@interop/was-client 0.64.0 → 0.66.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -23
- package/dist/Collection.d.ts +26 -2
- package/dist/Collection.d.ts.map +1 -1
- package/dist/Collection.js +49 -39
- package/dist/Collection.js.map +1 -1
- package/dist/Resource.d.ts +10 -4
- package/dist/Resource.d.ts.map +1 -1
- package/dist/Resource.js +21 -9
- package/dist/Resource.js.map +1 -1
- package/dist/Space.d.ts +32 -14
- package/dist/Space.d.ts.map +1 -1
- package/dist/Space.js +104 -42
- package/dist/Space.js.map +1 -1
- package/dist/WasClient.d.ts.map +1 -1
- package/dist/WasClient.js +5 -1
- package/dist/WasClient.js.map +1 -1
- package/dist/codec.d.ts +6 -5
- package/dist/codec.d.ts.map +1 -1
- package/dist/codec.js +1 -1
- package/dist/codec.js.map +1 -1
- package/dist/edv/EdvCodec.d.ts.map +1 -1
- package/dist/edv/EdvCodec.js +3 -2
- package/dist/edv/EdvCodec.js.map +1 -1
- package/dist/edv/descriptorStore.d.ts +14 -11
- package/dist/edv/descriptorStore.d.ts.map +1 -1
- package/dist/edv/descriptorStore.js +7 -5
- package/dist/edv/descriptorStore.js.map +1 -1
- package/dist/edv/docCipher.d.ts +11 -1
- package/dist/edv/docCipher.d.ts.map +1 -1
- package/dist/edv/docCipher.js +24 -6
- package/dist/edv/docCipher.js.map +1 -1
- package/dist/edv/epochRoster.d.ts +20 -11
- package/dist/edv/epochRoster.d.ts.map +1 -1
- package/dist/edv/epochRoster.js +29 -16
- package/dist/edv/epochRoster.js.map +1 -1
- package/dist/edv/index.d.ts +3 -1
- package/dist/edv/index.d.ts.map +1 -1
- package/dist/edv/index.js +3 -1
- package/dist/edv/index.js.map +1 -1
- package/dist/edv/logGovernedDescriptorStore.d.ts.map +1 -1
- package/dist/edv/logGovernedDescriptorStore.js +5 -2
- package/dist/edv/logGovernedDescriptorStore.js.map +1 -1
- package/dist/edv/refreshingDocCipher.d.ts +4 -1
- package/dist/edv/refreshingDocCipher.d.ts.map +1 -1
- package/dist/edv/refreshingDocCipher.js +7 -4
- package/dist/edv/refreshingDocCipher.js.map +1 -1
- package/dist/errors.d.ts +17 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +20 -1
- package/dist/errors.js.map +1 -1
- package/dist/internal/cas.d.ts +58 -1
- package/dist/internal/cas.d.ts.map +1 -1
- package/dist/internal/cas.js +79 -3
- package/dist/internal/cas.js.map +1 -1
- package/dist/internal/conditional.d.ts +85 -4
- package/dist/internal/conditional.d.ts.map +1 -1
- package/dist/internal/conditional.js +102 -2
- package/dist/internal/conditional.js.map +1 -1
- package/dist/internal/features.d.ts +9 -3
- package/dist/internal/features.d.ts.map +1 -1
- package/dist/internal/features.js +33 -4
- package/dist/internal/features.js.map +1 -1
- package/dist/internal/meta.d.ts +20 -2
- package/dist/internal/meta.d.ts.map +1 -1
- package/dist/internal/meta.js +30 -4
- package/dist/internal/meta.js.map +1 -1
- package/dist/internal/request.d.ts +10 -0
- package/dist/internal/request.d.ts.map +1 -1
- package/dist/internal/request.js.map +1 -1
- package/dist/internal/write.d.ts +9 -2
- package/dist/internal/write.d.ts.map +1 -1
- package/dist/internal/write.js +18 -3
- package/dist/internal/write.js.map +1 -1
- package/dist/log/logStore.d.ts +11 -5
- package/dist/log/logStore.d.ts.map +1 -1
- package/dist/log/logStore.js +18 -5
- package/dist/log/logStore.js.map +1 -1
- package/dist/sync/index.d.ts +8 -5
- package/dist/sync/index.d.ts.map +1 -1
- package/dist/sync/index.js +8 -5
- package/dist/sync/index.js.map +1 -1
- package/dist/sync/plaintextCipher.d.ts +6 -4
- package/dist/sync/plaintextCipher.d.ts.map +1 -1
- package/dist/sync/plaintextCipher.js +19 -6
- package/dist/sync/plaintextCipher.js.map +1 -1
- package/dist/sync/port.d.ts +7 -1
- package/dist/sync/port.d.ts.map +1 -1
- package/dist/sync/port.js +18 -2
- package/dist/sync/port.js.map +1 -1
- package/dist/sync/predicates.d.ts +14 -3
- package/dist/sync/predicates.d.ts.map +1 -1
- package/dist/sync/predicates.js +16 -3
- package/dist/sync/predicates.js.map +1 -1
- package/dist/sync/types.d.ts +21 -1
- package/dist/sync/types.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PreconditionFailedError } from '../errors.js';
|
|
1
|
+
import { NotSupportedError, PreconditionFailedError, ValidationError } from '../errors.js';
|
|
2
2
|
/**
|
|
3
3
|
* The request header the server reads a content write's key-epoch id from,
|
|
4
4
|
* stamping it onto the Resource's metadata (an absent header clears any prior
|
|
@@ -34,11 +34,30 @@ export function namedPrecondition(precondition) {
|
|
|
34
34
|
? precondition
|
|
35
35
|
: undefined;
|
|
36
36
|
}
|
|
37
|
+
/**
|
|
38
|
+
* Throws `ValidationError` when a precondition names both `ifMatch` and
|
|
39
|
+
* `ifNoneMatch`. `If-Match` needs a current representation and
|
|
40
|
+
* `If-None-Match: *` needs none, so no server state satisfies the pair. Every
|
|
41
|
+
* write route checks this before acting on either member, so the caller bug
|
|
42
|
+
* surfaces as itself rather than as a create that dropped `ifMatch` or as a
|
|
43
|
+
* 412 that looks like a lost race.
|
|
44
|
+
*
|
|
45
|
+
* @param [precondition] {WritePrecondition}
|
|
46
|
+
* @returns {void}
|
|
47
|
+
*/
|
|
48
|
+
export function assertSinglePrecondition(precondition) {
|
|
49
|
+
if (precondition?.ifMatch !== undefined && precondition.ifNoneMatch) {
|
|
50
|
+
throw new ValidationError('A write cannot name both `ifMatch` and `ifNoneMatch`: an update pinned ' +
|
|
51
|
+
'to a version and a create-if-absent can never both hold. Pass ' +
|
|
52
|
+
'`ifMatch` to update or `ifNoneMatch: true` to create.');
|
|
53
|
+
}
|
|
54
|
+
}
|
|
37
55
|
/**
|
|
38
56
|
* Builds the headers for a write request: the content-type (when present) and
|
|
39
57
|
* the conditional-write precondition headers (`If-Match` / `If-None-Match: *`).
|
|
40
58
|
* Returns `undefined` when no header is needed, matching the request layer's
|
|
41
|
-
* optional `headers`.
|
|
59
|
+
* optional `headers`. Throws `ValidationError` when the precondition names both
|
|
60
|
+
* `ifMatch` and `ifNoneMatch`, a pair no server state can satisfy.
|
|
42
61
|
*
|
|
43
62
|
* @param options {object}
|
|
44
63
|
* @param [options.contentType] {string} the body content-type, if any
|
|
@@ -51,6 +70,7 @@ export function namedPrecondition(precondition) {
|
|
|
51
70
|
* @returns {Record<string, string> | undefined}
|
|
52
71
|
*/
|
|
53
72
|
export function writeHeaders({ contentType, precondition = {}, epoch }) {
|
|
73
|
+
assertSinglePrecondition(precondition);
|
|
54
74
|
const headers = {};
|
|
55
75
|
if (contentType) {
|
|
56
76
|
headers['content-type'] = contentType;
|
|
@@ -67,6 +87,86 @@ export function writeHeaders({ contentType, precondition = {}, epoch }) {
|
|
|
67
87
|
}
|
|
68
88
|
return Object.keys(headers).length > 0 ? headers : undefined;
|
|
69
89
|
}
|
|
90
|
+
/**
|
|
91
|
+
* The refusal for a guarded write whose guard the backend cannot be shown to
|
|
92
|
+
* enforce. Every such gate builds its error here, so the messages do not
|
|
93
|
+
* drift apart. The reasons:
|
|
94
|
+
*
|
|
95
|
+
* - `no-validator`: the read the write is pinned to returned no `ETag`, so the
|
|
96
|
+
* write would go out with no `If-Match` at all.
|
|
97
|
+
* - `no-feature`: the backend descriptor was read and does not list
|
|
98
|
+
* `conditional-writes`. Such a backend may serve an `ETag` on reads and still
|
|
99
|
+
* ignore `If-Match` / `If-None-Match` on writes.
|
|
100
|
+
*
|
|
101
|
+
* @param options {object}
|
|
102
|
+
* @param options.operation {string} what was refused, as the message's
|
|
103
|
+
* opening clause (e.g. `Cannot append to the resource log`)
|
|
104
|
+
* @param options.reason {'no-validator' | 'no-feature'}
|
|
105
|
+
* @returns {NotSupportedError}
|
|
106
|
+
*/
|
|
107
|
+
export function unenforcedPreconditionError({ operation, reason }) {
|
|
108
|
+
const consequence = 'so a concurrent change could be silently overwritten instead of ' +
|
|
109
|
+
'failing with a 412.';
|
|
110
|
+
if (reason === 'no-validator') {
|
|
111
|
+
return new NotSupportedError(`${operation}: the read it is pinned to returned no ETag validator, ` +
|
|
112
|
+
`so the write would go out unconditionally, ${consequence} Use a ` +
|
|
113
|
+
"backend that advertises the 'conditional-writes' feature.");
|
|
114
|
+
}
|
|
115
|
+
return new NotSupportedError(`${operation}: the write carries a precondition, but the collection's ` +
|
|
116
|
+
"backend does not advertise the 'conditional-writes' feature and may " +
|
|
117
|
+
`ignore it, ${consequence} Use a backend that advertises conditional ` +
|
|
118
|
+
'writes.');
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Refuses a write that names a precondition the backend cannot be shown to
|
|
122
|
+
* enforce, throwing {@link unenforcedPreconditionError}. A write that names
|
|
123
|
+
* none (see {@link namedPrecondition}) never probes the backend.
|
|
124
|
+
*
|
|
125
|
+
* A descriptor that could not be read at all is not evidence either way, and
|
|
126
|
+
* the write proceeds. The probe reads a collection-level path
|
|
127
|
+
* (`GET .../backend`), so a capability whose `invocationTarget` sits below the
|
|
128
|
+
* Collection -- one delegated for a single Resource -- can never read it, and
|
|
129
|
+
* WAS masks that as a 404. Refusing there would lock every such capability out
|
|
130
|
+
* of conditional writes for the handle's lifetime, and would do the same to a
|
|
131
|
+
* handle whose collection was briefly absent, since the probe caches a
|
|
132
|
+
* definitive answer. The server still answers the write on its own terms: a
|
|
133
|
+
* 412 where the precondition fails, a 404 where the collection is gone.
|
|
134
|
+
*
|
|
135
|
+
* A transient probe failure (a network error, a `401`, a `5xx`) propagates as
|
|
136
|
+
* the probe's own error, so a retrying caller still sees it as transient.
|
|
137
|
+
*
|
|
138
|
+
* @param options {object}
|
|
139
|
+
* @param options.features {FeatureProbe} the handle's backend-feature probe
|
|
140
|
+
* @param [options.precondition] {WritePrecondition} the write's precondition
|
|
141
|
+
* @param options.operation {string} what would be refused, as the message's
|
|
142
|
+
* opening clause
|
|
143
|
+
* @returns {Promise<void>}
|
|
144
|
+
*/
|
|
145
|
+
export async function assertPreconditionEnforced({ features, precondition, operation }) {
|
|
146
|
+
if (namedPrecondition(precondition) === undefined) {
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
if (await preconditionsEnforced(features)) {
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
throw unenforcedPreconditionError({ operation, reason: 'no-feature' });
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Whether a precondition sent to this backend can be relied on: it advertises
|
|
156
|
+
* `conditional-writes`, or its descriptor could not be read at all and is
|
|
157
|
+
* therefore no evidence against it (see {@link assertPreconditionEnforced}).
|
|
158
|
+
*
|
|
159
|
+
* The predicate behind the refusal, for the one caller that degrades instead
|
|
160
|
+
* of refusing: `patchCustom`'s compare-and-swap, whose pin is its own and
|
|
161
|
+
* whose documented fallback is a last-write-wins update.
|
|
162
|
+
*
|
|
163
|
+
* @param features {FeatureProbe}
|
|
164
|
+
* @returns {Promise<boolean>}
|
|
165
|
+
*/
|
|
166
|
+
export async function preconditionsEnforced(features) {
|
|
167
|
+
return ((await features.has('conditional-writes')) ||
|
|
168
|
+
(await features.descriptorAbsent()));
|
|
169
|
+
}
|
|
70
170
|
/**
|
|
71
171
|
* Reads the strong `ETag` validator a write/read response returned, or
|
|
72
172
|
* `undefined` when the backend sent none (it does not advertise the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conditional.js","sourceRoot":"","sources":["../../src/internal/conditional.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"conditional.js","sourceRoot":"","sources":["../../src/internal/conditional.ts"],"names":[],"mappings":"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"}
|
|
@@ -81,15 +81,21 @@ export declare class BackendFeatures implements FeatureProbe {
|
|
|
81
81
|
descriptorAbsent(): Promise<boolean>;
|
|
82
82
|
}
|
|
83
83
|
/**
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
* the
|
|
84
|
+
* The {@link BackendFeatures} probe for a collection, reading its backend
|
|
85
|
+
* descriptor with a signed `GET` through the shared request layer -- the probe
|
|
86
|
+
* the core handles (Collection/Resource) hold, mirroring the one
|
|
87
87
|
* `WasTransport` builds over its own requester. A descriptor that is not
|
|
88
88
|
* readable with the bound capability surfaces as a 404 (WAS masks unauthorized
|
|
89
89
|
* reads), which the probe treats as "no features advertised" -- so every
|
|
90
90
|
* affordance gate falls closed for a capability that cannot read the
|
|
91
91
|
* descriptor.
|
|
92
92
|
*
|
|
93
|
+
* Probes are shared across every handle on one client that would send the same
|
|
94
|
+
* descriptor request, so a caller that rebuilds handles (`fromCapability` per
|
|
95
|
+
* resource, or `collection(id)` in a loop) pays one `GET .../backend` per
|
|
96
|
+
* collection rather than one per handle. `Collection.resource()` still passes
|
|
97
|
+
* its own probe to its children directly, which needs no lookup at all.
|
|
98
|
+
*
|
|
93
99
|
* @param context {ClientContext}
|
|
94
100
|
* @param options {object}
|
|
95
101
|
* @param options.spaceId {string}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"features.d.ts","sourceRoot":"","sources":["../../src/internal/features.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAKjD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AAcxC;;;;;;GAMG;AACH,MAAM,WAAW,YAAY;IAC3B,GAAG,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;IACxB,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IACtC;;;;;;;;;;OAUG;IACH,gBAAgB,IAAI,OAAO,CAAC,OAAO,CAAC,CAAA;CACrC;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,MAAM,OAAO,CAAC,MAAM,EAAE,CAAC,EAC5B,gBAAgB,GAAE,MAAM,OAAO,CAAC,OAAO,CAAqB,GAC3D,YAAY,CAQd;AAED;;;;;;;;;;;;;GAaG;AACH,qBAAa,eAAgB,YAAW,YAAY;;IAWlD;;;;OAIG;gBACS,cAAc,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC;IAKlD;;;;;OAKG;IACH,GAAG,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAIxB;;;;;OAKG;IACG,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAI5C;;;;;;OAMG;IACG,gBAAgB,IAAI,OAAO,CAAC,OAAO,CAAC;CAmC3C;
|
|
1
|
+
{"version":3,"file":"features.d.ts","sourceRoot":"","sources":["../../src/internal/features.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAKjD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AAcxC;;;;;;GAMG;AACH,MAAM,WAAW,YAAY;IAC3B,GAAG,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;IACxB,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IACtC;;;;;;;;;;OAUG;IACH,gBAAgB,IAAI,OAAO,CAAC,OAAO,CAAC,CAAA;CACrC;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,MAAM,OAAO,CAAC,MAAM,EAAE,CAAC,EAC5B,gBAAgB,GAAE,MAAM,OAAO,CAAC,OAAO,CAAqB,GAC3D,YAAY,CAQd;AAED;;;;;;;;;;;;;GAaG;AACH,qBAAa,eAAgB,YAAW,YAAY;;IAWlD;;;;OAIG;gBACS,cAAc,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC;IAKlD;;;;;OAKG;IACH,GAAG,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAIxB;;;;;OAKG;IACG,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAI5C;;;;;;OAMG;IACG,gBAAgB,IAAI,OAAO,CAAC,OAAO,CAAC;CAmC3C;AA2BD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,aAAa,EACtB,EACE,OAAO,EACP,YAAY,EACZ,UAAU,EACX,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,KAAK,CAAA;CAAE,GAC/D,eAAe,CAkBjB"}
|
|
@@ -137,15 +137,37 @@ export class BackendFeatures {
|
|
|
137
137
|
}
|
|
138
138
|
}
|
|
139
139
|
/**
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
* the probe
|
|
140
|
+
* The cache key for one collection's probe under one capability. A descriptor
|
|
141
|
+
* read is answered per-capability (WAS masks a read the capability cannot make
|
|
142
|
+
* as a 404, which the probe caches as a definitive answer), so two handles may
|
|
143
|
+
* share a probe only when they would send the same request. An unbound handle
|
|
144
|
+
* keys on the empty string, which no capability id can collide with.
|
|
145
|
+
*
|
|
146
|
+
* @param options {object}
|
|
147
|
+
* @param options.spaceId {string}
|
|
148
|
+
* @param options.collectionId {string}
|
|
149
|
+
* @param [options.capability] {IZcap}
|
|
150
|
+
* @returns {string}
|
|
151
|
+
*/
|
|
152
|
+
function probeKey({ spaceId, collectionId, capability }) {
|
|
153
|
+
return `${collectionBackend(spaceId, collectionId)}\n${capability?.id ?? ''}`;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* The {@link BackendFeatures} probe for a collection, reading its backend
|
|
157
|
+
* descriptor with a signed `GET` through the shared request layer -- the probe
|
|
158
|
+
* the core handles (Collection/Resource) hold, mirroring the one
|
|
143
159
|
* `WasTransport` builds over its own requester. A descriptor that is not
|
|
144
160
|
* readable with the bound capability surfaces as a 404 (WAS masks unauthorized
|
|
145
161
|
* reads), which the probe treats as "no features advertised" -- so every
|
|
146
162
|
* affordance gate falls closed for a capability that cannot read the
|
|
147
163
|
* descriptor.
|
|
148
164
|
*
|
|
165
|
+
* Probes are shared across every handle on one client that would send the same
|
|
166
|
+
* descriptor request, so a caller that rebuilds handles (`fromCapability` per
|
|
167
|
+
* resource, or `collection(id)` in a loop) pays one `GET .../backend` per
|
|
168
|
+
* collection rather than one per handle. `Collection.resource()` still passes
|
|
169
|
+
* its own probe to its children directly, which needs no lookup at all.
|
|
170
|
+
*
|
|
149
171
|
* @param context {ClientContext}
|
|
150
172
|
* @param options {object}
|
|
151
173
|
* @param options.spaceId {string}
|
|
@@ -154,7 +176,12 @@ export class BackendFeatures {
|
|
|
154
176
|
* @returns {BackendFeatures}
|
|
155
177
|
*/
|
|
156
178
|
export function collectionBackendFeatures(context, { spaceId, collectionId, capability }) {
|
|
157
|
-
|
|
179
|
+
const key = probeKey({ spaceId, collectionId, capability });
|
|
180
|
+
const cached = context.backendFeatures?.get(key);
|
|
181
|
+
if (cached !== undefined) {
|
|
182
|
+
return cached;
|
|
183
|
+
}
|
|
184
|
+
const probe = new BackendFeatures(async () => {
|
|
158
185
|
const response = await send(context, {
|
|
159
186
|
path: collectionBackend(spaceId, collectionId),
|
|
160
187
|
method: 'GET',
|
|
@@ -164,5 +191,7 @@ export function collectionBackendFeatures(context, { spaceId, collectionId, capa
|
|
|
164
191
|
// the probe maps it to "absent"), so this null-guard is for the type only.
|
|
165
192
|
return response === null ? null : readJsonData(response);
|
|
166
193
|
});
|
|
194
|
+
context.backendFeatures?.set(key, probe);
|
|
195
|
+
return probe;
|
|
167
196
|
}
|
|
168
197
|
//# sourceMappingURL=features.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"features.js","sourceRoot":"","sources":["../../src/internal/features.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;GAQG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAEzC,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAA;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAG9C;;;;;;;;;GASG;AACH,MAAM,0BAA0B,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAA;AA0B3D;;;;;;;;;;GAUG;AACH,MAAM,UAAU,gBAAgB,CAC9B,GAA4B,EAC5B,mBAA2C,KAAK,IAAI,EAAE,CAAC,KAAK;IAE5D,OAAO;QACL,GAAG;QACH,KAAK,CAAC,GAAG,CAAC,OAAe;YACvB,OAAO,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;QACxC,CAAC;QACD,gBAAgB;KACjB,CAAA;AACH,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,OAAO,eAAe;IACjB,KAAK,CAAgB;IAC9B;;;;;OAKG;IACH,iBAAiB,GAAG,KAAK,CAAA;IAChB,eAAe,CAAwB;IAEhD;;;;OAIG;IACH,YAAY,cAAsC;QAChD,IAAI,CAAC,eAAe,GAAG,cAAc,CAAA;QACrC,IAAI,CAAC,KAAK,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAA;IAC5C,CAAC;IAED;;;;;OAKG;IACH,GAAG;QACD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAA;IACzB,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,GAAG,CAAC,OAAe;QACvB,OAAO,CAAC,MAAM,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;IAC7C,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,gBAAgB;QACpB,MAAM,IAAI,CAAC,GAAG,EAAE,CAAA;QAChB,OAAO,IAAI,CAAC,iBAAiB,CAAA;IAC/B,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,MAAM;QACV,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,CAAC,MAAM,IAAI,CAAC,eAAe,EAAE,CAExC,CAAA;YACR,OAAO,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,QAAQ,CAAC;gBACxC,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,MAAM,CACxB,CAAC,OAAO,EAAqB,EAAE,CAAC,OAAO,OAAO,KAAK,QAAQ,CAC5D;gBACH,CAAC,CAAC,EAAE,CAAA;QACR,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,CAAA;YAC9B,IAAI,MAAM,KAAK,SAAS,IAAI,0BAA0B,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;gBACnE,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAA;gBAC7B,OAAO,EAAE,CAAA;YACX,CAAC;YACD,sEAAsE;YACtE,qEAAqE;YACrE,MAAM,GAAG,CAAA;QACX,CAAC;IACH,CAAC;CACF;AAED
|
|
1
|
+
{"version":3,"file":"features.js","sourceRoot":"","sources":["../../src/internal/features.ts"],"names":[],"mappings":"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"}
|
package/dist/internal/meta.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { MetaReadSlot, MetaWriteSlot, ResourceCodec } from '../codec.js';
|
|
2
2
|
import type { ClientContext } from './request.js';
|
|
3
|
+
import type { FeatureProbe } from './features.js';
|
|
3
4
|
import type { IZcap, ResourceMetadataCustom, ResourceMetadataCustomInput } from '../types.js';
|
|
4
5
|
/**
|
|
5
6
|
* Reads a metadata document and decodes its user-writable `custom` value.
|
|
@@ -52,16 +53,22 @@ export declare function readMeta<Metadata extends {
|
|
|
52
53
|
* properties, as a full replacement
|
|
53
54
|
* @param options.slot {MetaWriteSlot} the `meta` slot being written, which
|
|
54
55
|
* an encrypting codec binds into the envelope
|
|
56
|
+
* @param options.features {FeatureProbe} the handle's backend-feature probe.
|
|
57
|
+
* A Resource's metadata validator is a Resource-level validator, so a named
|
|
58
|
+
* precondition is refused when the backend advertises no `conditional-writes`
|
|
59
|
+
* (unlike the Collection Metadata object's `metaVersion`, which a server
|
|
60
|
+
* maintains regardless and `Collection.setMeta` therefore does not gate)
|
|
55
61
|
* @param [options.ifMatch] {string} update only if the `meta` ETag matches
|
|
56
62
|
* @param [options.ifNoneMatch] {boolean} write only if no metadata is set
|
|
57
63
|
* @param [options.capability] {IZcap}
|
|
58
64
|
* @returns {Promise<{ etag?: string }>} the metadata's new ETag
|
|
59
65
|
*/
|
|
60
|
-
export declare function writeMeta(context: ClientContext, { metaPath, codec: codecPromise, custom, slot, ifMatch, ifNoneMatch, capability }: {
|
|
66
|
+
export declare function writeMeta(context: ClientContext, { metaPath, codec: codecPromise, custom, slot, features, ifMatch, ifNoneMatch, capability }: {
|
|
61
67
|
metaPath: string;
|
|
62
68
|
codec: Promise<ResourceCodec>;
|
|
63
69
|
custom: ResourceMetadataCustomInput;
|
|
64
70
|
slot: MetaWriteSlot;
|
|
71
|
+
features: FeatureProbe;
|
|
65
72
|
ifMatch?: string;
|
|
66
73
|
ifNoneMatch?: boolean;
|
|
67
74
|
capability?: IZcap;
|
|
@@ -84,11 +91,22 @@ export declare function writeMeta(context: ClientContext, { metaPath, codec: cod
|
|
|
84
91
|
* alike, so a concurrent `configure` -- or an epoch rotation -- legitimately
|
|
85
92
|
* invalidates an in-flight annotation write.
|
|
86
93
|
*
|
|
94
|
+
* `features` is the Resource side's: a Resource's metadata validator is
|
|
95
|
+
* gated on `conditional-writes`, so on a backend that advertises none the read
|
|
96
|
+
* reports no validator and the loop takes its `allowUnconditional` path -- the
|
|
97
|
+
* same last-write-wins update a backend serving no validator at all gets. That
|
|
98
|
+
* keeps `setName` / `setTags` working there rather than refusing, which is what
|
|
99
|
+
* `setMeta` does for a precondition the caller named itself. The Collection
|
|
100
|
+
* side passes none: its `metaVersion` is maintained regardless of the backend
|
|
101
|
+
* feature, so its pin always stands.
|
|
102
|
+
*
|
|
87
103
|
* @param handle {object} the Collection or Resource handle to patch
|
|
88
104
|
* @param patch {ResourceMetadataCustom} the properties to merge over the
|
|
89
105
|
* current `custom`
|
|
90
106
|
* @param operation {string} what the caller is doing, for the exhaustion
|
|
91
107
|
* error (e.g. `Metadata update`)
|
|
108
|
+
* @param [features] {FeatureProbe} the handle's backend-feature probe, when
|
|
109
|
+
* its metadata validator is gated on `conditional-writes`
|
|
92
110
|
* @returns {Promise<void>}
|
|
93
111
|
*/
|
|
94
112
|
export declare function patchCustom(handle: {
|
|
@@ -103,5 +121,5 @@ export declare function patchCustom(handle: {
|
|
|
103
121
|
}): Promise<{
|
|
104
122
|
etag?: string;
|
|
105
123
|
}>;
|
|
106
|
-
}, patch: ResourceMetadataCustom, operation?: string): Promise<void>;
|
|
124
|
+
}, patch: ResourceMetadataCustom, operation?: string, features?: FeatureProbe): Promise<void>;
|
|
107
125
|
//# sourceMappingURL=meta.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"meta.d.ts","sourceRoot":"","sources":["../../src/internal/meta.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC7E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;
|
|
1
|
+
{"version":3,"file":"meta.d.ts","sourceRoot":"","sources":["../../src/internal/meta.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC7E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAQjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAEjD,OAAO,KAAK,EACV,KAAK,EACL,sBAAsB,EACtB,2BAA2B,EAC5B,MAAM,aAAa,CAAA;AAEpB;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,QAAQ,CAC5B,QAAQ,SAAS;IAAE,MAAM,CAAC,EAAE,sBAAsB,CAAA;CAAE,EAEpD,OAAO,EAAE,aAAa,EACtB,EACE,QAAQ,EACR,KAAK,EAAE,YAAY,EACnB,OAAO,EACP,IAAI,EACJ,UAAU,EACV,QAAQ,EACT,EAAE;IACD,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,OAAO,CAAC,aAAa,CAAC,CAAA;IAC7B,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,YAAY,CAAA;IAClB,UAAU,CAAC,EAAE,KAAK,CAAA;IAClB,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE;QAChB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;QACjC,IAAI,CAAC,EAAE,MAAM,CAAA;KACd,KAAK,IAAI,CAAA;CACX,GACA,OAAO,CAAC,CAAC,QAAQ,GAAG;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,IAAI,CAAC,CA4ChD;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAsB,SAAS,CAC7B,OAAO,EAAE,aAAa,EACtB,EACE,QAAQ,EACR,KAAK,EAAE,YAAY,EACnB,MAAM,EACN,IAAI,EACJ,QAAQ,EACR,OAAO,EACP,WAAW,EACX,UAAU,EACX,EAAE;IACD,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,OAAO,CAAC,aAAa,CAAC,CAAA;IAC7B,MAAM,EAAE,2BAA2B,CAAA;IACnC,IAAI,EAAE,aAAa,CAAA;IACnB,QAAQ,EAAE,YAAY,CAAA;IACtB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,UAAU,CAAC,EAAE,KAAK,CAAA;CACnB,GACA,OAAO,CAAC;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAgB5B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE;IACN,IAAI,IAAI,OAAO,CAAC;QAAE,MAAM,CAAC,EAAE,sBAAsB,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC,CAAA;IAC1E,OAAO,CACL,IAAI,EAAE;QAAE,MAAM,CAAC,EAAE,sBAAsB,CAAA;KAAE,EACzC,OAAO,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAC5B,OAAO,CAAC;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAC9B,EACD,KAAK,EAAE,sBAAsB,EAC7B,SAAS,SAAoB,EAC7B,QAAQ,CAAC,EAAE,YAAY,GACtB,OAAO,CAAC,IAAI,CAAC,CAuBf"}
|
package/dist/internal/meta.js
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
import { WasServerError } from '../errors.js';
|
|
16
16
|
import { compareAndSwap } from './cas.js';
|
|
17
17
|
import { send } from './request.js';
|
|
18
|
-
import { readEtag, writeHeaders } from './conditional.js';
|
|
18
|
+
import { assertPreconditionEnforced, preconditionsEnforced, readEtag, writeHeaders } from './conditional.js';
|
|
19
19
|
import { withCodec } from './withCodec.js';
|
|
20
20
|
/**
|
|
21
21
|
* Reads a metadata document and decodes its user-writable `custom` value.
|
|
@@ -93,12 +93,22 @@ export async function readMeta(context, { metaPath, codec: codecPromise, subject
|
|
|
93
93
|
* properties, as a full replacement
|
|
94
94
|
* @param options.slot {MetaWriteSlot} the `meta` slot being written, which
|
|
95
95
|
* an encrypting codec binds into the envelope
|
|
96
|
+
* @param options.features {FeatureProbe} the handle's backend-feature probe.
|
|
97
|
+
* A Resource's metadata validator is a Resource-level validator, so a named
|
|
98
|
+
* precondition is refused when the backend advertises no `conditional-writes`
|
|
99
|
+
* (unlike the Collection Metadata object's `metaVersion`, which a server
|
|
100
|
+
* maintains regardless and `Collection.setMeta` therefore does not gate)
|
|
96
101
|
* @param [options.ifMatch] {string} update only if the `meta` ETag matches
|
|
97
102
|
* @param [options.ifNoneMatch] {boolean} write only if no metadata is set
|
|
98
103
|
* @param [options.capability] {IZcap}
|
|
99
104
|
* @returns {Promise<{ etag?: string }>} the metadata's new ETag
|
|
100
105
|
*/
|
|
101
|
-
export async function writeMeta(context, { metaPath, codec: codecPromise, custom, slot, ifMatch, ifNoneMatch, capability }) {
|
|
106
|
+
export async function writeMeta(context, { metaPath, codec: codecPromise, custom, slot, features, ifMatch, ifNoneMatch, capability }) {
|
|
107
|
+
await assertPreconditionEnforced({
|
|
108
|
+
features,
|
|
109
|
+
precondition: { ifMatch, ifNoneMatch },
|
|
110
|
+
operation: `Cannot write the metadata at "${metaPath}"`
|
|
111
|
+
});
|
|
102
112
|
const codec = await codecPromise;
|
|
103
113
|
const { custom: encoded } = await codec.encodeMeta({ custom, slot });
|
|
104
114
|
const response = await send(context, {
|
|
@@ -126,21 +136,34 @@ export async function writeMeta(context, { metaPath, codec: codecPromise, custom
|
|
|
126
136
|
* alike, so a concurrent `configure` -- or an epoch rotation -- legitimately
|
|
127
137
|
* invalidates an in-flight annotation write.
|
|
128
138
|
*
|
|
139
|
+
* `features` is the Resource side's: a Resource's metadata validator is
|
|
140
|
+
* gated on `conditional-writes`, so on a backend that advertises none the read
|
|
141
|
+
* reports no validator and the loop takes its `allowUnconditional` path -- the
|
|
142
|
+
* same last-write-wins update a backend serving no validator at all gets. That
|
|
143
|
+
* keeps `setName` / `setTags` working there rather than refusing, which is what
|
|
144
|
+
* `setMeta` does for a precondition the caller named itself. The Collection
|
|
145
|
+
* side passes none: its `metaVersion` is maintained regardless of the backend
|
|
146
|
+
* feature, so its pin always stands.
|
|
147
|
+
*
|
|
129
148
|
* @param handle {object} the Collection or Resource handle to patch
|
|
130
149
|
* @param patch {ResourceMetadataCustom} the properties to merge over the
|
|
131
150
|
* current `custom`
|
|
132
151
|
* @param operation {string} what the caller is doing, for the exhaustion
|
|
133
152
|
* error (e.g. `Metadata update`)
|
|
153
|
+
* @param [features] {FeatureProbe} the handle's backend-feature probe, when
|
|
154
|
+
* its metadata validator is gated on `conditional-writes`
|
|
134
155
|
* @returns {Promise<void>}
|
|
135
156
|
*/
|
|
136
|
-
export async function patchCustom(handle, patch, operation = 'Metadata update') {
|
|
157
|
+
export async function patchCustom(handle, patch, operation = 'Metadata update', features) {
|
|
137
158
|
await compareAndSwap({
|
|
138
159
|
store: {
|
|
139
160
|
read: async () => {
|
|
140
161
|
const current = await handle.meta();
|
|
162
|
+
const pinnable = features === undefined || (await preconditionsEnforced(features));
|
|
163
|
+
const etag = pinnable ? current?.etag : undefined;
|
|
141
164
|
return {
|
|
142
165
|
value: current?.custom ?? {},
|
|
143
|
-
...(
|
|
166
|
+
...(etag !== undefined && { etag })
|
|
144
167
|
};
|
|
145
168
|
},
|
|
146
169
|
replace: async (custom, { ifMatch }) => {
|
|
@@ -148,6 +171,9 @@ export async function patchCustom(handle, patch, operation = 'Metadata update')
|
|
|
148
171
|
}
|
|
149
172
|
},
|
|
150
173
|
operation,
|
|
174
|
+
// A handle's name and tags stay writable on a backend that serves no
|
|
175
|
+
// metadata validator; the write is then last-write-wins.
|
|
176
|
+
allowUnconditional: true,
|
|
151
177
|
mutate: custom => ({ ...custom, ...patch })
|
|
152
178
|
});
|
|
153
179
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"meta.js","sourceRoot":"","sources":["../../src/internal/meta.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;GAUG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAGzC,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAA;AACnC,OAAO,
|
|
1
|
+
{"version":3,"file":"meta.js","sourceRoot":"","sources":["../../src/internal/meta.ts"],"names":[],"mappings":"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"}
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
import type { ZcapClient } from '@interop/ezcap';
|
|
14
14
|
import type { HttpResponse } from '@interop/http-client';
|
|
15
15
|
import type { EncryptionProvider } from '../codec.js';
|
|
16
|
+
import type { BackendFeatures } from './features.js';
|
|
16
17
|
import type { IZcap, RequestInput, ServiceInfo } from '../types.js';
|
|
17
18
|
/**
|
|
18
19
|
* The shared context threaded through every handle: the server base URL, the
|
|
@@ -27,6 +28,15 @@ export interface ClientContext {
|
|
|
27
28
|
controllerDid: string;
|
|
28
29
|
encryption?: EncryptionProvider;
|
|
29
30
|
service: () => Promise<ServiceInfo>;
|
|
31
|
+
/**
|
|
32
|
+
* The client's shared backend-feature probes, keyed by descriptor request
|
|
33
|
+
* (collection path plus bound capability id). Handles built separately --
|
|
34
|
+
* `fromCapability` per resource, `collection(id)` in a loop -- then share one
|
|
35
|
+
* `GET .../backend` instead of repeating it per handle. Optional: a context
|
|
36
|
+
* assembled without one (a test fixture, `WasTransport`'s own requester)
|
|
37
|
+
* simply builds an unshared probe per handle, as before.
|
|
38
|
+
*/
|
|
39
|
+
backendFeatures?: Map<string, BackendFeatures>;
|
|
30
40
|
}
|
|
31
41
|
/**
|
|
32
42
|
* A single signed request: the public `RequestInput` shape (either `path`,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../src/internal/request.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAChD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAKxD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../src/internal/request.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAChD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAKxD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAErD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AACpD,OAAO,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAEnE;;;;;;GAMG;AACH,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,UAAU,CAAA;IACtB,aAAa,EAAE,MAAM,CAAA;IACrB,UAAU,CAAC,EAAE,kBAAkB,CAAA;IAC/B,OAAO,EAAE,MAAM,OAAO,CAAC,WAAW,CAAC,CAAA;IACnC;;;;;;;OAOG;IACH,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAAA;CAC/C;AAED;;;;GAIG;AACH,MAAM,WAAW,SAAU,SAAQ,YAAY;IAC7C;;OAEG;IACH,IAAI,CAAC,EAAE,OAAO,CAAA;IACd;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAA;CACrB;AAYD;;;;;;;;;;GAUG;AACH,wBAAsB,UAAU,CAC9B,OAAO,EAAE,aAAa,EACtB,KAAK,EAAE,SAAS,GACf,OAAO,CAAC,YAAY,CAAC,CAcvB;AAED;;;;;;;;GAQG;AACH,wBAAsB,WAAW,CAC/B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,WAAW,GAChB,OAAO,CAAC,QAAQ,CAAC,CAMnB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,eAAe,CAAC,KAAK,EAAE;IAC3C,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,IAAI,CAAC,EAAE,OAAO,CAAA;CACf,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CA4B/B;AAED;;;;;;;;GAQG;AACH,wBAAsB,IAAI,CACxB,OAAO,EAAE,aAAa,EACtB,KAAK,EAAE,SAAS,GACf,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAe9B;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,QAAQ,CAAC,CAAC,EAC9B,OAAO,EAAE,aAAa,EACtB,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,KAAK,CAAA;CAAE,GACzD,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAQnB;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,gBAAgB,CAAC,CAAC,EACtC,OAAO,EAAE,aAAa,EACtB,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,KAAK,CAAA;CAAE,GACzD,OAAO,CAAC;IAAE,IAAI,EAAE,CAAC,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAY5C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request.js","sourceRoot":"","sources":["../../src/internal/request.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAC7D,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAClC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"request.js","sourceRoot":"","sources":["../../src/internal/request.ts"],"names":[],"mappings":"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"}
|
package/dist/internal/write.d.ts
CHANGED
|
@@ -154,6 +154,13 @@ export declare function insertResource(context: ClientContext, { itemsPath, path
|
|
|
154
154
|
* masked-404 insert would silently overwrite the existing document and reset
|
|
155
155
|
* its sequence. The insert-after-null-pre-read is therefore refused (fail
|
|
156
156
|
* closed) unless the backend advertises the feature.
|
|
157
|
+
* - A caller's named precondition is refused with `NotSupportedError` when the
|
|
158
|
+
* backend descriptor was read and advertises no `conditional-writes`,
|
|
159
|
+
* whatever the collection's codec. A backend that ignores `If-Match` would
|
|
160
|
+
* otherwise turn the caller's compare-and-swap into a silent overwrite. This
|
|
161
|
+
* is the one gate every guarded write through a handle passes, so the stores
|
|
162
|
+
* layered over `Resource.put` (the resource log, the descriptor stores) do
|
|
163
|
+
* not repeat it.
|
|
157
164
|
*
|
|
158
165
|
* @param context {ClientContext}
|
|
159
166
|
* @param options {object}
|
|
@@ -162,8 +169,8 @@ export declare function insertResource(context: ClientContext, { itemsPath, path
|
|
|
162
169
|
* @param options.id {string} the resource id
|
|
163
170
|
* @param options.data {ResourceData} the plaintext value
|
|
164
171
|
* @param options.features {FeatureProbe} the handle's shared
|
|
165
|
-
* `BackendFeatures` probe; consulted
|
|
166
|
-
* insert-after-null-pre-read
|
|
172
|
+
* `BackendFeatures` probe; consulted for a named precondition and for a
|
|
173
|
+
* conditional codec's insert-after-null-pre-read
|
|
167
174
|
* @param [options.contentType] {string} caller-supplied content type
|
|
168
175
|
* @param [options.capability] {IZcap}
|
|
169
176
|
* @param [options.precondition] {WritePrecondition} the caller's explicit
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"write.d.ts","sourceRoot":"","sources":["../../src/internal/write.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AACxD,OAAO,KAAK,EACV,mBAAmB,EACnB,YAAY,EACZ,aAAa,EACd,MAAM,aAAa,CAAA;AAGpB,OAAO,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AACtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAEjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"write.d.ts","sourceRoot":"","sources":["../../src/internal/write.ts"],"names":[],"mappings":"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"}
|
package/dist/internal/write.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { isChunkedWrite } from '../codec.js';
|
|
2
2
|
import { PreconditionFailedError, ValidationError } from '../errors.js';
|
|
3
3
|
import { send } from './request.js';
|
|
4
|
-
import { assertPreconditionAgainstPreRead, encodedPrecondition, writeHeaders, namedPrecondition } from './conditional.js';
|
|
4
|
+
import { assertPreconditionAgainstPreRead, assertPreconditionEnforced, assertSinglePrecondition, encodedPrecondition, writeHeaders, namedPrecondition } from './conditional.js';
|
|
5
5
|
/**
|
|
6
6
|
* Sends an encoded write (`PUT`/`POST`) to a resource path, applying the
|
|
7
7
|
* encoded body (`json` or `body`), its content-type, and the conditional-write
|
|
@@ -146,6 +146,13 @@ export async function insertResource(context, { itemsPath, pathForId, codec, dat
|
|
|
146
146
|
* masked-404 insert would silently overwrite the existing document and reset
|
|
147
147
|
* its sequence. The insert-after-null-pre-read is therefore refused (fail
|
|
148
148
|
* closed) unless the backend advertises the feature.
|
|
149
|
+
* - A caller's named precondition is refused with `NotSupportedError` when the
|
|
150
|
+
* backend descriptor was read and advertises no `conditional-writes`,
|
|
151
|
+
* whatever the collection's codec. A backend that ignores `If-Match` would
|
|
152
|
+
* otherwise turn the caller's compare-and-swap into a silent overwrite. This
|
|
153
|
+
* is the one gate every guarded write through a handle passes, so the stores
|
|
154
|
+
* layered over `Resource.put` (the resource log, the descriptor stores) do
|
|
155
|
+
* not repeat it.
|
|
149
156
|
*
|
|
150
157
|
* @param context {ClientContext}
|
|
151
158
|
* @param options {object}
|
|
@@ -154,8 +161,8 @@ export async function insertResource(context, { itemsPath, pathForId, codec, dat
|
|
|
154
161
|
* @param options.id {string} the resource id
|
|
155
162
|
* @param options.data {ResourceData} the plaintext value
|
|
156
163
|
* @param options.features {FeatureProbe} the handle's shared
|
|
157
|
-
* `BackendFeatures` probe; consulted
|
|
158
|
-
* insert-after-null-pre-read
|
|
164
|
+
* `BackendFeatures` probe; consulted for a named precondition and for a
|
|
165
|
+
* conditional codec's insert-after-null-pre-read
|
|
159
166
|
* @param [options.contentType] {string} caller-supplied content type
|
|
160
167
|
* @param [options.capability] {IZcap}
|
|
161
168
|
* @param [options.precondition] {WritePrecondition} the caller's explicit
|
|
@@ -165,6 +172,14 @@ export async function insertResource(context, { itemsPath, pathForId, codec, dat
|
|
|
165
172
|
export async function upsertResource(context, { path, codec, id, data, features, contentType, capability, precondition: callerPrecondition }) {
|
|
166
173
|
// An empty precondition object (the handle's default) names no baseline.
|
|
167
174
|
const precondition = namedPrecondition(callerPrecondition);
|
|
175
|
+
// Checked before the pre-read, whose comparison would otherwise answer the
|
|
176
|
+
// pair with a 412 either way.
|
|
177
|
+
assertSinglePrecondition(precondition);
|
|
178
|
+
await assertPreconditionEnforced({
|
|
179
|
+
features,
|
|
180
|
+
precondition,
|
|
181
|
+
operation: `Cannot write the resource at "${path}"`
|
|
182
|
+
});
|
|
168
183
|
let current;
|
|
169
184
|
if (codec.conditionalWrites) {
|
|
170
185
|
current = await send(context, {
|
|
@@ -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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"}
|
package/dist/log/logStore.d.ts
CHANGED
|
@@ -19,11 +19,17 @@
|
|
|
19
19
|
* document under a human-readable id. A Collection's history log is never
|
|
20
20
|
* encrypted and runs no codec: the server reads its head itself.
|
|
21
21
|
*
|
|
22
|
-
* Both the append and the create
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
22
|
+
* Both the append and the create depend on their precondition being enforced --
|
|
23
|
+
* the profile requires it (without it, concurrent appends silently overwrite
|
|
24
|
+
* one another instead of failing into the caller's rebase-and-retry loop). On
|
|
25
|
+
* a Resource host that is the backend's `conditional-writes` feature, and
|
|
26
|
+
* `Resource.put` refuses the write before it is sent when the backend was read
|
|
27
|
+
* and does not advertise it. A Collection's history log carries its own
|
|
28
|
+
* validator, which a server implementing the sub-resource honors whether or
|
|
29
|
+
* not the backend advertises the feature, so nothing gates that host. Either
|
|
30
|
+
* way an append is refused when the read it extends returned no validator.
|
|
31
|
+
* A lost race -- a stale `ifMatch`, or a guarded create against a log that
|
|
32
|
+
* already exists -- is rethrown as the library's
|
|
27
33
|
* `ResourceLogConflictError` with the transport's `PreconditionFailedError`
|
|
28
34
|
* as `cause`, which is the port's one conflict signal and what the library's
|
|
29
35
|
* rebase loop catches (by `name` rather than `instanceof`, since the error
|