doxum 0.1.25 → 0.1.26

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.
@@ -1,4 +1,4 @@
1
- import { W as ObjectSchema, g as Readable, s as DocumentRuntime } from "./contract-DB8XvNt0.cjs";
1
+ import { W as ObjectSchema, g as Readable, s as DocumentRuntime } from "./contract-CNR6BS75.cjs";
2
2
 
3
3
  //#region core/src/local-sync/json.d.ts
4
4
  type JsonPrimitive = null | boolean | number | string;
@@ -1,4 +1,4 @@
1
- import { W as ObjectSchema, g as Readable, s as DocumentRuntime } from "./contract-Dawq6LKS.js";
1
+ import { W as ObjectSchema, g as Readable, s as DocumentRuntime } from "./contract-COgxO5sv.js";
2
2
 
3
3
  //#region core/src/local-sync/json.d.ts
4
4
  type JsonPrimitive = null | boolean | number | string;
@@ -1 +1 @@
1
- {"version":3,"file":"scheduler--137L3j-.js","names":[],"sources":["../core/src/profile.ts","../core/src/projection/definition.ts","../core/src/projection/collection/view.ts","../core/src/projection/contract.ts","../core/src/projection/graph/scheduler.ts"],"sourcesContent":["const counters = () => ({\n projection: {\n sourceEvents: 0,\n scheduledNodes: 0,\n processedNodes: 0,\n touchedKeys: 0,\n changedKeys: 0,\n publishedNodes: 0,\n flushes: 0,\n },\n copy: { structures: 0, treeNodes: 0, shallowRecordItems: 0 },\n equality: { calls: 0, containers: 0 },\n recorder: {\n facts: 0,\n groups: 0,\n transitions: 0,\n absorbed: 0,\n orderSnapshots: 0,\n orderCaptures: 0,\n orderItems: 0,\n publishedOrderItems: 0,\n treeNodes: 0,\n sealed: 0,\n indexedGroups: 0,\n },\n access: { scopes: 0, proxies: 0, snapshots: 0, addresses: 0, resolutions: 0 },\n address: {\n schemaSteps: 0,\n documentSteps: 0,\n prefixComparisons: 0,\n segmentsCompared: 0,\n listIndexes: 0,\n listItems: 0,\n },\n impact: { affectsChecks: 0, indexes: 0 },\n dependency: { comparisons: 0, segmentsCompared: 0 },\n collectionIndex: { nodes: 0, builds: 0, builtItems: 0 },\n collectionView: { mappedItems: 0, idsScanned: 0, arraysCopied: 0 },\n materialized: { updated: 0, rebuilt: 0, notifications: 0 },\n});\ntype Counters = ReturnType<typeof counters>;\ntype DeepReadonly<T> = { readonly [K in keyof T]: T[K] extends object ? DeepReadonly<T[K]> : T[K] };\nexport type ProfileSnapshot = DeepReadonly<Counters>;\nlet active: Counters | undefined;\nconst freeze = <T extends object>(value: T): DeepReadonly<T> => {\n Object.values(value).forEach(child => {\n if (child && typeof child === 'object') freeze(child);\n });\n return Object.freeze(value) as DeepReadonly<T>;\n};\nexport const profile = {\n projection: (key: keyof Counters['projection'], amount = 1) => {\n if (active) active.projection[key] += amount;\n },\n recorder: (key: keyof Counters['recorder'], amount = 1) => {\n if (active) active.recorder[key] += amount;\n },\n access: (key: keyof Counters['access']) => {\n if (active) active.access[key]++;\n },\n copy: {\n structure: () => {\n if (active) active.copy.structures++;\n },\n treeNode: () => {\n if (active) active.copy.treeNodes++;\n },\n shallowRecord: (items: number) => {\n if (active) active.copy.shallowRecordItems += items;\n },\n },\n equality: {\n call: () => {\n if (active) active.equality.calls++;\n },\n container: () => {\n if (active) active.equality.containers++;\n },\n },\n address: {\n listIndex: (items: number) => {\n if (active) {\n active.address.listIndexes++;\n active.address.listItems += items;\n }\n },\n schemaStep: () => {\n if (active) active.address.schemaSteps++;\n },\n documentStep: () => {\n if (active) active.address.documentSteps++;\n },\n prefixComparison: () => {\n if (active) active.address.prefixComparisons++;\n },\n segmentCompared: () => {\n if (active) active.address.segmentsCompared++;\n },\n },\n impact: {\n index: () => {\n if (active) active.impact.indexes++;\n },\n affects: () => {\n if (active) active.impact.affectsChecks++;\n },\n },\n dependency: {\n comparison: () => {\n if (active) active.dependency.comparisons++;\n },\n segmentCompared: () => {\n if (active) active.dependency.segmentsCompared++;\n },\n },\n collectionIndex: {\n node: () => {\n if (active) active.collectionIndex.nodes++;\n },\n build: (items: number) => {\n if (active) {\n active.collectionIndex.builds++;\n active.collectionIndex.builtItems += items;\n }\n },\n },\n collectionView: {\n mapped: () => {\n if (active) active.collectionView.mappedItems++;\n },\n idsScanned: (amount = 1) => {\n if (active) active.collectionView.idsScanned += amount;\n },\n arrayCopied: () => {\n if (active) active.collectionView.arraysCopied++;\n },\n },\n materialized: {\n updated: () => {\n if (active) active.materialized.updated++;\n },\n rebuilt: () => {\n if (active) active.materialized.rebuilt++;\n },\n notification: () => {\n if (active) active.materialized.notifications++;\n },\n },\n};\nexport type ProfileSession = { snapshot(): ProfileSnapshot; stop(): ProfileSnapshot };\nexport const startProfile = (): ProfileSession => {\n if (active) throw new Error('A document profile session is already active.');\n const value = counters();\n active = value;\n const snapshot = () => freeze(structuredClone(value));\n return {\n snapshot,\n stop: () => {\n if (active === value) active = undefined;\n return snapshot();\n },\n };\n};\nexport const measureProfile = <T>(run: () => T): { value: T; profile: ProfileSnapshot } => {\n const session = startProfile();\n try {\n return { value: run(), profile: session.stop() };\n } finally {\n session.stop();\n }\n};\n","import type { ReadonlyDocument } from '../runtime/contract';\nimport type { ObjectSchema } from '../schema/model';\nimport type { CollectionSelector, ValueSelector } from '../schema/path';\nimport type {\n CollectionChange,\n CollectionDraft,\n CollectionRead,\n ExternalCollectionSource,\n ExternalValueSource,\n SourceContext,\n} from './contract';\nimport type { Readable } from '../readable';\n\ndeclare const projectionDefinition: unique symbol;\ndeclare const projectionChanges: unique symbol;\ndeclare const writableInput: unique symbol;\ndeclare const writableCollectionInput: unique symbol;\n\n/** A lazy output reference with no materialized Runtime state. */\nexport type Projection<T> = {\n readonly [projectionDefinition]: T;\n};\n\n/** A writable source projection. */\nexport type Input<T> = Projection<T> & { readonly [writableInput]: true };\n\n/** A writable keyed collection source projection. */\nexport type CollectionInput<K extends string, V> = Projection<ReadonlyMap<K, V>> & {\n readonly [writableCollectionInput]: { readonly key: K; readonly value: V };\n readonly [projectionChanges]: CollectionChange<K, V>;\n};\n\nexport type CollectionInputDraft<K extends string, V> = {\n get(key: K): V | undefined;\n has(key: K): boolean;\n set(key: K, value: V): void;\n remove(key: K): void;\n};\n\nexport type ProjectionWithChange<T, C> = Projection<T> & { readonly [projectionChanges]: C };\nexport type ProjectionChange<P> = P extends { readonly [projectionChanges]: infer C }\n ? C\n : undefined;\n\nexport type Equality = (a: unknown, b: unknown) => boolean;\n\nexport type OutputDefinition =\n | {\n readonly kind: 'value';\n readonly equality: Equality;\n readonly path?: readonly string[];\n }\n | {\n readonly kind: 'collection';\n readonly equality: Equality;\n readonly path?: readonly string[];\n };\n\nexport type ValueOutputEvaluation = {\n readonly kind: 'value';\n readonly previous: unknown;\n readonly next: () => unknown;\n readonly output: { set(value: unknown): void };\n};\n\nexport type CollectionOutputEvaluation = {\n readonly kind: 'collection';\n readonly previous: CollectionRead<string, unknown>;\n readonly next: CollectionRead<string, unknown>;\n readonly output: CollectionDraft<string, unknown>;\n};\n\nexport type OutputEvaluation = ValueOutputEvaluation | CollectionOutputEvaluation;\n\nexport type ProcessorEvaluation = {\n readonly reset: boolean;\n readonly cause: unknown;\n readonly sources: readonly SourceContext[];\n readonly outputs: readonly OutputEvaluation[];\n};\n\nexport type ProcessorInstance = {\n evaluate(input: ProcessorEvaluation): void;\n release?(): void;\n};\n\nexport type SourceAdapter =\n | {\n readonly kind: 'value-input';\n readonly initial: unknown;\n readonly equality: Equality;\n }\n | {\n readonly kind: 'collection-input';\n readonly initial: ReadonlyMap<string, unknown>;\n readonly equality: Equality;\n }\n | {\n readonly kind: 'readable';\n readonly readable: Readable<unknown>;\n readonly equality: Equality;\n }\n | {\n readonly kind: 'external-value';\n readonly source: ExternalValueSource<unknown>;\n readonly equality: Equality;\n }\n | {\n readonly kind: 'external-collection';\n readonly source: ExternalCollectionSource<string, unknown>;\n }\n | {\n readonly kind: 'document';\n readonly document: ReadonlyDocument<ObjectSchema<object>>;\n readonly selector: ValueSelector | CollectionSelector;\n };\n\nexport type SourceDefinition = {\n readonly kind: 'source';\n readonly source: SourceAdapter;\n readonly output: OutputDefinition;\n owner?: object;\n materialized?: true;\n};\n\nexport type ProcessorDefinition = {\n readonly kind: 'processor';\n readonly dependencies: readonly Projection<unknown>[];\n readonly outputs: readonly OutputDefinition[];\n readonly create: () => ProcessorInstance;\n readonly name?: string;\n owner?: object;\n materialized?: true;\n};\n\nexport type ProducerDefinition = SourceDefinition | ProcessorDefinition;\n\nexport type ProjectionRef = {\n readonly producer: ProducerDefinition;\n readonly output: number;\n};\n\nconst projections = new WeakMap<object, ProjectionRef>();\n\nconst defineRef = <T, C = undefined>(\n producer: ProducerDefinition,\n output: number\n): ProjectionWithChange<T, C> => {\n const handle = Object.freeze({}) as ProjectionWithChange<T, C>;\n projections.set(handle, Object.freeze({ producer, output }));\n return handle;\n};\n\nexport const projectionRef = (projection: Projection<unknown>): ProjectionRef => {\n const ref = projections.get(projection);\n if (!ref) throw new TypeError('Unknown projection definition.');\n return ref;\n};\n\nexport const producerOf = (projection: Projection<unknown>): ProducerDefinition =>\n projectionRef(projection).producer;\n\nexport const isProjection = (value: unknown): value is Projection<unknown> =>\n value !== null && typeof value === 'object' && projections.has(value);\n\nexport const ownProjections = (\n projections: readonly Projection<unknown>[],\n owner: object\n): void => {\n const producers = new Set(projections.map(producerOf));\n for (const producer of producers) {\n if (producer.owner !== undefined && producer.owner !== owner)\n throw new TypeError('Projection producer already belongs to another scope.');\n if (producer.owner === undefined && producer.materialized)\n throw new TypeError('A materialized root projection cannot become scope-owned.');\n if (producer.kind !== 'processor') continue;\n for (const dependency of producer.dependencies) {\n const dependencyOwner = producerOf(dependency).owner;\n if (dependencyOwner !== undefined && dependencyOwner !== owner)\n throw new TypeError('A scope cannot depend on another scope.');\n }\n }\n for (const producer of producers) producer.owner = owner;\n};\n\nconst freezeOutput = (output: OutputDefinition): OutputDefinition =>\n Object.freeze({\n kind: output.kind,\n equality: output.equality,\n ...(output.path ? { path: Object.freeze([...output.path]) } : {}),\n });\n\nexport const defineProcessor = (definition: {\n readonly dependencies: readonly Projection<unknown>[];\n readonly outputs: readonly OutputDefinition[];\n readonly create: () => ProcessorInstance;\n readonly name?: string;\n}): readonly Projection<unknown>[] => {\n if (!Array.isArray(definition.dependencies))\n throw new TypeError('Projection dependencies must be an array.');\n definition.dependencies.forEach(projectionRef);\n if (!definition.outputs.length) throw new TypeError('Projection processor requires an output.');\n const producer: ProcessorDefinition = {\n kind: 'processor',\n dependencies: Object.freeze([...definition.dependencies]),\n outputs: Object.freeze(definition.outputs.map(freezeOutput)),\n create: definition.create,\n ...(definition.name ? { name: definition.name } : {}),\n };\n return Object.freeze(\n producer.outputs.map((_, output) => defineRef<unknown, unknown>(producer, output))\n );\n};\n\nexport const defineSource = <T, C = undefined>(\n source: SourceAdapter,\n output: OutputDefinition\n): ProjectionWithChange<T, C> => {\n const producer: SourceDefinition = {\n kind: 'source',\n source,\n output: freezeOutput(output),\n };\n return defineRef<T, C>(producer, 0);\n};\n","import type { CollectionRead } from '../contract';\n\nexport const mapRead = <K extends string, V>(value: ReadonlyMap<K, V>): CollectionRead<K, V> => ({\n get: key => value.get(key),\n has: key => value.has(key),\n ids: () => Object.freeze([...value.keys()]),\n});\n\n/** Immutable map-like view over a CollectionRead. */\nexport const collectionView = <K extends string, V>(\n read: CollectionRead<K, V>\n): ReadonlyMap<K, V> => {\n const ids = read.ids();\n const entries = function* (): IterableIterator<[K, V]> {\n for (const key of ids) yield [key, read.get(key) as V];\n };\n const values = function* (): IterableIterator<V> {\n for (const key of 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 ids.length;\n },\n keys: () => ids[Symbol.iterator](),\n values,\n entries,\n forEach: (callback, thisArg) => {\n for (const key of ids) callback.call(thisArg, read.get(key) as V, key, view);\n },\n [Symbol.iterator]: entries,\n };\n return Object.freeze(view);\n};\n\n/** Eager durable view used when a processor result may retain its dependency value. */\nexport const snapshotCollectionView = <K extends string, V>(\n read: CollectionRead<K, V>\n): ReadonlyMap<K, V> => {\n const ids = read.ids();\n const values = new Map<K, V>();\n for (const key of ids) values.set(key, read.get(key) as V);\n return collectionView(mapRead(values));\n};\n","import type { CollectionImpact } from '../impact';\nimport type { Unsubscribe } from '../runtime/contract';\n\n/** Scheduler-owned metadata for one Runtime batch. */\nexport type BatchContext = {\n readonly id: number;\n readonly cause?: unknown;\n};\n\n/** The one processor-facing collection transition protocol. */\nexport type CollectionChange<K extends string, V> =\n | { readonly kind: 'reset' }\n | {\n readonly kind: 'incremental';\n readonly added: readonly { readonly key: K; readonly after: V }[];\n readonly updated: readonly {\n readonly key: K;\n readonly before: V;\n readonly after: V;\n }[];\n readonly removed: readonly { readonly key: K; readonly before: V }[];\n readonly order?: {\n readonly before: readonly K[];\n readonly after: readonly K[];\n };\n };\n\nexport type ValueContext<T> = {\n readonly kind: 'value';\n readonly value: T;\n readonly revision: number;\n readonly reset: boolean;\n readonly cause?: unknown;\n};\n\nexport type CollectionRead<K extends string, V> = {\n get(key: K): V | undefined;\n has(key: K): boolean;\n ids(): readonly K[];\n};\n\nexport type ExternalCollectionRead<K extends string, V> = {\n readonly get: (key: K) => V | undefined;\n readonly has: (key: K) => boolean;\n readonly ids: () => readonly K[];\n};\n\nexport type CollectionContext<K extends string, V> = {\n readonly kind: 'collection';\n readonly read: CollectionRead<K, V>;\n readonly change: CollectionChange<K, V> | undefined;\n readonly revision: number;\n readonly reset: boolean;\n readonly cause?: unknown;\n};\n\nexport type SourceContext = ValueContext<unknown> | CollectionContext<string, unknown>;\n\nexport type ExternalValueSource<T> = {\n readonly kind: 'value';\n current(): T;\n revision(): number;\n subscribe(listener: (event: ExternalValueEvent<T>) => void): Unsubscribe;\n};\n\nexport type ExternalCollectionSource<K extends string, V> = {\n readonly kind: 'collection';\n current(): ExternalCollectionRead<K, V>;\n revision(): number;\n subscribe(listener: (event: ExternalCollectionEvent<K, V>) => void): Unsubscribe;\n};\n\nexport type ExternalValueEvent<T> = {\n readonly value: T;\n readonly revision: number;\n readonly reset?: boolean;\n readonly cause?: unknown;\n};\n\nexport type ExternalCollectionEvent<K extends string, V> = {\n /** Stable read from the source before this event or external batch. */\n readonly previous: ExternalCollectionRead<K, V>;\n readonly revision: number;\n /** Optional document-style hint; the adapter resolves the canonical change. */\n readonly impact?: CollectionImpact<K>;\n readonly cause?: unknown;\n};\n\nexport type CollectionDraft<K extends string, V> = {\n set(key: K, value: V): void;\n remove(key: K): void;\n order(ids: readonly K[]): void;\n};\n\nexport class ProjectionError extends Error {\n readonly cause: unknown;\n\n constructor(\n readonly phase: 'processor' | 'listener' | 'source' | 'blocked',\n cause: unknown\n ) {\n super(`Projection ${phase} failed.`, { cause });\n this.name = 'ProjectionError';\n this.cause = cause;\n }\n}\n\nexport class ProjectionDisposedError extends Error {\n constructor() {\n super('Projection has been disposed.');\n this.name = 'ProjectionDisposedError';\n }\n}\n","import { profile } from '../../profile';\nimport type { ObserverError, Unsubscribe } from '../../runtime/contract';\nimport type { BatchContext, SourceContext } from '../contract';\nimport { ProjectionDisposedError, ProjectionError } from '../contract';\n\ntype BatchOptions = { readonly cause?: unknown };\n\ntype ProducerBase = {\n readonly name: string;\n readonly outputs: readonly OutputRecord[];\n fault: ProjectionError | undefined;\n disposed: boolean;\n clear(): void;\n release(): void;\n};\n\nexport type OutputRecord = {\n readonly kind: 'value' | 'collection';\n readonly owner: ProducerRecord;\n context(active: () => boolean): SourceContext;\n current(): unknown;\n revision(): number;\n reset(): boolean;\n subscribe(listener: () => void): Unsubscribe;\n emit(call: (listener: () => void) => void): void;\n hasConsumers(): boolean;\n forEachConsumer(run: (consumer: ProcessorRecord) => void): void;\n attachConsumer(consumer: ProcessorRecord): void;\n detachConsumer(consumer: ProcessorRecord): void;\n clear(): void;\n release(): void;\n};\n\nexport type SourceBoundaryRecord = ProducerBase & {\n readonly kind: 'source';\n readonly outputs: readonly [OutputRecord];\n pendingCause(): unknown;\n recovering(): boolean;\n prepare(cause: unknown): { readonly changed: boolean; readonly force: boolean };\n publish(): void;\n};\n\nexport type ProcessorRecord = ProducerBase & {\n readonly kind: 'processor';\n readonly dependencies: readonly OutputRecord[];\n readonly order: number;\n evaluate(reset: boolean, cause: unknown, recreate?: boolean): readonly OutputRecord[];\n publish(): void;\n};\n\nexport type ProducerRecord = SourceBoundaryRecord | ProcessorRecord;\n\nexport const createScheduler = (onError: (error: ProjectionError) => void) => {\n let disposed = false;\n let depth = 0;\n let batchSequence = 0;\n let activeBatch: BatchContext | undefined;\n let phase: 'idle' | 'compute' | 'notify' = 'idle';\n let sequence = 0;\n const sources = new Set<SourceBoundaryRecord>();\n const processors = new Set<ProcessorRecord>();\n const pendingSources = new Set<SourceBoundaryRecord>();\n const heap: ProcessorRecord[] = [];\n const queued = new Set<ProcessorRecord>();\n const completed = new Set<ProcessorRecord>();\n const emissions = new Set<OutputRecord>();\n const errors: ProjectionError[] = [];\n let reportingFailures: unknown[] = [];\n const guards = new Set<(locked: boolean) => void>();\n\n const assertActive = () => {\n if (disposed) throw new ProjectionDisposedError();\n };\n const assertIdle = () => {\n assertActive();\n if (phase !== 'idle')\n throw new Error('Projection cannot be re-entered during processing or notification.');\n };\n const lock = (value: boolean) => guards.forEach(guard => guard(value));\n\n const enqueue = (processor: ProcessorRecord) => {\n if (processor.disposed || queued.has(processor)) return;\n queued.add(processor);\n profile.projection('scheduledNodes');\n let index = heap.length;\n heap.push(processor);\n while (index > 0) {\n const parent = (index - 1) >> 1;\n if (heap[parent].order < processor.order) break;\n heap[index] = heap[parent];\n index = parent;\n }\n heap[index] = processor;\n };\n\n const pop = (): ProcessorRecord => {\n const first = heap[0];\n const last = heap.pop()!;\n if (heap.length) {\n let index = 0;\n while (index * 2 + 1 < heap.length) {\n let child = index * 2 + 1;\n if (child + 1 < heap.length && heap[child + 1].order < heap[child].order) child++;\n if (last.order < heap[child].order) break;\n heap[index] = heap[child];\n index = child;\n }\n heap[index] = last;\n }\n return first;\n };\n\n const errorFor = (\n producer: ProducerRecord,\n cause: unknown,\n kind: ProjectionError['phase'] = producer.kind === 'source' ? 'source' : 'processor'\n ) => new ProjectionError(kind, cause);\n\n const capture = (source: SourceBoundaryRecord) => {\n if (disposed) return;\n if (phase !== 'idle') {\n source.fault = errorFor(\n source,\n new Error('Source changed while projection was running.'),\n 'source'\n );\n errors.push(source.fault);\n throw source.fault;\n }\n pendingSources.add(source);\n profile.projection('sourceEvents');\n if (source.fault) errors.push(source.fault);\n };\n\n const settleCause = (): unknown => {\n if (activeBatch?.cause !== undefined) return activeBatch.cause;\n for (const source of pendingSources) {\n const cause = source.pendingCause();\n if (cause !== undefined) return cause;\n }\n return undefined;\n };\n\n const settle = () => {\n if (disposed || depth || phase !== 'idle') return;\n phase = 'compute';\n lock(true);\n const cause = settleCause();\n try {\n for (const source of pendingSources) {\n if (source.disposed) continue;\n const wasFaulted = source.fault !== undefined;\n let changed = false;\n let force = false;\n if (!source.fault || source.recovering()) {\n try {\n const prepared = source.prepare(cause);\n changed = prepared.changed;\n force = prepared.force;\n source.fault = undefined;\n } catch (failure) {\n source.fault = errorFor(source, failure, 'source');\n errors.push(source.fault);\n }\n }\n const recovered = wasFaulted && !source.fault;\n if (changed) source.publish();\n if (source.fault || changed || force || recovered) {\n const output = source.outputs[0];\n emissions.add(output);\n output.forEachConsumer(enqueue);\n }\n }\n\n while (heap.length) {\n const processor = pop();\n if (processor.disposed) continue;\n const wasFaulted = processor.fault !== undefined;\n profile.projection('processedNodes');\n let changedOutputs: readonly OutputRecord[] = Object.freeze([]);\n const blocked = processor.dependencies.find(\n output => output.owner.fault || output.owner.disposed\n );\n if (blocked) {\n processor.fault = errorFor(\n processor,\n blocked.owner.fault ?? new ProjectionDisposedError(),\n 'blocked'\n );\n } else {\n const reset = wasFaulted || processor.dependencies.some(output => output.reset());\n try {\n changedOutputs = processor.evaluate(reset, cause, wasFaulted);\n const dependencyFailure = processor.dependencies.find(output => output.owner.fault)\n ?.owner.fault;\n if (dependencyFailure) throw dependencyFailure;\n processor.fault = undefined;\n } catch (failure) {\n const error = errorFor(processor, failure);\n processor.fault = error;\n if (!reset) {\n try {\n changedOutputs = processor.evaluate(true, cause, true);\n const dependencyFailure = processor.dependencies.find(output => output.owner.fault)\n ?.owner.fault;\n if (dependencyFailure) throw dependencyFailure;\n processor.fault = undefined;\n errors.push(error);\n } catch (rebuildFailure) {\n processor.fault = errorFor(processor, rebuildFailure);\n errors.push(processor.fault);\n }\n } else errors.push(error);\n }\n }\n completed.add(processor);\n const recovered = wasFaulted && !processor.fault;\n if (processor.fault) {\n processor.outputs.forEach(output => {\n emissions.add(output);\n output.forEachConsumer(enqueue);\n });\n } else {\n if (changedOutputs.length) {\n processor.publish();\n changedOutputs.forEach(output => emissions.add(output));\n }\n const propagated = recovered ? processor.outputs : changedOutputs;\n propagated.forEach(output => output.forEachConsumer(enqueue));\n }\n if (processor.fault || changedOutputs.length) {\n profile.projection('publishedNodes');\n }\n }\n } finally {\n lock(false);\n phase = 'idle';\n }\n };\n\n const flush = (): readonly ObserverError[] => {\n if (disposed || depth) return [];\n if (pendingSources.size || completed.size) profile.projection('flushes');\n phase = 'notify';\n lock(true);\n const reportFailures: unknown[] = [];\n try {\n emissions.forEach(output =>\n output.emit(listener => {\n try {\n listener();\n } catch (cause) {\n errors.push(errorFor(output.owner, cause, 'listener'));\n }\n })\n );\n for (const error of errors.slice()) {\n try {\n onError(error);\n } catch (cause) {\n reportFailures.push(cause);\n }\n }\n return Object.freeze([\n ...errors.map(error =>\n Object.freeze({\n phase: error.phase === 'listener' ? ('listener' as const) : ('processor' as const),\n error,\n })\n ),\n ...reportFailures.map(error => Object.freeze({ phase: 'listener' as const, error })),\n ]);\n } finally {\n pendingSources.forEach(source => source.clear());\n completed.forEach(processor => processor.clear());\n pendingSources.clear();\n queued.clear();\n completed.clear();\n emissions.clear();\n errors.length = 0;\n reportingFailures = reportFailures;\n lock(false);\n phase = 'idle';\n }\n };\n\n const run = () => {\n settle();\n const result = flush();\n const failures = reportingFailures;\n reportingFailures = [];\n if (failures.length) throw new AggregateError(failures, 'Projection error reporter failed.');\n return result;\n };\n\n const batch = <T>(callback: () => T, options?: BatchOptions): T => {\n assertIdle();\n const outer = depth === 0;\n if (outer)\n activeBatch = Object.freeze({\n id: ++batchSequence,\n ...(options?.cause === undefined ? {} : { cause: options.cause }),\n });\n depth++;\n let failed = false;\n try {\n const value = callback();\n assertSynchronous(value);\n return value;\n } catch (error) {\n failed = true;\n throw error;\n } finally {\n depth--;\n if (!depth) {\n try {\n if (failed) {\n try {\n run();\n } catch {\n /* The original application error retains priority. */\n }\n } else run();\n } finally {\n activeBatch = undefined;\n }\n }\n }\n };\n\n const releaseProducer = (producer: ProducerRecord) => {\n assertIdle();\n if (producer.outputs.some(output => output.hasConsumers()))\n throw new Error('Projection producer is still used by another processor.');\n producer.disposed = true;\n if (producer.kind === 'processor') {\n producer.dependencies.forEach(output => output.detachConsumer(producer));\n processors.delete(producer);\n queued.delete(producer);\n completed.delete(producer);\n } else {\n sources.delete(producer);\n pendingSources.delete(producer);\n }\n const failures: unknown[] = [];\n try {\n producer.release();\n } catch (error) {\n failures.push(error);\n }\n try {\n producer.clear();\n } catch (error) {\n failures.push(error);\n }\n producer.outputs.forEach(output => emissions.delete(output));\n if (failures.length) throw failures[0];\n };\n\n return {\n assertActive,\n assertIdle,\n capture,\n settle,\n flush,\n run,\n registerGuard(guard: (locked: boolean) => void): Unsubscribe {\n assertActive();\n guards.add(guard);\n let registered = true;\n return () => {\n if (!registered) return;\n registered = false;\n guards.delete(guard);\n };\n },\n get active() {\n return !disposed;\n },\n addSource(source: SourceBoundaryRecord) {\n assertIdle();\n sources.add(source);\n },\n addProcessor(processor: ProcessorRecord) {\n assertIdle();\n processors.add(processor);\n processor.dependencies.forEach(output => output.attachConsumer(processor));\n },\n releaseProducer,\n order: () => sequence++,\n initialize<T>(callback: () => T): T {\n assertIdle();\n phase = 'compute';\n lock(true);\n try {\n return callback();\n } finally {\n lock(false);\n phase = 'idle';\n }\n },\n batch,\n batchContext: () => activeBatch,\n dispose() {\n if (disposed) return;\n assertIdle();\n disposed = true;\n const failures: unknown[] = [];\n processors.forEach(processor => {\n processor.disposed = true;\n try {\n processor.release();\n } catch (error) {\n failures.push(error);\n }\n });\n sources.forEach(source => {\n source.disposed = true;\n try {\n source.release();\n } catch (error) {\n failures.push(error);\n }\n });\n processors.clear();\n sources.clear();\n pendingSources.clear();\n heap.length = 0;\n queued.clear();\n completed.clear();\n emissions.clear();\n guards.clear();\n errors.length = 0;\n reportingFailures = [];\n if (failures.length) throw new AggregateError(failures, 'Projection cleanup failed.');\n },\n };\n};\n\nexport type Scheduler = ReturnType<typeof createScheduler>;\n\nexport const assertSynchronous = (value: unknown): void => {\n if (\n value != null &&\n (typeof value === 'object' || typeof value === 'function') &&\n 'then' in value &&\n typeof value.then === 'function'\n )\n throw new TypeError('Projection callbacks must be synchronous.');\n};\n\nexport const assertScope = (active: () => boolean) => {\n if (!active()) throw new Error('Projection reader or writer is no longer active.');\n};\n"],"mappings":"AAkDA,MAAa,UAAU;CACrB,aAAa,KAAmC,SAAS,MAAM;CAG/D,WAAW,KAAiC,SAAS,MAAM;CAG3D,SAAS,QAAkC;CAG3C,MAAM;EACJ,iBAAiB;EAGjB,gBAAgB;EAGhB,gBAAgB,UAAkB;EAGnC;CACD,UAAU;EACR,YAAY;EAGZ,iBAAiB;EAGlB;CACD,SAAS;EACP,YAAY,UAAkB;EAM9B,kBAAkB;EAGlB,oBAAoB;EAGpB,wBAAwB;EAGxB,uBAAuB;EAGxB;CACD,QAAQ;EACN,aAAa;EAGb,eAAe;EAGhB;CACD,YAAY;EACV,kBAAkB;EAGlB,uBAAuB;EAGxB;CACD,iBAAiB;EACf,YAAY;EAGZ,QAAQ,UAAkB;EAM3B;CACD,gBAAgB;EACd,cAAc;EAGd,aAAa,SAAS,MAAM;EAG5B,mBAAmB;EAGpB;CACD,cAAc;EACZ,eAAe;EAGf,eAAe;EAGf,oBAAoB;EAGrB;CACF;;;ACND,MAAM,8BAAc,IAAI,SAAgC;AAExD,MAAM,aACJ,UACA,WAC+B;CAC/B,MAAM,SAAS,OAAO,OAAO,EAAE,CAAC;AAChC,aAAY,IAAI,QAAQ,OAAO,OAAO;EAAE;EAAU;EAAQ,CAAC,CAAC;AAC5D,QAAO;;AAGT,MAAa,iBAAiB,eAAmD;CAC/E,MAAM,MAAM,YAAY,IAAI,WAAW;AACvC,KAAI,CAAC,IAAK,OAAM,IAAI,UAAU,iCAAiC;AAC/D,QAAO;;AAGT,MAAa,cAAc,eACzB,cAAc,WAAW,CAAC;AAE5B,MAAa,gBAAgB,UAC3B,UAAU,QAAQ,OAAO,UAAU,YAAY,YAAY,IAAI,MAAM;AAEvE,MAAa,kBACX,aACA,UACS;CACT,MAAM,YAAY,IAAI,IAAI,YAAY,IAAI,WAAW,CAAC;AACtD,MAAK,MAAM,YAAY,WAAW;AAChC,MAAI,SAAS,UAAU,KAAA,KAAa,SAAS,UAAU,MACrD,OAAM,IAAI,UAAU,wDAAwD;AAC9E,MAAI,SAAS,UAAU,KAAA,KAAa,SAAS,aAC3C,OAAM,IAAI,UAAU,4DAA4D;AAClF,MAAI,SAAS,SAAS,YAAa;AACnC,OAAK,MAAM,cAAc,SAAS,cAAc;GAC9C,MAAM,kBAAkB,WAAW,WAAW,CAAC;AAC/C,OAAI,oBAAoB,KAAA,KAAa,oBAAoB,MACvD,OAAM,IAAI,UAAU,0CAA0C;;;AAGpE,MAAK,MAAM,YAAY,UAAW,UAAS,QAAQ;;AAGrD,MAAM,gBAAgB,WACpB,OAAO,OAAO;CACZ,MAAM,OAAO;CACb,UAAU,OAAO;CACjB,GAAI,OAAO,OAAO,EAAE,MAAM,OAAO,OAAO,CAAC,GAAG,OAAO,KAAK,CAAC,EAAE,GAAG,EAAE;CACjE,CAAC;AAEJ,MAAa,mBAAmB,eAKM;AACpC,KAAI,CAAC,MAAM,QAAQ,WAAW,aAAa,CACzC,OAAM,IAAI,UAAU,4CAA4C;AAClE,YAAW,aAAa,QAAQ,cAAc;AAC9C,KAAI,CAAC,WAAW,QAAQ,OAAQ,OAAM,IAAI,UAAU,2CAA2C;CAC/F,MAAM,WAAgC;EACpC,MAAM;EACN,cAAc,OAAO,OAAO,CAAC,GAAG,WAAW,aAAa,CAAC;EACzD,SAAS,OAAO,OAAO,WAAW,QAAQ,IAAI,aAAa,CAAC;EAC5D,QAAQ,WAAW;EACnB,GAAI,WAAW,OAAO,EAAE,MAAM,WAAW,MAAM,GAAG,EAAE;EACrD;AACD,QAAO,OAAO,OACZ,SAAS,QAAQ,KAAK,GAAG,WAAW,UAA4B,UAAU,OAAO,CAAC,CACnF;;AAGH,MAAa,gBACX,QACA,WAC+B;AAM/B,QAAO,UAAgB;EAJrB,MAAM;EACN;EACA,QAAQ,aAAa,OAAO;EAEC,EAAE,EAAE;;;;AC7NrC,MAAa,WAAgC,WAAoD;CAC/F,MAAK,QAAO,MAAM,IAAI,IAAI;CAC1B,MAAK,QAAO,MAAM,IAAI,IAAI;CAC1B,WAAW,OAAO,OAAO,CAAC,GAAG,MAAM,MAAM,CAAC,CAAC;CAC5C;;AAGD,MAAa,kBACX,SACsB;CACtB,MAAM,MAAM,KAAK,KAAK;CACtB,MAAM,UAAU,aAAuC;AACrD,OAAK,MAAM,OAAO,IAAK,OAAM,CAAC,KAAK,KAAK,IAAI,IAAI,CAAM;;CAExD,MAAM,SAAS,aAAkC;AAC/C,OAAK,MAAM,OAAO,IAAK,OAAM,KAAK,IAAI,IAAI;;CAE5C,MAAM,OAA0B;EAC9B,MAAK,QAAO,KAAK,IAAI,IAAI;EACzB,MAAK,QAAO,KAAK,IAAI,IAAI;EACzB,IAAI,OAAO;AACT,UAAO,IAAI;;EAEb,YAAY,IAAI,OAAO,WAAW;EAClC;EACA;EACA,UAAU,UAAU,YAAY;AAC9B,QAAK,MAAM,OAAO,IAAK,UAAS,KAAK,SAAS,KAAK,IAAI,IAAI,EAAO,KAAK,KAAK;;GAE7E,OAAO,WAAW;EACpB;AACD,QAAO,OAAO,OAAO,KAAK;;;AAI5B,MAAa,0BACX,SACsB;CACtB,MAAM,MAAM,KAAK,KAAK;CACtB,MAAM,yBAAS,IAAI,KAAW;AAC9B,MAAK,MAAM,OAAO,IAAK,QAAO,IAAI,KAAK,KAAK,IAAI,IAAI,CAAM;AAC1D,QAAO,eAAe,QAAQ,OAAO,CAAC;;;;ACmDxC,IAAa,kBAAb,cAAqC,MAAM;CACzC;CAEA,YACE,OACA,OACA;AACA,QAAM,cAAc,MAAM,WAAW,EAAE,OAAO,CAAC;AAHtC,OAAA,QAAA;AAIT,OAAK,OAAO;AACZ,OAAK,QAAQ;;;AAIjB,IAAa,0BAAb,cAA6C,MAAM;CACjD,cAAc;AACZ,QAAM,gCAAgC;AACtC,OAAK,OAAO;;;;;AC1DhB,MAAa,mBAAmB,YAA8C;CAC5E,IAAI,WAAW;CACf,IAAI,QAAQ;CACZ,IAAI,gBAAgB;CACpB,IAAI;CACJ,IAAI,QAAuC;CAC3C,IAAI,WAAW;CACf,MAAM,0BAAU,IAAI,KAA2B;CAC/C,MAAM,6BAAa,IAAI,KAAsB;CAC7C,MAAM,iCAAiB,IAAI,KAA2B;CACtD,MAAM,OAA0B,EAAE;CAClC,MAAM,yBAAS,IAAI,KAAsB;CACzC,MAAM,4BAAY,IAAI,KAAsB;CAC5C,MAAM,4BAAY,IAAI,KAAmB;CACzC,MAAM,SAA4B,EAAE;CACpC,IAAI,oBAA+B,EAAE;CACrC,MAAM,yBAAS,IAAI,KAAgC;CAEnD,MAAM,qBAAqB;AACzB,MAAI,SAAU,OAAM,IAAI,yBAAyB;;CAEnD,MAAM,mBAAmB;AACvB,gBAAc;AACd,MAAI,UAAU,OACZ,OAAM,IAAI,MAAM,qEAAqE;;CAEzF,MAAM,QAAQ,UAAmB,OAAO,SAAQ,UAAS,MAAM,MAAM,CAAC;CAEtE,MAAM,WAAW,cAA+B;AAC9C,MAAI,UAAU,YAAY,OAAO,IAAI,UAAU,CAAE;AACjD,SAAO,IAAI,UAAU;AACrB,UAAQ,WAAW,iBAAiB;EACpC,IAAI,QAAQ,KAAK;AACjB,OAAK,KAAK,UAAU;AACpB,SAAO,QAAQ,GAAG;GAChB,MAAM,SAAU,QAAQ,KAAM;AAC9B,OAAI,KAAK,QAAQ,QAAQ,UAAU,MAAO;AAC1C,QAAK,SAAS,KAAK;AACnB,WAAQ;;AAEV,OAAK,SAAS;;CAGhB,MAAM,YAA6B;EACjC,MAAM,QAAQ,KAAK;EACnB,MAAM,OAAO,KAAK,KAAK;AACvB,MAAI,KAAK,QAAQ;GACf,IAAI,QAAQ;AACZ,UAAO,QAAQ,IAAI,IAAI,KAAK,QAAQ;IAClC,IAAI,QAAQ,QAAQ,IAAI;AACxB,QAAI,QAAQ,IAAI,KAAK,UAAU,KAAK,QAAQ,GAAG,QAAQ,KAAK,OAAO,MAAO;AAC1E,QAAI,KAAK,QAAQ,KAAK,OAAO,MAAO;AACpC,SAAK,SAAS,KAAK;AACnB,YAAQ;;AAEV,QAAK,SAAS;;AAEhB,SAAO;;CAGT,MAAM,YACJ,UACA,OACA,OAAiC,SAAS,SAAS,WAAW,WAAW,gBACtE,IAAI,gBAAgB,MAAM,MAAM;CAErC,MAAM,WAAW,WAAiC;AAChD,MAAI,SAAU;AACd,MAAI,UAAU,QAAQ;AACpB,UAAO,QAAQ,SACb,wBACA,IAAI,MAAM,+CAA+C,EACzD,SACD;AACD,UAAO,KAAK,OAAO,MAAM;AACzB,SAAM,OAAO;;AAEf,iBAAe,IAAI,OAAO;AAC1B,UAAQ,WAAW,eAAe;AAClC,MAAI,OAAO,MAAO,QAAO,KAAK,OAAO,MAAM;;CAG7C,MAAM,oBAA6B;AACjC,MAAI,aAAa,UAAU,KAAA,EAAW,QAAO,YAAY;AACzD,OAAK,MAAM,UAAU,gBAAgB;GACnC,MAAM,QAAQ,OAAO,cAAc;AACnC,OAAI,UAAU,KAAA,EAAW,QAAO;;;CAKpC,MAAM,eAAe;AACnB,MAAI,YAAY,SAAS,UAAU,OAAQ;AAC3C,UAAQ;AACR,OAAK,KAAK;EACV,MAAM,QAAQ,aAAa;AAC3B,MAAI;AACF,QAAK,MAAM,UAAU,gBAAgB;AACnC,QAAI,OAAO,SAAU;IACrB,MAAM,aAAa,OAAO,UAAU,KAAA;IACpC,IAAI,UAAU;IACd,IAAI,QAAQ;AACZ,QAAI,CAAC,OAAO,SAAS,OAAO,YAAY,CACtC,KAAI;KACF,MAAM,WAAW,OAAO,QAAQ,MAAM;AACtC,eAAU,SAAS;AACnB,aAAQ,SAAS;AACjB,YAAO,QAAQ,KAAA;aACR,SAAS;AAChB,YAAO,QAAQ,SAAS,QAAQ,SAAS,SAAS;AAClD,YAAO,KAAK,OAAO,MAAM;;IAG7B,MAAM,YAAY,cAAc,CAAC,OAAO;AACxC,QAAI,QAAS,QAAO,SAAS;AAC7B,QAAI,OAAO,SAAS,WAAW,SAAS,WAAW;KACjD,MAAM,SAAS,OAAO,QAAQ;AAC9B,eAAU,IAAI,OAAO;AACrB,YAAO,gBAAgB,QAAQ;;;AAInC,UAAO,KAAK,QAAQ;IAClB,MAAM,YAAY,KAAK;AACvB,QAAI,UAAU,SAAU;IACxB,MAAM,aAAa,UAAU,UAAU,KAAA;AACvC,YAAQ,WAAW,iBAAiB;IACpC,IAAI,iBAA0C,OAAO,OAAO,EAAE,CAAC;IAC/D,MAAM,UAAU,UAAU,aAAa,MACrC,WAAU,OAAO,MAAM,SAAS,OAAO,MAAM,SAC9C;AACD,QAAI,QACF,WAAU,QAAQ,SAChB,WACA,QAAQ,MAAM,SAAS,IAAI,yBAAyB,EACpD,UACD;SACI;KACL,MAAM,QAAQ,cAAc,UAAU,aAAa,MAAK,WAAU,OAAO,OAAO,CAAC;AACjF,SAAI;AACF,uBAAiB,UAAU,SAAS,OAAO,OAAO,WAAW;MAC7D,MAAM,oBAAoB,UAAU,aAAa,MAAK,WAAU,OAAO,MAAM,MAAM,EAC/E,MAAM;AACV,UAAI,kBAAmB,OAAM;AAC7B,gBAAU,QAAQ,KAAA;cACX,SAAS;MAChB,MAAM,QAAQ,SAAS,WAAW,QAAQ;AAC1C,gBAAU,QAAQ;AAClB,UAAI,CAAC,MACH,KAAI;AACF,wBAAiB,UAAU,SAAS,MAAM,OAAO,KAAK;OACtD,MAAM,oBAAoB,UAAU,aAAa,MAAK,WAAU,OAAO,MAAM,MAAM,EAC/E,MAAM;AACV,WAAI,kBAAmB,OAAM;AAC7B,iBAAU,QAAQ,KAAA;AAClB,cAAO,KAAK,MAAM;eACX,gBAAgB;AACvB,iBAAU,QAAQ,SAAS,WAAW,eAAe;AACrD,cAAO,KAAK,UAAU,MAAM;;UAEzB,QAAO,KAAK,MAAM;;;AAG7B,cAAU,IAAI,UAAU;IACxB,MAAM,YAAY,cAAc,CAAC,UAAU;AAC3C,QAAI,UAAU,MACZ,WAAU,QAAQ,SAAQ,WAAU;AAClC,eAAU,IAAI,OAAO;AACrB,YAAO,gBAAgB,QAAQ;MAC/B;SACG;AACL,SAAI,eAAe,QAAQ;AACzB,gBAAU,SAAS;AACnB,qBAAe,SAAQ,WAAU,UAAU,IAAI,OAAO,CAAC;;AAGzD,MADmB,YAAY,UAAU,UAAU,gBACxC,SAAQ,WAAU,OAAO,gBAAgB,QAAQ,CAAC;;AAE/D,QAAI,UAAU,SAAS,eAAe,OACpC,SAAQ,WAAW,iBAAiB;;YAGhC;AACR,QAAK,MAAM;AACX,WAAQ;;;CAIZ,MAAM,cAAwC;AAC5C,MAAI,YAAY,MAAO,QAAO,EAAE;AAChC,MAAI,eAAe,QAAQ,UAAU,KAAM,SAAQ,WAAW,UAAU;AACxE,UAAQ;AACR,OAAK,KAAK;EACV,MAAM,iBAA4B,EAAE;AACpC,MAAI;AACF,aAAU,SAAQ,WAChB,OAAO,MAAK,aAAY;AACtB,QAAI;AACF,eAAU;aACH,OAAO;AACd,YAAO,KAAK,SAAS,OAAO,OAAO,OAAO,WAAW,CAAC;;KAExD,CACH;AACD,QAAK,MAAM,SAAS,OAAO,OAAO,CAChC,KAAI;AACF,YAAQ,MAAM;YACP,OAAO;AACd,mBAAe,KAAK,MAAM;;AAG9B,UAAO,OAAO,OAAO,CACnB,GAAG,OAAO,KAAI,UACZ,OAAO,OAAO;IACZ,OAAO,MAAM,UAAU,aAAc,aAAwB;IAC7D;IACD,CAAC,CACH,EACD,GAAG,eAAe,KAAI,UAAS,OAAO,OAAO;IAAE,OAAO;IAAqB;IAAO,CAAC,CAAC,CACrF,CAAC;YACM;AACR,kBAAe,SAAQ,WAAU,OAAO,OAAO,CAAC;AAChD,aAAU,SAAQ,cAAa,UAAU,OAAO,CAAC;AACjD,kBAAe,OAAO;AACtB,UAAO,OAAO;AACd,aAAU,OAAO;AACjB,aAAU,OAAO;AACjB,UAAO,SAAS;AAChB,uBAAoB;AACpB,QAAK,MAAM;AACX,WAAQ;;;CAIZ,MAAM,YAAY;AAChB,UAAQ;EACR,MAAM,SAAS,OAAO;EACtB,MAAM,WAAW;AACjB,sBAAoB,EAAE;AACtB,MAAI,SAAS,OAAQ,OAAM,IAAI,eAAe,UAAU,oCAAoC;AAC5F,SAAO;;CAGT,MAAM,SAAY,UAAmB,YAA8B;AACjE,cAAY;AAEZ,MADc,UAAU,EAEtB,eAAc,OAAO,OAAO;GAC1B,IAAI,EAAE;GACN,GAAI,SAAS,UAAU,KAAA,IAAY,EAAE,GAAG,EAAE,OAAO,QAAQ,OAAO;GACjE,CAAC;AACJ;EACA,IAAI,SAAS;AACb,MAAI;GACF,MAAM,QAAQ,UAAU;AACxB,qBAAkB,MAAM;AACxB,UAAO;WACA,OAAO;AACd,YAAS;AACT,SAAM;YACE;AACR;AACA,OAAI,CAAC,MACH,KAAI;AACF,QAAI,OACF,KAAI;AACF,UAAK;YACC;QAGH,MAAK;aACJ;AACR,kBAAc,KAAA;;;;CAMtB,MAAM,mBAAmB,aAA6B;AACpD,cAAY;AACZ,MAAI,SAAS,QAAQ,MAAK,WAAU,OAAO,cAAc,CAAC,CACxD,OAAM,IAAI,MAAM,0DAA0D;AAC5E,WAAS,WAAW;AACpB,MAAI,SAAS,SAAS,aAAa;AACjC,YAAS,aAAa,SAAQ,WAAU,OAAO,eAAe,SAAS,CAAC;AACxE,cAAW,OAAO,SAAS;AAC3B,UAAO,OAAO,SAAS;AACvB,aAAU,OAAO,SAAS;SACrB;AACL,WAAQ,OAAO,SAAS;AACxB,kBAAe,OAAO,SAAS;;EAEjC,MAAM,WAAsB,EAAE;AAC9B,MAAI;AACF,YAAS,SAAS;WACX,OAAO;AACd,YAAS,KAAK,MAAM;;AAEtB,MAAI;AACF,YAAS,OAAO;WACT,OAAO;AACd,YAAS,KAAK,MAAM;;AAEtB,WAAS,QAAQ,SAAQ,WAAU,UAAU,OAAO,OAAO,CAAC;AAC5D,MAAI,SAAS,OAAQ,OAAM,SAAS;;AAGtC,QAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA,cAAc,OAA+C;AAC3D,iBAAc;AACd,UAAO,IAAI,MAAM;GACjB,IAAI,aAAa;AACjB,gBAAa;AACX,QAAI,CAAC,WAAY;AACjB,iBAAa;AACb,WAAO,OAAO,MAAM;;;EAGxB,IAAI,SAAS;AACX,UAAO,CAAC;;EAEV,UAAU,QAA8B;AACtC,eAAY;AACZ,WAAQ,IAAI,OAAO;;EAErB,aAAa,WAA4B;AACvC,eAAY;AACZ,cAAW,IAAI,UAAU;AACzB,aAAU,aAAa,SAAQ,WAAU,OAAO,eAAe,UAAU,CAAC;;EAE5E;EACA,aAAa;EACb,WAAc,UAAsB;AAClC,eAAY;AACZ,WAAQ;AACR,QAAK,KAAK;AACV,OAAI;AACF,WAAO,UAAU;aACT;AACR,SAAK,MAAM;AACX,YAAQ;;;EAGZ;EACA,oBAAoB;EACpB,UAAU;AACR,OAAI,SAAU;AACd,eAAY;AACZ,cAAW;GACX,MAAM,WAAsB,EAAE;AAC9B,cAAW,SAAQ,cAAa;AAC9B,cAAU,WAAW;AACrB,QAAI;AACF,eAAU,SAAS;aACZ,OAAO;AACd,cAAS,KAAK,MAAM;;KAEtB;AACF,WAAQ,SAAQ,WAAU;AACxB,WAAO,WAAW;AAClB,QAAI;AACF,YAAO,SAAS;aACT,OAAO;AACd,cAAS,KAAK,MAAM;;KAEtB;AACF,cAAW,OAAO;AAClB,WAAQ,OAAO;AACf,kBAAe,OAAO;AACtB,QAAK,SAAS;AACd,UAAO,OAAO;AACd,aAAU,OAAO;AACjB,aAAU,OAAO;AACjB,UAAO,OAAO;AACd,UAAO,SAAS;AAChB,uBAAoB,EAAE;AACtB,OAAI,SAAS,OAAQ,OAAM,IAAI,eAAe,UAAU,6BAA6B;;EAExF;;AAKH,MAAa,qBAAqB,UAAyB;AACzD,KACE,SAAS,SACR,OAAO,UAAU,YAAY,OAAO,UAAU,eAC/C,UAAU,SACV,OAAO,MAAM,SAAS,WAEtB,OAAM,IAAI,UAAU,4CAA4C;;AAGpE,MAAa,eAAe,WAA0B;AACpD,KAAI,CAAC,QAAQ,CAAE,OAAM,IAAI,MAAM,mDAAmD"}
1
+ {"version":3,"file":"scheduler--137L3j-.js","names":[],"sources":["../core/src/profile.ts","../core/src/projection/definition.ts","../core/src/projection/collection/view.ts","../core/src/projection/contract.ts","../core/src/projection/graph/scheduler.ts"],"sourcesContent":["const counters = () => ({\n projection: {\n sourceEvents: 0,\n scheduledNodes: 0,\n processedNodes: 0,\n touchedKeys: 0,\n changedKeys: 0,\n publishedNodes: 0,\n flushes: 0,\n },\n copy: { structures: 0, treeNodes: 0, shallowRecordItems: 0 },\n equality: { calls: 0, containers: 0 },\n recorder: {\n facts: 0,\n groups: 0,\n transitions: 0,\n absorbed: 0,\n orderSnapshots: 0,\n orderCaptures: 0,\n orderItems: 0,\n publishedOrderItems: 0,\n treeNodes: 0,\n sealed: 0,\n indexedGroups: 0,\n },\n access: { scopes: 0, proxies: 0, snapshots: 0, addresses: 0, resolutions: 0 },\n address: {\n schemaSteps: 0,\n documentSteps: 0,\n prefixComparisons: 0,\n segmentsCompared: 0,\n listIndexes: 0,\n listItems: 0,\n },\n impact: { affectsChecks: 0, indexes: 0 },\n dependency: { comparisons: 0, segmentsCompared: 0 },\n collectionIndex: { nodes: 0, builds: 0, builtItems: 0 },\n collectionView: { mappedItems: 0, idsScanned: 0, arraysCopied: 0 },\n materialized: { updated: 0, rebuilt: 0, notifications: 0 },\n});\ntype Counters = ReturnType<typeof counters>;\ntype DeepReadonly<T> = { readonly [K in keyof T]: T[K] extends object ? DeepReadonly<T[K]> : T[K] };\nexport type ProfileSnapshot = DeepReadonly<Counters>;\nlet active: Counters | undefined;\nconst freeze = <T extends object>(value: T): DeepReadonly<T> => {\n Object.values(value).forEach(child => {\n if (child && typeof child === 'object') freeze(child);\n });\n return Object.freeze(value) as DeepReadonly<T>;\n};\nexport const profile = {\n projection: (key: keyof Counters['projection'], amount = 1) => {\n if (active) active.projection[key] += amount;\n },\n recorder: (key: keyof Counters['recorder'], amount = 1) => {\n if (active) active.recorder[key] += amount;\n },\n access: (key: keyof Counters['access']) => {\n if (active) active.access[key]++;\n },\n copy: {\n structure: () => {\n if (active) active.copy.structures++;\n },\n treeNode: () => {\n if (active) active.copy.treeNodes++;\n },\n shallowRecord: (items: number) => {\n if (active) active.copy.shallowRecordItems += items;\n },\n },\n equality: {\n call: () => {\n if (active) active.equality.calls++;\n },\n container: () => {\n if (active) active.equality.containers++;\n },\n },\n address: {\n listIndex: (items: number) => {\n if (active) {\n active.address.listIndexes++;\n active.address.listItems += items;\n }\n },\n schemaStep: () => {\n if (active) active.address.schemaSteps++;\n },\n documentStep: () => {\n if (active) active.address.documentSteps++;\n },\n prefixComparison: () => {\n if (active) active.address.prefixComparisons++;\n },\n segmentCompared: () => {\n if (active) active.address.segmentsCompared++;\n },\n },\n impact: {\n index: () => {\n if (active) active.impact.indexes++;\n },\n affects: () => {\n if (active) active.impact.affectsChecks++;\n },\n },\n dependency: {\n comparison: () => {\n if (active) active.dependency.comparisons++;\n },\n segmentCompared: () => {\n if (active) active.dependency.segmentsCompared++;\n },\n },\n collectionIndex: {\n node: () => {\n if (active) active.collectionIndex.nodes++;\n },\n build: (items: number) => {\n if (active) {\n active.collectionIndex.builds++;\n active.collectionIndex.builtItems += items;\n }\n },\n },\n collectionView: {\n mapped: () => {\n if (active) active.collectionView.mappedItems++;\n },\n idsScanned: (amount = 1) => {\n if (active) active.collectionView.idsScanned += amount;\n },\n arrayCopied: () => {\n if (active) active.collectionView.arraysCopied++;\n },\n },\n materialized: {\n updated: () => {\n if (active) active.materialized.updated++;\n },\n rebuilt: () => {\n if (active) active.materialized.rebuilt++;\n },\n notification: () => {\n if (active) active.materialized.notifications++;\n },\n },\n};\nexport type ProfileSession = { snapshot(): ProfileSnapshot; stop(): ProfileSnapshot };\nexport const startProfile = (): ProfileSession => {\n if (active) throw new Error('A document profile session is already active.');\n const value = counters();\n active = value;\n const snapshot = () => freeze(structuredClone(value));\n return {\n snapshot,\n stop: () => {\n if (active === value) active = undefined;\n return snapshot();\n },\n };\n};\nexport const measureProfile = <T>(run: () => T): { value: T; profile: ProfileSnapshot } => {\n const session = startProfile();\n try {\n return { value: run(), profile: session.stop() };\n } finally {\n session.stop();\n }\n};\n","import type { ReadonlyDocument } from '../runtime/contract';\nimport type { ObjectSchema } from '../schema/model';\nimport type { CollectionSelector, ValueSelector } from '../schema/path';\nimport type {\n CollectionChange,\n CollectionDraft,\n CollectionRead,\n ExternalCollectionSource,\n ExternalValueSource,\n SourceContext,\n} from './contract';\nimport type { Readable } from '../readable';\n\ndeclare const projectionDefinition: unique symbol;\ndeclare const keyedProjection: unique symbol;\ndeclare const writableInput: unique symbol;\ndeclare const writableCollectionInput: unique symbol;\n\n/** A lazy output reference with no materialized Runtime state. */\nexport type Projection<T> = {\n readonly [projectionDefinition]: T;\n};\n\n/** A projection whose output is a keyed collection with per-key change semantics. */\nexport type KeyedProjection<K extends string, V> = Projection<ReadonlyMap<K, V>> & {\n readonly [keyedProjection]: { readonly key: K; readonly value: V };\n};\n\n/** A writable source projection. */\nexport type Input<T> = Projection<T> & { readonly [writableInput]: true };\n\n/** A writable keyed collection source projection. */\nexport type CollectionInput<K extends string, V> = KeyedProjection<K, V> & {\n readonly [writableCollectionInput]: { readonly key: K; readonly value: V };\n};\n\nexport type CollectionInputDraft<K extends string, V> = {\n get(key: K): V | undefined;\n has(key: K): boolean;\n set(key: K, value: V): void;\n remove(key: K): void;\n};\n\nexport type ProjectionChange<P> =\n P extends KeyedProjection<infer K, infer V> ? CollectionChange<K, V> : undefined;\n\nexport type Equality = (a: unknown, b: unknown) => boolean;\n\nexport type OutputDefinition =\n | {\n readonly kind: 'value';\n readonly equality: Equality;\n readonly path?: readonly string[];\n }\n | {\n readonly kind: 'collection';\n readonly equality: Equality;\n readonly path?: readonly string[];\n };\n\nexport type ValueOutputEvaluation = {\n readonly kind: 'value';\n readonly previous: unknown;\n readonly next: () => unknown;\n readonly output: { set(value: unknown): void };\n};\n\nexport type CollectionOutputEvaluation = {\n readonly kind: 'collection';\n readonly previous: CollectionRead<string, unknown>;\n readonly next: CollectionRead<string, unknown>;\n readonly output: CollectionDraft<string, unknown>;\n};\n\nexport type OutputEvaluation = ValueOutputEvaluation | CollectionOutputEvaluation;\n\nexport type ProcessorEvaluation = {\n readonly reset: boolean;\n readonly cause: unknown;\n readonly sources: readonly SourceContext[];\n readonly outputs: readonly OutputEvaluation[];\n};\n\nexport type ProcessorInstance = {\n evaluate(input: ProcessorEvaluation): void;\n release?(): void;\n};\n\nexport type SourceAdapter =\n | {\n readonly kind: 'value-input';\n readonly initial: unknown;\n readonly equality: Equality;\n }\n | {\n readonly kind: 'collection-input';\n readonly initial: ReadonlyMap<string, unknown>;\n readonly equality: Equality;\n }\n | {\n readonly kind: 'readable';\n readonly readable: Readable<unknown>;\n readonly equality: Equality;\n }\n | {\n readonly kind: 'external-value';\n readonly source: ExternalValueSource<unknown>;\n readonly equality: Equality;\n }\n | {\n readonly kind: 'external-collection';\n readonly source: ExternalCollectionSource<string, unknown>;\n }\n | {\n readonly kind: 'document';\n readonly document: ReadonlyDocument<ObjectSchema<object>>;\n readonly selector: ValueSelector | CollectionSelector;\n };\n\nexport type SourceDefinition = {\n readonly kind: 'source';\n readonly source: SourceAdapter;\n readonly output: OutputDefinition;\n owner?: object;\n materialized?: true;\n};\n\nexport type ProcessorDefinition = {\n readonly kind: 'processor';\n readonly dependencies: readonly Projection<unknown>[];\n readonly outputs: readonly OutputDefinition[];\n readonly create: () => ProcessorInstance;\n readonly name?: string;\n owner?: object;\n materialized?: true;\n};\n\nexport type ProducerDefinition = SourceDefinition | ProcessorDefinition;\n\nexport type ProjectionRef = {\n readonly producer: ProducerDefinition;\n readonly output: number;\n};\n\nconst projections = new WeakMap<object, ProjectionRef>();\n\nconst defineRef = <T>(producer: ProducerDefinition, output: number): Projection<T> => {\n const handle = Object.freeze({}) as Projection<T>;\n projections.set(handle, Object.freeze({ producer, output }));\n return handle;\n};\n\nexport const projectionRef = (projection: Projection<unknown>): ProjectionRef => {\n const ref = projections.get(projection);\n if (!ref) throw new TypeError('Unknown projection definition.');\n return ref;\n};\n\nexport const producerOf = (projection: Projection<unknown>): ProducerDefinition =>\n projectionRef(projection).producer;\n\nexport const isProjection = (value: unknown): value is Projection<unknown> =>\n value !== null && typeof value === 'object' && projections.has(value);\n\nexport const ownProjections = (\n projections: readonly Projection<unknown>[],\n owner: object\n): void => {\n const producers = new Set(projections.map(producerOf));\n for (const producer of producers) {\n if (producer.owner !== undefined && producer.owner !== owner)\n throw new TypeError('Projection producer already belongs to another scope.');\n if (producer.owner === undefined && producer.materialized)\n throw new TypeError('A materialized root projection cannot become scope-owned.');\n if (producer.kind !== 'processor') continue;\n for (const dependency of producer.dependencies) {\n const dependencyOwner = producerOf(dependency).owner;\n if (dependencyOwner !== undefined && dependencyOwner !== owner)\n throw new TypeError('A scope cannot depend on another scope.');\n }\n }\n for (const producer of producers) producer.owner = owner;\n};\n\nconst freezeOutput = (output: OutputDefinition): OutputDefinition =>\n Object.freeze({\n kind: output.kind,\n equality: output.equality,\n ...(output.path ? { path: Object.freeze([...output.path]) } : {}),\n });\n\nexport const defineProcessor = (definition: {\n readonly dependencies: readonly Projection<unknown>[];\n readonly outputs: readonly OutputDefinition[];\n readonly create: () => ProcessorInstance;\n readonly name?: string;\n}): readonly Projection<unknown>[] => {\n if (!Array.isArray(definition.dependencies))\n throw new TypeError('Projection dependencies must be an array.');\n definition.dependencies.forEach(projectionRef);\n if (!definition.outputs.length) throw new TypeError('Projection processor requires an output.');\n const producer: ProcessorDefinition = {\n kind: 'processor',\n dependencies: Object.freeze([...definition.dependencies]),\n outputs: Object.freeze(definition.outputs.map(freezeOutput)),\n create: definition.create,\n ...(definition.name ? { name: definition.name } : {}),\n };\n return Object.freeze(producer.outputs.map((_, output) => defineRef<unknown>(producer, output)));\n};\n\nexport const defineSource = <T>(source: SourceAdapter, output: OutputDefinition): Projection<T> => {\n const producer: SourceDefinition = {\n kind: 'source',\n source,\n output: freezeOutput(output),\n };\n return defineRef<T>(producer, 0);\n};\n","import type { CollectionRead } from '../contract';\n\nexport const mapRead = <K extends string, V>(value: ReadonlyMap<K, V>): CollectionRead<K, V> => ({\n get: key => value.get(key),\n has: key => value.has(key),\n ids: () => Object.freeze([...value.keys()]),\n});\n\n/** Immutable map-like view over a CollectionRead. */\nexport const collectionView = <K extends string, V>(\n read: CollectionRead<K, V>\n): ReadonlyMap<K, V> => {\n const ids = read.ids();\n const entries = function* (): IterableIterator<[K, V]> {\n for (const key of ids) yield [key, read.get(key) as V];\n };\n const values = function* (): IterableIterator<V> {\n for (const key of 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 ids.length;\n },\n keys: () => ids[Symbol.iterator](),\n values,\n entries,\n forEach: (callback, thisArg) => {\n for (const key of ids) callback.call(thisArg, read.get(key) as V, key, view);\n },\n [Symbol.iterator]: entries,\n };\n return Object.freeze(view);\n};\n\n/** Eager durable view used when a processor result may retain its dependency value. */\nexport const snapshotCollectionView = <K extends string, V>(\n read: CollectionRead<K, V>\n): ReadonlyMap<K, V> => {\n const ids = read.ids();\n const values = new Map<K, V>();\n for (const key of ids) values.set(key, read.get(key) as V);\n return collectionView(mapRead(values));\n};\n","import type { CollectionImpact } from '../impact';\nimport type { Unsubscribe } from '../runtime/contract';\n\n/** Scheduler-owned metadata for one Runtime batch. */\nexport type BatchContext = {\n readonly id: number;\n readonly cause?: unknown;\n};\n\n/** The one processor-facing collection transition protocol. */\nexport type CollectionChange<K extends string, V> =\n | { readonly kind: 'reset' }\n | {\n readonly kind: 'incremental';\n readonly added: readonly { readonly key: K; readonly after: V }[];\n readonly updated: readonly {\n readonly key: K;\n readonly before: V;\n readonly after: V;\n }[];\n readonly removed: readonly { readonly key: K; readonly before: V }[];\n readonly order?: {\n readonly before: readonly K[];\n readonly after: readonly K[];\n };\n };\n\nexport type ValueContext<T> = {\n readonly kind: 'value';\n readonly value: T;\n readonly revision: number;\n readonly reset: boolean;\n readonly cause?: unknown;\n};\n\nexport type CollectionRead<K extends string, V> = {\n get(key: K): V | undefined;\n has(key: K): boolean;\n ids(): readonly K[];\n};\n\nexport type ExternalCollectionRead<K extends string, V> = {\n readonly get: (key: K) => V | undefined;\n readonly has: (key: K) => boolean;\n readonly ids: () => readonly K[];\n};\n\nexport type CollectionContext<K extends string, V> = {\n readonly kind: 'collection';\n readonly read: CollectionRead<K, V>;\n readonly change: CollectionChange<K, V> | undefined;\n readonly revision: number;\n readonly reset: boolean;\n readonly cause?: unknown;\n};\n\nexport type SourceContext = ValueContext<unknown> | CollectionContext<string, unknown>;\n\nexport type ExternalValueSource<T> = {\n readonly kind: 'value';\n current(): T;\n revision(): number;\n subscribe(listener: (event: ExternalValueEvent<T>) => void): Unsubscribe;\n};\n\nexport type ExternalCollectionSource<K extends string, V> = {\n readonly kind: 'collection';\n current(): ExternalCollectionRead<K, V>;\n revision(): number;\n subscribe(listener: (event: ExternalCollectionEvent<K, V>) => void): Unsubscribe;\n};\n\nexport type ExternalValueEvent<T> = {\n readonly value: T;\n readonly revision: number;\n readonly reset?: boolean;\n readonly cause?: unknown;\n};\n\nexport type ExternalCollectionEvent<K extends string, V> = {\n /** Stable read from the source before this event or external batch. */\n readonly previous: ExternalCollectionRead<K, V>;\n readonly revision: number;\n /** Optional document-style hint; the adapter resolves the canonical change. */\n readonly impact?: CollectionImpact<K>;\n readonly cause?: unknown;\n};\n\nexport type CollectionDraft<K extends string, V> = {\n set(key: K, value: V): void;\n remove(key: K): void;\n order(ids: readonly K[]): void;\n};\n\nexport class ProjectionError extends Error {\n readonly cause: unknown;\n\n constructor(\n readonly phase: 'processor' | 'listener' | 'source' | 'blocked',\n cause: unknown\n ) {\n super(`Projection ${phase} failed.`, { cause });\n this.name = 'ProjectionError';\n this.cause = cause;\n }\n}\n\nexport class ProjectionDisposedError extends Error {\n constructor() {\n super('Projection has been disposed.');\n this.name = 'ProjectionDisposedError';\n }\n}\n","import { profile } from '../../profile';\nimport type { ObserverError, Unsubscribe } from '../../runtime/contract';\nimport type { BatchContext, SourceContext } from '../contract';\nimport { ProjectionDisposedError, ProjectionError } from '../contract';\n\ntype BatchOptions = { readonly cause?: unknown };\n\ntype ProducerBase = {\n readonly name: string;\n readonly outputs: readonly OutputRecord[];\n fault: ProjectionError | undefined;\n disposed: boolean;\n clear(): void;\n release(): void;\n};\n\nexport type OutputRecord = {\n readonly kind: 'value' | 'collection';\n readonly owner: ProducerRecord;\n context(active: () => boolean): SourceContext;\n current(): unknown;\n revision(): number;\n reset(): boolean;\n subscribe(listener: () => void): Unsubscribe;\n emit(call: (listener: () => void) => void): void;\n hasConsumers(): boolean;\n forEachConsumer(run: (consumer: ProcessorRecord) => void): void;\n attachConsumer(consumer: ProcessorRecord): void;\n detachConsumer(consumer: ProcessorRecord): void;\n clear(): void;\n release(): void;\n};\n\nexport type SourceBoundaryRecord = ProducerBase & {\n readonly kind: 'source';\n readonly outputs: readonly [OutputRecord];\n pendingCause(): unknown;\n recovering(): boolean;\n prepare(cause: unknown): { readonly changed: boolean; readonly force: boolean };\n publish(): void;\n};\n\nexport type ProcessorRecord = ProducerBase & {\n readonly kind: 'processor';\n readonly dependencies: readonly OutputRecord[];\n readonly order: number;\n evaluate(reset: boolean, cause: unknown, recreate?: boolean): readonly OutputRecord[];\n publish(): void;\n};\n\nexport type ProducerRecord = SourceBoundaryRecord | ProcessorRecord;\n\nexport const createScheduler = (onError: (error: ProjectionError) => void) => {\n let disposed = false;\n let depth = 0;\n let batchSequence = 0;\n let activeBatch: BatchContext | undefined;\n let phase: 'idle' | 'compute' | 'notify' = 'idle';\n let sequence = 0;\n const sources = new Set<SourceBoundaryRecord>();\n const processors = new Set<ProcessorRecord>();\n const pendingSources = new Set<SourceBoundaryRecord>();\n const heap: ProcessorRecord[] = [];\n const queued = new Set<ProcessorRecord>();\n const completed = new Set<ProcessorRecord>();\n const emissions = new Set<OutputRecord>();\n const errors: ProjectionError[] = [];\n let reportingFailures: unknown[] = [];\n const guards = new Set<(locked: boolean) => void>();\n\n const assertActive = () => {\n if (disposed) throw new ProjectionDisposedError();\n };\n const assertIdle = () => {\n assertActive();\n if (phase !== 'idle')\n throw new Error('Projection cannot be re-entered during processing or notification.');\n };\n const lock = (value: boolean) => guards.forEach(guard => guard(value));\n\n const enqueue = (processor: ProcessorRecord) => {\n if (processor.disposed || queued.has(processor)) return;\n queued.add(processor);\n profile.projection('scheduledNodes');\n let index = heap.length;\n heap.push(processor);\n while (index > 0) {\n const parent = (index - 1) >> 1;\n if (heap[parent].order < processor.order) break;\n heap[index] = heap[parent];\n index = parent;\n }\n heap[index] = processor;\n };\n\n const pop = (): ProcessorRecord => {\n const first = heap[0];\n const last = heap.pop()!;\n if (heap.length) {\n let index = 0;\n while (index * 2 + 1 < heap.length) {\n let child = index * 2 + 1;\n if (child + 1 < heap.length && heap[child + 1].order < heap[child].order) child++;\n if (last.order < heap[child].order) break;\n heap[index] = heap[child];\n index = child;\n }\n heap[index] = last;\n }\n return first;\n };\n\n const errorFor = (\n producer: ProducerRecord,\n cause: unknown,\n kind: ProjectionError['phase'] = producer.kind === 'source' ? 'source' : 'processor'\n ) => new ProjectionError(kind, cause);\n\n const capture = (source: SourceBoundaryRecord) => {\n if (disposed) return;\n if (phase !== 'idle') {\n source.fault = errorFor(\n source,\n new Error('Source changed while projection was running.'),\n 'source'\n );\n errors.push(source.fault);\n throw source.fault;\n }\n pendingSources.add(source);\n profile.projection('sourceEvents');\n if (source.fault) errors.push(source.fault);\n };\n\n const settleCause = (): unknown => {\n if (activeBatch?.cause !== undefined) return activeBatch.cause;\n for (const source of pendingSources) {\n const cause = source.pendingCause();\n if (cause !== undefined) return cause;\n }\n return undefined;\n };\n\n const settle = () => {\n if (disposed || depth || phase !== 'idle') return;\n phase = 'compute';\n lock(true);\n const cause = settleCause();\n try {\n for (const source of pendingSources) {\n if (source.disposed) continue;\n const wasFaulted = source.fault !== undefined;\n let changed = false;\n let force = false;\n if (!source.fault || source.recovering()) {\n try {\n const prepared = source.prepare(cause);\n changed = prepared.changed;\n force = prepared.force;\n source.fault = undefined;\n } catch (failure) {\n source.fault = errorFor(source, failure, 'source');\n errors.push(source.fault);\n }\n }\n const recovered = wasFaulted && !source.fault;\n if (changed) source.publish();\n if (source.fault || changed || force || recovered) {\n const output = source.outputs[0];\n emissions.add(output);\n output.forEachConsumer(enqueue);\n }\n }\n\n while (heap.length) {\n const processor = pop();\n if (processor.disposed) continue;\n const wasFaulted = processor.fault !== undefined;\n profile.projection('processedNodes');\n let changedOutputs: readonly OutputRecord[] = Object.freeze([]);\n const blocked = processor.dependencies.find(\n output => output.owner.fault || output.owner.disposed\n );\n if (blocked) {\n processor.fault = errorFor(\n processor,\n blocked.owner.fault ?? new ProjectionDisposedError(),\n 'blocked'\n );\n } else {\n const reset = wasFaulted || processor.dependencies.some(output => output.reset());\n try {\n changedOutputs = processor.evaluate(reset, cause, wasFaulted);\n const dependencyFailure = processor.dependencies.find(output => output.owner.fault)\n ?.owner.fault;\n if (dependencyFailure) throw dependencyFailure;\n processor.fault = undefined;\n } catch (failure) {\n const error = errorFor(processor, failure);\n processor.fault = error;\n if (!reset) {\n try {\n changedOutputs = processor.evaluate(true, cause, true);\n const dependencyFailure = processor.dependencies.find(output => output.owner.fault)\n ?.owner.fault;\n if (dependencyFailure) throw dependencyFailure;\n processor.fault = undefined;\n errors.push(error);\n } catch (rebuildFailure) {\n processor.fault = errorFor(processor, rebuildFailure);\n errors.push(processor.fault);\n }\n } else errors.push(error);\n }\n }\n completed.add(processor);\n const recovered = wasFaulted && !processor.fault;\n if (processor.fault) {\n processor.outputs.forEach(output => {\n emissions.add(output);\n output.forEachConsumer(enqueue);\n });\n } else {\n if (changedOutputs.length) {\n processor.publish();\n changedOutputs.forEach(output => emissions.add(output));\n }\n const propagated = recovered ? processor.outputs : changedOutputs;\n propagated.forEach(output => output.forEachConsumer(enqueue));\n }\n if (processor.fault || changedOutputs.length) {\n profile.projection('publishedNodes');\n }\n }\n } finally {\n lock(false);\n phase = 'idle';\n }\n };\n\n const flush = (): readonly ObserverError[] => {\n if (disposed || depth) return [];\n if (pendingSources.size || completed.size) profile.projection('flushes');\n phase = 'notify';\n lock(true);\n const reportFailures: unknown[] = [];\n try {\n emissions.forEach(output =>\n output.emit(listener => {\n try {\n listener();\n } catch (cause) {\n errors.push(errorFor(output.owner, cause, 'listener'));\n }\n })\n );\n for (const error of errors.slice()) {\n try {\n onError(error);\n } catch (cause) {\n reportFailures.push(cause);\n }\n }\n return Object.freeze([\n ...errors.map(error =>\n Object.freeze({\n phase: error.phase === 'listener' ? ('listener' as const) : ('processor' as const),\n error,\n })\n ),\n ...reportFailures.map(error => Object.freeze({ phase: 'listener' as const, error })),\n ]);\n } finally {\n pendingSources.forEach(source => source.clear());\n completed.forEach(processor => processor.clear());\n pendingSources.clear();\n queued.clear();\n completed.clear();\n emissions.clear();\n errors.length = 0;\n reportingFailures = reportFailures;\n lock(false);\n phase = 'idle';\n }\n };\n\n const run = () => {\n settle();\n const result = flush();\n const failures = reportingFailures;\n reportingFailures = [];\n if (failures.length) throw new AggregateError(failures, 'Projection error reporter failed.');\n return result;\n };\n\n const batch = <T>(callback: () => T, options?: BatchOptions): T => {\n assertIdle();\n const outer = depth === 0;\n if (outer)\n activeBatch = Object.freeze({\n id: ++batchSequence,\n ...(options?.cause === undefined ? {} : { cause: options.cause }),\n });\n depth++;\n let failed = false;\n try {\n const value = callback();\n assertSynchronous(value);\n return value;\n } catch (error) {\n failed = true;\n throw error;\n } finally {\n depth--;\n if (!depth) {\n try {\n if (failed) {\n try {\n run();\n } catch {\n /* The original application error retains priority. */\n }\n } else run();\n } finally {\n activeBatch = undefined;\n }\n }\n }\n };\n\n const releaseProducer = (producer: ProducerRecord) => {\n assertIdle();\n if (producer.outputs.some(output => output.hasConsumers()))\n throw new Error('Projection producer is still used by another processor.');\n producer.disposed = true;\n if (producer.kind === 'processor') {\n producer.dependencies.forEach(output => output.detachConsumer(producer));\n processors.delete(producer);\n queued.delete(producer);\n completed.delete(producer);\n } else {\n sources.delete(producer);\n pendingSources.delete(producer);\n }\n const failures: unknown[] = [];\n try {\n producer.release();\n } catch (error) {\n failures.push(error);\n }\n try {\n producer.clear();\n } catch (error) {\n failures.push(error);\n }\n producer.outputs.forEach(output => emissions.delete(output));\n if (failures.length) throw failures[0];\n };\n\n return {\n assertActive,\n assertIdle,\n capture,\n settle,\n flush,\n run,\n registerGuard(guard: (locked: boolean) => void): Unsubscribe {\n assertActive();\n guards.add(guard);\n let registered = true;\n return () => {\n if (!registered) return;\n registered = false;\n guards.delete(guard);\n };\n },\n get active() {\n return !disposed;\n },\n addSource(source: SourceBoundaryRecord) {\n assertIdle();\n sources.add(source);\n },\n addProcessor(processor: ProcessorRecord) {\n assertIdle();\n processors.add(processor);\n processor.dependencies.forEach(output => output.attachConsumer(processor));\n },\n releaseProducer,\n order: () => sequence++,\n initialize<T>(callback: () => T): T {\n assertIdle();\n phase = 'compute';\n lock(true);\n try {\n return callback();\n } finally {\n lock(false);\n phase = 'idle';\n }\n },\n batch,\n batchContext: () => activeBatch,\n dispose() {\n if (disposed) return;\n assertIdle();\n disposed = true;\n const failures: unknown[] = [];\n processors.forEach(processor => {\n processor.disposed = true;\n try {\n processor.release();\n } catch (error) {\n failures.push(error);\n }\n });\n sources.forEach(source => {\n source.disposed = true;\n try {\n source.release();\n } catch (error) {\n failures.push(error);\n }\n });\n processors.clear();\n sources.clear();\n pendingSources.clear();\n heap.length = 0;\n queued.clear();\n completed.clear();\n emissions.clear();\n guards.clear();\n errors.length = 0;\n reportingFailures = [];\n if (failures.length) throw new AggregateError(failures, 'Projection cleanup failed.');\n },\n };\n};\n\nexport type Scheduler = ReturnType<typeof createScheduler>;\n\nexport const assertSynchronous = (value: unknown): void => {\n if (\n value != null &&\n (typeof value === 'object' || typeof value === 'function') &&\n 'then' in value &&\n typeof value.then === 'function'\n )\n throw new TypeError('Projection callbacks must be synchronous.');\n};\n\nexport const assertScope = (active: () => boolean) => {\n if (!active()) throw new Error('Projection reader or writer is no longer active.');\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"scheduler-D4VthaaK.cjs","names":[],"sources":["../core/src/profile.ts","../core/src/projection/definition.ts","../core/src/projection/collection/view.ts","../core/src/projection/contract.ts","../core/src/projection/graph/scheduler.ts"],"sourcesContent":["const counters = () => ({\n projection: {\n sourceEvents: 0,\n scheduledNodes: 0,\n processedNodes: 0,\n touchedKeys: 0,\n changedKeys: 0,\n publishedNodes: 0,\n flushes: 0,\n },\n copy: { structures: 0, treeNodes: 0, shallowRecordItems: 0 },\n equality: { calls: 0, containers: 0 },\n recorder: {\n facts: 0,\n groups: 0,\n transitions: 0,\n absorbed: 0,\n orderSnapshots: 0,\n orderCaptures: 0,\n orderItems: 0,\n publishedOrderItems: 0,\n treeNodes: 0,\n sealed: 0,\n indexedGroups: 0,\n },\n access: { scopes: 0, proxies: 0, snapshots: 0, addresses: 0, resolutions: 0 },\n address: {\n schemaSteps: 0,\n documentSteps: 0,\n prefixComparisons: 0,\n segmentsCompared: 0,\n listIndexes: 0,\n listItems: 0,\n },\n impact: { affectsChecks: 0, indexes: 0 },\n dependency: { comparisons: 0, segmentsCompared: 0 },\n collectionIndex: { nodes: 0, builds: 0, builtItems: 0 },\n collectionView: { mappedItems: 0, idsScanned: 0, arraysCopied: 0 },\n materialized: { updated: 0, rebuilt: 0, notifications: 0 },\n});\ntype Counters = ReturnType<typeof counters>;\ntype DeepReadonly<T> = { readonly [K in keyof T]: T[K] extends object ? DeepReadonly<T[K]> : T[K] };\nexport type ProfileSnapshot = DeepReadonly<Counters>;\nlet active: Counters | undefined;\nconst freeze = <T extends object>(value: T): DeepReadonly<T> => {\n Object.values(value).forEach(child => {\n if (child && typeof child === 'object') freeze(child);\n });\n return Object.freeze(value) as DeepReadonly<T>;\n};\nexport const profile = {\n projection: (key: keyof Counters['projection'], amount = 1) => {\n if (active) active.projection[key] += amount;\n },\n recorder: (key: keyof Counters['recorder'], amount = 1) => {\n if (active) active.recorder[key] += amount;\n },\n access: (key: keyof Counters['access']) => {\n if (active) active.access[key]++;\n },\n copy: {\n structure: () => {\n if (active) active.copy.structures++;\n },\n treeNode: () => {\n if (active) active.copy.treeNodes++;\n },\n shallowRecord: (items: number) => {\n if (active) active.copy.shallowRecordItems += items;\n },\n },\n equality: {\n call: () => {\n if (active) active.equality.calls++;\n },\n container: () => {\n if (active) active.equality.containers++;\n },\n },\n address: {\n listIndex: (items: number) => {\n if (active) {\n active.address.listIndexes++;\n active.address.listItems += items;\n }\n },\n schemaStep: () => {\n if (active) active.address.schemaSteps++;\n },\n documentStep: () => {\n if (active) active.address.documentSteps++;\n },\n prefixComparison: () => {\n if (active) active.address.prefixComparisons++;\n },\n segmentCompared: () => {\n if (active) active.address.segmentsCompared++;\n },\n },\n impact: {\n index: () => {\n if (active) active.impact.indexes++;\n },\n affects: () => {\n if (active) active.impact.affectsChecks++;\n },\n },\n dependency: {\n comparison: () => {\n if (active) active.dependency.comparisons++;\n },\n segmentCompared: () => {\n if (active) active.dependency.segmentsCompared++;\n },\n },\n collectionIndex: {\n node: () => {\n if (active) active.collectionIndex.nodes++;\n },\n build: (items: number) => {\n if (active) {\n active.collectionIndex.builds++;\n active.collectionIndex.builtItems += items;\n }\n },\n },\n collectionView: {\n mapped: () => {\n if (active) active.collectionView.mappedItems++;\n },\n idsScanned: (amount = 1) => {\n if (active) active.collectionView.idsScanned += amount;\n },\n arrayCopied: () => {\n if (active) active.collectionView.arraysCopied++;\n },\n },\n materialized: {\n updated: () => {\n if (active) active.materialized.updated++;\n },\n rebuilt: () => {\n if (active) active.materialized.rebuilt++;\n },\n notification: () => {\n if (active) active.materialized.notifications++;\n },\n },\n};\nexport type ProfileSession = { snapshot(): ProfileSnapshot; stop(): ProfileSnapshot };\nexport const startProfile = (): ProfileSession => {\n if (active) throw new Error('A document profile session is already active.');\n const value = counters();\n active = value;\n const snapshot = () => freeze(structuredClone(value));\n return {\n snapshot,\n stop: () => {\n if (active === value) active = undefined;\n return snapshot();\n },\n };\n};\nexport const measureProfile = <T>(run: () => T): { value: T; profile: ProfileSnapshot } => {\n const session = startProfile();\n try {\n return { value: run(), profile: session.stop() };\n } finally {\n session.stop();\n }\n};\n","import type { ReadonlyDocument } from '../runtime/contract';\nimport type { ObjectSchema } from '../schema/model';\nimport type { CollectionSelector, ValueSelector } from '../schema/path';\nimport type {\n CollectionChange,\n CollectionDraft,\n CollectionRead,\n ExternalCollectionSource,\n ExternalValueSource,\n SourceContext,\n} from './contract';\nimport type { Readable } from '../readable';\n\ndeclare const projectionDefinition: unique symbol;\ndeclare const projectionChanges: unique symbol;\ndeclare const writableInput: unique symbol;\ndeclare const writableCollectionInput: unique symbol;\n\n/** A lazy output reference with no materialized Runtime state. */\nexport type Projection<T> = {\n readonly [projectionDefinition]: T;\n};\n\n/** A writable source projection. */\nexport type Input<T> = Projection<T> & { readonly [writableInput]: true };\n\n/** A writable keyed collection source projection. */\nexport type CollectionInput<K extends string, V> = Projection<ReadonlyMap<K, V>> & {\n readonly [writableCollectionInput]: { readonly key: K; readonly value: V };\n readonly [projectionChanges]: CollectionChange<K, V>;\n};\n\nexport type CollectionInputDraft<K extends string, V> = {\n get(key: K): V | undefined;\n has(key: K): boolean;\n set(key: K, value: V): void;\n remove(key: K): void;\n};\n\nexport type ProjectionWithChange<T, C> = Projection<T> & { readonly [projectionChanges]: C };\nexport type ProjectionChange<P> = P extends { readonly [projectionChanges]: infer C }\n ? C\n : undefined;\n\nexport type Equality = (a: unknown, b: unknown) => boolean;\n\nexport type OutputDefinition =\n | {\n readonly kind: 'value';\n readonly equality: Equality;\n readonly path?: readonly string[];\n }\n | {\n readonly kind: 'collection';\n readonly equality: Equality;\n readonly path?: readonly string[];\n };\n\nexport type ValueOutputEvaluation = {\n readonly kind: 'value';\n readonly previous: unknown;\n readonly next: () => unknown;\n readonly output: { set(value: unknown): void };\n};\n\nexport type CollectionOutputEvaluation = {\n readonly kind: 'collection';\n readonly previous: CollectionRead<string, unknown>;\n readonly next: CollectionRead<string, unknown>;\n readonly output: CollectionDraft<string, unknown>;\n};\n\nexport type OutputEvaluation = ValueOutputEvaluation | CollectionOutputEvaluation;\n\nexport type ProcessorEvaluation = {\n readonly reset: boolean;\n readonly cause: unknown;\n readonly sources: readonly SourceContext[];\n readonly outputs: readonly OutputEvaluation[];\n};\n\nexport type ProcessorInstance = {\n evaluate(input: ProcessorEvaluation): void;\n release?(): void;\n};\n\nexport type SourceAdapter =\n | {\n readonly kind: 'value-input';\n readonly initial: unknown;\n readonly equality: Equality;\n }\n | {\n readonly kind: 'collection-input';\n readonly initial: ReadonlyMap<string, unknown>;\n readonly equality: Equality;\n }\n | {\n readonly kind: 'readable';\n readonly readable: Readable<unknown>;\n readonly equality: Equality;\n }\n | {\n readonly kind: 'external-value';\n readonly source: ExternalValueSource<unknown>;\n readonly equality: Equality;\n }\n | {\n readonly kind: 'external-collection';\n readonly source: ExternalCollectionSource<string, unknown>;\n }\n | {\n readonly kind: 'document';\n readonly document: ReadonlyDocument<ObjectSchema<object>>;\n readonly selector: ValueSelector | CollectionSelector;\n };\n\nexport type SourceDefinition = {\n readonly kind: 'source';\n readonly source: SourceAdapter;\n readonly output: OutputDefinition;\n owner?: object;\n materialized?: true;\n};\n\nexport type ProcessorDefinition = {\n readonly kind: 'processor';\n readonly dependencies: readonly Projection<unknown>[];\n readonly outputs: readonly OutputDefinition[];\n readonly create: () => ProcessorInstance;\n readonly name?: string;\n owner?: object;\n materialized?: true;\n};\n\nexport type ProducerDefinition = SourceDefinition | ProcessorDefinition;\n\nexport type ProjectionRef = {\n readonly producer: ProducerDefinition;\n readonly output: number;\n};\n\nconst projections = new WeakMap<object, ProjectionRef>();\n\nconst defineRef = <T, C = undefined>(\n producer: ProducerDefinition,\n output: number\n): ProjectionWithChange<T, C> => {\n const handle = Object.freeze({}) as ProjectionWithChange<T, C>;\n projections.set(handle, Object.freeze({ producer, output }));\n return handle;\n};\n\nexport const projectionRef = (projection: Projection<unknown>): ProjectionRef => {\n const ref = projections.get(projection);\n if (!ref) throw new TypeError('Unknown projection definition.');\n return ref;\n};\n\nexport const producerOf = (projection: Projection<unknown>): ProducerDefinition =>\n projectionRef(projection).producer;\n\nexport const isProjection = (value: unknown): value is Projection<unknown> =>\n value !== null && typeof value === 'object' && projections.has(value);\n\nexport const ownProjections = (\n projections: readonly Projection<unknown>[],\n owner: object\n): void => {\n const producers = new Set(projections.map(producerOf));\n for (const producer of producers) {\n if (producer.owner !== undefined && producer.owner !== owner)\n throw new TypeError('Projection producer already belongs to another scope.');\n if (producer.owner === undefined && producer.materialized)\n throw new TypeError('A materialized root projection cannot become scope-owned.');\n if (producer.kind !== 'processor') continue;\n for (const dependency of producer.dependencies) {\n const dependencyOwner = producerOf(dependency).owner;\n if (dependencyOwner !== undefined && dependencyOwner !== owner)\n throw new TypeError('A scope cannot depend on another scope.');\n }\n }\n for (const producer of producers) producer.owner = owner;\n};\n\nconst freezeOutput = (output: OutputDefinition): OutputDefinition =>\n Object.freeze({\n kind: output.kind,\n equality: output.equality,\n ...(output.path ? { path: Object.freeze([...output.path]) } : {}),\n });\n\nexport const defineProcessor = (definition: {\n readonly dependencies: readonly Projection<unknown>[];\n readonly outputs: readonly OutputDefinition[];\n readonly create: () => ProcessorInstance;\n readonly name?: string;\n}): readonly Projection<unknown>[] => {\n if (!Array.isArray(definition.dependencies))\n throw new TypeError('Projection dependencies must be an array.');\n definition.dependencies.forEach(projectionRef);\n if (!definition.outputs.length) throw new TypeError('Projection processor requires an output.');\n const producer: ProcessorDefinition = {\n kind: 'processor',\n dependencies: Object.freeze([...definition.dependencies]),\n outputs: Object.freeze(definition.outputs.map(freezeOutput)),\n create: definition.create,\n ...(definition.name ? { name: definition.name } : {}),\n };\n return Object.freeze(\n producer.outputs.map((_, output) => defineRef<unknown, unknown>(producer, output))\n );\n};\n\nexport const defineSource = <T, C = undefined>(\n source: SourceAdapter,\n output: OutputDefinition\n): ProjectionWithChange<T, C> => {\n const producer: SourceDefinition = {\n kind: 'source',\n source,\n output: freezeOutput(output),\n };\n return defineRef<T, C>(producer, 0);\n};\n","import type { CollectionRead } from '../contract';\n\nexport const mapRead = <K extends string, V>(value: ReadonlyMap<K, V>): CollectionRead<K, V> => ({\n get: key => value.get(key),\n has: key => value.has(key),\n ids: () => Object.freeze([...value.keys()]),\n});\n\n/** Immutable map-like view over a CollectionRead. */\nexport const collectionView = <K extends string, V>(\n read: CollectionRead<K, V>\n): ReadonlyMap<K, V> => {\n const ids = read.ids();\n const entries = function* (): IterableIterator<[K, V]> {\n for (const key of ids) yield [key, read.get(key) as V];\n };\n const values = function* (): IterableIterator<V> {\n for (const key of 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 ids.length;\n },\n keys: () => ids[Symbol.iterator](),\n values,\n entries,\n forEach: (callback, thisArg) => {\n for (const key of ids) callback.call(thisArg, read.get(key) as V, key, view);\n },\n [Symbol.iterator]: entries,\n };\n return Object.freeze(view);\n};\n\n/** Eager durable view used when a processor result may retain its dependency value. */\nexport const snapshotCollectionView = <K extends string, V>(\n read: CollectionRead<K, V>\n): ReadonlyMap<K, V> => {\n const ids = read.ids();\n const values = new Map<K, V>();\n for (const key of ids) values.set(key, read.get(key) as V);\n return collectionView(mapRead(values));\n};\n","import type { CollectionImpact } from '../impact';\nimport type { Unsubscribe } from '../runtime/contract';\n\n/** Scheduler-owned metadata for one Runtime batch. */\nexport type BatchContext = {\n readonly id: number;\n readonly cause?: unknown;\n};\n\n/** The one processor-facing collection transition protocol. */\nexport type CollectionChange<K extends string, V> =\n | { readonly kind: 'reset' }\n | {\n readonly kind: 'incremental';\n readonly added: readonly { readonly key: K; readonly after: V }[];\n readonly updated: readonly {\n readonly key: K;\n readonly before: V;\n readonly after: V;\n }[];\n readonly removed: readonly { readonly key: K; readonly before: V }[];\n readonly order?: {\n readonly before: readonly K[];\n readonly after: readonly K[];\n };\n };\n\nexport type ValueContext<T> = {\n readonly kind: 'value';\n readonly value: T;\n readonly revision: number;\n readonly reset: boolean;\n readonly cause?: unknown;\n};\n\nexport type CollectionRead<K extends string, V> = {\n get(key: K): V | undefined;\n has(key: K): boolean;\n ids(): readonly K[];\n};\n\nexport type ExternalCollectionRead<K extends string, V> = {\n readonly get: (key: K) => V | undefined;\n readonly has: (key: K) => boolean;\n readonly ids: () => readonly K[];\n};\n\nexport type CollectionContext<K extends string, V> = {\n readonly kind: 'collection';\n readonly read: CollectionRead<K, V>;\n readonly change: CollectionChange<K, V> | undefined;\n readonly revision: number;\n readonly reset: boolean;\n readonly cause?: unknown;\n};\n\nexport type SourceContext = ValueContext<unknown> | CollectionContext<string, unknown>;\n\nexport type ExternalValueSource<T> = {\n readonly kind: 'value';\n current(): T;\n revision(): number;\n subscribe(listener: (event: ExternalValueEvent<T>) => void): Unsubscribe;\n};\n\nexport type ExternalCollectionSource<K extends string, V> = {\n readonly kind: 'collection';\n current(): ExternalCollectionRead<K, V>;\n revision(): number;\n subscribe(listener: (event: ExternalCollectionEvent<K, V>) => void): Unsubscribe;\n};\n\nexport type ExternalValueEvent<T> = {\n readonly value: T;\n readonly revision: number;\n readonly reset?: boolean;\n readonly cause?: unknown;\n};\n\nexport type ExternalCollectionEvent<K extends string, V> = {\n /** Stable read from the source before this event or external batch. */\n readonly previous: ExternalCollectionRead<K, V>;\n readonly revision: number;\n /** Optional document-style hint; the adapter resolves the canonical change. */\n readonly impact?: CollectionImpact<K>;\n readonly cause?: unknown;\n};\n\nexport type CollectionDraft<K extends string, V> = {\n set(key: K, value: V): void;\n remove(key: K): void;\n order(ids: readonly K[]): void;\n};\n\nexport class ProjectionError extends Error {\n readonly cause: unknown;\n\n constructor(\n readonly phase: 'processor' | 'listener' | 'source' | 'blocked',\n cause: unknown\n ) {\n super(`Projection ${phase} failed.`, { cause });\n this.name = 'ProjectionError';\n this.cause = cause;\n }\n}\n\nexport class ProjectionDisposedError extends Error {\n constructor() {\n super('Projection has been disposed.');\n this.name = 'ProjectionDisposedError';\n }\n}\n","import { profile } from '../../profile';\nimport type { ObserverError, Unsubscribe } from '../../runtime/contract';\nimport type { BatchContext, SourceContext } from '../contract';\nimport { ProjectionDisposedError, ProjectionError } from '../contract';\n\ntype BatchOptions = { readonly cause?: unknown };\n\ntype ProducerBase = {\n readonly name: string;\n readonly outputs: readonly OutputRecord[];\n fault: ProjectionError | undefined;\n disposed: boolean;\n clear(): void;\n release(): void;\n};\n\nexport type OutputRecord = {\n readonly kind: 'value' | 'collection';\n readonly owner: ProducerRecord;\n context(active: () => boolean): SourceContext;\n current(): unknown;\n revision(): number;\n reset(): boolean;\n subscribe(listener: () => void): Unsubscribe;\n emit(call: (listener: () => void) => void): void;\n hasConsumers(): boolean;\n forEachConsumer(run: (consumer: ProcessorRecord) => void): void;\n attachConsumer(consumer: ProcessorRecord): void;\n detachConsumer(consumer: ProcessorRecord): void;\n clear(): void;\n release(): void;\n};\n\nexport type SourceBoundaryRecord = ProducerBase & {\n readonly kind: 'source';\n readonly outputs: readonly [OutputRecord];\n pendingCause(): unknown;\n recovering(): boolean;\n prepare(cause: unknown): { readonly changed: boolean; readonly force: boolean };\n publish(): void;\n};\n\nexport type ProcessorRecord = ProducerBase & {\n readonly kind: 'processor';\n readonly dependencies: readonly OutputRecord[];\n readonly order: number;\n evaluate(reset: boolean, cause: unknown, recreate?: boolean): readonly OutputRecord[];\n publish(): void;\n};\n\nexport type ProducerRecord = SourceBoundaryRecord | ProcessorRecord;\n\nexport const createScheduler = (onError: (error: ProjectionError) => void) => {\n let disposed = false;\n let depth = 0;\n let batchSequence = 0;\n let activeBatch: BatchContext | undefined;\n let phase: 'idle' | 'compute' | 'notify' = 'idle';\n let sequence = 0;\n const sources = new Set<SourceBoundaryRecord>();\n const processors = new Set<ProcessorRecord>();\n const pendingSources = new Set<SourceBoundaryRecord>();\n const heap: ProcessorRecord[] = [];\n const queued = new Set<ProcessorRecord>();\n const completed = new Set<ProcessorRecord>();\n const emissions = new Set<OutputRecord>();\n const errors: ProjectionError[] = [];\n let reportingFailures: unknown[] = [];\n const guards = new Set<(locked: boolean) => void>();\n\n const assertActive = () => {\n if (disposed) throw new ProjectionDisposedError();\n };\n const assertIdle = () => {\n assertActive();\n if (phase !== 'idle')\n throw new Error('Projection cannot be re-entered during processing or notification.');\n };\n const lock = (value: boolean) => guards.forEach(guard => guard(value));\n\n const enqueue = (processor: ProcessorRecord) => {\n if (processor.disposed || queued.has(processor)) return;\n queued.add(processor);\n profile.projection('scheduledNodes');\n let index = heap.length;\n heap.push(processor);\n while (index > 0) {\n const parent = (index - 1) >> 1;\n if (heap[parent].order < processor.order) break;\n heap[index] = heap[parent];\n index = parent;\n }\n heap[index] = processor;\n };\n\n const pop = (): ProcessorRecord => {\n const first = heap[0];\n const last = heap.pop()!;\n if (heap.length) {\n let index = 0;\n while (index * 2 + 1 < heap.length) {\n let child = index * 2 + 1;\n if (child + 1 < heap.length && heap[child + 1].order < heap[child].order) child++;\n if (last.order < heap[child].order) break;\n heap[index] = heap[child];\n index = child;\n }\n heap[index] = last;\n }\n return first;\n };\n\n const errorFor = (\n producer: ProducerRecord,\n cause: unknown,\n kind: ProjectionError['phase'] = producer.kind === 'source' ? 'source' : 'processor'\n ) => new ProjectionError(kind, cause);\n\n const capture = (source: SourceBoundaryRecord) => {\n if (disposed) return;\n if (phase !== 'idle') {\n source.fault = errorFor(\n source,\n new Error('Source changed while projection was running.'),\n 'source'\n );\n errors.push(source.fault);\n throw source.fault;\n }\n pendingSources.add(source);\n profile.projection('sourceEvents');\n if (source.fault) errors.push(source.fault);\n };\n\n const settleCause = (): unknown => {\n if (activeBatch?.cause !== undefined) return activeBatch.cause;\n for (const source of pendingSources) {\n const cause = source.pendingCause();\n if (cause !== undefined) return cause;\n }\n return undefined;\n };\n\n const settle = () => {\n if (disposed || depth || phase !== 'idle') return;\n phase = 'compute';\n lock(true);\n const cause = settleCause();\n try {\n for (const source of pendingSources) {\n if (source.disposed) continue;\n const wasFaulted = source.fault !== undefined;\n let changed = false;\n let force = false;\n if (!source.fault || source.recovering()) {\n try {\n const prepared = source.prepare(cause);\n changed = prepared.changed;\n force = prepared.force;\n source.fault = undefined;\n } catch (failure) {\n source.fault = errorFor(source, failure, 'source');\n errors.push(source.fault);\n }\n }\n const recovered = wasFaulted && !source.fault;\n if (changed) source.publish();\n if (source.fault || changed || force || recovered) {\n const output = source.outputs[0];\n emissions.add(output);\n output.forEachConsumer(enqueue);\n }\n }\n\n while (heap.length) {\n const processor = pop();\n if (processor.disposed) continue;\n const wasFaulted = processor.fault !== undefined;\n profile.projection('processedNodes');\n let changedOutputs: readonly OutputRecord[] = Object.freeze([]);\n const blocked = processor.dependencies.find(\n output => output.owner.fault || output.owner.disposed\n );\n if (blocked) {\n processor.fault = errorFor(\n processor,\n blocked.owner.fault ?? new ProjectionDisposedError(),\n 'blocked'\n );\n } else {\n const reset = wasFaulted || processor.dependencies.some(output => output.reset());\n try {\n changedOutputs = processor.evaluate(reset, cause, wasFaulted);\n const dependencyFailure = processor.dependencies.find(output => output.owner.fault)\n ?.owner.fault;\n if (dependencyFailure) throw dependencyFailure;\n processor.fault = undefined;\n } catch (failure) {\n const error = errorFor(processor, failure);\n processor.fault = error;\n if (!reset) {\n try {\n changedOutputs = processor.evaluate(true, cause, true);\n const dependencyFailure = processor.dependencies.find(output => output.owner.fault)\n ?.owner.fault;\n if (dependencyFailure) throw dependencyFailure;\n processor.fault = undefined;\n errors.push(error);\n } catch (rebuildFailure) {\n processor.fault = errorFor(processor, rebuildFailure);\n errors.push(processor.fault);\n }\n } else errors.push(error);\n }\n }\n completed.add(processor);\n const recovered = wasFaulted && !processor.fault;\n if (processor.fault) {\n processor.outputs.forEach(output => {\n emissions.add(output);\n output.forEachConsumer(enqueue);\n });\n } else {\n if (changedOutputs.length) {\n processor.publish();\n changedOutputs.forEach(output => emissions.add(output));\n }\n const propagated = recovered ? processor.outputs : changedOutputs;\n propagated.forEach(output => output.forEachConsumer(enqueue));\n }\n if (processor.fault || changedOutputs.length) {\n profile.projection('publishedNodes');\n }\n }\n } finally {\n lock(false);\n phase = 'idle';\n }\n };\n\n const flush = (): readonly ObserverError[] => {\n if (disposed || depth) return [];\n if (pendingSources.size || completed.size) profile.projection('flushes');\n phase = 'notify';\n lock(true);\n const reportFailures: unknown[] = [];\n try {\n emissions.forEach(output =>\n output.emit(listener => {\n try {\n listener();\n } catch (cause) {\n errors.push(errorFor(output.owner, cause, 'listener'));\n }\n })\n );\n for (const error of errors.slice()) {\n try {\n onError(error);\n } catch (cause) {\n reportFailures.push(cause);\n }\n }\n return Object.freeze([\n ...errors.map(error =>\n Object.freeze({\n phase: error.phase === 'listener' ? ('listener' as const) : ('processor' as const),\n error,\n })\n ),\n ...reportFailures.map(error => Object.freeze({ phase: 'listener' as const, error })),\n ]);\n } finally {\n pendingSources.forEach(source => source.clear());\n completed.forEach(processor => processor.clear());\n pendingSources.clear();\n queued.clear();\n completed.clear();\n emissions.clear();\n errors.length = 0;\n reportingFailures = reportFailures;\n lock(false);\n phase = 'idle';\n }\n };\n\n const run = () => {\n settle();\n const result = flush();\n const failures = reportingFailures;\n reportingFailures = [];\n if (failures.length) throw new AggregateError(failures, 'Projection error reporter failed.');\n return result;\n };\n\n const batch = <T>(callback: () => T, options?: BatchOptions): T => {\n assertIdle();\n const outer = depth === 0;\n if (outer)\n activeBatch = Object.freeze({\n id: ++batchSequence,\n ...(options?.cause === undefined ? {} : { cause: options.cause }),\n });\n depth++;\n let failed = false;\n try {\n const value = callback();\n assertSynchronous(value);\n return value;\n } catch (error) {\n failed = true;\n throw error;\n } finally {\n depth--;\n if (!depth) {\n try {\n if (failed) {\n try {\n run();\n } catch {\n /* The original application error retains priority. */\n }\n } else run();\n } finally {\n activeBatch = undefined;\n }\n }\n }\n };\n\n const releaseProducer = (producer: ProducerRecord) => {\n assertIdle();\n if (producer.outputs.some(output => output.hasConsumers()))\n throw new Error('Projection producer is still used by another processor.');\n producer.disposed = true;\n if (producer.kind === 'processor') {\n producer.dependencies.forEach(output => output.detachConsumer(producer));\n processors.delete(producer);\n queued.delete(producer);\n completed.delete(producer);\n } else {\n sources.delete(producer);\n pendingSources.delete(producer);\n }\n const failures: unknown[] = [];\n try {\n producer.release();\n } catch (error) {\n failures.push(error);\n }\n try {\n producer.clear();\n } catch (error) {\n failures.push(error);\n }\n producer.outputs.forEach(output => emissions.delete(output));\n if (failures.length) throw failures[0];\n };\n\n return {\n assertActive,\n assertIdle,\n capture,\n settle,\n flush,\n run,\n registerGuard(guard: (locked: boolean) => void): Unsubscribe {\n assertActive();\n guards.add(guard);\n let registered = true;\n return () => {\n if (!registered) return;\n registered = false;\n guards.delete(guard);\n };\n },\n get active() {\n return !disposed;\n },\n addSource(source: SourceBoundaryRecord) {\n assertIdle();\n sources.add(source);\n },\n addProcessor(processor: ProcessorRecord) {\n assertIdle();\n processors.add(processor);\n processor.dependencies.forEach(output => output.attachConsumer(processor));\n },\n releaseProducer,\n order: () => sequence++,\n initialize<T>(callback: () => T): T {\n assertIdle();\n phase = 'compute';\n lock(true);\n try {\n return callback();\n } finally {\n lock(false);\n phase = 'idle';\n }\n },\n batch,\n batchContext: () => activeBatch,\n dispose() {\n if (disposed) return;\n assertIdle();\n disposed = true;\n const failures: unknown[] = [];\n processors.forEach(processor => {\n processor.disposed = true;\n try {\n processor.release();\n } catch (error) {\n failures.push(error);\n }\n });\n sources.forEach(source => {\n source.disposed = true;\n try {\n source.release();\n } catch (error) {\n failures.push(error);\n }\n });\n processors.clear();\n sources.clear();\n pendingSources.clear();\n heap.length = 0;\n queued.clear();\n completed.clear();\n emissions.clear();\n guards.clear();\n errors.length = 0;\n reportingFailures = [];\n if (failures.length) throw new AggregateError(failures, 'Projection cleanup failed.');\n },\n };\n};\n\nexport type Scheduler = ReturnType<typeof createScheduler>;\n\nexport const assertSynchronous = (value: unknown): void => {\n if (\n value != null &&\n (typeof value === 'object' || typeof value === 'function') &&\n 'then' in value &&\n typeof value.then === 'function'\n )\n throw new TypeError('Projection callbacks must be synchronous.');\n};\n\nexport const assertScope = (active: () => boolean) => {\n if (!active()) throw new Error('Projection reader or writer is no longer active.');\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"scheduler-D4VthaaK.cjs","names":[],"sources":["../core/src/profile.ts","../core/src/projection/definition.ts","../core/src/projection/collection/view.ts","../core/src/projection/contract.ts","../core/src/projection/graph/scheduler.ts"],"sourcesContent":["const counters = () => ({\n projection: {\n sourceEvents: 0,\n scheduledNodes: 0,\n processedNodes: 0,\n touchedKeys: 0,\n changedKeys: 0,\n publishedNodes: 0,\n flushes: 0,\n },\n copy: { structures: 0, treeNodes: 0, shallowRecordItems: 0 },\n equality: { calls: 0, containers: 0 },\n recorder: {\n facts: 0,\n groups: 0,\n transitions: 0,\n absorbed: 0,\n orderSnapshots: 0,\n orderCaptures: 0,\n orderItems: 0,\n publishedOrderItems: 0,\n treeNodes: 0,\n sealed: 0,\n indexedGroups: 0,\n },\n access: { scopes: 0, proxies: 0, snapshots: 0, addresses: 0, resolutions: 0 },\n address: {\n schemaSteps: 0,\n documentSteps: 0,\n prefixComparisons: 0,\n segmentsCompared: 0,\n listIndexes: 0,\n listItems: 0,\n },\n impact: { affectsChecks: 0, indexes: 0 },\n dependency: { comparisons: 0, segmentsCompared: 0 },\n collectionIndex: { nodes: 0, builds: 0, builtItems: 0 },\n collectionView: { mappedItems: 0, idsScanned: 0, arraysCopied: 0 },\n materialized: { updated: 0, rebuilt: 0, notifications: 0 },\n});\ntype Counters = ReturnType<typeof counters>;\ntype DeepReadonly<T> = { readonly [K in keyof T]: T[K] extends object ? DeepReadonly<T[K]> : T[K] };\nexport type ProfileSnapshot = DeepReadonly<Counters>;\nlet active: Counters | undefined;\nconst freeze = <T extends object>(value: T): DeepReadonly<T> => {\n Object.values(value).forEach(child => {\n if (child && typeof child === 'object') freeze(child);\n });\n return Object.freeze(value) as DeepReadonly<T>;\n};\nexport const profile = {\n projection: (key: keyof Counters['projection'], amount = 1) => {\n if (active) active.projection[key] += amount;\n },\n recorder: (key: keyof Counters['recorder'], amount = 1) => {\n if (active) active.recorder[key] += amount;\n },\n access: (key: keyof Counters['access']) => {\n if (active) active.access[key]++;\n },\n copy: {\n structure: () => {\n if (active) active.copy.structures++;\n },\n treeNode: () => {\n if (active) active.copy.treeNodes++;\n },\n shallowRecord: (items: number) => {\n if (active) active.copy.shallowRecordItems += items;\n },\n },\n equality: {\n call: () => {\n if (active) active.equality.calls++;\n },\n container: () => {\n if (active) active.equality.containers++;\n },\n },\n address: {\n listIndex: (items: number) => {\n if (active) {\n active.address.listIndexes++;\n active.address.listItems += items;\n }\n },\n schemaStep: () => {\n if (active) active.address.schemaSteps++;\n },\n documentStep: () => {\n if (active) active.address.documentSteps++;\n },\n prefixComparison: () => {\n if (active) active.address.prefixComparisons++;\n },\n segmentCompared: () => {\n if (active) active.address.segmentsCompared++;\n },\n },\n impact: {\n index: () => {\n if (active) active.impact.indexes++;\n },\n affects: () => {\n if (active) active.impact.affectsChecks++;\n },\n },\n dependency: {\n comparison: () => {\n if (active) active.dependency.comparisons++;\n },\n segmentCompared: () => {\n if (active) active.dependency.segmentsCompared++;\n },\n },\n collectionIndex: {\n node: () => {\n if (active) active.collectionIndex.nodes++;\n },\n build: (items: number) => {\n if (active) {\n active.collectionIndex.builds++;\n active.collectionIndex.builtItems += items;\n }\n },\n },\n collectionView: {\n mapped: () => {\n if (active) active.collectionView.mappedItems++;\n },\n idsScanned: (amount = 1) => {\n if (active) active.collectionView.idsScanned += amount;\n },\n arrayCopied: () => {\n if (active) active.collectionView.arraysCopied++;\n },\n },\n materialized: {\n updated: () => {\n if (active) active.materialized.updated++;\n },\n rebuilt: () => {\n if (active) active.materialized.rebuilt++;\n },\n notification: () => {\n if (active) active.materialized.notifications++;\n },\n },\n};\nexport type ProfileSession = { snapshot(): ProfileSnapshot; stop(): ProfileSnapshot };\nexport const startProfile = (): ProfileSession => {\n if (active) throw new Error('A document profile session is already active.');\n const value = counters();\n active = value;\n const snapshot = () => freeze(structuredClone(value));\n return {\n snapshot,\n stop: () => {\n if (active === value) active = undefined;\n return snapshot();\n },\n };\n};\nexport const measureProfile = <T>(run: () => T): { value: T; profile: ProfileSnapshot } => {\n const session = startProfile();\n try {\n return { value: run(), profile: session.stop() };\n } finally {\n session.stop();\n }\n};\n","import type { ReadonlyDocument } from '../runtime/contract';\nimport type { ObjectSchema } from '../schema/model';\nimport type { CollectionSelector, ValueSelector } from '../schema/path';\nimport type {\n CollectionChange,\n CollectionDraft,\n CollectionRead,\n ExternalCollectionSource,\n ExternalValueSource,\n SourceContext,\n} from './contract';\nimport type { Readable } from '../readable';\n\ndeclare const projectionDefinition: unique symbol;\ndeclare const keyedProjection: unique symbol;\ndeclare const writableInput: unique symbol;\ndeclare const writableCollectionInput: unique symbol;\n\n/** A lazy output reference with no materialized Runtime state. */\nexport type Projection<T> = {\n readonly [projectionDefinition]: T;\n};\n\n/** A projection whose output is a keyed collection with per-key change semantics. */\nexport type KeyedProjection<K extends string, V> = Projection<ReadonlyMap<K, V>> & {\n readonly [keyedProjection]: { readonly key: K; readonly value: V };\n};\n\n/** A writable source projection. */\nexport type Input<T> = Projection<T> & { readonly [writableInput]: true };\n\n/** A writable keyed collection source projection. */\nexport type CollectionInput<K extends string, V> = KeyedProjection<K, V> & {\n readonly [writableCollectionInput]: { readonly key: K; readonly value: V };\n};\n\nexport type CollectionInputDraft<K extends string, V> = {\n get(key: K): V | undefined;\n has(key: K): boolean;\n set(key: K, value: V): void;\n remove(key: K): void;\n};\n\nexport type ProjectionChange<P> =\n P extends KeyedProjection<infer K, infer V> ? CollectionChange<K, V> : undefined;\n\nexport type Equality = (a: unknown, b: unknown) => boolean;\n\nexport type OutputDefinition =\n | {\n readonly kind: 'value';\n readonly equality: Equality;\n readonly path?: readonly string[];\n }\n | {\n readonly kind: 'collection';\n readonly equality: Equality;\n readonly path?: readonly string[];\n };\n\nexport type ValueOutputEvaluation = {\n readonly kind: 'value';\n readonly previous: unknown;\n readonly next: () => unknown;\n readonly output: { set(value: unknown): void };\n};\n\nexport type CollectionOutputEvaluation = {\n readonly kind: 'collection';\n readonly previous: CollectionRead<string, unknown>;\n readonly next: CollectionRead<string, unknown>;\n readonly output: CollectionDraft<string, unknown>;\n};\n\nexport type OutputEvaluation = ValueOutputEvaluation | CollectionOutputEvaluation;\n\nexport type ProcessorEvaluation = {\n readonly reset: boolean;\n readonly cause: unknown;\n readonly sources: readonly SourceContext[];\n readonly outputs: readonly OutputEvaluation[];\n};\n\nexport type ProcessorInstance = {\n evaluate(input: ProcessorEvaluation): void;\n release?(): void;\n};\n\nexport type SourceAdapter =\n | {\n readonly kind: 'value-input';\n readonly initial: unknown;\n readonly equality: Equality;\n }\n | {\n readonly kind: 'collection-input';\n readonly initial: ReadonlyMap<string, unknown>;\n readonly equality: Equality;\n }\n | {\n readonly kind: 'readable';\n readonly readable: Readable<unknown>;\n readonly equality: Equality;\n }\n | {\n readonly kind: 'external-value';\n readonly source: ExternalValueSource<unknown>;\n readonly equality: Equality;\n }\n | {\n readonly kind: 'external-collection';\n readonly source: ExternalCollectionSource<string, unknown>;\n }\n | {\n readonly kind: 'document';\n readonly document: ReadonlyDocument<ObjectSchema<object>>;\n readonly selector: ValueSelector | CollectionSelector;\n };\n\nexport type SourceDefinition = {\n readonly kind: 'source';\n readonly source: SourceAdapter;\n readonly output: OutputDefinition;\n owner?: object;\n materialized?: true;\n};\n\nexport type ProcessorDefinition = {\n readonly kind: 'processor';\n readonly dependencies: readonly Projection<unknown>[];\n readonly outputs: readonly OutputDefinition[];\n readonly create: () => ProcessorInstance;\n readonly name?: string;\n owner?: object;\n materialized?: true;\n};\n\nexport type ProducerDefinition = SourceDefinition | ProcessorDefinition;\n\nexport type ProjectionRef = {\n readonly producer: ProducerDefinition;\n readonly output: number;\n};\n\nconst projections = new WeakMap<object, ProjectionRef>();\n\nconst defineRef = <T>(producer: ProducerDefinition, output: number): Projection<T> => {\n const handle = Object.freeze({}) as Projection<T>;\n projections.set(handle, Object.freeze({ producer, output }));\n return handle;\n};\n\nexport const projectionRef = (projection: Projection<unknown>): ProjectionRef => {\n const ref = projections.get(projection);\n if (!ref) throw new TypeError('Unknown projection definition.');\n return ref;\n};\n\nexport const producerOf = (projection: Projection<unknown>): ProducerDefinition =>\n projectionRef(projection).producer;\n\nexport const isProjection = (value: unknown): value is Projection<unknown> =>\n value !== null && typeof value === 'object' && projections.has(value);\n\nexport const ownProjections = (\n projections: readonly Projection<unknown>[],\n owner: object\n): void => {\n const producers = new Set(projections.map(producerOf));\n for (const producer of producers) {\n if (producer.owner !== undefined && producer.owner !== owner)\n throw new TypeError('Projection producer already belongs to another scope.');\n if (producer.owner === undefined && producer.materialized)\n throw new TypeError('A materialized root projection cannot become scope-owned.');\n if (producer.kind !== 'processor') continue;\n for (const dependency of producer.dependencies) {\n const dependencyOwner = producerOf(dependency).owner;\n if (dependencyOwner !== undefined && dependencyOwner !== owner)\n throw new TypeError('A scope cannot depend on another scope.');\n }\n }\n for (const producer of producers) producer.owner = owner;\n};\n\nconst freezeOutput = (output: OutputDefinition): OutputDefinition =>\n Object.freeze({\n kind: output.kind,\n equality: output.equality,\n ...(output.path ? { path: Object.freeze([...output.path]) } : {}),\n });\n\nexport const defineProcessor = (definition: {\n readonly dependencies: readonly Projection<unknown>[];\n readonly outputs: readonly OutputDefinition[];\n readonly create: () => ProcessorInstance;\n readonly name?: string;\n}): readonly Projection<unknown>[] => {\n if (!Array.isArray(definition.dependencies))\n throw new TypeError('Projection dependencies must be an array.');\n definition.dependencies.forEach(projectionRef);\n if (!definition.outputs.length) throw new TypeError('Projection processor requires an output.');\n const producer: ProcessorDefinition = {\n kind: 'processor',\n dependencies: Object.freeze([...definition.dependencies]),\n outputs: Object.freeze(definition.outputs.map(freezeOutput)),\n create: definition.create,\n ...(definition.name ? { name: definition.name } : {}),\n };\n return Object.freeze(producer.outputs.map((_, output) => defineRef<unknown>(producer, output)));\n};\n\nexport const defineSource = <T>(source: SourceAdapter, output: OutputDefinition): Projection<T> => {\n const producer: SourceDefinition = {\n kind: 'source',\n source,\n output: freezeOutput(output),\n };\n return defineRef<T>(producer, 0);\n};\n","import type { CollectionRead } from '../contract';\n\nexport const mapRead = <K extends string, V>(value: ReadonlyMap<K, V>): CollectionRead<K, V> => ({\n get: key => value.get(key),\n has: key => value.has(key),\n ids: () => Object.freeze([...value.keys()]),\n});\n\n/** Immutable map-like view over a CollectionRead. */\nexport const collectionView = <K extends string, V>(\n read: CollectionRead<K, V>\n): ReadonlyMap<K, V> => {\n const ids = read.ids();\n const entries = function* (): IterableIterator<[K, V]> {\n for (const key of ids) yield [key, read.get(key) as V];\n };\n const values = function* (): IterableIterator<V> {\n for (const key of 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 ids.length;\n },\n keys: () => ids[Symbol.iterator](),\n values,\n entries,\n forEach: (callback, thisArg) => {\n for (const key of ids) callback.call(thisArg, read.get(key) as V, key, view);\n },\n [Symbol.iterator]: entries,\n };\n return Object.freeze(view);\n};\n\n/** Eager durable view used when a processor result may retain its dependency value. */\nexport const snapshotCollectionView = <K extends string, V>(\n read: CollectionRead<K, V>\n): ReadonlyMap<K, V> => {\n const ids = read.ids();\n const values = new Map<K, V>();\n for (const key of ids) values.set(key, read.get(key) as V);\n return collectionView(mapRead(values));\n};\n","import type { CollectionImpact } from '../impact';\nimport type { Unsubscribe } from '../runtime/contract';\n\n/** Scheduler-owned metadata for one Runtime batch. */\nexport type BatchContext = {\n readonly id: number;\n readonly cause?: unknown;\n};\n\n/** The one processor-facing collection transition protocol. */\nexport type CollectionChange<K extends string, V> =\n | { readonly kind: 'reset' }\n | {\n readonly kind: 'incremental';\n readonly added: readonly { readonly key: K; readonly after: V }[];\n readonly updated: readonly {\n readonly key: K;\n readonly before: V;\n readonly after: V;\n }[];\n readonly removed: readonly { readonly key: K; readonly before: V }[];\n readonly order?: {\n readonly before: readonly K[];\n readonly after: readonly K[];\n };\n };\n\nexport type ValueContext<T> = {\n readonly kind: 'value';\n readonly value: T;\n readonly revision: number;\n readonly reset: boolean;\n readonly cause?: unknown;\n};\n\nexport type CollectionRead<K extends string, V> = {\n get(key: K): V | undefined;\n has(key: K): boolean;\n ids(): readonly K[];\n};\n\nexport type ExternalCollectionRead<K extends string, V> = {\n readonly get: (key: K) => V | undefined;\n readonly has: (key: K) => boolean;\n readonly ids: () => readonly K[];\n};\n\nexport type CollectionContext<K extends string, V> = {\n readonly kind: 'collection';\n readonly read: CollectionRead<K, V>;\n readonly change: CollectionChange<K, V> | undefined;\n readonly revision: number;\n readonly reset: boolean;\n readonly cause?: unknown;\n};\n\nexport type SourceContext = ValueContext<unknown> | CollectionContext<string, unknown>;\n\nexport type ExternalValueSource<T> = {\n readonly kind: 'value';\n current(): T;\n revision(): number;\n subscribe(listener: (event: ExternalValueEvent<T>) => void): Unsubscribe;\n};\n\nexport type ExternalCollectionSource<K extends string, V> = {\n readonly kind: 'collection';\n current(): ExternalCollectionRead<K, V>;\n revision(): number;\n subscribe(listener: (event: ExternalCollectionEvent<K, V>) => void): Unsubscribe;\n};\n\nexport type ExternalValueEvent<T> = {\n readonly value: T;\n readonly revision: number;\n readonly reset?: boolean;\n readonly cause?: unknown;\n};\n\nexport type ExternalCollectionEvent<K extends string, V> = {\n /** Stable read from the source before this event or external batch. */\n readonly previous: ExternalCollectionRead<K, V>;\n readonly revision: number;\n /** Optional document-style hint; the adapter resolves the canonical change. */\n readonly impact?: CollectionImpact<K>;\n readonly cause?: unknown;\n};\n\nexport type CollectionDraft<K extends string, V> = {\n set(key: K, value: V): void;\n remove(key: K): void;\n order(ids: readonly K[]): void;\n};\n\nexport class ProjectionError extends Error {\n readonly cause: unknown;\n\n constructor(\n readonly phase: 'processor' | 'listener' | 'source' | 'blocked',\n cause: unknown\n ) {\n super(`Projection ${phase} failed.`, { cause });\n this.name = 'ProjectionError';\n this.cause = cause;\n }\n}\n\nexport class ProjectionDisposedError extends Error {\n constructor() {\n super('Projection has been disposed.');\n this.name = 'ProjectionDisposedError';\n }\n}\n","import { profile } from '../../profile';\nimport type { ObserverError, Unsubscribe } from '../../runtime/contract';\nimport type { BatchContext, SourceContext } from '../contract';\nimport { ProjectionDisposedError, ProjectionError } from '../contract';\n\ntype BatchOptions = { readonly cause?: unknown };\n\ntype ProducerBase = {\n readonly name: string;\n readonly outputs: readonly OutputRecord[];\n fault: ProjectionError | undefined;\n disposed: boolean;\n clear(): void;\n release(): void;\n};\n\nexport type OutputRecord = {\n readonly kind: 'value' | 'collection';\n readonly owner: ProducerRecord;\n context(active: () => boolean): SourceContext;\n current(): unknown;\n revision(): number;\n reset(): boolean;\n subscribe(listener: () => void): Unsubscribe;\n emit(call: (listener: () => void) => void): void;\n hasConsumers(): boolean;\n forEachConsumer(run: (consumer: ProcessorRecord) => void): void;\n attachConsumer(consumer: ProcessorRecord): void;\n detachConsumer(consumer: ProcessorRecord): void;\n clear(): void;\n release(): void;\n};\n\nexport type SourceBoundaryRecord = ProducerBase & {\n readonly kind: 'source';\n readonly outputs: readonly [OutputRecord];\n pendingCause(): unknown;\n recovering(): boolean;\n prepare(cause: unknown): { readonly changed: boolean; readonly force: boolean };\n publish(): void;\n};\n\nexport type ProcessorRecord = ProducerBase & {\n readonly kind: 'processor';\n readonly dependencies: readonly OutputRecord[];\n readonly order: number;\n evaluate(reset: boolean, cause: unknown, recreate?: boolean): readonly OutputRecord[];\n publish(): void;\n};\n\nexport type ProducerRecord = SourceBoundaryRecord | ProcessorRecord;\n\nexport const createScheduler = (onError: (error: ProjectionError) => void) => {\n let disposed = false;\n let depth = 0;\n let batchSequence = 0;\n let activeBatch: BatchContext | undefined;\n let phase: 'idle' | 'compute' | 'notify' = 'idle';\n let sequence = 0;\n const sources = new Set<SourceBoundaryRecord>();\n const processors = new Set<ProcessorRecord>();\n const pendingSources = new Set<SourceBoundaryRecord>();\n const heap: ProcessorRecord[] = [];\n const queued = new Set<ProcessorRecord>();\n const completed = new Set<ProcessorRecord>();\n const emissions = new Set<OutputRecord>();\n const errors: ProjectionError[] = [];\n let reportingFailures: unknown[] = [];\n const guards = new Set<(locked: boolean) => void>();\n\n const assertActive = () => {\n if (disposed) throw new ProjectionDisposedError();\n };\n const assertIdle = () => {\n assertActive();\n if (phase !== 'idle')\n throw new Error('Projection cannot be re-entered during processing or notification.');\n };\n const lock = (value: boolean) => guards.forEach(guard => guard(value));\n\n const enqueue = (processor: ProcessorRecord) => {\n if (processor.disposed || queued.has(processor)) return;\n queued.add(processor);\n profile.projection('scheduledNodes');\n let index = heap.length;\n heap.push(processor);\n while (index > 0) {\n const parent = (index - 1) >> 1;\n if (heap[parent].order < processor.order) break;\n heap[index] = heap[parent];\n index = parent;\n }\n heap[index] = processor;\n };\n\n const pop = (): ProcessorRecord => {\n const first = heap[0];\n const last = heap.pop()!;\n if (heap.length) {\n let index = 0;\n while (index * 2 + 1 < heap.length) {\n let child = index * 2 + 1;\n if (child + 1 < heap.length && heap[child + 1].order < heap[child].order) child++;\n if (last.order < heap[child].order) break;\n heap[index] = heap[child];\n index = child;\n }\n heap[index] = last;\n }\n return first;\n };\n\n const errorFor = (\n producer: ProducerRecord,\n cause: unknown,\n kind: ProjectionError['phase'] = producer.kind === 'source' ? 'source' : 'processor'\n ) => new ProjectionError(kind, cause);\n\n const capture = (source: SourceBoundaryRecord) => {\n if (disposed) return;\n if (phase !== 'idle') {\n source.fault = errorFor(\n source,\n new Error('Source changed while projection was running.'),\n 'source'\n );\n errors.push(source.fault);\n throw source.fault;\n }\n pendingSources.add(source);\n profile.projection('sourceEvents');\n if (source.fault) errors.push(source.fault);\n };\n\n const settleCause = (): unknown => {\n if (activeBatch?.cause !== undefined) return activeBatch.cause;\n for (const source of pendingSources) {\n const cause = source.pendingCause();\n if (cause !== undefined) return cause;\n }\n return undefined;\n };\n\n const settle = () => {\n if (disposed || depth || phase !== 'idle') return;\n phase = 'compute';\n lock(true);\n const cause = settleCause();\n try {\n for (const source of pendingSources) {\n if (source.disposed) continue;\n const wasFaulted = source.fault !== undefined;\n let changed = false;\n let force = false;\n if (!source.fault || source.recovering()) {\n try {\n const prepared = source.prepare(cause);\n changed = prepared.changed;\n force = prepared.force;\n source.fault = undefined;\n } catch (failure) {\n source.fault = errorFor(source, failure, 'source');\n errors.push(source.fault);\n }\n }\n const recovered = wasFaulted && !source.fault;\n if (changed) source.publish();\n if (source.fault || changed || force || recovered) {\n const output = source.outputs[0];\n emissions.add(output);\n output.forEachConsumer(enqueue);\n }\n }\n\n while (heap.length) {\n const processor = pop();\n if (processor.disposed) continue;\n const wasFaulted = processor.fault !== undefined;\n profile.projection('processedNodes');\n let changedOutputs: readonly OutputRecord[] = Object.freeze([]);\n const blocked = processor.dependencies.find(\n output => output.owner.fault || output.owner.disposed\n );\n if (blocked) {\n processor.fault = errorFor(\n processor,\n blocked.owner.fault ?? new ProjectionDisposedError(),\n 'blocked'\n );\n } else {\n const reset = wasFaulted || processor.dependencies.some(output => output.reset());\n try {\n changedOutputs = processor.evaluate(reset, cause, wasFaulted);\n const dependencyFailure = processor.dependencies.find(output => output.owner.fault)\n ?.owner.fault;\n if (dependencyFailure) throw dependencyFailure;\n processor.fault = undefined;\n } catch (failure) {\n const error = errorFor(processor, failure);\n processor.fault = error;\n if (!reset) {\n try {\n changedOutputs = processor.evaluate(true, cause, true);\n const dependencyFailure = processor.dependencies.find(output => output.owner.fault)\n ?.owner.fault;\n if (dependencyFailure) throw dependencyFailure;\n processor.fault = undefined;\n errors.push(error);\n } catch (rebuildFailure) {\n processor.fault = errorFor(processor, rebuildFailure);\n errors.push(processor.fault);\n }\n } else errors.push(error);\n }\n }\n completed.add(processor);\n const recovered = wasFaulted && !processor.fault;\n if (processor.fault) {\n processor.outputs.forEach(output => {\n emissions.add(output);\n output.forEachConsumer(enqueue);\n });\n } else {\n if (changedOutputs.length) {\n processor.publish();\n changedOutputs.forEach(output => emissions.add(output));\n }\n const propagated = recovered ? processor.outputs : changedOutputs;\n propagated.forEach(output => output.forEachConsumer(enqueue));\n }\n if (processor.fault || changedOutputs.length) {\n profile.projection('publishedNodes');\n }\n }\n } finally {\n lock(false);\n phase = 'idle';\n }\n };\n\n const flush = (): readonly ObserverError[] => {\n if (disposed || depth) return [];\n if (pendingSources.size || completed.size) profile.projection('flushes');\n phase = 'notify';\n lock(true);\n const reportFailures: unknown[] = [];\n try {\n emissions.forEach(output =>\n output.emit(listener => {\n try {\n listener();\n } catch (cause) {\n errors.push(errorFor(output.owner, cause, 'listener'));\n }\n })\n );\n for (const error of errors.slice()) {\n try {\n onError(error);\n } catch (cause) {\n reportFailures.push(cause);\n }\n }\n return Object.freeze([\n ...errors.map(error =>\n Object.freeze({\n phase: error.phase === 'listener' ? ('listener' as const) : ('processor' as const),\n error,\n })\n ),\n ...reportFailures.map(error => Object.freeze({ phase: 'listener' as const, error })),\n ]);\n } finally {\n pendingSources.forEach(source => source.clear());\n completed.forEach(processor => processor.clear());\n pendingSources.clear();\n queued.clear();\n completed.clear();\n emissions.clear();\n errors.length = 0;\n reportingFailures = reportFailures;\n lock(false);\n phase = 'idle';\n }\n };\n\n const run = () => {\n settle();\n const result = flush();\n const failures = reportingFailures;\n reportingFailures = [];\n if (failures.length) throw new AggregateError(failures, 'Projection error reporter failed.');\n return result;\n };\n\n const batch = <T>(callback: () => T, options?: BatchOptions): T => {\n assertIdle();\n const outer = depth === 0;\n if (outer)\n activeBatch = Object.freeze({\n id: ++batchSequence,\n ...(options?.cause === undefined ? {} : { cause: options.cause }),\n });\n depth++;\n let failed = false;\n try {\n const value = callback();\n assertSynchronous(value);\n return value;\n } catch (error) {\n failed = true;\n throw error;\n } finally {\n depth--;\n if (!depth) {\n try {\n if (failed) {\n try {\n run();\n } catch {\n /* The original application error retains priority. */\n }\n } else run();\n } finally {\n activeBatch = undefined;\n }\n }\n }\n };\n\n const releaseProducer = (producer: ProducerRecord) => {\n assertIdle();\n if (producer.outputs.some(output => output.hasConsumers()))\n throw new Error('Projection producer is still used by another processor.');\n producer.disposed = true;\n if (producer.kind === 'processor') {\n producer.dependencies.forEach(output => output.detachConsumer(producer));\n processors.delete(producer);\n queued.delete(producer);\n completed.delete(producer);\n } else {\n sources.delete(producer);\n pendingSources.delete(producer);\n }\n const failures: unknown[] = [];\n try {\n producer.release();\n } catch (error) {\n failures.push(error);\n }\n try {\n producer.clear();\n } catch (error) {\n failures.push(error);\n }\n producer.outputs.forEach(output => emissions.delete(output));\n if (failures.length) throw failures[0];\n };\n\n return {\n assertActive,\n assertIdle,\n capture,\n settle,\n flush,\n run,\n registerGuard(guard: (locked: boolean) => void): Unsubscribe {\n assertActive();\n guards.add(guard);\n let registered = true;\n return () => {\n if (!registered) return;\n registered = false;\n guards.delete(guard);\n };\n },\n get active() {\n return !disposed;\n },\n addSource(source: SourceBoundaryRecord) {\n assertIdle();\n sources.add(source);\n },\n addProcessor(processor: ProcessorRecord) {\n assertIdle();\n processors.add(processor);\n processor.dependencies.forEach(output => output.attachConsumer(processor));\n },\n releaseProducer,\n order: () => sequence++,\n initialize<T>(callback: () => T): T {\n assertIdle();\n phase = 'compute';\n lock(true);\n try {\n return callback();\n } finally {\n lock(false);\n phase = 'idle';\n }\n },\n batch,\n batchContext: () => activeBatch,\n dispose() {\n if (disposed) return;\n assertIdle();\n disposed = true;\n const failures: unknown[] = [];\n processors.forEach(processor => {\n processor.disposed = true;\n try {\n processor.release();\n } catch (error) {\n failures.push(error);\n }\n });\n sources.forEach(source => {\n source.disposed = true;\n try {\n source.release();\n } catch (error) {\n failures.push(error);\n }\n });\n processors.clear();\n sources.clear();\n pendingSources.clear();\n heap.length = 0;\n queued.clear();\n completed.clear();\n emissions.clear();\n guards.clear();\n errors.length = 0;\n reportingFailures = [];\n if (failures.length) throw new AggregateError(failures, 'Projection cleanup failed.');\n },\n };\n};\n\nexport type Scheduler = ReturnType<typeof createScheduler>;\n\nexport const assertSynchronous = (value: unknown): void => {\n if (\n value != null &&\n (typeof value === 'object' || typeof value === 'function') &&\n 'then' in value &&\n typeof value.then === 'function'\n )\n throw new TypeError('Projection callbacks must be synchronous.');\n};\n\nexport const assertScope = (active: () => boolean) => {\n if (!active()) throw new Error('Projection reader or writer is no longer active.');\n};\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "doxum",
3
- "version": "0.1.25",
3
+ "version": "0.1.26",
4
4
  "private": false,
5
5
  "license": "MIT",
6
6
  "description": "Doxum is a typed runtime for complex mutable documents.",
@@ -79,13 +79,14 @@
79
79
  "vitest": "^4.0.16"
80
80
  },
81
81
  "scripts": {
82
- "build": "tsdown --config tsdown.config.ts && node scripts/check-build-exports.mjs",
82
+ "build": "tsdown --config tsdown.config.ts && node scripts/check-build-exports.mjs && pnpm run check:declaration-portability",
83
83
  "typecheck": "tsc -p tsconfig.json --noEmit",
84
84
  "test": "vitest run --config vitest.config.ts",
85
85
  "check": "pnpm run format:check && pnpm run lint && pnpm run typecheck && pnpm run check:public-types && pnpm run test && pnpm run check:projection-surface && pnpm run check:runtime-imports",
86
86
  "check:projection-surface": "node scripts/check-projection-surface.mjs",
87
87
  "check:runtime-imports": "node scripts/check-runtime-imports.mjs",
88
88
  "check:public-types": "tsc -p tsconfig.public-api.json --noEmit",
89
+ "check:declaration-portability": "tsc -p tsconfig.declaration-portability.json && node scripts/check-declaration-portability.mjs",
89
90
  "bench": "vitest bench --config vitest.bench.config.ts",
90
91
  "profile": "node --expose-gc --import tsx core/bench/profile.ts",
91
92
  "format": "prettier --write --ignore-unknown .",
@@ -39,8 +39,14 @@ Before runtime changes read [invariants](references/invariants.en.md) or
39
39
  kinds, optional before/after order in the same group, and a separate root reset.
40
40
  Standalone order records and duplicate groups are invalid. Grouping preserves field-level impact.
41
41
  - Paths belong in subscription, impact and collection source callbacks.
42
+ - `Schema` / `ObjectSchema` are portable schema handles. Export inferred schemas
43
+ directly; application code should not need `ReturnType<typeof object>` or internal
44
+ node types to make declarations portable.
42
45
  - Projection definitions are lazy; one ProjectionRuntime owns all materialized
43
46
  producers, outputs, scheduling and source attachments for that Runtime.
47
+ `KeyedProjection<K,V>` is the single public keyed projection handle. Collection
48
+ `observe`, `derive.keyed`, `incremental.collection`, group collection leaves and
49
+ `CollectionInput<K,V>` all use that same keyed capability.
44
50
  Use named-object `derive` for pure aggregate values. Use `derive.keyed` when one keyed
45
51
  driver owns the output key domain/order: per-entry equality suppresses unchanged
46
52
  selected values. Its dependency form uses a named object: plain Projection members
@@ -60,7 +66,7 @@ Before runtime changes read [invariants](references/invariants.en.md) or
60
66
  when retained state is actually needed. `incremental.group` declares its static
61
67
  output tree through the synchronous `output` callback. `define.value` and
62
68
  `define.collection` are callback methods, not separate imports; every returned leaf
63
- is an ordinary Projection from the same producer.
69
+ is a `Projection<T>` or `KeyedProjection<K,V>` from the same producer.
64
70
  - Observer errors leave commits accepted. Do not retry as if they rolled back.
65
71
  - Core stays framework-neutral; adapters consume standard `Readable`,
66
72
  document `select`, and projection readables without internal target/address protocols.
@@ -32,6 +32,8 @@ Public schema types are `Schema<T>`, `ObjectSchema<T>`, `Infer<S>`, `ReadonlyVal
32
32
  `Validator<T>`, `SchemaPath<S>`, `PathValueOf<P>`, `DocumentAnchor`,
33
33
  `DocumentListConfig<T>`, `DocumentTreeNode<T>` and `DocumentTreeValue<T>`.
34
34
  Concrete node representation types are internal.
35
+ `Schema` / `ObjectSchema` are declaration-portable handles; downstream packages can
36
+ export inferred schema constants directly without `ReturnType` wrappers.
35
37
 
36
38
  `Validator<T>` is validation-only. A function validator is a predicate/assertion:
37
39
  `true` or `undefined` succeeds, `false` rejects, and an assertion may throw.
@@ -142,9 +144,11 @@ applies none of that edit. `ProjectionScope` mirrors `read`, `select`, `update`,
142
144
  derives and advanced output trees. One definition can belong to only one scope; call
143
145
  `own` before that definition is first materialized as a root.
144
146
 
145
- Public projection types are `Projection<T>`, `Input<T>`, `CollectionInput<K,V>`,
146
- `CollectionInputDraft<K,V>`, `ProjectionRuntime`, `ProjectionScope`, plus the external
147
- source/event contracts. `ProjectionError` exposes only `phase` and `cause`;
147
+ Public projection types are `Projection<T>`, `KeyedProjection<K,V>`, `Input<T>`,
148
+ `CollectionInput<K,V>`, `CollectionInputDraft<K,V>`, `ProjectionRuntime`,
149
+ `ProjectionScope`, plus the external source/event contracts. All keyed producers return
150
+ `KeyedProjection<K,V>`; `CollectionInput<K,V>` is its writable Runtime-local form.
151
+ `ProjectionError` exposes only `phase` and `cause`;
148
152
  `ProjectionDisposedError` represents disposed access.
149
153
 
150
154
  External value sources expose `kind: 'value'`, `current()`, `revision()`, `subscribe()`.
@@ -190,8 +194,9 @@ const view = incremental.group(
190
194
  ```
191
195
 
192
196
  `define.collection<K,V>(equality?)` and `define.value<T>(equality?)` exist only inside
193
- `output`. The returned static object tree is mirrored with ordinary `Projection` leaves.
194
- Every declared descriptor must be returned exactly once.
197
+ `output`. The returned static object tree is mirrored with `KeyedProjection<K,V>`
198
+ collection leaves and `Projection<T>` value leaves. Every declared descriptor must be
199
+ returned exactly once.
195
200
 
196
201
  Normal source resets preserve retained state when declared. If a processor faults, the
197
202
  Runtime owns recovery: it recreates declared state and runs a reset evaluation. Stateless
@@ -199,8 +204,9 @@ processors use the same recovery path without a state object. There is no public
199
204
  token or manual recovery protocol.
200
205
 
201
206
  Exported advanced helper types are the value/collection/group context and definition
202
- types plus `CollectionChange`; internal scheduler/output declaration plumbing is not
203
- part of the public contract.
207
+ types, `CollectionChange`, and the declaration-safe `IncrementalGroupOutput` /
208
+ `IncrementalGroupResult` type boundaries. Normal callers infer the latter two; internal
209
+ scheduler/output plumbing is not part of the public contract.
204
210
 
205
211
  ## `doxum/react`
206
212
 
@@ -32,6 +32,8 @@
32
32
  `ReadonlyValue<T>`、`Validator<T>`、`SchemaPath<S>`、`PathValueOf<P>`、
33
33
  `DocumentAnchor`、`DocumentListConfig<T>`、`DocumentTreeNode<T>`、
34
34
  `DocumentTreeValue<T>`。具体 node representation 属于内部实现,不是公开契约。
35
+ `Schema` / `ObjectSchema` 是可跨 package 生成声明的 handle;下游 package 可以直接
36
+ export 推导出的 schema 常量,不需要应用层写 `ReturnType` 包装。
35
37
 
36
38
  `Validator<T>` 只负责校验。函数 validator 是 predicate/assertion:返回 `true` 或
37
39
  `undefined` 表示成功,返回 `false` 表示拒绝,assertion 也可以 throw。
@@ -139,9 +141,11 @@ dependency object 时为 `(value, key, dependencies)`。
139
141
  tree 的 lifecycle。同一个 definition 只能属于一个 scope,并且必须在该 definition
140
142
  首次作为 root materialize 之前调用 `own`。
141
143
 
142
- 公开 Projection 类型包括 `Projection<T>`、`Input<T>`、`CollectionInput<K,V>`、
143
- `CollectionInputDraft<K,V>`、`ProjectionRuntime`、`ProjectionScope` 和 external
144
- source/event contract。`ProjectionError` 只公开 `phase` 与 `cause`;
144
+ 公开 Projection 类型包括 `Projection<T>`、`KeyedProjection<K,V>`、`Input<T>`、
145
+ `CollectionInput<K,V>`、`CollectionInputDraft<K,V>`、`ProjectionRuntime`、
146
+ `ProjectionScope` 和 external source/event contract。所有 keyed producer 都返回
147
+ `KeyedProjection<K,V>`;`CollectionInput<K,V>` 是它的 Runtime-local writable 形式。
148
+ `ProjectionError` 只公开 `phase` 与 `cause`;
145
149
  `ProjectionDisposedError` 表达 disposed access。
146
150
 
147
151
  External value source 提供 `kind: 'value'`、`current()`、`revision()`、`subscribe()`。
@@ -187,14 +191,16 @@ const view = incremental.group(
187
191
 
188
192
  `define.collection<K,V>(equality?)`、`define.value<T>(equality?)` 只存在于
189
193
  `output` callback 内。返回值必须是非空静态 object tree,每个 descriptor 恰好返回一次;
190
- 最终同 shape 的每个 leaf 都是普通 `Projection`。
194
+ 最终同 shape 的 collection leaf 是 `KeyedProjection<K,V>`,value leaf 是
195
+ `Projection<T>`。
191
196
 
192
197
  普通 source reset 保留已声明的 retained state。processor fault 的 recovery 由 Runtime
193
198
  拥有:重新创建已声明的 state,再执行 reset evaluation;stateless processor 走同一恢复
194
199
  路径但没有 state object。没有公开 rebuild token 或手工恢复协议。
195
200
 
196
- advanced 只导出 value/collection/group 的 context/definition 类型以及
197
- `CollectionChange`;scheduler/output declaration plumbing 不属于公开 API。
201
+ advanced 导出 value/collection/group 的 context/definition 类型、`CollectionChange`,
202
+ 以及声明可移植性所需的 `IncrementalGroupOutput` / `IncrementalGroupResult` 类型边界。
203
+ 普通调用方通常只依赖推导;scheduler/output runtime plumbing 不属于公开 API。
198
204
 
199
205
  ## `doxum/react`
200
206
 
@@ -8,6 +8,8 @@ ownership, invalidation and recovery.
8
8
  Projection definitions are lazy. Root definitions are reusable across runtimes;
9
9
  scope definitions belong to one `ProjectionScope`. A public `Projection<T>` contains
10
10
  no materialized value, state, subscription or disposal state.
11
+ `KeyedProjection<K,V>` is the corresponding public keyed handle and is safe to export
12
+ from another package's declarations.
11
13
 
12
14
  ```ts
13
15
  const tasks = observe(document, path => path.tasks);
@@ -215,7 +217,8 @@ const render = incremental.group(
215
217
 
216
218
  `define.collection<K,V>(equality?)` and `define.value<T>(equality?)` are available only
217
219
  inside `output`. The returned static object tree is mirrored by ordinary Projection
218
- leaves from the same producer. Value leaves must be established on initial build and
220
+ leaves from the same producer: collections are `KeyedProjection<K,V>` and values are
221
+ `Projection<T>`. Value leaves must be established on initial build and
219
222
  Runtime recovery; untouched value leaves keep their value on ordinary incremental runs.
220
223
 
221
224
  Normal source resets preserve retained state when declared. A processor fault is
@@ -7,6 +7,8 @@
7
7
  Projection definition 是惰性的。root definition 可跨多个 runtime 复用;scope definition
8
8
  属于一个 `ProjectionScope`。公开 `Projection<T>` 本身不保存 materialized value、
9
9
  retained state、subscription 或 disposal state。
10
+ `KeyedProjection<K,V>` 是对应的公开 keyed handle,也可以安全出现在下游 package
11
+ 生成的声明中。
10
12
 
11
13
  ```ts
12
14
  const tasks = observe(document, path => path.tasks);
@@ -210,7 +212,8 @@ const render = incremental.group(
210
212
  ```
211
213
 
212
214
  `define.collection<K,V>(equality?)`、`define.value<T>(equality?)` 只存在于 `output`
213
- callback 内。返回的静态 object tree 会映射为同一 producer 的普通 Projection leaves。
215
+ callback 内。返回的静态 object tree 会映射为同一 producer 的 projection leaves:
216
+ collection 为 `KeyedProjection<K,V>`,value 为 `Projection<T>`。
214
217
  initial build 和 Runtime recovery 必须建立每个 value leaf;普通 incremental run 中未触碰
215
218
  value leaf 会保留已发布值。
216
219