Widget
interface SiteWidget<TApi extends object = {}> {
readonly widgetId: string; // unique; prefix it with your product, e.g. 'acme-counter'
readonly widgetTitle: string; // tile and window title
readonly widgetIcon: string; // a Material Symbols icon name
readonly optional: boolean; // false: opened automatically and cannot be closed
readonly backgroundConnectors: Array<new () => SiteConnector>;
windowed?: boolean; // show the roots in a movable window
styles?: string; // CSS added while the widget is open
api?: TApi; // returned by widgetsApi.get(widgetId) while open
mount(app: WeeiApp): HTMLElement | HTMLElement[] | void;
destroy(): void;
configureBackground?(app: WeeiApp, allowed: boolean): void;
createBackgroundApi?(app: WeeiApp): TApi; // an API available while the widget is closed
}| Member | When it runs |
|---|---|
mount(app) | Each time the widget opens. Return the root element(s); Weei places them and removes them on close. |
destroy() | Each time the widget closes. Stop timers and subscriptions. A new instance is created for the next opening. |
configureBackground(app, allowed) | When the widget is added and when its availability changes, whether open or not. |
createBackgroundApi(app) | Once, when the widget is added. widgetsApi.get() prefers this API. |
Connector
interface SiteConnector {
// static connectorName: string — required; must not contain '::'
initListeners(gateway: Gateway): void;
}
interface Gateway {
readonly myID: string; // this participant's peer ID
readonly reachablePeers$: Observable<string[]>;
createEvent<T>(name: string): Channel<T>;
}
interface Channel<T> extends Observable<T> { // subscribe to receive
next(value: T, toPeerId?: string): void; // send to everyone or to one peer
readonly lastMessageFrom: string; // sender of the message being handled
}One connector instance exists per class and is shared by every widget that requests it. Declare static connectorName: Weei addresses messages by this name, and a bundler may rename your class.
The app object
| Member | Use |
|---|---|
app.rtcService.getOrCreateConnector(Class) | Observable of the connector instance, created on first use. |
app.rtcService.myID | This participant's peer ID. |
app.snackbar.show(notice) | Shows a notification: { message, type?, duration?, key?, actionLabel?, onAction? }. type is info, success or error. |
app.widgetsApi | The same widgetsApi as on the client. |
app.initializedElements.add(widgetId, element) | Places an element created after mount() has returned; it is removed when the widget closes. |
weei.sdk
| Member | Contents |
|---|---|
rxjs | The RxJS of the loaded release. Use it instead of your own copy. |
connectors | Core connectors, shared with Weei itself. See Core connectors. |
version, moduleApiVersion | Release version and widget module API version. |
See Core connectors for what each connector provides.
Load a widget from a URL
addWidget(url) imports an ES module with these exports:
export const widgetId = 'acme-counter';
export const apiVersion = 1; // weei.sdk.moduleApiVersion
export const createWidget = () => new CounterWidget();Rules
widgetIdmust not be the ID of a built-in widget;addWidget()rejects it.- Treat every received message as untrusted: check its shape and take the sender from
lastMessageFrom, not from the message. - Render peer data as text (
textContent), never as HTML. - Site widgets run with the same access as your page; they are not sandboxed.