@fias/arche-sdk 2.11.0 → 2.13.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/dist/bridge.d.ts +27 -1
- package/dist/bridge.d.ts.map +1 -1
- package/dist/bridge.js +58 -0
- package/dist/bridge.js.map +1 -1
- package/dist/bridge.test.js +97 -4
- package/dist/bridge.test.js.map +1 -1
- package/dist/entity-ops.d.ts +24 -2
- package/dist/entity-ops.d.ts.map +1 -1
- package/dist/entity-ops.js +21 -1
- package/dist/entity-ops.js.map +1 -1
- package/dist/fias.d.ts +9 -4
- package/dist/fias.d.ts.map +1 -1
- package/dist/fias.js +15 -8
- package/dist/fias.js.map +1 -1
- package/dist/generated/permissions.d.ts +1 -1
- package/dist/generated/permissions.d.ts.map +1 -1
- package/dist/generated/permissions.js +6 -0
- package/dist/generated/permissions.js.map +1 -1
- package/dist/hooks.d.ts +58 -1
- package/dist/hooks.d.ts.map +1 -1
- package/dist/hooks.js +263 -3
- package/dist/hooks.js.map +1 -1
- package/dist/hooks.test.js +67 -0
- package/dist/hooks.test.js.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +29 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +719 -19
- package/dist/panels.d.ts +213 -0
- package/dist/panels.d.ts.map +1 -0
- package/dist/panels.js +422 -0
- package/dist/panels.js.map +1 -0
- package/dist/panels.test.d.ts +2 -0
- package/dist/panels.test.d.ts.map +1 -0
- package/dist/panels.test.js +127 -0
- package/dist/panels.test.js.map +1 -0
- package/dist/types.d.ts +311 -4
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/templates/default/AGENTS.md +186 -1
- package/templates/default/CLAUDE.md +186 -1
package/dist/fias.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fias.js","sourceRoot":"","sources":["../src/fias.ts"],"names":[],"mappings":";;;AAAA,qCAAqC;AACrC,6CAA0E;
|
|
1
|
+
{"version":3,"file":"fias.js","sourceRoot":"","sources":["../src/fias.ts"],"names":[],"mappings":";;;AAAA,qCAAqC;AACrC,6CAA0E;AAgB1E;;;;;;;;;;;;GAYG;AACU,QAAA,IAAI,GAAG;IAClB;;;;OAIG;IACH,KAAK;QACH,IAAA,kBAAS,GAAE,CAAC,KAAK,EAAE,CAAC;IACtB,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,MAAc;QACnB,IAAA,kBAAS,GAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC7B,CAAC;IAED;;OAEG;IACH,SAAS,CAAC,OAAe,EAAE,UAAoD,MAAM;QACnF,IAAA,kBAAS,GAAE,CAAC,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC1C,CAAC;IAED;;;OAGG;IACH,SAAS,EAAE;QACT,KAAK,CAAC,gBAAgB,CACpB,IAAY,EACZ,OAKC;YAED,MAAM,GAAG,GAAG,MAAM,IAAA,2BAAc,EAC9B,IAAA,kBAAS,GAAE,EACX,uCAA0B,EAC1B,mBAAmB,EACnB;gBACE,IAAI;gBACJ,SAAS,EAAE,OAAO,EAAE,SAAS,IAAI,MAAM;gBACvC,UAAU,EAAE,OAAO,EAAE,UAAU;gBAC/B,WAAW,EAAE,OAAO,EAAE,WAAW;gBACjC,WAAW,EAAE,OAAO,EAAE,WAAW;aAClC,CACF,CAAC;YACF,OAAO,GAAG,CAAC,UAAU,CAAC;QACxB,CAAC;QAED,KAAK,CAAC,eAAe;YACnB,MAAM,GAAG,GAAG,MAAM,IAAA,2BAAc,EAC9B,IAAA,kBAAS,GAAE,EACX,uCAA0B,EAC1B,kBAAkB,CACnB,CAAC;YACF,OAAO,GAAG,CAAC,WAAW,CAAC;QACzB,CAAC;QAED,KAAK,CAAC,gBAAgB,CAAC,IAAY;YACjC,MAAM,IAAA,2BAAc,EAAC,IAAA,kBAAS,GAAE,EAAE,uCAA0B,EAAE,mBAAmB,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/F,CAAC;QAED;qEAC6D;QAC7D,KAAK,CAAC,GAAG,CACP,UAAkB,EAClB,GAAW,EACX,IAAO;YAEP,MAAM,GAAG,GAAG,MAAM,IAAA,2BAAc,EAC9B,IAAA,kBAAS,GAAE,EACX,uCAA0B,EAC1B,KAAK,EACL,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,CAC1B,CAAC;YACF,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC;QACnC,CAAC;QAED,KAAK,CAAC,GAAG,CACP,UAAkB,EAClB,GAAW;YAEX,MAAM,GAAG,GAAG,MAAM,IAAA,2BAAc,EAC9B,IAAA,kBAAS,GAAE,EACX,uCAA0B,EAC1B,KAAK,EACL,EAAE,UAAU,EAAE,GAAG,EAAE,CACpB,CAAC;YACF,OAAO,GAAG,CAAC,IAAI,CAAC;QAClB,CAAC;QAED;qDAC6C;QAC7C,KAAK,CAAC,WAAW,CACf,UAAkB,EAClB,GAAW;YAEX,MAAM,GAAG,GAAG,MAAM,IAAA,2BAAc,EAM7B,IAAA,kBAAS,GAAE,EAAE,uCAA0B,EAAE,KAAK,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC;YACxE,IAAI,GAAG,CAAC,IAAI,KAAK,IAAI,IAAI,GAAG,CAAC,IAAI,KAAK,SAAS;gBAAE,OAAO,IAAI,CAAC;YAC7D,OAAO;gBACL,GAAG,EAAE,GAAG,CAAC,GAAG,IAAI,GAAG;gBACnB,IAAI,EAAE,GAAG,CAAC,IAAI;gBACd,SAAS,EAAE,GAAG,CAAC,SAAS,IAAI,EAAE;gBAC9B,GAAG,CAAC,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC9D,GAAG,CAAC,GAAG,CAAC,sBAAsB,KAAK,SAAS;oBAC1C,CAAC,CAAC,EAAE,sBAAsB,EAAE,GAAG,CAAC,sBAAsB,EAAE;oBACxD,CAAC,CAAC,EAAE,CAAC;aACR,CAAC;QACJ,CAAC;QAED,KAAK,CAAC,KAAK,CACT,UAAkB,EAClB,OAA+B;YAE/B,OAAO,IAAA,2BAAc,EACnB,IAAA,kBAAS,GAAE,EACX,uCAA0B,EAC1B,OAAO,EACP,EAAE,UAAU,EAAE,GAAG,OAAO,EAAE,CAC3B,CAAC;QACJ,CAAC;QAED,KAAK,CAAC,MAAM,CACV,UAAkB,EAClB,KAAa,EACb,OAAgC;YAEhC,MAAM,GAAG,GAAG,MAAM,IAAA,2BAAc,EAC9B,IAAA,kBAAS,GAAE,EACX,uCAA0B,EAC1B,QAAQ,EACR,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,OAAO,EAAE,CAClC,CAAC;YACF,OAAO,GAAG,CAAC,OAAO,CAAC;QACrB,CAAC;QAED,KAAK,CAAC,MAAM,CAAC,UAAkB,EAAE,GAAW;YAC1C,MAAM,IAAA,2BAAc,EAAC,IAAA,kBAAS,GAAE,EAAE,uCAA0B,EAAE,QAAQ,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC;QAC/F,CAAC;QAED;;gEAEwD;QACxD,KAAK,CAAC,KAAK,CACT,UAA8B,EAC9B,OAA+B;YAE/B,MAAM,GAAG,GAAG,MAAM,IAAA,2BAAc,EAC9B,IAAA,kBAAS,GAAE,EACX,uCAA0B,EAC1B,OAAO,EACP;gBACE,UAAU;gBACV,GAAG,CAAC,OAAO,EAAE,aAAa,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACpF,CACF,CAAC;YACF,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC;QACnC,CAAC;KACF;CACO,CAAC"}
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* `tests/architecture/sdk-permissions-match-db-types.test.ts` ensures
|
|
10
10
|
* this file stays in lockstep with the canonical source.
|
|
11
11
|
*/
|
|
12
|
-
export type PluginPermission = 'assets:read' | 'data:search' | 'data:store' | 'data:workspace' | 'entities:audio_generate' | 'entities:client_invoke' | 'entities:image_edit' | 'entities:image_generate' | 'entities:invoke' | 'entities:web_search' | 'navigation:open_arche' | 'sandbox:vendored-libraries' | 'storage:sandbox' | 'store:purchase' | 'theme:read' | 'user:profile:read' | 'vault:documents:read' | 'vault:documents:write' | 'vault:user-documents:read';
|
|
12
|
+
export type PluginPermission = 'ai:actions' | 'assets:community:publish' | 'assets:community:read' | 'assets:read' | 'data:search' | 'data:store' | 'data:workspace' | 'entities:audio_generate' | 'entities:client_invoke' | 'entities:image_edit' | 'entities:image_generate' | 'entities:invoke' | 'entities:web_search' | 'navigation:open_arche' | 'sandbox:vendored-libraries' | 'storage:sandbox' | 'store:purchase' | 'theme:read' | 'user:profile:read' | 'vault:documents:read' | 'vault:documents:write' | 'vault:user-documents:read';
|
|
13
13
|
export declare const VALID_PLUGIN_PERMISSIONS: readonly PluginPermission[];
|
|
14
14
|
export declare function isValidPluginPermission(perm: string): perm is PluginPermission;
|
|
15
15
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../../src/generated/permissions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,MAAM,MAAM,gBAAgB,GACxB,aAAa,GACb,aAAa,GACb,YAAY,GACZ,gBAAgB,GAChB,yBAAyB,GACzB,wBAAwB,GACxB,qBAAqB,GACrB,yBAAyB,GACzB,iBAAiB,GACjB,qBAAqB,GACrB,uBAAuB,GACvB,4BAA4B,GAC5B,iBAAiB,GACjB,gBAAgB,GAChB,YAAY,GACZ,mBAAmB,GACnB,sBAAsB,GACtB,uBAAuB,GACvB,2BAA2B,CAAC;AAEhC,eAAO,MAAM,wBAAwB,EAAE,SAAS,gBAAgB,
|
|
1
|
+
{"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../../src/generated/permissions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,MAAM,MAAM,gBAAgB,GACxB,YAAY,GACZ,0BAA0B,GAC1B,uBAAuB,GACvB,aAAa,GACb,aAAa,GACb,YAAY,GACZ,gBAAgB,GAChB,yBAAyB,GACzB,wBAAwB,GACxB,qBAAqB,GACrB,yBAAyB,GACzB,iBAAiB,GACjB,qBAAqB,GACrB,uBAAuB,GACvB,4BAA4B,GAC5B,iBAAiB,GACjB,gBAAgB,GAChB,YAAY,GACZ,mBAAmB,GACnB,sBAAsB,GACtB,uBAAuB,GACvB,2BAA2B,CAAC;AAEhC,eAAO,MAAM,wBAAwB,EAAE,SAAS,gBAAgB,EAuBtD,CAAC;AAEX,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,IAAI,gBAAgB,CAE9E;AAED;;;;GAIG;AACH,eAAO,MAAM,8BAA8B,EAAE,QAAQ,CAAC,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAAC,CA6BrF,CAAC"}
|
|
@@ -14,6 +14,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
14
14
|
exports.PLUGIN_PERMISSION_DESCRIPTIONS = exports.VALID_PLUGIN_PERMISSIONS = void 0;
|
|
15
15
|
exports.isValidPluginPermission = isValidPluginPermission;
|
|
16
16
|
exports.VALID_PLUGIN_PERMISSIONS = [
|
|
17
|
+
'ai:actions',
|
|
18
|
+
'assets:community:publish',
|
|
19
|
+
'assets:community:read',
|
|
17
20
|
'assets:read',
|
|
18
21
|
'data:search',
|
|
19
22
|
'data:store',
|
|
@@ -43,6 +46,9 @@ function isValidPluginPermission(perm) {
|
|
|
43
46
|
* PLUGIN_PERMISSION_DESCRIPTIONS.
|
|
44
47
|
*/
|
|
45
48
|
exports.PLUGIN_PERMISSION_DESCRIPTIONS = {
|
|
49
|
+
'ai:actions': 'Let Fias AI operate this app for you — only actions you could do yourself in its interface, and risky ones ask you first.',
|
|
50
|
+
'assets:community:publish': 'Share images you made here so other people using this app can see them, and manage what you have shared.',
|
|
51
|
+
'assets:community:read': 'Show you images that other people using this app have shared. Everything shared is checked before anyone can see it.',
|
|
46
52
|
'assets:read': "Show images from this app's published asset library.",
|
|
47
53
|
'data:search': "Search this app's own data semantically — costs credits per search.",
|
|
48
54
|
'data:store': "Save structured data in this app's own private database.",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"permissions.js","sourceRoot":"","sources":["../../src/generated/permissions.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;;;
|
|
1
|
+
{"version":3,"file":"permissions.js","sourceRoot":"","sources":["../../src/generated/permissions.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;;;AAmDH,0DAEC;AA3BY,QAAA,wBAAwB,GAAgC;IACnE,YAAY;IACZ,0BAA0B;IAC1B,uBAAuB;IACvB,aAAa;IACb,aAAa;IACb,YAAY;IACZ,gBAAgB;IAChB,yBAAyB;IACzB,wBAAwB;IACxB,qBAAqB;IACrB,yBAAyB;IACzB,iBAAiB;IACjB,qBAAqB;IACrB,uBAAuB;IACvB,4BAA4B;IAC5B,iBAAiB;IACjB,gBAAgB;IAChB,YAAY;IACZ,mBAAmB;IACnB,sBAAsB;IACtB,uBAAuB;IACvB,2BAA2B;CACnB,CAAC;AAEX,SAAgB,uBAAuB,CAAC,IAAY;IAClD,OAAQ,gCAA8C,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AACxE,CAAC;AAED;;;;GAIG;AACU,QAAA,8BAA8B,GAA+C;IACxF,YAAY,EACV,2HAA2H;IAC7H,0BAA0B,EACxB,0GAA0G;IAC5G,uBAAuB,EACrB,sHAAsH;IACxH,aAAa,EAAE,sDAAsD;IACrE,aAAa,EAAE,qEAAqE;IACpF,YAAY,EAAE,0DAA0D;IACxE,gBAAgB,EAAE,kDAAkD;IACpE,yBAAyB,EAAE,kDAAkD;IAC7E,wBAAwB,EACtB,wEAAwE;IAC1E,qBAAqB,EAAE,+CAA+C;IACtE,yBAAyB,EAAE,mDAAmD;IAC9E,iBAAiB,EAAE,wDAAwD;IAC3E,qBAAqB,EAAE,qDAAqD;IAC5E,uBAAuB,EAAE,8CAA8C;IACvE,4BAA4B,EAC1B,8EAA8E;IAChF,iBAAiB,EAAE,+CAA+C;IAClE,gBAAgB,EAAE,qDAAqD;IACvE,YAAY,EAAE,4BAA4B;IAC1C,mBAAmB,EAAE,mCAAmC;IACxD,sBAAsB,EAAE,uDAAuD;IAC/E,uBAAuB,EAAE,oDAAoD;IAC7E,2BAA2B,EACzB,gJAAgJ;CACnJ,CAAC"}
|
package/dist/hooks.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { FiasUser, FiasTheme, FiasStorageApi, DataSubscriptionState, EntityInvocationApi, ClientEntityApi, ImageGenerationApi, ImageEntityFilter, ImageEntitySummary, NllbLanguageOption, AudioGenerationApi, FiasNavigationApi, StepNavigationApi, StepNavigationOptions, FiasDataStoreApi, FiasWorkspacesApi, FiasStoreApi, VaultDocumentsApi, VaultDocumentDownloadUrl, ArcheAssetsApi } from './types';
|
|
1
|
+
import type { FiasUser, FiasTheme, FiasStorageApi, DataSubscriptionState, EntityInvocationApi, ClientEntityApi, ImageGenerationApi, ImageEntityFilter, ImageEntitySummary, NllbLanguageOption, AudioGenerationApi, FiasNavigationApi, StepNavigationApi, StepNavigationOptions, FiasDataStoreApi, FiasWorkspacesApi, FiasStoreApi, VaultDocumentsApi, VaultDocumentDownloadUrl, ArcheAssetsApi, CommunityAssetsApi, FiasAIActionsDeclaration } from './types';
|
|
2
2
|
/**
|
|
3
3
|
* Access the current user's profile information.
|
|
4
4
|
* Requires the `user:profile:read` permission in fias-plugin.json.
|
|
@@ -455,4 +455,61 @@ export interface VaultUserDocumentsApi {
|
|
|
455
455
|
* `useVaultDocuments` instead.
|
|
456
456
|
*/
|
|
457
457
|
export declare function useVaultUserDocuments(): VaultUserDocumentsApi;
|
|
458
|
+
/**
|
|
459
|
+
* Publish images to this arche's community, and browse what others published.
|
|
460
|
+
*
|
|
461
|
+
* The platform's only cross-user read path: an image published here is visible
|
|
462
|
+
* to every authenticated user of THIS arche (and no other), after it clears
|
|
463
|
+
* moderation. Publishing is free.
|
|
464
|
+
*
|
|
465
|
+
* Two things to design around:
|
|
466
|
+
*
|
|
467
|
+
* 1. **Publishing is not instant.** `publish` returns
|
|
468
|
+
* `status: 'pending_moderation'`; the asset appears in `listCommunity`
|
|
469
|
+
* only once it is approved. Show the author their own pending item via
|
|
470
|
+
* `listMine` rather than optimistically adding it to the community feed.
|
|
471
|
+
* 2. **Store structure in the Data Store, not here.** Which asset belongs on
|
|
472
|
+
* which page/level goes in a `shared`-scope collection holding `assetId`s.
|
|
473
|
+
* Community Assets holds the bytes and nothing queryable.
|
|
474
|
+
*
|
|
475
|
+
* Permissions: `assets:community:read` for browsing and viewing;
|
|
476
|
+
* `assets:community:publish` additionally for publish / unpublish / listMine.
|
|
477
|
+
* A plugin that only DISPLAYS community content should declare only the former.
|
|
478
|
+
*
|
|
479
|
+
* @returns Community assets API.
|
|
480
|
+
*/
|
|
481
|
+
export declare function useCommunityAssets(): CommunityAssetsApi;
|
|
482
|
+
/** Configuration for {@link useFiasAIActions}. */
|
|
483
|
+
export interface FiasAIActionsConfig extends FiasAIActionsDeclaration {
|
|
484
|
+
/**
|
|
485
|
+
* The state snapshot the assistant sees, and `availableWhen` filters
|
|
486
|
+
* against. Keep it SMALL and flag-shaped (`{documentOpen: true}` — publish
|
|
487
|
+
* `hasPages: true`, not a page array): accepted snapshots are embedded in
|
|
488
|
+
* the assistant's system prompt every turn, and the host drops oversized
|
|
489
|
+
* ones outright.
|
|
490
|
+
*/
|
|
491
|
+
state?: Record<string, unknown>;
|
|
492
|
+
/**
|
|
493
|
+
* Perform a dispatched action. Throw/reject to report failure — the
|
|
494
|
+
* assistant AWAITS this before telling the model the action applied, so a
|
|
495
|
+
* batch ("do X to each file") stops on the failing step instead of
|
|
496
|
+
* marching on. ALWAYS re-check preconditions here: `availableWhen`
|
|
497
|
+
* filtering is presentation, and a stale turn can dispatch a hidden verb.
|
|
498
|
+
*/
|
|
499
|
+
onAction: (actionId: string, params: Record<string, unknown>) => void | Promise<unknown>;
|
|
500
|
+
}
|
|
501
|
+
/**
|
|
502
|
+
* Declare Fias AI actions at RUNTIME — the dynamic half of the plugin
|
|
503
|
+
* AI-action plane (`ai:actions` permission; TRUSTED arches only — the host
|
|
504
|
+
* silently ignores runtime declarations from non-trusted arches, whose lane
|
|
505
|
+
* is the manifest `fiasAI` block, fixed at publish and reviewed with the
|
|
506
|
+
* submission). Both lanes merge host-side; the manifest wins id collisions.
|
|
507
|
+
*
|
|
508
|
+
* Pass `null` to declare nothing (e.g. while loading). The declaration and
|
|
509
|
+
* the state snapshot are each re-sent only when their content changes; the
|
|
510
|
+
* host additionally coalesces rapid re-sends trailing-edge (latest wins,
|
|
511
|
+
* applied within ~1s / ~250ms for state) — nothing is lost, but drive
|
|
512
|
+
* declaration changes off real capability changes, not render churn.
|
|
513
|
+
*/
|
|
514
|
+
export declare function useFiasAIActions(config: FiasAIActionsConfig | null): void;
|
|
458
515
|
//# sourceMappingURL=hooks.d.ts.map
|
package/dist/hooks.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,QAAQ,EACR,SAAS,EACT,cAAc,EACd,qBAAqB,EACrB,mBAAmB,EAGnB,eAAe,EACf,kBAAkB,EAGlB,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAGlB,iBAAiB,EACjB,iBAAiB,EACjB,qBAAqB,EACrB,gBAAgB,
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"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"}
|
package/dist/hooks.js
CHANGED
|
@@ -23,6 +23,8 @@ exports.useArcheAssets = useArcheAssets;
|
|
|
23
23
|
exports.useFiasPreviewState = useFiasPreviewState;
|
|
24
24
|
exports.useDataSubscription = useDataSubscription;
|
|
25
25
|
exports.useVaultUserDocuments = useVaultUserDocuments;
|
|
26
|
+
exports.useCommunityAssets = useCommunityAssets;
|
|
27
|
+
exports.useFiasAIActions = useFiasAIActions;
|
|
26
28
|
const react_1 = require("react");
|
|
27
29
|
const react_dom_1 = require("react-dom");
|
|
28
30
|
const context_1 = require("./context");
|
|
@@ -731,6 +733,7 @@ function useFiasDataStore() {
|
|
|
731
733
|
writeMinRole: options?.writeMinRole,
|
|
732
734
|
readMinRole: options?.readMinRole,
|
|
733
735
|
writePolicy: options?.writePolicy,
|
|
736
|
+
constraints: options?.constraints,
|
|
734
737
|
});
|
|
735
738
|
return res.collection;
|
|
736
739
|
}, [bridge]);
|
|
@@ -742,12 +745,13 @@ function useFiasDataStore() {
|
|
|
742
745
|
await (0, entity_ops_1.invokeEntityOp)(bridge, entity_ops_1.PLUGIN_DATASTORE_ENTITY_ID, 'delete_collection', { name });
|
|
743
746
|
}, [bridge]);
|
|
744
747
|
const put = (0, react_1.useCallback)(async (collection, key, data, options) => {
|
|
745
|
-
await (0, entity_ops_1.invokeEntityOp)(bridge, entity_ops_1.PLUGIN_DATASTORE_ENTITY_ID, 'put', {
|
|
748
|
+
const res = await (0, entity_ops_1.invokeEntityOp)(bridge, entity_ops_1.PLUGIN_DATASTORE_ENTITY_ID, 'put', {
|
|
746
749
|
collection,
|
|
747
750
|
key,
|
|
748
751
|
data,
|
|
749
752
|
workspaceId: options?.workspaceId,
|
|
750
753
|
});
|
|
754
|
+
return { version: res?.version };
|
|
751
755
|
}, [bridge]);
|
|
752
756
|
const get = (0, react_1.useCallback)(async (collection, key, options) => {
|
|
753
757
|
const res = await (0, entity_ops_1.invokeEntityOp)(bridge, entity_ops_1.PLUGIN_DATASTORE_ENTITY_ID, 'get', {
|
|
@@ -769,6 +773,7 @@ function useFiasDataStore() {
|
|
|
769
773
|
key: res.key ?? key,
|
|
770
774
|
data: res.data,
|
|
771
775
|
updatedAt: res.updatedAt ?? '',
|
|
776
|
+
...(res.version !== undefined ? { version: res.version } : {}),
|
|
772
777
|
...(res.authoredByCollaborator !== undefined
|
|
773
778
|
? { authoredByCollaborator: res.authoredByCollaborator }
|
|
774
779
|
: {}),
|
|
@@ -797,8 +802,12 @@ function useFiasDataStore() {
|
|
|
797
802
|
workspaceId: options?.workspaceId,
|
|
798
803
|
});
|
|
799
804
|
}, [bridge]);
|
|
800
|
-
const batch = (0, react_1.useCallback)(async (operations) => {
|
|
801
|
-
await (0, entity_ops_1.invokeEntityOp)(bridge, entity_ops_1.PLUGIN_DATASTORE_ENTITY_ID, 'batch', {
|
|
805
|
+
const batch = (0, react_1.useCallback)(async (operations, options) => {
|
|
806
|
+
const res = await (0, entity_ops_1.invokeEntityOp)(bridge, entity_ops_1.PLUGIN_DATASTORE_ENTITY_ID, 'batch', {
|
|
807
|
+
operations,
|
|
808
|
+
...(options?.preconditions?.length ? { preconditions: options.preconditions } : {}),
|
|
809
|
+
});
|
|
810
|
+
return { written: res?.written };
|
|
802
811
|
}, [bridge]);
|
|
803
812
|
return (0, react_1.useMemo)(() => ({
|
|
804
813
|
createCollection,
|
|
@@ -1403,4 +1412,255 @@ function useVaultUserDocuments() {
|
|
|
1403
1412
|
}, [bridge]);
|
|
1404
1413
|
return (0, react_1.useMemo)(() => ({ pick, list, get, getDownloadUrl }), [pick, list, get, getDownloadUrl]);
|
|
1405
1414
|
}
|
|
1415
|
+
/**
|
|
1416
|
+
* Refresh a community-asset URL this many ms before it expires. Larger than the
|
|
1417
|
+
* Vault buffer relative to the TTL (5 min vs 1 h) because a gallery render can
|
|
1418
|
+
* start well before its `<img>` loads finish.
|
|
1419
|
+
*/
|
|
1420
|
+
const COMMUNITY_ASSET_URL_REFRESH_BUFFER_MS = 30000;
|
|
1421
|
+
/**
|
|
1422
|
+
* Module-scoped cache of community-asset signed URLs, keyed by assetId.
|
|
1423
|
+
*
|
|
1424
|
+
* Same reasoning as the Vault download-URL cache above: a React render is not
|
|
1425
|
+
* the right invalidation boundary for something valid for a fixed wall-clock
|
|
1426
|
+
* window.
|
|
1427
|
+
*
|
|
1428
|
+
* Keyed by assetId ALONE, deliberately: this module is loaded inside one
|
|
1429
|
+
* plugin iframe, which runs one arche, so there is no second arche to collide
|
|
1430
|
+
* with. (The signature itself is still bound to the arche server-side — that
|
|
1431
|
+
* boundary does not depend on this cache.)
|
|
1432
|
+
*
|
|
1433
|
+
* Because signatures last only ~5 minutes, this cache is what stops a gallery
|
|
1434
|
+
* from re-minting on every render — while `unpublish` evicts eagerly so a
|
|
1435
|
+
* removed asset stops resolving straight away rather than at TTL.
|
|
1436
|
+
*/
|
|
1437
|
+
const communityAssetUrlCache = new Map();
|
|
1438
|
+
const communityAssetUrlInflight = new Map();
|
|
1439
|
+
/**
|
|
1440
|
+
* Batch resolver behind `getUrl` / `getUrls`.
|
|
1441
|
+
*
|
|
1442
|
+
* Serves what it can from cache, requests only the misses, and dedupes
|
|
1443
|
+
* concurrent requests for the same asset so a burst of mounting `<img>`
|
|
1444
|
+
* components collapses into one round-trip. Ids the server omits (taken down,
|
|
1445
|
+
* not yet published, never existed) are simply absent from the result.
|
|
1446
|
+
*/
|
|
1447
|
+
async function fetchCommunityAssetUrls(bridge, assetIds) {
|
|
1448
|
+
const now = Date.now();
|
|
1449
|
+
const hits = [];
|
|
1450
|
+
const misses = [];
|
|
1451
|
+
for (const assetId of assetIds) {
|
|
1452
|
+
const cached = communityAssetUrlCache.get(assetId);
|
|
1453
|
+
if (cached && now < cached.expiresAt - COMMUNITY_ASSET_URL_REFRESH_BUFFER_MS) {
|
|
1454
|
+
hits.push(cached);
|
|
1455
|
+
}
|
|
1456
|
+
else {
|
|
1457
|
+
misses.push(assetId);
|
|
1458
|
+
}
|
|
1459
|
+
}
|
|
1460
|
+
if (misses.length === 0)
|
|
1461
|
+
return hits;
|
|
1462
|
+
// Coalesce with any in-flight request covering the same asset.
|
|
1463
|
+
const pending = [];
|
|
1464
|
+
const toRequest = [];
|
|
1465
|
+
for (const assetId of misses) {
|
|
1466
|
+
const inflight = communityAssetUrlInflight.get(assetId);
|
|
1467
|
+
if (inflight)
|
|
1468
|
+
pending.push(inflight);
|
|
1469
|
+
else
|
|
1470
|
+
toRequest.push(assetId);
|
|
1471
|
+
}
|
|
1472
|
+
// CHUNKED to the server's cap. `get_urls` is `.max(COMMUNITY_ASSET_MAX_URL_BATCH)`
|
|
1473
|
+
// server-side and Zod rejects the whole request when it is exceeded — so an
|
|
1474
|
+
// un-chunked gallery of 60 images did not render 50 and drop 10, it rendered
|
|
1475
|
+
// NONE. Chunking here rather than surfacing the limit keeps the natural usage
|
|
1476
|
+
// (one book, every page at once) working, which is the case this hook exists
|
|
1477
|
+
// for. Chunks run concurrently; each caches and clears its own ids.
|
|
1478
|
+
for (let i = 0; i < toRequest.length; i += entity_ops_1.COMMUNITY_ASSET_MAX_URL_BATCH) {
|
|
1479
|
+
const chunk = toRequest.slice(i, i + entity_ops_1.COMMUNITY_ASSET_MAX_URL_BATCH);
|
|
1480
|
+
const promise = (0, entity_ops_1.invokeEntityOp)(bridge, entity_ops_1.COMMUNITY_ASSETS_ENTITY_ID, 'get_urls', { assetIds: chunk })
|
|
1481
|
+
.then((res) => {
|
|
1482
|
+
for (const url of res.urls) {
|
|
1483
|
+
communityAssetUrlCache.set(url.assetId, url);
|
|
1484
|
+
}
|
|
1485
|
+
return res.urls;
|
|
1486
|
+
})
|
|
1487
|
+
.finally(() => {
|
|
1488
|
+
for (const assetId of chunk) {
|
|
1489
|
+
communityAssetUrlInflight.delete(assetId);
|
|
1490
|
+
}
|
|
1491
|
+
});
|
|
1492
|
+
for (const assetId of chunk) {
|
|
1493
|
+
communityAssetUrlInflight.set(assetId, promise);
|
|
1494
|
+
}
|
|
1495
|
+
pending.push(promise);
|
|
1496
|
+
}
|
|
1497
|
+
const settled = await Promise.all(pending);
|
|
1498
|
+
const requested = new Set(assetIds);
|
|
1499
|
+
const seen = new Set(hits.map((h) => h.assetId));
|
|
1500
|
+
for (const batch of settled) {
|
|
1501
|
+
for (const url of batch) {
|
|
1502
|
+
// A coalesced in-flight request may cover assets we weren't asked about.
|
|
1503
|
+
if (!requested.has(url.assetId) || seen.has(url.assetId))
|
|
1504
|
+
continue;
|
|
1505
|
+
seen.add(url.assetId);
|
|
1506
|
+
hits.push(url);
|
|
1507
|
+
}
|
|
1508
|
+
}
|
|
1509
|
+
return hits;
|
|
1510
|
+
}
|
|
1511
|
+
/**
|
|
1512
|
+
* Publish images to this arche's community, and browse what others published.
|
|
1513
|
+
*
|
|
1514
|
+
* The platform's only cross-user read path: an image published here is visible
|
|
1515
|
+
* to every authenticated user of THIS arche (and no other), after it clears
|
|
1516
|
+
* moderation. Publishing is free.
|
|
1517
|
+
*
|
|
1518
|
+
* Two things to design around:
|
|
1519
|
+
*
|
|
1520
|
+
* 1. **Publishing is not instant.** `publish` returns
|
|
1521
|
+
* `status: 'pending_moderation'`; the asset appears in `listCommunity`
|
|
1522
|
+
* only once it is approved. Show the author their own pending item via
|
|
1523
|
+
* `listMine` rather than optimistically adding it to the community feed.
|
|
1524
|
+
* 2. **Store structure in the Data Store, not here.** Which asset belongs on
|
|
1525
|
+
* which page/level goes in a `shared`-scope collection holding `assetId`s.
|
|
1526
|
+
* Community Assets holds the bytes and nothing queryable.
|
|
1527
|
+
*
|
|
1528
|
+
* Permissions: `assets:community:read` for browsing and viewing;
|
|
1529
|
+
* `assets:community:publish` additionally for publish / unpublish / listMine.
|
|
1530
|
+
* A plugin that only DISPLAYS community content should declare only the former.
|
|
1531
|
+
*
|
|
1532
|
+
* @returns Community assets API.
|
|
1533
|
+
*/
|
|
1534
|
+
function useCommunityAssets() {
|
|
1535
|
+
const bridge = useBridge();
|
|
1536
|
+
const publish = (0, react_1.useCallback)(async (input) => {
|
|
1537
|
+
const res = await (0, entity_ops_1.invokeEntityOp)(bridge, entity_ops_1.COMMUNITY_ASSETS_ENTITY_ID, 'publish', {
|
|
1538
|
+
fileId: input.fileId,
|
|
1539
|
+
title: input.title,
|
|
1540
|
+
caption: input.caption,
|
|
1541
|
+
tags: input.tags,
|
|
1542
|
+
clientRef: input.clientRef,
|
|
1543
|
+
attributionName: input.attributionName,
|
|
1544
|
+
});
|
|
1545
|
+
return res.asset;
|
|
1546
|
+
}, [bridge]);
|
|
1547
|
+
const publishMany = (0, react_1.useCallback)(async (items) => {
|
|
1548
|
+
// Chunked to the server's cap for the same reason as `getUrls` — over the
|
|
1549
|
+
// limit, Zod rejects the entire call, so "publish this 30-page book"
|
|
1550
|
+
// published nothing rather than the first 20.
|
|
1551
|
+
//
|
|
1552
|
+
// SEQUENTIAL, unlike the URL chunks: each publish normalizes an image,
|
|
1553
|
+
// writes a row and stages bytes to S3, and firing several chunks at once
|
|
1554
|
+
// would push a burst through the per-(user, arche) quota checks and turn
|
|
1555
|
+
// a partial success into a wall of QUOTA_EXCEEDED entries. Items already
|
|
1556
|
+
// fail independently server-side, so results stay per-item either way.
|
|
1557
|
+
const results = [];
|
|
1558
|
+
for (let i = 0; i < items.length; i += entity_ops_1.COMMUNITY_ASSET_MAX_PUBLISH_BATCH) {
|
|
1559
|
+
const res = await (0, entity_ops_1.invokeEntityOp)(bridge, entity_ops_1.COMMUNITY_ASSETS_ENTITY_ID, 'publish_many', { items: items.slice(i, i + entity_ops_1.COMMUNITY_ASSET_MAX_PUBLISH_BATCH) });
|
|
1560
|
+
results.push(...res.results);
|
|
1561
|
+
}
|
|
1562
|
+
return results;
|
|
1563
|
+
}, [bridge]);
|
|
1564
|
+
const unpublish = (0, react_1.useCallback)(async (assetId) => {
|
|
1565
|
+
const res = await (0, entity_ops_1.invokeEntityOp)(bridge, entity_ops_1.COMMUNITY_ASSETS_ENTITY_ID, 'unpublish', { assetId });
|
|
1566
|
+
// Evict eagerly so a removed asset stops resolving from cache now, rather
|
|
1567
|
+
// than up to the signature TTL later.
|
|
1568
|
+
communityAssetUrlCache.delete(assetId);
|
|
1569
|
+
return res.asset;
|
|
1570
|
+
}, [bridge]);
|
|
1571
|
+
const listMine = (0, react_1.useCallback)(async (options) => (0, entity_ops_1.invokeEntityOp)(bridge, entity_ops_1.COMMUNITY_ASSETS_ENTITY_ID, 'list_mine', {
|
|
1572
|
+
limit: options?.limit,
|
|
1573
|
+
cursor: options?.cursor,
|
|
1574
|
+
}), [bridge]);
|
|
1575
|
+
const listCommunity = (0, react_1.useCallback)(async (options) => (0, entity_ops_1.invokeEntityOp)(bridge, entity_ops_1.COMMUNITY_ASSETS_ENTITY_ID, 'list_community', { limit: options?.limit, cursor: options?.cursor, tag: options?.tag }), [bridge]);
|
|
1576
|
+
const get = (0, react_1.useCallback)(async (assetId) => {
|
|
1577
|
+
const res = await (0, entity_ops_1.invokeEntityOp)(bridge, entity_ops_1.COMMUNITY_ASSETS_ENTITY_ID, 'get', { assetId });
|
|
1578
|
+
return res.asset;
|
|
1579
|
+
}, [bridge]);
|
|
1580
|
+
const getUrls = (0, react_1.useCallback)((assetIds) => fetchCommunityAssetUrls(bridge, assetIds), [bridge]);
|
|
1581
|
+
const getUrl = (0, react_1.useCallback)(async (assetId) => {
|
|
1582
|
+
const [url] = await fetchCommunityAssetUrls(bridge, [assetId]);
|
|
1583
|
+
if (!url) {
|
|
1584
|
+
throw new Error(`Community asset ${assetId} is not available`);
|
|
1585
|
+
}
|
|
1586
|
+
return url;
|
|
1587
|
+
}, [bridge]);
|
|
1588
|
+
const report = (0, react_1.useCallback)(async (assetId, reason, details) => (0, entity_ops_1.invokeEntityOp)(bridge, entity_ops_1.COMMUNITY_ASSETS_ENTITY_ID, 'report', { assetId, reason, details }), [bridge]);
|
|
1589
|
+
return (0, react_1.useMemo)(() => ({
|
|
1590
|
+
publish,
|
|
1591
|
+
publishMany,
|
|
1592
|
+
unpublish,
|
|
1593
|
+
listMine,
|
|
1594
|
+
listCommunity,
|
|
1595
|
+
get,
|
|
1596
|
+
getUrl,
|
|
1597
|
+
getUrls,
|
|
1598
|
+
report,
|
|
1599
|
+
}), [publish, publishMany, unpublish, listMine, listCommunity, get, getUrl, getUrls, report]);
|
|
1600
|
+
}
|
|
1601
|
+
/**
|
|
1602
|
+
* Declare Fias AI actions at RUNTIME — the dynamic half of the plugin
|
|
1603
|
+
* AI-action plane (`ai:actions` permission; TRUSTED arches only — the host
|
|
1604
|
+
* silently ignores runtime declarations from non-trusted arches, whose lane
|
|
1605
|
+
* is the manifest `fiasAI` block, fixed at publish and reviewed with the
|
|
1606
|
+
* submission). Both lanes merge host-side; the manifest wins id collisions.
|
|
1607
|
+
*
|
|
1608
|
+
* Pass `null` to declare nothing (e.g. while loading). The declaration and
|
|
1609
|
+
* the state snapshot are each re-sent only when their content changes; the
|
|
1610
|
+
* host additionally coalesces rapid re-sends trailing-edge (latest wins,
|
|
1611
|
+
* applied within ~1s / ~250ms for state) — nothing is lost, but drive
|
|
1612
|
+
* declaration changes off real capability changes, not render churn.
|
|
1613
|
+
*/
|
|
1614
|
+
function useFiasAIActions(config) {
|
|
1615
|
+
const bridge = useBridge();
|
|
1616
|
+
// The handler is registered once per bridge and reads the latest onAction
|
|
1617
|
+
// through a ref — a re-render must not tear down dispatch handling.
|
|
1618
|
+
const onActionRef = (0, react_1.useRef)(config?.onAction ?? null);
|
|
1619
|
+
onActionRef.current = config?.onAction ?? null;
|
|
1620
|
+
(0, react_1.useEffect)(() => {
|
|
1621
|
+
bridge.setAiActionHandler((actionId, params) => {
|
|
1622
|
+
const handler = onActionRef.current;
|
|
1623
|
+
if (!handler) {
|
|
1624
|
+
throw new Error('no Fias AI action handler is currently registered');
|
|
1625
|
+
}
|
|
1626
|
+
return handler(actionId, params);
|
|
1627
|
+
});
|
|
1628
|
+
return () => bridge.setAiActionHandler(null);
|
|
1629
|
+
}, [bridge]);
|
|
1630
|
+
// Declaration — content-diffed via JSON so callers may pass fresh object
|
|
1631
|
+
// literals each render without re-sending (the host throttles this lane).
|
|
1632
|
+
const declarationJson = config
|
|
1633
|
+
? JSON.stringify({ description: config.description, actions: config.actions })
|
|
1634
|
+
: null;
|
|
1635
|
+
(0, react_1.useEffect)(() => {
|
|
1636
|
+
let cancelled = false;
|
|
1637
|
+
void bridge.waitForInit().then(() => {
|
|
1638
|
+
if (cancelled)
|
|
1639
|
+
return;
|
|
1640
|
+
bridge.declareAiActions(declarationJson ? JSON.parse(declarationJson) : null);
|
|
1641
|
+
});
|
|
1642
|
+
return () => {
|
|
1643
|
+
cancelled = true;
|
|
1644
|
+
};
|
|
1645
|
+
}, [bridge, declarationJson]);
|
|
1646
|
+
// Clear the declaration when the consumer unmounts — the assistant must
|
|
1647
|
+
// not keep offering verbs nothing will handle.
|
|
1648
|
+
(0, react_1.useEffect)(() => {
|
|
1649
|
+
return () => bridge.declareAiActions(null);
|
|
1650
|
+
}, [bridge]);
|
|
1651
|
+
// State snapshot — content-diffed like the declaration.
|
|
1652
|
+
const stateJson = config?.state ? JSON.stringify(config.state) : null;
|
|
1653
|
+
(0, react_1.useEffect)(() => {
|
|
1654
|
+
if (stateJson === null)
|
|
1655
|
+
return;
|
|
1656
|
+
let cancelled = false;
|
|
1657
|
+
void bridge.waitForInit().then(() => {
|
|
1658
|
+
if (!cancelled)
|
|
1659
|
+
bridge.sendAiState(JSON.parse(stateJson));
|
|
1660
|
+
});
|
|
1661
|
+
return () => {
|
|
1662
|
+
cancelled = true;
|
|
1663
|
+
};
|
|
1664
|
+
}, [bridge, stateJson]);
|
|
1665
|
+
}
|
|
1406
1666
|
//# sourceMappingURL=hooks.js.map
|