jumpcut 1.0.0

JumpCut is a library and CLI for converting Fountain-formatted text files into FDX, HTML, JSON, text, and PDF formats.
Documentation
# WASM

JumpCut ships an in-repo wasm wrapper crate at [`jumpcut-wasm`](../jumpcut-wasm).

This document covers:

- what the wasm wrapper exposes
- how Cargo features affect wasm size
- how to build a Node-compatible package
- the internal wasm checks and size-report workflow

Embedded Courier Prime HTML export is documented separately in [`html-embedded-fonts.md`](html-embedded-fonts.md).

## Feature Model

JumpCut uses Cargo features so you can choose how much functionality to compile into a WASM build.

Current wasm feature slices:

- JSON: always available
- HTML: optional
- FDX: optional
- PDF: optional
- PDF font subsetting: optional through `pdf-font-subsetting`

### PDF Font Subsetting And Bundle Size

Font subsetting embeds only the glyphs used by the current document. This can materially reduce generated PDFs, especially short documents where the four font faces account for most of the file, but the subsetting implementation also adds substantial code to the wasm module, so it's an opt-in choice:

```sh
wasm-pack build --release --target web jumpcut-wasm --features pdf-font-subsetting
```

The `pdf-font-subsetting` feature includes `pdf`; it does not need to be listed separately.

The default WASM package keeps lossless PDF stream compression but does not subset fonts. Native JumpCut builds subset fonts by default. With the repository's release profile and `wasm-opt -Os`, the tradeoff measured as follows:

| Build | Raw WASM | gzip | Brotli |
| --- | ---: | ---: | ---: |
| PDF before stream compression | 1,627,578 bytes | 667,190 bytes | 497,466 bytes |
| Default WASM with PDF compression | 1,655,073 bytes | 678,912 bytes | 506,150 bytes |
| PDF compression and font subsetting | 2,260,714 bytes | 901,770 bytes | 672,320 bytes |

Compression adds about 27 KB of raw WASM, while subsetting adds about 606 KB. The latter can meaningfully reduce generated PDFs, especially short documents where fonts account for most of the file, but most web applications should prefer the smaller default bundle.

## JS-Facing Exports

The wasm wrapper currently exposes:

- `parse_to_fountain_string(text)`
- `parse_to_json_string(text)`
- `parse_to_html_string(text, include_head)`
- `parse_to_html_string_with_options(text, include_head, exact_wraps, paginated)`
- `parse_to_html_string_with_embedded_courier_prime(text, include_head, exact_wraps, paginated, regular_ttf_base64, italic_ttf_base64, bold_ttf_base64, bold_italic_ttf_base64)`
- `parse_to_fdx_string(text)`
- `parse_to_pdf_bytes(text)`
- `parse_fdx_to_fountain_string(text)`
- `parse_fdx_to_html_string(text, include_head)`
- `parse_fdx_to_pdf_bytes(text)`

## Build The WASM Wrapper

The low-level Rust build is:

```sh
cargo build -p jumpcut-wasm --target wasm32-unknown-unknown --release
```

To generate a browser/web-compatible JS package from the compiled `.wasm`, use:

```sh
./scripts/wasm/generate-package.sh --smoke
```

That script will:

- build `jumpcut-wasm`
- ensure `wasm-bindgen-cli` is available
- generate a web-targeted package under `target/wasm-package/web-full`
- run a small smoke benchmark

If you want a Node-targeted package instead, run:

```sh
./scripts/wasm/generate-package.sh --target nodejs --smoke
```

If you want the generated package without the smoke shortcut, run:

```sh
./scripts/wasm/generate-package.sh
```

## Use The Generated Package From Node

After running `./scripts/wasm/generate-package.sh`, the generated package lives under:

```text
target/wasm-package/web-full
```

For a Node-targeted package, use:

```js
const jumpcut = require("./target/wasm-package/node-full/jumpcut_wasm.js");

const input = `Title: Example

INT. HOUSE - DAY

Hello, world.`;

const fountain = jumpcut.parse_to_fountain_string(input);
const json = jumpcut.parse_to_json_string(input);
const html = jumpcut.parse_to_html_string(input, true);
const fdx = jumpcut.parse_to_fdx_string(input);

console.log(fountain.slice(0, 80));
console.log(json);
console.log(html.slice(0, 80));
console.log(fdx.slice(0, 80));
```

## Checks And Reports

The repo includes helper scripts for the wasm workflow:

- `./scripts/wasm/generate-package.sh`
  - builds the wasm wrapper
  - generates a web-targeted JS package by default
  - supports `--target nodejs` for a Node-targeted package
  - optionally runs a small smoke benchmark
- `./scripts/wasm/checks.sh`
  - repo-internal validation helper for wasm changes
  - runs tests and `wasm32` checks
  - generates a Node package, loads the compiled WASM, and validates every
    default-feature JS export against a small Fountain/FDX fixture
- `./scripts/wasm/report.sh`
  - repo-internal benchmark/size-report helper
  - emits bundle-size metrics, feature-slice metrics (`json_only`, `html_only`, `fdx_only`, `pdf_only`, `pdf_subset`), native guardrail metrics, and Node-side wasm runtime metrics

The current benchmark baseline artifact lives at:

```text
benchmarks/wasm/baseline-state.json
```