@quillmark/quiver 0.8.0 → 0.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
@@ -44,17 +44,16 @@ my-quiver/
44
44
  ```
45
45
 
46
46
  Recommended CI: use the bundled `@quillmark/quiver/testing` harness — it
47
- loads with `Quiver.fromDir` and exercises every quill so validation errors
48
- surface on publish, not on the consumer's build. The harness uses
49
- `node:test` (built into Node 18+); no extra test-runner dependency
50
- required. If you prefer vitest/jest/mocha, write a 12-line loop against
51
- the main API instead.
47
+ loads with `Quiver.fromDir`, compiles every quill, and renders each quill's
48
+ blueprint so validation errors surface on publish, not on the consumer's
49
+ build. The harness uses `node:test` (built into Node 18+); no extra
50
+ test-runner dependency required. If you prefer vitest/jest/mocha, write a
51
+ 12-line loop against the main API instead.
52
52
 
53
53
  ## Manual validation (rendering samples)
54
54
 
55
55
  The CI harness proves every quill _compiles_; it does not produce output a
56
- human can look at. To eyeball real renders, drop an `example.md` next to a
57
- quill's template (`quills/<name>/<x.y.z>/example.md`) and run the
56
+ human can look at. To eyeball real renders, run the
58
57
  `@quillmark/quiver/preview` helper:
59
58
 
60
59
  ```ts
@@ -69,12 +68,12 @@ await renderQuiverSamples(import.meta.url, {
69
68
  // → writes ./preview/<name>@<version>.<fmt> + index.html
70
69
  ```
71
70
 
72
- It renders every quill's `example.md`, writes the artifacts to `outDir`
73
- (default `preview/`), and emits an `index.html` gallery. A `.gitignore` is
74
- written into `outDir` so the generated artifacts are never accidentally
75
- committed. Quills without an `example.md` are skipped; a quill that throws
76
- is recorded as failed — with every diagnostic, not just the first —
77
- without aborting the run, so one broken quill never hides the rest.
71
+ It renders every quill's auto-generated blueprint (`quill.blueprint`), writes
72
+ the artifacts to `outDir` (default `preview/`), and emits an `index.html`
73
+ gallery. A `.gitignore` is written into `outDir` so the generated artifacts
74
+ are never accidentally committed. A quill that throws is recorded as failed
75
+ with every diagnostic, not just the first — without aborting the run, so one
76
+ broken quill never hides the rest.
78
77
 
79
78
  To iterate on a subset, pass `include` / `exclude` (each entry matches a
80
79
  quill name or canonical ref):
@@ -23,4 +23,6 @@ export interface QuillmarkLike {
23
23
  export interface QuillLike {
24
24
  render(doc: unknown, opts?: unknown): unknown;
25
25
  open?: (doc: unknown) => unknown;
26
+ /** Auto-generated annotated Markdown blueprint — always present in @quillmark/wasm >=0.79.0. */
27
+ blueprint: string;
26
28
  }
package/dist/preview.d.ts CHANGED
@@ -3,9 +3,9 @@
3
3
  *
4
4
  * `runQuiverTests` (`@quillmark/quiver/testing`) proves every quill *compiles*
5
5
  * — it never produces a rendered artifact a human can look at. This module
6
- * closes that gap: it renders each quill's bundled `example.md`, writes the
7
- * artifacts to a directory, and emits an `index.html` gallery so an author
8
- * can eyeball real output before publishing.
6
+ * closes that gap: it renders each quill's blueprint, writes the artifacts to
7
+ * a directory, and emits an `index.html` gallery so an author can eyeball real
8
+ * output before publishing.
9
9
  *
10
10
  * Node-only: writes files and loads a source quiver from disk.
11
11
  *
@@ -20,9 +20,9 @@
20
20
  * });
21
21
  * // → open ./preview/index.html
22
22
  *
23
- * The example document is the `example.md` file inside each quill version
24
- * directory (`quills/<name>/<version>/example.md`). Quills without one are
25
- * skipped, not failed.
23
+ * The sample document is the auto-generated blueprint (`quill.blueprint`) for
24
+ * each quill version. Every quill always has a blueprint, so no quills are
25
+ * skipped for lack of a sample document.
26
26
  *
27
27
  * A `.gitignore` is written into `outDir` so the generated artifacts are not
28
28
  * accidentally committed.
@@ -61,8 +61,8 @@ export interface RenderQuiverSamplesOptions {
61
61
  export interface RenderedSample {
62
62
  /** Canonical ref, e.g. `"memo@1.0.0"`. */
63
63
  ref: string;
64
- /** `rendered` — artifacts written; `skipped` — no example; `failed` — error. */
65
- status: "rendered" | "skipped" | "failed";
64
+ /** `rendered` — artifacts written; `failed` — error. */
65
+ status: "rendered" | "failed";
66
66
  /** Artifact filenames written under `outDir` (relative). */
67
67
  files: string[];
68
68
  /** Render warnings, formatted `"severity: message"`. */
@@ -74,7 +74,7 @@ export interface RenderedSample {
74
74
  reasons: string[];
75
75
  }
76
76
  /**
77
- * Renders every quill's `example.md` and writes the artifacts plus an
77
+ * Renders every quill's blueprint and writes the artifacts plus an
78
78
  * `index.html` gallery to `outDir`.
79
79
  *
80
80
  * Does NOT fail fast: a quill that throws is recorded as `failed` and the
package/dist/preview.js CHANGED
@@ -3,9 +3,9 @@
3
3
  *
4
4
  * `runQuiverTests` (`@quillmark/quiver/testing`) proves every quill *compiles*
5
5
  * — it never produces a rendered artifact a human can look at. This module
6
- * closes that gap: it renders each quill's bundled `example.md`, writes the
7
- * artifacts to a directory, and emits an `index.html` gallery so an author
8
- * can eyeball real output before publishing.
6
+ * closes that gap: it renders each quill's blueprint, writes the artifacts to
7
+ * a directory, and emits an `index.html` gallery so an author can eyeball real
8
+ * output before publishing.
9
9
  *
10
10
  * Node-only: writes files and loads a source quiver from disk.
11
11
  *
@@ -20,9 +20,9 @@
20
20
  * });
21
21
  * // → open ./preview/index.html
22
22
  *
23
- * The example document is the `example.md` file inside each quill version
24
- * directory (`quills/<name>/<version>/example.md`). Quills without one are
25
- * skipped, not failed.
23
+ * The sample document is the auto-generated blueprint (`quill.blueprint`) for
24
+ * each quill version. Every quill always has a blueprint, so no quills are
25
+ * skipped for lack of a sample document.
26
26
  *
27
27
  * A `.gitignore` is written into `outDir` so the generated artifacts are not
28
28
  * accidentally committed.
@@ -30,12 +30,10 @@
30
30
  import { mkdir, writeFile } from "node:fs/promises";
31
31
  import { join } from "node:path";
32
32
  import { Quiver } from "./node.js";
33
- /** The `example.md` filename looked up inside each quill version directory. */
34
- const EXAMPLE_FILE = "example.md";
35
33
  /** Default directory rendered artifacts are written to. */
36
34
  const DEFAULT_OUT_DIR = "preview";
37
35
  /**
38
- * Renders every quill's `example.md` and writes the artifacts plus an
36
+ * Renders every quill's blueprint and writes the artifacts plus an
39
37
  * `index.html` gallery to `outDir`.
40
38
  *
41
39
  * Does NOT fail fast: a quill that throws is recorded as `failed` and the
@@ -86,21 +84,10 @@ function failureReasons(err) {
86
84
  }
87
85
  async function renderOne(quiver, name, version, outDir, opts) {
88
86
  const ref = `${name}@${version}`;
89
- const tree = await quiver.loadTree(name, version);
90
- const exampleBytes = tree.get(EXAMPLE_FILE);
91
- if (exampleBytes === undefined) {
92
- return {
93
- ref,
94
- status: "skipped",
95
- files: [],
96
- warnings: [],
97
- reasons: [`no ${EXAMPLE_FILE} in quill directory`],
98
- };
99
- }
100
87
  let result;
101
88
  try {
102
89
  const quill = await quiver.getQuill(ref, { engine: opts.engine });
103
- const markdown = new TextDecoder().decode(exampleBytes);
90
+ const markdown = quill.blueprint;
104
91
  const doc = opts.Document.fromMarkdown(markdown);
105
92
  result = quill.render(doc, opts.format ? { format: opts.format } : undefined);
106
93
  }
@@ -145,8 +132,7 @@ function printSummary(quiverName, outDir, results) {
145
132
  for (const w of r.warnings)
146
133
  console.log(` ⚠ ${w}`);
147
134
  }
148
- console.log(`\n${count("rendered")} rendered, ${count("skipped")} skipped, ` +
149
- `${count("failed")} failed`);
135
+ console.log(`\n${count("rendered")} rendered, ${count("failed")} failed`);
150
136
  console.log(`Open ${join(outDir, "index.html")} to review.\n`);
151
137
  }
152
138
  function escapeHtml(text) {
@@ -198,7 +184,6 @@ function renderIndexHtml(quiverName, results) {
198
184
  .card { background: #fff; border: 1px solid #ddd; border-radius: 8px;
199
185
  padding: 1rem; margin: 1rem 0; }
200
186
  .card.failed { border-color: #e0b4b4; }
201
- .card.skipped { opacity: 0.7; }
202
187
  h2 { font-size: 1rem; margin: 0 0 0.5rem; }
203
188
  .badge { font-size: 0.7rem; text-transform: uppercase; background: #eee;
204
189
  border-radius: 4px; padding: 2px 6px; vertical-align: middle; }
package/dist/testing.d.ts CHANGED
@@ -7,14 +7,15 @@
7
7
  *
8
8
  * Usage (place this file next to your Quiver.yaml):
9
9
  *
10
- * import { Quillmark } from "@quillmark/wasm";
10
+ * import { Quillmark, Document } from "@quillmark/wasm";
11
11
  * import { runQuiverTests } from "@quillmark/quiver/testing";
12
12
  * const engine = new Quillmark();
13
- * runQuiverTests(import.meta.url, engine);
13
+ * runQuiverTests(import.meta.url, engine, Document);
14
14
  *
15
15
  * Run with `node --test`.
16
16
  */
17
17
  import type { QuillmarkLike } from "./engine-types.js";
18
+ import type { DocumentFactoryLike } from "./preview.js";
18
19
  /**
19
20
  * Registers a `node:test` describe block that validates every quill
20
21
  * version in the quiver at `metaUrlOrDir` against the provided engine.
@@ -23,6 +24,7 @@ import type { QuillmarkLike } from "./engine-types.js";
23
24
  * to Quiver.yaml). Pass an absolute directory path for any other layout.
24
25
  *
25
26
  * Validation covers the full loading pipeline: Quiver.yaml, Quill.yaml,
26
- * all template files, and engine compilation via engine.quill(tree).
27
+ * all template files, engine compilation via engine.quill(tree), and a
28
+ * full render of each quill's blueprint document.
27
29
  */
28
- export declare function runQuiverTests(metaUrlOrDir: string, engine: QuillmarkLike): void;
30
+ export declare function runQuiverTests(metaUrlOrDir: string, engine: QuillmarkLike, Document: DocumentFactoryLike): void;
package/dist/testing.js CHANGED
@@ -7,10 +7,10 @@
7
7
  *
8
8
  * Usage (place this file next to your Quiver.yaml):
9
9
  *
10
- * import { Quillmark } from "@quillmark/wasm";
10
+ * import { Quillmark, Document } from "@quillmark/wasm";
11
11
  * import { runQuiverTests } from "@quillmark/quiver/testing";
12
12
  * const engine = new Quillmark();
13
- * runQuiverTests(import.meta.url, engine);
13
+ * runQuiverTests(import.meta.url, engine, Document);
14
14
  *
15
15
  * Run with `node --test`.
16
16
  */
@@ -27,9 +27,10 @@ import { Quiver } from "./node.js";
27
27
  * to Quiver.yaml). Pass an absolute directory path for any other layout.
28
28
  *
29
29
  * Validation covers the full loading pipeline: Quiver.yaml, Quill.yaml,
30
- * all template files, and engine compilation via engine.quill(tree).
30
+ * all template files, engine compilation via engine.quill(tree), and a
31
+ * full render of each quill's blueprint document.
31
32
  */
32
- export function runQuiverTests(metaUrlOrDir, engine) {
33
+ export function runQuiverTests(metaUrlOrDir, engine, Document) {
33
34
  describe("Quiver", () => {
34
35
  let quiver;
35
36
  before(async () => {
@@ -40,12 +41,15 @@ export function runQuiverTests(metaUrlOrDir, engine) {
40
41
  throw new Error("Quiver has no quills");
41
42
  }
42
43
  });
43
- it("compiles every quill version without error", async () => {
44
+ it("compiles and renders every quill's blueprint without error", async () => {
44
45
  for (const name of quiver.quillNames()) {
45
46
  for (const version of quiver.versionsOf(name)) {
46
- const quill = await quiver.getQuill(`${name}@${version}`, { engine });
47
- if (typeof quill.render !== "function") {
48
- throw new Error(`${name}@${version}: engine returned non-conforming Quill`);
47
+ const ref = `${name}@${version}`;
48
+ const quill = await quiver.getQuill(ref, { engine });
49
+ const doc = Document.fromMarkdown(quill.blueprint);
50
+ const result = quill.render(doc);
51
+ if (!Array.isArray(result.artifacts) || result.artifacts.length === 0) {
52
+ throw new Error(`${ref}: blueprint render produced no artifacts`);
49
53
  }
50
54
  }
51
55
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quillmark/quiver",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "description": "Quiver registry and build tooling for Quillmark",
5
5
  "type": "module",
6
6
  "license": "MIT",