@owomark/view 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.
@@ -0,0 +1,228 @@
1
+ import { OwoMarkCore, OwoMarkEditorInstance, OwoMarkSharedState, PreviewBlockKind, PreviewBlock } from '@owomark/core';
2
+ export { DocumentChangeCallback } from '@owomark/core';
3
+ export { Callout, CodeDemo, DEFAULT_MDX_COMPONENTS, FileTree, Kbd, MdxComponentMap, OwoMarkProcessor, OwoMarkProcessorOptions, OwoMarkThemeName, PluginEntry, ProcessorMode, SideAnnotationNode, Step, Steps, THEME_DARK_CLASS, THEME_LIGHT_CLASS, Tab, Tabs, createOwoMarkProcessor, getOwoMarkPlugins, getThemeClassName, rehypeMathDisplayFix, rehypeSideAnnotation, remarkConvertSoftBreaksToHardBreaks, remarkSideAnnotation } from './static.js';
4
+ import 'react';
5
+ import 'mdast';
6
+ import 'hast';
7
+
8
+ /**
9
+ * Three-layer view engine for OwoMark.
10
+ *
11
+ * Layer 1: Active block input proxy + state-to-DOM engine
12
+ * Layer 2: Shadow Buffer (IME composition with active block isolation)
13
+ * Layer 3: Cross-block virtual selection
14
+ *
15
+ * Only the active block (cursor position) has contenteditable="true" and
16
+ * receives focus. All other blocks are contenteditable="false".
17
+ */
18
+
19
+ type OwoMarkViewEngine = {
20
+ mount(element: HTMLElement): void;
21
+ destroy(): void;
22
+ getActiveBlockId(): string | null;
23
+ };
24
+ type ViewEngineOptions = {
25
+ core: OwoMarkCore;
26
+ };
27
+ declare function createViewEngine(options: ViewEngineOptions): OwoMarkViewEngine;
28
+
29
+ /**
30
+ * View engine for OwoMark.
31
+ *
32
+ * Provides two APIs:
33
+ * - createOwoMarkView(core, element): Three-layer sovereign view engine
34
+ * - createOwoMarkVanillaEditor(): Legacy standalone editor (backward compat)
35
+ */
36
+
37
+ type OwoMarkView = OwoMarkViewEngine;
38
+ /**
39
+ * Create a sovereign view engine bound to an existing Core instance and DOM element.
40
+ *
41
+ * This is the primary public API for non-React usage:
42
+ * const core = createOwoMarkCore({ initialMarkdown: '# Hello' });
43
+ * const view = createOwoMarkView(core, element);
44
+ */
45
+ declare function createOwoMarkView(core: OwoMarkCore, element: HTMLElement): OwoMarkView;
46
+ /**
47
+ * Create a standalone editor (creates its own Core internally).
48
+ * Preserved for backward compatibility with vanilla adapter consumers.
49
+ */
50
+ declare function createOwoMarkVanillaEditor(): OwoMarkEditorInstance;
51
+
52
+ type PreviewRenderPhase = 'idle' | 'rendering' | 'highlighting' | 'ready' | 'error';
53
+ type PreviewCacheEntry = {
54
+ blockId: string;
55
+ renderKey: string;
56
+ html: string;
57
+ highlighted: boolean;
58
+ themeKey: string;
59
+ updatedAt: number;
60
+ };
61
+ type PreviewRenderContext = {
62
+ version: number;
63
+ themeKey: string;
64
+ abortSignal?: AbortSignal;
65
+ /**
66
+ * Line offset to add to source-line attributes in the rendered HTML.
67
+ * When a block starts at line N in the document, the renderer processes
68
+ * its raw content starting from line 1; this offset (N - 1) must be
69
+ * added to `data-source-line-start/end` so scroll sync anchors map
70
+ * to the correct document lines.
71
+ */
72
+ sourceLineOffset: number;
73
+ };
74
+ type PreviewRenderResult = {
75
+ kind: 'html';
76
+ html: string;
77
+ } | {
78
+ kind: 'dom';
79
+ mount: (container: HTMLElement) => void;
80
+ unmount?: () => void;
81
+ };
82
+ type PreviewRendererMode = 'html-worker-safe' | 'dom-main-thread';
83
+ type PreviewTaskPriority = 'realtime' | 'deferred';
84
+ type PreviewRendererDefinition = {
85
+ mode: PreviewRendererMode;
86
+ priority: PreviewTaskPriority;
87
+ render: PreviewBlockRenderer;
88
+ version: string;
89
+ };
90
+ type PreviewBlockRenderer = (block: PreviewBlock, context: PreviewRenderContext) => Promise<PreviewRenderResult> | PreviewRenderResult;
91
+ type PreviewRendererRegistry = {
92
+ get(kind: PreviewBlockKind): PreviewRendererDefinition | null;
93
+ register(kind: PreviewBlockKind, renderer: PreviewRendererDefinition): void;
94
+ unregister(kind: PreviewBlockKind): void;
95
+ };
96
+ type PreviewStrategy = 'incremental' | 'virtual';
97
+ type OwoMarkPreviewEngineOptions = {
98
+ strategy?: PreviewStrategy;
99
+ themeKey?: string;
100
+ registry?: PreviewRendererRegistry;
101
+ viewportFirst?: boolean;
102
+ /**
103
+ * External block renderer function. When provided, the engine uses this
104
+ * instead of the built-in default renderer. This allows the host to supply
105
+ * its own Markdown pipeline (unified, remark, rehype, Shiki, etc.) without
106
+ * the preview package bundling those heavy dependencies.
107
+ */
108
+ renderBlock?: (block: PreviewBlock, context: PreviewRenderContext) => Promise<string>;
109
+ /**
110
+ * Called after every DOM mutation — including idle-backfilled and deferred
111
+ * block renders — not just after the synchronous update() return.
112
+ * Use for scroll sync or other post-DOM-update side effects.
113
+ */
114
+ onContentUpdate?: () => void;
115
+ };
116
+ type OwoMarkPreviewEngine = {
117
+ mount(root: HTMLElement): void;
118
+ destroy(): void;
119
+ update(state: OwoMarkSharedState): void;
120
+ getRenderedVersion(): number;
121
+ };
122
+
123
+ /**
124
+ * OwoMark Preview Engine factory.
125
+ *
126
+ * Dispatches to the configured strategy implementation:
127
+ * - 'incremental': Block-level incremental rendering (Strategy A)
128
+ * - 'virtual': Offscreen measurement + virtual layout (Strategy B, default)
129
+ */
130
+
131
+ declare function createOwoMarkPreviewEngine(options?: OwoMarkPreviewEngineOptions): OwoMarkPreviewEngine;
132
+
133
+ declare function createRendererRegistry(): PreviewRendererRegistry;
134
+
135
+ /**
136
+ * Default block renderer using simple HTML conversion.
137
+ *
138
+ * This is a lightweight built-in renderer that converts Markdown block raw
139
+ * content to basic HTML. For full-featured rendering (GFM tables, math,
140
+ * syntax highlighting), the host should provide a custom `renderBlock`
141
+ * function via engine options, typically backed by unified/remark/rehype/Shiki.
142
+ *
143
+ * The default renderer handles common block types correctly and is suitable
144
+ * for basic previews without heavy dependencies.
145
+ */
146
+
147
+ /**
148
+ * Render a single PreviewBlock to HTML using the built-in lightweight renderer.
149
+ */
150
+ declare function renderBlockDefault(block: PreviewBlock): string;
151
+
152
+ /**
153
+ * DOM patcher: blockId-driven incremental DOM updates.
154
+ *
155
+ * Maintains a mapping of blockId -> DOM wrapper element.
156
+ * Only dirty blocks get their content replaced; unchanged blocks are preserved.
157
+ */
158
+
159
+ declare class PreviewDomPatcher {
160
+ private root;
161
+ private blockElements;
162
+ /** Tracked unmount callbacks for DOM-mounted renderers. */
163
+ private domUnmounts;
164
+ mount(root: HTMLElement): void;
165
+ destroy(): void;
166
+ /**
167
+ * Full render: replace all content with the given blocks.
168
+ */
169
+ fullRender(blocks: PreviewBlock[], htmlMap: Map<string, string>): void;
170
+ /**
171
+ * Incremental patch: update only dirty blocks.
172
+ * Handles additions, removals, and content changes.
173
+ */
174
+ patch(blocks: PreviewBlock[], htmlMap: Map<string, string>, dirtyBlockIds: Set<string>): void;
175
+ /**
176
+ * Rebuild DOM while reusing non-dirty block wrappers.
177
+ */
178
+ private rebuildWithReuse;
179
+ /**
180
+ * Update a single block's HTML content in place.
181
+ * Used by idle-scheduled backfill and deferred renders.
182
+ */
183
+ patchBlockHtml(blockId: string, html: string): void;
184
+ /**
185
+ * Mount a DOM renderer into a block's wrapper element.
186
+ * The renderer controls the wrapper's DOM directly.
187
+ */
188
+ mountDomContent(blockId: string, mountFn: (container: HTMLElement) => void, unmountFn?: () => void): void;
189
+ /**
190
+ * Cleanup a previous DOM mount for a block, if any.
191
+ */
192
+ private cleanupDomMount;
193
+ private createBlockWrapper;
194
+ private updateBlockAttributes;
195
+ /**
196
+ * Get the DOM element for a given blockId.
197
+ */
198
+ getBlockElement(blockId: string): HTMLElement | null;
199
+ }
200
+
201
+ /**
202
+ * SideAnnotationPositioner — Phase 3 JS dynamic positioning for side annotations.
203
+ *
204
+ * After the preview HTML is rendered with `.side-annotation` containers using CSS Grid,
205
+ * this module applies absolute positioning to annotation aside columns to handle
206
+ * collision avoidance when multiple annotations are near each other.
207
+ *
208
+ * Usage:
209
+ * const positioner = new SideAnnotationPositioner(previewContainer);
210
+ * positioner.reposition(); // call after each content update
211
+ * positioner.destroy(); // cleanup
212
+ */
213
+ declare class SideAnnotationPositioner {
214
+ private container;
215
+ private resizeObserver;
216
+ private repositionScheduled;
217
+ constructor(container: HTMLElement);
218
+ private setupResizeObserver;
219
+ private scheduleReposition;
220
+ /**
221
+ * Scan all side annotations in the container, detect overlaps,
222
+ * and apply offset positioning to avoid collisions.
223
+ */
224
+ reposition(): void;
225
+ destroy(): void;
226
+ }
227
+
228
+ export { type OwoMarkPreviewEngine, type OwoMarkPreviewEngineOptions, type OwoMarkView, type OwoMarkViewEngine, type PreviewBlockRenderer, type PreviewCacheEntry, PreviewDomPatcher, type PreviewRenderContext, type PreviewRenderPhase, type PreviewRenderResult, type PreviewRendererDefinition, type PreviewRendererMode, type PreviewRendererRegistry, type PreviewStrategy, type PreviewTaskPriority, SideAnnotationPositioner, type ViewEngineOptions, createOwoMarkPreviewEngine, createOwoMarkVanillaEditor, createOwoMarkView, createRendererRegistry, createViewEngine, renderBlockDefault };