@interop/was-client 0.33.0 → 0.35.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/README.md +112 -0
  2. package/dist/Collection.d.ts +172 -1
  3. package/dist/Collection.d.ts.map +1 -1
  4. package/dist/Collection.js +368 -2
  5. package/dist/Collection.js.map +1 -1
  6. package/dist/codec.d.ts +101 -3
  7. package/dist/codec.d.ts.map +1 -1
  8. package/dist/edv/EdvCodec.d.ts +34 -4
  9. package/dist/edv/EdvCodec.d.ts.map +1 -1
  10. package/dist/edv/EdvCodec.js +268 -42
  11. package/dist/edv/EdvCodec.js.map +1 -1
  12. package/dist/edv/docCipher.d.ts.map +1 -1
  13. package/dist/edv/docCipher.js +5 -9
  14. package/dist/edv/docCipher.js.map +1 -1
  15. package/dist/edv/hmacKey.d.ts +76 -0
  16. package/dist/edv/hmacKey.d.ts.map +1 -0
  17. package/dist/edv/hmacKey.js +105 -0
  18. package/dist/edv/hmacKey.js.map +1 -0
  19. package/dist/edv/index.d.ts +7 -0
  20. package/dist/edv/index.d.ts.map +1 -1
  21. package/dist/edv/index.js +6 -0
  22. package/dist/edv/index.js.map +1 -1
  23. package/dist/edv/recipients.d.ts +22 -3
  24. package/dist/edv/recipients.d.ts.map +1 -1
  25. package/dist/edv/recipients.js +197 -21
  26. package/dist/edv/recipients.js.map +1 -1
  27. package/dist/errors.d.ts +28 -0
  28. package/dist/errors.d.ts.map +1 -1
  29. package/dist/errors.js +36 -0
  30. package/dist/errors.js.map +1 -1
  31. package/dist/index.d.ts +3 -3
  32. package/dist/index.d.ts.map +1 -1
  33. package/dist/index.js +1 -1
  34. package/dist/index.js.map +1 -1
  35. package/dist/internal/codec.d.ts.map +1 -1
  36. package/dist/internal/codec.js +64 -3
  37. package/dist/internal/codec.js.map +1 -1
  38. package/dist/internal/content.d.ts +12 -0
  39. package/dist/internal/content.d.ts.map +1 -1
  40. package/dist/internal/content.js +18 -0
  41. package/dist/internal/content.js.map +1 -1
  42. package/dist/internal/indexSchema.d.ts +95 -0
  43. package/dist/internal/indexSchema.d.ts.map +1 -0
  44. package/dist/internal/indexSchema.js +120 -0
  45. package/dist/internal/indexSchema.js.map +1 -0
  46. package/dist/internal/paths.d.ts +6 -0
  47. package/dist/internal/paths.d.ts.map +1 -1
  48. package/dist/internal/paths.js +8 -0
  49. package/dist/internal/paths.js.map +1 -1
  50. package/dist/internal/revoke.d.ts +21 -1
  51. package/dist/internal/revoke.d.ts.map +1 -1
  52. package/dist/internal/revoke.js +1 -1
  53. package/dist/internal/revoke.js.map +1 -1
  54. package/dist/paths.d.ts +30 -0
  55. package/dist/paths.d.ts.map +1 -0
  56. package/dist/paths.js +29 -0
  57. package/dist/paths.js.map +1 -0
  58. package/dist/sync/index.d.ts +6 -4
  59. package/dist/sync/index.d.ts.map +1 -1
  60. package/dist/sync/index.js +6 -4
  61. package/dist/sync/index.js.map +1 -1
  62. package/dist/sync/port.d.ts +34 -4
  63. package/dist/sync/port.d.ts.map +1 -1
  64. package/dist/sync/port.js +123 -20
  65. package/dist/sync/port.js.map +1 -1
  66. package/dist/sync/types.d.ts +12 -4
  67. package/dist/sync/types.d.ts.map +1 -1
  68. package/dist/types.d.ts +40 -1
  69. package/dist/types.d.ts.map +1 -1
  70. package/package.json +8 -2
package/dist/paths.js ADDED
@@ -0,0 +1,29 @@
1
+ /*!
2
+ * Copyright (c) 2026 Interop Alliance. All rights reserved.
3
+ */
4
+ /**
5
+ * The `@interop/was-client/paths` subpath entry: the WAS URL grammar as
6
+ * standalone functions, for a consumer that has to form a WAS path or a zcap
7
+ * `invocationTarget` without going through a navigational handle.
8
+ *
9
+ * The path builders own the trailing-slash canonicalization (item-create and
10
+ * listing endpoints carry a trailing slash; get/put/delete-by-id endpoints do
11
+ * not) and the per-segment percent-encoding, and the zcap `invocationTarget` is
12
+ * derived from the request URL -- so a caller that hand-assembles a path is
13
+ * re-deriving rules that must match the server's `allowedTarget` byte for byte.
14
+ * Exporting the builders instead is what keeps that from happening.
15
+ *
16
+ * `parseSpacePath` / `parseSpaceTarget` are the inverse grammar (a pathname or
17
+ * an absolute URL back to the containment depth it addresses), and
18
+ * `rootCapabilityId` / `rootCapability` mint the `urn:zcap:root:` capability a
19
+ * target's own root invocation names -- the id form for parenting an unparented
20
+ * grant, the object form for invoking it (`@interop/ezcap` accepts a bare root
21
+ * capability id only for an `https:` target, which would break against an
22
+ * `http://localhost` server).
23
+ *
24
+ * Kept off the core entry so a consumer opts in; every export here is a pure
25
+ * function with no I/O and no client state.
26
+ */
27
+ export { spacePath, collectionPath, collectionItems, collectionMeta, collectionQuery, resourcePath, resourceMeta, toUrl, parseSpacePath, parseSpaceTarget } from './internal/paths.js';
28
+ export { rootCapabilityId, rootCapability } from './internal/revoke.js';
29
+ //# sourceMappingURL=paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,OAAO,EACL,SAAS,EACT,cAAc,EACd,eAAe,EACf,cAAc,EACd,eAAe,EACf,YAAY,EACZ,YAAY,EACZ,KAAK,EACL,cAAc,EACd,gBAAgB,EACjB,MAAM,qBAAqB,CAAA;AAG5B,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA"}
@@ -16,16 +16,18 @@
16
16
  * - `ensureSpaceAndCollection` -- idempotent Space + Collection provisioning.
17
17
  *
18
18
  * The 412 conflict / 404 not-found port signals (`WasSyncConflictError` /
19
- * `WasSyncNotFoundError`) live in the client's typed error hierarchy and are
20
- * re-exported here for convenience -- as is the stale-descriptor decrypt
19
+ * `WasSyncNotFoundError`), and the opt-in revoked-access signal
20
+ * (`WasSyncAuthError`, raised only under `mapAuthErrors`), live in the client's
21
+ * typed error hierarchy and are re-exported here for convenience -- as is the
22
+ * stale-descriptor decrypt
21
23
  * signal (`UnknownEpochError`), so a crypto-free sync consumer can
22
24
  * `instanceof`-match it without importing the `/edv` entry that throws it.
23
25
  */
24
- export { createWasSyncPort, KEY_EPOCH_HEADER, formatEtag, parseEtag, errorStatus } from './port.js';
26
+ export { createWasSyncPort, KEY_EPOCH_HEADER, formatEtag, parseEtag, errorStatus, errorMessage } from './port.js';
25
27
  export { contentCid, cidFrom, deriveSpaceId } from './cid.js';
26
28
  export { isEncryptedEnvelope } from './envelope.js';
27
29
  export { createPlaintextDocCipher } from './plaintextCipher.js';
28
30
  export { ensureSpaceAndCollection } from './provisioning.js';
29
- export { UnknownEpochError, WasSyncConflictError, WasSyncNotFoundError } from '../errors.js';
31
+ export { UnknownEpochError, WasSyncAuthError, WasSyncConflictError, WasSyncNotFoundError } from '../errors.js';
30
32
  export type { Json, SyncCheckpoint, WireDoc, SyncPage, MasterState, WasSyncPort, DocCipher } from './types.js';
31
33
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sync/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,UAAU,EACV,SAAS,EACT,WAAW,EACZ,MAAM,WAAW,CAAA;AAClB,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAA;AACnD,OAAO,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAA;AAC/D,OAAO,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAA;AAC5D,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,EACrB,MAAM,cAAc,CAAA;AAErB,YAAY,EACV,IAAI,EACJ,cAAc,EACd,OAAO,EACP,QAAQ,EACR,WAAW,EACX,WAAW,EACX,SAAS,EACV,MAAM,YAAY,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sync/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,UAAU,EACV,SAAS,EACT,WAAW,EACX,YAAY,EACb,MAAM,WAAW,CAAA;AAClB,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAA;AACnD,OAAO,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAA;AAC/D,OAAO,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAA;AAC5D,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,oBAAoB,EACpB,oBAAoB,EACrB,MAAM,cAAc,CAAA;AAErB,YAAY,EACV,IAAI,EACJ,cAAc,EACd,OAAO,EACP,QAAQ,EACR,WAAW,EACX,WAAW,EACX,SAAS,EACV,MAAM,YAAY,CAAA"}
@@ -16,15 +16,17 @@
16
16
  * - `ensureSpaceAndCollection` -- idempotent Space + Collection provisioning.
17
17
  *
18
18
  * The 412 conflict / 404 not-found port signals (`WasSyncConflictError` /
19
- * `WasSyncNotFoundError`) live in the client's typed error hierarchy and are
20
- * re-exported here for convenience -- as is the stale-descriptor decrypt
19
+ * `WasSyncNotFoundError`), and the opt-in revoked-access signal
20
+ * (`WasSyncAuthError`, raised only under `mapAuthErrors`), live in the client's
21
+ * typed error hierarchy and are re-exported here for convenience -- as is the
22
+ * stale-descriptor decrypt
21
23
  * signal (`UnknownEpochError`), so a crypto-free sync consumer can
22
24
  * `instanceof`-match it without importing the `/edv` entry that throws it.
23
25
  */
24
- export { createWasSyncPort, KEY_EPOCH_HEADER, formatEtag, parseEtag, errorStatus } from './port.js';
26
+ export { createWasSyncPort, KEY_EPOCH_HEADER, formatEtag, parseEtag, errorStatus, errorMessage } from './port.js';
25
27
  export { contentCid, cidFrom, deriveSpaceId } from './cid.js';
26
28
  export { isEncryptedEnvelope } from './envelope.js';
27
29
  export { createPlaintextDocCipher } from './plaintextCipher.js';
28
30
  export { ensureSpaceAndCollection } from './provisioning.js';
29
- export { UnknownEpochError, WasSyncConflictError, WasSyncNotFoundError } from '../errors.js';
31
+ export { UnknownEpochError, WasSyncAuthError, WasSyncConflictError, WasSyncNotFoundError } from '../errors.js';
30
32
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sync/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,UAAU,EACV,SAAS,EACT,WAAW,EACZ,MAAM,WAAW,CAAA;AAClB,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAA;AACnD,OAAO,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAA;AAC/D,OAAO,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAA;AAC5D,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,EACrB,MAAM,cAAc,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sync/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,UAAU,EACV,SAAS,EACT,WAAW,EACX,YAAY,EACb,MAAM,WAAW,CAAA;AAClB,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAA;AACnD,OAAO,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAA;AAC/D,OAAO,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAA;AAC5D,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,oBAAoB,EACpB,oBAAoB,EACrB,MAAM,cAAc,CAAA"}
@@ -27,7 +27,8 @@
27
27
  */
28
28
  import type { WasClient } from '../WasClient.js';
29
29
  import { KEY_EPOCH_HEADER } from '../internal/conditional.js';
30
- import { httpStatus } from '../errors.js';
30
+ import { errorMessage, httpStatus } from '../errors.js';
31
+ import type { IZcap } from '../types.js';
31
32
  import type { WasSyncPort } from './types.js';
32
33
  /**
33
34
  * The request header the server reads a content write's key-epoch id from,
@@ -43,6 +44,12 @@ export { KEY_EPOCH_HEADER };
43
44
  * for the client's own {@link httpStatus}.
44
45
  */
45
46
  export declare const errorStatus: typeof httpStatus;
47
+ /**
48
+ * Normalizes an unknown caught error into a display string. The sync subpath's
49
+ * name for the client's own {@link errorMessage}, the companion to
50
+ * {@link errorStatus}.
51
+ */
52
+ export { errorMessage };
46
53
  /**
47
54
  * Formats a numeric content `version` as the quoted strong `ETag` an
48
55
  * update-if-unchanged write passes as its `ifMatch` precondition (e.g. `3` to
@@ -62,18 +69,41 @@ export declare function formatEtag(version: number): string;
62
69
  export declare function parseEtag(etag: string | null): number | undefined;
63
70
  /**
64
71
  * Builds a {@link WasSyncPort} bound to one Space + Collection, backed by the
65
- * caller's signed {@link WasClient}. Requests invoke the client's own root
66
- * capability (no delegated `capability` is attached).
72
+ * caller's signed {@link WasClient}. With no `capability`, requests invoke the
73
+ * client's own root capability.
74
+ *
75
+ * `mapAuthErrors` exists because a WAS server MASKS an authorization failure as
76
+ * `404` ("not found or invalid authorization") rather than `403`, so an
77
+ * unauthorized caller cannot probe which resources exist. A replica that
78
+ * already synced its Space and Collection knows they exist, so on its sync
79
+ * paths a `404` can only mean the invocation itself was rejected -- the
80
+ * expired- or revoked-grant signal it needs in order to stop retrying and
81
+ * prompt for a reconnect. The reading is only safe with that knowledge, so it
82
+ * is opt-in: off (the default), every status behaves exactly as before.
83
+ *
84
+ * Two paths keep their own `404` semantics even when it is on, because there a
85
+ * `404` is a modeled outcome rather than an anomaly: `deleteContent` resolves
86
+ * (the tombstone's goal state already holds -- an idempotent delete), and `get`
87
+ * resolves `null` (absent or tombstoned -- the deletion-wins input its callers
88
+ * depend on). Revoked access still surfaces within one poll on `query` and on
89
+ * the content/metadata writes.
67
90
  *
68
91
  * @param options {object}
69
92
  * @param options.was {WasClient} the session client (holds the signer)
70
93
  * @param options.spaceId {string} the WAS Space id
71
94
  * @param options.collectionId {string} the WAS collection id
95
+ * @param [options.capability] {IZcap} a delegated capability to invoke on
96
+ * every request this port makes (pull, writes, and reads alike); omit to
97
+ * invoke the client's own root capability
98
+ * @param [options.mapAuthErrors] {boolean} map `401` / `403` / the masked
99
+ * `404` to {@link WasSyncAuthError} (default `false`)
72
100
  * @returns {WasSyncPort}
73
101
  */
74
- export declare function createWasSyncPort({ was, spaceId, collectionId }: {
102
+ export declare function createWasSyncPort({ was, spaceId, collectionId, capability, mapAuthErrors }: {
75
103
  was: WasClient;
76
104
  spaceId: string;
77
105
  collectionId: string;
106
+ capability?: IZcap;
107
+ mapAuthErrors?: boolean;
78
108
  }): WasSyncPort;
79
109
  //# sourceMappingURL=port.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"port.d.ts","sourceRoot":"","sources":["../../src/sync/port.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAEhD,OAAO,EACL,gBAAgB,EAGjB,MAAM,4BAA4B,CAAA;AAEnC,OAAO,EACL,UAAU,EAGX,MAAM,cAAc,CAAA;AACrB,OAAO,KAAK,EAAqB,WAAW,EAAE,MAAM,YAAY,CAAA;AAEhE;;;;;GAKG;AACH,OAAO,EAAE,gBAAgB,EAAE,CAAA;AAW3B;;;;;GAKG;AACH,eAAO,MAAM,WAAW,mBAAa,CAAA;AA4BrC;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAElD;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,SAAS,CAMjE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,GAAG,EACH,OAAO,EACP,YAAY,EACb,EAAE;IACD,GAAG,EAAE,SAAS,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,YAAY,EAAE,MAAM,CAAA;CACrB,GAAG,WAAW,CAgJd"}
1
+ {"version":3,"file":"port.d.ts","sourceRoot":"","sources":["../../src/sync/port.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAEhD,OAAO,EACL,gBAAgB,EAGjB,MAAM,4BAA4B,CAAA;AAEnC,OAAO,EACL,YAAY,EACZ,UAAU,EAIX,MAAM,cAAc,CAAA;AACrB,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,KAAK,EAAqB,WAAW,EAAE,MAAM,YAAY,CAAA;AAEhE;;;;;GAKG;AACH,OAAO,EAAE,gBAAgB,EAAE,CAAA;AAW3B;;;;;GAKG;AACH,eAAO,MAAM,WAAW,mBAAa,CAAA;AAErC;;;;GAIG;AACH,OAAO,EAAE,YAAY,EAAE,CAAA;AAmDvB;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAElD;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,SAAS,CAMjE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,GAAG,EACH,OAAO,EACP,YAAY,EACZ,UAAU,EACV,aAAqB,EACtB,EAAE;IACD,GAAG,EAAE,SAAS,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,YAAY,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,KAAK,CAAA;IAClB,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB,GAAG,WAAW,CAwMd"}
package/dist/sync/port.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { KEY_EPOCH_HEADER, readEtag, writeHeaders } from '../internal/conditional.js';
2
2
  import { resourceMeta, resourcePath } from '../internal/paths.js';
3
- import { httpStatus, WasSyncConflictError, WasSyncNotFoundError } from '../errors.js';
3
+ import { errorMessage, httpStatus, WasSyncAuthError, WasSyncConflictError, WasSyncNotFoundError } from '../errors.js';
4
4
  /**
5
5
  * The request header the server reads a content write's key-epoch id from,
6
6
  * stamping it onto the Resource's metadata. Defined next to the header
@@ -23,19 +23,41 @@ const UNKNOWN_UPDATED_AT = new Date(0).toISOString();
23
23
  * for the client's own {@link httpStatus}.
24
24
  */
25
25
  export const errorStatus = httpStatus;
26
+ /**
27
+ * Normalizes an unknown caught error into a display string. The sync subpath's
28
+ * name for the client's own {@link errorMessage}, the companion to
29
+ * {@link errorStatus}.
30
+ */
31
+ export { errorMessage };
32
+ /**
33
+ * The statuses a WAS server can return for an authorization failure: `401` (no
34
+ * verifiable invocation), `403` (not permitted), and the `404` it returns when
35
+ * it masks an authorization failure as "not found".
36
+ *
37
+ * @param status {number | undefined}
38
+ * @returns {boolean}
39
+ */
40
+ function isAuthStatus(status) {
41
+ return status === 401 || status === 403 || status === 404;
42
+ }
26
43
  /**
27
44
  * Maps a raw write error onto the port's typed signals, rethrowing anything
28
45
  * else unchanged: `412` becomes a {@link WasSyncConflictError} for every write.
29
46
  * `notFound` opts in to the `404` mapping, which only `deleteContent` performs
30
47
  * (an already-gone target is a settled outcome for a delete, but a hard error
31
- * for a content or metadata write).
48
+ * for a content or metadata write). `authErrors` is the port's `mapAuthErrors`
49
+ * option: it maps `401` / `403` / the masked `404` to a
50
+ * {@link WasSyncAuthError}. `notFound` is checked first, so a port that asked
51
+ * for both still gets the delete-specific signal.
32
52
  *
33
53
  * @param err {unknown} the caught error
34
54
  * @param [options] {object}
35
55
  * @param [options.notFound] {boolean} map `404` to {@link WasSyncNotFoundError}
56
+ * @param [options.authErrors] {boolean} map `401`/`403`/`404` to
57
+ * {@link WasSyncAuthError}
36
58
  * @returns {never} always throws
37
59
  */
38
- function mapWriteError(err, { notFound = false } = {}) {
60
+ function mapWriteError(err, { notFound = false, authErrors = false } = {}) {
39
61
  const status = errorStatus(err);
40
62
  if (notFound && status === 404) {
41
63
  throw new WasSyncNotFoundError();
@@ -43,6 +65,9 @@ function mapWriteError(err, { notFound = false } = {}) {
43
65
  if (status === 412) {
44
66
  throw new WasSyncConflictError();
45
67
  }
68
+ if (authErrors && isAuthStatus(status)) {
69
+ throw new WasSyncAuthError(status);
70
+ }
46
71
  throw err;
47
72
  }
48
73
  /**
@@ -72,16 +97,37 @@ export function parseEtag(etag) {
72
97
  }
73
98
  /**
74
99
  * Builds a {@link WasSyncPort} bound to one Space + Collection, backed by the
75
- * caller's signed {@link WasClient}. Requests invoke the client's own root
76
- * capability (no delegated `capability` is attached).
100
+ * caller's signed {@link WasClient}. With no `capability`, requests invoke the
101
+ * client's own root capability.
102
+ *
103
+ * `mapAuthErrors` exists because a WAS server MASKS an authorization failure as
104
+ * `404` ("not found or invalid authorization") rather than `403`, so an
105
+ * unauthorized caller cannot probe which resources exist. A replica that
106
+ * already synced its Space and Collection knows they exist, so on its sync
107
+ * paths a `404` can only mean the invocation itself was rejected -- the
108
+ * expired- or revoked-grant signal it needs in order to stop retrying and
109
+ * prompt for a reconnect. The reading is only safe with that knowledge, so it
110
+ * is opt-in: off (the default), every status behaves exactly as before.
111
+ *
112
+ * Two paths keep their own `404` semantics even when it is on, because there a
113
+ * `404` is a modeled outcome rather than an anomaly: `deleteContent` resolves
114
+ * (the tombstone's goal state already holds -- an idempotent delete), and `get`
115
+ * resolves `null` (absent or tombstoned -- the deletion-wins input its callers
116
+ * depend on). Revoked access still surfaces within one poll on `query` and on
117
+ * the content/metadata writes.
77
118
  *
78
119
  * @param options {object}
79
120
  * @param options.was {WasClient} the session client (holds the signer)
80
121
  * @param options.spaceId {string} the WAS Space id
81
122
  * @param options.collectionId {string} the WAS collection id
123
+ * @param [options.capability] {IZcap} a delegated capability to invoke on
124
+ * every request this port makes (pull, writes, and reads alike); omit to
125
+ * invoke the client's own root capability
126
+ * @param [options.mapAuthErrors] {boolean} map `401` / `403` / the masked
127
+ * `404` to {@link WasSyncAuthError} (default `false`)
82
128
  * @returns {WasSyncPort}
83
129
  */
84
- export function createWasSyncPort({ was, spaceId, collectionId }) {
130
+ export function createWasSyncPort({ was, spaceId, collectionId, capability, mapAuthErrors = false }) {
85
131
  // Paths come from the internal builders, so this port inherits the same
86
132
  // percent-encoding and reserved/dot-segment guards as the handle API.
87
133
  const contentPath = (id) => resourcePath(spaceId, collectionId, id);
@@ -89,16 +135,29 @@ export function createWasSyncPort({ was, spaceId, collectionId }) {
89
135
  // Construction is I/O-free (the codec/feature probes are lazy thunks) and
90
136
  // `changes()` never resolves the codec, so it ships the stored bodies
91
137
  // verbatim -- what this codec-bypassing port requires.
92
- const changesCollection = was.space(spaceId).collection(collectionId);
138
+ const changesCollection = was
139
+ .space(spaceId)
140
+ .collection(collectionId, { capability });
93
141
  /** Re-reads a resource's raw content body + version (no decrypt, no `/meta`). */
94
142
  const readContent = async (id) => {
95
143
  let response;
96
144
  try {
97
- response = await was.request({ path: contentPath(id), method: 'GET' });
145
+ response = await was.request({
146
+ capability,
147
+ path: contentPath(id),
148
+ method: 'GET'
149
+ });
98
150
  }
99
151
  catch (err) {
100
- if (errorStatus(err) === 404) {
101
- return null; // absent or tombstoned -- caller treats as deletion-wins
152
+ const status = errorStatus(err);
153
+ // A read's `404` stays "absent or tombstoned" even under
154
+ // `mapAuthErrors`: it is a modeled outcome here, and the callers read it
155
+ // as deletion-wins.
156
+ if (status === 404) {
157
+ return null;
158
+ }
159
+ if (mapAuthErrors && isAuthStatus(status)) {
160
+ throw new WasSyncAuthError(status);
102
161
  }
103
162
  throw err;
104
163
  }
@@ -118,11 +177,24 @@ export function createWasSyncPort({ was, spaceId, collectionId }) {
118
177
  };
119
178
  return {
120
179
  async query({ checkpoint, limit }) {
121
- return changesCollection.changes({ checkpoint, limit });
180
+ try {
181
+ return await changesCollection.changes({ checkpoint, limit });
182
+ }
183
+ catch (err) {
184
+ // The pull path is where revoked access surfaces reliably: unlike a
185
+ // read or a delete, a `404` on the collection's own query endpoint has
186
+ // no benign reading once the collection is known to exist.
187
+ const status = errorStatus(err);
188
+ if (mapAuthErrors && isAuthStatus(status)) {
189
+ throw new WasSyncAuthError(status);
190
+ }
191
+ throw err;
192
+ }
122
193
  },
123
194
  async putContent({ id, data, ifMatch, ifNoneMatch, epoch }) {
124
195
  try {
125
196
  const response = await was.request({
197
+ capability,
126
198
  path: contentPath(id),
127
199
  method: 'PUT',
128
200
  json: data,
@@ -134,12 +206,13 @@ export function createWasSyncPort({ was, spaceId, collectionId }) {
134
206
  return await ackedVersion(response, id);
135
207
  }
136
208
  catch (err) {
137
- mapWriteError(err);
209
+ mapWriteError(err, { authErrors: mapAuthErrors });
138
210
  }
139
211
  },
140
212
  async deleteContent({ id, ifMatch }) {
141
213
  try {
142
214
  const response = await was.request({
215
+ capability,
143
216
  path: contentPath(id),
144
217
  method: 'DELETE',
145
218
  headers: writeHeaders({ precondition: { ifMatch } })
@@ -147,20 +220,41 @@ export function createWasSyncPort({ was, spaceId, collectionId }) {
147
220
  return await ackedVersion(response, id);
148
221
  }
149
222
  catch (err) {
150
- mapWriteError(err, { notFound: true });
223
+ // Under `mapAuthErrors` a delete's `404` is an idempotent success: the
224
+ // resource is already gone (deleted locally before it was ever pushed,
225
+ // or deleted first by another replica), so the tombstone's goal state
226
+ // holds and the batch must not be retried forever. A masked
227
+ // authorization `404` is swallowed with it -- indistinguishable by
228
+ // design -- but revoked access still surfaces on the next `query`.
229
+ if (mapAuthErrors && errorStatus(err) === 404) {
230
+ return undefined;
231
+ }
232
+ mapWriteError(err, {
233
+ notFound: !mapAuthErrors,
234
+ authErrors: mapAuthErrors
235
+ });
151
236
  }
152
237
  },
153
238
  async putMeta({ id, custom, ifMatch, ifNoneMatch }) {
154
239
  try {
155
- await was.request({
240
+ const response = await was.request({
241
+ capability,
156
242
  path: metaPath(id),
157
243
  method: 'PUT',
158
- json: { custom },
244
+ // The `/meta` PUT fully replaces `custom`: a body omitting it writes
245
+ // the CLEARED state (the server clears every property the body
246
+ // leaves out), which is how a metadata clear replicates. Byte-
247
+ // identical on the wire to the `{ custom: undefined }` this used to
248
+ // send, since `JSON.stringify` drops an `undefined` member.
249
+ json: custom === undefined ? {} : { custom },
159
250
  headers: writeHeaders({ precondition: { ifMatch, ifNoneMatch } })
160
251
  });
252
+ // `readEtag` reports an absent header as `undefined`; `parseEtag` reads
253
+ // the `null` spelling of the same thing.
254
+ return parseEtag(readEtag(response) ?? null);
161
255
  }
162
256
  catch (err) {
163
- mapWriteError(err);
257
+ mapWriteError(err, { authErrors: mapAuthErrors });
164
258
  }
165
259
  },
166
260
  async get({ id }) {
@@ -168,7 +262,9 @@ export function createWasSyncPort({ was, spaceId, collectionId }) {
168
262
  // together. The metadata read settles into a value (its rejection handler
169
263
  // is attached before any `await` that can throw, so an abandoned read can
170
264
  // never surface as an unhandled rejection).
171
- const metaRead = was.request({ path: metaPath(id), method: 'GET' }).then(response => ({ ok: true, response }), (err) => ({ ok: false, err }));
265
+ const metaRead = was
266
+ .request({ capability, path: metaPath(id), method: 'GET' })
267
+ .then(response => ({ ok: true, response }), (err) => ({ ok: false, err }));
172
268
  const master = await readContent(id);
173
269
  if (master === null) {
174
270
  return null; // absent or tombstoned; the metadata read is discarded
@@ -179,10 +275,17 @@ export function createWasSyncPort({ was, spaceId, collectionId }) {
179
275
  // yet 404s here; only a hard error propagates.
180
276
  const meta = await metaRead;
181
277
  if (!meta.ok) {
182
- if (errorStatus(meta.err) !== 404) {
183
- throw meta.err;
278
+ const status = errorStatus(meta.err);
279
+ // A `/meta` `404` is routine (the resource has no metadata document
280
+ // yet), so it stays benign under `mapAuthErrors` -- only `401`/`403`
281
+ // map there.
282
+ if (status === 404) {
283
+ return master;
284
+ }
285
+ if (mapAuthErrors && isAuthStatus(status)) {
286
+ throw new WasSyncAuthError(status);
184
287
  }
185
- return master;
288
+ throw meta.err;
186
289
  }
187
290
  const metaBody = meta.response.data;
188
291
  if (metaBody?.updatedAt) {
@@ -1 +1 @@
1
- {"version":3,"file":"port.js","sourceRoot":"","sources":["../../src/sync/port.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"port.js","sourceRoot":"","sources":["../../src/sync/port.ts"],"names":[],"mappings":"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"}
@@ -96,22 +96,30 @@ export interface WasSyncPort {
96
96
  * unchanged. Returns the tombstone's new server `version`. Throws
97
97
  * {@link WasSyncConflictError} on `412`, {@link WasSyncNotFoundError} on `404`
98
98
  * (already gone -- a settled outcome for a delete).
99
+ *
100
+ * Resolves `undefined` instead when the port was built with
101
+ * `mapAuthErrors: true` and the target was already absent: there the delete
102
+ * is idempotent, so there is no acked revision to report.
99
103
  */
100
104
  deleteContent(options: {
101
105
  id: string;
102
106
  ifMatch?: string;
103
- }): Promise<number>;
107
+ }): Promise<number | undefined>;
104
108
  /**
105
109
  * Conditionally writes the user-writable metadata `custom` (`PUT /:id/meta`).
106
- * Optional -- present only on a port that syncs metadata. Throws
110
+ * Optional -- present only on a port that syncs metadata. The write fully
111
+ * replaces `custom`, so omitting it writes the CLEARED state (the server
112
+ * clears every property the body leaves out) -- that is how a metadata clear
113
+ * replicates. Returns the new `metaVersion` (parsed from the write's `ETag`),
114
+ * or `undefined` when the response carried none. Throws
107
115
  * {@link WasSyncConflictError} on `412`.
108
116
  */
109
117
  putMeta?(options: {
110
118
  id: string;
111
- custom: Json;
119
+ custom?: Json;
112
120
  ifMatch?: string;
113
121
  ifNoneMatch?: boolean;
114
- }): Promise<void>;
122
+ }): Promise<number | undefined>;
115
123
  /**
116
124
  * Re-reads a single resource's current master state for the 412-conflict
117
125
  * assembler. Returns `null` when the resource is genuinely absent OR a
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/sync/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;GASG;AACH,OAAO,KAAK,EACV,cAAc,EACd,iBAAiB,EACjB,WAAW,EACZ,MAAM,uBAAuB,CAAA;AAC9B,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AAEvC,YAAY,EAAE,IAAI,EAAE,CAAA;AAEpB;;;;;;GAMG;AACH,MAAM,MAAM,cAAc,GAAG,iBAAiB,CAAA;AAE9C;;;;;;;;GAQG;AACH,MAAM,MAAM,OAAO,GAAG,cAAc,CAAA;AAEpC;;;;GAIG;AACH,MAAM,MAAM,QAAQ,GAAG,WAAW,CAAA;AAElC;;;;;;;;GAQG;AACH,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,IAAI,CAAC,EAAE,IAAI,CAAA;IACX,MAAM,CAAC,EAAE,IAAI,CAAA;IACb,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,WAAW;IAC1B;;;;OAIG;IACH,KAAK,CAAC,OAAO,EAAE;QACb,UAAU,CAAC,EAAE,cAAc,CAAA;QAC3B,KAAK,EAAE,MAAM,CAAA;KACd,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAA;IAErB;;;;;;;OAOG;IACH,UAAU,CAAC,OAAO,EAAE;QAClB,EAAE,EAAE,MAAM,CAAA;QACV,IAAI,EAAE,IAAI,CAAA;QACV,OAAO,CAAC,EAAE,MAAM,CAAA;QAChB,WAAW,CAAC,EAAE,OAAO,CAAA;QACrB,KAAK,CAAC,EAAE,MAAM,CAAA;KACf,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IAEnB;;;;;;OAMG;IACH,aAAa,CAAC,OAAO,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IAEzE;;;;OAIG;IACH,OAAO,CAAC,CAAC,OAAO,EAAE;QAChB,EAAE,EAAE,MAAM,CAAA;QACV,MAAM,EAAE,IAAI,CAAA;QACZ,OAAO,CAAC,EAAE,MAAM,CAAA;QAChB,WAAW,CAAC,EAAE,OAAO,CAAA;KACtB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAEjB;;;;;OAKG;IACH,GAAG,CAAC,OAAO,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAA;CAC1D;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,SAAS;IACxB,OAAO,CAAC,OAAO,EAAE;QACf,IAAI,EAAE,IAAI,CAAA;KACX,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,IAAI,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAC3D,aAAa,CAAC,CAAC,OAAO,EAAE;QACtB,EAAE,EAAE,MAAM,CAAA;QACV,IAAI,EAAE,IAAI,CAAA;QACV,OAAO,EAAE,IAAI,CAAA;KACd,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,IAAI,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAC3D,OAAO,CAAC,OAAO,EAAE;QAAE,QAAQ,EAAE,IAAI,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACpD"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/sync/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;GASG;AACH,OAAO,KAAK,EACV,cAAc,EACd,iBAAiB,EACjB,WAAW,EACZ,MAAM,uBAAuB,CAAA;AAC9B,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AAEvC,YAAY,EAAE,IAAI,EAAE,CAAA;AAEpB;;;;;;GAMG;AACH,MAAM,MAAM,cAAc,GAAG,iBAAiB,CAAA;AAE9C;;;;;;;;GAQG;AACH,MAAM,MAAM,OAAO,GAAG,cAAc,CAAA;AAEpC;;;;GAIG;AACH,MAAM,MAAM,QAAQ,GAAG,WAAW,CAAA;AAElC;;;;;;;;GAQG;AACH,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,IAAI,CAAC,EAAE,IAAI,CAAA;IACX,MAAM,CAAC,EAAE,IAAI,CAAA;IACb,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,WAAW;IAC1B;;;;OAIG;IACH,KAAK,CAAC,OAAO,EAAE;QACb,UAAU,CAAC,EAAE,cAAc,CAAA;QAC3B,KAAK,EAAE,MAAM,CAAA;KACd,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAA;IAErB;;;;;;;OAOG;IACH,UAAU,CAAC,OAAO,EAAE;QAClB,EAAE,EAAE,MAAM,CAAA;QACV,IAAI,EAAE,IAAI,CAAA;QACV,OAAO,CAAC,EAAE,MAAM,CAAA;QAChB,WAAW,CAAC,EAAE,OAAO,CAAA;QACrB,KAAK,CAAC,EAAE,MAAM,CAAA;KACf,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IAEnB;;;;;;;;;;OAUG;IACH,aAAa,CAAC,OAAO,EAAE;QACrB,EAAE,EAAE,MAAM,CAAA;QACV,OAAO,CAAC,EAAE,MAAM,CAAA;KACjB,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;IAE/B;;;;;;;;OAQG;IACH,OAAO,CAAC,CAAC,OAAO,EAAE;QAChB,EAAE,EAAE,MAAM,CAAA;QACV,MAAM,CAAC,EAAE,IAAI,CAAA;QACb,OAAO,CAAC,EAAE,MAAM,CAAA;QAChB,WAAW,CAAC,EAAE,OAAO,CAAA;KACtB,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;IAE/B;;;;;OAKG;IACH,GAAG,CAAC,OAAO,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAA;CAC1D;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,SAAS;IACxB,OAAO,CAAC,OAAO,EAAE;QACf,IAAI,EAAE,IAAI,CAAA;KACX,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,IAAI,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAC3D,aAAa,CAAC,CAAC,OAAO,EAAE;QACtB,EAAE,EAAE,MAAM,CAAA;QACV,IAAI,EAAE,IAAI,CAAA;QACV,OAAO,EAAE,IAAI,CAAA;KACd,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,IAAI,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAC3D,OAAO,CAAC,OAAO,EAAE;QAAE,QAAQ,EAAE,IAAI,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACpD"}
package/dist/types.d.ts CHANGED
@@ -22,8 +22,32 @@ export type { IZcap, IDelegatedZcap, IRootZcap, IDID, ISigner };
22
22
  * `ResourceListing`) and the collections-in-a-space listing is `CollectionsList`
23
23
  * (formerly `CollectionListing`).
24
24
  */
25
- export type { Action, ActionInput, SpaceDescription, CollectionDescription, CollectionEncryption, CollectionEncryptionEpoch, CollectionEncryptionRecipient, PolicyDocument, LinkSet, LinkSetEntry, CollectionSummary, CollectionsList, SpaceSummary, SpaceListing, ResourceSummary, CollectionResourcesList, ResourceMetadata, ResourceMetadataCustom, ImportStats, BackendReference, BackendDescriptor, BackendRegistration, BackendConnectionInput, BackendConnectionPublic, StorageLimit, CollectionUsage, BackendUsage, SpaceQuotaReport } from '@interop/storage-core';
25
+ export type { Action, ActionInput, SpaceDescription, CollectionDescription, CollectionEncryption, CollectionEncryptionEpoch, CollectionEncryptionRecipient, PolicyDocument, LinkSet, LinkSetEntry, CollectionSummary, CollectionsList, SpaceSummary, SpaceListing, ResourceSummary, CollectionResourcesList, ResourceMetadata, ResourceMetadataCustom, CollectionMetadata, ImportStats, BackendReference, BackendDescriptor, BackendRegistration, BackendConnectionInput, BackendConnectionPublic, StorageLimit, CollectionUsage, BackendUsage, SpaceQuotaReport } from '@interop/storage-core';
26
26
  import type { BackendReference, CollectionEncryption } from '@interop/storage-core';
27
+ /**
28
+ * The Collection's blinded-index HMAC key, as it appears on the `encryption`
29
+ * descriptor: the key `id` (the value an envelope's `indexed[].hmac.id` and a
30
+ * blinded query's `index` name), its `type` (`'Sha256HmacKey2019'`), and the
31
+ * 32-byte HMAC secret wrapped once per recipient -- the same JWE `recipients`
32
+ * entry shape and `ECDH-ES+A256KW` wrap the epoch secrets use, so a recipient
33
+ * receives the blinding key exactly the way it receives epoch keys.
34
+ *
35
+ * The key is installed at Collection provisioning or never, and never rotates:
36
+ * blinded tokens must compare across the Collection's whole history. Removing a
37
+ * recipient drops its wrap entry as housekeeping only -- the key is unchanged,
38
+ * so a removed recipient keeps it (a documented revocation asymmetry).
39
+ *
40
+ * A named alias for the descriptor's own `hmac` member, so the blinding-key
41
+ * code can refer to the shape by name.
42
+ */
43
+ export type CollectionEncryptionHmac = NonNullable<CollectionEncryption['hmac']>;
44
+ /**
45
+ * A `CollectionEncryption` descriptor known to carry the blinded-index `hmac`
46
+ * member. `CollectionEncryption` declares `hmac` natively, so this is now an
47
+ * alias; the name is kept because the blinding-key code reads better naming the
48
+ * member it works with.
49
+ */
50
+ export type EncryptionWithHmac = CollectionEncryption;
27
51
  /**
28
52
  * The client-writable fields of a Collection Description -- the shape shared
29
53
  * by `Collection.configure` and `Collection.replaceDescription` and the single
@@ -76,6 +100,21 @@ export interface AddResult {
76
100
  */
77
101
  etag?: string;
78
102
  }
103
+ /**
104
+ * One page of `collection.find()` results: the matching resources, decoded
105
+ * (decrypted) the way `get()` decodes them, plus the means to ask for more.
106
+ * `cursor` is present exactly when `hasMore` is `true`; pass it back as
107
+ * `find({ ..., cursor })` to continue. It is an opaque server token, not an
108
+ * offset.
109
+ */
110
+ export interface FindPage {
111
+ items: Array<{
112
+ id: string;
113
+ data: Json | Blob;
114
+ }>;
115
+ hasMore: boolean;
116
+ cursor?: string;
117
+ }
79
118
  /**
80
119
  * A per-handle client-side encryption override -- the escape hatch / bootstrap
81
120
  * path that takes precedence over the Collection's declared `encryption`
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EACV,KAAK,EACL,cAAc,EACd,SAAS,EACV,MAAM,mCAAmC,CAAA;AAC1C,OAAO,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,8BAA8B,CAAA;AAEjE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAExD,YAAY,EAAE,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,CAAA;AAE/D;;;;;GAKG;AACH,YAAY,EACV,MAAM,EACN,WAAW,EACX,gBAAgB,EAChB,qBAAqB,EACrB,oBAAoB,EACpB,yBAAyB,EACzB,6BAA6B,EAC7B,cAAc,EACd,OAAO,EACP,YAAY,EACZ,iBAAiB,EACjB,eAAe,EACf,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,uBAAuB,EACvB,gBAAgB,EAChB,sBAAsB,EACtB,kBAAkB,EAClB,WAAW,EACX,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EACnB,sBAAsB,EACtB,uBAAuB,EACvB,YAAY,EACZ,eAAe,EACf,YAAY,EACZ,gBAAgB,EACjB,MAAM,uBAAuB,CAAA;AAE9B,OAAO,KAAK,EACV,gBAAgB,EAChB,oBAAoB,EACrB,MAAM,uBAAuB,CAAA;AAE9B;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,wBAAwB,GAAG,WAAW,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC,CAAA;AAEhF;;;;;GAKG;AACH,MAAM,MAAM,kBAAkB,GAAG,oBAAoB,CAAA;AAErD;;;;;GAKG;AACH,MAAM,WAAW,wBAAwB;IACvC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,gBAAgB,CAAA;IAC1B,UAAU,CAAC,EAAE,oBAAoB,CAAA;IACjC;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,IAAI,CAAA;IAChB,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB;AAED;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAA;AAC5D,MAAM,WAAW,UAAU;IACzB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;CACpB;AACD,MAAM,MAAM,SAAS,GAAG,IAAI,EAAE,CAAA;AAC9B,MAAM,MAAM,IAAI,GAAG,aAAa,GAAG,UAAU,GAAG,SAAS,CAAA;AAEzD;;;;;;GAMG;AACH,MAAM,MAAM,YAAY,GAAG,UAAU,GAAG,SAAS,GAAG,IAAI,GAAG,UAAU,CAAA;AAErE;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAA;IACV,GAAG,EAAE,MAAM,CAAA;IACX,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED;;;;;;GAMG;AACH,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAAA;KAAE,CAAC,CAAA;IAC/C,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,MAAM,kBAAkB,GAC5B;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,WAAW,CAAA;AAElD;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,UAAU,CAAC,EAAE,KAAK,CAAA;IAClB;;;OAGG;IACH,UAAU,CAAC,EAAE,kBAAkB,CAAA;CAChC;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAA;IACV,OAAO,EAAE,WAAW,EAAE,CAAA;IACtB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,UAAU,CAAC,EAAE,KAAK,CAAA;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,IAAI,GAAG,UAAU,CAAA;IACxB,UAAU,CAAC,EAAE,KAAK,CAAA;CACnB"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@interop/was-client",
3
3
  "description": "A developer-friendly client for Wallet Attached Storage (WAS) servers.",
4
- "version": "0.33.0",
4
+ "version": "0.35.0",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "build": "pnpm run clear && tsc",
@@ -36,6 +36,12 @@
36
36
  "import": "./dist/edv/index.js",
37
37
  "default": "./dist/edv/index.js"
38
38
  },
39
+ "./paths": {
40
+ "types": "./dist/paths.d.ts",
41
+ "react-native": "./dist/paths.js",
42
+ "import": "./dist/paths.js",
43
+ "default": "./dist/paths.js"
44
+ },
39
45
  "./log": {
40
46
  "types": "./dist/log/index.d.ts",
41
47
  "react-native": "./dist/log/index.js",
@@ -60,7 +66,7 @@
60
66
  "@interop/ezcap": "^7.4.1",
61
67
  "@interop/http-client": "^1.0.5",
62
68
  "@interop/minimal-cipher": "^7.8.1",
63
- "@interop/storage-core": "^0.6.0",
69
+ "@interop/storage-core": "^0.8.0",
64
70
  "@interop/x25519-key-agreement-key": "^5.2.1",
65
71
  "@noble/hashes": "^2.3.0",
66
72
  "@scure/base": "^2.3.0",