doxum 0.1.15 → 0.1.17
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 +6 -0
- package/dist/advanced.cjs +82 -49
- package/dist/advanced.cjs.map +1 -1
- package/dist/advanced.d.cts +18 -21
- package/dist/advanced.d.ts +18 -21
- package/dist/advanced.js +82 -49
- package/dist/advanced.js.map +1 -1
- package/dist/definition-BdLGD8Rq.d.ts +101 -0
- package/dist/definition-Bf8Z7xtX.d.cts +101 -0
- package/dist/{definition-c6XQXzvK.js → definition-DUo1lfQ8.js} +1 -2
- package/dist/definition-DUo1lfQ8.js.map +1 -0
- package/dist/{definition-Z6TagMup.cjs → definition-De6rhTlZ.cjs} +1 -2
- package/dist/definition-De6rhTlZ.cjs.map +1 -0
- package/dist/index.cjs +815 -777
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -7
- package/dist/index.d.ts +9 -7
- package/dist/index.js +816 -778
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +5 -10
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +4 -6
- package/dist/react.d.ts +4 -6
- package/dist/react.js +6 -10
- package/dist/react.js.map +1 -1
- package/package.json +3 -2
- package/skills/doxum-runtime/SKILL.md +2 -1
- package/skills/doxum-runtime/references/patterns.en.md +4 -4
- package/skills/doxum-runtime/references/patterns.zh-CN.md +2 -2
- package/skills/doxum-runtime/references/projections.en.md +15 -6
- package/skills/doxum-runtime/references/projections.zh-CN.md +14 -6
- package/dist/definition-B6J0SSNa.d.ts +0 -99
- package/dist/definition-DN6yW2vi.d.cts +0 -99
- package/dist/definition-Z6TagMup.cjs.map +0 -1
- package/dist/definition-c6XQXzvK.js.map +0 -1
package/README.md
CHANGED
|
@@ -254,6 +254,12 @@ const doubled = incremental.collection([tasks], ({ sources, output }) => {
|
|
|
254
254
|
});
|
|
255
255
|
```
|
|
256
256
|
|
|
257
|
+
Incremental processors receive a dependency-aligned `changes` tuple. Collection
|
|
258
|
+
entries carry `added`/`updated`/`removed` transitions with complete
|
|
259
|
+
`before`/`after` values, so a processor can patch indexes without rescanning the
|
|
260
|
+
collection; scalar dependencies use `undefined` and the initial collection build
|
|
261
|
+
reports `{ kind: 'reset' }`.
|
|
262
|
+
|
|
257
263
|
In React, `useProjection(projection)` reads a value and
|
|
258
264
|
`useProjection(projection, selector, equality?)` tracks keyed reads such as
|
|
259
265
|
`tasks => tasks.get(taskId)`. Unrelated key changes do not execute that selector;
|
package/dist/advanced.cjs
CHANGED
|
@@ -1,72 +1,98 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_scope = require("./scope-Ezs-Y3TY.cjs");
|
|
3
|
-
const require_definition = require("./definition-
|
|
3
|
+
const require_definition = require("./definition-De6rhTlZ.cjs");
|
|
4
4
|
//#region core/src/projection/advanced.ts
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
|
|
5
|
+
const resetCollectionChange = Object.freeze({ kind: "reset" });
|
|
6
|
+
const isRebuild = (value) => value !== null && typeof value === "object" && value.kind === "rebuild";
|
|
7
|
+
const collectionChange = (source) => {
|
|
8
|
+
if (!source || typeof source !== "object" || !("kind" in source)) return void 0;
|
|
9
|
+
if (source.kind !== "collection") return void 0;
|
|
10
|
+
return source.change;
|
|
8
11
|
};
|
|
9
12
|
const sourceCause = (sources) => {
|
|
10
|
-
for (const source of Object.values(sources)) if (source && typeof source === "object" && "
|
|
13
|
+
for (const source of Object.values(sources)) if (source && typeof source === "object" && "kind" in source) {
|
|
14
|
+
const cause = source.cause;
|
|
15
|
+
if (cause !== void 0) return cause;
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
const collectionView = (read) => {
|
|
19
|
+
const entries = function* () {
|
|
20
|
+
for (const key of read.ids()) yield [key, read.get(key)];
|
|
21
|
+
};
|
|
22
|
+
const values = function* () {
|
|
23
|
+
for (const key of read.ids()) yield read.get(key);
|
|
24
|
+
};
|
|
25
|
+
const view = {
|
|
26
|
+
get: (key) => read.get(key),
|
|
27
|
+
has: (key) => read.has(key),
|
|
28
|
+
get size() {
|
|
29
|
+
return read.ids().length;
|
|
30
|
+
},
|
|
31
|
+
keys: () => read.ids()[Symbol.iterator](),
|
|
32
|
+
values,
|
|
33
|
+
entries,
|
|
34
|
+
forEach: (callback, thisArg) => {
|
|
35
|
+
for (const key of read.ids()) callback.call(thisArg, read.get(key), key, view);
|
|
36
|
+
},
|
|
37
|
+
[Symbol.iterator]: entries
|
|
38
|
+
};
|
|
39
|
+
return Object.freeze(view);
|
|
11
40
|
};
|
|
12
41
|
const publicSource = (source) => {
|
|
13
42
|
if (!source || typeof source !== "object") return source;
|
|
14
|
-
if ("
|
|
15
|
-
if ("
|
|
43
|
+
if (!("kind" in source)) return source;
|
|
44
|
+
if (source.kind === "value") return source.value;
|
|
45
|
+
if (source.kind === "document") return require_scope.snapshot(source.read);
|
|
46
|
+
if (source.kind === "collection") {
|
|
16
47
|
const read = source.read;
|
|
17
|
-
|
|
18
|
-
const result = /* @__PURE__ */ new Map();
|
|
19
|
-
for (const id of read.ids()) result.set(id, read.get(id));
|
|
20
|
-
return result;
|
|
21
|
-
}
|
|
22
|
-
return require_scope.snapshot(read);
|
|
23
|
-
}
|
|
24
|
-
if ("ids" in source && typeof source.ids === "function") {
|
|
25
|
-
const result = /* @__PURE__ */ new Map();
|
|
26
|
-
const read = source;
|
|
27
|
-
for (const id of read.ids()) result.set(id, read.get(id));
|
|
28
|
-
return result;
|
|
48
|
+
return collectionView(read);
|
|
29
49
|
}
|
|
30
50
|
return source;
|
|
31
51
|
};
|
|
32
|
-
const
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
52
|
+
const publicInputs = (sources, initial = false) => {
|
|
53
|
+
const values = [];
|
|
54
|
+
const changes = [];
|
|
55
|
+
for (const key of Object.keys(sources).sort((left, right) => Number(left.slice(1)) - Number(right.slice(1)))) {
|
|
56
|
+
const source = sources[key];
|
|
57
|
+
values.push(publicSource(source));
|
|
58
|
+
changes.push(initial && source && typeof source === "object" && "kind" in source && source.kind === "collection" ? resetCollectionChange : collectionChange(source));
|
|
59
|
+
}
|
|
60
|
+
return {
|
|
61
|
+
values,
|
|
62
|
+
changes
|
|
63
|
+
};
|
|
64
|
+
};
|
|
37
65
|
function createIncrementalValue(dependencies, processor) {
|
|
38
66
|
const dependencyMap = dependenciesOf(dependencies);
|
|
39
67
|
let state = Object.create(null);
|
|
40
68
|
let current;
|
|
41
69
|
const build = (sources) => {
|
|
42
70
|
state = Object.create(null);
|
|
71
|
+
const publicInputsForBuild = publicInputs(sources, true);
|
|
43
72
|
const result = processor({
|
|
44
|
-
sources:
|
|
73
|
+
sources: publicInputsForBuild.values,
|
|
74
|
+
changes: publicInputsForBuild.changes,
|
|
45
75
|
previous: void 0,
|
|
46
76
|
reset: true,
|
|
47
|
-
change: void 0,
|
|
48
77
|
cause: sourceCause(sources),
|
|
49
78
|
state
|
|
50
79
|
});
|
|
51
|
-
if (result
|
|
52
|
-
|
|
53
|
-
current = normalized.value;
|
|
54
|
-
if (normalized.state) state = normalized.state;
|
|
80
|
+
if (isRebuild(result)) throw new TypeError("Initial incremental processor cannot rebuild.");
|
|
81
|
+
current = result;
|
|
55
82
|
return {
|
|
56
83
|
value: current,
|
|
57
84
|
update: (nextSources) => {
|
|
85
|
+
const publicInputsForUpdate = publicInputs(nextSources);
|
|
58
86
|
const next = processor({
|
|
59
|
-
sources:
|
|
87
|
+
sources: publicInputsForUpdate.values,
|
|
88
|
+
changes: publicInputsForUpdate.changes,
|
|
60
89
|
previous: current,
|
|
61
90
|
reset: false,
|
|
62
|
-
change: sourceChange(nextSources),
|
|
63
91
|
cause: sourceCause(nextSources),
|
|
64
92
|
state
|
|
65
93
|
});
|
|
66
|
-
if (next
|
|
67
|
-
|
|
68
|
-
current = nextValue.value;
|
|
69
|
-
if (nextValue.state) state = nextValue.state;
|
|
94
|
+
if (isRebuild(next)) return next;
|
|
95
|
+
current = next;
|
|
70
96
|
return {
|
|
71
97
|
kind: "changed",
|
|
72
98
|
value: current
|
|
@@ -79,31 +105,38 @@ function createIncrementalValue(dependencies, processor) {
|
|
|
79
105
|
build
|
|
80
106
|
});
|
|
81
107
|
}
|
|
108
|
+
function dependenciesOf(dependencies) {
|
|
109
|
+
return Object.fromEntries(dependencies.map((dependency, index) => [`d${index}`, dependency]));
|
|
110
|
+
}
|
|
82
111
|
function createIncrementalCollection(dependencies, processor) {
|
|
83
112
|
const dependencyMap = dependenciesOf(dependencies);
|
|
84
113
|
let state = Object.create(null);
|
|
85
114
|
const build = (input) => {
|
|
86
115
|
state = Object.create(null);
|
|
116
|
+
const publicInputsForBuild = publicInputs(input.sources, true);
|
|
87
117
|
if (processor({
|
|
88
|
-
sources:
|
|
118
|
+
sources: publicInputsForBuild.values,
|
|
119
|
+
changes: publicInputsForBuild.changes,
|
|
89
120
|
previous: input.previous,
|
|
90
121
|
next: input.next,
|
|
91
122
|
reset: true,
|
|
92
|
-
change: void 0,
|
|
93
123
|
cause: sourceCause(input.sources),
|
|
94
124
|
state,
|
|
95
|
-
output: input.
|
|
125
|
+
output: input.output
|
|
96
126
|
})?.kind === "rebuild") throw new TypeError("Initial incremental collection processor cannot rebuild.");
|
|
97
|
-
return { update: (nextInput) =>
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
127
|
+
return { update: (nextInput) => {
|
|
128
|
+
const publicInputsForUpdate = publicInputs(nextInput.sources);
|
|
129
|
+
return processor({
|
|
130
|
+
sources: publicInputsForUpdate.values,
|
|
131
|
+
changes: publicInputsForUpdate.changes,
|
|
132
|
+
previous: nextInput.previous,
|
|
133
|
+
next: nextInput.next,
|
|
134
|
+
reset: false,
|
|
135
|
+
cause: sourceCause(nextInput.sources),
|
|
136
|
+
state,
|
|
137
|
+
output: nextInput.output
|
|
138
|
+
});
|
|
139
|
+
} };
|
|
107
140
|
};
|
|
108
141
|
return require_definition.defineIncrementalCollection({
|
|
109
142
|
dependencies: dependencyMap,
|
package/dist/advanced.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"advanced.cjs","names":["snapshot","defineIncrementalValue","defineIncrementalCollection"],"sources":["../core/src/projection/advanced.ts"],"sourcesContent":["import type { Projection, ProjectionValues, PublicCollection } from './definition';\nimport { defineIncrementalCollection, defineIncrementalValue } from './definition';\nimport type { CollectionDraft, CollectionRead, GraphSources } from './contract';\nimport { snapshot } from '../access/scope';\n\nexport type IncrementalState = Record<string, unknown>;\n\nexport type IncrementalValueContext<S, T> = {\n readonly sources: S;\n readonly previous: T | undefined;\n readonly reset: boolean;\n readonly change: unknown;\n readonly cause: unknown;\n readonly state: IncrementalState;\n};\n\nexport type IncrementalValueProcessor<S, T> = (\n context: IncrementalValueContext<S, T>\n) =>\n | T\n | { readonly kind: 'value'; readonly value: T; readonly state?: IncrementalState }\n | { readonly kind: 'rebuild' };\n\nexport type IncrementalCollectionContext<S, K extends string, V> = {\n readonly sources: S;\n readonly previous: CollectionRead<K, V>;\n readonly next: CollectionRead<K, V>;\n readonly change: unknown;\n readonly reset: boolean;\n readonly cause: unknown;\n readonly state: IncrementalState;\n readonly output: CollectionDraft<K, V>;\n};\n\nexport type IncrementalCollectionProcessor<S, K extends string, V> = (\n context: IncrementalCollectionContext<S, K, V>\n) => void | { readonly kind: 'rebuild' };\n\ntype DependencyMap<D extends readonly Projection<unknown>[]> = {\n readonly [K in keyof D as `d${Extract<K, number>}`]: D[K];\n};\n\nconst dependenciesOf = <D extends readonly Projection<unknown>[]>(dependencies: D): GraphSources =>\n Object.fromEntries(\n dependencies.map((dependency, index) => [`d${index}`, dependency])\n ) as unknown as GraphSources;\n\nconst sourceChange = (sources: Record<string, unknown>): unknown => {\n for (const source of Object.values(sources)) {\n if (\n source &&\n typeof source === 'object' &&\n 'change' in source &&\n (source as { readonly change?: unknown }).change !== undefined\n )\n return (source as { readonly change?: unknown }).change;\n }\n return undefined;\n};\n\nconst sourceCause = (sources: Record<string, unknown>): unknown => {\n for (const source of Object.values(sources)) {\n if (\n source &&\n typeof source === 'object' &&\n 'cause' in source &&\n (source as { readonly cause?: unknown }).cause !== undefined\n )\n return (source as { readonly cause?: unknown }).cause;\n }\n return undefined;\n};\n\nconst publicSource = (source: unknown): unknown => {\n if (!source || typeof source !== 'object') return source;\n if ('value' in source) return (source as { readonly value: unknown }).value;\n if ('read' in source) {\n const read = (source as { readonly read: unknown }).read;\n if (\n read &&\n typeof read === 'object' &&\n 'ids' in read &&\n typeof (read as { ids?: unknown }).ids === 'function'\n ) {\n const result = new Map<string, unknown>();\n for (const id of (read as CollectionRead<string, unknown>).ids())\n result.set(id, (read as CollectionRead<string, unknown>).get(id));\n return result;\n }\n return snapshot(read);\n }\n if ('ids' in source && typeof (source as { ids?: unknown }).ids === 'function') {\n const result = new Map<string, unknown>();\n const read = source as CollectionRead<string, unknown>;\n for (const id of read.ids()) result.set(id, read.get(id));\n return result;\n }\n return source;\n};\n\nconst publicTuple = (sources: Record<string, unknown>): readonly unknown[] =>\n Object.keys(sources)\n .sort((left, right) => Number(left.slice(1)) - Number(right.slice(1)))\n .map(key => publicSource(sources[key]));\n\nconst normalizeValue = <T>(\n result: T | { readonly kind: 'value'; readonly value: T; readonly state?: IncrementalState }\n): { value: T; state?: IncrementalState } =>\n result && typeof result === 'object' && (result as { readonly kind?: unknown }).kind === 'value'\n ? {\n value: (result as { readonly value: T }).value,\n state: (result as { readonly state?: IncrementalState }).state,\n }\n : { value: result as T };\n\nfunction createIncrementalValue<const D extends readonly Projection<unknown>[], T>(\n dependencies: D,\n processor: IncrementalValueProcessor<ProjectionValues<D>, T>\n): Projection<T> {\n const dependencyMap = dependenciesOf(dependencies);\n let state: IncrementalState = Object.create(null) as IncrementalState;\n let current!: T;\n const build = (sources: Record<string, unknown>) => {\n state = Object.create(null) as IncrementalState;\n const result = processor({\n sources: publicTuple(sources) as ProjectionValues<D>,\n previous: undefined,\n reset: true,\n change: undefined,\n cause: sourceCause(sources),\n state,\n });\n if (result && typeof result === 'object' && 'kind' in result)\n throw new TypeError('Initial incremental processor cannot rebuild.');\n const normalized = normalizeValue(result as T);\n current = normalized.value;\n if (normalized.state) state = normalized.state;\n return {\n value: current,\n update: (nextSources: Record<string, unknown>) => {\n const next = processor({\n sources: publicTuple(nextSources) as ProjectionValues<D>,\n previous: current,\n reset: false,\n change: sourceChange(nextSources),\n cause: sourceCause(nextSources),\n state,\n });\n if (next && typeof next === 'object' && 'kind' in next) return next;\n const nextValue = normalizeValue(next as T);\n current = nextValue.value;\n if (nextValue.state) state = nextValue.state;\n return { kind: 'changed', value: current } as const;\n },\n };\n };\n return defineIncrementalValue({ dependencies: dependencyMap, build: build as never });\n}\n\nfunction createIncrementalCollection<\n const D extends readonly Projection<unknown>[],\n K extends string,\n V,\n>(\n dependencies: D,\n processor: IncrementalCollectionProcessor<ProjectionValues<D>, K, V>\n): Projection<PublicCollection<K, V>> {\n const dependencyMap = dependenciesOf(dependencies);\n let state: IncrementalState = Object.create(null) as IncrementalState;\n const build = (input: {\n readonly sources: Record<string, unknown>;\n readonly previous: CollectionRead<K, V>;\n readonly next: CollectionRead<K, V>;\n readonly writer: CollectionDraft<K, V>;\n }) => {\n state = Object.create(null) as IncrementalState;\n const result = processor({\n sources: publicTuple(input.sources) as ProjectionValues<D>,\n previous: input.previous,\n next: input.next,\n reset: true,\n change: undefined,\n cause: sourceCause(input.sources),\n state,\n output: input.writer,\n });\n if (result?.kind === 'rebuild')\n throw new TypeError('Initial incremental collection processor cannot rebuild.');\n return {\n update: (nextInput: typeof input) =>\n processor({\n sources: publicTuple(nextInput.sources) as ProjectionValues<D>,\n previous: nextInput.previous,\n next: nextInput.next,\n reset: false,\n change: sourceChange(nextInput.sources),\n cause: sourceCause(nextInput.sources),\n state,\n output: nextInput.writer,\n }),\n };\n };\n return defineIncrementalCollection({ dependencies: dependencyMap, build: build as never });\n}\n\nexport const incremental = Object.assign(createIncrementalValue, {\n collection: createIncrementalCollection,\n});\n\nexport type IncrementalDependencies<D extends readonly Projection<unknown>[]> = DependencyMap<D>;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"advanced.cjs","names":["snapshot","defineIncrementalValue","defineIncrementalCollection"],"sources":["../core/src/projection/advanced.ts"],"sourcesContent":["import type { Projection } from './definition';\nimport { defineIncrementalCollection, defineIncrementalValue } from './definition';\nimport type { CollectionChange, CollectionDraft, CollectionRead, GraphSources } from './contract';\nimport { snapshot } from '../access/scope';\n\ntype ProjectionValues<D extends readonly Projection<unknown, unknown>[]> = {\n readonly [K in keyof D]: D[K] extends Projection<infer T, unknown> ? T : never;\n};\n\ntype ProjectionChanges<D extends readonly Projection<unknown, unknown>[]> = {\n readonly [K in keyof D]: D[K] extends Projection<unknown, infer C>\n ? [C] extends [undefined]\n ? undefined\n : C | undefined\n : undefined;\n};\n\nexport type IncrementalValueContext<D extends readonly Projection<unknown, unknown>[], T> = {\n readonly sources: ProjectionValues<D>;\n readonly changes: ProjectionChanges<D>;\n readonly previous: T | undefined;\n readonly reset: boolean;\n readonly cause: unknown;\n readonly state: Record<string, unknown>;\n};\n\nexport type IncrementalValueProcessor<D extends readonly Projection<unknown, unknown>[], T> = (\n context: IncrementalValueContext<D, T>\n) => T | { readonly kind: 'rebuild' };\n\nexport type IncrementalCollectionContext<\n D extends readonly Projection<unknown, unknown>[],\n K extends string,\n V,\n> = {\n readonly sources: 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 state: Record<string, unknown>;\n readonly output: CollectionDraft<K, V>;\n};\n\nexport type IncrementalCollectionProcessor<\n D extends readonly Projection<unknown, unknown>[],\n K extends string,\n V,\n> = (context: IncrementalCollectionContext<D, K, V>) => void | { readonly kind: 'rebuild' };\n\ntype DependencyMap<D extends readonly Projection<unknown, unknown>[]> = {\n readonly [K in keyof D as `d${Extract<K, number>}`]: D[K];\n};\n\nconst resetCollectionChange = Object.freeze({ kind: 'reset' as const });\n\nconst isRebuild = (value: unknown): value is { readonly kind: 'rebuild' } =>\n value !== null &&\n typeof value === 'object' &&\n (value as { readonly kind?: unknown }).kind === 'rebuild';\n\nconst collectionChange = (source: unknown): CollectionChange<string, unknown> | undefined => {\n if (!source || typeof source !== 'object' || !('kind' in source)) return undefined;\n if (source.kind !== 'collection') return undefined;\n return (source as { readonly change?: CollectionChange<string, unknown> }).change;\n};\n\nconst sourceCause = (sources: Record<string, unknown>): unknown => {\n for (const source of Object.values(sources)) {\n if (source && typeof source === 'object' && 'kind' in source) {\n const cause = (source as { readonly cause?: unknown }).cause;\n if (cause !== undefined) return cause;\n }\n }\n return undefined;\n};\n\nconst collectionView = <K extends string, V>(read: CollectionRead<K, V>): ReadonlyMap<K, V> => {\n const entries = function* (): IterableIterator<[K, V]> {\n for (const key of read.ids()) yield [key, read.get(key) as V];\n };\n const values = function* (): IterableIterator<V> {\n for (const key of read.ids()) yield read.get(key) as V;\n };\n const view: ReadonlyMap<K, V> = {\n get: key => read.get(key),\n has: key => read.has(key),\n get size() {\n return read.ids().length;\n },\n keys: () => read.ids()[Symbol.iterator](),\n values,\n entries,\n forEach: (callback, thisArg) => {\n for (const key of read.ids()) callback.call(thisArg, read.get(key) as V, key, view);\n },\n [Symbol.iterator]: entries,\n };\n return Object.freeze(view);\n};\n\nconst publicSource = (source: unknown): unknown => {\n if (!source || typeof source !== 'object') return source;\n if (!('kind' in source)) return source;\n if (source.kind === 'value') return (source as unknown as { readonly value: unknown }).value;\n if (source.kind === 'document')\n return snapshot((source as unknown as { readonly read: unknown }).read as never);\n if (source.kind === 'collection') {\n const read = (source as unknown as { readonly read: CollectionRead<string, unknown> }).read;\n return collectionView(read);\n }\n return source;\n};\n\nconst publicInputs = (\n sources: Record<string, unknown>,\n initial = false\n): { readonly values: readonly unknown[]; readonly changes: readonly unknown[] } => {\n const values: unknown[] = [];\n const changes: unknown[] = [];\n for (const key of Object.keys(sources).sort(\n (left, right) => Number(left.slice(1)) - Number(right.slice(1))\n )) {\n const source = sources[key];\n values.push(publicSource(source));\n changes.push(\n initial &&\n source &&\n typeof source === 'object' &&\n 'kind' in source &&\n source.kind === 'collection'\n ? resetCollectionChange\n : collectionChange(source)\n );\n }\n return { values, changes };\n};\n\nfunction createIncrementalValue<const D extends readonly Projection<unknown, unknown>[], T>(\n dependencies: D,\n processor: IncrementalValueProcessor<D, T>\n): Projection<T> {\n const dependencyMap = dependenciesOf(dependencies);\n let state: Record<string, unknown> = Object.create(null) as Record<string, unknown>;\n let current!: T;\n const build = (sources: Record<string, unknown>) => {\n state = Object.create(null) as Record<string, unknown>;\n const publicInputsForBuild = publicInputs(sources, true);\n const result = processor({\n sources: publicInputsForBuild.values as ProjectionValues<D>,\n changes: publicInputsForBuild.changes as ProjectionChanges<D>,\n previous: undefined,\n reset: true,\n cause: sourceCause(sources),\n state,\n });\n if (isRebuild(result)) throw new TypeError('Initial incremental processor cannot rebuild.');\n current = result as T;\n return {\n value: current,\n update: (nextSources: Record<string, unknown>) => {\n const publicInputsForUpdate = publicInputs(nextSources);\n const next = processor({\n sources: publicInputsForUpdate.values as ProjectionValues<D>,\n changes: publicInputsForUpdate.changes as ProjectionChanges<D>,\n previous: current,\n reset: false,\n cause: sourceCause(nextSources),\n state,\n });\n if (isRebuild(next)) return next;\n current = next as T;\n return { kind: 'changed', value: current } as const;\n },\n };\n };\n return defineIncrementalValue({ dependencies: dependencyMap, build: build as never });\n}\n\nfunction dependenciesOf<D extends readonly Projection<unknown, unknown>[]>(\n dependencies: D\n): GraphSources {\n return Object.fromEntries(\n dependencies.map((dependency, index) => [`d${index}`, dependency])\n ) as unknown as GraphSources;\n}\n\nfunction createIncrementalCollection<\n const D extends readonly Projection<unknown, unknown>[],\n K extends string,\n V,\n>(\n dependencies: D,\n processor: IncrementalCollectionProcessor<D, K, V>\n): Projection<ReadonlyMap<K, V>, CollectionChange<K, V>> {\n const dependencyMap = dependenciesOf(dependencies);\n let state: Record<string, unknown> = Object.create(null) as Record<string, unknown>;\n const build = (input: {\n readonly sources: Record<string, unknown>;\n readonly previous: CollectionRead<K, V>;\n readonly next: CollectionRead<K, V>;\n readonly output: CollectionDraft<K, V>;\n }) => {\n state = Object.create(null) as Record<string, unknown>;\n const publicInputsForBuild = publicInputs(input.sources, true);\n const result = processor({\n sources: publicInputsForBuild.values as ProjectionValues<D>,\n changes: publicInputsForBuild.changes as ProjectionChanges<D>,\n previous: input.previous,\n next: input.next,\n reset: true,\n cause: sourceCause(input.sources),\n state,\n output: input.output,\n });\n if (result?.kind === 'rebuild')\n throw new TypeError('Initial incremental collection processor cannot rebuild.');\n return {\n update: (nextInput: typeof input) => {\n const publicInputsForUpdate = publicInputs(nextInput.sources);\n return processor({\n sources: publicInputsForUpdate.values as ProjectionValues<D>,\n changes: publicInputsForUpdate.changes as ProjectionChanges<D>,\n previous: nextInput.previous,\n next: nextInput.next,\n reset: false,\n cause: sourceCause(nextInput.sources),\n state,\n output: nextInput.output,\n });\n },\n };\n };\n return defineIncrementalCollection({ dependencies: dependencyMap, build: build as never });\n}\n\nexport const incremental = Object.assign(createIncrementalValue, {\n collection: createIncrementalCollection,\n});\n\nexport type IncrementalDependencies<D extends readonly Projection<unknown, unknown>[]> =\n DependencyMap<D>;\n\nexport type { CollectionChange } from './contract';\n"],"mappings":"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"}
|
package/dist/advanced.d.cts
CHANGED
|
@@ -1,42 +1,39 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { c as CollectionRead, n as Projection, o as CollectionChange, s as CollectionDraft } from "./definition-Bf8Z7xtX.cjs";
|
|
2
2
|
|
|
3
3
|
//#region core/src/projection/advanced.d.ts
|
|
4
|
-
type
|
|
5
|
-
type
|
|
6
|
-
|
|
4
|
+
type ProjectionValues<D extends readonly Projection<unknown, unknown>[]> = { readonly [K in keyof D]: D[K] extends Projection<infer T, unknown> ? T : never };
|
|
5
|
+
type ProjectionChanges<D extends readonly Projection<unknown, unknown>[]> = { readonly [K in keyof D]: D[K] extends Projection<unknown, infer C> ? [C] extends [undefined] ? undefined : C | undefined : undefined };
|
|
6
|
+
type IncrementalValueContext<D extends readonly Projection<unknown, unknown>[], T> = {
|
|
7
|
+
readonly sources: ProjectionValues<D>;
|
|
8
|
+
readonly changes: ProjectionChanges<D>;
|
|
7
9
|
readonly previous: T | undefined;
|
|
8
10
|
readonly reset: boolean;
|
|
9
|
-
readonly change: unknown;
|
|
10
11
|
readonly cause: unknown;
|
|
11
|
-
readonly state:
|
|
12
|
+
readonly state: Record<string, unknown>;
|
|
12
13
|
};
|
|
13
|
-
type IncrementalValueProcessor<
|
|
14
|
-
readonly kind: 'value';
|
|
15
|
-
readonly value: T;
|
|
16
|
-
readonly state?: IncrementalState;
|
|
17
|
-
} | {
|
|
14
|
+
type IncrementalValueProcessor<D extends readonly Projection<unknown, unknown>[], T> = (context: IncrementalValueContext<D, T>) => T | {
|
|
18
15
|
readonly kind: 'rebuild';
|
|
19
16
|
};
|
|
20
|
-
type IncrementalCollectionContext<
|
|
21
|
-
readonly sources:
|
|
17
|
+
type IncrementalCollectionContext<D extends readonly Projection<unknown, unknown>[], K extends string, V> = {
|
|
18
|
+
readonly sources: ProjectionValues<D>;
|
|
19
|
+
readonly changes: ProjectionChanges<D>;
|
|
22
20
|
readonly previous: CollectionRead<K, V>;
|
|
23
21
|
readonly next: CollectionRead<K, V>;
|
|
24
|
-
readonly change: unknown;
|
|
25
22
|
readonly reset: boolean;
|
|
26
23
|
readonly cause: unknown;
|
|
27
|
-
readonly state:
|
|
24
|
+
readonly state: Record<string, unknown>;
|
|
28
25
|
readonly output: CollectionDraft<K, V>;
|
|
29
26
|
};
|
|
30
|
-
type IncrementalCollectionProcessor<
|
|
27
|
+
type IncrementalCollectionProcessor<D extends readonly Projection<unknown, unknown>[], K extends string, V> = (context: IncrementalCollectionContext<D, K, V>) => void | {
|
|
31
28
|
readonly kind: 'rebuild';
|
|
32
29
|
};
|
|
33
|
-
type DependencyMap<D extends readonly Projection<unknown>[]> = { readonly [K in keyof D as `d${Extract<K, number>}`]: D[K] };
|
|
34
|
-
declare function createIncrementalValue<const D extends readonly Projection<unknown>[], T>(dependencies: D, processor: IncrementalValueProcessor<
|
|
35
|
-
declare function createIncrementalCollection<const D extends readonly Projection<unknown>[], K extends string, V>(dependencies: D, processor: IncrementalCollectionProcessor<
|
|
30
|
+
type DependencyMap<D extends readonly Projection<unknown, unknown>[]> = { readonly [K in keyof D as `d${Extract<K, number>}`]: D[K] };
|
|
31
|
+
declare function createIncrementalValue<const D extends readonly Projection<unknown, unknown>[], T>(dependencies: D, processor: IncrementalValueProcessor<D, T>): Projection<T>;
|
|
32
|
+
declare function createIncrementalCollection<const D extends readonly Projection<unknown, unknown>[], K extends string, V>(dependencies: D, processor: IncrementalCollectionProcessor<D, K, V>): Projection<ReadonlyMap<K, V>, CollectionChange<K, V>>;
|
|
36
33
|
declare const incremental: typeof createIncrementalValue & {
|
|
37
34
|
collection: typeof createIncrementalCollection;
|
|
38
35
|
};
|
|
39
|
-
type IncrementalDependencies<D extends readonly Projection<unknown>[]> = DependencyMap<D>;
|
|
36
|
+
type IncrementalDependencies<D extends readonly Projection<unknown, unknown>[]> = DependencyMap<D>;
|
|
40
37
|
//#endregion
|
|
41
|
-
export { IncrementalCollectionContext, IncrementalCollectionProcessor, IncrementalDependencies,
|
|
38
|
+
export { type CollectionChange, IncrementalCollectionContext, IncrementalCollectionProcessor, IncrementalDependencies, IncrementalValueContext, IncrementalValueProcessor, incremental };
|
|
42
39
|
//# sourceMappingURL=advanced.d.cts.map
|
package/dist/advanced.d.ts
CHANGED
|
@@ -1,42 +1,39 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { c as CollectionRead, n as Projection, o as CollectionChange, s as CollectionDraft } from "./definition-BdLGD8Rq.js";
|
|
2
2
|
|
|
3
3
|
//#region core/src/projection/advanced.d.ts
|
|
4
|
-
type
|
|
5
|
-
type
|
|
6
|
-
|
|
4
|
+
type ProjectionValues<D extends readonly Projection<unknown, unknown>[]> = { readonly [K in keyof D]: D[K] extends Projection<infer T, unknown> ? T : never };
|
|
5
|
+
type ProjectionChanges<D extends readonly Projection<unknown, unknown>[]> = { readonly [K in keyof D]: D[K] extends Projection<unknown, infer C> ? [C] extends [undefined] ? undefined : C | undefined : undefined };
|
|
6
|
+
type IncrementalValueContext<D extends readonly Projection<unknown, unknown>[], T> = {
|
|
7
|
+
readonly sources: ProjectionValues<D>;
|
|
8
|
+
readonly changes: ProjectionChanges<D>;
|
|
7
9
|
readonly previous: T | undefined;
|
|
8
10
|
readonly reset: boolean;
|
|
9
|
-
readonly change: unknown;
|
|
10
11
|
readonly cause: unknown;
|
|
11
|
-
readonly state:
|
|
12
|
+
readonly state: Record<string, unknown>;
|
|
12
13
|
};
|
|
13
|
-
type IncrementalValueProcessor<
|
|
14
|
-
readonly kind: 'value';
|
|
15
|
-
readonly value: T;
|
|
16
|
-
readonly state?: IncrementalState;
|
|
17
|
-
} | {
|
|
14
|
+
type IncrementalValueProcessor<D extends readonly Projection<unknown, unknown>[], T> = (context: IncrementalValueContext<D, T>) => T | {
|
|
18
15
|
readonly kind: 'rebuild';
|
|
19
16
|
};
|
|
20
|
-
type IncrementalCollectionContext<
|
|
21
|
-
readonly sources:
|
|
17
|
+
type IncrementalCollectionContext<D extends readonly Projection<unknown, unknown>[], K extends string, V> = {
|
|
18
|
+
readonly sources: ProjectionValues<D>;
|
|
19
|
+
readonly changes: ProjectionChanges<D>;
|
|
22
20
|
readonly previous: CollectionRead<K, V>;
|
|
23
21
|
readonly next: CollectionRead<K, V>;
|
|
24
|
-
readonly change: unknown;
|
|
25
22
|
readonly reset: boolean;
|
|
26
23
|
readonly cause: unknown;
|
|
27
|
-
readonly state:
|
|
24
|
+
readonly state: Record<string, unknown>;
|
|
28
25
|
readonly output: CollectionDraft<K, V>;
|
|
29
26
|
};
|
|
30
|
-
type IncrementalCollectionProcessor<
|
|
27
|
+
type IncrementalCollectionProcessor<D extends readonly Projection<unknown, unknown>[], K extends string, V> = (context: IncrementalCollectionContext<D, K, V>) => void | {
|
|
31
28
|
readonly kind: 'rebuild';
|
|
32
29
|
};
|
|
33
|
-
type DependencyMap<D extends readonly Projection<unknown>[]> = { readonly [K in keyof D as `d${Extract<K, number>}`]: D[K] };
|
|
34
|
-
declare function createIncrementalValue<const D extends readonly Projection<unknown>[], T>(dependencies: D, processor: IncrementalValueProcessor<
|
|
35
|
-
declare function createIncrementalCollection<const D extends readonly Projection<unknown>[], K extends string, V>(dependencies: D, processor: IncrementalCollectionProcessor<
|
|
30
|
+
type DependencyMap<D extends readonly Projection<unknown, unknown>[]> = { readonly [K in keyof D as `d${Extract<K, number>}`]: D[K] };
|
|
31
|
+
declare function createIncrementalValue<const D extends readonly Projection<unknown, unknown>[], T>(dependencies: D, processor: IncrementalValueProcessor<D, T>): Projection<T>;
|
|
32
|
+
declare function createIncrementalCollection<const D extends readonly Projection<unknown, unknown>[], K extends string, V>(dependencies: D, processor: IncrementalCollectionProcessor<D, K, V>): Projection<ReadonlyMap<K, V>, CollectionChange<K, V>>;
|
|
36
33
|
declare const incremental: typeof createIncrementalValue & {
|
|
37
34
|
collection: typeof createIncrementalCollection;
|
|
38
35
|
};
|
|
39
|
-
type IncrementalDependencies<D extends readonly Projection<unknown>[]> = DependencyMap<D>;
|
|
36
|
+
type IncrementalDependencies<D extends readonly Projection<unknown, unknown>[]> = DependencyMap<D>;
|
|
40
37
|
//#endregion
|
|
41
|
-
export { IncrementalCollectionContext, IncrementalCollectionProcessor, IncrementalDependencies,
|
|
38
|
+
export { type CollectionChange, IncrementalCollectionContext, IncrementalCollectionProcessor, IncrementalDependencies, IncrementalValueContext, IncrementalValueProcessor, incremental };
|
|
42
39
|
//# sourceMappingURL=advanced.d.ts.map
|
package/dist/advanced.js
CHANGED
|
@@ -1,71 +1,97 @@
|
|
|
1
1
|
import { i as snapshot } from "./scope-d-L87NeC.js";
|
|
2
|
-
import { n as defineIncrementalValue, t as defineIncrementalCollection } from "./definition-
|
|
2
|
+
import { n as defineIncrementalValue, t as defineIncrementalCollection } from "./definition-DUo1lfQ8.js";
|
|
3
3
|
//#region core/src/projection/advanced.ts
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
|
|
4
|
+
const resetCollectionChange = Object.freeze({ kind: "reset" });
|
|
5
|
+
const isRebuild = (value) => value !== null && typeof value === "object" && value.kind === "rebuild";
|
|
6
|
+
const collectionChange = (source) => {
|
|
7
|
+
if (!source || typeof source !== "object" || !("kind" in source)) return void 0;
|
|
8
|
+
if (source.kind !== "collection") return void 0;
|
|
9
|
+
return source.change;
|
|
7
10
|
};
|
|
8
11
|
const sourceCause = (sources) => {
|
|
9
|
-
for (const source of Object.values(sources)) if (source && typeof source === "object" && "
|
|
12
|
+
for (const source of Object.values(sources)) if (source && typeof source === "object" && "kind" in source) {
|
|
13
|
+
const cause = source.cause;
|
|
14
|
+
if (cause !== void 0) return cause;
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
const collectionView = (read) => {
|
|
18
|
+
const entries = function* () {
|
|
19
|
+
for (const key of read.ids()) yield [key, read.get(key)];
|
|
20
|
+
};
|
|
21
|
+
const values = function* () {
|
|
22
|
+
for (const key of read.ids()) yield read.get(key);
|
|
23
|
+
};
|
|
24
|
+
const view = {
|
|
25
|
+
get: (key) => read.get(key),
|
|
26
|
+
has: (key) => read.has(key),
|
|
27
|
+
get size() {
|
|
28
|
+
return read.ids().length;
|
|
29
|
+
},
|
|
30
|
+
keys: () => read.ids()[Symbol.iterator](),
|
|
31
|
+
values,
|
|
32
|
+
entries,
|
|
33
|
+
forEach: (callback, thisArg) => {
|
|
34
|
+
for (const key of read.ids()) callback.call(thisArg, read.get(key), key, view);
|
|
35
|
+
},
|
|
36
|
+
[Symbol.iterator]: entries
|
|
37
|
+
};
|
|
38
|
+
return Object.freeze(view);
|
|
10
39
|
};
|
|
11
40
|
const publicSource = (source) => {
|
|
12
41
|
if (!source || typeof source !== "object") return source;
|
|
13
|
-
if ("
|
|
14
|
-
if ("
|
|
42
|
+
if (!("kind" in source)) return source;
|
|
43
|
+
if (source.kind === "value") return source.value;
|
|
44
|
+
if (source.kind === "document") return snapshot(source.read);
|
|
45
|
+
if (source.kind === "collection") {
|
|
15
46
|
const read = source.read;
|
|
16
|
-
|
|
17
|
-
const result = /* @__PURE__ */ new Map();
|
|
18
|
-
for (const id of read.ids()) result.set(id, read.get(id));
|
|
19
|
-
return result;
|
|
20
|
-
}
|
|
21
|
-
return snapshot(read);
|
|
22
|
-
}
|
|
23
|
-
if ("ids" in source && typeof source.ids === "function") {
|
|
24
|
-
const result = /* @__PURE__ */ new Map();
|
|
25
|
-
const read = source;
|
|
26
|
-
for (const id of read.ids()) result.set(id, read.get(id));
|
|
27
|
-
return result;
|
|
47
|
+
return collectionView(read);
|
|
28
48
|
}
|
|
29
49
|
return source;
|
|
30
50
|
};
|
|
31
|
-
const
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
51
|
+
const publicInputs = (sources, initial = false) => {
|
|
52
|
+
const values = [];
|
|
53
|
+
const changes = [];
|
|
54
|
+
for (const key of Object.keys(sources).sort((left, right) => Number(left.slice(1)) - Number(right.slice(1)))) {
|
|
55
|
+
const source = sources[key];
|
|
56
|
+
values.push(publicSource(source));
|
|
57
|
+
changes.push(initial && source && typeof source === "object" && "kind" in source && source.kind === "collection" ? resetCollectionChange : collectionChange(source));
|
|
58
|
+
}
|
|
59
|
+
return {
|
|
60
|
+
values,
|
|
61
|
+
changes
|
|
62
|
+
};
|
|
63
|
+
};
|
|
36
64
|
function createIncrementalValue(dependencies, processor) {
|
|
37
65
|
const dependencyMap = dependenciesOf(dependencies);
|
|
38
66
|
let state = Object.create(null);
|
|
39
67
|
let current;
|
|
40
68
|
const build = (sources) => {
|
|
41
69
|
state = Object.create(null);
|
|
70
|
+
const publicInputsForBuild = publicInputs(sources, true);
|
|
42
71
|
const result = processor({
|
|
43
|
-
sources:
|
|
72
|
+
sources: publicInputsForBuild.values,
|
|
73
|
+
changes: publicInputsForBuild.changes,
|
|
44
74
|
previous: void 0,
|
|
45
75
|
reset: true,
|
|
46
|
-
change: void 0,
|
|
47
76
|
cause: sourceCause(sources),
|
|
48
77
|
state
|
|
49
78
|
});
|
|
50
|
-
if (result
|
|
51
|
-
|
|
52
|
-
current = normalized.value;
|
|
53
|
-
if (normalized.state) state = normalized.state;
|
|
79
|
+
if (isRebuild(result)) throw new TypeError("Initial incremental processor cannot rebuild.");
|
|
80
|
+
current = result;
|
|
54
81
|
return {
|
|
55
82
|
value: current,
|
|
56
83
|
update: (nextSources) => {
|
|
84
|
+
const publicInputsForUpdate = publicInputs(nextSources);
|
|
57
85
|
const next = processor({
|
|
58
|
-
sources:
|
|
86
|
+
sources: publicInputsForUpdate.values,
|
|
87
|
+
changes: publicInputsForUpdate.changes,
|
|
59
88
|
previous: current,
|
|
60
89
|
reset: false,
|
|
61
|
-
change: sourceChange(nextSources),
|
|
62
90
|
cause: sourceCause(nextSources),
|
|
63
91
|
state
|
|
64
92
|
});
|
|
65
|
-
if (next
|
|
66
|
-
|
|
67
|
-
current = nextValue.value;
|
|
68
|
-
if (nextValue.state) state = nextValue.state;
|
|
93
|
+
if (isRebuild(next)) return next;
|
|
94
|
+
current = next;
|
|
69
95
|
return {
|
|
70
96
|
kind: "changed",
|
|
71
97
|
value: current
|
|
@@ -78,31 +104,38 @@ function createIncrementalValue(dependencies, processor) {
|
|
|
78
104
|
build
|
|
79
105
|
});
|
|
80
106
|
}
|
|
107
|
+
function dependenciesOf(dependencies) {
|
|
108
|
+
return Object.fromEntries(dependencies.map((dependency, index) => [`d${index}`, dependency]));
|
|
109
|
+
}
|
|
81
110
|
function createIncrementalCollection(dependencies, processor) {
|
|
82
111
|
const dependencyMap = dependenciesOf(dependencies);
|
|
83
112
|
let state = Object.create(null);
|
|
84
113
|
const build = (input) => {
|
|
85
114
|
state = Object.create(null);
|
|
115
|
+
const publicInputsForBuild = publicInputs(input.sources, true);
|
|
86
116
|
if (processor({
|
|
87
|
-
sources:
|
|
117
|
+
sources: publicInputsForBuild.values,
|
|
118
|
+
changes: publicInputsForBuild.changes,
|
|
88
119
|
previous: input.previous,
|
|
89
120
|
next: input.next,
|
|
90
121
|
reset: true,
|
|
91
|
-
change: void 0,
|
|
92
122
|
cause: sourceCause(input.sources),
|
|
93
123
|
state,
|
|
94
|
-
output: input.
|
|
124
|
+
output: input.output
|
|
95
125
|
})?.kind === "rebuild") throw new TypeError("Initial incremental collection processor cannot rebuild.");
|
|
96
|
-
return { update: (nextInput) =>
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
126
|
+
return { update: (nextInput) => {
|
|
127
|
+
const publicInputsForUpdate = publicInputs(nextInput.sources);
|
|
128
|
+
return processor({
|
|
129
|
+
sources: publicInputsForUpdate.values,
|
|
130
|
+
changes: publicInputsForUpdate.changes,
|
|
131
|
+
previous: nextInput.previous,
|
|
132
|
+
next: nextInput.next,
|
|
133
|
+
reset: false,
|
|
134
|
+
cause: sourceCause(nextInput.sources),
|
|
135
|
+
state,
|
|
136
|
+
output: nextInput.output
|
|
137
|
+
});
|
|
138
|
+
} };
|
|
106
139
|
};
|
|
107
140
|
return defineIncrementalCollection({
|
|
108
141
|
dependencies: dependencyMap,
|
package/dist/advanced.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"advanced.js","names":[],"sources":["../core/src/projection/advanced.ts"],"sourcesContent":["import type { Projection, ProjectionValues, PublicCollection } from './definition';\nimport { defineIncrementalCollection, defineIncrementalValue } from './definition';\nimport type { CollectionDraft, CollectionRead, GraphSources } from './contract';\nimport { snapshot } from '../access/scope';\n\nexport type IncrementalState = Record<string, unknown>;\n\nexport type IncrementalValueContext<S, T> = {\n readonly sources: S;\n readonly previous: T | undefined;\n readonly reset: boolean;\n readonly change: unknown;\n readonly cause: unknown;\n readonly state: IncrementalState;\n};\n\nexport type IncrementalValueProcessor<S, T> = (\n context: IncrementalValueContext<S, T>\n) =>\n | T\n | { readonly kind: 'value'; readonly value: T; readonly state?: IncrementalState }\n | { readonly kind: 'rebuild' };\n\nexport type IncrementalCollectionContext<S, K extends string, V> = {\n readonly sources: S;\n readonly previous: CollectionRead<K, V>;\n readonly next: CollectionRead<K, V>;\n readonly change: unknown;\n readonly reset: boolean;\n readonly cause: unknown;\n readonly state: IncrementalState;\n readonly output: CollectionDraft<K, V>;\n};\n\nexport type IncrementalCollectionProcessor<S, K extends string, V> = (\n context: IncrementalCollectionContext<S, K, V>\n) => void | { readonly kind: 'rebuild' };\n\ntype DependencyMap<D extends readonly Projection<unknown>[]> = {\n readonly [K in keyof D as `d${Extract<K, number>}`]: D[K];\n};\n\nconst dependenciesOf = <D extends readonly Projection<unknown>[]>(dependencies: D): GraphSources =>\n Object.fromEntries(\n dependencies.map((dependency, index) => [`d${index}`, dependency])\n ) as unknown as GraphSources;\n\nconst sourceChange = (sources: Record<string, unknown>): unknown => {\n for (const source of Object.values(sources)) {\n if (\n source &&\n typeof source === 'object' &&\n 'change' in source &&\n (source as { readonly change?: unknown }).change !== undefined\n )\n return (source as { readonly change?: unknown }).change;\n }\n return undefined;\n};\n\nconst sourceCause = (sources: Record<string, unknown>): unknown => {\n for (const source of Object.values(sources)) {\n if (\n source &&\n typeof source === 'object' &&\n 'cause' in source &&\n (source as { readonly cause?: unknown }).cause !== undefined\n )\n return (source as { readonly cause?: unknown }).cause;\n }\n return undefined;\n};\n\nconst publicSource = (source: unknown): unknown => {\n if (!source || typeof source !== 'object') return source;\n if ('value' in source) return (source as { readonly value: unknown }).value;\n if ('read' in source) {\n const read = (source as { readonly read: unknown }).read;\n if (\n read &&\n typeof read === 'object' &&\n 'ids' in read &&\n typeof (read as { ids?: unknown }).ids === 'function'\n ) {\n const result = new Map<string, unknown>();\n for (const id of (read as CollectionRead<string, unknown>).ids())\n result.set(id, (read as CollectionRead<string, unknown>).get(id));\n return result;\n }\n return snapshot(read);\n }\n if ('ids' in source && typeof (source as { ids?: unknown }).ids === 'function') {\n const result = new Map<string, unknown>();\n const read = source as CollectionRead<string, unknown>;\n for (const id of read.ids()) result.set(id, read.get(id));\n return result;\n }\n return source;\n};\n\nconst publicTuple = (sources: Record<string, unknown>): readonly unknown[] =>\n Object.keys(sources)\n .sort((left, right) => Number(left.slice(1)) - Number(right.slice(1)))\n .map(key => publicSource(sources[key]));\n\nconst normalizeValue = <T>(\n result: T | { readonly kind: 'value'; readonly value: T; readonly state?: IncrementalState }\n): { value: T; state?: IncrementalState } =>\n result && typeof result === 'object' && (result as { readonly kind?: unknown }).kind === 'value'\n ? {\n value: (result as { readonly value: T }).value,\n state: (result as { readonly state?: IncrementalState }).state,\n }\n : { value: result as T };\n\nfunction createIncrementalValue<const D extends readonly Projection<unknown>[], T>(\n dependencies: D,\n processor: IncrementalValueProcessor<ProjectionValues<D>, T>\n): Projection<T> {\n const dependencyMap = dependenciesOf(dependencies);\n let state: IncrementalState = Object.create(null) as IncrementalState;\n let current!: T;\n const build = (sources: Record<string, unknown>) => {\n state = Object.create(null) as IncrementalState;\n const result = processor({\n sources: publicTuple(sources) as ProjectionValues<D>,\n previous: undefined,\n reset: true,\n change: undefined,\n cause: sourceCause(sources),\n state,\n });\n if (result && typeof result === 'object' && 'kind' in result)\n throw new TypeError('Initial incremental processor cannot rebuild.');\n const normalized = normalizeValue(result as T);\n current = normalized.value;\n if (normalized.state) state = normalized.state;\n return {\n value: current,\n update: (nextSources: Record<string, unknown>) => {\n const next = processor({\n sources: publicTuple(nextSources) as ProjectionValues<D>,\n previous: current,\n reset: false,\n change: sourceChange(nextSources),\n cause: sourceCause(nextSources),\n state,\n });\n if (next && typeof next === 'object' && 'kind' in next) return next;\n const nextValue = normalizeValue(next as T);\n current = nextValue.value;\n if (nextValue.state) state = nextValue.state;\n return { kind: 'changed', value: current } as const;\n },\n };\n };\n return defineIncrementalValue({ dependencies: dependencyMap, build: build as never });\n}\n\nfunction createIncrementalCollection<\n const D extends readonly Projection<unknown>[],\n K extends string,\n V,\n>(\n dependencies: D,\n processor: IncrementalCollectionProcessor<ProjectionValues<D>, K, V>\n): Projection<PublicCollection<K, V>> {\n const dependencyMap = dependenciesOf(dependencies);\n let state: IncrementalState = Object.create(null) as IncrementalState;\n const build = (input: {\n readonly sources: Record<string, unknown>;\n readonly previous: CollectionRead<K, V>;\n readonly next: CollectionRead<K, V>;\n readonly writer: CollectionDraft<K, V>;\n }) => {\n state = Object.create(null) as IncrementalState;\n const result = processor({\n sources: publicTuple(input.sources) as ProjectionValues<D>,\n previous: input.previous,\n next: input.next,\n reset: true,\n change: undefined,\n cause: sourceCause(input.sources),\n state,\n output: input.writer,\n });\n if (result?.kind === 'rebuild')\n throw new TypeError('Initial incremental collection processor cannot rebuild.');\n return {\n update: (nextInput: typeof input) =>\n processor({\n sources: publicTuple(nextInput.sources) as ProjectionValues<D>,\n previous: nextInput.previous,\n next: nextInput.next,\n reset: false,\n change: sourceChange(nextInput.sources),\n cause: sourceCause(nextInput.sources),\n state,\n output: nextInput.writer,\n }),\n };\n };\n return defineIncrementalCollection({ dependencies: dependencyMap, build: build as never });\n}\n\nexport const incremental = Object.assign(createIncrementalValue, {\n collection: createIncrementalCollection,\n});\n\nexport type IncrementalDependencies<D extends readonly Projection<unknown>[]> = DependencyMap<D>;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"advanced.js","names":[],"sources":["../core/src/projection/advanced.ts"],"sourcesContent":["import type { Projection } from './definition';\nimport { defineIncrementalCollection, defineIncrementalValue } from './definition';\nimport type { CollectionChange, CollectionDraft, CollectionRead, GraphSources } from './contract';\nimport { snapshot } from '../access/scope';\n\ntype ProjectionValues<D extends readonly Projection<unknown, unknown>[]> = {\n readonly [K in keyof D]: D[K] extends Projection<infer T, unknown> ? T : never;\n};\n\ntype ProjectionChanges<D extends readonly Projection<unknown, unknown>[]> = {\n readonly [K in keyof D]: D[K] extends Projection<unknown, infer C>\n ? [C] extends [undefined]\n ? undefined\n : C | undefined\n : undefined;\n};\n\nexport type IncrementalValueContext<D extends readonly Projection<unknown, unknown>[], T> = {\n readonly sources: ProjectionValues<D>;\n readonly changes: ProjectionChanges<D>;\n readonly previous: T | undefined;\n readonly reset: boolean;\n readonly cause: unknown;\n readonly state: Record<string, unknown>;\n};\n\nexport type IncrementalValueProcessor<D extends readonly Projection<unknown, unknown>[], T> = (\n context: IncrementalValueContext<D, T>\n) => T | { readonly kind: 'rebuild' };\n\nexport type IncrementalCollectionContext<\n D extends readonly Projection<unknown, unknown>[],\n K extends string,\n V,\n> = {\n readonly sources: 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 state: Record<string, unknown>;\n readonly output: CollectionDraft<K, V>;\n};\n\nexport type IncrementalCollectionProcessor<\n D extends readonly Projection<unknown, unknown>[],\n K extends string,\n V,\n> = (context: IncrementalCollectionContext<D, K, V>) => void | { readonly kind: 'rebuild' };\n\ntype DependencyMap<D extends readonly Projection<unknown, unknown>[]> = {\n readonly [K in keyof D as `d${Extract<K, number>}`]: D[K];\n};\n\nconst resetCollectionChange = Object.freeze({ kind: 'reset' as const });\n\nconst isRebuild = (value: unknown): value is { readonly kind: 'rebuild' } =>\n value !== null &&\n typeof value === 'object' &&\n (value as { readonly kind?: unknown }).kind === 'rebuild';\n\nconst collectionChange = (source: unknown): CollectionChange<string, unknown> | undefined => {\n if (!source || typeof source !== 'object' || !('kind' in source)) return undefined;\n if (source.kind !== 'collection') return undefined;\n return (source as { readonly change?: CollectionChange<string, unknown> }).change;\n};\n\nconst sourceCause = (sources: Record<string, unknown>): unknown => {\n for (const source of Object.values(sources)) {\n if (source && typeof source === 'object' && 'kind' in source) {\n const cause = (source as { readonly cause?: unknown }).cause;\n if (cause !== undefined) return cause;\n }\n }\n return undefined;\n};\n\nconst collectionView = <K extends string, V>(read: CollectionRead<K, V>): ReadonlyMap<K, V> => {\n const entries = function* (): IterableIterator<[K, V]> {\n for (const key of read.ids()) yield [key, read.get(key) as V];\n };\n const values = function* (): IterableIterator<V> {\n for (const key of read.ids()) yield read.get(key) as V;\n };\n const view: ReadonlyMap<K, V> = {\n get: key => read.get(key),\n has: key => read.has(key),\n get size() {\n return read.ids().length;\n },\n keys: () => read.ids()[Symbol.iterator](),\n values,\n entries,\n forEach: (callback, thisArg) => {\n for (const key of read.ids()) callback.call(thisArg, read.get(key) as V, key, view);\n },\n [Symbol.iterator]: entries,\n };\n return Object.freeze(view);\n};\n\nconst publicSource = (source: unknown): unknown => {\n if (!source || typeof source !== 'object') return source;\n if (!('kind' in source)) return source;\n if (source.kind === 'value') return (source as unknown as { readonly value: unknown }).value;\n if (source.kind === 'document')\n return snapshot((source as unknown as { readonly read: unknown }).read as never);\n if (source.kind === 'collection') {\n const read = (source as unknown as { readonly read: CollectionRead<string, unknown> }).read;\n return collectionView(read);\n }\n return source;\n};\n\nconst publicInputs = (\n sources: Record<string, unknown>,\n initial = false\n): { readonly values: readonly unknown[]; readonly changes: readonly unknown[] } => {\n const values: unknown[] = [];\n const changes: unknown[] = [];\n for (const key of Object.keys(sources).sort(\n (left, right) => Number(left.slice(1)) - Number(right.slice(1))\n )) {\n const source = sources[key];\n values.push(publicSource(source));\n changes.push(\n initial &&\n source &&\n typeof source === 'object' &&\n 'kind' in source &&\n source.kind === 'collection'\n ? resetCollectionChange\n : collectionChange(source)\n );\n }\n return { values, changes };\n};\n\nfunction createIncrementalValue<const D extends readonly Projection<unknown, unknown>[], T>(\n dependencies: D,\n processor: IncrementalValueProcessor<D, T>\n): Projection<T> {\n const dependencyMap = dependenciesOf(dependencies);\n let state: Record<string, unknown> = Object.create(null) as Record<string, unknown>;\n let current!: T;\n const build = (sources: Record<string, unknown>) => {\n state = Object.create(null) as Record<string, unknown>;\n const publicInputsForBuild = publicInputs(sources, true);\n const result = processor({\n sources: publicInputsForBuild.values as ProjectionValues<D>,\n changes: publicInputsForBuild.changes as ProjectionChanges<D>,\n previous: undefined,\n reset: true,\n cause: sourceCause(sources),\n state,\n });\n if (isRebuild(result)) throw new TypeError('Initial incremental processor cannot rebuild.');\n current = result as T;\n return {\n value: current,\n update: (nextSources: Record<string, unknown>) => {\n const publicInputsForUpdate = publicInputs(nextSources);\n const next = processor({\n sources: publicInputsForUpdate.values as ProjectionValues<D>,\n changes: publicInputsForUpdate.changes as ProjectionChanges<D>,\n previous: current,\n reset: false,\n cause: sourceCause(nextSources),\n state,\n });\n if (isRebuild(next)) return next;\n current = next as T;\n return { kind: 'changed', value: current } as const;\n },\n };\n };\n return defineIncrementalValue({ dependencies: dependencyMap, build: build as never });\n}\n\nfunction dependenciesOf<D extends readonly Projection<unknown, unknown>[]>(\n dependencies: D\n): GraphSources {\n return Object.fromEntries(\n dependencies.map((dependency, index) => [`d${index}`, dependency])\n ) as unknown as GraphSources;\n}\n\nfunction createIncrementalCollection<\n const D extends readonly Projection<unknown, unknown>[],\n K extends string,\n V,\n>(\n dependencies: D,\n processor: IncrementalCollectionProcessor<D, K, V>\n): Projection<ReadonlyMap<K, V>, CollectionChange<K, V>> {\n const dependencyMap = dependenciesOf(dependencies);\n let state: Record<string, unknown> = Object.create(null) as Record<string, unknown>;\n const build = (input: {\n readonly sources: Record<string, unknown>;\n readonly previous: CollectionRead<K, V>;\n readonly next: CollectionRead<K, V>;\n readonly output: CollectionDraft<K, V>;\n }) => {\n state = Object.create(null) as Record<string, unknown>;\n const publicInputsForBuild = publicInputs(input.sources, true);\n const result = processor({\n sources: publicInputsForBuild.values as ProjectionValues<D>,\n changes: publicInputsForBuild.changes as ProjectionChanges<D>,\n previous: input.previous,\n next: input.next,\n reset: true,\n cause: sourceCause(input.sources),\n state,\n output: input.output,\n });\n if (result?.kind === 'rebuild')\n throw new TypeError('Initial incremental collection processor cannot rebuild.');\n return {\n update: (nextInput: typeof input) => {\n const publicInputsForUpdate = publicInputs(nextInput.sources);\n return processor({\n sources: publicInputsForUpdate.values as ProjectionValues<D>,\n changes: publicInputsForUpdate.changes as ProjectionChanges<D>,\n previous: nextInput.previous,\n next: nextInput.next,\n reset: false,\n cause: sourceCause(nextInput.sources),\n state,\n output: nextInput.output,\n });\n },\n };\n };\n return defineIncrementalCollection({ dependencies: dependencyMap, build: build as never });\n}\n\nexport const incremental = Object.assign(createIncrementalValue, {\n collection: createIncrementalCollection,\n});\n\nexport type IncrementalDependencies<D extends readonly Projection<unknown, unknown>[]> =\n DependencyMap<D>;\n\nexport type { CollectionChange } from './contract';\n"],"mappings":"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"}
|