@takazudo/zfb-md-wasm 2.7.1 → 2.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -22,7 +22,69 @@ binary directly.
22
22
  pnpm add @takazudo/zfb-md-wasm
23
23
  ```
24
24
 
25
- ## Two API tiers
25
+ ## Choose an entry
26
+
27
+ The package has four additive entries. Keep using `.` for the complete current
28
+ API (`compile` plus render, parse, and highlight); root imports do not need a
29
+ migration. `./highlight` is also backward-compatible. New `./render` and
30
+ `./parse` entries are isolated **SWC-free** graphs: they omit `swc_core` and
31
+ `zfb-render` but intentionally retain `zfb-content` and `syntect-fancy`.
32
+ `./parse` is not syntect-free.
33
+
34
+ | Entry | gzip-9 wasm (2.9.0) | Exact runtime values | Exact exported types |
35
+ | --- | ---: | --- | --- |
36
+ | `.` | 1,458,452 B | `init`, `compile`, `renderHtml`, `parseToAst`, `highlightCode`, `version`, `__forceTrapForTests`, `__getTrapRecoveryStateForTests`, `toMdastRoot`, `ZfbMdWasmTrapError`, `ZfbMdWasmTrapRecoveryLimitError`, `MdastAdapterError` | Full current compile/render/parse/raw-mdast/highlight surface |
37
+ | `./highlight` | 758,246 B | `init`, `highlightCode`, `version`, `__forceTrapForTests`, `__getTrapRecoveryStateForTests`, `ZfbMdWasmTrapError`, `ZfbMdWasmTrapRecoveryLimitError` | `HighlightRole`, `HighlightCodeOptions`, `HighlightCodeResult`, `HighlightDiagnostic`, `HighlightDiagnosticSource` |
38
+ | `./render` | 1,011,165 B | `init`, `renderHtml`, `version`, `ZfbMdWasmTrapError`, `ZfbMdWasmTrapRecoveryLimitError`, `__forceTrapForTests`, `__getTrapRecoveryStateForTests` | `RenderHtmlResult`, `Diagnostic`, `DiagnosticSource`, `ZfbMdWasmOptions`, `ParseDialect`, `PipelineOptions`, `GfmOptions`, `CodeHighlightMode`, `CodeHighlightOptions`, `MarkdownFeaturesConfig`, `JsxRuntime`, `HighlightRole` |
39
+ | `./parse` | 276,437 B | `init`, `parseToAst`, `toMdastRoot`, `MdastAdapterError`, `version`, `ZfbMdWasmTrapError`, `ZfbMdWasmTrapRecoveryLimitError`, `__forceTrapForTests`, `__getTrapRecoveryStateForTests` | `ParseToAstResult`, `ParseToAstOptions`, `ParseDialect`, `FrontmatterPolicy`, `ParsePipelineOptions`, `Diagnostic`, `DiagnosticSource`, `AstPoint`, `AstPosition`, `RawMdastData`, `MarkdownRsStop`, `MdastNode`, `MdastRoot`, `UnknownMdastNode`, `Root`, `Paragraph`, `Heading`, `ThematicBreak`, `Blockquote`, `List`, `ListItem`, `Html`, `Code`, `Definition`, `Text`, `DirectiveNodeBase`, `ContainerDirective`, `LeafDirective`, `TextDirective`, `Emphasis`, `Strong`, `InlineCode`, `Break`, `Link`, `Image`, `ReferenceKind`, `LinkReference`, `ImageReference`, `FootnoteDefinition`, `FootnoteReference`, `TableAlign`, `Table`, `TableRow`, `TableCell`, `Delete`, `Yaml`, `MdxFlowExpression`, `MdxTextExpression`, `MdxJsxFlowElement`, `MdxJsxTextElement`, `MdxJsxAttributeContent`, `MdxJsxAttribute`, `MdxJsxAttributeValueExpression`, `MdxJsxExpressionAttribute` |
40
+
41
+ The focused entries own private resource pairs:
42
+
43
+ ```text
44
+ wasm-render/zfb_md_wasm_render_glue.zfb-resource.mjs
45
+ wasm-render/zfb_md_wasm_render_bg.wasm
46
+ wasm-parse/zfb_md_wasm_parse_glue.zfb-resource.mjs
47
+ wasm-parse/zfb_md_wasm_parse_bg.wasm
48
+ ```
49
+
50
+ Each also has only its matching declaration sidecars. Every entry creates its
51
+ own compiled-module, wasm-instance, generation, retry, and terminal state.
52
+ Importing multiple entries intentionally loads independent pairs and instances;
53
+ it does not deduplicate their resources.
54
+
55
+ Migration is only needed when a root consumer calls one focused function:
56
+
57
+ ```ts
58
+ // Direct Node import and browser-aware bundler import.
59
+ import { renderHtml } from "@takazudo/zfb-md-wasm/render";
60
+ import { parseToAst, toMdastRoot } from "@takazudo/zfb-md-wasm/parse";
61
+ ```
62
+
63
+ For browser lazy loading, import from the user action. The conditional browser
64
+ entry uses static URL edges for only that entry's own resource pair:
65
+
66
+ ```ts
67
+ button.addEventListener("click", async () => {
68
+ const { renderHtml } = await import("@takazudo/zfb-md-wasm/render");
69
+ const { html } = await renderHtml(source, { filename: "preview.md" });
70
+ preview.innerHTML = html ?? "";
71
+ });
72
+
73
+ parseButton.addEventListener("click", async () => {
74
+ const { parseToAst, toMdastRoot } = await import("@takazudo/zfb-md-wasm/parse");
75
+ const parsed = await parseToAst(source, { filename: "preview.md" });
76
+ const root = parsed.ast === null ? null : toMdastRoot(parsed.ast);
77
+ inspect(root);
78
+ });
79
+ ```
80
+
81
+ `compile()` remains root-only. It returns module source, not an evaluated
82
+ module; host evaluation must supply the JSX runtime and components. Controlled
83
+ consumer code may interpret an already-parsed AST in a controlled AST-to-React
84
+ renderer, but no slim entry evaluates author JavaScript. `renderHtml` is not a sanitizer and raw HTML remains
85
+ untrusted; MDX JSX, expression, and ESM-shaped AST nodes are inert data.
86
+
87
+ ## Root API
26
88
 
27
89
  Both functions take the markdown/MDX `source` and an options object (every
28
90
  field optional; `{}` selects all defaults). Both return a result object plus a
@@ -72,14 +134,17 @@ plain-markdown preview when you don't need to evaluate a component module.
72
134
  ```ts
73
135
  import { renderHtml } from "@takazudo/zfb-md-wasm";
74
136
 
75
- const { html, frontmatter, diagnostics } = await renderHtml("# Heading\n\nSome **bold** text.\n", {
137
+ const { html, frontmatter, diagnostics } = await renderHtml("Budget <8 ms\n", {
76
138
  filename: "post.md",
77
139
  });
78
- // html -> "<h1>Heading</h1><p>Some <strong>bold</strong> text.</p>"
140
+ // html -> "<p>Budget &lt;8 ms</p>"
79
141
  ```
80
142
 
81
- `renderHtml` accepts and ignores `jsxRuntime` / `development`, so one options
82
- object can serve both tiers.
143
+ `renderHtml` infers CommonMark for `.md` and MDX for `.mdx`; an explicit
144
+ `dialect: "markdown" | "mdx"` overrides either valid extension. Omitting the
145
+ filename uses `<anonymous>.md`, hence CommonMark. `compile` remains MDX-only
146
+ and accepts/ignores `dialect`, while `renderHtml` accepts/ignores
147
+ `jsxRuntime` / `development`, so one options object can serve both tiers.
83
148
 
84
149
  ### `version()` / `init()`
85
150
 
@@ -99,7 +164,7 @@ Shiki classes.
99
164
 
100
165
  If `highlightCode` is the only thing you use, import it from
101
166
  `@takazudo/zfb-md-wasm/highlight` instead of the package root — that entry
102
- ships a separate, much smaller wasm artifact with no `compile`/`renderHtml`
167
+ ships a separate highlight-only wasm artifact with no `compile`/`renderHtml`
103
168
  (and no md/MDX/JSX pipeline behind them at all). Same function, same result
104
169
  shape, same `init()`/`version()`; see "Artifact size" below for the byte
105
170
  savings.
@@ -110,7 +175,7 @@ import {
110
175
  type HighlightCodeOptions,
111
176
  type HighlightCodeResult,
112
177
  } from "@takazudo/zfb-md-wasm";
113
- // or, for the smaller highlight-only artifact:
178
+ // or, for the highlight-only artifact:
114
179
  // } from "@takazudo/zfb-md-wasm/highlight";
115
180
 
116
181
  const output: HighlightCodeResult = await highlightCode("const answer = 42;", {
@@ -403,25 +468,37 @@ for your own environment.
403
468
 
404
469
  ## Browser loading and emitted resources
405
470
 
406
- The package root has a `browser` export condition. Its browser entry imports
407
- the generated glue and Wasm binary through an explicit bundler `?url` asset
471
+ Every entry has a `browser` export condition. Its browser entry imports the
472
+ generated glue and Wasm binary through an explicit bundler `?url` asset
408
473
  contract. Vite and zfb's pinned esbuild setup therefore keep separate resource
409
- edges for exactly `zfb_md_wasm_glue.zfb-resource.mjs` and
410
- `zfb_md_wasm_bg.wasm`; a zfb production build emits them under hashed names:
474
+ edges for exactly its own pair. The focused pairs are:
411
475
 
412
476
  ```text
413
- assets/islands-resource-zfb_md_wasm_glue.zfb-resource-<hash>.mjs
414
- assets/islands-resource-zfb_md_wasm_bg-<hash>.wasm
477
+ wasm-render/zfb_md_wasm_render_glue.zfb-resource.mjs
478
+ wasm-render/zfb_md_wasm_render_bg.wasm
479
+ wasm-parse/zfb_md_wasm_parse_glue.zfb-resource.mjs
480
+ wasm-parse/zfb_md_wasm_parse_bg.wasm
415
481
  ```
416
482
 
483
+ Root and highlight retain their existing `wasm/` and `wasm-highlight/` pairs;
484
+ each directory is closed with its matching glue/wasm declaration sidecars. A
485
+ zfb production build emits each selected pair under hashed names.
486
+
417
487
  Keep the package import in a user action when first-load cost matters:
418
488
 
419
489
  ```ts
420
490
  button.addEventListener("click", async () => {
421
- const { highlightCode } = await import("@takazudo/zfb-md-wasm");
422
- const result = await highlightCode(editor.value, { language: "javascript" });
491
+ const { renderHtml } = await import("@takazudo/zfb-md-wasm/render");
492
+ const result = await renderHtml(editor.value, { filename: "preview.md" });
423
493
  preview.innerHTML = result.html ?? "";
424
494
  });
495
+
496
+ parseButton.addEventListener("click", async () => {
497
+ const { parseToAst, toMdastRoot } = await import("@takazudo/zfb-md-wasm/parse");
498
+ const parsed = await parseToAst(editor.value, { filename: "preview.md" });
499
+ const root = parsed.ast === null ? null : toMdastRoot(parsed.ast);
500
+ inspect(root);
501
+ });
425
502
  ```
426
503
 
427
504
  That import/call boundary keeps both resources unloaded before the action;
@@ -432,18 +509,17 @@ replace the static imports with source paths or manually copied resource
432
509
  files, which breaks the emitted URL graph. No Vite plugin, alias, or
433
510
  package-specific consumer configuration is required.
434
511
 
435
- The `./highlight` subpath (see "Artifact size" above) has the identical
436
- `browser` export condition and resource-loading contract, pointed at its own
437
- separate resources: `zfb_md_wasm_highlight_glue.zfb-resource.mjs` and
438
- `zfb_md_wasm_highlight_bg.wasm`. Importing `@takazudo/zfb-md-wasm` and
439
- `@takazudo/zfb-md-wasm/highlight` in the same bundle loads BOTH wasm
440
- artifacts — pick one entry per bundle.
512
+ The `./highlight` subpath has the identical `browser` export condition and
513
+ resource-loading contract, pointed at its own separate resources. Importing
514
+ multiple entries in the same bundle intentionally loads each private pair and
515
+ creates independent wasm state; no entry evicts or shares another's instance.
441
516
 
442
517
  ## Options shape
443
518
 
444
519
  ```ts
445
520
  interface ZfbMdWasmOptions {
446
521
  filename?: string; // must end .md/.mdx; drives frontmatter dispatch + diagnostics
522
+ dialect?: "markdown" | "mdx"; // renderHtml only; inferred from filename when absent
447
523
  jsxRuntime?: "preact" | "react"; // compile only; default "preact"
448
524
  development?: boolean; // compile only; default false
449
525
  pipeline?: {
@@ -574,9 +650,20 @@ alias.
574
650
  ## Node usage
575
651
 
576
652
  For tests and tooling, the package loads and runs under Node ≥ 20 with no extra
577
- setup the same `compile` / `renderHtml` / `parseToAst` / `version` API. This
578
- is exactly how this package's own vitest suite (and `parseToAst`'s Node
579
- benchmark against `remark-parse`) exercises the wasm.
653
+ setup. Direct imports select the resource pair that matches the operation:
654
+
655
+ ```ts
656
+ import { renderHtml } from "@takazudo/zfb-md-wasm/render";
657
+ import { parseToAst, toMdastRoot } from "@takazudo/zfb-md-wasm/parse";
658
+
659
+ const { html } = await renderHtml("# Hello from Node\n");
660
+ const parsed = await parseToAst("# Hello from Node\n", { filename: "post.md" });
661
+ const root = parsed.ast === null ? null : toMdastRoot(parsed.ast);
662
+ ```
663
+
664
+ The root import remains the compatibility choice for code that also calls
665
+ `compile`, and the existing highlight import remains compatible. This is also
666
+ how the package's vitest suite and parse benchmark exercise the built wasm.
580
667
 
581
668
  ## Parity guarantee & limitations
582
669
 
@@ -593,37 +680,80 @@ suite gates exact-match). Deliberate limitations of the browser build:
593
680
  - **No cross-file features.** Route-table link resolution and cross-file anchor
594
681
  resolution need the whole project graph, which a single-document browser call
595
682
  doesn't have.
596
- - **The default artifact carries SWC even for `renderHtml`-only use.** One
597
- cdylib can't tree-shake SWC away when only `renderHtml` is called; a slim
598
- `renderHtml`-only artifact is a documented possible follow-up. If you only
599
- ever call `highlightCode`, use the `./highlight` entry instead (see
600
- "Artifact size" below) it drops `compile`/`renderHtml` and the whole
601
- md/MDX/JSX pipeline entirely.
602
- - **Grammar subsetting is not built.** Both artifacts ship every bundled
683
+ - **Choose a focused artifact for non-compile calls.** The root remains the
684
+ compatibility entry and carries the complete compiler graph. `./highlight`
685
+ keeps its public API and resources while the post-#2449/#2450 graph is
686
+ proven SWC-free and its payload shows it: 758,246 B gzip-9 versus
687
+ 1,458,452 B for root. `./render` and `./parse` are also SWC-free and omit
688
+ `zfb-render`; parse intentionally retains `zfb-content`/`syntect-fancy`, so
689
+ it is not syntect-free. Use `./render` or `./parse` when a consumer does
690
+ not need `compile`; root and highlight callers otherwise require no
691
+ migration.
692
+ - **`compile` is the execution boundary.** It returns ES-module source and
693
+ only the root entry exposes it. Host code must explicitly evaluate that
694
+ source and provide the JSX runtime/components. Controlled consumer code may
695
+ interpret an already-parsed AST; no slim entry evaluates author JavaScript.
696
+ - **`renderHtml` is not a sanitizer.** Raw HTML remains untrusted, and JSX,
697
+ expression, or ESM-shaped AST nodes from MDX remain inert data.
698
+ - **`renderHtml` selects syntax from the filename.** `.md` uses CommonMark,
699
+ `.mdx` uses MDX, and an explicit `dialect` overrides either valid extension.
700
+ `compile` remains MDX-only.
701
+ - **Grammar subsetting is not built.** All four artifacts ship every bundled
603
702
  syntect grammar; there is no per-language allowlist knob.
604
703
  - **Syntax highlighting uses syntect's `fancy-regex` backend** (native zfb uses
605
704
  `oniguruma`, which can't compile to wasm). The two are byte-identical on
606
705
  zfb's fixture corpus; any grammar-level divergences are tracked in the
607
706
  crate's informational backend-divergence test.
608
707
 
609
- ## Artifact size
610
-
611
- Shipping SWC in the bytes makes the default module large. The build applies a
612
- size-optimized cargo profile (`opt-level = "z"`, LTO, one codegen unit,
613
- `panic = "abort"`) plus `wasm-opt`, which roughly halves the raw binary either
614
- way. The package ships **two** wasm artifacts (zfb#1849, epic zfb#1845):
615
-
616
- | Entry | Import | What it has | Raw `.wasm` | Gzipped |
617
- | -------------- | --------------------------------- | ----------------------------------------------------- | ----------- | ------- |
618
- | Default | `@takazudo/zfb-md-wasm` | `compile` + `renderHtml` + `highlightCode` | ~2.9 MB | ~1.3 MB |
619
- | Highlight-only | `@takazudo/zfb-md-wasm/highlight` | `highlightCode` only (no md/MDX/JSX pipeline, no SWC) | ~1.4 MB | ~0.7 MB |
620
-
621
- The highlight-only artifact drops the `pipeline` Cargo feature entirely (see
622
- `crates/zfb-md-wasm/Cargo.toml`) rather than subsetting syntect grammars
623
- both artifacts bundle every grammar (see "Grammar subsetting is not built"
624
- above). The CI `wasm-md` job prints the authoritative gzipped size for BOTH
625
- artifacts on every run — treat that as the source of truth rather than this
626
- table, which can drift.
708
+ ## Artifact size and locked ceilings
709
+
710
+ ### Maintainer repair workflow
711
+
712
+ These guarded size numbers use `crates/zfb-md-wasm/shipped-sizes.json` as their
713
+ source of truth. After an intentional artifact change, use this verified
714
+ three-step repair sequence:
715
+
716
+ 1. Re-run the four-artifact build and capture its summary:
717
+ `BUILD_LOG=/tmp/zfb-md-wasm-build.log; node crates/zfb-md-wasm/npm/scripts/build.mjs 2>&1 | tee "$BUILD_LOG"`.
718
+ 2. Run `node scripts/assert-zfb-md-wasm-budgets.mjs --build-log "$BUILD_LOG" --dist crates/zfb-md-wasm/npm/dist --update-manifest`.
719
+ 3. Run `node scripts/assert-md-wasm-size-docs.mjs --fix`, then `pnpm format:mdx`.
720
+
721
+ These are the shipped **2.9.0** artifact rows optimized final wasm after
722
+ wasm-bindgen and wasm-opt, Node `gzipSync(..., { level: 9 })`, and glue
723
+ bytes/gzip:
724
+
725
+ | Entry/graph | final wasm | gzip-9 | glue | glue gzip-9 |
726
+ | --- | ---: | ---: | ---: | ---: |
727
+ | root (full) | 3,274,064 B | 1,458,452 B | 14,998 B | 4,199 B |
728
+ | highlight | 1,476,740 B | 758,246 B | 8,758 B | 2,637 B |
729
+ | render | 2,083,465 B | 1,011,165 B | 8,772 B | 2,661 B |
730
+ | parse | 624,976 B | 276,437 B | 11,159 B | 3,797 B |
731
+
732
+ The #2447 decision snapshot measured the split package at 3,638,607 B versus
733
+ 2,314,818 B for the root-plus-highlight package. Locked gzip-9 ceilings are
734
+ root 1,600,000 B, highlight 820,000 B, render 1,100,000 B, and parse
735
+ 325,000 B; the complete packed tarball ceiling is 3,900,000 B. All four ship
736
+ inside their ceilings, with 141,548 B (root), 61,754 B (highlight), 88,835 B
737
+ (render), and 48,563 B (parse) of headroom. These are 2.9.0 measurements, not
738
+ permanent promises — re-measure against the version you actually install.
739
+ The clean four-step production ceiling is 210 seconds; the selected #2447
740
+ median was 155.015 s [153.496, 165.977].
741
+
742
+ Gating `swc_core` out of the highlight graph (#2449/#2450) was a
743
+ **provability win, not a size win**. The shipped highlight artifact is only
744
+ 7,965 B smaller than #2447's SWC-retaining baseline (1,484,705 B →
745
+ 1,476,740 B; gzip-9 767,009 B → 758,244 B, −8,765 B) — wasm-opt was already
746
+ dead-stripping the unreachable `swc_core`, and #2450's exact-parity and
747
+ no-`swc_core` assertions turned that emergent property into a guaranteed one.
748
+ The delta that matters to a highlight-only consumer is root versus
749
+ highlight: the highlight artifact is 1,797,324 B smaller raw and 700,206 B
750
+ smaller gzip-9, landing at about 45% of root's raw bytes and 52% of its
751
+ gzipped bytes.
752
+
753
+ Every shipped final wasm came in under its #2447 candidate measurement: root
754
+ −62,869 B, highlight −7,965 B, render −39,844 B, parse −25,482 B. The glue
755
+ rows moved the other way by a negligible amount (root +117 B, render +135 B,
756
+ parse +18 B; highlight unchanged).
627
757
 
628
758
  ## Error / trap / re-init contract
629
759
 
@@ -0,0 +1,12 @@
1
+ export declare const init: () => Promise<void>, parseToAst: (source: string, options?: import("./types.js").ParseToAstOptions) => Promise<import("./types.js").ParseToAstResult>, version: () => Promise<string>, __forceTrapForTests: () => Promise<void>, __getTrapRecoveryStateForTests: () => {
2
+ compiledModuleLoads: number;
3
+ currentGeneration: number;
4
+ freshInstanceStarts: number;
5
+ glueImportAttempts: number;
6
+ maxTrapRecoveries: number;
7
+ trapRecoveriesStarted: number;
8
+ terminal: boolean;
9
+ };
10
+ export { MdastAdapterError, toMdastRoot } from "./mdast.js";
11
+ export { ZfbMdWasmTrapError, ZfbMdWasmTrapRecoveryLimitError } from "./runtime.js";
12
+ export type { ParseToAstResult, ParseToAstOptions, ParseDialect, FrontmatterPolicy, ParsePipelineOptions, Diagnostic, DiagnosticSource, AstPoint, AstPosition, RawMdastData, MarkdownRsStop, MdastNode, MdastRoot, UnknownMdastNode, Root, Paragraph, Heading, ThematicBreak, Blockquote, List, ListItem, Html, Code, Definition, Text, DirectiveNodeBase, ContainerDirective, LeafDirective, TextDirective, Emphasis, Strong, InlineCode, Break, Link, Image, ReferenceKind, LinkReference, ImageReference, FootnoteDefinition, FootnoteReference, TableAlign, Table, TableRow, TableCell, Delete, Yaml, MdxFlowExpression, MdxTextExpression, MdxJsxFlowElement, MdxJsxTextElement, MdxJsxAttributeContent, MdxJsxAttribute, MdxJsxAttributeValueExpression, MdxJsxExpressionAttribute, } from "./types.js";
@@ -0,0 +1,17 @@
1
+ import glueHref from "./wasm-parse/zfb_md_wasm_parse_glue.zfb-resource.mjs?url";
2
+ import wasmHref from "./wasm-parse/zfb_md_wasm_parse_bg.wasm?url";
3
+ import { createWasmApi } from "./runtime.js";
4
+ const GLUE_URL = new URL(glueHref, import.meta.url);
5
+ const WASM_URL = new URL(wasmHref, import.meta.url);
6
+ async function loadBrowserWasmBytes() {
7
+ const response = await fetch(WASM_URL);
8
+ if (!response.ok) {
9
+ throw new Error(`zfb-md-wasm: failed to fetch wasm binary: ${response.status} ${response.statusText}`);
10
+ }
11
+ return response.arrayBuffer();
12
+ }
13
+ const api = createWasmApi({ glueUrl: GLUE_URL, loadWasmBytes: loadBrowserWasmBytes });
14
+ export const { init, parseToAst, version, __forceTrapForTests, __getTrapRecoveryStateForTests } = api;
15
+ export { MdastAdapterError, toMdastRoot } from "./mdast.js";
16
+ export { ZfbMdWasmTrapError, ZfbMdWasmTrapRecoveryLimitError } from "./runtime.js";
17
+ //# sourceMappingURL=parse-browser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-browser.js","sourceRoot":"","sources":["../src/parse-browser.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,0DAA0D,CAAC;AAChF,OAAO,QAAQ,MAAM,4CAA4C,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACpD,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAEpD,KAAK,UAAU,oBAAoB;IACjC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,QAAQ,CAAC,CAAC;IACvC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CACb,6CAA6C,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CACtF,CAAC;IACJ,CAAC;IACD,OAAO,QAAQ,CAAC,WAAW,EAAE,CAAC;AAChC,CAAC;AAED,MAAM,GAAG,GAAG,aAAa,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,oBAAoB,EAAE,CAAC,CAAC;AAEtF,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,mBAAmB,EAAE,8BAA8B,EAAE,GAC7F,GAAG,CAAC;AAEN,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,+BAA+B,EAAE,MAAM,cAAc,CAAC","sourcesContent":["import glueHref from \"./wasm-parse/zfb_md_wasm_parse_glue.zfb-resource.mjs?url\";\nimport wasmHref from \"./wasm-parse/zfb_md_wasm_parse_bg.wasm?url\";\nimport { createWasmApi } from \"./runtime.js\";\n\nconst GLUE_URL = new URL(glueHref, import.meta.url);\nconst WASM_URL = new URL(wasmHref, import.meta.url);\n\nasync function loadBrowserWasmBytes(): Promise<ArrayBuffer> {\n const response = await fetch(WASM_URL);\n if (!response.ok) {\n throw new Error(\n `zfb-md-wasm: failed to fetch wasm binary: ${response.status} ${response.statusText}`,\n );\n }\n return response.arrayBuffer();\n}\n\nconst api = createWasmApi({ glueUrl: GLUE_URL, loadWasmBytes: loadBrowserWasmBytes });\n\nexport const { init, parseToAst, version, __forceTrapForTests, __getTrapRecoveryStateForTests } =\n api;\n\nexport { MdastAdapterError, toMdastRoot } from \"./mdast.js\";\nexport { ZfbMdWasmTrapError, ZfbMdWasmTrapRecoveryLimitError } from \"./runtime.js\";\nexport type {\n ParseToAstResult,\n ParseToAstOptions,\n ParseDialect,\n FrontmatterPolicy,\n ParsePipelineOptions,\n Diagnostic,\n DiagnosticSource,\n AstPoint,\n AstPosition,\n RawMdastData,\n MarkdownRsStop,\n MdastNode,\n MdastRoot,\n UnknownMdastNode,\n Root,\n Paragraph,\n Heading,\n ThematicBreak,\n Blockquote,\n List,\n ListItem,\n Html,\n Code,\n Definition,\n Text,\n DirectiveNodeBase,\n ContainerDirective,\n LeafDirective,\n TextDirective,\n Emphasis,\n Strong,\n InlineCode,\n Break,\n Link,\n Image,\n ReferenceKind,\n LinkReference,\n ImageReference,\n FootnoteDefinition,\n FootnoteReference,\n TableAlign,\n Table,\n TableRow,\n TableCell,\n Delete,\n Yaml,\n MdxFlowExpression,\n MdxTextExpression,\n MdxJsxFlowElement,\n MdxJsxTextElement,\n MdxJsxAttributeContent,\n MdxJsxAttribute,\n MdxJsxAttributeValueExpression,\n MdxJsxExpressionAttribute,\n} from \"./types.js\";\n"]}
@@ -0,0 +1,12 @@
1
+ export declare const init: () => Promise<void>, parseToAst: (source: string, options?: import("./types.js").ParseToAstOptions) => Promise<import("./types.js").ParseToAstResult>, version: () => Promise<string>, __forceTrapForTests: () => Promise<void>, __getTrapRecoveryStateForTests: () => {
2
+ compiledModuleLoads: number;
3
+ currentGeneration: number;
4
+ freshInstanceStarts: number;
5
+ glueImportAttempts: number;
6
+ maxTrapRecoveries: number;
7
+ trapRecoveriesStarted: number;
8
+ terminal: boolean;
9
+ };
10
+ export { MdastAdapterError, toMdastRoot } from "./mdast.js";
11
+ export { ZfbMdWasmTrapError, ZfbMdWasmTrapRecoveryLimitError } from "./runtime.js";
12
+ export type { ParseToAstResult, ParseToAstOptions, ParseDialect, FrontmatterPolicy, ParsePipelineOptions, Diagnostic, DiagnosticSource, AstPoint, AstPosition, RawMdastData, MarkdownRsStop, MdastNode, MdastRoot, UnknownMdastNode, Root, Paragraph, Heading, ThematicBreak, Blockquote, List, ListItem, Html, Code, Definition, Text, DirectiveNodeBase, ContainerDirective, LeafDirective, TextDirective, Emphasis, Strong, InlineCode, Break, Link, Image, ReferenceKind, LinkReference, ImageReference, FootnoteDefinition, FootnoteReference, TableAlign, Table, TableRow, TableCell, Delete, Yaml, MdxFlowExpression, MdxTextExpression, MdxJsxFlowElement, MdxJsxTextElement, MdxJsxAttributeContent, MdxJsxAttribute, MdxJsxAttributeValueExpression, MdxJsxExpressionAttribute, } from "./types.js";
package/dist/parse.js ADDED
@@ -0,0 +1,23 @@
1
+ import { createWasmApi } from "./runtime.js";
2
+ const GLUE_URL = new URL("./wasm-parse/zfb_md_wasm_parse_glue.zfb-resource.mjs", import.meta.url);
3
+ const WASM_URL = new URL("./wasm-parse/zfb_md_wasm_parse_bg.wasm", import.meta.url);
4
+ async function loadDirectWasmBytes() {
5
+ if (typeof process !== "undefined" && process.versions?.node) {
6
+ const [{ readFile }, { fileURLToPath }] = await Promise.all([
7
+ import("node:fs/promises"),
8
+ import("node:url"),
9
+ ]);
10
+ const bytes = await readFile(fileURLToPath(WASM_URL));
11
+ return bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
12
+ }
13
+ const response = await fetch(WASM_URL);
14
+ if (!response.ok) {
15
+ throw new Error(`zfb-md-wasm: failed to fetch wasm binary: ${response.status} ${response.statusText}`);
16
+ }
17
+ return response.arrayBuffer();
18
+ }
19
+ const api = createWasmApi({ glueUrl: GLUE_URL, loadWasmBytes: loadDirectWasmBytes });
20
+ export const { init, parseToAst, version, __forceTrapForTests, __getTrapRecoveryStateForTests } = api;
21
+ export { MdastAdapterError, toMdastRoot } from "./mdast.js";
22
+ export { ZfbMdWasmTrapError, ZfbMdWasmTrapRecoveryLimitError } from "./runtime.js";
23
+ //# sourceMappingURL=parse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse.js","sourceRoot":"","sources":["../src/parse.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,sDAAsD,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClG,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,wCAAwC,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAEpF,KAAK,UAAU,mBAAmB;IAChC,IAAI,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC;QAC7D,MAAM,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,aAAa,EAAE,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YAC1D,MAAM,CAAC,kBAAkB,CAAC;YAC1B,MAAM,CAAC,UAAU,CAAC;SACnB,CAAC,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC;QACtD,OAAO,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,UAAU,GAAG,KAAK,CAAC,UAAU,CAAgB,CAAC;IAClG,CAAC;IACD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,QAAQ,CAAC,CAAC;IACvC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CACb,6CAA6C,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CACtF,CAAC;IACJ,CAAC;IACD,OAAO,QAAQ,CAAC,WAAW,EAAE,CAAC;AAChC,CAAC;AAED,MAAM,GAAG,GAAG,aAAa,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,mBAAmB,EAAE,CAAC,CAAC;AAErF,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,mBAAmB,EAAE,8BAA8B,EAAE,GAC7F,GAAG,CAAC;AAEN,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,+BAA+B,EAAE,MAAM,cAAc,CAAC","sourcesContent":["import { createWasmApi } from \"./runtime.js\";\n\nconst GLUE_URL = new URL(\"./wasm-parse/zfb_md_wasm_parse_glue.zfb-resource.mjs\", import.meta.url);\nconst WASM_URL = new URL(\"./wasm-parse/zfb_md_wasm_parse_bg.wasm\", import.meta.url);\n\nasync function loadDirectWasmBytes(): Promise<ArrayBuffer> {\n if (typeof process !== \"undefined\" && process.versions?.node) {\n const [{ readFile }, { fileURLToPath }] = await Promise.all([\n import(\"node:fs/promises\"),\n import(\"node:url\"),\n ]);\n const bytes = await readFile(fileURLToPath(WASM_URL));\n return bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength) as ArrayBuffer;\n }\n const response = await fetch(WASM_URL);\n if (!response.ok) {\n throw new Error(\n `zfb-md-wasm: failed to fetch wasm binary: ${response.status} ${response.statusText}`,\n );\n }\n return response.arrayBuffer();\n}\n\nconst api = createWasmApi({ glueUrl: GLUE_URL, loadWasmBytes: loadDirectWasmBytes });\n\nexport const { init, parseToAst, version, __forceTrapForTests, __getTrapRecoveryStateForTests } =\n api;\n\nexport { MdastAdapterError, toMdastRoot } from \"./mdast.js\";\nexport { ZfbMdWasmTrapError, ZfbMdWasmTrapRecoveryLimitError } from \"./runtime.js\";\nexport type {\n ParseToAstResult,\n ParseToAstOptions,\n ParseDialect,\n FrontmatterPolicy,\n ParsePipelineOptions,\n Diagnostic,\n DiagnosticSource,\n AstPoint,\n AstPosition,\n RawMdastData,\n MarkdownRsStop,\n MdastNode,\n MdastRoot,\n UnknownMdastNode,\n Root,\n Paragraph,\n Heading,\n ThematicBreak,\n Blockquote,\n List,\n ListItem,\n Html,\n Code,\n Definition,\n Text,\n DirectiveNodeBase,\n ContainerDirective,\n LeafDirective,\n TextDirective,\n Emphasis,\n Strong,\n InlineCode,\n Break,\n Link,\n Image,\n ReferenceKind,\n LinkReference,\n ImageReference,\n FootnoteDefinition,\n FootnoteReference,\n TableAlign,\n Table,\n TableRow,\n TableCell,\n Delete,\n Yaml,\n MdxFlowExpression,\n MdxTextExpression,\n MdxJsxFlowElement,\n MdxJsxTextElement,\n MdxJsxAttributeContent,\n MdxJsxAttribute,\n MdxJsxAttributeValueExpression,\n MdxJsxExpressionAttribute,\n} from \"./types.js\";\n"]}
@@ -0,0 +1,11 @@
1
+ export declare const init: () => Promise<void>, renderHtml: (source: string, options?: import("./types.js").ZfbMdWasmOptions) => Promise<import("./types.js").RenderHtmlResult>, version: () => Promise<string>, __forceTrapForTests: () => Promise<void>, __getTrapRecoveryStateForTests: () => {
2
+ compiledModuleLoads: number;
3
+ currentGeneration: number;
4
+ freshInstanceStarts: number;
5
+ glueImportAttempts: number;
6
+ maxTrapRecoveries: number;
7
+ trapRecoveriesStarted: number;
8
+ terminal: boolean;
9
+ };
10
+ export { ZfbMdWasmTrapError, ZfbMdWasmTrapRecoveryLimitError } from "./runtime.js";
11
+ export type { RenderHtmlResult, Diagnostic, DiagnosticSource, ZfbMdWasmOptions, ParseDialect, PipelineOptions, GfmOptions, CodeHighlightMode, CodeHighlightOptions, MarkdownFeaturesConfig, JsxRuntime, HighlightRole, } from "./types.js";
@@ -0,0 +1,16 @@
1
+ import glueHref from "./wasm-render/zfb_md_wasm_render_glue.zfb-resource.mjs?url";
2
+ import wasmHref from "./wasm-render/zfb_md_wasm_render_bg.wasm?url";
3
+ import { createWasmApi } from "./runtime.js";
4
+ const GLUE_URL = new URL(glueHref, import.meta.url);
5
+ const WASM_URL = new URL(wasmHref, import.meta.url);
6
+ async function loadBrowserWasmBytes() {
7
+ const response = await fetch(WASM_URL);
8
+ if (!response.ok) {
9
+ throw new Error(`zfb-md-wasm: failed to fetch wasm binary: ${response.status} ${response.statusText}`);
10
+ }
11
+ return response.arrayBuffer();
12
+ }
13
+ const api = createWasmApi({ glueUrl: GLUE_URL, loadWasmBytes: loadBrowserWasmBytes });
14
+ export const { init, renderHtml, version, __forceTrapForTests, __getTrapRecoveryStateForTests } = api;
15
+ export { ZfbMdWasmTrapError, ZfbMdWasmTrapRecoveryLimitError } from "./runtime.js";
16
+ //# sourceMappingURL=render-browser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render-browser.js","sourceRoot":"","sources":["../src/render-browser.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,4DAA4D,CAAC;AAClF,OAAO,QAAQ,MAAM,8CAA8C,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACpD,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAEpD,KAAK,UAAU,oBAAoB;IACjC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,QAAQ,CAAC,CAAC;IACvC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CACb,6CAA6C,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CACtF,CAAC;IACJ,CAAC;IACD,OAAO,QAAQ,CAAC,WAAW,EAAE,CAAC;AAChC,CAAC;AAED,MAAM,GAAG,GAAG,aAAa,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,oBAAoB,EAAE,CAAC,CAAC;AAEtF,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,mBAAmB,EAAE,8BAA8B,EAAE,GAC7F,GAAG,CAAC;AAEN,OAAO,EAAE,kBAAkB,EAAE,+BAA+B,EAAE,MAAM,cAAc,CAAC","sourcesContent":["import glueHref from \"./wasm-render/zfb_md_wasm_render_glue.zfb-resource.mjs?url\";\nimport wasmHref from \"./wasm-render/zfb_md_wasm_render_bg.wasm?url\";\nimport { createWasmApi } from \"./runtime.js\";\n\nconst GLUE_URL = new URL(glueHref, import.meta.url);\nconst WASM_URL = new URL(wasmHref, import.meta.url);\n\nasync function loadBrowserWasmBytes(): Promise<ArrayBuffer> {\n const response = await fetch(WASM_URL);\n if (!response.ok) {\n throw new Error(\n `zfb-md-wasm: failed to fetch wasm binary: ${response.status} ${response.statusText}`,\n );\n }\n return response.arrayBuffer();\n}\n\nconst api = createWasmApi({ glueUrl: GLUE_URL, loadWasmBytes: loadBrowserWasmBytes });\n\nexport const { init, renderHtml, version, __forceTrapForTests, __getTrapRecoveryStateForTests } =\n api;\n\nexport { ZfbMdWasmTrapError, ZfbMdWasmTrapRecoveryLimitError } from \"./runtime.js\";\nexport type {\n RenderHtmlResult,\n Diagnostic,\n DiagnosticSource,\n ZfbMdWasmOptions,\n ParseDialect,\n PipelineOptions,\n GfmOptions,\n CodeHighlightMode,\n CodeHighlightOptions,\n MarkdownFeaturesConfig,\n JsxRuntime,\n HighlightRole,\n} from \"./types.js\";\n"]}
@@ -0,0 +1,11 @@
1
+ export declare const init: () => Promise<void>, renderHtml: (source: string, options?: import("./types.js").ZfbMdWasmOptions) => Promise<import("./types.js").RenderHtmlResult>, version: () => Promise<string>, __forceTrapForTests: () => Promise<void>, __getTrapRecoveryStateForTests: () => {
2
+ compiledModuleLoads: number;
3
+ currentGeneration: number;
4
+ freshInstanceStarts: number;
5
+ glueImportAttempts: number;
6
+ maxTrapRecoveries: number;
7
+ trapRecoveriesStarted: number;
8
+ terminal: boolean;
9
+ };
10
+ export { ZfbMdWasmTrapError, ZfbMdWasmTrapRecoveryLimitError } from "./runtime.js";
11
+ export type { RenderHtmlResult, Diagnostic, DiagnosticSource, ZfbMdWasmOptions, ParseDialect, PipelineOptions, GfmOptions, CodeHighlightMode, CodeHighlightOptions, MarkdownFeaturesConfig, JsxRuntime, HighlightRole, } from "./types.js";
package/dist/render.js ADDED
@@ -0,0 +1,22 @@
1
+ import { createWasmApi } from "./runtime.js";
2
+ const GLUE_URL = new URL("./wasm-render/zfb_md_wasm_render_glue.zfb-resource.mjs", import.meta.url);
3
+ const WASM_URL = new URL("./wasm-render/zfb_md_wasm_render_bg.wasm", import.meta.url);
4
+ async function loadDirectWasmBytes() {
5
+ if (typeof process !== "undefined" && process.versions?.node) {
6
+ const [{ readFile }, { fileURLToPath }] = await Promise.all([
7
+ import("node:fs/promises"),
8
+ import("node:url"),
9
+ ]);
10
+ const bytes = await readFile(fileURLToPath(WASM_URL));
11
+ return bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
12
+ }
13
+ const response = await fetch(WASM_URL);
14
+ if (!response.ok) {
15
+ throw new Error(`zfb-md-wasm: failed to fetch wasm binary: ${response.status} ${response.statusText}`);
16
+ }
17
+ return response.arrayBuffer();
18
+ }
19
+ const api = createWasmApi({ glueUrl: GLUE_URL, loadWasmBytes: loadDirectWasmBytes });
20
+ export const { init, renderHtml, version, __forceTrapForTests, __getTrapRecoveryStateForTests } = api;
21
+ export { ZfbMdWasmTrapError, ZfbMdWasmTrapRecoveryLimitError } from "./runtime.js";
22
+ //# sourceMappingURL=render.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.js","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,wDAAwD,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACpG,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,0CAA0C,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAEtF,KAAK,UAAU,mBAAmB;IAChC,IAAI,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC;QAC7D,MAAM,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,aAAa,EAAE,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YAC1D,MAAM,CAAC,kBAAkB,CAAC;YAC1B,MAAM,CAAC,UAAU,CAAC;SACnB,CAAC,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC;QACtD,OAAO,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,UAAU,GAAG,KAAK,CAAC,UAAU,CAAgB,CAAC;IAClG,CAAC;IACD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,QAAQ,CAAC,CAAC;IACvC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CACb,6CAA6C,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CACtF,CAAC;IACJ,CAAC;IACD,OAAO,QAAQ,CAAC,WAAW,EAAE,CAAC;AAChC,CAAC;AAED,MAAM,GAAG,GAAG,aAAa,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,mBAAmB,EAAE,CAAC,CAAC;AAErF,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,mBAAmB,EAAE,8BAA8B,EAAE,GAC7F,GAAG,CAAC;AAEN,OAAO,EAAE,kBAAkB,EAAE,+BAA+B,EAAE,MAAM,cAAc,CAAC","sourcesContent":["import { createWasmApi } from \"./runtime.js\";\n\nconst GLUE_URL = new URL(\"./wasm-render/zfb_md_wasm_render_glue.zfb-resource.mjs\", import.meta.url);\nconst WASM_URL = new URL(\"./wasm-render/zfb_md_wasm_render_bg.wasm\", import.meta.url);\n\nasync function loadDirectWasmBytes(): Promise<ArrayBuffer> {\n if (typeof process !== \"undefined\" && process.versions?.node) {\n const [{ readFile }, { fileURLToPath }] = await Promise.all([\n import(\"node:fs/promises\"),\n import(\"node:url\"),\n ]);\n const bytes = await readFile(fileURLToPath(WASM_URL));\n return bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength) as ArrayBuffer;\n }\n const response = await fetch(WASM_URL);\n if (!response.ok) {\n throw new Error(\n `zfb-md-wasm: failed to fetch wasm binary: ${response.status} ${response.statusText}`,\n );\n }\n return response.arrayBuffer();\n}\n\nconst api = createWasmApi({ glueUrl: GLUE_URL, loadWasmBytes: loadDirectWasmBytes });\n\nexport const { init, renderHtml, version, __forceTrapForTests, __getTrapRecoveryStateForTests } =\n api;\n\nexport { ZfbMdWasmTrapError, ZfbMdWasmTrapRecoveryLimitError } from \"./runtime.js\";\nexport type {\n RenderHtmlResult,\n Diagnostic,\n DiagnosticSource,\n ZfbMdWasmOptions,\n ParseDialect,\n PipelineOptions,\n GfmOptions,\n CodeHighlightMode,\n CodeHighlightOptions,\n MarkdownFeaturesConfig,\n JsxRuntime,\n HighlightRole,\n} from \"./types.js\";\n"]}
package/dist/runtime.d.ts CHANGED
@@ -6,7 +6,7 @@ interface WasmGlueModule {
6
6
  compile?(source: string, optionsJson: string): string;
7
7
  renderHtml?(source: string, optionsJson: string): string;
8
8
  parseToAst?(source: string, optionsJson: string): string;
9
- highlightCode(code: string, optionsJson: string): string;
9
+ highlightCode?(code: string, optionsJson: string): string;
10
10
  version(): string;
11
11
  __forceTrapForTests(): void;
12
12
  }
package/dist/runtime.js CHANGED
@@ -122,26 +122,23 @@ export function createWasmApi({ glueUrl, loadWasmBytes, compileWasm = (bytes) =>
122
122
  async function init() {
123
123
  await getInstance();
124
124
  }
125
- // Both throw helpers below fire only if `compile`/`renderHtml` were
126
- // somehow invoked against the highlight-only glue -- unreachable through
127
- // the public API surface, since `src/highlight.ts`/`src/highlight-browser.ts`
128
- // never re-export these two functions. Kept as a clear runtime error
129
- // rather than a silent `undefined()` crash.
130
- function requirePipelineExport(fn, name) {
125
+ // Public entry surfaces make missing calls unreachable. This guard keeps
126
+ // structural glue mismatches artifact-neutral and actionable.
127
+ function requireCapability(fn, name) {
131
128
  if (!fn) {
132
- throw new Error(`zfb-md-wasm: ${name}() is not available in the highlight-only wasm artifact ` +
133
- `(built with the \`pipeline\` Cargo feature off) -- use the default \`.\` entry instead.`);
129
+ throw new Error(`zfb-md-wasm: ${name}() is not available in this wasm artifact. ` +
130
+ `Import an entry whose artifact provides that capability.`);
134
131
  }
135
132
  return fn;
136
133
  }
137
134
  async function compile(source, options = {}) {
138
135
  const optionsJson = JSON.stringify(options);
139
- const json = await callWasm(({ glue }) => requirePipelineExport(glue.compile, "compile").call(glue, source, optionsJson));
136
+ const json = await callWasm(({ glue }) => requireCapability(glue.compile, "compile").call(glue, source, optionsJson));
140
137
  return JSON.parse(json);
141
138
  }
142
139
  async function renderHtml(source, options = {}) {
143
140
  const optionsJson = JSON.stringify(options);
144
- const json = await callWasm(({ glue }) => requirePipelineExport(glue.renderHtml, "renderHtml").call(glue, source, optionsJson));
141
+ const json = await callWasm(({ glue }) => requireCapability(glue.renderHtml, "renderHtml").call(glue, source, optionsJson));
145
142
  return JSON.parse(json);
146
143
  }
147
144
  /**
@@ -153,12 +150,12 @@ export function createWasmApi({ glueUrl, loadWasmBytes, compileWasm = (bytes) =>
153
150
  */
154
151
  async function parseToAst(source, options = {}) {
155
152
  const optionsJson = JSON.stringify(options);
156
- const json = await callWasm(({ glue }) => requirePipelineExport(glue.parseToAst, "parseToAst").call(glue, source, optionsJson));
153
+ const json = await callWasm(({ glue }) => requireCapability(glue.parseToAst, "parseToAst").call(glue, source, optionsJson));
157
154
  return JSON.parse(json);
158
155
  }
159
156
  async function highlightCode(code, options) {
160
157
  const optionsJson = JSON.stringify(options);
161
- const json = await callWasm(({ glue }) => glue.highlightCode(code, optionsJson));
158
+ const json = await callWasm(({ glue }) => requireCapability(glue.highlightCode, "highlightCode").call(glue, code, optionsJson));
162
159
  return JSON.parse(json);
163
160
  }
164
161
  async function version() {