Storeware Docs

Admin bridge

Talk to the admin from a page it frames.

import { ... } from '@storeware/plugin-sdk';

connectToHost

Connects an extension to its host.

function connectToHost(options: BridgeOptions): Bridge

createAppBridge

Connects a framed page to the admin, version 2.

function createAppBridge(options: AppBridgeOptions): AppBridge

BridgeError

A request the admin refused, with its reason.

new BridgeError(code: BridgeErrorCode | 'timeout' | 'disposed', message: string)

ExtensionMessage

Sent by the extension to the host.

type ExtensionMessage = {
    protocol: typeof BRIDGE_PROTOCOL;
    type: 'ready';
} | {
    protocol: typeof BRIDGE_PROTOCOL;
    type: 'resize';
    height: number;
} | {
    protocol: typeof BRIDGE_PROTOCOL;
    type: 'toast';
    message: string;
    tone?: 'info' | 'error';
} | {
    protocol: typeof BRIDGE_PROTOCOL;
    type: 'navigate';
    path: string;
};

HostMessage

Sent by the host to the extension.

type HostMessage = {
    protocol: typeof BRIDGE_PROTOCOL;
    type: 'context';
    storeId: string;
    context: Record<string, string | string[]>;
} | {
    protocol: typeof BRIDGE_PROTOCOL;
    type: 'session';
    token: string;
} | {
    protocol: typeof BRIDGE_PROTOCOL;
    type: 'theme';
    scheme: 'light' | 'dark';
    variables: Record<string, string>;
};

BridgeOptions

NameTypeDescription
hostOriginstringThe admin origin, for example https://app.storeware.ai.
onContext?(storeId: string, context: Record<string, string | string[]>) => void
onSession?(token: string) => void
onTheme?(scheme: 'light' | 'dark', variables: Record<string, string>) => voidCalled with the admin's tokens on connect and whenever they change.

Bridge

NameTypeDescription
ready() => void
resize(height: number) => void
toast(message: string, tone?: 'info' | 'error') => void
navigate(path: string) => void
applyTheme(element: HTMLElement) => voidWrites the host's tokens onto an element, usually document.documentElement.
dispose() => voidStops listening. Call on unmount.

AppBridgeOptions

App Bridge version 2, for a page the admin frames.

NameTypeDescription
hostOriginstringThe admin origin, for example https://app.storeware.ai.
timeoutMs?numberHow long a request waits for the admin, in milliseconds. The merchant's answers never time out.
window?Pick<Window, 'addEventListener' | 'removeEventListener'>The window to listen on. Injectable for tests.
parent?{ postMessage(message: unknown, targetOrigin: string): void }Where messages are posted: the admin's window. Injectable for tests.

TitleBar

What a page can put above its frame. Send it again to change it, or \{\} to clear it.

NameTypeDescription
title?stringThe heading.
primary?TitleBarAction | nullThe one button the page is for.
secondary?TitleBarAction[]Up to three more.

AppBridgeEvents

Things the admin tells the page about after the handshake.

NameTypeDescription
title_bar.actionstringA title bar button, by its id.
save_bar.savevoidThe merchant pressed Save. Save, then call saveBar.result.
save_bar.discardvoidThe merchant chose to discard. Put the page back as it was last saved.
themeThemeThe admin's colours changed. applyTheme already has them.
session{ token: string; expiresAt: string }A fresh session token, sent every four minutes.

SaveBarControls

NameTypeDescription
dirty(dirty: boolean) => voidWhether there are unsaved changes. While there are, leaving the page is questioned.
result(ok: boolean, message?: string) => voidHow the save the merchant asked for went. Unsaved changes stay unsaved on a failure.

ModalControls

NameTypeDescription
open(path: string, title: string, options?: { size?: 'small' | 'medium' | 'large'; }) => Promise<unknown>Opens a page of your app's home in a window over the admin. Resolves with what that page passed to close, or undefined when the merchant closed it.
close(data?: unknown) => voidFrom inside a window: closes it, handing data to the page that opened it.

AppBridge

NameTypeDescription
readyPromise<Welcome>Resolves once the admin has answered the handshake.
welcomeWelcome | nullThe handshake's answer, or null until it arrives.
sessionToken() => Promise<string>A session token for a call to your own server.
toast(message: string, tone?: 'info' | 'error') => voidA short message, shown with your app's name in front of it. Three per ten seconds.
loading(on: boolean) => voidThe loading bar across the top of the frame.
titleBar(bar: TitleBar) => voidA heading and buttons above the frame. Presses come back as title_bar.action.
saveBarSaveBarControlsThe admin's save bar, on pages that have one.
modalModalControlsPages of your app's home in a window over the admin.
confirm(options: { title: string; message: string; confirmLabel?: string; destructive?: boolean; }) => Promise<boolean>Asks the merchant. The window is titled with your app's name.
pick(resource: PickerResource, options?: { multiple?: boolean; max?: number; }) => Promise<Picked[]>The merchant chooses records. Empty when they cancel. Refused with not_granted when your grant cannot read them.
navigate(path: string) => voidAnother page of this shop's admin, relative to the shop: /orders.
appNavigate(path: string) => voidA page of your app's home: /settings.
redirect(url: string) => voidA page off Storeware. The merchant is shown where it goes first.
resize(height: number) => voidThe frame's height in pixels, kept between 80 and 1200.
autoResize(element: HTMLElement) => () => voidKeeps the frame as tall as element. Returns a function that stops it.
on<E extends keyof AppBridgeEvents>(event: E, handler: (detail: AppBridgeEvents[E]) => void) => () => voidListens for something the admin tells the page. Returns a function that stops it.
applyTheme(element: HTMLElement) => voidWrites the admin's 13 --sw-* variables onto an element, usually the root.
dispose() => voidStops listening and fails anything still waiting. Call on unmount.

BRIDGE_PROTOCOL

Version 1's protocol name. Version 2's is PROTOCOL in ./bridge/protocol.

const BRIDGE_PROTOCOL: 'storeware.bridge.v1'

On this page