doxum 0.1.23 → 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.
- package/README.md +208 -102
- package/dist/advanced.cjs +237 -2
- package/dist/advanced.cjs.map +1 -0
- package/dist/advanced.d.cts +90 -2
- package/dist/advanced.d.ts +90 -2
- package/dist/advanced.js +236 -1
- package/dist/advanced.js.map +1 -0
- package/dist/{contract-ULPQmiEs.d.ts → contract-CNR6BS75.d.cts} +216 -30
- package/dist/{contract-SYJFP0lM.d.cts → contract-COgxO5sv.d.ts} +216 -30
- package/dist/definition-CDOuvb5C.d.cts +111 -0
- package/dist/definition-xgk3YNBp.d.ts +111 -0
- package/dist/{driver-yFfvDMX5.js → driver-B5vdPohL.js} +59 -3
- package/dist/driver-B5vdPohL.js.map +1 -0
- package/dist/{driver-BD3DQOW6.cjs → driver-BL91gn7_.cjs} +107 -9
- package/dist/driver-BL91gn7_.cjs.map +1 -0
- package/dist/index.cjs +1637 -703
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +65 -33
- package/dist/index.d.ts +65 -33
- package/dist/index.js +1432 -497
- package/dist/index.js.map +1 -1
- package/dist/local-sync.cjs +69 -103
- package/dist/local-sync.cjs.map +1 -1
- package/dist/local-sync.d.cts +14 -26
- package/dist/local-sync.d.ts +14 -26
- package/dist/local-sync.js +68 -96
- package/dist/local-sync.js.map +1 -1
- package/dist/react.cjs +4 -5
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +6 -8
- package/dist/react.d.ts +6 -8
- package/dist/react.js +4 -5
- package/dist/react.js.map +1 -1
- package/dist/record-B2yRhYsc.js +28 -0
- package/dist/record-B2yRhYsc.js.map +1 -0
- package/dist/record-ChYUi8PP.cjs +45 -0
- package/dist/record-ChYUi8PP.cjs.map +1 -0
- package/dist/scheduler--137L3j-.js +500 -0
- package/dist/scheduler--137L3j-.js.map +1 -0
- package/dist/scheduler-D4VthaaK.cjs +589 -0
- package/dist/scheduler-D4VthaaK.cjs.map +1 -0
- package/package.json +6 -3
- package/skills/doxum-runtime/SKILL.md +32 -7
- package/skills/doxum-runtime/agents/openai.yaml +1 -1
- package/skills/doxum-runtime/references/api.en.md +249 -0
- package/skills/doxum-runtime/references/api.zh-CN.md +242 -0
- package/skills/doxum-runtime/references/guide.en.md +18 -8
- package/skills/doxum-runtime/references/guide.zh-CN.md +14 -6
- package/skills/doxum-runtime/references/invariants.en.md +29 -5
- package/skills/doxum-runtime/references/invariants.zh-CN.md +24 -6
- package/skills/doxum-runtime/references/patterns.en.md +78 -18
- package/skills/doxum-runtime/references/patterns.zh-CN.md +76 -18
- package/skills/doxum-runtime/references/projections.en.md +209 -119
- package/skills/doxum-runtime/references/projections.zh-CN.md +200 -101
- package/dist/advanced-CLJCWkHa.d.cts +0 -176
- package/dist/advanced-CRNHfJBu.js +0 -1224
- package/dist/advanced-CRNHfJBu.js.map +0 -1
- package/dist/advanced-Cle5g3B4.cjs +0 -1517
- package/dist/advanced-Cle5g3B4.cjs.map +0 -1
- package/dist/advanced-d6J61er9.d.ts +0 -176
- package/dist/context-BcLKGfq8.cjs +0 -149
- package/dist/context-BcLKGfq8.cjs.map +0 -1
- package/dist/context-DFEaDUv5.js +0 -84
- package/dist/context-DFEaDUv5.js.map +0 -1
- package/dist/driver-BD3DQOW6.cjs.map +0 -1
- package/dist/driver-yFfvDMX5.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"driver-B5vdPohL.js","names":["issue.fail","tree.validNode"],"sources":["../core/src/tree/topology.ts","../core/src/mutation/issue.ts","../core/src/address/index.ts","../core/src/mutation/changes.ts","../core/src/runtime/context.ts","../core/src/runtime/driver.ts"],"sourcesContent":["import { isRecord } from '../value/record';\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 } from '../schema/model';\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","import type { DocumentAddress } from '../schema/model';\n\ntype AddressIndexNode<T> = {\n readonly children: Map<string, AddressIndexNode<T>>;\n readonly values: Set<T>;\n};\n\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 index = 0; index < address.length + (member === undefined ? 0 : 1); index++) {\n const segment = index < address.length ? address[index] : 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, member?: string): void {\n const parents: AddressIndexNode<T>[] = [];\n let node = this.root;\n const segments = member === undefined ? address : [...address, member];\n for (const segment of segments) {\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 (\n let index = segments.length - 1;\n index >= 0 && !node.values.size && !node.children.size;\n index--\n ) {\n node = parents[index];\n node.children.delete(segments[index]);\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 index = 0; index < address.length; index++) {\n if (node.values.size) return true;\n const child = node.children.get(address[index]);\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 index = 0; ; index++) {\n for (const value of node.values) if (predicate(value)) return true;\n if (index === address.length) return false;\n const child = node.children.get(address[index]);\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 { Change, ChangeSet, MemberChange, ValueTransition } from '../changes';\nimport { AddressIndex } from '../address/index';\nimport { isPlainObject } from '../value/record';\nimport * as issue from './issue';\nimport * as tree from '../tree/topology';\n\nconst validated = new WeakSet<ChangeSet>();\n\nconst compareChanges = (a: Change, b: Change): number => {\n if (a.kind === 'reset' || b.kind === 'reset')\n return a.kind === b.kind ? 0 : a.kind === 'reset' ? -1 : 1;\n const length = Math.min(a.at.length, b.at.length);\n for (let i = 0; i < length; i++) if (a.at[i] !== b.at[i]) return lexical(a.at[i], b.at[i]);\n return a.at.length - b.at.length || lexical(a.kind, b.kind);\n};\n\nconst publication = (changes: Change[]): ChangeSet => {\n const result = { changes };\n validated.add(result);\n return result;\n};\n\n/** Register complete recorder groups; unknown input is validated separately. */\nexport const sealChanges = (changes: Change[]): ChangeSet => {\n changes.sort(compareChanges);\n return publication(changes);\n};\n\nconst keys = (value: Record<string, unknown>, expected: readonly string[]) =>\n Object.keys(value).every(key => expected.includes(key));\nconst strings = (value: unknown): value is readonly string[] => {\n if (!Array.isArray(value)) return false;\n for (const item of value) if (typeof item !== 'string') return false;\n return true;\n};\nconst order = (value: unknown): value is readonly string[] =>\n strings(value) && new Set(value).size === value.length;\nconst transition = (\n value: unknown,\n key: 'key' | 'id'\n): value is ValueTransition & Record<string, unknown> => {\n if (!isPlainObject(value) || typeof value[key] !== 'string') return false;\n if (value.kind === 'added')\n return keys(value, ['kind', key, 'after']) && Object.hasOwn(value, 'after');\n if (value.kind === 'removed')\n return keys(value, ['kind', key, 'before']) && Object.hasOwn(value, 'before');\n return (\n value.kind === 'updated' &&\n keys(value, ['kind', key, 'before', 'after']) &&\n Object.hasOwn(value, 'before') &&\n Object.hasOwn(value, 'after')\n );\n};\nconst lexical = (a: string, b: string) => (a < b ? -1 : a === b ? 0 : 1);\n\n/** The sole unknown ChangeSet boundary, including normalized logical-address conflicts. */\nexport const decodeChanges = (input: unknown): ChangeSet => {\n if (typeof input === 'object' && input !== null && validated.has(input as ChangeSet))\n return input as ChangeSet;\n if (!isPlainObject(input) || !keys(input, ['changes']) || !Array.isArray(input.changes))\n return issue.fail([], 'invalid-changes', 'Expected a ChangeSet.');\n const result: Change[] = [];\n for (const entry of input.changes) {\n if (!isPlainObject(entry)) return issue.fail([], 'invalid-changes', 'Expected a change.');\n if (entry.kind === 'reset') {\n if (\n input.changes.length !== 1 ||\n !keys(entry, ['kind', 'before', 'after']) ||\n !Object.hasOwn(entry, 'before') ||\n !Object.hasOwn(entry, 'after')\n )\n return issue.fail(\n [],\n 'invalid-changes',\n 'A reset must be the only change and contain both values.'\n );\n return sealChanges([{ kind: 'reset', before: entry.before, after: entry.after }]);\n }\n if (!strings(entry.at))\n return issue.fail([], 'invalid-changes', 'Change addresses must contain strings.');\n const at = entry.at;\n if (\n entry.kind === 'members' &&\n keys(entry, ['kind', 'at', 'members', 'order']) &&\n Array.isArray(entry.members) &&\n (entry.members.length || Object.hasOwn(entry, 'order'))\n ) {\n const seen = new Set<string>();\n const members: MemberChange[] = [];\n for (const member of entry.members) {\n if (!transition(member, 'key') || typeof member.key !== 'string' || seen.has(member.key))\n return issue.fail(at, 'invalid-changes', 'Malformed or duplicate member transition.');\n seen.add(member.key);\n members.push({ ...member, key: member.key });\n }\n const change: Extract<Change, { kind: 'members' }> = {\n kind: 'members',\n at,\n members: members.sort((a, b) => lexical(a.key, b.key)),\n };\n if (Object.hasOwn(entry, 'order')) {\n if (\n !isPlainObject(entry.order) ||\n !keys(entry.order, ['before', 'after']) ||\n !order(entry.order.before) ||\n !order(entry.order.after)\n )\n return issue.fail(at, 'invalid-changes', 'Malformed container order.');\n result.push({ ...change, order: { before: entry.order.before, after: entry.order.after } });\n } else result.push(change);\n } else if (\n entry.kind === 'tree' &&\n keys(entry, ['kind', 'at', 'before', 'after', 'nodes']) &&\n (entry.before === null || typeof entry.before === 'string') &&\n (entry.after === null || typeof entry.after === 'string') &&\n Array.isArray(entry.nodes)\n ) {\n const seen = new Set<string>();\n for (const node of entry.nodes) {\n if (\n !transition(node, 'id') ||\n typeof node.id !== 'string' ||\n seen.has(node.id) ||\n (node.kind !== 'added' && !tree.validNode(node.before)) ||\n (node.kind !== 'removed' && !tree.validNode(node.after))\n )\n return issue.fail(at, 'invalid-changes', 'Malformed or duplicate tree transition.');\n seen.add(node.id);\n }\n const nodes = entry.nodes as Extract<Change, { kind: 'tree' }>['nodes'];\n result.push({\n kind: 'tree',\n at,\n before: entry.before,\n after: entry.after,\n nodes: [...nodes].sort((a, b) => lexical(a.id, b.id)),\n });\n } else return issue.fail(at, 'invalid-changes', 'Unknown or malformed change.');\n }\n return publication(normalizeChanges(result));\n};\n\nconst normalizeChanges = (changes: Change[]): Change[] => {\n const sorted = changes.sort(compareChanges);\n const groups = new AddressIndex<true>();\n const replacements = new AddressIndex<true>();\n const orders = new AddressIndex<true>();\n for (const change of sorted) {\n if (change.kind === 'reset') continue;\n if (change.kind === 'members') {\n if (groups.exact(change.at)?.size)\n return issue.fail(change.at, 'invalid-changes', 'Duplicate member group.');\n groups.add(change.at, true);\n if (change.order) {\n if (replacements.hasAncestor(change.at))\n return issue.fail(change.at, 'invalid-changes', 'Overlapping container order.');\n orders.add(change.at, true);\n }\n for (const member of change.members) {\n const at = change.at.concat(member.key);\n if (replacements.overlaps(at) || orders.hasDescendant(at))\n return issue.fail(at, 'invalid-changes', 'Overlapping member transitions.');\n replacements.add(at, true);\n }\n } else if (change.kind === 'tree') {\n if (replacements.overlaps(change.at) || orders.hasDescendant(change.at))\n return issue.fail(change.at, 'invalid-changes', 'Overlapping tree transitions.');\n replacements.add(change.at, true);\n }\n }\n return sorted;\n};\n\nexport const changeCount = (changes: ChangeSet): number => {\n let count = 0;\n for (const change of changes.changes)\n count +=\n change.kind === 'members'\n ? change.members.length + (change.order ? 1 : 0)\n : change.kind === 'tree'\n ? 1 + change.nodes.length\n : 1;\n return count;\n};\n","import type { Infer, ObjectSchema, RootNodeOf } from '../schema/model';\nimport type { DocumentRuntime } from './contract';\nimport type { RuntimeWriteDriver } from './driver';\nimport type { NotificationCenter } from './notification';\n\nexport type RuntimeState<TSchema extends ObjectSchema<object>> = {\n readonly schema: RootNodeOf<TSchema>;\n document: Infer<TSchema>;\n disposed: boolean;\n projectionLocks: number;\n};\n\nexport type RuntimeContext<TSchema extends ObjectSchema<object>> = {\n readonly state: RuntimeState<TSchema>;\n readonly owner: DocumentRuntime<TSchema>;\n readonly notifications: NotificationCenter<TSchema>;\n driver: RuntimeWriteDriver | undefined;\n bypassDepth: number;\n};\n\nconst contexts = new WeakMap<object, RuntimeContext<ObjectSchema<object>>>();\n\nexport const bindContext = <TSchema extends ObjectSchema<object>>(\n subject: object,\n context: RuntimeContext<TSchema>\n): void => {\n contexts.set(subject, context as unknown as RuntimeContext<ObjectSchema<object>>);\n};\n\nexport function contextOf<TSchema extends ObjectSchema<object>>(\n subject: object,\n required?: true\n): RuntimeContext<TSchema>;\nexport function contextOf<TSchema extends ObjectSchema<object>>(\n subject: object,\n required: false\n): RuntimeContext<TSchema> | undefined;\nexport function contextOf<TSchema extends ObjectSchema<object>>(\n subject: object,\n required = true\n): RuntimeContext<TSchema> | undefined {\n const context = contexts.get(subject);\n if (!context && required) throw new Error('Unknown Doxum runtime.');\n return context as unknown as RuntimeContext<TSchema> | undefined;\n}\n","import type { CommitSource, DocumentRuntime } from './contract';\nimport type { ObjectSchema } from '../schema/model';\nimport { contextOf } from './context';\n\nexport type RuntimeWriteIntent =\n | { readonly kind: 'update'; readonly source: Extract<CommitSource, 'local' | 'system'> }\n | { readonly kind: 'apply'; readonly source: CommitSource }\n | { readonly kind: 'replace'; readonly source: Extract<CommitSource, 'system' | 'remote'> };\n\nexport type RuntimeWriteDriver = {\n readonly assertWritable: (intent: RuntimeWriteIntent) => void;\n};\n\nexport type RuntimeWriteDriverLease = {\n readonly run: <TResult>(run: () => TResult) => TResult;\n readonly dispose: () => void;\n};\n\nexport const assertRuntimeWritable = (runtime: object, intent: RuntimeWriteIntent): void => {\n const context = contextOf(runtime);\n if (context.bypassDepth === 0) context.driver?.assertWritable(intent);\n};\n\nexport const installRuntimeWriteDriver = <TSchema extends ObjectSchema<object>>(\n runtime: DocumentRuntime<TSchema>,\n driver: RuntimeWriteDriver\n): RuntimeWriteDriverLease => {\n const context = contextOf(runtime);\n if (context.driver) throw new Error('Doxum runtime already has a write driver.');\n context.driver = driver;\n let active = true;\n return Object.freeze({\n run: <TResult>(run: () => TResult): TResult => {\n if (!active) throw new Error('Doxum runtime write driver is no longer active.');\n context.bypassDepth += 1;\n try {\n return run();\n } finally {\n context.bypassDepth -= 1;\n }\n },\n dispose: (): void => {\n if (!active) return;\n active = false;\n if (context.driver === driver) context.driver = undefined;\n },\n });\n};\n"],"mappings":"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"}
|
|
@@ -1,4 +1,49 @@
|
|
|
1
|
-
const
|
|
1
|
+
const require_record = require("./record-ChYUi8PP.cjs");
|
|
2
|
+
//#region core/src/tree/topology.ts
|
|
3
|
+
const node = (tree, id) => Object.hasOwn(tree.nodes, id) ? tree.nodes[id] : void 0;
|
|
4
|
+
const is = (value) => require_record.isRecord(value) && require_record.isRecord(value.nodes);
|
|
5
|
+
const validNode = (value) => {
|
|
6
|
+
if (!require_record.isRecord(value) || !Array.isArray(value.children)) return false;
|
|
7
|
+
if (value.parentId !== void 0 && typeof value.parentId !== "string") return false;
|
|
8
|
+
const children = /* @__PURE__ */ new Set();
|
|
9
|
+
for (const id of value.children) {
|
|
10
|
+
if (typeof id !== "string" || children.has(id)) return false;
|
|
11
|
+
children.add(id);
|
|
12
|
+
}
|
|
13
|
+
return true;
|
|
14
|
+
};
|
|
15
|
+
const contains = (tree, id) => Object.hasOwn(tree.nodes, id);
|
|
16
|
+
const parent = (tree, id) => node(tree, id)?.parentId;
|
|
17
|
+
const children = (tree, id) => node(tree, id)?.children;
|
|
18
|
+
const validate = (value) => {
|
|
19
|
+
if (!is(value)) return false;
|
|
20
|
+
const ids = Object.keys(value.nodes);
|
|
21
|
+
if (ids.length === 0) return value.rootId === void 0;
|
|
22
|
+
if (typeof value.rootId !== "string" || !Object.hasOwn(value.nodes, value.rootId)) return false;
|
|
23
|
+
for (const id of ids) {
|
|
24
|
+
const entry = value.nodes[id];
|
|
25
|
+
if (!validNode(entry)) return false;
|
|
26
|
+
if (id === value.rootId) {
|
|
27
|
+
if (entry.parentId !== void 0) return false;
|
|
28
|
+
} else if (entry.parentId === void 0 || !Object.hasOwn(value.nodes, entry.parentId)) return false;
|
|
29
|
+
for (const child of entry.children) {
|
|
30
|
+
const childNode = value.nodes[child];
|
|
31
|
+
if (!childNode || childNode.parentId !== id) return false;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
const seen = /* @__PURE__ */ new Set();
|
|
35
|
+
const stack = [value.rootId];
|
|
36
|
+
while (stack.length) {
|
|
37
|
+
const id = stack.pop();
|
|
38
|
+
if (seen.has(id)) return false;
|
|
39
|
+
seen.add(id);
|
|
40
|
+
const entry = value.nodes[id];
|
|
41
|
+
if (!entry) return false;
|
|
42
|
+
for (const child of entry.children) stack.push(child);
|
|
43
|
+
}
|
|
44
|
+
return seen.size === ids.length;
|
|
45
|
+
};
|
|
46
|
+
//#endregion
|
|
2
47
|
//#region core/src/mutation/issue.ts
|
|
3
48
|
const at = (address, code, message) => Object.freeze({
|
|
4
49
|
source: "mutation",
|
|
@@ -169,7 +214,7 @@ const strings = (value) => {
|
|
|
169
214
|
};
|
|
170
215
|
const order = (value) => strings(value) && new Set(value).size === value.length;
|
|
171
216
|
const transition = (value, key) => {
|
|
172
|
-
if (!
|
|
217
|
+
if (!require_record.isPlainObject(value) || typeof value[key] !== "string") return false;
|
|
173
218
|
if (value.kind === "added") return keys(value, [
|
|
174
219
|
"kind",
|
|
175
220
|
key,
|
|
@@ -191,10 +236,10 @@ const lexical = (a, b) => a < b ? -1 : a === b ? 0 : 1;
|
|
|
191
236
|
/** The sole unknown ChangeSet boundary, including normalized logical-address conflicts. */
|
|
192
237
|
const decodeChanges = (input) => {
|
|
193
238
|
if (typeof input === "object" && input !== null && validated.has(input)) return input;
|
|
194
|
-
if (!
|
|
239
|
+
if (!require_record.isPlainObject(input) || !keys(input, ["changes"]) || !Array.isArray(input.changes)) return fail([], "invalid-changes", "Expected a ChangeSet.");
|
|
195
240
|
const result = [];
|
|
196
241
|
for (const entry of input.changes) {
|
|
197
|
-
if (!
|
|
242
|
+
if (!require_record.isPlainObject(entry)) return fail([], "invalid-changes", "Expected a change.");
|
|
198
243
|
if (entry.kind === "reset") {
|
|
199
244
|
if (input.changes.length !== 1 || !keys(entry, [
|
|
200
245
|
"kind",
|
|
@@ -231,7 +276,7 @@ const decodeChanges = (input) => {
|
|
|
231
276
|
members: members.sort((a, b) => lexical(a.key, b.key))
|
|
232
277
|
};
|
|
233
278
|
if (Object.hasOwn(entry, "order")) {
|
|
234
|
-
if (!
|
|
279
|
+
if (!require_record.isPlainObject(entry.order) || !keys(entry.order, ["before", "after"]) || !order(entry.order.before) || !order(entry.order.after)) return fail(at, "invalid-changes", "Malformed container order.");
|
|
235
280
|
result.push({
|
|
236
281
|
...change,
|
|
237
282
|
order: {
|
|
@@ -249,7 +294,7 @@ const decodeChanges = (input) => {
|
|
|
249
294
|
]) && (entry.before === null || typeof entry.before === "string") && (entry.after === null || typeof entry.after === "string") && Array.isArray(entry.nodes)) {
|
|
250
295
|
const seen = /* @__PURE__ */ new Set();
|
|
251
296
|
for (const node of entry.nodes) {
|
|
252
|
-
if (!transition(node, "id") || typeof node.id !== "string" || seen.has(node.id) || node.kind !== "added" && !
|
|
297
|
+
if (!transition(node, "id") || typeof node.id !== "string" || seen.has(node.id) || node.kind !== "added" && !validNode(node.before) || node.kind !== "removed" && !validNode(node.after)) return fail(at, "invalid-changes", "Malformed or duplicate tree transition.");
|
|
253
298
|
seen.add(node.id);
|
|
254
299
|
}
|
|
255
300
|
const nodes = entry.nodes;
|
|
@@ -296,13 +341,24 @@ const changeCount = (changes) => {
|
|
|
296
341
|
return count;
|
|
297
342
|
};
|
|
298
343
|
//#endregion
|
|
344
|
+
//#region core/src/runtime/context.ts
|
|
345
|
+
const contexts = /* @__PURE__ */ new WeakMap();
|
|
346
|
+
const bindContext = (subject, context) => {
|
|
347
|
+
contexts.set(subject, context);
|
|
348
|
+
};
|
|
349
|
+
function contextOf(subject, required = true) {
|
|
350
|
+
const context = contexts.get(subject);
|
|
351
|
+
if (!context && required) throw new Error("Unknown Doxum runtime.");
|
|
352
|
+
return context;
|
|
353
|
+
}
|
|
354
|
+
//#endregion
|
|
299
355
|
//#region core/src/runtime/driver.ts
|
|
300
356
|
const assertRuntimeWritable = (runtime, intent) => {
|
|
301
|
-
const context =
|
|
357
|
+
const context = contextOf(runtime);
|
|
302
358
|
if (context.bypassDepth === 0) context.driver?.assertWritable(intent);
|
|
303
359
|
};
|
|
304
360
|
const installRuntimeWriteDriver = (runtime, driver) => {
|
|
305
|
-
const context =
|
|
361
|
+
const context = contextOf(runtime);
|
|
306
362
|
if (context.driver) throw new Error("Doxum runtime already has a write driver.");
|
|
307
363
|
context.driver = driver;
|
|
308
364
|
let active = true;
|
|
@@ -342,12 +398,36 @@ Object.defineProperty(exports, "assertRuntimeWritable", {
|
|
|
342
398
|
return assertRuntimeWritable;
|
|
343
399
|
}
|
|
344
400
|
});
|
|
401
|
+
Object.defineProperty(exports, "bindContext", {
|
|
402
|
+
enumerable: true,
|
|
403
|
+
get: function() {
|
|
404
|
+
return bindContext;
|
|
405
|
+
}
|
|
406
|
+
});
|
|
345
407
|
Object.defineProperty(exports, "changeCount", {
|
|
346
408
|
enumerable: true,
|
|
347
409
|
get: function() {
|
|
348
410
|
return changeCount;
|
|
349
411
|
}
|
|
350
412
|
});
|
|
413
|
+
Object.defineProperty(exports, "children", {
|
|
414
|
+
enumerable: true,
|
|
415
|
+
get: function() {
|
|
416
|
+
return children;
|
|
417
|
+
}
|
|
418
|
+
});
|
|
419
|
+
Object.defineProperty(exports, "contains", {
|
|
420
|
+
enumerable: true,
|
|
421
|
+
get: function() {
|
|
422
|
+
return contains;
|
|
423
|
+
}
|
|
424
|
+
});
|
|
425
|
+
Object.defineProperty(exports, "contextOf", {
|
|
426
|
+
enumerable: true,
|
|
427
|
+
get: function() {
|
|
428
|
+
return contextOf;
|
|
429
|
+
}
|
|
430
|
+
});
|
|
351
431
|
Object.defineProperty(exports, "decodeChanges", {
|
|
352
432
|
enumerable: true,
|
|
353
433
|
get: function() {
|
|
@@ -372,11 +452,29 @@ Object.defineProperty(exports, "invalidValue", {
|
|
|
372
452
|
return invalidValue;
|
|
373
453
|
}
|
|
374
454
|
});
|
|
455
|
+
Object.defineProperty(exports, "is", {
|
|
456
|
+
enumerable: true,
|
|
457
|
+
get: function() {
|
|
458
|
+
return is;
|
|
459
|
+
}
|
|
460
|
+
});
|
|
461
|
+
Object.defineProperty(exports, "parent", {
|
|
462
|
+
enumerable: true,
|
|
463
|
+
get: function() {
|
|
464
|
+
return parent;
|
|
465
|
+
}
|
|
466
|
+
});
|
|
375
467
|
Object.defineProperty(exports, "sealChanges", {
|
|
376
468
|
enumerable: true,
|
|
377
469
|
get: function() {
|
|
378
470
|
return sealChanges;
|
|
379
471
|
}
|
|
380
472
|
});
|
|
473
|
+
Object.defineProperty(exports, "validate", {
|
|
474
|
+
enumerable: true,
|
|
475
|
+
get: function() {
|
|
476
|
+
return validate;
|
|
477
|
+
}
|
|
478
|
+
});
|
|
381
479
|
|
|
382
|
-
//# sourceMappingURL=driver-
|
|
480
|
+
//# sourceMappingURL=driver-BL91gn7_.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"driver-BL91gn7_.cjs","names":["isRecord","isPlainObject","issue.fail","tree.validNode"],"sources":["../core/src/tree/topology.ts","../core/src/mutation/issue.ts","../core/src/address/index.ts","../core/src/mutation/changes.ts","../core/src/runtime/context.ts","../core/src/runtime/driver.ts"],"sourcesContent":["import { isRecord } from '../value/record';\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 } from '../schema/model';\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","import type { DocumentAddress } from '../schema/model';\n\ntype AddressIndexNode<T> = {\n readonly children: Map<string, AddressIndexNode<T>>;\n readonly values: Set<T>;\n};\n\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 index = 0; index < address.length + (member === undefined ? 0 : 1); index++) {\n const segment = index < address.length ? address[index] : 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, member?: string): void {\n const parents: AddressIndexNode<T>[] = [];\n let node = this.root;\n const segments = member === undefined ? address : [...address, member];\n for (const segment of segments) {\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 (\n let index = segments.length - 1;\n index >= 0 && !node.values.size && !node.children.size;\n index--\n ) {\n node = parents[index];\n node.children.delete(segments[index]);\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 index = 0; index < address.length; index++) {\n if (node.values.size) return true;\n const child = node.children.get(address[index]);\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 index = 0; ; index++) {\n for (const value of node.values) if (predicate(value)) return true;\n if (index === address.length) return false;\n const child = node.children.get(address[index]);\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 { Change, ChangeSet, MemberChange, ValueTransition } from '../changes';\nimport { AddressIndex } from '../address/index';\nimport { isPlainObject } from '../value/record';\nimport * as issue from './issue';\nimport * as tree from '../tree/topology';\n\nconst validated = new WeakSet<ChangeSet>();\n\nconst compareChanges = (a: Change, b: Change): number => {\n if (a.kind === 'reset' || b.kind === 'reset')\n return a.kind === b.kind ? 0 : a.kind === 'reset' ? -1 : 1;\n const length = Math.min(a.at.length, b.at.length);\n for (let i = 0; i < length; i++) if (a.at[i] !== b.at[i]) return lexical(a.at[i], b.at[i]);\n return a.at.length - b.at.length || lexical(a.kind, b.kind);\n};\n\nconst publication = (changes: Change[]): ChangeSet => {\n const result = { changes };\n validated.add(result);\n return result;\n};\n\n/** Register complete recorder groups; unknown input is validated separately. */\nexport const sealChanges = (changes: Change[]): ChangeSet => {\n changes.sort(compareChanges);\n return publication(changes);\n};\n\nconst keys = (value: Record<string, unknown>, expected: readonly string[]) =>\n Object.keys(value).every(key => expected.includes(key));\nconst strings = (value: unknown): value is readonly string[] => {\n if (!Array.isArray(value)) return false;\n for (const item of value) if (typeof item !== 'string') return false;\n return true;\n};\nconst order = (value: unknown): value is readonly string[] =>\n strings(value) && new Set(value).size === value.length;\nconst transition = (\n value: unknown,\n key: 'key' | 'id'\n): value is ValueTransition & Record<string, unknown> => {\n if (!isPlainObject(value) || typeof value[key] !== 'string') return false;\n if (value.kind === 'added')\n return keys(value, ['kind', key, 'after']) && Object.hasOwn(value, 'after');\n if (value.kind === 'removed')\n return keys(value, ['kind', key, 'before']) && Object.hasOwn(value, 'before');\n return (\n value.kind === 'updated' &&\n keys(value, ['kind', key, 'before', 'after']) &&\n Object.hasOwn(value, 'before') &&\n Object.hasOwn(value, 'after')\n );\n};\nconst lexical = (a: string, b: string) => (a < b ? -1 : a === b ? 0 : 1);\n\n/** The sole unknown ChangeSet boundary, including normalized logical-address conflicts. */\nexport const decodeChanges = (input: unknown): ChangeSet => {\n if (typeof input === 'object' && input !== null && validated.has(input as ChangeSet))\n return input as ChangeSet;\n if (!isPlainObject(input) || !keys(input, ['changes']) || !Array.isArray(input.changes))\n return issue.fail([], 'invalid-changes', 'Expected a ChangeSet.');\n const result: Change[] = [];\n for (const entry of input.changes) {\n if (!isPlainObject(entry)) return issue.fail([], 'invalid-changes', 'Expected a change.');\n if (entry.kind === 'reset') {\n if (\n input.changes.length !== 1 ||\n !keys(entry, ['kind', 'before', 'after']) ||\n !Object.hasOwn(entry, 'before') ||\n !Object.hasOwn(entry, 'after')\n )\n return issue.fail(\n [],\n 'invalid-changes',\n 'A reset must be the only change and contain both values.'\n );\n return sealChanges([{ kind: 'reset', before: entry.before, after: entry.after }]);\n }\n if (!strings(entry.at))\n return issue.fail([], 'invalid-changes', 'Change addresses must contain strings.');\n const at = entry.at;\n if (\n entry.kind === 'members' &&\n keys(entry, ['kind', 'at', 'members', 'order']) &&\n Array.isArray(entry.members) &&\n (entry.members.length || Object.hasOwn(entry, 'order'))\n ) {\n const seen = new Set<string>();\n const members: MemberChange[] = [];\n for (const member of entry.members) {\n if (!transition(member, 'key') || typeof member.key !== 'string' || seen.has(member.key))\n return issue.fail(at, 'invalid-changes', 'Malformed or duplicate member transition.');\n seen.add(member.key);\n members.push({ ...member, key: member.key });\n }\n const change: Extract<Change, { kind: 'members' }> = {\n kind: 'members',\n at,\n members: members.sort((a, b) => lexical(a.key, b.key)),\n };\n if (Object.hasOwn(entry, 'order')) {\n if (\n !isPlainObject(entry.order) ||\n !keys(entry.order, ['before', 'after']) ||\n !order(entry.order.before) ||\n !order(entry.order.after)\n )\n return issue.fail(at, 'invalid-changes', 'Malformed container order.');\n result.push({ ...change, order: { before: entry.order.before, after: entry.order.after } });\n } else result.push(change);\n } else if (\n entry.kind === 'tree' &&\n keys(entry, ['kind', 'at', 'before', 'after', 'nodes']) &&\n (entry.before === null || typeof entry.before === 'string') &&\n (entry.after === null || typeof entry.after === 'string') &&\n Array.isArray(entry.nodes)\n ) {\n const seen = new Set<string>();\n for (const node of entry.nodes) {\n if (\n !transition(node, 'id') ||\n typeof node.id !== 'string' ||\n seen.has(node.id) ||\n (node.kind !== 'added' && !tree.validNode(node.before)) ||\n (node.kind !== 'removed' && !tree.validNode(node.after))\n )\n return issue.fail(at, 'invalid-changes', 'Malformed or duplicate tree transition.');\n seen.add(node.id);\n }\n const nodes = entry.nodes as Extract<Change, { kind: 'tree' }>['nodes'];\n result.push({\n kind: 'tree',\n at,\n before: entry.before,\n after: entry.after,\n nodes: [...nodes].sort((a, b) => lexical(a.id, b.id)),\n });\n } else return issue.fail(at, 'invalid-changes', 'Unknown or malformed change.');\n }\n return publication(normalizeChanges(result));\n};\n\nconst normalizeChanges = (changes: Change[]): Change[] => {\n const sorted = changes.sort(compareChanges);\n const groups = new AddressIndex<true>();\n const replacements = new AddressIndex<true>();\n const orders = new AddressIndex<true>();\n for (const change of sorted) {\n if (change.kind === 'reset') continue;\n if (change.kind === 'members') {\n if (groups.exact(change.at)?.size)\n return issue.fail(change.at, 'invalid-changes', 'Duplicate member group.');\n groups.add(change.at, true);\n if (change.order) {\n if (replacements.hasAncestor(change.at))\n return issue.fail(change.at, 'invalid-changes', 'Overlapping container order.');\n orders.add(change.at, true);\n }\n for (const member of change.members) {\n const at = change.at.concat(member.key);\n if (replacements.overlaps(at) || orders.hasDescendant(at))\n return issue.fail(at, 'invalid-changes', 'Overlapping member transitions.');\n replacements.add(at, true);\n }\n } else if (change.kind === 'tree') {\n if (replacements.overlaps(change.at) || orders.hasDescendant(change.at))\n return issue.fail(change.at, 'invalid-changes', 'Overlapping tree transitions.');\n replacements.add(change.at, true);\n }\n }\n return sorted;\n};\n\nexport const changeCount = (changes: ChangeSet): number => {\n let count = 0;\n for (const change of changes.changes)\n count +=\n change.kind === 'members'\n ? change.members.length + (change.order ? 1 : 0)\n : change.kind === 'tree'\n ? 1 + change.nodes.length\n : 1;\n return count;\n};\n","import type { Infer, ObjectSchema, RootNodeOf } from '../schema/model';\nimport type { DocumentRuntime } from './contract';\nimport type { RuntimeWriteDriver } from './driver';\nimport type { NotificationCenter } from './notification';\n\nexport type RuntimeState<TSchema extends ObjectSchema<object>> = {\n readonly schema: RootNodeOf<TSchema>;\n document: Infer<TSchema>;\n disposed: boolean;\n projectionLocks: number;\n};\n\nexport type RuntimeContext<TSchema extends ObjectSchema<object>> = {\n readonly state: RuntimeState<TSchema>;\n readonly owner: DocumentRuntime<TSchema>;\n readonly notifications: NotificationCenter<TSchema>;\n driver: RuntimeWriteDriver | undefined;\n bypassDepth: number;\n};\n\nconst contexts = new WeakMap<object, RuntimeContext<ObjectSchema<object>>>();\n\nexport const bindContext = <TSchema extends ObjectSchema<object>>(\n subject: object,\n context: RuntimeContext<TSchema>\n): void => {\n contexts.set(subject, context as unknown as RuntimeContext<ObjectSchema<object>>);\n};\n\nexport function contextOf<TSchema extends ObjectSchema<object>>(\n subject: object,\n required?: true\n): RuntimeContext<TSchema>;\nexport function contextOf<TSchema extends ObjectSchema<object>>(\n subject: object,\n required: false\n): RuntimeContext<TSchema> | undefined;\nexport function contextOf<TSchema extends ObjectSchema<object>>(\n subject: object,\n required = true\n): RuntimeContext<TSchema> | undefined {\n const context = contexts.get(subject);\n if (!context && required) throw new Error('Unknown Doxum runtime.');\n return context as unknown as RuntimeContext<TSchema> | undefined;\n}\n","import type { CommitSource, DocumentRuntime } from './contract';\nimport type { ObjectSchema } from '../schema/model';\nimport { contextOf } from './context';\n\nexport type RuntimeWriteIntent =\n | { readonly kind: 'update'; readonly source: Extract<CommitSource, 'local' | 'system'> }\n | { readonly kind: 'apply'; readonly source: CommitSource }\n | { readonly kind: 'replace'; readonly source: Extract<CommitSource, 'system' | 'remote'> };\n\nexport type RuntimeWriteDriver = {\n readonly assertWritable: (intent: RuntimeWriteIntent) => void;\n};\n\nexport type RuntimeWriteDriverLease = {\n readonly run: <TResult>(run: () => TResult) => TResult;\n readonly dispose: () => void;\n};\n\nexport const assertRuntimeWritable = (runtime: object, intent: RuntimeWriteIntent): void => {\n const context = contextOf(runtime);\n if (context.bypassDepth === 0) context.driver?.assertWritable(intent);\n};\n\nexport const installRuntimeWriteDriver = <TSchema extends ObjectSchema<object>>(\n runtime: DocumentRuntime<TSchema>,\n driver: RuntimeWriteDriver\n): RuntimeWriteDriverLease => {\n const context = contextOf(runtime);\n if (context.driver) throw new Error('Doxum runtime already has a write driver.');\n context.driver = driver;\n let active = true;\n return Object.freeze({\n run: <TResult>(run: () => TResult): TResult => {\n if (!active) throw new Error('Doxum runtime write driver is no longer active.');\n context.bypassDepth += 1;\n try {\n return run();\n } finally {\n context.bypassDepth -= 1;\n }\n },\n dispose: (): void => {\n if (!active) return;\n active = false;\n if (context.driver === driver) context.driver = undefined;\n },\n });\n};\n"],"mappings":"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"}
|