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.
Files changed (39) hide show
  1. package/README.md +86 -3
  2. package/dist/advanced.cjs +40 -30
  3. package/dist/advanced.cjs.map +1 -1
  4. package/dist/advanced.d.cts +34 -2
  5. package/dist/advanced.d.ts +34 -2
  6. package/dist/advanced.js +31 -22
  7. package/dist/advanced.js.map +1 -1
  8. package/dist/{definition-xgk3YNBp.d.ts → dependency-B3E65M1E.d.cts} +27 -3
  9. package/dist/{definition-CDOuvb5C.d.cts → dependency-BYbdDHNa.d.ts} +27 -3
  10. package/dist/driver-B5vdPohL.js.map +1 -1
  11. package/dist/driver-BL91gn7_.cjs.map +1 -1
  12. package/dist/index.cjs +885 -394
  13. package/dist/index.cjs.map +1 -1
  14. package/dist/index.d.cts +33 -18
  15. package/dist/index.d.ts +33 -18
  16. package/dist/index.js +784 -293
  17. package/dist/index.js.map +1 -1
  18. package/dist/local-sync.cjs.map +1 -1
  19. package/dist/local-sync.js.map +1 -1
  20. package/dist/transform-B4T3AcJr.js +938 -0
  21. package/dist/transform-B4T3AcJr.js.map +1 -0
  22. package/dist/transform-DUleAsG0.cjs +1105 -0
  23. package/dist/transform-DUleAsG0.cjs.map +1 -0
  24. package/package.json +1 -1
  25. package/skills/doxum-runtime/SKILL.md +16 -6
  26. package/skills/doxum-runtime/references/api.en.md +49 -15
  27. package/skills/doxum-runtime/references/api.zh-CN.md +47 -13
  28. package/skills/doxum-runtime/references/guide.en.md +2 -1
  29. package/skills/doxum-runtime/references/guide.zh-CN.md +2 -1
  30. package/skills/doxum-runtime/references/invariants.en.md +2 -2
  31. package/skills/doxum-runtime/references/invariants.zh-CN.md +2 -2
  32. package/skills/doxum-runtime/references/patterns.en.md +1 -1
  33. package/skills/doxum-runtime/references/patterns.zh-CN.md +1 -1
  34. package/skills/doxum-runtime/references/projections.en.md +77 -4
  35. package/skills/doxum-runtime/references/projections.zh-CN.md +74 -3
  36. package/dist/scheduler--137L3j-.js +0 -500
  37. package/dist/scheduler--137L3j-.js.map +0 -1
  38. package/dist/scheduler-D4VthaaK.cjs +0 -589
  39. 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 is exported by `doxum/advanced`.
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 require_scheduler = require("./scheduler-D4VthaaK.cjs");
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 : require_scheduler.collectionView(source.read);
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
- require_scheduler.assertSynchronous(state);
35
+ require_transform.assertSynchronous(state);
53
36
  return Object.freeze({ state });
54
37
  };
55
38
  function createIncrementalValue(dependencies, definition) {
56
- const compiled = compileDependencies(dependencies);
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] = require_scheduler.defineProcessor({
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
- require_scheduler.assertSynchronous(result);
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 = compileDependencies(dependencies);
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] = require_scheduler.defineProcessor({
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
- require_scheduler.assertSynchronous(definition.process({
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 = compileDependencies(dependencies);
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
- require_scheduler.assertSynchronous(declared);
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, require_scheduler.defineProcessor({
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
- require_scheduler.assertSynchronous(definition.process({
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
@@ -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":"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"}
@@ -1,5 +1,12 @@
1
- import { a as Projection, c as CollectionDraft, i as KeyedProjection, l as CollectionRead, o as ProjectionChange, s as CollectionChange } from "./definition-CDOuvb5C.cjs";
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
@@ -1,5 +1,12 @@
1
- import { a as Projection, c as CollectionDraft, i as KeyedProjection, l as CollectionRead, o as ProjectionChange, s as CollectionChange } from "./definition-xgk3YNBp.js";
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 { d as isProjection, l as defineProcessor, m as projectionRef, n as assertSynchronous, o as collectionView } from "./scheduler--137L3j-.js";
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 = compileDependencies(dependencies);
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 = compileDependencies(dependencies);
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 = compileDependencies(dependencies);
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