@owomark/react 0.1.5 → 0.1.7

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/README.md CHANGED
@@ -52,7 +52,7 @@ function App() {
52
52
  | `coreRef` | `Ref<OwoMarkCore \| null>` | — | Direct access to the underlying OwoMarkCore instance |
53
53
  | `controller` | `OwoMarkSharedStateController` | — | Auto-connects editor to shared state (recommended for split editor) |
54
54
  | `indentMode` | `'auto' \| '2' \| '4'` | `'auto'` | Tab indent width |
55
- | `config` | `OwoMarkEditorConfig` | — | Unified editor config (`indentMode`, `enableSideAnnotation`, `enableMath`) |
55
+ | `config` | `OwoMarkEditorConfig` | — | Unified editor config (`indentMode`, `enableSideAnnotation`, `enableMath`, `enableComponents`) |
56
56
  | `ariaLabel` | `string` | — | Accessibility label |
57
57
 
58
58
  When `config` is provided, it becomes the unified configuration surface for editor behavior:
@@ -66,6 +66,7 @@ When `config` is provided, it becomes the unified configuration surface for edit
66
66
  indentMode: '2',
67
67
  enableSideAnnotation: true,
68
68
  enableMath: true,
69
+ enableComponents: true,
69
70
  }}
70
71
  />
71
72
  ```
@@ -135,6 +136,8 @@ For hosts that still need `onChange` callbacks (e.g. for local draft persistence
135
136
  />
136
137
  ```
137
138
 
139
+ When `OwoMarkPreview` runs in `strategy="mdx"`, syntax detection may use internal probe-only masking. The MDX compile path may also apply a private compatibility normalization for indented code blocks, but compile errors and `data-source-line-*` anchors are remapped back to the original editor lines.
140
+
138
141
  ### Custom Block Renderer
139
142
 
140
143
  Provide a host-side rendering function for full Markdown fidelity (GFM, math, syntax highlighting):
@@ -155,6 +158,8 @@ async function renderBlock(
155
158
 
156
159
  OwoMark supports right-side annotations for preview rendering and editor workflows. The feature is enabled by default and can be turned off with `config.enableSideAnnotation = false`.
157
160
 
161
+ The canonical syntax, type table, MDX boundary, and future descriptor contract are frozen in [docs/specs/owomark-side-annotation.md](/home/qq/proj/qblog/docs/specs/owomark-side-annotation.md).
162
+
158
163
  ```tsx
159
164
  <OwoMarkEditor
160
165
  value={md}
@@ -272,6 +277,57 @@ import '@owomark/view/style.css'; // includes owomark.css + side-annotation.css
272
277
  import '@owomark/processor/mdx-components.css'; // built-in MDX component styles
273
278
  ```
274
279
 
280
+ The current built-in MDX runtime registry includes `Note`, `Callout`, `CodeDemo`, `CodeTab`, `Details`, `LinkCard`, `Steps`, `Step`, `Tabs`, `Tab`, `FileTree`, and `Kbd`.
281
+
282
+ For the canonical built-in component contract and the full official component registry, see [docs/specs/owomark-components-extension.md](/home/qq/proj/qblog/docs/specs/owomark-components-extension.md). This README stays at the usage-summary level for the components that are actually exported today.
283
+
284
+ For the canonical math parsing, normalization, and slash-entry contract, see [docs/specs/owomark-math.md](/home/qq/proj/qblog/docs/specs/owomark-math.md).
285
+
286
+ Use `Note` for supplemental explanation, editor notes, and neutral guidance. Keep `Callout` for stronger feedback semantics such as `info`, `warn`, `error`, or `success`.
287
+
288
+ | Component | Use for | Example |
289
+ |---|---|---|
290
+ | `Callout` | Strong feedback blocks with explicit severity | `<Callout type="warn">Read this first.</Callout>` |
291
+ | `Note` | Neutral explanation, editor notes, low-emphasis guidance | `<Note title="Editor note">Background context.</Note>` |
292
+ | `CodeDemo` | Code sample + optional title wrapper | `<CodeDemo title="demo" code={"const x = 1;"} />` |
293
+ | `Steps` + `Step` | Ordered task or tutorial flows | `<Steps><Step title="Install">...</Step></Steps>` |
294
+ | `Tabs` + `Tab` | Small tabbed content groups | `<Tabs><Tab label="React">...</Tab></Tabs>` |
295
+ | `FileTree` | File/folder structure snippets | `<FileTree>{"src/\\n app.ts"}</FileTree>` |
296
+ | `Kbd` | Keyboard keycaps in inline prose | `Press <Kbd>Cmd</Kbd> + <Kbd>K</Kbd>` |
297
+
298
+ Complete example matrix:
299
+
300
+ ```mdx
301
+ <Note title="Editor note">
302
+ This paragraph is background context, not a warning or status message.
303
+ </Note>
304
+
305
+ <Callout type="info">
306
+ MDX components ship in the default registry.
307
+ </Callout>
308
+
309
+ <CodeDemo title="Minimal example" code={`const x = 1;`} />
310
+
311
+ <Steps>
312
+ <Step title="Install">Add the package.</Step>
313
+ <Step title="Render">Mount the preview.</Step>
314
+ </Steps>
315
+
316
+ <Tabs>
317
+ <Tab label="React">Use the React bindings.</Tab>
318
+ <Tab label="Core">Use the framework-agnostic core.</Tab>
319
+ </Tabs>
320
+
321
+ <FileTree>
322
+ {`src/
323
+ app.tsx
324
+ routes/
325
+ mdx-preview.tsx`}
326
+ </FileTree>
327
+
328
+ Press <Kbd>Cmd</Kbd> + <Kbd>K</Kbd>.
329
+ ```
330
+
275
331
  ### Selective imports
276
332
 
277
333
  ```ts
@@ -0,0 +1,58 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "packageName": "@owomark/react",
4
+ "packagePath": "owomark/packages/owomark-react",
5
+ "packageFingerprint": "cd194512b0273bc2317f818bca9056dd119e2b2e3148f0441e36e626429122c8",
6
+ "workspaceFingerprint": "29c91b05781cfd51984ade38b2b582f8dab1013dfaaf87ed5b2b6e9723653157",
7
+ "builtAt": "2026-04-23T03:06:11.526Z",
8
+ "builderVersion": "2026-04-22-industrialization-v1",
9
+ "inputFiles": [
10
+ "owomark/package.json",
11
+ "owomark/packages/owomark-react/package.json",
12
+ "owomark/packages/owomark-react/src/AsyncCodeBlock.tsx",
13
+ "owomark/packages/owomark-react/src/MdxComponentShell.tsx",
14
+ "owomark/packages/owomark-react/src/MdxPreview.tsx",
15
+ "owomark/packages/owomark-react/src/MdxSkeleton.tsx",
16
+ "owomark/packages/owomark-react/src/OwoMarkEditor.tsx",
17
+ "owomark/packages/owomark-react/src/OwoMarkPreview.tsx",
18
+ "owomark/packages/owomark-react/src/config.ts",
19
+ "owomark/packages/owomark-react/src/editor/EditorBlock.tsx",
20
+ "owomark/packages/owomark-react/src/editor/EditorDecorator.tsx",
21
+ "owomark/packages/owomark-react/src/editor/EditorLeaf.tsx",
22
+ "owomark/packages/owomark-react/src/editor/index.ts",
23
+ "owomark/packages/owomark-react/src/highlight-cache-key.ts",
24
+ "owomark/packages/owomark-react/src/highlight-types.ts",
25
+ "owomark/packages/owomark-react/src/highlight-worker-manager.ts",
26
+ "owomark/packages/owomark-react/src/highlight.worker.ts",
27
+ "owomark/packages/owomark-react/src/index.ts",
28
+ "owomark/packages/owomark-react/src/mdx-error.ts",
29
+ "owomark/packages/owomark-react/src/mdx-preview-utils.tsx",
30
+ "owomark/packages/owomark-react/src/mdx-runtime.ts",
31
+ "owomark/packages/owomark-react/src/mdx.worker.ts",
32
+ "owomark/packages/owomark-react/src/slash/SlashMenu.tsx",
33
+ "owomark/packages/owomark-react/src/slash/caret-position.ts",
34
+ "owomark/packages/owomark-react/src/slash/index.ts",
35
+ "owomark/packages/owomark-react/src/toolbar/Toolbar.tsx",
36
+ "owomark/packages/owomark-react/src/toolbar/index.ts",
37
+ "owomark/packages/owomark-react/src/useBlockContext.ts",
38
+ "owomark/packages/owomark-react/src/useMdxPreviewCompilation.ts",
39
+ "owomark/packages/owomark-react/src/useOwoMarkCore.ts",
40
+ "owomark/packages/owomark-react/src/useOwoMarkSharedState.ts",
41
+ "owomark/packages/owomark-react/src/useScrollController.ts",
42
+ "owomark/packages/owomark-react/src/useVirtualList.ts",
43
+ "owomark/packages/owomark-react/tsconfig.json",
44
+ "owomark/packages/owomark-react/tsup.config.ts",
45
+ "package-lock.json"
46
+ ],
47
+ "artifactFiles": [
48
+ "dist/highlight.worker.js",
49
+ "dist/index.d.ts",
50
+ "dist/index.js",
51
+ "dist/mdx.worker.js"
52
+ ],
53
+ "localDependencyFingerprints": {
54
+ "@owomark/core": "32024bd874bc287d8de92d6142487720dd3e31af4477e6f91a54b8e8db3aec4e",
55
+ "@owomark/processor": "edb4a27eeff05c48b721444470988e0e0b715fff56767e9a2da706f44fef425f",
56
+ "@owomark/view": "f70b7037c41905c87554e2d2a912d682e65e87ef960675bb32ee9a3776c4efd6"
57
+ }
58
+ }
@@ -0,0 +1,113 @@
1
+ // src/highlight.worker.ts
2
+ import {
3
+ bundledLanguages,
4
+ bundledLanguagesAlias,
5
+ bundledThemes,
6
+ createHighlighter,
7
+ createJavaScriptRegexEngine
8
+ } from "shiki";
9
+
10
+ // src/highlight-types.ts
11
+ var DEFAULT_HIGHLIGHT_THEME = "vitesse-light";
12
+
13
+ // src/highlight.worker.ts
14
+ var cancelledTaskIds = /* @__PURE__ */ new Set();
15
+ var highlighterPromise = null;
16
+ var loadedLanguages = /* @__PURE__ */ new Set();
17
+ var loadedThemes = /* @__PURE__ */ new Set();
18
+ function resolveLanguage(language) {
19
+ if (!language) {
20
+ return "text";
21
+ }
22
+ const normalized = language.trim().toLowerCase();
23
+ if (normalized in bundledLanguages) {
24
+ return normalized;
25
+ }
26
+ if (normalized in bundledLanguagesAlias) {
27
+ return bundledLanguagesAlias[normalized];
28
+ }
29
+ return "text";
30
+ }
31
+ function resolveTheme(themeKey) {
32
+ return themeKey in bundledThemes ? themeKey : DEFAULT_HIGHLIGHT_THEME;
33
+ }
34
+ async function getHighlighter() {
35
+ if (!highlighterPromise) {
36
+ highlighterPromise = createHighlighter({
37
+ langs: [],
38
+ themes: [DEFAULT_HIGHLIGHT_THEME],
39
+ engine: createJavaScriptRegexEngine()
40
+ });
41
+ loadedThemes.add(DEFAULT_HIGHLIGHT_THEME);
42
+ }
43
+ return highlighterPromise;
44
+ }
45
+ async function ensureAssets(highlighter, language, theme) {
46
+ if (language !== "text" && !loadedLanguages.has(language)) {
47
+ await highlighter.loadLanguage(language);
48
+ loadedLanguages.add(language);
49
+ }
50
+ if (!loadedThemes.has(theme)) {
51
+ await highlighter.loadTheme(theme);
52
+ loadedThemes.add(theme);
53
+ }
54
+ }
55
+ function wrapHighlightedHtml(preHtml, language, theme) {
56
+ const codeTag = `<code data-language="${language ?? "text"}" data-theme="${theme}" style="display:grid">`;
57
+ return preHtml.replace("<pre ", `<pre data-language="${language ?? "text"}" data-theme="${theme}" `).replace("<code>", codeTag).replaceAll('<span class="line">', '<span data-line="">');
58
+ }
59
+ async function highlight(request) {
60
+ const language = resolveLanguage(request.language);
61
+ const theme = resolveTheme(request.themeKey);
62
+ const highlighter = await getHighlighter();
63
+ await ensureAssets(highlighter, language, theme);
64
+ const html = highlighter.codeToHtml(request.code, {
65
+ lang: language,
66
+ theme
67
+ });
68
+ return wrapHighlightedHtml(html, request.language, theme);
69
+ }
70
+ self.onmessage = (event) => {
71
+ const message = event.data;
72
+ if (message.type === "cancel") {
73
+ cancelledTaskIds.add(message.taskId);
74
+ return;
75
+ }
76
+ void handleHighlight(message);
77
+ };
78
+ async function handleHighlight(request) {
79
+ const taskId = request.requestId;
80
+ try {
81
+ const html = await highlight(request);
82
+ if (cancelledTaskIds.has(taskId)) {
83
+ cancelledTaskIds.delete(taskId);
84
+ return;
85
+ }
86
+ self.postMessage({
87
+ type: "highlight-result",
88
+ taskId,
89
+ requestId: request.requestId,
90
+ documentVersion: request.documentVersion,
91
+ blockInstanceId: request.blockInstanceId,
92
+ cacheKey: request.cacheKey,
93
+ ok: true,
94
+ html
95
+ });
96
+ } catch (error) {
97
+ if (cancelledTaskIds.has(taskId)) {
98
+ cancelledTaskIds.delete(taskId);
99
+ return;
100
+ }
101
+ const message = error instanceof Error ? error.message : "Code highlighting failed";
102
+ self.postMessage({
103
+ type: "highlight-error",
104
+ taskId,
105
+ requestId: request.requestId,
106
+ documentVersion: request.documentVersion,
107
+ blockInstanceId: request.blockInstanceId,
108
+ cacheKey: request.cacheKey,
109
+ ok: false,
110
+ error: message
111
+ });
112
+ }
113
+ }
package/dist/index.d.ts CHANGED
@@ -1,12 +1,19 @@
1
1
  import * as react from 'react';
2
- import { Ref, MutableRefObject, CSSProperties, ReactNode, ComponentType } from 'react';
3
- import { IndentMode, OwoMarkSelection, OwoMarkCommands, OwoMarkCore, OwoMarkSharedStateController, OwoMarkSharedStateStore, PreviewBlock, CreateSharedStateOptions, OwoMarkSharedState, OwoMarkDocument, SlashState, BlockContext, BlockNode, VisibleRange, VirtualRow, Decorator } from '@owomark/core';
4
- export { BlockContext, BlockContextType, BlockInsertType, CommandDefinition, OwoMarkCommands, OwoMarkCore, OwoMarkEditorInstance, OwoMarkSelection, OwoMarkSharedState, OwoMarkSharedStateController, OwoMarkSharedStateStore, PreviewBlock, PreviewBlockKind, SlashState } from '@owomark/core';
2
+ import react__default, { Ref, MutableRefObject, CSSProperties, ReactNode, ComponentType } from 'react';
3
+ import { IndentMode, OwoMarkSelection, OwoMarkCommands, OwoMarkCore, OwoMarkSharedStateController, OwoMarkScrollController, OwoMarkSharedStateStore, PreviewBlock, CreateSharedStateOptions, OwoMarkSharedState, OwoMarkDocument, SlashState, BlockContext, BlockNode, VisibleRange, VirtualRow, Decorator } from '@owomark/core';
4
+ export { BlockContext, BlockContextType, BlockInsertType, CommandDefinition, GlobalScrollPosition, OwoMarkCommands, OwoMarkCore, OwoMarkScrollController, OwoMarkScrollProjectionSegment, OwoMarkScrollProjectionSnapshot, OwoMarkSelection, OwoMarkSharedState, OwoMarkSharedStateController, OwoMarkSharedStateStore, OwoMarkSurfaceGeometrySegment, OwoMarkSurfaceGeometrySnapshot, PreviewBlock, PreviewBlockKind, ScrollResolutionResult, ScrollSurface, ScrollToScrollPositionOptions, ScrollToScrollPositionResult, SlashState, ViewportMetrics } from '@owomark/core';
5
5
  import { OwoMarkThemeName, PreviewStrategy, PreviewRendererRegistry, PreviewRenderContext } from '@owomark/view';
6
6
  export { OwoMarkThemeName, PreviewRenderContext, PreviewRenderResult, PreviewRendererDefinition, PreviewRendererRegistry, THEME_DARK_CLASS, THEME_LIGHT_CLASS, getThemeClassName } from '@owomark/view';
7
- import { OwoMarkProcessorOptions } from '@owomark/processor';
7
+ import { OwoMarkProcessorOptions, PluginDescriptor, PluginEntry, MdxComponentMap } from '@owomark/processor';
8
+ export { registerPlugin } from '@owomark/processor';
8
9
  import * as react_jsx_runtime from 'react/jsx-runtime';
10
+ import { createScrollController } from '@owomark/core/browser';
9
11
 
12
+ type BuiltInComponentCommandId = 'component-note' | 'component-callout' | 'component-code-demo' | 'component-details' | 'component-steps' | 'component-tabs' | 'component-link-card' | 'component-file-tree';
13
+ type OwoMarkToolbarConfig = {
14
+ componentCommands?: BuiltInComponentCommandId[];
15
+ };
16
+ declare const DEFAULT_TOOLBAR_COMPONENT_COMMANDS: BuiltInComponentCommandId[];
10
17
  type OwoMarkEditorConfig = {
11
18
  /** Indent mode: 'auto' | '2' | '4'. Default: 'auto'. */
12
19
  indentMode?: IndentMode;
@@ -14,12 +21,16 @@ type OwoMarkEditorConfig = {
14
21
  enableSideAnnotation?: boolean;
15
22
  /** Enable math (KaTeX) rendering. Default: true. */
16
23
  enableMath?: boolean;
24
+ /** Enable built-in component extension syntax (:::note, :kbd, etc.). Default: true. */
25
+ enableComponents?: boolean;
17
26
  /** Enable fenced markdown sandbox rendering. Default: true. */
18
27
  enableMarkdownSandbox?: boolean;
19
28
  /** Minimum backtick count required for markdown sandbox fences. Default: 4. */
20
29
  markdownSandbox?: {
21
30
  outerFenceTicks?: number;
22
31
  };
32
+ /** Toolbar configuration for component quick-insert buttons. */
33
+ toolbarConfig?: OwoMarkToolbarConfig;
23
34
  };
24
35
  declare const DEFAULT_EDITOR_CONFIG: Required<OwoMarkEditorConfig>;
25
36
  declare function resolveEditorConfig(config?: OwoMarkEditorConfig): Required<OwoMarkEditorConfig>;
@@ -47,6 +58,7 @@ type OwoMarkEditorProps = {
47
58
  * shared state controller.
48
59
  */
49
60
  controller?: OwoMarkSharedStateController;
61
+ scrollController?: OwoMarkScrollController;
50
62
  indentMode?: IndentMode;
51
63
  ariaLabel?: string;
52
64
  /**
@@ -57,28 +69,114 @@ type OwoMarkEditorProps = {
57
69
  };
58
70
  declare const OwoMarkEditor: react.ForwardRefExoticComponent<OwoMarkEditorProps & react.RefAttributes<HTMLDivElement>>;
59
71
 
72
+ type OwoMarkMdxOptions = {
73
+ enableMath?: boolean;
74
+ enableSideAnnotation?: boolean;
75
+ enableCodeHighlight?: boolean;
76
+ sourceAnchors?: boolean;
77
+ forceFullDocumentCompile?: boolean;
78
+ extraRemarkDescriptors?: PluginDescriptor[];
79
+ extraRehypeDescriptors?: PluginDescriptor[];
80
+ extraRemarkPlugins?: PluginEntry[];
81
+ extraRehypePlugins?: PluginEntry[];
82
+ components?: MdxComponentMap;
83
+ };
84
+
85
+ type OwoMarkScrollSyncMode = 'off' | 'bidirectional';
60
86
  type OwoMarkPreviewProps = {
61
87
  state: OwoMarkSharedStateStore;
88
+ markdown?: string;
62
89
  className?: string;
63
90
  strategy?: PreviewStrategy;
64
91
  themeKey?: string;
65
92
  registry?: PreviewRendererRegistry;
66
93
  viewportFirst?: boolean;
67
94
  ariaLabel?: string;
68
- /**
69
- * External block renderer. When provided, the preview engine uses this
70
- * to render each block instead of the built-in lightweight renderer.
71
- * Typically backed by the host's unified/remark/rehype/Shiki pipeline.
72
- *
73
- * Engine is recreated when this prop transitions between defined/undefined.
74
- * Identity changes of the function itself do NOT cause engine recreation —
75
- * the latest reference is always used via a stable ref.
76
- */
95
+ scrollController?: OwoMarkScrollController;
96
+ scrollSync?: OwoMarkScrollSyncMode;
97
+ onScroll?: react__default.UIEventHandler<HTMLDivElement>;
77
98
  renderBlock?: (block: PreviewBlock, context: PreviewRenderContext) => Promise<string>;
78
- /** Called after each successful DOM update. Use to trigger scroll sync. */
99
+ mdx?: OwoMarkMdxOptions;
79
100
  onContentUpdate?: () => void;
80
101
  };
81
- declare const OwoMarkPreview: (props: OwoMarkPreviewProps) => react_jsx_runtime.JSX.Element;
102
+ declare const OwoMarkPreview: react__default.ForwardRefExoticComponent<OwoMarkPreviewProps & react__default.RefAttributes<HTMLDivElement>>;
103
+
104
+ type HighlightRequest = {
105
+ requestId: string;
106
+ documentVersion: number;
107
+ blockInstanceId: string;
108
+ cacheKey: string;
109
+ code: string;
110
+ language: string | null;
111
+ themeKey: string;
112
+ meta: string | null;
113
+ };
114
+ type HighlightSuccessResponse = {
115
+ requestId: string;
116
+ documentVersion: number;
117
+ blockInstanceId: string;
118
+ cacheKey: string;
119
+ ok: true;
120
+ html: string;
121
+ };
122
+ type HighlightErrorResponse = {
123
+ requestId: string;
124
+ documentVersion: number;
125
+ blockInstanceId: string;
126
+ cacheKey: string;
127
+ ok: false;
128
+ error: string;
129
+ };
130
+ type HighlightResponse = HighlightSuccessResponse | HighlightErrorResponse;
131
+ type HighlightTaskHandle = {
132
+ request: HighlightRequest;
133
+ promise: Promise<HighlightResponse>;
134
+ cancel: () => void;
135
+ };
136
+
137
+ type HighlightWorkerManagerOptions = {
138
+ timeoutMs?: number;
139
+ cacheMaxEntries?: number;
140
+ workerFactory?: () => Worker | null;
141
+ };
142
+ declare class HighlightWorkerManager {
143
+ private readonly timeoutMs;
144
+ private readonly cacheMaxEntries;
145
+ private readonly workerFactory?;
146
+ private worker;
147
+ private workerFailureCount;
148
+ private requestCounter;
149
+ private readonly cache;
150
+ private readonly inflightByCacheKey;
151
+ private readonly inflightByTaskId;
152
+ constructor(options?: HighlightWorkerManagerOptions);
153
+ highlight(input: Omit<HighlightRequest, 'requestId' | 'themeKey'> & {
154
+ themeKey?: string;
155
+ }): HighlightTaskHandle;
156
+ resetForTesting(): void;
157
+ private ensureWorker;
158
+ private startTask;
159
+ private handleWorkerMessage;
160
+ private cancelRequest;
161
+ private cancelTask;
162
+ private finishTaskWithError;
163
+ private clearTaskTimeout;
164
+ private getCached;
165
+ private setCached;
166
+ }
167
+
168
+ type AsyncCodeBlockProps = {
169
+ code: string;
170
+ language: string | null;
171
+ meta: string | null;
172
+ themeKey: string;
173
+ documentVersion: number;
174
+ className?: string;
175
+ codeProps?: Record<string, unknown>;
176
+ preProps?: Record<string, unknown>;
177
+ manager?: HighlightWorkerManager;
178
+ };
179
+ declare function AsyncCodeBlock(props: AsyncCodeBlockProps): react_jsx_runtime.JSX.Element;
82
180
 
83
181
  type UseOwoMarkSharedStateOptions = CreateSharedStateOptions;
84
182
  /**
@@ -93,6 +191,7 @@ declare function useOwoMarkSharedState(options?: UseOwoMarkSharedStateOptions):
93
191
  * Returns the current OwoMarkSharedState, triggering re-renders on changes.
94
192
  */
95
193
  declare function useSharedStateSnapshot(controller: OwoMarkSharedStateController): OwoMarkSharedState;
194
+ declare function useSharedStateSelector<T>(store: OwoMarkSharedStateStore, selector: (state: OwoMarkSharedState) => T, isEqual?: (prev: T, next: T) => boolean): T;
96
195
 
97
196
  /**
98
197
  * React hook that creates and manages an OwoMarkCore instance
@@ -125,6 +224,9 @@ declare function useOwoMarkCore(options: UseOwoMarkCoreOptions): UseOwoMarkCoreR
125
224
 
126
225
  declare function useBlockContext(core: OwoMarkCore): BlockContext;
127
226
 
227
+ type UseScrollControllerReturn = ReturnType<typeof createScrollController>;
228
+ declare function useScrollController(controller: OwoMarkSharedStateController): UseScrollControllerReturn;
229
+
128
230
  type UseVirtualListOptions = {
129
231
  blocks: readonly BlockNode[];
130
232
  /** The scrollable container element. */
@@ -210,39 +312,35 @@ declare function computeMenuPosition(caret: CaretRect, menuHeight: number, menuW
210
312
  left: number;
211
313
  };
212
314
 
315
+ type ToolbarProps = {
316
+ core: OwoMarkCore;
317
+ toolbarConfig: OwoMarkToolbarConfig;
318
+ };
319
+ declare const Toolbar: react.NamedExoticComponent<ToolbarProps>;
320
+
213
321
  type MdxSkeletonProps = {
214
- /** Height in pixels for the skeleton placeholder. */
215
322
  height?: number;
216
- /** Number of shimmer lines to show. Default: 3. */
217
323
  lines?: number;
218
324
  className?: string;
219
325
  style?: CSSProperties;
220
326
  };
221
- /**
222
- * Lightweight skeleton loading indicator for MDX component placeholders.
223
- * Pure CSS animation — no external UI library dependency.
224
- */
225
327
  declare function MdxSkeleton({ height, lines, className, style }: MdxSkeletonProps): react_jsx_runtime.JSX.Element;
226
328
 
227
329
  type MdxComponentShellProps = {
228
- /** Component display name, used as cache key for height estimation. */
229
330
  name: string;
331
+ propsFingerprint?: string;
230
332
  children: ReactNode;
231
333
  };
232
- /**
233
- * Wraps an MDX component to provide:
234
- * 1. Skeleton placeholder with estimated height before first paint
235
- * 2. Real-height measurement after mount via ResizeObserver
236
- * 3. Height caching so subsequent renders of the same component type
237
- * use a better estimate, reducing layout shift.
238
- */
239
- declare function MdxComponentShell({ name, children }: MdxComponentShellProps): react_jsx_runtime.JSX.Element;
240
- /**
241
- * Create a wrapped version of an MDX component that renders inside
242
- * MdxComponentShell for skeleton loading + height management.
243
- */
334
+ declare function MdxComponentShell({ name, propsFingerprint, children }: MdxComponentShellProps): react_jsx_runtime.JSX.Element;
244
335
  declare function wrapWithShell<P extends Record<string, any>>(name: string, Component: ComponentType<P>): ComponentType<P>;
245
336
  /** Clear the height cache (useful for testing or theme changes). */
246
337
  declare function clearComponentHeightCache(): void;
247
338
 
248
- export { type CaretRect, DEFAULT_EDITOR_CONFIG, EditorBlock, type EditorBlockProps, EditorDecorator, type EditorDecoratorProps, EditorLeaf, type EditorLeafProps, MdxComponentShell, type MdxComponentShellProps, MdxSkeleton, type MdxSkeletonProps, OwoMarkEditor, type OwoMarkEditorConfig, type OwoMarkEditorProps, OwoMarkPreview, type OwoMarkPreviewProps, SlashMenu, type SlashMenuProps, type UseOwoMarkCoreOptions, type UseOwoMarkCoreReturn, type UseOwoMarkSharedStateOptions, type UseVirtualListOptions, type UseVirtualListResult, clearComponentHeightCache, computeMenuPosition, deriveProcessorOptions, getCaretRect, resolveEditorConfig, useBlockContext, useOwoMarkCore, useOwoMarkSharedState, useSharedStateSnapshot, useVirtualList, wrapWithShell };
339
+ type CancellableCompile = {
340
+ promise: Promise<string>;
341
+ cancel: () => void;
342
+ };
343
+ declare function acquireMdxWorker(): void;
344
+ declare function releaseMdxWorker(): void;
345
+
346
+ export { AsyncCodeBlock, type BuiltInComponentCommandId, type CancellableCompile, type CaretRect, DEFAULT_EDITOR_CONFIG, DEFAULT_TOOLBAR_COMPONENT_COMMANDS, EditorBlock, type EditorBlockProps, EditorDecorator, type EditorDecoratorProps, EditorLeaf, type EditorLeafProps, MdxComponentShell, type MdxComponentShellProps, MdxSkeleton, type MdxSkeletonProps, OwoMarkEditor, type OwoMarkEditorConfig, type OwoMarkEditorProps, type OwoMarkMdxOptions, OwoMarkPreview, type OwoMarkPreviewProps, type OwoMarkScrollSyncMode, type OwoMarkToolbarConfig, SlashMenu, type SlashMenuProps, Toolbar, type ToolbarProps, type UseOwoMarkCoreOptions, type UseOwoMarkCoreReturn, type UseOwoMarkSharedStateOptions, type UseScrollControllerReturn, type UseVirtualListOptions, type UseVirtualListResult, acquireMdxWorker, clearComponentHeightCache, computeMenuPosition, deriveProcessorOptions, getCaretRect, releaseMdxWorker, resolveEditorConfig, useBlockContext, useOwoMarkCore, useOwoMarkSharedState, useScrollController, useSharedStateSelector, useSharedStateSnapshot, useVirtualList, wrapWithShell };