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.
- package/LICENSE +21 -0
- package/README.md +168 -0
- package/SPEC.md +327 -0
- package/dist/chunk-CZQO7TTL.js +1533 -0
- package/dist/chunk-CZQO7TTL.js.map +1 -0
- package/dist/chunk-KNEKNZXK.js +286 -0
- package/dist/chunk-KNEKNZXK.js.map +1 -0
- package/dist/chunk-M6IVEMXO.js +1398 -0
- package/dist/chunk-M6IVEMXO.js.map +1 -0
- package/dist/chunk-NJ7PJKHN.js +652 -0
- package/dist/chunk-NJ7PJKHN.js.map +1 -0
- package/dist/commands-Z3ndUSza.d.cts +221 -0
- package/dist/commands-Z3ndUSza.d.ts +221 -0
- package/dist/core/index.cjs +2952 -0
- package/dist/core/index.cjs.map +1 -0
- package/dist/core/index.d.cts +410 -0
- package/dist/core/index.d.ts +410 -0
- package/dist/core/index.js +4 -0
- package/dist/core/index.js.map +1 -0
- package/dist/mdx/index.cjs +662 -0
- package/dist/mdx/index.cjs.map +1 -0
- package/dist/mdx/index.d.cts +252 -0
- package/dist/mdx/index.d.ts +252 -0
- package/dist/mdx/index.js +3 -0
- package/dist/mdx/index.js.map +1 -0
- package/dist/react/index.cjs +7439 -0
- package/dist/react/index.cjs.map +1 -0
- package/dist/react/index.d.cts +140 -0
- package/dist/react/index.d.ts +140 -0
- package/dist/react/index.js +3644 -0
- package/dist/react/index.js.map +1 -0
- package/dist/streaming/index.cjs +1494 -0
- package/dist/streaming/index.cjs.map +1 -0
- package/dist/streaming/index.d.cts +64 -0
- package/dist/streaming/index.d.ts +64 -0
- package/dist/streaming/index.js +4 -0
- package/dist/streaming/index.js.map +1 -0
- package/dist/types-CX1GOx0Y.d.cts +319 -0
- package/dist/types-CX1GOx0Y.d.ts +319 -0
- 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 };
|