import { Query, TextAddress, TextMutationResolution, TextTarget, TocCreateLocation, UnknownNodeDiagnostic, WriteRequest } from '@superdoc/document-api'; import { BlockIndex } from './node-address-resolver.js'; import { Transaction } from 'prosemirror-state'; import { Editor } from '../../core/Editor.js'; export type WithinResult = { ok: true; range: { start: number; end: number; } | undefined; } | { ok: false; }; export type ResolvedTextTarget = { from: number; to: number; }; /** * Resolves a {@link TextAddress} to absolute ProseMirror positions. * * @param editor - The editor instance. * @param target - The text address to resolve. * @returns Absolute `{ from, to }` positions, or `null` if the target block cannot be found. * @throws {DocumentApiAdapterError} `INVALID_TARGET` when multiple text blocks share the same blockId. */ export declare function resolveTextTarget(editor: Editor, target: TextAddress): ResolvedTextTarget | null; /** * Resolves a {@link TextTarget} to absolute ProseMirror positions for inline insertion. * Extracts the first segment and delegates to {@link resolveTextTarget}. */ export declare function resolveInlineInsertPosition(editor: Editor, at: TextTarget, operationName: string): ResolvedTextTarget; /** * Resolves a {@link TocCreateLocation} to an absolute block insertion position. */ export declare function resolveBlockCreatePosition(editor: Editor, at: TocCreateLocation): number; /** * Result of resolving the default insertion target. * * - `text-block`: The last top-level text block was found; insert at its content end. * - `structural-end`: No top-level text block exists at or after the desired * insertion point. The caller must create a writable host (e.g. a paragraph) * at `insertPos` before inserting content. */ export type DefaultInsertTarget = { kind: 'text-block'; target: TextAddress; range: ResolvedTextTarget; } | { kind: 'structural-end'; insertPos: number; }; /** * Resolves the deterministic default insertion target for insert-without-target calls. * * Targets the **end** of the last top-level writable text block in document * order, so that target-less inserts behave as "append to document end." * * Only top-level blocks (direct children of the doc node) are considered. * Nested text blocks inside tables, SDTs, or other containers are excluded * so that a document ending in a table resolves to the last top-level * paragraph before it, not to a cell paragraph inside it. * * When no top-level text block exists, returns `structural-end` with the * position at the end of the document content (`doc.content.size`), signaling * that the caller must create a writable host before insertion. */ export declare function resolveDefaultInsertTarget(editor: Editor): DefaultInsertTarget | null; /** Resolved write target with the effective address, absolute range, and resolution snapshot. */ export type ResolvedWrite = { requestedTarget?: TextAddress; /** * The resolved target address used for the mutation. * * When {@link structuralEnd} is `true`, this is a synthetic placeholder * (`blockId: ''`) that should not be used for block lookup or display. */ effectiveTarget: TextAddress; range: ResolvedTextTarget; resolution: TextMutationResolution; /** * When `true`, the resolved position is at the structural end of the * document where no text block exists. The caller must create a writable * host (paragraph) at `range.from` before inserting content. */ structuralEnd?: true; }; /** * Creates a new paragraph containing the given text and inserts it at the * specified position using the editor's transaction pipeline. * * Used by structural-end handlers when the document ends with non-text blocks * and a writable host must be created before inserting content. * * @param applyMeta - Optional callback to annotate the transaction before * dispatch (e.g. `applyTrackedMutationMeta` for tracked-mode inserts). */ export declare function insertParagraphAtEnd(editor: Editor, pos: number, text: string, applyMeta?: (tr: Transaction) => Transaction): void; /** * Resolves the write target for a target-less insert request. * * Falls back to the document-end insertion point via {@link resolveDefaultInsertTarget}. * Targeted inserts now route through SelectionMutationAdapter, not WriteAdapter. * * For structural-end resolutions (doc ends in non-text blocks), the returned * `ResolvedWrite` has `structuralEnd: true` and the caller is responsible for * creating a writable host before insertion. */ export declare function resolveWriteTarget(editor: Editor, request: WriteRequest): ResolvedWrite | null; /** * Appends a diagnostic message to the mutable diagnostics array. * * @param diagnostics - Array to push the diagnostic into. * @param message - Human-readable diagnostic message. */ export declare function addDiagnostic(diagnostics: UnknownNodeDiagnostic[], message: string): void; /** * Validates pagination inputs, throwing `INVALID_INPUT` for invalid values. * * @param offset - Must be non-negative when provided. * @param limit - Must be positive when provided. * @throws {DocumentApiValidationError} `INVALID_INPUT` for negative offset or non-positive limit. */ export declare function validatePaginationInput(offset?: number, limit?: number): void; /** * Applies offset/limit pagination to an array, returning the total count and the sliced page. * * @param items - The full result array. * @param offset - Number of items to skip (default `0`). * @param limit - Maximum items to return (default: all remaining). * @returns An object with `total` (pre-pagination count) and `items` (the sliced page). * @throws {DocumentApiValidationError} `INVALID_INPUT` for negative offset or non-positive limit. */ export declare function paginate(items: T[], offset?: number, limit?: number): { total: number; items: T[]; }; /** * Deduplicates diagnostics by message + hint + address, preserving insertion order. * * @param diagnostics - The diagnostics to deduplicate. * @returns A new array with unique diagnostics. */ export declare function dedupeDiagnostics(diagnostics: UnknownNodeDiagnostic[]): UnknownNodeDiagnostic[]; /** * Resolves the `within` scope of a query to an absolute position range. * * @param index - Pre-built block index. * @param query - The query whose `within` clause should be resolved. * @param diagnostics - Mutable array to collect diagnostics into. * @returns `{ ok: true, range }` on success (range is `undefined` when no scope), or `{ ok: false }` with a diagnostic. */ export declare function resolveWithinScope(index: BlockIndex, query: Pick, diagnostics: UnknownNodeDiagnostic[]): WithinResult; /** * Filters candidates to those fully contained within the given position range. * Returns the full array unchanged when `range` is `undefined`. * * @param candidates - Candidates with `pos` and `end` fields. * @param range - Optional absolute position range to filter by. * @returns Filtered candidates. */ export declare function scopeByRange(candidates: T[], range: { start: number; end: number; } | undefined): T[]; /** * Binary-searches a sorted candidate array for the entry containing `pos`. * Uses half-open interval `[candidate.pos, candidate.end)`. * * @param candidates - Sorted array of candidates with `pos` and `end` fields. * @param pos - The absolute document position to look up. * @returns The matching candidate, or `undefined` if no candidate contains the position. */ export declare function findCandidateByPos(candidates: T[], pos: number): T | undefined; //# sourceMappingURL=adapter-utils.d.ts.map