@sobree/core 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +106 -0
- package/dist/__vite-browser-external-DYxpcVy9.js +5 -0
- package/dist/__vite-browser-external-DYxpcVy9.js.map +1 -0
- package/dist/blob/cache.d.ts +69 -0
- package/dist/blob/fetch.d.ts +18 -0
- package/dist/blob/hash.d.ts +13 -0
- package/dist/blob/index.d.ts +33 -0
- package/dist/blob/memory.d.ts +2 -0
- package/dist/blob/types.d.ts +80 -0
- package/dist/createSobree.d.ts +132 -0
- package/dist/doc/api.d.ts +132 -0
- package/dist/doc/builders.d.ts +42 -0
- package/dist/doc/pageSetupBridge.d.ts +26 -0
- package/dist/doc/parts.d.ts +18 -0
- package/dist/doc/runs.d.ts +47 -0
- package/dist/doc/styles.d.ts +19 -0
- package/dist/doc/types.d.ts +800 -0
- package/dist/doc/walk.d.ts +30 -0
- package/dist/docx/export/contentTypes.d.ts +35 -0
- package/dist/docx/export/context.d.ts +59 -0
- package/dist/docx/export/document.d.ts +19 -0
- package/dist/docx/export/drawings.d.ts +10 -0
- package/dist/docx/export/headers.d.ts +19 -0
- package/dist/docx/export/index.d.ts +14 -0
- package/dist/docx/export/runs.d.ts +8 -0
- package/dist/docx/export/styles.d.ts +8 -0
- package/dist/docx/export/zip.d.ts +13 -0
- package/dist/docx/import/anchoredFrames.d.ts +34 -0
- package/dist/docx/import/comments.d.ts +3 -0
- package/dist/docx/import/document.d.ts +57 -0
- package/dist/docx/import/flowFrames.d.ts +11 -0
- package/dist/docx/import/footnotes.d.ts +3 -0
- package/dist/docx/import/headers.d.ts +50 -0
- package/dist/docx/import/index.d.ts +12 -0
- package/dist/docx/import/inlineFrames.d.ts +62 -0
- package/dist/docx/import/numbering.d.ts +2 -0
- package/dist/docx/import/paragraph.d.ts +24 -0
- package/dist/docx/import/paragraphs.d.ts +27 -0
- package/dist/docx/import/rels.d.ts +5 -0
- package/dist/docx/import/runs.d.ts +64 -0
- package/dist/docx/import/settings.d.ts +48 -0
- package/dist/docx/import/styles.d.ts +3 -0
- package/dist/docx/import/tables.d.ts +12 -0
- package/dist/docx/import/unzip.d.ts +13 -0
- package/dist/docx/shared/namespaces.d.ts +31 -0
- package/dist/docx/shared/pageSize.d.ts +27 -0
- package/dist/docx/shared/shading.d.ts +2 -0
- package/dist/docx/shared/units.d.ts +35 -0
- package/dist/docx/shared/xml.d.ts +29 -0
- package/dist/docx/types.d.ts +98 -0
- package/dist/editor/index.d.ts +1078 -0
- package/dist/editor/internal/blockRegistry.d.ts +91 -0
- package/dist/editor/internal/mutations.d.ts +63 -0
- package/dist/editor/internal/positionMap.d.ts +35 -0
- package/dist/editor/table.d.ts +96 -0
- package/dist/editor/view/docRenderer/anchorLayer.d.ts +26 -0
- package/dist/editor/view/docRenderer/block.d.ts +13 -0
- package/dist/editor/view/docRenderer/fontFallback.d.ts +28 -0
- package/dist/editor/view/docRenderer/index.d.ts +18 -0
- package/dist/editor/view/docRenderer/inline.d.ts +15 -0
- package/dist/editor/view/docRenderer/inlineFrame.d.ts +4 -0
- package/dist/editor/view/docRenderer/lists.d.ts +28 -0
- package/dist/editor/view/docRenderer/paragraph.d.ts +2 -0
- package/dist/editor/view/docRenderer/properties.d.ts +2 -0
- package/dist/editor/view/docRenderer/table.d.ts +15 -0
- package/dist/editor/view/docRenderer/units.d.ts +48 -0
- package/dist/editor/view/docSerialize/block.d.ts +14 -0
- package/dist/editor/view/docSerialize/index.d.ts +8 -0
- package/dist/editor/view/docSerialize/inline.d.ts +11 -0
- package/dist/editor/view/docSerialize/table.d.ts +12 -0
- package/dist/editor/view/imageResize.d.ts +16 -0
- package/dist/embed/floatingCorner.d.ts +44 -0
- package/dist/embed/viewport.d.ts +133 -0
- package/dist/fonts/embedAPI.d.ts +33 -0
- package/dist/fonts/emit.d.ts +24 -0
- package/dist/fonts/fontFaceRegistry.d.ts +20 -0
- package/dist/fonts/fsType.d.ts +36 -0
- package/dist/fonts/index.d.ts +19 -0
- package/dist/fonts/liveness.d.ts +2 -0
- package/dist/fonts/odttf.d.ts +33 -0
- package/dist/fonts/parse.d.ts +29 -0
- package/dist/fonts/types.d.ts +52 -0
- package/dist/headless.d.ts +168 -0
- package/dist/history/history.d.ts +100 -0
- package/dist/history/index.d.ts +4 -0
- package/dist/history/types.d.ts +54 -0
- package/dist/index.css +1 -0
- package/dist/index.d.ts +52 -0
- package/dist/index.js +10561 -0
- package/dist/index.js.map +1 -0
- package/dist/markdown/parse.d.ts +6 -0
- package/dist/pagination/cost.d.ts +32 -0
- package/dist/pagination/index.d.ts +2 -0
- package/dist/pagination/paginate.d.ts +10 -0
- package/dist/pagination/postConditions.d.ts +10 -0
- package/dist/pagination/types.d.ts +94 -0
- package/dist/paperStack/pageSetup.d.ts +42 -0
- package/dist/paperStack/paginationAdapter/buildItems.d.ts +19 -0
- package/dist/paperStack/paginationAdapter/distribute.d.ts +23 -0
- package/dist/paperStack/paginationAdapter/index.d.ts +18 -0
- package/dist/paperStack/paginationAdapter/paragraphLines.d.ts +23 -0
- package/dist/paperStack/paginationAdapter/splitList.d.ts +19 -0
- package/dist/paperStack/paginationAdapter/splitParagraph.d.ts +21 -0
- package/dist/paperStack/paginationAdapter/types.d.ts +30 -0
- package/dist/paperStack/paper.d.ts +107 -0
- package/dist/paperStack/paperStack.d.ts +245 -0
- package/dist/plugin.d.ts +24 -0
- package/dist/plugins/marks.d.ts +49 -0
- package/dist/plugins/sections.d.ts +15 -0
- package/dist/presence/attach.d.ts +48 -0
- package/dist/presence/awareness.d.ts +28 -0
- package/dist/presence/index.d.ts +19 -0
- package/dist/presence/overlay.d.ts +28 -0
- package/dist/presence/state.d.ts +36 -0
- package/dist/sobree.d.ts +211 -0
- package/dist/tokens.css +144 -0
- package/dist/util/selection.d.ts +13 -0
- package/dist/ydoc/apply.d.ts +68 -0
- package/dist/ydoc/index.d.ts +18 -0
- package/dist/ydoc/project.d.ts +41 -0
- package/dist/ydoc/runs.d.ts +51 -0
- package/dist/ydoc/schema.d.ts +123 -0
- package/dist/ydoc/seed.d.ts +45 -0
- package/dist/ydoc/textDiff.d.ts +59 -0
- package/dist/zoneEdit/index.d.ts +22 -0
- package/package.json +61 -0
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
export interface ViewportOptions {
|
|
2
|
+
minScale?: number;
|
|
3
|
+
maxScale?: number;
|
|
4
|
+
/** Scale change per unit of wheel deltaY for shift+wheel. Default 0.005. */
|
|
5
|
+
wheelZoomSensitivity?: number;
|
|
6
|
+
/** Scale change per unit of wheel deltaY for pinch (ctrlKey). Default 0.02. */
|
|
7
|
+
pinchZoomSensitivity?: number;
|
|
8
|
+
onScaleChange?: (scale: number) => void;
|
|
9
|
+
/**
|
|
10
|
+
* Fires when the render tier changes — an integer ≥1 chosen from the
|
|
11
|
+
* current scale. The stage is laid out at that tier via CSS `zoom` so
|
|
12
|
+
* text rasterises at the zoomed size rather than being blitted from a
|
|
13
|
+
* 1× bitmap. Callers that care about layout (e.g. a paginator) should
|
|
14
|
+
* re-run their measurement + layout pass when the tier changes.
|
|
15
|
+
*/
|
|
16
|
+
onRenderTierChange?: (tier: number) => void;
|
|
17
|
+
/**
|
|
18
|
+
* Fires whenever the stage transform changes — zoom, pan, programmatic
|
|
19
|
+
* fit, or animated pan. Used by overlays (block toolbar, indicator)
|
|
20
|
+
* that live in viewport coordinates and must follow the page through
|
|
21
|
+
* any transform. Called frequently during gestures, so the handler
|
|
22
|
+
* should be cheap (read-rect-and-write-style cheap).
|
|
23
|
+
*/
|
|
24
|
+
onTransformChange?: () => void;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* A framework-free zoomable / pannable viewport.
|
|
28
|
+
*
|
|
29
|
+
* Layout:
|
|
30
|
+
* container (overflow:hidden, the element passed in)
|
|
31
|
+
* └ stage (absolutely positioned, transform: translate(tx,ty) scale(s))
|
|
32
|
+
* └ slot (where the embedded content lives — caller mounts here)
|
|
33
|
+
*
|
|
34
|
+
* Gestures:
|
|
35
|
+
* - Zoom: wheel with shiftKey OR ctrlKey (macOS pinch emits ctrlKey).
|
|
36
|
+
* The point under the cursor stays under the cursor (zoom-to-cursor).
|
|
37
|
+
* - Pan: wheel without modifiers — two-finger trackpad scroll deltas move
|
|
38
|
+
* the stage. Also supports click-drag with middle mouse or space.
|
|
39
|
+
*/
|
|
40
|
+
export declare class Viewport {
|
|
41
|
+
readonly container: HTMLElement;
|
|
42
|
+
readonly slot: HTMLElement;
|
|
43
|
+
private readonly stage;
|
|
44
|
+
private scale;
|
|
45
|
+
private tx;
|
|
46
|
+
private ty;
|
|
47
|
+
private readonly minScale;
|
|
48
|
+
private readonly maxScale;
|
|
49
|
+
private readonly wheelZoomSensitivity;
|
|
50
|
+
private readonly pinchZoomSensitivity;
|
|
51
|
+
private readonly onScaleChange;
|
|
52
|
+
private readonly onRenderTierChange;
|
|
53
|
+
private readonly onTransformChange;
|
|
54
|
+
private readonly onWheel;
|
|
55
|
+
/** Current layout-side zoom factor (integer ≥ 1). See ViewportOptions. */
|
|
56
|
+
private renderTier;
|
|
57
|
+
/** Suppresses `onTransformChange` during the constructor's initial
|
|
58
|
+
* `applyTransform` so consumers can capture `viewport` in their
|
|
59
|
+
* callback without TDZ traps. Flipped true at the end of the ctor. */
|
|
60
|
+
private constructed;
|
|
61
|
+
/** Timestamp of the last wheel event, used to delimit gestures. */
|
|
62
|
+
private gestureLastTime;
|
|
63
|
+
/** Dominant axis for the current gesture. Null until detected, cleared at gesture end. */
|
|
64
|
+
private gesturePrimaryAxis;
|
|
65
|
+
/**
|
|
66
|
+
* Signed cumulative dx within the current gesture. Drives lock release:
|
|
67
|
+
* wobble (±3-5px back-and-forth) cancels out; sustained one-way motion
|
|
68
|
+
* accumulates past the threshold quickly. Reset at gesture end.
|
|
69
|
+
*/
|
|
70
|
+
private gestureSignedDx;
|
|
71
|
+
/**
|
|
72
|
+
* Sticky horizontal-lock flag. Engaged by `fitTo` so alignment survives
|
|
73
|
+
* gentle diagonal trackpad gestures; broken when the gesture's signed
|
|
74
|
+
* cumulative dx crosses `X_RELEASE_THRESHOLD` — the user clearly intends
|
|
75
|
+
* sustained horizontal motion.
|
|
76
|
+
*/
|
|
77
|
+
private horizontalLock;
|
|
78
|
+
constructor(container: HTMLElement, options?: ViewportOptions);
|
|
79
|
+
/** Reset pan to origin and scale to 1. */
|
|
80
|
+
reset(): void;
|
|
81
|
+
getScale(): number;
|
|
82
|
+
/** Integer layout-side zoom currently applied via CSS `zoom` on the stage. */
|
|
83
|
+
getRenderTier(): number;
|
|
84
|
+
/**
|
|
85
|
+
* Fit `target` to the viewport.
|
|
86
|
+
* - `"width"`: scale so the target fills the viewport horizontally. The
|
|
87
|
+
* vertical centre of the current view is preserved (no jump to the top
|
|
88
|
+
* of the target).
|
|
89
|
+
* - `"contain"`: scale so the entire target is visible, centred in both
|
|
90
|
+
* axes.
|
|
91
|
+
* With `animate = true`, the transition runs with a CSS ease curve.
|
|
92
|
+
*/
|
|
93
|
+
fitTo(target: HTMLElement, mode: "width" | "contain", animate?: boolean): void;
|
|
94
|
+
/**
|
|
95
|
+
* Pan the stage by `(dx, dy)` CSS pixels. Optional `animate` runs the
|
|
96
|
+
* same cubic-ease transition fit-to-page uses; unflagged pans apply
|
|
97
|
+
* instantly.
|
|
98
|
+
*/
|
|
99
|
+
panBy(dx: number, dy: number, opts?: {
|
|
100
|
+
animate?: boolean;
|
|
101
|
+
}): void;
|
|
102
|
+
/** Zoom to `nextScale`, anchoring the point at (clientX, clientY) in container space. */
|
|
103
|
+
zoomTo(nextScale: number, clientX: number, clientY: number): void;
|
|
104
|
+
destroy(): void;
|
|
105
|
+
private handleWheel;
|
|
106
|
+
/**
|
|
107
|
+
* Axis-lock for pan gestures:
|
|
108
|
+
* - Within a gesture (events ≤ GESTURE_GAP_MS apart), a clear dominant
|
|
109
|
+
* axis zeros the other axis so a nearly-vertical swipe doesn't also
|
|
110
|
+
* drift the paper sideways.
|
|
111
|
+
* - An explicit `horizontalLock` set by `fitTo` survives across gestures,
|
|
112
|
+
* keeping fit-page / fit-width alignment stable.
|
|
113
|
+
* - Both locks release when the gesture's signed cumulative dx crosses
|
|
114
|
+
* `X_RELEASE_THRESHOLD`. Signed sum cancels wobble (back-and-forth
|
|
115
|
+
* averages to zero) while sustained one-way motion accumulates fast.
|
|
116
|
+
*/
|
|
117
|
+
private applyScrollAxisLock;
|
|
118
|
+
private applyTransform;
|
|
119
|
+
/**
|
|
120
|
+
* Apply the current transform with a CSS transition. Used only for
|
|
121
|
+
* programmatic fits — wheel pan/zoom must stay instant or feel sluggish.
|
|
122
|
+
*
|
|
123
|
+
* If the target scale falls into a different render tier, we DON'T flip
|
|
124
|
+
* `stage.style.zoom` mid-flight: that property can't transition, so the
|
|
125
|
+
* layout would snap instantly while the `transform` keeps easing — the
|
|
126
|
+
* visible "weird reset" before the animation. Instead, we keep the
|
|
127
|
+
* current tier through the transition, write the transform expressed in
|
|
128
|
+
* THAT tier's coordinate space (visually identical to the same transform
|
|
129
|
+
* in any other tier — tier is just a layout-quality choice), and snap to
|
|
130
|
+
* the target tier on `transitionend`.
|
|
131
|
+
*/
|
|
132
|
+
private applyTransformAnimated;
|
|
133
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { SobreeDocument } from '../doc/types';
|
|
2
|
+
export interface EmbedFontFaces {
|
|
3
|
+
regular?: Uint8Array;
|
|
4
|
+
bold?: Uint8Array;
|
|
5
|
+
italic?: Uint8Array;
|
|
6
|
+
boldItalic?: Uint8Array;
|
|
7
|
+
}
|
|
8
|
+
export interface EmbedFontOptions {
|
|
9
|
+
/** Embed even when OS/2 fsType marks the face as restricted. Default false. */
|
|
10
|
+
allowRestricted?: boolean;
|
|
11
|
+
}
|
|
12
|
+
export interface EmbedFontResult {
|
|
13
|
+
/** Next document — same reference as input when nothing was embedded. */
|
|
14
|
+
next: SobreeDocument;
|
|
15
|
+
/** Per-face refusal warnings (e.g. restricted licence). */
|
|
16
|
+
warnings: string[];
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Returns the next document with the given font embedded, plus any
|
|
20
|
+
* warnings (e.g. a face refused for licence reasons). When no face
|
|
21
|
+
* could be embedded, `next` is `===` the input doc — caller can
|
|
22
|
+
* skip a setDocument round.
|
|
23
|
+
*/
|
|
24
|
+
export declare function embedFontIntoDoc(doc: SobreeDocument, name: string, faces: EmbedFontFaces, opts?: EmbedFontOptions): EmbedFontResult;
|
|
25
|
+
/**
|
|
26
|
+
* Drop a font declaration by name. Returns the same doc reference if
|
|
27
|
+
* the name wasn't present (caller can skip a setDocument round).
|
|
28
|
+
*
|
|
29
|
+
* Font part bytes are NOT removed from `rawParts` — call
|
|
30
|
+
* `pruneOrphanParts(doc)` (or just rely on export-side filtering) to
|
|
31
|
+
* GC them.
|
|
32
|
+
*/
|
|
33
|
+
export declare function removeFontFromDoc(doc: SobreeDocument, name: string): SobreeDocument;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { ExportContext } from '../docx/export/context';
|
|
2
|
+
import { SobreeDocument } from '../doc/types';
|
|
3
|
+
interface FontTableEmission {
|
|
4
|
+
/** Inner XML of `word/fontTable.xml`. */
|
|
5
|
+
fontTableXml: string;
|
|
6
|
+
/** Inner XML of `word/_rels/fontTable.xml.rels`. */
|
|
7
|
+
fontTableRelsXml: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Stage every font-related artifact into the export context: the
|
|
11
|
+
* fontTable XML + companion rels, the document-level relationship,
|
|
12
|
+
* the content-type override, and the `.odttf` extension flag. Caller
|
|
13
|
+
* (docx/export/index.ts) just calls this once and forgets — no
|
|
14
|
+
* font-aware code needs to live in the export entry point any more.
|
|
15
|
+
*
|
|
16
|
+
* No-op when `doc.fonts` is empty.
|
|
17
|
+
*/
|
|
18
|
+
export declare function mountFontTableArtifacts(doc: SobreeDocument, ctx: ExportContext): void;
|
|
19
|
+
/**
|
|
20
|
+
* Render the font table and its companion .rels. Returns null if the
|
|
21
|
+
* document declares no fonts (caller skips emitting the parts).
|
|
22
|
+
*/
|
|
23
|
+
export declare function emitFontTable(doc: SobreeDocument): FontTableEmission | null;
|
|
24
|
+
export {};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { FontDeclaration } from './types';
|
|
2
|
+
export declare class FontFaceRegistry {
|
|
3
|
+
private readonly styleEl;
|
|
4
|
+
/** Mostly for cleanup — every blob URL we minted needs revoking. */
|
|
5
|
+
private blobUrls;
|
|
6
|
+
/** Last-applied snapshot — skip re-registration when nothing changed. */
|
|
7
|
+
private lastSerialised;
|
|
8
|
+
constructor();
|
|
9
|
+
/**
|
|
10
|
+
* Sync the registry to the current document's fonts. Idempotent —
|
|
11
|
+
* if the font list hasn't changed since the last call, no work
|
|
12
|
+
* happens (no blob revocation, no DOM churn).
|
|
13
|
+
*
|
|
14
|
+
* Bails out (no-op) when the runtime doesn't expose
|
|
15
|
+
* `URL.createObjectURL` — typically jsdom in tests, where the
|
|
16
|
+
* registry isn't observable anyway.
|
|
17
|
+
*/
|
|
18
|
+
sync(fonts: readonly FontDeclaration[], rawParts: Record<string, Uint8Array>): void;
|
|
19
|
+
destroy(): void;
|
|
20
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Read the OS/2 table's `fsType` field from a TrueType / OpenType font.
|
|
3
|
+
* The field encodes the font foundry's embedding licence — applications
|
|
4
|
+
* that embed must check it. See OpenType spec, OS/2 table § "fsType":
|
|
5
|
+
* https://learn.microsoft.com/en-us/typography/opentype/spec/os2#fst
|
|
6
|
+
*
|
|
7
|
+
* Bits (mask with 0x000F for the licence triplet — they're mutually
|
|
8
|
+
* exclusive in practice):
|
|
9
|
+
* 0x0000 Installable embedding allowed. ← happy path.
|
|
10
|
+
* 0x0002 Restricted licence — must NOT be embedded.
|
|
11
|
+
* 0x0004 Preview & Print — embed for view/print only, no editing.
|
|
12
|
+
* 0x0008 Editable — embed and allow modifications.
|
|
13
|
+
* 0x0100 No subsetting — must embed the full face.
|
|
14
|
+
* 0x0200 Bitmap embedding only.
|
|
15
|
+
*
|
|
16
|
+
* `readFsType` returns `null` on parse failure (corrupt header, missing
|
|
17
|
+
* OS/2 table, truncated input). Callers treat `null` as "unknown
|
|
18
|
+
* licence — don't embed unless explicitly forced."
|
|
19
|
+
*/
|
|
20
|
+
export type EmbedMode = "installable" | "preview" | "editable" | "restricted";
|
|
21
|
+
export interface FsTypeReport {
|
|
22
|
+
allowed: boolean;
|
|
23
|
+
mode: EmbedMode;
|
|
24
|
+
noSubset: boolean;
|
|
25
|
+
bitmapOnly: boolean;
|
|
26
|
+
/** Raw fsType field, for callers that want the bits. */
|
|
27
|
+
raw: number;
|
|
28
|
+
}
|
|
29
|
+
/** Walk the table directory and return `OS/2.fsType`, or null on failure. */
|
|
30
|
+
export declare function readFsType(font: Uint8Array): number | null;
|
|
31
|
+
/**
|
|
32
|
+
* Interpret an `fsType` value into a structured embedding decision.
|
|
33
|
+
* Defensive on `null` input (corrupt font) — reports as restricted so
|
|
34
|
+
* callers fail closed.
|
|
35
|
+
*/
|
|
36
|
+
export declare function canEmbed(fsType: number | null): FsTypeReport;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@sobree/core/fonts` — internal module aggregating everything
|
|
3
|
+
* font-related: AST shape, OOXML import + export, ODTTF codec,
|
|
4
|
+
* licensing check, in-memory `@font-face` registration.
|
|
5
|
+
*
|
|
6
|
+
* Consumers import from this `index.ts`, never reach into individual
|
|
7
|
+
* files. The module is internal to `@sobree/core`; the public surface
|
|
8
|
+
* is re-exported through `packages/core/src/index.ts`.
|
|
9
|
+
*/
|
|
10
|
+
export type { FontDeclaration, FontEmbedRef } from './types';
|
|
11
|
+
export { deobfuscate, generateFontKey, isUnobfuscated, obfuscate, } from './odttf';
|
|
12
|
+
export { canEmbed, readFsType } from './fsType';
|
|
13
|
+
export type { EmbedMode, FsTypeReport } from './fsType';
|
|
14
|
+
export { mountFontTableFromZip, parseFontTable } from './parse';
|
|
15
|
+
export { emitFontTable, mountFontTableArtifacts } from './emit';
|
|
16
|
+
export { embedFontIntoDoc, removeFontFromDoc, } from './embedAPI';
|
|
17
|
+
export type { EmbedFontFaces, EmbedFontOptions, EmbedFontResult, } from './embedAPI';
|
|
18
|
+
export { fontLivenessPaths } from './liveness';
|
|
19
|
+
export { FontFaceRegistry } from './fontFaceRegistry';
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ODTTF (Obfuscated TrueType Font) codec for OOXML font embedding.
|
|
3
|
+
*
|
|
4
|
+
* Per ECMA-376 Part 4 §2.8.1: Word obfuscates embedded font binaries
|
|
5
|
+
* by XORing the first 32 bytes with a 16-byte key derived from a GUID
|
|
6
|
+
* (the `w:fontKey` attribute on `<w:embedRegular/>` / etc.). The key
|
|
7
|
+
* is the GUID's 16 bytes in **reverse** order. The first 16 bytes of
|
|
8
|
+
* the font are XOR'd with the key, then the next 16 bytes are XOR'd
|
|
9
|
+
* with the same key. Bytes 32..end pass through unchanged.
|
|
10
|
+
*
|
|
11
|
+
* Symmetry — the operation is its own inverse (XOR is involutive), so
|
|
12
|
+
* `obfuscate(deobfuscate(x, k), k) === x`.
|
|
13
|
+
*
|
|
14
|
+
* A `fontKey` of all-zeros means "no obfuscation" and the bytes are
|
|
15
|
+
* already a raw TTF/OTF.
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* XOR-deobfuscate or -obfuscate the first 32 bytes of `bytes` with the
|
|
19
|
+
* key derived from `fontKey`. Returns a fresh `Uint8Array` — the input
|
|
20
|
+
* is not mutated.
|
|
21
|
+
*/
|
|
22
|
+
export declare function deobfuscate(bytes: Uint8Array, fontKey: string): Uint8Array;
|
|
23
|
+
/** Symmetric inverse — same operation as `deobfuscate`, named for clarity at call sites. */
|
|
24
|
+
export declare function obfuscate(bytes: Uint8Array, fontKey: string): Uint8Array;
|
|
25
|
+
/**
|
|
26
|
+
* Generate a fresh GUID in the canonical `{XX-...}` form Word uses for
|
|
27
|
+
* `w:fontKey`. Random bytes via `crypto.getRandomValues`; falls back to
|
|
28
|
+
* `Math.random()` if `crypto` isn't present (jsdom often is, Node 19+
|
|
29
|
+
* is too — fallback only matters for ancient runtimes).
|
|
30
|
+
*/
|
|
31
|
+
export declare function generateFontKey(): string;
|
|
32
|
+
/** True when `fontKey` is the sentinel "no obfuscation" GUID. */
|
|
33
|
+
export declare function isUnobfuscated(fontKey: string | undefined): boolean;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { FontDeclaration } from './types';
|
|
2
|
+
interface Loaded {
|
|
3
|
+
declarations: FontDeclaration[];
|
|
4
|
+
/** ZIP paths of embedded font parts that should be kept in rawParts. */
|
|
5
|
+
embeddedPartPaths: Set<string>;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Convenience for the import pipeline: pull `word/fontTable.xml` +
|
|
9
|
+
* `word/_rels/fontTable.xml.rels` out of the unzipped text-parts map
|
|
10
|
+
* and return the parsed declarations. Falls back to an empty array
|
|
11
|
+
* when the document carries no font table — most don't.
|
|
12
|
+
*
|
|
13
|
+
* `parseRels` is the same `parseRels` helper the document uses; passed
|
|
14
|
+
* in to avoid a cycle through `docx/import`.
|
|
15
|
+
*/
|
|
16
|
+
export declare function mountFontTableFromZip(textParts: Record<string, string>, parseRels: (xml: string) => Map<string, string>): FontDeclaration[];
|
|
17
|
+
/**
|
|
18
|
+
* Returns parsed declarations + the set of font-part ZIP paths the
|
|
19
|
+
* unzipped binary map should retain. `fontTableRels` resolves `r:id`
|
|
20
|
+
* references inside `<w:embed*>` elements to their target paths.
|
|
21
|
+
*/
|
|
22
|
+
export declare function parseFontTable(fontTableXml: string, fontTableRels: Map<string, string>): Loaded;
|
|
23
|
+
/**
|
|
24
|
+
* Convenience: parse direct-child `<w:font>` elements, in case some
|
|
25
|
+
* producers use children rather than descendants. Reserved for future
|
|
26
|
+
* "strict mode" callers.
|
|
27
|
+
*/
|
|
28
|
+
export declare function readChildFonts(parent: Element): Element[];
|
|
29
|
+
export {};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Font-table type definitions, lifted out of `doc/types.ts` so the
|
|
3
|
+
* fonts module owns its own AST shapes. Re-exported from
|
|
4
|
+
* `doc/types.ts` for backwards compat — existing consumers keep
|
|
5
|
+
* working unchanged.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* One entry in the document's font table — mirrors `<w:font>` in
|
|
9
|
+
* OOXML. Most fields are substitution hints used when the named font
|
|
10
|
+
* isn't installed on the reader's machine; `embed` carries pointers
|
|
11
|
+
* to actual font bytes stored under `rawParts`.
|
|
12
|
+
*/
|
|
13
|
+
export interface FontDeclaration {
|
|
14
|
+
/** `<w:font w:name="...">` — the font family this entry describes. */
|
|
15
|
+
name: string;
|
|
16
|
+
altName?: string;
|
|
17
|
+
/** 10-byte PANOSE classification, hex-encoded. */
|
|
18
|
+
panose?: string;
|
|
19
|
+
/** Character set, hex (default "00"). */
|
|
20
|
+
charset?: string;
|
|
21
|
+
family?: "auto" | "decorative" | "modern" | "roman" | "script" | "swiss";
|
|
22
|
+
pitch?: "default" | "fixed" | "variable";
|
|
23
|
+
/** Unicode/codepage subset bitmasks — mirrors `<w:sig>`. */
|
|
24
|
+
sig?: {
|
|
25
|
+
usb0: string;
|
|
26
|
+
usb1: string;
|
|
27
|
+
usb2: string;
|
|
28
|
+
usb3: string;
|
|
29
|
+
csb0: string;
|
|
30
|
+
csb1: string;
|
|
31
|
+
};
|
|
32
|
+
notTrueType?: boolean;
|
|
33
|
+
/** Embedded faces. Optional — most declarations are just name + panose. */
|
|
34
|
+
embed?: {
|
|
35
|
+
regular?: FontEmbedRef;
|
|
36
|
+
bold?: FontEmbedRef;
|
|
37
|
+
italic?: FontEmbedRef;
|
|
38
|
+
boldItalic?: FontEmbedRef;
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
export interface FontEmbedRef {
|
|
42
|
+
/** ZIP path of the font bytes (key into `SobreeDocument.rawParts`). */
|
|
43
|
+
partPath: string;
|
|
44
|
+
/**
|
|
45
|
+
* GUID used for ODTTF XOR-obfuscation of the first 32 bytes. Absent
|
|
46
|
+
* means the part is a raw TTF/OTF (no obfuscation). When writing
|
|
47
|
+
* `.docx`, a fresh GUID is generated per embed.
|
|
48
|
+
*/
|
|
49
|
+
fontKey?: string;
|
|
50
|
+
/** Round-trip flag — true if the on-disk file is already a subset. */
|
|
51
|
+
subsetted?: boolean;
|
|
52
|
+
}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { BlobCache, BlobStore } from './blob';
|
|
2
|
+
import { BlockRef, EditError, EditResult, Selection } from './doc/api';
|
|
3
|
+
import { ParagraphPropertiesPatch, BlockInfo, CommandBus, OutlineItem } from './editor';
|
|
4
|
+
import { Block, ParagraphAlignment, ParagraphProperties, SobreeDocument } from './doc/types';
|
|
5
|
+
import { History } from './history';
|
|
6
|
+
/**
|
|
7
|
+
* HeadlessSobree — a no-DOM Sobree peer for LLM agents, automation,
|
|
8
|
+
* back-end pipelines, MCP servers, anywhere code needs to read or
|
|
9
|
+
* write a Sobree document without rendering it.
|
|
10
|
+
*
|
|
11
|
+
* # The shape
|
|
12
|
+
*
|
|
13
|
+
* Same mental model as the browser editor: hold a `Y.Doc`, read it
|
|
14
|
+
* as a `SobreeDocument` projection, write through typed mutation
|
|
15
|
+
* methods, get a `change` event on every update (local or remote).
|
|
16
|
+
* The difference: no DOM, no rendering, no selection-from-DOM logic.
|
|
17
|
+
* Selection is just a value field you can read / write.
|
|
18
|
+
*
|
|
19
|
+
* # Use cases
|
|
20
|
+
*
|
|
21
|
+
* 1. **LLM agents.** Connect a Y-websocket provider to a Sobree
|
|
22
|
+
* room; the LLM sees the same doc the user sees. It can read
|
|
23
|
+
* structure (paragraphs, headings, runs) and apply edits that
|
|
24
|
+
* propagate back through Y.
|
|
25
|
+
*
|
|
26
|
+
* 2. **Server-side rendering / export.** Run `editor.toDocx()` in
|
|
27
|
+
* a Node worker against a snapshot loaded from `@sobree/collab-server`'s
|
|
28
|
+
* persistence backend.
|
|
29
|
+
*
|
|
30
|
+
* 3. **Automation pipelines.** Cron job that processes inbound
|
|
31
|
+
* content and writes formatted reports to a Sobree doc.
|
|
32
|
+
*
|
|
33
|
+
* 4. **Tests.** Build a fixture document programmatically without
|
|
34
|
+
* a DOM environment.
|
|
35
|
+
*
|
|
36
|
+
* # What it's NOT
|
|
37
|
+
*
|
|
38
|
+
* - A *relay*. That's `@sobree/collab-server` — a Node server that
|
|
39
|
+
* fans out Y messages between many peers. HeadlessSobree is a
|
|
40
|
+
* single peer with its own Y.Doc.
|
|
41
|
+
* - A *full editor*. The browser `Editor` adds DOM rendering,
|
|
42
|
+
* contentEditable event handling, image-resize handles, paste
|
|
43
|
+
* parsing, etc. HeadlessSobree skips all that — if you need
|
|
44
|
+
* them, mount a real Editor.
|
|
45
|
+
* - A *table editor*. The browser `Editor` has a rich table API
|
|
46
|
+
* (`editor.table.insertRow`, etc.). HeadlessSobree v0 doesn't
|
|
47
|
+
* wrap that — operate on `Table` blocks directly via
|
|
48
|
+
* `replaceBlock` until Phase 4.x adds a parallel table API.
|
|
49
|
+
*
|
|
50
|
+
* # Origin tagging
|
|
51
|
+
*
|
|
52
|
+
* Every mutation writes to the Y.Doc with a configurable origin
|
|
53
|
+
* (default `"headless"`). The local `Y.UndoManager` tracks only that
|
|
54
|
+
* origin — so the peer's `Cmd+Z`-equivalent (`peer.history.undo()`)
|
|
55
|
+
* reverses only its own edits, not the human peers'. Pick a stable
|
|
56
|
+
* per-peer origin string (e.g. `"agent:gpt-4-2024-05"`) if you want
|
|
57
|
+
* post-hoc telemetry to identify the author.
|
|
58
|
+
*/
|
|
59
|
+
import * as Y from "yjs";
|
|
60
|
+
export interface HeadlessSobreeOptions {
|
|
61
|
+
/**
|
|
62
|
+
* Origin string used for this peer's Y.Doc mutations. Identifies
|
|
63
|
+
* the source in `afterTransaction` events and scopes the
|
|
64
|
+
* Y.UndoManager. Default `"headless"`.
|
|
65
|
+
*/
|
|
66
|
+
origin?: string;
|
|
67
|
+
/**
|
|
68
|
+
* Initial document. Used only if the Y.Doc is empty at construction
|
|
69
|
+
* time — same semantics as `Editor.initialDocument`. If the Y.Doc
|
|
70
|
+
* is non-empty (a peer joining an active room), this is ignored
|
|
71
|
+
* and the existing state is adopted.
|
|
72
|
+
*/
|
|
73
|
+
initialDocument?: SobreeDocument;
|
|
74
|
+
/**
|
|
75
|
+
* Override the BlockRegistry's id prefix. Default is
|
|
76
|
+
* `${ydoc.clientID.toString(36)}_` — same convention the browser
|
|
77
|
+
* `Editor` uses, so newly-minted block ids never collide across
|
|
78
|
+
* peers.
|
|
79
|
+
*/
|
|
80
|
+
idPrefix?: string;
|
|
81
|
+
/**
|
|
82
|
+
* Optional content-hashed `BlobStore` (Phase 3.2+). Without one,
|
|
83
|
+
* binary parts ride inline in the Y.Doc; with one, the headless
|
|
84
|
+
* peer resolves `partRefs` hashes via a local `BlobCache` and
|
|
85
|
+
* fetches missing bytes from the store on demand. See
|
|
86
|
+
* `EditorOptions.blobStore` for the full contract.
|
|
87
|
+
*/
|
|
88
|
+
blobStore?: BlobStore;
|
|
89
|
+
}
|
|
90
|
+
export type HeadlessEvent = "change";
|
|
91
|
+
export interface HeadlessChangePayload {
|
|
92
|
+
doc: SobreeDocument;
|
|
93
|
+
/** Whether the change originated from THIS peer's mutations
|
|
94
|
+
* (true) or arrived via a Y provider from a remote peer (false). */
|
|
95
|
+
local: boolean;
|
|
96
|
+
}
|
|
97
|
+
export type HeadlessUnsubscribe = () => void;
|
|
98
|
+
/**
|
|
99
|
+
* Headless Sobree peer. Construct with a `Y.Doc` — typically one
|
|
100
|
+
* you've already attached a provider to. Reads project through the
|
|
101
|
+
* Y.Doc; writes mirror back inside `Y.Doc.transact` with the
|
|
102
|
+
* configured origin.
|
|
103
|
+
*/
|
|
104
|
+
export declare class HeadlessSobree {
|
|
105
|
+
readonly ydoc: Y.Doc;
|
|
106
|
+
readonly commands: CommandBus;
|
|
107
|
+
readonly history: History;
|
|
108
|
+
readonly origin: string;
|
|
109
|
+
/** Optional content-hashed blob layer. Mirrors the browser `Editor`'s
|
|
110
|
+
* `blobStore` field — null when no store is configured. */
|
|
111
|
+
readonly blobStore: BlobStore | null;
|
|
112
|
+
/** Local cache for blob bytes. Null when no `blobStore` is set. */
|
|
113
|
+
readonly blobCache: BlobCache | null;
|
|
114
|
+
private doc;
|
|
115
|
+
private readonly registry;
|
|
116
|
+
private currentSelection;
|
|
117
|
+
private readonly listeners;
|
|
118
|
+
private lastPartRefs;
|
|
119
|
+
private ydocUpdateListener;
|
|
120
|
+
constructor(ydoc: Y.Doc, opts?: HeadlessSobreeOptions);
|
|
121
|
+
/** Current document — a fresh projection of the Y.Doc state. */
|
|
122
|
+
getDocument(): SobreeDocument;
|
|
123
|
+
/** Summary of every top-level block. */
|
|
124
|
+
getBlocks(): BlockInfo[];
|
|
125
|
+
getBlock(index: number): BlockInfo;
|
|
126
|
+
getBlockById(id: string): BlockInfo | null;
|
|
127
|
+
/** Heading outline — one entry per `paragraph` block whose
|
|
128
|
+
* resolved style identifies it as a heading. */
|
|
129
|
+
getOutline(): OutlineItem[];
|
|
130
|
+
/** This peer's stored selection — same shape `editor.selection.get()`
|
|
131
|
+
* returns. `null` when no selection is set. */
|
|
132
|
+
getSelection(): Selection;
|
|
133
|
+
/**
|
|
134
|
+
* Set this peer's selection. Stored as a value (no DOM update);
|
|
135
|
+
* the value is what `history` captures on each mutation and
|
|
136
|
+
* restores on undo.
|
|
137
|
+
*/
|
|
138
|
+
setSelection(selection: Selection): void;
|
|
139
|
+
/** Replace the document. */
|
|
140
|
+
setDocument(doc: SobreeDocument): void;
|
|
141
|
+
/** Replace the block at `target`'s index with `block`. */
|
|
142
|
+
replaceBlock(target: BlockRef, block: Block): EditResult<BlockRef>;
|
|
143
|
+
/** Insert `block` before the target block. */
|
|
144
|
+
insertBlockBefore(target: BlockRef, block: Block): EditResult<BlockRef>;
|
|
145
|
+
/** Insert `block` after the target block. */
|
|
146
|
+
insertBlockAfter(target: BlockRef, block: Block): EditResult<BlockRef>;
|
|
147
|
+
/** Delete the target block. */
|
|
148
|
+
deleteBlock(target: BlockRef): EditResult<void>;
|
|
149
|
+
/** Merge a patch into each target paragraph's properties. */
|
|
150
|
+
applyBlockProperties(targets: BlockRef[], patch: ParagraphPropertiesPatch): EditResult<void>;
|
|
151
|
+
on<E extends HeadlessEvent>(event: E, cb: (payload: HeadlessChangePayload) => void): HeadlessUnsubscribe;
|
|
152
|
+
destroy(): void;
|
|
153
|
+
private allBlockIds;
|
|
154
|
+
private mirror;
|
|
155
|
+
private adoptYDocState;
|
|
156
|
+
private resolveCachedPartRefsInto;
|
|
157
|
+
private onBlobResolved;
|
|
158
|
+
/**
|
|
159
|
+
* Wait for every currently-referenced binary part to be available
|
|
160
|
+
* in the local cache. No-op when no `blobStore` is configured.
|
|
161
|
+
*/
|
|
162
|
+
ensurePartsLoaded(): Promise<void>;
|
|
163
|
+
private checkRefs;
|
|
164
|
+
private commit;
|
|
165
|
+
private fireChange;
|
|
166
|
+
private summariseBlock;
|
|
167
|
+
}
|
|
168
|
+
export type { Block, BlockInfo, BlockRef, EditError, EditResult, ParagraphAlignment, ParagraphProperties, Selection, SobreeDocument, };
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { Selection, Selection as PublicSelection } from '../doc/api';
|
|
2
|
+
import { HistoryConfig, HistoryDepth } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Undo / redo for the Sobree editor — backed by `Y.UndoManager`.
|
|
5
|
+
*
|
|
6
|
+
* # Why Y.UndoManager
|
|
7
|
+
*
|
|
8
|
+
* Phase 1b.6 swaps the snapshot-stack History for `Y.UndoManager` so:
|
|
9
|
+
*
|
|
10
|
+
* 1. **Per-peer undo.** UndoManager tracks operations by *origin*.
|
|
11
|
+
* When a peer types, those Y operations are tagged `"local"`. A
|
|
12
|
+
* remote peer's edits arrive with a different origin (the
|
|
13
|
+
* provider name), so the local UndoManager doesn't see them as
|
|
14
|
+
* its own. `Cmd+Z` reverses only the local user's edits — exactly
|
|
15
|
+
* what users expect in collab.
|
|
16
|
+
*
|
|
17
|
+
* 2. **CRDT-native.** Undoing produces *inverse Y operations*, which
|
|
18
|
+
* flow through the same broadcast pipeline as forward edits. No
|
|
19
|
+
* separate "undo over the wire" protocol needed.
|
|
20
|
+
*
|
|
21
|
+
* 3. **No snapshot stack.** Memory is bounded by Yjs's internal item
|
|
22
|
+
* list; no separate snapshot bookkeeping.
|
|
23
|
+
*
|
|
24
|
+
* # API compatibility
|
|
25
|
+
*
|
|
26
|
+
* The public surface (`undo`, `redo`, `canUndo`, `canRedo`, `clear`,
|
|
27
|
+
* `depth`, `on`) matches the old History so the Editor's command-bus
|
|
28
|
+
* registrations and the keyboard plugin's `Cmd+Z` mapping work
|
|
29
|
+
* unchanged. The legacy `recordCommit` / `recordTyping` / `flush`
|
|
30
|
+
* methods are kept as no-ops — UndoManager auto-tracks ops by origin
|
|
31
|
+
* and `captureTimeout` handles coalescing without explicit "begin a
|
|
32
|
+
* typing session" calls.
|
|
33
|
+
*
|
|
34
|
+
* # Selection restore
|
|
35
|
+
*
|
|
36
|
+
* Each undo/redo step needs to restore the cursor to its pre-edit
|
|
37
|
+
* position. We capture the live selection in `stack-item-added`'s
|
|
38
|
+
* `meta` and restore it on `stack-item-popped`. The restore happens
|
|
39
|
+
* AFTER the editor has re-projected and re-rendered (the Y observer
|
|
40
|
+
* fires before the popped event — see `Editor.adoptYDocState`).
|
|
41
|
+
*/
|
|
42
|
+
import * as Y from "yjs";
|
|
43
|
+
export type HistoryEvent = "change";
|
|
44
|
+
export type HistoryListener = (depth: HistoryDepth) => void;
|
|
45
|
+
export interface HistoryOptions extends Partial<HistoryConfig> {
|
|
46
|
+
/** Y.Doc to track. The UndoManager observes the body, meta, and
|
|
47
|
+
* parts top-level types — every Sobree mutation funnels through
|
|
48
|
+
* one of these, so any local edit produces a stack entry. */
|
|
49
|
+
ydoc: Y.Doc;
|
|
50
|
+
/** Origin string used by the Editor's `mirrorToYDoc()` and other
|
|
51
|
+
* local writes. UndoManager only tracks operations whose origin
|
|
52
|
+
* is in this set. Defaults to `"local"`. */
|
|
53
|
+
localOrigin?: unknown;
|
|
54
|
+
/** Capture the *current* live selection — called as a stack item
|
|
55
|
+
* is being added so we can stash it for restore on undo. */
|
|
56
|
+
captureSelection: () => Selection;
|
|
57
|
+
/** Restore a previously-captured selection to the live DOM /
|
|
58
|
+
* EditorSelection. Called on undo / redo after the Y.Doc has been
|
|
59
|
+
* re-projected and re-rendered. */
|
|
60
|
+
restoreSelection: (sel: Selection) => void;
|
|
61
|
+
}
|
|
62
|
+
export declare class History {
|
|
63
|
+
private readonly mgr;
|
|
64
|
+
private readonly listeners;
|
|
65
|
+
private readonly captureSelection;
|
|
66
|
+
private readonly restoreSelection;
|
|
67
|
+
constructor(opts: HistoryOptions);
|
|
68
|
+
undo(): boolean;
|
|
69
|
+
redo(): boolean;
|
|
70
|
+
canUndo(): boolean;
|
|
71
|
+
canRedo(): boolean;
|
|
72
|
+
clear(): void;
|
|
73
|
+
depth(): HistoryDepth;
|
|
74
|
+
on(_event: HistoryEvent, cb: HistoryListener): () => void;
|
|
75
|
+
destroy(): void;
|
|
76
|
+
/** @deprecated UndoManager auto-tracks ops by origin; no need to
|
|
77
|
+
* call this. Kept as a no-op so the Editor's existing call sites
|
|
78
|
+
* don't break. */
|
|
79
|
+
recordCommit(): void;
|
|
80
|
+
/** @deprecated UndoManager's `captureTimeout` coalesces consecutive
|
|
81
|
+
* ops into one stack item. No explicit recording needed. */
|
|
82
|
+
recordTyping(): void;
|
|
83
|
+
/** @deprecated UndoManager flushes implicitly on `captureTimeout`
|
|
84
|
+
* expiry or on the next non-tracked operation. */
|
|
85
|
+
flush(): void;
|
|
86
|
+
private fire;
|
|
87
|
+
}
|
|
88
|
+
/** @deprecated Selection survives undo/redo via stable block ids now;
|
|
89
|
+
* no snapshot-conversion is needed. Kept as a pass-through stub. */
|
|
90
|
+
export declare function makeEntry(doc: unknown, selection: PublicSelection, reason: string, _indexOfBlock: (id: string) => number): {
|
|
91
|
+
doc: unknown;
|
|
92
|
+
selection: PublicSelection;
|
|
93
|
+
reason: string;
|
|
94
|
+
timestamp: number;
|
|
95
|
+
};
|
|
96
|
+
/** @deprecated Pass-through; selection structure is no longer
|
|
97
|
+
* index-keyed in the new history. */
|
|
98
|
+
export declare function selectionToSnapshot(selection: PublicSelection, _indexOfBlock: (id: string) => number): PublicSelection;
|
|
99
|
+
/** @deprecated Pass-through; selection survives via stable ids. */
|
|
100
|
+
export declare function snapshotToSelection(snap: PublicSelection, _refAt: (idx: number) => unknown): PublicSelection;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { History, makeEntry, selectionToSnapshot, snapshotToSelection, } from './history';
|
|
2
|
+
export type { HistoryEvent, HistoryListener, HistoryOptions, } from './history';
|
|
3
|
+
export type { HistoryConfig, HistoryDepth, HistoryEntry, SnapshotPosition, SnapshotSelection, } from './types';
|
|
4
|
+
export { DEFAULT_HISTORY_CONFIG } from './types';
|