@bldrs-ai/conway 1.405.1243 → 1.409.1251

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 (55) hide show
  1. package/compiled/examples/browser-bundled.cjs +238 -13
  2. package/compiled/examples/cli-bundled.cjs +238 -13
  3. package/compiled/examples/cli-step-bundled.cjs +104 -9
  4. package/compiled/examples/validator-bundled.cjs +238 -13
  5. package/compiled/src/AP214E3_2010/ap214_step_model.d.ts +2 -1
  6. package/compiled/src/AP214E3_2010/ap214_step_model.d.ts.map +1 -1
  7. package/compiled/src/AP214E3_2010/ap214_step_model.js +1 -1
  8. package/compiled/src/core/geometry_tile_pool.d.ts +99 -0
  9. package/compiled/src/core/geometry_tile_pool.d.ts.map +1 -0
  10. package/compiled/src/core/geometry_tile_pool.js +104 -0
  11. package/compiled/src/core/geometry_tile_pool.test.d.ts +2 -0
  12. package/compiled/src/core/geometry_tile_pool.test.d.ts.map +1 -0
  13. package/compiled/src/core/geometry_tile_pool.test.js +180 -0
  14. package/compiled/src/core/mem/chunked_pool.d.ts +116 -0
  15. package/compiled/src/core/mem/chunked_pool.d.ts.map +1 -0
  16. package/compiled/src/core/mem/chunked_pool.js +149 -0
  17. package/compiled/src/core/mem/chunked_pool.test.d.ts +2 -0
  18. package/compiled/src/core/mem/chunked_pool.test.d.ts.map +1 -0
  19. package/compiled/src/core/mem/chunked_pool.test.js +63 -0
  20. package/compiled/src/core/mem/shared_asset_pool.d.ts +82 -0
  21. package/compiled/src/core/mem/shared_asset_pool.d.ts.map +1 -0
  22. package/compiled/src/core/mem/shared_asset_pool.js +113 -0
  23. package/compiled/src/core/mem/shared_asset_pool.test.d.ts +2 -0
  24. package/compiled/src/core/mem/shared_asset_pool.test.d.ts.map +1 -0
  25. package/compiled/src/core/mem/shared_asset_pool.test.js +49 -0
  26. package/compiled/src/ifc/ifc_step_model.d.ts +2 -1
  27. package/compiled/src/ifc/ifc_step_model.d.ts.map +1 -1
  28. package/compiled/src/ifc/ifc_step_model.js +1 -1
  29. package/compiled/src/ifc/ifc_step_parser.d.ts.map +1 -1
  30. package/compiled/src/ifc/ifc_step_parser.js +5 -3
  31. package/compiled/src/step/indexing/step_type_indexer.d.ts +20 -0
  32. package/compiled/src/step/indexing/step_type_indexer.d.ts.map +1 -1
  33. package/compiled/src/step/indexing/step_type_indexer.js +67 -0
  34. package/compiled/src/step/parsing/columnar_index.d.ts +81 -0
  35. package/compiled/src/step/parsing/columnar_index.d.ts.map +1 -0
  36. package/compiled/src/step/parsing/columnar_index.js +159 -0
  37. package/compiled/src/step/parsing/columnar_index.test.d.ts +2 -0
  38. package/compiled/src/step/parsing/columnar_index.test.d.ts.map +1 -0
  39. package/compiled/src/step/parsing/columnar_index.test.js +155 -0
  40. package/compiled/src/step/parsing/index_sidecar.d.ts +28 -0
  41. package/compiled/src/step/parsing/index_sidecar.d.ts.map +1 -1
  42. package/compiled/src/step/parsing/index_sidecar.js +117 -0
  43. package/compiled/src/step/parsing/index_sidecar.test.js +31 -1
  44. package/compiled/src/step/parsing/step_parser.d.ts +22 -1
  45. package/compiled/src/step/parsing/step_parser.d.ts.map +1 -1
  46. package/compiled/src/step/parsing/step_parser.js +19 -7
  47. package/compiled/src/step/parsing/streaming_index_builder.d.ts +29 -2
  48. package/compiled/src/step/parsing/streaming_index_builder.d.ts.map +1 -1
  49. package/compiled/src/step/parsing/streaming_index_builder.js +23 -2
  50. package/compiled/src/step/step_model_base.d.ts +2 -1
  51. package/compiled/src/step/step_model_base.d.ts.map +1 -1
  52. package/compiled/src/step/step_model_base.js +31 -0
  53. package/compiled/src/version/version.js +1 -1
  54. package/compiled/tsconfig.tsbuildinfo +1 -1
  55. package/package.json +1 -1
@@ -15943,7 +15943,7 @@ var ParsingBuffer = class {
15943
15943
  };
15944
15944
 
15945
15945
  // compiled/src/version/version.js
15946
- var versionString = "Conway v1.405.1243";
15946
+ var versionString = "Conway v1.409.1251";
15947
15947
 
15948
15948
  // compiled/dependencies/conway-geom/interface/conway_geometry.js
15949
15949
  function pThreadsAllowed() {
@@ -18309,8 +18309,8 @@ var StepParser = class extends StepHeaderParser {
18309
18309
  * @param onProgress Optional byte-cursor progress callback.
18310
18310
  * @return {BlockParseResult} The parsing result, including the index and result enum.
18311
18311
  */
18312
- parseDataBlockStreamed(input, onRecordBoundary, onRecordIndexed, onProgress) {
18313
- const parser28 = this.parseDataBlockIncremental(input, onRecordBoundary, onRecordIndexed);
18312
+ parseDataBlockStreamed(input, onRecordBoundary, onRecordIndexed, onProgress, sink) {
18313
+ const parser28 = this.parseDataBlockIncremental(input, onRecordBoundary, onRecordIndexed, sink);
18314
18314
  while (true) {
18315
18315
  const next = parser28.next();
18316
18316
  if (next.done === true) {
@@ -18356,8 +18356,14 @@ var StepParser = class extends StepHeaderParser {
18356
18356
  * @yields {number} The current byte cursor within the input buffer.
18357
18357
  * @return {BlockParseResult} The parsing result, including the index and result enum.
18358
18358
  */
18359
- *parseDataBlockIncremental(input, onRecordBoundary, onRecordIndexed) {
18359
+ *parseDataBlockIncremental(input, onRecordBoundary, onRecordIndexed, sink) {
18360
18360
  const indexResult = { elements: [] };
18361
+ let topLevelCount = 0;
18362
+ const pushEntry = sink !== void 0 ? (entry) => {
18363
+ sink.pushTopLevel(entry);
18364
+ } : (entry) => {
18365
+ indexResult.elements.push(entry);
18366
+ };
18361
18367
  const match = input.match;
18362
18368
  const comment = () => match(commentParser2);
18363
18369
  const whitespace = () => {
@@ -18533,8 +18539,9 @@ var StepParser = class extends StepHeaderParser {
18533
18539
  if (!charws(SEMICOLON)) {
18534
18540
  return syntaxError();
18535
18541
  }
18536
- onRecordIndexed?.(indexResult.elements.length, expressID, 0);
18537
- indexResult.elements.push({
18542
+ onRecordIndexed?.(topLevelCount, expressID, 0);
18543
+ ++topLevelCount;
18544
+ pushEntry({
18538
18545
  address: startElement2,
18539
18546
  length: input.address - startElement2,
18540
18547
  typeID: 0,
@@ -18625,8 +18632,9 @@ var StepParser = class extends StepHeaderParser {
18625
18632
  if (!charws(SEMICOLON)) {
18626
18633
  return syntaxError();
18627
18634
  }
18628
- onRecordIndexed?.(indexResult.elements.length, expressID, foundItem);
18629
- indexResult.elements.push({
18635
+ onRecordIndexed?.(topLevelCount, expressID, foundItem);
18636
+ ++topLevelCount;
18637
+ pushEntry({
18630
18638
  address: startElement,
18631
18639
  length: input.address - startElement,
18632
18640
  typeID: foundItem,
@@ -20605,6 +20613,31 @@ var StepModelBase = class {
20605
20613
  this.elementMemoization = true;
20606
20614
  this.nullOnErrors = true;
20607
20615
  this.bufferProvider_ = provider ?? new ResidentStepBufferProvider(buffer_);
20616
+ if (!Array.isArray(elementIndex)) {
20617
+ const columns = elementIndex;
20618
+ const firstInline = columns.firstInlineElement;
20619
+ const inlineCount = columns.count - firstInline;
20620
+ const inlineElementTable2 = new Uint32Array(inlineCount << 1);
20621
+ for (let where2 = 0; where2 < inlineCount; ++where2) {
20622
+ inlineElementTable2[where2 << 1] = firstInline + where2;
20623
+ inlineElementTable2[(where2 << 1) + 1] = columns.address[firstInline + where2];
20624
+ }
20625
+ this.inlineAddressMap_ = new InterpolationSearchTable32(inlineElementTable2, true);
20626
+ const expressIdTable2 = new Uint32Array(firstInline << 1);
20627
+ for (let where2 = 0; where2 < firstInline; ++where2) {
20628
+ expressIdTable2[where2 << 1] = where2;
20629
+ expressIdTable2[(where2 << 1) + 1] = columns.expressID[where2];
20630
+ }
20631
+ this.expressIDMap_ = new InterpolationSearchTable32(expressIdTable2, columns.expressIdsSorted);
20632
+ this.address_ = columns.address;
20633
+ this.length_ = columns.length;
20634
+ this.typeID_ = columns.typeID;
20635
+ this.expressID_ = columns.expressID;
20636
+ this.count_ = columns.count;
20637
+ this.firstInlineElement_ = firstInline;
20638
+ this.complexEntries_ = columns.complexEntries;
20639
+ return;
20640
+ }
20608
20641
  const localElementIndex = elementIndex;
20609
20642
  let where = 0;
20610
20643
  const firstInlineElement = localElementIndex.length;
@@ -79760,6 +79793,68 @@ var StepTypeIndexer = class {
79760
79793
  constructor(typeCount) {
79761
79794
  this.elementCounter_ = new Int32Array(typeCount << 1);
79762
79795
  }
79796
+ /**
79797
+ * Create a type index from either index form — the parsed object array or
79798
+ * the columnar index (M7).
79799
+ *
79800
+ * @param index The element index, object or columnar.
79801
+ * @return {MultiIndexSet} The created multi-set index.
79802
+ */
79803
+ createFor(index) {
79804
+ return Array.isArray(index) ? this.create(index) : this.createFromColumns(index);
79805
+ }
79806
+ /**
79807
+ * Create a type index straight from the columnar index — the same
79808
+ * membership `create` produces from the unfolded object array: every row's
79809
+ * concrete type (top-level + inline; −1 rows skipped) plus the
79810
+ * multi-mapping subtypes of retained complex entries at their parent's
79811
+ * dense index.
79812
+ *
79813
+ * @param columns The columnar index.
79814
+ * @return {MultiIndexSet} The created multi-set index.
79815
+ */
79816
+ createFromColumns(columns) {
79817
+ for (let where = 0, end = this.elementCounter_.length; where < end; where += 2) {
79818
+ initCountCompactedElements32State(this.elementCounter_, where);
79819
+ }
79820
+ const elementCounter = this.elementCounter_;
79821
+ const prefixSum = new Uint32Array((this.elementCounter_.length >>> 1) + 1);
79822
+ const typeIDs = columns.typeID;
79823
+ const count = columns.count;
79824
+ const walkRows = (addOne) => {
79825
+ const complexIterator = columns.complexEntries?.entries();
79826
+ let nextComplex = complexIterator?.next();
79827
+ for (let denseIndex = 0; denseIndex < count; ++denseIndex) {
79828
+ const typeID = typeIDs[denseIndex];
79829
+ if (typeID >= 0) {
79830
+ addOne(denseIndex, typeID);
79831
+ }
79832
+ if (nextComplex !== void 0 && !nextComplex.done && nextComplex.value[0] === denseIndex) {
79833
+ for (const subElement of nextComplex.value[1].multiMapping ?? []) {
79834
+ const subTypeID = subElement.typeID;
79835
+ if (subTypeID !== void 0) {
79836
+ addOne(denseIndex, subTypeID);
79837
+ }
79838
+ }
79839
+ nextComplex = complexIterator.next();
79840
+ }
79841
+ }
79842
+ };
79843
+ walkRows((denseIndex, typeID) => {
79844
+ prefixSum[typeID + 1] = addCompactedElementCount32State(denseIndex, elementCounter, typeID << 1);
79845
+ });
79846
+ for (let prefixSumIndex = 2, prefixSumEnd = prefixSum.length; prefixSumIndex < prefixSumEnd; ++prefixSumIndex) {
79847
+ prefixSum[prefixSumIndex] += prefixSum[prefixSumIndex - 1];
79848
+ }
79849
+ for (let where = 0, end = this.elementCounter_.length; where < end; where += 2) {
79850
+ initCountCompactedElements32State(this.elementCounter_, where);
79851
+ }
79852
+ const indexOutput = new Uint32Array(prefixSum[prefixSum.length - 1] << 1);
79853
+ walkRows((denseIndex, typeID) => {
79854
+ addCompactedElement32State(denseIndex, elementCounter, indexOutput, typeID << 1, prefixSum[typeID] << 1);
79855
+ });
79856
+ return new MultiIndexSet(prefixSum, indexOutput);
79857
+ }
79763
79858
  /**
79764
79859
  * Create a type index from a set of parsed STEP elements.
79765
79860
  *
@@ -80319,7 +80414,7 @@ var AP214StepModel = class extends StepModelBase {
80319
80414
  this.profiles = new AP214ModelProfile();
80320
80415
  this.curves = new AP214ModelCurves(this);
80321
80416
  this.csgOperations = new CsgMemoization();
80322
- this.typeIndex = indexerInstance.create(elementIndex);
80417
+ this.typeIndex = indexerInstance.createFor(elementIndex);
80323
80418
  }
80324
80419
  };
80325
80420
 
@@ -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.405.1243";
947
+ var versionString = "Conway v1.409.1251";
948
948
 
949
949
  // compiled/dependencies/conway-geom/interface/conway_geometry.js
950
950
  var wasmType = "";
@@ -3501,8 +3501,8 @@ var StepParser = class extends StepHeaderParser {
3501
3501
  * @param onProgress Optional byte-cursor progress callback.
3502
3502
  * @return {BlockParseResult} The parsing result, including the index and result enum.
3503
3503
  */
3504
- parseDataBlockStreamed(input, onRecordBoundary, onRecordIndexed, onProgress) {
3505
- const parser211 = this.parseDataBlockIncremental(input, onRecordBoundary, onRecordIndexed);
3504
+ parseDataBlockStreamed(input, onRecordBoundary, onRecordIndexed, onProgress, sink) {
3505
+ const parser211 = this.parseDataBlockIncremental(input, onRecordBoundary, onRecordIndexed, sink);
3506
3506
  while (true) {
3507
3507
  const next = parser211.next();
3508
3508
  if (next.done === true) {
@@ -3548,8 +3548,14 @@ var StepParser = class extends StepHeaderParser {
3548
3548
  * @yields {number} The current byte cursor within the input buffer.
3549
3549
  * @return {BlockParseResult} The parsing result, including the index and result enum.
3550
3550
  */
3551
- *parseDataBlockIncremental(input, onRecordBoundary, onRecordIndexed) {
3551
+ *parseDataBlockIncremental(input, onRecordBoundary, onRecordIndexed, sink) {
3552
3552
  const indexResult = { elements: [] };
3553
+ let topLevelCount = 0;
3554
+ const pushEntry = sink !== void 0 ? (entry) => {
3555
+ sink.pushTopLevel(entry);
3556
+ } : (entry) => {
3557
+ indexResult.elements.push(entry);
3558
+ };
3553
3559
  const match = input.match;
3554
3560
  const comment = () => match(commentParser2);
3555
3561
  const whitespace = () => {
@@ -3725,8 +3731,9 @@ var StepParser = class extends StepHeaderParser {
3725
3731
  if (!charws(SEMICOLON)) {
3726
3732
  return syntaxError();
3727
3733
  }
3728
- onRecordIndexed?.(indexResult.elements.length, expressID, 0);
3729
- indexResult.elements.push({
3734
+ onRecordIndexed?.(topLevelCount, expressID, 0);
3735
+ ++topLevelCount;
3736
+ pushEntry({
3730
3737
  address: startElement2,
3731
3738
  length: input.address - startElement2,
3732
3739
  typeID: 0,
@@ -3817,8 +3824,9 @@ var StepParser = class extends StepHeaderParser {
3817
3824
  if (!charws(SEMICOLON)) {
3818
3825
  return syntaxError();
3819
3826
  }
3820
- onRecordIndexed?.(indexResult.elements.length, expressID, foundItem);
3821
- indexResult.elements.push({
3827
+ onRecordIndexed?.(topLevelCount, expressID, foundItem);
3828
+ ++topLevelCount;
3829
+ pushEntry({
3822
3830
  address: startElement,
3823
3831
  length: input.address - startElement,
3824
3832
  typeID: foundItem,
@@ -4998,6 +5006,31 @@ var StepModelBase = class {
4998
5006
  this.elementMemoization = true;
4999
5007
  this.nullOnErrors = true;
5000
5008
  this.bufferProvider_ = provider ?? new ResidentStepBufferProvider(buffer_);
5009
+ if (!Array.isArray(elementIndex)) {
5010
+ const columns = elementIndex;
5011
+ const firstInline = columns.firstInlineElement;
5012
+ const inlineCount = columns.count - firstInline;
5013
+ const inlineElementTable2 = new Uint32Array(inlineCount << 1);
5014
+ for (let where2 = 0; where2 < inlineCount; ++where2) {
5015
+ inlineElementTable2[where2 << 1] = firstInline + where2;
5016
+ inlineElementTable2[(where2 << 1) + 1] = columns.address[firstInline + where2];
5017
+ }
5018
+ this.inlineAddressMap_ = new InterpolationSearchTable32(inlineElementTable2, true);
5019
+ const expressIdTable2 = new Uint32Array(firstInline << 1);
5020
+ for (let where2 = 0; where2 < firstInline; ++where2) {
5021
+ expressIdTable2[where2 << 1] = where2;
5022
+ expressIdTable2[(where2 << 1) + 1] = columns.expressID[where2];
5023
+ }
5024
+ this.expressIDMap_ = new InterpolationSearchTable32(expressIdTable2, columns.expressIdsSorted);
5025
+ this.address_ = columns.address;
5026
+ this.length_ = columns.length;
5027
+ this.typeID_ = columns.typeID;
5028
+ this.expressID_ = columns.expressID;
5029
+ this.count_ = columns.count;
5030
+ this.firstInlineElement_ = firstInline;
5031
+ this.complexEntries_ = columns.complexEntries;
5032
+ return;
5033
+ }
5001
5034
  const localElementIndex = elementIndex;
5002
5035
  let where = 0;
5003
5036
  const firstInlineElement = localElementIndex.length;
@@ -70115,6 +70148,68 @@ var StepTypeIndexer = class {
70115
70148
  constructor(typeCount) {
70116
70149
  this.elementCounter_ = new Int32Array(typeCount << 1);
70117
70150
  }
70151
+ /**
70152
+ * Create a type index from either index form — the parsed object array or
70153
+ * the columnar index (M7).
70154
+ *
70155
+ * @param index The element index, object or columnar.
70156
+ * @return {MultiIndexSet} The created multi-set index.
70157
+ */
70158
+ createFor(index) {
70159
+ return Array.isArray(index) ? this.create(index) : this.createFromColumns(index);
70160
+ }
70161
+ /**
70162
+ * Create a type index straight from the columnar index — the same
70163
+ * membership `create` produces from the unfolded object array: every row's
70164
+ * concrete type (top-level + inline; −1 rows skipped) plus the
70165
+ * multi-mapping subtypes of retained complex entries at their parent's
70166
+ * dense index.
70167
+ *
70168
+ * @param columns The columnar index.
70169
+ * @return {MultiIndexSet} The created multi-set index.
70170
+ */
70171
+ createFromColumns(columns) {
70172
+ for (let where = 0, end = this.elementCounter_.length; where < end; where += 2) {
70173
+ initCountCompactedElements32State(this.elementCounter_, where);
70174
+ }
70175
+ const elementCounter = this.elementCounter_;
70176
+ const prefixSum = new Uint32Array((this.elementCounter_.length >>> 1) + 1);
70177
+ const typeIDs = columns.typeID;
70178
+ const count = columns.count;
70179
+ const walkRows = (addOne) => {
70180
+ const complexIterator = columns.complexEntries?.entries();
70181
+ let nextComplex = complexIterator?.next();
70182
+ for (let denseIndex = 0; denseIndex < count; ++denseIndex) {
70183
+ const typeID = typeIDs[denseIndex];
70184
+ if (typeID >= 0) {
70185
+ addOne(denseIndex, typeID);
70186
+ }
70187
+ if (nextComplex !== void 0 && !nextComplex.done && nextComplex.value[0] === denseIndex) {
70188
+ for (const subElement of nextComplex.value[1].multiMapping ?? []) {
70189
+ const subTypeID = subElement.typeID;
70190
+ if (subTypeID !== void 0) {
70191
+ addOne(denseIndex, subTypeID);
70192
+ }
70193
+ }
70194
+ nextComplex = complexIterator.next();
70195
+ }
70196
+ }
70197
+ };
70198
+ walkRows((denseIndex, typeID) => {
70199
+ prefixSum[typeID + 1] = addCompactedElementCount32State(denseIndex, elementCounter, typeID << 1);
70200
+ });
70201
+ for (let prefixSumIndex = 2, prefixSumEnd = prefixSum.length; prefixSumIndex < prefixSumEnd; ++prefixSumIndex) {
70202
+ prefixSum[prefixSumIndex] += prefixSum[prefixSumIndex - 1];
70203
+ }
70204
+ for (let where = 0, end = this.elementCounter_.length; where < end; where += 2) {
70205
+ initCountCompactedElements32State(this.elementCounter_, where);
70206
+ }
70207
+ const indexOutput = new Uint32Array(prefixSum[prefixSum.length - 1] << 1);
70208
+ walkRows((denseIndex, typeID) => {
70209
+ addCompactedElement32State(denseIndex, elementCounter, indexOutput, typeID << 1, prefixSum[typeID] << 1);
70210
+ });
70211
+ return new MultiIndexSet(prefixSum, indexOutput);
70212
+ }
70118
70213
  /**
70119
70214
  * Create a type index from a set of parsed STEP elements.
70120
70215
  *
@@ -70776,12 +70871,136 @@ var IfcStepModel = class extends StepModelBase {
70776
70871
  this.materials = new IfcMaterialCache(this);
70777
70872
  this.voidMaterials = new IfcMaterialCache(this, true);
70778
70873
  this.elementTypeIDs = entity_types_ifc_gen_default;
70779
- this.typeIndex = indexerInstance.create(elementIndex);
70874
+ this.typeIndex = indexerInstance.createFor(elementIndex);
70780
70875
  }
70781
70876
  };
70782
70877
 
70878
+ // compiled/src/step/parsing/columnar_index.js
70879
+ var COLUMN_UNDEFINED_TYPE = -1;
70880
+ var SEGMENT_ROWS = 64 * 1024;
70881
+ var ColumnarIndexSink = class {
70882
+ constructor() {
70883
+ this.segments_ = [];
70884
+ this.count_ = 0;
70885
+ this.retained_ = /* @__PURE__ */ new Map();
70886
+ this.expressIdsSorted_ = true;
70887
+ this.previousExpressID_ = 0;
70888
+ }
70889
+ /**
70890
+ * @return {number} Top-level records pushed so far.
70891
+ */
70892
+ get topLevelCount() {
70893
+ return this.count_;
70894
+ }
70895
+ /**
70896
+ * Encode one completed top-level record into the columns. The entry object
70897
+ * is not kept unless it carries children (inline entities / multi-mapping).
70898
+ *
70899
+ * @param entry The completed top-level index entry.
70900
+ */
70901
+ pushTopLevel(entry) {
70902
+ const localID = this.count_++;
70903
+ const segmentIndex = Math.floor(localID / SEGMENT_ROWS);
70904
+ const row = localID % SEGMENT_ROWS;
70905
+ if (segmentIndex === this.segments_.length) {
70906
+ this.segments_.push({
70907
+ address: new Uint32Array(SEGMENT_ROWS),
70908
+ length: new Uint32Array(SEGMENT_ROWS),
70909
+ typeID: new Int32Array(SEGMENT_ROWS),
70910
+ expressID: new Uint32Array(SEGMENT_ROWS)
70911
+ });
70912
+ }
70913
+ const segment = this.segments_[segmentIndex];
70914
+ segment.address[row] = entry.address;
70915
+ segment.length[row] = entry.length;
70916
+ segment.typeID[row] = entry.typeID === void 0 ? COLUMN_UNDEFINED_TYPE : entry.typeID;
70917
+ segment.expressID[row] = entry.expressID;
70918
+ if (entry.expressID < this.previousExpressID_) {
70919
+ this.expressIdsSorted_ = false;
70920
+ }
70921
+ this.previousExpressID_ = entry.expressID;
70922
+ if (entry.inlineEntities !== void 0 || entry.multiMapping !== void 0) {
70923
+ this.retained_.set(localID, entry);
70924
+ }
70925
+ }
70926
+ /**
70927
+ * Rewind to empty (the streaming builder's grow-and-restart). The first
70928
+ * segment is kept for reuse.
70929
+ */
70930
+ reset() {
70931
+ this.segments_.length = Math.min(this.segments_.length, 1);
70932
+ this.count_ = 0;
70933
+ this.retained_.clear();
70934
+ this.expressIdsSorted_ = true;
70935
+ this.previousExpressID_ = 0;
70936
+ }
70937
+ /**
70938
+ * Assemble the final columns: concatenate the top-level segments (one
70939
+ * column at a time, bounding transient overhead to a single column's
70940
+ * segments) and unfold retained inline entities into the inline range in
70941
+ * the model's exact unfold order.
70942
+ *
70943
+ * @return {StepIndexColumns} The finished columnar index.
70944
+ */
70945
+ finalize() {
70946
+ const topLevel = this.count_;
70947
+ const unfolded = [];
70948
+ for (const entry of this.retained_.values()) {
70949
+ if (entry.inlineEntities !== void 0) {
70950
+ unfolded.push(...entry.inlineEntities);
70951
+ }
70952
+ }
70953
+ for (let where = 0; where < unfolded.length; ++where) {
70954
+ const inlineEntities = unfolded[where].inlineEntities;
70955
+ if (inlineEntities !== void 0) {
70956
+ unfolded.push(...inlineEntities);
70957
+ }
70958
+ }
70959
+ const count = topLevel + unfolded.length;
70960
+ const address = concatColumn(this.segments_, "address", topLevel, count);
70961
+ const length = concatColumn(this.segments_, "length", topLevel, count);
70962
+ const typeID = new Int32Array(count);
70963
+ for (let segment = 0; segment * SEGMENT_ROWS < topLevel; ++segment) {
70964
+ const rows = Math.min(SEGMENT_ROWS, topLevel - segment * SEGMENT_ROWS);
70965
+ typeID.set(this.segments_[segment].typeID.subarray(0, rows), segment * SEGMENT_ROWS);
70966
+ }
70967
+ const expressID = concatColumn(this.segments_, "expressID", topLevel, topLevel);
70968
+ for (let where = 0; where < unfolded.length; ++where) {
70969
+ const entry = unfolded[where];
70970
+ const row = topLevel + where;
70971
+ address[row] = entry.address;
70972
+ length[row] = entry.length;
70973
+ typeID[row] = entry.typeID === void 0 ? COLUMN_UNDEFINED_TYPE : entry.typeID;
70974
+ }
70975
+ let complexEntries;
70976
+ for (const [localID, entry] of this.retained_) {
70977
+ if (entry.multiMapping !== void 0) {
70978
+ (complexEntries ??= /* @__PURE__ */ new Map()).set(localID, entry);
70979
+ }
70980
+ }
70981
+ return {
70982
+ address,
70983
+ length,
70984
+ typeID,
70985
+ expressID,
70986
+ count,
70987
+ firstInlineElement: topLevel,
70988
+ complexEntries,
70989
+ expressIdsSorted: this.expressIdsSorted_
70990
+ };
70991
+ }
70992
+ };
70993
+ function concatColumn(segments, column, rows, finalLength) {
70994
+ const result = new Uint32Array(finalLength);
70995
+ for (let segment = 0; segment * SEGMENT_ROWS < rows; ++segment) {
70996
+ const valid = Math.min(SEGMENT_ROWS, rows - segment * SEGMENT_ROWS);
70997
+ result.set(segments[segment][column].subarray(0, valid), segment * SEGMENT_ROWS);
70998
+ }
70999
+ return result;
71000
+ }
71001
+
70783
71002
  // compiled/src/step/parsing/streaming_index_builder.js
70784
- function buildIndexStreaming(source, parser211, pool3, onRecordIndexed) {
71003
+ function buildIndexStreaming(source, parser211, pool3, onRecordIndexed, sink) {
70785
71004
  const fileSize = source.byteLength;
70786
71005
  let windowBytes = Math.max(pool3, MIN_WINDOW);
70787
71006
  for (; ; ) {
@@ -70827,11 +71046,12 @@ function buildIndexStreaming(source, parser211, pool3, onRecordIndexed) {
70827
71046
  buffer.rebaseWindow(window2, 0, windowLen, windowStartFile);
70828
71047
  ++slides;
70829
71048
  };
70830
- const [index, result] = parser211.parseDataBlockStreamed(input, onRecordBoundary, onRecordIndexed);
71049
+ const [index, result] = parser211.parseDataBlockStreamed(input, onRecordBoundary, onRecordIndexed, void 0, sink);
70831
71050
  const stoppedShort = result !== ParseResult.COMPLETE;
70832
71051
  const notAtEof = windowStartFile + windowLen < fileSize;
70833
71052
  if (stoppedShort && notAtEof) {
70834
71053
  windowBytes *= 2;
71054
+ sink?.reset();
70835
71055
  continue;
70836
71056
  }
70837
71057
  const lastRecordLen = windowStartFile + input.cursor - prevBoundaryFile;
@@ -70847,6 +71067,11 @@ function buildIndexStreaming(source, parser211, pool3, onRecordIndexed) {
70847
71067
  }
70848
71068
  }
70849
71069
  var MIN_WINDOW = 4 * 1024;
71070
+ function buildColumnarIndexStreaming(source, parser211, pool3, onRecordIndexed) {
71071
+ const sink = new ColumnarIndexSink();
71072
+ const { header, result, stats } = buildIndexStreaming(source, parser211, pool3, onRecordIndexed, sink);
71073
+ return { header, columns: sink.finalize(), result, stats };
71074
+ }
70850
71075
 
70851
71076
  // compiled/src/ifc/ifc_step_parser.js
70852
71077
  var DEFAULT_STREAM_POOL_BYTES = 1024 * 1024;
@@ -70912,9 +71137,9 @@ var IfcStepParser = class extends StepParser {
70912
71137
  if (store.byteLength !== source.byteLength) {
70913
71138
  throw new Error(`Streaming store byteLength ${store.byteLength} does not match source byteLength ${source.byteLength}`);
70914
71139
  }
70915
- const { elements, result } = buildIndexStreaming(source, this, opts?.pool ?? DEFAULT_STREAM_POOL_BYTES);
71140
+ const { columns, result } = buildColumnarIndexStreaming(source, this, opts?.pool ?? DEFAULT_STREAM_POOL_BYTES);
70916
71141
  const provider = new WindowedStepBufferProvider(store, opts?.chunkBytes, opts?.maxResidentChunks);
70917
- return [result, new IfcStepModel(void 0, elements, provider)];
71142
+ return [result, new IfcStepModel(void 0, columns, provider)];
70918
71143
  }
70919
71144
  };
70920
71145
  IfcStepParser.Instance = new IfcStepParser();
@@ -1,6 +1,7 @@
1
1
  import EntityTypesAP214 from "./AP214E3_2010_gen/entity_types_ap214.gen.js";
2
2
  import StepModelBase from "../step/step_model_base.js";
3
3
  import { StepIndexEntry } from "../step/parsing/step_parser.js";
4
+ import { StepIndexColumns } from "../step/parsing/columnar_index.js";
4
5
  import { MultiIndexSet } from "../indexing/multi_index_set.js";
5
6
  import { AP214ModelGeometry } from "./ap214_model_geometry.js";
6
7
  import { AP214ModelProfile } from "./ap214_model_profile.js";
@@ -26,6 +27,6 @@ export default class AP214StepModel extends StepModelBase<EntityTypesAP214> {
26
27
  * @param buffer The buffer to values from.
27
28
  * @param elementIndex The parsed index to elements in the STEP.
28
29
  */
29
- constructor(buffer: Uint8Array, elementIndex: StepIndexEntry<EntityTypesAP214>[]);
30
+ constructor(buffer: Uint8Array, elementIndex: StepIndexEntry<EntityTypesAP214>[] | StepIndexColumns<EntityTypesAP214>);
30
31
  }
31
32
  //# sourceMappingURL=ap214_step_model.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ap214_step_model.d.ts","sourceRoot":"","sources":["../../../src/AP214E3_2010/ap214_step_model.ts"],"names":[],"mappings":"AAAA,OAAO,gBAAyC,MAAM,2CAA2C,CAAA;AACjG,OAAO,aAAa,MAAM,yBAAyB,CAAA;AAEnD,OAAO,EAAC,cAAc,EAAC,MAAM,6BAA6B,CAAA;AAE1D,OAAO,EAAC,aAAa,EAAC,MAAM,6BAA6B,CAAA;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAA;AACzD,OAAO,wBAAwB,MAAM,+BAA+B,CAAA;AACpE,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AAC3D,OAAO,gBAAgB,MAAM,sBAAsB,CAAA;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAKvD;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,cAAe,SAAQ,aAAa,CAAE,gBAAgB,CAAE;IAE3E,SAAgB,SAAS,EAAE,aAAa,CAAE,gBAAgB,CAAE,CAAA;IAC5D,SAAgB,mBAAmB,kCAA2B;IAC9D,SAAgB,QAAQ,qBAA2B;IACnD,SAAgB,SAAS,qBAA2B;IACpD,SAAgB,QAAQ,oBAA0B;IAClD,SAAgB,MAAM,mBAA6B;IACnD,SAAgB,aAAa,iBAAuB;IAEpD;;;;;;OAMG;gBAEC,MAAM,EAAE,UAAU,EAClB,YAAY,EAAE,cAAc,CAAE,gBAAgB,CAAE,EAAE;CAKvD"}
1
+ {"version":3,"file":"ap214_step_model.d.ts","sourceRoot":"","sources":["../../../src/AP214E3_2010/ap214_step_model.ts"],"names":[],"mappings":"AAAA,OAAO,gBAAyC,MAAM,2CAA2C,CAAA;AACjG,OAAO,aAAa,MAAM,yBAAyB,CAAA;AAEnD,OAAO,EAAC,cAAc,EAAC,MAAM,6BAA6B,CAAA;AAC1D,OAAO,EAAC,gBAAgB,EAAC,MAAM,gCAAgC,CAAA;AAE/D,OAAO,EAAC,aAAa,EAAC,MAAM,6BAA6B,CAAA;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAA;AACzD,OAAO,wBAAwB,MAAM,+BAA+B,CAAA;AACpE,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AAC3D,OAAO,gBAAgB,MAAM,sBAAsB,CAAA;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAKvD;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,cAAe,SAAQ,aAAa,CAAE,gBAAgB,CAAE;IAE3E,SAAgB,SAAS,EAAE,aAAa,CAAE,gBAAgB,CAAE,CAAA;IAC5D,SAAgB,mBAAmB,kCAA2B;IAC9D,SAAgB,QAAQ,qBAA2B;IACnD,SAAgB,SAAS,qBAA2B;IACpD,SAAgB,QAAQ,oBAA0B;IAClD,SAAgB,MAAM,mBAA6B;IACnD,SAAgB,aAAa,iBAAuB;IAEpD;;;;;;OAMG;gBAEC,MAAM,EAAE,UAAU,EAClB,YAAY,EAAE,cAAc,CAAE,gBAAgB,CAAE,EAAE,GAAG,gBAAgB,CAAE,gBAAgB,CAAE;CAK9F"}
@@ -28,6 +28,6 @@ export default class AP214StepModel extends StepModelBase {
28
28
  this.profiles = new AP214ModelProfile();
29
29
  this.curves = new AP214ModelCurves(this);
30
30
  this.csgOperations = new CsgMemoization();
31
- this.typeIndex = indexerInstance.create(elementIndex);
31
+ this.typeIndex = indexerInstance.createFor(elementIndex);
32
32
  }
33
33
  }
@@ -0,0 +1,99 @@
1
+ import { GeometryTiles } from "./demand_geometry_queue.js";
2
+ import { ChunkedPool } from "./mem/chunked_pool.js";
3
+ import { SharedAssetPool } from "./mem/shared_asset_pool.js";
4
+ /**
5
+ * One shareable geometry payload an instance needs resident: the asset's
6
+ * identity and its byte size. For IFC, the asset is a representation's
7
+ * tessellated geometry and `byteSize` comes from the wasm-side extract.
8
+ */
9
+ export interface GeometryAsset<AssetID> {
10
+ assetID: AssetID;
11
+ byteSize: number;
12
+ }
13
+ /**
14
+ * The domain half the tile pool delegates to: what assets an instance is made
15
+ * of, and how to materialise / discard one asset's payload. This is the seam
16
+ * the production conway-geom surface implements (extract → tessellate into
17
+ * the asset's chunks; discard on last release); tests implement it with
18
+ * recording mocks.
19
+ */
20
+ export interface InstanceAssetSource<AssetID> {
21
+ /**
22
+ * The assets an instance requires resident, with their byte sizes. For a
23
+ * simple product this is one asset; mapped/instanced representations return
24
+ * the same assetID from many instances — that sharing is the point.
25
+ *
26
+ * @param instanceID The instance (product local ID in the geometry case).
27
+ * @return {GeometryAsset<AssetID>[]} The instance's assets.
28
+ */
29
+ assetsOf(instanceID: number): GeometryAsset<AssetID>[];
30
+ /**
31
+ * Materialise an asset's payload (called exactly once per residency, on
32
+ * the 0→1 reference). In production: run the wasm extract/tessellate and
33
+ * write the result into the asset's pool chunks.
34
+ *
35
+ * @param assetID The asset to materialise.
36
+ */
37
+ materialize(assetID: AssetID): void;
38
+ /**
39
+ * Discard an asset's payload (called exactly once per residency, on the
40
+ * 1→0 reference, after its chunks are already back in the pool).
41
+ *
42
+ * @param assetID The asset to discard.
43
+ */
44
+ discard(assetID: AssetID): void;
45
+ }
46
+ /**
47
+ * The geometry narrowing of the general memory system (`src/core/mem/`): a
48
+ * {@link GeometryTiles} backend where a product's "tile" is a set of
49
+ * refcounted, chunk-resident **assets** in a {@link SharedAssetPool}.
50
+ *
51
+ * Composed with {@link DemandGeometryQueue} this completes the M3 resident
52
+ * design: the queue owns demand ordering and the logical budget; this pool
53
+ * owns physical residency. Two accounting views, one invariant:
54
+ *
55
+ * - **Logical (queue-side):** `extract` charges an instance the full
56
+ * chunk-rounded cost of *every* asset it references, shared or not. Sharing
57
+ * is thus double-charged logically — deliberately conservative: summed
58
+ * logical charges always cover physical use, so with the queue's budget set
59
+ * to the pool's budget, an acquire can never fail mid-extract. (Heavy
60
+ * sharing under-utilises the logical budget; the production wiring can
61
+ * widen the queue budget once measured. The safe direction first.)
62
+ * - **Physical (pool-side):** `bytesInUse` counts real chunks. Shared assets
63
+ * are stored once, refcounted, and freed only on the last release — so
64
+ * evicting product A never discards the representation product B still
65
+ * renders (the mapped-item correctness rule, held structurally).
66
+ */
67
+ export declare class GeometryTilePool<AssetID> implements GeometryTiles {
68
+ private readonly assets_;
69
+ private readonly source_;
70
+ /** Assets each extracted instance holds references on. */
71
+ private readonly held_;
72
+ /**
73
+ * @param pool The chunk pool residents live in.
74
+ * @param source The domain half (asset composition + materialise/discard).
75
+ */
76
+ constructor(pool: ChunkedPool, source: InstanceAssetSource<AssetID>);
77
+ /**
78
+ * @return {SharedAssetPool<AssetID>} The refcounted asset layer (physical
79
+ * accounting lives here / on its pool).
80
+ */
81
+ get assets(): SharedAssetPool<AssetID>;
82
+ /**
83
+ * Materialise an instance's tile: take a reference on each of its assets,
84
+ * materialising the ones not yet resident.
85
+ *
86
+ * @param instanceID The instance (product local ID).
87
+ * @return {number} The instance's logical byte cost (chunk-rounded, every
88
+ * asset fully charged — see class docs for why sharing is double-charged).
89
+ */
90
+ extract(instanceID: number): number;
91
+ /**
92
+ * Release an instance's tile: drop the reference on each of its assets,
93
+ * discarding those this instance was the last holder of.
94
+ *
95
+ * @param instanceID The instance (product local ID).
96
+ */
97
+ release(instanceID: number): void;
98
+ }
99
+ //# sourceMappingURL=geometry_tile_pool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"geometry_tile_pool.d.ts","sourceRoot":"","sources":["../../../src/core/geometry_tile_pool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAA;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AAGzD;;;;GAIG;AACH,MAAM,WAAW,aAAa,CAAC,OAAO;IACpC,OAAO,EAAE,OAAO,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAGD;;;;;;GAMG;AACH,MAAM,WAAW,mBAAmB,CAAC,OAAO;IAE1C;;;;;;;OAOG;IACH,QAAQ,CAAE,UAAU,EAAE,MAAM,GAAI,aAAa,CAAC,OAAO,CAAC,EAAE,CAAA;IAExD;;;;;;OAMG;IACH,WAAW,CAAE,OAAO,EAAE,OAAO,GAAI,IAAI,CAAA;IAErC;;;;;OAKG;IACH,OAAO,CAAE,OAAO,EAAE,OAAO,GAAI,IAAI,CAAA;CAClC;AAGD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAAa,gBAAgB,CAAC,OAAO,CAAE,YAAW,aAAa;IAE7D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA0B;IAElD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA8B;IAEtD,0DAA0D;IAC1D,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA8C;IAEpE;;;OAGG;gBACU,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,mBAAmB,CAAC,OAAO,CAAC;IAKpE;;;OAGG;IACH,IAAW,MAAM,IAAI,eAAe,CAAC,OAAO,CAAC,CAE5C;IAED;;;;;;;OAOG;IACI,OAAO,CAAE,UAAU,EAAE,MAAM,GAAI,MAAM;IAoD5C;;;;;OAKG;IACI,OAAO,CAAE,UAAU,EAAE,MAAM,GAAI,IAAI;CAgB3C"}