typewright 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +168 -0
  3. package/SPEC.md +327 -0
  4. package/dist/chunk-CZQO7TTL.js +1533 -0
  5. package/dist/chunk-CZQO7TTL.js.map +1 -0
  6. package/dist/chunk-KNEKNZXK.js +286 -0
  7. package/dist/chunk-KNEKNZXK.js.map +1 -0
  8. package/dist/chunk-M6IVEMXO.js +1398 -0
  9. package/dist/chunk-M6IVEMXO.js.map +1 -0
  10. package/dist/chunk-NJ7PJKHN.js +652 -0
  11. package/dist/chunk-NJ7PJKHN.js.map +1 -0
  12. package/dist/commands-Z3ndUSza.d.cts +221 -0
  13. package/dist/commands-Z3ndUSza.d.ts +221 -0
  14. package/dist/core/index.cjs +2952 -0
  15. package/dist/core/index.cjs.map +1 -0
  16. package/dist/core/index.d.cts +410 -0
  17. package/dist/core/index.d.ts +410 -0
  18. package/dist/core/index.js +4 -0
  19. package/dist/core/index.js.map +1 -0
  20. package/dist/mdx/index.cjs +662 -0
  21. package/dist/mdx/index.cjs.map +1 -0
  22. package/dist/mdx/index.d.cts +252 -0
  23. package/dist/mdx/index.d.ts +252 -0
  24. package/dist/mdx/index.js +3 -0
  25. package/dist/mdx/index.js.map +1 -0
  26. package/dist/react/index.cjs +7439 -0
  27. package/dist/react/index.cjs.map +1 -0
  28. package/dist/react/index.d.cts +140 -0
  29. package/dist/react/index.d.ts +140 -0
  30. package/dist/react/index.js +3644 -0
  31. package/dist/react/index.js.map +1 -0
  32. package/dist/streaming/index.cjs +1494 -0
  33. package/dist/streaming/index.cjs.map +1 -0
  34. package/dist/streaming/index.d.cts +64 -0
  35. package/dist/streaming/index.d.ts +64 -0
  36. package/dist/streaming/index.js +4 -0
  37. package/dist/streaming/index.js.map +1 -0
  38. package/dist/types-CX1GOx0Y.d.cts +319 -0
  39. package/dist/types-CX1GOx0Y.d.ts +319 -0
  40. package/package.json +128 -0
@@ -0,0 +1,319 @@
1
+ /**
2
+ * Typewright — public type surface.
3
+ *
4
+ * These types ARE the API contract (spec-as-code). The from-scratch engine that
5
+ * fulfils them — document model, incremental block parser, virtualized DOM view,
6
+ * anticipatory streaming renderer — is described in SPEC.md and is in progress.
7
+ *
8
+ * The core types here intentionally carry NO React dependency, so the headless
9
+ * engine (`typewright/core`) is usable without React. React-specific types live
10
+ * in `src/react`.
11
+ */
12
+ /**
13
+ * How the document is presented and edited.
14
+ *
15
+ * - `edit` Raw Markdown/MDX source with syntax highlighting.
16
+ * - `unified` Obsidian-style live preview: formatting renders inline, and the
17
+ * raw syntax is revealed only around the caret/selection. Flagship.
18
+ * - `preview` Fully-rendered rich preview that is still editable.
19
+ * - `read` Fully-rendered, non-editable output.
20
+ */
21
+ type EditorMode = 'edit' | 'unified' | 'preview' | 'read';
22
+ interface GfmFeatures {
23
+ tables: boolean;
24
+ taskLists: boolean;
25
+ strikethrough: boolean;
26
+ autolinks: boolean;
27
+ footnotes: boolean;
28
+ }
29
+ interface MermaidOptions {
30
+ enabled: boolean;
31
+ /**
32
+ * Mermaid theme name (e.g. `'default'`, `'forest'`). Reserved: the value is
33
+ * not yet applied to the sandboxed diagram — the sandbox currently follows the
34
+ * editor's light/dark appearance only. Kept as forward-compatible API surface.
35
+ */
36
+ theme?: string;
37
+ /**
38
+ * Supplies the Mermaid engine to run **inside** the opaque-origin sandbox.
39
+ * Returns the engine's JavaScript *source*, which Typewright inlines as an
40
+ * `<script>` in the sandbox document. Source is used (rather than a script
41
+ * URL) deliberately: the sandbox CSP is `script-src 'unsafe-inline'` only, so
42
+ * an inline engine needs no CSP relaxation and no cross-origin fetch. The
43
+ * injected source is expected to expose either a global
44
+ * `self.__twMermaidRender(src): Promise<string>` returning SVG, or the
45
+ * standard `self.mermaid` object (`mermaid.render(id, src)`). May be async so
46
+ * the host can lazy-load the engine. Without it, `mermaid` fences render as a
47
+ * plain code block (unchanged v0.1 behaviour).
48
+ */
49
+ getEngine?: () => Promise<string> | string;
50
+ }
51
+ interface MathOptions {
52
+ enabled: boolean;
53
+ /**
54
+ * Advisory hint only, reserved: the renderer does not read `engine` — math is
55
+ * rendered solely via the host-supplied {@link MathOptions.render} function
56
+ * (regardless of this value). Kept as forward-compatible API surface.
57
+ */
58
+ engine?: 'katex' | 'custom';
59
+ /**
60
+ * Host-supplied math renderer — the actual path that renders math. Given the
61
+ * raw `$…$` / `$$…$$` source and whether it is display (block) math, returns
62
+ * **already-sanitized** HTML that the renderer inserts verbatim. The host owns
63
+ * sanitization (e.g. KaTeX with `trust: false`). Without a `render` fn, math
64
+ * renders as escaped source — enabling math without one has no visible effect.
65
+ */
66
+ render?: (src: string, display: boolean) => string;
67
+ }
68
+ interface SyntaxHighlightOptions {
69
+ enabled: boolean;
70
+ /**
71
+ * Highlight theme name. Reserved: not yet applied — token colours currently
72
+ * follow the editor's built-in native theme (light/dark) for both the editor
73
+ * and previews. Kept as forward-compatible API surface.
74
+ */
75
+ theme?: string;
76
+ }
77
+ /**
78
+ * How MDX's JSX/TS is transformed to runnable JavaScript before sandboxed
79
+ * execution. This is the single conceded dependency boundary (see SPEC.md §7):
80
+ * the Markdown/MDX *markup* is parsed by Typewright's own parser, but turning
81
+ * JSX/TS into plain JS is delegated to a wasm transform or a host-supplied fn.
82
+ */
83
+ type MdxTransform = 'wasm-esbuild' | 'wasm-swc' | 'constrained' | ((code: string, meta: {
84
+ filename?: string;
85
+ }) => string | Promise<string>);
86
+ interface SandboxOptions {
87
+ /**
88
+ * Must remain false. MDX executes in an `iframe srcdoc sandbox="allow-scripts"`
89
+ * with an opaque origin (no `allow-same-origin`) so an XSS payload cannot reach
90
+ * the host — Electron-safe (blocks the XSS→RCE path).
91
+ */
92
+ allowSameOrigin?: false;
93
+ /** Extra Content-Security-Policy appended to the sandbox document. */
94
+ csp?: string;
95
+ /** Proxy for host/network access requested by an MDX component via postMessage. */
96
+ onHostMessage?: (message: unknown) => void;
97
+ }
98
+ /** Component name → component. Loose in core to avoid a React type dependency. */
99
+ type ComponentMap = Record<string, unknown>;
100
+ interface MdxOptions {
101
+ enabled: boolean;
102
+ /** Components made available to MDX (`<Chart/>`, `<Callout/>`, …). */
103
+ components?: ComponentMap;
104
+ transform?: MdxTransform;
105
+ sandbox?: SandboxOptions;
106
+ }
107
+ interface FoldingOptions {
108
+ enabled: boolean;
109
+ /** Show the fold gutter + per-heading fold affordance. */
110
+ showGutter?: boolean;
111
+ /** localStorage key to persist fold state across reloads. */
112
+ persistKey?: string;
113
+ }
114
+ interface Extensions {
115
+ /** GitHub Flavored Markdown. `true` enables the full set. */
116
+ gfm?: boolean | Partial<GfmFeatures>;
117
+ /** MDX v3 (JSX + ESM + expressions). */
118
+ mdx?: boolean | MdxOptions;
119
+ mermaid?: boolean | MermaidOptions;
120
+ math?: boolean | MathOptions;
121
+ syntaxHighlight?: boolean | SyntaxHighlightOptions;
122
+ }
123
+ interface KeymapOptions {
124
+ /** Base keymap preset. `default` gives standard text-editing shortcuts. */
125
+ preset?: 'default' | 'none';
126
+ /** Override or add bindings: `"Mod-b" -> "toggleStrong"`. */
127
+ bindings?: Record<string, string>;
128
+ }
129
+ interface ThemeOptions {
130
+ appearance?: 'light' | 'dark' | 'auto';
131
+ /** CSS custom-property overrides (`--tw-accent`, …). */
132
+ tokens?: Record<string, string>;
133
+ }
134
+ interface DocPosition {
135
+ /** UTF-16 offset into the document string. */
136
+ offset: number;
137
+ line: number;
138
+ column: number;
139
+ }
140
+ interface DocRange {
141
+ from: number;
142
+ to: number;
143
+ }
144
+ interface DocSelection {
145
+ main: DocRange;
146
+ ranges: DocRange[];
147
+ }
148
+ /** A single edit expressed as a range replacement (CodeMirror-style). */
149
+ interface DocChange {
150
+ from: number;
151
+ to: number;
152
+ insert: string;
153
+ }
154
+ /** A single reply within a comment thread. */
155
+ interface CommentReply {
156
+ id: string;
157
+ author: string;
158
+ body: string;
159
+ /** ISO-8601 timestamp; host-supplied. */
160
+ createdAt?: string;
161
+ }
162
+ /** A comment thread anchored to a document range. */
163
+ interface CommentThread {
164
+ id: string;
165
+ /** Document offset range the thread is attached to. */
166
+ anchor: {
167
+ from: number;
168
+ to: number;
169
+ };
170
+ /** Snapshot of the anchored text at creation time. */
171
+ quote?: string;
172
+ author: string;
173
+ body: string;
174
+ /** ISO-8601 timestamp; host-supplied. */
175
+ createdAt?: string;
176
+ resolved?: boolean;
177
+ /** Emoji → list of user ids that reacted with it. */
178
+ reactions?: Record<string, string[]>;
179
+ replies: CommentReply[];
180
+ }
181
+ /** Comments configuration: threads in, edit intents out. */
182
+ interface CommentsOptions {
183
+ enabled?: boolean;
184
+ /** All threads to render; the host is the source of truth. */
185
+ threads: CommentThread[];
186
+ /** The current user, used to author new threads/replies/reactions. */
187
+ me?: {
188
+ id: string;
189
+ name: string;
190
+ };
191
+ /** Fired when the user creates a thread from a selection. */
192
+ onCreate?: (t: {
193
+ anchor: {
194
+ from: number;
195
+ to: number;
196
+ };
197
+ quote: string;
198
+ body: string;
199
+ }) => void;
200
+ onReply?: (threadId: string, body: string) => void;
201
+ onReact?: (threadId: string, emoji: string) => void;
202
+ onResolve?: (threadId: string, resolved: boolean) => void;
203
+ onDelete?: (threadId: string) => void;
204
+ }
205
+ /** A remote collaborator whose cursor/selection is rendered live. */
206
+ interface PresencePeer {
207
+ id: string;
208
+ name: string;
209
+ /** Cursor/selection colour (any CSS colour). */
210
+ color?: string;
211
+ /** Current selection as a document offset range; caret if `from === to`. */
212
+ cursor?: {
213
+ from: number;
214
+ to: number;
215
+ };
216
+ }
217
+ /** A host-extensible entry surfaced in the command palette. */
218
+ interface SettingsCommand {
219
+ id: string;
220
+ label: string;
221
+ run: () => void;
222
+ }
223
+ /** Settings panel + ⌘K command palette configuration. */
224
+ interface SettingsOptions {
225
+ enabled?: boolean;
226
+ /** Extra palette entries appended to the built-in commands. */
227
+ commands?: SettingsCommand[];
228
+ }
229
+ interface EditorConfig {
230
+ value?: string;
231
+ mode?: EditorMode;
232
+ /**
233
+ * How the raw syntax markers are revealed in `unified` mode.
234
+ *
235
+ * - `block` (default) Click-to-reveal: clicking a rendered block swaps the
236
+ * whole block for its raw Markdown source — today's behaviour.
237
+ * - `caret` Per-marker reveal around the caret: only the markers the caret
238
+ * sits on (a `**`, a `](url)`, a fence line, …) reveal, live, as
239
+ * the caret moves. Opt-in; contentEditable-backed, with IME handled
240
+ * by the platform's composition (not reimplemented).
241
+ *
242
+ * Additive and backward-compatible — omitting it keeps the `block` default,
243
+ * so existing embeds are unaffected.
244
+ */
245
+ unifiedReveal?: 'block' | 'caret';
246
+ extensions?: Extensions;
247
+ folding?: boolean | FoldingOptions;
248
+ readOnly?: boolean;
249
+ placeholder?: string;
250
+ keymap?: KeymapOptions;
251
+ theme?: ThemeOptions;
252
+ /**
253
+ * Show the built-in formatting toolbar (edit/unified modes). `true`/`"docked"`
254
+ * pins it; `"floating"` reveals it on hover/focus.
255
+ */
256
+ toolbar?: boolean | 'docked' | 'floating';
257
+ /** Lines rendered outside the viewport bounds (virtualization overscan). */
258
+ overscan?: number;
259
+ /**
260
+ * Inline comments & threads. `true` enables the surface with no threads;
261
+ * pass {@link CommentsOptions} to supply threads and edit callbacks.
262
+ */
263
+ comments?: boolean | CommentsOptions;
264
+ /** Remote collaborators whose cursors/selections render live (data-in). */
265
+ presence?: PresencePeer[];
266
+ /**
267
+ * Settings panel + ⌘K command palette. `true` enables the built-ins;
268
+ * pass {@link SettingsOptions} to append host commands.
269
+ */
270
+ settings?: boolean | SettingsOptions;
271
+ }
272
+ interface EditorEvents {
273
+ onChange?: (value: string, change: DocChange) => void;
274
+ onSelectionChange?: (selection: DocSelection) => void;
275
+ onModeChange?: (mode: EditorMode) => void;
276
+ }
277
+ /**
278
+ * Which incomplete constructs are optimistically rendered mid-stream.
279
+ * e.g. `emphasis` renders `*bo` as in-progress bold before the closing `*`.
280
+ */
281
+ interface AnticipationOptions {
282
+ emphasis?: boolean;
283
+ strong?: boolean;
284
+ code?: boolean;
285
+ strikethrough?: boolean;
286
+ links?: boolean;
287
+ headings?: boolean;
288
+ /** An unterminated ```` ``` ```` opens an in-progress code block. */
289
+ fences?: boolean;
290
+ listItems?: boolean;
291
+ tables?: boolean;
292
+ /** Partial JSX elements render a skeleton until the tag/props complete. */
293
+ jsx?: boolean;
294
+ }
295
+ interface StreamOptions {
296
+ /** Optimistically render incomplete formatting as tokens arrive. */
297
+ anticipate?: boolean | AnticipationOptions;
298
+ /** Skeleton rendered for a component whose props are still streaming. */
299
+ componentFallback?: unknown;
300
+ /** Reveal characters smoothly rather than in raw chunk jumps. */
301
+ smooth?: boolean | {
302
+ charsPerSecond: number;
303
+ };
304
+ }
305
+ /** Imperative handle for feeding a token stream into a preview. */
306
+ interface StreamController {
307
+ /** Append a chunk (token/word/sentence) to the stream. */
308
+ push(chunk: string): void;
309
+ /** Replace the whole buffer (e.g. a corrected re-generation). */
310
+ replace(full: string): void;
311
+ /** Mark the stream complete; resolves any anticipated formatting. */
312
+ end(): void;
313
+ /** Clear and start over. */
314
+ reset(): void;
315
+ readonly text: string;
316
+ readonly complete: boolean;
317
+ }
318
+
319
+ export type { AnticipationOptions as A, CommentReply as C, DocChange as D, EditorConfig as E, FoldingOptions as F, GfmFeatures as G, KeymapOptions as K, MathOptions as M, PresencePeer as P, SandboxOptions as S, ThemeOptions as T, EditorEvents as a, DocSelection as b, CommentThread as c, CommentsOptions as d, ComponentMap as e, DocPosition as f, DocRange as g, EditorMode as h, Extensions as i, MdxOptions as j, MdxTransform as k, MermaidOptions as l, SettingsCommand as m, SettingsOptions as n, StreamController as o, StreamOptions as p, SyntaxHighlightOptions as q };
@@ -0,0 +1,319 @@
1
+ /**
2
+ * Typewright — public type surface.
3
+ *
4
+ * These types ARE the API contract (spec-as-code). The from-scratch engine that
5
+ * fulfils them — document model, incremental block parser, virtualized DOM view,
6
+ * anticipatory streaming renderer — is described in SPEC.md and is in progress.
7
+ *
8
+ * The core types here intentionally carry NO React dependency, so the headless
9
+ * engine (`typewright/core`) is usable without React. React-specific types live
10
+ * in `src/react`.
11
+ */
12
+ /**
13
+ * How the document is presented and edited.
14
+ *
15
+ * - `edit` Raw Markdown/MDX source with syntax highlighting.
16
+ * - `unified` Obsidian-style live preview: formatting renders inline, and the
17
+ * raw syntax is revealed only around the caret/selection. Flagship.
18
+ * - `preview` Fully-rendered rich preview that is still editable.
19
+ * - `read` Fully-rendered, non-editable output.
20
+ */
21
+ type EditorMode = 'edit' | 'unified' | 'preview' | 'read';
22
+ interface GfmFeatures {
23
+ tables: boolean;
24
+ taskLists: boolean;
25
+ strikethrough: boolean;
26
+ autolinks: boolean;
27
+ footnotes: boolean;
28
+ }
29
+ interface MermaidOptions {
30
+ enabled: boolean;
31
+ /**
32
+ * Mermaid theme name (e.g. `'default'`, `'forest'`). Reserved: the value is
33
+ * not yet applied to the sandboxed diagram — the sandbox currently follows the
34
+ * editor's light/dark appearance only. Kept as forward-compatible API surface.
35
+ */
36
+ theme?: string;
37
+ /**
38
+ * Supplies the Mermaid engine to run **inside** the opaque-origin sandbox.
39
+ * Returns the engine's JavaScript *source*, which Typewright inlines as an
40
+ * `<script>` in the sandbox document. Source is used (rather than a script
41
+ * URL) deliberately: the sandbox CSP is `script-src 'unsafe-inline'` only, so
42
+ * an inline engine needs no CSP relaxation and no cross-origin fetch. The
43
+ * injected source is expected to expose either a global
44
+ * `self.__twMermaidRender(src): Promise<string>` returning SVG, or the
45
+ * standard `self.mermaid` object (`mermaid.render(id, src)`). May be async so
46
+ * the host can lazy-load the engine. Without it, `mermaid` fences render as a
47
+ * plain code block (unchanged v0.1 behaviour).
48
+ */
49
+ getEngine?: () => Promise<string> | string;
50
+ }
51
+ interface MathOptions {
52
+ enabled: boolean;
53
+ /**
54
+ * Advisory hint only, reserved: the renderer does not read `engine` — math is
55
+ * rendered solely via the host-supplied {@link MathOptions.render} function
56
+ * (regardless of this value). Kept as forward-compatible API surface.
57
+ */
58
+ engine?: 'katex' | 'custom';
59
+ /**
60
+ * Host-supplied math renderer — the actual path that renders math. Given the
61
+ * raw `$…$` / `$$…$$` source and whether it is display (block) math, returns
62
+ * **already-sanitized** HTML that the renderer inserts verbatim. The host owns
63
+ * sanitization (e.g. KaTeX with `trust: false`). Without a `render` fn, math
64
+ * renders as escaped source — enabling math without one has no visible effect.
65
+ */
66
+ render?: (src: string, display: boolean) => string;
67
+ }
68
+ interface SyntaxHighlightOptions {
69
+ enabled: boolean;
70
+ /**
71
+ * Highlight theme name. Reserved: not yet applied — token colours currently
72
+ * follow the editor's built-in native theme (light/dark) for both the editor
73
+ * and previews. Kept as forward-compatible API surface.
74
+ */
75
+ theme?: string;
76
+ }
77
+ /**
78
+ * How MDX's JSX/TS is transformed to runnable JavaScript before sandboxed
79
+ * execution. This is the single conceded dependency boundary (see SPEC.md §7):
80
+ * the Markdown/MDX *markup* is parsed by Typewright's own parser, but turning
81
+ * JSX/TS into plain JS is delegated to a wasm transform or a host-supplied fn.
82
+ */
83
+ type MdxTransform = 'wasm-esbuild' | 'wasm-swc' | 'constrained' | ((code: string, meta: {
84
+ filename?: string;
85
+ }) => string | Promise<string>);
86
+ interface SandboxOptions {
87
+ /**
88
+ * Must remain false. MDX executes in an `iframe srcdoc sandbox="allow-scripts"`
89
+ * with an opaque origin (no `allow-same-origin`) so an XSS payload cannot reach
90
+ * the host — Electron-safe (blocks the XSS→RCE path).
91
+ */
92
+ allowSameOrigin?: false;
93
+ /** Extra Content-Security-Policy appended to the sandbox document. */
94
+ csp?: string;
95
+ /** Proxy for host/network access requested by an MDX component via postMessage. */
96
+ onHostMessage?: (message: unknown) => void;
97
+ }
98
+ /** Component name → component. Loose in core to avoid a React type dependency. */
99
+ type ComponentMap = Record<string, unknown>;
100
+ interface MdxOptions {
101
+ enabled: boolean;
102
+ /** Components made available to MDX (`<Chart/>`, `<Callout/>`, …). */
103
+ components?: ComponentMap;
104
+ transform?: MdxTransform;
105
+ sandbox?: SandboxOptions;
106
+ }
107
+ interface FoldingOptions {
108
+ enabled: boolean;
109
+ /** Show the fold gutter + per-heading fold affordance. */
110
+ showGutter?: boolean;
111
+ /** localStorage key to persist fold state across reloads. */
112
+ persistKey?: string;
113
+ }
114
+ interface Extensions {
115
+ /** GitHub Flavored Markdown. `true` enables the full set. */
116
+ gfm?: boolean | Partial<GfmFeatures>;
117
+ /** MDX v3 (JSX + ESM + expressions). */
118
+ mdx?: boolean | MdxOptions;
119
+ mermaid?: boolean | MermaidOptions;
120
+ math?: boolean | MathOptions;
121
+ syntaxHighlight?: boolean | SyntaxHighlightOptions;
122
+ }
123
+ interface KeymapOptions {
124
+ /** Base keymap preset. `default` gives standard text-editing shortcuts. */
125
+ preset?: 'default' | 'none';
126
+ /** Override or add bindings: `"Mod-b" -> "toggleStrong"`. */
127
+ bindings?: Record<string, string>;
128
+ }
129
+ interface ThemeOptions {
130
+ appearance?: 'light' | 'dark' | 'auto';
131
+ /** CSS custom-property overrides (`--tw-accent`, …). */
132
+ tokens?: Record<string, string>;
133
+ }
134
+ interface DocPosition {
135
+ /** UTF-16 offset into the document string. */
136
+ offset: number;
137
+ line: number;
138
+ column: number;
139
+ }
140
+ interface DocRange {
141
+ from: number;
142
+ to: number;
143
+ }
144
+ interface DocSelection {
145
+ main: DocRange;
146
+ ranges: DocRange[];
147
+ }
148
+ /** A single edit expressed as a range replacement (CodeMirror-style). */
149
+ interface DocChange {
150
+ from: number;
151
+ to: number;
152
+ insert: string;
153
+ }
154
+ /** A single reply within a comment thread. */
155
+ interface CommentReply {
156
+ id: string;
157
+ author: string;
158
+ body: string;
159
+ /** ISO-8601 timestamp; host-supplied. */
160
+ createdAt?: string;
161
+ }
162
+ /** A comment thread anchored to a document range. */
163
+ interface CommentThread {
164
+ id: string;
165
+ /** Document offset range the thread is attached to. */
166
+ anchor: {
167
+ from: number;
168
+ to: number;
169
+ };
170
+ /** Snapshot of the anchored text at creation time. */
171
+ quote?: string;
172
+ author: string;
173
+ body: string;
174
+ /** ISO-8601 timestamp; host-supplied. */
175
+ createdAt?: string;
176
+ resolved?: boolean;
177
+ /** Emoji → list of user ids that reacted with it. */
178
+ reactions?: Record<string, string[]>;
179
+ replies: CommentReply[];
180
+ }
181
+ /** Comments configuration: threads in, edit intents out. */
182
+ interface CommentsOptions {
183
+ enabled?: boolean;
184
+ /** All threads to render; the host is the source of truth. */
185
+ threads: CommentThread[];
186
+ /** The current user, used to author new threads/replies/reactions. */
187
+ me?: {
188
+ id: string;
189
+ name: string;
190
+ };
191
+ /** Fired when the user creates a thread from a selection. */
192
+ onCreate?: (t: {
193
+ anchor: {
194
+ from: number;
195
+ to: number;
196
+ };
197
+ quote: string;
198
+ body: string;
199
+ }) => void;
200
+ onReply?: (threadId: string, body: string) => void;
201
+ onReact?: (threadId: string, emoji: string) => void;
202
+ onResolve?: (threadId: string, resolved: boolean) => void;
203
+ onDelete?: (threadId: string) => void;
204
+ }
205
+ /** A remote collaborator whose cursor/selection is rendered live. */
206
+ interface PresencePeer {
207
+ id: string;
208
+ name: string;
209
+ /** Cursor/selection colour (any CSS colour). */
210
+ color?: string;
211
+ /** Current selection as a document offset range; caret if `from === to`. */
212
+ cursor?: {
213
+ from: number;
214
+ to: number;
215
+ };
216
+ }
217
+ /** A host-extensible entry surfaced in the command palette. */
218
+ interface SettingsCommand {
219
+ id: string;
220
+ label: string;
221
+ run: () => void;
222
+ }
223
+ /** Settings panel + ⌘K command palette configuration. */
224
+ interface SettingsOptions {
225
+ enabled?: boolean;
226
+ /** Extra palette entries appended to the built-in commands. */
227
+ commands?: SettingsCommand[];
228
+ }
229
+ interface EditorConfig {
230
+ value?: string;
231
+ mode?: EditorMode;
232
+ /**
233
+ * How the raw syntax markers are revealed in `unified` mode.
234
+ *
235
+ * - `block` (default) Click-to-reveal: clicking a rendered block swaps the
236
+ * whole block for its raw Markdown source — today's behaviour.
237
+ * - `caret` Per-marker reveal around the caret: only the markers the caret
238
+ * sits on (a `**`, a `](url)`, a fence line, …) reveal, live, as
239
+ * the caret moves. Opt-in; contentEditable-backed, with IME handled
240
+ * by the platform's composition (not reimplemented).
241
+ *
242
+ * Additive and backward-compatible — omitting it keeps the `block` default,
243
+ * so existing embeds are unaffected.
244
+ */
245
+ unifiedReveal?: 'block' | 'caret';
246
+ extensions?: Extensions;
247
+ folding?: boolean | FoldingOptions;
248
+ readOnly?: boolean;
249
+ placeholder?: string;
250
+ keymap?: KeymapOptions;
251
+ theme?: ThemeOptions;
252
+ /**
253
+ * Show the built-in formatting toolbar (edit/unified modes). `true`/`"docked"`
254
+ * pins it; `"floating"` reveals it on hover/focus.
255
+ */
256
+ toolbar?: boolean | 'docked' | 'floating';
257
+ /** Lines rendered outside the viewport bounds (virtualization overscan). */
258
+ overscan?: number;
259
+ /**
260
+ * Inline comments & threads. `true` enables the surface with no threads;
261
+ * pass {@link CommentsOptions} to supply threads and edit callbacks.
262
+ */
263
+ comments?: boolean | CommentsOptions;
264
+ /** Remote collaborators whose cursors/selections render live (data-in). */
265
+ presence?: PresencePeer[];
266
+ /**
267
+ * Settings panel + ⌘K command palette. `true` enables the built-ins;
268
+ * pass {@link SettingsOptions} to append host commands.
269
+ */
270
+ settings?: boolean | SettingsOptions;
271
+ }
272
+ interface EditorEvents {
273
+ onChange?: (value: string, change: DocChange) => void;
274
+ onSelectionChange?: (selection: DocSelection) => void;
275
+ onModeChange?: (mode: EditorMode) => void;
276
+ }
277
+ /**
278
+ * Which incomplete constructs are optimistically rendered mid-stream.
279
+ * e.g. `emphasis` renders `*bo` as in-progress bold before the closing `*`.
280
+ */
281
+ interface AnticipationOptions {
282
+ emphasis?: boolean;
283
+ strong?: boolean;
284
+ code?: boolean;
285
+ strikethrough?: boolean;
286
+ links?: boolean;
287
+ headings?: boolean;
288
+ /** An unterminated ```` ``` ```` opens an in-progress code block. */
289
+ fences?: boolean;
290
+ listItems?: boolean;
291
+ tables?: boolean;
292
+ /** Partial JSX elements render a skeleton until the tag/props complete. */
293
+ jsx?: boolean;
294
+ }
295
+ interface StreamOptions {
296
+ /** Optimistically render incomplete formatting as tokens arrive. */
297
+ anticipate?: boolean | AnticipationOptions;
298
+ /** Skeleton rendered for a component whose props are still streaming. */
299
+ componentFallback?: unknown;
300
+ /** Reveal characters smoothly rather than in raw chunk jumps. */
301
+ smooth?: boolean | {
302
+ charsPerSecond: number;
303
+ };
304
+ }
305
+ /** Imperative handle for feeding a token stream into a preview. */
306
+ interface StreamController {
307
+ /** Append a chunk (token/word/sentence) to the stream. */
308
+ push(chunk: string): void;
309
+ /** Replace the whole buffer (e.g. a corrected re-generation). */
310
+ replace(full: string): void;
311
+ /** Mark the stream complete; resolves any anticipated formatting. */
312
+ end(): void;
313
+ /** Clear and start over. */
314
+ reset(): void;
315
+ readonly text: string;
316
+ readonly complete: boolean;
317
+ }
318
+
319
+ export type { AnticipationOptions as A, CommentReply as C, DocChange as D, EditorConfig as E, FoldingOptions as F, GfmFeatures as G, KeymapOptions as K, MathOptions as M, PresencePeer as P, SandboxOptions as S, ThemeOptions as T, EditorEvents as a, DocSelection as b, CommentThread as c, CommentsOptions as d, ComponentMap as e, DocPosition as f, DocRange as g, EditorMode as h, Extensions as i, MdxOptions as j, MdxTransform as k, MermaidOptions as l, SettingsCommand as m, SettingsOptions as n, StreamController as o, StreamOptions as p, SyntaxHighlightOptions as q };