@metreeca/keep 0.10.0 → 0.11.1

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 CHANGED
@@ -4,10 +4,10 @@
4
4
 
5
5
  Core model-driven storage API for the [@metreeca/keep](https://github.com/metreeca/keep) linked data storage framework.
6
6
 
7
- Defines the backend-agnostic `StoreClient` and `Store` interfaces for persisting and retrieving linked data resources as
8
- shape-validated states and query projections. Resource shapes are defined using
9
- [@metreeca/blue](https://github.com/metreeca/blue); resource states and retrieval templates follow the data and query
10
- models defined by [@metreeca/qest](https://github.com/metreeca/qest). Actual storage is delegated to backend
7
+ Provides one backend-agnostic API for persisting and retrieving linked data resources, validated against their models
8
+ and retrieved through client-defined templates and queries. Resource models are defined with
9
+ [@metreeca/blue](https://github.com/metreeca/blue), and resource states and retrieval templates follow the data and
10
+ query models of [@metreeca/qest](https://github.com/metreeca/qest). Actual storage is delegated to backend
11
11
  [connector packages](https://github.com/metreeca/keep#installation).
12
12
 
13
13
  # Installation
@@ -43,9 +43,11 @@ npm install @metreeca/keep
43
43
 
44
44
  [managing]: https://metreeca.github.io/keep/modules/_metreeca_keep.managing.html
45
45
 
46
- All store methods accept an `entry` that MUST be an absolute IRI without query string or fragment — non-conforming
47
- entries reject with `RangeError`. `model` and `state` are validated against the supplied shape; validation failures
48
- reject with a `TraceError`. Network, storage, and other processing errors reject with a structured `Problem`.
46
+ All store methods accept an `entry` that MUST be an absolute IRI without query string or fragment: non-conforming
47
+ entries reject with `RangeError`. `create` takes as `entry` the resource holding the collection, and as `model` a slice
48
+ naming the multi-valued property that holds it. An `id` stated in a `create` state MUST be nested under `entry`.
49
+ `model` and `state` are validated against the supplied shape, and validation failures reject with a `TraceError`.
50
+ Network, storage, and other processing errors reject with a structured `Problem`.
49
51
 
50
52
  ## Retrieving Resources
51
53
 
@@ -56,31 +58,31 @@ const product = await store.lookup({
56
58
  entry: "http://example.com/products/1",
57
59
  shape: ProductShape,
58
60
  model: {
59
- name: "",
60
- price: 0,
61
+ name: {},
62
+ price: {},
61
63
  vendor: {
62
- id: "",
63
- name: ""
64
+ id: {},
65
+ name: {}
64
66
  }
65
67
  }
66
68
  });
67
69
 
68
70
  // collection retrieval with filtering, ordering, and pagination
69
71
 
70
- const catalog = await store.lookup({
72
+ const catalogue = await store.lookup({
71
73
  entry: "http://example.com/products/",
72
- shape: ProductShape,
74
+ shape: CatalogueShape,
73
75
  model: {
74
- products: [{
75
- id: "",
76
- name: "",
77
- price: 0,
76
+ products: {
77
+ id: {},
78
+ name: {},
79
+ price: {},
78
80
  ">=price": 50, // price ≥ 50
79
81
  "~name": "widget", // name contains "widget"
80
82
  "^price": 1, // sort by price ascending
81
83
  "@": 0, // offset
82
84
  "#": 25 // limit
83
- }]
85
+ }
84
86
  }
85
87
  });
86
88
  ```
@@ -88,9 +90,10 @@ const catalog = await store.lookup({
88
90
  ## Creating and Updating Resources
89
91
 
90
92
  ```typescript
91
- await store.create({
92
- entry: "http://example.com/products/42", shape: ProductShape, state: {
93
- id: "http://example.com/products/42",
93
+ // creation within the collection holding the new resource, its identifier minted by the store unless stated
94
+
95
+ const product = await store.create({
96
+ entry: "http://example.com/products/", shape: CatalogueShape, model: { products: {} }, state: {
94
97
  name: "Widget",
95
98
  price: 29.99,
96
99
  vendor: "http://example.com/vendors/acme"
@@ -144,21 +147,21 @@ const unsubscribe = store.observe(mutations => {
144
147
  unsubscribe(); // stop receiving events
145
148
  ```
146
149
 
147
- The second argument scopes the observer to the given resources and their descendants; omit it to receive all mutations,
148
- pass an empty array to detach the observer.
150
+ The second argument scopes the observer to the given resources and their descendants: pass a single reference or any
151
+ collection of them, omit it to receive all mutations, or pass an empty collection to skip registration altogether.
149
152
 
150
153
  ## Executing Transactions
151
154
 
152
155
  ```typescript
153
156
  await store.execute(async store => {
154
- await store.create({ entry: product.id, shape: ProductShape, state: product });
157
+ await store.create({ entry: catalogue, shape: CatalogueShape, model: { products: {} }, state: product });
155
158
  await store.update({ entry: inventory.id, shape: InventoryShape, state: inventory });
156
159
  });
157
160
  ```
158
161
 
159
- Cross-backend isolation semantics, concurrency models, and the buffer-and-flush emulation pattern are documented in the
160
- [Transaction Design](https://metreeca.github.io/keep/documents/_metreeca_keep.Transaction_Design.html) companion
161
- document.
162
+ Cross-backend atomicity and isolation semantics, concurrency models, and the buffer-and-flush emulation pattern are
163
+ documented in the [Transaction Design](https://metreeca.github.io/keep/documents/_metreeca_keep.Transaction_Design.html)
164
+ companion document.
162
165
 
163
166
  # Implementing Connectors
164
167
 
@@ -178,9 +181,9 @@ function createMyStore(): Store {
178
181
 
179
182
  const backend: StoreClient = {
180
183
 
181
- lookup({ entry, shape, model }) { /* query the backend, return matching data or undefined */ },
184
+ lookup({ entry, shape, model }, scope) { /* query the backend, return matching data or undefined */ },
182
185
 
183
- create({ entry, shape, state }) { /* create if absent, return entry or undefined */ },
186
+ create({ entry, shape, model, state }) { /* create under the collection, return the new entry or undefined */ },
184
187
  update({ entry, shape, state }) { /* update if present, return entry or undefined */ },
185
188
  delete({ entry, shape }) { /* delete if present, return entry or undefined */ },
186
189
 
@@ -189,9 +192,11 @@ function createMyStore(): Store {
189
192
 
190
193
  };
191
194
 
192
- return createManagingStore(createValidatingStore(backend, { trusted: true }), {
195
+ const client = createValidatingStore(backend, { trusted: true });
196
+
197
+ return createManagingStore({
193
198
 
194
- execute: task => { /* run task within a backend transaction */ },
199
+ execute: task => { /* run task(client) within a backend transaction */ },
195
200
  close: () => { /* release connections */ }
196
201
 
197
202
  });
@@ -200,11 +205,12 @@ function createMyStore(): Store {
200
205
  ```
201
206
 
202
207
  Pass `trusted: true` to `createValidatingStore` when the backend is trusted to deliver shape-conforming data, so
203
- `lookup` responses skip the redundant outbound validation pass. Supply `execute` to `createManagingStore` to route every
204
- standalone call and the entire `execute` task body through the backend's transaction primitive; omit it for
205
- non-transactional backends and the wrapper degrades to per-call atomicity. `close` defaults to a no-op.
208
+ `lookup` responses skip the redundant validation pass. The `execute` option of `createManagingStore` is required: it runs
209
+ every standalone call and the entire `execute` task body within the backend's transaction primitive, and MUST call the
210
+ task with a store client dedicated to that transaction. A non-transactional backend supplies an `execute` applying the
211
+ task directly to the client, and documents that a failing task does not roll back. `close` defaults to a no-op.
206
212
 
207
- All errors reach the caller as promise rejections through the unified Store error channel — `RangeError` for malformed
213
+ All errors reach the caller as promise rejections through the unified store error channel: `RangeError` for malformed
208
214
  entries, `TraceError` for shape validation failures, `Problem` for network, storage, or other processing failures.
209
215
  Connectors MUST preserve this contract: convert backend-specific exceptions into `Problem` rejections and let validation
210
216
  rejections propagate untouched.
@@ -215,8 +221,8 @@ companion document.
215
221
 
216
222
  ## Testing
217
223
 
218
- Use [@metreeca/keep-suite](https://github.com/metreeca/keep/tree/main/packages/keep-suite) to run the full conformance
219
- suite against your connector:
224
+ Use [@metreeca/keep-suite](https://github.com/metreeca/keep/tree/main/packages/components/keep-suite) to run the full
225
+ conformance suite against your connector:
220
226
 
221
227
  ```typescript
222
228
  import { testStore } from "@metreeca/keep-suite";
@@ -224,11 +230,11 @@ import { describe } from "vitest";
224
230
 
225
231
  describe("my-store", () => testStore({
226
232
 
227
- build: () => createMyStore(), // create a store with schema but no data
233
+ open: () => createMyStore(), // open a store with schema but no data
228
234
 
229
- contains: id => { /* true if the resource has any stored data */ },
230
- includes: (resource, shape) => { /* true if every fact described by `resource` is present */ },
231
- excludes: (resource, shape) => { /* true if every fact described by `resource` is absent */ },
235
+ contains: entry => { /* true if the resource has any stored data */ },
236
+ includes: (probe, shape) => { /* true if every fact described by `probe` is present */ },
237
+ excludes: (probe, shape) => { /* true if every fact described by `probe` is absent */ },
232
238
 
233
239
  populate: () => { /* clear and reload the sample dataset */ },
234
240
  generate: (sample, shape) => { /* insert an isolated copy of `sample` with a unique id */ },
@@ -238,7 +244,8 @@ describe("my-store", () => testStore({
238
244
  }));
239
245
  ```
240
246
 
241
- Filter to a subset of sub-suites with the `match` option (for example, `["Retrieve", "PersistCreate"]`); see the
247
+ Narrow the run to a subset of sub-suites or tests with the `target` and `ignore` options (for example,
248
+ `target: ["Retrieve", "PersistCreate"]`); see the
242
249
  [API reference](https://metreeca.github.io/keep/modules/_metreeca_keep-suite.html) for the full list.
243
250
 
244
251
  # Support
@@ -1,18 +1,20 @@
1
- import type { Broker, Detect, Handler, Lookup, Modify, Select } from "./batching.js";
1
+ import type { ResourceShape } from "@metreeca/blue/resource";
2
+ import { type Lazy } from "@metreeca/core";
3
+ import type { Reference, Resource } from "@metreeca/qest/state";
4
+ import type { Broker, Detail, Detect, Handler, Modify, Select } from "./batching.js";
2
5
  /**
3
6
  * Creates a batching request {@link Broker}.
4
7
  *
5
- * Backs {@link createBatchingStore}: returns a broker that queues each submitted request by type and
6
- * drives the queues to completion against the supplied handlers. The first submission kicks a drain
7
- * loop that runs all four handlers concurrently, round by round, until every queue is quiescent;
8
- * requests issued mid-round, whether forwarded by a handler or freshly submitted, are served on a
9
- * later round, so handlers must not assume any ordering between handlers.
8
+ * Backs {@link createBatchingStore}: the broker queues each submitted request by type and serves the queues in rounds
9
+ * against the supplied handlers, running all four concurrently, until every queue is empty. Requests issued
10
+ * mid-round, whether forwarded by a handler or freshly submitted, are served in a later round, so handlers must not
11
+ * assume any ordering between handlers.
10
12
  *
11
- * Handler errors poison the run: every still-pending {@link Deferred} is rejected with the
12
- * originating error, so callers see a deterministic failure rather than a hang.
13
+ * A handler throw fails the whole run: every pending {@link Deferred} is rejected with the originating error, so
14
+ * callers see a deterministic failure rather than a hang.
13
15
  *
14
16
  * @param handlers The batch handlers, one per request type. Each settles every {@link Deferred} in
15
- * its batch and may issue nested {@link Broker.lookup} / {@link Broker.select} calls while
17
+ * its batch and may issue nested {@link Broker.detail} / {@link Broker.select} calls while
16
18
  * processing; its returned promise must settle only after every owned request, including
17
19
  * transitively nested ones, has settled.
18
20
  *
@@ -22,8 +24,26 @@ import type { Broker, Detect, Handler, Lookup, Modify, Select } from "./batching
22
24
  */
23
25
  export declare function createBroker(handlers: {
24
26
  detect: Handler<Detect>;
25
- lookup: Handler<Lookup>;
27
+ detail: Handler<Detail>;
26
28
  select: Handler<Select>;
27
29
  modify: Handler<Modify>;
28
30
  }): Broker;
31
+ /**
32
+ * Mints the identifier of a resource created under a collection.
33
+ *
34
+ * Returns an identifier nested under `entry`, matching the identifier {@link ResourceShape.pattern | pattern} declared
35
+ * by the shape, if any. Each `{name}` slot is filled with the like-named member of `state`, or with an opaque segment
36
+ * if the state has no such member. A trailing `/*` slot is always filled with an opaque segment. A root-relative
37
+ * pattern is resolved against `entry`. If the shape declares no pattern, the identifier is an opaque segment under
38
+ * `entry`.
39
+ *
40
+ * @param entry The absolute identifier of the resource collecting the new one
41
+ * @param shape The shape describing the new resource, possibly deferred to break definition cycles
42
+ * @param state The initial state of the new resource
43
+ *
44
+ * @returns The absolute identifier of the new resource
45
+ *
46
+ * @throws {@link !RangeError RangeError} If a member filling a slot is not a single non-empty path segment
47
+ */
48
+ export declare function mint(entry: Reference, shape: Lazy<ResourceShape>, state: Resource): Reference;
29
49
  //# sourceMappingURL=batching.core.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"batching.core.d.ts","sourceRoot":"","sources":["../../src/clients/batching.core.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,MAAM,EAAY,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAW,MAAM,EAAE,MAAM,eAAe,CAAC;AAExG;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE;IAEtC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAA;IACvB,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAA;IACvB,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAA;IACvB,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAA;CAEvB,GAAG,MAAM,CAgIT"}
1
+ {"version":3,"file":"batching.core.d.ts","sourceRoot":"","sources":["../../src/clients/batching.core.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAE7D,OAAO,EAA8C,KAAK,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAIvF,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAS,MAAM,sBAAsB,CAAC;AACvE,OAAO,KAAK,EAAE,MAAM,EAAY,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAW,MAAM,EAAE,MAAM,eAAe,CAAC;AAYxG;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE;IAEtC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAA;IACvB,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAA;IACvB,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAA;IACvB,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAA;CAEvB,GAAG,MAAM,CA+IT;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,CAAC,aAAa,CAAC,EAAE,KAAK,EAAE,QAAQ,GAAG,SAAS,CAwB7F"}
@@ -13,21 +13,29 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
- import { immutable } from "@metreeca/core/structures";
16
+ import { eager } from "@metreeca/blue/value";
17
+ import { error, isNumber, isString } from "@metreeca/core";
18
+ import { resolve } from "@metreeca/core/resource";
19
+ import { immutable } from "@metreeca/core/values";
20
+ /**
21
+ * The form a value read off a state has to take to stand as a path segment: non-empty, with no delimiter or
22
+ * whitespace.
23
+ */
24
+ const SegmentFormat = /^[^\s/?#]+$/;
25
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
17
26
  /**
18
27
  * Creates a batching request {@link Broker}.
19
28
  *
20
- * Backs {@link createBatchingStore}: returns a broker that queues each submitted request by type and
21
- * drives the queues to completion against the supplied handlers. The first submission kicks a drain
22
- * loop that runs all four handlers concurrently, round by round, until every queue is quiescent;
23
- * requests issued mid-round, whether forwarded by a handler or freshly submitted, are served on a
24
- * later round, so handlers must not assume any ordering between handlers.
29
+ * Backs {@link createBatchingStore}: the broker queues each submitted request by type and serves the queues in rounds
30
+ * against the supplied handlers, running all four concurrently, until every queue is empty. Requests issued
31
+ * mid-round, whether forwarded by a handler or freshly submitted, are served in a later round, so handlers must not
32
+ * assume any ordering between handlers.
25
33
  *
26
- * Handler errors poison the run: every still-pending {@link Deferred} is rejected with the
27
- * originating error, so callers see a deterministic failure rather than a hang.
34
+ * A handler throw fails the whole run: every pending {@link Deferred} is rejected with the originating error, so
35
+ * callers see a deterministic failure rather than a hang.
28
36
  *
29
37
  * @param handlers The batch handlers, one per request type. Each settles every {@link Deferred} in
30
- * its batch and may issue nested {@link Broker.lookup} / {@link Broker.select} calls while
38
+ * its batch and may issue nested {@link Broker.detail} / {@link Broker.select} calls while
31
39
  * processing; its returned promise must settle only after every owned request, including
32
40
  * transitively nested ones, has settled.
33
41
  *
@@ -40,12 +48,16 @@ export function createBroker(handlers) {
40
48
  const items = [];
41
49
  return [key, {
42
50
  items,
43
- drain: async () => {
44
- if (items.length > 0) {
45
- const batch = items.slice();
46
- await handler(batch, broker); // ;(cast) erased to the handler's union parameter
47
- items.splice(0, batch.length);
48
- }
51
+ // snapshots the queued requests and hands them to the handler, keeping them queued until the round
52
+ // is settled by the drain loop, which removes exactly the snapshot in the same step it re-checks the
53
+ // queues: a queue emptied any earlier would let a submission landing in between kick a second drain
54
+ // over the same snapshot, whose own removal would then drop whatever was queued behind it
55
+ round: () => {
56
+ const batch = items.slice();
57
+ return {
58
+ done: batch.length > 0 ? handler(batch, broker) : Promise.resolve(),
59
+ settle: () => { items.splice(0, batch.length); }
60
+ };
49
61
  },
50
62
  purge: error => {
51
63
  items.forEach(deferred => deferred.reject(error));
@@ -58,8 +70,8 @@ export function createBroker(handlers) {
58
70
  detect(request) {
59
71
  return new Promise((resolve, reject) => queues.detect.items.push({ request, resolve, reject }));
60
72
  },
61
- lookup(request) {
62
- return new Promise((resolve, reject) => queues.lookup.items.push({ request, resolve, reject }));
73
+ detail(request) {
74
+ return new Promise((resolve, reject) => queues.detail.items.push({ request, resolve, reject }));
63
75
  },
64
76
  select(request) {
65
77
  return new Promise((resolve, reject) => queues.select.items.push({ request, resolve, reject }));
@@ -73,8 +85,8 @@ export function createBroker(handlers) {
73
85
  detect(request) {
74
86
  return process(() => broker.detect(request));
75
87
  },
76
- lookup(request) {
77
- return process(() => broker.lookup(request));
88
+ detail(request) {
89
+ return process(() => broker.detail(request));
78
90
  },
79
91
  select(request) {
80
92
  return process(() => broker.select(request));
@@ -83,22 +95,23 @@ export function createBroker(handlers) {
83
95
  return process(() => broker.modify(request));
84
96
  }
85
97
  });
86
- // Kicks a drain only when every queue is idle: a running drain keeps its snapshot queued, so
87
- // "all empty" means "no drain in flight". The kick is a microtask, so a synchronous burst of
88
- // submissions coalesces into one drain. The check runs before `submit` enqueues, or it would
89
- // always see the request it just pushed.
98
+ // Kicks a drain only when every queue is idle: a running drain keeps its snapshots queued until the
99
+ // step that re-checks the queues, so "all empty" means "no drain in flight". The kick is a microtask,
100
+ // so a synchronous burst of submissions coalesces into one drain. The check runs before `submit`
101
+ // enqueues, or it would always see the request it just pushed.
90
102
  function process(submit) {
91
- // a running drain keeps its snapshot in the queues until the round ends, so any non-empty
92
- // queue means a drain is already in flight; all-empty is the only "no drain running" state
93
103
  if (Object.values(queues).every(queue => queue.items.length === 0)) {
94
104
  Promise.resolve().then(async () => {
95
105
  // Drain in rounds until every queue is quiescent, all four handlers concurrently per
96
- // round. A handler keeps its snapshot in the queue across the `await` (so the idle-check
97
- // still sees work and won't kick a second drain) and removes exactly it on success;
98
- // anything pushed mid-round is served next round. A throw leaves the snapshot queued to purge.
106
+ // round. Every snapshot stays queued across the `await` and is removed in the same
107
+ // synchronous step as the next idle check, so no submission can ever find the queues empty
108
+ // while the loop is alive; anything pushed mid-round is served next round. A throw leaves
109
+ // the snapshots queued to purge.
99
110
  try {
100
111
  while (Object.values(queues).some(queue => queue.items.length > 0)) {
101
- await Promise.all(Object.values(queues).map(queue => queue.drain()));
112
+ const rounds = Object.values(queues).map(queue => queue.round());
113
+ await Promise.all(rounds.map(round => round.done));
114
+ rounds.forEach(round => round.settle());
102
115
  }
103
116
  }
104
117
  catch (error) {
@@ -111,4 +124,36 @@ export function createBroker(handlers) {
111
124
  return submit();
112
125
  }
113
126
  }
127
+ /**
128
+ * Mints the identifier of a resource created under a collection.
129
+ *
130
+ * Returns an identifier nested under `entry`, matching the identifier {@link ResourceShape.pattern | pattern} declared
131
+ * by the shape, if any. Each `{name}` slot is filled with the like-named member of `state`, or with an opaque segment
132
+ * if the state has no such member. A trailing `/*` slot is always filled with an opaque segment. A root-relative
133
+ * pattern is resolved against `entry`. If the shape declares no pattern, the identifier is an opaque segment under
134
+ * `entry`.
135
+ *
136
+ * @param entry The absolute identifier of the resource collecting the new one
137
+ * @param shape The shape describing the new resource, possibly deferred to break definition cycles
138
+ * @param state The initial state of the new resource
139
+ *
140
+ * @returns The absolute identifier of the new resource
141
+ *
142
+ * @throws {@link !RangeError RangeError} If a member filling a slot is not a single non-empty path segment
143
+ */
144
+ export function mint(entry, shape, state) {
145
+ const { pattern } = eager(shape);
146
+ return pattern === undefined
147
+ ? resolve(entry.endsWith("/") ? entry : `${entry}/`, crypto.randomUUID())
148
+ : resolve(entry, pattern.replace(/\{(\w*)}|(?<=\/)\*$/g, (_, name) => name === undefined ? crypto.randomUUID() : segment(name)));
149
+ /**
150
+ * Reads a pattern slot off the like-named member of the state, or fills it with an opaque segment.
151
+ */
152
+ function segment(name) {
153
+ const value = state[name];
154
+ return value === undefined ? crypto.randomUUID()
155
+ : (isString(value) || isNumber(value)) && SegmentFormat.test(String(value)) ? String(value)
156
+ : error(new RangeError(`illegal identifier segment <${String(value)}> for slot <${name}>`));
157
+ }
158
+ }
114
159
  //# sourceMappingURL=batching.core.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"batching.core.js","sourceRoot":"","sources":["../../src/clients/batching.core.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"batching.core.js","sourceRoot":"","sources":["../../src/clients/batching.core.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,EAAE,KAAK,EAAc,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,KAAK,EAAmB,QAAQ,EAAE,QAAQ,EAAa,MAAM,gBAAgB,CAAC;AACvF,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAMlD;;;GAGG;AACH,MAAM,aAAa,GAAG,aAAa,CAAC;AAGpC,wHAAwH;AAExH;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,YAAY,CAAC,QAO5B;IAEA,MAAM,MAAM,GAOP,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,OAAO,CAAC,EAAE,EAAE;QAEvE,MAAM,KAAK,GAAwB,EAAE,CAAC;QAEtC,OAAO,CAAC,GAAG,EAAE;gBAEZ,KAAK;gBAEL,mGAAmG;gBACnG,qGAAqG;gBACrG,oGAAoG;gBACpG,0FAA0F;gBAE1F,KAAK,EAAE,GAAG,EAAE;oBAEX,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC;oBAE5B,OAAO;wBAEN,IAAI,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAc,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE;wBAE5E,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;qBAEhD,CAAC;gBAEH,CAAC;gBAED,KAAK,EAAE,KAAK,CAAC,EAAE;oBACd,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;oBAClD,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;gBAClB,CAAC;aAED,CAAC,CAAC;IAEJ,CAAC,CAAC,CAAC,CAAC;IAEJ,sFAAsF;IAEtF,MAAM,MAAM,GAAW,SAAS,CAAC;QAEhC,MAAM,CAAC,OAAe;YACrB,OAAO,IAAI,OAAO,CAAU,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,CAC/C,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAsB,CAAC,CAC1E,CAAC;QACH,CAAC;QAED,MAAM,CAAoD,OAAqB;YAC9E,OAAO,IAAI,OAAO,CAAc,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,CACnD,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAsB,CAAC,CAC1E,CAAC;QACH,CAAC;QAED,MAAM,CAAwB,OAAkB;YAC/C,OAAO,IAAI,OAAO,CAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,CACxD,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAsB,CAAC,CAC1E,CAAC;QACH,CAAC;QAED,MAAM,CAAC,OAAe;YACrB,OAAO,IAAI,OAAO,CAAY,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,CACjD,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAsB,CAAC,CAC1E,CAAC;QACH,CAAC;KAED,CAAC,CAAC;IAEH,gGAAgG;IAEhG,OAAO,SAAS,CAAC;QAEhB,MAAM,CAAC,OAAe;YACrB,OAAO,OAAO,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;QAC9C,CAAC;QAED,MAAM,CAAoD,OAAqB;YAC9E,OAAO,OAAO,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;QAC9C,CAAC;QAED,MAAM,CAAwB,OAAkB;YAC/C,OAAO,OAAO,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;QAC9C,CAAC;QAED,MAAM,CAAC,OAAe;YACrB,OAAO,OAAO,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;QAC9C,CAAC;KAED,CAAC,CAAC;IAGH,oGAAoG;IACpG,sGAAsG;IACtG,iGAAiG;IACjG,+DAA+D;IAE/D,SAAS,OAAO,CAAI,MAAe;QAElC,IAAK,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,EAAG,CAAC;YAEtE,OAAO,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;gBAEjC,qFAAqF;gBACrF,mFAAmF;gBACnF,2FAA2F;gBAC3F,0FAA0F;gBAC1F,iCAAiC;gBAEjC,IAAI,CAAC;oBAEJ,OAAQ,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,EAAG,CAAC;wBAEtE,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;wBAEjE,MAAM,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;wBAEnD,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;oBAEzC,CAAC;gBAEF,CAAC;gBAAC,OAAQ,KAAK,EAAG,CAAC;oBAElB,+EAA+E;oBAC/E,qDAAqD;oBAErD,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;gBAE5D,CAAC;YAEF,CAAC,CAAC,CAAC;QAEJ,CAAC;QAED,OAAO,MAAM,EAAE,CAAC;IACjB,CAAC;AAEF,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,IAAI,CAAC,KAAgB,EAAE,KAA0B,EAAE,KAAe;IAEjF,MAAM,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;IAEjC,OAAO,OAAO,KAAK,SAAS;QAC3B,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,EAAE,MAAM,CAAC,UAAU,EAAE,CAAC;QACzE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,sBAAsB,EAAE,CAAC,CAAC,EAAE,IAAa,EAAE,EAAE,CAC7E,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CACxD,CAAC,CAAC;IAGJ;;OAEG;IACH,SAAS,OAAO,CAAC,IAAY;QAE5B,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;QAE1B,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,EAAE;YAC/C,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;gBAC1F,CAAC,CAAC,KAAK,CAAC,IAAI,UAAU,CAAC,+BAA+B,MAAM,CAAC,KAAK,CAAC,eAAe,IAAI,GAAG,CAAC,CAAC,CAAC;IAE/F,CAAC;AAEF,CAAC"}