@fias/arche-sdk 2.2.1 → 2.10.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 (57) hide show
  1. package/dist/bridge.d.ts +76 -1
  2. package/dist/bridge.d.ts.map +1 -1
  3. package/dist/bridge.js +219 -6
  4. package/dist/bridge.js.map +1 -1
  5. package/dist/bridge.test.js +155 -6
  6. package/dist/bridge.test.js.map +1 -1
  7. package/dist/coverage-fills.test.js +26 -32
  8. package/dist/coverage-fills.test.js.map +1 -1
  9. package/dist/entity-ops.d.ts +55 -0
  10. package/dist/entity-ops.d.ts.map +1 -0
  11. package/dist/entity-ops.js +48 -0
  12. package/dist/entity-ops.js.map +1 -0
  13. package/dist/fias.d.ts +7 -1
  14. package/dist/fias.d.ts.map +1 -1
  15. package/dist/fias.js +19 -12
  16. package/dist/fias.js.map +1 -1
  17. package/dist/generated/fonts.d.ts.map +1 -1
  18. package/dist/generated/fonts.js +11 -0
  19. package/dist/generated/fonts.js.map +1 -1
  20. package/dist/generated/permissions.d.ts +7 -1
  21. package/dist/generated/permissions.d.ts.map +1 -1
  22. package/dist/generated/permissions.js +36 -1
  23. package/dist/generated/permissions.js.map +1 -1
  24. package/dist/generated/surfaces.d.ts +424 -0
  25. package/dist/generated/surfaces.d.ts.map +1 -1
  26. package/dist/generated/surfaces.js +97 -1
  27. package/dist/generated/surfaces.js.map +1 -1
  28. package/dist/hooks.d.ts +230 -3
  29. package/dist/hooks.d.ts.map +1 -1
  30. package/dist/hooks.js +519 -72
  31. package/dist/hooks.js.map +1 -1
  32. package/dist/hooks.test.js +322 -219
  33. package/dist/hooks.test.js.map +1 -1
  34. package/dist/index.d.ts +4 -4
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js +12 -1
  37. package/dist/index.js.map +1 -1
  38. package/dist/index.mjs +977 -97
  39. package/dist/protocol.d.ts +7 -0
  40. package/dist/protocol.d.ts.map +1 -1
  41. package/dist/protocol.js +7 -0
  42. package/dist/protocol.js.map +1 -1
  43. package/dist/provider.d.ts +50 -1
  44. package/dist/provider.d.ts.map +1 -1
  45. package/dist/provider.js +187 -2
  46. package/dist/provider.js.map +1 -1
  47. package/dist/provider.render.test.d.ts +17 -0
  48. package/dist/provider.render.test.d.ts.map +1 -0
  49. package/dist/provider.render.test.js +191 -0
  50. package/dist/provider.render.test.js.map +1 -0
  51. package/dist/provider.test.js +64 -8
  52. package/dist/provider.test.js.map +1 -1
  53. package/dist/types.d.ts +339 -13
  54. package/dist/types.d.ts.map +1 -1
  55. package/package.json +2 -1
  56. package/templates/default/AGENTS.md +328 -26
  57. package/templates/default/CLAUDE.md +328 -26
@@ -24,9 +24,17 @@ const MockProvider = jest.fn(({ children }) => children);
24
24
  jest.mock('./context', () => ({
25
25
  FiasBridgeContext: { Provider: MockProvider },
26
26
  }));
27
- // Capture React hook calls
28
- let capturedEffectCleanup = null;
27
+ // Capture React hook calls.
28
+ // UPDATED (Phase 6): the provider now has multiple effects (bridge init +
29
+ // unhandledrejection listener) — collect EVERY cleanup and run them all,
30
+ // instead of keeping only the last one (which silently pointed the old
31
+ // single-cleanup tests at whichever effect happened to run last).
32
+ let capturedEffectCleanups = [];
29
33
  const mockSetReady = jest.fn();
34
+ function runAllEffectCleanups() {
35
+ for (const cleanup of capturedEffectCleanups)
36
+ cleanup();
37
+ }
30
38
  jest.mock('react', () => {
31
39
  const actual = jest.requireActual('react');
32
40
  return {
@@ -36,7 +44,7 @@ jest.mock('react', () => {
36
44
  useEffect: jest.fn((cb) => {
37
45
  const cleanup = cb();
38
46
  if (typeof cleanup === 'function') {
39
- capturedEffectCleanup = cleanup;
47
+ capturedEffectCleanups.push(cleanup);
40
48
  }
41
49
  }),
42
50
  };
@@ -44,7 +52,7 @@ jest.mock('react', () => {
44
52
  describe('FiasProvider', () => {
45
53
  beforeEach(() => {
46
54
  jest.clearAllMocks();
47
- capturedEffectCleanup = null;
55
+ capturedEffectCleanups = [];
48
56
  mockBridge.waitForInit.mockResolvedValue(undefined);
49
57
  });
50
58
  it('uses getBridge() singleton via useMemo', () => {
@@ -66,8 +74,8 @@ describe('FiasProvider', () => {
66
74
  it('does NOT call bridge.destroy() on cleanup (StrictMode safety)', () => {
67
75
  const { FiasProvider } = require('./provider');
68
76
  FiasProvider({ children: null });
69
- expect(capturedEffectCleanup).toBeDefined();
70
- capturedEffectCleanup();
77
+ expect(capturedEffectCleanups.length).toBeGreaterThan(0);
78
+ runAllEffectCleanups();
71
79
  expect(mockBridge.destroy).not.toHaveBeenCalled();
72
80
  });
73
81
  it('does not call ready if unmounted before init resolves', async () => {
@@ -77,8 +85,8 @@ describe('FiasProvider', () => {
77
85
  }));
78
86
  const { FiasProvider } = require('./provider');
79
87
  FiasProvider({ children: null });
80
- // Run cleanup before init resolves (simulates unmount)
81
- capturedEffectCleanup();
88
+ // Run cleanups before init resolves (simulates unmount)
89
+ runAllEffectCleanups();
82
90
  resolveInit();
83
91
  await Promise.resolve();
84
92
  await Promise.resolve();
@@ -93,4 +101,52 @@ describe('FiasProvider', () => {
93
101
  expect(result).toBeNull();
94
102
  });
95
103
  });
104
+ describe('PluginErrorBoundary', () => {
105
+ beforeEach(() => {
106
+ jest.clearAllMocks();
107
+ });
108
+ it('getDerivedStateFromError captures the thrown error', () => {
109
+ const { PluginErrorBoundary } = require('./provider');
110
+ const err = new Error('Permission denied: user:profile:read not granted');
111
+ expect(PluginErrorBoundary.getDerivedStateFromError(err)).toEqual({ error: err });
112
+ });
113
+ it('renders children when there is no error', () => {
114
+ const { PluginErrorBoundary } = require('./provider');
115
+ const boundary = new PluginErrorBoundary({ children: 'the-app' });
116
+ boundary.state = { error: null, resetCount: 0 };
117
+ // UPDATED (Phase 6): children are wrapped in a keyed Fragment so a reset
118
+ // (key bump) remounts the crashed subtree instead of reusing its state.
119
+ const rendered = boundary.render();
120
+ expect(rendered.props.children).toBe('the-app');
121
+ expect(rendered.key).toBe('0');
122
+ });
123
+ it('renders the error screen (not children) once an error is captured', () => {
124
+ const { PluginErrorBoundary, FiasErrorScreen } = require('./provider');
125
+ const err = new Error('Permission denied: user:profile:read not granted');
126
+ const boundary = new PluginErrorBoundary({ children: 'the-app' });
127
+ boundary.state = { error: err, resetCount: 0 };
128
+ const rendered = boundary.render();
129
+ expect(rendered.type).toBe(FiasErrorScreen);
130
+ expect(rendered.props.error).toBe(err);
131
+ // The error screen gets a reset handler ("Try again").
132
+ expect(rendered.props.onReset).toBe(boundary.handleReset);
133
+ });
134
+ it('componentDidCatch logs instead of failing silently', () => {
135
+ const { PluginErrorBoundary } = require('./provider');
136
+ const spy = jest.spyOn(console, 'error').mockImplementation(() => { });
137
+ const boundary = new PluginErrorBoundary({ children: null });
138
+ const err = new Error('boom');
139
+ boundary.componentDidCatch(err, { componentStack: '\n at App' });
140
+ expect(spy).toHaveBeenCalledWith(expect.stringContaining('[fias-sdk]'), err, expect.any(String));
141
+ spy.mockRestore();
142
+ });
143
+ it('FiasErrorScreen surfaces the error message', () => {
144
+ const { FiasErrorScreen } = require('./provider');
145
+ const el = FiasErrorScreen({
146
+ error: new Error('Permission denied: user:profile:read not granted'),
147
+ });
148
+ expect(el.props.role).toBe('alert');
149
+ expect(JSON.stringify(el)).toContain('user:profile:read');
150
+ });
151
+ });
96
152
  //# sourceMappingURL=provider.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"provider.test.js","sourceRoot":"","sources":["../src/provider.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"provider.test.js","sourceRoot":"","sources":["../src/provider.test.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -95,6 +95,20 @@ export interface EntityInvocationApi {
95
95
  */
96
96
  streamingText: string;
97
97
  }
98
+ /**
99
+ * Client-side entity invocation API available via the `useClientEntity()`
100
+ * hook. The client-side counterpart to {@link EntityInvocationApi}: invokes
101
+ * an on-device entity (grammar check, background removal, …) by ID through
102
+ * the bridge's generic `client_entity_invoke` op. Requires the
103
+ * `entities:client_invoke` permission. The typed result flows back through
104
+ * the returned promise — supply the entity's input/output types at the call
105
+ * site, e.g. `invoke<GrammarCheckInput, GrammarCheckResult>(id, input)`.
106
+ */
107
+ export interface ClientEntityApi {
108
+ invoke: <TInput = unknown, TResult = unknown>(entityId: string, input: TInput) => Promise<TResult>;
109
+ isLoading: boolean;
110
+ error: Error | null;
111
+ }
98
112
  /**
99
113
  * How a plugin picks a text model for `useEntityInvocation({ entityId, ... })`:
100
114
  *
@@ -114,9 +128,27 @@ export type TextCapabilityId = 'text-fast' | 'text-standard' | 'text-advanced';
114
128
  export type TextEntitySelector = string | {
115
129
  capability: TextCapabilityId;
116
130
  };
131
+ /**
132
+ * An image sent to a vision-capable model alongside `input` (e.g. OCR,
133
+ * chart/figure understanding, visual Q&A). Base64-encoded bytes plus the MIME
134
+ * type — no `data:` prefix.
135
+ */
136
+ export interface EntityInvocationImage {
137
+ /** MIME type, e.g. `'image/jpeg'`, `'image/png'`, `'image/webp'`, `'image/gif'`. */
138
+ mediaType: string;
139
+ /** Base64-encoded image bytes, WITHOUT a `data:<type>;base64,` prefix. */
140
+ dataBase64: string;
141
+ }
117
142
  export interface EntityInvocationParams {
118
143
  entityId: TextEntitySelector;
119
144
  input: string;
145
+ /**
146
+ * Optional image inputs for a vision-capable model. The resolved model must
147
+ * support vision or the call is rejected. Sent together with `input` as a
148
+ * single user message. Billed like any other invocation (the 20% markup
149
+ * applies). Bounded per call — keep images small (downscale before sending).
150
+ */
151
+ images?: EntityInvocationImage[];
120
152
  parameters?: Record<string, unknown>;
121
153
  /** System prompt to send to the AI model. The arche/plugin provides context; the entity provides the capability. */
122
154
  systemPrompt?: string;
@@ -331,6 +363,88 @@ export interface BackgroundRemovalApi {
331
363
  result: Blob | null;
332
364
  error: Error | null;
333
365
  }
366
+ /**
367
+ * Parameters for on-device translation via the `client_entity_invoke` bridge
368
+ * op targeting the NLLB-200 translation entity.
369
+ */
370
+ export interface TranslateParams {
371
+ /** Text to translate. */
372
+ text: string;
373
+ /**
374
+ * Target language as a FLORES-200 code (e.g. `'fra_Latn'`). Pick from
375
+ * `NLLB_LANGUAGES` for a ready-made label/code list.
376
+ */
377
+ targetLang: string;
378
+ /**
379
+ * Source language as a FLORES-200 code. Omit to auto-detect on-device.
380
+ * Supplying it skips detection (faster; avoids misdetection on short text).
381
+ */
382
+ sourceLang?: string;
383
+ }
384
+ /**
385
+ * Result of on-device translation. Produced entirely in the host page by a
386
+ * WASM model — text never leaves the user's device.
387
+ */
388
+ export interface TranslationResult {
389
+ /** The translated text. */
390
+ translation: string;
391
+ /** The FLORES-200 source code actually used (detected, or the one passed in). */
392
+ detectedSourceLang: string;
393
+ }
394
+ /**
395
+ * Issue categories surfaced by the grammar_check client-side entity.
396
+ *
397
+ * NOTE: duplicated from the executor's type (the SDK is dependency-free and
398
+ * cannot import from the platform client). Kept in lockstep by review.
399
+ */
400
+ export type GrammarCategory = 'spelling' | 'grammar' | 'style' | 'readability';
401
+ /** A single grammar/spelling/style/readability issue. */
402
+ export interface GrammarIssue {
403
+ /** Inclusive start character offset into the submitted text. */
404
+ start: number;
405
+ /** Exclusive end character offset into the submitted text. */
406
+ end: number;
407
+ /** Human-readable description of the issue. */
408
+ message: string;
409
+ category: GrammarCategory;
410
+ /** Stable rule identifier, e.g. `retext-spell:colour`. */
411
+ ruleId: string;
412
+ /** Suggested replacements (may be empty). */
413
+ suggestions: string[];
414
+ }
415
+ /** Optional readability summary returned when the readability category is requested. */
416
+ export interface GrammarReadability {
417
+ /** Number of sentences flagged as hard to read. */
418
+ hardToReadSentences: number;
419
+ }
420
+ /** Input to the grammar_check client-side entity. */
421
+ export interface GrammarCheckInput {
422
+ /** The text to check. Capped at 100,000 characters. */
423
+ text: string;
424
+ /** Categories to report. Omitted/empty means all categories. */
425
+ categories?: GrammarCategory[];
426
+ /** Words the user added to their personal dictionary (never flagged as misspelled). */
427
+ customDictionary?: string[];
428
+ }
429
+ /**
430
+ * Result of a grammar check via the `client_entity_invoke` bridge op
431
+ * targeting the grammar_check entity. The text is checked entirely in the
432
+ * host page (no AI, no network) — it never leaves the user's device.
433
+ */
434
+ export interface GrammarCheckResult {
435
+ issues: GrammarIssue[];
436
+ readability?: GrammarReadability;
437
+ }
438
+ /**
439
+ * A selectable language for the NLLB translator: a human label paired with
440
+ * its FLORES-200 code. See `NLLB_LANGUAGES` for the curated list.
441
+ */
442
+ export interface NllbLanguageOption {
443
+ /** Display label, e.g. `'Spanish'`. */
444
+ label: string;
445
+ /** FLORES-200 code, e.g. `'spa_Latn'`. */
446
+ code: string;
447
+ }
334
448
  /**
335
449
  * Audio sub-type discriminator. v1 ships music only; future entries
336
450
  * (`'speech'`, `'sfx'`, ...) extend the unions on `AudioGenerationParams`,
@@ -403,6 +517,23 @@ export interface AudioGenerationApi {
403
517
  */
404
518
  export interface FiasNavigationApi {
405
519
  navigateTo: (path: string) => void;
520
+ /**
521
+ * Navigate the host to ANOTHER arche's page (`/a/<archeId>`).
522
+ *
523
+ * Unlike `navigateTo` (scoped to this arche's own route space), this
524
+ * crosses arches via the host-mediated `open_arche` bridge op. The host
525
+ * validates the id format and performs the navigation itself — the iframe
526
+ * sandbox is never loosened. Requires the `navigation:open_arche`
527
+ * permission in the manifest.
528
+ *
529
+ * @param archeId Target arche id (`arc_<32hex>` or `arche_<slug>`).
530
+ * @param opts.newTab Best-effort open in a new tab (keeps the current arche
531
+ * open). Browsers may block the popup since user activation does not cross
532
+ * the iframe→host boundary; the host falls back to same-tab navigation.
533
+ */
534
+ openArche: (archeId: string, opts?: {
535
+ newTab?: boolean;
536
+ }) => void;
406
537
  currentPath: string;
407
538
  }
408
539
  /**
@@ -719,7 +850,22 @@ export interface ArcheAssetsApi {
719
850
  /**
720
851
  * Message types sent from the plugin iframe to the parent frame.
721
852
  */
722
- export type PluginToHostMessageType = 'ready' | 'resize' | 'toast' | 'get_user' | 'get_theme' | 'storage_read' | 'storage_write' | 'storage_list' | 'storage_delete' | 'entity_invoke' | 'client_entity_invoke' | 'image_generate' | 'entities_list_image' | 'audio_generate' | 'surface_invoke' | 'navigate' | 'data_create_collection' | 'data_list_collections' | 'data_delete_collection' | 'data_put' | 'data_get' | 'data_query' | 'data_delete' | 'store_get_products' | 'store_purchase' | 'store_get_entitlements' | 'store_get_purchase_history' | 'store_restore' | 'store_cancel_subscription' | 'vault_documents_list' | 'vault_documents_read' | 'vault_documents_read_many' | 'vault_documents_download_url' | 'vault_documents_get_urls' | 'vault_documents_search' | 'vault_documents_write' | 'vault_documents_update' | 'vault_documents_delete' | 'vault_documents_attach' | 'vault_documents_detach' | 'vault_documents_upload_init' | 'vault_documents_upload_finalize' | 'arche_assets_list' | 'arche_assets_index' | 'arche_assets_get_url';
853
+ export type PluginToHostMessageType = 'ready' | 'resize' | 'toast' | 'get_user' | 'get_theme' | 'storage_read' | 'storage_write' | 'storage_list' | 'storage_delete' | 'entity_invoke' | 'client_entity_invoke' | 'image_generate' | 'entities_list_image' | 'audio_generate' | 'surface_invoke' | 'navigate' | 'open_arche' | 'data_create_collection' | 'data_list_collections' | 'data_delete_collection' | 'data_put' | 'data_get' | 'data_query' | 'data_delete' | 'data_batch' | 'data_search' | 'workspace_create' | 'workspace_list' | 'workspace_get' | 'workspace_archive' | 'workspace_list_members' | 'workspace_add_member' | 'workspace_update_member' | 'workspace_remove_member' | 'store_get_products' | 'store_purchase' | 'store_get_entitlements' | 'store_get_purchase_history' | 'store_restore' | 'store_cancel_subscription' | 'vault_documents_list' | 'vault_documents_read' | 'vault_documents_read_many' | 'vault_documents_download_url' | 'vault_documents_get_urls' | 'vault_documents_search' | 'vault_documents_write' | 'vault_documents_update' | 'vault_documents_delete' | 'vault_documents_attach' | 'vault_documents_detach' | 'vault_documents_upload_init' | 'vault_documents_upload_finalize' | 'vault_documents_upload' | 'vault_documents_pick' | 'arche_assets_list' | 'arche_assets_index' | 'arche_assets_get_url' | 'preview_state' | 'subscription_unsubscribe';
854
+ /**
855
+ * Why a realtime subscription ended (ADR-012 Phase M4). Closed union so
856
+ * hooks can distinguish terminal endings (`authorization_revoked`,
857
+ * `collection_deleted`) from ones worth resubscribing after conditions
858
+ * change (`limit`, `transport_error`, `lease_expired`).
859
+ */
860
+ export type SubscriptionEndedReason = 'authorization_revoked' | 'lease_expired' | 'collection_deleted' | 'limit' | 'transport_error' | 'unsubscribed';
861
+ /**
862
+ * State reported by useDataSubscription().
863
+ */
864
+ export interface DataSubscriptionState {
865
+ status: 'subscribing' | 'active' | 'ended';
866
+ /** Set once status === 'ended'. */
867
+ endedReason?: SubscriptionEndedReason;
868
+ }
723
869
  /**
724
870
  * Step navigation API available via useStepNavigation() hook.
725
871
  */
@@ -745,7 +891,7 @@ export interface StepNavigationOptions {
745
891
  /**
746
892
  * Message types sent from the parent frame to the plugin iframe.
747
893
  */
748
- export type HostToPluginMessageType = 'init' | 'response' | 'theme_update' | 'navigate_update' | 'step_navigate' | 'stream_token';
894
+ export type HostToPluginMessageType = 'init' | 'response' | 'theme_update' | 'navigate_update' | 'step_navigate' | 'stream_token' | 'preview_state_capture' | 'preview_state_restore' | 'subscription_event' | 'subscription_ended';
749
895
  /**
750
896
  * Base message structure for all bridge communication.
751
897
  */
@@ -762,6 +908,13 @@ export interface BridgeResponse<T = unknown> {
762
908
  messageId: string;
763
909
  payload: T;
764
910
  error?: string;
911
+ /**
912
+ * Machine-readable failure code accompanying `error` (e.g. a server bridge
913
+ * code like `BRIDGE_TOKEN_EXPIRED`, or the host's `BRIDGE_ERROR` fallback).
914
+ * Plain wire field — the SDK constructs a `FiasBridgeError` from
915
+ * `error` + `errorCode` locally; Errors are never structured-cloned.
916
+ */
917
+ errorCode?: string;
765
918
  }
766
919
  /**
767
920
  * Init message sent by the host to the plugin on load.
@@ -771,6 +924,25 @@ export interface BridgeResponse<T = unknown> {
771
924
  * include them still works — the SDK then assumes protocol version 1
772
925
  * (the first published contract).
773
926
  */
927
+ /**
928
+ * Asset URLs for ONE platform-vendored library (see `useFiasVendoredAssets`) —
929
+ * a file-key → absolute-URL map whose keys are defined by that library's
930
+ * registry entry. For `pdfjs-dist`: `mainModule`, `worker`, `cMapUrl`,
931
+ * `standardFontDataUrl`. All URLs share one pinned, immutable CDN version prefix
932
+ * so a library's main module and worker are always the same build.
933
+ */
934
+ export type FiasVendoredLibraryAssets = Record<string, string>;
935
+ /**
936
+ * Self-hosted vendored-library asset URLs, delivered in the init payload to
937
+ * plugins that declare the `sandbox:vendored-libraries` permission. Keyed by
938
+ * import specifier (e.g. `'pdfjs-dist'`). `null`/absent when the host's CDN
939
+ * isn't configured — the plugin then can't load vendored libraries and should
940
+ * degrade gracefully.
941
+ *
942
+ * The shape mirrors `@fias/platform-resources`' registry output, duplicated here
943
+ * so the SDK stays dependency-free (it ships inside plugin iframes).
944
+ */
945
+ export type FiasVendoredAssets = Record<string, FiasVendoredLibraryAssets>;
774
946
  export interface BridgeInitMessage {
775
947
  type: 'init';
776
948
  messageId: string;
@@ -779,6 +951,12 @@ export interface BridgeInitMessage {
779
951
  permissions: PluginPermission[];
780
952
  theme: FiasTheme;
781
953
  currentPath: string;
954
+ /**
955
+ * Self-hosted vendored-library asset URLs (keyed by import specifier) —
956
+ * present only when the plugin declared `sandbox:vendored-libraries` and the
957
+ * host's CDN is configured. Optional for backwards compat with older hosts.
958
+ */
959
+ vendoredAssets?: FiasVendoredAssets | null;
782
960
  /**
783
961
  * Bridge protocol version the HOST speaks. Optional for backwards
784
962
  * compat with hosts pre-dating the versioning work — absence is
@@ -806,6 +984,12 @@ export interface BridgeReadyMessage {
806
984
  payload: {
807
985
  /** Bridge protocol version this SDK speaks. */
808
986
  sdkProtocolVersion: number;
987
+ /**
988
+ * Whether this SDK understands the preview state capture/restore protocol
989
+ * (`preview_state_capture` / `preview_state_restore` / `preview_state`).
990
+ * The host gates capture/restore on this so older SDKs are unaffected.
991
+ */
992
+ supportsPreviewState?: boolean;
809
993
  };
810
994
  }
811
995
  /**
@@ -813,7 +997,14 @@ export interface BridgeReadyMessage {
813
997
  */
814
998
  export interface DataStoreCollection {
815
999
  name: string;
816
- userScope: 'user' | 'shared';
1000
+ userScope: 'user' | 'shared' | 'workspace';
1001
+ /** True when documents are embedded for semantic search (`data:search`). */
1002
+ searchable?: boolean;
1003
+ /** Dot-path into `data` that is embedded; present only when `searchable`. */
1004
+ searchField?: string | null;
1005
+ /** Min workspace role to write / read (workspace-scoped only); null = default. */
1006
+ writeMinRole?: WorkspaceRole | null;
1007
+ readMinRole?: WorkspaceRole | null;
817
1008
  createdAt: string;
818
1009
  }
819
1010
  /**
@@ -859,6 +1050,26 @@ export interface DataStoreQueryResult<T = Record<string, unknown>> {
859
1050
  /** Cursor for next page, or null if no more results */
860
1051
  nextCursor: string | null;
861
1052
  }
1053
+ /**
1054
+ * Options for semantic search over a searchable collection.
1055
+ */
1056
+ export interface DataStoreSearchOptions {
1057
+ /** Max matches (1-50, default 50). */
1058
+ topK?: number;
1059
+ /** Cosine-similarity floor (0-1, default 0.5). */
1060
+ minSimilarity?: number;
1061
+ /** Optional JSONB facet filters applied alongside the vector match. */
1062
+ filters?: DataStoreQueryFilter[];
1063
+ }
1064
+ /**
1065
+ * A single semantic-search match.
1066
+ */
1067
+ export interface DataStoreSearchMatch<T = Record<string, unknown>> {
1068
+ key: string;
1069
+ data: T;
1070
+ /** Cosine similarity in [0, 1]; higher is closer. */
1071
+ similarity: number;
1072
+ }
862
1073
  /**
863
1074
  * Data Store API available via useFiasDataStore() hook.
864
1075
  *
@@ -869,22 +1080,137 @@ export interface DataStoreQueryResult<T = Record<string, unknown>> {
869
1080
  * or 'shared' (all users of the arche share data).
870
1081
  */
871
1082
  export interface FiasDataStoreApi {
872
- /** Create a named collection. Default scope is 'user'. */
1083
+ /**
1084
+ * Create a named collection. Default scope is 'user'. Pass
1085
+ * `searchable: { field }` to make the collection semantically searchable over
1086
+ * a designated text field — documents written to it are embedded
1087
+ * (asynchronously, managed by the platform) and queryable via `search()`.
1088
+ * Searching requires the `data:search` permission.
1089
+ */
873
1090
  createCollection: (name: string, options?: {
874
- userScope?: 'user' | 'shared';
1091
+ userScope?: 'user' | 'shared' | 'workspace';
1092
+ searchable?: {
1093
+ field: string;
1094
+ };
1095
+ /** Workspace-scoped only: raise the min role to write / read this
1096
+ * collection above the default (write ≥ member, read ≥ viewer). */
1097
+ writeMinRole?: WorkspaceRole;
1098
+ readMinRole?: WorkspaceRole;
875
1099
  }) => Promise<DataStoreCollection>;
876
1100
  /** List all collections for this arche. */
877
1101
  listCollections: () => Promise<DataStoreCollection[]>;
878
1102
  /** Delete a collection and all its documents. */
879
1103
  deleteCollection: (name: string) => Promise<void>;
880
- /** Write (upsert) a document by key. */
881
- put: <T extends Record<string, unknown> = Record<string, unknown>>(collection: string, key: string, data: T) => Promise<void>;
882
- /** Get a document by key. Returns null if not found. */
883
- get: <T extends Record<string, unknown> = Record<string, unknown>>(collection: string, key: string) => Promise<T | null>;
884
- /** Query documents with filters, sorting, and pagination. */
885
- query: <T extends Record<string, unknown> = Record<string, unknown>>(collection: string, options?: DataStoreQueryOptions) => Promise<DataStoreQueryResult<T>>;
886
- /** Delete a document by key. */
887
- delete: (collection: string, key: string) => Promise<void>;
1104
+ /**
1105
+ * Write (upsert) a document by key. For a `workspace`-scoped collection pass
1106
+ * `{ workspaceId }`; the caller must be an active member with write access
1107
+ * (owner/admin/member). See {@link FiasWorkspacesApi}.
1108
+ */
1109
+ put: <T extends Record<string, unknown> = Record<string, unknown>>(collection: string, key: string, data: T, options?: DataStoreScopeOptions) => Promise<void>;
1110
+ /** Get a document by key. Returns null if not found. Pass `{ workspaceId }`
1111
+ * for a workspace-scoped collection. */
1112
+ get: <T extends Record<string, unknown> = Record<string, unknown>>(collection: string, key: string, options?: DataStoreScopeOptions) => Promise<T | null>;
1113
+ /** Query documents with filters, sorting, and pagination. For a
1114
+ * `workspace`-scoped collection pass `scope: { workspaceId }`; the caller must
1115
+ * be an active member (any role can read). */
1116
+ query: <T extends Record<string, unknown> = Record<string, unknown>>(collection: string, options?: DataStoreQueryOptions, scope?: DataStoreScopeOptions) => Promise<DataStoreQueryResult<T>>;
1117
+ /**
1118
+ * Semantic search over a `searchable` collection. Charges the caller's
1119
+ * credits for the query embedding. Requires the `data:search` permission. For
1120
+ * a `workspace`-scoped collection pass `scope: { workspaceId }` (any active
1121
+ * member can search).
1122
+ */
1123
+ search: <T extends Record<string, unknown> = Record<string, unknown>>(collection: string, query: string, options?: DataStoreSearchOptions, scope?: DataStoreScopeOptions) => Promise<DataStoreSearchMatch<T>[]>;
1124
+ /** Delete a document by key. Pass `{ workspaceId }` for a workspace-scoped
1125
+ * collection (requires owner/admin/member). */
1126
+ delete: (collection: string, key: string, options?: DataStoreScopeOptions) => Promise<void>;
1127
+ /**
1128
+ * Apply up to 25 put/delete operations in a SINGLE transaction — all-or-
1129
+ * nothing. Use for data-integrity flows (e.g. issuing a ledger entry AND
1130
+ * updating a running total together) where a sequence of separate calls could
1131
+ * leave a half-applied state. A batch may span collections and scopes; any
1132
+ * failure (bad key, role denial, quota) rolls the whole batch back.
1133
+ */
1134
+ batch: (operations: DataStoreBatchOp[]) => Promise<void>;
1135
+ }
1136
+ /** Per-call scope options for workspace-scoped Data Store documents. */
1137
+ export interface DataStoreScopeOptions {
1138
+ /** Target workspace for a `workspace`-scoped collection. */
1139
+ workspaceId?: string;
1140
+ }
1141
+ /**
1142
+ * One write in an atomic batch (see {@link FiasDataStoreApi.batch}). A `put`
1143
+ * upserts a document; a `delete` removes one. `workspaceId` targets a
1144
+ * workspace-scoped collection.
1145
+ */
1146
+ export type DataStoreBatchOp = {
1147
+ op: 'put';
1148
+ collection: string;
1149
+ key: string;
1150
+ data: Record<string, unknown>;
1151
+ workspaceId?: string;
1152
+ } | {
1153
+ op: 'delete';
1154
+ collection: string;
1155
+ key: string;
1156
+ workspaceId?: string;
1157
+ };
1158
+ /** Role a user holds within a workspace, in descending privilege. */
1159
+ export type WorkspaceRole = 'owner' | 'admin' | 'member' | 'viewer';
1160
+ /** A workspace (tenant) the caller belongs to. */
1161
+ export interface DataStoreWorkspace {
1162
+ workspaceId: string;
1163
+ displayName: string;
1164
+ /** The calling user's role in this workspace. */
1165
+ role: WorkspaceRole;
1166
+ createdAt: string;
1167
+ /** Soft-archive timestamp; null while active. */
1168
+ archivedAt: string | null;
1169
+ }
1170
+ /** A member of a workspace. Members are addressed by username — the platform
1171
+ * userId is internal and never exposed to plugins or users. */
1172
+ export interface DataStoreWorkspaceMember {
1173
+ username: string;
1174
+ role: WorkspaceRole;
1175
+ grantedAt: string;
1176
+ /** ISO-8601 expiry, or null for a permanent membership. Owners never expire. */
1177
+ expiresAt: string | null;
1178
+ }
1179
+ /**
1180
+ * Workspace tenancy API available via the `useFiasWorkspaces()` hook.
1181
+ *
1182
+ * Lets a plugin model team/org workspaces with role-gated membership
1183
+ * (owner/admin/member/viewer) over `workspace`-scoped Data Store collections.
1184
+ * The creating user becomes the founding owner. Role rules (enforced server-side):
1185
+ * - owner: manage the workspace + members, read/write docs
1186
+ * - admin: manage members (not owners), read/write docs
1187
+ * - member: read/write docs
1188
+ * - viewer: read docs only
1189
+ * A workspace always keeps at least one owner.
1190
+ *
1191
+ * Requires the `data:workspace` permission in fias-plugin.json. Reading/writing
1192
+ * the workspace's documents additionally uses `useFiasDataStore` (`data:store`)
1193
+ * with the `{ workspaceId }` option.
1194
+ */
1195
+ export interface FiasWorkspacesApi {
1196
+ /** Create a workspace; the caller becomes its owner. */
1197
+ create: (displayName: string) => Promise<DataStoreWorkspace>;
1198
+ /** List the workspaces the caller is an active member of. */
1199
+ list: () => Promise<DataStoreWorkspace[]>;
1200
+ /** Get a single workspace (caller must be a member). */
1201
+ get: (workspaceId: string) => Promise<DataStoreWorkspace>;
1202
+ /** Archive a workspace (owner only). */
1203
+ archive: (workspaceId: string) => Promise<void>;
1204
+ /** List a workspace's members (any member). */
1205
+ listMembers: (workspaceId: string) => Promise<DataStoreWorkspaceMember[]>;
1206
+ /** Add a member by username, with a role (owner/admin; cannot grant above your
1207
+ * own role). Optionally time-bound the membership with an ISO-8601 `expiresAt`
1208
+ * (owners cannot expire). Rejects with `USER_NOT_FOUND` if no such user. */
1209
+ addMember: (workspaceId: string, username: string, role: WorkspaceRole, expiresAt?: string) => Promise<DataStoreWorkspaceMember>;
1210
+ /** Change a member's role by username (owner/admin; keeps the one-owner invariant). */
1211
+ updateMember: (workspaceId: string, username: string, role: WorkspaceRole) => Promise<DataStoreWorkspaceMember>;
1212
+ /** Remove a member by username (owner/admin, or yourself; keeps the one-owner invariant). */
1213
+ removeMember: (workspaceId: string, username: string) => Promise<void>;
888
1214
  }
889
1215
  /**
890
1216
  * IAP product type (mirrors Apple StoreKit).