@bloklabs/angular 1.4.3 → 1.4.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bloklabs-angular.mjs","sources":["../../../../dist/.angular-build/angular/provide-blok.ts","../../../../dist/.angular-build/angular/block-context.ts","../../../../dist/.angular-build/angular/block-portal-registry.ts","../../../../dist/.angular-build/angular/registry-map.ts","../../../../dist/.angular-build/angular/blok-content.directive.ts","../../../../dist/.angular-build/components/errors/tool-not-found.ts","../../../../dist/.angular-build/components/utils/id-generator.ts","../../../../dist/.angular-build/shared/flatten-tree.ts","../../../../dist/.angular-build/components/utils/blocks-tree.ts","../../../../dist/.angular-build/components/utils/blocks-api.ts","../../../../dist/.angular-build/components/utils/readonly-config.ts","../../../../dist/.angular-build/shared/deep-equal.ts","../../../../dist/.angular-build/shared/output-data.ts","../../../../dist/.angular-build/shared/prop-schema.ts","../../../../dist/.angular-build/components/constants/data-attributes.ts","../../../../dist/.angular-build/tools/nested-blocks.ts","../../../../dist/.angular-build/angular/blok-editor.component.ts","../../../../dist/.angular-build/angular/createAngularBlock.ts","../../../../dist/.angular-build/angular/useBlocks.ts","../../../../dist/.angular-build/angular/useBlokReady.ts","../../../../dist/.angular-build/bloklabs-angular.ts"],"sourcesContent":["import {\n InjectionToken,\n makeEnvironmentProviders,\n type EnvironmentProviders,\n} from '@angular/core';\nimport type { BlokAngularConfig } from './types';\n\n/**\n * DI token holding app-wide Blok defaults (shared tools registry, default theme,\n * i18n). Merged under per-instance inputs by `BlokEditorComponent`.\n */\nexport const BLOK_DEFAULT_CONFIG = new InjectionToken<Partial<BlokAngularConfig>>(\n 'BLOK_DEFAULT_CONFIG'\n);\n\n/**\n * Standalone provider registering app-wide Blok defaults.\n *\n * @example\n * ```ts\n * bootstrapApplication(AppComponent, {\n * providers: [provideBlok({ theme: 'dark', tools: sharedTools })],\n * });\n * ```\n */\nexport function provideBlok(defaults: Partial<BlokAngularConfig>): EnvironmentProviders {\n return makeEnvironmentProviders([{ provide: BLOK_DEFAULT_CONFIG, useValue: defaults }]);\n}\n","import type { BlockAPI } from '@bloklabs/core';\n// packages/angular/src/block-context.ts\nimport { InjectionToken, type Signal } from '@angular/core';\n\n\n/**\n * Context handed to a `createAngularBlock` component. Delivered via DI (the\n * BLOK_BLOCK_CONTEXT token) rather than @Input, because core constructs the tool\n * outside Angular and the signal-input() form does not compile under the repo's\n * JIT test harness. The ONLY data write path is `commit`.\n */\nexport interface AngularBlockRenderContext<Data> {\n /** Reactive, FROZEN snapshot of the block data. Read `data()`; never mutate. */\n data: Signal<Readonly<Data>>;\n /** The ONLY data write path: merge a partial patch and sync once. */\n commit: (patch: Partial<Data>) => void;\n /** This block's per-block API (id, getChildren, dispatchChange…). */\n block: BlockAPI;\n /**\n * Reactive read-only flag. Read `readOnly()` in the template to disable\n * editing (drop `contenteditable`, hide controls). Toggled IN PLACE by core's\n * read-only switch — the component reacts without a remount, so ephemeral\n * state survives. A block that ignores it stays interactive when the editor is\n * read-only (same contract as a vanilla tool's `setReadOnly`).\n */\n readOnly: Signal<boolean>;\n /**\n * Container blocks only: append this block's real child holders into `host`\n * (a `data-blok-nested` element the author owns). Call it once in\n * `ngAfterViewInit`; the factory re-runs the same mount on every data change\n * so late-added children appear. Angular must NOT manage these child holders.\n */\n mountChildren: (host: HTMLElement) => void;\n}\n\n/** DI token carrying the per-block render context into the authored component. */\nexport const BLOK_BLOCK_CONTEXT = new InjectionToken<AngularBlockRenderContext<unknown>>(\n 'BLOK_BLOCK_CONTEXT'\n);\n","// packages/angular/src/block-portal-registry.ts\nimport {\n ApplicationRef,\n createComponent,\n EnvironmentInjector,\n ErrorHandler,\n Injector,\n type ComponentRef,\n type Type,\n} from '@angular/core';\n\nimport { BLOK_BLOCK_CONTEXT, type AngularBlockRenderContext } from './block-context';\n\n/**\n * Tool-config key carrying the editor's portal registry into a\n * `createAngularBlock` tool. The tool is constructed by CORE (outside any Angular\n * injection context), so it cannot `inject()` — the directive injects the\n * editor-scoped registry through each Angular-block tool's `config`, and the tool\n * reads it back from there.\n */\nexport const BLOK_PORTAL_REGISTRY_CONFIG_KEY = '__blokAngularPortalRegistry';\n\n/** One mounted Angular block: the Blok-owned host the component renders into. */\nexport interface BlockPortalEntry {\n hostEl: HTMLElement;\n component: Type<unknown>;\n context: AngularBlockRenderContext<unknown>;\n}\n\n/**\n * Per-editor registry of Angular blocks. Mounts each authored component directly\n * into its core-owned host via `createComponent({ hostElement })` (the Teleport\n * analog) and enrolls it in `ApplicationRef` for change detection. A plain Map —\n * Angular has no reactive-proxy hazard, so no `markRaw` equivalent is needed.\n */\nexport interface BlockPortalRegistry {\n /** Mount (or replace) the component for `id` into `entry.hostEl`. */\n register(id: string, entry: BlockPortalEntry): void;\n /** Detach + destroy the component for `id`. Safe (no-op) when absent. */\n unregister(id: string): void;\n /** Re-run change detection on the block's component (in-place update). */\n flush(id: string): void;\n /** Detach + destroy every mounted block (editor teardown / recreate). */\n destroyAll(): void;\n}\n\n/**\n * Create a fresh portal registry bound to a live Angular environment. One per\n * editor instance (associated via the registry map). The injectors/appRef are\n * passed in (captured by the directive in an injection context) because the\n * registry itself is built outside one.\n */\nexport const createBlockPortalRegistry = (\n envInjector: EnvironmentInjector,\n appRef: ApplicationRef,\n errorHandler: ErrorHandler\n): BlockPortalRegistry => {\n const mounted = new Map<string, { ref: ComponentRef<unknown>; injector: Injector }>();\n\n // Change detection runs outside NgZone here; a throwing author component must\n // degrade to a blank holder, not break core's block insertion.\n const safe = (fn: () => void): void => {\n try {\n fn();\n } catch (error) {\n errorHandler.handleError(error);\n }\n };\n\n const teardown = (id: string): void => {\n const entry = mounted.get(id);\n\n if (entry === undefined) {\n return;\n }\n\n const { ref, injector } = entry;\n // Capture host before deletion so we can clear it below.\n const hostEl = ref.location.nativeElement as HTMLElement;\n mounted.delete(id);\n appRef.detachView(ref.hostView);\n ref.destroy();\n // `Injector.create({ parent })` returns an injector that is NOT torn down by\n // `ref.destroy()`. We must destroy it explicitly to prevent one small injector\n // accumulating per block over a long editor session.\n const destroyable = injector as Injector & { destroy?: () => void };\n destroyable.destroy?.();\n // createComponent({ hostElement }) renders INTO an external div. Angular's\n // destroy() tears down the component instance and CD but does NOT clear the\n // host's DOM children — we must do it explicitly.\n hostEl.replaceChildren();\n };\n\n return {\n register(id: string, entry: BlockPortalEntry): void {\n // Idempotent: replace any prior mount for this id.\n teardown(id);\n\n // The context is provided through an ELEMENT injector (a node injector),\n // so it is destroyed automatically with the component view — no leaked\n // EnvironmentInjector. The shared app envInjector is the parent, so author\n // blocks still see app-level providers (HttpClient, etc.).\n const elementInjector = Injector.create({\n providers: [{ provide: BLOK_BLOCK_CONTEXT, useValue: entry.context }],\n parent: envInjector,\n });\n\n safe(() => {\n const ref = createComponent(entry.component, {\n environmentInjector: envInjector,\n elementInjector,\n hostElement: entry.hostEl,\n });\n\n appRef.attachView(ref.hostView);\n mounted.set(id, { ref, injector: elementInjector });\n // createComponent does not auto-run CD; render synchronously into the\n // (still-detached) host before core inserts it into the document.\n ref.changeDetectorRef.detectChanges();\n });\n },\n unregister(id: string): void {\n teardown(id);\n },\n flush(id: string): void {\n const entry = mounted.get(id);\n\n if (entry === undefined) {\n return;\n }\n\n safe(() => entry.ref.changeDetectorRef.detectChanges());\n },\n destroyAll(): void {\n for (const id of Array.from(mounted.keys())) {\n teardown(id);\n }\n },\n };\n};\n","// packages/angular/src/registry-map.ts\nimport type { BlockPortalRegistry } from './block-portal-registry';\n\n/**\n * Associates each live Blok instance with its portal registry. `BlokContentDirective`\n * sets it at creation so consumers (and future composables) can reach an editor's\n * registry. WeakMap → no leak when the editor is destroyed.\n */\nconst registries = new WeakMap<WeakKey, BlockPortalRegistry>();\n\nexport function setRegistry(editor: WeakKey, registry: BlockPortalRegistry): void {\n registries.set(editor, registry);\n}\n\nexport function getRegistry(editor: WeakKey): BlockPortalRegistry | undefined {\n return registries.get(editor);\n}\n\nexport function removeRegistry(editor: WeakKey): void {\n registries.delete(editor);\n}\n","import {\n Directive,\n ElementRef,\n EventEmitter,\n NgZone,\n Output,\n PLATFORM_ID,\n Input,\n ApplicationRef,\n EnvironmentInjector,\n ErrorHandler,\n afterNextRender,\n inject,\n signal,\n type OnDestroy,\n} from '@angular/core';\nimport { isPlatformBrowser } from '@angular/common';\n// Imported via the package's public specifier so ng-packagr externalizes the\n// core as a peer dependency (consumers share a single Blok instance + CSS).\nimport { Blok as BlokRuntime, type Blok } from '@bloklabs/core';\nimport { BLOK_DEFAULT_CONFIG } from './provide-blok';\nimport type { BlokAngularConfig } from './types';\nimport {\n BLOK_PORTAL_REGISTRY_CONFIG_KEY,\n createBlockPortalRegistry,\n type BlockPortalRegistry,\n} from './block-portal-registry';\nimport { removeRegistry, setRegistry } from './registry-map';\n\n/**\n * Escape-hatch directive and lifecycle engine for Blok (mirrors React's\n * `useBlok` + `BlokContent`). Constructs a Blok instance into its own host\n * element and tears it down on destroy.\n *\n * The editor renders directly into the directive's host element — so the host\n * IS the holder. This sidesteps the fact that Blok core exposes no public\n * `holder` accessor: the adapter never has to read it back, it owns it.\n *\n * `BlokEditorComponent` applies this directive to its internal `<div>` and reads\n * the instance back; consumers can also use it directly for full control:\n * `<div blokContent [config]=\"cfg\" (ready)=\"onReady($event)\"></div>`.\n *\n * Implementation note: classic `@Input()`/`@Output()` are used (not signal\n * `input()`/`output()`) because the repo's Vitest+Analog harness compiles the\n * adapter via JIT, which does not register signal-based members. `instance`\n * remains a plain `signal` (runtime API, JIT-safe) for reactive consumption.\n */\n@Directive({\n selector: '[blokContent]',\n standalone: true,\n})\nexport class BlokContentDirective implements OnDestroy {\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly ngZone = inject(NgZone);\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n /**\n * App-wide defaults from `provideBlok()`, merged UNDER the bound `[config]` so\n * the escape-hatch path honors them just like `<blok-editor>` (which also\n * merges, idempotently). Mirrors React's `useBlok` merging context defaults.\n */\n private readonly defaults = inject(BLOK_DEFAULT_CONFIG, { optional: true }) ?? {};\n // Captured in the injection context (field initializers) so the registry can\n // mount author components via createComponent — core constructs tools outside\n // Angular DI and cannot inject these itself.\n private readonly envInjector = inject(EnvironmentInjector);\n private readonly appRef = inject(ApplicationRef);\n private readonly errorHandler = inject(ErrorHandler);\n\n /** Construction-time Blok config (everything except `holder`, which the directive owns). */\n @Input() config: Partial<BlokAngularConfig> = {};\n\n /** Changing this input's identity (after the first build) destroys + recreates the editor. */\n @Input() set recreateKey(value: unknown) {\n const changed = this.built && value !== this.currentKey;\n this.currentKey = value;\n\n if (changed) {\n this.current?.destroy();\n this.build();\n }\n }\n\n /** Emits the live Blok instance once it is ready, after `instance` is populated. */\n @Output() readonly ready = new EventEmitter<Blok>();\n\n /** The live Blok instance, or null before `isReady` resolves / after destroy. */\n readonly instance = signal<Blok | null>(null);\n\n /** The editor created by the most recent construction; used as the staleness key. */\n private current: Blok | null = null;\n private destroyed = false;\n private built = false;\n private currentKey: unknown;\n /** The portal registry for the current editor (Angular-block mounting). */\n private registry: BlockPortalRegistry | undefined;\n\n constructor() {\n // afterNextRender is browser-only (skipped during SSR) and runs after the\n // host element exists and inputs are bound.\n afterNextRender(() => {\n // afterNextRender is browser-only by contract, but guard explicitly so the\n // editor is never constructed during SSR / on a non-browser platform.\n if (this.destroyed || !this.isBrowser) {\n return;\n }\n\n this.build();\n this.built = true;\n });\n }\n\n /** Construct a Blok into the host element and publish it once ready. */\n private build(): void {\n this.destroyed = false;\n this.instance.set(null);\n\n // Tear down any registry from a superseded editor (recreate path) before\n // building a new one.\n this.registry?.destroyAll();\n\n // Merge provideBlok defaults under the bound config (instance wins; tools\n // registries compose across both layers rather than replacing).\n const merged: Partial<BlokAngularConfig> = { ...this.defaults, ...this.config };\n\n if (this.defaults.tools !== undefined || this.config.tools !== undefined) {\n merged.tools = { ...this.defaults.tools, ...this.config.tools };\n }\n\n // Create the editor-scoped portal registry and thread it into every\n // Angular-block tool's config (vanilla tools pass through untouched).\n const registry = createBlockPortalRegistry(this.envInjector, this.appRef, this.errorHandler);\n\n this.registry = registry;\n merged.tools = injectPortalRegistry(merged.tools, registry);\n\n // Construct outside Angular's zone so the editor's internal DOM churn never\n // schedules change detection.\n const blok = this.ngZone.runOutsideAngular(\n () =>\n new BlokRuntime({\n ...merged,\n holder: this.host.nativeElement,\n }) as unknown as Blok\n );\n\n this.current = blok;\n setRegistry(blok, registry);\n\n void blok.isReady.then(() =>\n this.ngZone.run(() => {\n // Guard on the constructor-returned reference (not isReady's resolved\n // value): a superseded or torn-down editor must not publish itself.\n if (this.current !== blok || this.destroyed) {\n return;\n }\n\n this.instance.set(blok); // assign FIRST…\n this.ready.emit(blok); // …THEN emit, so consumers see a populated instance.\n })\n );\n }\n\n ngOnDestroy(): void {\n this.destroyed = true;\n this.registry?.destroyAll();\n\n if (this.current !== null) {\n removeRegistry(this.current);\n }\n\n this.current?.destroy();\n this.current = null;\n this.registry = undefined;\n this.instance.set(null);\n }\n}\n\n/**\n * Return a NEW tools map (never mutate the consumer's config) where each\n * Angular-block tool carries the portal registry under\n * BLOK_PORTAL_REGISTRY_CONFIG_KEY in its `config`. Vanilla tools are returned\n * unchanged. Handles both entry shapes: a bare constructor and `{ class, config }`.\n */\nfunction injectPortalRegistry(\n tools: BlokAngularConfig['tools'],\n registry: BlockPortalRegistry\n): BlokAngularConfig['tools'] {\n if (tools === undefined) {\n return tools;\n }\n\n const result: Record<string, unknown> = {};\n\n for (const [name, entry] of Object.entries(tools)) {\n const asObject = entry as { class?: unknown; config?: Record<string, unknown> } | undefined;\n const toolClass = (typeof entry === 'function' ? entry : asObject?.class) as\n | { __isBlokAngularBlock?: boolean }\n | undefined;\n\n if (toolClass?.__isBlokAngularBlock === true) {\n const base = typeof entry === 'function' ? { class: entry } : { ...asObject };\n\n result[name] = {\n ...base,\n config: { ...(base.config ?? {}), [BLOK_PORTAL_REGISTRY_CONFIG_KEY]: registry },\n };\n } else {\n result[name] = entry;\n }\n }\n\n return result as BlokAngularConfig['tools'];\n}\n","/**\n * Thrown when a block tool cannot be resolved during a creation/conversion\n * operation (insert, insertMany/composeBlock, composeBlockData, convert).\n *\n * A typed error lets adapters (React/Vue/Angular useBlocks) distinguish a\n * genuinely-unknown tool — an EXPECTED, recoverable outcome they surface as a\n * `null`/`[]` no-op — from a real bug, WITHOUT brittle `message.includes('not\n * found')` substring matching (which both mis-catches unrelated errors whose\n * message happens to contain \"not found\" and breaks under message localization).\n */\nexport class ToolNotFoundError extends Error {\n /**\n * @param toolName - the tool type that could not be resolved\n * @param message - optional override; defaults to a descriptive message\n */\n constructor(public readonly toolName: string, message?: string) {\n super(message ?? `Block Tool «${toolName}» not found.`);\n this.name = 'ToolNotFoundError';\n }\n}\n","/**\n * ID generation utilities\n */\n\n// nanoid replaced with inline crypto implementation for the Angular adapter bundle.\nconst _ID_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-';\nconst _nanoid = (n: number): string => {\n const buf = crypto.getRandomValues(new Uint8Array(n));\n return Array.from(buf, (b) => _ID_CHARS[b % 64]).join('');\n};\nconst nanoid = _nanoid;\n\n/**\n * Constants for ID generation\n */\nconst ID_RANDOM_MULTIPLIER = 100_000_000; // 1e8\nconst HEXADECIMAL_RADIX = 16;\n\n/**\n * Create a block id\n * @returns unique block ID\n */\nexport const generateBlockId = (): string => {\n const idLen = 10;\n\n return nanoid(idLen);\n};\n\n/**\n * Nanoid-compatible block ID pattern: exactly 10 URL-safe characters (A-Z, a-z, 0-9, _, -)\n */\nconst BLOCK_ID_PATTERN = /^[A-Za-z0-9_-]{10}$/;\n\n/**\n * Returns true if the given string is a valid block ID (nanoid format).\n * @param id - string to check\n */\nexport const isValidBlockId = (id: string): boolean => BLOCK_ID_PATTERN.test(id);\n\n/**\n * Returns random generated identifier\n * @param prefix - identifier prefix\n * @returns unique identifier with prefix\n */\nexport const generateId = (prefix = ''): string => {\n return `${prefix}${(Math.floor(Math.random() * ID_RANDOM_MULTIPLIER)).toString(HEXADECIMAL_RADIX)}`;\n};\n","import type { OutputBlockData, BlockId, BlockTreeSpec, FlattenTreeOptions } from '@bloklabs/core';\nimport { generateBlockId } from '../components/utils/id-generator';\n\n/** A flattened block with its `id` resolved (generated when the spec omitted one). */\ntype FlattenedBlock = OutputBlockData & { id: BlockId };\n\n/**\n * Flatten a hierarchical block spec (nodes with `children`) into the flat DFS\n * pre-order `OutputBlockData[]` Blok stores, wiring every node's `parent` and\n * `content` id links.\n *\n * This is the pure counterpart of the live `insertTree` mutation: the same DFS,\n * without an editor. Use it to seed nested content — columns, tables, a whole\n * document — without hand-authoring `parent`/`content` arrays:\n *\n * @example\n * new Blok({\n * data: {\n * blocks: flattenTree([\n * { type: 'column_list', children: [\n * { type: 'column', children: [{ type: 'paragraph', data: { text: 'L' } }] },\n * { type: 'column', children: [{ type: 'paragraph', data: { text: 'R' } }] },\n * ] },\n * ]),\n * },\n * });\n *\n * @param spec - a single root node or an array of root nodes.\n * @param options - `parentId` sets the `parent` of the root node(s);\n * `generateId` overrides id generation for nodes that omit an `id` (default:\n * Blok's nanoid scheme).\n * @returns DFS pre-order blocks with `parent`/`content` wired. Leaves omit the\n * empty `content` array, matching the documented `OutputBlockData` shape.\n * @throws if an explicit `id` is reused within the spec — a duplicate id would\n * corrupt every id-keyed lookup, so it is surfaced loudly rather than encoded.\n */\nexport function flattenTree(\n spec: BlockTreeSpec | BlockTreeSpec[],\n options: FlattenTreeOptions = {}\n): FlattenedBlock[] {\n const generateId = options.generateId ?? generateBlockId;\n const rootParent = options.parentId ?? undefined;\n\n const flat: FlattenedBlock[] = [];\n const usedIds = new Set<string>();\n\n // Pre-order DFS: push self FIRST, then recurse each child, so the flat array\n // is DFS-contiguous. `content` is filled as each child is visited and returns\n // its id; it is omitted for leaves.\n const visit = (node: BlockTreeSpec, parent: string | undefined): string => {\n const id = node.id ?? generateId();\n\n if (usedIds.has(id)) {\n throw new Error(`flattenTree: duplicate block id \"${id}\" — every block id must be unique.`);\n }\n usedIds.add(id);\n\n const childIds: string[] = [];\n const flatNode = {\n id,\n // `type` is OMITTED (not present-with-undefined) when absent so core's\n // `type || defaultBlock` fallback resolves the default block cleanly.\n ...(node.type !== undefined ? { type: node.type } : {}),\n data: node.data ?? {},\n ...(node.tunes !== undefined ? { tunes: node.tunes } : {}),\n ...(parent !== undefined ? { parent } : {}),\n } as FlattenedBlock;\n\n flat.push(flatNode);\n\n for (const child of node.children ?? []) {\n childIds.push(visit(child, id));\n }\n\n // Only wire `content` when there are children — leaves stay clean.\n if (childIds.length > 0) {\n flatNode.content = childIds;\n }\n\n return id;\n };\n\n const roots = Array.isArray(spec) ? spec : [spec];\n\n for (const root of roots) {\n visit(root, rootParent);\n }\n\n return flat;\n}\n","import type { BlockToolData, BlockTuneData, OutputBlockData, OutputData, MarkdownImportConfig } from '@bloklabs/core';\n\n/**\n * Where to place the caret within a block. `position` selects the input\n * (`'start'`/`'end'`/`'default'`) and `offset` is the character offset within it\n * — the same shape core's `caret.setToBlock` accepts.\n */\nexport interface CaretTarget {\n position?: 'start' | 'end' | 'default';\n offset?: number;\n}\n\n/**\n * A plain, serializable view of one block in the tree.\n *\n * Snapshot-volatile: every read allocates a fresh `BlockNode`, and `contentIds`\n * is DERIVED per read from the children that currently name this block as parent\n * (it is not a stored field). Read a node in render and re-read after a change —\n * don't stash one in a `useMemo`/`useEffect` dependency array expecting stable\n * identity; depend on the `id` instead.\n */\nexport interface BlockNode {\n id: string;\n type: string;\n parentId: string | null;\n contentIds: readonly string[];\n}\n\n/** Where to place a block among its siblings. */\nexport type InsertPosition = 'start' | 'end' | { before: string } | { after: string };\n\nexport interface InsertSpec {\n type?: string;\n data?: BlockToolData;\n parentId?: string | null;\n position?: InsertPosition;\n /**\n * Move the caret into the new block. Defaults to `false`: a programmatic\n * insert from React must not steal focus from wherever the user is typing.\n * Set `true` for an explicit \"add a block and start editing it\" flow.\n */\n focus?: boolean;\n /**\n * Replace the block at the resolved slot instead of inserting a new one — a\n * programmatic \"turn into\". Combine with a `position` that targets the block\n * to replace, e.g. `{ position: { before: id }, replace: true }`.\n */\n replace?: boolean;\n /**\n * Explicit id for the new block (generated when omitted). Passing a stable id\n * makes the insert idempotent: if a block with this id already exists the\n * existing node is returned and nothing is inserted (\"insert if absent\"),\n * so an effect that re-runs won't create duplicates.\n */\n id?: string;\n /** Block tune data to apply at creation, keyed by tune name. */\n tunes?: { [name: string]: BlockTuneData };\n /**\n * Place the caret inside the newly-created block at a specific position/offset\n * (e.g. `{ offset: 3 }`). Implies focus. Applied ONLY when a block is actually\n * created — an insert-if-absent hit (existing id) does not move the caret.\n * Use this instead of the boolean `focus` when you need a specific offset.\n */\n caret?: CaretTarget;\n}\n\n/**\n * One node of a pre-built nested subtree for {@link UseBlocksApi.insertTree}.\n *\n * Each node maps to one block; `children` are inserted nested under it (their\n * `parentId` set to this node's id) in array order, recursively. Placement\n * options (`parentId`/`position`) are ROOT-ONLY — they position the whole\n * subtree among existing blocks and are ignored on nested children, whose parent\n * is always their enclosing node.\n */\nexport interface TreeInsertSpec {\n type?: string;\n data?: BlockToolData;\n tunes?: { [name: string]: BlockTuneData };\n /**\n * Explicit id for this node (generated when omitted). Unlike `insert`, this is\n * NOT insert-if-absent: a tree insert always creates fresh blocks. A colliding\n * id — one that already exists in the document, or is reused by another node\n * in the same spec — is REJECTED up front: nothing is inserted and `insertTree`\n * returns `null` (a duplicate id would corrupt every id-keyed lookup).\n */\n id?: string;\n /** Direct children, inserted nested under this node, in array order. */\n children?: TreeInsertSpec[];\n /** Root-only: where to place the whole subtree. Ignored on nested children. */\n parentId?: string | null;\n /** Root-only: slot among siblings of `parentId`. Ignored on nested children. */\n position?: InsertPosition;\n}\n\n/**\n * Where to move an existing block.\n *\n * `before`/`after` are POSITION targets, not parent assignments: the block is\n * relocated to that flat slot and — because Blok keeps the flat array as the\n * canonical document order — ADOPTS the parent of wherever it lands. Moving a\n * nested block to `{ after: someRootBlock }` therefore unnests it to root, and\n * moving a root block in among a container's children nests it. Use\n * `nest`/`unnest` when you want to change the parent without choosing a sibling\n * slot. `toIndex` is an absolute flat index (clamped into range).\n */\nexport type MoveTarget = { before: string } | { after: string } | { toIndex: number };\n\nexport interface UseBlocksApi {\n getById(id: string): BlockNode | null;\n getChildren(parentId: string | null): BlockNode[];\n /**\n * Insert one block; returns the created node or null when rejected (unknown\n * tool type, dangling `parentId`, or a `replace` whose target is missing). An\n * explicit `id` that already exists is insert-if-absent (returns the existing\n * node, creates nothing). Atomic — one undo step. The returned node is\n * {@link BlockNode}-volatile; read it now, don't put it in a dep array.\n */\n insert(spec?: InsertSpec): BlockNode | null;\n /**\n * Insert several blocks atomically, in array order, as ONE undo step. Each\n * spec is a full {@link InsertSpec} (own type/data/parentId/position), routed\n * through the same single-`insert` path, so per-spec parent assertion and\n * positioning still apply. Specs that fail to insert (e.g. a dangling\n * parentId, or a replace whose target is missing) are dropped; the returned\n * array holds only the successfully created nodes. An empty input is a no-op\n * (returns `[]`, opens no transaction). Like `insert`, the returned nodes are\n * fresh-snapshot volatile — read them now, don't stash them in dep arrays.\n */\n insertMany(specs: InsertSpec[]): BlockNode[];\n /**\n * Insert a pre-built NESTED subtree in ONE atomic operation (one undo step).\n * Each {@link TreeInsertSpec} node becomes a block; its `children` are inserted\n * nested under it (recursively, in array order) so the whole hierarchy lands in\n * a single call — no follow-up `nest` round-trips. Delegates to core's\n * tree-aware `blocks.insertMany`, which composes the flat DFS pre-order array\n * honoring each node's `parent`/`content` links.\n *\n * Placement is root-only: the root node's `parentId`/`position` position the\n * whole subtree among existing blocks (default: appended at the document end);\n * nested children ignore those fields (their parent is their enclosing node). A\n * dangling root `parentId` is rejected — nothing is inserted and `null` is\n * returned (mirrors {@link insert}). Returns the root {@link BlockNode}, which\n * is fresh-snapshot volatile — read it now, don't stash it in a dep array.\n */\n insertTree(spec: TreeInsertSpec): BlockNode | null;\n /**\n * Convert a Markdown string to blocks and insert them ADDITIVELY at a\n * position, WITHOUT clearing the document (unlike core's `importMarkdown` /\n * `renderFromHTML`, which replace the whole document). This is the React\n * \"paste markdown → blocks appear\" path.\n *\n * Async: the markdown converter is lazy-loaded (kept out of the main bundle),\n * so this is the ONE async creator in the API — `await` the returned promise.\n * The whole batch is inserted as a single atomic undo step.\n *\n * `position` (default `'end'`) places the converted run among `parentId`'s\n * children (or root siblings when `parentId` is omitted/null), reusing the\n * same `start`/`end`/`before`/`after` semantics as {@link insert}.\n *\n * `parentId` (default `null` = root) nests the import: every TOP-LEVEL\n * converted block (one the converter left un-parented) is reparented under\n * `parentId`, while blocks the markdown nested internally (e.g. table-cell\n * children) keep their intra-import parent. A dangling `parentId` is a no-op\n * (returns `[]`, opens no transaction), matching {@link insert}.\n *\n * `config` (optional {@link MarkdownImportConfig}) is forwarded to the\n * converter so custom-tool consumers can map markdown nodes into their tools\n * (`toolMap`/`onUnknownNode`), toggle GFM, or add micromark/mdast extensions.\n *\n * Returns ALL created {@link BlockNode}s in document order — including any the\n * markdown nested internally (e.g. a table's cell children), not just the\n * top-level run (this differs from {@link insertTree}, which returns only the\n * root). Empty or whitespace-only markdown, a dangling `parentId` (checked\n * again after the async convert, so a parent removed mid-flight also no-ops),\n * and a converter failure (chunk-load or parse error, swallowed) all return\n * `[]` and open no transaction. The nodes are fresh-snapshot volatile — read\n * them now, don't stash them in dep arrays.\n */\n insertMarkdown(\n markdown: string,\n options?: { parentId?: string | null; position?: InsertPosition; config?: MarkdownImportConfig }\n ): Promise<BlockNode[]>;\n /**\n * Serialize the WHOLE document to a Markdown string — the outbound twin of\n * core's `blocks.exportMarkdown` (and the read-side counterpart of the\n * additive {@link insertMarkdown}). Async: the serializer is lazy-loaded, like\n * the importer. Markdown cannot express every block, so some structure is\n * dropped (table `colspan`/`rowspan`, heading columns). Returns `''` for an\n * empty document. Pre-ready: resolves to `''`.\n */\n exportMarkdown(): Promise<string>;\n move(id: string, target: MoveTarget): void;\n nest(id: string, parentId: string): void;\n unnest(id: string): void;\n remove(id: string): void;\n /**\n * Update a block's data and/or tunes by id. Delegates to core's async\n * `blocks.update`, which forms its OWN undo step — the call is NOT wrapped in\n * `transact` (that would close the group before the async write lands). An\n * unknown id is a silent no-op; a rejected update is swallowed so it can't\n * surface as an unhandled rejection. Reads refresh reactively once core emits\n * 'block changed'. Returns `void`.\n */\n update(id: string, data?: BlockToolData, tunes?: { [name: string]: BlockTuneData }): void;\n /**\n * Convert a block to another type (\"turn into\") by id. Delegates to core's\n * async `blocks.convert`; both tools must provide a `conversionConfig` or core\n * rejects — that rejection (and any other) is swallowed so a non-convertible\n * block is a graceful no-op rather than an unhandled rejection. An unknown id\n * is a silent no-op. Not wrapped in `transact` (core owns its history step).\n * Returns `void`.\n */\n convert(\n id: string,\n newType: string,\n dataOverrides?: BlockToolData,\n options?: { caret?: CaretTarget }\n ): void;\n transact(fn: () => void): void;\n /**\n * Run `fn` as one atomic operation that is NOT captured in the undo history —\n * the React-surface counterpart of core's `transactWithoutCapture`. Use for\n * silent auto-repair/normalization that a user's CMD+Z should never step\n * through. Mutations inside still emit reactively. Pre-ready it just runs `fn`.\n */\n transactWithoutCapture(fn: () => void): void;\n /**\n * The current block count. Reactive (re-reads on 'block changed'). Pre-ready: 0.\n */\n getBlocksCount(): number;\n /**\n * The flat index of the block holding the caret, or -1 when none. Pre-ready: -1.\n */\n getCurrentBlockIndex(): number;\n /** The block at a flat index as a snapshot {@link BlockNode}, or null. */\n getBlockByIndex(index: number): BlockNode | null;\n /**\n * The absolute flat index of a block by id, or null when unknown. The\n * counterpart to {@link getBlockByIndex} — use it to target an off-caret\n * {@link splitBlock} (whose `insertIndex` is absolute) without the ref. Unknown\n * ids return null silently (no console warn). Pre-ready: null.\n */\n getBlockIndex(id: string): number | null;\n /**\n * Read a block's current `data` and `tunes` by id WITHOUT mutating anything —\n * the synchronous last-extracted view (the same snapshot clipboard ops use).\n * Makes a client-side duplicate composable from the hook alone: read a node,\n * then `insert({ type, data, tunes, position })`, no ref escape hatch. Unknown\n * id returns null. Pre-ready: null.\n */\n getBlockData(id: string): { data: BlockToolData; tunes: { [name: string]: BlockTuneData } } | null;\n /**\n * The block whose holder contains/equals `element`, as a snapshot\n * {@link BlockNode}, or null. Useful for mapping a DOM event target back to a\n * block.\n */\n getBlockByElement(element: HTMLElement): BlockNode | null;\n /**\n * Read a tool's default empty data WITHOUT inserting anything — delegates to\n * core's `composeBlockData`. Async (a tool's data may be composed lazily).\n * Rejects (via core) for an unknown tool. Pre-ready: resolves to `{}`.\n */\n composeBlockData(toolName: string): Promise<BlockToolData>;\n /**\n * Replace the WHOLE document with blocks parsed from an HTML string —\n * delegates to core's `renderFromHTML`. Unlike {@link insertMarkdown} (which is\n * additive), this CLEARS existing content first, so it's a document-load\n * primitive, not an insert. Async. Pre-ready: resolves immediately (no-op).\n */\n renderFromHTML(html: string): Promise<void>;\n /**\n * Insert a flat array of already-serialized {@link OutputBlockData} (the\n * `save()` shape) directly, honoring each block's `parent`/`content` links —\n * the raw counterpart of core's `blocks.insertMany`. Use to re-insert a saved\n * document fragment without reshaping it into {@link TreeInsertSpec}. One\n * atomic undo step. Returns the created nodes; pre-ready: `[]` (no insert).\n */\n insertOutputData(blocks: OutputBlockData[], options?: { index?: number }): BlockNode[];\n /**\n * Atomically split a block: update `currentBlockId` with `currentBlockData`\n * and insert a new `newBlockType` block at `insertIndex`, as ONE undo step.\n * Delegates to core's `splitBlock`. Returns the new node, or null pre-ready /\n * on an unknown id.\n */\n splitBlock(\n currentBlockId: string,\n currentBlockData: Partial<BlockToolData>,\n newBlockType: string,\n newBlockData: BlockToolData,\n insertIndex: number\n ): BlockNode | null;\n /**\n * Insert a single child block under `parentId` at flat `insertIndex`, atomically\n * (block creation AND parent assignment in ONE undo step) — delegates to core's\n * `blocks.insertInsideParent`. This is the atomic nested-child creator: prefer it\n * over `insert()` + `nest()`, which is TWO undo steps. A dangling `parentId` is a\n * no-op returning `null` (mirrors {@link insert}); an unknown child tool returns\n * `null`. `childData` defaults to an empty paragraph. Returns the created\n * {@link BlockNode}, fresh-snapshot volatile — read it now, don't stash it in a\n * dep array. Pre-ready: `null`.\n */\n insertInsideParent(parentId: string, insertIndex: number, childData?: BlockToolData): BlockNode | null;\n /**\n * Replace the WHOLE document with blocks parsed from saved {@link OutputData}\n * (the `save()` shape) — delegates to core's `blocks.render`. Unlike\n * {@link insertOutputData}/{@link insertMarkdown} (which are ADDITIVE), this\n * CLEARS existing content first: a document-LOAD primitive, not an insert. The\n * HTML counterpart is {@link renderFromHTML}. Async. Pre-ready: resolves\n * immediately (no-op).\n */\n render(data: OutputData): Promise<void>;\n /**\n * Remove EVERY block from the document — delegates to core's `blocks.clear`. A\n * document-reset primitive (pairs with {@link render}). Async. Pre-ready:\n * resolves immediately (no-op).\n */\n clear(): Promise<void>;\n /**\n * Whether a Yjs sync (undo/redo) is currently in progress — the React mirror of\n * core's `blocks.isSyncingFromYjs`. A METHOD (not a property) so it reads the\n * LIVE flag at call time even though the api handle is memoized. Use it to skip\n * cleanup that would fight Yjs state during an undo/redo. Pre-ready: `false`.\n */\n isSyncingFromYjs(): boolean;\n}\n\n/** The minimal slice of editor.blocks that the snapshot helpers read. */\nexport interface BlocksReader {\n getBlocksCount(): number;\n getBlockByIndex(index: number): { id: string; name: string; parentId: string | null } | undefined;\n}\n\n/**\n * Enumerate the editor's blocks once into BlockNode records, in flat order,\n * deriving each node's contentIds from the children that name it as parent.\n */\nexport const snapshotNodes = (reader: BlocksReader): BlockNode[] => {\n const count = reader.getBlocksCount();\n const flat = Array.from({ length: count }, (_, i) => reader.getBlockByIndex(i))\n .filter((b): b is { id: string; name: string; parentId: string | null } => b !== undefined)\n .map((b) => ({ id: b.id, type: b.name, parentId: b.parentId }));\n\n const childrenByParent = new Map<string, string[]>();\n\n for (const b of flat) {\n if (b.parentId === null) {\n continue;\n }\n const bucket = childrenByParent.get(b.parentId) ?? [];\n\n bucket.push(b.id);\n childrenByParent.set(b.parentId, bucket);\n }\n\n return flat.map((b) => ({\n id: b.id,\n type: b.type,\n parentId: b.parentId,\n contentIds: childrenByParent.get(b.id) ?? [],\n }));\n};\n\n/** BlocksReader plus id→flat-index lookup. */\nexport interface IndexReader extends BlocksReader {\n getBlockIndex(id: string): number | undefined;\n}\n\n/** Flat indices of a parent's direct children, ascending. Empty if none. */\nconst childFlatIndices = (reader: IndexReader, parentId: string): number[] => {\n const count = reader.getBlocksCount();\n\n return Array.from({ length: count }, (_, i) => i).filter(\n (i) => reader.getBlockByIndex(i)?.parentId === parentId\n );\n};\n\n/** Map of block id -> parentId, in flat order. */\nexport const parentMap = (reader: IndexReader): Map<string, string | null> => {\n const count = reader.getBlocksCount();\n const entries = Array.from({ length: count }, (_, i) => reader.getBlockByIndex(i))\n .filter((b): b is { id: string; name: string; parentId: string | null } => b !== undefined)\n .map((b): [string, string | null] => [b.id, b.parentId]);\n\n return new Map(entries);\n};\n\n/** True if `id` descends from `ancestorId` via the parentId chain. */\nexport const isDescendantOf = (\n parentOf: Map<string, string | null>,\n id: string,\n ancestorId: string\n): boolean => {\n const parent = parentOf.get(id) ?? null;\n\n if (parent === null) {\n return false;\n }\n\n return parent === ancestorId || isDescendantOf(parentOf, parent, ancestorId);\n};\n\n/**\n * The flat index of the last block in the contiguous subtree rooted at `index`.\n * In flat (DFS) order a block's descendants sit immediately after it, so this\n * walks forward while blocks remain descendants of the block at `index`.\n * Returns `index` itself when the block has no descendants.\n */\nconst subtreeEndIndex = (reader: IndexReader, index: number): number => {\n const root = reader.getBlockByIndex(index);\n\n if (root === undefined) {\n return index;\n }\n\n const parentOf = parentMap(reader);\n const count = reader.getBlocksCount();\n // Walk forward from index+1 while blocks remain descendants (DFS contiguity).\n // The subtree ends just before the first non-descendant, or at the last block\n // when every follower is a descendant.\n const followers = Array.from({ length: count - (index + 1) }, (_, k) => index + 1 + k);\n const breakAt = followers.find((i) => {\n const b = reader.getBlockByIndex(i);\n\n return b === undefined || !isDescendantOf(parentOf, b.id, root.id);\n });\n\n return breakAt === undefined ? count - 1 : breakAt - 1;\n};\n\n/**\n * The flat index at which a new block should be inserted.\n *\n * `replace` flips the meaning of a before/after `position`: under replace the\n * ref IS the block being overwritten (a \"turn into\"), not a sibling anchor, so\n * it resolves to the ref's OWN flat slot regardless of which parent it lives in\n * — bypassing the sibling-relative parent guard that would otherwise redirect a\n * nested target to the requested parent's end and replace the wrong block.\n */\nexport const resolveInsertIndex = (\n reader: IndexReader,\n parentId: string | null,\n position: InsertPosition,\n replace = false\n): number => {\n if (typeof position === 'object') {\n const ref = 'before' in position ? position.before : position.after;\n const refIndex = reader.getBlockIndex(ref);\n\n if (replace && refIndex !== undefined) {\n return refIndex;\n }\n\n const refParent =\n refIndex === undefined ? undefined : reader.getBlockByIndex(refIndex)?.parentId ?? null;\n\n // before/after is sibling-relative: the ref must be a child of the requested\n // parent. When the ref is missing or lives in a DIFFERENT parent, the\n // parentId constraint wins — fall back to appending at the end of the\n // requested parent rather than splicing into an unrelated subtree (the\n // cross-parent mis-place) or silently landing at the document end.\n if (refIndex === undefined || refParent !== parentId) {\n return resolveInsertIndex(reader, parentId, 'end');\n }\n\n // 'after' must clear the ref's entire subtree, not just the ref node, or the\n // new block splits the ref's descendants in flat (DFS) order.\n return 'before' in position ? refIndex : subtreeEndIndex(reader, refIndex) + 1;\n }\n\n if (parentId === null) {\n return position === 'start' ? 0 : reader.getBlocksCount();\n }\n\n const parentIndex = reader.getBlockIndex(parentId);\n\n if (parentIndex === undefined) {\n return reader.getBlocksCount();\n }\n\n if (position === 'start') {\n const childIndices = childFlatIndices(reader, parentId);\n\n return childIndices.length === 0 ? parentIndex + 1 : childIndices[0];\n }\n\n // 'end': insert after the parent's last descendant.\n return subtreeEndIndex(reader, parentIndex) + 1;\n};\n\n/** The flat toIndex for editor.blocks.move. */\nexport const resolveMoveIndex = (reader: IndexReader, target: MoveTarget): number => {\n if ('toIndex' in target) {\n // Blok's Blocks.move() silently no-ops on an out-of-range index, so clamp\n // an explicit toIndex into [0, count-1] rather than dropping the move.\n const lastIndex = Math.max(0, reader.getBlocksCount() - 1);\n\n return Math.min(Math.max(target.toIndex, 0), lastIndex);\n }\n\n const ref = 'before' in target ? target.before : target.after;\n const refIndex = reader.getBlockIndex(ref);\n\n if (refIndex === undefined) {\n return reader.getBlocksCount();\n }\n\n // 'after' must clear the ref's entire subtree (see resolveInsertIndex), or the\n // moved block lands among the ref's descendants instead of past them.\n return 'before' in target ? refIndex : subtreeEndIndex(reader, refIndex) + 1;\n};\n","import type { Blok, BlockToolData, BlockTuneData, OutputBlockData, OutputData, MarkdownImportConfig } from '@bloklabs/core';\n// src/components/utils/blocks-api.ts\nimport { ToolNotFoundError } from '../errors/tool-not-found';\n\nimport { flattenTree } from '../../shared/flatten-tree';\nimport {\n snapshotNodes,\n resolveInsertIndex,\n resolveMoveIndex,\n parentMap,\n isDescendantOf,\n type BlockNode,\n type CaretTarget,\n type IndexReader,\n type InsertPosition,\n type InsertSpec,\n type MoveTarget,\n type TreeInsertSpec,\n type UseBlocksApi,\n} from './blocks-tree';\n\n/** Adapt the live editor to the IndexReader the snapshot helpers expect. */\nexport const readerFor = (editor: Blok): IndexReader => {\n const blocks = editor.blocks;\n\n return {\n getBlocksCount: () => blocks.getBlocksCount(),\n getBlockByIndex: (i: number) => {\n const b = blocks.getBlockByIndex(i);\n\n return b === undefined ? undefined : { id: b.id, name: b.name, parentId: b.parentId };\n },\n getBlockIndex: (id: string) => blocks.getBlockIndex(id),\n };\n};\n\n/**\n * Stable API returned while the editor is null (before the adapter resolves).\n * Every read returns empty/null and every MUTATOR is a no-op — EXCEPT\n * `transact`/`transactWithoutCapture`, which still invoke their callback so a\n * consumer wrapping conditional work in `transact` still runs that work even\n * pre-ready.\n */\nexport const EMPTY_API: UseBlocksApi = {\n getById: () => null,\n getChildren: () => [],\n insert: () => null,\n insertMany: () => [],\n insertTree: () => null,\n insertMarkdown: async () => [],\n exportMarkdown: async () => '',\n move: () => undefined,\n nest: () => undefined,\n unnest: () => undefined,\n remove: () => undefined,\n update: () => undefined,\n convert: () => undefined,\n // Not a no-op: still runs the callback (see EMPTY_API doc above).\n transact: (fn: () => void) => fn(),\n // Like transact, still runs the callback even pre-ready.\n transactWithoutCapture: (fn: () => void) => fn(),\n getBlocksCount: () => 0,\n getCurrentBlockIndex: () => -1,\n getBlockByIndex: () => null,\n getBlockByElement: () => null,\n getBlockData: () => null,\n getBlockIndex: () => null,\n composeBlockData: async () => ({}),\n renderFromHTML: async () => undefined,\n insertOutputData: () => [],\n splitBlock: () => null,\n insertInsideParent: () => null,\n render: async () => undefined,\n clear: async () => undefined,\n isSyncingFromYjs: () => false,\n};\n\n/**\n * Build the framework-agnostic, id/parentId-relative block-tree API over a LIVE\n * editor. Mutators route through the editor-level `blocks` API (core's\n * chokepoints), so undo/redo and Yjs sync are inherited rather than\n * re-implemented; readers enumerate the live tree on every call.\n *\n * This is the shared engine behind both the React (`useSyncExternalStore`) and\n * Vue (`shallowRef` version) `useBlocks` wrappers — one implementation so the\n * two adapters cannot drift. Each adapter supplies the `onRead` seam:\n *\n * - React leaves it the default no-op: `useSyncExternalStore` re-renders the\n * whole component on `block changed`, and the reads run live during that\n * render, so no per-call dependency tracking is needed.\n * - Vue passes `() => { void version.value }` so a read inside a `computed` /\n * template touches the reactive version ref and re-runs on every structural\n * mutation.\n *\n * `onRead` is invoked at the top of every read method; mutators never call it.\n * The editor MUST be the raw (non-proxied) instance — adapters `toRaw`-unwrap\n * before calling, so a Vue reactive proxy never reaches core (Risk R0).\n *\n * @param editor - the live Blok instance (never null; callers gate on EMPTY_API)\n * @param onRead - reactivity seam called at the start of each read (default no-op)\n */\nexport const createBlocksApiForEditor = (\n editor: Blok,\n onRead: () => void = () => undefined\n): UseBlocksApi => {\n const reader = readerFor(editor);\n\n const getById = (id: string): BlockNode | null => {\n onRead();\n const nodes = snapshotNodes(reader);\n\n return nodes.find((n) => n.id === id) ?? null;\n };\n\n const getChildren = (parentId: string | null): BlockNode[] => {\n onRead();\n\n return snapshotNodes(reader).filter((n) => n.parentId === parentId);\n };\n\n const transact = (fn: () => void): void => {\n if (editor.blocks.transact !== undefined) {\n editor.blocks.transact(fn);\n } else {\n fn();\n }\n };\n\n /** Flat list of id + all transitive descendants, via the parentId graph. */\n const collectSubtreeIds = (rootId: string): string[] => {\n const nodes = snapshotNodes(reader);\n const childrenOf = new Map<string, string[]>();\n\n for (const n of nodes) {\n if (n.parentId === null) {\n continue;\n }\n const bucket = childrenOf.get(n.parentId) ?? [];\n\n bucket.push(n.id);\n childrenOf.set(n.parentId, bucket);\n }\n\n const out: string[] = [];\n const visited = new Set<string>();\n const stack: string[] = [rootId];\n\n // A parentId cycle (possible from a concurrent remote Yjs reparent) would\n // make this DFS spin forever — track visited ids and skip re-entry so each\n // block is emitted at most once and the traversal always terminates.\n while (stack.length > 0) {\n const id = stack.pop() as string;\n\n if (visited.has(id)) {\n continue;\n }\n visited.add(id);\n out.push(id);\n const kids = childrenOf.get(id);\n\n if (kids !== undefined) {\n stack.push(...kids);\n }\n }\n\n return out;\n };\n\n /** Each subtree member's parentId, captured from the current snapshot. */\n const captureSubtreeParents = (rootId: string): Array<{ id: string; parentId: string | null }> => {\n const parentOf = new Map(snapshotNodes(reader).map((n) => [n.id, n.parentId]));\n\n return collectSubtreeIds(rootId).map((id) => ({ id, parentId: parentOf.get(id) ?? null }));\n };\n\n /**\n * Relocate id AND its whole subtree to sit contiguously starting at a\n * PRE-removal flat slot. Blok's Blocks.move() is post-removal index space and\n * only carries DOM-contained descendants (resortNestedBlocks) — indent /\n * parentId-nested children are NOT, so move each subtree member that a single\n * root move didn't already pull into place. Keeps the flat array DFS-contiguous,\n * the invariant the flat-index insert API and getChildren ordering depend on.\n */\n const relocateSubtree = (rootId: string, preRemovalSlot: number): 'moved' | 'skipped' | 'blocked' => {\n // Subtree members in current flat (document) order — root first.\n const members = collectSubtreeIds(rootId)\n .map((id) => ({ id, idx: editor.blocks.getBlockIndex(id) }))\n .filter((m): m is { id: string; idx: number } => m.idx !== undefined)\n .sort((a, b) => a.idx - b.idx)\n .map((m) => m.id);\n\n const rootFrom = editor.blocks.getBlockIndex(rootId);\n\n if (rootFrom === undefined) {\n return 'blocked';\n }\n\n // Self-overlap guard. `preRemovalSlot` is the destination the caller\n // computed as the END of the (new or former) parent's WHOLE subtree — and\n // when that parent is an ANCESTOR of the relocating block (always so for\n // unnest, and for a nest into a block this one already sits under), that\n // span still CONTAINS this block's own subtree. Moving the root to a slot\n // at the tail of (or inside) its own footprint splices it in right after\n // one of its OWN descendants; core's post-move auto-heal then reparents the\n // block under that descendant (setBlockParent(B, B) when the neighbour is\n // the block's last child), which BlockHierarchy REFUSES with a thrown cycle\n // error — crashing the caller. But the block is already DFS-contiguous at\n // that destination (its subtree is the tail of the parent's subtree), so\n // the relocation is a no-op: skip the move and report 'skipped', leaving the\n // caller to assert the reparent. Window: `rootFrom < preRemovalSlot <=\n // subtreeEnd + 1`. A backward move (`preRemovalSlot <= rootFrom`) or a\n // genuine forward move past unrelated content (`preRemovalSlot > subtreeEnd\n // + 1`) is untouched.\n //\n // 'skipped' (vs 'moved') is reported DISTINCTLY because no `editor.blocks.\n // move()` ran — so core's post-move parent auto-heal never fired. nest/unnest\n // re-assert the root's parent explicitly (reparentSubtree), so they don't\n // care; but move() leans on that auto-heal for the root's parent-adoption, so\n // it must apply the adopted parent itself on this path (see move()).\n const subtreeEnd = collectSubtreeIds(rootId)\n .map((memberId) => editor.blocks.getBlockIndex(memberId))\n .filter((i): i is number => i !== undefined)\n .reduce((max, i) => Math.max(max, i), rootFrom);\n\n if (preRemovalSlot > rootFrom && preRemovalSlot <= subtreeEnd + 1) {\n return 'skipped';\n }\n\n // Defensive clamp into [0, count-1]: Blok's move() silently no-ops on an\n // out-of-range index, so an over-large preRemovalSlot would strand the\n // root instead of appending it. (In practice resolveInsertIndex stays in\n // range; this guards a concurrently-shrunk tree.)\n const lastIndex = Math.max(0, editor.blocks.getBlocksCount() - 1);\n const rootTarget = Math.min(\n Math.max(rootFrom < preRemovalSlot ? preRemovalSlot - 1 : preRemovalSlot, 0),\n lastIndex\n );\n\n editor.blocks.move(rootTarget, rootFrom);\n\n // Detect a BLOCKED relocation: Blok's move() clamps a cross-`column`-\n // boundary move to a no-op. If the root could not reach its target (it\n // didn't move and wasn't already there), the relocation failed — report\n // it so the caller skips the reparent that would otherwise corrupt DFS\n // contiguity (a child wedged outside its parent's flat run). A legitimate\n // no-op (already at target, rootFrom === rootTarget) still counts as\n // relocated so an in-place nest/unnest reparents as intended.\n if (rootFrom !== rootTarget && editor.blocks.getBlockIndex(rootId) === rootFrom) {\n return 'blocked';\n }\n\n // Place each descendant immediately after the previously-positioned member,\n // re-reading the anchor's LIVE index every iteration. A cached root index\n // (rootNew + k + 1) only holds for a BACKWARD relocation, where descendants\n // already sit after the root. For a FORWARD relocation each descendant\n // move() splices an element out from BEFORE the root, sliding the root (and\n // a cached index) down one slot per step — so the target overshoots, trips\n // Blocks.move()'s out-of-range no-op guard, and strands the descendant.\n // Re-anchoring to the predecessor's current slot absorbs the drift in both\n // directions and keeps the subtree DFS-contiguous. A descendant already in\n // place (carried by resortNestedBlocks for a DOM-nested child) is skipped.\n // The anchor for the k-th descendant is the (k-1)-th — read live each step.\n const descendants = members.filter((memberId) => memberId !== rootId);\n\n descendants.forEach((memberId, k) => {\n const anchorId = k === 0 ? rootId : descendants[k - 1];\n const from = editor.blocks.getBlockIndex(memberId);\n const anchor = editor.blocks.getBlockIndex(anchorId);\n\n if (from === undefined || anchor === undefined) {\n return;\n }\n const target = anchor + 1;\n\n if (from !== target) {\n editor.blocks.move(from < target ? target - 1 : target, from);\n }\n });\n\n return 'moved';\n };\n\n // Reparent `id` (root → newParentId, descendants → their original parent).\n // Re-asserting after relocateSubtree heals move()'s auto-reparent (which sets\n // a moved block's parentId to its new neighbour) and never relocates the flat\n // array, so contiguity established by relocateSubtree is preserved.\n const reparentSubtree = (\n members: Array<{ id: string; parentId: string | null }>,\n rootId: string,\n newParentId: string | null\n ): void => {\n for (const m of members) {\n editor.blocks.setBlockParent(m.id, m.id === rootId ? newParentId : m.parentId);\n }\n };\n\n // Re-assert ONLY the descendants' captured parents after a subtree relocation,\n // leaving the ROOT's parent as core's post-move auto-heal set it — used by\n // move(), whose documented side effect is that the root ADOPTS the parent of\n // the slot it lands in while its subtree travels with it.\n const reassertDescendantParents = (\n members: Array<{ id: string; parentId: string | null }>,\n rootId: string\n ): void => {\n members\n .filter((m) => m.id !== rootId)\n .forEach((m) => editor.blocks.setBlockParent(m.id, m.parentId));\n };\n\n /**\n * Whether `id` is a DIRECT child of a `column` block. Column membership is\n * owned by the drag UI, so a programmatic nest/unnest that would change it is\n * a graceful no-op (see the nest/unnest docs). Checking this EXPLICITLY makes\n * that contract reliable: relying on core's move-clamp alone leaks, because\n * when the relocation needs no actual move (a tail column child already sits\n * at its relocation target) no boundary-crossing move fires, so nothing\n * clamps and the reparent would slip through.\n */\n const isColumnChild = (id: string): boolean => {\n const parent = getById(id)?.parentId ?? null;\n\n return parent !== null && getById(parent)?.type === 'column';\n };\n\n /**\n * Nest `id` (and its whole subtree) under `parentId`, as one undo step.\n * No-op when either id is unknown (probed via the silent snapshot, NOT\n * getBlockIndex, which warns on unknown ids), or when `parentId` is `id`\n * itself or one of `id`'s own descendants — that would form a cycle, which\n * core's setBlockParent THROWS on, so the hook guards it up front.\n *\n * Column boundary caveat: nesting a block that lives inside a `column`, or\n * nesting directly INTO one, is a GRACEFUL no-op — column membership is owned\n * by the drag UI. This is detected explicitly (via the block's and target's\n * parent type), so the no-op holds even when no boundary-crossing move fires.\n * Returns void.\n */\n const nest = (id: string, parentId: string): void => {\n if (getById(parentId) === null || getById(id) === null) {\n return;\n }\n\n // Cycle guard: a block can't become a child of itself or of one of its\n // own descendants. Without this, the relocate/reparent reaches core's\n // setBlockParent, which throws on a cycle and crashes the caller.\n if (parentId === id || isDescendantOf(parentMap(reader), parentId, id)) {\n return;\n }\n\n // Column-boundary no-op: pulling a block out of a `column`, or pushing one\n // directly into a column, changes column membership — owned by the drag UI.\n if (isColumnChild(id) || getById(parentId)?.type === 'column') {\n return;\n }\n\n // Relocate id's whole subtree to after the new parent's existing subtree,\n // THEN assert the parents. Blok keeps the flat array as the canonical\n // document order, and the flat-index insert API only resolves a parent's\n // \"end\" slot when that parent's descendants are contiguous — a bare reparent\n // (no relocation) would wedge unrelated blocks between the parent and its new\n // child, corrupting later inserts/reads. Mirrors the drag move-then-reparent.\n //\n // Only reparent when the relocation actually placed the block: a clamped\n // cross-column move leaves it where it was, and reparenting in place would\n // break DFS contiguity.\n const members = captureSubtreeParents(id);\n\n transact(() => {\n // reparentSubtree sets the root's parent EXPLICITLY, so nest is correct on\n // both the 'moved' and 'skipped' paths — it only bails on a 'blocked'\n // (clamped cross-column) relocation.\n if (relocateSubtree(id, resolveInsertIndex(reader, parentId, 'end')) !== 'blocked') {\n reparentSubtree(members, id, parentId);\n }\n });\n };\n\n /**\n * Promote `id` (and its subtree) to root, as one undo step. No-op when the\n * id is unknown or already at root. Same column-boundary caveat as\n * {@link nest}: unnesting a `column` member out to root is a graceful no-op\n * (column membership changes go through the drag UI). Returns void.\n */\n const unnest = (id: string): void => {\n const node = getById(id);\n\n if (node === null) {\n return;\n }\n const parentId = node.parentId;\n\n if (parentId === null) {\n return;\n }\n\n // Column-boundary no-op: a column member is detached only via the drag UI.\n if (isColumnChild(id)) {\n return;\n }\n\n // Move id's subtree out past its former parent's whole subtree before\n // clearing the parent, so the promoted block doesn't strand itself between\n // the parent and its remaining children (which would break contiguity).\n // As with nest, only clear the parent when the relocation succeeded — a\n // clamped cross-column move must stay a graceful no-op.\n const members = captureSubtreeParents(id);\n\n transact(() => {\n // As with nest, reparentSubtree asserts the root's (null) parent on both\n // 'moved' and 'skipped'; only a 'blocked' clamp keeps it a no-op.\n if (relocateSubtree(id, resolveInsertIndex(reader, parentId, 'end')) !== 'blocked') {\n reparentSubtree(members, id, null);\n }\n });\n };\n\n const remove = (id: string): void => {\n if (editor.blocks.getBlockIndex(id) === undefined) {\n return;\n }\n\n // Remove the block AND its descendants. Blok's single-block delete promotes\n // a (non-columns) container's children to root, which would orphan the\n // nested structure the caller meant to discard. Delete deepest-first (by\n // descending flat index) so a parent is childless by the time it's deleted\n // (no promotion). One undo step.\n //\n // Re-resolve each member's index by id AT DELETE TIME rather than reusing a\n // pre-captured snapshot: a core delete can cascade (deleting a column's last\n // child auto-removes the empty column) or shift indices, so a stale index\n // could target the wrong — or an already-gone — block.\n const orderedIds = collectSubtreeIds(id)\n .map((subId) => ({ subId, index: editor.blocks.getBlockIndex(subId) }))\n .filter((m): m is { subId: string; index: number } => m.index !== undefined)\n .sort((a, b) => b.index - a.index)\n .map((m) => m.subId);\n\n transact(() => {\n for (const subId of orderedIds) {\n const index = editor.blocks.getBlockIndex(subId);\n\n // Already removed by a cascading delete of one of its descendants.\n if (index === undefined) {\n continue;\n }\n void editor.blocks.delete(index, false);\n }\n });\n };\n\n /**\n * Move `id` to a flat slot, as a single operation. No-op when `id` is\n * unknown (probed via the silent snapshot, NOT getBlockIndex, which warns on\n * unknown ids); when a relative `{ before|after }` target references `id`\n * itself, one of its descendants (a block can't be a sibling of its own\n * child), or a ref that does not exist (an unresolved relative target must\n * not silently dump the block at the document end); or for ANY absolute\n * `{ toIndex }` of a block that HAS descendants (a multi-block subtree can't\n * land on one index — see the subtree note below). Guards run BEFORE the\n * index is resolved into a final move.\n *\n * Parent-adoption side effect: `before`/`after` make the moved block a\n * SIBLING of the ref — it adopts the REF's parent (moving before/after a\n * child of a container nests it into that container; moving before/after a\n * root block unnests it to root). `after` clears the ref's WHOLE subtree, so\n * the block lands past the ref's descendants, not among them. The adopted\n * parent is the ref's — NOT the parent of whatever block happens to sit at the\n * landing slot, which would nest under the ref for `after` a ref-with-children.\n * Use {@link nest}/{@link unnest} to change the parent without choosing a\n * sibling slot. Returns void.\n *\n * Subtree-aware: a block WITH descendants relocates its WHOLE subtree as one\n * undo step (core's single move() carries only DOM-contained descendants, so\n * a naive move would strand indent/parentId-nested children before their\n * parent and corrupt DFS contiguity). Only relative `{ before|after }`\n * targets name an unambiguous slot for a multi-block subtree; an absolute\n * `{ toIndex }` of a block that HAS descendants is ambiguous (k blocks can't\n * all land on one index) and is a graceful no-op — use `{ before|after }` to\n * relocate a subtree.\n */\n const move = (id: string, target: MoveTarget): void => {\n // Silent existence probe (NOT getBlockIndex, which warns on unknown ids).\n if (getById(id) === null) {\n return;\n }\n // id is known, so getBlockIndex won't warn.\n const fromIndex = editor.blocks.getBlockIndex(id);\n\n if (fromIndex === undefined) {\n return;\n }\n\n if (!('toIndex' in target)) {\n const ref = 'before' in target ? target.before : target.after;\n\n // A relative target can't reference the block itself or any of its own\n // descendants — a block can't become a sibling of its child.\n if (ref === id || isDescendantOf(parentMap(reader), ref, id)) {\n return;\n }\n\n // An unresolved relative ref must NOT fall through to a relocate-to-end:\n // a missing target is a no-op, not a surprise jump to the document end.\n if (getById(ref) === null) {\n return;\n }\n }\n // NB: an absolute { toIndex } needs no early guard here. A block WITH\n // descendants no-ops EVERY toIndex move in the subtree branch below\n // (ambiguous for a multi-block subtree); a leaf has no own-subtree range to\n // land inside. So a dedicated \"toIndex inside own subtree\" guard would be\n // dead code — the subtree-branch no-op already covers the cycle it guarded.\n\n // Subtree-aware relocation. A block WITH descendants can't ride a single\n // core move(): core carries only DOM-contained descendants (resortNested\n // Blocks), so indent/parentId-nested children are left at their old slot —\n // stranded BEFORE their now-moved parent in flat order, breaking the DFS\n // contiguity getChildren ordering and flat-index inserts depend on, and\n // corrupting saved document order. Relocate the whole subtree (as\n // nest/unnest do) and re-assert each descendant's own parent; the ROOT\n // keeps the parent core's post-move auto-heal gives it — move()'s\n // documented parent-adoption side effect — so only descendants are\n // re-parented. A blocked relocation (a clamped cross-`column` move) leaves\n // everything in place, a graceful no-op like nest/unnest. An absolute\n // { toIndex } is ambiguous for a multi-block subtree (see the move() doc),\n // so it is a graceful no-op here — relative targets relocate the subtree.\n // A leaf block (no descendants) falls through to the single-move fast path.\n const subtreeMembers = captureSubtreeParents(id);\n\n if (subtreeMembers.length > 1) {\n if ('toIndex' in target) {\n return;\n }\n\n const preRemovalSlot = resolveMoveIndex(reader, target);\n // The relative ref whose parent the moved block adopts (toIndex returned\n // above, so target is { before | after }).\n const ref = 'before' in target ? target.before : target.after;\n\n transact(() => {\n const outcome = relocateSubtree(id, preRemovalSlot);\n\n if (outcome === 'blocked') {\n return;\n }\n reassertDescendantParents(subtreeMembers, id);\n\n // Adopt the REF's parent (sibling-of-ref) on BOTH the 'moved' and\n // 'skipped' paths. The position is already sibling-of-ref: resolveMoveIndex\n // clears the ref's WHOLE subtree for `after` and uses the ref's own slot\n // for `before`, so id lands as the ref's sibling. The parent must match.\n // Core's post-move auto-heal does NOT give that — it adopts the parent of\n // the block at the landing SLOT (pre-removal), which for `after` a\n // ref-with-descendants is the ref's last descendant (parent = the ref →\n // nests id UNDER the ref) and for `before` a ref whose flat predecessor\n // sits in another container is that predecessor's parent. On the 'skipped'\n // path no move() ran, so no auto-heal fired at all. Assert ref.parentId so\n // position and parent agree regardless of path. Guarded (mirrors\n // insertWithinTransaction) so a same-container reorder — the common case,\n // where the landed parent already matches — fires no redundant reparent.\n // Can't cycle: ref is neither id nor a descendant (guarded above), so\n // ref's parent is outside id's subtree.\n const intendedParent = getById(ref)?.parentId ?? null;\n\n if ((getById(id)?.parentId ?? null) !== intendedParent) {\n editor.blocks.setBlockParent(id, intendedParent);\n }\n });\n\n return;\n }\n\n const resolved = resolveMoveIndex(reader, target);\n\n // Blok's Blocks.move() removes the block (splice fromIndex) BEFORE\n // re-inserting at toIndex, so toIndex lives in the POST-removal index\n // space. For a relative (before/after) forward move the reference index\n // shifts down by one once the block is removed, so compensate — this also\n // keeps a move-to-end within Blok's `toIndex < length` bound. A literal\n // { toIndex } is the caller's explicit final resting index: pass through.\n const isRelative = !('toIndex' in target);\n const toIndex = isRelative && fromIndex < resolved ? resolved - 1 : resolved;\n\n if (!isRelative) {\n // Absolute { toIndex }: the caller chose the slot, so let core's auto-heal\n // adopt that slot's container (the documented absolute-move semantics).\n editor.blocks.move(toIndex, fromIndex);\n\n return;\n }\n\n // Relative leaf move: same sibling-of-ref rule as the subtree branch — the\n // moved block adopts the REF's parent, not the landing-slot neighbour's\n // (which auto-heal would give: the ref's descendant for `after`, or a\n // cross-container predecessor for `before`). Assert it in the same undo step\n // as the move, guarded so a same-container reorder fires no redundant\n // reparent. Can't cycle: ref is guarded to be neither id nor a descendant,\n // and a leaf has no descendants for ref's parent to fall inside.\n const ref = 'before' in target ? target.before : target.after;\n\n transact(() => {\n editor.blocks.move(toIndex, fromIndex);\n const intendedParent = getById(ref)?.parentId ?? null;\n\n if ((getById(id)?.parentId ?? null) !== intendedParent) {\n editor.blocks.setBlockParent(id, intendedParent);\n }\n });\n };\n\n /**\n * Perform one insert (create + intended-parent assertion) WITHOUT opening a\n * transaction — the caller owns the undo grouping. `insert` wraps a single\n * call in its own transact; `insertMany` shares ONE transact across the whole\n * batch so the bulk insert is a single undo step. Returns the created node,\n * or null when nothing was inserted (idempotent hit returns the existing\n * node; a guard failure returns null).\n */\n const insertWithinTransaction = (spec: InsertSpec): { node: BlockNode | null; created: boolean } => {\n const parentId = spec.parentId ?? null;\n const position = spec.position ?? 'end';\n const data = spec.data ?? {};\n // Programmatic insert must not steal the caret unless explicitly asked.\n const needToFocus = spec.focus ?? false;\n const replace = spec.replace ?? false;\n\n // Every pre-insert guard (id-exists, dangling-parent, missing-ref) and the\n // replace-parent lookup used to call `getById`, which re-enumerates the\n // WHOLE tree each time — O(probes·n) per spec, O(k·probes·n) per batch.\n // The tree can't change until `editor.blocks.insert` runs below, so take\n // ONE snapshot here and resolve every pre-insert probe against it.\n const preById = new Map(snapshotNodes(reader).map((n) => [n.id, n]));\n const probe = (id: string): BlockNode | null => preById.get(id) ?? null;\n\n // Idempotent insert-if-absent: a stable explicit id that already exists\n // returns the existing node without inserting a duplicate, so a re-running\n // effect is safe. Probe via the silent snapshot getById, NOT\n // editor.blocks.getBlockIndex — the latter logs a `warn` for any unknown\n // id, which would spam the console on this (expected-absent) happy path.\n //\n // Skipped under `replace`: a replace is an explicit overwrite, not an\n // insert, so an existing id must not short-circuit it (the two would\n // otherwise silently conflict and replace nothing).\n if (spec.id !== undefined && !replace) {\n const existing = probe(spec.id);\n\n if (existing !== null) {\n // Insert-if-absent hit: the block already existed, nothing was created.\n // insert() still returns the existing node (documented), but insertMany\n // must EXCLUDE it from its created[] result — hence created: false.\n return { node: existing, created: false };\n }\n }\n\n // A dangling parentId would make core throw (dev) or silently misplace the\n // block at the document end (prod). Honor the null contract instead. Probe\n // via the silent snapshot getById, NOT editor.blocks.getBlockIndex, which\n // logs a `warn` for any unknown id and would spam the console on this\n // expected-absent no-op path. Skipped under replace: a replace ignores\n // parentId entirely (the overwritten block's own parent governs), so a\n // stale parentId must not abort the overwrite.\n if (!replace && parentId !== null && probe(parentId) === null) {\n return { node: null, created: false };\n }\n\n // A replace targets the before/after ref block ITSELF (the \"turn into\"\n // block being overwritten), not a sibling anchor. It therefore REQUIRES an\n // object position naming that ref:\n // - with position 'start'/'end' (or omitted) there is no target ref, so\n // a replace has nothing to overwrite — return null rather than silently\n // overwriting whatever block happens to sit at the resolved slot;\n // - with an object position whose ref doesn't exist there is likewise\n // nothing to overwrite — return null instead of falling through to\n // resolveInsertIndex's end-slot fallback (which would insert/replace at\n // the wrong place and reparent a dangling target).\n // Validation is skipped for a plain insert (above), so this is the only\n // guard that protects the replace path.\n if (replace) {\n if (typeof position !== 'object') {\n return { node: null, created: false };\n }\n\n const replaceTargetRef = 'before' in position ? position.before : position.after;\n\n if (probe(replaceTargetRef) === null) {\n return { node: null, created: false };\n }\n }\n\n // A plain insert with an object position naming a ref that does NOT exist\n // must be a no-op (return null), NOT a silent append at the document/parent\n // end. resolveInsertIndex falls back to the end slot for an unresolved ref,\n // which would dump the block somewhere surprising — a DX footgun. Mirror\n // move(), which already bails on a missing relative ref. (Skipped under\n // replace: the block above already validated the replace ref.)\n if (!replace && typeof position === 'object') {\n const positionTargetRef = 'before' in position ? position.before : position.after;\n\n if (probe(positionTargetRef) === null) {\n return { node: null, created: false };\n }\n }\n\n const flatIndex = resolveInsertIndex(reader, parentId, position, replace);\n\n // A replace is a positional type-swap that PRESERVES the replaced block's\n // parent link, so the intended parent is the target's existing parent, not\n // the caller's (root-defaulting) parentId. Capture it from the pre-insert\n // snapshot so the post-insert assertion re-nests the replacement correctly\n // instead of un-nesting it to root. A plain insert uses parentId as-is.\n const positionRef = ((): string | null => {\n if (typeof position !== 'object') {\n return null;\n }\n\n return 'before' in position ? position.before : position.after;\n })();\n const replaceRef = replace ? positionRef : null;\n const intendedParentId =\n replaceRef !== null ? probe(replaceRef)?.parentId ?? null : parentId;\n\n const created = ((): { id: string } | null | undefined => {\n try {\n return editor.blocks.insert(spec.type, data, {}, flatIndex, needToFocus, replace, spec.id, spec.tunes);\n } catch (error) {\n // The only EXPECTED throw here is an unknown/missing tool — core throws\n // a typed ToolNotFoundError. (A missing replace TARGET is a bare Error,\n // not this type, so it would re-throw — but the replace ref is already\n // pre-validated above, so it never reaches here.) Honor the null contract\n // for ToolNotFoundError; re-throw anything else so a genuine\n // bug surfaces instead of being masked as a null return. Keyed on the\n // error TYPE, not a 'not found' substring, so an unrelated error whose\n // message happens to contain \"not found\" is not wrongly swallowed.\n if (error instanceof ToolNotFoundError) {\n return null;\n }\n throw error;\n }\n })();\n\n if (created === undefined || created === null) {\n return { node: null, created: false };\n }\n\n // Assert the intended parent. Core derives a new block's parent from its\n // flat predecessor, so a block appended right after a `column` child is\n // auto-nested into that column. We know the caller's intent: for a\n // parented insert set the parent; for a root insert (parentId === null)\n // override back to root ONLY if core nested it, keeping the natural\n // `insert({ position: 'end' })` a root sibling instead of a stowaway. For\n // a replace, intendedParentId is the overwritten block's own parent, so\n // the replacement keeps its place in the tree.\n // ONE post-insert snapshot for both the landed-parent check and the return\n // node (was two separate getById enumerations). A freshly-created block has\n // no children, so reparenting it only flips its own parentId — its derived\n // contentIds stay `[]`. We therefore reconstruct the corrected node in place\n // rather than re-enumerating the tree a third time after setBlockParent.\n const createdNode = snapshotNodes(reader).find((n) => n.id === created.id) ?? null;\n const landedParentId = createdNode?.parentId ?? null;\n\n const node =\n landedParentId === intendedParentId\n ? createdNode\n : ((): BlockNode | null => {\n editor.blocks.setBlockParent(created.id, intendedParentId);\n\n return createdNode === null ? null : { ...createdNode, parentId: intendedParentId };\n })();\n\n // Position the caret inside the freshly-created block when the caller asked\n // for a specific spot (beyond the boolean `focus`). Applied only on a real\n // creation — an insert-if-absent hit returned earlier, so it never reaches\n // here. setToBlock takes the block id directly.\n if (spec.caret !== undefined) {\n editor.caret.setToBlock(created.id, spec.caret.position ?? 'default', spec.caret.offset ?? 0);\n }\n\n return { node, created: true };\n };\n\n /**\n * Insert one block. Returns the created {@link BlockNode}, or null when the\n * insert is rejected — an unknown tool type (core \"…not found\"), a dangling\n * `parentId`, or a `replace` whose target ref doesn't exist. An explicit\n * `id` that already exists is insert-if-absent: the existing node is returned\n * and nothing is created (skipped under `replace`, which is an explicit\n * overwrite). Validation runs BEFORE the slot is resolved; a `replace`\n * preserves the overwritten block's parent. Always one atomic undo step.\n *\n * The returned node is a fresh-snapshot view (its `contentIds` are derived\n * per call) — read it immediately; do NOT place it in a `useMemo`/`useEffect`\n * dependency array expecting per-mutation identity.\n */\n const insert = (spec: InsertSpec = {}): BlockNode | null => {\n // Mutable property on a const holder (no `let`): the node captured from\n // inside the transact closure for the post-transact return.\n const result: { node: BlockNode | null } = { node: null };\n\n // Always atomic: a single undo step removes the new block (and, for a\n // parented insert, its reparent) — and gives the insert its own boundary\n // instead of merging into adjacent typing history.\n transact(() => {\n // insert() returns the resolved node — including an insert-if-absent hit's\n // existing node (documented) — so it reads only `.node`, not `.created`.\n result.node = insertWithinTransaction(spec).node;\n });\n\n return result.node;\n };\n\n const insertMany = (specs: InsertSpec[]): BlockNode[] => {\n // An empty batch opens no transaction (no spurious undo boundary).\n if (specs.length === 0) {\n return [];\n }\n\n const created: BlockNode[] = [];\n\n // ONE transact for the whole batch → a single atomic undo step. Each spec\n // still runs the full single-insert path (parent assertion, positioning).\n // Per the documented contract, the result holds ONLY successfully-created\n // nodes: specs that fail to insert (null node) AND insert-if-absent hits\n // (existing block, created: false) are both dropped.\n transact(() => {\n for (const spec of specs) {\n const result = insertWithinTransaction(spec);\n\n if (result.created && result.node !== null) {\n created.push(result.node);\n }\n }\n });\n\n return created;\n };\n\n /**\n * Insert a pre-built nested subtree as ONE atomic operation. See the\n * {@link UseBlocksApi.insertTree} contract. Flattens the spec to a DFS\n * pre-order `OutputBlockData[]` — wiring every node's `parent`/`content`\n * links from ids generated up front — then delegates to core's tree-aware\n * `blocks.insertMany` inside a single transact.\n */\n const insertTree = (spec: TreeInsertSpec): BlockNode | null => {\n const parentId = spec.parentId ?? null;\n const position = spec.position ?? 'end';\n\n // Dangling root parentId: mirror `insert`'s guard via the silent snapshot\n // getById (NOT getBlockIndex, which warns on unknown ids). Reject so the\n // subtree isn't silently dumped at the document end.\n if (parentId !== null && getById(parentId) === null) {\n return null;\n }\n\n // Dangling relative position ref: an object { before|after } naming a block\n // that does not exist must be a no-op, NOT a silent append at the document\n // end (resolveInsertIndex's unresolved-ref fallback). Mirror insert()'s\n // missing-ref guard and reject before flattening anything.\n if (typeof position === 'object') {\n const positionTargetRef = 'before' in position ? position.before : position.after;\n\n if (getById(positionTargetRef) === null) {\n return null;\n }\n }\n\n // Flatten the nested spec to a DFS pre-order array with wired\n // `parent`/`content` links — the same transform used to seed nested data,\n // shared as the pure `flattenTree` helper. `parentId` becomes the root's\n // `parent`. flattenTree throws on an id reused WITHIN the spec (a duplicate\n // would corrupt every id-keyed lookup); a tree insert always creates fresh\n // blocks (NOT insert-if-absent), so that is rejected up front — null,\n // mirroring insert's null contract.\n const flat = (() => {\n try {\n return flattenTree(spec, { parentId: parentId ?? undefined });\n } catch {\n return null;\n }\n })();\n\n if (flat === null) {\n return null;\n }\n\n // External collision: an explicit id already present in the live tree would\n // also create a duplicate-id block. Snapshot the existing ids once and\n // reject if any flat node reuses one. Generated ids never collide.\n const existingIds = new Set(snapshotNodes(reader).map((n) => n.id));\n\n if (flat.some((node) => existingIds.has(node.id))) {\n return null;\n }\n\n const rootId = flat[0].id;\n\n // flattenTree omits `content` on leaves (clean seed-data shape). insertMany\n // wants every node to carry an explicit child-id array — a leaf's\n // `contentIds: []` states \"no children\" rather than leaving it undefined —\n // so stamp the empty array back on before handing the batch to core.\n for (const node of flat) {\n if (node.content === undefined) {\n node.content = [];\n }\n }\n\n const flatIndex = resolveInsertIndex(reader, parentId, position);\n\n // ONE transact for the whole subtree → a single atomic undo step. Core's\n // insertMany composes EVERY node before inserting any, so an unknown tool\n // type throws a typed ToolNotFoundError with nothing inserted. Honor the\n // same null-on-unknown-tool contract as insert/insertMany rather than\n // surfacing the throw to the caller; re-throw any other (genuine-bug)\n // error. Keyed on the error TYPE, not a 'not found' substring.\n try {\n transact(() => {\n editor.blocks.insertMany(flat, flatIndex);\n });\n } catch (error) {\n if (error instanceof ToolNotFoundError) {\n return null;\n }\n throw error;\n }\n\n return getById(rootId);\n };\n\n /**\n * Convert markdown to blocks and insert them ADDITIVELY — see the\n * {@link UseBlocksApi.insertMarkdown} doc for the full contract. Async\n * because the converter is lazy-loaded; the insert itself is one atomic\n * undo step. parentId nesting is supported: top-level converted blocks are\n * reparented under parentId, internally-nested ones keep their parent.\n */\n const insertMarkdown = async (\n markdown: string,\n options?: { parentId?: string | null; position?: InsertPosition; config?: MarkdownImportConfig }\n ): Promise<BlockNode[]> => {\n const parentId = options?.parentId ?? null;\n const position = options?.position ?? 'end';\n\n // A dangling parentId is a no-op (no insert), matching `insert`/`insertMany`.\n if (parentId !== null && getById(parentId) === null) {\n return [];\n }\n\n // A dangling relative position ref is likewise a no-op (no insert), NOT a\n // silent append at the document end — mirror insert()/insertTree's guard.\n if (typeof position === 'object') {\n const positionTargetRef = 'before' in position ? position.before : position.after;\n\n if (getById(positionTargetRef) === null) {\n return [];\n }\n }\n\n // Lazy-load the converter (dynamic import mirrors core's markdown lazy\n // loading and keeps the parser out of the main bundle) and run it,\n // forwarding the optional MarkdownImportConfig so custom-tool consumers can\n // map markdown nodes into their tools (gfm toggle, toolMap, extensions).\n // Both awaits can fail — a chunk-load error or a malformed-markdown throw;\n // swallow them and return [] so a converter failure is a graceful no-op\n // (matching update/convert) rather than an unhandled promise rejection in\n // the caller. This await resolves BEFORE the synchronous transact.\n // Mutable property on a const holder (no `let`): captured from the try.\n const conversion: { blocks: OutputBlockData[] } = { blocks: [] };\n\n try {\n const { markdownToBlocks } = await import('@bloklabs/core/markdown');\n\n conversion.blocks = await markdownToBlocks(markdown, options?.config);\n } catch (error) {\n // Graceful no-op: a converter failure (chunk-load or parse error) returns\n // [] rather than surfacing an unhandled rejection to the caller. But\n // surface it to the console so a genuine converter bug is DISTINGUISHABLE\n // from empty markdown (which returns [] via the blocks.length === 0 path\n // below, without ever reaching this catch) instead of being swallowed\n // silently and losing all diagnostics.\n console.warn('useBlocks.insertMarkdown: markdown conversion failed', error);\n\n return [];\n }\n\n const blocks = conversion.blocks;\n\n // Empty / whitespace-only markdown opens no transaction (no undo boundary).\n if (blocks.length === 0) {\n return [];\n }\n\n // Re-validate the parent AFTER the await: the pre-await existence check can\n // go stale if the parent was removed while the converter was in flight.\n // Stamping a now-dangling parent would orphan the blocks instead of the\n // promised [] no-op, so re-check and bail out here.\n if (parentId !== null && getById(parentId) === null) {\n return [];\n }\n\n // Re-validate the relative position ref after the await too: the target\n // could have been removed while the converter was in flight, in which case\n // inserting at the stale slot would surprise the caller. No-op instead.\n if (typeof position === 'object') {\n const positionTargetRef = 'before' in position ? position.before : position.after;\n\n if (getById(positionTargetRef) === null) {\n return [];\n }\n }\n\n // Nest under the parent by stamping `parent` on each TOP-LEVEL block (one\n // the converter left un-parented). Blocks the markdown nested internally\n // (their `parent` already points at a sibling in this batch) are untouched,\n // so the import's own structure is preserved.\n const seeded: OutputBlockData[] =\n parentId === null\n ? blocks\n : blocks.map((block) =>\n block.parent === undefined || block.parent === null\n ? { ...block, parent: parentId }\n : block\n );\n\n const flatIndex = resolveInsertIndex(reader, parentId, position);\n\n // Mutable property on a const holder (no `let`): captured from inside the\n // transact closure. insertMany returns BlockAPI[] (each has `.id`) — the\n // reliable record of what was created, since the converter's ids may not\n // survive composition. ONE transact → a single atomic undo step.\n const result: { created: Array<{ id: string }> } = { created: [] };\n\n // The insert lives OUTSIDE the conversion try/catch, so an unknown mapped\n // tool (core throws a typed ToolNotFoundError) would otherwise surface as an\n // unhandled promise rejection. Honor the same null-on-unknown-tool contract\n // as insertTree — return [] — and re-throw any other (genuine-bug) error.\n // Keyed on the error TYPE, not a 'not found' substring.\n try {\n transact(() => {\n result.created = editor.blocks.insertMany(seeded, flatIndex);\n });\n } catch (error) {\n if (error instanceof ToolNotFoundError) {\n return [];\n }\n throw error;\n }\n\n return result.created\n .map((block) => getById(block.id))\n .filter((node): node is BlockNode => node !== null);\n };\n\n const update = (\n id: string,\n data?: BlockToolData,\n tunes?: { [name: string]: BlockTuneData }\n ): void => {\n // Silent existence probe (NOT getBlockIndex, which warns on unknown ids).\n if (getById(id) === null) {\n return;\n }\n\n // Core update is async and forms its own undo/Yjs step, so it is NOT\n // wrapped in transact (that would close the group before the write lands).\n // Swallow any rejection so it can't surface as an unhandled rejection.\n void Promise.resolve(editor.blocks.update(id, data, tunes)).catch(() => undefined);\n };\n\n const convert = (\n id: string,\n newType: string,\n dataOverrides?: BlockToolData,\n options?: { caret?: CaretTarget }\n ): void => {\n if (getById(id) === null) {\n return;\n }\n\n // Core convert is async and rejects when a tool lacks a conversionConfig.\n // Like update, it owns its own history step (no transact). Position the\n // caret only AFTER a successful convert (matching the in-editor keyboard\n // turn-into, which preserves the caret) when the caller asked for it.\n // Swallow the rejection so a non-convertible block is a graceful no-op —\n // and on rejection the caret is left untouched.\n void Promise.resolve(editor.blocks.convert(id, newType, dataOverrides))\n .then((converted) => {\n if (options?.caret !== undefined) {\n // Core convert routes through replace(), which regenerates the block\n // id — the resolved BlockAPI carries the NEW id. Target it (falling\n // back to the original only if a faithless path resolves nothing) so\n // the caret lands in the converted block instead of a stale id.\n const targetId = converted?.id ?? id;\n\n editor.caret.setToBlock(\n targetId,\n options.caret.position ?? 'default',\n options.caret.offset ?? 0\n );\n }\n })\n .catch(() => undefined);\n };\n\n const transactWithoutCapture = (fn: () => void): void => {\n if (editor.blocks.transactWithoutCapture !== undefined) {\n editor.blocks.transactWithoutCapture(fn);\n } else {\n fn();\n }\n };\n\n const getBlocksCount = (): number => {\n onRead();\n\n return editor.blocks.getBlocksCount();\n };\n\n const getCurrentBlockIndex = (): number => {\n onRead();\n\n return editor.blocks.getCurrentBlockIndex();\n };\n\n const getBlockByIndex = (index: number): BlockNode | null => {\n onRead();\n const block = editor.blocks.getBlockByIndex(index);\n\n return block === undefined ? null : getById(block.id);\n };\n\n const getBlockByElement = (element: HTMLElement): BlockNode | null => {\n onRead();\n const block = editor.blocks.getBlockByElement(element);\n\n return block === undefined ? null : getById(block.id);\n };\n\n const composeBlockData = (toolName: string): Promise<BlockToolData> =>\n editor.blocks.composeBlockData(toolName);\n\n const getBlockData = (\n id: string\n ): { data: BlockToolData; tunes: { [name: string]: BlockTuneData } } | null => {\n // Silent existence probe via the snapshot getById (NOT editor.blocks.getById,\n // which logs a `warn` for an unknown id) so a miss is a quiet null, matching\n // getBlockIndex and the other id-taking readers.\n if (getById(id) === null) {\n return null;\n }\n\n const block = editor.blocks.getById(id);\n\n if (block === null) {\n return null;\n }\n\n // preservedData/preservedTunes are core's SYNCHRONOUS last-extracted view —\n // the same snapshot clipboard ops read. Returning it (rather than the async\n // save()) keeps this reader synchronous so a block can be read and re-inserted\n // (duplicated) inside one render/handler without the ref escape hatch.\n return { data: block.preservedData, tunes: block.preservedTunes };\n };\n\n const getBlockIndex = (id: string): number | null => {\n if (getById(id) === null) {\n // Silent existence probe (NOT editor.blocks.getBlockIndex, which warns on\n // unknown ids) so a miss is a quiet null, matching every other reader.\n return null;\n }\n\n return editor.blocks.getBlockIndex(id) ?? null;\n };\n\n const renderFromHTML = (html: string): Promise<void> => editor.blocks.renderFromHTML(html);\n\n const splitBlock = (\n currentBlockId: string,\n currentBlockData: Partial<BlockToolData>,\n newBlockType: string,\n newBlockData: BlockToolData,\n insertIndex: number\n ): BlockNode | null => {\n // Silent no-op for an unknown current block, matching every other id-taking\n // mutator. Probe via the snapshot getById (NOT getBlockIndex, which warns).\n if (getById(currentBlockId) === null) {\n return null;\n }\n\n // A negative insertIndex is malformed — core would forward it to a splice\n // (which counts from the array end) and silently split at the wrong slot.\n // Honor the silent-no-op convention instead (consistent with\n // insertOutputData's negative-index guard): return null without touching core.\n if (insertIndex < 0) {\n return null;\n }\n\n // An unknown newBlockType makes core's compose path throw a typed\n // ToolNotFoundError — honor the null contract (mirroring insert/insertTree);\n // re-throw any other (genuine-bug) error. Keyed on the error TYPE.\n const created = ((): { id: string } | null | undefined => {\n try {\n return editor.blocks.splitBlock(\n currentBlockId,\n currentBlockData,\n newBlockType,\n newBlockData,\n insertIndex\n );\n } catch (error) {\n if (error instanceof ToolNotFoundError) {\n return null;\n }\n throw error;\n }\n })();\n\n return created === undefined || created === null ? null : getById(created.id);\n };\n\n const insertOutputData = (\n blocks: OutputBlockData[],\n options?: { index?: number }\n ): BlockNode[] => {\n // An empty batch opens no transaction (no spurious undo boundary).\n if (blocks.length === 0) {\n return [];\n }\n\n // A negative index is malformed — core throws a bare validation Error. Honor\n // the silent-no-op convention instead: return [] without inserting (no\n // transaction, no surprise end-append), consistent with the rest of the API.\n if (options?.index !== undefined && options.index < 0) {\n return [];\n }\n\n // ONE transact for the whole batch → a single atomic undo step. Delegates\n // to core's raw insertMany, which honors each block's parent/content links.\n // Honor the same null/[]-on-unknown-tool contract as insertTree (core throws\n // a typed ToolNotFoundError); re-throw any other (genuine-bug) error.\n const result: { created: Array<{ id: string }> } = { created: [] };\n\n try {\n transact(() => {\n result.created =\n options?.index !== undefined\n ? editor.blocks.insertMany(blocks, options.index)\n : editor.blocks.insertMany(blocks);\n });\n } catch (error) {\n if (error instanceof ToolNotFoundError) {\n return [];\n }\n throw error;\n }\n\n return result.created\n .map((block) => getById(block.id))\n .filter((node): node is BlockNode => node !== null);\n };\n\n /**\n * Insert one child block under `parentId` at flat `insertIndex`, atomically.\n * Delegates to core's `insertInsideParent`, which groups the block creation\n * AND the parent assignment into a single undo entry itself — so this is NOT\n * wrapped in the hook's `transact` (that would be a redundant nested group).\n * A dangling parentId is a no-op (null), mirroring `insert`'s parent guard;\n * an unknown child tool throws a typed ToolNotFoundError from core's compose\n * path — honor the null contract and re-throw anything else (genuine bug).\n */\n const insertInsideParent = (\n parentId: string,\n insertIndex: number,\n childData?: BlockToolData\n ): BlockNode | null => {\n // Silent existence probe (NOT getBlockIndex, which warns on unknown ids).\n if (getById(parentId) === null) {\n return null;\n }\n\n const created = ((): { id: string } | null | undefined => {\n try {\n return editor.blocks.insertInsideParent(parentId, insertIndex, childData);\n } catch (error) {\n if (error instanceof ToolNotFoundError) {\n return null;\n }\n throw error;\n }\n })();\n\n return created === undefined || created === null ? null : getById(created.id);\n };\n\n /**\n * Replace the whole document with saved {@link OutputData} — a document-LOAD\n * primitive (clears existing content first), the counterpart of the additive\n * {@link insertOutputData}. Pure delegation to core's async `render`.\n */\n const render = (data: OutputData): Promise<void> => editor.blocks.render(data);\n\n /** Remove every block — document reset. Pure delegation to core's async `clear`. */\n const clear = (): Promise<void> => editor.blocks.clear();\n\n /**\n * Serialize the document to Markdown — the read-side twin of\n * {@link UseBlocksApi.insertMarkdown}. Pure delegation to core's async\n * `exportMarkdown` (which lazy-loads the serializer).\n */\n const exportMarkdown = (): Promise<string> => editor.blocks.exportMarkdown();\n\n /**\n * The LIVE Yjs-sync flag, read at call time (the api handle is memoized, so a\n * cached property would go stale). Pure delegation to core's read-only flag.\n */\n const isSyncingFromYjs = (): boolean => {\n onRead();\n\n return editor.blocks.isSyncingFromYjs;\n };\n\n // Every key is listed EXPLICITLY — do NOT spread `...EMPTY_API` here. The\n // return is typed `UseBlocksApi`, so an explicit list makes a forgotten live\n // wiring a COMPILE error (missing property). Spreading EMPTY_API would instead\n // backfill the missing key with its pre-ready no-op stub, silently shipping a\n // method that does nothing when the editor IS ready — a hole no key-presence\n // test can catch (the key is present, just wrong). Keep it exhaustive.\n return {\n getById,\n getChildren,\n insert,\n insertMany,\n insertTree,\n insertMarkdown,\n exportMarkdown,\n move,\n nest,\n unnest,\n remove,\n update,\n convert,\n transact,\n transactWithoutCapture,\n getBlocksCount,\n getCurrentBlockIndex,\n getBlockByIndex,\n getBlockByElement,\n getBlockData,\n getBlockIndex,\n composeBlockData,\n renderFromHTML,\n insertOutputData,\n splitBlock,\n insertInsideParent,\n render,\n clear,\n isSyncingFromYjs,\n };\n};\n","import type { ReadOnlyModeConfig } from '@bloklabs/core';\n\n/**\n * Normalized shape of the `readOnly` config option\n */\nexport interface NormalizedReadOnlyConfig {\n enabled: boolean;\n hideControls: boolean;\n}\n\n/**\n * Single source of truth for interpreting the `readOnly` config option.\n * The object form always means read-only is enabled.\n * @param value - raw `readOnly` value from BlokConfig\n */\nexport function normalizeReadOnlyConfig(value: boolean | ReadOnlyModeConfig | undefined): NormalizedReadOnlyConfig {\n if (typeof value === 'object' && value !== null) {\n return { enabled: true, hideControls: value.hideControls === true };\n }\n\n return { enabled: value === true, hideControls: false };\n}\n","/**\n * Structural deep equality for JSON-like values (Blok `OutputData`).\n *\n * Framework-agnostic: shared by the React and Angular adapters to dedupe\n * reactive `data` updates so identical content does not trigger a redundant\n * re-render that would clobber the caret/selection. Handles the value shapes\n * that appear in editor data: plain objects, arrays, and primitives (including\n * `null`/`undefined`).\n * @param a - first value to compare\n * @param b - second value to compare\n * @returns true when both values are structurally equal\n */\nexport function deepEqual(a: unknown, b: unknown): boolean {\n if (a === b) {\n return true;\n }\n\n if (typeof a !== 'object' || a === null || typeof b !== 'object' || b === null) {\n return false;\n }\n\n const aIsArray = Array.isArray(a);\n const bIsArray = Array.isArray(b);\n\n if (aIsArray !== bIsArray) {\n return false;\n }\n\n if (aIsArray && bIsArray) {\n if (a.length !== b.length) {\n return false;\n }\n\n return a.every((item, index) => deepEqual(item, b[index]));\n }\n\n const aObj = a as Record<string, unknown>;\n const bObj = b as Record<string, unknown>;\n const aKeys = Object.keys(aObj);\n const bKeys = Object.keys(bObj);\n\n if (aKeys.length !== bKeys.length) {\n return false;\n }\n\n return aKeys.every(\n (key) => Object.prototype.hasOwnProperty.call(bObj, key) && deepEqual(aObj[key], bObj[key])\n );\n}\n","import type { LooseOutputBlockData, LooseOutputData, OutputBlockData, OutputData } from '@bloklabs/core';\n/**\n * Public utilities for working with saved editor documents (`OutputData`).\n *\n * Consumers persisting editor content need two recurring predicates that the\n * editor itself already relies on internally:\n *\n * - structural equality, to dedupe the `data → render → onSave → data` echo\n * round-trip without clobbering the caret;\n * - emptiness, to decide whether a document carries any user content\n * (placeholder states, \"save\" button gating, skipping empty submissions).\n *\n * Both accept the loose wire shape (`data: null`, `id: null`, nullish\n * documents) so backend DTOs can be passed as-is.\n */\nimport { deepEqual } from './deep-equal';\n\n\ntype AnyOutputData = OutputData | LooseOutputData | null | undefined;\n\n/**\n * Compares two blocks structurally. The `id` participates only when BOTH\n * blocks carry one: the editor mints a fresh id whenever content arrives\n * without one (see {@link normalizeOutputBlocks}), so an id-less origin\n * document must still compare equal to its saved echo.\n * @param a - first block to compare\n * @param b - second block to compare\n * @returns true when the blocks are structurally equal\n */\nfunction equalsOutputBlock(\n a: OutputBlockData | LooseOutputBlockData,\n b: OutputBlockData | LooseOutputBlockData\n): boolean {\n const { id: idA, ...restA } = a;\n const { id: idB, ...restB } = b;\n\n const hasIdA = typeof idA === 'string' && idA !== '';\n const hasIdB = typeof idB === 'string' && idB !== '';\n\n if (hasIdA && hasIdB && idA !== idB) {\n return false;\n }\n\n return deepEqual(restA, restB);\n}\n\n/**\n * The tool a pristine editor seeds its first (empty) block with. An empty block\n * of this type is UI scaffolding, not user content — see\n * {@link EqualsOutputDataOptions.ignoreEmptyDefaultBlocks}.\n */\nconst DEFAULT_BLOCK_TYPE = 'paragraph';\n\n/**\n * Options for {@link equalsOutputData}.\n */\nexport interface EqualsOutputDataOptions {\n /**\n * Ignore empty default blocks on both sides before comparing. A fresh editor\n * always seeds one empty default paragraph, so a pristine document\n * (`[{ type: 'paragraph', data: { text: '' } }]`) does not content-equal a\n * saved-empty baseline (`[]`) by default. Turn this on for dirty-vs-baseline\n * checks (\"has the user actually typed anything?\"): empty blocks of the\n * default paragraph tool are dropped from both documents first, so pristine\n * scaffolding and trailing empty lines don't register as a change. Empty\n * NON-default blocks (a content-less divider, an empty image) are kept — they\n * are meaningful content.\n */\n ignoreEmptyDefaultBlocks?: boolean;\n}\n\n/**\n * True for an empty block of the default paragraph tool — the editor's own\n * scaffolding, not user content.\n * @param block - block to inspect\n * @returns true when the block is an empty default paragraph\n */\nfunction isEmptyDefaultBlock(block: OutputBlockData | LooseOutputBlockData): boolean {\n return block.type === DEFAULT_BLOCK_TYPE && isEmptyValue(block.data);\n}\n\n/**\n * Resolves the blocks to compare for a document, dropping empty default blocks\n * when {@link EqualsOutputDataOptions.ignoreEmptyDefaultBlocks} is set.\n * @param data - document whose blocks are collected\n * @param options - comparison options\n * @returns the blocks to compare\n */\nfunction comparableBlocks(\n data: AnyOutputData,\n options?: EqualsOutputDataOptions\n): Array<OutputBlockData | LooseOutputBlockData> {\n const blocks = data?.blocks ?? [];\n\n if (options?.ignoreEmptyDefaultBlocks === true) {\n return blocks.filter((block) => !isEmptyDefaultBlock(block));\n }\n\n return blocks;\n}\n\n/**\n * Structural equality for saved documents. Compares the `blocks` arrays\n * deeply; the volatile `time` and `version` envelope fields are ignored, so a\n * document round-tripped through `save()` compares equal to its echo. Block\n * ids are compared only when both sides carry one — the editor mints fresh\n * ids for id-less content, so a legacy document still equals its saved echo.\n * Nullish documents compare equal to `{ blocks: [] }`.\n *\n * Pass `{ ignoreEmptyDefaultBlocks: true }` for dirty-vs-baseline checks so a\n * pristine editor (one empty default paragraph) equals a saved-empty baseline —\n * see {@link EqualsOutputDataOptions}.\n * @param a - first document to compare\n * @param b - second document to compare\n * @param options - comparison options\n * @returns true when both documents hold structurally equal blocks\n */\nexport function equalsOutputData(a: AnyOutputData, b: AnyOutputData, options?: EqualsOutputDataOptions): boolean {\n const blocksA = comparableBlocks(a, options);\n const blocksB = comparableBlocks(b, options);\n\n return blocksA.length === blocksB.length && blocksA.every((block, index) => equalsOutputBlock(block, blocksB[index]));\n}\n\n/**\n * A bounded window of the editor's recently emitted `onSave` payloads, used by\n * the framework adapters to recognize controlled-`data` echoes. Deduping\n * against only the LAST emitted payload is not enough: a host that persists on\n * save and refetches can hand the adapter a STALE echo — an earlier save\n * arriving after a newer one already replaced the baseline — and re-rendering\n * it would clobber the caret and any content typed since. Matching is\n * structural ({@link equalsOutputData}), so envelopes reshaped in transit\n * (fresh `time`, stripped ids) still count as echoes.\n * @param capacity - number of payloads retained before the oldest is evicted\n * @returns the echo window\n */\nexport function createEmittedEchoWindow(capacity: number = 20): {\n /** Records a payload the editor emitted via `onSave`. */\n record(data: OutputData | LooseOutputData): void;\n /** True when the document content-equals any recorded payload. */\n matches(data: AnyOutputData): boolean;\n /** Forgets all recorded payloads (external content took over). */\n clear(): void;\n} {\n const emitted: Array<OutputData | LooseOutputData> = [];\n\n return {\n record(data: OutputData | LooseOutputData): void {\n emitted.push(data);\n if (emitted.length > capacity) {\n emitted.shift();\n }\n },\n matches(data: AnyOutputData): boolean {\n return emitted.some((payload) => equalsOutputData(payload, data));\n },\n clear(): void {\n emitted.length = 0;\n },\n };\n}\n\n/**\n * A shared, deeply frozen empty document. Consumers persisting editor content\n * repeatedly hand-write `{ blocks: [] }` for cleared/pristine baselines; this\n * is the canonical value to use instead. Frozen (blocks array included) so a\n * shared reference can never be mutated into a stale non-empty baseline.\n */\nexport const EMPTY_OUTPUT_DATA: OutputData = Object.freeze({\n // Freeze the array too, so a shared reference can't be mutated. The public\n // `blocks` type is mutable (`OutputBlockData[]`), so the frozen (readonly)\n // array is re-widened through `unknown` — runtime stays frozen.\n blocks: Object.freeze([]) as unknown as OutputBlockData[],\n});\n\n/**\n * Maps a controlled `data` value to something the editor's `render()` accepts.\n * A whole-document `null` — a controlled \"clear to empty\" — becomes\n * `{ blocks: [] }`; any real document passes through untouched.\n *\n * The framework adapters (React/Vue/Angular) route their reactive `data` path\n * through this so a `null` never reaches `render()`, whose strict guard reads\n * `data.blocks` and would throw on `null`. `undefined` (uncontrolled) is handled\n * by the adapters before this point, so it is intentionally not an input here.\n * @param data - a controlled document, or `null` for an empty document\n * @returns a document `render()` can consume\n */\nexport function toRenderableData(data: OutputData | LooseOutputData | null): OutputData | LooseOutputData {\n return data === null ? { blocks: [] } : data;\n}\n\n/**\n * Normalizes blocks from the loose wire shape into the strict saved shape at\n * the editor's input boundaries: a `null`/missing `data` becomes `{}`, a\n * `null`/empty `id` is dropped so the block factory generates a fresh one.\n * Idempotent — strict blocks pass through unchanged (shallow-copied).\n * @param blocks - blocks in either the strict or the loose wire shape\n * @returns blocks in the strict saved shape\n */\nexport function normalizeOutputBlocks(blocks: Array<OutputBlockData | LooseOutputBlockData>): OutputBlockData[] {\n return blocks.map((block) => {\n const { id, data, ...rest } = block;\n\n return {\n ...rest,\n ...(typeof id === 'string' && id !== '' ? { id } : {}),\n data: data ?? {},\n };\n });\n}\n\n/**\n * Normalizes a whole loose wire document into the strict saved\n * {@link OutputData} shape at an input boundary. A nullish document becomes\n * `{ blocks: [] }`; `null` envelope fields (`time`/`version`) are dropped; each\n * block is passed through {@link normalizeOutputBlocks}, so `null`/missing\n * `data` becomes `{}` and `null`/empty ids are dropped for regeneration.\n *\n * Unlike a hand-written `blocks.map(...)` mapper, this preserves every block\n * passthrough field — `tunes`, `parent`, `content`, `indent`, edit metadata —\n * so a backend DTO can be turned into strict `OutputData` without silently\n * losing hierarchy or tunes. Idempotent: a strict document passes through\n * unchanged (shallow-copied).\n * @param data - a document in the strict or loose wire shape, or nullish\n * @returns the document in the strict saved shape\n */\nexport function normalizeOutputData(data: AnyOutputData): OutputData {\n if (data === null || data === undefined) {\n return { blocks: [] };\n }\n\n return {\n ...(typeof data.version === 'string' ? { version: data.version } : {}),\n ...(typeof data.time === 'number' ? { time: data.time } : {}),\n blocks: normalizeOutputBlocks(data.blocks),\n };\n}\n\n/**\n * True when the value carries no user content: blank/whitespace-only strings,\n * empty arrays, plain objects whose values are all empty, and nullish values.\n * Numbers and booleans are presentation metadata (`level`, `checked`, styles)\n * and never count as content on their own.\n * @param value - block data value to inspect\n * @returns true when the value carries no user content\n */\nfunction isEmptyValue(value: unknown): boolean {\n if (value === null || value === undefined) {\n return true;\n }\n\n if (typeof value === 'string') {\n return value.trim() === '';\n }\n\n if (Array.isArray(value)) {\n return value.every(isEmptyValue);\n }\n\n if (typeof value === 'object') {\n return Object.values(value).every(isEmptyValue);\n }\n\n // Numbers, booleans and other primitives are metadata, not content.\n return true;\n}\n\n/**\n * True when the document carries no user content: it is nullish, has no\n * blocks, or every block's data holds only empty values (see\n * {@link isEmptyValue}). Note that content-less visual blocks (e.g. a divider,\n * whose data is `{}`) count as empty — check `blocks.length` when mere block\n * presence matters.\n * @param data - document to inspect\n * @returns true when the document carries no user content\n */\nexport function isEmptyOutputData(data: AnyOutputData): boolean {\n const blocks = data?.blocks ?? [];\n\n return blocks.every((block) => isEmptyValue(block.data));\n}\n","// src/shared/prop-schema.ts\n\n/** One field of a block's prop schema. */\nexport interface PropSchemaEntry {\n /** Default value, used when the incoming data omits this key. */\n default: unknown;\n /** Optional allowed values (advisory; not enforced at runtime in v1). */\n values?: readonly unknown[];\n}\n\n/**\n * Declarative data shape. The keys here are EXACTLY the keys `save()` returns to\n * Yjs — this closes the per-key-sync key-resurrection gap (a cleared field is\n * written as its explicit default, never dropped).\n */\nexport type PropSchema = Record<string, PropSchemaEntry>;\n\n/**\n * Fill a data object against the schema: every schema key present, incoming\n * value when defined else the schema default, and ONLY schema keys (so `save()`\n * is never partial). Returns a frozen plain object — safe to hand straight to\n * core's per-key Yjs sync.\n */\nexport const fillDefaults = <Data>(\n schema: PropSchema,\n data: Record<string, unknown>\n): Readonly<Data> => {\n const result: Record<string, unknown> = {};\n\n for (const key of Object.keys(schema)) {\n result[key] = data[key] !== undefined ? data[key] : schema[key].default;\n }\n\n return Object.freeze(result) as Readonly<Data>;\n};\n","/**\n * Centralized data attributes used across the Blok editor.\n * This is the single source of truth for all data-blok-* attributes.\n *\n * Exported as Blok.DATA_ATTR for users.\n *\n * Naming convention:\n * - Remove 'data-blok-' prefix and convert to camelCase\n * - Global attributes: hidden, disabled, focused\n * - Component prefixed: popover, popoverItem, toolbar, etc.\n */\nexport const DATA_ATTR = {\n // ============================================\n // Core Element Identifiers\n // ============================================\n\n /** Interface type identifier (blok, inline-toolbar, tooltip) */\n interface: 'data-blok-interface',\n /** Block element wrapper */\n element: 'data-blok-element',\n /** Block element content wrapper */\n elementContent: 'data-blok-element-content',\n /** Editor wrapper container */\n editor: 'data-blok-editor',\n /** Redactor zone */\n redactor: 'data-blok-redactor',\n /** Present on the editor wrapper once a `blocks.render()` batch has finished\n * inserting blocks into the DOM; removed while a re-render is in flight.\n * Acts as a stable render-readiness gate for consumers (e.g. E2E waits). */\n rendered: 'data-blok-rendered',\n\n // ============================================\n // Block Identifiers\n // ============================================\n\n /** Block unique identifier */\n id: 'data-blok-id',\n /** Block component/tool type */\n component: 'data-blok-component',\n /** Tool type attribute */\n tool: 'data-blok-tool',\n /** Block nesting depth (derived from the parentId chain) */\n depth: 'data-blok-depth',\n /** Flat list-nesting indentation level (0 = root); tool-agnostic, mirrors list depth */\n indent: 'data-blok-indent',\n /** Header tool's heading level (1-6). Public styling hook — keyed by level rather\n * than by tag name, so a level remapped to a custom tag via `levelOverrides[n].tag`\n * (types/tools/header.d.ts) still matches its level's typography rules. */\n headingLevel: 'data-blok-heading-level',\n\n // ============================================\n // Global States\n // ============================================\n\n /** Element is hidden from view */\n hidden: 'data-blok-hidden',\n /** Element is disabled and non-interactive */\n disabled: 'data-blok-disabled',\n /** Element is focused via keyboard navigation */\n focused: 'data-blok-focused',\n /** Block is selected */\n selected: 'data-blok-selected',\n /** Block is stretched */\n stretched: 'data-blok-stretched',\n /** Editor or element is empty */\n empty: 'data-blok-empty',\n /** Present on the editor wrapper while read-only mode is active.\n * Public styling hook — lets hosts key rules off the editing state\n * without JS. Deliberately does NOT collapse the gutter: plain\n * read-only still shows the block-hover copy-link control there, and\n * in-place readOnly.set() flips must not shift the layout. */\n readonly: 'data-blok-readonly',\n /** Present on the editor wrapper while read-only mode hides ALL editor\n * controls (readOnly: { hideControls: true }). Public styling hook —\n * drives the gutter auto-collapse for genuinely chromeless read-only. */\n controlsHidden: 'data-blok-controls-hidden',\n /** Present on the editor wrapper when config.hideToolbar is true.\n * Public styling hook — drives the gutter auto-collapse (the gutter\n * exists solely to house the toolbar's +/⠿ controls). */\n toolbarHidden: 'data-blok-toolbar-hidden',\n\n // ============================================\n // Editor Modes\n // ============================================\n\n /** Content alignment mode (left, center, right) */\n contentAlign: 'data-blok-content-align',\n /** Right-to-left mode */\n rtl: 'data-blok-rtl',\n /** Editor content width mode (present with value \"full\" for wide mode; absent = narrow) */\n width: 'data-blok-width',\n /** Present on the editor wrapper when config.style.nativeSelection is true.\n * Public styling hook — disables Blok's ::selection repaint (preflight.css)\n * and re-points the fake-background highlight at the UA Highlight color\n * (colors.css), so selection falls back to native/host-defined colors. */\n nativeSelection: 'data-blok-native-selection',\n\n // ============================================\n // Drag and Drop\n // ============================================\n\n /** Block is being dragged */\n dragging: 'data-blok-dragging',\n /** Multiple blocks being dragged */\n draggingMulti: 'data-blok-dragging-multi',\n /** Block is being duplicated (Alt+drag) */\n duplicating: 'data-blok-duplicating',\n /** Drag handle element */\n dragHandle: 'data-blok-drag-handle',\n\n // ============================================\n // Toolbar\n // ============================================\n\n /** Toolbar element */\n toolbar: 'data-blok-toolbar',\n /** Settings toggler button */\n settingsToggler: 'data-blok-settings-toggler',\n /** Toolbox is open */\n toolboxOpened: 'data-blok-toolbox-opened',\n /** Block settings is open */\n blockSettingsOpened: 'data-blok-block-settings-opened',\n /** Element is opened (generic) */\n opened: 'data-blok-opened',\n\n // ============================================\n // Popover Container\n // ============================================\n\n /** Root popover element */\n popover: 'data-blok-popover',\n /** Popover container wrapper */\n popoverContainer: 'data-blok-popover-container',\n /** Popover items list */\n popoverItems: 'data-blok-popover-items',\n /** Custom, engine-independent scrollbar thumb overlaid on the popover items */\n popoverScrollbar: 'data-blok-popover-scrollbar',\n /** Stamped on the custom scrollbar thumb while it is being dragged (keeps it revealed) */\n popoverScrollbarDragging: 'data-blok-dragging',\n /** Stamped on a scroll container while it is actively scrolling (reveals the auto-hidden scrollbar thumb) */\n scrolling: 'data-blok-scrolling',\n /** Popover overlay element */\n popoverOverlay: 'data-blok-popover-overlay',\n /** Popover custom content area */\n popoverCustomContent: 'data-blok-popover-custom-content',\n /** Popover custom class */\n popoverCustomClass: 'data-blok-popover-custom-class',\n /** Inline popover variant */\n popoverInline: 'data-blok-popover-inline',\n /** Popover is open */\n popoverOpened: 'data-blok-popover-opened',\n /** Popover opens upward */\n popoverOpenTop: 'data-blok-popover-open-top',\n /** Popover opens leftward */\n popoverOpenLeft: 'data-blok-popover-open-left',\n\n // ============================================\n // Popover Nesting\n // ============================================\n\n /** Nested popover indicator */\n nested: 'data-blok-nested',\n /** Nesting level value */\n nestedLevel: 'data-blok-nested-level',\n /** Group label for promoted search results from nested children */\n promotedGroupLabel: 'data-blok-promoted-group-label',\n /** Group label for top-level matches in search results */\n topLevelGroupLabel: 'data-blok-top-level-group-label',\n\n // ============================================\n // Popover Header\n // ============================================\n\n /** Header container */\n popoverHeader: 'data-blok-popover-header',\n /** Header text element */\n popoverHeaderText: 'data-blok-popover-header-text',\n /** Back button in nested popover */\n popoverHeaderBackButton: 'data-blok-popover-header-back-button',\n\n // ============================================\n // Popover Items\n // ============================================\n\n /** Item container */\n popoverItem: 'data-blok-popover-item',\n /** Item icon wrapper */\n popoverItemIcon: 'data-blok-popover-item-icon',\n /** Chevron icon for nested items */\n popoverItemIconChevronRight: 'data-blok-popover-item-icon-chevron-right',\n /** Item title text */\n popoverItemTitle: 'data-blok-popover-item-title',\n /** Item secondary title */\n popoverItemSecondaryTitle: 'data-blok-popover-item-secondary-title',\n /** Item is active/selected */\n popoverItemActive: 'data-blok-popover-item-active',\n /** Confirmation state */\n popoverItemConfirmation: 'data-blok-popover-item-confirmation',\n /** Disable hover styling */\n popoverItemNoHover: 'data-blok-popover-item-no-hover',\n /** Disable focus handling */\n popoverItemNoFocus: 'data-blok-popover-item-no-focus',\n /** Destructive action item (e.g. delete) */\n popoverItemDestructive: 'data-blok-popover-item-destructive',\n /** Separator item */\n popoverItemSeparator: 'data-blok-popover-item-separator',\n /** Separator line element */\n popoverItemSeparatorLine: 'data-blok-popover-item-separator-line',\n /** HTML-based item */\n popoverItemHtml: 'data-blok-popover-item-html',\n /** Item has child menu */\n hasChildren: 'data-blok-has-children',\n /** Item name identifier */\n itemName: 'data-blok-item-name',\n /** No search results shown */\n nothingFoundDisplayed: 'data-blok-nothing-found-displayed',\n\n // ============================================\n // Overlay / Selection\n // ============================================\n\n /** Selection overlay */\n overlay: 'data-blok-overlay',\n /** Overlay container */\n overlayContainer: 'data-blok-overlay-container',\n /** Selection rectangle */\n overlayRectangle: 'data-blok-overlay-rectangle',\n /** Overlay is hidden */\n overlayHidden: 'data-blok-overlay-hidden',\n /** Fake cursor indicator */\n fakeCursor: 'data-blok-fake-cursor',\n /** Fake background for selection */\n fakeBackground: 'data-blok-fake-background',\n\n // ============================================\n // Scroll\n // ============================================\n\n /** Auto-scroll zone (top/bottom) */\n scrollZone: 'data-blok-scroll-zone',\n /** Scroll is locked */\n scrollLocked: 'data-blok-scroll-locked',\n /** Hard scroll lock */\n scrollLockedHard: 'data-blok-scroll-locked-hard',\n\n // ============================================\n // Caret\n // ============================================\n\n /** Shadow caret element */\n shadowCaret: 'data-blok-shadow-caret',\n\n // ============================================\n // Placeholders\n // ============================================\n\n /** Placeholder text */\n placeholder: 'data-blok-placeholder',\n /** Active placeholder text */\n placeholderActive: 'data-blok-placeholder-active',\n\n // ============================================\n // Nested Blocks\n // ============================================\n\n /** Container that hosts nested block holders (table cells, toggle/callout/header children).\n * Used as a universal guard: before moving a block holder via appendChild,\n * check `holder.closest([nestedBlocks])` — if truthy, the holder is already\n * claimed by another container and must not be stolen. */\n nestedBlocks: 'data-blok-nested-blocks',\n\n // ============================================\n // Mutation Tracking\n // ============================================\n\n /** Element excluded from mutation tracking */\n mutationFree: 'data-blok-mutation-free',\n\n // ============================================\n // Navigation\n // ============================================\n\n /** Block has navigation focus */\n navigationFocused: 'data-blok-navigation-focused',\n /** Flipper navigation target */\n flipperNavigationTarget: 'data-blok-flipper-navigation-target',\n\n // ============================================\n // Inline Toolbar\n // ============================================\n\n /** Inline toolbar enabled on external element */\n inlineToolbar: 'data-blok-inline-toolbar',\n\n // ============================================\n // Link Tool\n // ============================================\n\n /** Link tool is active */\n linkToolActive: 'data-blok-link-tool-active',\n /** Link tool unlink mode */\n linkToolUnlink: 'data-blok-link-tool-unlink',\n /** Link tool input is opened */\n linkToolInputOpened: 'data-blok-link-tool-input-opened',\n\n // ============================================\n // Bold Tool\n // ============================================\n\n /** Bold collapsed length tracking */\n boldCollapsedLength: 'data-blok-bold-collapsed-length',\n /** Bold collapsed active state */\n boldCollapsedActive: 'data-blok-bold-collapsed-active',\n /** Bold previous length tracking */\n boldPrevLength: 'data-blok-bold-prev-length',\n /** Bold leading whitespace */\n boldLeadingWs: 'data-blok-bold-leading-ws',\n /** Bold marker */\n boldMarker: 'data-blok-bold-marker',\n\n // ============================================\n // Tooltip\n // ============================================\n\n /** Tooltip is shown */\n shown: 'data-blok-shown',\n /** Tooltip placement */\n placement: 'data-blok-placement',\n\n // ============================================\n // Notifier\n // ============================================\n\n /** Bounce in animation */\n bounceIn: 'data-blok-bounce-in',\n\n // ============================================\n // Announcer (Accessibility)\n // ============================================\n\n /** Live region announcer */\n announcer: 'data-blok-announcer',\n\n // ============================================\n // Stub Block\n // ============================================\n\n /** Stub block element */\n stub: 'data-blok-stub',\n /** Stub info section */\n stubInfo: 'data-blok-stub-info',\n /** Stub title */\n stubTitle: 'data-blok-stub-title',\n /** Stub subtitle */\n stubSubtitle: 'data-blok-stub-subtitle',\n\n // ============================================\n // Slash Search\n // ============================================\n\n /** Slash search active on content editable */\n slashSearch: 'data-blok-slash-search',\n\n // ============================================\n // Testing\n // ============================================\n\n /** Test identifier (for E2E tests) */\n testid: 'data-blok-testid',\n /** Force hover state (for tests/storybook) */\n forceHover: 'data-blok-force-hover',\n} as const;\n\n/**\n * Type for DATA_ATTR keys\n */\nexport type DataAttrKey = keyof typeof DATA_ATTR;\n\n/**\n * Type for DATA_ATTR values\n */\nexport type DataAttrValue = (typeof DATA_ATTR)[DataAttrKey];\n\n/**\n * Helper function to create a CSS selector from an attribute\n *\n * @param attr - The data attribute name from DATA_ATTR\n * @param value - Optional value for the attribute (defaults to presence selector)\n * @returns CSS selector string\n *\n * @example\n * createSelector(DATA_ATTR.element) // '[data-blok-element]'\n * createSelector(DATA_ATTR.selected, true) // '[data-blok-selected=\"true\"]'\n * createSelector(DATA_ATTR.tool, 'paragraph') // '[data-blok-tool=\"paragraph\"]'\n */\nexport const createSelector = (attr: DataAttrValue, value?: string | boolean): string => {\n if (value === undefined) {\n return `[${attr}]`;\n }\n\n return `[${attr}=\"${value}\"]`;\n};\n","import { DATA_ATTR } from '../components/constants/data-attributes';\n\n/**\n * Mount child block holders into a container, skipping children that are\n * already in place or claimed by another nested-blocks container.\n *\n * Used by toggle, header, column, and callout tools to reconcile child holders\n * during the `rendered()` lifecycle hook.\n */\nexport const mountChildBlocks = (\n container: HTMLElement,\n children: { holder: HTMLElement }[],\n): void => {\n for (const child of children) {\n if (child.holder.parentElement === container) {\n continue;\n }\n\n const nested = child.holder.closest(`[${DATA_ATTR.nestedBlocks}]`);\n\n // Claim a holder stranded in the column_list ROW. A drag reparent into a\n // column drops the moved holder directly into the [data-blok-columns] row\n // (itself a nested-blocks container that wraps each column's own container).\n // Left there it renders as a rogue new column, so pull it down into THIS\n // column container where it belongs. Scoped to the column_list row\n // specifically — claiming from arbitrary ancestor containers would let one\n // table cell steal a paragraph transiently parked in an outer container.\n if (\n nested !== null &&\n nested !== container &&\n nested.hasAttribute('data-blok-columns') &&\n nested.contains(container)\n ) {\n container.appendChild(child.holder);\n continue;\n }\n\n // Otherwise leave holders that already live inside another nested container\n // (a sibling, or a deeper nesting within this one) where they are.\n if (nested !== null) {\n continue;\n }\n\n container.appendChild(child.holder);\n }\n};\n","import {\n ChangeDetectionStrategy,\n Component,\n EventEmitter,\n Input,\n NgZone,\n Output,\n ViewChild,\n computed,\n effect,\n forwardRef,\n inject,\n signal,\n type AfterViewInit,\n} from '@angular/core';\nimport { NG_VALUE_ACCESSOR, type ControlValueAccessor } from '@angular/forms';\nimport { BlokContentDirective } from './blok-content.directive';\nimport { BLOK_DEFAULT_CONFIG } from './provide-blok';\nimport { deepEqual } from '../adapters-contract';\nimport { normalizeReadOnlyConfig } from '../adapters-contract';\nimport { toRenderableData } from '../adapters-contract';\nimport type {\n API,\n Blok,\n BlockMutationEvent,\n BlockRenderedPayload,\n BlocksRenderedPayload,\n BlokConfig,\n EditorWidth,\n LooseOutputData,\n OutputBlockData,\n OutputData,\n ResolvedTheme,\n ThemeMode,\n} from '@bloklabs/core';\nimport type { BlokAngularConfig } from './types';\n\n/**\n * The blessed all-in-one Angular component for embedding Blok (mirrors React's\n * `BlokEditor`). Delegates instance lifecycle to an internal `BlokContentDirective`\n * and layers the typed reactive input/output API on top.\n *\n * Reactive inputs (`readOnly`, `hideToolbar`, `inlineToolbar`, `theme`,\n * `width`, `placeholder`, `autofocus`, `styleTokens`, `i18n`, `data`) are\n * synced in place after mount via effects — `hideToolbar` through\n * `editor.toolbar.setHidden()`, `inlineToolbar` through\n * `editor.tools.setInlineToolbar()` (content-compared),\n * `styleTokens` through `editor.tokens.set()` (replace semantics),\n * `i18n` through `editor.i18n.update()` (deep-equal–deduped; seeded at\n * construction so the locale resolves during boot) and `data`\n * through `editor.render()` (deep-equal–deduped); everything else seeds\n * construction.\n *\n * Implementation note: classic `@Input()`/`@ViewChild()` decorators are used\n * (not signal `input()`/`viewChild()`) for JIT compatibility — see\n * `BlokContentDirective`. Each reactive input is backed by an internal `signal`\n * so effect-based syncing still works; the public template API is unchanged.\n */\n@Component({\n selector: 'blok-editor',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n exportAs: 'blok',\n imports: [BlokContentDirective],\n template: `<div blokContent [config]=\"buildConfig()\" [recreateKey]=\"recreateKey\"></div>`,\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => BlokEditorComponent),\n multi: true,\n },\n ],\n})\nexport class BlokEditorComponent implements AfterViewInit, ControlValueAccessor {\n private readonly ngZone = inject(NgZone);\n /** App-wide defaults from `provideBlok()`; merged UNDER per-instance inputs. */\n private readonly defaults = inject(BLOK_DEFAULT_CONFIG, { optional: true }) ?? {};\n\n @ViewChild(BlokContentDirective) private contentQuery?: BlokContentDirective;\n /** Signal bridge for the @ViewChild directive so effects react to its arrival. */\n private readonly content = signal<BlokContentDirective | null>(null);\n\n /**\n * Output half of two-way `[(data)]`. Emits the editor's serialized content on\n * every change. Wiring the core `onSave` callback is gated on this being\n * observed, since its mere presence makes the core serialize on every batch.\n */\n /** Emits the live Blok instance once ready, after `instance()` is populated. */\n @Output() readonly ready = new EventEmitter<Blok>();\n\n @Output() readonly dataChange = new EventEmitter<OutputData>();\n\n /** Fires with the full serialized content on every change (notification half). */\n @Output() readonly save = new EventEmitter<OutputData>();\n\n /** Raw block mutation channel (core `onChange`). */\n @Output() readonly change = new EventEmitter<{\n api: API;\n event: BlockMutationEvent | BlockMutationEvent[];\n }>();\n\n /** Fires after the editor finishes (re-)rendering (core `onAfterRender`). */\n @Output() readonly afterRender = new EventEmitter<API>();\n\n /** Fires with the resolved theme whenever it changes (core `onThemeChange`). */\n @Output() readonly themeChange = new EventEmitter<ResolvedTheme>();\n\n /** Fires after a batch render completes (core `blocks:rendered` event). */\n @Output() readonly blocksRendered = new EventEmitter<BlocksRenderedPayload>();\n\n /** Fires for each block rendered into the DOM (core `block:rendered` event). */\n @Output() readonly blockRendered = new EventEmitter<BlockRenderedPayload>();\n\n /**\n * Transform hook applied to blocks before render (core `onBeforeRender`). Must\n * return the (possibly modified) block list. An input, not an output, because\n * it returns a value.\n */\n @Input() onBeforeRender?: (blocks: OutputBlockData[]) => OutputBlockData[];\n\n /**\n * Transform hook applied to pasted HTML (core `onBeforePaste`). Returns the\n * (possibly modified) html, or null to drop the paste.\n */\n @Input() onBeforePaste?: (html: string) => string | null;\n\n /**\n * Error channel (core `onError`). Fires with the raised error whenever an\n * editor operation — currently serialization — fails instead of only logging.\n */\n @Input() onError?: BlokConfig['onError'];\n\n // ---- Reactive inputs (signal-backed setters; synced in place, never recreate) ----\n // Default undefined (not false) so an unset input falls back to a provideBlok\n // default; the readOnly effect / buildConfig coerce undefined to false.\n // Accepts the object form (`{ hideControls }`) too — it flows through\n // buildConfig unchanged and the effect expands it to\n // `readOnly.set(enabled, { hideControls })`.\n private readonly readOnly$ = signal<BlokConfig['readOnly'] | undefined>(undefined);\n @Input() set readOnly(value: BlokConfig['readOnly'] | undefined) {\n this.readOnly$.set(value);\n }\n\n private readonly hideToolbar$ = signal<boolean | undefined>(undefined);\n @Input() set hideToolbar(value: boolean | undefined) {\n this.hideToolbar$.set(value);\n }\n\n private readonly inlineToolbar$ = signal<boolean | string[] | undefined>(undefined);\n @Input() set inlineToolbar(value: boolean | string[] | undefined) {\n this.inlineToolbar$.set(value);\n }\n\n private readonly theme$ = signal<ThemeMode | undefined>(undefined);\n @Input() set theme(value: ThemeMode | undefined) {\n this.theme$.set(value);\n }\n\n private readonly width$ = signal<EditorWidth | undefined>(undefined);\n @Input() set width(value: EditorWidth | undefined) {\n this.width$.set(value);\n }\n\n private readonly placeholder$ = signal<string | false | undefined>(undefined);\n @Input() set placeholder(value: string | false | undefined) {\n this.placeholder$.set(value);\n }\n\n /**\n * Theme tokens. Construction-only config forced hosts with a live light/dark\n * toggle to recreate the editor or hand-write the global stylesheet Blok\n * already injects; this drives the runtime `tokens` API instead.\n */\n private readonly styleTokens$ = signal<Record<string, string> | undefined>(undefined);\n @Input() set styleTokens(value: Record<string, string> | undefined) {\n this.styleTokens$.set(value);\n }\n\n /**\n * Locale, host message overrides and text direction. `config.i18n` was\n * consumed once at boot, so a host driving a language switcher had to\n * recreate the editor (losing caret, focus and undo stack) to relabel the\n * UI; this drives the runtime `i18n.update` API instead. `defaultLocale` is\n * not forwarded — it only affects the INITIAL locale resolution.\n */\n private readonly i18n$ = signal<BlokConfig['i18n'] | undefined>(undefined);\n @Input() set i18n(value: BlokConfig['i18n'] | undefined) {\n this.i18n$.set(value);\n }\n\n private readonly autofocus$ = signal<boolean | undefined>(false);\n @Input() set autofocus(value: boolean | undefined) {\n this.autofocus$.set(value);\n }\n\n // ---- Reactive content (seeds construction, then re-renders on change) ----\n private readonly data$ = signal<OutputData | LooseOutputData | null | undefined>(undefined);\n @Input() set data(value: OutputData | LooseOutputData | null | undefined) {\n this.data$.set(value);\n }\n\n // ---- Construction-only seed inputs (read once at construction) ----\n @Input() tools?: BlokConfig['tools'];\n\n /**\n * Escape hatch: a full config object for keys without a dedicated input\n * (sanitizer, minHeight, …). Layered between provideBlok\n * defaults and the discrete inputs.\n */\n @Input() config?: Partial<BlokAngularConfig>;\n\n /** Changing this input's identity destroys and recreates the editor (≙ React `deps`). */\n @Input() recreateKey: unknown;\n\n /**\n * Content the editor currently reflects. Set when seeded or rendered (the data\n * effect below). A controlled `data` echo that deep-equals this baseline is a\n * no-op, so it won't clobber the caret. Renders are serialized via `renderChain`.\n */\n private lastRenderedData?: OutputData | LooseOutputData | null;\n\n /** Last token set pushed through `tokens.set`, for deep-equal deduping. */\n private appliedTokens?: Record<string, string>;\n /** Last i18n config pushed through `i18n.update`, for deep-equal deduping. */\n private appliedI18n?: BlokConfig['i18n'];\n /** Editor instance the i18n baseline above belongs to. */\n private i18nAppliedFor: Blok | null = null;\n /** Last value pushed through `tools.setInlineToolbar`, for content-compare deduping. */\n private appliedInlineToolbar?: boolean | string[];\n private seededEditor: Blok | null = null;\n private renderChain: Promise<void> = Promise.resolve();\n\n /** Registered by `ControlValueAccessor.registerOnChange` (Angular forms). */\n private cvaOnChange?: (data: OutputData) => void;\n private cvaOnTouched?: () => void;\n\n /**\n * Core `onSave` wrapper. Records the editor's own serialized output as the\n * rendered baseline BEFORE notifying Angular, so a controlled consumer echoing\n * it straight back into `data` deep-equals the baseline and is deduped to a\n * no-op (no redundant render, no caret reset). Re-enters the Angular zone since\n * the editor runs outside it.\n */\n private readonly coreOnSave = (data: OutputData): void => {\n this.lastRenderedData = data;\n this.ngZone.run(() => {\n this.dataChange.emit(data);\n this.save.emit(data);\n this.cvaOnChange?.(data);\n this.cvaOnTouched?.();\n });\n };\n\n /** Live Blok instance, or null until `isReady` resolves / after destroy. */\n readonly instance = computed<Blok | null>(() => this.content()?.instance() ?? null);\n\n /** Guards `ready` to one emission per editor instance. */\n private lastReadyInstance: Blok | null = null;\n\n /**\n * Construction config handed to the directive. Seeds the editor's initial\n * values; the directive only reads it once (at construction), so post-mount\n * changes to construction-only inputs are no-ops by design.\n */\n buildConfig(): Partial<BlokAngularConfig> {\n // Precedence: provideBlok defaults < [config] escape hatch < discrete inputs.\n const cfg: Partial<BlokAngularConfig> = { ...this.defaults, ...this.config };\n\n // The object form ({ hideControls }) is preserved as-is; the readOnly\n // effect expands it into `readOnly.set(enabled, { hideControls })`.\n cfg.readOnly = this.readOnly$() ?? this.config?.readOnly ?? this.defaults.readOnly ?? false;\n\n const hideToolbar = this.hideToolbar$();\n\n if (hideToolbar !== undefined) {\n cfg.hideToolbar = hideToolbar;\n }\n\n const inlineToolbar = this.inlineToolbar$();\n\n if (inlineToolbar !== undefined) {\n cfg.inlineToolbar = inlineToolbar;\n }\n\n // tools registries are MERGED (not replaced) across all three layers so a\n // shared registry composes with per-instance additions.\n if (\n this.tools !== undefined ||\n this.config?.tools !== undefined ||\n this.defaults.tools !== undefined\n ) {\n cfg.tools = { ...this.defaults.tools, ...this.config?.tools, ...this.tools };\n }\n\n const data = this.data$();\n\n if (data !== undefined) {\n cfg.data = data;\n }\n\n const theme = this.theme$();\n\n if (theme !== undefined) {\n cfg.theme = theme;\n }\n\n const width = this.width$();\n\n if (width !== undefined) {\n cfg.width = width;\n }\n\n const placeholder = this.placeholder$();\n\n if (placeholder !== undefined) {\n cfg.placeholder = placeholder;\n }\n\n // Seeded at construction (not applied by the i18n effect) so the locale is\n // resolved during boot instead of flashing the default language first.\n const i18n = this.i18n$();\n\n if (i18n !== undefined) {\n cfg.i18n = i18n;\n }\n\n // Opt-in: only attach each core callback when the consumer actually consumes\n // it (an observed output, a registered forms hook, or a provided transform).\n // Their mere presence makes the core serialize / run hooks on every change.\n if (this.dataChange.observed || this.save.observed || this.cvaOnChange !== undefined) {\n cfg.onSave = this.coreOnSave;\n }\n\n if (this.change.observed) {\n cfg.onChange = (api: API, event: BlockMutationEvent | BlockMutationEvent[]): void =>\n this.ngZone.run(() => this.change.emit({ api, event }));\n }\n\n if (this.afterRender.observed) {\n cfg.onAfterRender = (api: API): void => this.ngZone.run(() => this.afterRender.emit(api));\n }\n\n if (this.themeChange.observed) {\n cfg.onThemeChange = (resolved: ResolvedTheme): void =>\n this.ngZone.run(() => this.themeChange.emit(resolved));\n }\n\n // Transforms run synchronously inside core's render/paste pipeline and must\n // return a value — never wrap them in ngZone.run.\n const beforeRender = this.onBeforeRender;\n\n if (beforeRender !== undefined) {\n cfg.onBeforeRender = (blocks: OutputBlockData[]): OutputBlockData[] => beforeRender(blocks);\n }\n\n const beforePaste = this.onBeforePaste;\n\n if (beforePaste !== undefined) {\n cfg.onBeforePaste = (html: string): string | null => beforePaste(html);\n }\n\n const onError = this.onError;\n\n if (onError !== undefined) {\n cfg.onError = onError;\n }\n\n return cfg;\n }\n\n ngAfterViewInit(): void {\n this.content.set(this.contentQuery ?? null);\n }\n\n // ---- Curated imperative facade (delegates to the live instance; no-ops until ready) ----\n\n /** Serialize the current content. Resolves undefined until the editor is ready. */\n save$(): Promise<OutputData> | undefined {\n return this.instance()?.save();\n }\n\n /** Move the caret into the editor. */\n focus(atEnd?: boolean): void {\n this.instance()?.focus(atEnd);\n }\n\n /** Replace the editor content. Resolves undefined until the editor is ready. */\n render(data: OutputData | LooseOutputData): Promise<void> | undefined {\n return this.instance()?.render(data);\n }\n\n constructor() {\n // Each effect reads `instance()` so it re-applies once the editor appears\n // (the Angular analog of React's `editor` effect-dependency).\n effect(() => {\n const editor = this.instance();\n const readOnly = this.readOnly$() ?? this.config?.readOnly;\n\n if (editor) {\n const { enabled, hideControls } = normalizeReadOnlyConfig(readOnly);\n\n // Only the object form carries options; the boolean form keeps the\n // one-argument call so it never clobbers a config-seeded hideControls.\n if (typeof readOnly === 'object' && readOnly !== null) {\n void editor.readOnly.set(enabled, { hideControls });\n } else {\n void editor.readOnly.set(enabled);\n }\n }\n });\n\n effect(() => {\n const editor = this.instance();\n const hideToolbar = this.hideToolbar$();\n\n if (editor && hideToolbar !== undefined) {\n editor.toolbar.setHidden(hideToolbar);\n }\n });\n\n // Content-compared (not identity): a new array with the same tool names is\n // a no-op, so template-inline array literals don't thrash the assignment.\n effect(() => {\n const editor = this.instance();\n const inlineToolbar = this.inlineToolbar$();\n\n if (\n !editor ||\n inlineToolbar === undefined ||\n deepEqual(inlineToolbar, this.appliedInlineToolbar)\n ) {\n return;\n }\n\n this.appliedInlineToolbar = Array.isArray(inlineToolbar) ? [...inlineToolbar] : inlineToolbar;\n editor.tools.setInlineToolbar(inlineToolbar);\n });\n\n effect(() => {\n const editor = this.instance();\n const theme = this.theme$();\n\n if (editor && theme !== undefined) {\n editor.theme.set(theme);\n }\n });\n\n effect(() => {\n const editor = this.instance();\n const width = this.width$();\n\n if (editor && width !== undefined) {\n editor.width.set(width);\n }\n });\n\n effect(() => {\n const editor = this.instance();\n const placeholder = this.placeholder$();\n\n if (editor && placeholder !== undefined) {\n editor.placeholder.set(placeholder);\n }\n });\n\n effect(() => {\n const editor = this.instance();\n const tokens = this.styleTokens$() ?? this.config?.style?.tokens;\n\n if (!editor || tokens === undefined || deepEqual(tokens, this.appliedTokens)) {\n return;\n }\n\n this.appliedTokens = { ...tokens };\n editor.tokens.set(tokens);\n });\n\n effect(() => {\n const editor = this.instance();\n const i18n = this.i18n$() ?? this.config?.i18n;\n\n if (!editor) {\n return;\n }\n\n /*\n * A freshly constructed editor already resolved this config during its\n * own boot (buildConfig seeds it), so record the baseline and push\n * nothing — re-applying it here would reload the locale after mount and\n * flash the default language.\n */\n if (this.i18nAppliedFor !== editor) {\n this.i18nAppliedFor = editor;\n this.appliedI18n = i18n === undefined ? undefined : { ...i18n };\n\n return;\n }\n\n if (i18n === undefined || deepEqual(i18n, this.appliedI18n)) {\n return;\n }\n\n this.appliedI18n = { ...i18n };\n\n const { locale, messages, direction } = i18n;\n\n void editor.i18n.update({\n ...(locale === undefined ? {} : { locale }),\n ...(messages === undefined ? {} : { messages }),\n ...(direction === undefined ? {} : { direction }),\n });\n });\n\n effect(() => {\n const editor = this.instance();\n\n if (editor && this.autofocus$()) {\n editor.focus();\n }\n });\n\n // Reactive content. `data` seeds the editor at construction; afterwards a new\n // *content* value re-renders via the public render() API (deep-equal-deduped\n // and serialized, so an unchanged reference — including the editor's own\n // echoed output — is a no-op and never clobbers the caret).\n effect(() => {\n const editor = this.instance();\n const data = this.data$();\n\n if (!editor || data === undefined) {\n return;\n }\n\n // A freshly created editor was already seeded with `data` at construction;\n // record it without re-rendering.\n if (this.seededEditor !== editor) {\n this.seededEditor = editor;\n this.lastRenderedData = data;\n\n return;\n }\n\n if (deepEqual(data, this.lastRenderedData)) {\n return;\n }\n\n this.lastRenderedData = data;\n // `data` may be null (a controlled \"clear to empty\"); render() throws on\n // null, so normalize null → { blocks: [] } at the boundary.\n this.renderChain = this.renderChain.catch(() => undefined).then(() => editor.render(toRenderableData(data)));\n });\n\n // Emit `ready` once per editor, after `instance()` is populated so a consumer\n // reading the component/ref instance inside the handler sees it.\n effect(() => {\n const editor = this.instance();\n\n if (editor && editor !== this.lastReadyInstance) {\n this.lastReadyInstance = editor;\n this.ready.emit(editor);\n }\n });\n\n // Subscribe to the editor's rendered-lifecycle events once it exists (gated on\n // the outputs being observed). `onCleanup` unsubscribes when the instance is\n // replaced or the component is destroyed.\n effect((onCleanup) => {\n const editor = this.instance();\n\n if (!editor) {\n return;\n }\n\n const handlers: Array<[string, (payload?: unknown) => void]> = [];\n\n if (this.blocksRendered.observed) {\n const handler = (payload?: unknown): void =>\n this.ngZone.run(() => this.blocksRendered.emit(payload as BlocksRenderedPayload));\n\n editor.on('blocks:rendered', handler);\n handlers.push(['blocks:rendered', handler]);\n }\n\n if (this.blockRendered.observed) {\n const handler = (payload?: unknown): void =>\n this.ngZone.run(() => this.blockRendered.emit(payload as BlockRenderedPayload));\n\n editor.on('block:rendered', handler);\n handlers.push(['block:rendered', handler]);\n }\n\n onCleanup(() => {\n for (const [name, handler] of handlers) {\n editor.off(name, handler);\n }\n });\n });\n }\n\n // ---- ControlValueAccessor (optional forms integration) ----\n\n /** Seeds/renders an externally-set form value through the same dedup machinery. */\n writeValue(value: OutputData | LooseOutputData | null): void {\n this.data$.set(value ?? undefined);\n }\n\n registerOnChange(fn: (data: OutputData) => void): void {\n this.cvaOnChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.cvaOnTouched = fn;\n }\n\n /** Form disabled state maps to the editor's read-only mode (via the readOnly effect). */\n setDisabledState(isDisabled: boolean): void {\n this.readOnly$.set(isDisabled);\n }\n}\n","import type { BlockAPI, BlockToolConstructorOptions, BlockToolData, ToolboxConfig } from '@bloklabs/core';\n// packages/angular/src/createAngularBlock.ts\nimport { signal, type Type, type WritableSignal } from '@angular/core';\n\nimport { DATA_ATTR } from '../adapters-contract';\nimport { deepEqual } from '../adapters-contract';\nimport { fillDefaults, type PropSchema } from '../adapters-contract';\nimport { mountChildBlocks } from '../adapters-contract';\n\nimport type { AngularBlockRenderContext } from './block-context';\nimport { BLOK_PORTAL_REGISTRY_CONFIG_KEY, type BlockPortalRegistry } from './block-portal-registry';\n\n/** Spec for {@link createAngularBlock}. Authored as a standalone component. */\nexport interface CreateAngularBlockSpec<Data = BlockToolData> {\n /** Tool type name (registered key). */\n type: string;\n /** Optional toolbox entry. */\n toolbox?: ToolboxConfig;\n /** Declarative defaults that also define the exact `save()` key set. */\n propSchema: PropSchema;\n /**\n * The standalone Angular component to render for each block. It injects the\n * per-block context via `inject(BLOK_BLOCK_CONTEXT)`.\n */\n component: Type<unknown>;\n /** Optional lifecycle callbacks mapped from Blok's block hooks. */\n onRendered?: (block: BlockAPI) => void;\n onMoved?: (block: BlockAPI) => void;\n onRemoved?: (block: BlockAPI) => void;\n}\n\n/**\n * Author a first-party Angular block. Returns a `BlockToolConstructable`\n * registered exactly like a vanilla tool (`tools: { type: { class:\n * createAngularBlock(...) } }`).\n *\n * The factory owns the host element (`data-blok-mutation-free`), a frozen\n * defaults-filled data mirror, and signals the component reads. It mounts the\n * component into the host via the editor's shared portal registry (the analog of\n * Vue's Teleport registry), bridging Blok's block lifecycle to Angular:\n * - `render()` creates the host and registers the portal entry (mounted sync).\n * - `setData()` dedups, swaps the reactive snapshot, flushes CD, resolves true.\n * - `save()` returns the complete frozen mirror (never the DOM, never partial).\n * - `commit()` merges a patch and fires `dispatchChange` exactly once.\n * - `setReadOnly()` flips a reactive flag and flushes CD (in-place, no remount).\n * - `removed()`/`destroy()` unregister the portal (deterministic unmount).\n */\nexport function createAngularBlock<Data = BlockToolData>(\n spec: CreateAngularBlockSpec<Data>\n): (new (options: BlockToolConstructorOptions) => {\n render(): HTMLElement;\n save(): BlockToolData;\n setData(newData: BlockToolData): Promise<boolean>;\n setReadOnly(state: boolean): void;\n rendered(): void;\n moved(): void;\n removed(): void;\n destroy(): void;\n}) & {\n readonly __isBlokAngularBlock: true;\n readonly toolbox: ToolboxConfig | undefined;\n readonly isReadOnlySupported: boolean;\n} {\n return class AngularBlockTool {\n /** Marker so the directive can detect Angular-block tools and inject the registry. */\n public static readonly __isBlokAngularBlock = true as const;\n\n public static get toolbox(): ToolboxConfig | undefined {\n return spec.toolbox;\n }\n\n /**\n * Angular blocks support read-only mode: `setReadOnly` flips a reactive flag\n * the component reads, so the block re-renders read-only IN PLACE. Without\n * this static, core's ReadOnly module throws when read-only is enabled and an\n * Angular block is present.\n */\n public static get isReadOnlySupported(): boolean {\n return true;\n }\n\n private readonly blockApi: BlockAPI;\n private readonly registry: BlockPortalRegistry | undefined;\n private readonly pointerDrag: () => boolean;\n private readonly dataSig: WritableSignal<Readonly<Data>>;\n private readonly readOnlySig: WritableSignal<boolean>;\n private readonly ctx: AngularBlockRenderContext<Data>;\n private mirror: Readonly<Data>;\n /** Dedup baseline: skip a redundant flush of identical data. */\n private lastRendered: Readonly<Data>;\n private hostEl: HTMLElement | null = null;\n /** Last host passed to ctx.mountChildren, re-mounted on each data change. */\n private childHost: HTMLElement | null = null;\n /** True while a pointer drag suppresses dispatchChange. */\n private pendingDispatch = false;\n\n public constructor(options: BlockToolConstructorOptions) {\n this.blockApi = options.block;\n\n const config = (options.config ?? {}) as Record<string, unknown>;\n\n this.registry = config[BLOK_PORTAL_REGISTRY_CONFIG_KEY] as BlockPortalRegistry | undefined;\n\n // Read the LIVE pointer-drag flag so a mid-drag commit can be deferred\n // (core silently drops a dispatchChange while a drag is active).\n const api = options.api as unknown as { blocks?: { isPointerDragActive?: boolean } } | undefined;\n\n this.pointerDrag = (): boolean => api?.blocks?.isPointerDragActive === true;\n\n this.mirror = fillDefaults<Data>(spec.propSchema, (options.data ?? {}) as Record<string, unknown>);\n this.lastRendered = this.mirror;\n this.dataSig = signal(this.mirror);\n this.readOnlySig = signal(options.readOnly);\n\n this.ctx = {\n data: this.dataSig.asReadonly(),\n commit: this.commit,\n block: this.blockApi,\n readOnly: this.readOnlySig.asReadonly(),\n mountChildren: this.mountChildren,\n };\n }\n\n public render(): HTMLElement {\n const host = document.createElement('div');\n\n // Core's MutationObserver ignores this subtree, so Angular's DOM writes\n // never register as a user edit.\n host.setAttribute('data-blok-mutation-free', 'true');\n this.hostEl = host;\n\n this.registry?.register(this.blockApi.id, {\n hostEl: host,\n component: spec.component,\n context: this.ctx as AngularBlockRenderContext<unknown>,\n });\n\n return host;\n }\n\n public rendered(): void {\n spec.onRendered?.(this.blockApi);\n }\n\n public save(): BlockToolData {\n return this.mirror as BlockToolData;\n }\n\n public async setData(newData: BlockToolData): Promise<boolean> {\n const next = fillDefaults<Data>(spec.propSchema, (newData ?? {}) as Record<string, unknown>);\n\n // Dedup: identical data → skip the flush, but still return true so core\n // keeps the block in place (no remount).\n if (deepEqual(next, this.lastRendered)) {\n return true;\n }\n\n this.mirror = next;\n this.lastRendered = next;\n this.dataSig.set(next);\n // Synchronous CD: core drives setData outside NgZone, so nothing else\n // schedules a render. Never throw (a throw would make core remount).\n this.registry?.flush(this.blockApi.id);\n this.remountChildren();\n\n // Resolve after a microtask for interface symmetry with the async core\n // setData contract; CD has already flushed synchronously above.\n await Promise.resolve();\n\n return true;\n }\n\n /**\n * In-place read-only toggle. Flips the reactive flag the component reads via\n * `ctx.readOnly`, then flushes CD so the block re-renders read-only WITHOUT a\n * remount (ephemeral state survives). A prototype method (not an arrow field)\n * so core's `supportsInPlaceReadOnly` — which probes the PROTOTYPE — selects\n * the in-place path.\n */\n public setReadOnly(state: boolean): void {\n this.readOnlySig.set(state);\n this.registry?.flush(this.blockApi.id);\n }\n\n public moved(): void {\n // No remount: core relocates the host element; the mounted view rides along\n // as its DOM children.\n spec.onMoved?.(this.blockApi);\n }\n\n public removed(): void {\n this.registry?.unregister(this.blockApi.id);\n spec.onRemoved?.(this.blockApi);\n }\n\n public destroy(): void {\n // Idempotent with removed(); unregister is safe when already absent.\n this.registry?.unregister(this.blockApi.id);\n }\n\n /** Container blocks: remember the host and (re)mount the real child holders. */\n private readonly mountChildren = (host: HTMLElement): void => {\n this.childHost = host;\n host.setAttribute(DATA_ATTR.nestedBlocks, '');\n this.remountChildren();\n };\n\n private remountChildren(): void {\n if (this.childHost !== null) {\n mountChildBlocks(this.childHost, this.blockApi.getChildren());\n }\n }\n\n /**\n * The only data write path. Merges the patch into the frozen mirror, swaps\n * the reactive snapshot, flushes CD, and fires dispatchChange EXACTLY once —\n * deferring it while a pointer drag is active (core would otherwise silently\n * drop it).\n */\n private readonly commit = (patch: Partial<Data>): void => {\n const next = fillDefaults<Data>(spec.propSchema, {\n ...(this.mirror as Record<string, unknown>),\n ...(patch as Record<string, unknown>),\n });\n\n // Idempotent: a patch that changes nothing is a full no-op — no signal\n // swap, no CD flush, no dispatchChange — so an effect echoing the current\n // value back through commit can never loop.\n if (deepEqual(next, this.mirror)) {\n return;\n }\n\n this.mirror = next;\n this.lastRendered = next;\n this.dataSig.set(next);\n this.registry?.flush(this.blockApi.id);\n this.remountChildren();\n this.flushDispatch();\n };\n\n /** Dispatch the change, or retry on the next frame if a drag is in progress. */\n private flushDispatch(): void {\n if (!this.pointerDrag()) {\n this.pendingDispatch = false;\n this.blockApi.dispatchChange();\n\n return;\n }\n\n if (this.pendingDispatch) {\n return;\n }\n\n this.pendingDispatch = true;\n\n const retry = (): void => {\n if (this.pointerDrag()) {\n requestAnimationFrame(retry);\n\n return;\n }\n\n this.pendingDispatch = false;\n this.blockApi.dispatchChange();\n };\n\n requestAnimationFrame(retry);\n }\n };\n}\n","import type { Blok } from '@bloklabs/core';\n// packages/angular/src/useBlocks.ts\nimport { DestroyRef, effect, inject, signal, type Signal } from '@angular/core';\n\nimport { createBlocksApiForEditor, EMPTY_API } from '../adapters-contract';\n\nimport type { UseBlocksApi } from './blocks-snapshot';\n\nconst BLOCK_CHANGED_EVENT = 'block changed';\n\n/**\n * Angular factory exposing an id/parentId-relative, reactive view of the block\n * tree. Reads refresh whenever the editor emits `block changed`; mutators route\n * through the editor-level `blocks` API (core's chokepoints), so undo/redo and\n * Yjs sync are inherited rather than re-implemented.\n *\n * The block-tree logic is framework-agnostic and lives in the shared\n * {@link createBlocksApiForEditor} core — the SAME implementation behind React's\n * and Vue's `useBlocks`, so all three adapters expose the identical 28-method\n * surface and cannot drift. This wrapper supplies only Angular's reactivity:\n *\n * - A private `version` signal is bumped on every `block changed`. The shared API\n * is built with an `onRead` seam (`() => { version() }`) that every read method\n * calls, so reading inside a `computed`/template tracks `version` and re-runs on\n * each structural mutation.\n * - The bound API is rebuilt (via `bindToEditor`, called eagerly on first call and\n * then tracked by an `effect` for subsequent identity changes) when the editor\n * IDENTITY changes; the returned facade is stable across that swap.\n *\n * Call it in an injection context (component constructor / field initializer),\n * passing the editor signal (e.g. `BlokEditorComponent.instance` /\n * `BlokContentDirective.instance`). Pre-ready (editor null) the bound API is the\n * shared {@link EMPTY_API}: every mutator a no-op, reads empty/null — except\n * `transact`/`transactWithoutCapture`, which still run their callback.\n *\n * Note: Angular 20's `effect()` is scheduled (not eager) — it does not fire\n * synchronously on first call. The initial binding therefore runs synchronously\n * in the `injectBlocks` body itself (mirroring Vue's `{ immediate: true }` watch),\n * and the effect re-binds only on subsequent editor identity changes. When the\n * effect fires for the first time with the same editor already bound, the guard\n * `ed === sub.editor` makes it a no-op, so no double-subscription occurs.\n *\n * @param editor - a signal of the Blok instance, or null pre-ready\n */\nexport function injectBlocks(editor: Signal<Blok | null>): UseBlocksApi {\n // Bumped on every `block changed`; the shared API's read methods touch it (via\n // the onRead seam) so template/computed reads stay reactive.\n const version = signal(0);\n const touch = (): void => {\n version();\n };\n\n // The API bound to the CURRENT editor; EMPTY_API while null. A signal so the\n // facade's reads track the editor-identity swap.\n const bound = signal<UseBlocksApi>(EMPTY_API);\n\n // One subscription record (no `let` reassignment), re-bound on editor change.\n const sub: { editor: Blok | null; handler: (() => void) | null } = { editor: null, handler: null };\n\n const unsubscribe = (): void => {\n if (sub.editor !== null && sub.handler !== null) {\n sub.editor.off(BLOCK_CHANGED_EVENT, sub.handler);\n }\n sub.editor = null;\n sub.handler = null;\n };\n\n /**\n * Bind to `ed` if the identity has changed. Guards `ed === sub.editor` so a\n * deferred first effect-run with the same editor already bound is a no-op\n * (no double-subscription). Called synchronously on first call (immediate\n * binding) and then re-tracked by the effect below (future identity changes).\n */\n const bindToEditor = (ed: Blok | null): void => {\n if (ed === sub.editor) {\n return; // Same editor already bound; nothing to do.\n }\n\n unsubscribe();\n // A changed editor identity is itself a reason to re-read.\n version.update((v) => v + 1);\n\n if (ed === null) {\n bound.set(EMPTY_API);\n\n return;\n }\n\n const handler = (): void => {\n version.update((v) => v + 1);\n };\n\n ed.on(BLOCK_CHANGED_EVENT, handler);\n sub.editor = ed;\n sub.handler = handler;\n bound.set(createBlocksApiForEditor(ed, touch));\n };\n\n // Run the initial binding SYNCHRONOUSLY so the returned facade is immediately\n // usable (Angular's effect() is deferred — it does not fire on the same tick).\n // This mirrors Vue's `watch(..., { immediate: true })`.\n bindToEditor(editor());\n\n // Re-bind when the editor identity changes. Angular 20 permits signal writes\n // inside effect() by default (allowSignalWrites option was removed in v20).\n effect(() => {\n bindToEditor(editor());\n });\n\n inject(DestroyRef).onDestroy(unsubscribe);\n\n // A stable facade whose methods delegate to the currently-bound API. Reading\n // `bound()` tracks the editor swap; shared reads track `version` via onRead.\n // Every key listed EXPLICITLY (no spread) so a forgotten delegation is a\n // COMPILE error against UseBlocksApi rather than a silently-missing method.\n return {\n getById: (id) => bound().getById(id),\n getChildren: (parentId) => bound().getChildren(parentId),\n insert: (spec) => bound().insert(spec),\n insertMany: (specs) => bound().insertMany(specs),\n insertTree: (spec) => bound().insertTree(spec),\n insertMarkdown: (markdown, options) => bound().insertMarkdown(markdown, options),\n exportMarkdown: () => bound().exportMarkdown(),\n move: (id, target) => bound().move(id, target),\n nest: (id, parentId) => bound().nest(id, parentId),\n unnest: (id) => bound().unnest(id),\n remove: (id) => bound().remove(id),\n update: (id, data, tunes) => bound().update(id, data, tunes),\n convert: (id, newType, dataOverrides, options) => bound().convert(id, newType, dataOverrides, options),\n transact: (fn) => bound().transact(fn),\n transactWithoutCapture: (fn) => bound().transactWithoutCapture(fn),\n getBlocksCount: () => bound().getBlocksCount(),\n getCurrentBlockIndex: () => bound().getCurrentBlockIndex(),\n getBlockByIndex: (index) => bound().getBlockByIndex(index),\n getBlockByElement: (element) => bound().getBlockByElement(element),\n getBlockData: (id) => bound().getBlockData(id),\n getBlockIndex: (id) => bound().getBlockIndex(id),\n composeBlockData: (toolName) => bound().composeBlockData(toolName),\n renderFromHTML: (html) => bound().renderFromHTML(html),\n insertOutputData: (blocks, options) => bound().insertOutputData(blocks, options),\n splitBlock: (currentBlockId, currentBlockData, newBlockType, newBlockData, insertIndex) =>\n bound().splitBlock(currentBlockId, currentBlockData, newBlockType, newBlockData, insertIndex),\n insertInsideParent: (parentId, insertIndex, childData) =>\n bound().insertInsideParent(parentId, insertIndex, childData),\n render: (data) => bound().render(data),\n clear: () => bound().clear(),\n isSyncingFromYjs: () => bound().isSyncingFromYjs(),\n };\n}\n","// packages/angular/src/useBlokReady.ts\nimport { DestroyRef, ElementRef, afterNextRender, inject, signal, type Signal } from '@angular/core';\n\nimport { Blok as BlokRuntime } from '@bloklabs/core';\n\n/** How the caller names the DOM scope to observe. */\nexport type BlokReadyScope =\n | (() => Element | ElementRef<Element> | null | undefined)\n | ElementRef<Element>\n | Element\n | null;\n\n/** Options accepted by {@link injectBlokReady}. */\nexport interface InjectBlokReadyOptions {\n /**\n * Restrict the wait to editors mounted inside this element. Accepts an\n * element, an `ElementRef`, or a getter/signal returning either — the getter\n * form lets you pass `() => this.scopeRef?.nativeElement` from a field\n * initializer, before the view exists. It is re-read on every readiness\n * change.\n *\n * Omit it to observe every editor on the page. Passing it while it still\n * resolves to null reports NOT ready — an unresolved scope must never fall\n * back to the page-global one.\n */\n within?: BlokReadyScope;\n /**\n * `'ready'` (default) settles when each editor has finished booting.\n * `'rendered'` also waits for its content to be in the DOM and re-arms on\n * every post-boot re-render.\n */\n settleOn?: 'ready' | 'rendered';\n}\n\n/**\n * Resolves the caller's scope description to an element, or null when it is\n * not available yet.\n * @param within - the scope description passed in options\n */\nfunction resolveScope(within: BlokReadyScope): Element | null {\n const value = typeof within === 'function' ? within() : within;\n\n if (value === null || value === undefined) {\n return null;\n }\n\n return value instanceof ElementRef ? value.nativeElement : value;\n}\n\n/**\n * Angular factory exposing the live readiness of the Blok editors in a DOM\n * scope as a boolean signal.\n *\n * The readiness logic itself is framework-agnostic and lives in core\n * (`Blok.readyState` / `Blok.subscribeReady`) — the SAME implementation behind\n * React's and Vue's `useBlokReady`, so the three adapters cannot drift. This\n * wrapper supplies only Angular's reactivity: a signal re-read on every\n * registry change, unsubscribed through the injector's `DestroyRef`.\n *\n * Call it in an injection context (component constructor / field initializer).\n * The signal starts `false` and takes its first real reading in\n * `afterNextRender` — browser-only by contract, and late enough for a\n * `@ViewChild` scope to exist. Over-waiting is safe; under-waiting is a bug.\n * @param options - scope and readiness depth\n */\nexport function injectBlokReady(options: InjectBlokReadyOptions = {}): Signal<boolean> {\n const { within, settleOn } = options;\n const ready = signal(false);\n\n const read = (): void => {\n const scope = within === undefined ? null : resolveScope(within);\n\n // A scope that was asked for but has not resolved yet is NOT the global\n // scope — reporting ready here would gate on the wrong set of editors.\n ready.set(within !== undefined && scope === null\n ? false\n : BlokRuntime.readyState({\n within: scope,\n settleOn,\n }).ready);\n };\n\n inject(DestroyRef).onDestroy(BlokRuntime.subscribeReady(read));\n afterNextRender(read);\n\n return ready.asReadonly();\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["BlokRuntime"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"bloklabs-angular.mjs","sources":["../../../../dist/.angular-build/angular/provide-blok.ts","../../../../dist/.angular-build/angular/block-context.ts","../../../../dist/.angular-build/angular/block-portal-registry.ts","../../../../dist/.angular-build/angular/registry-map.ts","../../../../dist/.angular-build/angular/blok-content.directive.ts","../../../../dist/.angular-build/components/errors/tool-not-found.ts","../../../../dist/.angular-build/components/utils/id-generator.ts","../../../../dist/.angular-build/shared/flatten-tree.ts","../../../../dist/.angular-build/components/utils/blocks-tree.ts","../../../../dist/.angular-build/components/utils/blocks-api.ts","../../../../dist/.angular-build/components/utils/readonly-config.ts","../../../../dist/.angular-build/shared/deep-equal.ts","../../../../dist/.angular-build/shared/output-data.ts","../../../../dist/.angular-build/shared/prop-schema.ts","../../../../dist/.angular-build/components/constants/data-attributes.ts","../../../../dist/.angular-build/tools/nested-blocks.ts","../../../../dist/.angular-build/angular/blok-editor.component.ts","../../../../dist/.angular-build/angular/createAngularBlock.ts","../../../../dist/.angular-build/angular/useBlocks.ts","../../../../dist/.angular-build/angular/useBlokReady.ts","../../../../dist/.angular-build/bloklabs-angular.ts"],"sourcesContent":["import {\n InjectionToken,\n makeEnvironmentProviders,\n type EnvironmentProviders,\n} from '@angular/core';\nimport type { BlokAngularConfig } from './types';\n\n/**\n * DI token holding app-wide Blok defaults (shared tools registry, default theme,\n * i18n). Merged under per-instance inputs by `BlokEditorComponent`.\n */\nexport const BLOK_DEFAULT_CONFIG = new InjectionToken<Partial<BlokAngularConfig>>(\n 'BLOK_DEFAULT_CONFIG'\n);\n\n/**\n * Standalone provider registering app-wide Blok defaults.\n *\n * @example\n * ```ts\n * bootstrapApplication(AppComponent, {\n * providers: [provideBlok({ theme: 'dark', tools: sharedTools })],\n * });\n * ```\n */\nexport function provideBlok(defaults: Partial<BlokAngularConfig>): EnvironmentProviders {\n return makeEnvironmentProviders([{ provide: BLOK_DEFAULT_CONFIG, useValue: defaults }]);\n}\n","import type { BlockAPI } from '@bloklabs/core';\n// packages/angular/src/block-context.ts\nimport { InjectionToken, type Signal } from '@angular/core';\n\n\n/**\n * Context handed to a `createAngularBlock` component. Delivered via DI (the\n * BLOK_BLOCK_CONTEXT token) rather than @Input, because core constructs the tool\n * outside Angular and the signal-input() form does not compile under the repo's\n * JIT test harness. The ONLY data write path is `commit`.\n */\nexport interface AngularBlockRenderContext<Data> {\n /** Reactive, FROZEN snapshot of the block data. Read `data()`; never mutate. */\n data: Signal<Readonly<Data>>;\n /** The ONLY data write path: merge a partial patch and sync once. */\n commit: (patch: Partial<Data>) => void;\n /** This block's per-block API (id, getChildren, dispatchChange…). */\n block: BlockAPI;\n /**\n * Reactive read-only flag. Read `readOnly()` in the template to disable\n * editing (drop `contenteditable`, hide controls). Toggled IN PLACE by core's\n * read-only switch — the component reacts without a remount, so ephemeral\n * state survives. A block that ignores it stays interactive when the editor is\n * read-only (same contract as a vanilla tool's `setReadOnly`).\n */\n readOnly: Signal<boolean>;\n /**\n * Container blocks only: append this block's real child holders into `host`\n * (a `data-blok-nested` element the author owns). Call it once in\n * `ngAfterViewInit`; the factory re-runs the same mount on every data change\n * so late-added children appear. Angular must NOT manage these child holders.\n */\n mountChildren: (host: HTMLElement) => void;\n}\n\n/** DI token carrying the per-block render context into the authored component. */\nexport const BLOK_BLOCK_CONTEXT = new InjectionToken<AngularBlockRenderContext<unknown>>(\n 'BLOK_BLOCK_CONTEXT'\n);\n","// packages/angular/src/block-portal-registry.ts\nimport {\n ApplicationRef,\n createComponent,\n EnvironmentInjector,\n ErrorHandler,\n Injector,\n type ComponentRef,\n type Type,\n} from '@angular/core';\n\nimport { BLOK_BLOCK_CONTEXT, type AngularBlockRenderContext } from './block-context';\n\n/**\n * Tool-config key carrying the editor's portal registry into a\n * `createAngularBlock` tool. The tool is constructed by CORE (outside any Angular\n * injection context), so it cannot `inject()` — the directive injects the\n * editor-scoped registry through each Angular-block tool's `config`, and the tool\n * reads it back from there.\n */\nexport const BLOK_PORTAL_REGISTRY_CONFIG_KEY = '__blokAngularPortalRegistry';\n\n/** One mounted Angular block: the Blok-owned host the component renders into. */\nexport interface BlockPortalEntry {\n hostEl: HTMLElement;\n component: Type<unknown>;\n context: AngularBlockRenderContext<unknown>;\n}\n\n/**\n * Per-editor registry of Angular blocks. Mounts each authored component directly\n * into its core-owned host via `createComponent({ hostElement })` (the Teleport\n * analog) and enrolls it in `ApplicationRef` for change detection. A plain Map —\n * Angular has no reactive-proxy hazard, so no `markRaw` equivalent is needed.\n */\nexport interface BlockPortalRegistry {\n /** Mount (or replace) the component for `id` into `entry.hostEl`. */\n register(id: string, entry: BlockPortalEntry): void;\n /** Detach + destroy the component for `id`. Safe (no-op) when absent. */\n unregister(id: string): void;\n /** Re-run change detection on the block's component (in-place update). */\n flush(id: string): void;\n /** Detach + destroy every mounted block (editor teardown / recreate). */\n destroyAll(): void;\n}\n\n/**\n * Create a fresh portal registry bound to a live Angular environment. One per\n * editor instance (associated via the registry map). The injectors/appRef are\n * passed in (captured by the directive in an injection context) because the\n * registry itself is built outside one.\n */\nexport const createBlockPortalRegistry = (\n envInjector: EnvironmentInjector,\n appRef: ApplicationRef,\n errorHandler: ErrorHandler\n): BlockPortalRegistry => {\n const mounted = new Map<string, { ref: ComponentRef<unknown>; injector: Injector }>();\n\n // Change detection runs outside NgZone here; a throwing author component must\n // degrade to a blank holder, not break core's block insertion.\n const safe = (fn: () => void): void => {\n try {\n fn();\n } catch (error) {\n errorHandler.handleError(error);\n }\n };\n\n const teardown = (id: string): void => {\n const entry = mounted.get(id);\n\n if (entry === undefined) {\n return;\n }\n\n const { ref, injector } = entry;\n // Capture host before deletion so we can clear it below.\n const hostEl = ref.location.nativeElement as HTMLElement;\n mounted.delete(id);\n appRef.detachView(ref.hostView);\n ref.destroy();\n // `Injector.create({ parent })` returns an injector that is NOT torn down by\n // `ref.destroy()`. We must destroy it explicitly to prevent one small injector\n // accumulating per block over a long editor session.\n const destroyable = injector as Injector & { destroy?: () => void };\n destroyable.destroy?.();\n // createComponent({ hostElement }) renders INTO an external div. Angular's\n // destroy() tears down the component instance and CD but does NOT clear the\n // host's DOM children — we must do it explicitly.\n hostEl.replaceChildren();\n };\n\n return {\n register(id: string, entry: BlockPortalEntry): void {\n // Idempotent: replace any prior mount for this id.\n teardown(id);\n\n // The context is provided through an ELEMENT injector (a node injector),\n // so it is destroyed automatically with the component view — no leaked\n // EnvironmentInjector. The shared app envInjector is the parent, so author\n // blocks still see app-level providers (HttpClient, etc.).\n const elementInjector = Injector.create({\n providers: [{ provide: BLOK_BLOCK_CONTEXT, useValue: entry.context }],\n parent: envInjector,\n });\n\n safe(() => {\n const ref = createComponent(entry.component, {\n environmentInjector: envInjector,\n elementInjector,\n hostElement: entry.hostEl,\n });\n\n appRef.attachView(ref.hostView);\n mounted.set(id, { ref, injector: elementInjector });\n // createComponent does not auto-run CD; render synchronously into the\n // (still-detached) host before core inserts it into the document.\n ref.changeDetectorRef.detectChanges();\n });\n },\n unregister(id: string): void {\n teardown(id);\n },\n flush(id: string): void {\n const entry = mounted.get(id);\n\n if (entry === undefined) {\n return;\n }\n\n safe(() => entry.ref.changeDetectorRef.detectChanges());\n },\n destroyAll(): void {\n for (const id of Array.from(mounted.keys())) {\n teardown(id);\n }\n },\n };\n};\n","// packages/angular/src/registry-map.ts\nimport type { BlockPortalRegistry } from './block-portal-registry';\n\n/**\n * Associates each live Blok instance with its portal registry. `BlokContentDirective`\n * sets it at creation so consumers (and future composables) can reach an editor's\n * registry. WeakMap → no leak when the editor is destroyed.\n */\nconst registries = new WeakMap<WeakKey, BlockPortalRegistry>();\n\nexport function setRegistry(editor: WeakKey, registry: BlockPortalRegistry): void {\n registries.set(editor, registry);\n}\n\nexport function getRegistry(editor: WeakKey): BlockPortalRegistry | undefined {\n return registries.get(editor);\n}\n\nexport function removeRegistry(editor: WeakKey): void {\n registries.delete(editor);\n}\n","import {\n Directive,\n ElementRef,\n EventEmitter,\n NgZone,\n Output,\n PLATFORM_ID,\n Input,\n ApplicationRef,\n EnvironmentInjector,\n ErrorHandler,\n afterNextRender,\n inject,\n signal,\n type OnDestroy,\n} from '@angular/core';\nimport { isPlatformBrowser } from '@angular/common';\n// Imported via the package's public specifier so ng-packagr externalizes the\n// core as a peer dependency (consumers share a single Blok instance + CSS).\nimport { Blok as BlokRuntime, type Blok } from '@bloklabs/core';\nimport { BLOK_DEFAULT_CONFIG } from './provide-blok';\nimport type { BlokAngularConfig } from './types';\nimport {\n BLOK_PORTAL_REGISTRY_CONFIG_KEY,\n createBlockPortalRegistry,\n type BlockPortalRegistry,\n} from './block-portal-registry';\nimport { removeRegistry, setRegistry } from './registry-map';\n\n/**\n * Escape-hatch directive and lifecycle engine for Blok (mirrors React's\n * `useBlok` + `BlokContent`). Constructs a Blok instance into its own host\n * element and tears it down on destroy.\n *\n * The editor renders directly into the directive's host element — so the host\n * IS the holder. This sidesteps the fact that Blok core exposes no public\n * `holder` accessor: the adapter never has to read it back, it owns it.\n *\n * `BlokEditorComponent` applies this directive to its internal `<div>` and reads\n * the instance back; consumers can also use it directly for full control:\n * `<div blokContent [config]=\"cfg\" (ready)=\"onReady($event)\"></div>`.\n *\n * Implementation note: classic `@Input()`/`@Output()` are used (not signal\n * `input()`/`output()`) because the repo's Vitest+Analog harness compiles the\n * adapter via JIT, which does not register signal-based members. `instance`\n * remains a plain `signal` (runtime API, JIT-safe) for reactive consumption.\n */\n@Directive({\n selector: '[blokContent]',\n standalone: true,\n})\nexport class BlokContentDirective implements OnDestroy {\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly ngZone = inject(NgZone);\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n /**\n * App-wide defaults from `provideBlok()`, merged UNDER the bound `[config]` so\n * the escape-hatch path honors them just like `<blok-editor>` (which also\n * merges, idempotently). Mirrors React's `useBlok` merging context defaults.\n */\n private readonly defaults = inject(BLOK_DEFAULT_CONFIG, { optional: true }) ?? {};\n // Captured in the injection context (field initializers) so the registry can\n // mount author components via createComponent — core constructs tools outside\n // Angular DI and cannot inject these itself.\n private readonly envInjector = inject(EnvironmentInjector);\n private readonly appRef = inject(ApplicationRef);\n private readonly errorHandler = inject(ErrorHandler);\n\n /** Construction-time Blok config (everything except `holder`, which the directive owns). */\n @Input() config: Partial<BlokAngularConfig> = {};\n\n /** Changing this input's identity (after the first build) destroys + recreates the editor. */\n @Input() set recreateKey(value: unknown) {\n const changed = this.built && value !== this.currentKey;\n this.currentKey = value;\n\n if (changed) {\n this.current?.destroy();\n this.build();\n }\n }\n\n /** Emits the live Blok instance once it is ready, after `instance` is populated. */\n @Output() readonly ready = new EventEmitter<Blok>();\n\n /** The live Blok instance, or null before `isReady` resolves / after destroy. */\n readonly instance = signal<Blok | null>(null);\n\n /** The editor created by the most recent construction; used as the staleness key. */\n private current: Blok | null = null;\n private destroyed = false;\n private built = false;\n private currentKey: unknown;\n /** The portal registry for the current editor (Angular-block mounting). */\n private registry: BlockPortalRegistry | undefined;\n\n constructor() {\n // afterNextRender is browser-only (skipped during SSR) and runs after the\n // host element exists and inputs are bound.\n afterNextRender(() => {\n // afterNextRender is browser-only by contract, but guard explicitly so the\n // editor is never constructed during SSR / on a non-browser platform.\n if (this.destroyed || !this.isBrowser) {\n return;\n }\n\n this.build();\n this.built = true;\n });\n }\n\n /** Construct a Blok into the host element and publish it once ready. */\n private build(): void {\n this.destroyed = false;\n this.instance.set(null);\n\n // Tear down any registry from a superseded editor (recreate path) before\n // building a new one.\n this.registry?.destroyAll();\n\n // Merge provideBlok defaults under the bound config (instance wins; tools\n // registries compose across both layers rather than replacing).\n const merged: Partial<BlokAngularConfig> = { ...this.defaults, ...this.config };\n\n if (this.defaults.tools !== undefined || this.config.tools !== undefined) {\n merged.tools = { ...this.defaults.tools, ...this.config.tools };\n }\n\n // Create the editor-scoped portal registry and thread it into every\n // Angular-block tool's config (vanilla tools pass through untouched).\n const registry = createBlockPortalRegistry(this.envInjector, this.appRef, this.errorHandler);\n\n this.registry = registry;\n merged.tools = injectPortalRegistry(merged.tools, registry);\n\n // Construct outside Angular's zone so the editor's internal DOM churn never\n // schedules change detection.\n const blok = this.ngZone.runOutsideAngular(\n () =>\n new BlokRuntime({\n ...merged,\n holder: this.host.nativeElement,\n }) as unknown as Blok\n );\n\n this.current = blok;\n setRegistry(blok, registry);\n\n void blok.isReady.then(() =>\n this.ngZone.run(() => {\n // Guard on the constructor-returned reference (not isReady's resolved\n // value): a superseded or torn-down editor must not publish itself.\n if (this.current !== blok || this.destroyed) {\n return;\n }\n\n this.instance.set(blok); // assign FIRST…\n this.ready.emit(blok); // …THEN emit, so consumers see a populated instance.\n })\n );\n }\n\n ngOnDestroy(): void {\n this.destroyed = true;\n this.registry?.destroyAll();\n\n if (this.current !== null) {\n removeRegistry(this.current);\n }\n\n this.current?.destroy();\n this.current = null;\n this.registry = undefined;\n this.instance.set(null);\n }\n}\n\n/**\n * Return a NEW tools map (never mutate the consumer's config) where each\n * Angular-block tool carries the portal registry under\n * BLOK_PORTAL_REGISTRY_CONFIG_KEY in its `config`. Vanilla tools are returned\n * unchanged. Handles both entry shapes: a bare constructor and `{ class, config }`.\n */\nfunction injectPortalRegistry(\n tools: BlokAngularConfig['tools'],\n registry: BlockPortalRegistry\n): BlokAngularConfig['tools'] {\n if (tools === undefined) {\n return tools;\n }\n\n const result: Record<string, unknown> = {};\n\n for (const [name, entry] of Object.entries(tools)) {\n const asObject = entry as { class?: unknown; config?: Record<string, unknown> } | undefined;\n const toolClass = (typeof entry === 'function' ? entry : asObject?.class) as\n | { __isBlokAngularBlock?: boolean }\n | undefined;\n\n if (toolClass?.__isBlokAngularBlock === true) {\n const base = typeof entry === 'function' ? { class: entry } : { ...asObject };\n\n result[name] = {\n ...base,\n config: { ...(base.config ?? {}), [BLOK_PORTAL_REGISTRY_CONFIG_KEY]: registry },\n };\n } else {\n result[name] = entry;\n }\n }\n\n return result as BlokAngularConfig['tools'];\n}\n","/**\n * Thrown when a block tool cannot be resolved during a creation/conversion\n * operation (insert, insertMany/composeBlock, composeBlockData, convert).\n *\n * A typed error lets adapters (React/Vue/Angular useBlocks) distinguish a\n * genuinely-unknown tool — an EXPECTED, recoverable outcome they surface as a\n * `null`/`[]` no-op — from a real bug, WITHOUT brittle `message.includes('not\n * found')` substring matching (which both mis-catches unrelated errors whose\n * message happens to contain \"not found\" and breaks under message localization).\n */\nexport class ToolNotFoundError extends Error {\n /**\n * @param toolName - the tool type that could not be resolved\n * @param message - optional override; defaults to a descriptive message\n */\n constructor(public readonly toolName: string, message?: string) {\n super(message ?? `Block Tool «${toolName}» not found.`);\n this.name = 'ToolNotFoundError';\n }\n}\n","/**\n * ID generation utilities\n */\n\n// nanoid replaced with inline crypto implementation for the Angular adapter bundle.\nconst _ID_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-';\nconst _nanoid = (n: number): string => {\n const buf = crypto.getRandomValues(new Uint8Array(n));\n return Array.from(buf, (b) => _ID_CHARS[b % 64]).join('');\n};\nconst nanoid = _nanoid;\n\n/**\n * Constants for ID generation\n */\nconst ID_RANDOM_MULTIPLIER = 100_000_000; // 1e8\nconst HEXADECIMAL_RADIX = 16;\n\n/**\n * Create a block id\n * @returns unique block ID\n */\nexport const generateBlockId = (): string => {\n const idLen = 10;\n\n return nanoid(idLen);\n};\n\n/**\n * Nanoid-compatible block ID pattern: exactly 10 URL-safe characters (A-Z, a-z, 0-9, _, -)\n */\nconst BLOCK_ID_PATTERN = /^[A-Za-z0-9_-]{10}$/;\n\n/**\n * Returns true if the given string is a valid block ID (nanoid format).\n * @param id - string to check\n */\nexport const isValidBlockId = (id: string): boolean => BLOCK_ID_PATTERN.test(id);\n\n/**\n * Returns random generated identifier\n * @param prefix - identifier prefix\n * @returns unique identifier with prefix\n */\nexport const generateId = (prefix = ''): string => {\n return `${prefix}${(Math.floor(Math.random() * ID_RANDOM_MULTIPLIER)).toString(HEXADECIMAL_RADIX)}`;\n};\n","import type { OutputBlockData, BlockId, BlockTreeSpec, FlattenTreeOptions } from '@bloklabs/core';\nimport { generateBlockId } from '../components/utils/id-generator';\n\n/** A flattened block with its `id` resolved (generated when the spec omitted one). */\ntype FlattenedBlock = OutputBlockData & { id: BlockId };\n\n/**\n * Flatten a hierarchical block spec (nodes with `children`) into the flat DFS\n * pre-order `OutputBlockData[]` Blok stores, wiring every node's `parent` and\n * `content` id links.\n *\n * This is the pure counterpart of the live `insertTree` mutation: the same DFS,\n * without an editor. Use it to seed nested content — columns, tables, a whole\n * document — without hand-authoring `parent`/`content` arrays:\n *\n * @example\n * new Blok({\n * data: {\n * blocks: flattenTree([\n * { type: 'column_list', children: [\n * { type: 'column', children: [{ type: 'paragraph', data: { text: 'L' } }] },\n * { type: 'column', children: [{ type: 'paragraph', data: { text: 'R' } }] },\n * ] },\n * ]),\n * },\n * });\n *\n * @param spec - a single root node or an array of root nodes.\n * @param options - `parentId` sets the `parent` of the root node(s);\n * `generateId` overrides id generation for nodes that omit an `id` (default:\n * Blok's nanoid scheme).\n * @returns DFS pre-order blocks with `parent`/`content` wired. Leaves omit the\n * empty `content` array, matching the documented `OutputBlockData` shape.\n * @throws if an explicit `id` is reused within the spec — a duplicate id would\n * corrupt every id-keyed lookup, so it is surfaced loudly rather than encoded.\n */\nexport function flattenTree(\n spec: BlockTreeSpec | BlockTreeSpec[],\n options: FlattenTreeOptions = {}\n): FlattenedBlock[] {\n const generateId = options.generateId ?? generateBlockId;\n const rootParent = options.parentId ?? undefined;\n\n const flat: FlattenedBlock[] = [];\n const usedIds = new Set<string>();\n\n // Pre-order DFS: push self FIRST, then recurse each child, so the flat array\n // is DFS-contiguous. `content` is filled as each child is visited and returns\n // its id; it is omitted for leaves.\n const visit = (node: BlockTreeSpec, parent: string | undefined): string => {\n const id = node.id ?? generateId();\n\n if (usedIds.has(id)) {\n throw new Error(`flattenTree: duplicate block id \"${id}\" — every block id must be unique.`);\n }\n usedIds.add(id);\n\n const childIds: string[] = [];\n const flatNode = {\n id,\n // `type` is OMITTED (not present-with-undefined) when absent so core's\n // `type || defaultBlock` fallback resolves the default block cleanly.\n ...(node.type !== undefined ? { type: node.type } : {}),\n data: node.data ?? {},\n ...(node.tunes !== undefined ? { tunes: node.tunes } : {}),\n ...(parent !== undefined ? { parent } : {}),\n } as FlattenedBlock;\n\n flat.push(flatNode);\n\n for (const child of node.children ?? []) {\n childIds.push(visit(child, id));\n }\n\n // Only wire `content` when there are children — leaves stay clean.\n if (childIds.length > 0) {\n flatNode.content = childIds;\n }\n\n return id;\n };\n\n const roots = Array.isArray(spec) ? spec : [spec];\n\n for (const root of roots) {\n visit(root, rootParent);\n }\n\n return flat;\n}\n","import type { BlockToolData, BlockTuneData, OutputBlockData, OutputData, MarkdownImportConfig } from '@bloklabs/core';\n\n/**\n * Where to place the caret within a block. `position` selects the input\n * (`'start'`/`'end'`/`'default'`) and `offset` is the character offset within it\n * — the same shape core's `caret.setToBlock` accepts.\n */\nexport interface CaretTarget {\n position?: 'start' | 'end' | 'default';\n offset?: number;\n}\n\n/**\n * A plain, serializable view of one block in the tree.\n *\n * Snapshot-volatile: every read allocates a fresh `BlockNode`, and `contentIds`\n * is DERIVED per read from the children that currently name this block as parent\n * (it is not a stored field). Read a node in render and re-read after a change —\n * don't stash one in a `useMemo`/`useEffect` dependency array expecting stable\n * identity; depend on the `id` instead.\n */\nexport interface BlockNode {\n id: string;\n type: string;\n parentId: string | null;\n contentIds: readonly string[];\n}\n\n/** Where to place a block among its siblings. */\nexport type InsertPosition = 'start' | 'end' | { before: string } | { after: string };\n\nexport interface InsertSpec {\n type?: string;\n data?: BlockToolData;\n parentId?: string | null;\n position?: InsertPosition;\n /**\n * Move the caret into the new block. Defaults to `false`: a programmatic\n * insert from React must not steal focus from wherever the user is typing.\n * Set `true` for an explicit \"add a block and start editing it\" flow.\n */\n focus?: boolean;\n /**\n * Replace the block at the resolved slot instead of inserting a new one — a\n * programmatic \"turn into\". Combine with a `position` that targets the block\n * to replace, e.g. `{ position: { before: id }, replace: true }`.\n */\n replace?: boolean;\n /**\n * Explicit id for the new block (generated when omitted). Passing a stable id\n * makes the insert idempotent: if a block with this id already exists the\n * existing node is returned and nothing is inserted (\"insert if absent\"),\n * so an effect that re-runs won't create duplicates.\n */\n id?: string;\n /** Block tune data to apply at creation, keyed by tune name. */\n tunes?: { [name: string]: BlockTuneData };\n /**\n * Place the caret inside the newly-created block at a specific position/offset\n * (e.g. `{ offset: 3 }`). Implies focus. Applied ONLY when a block is actually\n * created — an insert-if-absent hit (existing id) does not move the caret.\n * Use this instead of the boolean `focus` when you need a specific offset.\n */\n caret?: CaretTarget;\n}\n\n/**\n * One node of a pre-built nested subtree for {@link UseBlocksApi.insertTree}.\n *\n * Each node maps to one block; `children` are inserted nested under it (their\n * `parentId` set to this node's id) in array order, recursively. Placement\n * options (`parentId`/`position`) are ROOT-ONLY — they position the whole\n * subtree among existing blocks and are ignored on nested children, whose parent\n * is always their enclosing node.\n */\nexport interface TreeInsertSpec {\n type?: string;\n data?: BlockToolData;\n tunes?: { [name: string]: BlockTuneData };\n /**\n * Explicit id for this node (generated when omitted). Unlike `insert`, this is\n * NOT insert-if-absent: a tree insert always creates fresh blocks. A colliding\n * id — one that already exists in the document, or is reused by another node\n * in the same spec — is REJECTED up front: nothing is inserted and `insertTree`\n * returns `null` (a duplicate id would corrupt every id-keyed lookup).\n */\n id?: string;\n /** Direct children, inserted nested under this node, in array order. */\n children?: TreeInsertSpec[];\n /** Root-only: where to place the whole subtree. Ignored on nested children. */\n parentId?: string | null;\n /** Root-only: slot among siblings of `parentId`. Ignored on nested children. */\n position?: InsertPosition;\n}\n\n/**\n * Where to move an existing block.\n *\n * `before`/`after` are POSITION targets, not parent assignments: the block is\n * relocated to that flat slot and — because Blok keeps the flat array as the\n * canonical document order — ADOPTS the parent of wherever it lands. Moving a\n * nested block to `{ after: someRootBlock }` therefore unnests it to root, and\n * moving a root block in among a container's children nests it. Use\n * `nest`/`unnest` when you want to change the parent without choosing a sibling\n * slot. `toIndex` is an absolute flat index (clamped into range).\n */\nexport type MoveTarget = { before: string } | { after: string } | { toIndex: number };\n\nexport interface UseBlocksApi {\n getById(id: string): BlockNode | null;\n getChildren(parentId: string | null): BlockNode[];\n /**\n * Insert one block; returns the created node or null when rejected (unknown\n * tool type, dangling `parentId`, or a `replace` whose target is missing). An\n * explicit `id` that already exists is insert-if-absent (returns the existing\n * node, creates nothing). Atomic — one undo step. The returned node is\n * {@link BlockNode}-volatile; read it now, don't put it in a dep array.\n */\n insert(spec?: InsertSpec): BlockNode | null;\n /**\n * Insert several blocks atomically, in array order, as ONE undo step. Each\n * spec is a full {@link InsertSpec} (own type/data/parentId/position), routed\n * through the same single-`insert` path, so per-spec parent assertion and\n * positioning still apply. Specs that fail to insert (e.g. a dangling\n * parentId, or a replace whose target is missing) are dropped; the returned\n * array holds only the successfully created nodes. An empty input is a no-op\n * (returns `[]`, opens no transaction). Like `insert`, the returned nodes are\n * fresh-snapshot volatile — read them now, don't stash them in dep arrays.\n */\n insertMany(specs: InsertSpec[]): BlockNode[];\n /**\n * Insert a pre-built NESTED subtree in ONE atomic operation (one undo step).\n * Each {@link TreeInsertSpec} node becomes a block; its `children` are inserted\n * nested under it (recursively, in array order) so the whole hierarchy lands in\n * a single call — no follow-up `nest` round-trips. Delegates to core's\n * tree-aware `blocks.insertMany`, which composes the flat DFS pre-order array\n * honoring each node's `parent`/`content` links.\n *\n * Placement is root-only: the root node's `parentId`/`position` position the\n * whole subtree among existing blocks (default: appended at the document end);\n * nested children ignore those fields (their parent is their enclosing node). A\n * dangling root `parentId` is rejected — nothing is inserted and `null` is\n * returned (mirrors {@link insert}). Returns the root {@link BlockNode}, which\n * is fresh-snapshot volatile — read it now, don't stash it in a dep array.\n */\n insertTree(spec: TreeInsertSpec): BlockNode | null;\n /**\n * Convert a Markdown string to blocks and insert them ADDITIVELY at a\n * position, WITHOUT clearing the document (unlike core's `importMarkdown` /\n * `renderFromHTML`, which replace the whole document). This is the React\n * \"paste markdown → blocks appear\" path.\n *\n * Async: the markdown converter is lazy-loaded (kept out of the main bundle),\n * so this is the ONE async creator in the API — `await` the returned promise.\n * The whole batch is inserted as a single atomic undo step.\n *\n * `position` (default `'end'`) places the converted run among `parentId`'s\n * children (or root siblings when `parentId` is omitted/null), reusing the\n * same `start`/`end`/`before`/`after` semantics as {@link insert}.\n *\n * `parentId` (default `null` = root) nests the import: every TOP-LEVEL\n * converted block (one the converter left un-parented) is reparented under\n * `parentId`, while blocks the markdown nested internally (e.g. table-cell\n * children) keep their intra-import parent. A dangling `parentId` is a no-op\n * (returns `[]`, opens no transaction), matching {@link insert}.\n *\n * `config` (optional {@link MarkdownImportConfig}) is forwarded to the\n * converter so custom-tool consumers can map markdown nodes into their tools\n * (`toolMap`/`onUnknownNode`), toggle GFM, or add micromark/mdast extensions.\n *\n * Returns ALL created {@link BlockNode}s in document order — including any the\n * markdown nested internally (e.g. a table's cell children), not just the\n * top-level run (this differs from {@link insertTree}, which returns only the\n * root). Empty or whitespace-only markdown, a dangling `parentId` (checked\n * again after the async convert, so a parent removed mid-flight also no-ops),\n * and a converter failure (chunk-load or parse error, swallowed) all return\n * `[]` and open no transaction. The nodes are fresh-snapshot volatile — read\n * them now, don't stash them in dep arrays.\n */\n insertMarkdown(\n markdown: string,\n options?: { parentId?: string | null; position?: InsertPosition; config?: MarkdownImportConfig }\n ): Promise<BlockNode[]>;\n /**\n * Serialize the WHOLE document to a Markdown string — the outbound twin of\n * core's `blocks.exportMarkdown` (and the read-side counterpart of the\n * additive {@link insertMarkdown}). Async: the serializer is lazy-loaded, like\n * the importer. Markdown cannot express every block, so some structure is\n * dropped (table `colspan`/`rowspan`, heading columns). Returns `''` for an\n * empty document. Pre-ready: resolves to `''`.\n */\n exportMarkdown(): Promise<string>;\n move(id: string, target: MoveTarget): void;\n nest(id: string, parentId: string): void;\n unnest(id: string): void;\n remove(id: string): void;\n /**\n * Update a block's data and/or tunes by id. Delegates to core's async\n * `blocks.update`, which forms its OWN undo step — the call is NOT wrapped in\n * `transact` (that would close the group before the async write lands). An\n * unknown id is a silent no-op; a rejected update is swallowed so it can't\n * surface as an unhandled rejection. Reads refresh reactively once core emits\n * 'block changed'. Returns `void`.\n */\n update(id: string, data?: BlockToolData, tunes?: { [name: string]: BlockTuneData }): void;\n /**\n * Convert a block to another type (\"turn into\") by id. Delegates to core's\n * async `blocks.convert`; both tools must provide a `conversionConfig` or core\n * rejects — that rejection (and any other) is swallowed so a non-convertible\n * block is a graceful no-op rather than an unhandled rejection. An unknown id\n * is a silent no-op. Not wrapped in `transact` (core owns its history step).\n * Returns `void`.\n */\n convert(\n id: string,\n newType: string,\n dataOverrides?: BlockToolData,\n options?: { caret?: CaretTarget }\n ): void;\n transact(fn: () => void): void;\n /**\n * Run `fn` as one atomic operation that is NOT captured in the undo history —\n * the React-surface counterpart of core's `transactWithoutCapture`. Use for\n * silent auto-repair/normalization that a user's CMD+Z should never step\n * through. Mutations inside still emit reactively. Pre-ready it just runs `fn`.\n */\n transactWithoutCapture(fn: () => void): void;\n /**\n * The current block count. Reactive (re-reads on 'block changed'). Pre-ready: 0.\n */\n getBlocksCount(): number;\n /**\n * The flat index of the block holding the caret, or -1 when none. Pre-ready: -1.\n */\n getCurrentBlockIndex(): number;\n /** The block at a flat index as a snapshot {@link BlockNode}, or null. */\n getBlockByIndex(index: number): BlockNode | null;\n /**\n * The absolute flat index of a block by id, or null when unknown. The\n * counterpart to {@link getBlockByIndex} — use it to target an off-caret\n * {@link splitBlock} (whose `insertIndex` is absolute) without the ref. Unknown\n * ids return null silently (no console warn). Pre-ready: null.\n */\n getBlockIndex(id: string): number | null;\n /**\n * Read a block's current `data` and `tunes` by id WITHOUT mutating anything —\n * the synchronous last-extracted view (the same snapshot clipboard ops use).\n * Makes a client-side duplicate composable from the hook alone: read a node,\n * then `insert({ type, data, tunes, position })`, no ref escape hatch. Unknown\n * id returns null. Pre-ready: null.\n */\n getBlockData(id: string): { data: BlockToolData; tunes: { [name: string]: BlockTuneData } } | null;\n /**\n * The block whose holder contains/equals `element`, as a snapshot\n * {@link BlockNode}, or null. Useful for mapping a DOM event target back to a\n * block.\n */\n getBlockByElement(element: HTMLElement): BlockNode | null;\n /**\n * Read a tool's default empty data WITHOUT inserting anything — delegates to\n * core's `composeBlockData`. Async (a tool's data may be composed lazily).\n * Rejects (via core) for an unknown tool. Pre-ready: resolves to `{}`.\n */\n composeBlockData(toolName: string): Promise<BlockToolData>;\n /**\n * Replace the WHOLE document with blocks parsed from an HTML string —\n * delegates to core's `renderFromHTML`. Unlike {@link insertMarkdown} (which is\n * additive), this CLEARS existing content first, so it's a document-load\n * primitive, not an insert. Async. Pre-ready: resolves immediately (no-op).\n */\n renderFromHTML(html: string): Promise<void>;\n /**\n * Insert a flat array of already-serialized {@link OutputBlockData} (the\n * `save()` shape) directly, honoring each block's `parent`/`content` links —\n * the raw counterpart of core's `blocks.insertMany`. Use to re-insert a saved\n * document fragment without reshaping it into {@link TreeInsertSpec}. One\n * atomic undo step. Returns the created nodes; pre-ready: `[]` (no insert).\n */\n insertOutputData(blocks: OutputBlockData[], options?: { index?: number }): BlockNode[];\n /**\n * Atomically split a block: update `currentBlockId` with `currentBlockData`\n * and insert a new `newBlockType` block at `insertIndex`, as ONE undo step.\n * Delegates to core's `splitBlock`. Returns the new node, or null pre-ready /\n * on an unknown id.\n */\n splitBlock(\n currentBlockId: string,\n currentBlockData: Partial<BlockToolData>,\n newBlockType: string,\n newBlockData: BlockToolData,\n insertIndex: number\n ): BlockNode | null;\n /**\n * Insert a single child block under `parentId` at flat `insertIndex`, atomically\n * (block creation AND parent assignment in ONE undo step) — delegates to core's\n * `blocks.insertInsideParent`. This is the atomic nested-child creator: prefer it\n * over `insert()` + `nest()`, which is TWO undo steps. A dangling `parentId` is a\n * no-op returning `null` (mirrors {@link insert}); an unknown child tool returns\n * `null`. `childData` defaults to an empty paragraph. Returns the created\n * {@link BlockNode}, fresh-snapshot volatile — read it now, don't stash it in a\n * dep array. Pre-ready: `null`.\n */\n insertInsideParent(parentId: string, insertIndex: number, childData?: BlockToolData): BlockNode | null;\n /**\n * Replace the WHOLE document with blocks parsed from saved {@link OutputData}\n * (the `save()` shape) — delegates to core's `blocks.render`. Unlike\n * {@link insertOutputData}/{@link insertMarkdown} (which are ADDITIVE), this\n * CLEARS existing content first: a document-LOAD primitive, not an insert. The\n * HTML counterpart is {@link renderFromHTML}. Async. Pre-ready: resolves\n * immediately (no-op).\n */\n render(data: OutputData): Promise<void>;\n /**\n * Remove EVERY block from the document — delegates to core's `blocks.clear`. A\n * document-reset primitive (pairs with {@link render}). Async. Pre-ready:\n * resolves immediately (no-op).\n */\n clear(): Promise<void>;\n /**\n * Whether a Yjs sync (undo/redo) is currently in progress — the React mirror of\n * core's `blocks.isSyncingFromYjs`. A METHOD (not a property) so it reads the\n * LIVE flag at call time even though the api handle is memoized. Use it to skip\n * cleanup that would fight Yjs state during an undo/redo. Pre-ready: `false`.\n */\n isSyncingFromYjs(): boolean;\n}\n\n/** The minimal slice of editor.blocks that the snapshot helpers read. */\nexport interface BlocksReader {\n getBlocksCount(): number;\n getBlockByIndex(index: number): { id: string; name: string; parentId: string | null } | undefined;\n}\n\n/**\n * Enumerate the editor's blocks once into BlockNode records, in flat order,\n * deriving each node's contentIds from the children that name it as parent.\n */\nexport const snapshotNodes = (reader: BlocksReader): BlockNode[] => {\n const count = reader.getBlocksCount();\n const flat = Array.from({ length: count }, (_, i) => reader.getBlockByIndex(i))\n .filter((b): b is { id: string; name: string; parentId: string | null } => b !== undefined)\n .map((b) => ({ id: b.id, type: b.name, parentId: b.parentId }));\n\n const childrenByParent = new Map<string, string[]>();\n\n for (const b of flat) {\n if (b.parentId === null) {\n continue;\n }\n const bucket = childrenByParent.get(b.parentId) ?? [];\n\n bucket.push(b.id);\n childrenByParent.set(b.parentId, bucket);\n }\n\n return flat.map((b) => ({\n id: b.id,\n type: b.type,\n parentId: b.parentId,\n contentIds: childrenByParent.get(b.id) ?? [],\n }));\n};\n\n/** BlocksReader plus id→flat-index lookup. */\nexport interface IndexReader extends BlocksReader {\n getBlockIndex(id: string): number | undefined;\n}\n\n/** Flat indices of a parent's direct children, ascending. Empty if none. */\nconst childFlatIndices = (reader: IndexReader, parentId: string): number[] => {\n const count = reader.getBlocksCount();\n\n return Array.from({ length: count }, (_, i) => i).filter(\n (i) => reader.getBlockByIndex(i)?.parentId === parentId\n );\n};\n\n/** Map of block id -> parentId, in flat order. */\nexport const parentMap = (reader: IndexReader): Map<string, string | null> => {\n const count = reader.getBlocksCount();\n const entries = Array.from({ length: count }, (_, i) => reader.getBlockByIndex(i))\n .filter((b): b is { id: string; name: string; parentId: string | null } => b !== undefined)\n .map((b): [string, string | null] => [b.id, b.parentId]);\n\n return new Map(entries);\n};\n\n/** True if `id` descends from `ancestorId` via the parentId chain. */\nexport const isDescendantOf = (\n parentOf: Map<string, string | null>,\n id: string,\n ancestorId: string\n): boolean => {\n const parent = parentOf.get(id) ?? null;\n\n if (parent === null) {\n return false;\n }\n\n return parent === ancestorId || isDescendantOf(parentOf, parent, ancestorId);\n};\n\n/**\n * The flat index of the last block in the contiguous subtree rooted at `index`.\n * In flat (DFS) order a block's descendants sit immediately after it, so this\n * walks forward while blocks remain descendants of the block at `index`.\n * Returns `index` itself when the block has no descendants.\n */\nconst subtreeEndIndex = (reader: IndexReader, index: number): number => {\n const root = reader.getBlockByIndex(index);\n\n if (root === undefined) {\n return index;\n }\n\n const parentOf = parentMap(reader);\n const count = reader.getBlocksCount();\n // Walk forward from index+1 while blocks remain descendants (DFS contiguity).\n // The subtree ends just before the first non-descendant, or at the last block\n // when every follower is a descendant.\n const followers = Array.from({ length: count - (index + 1) }, (_, k) => index + 1 + k);\n const breakAt = followers.find((i) => {\n const b = reader.getBlockByIndex(i);\n\n return b === undefined || !isDescendantOf(parentOf, b.id, root.id);\n });\n\n return breakAt === undefined ? count - 1 : breakAt - 1;\n};\n\n/**\n * The flat index at which a new block should be inserted.\n *\n * `replace` flips the meaning of a before/after `position`: under replace the\n * ref IS the block being overwritten (a \"turn into\"), not a sibling anchor, so\n * it resolves to the ref's OWN flat slot regardless of which parent it lives in\n * — bypassing the sibling-relative parent guard that would otherwise redirect a\n * nested target to the requested parent's end and replace the wrong block.\n */\nexport const resolveInsertIndex = (\n reader: IndexReader,\n parentId: string | null,\n position: InsertPosition,\n replace = false\n): number => {\n if (typeof position === 'object') {\n const ref = 'before' in position ? position.before : position.after;\n const refIndex = reader.getBlockIndex(ref);\n\n if (replace && refIndex !== undefined) {\n return refIndex;\n }\n\n const refParent =\n refIndex === undefined ? undefined : reader.getBlockByIndex(refIndex)?.parentId ?? null;\n\n // before/after is sibling-relative: the ref must be a child of the requested\n // parent. When the ref is missing or lives in a DIFFERENT parent, the\n // parentId constraint wins — fall back to appending at the end of the\n // requested parent rather than splicing into an unrelated subtree (the\n // cross-parent mis-place) or silently landing at the document end.\n if (refIndex === undefined || refParent !== parentId) {\n return resolveInsertIndex(reader, parentId, 'end');\n }\n\n // 'after' must clear the ref's entire subtree, not just the ref node, or the\n // new block splits the ref's descendants in flat (DFS) order.\n return 'before' in position ? refIndex : subtreeEndIndex(reader, refIndex) + 1;\n }\n\n if (parentId === null) {\n return position === 'start' ? 0 : reader.getBlocksCount();\n }\n\n const parentIndex = reader.getBlockIndex(parentId);\n\n if (parentIndex === undefined) {\n return reader.getBlocksCount();\n }\n\n if (position === 'start') {\n const childIndices = childFlatIndices(reader, parentId);\n\n return childIndices.length === 0 ? parentIndex + 1 : childIndices[0];\n }\n\n // 'end': insert after the parent's last descendant.\n return subtreeEndIndex(reader, parentIndex) + 1;\n};\n\n/** The flat toIndex for editor.blocks.move. */\nexport const resolveMoveIndex = (reader: IndexReader, target: MoveTarget): number => {\n if ('toIndex' in target) {\n // Blok's Blocks.move() silently no-ops on an out-of-range index, so clamp\n // an explicit toIndex into [0, count-1] rather than dropping the move.\n const lastIndex = Math.max(0, reader.getBlocksCount() - 1);\n\n return Math.min(Math.max(target.toIndex, 0), lastIndex);\n }\n\n const ref = 'before' in target ? target.before : target.after;\n const refIndex = reader.getBlockIndex(ref);\n\n if (refIndex === undefined) {\n return reader.getBlocksCount();\n }\n\n // 'after' must clear the ref's entire subtree (see resolveInsertIndex), or the\n // moved block lands among the ref's descendants instead of past them.\n return 'before' in target ? refIndex : subtreeEndIndex(reader, refIndex) + 1;\n};\n","import type { Blok, BlockToolData, BlockTuneData, OutputBlockData, OutputData, MarkdownImportConfig } from '@bloklabs/core';\n// src/components/utils/blocks-api.ts\nimport { ToolNotFoundError } from '../errors/tool-not-found';\n\nimport { flattenTree } from '../../shared/flatten-tree';\nimport {\n snapshotNodes,\n resolveInsertIndex,\n resolveMoveIndex,\n parentMap,\n isDescendantOf,\n type BlockNode,\n type CaretTarget,\n type IndexReader,\n type InsertPosition,\n type InsertSpec,\n type MoveTarget,\n type TreeInsertSpec,\n type UseBlocksApi,\n} from './blocks-tree';\n\n/** Adapt the live editor to the IndexReader the snapshot helpers expect. */\nexport const readerFor = (editor: Blok): IndexReader => {\n const blocks = editor.blocks;\n\n return {\n getBlocksCount: () => blocks.getBlocksCount(),\n getBlockByIndex: (i: number) => {\n const b = blocks.getBlockByIndex(i);\n\n return b === undefined ? undefined : { id: b.id, name: b.name, parentId: b.parentId };\n },\n getBlockIndex: (id: string) => blocks.getBlockIndex(id),\n };\n};\n\n/**\n * Stable API returned while the editor is null (before the adapter resolves).\n * Every read returns empty/null and every MUTATOR is a no-op — EXCEPT\n * `transact`/`transactWithoutCapture`, which still invoke their callback so a\n * consumer wrapping conditional work in `transact` still runs that work even\n * pre-ready.\n */\nexport const EMPTY_API: UseBlocksApi = {\n getById: () => null,\n getChildren: () => [],\n insert: () => null,\n insertMany: () => [],\n insertTree: () => null,\n insertMarkdown: async () => [],\n exportMarkdown: async () => '',\n move: () => undefined,\n nest: () => undefined,\n unnest: () => undefined,\n remove: () => undefined,\n update: () => undefined,\n convert: () => undefined,\n // Not a no-op: still runs the callback (see EMPTY_API doc above).\n transact: (fn: () => void) => fn(),\n // Like transact, still runs the callback even pre-ready.\n transactWithoutCapture: (fn: () => void) => fn(),\n getBlocksCount: () => 0,\n getCurrentBlockIndex: () => -1,\n getBlockByIndex: () => null,\n getBlockByElement: () => null,\n getBlockData: () => null,\n getBlockIndex: () => null,\n composeBlockData: async () => ({}),\n renderFromHTML: async () => undefined,\n insertOutputData: () => [],\n splitBlock: () => null,\n insertInsideParent: () => null,\n render: async () => undefined,\n clear: async () => undefined,\n isSyncingFromYjs: () => false,\n};\n\n/**\n * Build the framework-agnostic, id/parentId-relative block-tree API over a LIVE\n * editor. Mutators route through the editor-level `blocks` API (core's\n * chokepoints), so undo/redo and Yjs sync are inherited rather than\n * re-implemented; readers enumerate the live tree on every call.\n *\n * This is the shared engine behind both the React (`useSyncExternalStore`) and\n * Vue (`shallowRef` version) `useBlocks` wrappers — one implementation so the\n * two adapters cannot drift. Each adapter supplies the `onRead` seam:\n *\n * - React leaves it the default no-op: `useSyncExternalStore` re-renders the\n * whole component on `block changed`, and the reads run live during that\n * render, so no per-call dependency tracking is needed.\n * - Vue passes `() => { void version.value }` so a read inside a `computed` /\n * template touches the reactive version ref and re-runs on every structural\n * mutation.\n *\n * `onRead` is invoked at the top of every read method; mutators never call it.\n * The editor MUST be the raw (non-proxied) instance — adapters `toRaw`-unwrap\n * before calling, so a Vue reactive proxy never reaches core (Risk R0).\n *\n * @param editor - the live Blok instance (never null; callers gate on EMPTY_API)\n * @param onRead - reactivity seam called at the start of each read (default no-op)\n */\nexport const createBlocksApiForEditor = (\n editor: Blok,\n onRead: () => void = () => undefined\n): UseBlocksApi => {\n const reader = readerFor(editor);\n\n const getById = (id: string): BlockNode | null => {\n onRead();\n const nodes = snapshotNodes(reader);\n\n return nodes.find((n) => n.id === id) ?? null;\n };\n\n const getChildren = (parentId: string | null): BlockNode[] => {\n onRead();\n\n return snapshotNodes(reader).filter((n) => n.parentId === parentId);\n };\n\n const transact = (fn: () => void): void => {\n if (editor.blocks.transact !== undefined) {\n editor.blocks.transact(fn);\n } else {\n fn();\n }\n };\n\n /** Flat list of id + all transitive descendants, via the parentId graph. */\n const collectSubtreeIds = (rootId: string): string[] => {\n const nodes = snapshotNodes(reader);\n const childrenOf = new Map<string, string[]>();\n\n for (const n of nodes) {\n if (n.parentId === null) {\n continue;\n }\n const bucket = childrenOf.get(n.parentId) ?? [];\n\n bucket.push(n.id);\n childrenOf.set(n.parentId, bucket);\n }\n\n const out: string[] = [];\n const visited = new Set<string>();\n const stack: string[] = [rootId];\n\n // A parentId cycle (possible from a concurrent remote Yjs reparent) would\n // make this DFS spin forever — track visited ids and skip re-entry so each\n // block is emitted at most once and the traversal always terminates.\n while (stack.length > 0) {\n const id = stack.pop() as string;\n\n if (visited.has(id)) {\n continue;\n }\n visited.add(id);\n out.push(id);\n const kids = childrenOf.get(id);\n\n if (kids !== undefined) {\n stack.push(...kids);\n }\n }\n\n return out;\n };\n\n /** Each subtree member's parentId, captured from the current snapshot. */\n const captureSubtreeParents = (rootId: string): Array<{ id: string; parentId: string | null }> => {\n const parentOf = new Map(snapshotNodes(reader).map((n) => [n.id, n.parentId]));\n\n return collectSubtreeIds(rootId).map((id) => ({ id, parentId: parentOf.get(id) ?? null }));\n };\n\n /**\n * Relocate id AND its whole subtree to sit contiguously starting at a\n * PRE-removal flat slot. Blok's Blocks.move() is post-removal index space and\n * only carries DOM-contained descendants (resortNestedBlocks) — indent /\n * parentId-nested children are NOT, so move each subtree member that a single\n * root move didn't already pull into place. Keeps the flat array DFS-contiguous,\n * the invariant the flat-index insert API and getChildren ordering depend on.\n */\n const relocateSubtree = (rootId: string, preRemovalSlot: number): 'moved' | 'skipped' | 'blocked' => {\n // Subtree members in current flat (document) order — root first.\n const members = collectSubtreeIds(rootId)\n .map((id) => ({ id, idx: editor.blocks.getBlockIndex(id) }))\n .filter((m): m is { id: string; idx: number } => m.idx !== undefined)\n .sort((a, b) => a.idx - b.idx)\n .map((m) => m.id);\n\n const rootFrom = editor.blocks.getBlockIndex(rootId);\n\n if (rootFrom === undefined) {\n return 'blocked';\n }\n\n // Self-overlap guard. `preRemovalSlot` is the destination the caller\n // computed as the END of the (new or former) parent's WHOLE subtree — and\n // when that parent is an ANCESTOR of the relocating block (always so for\n // unnest, and for a nest into a block this one already sits under), that\n // span still CONTAINS this block's own subtree. Moving the root to a slot\n // at the tail of (or inside) its own footprint splices it in right after\n // one of its OWN descendants; core's post-move auto-heal then reparents the\n // block under that descendant (setBlockParent(B, B) when the neighbour is\n // the block's last child), which BlockHierarchy REFUSES with a thrown cycle\n // error — crashing the caller. But the block is already DFS-contiguous at\n // that destination (its subtree is the tail of the parent's subtree), so\n // the relocation is a no-op: skip the move and report 'skipped', leaving the\n // caller to assert the reparent. Window: `rootFrom < preRemovalSlot <=\n // subtreeEnd + 1`. A backward move (`preRemovalSlot <= rootFrom`) or a\n // genuine forward move past unrelated content (`preRemovalSlot > subtreeEnd\n // + 1`) is untouched.\n //\n // 'skipped' (vs 'moved') is reported DISTINCTLY because no `editor.blocks.\n // move()` ran — so core's post-move parent auto-heal never fired. nest/unnest\n // re-assert the root's parent explicitly (reparentSubtree), so they don't\n // care; but move() leans on that auto-heal for the root's parent-adoption, so\n // it must apply the adopted parent itself on this path (see move()).\n const subtreeEnd = collectSubtreeIds(rootId)\n .map((memberId) => editor.blocks.getBlockIndex(memberId))\n .filter((i): i is number => i !== undefined)\n .reduce((max, i) => Math.max(max, i), rootFrom);\n\n if (preRemovalSlot > rootFrom && preRemovalSlot <= subtreeEnd + 1) {\n return 'skipped';\n }\n\n // Defensive clamp into [0, count-1]: Blok's move() silently no-ops on an\n // out-of-range index, so an over-large preRemovalSlot would strand the\n // root instead of appending it. (In practice resolveInsertIndex stays in\n // range; this guards a concurrently-shrunk tree.)\n const lastIndex = Math.max(0, editor.blocks.getBlocksCount() - 1);\n const rootTarget = Math.min(\n Math.max(rootFrom < preRemovalSlot ? preRemovalSlot - 1 : preRemovalSlot, 0),\n lastIndex\n );\n\n editor.blocks.move(rootTarget, rootFrom);\n\n // Detect a BLOCKED relocation: Blok's move() clamps a cross-`column`-\n // boundary move to a no-op. If the root could not reach its target (it\n // didn't move and wasn't already there), the relocation failed — report\n // it so the caller skips the reparent that would otherwise corrupt DFS\n // contiguity (a child wedged outside its parent's flat run). A legitimate\n // no-op (already at target, rootFrom === rootTarget) still counts as\n // relocated so an in-place nest/unnest reparents as intended.\n if (rootFrom !== rootTarget && editor.blocks.getBlockIndex(rootId) === rootFrom) {\n return 'blocked';\n }\n\n // Place each descendant immediately after the previously-positioned member,\n // re-reading the anchor's LIVE index every iteration. A cached root index\n // (rootNew + k + 1) only holds for a BACKWARD relocation, where descendants\n // already sit after the root. For a FORWARD relocation each descendant\n // move() splices an element out from BEFORE the root, sliding the root (and\n // a cached index) down one slot per step — so the target overshoots, trips\n // Blocks.move()'s out-of-range no-op guard, and strands the descendant.\n // Re-anchoring to the predecessor's current slot absorbs the drift in both\n // directions and keeps the subtree DFS-contiguous. A descendant already in\n // place (carried by resortNestedBlocks for a DOM-nested child) is skipped.\n // The anchor for the k-th descendant is the (k-1)-th — read live each step.\n const descendants = members.filter((memberId) => memberId !== rootId);\n\n descendants.forEach((memberId, k) => {\n const anchorId = k === 0 ? rootId : descendants[k - 1];\n const from = editor.blocks.getBlockIndex(memberId);\n const anchor = editor.blocks.getBlockIndex(anchorId);\n\n if (from === undefined || anchor === undefined) {\n return;\n }\n const target = anchor + 1;\n\n if (from !== target) {\n editor.blocks.move(from < target ? target - 1 : target, from);\n }\n });\n\n return 'moved';\n };\n\n // Reparent `id` (root → newParentId, descendants → their original parent).\n // Re-asserting after relocateSubtree heals move()'s auto-reparent (which sets\n // a moved block's parentId to its new neighbour) and never relocates the flat\n // array, so contiguity established by relocateSubtree is preserved.\n const reparentSubtree = (\n members: Array<{ id: string; parentId: string | null }>,\n rootId: string,\n newParentId: string | null\n ): void => {\n for (const m of members) {\n editor.blocks.setBlockParent(m.id, m.id === rootId ? newParentId : m.parentId);\n }\n };\n\n // Re-assert ONLY the descendants' captured parents after a subtree relocation,\n // leaving the ROOT's parent as core's post-move auto-heal set it — used by\n // move(), whose documented side effect is that the root ADOPTS the parent of\n // the slot it lands in while its subtree travels with it.\n const reassertDescendantParents = (\n members: Array<{ id: string; parentId: string | null }>,\n rootId: string\n ): void => {\n members\n .filter((m) => m.id !== rootId)\n .forEach((m) => editor.blocks.setBlockParent(m.id, m.parentId));\n };\n\n /**\n * Whether `id` is a DIRECT child of a `column` block. Column membership is\n * owned by the drag UI, so a programmatic nest/unnest that would change it is\n * a graceful no-op (see the nest/unnest docs). Checking this EXPLICITLY makes\n * that contract reliable: relying on core's move-clamp alone leaks, because\n * when the relocation needs no actual move (a tail column child already sits\n * at its relocation target) no boundary-crossing move fires, so nothing\n * clamps and the reparent would slip through.\n */\n const isColumnChild = (id: string): boolean => {\n const parent = getById(id)?.parentId ?? null;\n\n return parent !== null && getById(parent)?.type === 'column';\n };\n\n /**\n * Nest `id` (and its whole subtree) under `parentId`, as one undo step.\n * No-op when either id is unknown (probed via the silent snapshot, NOT\n * getBlockIndex, which warns on unknown ids), or when `parentId` is `id`\n * itself or one of `id`'s own descendants — that would form a cycle, which\n * core's setBlockParent THROWS on, so the hook guards it up front.\n *\n * Column boundary caveat: nesting a block that lives inside a `column`, or\n * nesting directly INTO one, is a GRACEFUL no-op — column membership is owned\n * by the drag UI. This is detected explicitly (via the block's and target's\n * parent type), so the no-op holds even when no boundary-crossing move fires.\n * Returns void.\n */\n const nest = (id: string, parentId: string): void => {\n if (getById(parentId) === null || getById(id) === null) {\n return;\n }\n\n // Cycle guard: a block can't become a child of itself or of one of its\n // own descendants. Without this, the relocate/reparent reaches core's\n // setBlockParent, which throws on a cycle and crashes the caller.\n if (parentId === id || isDescendantOf(parentMap(reader), parentId, id)) {\n return;\n }\n\n // Column-boundary no-op: pulling a block out of a `column`, or pushing one\n // directly into a column, changes column membership — owned by the drag UI.\n if (isColumnChild(id) || getById(parentId)?.type === 'column') {\n return;\n }\n\n // Relocate id's whole subtree to after the new parent's existing subtree,\n // THEN assert the parents. Blok keeps the flat array as the canonical\n // document order, and the flat-index insert API only resolves a parent's\n // \"end\" slot when that parent's descendants are contiguous — a bare reparent\n // (no relocation) would wedge unrelated blocks between the parent and its new\n // child, corrupting later inserts/reads. Mirrors the drag move-then-reparent.\n //\n // Only reparent when the relocation actually placed the block: a clamped\n // cross-column move leaves it where it was, and reparenting in place would\n // break DFS contiguity.\n const members = captureSubtreeParents(id);\n\n transact(() => {\n // reparentSubtree sets the root's parent EXPLICITLY, so nest is correct on\n // both the 'moved' and 'skipped' paths — it only bails on a 'blocked'\n // (clamped cross-column) relocation.\n if (relocateSubtree(id, resolveInsertIndex(reader, parentId, 'end')) !== 'blocked') {\n reparentSubtree(members, id, parentId);\n }\n });\n };\n\n /**\n * Promote `id` (and its subtree) to root, as one undo step. No-op when the\n * id is unknown or already at root. Same column-boundary caveat as\n * {@link nest}: unnesting a `column` member out to root is a graceful no-op\n * (column membership changes go through the drag UI). Returns void.\n */\n const unnest = (id: string): void => {\n const node = getById(id);\n\n if (node === null) {\n return;\n }\n const parentId = node.parentId;\n\n if (parentId === null) {\n return;\n }\n\n // Column-boundary no-op: a column member is detached only via the drag UI.\n if (isColumnChild(id)) {\n return;\n }\n\n // Move id's subtree out past its former parent's whole subtree before\n // clearing the parent, so the promoted block doesn't strand itself between\n // the parent and its remaining children (which would break contiguity).\n // As with nest, only clear the parent when the relocation succeeded — a\n // clamped cross-column move must stay a graceful no-op.\n const members = captureSubtreeParents(id);\n\n transact(() => {\n // As with nest, reparentSubtree asserts the root's (null) parent on both\n // 'moved' and 'skipped'; only a 'blocked' clamp keeps it a no-op.\n if (relocateSubtree(id, resolveInsertIndex(reader, parentId, 'end')) !== 'blocked') {\n reparentSubtree(members, id, null);\n }\n });\n };\n\n const remove = (id: string): void => {\n if (editor.blocks.getBlockIndex(id) === undefined) {\n return;\n }\n\n // Remove the block AND its descendants. Blok's single-block delete promotes\n // a (non-columns) container's children to root, which would orphan the\n // nested structure the caller meant to discard. Delete deepest-first (by\n // descending flat index) so a parent is childless by the time it's deleted\n // (no promotion). One undo step.\n //\n // Re-resolve each member's index by id AT DELETE TIME rather than reusing a\n // pre-captured snapshot: a core delete can cascade (deleting a column's last\n // child auto-removes the empty column) or shift indices, so a stale index\n // could target the wrong — or an already-gone — block.\n const orderedIds = collectSubtreeIds(id)\n .map((subId) => ({ subId, index: editor.blocks.getBlockIndex(subId) }))\n .filter((m): m is { subId: string; index: number } => m.index !== undefined)\n .sort((a, b) => b.index - a.index)\n .map((m) => m.subId);\n\n transact(() => {\n for (const subId of orderedIds) {\n const index = editor.blocks.getBlockIndex(subId);\n\n // Already removed by a cascading delete of one of its descendants.\n if (index === undefined) {\n continue;\n }\n void editor.blocks.delete(index, false);\n }\n });\n };\n\n /**\n * Move `id` to a flat slot, as a single operation. No-op when `id` is\n * unknown (probed via the silent snapshot, NOT getBlockIndex, which warns on\n * unknown ids); when a relative `{ before|after }` target references `id`\n * itself, one of its descendants (a block can't be a sibling of its own\n * child), or a ref that does not exist (an unresolved relative target must\n * not silently dump the block at the document end); or for ANY absolute\n * `{ toIndex }` of a block that HAS descendants (a multi-block subtree can't\n * land on one index — see the subtree note below). Guards run BEFORE the\n * index is resolved into a final move.\n *\n * Parent-adoption side effect: `before`/`after` make the moved block a\n * SIBLING of the ref — it adopts the REF's parent (moving before/after a\n * child of a container nests it into that container; moving before/after a\n * root block unnests it to root). `after` clears the ref's WHOLE subtree, so\n * the block lands past the ref's descendants, not among them. The adopted\n * parent is the ref's — NOT the parent of whatever block happens to sit at the\n * landing slot, which would nest under the ref for `after` a ref-with-children.\n * Use {@link nest}/{@link unnest} to change the parent without choosing a\n * sibling slot. Returns void.\n *\n * Subtree-aware: a block WITH descendants relocates its WHOLE subtree as one\n * undo step (core's single move() carries only DOM-contained descendants, so\n * a naive move would strand indent/parentId-nested children before their\n * parent and corrupt DFS contiguity). Only relative `{ before|after }`\n * targets name an unambiguous slot for a multi-block subtree; an absolute\n * `{ toIndex }` of a block that HAS descendants is ambiguous (k blocks can't\n * all land on one index) and is a graceful no-op — use `{ before|after }` to\n * relocate a subtree.\n */\n const move = (id: string, target: MoveTarget): void => {\n // Silent existence probe (NOT getBlockIndex, which warns on unknown ids).\n if (getById(id) === null) {\n return;\n }\n // id is known, so getBlockIndex won't warn.\n const fromIndex = editor.blocks.getBlockIndex(id);\n\n if (fromIndex === undefined) {\n return;\n }\n\n if (!('toIndex' in target)) {\n const ref = 'before' in target ? target.before : target.after;\n\n // A relative target can't reference the block itself or any of its own\n // descendants — a block can't become a sibling of its child.\n if (ref === id || isDescendantOf(parentMap(reader), ref, id)) {\n return;\n }\n\n // An unresolved relative ref must NOT fall through to a relocate-to-end:\n // a missing target is a no-op, not a surprise jump to the document end.\n if (getById(ref) === null) {\n return;\n }\n }\n // NB: an absolute { toIndex } needs no early guard here. A block WITH\n // descendants no-ops EVERY toIndex move in the subtree branch below\n // (ambiguous for a multi-block subtree); a leaf has no own-subtree range to\n // land inside. So a dedicated \"toIndex inside own subtree\" guard would be\n // dead code — the subtree-branch no-op already covers the cycle it guarded.\n\n // Subtree-aware relocation. A block WITH descendants can't ride a single\n // core move(): core carries only DOM-contained descendants (resortNested\n // Blocks), so indent/parentId-nested children are left at their old slot —\n // stranded BEFORE their now-moved parent in flat order, breaking the DFS\n // contiguity getChildren ordering and flat-index inserts depend on, and\n // corrupting saved document order. Relocate the whole subtree (as\n // nest/unnest do) and re-assert each descendant's own parent; the ROOT\n // keeps the parent core's post-move auto-heal gives it — move()'s\n // documented parent-adoption side effect — so only descendants are\n // re-parented. A blocked relocation (a clamped cross-`column` move) leaves\n // everything in place, a graceful no-op like nest/unnest. An absolute\n // { toIndex } is ambiguous for a multi-block subtree (see the move() doc),\n // so it is a graceful no-op here — relative targets relocate the subtree.\n // A leaf block (no descendants) falls through to the single-move fast path.\n const subtreeMembers = captureSubtreeParents(id);\n\n if (subtreeMembers.length > 1) {\n if ('toIndex' in target) {\n return;\n }\n\n const preRemovalSlot = resolveMoveIndex(reader, target);\n // The relative ref whose parent the moved block adopts (toIndex returned\n // above, so target is { before | after }).\n const ref = 'before' in target ? target.before : target.after;\n\n transact(() => {\n const outcome = relocateSubtree(id, preRemovalSlot);\n\n if (outcome === 'blocked') {\n return;\n }\n reassertDescendantParents(subtreeMembers, id);\n\n // Adopt the REF's parent (sibling-of-ref) on BOTH the 'moved' and\n // 'skipped' paths. The position is already sibling-of-ref: resolveMoveIndex\n // clears the ref's WHOLE subtree for `after` and uses the ref's own slot\n // for `before`, so id lands as the ref's sibling. The parent must match.\n // Core's post-move auto-heal does NOT give that — it adopts the parent of\n // the block at the landing SLOT (pre-removal), which for `after` a\n // ref-with-descendants is the ref's last descendant (parent = the ref →\n // nests id UNDER the ref) and for `before` a ref whose flat predecessor\n // sits in another container is that predecessor's parent. On the 'skipped'\n // path no move() ran, so no auto-heal fired at all. Assert ref.parentId so\n // position and parent agree regardless of path. Guarded (mirrors\n // insertWithinTransaction) so a same-container reorder — the common case,\n // where the landed parent already matches — fires no redundant reparent.\n // Can't cycle: ref is neither id nor a descendant (guarded above), so\n // ref's parent is outside id's subtree.\n const intendedParent = getById(ref)?.parentId ?? null;\n\n if ((getById(id)?.parentId ?? null) !== intendedParent) {\n editor.blocks.setBlockParent(id, intendedParent);\n }\n });\n\n return;\n }\n\n const resolved = resolveMoveIndex(reader, target);\n\n // Blok's Blocks.move() removes the block (splice fromIndex) BEFORE\n // re-inserting at toIndex, so toIndex lives in the POST-removal index\n // space. For a relative (before/after) forward move the reference index\n // shifts down by one once the block is removed, so compensate — this also\n // keeps a move-to-end within Blok's `toIndex < length` bound. A literal\n // { toIndex } is the caller's explicit final resting index: pass through.\n const isRelative = !('toIndex' in target);\n const toIndex = isRelative && fromIndex < resolved ? resolved - 1 : resolved;\n\n if (!isRelative) {\n // Absolute { toIndex }: the caller chose the slot, so let core's auto-heal\n // adopt that slot's container (the documented absolute-move semantics).\n editor.blocks.move(toIndex, fromIndex);\n\n return;\n }\n\n // Relative leaf move: same sibling-of-ref rule as the subtree branch — the\n // moved block adopts the REF's parent, not the landing-slot neighbour's\n // (which auto-heal would give: the ref's descendant for `after`, or a\n // cross-container predecessor for `before`). Assert it in the same undo step\n // as the move, guarded so a same-container reorder fires no redundant\n // reparent. Can't cycle: ref is guarded to be neither id nor a descendant,\n // and a leaf has no descendants for ref's parent to fall inside.\n const ref = 'before' in target ? target.before : target.after;\n\n transact(() => {\n editor.blocks.move(toIndex, fromIndex);\n const intendedParent = getById(ref)?.parentId ?? null;\n\n if ((getById(id)?.parentId ?? null) !== intendedParent) {\n editor.blocks.setBlockParent(id, intendedParent);\n }\n });\n };\n\n /**\n * Perform one insert (create + intended-parent assertion) WITHOUT opening a\n * transaction — the caller owns the undo grouping. `insert` wraps a single\n * call in its own transact; `insertMany` shares ONE transact across the whole\n * batch so the bulk insert is a single undo step. Returns the created node,\n * or null when nothing was inserted (idempotent hit returns the existing\n * node; a guard failure returns null).\n */\n const insertWithinTransaction = (spec: InsertSpec): { node: BlockNode | null; created: boolean } => {\n const parentId = spec.parentId ?? null;\n const position = spec.position ?? 'end';\n const data = spec.data ?? {};\n // Programmatic insert must not steal the caret unless explicitly asked.\n const needToFocus = spec.focus ?? false;\n const replace = spec.replace ?? false;\n\n // Every pre-insert guard (id-exists, dangling-parent, missing-ref) and the\n // replace-parent lookup used to call `getById`, which re-enumerates the\n // WHOLE tree each time — O(probes·n) per spec, O(k·probes·n) per batch.\n // The tree can't change until `editor.blocks.insert` runs below, so take\n // ONE snapshot here and resolve every pre-insert probe against it.\n const preById = new Map(snapshotNodes(reader).map((n) => [n.id, n]));\n const probe = (id: string): BlockNode | null => preById.get(id) ?? null;\n\n // Idempotent insert-if-absent: a stable explicit id that already exists\n // returns the existing node without inserting a duplicate, so a re-running\n // effect is safe. Probe via the silent snapshot getById, NOT\n // editor.blocks.getBlockIndex — the latter logs a `warn` for any unknown\n // id, which would spam the console on this (expected-absent) happy path.\n //\n // Skipped under `replace`: a replace is an explicit overwrite, not an\n // insert, so an existing id must not short-circuit it (the two would\n // otherwise silently conflict and replace nothing).\n if (spec.id !== undefined && !replace) {\n const existing = probe(spec.id);\n\n if (existing !== null) {\n // Insert-if-absent hit: the block already existed, nothing was created.\n // insert() still returns the existing node (documented), but insertMany\n // must EXCLUDE it from its created[] result — hence created: false.\n return { node: existing, created: false };\n }\n }\n\n // A dangling parentId would make core throw (dev) or silently misplace the\n // block at the document end (prod). Honor the null contract instead. Probe\n // via the silent snapshot getById, NOT editor.blocks.getBlockIndex, which\n // logs a `warn` for any unknown id and would spam the console on this\n // expected-absent no-op path. Skipped under replace: a replace ignores\n // parentId entirely (the overwritten block's own parent governs), so a\n // stale parentId must not abort the overwrite.\n if (!replace && parentId !== null && probe(parentId) === null) {\n return { node: null, created: false };\n }\n\n // A replace targets the before/after ref block ITSELF (the \"turn into\"\n // block being overwritten), not a sibling anchor. It therefore REQUIRES an\n // object position naming that ref:\n // - with position 'start'/'end' (or omitted) there is no target ref, so\n // a replace has nothing to overwrite — return null rather than silently\n // overwriting whatever block happens to sit at the resolved slot;\n // - with an object position whose ref doesn't exist there is likewise\n // nothing to overwrite — return null instead of falling through to\n // resolveInsertIndex's end-slot fallback (which would insert/replace at\n // the wrong place and reparent a dangling target).\n // Validation is skipped for a plain insert (above), so this is the only\n // guard that protects the replace path.\n if (replace) {\n if (typeof position !== 'object') {\n return { node: null, created: false };\n }\n\n const replaceTargetRef = 'before' in position ? position.before : position.after;\n\n if (probe(replaceTargetRef) === null) {\n return { node: null, created: false };\n }\n }\n\n // A plain insert with an object position naming a ref that does NOT exist\n // must be a no-op (return null), NOT a silent append at the document/parent\n // end. resolveInsertIndex falls back to the end slot for an unresolved ref,\n // which would dump the block somewhere surprising — a DX footgun. Mirror\n // move(), which already bails on a missing relative ref. (Skipped under\n // replace: the block above already validated the replace ref.)\n if (!replace && typeof position === 'object') {\n const positionTargetRef = 'before' in position ? position.before : position.after;\n\n if (probe(positionTargetRef) === null) {\n return { node: null, created: false };\n }\n }\n\n const flatIndex = resolveInsertIndex(reader, parentId, position, replace);\n\n // A replace is a positional type-swap that PRESERVES the replaced block's\n // parent link, so the intended parent is the target's existing parent, not\n // the caller's (root-defaulting) parentId. Capture it from the pre-insert\n // snapshot so the post-insert assertion re-nests the replacement correctly\n // instead of un-nesting it to root. A plain insert uses parentId as-is.\n const positionRef = ((): string | null => {\n if (typeof position !== 'object') {\n return null;\n }\n\n return 'before' in position ? position.before : position.after;\n })();\n const replaceRef = replace ? positionRef : null;\n const intendedParentId =\n replaceRef !== null ? probe(replaceRef)?.parentId ?? null : parentId;\n\n const created = ((): { id: string } | null | undefined => {\n try {\n return editor.blocks.insert(spec.type, data, {}, flatIndex, needToFocus, replace, spec.id, spec.tunes);\n } catch (error) {\n // The only EXPECTED throw here is an unknown/missing tool — core throws\n // a typed ToolNotFoundError. (A missing replace TARGET is a bare Error,\n // not this type, so it would re-throw — but the replace ref is already\n // pre-validated above, so it never reaches here.) Honor the null contract\n // for ToolNotFoundError; re-throw anything else so a genuine\n // bug surfaces instead of being masked as a null return. Keyed on the\n // error TYPE, not a 'not found' substring, so an unrelated error whose\n // message happens to contain \"not found\" is not wrongly swallowed.\n if (error instanceof ToolNotFoundError) {\n return null;\n }\n throw error;\n }\n })();\n\n if (created === undefined || created === null) {\n return { node: null, created: false };\n }\n\n // Assert the intended parent. Core derives a new block's parent from its\n // flat predecessor, so a block appended right after a `column` child is\n // auto-nested into that column. We know the caller's intent: for a\n // parented insert set the parent; for a root insert (parentId === null)\n // override back to root ONLY if core nested it, keeping the natural\n // `insert({ position: 'end' })` a root sibling instead of a stowaway. For\n // a replace, intendedParentId is the overwritten block's own parent, so\n // the replacement keeps its place in the tree.\n // ONE post-insert snapshot for both the landed-parent check and the return\n // node (was two separate getById enumerations). A freshly-created block has\n // no children, so reparenting it only flips its own parentId — its derived\n // contentIds stay `[]`. We therefore reconstruct the corrected node in place\n // rather than re-enumerating the tree a third time after setBlockParent.\n const createdNode = snapshotNodes(reader).find((n) => n.id === created.id) ?? null;\n const landedParentId = createdNode?.parentId ?? null;\n\n const node =\n landedParentId === intendedParentId\n ? createdNode\n : ((): BlockNode | null => {\n editor.blocks.setBlockParent(created.id, intendedParentId);\n\n return createdNode === null ? null : { ...createdNode, parentId: intendedParentId };\n })();\n\n // Position the caret inside the freshly-created block when the caller asked\n // for a specific spot (beyond the boolean `focus`). Applied only on a real\n // creation — an insert-if-absent hit returned earlier, so it never reaches\n // here. setToBlock takes the block id directly.\n if (spec.caret !== undefined) {\n editor.caret.setToBlock(created.id, spec.caret.position ?? 'default', spec.caret.offset ?? 0);\n }\n\n return { node, created: true };\n };\n\n /**\n * Insert one block. Returns the created {@link BlockNode}, or null when the\n * insert is rejected — an unknown tool type (core \"…not found\"), a dangling\n * `parentId`, or a `replace` whose target ref doesn't exist. An explicit\n * `id` that already exists is insert-if-absent: the existing node is returned\n * and nothing is created (skipped under `replace`, which is an explicit\n * overwrite). Validation runs BEFORE the slot is resolved; a `replace`\n * preserves the overwritten block's parent. Always one atomic undo step.\n *\n * The returned node is a fresh-snapshot view (its `contentIds` are derived\n * per call) — read it immediately; do NOT place it in a `useMemo`/`useEffect`\n * dependency array expecting per-mutation identity.\n */\n const insert = (spec: InsertSpec = {}): BlockNode | null => {\n // Mutable property on a const holder (no `let`): the node captured from\n // inside the transact closure for the post-transact return.\n const result: { node: BlockNode | null } = { node: null };\n\n // Always atomic: a single undo step removes the new block (and, for a\n // parented insert, its reparent) — and gives the insert its own boundary\n // instead of merging into adjacent typing history.\n transact(() => {\n // insert() returns the resolved node — including an insert-if-absent hit's\n // existing node (documented) — so it reads only `.node`, not `.created`.\n result.node = insertWithinTransaction(spec).node;\n });\n\n return result.node;\n };\n\n const insertMany = (specs: InsertSpec[]): BlockNode[] => {\n // An empty batch opens no transaction (no spurious undo boundary).\n if (specs.length === 0) {\n return [];\n }\n\n const created: BlockNode[] = [];\n\n // ONE transact for the whole batch → a single atomic undo step. Each spec\n // still runs the full single-insert path (parent assertion, positioning).\n // Per the documented contract, the result holds ONLY successfully-created\n // nodes: specs that fail to insert (null node) AND insert-if-absent hits\n // (existing block, created: false) are both dropped.\n transact(() => {\n for (const spec of specs) {\n const result = insertWithinTransaction(spec);\n\n if (result.created && result.node !== null) {\n created.push(result.node);\n }\n }\n });\n\n return created;\n };\n\n /**\n * Insert a pre-built nested subtree as ONE atomic operation. See the\n * {@link UseBlocksApi.insertTree} contract. Flattens the spec to a DFS\n * pre-order `OutputBlockData[]` — wiring every node's `parent`/`content`\n * links from ids generated up front — then delegates to core's tree-aware\n * `blocks.insertMany` inside a single transact.\n */\n const insertTree = (spec: TreeInsertSpec): BlockNode | null => {\n const parentId = spec.parentId ?? null;\n const position = spec.position ?? 'end';\n\n // Dangling root parentId: mirror `insert`'s guard via the silent snapshot\n // getById (NOT getBlockIndex, which warns on unknown ids). Reject so the\n // subtree isn't silently dumped at the document end.\n if (parentId !== null && getById(parentId) === null) {\n return null;\n }\n\n // Dangling relative position ref: an object { before|after } naming a block\n // that does not exist must be a no-op, NOT a silent append at the document\n // end (resolveInsertIndex's unresolved-ref fallback). Mirror insert()'s\n // missing-ref guard and reject before flattening anything.\n if (typeof position === 'object') {\n const positionTargetRef = 'before' in position ? position.before : position.after;\n\n if (getById(positionTargetRef) === null) {\n return null;\n }\n }\n\n // Flatten the nested spec to a DFS pre-order array with wired\n // `parent`/`content` links — the same transform used to seed nested data,\n // shared as the pure `flattenTree` helper. `parentId` becomes the root's\n // `parent`. flattenTree throws on an id reused WITHIN the spec (a duplicate\n // would corrupt every id-keyed lookup); a tree insert always creates fresh\n // blocks (NOT insert-if-absent), so that is rejected up front — null,\n // mirroring insert's null contract.\n const flat = (() => {\n try {\n return flattenTree(spec, { parentId: parentId ?? undefined });\n } catch {\n return null;\n }\n })();\n\n if (flat === null) {\n return null;\n }\n\n // External collision: an explicit id already present in the live tree would\n // also create a duplicate-id block. Snapshot the existing ids once and\n // reject if any flat node reuses one. Generated ids never collide.\n const existingIds = new Set(snapshotNodes(reader).map((n) => n.id));\n\n if (flat.some((node) => existingIds.has(node.id))) {\n return null;\n }\n\n const rootId = flat[0].id;\n\n // flattenTree omits `content` on leaves (clean seed-data shape). insertMany\n // wants every node to carry an explicit child-id array — a leaf's\n // `contentIds: []` states \"no children\" rather than leaving it undefined —\n // so stamp the empty array back on before handing the batch to core.\n for (const node of flat) {\n if (node.content === undefined) {\n node.content = [];\n }\n }\n\n const flatIndex = resolveInsertIndex(reader, parentId, position);\n\n // ONE transact for the whole subtree → a single atomic undo step. Core's\n // insertMany composes EVERY node before inserting any, so an unknown tool\n // type throws a typed ToolNotFoundError with nothing inserted. Honor the\n // same null-on-unknown-tool contract as insert/insertMany rather than\n // surfacing the throw to the caller; re-throw any other (genuine-bug)\n // error. Keyed on the error TYPE, not a 'not found' substring.\n try {\n transact(() => {\n editor.blocks.insertMany(flat, flatIndex);\n });\n } catch (error) {\n if (error instanceof ToolNotFoundError) {\n return null;\n }\n throw error;\n }\n\n return getById(rootId);\n };\n\n /**\n * Convert markdown to blocks and insert them ADDITIVELY — see the\n * {@link UseBlocksApi.insertMarkdown} doc for the full contract. Async\n * because the converter is lazy-loaded; the insert itself is one atomic\n * undo step. parentId nesting is supported: top-level converted blocks are\n * reparented under parentId, internally-nested ones keep their parent.\n */\n const insertMarkdown = async (\n markdown: string,\n options?: { parentId?: string | null; position?: InsertPosition; config?: MarkdownImportConfig }\n ): Promise<BlockNode[]> => {\n const parentId = options?.parentId ?? null;\n const position = options?.position ?? 'end';\n\n // A dangling parentId is a no-op (no insert), matching `insert`/`insertMany`.\n if (parentId !== null && getById(parentId) === null) {\n return [];\n }\n\n // A dangling relative position ref is likewise a no-op (no insert), NOT a\n // silent append at the document end — mirror insert()/insertTree's guard.\n if (typeof position === 'object') {\n const positionTargetRef = 'before' in position ? position.before : position.after;\n\n if (getById(positionTargetRef) === null) {\n return [];\n }\n }\n\n // Lazy-load the converter (dynamic import mirrors core's markdown lazy\n // loading and keeps the parser out of the main bundle) and run it,\n // forwarding the optional MarkdownImportConfig so custom-tool consumers can\n // map markdown nodes into their tools (gfm toggle, toolMap, extensions).\n // Both awaits can fail — a chunk-load error or a malformed-markdown throw;\n // swallow them and return [] so a converter failure is a graceful no-op\n // (matching update/convert) rather than an unhandled promise rejection in\n // the caller. This await resolves BEFORE the synchronous transact.\n // Mutable property on a const holder (no `let`): captured from the try.\n const conversion: { blocks: OutputBlockData[] } = { blocks: [] };\n\n try {\n const { markdownToBlocks } = await import('@bloklabs/core/markdown');\n\n conversion.blocks = await markdownToBlocks(markdown, options?.config);\n } catch (error) {\n // Graceful no-op: a converter failure (chunk-load or parse error) returns\n // [] rather than surfacing an unhandled rejection to the caller. But\n // surface it to the console so a genuine converter bug is DISTINGUISHABLE\n // from empty markdown (which returns [] via the blocks.length === 0 path\n // below, without ever reaching this catch) instead of being swallowed\n // silently and losing all diagnostics.\n console.warn('useBlocks.insertMarkdown: markdown conversion failed', error);\n\n return [];\n }\n\n const blocks = conversion.blocks;\n\n // Empty / whitespace-only markdown opens no transaction (no undo boundary).\n if (blocks.length === 0) {\n return [];\n }\n\n // Re-validate the parent AFTER the await: the pre-await existence check can\n // go stale if the parent was removed while the converter was in flight.\n // Stamping a now-dangling parent would orphan the blocks instead of the\n // promised [] no-op, so re-check and bail out here.\n if (parentId !== null && getById(parentId) === null) {\n return [];\n }\n\n // Re-validate the relative position ref after the await too: the target\n // could have been removed while the converter was in flight, in which case\n // inserting at the stale slot would surprise the caller. No-op instead.\n if (typeof position === 'object') {\n const positionTargetRef = 'before' in position ? position.before : position.after;\n\n if (getById(positionTargetRef) === null) {\n return [];\n }\n }\n\n // Nest under the parent by stamping `parent` on each TOP-LEVEL block (one\n // the converter left un-parented). Blocks the markdown nested internally\n // (their `parent` already points at a sibling in this batch) are untouched,\n // so the import's own structure is preserved.\n const seeded: OutputBlockData[] =\n parentId === null\n ? blocks\n : blocks.map((block) =>\n block.parent === undefined || block.parent === null\n ? { ...block, parent: parentId }\n : block\n );\n\n const flatIndex = resolveInsertIndex(reader, parentId, position);\n\n // Mutable property on a const holder (no `let`): captured from inside the\n // transact closure. insertMany returns BlockAPI[] (each has `.id`) — the\n // reliable record of what was created, since the converter's ids may not\n // survive composition. ONE transact → a single atomic undo step.\n const result: { created: Array<{ id: string }> } = { created: [] };\n\n // The insert lives OUTSIDE the conversion try/catch, so an unknown mapped\n // tool (core throws a typed ToolNotFoundError) would otherwise surface as an\n // unhandled promise rejection. Honor the same null-on-unknown-tool contract\n // as insertTree — return [] — and re-throw any other (genuine-bug) error.\n // Keyed on the error TYPE, not a 'not found' substring.\n try {\n transact(() => {\n result.created = editor.blocks.insertMany(seeded, flatIndex);\n });\n } catch (error) {\n if (error instanceof ToolNotFoundError) {\n return [];\n }\n throw error;\n }\n\n return result.created\n .map((block) => getById(block.id))\n .filter((node): node is BlockNode => node !== null);\n };\n\n const update = (\n id: string,\n data?: BlockToolData,\n tunes?: { [name: string]: BlockTuneData }\n ): void => {\n // Silent existence probe (NOT getBlockIndex, which warns on unknown ids).\n if (getById(id) === null) {\n return;\n }\n\n // Core update is async and forms its own undo/Yjs step, so it is NOT\n // wrapped in transact (that would close the group before the write lands).\n // Swallow any rejection so it can't surface as an unhandled rejection.\n void Promise.resolve(editor.blocks.update(id, data, tunes)).catch(() => undefined);\n };\n\n const convert = (\n id: string,\n newType: string,\n dataOverrides?: BlockToolData,\n options?: { caret?: CaretTarget }\n ): void => {\n if (getById(id) === null) {\n return;\n }\n\n // Core convert is async and rejects when a tool lacks a conversionConfig.\n // Like update, it owns its own history step (no transact). Position the\n // caret only AFTER a successful convert (matching the in-editor keyboard\n // turn-into, which preserves the caret) when the caller asked for it.\n // Swallow the rejection so a non-convertible block is a graceful no-op —\n // and on rejection the caret is left untouched.\n void Promise.resolve(editor.blocks.convert(id, newType, dataOverrides))\n .then((converted) => {\n if (options?.caret !== undefined) {\n // Core convert routes through replace(), which regenerates the block\n // id — the resolved BlockAPI carries the NEW id. Target it (falling\n // back to the original only if a faithless path resolves nothing) so\n // the caret lands in the converted block instead of a stale id.\n const targetId = converted?.id ?? id;\n\n editor.caret.setToBlock(\n targetId,\n options.caret.position ?? 'default',\n options.caret.offset ?? 0\n );\n }\n })\n .catch(() => undefined);\n };\n\n const transactWithoutCapture = (fn: () => void): void => {\n if (editor.blocks.transactWithoutCapture !== undefined) {\n editor.blocks.transactWithoutCapture(fn);\n } else {\n fn();\n }\n };\n\n const getBlocksCount = (): number => {\n onRead();\n\n return editor.blocks.getBlocksCount();\n };\n\n const getCurrentBlockIndex = (): number => {\n onRead();\n\n return editor.blocks.getCurrentBlockIndex();\n };\n\n const getBlockByIndex = (index: number): BlockNode | null => {\n onRead();\n const block = editor.blocks.getBlockByIndex(index);\n\n return block === undefined ? null : getById(block.id);\n };\n\n const getBlockByElement = (element: HTMLElement): BlockNode | null => {\n onRead();\n const block = editor.blocks.getBlockByElement(element);\n\n return block === undefined ? null : getById(block.id);\n };\n\n const composeBlockData = (toolName: string): Promise<BlockToolData> =>\n editor.blocks.composeBlockData(toolName);\n\n const getBlockData = (\n id: string\n ): { data: BlockToolData; tunes: { [name: string]: BlockTuneData } } | null => {\n // Silent existence probe via the snapshot getById (NOT editor.blocks.getById,\n // which logs a `warn` for an unknown id) so a miss is a quiet null, matching\n // getBlockIndex and the other id-taking readers.\n if (getById(id) === null) {\n return null;\n }\n\n const block = editor.blocks.getById(id);\n\n if (block === null) {\n return null;\n }\n\n // preservedData/preservedTunes are core's SYNCHRONOUS last-extracted view —\n // the same snapshot clipboard ops read. Returning it (rather than the async\n // save()) keeps this reader synchronous so a block can be read and re-inserted\n // (duplicated) inside one render/handler without the ref escape hatch.\n return { data: block.preservedData, tunes: block.preservedTunes };\n };\n\n const getBlockIndex = (id: string): number | null => {\n if (getById(id) === null) {\n // Silent existence probe (NOT editor.blocks.getBlockIndex, which warns on\n // unknown ids) so a miss is a quiet null, matching every other reader.\n return null;\n }\n\n return editor.blocks.getBlockIndex(id) ?? null;\n };\n\n const renderFromHTML = (html: string): Promise<void> => editor.blocks.renderFromHTML(html);\n\n const splitBlock = (\n currentBlockId: string,\n currentBlockData: Partial<BlockToolData>,\n newBlockType: string,\n newBlockData: BlockToolData,\n insertIndex: number\n ): BlockNode | null => {\n // Silent no-op for an unknown current block, matching every other id-taking\n // mutator. Probe via the snapshot getById (NOT getBlockIndex, which warns).\n if (getById(currentBlockId) === null) {\n return null;\n }\n\n // A negative insertIndex is malformed — core would forward it to a splice\n // (which counts from the array end) and silently split at the wrong slot.\n // Honor the silent-no-op convention instead (consistent with\n // insertOutputData's negative-index guard): return null without touching core.\n if (insertIndex < 0) {\n return null;\n }\n\n // An unknown newBlockType makes core's compose path throw a typed\n // ToolNotFoundError — honor the null contract (mirroring insert/insertTree);\n // re-throw any other (genuine-bug) error. Keyed on the error TYPE.\n const created = ((): { id: string } | null | undefined => {\n try {\n return editor.blocks.splitBlock(\n currentBlockId,\n currentBlockData,\n newBlockType,\n newBlockData,\n insertIndex\n );\n } catch (error) {\n if (error instanceof ToolNotFoundError) {\n return null;\n }\n throw error;\n }\n })();\n\n return created === undefined || created === null ? null : getById(created.id);\n };\n\n const insertOutputData = (\n blocks: OutputBlockData[],\n options?: { index?: number }\n ): BlockNode[] => {\n // An empty batch opens no transaction (no spurious undo boundary).\n if (blocks.length === 0) {\n return [];\n }\n\n // A negative index is malformed — core throws a bare validation Error. Honor\n // the silent-no-op convention instead: return [] without inserting (no\n // transaction, no surprise end-append), consistent with the rest of the API.\n if (options?.index !== undefined && options.index < 0) {\n return [];\n }\n\n // ONE transact for the whole batch → a single atomic undo step. Delegates\n // to core's raw insertMany, which honors each block's parent/content links.\n // Honor the same null/[]-on-unknown-tool contract as insertTree (core throws\n // a typed ToolNotFoundError); re-throw any other (genuine-bug) error.\n const result: { created: Array<{ id: string }> } = { created: [] };\n\n try {\n transact(() => {\n result.created =\n options?.index !== undefined\n ? editor.blocks.insertMany(blocks, options.index)\n : editor.blocks.insertMany(blocks);\n });\n } catch (error) {\n if (error instanceof ToolNotFoundError) {\n return [];\n }\n throw error;\n }\n\n return result.created\n .map((block) => getById(block.id))\n .filter((node): node is BlockNode => node !== null);\n };\n\n /**\n * Insert one child block under `parentId` at flat `insertIndex`, atomically.\n * Delegates to core's `insertInsideParent`, which groups the block creation\n * AND the parent assignment into a single undo entry itself — so this is NOT\n * wrapped in the hook's `transact` (that would be a redundant nested group).\n * A dangling parentId is a no-op (null), mirroring `insert`'s parent guard;\n * an unknown child tool throws a typed ToolNotFoundError from core's compose\n * path — honor the null contract and re-throw anything else (genuine bug).\n */\n const insertInsideParent = (\n parentId: string,\n insertIndex: number,\n childData?: BlockToolData\n ): BlockNode | null => {\n // Silent existence probe (NOT getBlockIndex, which warns on unknown ids).\n if (getById(parentId) === null) {\n return null;\n }\n\n const created = ((): { id: string } | null | undefined => {\n try {\n return editor.blocks.insertInsideParent(parentId, insertIndex, childData);\n } catch (error) {\n if (error instanceof ToolNotFoundError) {\n return null;\n }\n throw error;\n }\n })();\n\n return created === undefined || created === null ? null : getById(created.id);\n };\n\n /**\n * Replace the whole document with saved {@link OutputData} — a document-LOAD\n * primitive (clears existing content first), the counterpart of the additive\n * {@link insertOutputData}. Pure delegation to core's async `render`.\n */\n const render = (data: OutputData): Promise<void> => editor.blocks.render(data);\n\n /** Remove every block — document reset. Pure delegation to core's async `clear`. */\n const clear = (): Promise<void> => editor.blocks.clear();\n\n /**\n * Serialize the document to Markdown — the read-side twin of\n * {@link UseBlocksApi.insertMarkdown}. Pure delegation to core's async\n * `exportMarkdown` (which lazy-loads the serializer).\n */\n const exportMarkdown = (): Promise<string> => editor.blocks.exportMarkdown();\n\n /**\n * The LIVE Yjs-sync flag, read at call time (the api handle is memoized, so a\n * cached property would go stale). Pure delegation to core's read-only flag.\n */\n const isSyncingFromYjs = (): boolean => {\n onRead();\n\n return editor.blocks.isSyncingFromYjs;\n };\n\n // Every key is listed EXPLICITLY — do NOT spread `...EMPTY_API` here. The\n // return is typed `UseBlocksApi`, so an explicit list makes a forgotten live\n // wiring a COMPILE error (missing property). Spreading EMPTY_API would instead\n // backfill the missing key with its pre-ready no-op stub, silently shipping a\n // method that does nothing when the editor IS ready — a hole no key-presence\n // test can catch (the key is present, just wrong). Keep it exhaustive.\n return {\n getById,\n getChildren,\n insert,\n insertMany,\n insertTree,\n insertMarkdown,\n exportMarkdown,\n move,\n nest,\n unnest,\n remove,\n update,\n convert,\n transact,\n transactWithoutCapture,\n getBlocksCount,\n getCurrentBlockIndex,\n getBlockByIndex,\n getBlockByElement,\n getBlockData,\n getBlockIndex,\n composeBlockData,\n renderFromHTML,\n insertOutputData,\n splitBlock,\n insertInsideParent,\n render,\n clear,\n isSyncingFromYjs,\n };\n};\n","import type { ReadOnlyModeConfig } from '@bloklabs/core';\n\n/**\n * Normalized shape of the `readOnly` config option\n */\nexport interface NormalizedReadOnlyConfig {\n enabled: boolean;\n hideControls: boolean;\n}\n\n/**\n * Single source of truth for interpreting the `readOnly` config option.\n * The object form always means read-only is enabled.\n * @param value - raw `readOnly` value from BlokConfig\n */\nexport function normalizeReadOnlyConfig(value: boolean | ReadOnlyModeConfig | undefined): NormalizedReadOnlyConfig {\n if (typeof value === 'object' && value !== null) {\n return { enabled: true, hideControls: value.hideControls === true };\n }\n\n return { enabled: value === true, hideControls: false };\n}\n","/**\n * Structural deep equality for JSON-like values (Blok `OutputData`).\n *\n * Framework-agnostic: shared by the React and Angular adapters to dedupe\n * reactive `data` updates so identical content does not trigger a redundant\n * re-render that would clobber the caret/selection. Handles the value shapes\n * that appear in editor data: plain objects, arrays, and primitives (including\n * `null`/`undefined`).\n * @param a - first value to compare\n * @param b - second value to compare\n * @returns true when both values are structurally equal\n */\nexport function deepEqual(a: unknown, b: unknown): boolean {\n if (a === b) {\n return true;\n }\n\n if (typeof a !== 'object' || a === null || typeof b !== 'object' || b === null) {\n return false;\n }\n\n const aIsArray = Array.isArray(a);\n const bIsArray = Array.isArray(b);\n\n if (aIsArray !== bIsArray) {\n return false;\n }\n\n if (aIsArray && bIsArray) {\n if (a.length !== b.length) {\n return false;\n }\n\n return a.every((item, index) => deepEqual(item, b[index]));\n }\n\n const aObj = a as Record<string, unknown>;\n const bObj = b as Record<string, unknown>;\n const aKeys = Object.keys(aObj);\n const bKeys = Object.keys(bObj);\n\n if (aKeys.length !== bKeys.length) {\n return false;\n }\n\n return aKeys.every(\n (key) => Object.prototype.hasOwnProperty.call(bObj, key) && deepEqual(aObj[key], bObj[key])\n );\n}\n","import type { LooseOutputBlockData, LooseOutputData, OutputBlockData, OutputData } from '@bloklabs/core';\n/**\n * Public utilities for working with saved editor documents (`OutputData`).\n *\n * Consumers persisting editor content need two recurring predicates that the\n * editor itself already relies on internally:\n *\n * - structural equality, to dedupe the `data → render → onSave → data` echo\n * round-trip without clobbering the caret;\n * - emptiness, to decide whether a document carries any user content\n * (placeholder states, \"save\" button gating, skipping empty submissions).\n *\n * Both accept the loose wire shape (`data: null`, `id: null`, nullish\n * documents) so backend DTOs can be passed as-is.\n */\nimport { deepEqual } from './deep-equal';\n\n\ntype AnyOutputData = OutputData | LooseOutputData | null | undefined;\n\n/**\n * Compares two blocks structurally. The `id` participates only when BOTH\n * blocks carry one: the editor mints a fresh id whenever content arrives\n * without one (see {@link normalizeOutputBlocks}), so an id-less origin\n * document must still compare equal to its saved echo.\n * @param a - first block to compare\n * @param b - second block to compare\n * @returns true when the blocks are structurally equal\n */\nfunction equalsOutputBlock(\n a: OutputBlockData | LooseOutputBlockData,\n b: OutputBlockData | LooseOutputBlockData\n): boolean {\n const { id: idA, ...restA } = a;\n const { id: idB, ...restB } = b;\n\n const hasIdA = typeof idA === 'string' && idA !== '';\n const hasIdB = typeof idB === 'string' && idB !== '';\n\n if (hasIdA && hasIdB && idA !== idB) {\n return false;\n }\n\n return deepEqual(restA, restB);\n}\n\n/**\n * The tool a pristine editor seeds its first (empty) block with. An empty block\n * of this type is UI scaffolding, not user content — see\n * {@link EqualsOutputDataOptions.ignoreEmptyDefaultBlocks}.\n */\nconst DEFAULT_BLOCK_TYPE = 'paragraph';\n\n/**\n * Options for {@link equalsOutputData}.\n */\nexport interface EqualsOutputDataOptions {\n /**\n * Ignore empty default blocks on both sides before comparing. A fresh editor\n * always seeds one empty default paragraph, so a pristine document\n * (`[{ type: 'paragraph', data: { text: '' } }]`) does not content-equal a\n * saved-empty baseline (`[]`) by default. Turn this on for dirty-vs-baseline\n * checks (\"has the user actually typed anything?\"): empty blocks of the\n * default paragraph tool are dropped from both documents first, so pristine\n * scaffolding and trailing empty lines don't register as a change. Empty\n * NON-default blocks (a content-less divider, an empty image) are kept — they\n * are meaningful content.\n */\n ignoreEmptyDefaultBlocks?: boolean;\n}\n\n/**\n * True for an empty block of the default paragraph tool — the editor's own\n * scaffolding, not user content.\n * @param block - block to inspect\n * @returns true when the block is an empty default paragraph\n */\nfunction isEmptyDefaultBlock(block: OutputBlockData | LooseOutputBlockData): boolean {\n return block.type === DEFAULT_BLOCK_TYPE && isEmptyValue(block.data);\n}\n\n/**\n * Resolves the blocks to compare for a document, dropping empty default blocks\n * when {@link EqualsOutputDataOptions.ignoreEmptyDefaultBlocks} is set.\n * @param data - document whose blocks are collected\n * @param options - comparison options\n * @returns the blocks to compare\n */\nfunction comparableBlocks(\n data: AnyOutputData,\n options?: EqualsOutputDataOptions\n): Array<OutputBlockData | LooseOutputBlockData> {\n const blocks = data?.blocks ?? [];\n\n if (options?.ignoreEmptyDefaultBlocks === true) {\n return blocks.filter((block) => !isEmptyDefaultBlock(block));\n }\n\n return blocks;\n}\n\n/**\n * Structural equality for saved documents. Compares the `blocks` arrays\n * deeply; the volatile `time` and `version` envelope fields are ignored, so a\n * document round-tripped through `save()` compares equal to its echo. Block\n * ids are compared only when both sides carry one — the editor mints fresh\n * ids for id-less content, so a legacy document still equals its saved echo.\n * Nullish documents compare equal to `{ blocks: [] }`.\n *\n * Pass `{ ignoreEmptyDefaultBlocks: true }` for dirty-vs-baseline checks so a\n * pristine editor (one empty default paragraph) equals a saved-empty baseline —\n * see {@link EqualsOutputDataOptions}.\n * @param a - first document to compare\n * @param b - second document to compare\n * @param options - comparison options\n * @returns true when both documents hold structurally equal blocks\n */\nexport function equalsOutputData(a: AnyOutputData, b: AnyOutputData, options?: EqualsOutputDataOptions): boolean {\n const blocksA = comparableBlocks(a, options);\n const blocksB = comparableBlocks(b, options);\n\n return blocksA.length === blocksB.length && blocksA.every((block, index) => equalsOutputBlock(block, blocksB[index]));\n}\n\n/**\n * A bounded window of the editor's recently emitted `onSave` payloads, used by\n * the framework adapters to recognize controlled-`data` echoes. Deduping\n * against only the LAST emitted payload is not enough: a host that persists on\n * save and refetches can hand the adapter a STALE echo — an earlier save\n * arriving after a newer one already replaced the baseline — and re-rendering\n * it would clobber the caret and any content typed since. Matching is\n * structural ({@link equalsOutputData}), so envelopes reshaped in transit\n * (fresh `time`, stripped ids) still count as echoes.\n * @param capacity - number of payloads retained before the oldest is evicted\n * @returns the echo window\n */\nexport function createEmittedEchoWindow(capacity: number = 20): {\n /** Records a payload the editor emitted via `onSave`. */\n record(data: OutputData | LooseOutputData): void;\n /** True when the document content-equals any recorded payload. */\n matches(data: AnyOutputData): boolean;\n /** Forgets all recorded payloads (external content took over). */\n clear(): void;\n} {\n const emitted: Array<OutputData | LooseOutputData> = [];\n\n return {\n record(data: OutputData | LooseOutputData): void {\n emitted.push(data);\n if (emitted.length > capacity) {\n emitted.shift();\n }\n },\n matches(data: AnyOutputData): boolean {\n return emitted.some((payload) => equalsOutputData(payload, data));\n },\n clear(): void {\n emitted.length = 0;\n },\n };\n}\n\n/**\n * A shared, deeply frozen empty document. Consumers persisting editor content\n * repeatedly hand-write `{ blocks: [] }` for cleared/pristine baselines; this\n * is the canonical value to use instead. Frozen (blocks array included) so a\n * shared reference can never be mutated into a stale non-empty baseline.\n */\nexport const EMPTY_OUTPUT_DATA: OutputData = Object.freeze({\n // Freeze the array too, so a shared reference can't be mutated. The public\n // `blocks` type is mutable (`OutputBlockData[]`), so the frozen (readonly)\n // array is re-widened through `unknown` — runtime stays frozen.\n blocks: Object.freeze([]) as unknown as OutputBlockData[],\n});\n\n/**\n * Maps a controlled `data` value to something the editor's `render()` accepts.\n * A whole-document `null` — a controlled \"clear to empty\" — becomes\n * `{ blocks: [] }`; any real document passes through untouched.\n *\n * The framework adapters (React/Vue/Angular) route their reactive `data` path\n * through this so a `null` never reaches `render()`, whose strict guard reads\n * `data.blocks` and would throw on `null`. `undefined` (uncontrolled) is handled\n * by the adapters before this point, so it is intentionally not an input here.\n * @param data - a controlled document, or `null` for an empty document\n * @returns a document `render()` can consume\n */\nexport function toRenderableData(data: OutputData | LooseOutputData | null): OutputData | LooseOutputData {\n return data === null ? { blocks: [] } : data;\n}\n\n/**\n * Normalizes blocks from the loose wire shape into the strict saved shape at\n * the editor's input boundaries: a `null`/missing `data` becomes `{}`, a\n * `null`/empty `id` is dropped so the block factory generates a fresh one.\n * Idempotent — strict blocks pass through unchanged (shallow-copied).\n * @param blocks - blocks in either the strict or the loose wire shape\n * @returns blocks in the strict saved shape\n */\nexport function normalizeOutputBlocks(blocks: Array<OutputBlockData | LooseOutputBlockData>): OutputBlockData[] {\n return blocks.map((block) => {\n const { id, data, ...rest } = block;\n\n return {\n ...rest,\n ...(typeof id === 'string' && id !== '' ? { id } : {}),\n data: data ?? {},\n };\n });\n}\n\n/**\n * Normalizes a whole loose wire document into the strict saved\n * {@link OutputData} shape at an input boundary. A nullish document becomes\n * `{ blocks: [] }`; `null` envelope fields (`time`/`version`) are dropped; each\n * block is passed through {@link normalizeOutputBlocks}, so `null`/missing\n * `data` becomes `{}` and `null`/empty ids are dropped for regeneration.\n *\n * Unlike a hand-written `blocks.map(...)` mapper, this preserves every block\n * passthrough field — `tunes`, `parent`, `content`, `indent`, edit metadata —\n * so a backend DTO can be turned into strict `OutputData` without silently\n * losing hierarchy or tunes. Idempotent: a strict document passes through\n * unchanged (shallow-copied).\n * @param data - a document in the strict or loose wire shape, or nullish\n * @returns the document in the strict saved shape\n */\nexport function normalizeOutputData(data: AnyOutputData): OutputData {\n if (data === null || data === undefined) {\n return { blocks: [] };\n }\n\n return {\n ...(typeof data.version === 'string' ? { version: data.version } : {}),\n ...(typeof data.time === 'number' ? { time: data.time } : {}),\n blocks: normalizeOutputBlocks(data.blocks),\n };\n}\n\n/**\n * True when the value carries no user content: blank/whitespace-only strings,\n * empty arrays, plain objects whose values are all empty, and nullish values.\n * Numbers and booleans are presentation metadata (`level`, `checked`, styles)\n * and never count as content on their own.\n * @param value - block data value to inspect\n * @returns true when the value carries no user content\n */\nfunction isEmptyValue(value: unknown): boolean {\n if (value === null || value === undefined) {\n return true;\n }\n\n if (typeof value === 'string') {\n return value.trim() === '';\n }\n\n if (Array.isArray(value)) {\n return value.every(isEmptyValue);\n }\n\n if (typeof value === 'object') {\n return Object.values(value).every(isEmptyValue);\n }\n\n // Numbers, booleans and other primitives are metadata, not content.\n return true;\n}\n\n/**\n * True when the document carries no user content: it is nullish, has no\n * blocks, or every block's data holds only empty values (see\n * {@link isEmptyValue}). Note that content-less visual blocks (e.g. a divider,\n * whose data is `{}`) count as empty — check `blocks.length` when mere block\n * presence matters.\n * @param data - document to inspect\n * @returns true when the document carries no user content\n */\nexport function isEmptyOutputData(data: AnyOutputData): boolean {\n const blocks = data?.blocks ?? [];\n\n return blocks.every((block) => isEmptyValue(block.data));\n}\n","// src/shared/prop-schema.ts\n\n/** One field of a block's prop schema. */\nexport interface PropSchemaEntry {\n /** Default value, used when the incoming data omits this key. */\n default: unknown;\n /** Optional allowed values (advisory; not enforced at runtime in v1). */\n values?: readonly unknown[];\n}\n\n/**\n * Declarative data shape. The keys here are EXACTLY the keys `save()` returns to\n * Yjs — this closes the per-key-sync key-resurrection gap (a cleared field is\n * written as its explicit default, never dropped).\n */\nexport type PropSchema = Record<string, PropSchemaEntry>;\n\n/**\n * Fill a data object against the schema: every schema key present, incoming\n * value when defined else the schema default, and ONLY schema keys (so `save()`\n * is never partial). Returns a frozen plain object — safe to hand straight to\n * core's per-key Yjs sync.\n */\nexport const fillDefaults = <Data>(\n schema: PropSchema,\n data: Record<string, unknown>\n): Readonly<Data> => {\n const result: Record<string, unknown> = {};\n\n for (const key of Object.keys(schema)) {\n result[key] = data[key] !== undefined ? data[key] : schema[key].default;\n }\n\n return Object.freeze(result) as Readonly<Data>;\n};\n","/**\n * Centralized data attributes used across the Blok editor.\n * This is the single source of truth for all data-blok-* attributes.\n *\n * Exported as Blok.DATA_ATTR for users.\n *\n * Naming convention:\n * - Remove 'data-blok-' prefix and convert to camelCase\n * - Global attributes: hidden, disabled, focused\n * - Component prefixed: popover, popoverItem, toolbar, etc.\n */\nexport const DATA_ATTR = {\n // ============================================\n // Core Element Identifiers\n // ============================================\n\n /** Interface type identifier (blok, inline-toolbar, tooltip) */\n interface: 'data-blok-interface',\n /** Block element wrapper */\n element: 'data-blok-element',\n /** Block element content wrapper */\n elementContent: 'data-blok-element-content',\n /** Editor wrapper container */\n editor: 'data-blok-editor',\n /** Redactor zone */\n redactor: 'data-blok-redactor',\n /** Present on the editor wrapper once a `blocks.render()` batch has finished\n * inserting blocks into the DOM; removed while a re-render is in flight.\n * Acts as a stable render-readiness gate for consumers (e.g. E2E waits). */\n rendered: 'data-blok-rendered',\n\n // ============================================\n // Block Identifiers\n // ============================================\n\n /** Block unique identifier */\n id: 'data-blok-id',\n /** Block component/tool type */\n component: 'data-blok-component',\n /** Tool type attribute */\n tool: 'data-blok-tool',\n /** Block nesting depth (derived from the parentId chain) */\n depth: 'data-blok-depth',\n /** Flat list-nesting indentation level (0 = root); tool-agnostic, mirrors list depth */\n indent: 'data-blok-indent',\n /** Header tool's heading level (1-6). Public styling hook — keyed by level rather\n * than by tag name, so a level remapped to a custom tag via `levelOverrides[n].tag`\n * (types/tools/header.d.ts) still matches its level's typography rules. */\n headingLevel: 'data-blok-heading-level',\n\n // ============================================\n // Global States\n // ============================================\n\n /** Element is hidden from view */\n hidden: 'data-blok-hidden',\n /** Element is disabled and non-interactive */\n disabled: 'data-blok-disabled',\n /** Element is focused via keyboard navigation */\n focused: 'data-blok-focused',\n /** Block is selected */\n selected: 'data-blok-selected',\n /** Block is stretched */\n stretched: 'data-blok-stretched',\n /** Editor or element is empty */\n empty: 'data-blok-empty',\n /** Present on the editor wrapper while read-only mode is active.\n * Public styling hook — lets hosts key rules off the editing state\n * without JS. Deliberately does NOT collapse the gutter: plain\n * read-only still shows the block-hover copy-link control there, and\n * in-place readOnly.set() flips must not shift the layout. */\n readonly: 'data-blok-readonly',\n /** Present on the editor wrapper while read-only mode hides ALL editor\n * controls (readOnly: { hideControls: true }). Public styling hook —\n * drives the gutter auto-collapse for genuinely chromeless read-only. */\n controlsHidden: 'data-blok-controls-hidden',\n /** Present on the editor wrapper when config.hideToolbar is true.\n * Public styling hook — drives the gutter auto-collapse (the gutter\n * exists solely to house the toolbar's +/⠿ controls). */\n toolbarHidden: 'data-blok-toolbar-hidden',\n\n // ============================================\n // Editor Modes\n // ============================================\n\n /** Content alignment mode (left, center, right) */\n contentAlign: 'data-blok-content-align',\n /** Right-to-left mode */\n rtl: 'data-blok-rtl',\n /** Editor content width mode (present with value \"full\" for wide mode; absent = narrow) */\n width: 'data-blok-width',\n /** Present on the editor wrapper when config.style.nativeSelection is true.\n * Public styling hook — disables Blok's ::selection repaint (preflight.css)\n * and re-points the fake-background highlight at the UA Highlight color\n * (colors.css), so selection falls back to native/host-defined colors. */\n nativeSelection: 'data-blok-native-selection',\n\n // ============================================\n // Drag and Drop\n // ============================================\n\n /** Block is being dragged */\n dragging: 'data-blok-dragging',\n /** Multiple blocks being dragged */\n draggingMulti: 'data-blok-dragging-multi',\n /** Block is being duplicated (Alt+drag) */\n duplicating: 'data-blok-duplicating',\n /** Drag handle element */\n dragHandle: 'data-blok-drag-handle',\n\n // ============================================\n // Toolbar\n // ============================================\n\n /** Toolbar element */\n toolbar: 'data-blok-toolbar',\n /** Settings toggler button */\n settingsToggler: 'data-blok-settings-toggler',\n /** Toolbox is open */\n toolboxOpened: 'data-blok-toolbox-opened',\n /** Block settings is open */\n blockSettingsOpened: 'data-blok-block-settings-opened',\n /** Element is opened (generic) */\n opened: 'data-blok-opened',\n\n // ============================================\n // Popover Container\n // ============================================\n\n /** Root popover element */\n popover: 'data-blok-popover',\n /** Popover container wrapper */\n popoverContainer: 'data-blok-popover-container',\n /** Popover items list */\n popoverItems: 'data-blok-popover-items',\n /** Custom, engine-independent scrollbar thumb overlaid on the popover items */\n popoverScrollbar: 'data-blok-popover-scrollbar',\n /** Stamped on the custom scrollbar thumb while it is being dragged (keeps it revealed) */\n popoverScrollbarDragging: 'data-blok-dragging',\n /** Stamped on a scroll container while it is actively scrolling (reveals the auto-hidden scrollbar thumb) */\n scrolling: 'data-blok-scrolling',\n /** Popover overlay element */\n popoverOverlay: 'data-blok-popover-overlay',\n /** Popover custom content area */\n popoverCustomContent: 'data-blok-popover-custom-content',\n /** Popover custom class */\n popoverCustomClass: 'data-blok-popover-custom-class',\n /** Inline popover variant */\n popoverInline: 'data-blok-popover-inline',\n /** Popover is open */\n popoverOpened: 'data-blok-popover-opened',\n /** Popover opens upward */\n popoverOpenTop: 'data-blok-popover-open-top',\n /** Popover opens leftward */\n popoverOpenLeft: 'data-blok-popover-open-left',\n\n // ============================================\n // Popover Nesting\n // ============================================\n\n /** Nested popover indicator */\n nested: 'data-blok-nested',\n /** Nesting level value */\n nestedLevel: 'data-blok-nested-level',\n /** Group label for promoted search results from nested children */\n promotedGroupLabel: 'data-blok-promoted-group-label',\n /** Group label for top-level matches in search results */\n topLevelGroupLabel: 'data-blok-top-level-group-label',\n\n // ============================================\n // Popover Header\n // ============================================\n\n /** Header container */\n popoverHeader: 'data-blok-popover-header',\n /** Header text element */\n popoverHeaderText: 'data-blok-popover-header-text',\n /** Back button in nested popover */\n popoverHeaderBackButton: 'data-blok-popover-header-back-button',\n\n // ============================================\n // Popover Items\n // ============================================\n\n /** Item container */\n popoverItem: 'data-blok-popover-item',\n /** Item icon wrapper */\n popoverItemIcon: 'data-blok-popover-item-icon',\n /** Chevron icon for nested items */\n popoverItemIconChevronRight: 'data-blok-popover-item-icon-chevron-right',\n /** Item title text */\n popoverItemTitle: 'data-blok-popover-item-title',\n /** Item secondary title */\n popoverItemSecondaryTitle: 'data-blok-popover-item-secondary-title',\n /** Item is active/selected */\n popoverItemActive: 'data-blok-popover-item-active',\n /** Confirmation state */\n popoverItemConfirmation: 'data-blok-popover-item-confirmation',\n /** Disable hover styling */\n popoverItemNoHover: 'data-blok-popover-item-no-hover',\n /** Disable focus handling */\n popoverItemNoFocus: 'data-blok-popover-item-no-focus',\n /** Destructive action item (e.g. delete) */\n popoverItemDestructive: 'data-blok-popover-item-destructive',\n /** Separator item */\n popoverItemSeparator: 'data-blok-popover-item-separator',\n /** Separator line element */\n popoverItemSeparatorLine: 'data-blok-popover-item-separator-line',\n /** HTML-based item */\n popoverItemHtml: 'data-blok-popover-item-html',\n /** Item has child menu */\n hasChildren: 'data-blok-has-children',\n /** Item name identifier */\n itemName: 'data-blok-item-name',\n /** No search results shown */\n nothingFoundDisplayed: 'data-blok-nothing-found-displayed',\n\n // ============================================\n // Overlay / Selection\n // ============================================\n\n /** Selection overlay */\n overlay: 'data-blok-overlay',\n /** Overlay container */\n overlayContainer: 'data-blok-overlay-container',\n /** Selection rectangle */\n overlayRectangle: 'data-blok-overlay-rectangle',\n /** Overlay is hidden */\n overlayHidden: 'data-blok-overlay-hidden',\n /** Fake cursor indicator */\n fakeCursor: 'data-blok-fake-cursor',\n /** Fake background for selection */\n fakeBackground: 'data-blok-fake-background',\n\n // ============================================\n // Scroll\n // ============================================\n\n /** Auto-scroll zone (top/bottom) */\n scrollZone: 'data-blok-scroll-zone',\n /** Scroll is locked */\n scrollLocked: 'data-blok-scroll-locked',\n /** Hard scroll lock */\n scrollLockedHard: 'data-blok-scroll-locked-hard',\n\n // ============================================\n // Caret\n // ============================================\n\n /** Shadow caret element */\n shadowCaret: 'data-blok-shadow-caret',\n\n // ============================================\n // Placeholders\n // ============================================\n\n /** Placeholder text */\n placeholder: 'data-blok-placeholder',\n /** Active placeholder text */\n placeholderActive: 'data-blok-placeholder-active',\n\n // ============================================\n // Nested Blocks\n // ============================================\n\n /** Container that hosts nested block holders (table cells, toggle/callout/header children).\n * Used as a universal guard: before moving a block holder via appendChild,\n * check `holder.closest([nestedBlocks])` — if truthy, the holder is already\n * claimed by another container and must not be stolen. */\n nestedBlocks: 'data-blok-nested-blocks',\n\n // ============================================\n // Mutation Tracking\n // ============================================\n\n /** Element excluded from mutation tracking */\n mutationFree: 'data-blok-mutation-free',\n\n // ============================================\n // Navigation\n // ============================================\n\n /** Block has navigation focus */\n navigationFocused: 'data-blok-navigation-focused',\n /** Flipper navigation target */\n flipperNavigationTarget: 'data-blok-flipper-navigation-target',\n\n // ============================================\n // Inline Toolbar\n // ============================================\n\n /** Inline toolbar enabled on external element */\n inlineToolbar: 'data-blok-inline-toolbar',\n\n // ============================================\n // Link Tool\n // ============================================\n\n /** Link tool is active */\n linkToolActive: 'data-blok-link-tool-active',\n /** Link tool unlink mode */\n linkToolUnlink: 'data-blok-link-tool-unlink',\n /** Link tool input is opened */\n linkToolInputOpened: 'data-blok-link-tool-input-opened',\n\n // ============================================\n // Bold Tool\n // ============================================\n\n /** Bold collapsed length tracking */\n boldCollapsedLength: 'data-blok-bold-collapsed-length',\n /** Bold collapsed active state */\n boldCollapsedActive: 'data-blok-bold-collapsed-active',\n /** Bold previous length tracking */\n boldPrevLength: 'data-blok-bold-prev-length',\n /** Bold leading whitespace */\n boldLeadingWs: 'data-blok-bold-leading-ws',\n /** Bold marker */\n boldMarker: 'data-blok-bold-marker',\n\n // ============================================\n // Tooltip\n // ============================================\n\n /** Tooltip is shown */\n shown: 'data-blok-shown',\n /** Tooltip placement */\n placement: 'data-blok-placement',\n\n // ============================================\n // Notifier\n // ============================================\n\n /** Bounce in animation */\n bounceIn: 'data-blok-bounce-in',\n\n // ============================================\n // Announcer (Accessibility)\n // ============================================\n\n /** Live region announcer */\n announcer: 'data-blok-announcer',\n\n // ============================================\n // Stub Block\n // ============================================\n\n /** Stub block element */\n stub: 'data-blok-stub',\n /** Stub info section */\n stubInfo: 'data-blok-stub-info',\n /** Stub title */\n stubTitle: 'data-blok-stub-title',\n /** Stub subtitle */\n stubSubtitle: 'data-blok-stub-subtitle',\n\n // ============================================\n // Slash Search\n // ============================================\n\n /** Slash search active on content editable */\n slashSearch: 'data-blok-slash-search',\n\n // ============================================\n // Testing\n // ============================================\n\n /** Test identifier (for E2E tests) */\n testid: 'data-blok-testid',\n /** Force hover state (for tests/storybook) */\n forceHover: 'data-blok-force-hover',\n} as const;\n\n/**\n * Type for DATA_ATTR keys\n */\nexport type DataAttrKey = keyof typeof DATA_ATTR;\n\n/**\n * Type for DATA_ATTR values\n */\nexport type DataAttrValue = (typeof DATA_ATTR)[DataAttrKey];\n\n/**\n * Helper function to create a CSS selector from an attribute\n *\n * @param attr - The data attribute name from DATA_ATTR\n * @param value - Optional value for the attribute (defaults to presence selector)\n * @returns CSS selector string\n *\n * @example\n * createSelector(DATA_ATTR.element) // '[data-blok-element]'\n * createSelector(DATA_ATTR.selected, true) // '[data-blok-selected=\"true\"]'\n * createSelector(DATA_ATTR.tool, 'paragraph') // '[data-blok-tool=\"paragraph\"]'\n */\nexport const createSelector = (attr: DataAttrValue, value?: string | boolean): string => {\n if (value === undefined) {\n return `[${attr}]`;\n }\n\n return `[${attr}=\"${value}\"]`;\n};\n","import { DATA_ATTR } from '../components/constants/data-attributes';\n\n/**\n * Mount child block holders into a container, skipping children that are\n * already in place or claimed by another nested-blocks container.\n *\n * Used by toggle, header, column, and callout tools to reconcile child holders\n * during the `rendered()` lifecycle hook.\n */\nexport const mountChildBlocks = (\n container: HTMLElement,\n children: { holder: HTMLElement }[],\n): void => {\n for (const child of children) {\n if (child.holder.parentElement === container) {\n continue;\n }\n\n const nested = child.holder.closest(`[${DATA_ATTR.nestedBlocks}]`);\n\n // Claim a holder stranded in the column_list ROW. A drag reparent into a\n // column drops the moved holder directly into the [data-blok-columns] row\n // (itself a nested-blocks container that wraps each column's own container).\n // Left there it renders as a rogue new column, so pull it down into THIS\n // column container where it belongs. Scoped to the column_list row\n // specifically — claiming from arbitrary ancestor containers would let one\n // table cell steal a paragraph transiently parked in an outer container.\n if (\n nested !== null &&\n nested !== container &&\n nested.hasAttribute('data-blok-columns') &&\n nested.contains(container)\n ) {\n container.appendChild(child.holder);\n continue;\n }\n\n // Otherwise leave holders that already live inside another nested container\n // (a sibling, or a deeper nesting within this one) where they are.\n if (nested !== null) {\n continue;\n }\n\n container.appendChild(child.holder);\n }\n};\n","import {\n ChangeDetectionStrategy,\n Component,\n EventEmitter,\n Input,\n NgZone,\n Output,\n ViewChild,\n computed,\n effect,\n forwardRef,\n inject,\n signal,\n type AfterViewInit,\n} from '@angular/core';\nimport { NG_VALUE_ACCESSOR, type ControlValueAccessor } from '@angular/forms';\nimport { BlokContentDirective } from './blok-content.directive';\nimport { BLOK_DEFAULT_CONFIG } from './provide-blok';\nimport { deepEqual } from '../adapters-contract';\nimport { normalizeReadOnlyConfig } from '../adapters-contract';\nimport { toRenderableData } from '../adapters-contract';\nimport type {\n API,\n Blok,\n BlockMutationEvent,\n BlockRenderedPayload,\n BlocksRenderedPayload,\n BlokConfig,\n EditorWidth,\n LooseOutputData,\n OutputBlockData,\n OutputData,\n ResolvedTheme,\n ThemeMode,\n} from '@bloklabs/core';\nimport type { BlokAngularConfig } from './types';\n\n/**\n * The blessed all-in-one Angular component for embedding Blok (mirrors React's\n * `BlokEditor`). Delegates instance lifecycle to an internal `BlokContentDirective`\n * and layers the typed reactive input/output API on top.\n *\n * Reactive inputs (`readOnly`, `hideToolbar`, `inlineToolbar`, `theme`,\n * `width`, `placeholder`, `autofocus`, `styleTokens`, `i18n`, `data`) are\n * synced in place after mount via effects — `hideToolbar` through\n * `editor.toolbar.setHidden()`, `inlineToolbar` through\n * `editor.tools.setInlineToolbar()` (content-compared),\n * `styleTokens` through `editor.tokens.set()` (replace semantics),\n * `i18n` through `editor.i18n.update()` (deep-equal–deduped; seeded at\n * construction so the locale resolves during boot) and `data`\n * through `editor.render()` (deep-equal–deduped); everything else seeds\n * construction.\n *\n * Implementation note: classic `@Input()`/`@ViewChild()` decorators are used\n * (not signal `input()`/`viewChild()`) for JIT compatibility — see\n * `BlokContentDirective`. Each reactive input is backed by an internal `signal`\n * so effect-based syncing still works; the public template API is unchanged.\n */\n@Component({\n selector: 'blok-editor',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n exportAs: 'blok',\n imports: [BlokContentDirective],\n template: `<div blokContent [config]=\"buildConfig()\" [recreateKey]=\"recreateKey\"></div>`,\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => BlokEditorComponent),\n multi: true,\n },\n ],\n})\nexport class BlokEditorComponent implements AfterViewInit, ControlValueAccessor {\n private readonly ngZone = inject(NgZone);\n /** App-wide defaults from `provideBlok()`; merged UNDER per-instance inputs. */\n private readonly defaults = inject(BLOK_DEFAULT_CONFIG, { optional: true }) ?? {};\n\n @ViewChild(BlokContentDirective) private contentQuery?: BlokContentDirective;\n /** Signal bridge for the @ViewChild directive so effects react to its arrival. */\n private readonly content = signal<BlokContentDirective | null>(null);\n\n /**\n * Output half of two-way `[(data)]`. Emits the editor's serialized content on\n * every change. Wiring the core `onSave` callback is gated on this being\n * observed, since its mere presence makes the core serialize on every batch.\n */\n /** Emits the live Blok instance once ready, after `instance()` is populated. */\n @Output() readonly ready = new EventEmitter<Blok>();\n\n @Output() readonly dataChange = new EventEmitter<OutputData>();\n\n /** Fires with the full serialized content on every change (notification half). */\n @Output() readonly save = new EventEmitter<OutputData>();\n\n /** Raw block mutation channel (core `onChange`). */\n @Output() readonly change = new EventEmitter<{\n api: API;\n event: BlockMutationEvent | BlockMutationEvent[];\n }>();\n\n /** Fires after the editor finishes (re-)rendering (core `onAfterRender`). */\n @Output() readonly afterRender = new EventEmitter<API>();\n\n /** Fires with the resolved theme whenever it changes (core `onThemeChange`). */\n @Output() readonly themeChange = new EventEmitter<ResolvedTheme>();\n\n /** Fires after a batch render completes (core `blocks:rendered` event). */\n @Output() readonly blocksRendered = new EventEmitter<BlocksRenderedPayload>();\n\n /** Fires for each block rendered into the DOM (core `block:rendered` event). */\n @Output() readonly blockRendered = new EventEmitter<BlockRenderedPayload>();\n\n /**\n * Transform hook applied to blocks before render (core `onBeforeRender`). Must\n * return the (possibly modified) block list. An input, not an output, because\n * it returns a value.\n */\n @Input() onBeforeRender?: (blocks: OutputBlockData[]) => OutputBlockData[];\n\n /**\n * Transform hook applied to pasted HTML (core `onBeforePaste`). Returns the\n * (possibly modified) html, or null to drop the paste.\n */\n @Input() onBeforePaste?: (html: string) => string | null;\n\n /**\n * Error channel (core `onError`). Fires with the raised error whenever an\n * editor operation — currently serialization — fails instead of only logging.\n */\n @Input() onError?: BlokConfig['onError'];\n\n // ---- Reactive inputs (signal-backed setters; synced in place, never recreate) ----\n // Default undefined (not false) so an unset input falls back to a provideBlok\n // default; the readOnly effect / buildConfig coerce undefined to false.\n // Accepts the object form (`{ hideControls }`) too — it flows through\n // buildConfig unchanged and the effect expands it to\n // `readOnly.set(enabled, { hideControls })`.\n private readonly readOnly$ = signal<BlokConfig['readOnly'] | undefined>(undefined);\n @Input() set readOnly(value: BlokConfig['readOnly'] | undefined) {\n this.readOnly$.set(value);\n }\n\n private readonly hideToolbar$ = signal<boolean | undefined>(undefined);\n @Input() set hideToolbar(value: boolean | undefined) {\n this.hideToolbar$.set(value);\n }\n\n private readonly inlineToolbar$ = signal<boolean | string[] | undefined>(undefined);\n @Input() set inlineToolbar(value: boolean | string[] | undefined) {\n this.inlineToolbar$.set(value);\n }\n\n private readonly theme$ = signal<ThemeMode | undefined>(undefined);\n @Input() set theme(value: ThemeMode | undefined) {\n this.theme$.set(value);\n }\n\n private readonly width$ = signal<EditorWidth | undefined>(undefined);\n @Input() set width(value: EditorWidth | undefined) {\n this.width$.set(value);\n }\n\n private readonly placeholder$ = signal<string | false | undefined>(undefined);\n @Input() set placeholder(value: string | false | undefined) {\n this.placeholder$.set(value);\n }\n\n /**\n * Theme tokens. Construction-only config forced hosts with a live light/dark\n * toggle to recreate the editor or hand-write the global stylesheet Blok\n * already injects; this drives the runtime `tokens` API instead.\n */\n private readonly styleTokens$ = signal<Record<string, string> | undefined>(undefined);\n @Input() set styleTokens(value: Record<string, string> | undefined) {\n this.styleTokens$.set(value);\n }\n\n /**\n * Locale, host message overrides and text direction. `config.i18n` was\n * consumed once at boot, so a host driving a language switcher had to\n * recreate the editor (losing caret, focus and undo stack) to relabel the\n * UI; this drives the runtime `i18n.update` API instead. `defaultLocale` is\n * not forwarded — it only affects the INITIAL locale resolution.\n */\n private readonly i18n$ = signal<BlokConfig['i18n'] | undefined>(undefined);\n @Input() set i18n(value: BlokConfig['i18n'] | undefined) {\n this.i18n$.set(value);\n }\n\n private readonly autofocus$ = signal<boolean | undefined>(false);\n @Input() set autofocus(value: boolean | undefined) {\n this.autofocus$.set(value);\n }\n\n // ---- Reactive content (seeds construction, then re-renders on change) ----\n private readonly data$ = signal<OutputData | LooseOutputData | null | undefined>(undefined);\n @Input() set data(value: OutputData | LooseOutputData | null | undefined) {\n this.data$.set(value);\n }\n\n // ---- Construction-only seed inputs (read once at construction) ----\n @Input() tools?: BlokConfig['tools'];\n /** Host-supplied per-type block migrations applied at load (merged across layers). */\n @Input() migrations?: BlokConfig['migrations'];\n\n /**\n * Escape hatch: a full config object for keys without a dedicated input\n * (sanitizer, minHeight, …). Layered between provideBlok\n * defaults and the discrete inputs.\n */\n @Input() config?: Partial<BlokAngularConfig>;\n\n /** Changing this input's identity destroys and recreates the editor (≙ React `deps`). */\n @Input() recreateKey: unknown;\n\n /**\n * Content the editor currently reflects. Set when seeded or rendered (the data\n * effect below). A controlled `data` echo that deep-equals this baseline is a\n * no-op, so it won't clobber the caret. Renders are serialized via `renderChain`.\n */\n private lastRenderedData?: OutputData | LooseOutputData | null;\n\n /** Last token set pushed through `tokens.set`, for deep-equal deduping. */\n private appliedTokens?: Record<string, string>;\n /** Last i18n config pushed through `i18n.update`, for deep-equal deduping. */\n private appliedI18n?: BlokConfig['i18n'];\n /** Editor instance the i18n baseline above belongs to. */\n private i18nAppliedFor: Blok | null = null;\n /** Last value pushed through `tools.setInlineToolbar`, for content-compare deduping. */\n private appliedInlineToolbar?: boolean | string[];\n private seededEditor: Blok | null = null;\n private renderChain: Promise<void> = Promise.resolve();\n\n /** Registered by `ControlValueAccessor.registerOnChange` (Angular forms). */\n private cvaOnChange?: (data: OutputData) => void;\n private cvaOnTouched?: () => void;\n\n /**\n * Core `onSave` wrapper. Records the editor's own serialized output as the\n * rendered baseline BEFORE notifying Angular, so a controlled consumer echoing\n * it straight back into `data` deep-equals the baseline and is deduped to a\n * no-op (no redundant render, no caret reset). Re-enters the Angular zone since\n * the editor runs outside it.\n */\n private readonly coreOnSave = (data: OutputData): void => {\n this.lastRenderedData = data;\n this.ngZone.run(() => {\n this.dataChange.emit(data);\n this.save.emit(data);\n this.cvaOnChange?.(data);\n this.cvaOnTouched?.();\n });\n };\n\n /** Live Blok instance, or null until `isReady` resolves / after destroy. */\n readonly instance = computed<Blok | null>(() => this.content()?.instance() ?? null);\n\n /** Guards `ready` to one emission per editor instance. */\n private lastReadyInstance: Blok | null = null;\n\n /**\n * Construction config handed to the directive. Seeds the editor's initial\n * values; the directive only reads it once (at construction), so post-mount\n * changes to construction-only inputs are no-ops by design.\n */\n buildConfig(): Partial<BlokAngularConfig> {\n // Precedence: provideBlok defaults < [config] escape hatch < discrete inputs.\n const cfg: Partial<BlokAngularConfig> = { ...this.defaults, ...this.config };\n\n // The object form ({ hideControls }) is preserved as-is; the readOnly\n // effect expands it into `readOnly.set(enabled, { hideControls })`.\n cfg.readOnly = this.readOnly$() ?? this.config?.readOnly ?? this.defaults.readOnly ?? false;\n\n const hideToolbar = this.hideToolbar$();\n\n if (hideToolbar !== undefined) {\n cfg.hideToolbar = hideToolbar;\n }\n\n const inlineToolbar = this.inlineToolbar$();\n\n if (inlineToolbar !== undefined) {\n cfg.inlineToolbar = inlineToolbar;\n }\n\n // tools registries are MERGED (not replaced) across all three layers so a\n // shared registry composes with per-instance additions.\n if (\n this.tools !== undefined ||\n this.config?.tools !== undefined ||\n this.defaults.tools !== undefined\n ) {\n cfg.tools = { ...this.defaults.tools, ...this.config?.tools, ...this.tools };\n }\n\n // migration registries merge like tools: shared defaults compose with\n // per-instance rules.\n if (\n this.migrations !== undefined ||\n this.config?.migrations !== undefined ||\n this.defaults.migrations !== undefined\n ) {\n cfg.migrations = { ...this.defaults.migrations, ...this.config?.migrations, ...this.migrations };\n }\n\n const data = this.data$();\n\n if (data !== undefined) {\n cfg.data = data;\n }\n\n const theme = this.theme$();\n\n if (theme !== undefined) {\n cfg.theme = theme;\n }\n\n const width = this.width$();\n\n if (width !== undefined) {\n cfg.width = width;\n }\n\n const placeholder = this.placeholder$();\n\n if (placeholder !== undefined) {\n cfg.placeholder = placeholder;\n }\n\n // Seeded at construction (not applied by the i18n effect) so the locale is\n // resolved during boot instead of flashing the default language first.\n const i18n = this.i18n$();\n\n if (i18n !== undefined) {\n cfg.i18n = i18n;\n }\n\n // Opt-in: only attach each core callback when the consumer actually consumes\n // it (an observed output, a registered forms hook, or a provided transform).\n // Their mere presence makes the core serialize / run hooks on every change.\n if (this.dataChange.observed || this.save.observed || this.cvaOnChange !== undefined) {\n cfg.onSave = this.coreOnSave;\n }\n\n if (this.change.observed) {\n cfg.onChange = (api: API, event: BlockMutationEvent | BlockMutationEvent[]): void =>\n this.ngZone.run(() => this.change.emit({ api, event }));\n }\n\n if (this.afterRender.observed) {\n cfg.onAfterRender = (api: API): void => this.ngZone.run(() => this.afterRender.emit(api));\n }\n\n if (this.themeChange.observed) {\n cfg.onThemeChange = (resolved: ResolvedTheme): void =>\n this.ngZone.run(() => this.themeChange.emit(resolved));\n }\n\n // Transforms run synchronously inside core's render/paste pipeline and must\n // return a value — never wrap them in ngZone.run.\n const beforeRender = this.onBeforeRender;\n\n if (beforeRender !== undefined) {\n cfg.onBeforeRender = (blocks: OutputBlockData[]): OutputBlockData[] => beforeRender(blocks);\n }\n\n const beforePaste = this.onBeforePaste;\n\n if (beforePaste !== undefined) {\n cfg.onBeforePaste = (html: string): string | null => beforePaste(html);\n }\n\n const onError = this.onError;\n\n if (onError !== undefined) {\n cfg.onError = onError;\n }\n\n return cfg;\n }\n\n ngAfterViewInit(): void {\n this.content.set(this.contentQuery ?? null);\n }\n\n // ---- Curated imperative facade (delegates to the live instance; no-ops until ready) ----\n\n /** Serialize the current content. Resolves undefined until the editor is ready. */\n save$(): Promise<OutputData> | undefined {\n return this.instance()?.save();\n }\n\n /** Move the caret into the editor. */\n focus(atEnd?: boolean): void {\n this.instance()?.focus(atEnd);\n }\n\n /** Replace the editor content. Resolves undefined until the editor is ready. */\n render(data: OutputData | LooseOutputData): Promise<void> | undefined {\n return this.instance()?.render(data);\n }\n\n constructor() {\n // Each effect reads `instance()` so it re-applies once the editor appears\n // (the Angular analog of React's `editor` effect-dependency).\n effect(() => {\n const editor = this.instance();\n const readOnly = this.readOnly$() ?? this.config?.readOnly;\n\n if (editor) {\n const { enabled, hideControls } = normalizeReadOnlyConfig(readOnly);\n\n // Only the object form carries options; the boolean form keeps the\n // one-argument call so it never clobbers a config-seeded hideControls.\n if (typeof readOnly === 'object' && readOnly !== null) {\n void editor.readOnly.set(enabled, { hideControls });\n } else {\n void editor.readOnly.set(enabled);\n }\n }\n });\n\n effect(() => {\n const editor = this.instance();\n const hideToolbar = this.hideToolbar$();\n\n if (editor && hideToolbar !== undefined) {\n editor.toolbar.setHidden(hideToolbar);\n }\n });\n\n // Content-compared (not identity): a new array with the same tool names is\n // a no-op, so template-inline array literals don't thrash the assignment.\n effect(() => {\n const editor = this.instance();\n const inlineToolbar = this.inlineToolbar$();\n\n if (\n !editor ||\n inlineToolbar === undefined ||\n deepEqual(inlineToolbar, this.appliedInlineToolbar)\n ) {\n return;\n }\n\n this.appliedInlineToolbar = Array.isArray(inlineToolbar) ? [...inlineToolbar] : inlineToolbar;\n editor.tools.setInlineToolbar(inlineToolbar);\n });\n\n effect(() => {\n const editor = this.instance();\n const theme = this.theme$();\n\n if (editor && theme !== undefined) {\n editor.theme.set(theme);\n }\n });\n\n effect(() => {\n const editor = this.instance();\n const width = this.width$();\n\n if (editor && width !== undefined) {\n editor.width.set(width);\n }\n });\n\n effect(() => {\n const editor = this.instance();\n const placeholder = this.placeholder$();\n\n if (editor && placeholder !== undefined) {\n editor.placeholder.set(placeholder);\n }\n });\n\n effect(() => {\n const editor = this.instance();\n const tokens = this.styleTokens$() ?? this.config?.style?.tokens;\n\n if (!editor || tokens === undefined || deepEqual(tokens, this.appliedTokens)) {\n return;\n }\n\n this.appliedTokens = { ...tokens };\n editor.tokens.set(tokens);\n });\n\n effect(() => {\n const editor = this.instance();\n const i18n = this.i18n$() ?? this.config?.i18n;\n\n if (!editor) {\n return;\n }\n\n /*\n * A freshly constructed editor already resolved this config during its\n * own boot (buildConfig seeds it), so record the baseline and push\n * nothing — re-applying it here would reload the locale after mount and\n * flash the default language.\n */\n if (this.i18nAppliedFor !== editor) {\n this.i18nAppliedFor = editor;\n this.appliedI18n = i18n === undefined ? undefined : { ...i18n };\n\n return;\n }\n\n if (i18n === undefined || deepEqual(i18n, this.appliedI18n)) {\n return;\n }\n\n this.appliedI18n = { ...i18n };\n\n const { locale, messages, direction } = i18n;\n\n void editor.i18n.update({\n ...(locale === undefined ? {} : { locale }),\n ...(messages === undefined ? {} : { messages }),\n ...(direction === undefined ? {} : { direction }),\n });\n });\n\n effect(() => {\n const editor = this.instance();\n\n if (editor && this.autofocus$()) {\n editor.focus();\n }\n });\n\n // Reactive content. `data` seeds the editor at construction; afterwards a new\n // *content* value re-renders via the public render() API (deep-equal-deduped\n // and serialized, so an unchanged reference — including the editor's own\n // echoed output — is a no-op and never clobbers the caret).\n effect(() => {\n const editor = this.instance();\n const data = this.data$();\n\n if (!editor || data === undefined) {\n return;\n }\n\n // A freshly created editor was already seeded with `data` at construction;\n // record it without re-rendering.\n if (this.seededEditor !== editor) {\n this.seededEditor = editor;\n this.lastRenderedData = data;\n\n return;\n }\n\n if (deepEqual(data, this.lastRenderedData)) {\n return;\n }\n\n this.lastRenderedData = data;\n // `data` may be null (a controlled \"clear to empty\"); render() throws on\n // null, so normalize null → { blocks: [] } at the boundary.\n this.renderChain = this.renderChain.catch(() => undefined).then(() => editor.render(toRenderableData(data)));\n });\n\n // Emit `ready` once per editor, after `instance()` is populated so a consumer\n // reading the component/ref instance inside the handler sees it.\n effect(() => {\n const editor = this.instance();\n\n if (editor && editor !== this.lastReadyInstance) {\n this.lastReadyInstance = editor;\n this.ready.emit(editor);\n }\n });\n\n // Subscribe to the editor's rendered-lifecycle events once it exists (gated on\n // the outputs being observed). `onCleanup` unsubscribes when the instance is\n // replaced or the component is destroyed.\n effect((onCleanup) => {\n const editor = this.instance();\n\n if (!editor) {\n return;\n }\n\n const handlers: Array<[string, (payload?: unknown) => void]> = [];\n\n if (this.blocksRendered.observed) {\n const handler = (payload?: unknown): void =>\n this.ngZone.run(() => this.blocksRendered.emit(payload as BlocksRenderedPayload));\n\n editor.on('blocks:rendered', handler);\n handlers.push(['blocks:rendered', handler]);\n }\n\n if (this.blockRendered.observed) {\n const handler = (payload?: unknown): void =>\n this.ngZone.run(() => this.blockRendered.emit(payload as BlockRenderedPayload));\n\n editor.on('block:rendered', handler);\n handlers.push(['block:rendered', handler]);\n }\n\n onCleanup(() => {\n for (const [name, handler] of handlers) {\n editor.off(name, handler);\n }\n });\n });\n }\n\n // ---- ControlValueAccessor (optional forms integration) ----\n\n /** Seeds/renders an externally-set form value through the same dedup machinery. */\n writeValue(value: OutputData | LooseOutputData | null): void {\n this.data$.set(value ?? undefined);\n }\n\n registerOnChange(fn: (data: OutputData) => void): void {\n this.cvaOnChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.cvaOnTouched = fn;\n }\n\n /** Form disabled state maps to the editor's read-only mode (via the readOnly effect). */\n setDisabledState(isDisabled: boolean): void {\n this.readOnly$.set(isDisabled);\n }\n}\n","import type { BlockAPI, BlockToolConstructorOptions, BlockToolData, ToolboxConfig } from '@bloklabs/core';\n// packages/angular/src/createAngularBlock.ts\nimport { signal, type Type, type WritableSignal } from '@angular/core';\n\nimport { DATA_ATTR } from '../adapters-contract';\nimport { deepEqual } from '../adapters-contract';\nimport { fillDefaults, type PropSchema } from '../adapters-contract';\nimport { mountChildBlocks } from '../adapters-contract';\n\nimport type { AngularBlockRenderContext } from './block-context';\nimport { BLOK_PORTAL_REGISTRY_CONFIG_KEY, type BlockPortalRegistry } from './block-portal-registry';\n\n/** Spec for {@link createAngularBlock}. Authored as a standalone component. */\nexport interface CreateAngularBlockSpec<Data = BlockToolData> {\n /** Tool type name (registered key). */\n type: string;\n /** Optional toolbox entry. */\n toolbox?: ToolboxConfig;\n /** Declarative defaults that also define the exact `save()` key set. */\n propSchema: PropSchema;\n /**\n * The standalone Angular component to render for each block. It injects the\n * per-block context via `inject(BLOK_BLOCK_CONTEXT)`.\n */\n component: Type<unknown>;\n /** Optional lifecycle callbacks mapped from Blok's block hooks. */\n onRendered?: (block: BlockAPI) => void;\n onMoved?: (block: BlockAPI) => void;\n onRemoved?: (block: BlockAPI) => void;\n}\n\n/**\n * Author a first-party Angular block. Returns a `BlockToolConstructable`\n * registered exactly like a vanilla tool (`tools: { type: { class:\n * createAngularBlock(...) } }`).\n *\n * The factory owns the host element (`data-blok-mutation-free`), a frozen\n * defaults-filled data mirror, and signals the component reads. It mounts the\n * component into the host via the editor's shared portal registry (the analog of\n * Vue's Teleport registry), bridging Blok's block lifecycle to Angular:\n * - `render()` creates the host and registers the portal entry (mounted sync).\n * - `setData()` dedups, swaps the reactive snapshot, flushes CD, resolves true.\n * - `save()` returns the complete frozen mirror (never the DOM, never partial).\n * - `commit()` merges a patch and fires `dispatchChange` exactly once.\n * - `setReadOnly()` flips a reactive flag and flushes CD (in-place, no remount).\n * - `removed()`/`destroy()` unregister the portal (deterministic unmount).\n */\nexport function createAngularBlock<Data = BlockToolData>(\n spec: CreateAngularBlockSpec<Data>\n): (new (options: BlockToolConstructorOptions) => {\n render(): HTMLElement;\n save(): BlockToolData;\n setData(newData: BlockToolData): Promise<boolean>;\n setReadOnly(state: boolean): void;\n rendered(): void;\n moved(): void;\n removed(): void;\n destroy(): void;\n}) & {\n readonly __isBlokAngularBlock: true;\n readonly toolbox: ToolboxConfig | undefined;\n readonly isReadOnlySupported: boolean;\n} {\n return class AngularBlockTool {\n /** Marker so the directive can detect Angular-block tools and inject the registry. */\n public static readonly __isBlokAngularBlock = true as const;\n\n public static get toolbox(): ToolboxConfig | undefined {\n return spec.toolbox;\n }\n\n /**\n * Angular blocks support read-only mode: `setReadOnly` flips a reactive flag\n * the component reads, so the block re-renders read-only IN PLACE. Without\n * this static, core's ReadOnly module throws when read-only is enabled and an\n * Angular block is present.\n */\n public static get isReadOnlySupported(): boolean {\n return true;\n }\n\n private readonly blockApi: BlockAPI;\n private readonly registry: BlockPortalRegistry | undefined;\n private readonly pointerDrag: () => boolean;\n private readonly dataSig: WritableSignal<Readonly<Data>>;\n private readonly readOnlySig: WritableSignal<boolean>;\n private readonly ctx: AngularBlockRenderContext<Data>;\n private mirror: Readonly<Data>;\n /** Dedup baseline: skip a redundant flush of identical data. */\n private lastRendered: Readonly<Data>;\n private hostEl: HTMLElement | null = null;\n /** Last host passed to ctx.mountChildren, re-mounted on each data change. */\n private childHost: HTMLElement | null = null;\n /** True while a pointer drag suppresses dispatchChange. */\n private pendingDispatch = false;\n\n public constructor(options: BlockToolConstructorOptions) {\n this.blockApi = options.block;\n\n const config = (options.config ?? {}) as Record<string, unknown>;\n\n this.registry = config[BLOK_PORTAL_REGISTRY_CONFIG_KEY] as BlockPortalRegistry | undefined;\n\n // Read the LIVE pointer-drag flag so a mid-drag commit can be deferred\n // (core silently drops a dispatchChange while a drag is active).\n const api = options.api as unknown as { blocks?: { isPointerDragActive?: boolean } } | undefined;\n\n this.pointerDrag = (): boolean => api?.blocks?.isPointerDragActive === true;\n\n this.mirror = fillDefaults<Data>(spec.propSchema, (options.data ?? {}) as Record<string, unknown>);\n this.lastRendered = this.mirror;\n this.dataSig = signal(this.mirror);\n this.readOnlySig = signal(options.readOnly);\n\n this.ctx = {\n data: this.dataSig.asReadonly(),\n commit: this.commit,\n block: this.blockApi,\n readOnly: this.readOnlySig.asReadonly(),\n mountChildren: this.mountChildren,\n };\n }\n\n public render(): HTMLElement {\n const host = document.createElement('div');\n\n // Core's MutationObserver ignores this subtree, so Angular's DOM writes\n // never register as a user edit.\n host.setAttribute('data-blok-mutation-free', 'true');\n this.hostEl = host;\n\n this.registry?.register(this.blockApi.id, {\n hostEl: host,\n component: spec.component,\n context: this.ctx as AngularBlockRenderContext<unknown>,\n });\n\n return host;\n }\n\n public rendered(): void {\n spec.onRendered?.(this.blockApi);\n }\n\n public save(): BlockToolData {\n return this.mirror as BlockToolData;\n }\n\n public async setData(newData: BlockToolData): Promise<boolean> {\n const next = fillDefaults<Data>(spec.propSchema, (newData ?? {}) as Record<string, unknown>);\n\n // Dedup: identical data → skip the flush, but still return true so core\n // keeps the block in place (no remount).\n if (deepEqual(next, this.lastRendered)) {\n return true;\n }\n\n this.mirror = next;\n this.lastRendered = next;\n this.dataSig.set(next);\n // Synchronous CD: core drives setData outside NgZone, so nothing else\n // schedules a render. Never throw (a throw would make core remount).\n this.registry?.flush(this.blockApi.id);\n this.remountChildren();\n\n // Resolve after a microtask for interface symmetry with the async core\n // setData contract; CD has already flushed synchronously above.\n await Promise.resolve();\n\n return true;\n }\n\n /**\n * In-place read-only toggle. Flips the reactive flag the component reads via\n * `ctx.readOnly`, then flushes CD so the block re-renders read-only WITHOUT a\n * remount (ephemeral state survives). A prototype method (not an arrow field)\n * so core's `supportsInPlaceReadOnly` — which probes the PROTOTYPE — selects\n * the in-place path.\n */\n public setReadOnly(state: boolean): void {\n this.readOnlySig.set(state);\n this.registry?.flush(this.blockApi.id);\n }\n\n public moved(): void {\n // No remount: core relocates the host element; the mounted view rides along\n // as its DOM children.\n spec.onMoved?.(this.blockApi);\n }\n\n public removed(): void {\n this.registry?.unregister(this.blockApi.id);\n spec.onRemoved?.(this.blockApi);\n }\n\n public destroy(): void {\n // Idempotent with removed(); unregister is safe when already absent.\n this.registry?.unregister(this.blockApi.id);\n }\n\n /** Container blocks: remember the host and (re)mount the real child holders. */\n private readonly mountChildren = (host: HTMLElement): void => {\n this.childHost = host;\n host.setAttribute(DATA_ATTR.nestedBlocks, '');\n this.remountChildren();\n };\n\n private remountChildren(): void {\n if (this.childHost !== null) {\n mountChildBlocks(this.childHost, this.blockApi.getChildren());\n }\n }\n\n /**\n * The only data write path. Merges the patch into the frozen mirror, swaps\n * the reactive snapshot, flushes CD, and fires dispatchChange EXACTLY once —\n * deferring it while a pointer drag is active (core would otherwise silently\n * drop it).\n */\n private readonly commit = (patch: Partial<Data>): void => {\n const next = fillDefaults<Data>(spec.propSchema, {\n ...(this.mirror as Record<string, unknown>),\n ...(patch as Record<string, unknown>),\n });\n\n // Idempotent: a patch that changes nothing is a full no-op — no signal\n // swap, no CD flush, no dispatchChange — so an effect echoing the current\n // value back through commit can never loop.\n if (deepEqual(next, this.mirror)) {\n return;\n }\n\n this.mirror = next;\n this.lastRendered = next;\n this.dataSig.set(next);\n this.registry?.flush(this.blockApi.id);\n this.remountChildren();\n this.flushDispatch();\n };\n\n /** Dispatch the change, or retry on the next frame if a drag is in progress. */\n private flushDispatch(): void {\n if (!this.pointerDrag()) {\n this.pendingDispatch = false;\n this.blockApi.dispatchChange();\n\n return;\n }\n\n if (this.pendingDispatch) {\n return;\n }\n\n this.pendingDispatch = true;\n\n const retry = (): void => {\n if (this.pointerDrag()) {\n requestAnimationFrame(retry);\n\n return;\n }\n\n this.pendingDispatch = false;\n this.blockApi.dispatchChange();\n };\n\n requestAnimationFrame(retry);\n }\n };\n}\n","import type { Blok } from '@bloklabs/core';\n// packages/angular/src/useBlocks.ts\nimport { DestroyRef, effect, inject, signal, type Signal } from '@angular/core';\n\nimport { createBlocksApiForEditor, EMPTY_API } from '../adapters-contract';\n\nimport type { UseBlocksApi } from './blocks-snapshot';\n\nconst BLOCK_CHANGED_EVENT = 'block changed';\n\n/**\n * Angular factory exposing an id/parentId-relative, reactive view of the block\n * tree. Reads refresh whenever the editor emits `block changed`; mutators route\n * through the editor-level `blocks` API (core's chokepoints), so undo/redo and\n * Yjs sync are inherited rather than re-implemented.\n *\n * The block-tree logic is framework-agnostic and lives in the shared\n * {@link createBlocksApiForEditor} core — the SAME implementation behind React's\n * and Vue's `useBlocks`, so all three adapters expose the identical 28-method\n * surface and cannot drift. This wrapper supplies only Angular's reactivity:\n *\n * - A private `version` signal is bumped on every `block changed`. The shared API\n * is built with an `onRead` seam (`() => { version() }`) that every read method\n * calls, so reading inside a `computed`/template tracks `version` and re-runs on\n * each structural mutation.\n * - The bound API is rebuilt (via `bindToEditor`, called eagerly on first call and\n * then tracked by an `effect` for subsequent identity changes) when the editor\n * IDENTITY changes; the returned facade is stable across that swap.\n *\n * Call it in an injection context (component constructor / field initializer),\n * passing the editor signal (e.g. `BlokEditorComponent.instance` /\n * `BlokContentDirective.instance`). Pre-ready (editor null) the bound API is the\n * shared {@link EMPTY_API}: every mutator a no-op, reads empty/null — except\n * `transact`/`transactWithoutCapture`, which still run their callback.\n *\n * Note: Angular 20's `effect()` is scheduled (not eager) — it does not fire\n * synchronously on first call. The initial binding therefore runs synchronously\n * in the `injectBlocks` body itself (mirroring Vue's `{ immediate: true }` watch),\n * and the effect re-binds only on subsequent editor identity changes. When the\n * effect fires for the first time with the same editor already bound, the guard\n * `ed === sub.editor` makes it a no-op, so no double-subscription occurs.\n *\n * @param editor - a signal of the Blok instance, or null pre-ready\n */\nexport function injectBlocks(editor: Signal<Blok | null>): UseBlocksApi {\n // Bumped on every `block changed`; the shared API's read methods touch it (via\n // the onRead seam) so template/computed reads stay reactive.\n const version = signal(0);\n const touch = (): void => {\n version();\n };\n\n // The API bound to the CURRENT editor; EMPTY_API while null. A signal so the\n // facade's reads track the editor-identity swap.\n const bound = signal<UseBlocksApi>(EMPTY_API);\n\n // One subscription record (no `let` reassignment), re-bound on editor change.\n const sub: { editor: Blok | null; handler: (() => void) | null } = { editor: null, handler: null };\n\n const unsubscribe = (): void => {\n if (sub.editor !== null && sub.handler !== null) {\n sub.editor.off(BLOCK_CHANGED_EVENT, sub.handler);\n }\n sub.editor = null;\n sub.handler = null;\n };\n\n /**\n * Bind to `ed` if the identity has changed. Guards `ed === sub.editor` so a\n * deferred first effect-run with the same editor already bound is a no-op\n * (no double-subscription). Called synchronously on first call (immediate\n * binding) and then re-tracked by the effect below (future identity changes).\n */\n const bindToEditor = (ed: Blok | null): void => {\n if (ed === sub.editor) {\n return; // Same editor already bound; nothing to do.\n }\n\n unsubscribe();\n // A changed editor identity is itself a reason to re-read.\n version.update((v) => v + 1);\n\n if (ed === null) {\n bound.set(EMPTY_API);\n\n return;\n }\n\n const handler = (): void => {\n version.update((v) => v + 1);\n };\n\n ed.on(BLOCK_CHANGED_EVENT, handler);\n sub.editor = ed;\n sub.handler = handler;\n bound.set(createBlocksApiForEditor(ed, touch));\n };\n\n // Run the initial binding SYNCHRONOUSLY so the returned facade is immediately\n // usable (Angular's effect() is deferred — it does not fire on the same tick).\n // This mirrors Vue's `watch(..., { immediate: true })`.\n bindToEditor(editor());\n\n // Re-bind when the editor identity changes. Angular 20 permits signal writes\n // inside effect() by default (allowSignalWrites option was removed in v20).\n effect(() => {\n bindToEditor(editor());\n });\n\n inject(DestroyRef).onDestroy(unsubscribe);\n\n // A stable facade whose methods delegate to the currently-bound API. Reading\n // `bound()` tracks the editor swap; shared reads track `version` via onRead.\n // Every key listed EXPLICITLY (no spread) so a forgotten delegation is a\n // COMPILE error against UseBlocksApi rather than a silently-missing method.\n return {\n getById: (id) => bound().getById(id),\n getChildren: (parentId) => bound().getChildren(parentId),\n insert: (spec) => bound().insert(spec),\n insertMany: (specs) => bound().insertMany(specs),\n insertTree: (spec) => bound().insertTree(spec),\n insertMarkdown: (markdown, options) => bound().insertMarkdown(markdown, options),\n exportMarkdown: () => bound().exportMarkdown(),\n move: (id, target) => bound().move(id, target),\n nest: (id, parentId) => bound().nest(id, parentId),\n unnest: (id) => bound().unnest(id),\n remove: (id) => bound().remove(id),\n update: (id, data, tunes) => bound().update(id, data, tunes),\n convert: (id, newType, dataOverrides, options) => bound().convert(id, newType, dataOverrides, options),\n transact: (fn) => bound().transact(fn),\n transactWithoutCapture: (fn) => bound().transactWithoutCapture(fn),\n getBlocksCount: () => bound().getBlocksCount(),\n getCurrentBlockIndex: () => bound().getCurrentBlockIndex(),\n getBlockByIndex: (index) => bound().getBlockByIndex(index),\n getBlockByElement: (element) => bound().getBlockByElement(element),\n getBlockData: (id) => bound().getBlockData(id),\n getBlockIndex: (id) => bound().getBlockIndex(id),\n composeBlockData: (toolName) => bound().composeBlockData(toolName),\n renderFromHTML: (html) => bound().renderFromHTML(html),\n insertOutputData: (blocks, options) => bound().insertOutputData(blocks, options),\n splitBlock: (currentBlockId, currentBlockData, newBlockType, newBlockData, insertIndex) =>\n bound().splitBlock(currentBlockId, currentBlockData, newBlockType, newBlockData, insertIndex),\n insertInsideParent: (parentId, insertIndex, childData) =>\n bound().insertInsideParent(parentId, insertIndex, childData),\n render: (data) => bound().render(data),\n clear: () => bound().clear(),\n isSyncingFromYjs: () => bound().isSyncingFromYjs(),\n };\n}\n","// packages/angular/src/useBlokReady.ts\nimport { DestroyRef, ElementRef, afterNextRender, inject, signal, type Signal } from '@angular/core';\n\nimport { Blok as BlokRuntime } from '@bloklabs/core';\n\n/** How the caller names the DOM scope to observe. */\nexport type BlokReadyScope =\n | (() => Element | ElementRef<Element> | null | undefined)\n | ElementRef<Element>\n | Element\n | null;\n\n/** Options accepted by {@link injectBlokReady}. */\nexport interface InjectBlokReadyOptions {\n /**\n * Restrict the wait to editors mounted inside this element. Accepts an\n * element, an `ElementRef`, or a getter/signal returning either — the getter\n * form lets you pass `() => this.scopeRef?.nativeElement` from a field\n * initializer, before the view exists. It is re-read on every readiness\n * change.\n *\n * Omit it to observe every editor on the page. Passing it while it still\n * resolves to null reports NOT ready — an unresolved scope must never fall\n * back to the page-global one.\n */\n within?: BlokReadyScope;\n /**\n * `'ready'` (default) settles when each editor has finished booting.\n * `'rendered'` also waits for its content to be in the DOM and re-arms on\n * every post-boot re-render.\n */\n settleOn?: 'ready' | 'rendered';\n}\n\n/**\n * Resolves the caller's scope description to an element, or null when it is\n * not available yet.\n * @param within - the scope description passed in options\n */\nfunction resolveScope(within: BlokReadyScope): Element | null {\n const value = typeof within === 'function' ? within() : within;\n\n if (value === null || value === undefined) {\n return null;\n }\n\n return value instanceof ElementRef ? value.nativeElement : value;\n}\n\n/**\n * Angular factory exposing the live readiness of the Blok editors in a DOM\n * scope as a boolean signal.\n *\n * The readiness logic itself is framework-agnostic and lives in core\n * (`Blok.readyState` / `Blok.subscribeReady`) — the SAME implementation behind\n * React's and Vue's `useBlokReady`, so the three adapters cannot drift. This\n * wrapper supplies only Angular's reactivity: a signal re-read on every\n * registry change, unsubscribed through the injector's `DestroyRef`.\n *\n * Call it in an injection context (component constructor / field initializer).\n * The signal starts `false` and takes its first real reading in\n * `afterNextRender` — browser-only by contract, and late enough for a\n * `@ViewChild` scope to exist. Over-waiting is safe; under-waiting is a bug.\n * @param options - scope and readiness depth\n */\nexport function injectBlokReady(options: InjectBlokReadyOptions = {}): Signal<boolean> {\n const { within, settleOn } = options;\n const ready = signal(false);\n\n const read = (): void => {\n const scope = within === undefined ? null : resolveScope(within);\n\n // A scope that was asked for but has not resolved yet is NOT the global\n // scope — reporting ready here would gate on the wrong set of editors.\n ready.set(within !== undefined && scope === null\n ? false\n : BlokRuntime.readyState({\n within: scope,\n settleOn,\n }).ready);\n };\n\n inject(DestroyRef).onDestroy(BlokRuntime.subscribeReady(read));\n afterNextRender(read);\n\n return ready.asReadonly();\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["BlokRuntime"],"mappings":"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"}
|