parsanol 0.10.3 → 0.10.4

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
@@ -23,6 +23,25 @@ const text = rt.renderString("ISO 5537:2025"); // F6 render
23
23
 
24
24
  Construction throws unless the artifact's embedded checksum verifies.
25
25
 
26
+ ## Provenance
27
+
28
+ Every artifact embeds its provenance; the runtime exposes and verifies
29
+ it (parsanol-ts#5):
30
+
31
+ ```ts
32
+ rt.sourceHash; // SHA-256 of the .parg source (bare hex)
33
+ rt.compilerVersion; // the compiler that produced the artifact
34
+ rt.source; // the embedded .parg source text
35
+ rt.shape; // wire-format family, "parsanol-tree/v2"
36
+ rt.compiledFrom(currentSource); // false = the artifact is stale
37
+ ```
38
+
39
+ A stale artifact (`compiledFrom` false against the current grammar text)
40
+ means the source moved since compilation — recompile or fall back.
41
+ `shape` moves independently of `compilerVersion`: the same
42
+ `parsanol-tree/v2` artifact parses identically on every engine, forever;
43
+ a shape bump means a new engine family.
44
+
26
45
  ## Vendored engine freshness
27
46
 
28
47
  `vendor/parsanol-wasm/BUILT_FROM` records the parsanol-rs commit the
package/dist/runtime.d.ts CHANGED
@@ -25,8 +25,21 @@ export declare class PargRuntime {
25
25
  readonly renderSpec: Record<string, RenderSegment[]>;
26
26
  readonly entry: string;
27
27
  readonly defaultEntry: string | null;
28
+ /** parsanol-ts#5 provenance: SHA-256 of the .parg source text and the
29
+ * compiler version. Null for artifacts compiled before these fields
30
+ * existed (unverifiable, not stale). */
31
+ readonly sourceHash: string | null;
32
+ readonly compilerVersion: string | null;
33
+ readonly source: string | null;
28
34
  readonly envelope: Record<string, unknown>;
29
35
  constructor(artifactJson: string, entry?: string);
36
+ /** The wire-format family ("parsanol-tree/v2"): a shape bump requires a
37
+ * new engine family; same-shape artifacts parse identically forever. */
38
+ get shape(): string | null;
39
+ /** True when this artifact was compiled from `source` (the current .parg
40
+ * revision). The compiler bakes a bare hex digest; artifacts without the
41
+ * field answer false — unverifiable rather than fresh. */
42
+ compiledFrom(source: string): boolean;
30
43
  /** Load an artifact JSON file and verify its checksum. */
31
44
  static fromFile(path: string, entry?: string): PargRuntime;
32
45
  /** The artifacts directory: PARG_ARTIFACT_DIR when set. */
package/dist/runtime.js CHANGED
@@ -3,6 +3,7 @@
3
3
  //! materialization. The engine is the vendored parsanol wasm build
4
4
  //! (PargArtifactJs) — no grammar code lives in this package; the baked
5
5
  //! artifact is the contract.
6
+ import { createHash } from "node:crypto";
6
7
  import { createRequire } from "node:module";
7
8
  import { existsSync, readFileSync } from "node:fs";
8
9
  import { fileURLToPath } from "node:url";
@@ -42,6 +43,12 @@ export class PargRuntime {
42
43
  renderSpec;
43
44
  entry;
44
45
  defaultEntry;
46
+ /** parsanol-ts#5 provenance: SHA-256 of the .parg source text and the
47
+ * compiler version. Null for artifacts compiled before these fields
48
+ * existed (unverifiable, not stale). */
49
+ sourceHash;
50
+ compilerVersion;
51
+ source;
45
52
  envelope;
46
53
  constructor(artifactJson, entry) {
47
54
  const parsed = JSON.parse(artifactJson);
@@ -62,8 +69,24 @@ export class PargRuntime {
62
69
  // The compiler bakes default_entry: JSON key order is not preserved
63
70
  // across engines, so the sorted entry list cannot rederive it.
64
71
  this.defaultEntry = parsed["default_entry"] ?? null;
72
+ this.sourceHash = parsed["source_hash"] ?? null;
73
+ this.compilerVersion = parsed["compiler_version"] ?? null;
74
+ this.source = parsed["source"] ?? null;
65
75
  this.entry = entry ?? this.defaultEntry ?? this.artifact.entryNames()[0];
66
76
  }
77
+ /** The wire-format family ("parsanol-tree/v2"): a shape bump requires a
78
+ * new engine family; same-shape artifacts parse identically forever. */
79
+ get shape() {
80
+ return this.envelope["shape"] ?? null;
81
+ }
82
+ /** True when this artifact was compiled from `source` (the current .parg
83
+ * revision). The compiler bakes a bare hex digest; artifacts without the
84
+ * field answer false — unverifiable rather than fresh. */
85
+ compiledFrom(source) {
86
+ if (this.sourceHash === null)
87
+ return false;
88
+ return this.sourceHash === createHash("sha256").update(source).digest("hex");
89
+ }
67
90
  /** Load an artifact JSON file and verify its checksum. */
68
91
  static fromFile(path, entry) {
69
92
  return new PargRuntime(readFileSync(path, "utf8"), entry);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "parsanol",
3
- "version": "0.10.3",
3
+ "version": "0.10.4",
4
4
  "description": "PARG artifact runtime for TypeScript \u2014 checksum-verified artifact load, wasm parse, bindings, schema-driven materialization",
5
5
  "type": "module",
6
6
  "main": "dist/runtime.js",
@@ -1,2 +1,2 @@
1
- 68d8f05b92379bd78365ca29fae05fc58b76f235
1
+ b3459f6887a178ffd177922a9b7666a525da6e2d
2
2
  built with: wasm-pack build --target=nodejs --features wasm (from parsanol-rs/parsanol)
@@ -39,7 +39,7 @@ class PargArtifactJs {
39
39
  */
40
40
  entryNames() {
41
41
  const ret = wasm.pargartifactjs_entryNames(this.__wbg_ptr);
42
- var v1 = getArrayJsValueFromWasm0(ret[0], ret[1]).slice();
42
+ var v1 = getArrayJsValueFromWasm0(ret[0], ret[1]);
43
43
  wasm.__wbindgen_free(ret[0], ret[1] * 4, 4);
44
44
  return v1;
45
45
  }
@@ -54,7 +54,7 @@ class PargArtifactJs {
54
54
  if (ret[2]) {
55
55
  throw takeFromExternrefTable0(ret[1]);
56
56
  }
57
- this.__wbg_ptr = ret[0] >>> 0;
57
+ this.__wbg_ptr = ret[0];
58
58
  PargArtifactJsFinalization.register(this, this.__wbg_ptr, this);
59
59
  return this;
60
60
  }
@@ -106,22 +106,22 @@ class PargArtifactJs {
106
106
  return takeFromExternrefTable0(ret[0]);
107
107
  }
108
108
  /**
109
- * The binding-requirements schema as JSON text.
109
+ * The binding-requirements schema as TypeScript source.
110
110
  * @returns {string}
111
111
  */
112
- schema() {
113
- const ret = wasm.pargartifactjs_schema(this.__wbg_ptr);
112
+ schemaTypescript() {
113
+ const ret = wasm.pargartifactjs_schemaTypescript(this.__wbg_ptr);
114
114
  if (ret[2]) {
115
115
  throw takeFromExternrefTable0(ret[1]);
116
116
  }
117
117
  return takeFromExternrefTable0(ret[0]);
118
118
  }
119
119
  /**
120
- * The binding-requirements schema as TypeScript source.
120
+ * The binding-requirements schema as JSON text.
121
121
  * @returns {string}
122
122
  */
123
- schemaTypescript() {
124
- const ret = wasm.pargartifactjs_schemaTypescript(this.__wbg_ptr);
123
+ schema() {
124
+ const ret = wasm.pargartifactjs_schema(this.__wbg_ptr);
125
125
  if (ret[2]) {
126
126
  throw takeFromExternrefTable0(ret[1]);
127
127
  }
@@ -138,7 +138,6 @@ exports.PargArtifactJs = PargArtifactJs;
138
138
  */
139
139
  class WasmParser {
140
140
  static __wrap(ptr) {
141
- ptr = ptr >>> 0;
142
141
  const obj = Object.create(WasmParser.prototype);
143
142
  obj.__wbg_ptr = ptr;
144
143
  WasmParserFinalization.register(obj, obj.__wbg_ptr, obj);
@@ -198,7 +197,7 @@ class WasmParser {
198
197
  if (ret[2]) {
199
198
  throw takeFromExternrefTable0(ret[1]);
200
199
  }
201
- this.__wbg_ptr = ret[0] >>> 0;
200
+ this.__wbg_ptr = ret[0];
202
201
  WasmParserFinalization.register(this, this.__wbg_ptr, this);
203
202
  return this;
204
203
  }
@@ -295,11 +294,10 @@ function init() {
295
294
  wasm.init();
296
295
  }
297
296
  exports.init = init;
298
-
299
297
  function __wbg_get_imports() {
300
298
  const import0 = {
301
299
  __proto__: null,
302
- __wbg___wbindgen_string_get_395e606bd0ee4427: function(arg0, arg1) {
300
+ __wbg___wbindgen_string_get_0380ccaa2f57f0d9: function(arg0, arg1) {
303
301
  const obj = arg1;
304
302
  const ret = typeof(obj) === 'string' ? obj : undefined;
305
303
  var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
@@ -307,10 +305,10 @@ function __wbg_get_imports() {
307
305
  getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
308
306
  getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
309
307
  },
310
- __wbg___wbindgen_throw_6ddd609b62940d55: function(arg0, arg1) {
308
+ __wbg___wbindgen_throw_41e9ee4f547fc59a: function(arg0, arg1) {
311
309
  throw new Error(getStringFromWasm0(arg0, arg1));
312
310
  },
313
- __wbg_error_a6fa202b58aa1cd3: function(arg0, arg1) {
311
+ __wbg_error_757e9472f8410341: function(arg0, arg1) {
314
312
  let deferred0_0;
315
313
  let deferred0_1;
316
314
  try {
@@ -321,26 +319,26 @@ function __wbg_get_imports() {
321
319
  wasm.__wbindgen_free(deferred0_0, deferred0_1, 1);
322
320
  }
323
321
  },
324
- __wbg_getRandomValues_3f44b700395062e5: function() { return handleError(function (arg0, arg1) {
322
+ __wbg_getRandomValues_a608c4436c19407a: function() { return handleError(function (arg0, arg1) {
325
323
  globalThis.crypto.getRandomValues(getArrayU8FromWasm0(arg0, arg1));
326
324
  }, arguments); },
327
325
  __wbg_new_227d7c05414eb861: function() {
328
326
  const ret = new Error();
329
327
  return ret;
330
328
  },
331
- __wbg_new_a70fbab9066b301f: function() {
332
- const ret = new Array();
329
+ __wbg_new_617a8cdb8bb1130e: function() {
330
+ const ret = new Object();
333
331
  return ret;
334
332
  },
335
- __wbg_new_ab79df5bd7c26067: function() {
336
- const ret = new Object();
333
+ __wbg_new_ee2291f50781bf1d: function() {
334
+ const ret = new Array();
337
335
  return ret;
338
336
  },
339
- __wbg_push_e87b0e732085a946: function(arg0, arg1) {
337
+ __wbg_push_2baf45db356cf468: function(arg0, arg1) {
340
338
  const ret = arg0.push(arg1);
341
339
  return ret;
342
340
  },
343
- __wbg_set_7eaa4f96924fd6b3: function() { return handleError(function (arg0, arg1, arg2) {
341
+ __wbg_set_145a351398b48c65: function() { return handleError(function (arg0, arg1, arg2) {
344
342
  const ret = Reflect.set(arg0, arg1, arg2);
345
343
  return ret;
346
344
  }, arguments); },
@@ -351,16 +349,16 @@ function __wbg_get_imports() {
351
349
  getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
352
350
  getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
353
351
  },
354
- __wbg_stringify_5ae93966a84901ac: function() { return handleError(function (arg0) {
352
+ __wbg_stringify_52ff602c1cc4fbb6: function() { return handleError(function (arg0) {
355
353
  const ret = JSON.stringify(arg0);
356
354
  return ret;
357
355
  }, arguments); },
358
- __wbindgen_cast_0000000000000001: function(arg0) {
356
+ __wbindgen_generic_0000000000000001: function(arg0) {
359
357
  // Cast intrinsic for `F64 -> Externref`.
360
358
  const ret = arg0;
361
359
  return ret;
362
360
  },
363
- __wbindgen_cast_0000000000000002: function(arg0, arg1) {
361
+ __wbindgen_generic_0000000000000002: function(arg0, arg1) {
364
362
  // Cast intrinsic for `Ref(String) -> Externref`.
365
363
  const ret = getStringFromWasm0(arg0, arg1);
366
364
  return ret;
@@ -383,10 +381,10 @@ function __wbg_get_imports() {
383
381
 
384
382
  const PargArtifactJsFinalization = (typeof FinalizationRegistry === 'undefined')
385
383
  ? { register: () => {}, unregister: () => {} }
386
- : new FinalizationRegistry(ptr => wasm.__wbg_pargartifactjs_free(ptr >>> 0, 1));
384
+ : new FinalizationRegistry(ptr => wasm.__wbg_pargartifactjs_free(ptr, 1));
387
385
  const WasmParserFinalization = (typeof FinalizationRegistry === 'undefined')
388
386
  ? { register: () => {}, unregister: () => {} }
389
- : new FinalizationRegistry(ptr => wasm.__wbg_wasmparser_free(ptr >>> 0, 1));
387
+ : new FinalizationRegistry(ptr => wasm.__wbg_wasmparser_free(ptr, 1));
390
388
 
391
389
  function addToExternrefTable0(obj) {
392
390
  const idx = wasm.__externref_table_alloc();
@@ -432,8 +430,7 @@ function getDataViewMemory0() {
432
430
  }
433
431
 
434
432
  function getStringFromWasm0(ptr, len) {
435
- ptr = ptr >>> 0;
436
- return decodeText(ptr, len);
433
+ return decodeText(ptr >>> 0, len);
437
434
  }
438
435
 
439
436
  let cachedUint8ArrayMemory0 = null;
@@ -524,5 +521,6 @@ let WASM_VECTOR_LEN = 0;
524
521
  const wasmPath = `${__dirname}/parsanol_bg.wasm`;
525
522
  const wasmBytes = require('fs').readFileSync(wasmPath);
526
523
  const wasmModule = new WebAssembly.Module(wasmBytes);
527
- let wasm = new WebAssembly.Instance(wasmModule, __wbg_get_imports()).exports;
524
+ let wasmInstance = new WebAssembly.Instance(wasmModule, __wbg_get_imports());
525
+ let wasm = wasmInstance.exports;
528
526
  wasm.__wbindgen_start();
@@ -35,14 +35,14 @@ export class PargArtifactJs {
35
35
  * JSON (empty array means green).
36
36
  */
37
37
  runTests(): string;
38
- /**
39
- * The binding-requirements schema as JSON text.
40
- */
41
- schema(): string;
42
38
  /**
43
39
  * The binding-requirements schema as TypeScript source.
44
40
  */
45
41
  schemaTypescript(): string;
42
+ /**
43
+ * The binding-requirements schema as JSON text.
44
+ */
45
+ schema(): string;
46
46
  }
47
47
 
48
48
  /**
@@ -3,6 +3,7 @@
3
3
  export const memory: WebAssembly.Memory;
4
4
  export const __wbg_pargartifactjs_free: (a: number, b: number) => void;
5
5
  export const __wbg_wasmparser_free: (a: number, b: number) => void;
6
+ export const init: () => void;
6
7
  export const pargartifactjs_applyBindings: (a: number, b: number, c: number, d: number, e: number) => [number, number, number];
7
8
  export const pargartifactjs_entryNames: (a: number) => [number, number];
8
9
  export const pargartifactjs_new: (a: number, b: number) => [number, number, number];
@@ -10,7 +11,6 @@ export const pargartifactjs_parseAndBind: (a: number, b: number, c: number, d: n
10
11
  export const pargartifactjs_parseShape: (a: number, b: number, c: number, d: number, e: number) => [number, number, number];
11
12
  export const pargartifactjs_runTests: (a: number) => [number, number, number];
12
13
  export const pargartifactjs_schema: (a: number) => [number, number, number];
13
- export const pargartifactjs_schemaTypescript: (a: number) => [number, number, number];
14
14
  export const parsanol_c_last_error: () => number;
15
15
  export const parsanol_c_parse: (a: bigint, b: number, c: number, d: number) => number;
16
16
  export const parsanol_c_parse_len: (a: bigint, b: number, c: number, d: number, e: number) => number;
@@ -33,12 +33,12 @@ export const parsanol_result_error: (a: number) => number;
33
33
  export const parsanol_result_free: (a: number) => void;
34
34
  export const parsanol_result_success: (a: number) => number;
35
35
  export const parsanol_version: () => number;
36
+ export const pargartifactjs_schemaTypescript: (a: number) => [number, number, number];
36
37
  export const wasmparser_fromArtifact: (a: number, b: number, c: number, d: number) => [number, number, number];
37
38
  export const wasmparser_new: (a: number, b: number) => [number, number, number];
38
39
  export const wasmparser_parse: (a: number, b: number, c: number) => [number, number, number];
39
40
  export const wasmparser_parse_flat: (a: number, b: number, c: number) => [number, number, number, number];
40
41
  export const wasmparser_parse_json: (a: number, b: number, c: number) => [number, number, number, number];
41
- export const init: () => void;
42
42
  export const parsanol_string_free: (a: number) => void;
43
43
  export const __wbindgen_malloc: (a: number, b: number) => number;
44
44
  export const __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;