@stackable-labs/sdk-extension-host 1.1.0 → 1.3.0

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.
Files changed (2) hide show
  1. package/README.md +103 -0
  2. package/package.json +2 -2
package/README.md CHANGED
@@ -45,6 +45,109 @@ function App() {
45
45
  - **`CapabilityRPCHandler`** — handles capability requests from extension sandboxes
46
46
  - **`SandboxManager`** — creates and destroys hidden iframe sandboxes per extension
47
47
 
48
+ ## Building a local preview host
49
+
50
+ During extension development, you can create a lightweight preview host app in your extension repo to test your extension against the real SDK sandbox — no private monorepo required.
51
+
52
+ ### Structure
53
+
54
+ ```
55
+ packages/
56
+ ├── extension/ ← your extension
57
+ └── preview/ ← local preview host
58
+ └── src/
59
+ ├── main.tsx
60
+ ├── App.tsx
61
+ └── mockData.json
62
+ ```
63
+
64
+ ### Preview App.tsx pattern
65
+
66
+ ```tsx
67
+ import { ExtensionProvider, ExtensionSlot } from '@stackable-labs/sdk-extension-host';
68
+ import type { CapabilityHandlers } from '@stackable-labs/sdk-extension-host';
69
+ import { hostComponents } from '@stackable-labs/embeddables/components';
70
+ import type {
71
+ ApiRequest,
72
+ ExtensionRegistryEntry,
73
+ Permission,
74
+ ToastPayload,
75
+ } from '@stackable-labs/sdk-extension-contracts';
76
+ import manifestRaw from '../../extension/public/manifest.json';
77
+ import mockData from './mockData.json';
78
+
79
+ const manifest = {
80
+ ...manifestRaw,
81
+ permissions: manifestRaw.permissions as Permission[],
82
+ };
83
+
84
+ const extensions: ExtensionRegistryEntry[] = [
85
+ {
86
+ id: manifest.name.toLowerCase().replace(/\s+/g, '-'),
87
+ manifest,
88
+ bundleUrl: `http://localhost:${import.meta.env.VITE_EXTENSION_PORT || '5173'}`,
89
+ enabled: true,
90
+ },
91
+ ];
92
+
93
+ const mockContext = { customerId: 'cust_123', customerEmail: 'dev@example.com' };
94
+
95
+ const capabilityHandlers: CapabilityHandlers = {
96
+ 'data.query': async (payload: ApiRequest) => {
97
+ // return mock data based on payload.action
98
+ return mockData;
99
+ },
100
+ 'actions.toast': async (payload: ToastPayload) => {
101
+ console.log('[Preview] toast:', payload);
102
+ },
103
+ 'context.read': async () => mockContext,
104
+ };
105
+
106
+ export default function App() {
107
+ return (
108
+ <ExtensionProvider
109
+ extensions={extensions}
110
+ components={hostComponents()}
111
+ capabilityHandlers={capabilityHandlers}
112
+ >
113
+ {manifest.targets.map((target) => (
114
+ <ExtensionSlot key={target} target={target} context={mockContext} />
115
+ ))}
116
+ </ExtensionProvider>
117
+ );
118
+ }
119
+ ```
120
+
121
+ ### Wiring two dev servers with Turborepo
122
+
123
+ At the workspace root, add:
124
+
125
+ **.env**
126
+ ```
127
+ VITE_EXTENSION_PORT=5173
128
+ VITE_PREVIEW_PORT=5174
129
+ ```
130
+
131
+ **turbo.json**
132
+ ```json
133
+ {
134
+ "$schema": "https://turbo.build/schema.json",
135
+ "globalEnv": ["VITE_EXTENSION_PORT", "VITE_PREVIEW_PORT"],
136
+ "tasks": {
137
+ "dev": { "cache": false, "persistent": true }
138
+ }
139
+ }
140
+ ```
141
+
142
+ Run both servers with one command:
143
+ ```bash
144
+ pnpm dev
145
+ ```
146
+
147
+ Extension runs at `:5173`, preview host at `:5174`. The preview host loads the extension bundle from the dev server, so edits to the extension hot-reload in the preview automatically.
148
+
149
+ See [sample-extension-commerce](https://github.com/agnostack/sample-extension-commerce) and [sample-extension-approvals](https://github.com/agnostack/sample-extension-approvals) for complete working examples.
150
+
48
151
  ## Changelog
49
152
 
50
153
  See [npm version history](https://www.npmjs.com/package/@stackable-labs/sdk-extension-host?activeTab=versions).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stackable-labs/sdk-extension-host",
3
- "version": "1.1.0",
3
+ "version": "1.3.0",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -12,7 +12,7 @@
12
12
  }
13
13
  },
14
14
  "dependencies": {
15
- "@stackable-labs/sdk-extension-contracts": "1.1.0",
15
+ "@stackable-labs/sdk-extension-contracts": "1.3.0",
16
16
  "@remote-dom/core": "1.x",
17
17
  "@remote-dom/react": "1.x"
18
18
  },