@bldrs-ai/conway 1.427.1287 → 1.428.1289
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/compiled/examples/browser-bundled.cjs +1 -1
- package/compiled/examples/cli-bundled.cjs +1 -1
- package/compiled/examples/cli-step-bundled.cjs +15 -1
- package/compiled/examples/validator-bundled.cjs +1 -1
- package/compiled/src/AP214E3_2010/ap214_geometry_extraction.d.ts +8 -0
- package/compiled/src/AP214E3_2010/ap214_geometry_extraction.d.ts.map +1 -1
- package/compiled/src/AP214E3_2010/ap214_geometry_extraction.js +14 -0
- package/compiled/src/compat/web-ifc/ap214_streamed_open.test.js +40 -0
- package/compiled/src/compat/web-ifc/ifc_api_preview_channel.test.js +2 -2
- package/compiled/src/compat/web-ifc/ifc_api_proxy_ap214.d.ts +3 -0
- package/compiled/src/compat/web-ifc/ifc_api_proxy_ap214.d.ts.map +1 -1
- package/compiled/src/compat/web-ifc/ifc_api_proxy_ap214.js +23 -1
- package/compiled/src/compat/web-ifc/ifc_api_proxy_ifc.d.ts.map +1 -1
- package/compiled/src/compat/web-ifc/ifc_api_proxy_ifc.js +2 -2
- package/compiled/src/compat/web-ifc/streamed_preview_channel.d.ts +111 -38
- package/compiled/src/compat/web-ifc/streamed_preview_channel.d.ts.map +1 -1
- package/compiled/src/compat/web-ifc/streamed_preview_channel.js +176 -106
- package/compiled/src/version/version.js +1 -1
- package/compiled/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -2,6 +2,8 @@ import { CanonicalMeshType } from "../../index.js";
|
|
|
2
2
|
import IfcStepModel from "../../ifc/ifc_step_model.js";
|
|
3
3
|
import { IfcGeometryExtraction } from "../../ifc/ifc_geometry_extraction.js";
|
|
4
4
|
import { IfcProduct } from "../../ifc/ifc4_gen/index.js";
|
|
5
|
+
import AP214StepModel from "../../AP214E3_2010/ap214_step_model.js";
|
|
6
|
+
import { AP214GeometryExtraction, } from "../../AP214E3_2010/ap214_geometry_extraction.js";
|
|
5
7
|
import * as glmatrix from "gl-matrix";
|
|
6
8
|
/* eslint-disable no-magic-numbers */
|
|
7
9
|
/** Ms between preview pump ticks (interleaves with the parse's yields). */
|
|
@@ -15,43 +17,123 @@ const FIRST_GENERATION_MIN_RECORDS = 1024;
|
|
|
15
17
|
/** A new generation only when the index grew this much past the previous
|
|
16
18
|
* snapshot (bounds snapshot copies to O(GROWTH/(GROWTH-1)) of the file). */
|
|
17
19
|
const GENERATION_GROWTH_FACTOR = 1.5;
|
|
18
|
-
/** Default cap on
|
|
20
|
+
/** Default cap on units the preview channel ever extracts. Preview
|
|
19
21
|
* generations are throwaway extractions whose native geometry is not
|
|
20
22
|
* reclaimed until page teardown (the shim never frees classic scenes
|
|
21
23
|
* either — see closeModel), so the cap bounds that one-time cost. */
|
|
22
|
-
const
|
|
24
|
+
const DEFAULT_MAX_PREVIEW_UNITS = 4096;
|
|
23
25
|
/** Default cap on total payload bytes copied out to the consumer. */
|
|
24
26
|
const DEFAULT_MAX_PREVIEW_BYTES = 48 * 1024 * 1024;
|
|
25
27
|
const FLOATS_PER_VERTEX = 6;
|
|
26
28
|
const BYTES_PER_FLOAT = 4;
|
|
27
29
|
const DEFAULT_COLOR = [0.8, 0.8, 0.8, 1];
|
|
28
|
-
// Matches the shim
|
|
30
|
+
// Matches the shim proxies' NormalizeMat (Z-up -> Y-up).
|
|
29
31
|
const NORMALIZE_MAT = glmatrix.mat4.fromValues(1, 0, 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1);
|
|
30
32
|
/**
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
* columnar index into a PREFIX model, extract a bounded number of products
|
|
34
|
-
* through a throwaway extraction, and emit self-contained mesh payloads —
|
|
35
|
-
* first pixels within the first seconds of a large parse instead of after
|
|
36
|
-
* it.
|
|
33
|
+
* IFC adapter: units are IfcProducts in localID order (stable across
|
|
34
|
+
* prefix growth), extracted through the per-product demand seam.
|
|
37
35
|
*
|
|
38
|
-
*
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
36
|
+
* @return {PreviewSchemaAdapter} The adapter.
|
|
37
|
+
*/
|
|
38
|
+
export function ifcPreviewAdapter() {
|
|
39
|
+
return {
|
|
40
|
+
buildGeneration(data, conwaywasm, columns) {
|
|
41
|
+
const model = new IfcStepModel(data, columns);
|
|
42
|
+
const products = [];
|
|
43
|
+
for (const product of model.types(IfcProduct)) {
|
|
44
|
+
products.push(product.localID);
|
|
45
|
+
}
|
|
46
|
+
if (products.length === 0) {
|
|
47
|
+
return void 0;
|
|
48
|
+
}
|
|
49
|
+
const extraction = new IfcGeometryExtraction(conwaywasm, model);
|
|
50
|
+
return {
|
|
51
|
+
scene: extraction.scene,
|
|
52
|
+
unitCount: products.length,
|
|
53
|
+
get linearScalingFactor() {
|
|
54
|
+
return extraction.getLinearScalingFactor();
|
|
55
|
+
},
|
|
56
|
+
runUnits: (from, count) => {
|
|
57
|
+
const end = Math.min(from + count, products.length);
|
|
58
|
+
let executed = 0;
|
|
59
|
+
for (let where = from; where < end; ++where) {
|
|
60
|
+
try {
|
|
61
|
+
if (extraction.extractProductGeometryByLocalID(products[where])) {
|
|
62
|
+
++executed;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
// Unparsed forward reference — the durable pump extracts
|
|
67
|
+
// this product from the full model later.
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return executed;
|
|
71
|
+
},
|
|
72
|
+
geometryExpressID: (geometryLocalID) => model.getElementByLocalID(geometryLocalID)?.expressID,
|
|
73
|
+
recenter: true,
|
|
74
|
+
};
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* AP214 adapter: units are assembly-tree units (see
|
|
80
|
+
* AP214GeometryExtraction.prepareDemandExtraction). Unit ordinals are
|
|
81
|
+
* only approximately stable across prefix growth (a root's child list
|
|
82
|
+
* can grow, shifting later ordinals) — for a preview that is
|
|
83
|
+
* acceptable: a shifted ordinal re-emits an instance at an identical
|
|
84
|
+
* placement (invisible overlap) or skips one (the durable pump renders
|
|
85
|
+
* it later).
|
|
86
|
+
*
|
|
87
|
+
* @return {PreviewSchemaAdapter} The adapter.
|
|
88
|
+
*/
|
|
89
|
+
export function ap214PreviewAdapter() {
|
|
90
|
+
return {
|
|
91
|
+
buildGeneration(data, conwaywasm, columns) {
|
|
92
|
+
const model = new AP214StepModel(data, columns);
|
|
93
|
+
const extraction = new AP214GeometryExtraction(conwaywasm, model);
|
|
94
|
+
extraction.prepareDemandExtraction();
|
|
95
|
+
if (extraction.demandUnitCount === 0) {
|
|
96
|
+
return void 0;
|
|
97
|
+
}
|
|
98
|
+
return {
|
|
99
|
+
scene: extraction.scene,
|
|
100
|
+
unitCount: extraction.demandUnitCount,
|
|
101
|
+
get linearScalingFactor() {
|
|
102
|
+
return extraction.getLinearScalingFactor();
|
|
103
|
+
},
|
|
104
|
+
runUnits: (from, count) => {
|
|
105
|
+
if (extraction.demandUnitCursor < from) {
|
|
106
|
+
extraction.skipDemandUnits(from - extraction.demandUnitCursor);
|
|
107
|
+
}
|
|
108
|
+
return extraction.extractDemandUnitBatch(count);
|
|
109
|
+
},
|
|
110
|
+
geometryExpressID: (geometryLocalID) => model.getElementByLocalID(geometryLocalID)?.expressID,
|
|
111
|
+
recenter: false,
|
|
112
|
+
};
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Parse-time preview channel (demand/tiled rendering slice A2): while a
|
|
118
|
+
* deferred streamed open is still parsing, periodically snapshot the
|
|
119
|
+
* growing columnar index into a PREFIX model, extract a bounded number of
|
|
120
|
+
* units through a throwaway extraction, and emit self-contained mesh
|
|
121
|
+
* payloads — first pixels within the first seconds of a large parse
|
|
122
|
+
* instead of after it. Schema knowledge lives in the
|
|
123
|
+
* {@link PreviewSchemaAdapter}; the channel owns scheduling, generations,
|
|
124
|
+
* watermarks, payload copies, caps and the coordination pin.
|
|
45
125
|
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
126
|
+
* Preview quality, by construction: relationship records (IFC voids,
|
|
127
|
+
* materials, styled items) spread to the very end of real files
|
|
128
|
+
* (measured ~92–97% depth), so a prefix extraction can miss
|
|
129
|
+
* openings and materials. That is why these extractions are throwaway:
|
|
130
|
+
* the durable batch pump after the parse re-extracts every unit with the
|
|
131
|
+
* full model and REPLACES the preview — final geometry parity is
|
|
132
|
+
* untouched by this channel.
|
|
49
133
|
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
* Products whose extraction throws mid-parse (unparsed forward references)
|
|
54
|
-
* are skipped — the durable pump extracts them correctly later.
|
|
134
|
+
* Scheduling: the cooperative parse yields to the event loop via
|
|
135
|
+
* macrotasks every ~50ms; each pump tick runs in one of those gaps under
|
|
136
|
+
* a hard time budget, so the parse keeps the bulk of the main thread.
|
|
55
137
|
*/
|
|
56
138
|
export class StreamedPreviewChannel {
|
|
57
139
|
/**
|
|
@@ -60,27 +142,30 @@ export class StreamedPreviewChannel {
|
|
|
60
142
|
* — ticks run between parse yields, never concurrently with the durable
|
|
61
143
|
* extraction, which is created after the parse completes).
|
|
62
144
|
* @param sink The live columnar sink the streamed parse is filling.
|
|
145
|
+
* @param adapter The schema adapter building prefix generations.
|
|
63
146
|
* @param coordinateToOrigin The open's COORDINATE_TO_ORIGIN setting.
|
|
64
147
|
* @param onMesh Consumer callback for each preview payload.
|
|
65
|
-
* @param
|
|
148
|
+
* @param maxUnits Cap on units ever preview-extracted.
|
|
66
149
|
* @param maxBytes Cap on total payload bytes copied out.
|
|
67
150
|
* @param firstGenerationMinRecords Records required before the first
|
|
68
151
|
* snapshot (tests lower it for tiny fixtures).
|
|
69
152
|
*/
|
|
70
|
-
constructor(data, conwaywasm, sink, coordinateToOrigin, onMesh,
|
|
153
|
+
constructor(data, conwaywasm, sink, adapter, coordinateToOrigin, onMesh, maxUnits = DEFAULT_MAX_PREVIEW_UNITS, maxBytes = DEFAULT_MAX_PREVIEW_BYTES, firstGenerationMinRecords = FIRST_GENERATION_MIN_RECORDS) {
|
|
71
154
|
this.data = data;
|
|
72
155
|
this.conwaywasm = conwaywasm;
|
|
73
156
|
this.sink = sink;
|
|
157
|
+
this.adapter = adapter;
|
|
74
158
|
this.coordinateToOrigin = coordinateToOrigin;
|
|
75
159
|
this.onMesh = onMesh;
|
|
76
|
-
this.
|
|
160
|
+
this.maxUnits = maxUnits;
|
|
77
161
|
this.maxBytes = maxBytes;
|
|
78
162
|
this.firstGenerationMinRecords = firstGenerationMinRecords;
|
|
79
163
|
this.stopped_ = false;
|
|
80
|
-
this.
|
|
164
|
+
this.emittedUnits_ = 0;
|
|
81
165
|
this.emittedBytes_ = 0;
|
|
82
|
-
/** Ordinal cursor into the (
|
|
83
|
-
|
|
166
|
+
/** Ordinal cursor into the unit list (see the adapter's stability
|
|
167
|
+
* notes). */
|
|
168
|
+
this.unitOrdinal_ = 0;
|
|
84
169
|
/** Geometry expressIDs whose payload has been emitted (cross-generation
|
|
85
170
|
* dedup for mapped/shared geometry). */
|
|
86
171
|
this.emittedGeometry_ = new Set();
|
|
@@ -104,7 +189,7 @@ export class StreamedPreviewChannel {
|
|
|
104
189
|
}
|
|
105
190
|
/** True when a cap was hit and the channel retired itself early. */
|
|
106
191
|
get capped() {
|
|
107
|
-
return this.
|
|
192
|
+
return this.emittedUnits_ >= this.maxUnits ||
|
|
108
193
|
this.emittedBytes_ >= this.maxBytes;
|
|
109
194
|
}
|
|
110
195
|
// eslint-disable-next-line require-jsdoc
|
|
@@ -126,7 +211,7 @@ export class StreamedPreviewChannel {
|
|
|
126
211
|
}, TICK_INTERVAL_MS);
|
|
127
212
|
}
|
|
128
213
|
/**
|
|
129
|
-
* One pump tick: ensure a generation with pending
|
|
214
|
+
* One pump tick: ensure a generation with pending units exists, then
|
|
130
215
|
* extract + capture under the time budget.
|
|
131
216
|
*/
|
|
132
217
|
tick_() {
|
|
@@ -134,87 +219,70 @@ export class StreamedPreviewChannel {
|
|
|
134
219
|
if (!this.ensureGeneration_()) {
|
|
135
220
|
return;
|
|
136
221
|
}
|
|
137
|
-
const
|
|
138
|
-
const {
|
|
222
|
+
const active = this.generation_;
|
|
223
|
+
const { generation } = active;
|
|
139
224
|
let extractedThisTick = 0;
|
|
140
|
-
while (
|
|
141
|
-
this.
|
|
225
|
+
while (this.unitOrdinal_ < generation.unitCount &&
|
|
226
|
+
this.emittedUnits_ + extractedThisTick < this.maxUnits &&
|
|
142
227
|
Date.now() < deadline) {
|
|
143
|
-
const
|
|
144
|
-
++this.
|
|
145
|
-
|
|
146
|
-
if (extraction.extractProductGeometryByLocalID(localID)) {
|
|
147
|
-
++extractedThisTick;
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
catch {
|
|
151
|
-
// Unparsed forward reference (or any other mid-parse gap): skip.
|
|
152
|
-
// The durable pump extracts this product from the full model.
|
|
153
|
-
}
|
|
228
|
+
const executed = generation.runUnits(this.unitOrdinal_, 1);
|
|
229
|
+
++this.unitOrdinal_;
|
|
230
|
+
extractedThisTick += executed;
|
|
154
231
|
}
|
|
155
232
|
if (extractedThisTick > 0) {
|
|
156
233
|
this.captureNewInstances_();
|
|
157
|
-
this.
|
|
234
|
+
this.emittedUnits_ += extractedThisTick;
|
|
158
235
|
}
|
|
159
236
|
}
|
|
160
237
|
/**
|
|
161
|
-
* Ensure a generation with pending
|
|
162
|
-
* it has work; otherwise snapshot a fresh prefix model once the index
|
|
163
|
-
* grown enough to be worth the copy.
|
|
238
|
+
* Ensure a generation with pending units: keep the current one while
|
|
239
|
+
* it has work; otherwise snapshot a fresh prefix model once the index
|
|
240
|
+
* has grown enough to be worth the copy.
|
|
164
241
|
*
|
|
165
|
-
* @return {boolean} True when a generation with pending
|
|
242
|
+
* @return {boolean} True when a generation with pending units exists.
|
|
166
243
|
*/
|
|
167
244
|
ensureGeneration_() {
|
|
168
|
-
const
|
|
169
|
-
if (
|
|
245
|
+
const active = this.generation_;
|
|
246
|
+
if (active !== void 0 && this.unitOrdinal_ < active.generation.unitCount) {
|
|
170
247
|
return true;
|
|
171
248
|
}
|
|
172
249
|
const records = this.sink.topLevelCount;
|
|
173
250
|
if (records < this.firstGenerationMinRecords) {
|
|
174
251
|
return false;
|
|
175
252
|
}
|
|
176
|
-
if (
|
|
253
|
+
if (active !== void 0 &&
|
|
177
254
|
records < this.lastSnapshotRecords_ * GENERATION_GROWTH_FACTOR) {
|
|
178
255
|
return false;
|
|
179
256
|
}
|
|
180
257
|
const columns = this.sink.snapshot();
|
|
181
|
-
const
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
}
|
|
186
|
-
if (products.length <= this.productOrdinal_) {
|
|
187
|
-
// Prefix grew but produced no new products — wait for more records.
|
|
188
|
-
this.lastSnapshotRecords_ = records;
|
|
258
|
+
const generation = this.adapter.buildGeneration(this.data, this.conwaywasm, columns);
|
|
259
|
+
this.lastSnapshotRecords_ = records;
|
|
260
|
+
if (generation === void 0 || generation.unitCount <= this.unitOrdinal_) {
|
|
261
|
+
// Prefix grew but produced no new units — wait for more records.
|
|
189
262
|
return false;
|
|
190
263
|
}
|
|
191
|
-
const extraction = new IfcGeometryExtraction(this.conwaywasm, model);
|
|
192
264
|
this.generation_ = {
|
|
193
|
-
|
|
194
|
-
extraction,
|
|
195
|
-
products,
|
|
196
|
-
nextIndex: this.productOrdinal_,
|
|
265
|
+
generation,
|
|
197
266
|
capturedCounts: new Map(),
|
|
198
|
-
snapshotRecords: records,
|
|
199
267
|
};
|
|
200
|
-
this.lastSnapshotRecords_ = records;
|
|
201
268
|
return true;
|
|
202
269
|
}
|
|
203
270
|
/**
|
|
204
271
|
* Walk the current generation's scene and emit every not-yet-captured
|
|
205
|
-
* placed instance as a payload — the preview twin of the
|
|
206
|
-
*
|
|
207
|
-
*
|
|
208
|
-
* geometry OUT of the wasm heap
|
|
272
|
+
* placed instance as a payload — the preview twin of the durable delta
|
|
273
|
+
* captures, with the same placed-geometry math per schema (recentering
|
|
274
|
+
* for IFC, bare composition for AP214) so preview and durable
|
|
275
|
+
* placements coincide, but copying geometry OUT of the wasm heap
|
|
276
|
+
* instead of retaining native references.
|
|
209
277
|
*/
|
|
210
278
|
captureNewInstances_() {
|
|
211
|
-
const
|
|
212
|
-
const {
|
|
213
|
-
const scene =
|
|
214
|
-
const linearScalingFactor =
|
|
279
|
+
const active = this.generation_;
|
|
280
|
+
const { generation, capturedCounts } = active;
|
|
281
|
+
const { scene, recenter } = generation;
|
|
282
|
+
const linearScalingFactor = generation.linearScalingFactor;
|
|
215
283
|
const seenThisPass = new Map();
|
|
216
|
-
|
|
217
|
-
|
|
284
|
+
for (const walked of scene.walk()) {
|
|
285
|
+
const [, nativeTransform, geometry, material, entity] = walked;
|
|
218
286
|
if (entity?.localID === void 0 || entity.expressID === void 0) {
|
|
219
287
|
continue;
|
|
220
288
|
}
|
|
@@ -238,14 +306,16 @@ export class StreamedPreviewChannel {
|
|
|
238
306
|
if (this.coordinationMatrix === void 0 && this.coordinateToOrigin) {
|
|
239
307
|
nativePt = geometry.geometry.getPoint(0);
|
|
240
308
|
}
|
|
241
|
-
const geomCenter = glmatrix.vec3.create();
|
|
242
|
-
const center = geometry.geometry.normalize();
|
|
243
|
-
geomCenter[0] = center.x;
|
|
244
|
-
geomCenter[1] = center.y;
|
|
245
|
-
geomCenter[2] = center.z;
|
|
246
309
|
const translationMatrixGeomMin = glmatrix.mat4.create();
|
|
247
|
-
|
|
248
|
-
|
|
310
|
+
if (recenter) {
|
|
311
|
+
const geomCenter = glmatrix.vec3.create();
|
|
312
|
+
const center = geometry.geometry.normalize();
|
|
313
|
+
geomCenter[0] = center.x;
|
|
314
|
+
geomCenter[1] = center.y;
|
|
315
|
+
geomCenter[2] = center.z;
|
|
316
|
+
glmatrix.mat4.fromTranslation(translationMatrixGeomMin, geomCenter);
|
|
317
|
+
}
|
|
318
|
+
const geometryExpressID = generation.geometryExpressID(geometry.localID);
|
|
249
319
|
const geometryTransform = nativeTransform?.getValues();
|
|
250
320
|
let newMatrix;
|
|
251
321
|
if (geometryTransform !== void 0) {
|
|
@@ -268,11 +338,18 @@ export class StreamedPreviewChannel {
|
|
|
268
338
|
}
|
|
269
339
|
const coordination = this.coordinationMatrix ?? glmatrix.mat4.create();
|
|
270
340
|
const newTransform = glmatrix.mat4.create();
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
341
|
+
if (recenter) {
|
|
342
|
+
const scaleMatrix = glmatrix.mat4.create();
|
|
343
|
+
const scaleVec = glmatrix.vec3.fromValues(linearScalingFactor, linearScalingFactor, linearScalingFactor);
|
|
344
|
+
glmatrix.mat4.scale(scaleMatrix, scaleMatrix, scaleVec);
|
|
345
|
+
glmatrix.mat4.multiply(newTransform, coordination, newMatrix);
|
|
346
|
+
glmatrix.mat4.multiply(newTransform, newTransform, translationMatrixGeomMin);
|
|
347
|
+
}
|
|
348
|
+
else {
|
|
349
|
+
// Bare composition — no per-leaf recenter (AP214 instances share
|
|
350
|
+
// one geometry buffer, issue #308), matching its durable capture.
|
|
351
|
+
glmatrix.mat4.multiply(newTransform, coordination, newMatrix);
|
|
352
|
+
}
|
|
276
353
|
const payload = {
|
|
277
354
|
expressID: entity.expressID,
|
|
278
355
|
geometryExpressID,
|
|
@@ -305,7 +382,7 @@ export class StreamedPreviewChannel {
|
|
|
305
382
|
}
|
|
306
383
|
/**
|
|
307
384
|
* Test seam: run generation building + extraction + capture synchronously
|
|
308
|
-
* until either every
|
|
385
|
+
* until either every unit currently in the sink is attempted or a cap
|
|
309
386
|
* is hit — what the timer-driven ticks do, without the timers.
|
|
310
387
|
*/
|
|
311
388
|
drainForTest() {
|
|
@@ -313,22 +390,15 @@ export class StreamedPreviewChannel {
|
|
|
313
390
|
if (this.capped || !this.ensureGeneration_()) {
|
|
314
391
|
return;
|
|
315
392
|
}
|
|
316
|
-
const
|
|
317
|
-
if (
|
|
393
|
+
const active = this.generation_;
|
|
394
|
+
if (this.unitOrdinal_ >= active.generation.unitCount) {
|
|
318
395
|
return;
|
|
319
396
|
}
|
|
320
|
-
const
|
|
321
|
-
++this.
|
|
322
|
-
|
|
323
|
-
try {
|
|
324
|
-
extracted = generation.extraction.extractProductGeometryByLocalID(localID);
|
|
325
|
-
}
|
|
326
|
-
catch {
|
|
327
|
-
// Skip — mirrors tick_.
|
|
328
|
-
}
|
|
329
|
-
if (extracted) {
|
|
397
|
+
const executed = active.generation.runUnits(this.unitOrdinal_, 1);
|
|
398
|
+
++this.unitOrdinal_;
|
|
399
|
+
if (executed > 0) {
|
|
330
400
|
this.captureNewInstances_();
|
|
331
|
-
++this.
|
|
401
|
+
++this.emittedUnits_;
|
|
332
402
|
}
|
|
333
403
|
}
|
|
334
404
|
}
|
|
@@ -5,5 +5,5 @@
|
|
|
5
5
|
// only the first segment (major) is meaningful and is the one CI carries forward.
|
|
6
6
|
// Must stay in `vN.N.N` shape: the CI stamp regex, scripts/updateVersion.mjs, and
|
|
7
7
|
// statistics.ts all match `v\d+\.\d+\.\d+`.
|
|
8
|
-
const versionString = 'Conway v1.
|
|
8
|
+
const versionString = 'Conway v1.428.1289';
|
|
9
9
|
export { versionString };
|