@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
package/dist/sobree.d.ts
ADDED
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import { PageSetup } from './paperStack/pageSetup';
|
|
2
|
+
import { Editor, OutlineItem, TrackChangesState } from './editor';
|
|
3
|
+
import { SobreeDocument } from './doc/types';
|
|
4
|
+
export type SobreeMode = "edit" | "read";
|
|
5
|
+
export type SobreeEvent = "change" | "paginate" | "setup" | "mode-change" | "track-changes-change" | "docx:import" | "docx:export";
|
|
6
|
+
export interface SobreeEventPayload {
|
|
7
|
+
change: {
|
|
8
|
+
doc: SobreeDocument;
|
|
9
|
+
/** @deprecated Use `doc`. Alias kept for backwards compatibility. */
|
|
10
|
+
document: SobreeDocument;
|
|
11
|
+
revision: number;
|
|
12
|
+
};
|
|
13
|
+
paginate: {
|
|
14
|
+
pageCount: number;
|
|
15
|
+
};
|
|
16
|
+
setup: {
|
|
17
|
+
setup: PageSetup;
|
|
18
|
+
};
|
|
19
|
+
"mode-change": {
|
|
20
|
+
mode: SobreeMode;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Fires when track-changes mode flips on/off or the author changes.
|
|
24
|
+
* Re-emitted from the underlying editor — `Sobree.setTrackChanges`
|
|
25
|
+
* delegates to `editor.setTrackChanges`, so listeners on either
|
|
26
|
+
* surface see the same events.
|
|
27
|
+
*/
|
|
28
|
+
"track-changes-change": TrackChangesState;
|
|
29
|
+
"docx:import": {
|
|
30
|
+
warnings: string[];
|
|
31
|
+
};
|
|
32
|
+
"docx:export": {
|
|
33
|
+
warnings: string[];
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
export type SobreeUnsubscribe = () => void;
|
|
37
|
+
export interface SobreeOptions {
|
|
38
|
+
/** Initial document AST. */
|
|
39
|
+
initialDocument?: SobreeDocument;
|
|
40
|
+
/** Page setup. Falls back to `DEFAULT_PAGE_SETUP`. */
|
|
41
|
+
pageSetup?: PageSetup;
|
|
42
|
+
/** Forwarded to the underlying Editor. */
|
|
43
|
+
changeDebounceMs?: number;
|
|
44
|
+
/**
|
|
45
|
+
* Y.Doc backing the document. Forwarded to the Editor — see
|
|
46
|
+
* `EditorOptions.ydoc` for the contract. Use this when you want to
|
|
47
|
+
* attach a provider (`y-websocket`, `y-indexeddb`, `y-webrtc`) for
|
|
48
|
+
* persistence or collaboration. If absent, the editor creates one
|
|
49
|
+
* internally (still observable via `sobree.editor.ydoc`).
|
|
50
|
+
*/
|
|
51
|
+
ydoc?: import('yjs').Doc;
|
|
52
|
+
/**
|
|
53
|
+
* Optional content-hashed `BlobStore` for binary parts. Forwarded
|
|
54
|
+
* to the Editor — see `EditorOptions.blobStore`.
|
|
55
|
+
*/
|
|
56
|
+
blobStore?: import('./blob').BlobStore;
|
|
57
|
+
/**
|
|
58
|
+
* Initial track-changes mode. Forwarded to the editor — see
|
|
59
|
+
* `TrackChangesState`. When omitted, the editor starts in
|
|
60
|
+
* direct-edit mode and embedders flip it later with
|
|
61
|
+
* `sobree.setTrackChanges(...)`.
|
|
62
|
+
*/
|
|
63
|
+
trackChanges?: TrackChangesState;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Top-level embeddable product surface. Composes a framework-free `Editor`
|
|
67
|
+
* with a paginated `PaperStack`, exposing a single wire-ready API for
|
|
68
|
+
* hosting webapps, headless Y peers (HeadlessSobree), and agents.
|
|
69
|
+
*
|
|
70
|
+
* Everything on this class is JSON-clean: plain data in, plain data out.
|
|
71
|
+
* No DOM nodes, Ranges, or function handles cross the public surface.
|
|
72
|
+
*/
|
|
73
|
+
export declare class Sobree {
|
|
74
|
+
readonly editor: Editor;
|
|
75
|
+
private readonly stack;
|
|
76
|
+
private setup;
|
|
77
|
+
private mode;
|
|
78
|
+
private readonly listeners;
|
|
79
|
+
private readonly detachPaginate;
|
|
80
|
+
private readonly detachChange;
|
|
81
|
+
private readonly detachTrackChanges;
|
|
82
|
+
/** Detachers for default + user-provided plugins, run in reverse on
|
|
83
|
+
* `destroy` so attach order is mirrored on teardown. */
|
|
84
|
+
private readonly pluginDetachers;
|
|
85
|
+
constructor(container: HTMLElement, options?: SobreeOptions);
|
|
86
|
+
/** Internal stack element — useful for attaching context tools / viewport. */
|
|
87
|
+
get stackRoot(): HTMLElement;
|
|
88
|
+
/** First paper element — useful as a viewport fit target on first layout. */
|
|
89
|
+
get firstPaper(): HTMLElement;
|
|
90
|
+
/**
|
|
91
|
+
* First paper's outer ROW (paper card + per-page comments sidebar).
|
|
92
|
+
* Use as `fitWidthTarget` so the viewport's fit-to-width scales to
|
|
93
|
+
* include the sidebar — fitting just `.paper` would leave the
|
|
94
|
+
* sidebar clipped by the viewport's overflow.
|
|
95
|
+
*/
|
|
96
|
+
get firstPaperRow(): HTMLElement;
|
|
97
|
+
/** Pass through for Viewport's renderTier callback. */
|
|
98
|
+
setRenderTier(tier: number): void;
|
|
99
|
+
/** Current page setup for section 0 (JSON-clean). */
|
|
100
|
+
getPageSetup(): PageSetup;
|
|
101
|
+
/** Number of sections in the current document. Always >= 1. */
|
|
102
|
+
getSectionCount(): number;
|
|
103
|
+
/**
|
|
104
|
+
* Read section `index` projected onto the demo's `PageSetup` shape so
|
|
105
|
+
* the same Page Setup modal can edit any section. Section 0 returns
|
|
106
|
+
* the live `setup`; other sections are projected from the AST.
|
|
107
|
+
*
|
|
108
|
+
* Lossy for properties the bridge doesn't carry (e.g. per-section
|
|
109
|
+
* pages-per-column will surface here as default), but enough for the
|
|
110
|
+
* fields the modal exposes today.
|
|
111
|
+
*/
|
|
112
|
+
getSectionSetup(index: number): PageSetup;
|
|
113
|
+
/**
|
|
114
|
+
* Write back to section `index`. Section 0 funnels through
|
|
115
|
+
* `setPageSetup` (the canonical path); section 1+ goes through the
|
|
116
|
+
* editor's `setDocument` so it round-trips and triggers the change
|
|
117
|
+
* pipeline (repagination, listeners).
|
|
118
|
+
*/
|
|
119
|
+
setSectionSetup(index: number, partial: Partial<PageSetup>): void;
|
|
120
|
+
/**
|
|
121
|
+
* Merge `partial` into the current page setup. Triggers repagination and
|
|
122
|
+
* fires `setup` event. Plain-data argument — safe over the wire.
|
|
123
|
+
*/
|
|
124
|
+
setPageSetup(partial: Partial<PageSetup>): void;
|
|
125
|
+
/** Project the current `setup` into `doc.sections[0]` and commit. */
|
|
126
|
+
private writeSetupToSection0;
|
|
127
|
+
/** Current rendered page count. */
|
|
128
|
+
getPageCount(): number;
|
|
129
|
+
/**
|
|
130
|
+
* Force a repagination. Normally unnecessary — repagination runs after
|
|
131
|
+
* every `change` event. Useful for hosts that need to ensure pagination
|
|
132
|
+
* after initial mount (layout must be applied first — call from a
|
|
133
|
+
* `requestAnimationFrame` after the container is in the DOM).
|
|
134
|
+
*/
|
|
135
|
+
repaginate(): void;
|
|
136
|
+
/** Delegate to `editor.getOutline()`. */
|
|
137
|
+
getOutline(): OutlineItem[];
|
|
138
|
+
/** Current mode. Default is `"edit"`. */
|
|
139
|
+
getMode(): SobreeMode;
|
|
140
|
+
/**
|
|
141
|
+
* Switch between edit and read mode. Read mode turns off
|
|
142
|
+
* `contenteditable`, tags the stack root with `is-read-mode` (so the
|
|
143
|
+
* embedder / block tools can hide indicators and toolbars via CSS or
|
|
144
|
+
* by listening to `mode-change`), and fires the `mode-change` event.
|
|
145
|
+
*
|
|
146
|
+
* Selection remains functional for copy / outline / accessibility;
|
|
147
|
+
* only editing is suspended.
|
|
148
|
+
*/
|
|
149
|
+
setMode(mode: SobreeMode): void;
|
|
150
|
+
/**
|
|
151
|
+
* Current track-changes state. See `TrackChangesState`.
|
|
152
|
+
*
|
|
153
|
+
* Thin proxy to `editor.getTrackChanges()` — exposed on the façade
|
|
154
|
+
* so embedders driving the UI don't need to reach `sobree.editor`.
|
|
155
|
+
*/
|
|
156
|
+
getTrackChanges(): TrackChangesState;
|
|
157
|
+
/**
|
|
158
|
+
* Switch authoring mode. Delegates to `editor.setTrackChanges`,
|
|
159
|
+
* which fires `track-changes-change`. Listeners attached to either
|
|
160
|
+
* `editor.on("track-changes-change", …)` or
|
|
161
|
+
* `sobree.on("track-changes-change", …)` receive the new state.
|
|
162
|
+
*
|
|
163
|
+
* The mode survives until flipped — it's not bound to selection or
|
|
164
|
+
* document. To run a one-off tracked edit, save the previous state,
|
|
165
|
+
* flip on, mutate, flip back.
|
|
166
|
+
*/
|
|
167
|
+
setTrackChanges(state: TrackChangesState): void;
|
|
168
|
+
/**
|
|
169
|
+
* Read a .docx file and load it into the editor. Fully native: the
|
|
170
|
+
* parsed `SobreeDocument` is handed straight to the editor — no djot
|
|
171
|
+
* intermediate.
|
|
172
|
+
*/
|
|
173
|
+
openDocx(src: File | Blob | ArrayBuffer | Uint8Array): Promise<void>;
|
|
174
|
+
/**
|
|
175
|
+
* Export the current document as a .docx Blob. Reads the editor's AST
|
|
176
|
+
* directly, overlays the current page setup's section/header/footer,
|
|
177
|
+
* and serialises to OOXML.
|
|
178
|
+
*/
|
|
179
|
+
exportDocx(): Blob;
|
|
180
|
+
on<E extends SobreeEvent>(event: E, cb: (payload: SobreeEventPayload[E]) => void): SobreeUnsubscribe;
|
|
181
|
+
/**
|
|
182
|
+
* Compose the sections array the paper stack needs:
|
|
183
|
+
*
|
|
184
|
+
* sections[0] is built from the live `setup` (the demo's UI model
|
|
185
|
+
* represents section 0; setPageSetup updates flow through here).
|
|
186
|
+
* sections[1..] come straight from the document AST — there's no UI
|
|
187
|
+
* for editing them yet, so they're effectively read-only until a
|
|
188
|
+
* future Page Setup section selector lands.
|
|
189
|
+
*
|
|
190
|
+
* Called whenever either source could have changed: constructor,
|
|
191
|
+
* `change` event, `setPageSetup`.
|
|
192
|
+
*/
|
|
193
|
+
private syncStackSections;
|
|
194
|
+
/**
|
|
195
|
+
* Re-derive `setup` from `doc.sections[0]` when they diverge.
|
|
196
|
+
*
|
|
197
|
+
* Why: every page-setup edit goes setup → AST via
|
|
198
|
+
* `writeSetupToSection0`. But the inverse — AST → setup — only ran
|
|
199
|
+
* at construction time. That left the renderer's `setup` stuck on
|
|
200
|
+
* the post-edit state when the AST got reverted by undo / redo /
|
|
201
|
+
* external Y-provider edits, so `Cmd+Z` for a margin change reverted
|
|
202
|
+
* the AST silently while the paper kept the new margins.
|
|
203
|
+
*
|
|
204
|
+
* The `sameSetup` early-out is load-bearing — without it, the
|
|
205
|
+
* `change` event fired by `editor.setDocument` inside
|
|
206
|
+
* `writeSetupToSection0` would loop back into here, see the same
|
|
207
|
+
* setup, and waste a re-paginate.
|
|
208
|
+
*/
|
|
209
|
+
private syncSetupFromDocument;
|
|
210
|
+
destroy(): void;
|
|
211
|
+
}
|
package/dist/tokens.css
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/* Carlito — Google's open-source, metric-compatible clone of Calibri.
|
|
2
|
+
* MUST be the first rule in this file: CSS `@import` only fires when
|
|
3
|
+
* it precedes every other declaration. Most Sobree-rendered docs are
|
|
4
|
+
* authored in Word with Calibri as the body font; without Calibri or
|
|
5
|
+
* Carlito on the host, browsers fall back to Helvetica/Arial whose
|
|
6
|
+
* ellipsis (…) glyph is roughly 2× wider than Calibri's. A 60-char
|
|
7
|
+
* dot-leader bullet ("……………") that fits one line in Word then
|
|
8
|
+
* overflows or wraps in Sobree.
|
|
9
|
+
*
|
|
10
|
+
* We pull Carlito from Google Fonts so any embedder that imports
|
|
11
|
+
* `@sobree/core/tokens.css` gets Word-fidelity ellipsis (and accurate
|
|
12
|
+
* line metrics) without bundling the ~200 KB font in the package
|
|
13
|
+
* itself. Google Fonts serves subset WOFF2 files (~50 KB per weight)
|
|
14
|
+
* with permissive caching. `font-display: swap` means text reads
|
|
15
|
+
* immediately while Carlito loads — no flash of invisible text.
|
|
16
|
+
*
|
|
17
|
+
* If the host is offline / the CDN is blocked, the cascade falls
|
|
18
|
+
* through to Helvetica → Arial (wider ellipsis but still readable).
|
|
19
|
+
* For deployments that need fully-bundled fonts, override this @import
|
|
20
|
+
* with a local woff2 in the embedder's own CSS.
|
|
21
|
+
*/
|
|
22
|
+
@import url("https://fonts.googleapis.com/css2?family=Carlito:ital,wght@0,400;0,700;1,400;1,700&display=swap");
|
|
23
|
+
|
|
24
|
+
/* @sobree/core — design tokens (the single source of truth for the brand).
|
|
25
|
+
*
|
|
26
|
+
* Consume from CSS:
|
|
27
|
+
*
|
|
28
|
+
* @import "@sobree/core/tokens.css";
|
|
29
|
+
*
|
|
30
|
+
* Or from JS / TS:
|
|
31
|
+
*
|
|
32
|
+
* import "@sobree/core/tokens.css";
|
|
33
|
+
*
|
|
34
|
+
* Add new tokens here, not in component CSS — keeps the brand coherent
|
|
35
|
+
* and makes theming a single edit.
|
|
36
|
+
*/
|
|
37
|
+
|
|
38
|
+
:root {
|
|
39
|
+
/* Primary — Sobree Amber. */
|
|
40
|
+
--sobree-50: #fdf6ee;
|
|
41
|
+
--sobree-100: #f9e6d0;
|
|
42
|
+
--sobree-500: #c96f22;
|
|
43
|
+
--sobree-600: #b2591a;
|
|
44
|
+
|
|
45
|
+
/* Neutrals — warm ink, not gray. */
|
|
46
|
+
--ink-0: #ffffff;
|
|
47
|
+
--ink-25: #fbfaf7;
|
|
48
|
+
--ink-50: #f6f4ef;
|
|
49
|
+
--ink-100: #eceae3;
|
|
50
|
+
--ink-200: #dedbd0;
|
|
51
|
+
--ink-300: #c4bfaf;
|
|
52
|
+
--ink-400: #a29c88;
|
|
53
|
+
--ink-500: #7c7764;
|
|
54
|
+
--ink-600: #5a5649;
|
|
55
|
+
--ink-700: #3d3a31;
|
|
56
|
+
--ink-800: #26241f;
|
|
57
|
+
--ink-900: #14130f;
|
|
58
|
+
|
|
59
|
+
/* Semantic tokens — what components reference. */
|
|
60
|
+
--bg: var(--ink-25);
|
|
61
|
+
--bg-elevated: var(--ink-0);
|
|
62
|
+
--bg-subtle: var(--ink-50);
|
|
63
|
+
--bg-hover: var(--ink-100);
|
|
64
|
+
--fg: var(--ink-800);
|
|
65
|
+
--fg-strong: var(--ink-900);
|
|
66
|
+
--fg-muted: var(--ink-600);
|
|
67
|
+
--fg-subtle: var(--ink-500);
|
|
68
|
+
--fg-on-primary: var(--ink-0);
|
|
69
|
+
--border: var(--ink-200);
|
|
70
|
+
--border-strong: var(--ink-300);
|
|
71
|
+
--primary: var(--sobree-500);
|
|
72
|
+
--primary-hover: var(--sobree-600);
|
|
73
|
+
--primary-soft: var(--sobree-50);
|
|
74
|
+
|
|
75
|
+
/* Radii. */
|
|
76
|
+
--radius-xs: 2px;
|
|
77
|
+
--radius-sm: 2px;
|
|
78
|
+
--radius-md: 4px;
|
|
79
|
+
--radius-lg: 6px;
|
|
80
|
+
|
|
81
|
+
/* Shadows — warm-ink tinted, never gray. */
|
|
82
|
+
--shadow-xs: 0 1px 0 rgba(20, 19, 15, 0.04);
|
|
83
|
+
--shadow-sm: 0 1px 2px rgba(20, 19, 15, 0.06), 0 1px 1px rgba(20, 19, 15, 0.04);
|
|
84
|
+
--shadow-md: 0 4px 8px -2px rgba(20, 19, 15, 0.08), 0 2px 4px -2px rgba(20, 19, 15, 0.05);
|
|
85
|
+
--shadow-lg: 0 12px 24px -8px rgba(20, 19, 15, 0.12), 0 4px 8px -4px rgba(20, 19, 15, 0.06);
|
|
86
|
+
|
|
87
|
+
/* Focus ring — amber glow. */
|
|
88
|
+
--ring-focus: 0 0 0 3px rgba(201, 111, 34, 0.25);
|
|
89
|
+
|
|
90
|
+
/* Motion. */
|
|
91
|
+
--ease-standard: cubic-bezier(0.2, 0, 0, 1);
|
|
92
|
+
--dur-fast: 120ms;
|
|
93
|
+
--dur-base: 180ms;
|
|
94
|
+
--dur-slow: 280ms;
|
|
95
|
+
|
|
96
|
+
/* Spacing — 4px base. */
|
|
97
|
+
--space-1: 4px;
|
|
98
|
+
--space-2: 8px;
|
|
99
|
+
--space-3: 12px;
|
|
100
|
+
--space-4: 16px;
|
|
101
|
+
--space-5: 20px;
|
|
102
|
+
--space-6: 24px;
|
|
103
|
+
|
|
104
|
+
/* Back-compat aliases for older component CSS. */
|
|
105
|
+
--sobree-primary: var(--sobree-500);
|
|
106
|
+
--sobree-primary-soft: var(--primary-soft);
|
|
107
|
+
--sobree-border: var(--border);
|
|
108
|
+
|
|
109
|
+
/* === Tracked changes & comments ===
|
|
110
|
+
*
|
|
111
|
+
* The renderer emits semantic `<ins>` / `<del>` / comment markup in
|
|
112
|
+
* core (visibility is document fidelity, not an opt-in feature).
|
|
113
|
+
* These tokens make the *styling* themeable — override them in a
|
|
114
|
+
* consumer stylesheet instead of fighting component CSS specificity.
|
|
115
|
+
*/
|
|
116
|
+
|
|
117
|
+
/* Per-author palette — 8 slots. `colorForAuthor()` hashes an author
|
|
118
|
+
* name to a slot index; the renderer references the matching token.
|
|
119
|
+
* Chosen for similar luminance (no author looks "louder") and to
|
|
120
|
+
* avoid pure red (clashes with deletion strikethrough) / pure yellow
|
|
121
|
+
* (clashes with the comment-range highlight). */
|
|
122
|
+
--sobree-author-0: #1f77b4; /* muted blue */
|
|
123
|
+
--sobree-author-1: #2ca02c; /* green */
|
|
124
|
+
--sobree-author-2: #9467bd; /* purple */
|
|
125
|
+
--sobree-author-3: #8c564b; /* brown */
|
|
126
|
+
--sobree-author-4: #e377c2; /* pink */
|
|
127
|
+
--sobree-author-5: #17becf; /* teal */
|
|
128
|
+
--sobree-author-6: #bcbd22; /* olive */
|
|
129
|
+
--sobree-author-7: #ff7f0e; /* orange */
|
|
130
|
+
|
|
131
|
+
/* Revision (tracked-change) styling. The author colour drives the
|
|
132
|
+
* text + decoration; `--sobree-revision-tint` is the background
|
|
133
|
+
* mix-strength applied via `color-mix`. */
|
|
134
|
+
--sobree-revision-ins-fallback: #0a7d2a; /* used when no author colour */
|
|
135
|
+
--sobree-revision-del-fallback: #b3261e;
|
|
136
|
+
--sobree-revision-tint: 8%;
|
|
137
|
+
|
|
138
|
+
/* Comment styling. */
|
|
139
|
+
--sobree-comment-range-bg: rgba(255, 217, 0, 0.25);
|
|
140
|
+
--sobree-comment-range-border: rgba(180, 130, 0, 0.5);
|
|
141
|
+
--sobree-comment-accent: #f59e0b; /* card rule when author colour absent */
|
|
142
|
+
--sobree-comment-resolved: #16a34a; /* resolved-thread green */
|
|
143
|
+
}
|
|
144
|
+
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Save and restore the current document selection as a pair of (node, offset)
|
|
3
|
+
* pairs. Works across block re-parenting because text nodes are referenced
|
|
4
|
+
* directly — only breaks when the saved node is actually removed from the DOM.
|
|
5
|
+
*/
|
|
6
|
+
export interface SavedSelection {
|
|
7
|
+
startContainer: Node;
|
|
8
|
+
startOffset: number;
|
|
9
|
+
endContainer: Node;
|
|
10
|
+
endOffset: number;
|
|
11
|
+
}
|
|
12
|
+
export declare function saveSelection(): SavedSelection | null;
|
|
13
|
+
export declare function restoreSelection(saved: SavedSelection | null): void;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { SobreeDocument } from '../doc/types';
|
|
2
|
+
import * as Y from "yjs";
|
|
3
|
+
/**
|
|
4
|
+
* Apply a new SobreeDocument to a Y.Doc, diffing against the current
|
|
5
|
+
* Y state by **block id**. The caller supplies the new id-per-block
|
|
6
|
+
* array (typically derived from the BlockRegistry — see
|
|
7
|
+
* `Editor.applyDocument`).
|
|
8
|
+
*
|
|
9
|
+
* # Granularity
|
|
10
|
+
*
|
|
11
|
+
* - **Body blocks:** matched by id; updated in-place / inserted /
|
|
12
|
+
* removed. Concurrent edits to *different* blocks always merge
|
|
13
|
+
* cleanly via the Y.Array CRDT.
|
|
14
|
+
*
|
|
15
|
+
* - **Paragraph block content:** the Y.Text is updated via
|
|
16
|
+
* `diffApplyText` — minimal `insert` / `delete` / `format`
|
|
17
|
+
* mutations matching what changed. Concurrent edits to *different
|
|
18
|
+
* positions* in the same paragraph merge cleanly. Concurrent
|
|
19
|
+
* edits to the *same* position still resolve via Yjs's standard
|
|
20
|
+
* ordering (later op wins per Yjs's deterministic conflict rules).
|
|
21
|
+
*
|
|
22
|
+
* - **Paragraph properties (alignment, indent, …):** stored as a
|
|
23
|
+
* JSON blob on the Y.Map's `props` field. Concurrent property
|
|
24
|
+
* edits clobber. Phase 1c may split into per-key Y.Map.
|
|
25
|
+
*
|
|
26
|
+
* - **Non-paragraph blocks (section_break, table):** stored as
|
|
27
|
+
* JSON-encoded `_ast`. Concurrent edits clobber.
|
|
28
|
+
*
|
|
29
|
+
* - **Document meta (sections, styles, numbering, fonts,
|
|
30
|
+
* headerFooterBodies):** JSON-encoded on a `meta` Y.Map.
|
|
31
|
+
* Clobber on concurrent edits — these change rarely.
|
|
32
|
+
*
|
|
33
|
+
* - **Binary parts (images, fonts):** stored as a Y.Map<Uint8Array>
|
|
34
|
+
* with adds / removes detected by key. Phase 3 moves these to a
|
|
35
|
+
* content-hashed blob store (out-of-band).
|
|
36
|
+
*
|
|
37
|
+
* The whole apply is wrapped in a single `Y.Doc.transact` with the
|
|
38
|
+
* supplied origin so subscribers (UndoManager, change listeners) see
|
|
39
|
+
* one batch.
|
|
40
|
+
*/
|
|
41
|
+
export interface ApplyDocumentOptions {
|
|
42
|
+
/**
|
|
43
|
+
* Part paths to **exclude** from the inline `parts` diff. Used when
|
|
44
|
+
* a `BlobStore` is configured — paths already managed via `partRefs`
|
|
45
|
+
* (or in-flight migration to it) must not also be written inline,
|
|
46
|
+
* or the Y.Doc would carry duplicate bytes.
|
|
47
|
+
*
|
|
48
|
+
* Empty / absent: today's path — every `rawParts` entry mirrors
|
|
49
|
+
* inline (no BlobStore).
|
|
50
|
+
*/
|
|
51
|
+
skipPartPaths?: ReadonlySet<string>;
|
|
52
|
+
}
|
|
53
|
+
export declare function applyDocumentToYDoc(ydoc: Y.Doc, newDoc: SobreeDocument, newIds: readonly string[], origin?: unknown, opts?: ApplyDocumentOptions): void;
|
|
54
|
+
/**
|
|
55
|
+
* Atomically write `partRefs` entries to a Y.Doc's `partRefs` Y.Map.
|
|
56
|
+
* Used by the Editor / HeadlessSobree when a `BlobStore` is configured —
|
|
57
|
+
* the editor hashes new bytes, uploads via the store, then calls this
|
|
58
|
+
* to publish the hash so other peers can fetch it.
|
|
59
|
+
*
|
|
60
|
+
* Wraps in `Y.Doc.transact` with the supplied origin so subscribers
|
|
61
|
+
* (UndoManager, observers) see one batch.
|
|
62
|
+
*/
|
|
63
|
+
export declare function applyPartRefsToYDoc(ydoc: Y.Doc, partRefs: Record<string, string>, origin?: unknown): void;
|
|
64
|
+
/**
|
|
65
|
+
* Remove `partRefs` entries from a Y.Doc. Used when an embedder
|
|
66
|
+
* prunes unreferenced parts.
|
|
67
|
+
*/
|
|
68
|
+
export declare function removePartRefsFromYDoc(ydoc: Y.Doc, paths: readonly string[], origin?: unknown): void;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Y.Doc backing for Sobree.
|
|
3
|
+
*
|
|
4
|
+
* The document is a Y.Doc; `SobreeDocument` is a *projection* computed
|
|
5
|
+
* by `projectYDoc` and cached by the Editor. All mutations go through
|
|
6
|
+
* `applyDocumentToYDoc` which diffs against the current Y state by
|
|
7
|
+
* block id and (for paragraphs) by Y.Text content.
|
|
8
|
+
*
|
|
9
|
+
* See `./schema.ts` for the Y.Doc layout, `./runs.ts` for the
|
|
10
|
+
* Run↔Delta mapping, and `./textDiff.ts` for the smart Y.Text diff
|
|
11
|
+
* that preserves CRDT semantics across applies.
|
|
12
|
+
*/
|
|
13
|
+
export { Y_BLOCK_AST_KEY, Y_BLOCK_ID_KEY, Y_BLOCK_KIND_KEY, Y_BLOCK_PROPS_KEY, Y_BLOCK_TEXT_KEY, Y_BODY_KEY, Y_META_FIELDS, Y_META_KEY, Y_PARTREFS_KEY, Y_PARTS_KEY, } from './schema';
|
|
14
|
+
export { seedYDoc, buildBlockYMap, buildSkeletonBlockYMap, populateBlockContent, populateParagraphContent, populateParagraphYMap, } from './seed';
|
|
15
|
+
export { projectYDoc, projectBlock } from './project';
|
|
16
|
+
export { applyDocumentToYDoc, applyPartRefsToYDoc, removePartRefsFromYDoc, } from './apply';
|
|
17
|
+
export { type DeltaOp, type EmbedContent, type LinkMark, attrsToRunProps, deepEqual, deltaToRuns, runPropsToAttrs, runsToDelta, } from './runs';
|
|
18
|
+
export { diffApplyText } from './textDiff';
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Block, SobreeDocument } from '../doc/types';
|
|
2
|
+
import type * as Y from "yjs";
|
|
3
|
+
/**
|
|
4
|
+
* Read the SobreeDocument projection out of a Y.Doc.
|
|
5
|
+
*
|
|
6
|
+
* Returns:
|
|
7
|
+
*
|
|
8
|
+
* - **`doc`** — the projected SobreeDocument. Its `rawParts` is
|
|
9
|
+
* populated from the Y.Doc's inline `parts` Y.Map only.
|
|
10
|
+
* - **`ids`** — block-id order matching `doc.body`. The Editor
|
|
11
|
+
* uses this to keep its BlockRegistry in sync.
|
|
12
|
+
* - **`partRefs`** — partPath → hash mappings from the Y.Doc's
|
|
13
|
+
* `partRefs` Y.Map (Phase 3.2+). Empty `{}` when no BlobStore-
|
|
14
|
+
* using peer has touched the doc. **The caller (Editor /
|
|
15
|
+
* HeadlessSobree) is responsible for resolving these through a
|
|
16
|
+
* `BlobCache`** and merging the results into `doc.rawParts`.
|
|
17
|
+
* We keep the resolution decoupled so projection has no async
|
|
18
|
+
* work or external dependency.
|
|
19
|
+
*
|
|
20
|
+
* Two block shapes are supported:
|
|
21
|
+
*
|
|
22
|
+
* - Phase 1b.5+: paragraphs as `{ kind: "paragraph", text: Y.Text, props }`.
|
|
23
|
+
* - Phase 1a: everything else as `{ _ast: JSON }`.
|
|
24
|
+
*
|
|
25
|
+
* Backwards compat: a Phase 1a-shaped paragraph (only `_ast`, no `kind`
|
|
26
|
+
* field) projects identically — the JSON is parsed straight to
|
|
27
|
+
* `Paragraph`.
|
|
28
|
+
*
|
|
29
|
+
* This is allocation-heavy; the Editor caches the result and invalidates
|
|
30
|
+
* on Y.Doc updates.
|
|
31
|
+
*/
|
|
32
|
+
export declare function projectYDoc(ydoc: Y.Doc): {
|
|
33
|
+
doc: SobreeDocument;
|
|
34
|
+
ids: string[];
|
|
35
|
+
partRefs: Record<string, string>;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Read a single block Y.Map into a Block. Returns `null` if the map
|
|
39
|
+
* is empty / unrecognizable (defensive — projectYDoc skips nulls).
|
|
40
|
+
*/
|
|
41
|
+
export declare function projectBlock(map: Y.Map<unknown>): Block | null;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { BreakRun, DrawingRun, InlineRun, RunProperties } from '../doc/types';
|
|
2
|
+
export interface DeltaOp {
|
|
3
|
+
/** Text content (string) or embed (object literal). Y.Text differentiates by typeof. */
|
|
4
|
+
insert: string | EmbedContent;
|
|
5
|
+
/** Per-op marks — bold, italic, color, link, etc. Undefined when
|
|
6
|
+
* no marks apply (Yjs preference: omit rather than set empty). */
|
|
7
|
+
attributes?: Record<string, unknown>;
|
|
8
|
+
}
|
|
9
|
+
/** All non-text run kinds become embed objects in the delta. */
|
|
10
|
+
export type EmbedContent = {
|
|
11
|
+
__sobree: "break";
|
|
12
|
+
type: BreakRun["type"];
|
|
13
|
+
} | {
|
|
14
|
+
__sobree: "tab";
|
|
15
|
+
} | {
|
|
16
|
+
__sobree: "field";
|
|
17
|
+
instruction: string;
|
|
18
|
+
cached?: string;
|
|
19
|
+
} | {
|
|
20
|
+
__sobree: "drawing";
|
|
21
|
+
partPath: string;
|
|
22
|
+
widthEmu: number;
|
|
23
|
+
heightEmu: number;
|
|
24
|
+
placement: DrawingRun["placement"];
|
|
25
|
+
altText?: string;
|
|
26
|
+
};
|
|
27
|
+
/** The `link` mark — stamped on every char inside a HyperlinkRun. */
|
|
28
|
+
export interface LinkMark {
|
|
29
|
+
href: string;
|
|
30
|
+
}
|
|
31
|
+
export declare function runsToDelta(runs: readonly InlineRun[]): DeltaOp[];
|
|
32
|
+
export declare function deltaToRuns(delta: readonly DeltaOp[]): InlineRun[];
|
|
33
|
+
/**
|
|
34
|
+
* Convert RunProperties to a flat attributes object. Empty / undefined
|
|
35
|
+
* fields are omitted entirely (Yjs convention). Returns `undefined`
|
|
36
|
+
* when no marks apply.
|
|
37
|
+
*/
|
|
38
|
+
export declare function runPropsToAttrs(props: RunProperties | undefined): Record<string, unknown> | undefined;
|
|
39
|
+
/**
|
|
40
|
+
* Inverse of `runPropsToAttrs`. Strips the `link` key (it's handled
|
|
41
|
+
* separately as a hyperlink wrapper). Strips any unknown attributes
|
|
42
|
+
* defensively (forward-compat: a future plugin may add marks Sobree
|
|
43
|
+
* doesn't model).
|
|
44
|
+
*/
|
|
45
|
+
export declare function attrsToRunProps(attrs: Record<string, unknown> | undefined): RunProperties;
|
|
46
|
+
/**
|
|
47
|
+
* Deep equality for delta op contents — strings compared as `===`,
|
|
48
|
+
* embeds and attribute objects compared structurally. Used by the
|
|
49
|
+
* Y.Text diff to detect cells that haven't changed.
|
|
50
|
+
*/
|
|
51
|
+
export declare function deepEqual(a: unknown, b: unknown): boolean;
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Y.Doc shape used by Sobree.
|
|
3
|
+
*
|
|
4
|
+
* The document is stored as a Y.Doc — that's the source of truth.
|
|
5
|
+
* `SobreeDocument` is a *projection* of this Y.Doc, computed by the
|
|
6
|
+
* helpers in `./project.ts` and cached by the Editor.
|
|
7
|
+
*
|
|
8
|
+
* # Top-level layout
|
|
9
|
+
*
|
|
10
|
+
* ```
|
|
11
|
+
* ydoc
|
|
12
|
+
* ├── getArray("body") : Y.Array<Y.Map> — block list, one Y.Map per block
|
|
13
|
+
* ├── getMap("meta") : Y.Map — sections, styles, numbering,
|
|
14
|
+
* │ headerFooterBodies, fonts.
|
|
15
|
+
* │ Stored as JSON-encoded values
|
|
16
|
+
* │ (rarely edited concurrently).
|
|
17
|
+
* │ Phase 1c may split fields into
|
|
18
|
+
* │ per-key Y types.
|
|
19
|
+
* ├── getMap("parts") : Y.Map<Uint8Array> — inline binary parts
|
|
20
|
+
* │ (legacy / no-BlobStore path).
|
|
21
|
+
* └── getMap("partRefs") : Y.Map<string> — partPath → SHA-256 hex hash
|
|
22
|
+
* (Phase 3.2+ / BlobStore path).
|
|
23
|
+
* Bytes live in a side-channel
|
|
24
|
+
* `BlobStore`; the editor's
|
|
25
|
+
* `BlobCache` resolves hashes.
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* Both `parts` and `partRefs` coexist — projection unions them so a
|
|
29
|
+
* Y.Doc with inline legacy bytes alongside hash-addressed refs reads
|
|
30
|
+
* correctly. The editor writes to whichever path matches its config
|
|
31
|
+
* (BlobStore → partRefs, otherwise parts).
|
|
32
|
+
*
|
|
33
|
+
* # Block Y.Map shape — paragraphs (Phase 1b.5+)
|
|
34
|
+
*
|
|
35
|
+
* Paragraph blocks (kind === `"paragraph"`, including headings) are
|
|
36
|
+
* structured for char-level CRDT:
|
|
37
|
+
*
|
|
38
|
+
* ```
|
|
39
|
+
* paragraphMap
|
|
40
|
+
* ├── get("id") : string — stable block id (matches BlockRegistry)
|
|
41
|
+
* ├── get("kind") : "paragraph" — discriminator
|
|
42
|
+
* ├── get("text") : Y.Text — runs flatten into here, marks for marks,
|
|
43
|
+
* │ embeds for breaks/tabs/fields/drawings,
|
|
44
|
+
* │ `link: { href }` mark for hyperlink chars
|
|
45
|
+
* └── get("props") : string (JSON) — ParagraphProperties (alignment, indent,
|
|
46
|
+
* numbering, …). JSON-encoded for v0.1;
|
|
47
|
+
* concurrent property edits clobber.
|
|
48
|
+
* ```
|
|
49
|
+
*
|
|
50
|
+
* # Block Y.Map shape — non-paragraphs
|
|
51
|
+
*
|
|
52
|
+
* Section breaks and tables stay JSON-encoded — neither has inline
|
|
53
|
+
* text content with concurrent-edit demand. Tables get their own
|
|
54
|
+
* structural CRDT in a future Phase 1c (per-cell Y.Map<body Y.Array>).
|
|
55
|
+
*
|
|
56
|
+
* ```
|
|
57
|
+
* otherBlockMap
|
|
58
|
+
* ├── get("id") : string — stable block id
|
|
59
|
+
* └── get("_ast") : string (JSON) — JSON-encoded Block
|
|
60
|
+
* ```
|
|
61
|
+
*
|
|
62
|
+
* # Y.Text mark conventions
|
|
63
|
+
*
|
|
64
|
+
* The mapping between Sobree's `RunProperties` and Y.Text marks is
|
|
65
|
+
* 1:1 — `bold: true` becomes `{ bold: true }` on each char's
|
|
66
|
+
* attributes. Two special cases:
|
|
67
|
+
*
|
|
68
|
+
* - `link: { href }` — chars inside a `HyperlinkRun` carry this mark.
|
|
69
|
+
* The decoder reconstructs the HyperlinkRun by grouping consecutive
|
|
70
|
+
* same-href chars.
|
|
71
|
+
* - Embeds — non-text runs (break / tab / field / drawing) appear as
|
|
72
|
+
* embed objects (`{ insert: { __sobree: "<kind>", … } }` in delta
|
|
73
|
+
* form), occupying one position in the Y.Text.
|
|
74
|
+
*
|
|
75
|
+
* See `./runs.ts` for the conversion helpers and `./textDiff.ts` for
|
|
76
|
+
* the smart Y.Text diff that preserves CRDT semantics across applies.
|
|
77
|
+
*/
|
|
78
|
+
export declare const Y_BODY_KEY = "body";
|
|
79
|
+
export declare const Y_META_KEY = "meta";
|
|
80
|
+
/**
|
|
81
|
+
* Inline binary parts — `Y.Map<string, Uint8Array>` keyed by part
|
|
82
|
+
* path (e.g. `word/media/image1.png`). The legacy path: bytes ride
|
|
83
|
+
* along inside Y updates. Acceptable for small docs; expensive at
|
|
84
|
+
* scale (every peer replicates every byte).
|
|
85
|
+
*
|
|
86
|
+
* Used when no `BlobStore` is configured on the editor.
|
|
87
|
+
*/
|
|
88
|
+
export declare const Y_PARTS_KEY = "parts";
|
|
89
|
+
/**
|
|
90
|
+
* Content-hashed part references — `Y.Map<string, string>` keyed by
|
|
91
|
+
* part path, valued by SHA-256 hex hash. The Phase 3.2+ path: bytes
|
|
92
|
+
* live in a side-channel `BlobStore`, the Y.Doc carries only small
|
|
93
|
+
* 64-char hashes. Y updates stay tiny regardless of image size.
|
|
94
|
+
*
|
|
95
|
+
* Used when a `BlobStore` is configured. The projection's `rawParts`
|
|
96
|
+
* resolves hashes against the editor's local `BlobCache` (which
|
|
97
|
+
* fetches from the store on miss).
|
|
98
|
+
*
|
|
99
|
+
* Both `parts` and `partRefs` coexist — a Y.Doc can carry inline
|
|
100
|
+
* legacy bytes alongside hash-addressed refs. Projection unions
|
|
101
|
+
* them; mixed-mode swarms work.
|
|
102
|
+
*/
|
|
103
|
+
export declare const Y_PARTREFS_KEY = "partRefs";
|
|
104
|
+
export declare const Y_BLOCK_ID_KEY = "id";
|
|
105
|
+
/** Discriminator: `"paragraph"` blocks have `text` + `props`; everything
|
|
106
|
+
* else has `_ast`. Defaults to "_ast" path for forward-compat with
|
|
107
|
+
* Phase 1a docs that didn't write a kind field. */
|
|
108
|
+
export declare const Y_BLOCK_KIND_KEY = "kind";
|
|
109
|
+
/** Phase 1b.5+: Y.Text on paragraph blocks. */
|
|
110
|
+
export declare const Y_BLOCK_TEXT_KEY = "text";
|
|
111
|
+
/** Phase 1b.5+: JSON-encoded ParagraphProperties on paragraph blocks. */
|
|
112
|
+
export declare const Y_BLOCK_PROPS_KEY = "props";
|
|
113
|
+
/** Phase 1a: JSON-encoded Block on non-paragraph blocks (and on
|
|
114
|
+
* Phase 1a-shaped paragraph blocks for backwards compat). */
|
|
115
|
+
export declare const Y_BLOCK_AST_KEY = "_ast";
|
|
116
|
+
/** Keys stored on the `meta` Y.Map. */
|
|
117
|
+
export declare const Y_META_FIELDS: {
|
|
118
|
+
readonly sections: "sections";
|
|
119
|
+
readonly headerFooterBodies: "headerFooterBodies";
|
|
120
|
+
readonly styles: "styles";
|
|
121
|
+
readonly numbering: "numbering";
|
|
122
|
+
readonly fonts: "fonts";
|
|
123
|
+
};
|