@bldrs-ai/conway 1.549.1515 → 1.556.1524

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.
Files changed (39) hide show
  1. package/compiled/examples/browser-bundled.cjs +85 -2
  2. package/compiled/examples/cli-bundled.cjs +97 -3
  3. package/compiled/examples/cli-step-bundled.cjs +90 -4
  4. package/compiled/examples/validator-bundled.cjs +85 -2
  5. package/compiled/src/AP214E3_2010/ap214_command_line_main.js +4 -1
  6. package/compiled/src/AP214E3_2010/ap214_regression_main.js +101 -5
  7. package/compiled/src/core/retained_memory.d.ts +134 -0
  8. package/compiled/src/core/retained_memory.d.ts.map +1 -0
  9. package/compiled/src/core/retained_memory.js +144 -0
  10. package/compiled/src/core/retained_memory.test.d.ts +2 -0
  11. package/compiled/src/core/retained_memory.test.d.ts.map +1 -0
  12. package/compiled/src/core/retained_memory.test.js +178 -0
  13. package/compiled/src/core/wasm_heap.d.ts +5 -4
  14. package/compiled/src/core/wasm_heap.d.ts.map +1 -1
  15. package/compiled/src/core/wasm_heap.js +5 -4
  16. package/compiled/src/ifc/ifc_command_line_main.js +12 -0
  17. package/compiled/src/ifc/ifc_regression_batch_main.js +37 -1
  18. package/compiled/src/ifc/ifc_regression_main.js +180 -7
  19. package/compiled/src/loaders/conway_model_loader.d.ts.map +1 -1
  20. package/compiled/src/loaders/conway_model_loader.js +75 -0
  21. package/compiled/src/memory/memory.d.ts.map +1 -1
  22. package/compiled/src/memory/memory.js +25 -1
  23. package/compiled/src/memory/memory_stats.test.d.ts +2 -0
  24. package/compiled/src/memory/memory_stats.test.d.ts.map +1 -0
  25. package/compiled/src/memory/memory_stats.test.js +115 -0
  26. package/compiled/src/scripts/bless_perf_snapshot.test.js +58 -6
  27. package/compiled/src/scripts/perf_csv_quoting.test.js +214 -22
  28. package/compiled/src/statistics/statistics.d.ts +66 -0
  29. package/compiled/src/statistics/statistics.d.ts.map +1 -1
  30. package/compiled/src/statistics/statistics.js +118 -0
  31. package/compiled/src/statistics/statistics_retained_memory.test.d.ts +2 -0
  32. package/compiled/src/statistics/statistics_retained_memory.test.d.ts.map +1 -0
  33. package/compiled/src/statistics/statistics_retained_memory.test.js +96 -0
  34. package/compiled/src/statistics/statistics_wasm_heap.test.d.ts +2 -0
  35. package/compiled/src/statistics/statistics_wasm_heap.test.d.ts.map +1 -0
  36. package/compiled/src/statistics/statistics_wasm_heap.test.js +60 -0
  37. package/compiled/src/version/version.js +1 -1
  38. package/compiled/tsconfig.tsbuildinfo +1 -1
  39. package/package.json +1 -1
@@ -30,7 +30,7 @@ var import_node_process = require("node:process");
30
30
  var readline = __toESM(require("node:readline"), 1);
31
31
 
32
32
  // compiled/src/version/version.js
33
- var versionString = "Conway v1.549.1515";
33
+ var versionString = "Conway v1.556.1524";
34
34
 
35
35
  // compiled/dependencies/conway-geom/interface/conway_geometry.js
36
36
  var wasmType = "";
@@ -45,6 +45,10 @@ var BlendMode;
45
45
  })(BlendMode || (BlendMode = {}));
46
46
 
47
47
  // compiled/src/statistics/statistics.js
48
+ var RETAINED_MB_PRECISION = 3;
49
+ function formatRetained(value) {
50
+ return value !== void 0 ? `${value.toFixed(RETAINED_MB_PRECISION)} MB` : "N/A";
51
+ }
48
52
  var Statistics = class {
49
53
  // Getters and setters
50
54
  /**
@@ -145,6 +149,84 @@ var Statistics = class {
145
149
  setGeometryMemory(value) {
146
150
  this.geometryMemory = value;
147
151
  }
152
+ /**
153
+ * Wasm linear-memory high-water mark in MB, from wasmHeapByteLength.
154
+ *
155
+ * @return {number | undefined} - wasm heap high-water, or undefined
156
+ */
157
+ getWasmHeapPeak() {
158
+ return this.wasmHeapPeak;
159
+ }
160
+ /**
161
+ * The wasm heap only ever grows, so a single reading of it IS the peak —
162
+ * no sampling loop and no forced GC. It is a different quantity from
163
+ * geometryMemory, and by a wide margin: on MB-Khaya an 8 MB live geometry
164
+ * payload sits under an 85 MB wasm heap, the gap being allocator overhead,
165
+ * fragmentation and the intermediate buffers a boolean leaves behind (see
166
+ * src/ifc/geometry_residency.ts). Neither substitutes for the other.
167
+ *
168
+ * @param value - wasm heap high-water in MB
169
+ */
170
+ setWasmHeapPeak(value) {
171
+ this.wasmHeapPeak = value;
172
+ }
173
+ /**
174
+ * RSS still held after the model was torn down, over a settled pre-load
175
+ * baseline (conway#554).
176
+ *
177
+ * @return {number | undefined} - retained RSS in MB, or undefined where the
178
+ * settle could not run
179
+ */
180
+ getRetainedRss() {
181
+ return this.retainedRss;
182
+ }
183
+ /**
184
+ * Both samples behind this figure are settled (`gc(); await setImmediate();
185
+ * gc()`) and both sit outside the timed region, so recording it costs the
186
+ * timing columns nothing. Leave it undefined rather than passing an
187
+ * unsettled difference: that is GC-timing noise, and it would be read as a
188
+ * leak signal.
189
+ *
190
+ * @param value - retained RSS in MB, signed
191
+ */
192
+ setRetainedRss(value) {
193
+ this.retainedRss = value;
194
+ }
195
+ /**
196
+ * V8 live heap still held after teardown, over the settled pre-load
197
+ * baseline (conway#554).
198
+ *
199
+ * @return {number | undefined} - retained heapUsed in MB, or undefined
200
+ * where the settle could not run
201
+ */
202
+ getRetainedHeapUsed() {
203
+ return this.retainedHeapUsed;
204
+ }
205
+ /**
206
+ *
207
+ * @param value - retained heapUsed in MB, signed
208
+ */
209
+ setRetainedHeapUsed(value) {
210
+ this.retainedHeapUsed = value;
211
+ }
212
+ /**
213
+ * Off-heap bytes still held after teardown, over the settled pre-load
214
+ * baseline (conway#554). This is where a released source buffer or parse
215
+ * structure that is still pinned shows up; heapUsed cannot see them.
216
+ *
217
+ * @return {number | undefined} - retained external in MB, or undefined
218
+ * where the settle could not run
219
+ */
220
+ getRetainedExternal() {
221
+ return this.retainedExternal;
222
+ }
223
+ /**
224
+ *
225
+ * @param value - retained external in MB, signed
226
+ */
227
+ setRetainedExternal(value) {
228
+ this.retainedExternal = value;
229
+ }
148
230
  /**
149
231
  *
150
232
  * @return {string | undefined} - preprocessor version or undefined
@@ -276,9 +358,10 @@ var Statistics = class {
276
358
  versionStr = "Version not defined";
277
359
  }
278
360
  const products = this.productCount !== void 0 ? `Products: ${this.productCount}, ` : "";
361
+ const retained = `Retained RSS Delta: ${formatRetained(this.retainedRss)}, Retained Heap-Used Delta: ${formatRetained(this.retainedHeapUsed)}, Retained External Delta: ${formatRetained(this.retainedExternal)}, `;
279
362
  const breakdown = this.formatGeometryTypeCounts();
280
363
  const geometryTypes = breakdown !== void 0 ? `, Geometry Types: ${breakdown}` : "";
281
- return `[${dateString}]: Load Status: ${this.loadStatus}, Project Name: ${this.projectName}, Version: ${versionStr}, Conway Version: ${conwayVersionNumber}-${wasmType}, Parse Time: ${this.parseTime} ms, Geometry Time: ${this.geometryTime} ms, Total Time: ${this.totalTime} ms, Geometry Memory: ${this.geometryMemory?.toFixed(3)} MB, ` + products + `Memory Statistics: ${this.memoryStatistics}, Preprocessor Version: ${this.preprocessorVersion}, Originating System: ${this.originatingSystem}` + geometryTypes;
364
+ return `[${dateString}]: Load Status: ${this.loadStatus}, Project Name: ${this.projectName}, Version: ${versionStr}, Conway Version: ${conwayVersionNumber}-${wasmType}, Parse Time: ${this.parseTime} ms, Geometry Time: ${this.geometryTime} ms, Total Time: ${this.totalTime} ms, Geometry Memory: ${this.geometryMemory?.toFixed(3)} MB, WASM Heap High-Water: ${this.wasmHeapPeak?.toFixed(3)} MB, ` + retained + products + `Memory Statistics: ${this.memoryStatistics}, Preprocessor Version: ${this.preprocessorVersion}, Originating System: ${this.originatingSystem}` + geometryTypes;
282
365
  }
283
366
  };
284
367
 
@@ -14965,7 +14965,7 @@ ${t5.join("\n")}` : "";
14965
14965
  var import_process = require("process");
14966
14966
 
14967
14967
  // compiled/src/version/version.js
14968
- var versionString = "Conway v1.549.1515";
14968
+ var versionString = "Conway v1.556.1524";
14969
14969
 
14970
14970
  // compiled/dependencies/conway-geom/interface/conway_geometry.js
14971
14971
  function pThreadsAllowed() {
@@ -15719,6 +15719,10 @@ function toAlphaMode(wasmModule, blendMode) {
15719
15719
  }
15720
15720
 
15721
15721
  // compiled/src/statistics/statistics.js
15722
+ var RETAINED_MB_PRECISION = 3;
15723
+ function formatRetained(value) {
15724
+ return value !== void 0 ? `${value.toFixed(RETAINED_MB_PRECISION)} MB` : "N/A";
15725
+ }
15722
15726
  var Statistics = class {
15723
15727
  // Getters and setters
15724
15728
  /**
@@ -15819,6 +15823,84 @@ var Statistics = class {
15819
15823
  setGeometryMemory(value) {
15820
15824
  this.geometryMemory = value;
15821
15825
  }
15826
+ /**
15827
+ * Wasm linear-memory high-water mark in MB, from wasmHeapByteLength.
15828
+ *
15829
+ * @return {number | undefined} - wasm heap high-water, or undefined
15830
+ */
15831
+ getWasmHeapPeak() {
15832
+ return this.wasmHeapPeak;
15833
+ }
15834
+ /**
15835
+ * The wasm heap only ever grows, so a single reading of it IS the peak —
15836
+ * no sampling loop and no forced GC. It is a different quantity from
15837
+ * geometryMemory, and by a wide margin: on MB-Khaya an 8 MB live geometry
15838
+ * payload sits under an 85 MB wasm heap, the gap being allocator overhead,
15839
+ * fragmentation and the intermediate buffers a boolean leaves behind (see
15840
+ * src/ifc/geometry_residency.ts). Neither substitutes for the other.
15841
+ *
15842
+ * @param value - wasm heap high-water in MB
15843
+ */
15844
+ setWasmHeapPeak(value) {
15845
+ this.wasmHeapPeak = value;
15846
+ }
15847
+ /**
15848
+ * RSS still held after the model was torn down, over a settled pre-load
15849
+ * baseline (conway#554).
15850
+ *
15851
+ * @return {number | undefined} - retained RSS in MB, or undefined where the
15852
+ * settle could not run
15853
+ */
15854
+ getRetainedRss() {
15855
+ return this.retainedRss;
15856
+ }
15857
+ /**
15858
+ * Both samples behind this figure are settled (`gc(); await setImmediate();
15859
+ * gc()`) and both sit outside the timed region, so recording it costs the
15860
+ * timing columns nothing. Leave it undefined rather than passing an
15861
+ * unsettled difference: that is GC-timing noise, and it would be read as a
15862
+ * leak signal.
15863
+ *
15864
+ * @param value - retained RSS in MB, signed
15865
+ */
15866
+ setRetainedRss(value) {
15867
+ this.retainedRss = value;
15868
+ }
15869
+ /**
15870
+ * V8 live heap still held after teardown, over the settled pre-load
15871
+ * baseline (conway#554).
15872
+ *
15873
+ * @return {number | undefined} - retained heapUsed in MB, or undefined
15874
+ * where the settle could not run
15875
+ */
15876
+ getRetainedHeapUsed() {
15877
+ return this.retainedHeapUsed;
15878
+ }
15879
+ /**
15880
+ *
15881
+ * @param value - retained heapUsed in MB, signed
15882
+ */
15883
+ setRetainedHeapUsed(value) {
15884
+ this.retainedHeapUsed = value;
15885
+ }
15886
+ /**
15887
+ * Off-heap bytes still held after teardown, over the settled pre-load
15888
+ * baseline (conway#554). This is where a released source buffer or parse
15889
+ * structure that is still pinned shows up; heapUsed cannot see them.
15890
+ *
15891
+ * @return {number | undefined} - retained external in MB, or undefined
15892
+ * where the settle could not run
15893
+ */
15894
+ getRetainedExternal() {
15895
+ return this.retainedExternal;
15896
+ }
15897
+ /**
15898
+ *
15899
+ * @param value - retained external in MB, signed
15900
+ */
15901
+ setRetainedExternal(value) {
15902
+ this.retainedExternal = value;
15903
+ }
15822
15904
  /**
15823
15905
  *
15824
15906
  * @return {string | undefined} - preprocessor version or undefined
@@ -15950,9 +16032,10 @@ var Statistics = class {
15950
16032
  versionStr = "Version not defined";
15951
16033
  }
15952
16034
  const products = this.productCount !== void 0 ? `Products: ${this.productCount}, ` : "";
16035
+ const retained = `Retained RSS Delta: ${formatRetained(this.retainedRss)}, Retained Heap-Used Delta: ${formatRetained(this.retainedHeapUsed)}, Retained External Delta: ${formatRetained(this.retainedExternal)}, `;
15953
16036
  const breakdown = this.formatGeometryTypeCounts();
15954
16037
  const geometryTypes = breakdown !== void 0 ? `, Geometry Types: ${breakdown}` : "";
15955
- return `[${dateString}]: Load Status: ${this.loadStatus}, Project Name: ${this.projectName}, Version: ${versionStr}, Conway Version: ${conwayVersionNumber}-${wasmType}, Parse Time: ${this.parseTime} ms, Geometry Time: ${this.geometryTime} ms, Total Time: ${this.totalTime} ms, Geometry Memory: ${this.geometryMemory?.toFixed(3)} MB, ` + products + `Memory Statistics: ${this.memoryStatistics}, Preprocessor Version: ${this.preprocessorVersion}, Originating System: ${this.originatingSystem}` + geometryTypes;
16038
+ return `[${dateString}]: Load Status: ${this.loadStatus}, Project Name: ${this.projectName}, Version: ${versionStr}, Conway Version: ${conwayVersionNumber}-${wasmType}, Parse Time: ${this.parseTime} ms, Geometry Time: ${this.geometryTime} ms, Total Time: ${this.totalTime} ms, Geometry Memory: ${this.geometryMemory?.toFixed(3)} MB, WASM Heap High-Water: ${this.wasmHeapPeak?.toFixed(3)} MB, ` + retained + products + `Memory Statistics: ${this.memoryStatistics}, Preprocessor Version: ${this.preprocessorVersion}, Originating System: ${this.originatingSystem}` + geometryTypes;
15956
16039
  }
15957
16040
  };
15958
16041
 
@@ -16324,7 +16407,10 @@ var Memory = class {
16324
16407
  const rss = (memoryUsage.rss / 1024 / 1024).toFixed(3);
16325
16408
  const heapTotal = (memoryUsage.heapTotal / 1024 / 1024).toFixed(3);
16326
16409
  const heapUsed = (memoryUsage.heapUsed / 1024 / 1024).toFixed(3);
16327
- return `Node Memory Usage: RSS ${rss} MB, Heap Total: ${heapTotal} MB, Heap Used: ${heapUsed} MB`;
16410
+ const external = (memoryUsage.external / 1024 / 1024).toFixed(3);
16411
+ const arrayBuffers = (memoryUsage.arrayBuffers / 1024 / 1024).toFixed(3);
16412
+ const peakRss = (process.resourceUsage().maxRSS / 1024).toFixed(3);
16413
+ return `Node Memory Usage: RSS ${rss} MB, Heap Total: ${heapTotal} MB, Heap Used: ${heapUsed} MB, Peak RSS: ${peakRss} MB, External: ${external} MB, ArrayBuffers: ${arrayBuffers} MB`;
16328
16414
  }
16329
16415
  };
16330
16416
 
@@ -27012,6 +27098,10 @@ function wasmHeapView(wasmModule, arrayType, pointer, elementCount) {
27012
27098
  const numBytes = elementCount * arrayType.BYTES_PER_ELEMENT;
27013
27099
  return new arrayType(reconcileHeapBuffer(wasmModule, address, numBytes), address, elementCount);
27014
27100
  }
27101
+ function wasmHeapByteLength(wasmModule) {
27102
+ refreshHeapViews(wasmModule);
27103
+ return currentHeapBuffer(wasmModule)?.byteLength ?? 0;
27104
+ }
27015
27105
  function arrayToWasmHeap(wasmModule, array) {
27016
27106
  const numBytes = array.length * array.BYTES_PER_ELEMENT;
27017
27107
  const arrayPtr = wasmModule._malloc(numBytes) >>> 0;
@@ -95450,6 +95540,10 @@ function geometryExtraction(model, limitCSGDepth = true, maxCSGDepth = 20, onPro
95450
95540
  const ONE_KB = 1024;
95451
95541
  const ONE_MB = ONE_KB * ONE_KB;
95452
95542
  statistics?.setGeometryMemory(conwayModel.model.geometry.calculateGeometrySize() / ONE_MB);
95543
+ const wasmModule = conwaywasm.wasmModule;
95544
+ if (wasmModule !== void 0) {
95545
+ statistics?.setWasmHeapPeak(wasmHeapByteLength(wasmModule) / ONE_MB);
95546
+ }
95453
95547
  const ifcProjectName = conwayModel.getIfcProjectName();
95454
95548
  if (ifcProjectName !== null) {
95455
95549
  statistics?.setProjectName(ifcProjectName);
@@ -15943,7 +15943,7 @@ var ParsingBuffer = class {
15943
15943
  };
15944
15944
 
15945
15945
  // compiled/src/version/version.js
15946
- var versionString = "Conway v1.549.1515";
15946
+ var versionString = "Conway v1.556.1524";
15947
15947
 
15948
15948
  // compiled/dependencies/conway-geom/interface/conway_geometry.js
15949
15949
  function pThreadsAllowed() {
@@ -16697,6 +16697,10 @@ function toAlphaMode(wasmModule, blendMode) {
16697
16697
  }
16698
16698
 
16699
16699
  // compiled/src/statistics/statistics.js
16700
+ var RETAINED_MB_PRECISION = 3;
16701
+ function formatRetained(value) {
16702
+ return value !== void 0 ? `${value.toFixed(RETAINED_MB_PRECISION)} MB` : "N/A";
16703
+ }
16700
16704
  var Statistics = class {
16701
16705
  // Getters and setters
16702
16706
  /**
@@ -16797,6 +16801,84 @@ var Statistics = class {
16797
16801
  setGeometryMemory(value) {
16798
16802
  this.geometryMemory = value;
16799
16803
  }
16804
+ /**
16805
+ * Wasm linear-memory high-water mark in MB, from wasmHeapByteLength.
16806
+ *
16807
+ * @return {number | undefined} - wasm heap high-water, or undefined
16808
+ */
16809
+ getWasmHeapPeak() {
16810
+ return this.wasmHeapPeak;
16811
+ }
16812
+ /**
16813
+ * The wasm heap only ever grows, so a single reading of it IS the peak —
16814
+ * no sampling loop and no forced GC. It is a different quantity from
16815
+ * geometryMemory, and by a wide margin: on MB-Khaya an 8 MB live geometry
16816
+ * payload sits under an 85 MB wasm heap, the gap being allocator overhead,
16817
+ * fragmentation and the intermediate buffers a boolean leaves behind (see
16818
+ * src/ifc/geometry_residency.ts). Neither substitutes for the other.
16819
+ *
16820
+ * @param value - wasm heap high-water in MB
16821
+ */
16822
+ setWasmHeapPeak(value) {
16823
+ this.wasmHeapPeak = value;
16824
+ }
16825
+ /**
16826
+ * RSS still held after the model was torn down, over a settled pre-load
16827
+ * baseline (conway#554).
16828
+ *
16829
+ * @return {number | undefined} - retained RSS in MB, or undefined where the
16830
+ * settle could not run
16831
+ */
16832
+ getRetainedRss() {
16833
+ return this.retainedRss;
16834
+ }
16835
+ /**
16836
+ * Both samples behind this figure are settled (`gc(); await setImmediate();
16837
+ * gc()`) and both sit outside the timed region, so recording it costs the
16838
+ * timing columns nothing. Leave it undefined rather than passing an
16839
+ * unsettled difference: that is GC-timing noise, and it would be read as a
16840
+ * leak signal.
16841
+ *
16842
+ * @param value - retained RSS in MB, signed
16843
+ */
16844
+ setRetainedRss(value) {
16845
+ this.retainedRss = value;
16846
+ }
16847
+ /**
16848
+ * V8 live heap still held after teardown, over the settled pre-load
16849
+ * baseline (conway#554).
16850
+ *
16851
+ * @return {number | undefined} - retained heapUsed in MB, or undefined
16852
+ * where the settle could not run
16853
+ */
16854
+ getRetainedHeapUsed() {
16855
+ return this.retainedHeapUsed;
16856
+ }
16857
+ /**
16858
+ *
16859
+ * @param value - retained heapUsed in MB, signed
16860
+ */
16861
+ setRetainedHeapUsed(value) {
16862
+ this.retainedHeapUsed = value;
16863
+ }
16864
+ /**
16865
+ * Off-heap bytes still held after teardown, over the settled pre-load
16866
+ * baseline (conway#554). This is where a released source buffer or parse
16867
+ * structure that is still pinned shows up; heapUsed cannot see them.
16868
+ *
16869
+ * @return {number | undefined} - retained external in MB, or undefined
16870
+ * where the settle could not run
16871
+ */
16872
+ getRetainedExternal() {
16873
+ return this.retainedExternal;
16874
+ }
16875
+ /**
16876
+ *
16877
+ * @param value - retained external in MB, signed
16878
+ */
16879
+ setRetainedExternal(value) {
16880
+ this.retainedExternal = value;
16881
+ }
16800
16882
  /**
16801
16883
  *
16802
16884
  * @return {string | undefined} - preprocessor version or undefined
@@ -16928,9 +17010,10 @@ var Statistics = class {
16928
17010
  versionStr = "Version not defined";
16929
17011
  }
16930
17012
  const products = this.productCount !== void 0 ? `Products: ${this.productCount}, ` : "";
17013
+ const retained = `Retained RSS Delta: ${formatRetained(this.retainedRss)}, Retained Heap-Used Delta: ${formatRetained(this.retainedHeapUsed)}, Retained External Delta: ${formatRetained(this.retainedExternal)}, `;
16931
17014
  const breakdown = this.formatGeometryTypeCounts();
16932
17015
  const geometryTypes = breakdown !== void 0 ? `, Geometry Types: ${breakdown}` : "";
16933
- return `[${dateString}]: Load Status: ${this.loadStatus}, Project Name: ${this.projectName}, Version: ${versionStr}, Conway Version: ${conwayVersionNumber}-${wasmType}, Parse Time: ${this.parseTime} ms, Geometry Time: ${this.geometryTime} ms, Total Time: ${this.totalTime} ms, Geometry Memory: ${this.geometryMemory?.toFixed(3)} MB, ` + products + `Memory Statistics: ${this.memoryStatistics}, Preprocessor Version: ${this.preprocessorVersion}, Originating System: ${this.originatingSystem}` + geometryTypes;
17016
+ return `[${dateString}]: Load Status: ${this.loadStatus}, Project Name: ${this.projectName}, Version: ${versionStr}, Conway Version: ${conwayVersionNumber}-${wasmType}, Parse Time: ${this.parseTime} ms, Geometry Time: ${this.geometryTime} ms, Total Time: ${this.totalTime} ms, Geometry Memory: ${this.geometryMemory?.toFixed(3)} MB, WASM Heap High-Water: ${this.wasmHeapPeak?.toFixed(3)} MB, ` + retained + products + `Memory Statistics: ${this.memoryStatistics}, Preprocessor Version: ${this.preprocessorVersion}, Originating System: ${this.originatingSystem}` + geometryTypes;
16934
17017
  }
16935
17018
  };
16936
17019
 
@@ -17302,7 +17385,10 @@ var Memory = class {
17302
17385
  const rss = (memoryUsage.rss / 1024 / 1024).toFixed(3);
17303
17386
  const heapTotal = (memoryUsage.heapTotal / 1024 / 1024).toFixed(3);
17304
17387
  const heapUsed = (memoryUsage.heapUsed / 1024 / 1024).toFixed(3);
17305
- return `Node Memory Usage: RSS ${rss} MB, Heap Total: ${heapTotal} MB, Heap Used: ${heapUsed} MB`;
17388
+ const external = (memoryUsage.external / 1024 / 1024).toFixed(3);
17389
+ const arrayBuffers = (memoryUsage.arrayBuffers / 1024 / 1024).toFixed(3);
17390
+ const peakRss = (process.resourceUsage().maxRSS / 1024).toFixed(3);
17391
+ return `Node Memory Usage: RSS ${rss} MB, Heap Total: ${heapTotal} MB, Heap Used: ${heapUsed} MB, Peak RSS: ${peakRss} MB, External: ${external} MB, ArrayBuffers: ${arrayBuffers} MB`;
17306
17392
  }
17307
17393
  };
17308
17394
 
@@ -86173,7 +86259,7 @@ function geometryExtraction(model, limitCSGDepth = true, maxCSGDepth = 20) {
86173
86259
  const ONE_MB = ONE_KB * ONE_KB;
86174
86260
  const wasmModule = conwaywasm.wasmModule;
86175
86261
  if (wasmModule !== void 0) {
86176
- logger_default.info(`WASM heap high-water: ${(wasmHeapByteLength(wasmModule) / ONE_MB).toFixed(1)} MB`);
86262
+ statistics?.setWasmHeapPeak(wasmHeapByteLength(wasmModule) / ONE_MB);
86177
86263
  }
86178
86264
  statistics?.setGeometryMemory(conwayModel.model.geometry.calculateGeometrySize() / ONE_MB);
86179
86265
  model.invalidate(true);
@@ -944,7 +944,7 @@ var EntityTypesIfcCount = 909;
944
944
  var entity_types_ifc_gen_default = EntityTypesIfc;
945
945
 
946
946
  // compiled/src/version/version.js
947
- var versionString = "Conway v1.549.1515";
947
+ var versionString = "Conway v1.556.1524";
948
948
 
949
949
  // compiled/dependencies/conway-geom/interface/conway_geometry.js
950
950
  var wasmType = "";
@@ -959,6 +959,10 @@ var BlendMode;
959
959
  })(BlendMode || (BlendMode = {}));
960
960
 
961
961
  // compiled/src/statistics/statistics.js
962
+ var RETAINED_MB_PRECISION = 3;
963
+ function formatRetained(value) {
964
+ return value !== void 0 ? `${value.toFixed(RETAINED_MB_PRECISION)} MB` : "N/A";
965
+ }
962
966
  var Statistics = class {
963
967
  // Getters and setters
964
968
  /**
@@ -1059,6 +1063,84 @@ var Statistics = class {
1059
1063
  setGeometryMemory(value) {
1060
1064
  this.geometryMemory = value;
1061
1065
  }
1066
+ /**
1067
+ * Wasm linear-memory high-water mark in MB, from wasmHeapByteLength.
1068
+ *
1069
+ * @return {number | undefined} - wasm heap high-water, or undefined
1070
+ */
1071
+ getWasmHeapPeak() {
1072
+ return this.wasmHeapPeak;
1073
+ }
1074
+ /**
1075
+ * The wasm heap only ever grows, so a single reading of it IS the peak —
1076
+ * no sampling loop and no forced GC. It is a different quantity from
1077
+ * geometryMemory, and by a wide margin: on MB-Khaya an 8 MB live geometry
1078
+ * payload sits under an 85 MB wasm heap, the gap being allocator overhead,
1079
+ * fragmentation and the intermediate buffers a boolean leaves behind (see
1080
+ * src/ifc/geometry_residency.ts). Neither substitutes for the other.
1081
+ *
1082
+ * @param value - wasm heap high-water in MB
1083
+ */
1084
+ setWasmHeapPeak(value) {
1085
+ this.wasmHeapPeak = value;
1086
+ }
1087
+ /**
1088
+ * RSS still held after the model was torn down, over a settled pre-load
1089
+ * baseline (conway#554).
1090
+ *
1091
+ * @return {number | undefined} - retained RSS in MB, or undefined where the
1092
+ * settle could not run
1093
+ */
1094
+ getRetainedRss() {
1095
+ return this.retainedRss;
1096
+ }
1097
+ /**
1098
+ * Both samples behind this figure are settled (`gc(); await setImmediate();
1099
+ * gc()`) and both sit outside the timed region, so recording it costs the
1100
+ * timing columns nothing. Leave it undefined rather than passing an
1101
+ * unsettled difference: that is GC-timing noise, and it would be read as a
1102
+ * leak signal.
1103
+ *
1104
+ * @param value - retained RSS in MB, signed
1105
+ */
1106
+ setRetainedRss(value) {
1107
+ this.retainedRss = value;
1108
+ }
1109
+ /**
1110
+ * V8 live heap still held after teardown, over the settled pre-load
1111
+ * baseline (conway#554).
1112
+ *
1113
+ * @return {number | undefined} - retained heapUsed in MB, or undefined
1114
+ * where the settle could not run
1115
+ */
1116
+ getRetainedHeapUsed() {
1117
+ return this.retainedHeapUsed;
1118
+ }
1119
+ /**
1120
+ *
1121
+ * @param value - retained heapUsed in MB, signed
1122
+ */
1123
+ setRetainedHeapUsed(value) {
1124
+ this.retainedHeapUsed = value;
1125
+ }
1126
+ /**
1127
+ * Off-heap bytes still held after teardown, over the settled pre-load
1128
+ * baseline (conway#554). This is where a released source buffer or parse
1129
+ * structure that is still pinned shows up; heapUsed cannot see them.
1130
+ *
1131
+ * @return {number | undefined} - retained external in MB, or undefined
1132
+ * where the settle could not run
1133
+ */
1134
+ getRetainedExternal() {
1135
+ return this.retainedExternal;
1136
+ }
1137
+ /**
1138
+ *
1139
+ * @param value - retained external in MB, signed
1140
+ */
1141
+ setRetainedExternal(value) {
1142
+ this.retainedExternal = value;
1143
+ }
1062
1144
  /**
1063
1145
  *
1064
1146
  * @return {string | undefined} - preprocessor version or undefined
@@ -1190,9 +1272,10 @@ var Statistics = class {
1190
1272
  versionStr = "Version not defined";
1191
1273
  }
1192
1274
  const products = this.productCount !== void 0 ? `Products: ${this.productCount}, ` : "";
1275
+ const retained = `Retained RSS Delta: ${formatRetained(this.retainedRss)}, Retained Heap-Used Delta: ${formatRetained(this.retainedHeapUsed)}, Retained External Delta: ${formatRetained(this.retainedExternal)}, `;
1193
1276
  const breakdown = this.formatGeometryTypeCounts();
1194
1277
  const geometryTypes = breakdown !== void 0 ? `, Geometry Types: ${breakdown}` : "";
1195
- return `[${dateString}]: Load Status: ${this.loadStatus}, Project Name: ${this.projectName}, Version: ${versionStr}, Conway Version: ${conwayVersionNumber}-${wasmType}, Parse Time: ${this.parseTime} ms, Geometry Time: ${this.geometryTime} ms, Total Time: ${this.totalTime} ms, Geometry Memory: ${this.geometryMemory?.toFixed(3)} MB, ` + products + `Memory Statistics: ${this.memoryStatistics}, Preprocessor Version: ${this.preprocessorVersion}, Originating System: ${this.originatingSystem}` + geometryTypes;
1278
+ return `[${dateString}]: Load Status: ${this.loadStatus}, Project Name: ${this.projectName}, Version: ${versionStr}, Conway Version: ${conwayVersionNumber}-${wasmType}, Parse Time: ${this.parseTime} ms, Geometry Time: ${this.geometryTime} ms, Total Time: ${this.totalTime} ms, Geometry Memory: ${this.geometryMemory?.toFixed(3)} MB, WASM Heap High-Water: ${this.wasmHeapPeak?.toFixed(3)} MB, ` + retained + products + `Memory Statistics: ${this.memoryStatistics}, Preprocessor Version: ${this.preprocessorVersion}, Originating System: ${this.originatingSystem}` + geometryTypes;
1196
1279
  }
1197
1280
  };
1198
1281
 
@@ -405,12 +405,15 @@ function geometryExtraction(model, limitCSGDepth = true, maxCSGDepth = 20) {
405
405
  statistics?.setGeometryTime(executionTimeInMs);
406
406
  const ONE_KB = 1024;
407
407
  const ONE_MB = ONE_KB * ONE_KB;
408
+ // Recorded on the statistics rather than logged on its own line, so the one
409
+ // spelling of this number reaches the benchmark's `peakWasmHeapMb` column
410
+ // through the same load-status line as every other measurement (#552).
408
411
  // Measured through wasmHeapByteLength rather than HEAPU8.length: the
409
412
  // module's cached view can be a growth step behind the real heap (#485), and
410
413
  // a high-water figure that under-reports is worse than none.
411
414
  const wasmModule = conwaywasm.wasmModule;
412
415
  if (wasmModule !== void 0) {
413
- Logger.info(`WASM heap high-water: ${(wasmHeapByteLength(wasmModule) / ONE_MB).toFixed(1)} MB`);
416
+ statistics?.setWasmHeapPeak(wasmHeapByteLength(wasmModule) / ONE_MB);
414
417
  }
415
418
  statistics?.setGeometryMemory(conwayModel.model.geometry.calculateGeometrySize() / (ONE_MB));
416
419
  model.invalidate(true);