@bldrs-ai/conway 1.408.1248 → 1.413.1255
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/Dist/ConwayGeomWasmNode.js +0 -0
- package/compiled/Dist/ConwayGeomWasmNodeMT.js +0 -0
- package/compiled/Dist/ConwayGeomWasmWeb.js +0 -0
- package/compiled/Dist/ConwayGeomWasmWebMT.js +1 -1
- package/compiled/Dist/ConwayGeomWasmWebMT.wasm +0 -0
- package/compiled/dependencies/conway-geom/Dist/ConwayGeomWasmNode.js +0 -0
- package/compiled/dependencies/conway-geom/Dist/ConwayGeomWasmNodeMT.js +0 -0
- package/compiled/dependencies/conway-geom/Dist/ConwayGeomWasmWeb.js +0 -0
- package/compiled/dependencies/conway-geom/Dist/ConwayGeomWasmWebMT.js +1 -1
- package/compiled/dependencies/conway-geom/Dist/ConwayGeomWasmWebMT.wasm +0 -0
- package/compiled/examples/browser-bundled.cjs +238 -13
- package/compiled/examples/cli-bundled.cjs +265 -40
- package/compiled/examples/cli-step-bundled.cjs +131 -36
- package/compiled/examples/validator-bundled.cjs +238 -13
- package/compiled/src/AP214E3_2010/ap214_step_model.d.ts +2 -1
- package/compiled/src/AP214E3_2010/ap214_step_model.d.ts.map +1 -1
- package/compiled/src/AP214E3_2010/ap214_step_model.js +1 -1
- package/compiled/src/core/demand_residency_pump.d.ts +93 -0
- package/compiled/src/core/demand_residency_pump.d.ts.map +1 -0
- package/compiled/src/core/demand_residency_pump.js +120 -0
- package/compiled/src/core/demand_residency_pump.test.d.ts +2 -0
- package/compiled/src/core/demand_residency_pump.test.d.ts.map +1 -0
- package/compiled/src/core/demand_residency_pump.test.js +148 -0
- package/compiled/src/core/geometry_tile_bindings.d.ts +110 -0
- package/compiled/src/core/geometry_tile_bindings.d.ts.map +1 -0
- package/compiled/src/core/geometry_tile_bindings.js +76 -0
- package/compiled/src/core/geometry_tile_bindings.test.d.ts +2 -0
- package/compiled/src/core/geometry_tile_bindings.test.d.ts.map +1 -0
- package/compiled/src/core/geometry_tile_bindings.test.js +211 -0
- package/compiled/src/ifc/ifc_step_model.d.ts +2 -1
- package/compiled/src/ifc/ifc_step_model.d.ts.map +1 -1
- package/compiled/src/ifc/ifc_step_model.js +1 -1
- package/compiled/src/ifc/ifc_step_parser.d.ts.map +1 -1
- package/compiled/src/ifc/ifc_step_parser.js +5 -3
- package/compiled/src/step/indexing/step_type_indexer.d.ts +20 -0
- package/compiled/src/step/indexing/step_type_indexer.d.ts.map +1 -1
- package/compiled/src/step/indexing/step_type_indexer.js +67 -0
- package/compiled/src/step/parsing/columnar_index.d.ts +81 -0
- package/compiled/src/step/parsing/columnar_index.d.ts.map +1 -0
- package/compiled/src/step/parsing/columnar_index.js +159 -0
- package/compiled/src/step/parsing/columnar_index.test.d.ts +2 -0
- package/compiled/src/step/parsing/columnar_index.test.d.ts.map +1 -0
- package/compiled/src/step/parsing/columnar_index.test.js +155 -0
- package/compiled/src/step/parsing/index_sidecar.d.ts +28 -0
- package/compiled/src/step/parsing/index_sidecar.d.ts.map +1 -1
- package/compiled/src/step/parsing/index_sidecar.js +117 -0
- package/compiled/src/step/parsing/index_sidecar.test.js +31 -1
- package/compiled/src/step/parsing/step_parser.d.ts +22 -1
- package/compiled/src/step/parsing/step_parser.d.ts.map +1 -1
- package/compiled/src/step/parsing/step_parser.js +19 -7
- package/compiled/src/step/parsing/streaming_index_builder.d.ts +29 -2
- package/compiled/src/step/parsing/streaming_index_builder.d.ts.map +1 -1
- package/compiled/src/step/parsing/streaming_index_builder.js +23 -2
- package/compiled/src/step/step_model_base.d.ts +2 -1
- package/compiled/src/step/step_model_base.d.ts.map +1 -1
- package/compiled/src/step/step_model_base.js +31 -0
- package/compiled/src/version/version.js +1 -1
- package/compiled/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -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.
|
|
947
|
+
var versionString = "Conway v1.413.1255";
|
|
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?.(
|
|
3729
|
-
|
|
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?.(
|
|
3821
|
-
|
|
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.
|
|
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 {
|
|
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,
|
|
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;
|
|
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.
|
|
31
|
+
this.typeIndex = indexerInstance.createFor(elementIndex);
|
|
32
32
|
}
|
|
33
33
|
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { DemandGeometryQueue } from "./demand_geometry_queue.js";
|
|
2
|
+
/**
|
|
3
|
+
* The async half of demand-driven geometry (Phase B): source-byte residency.
|
|
4
|
+
*
|
|
5
|
+
* Extraction is synchronous by design (the wasm extract reads source bytes
|
|
6
|
+
* through `StepBufferProvider.acquire`), but a windowed/streamed source pages
|
|
7
|
+
* bytes in asynchronously (`ensureResident`). This pump owns that seam: it
|
|
8
|
+
* admits demand, prefetches the source ranges for the most-wanted products,
|
|
9
|
+
* and only then forwards them to the synchronous {@link DemandGeometryQueue}
|
|
10
|
+
* — so a `pump()` never hits a non-resident range mid-extract.
|
|
11
|
+
*/
|
|
12
|
+
export interface ResidencyPrefetcher {
|
|
13
|
+
/**
|
|
14
|
+
* Page in the source byte ranges a product's extraction will read.
|
|
15
|
+
* `StepModelBase.ensureResidentByLocalID` satisfies this shape.
|
|
16
|
+
*
|
|
17
|
+
* @param localID The product's local ID.
|
|
18
|
+
* @return {Promise<void>} Resolves when resident.
|
|
19
|
+
*/
|
|
20
|
+
ensureResidentByLocalID(localID: number): Promise<void>;
|
|
21
|
+
}
|
|
22
|
+
/** Outcome of one pump cycle, for telemetry and tests. */
|
|
23
|
+
export interface PumpResult {
|
|
24
|
+
/** Tiles extracted this cycle (from the queue's pump). */
|
|
25
|
+
extracted: number;
|
|
26
|
+
/** Products whose prefetch failed this cycle (re-queued for retry). */
|
|
27
|
+
prefetchFailures: number;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Admission + prefetch orchestration in front of a {@link DemandGeometryQueue}.
|
|
31
|
+
*
|
|
32
|
+
* Consumers `request()` products as demand changes (the pump owns admission —
|
|
33
|
+
* don't request on the queue directly); each async `pump()` cycle:
|
|
34
|
+
*
|
|
35
|
+
* 1. selects the top-priority pending batch,
|
|
36
|
+
* 2. awaits source residency for the batch (failures re-queue for retry
|
|
37
|
+
* and are reported, never thrown — one bad range must not stall the
|
|
38
|
+
* viewport),
|
|
39
|
+
* 3. forwards the resident products to the queue and runs its synchronous
|
|
40
|
+
* pump under the same batch cap.
|
|
41
|
+
*
|
|
42
|
+
* Re-entrant calls coalesce: a `pump()` while one is in flight returns the
|
|
43
|
+
* in-flight cycle's promise rather than interleaving prefetch batches.
|
|
44
|
+
* Products already resident in the queue skip prefetch entirely (their
|
|
45
|
+
* ranking refresh is forwarded immediately).
|
|
46
|
+
*/
|
|
47
|
+
export declare class DemandResidencyPump {
|
|
48
|
+
private readonly queue_;
|
|
49
|
+
private readonly prefetcher_;
|
|
50
|
+
private readonly batch_;
|
|
51
|
+
/** Pending admission: product localID → highest requested priority. */
|
|
52
|
+
private readonly pending_;
|
|
53
|
+
private inFlight_;
|
|
54
|
+
/**
|
|
55
|
+
* @param queue_ The synchronous demand queue (extraction + budget).
|
|
56
|
+
* @param prefetcher_ Source-byte residency (the model / buffer provider).
|
|
57
|
+
* @param batch_ Max products prefetched + extracted per pump cycle.
|
|
58
|
+
*/
|
|
59
|
+
constructor(queue_: DemandGeometryQueue, prefetcher_: ResidencyPrefetcher, batch_?: number);
|
|
60
|
+
/**
|
|
61
|
+
* Request a product at a demand priority. Resident products forward
|
|
62
|
+
* immediately (ranking refresh); others queue for the next pump cycle at
|
|
63
|
+
* the highest priority requested so far.
|
|
64
|
+
*
|
|
65
|
+
* @param productLocalID The product to materialise.
|
|
66
|
+
* @param priority The demand priority (higher = more wanted).
|
|
67
|
+
*/
|
|
68
|
+
request(productLocalID: number, priority: number): void;
|
|
69
|
+
/**
|
|
70
|
+
* @return {number} Products awaiting admission (not yet prefetched).
|
|
71
|
+
*/
|
|
72
|
+
get pendingCount(): number;
|
|
73
|
+
/**
|
|
74
|
+
* Run one admission cycle (see class docs). Coalesces with an in-flight
|
|
75
|
+
* cycle.
|
|
76
|
+
*
|
|
77
|
+
* @return {Promise<PumpResult>} The cycle's outcome.
|
|
78
|
+
*/
|
|
79
|
+
pump(): Promise<PumpResult>;
|
|
80
|
+
/**
|
|
81
|
+
* One cycle: select top batch → prefetch → forward + queue pump.
|
|
82
|
+
*
|
|
83
|
+
* @return {Promise<PumpResult>} The cycle's outcome.
|
|
84
|
+
*/
|
|
85
|
+
private pumpCycle_;
|
|
86
|
+
/**
|
|
87
|
+
* Remove and return the top-priority pending entries, up to the batch cap.
|
|
88
|
+
*
|
|
89
|
+
* @return {[number, number][]} `[productLocalID, priority]` pairs.
|
|
90
|
+
*/
|
|
91
|
+
private takeTopPending_;
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=demand_residency_pump.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"demand_residency_pump.d.ts","sourceRoot":"","sources":["../../../src/core/demand_residency_pump.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAA;AAG7D;;;;;;;;;GASG;AACH,MAAM,WAAW,mBAAmB;IAElC;;;;;;OAMG;IACH,uBAAuB,CAAE,OAAO,EAAE,MAAM,GAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CAC1D;AAGD,0DAA0D;AAC1D,MAAM,WAAW,UAAU;IAEzB,0DAA0D;IAC1D,SAAS,EAAE,MAAM,CAAA;IAEjB,uEAAuE;IACvE,gBAAgB,EAAE,MAAM,CAAA;CACzB;AASD;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,mBAAmB;IAa5B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,MAAM;IAbzB,uEAAuE;IACvE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA4B;IAErD,OAAO,CAAC,SAAS,CAAiC;IAElD;;;;OAIG;gBAEgB,MAAM,EAAE,mBAAmB,EAC3B,WAAW,EAAE,mBAAmB,EAChC,MAAM,GAAE,MAAsB;IAOjD;;;;;;;OAOG;IACI,OAAO,CAAE,cAAc,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAI,IAAI;IAchE;;OAEG;IACH,IAAW,YAAY,IAAI,MAAM,CAEhC;IAED;;;;;OAKG;IACI,IAAI,IAAI,OAAO,CAAC,UAAU,CAAC;IAalC;;;;OAIG;YACW,UAAU;IAkCxB;;;;OAIG;IACH,OAAO,CAAC,eAAe;CAkBxB"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
// Defaults chosen for frame-cooperative pumping: enough per cycle to fill
|
|
2
|
+
// quickly, small enough that a cycle stays well under a frame budget once
|
|
3
|
+
// extraction costs are real. Both are tunable per call site.
|
|
4
|
+
const DEFAULT_BATCH = 32;
|
|
5
|
+
/**
|
|
6
|
+
* Admission + prefetch orchestration in front of a {@link DemandGeometryQueue}.
|
|
7
|
+
*
|
|
8
|
+
* Consumers `request()` products as demand changes (the pump owns admission —
|
|
9
|
+
* don't request on the queue directly); each async `pump()` cycle:
|
|
10
|
+
*
|
|
11
|
+
* 1. selects the top-priority pending batch,
|
|
12
|
+
* 2. awaits source residency for the batch (failures re-queue for retry
|
|
13
|
+
* and are reported, never thrown — one bad range must not stall the
|
|
14
|
+
* viewport),
|
|
15
|
+
* 3. forwards the resident products to the queue and runs its synchronous
|
|
16
|
+
* pump under the same batch cap.
|
|
17
|
+
*
|
|
18
|
+
* Re-entrant calls coalesce: a `pump()` while one is in flight returns the
|
|
19
|
+
* in-flight cycle's promise rather than interleaving prefetch batches.
|
|
20
|
+
* Products already resident in the queue skip prefetch entirely (their
|
|
21
|
+
* ranking refresh is forwarded immediately).
|
|
22
|
+
*/
|
|
23
|
+
export class DemandResidencyPump {
|
|
24
|
+
/**
|
|
25
|
+
* @param queue_ The synchronous demand queue (extraction + budget).
|
|
26
|
+
* @param prefetcher_ Source-byte residency (the model / buffer provider).
|
|
27
|
+
* @param batch_ Max products prefetched + extracted per pump cycle.
|
|
28
|
+
*/
|
|
29
|
+
constructor(queue_, prefetcher_, batch_ = DEFAULT_BATCH) {
|
|
30
|
+
this.queue_ = queue_;
|
|
31
|
+
this.prefetcher_ = prefetcher_;
|
|
32
|
+
this.batch_ = batch_;
|
|
33
|
+
/** Pending admission: product localID → highest requested priority. */
|
|
34
|
+
this.pending_ = new Map();
|
|
35
|
+
if (batch_ < 1) {
|
|
36
|
+
throw new Error(`Invalid batch ${batch_}`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Request a product at a demand priority. Resident products forward
|
|
41
|
+
* immediately (ranking refresh); others queue for the next pump cycle at
|
|
42
|
+
* the highest priority requested so far.
|
|
43
|
+
*
|
|
44
|
+
* @param productLocalID The product to materialise.
|
|
45
|
+
* @param priority The demand priority (higher = more wanted).
|
|
46
|
+
*/
|
|
47
|
+
request(productLocalID, priority) {
|
|
48
|
+
if (this.queue_.isResident(productLocalID)) {
|
|
49
|
+
this.queue_.request(productLocalID, priority);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
const existing = this.pending_.get(productLocalID);
|
|
53
|
+
this.pending_.set(productLocalID, existing === void 0 ? priority : Math.max(existing, priority));
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* @return {number} Products awaiting admission (not yet prefetched).
|
|
57
|
+
*/
|
|
58
|
+
get pendingCount() {
|
|
59
|
+
return this.pending_.size;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Run one admission cycle (see class docs). Coalesces with an in-flight
|
|
63
|
+
* cycle.
|
|
64
|
+
*
|
|
65
|
+
* @return {Promise<PumpResult>} The cycle's outcome.
|
|
66
|
+
*/
|
|
67
|
+
pump() {
|
|
68
|
+
if (this.inFlight_ !== void 0) {
|
|
69
|
+
return this.inFlight_;
|
|
70
|
+
}
|
|
71
|
+
this.inFlight_ = this.pumpCycle_().finally(() => {
|
|
72
|
+
this.inFlight_ = void 0;
|
|
73
|
+
});
|
|
74
|
+
return this.inFlight_;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* One cycle: select top batch → prefetch → forward + queue pump.
|
|
78
|
+
*
|
|
79
|
+
* @return {Promise<PumpResult>} The cycle's outcome.
|
|
80
|
+
*/
|
|
81
|
+
async pumpCycle_() {
|
|
82
|
+
const batch = this.takeTopPending_();
|
|
83
|
+
if (batch.length === 0) {
|
|
84
|
+
// Nothing to admit; still give the queue a chance to fill from its own
|
|
85
|
+
// pending set (e.g. entries deferred by an earlier budget refusal).
|
|
86
|
+
return { extracted: this.queue_.pump(this.batch_), prefetchFailures: 0 };
|
|
87
|
+
}
|
|
88
|
+
const outcomes = await Promise.allSettled(batch.map(([productLocalID]) => this.prefetcher_.ensureResidentByLocalID(productLocalID)));
|
|
89
|
+
let prefetchFailures = 0;
|
|
90
|
+
for (let where = 0; where < batch.length; ++where) {
|
|
91
|
+
const [productLocalID, priority] = batch[where];
|
|
92
|
+
if (outcomes[where].status === 'fulfilled') {
|
|
93
|
+
this.queue_.request(productLocalID, priority);
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
// Failed prefetch: re-queue for a later cycle (transient store errors
|
|
97
|
+
// retry; persistent ones keep surfacing in the failure count).
|
|
98
|
+
++prefetchFailures;
|
|
99
|
+
this.request(productLocalID, priority);
|
|
100
|
+
}
|
|
101
|
+
return { extracted: this.queue_.pump(this.batch_), prefetchFailures };
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Remove and return the top-priority pending entries, up to the batch cap.
|
|
105
|
+
*
|
|
106
|
+
* @return {[number, number][]} `[productLocalID, priority]` pairs.
|
|
107
|
+
*/
|
|
108
|
+
takeTopPending_() {
|
|
109
|
+
if (this.pending_.size === 0) {
|
|
110
|
+
return [];
|
|
111
|
+
}
|
|
112
|
+
const entries = [...this.pending_.entries()];
|
|
113
|
+
entries.sort((a, b) => b[1] - a[1]);
|
|
114
|
+
const batch = entries.slice(0, this.batch_);
|
|
115
|
+
for (const [productLocalID] of batch) {
|
|
116
|
+
this.pending_.delete(productLocalID);
|
|
117
|
+
}
|
|
118
|
+
return batch;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"demand_residency_pump.test.d.ts","sourceRoot":"","sources":["../../../src/core/demand_residency_pump.test.ts"],"names":[],"mappings":""}
|