@markup-carve/carve-wasm 0.1.4 โ†’ 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,740 @@
1
+ /* tslint:disable */
2
+ /* eslint-disable */
3
+
4
+
5
+ export function toHtmlWithOptions(source: string, options?: RenderOptions | null): string;
6
+ export function toHtmlWithRenderers(source: string, options?: StaticRenderOptions | null): StaticRenderResult;
7
+
8
+ export interface IncludeContext {
9
+ sourcePath: string | null;
10
+ stack: string[];
11
+ depth: number;
12
+ }
13
+ export type IncludeDenial = "outside-root" | "not-found" | "no-root" | "include-denied" | "include-unresolved";
14
+ export interface IncludeOptions {
15
+ resolve: (path: string, context: IncludeContext) => string | { source: string; id?: string } | { denial: IncludeDenial } | null;
16
+ sourcePath?: string;
17
+ extensions?: string[];
18
+ maxDepth?: number;
19
+ maxBytes?: number;
20
+ maxResolverCalls?: number;
21
+ maxWarnings?: number;
22
+ }
23
+ export interface IncludeExpansion {
24
+ json: string;
25
+ warnings: { rule: string; message: string; file: string | null }[];
26
+ suppressedWarnings: number;
27
+ dependencies: { id: string; resolved: boolean; denial: IncludeDenial | null }[];
28
+ chargedBytes: number;
29
+ resolverErrors: { path: string; message: string }[];
30
+ }
31
+ export interface SourcePosition {
32
+ startLine: number;
33
+ endLine: number;
34
+ startColumn: number;
35
+ endColumn: number;
36
+ /** Unicode codepoint offsets, not UTF-8 bytes or UTF-16 units. */
37
+ startOffset: number;
38
+ endOffset: number;
39
+ }
40
+ export interface RenderLoss {
41
+ code: string;
42
+ format: string;
43
+ target: string;
44
+ nodeType: string;
45
+ message: string;
46
+ pos?: SourcePosition;
47
+ }
48
+ export interface RenderResult {
49
+ value: string;
50
+ losses: RenderLoss[];
51
+ totalLosses: number;
52
+ /**
53
+ * How many losses each code accounts for, across the WHOLE render.
54
+ * `losses` is bounded, so counting codes off that array under-reports as
55
+ * soon as `truncated` is true; these totals do not.
56
+ */
57
+ totalsByCode: Record<string, number>;
58
+ truncated: boolean;
59
+ }
60
+ export interface RenderOptions {
61
+ full?: boolean;
62
+ extensions?: string[];
63
+ symbols?: Record<string, string> | Map<string, string>;
64
+ rawHtml?: boolean;
65
+ sections?: boolean;
66
+ sourceLine?: boolean;
67
+ positions?: boolean;
68
+ lowercaseHeadingIds?: boolean;
69
+ asciiHeadingIds?: "off" | "fold" | "strict";
70
+ smartTypography?: "glyph" | "source";
71
+ mode?: "interactive" | "static";
72
+ profile?: "full" | "article" | "comment" | "minimal";
73
+ profileBaseHost?: string;
74
+ mentionUrl?: string;
75
+ tagUrl?: string;
76
+ labels?: Record<string, string>;
77
+ }
78
+ export interface StaticRenderOptions extends RenderOptions {
79
+ renderers?: {
80
+ math?: (source: string, display: boolean) => string;
81
+ diagrams?: Record<string, (source: string) => string>;
82
+ };
83
+ }
84
+
85
+ export interface LintWarning {
86
+ /** 1-based line number. */
87
+ line: number;
88
+ /** 1-based column number. */
89
+ column: number;
90
+ /** Stable rule id, shared with carve-js and carve-php. */
91
+ rule: string;
92
+ message: string;
93
+ /**
94
+ * 0-based offset into the source in UTF-16 CODE UNITS, inclusive. That is
95
+ * what indexes a JavaScript string, so `source.slice(start, end)` selects the
96
+ * span the warning is about. It was a UTF-8 byte offset before 0.1.6, which
97
+ * agreed with this on an ASCII document and not outside one.
98
+ */
99
+ start: number;
100
+ /** 0-based UTF-16 code unit offset into the source, exclusive. */
101
+ end: number;
102
+ }
103
+
104
+ export interface ProfileViolation {
105
+ /** Canonical node type that was disallowed. */
106
+ nodeType: string;
107
+ /** Machine reason: element_not_allowed | max_nesting_exceeded | link_not_allowed | image_not_allowed. */
108
+ reason: string;
109
+ /** The profile's own wording for the denial, when it carries one. */
110
+ reasonDescription: string | null;
111
+ /** The engine's prose, the same text a thrown ProfileViolationError lists. */
112
+ message: string;
113
+ }
114
+ export interface ProfileFilterResult {
115
+ /** The filtered tree, as AST JSON. */
116
+ json: string;
117
+ violations: ProfileViolation[];
118
+ }
119
+
120
+ export interface Stamp {
121
+ /** The spec version the document was last processed under. */
122
+ version: string;
123
+ /** The engine that wrote the marker, when it recorded one. */
124
+ generatedBy: string | null;
125
+ }
126
+
127
+ export type MigrationFidelity = "preserved" | "normalized" | "degraded" | "dropped";
128
+ export type MigrationConfidence = "exact" | "inferred" | "fallback";
129
+ export interface MigrationDiagnostic {
130
+ code: string;
131
+ message: string;
132
+ severity: "info" | "warning" | "error";
133
+ fidelity: MigrationFidelity;
134
+ confidence: MigrationConfidence;
135
+ path?: string;
136
+ }
137
+ export interface MigrationReport {
138
+ schemaVersion: 2;
139
+ sourceFormat: string;
140
+ mode?: string;
141
+ adapter?: string;
142
+ diagnostics: MigrationDiagnostic[];
143
+ }
144
+ export interface MigrationResult { value: string; report: MigrationReport; }
145
+
146
+ export type SourceEditKind = "formatting" | "syntax-migration" | "quick-fix" | "refactor";
147
+ export interface SourceEdit {
148
+ /** Inclusive UTF-8 byte offset. */
149
+ start: number;
150
+ /** Exclusive UTF-8 byte offset. */
151
+ end: number;
152
+ replacement: string;
153
+ kind: SourceEditKind;
154
+ code: string;
155
+ }
156
+ export interface SourceSuggestion extends SourceEdit { message: string; }
157
+ export interface SourcePatch {
158
+ version: 1;
159
+ sourceFingerprint: string;
160
+ sourceBytes: number;
161
+ edits: SourceEdit[];
162
+ unresolved: SourceSuggestion[];
163
+ }
164
+
165
+ export interface StaticRendererError {
166
+ /** "math", or the diagram fence class. */
167
+ renderer: string;
168
+ /** Present for math callbacks only. */
169
+ display?: boolean;
170
+ /** The source the renderer was handed. */
171
+ source: string;
172
+ message: string;
173
+ }
174
+ export interface StaticRenderResult {
175
+ html: string;
176
+ /** Empty unless a render callback threw or returned a non-string. */
177
+ rendererErrors: StaticRendererError[];
178
+ }
179
+
180
+ export interface AccessibilityDiagnostic {
181
+ /** Stable rule id, e.g. a11y/image-alt. */
182
+ rule: string;
183
+ severity: "warning" | "error";
184
+ message: string;
185
+ /**
186
+ * 0-based Unicode CODEPOINT offset, or null when the node carried none.
187
+ * Codepoints, not the UTF-8 bytes `LintWarning` counts: the two lint
188
+ * families answer in different units.
189
+ */
190
+ startOffset: number | null;
191
+ endOffset: number | null;
192
+ /**
193
+ * The same span in UTF-16 code units, which is what indexes a JavaScript
194
+ * string. Null exactly when `startOffset` / `endOffset` are.
195
+ */
196
+ startUtf16: number | null;
197
+ endUtf16: number | null;
198
+ }
199
+
200
+ export interface SanitizeSvgOptions {
201
+ allowStyle?: boolean;
202
+ allowLinks?: boolean;
203
+ allowAnimation?: boolean;
204
+ allowExternalImages?: boolean;
205
+ }
206
+ export interface SanitizeResult {
207
+ /** Meaningful only when ok is true. */
208
+ svg: string;
209
+ /** False when the input was not a single well-formed <svg> root. */
210
+ ok: boolean;
211
+ }
212
+
213
+ export interface ParsedLocator {
214
+ label: string | null;
215
+ value: string | null;
216
+ suffixText: string | null;
217
+ }
218
+
219
+ export interface ProseMirrorResult {
220
+ /** The ProseMirror document, JSON-encoded. */
221
+ json: string;
222
+ /** Carve node type -> why its content is gone. */
223
+ dropped: Record<string, string>;
224
+ /** Carve node type -> why its node type is gone while its text survives. */
225
+ degraded: Record<string, string>;
226
+ }
227
+
228
+
229
+
230
+ export function astJsonToMarkdown(json: string, options?: RenderOptions | null): string;
231
+ export function astJsonToPlainText(json: string, options?: RenderOptions | null): string;
232
+ export function astJsonToAnsi(json: string, options?: RenderOptions | null): string;
233
+
234
+
235
+
236
+ export function lintCarveWithOptions(source: string, options?: RenderOptions | null): LintWarning[];
237
+
238
+
239
+
240
+ export function parseJsonWithOptions(source: string, options?: RenderOptions | null): string;
241
+ export function astJsonToHtml(json: string, options?: RenderOptions | null): string;
242
+
243
+
244
+
245
+ export function toHtmlWithReport(source: string, strict?: boolean | null, maximum?: number | null): RenderResult;
246
+ export function toMarkdownWithReport(source: string, strict?: boolean | null, maximum?: number | null): RenderResult;
247
+ export function toPlainTextWithReport(source: string, strict?: boolean | null, maximum?: number | null): RenderResult;
248
+ export function toAnsiWithReport(source: string, strict?: boolean | null, maximum?: number | null): RenderResult;
249
+ export function toCarveWithReport(source: string, strict?: boolean | null, maximum?: number | null): RenderResult;
250
+
251
+
252
+
253
+ export function toMarkdownWithOptions(source: string, options?: RenderOptions | null): string;
254
+ export function toPlainTextWithOptions(source: string, options?: RenderOptions | null): string;
255
+ export function toAnsiWithOptions(source: string, options?: RenderOptions | null): string;
256
+ export function toCarveWithOptions(source: string, options?: RenderOptions | null): string;
257
+
258
+
259
+
260
+ /**
261
+ * A parser snapshot retained between editor updates. Call `free()` when done.
262
+ */
263
+ export class ParserSession {
264
+ free(): void;
265
+ [Symbol.dispose](): void;
266
+ /**
267
+ * Apply byte edits; a rejected edit leaves the session unchanged.
268
+ */
269
+ edit(changes: string): string;
270
+ constructor(source: string);
271
+ /**
272
+ * The current result, with byte ranges and parser-work counters.
273
+ */
274
+ snapshot(): string;
275
+ }
276
+
277
+ /**
278
+ * Replay patch JSON onto a PART 12 tree, returning the result as AST JSON.
279
+ */
280
+ export function applyAstPatch(ast: string, patch: string): string;
281
+
282
+ /**
283
+ * Apply a security profile to an AST-JSON document (PART 12), keeping the
284
+ * filtered tree.
285
+ *
286
+ * The `profile` render option filters on the way to HTML and throws the result
287
+ * of the filtering away. This is the same pass with the tree kept, so a host
288
+ * that stores, diffs or re-renders an untrusted document does not have to
289
+ * render HTML and parse it back to get one.
290
+ *
291
+ * `violations` reports what the filter degraded or stripped, which the HTML
292
+ * path cannot: a profile whose action is `error` throws instead, so a
293
+ * resolved call under `to-text` or `strip` is the only place this is visible.
294
+ *
295
+ * Only `profileBaseHost` and `smartTypography` are read from `options`. The
296
+ * rest of the render options describe a renderer, and this is not one.
297
+ *
298
+ * The profile's `max_length` is NOT enforced here: the engine applies it to the
299
+ * source bytes before a parse, and this entry point is handed a tree.
300
+ */
301
+ export function applyProfile(json: string, profile: string, options?: object | null): ProfileFilterResult;
302
+
303
+ /**
304
+ * Replay a reversible patch, forward or inverted.
305
+ *
306
+ * The fingerprint is checked first: a tree that is not the one this patch was
307
+ * made against is refused rather than half-patched. That is a broken caller
308
+ * contract, so it throws.
309
+ */
310
+ export function applyReversibleAstPatch(ast: string, patch: string, inverse?: boolean | null): string;
311
+
312
+ /**
313
+ * Apply a trusted patch after its source length and fingerprint still match.
314
+ */
315
+ export function applySourcePatch(source: string, patch: SourcePatch): string;
316
+
317
+ /**
318
+ * Render an AST-JSON document (PART 12) back to canonical Carve source.
319
+ *
320
+ * The round trip a host needs to SAVE an edited tree, rather than only display
321
+ * it. A tree holding something no Carve source can spell is refused rather
322
+ * than written approximately.
323
+ */
324
+ export function astJsonToCarve(json: string): string;
325
+
326
+ /**
327
+ * The difference between two PART 12 trees, as patch JSON.
328
+ *
329
+ * ```js
330
+ * const patch = createAstPatch(parseJson('# One\n'), parseJson('# Two\n'))
331
+ * applyAstPatch(parseJson('# One\n'), patch) // the '# Two' tree
332
+ * ```
333
+ *
334
+ * Trees and patches both cross as JSON strings, matching `parseJson` and
335
+ * `astJsonToHtml`. A patch carries node payloads, so it carries arbitrary
336
+ * document text - the reason `parseJson` chose a string in the first place.
337
+ *
338
+ * The engine's `ast_patch_to_json` and `ast_patch_from_json` are not bound
339
+ * separately. With the patch crossing as JSON they ARE the encoding of this
340
+ * pair, and a host calling them would be converting JSON it already holds.
341
+ *
342
+ * The operations are position-independent `{ op, path, value }`, so a patch
343
+ * stays meaningful against a tree that moved underneath it - unlike a source
344
+ * patch, which `createSourcePatch` fingerprints against staleness.
345
+ */
346
+ export function createAstPatch(before: string, after: string): string;
347
+
348
+ /**
349
+ * The same difference with its inverse and both fingerprints, as one JSON
350
+ * object: `{ forward, inverse, beforeFingerprint, afterFingerprint }`.
351
+ *
352
+ * This is the shape an undo step wants. THE STACK IS THE HOST'S: every entry
353
+ * point in this package is a pure function that owns nothing, so there is no
354
+ * history kept here to undo against, and a browser host already has one - a
355
+ * key handler, a toolbar, an editor's own history plugin.
356
+ *
357
+ * What the pair adds over two `createAstPatch` calls is the precondition.
358
+ * [`apply_reversible_ast_patch`] refuses a tree whose fingerprint is not the
359
+ * one the patch was made against, so an undo cannot be replayed onto a
360
+ * document that has moved on.
361
+ */
362
+ export function createReversibleAstPatch(before: string, after: string): string;
363
+
364
+ /**
365
+ * Build the smallest single UTF-8 byte-range replacement between two sources.
366
+ */
367
+ export function createSourcePatch(source: string, replacement: string, kind: string, code: string): SourcePatch;
368
+
369
+ /**
370
+ * Expand `{{ path }}` include directives (spec PART 9 ยง19) through a JS
371
+ * resolver, and hand back the expanded tree as AST JSON.
372
+ *
373
+ * The resolver MUST BE SYNCHRONOUS, which decides who can use this. A browser
374
+ * host that would resolve a path by `fetch` cannot: `fetch` is a Promise and
375
+ * wasm-bindgen cannot await across the call. A host whose files are already in
376
+ * memory - an editor with its open buffers, a bundler, a VFS, a test harness -
377
+ * resolves from that map and is exactly who this is for.
378
+ *
379
+ * ```js
380
+ * const files = new Map([['child.crv', 'Included body.\n']])
381
+ * expandIncludes('Before.\n\n{{ child.crv }}\n', {
382
+ * resolve: (path) => files.get(path) ?? null,
383
+ * })
384
+ * // { json, warnings: [], suppressedWarnings: 0, dependencies: [โ€ฆ],
385
+ * // chargedBytes: 15, resolverErrors: [] }
386
+ * ```
387
+ *
388
+ * The resolver returns the child's source as a string, or
389
+ * `{ source, id }` when it can name the file canonically - the id is what the
390
+ * cycle guard compares, so two spellings of one file defeat it without one.
391
+ * `null` refuses the directive as `not-found`; `{ denial }` refuses it in one
392
+ * of the classes ยง19 names.
393
+ *
394
+ * An `async` resolver returns a Promise, which is not a string and cannot be
395
+ * awaited. That is a per-document failure reported in `resolverErrors`,
396
+ * matching what an `async` `renderers.math` gets from
397
+ * [`to_html_with_renderers`]: the directive stays literal and the caller is
398
+ * told why, rather than the value being swallowed or stringified.
399
+ *
400
+ * The BUDGETS are part of the contract, not a detail: `maxBytes` defaults to
401
+ * `max(1 MB, 8 x source bytes)`, `maxDepth` to 16, `maxResolverCalls` to 1000
402
+ * and `maxWarnings` to 100. They bound what a document of directives can make
403
+ * a host do, and lowering them is how a host serving untrusted documents keeps
404
+ * that bounded.
405
+ *
406
+ * The tree carries no positions. Expansion merges nodes from several files,
407
+ * and a span on a node that came from a child would point into a source the
408
+ * caller did not pass.
409
+ */
410
+ export function expandIncludes(source: string, options: IncludeOptions): IncludeExpansion;
411
+
412
+ /**
413
+ * Every extension name this build accepts, in registry order.
414
+ *
415
+ * Taken from the engine, so a new extension is reachable as soon as the pin
416
+ * moves. Nothing here lists names.
417
+ */
418
+ export function extensions(): string[];
419
+
420
+ /**
421
+ * Convert BBCode source to Carve.
422
+ *
423
+ * Rejects input past the engine's `BBCODE_MAX_INPUT_LENGTH` rather than
424
+ * working on it: the importer's cost is superlinear in places, and a browser
425
+ * host cannot afford to find that out on the main thread.
426
+ */
427
+ export function fromBbcode(source: string): string;
428
+
429
+ /**
430
+ * Convert Djot source to Carve.
431
+ *
432
+ * Carve diverges from Djot deliberately - the emphasis delimiters are swapped,
433
+ * among others - so a Djot document is not Carve source and pasting one in
434
+ * renders wrongly rather than failing.
435
+ */
436
+ export function fromDjot(source: string): string;
437
+
438
+ export function fromHtml(source: string, mode?: string | null): MigrationResult;
439
+
440
+ export function fromMarkdown(source: string): MigrationResult;
441
+
442
+ /**
443
+ * Convert a ProseMirror document back to canonical Carve source.
444
+ *
445
+ * The save half of the editor loop. A payload the schema map does not describe
446
+ * is refused rather than written approximately, so an editor extended with a
447
+ * node the bridge has never seen fails where it can be reported.
448
+ */
449
+ export function fromProseMirror(doc: string): string;
450
+
451
+ /**
452
+ * Import HTML straight to the tree, as AST JSON.
453
+ *
454
+ * `htmlToCarve` writes Carve SOURCE, so a host that wanted the tree had to
455
+ * re-parse what it had just written - two parses of one document to get one
456
+ * answer. This is the same importer without that round trip.
457
+ *
458
+ * ```js
459
+ * const { value, report } = htmlToAst('<p>Hello <b>world</b></p>', 'safe')
460
+ * astJsonToHtml(value)
461
+ * ```
462
+ *
463
+ * Returns the SAME `{ value, report }` shape `htmlToCarve` does, with `value`
464
+ * holding the tree instead of the source, in the same fidelity vocabulary. A
465
+ * third result shape for one importer is what that avoids.
466
+ *
467
+ * The REPORT IS NOT ALWAYS IDENTICAL, and the difference is the point. A loss
468
+ * only a WRITER takes is not reported here, because no writer ran (PART 12
469
+ * ยง16): a `<figure>` wrapping a table, or a table with an explicit
470
+ * head/body/foot grouping, has no Carve spelling, so `htmlToCarve` reports
471
+ * `structure-unspellable` and this does not - the tree keeps the thing that
472
+ * would have been lost.
473
+ *
474
+ * `mode` is spelled as it is there: `safe` (the default), `semantic`, and
475
+ * trusted-only `roundtrip`.
476
+ */
477
+ export function htmlToAst(source: string, mode?: string | null): MigrationResult;
478
+
479
+ /**
480
+ * Import HTML through the Rust HTML5 DOM and canonical Carve writer.
481
+ *
482
+ * Returns `{ value, report }`; `report.diagnostics` makes every lossy import
483
+ * decision observable. `roundtrip` is only safe for Carve-produced HTML.
484
+ */
485
+ export function htmlToCarve(source: string, mode?: string | null): MigrationResult;
486
+
487
+ /**
488
+ * The accessibility diagnostics, a second family beside `lintCarve`.
489
+ *
490
+ * Its own rule ids (`a11y/image-alt`, `a11y/heading-jump`) and its own
491
+ * severity, which `lintCarve` has no field for. Offsets are `null` when the
492
+ * node that triggered the rule carried no position.
493
+ */
494
+ export function lintAccessibility(source: string): AccessibilityDiagnostic[];
495
+
496
+ /**
497
+ * Lint a document for the degradations PART 15 describes.
498
+ *
499
+ * Returns an array of `{ line, column, rule, message, start, end }`. The rule
500
+ * ids are shared with carve-js and carve-php, so the same trigger reports the
501
+ * same id everywhere. Offsets count UTF-16 CODE UNITS, so they index the
502
+ * JavaScript string the caller holds; the engine answers in bytes and this
503
+ * wrapper converts (#164).
504
+ *
505
+ * Built as JS objects rather than a JSON string: a message carries arbitrary
506
+ * document text, and hand-rolled JSON escaping is where that goes wrong.
507
+ */
508
+ export function lintCarve(source: string): LintWarning[];
509
+
510
+ /**
511
+ * Import Markdown straight to the tree, as AST JSON.
512
+ *
513
+ * `fromMarkdown` writes Carve SOURCE, so a host that wanted the tree had to
514
+ * re-parse what it had just written. This is the same importer without that
515
+ * round trip. The losses `fromMarkdown` reports are not repeated here; a host
516
+ * that needs them calls that one.
517
+ */
518
+ export function markdownToAstJson(source: string): string;
519
+
520
+ /**
521
+ * Three-way merge over PART 12 trees, with conflicts as a VALUE.
522
+ *
523
+ * ```js
524
+ * const { ok, ast, conflicts } = JSON.parse(mergeAst(base, ours, theirs))
525
+ * ```
526
+ *
527
+ * Returns `{ ok, ast, conflicts, resolverErrors }` as one JSON string. A
528
+ * conflict does NOT throw: it is a result the caller asked for, and two people
529
+ * editing one document is the ordinary case rather than a broken contract.
530
+ * `ok` is false, `ast` is null, and `conflicts` says where and why.
531
+ *
532
+ * The `{ ok, ast, conflicts }` shape and the three `reason` names -
533
+ * `both-changed`, `delete-edit`, `concurrent-sequence-edit` - are carve-js's,
534
+ * so a host merging with either engine reads one contract. The Rust engine
535
+ * carries no `deleted` flags on a conflict, so that optional carve-js field is
536
+ * absent here rather than guessed at.
537
+ *
538
+ * `options.resolve` is an optional `(conflict) => 'base' | 'ours' | 'theirs' |
539
+ * { value } | null`, answering conflicts while the merge runs; an answer of
540
+ * `null` leaves one unresolved. IT MUST BE SYNCHRONOUS. A resolver that asks a
541
+ * server, or asks the user, returns a Promise the merge cannot await - that is
542
+ * reported in `resolverErrors` and the conflict is left unresolved, the same
543
+ * treatment an `async` `renderers.math` gets.
544
+ */
545
+ export function mergeAst(base: string, ours: string, theirs: string, options?: object | null): string;
546
+
547
+ /**
548
+ * Convert BBCode and retain a conservative v2 fidelity report.
549
+ */
550
+ export function migrateBbcode(source: string): MigrationResult;
551
+
552
+ /**
553
+ * Convert Djot and retain a conservative v2 fidelity report.
554
+ */
555
+ export function migrateDjot(source: string): MigrationResult;
556
+
557
+ /**
558
+ * Whether a document was last processed under an older spec version than
559
+ * `currentVersion`. An unstamped document counts as needing review.
560
+ */
561
+ export function needsReview(source: string, current_version: string): boolean;
562
+
563
+ /**
564
+ * Parse Carve source and return its AST as a JSON string.
565
+ *
566
+ * The PART 12 exchange shape (https://markup-carve.github.io/carve/ast-json):
567
+ * the same tree every Carve engine publishes, so a consumer written against
568
+ * one implementation reads another's output. The root carries exactly `type`,
569
+ * `children` and `srcByteLength`; frontmatter and footnote definitions are
570
+ * block nodes inside `children`, not root fields.
571
+ *
572
+ * Returns a STRING rather than a JS object: the caller runs `JSON.parse`, which
573
+ * is what a browser does natively and faster than building the object graph
574
+ * across the wasm boundary one property at a time. It also keeps the bytes
575
+ * available for a caller that stores or forwards them.
576
+ *
577
+ * Position tracking is on for this entry point and nowhere else. PART 12 ยง4
578
+ * lets an engine gate tracking behind a parse option but requires the
579
+ * serialized form to carry it, and rendering would pay for spans nobody reads.
580
+ */
581
+ export function parseJson(source: string): string;
582
+
583
+ /**
584
+ * Parse the locator portion of a citation into `{ label, value, suffixText }`.
585
+ *
586
+ * A field the source did not carry is `null`. Same shape as carve-js
587
+ * `parseLocator`; pure, and never throws on bad input.
588
+ */
589
+ export function parseLocator(loc: string): ParsedLocator;
590
+
591
+ /**
592
+ * Parse a document and keep what a later [`reparse`] needs.
593
+ *
594
+ * Returns one JSON object: `{ source, document, sourceLayout, changedSource,
595
+ * reusedPreviousTree }`. `document` is the PART 12 tree, `sourceLayout` the
596
+ * byte-exact record [`parse_source_layout_json`] produces, and
597
+ * `changedSource` the byte ranges this parse covered - the whole document, on
598
+ * a first parse.
599
+ *
600
+ * The snapshot crosses as JSON rather than as a handle a host has to `free()`.
601
+ * Every other entry point here is a pure function that owns nothing, and the
602
+ * engine's own snapshot holds only the source, so there is no tree being kept
603
+ * alive in wasm memory for a handle to point at.
604
+ */
605
+ export function parseSnapshot(source: string): string;
606
+
607
+ /**
608
+ * The PART 12 ยง13 source-layout sidecar for a document.
609
+ *
610
+ * Separate from `parseJson`, which carries semantic positions on the nodes.
611
+ * This is the byte-exact record of the SOURCE: its line endings, whether it
612
+ * had a BOM, and a path-addressed byte span per node - what a host needs to
613
+ * write an edit back into the file it came from.
614
+ */
615
+ export function parseSourceLayoutJson(source: string): string;
616
+
617
+ /**
618
+ * Read a document's provenance marker: `{ version, generatedBy }`, or `null`.
619
+ */
620
+ export function readStamp(source: string): Stamp | null;
621
+
622
+ /**
623
+ * Re-parse `source` with `changes` applied.
624
+ *
625
+ * ```js
626
+ * const first = JSON.parse(parseSnapshot('# One\n'))
627
+ * const next = JSON.parse(reparse(first.source, '[{"range":[2,5],"replacement":"Two"}]'))
628
+ * ```
629
+ *
630
+ * `changes` is a JSON array of `{ range: [start, end], replacement }`.
631
+ *
632
+ * THE OFFSETS ARE UTF-8 BYTE OFFSETS, matching `createSourcePatch` ranges.
633
+ * `parseJson` positions count Unicode codepoints instead. A browser editor counts UTF-16 code
634
+ * units, so a host holding a `selectionStart` converts before calling - an
635
+ * offset that lands inside a multi-byte character is refused rather than
636
+ * guessed at.
637
+ *
638
+ * A malformed change THROWS: overlapping ranges, an end past the source, and a
639
+ * range that splits a code point are all a broken caller contract, not a
640
+ * result the caller asked for.
641
+ *
642
+ * `reusedPreviousTree` says whether the parse reused any of the previous one.
643
+ * The engine can reuse unchanged plain paragraphs. Other syntax falls back
644
+ * to a full parse. This function rebuilds the initial snapshot from source;
645
+ * use a parser session to retain it across edits.
646
+ */
647
+ export function reparse(source: string, changes: string): string;
648
+
649
+ /**
650
+ * Sanitize an SVG document, the helper a host embedding SVG would otherwise
651
+ * reimplement.
652
+ *
653
+ * `{ svg, ok }`. `ok` false means the input was not a single well-formed
654
+ * `<svg>` root, and a caller must then show the SOURCE rather than the input:
655
+ * `svg` carries nothing to display. Every option defaults to `false`, which is
656
+ * the strict setting.
657
+ */
658
+ export function sanitizeSvg(source: string, options?: object | null): SanitizeResult;
659
+
660
+ /**
661
+ * Write a provenance marker onto already-formatted Carve.
662
+ *
663
+ * The other half of `readStamp` and `needsReview`, which could read a marker
664
+ * this package had no way to write. `generatedBy` is the engine identity a
665
+ * host wants recorded, e.g. `"my-app 1.2"`; `form` is `"line"` (default) or
666
+ * `"block"`. Same signature as carve-js `stampCarve`.
667
+ *
668
+ * The input is expected to be formatted already: this appends the marker and
669
+ * replaces one the document carries, it does not canonicalize. `toCarve` is
670
+ * the formatter.
671
+ */
672
+ export function stampCarve(formatted: string, generated_by: string, form?: string | null): string;
673
+
674
+ export function toAnsi(source: string): string;
675
+
676
+ export function toCarve(source: string): string;
677
+
678
+ /**
679
+ * Preview canonical formatting as a source-preserving patch.
680
+ */
681
+ export function toCarvePatch(source: string): SourcePatch;
682
+
683
+ export function toHtml(source: string): string;
684
+
685
+ /**
686
+ * Render with the preview extension set enabled (`PREVIEW_EXTENSIONS`), so the
687
+ * WASM engine matches an extensions-on host such as the docs Playground rather
688
+ * than the core-only `toHtml`.
689
+ *
690
+ * The set is curated, not "everything the engine has": `heading-numbers` and
691
+ * `table-of-contents` rewrite a document that never asked for it, which is
692
+ * wrong for a preview. Callers who want an exact set pass `extensions` to
693
+ * `toHtmlWithOptions`, and `extensions()` reports what this build accepts.
694
+ *
695
+ * The optional second argument is the same **symbols map** as
696
+ * [`to_html_with_symbols`], with the same trusted-raw contract: mapped values
697
+ * are emitted UNESCAPED, so never feed it untrusted input.
698
+ */
699
+ export function toHtmlFull(source: string, symbols?: object | null): string;
700
+
701
+ /**
702
+ * Render with the core profile and a **symbols map**: `{ rocket: "๐Ÿš€" }` (a
703
+ * plain object or a `Map`). A `:name:` symbol whose name is in the map renders
704
+ * the mapped value; an unmapped `:name:` stays literal `:name:` text, and the
705
+ * leading word-boundary guard still applies (`a:b:c`, `10:30:`,
706
+ * `me@example.com` never become symbols).
707
+ *
708
+ * Names and values must both be strings; a non-string value throws a JS
709
+ * `TypeError`.
710
+ *
711
+ * SECURITY: a mapped value is inserted as **TRUSTED RAW output in the target
712
+ * format** - it is NOT escaped, the same trust class as the static `renderers`
713
+ * map. So `{ b: "<b>x</b>" }` emits a real `<b>` element, not escaped text.
714
+ * This is deliberate: processor configuration is trusted. NEVER build a
715
+ * symbols map out of untrusted / user-supplied input.
716
+ */
717
+ export function toHtmlWithSymbols(source: string, symbols?: object | null): string;
718
+
719
+ export function toMarkdown(source: string): string;
720
+
721
+ export function toPlainText(source: string): string;
722
+
723
+ /**
724
+ * Convert Carve source to the ProseMirror document shape.
725
+ *
726
+ * ProseMirror runs in a browser and nowhere else, so this is the one engine
727
+ * capability whose whole audience sits behind a WASM binding. Without it a host
728
+ * wiring a Carve editor either round-trips to a server or reimplements the node
729
+ * mapping in JS, where it drifts from the engine's.
730
+ *
731
+ * Returns `{ json, dropped, degraded }`. `json` is the ProseMirror document as
732
+ * a JSON string, the same choice `parseJson` makes and for the same reason.
733
+ * The two maps say what the ProseMirror model could not hold: `dropped` where
734
+ * the content is gone, `degraded` where the text survives without its node
735
+ * type. A silent conversion is the degradation shape `lintCarve` exists to
736
+ * avoid.
737
+ */
738
+ export function toProseMirror(source: string): ProseMirrorResult;
739
+
740
+ export function version(): string;