@fias/arche-sdk 2.28.0 → 2.30.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 +42 -6
- package/dist/bridge.d.ts.map +1 -1
- package/dist/bridge.js +93 -2
- package/dist/bridge.js.map +1 -1
- package/dist/bridge.test.js +89 -0
- package/dist/bridge.test.js.map +1 -1
- package/dist/entity-ops.d.ts +27 -1
- package/dist/entity-ops.d.ts.map +1 -1
- package/dist/entity-ops.js +84 -6
- package/dist/entity-ops.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 +10 -0
- package/dist/generated/permissions.js.map +1 -1
- package/dist/generated/surfaces.d.ts +119 -5
- package/dist/generated/surfaces.d.ts.map +1 -1
- package/dist/generated/surfaces.js +14 -6
- package/dist/generated/surfaces.js.map +1 -1
- package/dist/hooks.d.ts +220 -18
- package/dist/hooks.d.ts.map +1 -1
- package/dist/hooks.js +792 -39
- package/dist/hooks.js.map +1 -1
- package/dist/hooks.test.js +702 -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 +24 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +771 -28
- package/dist/limits.d.ts +72 -0
- package/dist/limits.d.ts.map +1 -0
- package/dist/limits.js +75 -0
- package/dist/limits.js.map +1 -0
- package/dist/types.d.ts +720 -10
- package/dist/types.d.ts.map +1 -1
- package/dist/use-fias-access.render.test.d.ts +12 -0
- package/dist/use-fias-access.render.test.d.ts.map +1 -0
- package/dist/use-fias-access.render.test.js +407 -0
- package/dist/use-fias-access.render.test.js.map +1 -0
- package/package.json +3 -2
- package/templates/default/AGENTS.md +391 -13
- package/templates/default/CLAUDE.md +391 -13
package/dist/index.mjs
CHANGED
|
@@ -273,9 +273,17 @@ var FiasBridge = class {
|
|
|
273
273
|
this.vendoredAssets = null;
|
|
274
274
|
this.textModels = null;
|
|
275
275
|
this.textModelListeners = /* @__PURE__ */ new Set();
|
|
276
|
+
this.holder = null;
|
|
277
|
+
this.holderListeners = /* @__PURE__ */ new Set();
|
|
276
278
|
this.currentPath = "";
|
|
279
|
+
// Host-chrome state (useFiasChrome). `null` until init, and from a host
|
|
280
|
+
// older than the chrome lane — `hasChrome` tells the two apart.
|
|
281
|
+
this.chrome = null;
|
|
282
|
+
this.hasChrome = false;
|
|
283
|
+
this.chromeListeners = /* @__PURE__ */ new Set();
|
|
277
284
|
this.hostOrigin = "";
|
|
278
285
|
this.themeListeners = /* @__PURE__ */ new Set();
|
|
286
|
+
this.accessListeners = /* @__PURE__ */ new Set();
|
|
279
287
|
this.navigationListeners = /* @__PURE__ */ new Set();
|
|
280
288
|
this.stepNavigationListeners = /* @__PURE__ */ new Set();
|
|
281
289
|
// Preview-state preservation (preview mode only). Keyed so multiple
|
|
@@ -327,12 +335,21 @@ var FiasBridge = class {
|
|
|
327
335
|
this.theme = mergeThemeWithDefaults(initMsg.payload.theme);
|
|
328
336
|
this.vendoredAssets = initMsg.payload.vendoredAssets ?? null;
|
|
329
337
|
this.textModels = initMsg.payload.textModels ?? null;
|
|
338
|
+
this.holder = initMsg.payload.holder ?? null;
|
|
330
339
|
this.currentPath = initMsg.payload.currentPath;
|
|
340
|
+
this.hasChrome = "chrome" in initMsg.payload;
|
|
341
|
+
this.chrome = initMsg.payload.chrome ?? null;
|
|
331
342
|
this.initialized = true;
|
|
332
343
|
this.initResolve?.();
|
|
333
344
|
for (const listener of this.navigationListeners) {
|
|
334
345
|
listener(this.currentPath);
|
|
335
346
|
}
|
|
347
|
+
for (const listener of this.holderListeners) {
|
|
348
|
+
listener(this.holder);
|
|
349
|
+
}
|
|
350
|
+
for (const listener of this.chromeListeners) {
|
|
351
|
+
listener(this.chrome);
|
|
352
|
+
}
|
|
336
353
|
return;
|
|
337
354
|
}
|
|
338
355
|
if (this.hostOrigin && event.origin !== this.hostOrigin) return;
|
|
@@ -343,6 +360,10 @@ var FiasBridge = class {
|
|
|
343
360
|
}
|
|
344
361
|
return;
|
|
345
362
|
}
|
|
363
|
+
if (data.type === "access_update") {
|
|
364
|
+
for (const listener of this.accessListeners) listener();
|
|
365
|
+
return;
|
|
366
|
+
}
|
|
346
367
|
if (data.type === "text_models_update") {
|
|
347
368
|
if (Array.isArray(data.payload)) {
|
|
348
369
|
this.textModels = data.payload;
|
|
@@ -359,6 +380,16 @@ var FiasBridge = class {
|
|
|
359
380
|
}
|
|
360
381
|
return;
|
|
361
382
|
}
|
|
383
|
+
if (data.type === "chrome_update") {
|
|
384
|
+
if (data.payload && typeof data.payload === "object") {
|
|
385
|
+
this.hasChrome = true;
|
|
386
|
+
this.chrome = data.payload;
|
|
387
|
+
for (const listener of this.chromeListeners) {
|
|
388
|
+
listener(this.chrome);
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
362
393
|
if (data.type === "step_navigate") {
|
|
363
394
|
const { nodeId } = data.payload;
|
|
364
395
|
if (typeof nodeId === "string") {
|
|
@@ -586,6 +617,37 @@ var FiasBridge = class {
|
|
|
586
617
|
getCurrentPath() {
|
|
587
618
|
return this.currentPath;
|
|
588
619
|
}
|
|
620
|
+
/**
|
|
621
|
+
* The host-chrome state, or null before init / from a host without the
|
|
622
|
+
* chrome lane (`hasChromeSupport` tells the two apart). See `useFiasChrome`.
|
|
623
|
+
*/
|
|
624
|
+
getChrome() {
|
|
625
|
+
return this.chrome;
|
|
626
|
+
}
|
|
627
|
+
/** True once a host has delivered chrome state (init or chrome_update). */
|
|
628
|
+
hasChromeSupport() {
|
|
629
|
+
return this.hasChrome;
|
|
630
|
+
}
|
|
631
|
+
/** Called on init and on every chrome_update. */
|
|
632
|
+
onChromeUpdate(listener) {
|
|
633
|
+
this.chromeListeners.add(listener);
|
|
634
|
+
return () => this.chromeListeners.delete(listener);
|
|
635
|
+
}
|
|
636
|
+
/**
|
|
637
|
+
* Set host-chrome state for this arche (fire-and-forget; the host echoes the
|
|
638
|
+
* result as chrome_update). Every present key must be a boolean — the host
|
|
639
|
+
* drops the whole message otherwise. See `useFiasChrome`.
|
|
640
|
+
*/
|
|
641
|
+
setChrome(patch) {
|
|
642
|
+
this.send("chrome_set", patch);
|
|
643
|
+
}
|
|
644
|
+
/**
|
|
645
|
+
* Leave the arche for a host destination — a closed enum, never a URL.
|
|
646
|
+
* See `useFiasChrome`.
|
|
647
|
+
*/
|
|
648
|
+
navigateHost(target) {
|
|
649
|
+
this.send("chrome_navigate", { target });
|
|
650
|
+
}
|
|
589
651
|
/**
|
|
590
652
|
* The live text-model catalog, or null until the host has delivered it (or
|
|
591
653
|
* when the plugin lacks `entities:invoke`). See `useTextModels`.
|
|
@@ -593,6 +655,19 @@ var FiasBridge = class {
|
|
|
593
655
|
getTextModels() {
|
|
594
656
|
return this.textModels;
|
|
595
657
|
}
|
|
658
|
+
/**
|
|
659
|
+
* The workspace the plugin was opened in, or null before init, without
|
|
660
|
+
* `user:profile:read` / `data:workspace`, or from an older host. Fixed for
|
|
661
|
+
* the life of the plugin. See `useFiasHolder`.
|
|
662
|
+
*/
|
|
663
|
+
getHolder() {
|
|
664
|
+
return this.holder;
|
|
665
|
+
}
|
|
666
|
+
/** Called once, when init delivers the holder. */
|
|
667
|
+
onHolderReady(listener) {
|
|
668
|
+
this.holderListeners.add(listener);
|
|
669
|
+
return () => this.holderListeners.delete(listener);
|
|
670
|
+
}
|
|
596
671
|
onTextModelsUpdate(listener) {
|
|
597
672
|
this.textModelListeners.add(listener);
|
|
598
673
|
return () => this.textModelListeners.delete(listener);
|
|
@@ -601,6 +676,14 @@ var FiasBridge = class {
|
|
|
601
676
|
this.themeListeners.add(listener);
|
|
602
677
|
return () => this.themeListeners.delete(listener);
|
|
603
678
|
}
|
|
679
|
+
/**
|
|
680
|
+
* The host says the person's own access may have changed (ADR-034) — after
|
|
681
|
+
* its access sheet changed it. Carries nothing: ask `my_access` again.
|
|
682
|
+
*/
|
|
683
|
+
onAccessUpdate(listener) {
|
|
684
|
+
this.accessListeners.add(listener);
|
|
685
|
+
return () => this.accessListeners.delete(listener);
|
|
686
|
+
}
|
|
604
687
|
onNavigationUpdate(listener) {
|
|
605
688
|
this.navigationListeners.add(listener);
|
|
606
689
|
return () => this.navigationListeners.delete(listener);
|
|
@@ -724,7 +807,9 @@ var FiasBridge = class {
|
|
|
724
807
|
}
|
|
725
808
|
this.pendingRequests.clear();
|
|
726
809
|
this.themeListeners.clear();
|
|
810
|
+
this.accessListeners.clear();
|
|
727
811
|
this.textModelListeners.clear();
|
|
812
|
+
this.holderListeners.clear();
|
|
728
813
|
this.navigationListeners.clear();
|
|
729
814
|
this.stepNavigationListeners.clear();
|
|
730
815
|
this.previewStateProviders.clear();
|
|
@@ -757,7 +842,7 @@ var FiasBridge = class {
|
|
|
757
842
|
/**
|
|
758
843
|
* Listens for the terminal ending of a logical realtime subscription.
|
|
759
844
|
* Reasons are a closed union — `authorization_revoked` and
|
|
760
|
-
* `collection_deleted` are definitive; the rest may be worth a fresh
|
|
845
|
+
* `collection_deleted` (the resource is gone) are definitive; the rest may be worth a fresh
|
|
761
846
|
* subscribe once conditions change.
|
|
762
847
|
*/
|
|
763
848
|
onSubscriptionEnded(subscriptionId, listener) {
|
|
@@ -1068,17 +1153,46 @@ var PLUGIN_WORKSPACES_ENTITY_ID = "ent_intg_plugin_workspaces_00000";
|
|
|
1068
1153
|
var PLUGIN_STORE_ENTITY_ID = "ent_intg_plugin_store_0000000000";
|
|
1069
1154
|
var VAULT_USER_DOCUMENTS_ENTITY_ID = "ent_intg_vault_documents_0000000";
|
|
1070
1155
|
var VAULT_ARCHE_DOCUMENTS_ENTITY_ID = "ent_intg_vault_arche_docs_000000";
|
|
1156
|
+
var VAULT_CREATIVE_ENTITY_ID = "ent_intg_vault_creative_00000000";
|
|
1071
1157
|
var COMMUNITY_ASSETS_ENTITY_ID = "ent_intg_community_assets_000000";
|
|
1072
1158
|
var DOCUMENT_SIGN_ENTITY_ID = "ent_intg_document_sign_000000000";
|
|
1073
1159
|
var COMPANY_EMAIL_SEND_ENTITY_ID = "ent_intg_company_email_send_0000";
|
|
1160
|
+
var CONNECTIONS_ENTITY_ID = "ent_intg_connections_00000000000";
|
|
1161
|
+
var CONNECTIONS_CONNECT_ENTITY_ID = "ent_intg_connections_connect_000";
|
|
1162
|
+
var X_ENTITY_ID = "ent_intg_twitter_000000000000000";
|
|
1163
|
+
var LINKEDIN_ENTITY_ID = "ent_intg_linkedin_00000000000000";
|
|
1164
|
+
var ACTION_CONFIRMATION_ENTITY_ID = "ent_intg_action_confirmation_000";
|
|
1165
|
+
var APP_ACCESS_DIALOG_ENTITY_ID = "ent_intg_app_access_dialog_00000";
|
|
1166
|
+
var CREATIVE_PICKER_ENTITY_ID = "ent_intg_creative_picker_0000000";
|
|
1167
|
+
var SCHEDULED_INVOCATIONS_ENTITY_ID = "ent_intg_scheduled_invocations00";
|
|
1168
|
+
var CONFIRM_TIMEOUT_MS = 10 * 60 * 1e3;
|
|
1169
|
+
var APPROVED_CALL_TIMEOUT_MS = 2 * 60 * 1e3;
|
|
1074
1170
|
var COMMUNITY_ASSET_MAX_URL_BATCH = 50;
|
|
1075
1171
|
var COMMUNITY_ASSET_MAX_PUBLISH_BATCH = 20;
|
|
1076
1172
|
async function invokeEntityOp(bridge, entityId, op, args = {}) {
|
|
1077
|
-
const
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1173
|
+
const payload = { op, ...args };
|
|
1174
|
+
const res = await bridge.request("entity_invoke", { entityId, payload });
|
|
1175
|
+
if (!res.confirmationRequired) return res.output;
|
|
1176
|
+
return confirmAndResend(bridge, entityId, payload, res.confirmationRequired.pendingActionId);
|
|
1177
|
+
}
|
|
1178
|
+
async function confirmAndResend(bridge, entityId, payload, pendingActionId) {
|
|
1179
|
+
const answer = await bridge.request(
|
|
1180
|
+
"client_entity_invoke",
|
|
1181
|
+
{ entityId: ACTION_CONFIRMATION_ENTITY_ID, input: { pendingActionId } },
|
|
1182
|
+
CONFIRM_TIMEOUT_MS
|
|
1183
|
+
);
|
|
1184
|
+
if (answer && "error" in answer) {
|
|
1185
|
+
throw new FiasBridgeError(answer.error.message, answer.error.code);
|
|
1186
|
+
}
|
|
1187
|
+
if (!answer?.approved) {
|
|
1188
|
+
throw new FiasBridgeError("The person declined this action", "USER_DECLINED");
|
|
1189
|
+
}
|
|
1190
|
+
const done = await bridge.request(
|
|
1191
|
+
"entity_invoke",
|
|
1192
|
+
{ entityId, payload, pendingActionId },
|
|
1193
|
+
APPROVED_CALL_TIMEOUT_MS
|
|
1194
|
+
);
|
|
1195
|
+
return done.output;
|
|
1082
1196
|
}
|
|
1083
1197
|
async function invokeStoreOp(bridge, op, args = {}) {
|
|
1084
1198
|
return bridge.request("entity_invoke", {
|
|
@@ -1259,6 +1373,15 @@ function useTextModels() {
|
|
|
1259
1373
|
}, [bridge]);
|
|
1260
1374
|
return models;
|
|
1261
1375
|
}
|
|
1376
|
+
function useFiasHolder() {
|
|
1377
|
+
const bridge = useBridge();
|
|
1378
|
+
const [holder, setHolder] = useState2(bridge.getHolder());
|
|
1379
|
+
useEffect2(() => {
|
|
1380
|
+
setHolder(bridge.getHolder());
|
|
1381
|
+
return bridge.onHolderReady(setHolder);
|
|
1382
|
+
}, [bridge]);
|
|
1383
|
+
return holder;
|
|
1384
|
+
}
|
|
1262
1385
|
var IMAGE_GENERATE_TIMEOUT_MS = 32e4;
|
|
1263
1386
|
function useImageGeneration() {
|
|
1264
1387
|
const bridge = useBridge();
|
|
@@ -1518,6 +1641,72 @@ function usePersistentState(key, initialValue) {
|
|
|
1518
1641
|
);
|
|
1519
1642
|
return [value, setValue];
|
|
1520
1643
|
}
|
|
1644
|
+
var INERT_CHROME = {
|
|
1645
|
+
focusMode: false,
|
|
1646
|
+
focusModeAvailable: false,
|
|
1647
|
+
sidebarAvailable: false,
|
|
1648
|
+
sidebarCollapsed: false,
|
|
1649
|
+
hostExpandedBar: true,
|
|
1650
|
+
hostExpandButton: true
|
|
1651
|
+
};
|
|
1652
|
+
function useFiasChrome() {
|
|
1653
|
+
const bridge = useBridge();
|
|
1654
|
+
const [chrome, setChrome] = useState2(bridge.getChrome());
|
|
1655
|
+
const [supported, setSupported] = useState2(bridge.hasChromeSupport());
|
|
1656
|
+
useEffect2(() => {
|
|
1657
|
+
let cancelled = false;
|
|
1658
|
+
bridge.waitForInit().then(() => {
|
|
1659
|
+
if (cancelled) return;
|
|
1660
|
+
setChrome(bridge.getChrome());
|
|
1661
|
+
setSupported(bridge.hasChromeSupport());
|
|
1662
|
+
});
|
|
1663
|
+
const unsubscribe = bridge.onChromeUpdate((next) => {
|
|
1664
|
+
setChrome(next);
|
|
1665
|
+
setSupported(bridge.hasChromeSupport());
|
|
1666
|
+
});
|
|
1667
|
+
return () => {
|
|
1668
|
+
cancelled = true;
|
|
1669
|
+
unsubscribe();
|
|
1670
|
+
};
|
|
1671
|
+
}, [bridge]);
|
|
1672
|
+
useEffect2(() => {
|
|
1673
|
+
bridge.setChrome({ hostExpandButton: false });
|
|
1674
|
+
}, [bridge]);
|
|
1675
|
+
const setFocusMode = useCallback((on) => bridge.setChrome({ focusMode: on }), [bridge]);
|
|
1676
|
+
const setSidebarCollapsed = useCallback(
|
|
1677
|
+
(collapsed) => bridge.setChrome({ sidebarCollapsed: collapsed }),
|
|
1678
|
+
[bridge]
|
|
1679
|
+
);
|
|
1680
|
+
const setHostExpandedBar = useCallback(
|
|
1681
|
+
(shown) => bridge.setChrome({ hostExpandedBar: shown }),
|
|
1682
|
+
[bridge]
|
|
1683
|
+
);
|
|
1684
|
+
const goToFiasHome = useCallback(() => bridge.navigateHost("home"), [bridge]);
|
|
1685
|
+
const goToWorktop = useCallback(() => bridge.navigateHost("worktop"), [bridge]);
|
|
1686
|
+
const openAssistant = useCallback(() => bridge.openAssistant(), [bridge]);
|
|
1687
|
+
return useMemo2(
|
|
1688
|
+
() => ({
|
|
1689
|
+
...chrome ?? INERT_CHROME,
|
|
1690
|
+
supported: supported && chrome !== null,
|
|
1691
|
+
setFocusMode,
|
|
1692
|
+
setSidebarCollapsed,
|
|
1693
|
+
setHostExpandedBar,
|
|
1694
|
+
goToFiasHome,
|
|
1695
|
+
goToWorktop,
|
|
1696
|
+
openAssistant
|
|
1697
|
+
}),
|
|
1698
|
+
[
|
|
1699
|
+
chrome,
|
|
1700
|
+
supported,
|
|
1701
|
+
setFocusMode,
|
|
1702
|
+
setSidebarCollapsed,
|
|
1703
|
+
setHostExpandedBar,
|
|
1704
|
+
goToFiasHome,
|
|
1705
|
+
goToWorktop,
|
|
1706
|
+
openAssistant
|
|
1707
|
+
]
|
|
1708
|
+
);
|
|
1709
|
+
}
|
|
1521
1710
|
function useStepNavigation(initialStep, options) {
|
|
1522
1711
|
const bridge = useBridge();
|
|
1523
1712
|
const persistKey = options?.persistKey;
|
|
@@ -1619,15 +1808,34 @@ function useFiasDataStore() {
|
|
|
1619
1808
|
"put",
|
|
1620
1809
|
{
|
|
1621
1810
|
collection,
|
|
1622
|
-
key,
|
|
1811
|
+
// No key: the server makes one (collections with audiences, ADR-034).
|
|
1812
|
+
...key !== null ? { key } : {},
|
|
1623
1813
|
data,
|
|
1624
|
-
workspaceId: options?.workspaceId
|
|
1814
|
+
workspaceId: options?.workspaceId,
|
|
1815
|
+
...options?.audience !== void 0 ? { audience: options.audience } : {}
|
|
1625
1816
|
}
|
|
1626
1817
|
);
|
|
1627
|
-
return {
|
|
1818
|
+
return {
|
|
1819
|
+
version: res?.version,
|
|
1820
|
+
...res?.key !== void 0 ? { key: res.key } : {},
|
|
1821
|
+
...res?.audience !== void 0 ? { audience: res.audience } : {}
|
|
1822
|
+
};
|
|
1628
1823
|
},
|
|
1629
1824
|
[bridge]
|
|
1630
1825
|
);
|
|
1826
|
+
const create = useCallback(
|
|
1827
|
+
async (collection, data, options) => {
|
|
1828
|
+
const result = await put(collection, null, data, options);
|
|
1829
|
+
if (result.key === void 0) {
|
|
1830
|
+
throw new FiasBridgeError(
|
|
1831
|
+
"This Fias does not support creating documents in audiences yet",
|
|
1832
|
+
"AUDIENCES_UNAVAILABLE"
|
|
1833
|
+
);
|
|
1834
|
+
}
|
|
1835
|
+
return { ...result, key: result.key };
|
|
1836
|
+
},
|
|
1837
|
+
[put]
|
|
1838
|
+
);
|
|
1631
1839
|
const get = useCallback(
|
|
1632
1840
|
async (collection, key, options) => {
|
|
1633
1841
|
const res = await invokeEntityOp(
|
|
@@ -1637,7 +1845,8 @@ function useFiasDataStore() {
|
|
|
1637
1845
|
{
|
|
1638
1846
|
collection,
|
|
1639
1847
|
key,
|
|
1640
|
-
workspaceId: options?.workspaceId
|
|
1848
|
+
workspaceId: options?.workspaceId,
|
|
1849
|
+
...options?.audience !== void 0 ? { audience: options.audience } : {}
|
|
1641
1850
|
}
|
|
1642
1851
|
);
|
|
1643
1852
|
return res.data;
|
|
@@ -1649,7 +1858,8 @@ function useFiasDataStore() {
|
|
|
1649
1858
|
const res = await invokeEntityOp(bridge, PLUGIN_DATASTORE_ENTITY_ID, "get", {
|
|
1650
1859
|
collection,
|
|
1651
1860
|
key,
|
|
1652
|
-
workspaceId: options?.workspaceId
|
|
1861
|
+
workspaceId: options?.workspaceId,
|
|
1862
|
+
...options?.audience !== void 0 ? { audience: options.audience } : {}
|
|
1653
1863
|
});
|
|
1654
1864
|
if (res.data === null || res.data === void 0) return null;
|
|
1655
1865
|
return {
|
|
@@ -1657,7 +1867,8 @@ function useFiasDataStore() {
|
|
|
1657
1867
|
data: res.data,
|
|
1658
1868
|
updatedAt: res.updatedAt ?? "",
|
|
1659
1869
|
...res.version !== void 0 ? { version: res.version } : {},
|
|
1660
|
-
...res.authoredByCollaborator !== void 0 ? { authoredByCollaborator: res.authoredByCollaborator } : {}
|
|
1870
|
+
...res.authoredByCollaborator !== void 0 ? { authoredByCollaborator: res.authoredByCollaborator } : {},
|
|
1871
|
+
...res.audience !== void 0 ? { audience: res.audience } : {}
|
|
1661
1872
|
};
|
|
1662
1873
|
},
|
|
1663
1874
|
[bridge]
|
|
@@ -1674,7 +1885,8 @@ function useFiasDataStore() {
|
|
|
1674
1885
|
// answered WORKSPACE_REQUIRED, pointing the author at the collection
|
|
1675
1886
|
// rather than at the call. Take the scope arg when it carries one and
|
|
1676
1887
|
// otherwise leave whatever the spread put there.
|
|
1677
|
-
...scope?.workspaceId !== void 0 ? { workspaceId: scope.workspaceId } : {}
|
|
1888
|
+
...scope?.workspaceId !== void 0 ? { workspaceId: scope.workspaceId } : {},
|
|
1889
|
+
...scope?.audience !== void 0 ? { audience: scope.audience } : {}
|
|
1678
1890
|
});
|
|
1679
1891
|
},
|
|
1680
1892
|
[bridge]
|
|
@@ -1690,7 +1902,8 @@ function useFiasDataStore() {
|
|
|
1690
1902
|
query: queryText,
|
|
1691
1903
|
...options,
|
|
1692
1904
|
// See `query` above — never blank a caller-supplied workspaceId.
|
|
1693
|
-
...scope?.workspaceId !== void 0 ? { workspaceId: scope.workspaceId } : {}
|
|
1905
|
+
...scope?.workspaceId !== void 0 ? { workspaceId: scope.workspaceId } : {},
|
|
1906
|
+
...scope?.audience !== void 0 ? { audience: scope.audience } : {}
|
|
1694
1907
|
}
|
|
1695
1908
|
);
|
|
1696
1909
|
return res.matches;
|
|
@@ -1728,6 +1941,7 @@ function useFiasDataStore() {
|
|
|
1728
1941
|
listCollections,
|
|
1729
1942
|
deleteCollection,
|
|
1730
1943
|
put,
|
|
1944
|
+
create,
|
|
1731
1945
|
get,
|
|
1732
1946
|
getDocument,
|
|
1733
1947
|
query,
|
|
@@ -1740,6 +1954,7 @@ function useFiasDataStore() {
|
|
|
1740
1954
|
listCollections,
|
|
1741
1955
|
deleteCollection,
|
|
1742
1956
|
put,
|
|
1957
|
+
create,
|
|
1743
1958
|
get,
|
|
1744
1959
|
getDocument,
|
|
1745
1960
|
query,
|
|
@@ -1763,6 +1978,15 @@ function useFiasWorkspaces() {
|
|
|
1763
1978
|
},
|
|
1764
1979
|
[bridge]
|
|
1765
1980
|
);
|
|
1981
|
+
const openForWorkspace = useCallback(async () => {
|
|
1982
|
+
const res = await invokeEntityOp(
|
|
1983
|
+
bridge,
|
|
1984
|
+
PLUGIN_WORKSPACES_ENTITY_ID,
|
|
1985
|
+
"create",
|
|
1986
|
+
{ forActingHolder: true }
|
|
1987
|
+
);
|
|
1988
|
+
return res.workspace;
|
|
1989
|
+
}, [bridge]);
|
|
1766
1990
|
const list = useCallback(async () => {
|
|
1767
1991
|
const res = await invokeEntityOp(
|
|
1768
1992
|
bridge,
|
|
@@ -1840,10 +2064,237 @@ function useFiasWorkspaces() {
|
|
|
1840
2064
|
[bridge]
|
|
1841
2065
|
);
|
|
1842
2066
|
return useMemo2(
|
|
1843
|
-
() => ({
|
|
1844
|
-
|
|
2067
|
+
() => ({
|
|
2068
|
+
create,
|
|
2069
|
+
openForWorkspace,
|
|
2070
|
+
list,
|
|
2071
|
+
get,
|
|
2072
|
+
archive,
|
|
2073
|
+
listMembers,
|
|
2074
|
+
addMember,
|
|
2075
|
+
updateMember,
|
|
2076
|
+
removeMember
|
|
2077
|
+
}),
|
|
2078
|
+
[
|
|
2079
|
+
create,
|
|
2080
|
+
openForWorkspace,
|
|
2081
|
+
list,
|
|
2082
|
+
get,
|
|
2083
|
+
archive,
|
|
2084
|
+
listMembers,
|
|
2085
|
+
addMember,
|
|
2086
|
+
updateMember,
|
|
2087
|
+
removeMember
|
|
2088
|
+
]
|
|
1845
2089
|
);
|
|
1846
2090
|
}
|
|
2091
|
+
var NO_WORKSPACE_ACCESS_CODES = /* @__PURE__ */ new Set([
|
|
2092
|
+
"NOT_A_MEMBER",
|
|
2093
|
+
"WORKSPACE_NOT_FOUND"
|
|
2094
|
+
]);
|
|
2095
|
+
function useFiasAccess(workspaceId) {
|
|
2096
|
+
const bridge = useBridge();
|
|
2097
|
+
const known = workspaceId ? peekSharedAccess(bridge, workspaceId) : void 0;
|
|
2098
|
+
const [settled, setSettled] = useState2(known?.settled ?? null);
|
|
2099
|
+
const [fetching, setFetching] = useState2(known ? known.fetching : !!workspaceId);
|
|
2100
|
+
useEffect2(() => {
|
|
2101
|
+
if (!workspaceId) return;
|
|
2102
|
+
const shared = sharedAccessFor(bridge, workspaceId);
|
|
2103
|
+
const sync = () => {
|
|
2104
|
+
setSettled(shared.settled);
|
|
2105
|
+
setFetching(shared.fetching);
|
|
2106
|
+
};
|
|
2107
|
+
const unsubscribe = subscribeSharedAccess(shared, sync);
|
|
2108
|
+
askSharedAccess(shared, "ensure");
|
|
2109
|
+
sync();
|
|
2110
|
+
return unsubscribe;
|
|
2111
|
+
}, [bridge, workspaceId]);
|
|
2112
|
+
const refetch = useCallback(() => {
|
|
2113
|
+
if (workspaceId) askSharedAccess(sharedAccessFor(bridge, workspaceId), "again");
|
|
2114
|
+
}, [bridge, workspaceId]);
|
|
2115
|
+
const openAccessDialog = useCallback(async () => {
|
|
2116
|
+
let answer;
|
|
2117
|
+
try {
|
|
2118
|
+
answer = await bridge.request(
|
|
2119
|
+
"client_entity_invoke",
|
|
2120
|
+
{ entityId: APP_ACCESS_DIALOG_ENTITY_ID, input: {} },
|
|
2121
|
+
ACCESS_SHEET_TIMEOUT_MS
|
|
2122
|
+
);
|
|
2123
|
+
} catch (err) {
|
|
2124
|
+
if (err instanceof FiasBridgeError && err.code === "BRIDGE_ERROR" && err.message.includes("no client-side executor")) {
|
|
2125
|
+
throw new FiasBridgeError("Managing access is not available here", "ACCESS_UNAVAILABLE");
|
|
2126
|
+
}
|
|
2127
|
+
throw err;
|
|
2128
|
+
}
|
|
2129
|
+
if (answer && "error" in answer) {
|
|
2130
|
+
throw new FiasBridgeError(answer.error.message, answer.error.code);
|
|
2131
|
+
}
|
|
2132
|
+
const changed = answer?.changed === true;
|
|
2133
|
+
if (changed) refetch();
|
|
2134
|
+
return { changed };
|
|
2135
|
+
}, [bridge, refetch]);
|
|
2136
|
+
const own = workspaceId && settled?.workspaceId === workspaceId ? settled : null;
|
|
2137
|
+
const current = known ? known.settled : own;
|
|
2138
|
+
const access = current?.access ?? null;
|
|
2139
|
+
const error = current?.error ?? null;
|
|
2140
|
+
const isLoading = !!workspaceId && (current === null || (known ? known.fetching : fetching));
|
|
2141
|
+
const can = useCallback(
|
|
2142
|
+
(permission) => access?.mode === "roles" && access.permissions.includes(permission),
|
|
2143
|
+
[access]
|
|
2144
|
+
);
|
|
2145
|
+
const canReadAudience = useCallback(
|
|
2146
|
+
(audience) => access?.mode === "roles" && (access.audiences?.readable.includes(audience) ?? false),
|
|
2147
|
+
[access]
|
|
2148
|
+
);
|
|
2149
|
+
const canDiscloseTo = useCallback(
|
|
2150
|
+
(audience) => access?.mode === "roles" && (access.audiences?.disclosable.includes(audience) ?? false),
|
|
2151
|
+
[access]
|
|
2152
|
+
);
|
|
2153
|
+
return useMemo2(
|
|
2154
|
+
() => ({
|
|
2155
|
+
access,
|
|
2156
|
+
isLoading,
|
|
2157
|
+
error,
|
|
2158
|
+
refetch,
|
|
2159
|
+
can,
|
|
2160
|
+
canReadAudience,
|
|
2161
|
+
canDiscloseTo,
|
|
2162
|
+
openAccessDialog
|
|
2163
|
+
}),
|
|
2164
|
+
[access, isLoading, error, refetch, can, canReadAudience, canDiscloseTo, openAccessDialog]
|
|
2165
|
+
);
|
|
2166
|
+
}
|
|
2167
|
+
var lastAccessAnswers = /* @__PURE__ */ new Map();
|
|
2168
|
+
var FOCUS_REFETCH_MIN_MS = 3e4;
|
|
2169
|
+
var ACCESS_SHEET_TIMEOUT_MS = 30 * 60 * 1e3;
|
|
2170
|
+
var sharedAccessByBridge = /* @__PURE__ */ new WeakMap();
|
|
2171
|
+
function peekSharedAccess(bridge, workspaceId) {
|
|
2172
|
+
return sharedAccessByBridge.get(bridge)?.get(workspaceId);
|
|
2173
|
+
}
|
|
2174
|
+
function sharedAccessFor(bridge, workspaceId) {
|
|
2175
|
+
let byWorkspace = sharedAccessByBridge.get(bridge);
|
|
2176
|
+
if (!byWorkspace) {
|
|
2177
|
+
byWorkspace = /* @__PURE__ */ new Map();
|
|
2178
|
+
sharedAccessByBridge.set(bridge, byWorkspace);
|
|
2179
|
+
}
|
|
2180
|
+
let shared = byWorkspace.get(workspaceId);
|
|
2181
|
+
if (!shared) {
|
|
2182
|
+
shared = {
|
|
2183
|
+
bridge,
|
|
2184
|
+
workspaceId,
|
|
2185
|
+
settled: null,
|
|
2186
|
+
fetching: false,
|
|
2187
|
+
answered: false,
|
|
2188
|
+
answeredAt: 0,
|
|
2189
|
+
inFlight: null,
|
|
2190
|
+
scheduled: false,
|
|
2191
|
+
again: false,
|
|
2192
|
+
listeners: /* @__PURE__ */ new Set(),
|
|
2193
|
+
stopListening: null
|
|
2194
|
+
};
|
|
2195
|
+
byWorkspace.set(workspaceId, shared);
|
|
2196
|
+
}
|
|
2197
|
+
return shared;
|
|
2198
|
+
}
|
|
2199
|
+
function releaseSharedAccess(shared) {
|
|
2200
|
+
if (shared.listeners.size > 0 || shared.inFlight || shared.scheduled) return;
|
|
2201
|
+
const byWorkspace = sharedAccessByBridge.get(shared.bridge);
|
|
2202
|
+
if (byWorkspace?.get(shared.workspaceId) === shared) byWorkspace.delete(shared.workspaceId);
|
|
2203
|
+
}
|
|
2204
|
+
function notifySharedAccess(shared) {
|
|
2205
|
+
for (const listener of Array.from(shared.listeners)) listener();
|
|
2206
|
+
}
|
|
2207
|
+
function subscribeSharedAccess(shared, listener) {
|
|
2208
|
+
shared.listeners.add(listener);
|
|
2209
|
+
if (!shared.stopListening) {
|
|
2210
|
+
const unsubscribe = shared.bridge.onAccessUpdate(() => askSharedAccess(shared, "again"));
|
|
2211
|
+
const onFocus = () => {
|
|
2212
|
+
if (Date.now() - shared.answeredAt >= FOCUS_REFETCH_MIN_MS) {
|
|
2213
|
+
askSharedAccess(shared, "join");
|
|
2214
|
+
}
|
|
2215
|
+
};
|
|
2216
|
+
const win = typeof window === "undefined" ? null : window;
|
|
2217
|
+
win?.addEventListener("focus", onFocus);
|
|
2218
|
+
shared.stopListening = () => {
|
|
2219
|
+
unsubscribe();
|
|
2220
|
+
win?.removeEventListener("focus", onFocus);
|
|
2221
|
+
};
|
|
2222
|
+
}
|
|
2223
|
+
return () => {
|
|
2224
|
+
shared.listeners.delete(listener);
|
|
2225
|
+
if (shared.listeners.size === 0 && shared.stopListening) {
|
|
2226
|
+
shared.stopListening();
|
|
2227
|
+
shared.stopListening = null;
|
|
2228
|
+
}
|
|
2229
|
+
releaseSharedAccess(shared);
|
|
2230
|
+
};
|
|
2231
|
+
}
|
|
2232
|
+
function askSharedAccess(shared, demand) {
|
|
2233
|
+
if (shared.inFlight) {
|
|
2234
|
+
if (demand === "again") shared.again = true;
|
|
2235
|
+
return;
|
|
2236
|
+
}
|
|
2237
|
+
if (shared.scheduled) return;
|
|
2238
|
+
if (demand === "ensure" && shared.answered) return;
|
|
2239
|
+
shared.scheduled = true;
|
|
2240
|
+
void Promise.resolve().then(() => {
|
|
2241
|
+
shared.scheduled = false;
|
|
2242
|
+
startSharedAccess(shared);
|
|
2243
|
+
});
|
|
2244
|
+
}
|
|
2245
|
+
function settleSharedAccess(shared, access) {
|
|
2246
|
+
const answer = JSON.stringify(access);
|
|
2247
|
+
const before = lastAccessAnswers.get(shared.workspaceId);
|
|
2248
|
+
const noAccess = access.mode === "tier" && access.tier === null;
|
|
2249
|
+
if (noAccess || before !== void 0 && before !== answer) clearSdkReadCaches();
|
|
2250
|
+
lastAccessAnswers.set(shared.workspaceId, answer);
|
|
2251
|
+
shared.answered = true;
|
|
2252
|
+
shared.answeredAt = Date.now();
|
|
2253
|
+
shared.settled = { workspaceId: shared.workspaceId, access, error: null };
|
|
2254
|
+
}
|
|
2255
|
+
function startSharedAccess(shared) {
|
|
2256
|
+
if (shared.listeners.size === 0) {
|
|
2257
|
+
releaseSharedAccess(shared);
|
|
2258
|
+
return;
|
|
2259
|
+
}
|
|
2260
|
+
const { bridge, workspaceId } = shared;
|
|
2261
|
+
const background = shared.answered;
|
|
2262
|
+
if (!background) {
|
|
2263
|
+
shared.fetching = true;
|
|
2264
|
+
notifySharedAccess(shared);
|
|
2265
|
+
}
|
|
2266
|
+
shared.inFlight = (async () => {
|
|
2267
|
+
try {
|
|
2268
|
+
const res = await invokeEntityOp(
|
|
2269
|
+
bridge,
|
|
2270
|
+
PLUGIN_WORKSPACES_ENTITY_ID,
|
|
2271
|
+
"my_access",
|
|
2272
|
+
{ workspaceId }
|
|
2273
|
+
);
|
|
2274
|
+
if (shared.listeners.size > 0) settleSharedAccess(shared, res.access);
|
|
2275
|
+
} catch (err) {
|
|
2276
|
+
if (shared.listeners.size === 0) {
|
|
2277
|
+
} else if (err instanceof FiasBridgeError && NO_WORKSPACE_ACCESS_CODES.has(err.code)) {
|
|
2278
|
+
settleSharedAccess(shared, { mode: "tier", workspaceId, tier: null, expiresAt: null });
|
|
2279
|
+
} else if (!background) {
|
|
2280
|
+
shared.settled = {
|
|
2281
|
+
workspaceId,
|
|
2282
|
+
access: null,
|
|
2283
|
+
error: err instanceof Error ? err : new Error(String(err))
|
|
2284
|
+
};
|
|
2285
|
+
}
|
|
2286
|
+
} finally {
|
|
2287
|
+
shared.fetching = false;
|
|
2288
|
+
shared.inFlight = null;
|
|
2289
|
+
if (shared.again) {
|
|
2290
|
+
shared.again = false;
|
|
2291
|
+
askSharedAccess(shared, "again");
|
|
2292
|
+
}
|
|
2293
|
+
notifySharedAccess(shared);
|
|
2294
|
+
releaseSharedAccess(shared);
|
|
2295
|
+
}
|
|
2296
|
+
})();
|
|
2297
|
+
}
|
|
1847
2298
|
function useFiasStore() {
|
|
1848
2299
|
const bridge = useBridge();
|
|
1849
2300
|
const [products, setProducts] = useState2([]);
|
|
@@ -1929,6 +2380,12 @@ function useFiasStore() {
|
|
|
1929
2380
|
var DOWNLOAD_URL_REFRESH_BUFFER_MS = 6e4;
|
|
1930
2381
|
var downloadUrlCache = /* @__PURE__ */ new Map();
|
|
1931
2382
|
var downloadUrlInflight = /* @__PURE__ */ new Map();
|
|
2383
|
+
function clearSdkReadCaches() {
|
|
2384
|
+
downloadUrlGeneration += 1;
|
|
2385
|
+
downloadUrlCache.clear();
|
|
2386
|
+
downloadUrlInflight.clear();
|
|
2387
|
+
}
|
|
2388
|
+
var downloadUrlGeneration = 0;
|
|
1932
2389
|
async function fetchVaultDocumentDownloadUrl(documentId) {
|
|
1933
2390
|
const now = Date.now();
|
|
1934
2391
|
const cached = downloadUrlCache.get(documentId);
|
|
@@ -1938,6 +2395,7 @@ async function fetchVaultDocumentDownloadUrl(documentId) {
|
|
|
1938
2395
|
const inflight = downloadUrlInflight.get(documentId);
|
|
1939
2396
|
if (inflight) return inflight;
|
|
1940
2397
|
const bridge = getBridge();
|
|
2398
|
+
const generation = downloadUrlGeneration;
|
|
1941
2399
|
const promise = bridge.request(
|
|
1942
2400
|
"vault_documents_download_url",
|
|
1943
2401
|
{ documentId }
|
|
@@ -1947,14 +2405,16 @@ async function fetchVaultDocumentDownloadUrl(documentId) {
|
|
|
1947
2405
|
expiresAt: new Date(result.expiresAt).getTime(),
|
|
1948
2406
|
contentType: result.contentType
|
|
1949
2407
|
};
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
2408
|
+
if (generation === downloadUrlGeneration) {
|
|
2409
|
+
downloadUrlCache.set(documentId, {
|
|
2410
|
+
url: normalized.url,
|
|
2411
|
+
expiresAt: normalized.expiresAt,
|
|
2412
|
+
contentType: normalized.contentType
|
|
2413
|
+
});
|
|
2414
|
+
}
|
|
1955
2415
|
return normalized;
|
|
1956
2416
|
}).finally(() => {
|
|
1957
|
-
downloadUrlInflight.delete(documentId);
|
|
2417
|
+
if (downloadUrlInflight.get(documentId) === promise) downloadUrlInflight.delete(documentId);
|
|
1958
2418
|
});
|
|
1959
2419
|
downloadUrlInflight.set(documentId, promise);
|
|
1960
2420
|
return promise;
|
|
@@ -2715,13 +3175,22 @@ function useFiasPreviewState(key, getState, onRestore) {
|
|
|
2715
3175
|
);
|
|
2716
3176
|
}, [bridge, key]);
|
|
2717
3177
|
}
|
|
2718
|
-
function
|
|
3178
|
+
function stableStringify(value) {
|
|
3179
|
+
return JSON.stringify(
|
|
3180
|
+
value,
|
|
3181
|
+
(_key, v) => v && typeof v === "object" && !Array.isArray(v) ? Object.fromEntries(
|
|
3182
|
+
Object.keys(v).sort().map((k) => [k, v[k]])
|
|
3183
|
+
) : v
|
|
3184
|
+
);
|
|
3185
|
+
}
|
|
3186
|
+
function useEntitySubscription(entityId, payload, onInvalidate, options) {
|
|
2719
3187
|
const bridge = useBridge();
|
|
2720
3188
|
const [state, setState] = useState2({ status: "subscribing" });
|
|
2721
3189
|
const onInvalidateRef = useRef(onInvalidate);
|
|
2722
3190
|
onInvalidateRef.current = onInvalidate;
|
|
2723
3191
|
const enabled = options?.enabled ?? true;
|
|
2724
|
-
const
|
|
3192
|
+
const minRefetchIntervalMs = Math.max(0, options?.minRefetchIntervalMs ?? 0);
|
|
3193
|
+
const payloadKey = stableStringify(payload);
|
|
2725
3194
|
useEffect2(() => {
|
|
2726
3195
|
if (!enabled) {
|
|
2727
3196
|
setState({ status: "ended", endedReason: "unsubscribed" });
|
|
@@ -2733,12 +3202,27 @@ function useDataSubscription(collection, onInvalidate, options) {
|
|
|
2733
3202
|
let unsubscribeEnded = null;
|
|
2734
3203
|
let refetching = false;
|
|
2735
3204
|
let trailing = false;
|
|
3205
|
+
let lastRunAt = -Infinity;
|
|
3206
|
+
let intervalTimer = null;
|
|
2736
3207
|
const runInvalidate = async () => {
|
|
2737
|
-
if (refetching) {
|
|
3208
|
+
if (refetching || intervalTimer) {
|
|
3209
|
+
trailing = true;
|
|
3210
|
+
return;
|
|
3211
|
+
}
|
|
3212
|
+
const wait = lastRunAt + minRefetchIntervalMs - Date.now();
|
|
3213
|
+
if (wait > 0) {
|
|
2738
3214
|
trailing = true;
|
|
3215
|
+
intervalTimer = setTimeout(() => {
|
|
3216
|
+
intervalTimer = null;
|
|
3217
|
+
if (trailing && !cancelled) {
|
|
3218
|
+
trailing = false;
|
|
3219
|
+
void runInvalidate();
|
|
3220
|
+
}
|
|
3221
|
+
}, wait);
|
|
2739
3222
|
return;
|
|
2740
3223
|
}
|
|
2741
3224
|
refetching = true;
|
|
3225
|
+
lastRunAt = Date.now();
|
|
2742
3226
|
try {
|
|
2743
3227
|
await onInvalidateRef.current();
|
|
2744
3228
|
} catch {
|
|
@@ -2753,8 +3237,8 @@ function useDataSubscription(collection, onInvalidate, options) {
|
|
|
2753
3237
|
void (async () => {
|
|
2754
3238
|
try {
|
|
2755
3239
|
const res = await bridge.request("entity_invoke", {
|
|
2756
|
-
entityId
|
|
2757
|
-
payload:
|
|
3240
|
+
entityId,
|
|
3241
|
+
payload: JSON.parse(payloadKey)
|
|
2758
3242
|
});
|
|
2759
3243
|
const subscription = res?.output;
|
|
2760
3244
|
if (!subscription || subscription.kind !== "subscription" || typeof subscription.subscriptionId !== "string") {
|
|
@@ -2778,13 +3262,28 @@ function useDataSubscription(collection, onInvalidate, options) {
|
|
|
2778
3262
|
})();
|
|
2779
3263
|
return () => {
|
|
2780
3264
|
cancelled = true;
|
|
3265
|
+
if (intervalTimer) clearTimeout(intervalTimer);
|
|
2781
3266
|
unsubscribeEvent?.();
|
|
2782
3267
|
unsubscribeEnded?.();
|
|
2783
3268
|
if (subscriptionId) bridge.releaseSubscription(subscriptionId);
|
|
2784
3269
|
};
|
|
2785
|
-
}, [bridge,
|
|
3270
|
+
}, [bridge, entityId, payloadKey, enabled, minRefetchIntervalMs]);
|
|
2786
3271
|
return state;
|
|
2787
3272
|
}
|
|
3273
|
+
function useDataSubscription(collection, onInvalidate, options) {
|
|
3274
|
+
const audience = options?.audience;
|
|
3275
|
+
return useEntitySubscription(
|
|
3276
|
+
PLUGIN_DATASTORE_ENTITY_ID,
|
|
3277
|
+
{
|
|
3278
|
+
op: "subscribe",
|
|
3279
|
+
collection,
|
|
3280
|
+
workspaceId: options?.workspaceId,
|
|
3281
|
+
...audience !== void 0 ? { audience } : {}
|
|
3282
|
+
},
|
|
3283
|
+
onInvalidate,
|
|
3284
|
+
{ enabled: options?.enabled }
|
|
3285
|
+
);
|
|
3286
|
+
}
|
|
2788
3287
|
function useVaultUserDocuments() {
|
|
2789
3288
|
const bridge = useBridge();
|
|
2790
3289
|
const pick = useCallback(
|
|
@@ -2984,6 +3483,162 @@ async function fetchCommunityAssetUrls(bridge, assetIds) {
|
|
|
2984
3483
|
}
|
|
2985
3484
|
return hits;
|
|
2986
3485
|
}
|
|
3486
|
+
var CREATIVE_PICKER_TIMEOUT_MS = 30 * 60 * 1e3;
|
|
3487
|
+
function useCreativeLibrary() {
|
|
3488
|
+
const bridge = useBridge();
|
|
3489
|
+
return useMemo2(() => {
|
|
3490
|
+
const item = async (op, args) => (await invokeEntityOp(bridge, VAULT_CREATIVE_ENTITY_ID, op, args)).item;
|
|
3491
|
+
return {
|
|
3492
|
+
list: async (options = {}) => (await invokeEntityOp(
|
|
3493
|
+
bridge,
|
|
3494
|
+
VAULT_CREATIVE_ENTITY_ID,
|
|
3495
|
+
"list_items",
|
|
3496
|
+
{ ...options }
|
|
3497
|
+
)).items,
|
|
3498
|
+
get: (itemId, version) => item("get_item", { itemId, ...version !== void 0 ? { version } : {} }),
|
|
3499
|
+
create: (fields) => item("create_item", { referenceDocumentIds: [], ...fields }),
|
|
3500
|
+
update: (itemId, fields) => item("update_item", { itemId, ...fields }),
|
|
3501
|
+
remove: (itemId) => item("delete_item", { itemId }),
|
|
3502
|
+
restore: (itemId) => item("restore_item", { itemId }),
|
|
3503
|
+
pick: async (options = {}) => {
|
|
3504
|
+
let answer;
|
|
3505
|
+
try {
|
|
3506
|
+
answer = await bridge.request(
|
|
3507
|
+
"client_entity_invoke",
|
|
3508
|
+
{
|
|
3509
|
+
entityId: CREATIVE_PICKER_ENTITY_ID,
|
|
3510
|
+
input: options.kind ? { kind: options.kind } : {}
|
|
3511
|
+
},
|
|
3512
|
+
CREATIVE_PICKER_TIMEOUT_MS
|
|
3513
|
+
);
|
|
3514
|
+
} catch (err) {
|
|
3515
|
+
if (err instanceof FiasBridgeError && err.code === "BRIDGE_ERROR" && err.message.includes("no client-side executor")) {
|
|
3516
|
+
throw new FiasBridgeError(
|
|
3517
|
+
"The Creative Library picker is not available here",
|
|
3518
|
+
"PICKER_UNAVAILABLE"
|
|
3519
|
+
);
|
|
3520
|
+
}
|
|
3521
|
+
throw err;
|
|
3522
|
+
}
|
|
3523
|
+
if (answer && "error" in answer) {
|
|
3524
|
+
throw new FiasBridgeError(answer.error.message, answer.error.code);
|
|
3525
|
+
}
|
|
3526
|
+
return answer;
|
|
3527
|
+
}
|
|
3528
|
+
};
|
|
3529
|
+
}, [bridge]);
|
|
3530
|
+
}
|
|
3531
|
+
var CONNECT_TIMEOUT_MS = 10 * 60 * 1e3;
|
|
3532
|
+
function useFiasConnections() {
|
|
3533
|
+
const bridge = useBridge();
|
|
3534
|
+
const list = useCallback(async () => {
|
|
3535
|
+
const res = await invokeEntityOp(
|
|
3536
|
+
bridge,
|
|
3537
|
+
CONNECTIONS_ENTITY_ID,
|
|
3538
|
+
"list"
|
|
3539
|
+
);
|
|
3540
|
+
return res.connections;
|
|
3541
|
+
}, [bridge]);
|
|
3542
|
+
const connect = useCallback(
|
|
3543
|
+
async (provider) => {
|
|
3544
|
+
const result = await bridge.request(
|
|
3545
|
+
"client_entity_invoke",
|
|
3546
|
+
{ entityId: CONNECTIONS_CONNECT_ENTITY_ID, input: { provider } },
|
|
3547
|
+
CONNECT_TIMEOUT_MS
|
|
3548
|
+
);
|
|
3549
|
+
if (result && "error" in result) {
|
|
3550
|
+
throw new FiasBridgeError(result.error.message, result.error.code);
|
|
3551
|
+
}
|
|
3552
|
+
return result;
|
|
3553
|
+
},
|
|
3554
|
+
[bridge]
|
|
3555
|
+
);
|
|
3556
|
+
const release = useCallback(
|
|
3557
|
+
async (connectionId) => {
|
|
3558
|
+
await invokeEntityOp(bridge, CONNECTIONS_ENTITY_ID, "release", { connectionId });
|
|
3559
|
+
},
|
|
3560
|
+
[bridge]
|
|
3561
|
+
);
|
|
3562
|
+
return useMemo2(() => ({ list, connect, release }), [list, connect, release]);
|
|
3563
|
+
}
|
|
3564
|
+
function useFiasX() {
|
|
3565
|
+
const bridge = useBridge();
|
|
3566
|
+
return useMemo2(
|
|
3567
|
+
() => ({
|
|
3568
|
+
publishPost: (params) => invokeEntityOp(bridge, X_ENTITY_ID, "publish_post", { ...params }),
|
|
3569
|
+
searchUsers: async (connectionId, query, options) => (await invokeEntityOp(bridge, X_ENTITY_ID, "search_users", {
|
|
3570
|
+
connectionId,
|
|
3571
|
+
query,
|
|
3572
|
+
...options
|
|
3573
|
+
})).users,
|
|
3574
|
+
getUserPosts: async (connectionId, options) => (await invokeEntityOp(bridge, X_ENTITY_ID, "get_user_posts", {
|
|
3575
|
+
connectionId,
|
|
3576
|
+
...options
|
|
3577
|
+
})).posts,
|
|
3578
|
+
getPostMetrics: async (connectionId, postIds) => (await invokeEntityOp(
|
|
3579
|
+
bridge,
|
|
3580
|
+
X_ENTITY_ID,
|
|
3581
|
+
"get_post_metrics",
|
|
3582
|
+
{ connectionId, postIds }
|
|
3583
|
+
)).metrics,
|
|
3584
|
+
getAccountStats: (connectionId) => invokeEntityOp(bridge, X_ENTITY_ID, "get_account_stats", {
|
|
3585
|
+
connectionId
|
|
3586
|
+
})
|
|
3587
|
+
}),
|
|
3588
|
+
[bridge]
|
|
3589
|
+
);
|
|
3590
|
+
}
|
|
3591
|
+
function useFiasSchedules() {
|
|
3592
|
+
const bridge = useBridge();
|
|
3593
|
+
return useMemo2(
|
|
3594
|
+
() => ({
|
|
3595
|
+
schedule: (params) => invokeEntityOp(
|
|
3596
|
+
bridge,
|
|
3597
|
+
SCHEDULED_INVOCATIONS_ENTITY_ID,
|
|
3598
|
+
"schedule",
|
|
3599
|
+
{
|
|
3600
|
+
entityId: params.entityId,
|
|
3601
|
+
verb: params.verb,
|
|
3602
|
+
payload: params.payload,
|
|
3603
|
+
fireAt: params.fireAt instanceof Date ? params.fireAt.toISOString() : params.fireAt
|
|
3604
|
+
}
|
|
3605
|
+
),
|
|
3606
|
+
list: async (options) => (await invokeEntityOp(
|
|
3607
|
+
bridge,
|
|
3608
|
+
SCHEDULED_INVOCATIONS_ENTITY_ID,
|
|
3609
|
+
"list",
|
|
3610
|
+
{
|
|
3611
|
+
...options?.limit !== void 0 ? { limit: options.limit } : {},
|
|
3612
|
+
...options?.scheduleIds ? { scheduleIds: options.scheduleIds } : {}
|
|
3613
|
+
}
|
|
3614
|
+
)).schedules,
|
|
3615
|
+
cancel: async (scheduleId) => {
|
|
3616
|
+
await invokeEntityOp(bridge, SCHEDULED_INVOCATIONS_ENTITY_ID, "cancel", { scheduleId });
|
|
3617
|
+
}
|
|
3618
|
+
}),
|
|
3619
|
+
[bridge]
|
|
3620
|
+
);
|
|
3621
|
+
}
|
|
3622
|
+
function useFiasLinkedIn() {
|
|
3623
|
+
const bridge = useBridge();
|
|
3624
|
+
return useMemo2(
|
|
3625
|
+
() => ({
|
|
3626
|
+
publishPost: (params) => invokeEntityOp(
|
|
3627
|
+
bridge,
|
|
3628
|
+
LINKEDIN_ENTITY_ID,
|
|
3629
|
+
"publish_post",
|
|
3630
|
+
{ ...params }
|
|
3631
|
+
),
|
|
3632
|
+
searchOrganizations: async (connectionId, vanityName) => (await invokeEntityOp(
|
|
3633
|
+
bridge,
|
|
3634
|
+
LINKEDIN_ENTITY_ID,
|
|
3635
|
+
"search_organizations",
|
|
3636
|
+
{ connectionId, query: vanityName }
|
|
3637
|
+
)).organizations
|
|
3638
|
+
}),
|
|
3639
|
+
[bridge]
|
|
3640
|
+
);
|
|
3641
|
+
}
|
|
2987
3642
|
function useCompanyEmail() {
|
|
2988
3643
|
const bridge = useBridge();
|
|
2989
3644
|
const send = useCallback(
|
|
@@ -3227,6 +3882,8 @@ var AUDIO_VOICE_DESIGN_SURFACE_KEY = "audio.voice-design";
|
|
|
3227
3882
|
var useElevenLabsVoiceDesign = () => useSurface(
|
|
3228
3883
|
AUDIO_VOICE_DESIGN_SURFACE_KEY
|
|
3229
3884
|
);
|
|
3885
|
+
var IMAGE_CREATE_ASSET_SURFACE_KEY = "image.create-asset";
|
|
3886
|
+
var useCreateAsset = () => useSurface(IMAGE_CREATE_ASSET_SURFACE_KEY);
|
|
3230
3887
|
var IMAGE_SMART_CONTROL_SURFACE_KEY = "image.smart-control";
|
|
3231
3888
|
var useSmartControl = () => useSurface(IMAGE_SMART_CONTROL_SURFACE_KEY);
|
|
3232
3889
|
var IMAGE_SMART_ERASE_SURFACE_KEY = "image.smart-erase";
|
|
@@ -3270,6 +3927,7 @@ var VALID_PLUGIN_PERMISSIONS = [
|
|
|
3270
3927
|
"assets:community:publish",
|
|
3271
3928
|
"assets:community:read",
|
|
3272
3929
|
"assets:read",
|
|
3930
|
+
"connections:use",
|
|
3273
3931
|
"data:agents",
|
|
3274
3932
|
"data:search",
|
|
3275
3933
|
"data:store",
|
|
@@ -3282,14 +3940,18 @@ var VALID_PLUGIN_PERMISSIONS = [
|
|
|
3282
3940
|
"entities:image_generate",
|
|
3283
3941
|
"entities:invoke",
|
|
3284
3942
|
"entities:web_search",
|
|
3943
|
+
"litcraft:hub",
|
|
3285
3944
|
"navigation:open_arche",
|
|
3286
3945
|
"sandbox:vendored-libraries",
|
|
3946
|
+
"schedule:invoke",
|
|
3287
3947
|
"storage:local",
|
|
3288
3948
|
"storage:sandbox",
|
|
3289
3949
|
"store:purchase",
|
|
3290
3950
|
"theme:read",
|
|
3291
3951
|
"user:profile:read",
|
|
3292
3952
|
"vault:arche-saves:write",
|
|
3953
|
+
"vault:creative:read",
|
|
3954
|
+
"vault:creative:write",
|
|
3293
3955
|
"vault:documents:read",
|
|
3294
3956
|
"vault:documents:write",
|
|
3295
3957
|
"vault:user-documents:edit",
|
|
@@ -3305,6 +3967,7 @@ var PLUGIN_PERMISSION_DESCRIPTIONS = {
|
|
|
3305
3967
|
"assets:community:publish": "Share images you made here so other people using this arche can see them, and manage what you have shared.",
|
|
3306
3968
|
"assets:community:read": "Show you images that other people using this arche have shared. Everything shared is checked before anyone can see it.",
|
|
3307
3969
|
"assets:read": "Show images and play sounds from this arche's published asset library.",
|
|
3970
|
+
"connections:use": "Use outside accounts (like X or LinkedIn) that you connect and let it use \u2014 you choose each account and each workspace, approve what it posts, and can take access away any time in Workspace Controls.",
|
|
3308
3971
|
"data:agents": "Let Fias AI, and assistants you connect with an API key and allow here, read this arche's data \u2014 and change it where it says so \u2014 even while it is closed.",
|
|
3309
3972
|
"data:search": "Search this arche's own data semantically \u2014 costs credits per search.",
|
|
3310
3973
|
"data:store": "Save structured data in this arche's own private database.",
|
|
@@ -3317,14 +3980,18 @@ var PLUGIN_PERMISSION_DESCRIPTIONS = {
|
|
|
3317
3980
|
"entities:image_generate": "Generate images with platform AI \u2014 costs credits.",
|
|
3318
3981
|
"entities:invoke": "Use platform AI (text) on your behalf \u2014 costs credits.",
|
|
3319
3982
|
"entities:web_search": "Search the live web on your behalf \u2014 costs credits.",
|
|
3983
|
+
"litcraft:hub": "See your LitCraft profile, stats and inventory, and the LitCraft community leaderboards, play time and activity. It can hide your name on leaderboards, but only you can show it again.",
|
|
3320
3984
|
"navigation:open_arche": "Open other arches for you (navigation only).",
|
|
3321
3985
|
"sandbox:vendored-libraries": "Load platform-hosted libraries (like the PDF renderer) from the trusted CDN.",
|
|
3986
|
+
"schedule:invoke": "Schedule an action for later \u2014 like a post at 9 AM tomorrow. You approve exactly what will be sent and when, and can see or cancel what it scheduled.",
|
|
3322
3987
|
"storage:local": "Keep its working files on this device, so a refresh or crash does not lose your work. Nothing leaves your device; cleared when you sign out or when someone else signs in here.",
|
|
3323
3988
|
"storage:sandbox": "Save files in this arche's own private storage.",
|
|
3324
3989
|
"store:purchase": "Offer purchases inside the arche (you approve each purchase).",
|
|
3325
3990
|
"theme:read": "Match your platform theme.",
|
|
3326
3991
|
"user:profile:read": "See your display name and avatar.",
|
|
3327
3992
|
"vault:arche-saves:write": "Saves files to your Arche Saves automatically.",
|
|
3993
|
+
"vault:creative:read": "See and use your styles and characters, including their reference pictures \u2014 in a team workspace only after its owner or admin approves it there.",
|
|
3994
|
+
"vault:creative:write": "Create and change your styles and characters. Earlier versions are kept.",
|
|
3328
3995
|
"vault:documents:read": "Read files this arche itself created, in its own folders of your Vault.",
|
|
3329
3996
|
"vault:documents:write": "Create and manage its own files, in its own folder of your Vault.",
|
|
3330
3997
|
"vault:user-documents:edit": "Save changes to files of yours that you let it edit \u2014 you choose each file, earlier versions are kept unless you turned version history off, and you can remove access any time in Vault \u2192 Arche Access.",
|
|
@@ -5416,6 +6083,63 @@ function useFiasFonts() {
|
|
|
5416
6083
|
return useMemo3(() => ({ fonts: FONT_CATALOG, ensureFontLoaded }), []);
|
|
5417
6084
|
}
|
|
5418
6085
|
|
|
6086
|
+
// src/limits.ts
|
|
6087
|
+
var X_PUBLISH_LIMITS = {
|
|
6088
|
+
MAX_TEXT_CHARACTERS: 25e3,
|
|
6089
|
+
MAX_IMAGES_PER_POST: 4,
|
|
6090
|
+
MAX_IMAGES_PER_PUBLISH: 4,
|
|
6091
|
+
MAX_THREAD_POSTS: 10,
|
|
6092
|
+
MIN_POLL_OPTIONS: 2,
|
|
6093
|
+
MAX_POLL_OPTIONS: 4,
|
|
6094
|
+
MAX_POLL_OPTION_CHARACTERS: 25,
|
|
6095
|
+
MIN_POLL_MINUTES: 5,
|
|
6096
|
+
MAX_POLL_MINUTES: 10080,
|
|
6097
|
+
IMAGE_MIME_TYPES: ["image/png", "image/jpeg", "image/webp", "image/gif"],
|
|
6098
|
+
MAX_IMAGE_BYTES: 5 * 1024 * 1024
|
|
6099
|
+
};
|
|
6100
|
+
var LINKEDIN_PUBLISH_LIMITS = {
|
|
6101
|
+
MAX_TEXT_CHARACTERS: 3e3,
|
|
6102
|
+
MAX_IMAGES: 9,
|
|
6103
|
+
IMAGE_MIME_TYPES: ["image/png", "image/jpeg", "image/gif"],
|
|
6104
|
+
MAX_IMAGE_BYTES: 8 * 1024 * 1024
|
|
6105
|
+
};
|
|
6106
|
+
var SCHEDULE_LIMITS = {
|
|
6107
|
+
/** Waiting at once, per person, per app. */
|
|
6108
|
+
MAX_ACTIVE_PER_USER_ARCHE: 25,
|
|
6109
|
+
/** The earliest a call may be scheduled, from now. */
|
|
6110
|
+
MIN_LEAD_SECONDS: 5 * 60,
|
|
6111
|
+
/** The latest, from now. */
|
|
6112
|
+
MAX_LEAD_DAYS: 60
|
|
6113
|
+
};
|
|
6114
|
+
var DATA_STORE_LIMITS = {
|
|
6115
|
+
/** One document's `data`, serialized. */
|
|
6116
|
+
MAX_DOCUMENT_SIZE_BYTES: 100 * 1024,
|
|
6117
|
+
/** Per owner — one user, one workspace, or the app's shared data — per collection. */
|
|
6118
|
+
MAX_DOCUMENTS_PER_OWNER_PER_COLLECTION: 1e4,
|
|
6119
|
+
/** Writes in one atomic `batch`. */
|
|
6120
|
+
MAX_BATCH_OPERATIONS: 100
|
|
6121
|
+
};
|
|
6122
|
+
var DATA_STORE_RATE_LIMITS_PER_MINUTE = {
|
|
6123
|
+
put: 120,
|
|
6124
|
+
get: 300,
|
|
6125
|
+
query: 60,
|
|
6126
|
+
delete: 60,
|
|
6127
|
+
/** Counted in units of 25 operations: a full 100-op batch is 4. */
|
|
6128
|
+
batch: 30
|
|
6129
|
+
};
|
|
6130
|
+
var FIAS_AI_MANIFEST_LIMITS = {
|
|
6131
|
+
MAX_ACTIONS: 30,
|
|
6132
|
+
MAX_ID_LENGTH: 100,
|
|
6133
|
+
MAX_DESCRIPTION_LENGTH: 1e3,
|
|
6134
|
+
MAX_CATEGORY_LENGTH: 100,
|
|
6135
|
+
MAX_BLOCK_DESCRIPTION_LENGTH: 2e3,
|
|
6136
|
+
MAX_PARAMETER_SCHEMA_BYTES: 4096,
|
|
6137
|
+
MAX_AVAILABLE_WHEN_KEYS: 8,
|
|
6138
|
+
MAX_AVAILABLE_WHEN_KEY_LENGTH: 64,
|
|
6139
|
+
MAX_AVAILABLE_WHEN_STRING_LENGTH: 100,
|
|
6140
|
+
MAX_BLOCK_SERIALIZED_BYTES: 32 * 1024
|
|
6141
|
+
};
|
|
6142
|
+
|
|
5419
6143
|
// src/panels.ts
|
|
5420
6144
|
var PANEL_MIN_ELEMENTS = 1;
|
|
5421
6145
|
var PANEL_MAX_ELEMENTS = 24;
|
|
@@ -5823,8 +6547,11 @@ export {
|
|
|
5823
6547
|
AUDIO_VOICE_DESIGN_SURFACE_KEY,
|
|
5824
6548
|
ArcheAssetError,
|
|
5825
6549
|
DARK_THEME,
|
|
6550
|
+
DATA_STORE_LIMITS,
|
|
6551
|
+
DATA_STORE_RATE_LIMITS_PER_MINUTE,
|
|
5826
6552
|
ENTITY_INVOCATION_HISTORY_LIMITS,
|
|
5827
6553
|
ENTITY_INVOCATION_REQUEST_LIMITS,
|
|
6554
|
+
FIAS_AI_MANIFEST_LIMITS,
|
|
5828
6555
|
FONT_CATALOG,
|
|
5829
6556
|
FONT_PAIRINGS,
|
|
5830
6557
|
FiasBridge,
|
|
@@ -5833,6 +6560,7 @@ export {
|
|
|
5833
6560
|
FiasLocalStoreError,
|
|
5834
6561
|
FiasProvider,
|
|
5835
6562
|
GRAMMAR_CHECK_ENTITY_ID,
|
|
6563
|
+
IMAGE_CREATE_ASSET_SURFACE_KEY,
|
|
5836
6564
|
IMAGE_SMART_CONTROL_SURFACE_KEY,
|
|
5837
6565
|
IMAGE_SMART_ERASE_SURFACE_KEY,
|
|
5838
6566
|
IMAGE_SMART_IMAGE_TO_IMAGE_SURFACE_KEY,
|
|
@@ -5846,6 +6574,8 @@ export {
|
|
|
5846
6574
|
IMAGE_SMART_VECTORIZE_SURFACE_KEY,
|
|
5847
6575
|
INTEGRATION_WEB_SEARCH_SURFACE_KEY,
|
|
5848
6576
|
LIGHT_THEME,
|
|
6577
|
+
LINKEDIN_ENTITY_ID,
|
|
6578
|
+
LINKEDIN_PUBLISH_LIMITS,
|
|
5849
6579
|
NLLB_LANGUAGES,
|
|
5850
6580
|
NLLB_TRANSLATION_ENTITY_ID,
|
|
5851
6581
|
PANEL_BUTTON_LABEL_MAX_LENGTH,
|
|
@@ -5867,10 +6597,13 @@ export {
|
|
|
5867
6597
|
PLUGIN_LOCAL_STORE_ENTITY_ID,
|
|
5868
6598
|
PLUGIN_PERMISSION_DESCRIPTIONS,
|
|
5869
6599
|
REASONING_EFFORTS,
|
|
6600
|
+
SCHEDULE_LIMITS,
|
|
5870
6601
|
SDK_BRIDGE_PROTOCOL_VERSION,
|
|
5871
6602
|
SDK_REQUIRES_HOST_PROTOCOL_VERSION,
|
|
5872
6603
|
THEME_CATALOG,
|
|
5873
6604
|
VALID_PLUGIN_PERMISSIONS,
|
|
6605
|
+
X_ENTITY_ID,
|
|
6606
|
+
X_PUBLISH_LIMITS,
|
|
5874
6607
|
checkInvocationHistory,
|
|
5875
6608
|
checkInvocationRequestSize,
|
|
5876
6609
|
checkReasoningParameter,
|
|
@@ -5892,6 +6625,8 @@ export {
|
|
|
5892
6625
|
useClientEntity,
|
|
5893
6626
|
useCommunityAssets,
|
|
5894
6627
|
useCompanyEmail,
|
|
6628
|
+
useCreateAsset,
|
|
6629
|
+
useCreativeLibrary,
|
|
5895
6630
|
useDataSubscription,
|
|
5896
6631
|
useDocumentSign,
|
|
5897
6632
|
useElevenLabsAudioIsolation,
|
|
@@ -5903,18 +6638,26 @@ export {
|
|
|
5903
6638
|
useElevenLabsVoiceChanger,
|
|
5904
6639
|
useElevenLabsVoiceDesign,
|
|
5905
6640
|
useEntityInvocation,
|
|
6641
|
+
useEntitySubscription,
|
|
5906
6642
|
useFiasAIActions,
|
|
6643
|
+
useFiasAccess,
|
|
6644
|
+
useFiasChrome,
|
|
6645
|
+
useFiasConnections,
|
|
5907
6646
|
useFiasContent,
|
|
5908
6647
|
useFiasDataStore,
|
|
5909
6648
|
useFiasFonts,
|
|
6649
|
+
useFiasHolder,
|
|
6650
|
+
useFiasLinkedIn,
|
|
5910
6651
|
useFiasNavigation,
|
|
5911
6652
|
useFiasPreviewState,
|
|
6653
|
+
useFiasSchedules,
|
|
5912
6654
|
useFiasStorage,
|
|
5913
6655
|
useFiasStore,
|
|
5914
6656
|
useFiasTheme,
|
|
5915
6657
|
useFiasUser,
|
|
5916
6658
|
useFiasVendoredAssets,
|
|
5917
6659
|
useFiasWorkspaces,
|
|
6660
|
+
useFiasX,
|
|
5918
6661
|
useGeminiTranscribe,
|
|
5919
6662
|
useGeminiTts,
|
|
5920
6663
|
useImageEntities,
|