brookmd 0.22.0 → 0.22.2

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/CHANGELOG.md CHANGED
@@ -4,6 +4,40 @@ Notable changes to brookmd (formerly `flux-md`). Format based on
4
4
  [Keep a Changelog](https://keepachangelog.com/); this project aims to follow
5
5
  [Semantic Versioning](https://semver.org/).
6
6
 
7
+ ## 0.22.2 — 2026-07-21
8
+
9
+ ### Performance
10
+
11
+ - **7–24% faster streaming across every benchmarked document shape** (native
12
+ and WASM builds alike), from a final profiling pass over the Rust core:
13
+ - the scanner's newline search (`line_end`) — the hottest primitive, re-run
14
+ by every block probe on every line — now scans 8 bytes per step (SWAR)
15
+ instead of one;
16
+ - the inline renderer copies runs of plain text with a single `push_str`
17
+ instead of per-byte dispatch + escape calls.
18
+
19
+ Rendered HTML is byte-identical (spec goldens, wire-envelope goldens,
20
+ chunk-independence property tests, and the streaming-parity fuzzer all
21
+ pass); the WASM binary grows 338 bytes (+0.16%). Ships as `brookmd-core`
22
+ 0.22.1 on crates.io.
23
+
24
+ ## 0.22.1 — 2026-07-21
25
+
26
+ ### Fixed
27
+
28
+ - **React Native / Metro compatibility**, both issues found by the new
29
+ app-level e2e gate (a real RN app on an emulator + simulator asserting the
30
+ wire goldens through the native parser):
31
+ - every conditional-exports subpath now ships a `default` condition, so
32
+ Metro's stock package-exports resolution works without custom
33
+ `unstable_conditionNames` (which could poison `@babel/runtime` helper
34
+ resolution and crash release bundles at startup);
35
+ - the browser worker bootstrap moved behind a `react-native` field map to
36
+ an `import.meta`-free shim, so Hermes can parse release bundles (Hermes
37
+ rejects `import.meta` at parse time even in unreachable code). Web
38
+ behavior is unchanged — the `new Worker(new URL(...))` pattern bundlers
39
+ analyze stays intact.
40
+
7
41
  ## 0.22.0 — 2026-07-20
8
42
 
9
43
  ### Changed
package/README.md CHANGED
@@ -6,6 +6,12 @@ Drop in a streaming-aware renderer — **React, Vue, Svelte, Solid, a framework-
6
6
 
7
7
  Parsing runs entirely **off the main thread** — each stream gets its own pooled Web Worker, so many concurrent LLM responses render without contending for the UI thread. On each token the parser re-parses only the **active tail**, not the whole document, and heavy renderers (syntax highlighting, math, mermaid) are **deferred until a block closes**. The result is low retained memory and a main thread that stays responsive while streaming. See [the live demo](https://md.hsingh.app/).
8
8
 
9
+ > **Beyond the browser:** the same Rust core also powers experimental React
10
+ > Native, Swift (iOS/macOS), Kotlin/Android, Flutter, and C-ABI bindings —
11
+ > every platform speaks the same versioned wire, byte-for-byte. See the
12
+ > [platform matrix](https://github.com/siinghd/brookmd#platforms) in the
13
+ > repository README.
14
+
9
15
  ## Install
10
16
 
11
17
  ```bash
@@ -0,0 +1,3 @@
1
+ import type { WorkerLike } from "./types-core.js";
2
+ /** Spawn the streaming Web Worker (`dist/worker.js`) as an ES module. */
3
+ export declare function createWorker(): WorkerLike;
@@ -0,0 +1,6 @@
1
+ function createWorker() {
2
+ return new Worker(new URL("./worker.js", import.meta.url), { type: "module" });
3
+ }
4
+ export {
5
+ createWorker
6
+ };
@@ -0,0 +1,3 @@
1
+ import type { WorkerLike } from "./types-core.js";
2
+ /** Not available under React Native — there is no Web Worker to spawn. */
3
+ export declare function createWorker(): WorkerLike;
@@ -0,0 +1,8 @@
1
+ function createWorker() {
2
+ throw new Error(
3
+ "brookmd: the default Web Worker pool is unavailable in React Native. Use the brookmd-react-native package, which injects a native parser pool instead of spawning a Web Worker."
4
+ );
5
+ }
6
+ export {
7
+ createWorker
8
+ };
package/dist/client.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { createWorker } from "./asset-urls.js";
1
2
  function emptyBlockStore() {
2
3
  return { committed: /* @__PURE__ */ new Map(), committedOrder: [], active: [], snapshot: [] };
3
4
  }
@@ -171,7 +172,7 @@ let defaultPool = null;
171
172
  function getDefaultPool() {
172
173
  if (!defaultPool) {
173
174
  defaultPool = new BrookPool(
174
- () => new Worker(new URL("./worker.js", import.meta.url), { type: "module" }),
175
+ () => createWorker(),
175
176
  poolCap()
176
177
  );
177
178
  }
Binary file
package/package.json CHANGED
@@ -1,30 +1,33 @@
1
1
  {
2
2
  "name": "brookmd",
3
- "version": "0.22.0",
3
+ "version": "0.22.2",
4
4
  "description": "Zero-dep streaming markdown for the browser. Rust→WASM core, Web Worker per stream, incremental parse with speculative closure.",
5
5
  "type": "module",
6
6
  "sideEffects": ["./dist/worker.js", "./dist/styles.css"],
7
7
  "main": "./dist/index.js",
8
8
  "types": "./dist/index.d.ts",
9
9
  "exports": {
10
- ".": { "types": "./dist/index.d.ts", "import": "./dist/index.js" },
11
- "./client": { "types": "./dist/client.d.ts", "import": "./dist/client.js" },
12
- "./react": { "types": "./dist/react.d.ts", "import": "./dist/react.js" },
13
- "./server": { "types": "./dist/server.d.ts", "import": "./dist/server.js" },
14
- "./server/react": { "types": "./dist/server-react.d.ts", "import": "./dist/server-react.js" },
15
- "./dom": { "types": "./dist/dom.d.ts", "import": "./dist/dom.js" },
16
- "./element": { "types": "./dist/element.d.ts", "import": "./dist/element.js" },
17
- "./vue": { "types": "./dist/vue.d.ts", "import": "./dist/vue.js" },
18
- "./svelte": { "types": "./dist/svelte.d.ts", "import": "./dist/svelte.js" },
19
- "./solid": { "types": "./dist/solid.d.ts", "import": "./dist/solid.js" },
20
- "./highlight": { "types": "./dist/hi.d.ts", "import": "./dist/hi.js" },
21
- "./html-to-react": { "types": "./dist/html-to-react.d.ts", "import": "./dist/html-to-react.js" },
22
- "./block-props": { "types": "./dist/block-props.d.ts", "import": "./dist/block-props.js" },
23
- "./worker-core": { "types": "./dist/worker-core.d.ts", "import": "./dist/worker-core.js" },
24
- "./types": { "types": "./dist/types.d.ts", "import": "./dist/types.js" },
10
+ ".": { "types": "./dist/index.d.ts", "import": "./dist/index.js", "default": "./dist/index.js" },
11
+ "./client": { "types": "./dist/client.d.ts", "import": "./dist/client.js", "default": "./dist/client.js" },
12
+ "./react": { "types": "./dist/react.d.ts", "import": "./dist/react.js", "default": "./dist/react.js" },
13
+ "./server": { "types": "./dist/server.d.ts", "import": "./dist/server.js", "default": "./dist/server.js" },
14
+ "./server/react": { "types": "./dist/server-react.d.ts", "import": "./dist/server-react.js", "default": "./dist/server-react.js" },
15
+ "./dom": { "types": "./dist/dom.d.ts", "import": "./dist/dom.js", "default": "./dist/dom.js" },
16
+ "./element": { "types": "./dist/element.d.ts", "import": "./dist/element.js", "default": "./dist/element.js" },
17
+ "./vue": { "types": "./dist/vue.d.ts", "import": "./dist/vue.js", "default": "./dist/vue.js" },
18
+ "./svelte": { "types": "./dist/svelte.d.ts", "import": "./dist/svelte.js", "default": "./dist/svelte.js" },
19
+ "./solid": { "types": "./dist/solid.d.ts", "import": "./dist/solid.js", "default": "./dist/solid.js" },
20
+ "./highlight": { "types": "./dist/hi.d.ts", "import": "./dist/hi.js", "default": "./dist/hi.js" },
21
+ "./html-to-react": { "types": "./dist/html-to-react.d.ts", "import": "./dist/html-to-react.js", "default": "./dist/html-to-react.js" },
22
+ "./block-props": { "types": "./dist/block-props.d.ts", "import": "./dist/block-props.js", "default": "./dist/block-props.js" },
23
+ "./worker-core": { "types": "./dist/worker-core.d.ts", "import": "./dist/worker-core.js", "default": "./dist/worker-core.js" },
24
+ "./types": { "types": "./dist/types.d.ts", "import": "./dist/types.js", "default": "./dist/types.js" },
25
25
  "./styles.css": "./dist/styles.css",
26
26
  "./package.json": "./package.json"
27
27
  },
28
+ "react-native": {
29
+ "./dist/asset-urls.js": "./dist/asset-urls.native.js"
30
+ },
28
31
  "files": [
29
32
  "dist",
30
33
  "README.md",