doxum 0.1.26 → 0.1.28
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 +86 -3
- package/dist/advanced.cjs +40 -30
- package/dist/advanced.cjs.map +1 -1
- package/dist/advanced.d.cts +34 -2
- package/dist/advanced.d.ts +34 -2
- package/dist/advanced.js +31 -22
- package/dist/advanced.js.map +1 -1
- package/dist/{definition-xgk3YNBp.d.ts → dependency-B3E65M1E.d.cts} +27 -3
- package/dist/{definition-CDOuvb5C.d.cts → dependency-BYbdDHNa.d.ts} +27 -3
- package/dist/driver-B5vdPohL.js.map +1 -1
- package/dist/driver-BL91gn7_.cjs.map +1 -1
- package/dist/index.cjs +885 -394
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +33 -18
- package/dist/index.d.ts +33 -18
- package/dist/index.js +784 -293
- package/dist/index.js.map +1 -1
- package/dist/local-sync.cjs.map +1 -1
- package/dist/local-sync.js.map +1 -1
- package/dist/transform-B4T3AcJr.js +938 -0
- package/dist/transform-B4T3AcJr.js.map +1 -0
- package/dist/transform-DUleAsG0.cjs +1105 -0
- package/dist/transform-DUleAsG0.cjs.map +1 -0
- package/package.json +1 -1
- package/skills/doxum-runtime/SKILL.md +16 -6
- package/skills/doxum-runtime/references/api.en.md +49 -15
- package/skills/doxum-runtime/references/api.zh-CN.md +47 -13
- package/skills/doxum-runtime/references/guide.en.md +2 -1
- package/skills/doxum-runtime/references/guide.zh-CN.md +2 -1
- package/skills/doxum-runtime/references/invariants.en.md +2 -2
- package/skills/doxum-runtime/references/invariants.zh-CN.md +2 -2
- package/skills/doxum-runtime/references/patterns.en.md +1 -1
- package/skills/doxum-runtime/references/patterns.zh-CN.md +1 -1
- package/skills/doxum-runtime/references/projections.en.md +77 -4
- package/skills/doxum-runtime/references/projections.zh-CN.md +74 -3
- package/dist/scheduler--137L3j-.js +0 -500
- package/dist/scheduler--137L3j-.js.map +0 -1
- package/dist/scheduler-D4VthaaK.cjs +0 -589
- package/dist/scheduler-D4VthaaK.cjs.map +0 -1
package/README.md
CHANGED
|
@@ -276,8 +276,8 @@ runtime.dispose();
|
|
|
276
276
|
|
|
277
277
|
The stable vocabulary is `read` for a synchronous current value, `select` for a
|
|
278
278
|
`Readable`, and `observe` for declaring a lazy source boundary. `ProjectionRuntime`
|
|
279
|
-
exposes `read`, `select`, `update`, `batch`, `scope` and `dispose`.
|
|
280
|
-
`ProjectionScope` mirrors `read`, `select`, `update`, `batch` and `dispose`, plus
|
|
279
|
+
exposes `read`, `select`, `items`, `update`, `batch`, `scope` and `dispose`.
|
|
280
|
+
`ProjectionScope` mirrors `read`, `select`, `items`, `update`, `batch` and `dispose`, plus
|
|
281
281
|
`own(definitionOrTree)` for lifecycle ownership of lazy projection definitions.
|
|
282
282
|
|
|
283
283
|
### Keyed projection
|
|
@@ -293,6 +293,36 @@ The output keeps one key per source entry. The selector runs only for affected k
|
|
|
293
293
|
and the optional equality function suppresses `updated` output transitions when the
|
|
294
294
|
derived value is equal.
|
|
295
295
|
|
|
296
|
+
The same family covers standard keyed structure reads and membership-changing derives:
|
|
297
|
+
|
|
298
|
+
```ts
|
|
299
|
+
const ids = derive.keyed.keys(records);
|
|
300
|
+
const all = derive.keyed.values(records);
|
|
301
|
+
const entries = derive.keyed.entries(records);
|
|
302
|
+
const active = derive.keyed.get(records, activeRecordId);
|
|
303
|
+
const visible = derive.keyed.filter(records, record => record.visible);
|
|
304
|
+
const orderedVisible = derive.keyed.subset(records, visibleIds);
|
|
305
|
+
const definedContent = derive.keyed.compact(records, record => record.content);
|
|
306
|
+
const recordsBySection = derive.keyed.groupBy(records, record => record.sectionId);
|
|
307
|
+
const activeAsCollection = derive.keyed.singleton(activeRecord, record => record.id);
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
`keys` publishes only for membership/order/reset changes; value-only updates keep the
|
|
311
|
+
same array reference and revision. `values` and `entries` follow the formal keyed order;
|
|
312
|
+
`entries` publishes readonly `[key, value]` tuples and reuses unchanged tuple references.
|
|
313
|
+
`get` is a scalar dynamic lookup: it depends only on the selected key, keeps a missing
|
|
314
|
+
key bound for later adds, and accepts optional result equality. `subset`
|
|
315
|
+
uses the supplied ordered keys as both membership selection and output order, ignoring
|
|
316
|
+
currently missing source keys until they appear. `filter` preserves source values and
|
|
317
|
+
source-relative order. `compact` omits keys whose selected value is `undefined` and
|
|
318
|
+
uses its optional equality for present values. `filter` and `compact` support the same
|
|
319
|
+
named global/dynamic keyed dependency object as ordinary `derive.keyed`.
|
|
320
|
+
|
|
321
|
+
`groupBy` is the general reverse-index primitive. A source entry may return one group
|
|
322
|
+
key or several; each output bucket contains source keys in the source's formal order,
|
|
323
|
+
and group order follows first appearance in that same order. `singleton` converts an
|
|
324
|
+
optional scalar projection into a zero-or-one keyed projection.
|
|
325
|
+
|
|
296
326
|
All keyed projection producers use the public `KeyedProjection<K,V>` handle, including
|
|
297
327
|
collection `observe`, `derive.keyed`, `incremental.collection`, and collection leaves
|
|
298
328
|
from `incremental.group`. `CollectionInput<K,V>` is the writable Runtime-local form of
|
|
@@ -320,6 +350,30 @@ bound, so adding it later invalidates the dependent output keys. An ordinary pro
|
|
|
320
350
|
dependency invalidates the driver key set when its value changes. Processor code never
|
|
321
351
|
performs imperative Runtime reads to discover dependencies.
|
|
322
352
|
|
|
353
|
+
Use `{ source, keys }` when one driver key depends on several keys from another keyed
|
|
354
|
+
projection. The callback returns a duplicate-free ordered key array; the dependency
|
|
355
|
+
value is a readonly map containing the currently present selected entries in that order.
|
|
356
|
+
Source-key changes invalidate only the driver keys reverse-bound to that key.
|
|
357
|
+
|
|
358
|
+
### Keyed Readables
|
|
359
|
+
|
|
360
|
+
Use `runtime.items(projection)` when a consumer needs stable per-key `Readable`
|
|
361
|
+
identities instead of a whole-collection selector:
|
|
362
|
+
|
|
363
|
+
```ts
|
|
364
|
+
const recordItems = runtime.items(records);
|
|
365
|
+
const orderedIds = recordItems.keys;
|
|
366
|
+
const record = recordItems.get(recordId); // Readable<Record | undefined>
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
One family is cached per Runtime/scope lifetime and materialized keyed output. `keys`
|
|
370
|
+
publishes only for membership/order changes. While a key remains a published member,
|
|
371
|
+
`get(key)` returns the same Readable identity and value-only updates notify only that
|
|
372
|
+
item. Removal publishes `undefined` to that generation and retires it; adding the same
|
|
373
|
+
key later creates a new generation. A subscribed missing item stays latent and activates
|
|
374
|
+
if the key is later added. Runtime batches follow the net published membership, so a
|
|
375
|
+
remove/add collapsed to an update does not create a false lifecycle break.
|
|
376
|
+
|
|
323
377
|
### Runtime-local keyed state
|
|
324
378
|
|
|
325
379
|
Use `input.collection` for selection, expanded state, local overrides and other
|
|
@@ -343,7 +397,9 @@ transitions and preserves order. The optional per-entry equality defaults to `Ob
|
|
|
343
397
|
and suppresses equivalent `set` operations. Callback and equality failures leave both
|
|
344
398
|
the published value and the next draft unchanged.
|
|
345
399
|
|
|
346
|
-
The processor-facing `CollectionChange` type
|
|
400
|
+
The processor-facing `CollectionChange` type and `collectionChange.keys(...)` utility
|
|
401
|
+
are exported by `doxum/advanced`. The utility lazily iterates incremental added,
|
|
402
|
+
updated, then removed keys; it does not interpret reset or order changes.
|
|
347
403
|
|
|
348
404
|
A root input definition can be materialized independently by several runtimes. Wrap any
|
|
349
405
|
definition in `scope.own(...)` when its lifecycle belongs to one scope; scalar inputs,
|
|
@@ -412,8 +468,35 @@ const doubled = incremental.collection(
|
|
|
412
468
|
);
|
|
413
469
|
```
|
|
414
470
|
|
|
471
|
+
For retained state that belongs independently to each driver key, use
|
|
472
|
+
`incremental.keyed`:
|
|
473
|
+
|
|
474
|
+
```ts
|
|
475
|
+
const sectionTotals = incremental.keyed(
|
|
476
|
+
sections,
|
|
477
|
+
{
|
|
478
|
+
records: { source: records, keys: section => section.recordIds },
|
|
479
|
+
},
|
|
480
|
+
{
|
|
481
|
+
state: () => ({ runs: 0 }),
|
|
482
|
+
process: ({ value, dependencies, state }) => {
|
|
483
|
+
state.runs++;
|
|
484
|
+
return [...dependencies.records.values()].reduce((sum, record) => sum + record.score, 0);
|
|
485
|
+
},
|
|
486
|
+
}
|
|
487
|
+
);
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
The driver exclusively owns output membership/order. Each membership owns its retained
|
|
491
|
+
state; removing a key releases that state and a later re-add starts a new membership
|
|
492
|
+
lifecycle. Scalar dependencies invalidate all current driver keys, while singular or
|
|
493
|
+
plural keyed dependencies use reverse routing to run only affected keys. The processor
|
|
494
|
+
returns only its own output value and does not receive a collection draft.
|
|
495
|
+
|
|
415
496
|
`incremental(...)` produces one scalar value projection.
|
|
416
497
|
`incremental.collection(...)` exposes keyed `previous`, `next` and `output`.
|
|
498
|
+
`incremental.keyed(...)` preserves one driver's keys/order with independent per-key
|
|
499
|
+
retained state and precise dynamic keyed invalidation.
|
|
417
500
|
`incremental.group(...)` runs one processor for several atomic output leaves:
|
|
418
501
|
|
|
419
502
|
```ts
|
package/dist/advanced.cjs
CHANGED
|
@@ -1,26 +1,9 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const
|
|
2
|
+
const require_transform = require("./transform-DUleAsG0.cjs");
|
|
3
3
|
const require_record = require("./record-ChYUi8PP.cjs");
|
|
4
4
|
//#region core/src/projection/advanced.ts
|
|
5
5
|
const resetCollectionChange = Object.freeze({ kind: "reset" });
|
|
6
|
-
const publicValue = (source) => source.kind === "value" ? source.value :
|
|
7
|
-
const compileDependencies = (dependencies) => {
|
|
8
|
-
if (!require_record.isPlainObject(dependencies) || require_scheduler.isProjection(dependencies)) throw new TypeError("Incremental dependencies must be a plain object.");
|
|
9
|
-
const names = [];
|
|
10
|
-
const projections = [];
|
|
11
|
-
for (const key of Reflect.ownKeys(dependencies)) {
|
|
12
|
-
if (typeof key !== "string") throw new TypeError("Incremental dependency names must be strings.");
|
|
13
|
-
const descriptor = Object.getOwnPropertyDescriptor(dependencies, key);
|
|
14
|
-
if (!descriptor?.enumerable || !("value" in descriptor)) throw new TypeError("Incremental dependencies must be enumerable data properties.");
|
|
15
|
-
require_scheduler.projectionRef(descriptor.value);
|
|
16
|
-
names.push(key);
|
|
17
|
-
projections.push(descriptor.value);
|
|
18
|
-
}
|
|
19
|
-
return Object.freeze({
|
|
20
|
-
names: Object.freeze(names),
|
|
21
|
-
projections: Object.freeze(projections)
|
|
22
|
-
});
|
|
23
|
-
};
|
|
6
|
+
const publicValue = (source) => source.kind === "value" ? source.value : require_transform.collectionView(source.read);
|
|
24
7
|
const publicInputs = (sources, names, reset) => {
|
|
25
8
|
const values = Object.create(null);
|
|
26
9
|
const changes = Object.create(null);
|
|
@@ -49,15 +32,15 @@ const validateRetainedState = (definition, label) => {
|
|
|
49
32
|
const initializeRetainedState = (definition) => {
|
|
50
33
|
if (definition.state === void 0) return Object.freeze({});
|
|
51
34
|
const state = definition.state();
|
|
52
|
-
|
|
35
|
+
require_transform.assertSynchronous(state);
|
|
53
36
|
return Object.freeze({ state });
|
|
54
37
|
};
|
|
55
38
|
function createIncrementalValue(dependencies, definition) {
|
|
56
|
-
const compiled =
|
|
39
|
+
const compiled = require_transform.compileProjectionDependencies(dependencies, "Incremental");
|
|
57
40
|
validateDefinition(definition, ["state", "process"], "Incremental value");
|
|
58
41
|
validateRetainedState(definition, "Incremental value");
|
|
59
42
|
if (typeof definition.process !== "function") throw new TypeError("Incremental value definition requires a process function.");
|
|
60
|
-
const [projection] =
|
|
43
|
+
const [projection] = require_transform.defineProcessor({
|
|
61
44
|
dependencies: compiled.projections,
|
|
62
45
|
outputs: [{
|
|
63
46
|
kind: "value",
|
|
@@ -77,7 +60,7 @@ function createIncrementalValue(dependencies, definition) {
|
|
|
77
60
|
cause: evaluation.cause,
|
|
78
61
|
...state
|
|
79
62
|
});
|
|
80
|
-
|
|
63
|
+
require_transform.assertSynchronous(result);
|
|
81
64
|
output.output.set(result);
|
|
82
65
|
} };
|
|
83
66
|
}
|
|
@@ -85,11 +68,11 @@ function createIncrementalValue(dependencies, definition) {
|
|
|
85
68
|
return projection;
|
|
86
69
|
}
|
|
87
70
|
function createIncrementalCollection(dependencies, definition) {
|
|
88
|
-
const compiled =
|
|
71
|
+
const compiled = require_transform.compileProjectionDependencies(dependencies, "Incremental");
|
|
89
72
|
validateDefinition(definition, ["state", "process"], "Incremental collection");
|
|
90
73
|
validateRetainedState(definition, "Incremental collection");
|
|
91
74
|
if (typeof definition.process !== "function") throw new TypeError("Incremental collection definition requires a process function.");
|
|
92
|
-
const [projection] =
|
|
75
|
+
const [projection] = require_transform.defineProcessor({
|
|
93
76
|
dependencies: compiled.projections,
|
|
94
77
|
outputs: [{
|
|
95
78
|
kind: "collection",
|
|
@@ -101,7 +84,7 @@ function createIncrementalCollection(dependencies, definition) {
|
|
|
101
84
|
const output = evaluation.outputs[0];
|
|
102
85
|
if (output.kind !== "collection") throw new Error("Incremental collection output is invalid.");
|
|
103
86
|
const publicInput = publicInputs(evaluation.sources, compiled.names, evaluation.reset);
|
|
104
|
-
|
|
87
|
+
require_transform.assertSynchronous(definition.process({
|
|
105
88
|
values: publicInput.values,
|
|
106
89
|
changes: publicInput.changes,
|
|
107
90
|
previous: output.previous,
|
|
@@ -116,6 +99,31 @@ function createIncrementalCollection(dependencies, definition) {
|
|
|
116
99
|
});
|
|
117
100
|
return projection;
|
|
118
101
|
}
|
|
102
|
+
function createIncrementalKeyed(driver, dependencies, definition) {
|
|
103
|
+
validateDefinition(definition, [
|
|
104
|
+
"state",
|
|
105
|
+
"equality",
|
|
106
|
+
"process"
|
|
107
|
+
], "Incremental keyed");
|
|
108
|
+
if (definition.state !== void 0 && typeof definition.state !== "function") throw new TypeError("Incremental keyed state must be a function when provided.");
|
|
109
|
+
if (definition.equality !== void 0 && typeof definition.equality !== "function") throw new TypeError("Incremental keyed equality must be a function when provided.");
|
|
110
|
+
if (typeof definition.process !== "function") throw new TypeError("Incremental keyed definition requires a process function.");
|
|
111
|
+
return require_transform.createKeyedTransform({
|
|
112
|
+
source: driver,
|
|
113
|
+
dependencies,
|
|
114
|
+
equality: definition.equality,
|
|
115
|
+
name: "incremental.keyed",
|
|
116
|
+
...definition.state ? { state: definition.state } : {},
|
|
117
|
+
evaluate: ({ key, value, dependencies: values, state, reset, cause }) => definition.process({
|
|
118
|
+
key,
|
|
119
|
+
value,
|
|
120
|
+
dependencies: values,
|
|
121
|
+
reset,
|
|
122
|
+
cause,
|
|
123
|
+
...definition.state ? { state } : {}
|
|
124
|
+
})
|
|
125
|
+
});
|
|
126
|
+
}
|
|
119
127
|
const isPlainGroupNamespace = (value, metadata) => require_record.isPlainObject(value) && !metadata.has(value);
|
|
120
128
|
const compileGroupShape = (value, path, metadata, used, outputs) => {
|
|
121
129
|
if (value !== null && typeof value === "object") {
|
|
@@ -169,7 +177,7 @@ const hydrateGroupReads = (shape, outputs, next) => {
|
|
|
169
177
|
return Object.freeze(result);
|
|
170
178
|
};
|
|
171
179
|
function createIncrementalGroup(dependencies, definition) {
|
|
172
|
-
const compiled =
|
|
180
|
+
const compiled = require_transform.compileProjectionDependencies(dependencies, "Incremental");
|
|
173
181
|
validateDefinition(definition, [
|
|
174
182
|
"output",
|
|
175
183
|
"state",
|
|
@@ -199,21 +207,21 @@ function createIncrementalGroup(dependencies, definition) {
|
|
|
199
207
|
return descriptor;
|
|
200
208
|
}
|
|
201
209
|
});
|
|
202
|
-
|
|
210
|
+
require_transform.assertSynchronous(declared);
|
|
203
211
|
active = false;
|
|
204
212
|
const outputs = [];
|
|
205
213
|
const used = /* @__PURE__ */ new Set();
|
|
206
214
|
const shape = compileGroupShape(declared, [], metadata, used, outputs);
|
|
207
215
|
if (typeof shape === "number") throw new TypeError("Incremental group declarations must return an output namespace.");
|
|
208
216
|
if (used.size === 0 || used.size !== metadata.size) throw new TypeError("Every incremental group output must be returned by the declaration.");
|
|
209
|
-
return hydrateGroupShape(shape,
|
|
217
|
+
return hydrateGroupShape(shape, require_transform.defineProcessor({
|
|
210
218
|
dependencies: compiled.projections,
|
|
211
219
|
outputs,
|
|
212
220
|
create: () => {
|
|
213
221
|
const state = initializeRetainedState(definition);
|
|
214
222
|
return { evaluate: (evaluation) => {
|
|
215
223
|
const publicInput = publicInputs(evaluation.sources, compiled.names, evaluation.reset);
|
|
216
|
-
|
|
224
|
+
require_transform.assertSynchronous(definition.process({
|
|
217
225
|
values: publicInput.values,
|
|
218
226
|
changes: publicInput.changes,
|
|
219
227
|
previous: hydrateGroupReads(shape, evaluation.outputs, false),
|
|
@@ -230,9 +238,11 @@ function createIncrementalGroup(dependencies, definition) {
|
|
|
230
238
|
}
|
|
231
239
|
const incremental = Object.assign(createIncrementalValue, {
|
|
232
240
|
collection: createIncrementalCollection,
|
|
241
|
+
keyed: createIncrementalKeyed,
|
|
233
242
|
group: createIncrementalGroup
|
|
234
243
|
});
|
|
235
244
|
//#endregion
|
|
245
|
+
exports.collectionChange = require_transform.collectionChange;
|
|
236
246
|
exports.incremental = incremental;
|
|
237
247
|
|
|
238
248
|
//# sourceMappingURL=advanced.cjs.map
|
package/dist/advanced.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"advanced.cjs","names":["collectionView","isPlainObject","isProjection","defineProcessor"],"sources":["../core/src/projection/advanced.ts"],"sourcesContent":["import { collectionView } from './collection/view';\nimport type { CollectionChange, CollectionDraft, CollectionRead, SourceContext } from './contract';\nimport type {\n KeyedProjection,\n OutputDefinition,\n OutputEvaluation,\n Projection,\n ProjectionChange,\n} from './definition';\nimport { defineProcessor, isProjection, projectionRef } from './definition';\nimport { assertSynchronous } from './graph/scheduler';\nimport { isPlainObject } from '../value/record';\n\ntype ProjectionDependencies = Readonly<Record<string, Projection<unknown>>>;\n\ntype ProjectionValues<D extends ProjectionDependencies> = {\n readonly [K in keyof D]: D[K] extends Projection<infer T> ? T : never;\n};\n\ntype ProjectionChanges<D extends ProjectionDependencies> = {\n readonly [K in keyof D]: ProjectionChange<D[K]> extends undefined\n ? undefined\n : ProjectionChange<D[K]> | undefined;\n};\n\ntype RetainedStateContext<State> = [State] extends [never] ? {} : { readonly state: State };\ntype RetainedStateDefinition<State> = [State] extends [never]\n ? { readonly state?: never }\n : { readonly state: () => State };\n\nexport type IncrementalValueContext<D extends ProjectionDependencies, T, State = never> = {\n readonly values: ProjectionValues<D>;\n readonly changes: ProjectionChanges<D>;\n readonly previous: T | undefined;\n readonly reset: boolean;\n readonly cause: unknown;\n} & RetainedStateContext<State>;\n\nexport type IncrementalValueDefinition<D extends ProjectionDependencies, T, State = never> = {\n readonly process: (context: IncrementalValueContext<D, T, State>) => T;\n} & RetainedStateDefinition<State>;\n\nexport type IncrementalCollectionContext<\n D extends ProjectionDependencies,\n K extends string,\n V,\n State = never,\n> = {\n readonly values: ProjectionValues<D>;\n readonly changes: ProjectionChanges<D>;\n readonly previous: CollectionRead<K, V>;\n readonly next: CollectionRead<K, V>;\n readonly reset: boolean;\n readonly cause: unknown;\n readonly output: CollectionDraft<K, V>;\n} & RetainedStateContext<State>;\n\nexport type IncrementalCollectionDefinition<\n D extends ProjectionDependencies,\n K extends string,\n V,\n State = never,\n> = {\n readonly process: (context: IncrementalCollectionContext<D, K, V, State>) => void;\n} & RetainedStateDefinition<State>;\n\ndeclare const groupOutput: unique symbol;\n\n/** Type-only declaration token used by incremental.group output builders. */\nexport type IncrementalGroupOutput<P extends Projection<unknown>> = {\n readonly [groupOutput]: P;\n};\n\ntype GroupOutputShape = {\n readonly [name: string]: IncrementalGroupOutput<Projection<unknown>> | GroupOutputShape;\n};\n\ntype GroupOutputBuilder = {\n collection<K extends string, V>(\n equality?: (previous: V, next: V) => boolean\n ): IncrementalGroupOutput<KeyedProjection<K, V>>;\n value<T>(equality?: (previous: T, next: T) => boolean): IncrementalGroupOutput<Projection<T>>;\n};\n\n/** Portable projection tree returned from an incremental.group declaration. */\nexport type IncrementalGroupResult<O> =\n O extends IncrementalGroupOutput<infer P>\n ? P\n : O extends Readonly<Record<string, unknown>>\n ? { readonly [K in keyof O]: IncrementalGroupResult<O[K]> }\n : never;\n\ntype GroupReads<O> =\n O extends IncrementalGroupOutput<infer P>\n ? P extends KeyedProjection<infer K, infer V>\n ? CollectionRead<K, V>\n : P extends Projection<infer T>\n ? T | undefined\n : never\n : { readonly [K in keyof O]: GroupReads<O[K]> };\n\ntype GroupDrafts<O> =\n O extends IncrementalGroupOutput<infer P>\n ? P extends KeyedProjection<infer K, infer V>\n ? CollectionDraft<K, V>\n : P extends Projection<infer T>\n ? { set(value: T): void }\n : never\n : { readonly [K in keyof O]: GroupDrafts<O[K]> };\n\nexport type IncrementalGroupContext<\n D extends ProjectionDependencies,\n O extends GroupOutputShape,\n State = never,\n> = {\n readonly values: ProjectionValues<D>;\n readonly changes: ProjectionChanges<D>;\n readonly previous: GroupReads<O>;\n readonly next: GroupReads<O>;\n readonly output: GroupDrafts<O>;\n readonly reset: boolean;\n readonly cause: unknown;\n} & RetainedStateContext<State>;\n\ntype IncrementalGroupDefinition<\n D extends ProjectionDependencies,\n O extends GroupOutputShape,\n State = never,\n> = {\n readonly output: (define: GroupOutputBuilder) => O;\n readonly process: (context: IncrementalGroupContext<D, O, State>) => void;\n} & RetainedStateDefinition<State>;\n\nconst resetCollectionChange = Object.freeze({ kind: 'reset' as const });\n\nconst publicValue = (source: SourceContext): unknown =>\n source.kind === 'value' ? source.value : collectionView(source.read);\n\nconst compileDependencies = <D extends ProjectionDependencies>(dependencies: D) => {\n if (!isPlainObject(dependencies) || isProjection(dependencies))\n throw new TypeError('Incremental dependencies must be a plain object.');\n const names: string[] = [];\n const projections: Projection<unknown>[] = [];\n for (const key of Reflect.ownKeys(dependencies)) {\n if (typeof key !== 'string')\n throw new TypeError('Incremental dependency names must be strings.');\n const descriptor = Object.getOwnPropertyDescriptor(dependencies, key);\n if (!descriptor?.enumerable || !('value' in descriptor))\n throw new TypeError('Incremental dependencies must be enumerable data properties.');\n projectionRef(descriptor.value as Projection<unknown>);\n names.push(key);\n projections.push(descriptor.value as Projection<unknown>);\n }\n return Object.freeze({ names: Object.freeze(names), projections: Object.freeze(projections) });\n};\n\nconst publicInputs = (\n sources: readonly SourceContext[],\n names: readonly string[],\n reset: boolean\n): {\n readonly values: Readonly<Record<string, unknown>>;\n readonly changes: Readonly<Record<string, unknown>>;\n} => {\n const values: Record<string, unknown> = Object.create(null) as Record<string, unknown>;\n const changes: Record<string, unknown> = Object.create(null) as Record<string, unknown>;\n for (let index = 0; index < names.length; index++) {\n const source = sources[index];\n values[names[index]] = publicValue(source);\n changes[names[index]] =\n source.kind === 'collection' ? (reset ? resetCollectionChange : source.change) : undefined;\n }\n return Object.freeze({ values: Object.freeze(values), changes: Object.freeze(changes) });\n};\n\nfunction validateDefinition(\n definition: unknown,\n allowed: readonly string[],\n label: string\n): asserts definition is Record<string, unknown> {\n if (!isPlainObject(definition))\n throw new TypeError(`${label} definition must be a plain object.`);\n const allowedKeys = new Set(allowed);\n for (const key of Reflect.ownKeys(definition)) {\n if (typeof key !== 'string' || !allowedKeys.has(key))\n throw new TypeError(`${label} definition contains an unknown property.`);\n const descriptor = Object.getOwnPropertyDescriptor(definition, key);\n if (!descriptor?.enumerable || !('value' in descriptor))\n throw new TypeError(`${label} definition must contain enumerable data properties.`);\n }\n}\n\nconst validateRetainedState = (definition: Record<string, unknown>, label: string): void => {\n if (\n Object.prototype.hasOwnProperty.call(definition, 'state') &&\n typeof definition.state !== 'function'\n )\n throw new TypeError(`${label} state must be a function when provided.`);\n};\n\nconst initializeRetainedState = (definition: {\n readonly state?: () => unknown;\n}): Readonly<Record<string, unknown>> => {\n if (definition.state === undefined) return Object.freeze({});\n const state = definition.state();\n assertSynchronous(state);\n return Object.freeze({ state });\n};\n\ntype RuntimeIncrementalDefinition<Result> = {\n readonly state?: () => unknown;\n readonly process: (context: never) => Result;\n};\n\nfunction createIncrementalValue<const D extends ProjectionDependencies, T>(\n dependencies: D,\n definition: IncrementalValueDefinition<D, T>\n): Projection<T>;\nfunction createIncrementalValue<const D extends ProjectionDependencies, T, State>(\n dependencies: D,\n definition: {\n readonly state: () => State;\n readonly process: (context: IncrementalValueContext<D, T, State>) => T;\n }\n): Projection<T>;\nfunction createIncrementalValue<const D extends ProjectionDependencies, T>(\n dependencies: D,\n definition: RuntimeIncrementalDefinition<T>\n): Projection<T> {\n const compiled = compileDependencies(dependencies);\n validateDefinition(definition, ['state', 'process'], 'Incremental value');\n validateRetainedState(definition, 'Incremental value');\n if (typeof definition.process !== 'function')\n throw new TypeError('Incremental value definition requires a process function.');\n const [projection] = defineProcessor({\n dependencies: compiled.projections,\n outputs: [{ kind: 'value', equality: Object.is }],\n create: () => {\n const state = initializeRetainedState(definition);\n return {\n evaluate: evaluation => {\n const output = evaluation.outputs[0];\n if (output.kind !== 'value') throw new Error('Incremental value output is invalid.');\n const publicInput = publicInputs(evaluation.sources, compiled.names, evaluation.reset);\n const result = definition.process({\n values: publicInput.values as ProjectionValues<D>,\n changes: publicInput.changes as ProjectionChanges<D>,\n previous: output.previous as T | undefined,\n reset: evaluation.reset,\n cause: evaluation.cause,\n ...state,\n } as never);\n assertSynchronous(result);\n output.output.set(result);\n },\n };\n },\n });\n return projection as Projection<T>;\n}\n\nfunction createIncrementalCollection<const D extends ProjectionDependencies, K extends string, V>(\n dependencies: D,\n definition: IncrementalCollectionDefinition<D, K, V>\n): KeyedProjection<K, V>;\nfunction createIncrementalCollection<\n const D extends ProjectionDependencies,\n K extends string,\n V,\n State,\n>(\n dependencies: D,\n definition: {\n readonly state: () => State;\n readonly process: (context: IncrementalCollectionContext<D, K, V, State>) => void;\n }\n): KeyedProjection<K, V>;\nfunction createIncrementalCollection<const D extends ProjectionDependencies, K extends string, V>(\n dependencies: D,\n definition: RuntimeIncrementalDefinition<void>\n): KeyedProjection<K, V> {\n const compiled = compileDependencies(dependencies);\n validateDefinition(definition, ['state', 'process'], 'Incremental collection');\n validateRetainedState(definition, 'Incremental collection');\n if (typeof definition.process !== 'function')\n throw new TypeError('Incremental collection definition requires a process function.');\n const [projection] = defineProcessor({\n dependencies: compiled.projections,\n outputs: [{ kind: 'collection', equality: Object.is }],\n create: () => {\n const state = initializeRetainedState(definition);\n return {\n evaluate: evaluation => {\n const output = evaluation.outputs[0];\n if (output.kind !== 'collection')\n throw new Error('Incremental collection output is invalid.');\n const publicInput = publicInputs(evaluation.sources, compiled.names, evaluation.reset);\n const result = definition.process({\n values: publicInput.values as ProjectionValues<D>,\n changes: publicInput.changes as ProjectionChanges<D>,\n previous: output.previous as CollectionRead<K, V>,\n next: output.next as CollectionRead<K, V>,\n reset: evaluation.reset,\n cause: evaluation.cause,\n output: output.output as CollectionDraft<K, V>,\n ...state,\n } as never);\n assertSynchronous(result);\n },\n };\n },\n });\n return projection as KeyedProjection<K, V>;\n}\n\ntype GroupShape = number | { readonly [key: string]: GroupShape };\ntype GroupOutputMetadata = {\n readonly kind: OutputDefinition['kind'];\n readonly equality: (a: unknown, b: unknown) => boolean;\n};\n\nconst isPlainGroupNamespace = (\n value: unknown,\n metadata: ReadonlyMap<object, GroupOutputMetadata>\n): value is Record<string, unknown> => isPlainObject(value) && !metadata.has(value);\n\nconst compileGroupShape = (\n value: unknown,\n path: readonly string[],\n metadata: ReadonlyMap<object, GroupOutputMetadata>,\n used: Set<object>,\n outputs: OutputDefinition[]\n): GroupShape => {\n if (value !== null && typeof value === 'object') {\n const output = metadata.get(value);\n if (output) {\n if (used.has(value)) throw new TypeError('An incremental group output cannot be reused.');\n used.add(value);\n const index = outputs.length;\n outputs.push({\n kind: output.kind,\n equality: output.equality,\n path: Object.freeze([...path]),\n });\n return index;\n }\n }\n if (!isPlainGroupNamespace(value, metadata))\n throw new TypeError('Incremental group outputs must be a static object tree.');\n for (const key of Reflect.ownKeys(value)) {\n if (typeof key !== 'string')\n throw new TypeError('Incremental group output names must be strings.');\n if (!Object.prototype.propertyIsEnumerable.call(value, key))\n throw new TypeError('Incremental group namespaces must contain enumerable properties.');\n }\n const keys = Object.keys(value);\n if (!keys.length) throw new TypeError('Incremental group namespaces cannot be empty.');\n const result: Record<string, GroupShape> = Object.create(null) as Record<string, GroupShape>;\n for (const key of keys) {\n if (key === '__proto__' || key === 'prototype' || key === 'constructor')\n throw new TypeError(`Invalid incremental group output name: ${key}`);\n const descriptor = Object.getOwnPropertyDescriptor(value, key);\n if (!descriptor || !('value' in descriptor))\n throw new TypeError('Incremental group namespaces cannot contain accessors.');\n result[key] = compileGroupShape(descriptor.value, [...path, key], metadata, used, outputs);\n }\n return Object.freeze(result);\n};\n\nconst hydrateGroupShape = <T>(shape: GroupShape, values: readonly T[]): unknown => {\n if (typeof shape === 'number') return values[shape];\n const result: Record<string, unknown> = {};\n for (const [key, child] of Object.entries(shape)) result[key] = hydrateGroupShape(child, values);\n return Object.freeze(result);\n};\n\nconst hydrateGroupReads = (\n shape: GroupShape,\n outputs: readonly OutputEvaluation[],\n next: boolean\n): unknown => {\n if (typeof shape === 'number') {\n const output = outputs[shape];\n return next && output.kind === 'value' ? output.next() : next ? output.next : output.previous;\n }\n const result: Record<string, unknown> = {};\n for (const [key, child] of Object.entries(shape)) {\n if (typeof child === 'number' && next && outputs[child].kind === 'value') {\n Object.defineProperty(result, key, {\n enumerable: true,\n configurable: false,\n get: () => (outputs[child] as Extract<OutputEvaluation, { kind: 'value' }>).next(),\n });\n } else result[key] = hydrateGroupReads(child, outputs, next);\n }\n return Object.freeze(result);\n};\n\nfunction createIncrementalGroup<\n const D extends ProjectionDependencies,\n const O extends GroupOutputShape,\n>(dependencies: D, definition: IncrementalGroupDefinition<D, O>): IncrementalGroupResult<O>;\nfunction createIncrementalGroup<\n const D extends ProjectionDependencies,\n const O extends GroupOutputShape,\n State,\n>(\n dependencies: D,\n definition: {\n readonly output: (define: GroupOutputBuilder) => O;\n readonly state: () => State;\n readonly process: (context: IncrementalGroupContext<D, O, State>) => void;\n }\n): IncrementalGroupResult<O>;\nfunction createIncrementalGroup<\n const D extends ProjectionDependencies,\n const O extends GroupOutputShape,\n>(\n dependencies: D,\n definition: RuntimeIncrementalDefinition<void> & {\n readonly output: (define: GroupOutputBuilder) => O;\n }\n): IncrementalGroupResult<O> {\n const compiled = compileDependencies(dependencies);\n validateDefinition(definition, ['output', 'state', 'process'], 'Incremental group');\n validateRetainedState(definition, 'Incremental group');\n if (typeof definition.output !== 'function' || typeof definition.process !== 'function')\n throw new TypeError('Incremental group definition requires output and process functions.');\n\n let active = true;\n const metadata = new Map<object, GroupOutputMetadata>();\n const defineOutput: GroupOutputBuilder = {\n collection: <K extends string, V>(equality: (previous: V, next: V) => boolean = Object.is) => {\n if (!active) throw new TypeError('Incremental group output declarations are synchronous.');\n const descriptor = Object.freeze({});\n metadata.set(descriptor, {\n kind: 'collection',\n equality: equality as (a: unknown, b: unknown) => boolean,\n });\n return descriptor as IncrementalGroupOutput<KeyedProjection<K, V>>;\n },\n value: <T>(equality: (previous: T, next: T) => boolean = Object.is) => {\n if (!active) throw new TypeError('Incremental group output declarations are synchronous.');\n const descriptor = Object.freeze({});\n metadata.set(descriptor, {\n kind: 'value',\n equality: equality as (a: unknown, b: unknown) => boolean,\n });\n return descriptor as IncrementalGroupOutput<Projection<T>>;\n },\n };\n const declared = definition.output(defineOutput);\n assertSynchronous(declared);\n active = false;\n const outputs: OutputDefinition[] = [];\n const used = new Set<object>();\n const shape = compileGroupShape(declared, [], metadata, used, outputs);\n if (typeof shape === 'number')\n throw new TypeError('Incremental group declarations must return an output namespace.');\n if (used.size === 0 || used.size !== metadata.size)\n throw new TypeError('Every incremental group output must be returned by the declaration.');\n\n const projections = defineProcessor({\n dependencies: compiled.projections,\n outputs,\n create: () => {\n const state = initializeRetainedState(definition);\n return {\n evaluate: evaluation => {\n const publicInput = publicInputs(evaluation.sources, compiled.names, evaluation.reset);\n const result = definition.process({\n values: publicInput.values as ProjectionValues<D>,\n changes: publicInput.changes as ProjectionChanges<D>,\n previous: hydrateGroupReads(shape, evaluation.outputs, false) as GroupReads<O>,\n next: hydrateGroupReads(shape, evaluation.outputs, true) as GroupReads<O>,\n output: hydrateGroupShape(\n shape,\n evaluation.outputs.map(output => output.output)\n ) as GroupDrafts<O>,\n reset: evaluation.reset,\n cause: evaluation.cause,\n ...state,\n } as never);\n assertSynchronous(result);\n },\n };\n },\n name: `processor-group:${outputs.map(output => output.path?.join('.') ?? '').join(',')}`,\n });\n return hydrateGroupShape(shape, projections) as IncrementalGroupResult<O>;\n}\n\nexport const incremental = Object.assign(createIncrementalValue, {\n collection: createIncrementalCollection,\n group: createIncrementalGroup,\n});\n\nexport type { CollectionChange } from './contract';\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"advanced.cjs","names":["collectionView","isPlainObject","compileProjectionDependencies","defineProcessor","createKeyedTransform"],"sources":["../core/src/projection/advanced.ts"],"sourcesContent":["import { collectionView } from '@/projection/collection/view';\nimport type { CollectionChange, CollectionDraft, CollectionRead, SourceContext } from './contract';\nimport type {\n KeyedProjection,\n OutputDefinition,\n OutputEvaluation,\n Projection,\n ProjectionChange,\n} from './definition';\nimport { defineProcessor } from './definition';\nimport { compileProjectionDependencies } from './dependency';\nimport { assertSynchronous } from '@/projection/graph/scheduler';\nimport { isPlainObject } from '@/value/record';\nimport type {\n KeyedDependencies,\n KeyedDependencyRecord,\n KeyedDependencyValues,\n} from '@/projection/keyed/dependency';\nimport { createKeyedTransform } from '@/projection/keyed/transform';\n\ntype ProjectionDependencies = Readonly<Record<string, Projection<unknown>>>;\n\ntype ProjectionValues<D extends ProjectionDependencies> = {\n readonly [K in keyof D]: D[K] extends Projection<infer T> ? T : never;\n};\n\ntype ProjectionChanges<D extends ProjectionDependencies> = {\n readonly [K in keyof D]: ProjectionChange<D[K]> extends undefined\n ? undefined\n : ProjectionChange<D[K]> | undefined;\n};\n\ntype RetainedStateContext<State> = [State] extends [never] ? {} : { readonly state: State };\ntype RetainedStateDefinition<State> = [State] extends [never]\n ? { readonly state?: never }\n : { readonly state: () => State };\n\nexport type IncrementalValueContext<D extends ProjectionDependencies, T, State = never> = {\n readonly values: ProjectionValues<D>;\n readonly changes: ProjectionChanges<D>;\n readonly previous: T | undefined;\n readonly reset: boolean;\n readonly cause: unknown;\n} & RetainedStateContext<State>;\n\nexport type IncrementalValueDefinition<D extends ProjectionDependencies, T, State = never> = {\n readonly process: (context: IncrementalValueContext<D, T, State>) => T;\n} & RetainedStateDefinition<State>;\n\nexport type IncrementalCollectionContext<\n D extends ProjectionDependencies,\n K extends string,\n V,\n State = never,\n> = {\n readonly values: ProjectionValues<D>;\n readonly changes: ProjectionChanges<D>;\n readonly previous: CollectionRead<K, V>;\n readonly next: CollectionRead<K, V>;\n readonly reset: boolean;\n readonly cause: unknown;\n readonly output: CollectionDraft<K, V>;\n} & RetainedStateContext<State>;\n\nexport type IncrementalCollectionDefinition<\n D extends ProjectionDependencies,\n K extends string,\n V,\n State = never,\n> = {\n readonly process: (context: IncrementalCollectionContext<D, K, V, State>) => void;\n} & RetainedStateDefinition<State>;\n\nexport type IncrementalKeyedContext<K extends string, V, D extends object, State = never> = {\n readonly key: K;\n readonly value: V;\n readonly dependencies: KeyedDependencyValues<D>;\n readonly reset: boolean;\n readonly cause: unknown;\n} & RetainedStateContext<State>;\n\nexport type IncrementalKeyedDefinition<K extends string, V, D extends object, T, State = never> = {\n readonly equality?: (previous: T, next: T) => boolean;\n readonly process: (context: IncrementalKeyedContext<K, V, D, State>) => T;\n} & ([State] extends [never]\n ? { readonly state?: never }\n : { readonly state: (value: V, key: K) => State });\n\ndeclare const groupOutput: unique symbol;\n\n/** Type-only declaration token used by incremental.group output builders. */\nexport type IncrementalGroupOutput<P extends Projection<unknown>> = {\n readonly [groupOutput]: P;\n};\n\ntype GroupOutputShape = {\n readonly [name: string]: IncrementalGroupOutput<Projection<unknown>> | GroupOutputShape;\n};\n\ntype GroupOutputBuilder = {\n collection<K extends string, V>(\n equality?: (previous: V, next: V) => boolean\n ): IncrementalGroupOutput<KeyedProjection<K, V>>;\n value<T>(equality?: (previous: T, next: T) => boolean): IncrementalGroupOutput<Projection<T>>;\n};\n\n/** Portable projection tree returned from an incremental.group declaration. */\nexport type IncrementalGroupResult<O> =\n O extends IncrementalGroupOutput<infer P>\n ? P\n : O extends Readonly<Record<string, unknown>>\n ? { readonly [K in keyof O]: IncrementalGroupResult<O[K]> }\n : never;\n\ntype GroupReads<O> =\n O extends IncrementalGroupOutput<infer P>\n ? P extends KeyedProjection<infer K, infer V>\n ? CollectionRead<K, V>\n : P extends Projection<infer T>\n ? T | undefined\n : never\n : { readonly [K in keyof O]: GroupReads<O[K]> };\n\ntype GroupDrafts<O> =\n O extends IncrementalGroupOutput<infer P>\n ? P extends KeyedProjection<infer K, infer V>\n ? CollectionDraft<K, V>\n : P extends Projection<infer T>\n ? { set(value: T): void }\n : never\n : { readonly [K in keyof O]: GroupDrafts<O[K]> };\n\nexport type IncrementalGroupContext<\n D extends ProjectionDependencies,\n O extends GroupOutputShape,\n State = never,\n> = {\n readonly values: ProjectionValues<D>;\n readonly changes: ProjectionChanges<D>;\n readonly previous: GroupReads<O>;\n readonly next: GroupReads<O>;\n readonly output: GroupDrafts<O>;\n readonly reset: boolean;\n readonly cause: unknown;\n} & RetainedStateContext<State>;\n\ntype IncrementalGroupDefinition<\n D extends ProjectionDependencies,\n O extends GroupOutputShape,\n State = never,\n> = {\n readonly output: (define: GroupOutputBuilder) => O;\n readonly process: (context: IncrementalGroupContext<D, O, State>) => void;\n} & RetainedStateDefinition<State>;\n\nconst resetCollectionChange = Object.freeze({ kind: 'reset' as const });\n\nconst publicValue = (source: SourceContext): unknown =>\n source.kind === 'value' ? source.value : collectionView(source.read);\n\nconst publicInputs = (\n sources: readonly SourceContext[],\n names: readonly string[],\n reset: boolean\n): {\n readonly values: Readonly<Record<string, unknown>>;\n readonly changes: Readonly<Record<string, unknown>>;\n} => {\n const values: Record<string, unknown> = Object.create(null) as Record<string, unknown>;\n const changes: Record<string, unknown> = Object.create(null) as Record<string, unknown>;\n for (let index = 0; index < names.length; index++) {\n const source = sources[index];\n values[names[index]] = publicValue(source);\n changes[names[index]] =\n source.kind === 'collection' ? (reset ? resetCollectionChange : source.change) : undefined;\n }\n return Object.freeze({ values: Object.freeze(values), changes: Object.freeze(changes) });\n};\n\nfunction validateDefinition(\n definition: unknown,\n allowed: readonly string[],\n label: string\n): asserts definition is Record<string, unknown> {\n if (!isPlainObject(definition))\n throw new TypeError(`${label} definition must be a plain object.`);\n const allowedKeys = new Set(allowed);\n for (const key of Reflect.ownKeys(definition)) {\n if (typeof key !== 'string' || !allowedKeys.has(key))\n throw new TypeError(`${label} definition contains an unknown property.`);\n const descriptor = Object.getOwnPropertyDescriptor(definition, key);\n if (!descriptor?.enumerable || !('value' in descriptor))\n throw new TypeError(`${label} definition must contain enumerable data properties.`);\n }\n}\n\nconst validateRetainedState = (definition: Record<string, unknown>, label: string): void => {\n if (\n Object.prototype.hasOwnProperty.call(definition, 'state') &&\n typeof definition.state !== 'function'\n )\n throw new TypeError(`${label} state must be a function when provided.`);\n};\n\nconst initializeRetainedState = (definition: {\n readonly state?: () => unknown;\n}): Readonly<Record<string, unknown>> => {\n if (definition.state === undefined) return Object.freeze({});\n const state = definition.state();\n assertSynchronous(state);\n return Object.freeze({ state });\n};\n\ntype RuntimeIncrementalDefinition<Result> = {\n readonly state?: () => unknown;\n readonly process: (context: never) => Result;\n};\n\nfunction createIncrementalValue<const D extends ProjectionDependencies, T>(\n dependencies: D,\n definition: IncrementalValueDefinition<D, T>\n): Projection<T>;\nfunction createIncrementalValue<const D extends ProjectionDependencies, T, State>(\n dependencies: D,\n definition: {\n readonly state: () => State;\n readonly process: (context: IncrementalValueContext<D, T, State>) => T;\n }\n): Projection<T>;\nfunction createIncrementalValue<const D extends ProjectionDependencies, T>(\n dependencies: D,\n definition: RuntimeIncrementalDefinition<T>\n): Projection<T> {\n const compiled = compileProjectionDependencies(dependencies, 'Incremental');\n validateDefinition(definition, ['state', 'process'], 'Incremental value');\n validateRetainedState(definition, 'Incremental value');\n if (typeof definition.process !== 'function')\n throw new TypeError('Incremental value definition requires a process function.');\n const [projection] = defineProcessor({\n dependencies: compiled.projections,\n outputs: [{ kind: 'value', equality: Object.is }],\n create: () => {\n const state = initializeRetainedState(definition);\n return {\n evaluate: evaluation => {\n const output = evaluation.outputs[0];\n if (output.kind !== 'value') throw new Error('Incremental value output is invalid.');\n const publicInput = publicInputs(evaluation.sources, compiled.names, evaluation.reset);\n const result = definition.process({\n values: publicInput.values as ProjectionValues<D>,\n changes: publicInput.changes as ProjectionChanges<D>,\n previous: output.previous as T | undefined,\n reset: evaluation.reset,\n cause: evaluation.cause,\n ...state,\n } as never);\n assertSynchronous(result);\n output.output.set(result);\n },\n };\n },\n });\n return projection as Projection<T>;\n}\n\nfunction createIncrementalCollection<const D extends ProjectionDependencies, K extends string, V>(\n dependencies: D,\n definition: IncrementalCollectionDefinition<D, K, V>\n): KeyedProjection<K, V>;\nfunction createIncrementalCollection<\n const D extends ProjectionDependencies,\n K extends string,\n V,\n State,\n>(\n dependencies: D,\n definition: {\n readonly state: () => State;\n readonly process: (context: IncrementalCollectionContext<D, K, V, State>) => void;\n }\n): KeyedProjection<K, V>;\nfunction createIncrementalCollection<const D extends ProjectionDependencies, K extends string, V>(\n dependencies: D,\n definition: RuntimeIncrementalDefinition<void>\n): KeyedProjection<K, V> {\n const compiled = compileProjectionDependencies(dependencies, 'Incremental');\n validateDefinition(definition, ['state', 'process'], 'Incremental collection');\n validateRetainedState(definition, 'Incremental collection');\n if (typeof definition.process !== 'function')\n throw new TypeError('Incremental collection definition requires a process function.');\n const [projection] = defineProcessor({\n dependencies: compiled.projections,\n outputs: [{ kind: 'collection', equality: Object.is }],\n create: () => {\n const state = initializeRetainedState(definition);\n return {\n evaluate: evaluation => {\n const output = evaluation.outputs[0];\n if (output.kind !== 'collection')\n throw new Error('Incremental collection output is invalid.');\n const publicInput = publicInputs(evaluation.sources, compiled.names, evaluation.reset);\n const result = definition.process({\n values: publicInput.values as ProjectionValues<D>,\n changes: publicInput.changes as ProjectionChanges<D>,\n previous: output.previous as CollectionRead<K, V>,\n next: output.next as CollectionRead<K, V>,\n reset: evaluation.reset,\n cause: evaluation.cause,\n output: output.output as CollectionDraft<K, V>,\n ...state,\n } as never);\n assertSynchronous(result);\n },\n };\n },\n });\n return projection as KeyedProjection<K, V>;\n}\n\nfunction createIncrementalKeyed<K extends string, V, const D extends object, T, State>(\n driver: KeyedProjection<K, V>,\n dependencies: D & KeyedDependencies<NoInfer<K>, NoInfer<V>, D>,\n definition: {\n readonly state: (value: NoInfer<V>, key: NoInfer<K>) => State;\n readonly equality?: (previous: T, next: T) => boolean;\n readonly process: (context: IncrementalKeyedContext<NoInfer<K>, NoInfer<V>, D, State>) => T;\n }\n): KeyedProjection<K, T>;\nfunction createIncrementalKeyed<K extends string, V, const D extends object, T>(\n driver: KeyedProjection<K, V>,\n dependencies: D & KeyedDependencies<NoInfer<K>, NoInfer<V>, D>,\n definition: {\n readonly equality?: (previous: T, next: T) => boolean;\n readonly process: (context: IncrementalKeyedContext<NoInfer<K>, NoInfer<V>, D>) => T;\n }\n): KeyedProjection<K, T>;\nfunction createIncrementalKeyed<K extends string, V, T>(\n driver: KeyedProjection<K, V>,\n dependencies: KeyedDependencyRecord<K, V>,\n definition: {\n readonly state?: (value: V, key: K) => unknown;\n readonly equality?: (previous: T, next: T) => boolean;\n readonly process: (context: never) => T;\n }\n): KeyedProjection<K, T> {\n validateDefinition(definition, ['state', 'equality', 'process'], 'Incremental keyed');\n if (definition.state !== undefined && typeof definition.state !== 'function')\n throw new TypeError('Incremental keyed state must be a function when provided.');\n if (definition.equality !== undefined && typeof definition.equality !== 'function')\n throw new TypeError('Incremental keyed equality must be a function when provided.');\n if (typeof definition.process !== 'function')\n throw new TypeError('Incremental keyed definition requires a process function.');\n\n return createKeyedTransform<K, V, T, unknown>({\n source: driver,\n dependencies,\n equality: definition.equality,\n name: 'incremental.keyed',\n ...(definition.state ? { state: definition.state } : {}),\n evaluate: ({ key, value, dependencies: values, state, reset, cause }) =>\n definition.process({\n key,\n value,\n dependencies: values,\n reset,\n cause,\n ...(definition.state ? { state } : {}),\n } as never),\n });\n}\n\ntype GroupShape = number | { readonly [key: string]: GroupShape };\ntype GroupOutputMetadata = {\n readonly kind: OutputDefinition['kind'];\n readonly equality: (a: unknown, b: unknown) => boolean;\n};\n\nconst isPlainGroupNamespace = (\n value: unknown,\n metadata: ReadonlyMap<object, GroupOutputMetadata>\n): value is Record<string, unknown> => isPlainObject(value) && !metadata.has(value);\n\nconst compileGroupShape = (\n value: unknown,\n path: readonly string[],\n metadata: ReadonlyMap<object, GroupOutputMetadata>,\n used: Set<object>,\n outputs: OutputDefinition[]\n): GroupShape => {\n if (value !== null && typeof value === 'object') {\n const output = metadata.get(value);\n if (output) {\n if (used.has(value)) throw new TypeError('An incremental group output cannot be reused.');\n used.add(value);\n const index = outputs.length;\n outputs.push({\n kind: output.kind,\n equality: output.equality,\n path: Object.freeze([...path]),\n });\n return index;\n }\n }\n if (!isPlainGroupNamespace(value, metadata))\n throw new TypeError('Incremental group outputs must be a static object tree.');\n for (const key of Reflect.ownKeys(value)) {\n if (typeof key !== 'string')\n throw new TypeError('Incremental group output names must be strings.');\n if (!Object.prototype.propertyIsEnumerable.call(value, key))\n throw new TypeError('Incremental group namespaces must contain enumerable properties.');\n }\n const keys = Object.keys(value);\n if (!keys.length) throw new TypeError('Incremental group namespaces cannot be empty.');\n const result: Record<string, GroupShape> = Object.create(null) as Record<string, GroupShape>;\n for (const key of keys) {\n if (key === '__proto__' || key === 'prototype' || key === 'constructor')\n throw new TypeError(`Invalid incremental group output name: ${key}`);\n const descriptor = Object.getOwnPropertyDescriptor(value, key);\n if (!descriptor || !('value' in descriptor))\n throw new TypeError('Incremental group namespaces cannot contain accessors.');\n result[key] = compileGroupShape(descriptor.value, [...path, key], metadata, used, outputs);\n }\n return Object.freeze(result);\n};\n\nconst hydrateGroupShape = <T>(shape: GroupShape, values: readonly T[]): unknown => {\n if (typeof shape === 'number') return values[shape];\n const result: Record<string, unknown> = {};\n for (const [key, child] of Object.entries(shape)) result[key] = hydrateGroupShape(child, values);\n return Object.freeze(result);\n};\n\nconst hydrateGroupReads = (\n shape: GroupShape,\n outputs: readonly OutputEvaluation[],\n next: boolean\n): unknown => {\n if (typeof shape === 'number') {\n const output = outputs[shape];\n return next && output.kind === 'value' ? output.next() : next ? output.next : output.previous;\n }\n const result: Record<string, unknown> = {};\n for (const [key, child] of Object.entries(shape)) {\n if (typeof child === 'number' && next && outputs[child].kind === 'value') {\n Object.defineProperty(result, key, {\n enumerable: true,\n configurable: false,\n get: () => (outputs[child] as Extract<OutputEvaluation, { kind: 'value' }>).next(),\n });\n } else result[key] = hydrateGroupReads(child, outputs, next);\n }\n return Object.freeze(result);\n};\n\nfunction createIncrementalGroup<\n const D extends ProjectionDependencies,\n const O extends GroupOutputShape,\n>(dependencies: D, definition: IncrementalGroupDefinition<D, O>): IncrementalGroupResult<O>;\nfunction createIncrementalGroup<\n const D extends ProjectionDependencies,\n const O extends GroupOutputShape,\n State,\n>(\n dependencies: D,\n definition: {\n readonly output: (define: GroupOutputBuilder) => O;\n readonly state: () => State;\n readonly process: (context: IncrementalGroupContext<D, O, State>) => void;\n }\n): IncrementalGroupResult<O>;\nfunction createIncrementalGroup<\n const D extends ProjectionDependencies,\n const O extends GroupOutputShape,\n>(\n dependencies: D,\n definition: RuntimeIncrementalDefinition<void> & {\n readonly output: (define: GroupOutputBuilder) => O;\n }\n): IncrementalGroupResult<O> {\n const compiled = compileProjectionDependencies(dependencies, 'Incremental');\n validateDefinition(definition, ['output', 'state', 'process'], 'Incremental group');\n validateRetainedState(definition, 'Incremental group');\n if (typeof definition.output !== 'function' || typeof definition.process !== 'function')\n throw new TypeError('Incremental group definition requires output and process functions.');\n\n let active = true;\n const metadata = new Map<object, GroupOutputMetadata>();\n const defineOutput: GroupOutputBuilder = {\n collection: <K extends string, V>(equality: (previous: V, next: V) => boolean = Object.is) => {\n if (!active) throw new TypeError('Incremental group output declarations are synchronous.');\n const descriptor = Object.freeze({});\n metadata.set(descriptor, {\n kind: 'collection',\n equality: equality as (a: unknown, b: unknown) => boolean,\n });\n return descriptor as IncrementalGroupOutput<KeyedProjection<K, V>>;\n },\n value: <T>(equality: (previous: T, next: T) => boolean = Object.is) => {\n if (!active) throw new TypeError('Incremental group output declarations are synchronous.');\n const descriptor = Object.freeze({});\n metadata.set(descriptor, {\n kind: 'value',\n equality: equality as (a: unknown, b: unknown) => boolean,\n });\n return descriptor as IncrementalGroupOutput<Projection<T>>;\n },\n };\n const declared = definition.output(defineOutput);\n assertSynchronous(declared);\n active = false;\n const outputs: OutputDefinition[] = [];\n const used = new Set<object>();\n const shape = compileGroupShape(declared, [], metadata, used, outputs);\n if (typeof shape === 'number')\n throw new TypeError('Incremental group declarations must return an output namespace.');\n if (used.size === 0 || used.size !== metadata.size)\n throw new TypeError('Every incremental group output must be returned by the declaration.');\n\n const projections = defineProcessor({\n dependencies: compiled.projections,\n outputs,\n create: () => {\n const state = initializeRetainedState(definition);\n return {\n evaluate: evaluation => {\n const publicInput = publicInputs(evaluation.sources, compiled.names, evaluation.reset);\n const result = definition.process({\n values: publicInput.values as ProjectionValues<D>,\n changes: publicInput.changes as ProjectionChanges<D>,\n previous: hydrateGroupReads(shape, evaluation.outputs, false) as GroupReads<O>,\n next: hydrateGroupReads(shape, evaluation.outputs, true) as GroupReads<O>,\n output: hydrateGroupShape(\n shape,\n evaluation.outputs.map(output => output.output)\n ) as GroupDrafts<O>,\n reset: evaluation.reset,\n cause: evaluation.cause,\n ...state,\n } as never);\n assertSynchronous(result);\n },\n };\n },\n name: `processor-group:${outputs.map(output => output.path?.join('.') ?? '').join(',')}`,\n });\n return hydrateGroupShape(shape, projections) as IncrementalGroupResult<O>;\n}\n\nexport const incremental = Object.assign(createIncrementalValue, {\n collection: createIncrementalCollection,\n keyed: createIncrementalKeyed,\n group: createIncrementalGroup,\n});\n\nexport { collectionChange } from '@/projection/collection/change';\nexport type { CollectionChange } from './contract';\n"],"mappings":";;;;AA2JA,MAAM,wBAAwB,OAAO,OAAO,EAAE,MAAM,SAAkB,CAAC;AAEvE,MAAM,eAAe,WACnB,OAAO,SAAS,UAAU,OAAO,QAAQA,kBAAAA,eAAe,OAAO,KAAK;AAEtE,MAAM,gBACJ,SACA,OACA,UAIG;CACH,MAAM,SAAkC,OAAO,OAAO,KAAK;CAC3D,MAAM,UAAmC,OAAO,OAAO,KAAK;AAC5D,MAAK,IAAI,QAAQ,GAAG,QAAQ,MAAM,QAAQ,SAAS;EACjD,MAAM,SAAS,QAAQ;AACvB,SAAO,MAAM,UAAU,YAAY,OAAO;AAC1C,UAAQ,MAAM,UACZ,OAAO,SAAS,eAAgB,QAAQ,wBAAwB,OAAO,SAAU,KAAA;;AAErF,QAAO,OAAO,OAAO;EAAE,QAAQ,OAAO,OAAO,OAAO;EAAE,SAAS,OAAO,OAAO,QAAQ;EAAE,CAAC;;AAG1F,SAAS,mBACP,YACA,SACA,OAC+C;AAC/C,KAAI,CAACC,eAAAA,cAAc,WAAW,CAC5B,OAAM,IAAI,UAAU,GAAG,MAAM,qCAAqC;CACpE,MAAM,cAAc,IAAI,IAAI,QAAQ;AACpC,MAAK,MAAM,OAAO,QAAQ,QAAQ,WAAW,EAAE;AAC7C,MAAI,OAAO,QAAQ,YAAY,CAAC,YAAY,IAAI,IAAI,CAClD,OAAM,IAAI,UAAU,GAAG,MAAM,2CAA2C;EAC1E,MAAM,aAAa,OAAO,yBAAyB,YAAY,IAAI;AACnE,MAAI,CAAC,YAAY,cAAc,EAAE,WAAW,YAC1C,OAAM,IAAI,UAAU,GAAG,MAAM,sDAAsD;;;AAIzF,MAAM,yBAAyB,YAAqC,UAAwB;AAC1F,KACE,OAAO,UAAU,eAAe,KAAK,YAAY,QAAQ,IACzD,OAAO,WAAW,UAAU,WAE5B,OAAM,IAAI,UAAU,GAAG,MAAM,0CAA0C;;AAG3E,MAAM,2BAA2B,eAEQ;AACvC,KAAI,WAAW,UAAU,KAAA,EAAW,QAAO,OAAO,OAAO,EAAE,CAAC;CAC5D,MAAM,QAAQ,WAAW,OAAO;AAChC,mBAAA,kBAAkB,MAAM;AACxB,QAAO,OAAO,OAAO,EAAE,OAAO,CAAC;;AAmBjC,SAAS,uBACP,cACA,YACe;CACf,MAAM,WAAWC,kBAAAA,8BAA8B,cAAc,cAAc;AAC3E,oBAAmB,YAAY,CAAC,SAAS,UAAU,EAAE,oBAAoB;AACzE,uBAAsB,YAAY,oBAAoB;AACtD,KAAI,OAAO,WAAW,YAAY,WAChC,OAAM,IAAI,UAAU,4DAA4D;CAClF,MAAM,CAAC,cAAcC,kBAAAA,gBAAgB;EACnC,cAAc,SAAS;EACvB,SAAS,CAAC;GAAE,MAAM;GAAS,UAAU,OAAO;GAAI,CAAC;EACjD,cAAc;GACZ,MAAM,QAAQ,wBAAwB,WAAW;AACjD,UAAO,EACL,WAAU,eAAc;IACtB,MAAM,SAAS,WAAW,QAAQ;AAClC,QAAI,OAAO,SAAS,QAAS,OAAM,IAAI,MAAM,uCAAuC;IACpF,MAAM,cAAc,aAAa,WAAW,SAAS,SAAS,OAAO,WAAW,MAAM;IACtF,MAAM,SAAS,WAAW,QAAQ;KAChC,QAAQ,YAAY;KACpB,SAAS,YAAY;KACrB,UAAU,OAAO;KACjB,OAAO,WAAW;KAClB,OAAO,WAAW;KAClB,GAAG;KACJ,CAAU;AACX,sBAAA,kBAAkB,OAAO;AACzB,WAAO,OAAO,IAAI,OAAO;MAE5B;;EAEJ,CAAC;AACF,QAAO;;AAmBT,SAAS,4BACP,cACA,YACuB;CACvB,MAAM,WAAWD,kBAAAA,8BAA8B,cAAc,cAAc;AAC3E,oBAAmB,YAAY,CAAC,SAAS,UAAU,EAAE,yBAAyB;AAC9E,uBAAsB,YAAY,yBAAyB;AAC3D,KAAI,OAAO,WAAW,YAAY,WAChC,OAAM,IAAI,UAAU,iEAAiE;CACvF,MAAM,CAAC,cAAcC,kBAAAA,gBAAgB;EACnC,cAAc,SAAS;EACvB,SAAS,CAAC;GAAE,MAAM;GAAc,UAAU,OAAO;GAAI,CAAC;EACtD,cAAc;GACZ,MAAM,QAAQ,wBAAwB,WAAW;AACjD,UAAO,EACL,WAAU,eAAc;IACtB,MAAM,SAAS,WAAW,QAAQ;AAClC,QAAI,OAAO,SAAS,aAClB,OAAM,IAAI,MAAM,4CAA4C;IAC9D,MAAM,cAAc,aAAa,WAAW,SAAS,SAAS,OAAO,WAAW,MAAM;AAWtF,sBAAA,kBAVe,WAAW,QAAQ;KAChC,QAAQ,YAAY;KACpB,SAAS,YAAY;KACrB,UAAU,OAAO;KACjB,MAAM,OAAO;KACb,OAAO,WAAW;KAClB,OAAO,WAAW;KAClB,QAAQ,OAAO;KACf,GAAG;KACJ,CACuB,CAAC;MAE5B;;EAEJ,CAAC;AACF,QAAO;;AAoBT,SAAS,uBACP,QACA,cACA,YAKuB;AACvB,oBAAmB,YAAY;EAAC;EAAS;EAAY;EAAU,EAAE,oBAAoB;AACrF,KAAI,WAAW,UAAU,KAAA,KAAa,OAAO,WAAW,UAAU,WAChE,OAAM,IAAI,UAAU,4DAA4D;AAClF,KAAI,WAAW,aAAa,KAAA,KAAa,OAAO,WAAW,aAAa,WACtE,OAAM,IAAI,UAAU,+DAA+D;AACrF,KAAI,OAAO,WAAW,YAAY,WAChC,OAAM,IAAI,UAAU,4DAA4D;AAElF,QAAOC,kBAAAA,qBAAuC;EAC5C,QAAQ;EACR;EACA,UAAU,WAAW;EACrB,MAAM;EACN,GAAI,WAAW,QAAQ,EAAE,OAAO,WAAW,OAAO,GAAG,EAAE;EACvD,WAAW,EAAE,KAAK,OAAO,cAAc,QAAQ,OAAO,OAAO,YAC3D,WAAW,QAAQ;GACjB;GACA;GACA,cAAc;GACd;GACA;GACA,GAAI,WAAW,QAAQ,EAAE,OAAO,GAAG,EAAE;GACtC,CAAU;EACd,CAAC;;AASJ,MAAM,yBACJ,OACA,aACqCH,eAAAA,cAAc,MAAM,IAAI,CAAC,SAAS,IAAI,MAAM;AAEnF,MAAM,qBACJ,OACA,MACA,UACA,MACA,YACe;AACf,KAAI,UAAU,QAAQ,OAAO,UAAU,UAAU;EAC/C,MAAM,SAAS,SAAS,IAAI,MAAM;AAClC,MAAI,QAAQ;AACV,OAAI,KAAK,IAAI,MAAM,CAAE,OAAM,IAAI,UAAU,gDAAgD;AACzF,QAAK,IAAI,MAAM;GACf,MAAM,QAAQ,QAAQ;AACtB,WAAQ,KAAK;IACX,MAAM,OAAO;IACb,UAAU,OAAO;IACjB,MAAM,OAAO,OAAO,CAAC,GAAG,KAAK,CAAC;IAC/B,CAAC;AACF,UAAO;;;AAGX,KAAI,CAAC,sBAAsB,OAAO,SAAS,CACzC,OAAM,IAAI,UAAU,0DAA0D;AAChF,MAAK,MAAM,OAAO,QAAQ,QAAQ,MAAM,EAAE;AACxC,MAAI,OAAO,QAAQ,SACjB,OAAM,IAAI,UAAU,kDAAkD;AACxE,MAAI,CAAC,OAAO,UAAU,qBAAqB,KAAK,OAAO,IAAI,CACzD,OAAM,IAAI,UAAU,mEAAmE;;CAE3F,MAAM,OAAO,OAAO,KAAK,MAAM;AAC/B,KAAI,CAAC,KAAK,OAAQ,OAAM,IAAI,UAAU,gDAAgD;CACtF,MAAM,SAAqC,OAAO,OAAO,KAAK;AAC9D,MAAK,MAAM,OAAO,MAAM;AACtB,MAAI,QAAQ,eAAe,QAAQ,eAAe,QAAQ,cACxD,OAAM,IAAI,UAAU,0CAA0C,MAAM;EACtE,MAAM,aAAa,OAAO,yBAAyB,OAAO,IAAI;AAC9D,MAAI,CAAC,cAAc,EAAE,WAAW,YAC9B,OAAM,IAAI,UAAU,yDAAyD;AAC/E,SAAO,OAAO,kBAAkB,WAAW,OAAO,CAAC,GAAG,MAAM,IAAI,EAAE,UAAU,MAAM,QAAQ;;AAE5F,QAAO,OAAO,OAAO,OAAO;;AAG9B,MAAM,qBAAwB,OAAmB,WAAkC;AACjF,KAAI,OAAO,UAAU,SAAU,QAAO,OAAO;CAC7C,MAAM,SAAkC,EAAE;AAC1C,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,MAAM,CAAE,QAAO,OAAO,kBAAkB,OAAO,OAAO;AAChG,QAAO,OAAO,OAAO,OAAO;;AAG9B,MAAM,qBACJ,OACA,SACA,SACY;AACZ,KAAI,OAAO,UAAU,UAAU;EAC7B,MAAM,SAAS,QAAQ;AACvB,SAAO,QAAQ,OAAO,SAAS,UAAU,OAAO,MAAM,GAAG,OAAO,OAAO,OAAO,OAAO;;CAEvF,MAAM,SAAkC,EAAE;AAC1C,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,MAAM,CAC9C,KAAI,OAAO,UAAU,YAAY,QAAQ,QAAQ,OAAO,SAAS,QAC/D,QAAO,eAAe,QAAQ,KAAK;EACjC,YAAY;EACZ,cAAc;EACd,WAAY,QAAQ,OAAwD,MAAM;EACnF,CAAC;KACG,QAAO,OAAO,kBAAkB,OAAO,SAAS,KAAK;AAE9D,QAAO,OAAO,OAAO,OAAO;;AAmB9B,SAAS,uBAIP,cACA,YAG2B;CAC3B,MAAM,WAAWC,kBAAAA,8BAA8B,cAAc,cAAc;AAC3E,oBAAmB,YAAY;EAAC;EAAU;EAAS;EAAU,EAAE,oBAAoB;AACnF,uBAAsB,YAAY,oBAAoB;AACtD,KAAI,OAAO,WAAW,WAAW,cAAc,OAAO,WAAW,YAAY,WAC3E,OAAM,IAAI,UAAU,sEAAsE;CAE5F,IAAI,SAAS;CACb,MAAM,2BAAW,IAAI,KAAkC;CAqBvD,MAAM,WAAW,WAAW,OAAO;EAnBjC,aAAkC,WAA8C,OAAO,OAAO;AAC5F,OAAI,CAAC,OAAQ,OAAM,IAAI,UAAU,yDAAyD;GAC1F,MAAM,aAAa,OAAO,OAAO,EAAE,CAAC;AACpC,YAAS,IAAI,YAAY;IACvB,MAAM;IACI;IACX,CAAC;AACF,UAAO;;EAET,QAAW,WAA8C,OAAO,OAAO;AACrE,OAAI,CAAC,OAAQ,OAAM,IAAI,UAAU,yDAAyD;GAC1F,MAAM,aAAa,OAAO,OAAO,EAAE,CAAC;AACpC,YAAS,IAAI,YAAY;IACvB,MAAM;IACI;IACX,CAAC;AACF,UAAO;;EAGoC,CAAC;AAChD,mBAAA,kBAAkB,SAAS;AAC3B,UAAS;CACT,MAAM,UAA8B,EAAE;CACtC,MAAM,uBAAO,IAAI,KAAa;CAC9B,MAAM,QAAQ,kBAAkB,UAAU,EAAE,EAAE,UAAU,MAAM,QAAQ;AACtE,KAAI,OAAO,UAAU,SACnB,OAAM,IAAI,UAAU,kEAAkE;AACxF,KAAI,KAAK,SAAS,KAAK,KAAK,SAAS,SAAS,KAC5C,OAAM,IAAI,UAAU,sEAAsE;AA6B5F,QAAO,kBAAkB,OA3BLC,kBAAAA,gBAAgB;EAClC,cAAc,SAAS;EACvB;EACA,cAAc;GACZ,MAAM,QAAQ,wBAAwB,WAAW;AACjD,UAAO,EACL,WAAU,eAAc;IACtB,MAAM,cAAc,aAAa,WAAW,SAAS,SAAS,OAAO,WAAW,MAAM;AActF,sBAAA,kBAbe,WAAW,QAAQ;KAChC,QAAQ,YAAY;KACpB,SAAS,YAAY;KACrB,UAAU,kBAAkB,OAAO,WAAW,SAAS,MAAM;KAC7D,MAAM,kBAAkB,OAAO,WAAW,SAAS,KAAK;KACxD,QAAQ,kBACN,OACA,WAAW,QAAQ,KAAI,WAAU,OAAO,OAAO,CAChD;KACD,OAAO,WAAW;KAClB,OAAO,WAAW;KAClB,GAAG;KACJ,CACuB,CAAC;MAE5B;;EAEH,MAAM,mBAAmB,QAAQ,KAAI,WAAU,OAAO,MAAM,KAAK,IAAI,IAAI,GAAG,CAAC,KAAK,IAAI;EACvF,CAC0C,CAAC;;AAG9C,MAAa,cAAc,OAAO,OAAO,wBAAwB;CAC/D,YAAY;CACZ,OAAO;CACP,OAAO;CACR,CAAC"}
|
package/dist/advanced.d.cts
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { c as ProjectionChange, d as CollectionRead, l as CollectionChange, n as KeyedDependencyValues, o as KeyedProjection, s as Projection, t as KeyedDependencies, u as CollectionDraft } from "./dependency-B3E65M1E.cjs";
|
|
2
2
|
|
|
3
|
+
//#region core/src/projection/collection/change.d.ts
|
|
4
|
+
declare const collectionChange: {
|
|
5
|
+
readonly keys: <K extends string, V>(change: Extract<CollectionChange<K, V>, {
|
|
6
|
+
readonly kind: 'incremental';
|
|
7
|
+
}>) => Iterable<K>;
|
|
8
|
+
};
|
|
9
|
+
//#endregion
|
|
3
10
|
//#region core/src/projection/advanced.d.ts
|
|
4
11
|
type ProjectionDependencies = Readonly<Record<string, Projection<unknown>>>;
|
|
5
12
|
type ProjectionValues<D extends ProjectionDependencies> = { readonly [K in keyof D]: D[K] extends Projection<infer T> ? T : never };
|
|
@@ -34,6 +41,21 @@ type IncrementalCollectionContext<D extends ProjectionDependencies, K extends st
|
|
|
34
41
|
type IncrementalCollectionDefinition<D extends ProjectionDependencies, K extends string, V, State = never> = {
|
|
35
42
|
readonly process: (context: IncrementalCollectionContext<D, K, V, State>) => void;
|
|
36
43
|
} & RetainedStateDefinition<State>;
|
|
44
|
+
type IncrementalKeyedContext<K extends string, V, D extends object, State = never> = {
|
|
45
|
+
readonly key: K;
|
|
46
|
+
readonly value: V;
|
|
47
|
+
readonly dependencies: KeyedDependencyValues<D>;
|
|
48
|
+
readonly reset: boolean;
|
|
49
|
+
readonly cause: unknown;
|
|
50
|
+
} & RetainedStateContext<State>;
|
|
51
|
+
type IncrementalKeyedDefinition<K extends string, V, D extends object, T, State = never> = {
|
|
52
|
+
readonly equality?: (previous: T, next: T) => boolean;
|
|
53
|
+
readonly process: (context: IncrementalKeyedContext<K, V, D, State>) => T;
|
|
54
|
+
} & ([State] extends [never] ? {
|
|
55
|
+
readonly state?: never;
|
|
56
|
+
} : {
|
|
57
|
+
readonly state: (value: V, key: K) => State;
|
|
58
|
+
});
|
|
37
59
|
declare const groupOutput: unique symbol;
|
|
38
60
|
/** Type-only declaration token used by incremental.group output builders. */
|
|
39
61
|
type IncrementalGroupOutput<P extends Projection<unknown>> = {
|
|
@@ -75,6 +97,15 @@ declare function createIncrementalCollection<const D extends ProjectionDependenc
|
|
|
75
97
|
readonly state: () => State;
|
|
76
98
|
readonly process: (context: IncrementalCollectionContext<D, K, V, State>) => void;
|
|
77
99
|
}): KeyedProjection<K, V>;
|
|
100
|
+
declare function createIncrementalKeyed<K extends string, V, const D extends object, T, State>(driver: KeyedProjection<K, V>, dependencies: D & KeyedDependencies<NoInfer<K>, NoInfer<V>, D>, definition: {
|
|
101
|
+
readonly state: (value: NoInfer<V>, key: NoInfer<K>) => State;
|
|
102
|
+
readonly equality?: (previous: T, next: T) => boolean;
|
|
103
|
+
readonly process: (context: IncrementalKeyedContext<NoInfer<K>, NoInfer<V>, D, State>) => T;
|
|
104
|
+
}): KeyedProjection<K, T>;
|
|
105
|
+
declare function createIncrementalKeyed<K extends string, V, const D extends object, T>(driver: KeyedProjection<K, V>, dependencies: D & KeyedDependencies<NoInfer<K>, NoInfer<V>, D>, definition: {
|
|
106
|
+
readonly equality?: (previous: T, next: T) => boolean;
|
|
107
|
+
readonly process: (context: IncrementalKeyedContext<NoInfer<K>, NoInfer<V>, D>) => T;
|
|
108
|
+
}): KeyedProjection<K, T>;
|
|
78
109
|
declare function createIncrementalGroup<const D extends ProjectionDependencies, const O extends GroupOutputShape>(dependencies: D, definition: IncrementalGroupDefinition<D, O>): IncrementalGroupResult<O>;
|
|
79
110
|
declare function createIncrementalGroup<const D extends ProjectionDependencies, const O extends GroupOutputShape, State>(dependencies: D, definition: {
|
|
80
111
|
readonly output: (define: GroupOutputBuilder) => O;
|
|
@@ -83,8 +114,9 @@ declare function createIncrementalGroup<const D extends ProjectionDependencies,
|
|
|
83
114
|
}): IncrementalGroupResult<O>;
|
|
84
115
|
declare const incremental: typeof createIncrementalValue & {
|
|
85
116
|
collection: typeof createIncrementalCollection;
|
|
117
|
+
keyed: typeof createIncrementalKeyed;
|
|
86
118
|
group: typeof createIncrementalGroup;
|
|
87
119
|
};
|
|
88
120
|
//#endregion
|
|
89
|
-
export { type CollectionChange, IncrementalCollectionContext, IncrementalCollectionDefinition, IncrementalGroupContext, IncrementalGroupOutput, IncrementalGroupResult, IncrementalValueContext, IncrementalValueDefinition, incremental };
|
|
121
|
+
export { type CollectionChange, IncrementalCollectionContext, IncrementalCollectionDefinition, IncrementalGroupContext, IncrementalGroupOutput, IncrementalGroupResult, IncrementalKeyedContext, IncrementalKeyedDefinition, IncrementalValueContext, IncrementalValueDefinition, collectionChange, incremental };
|
|
90
122
|
//# sourceMappingURL=advanced.d.cts.map
|
package/dist/advanced.d.ts
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { c as ProjectionChange, d as CollectionRead, l as CollectionChange, n as KeyedDependencyValues, o as KeyedProjection, s as Projection, t as KeyedDependencies, u as CollectionDraft } from "./dependency-BYbdDHNa.js";
|
|
2
2
|
|
|
3
|
+
//#region core/src/projection/collection/change.d.ts
|
|
4
|
+
declare const collectionChange: {
|
|
5
|
+
readonly keys: <K extends string, V>(change: Extract<CollectionChange<K, V>, {
|
|
6
|
+
readonly kind: 'incremental';
|
|
7
|
+
}>) => Iterable<K>;
|
|
8
|
+
};
|
|
9
|
+
//#endregion
|
|
3
10
|
//#region core/src/projection/advanced.d.ts
|
|
4
11
|
type ProjectionDependencies = Readonly<Record<string, Projection<unknown>>>;
|
|
5
12
|
type ProjectionValues<D extends ProjectionDependencies> = { readonly [K in keyof D]: D[K] extends Projection<infer T> ? T : never };
|
|
@@ -34,6 +41,21 @@ type IncrementalCollectionContext<D extends ProjectionDependencies, K extends st
|
|
|
34
41
|
type IncrementalCollectionDefinition<D extends ProjectionDependencies, K extends string, V, State = never> = {
|
|
35
42
|
readonly process: (context: IncrementalCollectionContext<D, K, V, State>) => void;
|
|
36
43
|
} & RetainedStateDefinition<State>;
|
|
44
|
+
type IncrementalKeyedContext<K extends string, V, D extends object, State = never> = {
|
|
45
|
+
readonly key: K;
|
|
46
|
+
readonly value: V;
|
|
47
|
+
readonly dependencies: KeyedDependencyValues<D>;
|
|
48
|
+
readonly reset: boolean;
|
|
49
|
+
readonly cause: unknown;
|
|
50
|
+
} & RetainedStateContext<State>;
|
|
51
|
+
type IncrementalKeyedDefinition<K extends string, V, D extends object, T, State = never> = {
|
|
52
|
+
readonly equality?: (previous: T, next: T) => boolean;
|
|
53
|
+
readonly process: (context: IncrementalKeyedContext<K, V, D, State>) => T;
|
|
54
|
+
} & ([State] extends [never] ? {
|
|
55
|
+
readonly state?: never;
|
|
56
|
+
} : {
|
|
57
|
+
readonly state: (value: V, key: K) => State;
|
|
58
|
+
});
|
|
37
59
|
declare const groupOutput: unique symbol;
|
|
38
60
|
/** Type-only declaration token used by incremental.group output builders. */
|
|
39
61
|
type IncrementalGroupOutput<P extends Projection<unknown>> = {
|
|
@@ -75,6 +97,15 @@ declare function createIncrementalCollection<const D extends ProjectionDependenc
|
|
|
75
97
|
readonly state: () => State;
|
|
76
98
|
readonly process: (context: IncrementalCollectionContext<D, K, V, State>) => void;
|
|
77
99
|
}): KeyedProjection<K, V>;
|
|
100
|
+
declare function createIncrementalKeyed<K extends string, V, const D extends object, T, State>(driver: KeyedProjection<K, V>, dependencies: D & KeyedDependencies<NoInfer<K>, NoInfer<V>, D>, definition: {
|
|
101
|
+
readonly state: (value: NoInfer<V>, key: NoInfer<K>) => State;
|
|
102
|
+
readonly equality?: (previous: T, next: T) => boolean;
|
|
103
|
+
readonly process: (context: IncrementalKeyedContext<NoInfer<K>, NoInfer<V>, D, State>) => T;
|
|
104
|
+
}): KeyedProjection<K, T>;
|
|
105
|
+
declare function createIncrementalKeyed<K extends string, V, const D extends object, T>(driver: KeyedProjection<K, V>, dependencies: D & KeyedDependencies<NoInfer<K>, NoInfer<V>, D>, definition: {
|
|
106
|
+
readonly equality?: (previous: T, next: T) => boolean;
|
|
107
|
+
readonly process: (context: IncrementalKeyedContext<NoInfer<K>, NoInfer<V>, D>) => T;
|
|
108
|
+
}): KeyedProjection<K, T>;
|
|
78
109
|
declare function createIncrementalGroup<const D extends ProjectionDependencies, const O extends GroupOutputShape>(dependencies: D, definition: IncrementalGroupDefinition<D, O>): IncrementalGroupResult<O>;
|
|
79
110
|
declare function createIncrementalGroup<const D extends ProjectionDependencies, const O extends GroupOutputShape, State>(dependencies: D, definition: {
|
|
80
111
|
readonly output: (define: GroupOutputBuilder) => O;
|
|
@@ -83,8 +114,9 @@ declare function createIncrementalGroup<const D extends ProjectionDependencies,
|
|
|
83
114
|
}): IncrementalGroupResult<O>;
|
|
84
115
|
declare const incremental: typeof createIncrementalValue & {
|
|
85
116
|
collection: typeof createIncrementalCollection;
|
|
117
|
+
keyed: typeof createIncrementalKeyed;
|
|
86
118
|
group: typeof createIncrementalGroup;
|
|
87
119
|
};
|
|
88
120
|
//#endregion
|
|
89
|
-
export { type CollectionChange, IncrementalCollectionContext, IncrementalCollectionDefinition, IncrementalGroupContext, IncrementalGroupOutput, IncrementalGroupResult, IncrementalValueContext, IncrementalValueDefinition, incremental };
|
|
121
|
+
export { type CollectionChange, IncrementalCollectionContext, IncrementalCollectionDefinition, IncrementalGroupContext, IncrementalGroupOutput, IncrementalGroupResult, IncrementalKeyedContext, IncrementalKeyedDefinition, IncrementalValueContext, IncrementalValueDefinition, collectionChange, incremental };
|
|
90
122
|
//# sourceMappingURL=advanced.d.ts.map
|
package/dist/advanced.js
CHANGED
|
@@ -1,25 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { S as defineProcessor, _ as compileProjectionDependencies, l as assertSynchronous, p as collectionChange, t as createKeyedTransform, y as collectionView } from "./transform-B4T3AcJr.js";
|
|
2
2
|
import { n as isPlainObject } from "./record-B2yRhYsc.js";
|
|
3
3
|
//#region core/src/projection/advanced.ts
|
|
4
4
|
const resetCollectionChange = Object.freeze({ kind: "reset" });
|
|
5
5
|
const publicValue = (source) => source.kind === "value" ? source.value : collectionView(source.read);
|
|
6
|
-
const compileDependencies = (dependencies) => {
|
|
7
|
-
if (!isPlainObject(dependencies) || isProjection(dependencies)) throw new TypeError("Incremental dependencies must be a plain object.");
|
|
8
|
-
const names = [];
|
|
9
|
-
const projections = [];
|
|
10
|
-
for (const key of Reflect.ownKeys(dependencies)) {
|
|
11
|
-
if (typeof key !== "string") throw new TypeError("Incremental dependency names must be strings.");
|
|
12
|
-
const descriptor = Object.getOwnPropertyDescriptor(dependencies, key);
|
|
13
|
-
if (!descriptor?.enumerable || !("value" in descriptor)) throw new TypeError("Incremental dependencies must be enumerable data properties.");
|
|
14
|
-
projectionRef(descriptor.value);
|
|
15
|
-
names.push(key);
|
|
16
|
-
projections.push(descriptor.value);
|
|
17
|
-
}
|
|
18
|
-
return Object.freeze({
|
|
19
|
-
names: Object.freeze(names),
|
|
20
|
-
projections: Object.freeze(projections)
|
|
21
|
-
});
|
|
22
|
-
};
|
|
23
6
|
const publicInputs = (sources, names, reset) => {
|
|
24
7
|
const values = Object.create(null);
|
|
25
8
|
const changes = Object.create(null);
|
|
@@ -52,7 +35,7 @@ const initializeRetainedState = (definition) => {
|
|
|
52
35
|
return Object.freeze({ state });
|
|
53
36
|
};
|
|
54
37
|
function createIncrementalValue(dependencies, definition) {
|
|
55
|
-
const compiled =
|
|
38
|
+
const compiled = compileProjectionDependencies(dependencies, "Incremental");
|
|
56
39
|
validateDefinition(definition, ["state", "process"], "Incremental value");
|
|
57
40
|
validateRetainedState(definition, "Incremental value");
|
|
58
41
|
if (typeof definition.process !== "function") throw new TypeError("Incremental value definition requires a process function.");
|
|
@@ -84,7 +67,7 @@ function createIncrementalValue(dependencies, definition) {
|
|
|
84
67
|
return projection;
|
|
85
68
|
}
|
|
86
69
|
function createIncrementalCollection(dependencies, definition) {
|
|
87
|
-
const compiled =
|
|
70
|
+
const compiled = compileProjectionDependencies(dependencies, "Incremental");
|
|
88
71
|
validateDefinition(definition, ["state", "process"], "Incremental collection");
|
|
89
72
|
validateRetainedState(definition, "Incremental collection");
|
|
90
73
|
if (typeof definition.process !== "function") throw new TypeError("Incremental collection definition requires a process function.");
|
|
@@ -115,6 +98,31 @@ function createIncrementalCollection(dependencies, definition) {
|
|
|
115
98
|
});
|
|
116
99
|
return projection;
|
|
117
100
|
}
|
|
101
|
+
function createIncrementalKeyed(driver, dependencies, definition) {
|
|
102
|
+
validateDefinition(definition, [
|
|
103
|
+
"state",
|
|
104
|
+
"equality",
|
|
105
|
+
"process"
|
|
106
|
+
], "Incremental keyed");
|
|
107
|
+
if (definition.state !== void 0 && typeof definition.state !== "function") throw new TypeError("Incremental keyed state must be a function when provided.");
|
|
108
|
+
if (definition.equality !== void 0 && typeof definition.equality !== "function") throw new TypeError("Incremental keyed equality must be a function when provided.");
|
|
109
|
+
if (typeof definition.process !== "function") throw new TypeError("Incremental keyed definition requires a process function.");
|
|
110
|
+
return createKeyedTransform({
|
|
111
|
+
source: driver,
|
|
112
|
+
dependencies,
|
|
113
|
+
equality: definition.equality,
|
|
114
|
+
name: "incremental.keyed",
|
|
115
|
+
...definition.state ? { state: definition.state } : {},
|
|
116
|
+
evaluate: ({ key, value, dependencies: values, state, reset, cause }) => definition.process({
|
|
117
|
+
key,
|
|
118
|
+
value,
|
|
119
|
+
dependencies: values,
|
|
120
|
+
reset,
|
|
121
|
+
cause,
|
|
122
|
+
...definition.state ? { state } : {}
|
|
123
|
+
})
|
|
124
|
+
});
|
|
125
|
+
}
|
|
118
126
|
const isPlainGroupNamespace = (value, metadata) => isPlainObject(value) && !metadata.has(value);
|
|
119
127
|
const compileGroupShape = (value, path, metadata, used, outputs) => {
|
|
120
128
|
if (value !== null && typeof value === "object") {
|
|
@@ -168,7 +176,7 @@ const hydrateGroupReads = (shape, outputs, next) => {
|
|
|
168
176
|
return Object.freeze(result);
|
|
169
177
|
};
|
|
170
178
|
function createIncrementalGroup(dependencies, definition) {
|
|
171
|
-
const compiled =
|
|
179
|
+
const compiled = compileProjectionDependencies(dependencies, "Incremental");
|
|
172
180
|
validateDefinition(definition, [
|
|
173
181
|
"output",
|
|
174
182
|
"state",
|
|
@@ -229,9 +237,10 @@ function createIncrementalGroup(dependencies, definition) {
|
|
|
229
237
|
}
|
|
230
238
|
const incremental = Object.assign(createIncrementalValue, {
|
|
231
239
|
collection: createIncrementalCollection,
|
|
240
|
+
keyed: createIncrementalKeyed,
|
|
232
241
|
group: createIncrementalGroup
|
|
233
242
|
});
|
|
234
243
|
//#endregion
|
|
235
|
-
export { incremental };
|
|
244
|
+
export { collectionChange, incremental };
|
|
236
245
|
|
|
237
246
|
//# sourceMappingURL=advanced.js.map
|