@peisar/peisar-wasm32-wasi 0.2.0 → 0.2.21
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/package.json +2 -2
- package/peisar.wasi-browser.js +1446 -0
- package/peisar.wasi.cjs +2143 -0
- package/peisar.wasi.d.cts +585 -0
- package/peisar.wasm32-wasi.wasm +0 -0
- package/wasi-worker-browser.mjs +67 -0
- package/wasi-worker.mjs +186 -0
|
@@ -0,0 +1,585 @@
|
|
|
1
|
+
/* auto-generated by NAPI-RS */
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
|
|
4
|
+
/** The WASI flavor this loader instantiates. */
|
|
5
|
+
export declare const __napiBindingTarget: 'wasm32-wasi'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Parses one Markdown document and exposes its AST, HTML, and front matter
|
|
9
|
+
* to JavaScript.
|
|
10
|
+
*
|
|
11
|
+
* Construct this class with the Markdown source and an optional
|
|
12
|
+
* [`PeisarOptions`] object. Properties are computed from the source document;
|
|
13
|
+
* accessing `ast`, `html`, or `astJson` also applies registered visitors.
|
|
14
|
+
*/
|
|
15
|
+
export declare class Peisar {
|
|
16
|
+
/**
|
|
17
|
+
* Creates a parser for `rawMd`.
|
|
18
|
+
*
|
|
19
|
+
* When `options` is omitted, GFM and Kramdown parsing are enabled and
|
|
20
|
+
* `html` returns a complete HTML document.
|
|
21
|
+
*/
|
|
22
|
+
constructor(rawMd: string, options?: PeisarOptions | undefined | null)
|
|
23
|
+
/**
|
|
24
|
+
* Gets the parsed Markdown document as a JavaScript AST object.
|
|
25
|
+
*
|
|
26
|
+
* Registered visitors run before the AST is returned. The returned value
|
|
27
|
+
* is a clone, so reading this property does not consume the parser state.
|
|
28
|
+
*/
|
|
29
|
+
get ast(): Document
|
|
30
|
+
/**
|
|
31
|
+
* Registers a JavaScript AST visitor.
|
|
32
|
+
*
|
|
33
|
+
* The visitor can provide `visitBlock` and/or `visitInline` callbacks.
|
|
34
|
+
* Each callback receives a one-item node tuple and may return a control object that
|
|
35
|
+
* changes the node or determines whether its children are visited.
|
|
36
|
+
*/
|
|
37
|
+
useVisitor(visitor: Visitor): void
|
|
38
|
+
/**
|
|
39
|
+
* Registers a JavaScript custom parser hook.
|
|
40
|
+
*
|
|
41
|
+
* The parser can provide `parseBlock` and/or `parseInline` callbacks.
|
|
42
|
+
* `parseBlock` receives `{ line, lineIndex, lines }` and returns
|
|
43
|
+
* `{ block, consumed }`; `parseInline` receives `{ rest, index }` and
|
|
44
|
+
* returns `{ inline, consumed }`. Return `undefined` (or omit the
|
|
45
|
+
* node) to decline a position.
|
|
46
|
+
*
|
|
47
|
+
* Hooks run before the built-in parsers, in registration order. Since
|
|
48
|
+
* the document is parsed at construction, registering a parser hook
|
|
49
|
+
* re-parses the original Markdown so hook syntax is recognized.
|
|
50
|
+
*/
|
|
51
|
+
useParser(parser: Parser): void
|
|
52
|
+
/**
|
|
53
|
+
* Renders the parsed Markdown as HTML using the configured render options.
|
|
54
|
+
*
|
|
55
|
+
* Registered visitors run before rendering.
|
|
56
|
+
*/
|
|
57
|
+
get html(): string
|
|
58
|
+
/** Gets the deserialized YAML front matter, or `null` when none exists. */
|
|
59
|
+
get frontmatter(): any | null
|
|
60
|
+
/**
|
|
61
|
+
* Gets the parsed Markdown AST serialized as JSON.
|
|
62
|
+
*
|
|
63
|
+
* Registered visitors run before serialization.
|
|
64
|
+
*/
|
|
65
|
+
get astJson(): string
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Options that control how Markdown is parsed.
|
|
70
|
+
*
|
|
71
|
+
* # Defaults
|
|
72
|
+
*
|
|
73
|
+
* Both GFM and Kramdown extensions are enabled by default. To parse
|
|
74
|
+
* strict CommonMark only:
|
|
75
|
+
*/
|
|
76
|
+
export interface AstOptions {
|
|
77
|
+
/**
|
|
78
|
+
* Enable GitHub Flavored Markdown (tables, strikethrough, task lists,
|
|
79
|
+
* autolinks). Default: `true`.
|
|
80
|
+
*/
|
|
81
|
+
gfm: boolean
|
|
82
|
+
/**
|
|
83
|
+
* Enable Kramdown-style block attributes (`{:#id .class key="val"}`).
|
|
84
|
+
* Default: `true`.
|
|
85
|
+
*/
|
|
86
|
+
kramdown: boolean
|
|
87
|
+
/**
|
|
88
|
+
* Optional file name to attach to the parsed
|
|
89
|
+
* [`Document`](crate::markdown::ast::Document).
|
|
90
|
+
*/
|
|
91
|
+
fileName?: string
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/** Parsed Kramdown block attributes (`{:#id .class key="val"}`). */
|
|
95
|
+
export interface Attributes {
|
|
96
|
+
/** HTML `id` attribute. */
|
|
97
|
+
id?: string
|
|
98
|
+
/** CSS class list. */
|
|
99
|
+
classes?: Array<string>
|
|
100
|
+
/** Arbitrary key/value attributes. */
|
|
101
|
+
attributes?: Array<[string, string]>
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/** Block-level nodes. */
|
|
105
|
+
export type Block =
|
|
106
|
+
| { type: 'Heading'; /** Heading level (1–6). */
|
|
107
|
+
level: number; /** Inline content of the heading. */
|
|
108
|
+
children: Array<Inline>; /** Source span. */
|
|
109
|
+
pos: Span; /** Optional Kramdown attributes. */
|
|
110
|
+
attrs?: Attributes }
|
|
111
|
+
| { type: 'Paragraph'; /** Inline content of the paragraph. */
|
|
112
|
+
children: Array<Inline>; /** Source span. */
|
|
113
|
+
pos: Span; /** Optional Kramdown attributes. */
|
|
114
|
+
attrs?: Attributes }
|
|
115
|
+
| { type: 'CodeBlock'; /** Language hint from the info string (e.g. `rust` from ` ```rust `). */
|
|
116
|
+
lang?: string; /** The raw code content. */
|
|
117
|
+
code: string; /** Source span. */
|
|
118
|
+
pos: Span; /** Optional Kramdown attributes. */
|
|
119
|
+
attrs?: Attributes }
|
|
120
|
+
| { type: 'BlockQuote'; /** Nested block content inside the quote. */
|
|
121
|
+
children: Array<Block>; /** Source span. */
|
|
122
|
+
pos: Span; /** Optional Kramdown attributes. */
|
|
123
|
+
attrs?: Attributes }
|
|
124
|
+
| { type: 'List'; /** `true` for ordered lists, `false` for unordered. */
|
|
125
|
+
ordered: boolean; /** The list items. */
|
|
126
|
+
items: Array<ListItem>; /** Source span. */
|
|
127
|
+
pos: Span; /** Optional Kramdown attributes. */
|
|
128
|
+
attrs?: Attributes }
|
|
129
|
+
| { type: 'ThematicBreak'; /** Source span. */
|
|
130
|
+
pos: Span }
|
|
131
|
+
| { type: 'HtmlBlock'; /** The raw HTML content. */
|
|
132
|
+
html: string; /** Source span. */
|
|
133
|
+
pos: Span; /** Optional Kramdown attributes. */
|
|
134
|
+
attrs?: Attributes }
|
|
135
|
+
| { type: 'Table'; /** The table structure (header, rows, alignments). */
|
|
136
|
+
table: Table; /** Source span. */
|
|
137
|
+
pos: Span; /** Optional Kramdown attributes. */
|
|
138
|
+
attrs?: Attributes }
|
|
139
|
+
| { type: 'LinkReferenceDefinition'; /** Normalised label (lowercased, trimmed). */
|
|
140
|
+
label: string; /** The destination URL. */
|
|
141
|
+
url: string; /** Optional link title. */
|
|
142
|
+
title?: string; /** Source span. */
|
|
143
|
+
pos: Span }
|
|
144
|
+
| { type: 'Comment'; /** The comment text (markers stripped). */
|
|
145
|
+
value: string; /** Source span. */
|
|
146
|
+
pos: Span }
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Synchronous block-visitor callback. Receives a `Block`, returns
|
|
150
|
+
* `VisitControlJs` (or `undefined` for no changes).
|
|
151
|
+
*/
|
|
152
|
+
export type BlockCallback = (arg: [Block]) => VisitControlJs | null
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Synchronous block parser hook. Receives a [`BlockParseContext`], returns
|
|
156
|
+
* a [`BlockParseResultJs`] (or `undefined` to decline).
|
|
157
|
+
*/
|
|
158
|
+
export type BlockParseCallback = (arg: [BlockParseContext]) => BlockParseResultJs | null
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Context passed to block parser hooks.
|
|
162
|
+
*
|
|
163
|
+
* On the JavaScript side the fields are exposed as `line`, `lineIndex`,
|
|
164
|
+
* and `lines`.
|
|
165
|
+
*/
|
|
166
|
+
export interface BlockParseContext {
|
|
167
|
+
/** The current (unmodified) source line. */
|
|
168
|
+
line: string
|
|
169
|
+
/** 0-based index of the current line in the (sub-)document. */
|
|
170
|
+
lineIndex: number
|
|
171
|
+
/** Remaining lines starting at the current line (`lines[0]` is `line`). */
|
|
172
|
+
lines: Array<string>
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Result returned from the JS `parseBlock` callback.
|
|
177
|
+
*
|
|
178
|
+
* All fields are optional; omitting `block` (or returning `undefined`)
|
|
179
|
+
* declines the position so the next hook / built-in parser handles it.
|
|
180
|
+
*/
|
|
181
|
+
export interface BlockParseResultJs {
|
|
182
|
+
/** The parsed block node. */
|
|
183
|
+
block?: Block
|
|
184
|
+
/** Number of source lines consumed (must be at least `1`). */
|
|
185
|
+
consumed?: number
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* A Markdown document — the root of the AST.
|
|
190
|
+
*
|
|
191
|
+
* Contains the top-level block children and all link reference definitions
|
|
192
|
+
* collected from the source text.
|
|
193
|
+
*/
|
|
194
|
+
export interface Document {
|
|
195
|
+
/** Always `"root"`. */
|
|
196
|
+
nodeType: string
|
|
197
|
+
/** Optional source file name. */
|
|
198
|
+
fileName?: string
|
|
199
|
+
/** Span of the whole document in the source text. */
|
|
200
|
+
pos: Span
|
|
201
|
+
/** Top-level block children. */
|
|
202
|
+
children: Array<Block>
|
|
203
|
+
/** All link reference definitions collected from the document. */
|
|
204
|
+
linkReferences: Array<LinkReferenceDefinition>
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/** Emphasis strength. */
|
|
208
|
+
export declare const enum EmphasisLevel {
|
|
209
|
+
/** `*italic*` / `_italic_` */
|
|
210
|
+
Italic = 0,
|
|
211
|
+
/** `**bold**` / `__bold__` */
|
|
212
|
+
Bold = 1,
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/** Inline-level nodes. */
|
|
216
|
+
export type Inline =
|
|
217
|
+
| { type: 'Text'; /** The text value. */
|
|
218
|
+
value: string; /** Source span. */
|
|
219
|
+
pos: Span }
|
|
220
|
+
| { type: 'Emphasis'; /** Emphasis level (italic or bold). */
|
|
221
|
+
level: EmphasisLevel; /** Nested inline content. */
|
|
222
|
+
children: Array<Inline>; /** Source span. */
|
|
223
|
+
pos: Span }
|
|
224
|
+
| { type: 'Code'; /** The code text. */
|
|
225
|
+
code: string; /** Source span. */
|
|
226
|
+
pos: Span }
|
|
227
|
+
| { type: 'HtmlInline'; /** The raw HTML string. */
|
|
228
|
+
html: string; /** Source span. */
|
|
229
|
+
pos: Span }
|
|
230
|
+
| { type: 'Strikethrough'; /** Nested inline content. */
|
|
231
|
+
children: Array<Inline>; /** Source span. */
|
|
232
|
+
pos: Span }
|
|
233
|
+
| { type: 'HardBreak'; /** Source span. */
|
|
234
|
+
pos: Span }
|
|
235
|
+
| { type: 'SoftBreak'; /** Source span. */
|
|
236
|
+
pos: Span }
|
|
237
|
+
| { type: 'Image'; /** Alternative text. */
|
|
238
|
+
alt: string; /** Image URL. */
|
|
239
|
+
url: string; /** Optional title. */
|
|
240
|
+
title?: string; /** Source span. */
|
|
241
|
+
pos: Span }
|
|
242
|
+
| { type: 'Link'; /** Link text (inline children). */
|
|
243
|
+
text: Array<Inline>; /** Destination URL. */
|
|
244
|
+
url: string; /** Optional link title. */
|
|
245
|
+
title?: string; /** `true` if this is a GFM autolink (bare URL). */
|
|
246
|
+
autolink: boolean; /** Source span. */
|
|
247
|
+
pos: Span }
|
|
248
|
+
| { type: 'LinkReference'; /** Link text (inline children). */
|
|
249
|
+
text: Array<Inline>; /** Normalised label used to look up the reference. */
|
|
250
|
+
label: string; /** Resolved destination URL. */
|
|
251
|
+
url: string; /** Optional resolved title. */
|
|
252
|
+
title?: string; /** Source span. */
|
|
253
|
+
pos: Span }
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Synchronous inline-visitor callback. Receives an `Inline`, returns
|
|
257
|
+
* `InlineVisitControlJs` (or `undefined` for no changes).
|
|
258
|
+
*/
|
|
259
|
+
export type InlineCallback = (arg: [Inline]) => InlineVisitControlJs | null
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Synchronous inline parser hook. Receives an [`InlineParseContext`],
|
|
263
|
+
* returns an [`InlineParseResultJs`] (or `undefined` to decline).
|
|
264
|
+
*/
|
|
265
|
+
export type InlineParseCallback = (arg: [InlineParseContext]) => InlineParseResultJs | null
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Context passed to inline parser hooks.
|
|
269
|
+
*
|
|
270
|
+
* On the JavaScript side the fields are exposed as `rest` and `index`.
|
|
271
|
+
*/
|
|
272
|
+
export interface InlineParseContext {
|
|
273
|
+
/** Remaining inline text starting at the current character position. */
|
|
274
|
+
rest: string
|
|
275
|
+
/** 0-based character index of the current position in the inline text. */
|
|
276
|
+
index: number
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Result returned from the JS `parseInline` callback.
|
|
281
|
+
*
|
|
282
|
+
* All fields are optional; omitting `inline` (or returning `undefined`)
|
|
283
|
+
* declines the position so the next hook / built-in parser handles it.
|
|
284
|
+
*/
|
|
285
|
+
export interface InlineParseResultJs {
|
|
286
|
+
/** The parsed inline node. */
|
|
287
|
+
inline?: Inline
|
|
288
|
+
/** Number of characters consumed (`0` or missing declines). */
|
|
289
|
+
consumed?: number
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* JS-facing mirror of [`InlineVisitControl`].
|
|
294
|
+
*
|
|
295
|
+
* Returned from the JS `visitInline` callback. All fields are optional;
|
|
296
|
+
* omitting a field means "no change" for that operation.
|
|
297
|
+
*/
|
|
298
|
+
export interface InlineVisitControlJs {
|
|
299
|
+
/** Nodes to insert before the current node. */
|
|
300
|
+
insertBefore?: Array<Inline>
|
|
301
|
+
/** Nodes to insert after the current node. */
|
|
302
|
+
insertAfter?: Array<Inline>
|
|
303
|
+
/** Replace the current node with these nodes. */
|
|
304
|
+
replaceWith?: Array<Inline>
|
|
305
|
+
/** Remove the current node entirely. */
|
|
306
|
+
remove?: boolean
|
|
307
|
+
/** Whether to recurse into this node's children. */
|
|
308
|
+
recurse?: boolean
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/** A link reference definition collected at the document level. */
|
|
312
|
+
export interface LinkReferenceDefinition {
|
|
313
|
+
/** Normalised label (lowercased, trimmed). */
|
|
314
|
+
label: string
|
|
315
|
+
/** The destination URL. */
|
|
316
|
+
url: string
|
|
317
|
+
/** Optional link title. */
|
|
318
|
+
title?: string
|
|
319
|
+
/** Source span. */
|
|
320
|
+
pos: Span
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/** A single list item (an `<li>`). Contains nested block content. */
|
|
324
|
+
export interface ListItem {
|
|
325
|
+
/** Nested block content of the item. */
|
|
326
|
+
children: Array<Block>
|
|
327
|
+
/** GFM task-list state: `None` = not a task, `Some` = checked / unchecked. */
|
|
328
|
+
task?: TaskState
|
|
329
|
+
/** Span of the item in the *sub-document* of its enclosing list. */
|
|
330
|
+
pos: Span
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* JavaScript object shape for a parser hook pair.
|
|
335
|
+
*
|
|
336
|
+
* ```js
|
|
337
|
+
* const myParser = {
|
|
338
|
+
* parseBlock(ctx) {
|
|
339
|
+
* if (!ctx.line.startsWith(':::')) return; // decline
|
|
340
|
+
* const name = ctx.line.slice(3).trim();
|
|
341
|
+
* return {
|
|
342
|
+
* block: { type: 'HtmlBlock', html: `<div data-name="${name}"></div>`, pos: { start: {}, end: {} } },
|
|
343
|
+
* consumed: 1,
|
|
344
|
+
* };
|
|
345
|
+
* },
|
|
346
|
+
* parseInline(ctx) {
|
|
347
|
+
* if (!ctx.rest.startsWith('@@')) return; // decline
|
|
348
|
+
* const end = ctx.rest.indexOf(' ', 2);
|
|
349
|
+
* const name = end === -1 ? ctx.rest.slice(2) : ctx.rest.slice(2, end);
|
|
350
|
+
* return {
|
|
351
|
+
* inline: { type: 'HtmlInline', html: `<span data-name="${name}"></span>`, pos: { start: {}, end: {} } },
|
|
352
|
+
* consumed: name.length + 2,
|
|
353
|
+
* };
|
|
354
|
+
* },
|
|
355
|
+
* };
|
|
356
|
+
* document.useParser(myParser);
|
|
357
|
+
* ```
|
|
358
|
+
*
|
|
359
|
+
* Either property may be omitted / `null` to skip that phase.
|
|
360
|
+
*/
|
|
361
|
+
export interface Parser {
|
|
362
|
+
/** Optional JS block parser hook (JS: `parseBlock`). */
|
|
363
|
+
parseBlock?: BlockParseCallback
|
|
364
|
+
/** Optional JS inline parser hook (JS: `parseInline`). */
|
|
365
|
+
parseInline?: InlineParseCallback
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
/** The Markdown body and YAML metadata parsed from a front-matter document. */
|
|
369
|
+
export interface ParseResult {
|
|
370
|
+
/** Markdown source after the leading YAML front matter is removed. */
|
|
371
|
+
pureMarkdownContent: string
|
|
372
|
+
/** Deserialized YAML front matter, or `null` when no front matter exists. */
|
|
373
|
+
yamlData?: Record<string, any>
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* JavaScript options for Markdown parsing and HTML rendering.
|
|
378
|
+
*
|
|
379
|
+
* Every property is optional. Omitted parsing options enable GFM and
|
|
380
|
+
* Kramdown; omitted rendering options produce a complete HTML document with
|
|
381
|
+
* charset and viewport metadata.
|
|
382
|
+
*
|
|
383
|
+
* # Defaults
|
|
384
|
+
*
|
|
385
|
+
* | Property | Default |
|
|
386
|
+
* |------------|-------------|
|
|
387
|
+
* | `gfm` | `true` |
|
|
388
|
+
* | `kramdown` | `true` |
|
|
389
|
+
* | `fragment` | `false` (full document) |
|
|
390
|
+
* | `charset` | `true` |
|
|
391
|
+
* | `viewport` | `true` |
|
|
392
|
+
* | `file_name`, `title`, `body_class`, `style` | `null` |
|
|
393
|
+
*/
|
|
394
|
+
export interface PeisarOptions {
|
|
395
|
+
/**
|
|
396
|
+
* Enable GitHub Flavored Markdown (tables, strikethrough, task lists,
|
|
397
|
+
* autolinks). Default: `true`.
|
|
398
|
+
*/
|
|
399
|
+
gfm?: boolean
|
|
400
|
+
/**
|
|
401
|
+
* Enable Kramdown-style block attributes (`{:#id .class key="val"}`).
|
|
402
|
+
* Default: `true`.
|
|
403
|
+
*/
|
|
404
|
+
kramdown?: boolean
|
|
405
|
+
/**
|
|
406
|
+
* Optional file name to attach to the parsed
|
|
407
|
+
* [`Document`](crate::markdown::ast::Document).
|
|
408
|
+
*/
|
|
409
|
+
fileName?: string
|
|
410
|
+
/**
|
|
411
|
+
* If `true`, emit only the body content (no `<!DOCTYPE>`, `<html>`,
|
|
412
|
+
* `<head>`, or `<body>` wrapper). If `false`, emit a full HTML
|
|
413
|
+
* document. Default: `true` (fragment).
|
|
414
|
+
*/
|
|
415
|
+
fragment?: boolean
|
|
416
|
+
/**
|
|
417
|
+
* Include a `<meta charset="utf-8">` in the head (only relevant when
|
|
418
|
+
* `fragment` is `false`). Default: `true`.
|
|
419
|
+
*/
|
|
420
|
+
charset?: boolean
|
|
421
|
+
/**
|
|
422
|
+
* Include a `<meta name="viewport" content="width=device-width,
|
|
423
|
+
* initial-scale=1.0">` in the head (only relevant when `fragment` is
|
|
424
|
+
* `false`). Default: `true`.
|
|
425
|
+
*/
|
|
426
|
+
viewport?: boolean
|
|
427
|
+
/**
|
|
428
|
+
* Optional `<title>` for the HTML head (only relevant when
|
|
429
|
+
* `fragment` is `false`). Default: `None`.
|
|
430
|
+
*/
|
|
431
|
+
title?: string
|
|
432
|
+
/**
|
|
433
|
+
* Optional additional CSS classes to add to `<body>` (only relevant
|
|
434
|
+
* when `fragment` is `false`). Default: `None`.
|
|
435
|
+
*/
|
|
436
|
+
bodyClass?: string
|
|
437
|
+
/**
|
|
438
|
+
* Optional inline CSS to inject in a `<style>` tag in the head.
|
|
439
|
+
* Default: `None`.
|
|
440
|
+
*/
|
|
441
|
+
style?: string
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
/** A zero-based point in the source text. */
|
|
445
|
+
export interface Position {
|
|
446
|
+
/** Line number, 0-based. */
|
|
447
|
+
line: number
|
|
448
|
+
/** Column number, 0-based (in characters). */
|
|
449
|
+
column: number
|
|
450
|
+
/** Byte offset from the start of the input. */
|
|
451
|
+
offset: number
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
/** Options that control how the AST is rendered to HTML. */
|
|
455
|
+
export interface RenderOptions {
|
|
456
|
+
/**
|
|
457
|
+
* If `true`, emit only the body content (no `<!DOCTYPE>`, `<html>`,
|
|
458
|
+
* `<head>`, or `<body>` wrapper). If `false`, emit a full HTML
|
|
459
|
+
* document. Default: `true` (fragment).
|
|
460
|
+
*/
|
|
461
|
+
fragment: boolean
|
|
462
|
+
/**
|
|
463
|
+
* Include a `<meta charset="utf-8">` in the head (only relevant when
|
|
464
|
+
* `fragment` is `false`). Default: `true`.
|
|
465
|
+
*/
|
|
466
|
+
charset: boolean
|
|
467
|
+
/**
|
|
468
|
+
* Include a `<meta name="viewport" content="width=device-width,
|
|
469
|
+
* initial-scale=1.0">` in the head (only relevant when `fragment` is
|
|
470
|
+
* `false`). Default: `true`.
|
|
471
|
+
*/
|
|
472
|
+
viewport: boolean
|
|
473
|
+
/**
|
|
474
|
+
* Optional `<title>` for the HTML head (only relevant when
|
|
475
|
+
* `fragment` is `false`). Default: `None`.
|
|
476
|
+
*/
|
|
477
|
+
title?: string
|
|
478
|
+
/**
|
|
479
|
+
* Optional additional CSS classes to add to `<body>` (only relevant
|
|
480
|
+
* when `fragment` is `false`). Default: `None`.
|
|
481
|
+
*/
|
|
482
|
+
bodyClass?: string
|
|
483
|
+
/**
|
|
484
|
+
* Optional inline CSS to inject in a `<style>` tag in the head.
|
|
485
|
+
* Default: `None`.
|
|
486
|
+
*/
|
|
487
|
+
style?: string
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
/**
|
|
491
|
+
* A half-open span `[start, end)` covering a node's source text.
|
|
492
|
+
*
|
|
493
|
+
* `start` is inclusive and `end` is exclusive; both positions point into the
|
|
494
|
+
* original source string.
|
|
495
|
+
*/
|
|
496
|
+
export interface Span {
|
|
497
|
+
/** The start position (inclusive). */
|
|
498
|
+
start: Position
|
|
499
|
+
/** The end position (exclusive). */
|
|
500
|
+
end: Position
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
/** A GFM table. */
|
|
504
|
+
export interface Table {
|
|
505
|
+
/** The header row. */
|
|
506
|
+
header: TableRow
|
|
507
|
+
/** Body rows. */
|
|
508
|
+
rows: Array<TableRow>
|
|
509
|
+
/** Column alignment specifications (one per column). */
|
|
510
|
+
alignments: Array<TableCellAlignment>
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
/** A single table cell. */
|
|
514
|
+
export interface TableCell {
|
|
515
|
+
/** Inline content of the cell. */
|
|
516
|
+
children: Array<Inline>
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
/** Column alignment for table cells. */
|
|
520
|
+
export declare const enum TableCellAlignment {
|
|
521
|
+
/** `:---` or `---` — default (left) */
|
|
522
|
+
Default = 0,
|
|
523
|
+
/** `:---` */
|
|
524
|
+
Left = 1,
|
|
525
|
+
/** `:---:` */
|
|
526
|
+
Center = 2,
|
|
527
|
+
/** `---:` */
|
|
528
|
+
Right = 3,
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
/** A single table row (header or body). */
|
|
532
|
+
export interface TableRow {
|
|
533
|
+
/** The cells in this row. */
|
|
534
|
+
cells: Array<TableCell>
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
/** GFM task-list checkbox state. */
|
|
538
|
+
export declare const enum TaskState {
|
|
539
|
+
/** `[ ]` — unchecked */
|
|
540
|
+
Unchecked = 0,
|
|
541
|
+
/** `[x]` / `[X]` — checked */
|
|
542
|
+
Checked = 1,
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
/**
|
|
546
|
+
* JS-facing mirror of [`VisitControl`].
|
|
547
|
+
*
|
|
548
|
+
* Returned from the JS `visitBlock` callback. All fields are optional;
|
|
549
|
+
* omitting a field means "no change" for that operation.
|
|
550
|
+
*/
|
|
551
|
+
export interface VisitControlJs {
|
|
552
|
+
/** Nodes to insert before the current node. */
|
|
553
|
+
insertBefore?: Array<Block>
|
|
554
|
+
/** Nodes to insert after the current node. */
|
|
555
|
+
insertAfter?: Array<Block>
|
|
556
|
+
/** Replace the current node with these nodes. */
|
|
557
|
+
replaceWith?: Array<Block>
|
|
558
|
+
/** Remove the current node entirely. */
|
|
559
|
+
remove?: boolean
|
|
560
|
+
/** Whether to recurse into this node's children. */
|
|
561
|
+
recurse?: boolean
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
/**
|
|
565
|
+
* JavaScript object shape for a visitor callback pair.
|
|
566
|
+
*
|
|
567
|
+
* On the JS side it is a plain object with two optional
|
|
568
|
+
* function properties:
|
|
569
|
+
*
|
|
570
|
+
* ```js
|
|
571
|
+
* const myPlugin = {
|
|
572
|
+
* visitBlock(block) { return { recurse: true }; },
|
|
573
|
+
* visitInline(inline) { return {}; },
|
|
574
|
+
* };
|
|
575
|
+
* ast.addVisitor(myPlugin);
|
|
576
|
+
* ```
|
|
577
|
+
*
|
|
578
|
+
* Either property may be omitted / `null` to skip that node kind.
|
|
579
|
+
*/
|
|
580
|
+
export interface Visitor {
|
|
581
|
+
/** Optional JS callback for block nodes (JS: `visitBlock`). */
|
|
582
|
+
visitBlock?: BlockCallback
|
|
583
|
+
/** Optional JS callback for inline nodes (JS: `visitInline`). */
|
|
584
|
+
visitInline?: InlineCallback
|
|
585
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import {
|
|
2
|
+
instantiateNapiModuleSync,
|
|
3
|
+
MessageHandler,
|
|
4
|
+
WASI,
|
|
5
|
+
emnapiAsyncWorkPlugin,
|
|
6
|
+
emnapiTSFNPlugin,
|
|
7
|
+
} from '@napi-rs/wasm-runtime'
|
|
8
|
+
|
|
9
|
+
const handler = new MessageHandler({
|
|
10
|
+
onLoad({ wasmModule, wasmMemory }) {
|
|
11
|
+
const wasi = new WASI({
|
|
12
|
+
print: function () {
|
|
13
|
+
// eslint-disable-next-line no-console
|
|
14
|
+
console.log.apply(console, arguments)
|
|
15
|
+
},
|
|
16
|
+
printErr: function () {
|
|
17
|
+
// eslint-disable-next-line no-console
|
|
18
|
+
console.error.apply(console, arguments)
|
|
19
|
+
},
|
|
20
|
+
})
|
|
21
|
+
return instantiateNapiModuleSync(wasmModule, {
|
|
22
|
+
childThread: true,
|
|
23
|
+
wasi,
|
|
24
|
+
// The wasm links a "basic" emnapi archive (no C async-work /
|
|
25
|
+
// threadsafe-function implementations), so every thread that
|
|
26
|
+
// instantiates it must provide the JavaScript implementations
|
|
27
|
+
// through the emnapi plugins.
|
|
28
|
+
plugins: [emnapiAsyncWorkPlugin, emnapiTSFNPlugin],
|
|
29
|
+
overwriteImports(importObject) {
|
|
30
|
+
importObject.env = {
|
|
31
|
+
...importObject.env,
|
|
32
|
+
...importObject.napi,
|
|
33
|
+
...importObject.emnapi,
|
|
34
|
+
memory: wasmMemory,
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
})
|
|
38
|
+
},
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
// When this wasm thread dies, raise the addon's crash flag before emnapi reports
|
|
42
|
+
// it. The loader thread may be inside wasm, in a cleanup call that waits on this
|
|
43
|
+
// thread; the flag is what those waits check between short slices, and once it
|
|
44
|
+
// is up they trap instead of waiting for good. It is a word in the shared wasm
|
|
45
|
+
// memory, and the loader posts a view of it (see
|
|
46
|
+
// napi_wasm_thread_crash_flag_address) after it instantiated the wasm, or right
|
|
47
|
+
// after it created this worker. No view, no flag: an addon built with an older
|
|
48
|
+
// napi, or a failure before the view arrived.
|
|
49
|
+
let __addonCrashFlag
|
|
50
|
+
const __beforeReportError = handler.beforeReportError
|
|
51
|
+
handler.beforeReportError = function (...args) {
|
|
52
|
+
if (__addonCrashFlag !== undefined) {
|
|
53
|
+
try {
|
|
54
|
+
Atomics.store(__addonCrashFlag, 0, 1)
|
|
55
|
+
} catch {}
|
|
56
|
+
}
|
|
57
|
+
return __beforeReportError.apply(this, args)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
globalThis.onmessage = function (e) {
|
|
61
|
+
const data = e && e.data
|
|
62
|
+
if (data && data.__napiRsAddonCrashFlag instanceof Int32Array) {
|
|
63
|
+
__addonCrashFlag = data.__napiRsAddonCrashFlag
|
|
64
|
+
return
|
|
65
|
+
}
|
|
66
|
+
handler.handle(e)
|
|
67
|
+
}
|