@metreeca/keep 0.10.0 → 0.11.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 +49 -42
- package/dist/clients/batching.core.d.ts +30 -10
- package/dist/clients/batching.core.d.ts.map +1 -1
- package/dist/clients/batching.core.js +74 -29
- package/dist/clients/batching.core.js.map +1 -1
- package/dist/clients/batching.d.ts +84 -89
- package/dist/clients/batching.d.ts.map +1 -1
- package/dist/clients/batching.js +36 -32
- package/dist/clients/batching.js.map +1 -1
- package/dist/clients/validating.d.ts +25 -22
- package/dist/clients/validating.d.ts.map +1 -1
- package/dist/clients/validating.js +70 -48
- package/dist/clients/validating.js.map +1 -1
- package/dist/index.d.ts +285 -179
- package/dist/index.d.ts.map +1 -1
- package/dist/stores/caching.d.ts +17 -20
- package/dist/stores/caching.d.ts.map +1 -1
- package/dist/stores/caching.js +60 -51
- package/dist/stores/caching.js.map +1 -1
- package/dist/stores/managing.d.ts +44 -42
- package/dist/stores/managing.d.ts.map +1 -1
- package/dist/stores/managing.js +58 -70
- package/dist/stores/managing.js.map +1 -1
- package/package.json +6 -6
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAyMA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/stores/caching.d.ts
CHANGED
|
@@ -1,36 +1,33 @@
|
|
|
1
|
-
import type { Reference } from "@metreeca/qest/
|
|
1
|
+
import type { Reference } from "@metreeca/qest/state";
|
|
2
2
|
import type { Store } from "../index.js";
|
|
3
3
|
/**
|
|
4
4
|
* Creates a caching store backed by a delegate.
|
|
5
5
|
*
|
|
6
|
-
* Serves repeated retrievals from an in-memory cache, sparing the delegate a round-trip whenever a prior
|
|
7
|
-
*
|
|
6
|
+
* Serves repeated retrievals from an in-memory cache, sparing the delegate a round-trip whenever a prior result can
|
|
7
|
+
* be reused. This cuts latency and backend load for read-heavy workloads, while writes and eviction keep cached
|
|
8
8
|
* results coherent and bounded.
|
|
9
9
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* the set of requests a single cached result can serve.
|
|
10
|
+
* Results are cached by `entry`, `model`, and the `locale` and `limit` of the {@link Store.lookup lookup} retrieval scope.
|
|
11
|
+
* Templates differing only in member or element order share a cached result.
|
|
13
12
|
*
|
|
14
13
|
* > [!IMPORTANT]
|
|
15
|
-
* > `shape` is
|
|
16
|
-
* > `
|
|
17
|
-
* > returned payload.
|
|
14
|
+
* > `shape` is not part of the cache key. A retrieval result MUST depend only on `entry`, `model`, `locale` and
|
|
15
|
+
* > `limit`, with `shape` supplying structural metadata that does not affect the returned payload.
|
|
18
16
|
*
|
|
19
17
|
* > [!IMPORTANT]
|
|
20
|
-
* > `
|
|
21
|
-
* > the model, the locale priority list is order-significant
|
|
22
|
-
* >
|
|
23
|
-
* > distinct from any explicit list.
|
|
18
|
+
* > The scope `locale` is part of the cache key, because it selects which localised content a retrieval returns.
|
|
19
|
+
* > Unlike the model, the locale priority list is order-significant: `["en", "it"]` and `["it", "en"]` are cached
|
|
20
|
+
* > separately. An omitted and an empty locale list share a single cached result, distinct from any explicit list.
|
|
24
21
|
*
|
|
25
22
|
* > [!IMPORTANT]
|
|
26
|
-
* > `
|
|
27
|
-
* >
|
|
28
|
-
* > only accept or reject a model, never
|
|
23
|
+
* > The scope `limit` is part of the cache key, because it caps the page size of each collection and so changes the
|
|
24
|
+
* > returned payload. An omitted and a `0` limit share a single cached result. The scope `plain` and `depth` are not
|
|
25
|
+
* > part of the key: they only accept or reject a model, and never alter a successful payload.
|
|
29
26
|
*
|
|
30
27
|
* The cache offers three observable guarantees:
|
|
31
28
|
*
|
|
32
29
|
* - **coalescing** — concurrent retrievals for the same key resolve from a single delegate fetch, and a failed
|
|
33
|
-
* retrieval is never cached, so a later retrieval re-fetches;
|
|
30
|
+
* retrieval or one finding no resource is never cached, so a later retrieval re-fetches;
|
|
34
31
|
* - **read-after-write coherence** — a retrieval never returns content staler than the latest write made through this
|
|
35
32
|
* store: {@link Store.create create}, {@link Store.update update}, {@link Store.delete delete},
|
|
36
33
|
* {@link Store.insert insert} and {@link Store.remove remove} invalidate matching entries, and a
|
|
@@ -80,9 +77,9 @@ export declare function createCachingStore(store: Store, { size, ttl, match }?:
|
|
|
80
77
|
/**
|
|
81
78
|
* Predicate deciding which cached records an invalidation event discards.
|
|
82
79
|
*
|
|
83
|
-
* Invoked
|
|
84
|
-
*
|
|
85
|
-
*
|
|
80
|
+
* Invoked for writes made through the wrapper and for mutation events signalled by the delegate. It receives the
|
|
81
|
+
* identifier of the mutated resource and the identifier of each cached record, and returns `true` if the record
|
|
82
|
+
* is to be evicted.
|
|
86
83
|
*
|
|
87
84
|
* @param entry - Identifier of the mutated resource
|
|
88
85
|
* @param cache - Identifier associated with a cached record
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"caching.d.ts","sourceRoot":"","sources":["../../src/stores/caching.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"caching.d.ts","sourceRoot":"","sources":["../../src/stores/caching.ts"],"names":[],"mappings":"AA6BA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAGzC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,KAAK,EAAE,EAEhD,IAAQ,EACR,GAAO,EACP,KAAkB,EAElB,GAAE;IAEF;;;;;;OAMG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAEvB;;;;;;;;OAQG;IACH,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAEtB;;;;;;;;;;;;;OAaG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,KAAK,OAAO,CAAC;CAE5D,GAAG,KAAK,CA0Vb"}
|
package/dist/stores/caching.js
CHANGED
|
@@ -16,46 +16,42 @@
|
|
|
16
16
|
/**
|
|
17
17
|
* Caching store wrapper.
|
|
18
18
|
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* operations and the delegate's mutation events.
|
|
19
|
+
* Speeds up read-heavy workloads by serving repeated retrievals from an in-memory cache. The cache stays bounded
|
|
20
|
+
* by size and age, shares concurrent identical retrievals, and stays coherent with writes made through the store, by
|
|
21
|
+
* other clients, or signalled by the backend.
|
|
23
22
|
*
|
|
24
23
|
* @module
|
|
25
24
|
*/
|
|
26
25
|
import { isArray, isObject } from "@metreeca/core";
|
|
27
|
-
import { immutable } from "@metreeca/core/
|
|
26
|
+
import { immutable } from "@metreeca/core/values";
|
|
28
27
|
/**
|
|
29
28
|
* Creates a caching store backed by a delegate.
|
|
30
29
|
*
|
|
31
|
-
* Serves repeated retrievals from an in-memory cache, sparing the delegate a round-trip whenever a prior
|
|
32
|
-
*
|
|
30
|
+
* Serves repeated retrievals from an in-memory cache, sparing the delegate a round-trip whenever a prior result can
|
|
31
|
+
* be reused. This cuts latency and backend load for read-heavy workloads, while writes and eviction keep cached
|
|
33
32
|
* results coherent and bounded.
|
|
34
33
|
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
* the set of requests a single cached result can serve.
|
|
34
|
+
* Results are cached by `entry`, `model`, and the `locale` and `limit` of the {@link Store.lookup lookup} retrieval scope.
|
|
35
|
+
* Templates differing only in member or element order share a cached result.
|
|
38
36
|
*
|
|
39
37
|
* > [!IMPORTANT]
|
|
40
|
-
* > `shape` is
|
|
41
|
-
* > `
|
|
42
|
-
* > returned payload.
|
|
38
|
+
* > `shape` is not part of the cache key. A retrieval result MUST depend only on `entry`, `model`, `locale` and
|
|
39
|
+
* > `limit`, with `shape` supplying structural metadata that does not affect the returned payload.
|
|
43
40
|
*
|
|
44
41
|
* > [!IMPORTANT]
|
|
45
|
-
* > `
|
|
46
|
-
* > the model, the locale priority list is order-significant
|
|
47
|
-
* >
|
|
48
|
-
* > distinct from any explicit list.
|
|
42
|
+
* > The scope `locale` is part of the cache key, because it selects which localised content a retrieval returns.
|
|
43
|
+
* > Unlike the model, the locale priority list is order-significant: `["en", "it"]` and `["it", "en"]` are cached
|
|
44
|
+
* > separately. An omitted and an empty locale list share a single cached result, distinct from any explicit list.
|
|
49
45
|
*
|
|
50
46
|
* > [!IMPORTANT]
|
|
51
|
-
* > `
|
|
52
|
-
* >
|
|
53
|
-
* > only accept or reject a model, never
|
|
47
|
+
* > The scope `limit` is part of the cache key, because it caps the page size of each collection and so changes the
|
|
48
|
+
* > returned payload. An omitted and a `0` limit share a single cached result. The scope `plain` and `depth` are not
|
|
49
|
+
* > part of the key: they only accept or reject a model, and never alter a successful payload.
|
|
54
50
|
*
|
|
55
51
|
* The cache offers three observable guarantees:
|
|
56
52
|
*
|
|
57
53
|
* - **coalescing** — concurrent retrievals for the same key resolve from a single delegate fetch, and a failed
|
|
58
|
-
* retrieval is never cached, so a later retrieval re-fetches;
|
|
54
|
+
* retrieval or one finding no resource is never cached, so a later retrieval re-fetches;
|
|
59
55
|
* - **read-after-write coherence** — a retrieval never returns content staler than the latest write made through this
|
|
60
56
|
* store: {@link Store.create create}, {@link Store.update update}, {@link Store.delete delete},
|
|
61
57
|
* {@link Store.insert insert} and {@link Store.remove remove} invalidate matching entries, and a
|
|
@@ -88,8 +84,8 @@ export function createCachingStore(store, { size = 0, ttl = 0, match = () => tru
|
|
|
88
84
|
// moving it to the tail, so `cache.keys().next().value` is always the least-recently-used key.
|
|
89
85
|
const cache = new Map();
|
|
90
86
|
// Tracks entries with at least one in-flight wrapper-initiated write. Reads of these entries bypass the
|
|
91
|
-
// cache entirely
|
|
92
|
-
// between a lookup resolving with a pre-commit value and the reactive observer firing on commit, during
|
|
87
|
+
// cache entirely: they still query the delegate, but their result is not stored. This closes the window
|
|
88
|
+
// between a lookup call resolving with a pre-commit value and the reactive observer firing on commit, during
|
|
93
89
|
// which the cache would otherwise hold a stale-but-fresh-looking record.
|
|
94
90
|
const writing = new Map();
|
|
95
91
|
// Reactive invalidation: subscribe to the delegate's mutation events and drop matching records on commit.
|
|
@@ -103,8 +99,8 @@ export function createCachingStore(store, { size = 0, ttl = 0, match = () => tru
|
|
|
103
99
|
lookup({ entry, shape, model }, opts) {
|
|
104
100
|
return memoise(entry, model, opts, () => store.lookup({ entry, shape, model }, opts));
|
|
105
101
|
},
|
|
106
|
-
create({ entry, shape, state }) {
|
|
107
|
-
return write(entry, () => store.create({ entry, shape, state }));
|
|
102
|
+
create({ entry, shape, model, state }) {
|
|
103
|
+
return write(entry, () => store.create({ entry, shape, model, state }));
|
|
108
104
|
},
|
|
109
105
|
update({ entry, shape, state }) {
|
|
110
106
|
return write(entry, () => store.update({ entry, shape, state }));
|
|
@@ -112,8 +108,8 @@ export function createCachingStore(store, { size = 0, ttl = 0, match = () => tru
|
|
|
112
108
|
delete({ entry, shape }) {
|
|
113
109
|
return write(entry, () => store.delete({ entry, shape }));
|
|
114
110
|
},
|
|
115
|
-
insert({ entry, shape, state }
|
|
116
|
-
return write(entry, () => store.insert({ entry, shape, state }
|
|
111
|
+
insert({ entry, shape, state }) {
|
|
112
|
+
return write(entry, () => store.insert({ entry, shape, state }));
|
|
117
113
|
},
|
|
118
114
|
remove({ entry, shape }) {
|
|
119
115
|
return write(entry, () => store.remove({ entry, shape }));
|
|
@@ -139,57 +135,70 @@ export function createCachingStore(store, { size = 0, ttl = 0, match = () => tru
|
|
|
139
135
|
* - **fresh hit** — returns the memoised promise and re-inserts the record to bump its LRU position;
|
|
140
136
|
* - **miss / TTL-expired** — runs `miss()`, stores the pending promise under the canonicalised key so
|
|
141
137
|
* concurrent callers share the in-flight request, and enforces TTL/size bounds via {@link purge}; a
|
|
142
|
-
*
|
|
138
|
+
* fetch resolving to an absent resource or rejecting evicts its record only if an intervening invalidation
|
|
139
|
+
* has not already replaced it.
|
|
143
140
|
*
|
|
144
|
-
* @
|
|
145
|
-
*
|
|
146
|
-
* @param
|
|
141
|
+
* @typeParam V - The retrieved payload, opaque to the cache
|
|
142
|
+
*
|
|
143
|
+
* @param entry - Resource identifier; paired with the canonicalised model and varying scope members to form the
|
|
144
|
+
* cache key
|
|
145
|
+
* @param model - Retrieval model, canonicalised so that equivalent models in different orderings share a key
|
|
146
|
+
* @param vary - Retrieval scope members whose values vary the returned payload, folded into the key: `locale`
|
|
147
147
|
* order-significantly (an omitted or empty list collapsing to a single key) and `limit` because it caps each
|
|
148
|
-
*
|
|
148
|
+
* collection's `#` pagination bound (an omitted or `0` unbounded value collapsing to a single key)
|
|
149
149
|
* @param miss - Fetcher invoked on cache miss, on TTL expiration, or while the entry has an in-flight write
|
|
150
150
|
*
|
|
151
151
|
* @returns The memoised, freshly-fetched, or bypass-fetched promise
|
|
152
152
|
*/
|
|
153
153
|
function memoise(entry, model, vary = {}, miss) {
|
|
154
154
|
// Bypass the cache while a write to this entry is in flight: still query the delegate so the caller
|
|
155
|
-
// gets a value, but do not store the result
|
|
155
|
+
// gets a value, but do not store the result: it is liable to be the pre-commit snapshot that the
|
|
156
156
|
// reactive observer would invalidate moments later
|
|
157
157
|
if (writing.has(entry)) {
|
|
158
158
|
return miss();
|
|
159
159
|
}
|
|
160
160
|
else {
|
|
161
|
-
// Cache key layout: `<entry>\x00<canonical-model>\x00<locale>\x00<limit>`. `canonical` walks the
|
|
162
|
-
// bottom-up, sorting object keys and (already-canonical) array elements, so
|
|
163
|
-
// ordering share a key. The locale segment is serialised verbatim (order preserved, since the priority
|
|
161
|
+
// Cache key layout: `<entry>\x00<canonical-model>\x00<locale>\x00<limit>`. `canonical` walks the
|
|
162
|
+
// model bottom-up, sorting object keys and (already-canonical) array elements, so models differing only
|
|
163
|
+
// in ordering share a key. The locale segment is serialised verbatim (order preserved, since the priority
|
|
164
164
|
// list is order-significant) with omitted and empty lists collapsing to `[]`. The limit segment is
|
|
165
|
-
// keyed because it caps each
|
|
166
|
-
// unbounded) collapsing to `0`. `\x00` is safe as a separator
|
|
165
|
+
// keyed because it caps each collection's `#` and so changes the payload, with omitted and `0` (both
|
|
166
|
+
// unbounded) collapsing to `0`. `\x00` is safe as a separator: IRIs cannot contain it and JSON always
|
|
167
167
|
// escapes it inside string payloads.
|
|
168
|
-
const key =
|
|
168
|
+
const key = [entry, canonical(model), JSON.stringify(vary.locale ?? []), vary.limit ?? 0].join("\x00");
|
|
169
169
|
const cached = cache.get(key);
|
|
170
170
|
if (cached && !expired(cached.created)) {
|
|
171
171
|
// hit: re-insert to move the entry to the tail of the Map's iteration order (the LRU position),
|
|
172
|
-
// and return the memoised promise;
|
|
173
|
-
//
|
|
172
|
+
// and return the memoised promise; ;(cast) the type-erased `Promise<unknown>` storage lets records
|
|
173
|
+
// with different payload types share one Map
|
|
174
174
|
cache.delete(key);
|
|
175
175
|
cache.set(key, cached);
|
|
176
176
|
return cached.value;
|
|
177
177
|
}
|
|
178
178
|
else {
|
|
179
179
|
// miss (or TTL-expired): drop any stale record, run the fetcher, and memoise the pending promise
|
|
180
|
-
// under the same key so concurrent callers share the in-flight request;
|
|
181
|
-
//
|
|
180
|
+
// under the same key so concurrent callers share the in-flight request; an absent resource or a
|
|
181
|
+
// failure evicts its own record once settled, so neither a missing resource nor a transient error
|
|
182
|
+
// is retained
|
|
182
183
|
if (cached) {
|
|
183
184
|
cache.delete(key);
|
|
184
185
|
}
|
|
185
|
-
const value = miss().
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
if (cache.get(key)?.value === value) {
|
|
189
|
-
cache.delete(key);
|
|
186
|
+
const value = miss().then(resource => {
|
|
187
|
+
if (resource === undefined) {
|
|
188
|
+
evict();
|
|
190
189
|
}
|
|
190
|
+
return resource;
|
|
191
|
+
}, error => {
|
|
192
|
+
evict();
|
|
191
193
|
throw error;
|
|
192
194
|
});
|
|
195
|
+
// identity-check: only evict if this promise is still the cached one, avoiding dropping a newer
|
|
196
|
+
// record installed after an intervening invalidate
|
|
197
|
+
function evict() {
|
|
198
|
+
if (cache.get(key)?.value === value) {
|
|
199
|
+
cache.delete(key);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
193
202
|
cache.set(key, {
|
|
194
203
|
entry,
|
|
195
204
|
value,
|
|
@@ -203,7 +212,7 @@ export function createCachingStore(store, { size = 0, ttl = 0, match = () => tru
|
|
|
203
212
|
/**
|
|
204
213
|
* Serialises a value to a canonical JSON-like string.
|
|
205
214
|
*
|
|
206
|
-
* Children are canonicalised first, then sorted by their already-canonical string form
|
|
215
|
+
* Children are canonicalised first, then sorted by their already-canonical string form, so arrays of
|
|
207
216
|
* objects are ordered by structural content rather than by the `"[object Object]"` placeholder that
|
|
208
217
|
* `Array.prototype.sort` would otherwise impose. The output collapses values differing only in property
|
|
209
218
|
* or element order to the same string.
|
|
@@ -288,7 +297,7 @@ export function createCachingStore(store, { size = 0, ttl = 0, match = () => tru
|
|
|
288
297
|
* Runs two sweeps: first, when `ttl > 0`, drops every record older than `ttl` milliseconds; second, when
|
|
289
298
|
* `size > 0` and the cache is overfull, drops the head slice of the Map (least-recently-used first) in
|
|
290
299
|
* a single batch sized to the exact overflow. Invoked after every miss so expired siblings and overfill
|
|
291
|
-
* are cleaned up incrementally
|
|
300
|
+
* are cleaned up incrementally, as the cache has no background sweeper.
|
|
292
301
|
*/
|
|
293
302
|
function purge() {
|
|
294
303
|
if (ttl > 0) {
|
|
@@ -300,7 +309,7 @@ export function createCachingStore(store, { size = 0, ttl = 0, match = () => tru
|
|
|
300
309
|
}
|
|
301
310
|
}
|
|
302
311
|
// LRU sweep: when over the size bound, take the head slice of Map keys (insertion order = LRU first)
|
|
303
|
-
// and drop them
|
|
312
|
+
// and drop them: `cache.size - size` is the exact overflow, so no loop condition needs re-checking
|
|
304
313
|
if (size > 0 && cache.size > size) {
|
|
305
314
|
Array.from(cache.keys())
|
|
306
315
|
.slice(0, cache.size - size)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"caching.js","sourceRoot":"","sources":["../../src/stores/caching.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH
|
|
1
|
+
{"version":3,"file":"caching.js","sourceRoot":"","sources":["../../src/stores/caching.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,55 +1,57 @@
|
|
|
1
|
-
import type { Store
|
|
1
|
+
import type { Store } from "../index.js";
|
|
2
2
|
/**
|
|
3
|
-
* Manages mutation events, transactional execution, and lifecycle for a
|
|
3
|
+
* Manages mutation events, transactional execution, and lifecycle for a connector's {@link StoreClient},
|
|
4
4
|
* exposing it as a full {@link Store}.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
6
|
+
* A connector can implement only the {@link StoreClient} data surface and still offer the full {@link Store}
|
|
7
|
+
* contract. The connector supplies its transaction primitive through `management.execute`, which hands the
|
|
8
|
+
* connector's {@link StoreClient} to every data call. The option is required, since only the connector knows what
|
|
9
|
+
* atomicity its backend can provide. Backend primitives supplied through `management` may also back `observe` or
|
|
10
|
+
* `close`, and the wrapper fills in whatever is missing.
|
|
9
11
|
*
|
|
10
|
-
* Each standalone mutation call and each {@link Store.execute execute} call
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* are caught and silently ignored so that one faulty observer cannot break delivery to others.
|
|
12
|
+
* Each standalone mutation call and each {@link Store.execute execute} call delivers a single filtered event to each
|
|
13
|
+
* matching {@link StoreObserver observer} once the call resolves. If the call rejects, its pending events are
|
|
14
|
+
* discarded and no observer is notified. Synchronous throws and asynchronous rejections from observers are caught and
|
|
15
|
+
* silently ignored, so one faulty observer cannot break delivery to others.
|
|
15
16
|
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* All errors — `RangeError`, {@link @metreeca/core!TraceError | TraceError},
|
|
20
|
-
* {@link @metreeca/http!Problem | Problem} —
|
|
21
|
-
* propagate as promise rejections per the unified {@link Store} error channel.
|
|
17
|
+
* All errors, including {@link !RangeError RangeError}, {@link @metreeca/core!TraceError | TraceError} and
|
|
18
|
+
* {@link @metreeca/http!Problem | Problem}, propagate as promise rejections, in line with the unified {@link Store}
|
|
19
|
+
* error channel.
|
|
22
20
|
*
|
|
23
21
|
* > [!IMPORTANT]
|
|
24
|
-
* > **Transaction Isolation** —
|
|
25
|
-
* >
|
|
26
|
-
* > the level is determined by that wrapper (typically a backend transaction primitive).
|
|
22
|
+
* > **Transaction Isolation** — Determined by the supplied `execute` option, typically through a backend
|
|
23
|
+
* > transaction primitive: the wrapper adds neither isolation nor atomicity of its own.
|
|
27
24
|
*
|
|
28
25
|
* > [!IMPORTANT]
|
|
29
26
|
* > **Mutation Events** — emits in-process observer events: each standalone mutation and each
|
|
30
27
|
* > {@link Store.execute execute} call delivers a single filtered batch to matching {@link StoreObserver observer}s
|
|
31
|
-
* > on resolve, and none on rejection.
|
|
32
|
-
* > `observe`
|
|
33
|
-
*
|
|
34
|
-
* @param
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
* @
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
28
|
+
* > on resolve, and none on rejection. Mutations made by other clients reach local observers only if a
|
|
29
|
+
* > backend-bridging `observe` option is supplied through `management`.
|
|
30
|
+
*
|
|
31
|
+
* @param management - {@link Store} management methods backed by the connector: `execute` is required, and the
|
|
32
|
+
* wrapper fills in whatever else is missing
|
|
33
|
+
* @param management.execute - Transaction wrapper applied to every standalone StoreClient call and to the body of
|
|
34
|
+
* each {@link Store.execute execute} call, typically a backend transaction primitive (for example,
|
|
35
|
+
* `graph.execute` for a SPARQL connector) responsible for atomic commit and rollback. A backend with no
|
|
36
|
+
* transaction primitive supplies a wrapper applying the task directly to its StoreClient, and declares on its
|
|
37
|
+
* factory that a failing task neither rolls back nor isolates its mutations. The option MUST call each task it
|
|
38
|
+
* receives with a `scope` StoreClient dedicated to that call, so per-call state, such as a freshly bound graph
|
|
39
|
+
* buffer, never leaks across concurrent invocations; every data call within the transaction is routed through
|
|
40
|
+
* `scope`. Calls made by a user task inside {@link Store.execute execute} do not open further transactions: they
|
|
41
|
+
* share the outer one. The option MUST convert synchronous throws from the task into promise rejections, to
|
|
42
|
+
* preserve the unified Store error channel: lookups are routed through it with no additional guard
|
|
43
|
+
* @param management.observe - Backend registration for storage-level events, such as mutations made by other clients
|
|
44
|
+
* sharing the backend. Each observer is registered both with this option and locally, and a single detach call
|
|
45
|
+
* releases both registrations. The resource filter always arrives as an array of references, or as `undefined`
|
|
46
|
+
* for an unfiltered registration, so the option never has to handle bare references or single-pass iterables.
|
|
47
|
+
* Absent by default
|
|
48
|
+
* @param management.close - Exposed as is on the returned store. Defaults to a resolved no-op
|
|
49
|
+
*
|
|
50
|
+
* @returns An immutable {@link Store} serving data calls through the supplied `management` opts
|
|
53
51
|
*/
|
|
54
|
-
export declare function createManagingStore(
|
|
52
|
+
export declare function createManagingStore({ observe, execute, close }: {
|
|
53
|
+
readonly observe?: Store["observe"];
|
|
54
|
+
readonly execute: Store["execute"];
|
|
55
|
+
readonly close?: Store["close"];
|
|
56
|
+
}): Store;
|
|
55
57
|
//# sourceMappingURL=managing.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"managing.d.ts","sourceRoot":"","sources":["../../src/stores/managing.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"managing.d.ts","sourceRoot":"","sources":["../../src/stores/managing.ts"],"names":[],"mappings":"AAiCA,OAAO,KAAK,EAAE,KAAK,EAA8B,MAAM,aAAa,CAAC;AAGrE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AACH,wBAAgB,mBAAmB,CAAC,EAEnC,OAAO,EACP,OAAO,EAEP,KAA+B,EAE/B,EAAE;IAEF,QAAQ,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,CAAA;IACnC,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC,CAAA;IAElC,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC,CAAA;CAE/B,GAAG,KAAK,CA2HR"}
|