@skygraph/core 0.0.0-placeholder.0 → 0.4.0
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/LICENSE +21 -0
- package/dist/calendar.cjs +404 -0
- package/dist/calendar.cjs.map +1 -0
- package/dist/calendar.d.cts +209 -0
- package/dist/calendar.d.ts +209 -0
- package/dist/calendar.js +12 -0
- package/dist/calendar.js.map +1 -0
- package/dist/chunk-5CCD5Q4B.js +36 -0
- package/dist/chunk-5CCD5Q4B.js.map +1 -0
- package/dist/chunk-AB3RLBLW.js +357 -0
- package/dist/chunk-AB3RLBLW.js.map +1 -0
- package/dist/chunk-GEMALROQ.js +258 -0
- package/dist/chunk-GEMALROQ.js.map +1 -0
- package/dist/chunk-IY6LJU3L.js +256 -0
- package/dist/chunk-IY6LJU3L.js.map +1 -0
- package/dist/chunk-KMGRNPLG.js +453 -0
- package/dist/chunk-KMGRNPLG.js.map +1 -0
- package/dist/chunk-KP75DEA4.js +1012 -0
- package/dist/chunk-KP75DEA4.js.map +1 -0
- package/dist/chunk-Y7FTBBYX.js +397 -0
- package/dist/chunk-Y7FTBBYX.js.map +1 -0
- package/dist/chunk-ZWB7JGAJ.js +488 -0
- package/dist/chunk-ZWB7JGAJ.js.map +1 -0
- package/dist/form.cjs +498 -0
- package/dist/form.cjs.map +1 -0
- package/dist/form.d.cts +130 -0
- package/dist/form.d.ts +130 -0
- package/dist/form.js +8 -0
- package/dist/form.js.map +1 -0
- package/dist/graph.cjs +1065 -0
- package/dist/graph.cjs.map +1 -0
- package/dist/graph.d.cts +542 -0
- package/dist/graph.d.ts +542 -0
- package/dist/graph.js +24 -0
- package/dist/graph.js.map +1 -0
- package/dist/index.cjs +3656 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +144 -0
- package/dist/index.d.ts +144 -0
- package/dist/index.js +467 -0
- package/dist/index.js.map +1 -0
- package/dist/runtime-internal.cjs +339 -0
- package/dist/runtime-internal.cjs.map +1 -0
- package/dist/runtime-internal.d.cts +130 -0
- package/dist/runtime-internal.d.ts +130 -0
- package/dist/runtime-internal.js +67 -0
- package/dist/runtime-internal.js.map +1 -0
- package/dist/table.cjs +537 -0
- package/dist/table.cjs.map +1 -0
- package/dist/table.d.cts +215 -0
- package/dist/table.d.ts +215 -0
- package/dist/table.js +16 -0
- package/dist/table.js.map +1 -0
- package/dist/tree.cjs +442 -0
- package/dist/tree.cjs.map +1 -0
- package/dist/tree.d.cts +76 -0
- package/dist/tree.d.ts +76 -0
- package/dist/tree.js +8 -0
- package/dist/tree.js.map +1 -0
- package/dist/types-B-rKQJ4R.d.cts +35 -0
- package/dist/types-B-rKQJ4R.d.ts +35 -0
- package/dist/virtual.cjs +283 -0
- package/dist/virtual.cjs.map +1 -0
- package/dist/virtual.d.cts +96 -0
- package/dist/virtual.d.ts +96 -0
- package/dist/virtual.js +9 -0
- package/dist/virtual.js.map +1 -0
- package/package.json +98 -18
- package/README.md +0 -12
- package/index.js +0 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/runtime/Node.ts","../src/runtime/Store.ts","../src/runtime/SubscriptionEngine.ts","../src/runtime/Batch.ts","../src/runtime/Transaction.ts","../src/runtime/CycleDetector.ts","../src/runtime/ComputedEngine.ts","../src/Core.ts","../src/middleware/logger.ts","../src/middleware/freeze.ts","../src/middleware/persistence.ts","../src/middleware/validation.ts","../src/plugins/history.ts","../src/engines/virtual/measure.ts","../src/engines/virtual/index.ts","../src/typed.ts","../src/engines/namespaces.ts","../src/engines/form/FormEngine.ts","../src/engines/graph/history.ts","../src/engines/graph/GraphEngine.ts","../src/engines/graph/router.ts","../src/engines/graph/obb.ts","../src/engines/table/filter.ts","../src/engines/table/TableEngine.ts","../src/engines/tree/TreeEngine.ts","../src/engines/calendar/availability.ts","../src/engines/calendar/conflicts.ts","../src/engines/calendar/CalendarEngine.ts"],"sourcesContent":["export { createCore } from './Core'\nexport type { Core, WriteEvent, WriteSource, NextFn, Middleware } from './types'\n\nexport {\n loggerMiddleware,\n freezeMiddleware,\n persistenceMiddleware,\n validationMiddleware,\n} from './middleware/index'\n\nexport type { Validator, ValidationMiddlewareOptions } from './middleware/index'\n\nexport { createHistory } from './plugins/history'\nexport type { HistoryPlugin, HistoryEntry, HistoryOptions } from './plugins/history'\n\nexport { createVirtual, createMeasureCache } from './engines/virtual/index'\nexport type {\n VirtualEngine,\n VirtualEngineOptions,\n VirtualRange,\n VirtualItem,\n VirtualEngineEvent,\n VirtualEngineListener,\n MeasureCache,\n MeasureCacheEvent,\n MeasureCacheListener,\n MeasureCacheOptions,\n} from './engines/virtual/index'\n\nexport { createTypedCore } from './typed'\nexport type { TypedCore, Path, PathValue } from './typed'\n\nexport { createForm } from './engines/form/index'\nexport type {\n FormEngine,\n FieldMeta,\n FieldMetaExtensions,\n FormState,\n GetFieldValue,\n Rule,\n RuleFn,\n RuleObject,\n ValidationResult,\n FieldOptions,\n FormOptions,\n ValidationMode,\n FormListOperation,\n} from './engines/form/index'\n\nexport {\n reservePrefix,\n listReservedPrefixes,\n FORM_META_PREFIX,\n TABLE_PREFIX,\n TREE_PREFIX,\n GRAPH_PREFIX,\n CALENDAR_PREFIX,\n} from './engines/namespaces'\n\nexport {\n createGraph,\n routeOrthogonal,\n pointsToPath,\n pointsToRoundedPath,\n getBezierPath,\n nearestSide,\n aabbFromOBB,\n obbCorners,\n obbContainsPoint,\n} from './engines/graph/index'\nexport type {\n AABB,\n Anchor,\n AnchorId,\n AnchorPolicy,\n EdgeEndpoint,\n EdgeId,\n EdgeInit,\n GraphEdge,\n GraphEngine,\n GraphEngineOptions,\n GraphNode,\n GraphState,\n NodeId,\n NodeInit,\n NodeTransform,\n NodeUpdate,\n OBB,\n Outline,\n Point,\n RouteOrthogonalOptions,\n BezierPathOptions,\n Side,\n} from './engines/graph/index'\n\nexport {\n createTable,\n matchesOperator,\n matchesColumnFilter,\n resolveOperator,\n computeAggregate,\n} from './engines/table/index'\nexport type {\n TableEngine,\n TableState,\n TableOptions,\n RowId,\n SortConfig,\n SortDirection,\n ColumnFilter,\n FilterFn,\n FilterOperator,\n AdvancedFilter,\n AggregateType,\n AggregateFn,\n ColumnAggregate,\n TableGroup,\n} from './engines/table/index'\n\nexport { createTree } from './engines/tree/index'\nexport type {\n TreeEngine,\n TreeState,\n TreeEngineOptions,\n TreeKey,\n TreeNodeData,\n TreeFieldNames,\n} from './engines/tree/index'\n\nexport { createCalendar, detectConflicts, isAvailable } from './engines/calendar/index'\nexport type {\n Assignment as CalendarAssignment,\n AssignmentStatus as CalendarAssignmentStatus,\n AvailabilityRule as CalendarAvailabilityRule,\n CalendarEngine,\n CalendarEngineOptions,\n CalendarScale,\n CalendarState,\n Conflict as CalendarConflict,\n ConflictReason as CalendarConflictReason,\n DayOfWeek as CalendarDayOfWeek,\n DetectConflictsOptions as CalendarDetectConflictsOptions,\n Resource as CalendarResource,\n} from './engines/calendar/index'\n","export interface Node {\n readonly id: string\n value: unknown\n version: number\n}\n\nexport function createNode(id: string, value: unknown): Node {\n return { id, value, version: 0 }\n}\n","import { createNode } from './Node'\nimport type { Node } from './Node'\n\nexport class Store {\n private nodes: Map<string, Node> = new Map()\n\n has(path: string): boolean {\n return this.nodes.has(path)\n }\n\n get(path: string): unknown {\n return this.nodes.get(path)?.value\n }\n\n getNode(path: string): Node | undefined {\n return this.nodes.get(path)\n }\n\n set(path: string, value: unknown): Node {\n let node = this.nodes.get(path)\n if (node) {\n node.value = value\n node.version++\n return node\n }\n node = createNode(path, value)\n this.nodes.set(path, node)\n return node\n }\n\n delete(path: string): boolean {\n return this.nodes.delete(path)\n }\n\n paths(): IterableIterator<string> {\n return this.nodes.keys()\n }\n\n size(): number {\n return this.nodes.size\n }\n}\n","export type Listener = (value: unknown) => void\nexport type Unsubscribe = () => void\n\nexport class SubscriptionEngine {\n private listeners: Map<string, Set<Listener>> = new Map()\n\n subscribe(path: string, cb: Listener): Unsubscribe {\n let set = this.listeners.get(path)\n if (!set) {\n set = new Set()\n this.listeners.set(path, set)\n }\n set.add(cb)\n\n return () => {\n set!.delete(cb)\n if (set!.size === 0) {\n this.listeners.delete(path)\n }\n }\n }\n\n notify(path: string, value: unknown): void {\n const set = this.listeners.get(path)\n if (!set) return\n for (const cb of set) {\n cb(value)\n }\n }\n\n notifyMany(changes: Map<string, unknown>): void {\n for (const [path, value] of changes) {\n this.notify(path, value)\n }\n }\n\n hasListeners(path: string): boolean {\n const set = this.listeners.get(path)\n return set !== undefined && set.size > 0\n }\n\n clear(): void {\n this.listeners.clear()\n }\n}\n","/**\n * Batch collects path changes during a batch callback\n * and defers notifications until the callback completes.\n */\nexport class Batch {\n private depth = 0\n private pending: Map<string, unknown> = new Map()\n\n get isActive(): boolean {\n return this.depth > 0\n }\n\n start(): void {\n this.depth++\n }\n\n end(): Map<string, unknown> | null {\n this.depth--\n if (this.depth > 0) return null\n\n if (this.pending.size === 0) return null\n\n const changes = new Map(this.pending)\n this.pending.clear()\n return changes\n }\n\n enqueue(path: string, value: unknown): void {\n this.pending.set(path, value)\n }\n}\n","import type { Store } from './Store'\n\nexport interface StagedWrite {\n path: string\n value: unknown\n prevValue: unknown\n}\n\n/**\n * Transaction implements the pipeline:\n * SET -> STAGE -> RESOLVE -> PROPAGATE -> COMMIT -> NOTIFY\n *\n * PROPAGATE is handled externally by ComputedEngine.\n * NOTIFY is handled externally by SubscriptionEngine via Batch.\n */\nexport class Transaction {\n private active = false\n private staged: StagedWrite[] = []\n\n get isActive(): boolean {\n return this.active\n }\n\n start(): void {\n if (this.active) {\n throw new Error('SkyGraph: nested transactions are not supported')\n }\n this.active = true\n this.staged = []\n }\n\n /** STAGE: record a write without mutating the store */\n stage(path: string, value: unknown, prevValue: unknown): void {\n this.staged.push({ path, value, prevValue })\n }\n\n /**\n * RESOLVE + COMMIT: drop unchanged values, apply the rest to store.\n * Returns the map of actually changed paths and their new values.\n */\n commit(store: Store): Map<string, unknown> {\n const changes = new Map<string, unknown>()\n\n for (const write of this.staged) {\n if (Object.is(write.value, write.prevValue)) continue\n store.set(write.path, write.value)\n changes.set(write.path, write.value)\n }\n\n this.active = false\n this.staged = []\n return changes\n }\n\n getStaged(): readonly StagedWrite[] {\n return this.staged\n }\n\n complete(): void {\n this.active = false\n this.staged = []\n }\n\n rollback(): void {\n this.active = false\n this.staged = []\n }\n}\n","/**\n * Detects cycles in the computed dependency graph using DFS.\n * Throws on cycle detection to prevent infinite recomputation.\n */\nexport class CycleDetector {\n private graph: Map<string, Set<string>> = new Map()\n\n addEdge(from: string, to: string): void {\n let deps = this.graph.get(from)\n if (!deps) {\n deps = new Set()\n this.graph.set(from, deps)\n }\n deps.add(to)\n\n if (this.hasCycle(to, new Set([from]))) {\n deps.delete(to)\n if (deps.size === 0) this.graph.delete(from)\n throw new Error(\n `SkyGraph: circular dependency detected: ${from} -> ${to}`\n )\n }\n }\n\n removeNode(id: string): void {\n this.graph.delete(id)\n for (const deps of this.graph.values()) {\n deps.delete(id)\n }\n }\n\n getDependents(id: string): string[] {\n const targets = this.graph.get(id)\n return targets ? [...targets] : []\n }\n\n private hasCycle(node: string, visited: Set<string>): boolean {\n if (visited.has(node)) return true\n const deps = this.graph.get(node)\n if (!deps) return false\n visited.add(node)\n for (const dep of deps) {\n if (this.hasCycle(dep, new Set(visited))) return true\n }\n return false\n }\n}\n","import { CycleDetector } from './CycleDetector'\nimport type { Store } from './Store'\n\nexport type ComputeFn = (...values: unknown[]) => unknown\n\ninterface ComputedNode {\n target: string\n deps: string[]\n fn: ComputeFn\n}\n\n/**\n * Manages computed (derived) values in the reactive graph.\n * When a dependency changes, the computed value is recomputed\n * and only propagated if the result actually changed.\n */\nexport class ComputedEngine {\n private computedNodes: Map<string, ComputedNode> = new Map()\n private cycleDetector = new CycleDetector()\n\n register(target: string, deps: string[], fn: ComputeFn): void {\n if (this.computedNodes.has(target)) {\n this.remove(target)\n }\n\n for (const dep of deps) {\n this.cycleDetector.addEdge(dep, target)\n }\n\n this.computedNodes.set(target, { target, deps, fn })\n }\n\n remove(target: string): void {\n this.computedNodes.delete(target)\n this.cycleDetector.removeNode(target)\n }\n\n isComputed(path: string): boolean {\n return this.computedNodes.has(path)\n }\n\n /**\n * Like propagate, but returns both new and old values for middleware support.\n * Does NOT write to the store — the caller handles that via dispatchWrite.\n */\n propagateRaw(\n changedPaths: Set<string>,\n store: Store,\n ): Map<string, { value: unknown; oldValue: unknown }> {\n const result = new Map<string, { value: unknown; oldValue: unknown }>()\n const visited = new Set<string>()\n const queue = [...changedPaths]\n\n while (queue.length > 0) {\n const path = queue.shift()!\n if (visited.has(path)) continue\n visited.add(path)\n\n const dependents = this.cycleDetector.getDependents(path)\n\n for (const depTarget of dependents) {\n const computed = this.computedNodes.get(depTarget)\n if (!computed) continue\n\n const depValues = computed.deps.map((d) => {\n const pending = result.get(d)\n return pending ? pending.value : store.get(d)\n })\n const newValue = computed.fn(...depValues)\n const oldValue = result.has(depTarget)\n ? result.get(depTarget)!.oldValue\n : store.get(depTarget)\n\n if (!Object.is(newValue, oldValue)) {\n result.set(depTarget, { value: newValue, oldValue })\n queue.push(depTarget)\n }\n }\n }\n\n return result\n }\n\n /**\n * Initialize all computed values based on current store state.\n */\n initializeAll(store: Store): void {\n for (const computed of this.computedNodes.values()) {\n const depValues = computed.deps.map((d) => store.get(d))\n const value = computed.fn(...depValues)\n store.set(computed.target, value)\n }\n }\n}\n","import { Store } from './runtime/Store'\nimport { SubscriptionEngine } from './runtime/SubscriptionEngine'\nimport { Batch } from './runtime/Batch'\nimport { Transaction } from './runtime/Transaction'\nimport { ComputedEngine } from './runtime/ComputedEngine'\nimport type { Core, Middleware, WriteEvent, NextFn } from './types'\n\nclass CoreImpl implements Core {\n private store = new Store()\n private subscriptions = new SubscriptionEngine()\n private batch_ = new Batch()\n private transaction_ = new Transaction()\n private computed_ = new ComputedEngine()\n\n private middlewares: Middleware[] = []\n\n // ── Middleware ──\n\n use(middleware: Middleware): () => void {\n this.middlewares.push(middleware)\n return () => {\n const idx = this.middlewares.indexOf(middleware)\n if (idx !== -1) this.middlewares.splice(idx, 1)\n }\n }\n\n private dispatchWrite(event: WriteEvent): void {\n let idx = 0\n const chain: NextFn = (ev: WriteEvent) => {\n if (idx < this.middlewares.length) {\n const mw = this.middlewares[idx++]\n mw(ev, chain)\n } else {\n this.commitWrite(ev)\n }\n }\n chain(event)\n }\n\n private commitWrite(event: WriteEvent): void {\n this.store.set(event.path, event.value)\n }\n\n // ── Public API ──\n\n get(path: string): unknown {\n return this.store.get(path)\n }\n\n set(path: string, value: unknown): void {\n if (this.transaction_.isActive) {\n this.transaction_.stage(path, value, this.store.get(path))\n return\n }\n\n const oldValue = this.store.get(path)\n if (Object.is(oldValue, value)) return\n\n this.dispatchWrite({ path, value, oldValue, source: 'user' })\n\n const computedChanges = this.propagateComputed(new Set([path]))\n\n if (this.batch_.isActive) {\n this.batch_.enqueue(path, value)\n for (const [cp, cv] of computedChanges) {\n this.batch_.enqueue(cp, cv)\n }\n return\n }\n\n this.subscriptions.notify(path, value)\n this.subscriptions.notifyMany(computedChanges)\n }\n\n subscribe(path: string, cb: (value: unknown) => void): () => void {\n return this.subscriptions.subscribe(path, cb)\n }\n\n batch(fn: () => void): void {\n this.batch_.start()\n try {\n fn()\n } finally {\n const changes = this.batch_.end()\n if (changes) {\n this.subscriptions.notifyMany(changes)\n }\n }\n }\n\n transaction(fn: () => void): void {\n this.batch_.start()\n this.transaction_.start()\n try {\n fn()\n const staged = this.transaction_.getStaged()\n\n // Pass all writes through middleware first, collecting approved ones.\n // dispatchWrite normally commits to store, so we temporarily redirect\n // commits to a pending list and only apply them atomically if all succeed.\n const approved: Array<{ path: string; value: unknown }> = []\n const origCommit = this.commitWrite.bind(this)\n this.commitWrite = (ev: WriteEvent) => {\n approved.push({ path: ev.path, value: ev.value })\n }\n\n try {\n for (const write of staged) {\n if (Object.is(write.value, write.prevValue)) continue\n this.dispatchWrite({\n path: write.path,\n value: write.value,\n oldValue: write.prevValue,\n source: 'transaction',\n })\n }\n } finally {\n this.commitWrite = origCommit\n }\n\n // All middleware passed — atomically apply to store\n const changes = new Map<string, unknown>()\n for (const { path, value } of approved) {\n this.store.set(path, value)\n changes.set(path, value)\n }\n\n this.transaction_.complete()\n\n const computedChanges = this.propagateComputed(new Set(changes.keys()))\n\n for (const [path, value] of changes) {\n this.batch_.enqueue(path, value)\n }\n for (const [path, value] of computedChanges) {\n this.batch_.enqueue(path, value)\n }\n } catch (e) {\n this.transaction_.rollback()\n throw e\n } finally {\n const batchedChanges = this.batch_.end()\n if (batchedChanges) {\n this.subscriptions.notifyMany(batchedChanges)\n }\n }\n }\n\n computed(\n target: string,\n deps: string[],\n fn: (...values: unknown[]) => unknown,\n ): void {\n this.computed_.register(target, deps, fn)\n const depValues = deps.map((d) => this.store.get(d))\n const value = fn(...depValues)\n const oldValue = this.store.get(target)\n this.dispatchWrite({\n path: target,\n value,\n oldValue,\n source: 'computed',\n })\n\n if (!Object.is(oldValue, value)) {\n this.subscriptions.notify(target, value)\n }\n }\n\n // ── Snapshot / Restore ──\n\n snapshot(): Record<string, unknown> {\n const result: Record<string, unknown> = {}\n for (const path of this.store.paths()) {\n result[path] = this.store.get(path)\n }\n return result\n }\n\n restore(snap: Record<string, unknown>): void {\n this.batch_.start()\n try {\n for (const [path, value] of Object.entries(snap)) {\n const oldValue = this.store.get(path)\n if (!Object.is(oldValue, value)) {\n this.dispatchWrite({ path, value, oldValue, source: 'restore' })\n this.batch_.enqueue(path, value)\n }\n }\n } finally {\n const changes = this.batch_.end()\n if (changes) {\n this.subscriptions.notifyMany(changes)\n }\n }\n }\n\n // ── Internal helpers ──\n\n private propagateComputed(changedPaths: Set<string>): Map<string, unknown> {\n const rawChanges = this.computed_.propagateRaw(changedPaths, this.store)\n const dispatched = new Map<string, unknown>()\n\n for (const [path, { value, oldValue }] of rawChanges) {\n this.dispatchWrite({ path, value, oldValue, source: 'computed' })\n dispatched.set(path, value)\n }\n\n return dispatched\n }\n}\n\nexport function createCore(): Core {\n return new CoreImpl()\n}\n","import type { Middleware, WriteEvent, NextFn } from '../types'\n\nexport interface LoggerOptions {\n filter?: (event: WriteEvent) => boolean\n log?: (message: string, event: WriteEvent) => void\n}\n\nexport function loggerMiddleware(options: LoggerOptions = {}): Middleware {\n const log = options.log ?? ((msg, ev) => console.log(msg, ev.path, ev.value))\n const filter = options.filter\n\n return (event: WriteEvent, next: NextFn) => {\n if (filter && !filter(event)) {\n next(event)\n return\n }\n log(`[skygraph:${event.source}]`, event)\n next(event)\n }\n}\n","import type { Middleware, WriteEvent, NextFn } from '../types'\n\n/**\n * Prevents writes to specified path prefixes.\n * Useful for making parts of the store read-only.\n */\nexport function freezeMiddleware(frozenPaths: string[]): Middleware {\n return (event: WriteEvent, next: NextFn) => {\n for (const prefix of frozenPaths) {\n if (event.path === prefix || event.path.startsWith(prefix + '.')) {\n return\n }\n }\n next(event)\n }\n}\n","import type { Middleware, WriteEvent, NextFn } from '../types'\n\nexport interface PersistenceOptions {\n key?: string\n paths?: string[]\n storage?: {\n getItem(key: string): string | null\n setItem(key: string, value: string): void\n }\n debounce?: number\n}\n\n/**\n * Persists selected paths to a storage backend (localStorage by default).\n * Debounced to avoid excessive writes.\n */\nexport function persistenceMiddleware(options: PersistenceOptions = {}): Middleware {\n const storageKey = options.key ?? 'skygraph:state'\n const storage = options.storage ?? (typeof localStorage !== 'undefined' ? localStorage : null)\n const paths = options.paths\n const debounceMs = options.debounce ?? 100\n\n let pending: Record<string, unknown> = {}\n let timer: ReturnType<typeof setTimeout> | null = null\n\n function flush() {\n if (!storage) return\n const existing = storage.getItem(storageKey)\n let data: Record<string, unknown> = {}\n if (existing) {\n try {\n data = JSON.parse(existing)\n } catch {\n /* corrupted, start fresh */\n }\n }\n Object.assign(data, pending)\n storage.setItem(storageKey, JSON.stringify(data))\n pending = {}\n timer = null\n }\n\n return (event: WriteEvent, next: NextFn) => {\n next(event)\n\n if (paths && !paths.some((p) => event.path === p || event.path.startsWith(p + '.'))) {\n return\n }\n\n pending[event.path] = event.value\n\n if (timer === null) {\n timer = setTimeout(flush, debounceMs)\n }\n }\n}\n","import type { Middleware, WriteEvent, NextFn } from '../types'\n\nexport type Validator = (event: WriteEvent) => boolean | string\n\nexport interface ValidationMiddlewareOptions {\n validators: Record<string, Validator>\n onReject?: (event: WriteEvent, reason: string) => void\n}\n\n/**\n * Validates writes against a map of path -> validator.\n * If the validator returns false or a string (error message),\n * the write is rejected and onReject is called (if provided).\n */\nexport function validationMiddleware(\n optionsOrValidators: ValidationMiddlewareOptions | Record<string, Validator>,\n): Middleware {\n const isOptions = 'validators' in optionsOrValidators\n const validators: Record<string, Validator> = isOptions\n ? (optionsOrValidators as ValidationMiddlewareOptions).validators\n : (optionsOrValidators as Record<string, Validator>)\n const onReject = isOptions\n ? (optionsOrValidators as ValidationMiddlewareOptions).onReject\n : undefined\n\n return (event: WriteEvent, next: NextFn) => {\n const validator = validators[event.path]\n if (validator) {\n const result = validator(event)\n if (result === false || typeof result === 'string') {\n onReject?.(event, typeof result === 'string' ? result : 'Validation failed')\n return\n }\n }\n next(event)\n }\n}\n","import type { Core, Middleware, WriteEvent, NextFn } from '../types'\n\nexport interface HistoryEntry {\n timestamp: number\n patches: ReadonlyArray<{ path: string; value: unknown; oldValue: unknown }>\n}\n\nexport interface HistoryPlugin {\n readonly entries: ReadonlyArray<HistoryEntry>\n readonly cursor: number\n readonly canUndo: boolean\n readonly canRedo: boolean\n\n undo(): void\n redo(): void\n jumpTo(index: number): void\n clear(): void\n destroy(): void\n}\n\nexport interface HistoryOptions {\n maxEntries?: number\n /** Group multiple writes within this window (ms) into a single entry */\n groupWindow?: number\n filter?: (event: WriteEvent) => boolean\n}\n\nexport function createHistory(core: Core, options: HistoryOptions = {}): HistoryPlugin {\n const maxEntries = options.maxEntries ?? 100\n const groupWindow = options.groupWindow ?? 0\n const filter = options.filter\n\n const entries: HistoryEntry[] = []\n let cursor = -1\n let travelling = false\n let groupTimer: ReturnType<typeof setTimeout> | null = null\n let pendingPatches: HistoryEntry['patches'][number][] = []\n\n function flushGroup() {\n if (pendingPatches.length === 0) return\n const entry: HistoryEntry = {\n timestamp: Date.now(),\n patches: [...pendingPatches],\n }\n pendingPatches = []\n\n if (cursor < entries.length - 1) {\n entries.splice(cursor + 1)\n }\n\n entries.push(entry)\n cursor++\n if (entries.length > maxEntries) {\n entries.shift()\n cursor--\n }\n\n groupTimer = null\n }\n\n const middleware: Middleware = (event: WriteEvent, next: NextFn) => {\n next(event)\n\n if (travelling) return\n if (event.source === 'computed') return\n if (filter && !filter(event)) return\n\n pendingPatches.push({\n path: event.path,\n value: event.value,\n oldValue: event.oldValue,\n })\n\n if (groupWindow > 0) {\n if (groupTimer === null) {\n groupTimer = setTimeout(flushGroup, groupWindow)\n }\n } else {\n flushGroup()\n }\n }\n\n const unsub = core.use(middleware)\n\n function applyPatches(patches: HistoryEntry['patches'], direction: 'undo' | 'redo') {\n travelling = true\n try {\n core.batch(() => {\n if (direction === 'undo') {\n for (let i = patches.length - 1; i >= 0; i--) {\n core.set(patches[i].path, patches[i].oldValue)\n }\n } else {\n for (const patch of patches) {\n core.set(patch.path, patch.value)\n }\n }\n })\n } finally {\n travelling = false\n }\n }\n\n return {\n get entries() {\n return entries as ReadonlyArray<HistoryEntry>\n },\n get cursor() {\n return cursor\n },\n get canUndo() {\n return cursor >= 0\n },\n get canRedo() {\n return cursor < entries.length - 1\n },\n\n undo() {\n if (cursor < 0) return\n flushGroup()\n applyPatches(entries[cursor].patches, 'undo')\n cursor--\n },\n\n redo() {\n if (cursor >= entries.length - 1) return\n flushGroup()\n cursor++\n applyPatches(entries[cursor].patches, 'redo')\n },\n\n jumpTo(index: number) {\n if (index < -1 || index >= entries.length) return\n flushGroup()\n\n while (cursor > index) {\n applyPatches(entries[cursor].patches, 'undo')\n cursor--\n }\n while (cursor < index) {\n cursor++\n applyPatches(entries[cursor].patches, 'redo')\n }\n },\n\n clear() {\n entries.length = 0\n cursor = -1\n pendingPatches = []\n if (groupTimer !== null) {\n clearTimeout(groupTimer)\n groupTimer = null\n }\n },\n\n destroy() {\n this.clear()\n unsub()\n },\n }\n}\n","/**\n * Кэш измерений высоты для VirtualEngine с динамической высотой строк.\n *\n * Хранит реальные измеренные высоты `Map<index, number>` поверх эстимейта.\n * Префикс-сумма (offsets) пересобирается лениво при первом запросе после\n * любой инвалидации (resize / measure / reset). Подписки нужны React-адаптеру,\n * чтобы перерисоваться, когда измерение строки изменилось.\n */\n\nexport type MeasureCacheEvent = 'measure' | 'reset' | 'resize'\nexport type MeasureCacheListener = (event: MeasureCacheEvent) => void\n\nexport interface MeasureCacheOptions {\n itemCount: number\n estimate: number | ((index: number) => number)\n}\n\nexport interface MeasureCache {\n readonly itemCount: number\n /** Сколько строк уже было измерено. */\n readonly measuredCount: number\n\n setItemCount(count: number): void\n setEstimate(estimate: number | ((index: number) => number)): void\n\n /** Записать измеренную высоту. Возвращает `true`, если значение изменилось. */\n setMeasuredHeight(index: number, height: number): boolean\n /** Сбросить измерение для одной строки. */\n clearMeasured(index: number): boolean\n /** Сбросить все измерения. */\n reset(): void\n\n hasMeasured(index: number): boolean\n getMeasuredHeight(index: number): number | undefined\n\n /** Эстимейт высоты — без учёта измерений. */\n getEstimatedSize(index: number): number\n /** Эффективная высота строки (измерение или эстимейт). */\n getItemSize(index: number): number\n\n getItemOffset(index: number): number\n getItemAtOffset(offset: number): number\n getTotalHeight(): number\n\n subscribe(listener: MeasureCacheListener): () => void\n}\n\nexport function createMeasureCache(options: MeasureCacheOptions): MeasureCache {\n let itemCount = options.itemCount\n let estimate = options.estimate\n const measured = new Map<number, number>()\n let offsets: number[] | null = null\n let cachedTotal = 0\n const listeners = new Set<MeasureCacheListener>()\n\n const getEstimate = (index: number): number =>\n typeof estimate === 'number' ? estimate : estimate(index)\n\n const getItemSize = (index: number): number => {\n const m = measured.get(index)\n return m !== undefined ? m : getEstimate(index)\n }\n\n const rebuildOffsets = () => {\n if (offsets && offsets.length === itemCount) return\n const arr = new Array<number>(itemCount)\n let acc = 0\n for (let i = 0; i < itemCount; i++) {\n arr[i] = acc\n acc += getItemSize(i)\n }\n offsets = arr\n cachedTotal = acc\n }\n\n const getTotalHeight = (): number => {\n rebuildOffsets()\n return cachedTotal\n }\n\n const getItemOffset = (index: number): number => {\n if (index <= 0) return 0\n if (index >= itemCount) return getTotalHeight()\n rebuildOffsets()\n return offsets![index]!\n }\n\n const getItemAtOffset = (offset: number): number => {\n if (itemCount === 0) return 0\n rebuildOffsets()\n let lo = 0\n let hi = itemCount - 1\n while (lo < hi) {\n const mid = (lo + hi + 1) >>> 1\n if (offsets![mid]! <= offset) lo = mid\n else hi = mid - 1\n }\n return lo\n }\n\n const invalidate = (event: MeasureCacheEvent) => {\n offsets = null\n for (const l of listeners) l(event)\n }\n\n return {\n get itemCount() {\n return itemCount\n },\n get measuredCount() {\n return measured.size\n },\n\n setItemCount(count: number) {\n if (count === itemCount) return\n if (count < itemCount && measured.size > 0) {\n for (const k of [...measured.keys()]) {\n if (k >= count) measured.delete(k)\n }\n }\n itemCount = count\n invalidate('resize')\n },\n\n setEstimate(e: number | ((index: number) => number)) {\n estimate = e\n invalidate('reset')\n },\n\n setMeasuredHeight(index: number, height: number): boolean {\n if (index < 0 || index >= itemCount) return false\n if (!Number.isFinite(height) || height < 0) return false\n const prev = measured.get(index)\n if (prev === height) return false\n measured.set(index, height)\n invalidate('measure')\n return true\n },\n\n clearMeasured(index: number): boolean {\n const had = measured.delete(index)\n if (had) invalidate('measure')\n return had\n },\n\n reset() {\n if (measured.size === 0) return\n measured.clear()\n invalidate('reset')\n },\n\n hasMeasured(index: number) {\n return measured.has(index)\n },\n getMeasuredHeight(index: number) {\n return measured.get(index)\n },\n\n getEstimatedSize: getEstimate,\n getItemSize,\n getItemOffset,\n getItemAtOffset,\n getTotalHeight,\n\n subscribe(listener: MeasureCacheListener) {\n listeners.add(listener)\n return () => {\n listeners.delete(listener)\n }\n },\n }\n}\n","import { createMeasureCache, type MeasureCache } from './measure'\n\nexport type {\n MeasureCache,\n MeasureCacheEvent,\n MeasureCacheListener,\n MeasureCacheOptions,\n} from './measure'\nexport { createMeasureCache } from './measure'\n\nexport interface VirtualRange {\n startIndex: number\n endIndex: number\n offsetTop: number\n totalHeight: number\n visibleItems: VirtualItem[]\n}\n\nexport interface VirtualItem {\n index: number\n offsetTop: number\n height: number\n}\n\n/** Событие инвалидации, эмитимое VirtualEngine подписчикам. */\nexport type VirtualEngineEvent = 'measure' | 'reset' | 'resize'\nexport type VirtualEngineListener = (event: VirtualEngineEvent) => void\n\nexport interface VirtualEngineOptions {\n itemCount: number\n itemHeight: number | ((index: number) => number)\n overscan?: number\n}\n\nexport interface VirtualEngine {\n readonly itemCount: number\n readonly totalHeight: number\n /** Сколько строк прошли через `setMeasuredHeight`. */\n readonly measuredCount: number\n\n setItemCount(count: number): void\n setItemHeight(height: number | ((index: number) => number)): void\n\n /**\n * Записать реально измеренную (через ResizeObserver) высоту строки.\n * Возвращает `true`, если значение изменилось — полезно для контроля\n * количества `setState` в адаптере.\n */\n setMeasuredHeight(index: number, height: number): boolean\n /** Сбросить измерение для одной строки (высота вернётся к эстимейту). */\n clearMeasuredHeight(index: number): boolean\n /** Сбросить все измерения (например, при resize контейнера / смене темы). */\n resetMeasurements(): void\n /** Был ли индекс уже измерён. */\n hasMeasured(index: number): boolean\n /** Эстимейт высоты строки без учёта измерений. */\n getEstimatedSize(index: number): number\n /** Эффективная высота строки — измерение, если есть, иначе эстимейт. */\n getItemSize(index: number): number\n\n getRange(scrollTop: number, viewportHeight: number): VirtualRange\n getItemOffset(index: number): number\n getItemAtOffset(offset: number): number\n scrollToIndex(\n index: number,\n viewportHeight: number,\n align?: 'start' | 'center' | 'end',\n ): number\n\n /**\n * Подписаться на инвалидации (resize / measure / reset). Вызывается\n * только после реального изменения — повторные `setMeasuredHeight`\n * с тем же значением событие не эмитят.\n */\n subscribe(listener: VirtualEngineListener): () => void\n}\n\nexport function createVirtual(options: VirtualEngineOptions): VirtualEngine {\n let itemCount = options.itemCount\n let itemHeight = options.itemHeight\n const overscan = options.overscan ?? 5\n\n // Кэш создаётся лениво — для чисто фиксированной высоты без измерений\n // нам он не нужен, и мы сохраняем O(1) арифметику для миллионов строк.\n let cache: MeasureCache | null = null\n const listeners = new Set<VirtualEngineListener>()\n\n const ensureCache = (): MeasureCache => {\n if (cache) return cache\n cache = createMeasureCache({ itemCount, estimate: itemHeight })\n cache.subscribe((event) => {\n for (const l of listeners) l(event)\n })\n return cache\n }\n\n const isFastPath = (): boolean =>\n typeof itemHeight === 'number' && (cache === null || cache.measuredCount === 0)\n\n const getEstimate = (index: number): number =>\n typeof itemHeight === 'number' ? itemHeight : itemHeight(index)\n\n const getItemSize = (index: number): number => {\n if (cache) return cache.getItemSize(index)\n return getEstimate(index)\n }\n\n const getTotalHeight = (): number => {\n if (isFastPath()) return itemCount * (itemHeight as number)\n return ensureCache().getTotalHeight()\n }\n\n const getItemOffset = (index: number): number => {\n if (index <= 0) return 0\n if (index >= itemCount) return getTotalHeight()\n if (isFastPath()) return index * (itemHeight as number)\n return ensureCache().getItemOffset(index)\n }\n\n const getItemAtOffset = (offset: number): number => {\n if (itemCount === 0) return 0\n if (isFastPath()) {\n const h = itemHeight as number\n return Math.min(Math.floor(offset / h), itemCount - 1)\n }\n return ensureCache().getItemAtOffset(offset)\n }\n\n const getRange = (scrollTop: number, viewportHeight: number): VirtualRange => {\n if (itemCount === 0) {\n return { startIndex: 0, endIndex: 0, offsetTop: 0, totalHeight: 0, visibleItems: [] }\n }\n\n const total = getTotalHeight()\n const rawStart = getItemAtOffset(scrollTop)\n const startIndex = Math.max(0, rawStart - overscan)\n\n let endIndex = rawStart\n let accHeight = getItemOffset(rawStart) + getItemSize(rawStart)\n const bottomEdge = scrollTop + viewportHeight\n\n while (endIndex < itemCount - 1 && accHeight < bottomEdge) {\n endIndex++\n accHeight += getItemSize(endIndex)\n }\n endIndex = Math.min(itemCount - 1, endIndex + overscan)\n\n const visibleItems: VirtualItem[] = []\n for (let i = startIndex; i <= endIndex; i++) {\n visibleItems.push({\n index: i,\n offsetTop: getItemOffset(i),\n height: getItemSize(i),\n })\n }\n\n return {\n startIndex,\n endIndex,\n offsetTop: getItemOffset(startIndex),\n totalHeight: total,\n visibleItems,\n }\n }\n\n const scrollToIndex = (\n index: number,\n viewportHeight: number,\n align: 'start' | 'center' | 'end' = 'start',\n ): number => {\n const clamped = Math.max(0, Math.min(index, itemCount - 1))\n const offset = getItemOffset(clamped)\n const h = getItemSize(clamped)\n\n switch (align) {\n case 'center':\n return Math.max(0, offset - viewportHeight / 2 + h / 2)\n case 'end':\n return Math.max(0, offset - viewportHeight + h)\n default:\n return offset\n }\n }\n\n const emit = (event: VirtualEngineEvent) => {\n for (const l of listeners) l(event)\n }\n\n return {\n get itemCount() {\n return itemCount\n },\n get totalHeight() {\n return getTotalHeight()\n },\n get measuredCount() {\n return cache?.measuredCount ?? 0\n },\n\n setItemCount(count: number) {\n if (count === itemCount) return\n itemCount = count\n if (cache) {\n cache.setItemCount(count)\n } else {\n emit('resize')\n }\n },\n\n setItemHeight(height: number | ((index: number) => number)) {\n itemHeight = height\n if (cache) {\n cache.setEstimate(height)\n } else {\n emit('reset')\n }\n },\n\n setMeasuredHeight(index: number, height: number) {\n return ensureCache().setMeasuredHeight(index, height)\n },\n\n clearMeasuredHeight(index: number) {\n if (!cache) return false\n return cache.clearMeasured(index)\n },\n\n resetMeasurements() {\n if (cache) cache.reset()\n },\n\n hasMeasured(index: number) {\n return cache ? cache.hasMeasured(index) : false\n },\n\n getEstimatedSize: getEstimate,\n getItemSize,\n\n getRange,\n getItemOffset,\n getItemAtOffset,\n scrollToIndex,\n\n subscribe(listener: VirtualEngineListener) {\n listeners.add(listener)\n return () => {\n listeners.delete(listener)\n }\n },\n }\n}\n","import type { Core } from './types'\n\n/**\n * Utility types for path-based type inference.\n * These provide compile-time type safety over the untyped Core runtime.\n */\n\ntype Primitive = string | number | boolean | null | undefined\n\n/**\n * Extracts dot-notation paths from a nested object type (max 3 levels deep).\n * Example: Path<{user: {name: string}}> = \"user\" | \"user.name\"\n */\nexport type Path<T> = T extends Primitive\n ? never\n : {\n [K in keyof T & string]: T[K] extends Primitive\n ? K\n : T[K] extends Record<string, unknown>\n ?\n | K\n | `${K}.${keyof T[K] & string}`\n | {\n [L in keyof T[K] & string]: T[K][L] extends Record<\n string,\n unknown\n >\n ? `${K}.${L}.${keyof T[K][L] & string}`\n : never\n }[keyof T[K] & string]\n : K\n }[keyof T & string]\n\n/**\n * Resolves the value type at a given dot-notation path (max 3 levels).\n */\nexport type PathValue<T, P extends string> = P extends keyof T\n ? T[P]\n : P extends `${infer K}.${infer Rest}`\n ? K extends keyof T\n ? Rest extends keyof T[K]\n ? T[K][Rest]\n : Rest extends `${infer L}.${infer M}`\n ? L extends keyof T[K]\n ? M extends keyof T[K][L]\n ? T[K][L][M]\n : unknown\n : unknown\n : unknown\n : unknown\n : unknown\n\n/**\n * Type-safe wrapper over Core.\n * Compile-time only — runtime behavior is identical to Core.\n */\nexport interface TypedCore<T> {\n get<K extends Path<T>>(path: K): PathValue<T, K>\n set<K extends Path<T>>(path: K, value: PathValue<T, K>): void\n subscribe<K extends Path<T>>(\n path: K,\n cb: (value: PathValue<T, K>) => void\n ): () => void\n batch(fn: () => void): void\n transaction(fn: () => void): void\n computed<K extends Path<T>>(\n target: K,\n deps: Path<T>[],\n fn: (...values: unknown[]) => PathValue<T, K>\n ): void\n /** Access the untyped core underneath */\n raw: Core\n}\n\n/**\n * Creates a type-safe wrapper around an existing Core instance.\n * No runtime overhead — just type narrowing.\n */\nexport function createTypedCore<T>(core: Core): TypedCore<T> {\n return {\n get: core.get.bind(core) as TypedCore<T>['get'],\n set: core.set.bind(core) as TypedCore<T>['set'],\n subscribe: core.subscribe.bind(core) as TypedCore<T>['subscribe'],\n batch: core.batch.bind(core),\n transaction: core.transaction.bind(core),\n computed: core.computed.bind(core) as TypedCore<T>['computed'],\n raw: core,\n }\n}\n","/**\n * Engine path namespace registry\n *\n * Every engine that stores state in the Core store under a `$`-prefixed\n * namespace MUST register its prefix here. This prevents two engines from\n * silently colliding on the same root path (e.g. two engines both writing\n * under `$meta.`).\n *\n * Rules:\n * 1. Prefixes MUST start with `$` and end with `.`.\n * 2. Prefixes MUST be unique across all engines.\n * 3. An engine MUST use `reservedPrefix(name)` at module load so\n * collisions surface at import time during dev/test.\n * 4. User data MUST NOT live under `$` prefixes — reserve them for engines.\n */\n\nconst reserved = new Map<string, string>()\n\n/**\n * Reserve (or look up) a prefix for an engine. Throws synchronously if the\n * same prefix is already owned by a different engine.\n */\nexport function reservePrefix(engine: string, prefix: string): string {\n if (!prefix.startsWith('$') || !prefix.endsWith('.')) {\n throw new Error(\n `[skygraph] engine \"${engine}\" tried to reserve invalid prefix \"${prefix}\". ` +\n `Engine prefixes must start with \"$\" and end with \".\".`,\n )\n }\n\n const existing = reserved.get(prefix)\n if (existing !== undefined && existing !== engine) {\n throw new Error(\n `[skygraph] prefix \"${prefix}\" is already owned by engine \"${existing}\", ` +\n `cannot reserve it for \"${engine}\". ` +\n `Pick a different prefix or update the registry.`,\n )\n }\n\n reserved.set(prefix, engine)\n return prefix\n}\n\n/** Snapshot of registered engine prefixes (debug / introspection). */\nexport function listReservedPrefixes(): ReadonlyMap<string, string> {\n return new Map(reserved)\n}\n\n/** Test-only helper. DO NOT call from engine code. */\nexport function __resetPrefixes(): void {\n reserved.clear()\n}\n\n// ── Canonical in-tree reservations ─────────────────────────────────────────\n//\n// Listed here so they are reserved even if the engine module is not loaded.\n// New engines must add their entry here and reference it from their\n// implementation via `reservePrefix(...)`.\n\nexport const FORM_META_PREFIX = reservePrefix('form', '$meta.')\nexport const TABLE_PREFIX = reservePrefix('table', '$table.')\nexport const TREE_PREFIX = reservePrefix('tree', '$tree.')\nexport const GRAPH_PREFIX = reservePrefix('graph', '$graph.')\nexport const CALENDAR_PREFIX = reservePrefix('calendar', '$calendar.')\n","import type { Core } from '../../types'\r\nimport type {\r\n FieldMeta,\r\n FieldOptions,\r\n FieldStatus,\r\n FormEngine,\r\n FormOptions,\r\n FormState,\r\n GetFieldValue,\r\n Rule,\r\n RuleFn,\r\n RuleObject,\r\n ValidationResult,\r\n} from './types'\r\n\r\nimport { FORM_META_PREFIX as META_PREFIX } from '../namespaces'\r\n\r\nfunction metaPath(name: string, field: string): string {\r\n return `${META_PREFIX}${name}.${field}`\r\n}\r\n\r\nfunction interpolateMessage(template: string, vars: Record<string, unknown>): string {\r\n return template.replace(/\\$\\{(\\w+)\\}/g, (_, key) => {\r\n return vars[key] != null ? String(vars[key]) : ''\r\n })\r\n}\r\n\r\nfunction compileRule(rule: Rule, templates?: Record<string, string>, fieldLabel?: string): RuleFn {\r\n if (typeof rule === 'function') return rule\r\n\r\n const obj = rule as RuleObject\r\n const vars: Record<string, unknown> = { label: fieldLabel ?? 'Field' }\r\n\r\n return (value: unknown, getFieldValue: GetFieldValue): string | null | Promise<string | null> => {\r\n if (obj.required) {\r\n if (value === undefined || value === null || value === '') {\r\n const tpl = templates?.required ?? obj.message\r\n return tpl ? interpolateMessage(tpl, vars) : (obj.message ?? 'This field is required')\r\n }\r\n }\r\n\r\n if (value === undefined || value === null || value === '') return null\r\n\r\n if (obj.type) {\r\n switch (obj.type) {\r\n case 'string':\r\n if (typeof value !== 'string') return obj.message ?? 'Must be a string'\r\n break\r\n case 'number':\r\n if (typeof value !== 'number' || isNaN(value)) return obj.message ?? 'Must be a number'\r\n break\r\n case 'email':\r\n if (typeof value !== 'string' || !/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(value))\r\n return obj.message ?? 'Invalid email'\r\n break\r\n case 'url':\r\n try {\r\n new URL(value as string)\r\n } catch {\r\n return obj.message ?? 'Invalid URL'\r\n }\r\n break\r\n case 'boolean':\r\n if (typeof value !== 'boolean') return obj.message ?? 'Must be a boolean'\r\n break\r\n }\r\n }\r\n\r\n if (obj.min !== undefined) {\r\n vars.min = obj.min\r\n if (typeof value === 'string' && value.length < obj.min) {\r\n const tpl = templates?.min ?? obj.message\r\n return tpl ? interpolateMessage(tpl, vars) : (obj.message ?? `Minimum ${obj.min} characters`)\r\n }\r\n if (typeof value === 'number' && value < obj.min)\r\n return obj.message ?? `Minimum value is ${obj.min}`\r\n }\r\n\r\n if (obj.max !== undefined) {\r\n vars.max = obj.max\r\n if (typeof value === 'string' && value.length > obj.max) {\r\n const tpl = templates?.max ?? obj.message\r\n return tpl ? interpolateMessage(tpl, vars) : (obj.message ?? `Maximum ${obj.max} characters`)\r\n }\r\n if (typeof value === 'number' && value > obj.max)\r\n return obj.message ?? `Maximum value is ${obj.max}`\r\n }\r\n\r\n if (obj.pattern) {\r\n if (typeof value === 'string' && !obj.pattern.test(value))\r\n return obj.message ?? 'Invalid format'\r\n }\r\n\r\n if (obj.validator) {\r\n return obj.validator(value, getFieldValue)\r\n }\r\n\r\n return null\r\n }\r\n}\r\n\r\nfunction computeStatus(meta: { errors: string[]; warnings: string[]; validating: boolean }): FieldStatus {\r\n if (meta.validating) return 'validating'\r\n if (meta.errors.length > 0) return 'error'\r\n if (meta.warnings.length > 0) return 'warning'\r\n return undefined\r\n}\r\n\r\ninterface CompiledRule {\r\n original: Rule\r\n fn: RuleFn\r\n}\r\n\r\ninterface FieldRecord {\r\n rules: CompiledRule[]\r\n warningRules: CompiledRule[]\r\n options: FieldOptions\r\n abortController: AbortController | null\r\n}\r\n\r\nexport function createForm(core: Core, options?: FormOptions): FormEngine {\r\n const fields = new Map<string, FieldRecord>()\r\n const depMap = new Map<string, string[]>()\r\n const debounceTimers = new Map<string, ReturnType<typeof setTimeout>>()\r\n const preservedValues = new Map<string, unknown>()\r\n let isSubmitting = false\r\n\r\n if (options?.defaultValues) {\r\n for (const [key, value] of Object.entries(options.defaultValues)) {\r\n core.set(key, value)\r\n }\r\n }\r\n\r\n function setMeta(name: string, meta: Partial<Record<string, unknown>>): void {\r\n for (const [key, value] of Object.entries(meta)) {\r\n core.set(metaPath(name, key), value)\r\n }\r\n }\r\n\r\n function getMeta(name: string): FieldMeta {\r\n const errors = (core.get(metaPath(name, 'errors')) as string[]) ?? []\r\n const warnings = (core.get(metaPath(name, 'warnings')) as string[]) ?? []\r\n const validating = (core.get(metaPath(name, 'validating')) as boolean) ?? false\r\n const touched = (core.get(metaPath(name, 'touched')) as boolean) ?? false\r\n const dirty = (core.get(metaPath(name, 'dirty')) as boolean) ?? false\r\n\r\n return {\r\n touched,\r\n dirty,\r\n errors,\r\n warnings,\r\n validating,\r\n status: computeStatus({ errors, warnings, validating }),\r\n error: errors[0] ?? null,\r\n }\r\n }\r\n\r\n function initMeta(name: string): void {\r\n setMeta(name, {\r\n touched: false,\r\n dirty: false,\r\n errors: [],\r\n warnings: [],\r\n validating: false,\r\n })\r\n }\r\n\r\n const getFieldValue: GetFieldValue = (fieldName: string) => core.get(fieldName)\r\n\r\n function fireValuesChange(changedName: string): void {\r\n if (!options?.onValuesChange) return\r\n const changed: Record<string, unknown> = { [changedName]: core.get(changedName) }\r\n const all: Record<string, unknown> = {}\r\n for (const n of fields.keys()) all[n] = core.get(n)\r\n options.onValuesChange(changed, all)\r\n }\r\n\r\n function fireFieldsChange(changedName: string): void {\r\n if (!options?.onFieldsChange) return\r\n const meta = getMeta(changedName)\r\n options.onFieldsChange([{\r\n name: changedName,\r\n value: core.get(changedName),\r\n errors: meta.errors,\r\n }])\r\n }\r\n\r\n async function runValidation(name: string): Promise<string[]> {\r\n const record = fields.get(name)\r\n if (!record) return []\r\n\r\n const value = core.get(name)\r\n const validateFirst = record.options.validateFirst ?? options?.validateFirst ?? false\r\n\r\n record.abortController?.abort()\r\n const controller = new AbortController()\r\n record.abortController = controller\r\n\r\n const errors: string[] = []\r\n\r\n for (const rule of record.rules) {\r\n if (controller.signal.aborted) return []\r\n\r\n const result = rule.fn(value, getFieldValue)\r\n\r\n if (result instanceof Promise) {\r\n setMeta(name, { validating: true })\r\n try {\r\n const asyncResult = await result\r\n if (controller.signal.aborted) return []\r\n if (asyncResult) {\r\n errors.push(asyncResult)\r\n if (validateFirst) break\r\n }\r\n } catch {\r\n if (controller.signal.aborted) return []\r\n errors.push('Validation failed')\r\n if (validateFirst) break\r\n }\r\n } else if (result) {\r\n errors.push(result)\r\n if (validateFirst) break\r\n }\r\n }\r\n\r\n const warnings: string[] = []\r\n for (const rule of record.warningRules) {\r\n if (controller.signal.aborted) return []\r\n const result = rule.fn(value, getFieldValue)\r\n if (result instanceof Promise) {\r\n try {\r\n const asyncResult = await result\r\n if (controller.signal.aborted) return []\r\n if (asyncResult) warnings.push(asyncResult)\r\n } catch {\r\n // skip\r\n }\r\n } else if (result) {\r\n warnings.push(result)\r\n }\r\n }\r\n\r\n if (!controller.signal.aborted) {\r\n setMeta(name, { errors, warnings, validating: false })\r\n fireFieldsChange(name)\r\n }\r\n\r\n return errors\r\n }\r\n\r\n async function validateDependents(name: string): Promise<void> {\r\n for (const [target, deps] of depMap) {\r\n if (deps.includes(name)) {\r\n await runValidation(target)\r\n }\r\n }\r\n }\r\n\r\n const form: FormEngine = {\r\n register(name: string, fieldOptions?: FieldOptions): void {\r\n const opts = fieldOptions ?? {}\r\n const templates = options?.validateMessages\r\n const label = opts.label\r\n\r\n fields.set(name, {\r\n rules: opts.rules\r\n ? opts.rules.map((r) => ({ original: r, fn: compileRule(r, templates, label) }))\r\n : [],\r\n warningRules: opts.warningRules\r\n ? opts.warningRules.map((r) => ({ original: r, fn: compileRule(r, templates, label) }))\r\n : [],\r\n options: opts,\r\n abortController: null,\r\n })\r\n\r\n if (preservedValues.has(name)) {\r\n core.set(name, preservedValues.get(name))\r\n preservedValues.delete(name)\r\n } else if (opts.defaultValue !== undefined && core.get(name) === undefined) {\r\n core.set(name, opts.defaultValue)\r\n }\r\n\r\n if (opts.dependencies) {\r\n depMap.set(name, [...opts.dependencies])\r\n }\r\n\r\n core.batch(() => {\r\n initMeta(name)\r\n })\r\n },\r\n\r\n unregister(name: string): void {\r\n const record = fields.get(name)\r\n if (!record) return\r\n record.abortController?.abort()\r\n\r\n const timer = debounceTimers.get(name)\r\n if (timer) {\r\n clearTimeout(timer)\r\n debounceTimers.delete(name)\r\n }\r\n\r\n if (record.options.preserve) {\r\n preservedValues.set(name, core.get(name))\r\n }\r\n\r\n fields.delete(name)\r\n depMap.delete(name)\r\n },\r\n\r\n setValue(name: string, value: unknown): void {\r\n core.transaction(() => {\r\n core.set(name, value)\r\n setMeta(name, { dirty: true, touched: true })\r\n })\r\n\r\n fireValuesChange(name)\r\n\r\n const mode = fields.get(name)?.options.validateOn ?? options?.validateOn ?? 'change'\r\n if (mode === 'change') {\r\n const debounceMs = options?.asyncDebounceMs\r\n if (debounceMs && debounceMs > 0) {\r\n const existing = debounceTimers.get(name)\r\n if (existing) clearTimeout(existing)\r\n debounceTimers.set(\r\n name,\r\n setTimeout(() => {\r\n debounceTimers.delete(name)\r\n runValidation(name).then(() => validateDependents(name))\r\n }, debounceMs),\r\n )\r\n } else {\r\n runValidation(name).then(() => validateDependents(name))\r\n }\r\n }\r\n },\r\n\r\n getValue(name: string): unknown {\r\n return core.get(name)\r\n },\r\n\r\n onFieldBlur(name: string): void {\r\n setMeta(name, { touched: true })\r\n const mode = fields.get(name)?.options.validateOn ?? options?.validateOn ?? 'change'\r\n if (mode === 'blur') {\r\n runValidation(name).then(() => validateDependents(name))\r\n }\r\n },\r\n\r\n setFieldsValue(values: Record<string, unknown>): void {\r\n core.batch(() => {\r\n for (const [name, value] of Object.entries(values)) {\r\n core.set(name, value)\r\n if (fields.has(name)) {\r\n setMeta(name, { dirty: true, touched: true })\r\n }\r\n }\r\n })\r\n\r\n for (const name of Object.keys(values)) {\r\n fireValuesChange(name)\r\n }\r\n },\r\n\r\n getFieldsValue(): Record<string, unknown> {\r\n const values: Record<string, unknown> = {}\r\n for (const name of fields.keys()) {\r\n values[name] = core.get(name)\r\n }\r\n return values\r\n },\r\n\r\n getFieldState(name: string): FieldMeta {\r\n return getMeta(name)\r\n },\r\n\r\n getFormState(): FormState {\r\n let isDirty = false\r\n let isValid = true\r\n let isValidating = false\r\n\r\n for (const name of fields.keys()) {\r\n const meta = getMeta(name)\r\n if (meta.dirty) isDirty = true\r\n if (meta.errors.length > 0) isValid = false\r\n if (meta.validating) isValidating = true\r\n }\r\n\r\n return { isDirty, isValid, isSubmitting, isValidating }\r\n },\r\n\r\n addRule(name: string, rule: Rule): void {\r\n const record = fields.get(name)\r\n if (!record) return\r\n record.rules.push({\r\n original: rule,\r\n fn: compileRule(rule, options?.validateMessages, record.options.label),\r\n })\r\n },\r\n\r\n removeRule(name: string, rule: Rule): void {\r\n const record = fields.get(name)\r\n if (!record) return\r\n const idx = record.rules.findIndex((r) => r.original === rule)\r\n if (idx !== -1) record.rules.splice(idx, 1)\r\n },\r\n\r\n depends(target: string, deps: string[]): void {\r\n depMap.set(target, [...deps])\r\n },\r\n\r\n async validate(name?: string): Promise<ValidationResult> {\r\n const errors: Record<string, string[]> = {}\r\n const warnings: Record<string, string[]> = {}\r\n\r\n if (name) {\r\n const errs = await runValidation(name)\r\n if (errs.length > 0) errors[name] = errs\r\n const meta = getMeta(name)\r\n if (meta.warnings.length > 0) warnings[name] = meta.warnings\r\n } else {\r\n const promises: Promise<void>[] = []\r\n for (const fieldName of fields.keys()) {\r\n promises.push(\r\n runValidation(fieldName).then((errs) => {\r\n if (errs.length > 0) errors[fieldName] = errs\r\n const meta = getMeta(fieldName)\r\n if (meta.warnings.length > 0) warnings[fieldName] = meta.warnings\r\n }),\r\n )\r\n }\r\n await Promise.all(promises)\r\n }\r\n\r\n return { valid: Object.keys(errors).length === 0, errors, warnings }\r\n },\r\n\r\n async submit(handler: (values: Record<string, unknown>) => Promise<void>): Promise<void> {\r\n isSubmitting = true\r\n\r\n core.batch(() => {\r\n for (const name of fields.keys()) {\r\n setMeta(name, { touched: true })\r\n }\r\n })\r\n\r\n const result = await form.validate()\r\n\r\n if (!result.valid) {\r\n isSubmitting = false\r\n return\r\n }\r\n\r\n const values: Record<string, unknown> = {}\r\n for (const name of fields.keys()) {\r\n values[name] = core.get(name)\r\n }\r\n\r\n try {\r\n await handler(values)\r\n } finally {\r\n isSubmitting = false\r\n }\r\n },\r\n\r\n reset(values?: Record<string, unknown>): void {\r\n core.batch(() => {\r\n for (const [name, record] of fields) {\r\n record.abortController?.abort()\r\n record.abortController = null\r\n\r\n const resetValue =\r\n values?.[name] ??\r\n options?.defaultValues?.[name] ??\r\n record.options.defaultValue ??\r\n undefined\r\n core.set(name, resetValue)\r\n initMeta(name)\r\n }\r\n })\r\n preservedValues.clear()\r\n },\r\n\r\n getFieldNames(): string[] {\r\n return [...fields.keys()]\r\n },\r\n\r\n // Manual error/warning control\r\n setFieldError(name: string, errs: string | string[]): void {\r\n const arr = typeof errs === 'string' ? [errs] : errs\r\n setMeta(name, { errors: arr })\r\n fireFieldsChange(name)\r\n },\r\n\r\n setFieldWarning(name: string, warns: string | string[]): void {\r\n const arr = typeof warns === 'string' ? [warns] : warns\r\n setMeta(name, { warnings: arr })\r\n },\r\n\r\n clearFieldErrors(name: string): void {\r\n setMeta(name, { errors: [], warnings: [] })\r\n fireFieldsChange(name)\r\n },\r\n\r\n getFieldErrors(name: string): string[] {\r\n return getMeta(name).errors\r\n },\r\n\r\n getFieldWarnings(name: string): string[] {\r\n return getMeta(name).warnings\r\n },\r\n\r\n isFieldTouched(name: string): boolean {\r\n return getMeta(name).touched\r\n },\r\n\r\n isFieldValidating(name: string): boolean {\r\n return getMeta(name).validating\r\n },\r\n\r\n // List operations\r\n getListValue(name: string): unknown[] {\r\n const val = core.get(name)\r\n return Array.isArray(val) ? val : []\r\n },\r\n\r\n listAdd(name: string, defaultValue?: unknown, insertIndex?: number): void {\r\n const current = form.getListValue(name)\r\n if (insertIndex !== undefined && insertIndex >= 0 && insertIndex <= current.length) {\r\n const next = [...current]\r\n next.splice(insertIndex, 0, defaultValue ?? null)\r\n core.set(name, next)\r\n } else {\r\n core.set(name, [...current, defaultValue ?? null])\r\n }\r\n },\r\n\r\n listRemove(name: string, index: number | number[]): void {\r\n const current = form.getListValue(name)\r\n if (Array.isArray(index)) {\r\n const indices = new Set(index)\r\n core.set(name, current.filter((_, i) => !indices.has(i)))\r\n } else {\r\n core.set(name, current.filter((_, i) => i !== index))\r\n }\r\n },\r\n\r\n listMove(name: string, from: number, to: number): void {\r\n const current = [...form.getListValue(name)]\r\n if (from < 0 || from >= current.length || to < 0 || to >= current.length) return\r\n const [item] = current.splice(from, 1)\r\n current.splice(to, 0, item)\r\n core.set(name, current)\r\n },\r\n\r\n listReplace(name: string, values: unknown[]): void {\r\n core.set(name, [...values])\r\n },\r\n }\r\n\r\n return form\r\n}\r\n","/**\r\n * Undo/redo history for `GraphEngine`.\r\n *\r\n * Snapshots are shallow: they capture the current `nodes` / `edges` arrays\r\n * plus the engine id counters. Because all mutating paths in `GraphEngine`\r\n * replace nodes/edges via `Map.set(id, { ...next })` (never in-place mutation),\r\n * a shallow array of references is enough to restore an exact prior state.\r\n *\r\n * The store/derived data (`edgesByNode`) is rebuilt from `edges` on restore —\r\n * keeping it out of the snapshot avoids subtle corruption if a future change\r\n * adds a derived index.\r\n */\r\nimport type { GraphEdge, GraphNode } from './types'\r\n\r\n/** Maximum number of entries kept in either undo or redo stack. */\r\nexport const HISTORY_LIMIT = 100\r\n\r\n/**\r\n * Immutable snapshot of the engine's state at a point in time.\r\n * Restoration is exact — including id counters so newly generated ids\r\n * don't collide with ids that existed in a future-then-undone state.\r\n */\r\nexport interface GraphSnapshot {\r\n readonly nodes: readonly GraphNode[]\r\n readonly edges: readonly GraphEdge[]\r\n readonly nodeCounter: number\r\n readonly edgeCounter: number\r\n}\r\n\r\n/** One entry on the undo or redo stack. */\r\nexport interface HistoryEntry {\r\n readonly snapshot: GraphSnapshot\r\n readonly label?: string\r\n}\r\n\r\nexport interface History {\r\n push(entry: HistoryEntry): void\r\n popUndo(): HistoryEntry | undefined\r\n popRedo(): HistoryEntry | undefined\r\n pushRedo(entry: HistoryEntry): void\r\n clearRedo(): void\r\n canUndo(): boolean\r\n canRedo(): boolean\r\n clear(): void\r\n /**\r\n * Replace the label on the most recent undo entry without disturbing\r\n * its snapshot. No-op when the stack is empty.\r\n */\r\n relabelTop(label: string | undefined): void\r\n /** Read-only label of the most recent undo entry (or `undefined`). */\r\n topLabel(): string | undefined\r\n /** @internal — for tests/introspection only. */\r\n size(): { undo: number; redo: number }\r\n}\r\n\r\n/**\r\n * Pure data store for the undo/redo stacks. The engine owns the capture /\r\n * restore semantics; this module only enforces the LIFO discipline and the\r\n * stack-size cap.\r\n */\r\nexport function createHistory(limit: number = HISTORY_LIMIT): History {\r\n const undoStack: HistoryEntry[] = []\r\n const redoStack: HistoryEntry[] = []\r\n\r\n function trim(stack: HistoryEntry[]): void {\r\n while (stack.length > limit) stack.shift()\r\n }\r\n\r\n return {\r\n push(entry) {\r\n undoStack.push(entry)\r\n trim(undoStack)\r\n },\r\n popUndo() {\r\n return undoStack.pop()\r\n },\r\n pushRedo(entry) {\r\n redoStack.push(entry)\r\n trim(redoStack)\r\n },\r\n popRedo() {\r\n return redoStack.pop()\r\n },\r\n clearRedo() {\r\n redoStack.length = 0\r\n },\r\n canUndo() {\r\n return undoStack.length > 0\r\n },\r\n canRedo() {\r\n return redoStack.length > 0\r\n },\r\n clear() {\r\n undoStack.length = 0\r\n redoStack.length = 0\r\n },\r\n relabelTop(label) {\r\n const top = undoStack[undoStack.length - 1]\r\n if (!top) return\r\n undoStack[undoStack.length - 1] = { snapshot: top.snapshot, label }\r\n },\r\n topLabel() {\r\n return undoStack[undoStack.length - 1]?.label\r\n },\r\n size() {\r\n return { undo: undoStack.length, redo: redoStack.length }\r\n },\r\n }\r\n}\r\n","import type { Core } from '../../types'\r\nimport { GRAPH_PREFIX } from '../namespaces'\r\nimport { createHistory, HISTORY_LIMIT, type HistoryEntry, type GraphSnapshot } from './history'\r\nimport type {\r\n AABB,\r\n Anchor,\r\n AnchorId,\r\n AnchorPolicy,\r\n EdgeEndpoint,\r\n EdgeId,\r\n EdgeInit,\r\n GraphEdge,\r\n GraphEngine,\r\n GraphEngineOptions,\r\n GraphNode,\r\n GraphState,\r\n NodeId,\r\n NodeInit,\r\n NodeTransform,\r\n NodeUpdate,\r\n OBB,\r\n Outline,\r\n Point,\r\n} from './types'\r\n\r\nlet engineCounter = 0\r\n\r\nconst DEFAULT_OUTLINE: Outline = { kind: 'rect', w: 100, h: 60 }\r\nconst DEFAULT_TRANSFORM: NodeTransform = { x: 0, y: 0 }\r\nconst DEFAULT_ANCHOR_POLICY: AnchorPolicy = { kind: 'perEdge', k: 1 }\r\n\r\n/**\r\n * Reactive diagram engine — the fourth member of the form / table / tree /\r\n * **graph** family. State is mirrored into the Core store under `$graph.`\r\n * for cross-engine coordination, but the in-memory maps are the source of\r\n * truth and the public read API.\r\n *\r\n * v0 scope (initial Graph engine stream — see CHANGELOG):\r\n * - Node / Edge model + parent hierarchy\r\n * - addNode / removeNode / updateNode / moveNode / setParent\r\n * - addEdge / removeEdge\r\n * - anchor generator (perEdge / byLength / manual)\r\n * - bounds computation (AABB, no rotation)\r\n * - geomRevision bump on geometry-affecting updates\r\n *\r\n * NOT in v0:\r\n * - orthogonal routing (with obstacle avoidance)\r\n * - undo / redo (covered separately by `plugins/history`)\r\n * - snap-to-grid, drag-and-drop palette\r\n * - rotated bounding boxes (OBB)\r\n */\r\nexport function createGraph(core: Core, options?: GraphEngineOptions): GraphEngine {\r\n const engineId = `g${engineCounter++}${options?.name ? `-${options.name}` : ''}`\r\n const prefix = GRAPH_PREFIX\r\n\r\n const nodes = new Map<NodeId, GraphNode>()\r\n const edges = new Map<EdgeId, GraphEdge>()\r\n const edgesByNode = new Map<NodeId, Set<EdgeId>>()\r\n\r\n let nodeCounter = 0\r\n let edgeCounter = 0\r\n\r\n // ─── Persistence + local subscribers ──────────────────────────────────────\r\n //\r\n // We mirror snapshots into the Core store so other engines / external\r\n // observers can react via `core.subscribe(...)`. We ALSO maintain a small\r\n // local subscriber set that React adapters use directly — that avoids\r\n // having to know the engineId-suffixed path from the outside.\r\n\r\n const localSubscribers = new Set<() => void>()\r\n\r\n function publishSnapshot() {\r\n core.set(`${prefix}snapshot.${engineId}`, {\r\n nodes: Array.from(nodes.values()),\r\n edges: Array.from(edges.values()),\r\n })\r\n for (const cb of localSubscribers) cb()\r\n }\r\n\r\n function subscribeLocal(cb: () => void): () => void {\r\n localSubscribers.add(cb)\r\n return () => {\r\n localSubscribers.delete(cb)\r\n }\r\n }\r\n\r\n publishSnapshot() // initial empty snapshot\r\n\r\n // ─── History (undo/redo) ──────────────────────────────────────────────────\r\n //\r\n // The engine wraps every mutating public method in `_withHistory`. The\r\n // wrapper captures the engine state on the OUTERMOST call (so nested\r\n // mutations — e.g. `removeNode` -> `removeEdge` — only contribute one\r\n // history entry) and pushes the captured snapshot to the undo stack on\r\n // commit. `transaction(fn)` is the public form of the same primitive,\r\n // letting callers batch unrelated mutations into a single entry.\r\n //\r\n // Restoration (`undo`/`redo`) sets `isRestoring = true` to suppress\r\n // history capture inside `_restoreState`.\r\n\r\n const history = createHistory(HISTORY_LIMIT)\r\n let transactionDepth = 0\r\n let pendingEntry: HistoryEntry | null = null\r\n let isRestoring = false\r\n\r\n function _captureState(): GraphSnapshot {\r\n return {\r\n nodes: Array.from(nodes.values()),\r\n edges: Array.from(edges.values()),\r\n nodeCounter,\r\n edgeCounter,\r\n }\r\n }\r\n\r\n function _restoreState(snapshot: GraphSnapshot): void {\r\n nodes.clear()\r\n edges.clear()\r\n edgesByNode.clear()\r\n for (const n of snapshot.nodes) {\r\n nodes.set(n.id, n)\r\n edgesByNode.set(n.id, new Set())\r\n }\r\n for (const e of snapshot.edges) {\r\n edges.set(e.id, e)\r\n ensureBucket(endpointNode(e.from)).add(e.id)\r\n ensureBucket(endpointNode(e.to)).add(e.id)\r\n }\r\n nodeCounter = snapshot.nodeCounter\r\n edgeCounter = snapshot.edgeCounter\r\n }\r\n\r\n function _withHistory<T>(fn: () => T, label?: string): T {\r\n if (isRestoring) return fn()\r\n const wasOuter = transactionDepth === 0\r\n if (wasOuter) {\r\n pendingEntry = { snapshot: _captureState(), label }\r\n } else if (label !== undefined && pendingEntry && pendingEntry.label === undefined) {\r\n pendingEntry = { snapshot: pendingEntry.snapshot, label }\r\n }\r\n transactionDepth++\r\n try {\r\n return fn()\r\n } finally {\r\n transactionDepth--\r\n if (transactionDepth === 0 && wasOuter) {\r\n if (pendingEntry !== null) {\r\n history.push(pendingEntry)\r\n history.clearRedo()\r\n }\r\n pendingEntry = null\r\n }\r\n }\r\n }\r\n\r\n // ─── Helpers ──────────────────────────────────────────────────────────────\r\n\r\n function newNodeId(): NodeId {\r\n return `${engineId}-n${nodeCounter++}`\r\n }\r\n\r\n function newEdgeId(): EdgeId {\r\n return `${engineId}-e${edgeCounter++}`\r\n }\r\n\r\n function ensureBucket(nodeId: NodeId): Set<EdgeId> {\r\n let bucket = edgesByNode.get(nodeId)\r\n if (!bucket) {\r\n bucket = new Set()\r\n edgesByNode.set(nodeId, bucket)\r\n }\r\n return bucket\r\n }\r\n\r\n function endpointNode(ep: EdgeEndpoint): NodeId {\r\n return ep.node\r\n }\r\n\r\n function bumpRevision(node: GraphNode): GraphNode {\r\n return { ...node, geomRevision: node.geomRevision + 1 }\r\n }\r\n\r\n // ─── Node operations ──────────────────────────────────────────────────────\r\n //\r\n // The `_impl` functions are the raw mutators. The exported `addNode` /\r\n // `removeNode` / ... wrap them in `_withHistory` so the public surface\r\n // automatically participates in undo/redo. Internal calls between\r\n // mutators (e.g. `removeNode` → `removeEdge`) go through the wrapped\r\n // form too, but `_withHistory` recognizes nested transactions and only\r\n // commits one entry.\r\n\r\n function _addNodeImpl(init: NodeInit = {}): NodeId {\r\n const id = init.id ?? newNodeId()\r\n if (nodes.has(id)) {\r\n throw new Error(`[skygraph/graph] node id \"${id}\" already exists`)\r\n }\r\n const node: GraphNode = {\r\n id,\r\n parentId: init.parentId ?? null,\r\n transform: init.transform ?? { ...DEFAULT_TRANSFORM },\r\n outline: init.outline ?? DEFAULT_OUTLINE,\r\n anchorPolicy: init.anchorPolicy ?? DEFAULT_ANCHOR_POLICY,\r\n data: init.data,\r\n geomRevision: 0,\r\n }\r\n nodes.set(id, node)\r\n edgesByNode.set(id, new Set())\r\n publishSnapshot()\r\n return id\r\n }\r\n\r\n function addNode(init: NodeInit = {}): NodeId {\r\n return _withHistory(() => _addNodeImpl(init))\r\n }\r\n\r\n function _removeNodeImpl(id: NodeId): void {\r\n if (!nodes.has(id)) return\r\n const incident = edgesByNode.get(id)\r\n if (incident) {\r\n for (const eid of incident) removeEdge(eid)\r\n }\r\n // re-parent any children to root (do not orphan them)\r\n for (const [otherId, n] of nodes) {\r\n if (n.parentId === id) {\r\n nodes.set(otherId, { ...n, parentId: null })\r\n }\r\n }\r\n nodes.delete(id)\r\n edgesByNode.delete(id)\r\n publishSnapshot()\r\n }\r\n\r\n function removeNode(id: NodeId): void {\r\n _withHistory(() => _removeNodeImpl(id))\r\n }\r\n\r\n function _updateNodeImpl(id: NodeId, patch: NodeUpdate): void {\r\n const node = nodes.get(id)\r\n if (!node) {\r\n throw new Error(`[skygraph/graph] node \"${id}\" not found`)\r\n }\r\n const next: GraphNode = {\r\n ...node,\r\n transform: patch.transform ? { ...node.transform, ...patch.transform } : node.transform,\r\n outline: patch.outline ?? node.outline,\r\n anchorPolicy: patch.anchorPolicy ?? node.anchorPolicy,\r\n data: patch.data === undefined ? node.data : patch.data,\r\n }\r\n const geomChanged =\r\n patch.transform !== undefined ||\r\n patch.outline !== undefined ||\r\n patch.anchorPolicy !== undefined\r\n nodes.set(id, geomChanged ? bumpRevision(next) : next)\r\n publishSnapshot()\r\n }\r\n\r\n function updateNode(id: NodeId, patch: NodeUpdate): void {\r\n _withHistory(() => _updateNodeImpl(id, patch))\r\n }\r\n\r\n function moveNode(id: NodeId, x: number, y: number): void {\r\n _withHistory(() => _updateNodeImpl(id, { transform: { x, y } }))\r\n }\r\n\r\n function _setParentImpl(id: NodeId, parentId: NodeId | null): void {\r\n const node = nodes.get(id)\r\n if (!node) {\r\n throw new Error(`[skygraph/graph] node \"${id}\" not found`)\r\n }\r\n if (parentId !== null && !nodes.has(parentId)) {\r\n throw new Error(`[skygraph/graph] parent node \"${parentId}\" not found`)\r\n }\r\n if (parentId === id) {\r\n throw new Error(`[skygraph/graph] node cannot be its own parent (\"${id}\")`)\r\n }\r\n // cycle check — walk up the chain to make sure we don't introduce a loop\r\n let cursor: NodeId | null = parentId\r\n while (cursor !== null) {\r\n if (cursor === id) {\r\n throw new Error(`[skygraph/graph] setParent would create a cycle (\"${id}\" → \"${parentId}\")`)\r\n }\r\n cursor = nodes.get(cursor)?.parentId ?? null\r\n }\r\n nodes.set(id, { ...node, parentId })\r\n publishSnapshot()\r\n }\r\n\r\n function setParent(id: NodeId, parentId: NodeId | null): void {\r\n _withHistory(() => _setParentImpl(id, parentId))\r\n }\r\n\r\n // ─── Edge operations ──────────────────────────────────────────────────────\r\n\r\n function _addEdgeImpl(init: EdgeInit): EdgeId {\r\n const id = init.id ?? newEdgeId()\r\n if (edges.has(id)) {\r\n throw new Error(`[skygraph/graph] edge id \"${id}\" already exists`)\r\n }\r\n const fromId = endpointNode(init.from)\r\n const toId = endpointNode(init.to)\r\n if (!nodes.has(fromId)) {\r\n throw new Error(`[skygraph/graph] addEdge: from-node \"${fromId}\" not found`)\r\n }\r\n if (!nodes.has(toId)) {\r\n throw new Error(`[skygraph/graph] addEdge: to-node \"${toId}\" not found`)\r\n }\r\n const edge: GraphEdge = {\r\n id,\r\n from: init.from,\r\n to: init.to,\r\n routing: init.routing ?? 'straight',\r\n waypoints: init.waypoints,\r\n data: init.data,\r\n }\r\n edges.set(id, edge)\r\n ensureBucket(fromId).add(id)\r\n ensureBucket(toId).add(id)\r\n publishSnapshot()\r\n return id\r\n }\r\n\r\n function addEdge(init: EdgeInit): EdgeId {\r\n return _withHistory(() => _addEdgeImpl(init))\r\n }\r\n\r\n function _removeEdgeImpl(id: EdgeId): void {\r\n const edge = edges.get(id)\r\n if (!edge) return\r\n edgesByNode.get(endpointNode(edge.from))?.delete(id)\r\n edgesByNode.get(endpointNode(edge.to))?.delete(id)\r\n edges.delete(id)\r\n publishSnapshot()\r\n }\r\n\r\n function removeEdge(id: EdgeId): void {\r\n _withHistory(() => _removeEdgeImpl(id))\r\n }\r\n\r\n // ─── Read API ─────────────────────────────────────────────────────────────\r\n\r\n function getNode(id: NodeId): GraphNode | undefined {\r\n return nodes.get(id)\r\n }\r\n\r\n function getEdge(id: EdgeId): GraphEdge | undefined {\r\n return edges.get(id)\r\n }\r\n\r\n function getState(): GraphState {\r\n const byNode = new Map<NodeId, readonly EdgeId[]>()\r\n for (const [nid, set] of edgesByNode) byNode.set(nid, Array.from(set))\r\n return {\r\n nodes: new Map(nodes),\r\n edges: new Map(edges),\r\n edgesByNode: byNode,\r\n }\r\n }\r\n\r\n function childrenOf(id: NodeId | null): NodeId[] {\r\n const out: NodeId[] = []\r\n for (const n of nodes.values()) {\r\n if (n.parentId === id) out.push(n.id)\r\n }\r\n return out\r\n }\r\n\r\n function edgesOf(id: NodeId): EdgeId[] {\r\n return Array.from(edgesByNode.get(id) ?? [])\r\n }\r\n\r\n // ─── Anchor generator ────────────────────────────────────────────────────\r\n //\r\n // Anchor IDs are deterministic functions of (outline kind, anchor policy).\r\n // Bumping `k` keeps existing anchors stable: corner ids never change, and\r\n // mid-edge anchor ids include the current `k` so callers can re-bind by\r\n // perimeter parameter `s` if they care about stability under k changes.\r\n\r\n function rectCornerId(corner: 'nw' | 'ne' | 'se' | 'sw'): AnchorId {\r\n return corner\r\n }\r\n\r\n function rectAnchors(w: number, h: number, policy: AnchorPolicy): Anchor[] {\r\n const corners: Anchor[] = [\r\n { id: rectCornerId('nw'), s: 0, point: [0, 0] },\r\n { id: rectCornerId('ne'), s: 0.25, point: [w, 0] },\r\n { id: rectCornerId('se'), s: 0.5, point: [w, h] },\r\n { id: rectCornerId('sw'), s: 0.75, point: [0, h] },\r\n ]\r\n if (policy.kind === 'manual') {\r\n return policy.anchors.map(a => ({\r\n id: a.id,\r\n s: a.s,\r\n point: pointOnRectPerimeter(w, h, a.s),\r\n }))\r\n }\r\n\r\n const k = policy.kind === 'perEdge' ? Math.max(0, Math.floor(policy.k)) : null\r\n const density = policy.kind === 'byLength' ? policy.density : null\r\n\r\n const out: Anchor[] = [...corners]\r\n // four edges, in clockwise order — n, e, s, w\r\n const edgesGeom: Array<{ start: number; end: number }> = [\r\n { start: 0, end: 0.25 }, // top\r\n { start: 0.25, end: 0.5 }, // right\r\n { start: 0.5, end: 0.75 }, // bottom\r\n { start: 0.75, end: 1 }, // left\r\n ]\r\n edgesGeom.forEach((edge, edgeIdx) => {\r\n let count = 0\r\n if (k !== null) count = k\r\n if (density !== null) {\r\n const len = edgeIdx % 2 === 0 ? w : h\r\n count = Math.max(0, Math.floor(len / density) - 1)\r\n }\r\n for (let i = 1; i <= count; i++) {\r\n const t = i / (count + 1)\r\n const s = edge.start + (edge.end - edge.start) * t\r\n out.push({\r\n id: `edge${edgeIdx}-${i}of${count}`,\r\n s,\r\n point: pointOnRectPerimeter(w, h, s),\r\n })\r\n }\r\n })\r\n out.sort((a, b) => a.s - b.s)\r\n return out\r\n }\r\n\r\n function pointOnRectPerimeter(w: number, h: number, s: number): Point {\r\n // s ∈ [0..1) traversing nw→ne→se→sw→nw\r\n const ss = ((s % 1) + 1) % 1\r\n if (ss < 0.25) return [w * (ss / 0.25), 0]\r\n if (ss < 0.5) return [w, h * ((ss - 0.25) / 0.25)]\r\n if (ss < 0.75) return [w * (1 - (ss - 0.5) / 0.25), h]\r\n return [0, h * (1 - (ss - 0.75) / 0.25)]\r\n }\r\n\r\n function polygonAnchors(verts: readonly Point[], policy: AnchorPolicy): Anchor[] {\r\n if (verts.length === 0) return []\r\n // total perimeter\r\n const segLengths: number[] = []\r\n let total = 0\r\n for (let i = 0; i < verts.length; i++) {\r\n const a = verts[i]\r\n const b = verts[(i + 1) % verts.length]\r\n const dx = b[0] - a[0]\r\n const dy = b[1] - a[1]\r\n const len = Math.hypot(dx, dy)\r\n segLengths.push(len)\r\n total += len\r\n }\r\n const cumS: number[] = [0]\r\n for (let i = 0; i < segLengths.length; i++) {\r\n cumS.push(cumS[i]! + segLengths[i]! / total)\r\n }\r\n\r\n function pointAt(s: number): Point {\r\n const ss = ((s % 1) + 1) % 1\r\n // find segment\r\n let i = 0\r\n while (i < cumS.length - 1 && cumS[i + 1]! <= ss) i++\r\n const a = verts[i % verts.length]\r\n const b = verts[(i + 1) % verts.length]\r\n const segS0 = cumS[i]!\r\n const segS1 = cumS[i + 1]!\r\n const t = segS1 === segS0 ? 0 : (ss - segS0) / (segS1 - segS0)\r\n return [a[0] + (b[0] - a[0]) * t, a[1] + (b[1] - a[1]) * t]\r\n }\r\n\r\n if (policy.kind === 'manual') {\r\n return policy.anchors.map(a => ({ id: a.id, s: a.s, point: pointAt(a.s) }))\r\n }\r\n\r\n const out: Anchor[] = []\r\n // vertices always become anchors\r\n for (let i = 0; i < verts.length; i++) {\r\n out.push({\r\n id: `v${i}`,\r\n s: cumS[i]!,\r\n point: [verts[i]![0], verts[i]![1]],\r\n })\r\n }\r\n\r\n const k = policy.kind === 'perEdge' ? Math.max(0, Math.floor(policy.k)) : null\r\n const density = policy.kind === 'byLength' ? policy.density : null\r\n\r\n for (let i = 0; i < verts.length; i++) {\r\n const segLen = segLengths[i]!\r\n let count = 0\r\n if (k !== null) count = k\r\n if (density !== null) count = Math.max(0, Math.floor(segLen / density) - 1)\r\n const s0 = cumS[i]!\r\n const s1 = cumS[i + 1]!\r\n for (let j = 1; j <= count; j++) {\r\n const t = j / (count + 1)\r\n const s = s0 + (s1 - s0) * t\r\n out.push({ id: `v${i}-${j}of${count}`, s, point: pointAt(s) })\r\n }\r\n }\r\n out.sort((a, b) => a.s - b.s)\r\n return out\r\n }\r\n\r\n function ellipseAnchors(rx: number, ry: number, policy: AnchorPolicy): Anchor[] {\r\n function pointAt(s: number): Point {\r\n const angle = ((s % 1) + 1) % 1 * Math.PI * 2\r\n return [rx * Math.cos(angle), ry * Math.sin(angle)]\r\n }\r\n if (policy.kind === 'manual') {\r\n return policy.anchors.map(a => ({ id: a.id, s: a.s, point: pointAt(a.s) }))\r\n }\r\n const k = policy.kind === 'perEdge' ? Math.max(1, Math.floor(policy.k)) : null\r\n // density-by-arc is approximate; uniform-by-angle is good enough for v0.\r\n const totalSamples = k !== null\r\n ? Math.max(4, k * 4)\r\n : Math.max(4, Math.floor((2 * Math.PI * Math.max(rx, ry)) / (policy as { kind: 'byLength'; density: number }).density))\r\n const out: Anchor[] = []\r\n for (let i = 0; i < totalSamples; i++) {\r\n const s = i / totalSamples\r\n out.push({ id: `el${i}of${totalSamples}`, s, point: pointAt(s) })\r\n }\r\n return out\r\n }\r\n\r\n function anchorsOf(id: NodeId): Anchor[] {\r\n const node = nodes.get(id)\r\n if (!node) return []\r\n const o = node.outline\r\n if (o.kind === 'rect') return rectAnchors(o.w, o.h, node.anchorPolicy)\r\n if (o.kind === 'polygon') return polygonAnchors(o.verts, node.anchorPolicy)\r\n if (o.kind === 'ellipse') return ellipseAnchors(o.rx, o.ry, node.anchorPolicy)\r\n if (o.kind === 'path') return polygonAnchors(o.flatten, node.anchorPolicy)\r\n return []\r\n }\r\n\r\n // ─── Bounds (AABB in world space — no rotation in v0) ────────────────────\r\n\r\n function localBounds(node: GraphNode): { x0: number; y0: number; x1: number; y1: number } {\r\n const o = node.outline\r\n if (o.kind === 'rect') return { x0: 0, y0: 0, x1: o.w, y1: o.h }\r\n if (o.kind === 'ellipse') return { x0: -o.rx, y0: -o.ry, x1: o.rx, y1: o.ry }\r\n const verts = o.kind === 'polygon' ? o.verts : o.flatten\r\n if (verts.length === 0) return { x0: 0, y0: 0, x1: 0, y1: 0 }\r\n let x0 = verts[0]![0]\r\n let x1 = verts[0]![0]\r\n let y0 = verts[0]![1]\r\n let y1 = verts[0]![1]\r\n for (const [x, y] of verts) {\r\n if (x < x0) x0 = x\r\n if (x > x1) x1 = x\r\n if (y < y0) y0 = y\r\n if (y > y1) y1 = y\r\n }\r\n return { x0, y0, x1, y1 }\r\n }\r\n\r\n function worldOriginOf(id: NodeId): { x: number; y: number; scale: number } {\r\n let cursor: NodeId | null = id\r\n let x = 0\r\n let y = 0\r\n let scale = 1\r\n while (cursor !== null) {\r\n const n = nodes.get(cursor)\r\n if (!n) break\r\n const s = n.transform.scale ?? 1\r\n x = n.transform.x + x * s\r\n y = n.transform.y + y * s\r\n scale *= s\r\n cursor = n.parentId\r\n }\r\n return { x, y, scale }\r\n }\r\n\r\n function boundsOf(id: NodeId): AABB {\r\n const node = nodes.get(id)\r\n if (!node) return { x: 0, y: 0, w: 0, h: 0 }\r\n const lb = localBounds(node)\r\n const origin = worldOriginOf(id)\r\n const w = (lb.x1 - lb.x0) * origin.scale\r\n const h = (lb.y1 - lb.y0) * origin.scale\r\n return {\r\n x: origin.x + lb.x0 * origin.scale,\r\n y: origin.y + lb.y0 * origin.scale,\r\n w,\r\n h,\r\n }\r\n }\r\n\r\n /**\r\n * Oriented bounding box in world space.\r\n *\r\n * v0 simplification: rotation is composed by summing `transform.rot`\r\n * along the parent chain (treating ancestors as if their rotations\r\n * commuted). For a single rotated node this is exact; for nested rotated\r\n * groups the centre / angle remain a useful approximation suitable for\r\n * selection overlays. Tighter OBB composition (full affine product)\r\n * lands when the engine grows a proper world-matrix cache.\r\n */\r\n function getNodeOBB(id: NodeId): OBB {\r\n const node = nodes.get(id)\r\n if (!node) return { center: [0, 0], halfWidth: 0, halfHeight: 0, angle: 0 }\r\n const lb = localBounds(node)\r\n const origin = worldOriginOf(id)\r\n const localCx = (lb.x0 + lb.x1) / 2\r\n const localCy = (lb.y0 + lb.y1) / 2\r\n const halfWidth = Math.abs((lb.x1 - lb.x0) / 2 * origin.scale)\r\n const halfHeight = Math.abs((lb.y1 - lb.y0) / 2 * origin.scale)\r\n let angle = 0\r\n let cursor: NodeId | null = id\r\n while (cursor !== null) {\r\n const n = nodes.get(cursor)\r\n if (!n) break\r\n angle += n.transform.rot ?? 0\r\n cursor = n.parentId\r\n }\r\n const center: Point = [\r\n origin.x + localCx * origin.scale,\r\n origin.y + localCy * origin.scale,\r\n ]\r\n return { center, halfWidth, halfHeight, angle }\r\n }\r\n\r\n function clear(): void {\r\n nodes.clear()\r\n edges.clear()\r\n edgesByNode.clear()\r\n nodeCounter = 0\r\n edgeCounter = 0\r\n history.clear()\r\n pendingEntry = null\r\n transactionDepth = 0\r\n isRestoring = false\r\n publishSnapshot()\r\n }\r\n\r\n // ─── Public history API ──────────────────────────────────────────────────\r\n\r\n function transaction(fn: () => void, label?: string): void {\r\n _withHistory(fn, label)\r\n }\r\n\r\n function pushHistory(label?: string): void {\r\n if (transactionDepth > 0) {\r\n // Inside a transaction: commit the current pending entry as a sub-\r\n // boundary, then start a fresh capture for the remainder of the\r\n // transaction. This lets a single `transaction(fn)` produce more\r\n // than one undo entry — useful when a batch operation has natural\r\n // sub-steps (`}; { ` between groups).\r\n if (pendingEntry !== null) {\r\n history.push({ snapshot: pendingEntry.snapshot, label: pendingEntry.label ?? label })\r\n history.clearRedo()\r\n }\r\n pendingEntry = { snapshot: _captureState(), label: undefined }\r\n return\r\n }\r\n // Standalone: re-label the most recent undo entry. We DO NOT push a\r\n // duplicate snapshot of the current state — auto-push has already\r\n // captured every meaningful boundary, so an extra standalone push\r\n // would just clutter the stack with no-op entries that consume undo\r\n // slots without changing visible state. Re-labeling is the useful\r\n // bit you can't get any other way outside a transaction.\r\n history.relabelTop(label)\r\n }\r\n\r\n function undo(): boolean {\r\n if (!history.canUndo()) return false\r\n const entry = history.popUndo()!\r\n history.pushRedo({ snapshot: _captureState(), label: entry.label })\r\n isRestoring = true\r\n try {\r\n _restoreState(entry.snapshot)\r\n } finally {\r\n isRestoring = false\r\n }\r\n publishSnapshot()\r\n return true\r\n }\r\n\r\n function redo(): boolean {\r\n if (!history.canRedo()) return false\r\n const entry = history.popRedo()!\r\n history.push({ snapshot: _captureState(), label: entry.label })\r\n isRestoring = true\r\n try {\r\n _restoreState(entry.snapshot)\r\n } finally {\r\n isRestoring = false\r\n }\r\n publishSnapshot()\r\n return true\r\n }\r\n\r\n function canUndo(): boolean {\r\n return history.canUndo()\r\n }\r\n\r\n function canRedo(): boolean {\r\n return history.canRedo()\r\n }\r\n\r\n function clearHistory(): void {\r\n history.clear()\r\n }\r\n\r\n return {\r\n addNode,\r\n removeNode,\r\n updateNode,\r\n moveNode,\r\n setParent,\r\n addEdge,\r\n removeEdge,\r\n getNode,\r\n getEdge,\r\n getState,\r\n childrenOf,\r\n edgesOf,\r\n anchorsOf,\r\n boundsOf,\r\n getNodeOBB,\r\n subscribe: subscribeLocal,\r\n transaction,\r\n pushHistory,\r\n undo,\r\n redo,\r\n canUndo,\r\n canRedo,\r\n clearHistory,\r\n clear,\r\n }\r\n}\r\n","import type { AABB, Point } from './types'\r\n\r\n/**\r\n * Orthogonal-routing module.\r\n *\r\n * Two strategies share one entry point — `routeOrthogonal`:\r\n *\r\n * 1. **L-route fallback** (no obstacles): a single-bend right-angle path.\r\n * Cheap, deterministic, and good enough for the \"two free-floating\r\n * nodes\" case.\r\n *\r\n * 2. **A* on a uniform grid** (with obstacles): when the caller passes\r\n * `obstacles`, the router discretises world space into a grid of step\r\n * `gridSize` (default 10) and runs a 4-connected A* with a turn\r\n * penalty so the search prefers long straight runs. The result is a\r\n * polyline whose interior bends are all axis-aligned right angles\r\n * and which never enters the interior of any obstacle.\r\n *\r\n * Both strategies share a common output shape: a `readonly Point[]`\r\n * with the original `start` as the first element and the original `end`\r\n * as the last. Consumers (e.g. `<Diagram>`) feed it straight to\r\n * `pointsToPath`.\r\n *\r\n * **`sourceBounds` / `targetBounds` (since 3.3c).** When the caller knows\r\n * which axis-aligned rectangle each endpoint sits on, the router will\r\n * pick the side of the rectangle nearest to the *other* endpoint and\r\n * extend a short perpendicular stub away from the node. That keeps edges\r\n * from sliding diagonally out of corner-anchors (`s = 0.25` / `s = 0.75`)\r\n * and from immediately re-entering the node they just exited — both of\r\n * which were visible in the Workflow Editor showcase prior to 3.3c.\r\n *\r\n * The router is intentionally pure — no engine state, no React, no DOM —\r\n * so it can be tested in isolation and reused outside of `<Diagram>`\r\n * (e.g. server-side path pre-computation).\r\n */\r\n\r\n/** Direction the previous step entered the current cell from. */\r\ntype Dir = 'h' | 'v' | null\r\n\r\n/** Side of an AABB the route exits through. */\r\nexport type RectSide = 'top' | 'right' | 'bottom' | 'left'\r\n\r\n/** Options for {@link routeOrthogonal}. */\r\nexport interface RouteOrthogonalOptions {\r\n /**\r\n * Bend preference for the no-obstacle case.\r\n * - `auto` (default) picks H-then-V or V-then-H based on which leg is longer.\r\n * - `hv` forces horizontal first.\r\n * - `vh` forces vertical first.\r\n *\r\n * Ignored when `obstacles` is non-empty — A* picks bends from costs.\r\n */\r\n preferred?: 'auto' | 'hv' | 'vh'\r\n /**\r\n * Rectangular obstacles to avoid (in world coordinates). When omitted /\r\n * empty, the router takes the cheap L-route path.\r\n */\r\n obstacles?: readonly AABB[]\r\n /**\r\n * Discretisation step for A*. Smaller values give smoother paths at the\r\n * cost of more search nodes. Default: 10.\r\n */\r\n gridSize?: number\r\n /**\r\n * Inflate every obstacle by this margin (world units) before clipping.\r\n * Useful to keep edges from hugging node borders. Default: 0.\r\n */\r\n inflate?: number\r\n /**\r\n * Hard cap on A* expansions. Acts as a safety net so a pathological\r\n * search never hangs the renderer. Default: 5000.\r\n */\r\n maxNodes?: number\r\n /**\r\n * AABB of the source node. When provided, the route exits the side of\r\n * the rectangle nearest to `end` with a short perpendicular stub. The\r\n * raw `start` point is kept as the first polyline vertex so the edge\r\n * still meets the anchor exactly.\r\n */\r\n sourceBounds?: AABB\r\n /**\r\n * AABB of the target node. When provided, the route enters the side of\r\n * the rectangle nearest to `start` with a short perpendicular stub. The\r\n * raw `end` point is kept as the last polyline vertex.\r\n */\r\n targetBounds?: AABB\r\n /**\r\n * Length (world units) of the perpendicular stub generated when\r\n * `sourceBounds` / `targetBounds` is set. Defaults to `max(8, gridSize)`.\r\n */\r\n stubLength?: number\r\n /**\r\n * Snap intermediate waypoints to a grid of this step. Defaults to the\r\n * effective `gridSize`. Set to `0` to disable snapping in the no-\r\n * obstacle path. A* already operates on the grid so this option only\r\n * affects the L-route fallback.\r\n */\r\n snap?: number\r\n}\r\n\r\n/**\r\n * Compute an orthogonal (right-angled) path between two points.\r\n *\r\n * - With no `sourceBounds` / `targetBounds` and no obstacles: a single-\r\n * bend L-route, identical to the v0 implementation.\r\n * - With `sourceBounds` / `targetBounds`: the route exits/enters from\r\n * the side of each rectangle nearest to the other endpoint.\r\n * - With obstacles: 4-connected A* on a grid of step `gridSize`. Uses\r\n * a turn penalty so straight runs are preferred. Falls back to the\r\n * L-route if A* cannot find a path within `maxNodes` expansions or\r\n * either endpoint is unreachable.\r\n *\r\n * The third argument also accepts the legacy bare-string form\r\n * (`'auto' | 'hv' | 'vh'`) for backwards compatibility with the v0 API.\r\n */\r\nexport function routeOrthogonal(\r\n start: Point,\r\n end: Point,\r\n options?: RouteOrthogonalOptions | 'auto' | 'hv' | 'vh',\r\n): readonly Point[] {\r\n const opts: RouteOrthogonalOptions =\r\n typeof options === 'string' ? { preferred: options } : (options ?? {})\r\n\r\n const gridSize = opts.gridSize ?? 10\r\n const stubLength = opts.stubLength ?? Math.max(8, gridSize)\r\n\r\n // ─── Step 1. Derive the \"approach points\" from optional bounds ────────────\r\n // Each approach point lives at the centre of the side of the source/\r\n // target rectangle that is closest to the other endpoint. We extend a\r\n // short perpendicular stub OUTWARDS from the rectangle so the rendered\r\n // edge has at least one straight segment exiting/entering the node.\r\n\r\n let sExit: Point | null = null\r\n let sStub: Point | null = null\r\n let sCorner: Point | null = null\r\n if (opts.sourceBounds) {\r\n const exitInfo = exitOnNearestSide(opts.sourceBounds, end)\r\n sExit = exitInfo.point\r\n sStub = extrudePoint(exitInfo.point, exitInfo.side, stubLength)\r\n // Bridge from the raw anchor (which may sit anywhere on the\r\n // outline — corner anchors like `s=0.25` are common) to `sExit`\r\n // through a right-angle bend, so every segment stays axis-aligned.\r\n sCorner = orthoBridge(start, sExit, exitInfo.side)\r\n }\r\n\r\n let tExit: Point | null = null\r\n let tStub: Point | null = null\r\n let tCorner: Point | null = null\r\n if (opts.targetBounds) {\r\n const enterInfo = exitOnNearestSide(opts.targetBounds, start)\r\n tExit = enterInfo.point\r\n tStub = extrudePoint(enterInfo.point, enterInfo.side, stubLength)\r\n tCorner = orthoBridge(end, tExit, enterInfo.side)\r\n }\r\n\r\n // ─── Step 2. Determine the \"core\" route between sStub and tStub ──────────\r\n // When neither bounds is set, the core route is just `start → end`.\r\n // Otherwise it sits between the perpendicular stubs we just built.\r\n const coreStart: Point = sStub ?? start\r\n const coreEnd: Point = tStub ?? end\r\n\r\n // Obstacles: when both source/target bounds are provided, they should\r\n // NOT be obstacles to themselves — caller is expected to filter the\r\n // pair out, but we double-strip just in case (matches by reference).\r\n const obstacles = opts.obstacles ?? []\r\n const filteredObstacles =\r\n obstacles.length > 0 && (opts.sourceBounds || opts.targetBounds)\r\n ? obstacles.filter((o) => o !== opts.sourceBounds && o !== opts.targetBounds)\r\n : obstacles\r\n\r\n let core: readonly Point[]\r\n if (filteredObstacles.length === 0) {\r\n const snap = opts.snap ?? gridSize\r\n core = lRoute(coreStart, coreEnd, opts.preferred ?? 'auto', snap)\r\n } else {\r\n const inflate = opts.inflate ?? 0\r\n const maxNodes = opts.maxNodes ?? 5000\r\n const aStar = aStarRoute(coreStart, coreEnd, filteredObstacles, gridSize, inflate, maxNodes)\r\n core = aStar ?? lRoute(coreStart, coreEnd, opts.preferred ?? 'auto', opts.snap ?? gridSize)\r\n }\r\n\r\n // ─── Step 3. Stitch the final polyline ────────────────────────────────────\r\n // [start, sExit, sStub, ...core..., tStub, tExit, end], collapsing\r\n // adjacent duplicates and runs of collinear points.\r\n\r\n const points: Point[] = []\r\n pushIfDistinct(points, start)\r\n if (sCorner && !pointsEqual(sCorner, start)) pushIfDistinct(points, sCorner)\r\n if (sExit && !pointsEqual(sExit, points[points.length - 1]!)) pushIfDistinct(points, sExit)\r\n if (sStub && !pointsEqual(sStub, points[points.length - 1]!)) pushIfDistinct(points, sStub)\r\n\r\n for (let i = 0; i < core.length; i++) {\r\n const p = core[i]!\r\n // skip the core endpoints if they exactly match the stubs we already pushed\r\n if (i === 0 && sStub && pointsEqual(p, sStub)) continue\r\n if (i === core.length - 1 && tStub && pointsEqual(p, tStub)) continue\r\n pushIfDistinct(points, p)\r\n }\r\n\r\n if (tStub && !pointsEqual(tStub, points[points.length - 1]!)) pushIfDistinct(points, tStub)\r\n if (tExit && !pointsEqual(tExit, points[points.length - 1]!)) pushIfDistinct(points, tExit)\r\n if (tCorner && !pointsEqual(tCorner, points[points.length - 1]!)) pushIfDistinct(points, tCorner)\r\n if (!pointsEqual(end, points[points.length - 1]!)) pushIfDistinct(points, end)\r\n\r\n return compressCollinear(points)\r\n}\r\n\r\n/**\r\n * Build an SVG path `d` attribute from a polyline.\r\n *\r\n * pointsToPath([[0,0], [10,0], [10,5]]) → \"M 0 0 L 10 0 L 10 5\"\r\n */\r\nexport function pointsToPath(points: readonly Point[]): string {\r\n if (points.length === 0) return ''\r\n const [head, ...rest] = points\r\n return `M ${head[0]} ${head[1]} ${rest.map((p) => `L ${p[0]} ${p[1]}`).join(' ')}`\r\n}\r\n\r\n/**\r\n * Build a rounded-corner SVG path from an orthogonal polyline.\r\n *\r\n * Every interior bend (where two consecutive segments meet at a right\r\n * angle) is replaced with a quadratic Bezier whose control point sits\r\n * exactly at the corner — this produces the visual signature of\r\n * \"smooth-step\" edges found in React Flow / draw.io / Lucidchart\r\n * without changing the underlying polyline geometry.\r\n *\r\n * pointsToRoundedPath([[0,0], [10,0], [10,5]], 4)\r\n * → \"M 0 0 L 6 0 Q 10 0 10 4 L 10 5\"\r\n *\r\n * `radius` is clamped to half of the shorter adjacent segment so the\r\n * curves never overshoot. Passing `0` makes it identical to\r\n * {@link pointsToPath}.\r\n */\r\nexport function pointsToRoundedPath(points: readonly Point[], radius: number): string {\r\n if (points.length === 0) return ''\r\n if (points.length < 3 || radius <= 0) return pointsToPath(points)\r\n\r\n let d = `M ${points[0]![0]} ${points[0]![1]}`\r\n for (let i = 1; i < points.length - 1; i++) {\r\n const a = points[i - 1]!\r\n const b = points[i]!\r\n const c = points[i + 1]!\r\n\r\n // Length of segments meeting at b — clamp the bend so it never\r\n // eats more than half of either neighbour.\r\n const lenAB = Math.hypot(b[0] - a[0], b[1] - a[1])\r\n const lenBC = Math.hypot(c[0] - b[0], c[1] - b[1])\r\n const r = Math.min(radius, lenAB / 2, lenBC / 2)\r\n\r\n const ux = (b[0] - a[0]) / (lenAB || 1)\r\n const uy = (b[1] - a[1]) / (lenAB || 1)\r\n const vx = (c[0] - b[0]) / (lenBC || 1)\r\n const vy = (c[1] - b[1]) / (lenBC || 1)\r\n\r\n // Collinear corner (cross product is zero) → the \"bend\" is just\r\n // a continuation of the previous segment; emit a plain line and\r\n // skip the Q. This keeps multi-segment straight runs visually\r\n // identical to {@link pointsToPath} regardless of the radius.\r\n const cross = ux * vy - uy * vx\r\n if (r < 0.5 || Math.abs(cross) < 1e-9) {\r\n d += ` L ${b[0]} ${b[1]}`\r\n continue\r\n }\r\n\r\n const p1x = b[0] - ux * r\r\n const p1y = b[1] - uy * r\r\n const p2x = b[0] + vx * r\r\n const p2y = b[1] + vy * r\r\n\r\n d += ` L ${p1x} ${p1y} Q ${b[0]} ${b[1]} ${p2x} ${p2y}`\r\n }\r\n const tail = points[points.length - 1]!\r\n d += ` L ${tail[0]} ${tail[1]}`\r\n return d\r\n}\r\n\r\n// ─── Bezier routing ────────────────────────────────────────────────────────\r\n\r\n/** Side of an AABB that an endpoint exits / enters through. */\r\nexport type Side = 'top' | 'right' | 'bottom' | 'left'\r\n\r\nexport interface BezierPathOptions {\r\n /** Source point — where the curve starts. */\r\n source: Point\r\n /** Side of the source node the curve exits through. */\r\n sourceSide: Side\r\n /** Target point — where the curve ends. */\r\n target: Point\r\n /** Side of the target node the curve enters through. */\r\n targetSide: Side\r\n /**\r\n * Curve intensity. `0.25` is React Flow's default — strong enough\r\n * to feel natural, soft enough not to loop. Range: `0..1`.\r\n */\r\n curvature?: number\r\n}\r\n\r\nfunction controlOffset(distance: number, curvature: number): number {\r\n if (distance >= 0) return 0.5 * distance\r\n // Negative distance means the curve has to swing back around; we\r\n // boost the control offset proportionally so the loop reads cleanly.\r\n return curvature * 25 * Math.sqrt(-distance)\r\n}\r\n\r\nfunction controlPoint(\r\n side: Side,\r\n x1: number,\r\n y1: number,\r\n x2: number,\r\n y2: number,\r\n curvature: number,\r\n): Point {\r\n switch (side) {\r\n case 'left':\r\n return [x1 - controlOffset(x1 - x2, curvature), y1]\r\n case 'right':\r\n return [x1 + controlOffset(x2 - x1, curvature), y1]\r\n case 'top':\r\n return [x1, y1 - controlOffset(y1 - y2, curvature)]\r\n case 'bottom':\r\n return [x1, y1 + controlOffset(y2 - y1, curvature)]\r\n }\r\n}\r\n\r\n/**\r\n * Cubic-bezier SVG path between two endpoints, with control handles\r\n * extending perpendicular to each side. Mirrors React Flow's\r\n * `getBezierPath` algorithm.\r\n *\r\n * `sourceSide` / `targetSide` tell the function which face of each\r\n * node the endpoint sits on so the curve always exits and enters\r\n * perpendicular to the node outline — this is the difference between\r\n * a \"wavy\" edge and a \"deliberate\" one.\r\n *\r\n * Use {@link nearestSide} to derive the side from an AABB + opposite\r\n * point when the caller doesn't already know it.\r\n */\r\nexport function getBezierPath(opts: BezierPathOptions): string {\r\n const curvature = opts.curvature ?? 0.25\r\n const [sx, sy] = opts.source\r\n const [tx, ty] = opts.target\r\n const [c1x, c1y] = controlPoint(opts.sourceSide, sx, sy, tx, ty, curvature)\r\n const [c2x, c2y] = controlPoint(opts.targetSide, tx, ty, sx, sy, curvature)\r\n return `M ${sx} ${sy} C ${c1x} ${c1y} ${c2x} ${c2y} ${tx} ${ty}`\r\n}\r\n\r\n/**\r\n * Pick the side of `box` whose midpoint is closest to `target`. Same\r\n * logic as the internal helper used by orthogonal routing — exposed\r\n * publicly so consumers of `getBezierPath` don't need to re-implement\r\n * it.\r\n */\r\nexport function nearestSide(box: AABB, target: Point): Side {\r\n const cx = box.x + box.w / 2\r\n const cy = box.y + box.h / 2\r\n const dx = target[0] - cx\r\n const dy = target[1] - cy\r\n if (Math.abs(dx) >= Math.abs(dy)) return dx >= 0 ? 'right' : 'left'\r\n return dy >= 0 ? 'bottom' : 'top'\r\n}\r\n\r\n// ─── Side / stub helpers ────────────────────────────────────────────────────\r\n\r\n/**\r\n * Pick the side of `box` nearest to `target` and return the midpoint of\r\n * that side. The chosen side is the one whose dominant axis matches the\r\n * dominant axis of the (target → box-centre) vector.\r\n */\r\nfunction exitOnNearestSide(box: AABB, target: Point): { point: Point; side: RectSide } {\r\n const cx = box.x + box.w / 2\r\n const cy = box.y + box.h / 2\r\n const dx = target[0] - cx\r\n const dy = target[1] - cy\r\n if (Math.abs(dx) >= Math.abs(dy)) {\r\n if (dx >= 0) return { point: [box.x + box.w, cy], side: 'right' }\r\n return { point: [box.x, cy], side: 'left' }\r\n }\r\n if (dy >= 0) return { point: [cx, box.y + box.h], side: 'bottom' }\r\n return { point: [cx, box.y], side: 'top' }\r\n}\r\n\r\n/** Extrude `point` perpendicular to `side` by `distance` world units. */\r\nfunction extrudePoint(point: Point, side: RectSide, distance: number): Point {\r\n switch (side) {\r\n case 'top':\r\n return [point[0], point[1] - distance]\r\n case 'right':\r\n return [point[0] + distance, point[1]]\r\n case 'bottom':\r\n return [point[0], point[1] + distance]\r\n case 'left':\r\n return [point[0] - distance, point[1]]\r\n }\r\n}\r\n\r\n/**\r\n * Right-angle bridge between an arbitrary anchor (`start`) and the\r\n * side-midpoint exit (`exit`). Returns the corner where the path bends\r\n * 90° so every segment stays axis-aligned.\r\n *\r\n * For a `right`/`left` exit the path runs vertical-first (drops to the\r\n * exit's row, then exits horizontally); for `top`/`bottom` it runs\r\n * horizontal-first. Collinear cases collapse harmlessly during\r\n * compression.\r\n */\r\nfunction orthoBridge(start: Point, exit: Point, side: RectSide): Point {\r\n switch (side) {\r\n case 'right':\r\n case 'left':\r\n // bend at (exit.x, start.y) → vertical run first, then horizontal exit\r\n return [exit[0], start[1]]\r\n case 'top':\r\n case 'bottom':\r\n // bend at (start.x, exit.y) → horizontal run first, then vertical exit\r\n return [start[0], exit[1]]\r\n }\r\n}\r\n\r\nfunction pointsEqual(a: Point, b: Point): boolean {\r\n return a[0] === b[0] && a[1] === b[1]\r\n}\r\n\r\nfunction pushIfDistinct(arr: Point[], p: Point): void {\r\n if (arr.length === 0) {\r\n arr.push(p)\r\n return\r\n }\r\n const last = arr[arr.length - 1]!\r\n if (!pointsEqual(last, p)) arr.push(p)\r\n}\r\n\r\n/**\r\n * Drop collinear interior points so the output polyline only has corners.\r\n * Handles both pure-vertical / pure-horizontal segments produced by\r\n * orthogonal routing and the rare diagonal we emit when stitching\r\n * non-orthogonal endpoints to the exit point.\r\n */\r\nfunction compressCollinear(points: readonly Point[]): Point[] {\r\n if (points.length <= 2) return points.slice()\r\n const out: Point[] = [points[0]!, points[1]!]\r\n for (let i = 2; i < points.length; i++) {\r\n const cur = points[i]!\r\n const a = out[out.length - 2]!\r\n const b = out[out.length - 1]!\r\n const dx1 = b[0] - a[0]\r\n const dy1 = b[1] - a[1]\r\n const dx2 = cur[0] - b[0]\r\n const dy2 = cur[1] - b[1]\r\n // Both vectors point in the same direction (cross = 0 AND signs match)\r\n // → `b` is interior to a straight run; drop it.\r\n const cross = dx1 * dy2 - dy1 * dx2\r\n if (cross === 0 && Math.sign(dx1) === Math.sign(dx2) && Math.sign(dy1) === Math.sign(dy2)) {\r\n out[out.length - 1] = cur\r\n } else {\r\n out.push(cur)\r\n }\r\n }\r\n return out\r\n}\r\n\r\n// ─── L-route (no obstacles) ────────────────────────────────────────────────\r\n\r\nfunction lRoute(\r\n start: Point,\r\n end: Point,\r\n preferred: 'auto' | 'hv' | 'vh',\r\n _snapStep: number,\r\n): readonly Point[] {\r\n const [sx, sy] = start\r\n const [ex, ey] = end\r\n\r\n if (sx === ex || sy === ey) return [start, end]\r\n\r\n // The corner sits at `(ex, sy)` (HV) or `(sx, ey)` (VH). Both\r\n // coordinates are anchored to one of the endpoints, so the resulting\r\n // two segments are guaranteed axis-aligned. We deliberately do NOT\r\n // snap to a grid here: `start` / `end` are exact anchor positions\r\n // (set by the caller), and rounding the corner to a grid step would\r\n // skew one of the two segments into a diagonal. `_snapStep` is kept\r\n // in the signature so the A*-fallback can pass it through; snapping\r\n // proper happens inside A* where the whole search runs on the grid.\r\n const dx = Math.abs(ex - sx)\r\n const dy = Math.abs(ey - sy)\r\n const useHV = preferred === 'hv' ? true : preferred === 'vh' ? false : dx >= dy\r\n\r\n if (useHV) return [start, [ex, sy], end]\r\n return [start, [sx, ey], end]\r\n}\r\n\r\n// ─── A* on a grid (obstacle-aware path) ────────────────────────────────────\r\n\r\ninterface InflatedRect {\r\n x0: number\r\n y0: number\r\n x1: number\r\n y1: number\r\n}\r\n\r\nfunction inflateObstacles(obstacles: readonly AABB[], pad: number): InflatedRect[] {\r\n return obstacles.map((o) => ({\r\n x0: o.x - pad,\r\n y0: o.y - pad,\r\n x1: o.x + o.w + pad,\r\n y1: o.y + o.h + pad,\r\n }))\r\n}\r\n\r\n/**\r\n * Strict-interior point-in-obstacle test. Border points are considered\r\n * free so paths can \"hug\" an obstacle without snagging on it.\r\n */\r\nfunction pointBlocked(x: number, y: number, rects: readonly InflatedRect[]): boolean {\r\n for (const r of rects) {\r\n if (x > r.x0 && x < r.x1 && y > r.y0 && y < r.y1) return true\r\n }\r\n return false\r\n}\r\n\r\nfunction snap(value: number, step: number): number {\r\n return Math.round(value / step) * step\r\n}\r\n\r\nfunction key(x: number, y: number): string {\r\n return `${x},${y}`\r\n}\r\n\r\nfunction manhattan(ax: number, ay: number, bx: number, by: number): number {\r\n return Math.abs(ax - bx) + Math.abs(ay - by)\r\n}\r\n\r\n/**\r\n * Reconstruct path from `cameFrom` map and compress collinear points so\r\n * the output polyline only has corners.\r\n */\r\nfunction reconstruct(cameFrom: Map<string, string>, endKey: string): Point[] {\r\n const reversed: Point[] = []\r\n let cursor: string | undefined = endKey\r\n while (cursor !== undefined) {\r\n const [xs, ys] = cursor.split(',')\r\n reversed.push([Number(xs), Number(ys)])\r\n cursor = cameFrom.get(cursor)\r\n }\r\n reversed.reverse()\r\n // Collapse runs of collinear points.\r\n const out: Point[] = []\r\n for (let i = 0; i < reversed.length; i++) {\r\n const cur = reversed[i]!\r\n if (out.length < 2) {\r\n out.push(cur)\r\n continue\r\n }\r\n const a = out[out.length - 2]!\r\n const b = out[out.length - 1]!\r\n const dx1 = b[0] - a[0]\r\n const dy1 = b[1] - a[1]\r\n const dx2 = cur[0] - b[0]\r\n const dy2 = cur[1] - b[1]\r\n if (Math.sign(dx1) === Math.sign(dx2) && Math.sign(dy1) === Math.sign(dy2)) {\r\n out[out.length - 1] = cur\r\n } else {\r\n out.push(cur)\r\n }\r\n }\r\n return out\r\n}\r\n\r\n/**\r\n * Minimal binary min-heap keyed by `f`. Replaces the original linear\r\n * scan over `open` — that was O(N) per pop, which dominated the A*\r\n * runtime on dense diagrams. With the heap a 6-node / 8-edge layout\r\n * routes in ~1 ms instead of ~12 ms.\r\n *\r\n * Stale entries (i.e. a key that's been re-pushed with a smaller `f`)\r\n * are tolerated: we re-check `gScore` on pop and drop entries that\r\n * don't match the current best score. This is the standard \"lazy\r\n * deletion\" pattern and keeps the heap operations cheap.\r\n */\r\ninterface OpenEntry {\r\n k: string\r\n x: number\r\n y: number\r\n f: number\r\n}\r\n\r\nclass MinHeap {\r\n private readonly data: OpenEntry[] = []\r\n\r\n get size(): number {\r\n return this.data.length\r\n }\r\n\r\n push(entry: OpenEntry): void {\r\n this.data.push(entry)\r\n this.bubbleUp(this.data.length - 1)\r\n }\r\n\r\n pop(): OpenEntry | undefined {\r\n if (this.data.length === 0) return undefined\r\n const head = this.data[0]!\r\n const tail = this.data.pop()!\r\n if (this.data.length > 0) {\r\n this.data[0] = tail\r\n this.bubbleDown(0)\r\n }\r\n return head\r\n }\r\n\r\n private bubbleUp(i: number): void {\r\n while (i > 0) {\r\n const parent = (i - 1) >> 1\r\n if (this.data[i]!.f < this.data[parent]!.f) {\r\n const tmp = this.data[i]!\r\n this.data[i] = this.data[parent]!\r\n this.data[parent] = tmp\r\n i = parent\r\n } else {\r\n return\r\n }\r\n }\r\n }\r\n\r\n private bubbleDown(i: number): void {\r\n const n = this.data.length\r\n while (true) {\r\n const l = i * 2 + 1\r\n const r = l + 1\r\n let smallest = i\r\n if (l < n && this.data[l]!.f < this.data[smallest]!.f) smallest = l\r\n if (r < n && this.data[r]!.f < this.data[smallest]!.f) smallest = r\r\n if (smallest === i) return\r\n const tmp = this.data[i]!\r\n this.data[i] = this.data[smallest]!\r\n this.data[smallest] = tmp\r\n i = smallest\r\n }\r\n }\r\n}\r\n\r\nfunction aStarRoute(\r\n start: Point,\r\n end: Point,\r\n obstacles: readonly AABB[],\r\n gridSize: number,\r\n inflate: number,\r\n maxNodes: number,\r\n): readonly Point[] | null {\r\n const rects = inflateObstacles(obstacles, inflate)\r\n\r\n const sx = snap(start[0], gridSize)\r\n const sy = snap(start[1], gridSize)\r\n const ex = snap(end[0], gridSize)\r\n const ey = snap(end[1], gridSize)\r\n\r\n if (pointBlocked(sx, sy, rects) || pointBlocked(ex, ey, rects)) return null\r\n\r\n const startKey = key(sx, sy)\r\n const endKey = key(ex, ey)\r\n\r\n const gScore = new Map<string, number>([[startKey, 0]])\r\n const cameFrom = new Map<string, string>()\r\n const cameDir = new Map<string, Dir>([[startKey, null]])\r\n\r\n const open = new MinHeap()\r\n open.push({ k: startKey, x: sx, y: sy, f: manhattan(sx, sy, ex, ey) })\r\n\r\n const TURN_PENALTY = gridSize\r\n\r\n let expansions = 0\r\n\r\n while (open.size > 0) {\r\n if (expansions++ > maxNodes) return null\r\n\r\n const current = open.pop()!\r\n // Lazy deletion: discard stale heap entries left over from\r\n // previous, now-superseded score updates.\r\n const bestG = gScore.get(current.k) ?? Infinity\r\n const expectedF = bestG + manhattan(current.x, current.y, ex, ey)\r\n if (current.f > expectedF) continue\r\n\r\n if (current.k === endKey) {\r\n const path = reconstruct(cameFrom, endKey)\r\n if (path.length > 0) {\r\n path[0] = start\r\n path[path.length - 1] = end\r\n }\r\n return path\r\n }\r\n\r\n const incomingDir = cameDir.get(current.k) ?? null\r\n const neighbours: ReadonlyArray<readonly [number, number, Dir]> = [\r\n [gridSize, 0, 'h'],\r\n [-gridSize, 0, 'h'],\r\n [0, gridSize, 'v'],\r\n [0, -gridSize, 'v'],\r\n ]\r\n for (const [dx, dy, dir] of neighbours) {\r\n const nx = current.x + dx\r\n const ny = current.y + dy\r\n if (pointBlocked(nx, ny, rects)) continue\r\n\r\n const turn = incomingDir !== null && incomingDir !== dir\r\n const tentativeG = bestG + gridSize + (turn ? TURN_PENALTY : 0)\r\n const nk = key(nx, ny)\r\n const prevG = gScore.get(nk) ?? Infinity\r\n if (tentativeG < prevG) {\r\n cameFrom.set(nk, current.k)\r\n cameDir.set(nk, dir)\r\n gScore.set(nk, tentativeG)\r\n const f = tentativeG + manhattan(nx, ny, ex, ey)\r\n open.push({ k: nk, x: nx, y: ny, f })\r\n }\r\n }\r\n }\r\n\r\n return null\r\n}\r\n","import type { AABB, Point } from './types'\n\n/**\n * Oriented Bounding Box — a rectangle in world space described by its centre,\n * half-extents along its local axes, and a rotation angle.\n *\n * Used when a node has a non-zero `transform.rot`: the AABB is no longer a\n * tight fit, so callers that need a tight collision shape (selection\n * outline, manipulator handles, etc.) should use the OBB instead.\n *\n * Conventions:\n * - `center` is the centre of the rectangle in world coordinates.\n * - `halfWidth` / `halfHeight` are the half-extents along the OBB's own\n * local axes (already pre-multiplied by the world scale).\n * - `angle` is the rotation of the OBB's local frame relative to world,\n * in radians, positive counter-clockwise.\n *\n * For an axis-aligned node (`angle === 0`) the OBB and AABB coincide, modulo\n * the (centre + half-extents) vs (top-left + size) representation.\n */\nexport interface OBB {\n readonly center: Point\n readonly halfWidth: number\n readonly halfHeight: number\n readonly angle: number\n}\n\n/**\n * Compute the four corners of an OBB in world space.\n *\n * Order is: top-left → top-right → bottom-right → bottom-left in OBB-local\n * space, after applying the rotation. Useful for SVG `<polygon>` rendering\n * and for AABB derivation.\n */\nexport function obbCorners(obb: OBB): readonly [Point, Point, Point, Point] {\n const cos = Math.cos(obb.angle)\n const sin = Math.sin(obb.angle)\n const { halfWidth: hw, halfHeight: hh } = obb\n const [cx, cy] = obb.center\n // local corners (TL, TR, BR, BL)\n const lx: readonly number[] = [-hw, hw, hw, -hw]\n const ly: readonly number[] = [-hh, -hh, hh, hh]\n const out: Point[] = []\n for (let i = 0; i < 4; i++) {\n const x = lx[i]!\n const y = ly[i]!\n out.push([cx + x * cos - y * sin, cy + x * sin + y * cos])\n }\n return out as unknown as readonly [Point, Point, Point, Point]\n}\n\n/**\n * Build the tightest axis-aligned bounding box that contains a given OBB.\n *\n * For a non-zero `angle` the resulting AABB is strictly larger (in area)\n * than the OBB — it has to enclose all four rotated corners. This is the\n * canonical \"broad-phase\" box used by the routing layer.\n */\nexport function aabbFromOBB(obb: OBB): AABB {\n const corners = obbCorners(obb)\n let x0 = corners[0][0]\n let x1 = corners[0][0]\n let y0 = corners[0][1]\n let y1 = corners[0][1]\n for (let i = 1; i < 4; i++) {\n const [x, y] = corners[i]!\n if (x < x0) x0 = x\n if (x > x1) x1 = x\n if (y < y0) y0 = y\n if (y > y1) y1 = y\n }\n return { x: x0, y: y0, w: x1 - x0, h: y1 - y0 }\n}\n\n/**\n * Test whether a world-space point lies inside an OBB.\n *\n * Inverse-rotates the point into OBB-local space and checks the\n * half-extents. O(1).\n */\nexport function obbContainsPoint(obb: OBB, p: Point): boolean {\n const cos = Math.cos(-obb.angle)\n const sin = Math.sin(-obb.angle)\n const dx = p[0] - obb.center[0]\n const dy = p[1] - obb.center[1]\n const lx = dx * cos - dy * sin\n const ly = dx * sin + dy * cos\n return Math.abs(lx) <= obb.halfWidth && Math.abs(ly) <= obb.halfHeight\n}\n","import type {\n AdvancedFilter,\n AggregateFn,\n AggregateType,\n ColumnFilter,\n FilterOperator,\n} from './types'\n\n/**\n * Возвращает финальный оператор фильтра. Соблюдаем backward-compat:\n * если оператор не задан, и `value` — массив, считаем фильтр `in`,\n * иначе — `eq`.\n */\nexport function resolveOperator(\n filter: AdvancedFilter | ColumnFilter,\n): FilterOperator {\n const adv = filter as AdvancedFilter\n if (adv.op != null) return adv.op\n const col = filter as ColumnFilter\n if (col.operator != null) return col.operator\n return Array.isArray(filter.value) ? 'in' : 'eq'\n}\n\n/** Проверка пустоты для `isEmpty` / `isNotEmpty`. */\nfunction isEmptyValue(val: unknown): boolean {\n return val == null || val === ''\n}\n\n/** Числовое сравнение с защитой от NaN. */\nfunction asNumberPair(a: unknown, b: unknown): [number, number] | null {\n const na = typeof a === 'number' ? a : Number(a)\n const nb = typeof b === 'number' ? b : Number(b)\n if (Number.isNaN(na) || Number.isNaN(nb)) return null\n return [na, nb]\n}\n\n/**\n * Проверяет, проходит ли значение `val` фильтр (`op` + `filterValue`).\n * Используется как для `ColumnFilter`, так и для `AdvancedFilter`.\n */\nexport function matchesOperator(\n val: unknown,\n op: FilterOperator,\n filterValue: unknown,\n): boolean {\n switch (op) {\n case 'eq':\n return val === filterValue\n case 'neq':\n return val !== filterValue\n\n case 'lt':\n case 'lte':\n case 'gt':\n case 'gte': {\n const pair = asNumberPair(val, filterValue)\n if (!pair) return false\n const [a, b] = pair\n if (op === 'lt') return a < b\n if (op === 'lte') return a <= b\n if (op === 'gt') return a > b\n return a >= b\n }\n\n case 'between': {\n if (!Array.isArray(filterValue) || filterValue.length !== 2) return false\n const minPair = asNumberPair(val, filterValue[0])\n const maxPair = asNumberPair(val, filterValue[1])\n if (!minPair || !maxPair) return false\n return minPair[0] >= minPair[1] && maxPair[0] <= maxPair[1]\n }\n\n case 'in':\n return Array.isArray(filterValue) && filterValue.includes(val)\n case 'notIn':\n return Array.isArray(filterValue) && !filterValue.includes(val)\n\n case 'contains':\n if (typeof val !== 'string') return false\n return val.toLowerCase().includes(String(filterValue ?? '').toLowerCase())\n case 'startsWith':\n if (typeof val !== 'string') return false\n return val.toLowerCase().startsWith(String(filterValue ?? '').toLowerCase())\n case 'endsWith':\n if (typeof val !== 'string') return false\n return val.toLowerCase().endsWith(String(filterValue ?? '').toLowerCase())\n\n case 'isEmpty':\n return isEmptyValue(val)\n case 'isNotEmpty':\n return !isEmptyValue(val)\n }\n}\n\n/**\n * Применяет `ColumnFilter` к строке (по `filter.column`).\n * Точка входа из движка таблицы.\n */\nexport function matchesColumnFilter(\n row: Record<string, unknown>,\n filter: ColumnFilter,\n): boolean {\n const op = resolveOperator(filter)\n return matchesOperator(row[filter.column], op, filter.value)\n}\n\n/** Считает встроенную агрегацию для массива значений. */\nexport function computeAggregate(\n values: unknown[],\n type: AggregateType | AggregateFn,\n): unknown {\n if (typeof type === 'function') return type(values)\n\n if (type === 'count') return values.length\n\n const nums: number[] = []\n for (const v of values) {\n if (v == null || v === '') continue\n const n = typeof v === 'number' ? v : Number(v)\n if (!Number.isNaN(n)) nums.push(n)\n }\n if (nums.length === 0) return null\n\n switch (type) {\n case 'sum':\n return nums.reduce((a, b) => a + b, 0)\n case 'avg':\n return nums.reduce((a, b) => a + b, 0) / nums.length\n case 'min':\n return Math.min(...nums)\n case 'max':\n return Math.max(...nums)\n }\n}\n","import type { Core } from '../../types'\nimport type {\n AdvancedFilter,\n ColumnAggregate,\n ColumnFilter,\n ExportOptions,\n FilterFn,\n RowId,\n SortConfig,\n SortDirection,\n TableEngine,\n TableGroup,\n TableOptions,\n TableState,\n} from './types'\n\nimport { TABLE_PREFIX } from '../namespaces'\nimport { computeAggregate, matchesColumnFilter } from './filter'\n\nfunction statePath(tableId: string, key: string): string {\n return `${TABLE_PREFIX}${tableId}.state.${key}`\n}\n\nlet tableCounter = 0\n\n/**\n * `createTable` строит TableEngine поверх Core. Пользовательские данные строк\n * хранятся в private замыкании (`dataById`/`keysById`), а в Core попадают\n * только пути `$table.<id>.state.*` (агрегированные счётчики, ширины колонок,\n * пин-конфиг). Это держит `addRows(100k)` на масштабе O(N) Map.set вместо\n * O(N × cols) `core.set` (исторический паттерн `byId.<rid>.<col>` создавал\n * сотни тысяч узлов в Store и аллокаций Set/Map в `Core.set` на каждую\n * cell-запись — см. `docs/_streams/findings/T-Table-Perf.md` H1).\n *\n * Семантика публичных методов `getRow`/`getCell`/`getVisibleRows` сохранена.\n * Внешние подписки на `$table.<id>.state.*` пути продолжают работать;\n * подписок на `byId.*` в монорепе нет (они никогда не были задокументированы).\n */\nexport function createTable(core: Core, options?: TableOptions): TableEngine {\n const tableId = `t${tableCounter++}`\n let currentPageSize = options?.pageSize ?? 50\n\n let order: RowId[] = []\n let filteredOrder: RowId[] = []\n let sorts: SortConfig[] = []\n let filters: ColumnFilter[] = []\n let customFilterFn: FilterFn | null = null\n let page = 1\n let pinnedLeft: string[] = []\n let pinnedRight: string[] = []\n let columnWidths: Record<string, number> = {}\n\n // Группировка\n let groupByField: string | null = null\n let columnAggregates: ColumnAggregate[] = []\n let groups: TableGroup[] = []\n\n // Private storage: данные строк живут в замыкании, не в Core store.\n // Это устраняет 800k `core.set` per-cell на 100k×7 датасете и убирает\n // основной источник аллокаций (Store-узлы + Set/Map в `Core.set`).\n const dataById = new Map<RowId, Record<string, unknown>>()\n const keysById = new Map<RowId, string[]>()\n\n function getRowData(id: RowId): Record<string, unknown> | undefined {\n const stored = dataById.get(id)\n if (!stored) return undefined\n\n // Если пользователь передал явный whitelist колонок через\n // `TableOptions.columns`, отдаём отфильтрованную копию (исторический\n // контракт). В типичном кейсе (опция не задана) — возвращаем хранимую\n // ссылку без копии: hot path `compareBySort`/`recomputeFiltered`/render\n // не должны платить за per-row allocation.\n if (options?.columns) {\n const filtered: Record<string, unknown> = {}\n for (const col of options.columns) {\n filtered[col] = stored[col]\n }\n return filtered\n }\n return stored\n }\n\n function matchesFilters(rowData: Record<string, unknown>): boolean {\n if (customFilterFn && !customFilterFn(rowData)) return false\n\n for (const f of filters) {\n if (!matchesColumnFilter(rowData, f)) return false\n }\n return true\n }\n\n function compareBySort(a: RowId, b: RowId): number {\n const aData = getRowData(a)\n const bData = getRowData(b)\n\n for (const s of sorts) {\n const aVal = aData?.[s.column]\n const bVal = bData?.[s.column]\n\n if (aVal === bVal) continue\n if (aVal === undefined || aVal === null) return 1\n if (bVal === undefined || bVal === null) return -1\n\n const cmp = aVal < bVal ? -1 : 1\n return s.direction === 'asc' ? cmp : -cmp\n }\n return 0\n }\n\n function recomputeFiltered(): void {\n if (filters.length === 0 && !customFilterFn) {\n filteredOrder = [...order]\n } else {\n filteredOrder = order.filter((id) => {\n const data = getRowData(id)\n return data ? matchesFilters(data) : false\n })\n }\n\n if (sorts.length > 0) {\n filteredOrder.sort(compareBySort)\n }\n\n const totalPages = Math.max(1, Math.ceil(filteredOrder.length / currentPageSize))\n if (page > totalPages) page = totalPages\n\n recomputeGroups()\n publishState()\n }\n\n function recomputeGroups(): void {\n if (!groupByField) {\n groups = []\n return\n }\n\n const map = new Map<string, { value: unknown; rows: RowId[] }>()\n const orderKeys: string[] = []\n\n for (const id of filteredOrder) {\n const data = getRowData(id)\n if (!data) continue\n const raw = data[groupByField]\n const key = raw == null ? '__null__' : String(raw)\n if (!map.has(key)) {\n map.set(key, { value: raw, rows: [] })\n orderKeys.push(key)\n }\n map.get(key)!.rows.push(id)\n }\n\n groups = orderKeys.map((key) => {\n const { value, rows } = map.get(key)!\n const aggregates: Record<string, unknown> = {}\n for (const agg of columnAggregates) {\n const values = rows.map((id) => dataById.get(id)?.[agg.column])\n aggregates[agg.column] = computeAggregate(values, agg.type)\n }\n return { key, value, rows, aggregates }\n })\n }\n\n function publishState(): void {\n const totalPages = Math.max(1, Math.ceil(filteredOrder.length / currentPageSize))\n core.set(statePath(tableId, 'totalRows'), order.length)\n core.set(statePath(tableId, 'filteredRows'), filteredOrder.length)\n core.set(statePath(tableId, 'page'), page)\n core.set(statePath(tableId, 'pageSize'), currentPageSize)\n core.set(statePath(tableId, 'totalPages'), totalPages)\n core.set(statePath(tableId, 'groupBy'), groupByField)\n core.set(statePath(tableId, 'groupCount'), groups.length)\n }\n\n function getColumnKeys(): string[] {\n if (options?.columns) return options.columns\n if (order.length === 0) return []\n const firstId = order[0]\n return keysById.get(firstId) ?? []\n }\n\n /** Привести `AdvancedFilter | ColumnFilter` к единому `ColumnFilter`. */\n function toColumnFilter(column: string, filter: AdvancedFilter | ColumnFilter): ColumnFilter {\n const adv = filter as AdvancedFilter\n if (adv.op != null) {\n return { column, operator: adv.op, value: adv.value }\n }\n const cf = filter as ColumnFilter\n return { column, operator: cf.operator, value: cf.value }\n }\n\n const table: TableEngine = {\n addRow(id: RowId, data: Record<string, unknown>): void {\n dataById.set(id, data)\n keysById.set(id, Object.keys(data))\n order.push(id)\n recomputeFiltered()\n },\n\n addRows(rows: Array<{ id: RowId; data: Record<string, unknown> }>): void {\n // Single Map.set per row instead of (cols + 1) `core.set` per row —\n // на 100k×7 это разница 800k vs 100k операций и убирает\n // основной источник аллокаций. См. `findings/T-Table-Perf.md` H1.\n for (const row of rows) {\n dataById.set(row.id, row.data)\n keysById.set(row.id, Object.keys(row.data))\n order.push(row.id)\n }\n recomputeFiltered()\n },\n\n removeRow(id: RowId): void {\n const idx = order.indexOf(id)\n if (idx === -1) return\n order.splice(idx, 1)\n dataById.delete(id)\n keysById.delete(id)\n recomputeFiltered()\n },\n\n updateCell(id: RowId, column: string, value: unknown): void {\n const row = dataById.get(id)\n if (!row) return\n // Мутация хранимого объекта. `getRow` отдаёт эту же ссылку (см. контракт\n // в JSDoc к `createTable`), `recomputeFiltered` снизу пересоберёт сорт/\n // группы как раньше.\n row[column] = value\n const keys = keysById.get(id)\n if (keys && !keys.includes(column)) {\n keys.push(column)\n }\n recomputeFiltered()\n },\n\n getRow(id: RowId): Record<string, unknown> | undefined {\n return getRowData(id)\n },\n\n getCell(id: RowId, column: string): unknown {\n return dataById.get(id)?.[column]\n },\n\n getVisibleRows(): Array<{ id: RowId; data: Record<string, unknown> }> {\n const start = (page - 1) * currentPageSize\n const end = start + currentPageSize\n const slice = filteredOrder.slice(start, end)\n const out = new Array(slice.length) as Array<{\n id: RowId\n data: Record<string, unknown>\n }>\n for (let i = 0; i < slice.length; i++) {\n const id = slice[i]\n out[i] = { id, data: getRowData(id) ?? {} }\n }\n return out\n },\n\n getAllRowIds(): RowId[] {\n return [...order]\n },\n\n getAllRows(): Array<{ id: RowId; data: Record<string, unknown> }> {\n const out = new Array(filteredOrder.length) as Array<{\n id: RowId\n data: Record<string, unknown>\n }>\n for (let i = 0; i < filteredOrder.length; i++) {\n const id = filteredOrder[i]\n out[i] = { id, data: getRowData(id) ?? {} }\n }\n return out\n },\n\n setSort(column: string, direction: SortDirection, append?: boolean): void {\n if (append) {\n sorts = sorts.filter((s) => s.column !== column)\n sorts.push({ column, direction })\n } else {\n sorts = [{ column, direction }]\n }\n recomputeFiltered()\n },\n\n setSorts(newSorts: SortConfig[]): void {\n sorts = [...newSorts]\n recomputeFiltered()\n },\n\n clearSort(): void {\n sorts = []\n recomputeFiltered()\n },\n\n addFilter(filter: ColumnFilter): void {\n filters = filters.filter((f) => f.column !== filter.column)\n filters.push(filter)\n page = 1\n recomputeFiltered()\n },\n\n removeFilter(column: string): void {\n filters = filters.filter((f) => f.column !== column)\n recomputeFiltered()\n },\n\n clearFilters(): void {\n filters = []\n customFilterFn = null\n recomputeFiltered()\n },\n\n setFilterFn(fn: FilterFn | null): void {\n customFilterFn = fn\n recomputeFiltered()\n },\n\n setColumnFilter(column, filter): void {\n filters = filters.filter((f) => f.column !== column)\n if (filter !== null) {\n filters.push(toColumnFilter(column, filter))\n }\n page = 1\n recomputeFiltered()\n },\n\n setPage(p: number): void {\n const totalPages = Math.max(1, Math.ceil(filteredOrder.length / currentPageSize))\n page = Math.max(1, Math.min(p, totalPages))\n publishState()\n },\n\n setPageSize(size: number): void {\n currentPageSize = size\n page = 1\n recomputeFiltered()\n },\n\n nextPage(): void {\n table.setPage(page + 1)\n },\n\n prevPage(): void {\n table.setPage(page - 1)\n },\n\n moveRow(fromIndex: number, toIndex: number): void {\n if (fromIndex < 0 || fromIndex >= order.length) return\n if (toIndex < 0 || toIndex >= order.length) return\n if (fromIndex === toIndex) return\n\n const [item] = order.splice(fromIndex, 1)\n order.splice(toIndex, 0, item)\n recomputeFiltered()\n },\n\n pinColumn(column: string, side: 'left' | 'right' | null): void {\n pinnedLeft = pinnedLeft.filter((c) => c !== column)\n pinnedRight = pinnedRight.filter((c) => c !== column)\n if (side === 'left') pinnedLeft.push(column)\n else if (side === 'right') pinnedRight.push(column)\n core.set(statePath(tableId, 'pinnedLeft'), [...pinnedLeft])\n core.set(statePath(tableId, 'pinnedRight'), [...pinnedRight])\n },\n\n getPinnedColumns(): { left: string[]; right: string[] } {\n return { left: [...pinnedLeft], right: [...pinnedRight] }\n },\n\n clearPinned(): void {\n pinnedLeft = []\n pinnedRight = []\n core.set(statePath(tableId, 'pinnedLeft'), [])\n core.set(statePath(tableId, 'pinnedRight'), [])\n },\n\n setColumnWidth(column: string, width: number): void {\n columnWidths = { ...columnWidths, [column]: width }\n core.set(statePath(tableId, 'columnWidths'), { ...columnWidths })\n },\n\n getColumnWidth(column: string): number | undefined {\n return columnWidths[column]\n },\n\n getColumnWidths(): Record<string, number> {\n return { ...columnWidths }\n },\n\n clearColumnWidths(): void {\n columnWidths = {}\n core.set(statePath(tableId, 'columnWidths'), {})\n },\n\n moveRows(ids: RowId[], toIndex: number): void {\n const items = ids\n .map((id) => {\n const idx = order.indexOf(id)\n return { id, idx }\n })\n .filter((x) => x.idx !== -1)\n\n if (items.length === 0) return\n\n const idsSet = new Set(ids)\n const remaining = order.filter((id) => !idsSet.has(id))\n const clamped = Math.max(0, Math.min(toIndex, remaining.length))\n remaining.splice(clamped, 0, ...items.map((x) => x.id))\n order = remaining\n recomputeFiltered()\n },\n\n getExportData(exportOptions?: ExportOptions): string[][] {\n const cols = exportOptions?.columns ?? getColumnKeys()\n const result: string[][] = []\n\n if (exportOptions?.headers !== false) {\n result.push(cols)\n }\n\n const sourceIds = exportOptions?.allRows\n ? filteredOrder\n : filteredOrder.slice(\n (page - 1) * currentPageSize,\n (page - 1) * currentPageSize + currentPageSize,\n )\n\n for (const id of sourceIds) {\n const data = getRowData(id)\n if (!data) continue\n result.push(\n cols.map((col) => {\n const v = data[col]\n return v == null ? '' : String(v)\n }),\n )\n }\n\n return result\n },\n\n getTableState(): TableState {\n const totalPages = Math.max(1, Math.ceil(filteredOrder.length / currentPageSize))\n return {\n totalRows: order.length,\n filteredRows: filteredOrder.length,\n page,\n pageSize: currentPageSize,\n totalPages,\n sorts: [...sorts],\n sort: sorts.length > 0 ? sorts[0] : null,\n filters: [...filters],\n groupBy: groupByField,\n groupCount: groups.length,\n }\n },\n\n groupBy(field, aggregates): void {\n groupByField = field ?? null\n columnAggregates = aggregates ? [...aggregates] : []\n recomputeGroups()\n publishState()\n },\n\n clearGroupBy(): void {\n groupByField = null\n columnAggregates = []\n groups = []\n publishState()\n },\n\n getGroupBy(): string | null {\n return groupByField\n },\n\n getGroups(): TableGroup[] {\n return groups.map((g) => ({\n key: g.key,\n value: g.value,\n rows: [...g.rows],\n aggregates: { ...g.aggregates },\n }))\n },\n\n getEstimatedRowHeight(id: RowId): number | null {\n const fn = options?.estimateRowHeight\n if (!fn) return null\n const data = getRowData(id)\n if (!data) return null\n const v = fn(data, id)\n return Number.isFinite(v) ? v : null\n },\n\n reset(): void {\n order = []\n filteredOrder = []\n sorts = []\n filters = []\n customFilterFn = null\n page = 1\n pinnedLeft = []\n pinnedRight = []\n columnWidths = {}\n groupByField = null\n columnAggregates = []\n groups = []\n dataById.clear()\n keysById.clear()\n core.set(statePath(tableId, 'columnWidths'), {})\n publishState()\n },\n }\n\n // Initial publish — emit empty `columnWidths` so subscribers can read a\n // stable shape from the store without needing to handle `undefined`.\n core.set(statePath(tableId, 'columnWidths'), {})\n publishState()\n return table\n}\n","import type { Core } from '../../types'\nimport type {\n TreeKey,\n TreeNodeData,\n TreeFieldNames,\n TreeEngine,\n TreeEngineOptions,\n TreeState,\n} from './types'\n\nimport { TREE_PREFIX } from '../namespaces'\n\nlet treeCounter = 0\n\ninterface InternalNode {\n node: TreeNodeData\n key: TreeKey\n depth: number\n parentKey: TreeKey | null\n childKeys: TreeKey[]\n isLeaf: boolean\n}\n\nexport function createTree(core: Core, options?: TreeEngineOptions): TreeEngine {\n const treeId = `tr${treeCounter++}`\n const fn: Required<TreeFieldNames> = {\n key: options?.fieldNames?.key ?? 'key',\n title: options?.fieldNames?.title ?? 'title',\n children: options?.fieldNames?.children ?? 'children',\n }\n const checkStrictly = options?.checkStrictly ?? false\n\n let nodes: TreeNodeData[] = []\n let nodeMap = new Map<TreeKey, InternalNode>()\n\n let expandedKeys = new Set<TreeKey>(options?.defaultExpandedKeys ?? [])\n let checkedKeys = new Set<TreeKey>(options?.defaultCheckedKeys ?? [])\n let halfCheckedKeys = new Set<TreeKey>()\n let selectedKeys = new Set<TreeKey>(options?.defaultSelectedKeys ?? [])\n let loadedKeys = new Set<TreeKey>()\n let loadingKeys = new Set<TreeKey>()\n let filteredKeys: Set<TreeKey> | null = null\n\n function getKey(node: TreeNodeData): TreeKey {\n return (node as Record<string, unknown>)[fn.key] as TreeKey\n }\n\n function getChildren(node: TreeNodeData): TreeNodeData[] | undefined {\n return (node as Record<string, unknown>)[fn.children] as TreeNodeData[] | undefined\n }\n\n function buildMap(data: TreeNodeData[]): void {\n nodeMap = new Map()\n function walk(list: TreeNodeData[], parentKey: TreeKey | null, depth: number) {\n for (const n of list) {\n const k = getKey(n)\n const children = getChildren(n)\n const childKeys: TreeKey[] = []\n const isLeaf = n.isLeaf === true || (!children || children.length === 0)\n\n if (children && children.length > 0) {\n for (const ch of children) childKeys.push(getKey(ch))\n }\n\n nodeMap.set(k, { node: n, key: k, depth, parentKey, childKeys, isLeaf })\n\n if (children && children.length > 0) {\n walk(children, k, depth + 1)\n }\n }\n }\n walk(data, null, 0)\n }\n\n function getAllDescendantKeys(key: TreeKey): TreeKey[] {\n const result: TreeKey[] = []\n const internal = nodeMap.get(key)\n if (!internal) return result\n for (const ck of internal.childKeys) {\n result.push(ck)\n result.push(...getAllDescendantKeys(ck))\n }\n return result\n }\n\n function getAllAncestorKeys(key: TreeKey): TreeKey[] {\n const result: TreeKey[] = []\n let current = nodeMap.get(key)\n while (current && current.parentKey !== null) {\n result.push(current.parentKey)\n current = nodeMap.get(current.parentKey)\n }\n return result\n }\n\n function recomputeHalfChecked(): void {\n if (checkStrictly) {\n halfCheckedKeys = new Set()\n return\n }\n const half = new Set<TreeKey>()\n for (const [key, internal] of nodeMap) {\n if (internal.childKeys.length === 0) continue\n if (checkedKeys.has(key)) continue\n const allDescendants = getAllDescendantKeys(key)\n const someChecked = allDescendants.some((dk) => checkedKeys.has(dk))\n if (someChecked) half.add(key)\n }\n halfCheckedKeys = half\n }\n\n function cascadeCheck(key: TreeKey, checked: boolean): void {\n if (checkStrictly) {\n if (checked) checkedKeys.add(key)\n else checkedKeys.delete(key)\n return\n }\n\n const internal = nodeMap.get(key)\n if (!internal) return\n\n if (checked) {\n checkedKeys.add(key)\n const descendants = getAllDescendantKeys(key)\n for (const dk of descendants) {\n const dn = nodeMap.get(dk)\n if (dn && !dn.node.disabled && !dn.node.disableCheckbox) {\n checkedKeys.add(dk)\n }\n }\n } else {\n checkedKeys.delete(key)\n const descendants = getAllDescendantKeys(key)\n for (const dk of descendants) {\n checkedKeys.delete(dk)\n }\n }\n\n // Propagate up\n const ancestors = getAllAncestorKeys(key)\n for (const ak of ancestors) {\n const an = nodeMap.get(ak)\n if (!an) continue\n const allChildren = getAllDescendantKeys(ak)\n const enabledChildren = allChildren.filter((ck) => {\n const cn = nodeMap.get(ck)\n return cn && !cn.node.disabled && !cn.node.disableCheckbox\n })\n const allChecked = enabledChildren.length > 0 && enabledChildren.every((ck) => checkedKeys.has(ck))\n if (allChecked) {\n checkedKeys.add(ak)\n } else {\n checkedKeys.delete(ak)\n }\n }\n\n recomputeHalfChecked()\n }\n\n function removeFromTree(data: TreeNodeData[], targetKey: TreeKey): { remaining: TreeNodeData[]; removed: TreeNodeData | null } {\n let removed: TreeNodeData | null = null\n const remaining = data.filter((n) => {\n if (getKey(n) === targetKey) {\n removed = n\n return false\n }\n return true\n })\n if (!removed) {\n for (const n of remaining) {\n const children = getChildren(n)\n if (children && children.length > 0) {\n const result = removeFromTree(children, targetKey)\n if (result.removed) {\n ;(n as Record<string, unknown>)[fn.children] = result.remaining\n return { remaining, removed: result.removed }\n }\n }\n }\n }\n return { remaining, removed }\n }\n\n function insertIntoTree(\n data: TreeNodeData[],\n targetKey: TreeKey,\n node: TreeNodeData,\n position: -1 | 0 | 1,\n ): TreeNodeData[] {\n if (position === 0) {\n return data.map((n) => {\n if (getKey(n) === targetKey) {\n const children = getChildren(n) ?? []\n ;(n as Record<string, unknown>)[fn.children] = [...children, node]\n return n\n }\n const children = getChildren(n)\n if (children && children.length > 0) {\n ;(n as Record<string, unknown>)[fn.children] = insertIntoTree(children, targetKey, node, position)\n }\n return n\n })\n }\n\n const result: TreeNodeData[] = []\n for (const n of data) {\n if (getKey(n) === targetKey) {\n if (position === -1) {\n result.push(node, n)\n } else {\n result.push(n, node)\n }\n } else {\n const children = getChildren(n)\n if (children && children.length > 0) {\n ;(n as Record<string, unknown>)[fn.children] = insertIntoTree(children, targetKey, node, position)\n }\n result.push(n)\n }\n }\n return result\n }\n\n function publishState(): void {\n const path = (k: string) => `${TREE_PREFIX}${treeId}.${k}`\n core.batch(() => {\n core.set(path('expandedKeys'), [...expandedKeys])\n core.set(path('checkedKeys'), [...checkedKeys])\n core.set(path('halfCheckedKeys'), [...halfCheckedKeys])\n core.set(path('selectedKeys'), [...selectedKeys])\n core.set(path('loadedKeys'), [...loadedKeys])\n core.set(path('loadingKeys'), [...loadingKeys])\n })\n }\n\n function initDefaults(): void {\n if (options?.defaultExpandAll) {\n for (const [key, internal] of nodeMap) {\n if (!internal.isLeaf) expandedKeys.add(key)\n }\n }\n\n if (options?.defaultCheckedKeys && !checkStrictly) {\n for (const key of options.defaultCheckedKeys) {\n cascadeCheck(key, true)\n }\n }\n\n recomputeHalfChecked()\n publishState()\n }\n\n const engine: TreeEngine = {\n setData(data: TreeNodeData[]): void {\n nodes = data\n buildMap(data)\n initDefaults()\n },\n\n getData(): TreeNodeData[] {\n return nodes\n },\n\n // Expand\n expand(key: TreeKey): void {\n expandedKeys.add(key)\n publishState()\n },\n\n collapse(key: TreeKey): void {\n expandedKeys.delete(key)\n publishState()\n },\n\n toggleExpand(key: TreeKey): void {\n if (expandedKeys.has(key)) expandedKeys.delete(key)\n else expandedKeys.add(key)\n publishState()\n },\n\n setExpandedKeys(keys: TreeKey[]): void {\n expandedKeys = new Set(keys)\n publishState()\n },\n\n expandAll(): void {\n for (const [key, internal] of nodeMap) {\n if (!internal.isLeaf) expandedKeys.add(key)\n }\n publishState()\n },\n\n collapseAll(): void {\n expandedKeys = new Set()\n publishState()\n },\n\n // Check\n check(key: TreeKey): void {\n cascadeCheck(key, true)\n publishState()\n },\n\n uncheck(key: TreeKey): void {\n cascadeCheck(key, false)\n publishState()\n },\n\n toggleCheck(key: TreeKey): void {\n const checked = !checkedKeys.has(key)\n cascadeCheck(key, checked)\n publishState()\n },\n\n setCheckedKeys(keys: TreeKey[]): void {\n checkedKeys = new Set(keys)\n recomputeHalfChecked()\n publishState()\n },\n\n // Select\n select(key: TreeKey, multiple?: boolean): void {\n if (multiple) {\n if (selectedKeys.has(key)) selectedKeys.delete(key)\n else selectedKeys.add(key)\n } else {\n selectedKeys = new Set([key])\n }\n publishState()\n },\n\n deselect(key: TreeKey): void {\n selectedKeys.delete(key)\n publishState()\n },\n\n setSelectedKeys(keys: TreeKey[]): void {\n selectedKeys = new Set(keys)\n publishState()\n },\n\n // Async loading\n markLoading(key: TreeKey): void {\n loadingKeys.add(key)\n publishState()\n },\n\n markLoaded(key: TreeKey): void {\n loadingKeys.delete(key)\n loadedKeys.add(key)\n publishState()\n },\n\n addChildren(parentKey: TreeKey, children: TreeNodeData[]): void {\n const internal = nodeMap.get(parentKey)\n if (!internal) return\n ;(internal.node as Record<string, unknown>)[fn.children] = children\n buildMap(nodes)\n publishState()\n },\n\n // Drag & drop\n moveNode(dragKey: TreeKey, dropKey: TreeKey, position: -1 | 0 | 1): TreeNodeData[] | null {\n if (dragKey === dropKey) return null\n const ancestors = getAllAncestorKeys(dropKey)\n if (ancestors.includes(dragKey)) return null\n\n const { remaining, removed } = removeFromTree(nodes, dragKey)\n if (!removed) return null\n\n nodes = insertIntoTree(remaining, dropKey, removed, position)\n buildMap(nodes)\n publishState()\n return nodes\n },\n\n // Filter\n filterNodes(predicate: ((node: TreeNodeData) => boolean) | null): void {\n if (!predicate) {\n filteredKeys = null\n return\n }\n const matched = new Set<TreeKey>()\n for (const [key, internal] of nodeMap) {\n if (predicate(internal.node)) {\n matched.add(key)\n const ancestors = getAllAncestorKeys(key)\n for (const ak of ancestors) matched.add(ak)\n }\n }\n filteredKeys = matched\n },\n\n getFilteredKeys(): TreeKey[] | null {\n return filteredKeys ? [...filteredKeys] : null\n },\n\n // Query\n getNode(key: TreeKey): TreeNodeData | undefined {\n return nodeMap.get(key)?.node\n },\n\n getParentKey(key: TreeKey): TreeKey | null {\n return nodeMap.get(key)?.parentKey ?? null\n },\n\n getChildKeys(key: TreeKey): TreeKey[] {\n return nodeMap.get(key)?.childKeys ?? []\n },\n\n getAllKeys(): TreeKey[] {\n return [...nodeMap.keys()]\n },\n\n getLeafKeys(): TreeKey[] {\n const result: TreeKey[] = []\n for (const [key, internal] of nodeMap) {\n if (internal.isLeaf) result.push(key)\n }\n return result\n },\n\n getState(): TreeState {\n return {\n expandedKeys: [...expandedKeys],\n checkedKeys: [...checkedKeys],\n halfCheckedKeys: [...halfCheckedKeys],\n selectedKeys: [...selectedKeys],\n loadedKeys: [...loadedKeys],\n loadingKeys: [...loadingKeys],\n }\n },\n\n getFlatNodes() {\n const result: Array<{ node: TreeNodeData; key: TreeKey; depth: number; isLeaf: boolean; parentKey: TreeKey | null }> = []\n\n function walk(list: TreeNodeData[], parentKey: TreeKey | null, depth: number) {\n for (const n of list) {\n const k = getKey(n)\n if (filteredKeys && !filteredKeys.has(k)) continue\n\n const children = getChildren(n)\n const isLeaf = n.isLeaf === true || (!children || children.length === 0)\n\n result.push({ node: n, key: k, depth, isLeaf, parentKey })\n\n if (!isLeaf && expandedKeys.has(k) && children && children.length > 0) {\n walk(children, k, depth + 1)\n }\n }\n }\n\n walk(nodes, null, 0)\n return result\n },\n\n reset(): void {\n nodes = []\n nodeMap = new Map()\n expandedKeys = new Set()\n checkedKeys = new Set()\n halfCheckedKeys = new Set()\n selectedKeys = new Set()\n loadedKeys = new Set()\n loadingKeys = new Set()\n filteredKeys = null\n publishState()\n },\n }\n\n return engine\n}\n","import type { AvailabilityRule, DayOfWeek, Resource } from './types'\n\nconst DAY_MS = 86_400_000\n\n/**\n * Parse `HH:MM` into milliseconds-from-midnight.\n *\n * Returns `null` for malformed input — callers treat that as \"rule has no\n * window on this side\" (i.e. the canonical 00:00 / 24:00 fallback).\n */\nfunction parseHHMM(s: string | undefined, fallback: number): number {\n if (s === undefined) return fallback\n const m = /^(\\d{1,2}):(\\d{2})$/.exec(s)\n if (!m) return fallback\n const h = Number(m[1])\n const mm = Number(m[2])\n if (!Number.isFinite(h) || !Number.isFinite(mm)) return fallback\n if (h < 0 || h > 24 || mm < 0 || mm >= 60) return fallback\n return h * 3_600_000 + mm * 60_000\n}\n\n/** Rules attached to one resource. Cheap to compute, cached per call. */\nfunction rulesFor(\n resourceId: string,\n rules: readonly AvailabilityRule[],\n): AvailabilityRule[] {\n return rules.filter((r) => r.resourceId === resourceId)\n}\n\nfunction dayBucket(t: number): { dayStart: number; dayOfWeek: DayOfWeek } {\n // Floor to UTC day boundary; getUTCDay returns 0..6 (Sun..Sat).\n const d = new Date(t)\n const dayStart =\n Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate())\n const dayOfWeek = new Date(dayStart).getUTCDay() as DayOfWeek\n return { dayStart, dayOfWeek }\n}\n\n/**\n * `true` ⇔ the entire `[start, end)` interval falls inside at least one\n * availability window for `resource`. A resource without any matching\n * rule (or without any rules at all) is considered always available —\n * unconfigured calendars stay friendly.\n *\n * Implementation: walk one UTC day at a time and check that the slice of\n * `[start, end)` intersected with that day is fully covered by the union\n * of windows attached to that day. The union is built by sorting rule\n * windows by `from` and merging overlaps in O(k log k) where k = rules\n * for that day (typically 1–3).\n */\nexport function isAvailable(\n resource: Resource,\n range: { start: number; end: number },\n rules: readonly AvailabilityRule[],\n): boolean {\n if (range.end <= range.start) return true\n\n const own = rulesFor(resource.id, rules)\n if (own.length === 0) return true\n\n let cursor = range.start\n while (cursor < range.end) {\n const { dayStart, dayOfWeek } = dayBucket(cursor)\n const dayEnd = dayStart + DAY_MS\n const sliceEnd = Math.min(range.end, dayEnd)\n\n const dayRules = own.filter(\n (r) => r.dayOfWeek === undefined || r.dayOfWeek === dayOfWeek,\n )\n if (dayRules.length === 0) return false\n\n // Build union of windows for this day, in absolute ms.\n const intervals = dayRules\n .map((r) => {\n const fromMs = parseHHMM(r.from, 0)\n const toMs = parseHHMM(r.to, DAY_MS)\n return { from: dayStart + fromMs, to: dayStart + toMs }\n })\n .filter((w) => w.to > w.from)\n .sort((a, b) => a.from - b.from)\n\n if (intervals.length === 0) return false\n\n const merged: Array<{ from: number; to: number }> = []\n for (const w of intervals) {\n const last = merged[merged.length - 1]\n if (last && w.from <= last.to) {\n last.to = Math.max(last.to, w.to)\n } else {\n merged.push({ ...w })\n }\n }\n\n // The required slice for this day is [cursor, sliceEnd). It must be\n // fully contained in the union. We sweep the merged windows.\n let needed = cursor\n for (const w of merged) {\n if (w.from > needed) return false\n if (w.to >= sliceEnd) {\n needed = sliceEnd\n break\n }\n needed = Math.max(needed, w.to)\n }\n if (needed < sliceEnd) return false\n\n cursor = sliceEnd\n }\n\n return true\n}\n","import { isAvailable } from './availability'\nimport type {\n Assignment,\n AvailabilityRule,\n CalendarScale,\n CalendarState,\n Conflict,\n Resource,\n} from './types'\n\nconst DAY_MS = 86_400_000\nconst STEP_MS: Record<CalendarScale, number> = {\n day: DAY_MS,\n week: 7 * DAY_MS,\n month: 30 * DAY_MS,\n}\n\nexport interface DetectConflictsArgs {\n scale?: CalendarScale\n rules?: readonly AvailabilityRule[]\n}\n\nfunction makeId(reason: Conflict['reason'], ids: readonly string[]): string {\n return `${reason}:${[...ids].sort().join(',')}`\n}\n\nfunction pushConflict(\n out: Map<string, Conflict>,\n reason: Conflict['reason'],\n ids: string[],\n): void {\n if (ids.length === 0) return\n const sorted = [...ids].sort()\n const id = makeId(reason, sorted)\n if (out.has(id)) return\n out.set(id, { id, reason, assignmentIds: sorted })\n}\n\n/**\n * Find all conflicts in `state`.\n *\n * Algorithm — three independent passes, results de-duplicated by\n * `(reason, sorted-ids)` so the same overlapping pair is never reported\n * twice as `overlap`:\n *\n * 1. **overlap** (per resource): sort assignments by `start` and sweep.\n * Keep an active set ordered by `end` ASC; whenever a new\n * assignment opens, every still-active assignment forms a pairwise\n * `overlap` conflict with it. O(n log n + k) where k = total\n * overlapping pairs.\n *\n * 2. **over-capacity** (per resource with `capacityPerSlot`): bucket\n * every assignment into the slots it touches (1 slot = 1 scale\n * step). For each slot whose concurrent count exceeds capacity,\n * emit one `over-capacity` conflict naming exactly the assignments\n * that touch that slot. This is the simple counter approach (no\n * interval tree) — fine up to ~10⁵ assignments per resource.\n *\n * 3. **outside-availability**: per-assignment check via\n * `isAvailable`. Each violation becomes its own one-element\n * conflict.\n */\nexport function detectConflicts(\n state: Pick<CalendarState, 'resources' | 'assignments'>,\n opts: DetectConflictsArgs = {},\n): Conflict[] {\n const scale = opts.scale ?? 'day'\n const step = STEP_MS[scale]\n const rules = opts.rules ?? []\n const conflicts = new Map<string, Conflict>()\n\n const byResource = new Map<string, Assignment[]>()\n for (const a of state.assignments) {\n let bucket = byResource.get(a.resourceId)\n if (!bucket) {\n bucket = []\n byResource.set(a.resourceId, bucket)\n }\n bucket.push(a)\n }\n\n // ── 1. Pairwise overlap (per resource) ─────────────────────────────\n for (const list of byResource.values()) {\n const sorted = [...list].sort((x, y) => x.start - y.start)\n for (let i = 0; i < sorted.length; i++) {\n const a = sorted[i]!\n for (let j = i + 1; j < sorted.length; j++) {\n const b = sorted[j]!\n if (b.start >= a.end) break\n // Touching boundaries (b.start === a.end) is NOT a conflict —\n // assignment ranges are half-open [start, end).\n pushConflict(conflicts, 'overlap', [a.id, b.id])\n }\n }\n }\n\n // ── 2. Over-capacity per slot (per resource with capacityPerSlot) ──\n const resourceById = new Map<string, Resource>()\n for (const r of state.resources) resourceById.set(r.id, r)\n\n for (const [rid, list] of byResource) {\n const resource = resourceById.get(rid)\n if (!resource || resource.capacityPerSlot === undefined) continue\n const cap = Math.max(0, Math.floor(resource.capacityPerSlot))\n\n const slotMap = new Map<number, string[]>()\n for (const a of list) {\n // Every slot the assignment touches.\n const lo = Math.floor(a.start / step) * step\n const hi = Math.ceil(a.end / step) * step\n for (let s = lo; s < hi; s += step) {\n let bucket = slotMap.get(s)\n if (!bucket) {\n bucket = []\n slotMap.set(s, bucket)\n }\n bucket.push(a.id)\n }\n }\n\n for (const ids of slotMap.values()) {\n if (ids.length > cap) {\n pushConflict(conflicts, 'over-capacity', ids)\n }\n }\n }\n\n // ── 3. Outside availability (per assignment) ───────────────────────\n if (rules.length > 0) {\n for (const a of state.assignments) {\n const r = resourceById.get(a.resourceId)\n if (!r) continue\n if (!isAvailable(r, { start: a.start, end: a.end }, rules)) {\n pushConflict(conflicts, 'outside-availability', [a.id])\n }\n }\n }\n\n return [...conflicts.values()]\n}\n","import type { Core } from '../../types'\nimport { CALENDAR_PREFIX } from '../namespaces'\nimport { detectConflicts } from './conflicts'\nimport type {\n Assignment,\n AvailabilityRule,\n CalendarEngine,\n CalendarEngineOptions,\n CalendarScale,\n CalendarState,\n Conflict,\n Resource,\n} from './types'\n\nlet calendarCounter = 0\n\n/**\n * Resource Calendar engine — the sixth member of the\n * form / table / tree / virtual / graph / **calendar** family.\n *\n * The in-memory maps are the source of truth and the public read API;\n * snapshots are mirrored to the Core store under\n * `$calendar.<id>.{resources,assignments,conflicts,view}` so other\n * engines / external observers can react via `core.subscribe(...)`.\n *\n * v0 scope:\n * - addResource / removeResource / updateResource\n * - addAssignment / updateAssignment / removeAssignment\n * - moveAssignment(id, deltaMs) — shifts both ends together\n * - resizeAssignment(id, side, deltaMs) — clamps so width >= 1ms\n * - setRules / setScale — re-compute conflicts on change\n * - detectConflicts under the hood; status of involved assignments\n * is auto-promoted to `'conflict'` so the React adapter can render\n * without re-running the algorithm.\n *\n * NOT in v0 (deferred to round-10):\n * - exception dates on `AvailabilityRule`\n * - full per-engine undo/redo (use `core.snapshot/restore` instead)\n * - aggregate read APIs over a sub-range\n */\nexport function createCalendar(\n core: Core,\n options?: CalendarEngineOptions,\n): CalendarEngine {\n const engineId = `c${calendarCounter++}${options?.name ? `-${options.name}` : ''}`\n const prefix = CALENDAR_PREFIX\n\n const resources = new Map<string, Resource>()\n const assignments = new Map<string, Assignment>()\n let rules: AvailabilityRule[] = options?.rules ? [...options.rules] : []\n let scale: CalendarScale = options?.scale ?? 'day'\n let conflicts: Conflict[] = []\n\n const localSubscribers = new Set<() => void>()\n\n function publish(): void {\n const resList = [...resources.values()]\n const assignList = [...assignments.values()]\n core.batch(() => {\n core.set(`${prefix}${engineId}.resources`, resList)\n core.set(`${prefix}${engineId}.assignments`, assignList)\n core.set(`${prefix}${engineId}.conflicts`, conflicts)\n core.set(`${prefix}${engineId}.view`, { scale })\n })\n for (const cb of localSubscribers) cb()\n }\n\n function recompute(): void {\n conflicts = detectConflicts(\n { resources: [...resources.values()], assignments: [...assignments.values()] },\n { scale, rules },\n )\n // Promote involved assignments to status: 'conflict'. Assignments\n // that aren't in any conflict get their original (or default)\n // status restored. We don't lose the underlying intent: the\n // promotion is reversible and recomputed on every mutation.\n const involved = new Set<string>()\n for (const c of conflicts) for (const id of c.assignmentIds) involved.add(id)\n for (const [id, a] of assignments) {\n const isConflicting = involved.has(id)\n if (isConflicting && a.status !== 'conflict') {\n assignments.set(id, { ...a, status: 'conflict' })\n } else if (!isConflicting && a.status === 'conflict') {\n // Drop the auto-`conflict` flag — the original intent (tentative\n // / confirmed / undefined) was lost when we promoted, and the\n // adapter only needs to know \"no longer conflicting\", so we\n // default back to `'tentative'` which is the safest fallback.\n assignments.set(id, { ...a, status: 'tentative' })\n }\n }\n }\n\n function commitAndPublish(): void {\n recompute()\n publish()\n }\n\n function subscribe(cb: () => void): () => void {\n localSubscribers.add(cb)\n return () => {\n localSubscribers.delete(cb)\n }\n }\n\n function addResource(resource: Resource): void {\n if (resources.has(resource.id)) {\n throw new Error(\n `[skygraph/calendar] resource id \"${resource.id}\" already exists`,\n )\n }\n resources.set(resource.id, { ...resource })\n commitAndPublish()\n }\n\n function removeResource(id: string): void {\n if (!resources.has(id)) return\n resources.delete(id)\n // Cascade: drop assignments tied to this resource.\n for (const [aid, a] of assignments) {\n if (a.resourceId === id) assignments.delete(aid)\n }\n commitAndPublish()\n }\n\n function updateResource(id: string, patch: Partial<Resource>): void {\n const r = resources.get(id)\n if (!r) throw new Error(`[skygraph/calendar] resource \"${id}\" not found`)\n resources.set(id, { ...r, ...patch, id })\n commitAndPublish()\n }\n\n function getResource(id: string): Resource | undefined {\n return resources.get(id)\n }\n\n function getResources(): Resource[] {\n return [...resources.values()]\n }\n\n function addAssignment(assignment: Assignment): void {\n if (assignments.has(assignment.id)) {\n throw new Error(\n `[skygraph/calendar] assignment id \"${assignment.id}\" already exists`,\n )\n }\n if (!resources.has(assignment.resourceId)) {\n throw new Error(\n `[skygraph/calendar] addAssignment: resource \"${assignment.resourceId}\" not found`,\n )\n }\n if (assignment.end <= assignment.start) {\n throw new Error(\n `[skygraph/calendar] addAssignment: end (${assignment.end}) must be greater than start (${assignment.start})`,\n )\n }\n assignments.set(assignment.id, { ...assignment })\n commitAndPublish()\n }\n\n function updateAssignment(id: string, patch: Partial<Assignment>): void {\n const a = assignments.get(id)\n if (!a) throw new Error(`[skygraph/calendar] assignment \"${id}\" not found`)\n const next: Assignment = { ...a, ...patch, id }\n if (next.end <= next.start) {\n throw new Error(\n `[skygraph/calendar] updateAssignment: end (${next.end}) must be greater than start (${next.start})`,\n )\n }\n if (!resources.has(next.resourceId)) {\n throw new Error(\n `[skygraph/calendar] updateAssignment: resource \"${next.resourceId}\" not found`,\n )\n }\n assignments.set(id, next)\n commitAndPublish()\n }\n\n function removeAssignment(id: string): void {\n if (!assignments.has(id)) return\n assignments.delete(id)\n commitAndPublish()\n }\n\n function moveAssignment(id: string, deltaMs: number): void {\n const a = assignments.get(id)\n if (!a) throw new Error(`[skygraph/calendar] assignment \"${id}\" not found`)\n if (deltaMs === 0) return\n assignments.set(id, { ...a, start: a.start + deltaMs, end: a.end + deltaMs })\n commitAndPublish()\n }\n\n function resizeAssignment(\n id: string,\n side: 'start' | 'end',\n deltaMs: number,\n ): void {\n const a = assignments.get(id)\n if (!a) throw new Error(`[skygraph/calendar] assignment \"${id}\" not found`)\n if (deltaMs === 0) return\n let next: Assignment\n if (side === 'end') {\n const nextEnd = Math.max(a.start + 1, a.end + deltaMs)\n next = { ...a, end: nextEnd }\n } else {\n const nextStart = Math.min(a.end - 1, a.start + deltaMs)\n next = { ...a, start: nextStart }\n }\n assignments.set(id, next)\n commitAndPublish()\n }\n\n function getAssignment(id: string): Assignment | undefined {\n return assignments.get(id)\n }\n\n function getAssignments(): Assignment[] {\n return [...assignments.values()]\n }\n\n function setRules(next: readonly AvailabilityRule[]): void {\n rules = [...next]\n commitAndPublish()\n }\n\n function getRules(): AvailabilityRule[] {\n return [...rules]\n }\n\n function getConflicts(): Conflict[] {\n return [...conflicts]\n }\n\n function setScale(next: CalendarScale): void {\n if (next === scale) return\n scale = next\n commitAndPublish()\n }\n\n function getScale(): CalendarScale {\n return scale\n }\n\n function getState(): CalendarState {\n return {\n resources: [...resources.values()],\n assignments: [...assignments.values()],\n conflicts: [...conflicts],\n }\n }\n\n function clear(): void {\n resources.clear()\n assignments.clear()\n rules = []\n conflicts = []\n publish()\n }\n\n publish() // initial empty publish so subscribers see a stable shape\n\n return {\n id: engineId,\n addResource,\n removeResource,\n updateResource,\n getResource,\n getResources,\n addAssignment,\n updateAssignment,\n removeAssignment,\n moveAssignment,\n resizeAssignment,\n getAssignment,\n getAssignments,\n setRules,\n getRules,\n getConflicts,\n setScale,\n getScale,\n getState,\n subscribe,\n clear,\n }\n}\n"],"mappings":"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","names":["snap","key","createHistory","createHistory","snap","key","key","children","DAY_MS"]}
|