@sobree/core 0.1.1 → 0.1.2

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.
Files changed (37) hide show
  1. package/dist/doc/types.d.ts +40 -30
  2. package/dist/docx/shared/units.d.ts +3 -2
  3. package/dist/docx/shared/xml.d.ts +12 -0
  4. package/dist/editor/commands.d.ts +14 -0
  5. package/dist/editor/context.d.ts +71 -0
  6. package/dist/editor/dom.d.ts +21 -0
  7. package/dist/editor/events.d.ts +29 -0
  8. package/dist/editor/index.d.ts +85 -663
  9. package/dist/editor/internal/mutations.d.ts +1 -1
  10. package/dist/editor/ops/blocks.d.ts +42 -0
  11. package/dist/editor/ops/comments.d.ts +12 -0
  12. package/dist/editor/ops/parts.d.ts +71 -0
  13. package/dist/editor/ops/review.d.ts +67 -0
  14. package/dist/editor/ops/runs.d.ts +83 -0
  15. package/dist/editor/ops/trackedInput.d.ts +44 -0
  16. package/dist/editor/query.d.ts +22 -0
  17. package/dist/editor/revisionRuns.d.ts +56 -0
  18. package/dist/editor/selection.d.ts +34 -0
  19. package/dist/editor/types.d.ts +292 -0
  20. package/dist/editor/view/docRenderer/anchorPosition.d.ts +18 -0
  21. package/dist/editor/view/docRenderer/sectionFlow.d.ts +23 -0
  22. package/dist/editor/view/docRenderer/table.d.ts +11 -2
  23. package/dist/index.css +1 -1
  24. package/dist/index.js +6099 -6020
  25. package/dist/index.js.map +1 -1
  26. package/dist/paperStack/paginationV2/apply.d.ts +18 -0
  27. package/dist/paperStack/paginationV2/engine.d.ts +7 -0
  28. package/dist/paperStack/paginationV2/measure.d.ts +9 -0
  29. package/dist/paperStack/paginationV2/types.d.ts +273 -0
  30. package/dist/paperStack/paper.d.ts +31 -9
  31. package/dist/paperStack/paperStack.d.ts +13 -1
  32. package/dist/paperStack/paperZone.d.ts +35 -0
  33. package/dist/plugins/marks.d.ts +4 -4
  34. package/dist/ydoc/schema.d.ts +5 -0
  35. package/package.json +1 -1
  36. package/dist/__vite-browser-external-DYxpcVy9.js +0 -5
  37. package/dist/__vite-browser-external-DYxpcVy9.js.map +0 -1
@@ -1,5 +1,5 @@
1
1
  import { Block, ParagraphProperties, RunProperties, SectionProperties, SobreeDocument } from '../../doc/types';
2
- import { ParagraphPropertiesPatch, WrapTag } from '../index';
2
+ import { ParagraphPropertiesPatch, WrapTag } from '../types';
3
3
  import { RunPropertiesPatch } from '../../doc/runs';
4
4
  /**
5
5
  * One registry-level operation produced by a mutation. The caller
@@ -0,0 +1,42 @@
1
+ import { BlockRef, EditResult } from '../../doc/api';
2
+ import { Block } from '../../doc/types';
3
+ import { EditorContext } from '../context';
4
+ import { ParagraphPropertiesPatch } from '../types';
5
+ /**
6
+ * Block-level mutations: replace / insert / delete whole blocks and
7
+ * patch paragraph properties. All enforce optimistic locking via
8
+ * `ctx.checkRefs` and route through `ctx.commit`. Section-break removal
9
+ * merges the two sections it delimited. Track-changes mode stamps
10
+ * paragraph insert/delete markers instead of moving content outright.
11
+ */
12
+ /** Replace the block at `target`'s index with `block`. */
13
+ export declare function replaceBlock(ctx: EditorContext, target: BlockRef, block: Block): EditResult<BlockRef>;
14
+ /**
15
+ * Insert `block` before the target block. Returns the new ref.
16
+ *
17
+ * In track-changes mode, if `block` is a paragraph it gets stamped with
18
+ * `revision: { type: "ins", author }` on its properties — the same
19
+ * paragraph-mark semantics as `splitBlock`. Non-paragraph blocks (table,
20
+ * section_break) don't carry the marker in v1 and insert plain.
21
+ */
22
+ export declare function insertBlockBefore(ctx: EditorContext, target: BlockRef, block: Block): EditResult<BlockRef>;
23
+ /**
24
+ * Insert `block` after the target block. Returns the new ref.
25
+ * Tracked-mode behaviour matches `insertBlockBefore`.
26
+ */
27
+ export declare function insertBlockAfter(ctx: EditorContext, target: BlockRef, block: Block): EditResult<BlockRef>;
28
+ /**
29
+ * Delete the target block.
30
+ *
31
+ * In track-changes mode, paragraph blocks aren't removed — their
32
+ * `properties.revision` is stamped `del` (the renderer shows the
33
+ * paragraph mark with a strikethrough ¶ glyph; the body text stays
34
+ * visible). If the paragraph carries the *current author's* pending
35
+ * `ins` marker (a paragraph the user themselves just created), the block
36
+ * is removed outright — cancelling an un-committed insert, matching the
37
+ * inline `deleteRange` semantics. Non-paragraph blocks (tables, section
38
+ * breaks) bypass tracking in v1 — they remove plainly.
39
+ */
40
+ export declare function deleteBlock(ctx: EditorContext, target: BlockRef): EditResult<void>;
41
+ /** Merge a patch into each target paragraph's properties. */
42
+ export declare function applyBlockProperties(ctx: EditorContext, targets: BlockRef[], patch: ParagraphPropertiesPatch): EditResult<void>;
@@ -0,0 +1,12 @@
1
+ import { EditResult } from '../../doc/api';
2
+ import { EditorContext } from '../context';
3
+ /**
4
+ * Comment resolve/reopen — flips `Comment.done` on the document's
5
+ * comment map. Comments live outside the body registry, so no block
6
+ * version bumps are needed; the change still commits (and mirrors) so
7
+ * collaborators and the change event see it.
8
+ */
9
+ /** Mark comment `id` resolved (`Comment.done = true`). */
10
+ export declare function resolveComment(ctx: EditorContext, id: number): EditResult<void>;
11
+ /** Re-open a resolved comment `id` (`Comment.done = false`). */
12
+ export declare function reopenComment(ctx: EditorContext, id: number): EditResult<void>;
@@ -0,0 +1,71 @@
1
+ import { SobreeDocument } from '../../doc/types';
2
+ import { EmbedFontFaces, EmbedFontOptions } from '../../fonts';
3
+ import { EditorContext } from '../context';
4
+ /**
5
+ * Binary-part lifecycle: font embedding, orphan pruning, and the
6
+ * content-blob (`BlobStore`) migration path. When a `BlobStore` is
7
+ * configured, inline part bytes are mirrored to the store by content
8
+ * hash and referenced via `partRefs` instead of living inline in the
9
+ * Y.Doc; `resolveCachedPartRefsInto` / `onBlobResolved` patch bytes
10
+ * back into `doc.rawParts` as they arrive so the renderer stays
11
+ * synchronous. With no `BlobStore` (the default) the migration paths are
12
+ * no-ops and bytes are always inline.
13
+ */
14
+ /** Patch any cached blob bytes for known partRefs into `doc.rawParts`. */
15
+ export declare function resolveCachedPartRefsInto(ctx: EditorContext, doc: SobreeDocument): void;
16
+ /**
17
+ * Callback fired by the BlobCache when a background fetch lands. Walks
18
+ * `lastPartRefs` to find which paths reference this hash, patches
19
+ * `doc.rawParts`, and re-renders so the user sees the part appear.
20
+ */
21
+ export declare function onBlobResolved(ctx: EditorContext, hash: string): void;
22
+ /**
23
+ * Wait for every currently-referenced binary part to be available in
24
+ * the local cache. Useful before `toDocx()` so the exported file
25
+ * contains all images / fonts. Resolves immediately when no `blobStore`
26
+ * is configured (bytes are always inline).
27
+ */
28
+ export declare function ensurePartsLoaded(ctx: EditorContext): Promise<void>;
29
+ /**
30
+ * Drop entries from `rawParts` that nothing in the AST references.
31
+ * Idempotent; reports the keys removed. Not auto-invoked — `exportDocx`
32
+ * filters at packaging time, so callers only need this when keeping the
33
+ * doc in-memory across many edits.
34
+ */
35
+ export declare function pruneUnusedParts(ctx: EditorContext): {
36
+ kept: number;
37
+ pruned: string[];
38
+ };
39
+ /**
40
+ * Embed a TTF/OTF font into the document. Thin wrapper around
41
+ * `embedFontIntoDoc()` — handles the `setDocument` round so the renderer
42
+ * + `@font-face` registry pick up the new face, and migrates the added
43
+ * part bytes to the BlobStore when one is configured. Refuses (with a
44
+ * warning) restricted fonts unless `opts.allowRestricted`.
45
+ */
46
+ export declare function embedFont(ctx: EditorContext, name: string, faces: EmbedFontFaces, opts?: EmbedFontOptions): {
47
+ warnings: string[];
48
+ };
49
+ /**
50
+ * Drop a font declaration by name. The associated font parts aren't
51
+ * removed immediately — call `pruneUnusedParts()` (or export) to GC them.
52
+ */
53
+ export declare function removeEmbeddedFont(ctx: EditorContext, name: string): void;
54
+ /**
55
+ * Part paths the Y.Doc mirror must NOT write inline — they're (or will
56
+ * soon be) tracked via `partRefs` instead. Returns `undefined` when
57
+ * there's nothing to skip (the common no-BlobStore case) so the mirror
58
+ * takes its fastest path.
59
+ */
60
+ export declare function computePartPathSkipSet(ctx: EditorContext): ReadonlySet<string> | undefined;
61
+ /**
62
+ * Background-migrate inline part bytes into the BlobStore. Called by
63
+ * mutators (`insertImage`, `embedFont`) when a `BlobStore` is configured.
64
+ * The local `doc.rawParts` keeps its inline copy so the renderer stays
65
+ * synchronous; the Y.Doc gets a `partRefs` entry referencing the
66
+ * content hash and any stale `parts` entry is deleted.
67
+ *
68
+ * Robust against errors: an upload failure logs and leaves the path in
69
+ * the pending set so a future call can retry.
70
+ */
71
+ export declare function migratePartToBlobStore(ctx: EditorContext, partPath: string, bytes: Uint8Array): Promise<void>;
@@ -0,0 +1,67 @@
1
+ import { Range as ApiRange, BlockRef, EditResult } from '../../doc/api';
2
+ import { EditorContext } from '../context';
3
+ import { RevisionSpan } from '../types';
4
+ /**
5
+ * Tracked-change review: accept/reject of inline, format, and
6
+ * paragraph-mark revisions (single-range, paragraph-level, or
7
+ * whole-document), plus `getRevisions` which enumerates every logical
8
+ * change as coalesced `RevisionSpan`s. The run-level decisions reuse the
9
+ * pure transforms in `revisionRuns`; the engine is `mutateRunsInRange`
10
+ * (shared with the authoring path in `ops/runs`).
11
+ */
12
+ /**
13
+ * Accept the tracked changes inside `range`: insertions become permanent
14
+ * (marker stripped, text kept), deletions are applied (text dropped).
15
+ * Runs with no revision pass through, so a slightly-wider range is safe.
16
+ */
17
+ export declare function acceptRevision(ctx: EditorContext, range: ApiRange, opts?: {
18
+ expect?: Record<string, number>;
19
+ }): EditResult<void>;
20
+ /** Reject the tracked changes inside `range`. Inverse of `acceptRevision`. */
21
+ export declare function rejectRevision(ctx: EditorContext, range: ApiRange, opts?: {
22
+ expect?: Record<string, number>;
23
+ }): EditResult<void>;
24
+ /** Accept tracked format changes inside `range` (drop the snapshot). */
25
+ export declare function acceptFormatRevision(ctx: EditorContext, range: ApiRange, opts?: {
26
+ expect?: Record<string, number>;
27
+ }): EditResult<void>;
28
+ /** Reject tracked format changes inside `range` (revert to `before`). */
29
+ export declare function rejectFormatRevision(ctx: EditorContext, range: ApiRange, opts?: {
30
+ expect?: Record<string, number>;
31
+ }): EditResult<void>;
32
+ /**
33
+ * Accept the paragraph-mark revision on `target`:
34
+ * - `ins` → strip the marker; the paragraph break stays permanent.
35
+ * - `del` → merge this paragraph's content into the *previous* one.
36
+ */
37
+ export declare function acceptParagraphRevision(ctx: EditorContext, target: BlockRef): EditResult<void>;
38
+ /**
39
+ * Reject the paragraph-mark revision on `target`:
40
+ * - `ins` → merge this paragraph into the *previous* (undo the split).
41
+ * - `del` → strip the marker; the paragraph break stays.
42
+ */
43
+ export declare function rejectParagraphRevision(ctx: EditorContext, target: BlockRef): EditResult<void>;
44
+ /**
45
+ * Flag `body[index]`'s paragraph break as a tracked deletion. Used by
46
+ * the Backspace-at-start-of-paragraph keystroke. Cancels the author's
47
+ * own pending `ins` by merging instead; leaves peer revisions alone.
48
+ */
49
+ export declare function markParagraphBreakForDelete(ctx: EditorContext, index: number): EditResult<void>;
50
+ /**
51
+ * Enumerate every logical tracked change. Consecutive revision-bearing
52
+ * runs by the same author coalesce into one `RevisionSpan`; each span
53
+ * carries fresh versioned refs ready for accept/reject. Re-query after
54
+ * each `change` — the ranges are positional.
55
+ */
56
+ export declare function getRevisions(ctx: EditorContext): RevisionSpan[];
57
+ /**
58
+ * Accept every tracked change (optionally filtered by author). One
59
+ * commit for the whole sweep.
60
+ */
61
+ export declare function acceptAllRevisions(ctx: EditorContext, opts?: {
62
+ author?: string;
63
+ }): EditResult<void>;
64
+ /** Reject every tracked change (optionally filtered by author). */
65
+ export declare function rejectAllRevisions(ctx: EditorContext, opts?: {
66
+ author?: string;
67
+ }): EditResult<void>;
@@ -0,0 +1,83 @@
1
+ import { Range as ApiRange, BlockRef, EditResult, InlinePosition } from '../../doc/api';
2
+ import { RunPropertiesPatch } from '../../doc/runs';
3
+ import { InlineRun } from '../../doc/types';
4
+ import { EditorContext } from '../context';
5
+ import { WrapTag } from '../types';
6
+ /**
7
+ * Inline (run-level) mutations — run properties, wrapping, run/image
8
+ * insertion, paragraph split, and range deletion — plus the image
9
+ * clipboard/drag handlers. `mutateRunsInRange` is the shared engine that
10
+ * applies a run transform to the slice a range covers (single- or
11
+ * multi-block); it's exported because the review module reuses it for
12
+ * accept/reject. Track-changes mode stamps `ins`/`del`/`revisionFormat`
13
+ * markers instead of mutating text outright.
14
+ */
15
+ /** Apply run-level properties across `range`. */
16
+ export declare function applyRunProperties(ctx: EditorContext, range: ApiRange, patch: RunPropertiesPatch, opts?: {
17
+ expect?: Record<string, number>;
18
+ }): EditResult<void>;
19
+ /** Wrap the runs in `range` with semantic formatting. */
20
+ export declare function wrapRange(ctx: EditorContext, range: ApiRange, tag: WrapTag, opts?: {
21
+ expect?: Record<string, number>;
22
+ }): EditResult<void>;
23
+ /**
24
+ * Insert a run at `at`. Splits the run list at the offset. In
25
+ * track-changes mode the run is stamped `revision: ins` (unless it
26
+ * already carries one — caller-provided revisions win).
27
+ */
28
+ export declare function insertRun(ctx: EditorContext, at: InlinePosition, run: InlineRun): EditResult<BlockRef>;
29
+ /**
30
+ * Split a paragraph at `at`. Runs before the offset stay; runs after
31
+ * move into a fresh paragraph inserted immediately after, inheriting the
32
+ * original's properties. In track-changes mode the new paragraph's
33
+ * `properties.revision` is stamped `ins` (the "this break is a tracked
34
+ * insert" marker). Returns the ref of the *new* (second) block.
35
+ */
36
+ export declare function splitBlock(ctx: EditorContext, at: InlinePosition): EditResult<BlockRef>;
37
+ /**
38
+ * Insert an image at `at`. Bytes go into `doc.rawParts` under a fresh
39
+ * `word/media/imageN.{ext}` path; a `DrawingRun` referencing it is
40
+ * inserted. When a `blobStore` is configured the bytes migrate in the
41
+ * background (hashed + uploaded + `partRefs` entry); the local renderer
42
+ * keeps reading the inline bytes throughout.
43
+ */
44
+ export declare function insertImage(ctx: EditorContext, at: InlinePosition, bytes: Uint8Array, opts: {
45
+ mime: string;
46
+ widthPx?: number;
47
+ heightPx?: number;
48
+ altText?: string;
49
+ }): EditResult<BlockRef>;
50
+ /**
51
+ * Delete the content inside `range` (single- or cross-block). In
52
+ * track-changes mode the deletion is *recorded*: plain runs are stamped
53
+ * `del`, a run already marked as the same author's pending `ins` is
54
+ * dropped (cancelling an un-committed insert), peer revisions are left
55
+ * for accept/reject. Cross-paragraph tracked deletes also stamp each
56
+ * later paragraph-mark `del` so `acceptAllRevisions` collapses the range.
57
+ */
58
+ export declare function deleteRange(ctx: EditorContext, range: ApiRange, opts?: {
59
+ expect?: Record<string, number>;
60
+ }): EditResult<void>;
61
+ /**
62
+ * Apply a runs transform to the runs covered by `range`. Handles single-
63
+ * and multi-block ranges. Assumes locks have already been checked.
64
+ * Exported for reuse by the review (accept/reject) module.
65
+ */
66
+ export declare function mutateRunsInRange(ctx: EditorContext, range: ApiRange, transform: (runs: InlineRun[]) => InlineRun[]): EditResult<void>;
67
+ /**
68
+ * Unwrap span ancestors intersecting the selection, up to the block.
69
+ * Best-effort DOM-level cleanup — preserves the in-place UX without a
70
+ * re-render.
71
+ */
72
+ export declare function clearInlineFormattingAtSelection(ctx: EditorContext): void;
73
+ /** Insert an image at the current caret. */
74
+ export declare function insertImageAtSelection(ctx: EditorContext, bytes: Uint8Array, opts: {
75
+ mime: string;
76
+ widthPx?: number;
77
+ heightPx?: number;
78
+ altText?: string;
79
+ }): EditResult<BlockRef>;
80
+ /** Read a File's bytes + intrinsic dimensions and insert it at the caret. */
81
+ export declare function insertImageFromFile(ctx: EditorContext, file: File): Promise<void>;
82
+ export declare function onDragOver(_ctx: EditorContext, e: DragEvent): void;
83
+ export declare function onDrop(ctx: EditorContext, e: DragEvent): Promise<void>;
@@ -0,0 +1,44 @@
1
+ import { EditorContext } from '../context';
2
+ /**
3
+ * Track-changes *authoring* input — the DOM event handlers that route
4
+ * tracked-mode keystrokes, IME composition, and paste through the typed
5
+ * API so the resulting runs carry revision markers. Stateful (it holds
6
+ * the IME composition snapshot + a warn-once set), so it's built once per
7
+ * editor via {@link createTrackedInput} rather than exposed as free
8
+ * functions like the other `ops/*` modules.
9
+ *
10
+ * Collaborators: `ops/runs` (insertRun / splitBlock / deleteRange /
11
+ * insertImageFromFile), `ops/review` (markParagraphBreakForDelete for the
12
+ * Backspace-at-start-of-paragraph merge), `query` (caret placement +
13
+ * position refresh), and the kernel `restoreSnapshot` for the IME
14
+ * rollback. The mode *config* (`getTrackChanges` / `setTrackChanges`)
15
+ * stays on the Editor — it only touches the listener registry.
16
+ */
17
+ export interface TrackedInput {
18
+ /**
19
+ * Route a tracked-mode `beforeinput` through the typed API. Returns
20
+ * `true` if consumed (caller should `preventDefault`), `false` to let
21
+ * the browser handle it natively (untracked).
22
+ */
23
+ handleBeforeInput(ie: InputEvent): boolean;
24
+ /**
25
+ * True when the caret sits in a block containing any revision wrapper
26
+ * (`<ins>` / `<del>` / `.sobree-revision-format`). `beforeinput` uses
27
+ * this in mode-OFF to take over the insert path so the browser doesn't
28
+ * stamp the new character with the wrapper's marker.
29
+ */
30
+ caretInsideRevisionWrapper(): boolean;
31
+ handleCompositionStart(e: CompositionEvent): void;
32
+ handleCompositionEnd(e: CompositionEvent): void;
33
+ onPaste(e: ClipboardEvent): Promise<void>;
34
+ /**
35
+ * Insert `text` at the current selection as a tracked paste — each
36
+ * `\n` becomes a `splitBlock`, CRLF/CR normalised to LF. The plain-text
37
+ * core of `onPaste`, exposed directly because jsdom provides no
38
+ * `DataTransfer` to drive `onPaste` end-to-end in tests.
39
+ */
40
+ pasteTrackedText(text: string): void;
41
+ /** Clear any in-flight composition state (called on editor destroy). */
42
+ reset(): void;
43
+ }
44
+ export declare function createTrackedInput(ctx: EditorContext): TrackedInput;
@@ -0,0 +1,22 @@
1
+ import { InlinePosition } from '../doc/api';
2
+ import { Block } from '../doc/types';
3
+ import { EditorContext } from './context';
4
+ import { BlockInfo, OutlineItem } from './types';
5
+ /**
6
+ * Read-only projections of the document — block summaries, the heading
7
+ * outline, an HTML snapshot — plus the two position helpers
8
+ * (`placeCaret` / `refreshedPosition`) that resolve a block id to a live
9
+ * ref. All pull through `ctx.ensureCurrent()` so a pending DOM edit is
10
+ * folded in before the read. No mutation, no commit.
11
+ */
12
+ export declare function toHtml(ctx: EditorContext): string;
13
+ export declare function getBlocks(ctx: EditorContext): BlockInfo[];
14
+ export declare function getBlock(ctx: EditorContext, index: number): BlockInfo;
15
+ /** Same summary, looked up by stable id. Returns `null` if unknown. */
16
+ export declare function getBlockById(ctx: EditorContext, id: string): BlockInfo | null;
17
+ export declare function getOutline(ctx: EditorContext): OutlineItem[];
18
+ export declare function summariseBlock(ctx: EditorContext, block: Block, index: number): BlockInfo;
19
+ /** Refresh a position's block ref to the live version (id stays stable). */
20
+ export declare function refreshedPosition(ctx: EditorContext, at: InlinePosition): InlinePosition | null;
21
+ /** Place the caret at `(blockId, offset)` using a fresh block ref. */
22
+ export declare function placeCaret(ctx: EditorContext, blockId: string, offset: number): void;
@@ -0,0 +1,56 @@
1
+ import { InlineRun } from '../doc/types';
2
+ /**
3
+ * Resolve one run against an accept/reject decision on its tracked
4
+ * change. Returns the replacement run list — `[run]` unchanged,
5
+ * `[stripped]` to keep the text minus the revision marker, or `[]` to
6
+ * drop the run entirely.
7
+ *
8
+ * accept + ins → keep text, strip marker (insertion confirmed)
9
+ * accept + del → drop run (deletion applied)
10
+ * reject + ins → drop run (insertion undone)
11
+ * reject + del → keep text, strip marker (deletion undone)
12
+ *
13
+ * Non-text runs and runs with no `revision` pass through untouched.
14
+ */
15
+ export declare function decideRevisionRun(run: InlineRun, decision: "accept" | "reject"): InlineRun[];
16
+ /**
17
+ * Authoring helper for `insertRun` in track-changes mode. Stamps an
18
+ * `ins` revision on the run if it doesn't already carry one — a caller
19
+ * providing a pre-stamped run (e.g. an import code path replaying a
20
+ * revision) wins. Mirrors `decideRevisionRun`'s text-only contract:
21
+ * non-text runs (drawings, breaks, tabs, …) pass through unchanged in
22
+ * v1 — Word does track drawing inserts as revisions, but layering that
23
+ * on the non-uniform `properties` shape of non-text runs is a follow-up.
24
+ */
25
+ export declare function stampInsertRevision(run: InlineRun, author: string | undefined): InlineRun;
26
+ /**
27
+ * Consumption helper for `acceptFormatRevision` / `rejectFormatRevision`.
28
+ *
29
+ * accept → drop `revisionFormat`; current `properties` stay.
30
+ * reject → restore `properties` to `revisionFormat.before`; the
31
+ * snapshot is then dropped too (the run is back to its
32
+ * pre-tracking state and there's nothing to undo).
33
+ *
34
+ * Runs without a `revisionFormat` snapshot pass through unchanged.
35
+ */
36
+ export declare function decideFormatRun(run: InlineRun, decision: "accept" | "reject"): InlineRun;
37
+ /**
38
+ * Authoring helper for `applyRunProperties` in track-changes mode.
39
+ * Captures the run's current `properties` (excluding any existing
40
+ * `revisionFormat` so the snapshot stays self-contained) as
41
+ * `revisionFormat.before` if no snapshot is already in place.
42
+ * Subsequent tracked format edits skip re-snapshotting — the *original*
43
+ * pre-tracking state always wins on reject.
44
+ */
45
+ export declare function snapshotFormatRevision(run: InlineRun, author: string | undefined): InlineRun;
46
+ /**
47
+ * Authoring helper for `deleteRange` in track-changes mode. Per the
48
+ * `TrackChangesState` semantics, applied per text run in range:
49
+ * - plain run (no revision) → stamp `del`
50
+ * - already-pending `ins` by same author → drop the run (cancel)
51
+ * - everything else (peer revision, peer
52
+ * `del`, anything pre-marked) → leave untouched
53
+ * Non-text runs pass through unchanged (same text-only contract as
54
+ * `stampInsertRevision`).
55
+ */
56
+ export declare function stampDeleteRevision(run: InlineRun, author: string | undefined): InlineRun[];
@@ -0,0 +1,34 @@
1
+ import { Range as ApiRange, BlockRef, InlinePosition, Selection } from '../doc/api';
2
+ import { BlockRegistry } from './internal/blockRegistry';
3
+ /**
4
+ * The slice of Editor internals `EditorSelection` reads — its
5
+ * decoupling seam, so this module doesn't import the concrete `Editor`
6
+ * class (which would re-introduce an import cycle). The `Editor`
7
+ * structurally satisfies it via its `_hosts()` / `_registry()`
8
+ * accessors.
9
+ */
10
+ export interface SelectionHost {
11
+ _hosts(): HTMLElement[];
12
+ _registry(): BlockRegistry;
13
+ }
14
+ /**
15
+ * Model-level view of the editor's live DOM selection. `editor.selection`
16
+ * is an instance of this; it translates between the browser selection
17
+ * and Sobree's `Selection` / `Range` / `InlinePosition` shapes.
18
+ */
19
+ export declare class EditorSelection {
20
+ private readonly editor;
21
+ constructor(editor: SelectionHost);
22
+ /** Current selection as a model `Selection`. Returns `null` when focus is outside. */
23
+ get(): Selection;
24
+ /** Apply a model selection to the DOM. */
25
+ set(sel: Selection): boolean;
26
+ /** Shortcut: current selection as a `Range`, or `null` when collapsed/absent. */
27
+ currentRange(): ApiRange | null;
28
+ /** Shortcut: the caret position (collapses a range to its `from`). */
29
+ currentCaret(): InlinePosition | null;
30
+ /** Shortcut: ref of the block containing the caret. */
31
+ currentBlock(): BlockRef | null;
32
+ /** Legacy: current block index (for code still using indices). */
33
+ currentBlockIndex(): number | null;
34
+ }