@canonical/pragma-cli 0.21.0 → 0.22.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/dist/pragma CHANGED
Binary file
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@canonical/pragma-cli",
3
3
  "description": "CLI and MCP server for Canonical's design system.",
4
- "version": "0.21.0",
4
+ "version": "0.22.0",
5
5
  "type": "module",
6
6
  "module": "src/index.ts",
7
7
  "types": "src/index.ts",
@@ -57,9 +57,9 @@
57
57
  },
58
58
  "devDependencies": {
59
59
  "@biomejs/biome": "2.4.9",
60
- "@canonical/biome-config": "^0.21.0",
61
- "@canonical/typescript-config": "^0.21.0",
62
- "@canonical/webarchitect": "^0.21.0",
60
+ "@canonical/biome-config": "^0.22.0",
61
+ "@canonical/typescript-config": "^0.22.0",
62
+ "@canonical/webarchitect": "^0.22.0",
63
63
  "@types/bun": "^1.3.10",
64
64
  "@types/node": "^24.12.0",
65
65
  "@types/react": "^19.2.14",
@@ -73,19 +73,20 @@
73
73
  "@canonical/design-system": "^0.1.2"
74
74
  },
75
75
  "dependencies": {
76
- "@canonical/cli-core": "^0.21.0",
77
- "@canonical/harnesses": "^0.21.0",
78
- "@canonical/ke": "^0.21.0",
79
- "@canonical/summon-component": "^0.21.0",
80
- "@canonical/summon-core": "^0.21.0",
81
- "@canonical/summon-package": "^0.21.0",
82
- "@canonical/task": "^0.21.0",
76
+ "@canonical/cli-core": "^0.22.0",
77
+ "@canonical/harnesses": "^0.22.0",
78
+ "@canonical/ke": "^0.22.0",
79
+ "@canonical/summon-component": "^0.22.0",
80
+ "@canonical/summon-core": "^0.22.0",
81
+ "@canonical/summon-package": "^0.22.0",
82
+ "@canonical/task": "^0.22.0",
83
83
  "@modelcontextprotocol/sdk": "^1.12.0",
84
84
  "chalk": "^5.6.2",
85
85
  "commander": "^14.0.3",
86
86
  "ink": "^6.8.0",
87
+ "oxigraph": "^0.5.0",
87
88
  "react": "^19.2.4",
88
89
  "zod": "^3.25.0"
89
90
  },
90
- "gitHead": "4a39c954e7bbad4903397f8371f801982034a26d"
91
+ "gitHead": "99e187cf46d8bd7f3933705322fa4ab2d4a711e7"
91
92
  }
package/src/bin.test.ts CHANGED
@@ -12,6 +12,8 @@ vi.mock("./pipeline/runCli.js", () => ({
12
12
  default: runCliMock,
13
13
  }));
14
14
 
15
+ vi.mock("./embedWasm.js", () => ({}));
16
+
15
17
  describe("bin", () => {
16
18
  const originalArgv = process.argv;
17
19
 
package/src/bin.ts CHANGED
@@ -8,6 +8,7 @@
8
8
  * @note Impure
9
9
  */
10
10
 
11
+ import "./embedWasm.js";
11
12
  import { detectLocalInstall } from "./package-manager/index.js";
12
13
  import runCli from "./pipeline/runCli.js";
13
14
 
@@ -6,7 +6,7 @@
6
6
  * and queries correctly when embedded in a compiled Bun binary.
7
7
  *
8
8
  * Tests exercised:
9
- * 1. Dynamic import of @canonical/ke (triggers WASM loading)
9
+ * 1. Static import of @canonical/ke (triggers WASM loading)
10
10
  * 2. createStore() with file sources
11
11
  * 3. SPARQL SELECT query with prefix expansion
12
12
  * 4. sparql tagged template with branded URI interpolation
@@ -18,9 +18,11 @@
18
18
  * It is a build validation program, not a library module.
19
19
  */
20
20
 
21
+ import "./embedWasm.js";
21
22
  import { existsSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
22
23
  import { tmpdir } from "node:os";
23
24
  import { join } from "node:path";
25
+ import { createNamespace, createStore, sparql } from "@canonical/ke";
24
26
 
25
27
  async function run() {
26
28
  const start = performance.now();
@@ -58,9 +60,6 @@ ex:charlie a schema:Person ;
58
60
  // --- 1. Load ke (triggers WASM) ---
59
61
  console.log("[validate] Loading @canonical/ke (triggers WASM)...");
60
62
  const wasmStart = performance.now();
61
- const { createStore, sparql, createNamespace } = await import(
62
- "@canonical/ke"
63
- );
64
63
  console.log(
65
64
  `[validate] WASM loaded in ${(performance.now() - wasmStart).toFixed(1)}ms`,
66
65
  );
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Embed oxigraph WASM for `bun build --compile`.
3
+ *
4
+ * Bun's bundler does not automatically embed WASM files loaded via
5
+ * `readFileSync(path.join(__dirname, 'node_bg.wasm'))` — the `__dirname`
6
+ * is hardcoded to the build-time path and `readFileSync` is not
7
+ * intercepted for embedded data at runtime.
8
+ *
9
+ * This module dynamically imports the WASM file with `{ type: "file" }`,
10
+ * which bun embeds into the compiled binary's `$bunfs` virtual filesystem.
11
+ * It then patches CJS `readFileSync` so that oxigraph's WASM loader
12
+ * returns the pre-loaded bytes instead of reading from a stale path.
13
+ *
14
+ * In interpreted mode the dynamic import resolves to the real filesystem
15
+ * path and the patch is effectively a no-op (reads the same bytes).
16
+ *
17
+ * This module MUST be imported before any code that loads oxigraph.
18
+ */
19
+
20
+ import { readFileSync } from "node:fs";
21
+
22
+ // @ts-expect-error — bun-specific import attribute for file embedding
23
+ const { default: wasmPath } = await import("oxigraph/node_bg.wasm", {
24
+ with: { type: "file" },
25
+ });
26
+ const wasmBytes = readFileSync(wasmPath);
27
+
28
+ // Oxigraph's CJS wrapper uses require("fs").readFileSync(...) to load
29
+ // the WASM. Patch the CJS fs module (mutable, unlike ESM bindings) so
30
+ // reads targeting node_bg.wasm return the pre-loaded bytes.
31
+ const cjsFs = import.meta.require("fs");
32
+ const origReadFileSync = cjsFs.readFileSync;
33
+
34
+ cjsFs.readFileSync = function patchedReadFileSync(
35
+ path: string,
36
+ ...args: unknown[]
37
+ ) {
38
+ if (typeof path === "string" && path.endsWith("/node_bg.wasm")) {
39
+ return wasmBytes;
40
+ }
41
+ return origReadFileSync(path, ...args);
42
+ };