@interop/wallet-core 0.84.0 → 0.86.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.
@@ -20,7 +20,7 @@ type DerivedGap = Pick<InvariantGap, 'invariant' | 'kind'>;
20
20
  * The invariants a transient visit on a standing credential reaches. The
21
21
  * two chain triggers are read through `dueAt` over the ladder held set; a
22
22
  * `login-routing` site counts unless the client-key-record probe guards it;
23
- * a `read-path` site counts, since the read it rides runs on any session;
23
+ * an `encounter` site counts, since the read it rides runs on any session;
24
24
  * a `ceremony-tail` entry counts, every such ceremony running on any
25
25
  * session type; and a detector no site reports (a declaration carrying
26
26
  * `holdsWhen`) counts when it is checked at a trigger a transient visit
@@ -21,7 +21,7 @@ function reportedIds(registry) {
21
21
  * The invariants a transient visit on a standing credential reaches. The
22
22
  * two chain triggers are read through `dueAt` over the ladder held set; a
23
23
  * `login-routing` site counts unless the client-key-record probe guards it;
24
- * a `read-path` site counts, since the read it rides runs on any session;
24
+ * an `encounter` site counts, since the read it rides runs on any session;
25
25
  * a `ceremony-tail` entry counts, every such ceremony running on any
26
26
  * session type; and a detector no site reports (a declaration carrying
27
27
  * `holdsWhen`) counts when it is checked at a trigger a transient visit
@@ -45,7 +45,7 @@ export function transientReachableInvariants({ registry }) {
45
45
  }
46
46
  for (const site of registry.sites()) {
47
47
  if ((site.trigger === 'login-routing' && !site.guardedBy) ||
48
- site.trigger === 'read-path') {
48
+ site.trigger === 'encounter') {
49
49
  for (const id of site.reports) {
50
50
  reached.add(id);
51
51
  }
@@ -61,7 +61,7 @@ export function transientReachableInvariants({ registry }) {
61
61
  continue;
62
62
  }
63
63
  const checkedOnVisit = decl.triggers.includes('login-routing') ||
64
- decl.triggers.includes('read-path') ||
64
+ decl.triggers.includes('encounter') ||
65
65
  (decl.triggers.includes('transient-login-chain') &&
66
66
  held.includes(decl.authority));
67
67
  if (checkedOnVisit) {
@@ -27,11 +27,11 @@ export type Authority = (typeof AUTHORITIES)[number];
27
27
  * entries are invoked by name at a routing call site before or during
28
28
  * session assembly and may refuse the login; `ceremony-tail` entries execute
29
29
  * inside a ceremony's own sequenced code and only report through the
30
- * registry; `read-path` entries run on an ordinary read of the state they
31
- * converge (a sweep-on-read), on any session type, and never on a login
32
- * chain.
30
+ * registry; `encounter` entries run where an ordinary read or write meets
31
+ * the state they converge (a sweep-on-read, or a refusal a page handles),
32
+ * inside a live session, and are not on a login chain.
33
33
  */
34
- export declare const TRIGGERS: readonly ["remembered-login-chain", "transient-login-chain", "login-routing", "ceremony-tail", "read-path"];
34
+ export declare const TRIGGERS: readonly ["remembered-login-chain", "transient-login-chain", "login-routing", "ceremony-tail", "encounter"];
35
35
  /**
36
36
  * One value of {@link TRIGGERS}.
37
37
  */
@@ -23,16 +23,16 @@ export const AUTHORITIES = ['none', 'account', 'enrolled', 'ladder'];
23
23
  * entries are invoked by name at a routing call site before or during
24
24
  * session assembly and may refuse the login; `ceremony-tail` entries execute
25
25
  * inside a ceremony's own sequenced code and only report through the
26
- * registry; `read-path` entries run on an ordinary read of the state they
27
- * converge (a sweep-on-read), on any session type, and never on a login
28
- * chain.
26
+ * registry; `encounter` entries run where an ordinary read or write meets
27
+ * the state they converge (a sweep-on-read, or a refusal a page handles),
28
+ * inside a live session, and are not on a login chain.
29
29
  */
30
30
  export const TRIGGERS = [
31
31
  'remembered-login-chain',
32
32
  'transient-login-chain',
33
33
  'login-routing',
34
34
  'ceremony-tail',
35
- 'read-path'
35
+ 'encounter'
36
36
  ];
37
37
  /**
38
38
  * The two triggers a runner batches registrations for, and the only two the
@@ -2,14 +2,18 @@
2
2
  * Copyright (c) 2026 Interop Alliance. All rights reserved.
3
3
  */
4
4
  /**
5
- * The typed ceremony vocabulary: one stable id per shared account ceremony.
6
- * The ids are code-only identifiers (nothing persists them yet); each names
7
- * one ceremony documented in the wallets' ceremony inventories.
5
+ * The typed ceremony vocabulary: one stable id per account ceremony either
6
+ * wallet runs. Most have a shared half in this package; some are still
7
+ * implemented app-side. The ids are code-only identifiers (nothing persists
8
+ * them yet); each names one ceremony documented in the wallets' ceremony
9
+ * inventories.
8
10
  */
9
11
  /**
10
- * The shared account ceremony ids, in ceremony-inventory order.
12
+ * The account ceremony ids, in ceremony-inventory order. The last four
13
+ * (account deletion, the shared wipe executor, content migration, and backup
14
+ * export) are implemented in the app for now.
11
15
  */
12
- export declare const CEREMONY_IDS: readonly ["account-genesis", "credential-anchored-genesis", "self-enrollment", "client-enrollment", "client-revocation", "recovery-code-issuance", "recovery-code-spend", "recovery-code-revocation", "unlock-credential-rotation", "forget-client", "last-client-transition", "update-key-rotation"];
16
+ export declare const CEREMONY_IDS: readonly ["account-genesis", "credential-anchored-genesis", "self-enrollment", "client-enrollment", "client-revocation", "recovery-code-issuance", "recovery-code-spend", "recovery-code-revocation", "unlock-credential-rotation", "forget-client", "last-client-transition", "update-key-rotation", "account-deletion", "wallet-wipe", "content-migration", "backup-export"];
13
17
  /**
14
18
  * One id from {@link CEREMONY_IDS}.
15
19
  */
@@ -1 +1 @@
1
- {"version":3,"file":"ceremony.d.ts","sourceRoot":"","sources":["../../src/space/ceremony.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;GAIG;AAEH;;GAEG;AACH,eAAO,MAAM,YAAY,uSAaf,CAAA;AAEV;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAA"}
1
+ {"version":3,"file":"ceremony.d.ts","sourceRoot":"","sources":["../../src/space/ceremony.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;GAMG;AAEH;;;;GAIG;AACH,eAAO,MAAM,YAAY,gXAiBf,CAAA;AAEV;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAA"}
@@ -2,12 +2,16 @@
2
2
  * Copyright (c) 2026 Interop Alliance. All rights reserved.
3
3
  */
4
4
  /**
5
- * The typed ceremony vocabulary: one stable id per shared account ceremony.
6
- * The ids are code-only identifiers (nothing persists them yet); each names
7
- * one ceremony documented in the wallets' ceremony inventories.
5
+ * The typed ceremony vocabulary: one stable id per account ceremony either
6
+ * wallet runs. Most have a shared half in this package; some are still
7
+ * implemented app-side. The ids are code-only identifiers (nothing persists
8
+ * them yet); each names one ceremony documented in the wallets' ceremony
9
+ * inventories.
8
10
  */
9
11
  /**
10
- * The shared account ceremony ids, in ceremony-inventory order.
12
+ * The account ceremony ids, in ceremony-inventory order. The last four
13
+ * (account deletion, the shared wipe executor, content migration, and backup
14
+ * export) are implemented in the app for now.
11
15
  */
12
16
  export const CEREMONY_IDS = [
13
17
  'account-genesis',
@@ -21,6 +25,10 @@ export const CEREMONY_IDS = [
21
25
  'unlock-credential-rotation',
22
26
  'forget-client',
23
27
  'last-client-transition',
24
- 'update-key-rotation'
28
+ 'update-key-rotation',
29
+ 'account-deletion',
30
+ 'wallet-wipe',
31
+ 'content-migration',
32
+ 'backup-export'
25
33
  ];
26
34
  //# sourceMappingURL=ceremony.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ceremony.js","sourceRoot":"","sources":["../../src/space/ceremony.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;GAIG;AAEH;;GAEG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,iBAAiB;IACjB,6BAA6B;IAC7B,iBAAiB;IACjB,mBAAmB;IACnB,mBAAmB;IACnB,wBAAwB;IACxB,qBAAqB;IACrB,0BAA0B;IAC1B,4BAA4B;IAC5B,eAAe;IACf,wBAAwB;IACxB,qBAAqB;CACb,CAAA"}
1
+ {"version":3,"file":"ceremony.js","sourceRoot":"","sources":["../../src/space/ceremony.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;GAMG;AAEH;;;;GAIG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,iBAAiB;IACjB,6BAA6B;IAC7B,iBAAiB;IACjB,mBAAmB;IACnB,mBAAmB;IACnB,wBAAwB;IACxB,qBAAqB;IACrB,0BAA0B;IAC1B,4BAA4B;IAC5B,eAAe;IACf,wBAAwB;IACxB,qBAAqB;IACrB,kBAAkB;IAClB,aAAa;IACb,mBAAmB;IACnB,eAAe;CACP,CAAA"}
@@ -34,8 +34,8 @@
34
34
  * `parseWasLinkPayload` / `encodeWasLinkSecret`) and `isWasLinkPayload`,
35
35
  * the recognizer a wallet hands `@interop/wallet-request`'s input
36
36
  * classifier.
37
- * - `CEREMONY_IDS` / `CeremonyId`, the typed vocabulary of shared account
38
- * ceremony ids.
37
+ * - `CEREMONY_IDS` / `CeremonyId`, the typed vocabulary of account ceremony
38
+ * ids, including the ceremonies still implemented app-side.
39
39
  */
40
40
  export { deleteSpaceWithCapability } from './deleteSpace.js';
41
41
  export { WALLET_SPACE_NAME, PRIVATE_CREDENTIALS_COLLECTION, PUBLIC_CREDENTIALS_COLLECTION, WALLET_ACTIVITY_COLLECTION, APP_CONNECTIONS_COLLECTION, REGISTERED_WRITERS_COLLECTION, PRIVATE_CREDENTIALS_COLLECTION_SPEC, PUBLIC_CREDENTIALS_COLLECTION_SPEC, WALLET_ACTIVITY_COLLECTION_SPEC, CONTACTS_SPACE_COLLECTION_SPEC, CONTACTS_HISTORY_SPACE_COLLECTION_SPEC, APP_CONNECTIONS_COLLECTION_SPEC, REGISTERED_WRITERS_COLLECTION_SPEC, WALLET_SPACE_SYNCED_SPECS, WALLET_SPACE_SYSTEM_SPECS, WALLET_SPACE_PROVISION_ROSTER } from './collections.js';
@@ -34,8 +34,8 @@
34
34
  * `parseWasLinkPayload` / `encodeWasLinkSecret`) and `isWasLinkPayload`,
35
35
  * the recognizer a wallet hands `@interop/wallet-request`'s input
36
36
  * classifier.
37
- * - `CEREMONY_IDS` / `CeremonyId`, the typed vocabulary of shared account
38
- * ceremony ids.
37
+ * - `CEREMONY_IDS` / `CeremonyId`, the typed vocabulary of account ceremony
38
+ * ids, including the ceremonies still implemented app-side.
39
39
  */
40
40
  export { deleteSpaceWithCapability } from './deleteSpace.js';
41
41
  export { WALLET_SPACE_NAME, PRIVATE_CREDENTIALS_COLLECTION, PUBLIC_CREDENTIALS_COLLECTION, WALLET_ACTIVITY_COLLECTION, APP_CONNECTIONS_COLLECTION, REGISTERED_WRITERS_COLLECTION, PRIVATE_CREDENTIALS_COLLECTION_SPEC, PUBLIC_CREDENTIALS_COLLECTION_SPEC, WALLET_ACTIVITY_COLLECTION_SPEC, CONTACTS_SPACE_COLLECTION_SPEC, CONTACTS_HISTORY_SPACE_COLLECTION_SPEC, APP_CONNECTIONS_COLLECTION_SPEC, REGISTERED_WRITERS_COLLECTION_SPEC, WALLET_SPACE_SYNCED_SPECS, WALLET_SPACE_SYSTEM_SPECS, WALLET_SPACE_PROVISION_ROSTER } from './collections.js';
@@ -45,6 +45,17 @@ export interface SyncEngineDeps {
45
45
  * conflict.
46
46
  */
47
47
  resolveConflict?: ResolveConflict;
48
+ /**
49
+ * This replica's writer-attribution label (the WAS `writerId`), minted and
50
+ * kept app-side. The engine never mints, persists, or derives one. When
51
+ * present, every push declares it as the `Writer-Id` header, and the pull
52
+ * skips decrypting its own echoes where the store confirms it holds them
53
+ * ({@link SyncStore.heldRevisions}). When absent, pushes declare no label
54
+ * (clearing any stored one, under the server's declare-or-clear rule) and
55
+ * suppression is off. A session that must not reveal a stable label to the
56
+ * host leaves it absent or passes a per-session one.
57
+ */
58
+ writerId?: string;
48
59
  batchSize?: number;
49
60
  /**
50
61
  * Idempotent space + collection provisioning. For an encrypted collection
@@ -1 +1 @@
1
- {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/sync/engine.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAA;AAC1D,OAAO,KAAK,EAAE,IAAI,EAAE,eAAe,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAQ/E;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,WAAW,CAAA;IACjB,KAAK,EAAE,SAAS,CAAA;IAChB;;;;;OAKG;IACH,UAAU,EAAE,CAAC,OAAO,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,IAAI,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACtE;;;OAGG;IACH,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,IAAI,KAAK,OAAO,CAAA;IAC5C;;;;OAIG;IACH,eAAe,CAAC,EAAE,eAAe,CAAA;IACjC,SAAS,CAAC,EAAE,MAAM,CAAA;IAElB;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,iBAAiB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IACtC;;;;;;;;;OASG;IACH,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACtD;;OAEG;IACH,UAAU,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAA;IAClC;;OAEG;IACH,gBAAgB,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACxD;;OAEG;IACH,aAAa,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAClC;;OAEG;IACH,eAAe,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAEpC;;OAEG;IACH,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI,CAAA;IAC7C;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,IAAI,CAAA;IAE1B,OAAO,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IACvD;;OAEG;IACH,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,IAAI,EAAE,OAAO,EAAE,MAAM,KAAK,MAAM,IAAI,CAAA;IAC1D;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,MAAM,CAAA;CACtB;AAOD,qBAAa,UAAU;IAmBT,OAAO,CAAC,QAAQ,CAAC,IAAI;IAlBjC,MAAM,EAAE,UAAU,CAAS;IAE3B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAQ;IAClC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAQ;IACpC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAQ;IACnC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAiD;IAC1E,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;IAErC,OAAO,CAAC,OAAO,CAAQ;IACvB,OAAO,CAAC,cAAc,CAAQ;IAC9B,OAAO,CAAC,OAAO,CAAQ;IACvB,OAAO,CAAC,YAAY,CAAI;IACxB,OAAO,CAAC,UAAU,CAA6B;IAC/C,OAAO,CAAC,eAAe,CAA+B;IACtD,OAAO,CAAC,WAAW,CAA4B;IAC/C,OAAO,CAAC,WAAW,CAAQ;IAC3B,OAAO,CAAC,sBAAsB,CAAI;gBAEL,IAAI,EAAE,cAAc;IAQjD;;;;;;;;OAQG;IACH,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAYrB;;;;;;OAMG;IACH,sBAAsB,IAAI,IAAI;IAQ9B;;;;;OAKG;IACH,IAAI,IAAI,IAAI;YAOE,GAAG;IA8BjB;;;;;;;;;;;;;;;;;;;OAmBG;YACW,QAAQ;YAsER,IAAI;IAYlB,OAAO,CAAC,aAAa;IAgBrB,OAAO,CAAC,UAAU;IAOlB,OAAO,CAAC,SAAS;CAOlB"}
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/sync/engine.ts"],"names":[],"mappings":"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"}
@@ -171,6 +171,7 @@ export class SyncEngine {
171
171
  port: this.deps.port,
172
172
  store: this.deps.store,
173
173
  resolveConflict: this.deps.resolveConflict,
174
+ writerId: this.deps.writerId,
174
175
  signal
175
176
  });
176
177
  if (signal.aborted) {
@@ -198,6 +199,7 @@ export class SyncEngine {
198
199
  batchSize: this.batchSize,
199
200
  decryptDoc: this.deps.decryptDoc,
200
201
  validatePayload: this.deps.validatePayload,
202
+ writerId: this.deps.writerId,
201
203
  signal
202
204
  });
203
205
  return applied;
@@ -1 +1 @@
1
- {"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/sync/engine.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/sync/engine.ts"],"names":[],"mappings":"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"}
@@ -57,10 +57,14 @@ export declare function projectionForDoc(doc: WireDoc, decryptDoc: (options: {
57
57
  * Promise<Json>}
58
58
  * @param [options.validatePayload] {(payload: Json) => boolean} collection
59
59
  * payload guard; a decrypted document failing it is stored but not projected
60
+ * @param [options.writerId] {string} this writer's attribution label; turns
61
+ * on echo suppression when the store implements `heldRevisions`
60
62
  * @param [options.signal] {AbortSignal}
61
- * @returns {Promise<{ applied: number }>} documents applied across all pages
63
+ * @returns {Promise<{ applied: number; suppressed: number }>} documents
64
+ * applied across all pages, and how many of them skipped the decrypt as a
65
+ * held own-writer echo
62
66
  */
63
- export declare function runPull({ port, store, batchSize, decryptDoc, validatePayload, signal }: {
67
+ export declare function runPull({ port, store, batchSize, decryptDoc, validatePayload, writerId, signal }: {
64
68
  port: WasSyncPort;
65
69
  store: SyncStore;
66
70
  batchSize: number;
@@ -69,8 +73,10 @@ export declare function runPull({ port, store, batchSize, decryptDoc, validatePa
69
73
  envelope: Json;
70
74
  }) => Promise<Json>;
71
75
  validatePayload?: (payload: Json) => boolean;
76
+ writerId?: string;
72
77
  signal?: AbortSignal;
73
78
  }): Promise<{
74
79
  applied: number;
80
+ suppressed: number;
75
81
  }>;
76
82
  //# sourceMappingURL=pull.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pull.d.ts","sourceRoot":"","sources":["../../src/sync/pull.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EACV,IAAI,EACJ,gBAAgB,EAEhB,SAAS,EACT,WAAW,EACX,OAAO,EACR,MAAM,YAAY,CAAA;AAEnB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,OAAO,EACZ,UAAU,EAAE,CAAC,OAAO,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,IAAI,CAAA;CAAE,KAAK,OAAO,CAAC,IAAI,CAAC,EACtE,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,IAAI,KAAK,OAAO,GAC3C,OAAO,CAAC,gBAAgB,CAAC,CAkC3B;AAqBD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,OAAO,CAAC,EAC5B,IAAI,EACJ,KAAK,EACL,SAAS,EACT,UAAU,EACV,eAAe,EACf,MAAM,EACP,EAAE;IACD,IAAI,EAAE,WAAW,CAAA;IACjB,KAAK,EAAE,SAAS,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,CAAC,OAAO,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,IAAI,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACtE,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,IAAI,KAAK,OAAO,CAAA;IAC5C,MAAM,CAAC,EAAE,WAAW,CAAA;CACrB,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAyD/B"}
1
+ {"version":3,"file":"pull.d.ts","sourceRoot":"","sources":["../../src/sync/pull.ts"],"names":[],"mappings":"AAoCA,OAAO,KAAK,EACV,IAAI,EACJ,gBAAgB,EAEhB,SAAS,EACT,WAAW,EACX,OAAO,EACR,MAAM,YAAY,CAAA;AAEnB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,OAAO,EACZ,UAAU,EAAE,CAAC,OAAO,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,IAAI,CAAA;CAAE,KAAK,OAAO,CAAC,IAAI,CAAC,EACtE,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,IAAI,KAAK,OAAO,GAC3C,OAAO,CAAC,gBAAgB,CAAC,CAkC3B;AA4DD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAsB,OAAO,CAAC,EAC5B,IAAI,EACJ,KAAK,EACL,SAAS,EACT,UAAU,EACV,eAAe,EACf,QAAQ,EACR,MAAM,EACP,EAAE;IACD,IAAI,EAAE,WAAW,CAAA;IACjB,KAAK,EAAE,SAAS,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,CAAC,OAAO,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,IAAI,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACtE,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,IAAI,KAAK,OAAO,CAAA;IAC5C,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,WAAW,CAAA;CACrB,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,CAiEnD"}
package/dist/sync/pull.js CHANGED
@@ -19,6 +19,17 @@
19
19
  * never overwrite it with `null`, or the feed restarts from the beginning.
20
20
  * - A tombstone deletes the projected row; a live document decrypts its `data`
21
21
  * body to the payload to upsert.
22
+ *
23
+ * Echo suppression is an optimization on top of that and must not change what
24
+ * converges. A live feed document whose `writerId` equals the engine's own
25
+ * injected label, and whose revision the store confirms it already holds
26
+ * ({@link SyncStore.heldRevisions}), skips the decrypt and applies with a
27
+ * `none` projection: the local projection already reflects that revision,
28
+ * since this replica wrote it. Every other document -- no `writerId`, a
29
+ * foreign one, or one the store does not confirm -- is decrypted exactly as
30
+ * before. The label is advisory plaintext a host can rewrite, which is why the
31
+ * store's revision check, not the label, is what licenses the skip: a forged
32
+ * label on a revision this replica does not hold still decrypts.
22
33
  */
23
34
  import { isIntegrityError } from '@interop/was-client/sync';
24
35
  import { log } from '../log.js';
@@ -105,6 +116,36 @@ function sameCheckpoint(left, right) {
105
116
  }
106
117
  return left.id === right.id && left.updatedAt === right.updatedAt;
107
118
  }
119
+ /**
120
+ * The ids of a page's own-writer echoes the store already holds. A document
121
+ * qualifies as a candidate when it is live, carries an `etag`, and names
122
+ * `writerId`; the store then confirms which of those revisions it holds.
123
+ * Suppression is off (an empty set) when no `writerId` was injected or the
124
+ * store does not implement {@link SyncStore.heldRevisions}.
125
+ *
126
+ * @param options {object}
127
+ * @param options.store {SyncStore}
128
+ * @param options.documents {WireDoc[]}
129
+ * @param [options.writerId] {string}
130
+ * @returns {Promise<Set<string>>}
131
+ */
132
+ async function heldEchoes({ store, documents, writerId }) {
133
+ if (writerId === undefined || store.heldRevisions === undefined) {
134
+ return new Set();
135
+ }
136
+ const candidates = [];
137
+ for (const doc of documents) {
138
+ if (!doc._deleted && doc.etag !== undefined && doc.writerId === writerId) {
139
+ candidates.push({ id: doc.id, etag: doc.etag });
140
+ }
141
+ }
142
+ if (candidates.length === 0) {
143
+ return new Set();
144
+ }
145
+ const confirmed = await store.heldRevisions({ documents: candidates });
146
+ // Only a candidate can be suppressed, whatever else the store answers.
147
+ return new Set(candidates.map(({ id }) => id).filter(id => confirmed.has(id)));
148
+ }
108
149
  /**
109
150
  * Runs the pull loop to exhaustion for one feed. Fetches a page from the current
110
151
  * checkpoint, decrypts it to projections, and applies it (upserts + projection +
@@ -124,11 +165,16 @@ function sameCheckpoint(left, right) {
124
165
  * Promise<Json>}
125
166
  * @param [options.validatePayload] {(payload: Json) => boolean} collection
126
167
  * payload guard; a decrypted document failing it is stored but not projected
168
+ * @param [options.writerId] {string} this writer's attribution label; turns
169
+ * on echo suppression when the store implements `heldRevisions`
127
170
  * @param [options.signal] {AbortSignal}
128
- * @returns {Promise<{ applied: number }>} documents applied across all pages
171
+ * @returns {Promise<{ applied: number; suppressed: number }>} documents
172
+ * applied across all pages, and how many of them skipped the decrypt as a
173
+ * held own-writer echo
129
174
  */
130
- export async function runPull({ port, store, batchSize, decryptDoc, validatePayload, signal }) {
175
+ export async function runPull({ port, store, batchSize, decryptDoc, validatePayload, writerId, signal }) {
131
176
  let applied = 0;
177
+ let suppressed = 0;
132
178
  for (;;) {
133
179
  if (signal?.aborted) {
134
180
  break;
@@ -147,7 +193,11 @@ export async function runPull({ port, store, batchSize, decryptDoc, validatePayl
147
193
  // Decrypt the whole page concurrently -- each document is independent, and
148
194
  // decryption dominates the page's cost. The entries are collected in
149
195
  // document order, so `projections` is keyed identically to a sequential run.
150
- const actions = await Promise.all(documents.map(doc => projectionForDoc(doc, decryptDoc, validatePayload)));
196
+ // A held own-writer echo skips the decrypt with a `none` projection.
197
+ const held = await heldEchoes({ store, documents, writerId });
198
+ const actions = await Promise.all(documents.map(doc => held.has(doc.id)
199
+ ? Promise.resolve({ kind: 'none' })
200
+ : projectionForDoc(doc, decryptDoc, validatePayload)));
151
201
  const projections = new Map(documents.map((doc, index) => [doc.id, actions[index]]));
152
202
  // A lock/stop between decrypt and apply drops this page (checkpoint not
153
203
  // advanced), leaving it to a clean re-pull -- cheaper than holding the write
@@ -161,6 +211,7 @@ export async function runPull({ port, store, batchSize, decryptDoc, validatePayl
161
211
  projections
162
212
  });
163
213
  applied += documents.length;
214
+ suppressed += held.size;
164
215
  // Caught-up is decided by the SERVER, not by page size: a server free to
165
216
  // clamp `limit` returns full-but-short pages forever, so a
166
217
  // `documents.length < batchSize` test would stop the loop one page into the
@@ -173,6 +224,6 @@ export async function runPull({ port, store, batchSize, decryptDoc, validatePayl
173
224
  break;
174
225
  }
175
226
  }
176
- return { applied };
227
+ return { applied, suppressed };
177
228
  }
178
229
  //# sourceMappingURL=pull.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"pull.js","sourceRoot":"","sources":["../../src/sync/pull.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pull.js","sourceRoot":"","sources":["../../src/sync/pull.ts"],"names":[],"mappings":"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"}
@@ -9,15 +9,18 @@ import type { ResolveConflict, SyncStore, WasSyncPort } from './types.js';
9
9
  * @param options.port {WasSyncPort}
10
10
  * @param options.store {SyncStore}
11
11
  * @param [options.resolveConflict] {ResolveConflict} mutable-collection policy
12
+ * @param [options.writerId] {string} this writer's attribution label, sent
13
+ * as `Writer-Id` on every write and delete; absent sends none
12
14
  * @param [options.signal] {AbortSignal}
13
15
  * @returns {Promise<{ pushed: number; conflictsResolved: number }>} dirty rows
14
16
  * processed this cycle, and how many invoked the LWW resolver (a positive
15
17
  * count means the caller should rerun so a local-wins re-push settles)
16
18
  */
17
- export declare function runPush({ port, store, resolveConflict, signal }: {
19
+ export declare function runPush({ port, store, resolveConflict, writerId, signal }: {
18
20
  port: WasSyncPort;
19
21
  store: SyncStore;
20
22
  resolveConflict?: ResolveConflict;
23
+ writerId?: string;
21
24
  signal?: AbortSignal;
22
25
  }): Promise<{
23
26
  pushed: number;
@@ -1 +1 @@
1
- {"version":3,"file":"push.d.ts","sourceRoot":"","sources":["../../src/sync/push.ts"],"names":[],"mappings":"AA+BA,OAAO,KAAK,EAAQ,eAAe,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AA2L/E;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,OAAO,CAAC,EAC5B,IAAI,EACJ,KAAK,EACL,eAAe,EACf,MAAM,EACP,EAAE;IACD,IAAI,EAAE,WAAW,CAAA;IACjB,KAAK,EAAE,SAAS,CAAA;IAChB,eAAe,CAAC,EAAE,eAAe,CAAA;IACjC,MAAM,CAAC,EAAE,WAAW,CAAA;CACrB,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,iBAAiB,EAAE,MAAM,CAAA;CAAE,CAAC,CAwBzD"}
1
+ {"version":3,"file":"push.d.ts","sourceRoot":"","sources":["../../src/sync/push.ts"],"names":[],"mappings":"AAsCA,OAAO,KAAK,EAAQ,eAAe,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAqM/E;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,OAAO,CAAC,EAC5B,IAAI,EACJ,KAAK,EACL,eAAe,EACf,QAAQ,EACR,MAAM,EACP,EAAE;IACD,IAAI,EAAE,WAAW,CAAA;IACjB,KAAK,EAAE,SAAS,CAAA;IAChB,eAAe,CAAC,EAAE,eAAe,CAAA;IACjC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,WAAW,CAAA;CACrB,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,iBAAiB,EAAE,MAAM,CAAA;CAAE,CAAC,CAyBzD"}
package/dist/sync/push.js CHANGED
@@ -24,6 +24,13 @@
24
24
  * folding a `putMeta` diff into this loop would add an untested code path with
25
25
  * no collection to exercise it. The `WasSyncPort.putMeta` capability stays
26
26
  * optional on the port for the driver that needs it.
27
+ *
28
+ * Every content write and delete carries the engine's injected `writerId`, when
29
+ * one was injected, as the `Writer-Id` header (the WAS writer-attribution
30
+ * label). The label is minted app-side; this loop never mints, persists, or
31
+ * derives one. The server's declare-or-clear rule means a write without it
32
+ * clears the stored label, so an engine run without a `writerId` attributes
33
+ * nothing rather than leaving a previous writer's label in place.
27
34
  */
28
35
  import { isSyncConflictError, isSyncNotFoundError } from '@interop/was-client/sync';
29
36
  /**
@@ -46,12 +53,13 @@ import { isSyncConflictError, isSyncNotFoundError } from '@interop/was-client/sy
46
53
  * absent/tombstone -> deletion wins, adopt the tombstone and delete the
47
54
  * projection (a later re-add re-encrypts to a fresh id, so nothing is blocked).
48
55
  */
49
- async function pushUpsert({ port, store, row, resolveConflict }) {
56
+ async function pushUpsert({ port, store, row, resolveConflict, writerId }) {
50
57
  try {
51
58
  const ack = await port.putContent({
52
59
  id: row.id,
53
60
  data: row.data ?? null,
54
- ...(row.version > 0 ? { ifMatch: row.etag } : { ifNoneMatch: true })
61
+ ...(row.version > 0 ? { ifMatch: row.etag } : { ifNoneMatch: true }),
62
+ ...(writerId !== undefined && { writerId })
55
63
  });
56
64
  await store.markPushed({
57
65
  id: row.id,
@@ -100,12 +108,13 @@ async function pushUpsert({ port, store, row, resolveConflict }) {
100
108
  * on a `412` so the caller can re-read and retry. Any other error propagates to
101
109
  * the engine's backoff.
102
110
  */
103
- async function tryDelete({ port, store, id, ifMatch, revision }) {
111
+ async function tryDelete({ port, store, id, ifMatch, revision, writerId }) {
104
112
  const revisionAck = revision !== undefined ? { revision } : {};
105
113
  try {
106
114
  const ack = await port.deleteContent({
107
115
  id,
108
- ...(ifMatch !== undefined && { ifMatch })
116
+ ...(ifMatch !== undefined && { ifMatch }),
117
+ ...(writerId !== undefined && { writerId })
109
118
  });
110
119
  await store.markDeletedPushed({
111
120
  id,
@@ -136,7 +145,7 @@ async function tryDelete({ port, store, id, ifMatch, revision }) {
136
145
  * refreshes its `version` / `etag` via the dirty-deleted-vs-live rule, so the
137
146
  * retry's `If-Match` becomes current).
138
147
  */
139
- async function pushDelete({ port, store, row }) {
148
+ async function pushDelete({ port, store, row, writerId }) {
140
149
  const revisionAck = row.revision !== undefined ? { revision: row.revision } : {};
141
150
  const firstIfMatch = row.version > 0 ? row.etag : undefined;
142
151
  if (await tryDelete({
@@ -144,6 +153,7 @@ async function pushDelete({ port, store, row }) {
144
153
  store,
145
154
  id: row.id,
146
155
  ifMatch: firstIfMatch,
156
+ writerId,
147
157
  ...revisionAck
148
158
  })) {
149
159
  return;
@@ -162,6 +172,7 @@ async function pushDelete({ port, store, row }) {
162
172
  store,
163
173
  id: row.id,
164
174
  ifMatch: master.etag,
175
+ writerId,
165
176
  ...revisionAck
166
177
  });
167
178
  }
@@ -175,12 +186,14 @@ async function pushDelete({ port, store, row }) {
175
186
  * @param options.port {WasSyncPort}
176
187
  * @param options.store {SyncStore}
177
188
  * @param [options.resolveConflict] {ResolveConflict} mutable-collection policy
189
+ * @param [options.writerId] {string} this writer's attribution label, sent
190
+ * as `Writer-Id` on every write and delete; absent sends none
178
191
  * @param [options.signal] {AbortSignal}
179
192
  * @returns {Promise<{ pushed: number; conflictsResolved: number }>} dirty rows
180
193
  * processed this cycle, and how many invoked the LWW resolver (a positive
181
194
  * count means the caller should rerun so a local-wins re-push settles)
182
195
  */
183
- export async function runPush({ port, store, resolveConflict, signal }) {
196
+ export async function runPush({ port, store, resolveConflict, writerId, signal }) {
184
197
  const rows = await store.getDirtyRows();
185
198
  let pushed = 0;
186
199
  let conflictsResolved = 0;
@@ -189,14 +202,15 @@ export async function runPush({ port, store, resolveConflict, signal }) {
189
202
  break;
190
203
  }
191
204
  if (row.deleted) {
192
- await pushDelete({ port, store, row });
205
+ await pushDelete({ port, store, row, writerId });
193
206
  }
194
207
  else {
195
208
  const { conflictResolved } = await pushUpsert({
196
209
  port,
197
210
  store,
198
211
  row,
199
- resolveConflict
212
+ resolveConflict,
213
+ writerId
200
214
  });
201
215
  if (conflictResolved) {
202
216
  conflictsResolved += 1;
@@ -1 +1 @@
1
- {"version":3,"file":"push.js","sourceRoot":"","sources":["../../src/sync/push.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"push.js","sourceRoot":"","sources":["../../src/sync/push.ts"],"names":[],"mappings":"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"}
@@ -165,6 +165,28 @@ export interface SyncStore {
165
165
  latest: MasterState | null;
166
166
  projection: ProjectionAction;
167
167
  }): Promise<void>;
168
+ /**
169
+ * Which of these feed revisions does the replica already hold? Answers with
170
+ * the ids whose local row records exactly that `etag` as its validator (the
171
+ * one a push ack or an earlier pull recorded). The pull loop asks it only
172
+ * about live feed documents carrying the engine's own `writerId`, and skips
173
+ * the decrypt of each confirmed one, applying it with a `none` projection
174
+ * (see `pull.ts`). The label is host-visible plaintext, so the skip also
175
+ * requires the `etag` match. That match limits the skip to a revision the
176
+ * replica already records. It does not authenticate the label or the
177
+ * envelope, since the `etag` is host-supplied too. A host that replays an
178
+ * older envelope under the current `etag` gets the local projection left
179
+ * as it was, where a decrypt would have rolled it back.
180
+ *
181
+ * Optional: a store that omits it turns echo suppression off, and every
182
+ * echo is decrypted as before.
183
+ */
184
+ heldRevisions?(options: {
185
+ documents: {
186
+ id: string;
187
+ etag: string;
188
+ }[];
189
+ }): Promise<Set<string>>;
168
190
  /**
169
191
  * Replaces the body of a pending row (dirty, never-acked, live -- no feed
170
192
  * existence) with a re-minted envelope, re-keying the row from `id` to
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/sync/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,EACrB,MAAM,0BAA0B,CAAA;AACjC,YAAY,EACV,IAAI,EACJ,cAAc,EACd,OAAO,EACP,WAAW,EACX,QAAQ,EACR,WAAW,EACX,SAAS,EACV,MAAM,0BAA0B,CAAA;AAEjC,OAAO,KAAK,EACV,IAAI,EACJ,WAAW,EACX,cAAc,EACd,OAAO,EACR,MAAM,0BAA0B,CAAA;AAEjC;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAA;IACV,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,OAAO,CAAA;IAChB,IAAI,EAAE,IAAI,GAAG,IAAI,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;CAC3B;AAED;;;;;;;;;GASG;AACH,MAAM,MAAM,gBAAgB,GAC1B;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAA;AAE3E;;;;;;;;GAQG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,GAAG,EAAE;IAClC,EAAE,EAAE,MAAM,CAAA;IACV,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,IAAI,GAAG,IAAI,CAAA;CAClB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;AAEnB;;;;;;GAMG;AACH,MAAM,WAAW,SAAS;IACxB;;OAEG;IACH,aAAa,IAAI,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CAAA;IAEpD;;OAEG;IACH,YAAY,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC,CAAA;IAEpC;;;;;;;;OAQG;IACH,eAAe,CAAC,OAAO,EAAE;QACvB,SAAS,EAAE,OAAO,EAAE,CAAA;QACpB,UAAU,EAAE,cAAc,CAAA;QAC1B,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAA;KAC3C,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAEjB;;;;;;;;;;OAUG;IACH,UAAU,CAAC,OAAO,EAAE;QAClB,EAAE,EAAE,MAAM,CAAA;QACV,OAAO,CAAC,EAAE,MAAM,CAAA;QAChB,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;KAC3B,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAEjB;;;;;;OAMG;IACH,iBAAiB,CAAC,OAAO,EAAE;QACzB,EAAE,EAAE,MAAM,CAAA;QACV,OAAO,CAAC,EAAE,MAAM,CAAA;QAChB,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;KAC3B,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAEjB;;;;;;;;OAQG;IACH,WAAW,CAAC,OAAO,EAAE;QACnB,EAAE,EAAE,MAAM,CAAA;QACV,MAAM,EAAE,WAAW,GAAG,IAAI,CAAA;QAC1B,UAAU,EAAE,gBAAgB,CAAA;KAC7B,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAEjB;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACH,cAAc,CAAC,CAAC,OAAO,EAAE;QACvB,EAAE,EAAE,MAAM,CAAA;QACV,KAAK,EAAE,MAAM,CAAA;QACb,QAAQ,EAAE,IAAI,CAAA;QACd,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;KAC3B,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAA;CAClC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/sync/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@interop/wallet-core",
3
3
  "description": "Shared wallet-domain logic (WAS sync engine core and wallet Space layout contracts) for Interop wallet apps.",
4
- "version": "0.84.0",
4
+ "version": "0.86.0",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "build": "pnpm run clear && tsc",
@@ -37,8 +37,8 @@
37
37
  "devDependencies": {
38
38
  "@eslint/js": "^10.0.1",
39
39
  "@interop/logger": "^0.2.0",
40
- "@interop/storage-core": "^0.21.0",
41
- "@interop/was-client": "^0.78.0",
40
+ "@interop/storage-core": "^0.22.0",
41
+ "@interop/was-client": "^0.80.0",
42
42
  "@playwright/test": "^1.60.0",
43
43
  "@types/node": "^26.0.1",
44
44
  "@vitest/coverage-v8": "^4.1.7",