@interop/was-client 0.22.0 → 0.23.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 +12 -11
- package/dist/Collection.d.ts +28 -25
- package/dist/Collection.d.ts.map +1 -1
- package/dist/Collection.js +55 -51
- package/dist/Collection.js.map +1 -1
- package/dist/Resource.d.ts +7 -7
- package/dist/Resource.d.ts.map +1 -1
- package/dist/Resource.js +19 -18
- package/dist/Resource.js.map +1 -1
- package/dist/Space.d.ts +3 -2
- package/dist/Space.d.ts.map +1 -1
- package/dist/Space.js +5 -4
- package/dist/Space.js.map +1 -1
- package/dist/WasClient.d.ts +19 -17
- package/dist/WasClient.d.ts.map +1 -1
- package/dist/WasClient.js +23 -21
- package/dist/WasClient.js.map +1 -1
- package/dist/codec.d.ts +16 -15
- package/dist/codec.d.ts.map +1 -1
- package/dist/edv/EdvCodec.d.ts +2 -2
- package/dist/edv/EdvCodec.d.ts.map +1 -1
- package/dist/edv/EdvCodec.js +29 -28
- package/dist/edv/EdvCodec.js.map +1 -1
- package/dist/edv/WasTransport.d.ts +9 -8
- package/dist/edv/WasTransport.d.ts.map +1 -1
- package/dist/edv/WasTransport.js +9 -8
- package/dist/edv/WasTransport.js.map +1 -1
- package/dist/edv/constants.js +1 -1
- package/dist/edv/descriptorStore.d.ts +119 -0
- package/dist/edv/descriptorStore.d.ts.map +1 -0
- package/dist/edv/{markerStore.js → descriptorStore.js} +41 -40
- package/dist/edv/descriptorStore.js.map +1 -0
- package/dist/edv/docCipher.d.ts +31 -29
- package/dist/edv/docCipher.d.ts.map +1 -1
- package/dist/edv/docCipher.js +26 -24
- package/dist/edv/docCipher.js.map +1 -1
- package/dist/edv/epochCrypto.d.ts +8 -8
- package/dist/edv/epochCrypto.d.ts.map +1 -1
- package/dist/edv/epochCrypto.js +15 -14
- package/dist/edv/epochCrypto.js.map +1 -1
- package/dist/edv/epochKeys.d.ts +18 -15
- package/dist/edv/epochKeys.d.ts.map +1 -1
- package/dist/edv/epochKeys.js +20 -19
- package/dist/edv/epochKeys.js.map +1 -1
- package/dist/edv/epochMac.d.ts +11 -10
- package/dist/edv/epochMac.d.ts.map +1 -1
- package/dist/edv/epochMac.js +24 -23
- package/dist/edv/epochMac.js.map +1 -1
- package/dist/edv/index.d.ts +8 -7
- package/dist/edv/index.d.ts.map +1 -1
- package/dist/edv/index.js +7 -6
- package/dist/edv/index.js.map +1 -1
- package/dist/edv/recipients.d.ts +31 -30
- package/dist/edv/recipients.d.ts.map +1 -1
- package/dist/edv/recipients.js +83 -80
- package/dist/edv/recipients.js.map +1 -1
- package/dist/errors.d.ts +2 -2
- package/dist/errors.js +2 -2
- package/dist/internal/codec.d.ts +8 -8
- package/dist/internal/codec.d.ts.map +1 -1
- package/dist/internal/codec.js +12 -12
- package/dist/internal/codec.js.map +1 -1
- package/dist/internal/describe.d.ts +3 -3
- package/dist/sync/envelope.d.ts +2 -2
- package/dist/sync/envelope.js +2 -2
- package/dist/sync/provisioning.d.ts +10 -10
- package/dist/sync/provisioning.js +9 -9
- package/dist/sync/types.d.ts +4 -4
- package/dist/types.d.ts +5 -5
- package/package.json +2 -2
- package/dist/edv/markerStore.d.ts +0 -118
- package/dist/edv/markerStore.d.ts.map +0 -1
- package/dist/edv/markerStore.js.map +0 -1
package/dist/internal/codec.js
CHANGED
|
@@ -4,9 +4,9 @@ import { EncryptionError } from '../errors.js';
|
|
|
4
4
|
/**
|
|
5
5
|
* A per-handle codec cache. Memoizes the in-flight resolution so concurrent
|
|
6
6
|
* callers share one round-trip, but drops it on rejection so a transient
|
|
7
|
-
* failure (e.g. a 500/network error during
|
|
7
|
+
* failure (e.g. a 500/network error during descriptor discovery) does not
|
|
8
8
|
* permanently poison the handle, and exposes `reset()` for when a handle's
|
|
9
|
-
* encryption state changes (e.g. `Collection.configure()` adds the
|
|
9
|
+
* encryption state changes (e.g. `Collection.configure()` adds the descriptor).
|
|
10
10
|
*/
|
|
11
11
|
export class CodecHolder {
|
|
12
12
|
#promise;
|
|
@@ -93,25 +93,25 @@ export const identityCodec = {
|
|
|
93
93
|
}
|
|
94
94
|
};
|
|
95
95
|
/**
|
|
96
|
-
* Resolves the codec for a collection by deciding policy (override >
|
|
97
|
-
* plaintext) and then, when encrypted, building the encrypting codec from the
|
|
96
|
+
* Resolves the codec for a collection by deciding policy (override > descriptor
|
|
97
|
+
* > plaintext) and then, when encrypted, building the encrypting codec from the
|
|
98
98
|
* keystore. Fails closed: a collection declared encrypted (by override or
|
|
99
|
-
*
|
|
100
|
-
* than falling back to {@link identityCodec}.
|
|
99
|
+
* descriptor) for which no codec can be built throws {@link EncryptionError}
|
|
100
|
+
* rather than falling back to {@link identityCodec}.
|
|
101
101
|
*
|
|
102
102
|
* @param context {ClientContext}
|
|
103
103
|
* @param options {object}
|
|
104
104
|
* @param options.spaceId {string}
|
|
105
105
|
* @param options.collectionId {string}
|
|
106
106
|
* @param [options.override] {EncryptionOverride} per-handle override; wins
|
|
107
|
-
* over the
|
|
107
|
+
* over the descriptor and skips the descriptor read
|
|
108
108
|
* @param [options.capability] {IZcap} the handle's bound capability, used for
|
|
109
|
-
* the
|
|
109
|
+
* the descriptor-discovery describe (which happens only when there is no
|
|
110
110
|
* override and the client has a keystore)
|
|
111
111
|
* @returns {Promise<ResourceCodec>}
|
|
112
112
|
*/
|
|
113
113
|
export async function resolveCodec(context, { spaceId, collectionId, override, capability }) {
|
|
114
|
-
// 1. A per-handle override wins and skips the
|
|
114
|
+
// 1. A per-handle override wins and skips the descriptor read.
|
|
115
115
|
if (override !== undefined) {
|
|
116
116
|
if (override === 'plaintext') {
|
|
117
117
|
return identityCodec;
|
|
@@ -121,9 +121,9 @@ export async function resolveCodec(context, { spaceId, collectionId, override, c
|
|
|
121
121
|
collectionId,
|
|
122
122
|
scheme: override.scheme,
|
|
123
123
|
keys: override.keys,
|
|
124
|
-
// A full `CollectionEncryption`
|
|
124
|
+
// A full `CollectionEncryption` descriptor is itself a valid override
|
|
125
125
|
// (Space.createCollection pre-seeds exactly this). Forward the whole
|
|
126
|
-
// override as the `encryption`
|
|
126
|
+
// override as the `encryption` descriptor so an epoch-bearing override
|
|
127
127
|
// resolves the epoch codec -- the provider's `codecFor` selects the epoch
|
|
128
128
|
// path solely on `encryption?.epochs?.length > 0`, so dropping it here
|
|
129
129
|
// would force the single-key path and break epoch reads/writes.
|
|
@@ -134,7 +134,7 @@ export async function resolveCodec(context, { spaceId, collectionId, override, c
|
|
|
134
134
|
if (!context.encryption) {
|
|
135
135
|
return identityCodec;
|
|
136
136
|
}
|
|
137
|
-
// 3. Otherwise the Collection's declared `encryption`
|
|
137
|
+
// 3. Otherwise the Collection's declared `encryption` descriptor decides -- but
|
|
138
138
|
// only if we could actually read the description. An unreadable description
|
|
139
139
|
// (a resource-scoped capability cannot GET the collection description, and
|
|
140
140
|
// WAS masks that as a 404) is ambiguous: it is indistinguishable from
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codec.js","sourceRoot":"","sources":["../../src/internal/codec.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"codec.js","sourceRoot":"","sources":["../../src/internal/codec.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
*/
|
|
4
4
|
/**
|
|
5
5
|
* Reads a Collection Description with a single GET. Shared by
|
|
6
|
-
* `Collection.describe()` and the standalone-resource codec's
|
|
7
|
-
* so the request shape (path, capability, null-unwrap) lives in one
|
|
8
|
-
* Also owns the masked-404 fail-closed policy: WAS returns 404 for both
|
|
6
|
+
* `Collection.describe()` and the standalone-resource codec's descriptor
|
|
7
|
+
* discovery so the request shape (path, capability, null-unwrap) lives in one
|
|
8
|
+
* place. Also owns the masked-404 fail-closed policy: WAS returns 404 for both
|
|
9
9
|
* not-found and unauthorized, so a `null` description is ambiguous and an
|
|
10
10
|
* operation that must know the current state fails closed via
|
|
11
11
|
* `unreadableDescriptionError` rather than guessing.
|
package/dist/sync/envelope.d.ts
CHANGED
|
@@ -10,8 +10,8 @@ import type { Json } from '../types.js';
|
|
|
10
10
|
/**
|
|
11
11
|
* Whether a stored body is an EDV encryption envelope (carries an object `jwe`)
|
|
12
12
|
* rather than a plaintext document. Lets read paths stay tolerant of legacy
|
|
13
|
-
* plaintext rows (written before a collection's encryption
|
|
14
|
-
* and lets a one-time migration find the rows it must re-key.
|
|
13
|
+
* plaintext rows (written before a collection's encryption descriptor was
|
|
14
|
+
* declared) and lets a one-time migration find the rows it must re-key.
|
|
15
15
|
*
|
|
16
16
|
* @param data {Json | undefined} the stored resource body
|
|
17
17
|
* @returns {boolean}
|
package/dist/sync/envelope.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Whether a stored body is an EDV encryption envelope (carries an object `jwe`)
|
|
3
3
|
* rather than a plaintext document. Lets read paths stay tolerant of legacy
|
|
4
|
-
* plaintext rows (written before a collection's encryption
|
|
5
|
-
* and lets a one-time migration find the rows it must re-key.
|
|
4
|
+
* plaintext rows (written before a collection's encryption descriptor was
|
|
5
|
+
* declared) and lets a one-time migration find the rows it must re-key.
|
|
6
6
|
*
|
|
7
7
|
* @param data {Json | undefined} the stored resource body
|
|
8
8
|
* @returns {boolean}
|
|
@@ -3,20 +3,20 @@
|
|
|
3
3
|
*/
|
|
4
4
|
/**
|
|
5
5
|
* Idempotent Space + Collection provisioning for a synced collection. Re-running
|
|
6
|
-
* is safe: the server upserts the Space and allows a late encryption-
|
|
6
|
+
* is safe: the server upserts the Space and allows a late encryption-descriptor
|
|
7
7
|
* declaration, so reconnecting an existing account is a no-op upgrade.
|
|
8
8
|
*/
|
|
9
9
|
import type { WasClient } from '../WasClient.js';
|
|
10
10
|
/**
|
|
11
|
-
* Ensures the controller's Space exists and one synced collection is
|
|
12
|
-
* An `'edv'` collection declares the encryption
|
|
13
|
-
* the server stores only ciphertext it can never decrypt);
|
|
14
|
-
* collection is configured without one, with `force` so the
|
|
15
|
-
* can create a fresh collection (running with the root
|
|
16
|
-
* the pre-merge describe really means absent). A public
|
|
17
|
-
* gets a collection-level world-read grant
|
|
18
|
-
* resource URL in it resolve for anyone.
|
|
19
|
-
* its own root capability.
|
|
11
|
+
* Ensures the controller's Space exists and one synced collection is
|
|
12
|
+
* configured. An `'edv'` collection declares the encryption descriptor `{
|
|
13
|
+
* scheme: 'edv' }` (so the server stores only ciphertext it can never decrypt);
|
|
14
|
+
* a `'plaintext'` collection is configured without one, with `force` so the
|
|
15
|
+
* descriptor-less upsert can create a fresh collection (running with the root
|
|
16
|
+
* capability, a 404 from the pre-merge describe really means absent). A public
|
|
17
|
+
* collection additionally gets a collection-level world-read grant
|
|
18
|
+
* (`setPublic`), which is what makes a resource URL in it resolve for anyone.
|
|
19
|
+
* Runs full-tier -- the client invokes its own root capability.
|
|
20
20
|
*
|
|
21
21
|
* @param options {object}
|
|
22
22
|
* @param options.was {WasClient}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Ensures the controller's Space exists and one synced collection is
|
|
3
|
-
* An `'edv'` collection declares the encryption
|
|
4
|
-
* the server stores only ciphertext it can never decrypt);
|
|
5
|
-
* collection is configured without one, with `force` so the
|
|
6
|
-
* can create a fresh collection (running with the root
|
|
7
|
-
* the pre-merge describe really means absent). A public
|
|
8
|
-
* gets a collection-level world-read grant
|
|
9
|
-
* resource URL in it resolve for anyone.
|
|
10
|
-
* its own root capability.
|
|
2
|
+
* Ensures the controller's Space exists and one synced collection is
|
|
3
|
+
* configured. An `'edv'` collection declares the encryption descriptor `{
|
|
4
|
+
* scheme: 'edv' }` (so the server stores only ciphertext it can never decrypt);
|
|
5
|
+
* a `'plaintext'` collection is configured without one, with `force` so the
|
|
6
|
+
* descriptor-less upsert can create a fresh collection (running with the root
|
|
7
|
+
* capability, a 404 from the pre-merge describe really means absent). A public
|
|
8
|
+
* collection additionally gets a collection-level world-read grant
|
|
9
|
+
* (`setPublic`), which is what makes a resource URL in it resolve for anyone.
|
|
10
|
+
* Runs full-tier -- the client invokes its own root capability.
|
|
11
11
|
*
|
|
12
12
|
* @param options {object}
|
|
13
13
|
* @param options.was {WasClient}
|
package/dist/sync/types.d.ts
CHANGED
|
@@ -33,9 +33,9 @@ export type SyncCheckpoint = ChangesCheckpoint;
|
|
|
33
33
|
*/
|
|
34
34
|
export type WireDoc = ChangeDocument;
|
|
35
35
|
/**
|
|
36
|
-
* One page of the `changes` feed -- the return shape of {@link
|
|
37
|
-
* (the shared `ChangesPage`): the page's `documents` and its
|
|
38
|
-
* `checkpoint`, or `checkpoint: null` for an empty (no-change) page.
|
|
36
|
+
* One page of the `changes` feed -- the return shape of {@link
|
|
37
|
+
* WasSyncPort.query} (the shared `ChangesPage`): the page's `documents` and its
|
|
38
|
+
* resume `checkpoint`, or `checkpoint: null` for an empty (no-change) page.
|
|
39
39
|
*/
|
|
40
40
|
export type SyncPage = ChangesPage;
|
|
41
41
|
/**
|
|
@@ -135,7 +135,7 @@ export interface WasSyncPort {
|
|
|
135
135
|
* cipher, and a multi-recipient (key-epoch) EDV cipher:
|
|
136
136
|
*
|
|
137
137
|
* - `encrypt` may surface the `epoch` id a multi-recipient write encrypted
|
|
138
|
-
* under (the
|
|
138
|
+
* under (the descriptor's `currentEpoch`); absent on a single-key or plaintext
|
|
139
139
|
* cipher.
|
|
140
140
|
* - `encryptUpdate` is optional -- present only for a mutable, random-id
|
|
141
141
|
* collection that re-encrypts a head document in place under its existing id
|
package/dist/types.d.ts
CHANGED
|
@@ -69,16 +69,16 @@ export interface AddResult {
|
|
|
69
69
|
}
|
|
70
70
|
/**
|
|
71
71
|
* A per-handle client-side encryption override -- the escape hatch / bootstrap
|
|
72
|
-
* path that takes precedence over the Collection's declared `encryption`
|
|
73
|
-
* AND skips the
|
|
72
|
+
* path that takes precedence over the Collection's declared `encryption`
|
|
73
|
+
* descriptor AND skips the descriptor-discovery round-trip:
|
|
74
74
|
*
|
|
75
75
|
* - `{ scheme }` -- treat the collection as encrypted under `scheme`, pulling
|
|
76
76
|
* keys from the client's keystore. Use right after `createCollection` (before
|
|
77
|
-
* the
|
|
77
|
+
* the descriptor is readable), or to avoid the `describe()` round-trip.
|
|
78
78
|
* - `{ scheme, keys }` -- additionally supply the key material inline (opaque to
|
|
79
79
|
* core; the encryption provider interprets it per `scheme`) instead of the
|
|
80
80
|
* keystore.
|
|
81
|
-
* - `'plaintext'` -- force plaintext even if a
|
|
81
|
+
* - `'plaintext'` -- force plaintext even if a descriptor / keystore would encrypt.
|
|
82
82
|
*
|
|
83
83
|
* The non-`'plaintext'` forms require the `WasClient` to be constructed with an
|
|
84
84
|
* `encryption` provider (which turns a scheme + keys into a codec).
|
|
@@ -96,7 +96,7 @@ export interface HandleOptions {
|
|
|
96
96
|
capability?: IZcap;
|
|
97
97
|
/**
|
|
98
98
|
* Per-handle client-side encryption override (see {@link EncryptionOverride}).
|
|
99
|
-
* Omit to let the Collection's declared `encryption`
|
|
99
|
+
* Omit to let the Collection's declared `encryption` descriptor decide.
|
|
100
100
|
*/
|
|
101
101
|
encryption?: EncryptionOverride;
|
|
102
102
|
}
|
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.
|
|
4
|
+
"version": "0.23.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"build": "pnpm run clear && tsc",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"@interop/ezcap": "^7.4.1",
|
|
55
55
|
"@interop/http-client": "^1.0.4",
|
|
56
56
|
"@interop/minimal-cipher": "^7.8.0",
|
|
57
|
-
"@interop/storage-core": "^0.3.
|
|
57
|
+
"@interop/storage-core": "^0.3.12",
|
|
58
58
|
"@interop/x25519-key-agreement-key": "^5.2.1",
|
|
59
59
|
"@noble/hashes": "^2.2.0",
|
|
60
60
|
"@scure/base": "^2.2.0",
|
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Copyright (c) 2026 Interop Alliance. All rights reserved.
|
|
3
|
-
*/
|
|
4
|
-
/**
|
|
5
|
-
* The marker-store seam: where a `CollectionEncryption` marker lives and how it
|
|
6
|
-
* is compare-and-swapped. The recipient primitives (`initRecipients` /
|
|
7
|
-
* `addRecipient` / `removeRecipient`) mutate a marker only through this port,
|
|
8
|
-
* so the same key-epoch machinery manages a Collection's own `encryption`
|
|
9
|
-
* marker (the classic host) or a marker hosted as a plain JSON Resource (e.g. a
|
|
10
|
-
* per-user-key roster in a private collection).
|
|
11
|
-
*
|
|
12
|
-
* Two adapters:
|
|
13
|
-
*
|
|
14
|
-
* - {@link collectionMarkerStore} -- the Collection Description's `encryption`
|
|
15
|
-
* member, read with `describeWithEtag` and written back with
|
|
16
|
-
* `replaceDescription` + `If-Match`. The server enforces the marker
|
|
17
|
-
* invariants (append-only epochs, monotone `currentEpoch`, non-decreasing
|
|
18
|
-
* `version`) on this path.
|
|
19
|
-
* - {@link resourceMarkerStore} -- a marker stored verbatim as a JSON Resource.
|
|
20
|
-
* The server treats the resource as opaque content and enforces NO marker
|
|
21
|
-
* invariants there; integrity rests on the client-side `epochsMac` (verified
|
|
22
|
-
* by writers before encrypting) plus client-side epoch pinning. Both the
|
|
23
|
-
* compare-and-swap and the create-if-absent guard ride the backend's
|
|
24
|
-
* `conditional-writes` feature. The hosting collection must be plaintext: on
|
|
25
|
-
* an encrypted collection the EDV codec computes the write preconditions
|
|
26
|
-
* itself and the store's `ifMatch` would not be honored.
|
|
27
|
-
*/
|
|
28
|
-
import type { Collection } from '../Collection.js';
|
|
29
|
-
import type { Resource } from '../Resource.js';
|
|
30
|
-
import type { CollectionEncryption } from '../types.js';
|
|
31
|
-
/**
|
|
32
|
-
* Where a `CollectionEncryption` marker lives: a read-with-validator plus a
|
|
33
|
-
* compare-and-swap write, the two operations the recipient primitives' CAS
|
|
34
|
-
* loop needs. Implementations host the marker anywhere a versioned JSON value
|
|
35
|
-
* can live; the two shipped adapters are {@link collectionMarkerStore} and
|
|
36
|
-
* {@link resourceMarkerStore}.
|
|
37
|
-
*/
|
|
38
|
-
export interface MarkerStore {
|
|
39
|
-
/**
|
|
40
|
-
* Reads the current marker together with the opaque `etag` validator the
|
|
41
|
-
* next {@link replace} must be compare-and-swapped against. Resolves `null`
|
|
42
|
-
* when no marker exists yet AND this store can create one (the resource
|
|
43
|
-
* adapter before the first `initRecipients`); a store whose host must
|
|
44
|
-
* already exist (the description adapter) throws instead of resolving
|
|
45
|
-
* `null`. Throws when the hosted value is not an `edv`-scheme marker.
|
|
46
|
-
*
|
|
47
|
-
* @returns {Promise<{ marker: CollectionEncryption; etag?: string } | null>}
|
|
48
|
-
*/
|
|
49
|
-
read(): Promise<{
|
|
50
|
-
marker: CollectionEncryption;
|
|
51
|
-
etag?: string;
|
|
52
|
-
} | null>;
|
|
53
|
-
/**
|
|
54
|
-
* Replaces the marker, compare-and-swapped against `ifMatch` (the validator
|
|
55
|
-
* from {@link read}); a stale validator throws `PreconditionFailedError`
|
|
56
|
-
* (412). Must follow a {@link read} on the same store instance -- an adapter
|
|
57
|
-
* may forward sibling state observed by its most recent read (the
|
|
58
|
-
* description adapter forwards the description's `name` / `backend`).
|
|
59
|
-
*
|
|
60
|
-
* @param marker {CollectionEncryption}
|
|
61
|
-
* @param options {object}
|
|
62
|
-
* @param [options.ifMatch] {string} the validator from the prior read;
|
|
63
|
-
* absent against a host that does not version its writes
|
|
64
|
-
* @returns {Promise<void>}
|
|
65
|
-
*/
|
|
66
|
-
replace(marker: CollectionEncryption, options: {
|
|
67
|
-
ifMatch?: string;
|
|
68
|
-
}): Promise<void>;
|
|
69
|
-
/**
|
|
70
|
-
* Creates the FIRST marker where {@link read} resolved `null`, guarded
|
|
71
|
-
* create-if-absent (`If-None-Match: *`); throws `PreconditionFailedError`
|
|
72
|
-
* (412) when a concurrent writer created one first. Absent on stores whose
|
|
73
|
-
* host always exists (the description adapter).
|
|
74
|
-
*
|
|
75
|
-
* @param marker {CollectionEncryption}
|
|
76
|
-
* @returns {Promise<void>}
|
|
77
|
-
*/
|
|
78
|
-
create?(marker: CollectionEncryption): Promise<void>;
|
|
79
|
-
}
|
|
80
|
-
/**
|
|
81
|
-
* The Collection Description adapter: the marker is the Description's
|
|
82
|
-
* `encryption` member. Read fails closed when the Description is unreadable
|
|
83
|
-
* (WAS masks unauthorized reads as 404) or the collection is not declared
|
|
84
|
-
* encrypted with the `edv` scheme; the CAS write forwards the description's
|
|
85
|
-
* sibling fields (`name` / `backend`) observed by the most recent read, so
|
|
86
|
-
* the replace-semantics PUT does not drop them. No `create`: a Collection
|
|
87
|
-
* Description always exists, so a first marker is declared via
|
|
88
|
-
* `collection.configure({ encryption })`, never through this store.
|
|
89
|
-
*
|
|
90
|
-
* @param options {object}
|
|
91
|
-
* @param options.collection {Collection}
|
|
92
|
-
* @returns {MarkerStore}
|
|
93
|
-
*/
|
|
94
|
-
export declare function collectionMarkerStore({ collection }: {
|
|
95
|
-
collection: Collection;
|
|
96
|
-
}): MarkerStore;
|
|
97
|
-
/**
|
|
98
|
-
* The plain-JSON-Resource adapter: the marker is the resource's entire
|
|
99
|
-
* content, stored verbatim. Read resolves `null` when the resource is absent
|
|
100
|
-
* (the pre-`initRecipients` state -- `create` then writes the first marker
|
|
101
|
-
* with `If-None-Match: *`), and throws when the resource holds something other
|
|
102
|
-
* than an `edv`-scheme marker object.
|
|
103
|
-
*
|
|
104
|
-
* The server enforces no marker invariants on a resource (unlike a Collection
|
|
105
|
-
* Description): rollback/tamper detection rests on the marker's `epochsMac`
|
|
106
|
-
* and client-side epoch pinning, and the CAS/create guards ride the backend's
|
|
107
|
-
* `conditional-writes` feature. Host the resource in a plaintext collection --
|
|
108
|
-
* on an encrypted collection the EDV codec computes the write preconditions
|
|
109
|
-
* itself, so this store's `ifMatch` would not be honored.
|
|
110
|
-
*
|
|
111
|
-
* @param options {object}
|
|
112
|
-
* @param options.resource {Resource}
|
|
113
|
-
* @returns {MarkerStore}
|
|
114
|
-
*/
|
|
115
|
-
export declare function resourceMarkerStore({ resource }: {
|
|
116
|
-
resource: Resource;
|
|
117
|
-
}): MarkerStore;
|
|
118
|
-
//# sourceMappingURL=markerStore.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"markerStore.d.ts","sourceRoot":"","sources":["../../src/edv/markerStore.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAClD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAG9C,OAAO,KAAK,EAEV,oBAAoB,EAErB,MAAM,aAAa,CAAA;AAEpB;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IAC1B;;;;;;;;;OASG;IACH,IAAI,IAAI,OAAO,CAAC;QAAE,MAAM,EAAE,oBAAoB,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC,CAAA;IAEvE;;;;;;;;;;;;OAYG;IACH,OAAO,CACL,MAAM,EAAE,oBAAoB,EAC5B,OAAO,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAC5B,OAAO,CAAC,IAAI,CAAC,CAAA;IAEhB;;;;;;;;OAQG;IACH,MAAM,CAAC,CAAC,MAAM,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACrD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,UAAU,EACX,EAAE;IACD,UAAU,EAAE,UAAU,CAAA;CACvB,GAAG,WAAW,CAoCd;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,QAAQ,EACT,EAAE;IACD,QAAQ,EAAE,QAAQ,CAAA;CACnB,GAAG,WAAW,CAgCd"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"markerStore.js","sourceRoot":"","sources":["../../src/edv/markerStore.ts"],"names":[],"mappings":"AA6BA,OAAO,EAAE,0BAA0B,EAAE,MAAM,yBAAyB,CAAA;AACpE,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAyD9C;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,qBAAqB,CAAC,EACpC,UAAU,EAGX;IACC,6EAA6E;IAC7E,4EAA4E;IAC5E,6EAA6E;IAC7E,yEAAyE;IACzE,IAAI,SAA4C,CAAA;IAChD,OAAO;QACL,KAAK,CAAC,IAAI;YACR,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,gBAAgB,EAAE,CAAA;YACnD,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;gBACrB,MAAM,0BAA0B,CAAC;oBAC/B,SAAS,EAAE,mBAAmB;oBAC9B,MAAM,EAAE,4DAA4D;iBACrE,CAAC,CAAA;YACJ,CAAC;YACD,MAAM,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,UAAU,CAAA;YAC7C,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;gBACvC,MAAM,IAAI,eAAe,CACvB,4DAA4D;oBAC1D,kCAAkC,CACrC,CAAA;YACH,CAAC;YACD,SAAS,GAAG,OAAO,CAAC,WAAW,CAAA;YAC/B,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAA;QACvC,CAAC;QACD,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE;YAC/B,MAAM,UAAU,CAAC,kBAAkB,CACjC;gBACE,IAAI,EAAE,SAAS,EAAE,IAAI;gBACrB,OAAO,EAAE,SAAS,EAAE,OAAO;gBAC3B,UAAU,EAAE,MAAM;aACnB,EACD,EAAE,OAAO,EAAE,CACZ,CAAA;QACH,CAAC;KACF,CAAA;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,mBAAmB,CAAC,EAClC,QAAQ,EAGT;IACC,OAAO;QACL,KAAK,CAAC,IAAI;YACR,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAA;YAC5C,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;gBACrB,OAAO,IAAI,CAAA;YACb,CAAC;YACD,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAA;YAC3B,IACE,MAAM,KAAK,IAAI;gBACf,OAAO,MAAM,KAAK,QAAQ;gBAC1B,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;gBACrB,MAAM,YAAY,IAAI;gBACrB,MAA+B,CAAC,MAAM,KAAK,KAAK,EACjD,CAAC;gBACD,MAAM,IAAI,eAAe,CACvB,2CAA2C,QAAQ,CAAC,EAAE,aAAa;oBACjE,2DAA2D,CAC9D,CAAA;YACH,CAAC;YACD,OAAO;gBACL,MAAM,EAAE,MAAyC;gBACjD,IAAI,EAAE,OAAO,CAAC,IAAI;aACnB,CAAA;QACH,CAAC;QACD,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE;YAC/B,MAAM,QAAQ,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,EAAE,OAAO,EAAE,CAAC,CAAA;QACvD,CAAC;QACD,KAAK,CAAC,MAAM,CAAC,MAAM;YACjB,MAAM,QAAQ,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAA;QACjE,CAAC;KACF,CAAA;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,YAAY,CAAC,MAA4B;IAChD,OAAO,MAA+B,CAAA;AACxC,CAAC"}
|