@fias/arche-sdk 1.0.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.
- package/README.md +356 -0
- package/dist/bridge.d.ts +56 -0
- package/dist/bridge.d.ts.map +1 -0
- package/dist/bridge.js +190 -0
- package/dist/bridge.js.map +1 -0
- package/dist/cli/create-plugin.d.ts +3 -0
- package/dist/cli/create-plugin.d.ts.map +1 -0
- package/dist/cli/create-plugin.js +80 -0
- package/dist/cli/create-plugin.js.map +1 -0
- package/dist/context.d.ts +6 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +9 -0
- package/dist/context.js.map +1 -0
- package/dist/fias.d.ts +30 -0
- package/dist/fias.d.ts.map +1 -0
- package/dist/fias.js +40 -0
- package/dist/fias.js.map +1 -0
- package/dist/hooks.d.ts +37 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +116 -0
- package/dist/hooks.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +323 -0
- package/dist/provider.d.ts +25 -0
- package/dist/provider.d.ts.map +1 -0
- package/dist/provider.js +47 -0
- package/dist/provider.js.map +1 -0
- package/dist/types.d.ts +118 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +54 -0
- package/templates/default/fias-plugin.json +11 -0
- package/templates/default/index.html +12 -0
- package/templates/default/package.json +23 -0
- package/templates/default/src/App.tsx +12 -0
- package/templates/default/src/index.tsx +12 -0
- package/templates/default/tsconfig.json +17 -0
- package/templates/default/vite.config.ts +18 -0
package/README.md
ADDED
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
# @fias/arche-sdk
|
|
2
|
+
|
|
3
|
+
Build plugin arches for the FIAS platform. This SDK provides React hooks, a bridge communication layer, and a CLI scaffolder so you can develop, test, and submit plugins that run inside the FIAS platform.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Scaffold a new plugin
|
|
9
|
+
npx create-fias-plugin my-plugin
|
|
10
|
+
cd my-plugin
|
|
11
|
+
npm install
|
|
12
|
+
|
|
13
|
+
# Start the dev server
|
|
14
|
+
npm run dev
|
|
15
|
+
|
|
16
|
+
# Open the dev preview in your browser (requires a running FIAS platform)
|
|
17
|
+
# http://localhost:3000/a/arche_plugins/dev-preview?url=http://localhost:3100&permissions=theme:read
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
When you're ready to submit:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm run build
|
|
24
|
+
# Package your plugin into a tarball, then upload it through the submission flow (see below)
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Manifest Reference (`fias-plugin.json`)
|
|
28
|
+
|
|
29
|
+
Every plugin must include a `fias-plugin.json` at its root:
|
|
30
|
+
|
|
31
|
+
```json
|
|
32
|
+
{
|
|
33
|
+
"name": "my-plugin",
|
|
34
|
+
"version": "1.0.0",
|
|
35
|
+
"description": "A short description of what the plugin does",
|
|
36
|
+
"main": "src/index.tsx",
|
|
37
|
+
"archeType": "tool",
|
|
38
|
+
"tags": ["utility"],
|
|
39
|
+
"pricing": { "model": "free", "currency": "usd" },
|
|
40
|
+
"permissions": ["theme:read", "storage:sandbox"],
|
|
41
|
+
"sdk": "^1.0.0"
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
| Field | Type | Description |
|
|
46
|
+
| ------------- | ----------------------------------------------- | ----------------------------------------------------- |
|
|
47
|
+
| `name` | `string` | Unique plugin identifier (lowercase, hyphens allowed) |
|
|
48
|
+
| `version` | `string` | Semver version of your plugin |
|
|
49
|
+
| `description` | `string` | Short description shown in the marketplace |
|
|
50
|
+
| `main` | `string` | Entry point source file |
|
|
51
|
+
| `archeType` | `"tool" \| "assistant" \| "workflow"` | Category of your plugin |
|
|
52
|
+
| `tags` | `string[]` | Discovery tags for the marketplace |
|
|
53
|
+
| `pricing` | `{ model: "free" \| "paid", currency: string }` | Pricing model |
|
|
54
|
+
| `permissions` | `PluginPermission[]` | Scopes your plugin requires (see Permissions) |
|
|
55
|
+
| `sdk` | `string` | Required SDK version range |
|
|
56
|
+
|
|
57
|
+
## API Reference
|
|
58
|
+
|
|
59
|
+
Wrap your app in `<FiasProvider>` to enable all hooks:
|
|
60
|
+
|
|
61
|
+
```tsx
|
|
62
|
+
import { FiasProvider } from '@fias/arche-sdk';
|
|
63
|
+
|
|
64
|
+
function main() {
|
|
65
|
+
return (
|
|
66
|
+
<FiasProvider>
|
|
67
|
+
<App />
|
|
68
|
+
</FiasProvider>
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### `useFiasTheme()`
|
|
74
|
+
|
|
75
|
+
Access platform theme tokens for consistent styling. Automatically updates when the user toggles light/dark mode.
|
|
76
|
+
|
|
77
|
+
- **Requires:** `theme:read`
|
|
78
|
+
- **Returns:** `FiasTheme | null`
|
|
79
|
+
|
|
80
|
+
```tsx
|
|
81
|
+
import { useFiasTheme } from '@fias/arche-sdk';
|
|
82
|
+
|
|
83
|
+
function MyComponent() {
|
|
84
|
+
const theme = useFiasTheme();
|
|
85
|
+
if (!theme) return null;
|
|
86
|
+
|
|
87
|
+
return (
|
|
88
|
+
<div
|
|
89
|
+
style={{
|
|
90
|
+
color: theme.colors.text,
|
|
91
|
+
backgroundColor: theme.colors.background,
|
|
92
|
+
fontFamily: theme.fonts.body,
|
|
93
|
+
padding: theme.spacing.md,
|
|
94
|
+
}}
|
|
95
|
+
>
|
|
96
|
+
Current mode: {theme.mode}
|
|
97
|
+
</div>
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
**`FiasTheme` shape:**
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
interface FiasTheme {
|
|
106
|
+
colors: {
|
|
107
|
+
primary: string;
|
|
108
|
+
secondary: string;
|
|
109
|
+
background: string;
|
|
110
|
+
surface: string;
|
|
111
|
+
text: string;
|
|
112
|
+
textSecondary: string;
|
|
113
|
+
border: string;
|
|
114
|
+
error: string;
|
|
115
|
+
warning: string;
|
|
116
|
+
success: string;
|
|
117
|
+
};
|
|
118
|
+
spacing: { xs: string; sm: string; md: string; lg: string; xl: string };
|
|
119
|
+
fonts: { body: string; heading: string; mono: string };
|
|
120
|
+
mode: 'light' | 'dark';
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### `useFiasUser()`
|
|
125
|
+
|
|
126
|
+
Access the authenticated user's profile.
|
|
127
|
+
|
|
128
|
+
- **Requires:** `user:profile:read`
|
|
129
|
+
- **Returns:** `FiasUser | null`
|
|
130
|
+
|
|
131
|
+
```tsx
|
|
132
|
+
import { useFiasUser } from '@fias/arche-sdk';
|
|
133
|
+
|
|
134
|
+
function Greeting() {
|
|
135
|
+
const user = useFiasUser();
|
|
136
|
+
if (!user) return <span>Loading...</span>;
|
|
137
|
+
|
|
138
|
+
return <span>Hello, {user.displayName}!</span>;
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
**`FiasUser` shape:**
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
interface FiasUser {
|
|
146
|
+
userId: string;
|
|
147
|
+
displayName: string;
|
|
148
|
+
avatar: string | null;
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### `useFiasStorage()`
|
|
153
|
+
|
|
154
|
+
Read and write files in your plugin's sandboxed storage. Each plugin gets its own isolated namespace.
|
|
155
|
+
|
|
156
|
+
- **Requires:** `storage:sandbox`
|
|
157
|
+
- **Returns:** `FiasStorageApi`
|
|
158
|
+
|
|
159
|
+
```tsx
|
|
160
|
+
import { useFiasStorage } from '@fias/arche-sdk';
|
|
161
|
+
|
|
162
|
+
function NotesEditor() {
|
|
163
|
+
const { readFile, writeFile, listFiles, deleteFile } = useFiasStorage();
|
|
164
|
+
|
|
165
|
+
async function saveNote(content: string) {
|
|
166
|
+
await writeFile('notes/draft.txt', content);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
async function loadNotes() {
|
|
170
|
+
const files = await listFiles('notes/');
|
|
171
|
+
// files: ['notes/draft.txt', 'notes/archive.txt']
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
**`FiasStorageApi` shape:**
|
|
177
|
+
|
|
178
|
+
```typescript
|
|
179
|
+
interface FiasStorageApi {
|
|
180
|
+
readFile: (path: string) => Promise<string | null>;
|
|
181
|
+
writeFile: (path: string, content: string) => Promise<void>;
|
|
182
|
+
listFiles: (prefix?: string) => Promise<string[]>;
|
|
183
|
+
deleteFile: (path: string) => Promise<void>;
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### `useEntityInvocation()`
|
|
188
|
+
|
|
189
|
+
Invoke platform entities (AI models, tools, etc.) through the bridge.
|
|
190
|
+
|
|
191
|
+
- **Requires:** `entities:invoke`
|
|
192
|
+
- **Returns:** `EntityInvocationApi`
|
|
193
|
+
|
|
194
|
+
```tsx
|
|
195
|
+
import { useEntityInvocation } from '@fias/arche-sdk';
|
|
196
|
+
|
|
197
|
+
function AISummarizer() {
|
|
198
|
+
const { invoke, isLoading, result, error } = useEntityInvocation();
|
|
199
|
+
|
|
200
|
+
async function summarize(text: string) {
|
|
201
|
+
const res = await invoke({
|
|
202
|
+
entityId: 'entity_summarizer',
|
|
203
|
+
input: text,
|
|
204
|
+
parameters: { maxLength: 200 },
|
|
205
|
+
});
|
|
206
|
+
console.log(res.output);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
return (
|
|
210
|
+
<div>
|
|
211
|
+
<button onClick={() => summarize('...')} disabled={isLoading}>
|
|
212
|
+
{isLoading ? 'Summarizing...' : 'Summarize'}
|
|
213
|
+
</button>
|
|
214
|
+
{result && <p>{result.output}</p>}
|
|
215
|
+
{error && <p>Error: {error.message}</p>}
|
|
216
|
+
</div>
|
|
217
|
+
);
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### `useFiasNavigation()`
|
|
222
|
+
|
|
223
|
+
Navigate within your plugin's route space and react to navigation changes.
|
|
224
|
+
|
|
225
|
+
- **Requires:** No special permission
|
|
226
|
+
- **Returns:** `FiasNavigationApi`
|
|
227
|
+
|
|
228
|
+
```tsx
|
|
229
|
+
import { useFiasNavigation } from '@fias/arche-sdk';
|
|
230
|
+
|
|
231
|
+
function NavBar() {
|
|
232
|
+
const { navigateTo, currentPath } = useFiasNavigation();
|
|
233
|
+
|
|
234
|
+
return (
|
|
235
|
+
<nav>
|
|
236
|
+
<button onClick={() => navigateTo('/settings')}>Settings</button>
|
|
237
|
+
<span>Current: {currentPath}</span>
|
|
238
|
+
</nav>
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### `fias` (imperative utilities)
|
|
244
|
+
|
|
245
|
+
For operations outside React components:
|
|
246
|
+
|
|
247
|
+
```typescript
|
|
248
|
+
import { fias } from '@fias/arche-sdk';
|
|
249
|
+
|
|
250
|
+
// Resize the plugin iframe
|
|
251
|
+
fias.resize(800);
|
|
252
|
+
|
|
253
|
+
// Show a platform toast notification
|
|
254
|
+
fias.showToast('Saved successfully!', 'success');
|
|
255
|
+
// Variants: 'info' | 'success' | 'warning' | 'error'
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
## Permissions
|
|
259
|
+
|
|
260
|
+
Declare required permissions in your `fias-plugin.json`. Users see these before installing.
|
|
261
|
+
|
|
262
|
+
| Scope | Grants | Used by |
|
|
263
|
+
| ------------------- | ------------------------------------------------------------- | ----------------------- |
|
|
264
|
+
| `theme:read` | Read platform theme tokens (colors, fonts, spacing, mode) | `useFiasTheme()` |
|
|
265
|
+
| `user:profile:read` | Read the current user's profile (userId, displayName, avatar) | `useFiasUser()` |
|
|
266
|
+
| `storage:sandbox` | Read/write files in the plugin's sandboxed storage namespace | `useFiasStorage()` |
|
|
267
|
+
| `entities:invoke` | Invoke platform entities (AI models, tools) | `useEntityInvocation()` |
|
|
268
|
+
|
|
269
|
+
Requesting only the permissions you need improves user trust and review speed.
|
|
270
|
+
|
|
271
|
+
## Constraints
|
|
272
|
+
|
|
273
|
+
- **Bundle size:** Maximum 5 MB compressed
|
|
274
|
+
- **No external scripts/stylesheets:** All assets must be included in the bundle
|
|
275
|
+
- **Rate limits:** API calls through the bridge are rate-limited per type:
|
|
276
|
+
- `entity_invoke`: 60/minute
|
|
277
|
+
- `storage_write`: 120/minute
|
|
278
|
+
- `storage_read`: 300/minute
|
|
279
|
+
- `storage_list`: 60/minute
|
|
280
|
+
- `storage_delete`: 60/minute
|
|
281
|
+
- **Sandboxing:** Plugins run in an iframe with `sandbox="allow-scripts allow-forms"`. No access to the parent page DOM, cookies, or local storage.
|
|
282
|
+
|
|
283
|
+
## Dev Preview
|
|
284
|
+
|
|
285
|
+
Test your plugin locally against the real FIAS platform:
|
|
286
|
+
|
|
287
|
+
1. Start the FIAS platform on `localhost:3000`
|
|
288
|
+
2. Start your plugin dev server:
|
|
289
|
+
```bash
|
|
290
|
+
cd my-plugin
|
|
291
|
+
npm run dev
|
|
292
|
+
# Runs on localhost:3100
|
|
293
|
+
```
|
|
294
|
+
3. Open the dev preview URL in your browser:
|
|
295
|
+
```
|
|
296
|
+
http://localhost:3000/a/arche_plugins/dev-preview?url=http://localhost:3100&permissions=theme:read,storage:sandbox
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
The dev preview page:
|
|
300
|
+
|
|
301
|
+
- Loads your plugin in an iframe with a real `PluginBridgeHost`
|
|
302
|
+
- Provides real auth tokens, user data, and theme from the platform
|
|
303
|
+
- Grants the permissions you specify in the `permissions` query parameter
|
|
304
|
+
- Shows a toolbar with the plugin URL, reload button, and active permissions
|
|
305
|
+
|
|
306
|
+
**URL requirements:**
|
|
307
|
+
|
|
308
|
+
- Must be `localhost` or `https://` (no arbitrary HTTP origins)
|
|
309
|
+
- Your Vite dev server must have CORS enabled (the scaffold template configures this)
|
|
310
|
+
|
|
311
|
+
## Submission Flow
|
|
312
|
+
|
|
313
|
+
Once your plugin is ready for review:
|
|
314
|
+
|
|
315
|
+
1. **Build:** `npm run build` to create the production bundle in `dist/`
|
|
316
|
+
2. **Package:** Create a tarball of the build output
|
|
317
|
+
3. **Get upload URL:**
|
|
318
|
+
```
|
|
319
|
+
POST /v1/arches/plugins/submissions/upload-url
|
|
320
|
+
→ { uploadUrl, submissionId }
|
|
321
|
+
```
|
|
322
|
+
4. **Upload:** PUT the tarball to the returned `uploadUrl`
|
|
323
|
+
5. **Create submission:**
|
|
324
|
+
```
|
|
325
|
+
POST /v1/arches/plugins/submissions
|
|
326
|
+
Body: { submissionId, manifest: <contents of fias-plugin.json> }
|
|
327
|
+
```
|
|
328
|
+
6. **Track status:**
|
|
329
|
+
```
|
|
330
|
+
GET /v1/arches/plugins/submissions/:submissionId
|
|
331
|
+
→ { status: "pending" | "reviewing" | "approved" | "rejected", feedback?: string }
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
## TypeScript Types
|
|
335
|
+
|
|
336
|
+
All types are exported for advanced usage:
|
|
337
|
+
|
|
338
|
+
```typescript
|
|
339
|
+
import type {
|
|
340
|
+
FiasUser,
|
|
341
|
+
FiasTheme,
|
|
342
|
+
FiasStorageApi,
|
|
343
|
+
EntityInvocationApi,
|
|
344
|
+
EntityInvocationParams,
|
|
345
|
+
EntityInvocationResult,
|
|
346
|
+
FiasNavigationApi,
|
|
347
|
+
PluginPermission,
|
|
348
|
+
BridgeMessage,
|
|
349
|
+
BridgeResponse,
|
|
350
|
+
BridgeInitMessage,
|
|
351
|
+
} from '@fias/arche-sdk';
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
## License
|
|
355
|
+
|
|
356
|
+
MIT
|
package/dist/bridge.d.ts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { PluginToHostMessageType, FiasTheme, PluginPermission } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Low-level bridge client for postMessage communication with the FIAS host frame.
|
|
4
|
+
* Used internally by SDK hooks. Plugin developers should use hooks instead.
|
|
5
|
+
*/
|
|
6
|
+
export declare class FiasBridge {
|
|
7
|
+
private pendingRequests;
|
|
8
|
+
private initialized;
|
|
9
|
+
private initPromise;
|
|
10
|
+
private initResolve;
|
|
11
|
+
private archId;
|
|
12
|
+
private permissions;
|
|
13
|
+
private theme;
|
|
14
|
+
private currentPath;
|
|
15
|
+
private themeListeners;
|
|
16
|
+
private navigationListeners;
|
|
17
|
+
constructor();
|
|
18
|
+
/**
|
|
19
|
+
* Wait for the host to send the init message.
|
|
20
|
+
*/
|
|
21
|
+
waitForInit(): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* Signal to the host that the plugin is loaded and ready.
|
|
24
|
+
*/
|
|
25
|
+
ready(): void;
|
|
26
|
+
/**
|
|
27
|
+
* Request the host to resize the plugin iframe.
|
|
28
|
+
*/
|
|
29
|
+
resize(height: number): void;
|
|
30
|
+
/**
|
|
31
|
+
* Show a platform toast notification.
|
|
32
|
+
*/
|
|
33
|
+
showToast(message: string, variant?: 'info' | 'success' | 'warning' | 'error'): void;
|
|
34
|
+
/**
|
|
35
|
+
* Send a request to the host and wait for a response.
|
|
36
|
+
*/
|
|
37
|
+
request<T>(type: PluginToHostMessageType, payload: unknown): Promise<T>;
|
|
38
|
+
getArchId(): string;
|
|
39
|
+
getPermissions(): PluginPermission[];
|
|
40
|
+
getTheme(): FiasTheme | null;
|
|
41
|
+
getCurrentPath(): string;
|
|
42
|
+
onThemeUpdate(listener: (theme: FiasTheme) => void): () => void;
|
|
43
|
+
onNavigationUpdate(listener: (path: string) => void): () => void;
|
|
44
|
+
/**
|
|
45
|
+
* Clean up event listeners. Called when FiasProvider unmounts.
|
|
46
|
+
*/
|
|
47
|
+
destroy(): void;
|
|
48
|
+
private handleMessage;
|
|
49
|
+
private send;
|
|
50
|
+
}
|
|
51
|
+
export declare function getBridge(): FiasBridge;
|
|
52
|
+
/**
|
|
53
|
+
* Reset the bridge singleton (used in testing).
|
|
54
|
+
*/
|
|
55
|
+
export declare function resetBridge(): void;
|
|
56
|
+
//# sourceMappingURL=bridge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bridge.d.ts","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAIV,uBAAuB,EACvB,SAAS,EACT,gBAAgB,EACjB,MAAM,SAAS,CAAC;AAgBjB;;;GAGG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,eAAe,CAAqC;IAC5D,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,WAAW,CAA8B;IACjD,OAAO,CAAC,WAAW,CAA6B;IAChD,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,WAAW,CAA0B;IAC7C,OAAO,CAAC,KAAK,CAA0B;IACvC,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,cAAc,CAAyC;IAC/D,OAAO,CAAC,mBAAmB,CAAqC;;IAYhE;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAKlC;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;OAEG;IACH,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAI5B;;OAEG;IACH,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,OAAgB,GAAG,IAAI;IAI5F;;OAEG;IACG,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,uBAAuB,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;IAoB7E,SAAS,IAAI,MAAM;IAInB,cAAc,IAAI,gBAAgB,EAAE;IAIpC,QAAQ,IAAI,SAAS,GAAG,IAAI;IAI5B,cAAc,IAAI,MAAM;IAIxB,aAAa,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,GAAG,MAAM,IAAI;IAK/D,kBAAkB,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,MAAM,IAAI;IAKhE;;OAEG;IACH,OAAO,IAAI,IAAI;IAaf,OAAO,CAAC,aAAa,CAiDnB;IAEF,OAAO,CAAC,IAAI;CAWb;AAOD,wBAAgB,SAAS,IAAI,UAAU,CAKtC;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,IAAI,CAGlC"}
|
package/dist/bridge.js
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FiasBridge = void 0;
|
|
4
|
+
exports.getBridge = getBridge;
|
|
5
|
+
exports.resetBridge = resetBridge;
|
|
6
|
+
let messageCounter = 0;
|
|
7
|
+
function generateMessageId() {
|
|
8
|
+
return `msg_${Date.now()}_${++messageCounter}`;
|
|
9
|
+
}
|
|
10
|
+
const DEFAULT_TIMEOUT_MS = 30000;
|
|
11
|
+
/**
|
|
12
|
+
* Low-level bridge client for postMessage communication with the FIAS host frame.
|
|
13
|
+
* Used internally by SDK hooks. Plugin developers should use hooks instead.
|
|
14
|
+
*/
|
|
15
|
+
class FiasBridge {
|
|
16
|
+
constructor() {
|
|
17
|
+
this.pendingRequests = new Map();
|
|
18
|
+
this.initialized = false;
|
|
19
|
+
this.initPromise = null;
|
|
20
|
+
this.initResolve = null;
|
|
21
|
+
this.archId = '';
|
|
22
|
+
this.permissions = [];
|
|
23
|
+
this.theme = null;
|
|
24
|
+
this.currentPath = '';
|
|
25
|
+
this.themeListeners = new Set();
|
|
26
|
+
this.navigationListeners = new Set();
|
|
27
|
+
this.handleMessage = (event) => {
|
|
28
|
+
const data = event.data;
|
|
29
|
+
if (!data || typeof data !== 'object' || !data.type)
|
|
30
|
+
return;
|
|
31
|
+
// Handle init message from host
|
|
32
|
+
if (data.type === 'init') {
|
|
33
|
+
const initMsg = data;
|
|
34
|
+
this.archId = initMsg.payload.archId;
|
|
35
|
+
this.permissions = initMsg.payload.permissions;
|
|
36
|
+
this.theme = initMsg.payload.theme;
|
|
37
|
+
this.currentPath = initMsg.payload.currentPath;
|
|
38
|
+
this.initialized = true;
|
|
39
|
+
this.initResolve?.();
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
// Handle theme updates
|
|
43
|
+
if (data.type === 'theme_update') {
|
|
44
|
+
this.theme = data.payload;
|
|
45
|
+
for (const listener of this.themeListeners) {
|
|
46
|
+
listener(this.theme);
|
|
47
|
+
}
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
// Handle navigation updates
|
|
51
|
+
if (data.type === 'navigate_update') {
|
|
52
|
+
this.currentPath = data.payload;
|
|
53
|
+
for (const listener of this.navigationListeners) {
|
|
54
|
+
listener(this.currentPath);
|
|
55
|
+
}
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
// Handle response messages
|
|
59
|
+
if (data.type === 'response') {
|
|
60
|
+
const response = data;
|
|
61
|
+
const pending = this.pendingRequests.get(response.messageId);
|
|
62
|
+
if (!pending)
|
|
63
|
+
return;
|
|
64
|
+
clearTimeout(pending.timer);
|
|
65
|
+
this.pendingRequests.delete(response.messageId);
|
|
66
|
+
if (response.error) {
|
|
67
|
+
pending.reject(new Error(response.error));
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
pending.resolve(response.payload);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
this.initPromise = new Promise((resolve) => {
|
|
75
|
+
this.initResolve = resolve;
|
|
76
|
+
});
|
|
77
|
+
if (typeof window !== 'undefined') {
|
|
78
|
+
window.addEventListener('message', this.handleMessage);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Wait for the host to send the init message.
|
|
83
|
+
*/
|
|
84
|
+
async waitForInit() {
|
|
85
|
+
if (this.initialized)
|
|
86
|
+
return;
|
|
87
|
+
return this.initPromise;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Signal to the host that the plugin is loaded and ready.
|
|
91
|
+
*/
|
|
92
|
+
ready() {
|
|
93
|
+
this.send('ready', {});
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Request the host to resize the plugin iframe.
|
|
97
|
+
*/
|
|
98
|
+
resize(height) {
|
|
99
|
+
this.send('resize', { height });
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Show a platform toast notification.
|
|
103
|
+
*/
|
|
104
|
+
showToast(message, variant = 'info') {
|
|
105
|
+
this.send('toast', { message, variant });
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Send a request to the host and wait for a response.
|
|
109
|
+
*/
|
|
110
|
+
async request(type, payload) {
|
|
111
|
+
await this.waitForInit();
|
|
112
|
+
return new Promise((resolve, reject) => {
|
|
113
|
+
const messageId = generateMessageId();
|
|
114
|
+
const timer = setTimeout(() => {
|
|
115
|
+
this.pendingRequests.delete(messageId);
|
|
116
|
+
reject(new Error(`Bridge request timed out: ${type}`));
|
|
117
|
+
}, DEFAULT_TIMEOUT_MS);
|
|
118
|
+
this.pendingRequests.set(messageId, {
|
|
119
|
+
resolve: resolve,
|
|
120
|
+
reject,
|
|
121
|
+
timer,
|
|
122
|
+
});
|
|
123
|
+
this.send(type, payload, messageId);
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
getArchId() {
|
|
127
|
+
return this.archId;
|
|
128
|
+
}
|
|
129
|
+
getPermissions() {
|
|
130
|
+
return [...this.permissions];
|
|
131
|
+
}
|
|
132
|
+
getTheme() {
|
|
133
|
+
return this.theme;
|
|
134
|
+
}
|
|
135
|
+
getCurrentPath() {
|
|
136
|
+
return this.currentPath;
|
|
137
|
+
}
|
|
138
|
+
onThemeUpdate(listener) {
|
|
139
|
+
this.themeListeners.add(listener);
|
|
140
|
+
return () => this.themeListeners.delete(listener);
|
|
141
|
+
}
|
|
142
|
+
onNavigationUpdate(listener) {
|
|
143
|
+
this.navigationListeners.add(listener);
|
|
144
|
+
return () => this.navigationListeners.delete(listener);
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Clean up event listeners. Called when FiasProvider unmounts.
|
|
148
|
+
*/
|
|
149
|
+
destroy() {
|
|
150
|
+
if (typeof window !== 'undefined') {
|
|
151
|
+
window.removeEventListener('message', this.handleMessage);
|
|
152
|
+
}
|
|
153
|
+
for (const pending of this.pendingRequests.values()) {
|
|
154
|
+
clearTimeout(pending.timer);
|
|
155
|
+
pending.reject(new Error('Bridge destroyed'));
|
|
156
|
+
}
|
|
157
|
+
this.pendingRequests.clear();
|
|
158
|
+
this.themeListeners.clear();
|
|
159
|
+
this.navigationListeners.clear();
|
|
160
|
+
}
|
|
161
|
+
send(type, payload, messageId) {
|
|
162
|
+
if (typeof window === 'undefined')
|
|
163
|
+
return;
|
|
164
|
+
const message = {
|
|
165
|
+
type,
|
|
166
|
+
messageId: messageId ?? generateMessageId(),
|
|
167
|
+
payload,
|
|
168
|
+
};
|
|
169
|
+
window.parent.postMessage(message, '*');
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
exports.FiasBridge = FiasBridge;
|
|
173
|
+
/**
|
|
174
|
+
* Singleton bridge instance. Created lazily on first access.
|
|
175
|
+
*/
|
|
176
|
+
let bridgeInstance = null;
|
|
177
|
+
function getBridge() {
|
|
178
|
+
if (!bridgeInstance) {
|
|
179
|
+
bridgeInstance = new FiasBridge();
|
|
180
|
+
}
|
|
181
|
+
return bridgeInstance;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Reset the bridge singleton (used in testing).
|
|
185
|
+
*/
|
|
186
|
+
function resetBridge() {
|
|
187
|
+
bridgeInstance?.destroy();
|
|
188
|
+
bridgeInstance = null;
|
|
189
|
+
}
|
|
190
|
+
//# sourceMappingURL=bridge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bridge.js","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-plugin.d.ts","sourceRoot":"","sources":["../../src/cli/create-plugin.ts"],"names":[],"mappings":""}
|