@ifc-lite/geometry 3.5.0 → 3.7.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.
Files changed (53) hide show
  1. package/dist/diagnostics.d.ts +20 -0
  2. package/dist/diagnostics.d.ts.map +1 -1
  3. package/dist/diagnostics.js +18 -0
  4. package/dist/diagnostics.js.map +1 -1
  5. package/dist/geometry-coordinate.d.ts.map +1 -1
  6. package/dist/geometry-coordinate.js +19 -34
  7. package/dist/geometry-coordinate.js.map +1 -1
  8. package/dist/geometry-fingerprints.d.ts +114 -0
  9. package/dist/geometry-fingerprints.d.ts.map +1 -0
  10. package/dist/geometry-fingerprints.js +114 -0
  11. package/dist/geometry-fingerprints.js.map +1 -0
  12. package/dist/geometry-native.d.ts +26 -3
  13. package/dist/geometry-native.d.ts.map +1 -1
  14. package/dist/geometry-native.js +82 -11
  15. package/dist/geometry-native.js.map +1 -1
  16. package/dist/geometry-parallel.d.ts +34 -0
  17. package/dist/geometry-parallel.d.ts.map +1 -1
  18. package/dist/geometry-parallel.js +132 -53
  19. package/dist/geometry-parallel.js.map +1 -1
  20. package/dist/geometry.worker.d.ts +19 -8
  21. package/dist/geometry.worker.d.ts.map +1 -1
  22. package/dist/geometry.worker.js +96 -61
  23. package/dist/geometry.worker.js.map +1 -1
  24. package/dist/ifc-lite-bridge.d.ts +2 -0
  25. package/dist/ifc-lite-bridge.d.ts.map +1 -1
  26. package/dist/ifc-lite-bridge.js +4 -0
  27. package/dist/ifc-lite-bridge.js.map +1 -1
  28. package/dist/index.d.ts +21 -0
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +40 -78
  31. package/dist/index.js.map +1 -1
  32. package/dist/native-bridge-conversion.d.ts.map +1 -1
  33. package/dist/native-bridge-conversion.js +42 -8
  34. package/dist/native-bridge-conversion.js.map +1 -1
  35. package/dist/packed-geometry-decoder.d.ts.map +1 -1
  36. package/dist/packed-geometry-decoder.js +17 -0
  37. package/dist/packed-geometry-decoder.js.map +1 -1
  38. package/dist/types.d.ts +67 -0
  39. package/dist/types.d.ts.map +1 -1
  40. package/dist/wasm-asset-error.d.ts.map +1 -1
  41. package/dist/wasm-asset-error.js +6 -2
  42. package/dist/wasm-asset-error.js.map +1 -1
  43. package/dist/wasm-instance-free.d.ts +12 -0
  44. package/dist/wasm-instance-free.d.ts.map +1 -0
  45. package/dist/wasm-instance-free.js +41 -0
  46. package/dist/wasm-instance-free.js.map +1 -0
  47. package/dist/wasm-runtime-trap.d.ts.map +1 -1
  48. package/dist/wasm-runtime-trap.js +5 -2
  49. package/dist/wasm-runtime-trap.js.map +1 -1
  50. package/dist/wasm-shared-module.d.ts.map +1 -1
  51. package/dist/wasm-shared-module.js +7 -1
  52. package/dist/wasm-shared-module.js.map +1 -1
  53. package/package.json +3 -3
@@ -49,8 +49,8 @@ export function enqueueNativeStreamingEvent(queuedEvents, event, queueState) {
49
49
  queueState.queuedMeshes += event.meshes.length;
50
50
  }
51
51
  /**
52
- * Shared native streaming generator used by both buffer-based and
53
- * path-based native geometry streaming.
52
+ * Shared native streaming generator used by every native geometry route:
53
+ * buffer-based (`processStreaming`), path-based and cache-based.
54
54
  *
55
55
  * @param startStream Callback that kicks off the native stream and
56
56
  * returns a promise resolving when it finishes.
@@ -58,8 +58,11 @@ export function enqueueNativeStreamingEvent(queuedEvents, event, queueState) {
58
58
  * @param coordinator CoordinateHandler for incremental bounds.
59
59
  * @param setLastNativeStats Callback to persist the latest stats on
60
60
  * the owning GeometryProcessor instance.
61
+ * @param options Per-route queue/coordinate behaviour; see NativeStreamOptions.
61
62
  */
62
- export async function* streamNativeGeometry(startStream, totalEstimate, coordinator, setLastNativeStats) {
63
+ export async function* streamNativeGeometry(startStream, totalEstimate, coordinator, setLastNativeStats, options = {}) {
64
+ const coalesce = options.coalesce !== false;
65
+ const processMeshes = options.processMeshes ?? ((meshes) => coordinator.processTrustedMeshesIncremental(meshes));
63
66
  coordinator.reset();
64
67
  yield { type: 'start', totalEstimate };
65
68
  await yieldToEventLoop();
@@ -78,13 +81,21 @@ export async function* streamNativeGeometry(startStream, totalEstimate, coordina
78
81
  resolvePending = null;
79
82
  }
80
83
  };
84
+ const enqueue = (event) => {
85
+ if (coalesce) {
86
+ enqueueNativeStreamingEvent(queuedEvents, event, queueState);
87
+ }
88
+ else {
89
+ queuedEvents.push(event);
90
+ }
91
+ };
81
92
  const streamingPromise = startStream({
82
93
  onBatch: (batch) => {
83
- enqueueNativeStreamingEvent(queuedEvents, { type: 'batch', meshes: batch.meshes, nativeTelemetry: batch.nativeTelemetry }, queueState);
94
+ enqueue({ type: 'batch', meshes: batch.meshes, nativeTelemetry: batch.nativeTelemetry });
84
95
  wake();
85
96
  },
86
97
  onColorUpdate: (updates) => {
87
- enqueueNativeStreamingEvent(queuedEvents, { type: 'colorUpdate', updates: new Map(updates) }, queueState);
98
+ enqueue({ type: 'colorUpdate', updates: new Map(updates) });
88
99
  wake();
89
100
  },
90
101
  onComplete: (stats) => {
@@ -100,6 +111,35 @@ export async function* streamNativeGeometry(startStream, totalEstimate, coordina
100
111
  wake();
101
112
  },
102
113
  });
114
+ // A `startStream` rejection that never reached `onError` used to strand this
115
+ // generator: `completed` stays false, so the drain loop parks on the wake
116
+ // promise below and nothing ever resolves it — the load hangs forever and the
117
+ // failure surfaces only as an unhandled rejection. That is reachable today,
118
+ // because the bridge only routes throws through `onError` from inside its own
119
+ // try/catch: `NativeBridge.processGeometryStreamingPath` has none at all (the
120
+ // missing-cache-key throw, and every failure of the packed-shard stream it
121
+ // delegates to — including the Rust-reported `failed` status and the 60 s
122
+ // stall guard — reject straight out), and its siblings can still reject from
123
+ // the `init()` / `listen()` calls that precede their try. Treat a rejected
124
+ // stream promise as a stream error so the caller sees the real message.
125
+ //
126
+ // Only while the stream is still running, though. A rejection that arrives
127
+ // AFTER `onComplete`/`onError` has settled the stream is teardown fallout,
128
+ // not the load's outcome: `NativeBridge.processGeometryStreaming` runs its
129
+ // three `unlisten()` calls in a `finally`, which executes after `onComplete`,
130
+ // so a throwing `unlisten` rejects the promise of a load that fully
131
+ // succeeded. Failing it here would discard every mesh already delivered.
132
+ // Post-completion rejections are logged by the `finally` below instead.
133
+ void streamingPromise.catch((error) => {
134
+ if (completed)
135
+ return;
136
+ // `??=` rather than `=`: `onError` sets `streamError` and `completed`
137
+ // together, so the guard above already covers it, but this keeps the
138
+ // "never shadow a richer onError message" property local to the assignment.
139
+ streamError ??= error instanceof Error ? error : new Error(String(error));
140
+ completed = true;
141
+ wake();
142
+ });
103
143
  try {
104
144
  while (!completed || queuedEvents.length > 0) {
105
145
  let drainedEventCount = 0;
@@ -112,9 +152,7 @@ export async function* streamNativeGeometry(startStream, totalEstimate, coordina
112
152
  continue;
113
153
  }
114
154
  queueState.queuedMeshes = Math.max(0, queueState.queuedMeshes - event.meshes.length);
115
- // Native desktop streaming already produces site-local geometry, so
116
- // avoid the generic JS RTC/outlier scan on every streamed batch.
117
- coordinator.processTrustedMeshesIncremental(event.meshes);
155
+ processMeshes(event.meshes);
118
156
  totalMeshes += event.meshes.length;
119
157
  const coordinateInfo = coordinator.getCurrentCoordinateInfo();
120
158
  yield {
@@ -126,7 +164,7 @@ export async function* streamNativeGeometry(startStream, totalEstimate, coordina
126
164
  };
127
165
  drainedEventCount += 1;
128
166
  drainedMeshCount += event.meshes.length;
129
- if (queuedEvents.length > 0) {
167
+ if (coalesce && queuedEvents.length > 0) {
130
168
  const shouldYield = drainedEventCount >= MAX_NATIVE_STREAM_EVENTS_PER_TURN ||
131
169
  drainedMeshCount >= MAX_NATIVE_STREAM_MESHES_PER_TURN ||
132
170
  performance.now() - drainStartedAt >= MAX_NATIVE_STREAM_DRAIN_MS;
@@ -147,6 +185,14 @@ export async function* streamNativeGeometry(startStream, totalEstimate, coordina
147
185
  });
148
186
  }
149
187
  }
188
+ // The in-loop check above only runs while the loop still has a reason to
189
+ // spin. `onError` sets `completed` AND leaves the queue empty, so the wake
190
+ // it triggers falls straight out of the loop past that check — and this
191
+ // generator then reported `complete` for a stream that failed. Re-check on
192
+ // the way out so the error reaches the caller.
193
+ if (streamError) {
194
+ throw streamError;
195
+ }
150
196
  }
151
197
  finally {
152
198
  // Ensure the native stream and its Tauri listeners are torn down
@@ -155,10 +201,35 @@ export async function* streamNativeGeometry(startStream, totalEstimate, coordina
155
201
  try {
156
202
  await streamingPromise;
157
203
  }
158
- catch {
159
- /* cleanup safe to ignore */
204
+ catch (err) {
205
+ // Two ways to land here, neither of which the caller learns anything new
206
+ // from: the rejection arrived while the stream was still running, in which
207
+ // case the handler above already recorded it as `streamError` and the
208
+ // drain loop threw it — this is the same error a second time; or it
209
+ // arrived after the stream had already completed, in which case it is
210
+ // teardown fallout that must NOT retro-fail a finished load. Debug level,
211
+ // because this is the only place that kind is reported at all — a real
212
+ // failure reported through `onError` (rather than only this bare
213
+ // rejection) is not swallowed here: it sets `streamError` unconditionally
214
+ // and the recheck right after this `finally` still throws it below.
215
+ console.debug('[GeometryProcessor] native stream teardown rejected:', err);
160
216
  }
161
217
  }
218
+ // Defense in depth, matching the shape of the two exit-guard checks above:
219
+ // `onError` is never gated on `completed` — a bridge that reports a genuine
220
+ // failure must win regardless of when that report arrives — so it can still
221
+ // fire after both of those checks already ran clean (streamError was null
222
+ // at both), while this generator sits in the `finally` above awaiting
223
+ // `streamingPromise`. Nothing rechecked `streamError` after that point, so
224
+ // a failure signalled that late was recorded and then never read: the
225
+ // caller got `complete` for a stream that, per its own `onError` call,
226
+ // failed. This does NOT reopen the post-complete teardown case just above —
227
+ // a rejection that only ever reaches the detached `.catch()` (never
228
+ // `onError`) is still gated on `!completed` there and leaves `streamError`
229
+ // null, so that case still falls through to `complete` unchanged.
230
+ if (streamError) {
231
+ throw streamError;
232
+ }
162
233
  if (queueState.coalescedBatchCount > 0) {
163
234
  console.info(`[GeometryProcessor] Coalesced ${queueState.coalescedBatchCount} native batches while JS drained the queue`);
164
235
  }
@@ -1 +1 @@
1
- {"version":3,"file":"geometry-native.js","sourceRoot":"","sources":["../src/geometry-native.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAgB/D,+BAA+B;AAE/B,MAAM,CAAC,MAAM,8BAA8B,GAAG,CAAC,CAAC;AAChD,MAAM,CAAC,MAAM,8BAA8B,GAAG,KAAK,CAAC;AACpD,MAAM,CAAC,MAAM,iCAAiC,GAAG,CAAC,CAAC;AACnD,MAAM,CAAC,MAAM,iCAAiC,GAAG,IAAI,CAAC;AACtD,MAAM,CAAC,MAAM,0BAA0B,GAAG,EAAE,CAAC;AAQ7C,gBAAgB;AAEhB,MAAM,UAAU,gBAAgB;IAC9B,MAAM,cAAc,GAAI,UAEtB,CAAC,SAAS,CAAC;IACb,IAAI,OAAO,cAAc,EAAE,KAAK,KAAK,UAAU,EAAE,CAAC;QAChD,OAAO,cAAc,CAAC,KAAK,EAAE,CAAC;IAChC,CAAC;IACD,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;QACnC,UAAU,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,2BAA2B,CACzC,YAA0C,EAC1C,KAAiC,EACjC,UAAiE;IAEjE,IAAI,KAAK,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;QACjC,MAAM,SAAS,GAAG,YAAY,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACxD,IAAI,SAAS,EAAE,IAAI,KAAK,aAAa,EAAE,CAAC;YACtC,KAAK,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;gBAC/C,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;YAC1C,CAAC;YACD,OAAO;QACT,CAAC;QACD,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACzB,OAAO;IACT,CAAC;IAED,MAAM,SAAS,GAAG,YAAY,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACxD,MAAM,cAAc,GAClB,SAAS,EAAE,IAAI,KAAK,OAAO;QAC3B,CAAC,YAAY,CAAC,MAAM,IAAI,8BAA8B,IAAI,UAAU,CAAC,YAAY,IAAI,8BAA8B,CAAC,CAAC;IAEvH,IAAI,cAAc,EAAE,CAAC;QACnB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC7C,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QACzC,CAAC;QACD,SAAS,CAAC,eAAe,GAAG,KAAK,CAAC,eAAe,CAAC;QAClD,UAAU,CAAC,mBAAmB,IAAI,CAAC,CAAC;IACtC,CAAC;SAAM,CAAC;QACN,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC;IAED,UAAU,CAAC,YAAY,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC;AACjD,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,SAAS,CAAC,CAAC,oBAAoB,CACzC,WAKoC,EACpC,aAAqB,EACrB,WAA8B,EAC9B,kBAA0D;IAE1D,WAAW,CAAC,KAAK,EAAE,CAAC;IAEpB,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,aAAa,EAAE,CAAC;IACvC,MAAM,gBAAgB,EAAE,CAAC;IACzB,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;IAEzC,MAAM,YAAY,GAAiC,EAAE,CAAC;IACtD,MAAM,UAAU,GAAG,EAAE,YAAY,EAAE,CAAC,EAAE,mBAAmB,EAAE,CAAC,EAAE,CAAC;IAC/D,IAAI,cAAc,GAAwB,IAAI,CAAC;IAC/C,IAAI,SAAS,GAAG,KAAK,CAAC;IACtB,IAAI,WAAW,GAAiB,IAAI,CAAC;IACrC,IAAI,oBAAwC,CAAC;IAC7C,IAAI,oBAAqD,CAAC;IAC1D,IAAI,WAAW,GAAG,CAAC,CAAC;IAEpB,MAAM,IAAI,GAAG,GAAG,EAAE;QAChB,IAAI,cAAc,EAAE,CAAC;YACnB,cAAc,EAAE,CAAC;YACjB,cAAc,GAAG,IAAI,CAAC;QACxB,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,gBAAgB,GAAG,WAAW,CAAC;QACnC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;YACjB,2BAA2B,CACzB,YAAY,EACZ,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,eAAe,EAAE,KAAK,CAAC,eAAe,EAAE,EAC/E,UAAU,CACX,CAAC;YACF,IAAI,EAAE,CAAC;QACT,CAAC;QACD,aAAa,EAAE,CAAC,OAAO,EAAE,EAAE;YACzB,2BAA2B,CAAC,YAAY,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,IAAI,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;YAC1G,IAAI,EAAE,CAAC;QACT,CAAC;QACD,UAAU,EAAE,CAAC,KAAK,EAAE,EAAE;YACpB,kBAAkB,CAAC,KAAK,CAAC,CAAC;YAC1B,oBAAoB,GAAG,KAAK,CAAC,WAAW,CAAC;YACzC,oBAAoB,GAAG,KAAK,CAAC,WAAW,CAAC;YACzC,SAAS,GAAG,IAAI,CAAC;YACjB,IAAI,EAAE,CAAC;QACT,CAAC;QACD,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;YACjB,WAAW,GAAG,KAAK,CAAC;YACpB,SAAS,GAAG,IAAI,CAAC;YACjB,IAAI,EAAE,CAAC;QACT,CAAC;KACF,CAAC,CAAC;IAEH,IAAI,CAAC;QACH,OAAO,CAAC,SAAS,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7C,IAAI,iBAAiB,GAAG,CAAC,CAAC;YAC1B,IAAI,gBAAgB,GAAG,CAAC,CAAC;YACzB,IAAI,cAAc,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;YACvC,OAAO,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC/B,MAAM,KAAK,GAAG,YAAY,CAAC,KAAK,EAAG,CAAC;gBACpC,IAAI,KAAK,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;oBACjC,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;oBACtD,SAAS;gBACX,CAAC;gBAED,UAAU,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,CAAC,YAAY,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;gBACrF,oEAAoE;gBACpE,iEAAiE;gBACjE,WAAW,CAAC,+BAA+B,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;gBAC1D,WAAW,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC;gBACnC,MAAM,cAAc,GAAG,WAAW,CAAC,wBAAwB,EAAE,CAAC;gBAC9D,MAAM;oBACJ,IAAI,EAAE,OAAO;oBACb,MAAM,EAAE,KAAK,CAAC,MAAM;oBACpB,UAAU,EAAE,WAAW;oBACvB,cAAc,EAAE,cAAc,IAAI,SAAS;oBAC3C,eAAe,EAAE,KAAK,CAAC,eAAe;iBACvC,CAAC;gBACF,iBAAiB,IAAI,CAAC,CAAC;gBACvB,gBAAgB,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC;gBAExC,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC5B,MAAM,WAAW,GACf,iBAAiB,IAAI,iCAAiC;wBACtD,gBAAgB,IAAI,iCAAiC;wBACrD,WAAW,CAAC,GAAG,EAAE,GAAG,cAAc,IAAI,0BAA0B,CAAC;oBACnE,IAAI,WAAW,EAAE,CAAC;wBAChB,MAAM,gBAAgB,EAAE,CAAC;wBACzB,iBAAiB,GAAG,CAAC,CAAC;wBACtB,gBAAgB,GAAG,CAAC,CAAC;wBACrB,cAAc,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;oBACrC,CAAC;gBACH,CAAC;YACH,CAAC;YAED,IAAI,WAAW,EAAE,CAAC;gBAChB,MAAM,WAAW,CAAC;YACpB,CAAC;YAED,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;oBAClC,cAAc,GAAG,OAAO,CAAC;gBAC3B,CAAC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;YAAS,CAAC;QACT,iEAAiE;QACjE,sEAAsE;QACtE,4DAA4D;QAC5D,IAAI,CAAC;YACH,MAAM,gBAAgB,CAAC;QACzB,CAAC;QAAC,MAAM,CAAC;YACP,8BAA8B;QAChC,CAAC;IACH,CAAC;IAED,IAAI,UAAU,CAAC,mBAAmB,GAAG,CAAC,EAAE,CAAC;QACvC,OAAO,CAAC,IAAI,CACV,iCAAiC,UAAU,CAAC,mBAAmB,4CAA4C,CAC5G,CAAC;IACJ,CAAC;IAED,MAAM,cAAc,GAAG,WAAW,CAAC,sBAAsB,EAAE,CAAC;IAC5D,MAAM;QACJ,IAAI,EAAE,UAAU;QAChB,WAAW,EAAE,oBAAoB,IAAI,WAAW;QAChD,cAAc;QACd,2EAA2E;QAC3E,6EAA6E;QAC7E,GAAG,CAAC,oBAAoB,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,oBAAoB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACvE,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"geometry-native.js","sourceRoot":"","sources":["../src/geometry-native.ts"],"names":[],"mappings":"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"}
@@ -23,6 +23,40 @@ import type { CoordinateHandler } from './coordinate-handler.js';
23
23
  import type { TessellationQuality } from './types.js';
24
24
  import type { StreamingGeometryEvent } from './index.js';
25
25
  import type { BatchSizingConfig } from './batch-sizing.js';
26
+ /**
27
+ * Prepass class-byte layout, mirroring the `PREPASS_CLASS_*` definitions in
28
+ * `rust/processing/src/shard_classes.rs` (the source of truth — these are
29
+ * pinned to it by `prepass-class-spans.test.ts`).
30
+ *
31
+ * The producer packs a named code in the LOW bits and composes FLAG bits on
32
+ * top (`PREPASS_CLASS_FLAG_GEOMETRY_JOB` 0x80, `..._FLAG_TYPE_CANDIDATE`
33
+ * 0x40), so a consumer must mask before comparing — the Rust consumer does
34
+ * (`gpu_meshes/prepass_discovery.rs`), and so does {@link extractPrepassSpanLists}.
35
+ */
36
+ export declare const PREPASS_CLASS_CODE_MASK = 63;
37
+ /** `IFCSTYLEDITEM`. */
38
+ export declare const PREPASS_CLASS_STYLED_ITEM = 4;
39
+ /** `IFCINDEXEDCOLOURMAP`. */
40
+ export declare const PREPASS_CLASS_INDEXED_COLOUR_MAP = 5;
41
+ /** `IFCMATERIALDEFINITIONREPRESENTATION`. */
42
+ export declare const PREPASS_CLASS_MATERIAL_DEF_REPR = 6;
43
+ /** `IFCRELASSOCIATESMATERIAL`. */
44
+ export declare const PREPASS_CLASS_REL_ASSOCIATES_MATERIAL = 7;
45
+ /** `IFCRELVOIDSELEMENT`. */
46
+ export declare const PREPASS_CLASS_REL_VOIDS = 8;
47
+ /** `IFCRELFILLSELEMENT`. */
48
+ export declare const PREPASS_CLASS_REL_FILLS = 9;
49
+ /** `IFCRELAGGREGATES`. */
50
+ export declare const PREPASS_CLASS_REL_AGGREGATES = 10;
51
+ /**
52
+ * Build one `(id, start, length)` span list per host-consumed prepass class
53
+ * from the stitched shard columns, in FILE ORDER. Every comparison goes
54
+ * through {@link PREPASS_CLASS_CODE_MASK}, so a record that carries a flag bit
55
+ * alongside its named code still lands in its list instead of being dropped.
56
+ * Returns exact-size arrays (one entry per class in `HOST_SPAN_CLASSES`,
57
+ * empty when the file has none).
58
+ */
59
+ export declare function extractPrepassSpanLists(classes: Uint8Array, ids: Uint32Array, starts: Uint32Array, lengths: Uint32Array): Map<number, Uint32Array>;
26
60
  /**
27
61
  * Plan content-affinity routing for one chunk: assign each job (by index) to a
28
62
  * worker bucket so that every job sharing an affinity key lands on the SAME
@@ -1 +1 @@
1
- {"version":3,"file":"geometry-parallel.d.ts","sourceRoot":"","sources":["../src/geometry-parallel.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AACjE,OAAO,KAAK,EAAY,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAChE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAGzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAO3D;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,WAAW,EACrB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAChC,WAAW,EAAE,MAAM,GAClB;IAAE,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAc7C;AA6ID,MAAM,WAAW,sBAAsB;IACrC;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,CACd,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,WAAW,EACnB,OAAO,EAAE,WAAW,KACjB,IAAI,CAAC;IACV;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;;;;;OAMG;IACH,qBAAqB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC;;;;;OAKG;IACH,mBAAmB,CAAC,EAAE,mBAAmB,GAAG,IAAI,CAAC;IACjD;;;;;OAKG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,EAAE;QACT,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IACF;;;;;OAKG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC;IACzC;;;;;;;OAOG;IACH,gBAAgB,CAAC,EAAE;QAAE,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,gBAAgB,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAC5E;;;;;;;OAOG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,wBAAuB,eAAe,CACpC,MAAM,EAAE,UAAU,EAClB,WAAW,EAAE,iBAAiB,EAC9B,eAAe,CAAC,EAAE;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE;AACrD,gFAAgF;AAChF,WAAW,CAAC,EAAE,iBAAiB,EAC/B,OAAO,CAAC,EAAE,sBAAsB,GAC/B,cAAc,CAAC,sBAAsB,CAAC,CAivCxC"}
1
+ {"version":3,"file":"geometry-parallel.d.ts","sourceRoot":"","sources":["../src/geometry-parallel.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AACjE,OAAO,KAAK,EAAY,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAChE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAGzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAO3D;;;;;;;;;GASG;AACH,eAAO,MAAM,uBAAuB,KAAO,CAAC;AAC5C,uBAAuB;AACvB,eAAO,MAAM,yBAAyB,IAAI,CAAC;AAC3C,6BAA6B;AAC7B,eAAO,MAAM,gCAAgC,IAAI,CAAC;AAClD,6CAA6C;AAC7C,eAAO,MAAM,+BAA+B,IAAI,CAAC;AACjD,kCAAkC;AAClC,eAAO,MAAM,qCAAqC,IAAI,CAAC;AACvD,4BAA4B;AAC5B,eAAO,MAAM,uBAAuB,IAAI,CAAC;AACzC,4BAA4B;AAC5B,eAAO,MAAM,uBAAuB,IAAI,CAAC;AACzC,0BAA0B;AAC1B,eAAO,MAAM,4BAA4B,KAAK,CAAC;AAa/C;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,UAAU,EACnB,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,WAAW,EACnB,OAAO,EAAE,WAAW,GACnB,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAmB1B;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,WAAW,EACrB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAChC,WAAW,EAAE,MAAM,GAClB;IAAE,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAc7C;AAiKD,MAAM,WAAW,sBAAsB;IACrC;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,CACd,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,WAAW,EACnB,OAAO,EAAE,WAAW,KACjB,IAAI,CAAC;IACV;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;;;;;OAMG;IACH,qBAAqB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC;;;;;OAKG;IACH,mBAAmB,CAAC,EAAE,mBAAmB,GAAG,IAAI,CAAC;IACjD;;;;;OAKG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,EAAE;QACT,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IACF;;;;;OAKG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC;IACzC;;;;;;;OAOG;IACH,gBAAgB,CAAC,EAAE;QAAE,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,gBAAgB,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAC5E;;;;;;;OAOG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,wBAAuB,eAAe,CACpC,MAAM,EAAE,UAAU,EAClB,WAAW,EAAE,iBAAiB,EAC9B,eAAe,CAAC,EAAE;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE;AACrD,gFAAgF;AAChF,WAAW,CAAC,EAAE,iBAAiB,EAC/B,OAAO,CAAC,EAAE,sBAAsB,GAC/B,cAAc,CAAC,sBAAsB,CAAC,CAkwCxC"}
@@ -8,6 +8,73 @@ import { notifyIfWasmAssetUnavailable, notifyIfWorkerScriptUnavailable } from '.
8
8
  // `IfcLiteBridge.init()` path can reuse whatever this pool already compiled
9
9
  // (and vice versa) instead of fetching the same binary a second time.
10
10
  import { compileSharedWasmModule } from './wasm-shared-module.js';
11
+ /**
12
+ * Prepass class-byte layout, mirroring the `PREPASS_CLASS_*` definitions in
13
+ * `rust/processing/src/shard_classes.rs` (the source of truth — these are
14
+ * pinned to it by `prepass-class-spans.test.ts`).
15
+ *
16
+ * The producer packs a named code in the LOW bits and composes FLAG bits on
17
+ * top (`PREPASS_CLASS_FLAG_GEOMETRY_JOB` 0x80, `..._FLAG_TYPE_CANDIDATE`
18
+ * 0x40), so a consumer must mask before comparing — the Rust consumer does
19
+ * (`gpu_meshes/prepass_discovery.rs`), and so does {@link extractPrepassSpanLists}.
20
+ */
21
+ export const PREPASS_CLASS_CODE_MASK = 0x3f;
22
+ /** `IFCSTYLEDITEM`. */
23
+ export const PREPASS_CLASS_STYLED_ITEM = 4;
24
+ /** `IFCINDEXEDCOLOURMAP`. */
25
+ export const PREPASS_CLASS_INDEXED_COLOUR_MAP = 5;
26
+ /** `IFCMATERIALDEFINITIONREPRESENTATION`. */
27
+ export const PREPASS_CLASS_MATERIAL_DEF_REPR = 6;
28
+ /** `IFCRELASSOCIATESMATERIAL`. */
29
+ export const PREPASS_CLASS_REL_ASSOCIATES_MATERIAL = 7;
30
+ /** `IFCRELVOIDSELEMENT`. */
31
+ export const PREPASS_CLASS_REL_VOIDS = 8;
32
+ /** `IFCRELFILLSELEMENT`. */
33
+ export const PREPASS_CLASS_REL_FILLS = 9;
34
+ /** `IFCRELAGGREGATES`. */
35
+ export const PREPASS_CLASS_REL_AGGREGATES = 10;
36
+ /** The classes the host builds span lists for (every other code is ignored). */
37
+ const HOST_SPAN_CLASSES = [
38
+ PREPASS_CLASS_STYLED_ITEM,
39
+ PREPASS_CLASS_INDEXED_COLOUR_MAP,
40
+ PREPASS_CLASS_MATERIAL_DEF_REPR,
41
+ PREPASS_CLASS_REL_ASSOCIATES_MATERIAL,
42
+ PREPASS_CLASS_REL_VOIDS,
43
+ PREPASS_CLASS_REL_FILLS,
44
+ PREPASS_CLASS_REL_AGGREGATES,
45
+ ];
46
+ /**
47
+ * Build one `(id, start, length)` span list per host-consumed prepass class
48
+ * from the stitched shard columns, in FILE ORDER. Every comparison goes
49
+ * through {@link PREPASS_CLASS_CODE_MASK}, so a record that carries a flag bit
50
+ * alongside its named code still lands in its list instead of being dropped.
51
+ * Returns exact-size arrays (one entry per class in `HOST_SPAN_CLASSES`,
52
+ * empty when the file has none).
53
+ */
54
+ export function extractPrepassSpanLists(classes, ids, starts, lengths) {
55
+ // Sized by the code mask rather than by the highest class the host consumes:
56
+ // a masked code is always < 64, so a class added on the Rust side cannot
57
+ // write out of bounds here (typed arrays discard such writes silently).
58
+ const counts = new Uint32Array(PREPASS_CLASS_CODE_MASK + 1);
59
+ for (let i = 0; i < classes.length; i++)
60
+ counts[classes[i] & PREPASS_CLASS_CODE_MASK]++;
61
+ const slots = new Map();
62
+ for (const k of HOST_SPAN_CLASSES)
63
+ slots.set(k, { arr: new Uint32Array(counts[k] * 3), w: 0 });
64
+ for (let i = 0; i < classes.length; i++) {
65
+ const slot = slots.get(classes[i] & PREPASS_CLASS_CODE_MASK);
66
+ if (!slot)
67
+ continue;
68
+ slot.arr[slot.w] = ids[i];
69
+ slot.arr[slot.w + 1] = starts[i];
70
+ slot.arr[slot.w + 2] = lengths[i];
71
+ slot.w += 3;
72
+ }
73
+ const spans = new Map();
74
+ for (const [k, slot] of slots)
75
+ spans.set(k, slot.arr);
76
+ return spans;
77
+ }
11
78
  /**
12
79
  * Plan content-affinity routing for one chunk: assign each job (by index) to a
13
80
  * worker bucket so that every job sharing an affinity key lands on the SAME
@@ -70,6 +137,26 @@ function readShardScanFlag() {
70
137
  return false;
71
138
  return true;
72
139
  }
140
+ /**
141
+ * Terminate a pool worker on a teardown path that is already unwinding.
142
+ *
143
+ * `Worker.terminate()` is specified never to throw, and is a no-op on a worker
144
+ * that is already gone — so every one of these teardown calls is expected to
145
+ * succeed and a throw means something unexpected about the host, not a
146
+ * double-terminate. Worth one line; never worth failing a teardown that runs
147
+ * while a real error is on its way to the caller.
148
+ *
149
+ * Bounded by construction: each caller terminates the pool once and then
150
+ * throws, returns, or leaves the generator.
151
+ */
152
+ function terminateWorkerQuietly(worker, label) {
153
+ try {
154
+ worker.terminate();
155
+ }
156
+ catch (err) {
157
+ console.warn(`[stream] ${label} terminate failed:`, err);
158
+ }
159
+ }
73
160
  /**
74
161
  * SPIKE: stitch N speculative shard scans into the full entity index —
75
162
  * byte-identical to the single-threaded scan. Port of the native
@@ -354,6 +441,13 @@ existingSab, options) {
354
441
  // (no flat mesh carries them). Forward straight through to the consumer.
355
442
  const instancedGeometryHashIds = msg.instancedGeometryHashIds;
356
443
  const instancedGeometryHashValues = msg.instancedGeometryHashValues;
444
+ // #1891: the world boxes for those same ids, six values per id. Travels
445
+ // with the ids, never on its own — an aabb array without its id array
446
+ // indexes nothing.
447
+ const instancedGeometryAabbValues = msg.instancedGeometryAabbValues;
448
+ // #1993: and their proved volumes, one per id. Same rule as the boxes —
449
+ // it travels with the ids or not at all.
450
+ const instancedGeometryVolumeValues = msg.instancedGeometryVolumeValues;
357
451
  if (meshes.length > 0 ||
358
452
  (instancedShards && instancedShards.length > 0) ||
359
453
  (instancedGeometryHashIds && instancedGeometryHashIds.length > 0)) {
@@ -376,7 +470,12 @@ existingSab, options) {
376
470
  coordinateInfo: coordinateInfo || undefined,
377
471
  ...(instancedShards && instancedShards.length > 0 ? { instancedShards } : {}),
378
472
  ...(instancedGeometryHashIds && instancedGeometryHashIds.length > 0
379
- ? { instancedGeometryHashIds, instancedGeometryHashValues }
473
+ ? {
474
+ instancedGeometryHashIds,
475
+ instancedGeometryHashValues,
476
+ ...(instancedGeometryAabbValues ? { instancedGeometryAabbValues } : {}),
477
+ ...(instancedGeometryVolumeValues ? { instancedGeometryVolumeValues } : {}),
478
+ }
380
479
  : {}),
381
480
  });
382
481
  wake();
@@ -519,7 +618,23 @@ existingSab, options) {
519
618
  try {
520
619
  w.postMessage({ type: 'stream-end' });
521
620
  }
522
- catch { /* worker terminated already — safe to ignore */ }
621
+ catch (err) {
622
+ // A structured-clonable payload posted to a terminated worker is a
623
+ // no-op, not a throw — so this means the port is in a state we did
624
+ // not expect. That worker will never flush its tail: `complete` is
625
+ // posted ONLY from `emitSessionEnd` in geometry.worker.js, which
626
+ // fires ONLY in response to `stream-end`. The drain loop below waits
627
+ // for a `complete` from every worker (`workersCompleted >=
628
+ // workers.length`), so leaving this as a log would make the load
629
+ // hang forever instead of failing loudly — the same "swallowed
630
+ // failure" shape as the fixes already on this branch, just a stall
631
+ // instead of a false success. Surface it as a load error and
632
+ // terminate the unreachable worker so it isn't left dangling.
633
+ console.warn('[stream] stream-end postMessage failed; failing the load instead of hanging on that worker:', err);
634
+ workerError = workerError ?? new Error(`Geometry worker failed: stream-end could not be delivered (${err instanceof Error ? err.message : String(err)})`);
635
+ terminateWorkerQuietly(w, 'process worker');
636
+ wake();
637
+ }
523
638
  }
524
639
  };
525
640
  const sendStreamStartIfReady = () => {
@@ -777,35 +892,17 @@ existingSab, options) {
777
892
  // stitched columns, split into one contiguous slice per worker, and
778
893
  // resolve them in parallel while everyone waits on the pre-pass scan.
779
894
  const classes = stitched.classes;
780
- // Class codes (see Rust PREPASS_CLASS_*): 4 styled, 5 colour map,
781
- // 6 material def repr, 7 rel-associates-material, 8 voids, 9 fills,
782
- // 10 aggregates. Extract each list in FILE ORDER.
783
- const counts = new Uint32Array(11);
784
- for (let i = 0; i < classes.length; i++)
785
- counts[classes[i]]++;
786
- const kinds = [4, 5, 6, 7, 8, 9, 10];
787
- const spanLists = new Map();
788
- for (const k of kinds)
789
- spanLists.set(k, { arr: new Uint32Array(counts[k] * 3), w: 0 });
790
- for (let i = 0; i < classes.length; i++) {
791
- const slot = spanLists.get(classes[i]);
792
- if (!slot)
793
- continue;
794
- slot.arr[slot.w] = ids[i];
795
- slot.arr[slot.w + 1] = starts[i];
796
- slot.arr[slot.w + 2] = lengths[i];
797
- slot.w += 3;
798
- }
895
+ const spanLists = extractPrepassSpanLists(classes, ids, starts, lengths);
799
896
  supportSpans = {
800
- colourMapSpans: spanLists.get(5).arr,
801
- materialDefSpans: spanLists.get(6).arr,
802
- relMaterialSpans: spanLists.get(7).arr,
803
- voidSpans: spanLists.get(8).arr,
804
- fillsSpans: spanLists.get(9).arr,
805
- aggregateSpans: spanLists.get(10).arr,
897
+ colourMapSpans: spanLists.get(PREPASS_CLASS_INDEXED_COLOUR_MAP),
898
+ materialDefSpans: spanLists.get(PREPASS_CLASS_MATERIAL_DEF_REPR),
899
+ relMaterialSpans: spanLists.get(PREPASS_CLASS_REL_ASSOCIATES_MATERIAL),
900
+ voidSpans: spanLists.get(PREPASS_CLASS_REL_VOIDS),
901
+ fillsSpans: spanLists.get(PREPASS_CLASS_REL_FILLS),
902
+ aggregateSpans: spanLists.get(PREPASS_CLASS_REL_AGGREGATES),
806
903
  };
807
- const styledCount = counts[4];
808
- const styledSpans = spanLists.get(4).arr;
904
+ const styledSpans = spanLists.get(PREPASS_CLASS_STYLED_ITEM);
905
+ const styledCount = styledSpans.length / 3;
809
906
  // 2 slices per worker (round-robin): the tail is set by the SLOWEST
810
907
  // worker, and macOS occasionally schedules one onto a slow core — halving
811
908
  // the slice size halves the damage a slow core can do to the tail.
@@ -1276,23 +1373,14 @@ existingSab, options) {
1276
1373
  }
1277
1374
  if (workerError) {
1278
1375
  for (const w of workers) {
1279
- try {
1280
- w.terminate();
1281
- }
1282
- catch { /* cleanup — safe to ignore */ }
1283
- }
1284
- try {
1285
- prepassWorker.terminate();
1376
+ terminateWorkerQuietly(w, 'process worker');
1286
1377
  }
1287
- catch { /* cleanup — safe to ignore */ }
1378
+ terminateWorkerQuietly(prepassWorker, 'pre-pass worker');
1288
1379
  throw workerError;
1289
1380
  }
1290
1381
  if (prepassError) {
1291
1382
  for (const w of workers) {
1292
- try {
1293
- w.terminate();
1294
- }
1295
- catch { /* cleanup — safe to ignore */ }
1383
+ terminateWorkerQuietly(w, 'process worker');
1296
1384
  }
1297
1385
  throw prepassError;
1298
1386
  }
@@ -1303,10 +1391,7 @@ existingSab, options) {
1303
1391
  // explicit terminate to exit.
1304
1392
  if (prepassDone && !streamStartSentToWorkers && prepassJobsTotal === 0) {
1305
1393
  for (const w of workers) {
1306
- try {
1307
- w.terminate();
1308
- }
1309
- catch { /* cleanup — safe to ignore */ }
1394
+ terminateWorkerQuietly(w, 'process worker');
1310
1395
  }
1311
1396
  const coordinateInfo = coordinator.getFinalCoordinateInfo();
1312
1397
  yield { type: 'complete', totalMeshes: 0, coordinateInfo };
@@ -1341,15 +1426,9 @@ existingSab, options) {
1341
1426
  }
1342
1427
  finally {
1343
1428
  for (const w of workers) {
1344
- try {
1345
- w.terminate();
1346
- }
1347
- catch { /* cleanup — safe to ignore */ }
1348
- }
1349
- try {
1350
- prepassWorker.terminate();
1429
+ terminateWorkerQuietly(w, 'process worker');
1351
1430
  }
1352
- catch { /* cleanup — safe to ignore */ }
1431
+ terminateWorkerQuietly(prepassWorker, 'pre-pass worker');
1353
1432
  }
1354
1433
  }
1355
1434
  //# sourceMappingURL=geometry-parallel.js.map