doxum 0.1.19 → 0.1.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -11
- package/dist/{scope-d-L87NeC.js → access-BeSV5ve-.js} +114 -20
- package/dist/access-BeSV5ve-.js.map +1 -0
- package/dist/{scope-Ezs-Y3TY.cjs → access-Bienf28h.cjs} +149 -19
- package/dist/access-Bienf28h.cjs.map +1 -0
- package/dist/advanced-BRL5pN0y.cjs +1361 -0
- package/dist/advanced-BRL5pN0y.cjs.map +1 -0
- package/dist/advanced-COFJtWMT.js +1188 -0
- package/dist/advanced-COFJtWMT.js.map +1 -0
- package/dist/{advanced-C2fpjbK3.d.ts → advanced-DfKc7TZR.d.cts} +27 -22
- package/dist/{advanced-DlOYk1vi.d.cts → advanced-FgdTwu5b.d.ts} +27 -22
- package/dist/advanced.cjs +1 -1
- package/dist/advanced.d.cts +2 -2
- package/dist/advanced.d.ts +2 -2
- package/dist/advanced.js +1 -1
- package/dist/{contract-XmKnroJq.d.cts → contract-CdmDHRUq.d.cts} +8 -6
- package/dist/{contract-CATCCVu5.d.ts → contract-KG5XnQZt.d.ts} +8 -6
- package/dist/{driver-CSnhMjbP.js → driver-CLYJOGDQ.js} +2 -2
- package/dist/{driver-CSnhMjbP.js.map → driver-CLYJOGDQ.js.map} +1 -1
- package/dist/{driver-BCyfqxsl.cjs → driver-Djr3BVvo.cjs} +2 -2
- package/dist/{driver-BCyfqxsl.cjs.map → driver-Djr3BVvo.cjs.map} +1 -1
- package/dist/index.cjs +1150 -1993
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1105 -1948
- package/dist/index.js.map +1 -1
- package/dist/{integration-CxVhq-KD.js → integration-C4Isp8lJ.js} +3 -2
- package/dist/{integration-CxVhq-KD.js.map → integration-C4Isp8lJ.js.map} +1 -1
- package/dist/{integration-B7VDgAOJ.cjs → integration-Z6MsfFI7.cjs} +4 -3
- package/dist/{integration-B7VDgAOJ.cjs.map → integration-Z6MsfFI7.cjs.map} +1 -1
- package/dist/integration.cjs +3 -3
- package/dist/integration.d.cts +1 -1
- package/dist/integration.d.ts +1 -1
- package/dist/integration.js +3 -3
- package/dist/{issue-DhrNdQNg.cjs → issue-DjK1xp5K.cjs} +106 -22
- package/dist/issue-DjK1xp5K.cjs.map +1 -0
- package/dist/{issue-DVaGQGeP.js → issue-W0hT8u8D.js} +81 -15
- package/dist/issue-W0hT8u8D.js.map +1 -0
- package/dist/local-sync.cjs +2 -2
- package/dist/local-sync.d.cts +1 -1
- package/dist/local-sync.d.ts +1 -1
- package/dist/local-sync.js +2 -2
- package/dist/{notification-IQIJyH3Q.js → notification-Bkjau6B6.js} +3 -56
- package/dist/notification-Bkjau6B6.js.map +1 -0
- package/dist/{notification-CDSUfiip.cjs → notification-DJfouMEb.cjs} +2 -91
- package/dist/notification-DJfouMEb.cjs.map +1 -0
- package/dist/react.cjs +2 -2
- package/dist/react.js +2 -2
- package/package.json +1 -1
- package/skills/doxum-runtime/SKILL.md +4 -1
- package/skills/doxum-runtime/references/guide.en.md +5 -2
- package/skills/doxum-runtime/references/guide.zh-CN.md +5 -2
- package/skills/doxum-runtime/references/projections.en.md +23 -9
- package/skills/doxum-runtime/references/projections.zh-CN.md +18 -6
- package/dist/advanced-BYZCjNWL.js +0 -680
- package/dist/advanced-BYZCjNWL.js.map +0 -1
- package/dist/advanced-CMMNk49G.cjs +0 -763
- package/dist/advanced-CMMNk49G.cjs.map +0 -1
- package/dist/issue-DVaGQGeP.js.map +0 -1
- package/dist/issue-DhrNdQNg.cjs.map +0 -1
- package/dist/notification-CDSUfiip.cjs.map +0 -1
- package/dist/notification-IQIJyH3Q.js.map +0 -1
- package/dist/scope-Ezs-Y3TY.cjs.map +0 -1
- package/dist/scope-d-L87NeC.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"issue-W0hT8u8D.js","names":["isRecord","isRecord","contains","anchor.indexedKeys","isTree"],"sources":["../core/src/profile.ts","../core/src/mutation/anchor.ts","../core/src/value/ownership.ts","../core/src/mutation/tree.ts","../core/src/address.ts","../core/src/mutation/issue.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 },\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 arraysCopied: 0,\n listIndexes: 0,\n listItems: 0,\n },\n impact: { affectsChecks: 0, indexes: 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 },\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 arrayCopied: () => {\n if (active) active.address.arraysCopied++;\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 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 { DocumentAnchor } from '../schema';\nimport { profile } from '../profile';\n\nexport const equal = (left: readonly string[], right: Keys): boolean => {\n profile.equality.call();\n if (left === right) return true;\n profile.equality.container();\n if (left.length !== right.length) return false;\n for (let i = 0; i < left.length; i++) if (left[i] !== keyAt(right, i)) return false;\n return true;\n};\n\nexport type KeyOrder = {\n readonly length: number;\n readonly at: (index: number) => string | undefined;\n readonly index: (key: string) => number;\n};\n\ntype Keys = readonly string[] | KeyOrder;\n\ntype ListSequence = {\n readonly order: readonly string[];\n readonly values: ReadonlyMap<string, unknown>;\n};\n\ntype MoveSelection =\n | { readonly kind: 'ok'; readonly order: readonly string[] }\n | { readonly kind: 'duplicate' }\n | { readonly kind: 'missing' }\n | { readonly kind: 'invalid-anchor' };\n\nconst length = (keys: Keys): number => keys.length;\nconst keyAt = (keys: Keys, index: number): string | undefined =>\n Array.isArray(keys) ? keys[index] : keys.at(index);\nconst keyIndex = (keys: Keys, key: string): number =>\n Array.isArray(keys) ? keys.indexOf(key) : (keys as KeyOrder).index(key);\n\nexport const keys = (values: readonly unknown[], keyOf: (value: unknown) => string): KeyOrder => ({\n length: values.length,\n at: index => (index >= 0 && index < values.length ? keyOf(values[index]) : undefined),\n index: key => {\n for (let index = 0; index < values.length; index += 1)\n if (keyOf(values[index]) === key) return index;\n return -1;\n },\n});\n\nconst listIndexes = new WeakMap<\n readonly unknown[],\n { keyOf: (value: unknown) => string; order: KeyOrder }\n>();\n\nconst knownKeys = (keys: readonly string[]): KeyOrder => {\n let positions: Map<string, number> | undefined;\n return {\n length: keys.length,\n at: index => keys[index],\n index: key => {\n if (!positions) {\n positions = new Map();\n for (let index = 0; index < keys.length; index++) positions.set(keys[index], index);\n profile.address.listIndex(keys.length);\n }\n return positions.get(key) ?? -1;\n },\n };\n};\n\nconst cacheKnownKeys = (\n values: readonly unknown[],\n keyOf: (value: unknown) => string,\n keys: readonly string[]\n): void => {\n listIndexes.set(values, { keyOf, order: knownKeys(keys) });\n};\n\n/** Canonical lists keep their key positions until a structural write invalidates them. */\nexport const indexedKeys = (\n values: readonly unknown[],\n keyOf: (value: unknown) => string\n): KeyOrder => {\n const cached = listIndexes.get(values);\n if (cached?.keyOf === keyOf) return cached.order;\n let positions: Map<string, number> | undefined;\n const order: KeyOrder = {\n length: values.length,\n at: index => (index >= 0 && index < values.length ? keyOf(values[index]) : undefined),\n index: key => {\n if (!positions) {\n positions = new Map();\n for (let i = 0; i < values.length; i++) positions.set(keyOf(values[i]), i);\n profile.address.listIndex(values.length);\n }\n return positions.get(key) ?? -1;\n },\n };\n listIndexes.set(values, { keyOf, order });\n return order;\n};\n\nexport const toArray = (keys: Keys): string[] => {\n const result = new Array<string>(length(keys));\n for (let index = 0; index < result.length; index++) result[index] = keyAt(keys, index) as string;\n return result;\n};\n\n/** One operation-local list scan provides both stable keys and item association. */\nexport const listSequence = (\n values: readonly unknown[],\n keyOf: (value: unknown) => string\n): ListSequence => {\n const current = indexedKeys(values, keyOf);\n const order = new Array<string>(values.length);\n const byKey = new Map<string, unknown>();\n for (let index = 0; index < values.length; index++) {\n const key = current.at(index) as string;\n order[index] = key;\n byKey.set(key, values[index]);\n }\n cacheKnownKeys(values, keyOf, order);\n return { order, values: byKey };\n};\n\n/** Plan one relative move against the order that remains after removing the selection. */\nexport const moveSelection = (\n current: readonly string[],\n selection: readonly string[],\n position?: DocumentAnchor\n): MoveSelection => {\n if (!selection.length) return { kind: 'ok', order: current };\n const selected = new Set<string>();\n for (const key of selection) {\n if (selected.has(key)) return { kind: 'duplicate' };\n selected.add(key);\n }\n const moved: string[] = [];\n const remaining: string[] = [];\n for (const key of current) (selected.has(key) ? moved : remaining).push(key);\n if (moved.length !== selected.size) return { kind: 'missing' };\n if (!valid(remaining, position)) return { kind: 'invalid-anchor' };\n const insertion = index(remaining, position);\n return {\n kind: 'ok',\n order: [...remaining.slice(0, insertion), ...moved, ...remaining.slice(insertion)],\n };\n};\n\n/** Structural sequence writes own invalidation, including rollback writes. */\nexport const insert = (values: unknown[], index: number, value: unknown): void => {\n values.splice(index, 0, value);\n listIndexes.delete(values);\n};\n\nexport const remove = (values: unknown[], index: number): void => {\n values.splice(index, 1);\n listIndexes.delete(values);\n};\n\n/** Install an exact string-key sequence such as table ids in one structural write. */\nexport const installKeys = (values: string[], order: readonly string[]): void => {\n values.length = order.length;\n for (let index = 0; index < order.length; index++) values[index] = order[index];\n};\n\n/** Install a pre-resolved list sequence without running keyOf again. */\nexport const installList = (\n values: unknown[],\n keyOf: (value: unknown) => string,\n sequence: ListSequence,\n order: readonly string[]\n): void => {\n values.length = order.length;\n for (let index = 0; index < order.length; index++)\n values[index] = sequence.values.get(order[index]);\n cacheKnownKeys(values, keyOf, order);\n};\n\nexport const install = (\n values: unknown[],\n keyOf: (value: unknown) => string,\n order: readonly string[]\n): void => {\n installList(values, keyOf, listSequence(values, keyOf), order);\n};\n\nexport const matches = (order: readonly string[], members: readonly string[]): boolean => {\n if (order.length !== members.length) return false;\n const ids = new Set(order);\n return ids.size === order.length && members.every(id => ids.has(id));\n};\n\nexport const index = (keys: Keys, anchor?: DocumentAnchor): number => {\n if (!anchor) return length(keys);\n if ('at' in anchor) return anchor.at === 'start' ? 0 : length(keys);\n if ('before' in anchor) return keyIndex(keys, anchor.before);\n return keyIndex(keys, anchor.after) + 1;\n};\n\nexport const at = (keys: Keys, position: number): DocumentAnchor =>\n position <= 0 ? { at: 'start' } : { after: keyAt(keys, position - 1) as string };\n\nexport const valid = (keys: Keys, anchor?: DocumentAnchor): boolean => {\n if (!anchor) return true;\n if (typeof anchor !== 'object' || anchor === null) return false;\n if (Number('at' in anchor) + Number('before' in anchor) + Number('after' in anchor) !== 1)\n return false;\n if ('at' in anchor) return anchor.at === 'start' || anchor.at === 'end';\n return keyIndex(keys, 'before' in anchor ? anchor.before : anchor.after) >= 0;\n};\n\nexport const validPositions = (length: number, positions: readonly number[]): boolean => {\n let previous = -1;\n for (let index = 0; index < positions.length; index += 1) {\n const position = positions[index];\n if (\n !Number.isInteger(position) ||\n position < 0 ||\n position <= previous ||\n position > length + index\n )\n return false;\n previous = position;\n }\n return true;\n};\n\nexport const restore = (\n keys: string[],\n inserted: readonly string[],\n positions: readonly number[]\n): void => {\n const currentLength = keys.length;\n if (inserted.length !== positions.length || !validPositions(currentLength, positions))\n throw new Error('Ordered restore positions are invalid.');\n let readIndex = currentLength - 1;\n let insertedIndex = inserted.length - 1;\n keys.length = currentLength + inserted.length;\n for (let writeIndex = keys.length - 1; writeIndex >= 0; writeIndex -= 1) {\n if (insertedIndex >= 0 && positions[insertedIndex] === writeIndex) {\n keys[writeIndex] = inserted[insertedIndex];\n insertedIndex -= 1;\n } else {\n keys[writeIndex] = keys[readIndex];\n readIndex -= 1;\n }\n }\n};\n","export const isPlainObject = (value: unknown): value is Record<string, unknown> => {\n if (value === null || typeof value !== 'object') return false;\n const prototype = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n};\n\nexport const isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value);\n","import { isRecord } from '../value/ownership';\nexport type MutableTreeNode = { parentId?: string; children: string[]; value?: unknown };\nexport type MutableTree = { rootId?: string; nodes: Record<string, MutableTreeNode> };\nconst node = (tree: MutableTree, id: string) =>\n Object.hasOwn(tree.nodes, id) ? tree.nodes[id] : undefined;\nexport const is = (value: unknown): value is MutableTree =>\n isRecord(value) && isRecord(value.nodes);\n\nexport const validNode = (value: unknown): value is MutableTreeNode => {\n if (!isRecord(value) || !Array.isArray(value.children)) return false;\n if (value.parentId !== undefined && typeof value.parentId !== 'string') return false;\n const children = new Set<string>();\n for (const id of value.children) {\n if (typeof id !== 'string' || children.has(id)) return false;\n children.add(id);\n }\n return true;\n};\n\nexport const contains = (tree: MutableTree, id: string): boolean => Object.hasOwn(tree.nodes, id);\n\nexport const parent = (tree: MutableTree, id: string): string | undefined =>\n node(tree, id)?.parentId;\n\nexport const children = (tree: MutableTree, id: string): readonly string[] | undefined =>\n node(tree, id)?.children;\n\nexport const validate = (value: unknown): value is MutableTree => {\n if (!is(value)) return false;\n const ids = Object.keys(value.nodes);\n if (ids.length === 0) return value.rootId === undefined;\n if (typeof value.rootId !== 'string' || !Object.hasOwn(value.nodes, value.rootId)) return false;\n\n for (const id of ids) {\n const entry = value.nodes[id];\n if (!validNode(entry)) return false;\n if (id === value.rootId) {\n if (entry.parentId !== undefined) return false;\n } else if (entry.parentId === undefined || !Object.hasOwn(value.nodes, entry.parentId))\n return false;\n for (const child of entry.children) {\n const childNode = value.nodes[child];\n if (!childNode || childNode.parentId !== id) return false;\n }\n }\n\n const seen = new Set<string>();\n const stack = [value.rootId];\n while (stack.length) {\n const id = stack.pop() as string;\n if (seen.has(id)) return false;\n seen.add(id);\n const entry = value.nodes[id];\n if (!entry) return false;\n for (const child of entry.children) stack.push(child);\n }\n return seen.size === ids.length;\n};\n\nexport type TreePosition = { readonly parentId?: string; readonly index?: number };\n","import type { DocumentAddress, DocumentNode, ObjectNode, ObjectShape } from './schema';\nimport * as anchor from './mutation/anchor';\nimport { profile } from './profile';\nimport type { MutableTree } from './mutation/tree';\nimport { is as isTree } from './mutation/tree';\n\n/** The only resolved address representation used inside the runtime. */\nexport type AddressRef = {\n readonly path: number;\n readonly address: DocumentAddress;\n};\n\ntype RegistryNode = {\n readonly static: Map<string, RegistryNode>;\n dynamic?: RegistryNode;\n path?: number;\n};\n\ntype Registry = {\n readonly root: RegistryNode;\n nextPath: number;\n};\n\nconst registries = new WeakMap<object, Registry>();\nconst registryNode = (): RegistryNode => ({ static: new Map() });\nconst registryFor = (schema: ObjectNode): Registry => {\n const cached = registries.get(schema as object);\n if (cached) return cached;\n const registry: Registry = { root: registryNode(), nextPath: 0 };\n registries.set(schema as object, registry);\n return registry;\n};\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value);\n\nconst variantNode = (\n node: Extract<DocumentNode, { kind: 'variant' }>,\n value: unknown\n): DocumentNode | undefined => {\n const tag = isRecord(value) && typeof value[node.tag] === 'string' ? value[node.tag] : undefined;\n return node.variants[String(tag ?? Object.keys(node.variants)[0] ?? '')];\n};\n\nconst step = (\n nodeInput: DocumentNode | undefined,\n value: unknown,\n segment: string\n): DocumentNode | undefined => {\n let node = nodeInput;\n if (!node) return undefined;\n if (node.kind === 'variant') {\n node = variantNode(node, value);\n }\n if (!node) return undefined;\n if (node.kind === 'object')\n return Object.hasOwn(node.shape, segment) ? node.shape[segment] : undefined;\n if (node.kind === 'table' || node.kind === 'map') return node.value;\n // List items use stable keys; tree topology remains a structural unit.\n if (node.kind === 'list') return node.value;\n return undefined;\n};\n\nconst pathFor = (\n schema: ObjectNode,\n address: DocumentAddress,\n document?: unknown\n): number | undefined => {\n const registry = registryFor(schema);\n let trie = registry.root;\n let node: DocumentNode | undefined = schema;\n let value: unknown = document;\n for (const segment of address) {\n profile.address.schemaStep();\n profile.address.documentStep();\n const resolved = step(node, value, segment);\n if (!resolved) return undefined;\n const next =\n node &&\n (node.kind === 'table' || node.kind === 'map' || node.kind === 'list' || node.kind === 'tree')\n ? (trie.dynamic ??= registryNode())\n : (() => {\n const existing = trie.static.get(segment);\n if (existing) return existing;\n const created = registryNode();\n trie.static.set(segment, created);\n return created;\n })();\n trie = next;\n value = readSegment(value, segment, node);\n node = resolved;\n }\n if (trie.path === undefined) trie.path = registry.nextPath++;\n return trie.path;\n};\n\nexport const resolveAddress = (\n schema: ObjectNode,\n address: DocumentAddress,\n document?: unknown\n): AddressRef | undefined => {\n if (!Array.isArray(address)) return undefined;\n for (const segment of address) if (typeof segment !== 'string') return undefined;\n profile.address.arrayCopied();\n const owned = Object.freeze(address.slice()) as DocumentAddress;\n const path = pathFor(schema, owned, document);\n return path === undefined ? undefined : { path, address: owned };\n};\n\nexport const nodeAt = (\n schema: DocumentNode,\n address: DocumentAddress,\n document?: unknown\n): DocumentNode | undefined => {\n let node: DocumentNode | undefined = schema;\n let value = document;\n for (const segment of address) {\n const resolved = step(node, value, segment);\n value = readSegment(value, segment, node);\n node = resolved;\n if (!node) return undefined;\n }\n return node;\n};\n\nexport const readSegment = (value: unknown, segment: string, node?: DocumentNode): unknown => {\n if (!isRecord(value) && !Array.isArray(value)) return undefined;\n if (node?.kind === 'list' && Array.isArray(value))\n return value[anchor.indexedKeys(value, node.keyOf).index(segment)];\n if (node?.kind === 'table' && isRecord(value) && isRecord(value.byId)) {\n return Object.hasOwn(value.byId, segment) ? value.byId[segment] : undefined;\n }\n return Object.prototype.hasOwnProperty.call(value, segment)\n ? (value as Record<string, unknown>)[segment]\n : undefined;\n};\n\nexport const read = (root: unknown, address: DocumentAddress, schema: DocumentNode): unknown => {\n let value = root;\n let node: DocumentNode | undefined = schema;\n for (const segment of address) {\n const next = step(node, value, segment);\n value = readSegment(value, segment, node);\n node = next;\n if (value === undefined) return undefined;\n }\n return value;\n};\n\nexport type ResolvedAddress = {\n readonly parent: Record<string, unknown> | unknown[];\n readonly key: string | number;\n readonly node: DocumentNode;\n};\n\ntype MemberDefinition = {\n readonly node: DocumentNode;\n readonly field: boolean;\n};\nexport type FixedMember = MemberDefinition & {\n readonly kind: 'fixed';\n readonly key: string;\n readonly slot: number;\n};\ntype CollectionMember = MemberDefinition & { readonly kind: 'entry' };\nexport type CompiledMember = FixedMember | CollectionMember;\nexport type FixedLayout = {\n readonly kind: 'fixed';\n readonly members: ReadonlyMap<string, FixedMember>;\n};\ntype DynamicLayout = { readonly kind: 'dynamic'; readonly entry: CollectionMember };\nexport type MemberLayout = FixedLayout | DynamicLayout;\nconst compiledObjects = new WeakMap<object, FixedLayout>();\nconst compiledEntries = new WeakMap<DocumentNode, DynamicLayout>();\nexport const compiledShape = (node: DocumentNode, value: unknown): FixedLayout | undefined => {\n const branch = node.kind === 'variant' ? variantNode(node, value) : node;\n if (branch?.kind !== 'object') return undefined;\n const shape: ObjectShape = branch.shape;\n let layout = compiledObjects.get(shape);\n if (!layout) {\n const compiled = new Map<string, FixedMember>();\n for (const key of Object.keys(shape).sort()) {\n profile.address.schemaStep();\n compiled.set(key, {\n kind: 'fixed',\n key,\n node: shape[key],\n field: shape[key].kind === 'field',\n slot: compiled.size,\n });\n }\n layout = { kind: 'fixed', members: compiled };\n compiledObjects.set(shape, layout);\n }\n return layout;\n};\n\n/** Immutable location facts, valid only for the resolving session generation. */\nexport type ResolvedContainer = {\n readonly owner: object;\n readonly generation: number;\n readonly at: DocumentAddress;\n readonly node: Exclude<DocumentNode, { kind: 'tree' }>;\n readonly parent: Record<string, unknown> | unknown[];\n readonly value: unknown;\n readonly layout: MemberLayout;\n};\nexport type ResolvedTreeContainer = {\n readonly owner: object;\n readonly generation: number;\n readonly at: DocumentAddress;\n readonly node: Extract<DocumentNode, { kind: 'tree' }>;\n readonly value: MutableTree;\n};\nexport const resolveContainer = (\n owner: object,\n generation: number,\n at: DocumentAddress,\n node: DocumentNode | undefined,\n value: unknown\n): ResolvedContainer | undefined => {\n if (!node || (!isRecord(value) && !Array.isArray(value))) return undefined;\n const parent = node.kind === 'table' && isRecord(value) ? value.byId : value;\n if (!isRecord(parent) && !Array.isArray(parent)) return undefined;\n if (node.kind === 'tree') return undefined;\n let layout: MemberLayout;\n if (node.kind === 'map' || node.kind === 'table' || node.kind === 'list') {\n let dynamic = compiledEntries.get(node);\n if (!dynamic) {\n dynamic = {\n kind: 'dynamic',\n entry: { kind: 'entry', node: node.value, field: node.value.kind === 'field' },\n };\n compiledEntries.set(node, dynamic);\n }\n layout = dynamic;\n } else {\n const fixed = compiledShape(node, value);\n if (!fixed) return undefined;\n layout = fixed;\n }\n return { owner, generation, at, node, parent, value, layout };\n};\nexport const resolveTreeContainer = (\n owner: object,\n generation: number,\n at: DocumentAddress,\n node: DocumentNode | undefined,\n value: unknown\n): ResolvedTreeContainer | undefined =>\n node?.kind === 'tree' && isTree(value) ? { owner, generation, at, node, value } : undefined;\nexport const memberKey = (\n container: { readonly node: DocumentNode; readonly parent: Record<string, unknown> | unknown[] },\n key: string\n): string | number =>\n container.node.kind === 'list'\n ? anchor.indexedKeys(container.parent as unknown[], container.node.keyOf).index(key)\n : key;\n\ntype ResolutionPrefix = {\n segment: string;\n node: DocumentNode;\n value: unknown;\n};\n\n/** One recent path per transaction; structural writes invalidate all retained locations. */\nexport const createAddressResolver = (schema: DocumentNode, root: unknown) => {\n const prefix: ResolutionPrefix[] = [];\n return {\n container: (owner: object, generation: number, at: DocumentAddress) => {\n if (!at.length) return resolveContainer(owner, generation, at, schema, root);\n const location = resolveWithPrefix(schema, root, at, prefix);\n if (!location || !Object.hasOwn(location.parent, location.key)) return undefined;\n return resolveContainer(\n owner,\n generation,\n at,\n location.node,\n (location.parent as Record<string | number, unknown>)[location.key]\n );\n },\n invalidate: () => {\n prefix.length = 0;\n },\n };\n};\n\n/** A subtree root is a value, not a fabricated member of an ObjectNode. */\nexport const resolveValue = (\n schema: DocumentNode,\n root: unknown,\n address: DocumentAddress,\n prefix?: ResolutionPrefix[]\n): { node: DocumentNode; value: unknown } | undefined => {\n if (!address.length) return { node: schema, value: root };\n const location = resolveWithPrefix(schema, root, address, prefix);\n return (\n location && {\n node: location.node,\n value: Object.hasOwn(location.parent, location.key)\n ? (location.parent as Record<string | number, unknown>)[location.key]\n : undefined,\n }\n );\n};\n\n/** Resolves schema and document location in one address traversal. */\nexport const resolveLocated = (\n schema: DocumentNode,\n root: unknown,\n address: DocumentAddress\n): ResolvedAddress | undefined => resolveWithPrefix(schema, root, address);\n\nconst resolveWithPrefix = (\n schema: DocumentNode,\n root: unknown,\n address: DocumentAddress,\n prefix?: ResolutionPrefix[]\n): ResolvedAddress | undefined => {\n if (address.length === 0) return undefined;\n let node: DocumentNode | undefined = schema;\n let current: unknown = root;\n let start = 0;\n if (prefix) {\n while (\n start < prefix.length &&\n start < address.length - 1 &&\n prefix[start].segment === address[start]\n )\n start++;\n prefix.length = start;\n if (start) {\n const retained = prefix[start - 1];\n node = retained.node;\n current = retained.value;\n }\n }\n let cacheable = true;\n for (let index = start; index < address.length - 1; index += 1) {\n profile.address.schemaStep();\n profile.address.documentStep();\n const resolved = step(node, current, address[index]);\n if (!resolved) return undefined;\n if (node?.kind !== 'object' && node?.kind !== 'table' && node?.kind !== 'map')\n cacheable = false;\n current = readSegment(current, address[index], node);\n node = resolved;\n if (prefix && cacheable)\n prefix.push({\n segment: address[index],\n node: resolved,\n value: current,\n });\n if (!node) return undefined;\n }\n const last = address[address.length - 1];\n return resolveChild(node, current, last);\n};\n\n/** Resolves one member from an already current schema/container pair. */\nexport const resolveChild = (\n node: DocumentNode | undefined,\n current: unknown,\n last: string\n): ResolvedAddress | undefined => {\n profile.address.schemaStep();\n profile.address.documentStep();\n const resolved = step(node, current, last);\n if (!resolved || (!isRecord(current) && !Array.isArray(current))) return undefined;\n if (node?.kind === 'table' && isRecord(current) && isRecord(current.byId))\n return {\n node: resolved,\n parent: current.byId,\n key: last,\n };\n return {\n node: resolved,\n parent: current,\n key:\n node?.kind === 'list' && Array.isArray(current)\n ? anchor.indexedKeys(current, node.keyOf).index(last)\n : last,\n };\n};\n\nexport const contains = (parent: DocumentAddress, child: DocumentAddress): boolean => {\n profile.address.prefixComparison();\n if (parent.length > child.length) return false;\n for (let index = 0; index < parent.length; index += 1) {\n profile.address.segmentCompared();\n if (parent[index] !== child[index]) return false;\n }\n return true;\n};\n\nexport const overlaps = (a: DocumentAddress, b: DocumentAddress): boolean =>\n contains(a, b) || contains(b, a);\n\nexport const debugKey = (address: DocumentAddress): string => {\n let result = '';\n for (let index = 0; index < address.length; index += 1) {\n if (index > 0) result += '/';\n result += address[index].replaceAll('~', '~~').replaceAll('/', '~/');\n }\n return result;\n};\n\nexport const same = (a: AddressRef, b: AddressRef): boolean => {\n if (a.path !== b.path || a.address.length !== b.address.length) return false;\n for (let index = 0; index < a.address.length; index += 1) {\n profile.address.segmentCompared();\n if (a.address[index] !== b.address[index]) return false;\n }\n return true;\n};\n\nexport type { DocumentAddress } from './schema';\n\ntype AddressIndexNode<T> = {\n readonly children: Map<string, AddressIndexNode<T>>;\n readonly values: Set<T>;\n};\n\n/** An index over canonical address segments, shared by impact and subscriptions. */\nexport class AddressIndex<T> {\n private readonly root: AddressIndexNode<T> = { children: new Map(), values: new Set() };\n\n add(address: DocumentAddress, value: T, member?: string): void {\n let node = this.root;\n for (let i = 0; i < address.length + (member === undefined ? 0 : 1); i++) {\n const segment = i < address.length ? address[i] : member!;\n let child = node.children.get(segment);\n if (!child) {\n child = { children: new Map(), values: new Set() };\n node.children.set(segment, child);\n }\n node = child;\n }\n node.values.add(value);\n }\n\n delete(address: DocumentAddress, value: T): void {\n const parents: AddressIndexNode<T>[] = [];\n let node = this.root;\n for (const segment of address) {\n const child = node.children.get(segment);\n if (!child) return;\n parents.push(node);\n node = child;\n }\n node.values.delete(value);\n for (let i = address.length - 1; i >= 0 && !node.values.size && !node.children.size; i--) {\n node = parents[i];\n node.children.delete(address[i]);\n }\n }\n\n exact(address: DocumentAddress): ReadonlySet<T> | undefined {\n let node = this.root;\n for (const segment of address) {\n const child = node.children.get(segment);\n if (!child) return undefined;\n node = child;\n }\n return node.values;\n }\n\n hasAncestor(address: DocumentAddress, strict = false): boolean {\n let node = this.root;\n for (let i = 0; i < address.length; i++) {\n if (node.values.size) return true;\n const child = node.children.get(address[i]);\n if (!child) return false;\n node = child;\n }\n return !strict && node.values.size > 0;\n }\n\n someAncestor(address: DocumentAddress, predicate: (value: T) => boolean): boolean {\n let node = this.root;\n for (let i = 0; ; i++) {\n for (const value of node.values) if (predicate(value)) return true;\n if (i === address.length) return false;\n const child = node.children.get(address[i]);\n if (!child) return false;\n node = child;\n }\n }\n\n overlaps(address: DocumentAddress): boolean {\n let node = this.root;\n for (const segment of address) {\n if (node.values.size) return true;\n const child = node.children.get(segment);\n if (!child) return false;\n node = child;\n }\n return node.values.size > 0 || node.children.size > 0;\n }\n\n hasDescendant(address: DocumentAddress): boolean {\n let node = this.root;\n for (const segment of address) {\n const child = node.children.get(segment);\n if (!child) return false;\n node = child;\n }\n return node.values.size > 0 || node.children.size > 0;\n }\n\n query(\n visit: (value: T) => void,\n relation: 'overlap' | 'ancestors' | 'descendants' = 'overlap'\n ): (address: DocumentAddress, members?: readonly { readonly key: string }[]) => void {\n const visited = new Set<AddressIndexNode<T>>();\n const subtrees = new Set<AddressIndexNode<T>>();\n const values = (node: AddressIndexNode<T>) => {\n if (visited.has(node)) return;\n visited.add(node);\n node.values.forEach(visit);\n };\n const descend = (current: AddressIndexNode<T>): void => {\n if (subtrees.has(current)) return;\n subtrees.add(current);\n values(current);\n current.children.forEach(descend);\n };\n const terminal = (node: AddressIndexNode<T>) =>\n relation === 'ancestors' ? values(node) : descend(node);\n return (address, members) => {\n let node = this.root;\n for (const segment of address) {\n if (subtrees.has(node)) return;\n if (relation !== 'descendants') values(node);\n const child = node.children.get(segment);\n if (!child) return;\n node = child;\n }\n if (!members) terminal(node);\n else {\n if (relation !== 'descendants') values(node);\n for (const member of members) {\n const child = node.children.get(member.key);\n if (child) terminal(child);\n }\n }\n };\n }\n\n clear(): void {\n this.root.values.clear();\n this.root.children.clear();\n }\n}\n","import type { DocumentAddress } from '../schema';\nimport type { ParseIssue } from '../schema-value';\n\nexport type MutationIssueCode =\n | 'invalid-address'\n | 'invalid-value'\n | 'invalid-key'\n | 'invalid-changes'\n | 'baseline-mismatch'\n | 'required-field'\n | 'invalid-anchor'\n | 'duplicate-entity'\n | 'missing-entity'\n | 'invalid-collection'\n | 'invalid-list-keys'\n | 'invalid-list-key'\n | 'duplicate-list-item'\n | 'missing-list-item'\n | 'invalid-tree'\n | 'duplicate-tree-node'\n | 'missing-tree-parent'\n | 'invalid-tree-index'\n | 'missing-tree-node'\n | 'tree-cycle';\nexport type MutationIssue = {\n readonly source: 'mutation';\n readonly code: MutationIssueCode;\n readonly address: DocumentAddress;\n readonly message: string;\n};\nexport const at = (\n address: DocumentAddress,\n code: MutationIssueCode,\n message: string\n): MutationIssue =>\n Object.freeze({ source: 'mutation', code, address: Object.freeze([...address]), message });\nexport class MutationRejected extends Error {\n constructor(readonly issue: MutationIssue) {\n super(issue.message);\n }\n}\nexport const fail = (address: DocumentAddress, code: MutationIssueCode, message: string): never => {\n throw new MutationRejected(at(address, code, message));\n};\n\nexport const invalidValue = (issue: ParseIssue, address = issue.address): never =>\n fail(address, issue.code === 'missing-validator' ? 'invalid-value' : issue.code, issue.message);\n"],"mappings":"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"}
|
package/dist/local-sync.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_issue = require("./issue-
|
|
3
|
-
const require_driver = require("./driver-
|
|
2
|
+
const require_issue = require("./issue-DjK1xp5K.cjs");
|
|
3
|
+
const require_driver = require("./driver-Djr3BVvo.cjs");
|
|
4
4
|
//#region core/src/local-sync/contract.ts
|
|
5
5
|
var LocalSyncUnavailableError = class extends Error {
|
|
6
6
|
constructor(capability) {
|
package/dist/local-sync.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Z as ObjectNode, l as DocumentRuntime, v as Readable } from "./contract-
|
|
1
|
+
import { Z as ObjectNode, l as DocumentRuntime, v as Readable } from "./contract-CdmDHRUq.cjs";
|
|
2
2
|
|
|
3
3
|
//#region core/src/local-sync/json.d.ts
|
|
4
4
|
type JsonPrimitive = null | boolean | number | string;
|
package/dist/local-sync.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Z as ObjectNode, l as DocumentRuntime, v as Readable } from "./contract-
|
|
1
|
+
import { Z as ObjectNode, l as DocumentRuntime, v as Readable } from "./contract-KG5XnQZt.js";
|
|
2
2
|
|
|
3
3
|
//#region core/src/local-sync/json.d.ts
|
|
4
4
|
type JsonPrimitive = null | boolean | number | string;
|
package/dist/local-sync.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { T as isRecord, w as isPlainObject } from "./issue-
|
|
2
|
-
import { a as changeCount, i as installRuntimeWriteDriver, o as decodeChanges } from "./driver-
|
|
1
|
+
import { T as isRecord, w as isPlainObject } from "./issue-W0hT8u8D.js";
|
|
2
|
+
import { a as changeCount, i as installRuntimeWriteDriver, o as decodeChanges } from "./driver-CLYJOGDQ.js";
|
|
3
3
|
//#region core/src/local-sync/contract.ts
|
|
4
4
|
var LocalSyncUnavailableError = class extends Error {
|
|
5
5
|
constructor(capability) {
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { i as AddressIndex } from "./issue-
|
|
2
|
-
import { n as createAccess } from "./scope-d-L87NeC.js";
|
|
1
|
+
import { i as AddressIndex } from "./issue-W0hT8u8D.js";
|
|
3
2
|
//#region core/src/impact-target.ts
|
|
4
3
|
const address = (target) => "at" in target ? target.at : target.address;
|
|
5
4
|
const id = (target) => target.kind === "collection" && "id" in target ? target.id : void 0;
|
|
@@ -56,58 +55,6 @@ var SubscriptionIndex = class {
|
|
|
56
55
|
}
|
|
57
56
|
};
|
|
58
57
|
//#endregion
|
|
59
|
-
//#region core/src/runtime/contract.ts
|
|
60
|
-
var DocumentReentrancyError = class extends Error {
|
|
61
|
-
constructor() {
|
|
62
|
-
super("Document writes cannot be re-entered during an update or notification.");
|
|
63
|
-
this.name = "DocumentReentrancyError";
|
|
64
|
-
}
|
|
65
|
-
};
|
|
66
|
-
var DocumentDisposedError = class extends Error {
|
|
67
|
-
constructor() {
|
|
68
|
-
super("Doxum runtime has been disposed.");
|
|
69
|
-
this.name = "DocumentDisposedError";
|
|
70
|
-
}
|
|
71
|
-
};
|
|
72
|
-
var TransactionRejected = class extends Error {
|
|
73
|
-
issues;
|
|
74
|
-
constructor(input) {
|
|
75
|
-
super("Document update rejected.");
|
|
76
|
-
this.name = "TransactionRejected";
|
|
77
|
-
const issues = Array.isArray(input) ? input : [input];
|
|
78
|
-
this.issues = Object.freeze(issues.map((issue) => Object.freeze({
|
|
79
|
-
code: issue.code,
|
|
80
|
-
message: issue.message,
|
|
81
|
-
source: "application",
|
|
82
|
-
...issue.address === void 0 ? {} : { address: Object.freeze([...issue.address]) }
|
|
83
|
-
})));
|
|
84
|
-
}
|
|
85
|
-
};
|
|
86
|
-
//#endregion
|
|
87
|
-
//#region core/src/runtime/access.ts
|
|
88
|
-
const states = /* @__PURE__ */ new WeakMap();
|
|
89
|
-
const bindRuntimeAccess = (runtime, state) => {
|
|
90
|
-
states.set(runtime, state);
|
|
91
|
-
};
|
|
92
|
-
const accessOf = (runtime) => {
|
|
93
|
-
const state = states.get(runtime);
|
|
94
|
-
if (!state) throw new Error("Unknown Doxum runtime.");
|
|
95
|
-
return state;
|
|
96
|
-
};
|
|
97
|
-
const readWith = (runtime, run, dependencies) => {
|
|
98
|
-
const state = accessOf(runtime);
|
|
99
|
-
if (state.disposed) throw new DocumentDisposedError();
|
|
100
|
-
state.projectionLocks = (state.projectionLocks ?? 0) + 1;
|
|
101
|
-
try {
|
|
102
|
-
return run(createAccess({
|
|
103
|
-
state,
|
|
104
|
-
dependencies
|
|
105
|
-
}));
|
|
106
|
-
} finally {
|
|
107
|
-
state.projectionLocks--;
|
|
108
|
-
}
|
|
109
|
-
};
|
|
110
|
-
//#endregion
|
|
111
58
|
//#region core/src/runtime/notification.ts
|
|
112
59
|
const notifications = /* @__PURE__ */ new WeakMap();
|
|
113
60
|
const readableOwners = /* @__PURE__ */ new WeakMap();
|
|
@@ -280,6 +227,6 @@ const disposeNotification = (notification) => {
|
|
|
280
227
|
if (errors.length) throw new AggregateError(errors, "Projection disposal notification failed.");
|
|
281
228
|
};
|
|
282
229
|
//#endregion
|
|
283
|
-
export {
|
|
230
|
+
export { documentReadableOwner as a, subscribeDependencies as c, affected as d, belongs as f, disposeNotification as i, subscribeRoot as l, bindDocumentReadable as n, notify as o, same as p, createNotification as r, shareNotification as s, attachProjection as t, subscribeTargets as u };
|
|
284
231
|
|
|
285
|
-
//# sourceMappingURL=notification-
|
|
232
|
+
//# sourceMappingURL=notification-Bkjau6B6.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notification-Bkjau6B6.js","names":["target.SubscriptionIndex"],"sources":["../core/src/impact-target.ts","../core/src/runtime/notification.ts"],"sourcesContent":["import type { DocumentAddress, ObjectNode, ImpactTarget } from './schema';\nimport type { ChangeSet } from './changes';\nimport { AddressIndex } from './address';\n\nexport const address = (target: ImpactTarget<unknown>): DocumentAddress =>\n 'at' in target ? target.at : target.address;\n\nexport const id = (target: ImpactTarget<unknown>): string | undefined =>\n target.kind === 'collection' && 'id' in target ? target.id : undefined;\n\nexport const belongs = (target: ImpactTarget<unknown>, schema: ObjectNode): boolean =>\n !('schema' in target) || target.schema === schema;\n\nexport const same = (left: ImpactTarget<unknown>, right: ImpactTarget<unknown>): boolean => {\n if (left.kind !== right.kind) return false;\n if ('schema' in left && 'schema' in right && left.schema !== right.schema) return false;\n const leftAddress = address(left);\n const rightAddress = address(right);\n if (leftAddress.length !== rightAddress.length) return false;\n for (let index = 0; index < leftAddress.length; index += 1)\n if (leftAddress[index] !== rightAddress[index]) return false;\n return left.kind !== 'collection' || id(left) === id(right);\n};\n\nexport const indexedAddress = (target: ImpactTarget<unknown>): DocumentAddress => {\n const key = id(target);\n return key === undefined ? address(target) : [...address(target), key];\n};\n\nexport const affected = (\n target: ImpactTarget,\n values: AddressIndex<true>,\n orders: AddressIndex<true>\n): boolean => {\n const at = indexedAddress(target);\n return id(target) !== undefined\n ? values.hasAncestor(at)\n : values.overlaps(at) || orders.hasDescendant(at);\n};\n\n/** Targets are classified once; commit matching never builds a reverse impact index. */\nexport class SubscriptionIndex<T> {\n private readonly ordinary = new AddressIndex<T>();\n private readonly membership = new AddressIndex<T>();\n constructor(private readonly schema: ObjectNode) {}\n add(target: ImpactTarget, value: T): void {\n if (belongs(target, this.schema))\n (id(target) === undefined ? this.ordinary : this.membership).add(\n indexedAddress(target),\n value\n );\n }\n delete(target: ImpactTarget, value: T): void {\n if (belongs(target, this.schema))\n (id(target) === undefined ? this.ordinary : this.membership).delete(\n indexedAddress(target),\n value\n );\n }\n collect(changes: ChangeSet, visit: (value: T) => void): void {\n const values = this.ordinary.query(visit);\n const members = this.membership.query(visit, 'descendants');\n const orders = this.ordinary.query(visit, 'ancestors');\n for (const change of changes.changes) {\n if (change.kind === 'reset') {\n values([]);\n members([]);\n } else if (change.kind === 'members') {\n values(change.at, change.members);\n members(change.at, change.members);\n if (change.order) orders(change.at);\n } else {\n values(change.at);\n members(change.at);\n }\n }\n }\n clear(): void {\n this.ordinary.clear();\n this.membership.clear();\n }\n}\n","import type { ObjectNode, ImpactTarget } from '../schema';\nimport type {\n CommitListener,\n DocumentCommit,\n DocumentReadable,\n DocumentRuntime,\n Unsubscribe,\n ObserverError,\n} from './contract';\nimport * as target from '../impact-target';\n\nexport type ProjectionAttachment<TSchema extends ObjectNode> = {\n capture(commit: DocumentCommit<TSchema>): void;\n settle(): void;\n flush(): readonly ObserverError[];\n dispose(): void;\n};\ntype ProcessorEntry<TSchema extends ObjectNode> = {\n readonly processor: ProjectionAttachment<TSchema>;\n active: boolean;\n};\ntype RootEntry<TSchema extends ObjectNode> = {\n readonly listener: CommitListener<TSchema>;\n active: boolean;\n};\ntype FilteredEntry<TSchema extends ObjectNode> = {\n readonly targets: readonly ImpactTarget<unknown>[];\n readonly listener: CommitListener<TSchema>;\n active: boolean;\n};\nexport type RuntimeNotification<TSchema extends ObjectNode> = {\n readonly root: Set<RootEntry<TSchema>>;\n readonly filtered: Set<FilteredEntry<TSchema>>;\n readonly index: target.SubscriptionIndex<FilteredEntry<TSchema>>;\n readonly cleanups: Set<() => void>;\n readonly processors: ProcessorEntry<TSchema>[];\n readonly candidates: Set<FilteredEntry<TSchema>>;\n readonly rootSnapshot: RootEntry<TSchema>[];\n notifying: boolean;\n};\n\nconst notifications = new WeakMap<object, RuntimeNotification<ObjectNode>>();\nconst readableOwners = new WeakMap<object, DocumentReadable<ObjectNode>>();\n\nexport const bindDocumentReadable = (\n readable: object,\n runtime: DocumentReadable<ObjectNode>\n): void => {\n readableOwners.set(readable, runtime);\n};\nexport const documentReadableOwner = (readable: object): DocumentReadable<ObjectNode> | undefined =>\n readableOwners.get(readable);\n\nexport const createNotification = <TSchema extends ObjectNode>(\n runtime: DocumentRuntime<TSchema>\n): RuntimeNotification<TSchema> => {\n const notification: RuntimeNotification<TSchema> = {\n root: new Set(),\n filtered: new Set(),\n index: new target.SubscriptionIndex(runtime.schema),\n cleanups: new Set(),\n processors: [],\n candidates: new Set(),\n rootSnapshot: [],\n notifying: false,\n };\n notifications.set(runtime as object, notification as RuntimeNotification<ObjectNode>);\n return notification;\n};\n\nconst notificationOf = <TSchema extends ObjectNode>(\n runtime: DocumentReadable<TSchema>\n): RuntimeNotification<TSchema> => {\n const value = notifications.get(runtime as object);\n if (!value) throw new Error('Unknown Doxum runtime.');\n return value as RuntimeNotification<TSchema>;\n};\n\nexport const shareNotification = <TSchema extends ObjectNode>(\n source: DocumentRuntime<TSchema>,\n target: DocumentReadable<TSchema>\n): void => {\n notifications.set(target as object, notificationOf(source) as RuntimeNotification<ObjectNode>);\n};\n\nexport const attachProjection = <TSchema extends ObjectNode>(\n runtime: DocumentReadable<TSchema>,\n processor: ProjectionAttachment<TSchema>\n): Unsubscribe => {\n const notification = notificationOf(runtime);\n const entry: ProcessorEntry<TSchema> = { processor, active: true };\n notification.processors.push(entry);\n return () => {\n if (!entry.active) return;\n entry.active = false;\n if (!notification.notifying) {\n const index = notification.processors.indexOf(entry);\n if (index >= 0) notification.processors.splice(index, 1);\n }\n };\n};\n\nexport const subscribeRoot = <TSchema extends ObjectNode>(\n notification: RuntimeNotification<TSchema>,\n listener: CommitListener<TSchema>\n): Unsubscribe => {\n const entry: RootEntry<TSchema> = { listener, active: true };\n notification.root.add(entry);\n return () => {\n entry.active = false;\n if (!notification.notifying) notification.root.delete(entry);\n else\n notification.cleanups.add(() => {\n notification.root.delete(entry);\n });\n };\n};\n\nexport const subscribeTargets = <TSchema extends ObjectNode>(\n notification: RuntimeNotification<TSchema>,\n targets: readonly ImpactTarget<unknown>[],\n listener: CommitListener<TSchema>\n): Unsubscribe => {\n const entry: FilteredEntry<TSchema> = {\n targets: Object.freeze(targets.slice()),\n listener,\n active: true,\n };\n notification.filtered.add(entry);\n entry.targets.forEach(value => notification.index.add(value, entry));\n const remove = () => {\n notification.filtered.delete(entry);\n entry.targets.forEach(value => notification.index.delete(value, entry));\n };\n return () => {\n if (!entry.active) return;\n entry.active = false;\n if (notification.notifying) notification.cleanups.add(remove);\n else remove();\n };\n};\n\nexport const notify = <TSchema extends ObjectNode>(\n notification: RuntimeNotification<TSchema>,\n commit: DocumentCommit<TSchema>,\n afterSettle?: () => readonly ObserverError[]\n): readonly ObserverError[] => {\n notification.notifying = true;\n const errors: ObserverError[] = [];\n const call = (listener: CommitListener<TSchema>): void => {\n try {\n listener(commit);\n } catch (error) {\n errors.push(Object.freeze({ phase: 'listener', error }));\n }\n };\n try {\n const processorCount = notification.processors.length;\n for (let index = 0; index < processorCount; index += 1) {\n const entry = notification.processors[index];\n if (!entry?.active) continue;\n try {\n entry.processor.capture(commit);\n } catch (error) {\n errors.push(Object.freeze({ phase: 'processor', error }));\n }\n }\n for (let index = 0; index < processorCount; index += 1) {\n const entry = notification.processors[index];\n if (!entry?.active) continue;\n try {\n entry.processor.settle();\n } catch (error) {\n errors.push(Object.freeze({ phase: 'processor', error }));\n }\n }\n for (let index = 0; index < processorCount; index += 1) {\n const entry = notification.processors[index];\n if (!entry?.active) continue;\n try {\n errors.push(...entry.processor.flush());\n } catch (error) {\n errors.push(Object.freeze({ phase: 'flush', error }));\n }\n }\n\n if (afterSettle) errors.push(...afterSettle());\n const candidates = notification.candidates;\n candidates.clear();\n if (notification.filtered.size)\n notification.index.collect(commit.changes, entry => candidates.add(entry));\n candidates.forEach(entry => {\n if (entry.active) call(entry.listener);\n });\n const rootSnapshot = notification.rootSnapshot;\n rootSnapshot.length = 0;\n notification.root.forEach(entry => rootSnapshot.push(entry));\n for (const entry of rootSnapshot) if (entry.active) call(entry.listener);\n } finally {\n notification.notifying = false;\n let writeIndex = 0;\n for (const entry of notification.processors)\n if (entry.active) notification.processors[writeIndex++] = entry;\n notification.processors.length = writeIndex;\n notification.cleanups.forEach(cleanup => cleanup());\n notification.cleanups.clear();\n }\n return Object.freeze(errors);\n};\n\nexport const subscribeDependencies = <S extends ObjectNode>(\n runtime: DocumentReadable<S>,\n targets: readonly ImpactTarget[],\n listener: CommitListener<S>\n): Unsubscribe => subscribeTargets(notificationOf(runtime), targets, listener);\n\nexport const disposeNotification = <TSchema extends ObjectNode>(\n notification: RuntimeNotification<TSchema>\n): void => {\n const attachments = notification.processors.slice();\n notification.root.clear();\n notification.filtered.clear();\n notification.index.clear();\n notification.cleanups.clear();\n notification.processors.length = 0;\n notification.candidates.clear();\n notification.rootSnapshot.length = 0;\n const errors: unknown[] = [];\n attachments.forEach(entry => {\n if (!entry.active) return;\n try {\n entry.processor.dispose();\n } catch (error) {\n errors.push(error);\n }\n });\n if (errors.length) throw new AggregateError(errors, 'Projection disposal notification failed.');\n};\n"],"mappings":"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"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
const require_issue = require("./issue-
|
|
2
|
-
const require_scope = require("./scope-Ezs-Y3TY.cjs");
|
|
1
|
+
const require_issue = require("./issue-DjK1xp5K.cjs");
|
|
3
2
|
//#region core/src/impact-target.ts
|
|
4
3
|
const address = (target) => "at" in target ? target.at : target.address;
|
|
5
4
|
const id = (target) => target.kind === "collection" && "id" in target ? target.id : void 0;
|
|
@@ -56,58 +55,6 @@ var SubscriptionIndex = class {
|
|
|
56
55
|
}
|
|
57
56
|
};
|
|
58
57
|
//#endregion
|
|
59
|
-
//#region core/src/runtime/contract.ts
|
|
60
|
-
var DocumentReentrancyError = class extends Error {
|
|
61
|
-
constructor() {
|
|
62
|
-
super("Document writes cannot be re-entered during an update or notification.");
|
|
63
|
-
this.name = "DocumentReentrancyError";
|
|
64
|
-
}
|
|
65
|
-
};
|
|
66
|
-
var DocumentDisposedError = class extends Error {
|
|
67
|
-
constructor() {
|
|
68
|
-
super("Doxum runtime has been disposed.");
|
|
69
|
-
this.name = "DocumentDisposedError";
|
|
70
|
-
}
|
|
71
|
-
};
|
|
72
|
-
var TransactionRejected = class extends Error {
|
|
73
|
-
issues;
|
|
74
|
-
constructor(input) {
|
|
75
|
-
super("Document update rejected.");
|
|
76
|
-
this.name = "TransactionRejected";
|
|
77
|
-
const issues = Array.isArray(input) ? input : [input];
|
|
78
|
-
this.issues = Object.freeze(issues.map((issue) => Object.freeze({
|
|
79
|
-
code: issue.code,
|
|
80
|
-
message: issue.message,
|
|
81
|
-
source: "application",
|
|
82
|
-
...issue.address === void 0 ? {} : { address: Object.freeze([...issue.address]) }
|
|
83
|
-
})));
|
|
84
|
-
}
|
|
85
|
-
};
|
|
86
|
-
//#endregion
|
|
87
|
-
//#region core/src/runtime/access.ts
|
|
88
|
-
const states = /* @__PURE__ */ new WeakMap();
|
|
89
|
-
const bindRuntimeAccess = (runtime, state) => {
|
|
90
|
-
states.set(runtime, state);
|
|
91
|
-
};
|
|
92
|
-
const accessOf = (runtime) => {
|
|
93
|
-
const state = states.get(runtime);
|
|
94
|
-
if (!state) throw new Error("Unknown Doxum runtime.");
|
|
95
|
-
return state;
|
|
96
|
-
};
|
|
97
|
-
const readWith = (runtime, run, dependencies) => {
|
|
98
|
-
const state = accessOf(runtime);
|
|
99
|
-
if (state.disposed) throw new DocumentDisposedError();
|
|
100
|
-
state.projectionLocks = (state.projectionLocks ?? 0) + 1;
|
|
101
|
-
try {
|
|
102
|
-
return run(require_scope.createAccess({
|
|
103
|
-
state,
|
|
104
|
-
dependencies
|
|
105
|
-
}));
|
|
106
|
-
} finally {
|
|
107
|
-
state.projectionLocks--;
|
|
108
|
-
}
|
|
109
|
-
};
|
|
110
|
-
//#endregion
|
|
111
58
|
//#region core/src/runtime/notification.ts
|
|
112
59
|
const notifications = /* @__PURE__ */ new WeakMap();
|
|
113
60
|
const readableOwners = /* @__PURE__ */ new WeakMap();
|
|
@@ -280,30 +227,6 @@ const disposeNotification = (notification) => {
|
|
|
280
227
|
if (errors.length) throw new AggregateError(errors, "Projection disposal notification failed.");
|
|
281
228
|
};
|
|
282
229
|
//#endregion
|
|
283
|
-
Object.defineProperty(exports, "DocumentDisposedError", {
|
|
284
|
-
enumerable: true,
|
|
285
|
-
get: function() {
|
|
286
|
-
return DocumentDisposedError;
|
|
287
|
-
}
|
|
288
|
-
});
|
|
289
|
-
Object.defineProperty(exports, "DocumentReentrancyError", {
|
|
290
|
-
enumerable: true,
|
|
291
|
-
get: function() {
|
|
292
|
-
return DocumentReentrancyError;
|
|
293
|
-
}
|
|
294
|
-
});
|
|
295
|
-
Object.defineProperty(exports, "TransactionRejected", {
|
|
296
|
-
enumerable: true,
|
|
297
|
-
get: function() {
|
|
298
|
-
return TransactionRejected;
|
|
299
|
-
}
|
|
300
|
-
});
|
|
301
|
-
Object.defineProperty(exports, "accessOf", {
|
|
302
|
-
enumerable: true,
|
|
303
|
-
get: function() {
|
|
304
|
-
return accessOf;
|
|
305
|
-
}
|
|
306
|
-
});
|
|
307
230
|
Object.defineProperty(exports, "affected", {
|
|
308
231
|
enumerable: true,
|
|
309
232
|
get: function() {
|
|
@@ -328,12 +251,6 @@ Object.defineProperty(exports, "bindDocumentReadable", {
|
|
|
328
251
|
return bindDocumentReadable;
|
|
329
252
|
}
|
|
330
253
|
});
|
|
331
|
-
Object.defineProperty(exports, "bindRuntimeAccess", {
|
|
332
|
-
enumerable: true,
|
|
333
|
-
get: function() {
|
|
334
|
-
return bindRuntimeAccess;
|
|
335
|
-
}
|
|
336
|
-
});
|
|
337
254
|
Object.defineProperty(exports, "createNotification", {
|
|
338
255
|
enumerable: true,
|
|
339
256
|
get: function() {
|
|
@@ -358,12 +275,6 @@ Object.defineProperty(exports, "notify", {
|
|
|
358
275
|
return notify;
|
|
359
276
|
}
|
|
360
277
|
});
|
|
361
|
-
Object.defineProperty(exports, "readWith", {
|
|
362
|
-
enumerable: true,
|
|
363
|
-
get: function() {
|
|
364
|
-
return readWith;
|
|
365
|
-
}
|
|
366
|
-
});
|
|
367
278
|
Object.defineProperty(exports, "same", {
|
|
368
279
|
enumerable: true,
|
|
369
280
|
get: function() {
|
|
@@ -395,4 +306,4 @@ Object.defineProperty(exports, "subscribeTargets", {
|
|
|
395
306
|
}
|
|
396
307
|
});
|
|
397
308
|
|
|
398
|
-
//# sourceMappingURL=notification-
|
|
309
|
+
//# sourceMappingURL=notification-DJfouMEb.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notification-DJfouMEb.cjs","names":["AddressIndex","target.SubscriptionIndex"],"sources":["../core/src/impact-target.ts","../core/src/runtime/notification.ts"],"sourcesContent":["import type { DocumentAddress, ObjectNode, ImpactTarget } from './schema';\nimport type { ChangeSet } from './changes';\nimport { AddressIndex } from './address';\n\nexport const address = (target: ImpactTarget<unknown>): DocumentAddress =>\n 'at' in target ? target.at : target.address;\n\nexport const id = (target: ImpactTarget<unknown>): string | undefined =>\n target.kind === 'collection' && 'id' in target ? target.id : undefined;\n\nexport const belongs = (target: ImpactTarget<unknown>, schema: ObjectNode): boolean =>\n !('schema' in target) || target.schema === schema;\n\nexport const same = (left: ImpactTarget<unknown>, right: ImpactTarget<unknown>): boolean => {\n if (left.kind !== right.kind) return false;\n if ('schema' in left && 'schema' in right && left.schema !== right.schema) return false;\n const leftAddress = address(left);\n const rightAddress = address(right);\n if (leftAddress.length !== rightAddress.length) return false;\n for (let index = 0; index < leftAddress.length; index += 1)\n if (leftAddress[index] !== rightAddress[index]) return false;\n return left.kind !== 'collection' || id(left) === id(right);\n};\n\nexport const indexedAddress = (target: ImpactTarget<unknown>): DocumentAddress => {\n const key = id(target);\n return key === undefined ? address(target) : [...address(target), key];\n};\n\nexport const affected = (\n target: ImpactTarget,\n values: AddressIndex<true>,\n orders: AddressIndex<true>\n): boolean => {\n const at = indexedAddress(target);\n return id(target) !== undefined\n ? values.hasAncestor(at)\n : values.overlaps(at) || orders.hasDescendant(at);\n};\n\n/** Targets are classified once; commit matching never builds a reverse impact index. */\nexport class SubscriptionIndex<T> {\n private readonly ordinary = new AddressIndex<T>();\n private readonly membership = new AddressIndex<T>();\n constructor(private readonly schema: ObjectNode) {}\n add(target: ImpactTarget, value: T): void {\n if (belongs(target, this.schema))\n (id(target) === undefined ? this.ordinary : this.membership).add(\n indexedAddress(target),\n value\n );\n }\n delete(target: ImpactTarget, value: T): void {\n if (belongs(target, this.schema))\n (id(target) === undefined ? this.ordinary : this.membership).delete(\n indexedAddress(target),\n value\n );\n }\n collect(changes: ChangeSet, visit: (value: T) => void): void {\n const values = this.ordinary.query(visit);\n const members = this.membership.query(visit, 'descendants');\n const orders = this.ordinary.query(visit, 'ancestors');\n for (const change of changes.changes) {\n if (change.kind === 'reset') {\n values([]);\n members([]);\n } else if (change.kind === 'members') {\n values(change.at, change.members);\n members(change.at, change.members);\n if (change.order) orders(change.at);\n } else {\n values(change.at);\n members(change.at);\n }\n }\n }\n clear(): void {\n this.ordinary.clear();\n this.membership.clear();\n }\n}\n","import type { ObjectNode, ImpactTarget } from '../schema';\nimport type {\n CommitListener,\n DocumentCommit,\n DocumentReadable,\n DocumentRuntime,\n Unsubscribe,\n ObserverError,\n} from './contract';\nimport * as target from '../impact-target';\n\nexport type ProjectionAttachment<TSchema extends ObjectNode> = {\n capture(commit: DocumentCommit<TSchema>): void;\n settle(): void;\n flush(): readonly ObserverError[];\n dispose(): void;\n};\ntype ProcessorEntry<TSchema extends ObjectNode> = {\n readonly processor: ProjectionAttachment<TSchema>;\n active: boolean;\n};\ntype RootEntry<TSchema extends ObjectNode> = {\n readonly listener: CommitListener<TSchema>;\n active: boolean;\n};\ntype FilteredEntry<TSchema extends ObjectNode> = {\n readonly targets: readonly ImpactTarget<unknown>[];\n readonly listener: CommitListener<TSchema>;\n active: boolean;\n};\nexport type RuntimeNotification<TSchema extends ObjectNode> = {\n readonly root: Set<RootEntry<TSchema>>;\n readonly filtered: Set<FilteredEntry<TSchema>>;\n readonly index: target.SubscriptionIndex<FilteredEntry<TSchema>>;\n readonly cleanups: Set<() => void>;\n readonly processors: ProcessorEntry<TSchema>[];\n readonly candidates: Set<FilteredEntry<TSchema>>;\n readonly rootSnapshot: RootEntry<TSchema>[];\n notifying: boolean;\n};\n\nconst notifications = new WeakMap<object, RuntimeNotification<ObjectNode>>();\nconst readableOwners = new WeakMap<object, DocumentReadable<ObjectNode>>();\n\nexport const bindDocumentReadable = (\n readable: object,\n runtime: DocumentReadable<ObjectNode>\n): void => {\n readableOwners.set(readable, runtime);\n};\nexport const documentReadableOwner = (readable: object): DocumentReadable<ObjectNode> | undefined =>\n readableOwners.get(readable);\n\nexport const createNotification = <TSchema extends ObjectNode>(\n runtime: DocumentRuntime<TSchema>\n): RuntimeNotification<TSchema> => {\n const notification: RuntimeNotification<TSchema> = {\n root: new Set(),\n filtered: new Set(),\n index: new target.SubscriptionIndex(runtime.schema),\n cleanups: new Set(),\n processors: [],\n candidates: new Set(),\n rootSnapshot: [],\n notifying: false,\n };\n notifications.set(runtime as object, notification as RuntimeNotification<ObjectNode>);\n return notification;\n};\n\nconst notificationOf = <TSchema extends ObjectNode>(\n runtime: DocumentReadable<TSchema>\n): RuntimeNotification<TSchema> => {\n const value = notifications.get(runtime as object);\n if (!value) throw new Error('Unknown Doxum runtime.');\n return value as RuntimeNotification<TSchema>;\n};\n\nexport const shareNotification = <TSchema extends ObjectNode>(\n source: DocumentRuntime<TSchema>,\n target: DocumentReadable<TSchema>\n): void => {\n notifications.set(target as object, notificationOf(source) as RuntimeNotification<ObjectNode>);\n};\n\nexport const attachProjection = <TSchema extends ObjectNode>(\n runtime: DocumentReadable<TSchema>,\n processor: ProjectionAttachment<TSchema>\n): Unsubscribe => {\n const notification = notificationOf(runtime);\n const entry: ProcessorEntry<TSchema> = { processor, active: true };\n notification.processors.push(entry);\n return () => {\n if (!entry.active) return;\n entry.active = false;\n if (!notification.notifying) {\n const index = notification.processors.indexOf(entry);\n if (index >= 0) notification.processors.splice(index, 1);\n }\n };\n};\n\nexport const subscribeRoot = <TSchema extends ObjectNode>(\n notification: RuntimeNotification<TSchema>,\n listener: CommitListener<TSchema>\n): Unsubscribe => {\n const entry: RootEntry<TSchema> = { listener, active: true };\n notification.root.add(entry);\n return () => {\n entry.active = false;\n if (!notification.notifying) notification.root.delete(entry);\n else\n notification.cleanups.add(() => {\n notification.root.delete(entry);\n });\n };\n};\n\nexport const subscribeTargets = <TSchema extends ObjectNode>(\n notification: RuntimeNotification<TSchema>,\n targets: readonly ImpactTarget<unknown>[],\n listener: CommitListener<TSchema>\n): Unsubscribe => {\n const entry: FilteredEntry<TSchema> = {\n targets: Object.freeze(targets.slice()),\n listener,\n active: true,\n };\n notification.filtered.add(entry);\n entry.targets.forEach(value => notification.index.add(value, entry));\n const remove = () => {\n notification.filtered.delete(entry);\n entry.targets.forEach(value => notification.index.delete(value, entry));\n };\n return () => {\n if (!entry.active) return;\n entry.active = false;\n if (notification.notifying) notification.cleanups.add(remove);\n else remove();\n };\n};\n\nexport const notify = <TSchema extends ObjectNode>(\n notification: RuntimeNotification<TSchema>,\n commit: DocumentCommit<TSchema>,\n afterSettle?: () => readonly ObserverError[]\n): readonly ObserverError[] => {\n notification.notifying = true;\n const errors: ObserverError[] = [];\n const call = (listener: CommitListener<TSchema>): void => {\n try {\n listener(commit);\n } catch (error) {\n errors.push(Object.freeze({ phase: 'listener', error }));\n }\n };\n try {\n const processorCount = notification.processors.length;\n for (let index = 0; index < processorCount; index += 1) {\n const entry = notification.processors[index];\n if (!entry?.active) continue;\n try {\n entry.processor.capture(commit);\n } catch (error) {\n errors.push(Object.freeze({ phase: 'processor', error }));\n }\n }\n for (let index = 0; index < processorCount; index += 1) {\n const entry = notification.processors[index];\n if (!entry?.active) continue;\n try {\n entry.processor.settle();\n } catch (error) {\n errors.push(Object.freeze({ phase: 'processor', error }));\n }\n }\n for (let index = 0; index < processorCount; index += 1) {\n const entry = notification.processors[index];\n if (!entry?.active) continue;\n try {\n errors.push(...entry.processor.flush());\n } catch (error) {\n errors.push(Object.freeze({ phase: 'flush', error }));\n }\n }\n\n if (afterSettle) errors.push(...afterSettle());\n const candidates = notification.candidates;\n candidates.clear();\n if (notification.filtered.size)\n notification.index.collect(commit.changes, entry => candidates.add(entry));\n candidates.forEach(entry => {\n if (entry.active) call(entry.listener);\n });\n const rootSnapshot = notification.rootSnapshot;\n rootSnapshot.length = 0;\n notification.root.forEach(entry => rootSnapshot.push(entry));\n for (const entry of rootSnapshot) if (entry.active) call(entry.listener);\n } finally {\n notification.notifying = false;\n let writeIndex = 0;\n for (const entry of notification.processors)\n if (entry.active) notification.processors[writeIndex++] = entry;\n notification.processors.length = writeIndex;\n notification.cleanups.forEach(cleanup => cleanup());\n notification.cleanups.clear();\n }\n return Object.freeze(errors);\n};\n\nexport const subscribeDependencies = <S extends ObjectNode>(\n runtime: DocumentReadable<S>,\n targets: readonly ImpactTarget[],\n listener: CommitListener<S>\n): Unsubscribe => subscribeTargets(notificationOf(runtime), targets, listener);\n\nexport const disposeNotification = <TSchema extends ObjectNode>(\n notification: RuntimeNotification<TSchema>\n): void => {\n const attachments = notification.processors.slice();\n notification.root.clear();\n notification.filtered.clear();\n notification.index.clear();\n notification.cleanups.clear();\n notification.processors.length = 0;\n notification.candidates.clear();\n notification.rootSnapshot.length = 0;\n const errors: unknown[] = [];\n attachments.forEach(entry => {\n if (!entry.active) return;\n try {\n entry.processor.dispose();\n } catch (error) {\n errors.push(error);\n }\n });\n if (errors.length) throw new AggregateError(errors, 'Projection disposal notification failed.');\n};\n"],"mappings":"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"}
|
package/dist/react.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_notification = require("./notification-
|
|
3
|
-
const require_integration = require("./integration-
|
|
2
|
+
const require_notification = require("./notification-DJfouMEb.cjs");
|
|
3
|
+
const require_integration = require("./integration-Z6MsfFI7.cjs");
|
|
4
4
|
let react = require("react");
|
|
5
5
|
//#region react/src/hooks.ts
|
|
6
6
|
const ProjectionContext = (0, react.createContext)(void 0);
|
package/dist/react.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { c as subscribeDependencies,
|
|
2
|
-
import { t as track } from "./integration-
|
|
1
|
+
import { c as subscribeDependencies, p as same } from "./notification-Bkjau6B6.js";
|
|
2
|
+
import { t as track } from "./integration-C4Isp8lJ.js";
|
|
3
3
|
import { createContext, useCallback, useContext, useMemo, useRef, useSyncExternalStore } from "react";
|
|
4
4
|
//#region react/src/hooks.ts
|
|
5
5
|
const ProjectionContext = createContext(void 0);
|
package/package.json
CHANGED
|
@@ -22,6 +22,8 @@ Before runtime changes read [invariants](references/invariants.en.md) or
|
|
|
22
22
|
- Maps use get/has/ids/put/remove/replace; table/list/tree use overloaded replace
|
|
23
23
|
for member and whole-container replacement. Use replace(parent, key, value) for
|
|
24
24
|
object or variant members whose Draft type contains collection tools.
|
|
25
|
+
- Ordered table/list Drafts use move(key | readonly key[], anchor?) for relative
|
|
26
|
+
movement and reorder(keys) for an exact full-membership permutation.
|
|
25
27
|
- Expected business failure throws TransactionRejected. Other exceptions roll back
|
|
26
28
|
and rethrow unchanged. Callback returns carry business values and notices.
|
|
27
29
|
- Commits contain final reversible ChangeSets. History and impact share those facts.
|
|
@@ -29,7 +31,8 @@ Before runtime changes read [invariants](references/invariants.en.md) or
|
|
|
29
31
|
kinds, optional before/after order in the same group, and a separate root reset.
|
|
30
32
|
Standalone order records and duplicate groups are invalid. Grouping preserves field-level impact.
|
|
31
33
|
- Paths belong in subscription, impact and collection source callbacks.
|
|
32
|
-
- Projection definitions are lazy; one ProjectionRuntime owns
|
|
34
|
+
- Projection definitions are lazy; one ProjectionRuntime owns all materialized
|
|
35
|
+
producers, outputs, scheduling and source attachments for that Runtime.
|
|
33
36
|
Use tuple `derive` for pure values. Advanced `incremental` processors declare every
|
|
34
37
|
source, own any forward/reverse dependency indexes, derive from final batched source
|
|
35
38
|
state, and recover from resets internally. Core projections never track reads
|
|
@@ -52,8 +52,8 @@ plain replacement of object or variant members that contain collection data.
|
|
|
52
52
|
| Definition | Data | Draft methods |
|
|
53
53
|
| -------------------------------- | ------------- | --------------------------------------------------------- |
|
|
54
54
|
| map(valueSchema, { key }?) | record | get/has/ids/put/remove/replace |
|
|
55
|
-
| table(objectOrVariant, { key }?) | ids/byId | get/has/ids/create/remove/move/replace
|
|
56
|
-
| list(field, { keyOf }) | array | get/has/ids/insert/remove/move/replace
|
|
55
|
+
| table(objectOrVariant, { key }?) | ids/byId | get/has/ids/create/remove/move/reorder/replace |
|
|
56
|
+
| list(field, { keyOf }) | array | get/has/ids/insert/remove/move/reorder/replace |
|
|
57
57
|
| tree(field) | rootId?/nodes | get/has/rootId/parent/children/insert/remove/move/replace |
|
|
58
58
|
|
|
59
59
|
Read scopes expose only read methods. Map supports field/object/variant values;
|
|
@@ -63,6 +63,9 @@ tree payload. `replace(value)` replaces a whole collection. List member replacem
|
|
|
63
63
|
retains the addressed key. Simple arrays and strokes can be one
|
|
64
64
|
atomic field. Optional supports field/variant/map/list/tree. Absent differs from
|
|
65
65
|
present undefined. Variant tags are readonly; change branch by whole replacement.
|
|
66
|
+
For table/list, `move(key | readonly key[], anchor?)` preserves a moved selection's
|
|
67
|
+
current relative order and resolves the anchor after removal. `reorder(keys)` requires
|
|
68
|
+
an exact permutation of current membership and changes only order.
|
|
66
69
|
|
|
67
70
|
Pure synchronous functions and Standard Schema v1 validators receive original input.
|
|
68
71
|
They must not mutate it; successful output is ignored, with no copy or deep conversion
|
|
@@ -46,8 +46,8 @@ table/list/tree 的 replace 同时支持成员和整体替换。含集合数据
|
|
|
46
46
|
| 声明 | 数据 | Draft 方法 |
|
|
47
47
|
| -------------------------------- | ------------- | --------------------------------------------------------- |
|
|
48
48
|
| map(valueSchema, { key }?) | record | get/has/ids/put/remove/replace |
|
|
49
|
-
| table(objectOrVariant, { key }?) | ids/byId | get/has/ids/create/remove/move/replace
|
|
50
|
-
| list(field, { keyOf }) | 普通数组 | get/has/ids/insert/remove/move/replace
|
|
49
|
+
| table(objectOrVariant, { key }?) | ids/byId | get/has/ids/create/remove/move/reorder/replace |
|
|
50
|
+
| list(field, { keyOf }) | 普通数组 | get/has/ids/insert/remove/move/reorder/replace |
|
|
51
51
|
| tree(field) | rootId?/nodes | get/has/rootId/parent/children/insert/remove/move/replace |
|
|
52
52
|
|
|
53
53
|
Read 只暴露读取方法。map 支持 field/object/variant;put 是 upsert,remove 缺失键是 no-op。
|
|
@@ -55,6 +55,9 @@ table/list/tree 的 `replace(id, value)` 只替换已存在成员,保持 table
|
|
|
55
55
|
只改变 payload;`replace(value)` 替换整个集合。list 替换项必须保持寻址键。
|
|
56
56
|
简单数组与笔画可作为一个原子 field。optional 支持 field/variant/map/list/tree,
|
|
57
57
|
缺失与存在的 undefined 不同。variant tag 只读,通过整体替换切换分支。
|
|
58
|
+
table/list 的 `move(key | readonly key[], anchor?)` 会保持 moved selection 当前的相对顺序,
|
|
59
|
+
并在移除 selection 后解析 anchor;`reorder(keys)` 要求与当前 membership 完全一致的排列,
|
|
60
|
+
只改变顺序而不改变成员值。
|
|
58
61
|
|
|
59
62
|
校验器是纯同步函数或 Standard Schema v1,直接接收原始引用且不得修改它。
|
|
60
63
|
成功返回值被忽略,不复制输入,也不深度检查转换;数据转换在进入 Doxum 前完成。
|
|
@@ -22,6 +22,10 @@ and eventful external sources can also be observed at this boundary. External
|
|
|
22
22
|
sources use `kind: 'value'` or `kind: 'collection'`; the caller still uses only
|
|
23
23
|
`observe(source)`.
|
|
24
24
|
|
|
25
|
+
Schema maps, tables, and `list(field, { keyOf })` nodes are all keyed collection
|
|
26
|
+
paths. A list uses its schema `keyOf` identity and preserves document order in
|
|
27
|
+
iteration; array-valued fields remain scalar value observations.
|
|
28
|
+
|
|
25
29
|
External events are smaller than Runtime contexts. A value event carries the new
|
|
26
30
|
`value` and `revision`; a collection event carries a stable `previous` read,
|
|
27
31
|
`revision`, and an optional `impact` hint. The Runtime derives the exact
|
|
@@ -50,10 +54,11 @@ runtime.dispose();
|
|
|
50
54
|
atomic per callback, and a Runtime batch publishes one exact net
|
|
51
55
|
`CollectionChange`. A scope declares local inputs, derives, and incremental
|
|
52
56
|
processors through `scope.input`, `scope.derive`, and `scope.incremental`. They
|
|
53
|
-
depend directly on root projections in the same
|
|
54
|
-
releases local state and subscriptions without disposing its root
|
|
57
|
+
depend directly on root projections in the same Runtime. Disposing the scope
|
|
58
|
+
releases local producers, state and subscriptions without disposing its root
|
|
59
|
+
dependencies.
|
|
55
60
|
|
|
56
|
-
The Runtime exposes no
|
|
61
|
+
The Runtime exposes no scheduler/output internals, item handle, rebuild or release operation;
|
|
57
62
|
only a `Readable`'s own publication revision is public for store integrations.
|
|
58
63
|
Runtime materialization, keyed storage, recovery and disposal are one owner.
|
|
59
64
|
|
|
@@ -79,6 +84,8 @@ const render = incremental.group(
|
|
|
79
84
|
content: define.collection<string, Content>(),
|
|
80
85
|
},
|
|
81
86
|
labels: define.collection<string, Label>(),
|
|
87
|
+
chrome: define.value<Chrome>(),
|
|
88
|
+
revision: define.value<number>(),
|
|
82
89
|
}),
|
|
83
90
|
({ sources, outputs }) => {
|
|
84
91
|
for (const [id, task] of sources[0]) {
|
|
@@ -86,6 +93,8 @@ const render = incremental.group(
|
|
|
86
93
|
outputs.node.content.set(id, makeContent(task));
|
|
87
94
|
outputs.labels.set(id, makeLabel(task));
|
|
88
95
|
}
|
|
96
|
+
outputs.chrome.set(makeChrome(sources[0]));
|
|
97
|
+
outputs.revision.set(sources[0].size);
|
|
89
98
|
}
|
|
90
99
|
);
|
|
91
100
|
```
|
|
@@ -106,12 +115,17 @@ an explicit full-collection read.
|
|
|
106
115
|
`set`, `remove`, and `order`; the Runtime validates and seals them after
|
|
107
116
|
the synchronous callback, computes keyed transitions and publishes one immutable
|
|
108
117
|
map-like value. Reset or fault recovery is internal.
|
|
109
|
-
`incremental.group(...)` is the composition boundary for several named
|
|
110
|
-
outputs.
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
118
|
+
`incremental.group(...)` is the composition boundary for several named value and
|
|
119
|
+
keyed collection outputs. `define.value<T>(equality?)` creates a scalar leaf and
|
|
120
|
+
`define.collection<K, V>(equality?)` creates a keyed leaf. Its nested namespace is
|
|
121
|
+
static API organization, not another producer, runtime or scheduler concept. Every
|
|
122
|
+
leaf is an ordinary `Projection` pointing to one output of the same processor
|
|
123
|
+
producer; one processor execution seals and publishes all changed leaves atomically,
|
|
124
|
+
and downstream processors depend on those leaves directly.
|
|
125
|
+
Initial builds and rebuilds must set every value leaf; ordinary incremental runs
|
|
126
|
+
may leave a value leaf untouched to preserve its current value and revision.
|
|
127
|
+
Reading any leaf materializes that producer once, while scope disposal releases the
|
|
128
|
+
producer and its retained state once.
|
|
115
129
|
|
|
116
130
|
## React selector tracking
|
|
117
131
|
|