@interop/was-client 0.27.0 → 0.27.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.
Files changed (99) hide show
  1. package/dist/Collection.d.ts.map +1 -1
  2. package/dist/Collection.js +27 -66
  3. package/dist/Collection.js.map +1 -1
  4. package/dist/Resource.d.ts.map +1 -1
  5. package/dist/Resource.js +28 -6
  6. package/dist/Resource.js.map +1 -1
  7. package/dist/Space.d.ts.map +1 -1
  8. package/dist/Space.js +10 -25
  9. package/dist/Space.js.map +1 -1
  10. package/dist/WasClient.d.ts.map +1 -1
  11. package/dist/WasClient.js +9 -19
  12. package/dist/WasClient.js.map +1 -1
  13. package/dist/codec.d.ts +31 -5
  14. package/dist/codec.d.ts.map +1 -1
  15. package/dist/edv/EdvCodec.d.ts +9 -14
  16. package/dist/edv/EdvCodec.d.ts.map +1 -1
  17. package/dist/edv/EdvCodec.js +147 -71
  18. package/dist/edv/EdvCodec.js.map +1 -1
  19. package/dist/edv/WasTransport.d.ts +1 -2
  20. package/dist/edv/WasTransport.d.ts.map +1 -1
  21. package/dist/edv/WasTransport.js +19 -28
  22. package/dist/edv/WasTransport.js.map +1 -1
  23. package/dist/edv/constants.d.ts +11 -0
  24. package/dist/edv/constants.d.ts.map +1 -1
  25. package/dist/edv/constants.js +16 -4
  26. package/dist/edv/constants.js.map +1 -1
  27. package/dist/edv/docCipher.d.ts +10 -26
  28. package/dist/edv/docCipher.d.ts.map +1 -1
  29. package/dist/edv/docCipher.js +62 -135
  30. package/dist/edv/docCipher.js.map +1 -1
  31. package/dist/edv/epochCrypto.d.ts +0 -4
  32. package/dist/edv/epochCrypto.d.ts.map +1 -1
  33. package/dist/edv/epochCrypto.js +4 -4
  34. package/dist/edv/epochCrypto.js.map +1 -1
  35. package/dist/edv/epochKeys.d.ts.map +1 -1
  36. package/dist/edv/epochKeys.js +2 -4
  37. package/dist/edv/epochKeys.js.map +1 -1
  38. package/dist/edv/epochMac.d.ts.map +1 -1
  39. package/dist/edv/epochMac.js +4 -4
  40. package/dist/edv/epochMac.js.map +1 -1
  41. package/dist/edv/index.d.ts +3 -2
  42. package/dist/edv/index.d.ts.map +1 -1
  43. package/dist/edv/index.js +2 -1
  44. package/dist/edv/index.js.map +1 -1
  45. package/dist/edv/recipients.d.ts +13 -14
  46. package/dist/edv/recipients.d.ts.map +1 -1
  47. package/dist/edv/recipients.js +126 -99
  48. package/dist/edv/recipients.js.map +1 -1
  49. package/dist/errors.d.ts +29 -12
  50. package/dist/errors.d.ts.map +1 -1
  51. package/dist/errors.js +37 -65
  52. package/dist/errors.js.map +1 -1
  53. package/dist/index.d.ts +1 -1
  54. package/dist/index.d.ts.map +1 -1
  55. package/dist/internal/codec.d.ts +15 -12
  56. package/dist/internal/codec.d.ts.map +1 -1
  57. package/dist/internal/codec.js +4 -6
  58. package/dist/internal/codec.js.map +1 -1
  59. package/dist/internal/conditional.d.ts +9 -4
  60. package/dist/internal/conditional.d.ts.map +1 -1
  61. package/dist/internal/conditional.js +9 -2
  62. package/dist/internal/conditional.js.map +1 -1
  63. package/dist/internal/content.d.ts +28 -24
  64. package/dist/internal/content.d.ts.map +1 -1
  65. package/dist/internal/content.js +28 -13
  66. package/dist/internal/content.js.map +1 -1
  67. package/dist/internal/describe.d.ts +15 -2
  68. package/dist/internal/describe.d.ts.map +1 -1
  69. package/dist/internal/describe.js +17 -0
  70. package/dist/internal/describe.js.map +1 -1
  71. package/dist/internal/pagination.d.ts +20 -1
  72. package/dist/internal/pagination.d.ts.map +1 -1
  73. package/dist/internal/pagination.js +22 -0
  74. package/dist/internal/pagination.js.map +1 -1
  75. package/dist/internal/paths.d.ts +0 -11
  76. package/dist/internal/paths.d.ts.map +1 -1
  77. package/dist/internal/paths.js +20 -33
  78. package/dist/internal/paths.js.map +1 -1
  79. package/dist/internal/policy.d.ts.map +1 -1
  80. package/dist/internal/policy.js +2 -9
  81. package/dist/internal/policy.js.map +1 -1
  82. package/dist/internal/write.d.ts +50 -4
  83. package/dist/internal/write.d.ts.map +1 -1
  84. package/dist/internal/write.js +45 -0
  85. package/dist/internal/write.js.map +1 -1
  86. package/dist/sync/cid.d.ts.map +1 -1
  87. package/dist/sync/cid.js +8 -2
  88. package/dist/sync/cid.js.map +1 -1
  89. package/dist/sync/port.d.ts +9 -8
  90. package/dist/sync/port.d.ts.map +1 -1
  91. package/dist/sync/port.js +74 -70
  92. package/dist/sync/port.js.map +1 -1
  93. package/dist/sync/provisioning.d.ts +4 -1
  94. package/dist/sync/provisioning.d.ts.map +1 -1
  95. package/dist/sync/provisioning.js +11 -2
  96. package/dist/sync/provisioning.js.map +1 -1
  97. package/dist/sync/types.d.ts +7 -10
  98. package/dist/sync/types.d.ts.map +1 -1
  99. package/package.json +13 -13
@@ -5,10 +5,13 @@
5
5
  * The shared write orchestration. `sendEncodedWrite` turns a codec's
6
6
  * {@link EncodedWrite} plus a conditional-write precondition into request
7
7
  * headers and sends it (the shape `Collection.add` and `Resource.put` would
8
- * otherwise each re-implement). `upsertResource` layers the upsert flow on
9
- * top: the conditional-codec pre-read of the current document, the
10
- * codec-vs-caller precondition selection, and the masked-404 policy for a
11
- * document that exists but is not readable with the bound capability.
8
+ * otherwise each re-implement). Two flows layer on top: `insertResource` (the
9
+ * create path behind `Collection.add` -- encode, the minted-id `PUT` vs
10
+ * server-minting `POST` branch, and the precondition selection) and
11
+ * `upsertResource` (the write-by-id path behind `Resource.put` -- the
12
+ * conditional-codec pre-read of the current document, the codec-vs-caller
13
+ * precondition selection, and the masked-404 policy for a document that exists
14
+ * but is not readable with the bound capability).
12
15
  */
13
16
  import type { HttpResponse } from '@interop/http-client';
14
17
  import type { EncodedWrite, ResourceCodec } from '../codec.js';
@@ -37,6 +40,49 @@ export declare function sendEncodedWrite(context: ClientContext, { path, method,
37
40
  capability?: IZcap;
38
41
  precondition?: WritePrecondition;
39
42
  }): Promise<HttpResponse>;
43
+ /**
44
+ * Creates a resource with a codec-minted or server-minted id (insert) through
45
+ * its codec, owning the create orchestration in one place: the encode, the
46
+ * `PUT`-vs-`POST` branch, and the precondition selection.
47
+ *
48
+ * A codec that mints its own id (e.g. the encrypting codec's EDV id) writes it
49
+ * by `PUT` to that id's path; a codec that mints none (the identity codec)
50
+ * `POST`s to the items path and lets the server mint one. As in
51
+ * {@link upsertResource}, a conditional codec computes the precondition itself
52
+ * (the EDV codec guards its fresh insert with `If-None-Match: *`) and a
53
+ * non-conditional one defers to the caller's explicit precondition.
54
+ *
55
+ * Returns the codec's encoded write and the path actually written alongside the
56
+ * response, so the caller can shape its result (the created id and URL) without
57
+ * re-deriving either.
58
+ *
59
+ * @param context {ClientContext}
60
+ * @param options {object}
61
+ * @param options.itemsPath {string} the collection's items path, the
62
+ * `POST` target when the codec mints no id
63
+ * @param options.pathForId {function} builds the resource path for a
64
+ * codec-minted id
65
+ * @param options.codec {ResourceCodec} the collection's resolved codec
66
+ * @param options.data {ResourceData} the plaintext value
67
+ * @param [options.contentType] {string} caller-supplied content type
68
+ * @param [options.capability] {IZcap}
69
+ * @param [options.precondition] {WritePrecondition} the caller's explicit
70
+ * precondition (used only for a non-conditional codec)
71
+ * @returns {Promise<{ encoded: EncodedWrite; path: string; response: HttpResponse }>}
72
+ */
73
+ export declare function insertResource(context: ClientContext, { itemsPath, pathForId, codec, data, contentType, capability, precondition }: {
74
+ itemsPath: string;
75
+ pathForId: (id: string) => string;
76
+ codec: ResourceCodec;
77
+ data: ResourceData;
78
+ contentType?: string;
79
+ capability?: IZcap;
80
+ precondition?: WritePrecondition;
81
+ }): Promise<{
82
+ encoded: EncodedWrite;
83
+ path: string;
84
+ response: HttpResponse;
85
+ }>;
40
86
  /**
41
87
  * Creates or replaces a resource by id (upsert) through its codec, owning the
42
88
  * conditional-write orchestration in one place:
@@ -1 +1 @@
1
- {"version":3,"file":"write.d.ts","sourceRoot":"","sources":["../../src/internal/write.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAE9D,OAAO,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AACtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAGjD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AAEzD;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,aAAa,EACtB,EACE,IAAI,EACJ,MAAM,EACN,OAAO,EACP,UAAU,EACV,YAAY,EACb,EAAE;IACD,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,YAAY,CAAA;IACrB,UAAU,CAAC,EAAE,KAAK,CAAA;IAClB,YAAY,CAAC,EAAE,iBAAiB,CAAA;CACjC,GACA,OAAO,CAAC,YAAY,CAAC,CAcvB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,aAAa,EACtB,EACE,IAAI,EACJ,KAAK,EACL,EAAE,EACF,IAAI,EACJ,QAAQ,EACR,WAAW,EACX,UAAU,EACV,YAAY,EACb,EAAE;IACD,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,aAAa,CAAA;IACpB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,YAAY,CAAA;IAClB,QAAQ,EAAE,MAAM,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;IACjC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,KAAK,CAAA;IAClB,YAAY,CAAC,EAAE,iBAAiB,CAAA;CACjC,GACA,OAAO,CAAC,YAAY,CAAC,CAgEvB"}
1
+ {"version":3,"file":"write.d.ts","sourceRoot":"","sources":["../../src/internal/write.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAE9D,OAAO,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AACtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAGjD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AAEzD;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,aAAa,EACtB,EACE,IAAI,EACJ,MAAM,EACN,OAAO,EACP,UAAU,EACV,YAAY,EACb,EAAE;IACD,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,YAAY,CAAA;IACrB,UAAU,CAAC,EAAE,KAAK,CAAA;IAClB,YAAY,CAAC,EAAE,iBAAiB,CAAA;CACjC,GACA,OAAO,CAAC,YAAY,CAAC,CAcvB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,aAAa,EACtB,EACE,SAAS,EACT,SAAS,EACT,KAAK,EACL,IAAI,EACJ,WAAW,EACX,UAAU,EACV,YAAY,EACb,EAAE;IACD,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,MAAM,CAAA;IACjC,KAAK,EAAE,aAAa,CAAA;IACpB,IAAI,EAAE,YAAY,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,KAAK,CAAA;IAClB,YAAY,CAAC,EAAE,iBAAiB,CAAA;CACjC,GACA,OAAO,CAAC;IAAE,OAAO,EAAE,YAAY,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,YAAY,CAAA;CAAE,CAAC,CAc1E;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,aAAa,EACtB,EACE,IAAI,EACJ,KAAK,EACL,EAAE,EACF,IAAI,EACJ,QAAQ,EACR,WAAW,EACX,UAAU,EACV,YAAY,EACb,EAAE;IACD,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,aAAa,CAAA;IACpB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,YAAY,CAAA;IAClB,QAAQ,EAAE,MAAM,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;IACjC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,KAAK,CAAA;IAClB,YAAY,CAAC,EAAE,iBAAiB,CAAA;CACjC,GACA,OAAO,CAAC,YAAY,CAAC,CAgEvB"}
@@ -31,6 +31,51 @@ export async function sendEncodedWrite(context, { path, method, encoded, capabil
31
31
  });
32
32
  return response;
33
33
  }
34
+ /**
35
+ * Creates a resource with a codec-minted or server-minted id (insert) through
36
+ * its codec, owning the create orchestration in one place: the encode, the
37
+ * `PUT`-vs-`POST` branch, and the precondition selection.
38
+ *
39
+ * A codec that mints its own id (e.g. the encrypting codec's EDV id) writes it
40
+ * by `PUT` to that id's path; a codec that mints none (the identity codec)
41
+ * `POST`s to the items path and lets the server mint one. As in
42
+ * {@link upsertResource}, a conditional codec computes the precondition itself
43
+ * (the EDV codec guards its fresh insert with `If-None-Match: *`) and a
44
+ * non-conditional one defers to the caller's explicit precondition.
45
+ *
46
+ * Returns the codec's encoded write and the path actually written alongside the
47
+ * response, so the caller can shape its result (the created id and URL) without
48
+ * re-deriving either.
49
+ *
50
+ * @param context {ClientContext}
51
+ * @param options {object}
52
+ * @param options.itemsPath {string} the collection's items path, the
53
+ * `POST` target when the codec mints no id
54
+ * @param options.pathForId {function} builds the resource path for a
55
+ * codec-minted id
56
+ * @param options.codec {ResourceCodec} the collection's resolved codec
57
+ * @param options.data {ResourceData} the plaintext value
58
+ * @param [options.contentType] {string} caller-supplied content type
59
+ * @param [options.capability] {IZcap}
60
+ * @param [options.precondition] {WritePrecondition} the caller's explicit
61
+ * precondition (used only for a non-conditional codec)
62
+ * @returns {Promise<{ encoded: EncodedWrite; path: string; response: HttpResponse }>}
63
+ */
64
+ export async function insertResource(context, { itemsPath, pathForId, codec, data, contentType, capability, precondition }) {
65
+ const encoded = await codec.encode({ data, contentType });
66
+ const chosen = codec.conditionalWrites
67
+ ? encodedPrecondition(encoded)
68
+ : precondition;
69
+ const path = encoded.id !== undefined ? pathForId(encoded.id) : itemsPath;
70
+ const response = await sendEncodedWrite(context, {
71
+ path,
72
+ method: encoded.id !== undefined ? 'PUT' : 'POST',
73
+ capability,
74
+ encoded,
75
+ precondition: chosen
76
+ });
77
+ return { encoded, path, response };
78
+ }
34
79
  /**
35
80
  * Creates or replaces a resource by id (upsert) through its codec, owning the
36
81
  * conditional-write orchestration in one place:
@@ -1 +1 @@
1
- {"version":3,"file":"write.js","sourceRoot":"","sources":["../../src/internal/write.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"write.js","sourceRoot":"","sources":["../../src/internal/write.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"cid.d.ts","sourceRoot":"","sources":["../../src/sync/cid.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AAEvC;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,IAAI,GAAG,MAAM,CAI5C;AAED;;;;;;;GAOG;AACH,wBAAgB,OAAO,CAAC,EAAE,GAAG,EAAE,EAAE;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAExD;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAE3D"}
1
+ {"version":3,"file":"cid.d.ts","sourceRoot":"","sources":["../../src/sync/cid.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AASvC;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,IAAI,GAAG,MAAM,CAE5C;AAED;;;;;;;GAOG;AACH,wBAAgB,OAAO,CAAC,EAAE,GAAG,EAAE,EAAE;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAExD;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAE3D"}
package/dist/sync/cid.js CHANGED
@@ -19,6 +19,12 @@
19
19
  import { sha256 } from '@noble/hashes/sha2.js';
20
20
  import { base64urlnopad } from '@scure/base';
21
21
  import { canonicalize } from 'json-canonicalize';
22
+ /**
23
+ * The one UTF-8 encoder every derivation here shares: hashing runs on the
24
+ * per-document hot path, so the encoder is allocated once for the module rather
25
+ * than per call. `TextEncoder` is stateless, so reuse is safe.
26
+ */
27
+ const ENCODER = new TextEncoder();
22
28
  /**
23
29
  * Derives a document's content id: `base64url(SHA-256(utf8(canonicalize(doc))))`,
24
30
  * no padding. Byte-identical across replicas for the same logical document, so a
@@ -28,7 +34,7 @@ import { canonicalize } from 'json-canonicalize';
28
34
  * @returns {string} the unpadded base64url content id (43 chars for SHA-256)
29
35
  */
30
36
  export function contentCid(doc) {
31
- return base64urlnopad.encode(sha256(new TextEncoder().encode(canonicalize(doc))));
37
+ return base64urlnopad.encode(sha256(ENCODER.encode(canonicalize(doc))));
32
38
  }
33
39
  /**
34
40
  * Named-options alias of {@link contentCid}, for callers that address a `doc`
@@ -50,6 +56,6 @@ export function cidFrom({ doc }) {
50
56
  * @returns {string} the unpadded base64url Space id
51
57
  */
52
58
  export function deriveSpaceId(controllerDid) {
53
- return base64urlnopad.encode(sha256(new TextEncoder().encode(controllerDid)));
59
+ return base64urlnopad.encode(sha256(ENCODER.encode(controllerDid)));
54
60
  }
55
61
  //# sourceMappingURL=cid.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cid.js","sourceRoot":"","sources":["../../src/sync/cid.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAGhD;;;;;;;GAOG;AACH,MAAM,UAAU,UAAU,CAAC,GAAS;IAClC,OAAO,cAAc,CAAC,MAAM,CAC1B,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,CACpD,CAAA;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,OAAO,CAAC,EAAE,GAAG,EAAmB;IAC9C,OAAO,UAAU,CAAC,GAAW,CAAC,CAAA;AAChC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAAC,aAAqB;IACjD,OAAO,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAA;AAC/E,CAAC"}
1
+ {"version":3,"file":"cid.js","sourceRoot":"","sources":["../../src/sync/cid.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAGhD;;;;GAIG;AACH,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAA;AAEjC;;;;;;;GAOG;AACH,MAAM,UAAU,UAAU,CAAC,GAAS;IAClC,OAAO,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;AACzE,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,OAAO,CAAC,EAAE,GAAG,EAAmB;IAC9C,OAAO,UAAU,CAAC,GAAW,CAAC,CAAA;AAChC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAAC,aAAqB;IACjD,OAAO,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAA;AACrE,CAAC"}
@@ -26,22 +26,23 @@
26
26
  * sent none), so a caller can record acked revisions immediately.
27
27
  */
28
28
  import type { WasClient } from '../WasClient.js';
29
+ import { WAS_KEY_EPOCH_HEADER } from '../internal/conditional.js';
30
+ import { httpStatus } from '../errors.js';
29
31
  import type { WasSyncPort } from './types.js';
30
32
  /**
31
33
  * The request header the server reads a content write's key-epoch id from,
32
- * stamping it onto the Resource's metadata (an absent header clears any prior
33
- * stamp). HTTP header names are case-insensitive; the wire form is `WAS-Key-Epoch`.
34
+ * stamping it onto the Resource's metadata. Defined next to the header
35
+ * assembly it drives (`internal/conditional.ts`) and re-exported here as part
36
+ * of the sync subpath's public surface.
34
37
  */
35
- export declare const WAS_KEY_EPOCH_HEADER = "WAS-Key-Epoch";
38
+ export { WAS_KEY_EPOCH_HEADER };
36
39
  /**
37
40
  * Extracts an HTTP status from a raw ky/ezcap error. `was.request()` rejects on
38
41
  * any non-2xx with `err.status` set; this reads it defensively from either the
39
- * flat `status` or the nested `response.status` shape.
40
- *
41
- * @param err {unknown} the caught error
42
- * @returns {number | undefined}
42
+ * flat `status` or the nested `response.status` shape. The sync subpath's name
43
+ * for the client's own {@link httpStatus}.
43
44
  */
44
- export declare function errorStatus(err: unknown): number | undefined;
45
+ export declare const errorStatus: typeof httpStatus;
45
46
  /**
46
47
  * Formats a numeric content `version` as the quoted strong `ETag` an
47
48
  * update-if-unchanged write passes as its `ifMatch` precondition (e.g. `3` to
@@ -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;AAIhD,OAAO,KAAK,EAIV,WAAW,EAEZ,MAAM,YAAY,CAAA;AAEnB;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,kBAAkB,CAAA;AAWnD;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAK5D;AAED;;;;;;;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,CA0Jd"}
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,oBAAoB,EAGrB,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,oBAAoB,EAAE,CAAA;AAW/B;;;;;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"}
package/dist/sync/port.js CHANGED
@@ -1,11 +1,13 @@
1
- import { writeHeaders } from '../internal/conditional.js';
2
- import { WasSyncConflictError, WasSyncNotFoundError } from '../errors.js';
1
+ import { WAS_KEY_EPOCH_HEADER, readEtag, writeHeaders } from '../internal/conditional.js';
2
+ import { resourceMeta, resourcePath } from '../internal/paths.js';
3
+ import { httpStatus, WasSyncConflictError, WasSyncNotFoundError } from '../errors.js';
3
4
  /**
4
5
  * The request header the server reads a content write's key-epoch id from,
5
- * stamping it onto the Resource's metadata (an absent header clears any prior
6
- * stamp). HTTP header names are case-insensitive; the wire form is `WAS-Key-Epoch`.
6
+ * stamping it onto the Resource's metadata. Defined next to the header
7
+ * assembly it drives (`internal/conditional.ts`) and re-exported here as part
8
+ * of the sync subpath's public surface.
7
9
  */
8
- export const WAS_KEY_EPOCH_HEADER = 'WAS-Key-Epoch';
10
+ export { WAS_KEY_EPOCH_HEADER };
9
11
  /**
10
12
  * The placeholder `updatedAt` for a 412-conflict re-read whose resource has no
11
13
  * `/meta` document yet (its server-managed timestamp is unknown). An epoch-zero
@@ -17,14 +19,31 @@ const UNKNOWN_UPDATED_AT = new Date(0).toISOString();
17
19
  /**
18
20
  * Extracts an HTTP status from a raw ky/ezcap error. `was.request()` rejects on
19
21
  * any non-2xx with `err.status` set; this reads it defensively from either the
20
- * flat `status` or the nested `response.status` shape.
22
+ * flat `status` or the nested `response.status` shape. The sync subpath's name
23
+ * for the client's own {@link httpStatus}.
24
+ */
25
+ export const errorStatus = httpStatus;
26
+ /**
27
+ * Maps a raw write error onto the port's typed signals, rethrowing anything
28
+ * else unchanged: `412` becomes a {@link WasSyncConflictError} for every write.
29
+ * `notFound` opts in to the `404` mapping, which only `deleteContent` performs
30
+ * (an already-gone target is a settled outcome for a delete, but a hard error
31
+ * for a content or metadata write).
21
32
  *
22
33
  * @param err {unknown} the caught error
23
- * @returns {number | undefined}
34
+ * @param [options] {object}
35
+ * @param [options.notFound] {boolean} map `404` to {@link WasSyncNotFoundError}
36
+ * @returns {never} always throws
24
37
  */
25
- export function errorStatus(err) {
26
- return (err.status ??
27
- err.response?.status);
38
+ function mapWriteError(err, { notFound = false } = {}) {
39
+ const status = errorStatus(err);
40
+ if (notFound && status === 404) {
41
+ throw new WasSyncNotFoundError();
42
+ }
43
+ if (status === 412) {
44
+ throw new WasSyncConflictError();
45
+ }
46
+ throw err;
28
47
  }
29
48
  /**
30
49
  * Formats a numeric content `version` as the quoted strong `ETag` an
@@ -63,8 +82,10 @@ export function parseEtag(etag) {
63
82
  * @returns {WasSyncPort}
64
83
  */
65
84
  export function createWasSyncPort({ was, spaceId, collectionId }) {
66
- const collectionPath = `/space/${spaceId}/${collectionId}`;
67
- const resourcePath = (id) => `${collectionPath}/${encodeURIComponent(id)}`;
85
+ // Paths come from the internal builders, so this port inherits the same
86
+ // percent-encoding and reserved/dot-segment guards as the handle API.
87
+ const contentPath = (id) => resourcePath(spaceId, collectionId, id);
88
+ const metaPath = (id) => resourceMeta(spaceId, collectionId, id);
68
89
  // Construction is I/O-free (the codec/feature probes are lazy thunks) and
69
90
  // `changes()` never resolves the codec, so it ships the stored bodies
70
91
  // verbatim -- what this codec-bypassing port requires.
@@ -73,7 +94,7 @@ export function createWasSyncPort({ was, spaceId, collectionId }) {
73
94
  const readContent = async (id) => {
74
95
  let response;
75
96
  try {
76
- response = await was.request({ path: resourcePath(id), method: 'GET' });
97
+ response = await was.request({ path: contentPath(id), method: 'GET' });
77
98
  }
78
99
  catch (err) {
79
100
  if (errorStatus(err) === 404) {
@@ -82,15 +103,14 @@ export function createWasSyncPort({ was, spaceId, collectionId }) {
82
103
  throw err;
83
104
  }
84
105
  return {
85
- version: parseEtag(response.headers.get('etag')) ?? 0,
106
+ version: parseEtag(readEtag(response) ?? null) ?? 0,
86
107
  updatedAt: UNKNOWN_UPDATED_AT,
87
- deleted: false,
88
108
  data: response.data
89
109
  };
90
110
  };
91
111
  /** Resolves the acked version from a write response, or via a content re-read. */
92
112
  const ackedVersion = async (response, id) => {
93
- const version = parseEtag(response.headers.get('etag'));
113
+ const version = parseEtag(readEtag(response) ?? null);
94
114
  if (version !== undefined) {
95
115
  return version;
96
116
  }
@@ -98,16 +118,12 @@ export function createWasSyncPort({ was, spaceId, collectionId }) {
98
118
  };
99
119
  return {
100
120
  async query({ checkpoint, limit }) {
101
- const page = await changesCollection.changes({ checkpoint, limit });
102
- return {
103
- documents: page.documents,
104
- checkpoint: page.checkpoint
105
- };
121
+ return changesCollection.changes({ checkpoint, limit });
106
122
  },
107
123
  async putContent({ id, data, ifMatch, ifNoneMatch, epoch }) {
108
124
  try {
109
125
  const response = await was.request({
110
- path: resourcePath(id),
126
+ path: contentPath(id),
111
127
  method: 'PUT',
112
128
  json: data,
113
129
  headers: writeHeaders({
@@ -118,84 +134,72 @@ export function createWasSyncPort({ was, spaceId, collectionId }) {
118
134
  return await ackedVersion(response, id);
119
135
  }
120
136
  catch (err) {
121
- if (errorStatus(err) === 412) {
122
- throw new WasSyncConflictError();
123
- }
124
- throw err;
137
+ mapWriteError(err);
125
138
  }
126
139
  },
127
140
  async deleteContent({ id, ifMatch }) {
128
141
  try {
129
142
  const response = await was.request({
130
- path: resourcePath(id),
143
+ path: contentPath(id),
131
144
  method: 'DELETE',
132
145
  headers: writeHeaders({ precondition: { ifMatch } })
133
146
  });
134
147
  return await ackedVersion(response, id);
135
148
  }
136
149
  catch (err) {
137
- const status = errorStatus(err);
138
- if (status === 404) {
139
- throw new WasSyncNotFoundError();
140
- }
141
- if (status === 412) {
142
- throw new WasSyncConflictError();
143
- }
144
- throw err;
150
+ mapWriteError(err, { notFound: true });
145
151
  }
146
152
  },
147
153
  async putMeta({ id, custom, ifMatch, ifNoneMatch }) {
148
154
  try {
149
155
  await was.request({
150
- path: `${resourcePath(id)}/meta`,
156
+ path: metaPath(id),
151
157
  method: 'PUT',
152
158
  json: { custom },
153
159
  headers: writeHeaders({ precondition: { ifMatch, ifNoneMatch } })
154
160
  });
155
161
  }
156
162
  catch (err) {
157
- if (errorStatus(err) === 412) {
158
- throw new WasSyncConflictError();
159
- }
160
- throw err;
163
+ mapWriteError(err);
161
164
  }
162
165
  },
163
166
  async get({ id }) {
167
+ // The content and metadata reads hit independent endpoints, so both fly
168
+ // together. The metadata read settles into a value (its rejection handler
169
+ // is attached before any `await` that can throw, so an abandoned read can
170
+ // 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 }));
164
172
  const master = await readContent(id);
165
173
  if (master === null) {
166
- return null;
174
+ return null; // absent or tombstoned; the metadata read is discarded
167
175
  }
168
- // Metadata re-read (best-effort): the `/meta` body carries the server-
169
- // managed `updatedAt`, the creator DID, the key-epoch id, and the user-
170
- // writable `custom`, plus its own `metaVersion` ETag. A resource with no
171
- // metadata yet 404s here; only a hard error propagates.
172
- try {
173
- const metaResponse = await was.request({
174
- path: `${resourcePath(id)}/meta`,
175
- method: 'GET'
176
- });
177
- const metaBody = metaResponse.data;
178
- if (metaBody?.updatedAt) {
179
- master.updatedAt = metaBody.updatedAt;
180
- }
181
- if (metaBody?.createdBy !== undefined) {
182
- master.createdBy = metaBody.createdBy;
183
- }
184
- if (metaBody?.epoch !== undefined) {
185
- master.epoch = metaBody.epoch;
186
- }
187
- if (metaBody?.custom !== undefined) {
188
- master.custom = metaBody.custom;
189
- }
190
- const metaVersion = parseEtag(metaResponse.headers.get('etag'));
191
- if (metaVersion !== undefined) {
192
- master.metaVersion = metaVersion;
176
+ // Metadata (best-effort): the `/meta` body carries the server-managed
177
+ // `updatedAt`, the creator DID, the key-epoch id, and the user-writable
178
+ // `custom`, plus its own `metaVersion` ETag. A resource with no metadata
179
+ // yet 404s here; only a hard error propagates.
180
+ const meta = await metaRead;
181
+ if (!meta.ok) {
182
+ if (errorStatus(meta.err) !== 404) {
183
+ throw meta.err;
193
184
  }
185
+ return master;
194
186
  }
195
- catch (err) {
196
- if (errorStatus(err) !== 404) {
197
- throw err;
198
- }
187
+ const metaBody = meta.response.data;
188
+ if (metaBody?.updatedAt) {
189
+ master.updatedAt = metaBody.updatedAt;
190
+ }
191
+ if (metaBody?.createdBy !== undefined) {
192
+ master.createdBy = metaBody.createdBy;
193
+ }
194
+ if (metaBody?.epoch !== undefined) {
195
+ master.epoch = metaBody.epoch;
196
+ }
197
+ if (metaBody?.custom !== undefined) {
198
+ master.custom = metaBody.custom;
199
+ }
200
+ const metaVersion = parseEtag(readEtag(meta.response) ?? null);
201
+ if (metaVersion !== undefined) {
202
+ master.metaVersion = metaVersion;
199
203
  }
200
204
  return master;
201
205
  }
@@ -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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"}
@@ -10,7 +10,10 @@ import type { WasClient } from '../WasClient.js';
10
10
  /**
11
11
  * Ensures the controller's Space exists and one synced collection is
12
12
  * configured. An `'edv'` collection declares the encryption descriptor `{
13
- * scheme: 'edv' }` (so the server stores only ciphertext it can never decrypt);
13
+ * scheme: 'edv', version: EDV_SCHEME_VERSION }`, so the server stores only
14
+ * ciphertext it can never decrypt and validates every write against the
15
+ * declared envelope wire format -- the same version the cipher binds into each
16
+ * envelope's AEAD-protected header, so descriptor and envelopes cannot drift;
14
17
  * a `'plaintext'` collection is configured without one, with `force` so the
15
18
  * descriptor-less upsert can create a fresh collection (running with the root
16
19
  * capability, a 404 from the pre-merge describe really means absent). A public
@@ -1 +1 @@
1
- {"version":3,"file":"provisioning.d.ts","sourceRoot":"","sources":["../../src/sync/provisioning.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;GAIG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAEhD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,wBAAwB,CAAC,EAC7C,GAAG,EACH,OAAO,EACP,aAAa,EACb,YAAY,EACZ,UAAkB,EAClB,QAAgB,EAChB,SAAuB,EACvB,cAA6B,EAC9B,EAAE;IACD,GAAG,EAAE,SAAS,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,aAAa,EAAE,MAAM,CAAA;IACrB,YAAY,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,KAAK,GAAG,WAAW,CAAA;IAChC,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB,GAAG,OAAO,CAAC,IAAI,CAAC,CA4BhB"}
1
+ {"version":3,"file":"provisioning.d.ts","sourceRoot":"","sources":["../../src/sync/provisioning.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;GAIG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAKhD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAsB,wBAAwB,CAAC,EAC7C,GAAG,EACH,OAAO,EACP,aAAa,EACb,YAAY,EACZ,UAAkB,EAClB,QAAgB,EAChB,SAAuB,EACvB,cAA6B,EAC9B,EAAE;IACD,GAAG,EAAE,SAAS,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,aAAa,EAAE,MAAM,CAAA;IACrB,YAAY,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,KAAK,GAAG,WAAW,CAAA;IAChC,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB,GAAG,OAAO,CAAC,IAAI,CAAC,CA+BhB"}
@@ -1,7 +1,13 @@
1
+ // A direct module import (not the `./edv` subpath entry), so the crypto-free
2
+ // sync module does not pull the EDV crypto graph for one number.
3
+ import { EDV_SCHEME_VERSION } from '../edv/constants.js';
1
4
  /**
2
5
  * Ensures the controller's Space exists and one synced collection is
3
6
  * configured. An `'edv'` collection declares the encryption descriptor `{
4
- * scheme: 'edv' }` (so the server stores only ciphertext it can never decrypt);
7
+ * scheme: 'edv', version: EDV_SCHEME_VERSION }`, so the server stores only
8
+ * ciphertext it can never decrypt and validates every write against the
9
+ * declared envelope wire format -- the same version the cipher binds into each
10
+ * envelope's AEAD-protected header, so descriptor and envelopes cannot drift;
5
11
  * a `'plaintext'` collection is configured without one, with `force` so the
6
12
  * descriptor-less upsert can create a fresh collection (running with the root
7
13
  * capability, a 404 from the pre-merge describe really means absent). A public
@@ -33,7 +39,10 @@ export async function ensureSpaceAndCollection({ was, spaceId, controllerDid, co
33
39
  try {
34
40
  const collection = space.collection(collectionId);
35
41
  await collection.configure(encryption === 'edv'
36
- ? { name: collectionName, encryption: { scheme: 'edv' } }
42
+ ? {
43
+ name: collectionName,
44
+ encryption: { scheme: 'edv', version: EDV_SCHEME_VERSION }
45
+ }
37
46
  : { name: collectionName, force: true });
38
47
  if (isPublic) {
39
48
  await collection.setPublic();
@@ -1 +1 @@
1
- {"version":3,"file":"provisioning.js","sourceRoot":"","sources":["../../src/sync/provisioning.ts"],"names":[],"mappings":"AAUA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,EAC7C,GAAG,EACH,OAAO,EACP,aAAa,EACb,YAAY,EACZ,UAAU,GAAG,KAAK,EAClB,QAAQ,GAAG,KAAK,EAChB,SAAS,GAAG,WAAW,EACvB,cAAc,GAAG,YAAY,EAU9B;IACC,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;IAEhC,IAAI,CAAC;QACH,MAAM,KAAK,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,EAAE,CAAC,CAAA;IACvE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,kCAAkC,OAAO,UAAU,aAAa,IAAI,EACpE,EAAE,KAAK,EAAE,GAAG,EAAE,CACf,CAAA;IACH,CAAC;IAED,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC,YAAY,CAAC,CAAA;QACjD,MAAM,UAAU,CAAC,SAAS,CACxB,UAAU,KAAK,KAAK;YAClB,CAAC,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,UAAU,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE;YACzD,CAAC,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,IAAI,EAAE,CAC1C,CAAA;QACD,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,UAAU,CAAC,SAAS,EAAE,CAAA;QAC9B,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,mCAAmC,YAAY,eAAe,OAAO,IAAI,EACzE,EAAE,KAAK,EAAE,GAAG,EAAE,CACf,CAAA;IACH,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"provisioning.js","sourceRoot":"","sources":["../../src/sync/provisioning.ts"],"names":[],"mappings":"AASA,6EAA6E;AAC7E,iEAAiE;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AAExD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,EAC7C,GAAG,EACH,OAAO,EACP,aAAa,EACb,YAAY,EACZ,UAAU,GAAG,KAAK,EAClB,QAAQ,GAAG,KAAK,EAChB,SAAS,GAAG,WAAW,EACvB,cAAc,GAAG,YAAY,EAU9B;IACC,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;IAEhC,IAAI,CAAC;QACH,MAAM,KAAK,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,EAAE,CAAC,CAAA;IACvE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,kCAAkC,OAAO,UAAU,aAAa,IAAI,EACpE,EAAE,KAAK,EAAE,GAAG,EAAE,CACf,CAAA;IACH,CAAC;IAED,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC,YAAY,CAAC,CAAA;QACjD,MAAM,UAAU,CAAC,SAAS,CACxB,UAAU,KAAK,KAAK;YAClB,CAAC,CAAC;gBACE,IAAI,EAAE,cAAc;gBACpB,UAAU,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,kBAAkB,EAAE;aAC3D;YACH,CAAC,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,IAAI,EAAE,CAC1C,CAAA;QACD,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,UAAU,CAAC,SAAS,EAAE,CAAA;QAC9B,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,mCAAmC,YAAY,eAAe,OAAO,IAAI,EACzE,EAAE,KAAK,EAAE,GAAG,EAAE,CACf,CAAA;IACH,CAAC;AACH,CAAC"}
@@ -40,16 +40,16 @@ export type WireDoc = ChangeDocument;
40
40
  export type SyncPage = ChangesPage;
41
41
  /**
42
42
  * The current master state of a single resource, read back for the 412-conflict
43
- * path ({@link WasSyncPort.get}). `deleted` distinguishes a tombstone from a
44
- * live resource. `updatedAt`, `metaVersion`, `custom`, `createdBy`, and `epoch`
45
- * are populated from the resource's `/meta` document when it exists; a resource
46
- * with no metadata yet reports an epoch-zero `updatedAt` placeholder (a valid,
47
- * sortable timestamp -- the change feed remains the authority on ordering).
43
+ * path ({@link WasSyncPort.get}). An absent or tombstoned resource surfaces as
44
+ * `get` resolving `null`, never as a `MasterState`. `updatedAt`, `metaVersion`,
45
+ * `custom`, `createdBy`, and `epoch` are populated from the resource's `/meta`
46
+ * document when it exists; a resource with no metadata yet reports an
47
+ * epoch-zero `updatedAt` placeholder (a valid, sortable timestamp -- the
48
+ * change feed remains the authority on ordering).
48
49
  */
49
50
  export interface MasterState {
50
51
  version: number;
51
52
  updatedAt: string;
52
- deleted: boolean;
53
53
  metaVersion?: number;
54
54
  data?: Json;
55
55
  custom?: Json;
@@ -74,10 +74,7 @@ export interface WasSyncPort {
74
74
  query(options: {
75
75
  checkpoint?: SyncCheckpoint;
76
76
  limit: number;
77
- }): Promise<{
78
- documents: WireDoc[];
79
- checkpoint: SyncCheckpoint | null;
80
- }>;
77
+ }): Promise<SyncPage>;
81
78
  /**
82
79
  * Conditionally writes the content body verbatim (`PUT /:id`). Pass
83
80
  * `ifNoneMatch: true` for create-if-absent, or `ifMatch` (a quoted ETag over
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/sync/types.ts"],"names":[],"mappings":"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"}
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"}