@fias/arche-sdk 2.19.1 → 2.19.2

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.
@@ -30,10 +30,13 @@ export declare const PLUGIN_STORE_ENTITY_ID = "ent_intg_plugin_store_0000000000"
30
30
  /** Vault Documents entity — plugins may reach ONLY its consented-read verbs
31
31
  * (user-granted documents via the host picker; `vault:user-documents:read`). */
32
32
  export declare const VAULT_USER_DOCUMENTS_ENTITY_ID = "ent_intg_vault_documents_0000000";
33
- /** Vault Arche Documents — documents THIS arche created. Two verbs:
34
- * `get_own_document_bytes` (`vault:documents:read`) and
35
- * `save_own_document_content` (additionally `vault:documents:write`) — the
36
- * permissions `useVaultDocuments` already derives. */
33
+ /** Vault Arche Documents — documents THIS arche created.
34
+ * `get_own_document_bytes` (`vault:documents:read`), and the in-place save:
35
+ * `save_own_document_content` for small text, or — driven by the HOST, since
36
+ * the iframe cannot PUT — `init_own_document_save` /
37
+ * `finalize_own_document_save` for bytes and large text (all three
38
+ * additionally `vault:documents:write`). `useVaultDocuments` already derives
39
+ * both permissions, and `saveContent` picks the lane. */
37
40
  export declare const VAULT_ARCHE_DOCUMENTS_ENTITY_ID = "ent_intg_vault_arche_docs_000000";
38
41
  /** Community Assets — user-published, moderated images readable by every
39
42
  * authenticated user of the SAME arche. `assets:community:read` for the read
@@ -1 +1 @@
1
- {"version":3,"file":"entity-ops.d.ts","sourceRoot":"","sources":["../src/entity-ops.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAE3C,eAAO,MAAM,wBAAwB,qCAAqC,CAAC;AAC3E,eAAO,MAAM,0BAA0B,qCAAqC,CAAC;AAC7E,eAAO,MAAM,2BAA2B,qCAAqC,CAAC;AAC9E,eAAO,MAAM,sBAAsB,qCAAqC,CAAC;AACzE;gFACgF;AAChF,eAAO,MAAM,8BAA8B,qCAAqC,CAAC;AACjF;;;sDAGsD;AACtD,eAAO,MAAM,+BAA+B,qCAAqC,CAAC;AAClF;;;iEAGiE;AACjE,eAAO,MAAM,0BAA0B,qCAAqC,CAAC;AAE7E;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,6BAA6B,KAAK,CAAC;AAChD,eAAO,MAAM,iCAAiC,KAAK,CAAC;AAEpD;;;;;;;;;;;;GAYG;AACH,wBAAsB,cAAc,CAAC,CAAC,EACpC,MAAM,EAAE,UAAU,EAClB,QAAQ,EAAE,MAAM,EAChB,EAAE,EAAE,MAAM,EACV,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACjC,OAAO,CAAC,CAAC,CAAC,CAMZ;AAED;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CAAC,CAAC,EACnC,MAAM,EAAE,UAAU,EAClB,EAAE,EAAE,MAAM,EACV,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACjC,OAAO,CAAC,CAAC,CAAC,CAKZ"}
1
+ {"version":3,"file":"entity-ops.d.ts","sourceRoot":"","sources":["../src/entity-ops.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAE3C,eAAO,MAAM,wBAAwB,qCAAqC,CAAC;AAC3E,eAAO,MAAM,0BAA0B,qCAAqC,CAAC;AAC7E,eAAO,MAAM,2BAA2B,qCAAqC,CAAC;AAC9E,eAAO,MAAM,sBAAsB,qCAAqC,CAAC;AACzE;gFACgF;AAChF,eAAO,MAAM,8BAA8B,qCAAqC,CAAC;AACjF;;;;;;yDAMyD;AACzD,eAAO,MAAM,+BAA+B,qCAAqC,CAAC;AAClF;;;iEAGiE;AACjE,eAAO,MAAM,0BAA0B,qCAAqC,CAAC;AAE7E;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,6BAA6B,KAAK,CAAC;AAChD,eAAO,MAAM,iCAAiC,KAAK,CAAC;AAEpD;;;;;;;;;;;;GAYG;AACH,wBAAsB,cAAc,CAAC,CAAC,EACpC,MAAM,EAAE,UAAU,EAClB,QAAQ,EAAE,MAAM,EAChB,EAAE,EAAE,MAAM,EACV,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACjC,OAAO,CAAC,CAAC,CAAC,CAMZ;AAED;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CAAC,CAAC,EACnC,MAAM,EAAE,UAAU,EAClB,EAAE,EAAE,MAAM,EACV,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACjC,OAAO,CAAC,CAAC,CAAC,CAKZ"}
@@ -10,10 +10,13 @@ exports.PLUGIN_STORE_ENTITY_ID = 'ent_intg_plugin_store_0000000000';
10
10
  /** Vault Documents entity — plugins may reach ONLY its consented-read verbs
11
11
  * (user-granted documents via the host picker; `vault:user-documents:read`). */
12
12
  exports.VAULT_USER_DOCUMENTS_ENTITY_ID = 'ent_intg_vault_documents_0000000';
13
- /** Vault Arche Documents — documents THIS arche created. Two verbs:
14
- * `get_own_document_bytes` (`vault:documents:read`) and
15
- * `save_own_document_content` (additionally `vault:documents:write`) — the
16
- * permissions `useVaultDocuments` already derives. */
13
+ /** Vault Arche Documents — documents THIS arche created.
14
+ * `get_own_document_bytes` (`vault:documents:read`), and the in-place save:
15
+ * `save_own_document_content` for small text, or — driven by the HOST, since
16
+ * the iframe cannot PUT — `init_own_document_save` /
17
+ * `finalize_own_document_save` for bytes and large text (all three
18
+ * additionally `vault:documents:write`). `useVaultDocuments` already derives
19
+ * both permissions, and `saveContent` picks the lane. */
17
20
  exports.VAULT_ARCHE_DOCUMENTS_ENTITY_ID = 'ent_intg_vault_arche_docs_000000';
18
21
  /** Community Assets — user-published, moderated images readable by every
19
22
  * authenticated user of the SAME arche. `assets:community:read` for the read
@@ -1 +1 @@
1
- {"version":3,"file":"entity-ops.js","sourceRoot":"","sources":["../src/entity-ops.ts"],"names":[],"mappings":";;;AAyEA,wCAWC;AAWD,sCASC;AA9EY,QAAA,wBAAwB,GAAG,kCAAkC,CAAC;AAC9D,QAAA,0BAA0B,GAAG,kCAAkC,CAAC;AAChE,QAAA,2BAA2B,GAAG,kCAAkC,CAAC;AACjE,QAAA,sBAAsB,GAAG,kCAAkC,CAAC;AACzE;gFACgF;AACnE,QAAA,8BAA8B,GAAG,kCAAkC,CAAC;AACjF;;;sDAGsD;AACzC,QAAA,+BAA+B,GAAG,kCAAkC,CAAC;AAClF;;;iEAGiE;AACpD,QAAA,0BAA0B,GAAG,kCAAkC,CAAC;AAE7E;;;;;;;;;;;;GAYG;AACU,QAAA,6BAA6B,GAAG,EAAE,CAAC;AACnC,QAAA,iCAAiC,GAAG,EAAE,CAAC;AAEpD;;;;;;;;;;;;GAYG;AACI,KAAK,UAAU,cAAc,CAClC,MAAkB,EAClB,QAAgB,EAChB,EAAU,EACV,OAAgC,EAAE;IAElC,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,OAAO,CAAgB,eAAe,EAAE;QAC/D,QAAQ;QACR,OAAO,EAAE,EAAE,EAAE,EAAE,GAAG,IAAI,EAAE;KACzB,CAAC,CAAC;IACH,OAAO,GAAG,CAAC,MAAM,CAAC;AACpB,CAAC;AAED;;;;;;;;GAQG;AACI,KAAK,UAAU,aAAa,CACjC,MAAkB,EAClB,EAAU,EACV,OAAgC,EAAE;IAElC,OAAO,MAAM,CAAC,OAAO,CAAI,eAAe,EAAE;QACxC,QAAQ,EAAE,8BAAsB;QAChC,OAAO,EAAE,EAAE,EAAE,EAAE,GAAG,IAAI,EAAE;KACzB,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"entity-ops.js","sourceRoot":"","sources":["../src/entity-ops.ts"],"names":[],"mappings":";;;AA4EA,wCAWC;AAWD,sCASC;AAjFY,QAAA,wBAAwB,GAAG,kCAAkC,CAAC;AAC9D,QAAA,0BAA0B,GAAG,kCAAkC,CAAC;AAChE,QAAA,2BAA2B,GAAG,kCAAkC,CAAC;AACjE,QAAA,sBAAsB,GAAG,kCAAkC,CAAC;AACzE;gFACgF;AACnE,QAAA,8BAA8B,GAAG,kCAAkC,CAAC;AACjF;;;;;;yDAMyD;AAC5C,QAAA,+BAA+B,GAAG,kCAAkC,CAAC;AAClF;;;iEAGiE;AACpD,QAAA,0BAA0B,GAAG,kCAAkC,CAAC;AAE7E;;;;;;;;;;;;GAYG;AACU,QAAA,6BAA6B,GAAG,EAAE,CAAC;AACnC,QAAA,iCAAiC,GAAG,EAAE,CAAC;AAEpD;;;;;;;;;;;;GAYG;AACI,KAAK,UAAU,cAAc,CAClC,MAAkB,EAClB,QAAgB,EAChB,EAAU,EACV,OAAgC,EAAE;IAElC,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,OAAO,CAAgB,eAAe,EAAE;QAC/D,QAAQ;QACR,OAAO,EAAE,EAAE,EAAE,EAAE,GAAG,IAAI,EAAE;KACzB,CAAC,CAAC;IACH,OAAO,GAAG,CAAC,MAAM,CAAC;AACpB,CAAC;AAED;;;;;;;;GAQG;AACI,KAAK,UAAU,aAAa,CACjC,MAAkB,EAClB,EAAU,EACV,OAAgC,EAAE;IAElC,OAAO,MAAM,CAAC,OAAO,CAAI,eAAe,EAAE;QACxC,QAAQ,EAAE,8BAAsB;QAChC,OAAO,EAAE,EAAE,EAAE,EAAE,GAAG,IAAI,EAAE;KACzB,CAAC,CAAC;AACL,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 = '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' | 'vault:user-documents:write';
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:edit' | 'vault:user-documents:read' | 'vault:user-documents:write';
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,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,GAC3B,4BAA4B,CAAC;AAEjC,eAAO,MAAM,wBAAwB,EAAE,SAAS,gBAAgB,EAwBtD,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,CA+BrF,CAAC"}
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,GAC3B,2BAA2B,GAC3B,4BAA4B,CAAC;AAEjC,eAAO,MAAM,wBAAwB,EAAE,SAAS,gBAAgB,EAyBtD,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,CAiCrF,CAAC"}
@@ -35,6 +35,7 @@ exports.VALID_PLUGIN_PERMISSIONS = [
35
35
  'user:profile:read',
36
36
  'vault:documents:read',
37
37
  'vault:documents:write',
38
+ 'vault:user-documents:edit',
38
39
  'vault:user-documents:read',
39
40
  'vault:user-documents:write',
40
41
  ];
@@ -68,6 +69,7 @@ exports.PLUGIN_PERMISSION_DESCRIPTIONS = {
68
69
  'user:profile:read': 'See your display name and avatar.',
69
70
  'vault:documents:read': 'Read documents this app itself created in your Vault.',
70
71
  'vault:documents:write': 'Create and manage its own documents in your Vault.',
72
+ 'vault:user-documents:edit': 'Save changes to files of yours that you let it edit — you choose each file, earlier versions are kept, and you can remove access any time in Vault → App Access.',
71
73
  'vault:user-documents:read': 'Read documents YOU choose to share with it from your Vault — you pick each document, and you can remove access any time in Vault → App Access.',
72
74
  'vault:user-documents:write': 'Save its work to your Fias files, where you can find and reuse it. You confirm each save.',
73
75
  };
@@ -1 +1 @@
1
- {"version":3,"file":"permissions.js","sourceRoot":"","sources":["../../src/generated/permissions.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;;;AAqDH,0DAEC;AA5BY,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;IAC3B,4BAA4B;CACpB,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;IAClJ,4BAA4B,EAC1B,2FAA2F;CAC9F,CAAC"}
1
+ {"version":3,"file":"permissions.js","sourceRoot":"","sources":["../../src/generated/permissions.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;;;AAuDH,0DAEC;AA7BY,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;IAC3B,2BAA2B;IAC3B,4BAA4B;CACpB,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,kKAAkK;IACpK,2BAA2B,EACzB,gJAAgJ;IAClJ,4BAA4B,EAC1B,2FAA2F;CAC9F,CAAC"}
package/dist/hooks.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { ArcheHandoffPayload, FiasUser, FiasTheme, FiasStorageApi, DataSubscriptionState, EntityInvocationApi, ClientEntityApi, ImageGenerationApi, ImageEntityFilter, ImageEntitySummary, NllbLanguageOption, AudioGenerationApi, FiasNavigationApi, StepNavigationApi, StepNavigationOptions, FiasDataStoreApi, FiasWorkspacesApi, FiasStoreApi, VaultDocumentsApi, VaultDocumentDownloadUrl, ArcheAssetsApi, CommunityAssetsApi, FiasAIActionsDeclaration } from './types';
1
+ import type { ArcheHandoffPayload, FiasUser, FiasTheme, FiasStorageApi, DataSubscriptionState, EntityInvocationApi, ClientEntityApi, ImageGenerationApi, ImageEntityFilter, ImageEntitySummary, NllbLanguageOption, AudioGenerationApi, FiasNavigationApi, StepNavigationApi, StepNavigationOptions, FiasDataStoreApi, FiasWorkspacesApi, FiasStoreApi, VaultDocumentsApi, VaultDocumentDownloadUrl, VaultUserDocumentSaveContentResult, 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.
@@ -412,14 +412,41 @@ export interface VaultUserDocumentSummary {
412
412
  sensitivity: string;
413
413
  createdAt: string;
414
414
  updatedAt: string;
415
+ /**
416
+ * What the user lets you do with this document: `'read'` (open it) or
417
+ * `'write'` (also save changes to it — see `saveContent`). Open a `'read'`
418
+ * document read-only, and call `requestEditAccess` when the user starts
419
+ * editing. Optional: absent on hosts that predate edit access — treat
420
+ * absent as `'read'`.
421
+ */
422
+ access?: 'read' | 'write';
423
+ /**
424
+ * Opaque token naming the document's current CONTENT. REQUIRED by
425
+ * `saveContent` as `expectedRevision` — it is the user's file and they may
426
+ * be changing it elsewhere. Never parse it.
427
+ */
428
+ revision?: string;
415
429
  }
416
430
  /** Result of the host picker: what the user picked and confirmed, or a
417
431
  * cancel. A cancel is a normal outcome — never treat it as an error. */
418
432
  export type VaultUserDocumentPickResult = {
419
433
  canceled: true;
420
434
  } | {
421
- documents: Array<Pick<VaultUserDocumentSummary, 'documentId' | 'name' | 'mimeType' | 'sizeBytes'>>;
435
+ documents: Array<Pick<VaultUserDocumentSummary, 'documentId' | 'name' | 'mimeType' | 'sizeBytes'> & {
436
+ /** What the user granted for this document. */
437
+ access?: 'read' | 'write';
438
+ }>;
422
439
  };
440
+ /** Input to `useVaultUserDocuments().saveContent`. */
441
+ export interface VaultUserDocumentSaveContentParams {
442
+ documentId: string;
443
+ /** The new content, up to 15 MB: a `string` (UTF-8 text — the document must
444
+ * be a text type) or bytes. Transport is chosen for you. The document's
445
+ * TYPE cannot change, so there is no `contentType`. */
446
+ content: string | Uint8Array | ArrayBuffer | Blob;
447
+ /** REQUIRED. The `revision` you last saw for this document. */
448
+ expectedRevision: string;
449
+ }
423
450
  export interface VaultUserDocumentsApi {
424
451
  /**
425
452
  * Open the HOST's Vault picker + consent sheet. The user hand-picks
@@ -430,7 +457,55 @@ export interface VaultUserDocumentsApi {
430
457
  */
431
458
  pick(options?: {
432
459
  maxDocuments?: number;
460
+ /** Ask for EDIT access: the user is shown a consent that says your app
461
+ * may CHANGE what they pick. Needs `vault:user-documents:edit` IN
462
+ * ADDITION TO `vault:user-documents:read` — `:edit` does not include
463
+ * `:read`, and every method of this hook (this one included) is gated
464
+ * on `:read`. */
465
+ access?: 'read' | 'write';
433
466
  }): Promise<VaultUserDocumentPickResult>;
467
+ /**
468
+ * Ask the user to let you EDIT a document you can already open. The host
469
+ * shows its own consent for that one file — no picker — and resolves with
470
+ * the document (now `access: 'write'`), or `{ canceled: true }`. Call it
471
+ * from a user gesture, when the user actually starts editing — not on open,
472
+ * and not again right after a decline. Needs `vault:user-documents:edit`
473
+ * together with `vault:user-documents:read`.
474
+ * If you hold no grant on the document the host shows the ordinary picker
475
+ * instead, so you learn nothing about files you were not given.
476
+ *
477
+ * CHECK THE RESULT — a resolved promise is not "you may now edit
478
+ * `documentId`". Because of that picker fallback the one document that
479
+ * comes back may be a DIFFERENT one the user chose, and the user may have
480
+ * answered from a sheet that offered view-only. Proceed only when
481
+ * `documents[0].documentId === documentId` and `documents[0].access ===
482
+ * 'write'`; treat anything else (including `{ canceled: true }`) as "no".
483
+ */
484
+ requestEditAccess(documentId: string): Promise<VaultUserDocumentPickResult>;
485
+ /**
486
+ * Save changes, IN PLACE, to a document the user has given you EDIT access
487
+ * to — same `documentId`, so nothing attached to it detaches. Text or bytes,
488
+ * up to 15 MB; one method, transport chosen for you.
489
+ *
490
+ * Manifest: `vault:user-documents:edit` AND `vault:user-documents:read`.
491
+ * Declaring `:edit` alone is not enough — it does not include `:read`.
492
+ *
493
+ * It is the USER'S file, which makes this stricter than saving your own:
494
+ * `expectedRevision` is REQUIRED (they may be editing it elsewhere — a stale
495
+ * one rejects `VERSION_CONFLICT`: re-read, merge or ask, retry); the file's
496
+ * TYPE cannot change (`MIME_CHANGE_NOT_ALLOWED`); and the platform keeps
497
+ * earlier versions for them, which count against THEIR storage — a save
498
+ * that would exceed it rejects `STORAGE_QUOTA_EXCEEDED` and nothing is lost.
499
+ *
500
+ * Rejects `EDIT_ACCESS_REQUIRED` when you hold view-only access (call
501
+ * `requestEditAccess`), and `DOCUMENT_NOT_FOUND` once the user removes your
502
+ * access in Vault → App Access — which takes effect on your very next save.
503
+ * Handle both. Debounce (a few seconds idle, plus blur and close) and
504
+ * surface `RATE_LIMIT` rather than looping: this lane allows fewer saves per
505
+ * minute than your own documents do. Every save is recorded with your app's
506
+ * name, and the file shows the user that you changed it.
507
+ */
508
+ saveContent(params: VaultUserDocumentSaveContentParams): Promise<VaultUserDocumentSaveContentResult>;
434
509
  /** Documents the user has granted this arche (empty until they pick). */
435
510
  list(options?: {
436
511
  limit?: number;
@@ -481,7 +556,15 @@ export interface VaultUserDocumentsApi {
481
556
  * surface that reaches data your plugin did not create. Requires the
482
557
  * `vault:user-documents:read` permission. Every access is user-consented
483
558
  * (per-document grants created in the host picker, revocable any time in
484
- * Vault → App Access) and audited by the platform. Proprietary-sensitivity
559
+ * Vault → App Access) and audited by the platform.
560
+ *
561
+ * The picker offers the files of the workspace the user is acting in (the
562
+ * host's workspace switcher — Personal, or an org workspace they belong to)
563
+ * and `list()` returns the grants made in it; a document you hold a grant on
564
+ * stays readable by id whichever workspace the user is in, because a grant
565
+ * belongs to the workspace the document lives in. A plugin never names a
566
+ * workspace; the host does. A member's role caps what they can share and
567
+ * read. Proprietary-sensitivity
485
568
  * documents are never grantable. For documents your plugin CREATES, use
486
569
  * `useVaultDocuments` instead.
487
570
  */
@@ -1 +1 @@
1
- {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"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"}
package/dist/hooks.js CHANGED
@@ -185,7 +185,13 @@ function useFiasStorage() {
185
185
  path,
186
186
  });
187
187
  }, [bridge]);
188
- return { readFile, writeFile, listFiles, deleteFile };
188
+ // Memoized, like useArcheAssets. An unmemoized object literal here is a
189
+ // footgun rather than a style question: the natural way to use this hook is
190
+ // `useEffect(() => { void storage.readFile(...) }, [storage])`, and a fresh
191
+ // identity every render turns that into an infinite loop — effect, setState,
192
+ // render, effect. The inner callbacks were already stable; only the
193
+ // container was not.
194
+ return (0, react_1.useMemo)(() => ({ readFile, writeFile, listFiles, deleteFile }), [readFile, writeFile, listFiles, deleteFile]);
189
195
  }
190
196
  /**
191
197
  * Invoke platform entities (AI models, etc.) through the bridge.
@@ -573,16 +579,21 @@ function useFiasNavigation() {
573
579
  bridge.request('navigate', { path });
574
580
  }, [bridge]);
575
581
  const openArche = (0, react_1.useCallback)((archeId, opts) => {
576
- // `path` is spread in only when supplied: an older host ignores unknown
577
- // keys, but sending `path: undefined` would add a key to every call for
578
- // no reason and churn the wire shape shipped plugins already emit.
582
+ // `path` / `payload` are spread in only when supplied: an older host
583
+ // ignores unknown keys, but sending `path: undefined` would add a key to
584
+ // every call for no reason and churn the wire shape shipped plugins
585
+ // already emit.
579
586
  bridge.request('open_arche', {
580
587
  archeId,
581
588
  newTab: opts?.newTab === true,
582
589
  ...(opts?.path ? { path: opts.path } : {}),
590
+ ...(opts?.payload ? { payload: opts.payload } : {}),
583
591
  });
584
592
  }, [bridge]);
585
- return { navigateTo, openArche, currentPath };
593
+ // Memoized for the same reason as useFiasStorage. `currentPath` is state, so
594
+ // this identity still changes when the path does — which is correct, and is
595
+ // exactly what a consumer depending on it wants.
596
+ return (0, react_1.useMemo)(() => ({ navigateTo, openArche, currentPath }), [navigateTo, openArche, currentPath]);
586
597
  }
587
598
  /**
588
599
  * Like useState, but auto-persists to bridge storage.
@@ -596,12 +607,22 @@ function usePersistentState(key, initialValue) {
596
607
  const [value, setValueInternal] = (0, react_1.useState)(initialValue);
597
608
  const initializedRef = (0, react_1.useRef)(false);
598
609
  const valueRef = (0, react_1.useRef)(initialValue);
610
+ // Set once the plugin calls the setter. A value set BEFORE the mount read
611
+ // resolves is newer than anything in storage, so the read must not
612
+ // overwrite it — it used to, silently reverting e.g. a click that landed
613
+ // while the read was in flight (the debounced write then persisted the
614
+ // user's value while the UI showed the stale one).
615
+ const setByPluginRef = (0, react_1.useRef)(false);
599
616
  const writer = (0, react_1.useMemo)(() => createDebouncedWriter(bridge), [bridge]);
600
617
  // Load from storage on mount; flush any pending write on unmount/key change
601
618
  // so rapid updates in a game loop never lose their last value.
602
619
  (0, react_1.useEffect)(() => {
603
620
  (0, entity_ops_1.invokeEntityOp)(bridge, entity_ops_1.PLUGIN_STORAGE_ENTITY_ID, 'read', { path: `__state/${key}` })
604
621
  .then((result) => {
622
+ if (setByPluginRef.current) {
623
+ initializedRef.current = true;
624
+ return;
625
+ }
605
626
  if (result.exists && result.content !== null) {
606
627
  try {
607
628
  const parsed = JSON.parse(result.content);
@@ -627,6 +648,7 @@ function usePersistentState(key, initialValue) {
627
648
  }, [bridge, key, writer]);
628
649
  const setValue = (0, react_1.useCallback)((next) => {
629
650
  const resolved = typeof next === 'function' ? next(valueRef.current) : next;
651
+ setByPluginRef.current = true;
630
652
  valueRef.current = resolved;
631
653
  setValueInternal(resolved);
632
654
  writer.schedule(`__state/${key}`, JSON.stringify(resolved));
@@ -1079,9 +1101,7 @@ function useVaultDocuments() {
1079
1101
  });
1080
1102
  }, [bridge]);
1081
1103
  const read = (0, react_1.useCallback)(async (documentId) => {
1082
- return bridge.request('vault_documents_read', {
1083
- documentId,
1084
- });
1104
+ return bridge.request('vault_documents_read', { documentId });
1085
1105
  }, [bridge]);
1086
1106
  const getDownloadUrl = (0, react_1.useCallback)((documentId) => fetchVaultDocumentDownloadUrl(documentId),
1087
1107
  // The hook closes over the React context's bridge, but the resolver
@@ -1098,16 +1118,47 @@ function useVaultDocuments() {
1098
1118
  };
1099
1119
  }, [bridge]);
1100
1120
  const saveContent = (0, react_1.useCallback)(async (params) => {
1101
- const res = await (0, entity_ops_1.invokeEntityOp)(bridge, entity_ops_1.VAULT_ARCHE_DOCUMENTS_ENTITY_ID, 'save_own_document_content', {
1102
- documentId: params.documentId,
1103
- content: params.content,
1104
- contentType: params.contentType,
1105
- });
1121
+ const routed = await routeSaveContent(params.content);
1122
+ let res;
1123
+ if (routed.lane === 'body') {
1124
+ // Small text rides the entity_invoke body.
1125
+ res = await (0, entity_ops_1.invokeEntityOp)(bridge, entity_ops_1.VAULT_ARCHE_DOCUMENTS_ENTITY_ID, 'save_own_document_content', {
1126
+ documentId: params.documentId,
1127
+ content: routed.text,
1128
+ contentType: params.contentType,
1129
+ expectedRevision: params.expectedRevision,
1130
+ });
1131
+ }
1132
+ else {
1133
+ // Bytes — or text too large for the bridge body — go through the
1134
+ // host, which does the presigned PUT the iframe's CSP forbids (same
1135
+ // reason `upload` does; see there). `contentKind: 'text'` keeps the
1136
+ // text lane's must-be-a-text-type rule in force at any size.
1137
+ //
1138
+ // Deliberately NO `name` in this payload: a host that predates
1139
+ // in-place saves requires one for an upload, so it refuses this
1140
+ // message instead of silently creating a NEW document.
1141
+ res = await bridge.request('vault_documents_upload', {
1142
+ saveToDocumentId: params.documentId,
1143
+ bytes: bytesToBase64(routed.bytes),
1144
+ mimeType: params.contentType,
1145
+ contentKind: routed.contentKind,
1146
+ expectedRevision: params.expectedRevision,
1147
+ });
1148
+ }
1106
1149
  // The bytes behind any cached download URL just changed.
1107
1150
  downloadUrlCache.delete(params.documentId);
1108
1151
  return res;
1109
1152
  }, [bridge]);
1110
1153
  const write = (0, react_1.useCallback)(async (params) => {
1154
+ // `write` has no second lane to fall back to, so say so here rather
1155
+ // than let the request die as an opaque 413 at the bridge.
1156
+ if (params.content.length > SAVE_CONTENT_BODY_LANE_MAX_BYTES ||
1157
+ !fitsBridgeBodyAsJsonText(params.content)) {
1158
+ throw new bridge_1.FiasBridgeError('write() takes small text only: at most 200,000 characters, and small enough to ' +
1159
+ 'travel in one bridge request once JSON-escaped (quotes, backslashes and newlines ' +
1160
+ 'double). Use upload() for larger documents.', 'INVALID_PARAMS');
1161
+ }
1111
1162
  return bridge.request('vault_documents_write', {
1112
1163
  name: params.name,
1113
1164
  content: params.content,
@@ -1128,6 +1179,18 @@ function useVaultDocuments() {
1128
1179
  // drop any cached URL for this document.
1129
1180
  downloadUrlCache.delete(documentId);
1130
1181
  }, [bridge]);
1182
+ const promoteToUserFiles = (0, react_1.useCallback)(async (documentId) => {
1183
+ // Rides the existing update op with a host-only flag. The HOST
1184
+ // intercepts it, shows the user its own confirmation, and performs the
1185
+ // promote from the user's session — nothing here (or anywhere in the
1186
+ // iframe) can promote a file without the user agreeing.
1187
+ const res = await bridge.request('vault_documents_update', {
1188
+ documentId,
1189
+ userVisible: true,
1190
+ });
1191
+ downloadUrlCache.delete(documentId);
1192
+ return res;
1193
+ }, [bridge]);
1131
1194
  const deleteDocument = (0, react_1.useCallback)(async (documentId) => {
1132
1195
  await bridge.request('vault_documents_delete', { documentId });
1133
1196
  downloadUrlCache.delete(documentId);
@@ -1204,6 +1267,7 @@ function useVaultDocuments() {
1204
1267
  getDownloadUrl,
1205
1268
  write,
1206
1269
  update,
1270
+ promoteToUserFiles,
1207
1271
  delete: deleteDocument,
1208
1272
  search,
1209
1273
  attach,
@@ -1219,6 +1283,7 @@ function useVaultDocuments() {
1219
1283
  getDownloadUrl,
1220
1284
  write,
1221
1285
  update,
1286
+ promoteToUserFiles,
1222
1287
  deleteDocument,
1223
1288
  search,
1224
1289
  attach,
@@ -1228,6 +1293,74 @@ function useVaultDocuments() {
1228
1293
  uploadFinalize,
1229
1294
  ]);
1230
1295
  }
1296
+ /** Encoded-size ceiling of the text lane (`save_own_document_content`). Must
1297
+ * match the server's MAX_OWN_DOCUMENT_SAVE_BYTES; content past it is routed
1298
+ * through the host-uploaded lane rather than refused. */
1299
+ const SAVE_CONTENT_BODY_LANE_MAX_BYTES = 200000;
1300
+ /**
1301
+ * What the text may occupy ON THE WIRE. The bridge request body is capped at
1302
+ * 256 KB (the server's `PLUGIN_BRIDGE_BODY_LIMIT_BYTES`) and the text travels
1303
+ * inside it as a JSON string, where every `"`, `\` and newline doubles and
1304
+ * every other control character becomes six bytes. So 200 KB of text can be
1305
+ * 400 KB — or 1.2 MB — of request, and the answer is an opaque 413 rather
1306
+ * than a save. Routing therefore looks at the SERIALIZED size too, with ~16 KB
1307
+ * left for the envelope (ids, revision, content type, JSON keys).
1308
+ */
1309
+ const BRIDGE_BODY_TEXT_MAX_SERIALIZED_BYTES = 256 * 1024 - 16 * 1024;
1310
+ /** True when `text` fits a bridge request body as a JSON string. Encodes at
1311
+ * most once, and not at all for short strings (a UTF-16 unit is at most six
1312
+ * bytes of JSON). */
1313
+ function fitsBridgeBodyAsJsonText(text, utf8Bytes) {
1314
+ if (text.length * 6 <= BRIDGE_BODY_TEXT_MAX_SERIALIZED_BYTES)
1315
+ return true;
1316
+ // JSON escapes are ASCII, so they cost the same in UTF-16 units as in
1317
+ // bytes: serialized bytes = UTF-8 bytes + the units escaping added.
1318
+ const escapeOverhead = JSON.stringify(text).length - text.length;
1319
+ const bytes = utf8Bytes ?? new TextEncoder().encode(text).length;
1320
+ return bytes + escapeOverhead <= BRIDGE_BODY_TEXT_MAX_SERIALIZED_BYTES;
1321
+ }
1322
+ /** Mirrors the server's `MAX_OWN_DOCUMENT_PRESIGNED_SAVE_BYTES` — the most an
1323
+ * in-place save accepts, pinned to what `readBytes` / `getBytes` can serve
1324
+ * back, so anything saved can be reopened. */
1325
+ const SAVE_CONTENT_MAX_BYTES = 15 * 1024 * 1024;
1326
+ /**
1327
+ * Pick the lane for `saveContent` from the content itself, encoding text AT
1328
+ * MOST ONCE (a UTF-16 code unit is at most 3 UTF-8 bytes, so short strings
1329
+ * are routed without encoding at all) and refusing anything past the cap
1330
+ * BEFORE the base64 step — which would otherwise build a 20 MB string on the
1331
+ * plugin's main thread for a save the server is certain to refuse.
1332
+ */
1333
+ async function routeSaveContent(content) {
1334
+ let routed;
1335
+ if (typeof content === 'string') {
1336
+ // Short enough that neither limit can be reached, whatever it contains:
1337
+ // six bytes of JSON per unit is the worst case, three of UTF-8.
1338
+ if (content.length * 6 <= SAVE_CONTENT_BODY_LANE_MAX_BYTES) {
1339
+ return { lane: 'body', text: content };
1340
+ }
1341
+ const bytes = new TextEncoder().encode(content);
1342
+ routed =
1343
+ bytes.length <= SAVE_CONTENT_BODY_LANE_MAX_BYTES &&
1344
+ fitsBridgeBodyAsJsonText(content, bytes.length)
1345
+ ? { lane: 'body', text: content }
1346
+ : { lane: 'host', bytes, contentKind: 'text' };
1347
+ }
1348
+ else {
1349
+ routed = { lane: 'host', bytes: await toUint8Array(content), contentKind: 'binary' };
1350
+ }
1351
+ if (routed.lane === 'host' && routed.bytes.length > SAVE_CONTENT_MAX_BYTES) {
1352
+ throw new bridge_1.FiasBridgeError(`Content is ${routed.bytes.length} bytes; saveContent accepts at most ` +
1353
+ `${SAVE_CONTENT_MAX_BYTES} bytes (15 MB).`, 'OWN_DOCUMENT_SAVE_TOO_LARGE');
1354
+ }
1355
+ return routed;
1356
+ }
1357
+ async function toUint8Array(content) {
1358
+ if (content instanceof Uint8Array)
1359
+ return content;
1360
+ if (content instanceof ArrayBuffer)
1361
+ return new Uint8Array(content);
1362
+ return new Uint8Array(await content.arrayBuffer());
1363
+ }
1231
1364
  /** Decode base64 transport back to bytes (`get_consented_document_bytes`). */
1232
1365
  function base64ToBytes(base64) {
1233
1366
  const binary = atob(base64);
@@ -1448,7 +1581,15 @@ function useDataSubscription(collection, onInvalidate, options) {
1448
1581
  * surface that reaches data your plugin did not create. Requires the
1449
1582
  * `vault:user-documents:read` permission. Every access is user-consented
1450
1583
  * (per-document grants created in the host picker, revocable any time in
1451
- * Vault → App Access) and audited by the platform. Proprietary-sensitivity
1584
+ * Vault → App Access) and audited by the platform.
1585
+ *
1586
+ * The picker offers the files of the workspace the user is acting in (the
1587
+ * host's workspace switcher — Personal, or an org workspace they belong to)
1588
+ * and `list()` returns the grants made in it; a document you hold a grant on
1589
+ * stays readable by id whichever workspace the user is in, because a grant
1590
+ * belongs to the workspace the document lives in. A plugin never names a
1591
+ * workspace; the host does. A member's role caps what they can share and
1592
+ * read. Proprietary-sensitivity
1452
1593
  * documents are never grantable. For documents your plugin CREATES, use
1453
1594
  * `useVaultDocuments` instead.
1454
1595
  */
@@ -1457,6 +1598,38 @@ function useVaultUserDocuments() {
1457
1598
  const pick = (0, react_1.useCallback)(async (options) => {
1458
1599
  return bridge.request('vault_documents_pick', {
1459
1600
  maxDocuments: options?.maxDocuments,
1601
+ access: options?.access,
1602
+ });
1603
+ }, [bridge]);
1604
+ const requestEditAccess = (0, react_1.useCallback)(async (documentId) => {
1605
+ // The same host-mediated op as `pick`, naming one document. The HOST
1606
+ // decides whether it may skip the picker (only for a document this arche
1607
+ // already holds a grant on) — nothing here can.
1608
+ return bridge.request('vault_documents_pick', {
1609
+ maxDocuments: 1,
1610
+ access: 'write',
1611
+ documentId,
1612
+ });
1613
+ }, [bridge]);
1614
+ const saveContent = (0, react_1.useCallback)(async (params) => {
1615
+ const routed = await routeSaveContent(params.content);
1616
+ if (routed.lane === 'body') {
1617
+ return (0, entity_ops_1.invokeEntityOp)(bridge, entity_ops_1.VAULT_USER_DOCUMENTS_ENTITY_ID, 'save_consented_document_content', {
1618
+ documentId: params.documentId,
1619
+ content: routed.text,
1620
+ expectedRevision: params.expectedRevision,
1621
+ });
1622
+ }
1623
+ // Bytes, or text past the bridge body: the host does the presigned PUT
1624
+ // (the iframe's CSP forbids it). `saveTarget: 'user'` selects the
1625
+ // consented lane; no `name`, so an older host refuses rather than
1626
+ // creating a new document.
1627
+ return bridge.request('vault_documents_upload', {
1628
+ saveToDocumentId: params.documentId,
1629
+ saveTarget: 'user',
1630
+ bytes: bytesToBase64(routed.bytes),
1631
+ contentKind: routed.contentKind,
1632
+ expectedRevision: params.expectedRevision,
1460
1633
  });
1461
1634
  }, [bridge]);
1462
1635
  const list = (0, react_1.useCallback)(async (options) => {
@@ -1482,7 +1655,7 @@ function useVaultUserDocuments() {
1482
1655
  contentType: res.contentType,
1483
1656
  };
1484
1657
  }, [bridge]);
1485
- return (0, react_1.useMemo)(() => ({ pick, list, get, getDownloadUrl, getBytes }), [pick, list, get, getDownloadUrl, getBytes]);
1658
+ return (0, react_1.useMemo)(() => ({ pick, requestEditAccess, saveContent, list, get, getDownloadUrl, getBytes }), [pick, requestEditAccess, saveContent, list, get, getDownloadUrl, getBytes]);
1486
1659
  }
1487
1660
  /**
1488
1661
  * Refresh a community-asset URL this many ms before it expires. Larger than the