@aglyn/aglyn 1.0.0-beta.223 → 1.0.0-beta.224
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aglyn/aglyn",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.224",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"homepage": "https://aglyn.com",
|
|
6
6
|
"repository": {
|
|
@@ -37,16 +37,16 @@
|
|
|
37
37
|
"./package.json": "./package.json"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@aglyn/shared-data-enums": "1.0.0-beta.
|
|
41
|
-
"@aglyn/shared-data-mdi": "1.0.0-beta.
|
|
42
|
-
"@aglyn/shared-data-types": "1.0.0-beta.
|
|
43
|
-
"@aglyn/shared-util-email": "1.0.0-beta.
|
|
44
|
-
"@aglyn/shared-util-first-touch": "1.0.0-beta.
|
|
45
|
-
"@aglyn/shared-util-http": "1.0.0-beta.
|
|
46
|
-
"@aglyn/shared-util-logger": "1.0.0-beta.
|
|
47
|
-
"@aglyn/shared-util-timestamp": "1.0.0-beta.
|
|
48
|
-
"@aglyn/shared-util-tools": "1.0.0-beta.
|
|
49
|
-
"@aglyn/shared-util-vendor": "1.0.0-beta.
|
|
40
|
+
"@aglyn/shared-data-enums": "1.0.0-beta.224",
|
|
41
|
+
"@aglyn/shared-data-mdi": "1.0.0-beta.224",
|
|
42
|
+
"@aglyn/shared-data-types": "1.0.0-beta.224",
|
|
43
|
+
"@aglyn/shared-util-email": "1.0.0-beta.224",
|
|
44
|
+
"@aglyn/shared-util-first-touch": "1.0.0-beta.224",
|
|
45
|
+
"@aglyn/shared-util-http": "1.0.0-beta.224",
|
|
46
|
+
"@aglyn/shared-util-logger": "1.0.0-beta.224",
|
|
47
|
+
"@aglyn/shared-util-timestamp": "1.0.0-beta.224",
|
|
48
|
+
"@aglyn/shared-util-tools": "1.0.0-beta.224",
|
|
49
|
+
"@aglyn/shared-util-vendor": "1.0.0-beta.224",
|
|
50
50
|
"@data-driven-forms/react-form-renderer": "^4.2.0",
|
|
51
51
|
"@msgpack/msgpack": "^3.1.3",
|
|
52
52
|
"@types/unist": "^3.0.3",
|
|
@@ -30,7 +30,9 @@ export const NODE_ROOT_ID = '_@_';
|
|
|
30
30
|
export const NODE_ROOT_LABEL = 'Document';
|
|
31
31
|
export class AglynNode {
|
|
32
32
|
get parent() {
|
|
33
|
-
|
|
33
|
+
// The root is stored as its own parent (`parentId: "_@_"`); answering it
|
|
34
|
+
// here would hand every ancestor walk an endless loop (AGL-3565).
|
|
35
|
+
if (!this.parentId || this.parentId === this.$id) return;
|
|
34
36
|
return this.store.getNode(this.parentId);
|
|
35
37
|
}
|
|
36
38
|
get index() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../libs/aglyn/src/lib/canvas-manager/canvas-manager.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { _isObj, _isStrT } from '@aglyn/shared-util-tools'\nimport { arraySafe } from '@aglyn/shared-util-tools'\nimport cloneDeep from 'lodash-es/cloneDeep.js'\nimport isEqual from 'lodash-es/isEqual.js'\nimport {\n action,\n computed,\n type IObservableArray,\n makeAutoObservable,\n makeObservable,\n observable,\n observableRef,\n type ObservableMap,\n runInAction,\n toJS,\n} from 'mobx'\n// The leaf module, not the 68 KB package bundle — see the note there.\nimport { computedFn } from '@aglyn/shared-util-vendor/mobx-computed-fn'\nimport type { Aglyn } from '../aglyn'\nimport type { NodeInteraction } from '../app-utils/node-interactions'\nimport { schemaAcceptsChildren } from '../app-utils/child-contract'\nimport { REUSABLE_INSTANCE_COMPONENT_ID } from '../app-utils/reusable-component-keys'\nimport { stripUndefinedDeep } from '../app-utils/strip-undefined'\nimport { createIdUrlSafe } from '../foundation/constants/app'\nimport type { PluginId } from '../plugin-manager'\nimport {\n type ComponentId,\n type ComponentSchema,\n type NodeBreadcrumbPath,\n type NodeId,\n type NodeSchema,\n type NodeSchemaJSON,\n type NodeSchemaNested,\n type NodesMap,\n NodeType,\n type PresetSchema,\n type ProcessableNodes,\n} from '../types/nodes'\n\nexport const NODE_ROOT_ID = '_@_'\nexport const NODE_ROOT_LABEL = 'Document'\n\nexport class AglynNode<P = JSX.AnyProps> implements NodeSchema<P> {\n // public store: CanvasManager\n public $id: NodeId\n public name?: string\n public type: NodeType | string\n public pluginId?: PluginId\n public componentId?: ComponentId\n public parentId?: NodeId\n public nodes?: NodeId[]\n public props: P\n public sx?: JSX.SxProps\n public className?: string\n /**\n * Per-instance style overrides (AGL-1306) — see `NodeSchema`. Assigned\n * by name like every other field: this constructor DROPS unknown\n * top-level keys, so forgetting a field here silently strips it from\n * every canvas round-trip.\n */\n public styleOverrides?: Record<string, JSX.SxProps>\n /**\n * Per-instance attribute overrides (AGL-1899) — see `NodeSchema`. Same\n * three-touch-point rule as `styleOverrides` above: declared here,\n * assigned in the constructor, emitted in `toJSON`. Miss one and the\n * field survives in memory but not across a save.\n */\n public attrOverrides?: Record<string, Record<string, unknown>>\n /**\n * A screen's layout style overrides, on the canvas root only (AGL-3286) —\n * see `NodeSchema`. Same three touch points as the fields around it.\n */\n public layoutStyleOverrides?: Record<\n string,\n Record<string, Record<string, unknown>>\n >\n /**\n * Interactions authored on this element — see `NodeSchema`.\n * Third field under the same three-touch-point rule as the two above:\n * declared here, assigned in the constructor, emitted in `toJSON`.\n */\n public interactions?: NodeInteraction[]\n /**\n * Hidden by the author — see `NodeSchema`. Same three touch\n * points, and it needs all of them for a second reason as well: an\n * undeclared field assigned at runtime is not observable, so the hierarchy\n * row would not repaint when the eye was clicked.\n */\n public hidden?: boolean\n\n get parent(): NodeSchema<any> | undefined {\n if (!this.parentId) return\n return this.store.getNode(this.parentId)\n }\n get index(): number | null {\n return this.store.getNodeIndex(this)\n }\n get children(): NodeSchema<any>[] {\n const res: NodeSchema[] = []\n // `?? []`, not `||= []` — a computed getter must not assign to observable\n // state, and this only reads (AGL-763).\n for (const $id of this.nodes ?? []) {\n const node = this.store.getNode($id)\n if (node) res.push(node)\n }\n return res\n }\n get labelShort(): string {\n return this.store.getNodeLabelShort(this)\n }\n get breadcrumbPath(): NodeBreadcrumbPath {\n return this.store.getNodeBreadcrumbPath(this)\n }\n get componentSchema(): ComponentSchema | undefined {\n if (!this.componentId) return\n return this.store.aglyn.components.getSchema(this.componentId)\n }\n get hasNodes(): boolean {\n return Array.isArray(this.nodes) && this.nodes.length > 0\n }\n get resolvedProps(): P {\n const resolveProps = this.componentSchema?.resolveProps\n if (typeof resolveProps === 'function') {\n return (resolveProps(this) || {}) as P\n }\n return this.props\n }\n\n get asJSON(): NodeSchemaJSON<P> {\n return this.toJSON()\n }\n\n constructor(\n schema: NodeSchema<P>,\n public store: CanvasManager,\n ) {\n this.$id = schema.$id\n this.name = schema.name\n this.type = schema.type || NodeType.NODE\n this.parentId = schema.parentId\n this.pluginId = schema.pluginId\n this.componentId = schema.componentId\n this.className = schema.className\n this.nodes = Array.isArray(schema.nodes) ? [...schema.nodes] : []\n this.props = { ...schema.props } as P\n this.sx = Array.isArray(schema.sx) ? [...schema.sx] : { ...schema.sx }\n this.styleOverrides = schema.styleOverrides\n ? { ...schema.styleOverrides }\n : undefined\n this.attrOverrides = schema.attrOverrides\n ? { ...schema.attrOverrides }\n : undefined\n this.layoutStyleOverrides = schema.layoutStyleOverrides\n ? { ...schema.layoutStyleOverrides }\n : undefined\n this.interactions = Array.isArray(schema.interactions)\n ? [...schema.interactions]\n : undefined\n this.hidden = schema.hidden || undefined\n\n makeAutoObservable(this, {\n store: false,\n toJSON: false,\n })\n }\n\n public delete() {\n this.store.deleteNode(this)\n }\n\n public toJSON = (): NodeSchemaJSON<P> => {\n const json: Record<string, unknown> = {\n $id: this.$id,\n type: this.type,\n }\n // Omit optional scalar fields when undefined — Firestore rejects undefined values\n if (this.name !== undefined) json['name'] = this.name\n if (this.parentId !== undefined) json['parentId'] = this.parentId\n if (this.pluginId !== undefined) json['pluginId'] = this.pluginId\n if (this.componentId !== undefined) json['componentId'] = this.componentId\n if (this.className !== undefined) json['className'] = this.className\n // Omit collection fields when empty to save Firestore storage\n const nodes = this.nodes ? [...this.nodes] : []\n if (nodes.length > 0) json['nodes'] = nodes\n // The scalar omissions above stopped at the top level, so an OWN key\n // holding `undefined` inside these bags still reached storage (AGL-1334).\n // An editor form writes the whole field set back, so a never-set or\n // cleared optional attribute is such a key — and the two write paths then\n // disagreed: a save msgpacked it to `null`, a publish handed `undefined`\n // straight to `updateDoc()`, which rejects it. Stripping HERE is what\n // makes save and publish agree: both serialize from this one method.\n const props = stripUndefinedDeep(toJS(this.props))\n if (props && Object.keys(props).length > 0) json['props'] = props\n const sx = stripUndefinedDeep(toJS(this.sx))\n const sxEmpty = Array.isArray(sx) ? sx.length === 0 : !sx || Object.keys(sx).length === 0\n if (!sxEmpty) json['sx'] = sx\n // Instance style overrides (AGL-1306): emitted like sx — absent when\n // empty — so the SAVED node map carries them into both storage forms\n // (the plain map and the msgpack bytes both serialize this output).\n const styleOverrides = stripUndefinedDeep(toJS(this.styleOverrides))\n if (styleOverrides && Object.keys(styleOverrides).length > 0) {\n json['styleOverrides'] = styleOverrides\n }\n // Instance attribute overrides (AGL-1899): same treatment, same reason.\n const attrOverrides = stripUndefinedDeep(toJS(this.attrOverrides))\n if (attrOverrides && Object.keys(attrOverrides).length > 0) {\n json['attrOverrides'] = attrOverrides\n }\n // Layout style overrides (AGL-3286): same treatment. Only the screen\n // editor's root ever carries them, and its save lifts them out of the map.\n const layoutStyleOverrides = stripUndefinedDeep(\n toJS(this.layoutStyleOverrides),\n )\n if (layoutStyleOverrides && Object.keys(layoutStyleOverrides).length > 0) {\n json['layoutStyleOverrides'] = layoutStyleOverrides\n }\n // Element interactions: emitted like the bags above, absent\n // when empty. This is the field that makes them versioned with the\n // document at all — an interaction the canvas holds but this method\n // does not write is one that never reaches a save.\n const interactions = stripUndefinedDeep(toJS(this.interactions))\n if (Array.isArray(interactions) && interactions.length > 0) {\n json['interactions'] = interactions\n }\n // Author visibility. Emitted only when TRUE: `false` and\n // absent mean the same thing, and a field on every node in the document\n // is bytes on every save and every page.\n if (this.hidden) json['hidden'] = true\n return json as NodeSchemaJSON<P>\n }\n}\n\n/**\n * One recorded state, plus the {@link CanvasManager._epoch} it was taken at.\n *\n * The epoch is what makes a whole-document snapshot safe to restore in a\n * co-editing session (AGL-1958). Restoring the map wholesale reverts every\n * node in it — including nodes a *colleague* changed after the snapshot was\n * taken, whose new values the snapshot has never seen. Stamping each entry\n * lets {@link CanvasManager.restoreSnapshot} tell \"this remote change is\n * already in the snapshot\" from \"this remote change happened later and the\n * snapshot would undo it\", which is exactly the distinction a plain\n * `Map<K, T>` cannot express.\n */\ninterface HistorySnapshot<K extends string, T> {\n nodes: Map<K, T>\n epoch: number\n}\n\nclass HistoryManager<K extends string, T> {\n public present = observable.map<K, T>({})\n public past = observable.array<HistorySnapshot<K, T>>([], { deep: false })\n public future = observable.array<HistorySnapshot<K, T>>([], { deep: false })\n\n constructor() {\n makeObservable(this, {\n canUndo: computed,\n canRedo: computed,\n undo: action,\n redo: action,\n clearPast: action,\n clearFuture: action,\n clearHistory: action,\n saveHistory: action,\n })\n }\n\n public get [Symbol.toStringTag]() {\n return 'HistoryManager'\n }\n\n public toString(): string {\n return '[object HistoryManager]'\n }\n\n public toJSON(): {\n past: IObservableArray<HistorySnapshot<K, T>>\n present: ObservableMap<K, T>\n future: IObservableArray<HistorySnapshot<K, T>>\n } {\n return {\n past: toJS(this.past),\n present: toJS(this.present),\n future: toJS(this.future),\n }\n }\n\n public get canUndo() {\n return this.past.length >= 1\n }\n\n public get canRedo() {\n return this.future.length >= 1\n }\n\n public undo(epoch: number): HistorySnapshot<K, T> {\n if (!this.canUndo) throw new Error('No history to undo')\n this.future.push({ nodes: toJS(this.present), epoch })\n return this.past.pop()!\n }\n\n public redo(epoch: number): HistorySnapshot<K, T> {\n if (!this.canRedo) throw new Error('No history to redo')\n this.past.push({ nodes: toJS(this.present), epoch })\n return this.future.pop()!\n }\n\n public clearPast(): this {\n this.past.clear()\n return this\n }\n\n public clearFuture(): this {\n this.future.clear()\n return this\n }\n\n public clearHistory(): this {\n this.clearPast()\n this.clearFuture()\n return this\n }\n\n public saveHistory(epoch: number): this {\n this.clearFuture()\n this.past.push({ nodes: toJS(this.present), epoch })\n return this\n }\n}\n\nexport class CanvasManager {\n /**\n * How long a coalesced burst stays open. Comfortably above typing cadence\n * and slider tick rate, well below the pause that means \"a new adjustment\".\n */\n public static readonly COALESCE_WINDOW_MS = 500\n\n private _initial: NodesMap | undefined = undefined\n /**\n * Whether {@link _initial} is a state the STORE has confirmed, or merely\n * one the client believes. See {@link updateInitialNodes}.\n */\n private _initialConfirmed = true\n /**\n * The tree a SECOND store — one that is not the document — is known to\n * hold (AGL-3271). Undefined until something records one.\n *\n * {@link _initial} answers \"is there anything to save\", and on the version\n * a site is serving that answer is permanently yes: the working draft is\n * written beside the version and the version itself is deliberately left\n * alone, so the canvas differs from the document for as long as the draft\n * is unpublished. This is what lets a caller still ask the other question\n * — \"is this work stored anywhere\" — without pretending the document holds\n * it.\n */\n private _drafted: NodesMap | undefined = undefined\n private _history: HistoryManager<NodeId, NodeSchema<any>>\n /** The open {@link transact} burst, if any. See that method. */\n private _coalescing: { key: string; at: number } | undefined = undefined\n /** How deep the running {@link batch} calls are nested; 0 outside one. */\n private _batchDepth = 0\n /**\n * Monotonic counter, bumped once per node a REMOTE session changes. See\n * {@link markRemoteNode} and {@link restoreSnapshot} (AGL-1958).\n */\n private _epoch = 0\n /** Node id → the {@link _epoch} at which a remote session last touched it. */\n private _foreignAt = new Map<NodeId, number>()\n\n constructor(public aglyn: Aglyn) {\n makeObservable<\n CanvasManager,\n '_initial' | '_initialConfirmed' | '_drafted' | '_epoch'\n >(this, {\n _initial: observableRef,\n _initialConfirmed: observable,\n // Observable for the same reason `_epoch` is: {@link isDraftedSame} is\n // read while rendering the toolbar, and the label it decides has to\n // change on the author's next keystroke rather than on the next\n // unrelated render (AGL-3271).\n _drafted: observableRef,\n // Observable so {@link hasRemoteEdits} is a computed a React observer\n // re-renders on: the draft prompt has to stop offering Restore the\n // moment a peer's first change lands, not on the next unrelated\n // render (AGL-2486).\n _epoch: observable,\n nodes: computed,\n serializedNodes: computed,\n isInitialSame: computed,\n isDraftedSame: computed,\n didSetInitial: computed,\n hasRemoteEdits: computed,\n markRemoteNode: action,\n undo: action,\n redo: action,\n saveHistory: action,\n // An action so the snapshot and the mutation land in ONE mobx\n // transaction — otherwise `saveHistory` alone notifies observers, and\n // the canvas renders a frame between the two (AGL-1204).\n transact: action,\n // Same reason: several guarded mutators composed into one change are\n // one render, not one per mutator.\n batch: action,\n clearHistory: action,\n clearNodes: action,\n reset: action,\n updateInitialNodes: action,\n confirmInitialNodes: action,\n updateDraftedNodes: action,\n setNode: action,\n setNodes: action,\n applyNodes: action,\n deleteNode: action,\n reparentNode: action,\n reorderNode: action,\n updateNodeFields: action,\n updateNodeProps: action,\n })\n\n this._history = new HistoryManager()\n }\n\n public get nodes() {\n return this._history.present\n }\n\n public get canRedo() {\n return this._history.canRedo\n }\n public get canUndo() {\n return this._history.canUndo\n }\n /**\n * True when the canvas matches the last state the store is known to hold —\n * i.e. there is nothing to save.\n *\n * An UNCONFIRMED baseline (see {@link updateInitialNodes}) always reads as\n * different. The editor is loaded, but nothing in it is known to be\n * persisted, and \"clean\" here disables Save: claiming a state is saved on\n * the strength of a snapshot the server never acknowledged is how unsaved\n * work becomes unsavable work (AGL-1262).\n */\n /**\n * The node map as it would be stored, cached until a node changes.\n *\n * A mobx computed rather than a call per reader because there are two\n * readers now (AGL-3271): {@link isInitialSame} and {@link isDraftedSame}\n * both compare a baseline against this, both are read while rendering the\n * toolbar, and serializing the whole tree twice per keystroke on a\n * document that can reach a megabyte is a cost neither of them needs to\n * pay. Read-only by contract — both hand it to `isEqual` and neither may\n * mutate what comes back.\n */\n public get serializedNodes(): NodesMap {\n return this.serializeNodes()\n }\n public get isInitialSame() {\n if (!this._initial) return true\n if (!this._initialConfirmed) return false\n return isEqual(this._initial, this.serializedNodes)\n }\n /**\n * True when the canvas is exactly the tree last recorded by\n * {@link updateDraftedNodes} — i.e. this work is stored somewhere, even\n * though {@link isInitialSame} says the DOCUMENT does not have it\n * (AGL-3271).\n *\n * FALSE when nothing has been recorded, which is the opposite default to\n * {@link isInitialSame}: no baseline there means nothing is loaded and so\n * there is nothing to save, while no draft here means no draft — and\n * \"stored\" is a claim that needs evidence, never an absence of it.\n */\n public get isDraftedSame() {\n if (!this._drafted) return false\n return isEqual(this._drafted, this.serializedNodes)\n }\n public get didSetInitial() {\n return Boolean(this._initial)\n }\n /** Whether the recorded baseline is one the store confirmed. */\n public get isInitialConfirmed() {\n return this._initialConfirmed\n }\n public get rootNode() {\n return this.nodes.get(NODE_ROOT_ID)\n }\n public get nestedNodes(): NodeSchemaNested<any> {\n const root = this.rootNode\n if (!root) throw new Error('Missing root node')\n return this.makeNested(root)\n }\n\n public hasNode = computedFn(($id: NodeId): boolean => {\n return this.nodes.has($id)\n })\n public getNode = computedFn(($id: NodeId): NodeSchema<any> | undefined => {\n if (!$id) return\n return this.nodes.get($id)\n })\n public nodesAreEqual = computedFn(\n (left: NodesMap, right?: NodesMap): boolean => {\n const _right = right ? right : this.nodes\n return isEqual(toJS(left), toJS(_right))\n },\n )\n public getNodeParent = computedFn(\n (node: NodeSchema<any>): NodeSchema<any> | undefined => {\n if (!node) throw new Error('Invalid node')\n if (!node.parentId) return\n return this.getNode(node.parentId)\n },\n )\n public getNodeIndex = computedFn((node: NodeSchema<any>): number => {\n if (!node || !node.$id) throw new Error('Invalid node')\n const parent = this.getNodeParent(node)\n if (!parent) throw new Error('Invalid parent node')\n return parent.nodes?.indexOf(node.$id) ?? -1\n })\n public isRootNodeId = computedFn(\n (id: NodeId): id is string & typeof NODE_ROOT_ID => {\n return id === NODE_ROOT_ID\n },\n )\n public isRootNode = computedFn((node: NodeSchema<any>): boolean => {\n return node?.$id === NODE_ROOT_ID\n })\n public getNodeBreadcrumbPath = computedFn(\n (nodeOrId: NodeId | NodeSchema<any>): NodeBreadcrumbPath => {\n const hierarchy = [NODE_ROOT_ID]\n\n // Visited ids, not just the root check: the root terminates the walk on\n // a well-formed document, but two nodes that parent each other\n // terminate nothing. An unbounded ancestor walk is a synchronous\n // infinite loop on the renderer's main thread — the tab stops answering\n // input entirely — so a malformed tree has to cost a truncated\n // breadcrumb instead.\n const seen = new Set<string>()\n let currentId: string | undefined =\n typeof nodeOrId !== 'string' ? nodeOrId?.$id : nodeOrId\n while (currentId && !this.isRootNodeId(currentId) && !seen.has(currentId)) {\n seen.add(currentId)\n hierarchy.splice(1, 0, currentId)\n currentId = this.getNode(currentId)?.parentId\n }\n\n return hierarchy as NodeBreadcrumbPath\n },\n )\n public getNodeLabelShort = computedFn((node: NodeSchema<any>): any => {\n if (!node) throw new Error('Invalid node')\n if (this.isRootNode(node)) return NODE_ROOT_LABEL\n // A reusable-component instance stands for one specific definition, and\n // its component label is the same generic word for every one of them —\n // a page built from promoted sections reads as a column of identical\n // \"Reusable Component\" rows in the hierarchy and identical badges on the\n // canvas. The definition's name rides on the instance for exactly this\n // (`props.name`, AGL-1193), so prefer it. An explicit per-node `name`\n // still wins, since that is someone deliberately renaming this instance.\n const instanceName =\n node.componentId === REUSABLE_INSTANCE_COMPONENT_ID\n ? (node.props as { name?: unknown } | undefined)?.name\n : undefined\n const componentLabel =\n node.componentId && this.aglyn.components.getLabel(node.componentId)\n return (\n node?.name ||\n (_isStrT(instanceName) ? instanceName : undefined) ||\n componentLabel ||\n node?.$id\n )\n })\n\n /**\n * Whether a node can host inserted child nodes. The document root and\n * layout containers (Stack, Section, Container — anything with a real\n * children slot) can; a leaf whose component is self-closing or renders\n * its `children` as inline text (a screen link, button, icon, image) has\n * no slot to receive them and can't. Components with no registered schema\n * default to accepting children.\n *\n * `flags.dropping: DISABLED` is the third way to say \"no canvas child\n * slot\" (AGL-1388), for components that are neither self-closing nor text\n * leaves but still have nowhere to put a dropped node:\n *\n * - Markdown renders the parsed `content` prop and nothing else, so a\n * dropped element lands somewhere the markdown source cannot say.\n * - A Reusable Component instance is opaque: compose REPLACES its child\n * list with the grafted definition subtree, so a canvas-dropped child is\n * destroyed before the page is rendered.\n * - A Layout Slot's children come from screen composition.\n *\n * The flag was declared on all three, and until now nothing read it —\n * which is exactly how three /press screenshots came to be parented under\n * a Markdown node, shipped in the page payload, and never drawn. A\n * container that accepts children in the hierarchy and discards them at\n * render is silent data loss: the author sees the nodes in the tree and\n * the published page does not have them.\n *\n * The rule itself lives in {@link schemaAcceptsChildren} (AGL-1389) so the\n * registry audit that enforces it cannot be checking a *copy* of it — a\n * second implementation would drift, and would then certify the editor's\n * behaviour against a rule the editor no longer follows.\n */\n public nodeAcceptsChildren = computedFn((node: NodeSchema<any>): boolean => {\n if (!node) return false\n if (this.isRootNode(node)) return true\n return schemaAcceptsChildren(\n this.aglyn?.components?.getSchema(node.componentId),\n )\n })\n\n /**\n * Resolve where a newly inserted node should attach, given the node the\n * user had selected (the Insert menu passes the current selection). A\n * container target — including the document-root fallback for a missing,\n * stale, or non-node target (AGL-537) — receives the node as an appended\n * child. A leaf target has no child slot, so the node lands as the leaf's\n * next sibling in its own container instead, mirroring how a\n * drag-and-drop side-drop resolves rather than nesting the node where it\n * can never render.\n */\n public resolveInsertTarget(target?: NodeSchema<any>): {\n parent: NodeSchema<any>\n index: number\n } {\n const root = this.getNode(NODE_ROOT_ID)!\n const requested =\n (typeof target?.$id === 'string' && this.getNode(target.$id)) || root\n if (this.nodeAcceptsChildren(requested)) {\n return { parent: requested, index: NaN }\n }\n const parent = this.getNodeParent(requested) ?? root\n const at = parent.nodes?.indexOf(requested.$id) ?? -1\n return { parent, index: at < 0 ? NaN : at + 1 }\n }\n\n public makeNested = computedFn((node: NodeSchema<any>) => {\n // Serialize to a plain schema object: a toJS copy would carry the node's\n // own toJSON arrow (bound to the live instance), which JSON.stringify\n // would then prefer over the nested structure built here.\n const newNode = (\n node instanceof AglynNode ? node.toJSON() : { ...toJS(node) }\n ) as unknown as NodeSchemaNested<any>\n\n const childNodes: NodeSchemaNested<any>[] = []\n for (const childId of (toJS(node.nodes) || []) as unknown as NodeId[]) {\n const child = this.getNode(childId)\n if (child) {\n const nested = this.makeNested(child)\n childNodes.push(nested)\n }\n }\n newNode.nodes = childNodes\n\n return newNode\n })\n\n private serializeNodes(): NodesMap {\n const nodes: NodesMap = {}\n this.nodes.forEach((node, id) => {\n nodes[id] = node.toJSON()\n })\n return nodes\n }\n\n public toJSON() {\n return { nodes: this.serializeNodes() }\n }\n\n public redo(): this {\n return this.restoreSnapshot(this._history.redo(this._epoch))\n }\n public undo(): this {\n return this.restoreSnapshot(this._history.undo(this._epoch))\n }\n public saveHistory(): this {\n // Inside a batch, the snapshot the batch took is the step every mutation\n // folds into — see `batch`.\n if (this._batchDepth > 0) return this\n this._history.saveHistory(this._epoch)\n return this\n }\n /**\n * Records that a REMOTE session changed `nodeId`, so a later local undo\n * does not roll that change back (AGL-1958).\n *\n * Call this from the co-editing apply path for every node a peer creates,\n * changes or deletes — including the delete, whose absence is as much a\n * remote state as a value is.\n *\n * ## Why this is needed at all\n *\n * Applying a remote change deliberately does NOT record local history\n * (AGL-677 rule 1), which keeps a colleague's edit out of your undo\n * stack. That is necessary and it is not sufficient. Every entry already\n * in the stack is a snapshot of the WHOLE document taken before one of\n * your edits, and a colleague's later edit is by definition not in it. So\n * an undo that replays such a snapshot wholesale reverts their node too,\n * and — because the reverted map is then diffed against the co-editing\n * shadow like any other local edit — publishes that revert back to them\n * under YOUR session id. Their work is destroyed on their screen, with no\n * signal and nothing that restores it.\n *\n * Measured before this fix: a peer's edit came back reverted, and a node\n * the peer had CREATED was deleted outright.\n *\n * ## An apply that changed nothing is not a peer edit (AGL-2486)\n *\n * `previousJson` is the node's serialization from BEFORE the apply. When\n * the apply left it byte-for-byte identical, this records nothing: no\n * mark, no epoch bump. That is not an optimisation, it is the difference\n * between a peer edit and an ECHO, and getting it wrong broke undo\n * outright.\n *\n * The mirror is per node and every session in the room republishes what it\n * holds, so a value you wrote can come back to you from ANOTHER SESSION —\n * your own second tab most of all, which is ordinary once same-account\n * sessions count as co-editors. The room already drops your own tab's\n * echoes by session id, but not another session's echo of your value.\n *\n * Marking that echo is fatal because the mark is what {@link\n * restoreSnapshot} reads. It lands with a FRESH epoch, therefore newer\n * than every snapshot already on your stack, so the overlay puts the live\n * value back over each one of them. Undo then consumed its entry and\n * changed nothing at all — measured on the running editor, one account,\n * two tabs on one screen: `past: 0, future: 1, canUndo: false`, the node\n * still holding the edit that had just been undone.\n *\n * Note what this deliberately does NOT do: it does not ask whose session\n * or whose account the change came from. A genuinely different value from\n * your other tab is a real concurrent edit with its own undo stack and is\n * protected like any other. \"Foreign\" keeps its one meaning — a session\n * other than this tab moved this node — and the defect was counting a\n * non-change as a change.\n */\n public markRemoteNode(nodeId: NodeId, previousJson?: string): this {\n if (!nodeId) return this\n if (previousJson !== undefined) {\n const live = this.nodes.get(nodeId)\n const nowJson = live ? JSON.stringify(live.toJSON()) : undefined\n if (nowJson === previousJson) return this\n }\n this._foreignAt.set(nodeId, ++this._epoch)\n return this\n }\n /**\n * A node's serialization as it stands right now, for handing back to\n * {@link markRemoteNode} after an apply — the \"before\" half of the echo\n * test. `undefined` when the node is not in the map.\n */\n public serializeNode(nodeId: NodeId): string | undefined {\n const node = this.nodes.get(nodeId)\n return node ? JSON.stringify(node.toJSON()) : undefined\n }\n /**\n * Restores a history snapshot, keeping every node a remote session has\n * touched SINCE that snapshot was taken (AGL-1958).\n *\n * The epoch comparison is the whole mechanism, and it is what keeps undo\n * honest rather than merely safe:\n *\n * * `foreignAt > snapshot.epoch` — the peer's change landed *after* this\n * snapshot, so the snapshot predates it and would roll it back. Keep\n * what is live now: the current value, or the node's absence when the\n * peer deleted it.\n * * `foreignAt <= snapshot.epoch` — the snapshot was taken after the\n * peer's change and therefore already contains it. Restore it normally,\n * or undo would stop rewinding your own edits to co-edited nodes.\n *\n * A node both you and a peer changed resolves to the peer's value, which\n * is the same last-writer-wins rule the per-node mirror applies\n * everywhere else (AGL-677) rather than a new one invented here.\n *\n * A peer that adds a child republishes the parent's child list, so the\n * parent is marked too and its list survives with the child.\n *\n * ## Both directions, and why redo is not the special case it looks like\n *\n * This serves {@link redo} as well as {@link undo}, and the stamp is what\n * makes that work rather than a second rule (AGL-2486). A `future` entry\n * replays a state from before the undo, so the intuition is that it must\n * predate any later peer change and roll it back. It does not:\n * `HistoryManager.undo` captures the present and stamps it with the epoch\n * AT THE TIME OF THE UNDO, so a peer change that lands between the undo\n * and the redo is strictly newer than `snapshot.epoch` and is kept here —\n * including a node the peer CREATED in that gap, which the `future` entry\n * has no key for at all and a bare replace would broadcast as a delete.\n */\n private restoreSnapshot(\n snapshot: HistorySnapshot<NodeId, NodeSchema<any>>,\n ): this {\n const json: Record<NodeId, NodeSchema<any>> = Object.fromEntries(\n snapshot.nodes.entries(),\n )\n this.setNodes(this.withForeignNodes(json, snapshot.epoch) as NodesMap)\n return this\n }\n /**\n * Overlays the nodes a remote session has touched since `sinceEpoch` onto a\n * map about to REPLACE the canvas — the current value, or the node's\n * absence when the peer deleted it (AGL-1958).\n *\n * Shared by {@link restoreSnapshot} and {@link applyNodes} because it is\n * one rule, not two: any wholesale replace composed without knowledge of a\n * peer's change would otherwise roll that change back and — through the\n * co-editing diff — publish the rollback to its author.\n *\n * Mutates and returns `json`; callers pass a map they own.\n */\n private withForeignNodes(\n json: Record<NodeId, NodeSchema<any>>,\n sinceEpoch: number,\n ): Record<NodeId, NodeSchema<any>> {\n for (const [nodeId, at] of this._foreignAt) {\n if (at <= sinceEpoch) continue\n const live = this.nodes.get(nodeId)\n if (live) json[nodeId] = live\n else delete json[nodeId]\n }\n return json\n }\n /**\n * Whether any REMOTE session has changed this canvas since it loaded\n * (AGL-2486).\n *\n * The draft prompt reads it to decide whether offering a private\n * per-browser snapshot back is still honest: once a colleague's live work\n * is on the canvas, applying an older whole-document snapshot is not\n * \"restore my unsaved changes\" but \"roll the shared canvas back\".\n *\n * `_epoch` only ever moves in {@link markRemoteNode}, so a non-zero epoch\n * IS \"a peer has touched this canvas\", and {@link reset} returns it to zero\n * with the rest of the session.\n */\n public get hasRemoteEdits(): boolean {\n return this._epoch > 0\n }\n /**\n * Runs `mutate` as one undoable step (AGL-1204).\n *\n * Every mutator on this class records history for itself, but a panel that\n * writes `node.sx` directly does not go through any of them — the Styles and\n * custom-CSS forms assign to the node, so an undo after a style change\n * restored the last *recorded* snapshot instead, silently discarding\n * everything done since. This is the seam those panels were missing.\n *\n * **`coalesceKey` is what makes it usable for a live-applying control.**\n * Those forms fire on every change — one per character typed, one per drag\n * tick of a slider — so recording unconditionally would replace \"undo does\n * not step back far enough\" with \"undo steps back one character\", which is\n * no better. Consecutive calls sharing a key inside {@link\n * COALESCE_WINDOW_MS} record **once**, at the start of the burst, so the\n * snapshot is the state *before* the adjustment began. Omit the key for a\n * discrete commit (a toggle, an Apply button) that deserves its own step.\n *\n * The window is evaluated on call rather than by a timer: a burst ends\n * because the next edit arrives late, not because something fired in the\n * background. That keeps the canvas free of pending timers it would have to\n * cancel on {@link reset}, and keeps this testable without fake clocks.\n *\n * The key should identify *what* is being adjusted, not just the node —\n * moving from Gap to Padding is a second adjustment even if it happens\n * within the window.\n */\n public transact<T>(mutate: () => T, coalesceKey?: string): T {\n const now = Date.now()\n const burst = this._coalescing\n const continues =\n coalesceKey !== undefined &&\n burst?.key === coalesceKey &&\n now - burst.at < CanvasManager.COALESCE_WINDOW_MS\n if (!continues) this.saveHistory()\n this._coalescing =\n coalesceKey === undefined ? undefined : { key: coalesceKey, at: now }\n return mutate()\n }\n /**\n * Runs several mutations as ONE undoable step, all or nothing.\n *\n * `transact` records one snapshot and then runs code that assigns to nodes\n * directly. That is right for a panel writing `node.sx`, and wrong for a\n * caller that composes the guarded mutators — `addNodeFromNested`,\n * `updateNodeProps`, `reparentNode`, `deleteNode` — because each of those\n * records its own step. A change made of five of them would take five\n * undos to take back, and an undo that stops part-way leaves the document\n * in a state nobody authored.\n *\n * So inside a batch the mutators keep every guard and record nothing: the\n * batch's own snapshot, taken before `mutate` runs, is the step. A nested\n * batch folds into the outer one.\n *\n * A mutation that throws — a guard refusing a stale parent, a move into\n * the node's own subtree — rolls the whole batch back to that snapshot\n * and removes the snapshot from both stacks before the error propagates.\n * Half a batch is not an edit anyone asked for, and a refused batch must\n * not leave an undo step that restores a state identical to the present.\n */\n public batch<T>(mutate: () => T): T {\n if (this._batchDepth > 0) return mutate()\n this._history.saveHistory(this._epoch)\n // Whatever burst was open described the state before this batch.\n this._coalescing = undefined\n this._batchDepth += 1\n let completed = false\n try {\n const result = mutate()\n completed = true\n return result\n } finally {\n this._batchDepth -= 1\n // `canUndo` is only false when `mutate` itself cleared the history,\n // and then there is no snapshot left to roll back to.\n if (!completed && this._history.canUndo) {\n this.restoreSnapshot(this._history.undo(this._epoch))\n this._history.clearFuture()\n }\n }\n }\n /**\n * Drops BOTH history stacks and any open {@link transact} burst.\n *\n * Both, deliberately (AGL-2486). This used to clear `past` alone, which\n * left a caller that had just \"cleared history\" holding a live redo stack\n * — `canRedo` still true, still offering a snapshot of the state before\n * the clear. `reset` was the only caller and compensated for it a line\n * later, which is exactly how the next caller inherits the trap.\n *\n * A stale redo is worse than a stale undo in a co-editing session: redo\n * replays a WHOLE-DOCUMENT snapshot, and the restored map is diffed\n * against the co-editing shadow and published, so every node the snapshot\n * does not have goes out as a delete under this session's id.\n */\n public clearHistory() {\n this._history.clearHistory()\n this._coalescing = undefined\n }\n public createNodeId(): NodeId {\n return createIdUrlSafe()\n }\n public createNode(\n schema: PartialKeys<NodeSchema<any>, '$id'>,\n ): NodeSchema<any> {\n return new AglynNode<any>(\n {\n ...schema,\n $id: schema?.$id || this.createNodeId(),\n } as NodeSchema<any>,\n this,\n )\n }\n public clearNodes() {\n this.nodes.clear()\n return this\n }\n /**\n * Returns the canvas to its pristine state (no nodes, no history, no\n * recorded initial snapshot). The canvas is an app-level singleton shared\n * by every editing session — call this when a session ends so the next\n * document doesn't inherit stale content.\n */\n public reset() {\n this.clearNodes()\n this.clearHistory()\n this._initial = undefined\n this._initialConfirmed = true\n this._drafted = undefined\n // A new document gets a new epoch line. Stale marks would otherwise\n // preserve node ids that mean something else here (AGL-1958).\n this._foreignAt.clear()\n this._epoch = 0\n return this\n }\n /**\n * Record the state the canvas should be considered saved against.\n *\n * `confirmed` is what makes this honest. Pass `false` when the map came\n * from a source the STORE has not acknowledged — a Firestore snapshot\n * carrying this client's own pending write is the case that motivated it\n * (AGL-1262): the document is loaded and must be shown, but nothing in it\n * is known to have reached the server, so it must not be adopted as\n * \"already saved\". An unconfirmed baseline keeps {@link isInitialSame}\n * false — the editor stays savable — until a real save records a\n * confirmed one.\n */\n public updateInitialNodes(nodes?: NodesMap, options?: { confirmed?: boolean }) {\n this._initial = nodes ? (toJS(nodes) as NodesMap) : this.serializeNodes()\n this._initialConfirmed = options?.confirmed ?? true\n return this\n }\n /**\n * Promote an UNCONFIRMED baseline to a confirmed one, once the store has\n * acknowledged the write that made it unconfirmed (AGL-2486).\n *\n * Without this there is no way back. `_initialConfirmed` moves to true in\n * only two other places — {@link reset} and {@link updateInitialNodes} —\n * and the editor records its baseline exactly once, on the first snapshot\n * that carries nodes. A document whose first snapshot happens to carry\n * this client's own queued write therefore reads dirty for the rest of the\n * session over content nobody has edited.\n *\n * Conditional on the canvas still MATCHING the baseline, which is what\n * keeps AGL-1262 intact. The acknowledgement is for the write that was in\n * flight, and says nothing about work the author has done since; adopting\n * a canvas that has moved on would call that work saved and take away the\n * only control that could still write it.\n *\n * @returns whether the baseline is confirmed as a result.\n */\n public confirmInitialNodes(): boolean {\n if (!this._initial) return false\n if (this._initialConfirmed) return true\n if (!isEqual(this._initial, this.serializeNodes())) return false\n this._initialConfirmed = true\n return true\n }\n /**\n * Record the tree a store OTHER than the document now holds — today the\n * shared working draft, written by Save draft on the version a site is\n * serving (AGL-3271).\n *\n * Pass what was actually WRITTEN, not the canvas at the moment the write\n * resolved: an author who kept typing through the round trip has work the\n * draft does not hold, and recording the later canvas would call it stored.\n * Omit the argument only when the two are known to be the same.\n *\n * Records nothing about the document, so {@link isInitialSame} is\n * untouched: a drafted canvas still has everything to save, and Save stays\n * alive (AGL-1262).\n */\n public updateDraftedNodes(nodes?: NodesMap) {\n this._drafted = nodes ? (toJS(nodes) as NodesMap) : this.serializeNodes()\n return this\n }\n /**\n * Registers a node in the map AND lists it on `parent`, in one action\n * (AGL-1366).\n *\n * `parent` is required, and that is the whole point: this was the last way\n * left to put an entry in `this.nodes` with no parent linkage at all. The\n * besigner saves a flat map and renders a tree — `serializeNodes` dumps\n * every entry in the map while the renderer walks child lists down from\n * `NODE_ROOT_ID` — so a node the map holds and no parent lists is not a\n * rendering glitch that a reload clears. It is saved on every save,\n * shipped in every payload, counted against the 1 MiB ceiling, and never\n * drawn. That is the mechanism behind the 61 unreachable nodes `/product`\n * served, 26 of them carrying the only copy of two Hero sections' text\n * (AGL-1363).\n *\n * An *optional* parent would not have closed it, because the caller who\n * omits it is precisely the caller who creates the orphan. So the linkage\n * is not a second step a caller may forget — it happens here, and the\n * parent is resolved through `getNode($id)` and throws on a miss: the same\n * guard `addNodeFromNested` has carried since AGL-537 and `reparentNode`\n * took on in AGL-1363, rather than a second mechanism. A stale instance a\n * panel closure kept across a co-editor's merge, or a parent a peer has\n * since deleted, therefore fails loud instead of stranding the node.\n *\n * Linking is idempotent: re-setting a node its parent already lists\n * replaces the map entry and leaves the child list untouched, so this\n * stays usable as an update.\n *\n * The root is refused outright — it has no parent to be listed on, and\n * seeding it belongs to `setNodes`, which alone keeps its canonical id.\n */\n public setNode(\n node: NodeSchema<any>,\n parent: NodeSchema<any> | NodeId,\n index = NaN,\n create = false,\n ): NodeSchema<any> {\n if (!node) throw new Error('Invalid node')\n if (!create && !node.$id) throw new Error('Invalid node id')\n if (this.isRootNode(node)) throw new Error('Cannot set root node')\n\n // Resolve through the LIVE map BEFORE anything is inserted, so a refused\n // call leaves the canvas exactly as it found it.\n const parentId = typeof parent === 'string' ? parent : parent?.$id\n const target = parentId != null ? this.getNode(parentId) : undefined\n if (!target) throw new Error('Invalid parent node')\n\n return runInAction(() => {\n const _node = create ? this.createNode(node) : node\n // Both directions of the link are set here; a `parentId` disagreeing\n // with the list that holds the id is the same orphan by another route.\n _node.parentId = target.$id\n this.nodes.set(_node.$id!, _node)\n // Read-back, not `(target.nodes ||= []).push()` — see reparentNode\n // (AGL-763): the `||=` value is the detached plain array on an\n // observable.\n if (!target.nodes) target.nodes = []\n if (!target.nodes.includes(_node.$id!)) {\n if (isNaN(index)) target.nodes.push(_node.$id!)\n else target.nodes.splice(index, 0, _node.$id!)\n }\n return this.nodes.get(_node.$id!)!\n })\n }\n public setNodes(schemas: NodesMap, merge = false): this {\n if (!schemas) throw new Error('Invalid schemas')\n // Replacing the map ends any open {@link transact} burst (AGL-1204).\n // This is the seam a co-editor's incoming change arrives through, and\n // the one an undo restores through: in both cases the state the open\n // burst snapshotted is no longer the state the next edit is adjusting,\n // so the next edit must record its own step rather than fold into it.\n this._coalescing = undefined\n const cloned = toJS(schemas)\n const nodes: Record<NodeId, NodeSchema<any>> = {}\n for (const nodeId in cloned) {\n const node = cloned[nodeId]\n if (!node) continue\n // Persisted maps key nodes by id. Early seeds omitted $id (which used\n // to mint a random one), and the root must always keep the canonical\n // id — the map key is authoritative.\n const $id =\n nodeId === NODE_ROOT_ID ? NODE_ROOT_ID : (node.$id ?? nodeId)\n nodes[nodeId] = this.createNode({ ...node, $id })\n }\n if (merge) {\n this.nodes.merge(nodes)\n } else {\n this.nodes.replace(nodes)\n }\n return this\n }\n /**\n * Replaces the whole node map with a map the USER supplied — the raw-JSON\n * editor, and the local draft the crash net offers back (AGL-2486).\n *\n * Snapshots first, so the replacement is undoable — unlike `setNodes`,\n * which also serves the history-restore and initial-load paths.\n *\n * **Every node a remote session has touched survives it**, on exactly the\n * reasoning AGL-1958 established for undo. A wholesale replace is the same\n * shape of write as a snapshot restore: the map being applied was composed\n * without any knowledge of the peer's later changes, and the result is\n * diffed against the co-editing shadow and published, so a node the map\n * happens to lack is broadcast as a DELETE under this session's id.\n * Measured on the running editor before this changed (AGL-2486): a peer\n * created a node, the other session pressed Restore, and the node vanished\n * from the peer's own canvas with an RTDB tombstone to show for it.\n *\n * Every mark counts, not only those newer than some epoch: unlike a\n * snapshot, an applied map carries no epoch of its own, and a draft was by\n * definition composed before this page joined the room.\n */\n public applyNodes(value: ProcessableNodes): this {\n this.saveHistory()\n const parsed = this.processNodesToDenormalized(value)\n return this.setNodes(\n this.withForeignNodes({ ...parsed }, 0) as typeof parsed,\n )\n }\n public deleteNode(node: NodeSchema<any>): this {\n const validateNode = (node: NodeSchema<any>) => {\n if (!node || !node?.$id || !node?.parentId)\n throw new Error('Invalid node')\n if (this.isRootNode(node)) throw new Error('Cannot delete root node')\n }\n\n validateNode(node)\n this.saveHistory()\n\n const del = (node: NodeSchema<any>) => {\n validateNode(node)\n const parent = this.getNode(node.parentId!)\n if (!parent) throw new Error('Invalid parent node')\n const index = parent.nodes?.indexOf(node.$id) ?? -1\n const nodes = toJS(node.nodes || [])\n\n for (const childId of [...nodes]) {\n const child = this.getNode(childId)\n if (child) del(child)\n }\n\n if (index > -1) parent.nodes?.splice(index, 1)\n this.nodes.delete(node.$id)\n }\n del(node)\n return this\n }\n /**\n * Moves a node under `newParent`, resolving BOTH ends through the live\n * node map first (AGL-1363).\n *\n * The resolution is the guard, and it is the same one `addNodeFromNested`\n * has carried since AGL-537. This method splices the node out of its\n * *live* old parent and then attaches it to the object it was handed — so\n * a `newParent` that is merely SHAPED like a node (a stale instance a\n * panel closure kept across a co-editor's merge, a node a peer has since\n * deleted, historically a click event) took the node out of the tree and\n * pushed its id onto a detached array. Nothing put it back.\n *\n * That is not a recoverable glitch: `serializeNodes` dumps the whole map\n * while the renderer walks the tree from `NODE_ROOT_ID`, so a node in the\n * map that no live parent lists is saved on every save, shipped in every\n * payload, counted against the 1 MiB ceiling — and never drawn. It is why\n * `/product` served 61 unreachable nodes, 26 of them carrying the only\n * copy of two Hero sections' text. Fail loud instead.\n *\n * `index` is the node's position in the resulting sibling list — i.e. it is\n * read AFTER the node has been spliced out of wherever it was. A caller\n * holding a drop marker (\"put it before the sibling currently at 3\") is\n * describing the list BEFORE the removal and has to convert; the dnd\n * manager does exactly that for same-parent drops.\n */\n public reparentNode(\n node: NodeSchema<any>,\n newParent: NodeSchema<any>,\n index = NaN,\n ): typeof node {\n if (!node) throw new Error('Invalid node')\n if (this.isRootNode(node)) throw new Error('Cannot move root node')\n if (!newParent) throw new Error('Invalid parent node')\n\n // Every refusal below runs before `saveHistory`: a move that never\n // happened must not leave an undo step behind it.\n const target = node.$id != null ? this.getNode(node.$id) : undefined\n if (!target) throw new Error('Invalid node')\n const parent =\n newParent.$id != null ? this.getNode(newParent.$id) : undefined\n if (!parent) throw new Error('Invalid parent node')\n\n const oldParent = this.getNodeParent(target)\n const oldIndex = oldParent?.nodes?.indexOf(target.$id) ?? -1\n const sameParent = oldParent?.$id === parent.$id\n\n if (!sameParent) {\n // A node into its own subtree detaches that subtree from the document\n // and hands the renderer a cycle. `breadcrumbPath` is the ancestor\n // chain, so the target appearing in the new parent's is the whole test\n // — and it covers `parent === target` on its own.\n if (this.getNodeBreadcrumbPath(parent)?.some((id) => id === target.$id)) {\n throw new Error('Cannot move an element inside itself')\n }\n\n /**\n * The gate that was missing (AGL-1405). `nodeAcceptsChildren` guarded\n * every path that CREATES a node — the Insert menu and paste through\n * `resolveInsertTarget`, drag-and-drop through the dnd manager — but\n * not the one that MOVES one. So a `markdown` block (or any component\n * whose content is an attribute: a Reusable Component instance, a\n * Layout Slot, a List Item Text) could still be handed a child, which\n * it then renders nowhere. That is not a cosmetic mistake: the node is\n * saved on every save and shipped in every payload while the page it\n * belongs to shows nothing, so the work reads as never done rather\n * than broken. Three /press screenshots are still sitting in exactly\n * that hole, and the point of the click-path this guard protects is\n * that it must not be able to dig another one.\n *\n * A same-parent reorder is deliberately NOT gated: the nodes already\n * trapped by AGL-1388 have to stay shufflable, and `reorderNode`\n * routes Shift up / Shift down straight through here.\n */\n // Deliberately label-free: `getNodeLabelShort` reaches into the\n // component registry, and a refusal path that can itself throw is no\n // refusal at all. Callers that want \"Markdown can't hold elements\"\n // name the node themselves — `moveNodeOut`/`moveNodeIn` do.\n if (!this.nodeAcceptsChildren(parent)) {\n throw new Error('That element cannot hold other elements')\n }\n }\n\n // Assign then read back, never `(x.nodes ||= []).push()` (AGL-763). A\n // live node is a `makeAutoObservable` proxy: assigning a fresh `[]` stores\n // an observable copy, but the `||=` expression evaluates to the plain\n // array that was assigned — so pushing onto it writes to a detached array\n // and the child silently orphans. `AglynNode`'s constructor seeds `nodes`\n // so this never actually fires today, but relying on that invariant from\n // here is how the same defect returned as AGL-759.\n if (!parent.nodes) parent.nodes = []\n\n // Resolve the landing slot against the list as it will be AFTER the\n // removal, and clamp it. `splice(-1, 0, id)` inserts before the LAST\n // element, so an unclamped negative index moved a first child DOWN —\n // `reorderNode(node, node.index - 1)` on index 0 did precisely that, and\n // only the menu's `disabled` prop hid it.\n const settled = parent.nodes.length - (sameParent && oldIndex > -1 ? 1 : 0)\n const at = isNaN(index) ? settled : Math.min(Math.max(index, 0), settled)\n\n // A move that resolves to the slot the node already occupies is not a\n // move. It used to cost an undo step anyway — which is how a hierarchy\n // drag came to \"record an undo entry without moving anything\" (AGL-1405),\n // and worse, made the next Undo discard the author's PREVIOUS edit.\n if (sameParent && at === oldIndex) return target\n\n this.saveHistory()\n if (oldIndex > -1) oldParent?.nodes?.splice(oldIndex, 1)\n if (!sameParent) target.parentId = parent.$id\n parent.nodes.splice(at, 0, target.$id)\n return target\n }\n public reorderNode(node: NodeSchema<any>, index = NaN): typeof node {\n if (!node) throw new Error('Invalid node')\n // Resolve the node first, so the parent is read off the LIVE node's\n // `parentId` rather than a stale copy's (AGL-1363).\n const target = node.$id != null ? this.getNode(node.$id) : undefined\n if (!target) throw new Error('Invalid node')\n const parent = this.getNodeParent(target)\n if (!parent) throw new Error('Invalid parent node')\n return this.reparentNode(target, parent, index)\n }\n public duplicateNode(node: NodeSchema<any>): NodeSchema<any> {\n if (!node) throw new Error('Invalid node')\n if (this.isRootNode(node)) throw new Error('Cannot duplicate root node')\n const parent = this.getNodeParent(node)\n if (!parent) throw new Error('Invalid parent node')\n\n const duplicateNodeAndChildren = (\n node: NodeSchema<any>,\n parentId: NodeId,\n index = NaN,\n ): NodeSchema<any> => {\n if (!node) throw new Error('Invalid node')\n\n const json = toJS(node)\n // `setNode` registers the copy AND lists it on its parent, so no copy\n // can be left in the map unreferenced — the linkage is no longer a\n // separate step this recursion could get wrong (AGL-1366).\n const newNode = this.setNode(\n this.createNode({\n ...json,\n $id: this.createNodeId(),\n parentId,\n nodes: [],\n }),\n parentId,\n index,\n )\n if (!json) return newNode\n\n for (const childId of arraySafe(json.nodes)) {\n const child = childId && this.getNode(childId)\n if (child) duplicateNodeAndChildren(child, newNode.$id!)\n }\n\n return newNode\n }\n\n this.saveHistory()\n const nodeIndex = this.getNodeIndex(node)\n const index =\n nodeIndex === -1 ? parent.nodes?.length ?? 0 : nodeIndex + 1\n // One action, so observers never see the copy listed on its parent\n // before its own subtree has been built under it.\n return runInAction(() =>\n duplicateNodeAndChildren(node, node.parentId!, index),\n )\n }\n public createDuplicateNode(\n node: NodeSchemaNested<any>,\n ): NodeSchemaNested<any> {\n const $id = this.createNodeId()\n const cloned = toJS(node)\n const nodes = Array.isArray(cloned?.nodes) ? [...cloned.nodes] : []\n const res: NodeSchemaNested<any> = { ...cloned, $id, nodes: [] }\n for (const child of nodes) {\n const childDuplicate = this.createDuplicateNode({\n ...child,\n parentId: $id,\n })\n res.nodes!.push(childDuplicate)\n }\n return res\n }\n /**\n * Insert a *detached* nested subtree as a child of `parent`, minting a\n * fresh id for every node in it (AGL-1202).\n *\n * The subtree is plain JSON with no ties to this canvas, so the source can\n * be anything — an element preset, the besigner clipboard, or a subtree\n * copied out of a different document altogether. Callers are responsible\n * for checking that the root's component is registered and that the\n * lineal relationship with `parent` is allowed; this method only does the\n * structural work.\n */\n public addNodeFromNested(\n nested: NodeSchemaNested<any>,\n parent: NodeSchema<any>,\n index = NaN,\n ): NodeSchema<any> {\n if (!nested) throw new Error('Invalid node')\n // Attach to the live node in this canvas. A caller-supplied object\n // that is not in the node map (a stale reference — or historically the\n // console INSERT menu's click event) would otherwise get the child id\n // pushed onto ITS `nodes` array while the child lands in the map as a\n // detached node: absent from the hierarchy, the canvas, and saves\n // (AGL-537). Fail loud instead of corrupting the tree.\n const target = parent?.$id != null ? this.getNode(parent.$id) : undefined\n if (!target) throw new Error('Invalid parent node')\n this.saveHistory()\n const duplicate = this.createDuplicateNode(nested)\n duplicate.parentId = target.$id\n const parsed = this.processNodesToDenormalized(duplicate)\n\n // Register the subtree and append the child id in one action so\n // observers never see the intermediate detached state.\n runInAction(() => {\n this.setNodes(parsed, true)\n // Read-back, not `(target.nodes ||= []).push()` — see reparentNode\n // (AGL-763): the `||=` value is the detached plain array on an observable.\n if (!target.nodes) target.nodes = []\n if (isNaN(index)) target.nodes.push(duplicate.$id)\n else target.nodes.splice(index, 0, duplicate.$id)\n })\n\n return this.getNode(duplicate.$id)!\n }\n\n public addNodeFromPreset(\n preset: PresetSchema<any>,\n parent: NodeSchema<any>,\n index = NaN,\n ): NodeSchema<any> {\n if (!preset) throw new Error('Invalid preset')\n return this.addNodeFromNested(toJS(preset).data, parent, index)\n }\n /**\n * REPLACES a node's props — callers spread the current ones to merge.\n *\n * An editor form submits every field it renders, so keys the author left\n * empty arrive as `undefined`. Those are dropped here rather than stored as\n * own keys (AGL-1334): for a props bag that is REPLACED wholesale, absent IS\n * cleared, and an `undefined` member is a value no storage layer accepts.\n * `AglynNode.toJSON` strips again at the write boundary — this one keeps the\n * live tree honest for everything that reads it before a save.\n */\n /**\n * Writes top-level node FIELDS, with an undo step.\n *\n * The sibling of {@link updateNodeProps}, and it exists for the same two\n * reasons that one documents. An edit with no `saveHistory` is an edit the\n * author cannot take back — and every panel that assigned to a node\n * directly was quietly in that state. And it re-resolves by `$id`: callers\n * hold node objects across time (the focus store keeps the selection that\n * way), while every wholesale replace of the map — `undo`, `redo`,\n * `applyNodes`, a draft restore — builds fresh instances. Assigning to the\n * caller's copy then mutates an orphan: no error, no dirty state, and the\n * author's edit is simply gone.\n *\n * Only the keys the patch names are touched, and `undefined` clears one —\n * which is how a cleared style or a shown element is stored, since `toJSON`\n * omits what is undefined.\n */\n public updateNodeFields(\n node: NodeSchema<any>,\n patch: Partial<NodeSchema<any>>,\n ): void {\n if (!node) throw new Error('Invalid node')\n this.saveHistory()\n const target = this.getNode(node.$id) ?? node\n Object.assign(target, patch)\n }\n\n public updateNodeProps(\n node: NodeSchema<any>,\n props: NodeSchema<any>['props'],\n ): void {\n if (!node) throw new Error('Invalid node')\n this.saveHistory()\n // Write to the node the MAP holds, not the reference the caller kept\n // (AGL-2486). Callers hold node objects across time — the besigner's\n // focus store keeps the selection that way — and every wholesale replace\n // of the map (`undo`, `redo`, `applyNodes`, a draft restore) builds fresh\n // instances. Assigning to the caller's copy then mutates an orphan: no\n // error, no dirty state, and the author's edit is simply gone. Re-resolve\n // by `$id` so the write always reaches the canvas.\n //\n // The fallback keeps a node that is genuinely not in the map — deleted,\n // or never inserted — behaving as before rather than being resurrected.\n const target = this.getNode(node.$id) ?? node\n target.props = stripUndefinedDeep({ ...props })\n }\n\n public static nestDenormalizedNodes(\n nodes: NodesMap,\n rootId: NodeId = NODE_ROOT_ID,\n ): NodeSchemaNested<any> {\n const rootNode = nodes[rootId]\n if (!rootNode) throw new Error('Invalid root node')\n const response = { ...(rootNode as unknown as NodeSchemaNested<any>) }\n const children: NodeSchemaNested<any>[] = []\n // `?? []`, not `||= []` — a read-only walk should not mutate its input\n // (AGL-763).\n for (const id of rootNode.nodes ?? []) {\n const child = { ...nodes[id] }\n const nestedChild = this.nestDenormalizedNodes(nodes, child.$id)\n children.push(nestedChild)\n }\n response.nodes = children\n return response\n }\n\n public denormalizeNodes(\n nodes: NodeSchemaNested<any>[],\n parentId: NodeId,\n accumulator: NodesMap = {},\n ): NodesMap {\n return CanvasManager.denormalizeNodes(nodes, parentId, accumulator)\n }\n public static denormalizeNodes(\n nodes: NodeSchemaNested<any>[],\n parentId: NodeId,\n accumulator: NodesMap = {},\n ): NodesMap {\n for (const childNode of Array.isArray(nodes) ? nodes : []) {\n const child =\n _isStrT(childNode) && accumulator[childNode]\n ? accumulator[childNode]\n : childNode\n if (!_isObj(child)) continue\n\n const node = cloneDeep(child) as unknown as NodeSchema<any>\n\n // TODO: Remove after migration to nodes property\n if (node['elements']) {\n node.nodes = node['elements']\n delete node['elements']\n }\n // TODO: Remove after migration to pluginId property\n if (node['bundleId']) {\n node.pluginId = node['bundleId']\n delete node['bundleId']\n }\n\n const nodes = (node as unknown as NodeSchemaNested<any>)?.nodes\n const nodesArray = [...(Array.isArray(nodes) ? nodes : [])].filter(\n Boolean,\n )\n accumulator[node.$id] = {\n ...node,\n parentId,\n nodes: [...nodesArray]\n .map((i) => {\n if (_isStrT(i)) return i\n if (_isObj(i)) return i.$id\n return null\n })\n .filter(Boolean),\n }\n this.denormalizeNodes(nodesArray, node.$id, accumulator)\n }\n\n return accumulator\n }\n\n public processNodesToDenormalized(value: ProcessableNodes): NodesMap {\n return CanvasManager.processNodesToDenormalized(value)\n }\n public static processNodesToDenormalized(value: ProcessableNodes): NodesMap {\n let response: NodesMap = {}\n const isArray = Array.isArray(value)\n\n if (isArray && value.length === 1) {\n const item = value[0]\n if (item?.$id === NODE_ROOT_ID) {\n response = this.denormalizeNodes(\n [{ ...item, parentId: null }],\n NODE_ROOT_ID,\n response,\n )\n } else if (item?.parentId === NODE_ROOT_ID || (item && item.parentId)) {\n response = this.denormalizeNodes(\n [{ $id: NODE_ROOT_ID, componentId: 'div', nodes: [item] }],\n NODE_ROOT_ID,\n response,\n )\n } else if (item?.parentId) {\n response = this.denormalizeNodes(\n [{ $id: item?.parentId, componentId: 'div', nodes: [item] }],\n item?.parentId,\n response,\n )\n } else {\n response = this.denormalizeNodes(\n [{ $id: NODE_ROOT_ID, componentId: 'div', nodes: [] }],\n NODE_ROOT_ID,\n response,\n )\n }\n } else if (isArray) {\n response = this.denormalizeNodes(\n [{ $id: NODE_ROOT_ID, componentId: 'div', nodes: [...value] }],\n NODE_ROOT_ID,\n response,\n )\n } else if (\n _isObj(value) &&\n Array.isArray(value?.nodes) &&\n typeof value.nodes[0] !== 'string'\n ) {\n const _value = { ...(value as NodeSchemaNested<any>) }\n response = this.denormalizeNodes(\n [_value],\n _value?.parentId || NODE_ROOT_ID,\n response,\n )\n } else {\n response = value as unknown as NodesMap\n }\n\n return response\n }\n}\n\nexport default CanvasManager\n"],"names":["_isObj","_isStrT","arraySafe","cloneDeep","isEqual","action","computed","makeAutoObservable","makeObservable","observable","observableRef","runInAction","toJS","computedFn","schemaAcceptsChildren","REUSABLE_INSTANCE_COMPONENT_ID","stripUndefinedDeep","createIdUrlSafe","NodeType","NODE_ROOT_ID","NODE_ROOT_LABEL","AglynNode","parent","parentId","store","getNode","index","getNodeIndex","children","res","$id","nodes","node","push","labelShort","getNodeLabelShort","breadcrumbPath","getNodeBreadcrumbPath","componentSchema","componentId","aglyn","components","getSchema","hasNodes","Array","isArray","length","resolvedProps","resolveProps","props","asJSON","toJSON","delete","deleteNode","schema","json","type","name","undefined","pluginId","className","Object","keys","sx","sxEmpty","styleOverrides","attrOverrides","layoutStyleOverrides","interactions","hidden","NODE","HistoryManager","Symbol","toStringTag","toString","past","present","future","canUndo","canRedo","undo","epoch","Error","pop","redo","clearPast","clear","clearFuture","clearHistory","saveHistory","map","array","deep","CanvasManager","_history","serializedNodes","serializeNodes","isInitialSame","_initial","_initialConfirmed","isDraftedSame","_drafted","didSetInitial","Boolean","isInitialConfirmed","rootNode","get","nestedNodes","root","makeNested","resolveInsertTarget","target","requested","nodeAcceptsChildren","NaN","getNodeParent","at","indexOf","forEach","id","restoreSnapshot","_epoch","_batchDepth","markRemoteNode","nodeId","previousJson","live","nowJson","JSON","stringify","_foreignAt","set","serializeNode","snapshot","fromEntries","entries","setNodes","withForeignNodes","sinceEpoch","hasRemoteEdits","transact","mutate","coalesceKey","now","Date","burst","_coalescing","continues","key","COALESCE_WINDOW_MS","batch","completed","result","createNodeId","createNode","clearNodes","reset","updateInitialNodes","options","confirmed","confirmInitialNodes","updateDraftedNodes","setNode","create","isRootNode","_node","includes","isNaN","splice","schemas","merge","cloned","replace","applyNodes","value","parsed","processNodesToDenormalized","validateNode","del","childId","child","reparentNode","newParent","oldParent","oldIndex","sameParent","some","settled","Math","min","max","reorderNode","duplicateNode","duplicateNodeAndChildren","newNode","nodeIndex","createDuplicateNode","childDuplicate","addNodeFromNested","nested","duplicate","addNodeFromPreset","preset","data","updateNodeFields","patch","assign","updateNodeProps","nestDenormalizedNodes","rootId","response","nestedChild","denormalizeNodes","accumulator","childNode","nodesArray","filter","i","item","_value","Map","hasNode","has","nodesAreEqual","left","right","_right","isRootNodeId","nodeOrId","hierarchy","seen","Set","currentId","add","instanceName","componentLabel","getLabel","childNodes"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../libs/aglyn/src/lib/canvas-manager/canvas-manager.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { _isObj, _isStrT } from '@aglyn/shared-util-tools'\nimport { arraySafe } from '@aglyn/shared-util-tools'\nimport cloneDeep from 'lodash-es/cloneDeep.js'\nimport isEqual from 'lodash-es/isEqual.js'\nimport {\n action,\n computed,\n type IObservableArray,\n makeAutoObservable,\n makeObservable,\n observable,\n observableRef,\n type ObservableMap,\n runInAction,\n toJS,\n} from 'mobx'\n// The leaf module, not the 68 KB package bundle — see the note there.\nimport { computedFn } from '@aglyn/shared-util-vendor/mobx-computed-fn'\nimport type { Aglyn } from '../aglyn'\nimport type { NodeInteraction } from '../app-utils/node-interactions'\nimport { schemaAcceptsChildren } from '../app-utils/child-contract'\nimport { REUSABLE_INSTANCE_COMPONENT_ID } from '../app-utils/reusable-component-keys'\nimport { stripUndefinedDeep } from '../app-utils/strip-undefined'\nimport { createIdUrlSafe } from '../foundation/constants/app'\nimport type { PluginId } from '../plugin-manager'\nimport {\n type ComponentId,\n type ComponentSchema,\n type NodeBreadcrumbPath,\n type NodeId,\n type NodeSchema,\n type NodeSchemaJSON,\n type NodeSchemaNested,\n type NodesMap,\n NodeType,\n type PresetSchema,\n type ProcessableNodes,\n} from '../types/nodes'\n\nexport const NODE_ROOT_ID = '_@_'\nexport const NODE_ROOT_LABEL = 'Document'\n\nexport class AglynNode<P = JSX.AnyProps> implements NodeSchema<P> {\n // public store: CanvasManager\n public $id: NodeId\n public name?: string\n public type: NodeType | string\n public pluginId?: PluginId\n public componentId?: ComponentId\n public parentId?: NodeId\n public nodes?: NodeId[]\n public props: P\n public sx?: JSX.SxProps\n public className?: string\n /**\n * Per-instance style overrides (AGL-1306) — see `NodeSchema`. Assigned\n * by name like every other field: this constructor DROPS unknown\n * top-level keys, so forgetting a field here silently strips it from\n * every canvas round-trip.\n */\n public styleOverrides?: Record<string, JSX.SxProps>\n /**\n * Per-instance attribute overrides (AGL-1899) — see `NodeSchema`. Same\n * three-touch-point rule as `styleOverrides` above: declared here,\n * assigned in the constructor, emitted in `toJSON`. Miss one and the\n * field survives in memory but not across a save.\n */\n public attrOverrides?: Record<string, Record<string, unknown>>\n /**\n * A screen's layout style overrides, on the canvas root only (AGL-3286) —\n * see `NodeSchema`. Same three touch points as the fields around it.\n */\n public layoutStyleOverrides?: Record<\n string,\n Record<string, Record<string, unknown>>\n >\n /**\n * Interactions authored on this element — see `NodeSchema`.\n * Third field under the same three-touch-point rule as the two above:\n * declared here, assigned in the constructor, emitted in `toJSON`.\n */\n public interactions?: NodeInteraction[]\n /**\n * Hidden by the author — see `NodeSchema`. Same three touch\n * points, and it needs all of them for a second reason as well: an\n * undeclared field assigned at runtime is not observable, so the hierarchy\n * row would not repaint when the eye was clicked.\n */\n public hidden?: boolean\n\n get parent(): NodeSchema<any> | undefined {\n // The root is stored as its own parent (`parentId: \"_@_\"`); answering it\n // here would hand every ancestor walk an endless loop (AGL-3565).\n if (!this.parentId || this.parentId === this.$id) return\n return this.store.getNode(this.parentId)\n }\n get index(): number | null {\n return this.store.getNodeIndex(this)\n }\n get children(): NodeSchema<any>[] {\n const res: NodeSchema[] = []\n // `?? []`, not `||= []` — a computed getter must not assign to observable\n // state, and this only reads (AGL-763).\n for (const $id of this.nodes ?? []) {\n const node = this.store.getNode($id)\n if (node) res.push(node)\n }\n return res\n }\n get labelShort(): string {\n return this.store.getNodeLabelShort(this)\n }\n get breadcrumbPath(): NodeBreadcrumbPath {\n return this.store.getNodeBreadcrumbPath(this)\n }\n get componentSchema(): ComponentSchema | undefined {\n if (!this.componentId) return\n return this.store.aglyn.components.getSchema(this.componentId)\n }\n get hasNodes(): boolean {\n return Array.isArray(this.nodes) && this.nodes.length > 0\n }\n get resolvedProps(): P {\n const resolveProps = this.componentSchema?.resolveProps\n if (typeof resolveProps === 'function') {\n return (resolveProps(this) || {}) as P\n }\n return this.props\n }\n\n get asJSON(): NodeSchemaJSON<P> {\n return this.toJSON()\n }\n\n constructor(\n schema: NodeSchema<P>,\n public store: CanvasManager,\n ) {\n this.$id = schema.$id\n this.name = schema.name\n this.type = schema.type || NodeType.NODE\n this.parentId = schema.parentId\n this.pluginId = schema.pluginId\n this.componentId = schema.componentId\n this.className = schema.className\n this.nodes = Array.isArray(schema.nodes) ? [...schema.nodes] : []\n this.props = { ...schema.props } as P\n this.sx = Array.isArray(schema.sx) ? [...schema.sx] : { ...schema.sx }\n this.styleOverrides = schema.styleOverrides\n ? { ...schema.styleOverrides }\n : undefined\n this.attrOverrides = schema.attrOverrides\n ? { ...schema.attrOverrides }\n : undefined\n this.layoutStyleOverrides = schema.layoutStyleOverrides\n ? { ...schema.layoutStyleOverrides }\n : undefined\n this.interactions = Array.isArray(schema.interactions)\n ? [...schema.interactions]\n : undefined\n this.hidden = schema.hidden || undefined\n\n makeAutoObservable(this, {\n store: false,\n toJSON: false,\n })\n }\n\n public delete() {\n this.store.deleteNode(this)\n }\n\n public toJSON = (): NodeSchemaJSON<P> => {\n const json: Record<string, unknown> = {\n $id: this.$id,\n type: this.type,\n }\n // Omit optional scalar fields when undefined — Firestore rejects undefined values\n if (this.name !== undefined) json['name'] = this.name\n if (this.parentId !== undefined) json['parentId'] = this.parentId\n if (this.pluginId !== undefined) json['pluginId'] = this.pluginId\n if (this.componentId !== undefined) json['componentId'] = this.componentId\n if (this.className !== undefined) json['className'] = this.className\n // Omit collection fields when empty to save Firestore storage\n const nodes = this.nodes ? [...this.nodes] : []\n if (nodes.length > 0) json['nodes'] = nodes\n // The scalar omissions above stopped at the top level, so an OWN key\n // holding `undefined` inside these bags still reached storage (AGL-1334).\n // An editor form writes the whole field set back, so a never-set or\n // cleared optional attribute is such a key — and the two write paths then\n // disagreed: a save msgpacked it to `null`, a publish handed `undefined`\n // straight to `updateDoc()`, which rejects it. Stripping HERE is what\n // makes save and publish agree: both serialize from this one method.\n const props = stripUndefinedDeep(toJS(this.props))\n if (props && Object.keys(props).length > 0) json['props'] = props\n const sx = stripUndefinedDeep(toJS(this.sx))\n const sxEmpty = Array.isArray(sx) ? sx.length === 0 : !sx || Object.keys(sx).length === 0\n if (!sxEmpty) json['sx'] = sx\n // Instance style overrides (AGL-1306): emitted like sx — absent when\n // empty — so the SAVED node map carries them into both storage forms\n // (the plain map and the msgpack bytes both serialize this output).\n const styleOverrides = stripUndefinedDeep(toJS(this.styleOverrides))\n if (styleOverrides && Object.keys(styleOverrides).length > 0) {\n json['styleOverrides'] = styleOverrides\n }\n // Instance attribute overrides (AGL-1899): same treatment, same reason.\n const attrOverrides = stripUndefinedDeep(toJS(this.attrOverrides))\n if (attrOverrides && Object.keys(attrOverrides).length > 0) {\n json['attrOverrides'] = attrOverrides\n }\n // Layout style overrides (AGL-3286): same treatment. Only the screen\n // editor's root ever carries them, and its save lifts them out of the map.\n const layoutStyleOverrides = stripUndefinedDeep(\n toJS(this.layoutStyleOverrides),\n )\n if (layoutStyleOverrides && Object.keys(layoutStyleOverrides).length > 0) {\n json['layoutStyleOverrides'] = layoutStyleOverrides\n }\n // Element interactions: emitted like the bags above, absent\n // when empty. This is the field that makes them versioned with the\n // document at all — an interaction the canvas holds but this method\n // does not write is one that never reaches a save.\n const interactions = stripUndefinedDeep(toJS(this.interactions))\n if (Array.isArray(interactions) && interactions.length > 0) {\n json['interactions'] = interactions\n }\n // Author visibility. Emitted only when TRUE: `false` and\n // absent mean the same thing, and a field on every node in the document\n // is bytes on every save and every page.\n if (this.hidden) json['hidden'] = true\n return json as NodeSchemaJSON<P>\n }\n}\n\n/**\n * One recorded state, plus the {@link CanvasManager._epoch} it was taken at.\n *\n * The epoch is what makes a whole-document snapshot safe to restore in a\n * co-editing session (AGL-1958). Restoring the map wholesale reverts every\n * node in it — including nodes a *colleague* changed after the snapshot was\n * taken, whose new values the snapshot has never seen. Stamping each entry\n * lets {@link CanvasManager.restoreSnapshot} tell \"this remote change is\n * already in the snapshot\" from \"this remote change happened later and the\n * snapshot would undo it\", which is exactly the distinction a plain\n * `Map<K, T>` cannot express.\n */\ninterface HistorySnapshot<K extends string, T> {\n nodes: Map<K, T>\n epoch: number\n}\n\nclass HistoryManager<K extends string, T> {\n public present = observable.map<K, T>({})\n public past = observable.array<HistorySnapshot<K, T>>([], { deep: false })\n public future = observable.array<HistorySnapshot<K, T>>([], { deep: false })\n\n constructor() {\n makeObservable(this, {\n canUndo: computed,\n canRedo: computed,\n undo: action,\n redo: action,\n clearPast: action,\n clearFuture: action,\n clearHistory: action,\n saveHistory: action,\n })\n }\n\n public get [Symbol.toStringTag]() {\n return 'HistoryManager'\n }\n\n public toString(): string {\n return '[object HistoryManager]'\n }\n\n public toJSON(): {\n past: IObservableArray<HistorySnapshot<K, T>>\n present: ObservableMap<K, T>\n future: IObservableArray<HistorySnapshot<K, T>>\n } {\n return {\n past: toJS(this.past),\n present: toJS(this.present),\n future: toJS(this.future),\n }\n }\n\n public get canUndo() {\n return this.past.length >= 1\n }\n\n public get canRedo() {\n return this.future.length >= 1\n }\n\n public undo(epoch: number): HistorySnapshot<K, T> {\n if (!this.canUndo) throw new Error('No history to undo')\n this.future.push({ nodes: toJS(this.present), epoch })\n return this.past.pop()!\n }\n\n public redo(epoch: number): HistorySnapshot<K, T> {\n if (!this.canRedo) throw new Error('No history to redo')\n this.past.push({ nodes: toJS(this.present), epoch })\n return this.future.pop()!\n }\n\n public clearPast(): this {\n this.past.clear()\n return this\n }\n\n public clearFuture(): this {\n this.future.clear()\n return this\n }\n\n public clearHistory(): this {\n this.clearPast()\n this.clearFuture()\n return this\n }\n\n public saveHistory(epoch: number): this {\n this.clearFuture()\n this.past.push({ nodes: toJS(this.present), epoch })\n return this\n }\n}\n\nexport class CanvasManager {\n /**\n * How long a coalesced burst stays open. Comfortably above typing cadence\n * and slider tick rate, well below the pause that means \"a new adjustment\".\n */\n public static readonly COALESCE_WINDOW_MS = 500\n\n private _initial: NodesMap | undefined = undefined\n /**\n * Whether {@link _initial} is a state the STORE has confirmed, or merely\n * one the client believes. See {@link updateInitialNodes}.\n */\n private _initialConfirmed = true\n /**\n * The tree a SECOND store — one that is not the document — is known to\n * hold (AGL-3271). Undefined until something records one.\n *\n * {@link _initial} answers \"is there anything to save\", and on the version\n * a site is serving that answer is permanently yes: the working draft is\n * written beside the version and the version itself is deliberately left\n * alone, so the canvas differs from the document for as long as the draft\n * is unpublished. This is what lets a caller still ask the other question\n * — \"is this work stored anywhere\" — without pretending the document holds\n * it.\n */\n private _drafted: NodesMap | undefined = undefined\n private _history: HistoryManager<NodeId, NodeSchema<any>>\n /** The open {@link transact} burst, if any. See that method. */\n private _coalescing: { key: string; at: number } | undefined = undefined\n /** How deep the running {@link batch} calls are nested; 0 outside one. */\n private _batchDepth = 0\n /**\n * Monotonic counter, bumped once per node a REMOTE session changes. See\n * {@link markRemoteNode} and {@link restoreSnapshot} (AGL-1958).\n */\n private _epoch = 0\n /** Node id → the {@link _epoch} at which a remote session last touched it. */\n private _foreignAt = new Map<NodeId, number>()\n\n constructor(public aglyn: Aglyn) {\n makeObservable<\n CanvasManager,\n '_initial' | '_initialConfirmed' | '_drafted' | '_epoch'\n >(this, {\n _initial: observableRef,\n _initialConfirmed: observable,\n // Observable for the same reason `_epoch` is: {@link isDraftedSame} is\n // read while rendering the toolbar, and the label it decides has to\n // change on the author's next keystroke rather than on the next\n // unrelated render (AGL-3271).\n _drafted: observableRef,\n // Observable so {@link hasRemoteEdits} is a computed a React observer\n // re-renders on: the draft prompt has to stop offering Restore the\n // moment a peer's first change lands, not on the next unrelated\n // render (AGL-2486).\n _epoch: observable,\n nodes: computed,\n serializedNodes: computed,\n isInitialSame: computed,\n isDraftedSame: computed,\n didSetInitial: computed,\n hasRemoteEdits: computed,\n markRemoteNode: action,\n undo: action,\n redo: action,\n saveHistory: action,\n // An action so the snapshot and the mutation land in ONE mobx\n // transaction — otherwise `saveHistory` alone notifies observers, and\n // the canvas renders a frame between the two (AGL-1204).\n transact: action,\n // Same reason: several guarded mutators composed into one change are\n // one render, not one per mutator.\n batch: action,\n clearHistory: action,\n clearNodes: action,\n reset: action,\n updateInitialNodes: action,\n confirmInitialNodes: action,\n updateDraftedNodes: action,\n setNode: action,\n setNodes: action,\n applyNodes: action,\n deleteNode: action,\n reparentNode: action,\n reorderNode: action,\n updateNodeFields: action,\n updateNodeProps: action,\n })\n\n this._history = new HistoryManager()\n }\n\n public get nodes() {\n return this._history.present\n }\n\n public get canRedo() {\n return this._history.canRedo\n }\n public get canUndo() {\n return this._history.canUndo\n }\n /**\n * True when the canvas matches the last state the store is known to hold —\n * i.e. there is nothing to save.\n *\n * An UNCONFIRMED baseline (see {@link updateInitialNodes}) always reads as\n * different. The editor is loaded, but nothing in it is known to be\n * persisted, and \"clean\" here disables Save: claiming a state is saved on\n * the strength of a snapshot the server never acknowledged is how unsaved\n * work becomes unsavable work (AGL-1262).\n */\n /**\n * The node map as it would be stored, cached until a node changes.\n *\n * A mobx computed rather than a call per reader because there are two\n * readers now (AGL-3271): {@link isInitialSame} and {@link isDraftedSame}\n * both compare a baseline against this, both are read while rendering the\n * toolbar, and serializing the whole tree twice per keystroke on a\n * document that can reach a megabyte is a cost neither of them needs to\n * pay. Read-only by contract — both hand it to `isEqual` and neither may\n * mutate what comes back.\n */\n public get serializedNodes(): NodesMap {\n return this.serializeNodes()\n }\n public get isInitialSame() {\n if (!this._initial) return true\n if (!this._initialConfirmed) return false\n return isEqual(this._initial, this.serializedNodes)\n }\n /**\n * True when the canvas is exactly the tree last recorded by\n * {@link updateDraftedNodes} — i.e. this work is stored somewhere, even\n * though {@link isInitialSame} says the DOCUMENT does not have it\n * (AGL-3271).\n *\n * FALSE when nothing has been recorded, which is the opposite default to\n * {@link isInitialSame}: no baseline there means nothing is loaded and so\n * there is nothing to save, while no draft here means no draft — and\n * \"stored\" is a claim that needs evidence, never an absence of it.\n */\n public get isDraftedSame() {\n if (!this._drafted) return false\n return isEqual(this._drafted, this.serializedNodes)\n }\n public get didSetInitial() {\n return Boolean(this._initial)\n }\n /** Whether the recorded baseline is one the store confirmed. */\n public get isInitialConfirmed() {\n return this._initialConfirmed\n }\n public get rootNode() {\n return this.nodes.get(NODE_ROOT_ID)\n }\n public get nestedNodes(): NodeSchemaNested<any> {\n const root = this.rootNode\n if (!root) throw new Error('Missing root node')\n return this.makeNested(root)\n }\n\n public hasNode = computedFn(($id: NodeId): boolean => {\n return this.nodes.has($id)\n })\n public getNode = computedFn(($id: NodeId): NodeSchema<any> | undefined => {\n if (!$id) return\n return this.nodes.get($id)\n })\n public nodesAreEqual = computedFn(\n (left: NodesMap, right?: NodesMap): boolean => {\n const _right = right ? right : this.nodes\n return isEqual(toJS(left), toJS(_right))\n },\n )\n public getNodeParent = computedFn(\n (node: NodeSchema<any>): NodeSchema<any> | undefined => {\n if (!node) throw new Error('Invalid node')\n if (!node.parentId) return\n return this.getNode(node.parentId)\n },\n )\n public getNodeIndex = computedFn((node: NodeSchema<any>): number => {\n if (!node || !node.$id) throw new Error('Invalid node')\n const parent = this.getNodeParent(node)\n if (!parent) throw new Error('Invalid parent node')\n return parent.nodes?.indexOf(node.$id) ?? -1\n })\n public isRootNodeId = computedFn(\n (id: NodeId): id is string & typeof NODE_ROOT_ID => {\n return id === NODE_ROOT_ID\n },\n )\n public isRootNode = computedFn((node: NodeSchema<any>): boolean => {\n return node?.$id === NODE_ROOT_ID\n })\n public getNodeBreadcrumbPath = computedFn(\n (nodeOrId: NodeId | NodeSchema<any>): NodeBreadcrumbPath => {\n const hierarchy = [NODE_ROOT_ID]\n\n // Visited ids, not just the root check: the root terminates the walk on\n // a well-formed document, but two nodes that parent each other\n // terminate nothing. An unbounded ancestor walk is a synchronous\n // infinite loop on the renderer's main thread — the tab stops answering\n // input entirely — so a malformed tree has to cost a truncated\n // breadcrumb instead.\n const seen = new Set<string>()\n let currentId: string | undefined =\n typeof nodeOrId !== 'string' ? nodeOrId?.$id : nodeOrId\n while (currentId && !this.isRootNodeId(currentId) && !seen.has(currentId)) {\n seen.add(currentId)\n hierarchy.splice(1, 0, currentId)\n currentId = this.getNode(currentId)?.parentId\n }\n\n return hierarchy as NodeBreadcrumbPath\n },\n )\n public getNodeLabelShort = computedFn((node: NodeSchema<any>): any => {\n if (!node) throw new Error('Invalid node')\n if (this.isRootNode(node)) return NODE_ROOT_LABEL\n // A reusable-component instance stands for one specific definition, and\n // its component label is the same generic word for every one of them —\n // a page built from promoted sections reads as a column of identical\n // \"Reusable Component\" rows in the hierarchy and identical badges on the\n // canvas. The definition's name rides on the instance for exactly this\n // (`props.name`, AGL-1193), so prefer it. An explicit per-node `name`\n // still wins, since that is someone deliberately renaming this instance.\n const instanceName =\n node.componentId === REUSABLE_INSTANCE_COMPONENT_ID\n ? (node.props as { name?: unknown } | undefined)?.name\n : undefined\n const componentLabel =\n node.componentId && this.aglyn.components.getLabel(node.componentId)\n return (\n node?.name ||\n (_isStrT(instanceName) ? instanceName : undefined) ||\n componentLabel ||\n node?.$id\n )\n })\n\n /**\n * Whether a node can host inserted child nodes. The document root and\n * layout containers (Stack, Section, Container — anything with a real\n * children slot) can; a leaf whose component is self-closing or renders\n * its `children` as inline text (a screen link, button, icon, image) has\n * no slot to receive them and can't. Components with no registered schema\n * default to accepting children.\n *\n * `flags.dropping: DISABLED` is the third way to say \"no canvas child\n * slot\" (AGL-1388), for components that are neither self-closing nor text\n * leaves but still have nowhere to put a dropped node:\n *\n * - Markdown renders the parsed `content` prop and nothing else, so a\n * dropped element lands somewhere the markdown source cannot say.\n * - A Reusable Component instance is opaque: compose REPLACES its child\n * list with the grafted definition subtree, so a canvas-dropped child is\n * destroyed before the page is rendered.\n * - A Layout Slot's children come from screen composition.\n *\n * The flag was declared on all three, and until now nothing read it —\n * which is exactly how three /press screenshots came to be parented under\n * a Markdown node, shipped in the page payload, and never drawn. A\n * container that accepts children in the hierarchy and discards them at\n * render is silent data loss: the author sees the nodes in the tree and\n * the published page does not have them.\n *\n * The rule itself lives in {@link schemaAcceptsChildren} (AGL-1389) so the\n * registry audit that enforces it cannot be checking a *copy* of it — a\n * second implementation would drift, and would then certify the editor's\n * behaviour against a rule the editor no longer follows.\n */\n public nodeAcceptsChildren = computedFn((node: NodeSchema<any>): boolean => {\n if (!node) return false\n if (this.isRootNode(node)) return true\n return schemaAcceptsChildren(\n this.aglyn?.components?.getSchema(node.componentId),\n )\n })\n\n /**\n * Resolve where a newly inserted node should attach, given the node the\n * user had selected (the Insert menu passes the current selection). A\n * container target — including the document-root fallback for a missing,\n * stale, or non-node target (AGL-537) — receives the node as an appended\n * child. A leaf target has no child slot, so the node lands as the leaf's\n * next sibling in its own container instead, mirroring how a\n * drag-and-drop side-drop resolves rather than nesting the node where it\n * can never render.\n */\n public resolveInsertTarget(target?: NodeSchema<any>): {\n parent: NodeSchema<any>\n index: number\n } {\n const root = this.getNode(NODE_ROOT_ID)!\n const requested =\n (typeof target?.$id === 'string' && this.getNode(target.$id)) || root\n if (this.nodeAcceptsChildren(requested)) {\n return { parent: requested, index: NaN }\n }\n const parent = this.getNodeParent(requested) ?? root\n const at = parent.nodes?.indexOf(requested.$id) ?? -1\n return { parent, index: at < 0 ? NaN : at + 1 }\n }\n\n public makeNested = computedFn((node: NodeSchema<any>) => {\n // Serialize to a plain schema object: a toJS copy would carry the node's\n // own toJSON arrow (bound to the live instance), which JSON.stringify\n // would then prefer over the nested structure built here.\n const newNode = (\n node instanceof AglynNode ? node.toJSON() : { ...toJS(node) }\n ) as unknown as NodeSchemaNested<any>\n\n const childNodes: NodeSchemaNested<any>[] = []\n for (const childId of (toJS(node.nodes) || []) as unknown as NodeId[]) {\n const child = this.getNode(childId)\n if (child) {\n const nested = this.makeNested(child)\n childNodes.push(nested)\n }\n }\n newNode.nodes = childNodes\n\n return newNode\n })\n\n private serializeNodes(): NodesMap {\n const nodes: NodesMap = {}\n this.nodes.forEach((node, id) => {\n nodes[id] = node.toJSON()\n })\n return nodes\n }\n\n public toJSON() {\n return { nodes: this.serializeNodes() }\n }\n\n public redo(): this {\n return this.restoreSnapshot(this._history.redo(this._epoch))\n }\n public undo(): this {\n return this.restoreSnapshot(this._history.undo(this._epoch))\n }\n public saveHistory(): this {\n // Inside a batch, the snapshot the batch took is the step every mutation\n // folds into — see `batch`.\n if (this._batchDepth > 0) return this\n this._history.saveHistory(this._epoch)\n return this\n }\n /**\n * Records that a REMOTE session changed `nodeId`, so a later local undo\n * does not roll that change back (AGL-1958).\n *\n * Call this from the co-editing apply path for every node a peer creates,\n * changes or deletes — including the delete, whose absence is as much a\n * remote state as a value is.\n *\n * ## Why this is needed at all\n *\n * Applying a remote change deliberately does NOT record local history\n * (AGL-677 rule 1), which keeps a colleague's edit out of your undo\n * stack. That is necessary and it is not sufficient. Every entry already\n * in the stack is a snapshot of the WHOLE document taken before one of\n * your edits, and a colleague's later edit is by definition not in it. So\n * an undo that replays such a snapshot wholesale reverts their node too,\n * and — because the reverted map is then diffed against the co-editing\n * shadow like any other local edit — publishes that revert back to them\n * under YOUR session id. Their work is destroyed on their screen, with no\n * signal and nothing that restores it.\n *\n * Measured before this fix: a peer's edit came back reverted, and a node\n * the peer had CREATED was deleted outright.\n *\n * ## An apply that changed nothing is not a peer edit (AGL-2486)\n *\n * `previousJson` is the node's serialization from BEFORE the apply. When\n * the apply left it byte-for-byte identical, this records nothing: no\n * mark, no epoch bump. That is not an optimisation, it is the difference\n * between a peer edit and an ECHO, and getting it wrong broke undo\n * outright.\n *\n * The mirror is per node and every session in the room republishes what it\n * holds, so a value you wrote can come back to you from ANOTHER SESSION —\n * your own second tab most of all, which is ordinary once same-account\n * sessions count as co-editors. The room already drops your own tab's\n * echoes by session id, but not another session's echo of your value.\n *\n * Marking that echo is fatal because the mark is what {@link\n * restoreSnapshot} reads. It lands with a FRESH epoch, therefore newer\n * than every snapshot already on your stack, so the overlay puts the live\n * value back over each one of them. Undo then consumed its entry and\n * changed nothing at all — measured on the running editor, one account,\n * two tabs on one screen: `past: 0, future: 1, canUndo: false`, the node\n * still holding the edit that had just been undone.\n *\n * Note what this deliberately does NOT do: it does not ask whose session\n * or whose account the change came from. A genuinely different value from\n * your other tab is a real concurrent edit with its own undo stack and is\n * protected like any other. \"Foreign\" keeps its one meaning — a session\n * other than this tab moved this node — and the defect was counting a\n * non-change as a change.\n */\n public markRemoteNode(nodeId: NodeId, previousJson?: string): this {\n if (!nodeId) return this\n if (previousJson !== undefined) {\n const live = this.nodes.get(nodeId)\n const nowJson = live ? JSON.stringify(live.toJSON()) : undefined\n if (nowJson === previousJson) return this\n }\n this._foreignAt.set(nodeId, ++this._epoch)\n return this\n }\n /**\n * A node's serialization as it stands right now, for handing back to\n * {@link markRemoteNode} after an apply — the \"before\" half of the echo\n * test. `undefined` when the node is not in the map.\n */\n public serializeNode(nodeId: NodeId): string | undefined {\n const node = this.nodes.get(nodeId)\n return node ? JSON.stringify(node.toJSON()) : undefined\n }\n /**\n * Restores a history snapshot, keeping every node a remote session has\n * touched SINCE that snapshot was taken (AGL-1958).\n *\n * The epoch comparison is the whole mechanism, and it is what keeps undo\n * honest rather than merely safe:\n *\n * * `foreignAt > snapshot.epoch` — the peer's change landed *after* this\n * snapshot, so the snapshot predates it and would roll it back. Keep\n * what is live now: the current value, or the node's absence when the\n * peer deleted it.\n * * `foreignAt <= snapshot.epoch` — the snapshot was taken after the\n * peer's change and therefore already contains it. Restore it normally,\n * or undo would stop rewinding your own edits to co-edited nodes.\n *\n * A node both you and a peer changed resolves to the peer's value, which\n * is the same last-writer-wins rule the per-node mirror applies\n * everywhere else (AGL-677) rather than a new one invented here.\n *\n * A peer that adds a child republishes the parent's child list, so the\n * parent is marked too and its list survives with the child.\n *\n * ## Both directions, and why redo is not the special case it looks like\n *\n * This serves {@link redo} as well as {@link undo}, and the stamp is what\n * makes that work rather than a second rule (AGL-2486). A `future` entry\n * replays a state from before the undo, so the intuition is that it must\n * predate any later peer change and roll it back. It does not:\n * `HistoryManager.undo` captures the present and stamps it with the epoch\n * AT THE TIME OF THE UNDO, so a peer change that lands between the undo\n * and the redo is strictly newer than `snapshot.epoch` and is kept here —\n * including a node the peer CREATED in that gap, which the `future` entry\n * has no key for at all and a bare replace would broadcast as a delete.\n */\n private restoreSnapshot(\n snapshot: HistorySnapshot<NodeId, NodeSchema<any>>,\n ): this {\n const json: Record<NodeId, NodeSchema<any>> = Object.fromEntries(\n snapshot.nodes.entries(),\n )\n this.setNodes(this.withForeignNodes(json, snapshot.epoch) as NodesMap)\n return this\n }\n /**\n * Overlays the nodes a remote session has touched since `sinceEpoch` onto a\n * map about to REPLACE the canvas — the current value, or the node's\n * absence when the peer deleted it (AGL-1958).\n *\n * Shared by {@link restoreSnapshot} and {@link applyNodes} because it is\n * one rule, not two: any wholesale replace composed without knowledge of a\n * peer's change would otherwise roll that change back and — through the\n * co-editing diff — publish the rollback to its author.\n *\n * Mutates and returns `json`; callers pass a map they own.\n */\n private withForeignNodes(\n json: Record<NodeId, NodeSchema<any>>,\n sinceEpoch: number,\n ): Record<NodeId, NodeSchema<any>> {\n for (const [nodeId, at] of this._foreignAt) {\n if (at <= sinceEpoch) continue\n const live = this.nodes.get(nodeId)\n if (live) json[nodeId] = live\n else delete json[nodeId]\n }\n return json\n }\n /**\n * Whether any REMOTE session has changed this canvas since it loaded\n * (AGL-2486).\n *\n * The draft prompt reads it to decide whether offering a private\n * per-browser snapshot back is still honest: once a colleague's live work\n * is on the canvas, applying an older whole-document snapshot is not\n * \"restore my unsaved changes\" but \"roll the shared canvas back\".\n *\n * `_epoch` only ever moves in {@link markRemoteNode}, so a non-zero epoch\n * IS \"a peer has touched this canvas\", and {@link reset} returns it to zero\n * with the rest of the session.\n */\n public get hasRemoteEdits(): boolean {\n return this._epoch > 0\n }\n /**\n * Runs `mutate` as one undoable step (AGL-1204).\n *\n * Every mutator on this class records history for itself, but a panel that\n * writes `node.sx` directly does not go through any of them — the Styles and\n * custom-CSS forms assign to the node, so an undo after a style change\n * restored the last *recorded* snapshot instead, silently discarding\n * everything done since. This is the seam those panels were missing.\n *\n * **`coalesceKey` is what makes it usable for a live-applying control.**\n * Those forms fire on every change — one per character typed, one per drag\n * tick of a slider — so recording unconditionally would replace \"undo does\n * not step back far enough\" with \"undo steps back one character\", which is\n * no better. Consecutive calls sharing a key inside {@link\n * COALESCE_WINDOW_MS} record **once**, at the start of the burst, so the\n * snapshot is the state *before* the adjustment began. Omit the key for a\n * discrete commit (a toggle, an Apply button) that deserves its own step.\n *\n * The window is evaluated on call rather than by a timer: a burst ends\n * because the next edit arrives late, not because something fired in the\n * background. That keeps the canvas free of pending timers it would have to\n * cancel on {@link reset}, and keeps this testable without fake clocks.\n *\n * The key should identify *what* is being adjusted, not just the node —\n * moving from Gap to Padding is a second adjustment even if it happens\n * within the window.\n */\n public transact<T>(mutate: () => T, coalesceKey?: string): T {\n const now = Date.now()\n const burst = this._coalescing\n const continues =\n coalesceKey !== undefined &&\n burst?.key === coalesceKey &&\n now - burst.at < CanvasManager.COALESCE_WINDOW_MS\n if (!continues) this.saveHistory()\n this._coalescing =\n coalesceKey === undefined ? undefined : { key: coalesceKey, at: now }\n return mutate()\n }\n /**\n * Runs several mutations as ONE undoable step, all or nothing.\n *\n * `transact` records one snapshot and then runs code that assigns to nodes\n * directly. That is right for a panel writing `node.sx`, and wrong for a\n * caller that composes the guarded mutators — `addNodeFromNested`,\n * `updateNodeProps`, `reparentNode`, `deleteNode` — because each of those\n * records its own step. A change made of five of them would take five\n * undos to take back, and an undo that stops part-way leaves the document\n * in a state nobody authored.\n *\n * So inside a batch the mutators keep every guard and record nothing: the\n * batch's own snapshot, taken before `mutate` runs, is the step. A nested\n * batch folds into the outer one.\n *\n * A mutation that throws — a guard refusing a stale parent, a move into\n * the node's own subtree — rolls the whole batch back to that snapshot\n * and removes the snapshot from both stacks before the error propagates.\n * Half a batch is not an edit anyone asked for, and a refused batch must\n * not leave an undo step that restores a state identical to the present.\n */\n public batch<T>(mutate: () => T): T {\n if (this._batchDepth > 0) return mutate()\n this._history.saveHistory(this._epoch)\n // Whatever burst was open described the state before this batch.\n this._coalescing = undefined\n this._batchDepth += 1\n let completed = false\n try {\n const result = mutate()\n completed = true\n return result\n } finally {\n this._batchDepth -= 1\n // `canUndo` is only false when `mutate` itself cleared the history,\n // and then there is no snapshot left to roll back to.\n if (!completed && this._history.canUndo) {\n this.restoreSnapshot(this._history.undo(this._epoch))\n this._history.clearFuture()\n }\n }\n }\n /**\n * Drops BOTH history stacks and any open {@link transact} burst.\n *\n * Both, deliberately (AGL-2486). This used to clear `past` alone, which\n * left a caller that had just \"cleared history\" holding a live redo stack\n * — `canRedo` still true, still offering a snapshot of the state before\n * the clear. `reset` was the only caller and compensated for it a line\n * later, which is exactly how the next caller inherits the trap.\n *\n * A stale redo is worse than a stale undo in a co-editing session: redo\n * replays a WHOLE-DOCUMENT snapshot, and the restored map is diffed\n * against the co-editing shadow and published, so every node the snapshot\n * does not have goes out as a delete under this session's id.\n */\n public clearHistory() {\n this._history.clearHistory()\n this._coalescing = undefined\n }\n public createNodeId(): NodeId {\n return createIdUrlSafe()\n }\n public createNode(\n schema: PartialKeys<NodeSchema<any>, '$id'>,\n ): NodeSchema<any> {\n return new AglynNode<any>(\n {\n ...schema,\n $id: schema?.$id || this.createNodeId(),\n } as NodeSchema<any>,\n this,\n )\n }\n public clearNodes() {\n this.nodes.clear()\n return this\n }\n /**\n * Returns the canvas to its pristine state (no nodes, no history, no\n * recorded initial snapshot). The canvas is an app-level singleton shared\n * by every editing session — call this when a session ends so the next\n * document doesn't inherit stale content.\n */\n public reset() {\n this.clearNodes()\n this.clearHistory()\n this._initial = undefined\n this._initialConfirmed = true\n this._drafted = undefined\n // A new document gets a new epoch line. Stale marks would otherwise\n // preserve node ids that mean something else here (AGL-1958).\n this._foreignAt.clear()\n this._epoch = 0\n return this\n }\n /**\n * Record the state the canvas should be considered saved against.\n *\n * `confirmed` is what makes this honest. Pass `false` when the map came\n * from a source the STORE has not acknowledged — a Firestore snapshot\n * carrying this client's own pending write is the case that motivated it\n * (AGL-1262): the document is loaded and must be shown, but nothing in it\n * is known to have reached the server, so it must not be adopted as\n * \"already saved\". An unconfirmed baseline keeps {@link isInitialSame}\n * false — the editor stays savable — until a real save records a\n * confirmed one.\n */\n public updateInitialNodes(nodes?: NodesMap, options?: { confirmed?: boolean }) {\n this._initial = nodes ? (toJS(nodes) as NodesMap) : this.serializeNodes()\n this._initialConfirmed = options?.confirmed ?? true\n return this\n }\n /**\n * Promote an UNCONFIRMED baseline to a confirmed one, once the store has\n * acknowledged the write that made it unconfirmed (AGL-2486).\n *\n * Without this there is no way back. `_initialConfirmed` moves to true in\n * only two other places — {@link reset} and {@link updateInitialNodes} —\n * and the editor records its baseline exactly once, on the first snapshot\n * that carries nodes. A document whose first snapshot happens to carry\n * this client's own queued write therefore reads dirty for the rest of the\n * session over content nobody has edited.\n *\n * Conditional on the canvas still MATCHING the baseline, which is what\n * keeps AGL-1262 intact. The acknowledgement is for the write that was in\n * flight, and says nothing about work the author has done since; adopting\n * a canvas that has moved on would call that work saved and take away the\n * only control that could still write it.\n *\n * @returns whether the baseline is confirmed as a result.\n */\n public confirmInitialNodes(): boolean {\n if (!this._initial) return false\n if (this._initialConfirmed) return true\n if (!isEqual(this._initial, this.serializeNodes())) return false\n this._initialConfirmed = true\n return true\n }\n /**\n * Record the tree a store OTHER than the document now holds — today the\n * shared working draft, written by Save draft on the version a site is\n * serving (AGL-3271).\n *\n * Pass what was actually WRITTEN, not the canvas at the moment the write\n * resolved: an author who kept typing through the round trip has work the\n * draft does not hold, and recording the later canvas would call it stored.\n * Omit the argument only when the two are known to be the same.\n *\n * Records nothing about the document, so {@link isInitialSame} is\n * untouched: a drafted canvas still has everything to save, and Save stays\n * alive (AGL-1262).\n */\n public updateDraftedNodes(nodes?: NodesMap) {\n this._drafted = nodes ? (toJS(nodes) as NodesMap) : this.serializeNodes()\n return this\n }\n /**\n * Registers a node in the map AND lists it on `parent`, in one action\n * (AGL-1366).\n *\n * `parent` is required, and that is the whole point: this was the last way\n * left to put an entry in `this.nodes` with no parent linkage at all. The\n * besigner saves a flat map and renders a tree — `serializeNodes` dumps\n * every entry in the map while the renderer walks child lists down from\n * `NODE_ROOT_ID` — so a node the map holds and no parent lists is not a\n * rendering glitch that a reload clears. It is saved on every save,\n * shipped in every payload, counted against the 1 MiB ceiling, and never\n * drawn. That is the mechanism behind the 61 unreachable nodes `/product`\n * served, 26 of them carrying the only copy of two Hero sections' text\n * (AGL-1363).\n *\n * An *optional* parent would not have closed it, because the caller who\n * omits it is precisely the caller who creates the orphan. So the linkage\n * is not a second step a caller may forget — it happens here, and the\n * parent is resolved through `getNode($id)` and throws on a miss: the same\n * guard `addNodeFromNested` has carried since AGL-537 and `reparentNode`\n * took on in AGL-1363, rather than a second mechanism. A stale instance a\n * panel closure kept across a co-editor's merge, or a parent a peer has\n * since deleted, therefore fails loud instead of stranding the node.\n *\n * Linking is idempotent: re-setting a node its parent already lists\n * replaces the map entry and leaves the child list untouched, so this\n * stays usable as an update.\n *\n * The root is refused outright — it has no parent to be listed on, and\n * seeding it belongs to `setNodes`, which alone keeps its canonical id.\n */\n public setNode(\n node: NodeSchema<any>,\n parent: NodeSchema<any> | NodeId,\n index = NaN,\n create = false,\n ): NodeSchema<any> {\n if (!node) throw new Error('Invalid node')\n if (!create && !node.$id) throw new Error('Invalid node id')\n if (this.isRootNode(node)) throw new Error('Cannot set root node')\n\n // Resolve through the LIVE map BEFORE anything is inserted, so a refused\n // call leaves the canvas exactly as it found it.\n const parentId = typeof parent === 'string' ? parent : parent?.$id\n const target = parentId != null ? this.getNode(parentId) : undefined\n if (!target) throw new Error('Invalid parent node')\n\n return runInAction(() => {\n const _node = create ? this.createNode(node) : node\n // Both directions of the link are set here; a `parentId` disagreeing\n // with the list that holds the id is the same orphan by another route.\n _node.parentId = target.$id\n this.nodes.set(_node.$id!, _node)\n // Read-back, not `(target.nodes ||= []).push()` — see reparentNode\n // (AGL-763): the `||=` value is the detached plain array on an\n // observable.\n if (!target.nodes) target.nodes = []\n if (!target.nodes.includes(_node.$id!)) {\n if (isNaN(index)) target.nodes.push(_node.$id!)\n else target.nodes.splice(index, 0, _node.$id!)\n }\n return this.nodes.get(_node.$id!)!\n })\n }\n public setNodes(schemas: NodesMap, merge = false): this {\n if (!schemas) throw new Error('Invalid schemas')\n // Replacing the map ends any open {@link transact} burst (AGL-1204).\n // This is the seam a co-editor's incoming change arrives through, and\n // the one an undo restores through: in both cases the state the open\n // burst snapshotted is no longer the state the next edit is adjusting,\n // so the next edit must record its own step rather than fold into it.\n this._coalescing = undefined\n const cloned = toJS(schemas)\n const nodes: Record<NodeId, NodeSchema<any>> = {}\n for (const nodeId in cloned) {\n const node = cloned[nodeId]\n if (!node) continue\n // Persisted maps key nodes by id. Early seeds omitted $id (which used\n // to mint a random one), and the root must always keep the canonical\n // id — the map key is authoritative.\n const $id =\n nodeId === NODE_ROOT_ID ? NODE_ROOT_ID : (node.$id ?? nodeId)\n nodes[nodeId] = this.createNode({ ...node, $id })\n }\n if (merge) {\n this.nodes.merge(nodes)\n } else {\n this.nodes.replace(nodes)\n }\n return this\n }\n /**\n * Replaces the whole node map with a map the USER supplied — the raw-JSON\n * editor, and the local draft the crash net offers back (AGL-2486).\n *\n * Snapshots first, so the replacement is undoable — unlike `setNodes`,\n * which also serves the history-restore and initial-load paths.\n *\n * **Every node a remote session has touched survives it**, on exactly the\n * reasoning AGL-1958 established for undo. A wholesale replace is the same\n * shape of write as a snapshot restore: the map being applied was composed\n * without any knowledge of the peer's later changes, and the result is\n * diffed against the co-editing shadow and published, so a node the map\n * happens to lack is broadcast as a DELETE under this session's id.\n * Measured on the running editor before this changed (AGL-2486): a peer\n * created a node, the other session pressed Restore, and the node vanished\n * from the peer's own canvas with an RTDB tombstone to show for it.\n *\n * Every mark counts, not only those newer than some epoch: unlike a\n * snapshot, an applied map carries no epoch of its own, and a draft was by\n * definition composed before this page joined the room.\n */\n public applyNodes(value: ProcessableNodes): this {\n this.saveHistory()\n const parsed = this.processNodesToDenormalized(value)\n return this.setNodes(\n this.withForeignNodes({ ...parsed }, 0) as typeof parsed,\n )\n }\n public deleteNode(node: NodeSchema<any>): this {\n const validateNode = (node: NodeSchema<any>) => {\n if (!node || !node?.$id || !node?.parentId)\n throw new Error('Invalid node')\n if (this.isRootNode(node)) throw new Error('Cannot delete root node')\n }\n\n validateNode(node)\n this.saveHistory()\n\n const del = (node: NodeSchema<any>) => {\n validateNode(node)\n const parent = this.getNode(node.parentId!)\n if (!parent) throw new Error('Invalid parent node')\n const index = parent.nodes?.indexOf(node.$id) ?? -1\n const nodes = toJS(node.nodes || [])\n\n for (const childId of [...nodes]) {\n const child = this.getNode(childId)\n if (child) del(child)\n }\n\n if (index > -1) parent.nodes?.splice(index, 1)\n this.nodes.delete(node.$id)\n }\n del(node)\n return this\n }\n /**\n * Moves a node under `newParent`, resolving BOTH ends through the live\n * node map first (AGL-1363).\n *\n * The resolution is the guard, and it is the same one `addNodeFromNested`\n * has carried since AGL-537. This method splices the node out of its\n * *live* old parent and then attaches it to the object it was handed — so\n * a `newParent` that is merely SHAPED like a node (a stale instance a\n * panel closure kept across a co-editor's merge, a node a peer has since\n * deleted, historically a click event) took the node out of the tree and\n * pushed its id onto a detached array. Nothing put it back.\n *\n * That is not a recoverable glitch: `serializeNodes` dumps the whole map\n * while the renderer walks the tree from `NODE_ROOT_ID`, so a node in the\n * map that no live parent lists is saved on every save, shipped in every\n * payload, counted against the 1 MiB ceiling — and never drawn. It is why\n * `/product` served 61 unreachable nodes, 26 of them carrying the only\n * copy of two Hero sections' text. Fail loud instead.\n *\n * `index` is the node's position in the resulting sibling list — i.e. it is\n * read AFTER the node has been spliced out of wherever it was. A caller\n * holding a drop marker (\"put it before the sibling currently at 3\") is\n * describing the list BEFORE the removal and has to convert; the dnd\n * manager does exactly that for same-parent drops.\n */\n public reparentNode(\n node: NodeSchema<any>,\n newParent: NodeSchema<any>,\n index = NaN,\n ): typeof node {\n if (!node) throw new Error('Invalid node')\n if (this.isRootNode(node)) throw new Error('Cannot move root node')\n if (!newParent) throw new Error('Invalid parent node')\n\n // Every refusal below runs before `saveHistory`: a move that never\n // happened must not leave an undo step behind it.\n const target = node.$id != null ? this.getNode(node.$id) : undefined\n if (!target) throw new Error('Invalid node')\n const parent =\n newParent.$id != null ? this.getNode(newParent.$id) : undefined\n if (!parent) throw new Error('Invalid parent node')\n\n const oldParent = this.getNodeParent(target)\n const oldIndex = oldParent?.nodes?.indexOf(target.$id) ?? -1\n const sameParent = oldParent?.$id === parent.$id\n\n if (!sameParent) {\n // A node into its own subtree detaches that subtree from the document\n // and hands the renderer a cycle. `breadcrumbPath` is the ancestor\n // chain, so the target appearing in the new parent's is the whole test\n // — and it covers `parent === target` on its own.\n if (this.getNodeBreadcrumbPath(parent)?.some((id) => id === target.$id)) {\n throw new Error('Cannot move an element inside itself')\n }\n\n /**\n * The gate that was missing (AGL-1405). `nodeAcceptsChildren` guarded\n * every path that CREATES a node — the Insert menu and paste through\n * `resolveInsertTarget`, drag-and-drop through the dnd manager — but\n * not the one that MOVES one. So a `markdown` block (or any component\n * whose content is an attribute: a Reusable Component instance, a\n * Layout Slot, a List Item Text) could still be handed a child, which\n * it then renders nowhere. That is not a cosmetic mistake: the node is\n * saved on every save and shipped in every payload while the page it\n * belongs to shows nothing, so the work reads as never done rather\n * than broken. Three /press screenshots are still sitting in exactly\n * that hole, and the point of the click-path this guard protects is\n * that it must not be able to dig another one.\n *\n * A same-parent reorder is deliberately NOT gated: the nodes already\n * trapped by AGL-1388 have to stay shufflable, and `reorderNode`\n * routes Shift up / Shift down straight through here.\n */\n // Deliberately label-free: `getNodeLabelShort` reaches into the\n // component registry, and a refusal path that can itself throw is no\n // refusal at all. Callers that want \"Markdown can't hold elements\"\n // name the node themselves — `moveNodeOut`/`moveNodeIn` do.\n if (!this.nodeAcceptsChildren(parent)) {\n throw new Error('That element cannot hold other elements')\n }\n }\n\n // Assign then read back, never `(x.nodes ||= []).push()` (AGL-763). A\n // live node is a `makeAutoObservable` proxy: assigning a fresh `[]` stores\n // an observable copy, but the `||=` expression evaluates to the plain\n // array that was assigned — so pushing onto it writes to a detached array\n // and the child silently orphans. `AglynNode`'s constructor seeds `nodes`\n // so this never actually fires today, but relying on that invariant from\n // here is how the same defect returned as AGL-759.\n if (!parent.nodes) parent.nodes = []\n\n // Resolve the landing slot against the list as it will be AFTER the\n // removal, and clamp it. `splice(-1, 0, id)` inserts before the LAST\n // element, so an unclamped negative index moved a first child DOWN —\n // `reorderNode(node, node.index - 1)` on index 0 did precisely that, and\n // only the menu's `disabled` prop hid it.\n const settled = parent.nodes.length - (sameParent && oldIndex > -1 ? 1 : 0)\n const at = isNaN(index) ? settled : Math.min(Math.max(index, 0), settled)\n\n // A move that resolves to the slot the node already occupies is not a\n // move. It used to cost an undo step anyway — which is how a hierarchy\n // drag came to \"record an undo entry without moving anything\" (AGL-1405),\n // and worse, made the next Undo discard the author's PREVIOUS edit.\n if (sameParent && at === oldIndex) return target\n\n this.saveHistory()\n if (oldIndex > -1) oldParent?.nodes?.splice(oldIndex, 1)\n if (!sameParent) target.parentId = parent.$id\n parent.nodes.splice(at, 0, target.$id)\n return target\n }\n public reorderNode(node: NodeSchema<any>, index = NaN): typeof node {\n if (!node) throw new Error('Invalid node')\n // Resolve the node first, so the parent is read off the LIVE node's\n // `parentId` rather than a stale copy's (AGL-1363).\n const target = node.$id != null ? this.getNode(node.$id) : undefined\n if (!target) throw new Error('Invalid node')\n const parent = this.getNodeParent(target)\n if (!parent) throw new Error('Invalid parent node')\n return this.reparentNode(target, parent, index)\n }\n public duplicateNode(node: NodeSchema<any>): NodeSchema<any> {\n if (!node) throw new Error('Invalid node')\n if (this.isRootNode(node)) throw new Error('Cannot duplicate root node')\n const parent = this.getNodeParent(node)\n if (!parent) throw new Error('Invalid parent node')\n\n const duplicateNodeAndChildren = (\n node: NodeSchema<any>,\n parentId: NodeId,\n index = NaN,\n ): NodeSchema<any> => {\n if (!node) throw new Error('Invalid node')\n\n const json = toJS(node)\n // `setNode` registers the copy AND lists it on its parent, so no copy\n // can be left in the map unreferenced — the linkage is no longer a\n // separate step this recursion could get wrong (AGL-1366).\n const newNode = this.setNode(\n this.createNode({\n ...json,\n $id: this.createNodeId(),\n parentId,\n nodes: [],\n }),\n parentId,\n index,\n )\n if (!json) return newNode\n\n for (const childId of arraySafe(json.nodes)) {\n const child = childId && this.getNode(childId)\n if (child) duplicateNodeAndChildren(child, newNode.$id!)\n }\n\n return newNode\n }\n\n this.saveHistory()\n const nodeIndex = this.getNodeIndex(node)\n const index =\n nodeIndex === -1 ? parent.nodes?.length ?? 0 : nodeIndex + 1\n // One action, so observers never see the copy listed on its parent\n // before its own subtree has been built under it.\n return runInAction(() =>\n duplicateNodeAndChildren(node, node.parentId!, index),\n )\n }\n public createDuplicateNode(\n node: NodeSchemaNested<any>,\n ): NodeSchemaNested<any> {\n const $id = this.createNodeId()\n const cloned = toJS(node)\n const nodes = Array.isArray(cloned?.nodes) ? [...cloned.nodes] : []\n const res: NodeSchemaNested<any> = { ...cloned, $id, nodes: [] }\n for (const child of nodes) {\n const childDuplicate = this.createDuplicateNode({\n ...child,\n parentId: $id,\n })\n res.nodes!.push(childDuplicate)\n }\n return res\n }\n /**\n * Insert a *detached* nested subtree as a child of `parent`, minting a\n * fresh id for every node in it (AGL-1202).\n *\n * The subtree is plain JSON with no ties to this canvas, so the source can\n * be anything — an element preset, the besigner clipboard, or a subtree\n * copied out of a different document altogether. Callers are responsible\n * for checking that the root's component is registered and that the\n * lineal relationship with `parent` is allowed; this method only does the\n * structural work.\n */\n public addNodeFromNested(\n nested: NodeSchemaNested<any>,\n parent: NodeSchema<any>,\n index = NaN,\n ): NodeSchema<any> {\n if (!nested) throw new Error('Invalid node')\n // Attach to the live node in this canvas. A caller-supplied object\n // that is not in the node map (a stale reference — or historically the\n // console INSERT menu's click event) would otherwise get the child id\n // pushed onto ITS `nodes` array while the child lands in the map as a\n // detached node: absent from the hierarchy, the canvas, and saves\n // (AGL-537). Fail loud instead of corrupting the tree.\n const target = parent?.$id != null ? this.getNode(parent.$id) : undefined\n if (!target) throw new Error('Invalid parent node')\n this.saveHistory()\n const duplicate = this.createDuplicateNode(nested)\n duplicate.parentId = target.$id\n const parsed = this.processNodesToDenormalized(duplicate)\n\n // Register the subtree and append the child id in one action so\n // observers never see the intermediate detached state.\n runInAction(() => {\n this.setNodes(parsed, true)\n // Read-back, not `(target.nodes ||= []).push()` — see reparentNode\n // (AGL-763): the `||=` value is the detached plain array on an observable.\n if (!target.nodes) target.nodes = []\n if (isNaN(index)) target.nodes.push(duplicate.$id)\n else target.nodes.splice(index, 0, duplicate.$id)\n })\n\n return this.getNode(duplicate.$id)!\n }\n\n public addNodeFromPreset(\n preset: PresetSchema<any>,\n parent: NodeSchema<any>,\n index = NaN,\n ): NodeSchema<any> {\n if (!preset) throw new Error('Invalid preset')\n return this.addNodeFromNested(toJS(preset).data, parent, index)\n }\n /**\n * REPLACES a node's props — callers spread the current ones to merge.\n *\n * An editor form submits every field it renders, so keys the author left\n * empty arrive as `undefined`. Those are dropped here rather than stored as\n * own keys (AGL-1334): for a props bag that is REPLACED wholesale, absent IS\n * cleared, and an `undefined` member is a value no storage layer accepts.\n * `AglynNode.toJSON` strips again at the write boundary — this one keeps the\n * live tree honest for everything that reads it before a save.\n */\n /**\n * Writes top-level node FIELDS, with an undo step.\n *\n * The sibling of {@link updateNodeProps}, and it exists for the same two\n * reasons that one documents. An edit with no `saveHistory` is an edit the\n * author cannot take back — and every panel that assigned to a node\n * directly was quietly in that state. And it re-resolves by `$id`: callers\n * hold node objects across time (the focus store keeps the selection that\n * way), while every wholesale replace of the map — `undo`, `redo`,\n * `applyNodes`, a draft restore — builds fresh instances. Assigning to the\n * caller's copy then mutates an orphan: no error, no dirty state, and the\n * author's edit is simply gone.\n *\n * Only the keys the patch names are touched, and `undefined` clears one —\n * which is how a cleared style or a shown element is stored, since `toJSON`\n * omits what is undefined.\n */\n public updateNodeFields(\n node: NodeSchema<any>,\n patch: Partial<NodeSchema<any>>,\n ): void {\n if (!node) throw new Error('Invalid node')\n this.saveHistory()\n const target = this.getNode(node.$id) ?? node\n Object.assign(target, patch)\n }\n\n public updateNodeProps(\n node: NodeSchema<any>,\n props: NodeSchema<any>['props'],\n ): void {\n if (!node) throw new Error('Invalid node')\n this.saveHistory()\n // Write to the node the MAP holds, not the reference the caller kept\n // (AGL-2486). Callers hold node objects across time — the besigner's\n // focus store keeps the selection that way — and every wholesale replace\n // of the map (`undo`, `redo`, `applyNodes`, a draft restore) builds fresh\n // instances. Assigning to the caller's copy then mutates an orphan: no\n // error, no dirty state, and the author's edit is simply gone. Re-resolve\n // by `$id` so the write always reaches the canvas.\n //\n // The fallback keeps a node that is genuinely not in the map — deleted,\n // or never inserted — behaving as before rather than being resurrected.\n const target = this.getNode(node.$id) ?? node\n target.props = stripUndefinedDeep({ ...props })\n }\n\n public static nestDenormalizedNodes(\n nodes: NodesMap,\n rootId: NodeId = NODE_ROOT_ID,\n ): NodeSchemaNested<any> {\n const rootNode = nodes[rootId]\n if (!rootNode) throw new Error('Invalid root node')\n const response = { ...(rootNode as unknown as NodeSchemaNested<any>) }\n const children: NodeSchemaNested<any>[] = []\n // `?? []`, not `||= []` — a read-only walk should not mutate its input\n // (AGL-763).\n for (const id of rootNode.nodes ?? []) {\n const child = { ...nodes[id] }\n const nestedChild = this.nestDenormalizedNodes(nodes, child.$id)\n children.push(nestedChild)\n }\n response.nodes = children\n return response\n }\n\n public denormalizeNodes(\n nodes: NodeSchemaNested<any>[],\n parentId: NodeId,\n accumulator: NodesMap = {},\n ): NodesMap {\n return CanvasManager.denormalizeNodes(nodes, parentId, accumulator)\n }\n public static denormalizeNodes(\n nodes: NodeSchemaNested<any>[],\n parentId: NodeId,\n accumulator: NodesMap = {},\n ): NodesMap {\n for (const childNode of Array.isArray(nodes) ? nodes : []) {\n const child =\n _isStrT(childNode) && accumulator[childNode]\n ? accumulator[childNode]\n : childNode\n if (!_isObj(child)) continue\n\n const node = cloneDeep(child) as unknown as NodeSchema<any>\n\n // TODO: Remove after migration to nodes property\n if (node['elements']) {\n node.nodes = node['elements']\n delete node['elements']\n }\n // TODO: Remove after migration to pluginId property\n if (node['bundleId']) {\n node.pluginId = node['bundleId']\n delete node['bundleId']\n }\n\n const nodes = (node as unknown as NodeSchemaNested<any>)?.nodes\n const nodesArray = [...(Array.isArray(nodes) ? nodes : [])].filter(\n Boolean,\n )\n accumulator[node.$id] = {\n ...node,\n parentId,\n nodes: [...nodesArray]\n .map((i) => {\n if (_isStrT(i)) return i\n if (_isObj(i)) return i.$id\n return null\n })\n .filter(Boolean),\n }\n this.denormalizeNodes(nodesArray, node.$id, accumulator)\n }\n\n return accumulator\n }\n\n public processNodesToDenormalized(value: ProcessableNodes): NodesMap {\n return CanvasManager.processNodesToDenormalized(value)\n }\n public static processNodesToDenormalized(value: ProcessableNodes): NodesMap {\n let response: NodesMap = {}\n const isArray = Array.isArray(value)\n\n if (isArray && value.length === 1) {\n const item = value[0]\n if (item?.$id === NODE_ROOT_ID) {\n response = this.denormalizeNodes(\n [{ ...item, parentId: null }],\n NODE_ROOT_ID,\n response,\n )\n } else if (item?.parentId === NODE_ROOT_ID || (item && item.parentId)) {\n response = this.denormalizeNodes(\n [{ $id: NODE_ROOT_ID, componentId: 'div', nodes: [item] }],\n NODE_ROOT_ID,\n response,\n )\n } else if (item?.parentId) {\n response = this.denormalizeNodes(\n [{ $id: item?.parentId, componentId: 'div', nodes: [item] }],\n item?.parentId,\n response,\n )\n } else {\n response = this.denormalizeNodes(\n [{ $id: NODE_ROOT_ID, componentId: 'div', nodes: [] }],\n NODE_ROOT_ID,\n response,\n )\n }\n } else if (isArray) {\n response = this.denormalizeNodes(\n [{ $id: NODE_ROOT_ID, componentId: 'div', nodes: [...value] }],\n NODE_ROOT_ID,\n response,\n )\n } else if (\n _isObj(value) &&\n Array.isArray(value?.nodes) &&\n typeof value.nodes[0] !== 'string'\n ) {\n const _value = { ...(value as NodeSchemaNested<any>) }\n response = this.denormalizeNodes(\n [_value],\n _value?.parentId || NODE_ROOT_ID,\n response,\n )\n } else {\n response = value as unknown as NodesMap\n }\n\n return response\n }\n}\n\nexport default CanvasManager\n"],"names":["_isObj","_isStrT","arraySafe","cloneDeep","isEqual","action","computed","makeAutoObservable","makeObservable","observable","observableRef","runInAction","toJS","computedFn","schemaAcceptsChildren","REUSABLE_INSTANCE_COMPONENT_ID","stripUndefinedDeep","createIdUrlSafe","NodeType","NODE_ROOT_ID","NODE_ROOT_LABEL","AglynNode","parent","parentId","$id","store","getNode","index","getNodeIndex","children","res","nodes","node","push","labelShort","getNodeLabelShort","breadcrumbPath","getNodeBreadcrumbPath","componentSchema","componentId","aglyn","components","getSchema","hasNodes","Array","isArray","length","resolvedProps","resolveProps","props","asJSON","toJSON","delete","deleteNode","schema","json","type","name","undefined","pluginId","className","Object","keys","sx","sxEmpty","styleOverrides","attrOverrides","layoutStyleOverrides","interactions","hidden","NODE","HistoryManager","Symbol","toStringTag","toString","past","present","future","canUndo","canRedo","undo","epoch","Error","pop","redo","clearPast","clear","clearFuture","clearHistory","saveHistory","map","array","deep","CanvasManager","_history","serializedNodes","serializeNodes","isInitialSame","_initial","_initialConfirmed","isDraftedSame","_drafted","didSetInitial","Boolean","isInitialConfirmed","rootNode","get","nestedNodes","root","makeNested","resolveInsertTarget","target","requested","nodeAcceptsChildren","NaN","getNodeParent","at","indexOf","forEach","id","restoreSnapshot","_epoch","_batchDepth","markRemoteNode","nodeId","previousJson","live","nowJson","JSON","stringify","_foreignAt","set","serializeNode","snapshot","fromEntries","entries","setNodes","withForeignNodes","sinceEpoch","hasRemoteEdits","transact","mutate","coalesceKey","now","Date","burst","_coalescing","continues","key","COALESCE_WINDOW_MS","batch","completed","result","createNodeId","createNode","clearNodes","reset","updateInitialNodes","options","confirmed","confirmInitialNodes","updateDraftedNodes","setNode","create","isRootNode","_node","includes","isNaN","splice","schemas","merge","cloned","replace","applyNodes","value","parsed","processNodesToDenormalized","validateNode","del","childId","child","reparentNode","newParent","oldParent","oldIndex","sameParent","some","settled","Math","min","max","reorderNode","duplicateNode","duplicateNodeAndChildren","newNode","nodeIndex","createDuplicateNode","childDuplicate","addNodeFromNested","nested","duplicate","addNodeFromPreset","preset","data","updateNodeFields","patch","assign","updateNodeProps","nestDenormalizedNodes","rootId","response","nestedChild","denormalizeNodes","accumulator","childNode","nodesArray","filter","i","item","_value","Map","hasNode","has","nodesAreEqual","left","right","_right","isRootNodeId","nodeOrId","hierarchy","seen","Set","currentId","add","instanceName","componentLabel","getLabel","childNodes"],"mappings":"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"}
|