@stackable-labs/sdk-extension-react 1.22.0 → 1.22.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stackable-labs/sdk-extension-react",
3
- "version": "1.22.0",
3
+ "version": "1.22.2",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -12,9 +12,7 @@
12
12
  }
13
13
  },
14
14
  "dependencies": {
15
- "@agnostack/verifyd": "2.x",
16
- "@stackable-labs/lib-utils-js": "workspace:*",
17
- "@stackable-labs/sdk-extension-contracts": "1.22.0",
15
+ "@stackable-labs/sdk-extension-contracts": "1.22.2",
18
16
  "@remote-dom/core": "1.x",
19
17
  "@remote-dom/react": "1.x"
20
18
  },
package/dist/Surface.d.ts DELETED
@@ -1,24 +0,0 @@
1
- /**
2
- * Surface component — represents a single UI surface within an extension.
3
- * Each Surface maps to an extension point (target) in the host app.
4
- *
5
- * Serializes the React element tree (including event handler references) and
6
- * sends it to the host via postMessage. The host renders using its component
7
- * registry and proxies user interactions back via postMessage.
8
- */
9
- import React from 'react';
10
- interface SurfaceProps {
11
- /** The extension point target ID (e.g., "slot.header") */
12
- id: string;
13
- children: React.ReactNode;
14
- }
15
- export interface SerializedNode {
16
- type: 'element' | 'text';
17
- tag?: string;
18
- attrs?: Record<string, string>;
19
- actionId?: string;
20
- children?: SerializedNode[];
21
- text?: string;
22
- }
23
- export declare const Surface: ({ id, children }: SurfaceProps) => import("react/jsx-runtime").JSX.Element;
24
- export {};
package/dist/Surface.js DELETED
@@ -1,176 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- /**
3
- * Surface component — represents a single UI surface within an extension.
4
- * Each Surface maps to an extension point (target) in the host app.
5
- *
6
- * Serializes the React element tree (including event handler references) and
7
- * sends it to the host via postMessage. The host renders using its component
8
- * registry and proxies user interactions back via postMessage.
9
- */
10
- import React, { useEffect, useRef, useState, useCallback } from 'react';
11
- import { SurfaceContext, ExtensionContext } from './context';
12
- const useExtensionId = () => {
13
- const ctx = React.useContext(ExtensionContext);
14
- return ctx?.extensionId ?? 'unknown';
15
- };
16
- /**
17
- * Per-surface action handler registry.
18
- * Each Surface instance gets its own map keyed by surfaceId so they don't collide.
19
- */
20
- const surfaceHandlers = new Map();
21
- const getSurfaceRegistry = (surfaceId) => {
22
- let reg = surfaceHandlers.get(surfaceId);
23
- if (!reg) {
24
- reg = { handlers: new Map(), counter: 0 };
25
- surfaceHandlers.set(surfaceId, reg);
26
- }
27
- return reg;
28
- };
29
- /**
30
- * Serialize the rendered DOM tree from the hidden container.
31
- * This approach works with hook-based child components because React has
32
- * already rendered them into actual DOM elements by the time we traverse.
33
- */
34
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
35
- const serializeDOMNode = (domNode, registry) => {
36
- if (domNode.nodeType === Node.TEXT_NODE) {
37
- const text = domNode.textContent || '';
38
- if (!text.trim())
39
- return [];
40
- return [{ type: 'text', text }];
41
- }
42
- if (domNode.nodeType !== Node.ELEMENT_NODE)
43
- return [];
44
- const el = domNode;
45
- const tag = el.tagName.toLowerCase();
46
- // Skip the container div
47
- if (tag === 'div' && el.hasAttribute('data-surface-id')) {
48
- return Array.from(el.childNodes).flatMap((child) => serializeDOMNode(child, registry));
49
- }
50
- const attrs = {};
51
- let actionId;
52
- // Extract props from React's internal __reactProps$ to preserve original
53
- // prop names (e.g. className instead of class) and custom element props
54
- // (e.g. variant, gap, direction) that may not appear as DOM attributes.
55
- const propsKey = Object.keys(el).find((k) => k.startsWith('__reactProps$'));
56
- if (propsKey) {
57
- const reactProps = el[propsKey];
58
- if (reactProps) {
59
- for (const [key, value] of Object.entries(reactProps)) {
60
- if (key === 'children')
61
- continue;
62
- if ((key === 'onClick' || key === 'onChange') && typeof value === 'function') {
63
- const id = `action-${++registry.counter}`;
64
- registry.handlers.set(id, value);
65
- if (key === 'onClick')
66
- actionId = id;
67
- if (key === 'onChange')
68
- attrs['data-onchange-id'] = id;
69
- continue;
70
- }
71
- if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
72
- attrs[key] = String(value);
73
- }
74
- }
75
- }
76
- }
77
- else {
78
- // Fallback: copy DOM attributes if React props are unavailable
79
- for (const attr of Array.from(el.attributes)) {
80
- if (attr.name === 'style')
81
- continue;
82
- // Map 'class' back to 'className' for host components
83
- const name = attr.name === 'class' ? 'className' : attr.name;
84
- attrs[name] = attr.value;
85
- }
86
- }
87
- const children = Array.from(el.childNodes).flatMap((child) => serializeDOMNode(child, registry));
88
- return [{ type: 'element', tag, attrs, actionId, children }];
89
- };
90
- export const Surface = ({ id, children }) => {
91
- const extId = useExtensionId();
92
- const [context, setContext] = useState({});
93
- const prevTreeRef = useRef('');
94
- const containerRef = useRef(null);
95
- const serializeAndSend = useCallback(() => {
96
- const container = containerRef.current;
97
- if (!container)
98
- return;
99
- const registry = getSurfaceRegistry(id);
100
- // Clear previous handlers for THIS surface only
101
- registry.handlers.clear();
102
- registry.counter = 0;
103
- const serialized = serializeDOMNode(container, registry);
104
- const tree = {
105
- type: 'element',
106
- tag: '__fragment',
107
- children: serialized,
108
- };
109
- // Only send if tree structure actually changed (ignore action ID changes)
110
- const treeForComparison = JSON.stringify(tree, (key, value) => key === 'actionId' || key === 'data-onchange-id' ? undefined : value);
111
- if (treeForComparison === prevTreeRef.current)
112
- return;
113
- prevTreeRef.current = treeForComparison;
114
- window.parent.postMessage({ type: 'surface-update', surfaceId: id, tree }, '*');
115
- }, [id]);
116
- // Serialize after every Surface render
117
- useEffect(() => {
118
- serializeAndSend();
119
- });
120
- // Watch for DOM mutations from child component state changes
121
- // (children may re-render without Surface itself re-rendering)
122
- useEffect(() => {
123
- const container = containerRef.current;
124
- if (!container)
125
- return;
126
- const observer = new MutationObserver(() => {
127
- serializeAndSend();
128
- });
129
- observer.observe(container, {
130
- childList: true,
131
- subtree: true,
132
- attributes: true,
133
- characterData: true,
134
- });
135
- return () => observer.disconnect();
136
- }, [serializeAndSend]);
137
- useEffect(() => {
138
- // Listen for context updates and action invocations from host
139
- const handleMessage = (event) => {
140
- const msg = event.data;
141
- if (!msg || typeof msg !== 'object')
142
- return;
143
- if (msg.type === 'context-update' && msg.surfaceId === id) {
144
- setContext(msg.context);
145
- }
146
- if (msg.type === 'surface-render' && msg.surfaceId === id) {
147
- // Host slot mounted late — re-send current tree
148
- if (msg.context) {
149
- setContext(msg.context);
150
- }
151
- prevTreeRef.current = '';
152
- serializeAndSend();
153
- }
154
- if (msg.type === 'action-invoke' && msg.surfaceId === id && msg.actionId) {
155
- const registry = getSurfaceRegistry(id);
156
- const handler = registry.handlers.get(msg.actionId);
157
- if (handler) {
158
- if (msg.value !== undefined) {
159
- handler({ target: { value: msg.value } });
160
- }
161
- else {
162
- handler();
163
- }
164
- }
165
- }
166
- };
167
- window.addEventListener('message', handleMessage);
168
- // Notify host that this surface is ready
169
- window.parent.postMessage({ type: 'surface-ready', extensionId: extId, surfaceId: id }, '*');
170
- return () => {
171
- window.removeEventListener('message', handleMessage);
172
- };
173
- }, [id, extId, serializeAndSend]);
174
- return (_jsx(SurfaceContext.Provider, { value: context, children: _jsx("div", { ref: containerRef, "data-surface-id": id, style: { display: 'none' }, children: children }) }));
175
- };
176
- //# sourceMappingURL=Surface.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Surface.js","sourceRoot":"","sources":["../src/Surface.tsx"],"names":[],"mappings":"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"}
package/dist/context.d.ts DELETED
@@ -1,10 +0,0 @@
1
- /**
2
- * React contexts for the extension runtime.
3
- */
4
- /** Context for surface-level data (provided by host per surface) */
5
- export declare const SurfaceContext: import("react").Context<Record<string, unknown> | null>;
6
- /** Context for extension-level data (provided by createExtension) */
7
- export interface ExtensionContextValue {
8
- extensionId: string;
9
- }
10
- export declare const ExtensionContext: import("react").Context<ExtensionContextValue | null>;
package/dist/context.js DELETED
@@ -1,8 +0,0 @@
1
- /**
2
- * React contexts for the extension runtime.
3
- */
4
- import { createContext } from 'react';
5
- /** Context for surface-level data (provided by host per surface) */
6
- export const SurfaceContext = createContext(null);
7
- export const ExtensionContext = createContext(null);
8
- //# sourceMappingURL=context.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAA;AAErC,oEAAoE;AACpE,MAAM,CAAC,MAAM,cAAc,GAAG,aAAa,CAAiC,IAAI,CAAC,CAAA;AAOjF,MAAM,CAAC,MAAM,gBAAgB,GAAG,aAAa,CAA+B,IAAI,CAAC,CAAA"}
@@ -1,21 +0,0 @@
1
- /**
2
- * createExtension — bootstraps the extension runtime in the iframe sandbox.
3
- * Sets up Remote DOM, RPC listener, and renders the extension's React tree.
4
- */
5
- import React from 'react';
6
- interface CreateExtensionOptions {
7
- extensionId?: string;
8
- }
9
- /**
10
- * Bootstrap an extension. Call this as the entry point of your extension bundle.
11
- *
12
- * @example
13
- * export default createExtension(() => (
14
- * <>
15
- * <Surface id="slot.header"><Header /></Surface>
16
- * <Surface id="slot.content"><Content /></Surface>
17
- * </>
18
- * ));
19
- */
20
- export declare const createExtension: (factory: () => React.ReactElement, options?: CreateExtensionOptions) => void;
21
- export {};
@@ -1,35 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { createRoot } from 'react-dom/client';
3
- import { ExtensionContext } from './context';
4
- import { initRpcListener } from './rpc-client';
5
- /**
6
- * Bootstrap an extension. Call this as the entry point of your extension bundle.
7
- *
8
- * @example
9
- * export default createExtension(() => (
10
- * <>
11
- * <Surface id="slot.header"><Header /></Surface>
12
- * <Surface id="slot.content"><Content /></Surface>
13
- * </>
14
- * ));
15
- */
16
- export const createExtension = (factory, options) => {
17
- // Resolve extensionId: prefer host-injected value, then options, then fallback
18
- const injectedId = window.__STACKABLE_EXTENSION_ID__ ??
19
- new URLSearchParams(window.location.search).get('__extensionId') ??
20
- undefined;
21
- const extensionId = injectedId ?? options?.extensionId ?? 'unknown';
22
- console.debug(`[createExtension] extensionId resolved: "${extensionId}" (injected: ${injectedId ?? 'none'}, options: ${options?.extensionId ?? 'none'})`);
23
- // Initialize RPC listener for capability responses
24
- initRpcListener(extensionId);
25
- const contextValue = {
26
- extensionId,
27
- };
28
- // Mount the extension React tree
29
- const container = document.getElementById('extension-root') ?? document.body;
30
- const root = createRoot(container);
31
- root.render(_jsx(ExtensionContext.Provider, { value: contextValue, children: factory() }));
32
- // Notify host that the extension is ready
33
- window.parent.postMessage({ type: 'extension-ready', extensionId }, '*');
34
- };
35
- //# sourceMappingURL=createExtension.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"createExtension.js","sourceRoot":"","sources":["../src/createExtension.tsx"],"names":[],"mappings":";AAMA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAA;AAE5C,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAM9C;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,OAAiC,EAAE,OAAgC,EAAQ,EAAE;IAC3G,+EAA+E;IAC/E,MAAM,UAAU,GACb,MAA6C,CAAC,0BAAgD;QAC/F,IAAI,eAAe,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,eAAe,CAAC;QAChE,SAAS,CAAA;IACX,MAAM,WAAW,GAAG,UAAU,IAAI,OAAO,EAAE,WAAW,IAAI,SAAS,CAAA;IACnE,OAAO,CAAC,KAAK,CAAC,4CAA4C,WAAW,gBAAgB,UAAU,IAAI,MAAM,cAAc,OAAO,EAAE,WAAW,IAAI,MAAM,GAAG,CAAC,CAAA;IAEzJ,mDAAmD;IACnD,eAAe,CAAC,WAAW,CAAC,CAAA;IAE5B,MAAM,YAAY,GAA0B;QAC1C,WAAW;KACZ,CAAA;IAED,iCAAiC;IACjC,MAAM,SAAS,GAAG,QAAQ,CAAC,cAAc,CAAC,gBAAgB,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAA;IAC5E,MAAM,IAAI,GAAG,UAAU,CAAC,SAAS,CAAC,CAAA;IAElC,IAAI,CAAC,MAAM,CACT,KAAC,gBAAgB,CAAC,QAAQ,IAAC,KAAK,EAAE,YAAY,YAC3C,OAAO,EAAE,GACgB,CAC7B,CAAA;IAED,0CAA0C;IAC1C,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,iBAAiB,EAAE,WAAW,EAAE,EAAE,GAAG,CAAC,CAAA;AAC1E,CAAC,CAAA"}
package/dist/hooks.d.ts DELETED
@@ -1,33 +0,0 @@
1
- /**
2
- * React hooks for extension developers.
3
- */
4
- import type { ContextData, ApiRequest, FetchRequestInit, FetchResponse, ToastPayload } from '@stackable-labs/sdk-extension-contracts';
5
- import type { Store } from './store';
6
- /**
7
- * Read the host-provided context for the current surface.
8
- */
9
- export declare const useSurfaceContext: () => Record<string, unknown>;
10
- /**
11
- * Access host-mediated capabilities (data, actions, context).
12
- */
13
- export declare const useCapabilities: () => {
14
- data: {
15
- query: <T = unknown>(payload: ApiRequest) => Promise<T>;
16
- fetch: (url: string, init?: FetchRequestInit) => Promise<FetchResponse>;
17
- };
18
- actions: {
19
- toast: (payload: ToastPayload) => Promise<void>;
20
- invoke: <T = unknown>(action: string, payload?: Record<string, unknown>) => Promise<T>;
21
- };
22
- context: {
23
- read: () => Promise<ContextData>;
24
- };
25
- };
26
- /**
27
- * Subscribe to a shared store with an optional selector.
28
- */
29
- export declare const useStore: <T, S = T>(store: Store<T>, selector?: (state: T) => S) => S;
30
- /**
31
- * Access the extension-level context (extension ID, manifest, etc.)
32
- */
33
- export declare const useExtension: () => import("./context").ExtensionContextValue;
package/dist/hooks.js DELETED
@@ -1,52 +0,0 @@
1
- /**
2
- * React hooks for extension developers.
3
- */
4
- import { useContext, useSyncExternalStore, useCallback } from 'react';
5
- import { ExtensionContext, SurfaceContext } from './context';
6
- import { callCapability } from './rpc-client';
7
- /**
8
- * Read the host-provided context for the current surface.
9
- */
10
- export const useSurfaceContext = () => {
11
- const ctx = useContext(SurfaceContext);
12
- if (!ctx) {
13
- throw new Error('useSurfaceContext must be used inside a <Surface> component');
14
- }
15
- return ctx;
16
- };
17
- /**
18
- * Access host-mediated capabilities (data, actions, context).
19
- */
20
- export const useCapabilities = () => ({
21
- data: {
22
- query: (payload) => callCapability('data.query', payload),
23
- fetch: (url, init) => callCapability('data.fetch', { url, ...init }),
24
- },
25
- actions: {
26
- toast: (payload) => callCapability('actions.toast', payload),
27
- invoke: (action, payload) => callCapability('actions.invoke', { action, payload }),
28
- },
29
- context: {
30
- read: () => callCapability('context.read'),
31
- },
32
- });
33
- /**
34
- * Subscribe to a shared store with an optional selector.
35
- */
36
- export const useStore = (store, selector) => {
37
- const select = selector ?? ((s) => s);
38
- const getSnapshot = useCallback(() => select(store.get()), [store, select]);
39
- const subscribe = useCallback((onStoreChange) => store.subscribe(onStoreChange), [store]);
40
- return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
41
- };
42
- /**
43
- * Access the extension-level context (extension ID, manifest, etc.)
44
- */
45
- export const useExtension = () => {
46
- const ctx = useContext(ExtensionContext);
47
- if (!ctx) {
48
- throw new Error('useExtension must be used inside a createExtension() tree');
49
- }
50
- return ctx;
51
- };
52
- //# sourceMappingURL=hooks.js.map
package/dist/hooks.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"hooks.js","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AASrE,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAG7C;;GAEG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAA4B,EAAE;IAC7D,MAAM,GAAG,GAAG,UAAU,CAAC,cAAc,CAAC,CAAA;IACtC,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CAAC,6DAA6D,CAAC,CAAA;IAChF,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC,CAAA;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,EAAE,CAAC,CAAC;IAClC,IAAI,EAAE;QACJ,KAAK,EAAE,CAAc,OAAmB,EAAc,EAAE,CACtD,cAAc,CAAI,YAAY,EAAE,OAAO,CAAC;QAC1C,KAAK,EAAE,CAAC,GAAW,EAAE,IAAuB,EAA0B,EAAE,CACtE,cAAc,CAAgB,YAAY,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,CAAC;KAChE;IACD,OAAO,EAAE;QACP,KAAK,EAAE,CAAC,OAAqB,EAAiB,EAAE,CAC9C,cAAc,CAAO,eAAe,EAAE,OAAO,CAAC;QAChD,MAAM,EAAE,CAAc,MAAc,EAAE,OAAiC,EAAc,EAAE,CACrF,cAAc,CAAI,gBAAgB,EAAE,EAAE,MAAM,EAAE,OAAO,EAAgC,CAAC;KACzF;IACD,OAAO,EAAE;QACP,IAAI,EAAE,GAAyB,EAAE,CAC/B,cAAc,CAAc,cAAc,CAAC;KAC9C;CACF,CAAC,CAAA;AAEJ;;GAEG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAW,KAAe,EAAE,QAA0B,EAAK,EAAE;IACnF,MAAM,MAAM,GAAG,QAAQ,IAAI,CAAC,CAAC,CAAI,EAAE,EAAE,CAAC,CAAiB,CAAC,CAAA;IAExD,MAAM,WAAW,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAA;IAE3E,MAAM,SAAS,GAAG,WAAW,CAC3B,CAAC,aAAyB,EAAE,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,aAAa,CAAC,EAC7D,CAAC,KAAK,CAAC,CACR,CAAA;IAED,OAAO,oBAAoB,CAAC,SAAS,EAAE,WAAW,EAAE,WAAW,CAAC,CAAA;AAClE,CAAC,CAAA;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,GAAG,EAAE;IAC/B,MAAM,GAAG,GAAG,UAAU,CAAC,gBAAgB,CAAC,CAAA;IACxC,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CAAC,2DAA2D,CAAC,CAAA;IAC9E,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC,CAAA"}
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AACrC,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,QAAQ,EACR,YAAY,GACb,MAAM,SAAS,CAAA;AAEhB,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,KAAK,EAAE,MAAM,MAAM,CAAA;AAC1B,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA"}
@@ -1,21 +0,0 @@
1
- /**
2
- * RPC Client — sends capability requests from sandbox to host via postMessage.
3
- * Handles transparent AES-256-GCM encryption for data.fetch payloads when
4
- * an encryption key is provided by the host.
5
- */
6
- import type { CapabilityType } from '@stackable-labs/sdk-extension-contracts';
7
- /**
8
- * Set the encryption key from a base64-encoded string.
9
- * Called when the host sends an 'extension-encryption-key' message.
10
- */
11
- export declare const setEncryptionKey: (keyBase64: string) => Promise<void>;
12
- /**
13
- * Initialize the RPC listener for responses from the host.
14
- */
15
- export declare const initRpcListener: (extensionId: string) => void;
16
- /**
17
- * Send a capability request to the host and await the response.
18
- * For data.fetch, transparently encrypts the request payload and
19
- * decrypts the response when an encryption key is available.
20
- */
21
- export declare const callCapability: <T = unknown>(capability: CapabilityType, payload?: unknown) => Promise<T>;
@@ -1,104 +0,0 @@
1
- /**
2
- * RPC Client — sends capability requests from sandbox to host via postMessage.
3
- * Handles transparent AES-256-GCM encryption for data.fetch payloads when
4
- * an encryption key is provided by the host.
5
- */
6
- import { WebCrypto } from '@agnostack/verifyd';
7
- import { importKeyForEncryption } from '@stackable-labs/lib-utils-js';
8
- // Lazy-init to avoid accessing globalThis.crypto at module load time.
9
- // Uses native crypto to ensure CryptoKey compatibility with importKeyForEncryption.
10
- let _webCrypto = null;
11
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
12
- const getWebCrypto = () => (_webCrypto ??= new WebCrypto({ crypto: globalThis.crypto }));
13
- let requestCounter = 0;
14
- let registeredExtensionId = 'unknown';
15
- let encryptionKey = null;
16
- const pendingRequests = new Map();
17
- const generateRequestId = () => `req_${++requestCounter}_${Date.now()}`;
18
- /**
19
- * Set the encryption key from a base64-encoded string.
20
- * Called when the host sends an 'extension-encryption-key' message.
21
- */
22
- export const setEncryptionKey = async (keyBase64) => {
23
- encryptionKey = await importKeyForEncryption(keyBase64);
24
- };
25
- /**
26
- * Initialize the RPC listener for responses from the host.
27
- */
28
- export const initRpcListener = (extensionId) => {
29
- registeredExtensionId = extensionId;
30
- window.addEventListener('message', (event) => {
31
- const msg = event.data;
32
- // Handle encryption key distribution from host
33
- if (msg?.type === 'extension-encryption-key') {
34
- setEncryptionKey(msg.encryptionKey);
35
- return;
36
- }
37
- if (msg?.type === 'capability-response') {
38
- const response = msg;
39
- const pending = pendingRequests.get(response.id);
40
- if (pending) {
41
- pendingRequests.delete(response.id);
42
- if (response.success) {
43
- pending.resolve(response.data);
44
- }
45
- else {
46
- pending.reject(new Error(response.error || 'Capability call failed'));
47
- }
48
- }
49
- }
50
- });
51
- };
52
- const isEncryptedPayload = (value) => typeof value === 'object' && value !== null && value.encrypted === true && Array.isArray(value.data);
53
- /**
54
- * Send a capability request to the host and await the response.
55
- * For data.fetch, transparently encrypts the request payload and
56
- * decrypts the response when an encryption key is available.
57
- */
58
- export const callCapability = async (capability, payload) => {
59
- let actualPayload = payload;
60
- // Encrypt data.fetch payloads if we have an encryption key
61
- if (capability === 'data.fetch' && encryptionKey) {
62
- const encrypted = await getWebCrypto().encryptMessage(JSON.stringify(payload), encryptionKey);
63
- if (!encrypted)
64
- throw new Error('Failed to encrypt data.fetch payload');
65
- actualPayload = { encrypted: true, data: encrypted };
66
- }
67
- const result = await sendCapabilityRequest(capability, actualPayload);
68
- // Decrypt data.fetch response if it came back encrypted
69
- if (capability === 'data.fetch' && encryptionKey) {
70
- const fetchResult = result;
71
- if (isEncryptedPayload(fetchResult.data)) {
72
- const decrypted = await getWebCrypto().decryptMessage(fetchResult.data.data, encryptionKey);
73
- fetchResult.data = JSON.parse(decrypted);
74
- }
75
- }
76
- return result;
77
- };
78
- /**
79
- * Low-level: send a capability request to the host and await the response via postMessage.
80
- */
81
- const sendCapabilityRequest = (capability, payload) => (new Promise((resolve, reject) => {
82
- const id = generateRequestId();
83
- pendingRequests.set(id, {
84
- resolve: resolve,
85
- reject,
86
- });
87
- const request = {
88
- type: 'capability-request',
89
- id,
90
- extensionId: registeredExtensionId,
91
- capability,
92
- payload,
93
- };
94
- // Post to parent (host) window
95
- window.parent.postMessage(request, '*');
96
- // Timeout after 30 seconds
97
- setTimeout(() => {
98
- if (pendingRequests.has(id)) {
99
- pendingRequests.delete(id);
100
- reject(new Error(`Capability call '${capability}' timed out`));
101
- }
102
- }, 30000);
103
- }));
104
- //# sourceMappingURL=rpc-client.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"rpc-client.js","sourceRoot":"","sources":["../src/rpc-client.ts"],"names":[],"mappings":"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"}
package/dist/store.d.ts DELETED
@@ -1,20 +0,0 @@
1
- /**
2
- * Shared Store — cross-surface state coordination.
3
- * All surfaces in the same extension runtime share a store instance.
4
- */
5
- type Listener<T> = (state: T) => void;
6
- export interface Store<T> {
7
- get(): T;
8
- set(partial: Partial<T>): void;
9
- subscribe(listener: Listener<T>): () => void;
10
- }
11
- /**
12
- * Create a shared store for cross-surface coordination.
13
- *
14
- * @example
15
- * const store = createStore({ mode: 'account', selectedId: null });
16
- * store.set({ mode: 'conversations' });
17
- * store.subscribe((state) => console.log(state));
18
- */
19
- export declare const createStore: <T extends object>(initialState: T) => Store<T>;
20
- export {};
package/dist/store.js DELETED
@@ -1,30 +0,0 @@
1
- /**
2
- * Shared Store — cross-surface state coordination.
3
- * All surfaces in the same extension runtime share a store instance.
4
- */
5
- /**
6
- * Create a shared store for cross-surface coordination.
7
- *
8
- * @example
9
- * const store = createStore({ mode: 'account', selectedId: null });
10
- * store.set({ mode: 'conversations' });
11
- * store.subscribe((state) => console.log(state));
12
- */
13
- export const createStore = (initialState) => {
14
- let state = { ...initialState };
15
- const listeners = new Set();
16
- return {
17
- get: () => state,
18
- set: (partial) => {
19
- state = { ...state, ...partial };
20
- listeners.forEach((listener) => listener(state));
21
- },
22
- subscribe: (listener) => {
23
- listeners.add(listener);
24
- return () => {
25
- listeners.delete(listener);
26
- };
27
- },
28
- };
29
- };
30
- //# sourceMappingURL=store.js.map
package/dist/store.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAUH;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAmB,YAAe,EAAY,EAAE;IACzE,IAAI,KAAK,GAAG,EAAE,GAAG,YAAY,EAAE,CAAA;IAC/B,MAAM,SAAS,GAAG,IAAI,GAAG,EAAe,CAAA;IAExC,OAAO;QACL,GAAG,EAAE,GAAG,EAAE,CAAC,KAAK;QAEhB,GAAG,EAAE,CAAC,OAAmB,EAAE,EAAE;YAC3B,KAAK,GAAG,EAAE,GAAG,KAAK,EAAE,GAAG,OAAO,EAAE,CAAA;YAChC,SAAS,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAA;QAClD,CAAC;QAED,SAAS,EAAE,CAAC,QAAqB,EAAE,EAAE;YACnC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;YACvB,OAAO,GAAG,EAAE;gBACV,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;YAC5B,CAAC,CAAA;QACH,CAAC;KACF,CAAA;AACH,CAAC,CAAA"}