@quillmark/wasm 0.54.1 → 0.58.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
@@ -1,177 +1,70 @@
1
1
  # Quillmark WASM
2
2
 
3
- WebAssembly bindings for the Quillmark markdown rendering engine.
3
+ WebAssembly bindings for Quillmark.
4
4
 
5
5
  Maintained by [TTQ](https://tonguetoquill.com).
6
6
 
7
7
  ## Overview
8
8
 
9
- This crate provides WASM bindings for Quillmark, enabling use in web browsers, Node.js, and other JavaScript/TypeScript environments. All data exchange uses JSON serialization, and JavaScript is responsible for all I/O operations.
9
+ Use Quillmark in browsers/Node.js with explicit in-memory trees (`Map<string, Uint8Array>` / `Record<string, Uint8Array>`).
10
10
 
11
- ## Building
12
-
13
- ### For Web (bundler)
11
+ ## Build
14
12
 
15
13
  ```bash
16
14
  wasm-pack build --target bundler --scope quillmark
17
15
  ```
18
16
 
19
- ### For Node.js
20
-
21
- ```bash
22
- wasm-pack build --target nodejs --scope quillmark
23
- ```
24
-
25
- ### All targets
17
+ ## Test
26
18
 
27
19
  ```bash
28
20
  bash scripts/build-wasm.sh
29
- ```
30
-
31
- ## Testing
32
-
33
- Minimal smoke tests validate the core WASM functionality:
34
-
35
- ```bash
36
- # Build WASM module first
37
- bash scripts/build-wasm.sh
38
-
39
- # Run tests
40
- cd quillmark-wasm
21
+ cd crates/bindings/wasm
41
22
  npm install
42
23
  npm test
43
24
  ```
44
25
 
45
- The test suite includes:
46
- - `basic.test.js` - Core WASM API functionality tests
47
- - `resolve.test.js` - Quill version resolution against the WASM engine
48
-
49
26
  ## Usage
50
27
 
51
- ```typescript
52
- import { Quillmark } from '@quillmark-test/wasm';
28
+ ```ts
29
+ import { ParsedDocument, Quillmark } from "@quillmark-test/wasm";
30
+
31
+ const engine = new Quillmark();
32
+ const quill = engine.quill(tree);
53
33
 
54
- // Step 1: Parse markdown
55
34
  const markdown = `---
56
- title: My Document
57
- author: Alice
58
35
  QUILL: my_quill
36
+ title: My Document
59
37
  ---
60
38
 
61
- # Hello World
62
-
63
- This is my document.
64
- `;
65
-
66
- const parsed = Quillmark.parseMarkdown(markdown);
39
+ # Hello`;
67
40
 
68
- // Step 2: Create engine and register Quill
69
- const engine = new Quillmark();
70
-
71
- const quillJson = {
72
- files: {
73
- 'Quill.yaml': {
74
- contents: 'Quill:\n name: my_quill\n version: "1.0"\n backend: typst\n plate_file: plate.typ\n description: My template\n'
75
- },
76
- 'plate.typ': {
77
- contents: '= {{ title }}\n\n{{ body | Content }}'
78
- }
79
- }
80
- };
81
-
82
- engine.registerQuill(quillJson);
83
-
84
- // Step 3: Get Quill info (optional)
85
- const info = engine.getQuillInfo('my-quill');
86
- console.log('Supported formats:', info.supportedFormats);
87
- console.log('Schema YAML:', info.schema);
88
-
89
- // Step 4: Render
90
- const result = engine.render(parsed, { format: 'pdf' });
91
-
92
- // Access the PDF bytes
93
- const pdfArtifact = result.artifacts[0];
94
- const blob = new Blob([pdfArtifact.bytes], { type: pdfArtifact.mimeType });
95
- const url = URL.createObjectURL(blob);
96
- window.open(url);
41
+ const parsed = ParsedDocument.fromMarkdown(markdown);
42
+ const result = quill.render(parsed, { format: "pdf" });
97
43
  ```
98
44
 
99
45
  ## API
100
46
 
101
- The `Quillmark` class provides the following methods:
102
-
103
- ### Workflow Methods
104
-
105
- The main workflow for rendering documents:
106
-
107
- - `static parseMarkdown(markdown)` - Parse markdown into a ParsedDocument (Step 1)
108
- - `registerQuill(quillJson)` - Register a Quill template bundle from JSON (Step 2)
109
- - `render(parsedDoc, options)` - Render a ParsedDocument to final artifacts using the required `QUILL` reference parsed from the document (Step 4)
110
-
111
- ### Utility Methods
112
-
113
- Additional methods for managing the engine and debugging:
114
-
115
- - `new Quillmark()` - Create a new engine instance
116
- - `renderQuill(RenderOptions, markdown)` - Load markdown and map it onto an internally fetched Quill, resolving to `RenderResult` including output format, the artifact byte slice buffer, and time to render
117
- - `processPlate(quillRef, markdown)` - Debug helper that processes markdown through the template engine and returns the intermediate template source code (e.g., Typst, LaTeX) without compiling to final artifacts. Useful for inspecting template output during development.
118
- - `fetchQuillInfo(quillRef)` - Fetches metadata and schema about an available Quill from the configured registry without loading the full filesystem or rendering context.
119
- - `listQuills()` - List all registered Quill names
120
- - `unregisterQuill(name)` - Unregister a Quill to free memory
121
-
122
- ### Render Options
47
+ ### `new Quillmark()`
48
+ Create engine.
123
49
 
124
- ```typescript
125
- type RenderOptions = {
126
- format?: 'pdf' | 'svg' | 'txt'
127
- assets?: Record<string, Uint8Array | number[]>
128
- }
129
- ```
130
-
131
- ### ParsedDocument
132
-
133
- Returned by `parseMarkdown()`:
134
-
135
- ```typescript
136
- {
137
- fields: object, // YAML frontmatter fields
138
- quillRef: string // Quill reference from required QUILL field
139
- }
140
- ```
141
-
142
- ### QuillInfo
143
-
144
- Returned by `getQuillInfo()`:
145
-
146
- ```typescript
147
- {
148
- name: string,
149
- backend: string, // e.g., "typst"
150
- metadata: object, // Quill metadata from Quill.yaml
151
- example?: string, // Example markdown (if available)
152
- schema: string, // Public schema YAML text
153
- supportedFormats: Array<'pdf' | 'svg' | 'txt'> // Formats this backend supports
154
- }
155
- ```
50
+ ### `engine.quill(tree)`
51
+ Build + validate + attach backend. Returns a render-ready `Quill`.
156
52
 
157
- ## WASM Boundary Types
53
+ ### `ParsedDocument.fromMarkdown(markdown)`
54
+ Parse markdown to parsed document.
158
55
 
159
- Data crossing the JavaScript ↔ WebAssembly boundary:
56
+ ### `quill.render(parsed, opts?)`
57
+ Render with a pre-parsed `ParsedDocument`.
160
58
 
161
- - **Enums**: Serialized as lowercase strings (`"pdf"`, `"svg"`, `"txt"`)
162
- - **Binary data**: `Vec<u8>` maps to `Uint8Array`
163
- - **Collections**: `Vec<T>` maps to JS arrays; object types use plain JS objects `{}`
164
- - **Option**: `Option<T>` maps to `T | null`
165
- - **Errors**: Thrown as exceptions using `SerializableDiagnostic` from core, containing structured diagnostic information (severity, message, location, hint, source chain)
59
+ ### `quill.open(parsed)` + `session.render(opts?)`
60
+ Open once, render all or selected pages (`opts.pages`).
166
61
 
167
- ## Design Principles
62
+ ## Notes
168
63
 
169
- - **JSON-Only Data Exchange**: All structured data uses `serde-wasm-bindgen`
170
- - **JavaScript Handles I/O**: WASM layer only handles rendering
171
- - **Synchronous Operations**: Rendering is fast enough (<100ms typically)
172
- - **No File System Abstractions**: JavaScript prepares all data
173
- - **Error Delegation**: Error handling delegated to core types (`SerializableDiagnostic`) for consistency with Python bindings
64
+ - Parsed markdown requires top-level `QUILL` in frontmatter.
65
+ - QUILL mismatch during `quill.render(parsed)` is a warning (`quill::ref_mismatch`), not an error.
66
+ - Output schema APIs are no longer engine-level in WASM.
174
67
 
175
68
  ## License
176
69
 
177
- Licensed under the Apache License, Version 2.0.
70
+ Apache-2.0
package/bundler/wasm.d.ts CHANGED
@@ -6,8 +6,6 @@ export interface Artifact {
6
6
  mimeType: string;
7
7
  }
8
8
 
9
- export interface CompileOptions {}
10
-
11
9
  export interface Diagnostic {
12
10
  severity: Severity;
13
11
  code?: string;
@@ -28,26 +26,11 @@ export interface ParsedDocument {
28
26
  quillRef: string;
29
27
  }
30
28
 
31
- export interface QuillInfo {
32
- name: string;
33
- backend: string;
34
- metadata: Record<string, any>;
35
- example?: string;
36
- schema: string;
37
- defaults: Record<string, any>;
38
- examples: Record<string, any[]>;
39
- supportedFormats: OutputFormat[];
40
- }
41
-
42
29
  export interface RenderOptions {
43
30
  format?: OutputFormat;
44
31
  assets?: Record<string, Uint8Array | number[]>;
45
32
  ppi?: number;
46
- }
47
-
48
- export interface RenderPagesOptions {
49
- format: OutputFormat;
50
- ppi?: number;
33
+ pages?: number[];
51
34
  }
52
35
 
53
36
  export interface RenderResult {
@@ -62,108 +45,53 @@ export type OutputFormat = "pdf" | "svg" | "txt" | "png";
62
45
  export type Severity = "error" | "warning" | "note";
63
46
 
64
47
 
65
- export class CompiledDocument {
48
+ /**
49
+ * Opaque, shareable Quill handle.
50
+ */
51
+ export class Quill {
66
52
  private constructor();
67
53
  free(): void;
68
54
  [Symbol.dispose](): void;
69
55
  /**
70
- * Render selected pages. `pages = null/undefined` renders all pages.
56
+ * Open an iterative render session for page-selective rendering.
71
57
  */
72
- renderPages(pages: Uint32Array | null | undefined, opts: RenderPagesOptions): RenderResult;
58
+ open(parsed: ParsedDocument): RenderSession;
73
59
  /**
74
- * Number of pages in this compiled document.
60
+ * Render a document to final artifacts.
75
61
  */
76
- readonly pageCount: number;
62
+ render(parsed: ParsedDocument, opts: RenderOptions): RenderResult;
77
63
  }
78
64
 
79
65
  /**
80
66
  * Quillmark WASM Engine
81
- *
82
- * Create once, register Quills, render markdown. That's it.
83
67
  */
84
68
  export class Quillmark {
85
69
  free(): void;
86
70
  [Symbol.dispose](): void;
87
- /**
88
- * Compile a parsed document into an opaque compiled document handle.
89
- */
90
- compile(parsed: ParsedDocument, opts?: CompileOptions | null): CompiledDocument;
91
- /**
92
- * Compile markdown to JSON data without rendering artifacts.
93
- *
94
- * This exposes the intermediate data structure that would be passed to the backend.
95
- * Useful for debugging and validation.
96
- */
97
- compileData(markdown: string): any;
98
- /**
99
- * Perform a dry run validation without backend compilation.
100
- *
101
- * Executes parsing, schema validation, and template composition to
102
- * surface input errors quickly. Returns successfully on valid input,
103
- * or throws an error with diagnostic payload on failure.
104
- *
105
- * The quill name is read from the markdown's required QUILL tag.
106
- *
107
- * This is useful for fast feedback loops in LLM-driven document generation.
108
- */
109
- dryRun(markdown: string): void;
110
- /**
111
- * Get shallow information about a registered Quill
112
- *
113
- * This returns metadata, backend info, field schemas, and supported formats
114
- * that consumers need to configure render options for the next step.
115
- */
116
- getQuillInfo(name: string): QuillInfo;
117
- /**
118
- * Get the public YAML schema contract for a registered quill.
119
- */
120
- getQuillSchema(name: string): string;
121
- /**
122
- * List registered Quills with their exact versions
123
- *
124
- * Returns strings in the format "name@version" (e.g. "resume-template@2.1.0")
125
- */
126
- listQuills(): string[];
127
71
  /**
128
72
  * JavaScript constructor: `new Quillmark()`
129
73
  */
130
74
  constructor();
131
75
  /**
132
- * Parse markdown into a ParsedDocument
133
- *
134
- * This is the first step in the workflow. The returned ParsedDocument contains
135
- * the parsed YAML frontmatter fields and the quill_ref from QUILL.
136
- */
137
- static parseMarkdown(markdown: string): ParsedDocument;
138
- /**
139
- * Register a Quill template bundle
140
- *
141
- * Accepts either a JSON string or a JsValue object representing the Quill file tree.
142
- * Validation happens automatically on registration.
143
- */
144
- registerQuill(quill_json: any): QuillInfo;
145
- /**
146
- * Render a ParsedDocument to final artifacts (PDF, SVG, TXT)
76
+ * Load a quill from a file tree and attach the appropriate backend.
147
77
  *
148
- * Uses the Quill specified in the ParsedDocument's quill_ref field.
78
+ * The tree must be a `Map<string, Uint8Array>`.
149
79
  */
150
- render(parsed: ParsedDocument, opts: RenderOptions): RenderResult;
80
+ quill(tree: any): Quill;
81
+ }
82
+
83
+ export class RenderSession {
84
+ private constructor();
85
+ free(): void;
86
+ [Symbol.dispose](): void;
151
87
  /**
152
- * Resolve a Quill reference to a registered Quill, or null if not available
153
- *
154
- * Accepts a quill reference string like "resume-template", "resume-template@2",
155
- * or "resume-template@2.1.0". Returns QuillInfo if the engine can resolve it
156
- * locally, or null if an external fetch is needed.
88
+ * Render all or selected pages from this session.
157
89
  */
158
- resolveQuill(quill_ref: string): any;
90
+ render(opts: RenderOptions): RenderResult;
159
91
  /**
160
- * Unregister a Quill by name or specific version
161
- *
162
- * If a base name is provided (e.g., "my-quill"), all versions of that quill are freed.
163
- * If a versioned name is provided (e.g., "my-quill@2.1.0"), only that specific version is freed.
164
- * Returns true if something was unregistered, false if not found.
92
+ * Number of pages in this render session.
165
93
  */
166
- unregisterQuill(name_or_ref: string): boolean;
94
+ readonly pageCount: number;
167
95
  }
168
96
 
169
97
  /**
package/bundler/wasm.js CHANGED
@@ -1,9 +1,9 @@
1
1
  /* @ts-self-types="./wasm.d.ts" */
2
-
3
2
  import * as wasm from "./wasm_bg.wasm";
4
3
  import { __wbg_set_wasm } from "./wasm_bg.js";
4
+
5
5
  __wbg_set_wasm(wasm);
6
6
  wasm.__wbindgen_start();
7
7
  export {
8
- CompiledDocument, Quillmark, init
8
+ ParsedDocument, Quill, Quillmark, RenderSession, init
9
9
  } from "./wasm_bg.js";