@searsuite/sear-domain-doc
Document nodes
A rich document is a tree of RichDocNode values. Paragraphs, text runs, tables, rows, and cells are node types
in that tree. DocNodeRegistry creates nodes from schema data; Schema, NodeSchema, and the node guards describe which
shapes the runtime accepts. Use the built-in node types when reading or constructing document content, then add
custom node behavior through the registry used by your Doc assembly.
The tree is document data. Layout measurements and painted nodes are computed later by the editor and render packages, so storing a document does not require a visual host.
- classRichDocNode
-
Base class for rich-document nodes used by the document layout engine.
property attrs: Record<string, any>Node attributes such as text styles or block metadata.
property content: RichDocNode[] | TextNode[]Child rich-document nodes.
property id: string | undefinedStable structural identity for layout, retained render nodes, and collaboration mapping.
property type: stringDomain node type identifier.
method create(_schema: Schema): RichDocNodestaticCreates a concrete rich-document node from persisted schema.
- classDocNodeRegistry
-
Registry that maps persisted rich-document node types to constructors.
constructor DocNodeRegistry(): DocNodeRegistryproperty readonly symbol: typeof symbolstaticDI token for resolving the document node registry.
method create(schema: Schema): RichDocNodeInstance method: delegates to the static registry; used by DI-injected consumers.
method isBlockType(type: string): booleanInstance method: returns whether the persisted type has been registered as a block container.
method isTextType(type: string): booleanInstance method: returns whether the persisted type has been registered as text-like.
method register(definition: DocNodeDefinition): voidRegisters a node factory on this registry instance.
method requireDefaultBlockType(): stringInstance method: returns the registered default block type for generic text editing.
method requireDefaultTextType(): stringInstance method: returns the registered default text type for generic text editing.
method create(schema: Schema): RichDocNodestaticCreates a rich-document node from persisted schema.
method isBlockType(type: string): booleanstaticReturns whether the persisted type has been registered as a block container.
method isTextType(type: string): booleanstaticReturns whether the persisted type has been registered as text-like.
methodregisterstatic register(type: string, creator: (schema: Schema): RichDocNode): voidregister(definition: DocNodeDefinition): voidRegisters a node factory for a persisted node type.
method requireDefaultBlockType(): stringstaticReturns the registered default block type for generic text editing.
method requireDefaultTextType(): stringstaticReturns the registered default text type for generic text editing.
- classParagraphNode
-
class ParagraphNode extends RichDocNodeBuilt-in paragraph node.
constructor ParagraphNode(schema: NodeSchema): ParagraphNodeCreates a paragraph node from persisted schema.
property readonly nodeType: "paragraph"staticPersisted schema type owned by the paragraph document feature.
- classTableCellNode
-
class TableCellNode extends RichDocNodeBuilt-in table cell node.
constructor TableCellNode(schema: NodeSchema): TableCellNodeCreates a table cell node from persisted schema.
property readonly nodeType: "tableCell"staticPersisted schema type owned by the table document feature.
- classTableNode
-
class TableNode extends RichDocNodeBuilt-in table block node.
constructor TableNode(schema: NodeSchema): TableNodeCreates a table node from persisted schema.
property readonly nodeType: "table"staticPersisted schema type owned by the table document feature.
- classTableRowNode
-
class TableRowNode extends RichDocNodeBuilt-in table row node.
constructor TableRowNode(schema: NodeSchema): TableRowNodeCreates a table row node from persisted schema.
property readonly nodeType: "tableRow"staticPersisted schema type owned by the table document feature.
- classTextNode
-
class TextNode extends RichDocNodeBuilt-in text leaf node.
constructorconstructor TextNode(schema: NodeSchema): TextNodeTextNode(schema: TextSchema): TextNodeCreates a text node from persisted schema.
property text?: stringText content carried by this leaf node.
property readonly nodeType: "text"staticPersisted schema type owned by the text input document feature.
- interfaceDocNodeDefinition
-
Registration contract for one persisted rich-document node type.
property readonly create: (schema: Schema): RichDocNodeFactory that creates the runtime node instance for this persisted schema.
property readonly defaultBlock?: booleanWhether this block is the default container for plain text editing.
property readonly defaultText?: booleanWhether this text-like node is the default leaf for plain text editing.
property readonly role?: DocNodeRoleGeneric role consumed by core editing/layout helpers.
property readonly type: stringPersisted schema type owned by a document feature plugin.
- interfaceRichNodeFactory
-
Minimal factory interface for creating document nodes. Implemented by
DocNodeRegistry(static or injected). - typeDocNodeId
-
type DocNodeId = string & { [docNodeIdBrand]: true }Stable identity used by document layout and retained render nodes.
- typeDocNodeRole
-
type DocNodeRole = typeof DocNodeRole[keyof typeof DocNodeRole]DocNodeRole: { Block: "block"; Text: "text" } - typeRichTextChar
-
type RichTextChar = unknownMeasured inline character/token used by rich-text line wrapping.
property char: stringproperty fontAscent: numberproperty fontDescent?: numberproperty fontLineGap?: numberproperty height: numberproperty style?: RichTextInlineStyleproperty textNodeIndex?: numberDirect child index of the source text node within its paragraph.
property textNodeOffset?: numberCharacter offset within the source text node.
property width: number - functioncloneRichDocument
-
cloneRichDocument(document: readonly RichDocNode[]): RichDocNode[]Returns a detached mutable snapshot of a rich document.
- functioncreateDocNodeId
-
createDocNodeId(value: string): DocNodeIdCreates a typed document node id from a non-empty string value.
- functioncreateDocNodeIdFromPath
-
createDocNodeIdFromPath(path: readonly string | number[]): DocNodeIdCreates a fallback document node id from a rich-document path.
- functioncreateEmptyParagraph
-
createEmptyParagraph(): RichDocNodeCreate a single empty paragraph containing one empty text node.
- functiongetTextNodeLength
-
getTextNodeLength(doc: RichDocNode[], path: number[]): numberCharacter length of the text node at
path. Returns 0 for missing / non-text nodes. - functionisDocSemanticallyEmpty
-
isDocSemanticallyEmpty(doc: RichDocNode[]): booleanReturns true if every paragraph in
doccontains no meaningful text. - functionisTextNode
-
isTextNode(node: TextNode | RichDocNode): nodeReturns true when a rich-document node is a text leaf.
- functionnormalizeDocForEdit
-
normalizeDocForEdit(doc: RichDocNode[]): RichDocNode[]Ensure
dochas at least one paragraph. Returns the same array if already valid; otherwise[createEmptyParagraph()]. - functionparaText
-
paraText(para: RichDocNode): stringExtract the concatenated plain text of a paragraph node.
- functionparaTextLength
-
paraTextLength(para: RichDocNode): numberTotal plain-text length of a paragraph node (sums all direct text children).
- functionregisterParagraphDocNode
-
registerParagraphDocNode(registry: DocNodeRegistrar): voidRegisters the paragraph node type owned by paragraph-oriented document features.
- functionregisterTableDocNodes
-
registerTableDocNodes(registry: DocNodeRegistrar): voidRegisters the table node types owned by table-oriented document features.
- functionregisterTextDocNode
-
registerTextDocNode(registry: DocNodeRegistrar): voidRegisters the text node type owned by text-input document features.
- functionresolveDocNodeId
-
resolveDocNodeId(node: { id?: string } | undefined, path: readonly string | number[]): DocNodeIdResolves a block-level document id, preferring persisted node identity over path fallback.
- functionresolveNode
-
resolveNode(doc: RichDocNode[], path: number[]): RichDocNode | undefinedResolve the text node at
pathinsidedoc(treated as the root content array). Returnsundefinedif the path is invalid. - functionstringToRichDoc
-
stringToRichDoc(text: string): RichDocNode[]Convert a plain string to a single-paragraph RichDocNode[]. Used for backward-compat when cell data is still stored as a plain string.
- interfaceNodeSchema
-
Persisted rich-document node schema shared by document runtime, commands, and OT.
property attrs?: Record<string, any>Node attributes for styles, formatting, and feature-owned metadata.
property content?: Schema[]Child rich-document nodes.
property id?: stringStable structural identity for layout, retained render nodes, and collaboration mapping.
property text?: stringOptional text content for leaf text nodes.
property type: stringDomain node type identifier.
- typeSchema
-
type Schema = NodeSchema | TextSchemaPersisted rich-document schema node.
- interfaceTextSchema
-
interface TextSchema extends NodeSchemaPersisted text-bearing rich-document node schema.
property text: stringOptional text content for leaf text nodes.
Selection and positions
DocCursorPos identifies a text node with a path from the document root and an offset inside that node.
DocSelection holds an anchor and a head; when they point to the same position, the selection is a cursor.
Commands use these positions to target edits, and OT paths follow the same tree structure.
Start with DocSelection when moving a caret or selecting text. Use the layout contracts only when a host needs
geometry for rendering or hit testing.
- interfaceDocSelection
-
Anchor + head selection model. Collapsed selection (cursor only): anchor === head.
headmoves freely;anchoris fixed until a non-Shift action resets it.property anchor: DocCursorPosproperty head: DocCursorPos - interfaceDocCursorPos
-
Cursor position inside a RichDocNode tree.
pathis an array of integer indices that navigates from the implicit document root (theRichDocNode[]array treated asroot.content) down to the text node that contains the cursor.Examples for a flat document: [0, 0] → paragraph 0 → text node 0 (the most common case in P0) [1, 2] → paragraph 1 → inline span 2
The path aligns with OT operation paths: a StringInsert at this cursor becomes
{ p: [...path, offset], si: text }applied to the root wrapper{ type: 'doc', content: doc }.offsetis the character position within the leaf text node: 0 = before first character n = after the nth character (= text.length means "end of node")property offset: numberCharacter offset within the leaf text node.
property path: number[]Path from root
content[]to the leaf text node. - interfaceTextSelection
-
property anchor: string | number[]property head: string | number[] - functioncompareCursor
-
compareCursor(a: DocCursorPos, b: DocCursorPos): -1 | 0 | 1Lexicographic comparison of two cursor positions. Compares
pathelement-by-element, thenoffset. Returns -1 | 0 | 1. - functiongetDocumentOffset
-
getDocumentOffset(doc: RichDocNode[], position: DocCursorPos): numberConverts a cursor position into a zero-based offset in the document's plain text, using one newline character between paragraphs.
- functionisCollapsed
-
isCollapsed(sel: DocSelection): boolean - functionmapInlineTextRangePatchCursor
-
mapInlineTextRangePatchCursor(cursor: DocCursorPos, patches: readonly InlineTextRangePatch[]): DocCursorPosRepositions a cursor after an inline text range patch plan has been applied.
- functionnormalizeSelection
-
normalizeSelection(sel: DocSelection): { end: DocCursorPos; start: DocCursorPos }Normalize selection so
start≤endregardless of direction. - functionresolveTextContent
-
resolveTextContent(doc: RichDocNode[], path: number[]): stringGet the plain-text string of the node at
path. Convenience wrapper aroundresolveNode.
Text formatting
Inline style functions patch a text range while preserving the surrounding document tree.
- classRichTextInlineStyleRegistry
-
Ordered registry for plugin-owned rich-text inline style readers and mutations.
constructor RichTextInlineStyleRegistry(): RichTextInlineStyleRegistryproperty readonly symbol: typeof symbolstaticDI token for resolving the inline style registry.
method enforceWriteBoundary(assertWrite: (): void): voidmethod getMutation(styleKey: string): RichTextInlineStyleMutation | undefinedResolves a plugin-owned persisted inline style mutation by style key when registered.
method getMutationKeys(): readonly string[]Returns all registered persisted inline-style mutation keys in registration order.
method readTextNodeStyle(node: TextNode): Readonly<Record<string, unknown>> | undefinedReads all registered style slices from a text node.
method register(contribution: RichTextInlineStyleContribution): (): voidRegisters one plugin-owned inline style contribution.
method requireMutation(styleKey: string): RichTextInlineStyleMutationResolves a plugin-owned persisted inline style mutation by style key.
method sameStyle(styleA: Readonly<Record<string, unknown>> | undefined, styleB: Readonly<Record<string, unknown>> | undefined): booleanCompares two style bags using stable key/value serialization.
- interfaceInlineTextRangePatch
-
One text-node replacement produced by an inline text range edit.
property readonly beforeLength: numberproperty readonly blockIndex: numberproperty readonly childIndex: numberproperty readonly endOffset: numberproperty readonly oldNode: TextNodeproperty readonly replacement: readonly RichDocNode[]property readonly replacementCount: numberproperty readonly selectedLength: numberproperty readonly startOffset: numberproperty readonly wholeNode: boolean - interfaceInlineTextRangePatchContext
-
Context supplied when patching one selected text-node segment.
property readonly blockIndex: numberproperty readonly childIndex: numberproperty readonly endOffset: numberproperty readonly node: TextNodeproperty readonly startOffset: number - interfaceRichTextInlineStyleContribution
-
Plugin-owned contribution for one inline text style concern.
property readonly key: stringStable contribution key used for duplicate detection and unregister.
property mutations?: readonly RichTextInlineStyleMutation[]Persisted inline text-style mutations owned by this contribution.
method read(input: RichTextInlineStyleReadInput): Readonly<Record<string, unknown>> | undefinedReads this contribution's style slice from a text node.
- interfaceRichTextInlineStyleMutation
-
Plugin-owned mutation for one persisted inline text-style concern.
property readonly styleKey: stringStable style key used by commands to resolve this mutation.
method apply(input: RichTextInlineStyleMutationInput): Record<string, unknown>Applies the normalized style value to a text node's persisted attrs.
- interfaceRichTextInlineStyleMutationInput
-
Input supplied when an inline-style contribution mutates persisted text-node attrs.
property readonly attrs: Record<string, unknown>property readonly value: unknown - interfaceRichTextInlineStyleReadInput
-
Input supplied when an inline-style contribution reads document attrs.
property readonly attrs: Record<string, unknown>property readonly node: TextNode - interfaceTextAttributeRange
-
interface TextAttributeRange<TAttributes>A generic text attribute range in document-relative character offsets.
- interfaceTextGraphemeRange
-
One grapheme range expressed in UTF-16 source offsets.
property readonly end: numberproperty readonly start: number - typeInlineTextRangeAttrsPatcher
-
type InlineTextRangeAttrsPatcher = (attrs: Record<string, unknown>, context: InlineTextRangePatchContext): Record<string, unknown>Patches the attrs for the selected segment of one text node.
- typeRichTextInlineStyle
-
type RichTextInlineStyle = Readonly<Record<string, unknown>>Domain-neutral inline style bag carried by measured rich-text chars.
- typeTextAttributePatch
-
type TextAttributePatch = Readonly<Record<string, unknown>>Attributes merged into a text node for one presentation range.
- variableRichTextParagraphAttribute
-
RichTextParagraphAttribute: { LineSpacing: "lineSpacing"; SpacingAfter: "spacingAfter" }Persisted paragraph attribute keys owned by the paragraph feature.
- functionapplyInlineTextRangePatchPlan
-
applyInlineTextRangePatchPlan(doc: readonly RichDocNode[], patches: readonly InlineTextRangePatch[]): RichDocNode[]Applies an inline text range patch plan to an immutable document snapshot.
- functionapplyInlineTextStylePropertyMutation
-
applyInlineTextStylePropertyMutation(attrs: Readonly<Record<string, unknown>>, property: string, value: unknown): Record<string, unknown>Applies or removes one persisted inline-text style property.
- functionapplyRichTextFormat
-
applyRichTextFormat(document: readonly Schema[], format: Readonly<Record<string, unknown>>, registry: RichTextInlineStyleRegistry): Schema[]Replaces registered styles while retaining text, structure and unrelated attributes.
- functionapplyTextAttributeRanges
-
applyTextAttributeRanges(doc: RichDocNode[], ranges: readonly TextAttributeRange<Readonly<Record<string, unknown>>>[]): RichDocNode[]Applies presentation attributes to text ranges without owning their meaning. Plugins decide how to interpret the resulting text-node attrs.
- functionbuildInlineTextRangePatchPlan
-
buildInlineTextRangePatchPlan(doc: readonly RichDocNode[], selection: DocSelection, patchAttrs: InlineTextRangeAttrsPatcher): InlineTextRangePatch[]Builds reusable text-node split/replacement patches for a document selection.
- functioncaptureRichTextFormat
-
captureRichTextFormat(document: readonly Schema[], registry: RichTextInlineStyleRegistry): Readonly<Record<string, unknown>>Captures the leading text run's explicit registered styles, excluding host defaults.
- functioncreateInlineTextStyleAttrsPatcher
-
createInlineTextStyleAttrsPatcher(property: string, value: unknown): InlineTextRangeAttrsPatcherCreates the compatibility inline text-style attrs patcher for property/value callers.
- functionreadTextStyleAttrs
-
readTextStyleAttrs(attrs: Record<string, unknown>): Record<string, unknown>Reads the inline text-style attribute bag from a node's attributes.
- functionreplaceInlineTextStyle
-
replaceInlineTextStyle(doc: RichDocNode[], selection: DocSelection, property: string, value: unknown, patchAttrs?: InlineTextRangeAttrsPatcher): RichDocNode[]Replaces one inline text-style property on the selected document range.
- functionsegmentTextGraphemes
-
segmentTextGraphemes(text: string): readonly TextGraphemeRange[]Segments text into grapheme ranges, with a code-point fallback for older hosts.
- functionupdateInlineTextStyleAttrs
-
updateInlineTextStyleAttrs(current: unknown, property: string, value: unknown): Record<string, unknown>Updates one entry in a text node's style attrs bag.
Text layout
- classRichTextBlockFlowRegistry
-
Ordered registry for plugin-owned top-level block flow resolution.
constructor RichTextBlockFlowRegistry(defaultSpacingAfter?: number): RichTextBlockFlowRegistryproperty readonly symbol: typeof symbolstaticmethod enforceWriteBoundary(assertWrite: (): void): voidmethod register(contribution: RichTextBlockFlowContribution): (): voidmethod resolve(input: { blockCount: number; index: number; node: RichDocNode }): number - classRichTextLineBoxRegistry
-
Ordered registry for plugin-owned rich-text line box resolution.
constructor RichTextLineBoxRegistry(): RichTextLineBoxRegistryproperty readonly symbol: typeof symbolstaticDI token for resolving the rich-text line box registry.
method enforceWriteBoundary(assertWrite: (): void): voidmethod register(contribution: RichTextLineBoxContribution): (): voidRegisters one plugin-owned line box contribution.
method resolve(input: { chars: readonly RichTextChar[]; lineSpacing?: RichTextLineSpacing }): RichTextLineBoxResolves the final line box for one measured line.
- interfaceRichTextBlockFlowContribution
-
Plugin-owned contribution that can refine block flow metrics.
- interfaceRichTextBlockFlowResolveInput
-
Input used to resolve the flow spacing after one top-level document block.
property readonly blockCount: numberproperty readonly index: numberproperty readonly node: RichDocNodeproperty readonly spacingAfter: number - interfaceRichTextBlockLayoutProvider
-
Domain-side contract for services that provide measured rich-text block layout.
method calculateLayoutPerParagraph(width: number): RichTextLine[][]method setBaseFont(font: string): voidUpdates the transient font used when measuring unstyled text.
- interfaceRichTextLineBox
-
Flow metrics for one rich-text line.
property readonly ascent: numberproperty readonly contentHeight: numberproperty readonly descent: numberproperty readonly leadingBottom: numberproperty readonly leadingTop: numberproperty readonly lineGap: numberproperty readonly lineHeight: number - interfaceRichTextLineBoxContribution
-
Plugin-owned contribution that can refine rich-text line flow metrics.
property readonly key: stringStable contribution key used for duplicate detection and unregister.
method resolve(input: RichTextLineBoxResolveInput): RichTextLineBoxResolves the next line box from the current accumulated line box.
- interfaceRichTextLineBoxResolveInput
-
Input used to resolve the flow box for one measured rich-text line.
- interfaceRichTextLineSpacing
-
Persisted or default line-spacing policy resolved by paragraph layout.
property readonly mode: RichTextLineSpacingModeproperty readonly value?: number - interfaceRichTextParagraphLayout
-
Resolved paragraph layout values consumed by line and block flow.
- interfaceRichTextParagraphLayoutDefaults
-
Default paragraph layout values supplied by the owning document runtime.
- typeRichTextLine
-
type RichTextLine = unknownOne laid-out rich-text line with aggregate dimensions.
property chars: RichTextChar[]property fontAscent: numberMax measured font ascent across all chars on this line; used for stable vertical centering.
property fontDescent?: numberMax measured font descent across all chars on this line.
property height: numberproperty lineBox?: RichTextLineBoxPlugin-resolved line box used for flow and baseline placement.
property width: number - typeRichTextLineSpacingMode
-
type RichTextLineSpacingMode = "auto" | "multiple" | "atLeast" | "exact"Supported paragraph line-spacing semantics.
- variabledefaultRichTextParagraphLayoutDefaults
-
defaultRichTextParagraphLayoutDefaults: RichTextParagraphLayoutDefaultsNeutral defaults for runtimes that do not configure document paragraph spacing.
- functioncomputeFirstBaselineY
-
computeFirstBaselineY(boxHeight: number, cellPadding: number, fontAscent: number, lineHeight: number, offsetY?: number): numberCompute the Y coordinate of the first text line's baseline for vertical centering.
Text painters in this engine position runs by their alphabetic baseline, so the correct formula to visually center a line inside a padded box is:
baseline = center + (fontAscent - fontDescent) / 2
Since
lineHeight = fontAscent + fontDescent, this simplifies to:baseline = offsetY + cellPadding + (boxHeight - 2·cellPadding + 2·fontAscent - lineHeight) / 2
boxHeightTotal pixel height of the containing box (e.g. cell height).
cellPaddingPadding on each side of the box.
fontAscentMeasured font ascent of the first line (stable across all glyphs in the font).
lineHeightTotal line height (
fontAscent + fontDescent) of the first line.offsetYAbsolute Y offset of the box top-left (default 0 for relative coordinates).
- functioncreateDefaultRichTextBlockFlowContribution
-
createDefaultRichTextBlockFlowContribution(): RichTextBlockFlowContributionCreates the paragraph-owned default after-spacing contribution.
- functioncreateDefaultRichTextLineBoxContribution
-
createDefaultRichTextLineBoxContribution(): RichTextLineBoxContributionCreates the default line box contribution used by document composition roots.
- functioncreateRichTextLineSpacingContribution
-
createRichTextLineSpacingContribution(): RichTextLineBoxContributionCreates the paragraph-owned line-spacing contribution.
- functionparseRichTextLineSpacing
-
parseRichTextLineSpacing(value: unknown): RichTextLineSpacing | nullParses a persisted line-spacing override, returning null when invalid.
- functionparseRichTextParagraphSpacing
-
parseRichTextParagraphSpacing(value: unknown): number | nullParses a persisted paragraph-spacing override, returning null when invalid.
- functionresolveRichTextParagraphLayout
-
resolveRichTextParagraphLayout(node: RichDocNode | undefined, defaults?: RichTextParagraphLayoutDefaults): RichTextParagraphLayoutResolves paragraph-owned overrides over the runtime defaults.
No matching API entries.