@bldrs-ai/conway 1.429.1291 → 1.431.1296

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 (27) hide show
  1. package/compiled/examples/browser-bundled.cjs +21 -2
  2. package/compiled/examples/cli-bundled.cjs +37 -3
  3. package/compiled/examples/cli-step-bundled.cjs +61 -21
  4. package/compiled/examples/validator-bundled.cjs +21 -2
  5. package/compiled/src/AP214E3_2010/ap214_geometry_extraction.d.ts.map +1 -1
  6. package/compiled/src/AP214E3_2010/ap214_geometry_extraction.js +83 -24
  7. package/compiled/src/compat/web-ifc/ifc_api.d.ts +10 -0
  8. package/compiled/src/compat/web-ifc/ifc_api.d.ts.map +1 -1
  9. package/compiled/src/compat/web-ifc/ifc_api.js +12 -0
  10. package/compiled/src/compat/web-ifc/ifc_api_model_passthrough.d.ts +2 -0
  11. package/compiled/src/compat/web-ifc/ifc_api_model_passthrough.d.ts.map +1 -1
  12. package/compiled/src/compat/web-ifc/ifc_api_preview_channel.test.js +104 -0
  13. package/compiled/src/compat/web-ifc/ifc_api_proxy_ap214.d.ts.map +1 -1
  14. package/compiled/src/compat/web-ifc/ifc_api_proxy_ap214.js +9 -1
  15. package/compiled/src/compat/web-ifc/ifc_api_proxy_ifc.d.ts.map +1 -1
  16. package/compiled/src/compat/web-ifc/ifc_api_proxy_ifc.js +9 -1
  17. package/compiled/src/compat/web-ifc/streamed_preview_channel.d.ts +47 -0
  18. package/compiled/src/compat/web-ifc/streamed_preview_channel.d.ts.map +1 -1
  19. package/compiled/src/compat/web-ifc/streamed_preview_channel.js +144 -16
  20. package/compiled/src/ifc/ifc_geometry_extraction.d.ts +9 -1
  21. package/compiled/src/ifc/ifc_geometry_extraction.d.ts.map +1 -1
  22. package/compiled/src/ifc/ifc_geometry_extraction.js +16 -1
  23. package/compiled/src/step/parsing/columnar_index.d.ts.map +1 -1
  24. package/compiled/src/step/parsing/columnar_index.js +40 -1
  25. package/compiled/src/version/version.js +1 -1
  26. package/compiled/tsconfig.tsbuildinfo +1 -1
  27. package/package.json +1 -1
@@ -182,4 +182,108 @@ describe("StreamedPreviewChannel", () => {
182
182
  api.CloseModel(classicID);
183
183
  api.CloseModel(deferredID);
184
184
  }, 240000);
185
+ test("a throwing prefix build retires the attempt, not the channel", () => {
186
+ // Mid-parse prefixes can be structurally incomplete and the adapter's
187
+ // generation build can THROW (AP214's assembly-tree prep does on
188
+ // dangling references — this killed the whole STEP preview). The
189
+ // channel must swallow the attempt and succeed on a later, larger
190
+ // prefix. The sink is complete here, so growth is simulated by
191
+ // inflating the reported record count past the retry gate.
192
+ const sink = buildSink();
193
+ const realRecords = sink.topLevelCount;
194
+ let reportedRecords = realRecords;
195
+ const growingSink = {
196
+ get topLevelCount() {
197
+ return reportedRecords;
198
+ },
199
+ snapshot: () => sink.snapshot(),
200
+ };
201
+ let buildAttempts = 0;
202
+ const inner = ifcPreviewAdapter();
203
+ const flakyAdapter = {
204
+ buildGeneration: (source, wasm, columns) => {
205
+ if (buildAttempts++ === 0) {
206
+ throw new Error("structurally incomplete prefix");
207
+ }
208
+ return inner.buildGeneration(source, wasm, columns);
209
+ },
210
+ };
211
+ const payloads = [];
212
+ const channel = new StreamedPreviewChannel(data, conwayGeometry, growingSink, flakyAdapter, true, (mesh) => payloads.push(mesh), void 0, void 0, 1);
213
+ // First drain: the build throws — no payloads, but the channel
214
+ // survives the attempt.
215
+ channel.drainForTest();
216
+ expect(buildAttempts).toBe(1);
217
+ expect(payloads.length).toBe(0);
218
+ // Same record count: the failure gate must hold the retry.
219
+ channel.drainForTest();
220
+ expect(buildAttempts).toBe(1);
221
+ // The index "grows" past the gate: the retry builds and drains fully.
222
+ reportedRecords = realRecords * 4;
223
+ channel.drainForTest();
224
+ expect(buildAttempts).toBe(2);
225
+ expect(payloads.length).toBeGreaterThan(0);
226
+ }, 240000);
227
+ test("retryEmptyUnits re-runs empty units on later generations", () => {
228
+ // AP214-style schema: the unit list is fixed up front but the
229
+ // geometry units reference arrives later in the file. The channel
230
+ // must re-run units that captured nothing against each richer
231
+ // generation, and stop retrying a unit once it captures.
232
+ const UNIT_COUNT = 3;
233
+ const runsPerGeneration = [];
234
+ let reportedRecords = 2048;
235
+ const fakeSink = {
236
+ get topLevelCount() {
237
+ return reportedRecords;
238
+ },
239
+ snapshot: () => ({}),
240
+ };
241
+ const disposed = [];
242
+ const makeGeneration = (generationIndex) => {
243
+ const runs = [];
244
+ runsPerGeneration.push(runs);
245
+ return {
246
+ // Empty scene: units "execute" but never capture, so no unit
247
+ // ever completes and every generation re-runs all of them.
248
+ scene: { *walk() { } },
249
+ unitCount: UNIT_COUNT,
250
+ linearScalingFactor: 1,
251
+ runUnits: (from) => {
252
+ runs.push(from);
253
+ return 1;
254
+ },
255
+ geometryExpressID: () => void 0,
256
+ recenter: false,
257
+ dispose: () => disposed.push(generationIndex),
258
+ };
259
+ };
260
+ let generationIndex = 0;
261
+ const adapter = {
262
+ retryEmptyUnits: true,
263
+ buildGeneration: () => makeGeneration(generationIndex++),
264
+ };
265
+ const channel = new StreamedPreviewChannel(data, conwayGeometry, fakeSink, adapter, false, () => { }, void 0, void 0, 1);
266
+ const forceTick = () => {
267
+ /* eslint-disable @typescript-eslint/no-explicit-any */
268
+ channel.lastInlineTick_ = 0;
269
+ channel.tickIntervalMs_ = 0;
270
+ /* eslint-enable @typescript-eslint/no-explicit-any */
271
+ channel.maybeTickInline();
272
+ };
273
+ // Generation 1: all units run once (none capture).
274
+ forceTick();
275
+ expect(runsPerGeneration[0]).toEqual([0, 1, 2]);
276
+ // Same record count: growth-gated, no rebuild, no re-runs.
277
+ forceTick();
278
+ expect(runsPerGeneration.length).toBe(1);
279
+ expect(runsPerGeneration[0]).toEqual([0, 1, 2]);
280
+ // Records double: a fresh generation re-runs every empty unit and
281
+ // the outgoing generation is disposed.
282
+ reportedRecords *= 4;
283
+ forceTick();
284
+ expect(runsPerGeneration.length).toBe(2);
285
+ expect(runsPerGeneration[1]).toEqual([0, 1, 2]);
286
+ expect(disposed).toContain(0);
287
+ channel.stop();
288
+ }, 240000);
185
289
  });
@@ -1 +1 @@
1
- {"version":3,"file":"ifc_api_proxy_ap214.d.ts","sourceRoot":"","sources":["../../../../src/compat/web-ifc/ifc_api_proxy_ap214.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ifc_api_proxy_ap214.d.ts","sourceRoot":"","sources":["../../../../src/compat/web-ifc/ifc_api_proxy_ap214.ts"],"names":[],"mappings":"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"}
@@ -338,9 +338,17 @@ export class IfcApiProxyAP214 {
338
338
  const previewChannel = deferGeometry && settings?.ON_PREVIEW_MESH !== void 0 ?
339
339
  new StreamedPreviewChannel(data, conwaywasm, sink, ap214PreviewAdapter(), settings.COORDINATE_TO_ORIGIN === true, settings.ON_PREVIEW_MESH) : void 0;
340
340
  previewChannel?.start();
341
+ // Channel ticks ride the parse's own progress callback (see
342
+ // maybeTickInline) — timer ticks alone starve under the parse's
343
+ // scheduler-priority yields in browsers.
344
+ const parseProgress = previewChannel !== void 0 ?
345
+ (cursorBytes) => {
346
+ parseTick?.(cursorBytes);
347
+ previewChannel.maybeTickInline();
348
+ } : parseTick;
341
349
  let result;
342
350
  try {
343
- ({ result } = await buildIndexStreamingAsync(new BufferByteSource(data), parser, STREAMED_PARSE_POOL_BYTES, void 0, sink, parseTick));
351
+ ({ result } = await buildIndexStreamingAsync(new BufferByteSource(data), parser, STREAMED_PARSE_POOL_BYTES, void 0, sink, parseProgress));
344
352
  }
345
353
  finally {
346
354
  previewChannel?.stop();
@@ -1 +1 @@
1
- {"version":3,"file":"ifc_api_proxy_ifc.d.ts","sourceRoot":"","sources":["../../../../src/compat/web-ifc/ifc_api_proxy_ifc.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ifc_api_proxy_ifc.d.ts","sourceRoot":"","sources":["../../../../src/compat/web-ifc/ifc_api_proxy_ifc.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,cAAc,EACf,MAAM,aAAa,CAAA;AAEpB,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAA;AAC7D,OAAO,YAAY,MAAM,0BAA0B,CAAA;AACnD,OAAO,EACL,QAAQ,EACR,WAAW,EACX,WAAW,EACX,cAAc,EACd,cAAc,EACd,WAAW,EACX,MAAM,EACP,MAAM,WAAW,CAAA;AAClB,OAAO,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAA;AACvE,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAA;AACpE,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAC1D,OAAO,KAAK,QAAQ,MAAM,WAAW,CAAA;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAiBhD,OAAO,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAA;AAE3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAA;AAmBzE;;;;;GAKG;AACH,UAAU,iBAAiB;IACzB,UAAU,EAAE,cAAc,CAAA;IAC1B,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;uEACmE;IACnE,yBAAyB,CAAC,EAAE,QAAQ,CAAC,IAAI,CAAA;IACzC,YAAY,EAAE,MAAM,CAAA;IACpB,UAAU,EAAE,UAAU,CAAA;IACtB,KAAK,EAAE,YAAY,CAAA;IACnB,KAAK,EAAE,eAAe,CAAA;IACtB,cAAc,EAAE,qBAAqB,CAAA;IACrC,gBAAgB,EAAE,MAAM,CAAA;CACzB;AAED;;GAEG;AACH,qBAAa,cAAe,YAAW,sBAAsB;aAuEvC,OAAO,EAAE,MAAM;IAE/B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC;IAxE9B,EAAE,CAAC,EAAE,GAAG,CAAY;IAEpB,KAAK,EACH;QAAC,YAAY;QACX,eAAe;QACf,GAAG,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE,QAAQ,CAAC,CAAC;QAC/C,GAAG,CAAC,MAAM,EAAE,CAAC,cAAc,EAAE,iBAAiB,EAAE,MAAM,EAAE,CAAC,CAAC;QAE1D,MAAM,CAAC,QAAQ,CAAC;QAAE,QAAQ,CAAC,IAAI;KAAC,CAAA;IACpC,UAAU,EAAE,cAAc,CAAA;IAE1B,yEAAyE;IACzE,OAAO,CAAC,eAAe,CAAuB;IAE9C,iEAAiE;IACjE,OAAO,CAAC,aAAa,CAAiB;IAEtC,sEAAsE;IACtE,OAAO,CAAC,eAAe,CAAC,CAAU;IAElC;;;;;;;OAOG;IACH,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAA4B;IAElE,sEAAsE;IACtE,OAAO,CAAC,aAAa,CAAI;IAEzB;;;;;;;;;OASG;IACH,OAAO,CAAC,mBAAmB,CAAC,CAAe;IAE3C,cAAc,EAAE,OAAO,CAAQ;IAC/B,mBAAmB,EAAE,MAAM,CAAI;IAC/B,QAAQ,EAAE,MAAM,EAAE,CAAmD;IAGrE,YAAY,EAAE,QAAQ,CAAC,IAAI,CAK1B;IAED;;OAEG;IACH,UAAU,gBAA0B;IAEpC;;;;OAIG;gBAGiB,OAAO,EAAE,MAAM,EAC/B,IAAI,EAAE,UAAU,EACC,UAAU,EAAE,GAAG,EACf,QAAQ,CAAC,EAAE,cAAc,YAAA,EAC1C,WAAW,CAAC,EAAE,iBAAiB;IAmKnC;;;;;;;;;;OAUG;WACiB,WAAW,CAC3B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,UAAU,EAChB,UAAU,EAAE,GAAG,EACf,QAAQ,CAAC,EAAE,cAAc,GAAI,OAAO,CAAC,cAAc,CAAC;IAQxD;;;;;;;;;;;;;;;OAeG;WACiB,cAAc,CAC9B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,UAAU,EAChB,UAAU,EAAE,GAAG,EACf,QAAQ,CAAC,EAAE,cAAc,GAAI,OAAO,CAAC,cAAc,CAAC;IAQxD;;;;;;;;;;;;;;;OAeG;WACiB,cAAc,CAC9B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,UAAU,EAChB,UAAU,EAAE,GAAG,EACf,QAAQ,CAAC,EAAE,cAAc,GAAI,OAAO,CAAC,cAAc,CAAC;IAQxD;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,CAAC,uBAAuB;IAwCtC;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,CAAC,WAAW;IAU1B;;;;;;;;OAQG;IACH,OAAO,CAAC,MAAM,CAAC,eAAe;IAsF9B;;;;;;;;;OASG;mBACkB,oBAAoB;IAsFzC;;;;;;;;;;;;;;;;;;;;;;OAsBG;mBACkB,4BAA4B;IAwJjD;;;;OAIG;IACH,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;IA4BxC;;;;;OAKG;IACH,WAAW,CAAC,QAAQ,CAAC,EAAE,cAAc,GAAG,MAAM;IAM9C;;;;OAIG;IACH,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU;IAO5C;;;;;;OAMG;IACH,WAAW,CAAC,iBAAiB,EAAE,MAAM,GAAG,WAAW;IA8BnD;;;;;;OAMG;IACH,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,GAAE,OAAe;IA0BnD;;;;;;;;;;;;OAYG;IACH,qBAAqB,CAAC,SAAS,EAAE,MAAM,GACrC;QAAE,IAAI,CAAC,EAAE,eAAe,CAAC;QACvB,QAAQ,CAAC,EAAE,eAAe,CAAC;QAC3B,QAAQ,CAAC,EAAE,eAAe,CAAA;KAAE;IAoChC;;;;;;OAMG;IACH,kBAAkB,IAAI,IAAI;IAI1B;;;;;OAKG;IACH,IAAI,gBAAgB,IAAI,OAAO,CAE9B;IAED;;;;;;;;;;OAUG;IACH,0BAA0B,CACtB,KAAK,EAAE,qBAAqB,EAC5B,UAAU,CAAC,EAAE,MAAM,EACnB,iBAAiB,CAAC,EAAE,MAAM,GAAI,IAAI;IAItC;;;;;;;;;;;OAWG;IACG,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI1D;;;;;;;;;;;OAWG;IACH,cAAc,IAAI,gBAAgB,CAAC,MAAM,CAAC;IAI1C;;;;OAIG;IACH,iBAAiB,IAAI,MAAM,CAAC,WAAW,CAAC;IAoBxC;;;;OAIG;IACH,SAAS,CAAC,UAAU,EAAE,GAAG;IAIzB;;;;OAIG;IACH,WAAW,CAAC,IAAI,EAAE,GAAG,GAAG,IAAI;IAkB5B;;;;;OAKG;IACH,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,WAAW;IAgD9C;;;;OAIG;IACH,gBAAgB,CAAC,IAAI,EAAE,WAAW;IAIlC;;;;;OAKG;IACH,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IA6ChD;;;;OAIG;IACH,WAAW,IAAI,MAAM,CAAC,MAAM,CAAC;IA0C7B;;;;OAIG;IACH,yBAAyB,CAAC,oBAAoB,EAAE,KAAK,CAAC,MAAM,CAAC;IAU7D;;;;OAIG;IACH,qBAAqB,IAAI,KAAK,CAAC,MAAM,CAAC;IActC;;;;;OAKG;IACH,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,YAAY;IAIvD;;;;;OAKG;IACH,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,WAAW;IAIrD;;;;;;OAMG;IACH,WAAW,CAAC,IAAI,EAAE,YAAY,GAAG,WAAW,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAC/E,YAAY,GAAG,WAAW;IAK5B;;;;OAIG;IACH,UAAU;IAIV;;;;;;;;;;;;;OAaG;IACH,eAAe,IAAI,OAAO;IAkC1B;0EACsE;IACtE,OAAO,CAAC,SAAS,CAAQ;IAEzB;;;;;;;;;;;;;;;;;OAiBG;IACH,oBAAoB,CAChB,SAAS,EAAE,MAAM,EACjB,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,IAAI,GAAI;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAC;IA6CrF;;;;;;;;;;;;;;;;;;;OAmBG;IACH,OAAO,CAAC,gBAAgB;IAoLxB;;;;OAIG;IACH,eAAe,CAAE,YAAY,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,IAAI;IAiQvD;;;;;OAKG;IACH,wBAAwB,CACpB,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,EACpB,YAAY,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,IAAI;IA+O1C;;;;OAIG;IACH,eAAe,IAAI,MAAM,CAAC,QAAQ,CAAC;IA0RnC;;;;;OAKG;IACH,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,QAAQ;IAqDxC;;;;;OAKG;IACH,4BAA4B,IAAI,IAAI;CAwBrC"}
@@ -472,9 +472,17 @@ export class IfcApiProxyIfc {
472
472
  const previewChannel = deferGeometry && settings?.ON_PREVIEW_MESH !== void 0 ?
473
473
  new StreamedPreviewChannel(data, conwaywasm, sink, ifcPreviewAdapter(), settings.COORDINATE_TO_ORIGIN === true, settings.ON_PREVIEW_MESH) : void 0;
474
474
  previewChannel?.start();
475
+ // Channel ticks ride the parse's own progress callback (see
476
+ // maybeTickInline) — timer ticks alone starve under the parse's
477
+ // scheduler-priority yields in browsers.
478
+ const parseProgress = previewChannel !== void 0 ?
479
+ (cursorBytes) => {
480
+ parseTick?.(cursorBytes);
481
+ previewChannel.maybeTickInline();
482
+ } : parseTick;
475
483
  let result;
476
484
  try {
477
- ({ result } = await buildIndexStreamingAsync(new BufferByteSource(data), parser, STREAMED_PARSE_POOL_BYTES, void 0, sink, parseTick));
485
+ ({ result } = await buildIndexStreamingAsync(new BufferByteSource(data), parser, STREAMED_PARSE_POOL_BYTES, void 0, sink, parseProgress));
478
486
  }
479
487
  finally {
480
488
  previewChannel?.stop();
@@ -72,6 +72,19 @@ export interface PreviewPrefixGeneration {
72
72
  * the preview channel that knows what a "model" or a "unit" is.
73
73
  */
74
74
  export interface PreviewSchemaAdapter {
75
+ /**
76
+ * Retry semantics for schemas whose unit list is FIXED up front while
77
+ * the geometry those units reference arrives throughout the file
78
+ * (AP214: the assembly tree sits at the head, solids follow). Without
79
+ * this, the first generation "consumes" every unit against a prefix
80
+ * that has no geometry yet and later, richer generations report no
81
+ * new units — the channel then never emits anything. With it, the
82
+ * channel re-runs units that emitted no instances against each new
83
+ * generation, and marks a unit done only once it captures something.
84
+ * Leave unset for schemas whose units keep appearing with the parse
85
+ * (IFC products) — re-running those would be quadratic for no gain.
86
+ */
87
+ readonly retryEmptyUnits?: boolean;
75
88
  /**
76
89
  * Build a generation over the given prefix columns.
77
90
  *
@@ -146,11 +159,21 @@ export declare class StreamedPreviewChannel {
146
159
  /** Ordinal cursor into the unit list (see the adapter's stability
147
160
  * notes). */
148
161
  private unitOrdinal_;
162
+ /** Retry mode (adapter.retryEmptyUnits): ordinals that captured ≥ 1
163
+ * instance — done for good, skipped on later generations. */
164
+ private readonly completedUnits_;
165
+ /** Retry mode: scan position within the CURRENT generation (resets to
166
+ * 0 on every new generation so empty units get re-run). */
167
+ private retryScan_;
149
168
  /** Geometry expressIDs whose payload has been emitted (cross-generation
150
169
  * dedup for mapped/shared geometry). */
151
170
  private readonly emittedGeometry_;
152
171
  private generation_?;
153
172
  private lastSnapshotRecords_;
173
+ /** Records at the last snapshot whose generation build THREW (a
174
+ * structurally incomplete prefix) — gates retries to index growth so a
175
+ * throwing prefix build can't hot-loop every tick. */
176
+ private lastFailedSnapshotRecords_;
154
177
  /**
155
178
  * @param data The (fully resident) source buffer the parse is indexing.
156
179
  * @param conwaywasm The shared geometry wasm wrapper (sequential use only
@@ -166,8 +189,20 @@ export declare class StreamedPreviewChannel {
166
189
  * snapshot (tests lower it for tiny fixtures).
167
190
  */
168
191
  constructor(data: Uint8Array, conwaywasm: ConwayGeometry, sink: ColumnarIndexSink<number>, adapter: PreviewSchemaAdapter, coordinateToOrigin: boolean, onMesh: (mesh: PreviewMeshPayload) => void, maxUnits?: number, maxBytes?: number, firstGenerationMinRecords?: number);
192
+ private lastInlineTick_;
193
+ private tickIntervalMs_;
169
194
  /** Begin ticking (call just before awaiting the parse). */
170
195
  start(): void;
196
+ /**
197
+ * Tick inline if one is due — called from the parse's own progress
198
+ * callback, so the channel keeps its cadence even when the event
199
+ * loop's timer queue is starved (browser: the cooperative parse
200
+ * yields via scheduler.yield / MessageChannel, whose continuations
201
+ * outrank setTimeout; the 150ms timer ticks barely ran on PSB-class
202
+ * parses, starving the preview until parse end). The timer remains
203
+ * as a fallback for gaps between progress calls.
204
+ */
205
+ maybeTickInline(): void;
171
206
  /**
172
207
  * Stop ticking (call once the parse settles, before finalize/fallback).
173
208
  * Idempotent; no tick runs after this returns (ticks are synchronous and
@@ -190,6 +225,15 @@ export declare class StreamedPreviewChannel {
190
225
  * @return {boolean} True when a generation with pending units exists.
191
226
  */
192
227
  private ensureGeneration_;
228
+ /**
229
+ * Does the given generation still have units this channel would run —
230
+ * retry mode: not-yet-captured ordinals ahead of the scan; classic
231
+ * mode: ordinals beyond the global forward-only cursor.
232
+ *
233
+ * @param generation The generation to check.
234
+ * @return {boolean} True when a tick can make progress on it.
235
+ */
236
+ private hasPendingUnits_;
193
237
  /**
194
238
  * Walk the current generation's scene and emit every not-yet-captured
195
239
  * placed instance as a payload — the preview twin of the durable delta
@@ -197,6 +241,9 @@ export declare class StreamedPreviewChannel {
197
241
  * for IFC, bare composition for AP214) so preview and durable
198
242
  * placements coincide, but copying geometry OUT of the wasm heap
199
243
  * instead of retaining native references.
244
+ *
245
+ * @return {number} Instances emitted by this pass (retry mode uses
246
+ * this to attribute unit completion).
200
247
  */
201
248
  private captureNewInstances_;
202
249
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"streamed_preview_channel.d.ts","sourceRoot":"","sources":["../../../../src/compat/web-ifc/streamed_preview_channel.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"streamed_preview_channel.d.ts","sourceRoot":"","sources":["../../../../src/compat/web-ifc/streamed_preview_channel.ts"],"names":[],"mappings":"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"}
@@ -4,10 +4,17 @@ import { IfcGeometryExtraction } from "../../ifc/ifc_geometry_extraction.js";
4
4
  import { IfcProduct } from "../../ifc/ifc4_gen/index.js";
5
5
  import AP214StepModel from "../../AP214E3_2010/ap214_step_model.js";
6
6
  import { AP214GeometryExtraction, } from "../../AP214E3_2010/ap214_geometry_extraction.js";
7
+ import { cursorIterator } from "../../indexing/cursor_utilities.js";
7
8
  import * as glmatrix from "gl-matrix";
8
9
  /* eslint-disable no-magic-numbers */
9
- /** Ms between preview pump ticks (interleaves with the parse's yields). */
10
+ /** Initial ms between preview pump ticks (interleaves with the parse's
11
+ * yields). The interval decays (TICK_INTERVAL_GROWTH per tick, capped at
12
+ * TICK_INTERVAL_MAX_MS): dense ticking in the first seconds delivers the
13
+ * immediate-feedback wow, then the channel backs off so a long parse
14
+ * isn't taxed all the way through. */
10
15
  const TICK_INTERVAL_MS = 150;
16
+ const TICK_INTERVAL_MAX_MS = 600;
17
+ const TICK_INTERVAL_GROWTH = 1.1;
11
18
  /** Extraction + capture time budget per tick, so the parse keeps most of
12
19
  * the main thread (~25/150 ≈ 17% worst-case preview share). */
13
20
  const TICK_BUDGET_MS = 25;
@@ -16,7 +23,7 @@ const TICK_BUDGET_MS = 25;
16
23
  const FIRST_GENERATION_MIN_RECORDS = 1024;
17
24
  /** A new generation only when the index grew this much past the previous
18
25
  * snapshot (bounds snapshot copies to O(GROWTH/(GROWTH-1)) of the file). */
19
- const GENERATION_GROWTH_FACTOR = 1.5;
26
+ const GENERATION_GROWTH_FACTOR = 2;
20
27
  /** Default cap on units the preview channel ever extracts. Preview
21
28
  * generations are throwaway extractions whose native geometry is not
22
29
  * reclaimed until page teardown (the shim never frees classic scenes
@@ -39,14 +46,20 @@ export function ifcPreviewAdapter() {
39
46
  return {
40
47
  buildGeneration(data, conwaywasm, columns) {
41
48
  const model = new IfcStepModel(data, columns);
49
+ // Enumerate product localIDs straight off the type index — NO
50
+ // entity materialization (a per-generation sweep of 50k+ product
51
+ // entities was a dominant channel cost on PSB-class models).
42
52
  const products = [];
43
- for (const product of model.types(IfcProduct)) {
44
- products.push(product.localID);
53
+ for (const localID of cursorIterator(model.typeIndex.cursor(...IfcProduct.query))) {
54
+ products.push(localID);
45
55
  }
46
56
  if (products.length === 0) {
47
57
  return void 0;
48
58
  }
49
59
  const extraction = new IfcGeometryExtraction(conwaywasm, model);
60
+ // Preview-only preparation: skip the relationship sweeps whose
61
+ // entity materialization dominates per-generation cost.
62
+ extraction.prepareDemandExtraction(true);
50
63
  return {
51
64
  scene: extraction.scene,
52
65
  unitCount: products.length,
@@ -113,6 +126,7 @@ function releaseModelGeometry(geometry) {
113
126
  */
114
127
  export function ap214PreviewAdapter() {
115
128
  return {
129
+ retryEmptyUnits: true,
116
130
  buildGeneration(data, conwaywasm, columns) {
117
131
  const model = new AP214StepModel(data, columns);
118
132
  const extraction = new AP214GeometryExtraction(conwaywasm, model);
@@ -194,15 +208,55 @@ export class StreamedPreviewChannel {
194
208
  /** Ordinal cursor into the unit list (see the adapter's stability
195
209
  * notes). */
196
210
  this.unitOrdinal_ = 0;
211
+ /** Retry mode (adapter.retryEmptyUnits): ordinals that captured ≥ 1
212
+ * instance — done for good, skipped on later generations. */
213
+ this.completedUnits_ = new Set();
214
+ /** Retry mode: scan position within the CURRENT generation (resets to
215
+ * 0 on every new generation so empty units get re-run). */
216
+ this.retryScan_ = 0;
197
217
  /** Geometry expressIDs whose payload has been emitted (cross-generation
198
218
  * dedup for mapped/shared geometry). */
199
219
  this.emittedGeometry_ = new Set();
200
220
  this.lastSnapshotRecords_ = 0;
221
+ /** Records at the last snapshot whose generation build THREW (a
222
+ * structurally incomplete prefix) — gates retries to index growth so a
223
+ * throwing prefix build can't hot-loop every tick. */
224
+ this.lastFailedSnapshotRecords_ = 0;
225
+ this.lastInlineTick_ = 0;
226
+ this.tickIntervalMs_ = TICK_INTERVAL_MS;
201
227
  }
202
228
  /** Begin ticking (call just before awaiting the parse). */
203
229
  start() {
204
230
  this.schedule_();
205
231
  }
232
+ /**
233
+ * Tick inline if one is due — called from the parse's own progress
234
+ * callback, so the channel keeps its cadence even when the event
235
+ * loop's timer queue is starved (browser: the cooperative parse
236
+ * yields via scheduler.yield / MessageChannel, whose continuations
237
+ * outrank setTimeout; the 150ms timer ticks barely ran on PSB-class
238
+ * parses, starving the preview until parse end). The timer remains
239
+ * as a fallback for gaps between progress calls.
240
+ */
241
+ maybeTickInline() {
242
+ if (this.stopped_ || this.capped) {
243
+ return;
244
+ }
245
+ const now = Date.now();
246
+ if (now - this.lastInlineTick_ < this.tickIntervalMs_) {
247
+ return;
248
+ }
249
+ this.lastInlineTick_ = now;
250
+ this.tickIntervalMs_ =
251
+ Math.min(this.tickIntervalMs_ * TICK_INTERVAL_GROWTH, TICK_INTERVAL_MAX_MS);
252
+ try {
253
+ this.tick_();
254
+ }
255
+ catch {
256
+ // A preview failure must never break the open.
257
+ this.stopped_ = true;
258
+ }
259
+ }
206
260
  /**
207
261
  * Stop ticking (call once the parse settles, before finalize/fallback).
208
262
  * Idempotent; no tick runs after this returns (ticks are synchronous and
@@ -246,7 +300,7 @@ export class StreamedPreviewChannel {
246
300
  this.stopped_ = true;
247
301
  }
248
302
  this.schedule_();
249
- }, TICK_INTERVAL_MS);
303
+ }, this.tickIntervalMs_);
250
304
  }
251
305
  /**
252
306
  * One pump tick: ensure a generation with pending units exists, then
@@ -259,6 +313,26 @@ export class StreamedPreviewChannel {
259
313
  }
260
314
  const active = this.generation_;
261
315
  const { generation } = active;
316
+ if (this.adapter.retryEmptyUnits === true) {
317
+ // Retry mode: scan the fixed unit list, skipping units that
318
+ // already captured instances on an earlier (or this) generation.
319
+ // Capture runs per unit so completion can be attributed — unit
320
+ // counts here are small by construction (assembly roots).
321
+ while (this.retryScan_ < generation.unitCount &&
322
+ this.emittedUnits_ < this.maxUnits &&
323
+ Date.now() < deadline) {
324
+ const ordinal = this.retryScan_++;
325
+ if (this.completedUnits_.has(ordinal)) {
326
+ continue;
327
+ }
328
+ const executed = generation.runUnits(ordinal, 1);
329
+ if (executed > 0 && this.captureNewInstances_() > 0) {
330
+ this.completedUnits_.add(ordinal);
331
+ ++this.emittedUnits_;
332
+ }
333
+ }
334
+ return;
335
+ }
262
336
  let extractedThisTick = 0;
263
337
  while (this.unitOrdinal_ < generation.unitCount &&
264
338
  this.emittedUnits_ + extractedThisTick < this.maxUnits &&
@@ -281,7 +355,7 @@ export class StreamedPreviewChannel {
281
355
  */
282
356
  ensureGeneration_() {
283
357
  const active = this.generation_;
284
- if (active !== void 0 && this.unitOrdinal_ < active.generation.unitCount) {
358
+ if (active !== void 0 && this.hasPendingUnits_(active.generation)) {
285
359
  return true;
286
360
  }
287
361
  const records = this.sink.topLevelCount;
@@ -292,30 +366,78 @@ export class StreamedPreviewChannel {
292
366
  records < this.lastSnapshotRecords_ * GENERATION_GROWTH_FACTOR) {
293
367
  return false;
294
368
  }
369
+ if (records < this.lastFailedSnapshotRecords_ * GENERATION_GROWTH_FACTOR) {
370
+ return false;
371
+ }
295
372
  const columns = this.sink.snapshot();
296
- const generation = this.adapter.buildGeneration(this.data, this.conwaywasm, columns);
373
+ let generation;
374
+ try {
375
+ generation =
376
+ this.adapter.buildGeneration(this.data, this.conwaywasm, columns);
377
+ }
378
+ catch {
379
+ // A mid-parse prefix can be structurally incomplete — dangling
380
+ // references throw schema-typed errors (AP214's assembly-tree
381
+ // prep especially; a bad prefix killed the whole STEP preview
382
+ // before this catch). That retires THIS attempt, not the
383
+ // channel: the growth gate above retries once the index has
384
+ // grown enough for a materially different prefix.
385
+ this.lastFailedSnapshotRecords_ = records;
386
+ return false;
387
+ }
388
+ this.lastFailedSnapshotRecords_ = 0;
297
389
  this.lastSnapshotRecords_ = records;
298
- // The outgoing generation's instances are all captured (a
299
- // generation is only replaced once exhausted + captured) free its
300
- // native scenes before adopting the new one.
301
- if (generation !== void 0 && generation.unitCount > this.unitOrdinal_) {
390
+ if (generation === void 0) {
391
+ // Prefix grew but cannot build yet wait for more records.
392
+ return false;
393
+ }
394
+ const newGenerationPending = this.adapter.retryEmptyUnits === true ?
395
+ generation.unitCount > 0 &&
396
+ this.completedUnits_.size < generation.unitCount :
397
+ generation.unitCount > this.unitOrdinal_;
398
+ if (!newGenerationPending) {
399
+ // Nothing this prefix can add — free it and wait for more records.
400
+ // (The active generation, if any, keeps its scan state untouched.)
302
401
  try {
303
- active?.generation.dispose();
402
+ generation.dispose();
304
403
  }
305
404
  catch {
306
405
  // Never let a free break the open.
307
406
  }
308
- }
309
- if (generation === void 0 || generation.unitCount <= this.unitOrdinal_) {
310
- // Prefix grew but produced no new units — wait for more records.
311
407
  return false;
312
408
  }
409
+ // Retry mode: a fresh generation re-runs every not-yet-captured unit.
410
+ this.retryScan_ = 0;
411
+ // The outgoing generation's instances are all captured (a
412
+ // generation is only replaced once exhausted + captured) — free its
413
+ // native scenes before adopting the new one.
414
+ try {
415
+ active?.generation.dispose();
416
+ }
417
+ catch {
418
+ // Never let a free break the open.
419
+ }
313
420
  this.generation_ = {
314
421
  generation,
315
422
  capturedCounts: new Map(),
316
423
  };
317
424
  return true;
318
425
  }
426
+ /**
427
+ * Does the given generation still have units this channel would run —
428
+ * retry mode: not-yet-captured ordinals ahead of the scan; classic
429
+ * mode: ordinals beyond the global forward-only cursor.
430
+ *
431
+ * @param generation The generation to check.
432
+ * @return {boolean} True when a tick can make progress on it.
433
+ */
434
+ hasPendingUnits_(generation) {
435
+ if (this.adapter.retryEmptyUnits === true) {
436
+ return this.retryScan_ < generation.unitCount &&
437
+ this.completedUnits_.size < generation.unitCount;
438
+ }
439
+ return this.unitOrdinal_ < generation.unitCount;
440
+ }
319
441
  /**
320
442
  * Walk the current generation's scene and emit every not-yet-captured
321
443
  * placed instance as a payload — the preview twin of the durable delta
@@ -323,6 +445,9 @@ export class StreamedPreviewChannel {
323
445
  * for IFC, bare composition for AP214) so preview and durable
324
446
  * placements coincide, but copying geometry OUT of the wasm heap
325
447
  * instead of retaining native references.
448
+ *
449
+ * @return {number} Instances emitted by this pass (retry mode uses
450
+ * this to attribute unit completion).
326
451
  */
327
452
  captureNewInstances_() {
328
453
  const active = this.generation_;
@@ -330,6 +455,7 @@ export class StreamedPreviewChannel {
330
455
  const { scene, recenter } = generation;
331
456
  const linearScalingFactor = generation.linearScalingFactor;
332
457
  const seenThisPass = new Map();
458
+ let emitted = 0;
333
459
  for (const walked of scene.walk()) {
334
460
  const [, nativeTransform, geometry, material, entity] = walked;
335
461
  if (entity?.localID === void 0 || entity.expressID === void 0) {
@@ -424,10 +550,12 @@ export class StreamedPreviewChannel {
424
550
  (vertexData.length + indexData.length) * BYTES_PER_FLOAT;
425
551
  }
426
552
  this.onMesh(payload);
553
+ ++emitted;
427
554
  if (this.emittedBytes_ >= this.maxBytes) {
428
- return;
555
+ return emitted;
429
556
  }
430
557
  }
558
+ return emitted;
431
559
  }
432
560
  /**
433
561
  * Test seam: run generation building + extraction + capture synchronously
@@ -933,8 +933,16 @@ export declare class IfcGeometryExtraction {
933
933
  * whole-model walk: populates the shared extraction maps so
934
934
  * {@link extractProductGeometryByLocalID} can extract any single product.
935
935
  * Idempotent; the whole-model walk shares the same preparation.
936
+ *
937
+ * @param lightweightPreview Preview-only preparation (parse-time
938
+ * preview generations): skips the relationship sweeps
939
+ * (rel-materials, rel-voids) whose entity materialization dominates
940
+ * preparation cost on large models — extracted products then miss
941
+ * openings and rel-bound materials, which preview consumers accept
942
+ * by contract. Styled-item and material-definition maps are kept
943
+ * (colors), as is the linear scaling factor.
936
944
  */
937
- prepareDemandExtraction(): void;
945
+ prepareDemandExtraction(lightweightPreview?: boolean): void;
938
946
  /**
939
947
  * Extract one product's geometry into the scene by local ID — the demand
940
948
  * path's entry (Phase B2). Requires {@link prepareDemandExtraction} (or a