@francisdb/vpin-wasm 0.33.1 → 0.34.1

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
@@ -66,25 +66,33 @@ const vpxBytes = assemble(files, (message) => {
66
66
 
67
67
  Checks the expanded table files for consistency problems: references to
68
68
  images, materials, surfaces or collection items that do not exist, duplicate
69
- or over-long names, and storage suggestions. The checks themselves run in a
70
- few milliseconds even on very large tables, so it is fine to call this after
71
- every change; the cost is dominated by reading the files into a table.
69
+ or over-long names, storage suggestions, and script checks (missing
70
+ `Option Explicit`, duplicate procedures, unused variables, timers without a
71
+ handler, VPinMAME setup). The checks themselves run in a few milliseconds
72
+ even on very large tables, so it is fine to call this after every change;
73
+ the cost is dominated by reading the files into a table.
72
74
 
73
75
  ```typescript
74
76
  const findings = audit(files);
75
77
  for (const finding of findings) {
76
- console.log(`${finding.severity}: ${finding.message}`);
78
+ const where = finding.line ? ` (line ${finding.line})` : "";
79
+ console.log(`${finding.severity} [${finding.code}]${where}: ${finding.message}`);
77
80
  }
78
- // warning: Light "L18": placed on missing surface "!l68"
79
- // suggestion: image "chrome" is stored as a bitmap, consider converting to webp
81
+ // warning [missing-surface]: Light "L18": placed on missing surface "!l68"
82
+ // suggestion [bmp-image]: image "chrome" is stored as a bitmap, consider converting to webp
83
+ // suggestion [execute-used] (line 812): script uses Execute, which runs runtime-built code and can stutter
80
84
  ```
81
85
 
86
+ `code` names the check and is stable, so findings can be grouped or
87
+ suppressed by it; `line` and `column` (both from 1) are set for findings
88
+ about one place in the script.
89
+
82
90
  **Parameters:**
83
91
 
84
92
  - `files: VpxFileMap` (`Record<string, Uint8Array>`) - file paths to contents
85
93
  - `callback?: (message: string) => void` - Optional progress callback
86
94
 
87
- **Returns:** `{severity: "warning" | "suggestion", message: string}[]` - empty when the table is clean
95
+ **Returns:** `{severity: "error" | "warning" | "suggestion" | "info", code: string, message: string, line?: number, column?: number}[]` - empty when the table is clean
88
96
 
89
97
  ### export_glb(files, options?, callback?)
90
98
 
@@ -113,10 +121,14 @@ down on sound-heavy tables. A map without them works too.
113
121
  **Parameters:**
114
122
 
115
123
  - `files: VpxFileMap` (`Record<string, Uint8Array>`) - file paths to contents
116
- - `options?: GlbExportOptions` - `{ exportInvisibleItems?: boolean }`;
117
- when `true`, invisible items are exported with the
118
- `KHR_node_visibility` extension instead of skipped (needs viewer
119
- support; leave off for Blender). Default `false`.
124
+ - `options?: GlbExportOptions` - `{ exportInvisibleItems?: boolean, itemFilter?: "everything" | "vpinball", skipEditorHiddenItems?: boolean, onlyItems?: string[], excludeItems?: string[] }`;
125
+ `exportInvisibleItems: true` exports invisible items with the
126
+ `KHR_node_visibility` extension instead of skipping them (needs viewer
127
+ support; leave off for Blender). `itemFilter` picks the item selection:
128
+ `"everything"` (default) or `"vpinball"`, what vpinball's own OBJ export
129
+ writes. `skipEditorHiddenItems` leaves out the items on hidden editor
130
+ layers, and `onlyItems` / `excludeItems` select items by name. The same
131
+ four filter options exist on `export_obj`.
120
132
  - `callback?: (message: string) => void` - Optional progress callback
121
133
 
122
134
  **Returns:** `Uint8Array` - GLB file bytes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@francisdb/vpin-wasm",
3
- "version": "0.33.1",
3
+ "version": "0.34.1",
4
4
  "description": "WASM bindings for vpin, a rust library for the visual/virtual pinball ecosystem.",
5
5
  "homepage": "https://github.com/francisdb/vpin",
6
6
  "bugs": {
package/vpin.d.ts CHANGED
@@ -18,8 +18,15 @@ export type ProgressCallback = (message: string) => void;
18
18
  * One table consistency finding reported by `audit`.
19
19
  */
20
20
  export type AuditFinding = {
21
- severity: "error" | "warning" | "suggestion";
21
+ severity: "error" | "warning" | "suggestion" | "info";
22
+ /** The check that produced the finding, in kebab case, e.g. "missing-image" */
23
+ code: string;
24
+ /** What is wrong, without the location */
22
25
  message: string;
26
+ /** Script line the finding is about, from 1, when it points at one */
27
+ line?: number;
28
+ /** Script column of the first character, from 1, when known */
29
+ column?: number;
23
30
  };
24
31
 
25
32
 
@@ -37,6 +44,29 @@ export interface GlbExportOptions {
37
44
  * engines); leave off for Blender. Default: `false`.
38
45
  */
39
46
  exportInvisibleItems?: boolean;
47
+ /**
48
+ * Which items the export includes. `"everything"`: every item type
49
+ * with geometry, skipping the ones invisible at play time.
50
+ * `"vpinball"`: what vpinball's own `File -> Export -> OBJ Mesh`
51
+ * writes (no lights, flashers, decals, plungers or balls). Default:
52
+ * `"everything"`.
53
+ */
54
+ itemFilter?: "everything" | "vpinball";
55
+ /**
56
+ * Skip the items whose editor layer is hidden (the `LVIS` record),
57
+ * like vpinball's own OBJ export does. Opt-in: the record holds the
58
+ * layer panel state of the last save, and released tables often
59
+ * have most layers hidden. Default: `false`.
60
+ */
61
+ skipEditorHiddenItems?: boolean;
62
+ /**
63
+ * Only export the items with these names (case insensitive).
64
+ */
65
+ onlyItems?: string[];
66
+ /**
67
+ * Skip the items with these names (case insensitive).
68
+ */
69
+ excludeItems?: string[];
40
70
  }
41
71
 
42
72
 
@@ -68,9 +98,28 @@ export interface ObjExportOptions {
68
98
  */
69
99
  extractTextures?: boolean;
70
100
  /**
71
- * Include the plunger mesh. Default: `true`.
101
+ * Which items the export includes. `"everything"`: every item type
102
+ * with geometry, skipping the ones invisible at play time.
103
+ * `"vpinball"`: what vpinball's own `File -> Export -> OBJ Mesh`
104
+ * writes (no lights, flashers, decals, plungers or balls). Default:
105
+ * `"everything"`.
106
+ */
107
+ itemFilter?: "everything" | "vpinball";
108
+ /**
109
+ * Skip the items whose editor layer is hidden (the `LVIS` record),
110
+ * like vpinball's own OBJ export does. Opt-in: the record holds the
111
+ * layer panel state of the last save, and released tables often
112
+ * have most layers hidden. Default: `false`.
72
113
  */
73
- includePlunger?: boolean;
114
+ skipEditorHiddenItems?: boolean;
115
+ /**
116
+ * Only export the items with these names (case insensitive).
117
+ */
118
+ onlyItems?: string[];
119
+ /**
120
+ * Skip the items with these names (case insensitive).
121
+ */
122
+ excludeItems?: string[];
74
123
  }
75
124
 
76
125
  /**
@@ -214,6 +263,11 @@ export class PrimitiveMesh {
214
263
  private constructor();
215
264
  free(): void;
216
265
  [Symbol.dispose](): void;
266
+ /**
267
+ * Triangle corner indices, three per triangle, as 0-based offsets
268
+ * into the aligned vertex arrays. Each access copies the data out of
269
+ * wasm memory.
270
+ */
217
271
  readonly indices: Uint32Array;
218
272
  /**
219
273
  * Bounding-box midpoint of the mesh's positions, in the same
@@ -229,19 +283,57 @@ export class PrimitiveMesh {
229
283
  * Returns `[0, 0, 0]` for an empty mesh.
230
284
  */
231
285
  readonly midpoint: Float32Array;
286
+ /**
287
+ * The mesh name: the `o` name of the OBJ it was read from, or
288
+ * `primitive` for a generated mesh.
289
+ */
232
290
  readonly name: string;
291
+ /**
292
+ * Vertex normals as a flat `x, y, z` array, three values per corner,
293
+ * aligned with `positions`. Each access copies the data out of wasm
294
+ * memory.
295
+ */
233
296
  readonly normals: Float32Array;
297
+ /**
298
+ * Vertex positions as a flat `x, y, z` array, three values per
299
+ * corner. Each access copies the data out of wasm memory.
300
+ */
234
301
  readonly positions: Float32Array;
302
+ /**
303
+ * Texture coordinates as a flat `u, v` array, two values per corner,
304
+ * aligned with `positions`. Exposed to JavaScript as `texCoords`.
305
+ * Each access copies the data out of wasm memory.
306
+ */
235
307
  readonly texCoords: Float32Array;
236
308
  }
237
309
 
310
+ /**
311
+ * Packs an expanded table back into a `.vpx` file.
312
+ *
313
+ * `files` is the `VpxFileMap` produced by [`extract`], with whatever
314
+ * edits the caller made to its entries; the table is read from the
315
+ * entries under `/vpx`. The result is the bytes of the `.vpx` file, as
316
+ * a `Uint8Array`.
317
+ * Assembling an unmodified map writes a file that holds the same table
318
+ * as the one that was extracted.
319
+ *
320
+ * `callback`, when given, receives a status message at every stage of
321
+ * the assembly.
322
+ *
323
+ * # Errors
324
+ *
325
+ * Throws a `JsError` whose message names the problem when a map value is
326
+ * not a byte array, a required file is missing or malformed, or the
327
+ * table cannot be written.
328
+ */
238
329
  export function assemble(files: VpxFileMap, callback?: ProgressCallback | null): Uint8Array;
239
330
 
240
331
  /**
241
332
  * Checks the expanded table files for consistency problems: references to
242
333
  * images, materials, surfaces or collection items that do not exist,
243
- * duplicate or over-long names, and storage suggestions. Returns an array
244
- * of `{severity, message}` objects, empty when the table is clean.
334
+ * duplicate or over-long names, storage suggestions and script checks.
335
+ * Returns an array of `{severity, code, message, line?, column?}` objects,
336
+ * empty when the table is clean.
245
337
  */
246
338
  export function audit(files: VpxFileMap, callback?: ProgressCallback | null): AuditFinding[];
247
339
 
@@ -276,6 +368,25 @@ export function export_glb(files: VpxFileMap, options?: GlbExportOptions | null,
276
368
  */
277
369
  export function export_obj(files: VpxFileMap, options?: ObjExportOptions | null, callback?: ProgressCallback | null): ObjExportFileMap;
278
370
 
371
+ /**
372
+ * Unpacks a `.vpx` file into the expanded directory format as a file map.
373
+ *
374
+ * `data` holds the bytes of the `.vpx` file, as a `Uint8Array`. The
375
+ * result is a `VpxFileMap`: a plain object from absolute path under
376
+ * `/vpx` to a `Uint8Array`, for example `/vpx/images/ball.png` or
377
+ * `/vpx/gameitems/Wall1.json`. Primitive meshes come out as `.obj`
378
+ * files; the derived meshes vpinball generates for other items are not
379
+ * included. The map is what [`assemble`], [`audit`], [`export_glb`] and
380
+ * [`export_obj`] take.
381
+ *
382
+ * `callback`, when given, receives a status message at every stage of
383
+ * the extraction.
384
+ *
385
+ * # Errors
386
+ *
387
+ * Throws a `JsError` whose message names the problem when the bytes are
388
+ * not a readable `.vpx` file or the expansion fails.
389
+ */
279
390
  export function extract(data: Uint8Array, callback?: ProgressCallback | null): VpxFileMap;
280
391
 
281
392
  /**
@@ -299,6 +410,11 @@ export function extract(data: Uint8Array, callback?: ProgressCallback | null): V
299
410
  */
300
411
  export function generate_builtin_primitive(sides: number, draw_textures_inside: boolean): PrimitiveMesh;
301
412
 
413
+ /**
414
+ * Runs once when the wasm module is instantiated; installs the panic
415
+ * hook that forwards Rust panics to the browser console. JavaScript
416
+ * callers never call this themselves.
417
+ */
302
418
  export function init(): void;
303
419
 
304
420
  /**
package/vpin.js CHANGED
@@ -112,6 +112,9 @@ export class PrimitiveMesh {
112
112
  wasm.__wbg_primitivemesh_free(ptr, 0);
113
113
  }
114
114
  /**
115
+ * Triangle corner indices, three per triangle, as 0-based offsets
116
+ * into the aligned vertex arrays. Each access copies the data out of
117
+ * wasm memory.
115
118
  * @returns {Uint32Array}
116
119
  */
117
120
  get indices() {
@@ -137,6 +140,8 @@ export class PrimitiveMesh {
137
140
  return ret;
138
141
  }
139
142
  /**
143
+ * The mesh name: the `o` name of the OBJ it was read from, or
144
+ * `primitive` for a generated mesh.
140
145
  * @returns {string}
141
146
  */
142
147
  get name() {
@@ -152,6 +157,9 @@ export class PrimitiveMesh {
152
157
  }
153
158
  }
154
159
  /**
160
+ * Vertex normals as a flat `x, y, z` array, three values per corner,
161
+ * aligned with `positions`. Each access copies the data out of wasm
162
+ * memory.
155
163
  * @returns {Float32Array}
156
164
  */
157
165
  get normals() {
@@ -159,6 +167,8 @@ export class PrimitiveMesh {
159
167
  return ret;
160
168
  }
161
169
  /**
170
+ * Vertex positions as a flat `x, y, z` array, three values per
171
+ * corner. Each access copies the data out of wasm memory.
162
172
  * @returns {Float32Array}
163
173
  */
164
174
  get positions() {
@@ -166,6 +176,9 @@ export class PrimitiveMesh {
166
176
  return ret;
167
177
  }
168
178
  /**
179
+ * Texture coordinates as a flat `u, v` array, two values per corner,
180
+ * aligned with `positions`. Exposed to JavaScript as `texCoords`.
181
+ * Each access copies the data out of wasm memory.
169
182
  * @returns {Float32Array}
170
183
  */
171
184
  get texCoords() {
@@ -176,6 +189,23 @@ export class PrimitiveMesh {
176
189
  if (Symbol.dispose) PrimitiveMesh.prototype[Symbol.dispose] = PrimitiveMesh.prototype.free;
177
190
 
178
191
  /**
192
+ * Packs an expanded table back into a `.vpx` file.
193
+ *
194
+ * `files` is the `VpxFileMap` produced by [`extract`], with whatever
195
+ * edits the caller made to its entries; the table is read from the
196
+ * entries under `/vpx`. The result is the bytes of the `.vpx` file, as
197
+ * a `Uint8Array`.
198
+ * Assembling an unmodified map writes a file that holds the same table
199
+ * as the one that was extracted.
200
+ *
201
+ * `callback`, when given, receives a status message at every stage of
202
+ * the assembly.
203
+ *
204
+ * # Errors
205
+ *
206
+ * Throws a `JsError` whose message names the problem when a map value is
207
+ * not a byte array, a required file is missing or malformed, or the
208
+ * table cannot be written.
179
209
  * @param {VpxFileMap} files
180
210
  * @param {ProgressCallback | null} [callback]
181
211
  * @returns {Uint8Array}
@@ -193,8 +223,9 @@ export function assemble(files, callback) {
193
223
  /**
194
224
  * Checks the expanded table files for consistency problems: references to
195
225
  * images, materials, surfaces or collection items that do not exist,
196
- * duplicate or over-long names, and storage suggestions. Returns an array
197
- * of `{severity, message}` objects, empty when the table is clean.
226
+ * duplicate or over-long names, storage suggestions and script checks.
227
+ * Returns an array of `{severity, code, message, line?, column?}` objects,
228
+ * empty when the table is clean.
198
229
  * @param {VpxFileMap} files
199
230
  * @param {ProgressCallback | null} [callback]
200
231
  * @returns {AuditFinding[]}
@@ -261,6 +292,23 @@ export function export_obj(files, options, callback) {
261
292
  }
262
293
 
263
294
  /**
295
+ * Unpacks a `.vpx` file into the expanded directory format as a file map.
296
+ *
297
+ * `data` holds the bytes of the `.vpx` file, as a `Uint8Array`. The
298
+ * result is a `VpxFileMap`: a plain object from absolute path under
299
+ * `/vpx` to a `Uint8Array`, for example `/vpx/images/ball.png` or
300
+ * `/vpx/gameitems/Wall1.json`. Primitive meshes come out as `.obj`
301
+ * files; the derived meshes vpinball generates for other items are not
302
+ * included. The map is what [`assemble`], [`audit`], [`export_glb`] and
303
+ * [`export_obj`] take.
304
+ *
305
+ * `callback`, when given, receives a status message at every stage of
306
+ * the extraction.
307
+ *
308
+ * # Errors
309
+ *
310
+ * Throws a `JsError` whose message names the problem when the bytes are
311
+ * not a readable `.vpx` file or the expansion fails.
264
312
  * @param {Uint8Array} data
265
313
  * @param {ProgressCallback | null} [callback]
266
314
  * @returns {VpxFileMap}
@@ -305,6 +353,11 @@ export function generate_builtin_primitive(sides, draw_textures_inside) {
305
353
  return PrimitiveMesh.__wrap(ret[0]);
306
354
  }
307
355
 
356
+ /**
357
+ * Runs once when the wasm module is instantiated; installs the panic
358
+ * hook that forwards Rust panics to the browser console. JavaScript
359
+ * callers never call this themselves.
360
+ */
308
361
  export function init() {
309
362
  wasm.init();
310
363
  }
@@ -489,6 +542,10 @@ function __wbg_get_imports() {
489
542
  const ret = arg0 in arg1;
490
543
  return ret;
491
544
  },
545
+ __wbg___wbindgen_is_function_fcda5e3902d732fe: function(arg0) {
546
+ const ret = typeof(arg0) === 'function';
547
+ return ret;
548
+ },
492
549
  __wbg___wbindgen_is_null_5160b3e381865372: function(arg0) {
493
550
  const ret = arg0 === null;
494
551
  return ret;
@@ -523,10 +580,18 @@ function __wbg_get_imports() {
523
580
  __wbg___wbindgen_throw_5d9e815e6fdf150f: function(arg0, arg1) {
524
581
  throw new Error(getStringFromWasm0(arg0, arg1));
525
582
  },
583
+ __wbg_call_269c5566fbede3eb: function() { return handleError(function (arg0, arg1) {
584
+ const ret = arg0.call(arg1);
585
+ return ret;
586
+ }, arguments); },
526
587
  __wbg_call_6bcf8d3e20937e46: function() { return handleError(function (arg0, arg1, arg2) {
527
588
  const ret = arg0.call(arg1, arg2);
528
589
  return ret;
529
590
  }, arguments); },
591
+ __wbg_done_cffed884d87aa22e: function(arg0) {
592
+ const ret = arg0.done;
593
+ return ret;
594
+ },
530
595
  __wbg_error_757e9472f8410341: function(arg0, arg1) {
531
596
  let deferred0_0;
532
597
  let deferred0_1;
@@ -538,6 +603,10 @@ function __wbg_get_imports() {
538
603
  wasm.__wbindgen_free(deferred0_0, deferred0_1, 1);
539
604
  }
540
605
  },
606
+ __wbg_get_6cf5a4d4d8ad3c5a: function() { return handleError(function (arg0, arg1) {
607
+ const ret = Reflect.get(arg0, arg1);
608
+ return ret;
609
+ }, arguments); },
541
610
  __wbg_get_989d0a1309644f2b: function() { return handleError(function (arg0, arg1) {
542
611
  const ret = Reflect.get(arg0, arg1);
543
612
  return ret;
@@ -546,6 +615,10 @@ function __wbg_get_imports() {
546
615
  const ret = arg0[arg1 >>> 0];
547
616
  return ret;
548
617
  },
618
+ __wbg_get_unchecked_363572bdd397d473: function(arg0, arg1) {
619
+ const ret = arg0[arg1 >>> 0];
620
+ return ret;
621
+ },
549
622
  __wbg_get_with_ref_key_6412cf3094599694: function(arg0, arg1) {
550
623
  const ret = arg0[arg1];
551
624
  return ret;
@@ -570,10 +643,18 @@ function __wbg_get_imports() {
570
643
  const ret = result;
571
644
  return ret;
572
645
  },
646
+ __wbg_isArray_5674713bb7b79043: function(arg0) {
647
+ const ret = Array.isArray(arg0);
648
+ return ret;
649
+ },
573
650
  __wbg_isSafeInteger_8f51c743827d1ec5: function(arg0) {
574
651
  const ret = Number.isSafeInteger(arg0);
575
652
  return ret;
576
653
  },
654
+ __wbg_iterator_22ddeb808cf55a6f: function() {
655
+ const ret = Symbol.iterator;
656
+ return ret;
657
+ },
577
658
  __wbg_keys_6efc298980178da1: function(arg0) {
578
659
  const ret = Object.keys(arg0);
579
660
  return ret;
@@ -614,6 +695,14 @@ function __wbg_get_imports() {
614
695
  const ret = new Uint32Array(getArrayU32FromWasm0(arg0, arg1));
615
696
  return ret;
616
697
  },
698
+ __wbg_next_95053e306b1c3aed: function(arg0) {
699
+ const ret = arg0.next;
700
+ return ret;
701
+ },
702
+ __wbg_next_f31ecb8646d2c605: function() { return handleError(function (arg0) {
703
+ const ret = arg0.next();
704
+ return ret;
705
+ }, arguments); },
617
706
  __wbg_now_d1fb6650485d7f3e: function() {
618
707
  const ret = Date.now();
619
708
  return ret;
@@ -638,11 +727,25 @@ function __wbg_get_imports() {
638
727
  getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
639
728
  getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
640
729
  },
641
- __wbindgen_generic_0000000000000001: function(arg0, arg1) {
730
+ __wbg_value_c227f843d21da141: function(arg0) {
731
+ const ret = arg0.value;
732
+ return ret;
733
+ },
734
+ __wbindgen_generic_0000000000000001: function(arg0) {
735
+ // Cast intrinsic for `F64 -> Externref`.
736
+ const ret = arg0;
737
+ return ret;
738
+ },
739
+ __wbindgen_generic_0000000000000002: function(arg0, arg1) {
642
740
  // Cast intrinsic for `Ref(String) -> Externref`.
643
741
  const ret = getStringFromWasm0(arg0, arg1);
644
742
  return ret;
645
743
  },
744
+ __wbindgen_generic_0000000000000003: function(arg0) {
745
+ // Cast intrinsic for `U64 -> Externref`.
746
+ const ret = BigInt.asUintN(64, arg0);
747
+ return ret;
748
+ },
646
749
  __wbindgen_init_externref_table: function() {
647
750
  const table = wasm.__wbindgen_externrefs;
648
751
  const offset = table.grow(4);
package/vpin_bg.wasm CHANGED
Binary file