@ifc-lite/data 1.15.1 → 1.17.0
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/README.md +58 -28
- package/dist/entity-table.d.ts +53 -0
- package/dist/entity-table.d.ts.map +1 -1
- package/dist/entity-table.js +147 -93
- package/dist/entity-table.js.map +1 -1
- package/dist/ifc-schema/generated/attributes.d.ts +10 -0
- package/dist/ifc-schema/generated/attributes.d.ts.map +1 -0
- package/dist/ifc-schema/generated/attributes.js +2775 -0
- package/dist/ifc-schema/generated/attributes.js.map +1 -0
- package/dist/ifc-schema/generated/data-types.d.ts +8 -0
- package/dist/ifc-schema/generated/data-types.d.ts.map +1 -0
- package/dist/ifc-schema/generated/data-types.js +396 -0
- package/dist/ifc-schema/generated/data-types.js.map +1 -0
- package/dist/ifc-schema/generated/entities-ifc2x3.d.ts +8 -0
- package/dist/ifc-schema/generated/entities-ifc2x3.d.ts.map +1 -0
- package/dist/ifc-schema/generated/entities-ifc2x3.js +777 -0
- package/dist/ifc-schema/generated/entities-ifc2x3.js.map +1 -0
- package/dist/ifc-schema/generated/entities-ifc4.d.ts +8 -0
- package/dist/ifc-schema/generated/entities-ifc4.d.ts.map +1 -0
- package/dist/ifc-schema/generated/entities-ifc4.js +938 -0
- package/dist/ifc-schema/generated/entities-ifc4.js.map +1 -0
- package/dist/ifc-schema/generated/entities-ifc4x3.d.ts +8 -0
- package/dist/ifc-schema/generated/entities-ifc4x3.d.ts.map +1 -0
- package/dist/ifc-schema/generated/entities-ifc4x3.js +1014 -0
- package/dist/ifc-schema/generated/entities-ifc4x3.js.map +1 -0
- package/dist/ifc-schema/generated/partof-relations.d.ts +10 -0
- package/dist/ifc-schema/generated/partof-relations.d.ts.map +1 -0
- package/dist/ifc-schema/generated/partof-relations.js +28 -0
- package/dist/ifc-schema/generated/partof-relations.js.map +1 -0
- package/dist/ifc-schema/generated/psets-ifc2x3.d.ts +8 -0
- package/dist/ifc-schema/generated/psets-ifc2x3.d.ts.map +1 -0
- package/dist/ifc-schema/generated/psets-ifc2x3.js +3416 -0
- package/dist/ifc-schema/generated/psets-ifc2x3.js.map +1 -0
- package/dist/ifc-schema/generated/psets-ifc4.d.ts +8 -0
- package/dist/ifc-schema/generated/psets-ifc4.d.ts.map +1 -0
- package/dist/ifc-schema/generated/psets-ifc4.js +4510 -0
- package/dist/ifc-schema/generated/psets-ifc4.js.map +1 -0
- package/dist/ifc-schema/generated/psets-ifc4x3.d.ts +8 -0
- package/dist/ifc-schema/generated/psets-ifc4x3.d.ts.map +1 -0
- package/dist/ifc-schema/generated/psets-ifc4x3.js +8554 -0
- package/dist/ifc-schema/generated/psets-ifc4x3.js.map +1 -0
- package/dist/ifc-schema/index.d.ts +61 -0
- package/dist/ifc-schema/index.d.ts.map +1 -0
- package/dist/ifc-schema/index.js +212 -0
- package/dist/ifc-schema/index.js.map +1 -0
- package/dist/ifc-schema/types.d.ts +108 -0
- package/dist/ifc-schema/types.d.ts.map +1 -0
- package/dist/ifc-schema/types.js +5 -0
- package/dist/ifc-schema/types.js.map +1 -0
- package/dist/index.d.ts +11 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -4
- package/dist/index.js.map +1 -1
- package/dist/property-table.d.ts +22 -0
- package/dist/property-table.d.ts.map +1 -1
- package/dist/property-table.js +89 -62
- package/dist/property-table.js.map +1 -1
- package/dist/quantity-table.d.ts +18 -0
- package/dist/quantity-table.d.ts.map +1 -1
- package/dist/quantity-table.js +80 -66
- package/dist/quantity-table.js.map +1 -1
- package/dist/relationship-graph.d.ts +53 -6
- package/dist/relationship-graph.d.ts.map +1 -1
- package/dist/relationship-graph.js +149 -113
- package/dist/relationship-graph.js.map +1 -1
- package/dist/string-table.d.ts +8 -0
- package/dist/string-table.d.ts.map +1 -1
- package/dist/string-table.js +20 -0
- package/dist/string-table.js.map +1 -1
- package/dist/utf8-decode.d.ts +24 -0
- package/dist/utf8-decode.d.ts.map +1 -0
- package/dist/utf8-decode.js +103 -0
- package/dist/utf8-decode.js.map +1 -0
- package/package.json +3 -2
|
@@ -25,122 +25,158 @@ export class RelationshipGraphBuilder {
|
|
|
25
25
|
}
|
|
26
26
|
build() {
|
|
27
27
|
const n = this._sources.length;
|
|
28
|
-
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
const inverse = this.buildCSR(n, this._targets, this._sources, this._types, this._relIds);
|
|
32
|
-
return {
|
|
33
|
-
forward,
|
|
34
|
-
inverse,
|
|
35
|
-
getRelated: (entityId, relType, direction) => {
|
|
36
|
-
const edges = direction === 'forward'
|
|
37
|
-
? forward.getEdges(entityId, relType)
|
|
38
|
-
: inverse.getEdges(entityId, relType);
|
|
39
|
-
return edges.map((e) => e.target);
|
|
40
|
-
},
|
|
41
|
-
hasRelationship: (sourceId, targetId, relType) => {
|
|
42
|
-
const edges = forward.getEdges(sourceId, relType);
|
|
43
|
-
return edges.some((e) => e.target === targetId);
|
|
44
|
-
},
|
|
45
|
-
getRelationshipsBetween: (sourceId, targetId) => {
|
|
46
|
-
const edges = forward.getEdges(sourceId);
|
|
47
|
-
return edges
|
|
48
|
-
.filter((e) => e.target === targetId)
|
|
49
|
-
.map((e) => ({
|
|
50
|
-
relationshipId: e.relationshipId,
|
|
51
|
-
type: e.type,
|
|
52
|
-
typeName: RelationshipTypeToString(e.type),
|
|
53
|
-
}));
|
|
54
|
-
},
|
|
55
|
-
};
|
|
28
|
+
const forward = buildCSR(n, this._sources, this._targets, this._types, this._relIds);
|
|
29
|
+
const inverse = buildCSR(n, this._targets, this._sources, this._types, this._relIds);
|
|
30
|
+
return relationshipGraphFromEdges(forward, inverse);
|
|
56
31
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
// Step 3: Place edges into sorted positions (counting sort scatter)
|
|
85
|
-
const edgeTargets = new Uint32Array(n);
|
|
86
|
-
const edgeTypes = new Uint16Array(n);
|
|
87
|
-
const edgeRelIds = new Uint32Array(n);
|
|
88
|
-
// Track current write position per key
|
|
89
|
-
const writePos = new Map();
|
|
90
|
-
for (const [k, o] of offsets) {
|
|
91
|
-
writePos.set(k, o);
|
|
92
|
-
}
|
|
93
|
-
for (let i = 0; i < n; i++) {
|
|
94
|
-
const k = keys[i];
|
|
95
|
-
const pos = writePos.get(k);
|
|
96
|
-
edgeTargets[pos] = values[i];
|
|
97
|
-
edgeTypes[pos] = types[i];
|
|
98
|
-
edgeRelIds[pos] = relIds[i];
|
|
99
|
-
writePos.set(k, pos + 1);
|
|
100
|
-
}
|
|
101
|
-
return {
|
|
102
|
-
offsets,
|
|
103
|
-
counts,
|
|
104
|
-
edgeTargets,
|
|
105
|
-
edgeTypes,
|
|
106
|
-
edgeRelIds,
|
|
107
|
-
getEdges(entityId, type) {
|
|
108
|
-
const o = offsets.get(entityId);
|
|
109
|
-
if (o === undefined)
|
|
110
|
-
return [];
|
|
111
|
-
const c = counts.get(entityId);
|
|
112
|
-
const edges = [];
|
|
113
|
-
for (let i = o; i < o + c; i++) {
|
|
114
|
-
if (type === undefined || edgeTypes[i] === type) {
|
|
115
|
-
edges.push({
|
|
116
|
-
target: edgeTargets[i],
|
|
117
|
-
type: edgeTypes[i],
|
|
118
|
-
relationshipId: edgeRelIds[i],
|
|
119
|
-
});
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
return edges;
|
|
123
|
-
},
|
|
124
|
-
getTargets(entityId, type) {
|
|
125
|
-
return this.getEdges(entityId, type).map(e => e.target);
|
|
126
|
-
},
|
|
127
|
-
hasAnyEdges(entityId) {
|
|
128
|
-
return offsets.has(entityId);
|
|
129
|
-
},
|
|
130
|
-
};
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Build CSR (Compressed Sparse Row) using counting sort.
|
|
35
|
+
* O(n) instead of O(n log n) — crucial for 12M+ edges.
|
|
36
|
+
*
|
|
37
|
+
* Exported because the graph can be reconstructed from raw edge arrays
|
|
38
|
+
* (e.g. when merging or rebuilding a graph) without going through the
|
|
39
|
+
* `RelationshipGraphBuilder` mutation API.
|
|
40
|
+
*/
|
|
41
|
+
export function buildCSR(n, keys, values, types, relIds) {
|
|
42
|
+
if (n === 0)
|
|
43
|
+
return emptyRelationshipEdges();
|
|
44
|
+
// Step 1: count per key
|
|
45
|
+
const countMap = new Map();
|
|
46
|
+
for (let i = 0; i < n; i++) {
|
|
47
|
+
const k = keys[i];
|
|
48
|
+
countMap.set(k, (countMap.get(k) ?? 0) + 1);
|
|
49
|
+
}
|
|
50
|
+
// Step 2: prefix-sum offsets, sorted for deterministic order
|
|
51
|
+
const offsets = new Map();
|
|
52
|
+
const counts = new Map();
|
|
53
|
+
const uniqueKeys = Array.from(countMap.keys()).sort((a, b) => a - b);
|
|
54
|
+
let offset = 0;
|
|
55
|
+
for (const k of uniqueKeys) {
|
|
56
|
+
offsets.set(k, offset);
|
|
57
|
+
counts.set(k, countMap.get(k));
|
|
58
|
+
offset += countMap.get(k);
|
|
131
59
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
60
|
+
// Step 3: scatter edges into sorted positions
|
|
61
|
+
const edgeTargets = new Uint32Array(n);
|
|
62
|
+
const edgeTypes = new Uint16Array(n);
|
|
63
|
+
const edgeRelIds = new Uint32Array(n);
|
|
64
|
+
const writePos = new Map();
|
|
65
|
+
for (const [k, o] of offsets)
|
|
66
|
+
writePos.set(k, o);
|
|
67
|
+
for (let i = 0; i < n; i++) {
|
|
68
|
+
const k = keys[i];
|
|
69
|
+
const pos = writePos.get(k);
|
|
70
|
+
edgeTargets[pos] = values[i];
|
|
71
|
+
edgeTypes[pos] = types[i];
|
|
72
|
+
edgeRelIds[pos] = relIds[i];
|
|
73
|
+
writePos.set(k, pos + 1);
|
|
143
74
|
}
|
|
75
|
+
return relationshipEdgesFromColumns({ offsets, counts, edgeTargets, edgeTypes, edgeRelIds });
|
|
76
|
+
}
|
|
77
|
+
function emptyRelationshipEdges() {
|
|
78
|
+
return relationshipEdgesFromColumns({
|
|
79
|
+
offsets: new Map(),
|
|
80
|
+
counts: new Map(),
|
|
81
|
+
edgeTargets: new Uint32Array(0),
|
|
82
|
+
edgeTypes: new Uint16Array(0),
|
|
83
|
+
edgeRelIds: new Uint32Array(0),
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Rebuild the closure-bearing `RelationshipEdges` view (one direction of
|
|
88
|
+
* the graph) from raw CSR columns. Used by both the in-process builder and
|
|
89
|
+
* the parser-worker transport layer.
|
|
90
|
+
*/
|
|
91
|
+
export function relationshipEdgesFromColumns(columns) {
|
|
92
|
+
const { offsets, counts, edgeTargets, edgeTypes, edgeRelIds } = columns;
|
|
93
|
+
const edges = {
|
|
94
|
+
offsets,
|
|
95
|
+
counts,
|
|
96
|
+
edgeTargets,
|
|
97
|
+
edgeTypes,
|
|
98
|
+
edgeRelIds,
|
|
99
|
+
getEdges(entityId, type) {
|
|
100
|
+
const o = offsets.get(entityId);
|
|
101
|
+
if (o === undefined)
|
|
102
|
+
return [];
|
|
103
|
+
const c = counts.get(entityId);
|
|
104
|
+
const out = [];
|
|
105
|
+
for (let i = o; i < o + c; i++) {
|
|
106
|
+
if (type === undefined || edgeTypes[i] === type) {
|
|
107
|
+
out.push({ target: edgeTargets[i], type: edgeTypes[i], relationshipId: edgeRelIds[i] });
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return out;
|
|
111
|
+
},
|
|
112
|
+
getTargets(entityId, type) {
|
|
113
|
+
return edges.getEdges(entityId, type).map(e => e.target);
|
|
114
|
+
},
|
|
115
|
+
hasAnyEdges(entityId) {
|
|
116
|
+
return offsets.has(entityId);
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
return edges;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Compose a complete `RelationshipGraph` from the two directional halves.
|
|
123
|
+
* Splits cleanly so that the column extractor can pull edges without
|
|
124
|
+
* touching the closures attached above.
|
|
125
|
+
*/
|
|
126
|
+
export function relationshipGraphFromEdges(forward, inverse) {
|
|
127
|
+
return {
|
|
128
|
+
forward,
|
|
129
|
+
inverse,
|
|
130
|
+
getRelated: (entityId, relType, direction) => {
|
|
131
|
+
const e = direction === 'forward'
|
|
132
|
+
? forward.getEdges(entityId, relType)
|
|
133
|
+
: inverse.getEdges(entityId, relType);
|
|
134
|
+
return e.map((edge) => edge.target);
|
|
135
|
+
},
|
|
136
|
+
hasRelationship: (sourceId, targetId, relType) => {
|
|
137
|
+
const e = forward.getEdges(sourceId, relType);
|
|
138
|
+
return e.some((edge) => edge.target === targetId);
|
|
139
|
+
},
|
|
140
|
+
getRelationshipsBetween: (sourceId, targetId) => {
|
|
141
|
+
return forward.getEdges(sourceId)
|
|
142
|
+
.filter((edge) => edge.target === targetId)
|
|
143
|
+
.map((edge) => ({
|
|
144
|
+
relationshipId: edge.relationshipId,
|
|
145
|
+
type: edge.type,
|
|
146
|
+
typeName: RelationshipTypeToString(edge.type),
|
|
147
|
+
}));
|
|
148
|
+
},
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Reconstruct a `RelationshipGraph` (closures + both halves) from the
|
|
153
|
+
* column-only POJO produced by `relationshipGraphToColumns`.
|
|
154
|
+
*/
|
|
155
|
+
export function relationshipGraphFromColumns(columns) {
|
|
156
|
+
return relationshipGraphFromEdges(relationshipEdgesFromColumns(columns.forward), relationshipEdgesFromColumns(columns.inverse));
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Extract the column data (CSR offsets, counts, parallel edge arrays) from
|
|
160
|
+
* a `RelationshipGraph`. The returned typed arrays alias the source — they
|
|
161
|
+
* detach from the source when used in a `postMessage` transfer list.
|
|
162
|
+
*/
|
|
163
|
+
export function relationshipGraphToColumns(graph) {
|
|
164
|
+
return {
|
|
165
|
+
forward: {
|
|
166
|
+
offsets: graph.forward.offsets,
|
|
167
|
+
counts: graph.forward.counts,
|
|
168
|
+
edgeTargets: graph.forward.edgeTargets,
|
|
169
|
+
edgeTypes: graph.forward.edgeTypes,
|
|
170
|
+
edgeRelIds: graph.forward.edgeRelIds,
|
|
171
|
+
},
|
|
172
|
+
inverse: {
|
|
173
|
+
offsets: graph.inverse.offsets,
|
|
174
|
+
counts: graph.inverse.counts,
|
|
175
|
+
edgeTargets: graph.inverse.edgeTargets,
|
|
176
|
+
edgeTypes: graph.inverse.edgeTypes,
|
|
177
|
+
edgeRelIds: graph.inverse.edgeRelIds,
|
|
178
|
+
},
|
|
179
|
+
};
|
|
144
180
|
}
|
|
145
181
|
function RelationshipTypeToString(type) {
|
|
146
182
|
const names = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"relationship-graph.js","sourceRoot":"","sources":["../src/relationship-graph.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAmC9C;;;;;GAKG;AACH,MAAM,OAAO,wBAAwB;IAC3B,QAAQ,GAAa,EAAE,CAAC;IACxB,QAAQ,GAAa,EAAE,CAAC;IACxB,MAAM,GAAa,EAAE,CAAC;IACtB,OAAO,GAAa,EAAE,CAAC;IAE/B,OAAO,CAAC,MAAc,EAAE,MAAc,EAAE,IAAsB,EAAE,KAAa;QAC3E,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC3B,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC3B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC;IAED,KAAK;QACH,MAAM,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"relationship-graph.js","sourceRoot":"","sources":["../src/relationship-graph.ts"],"names":[],"mappings":"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"}
|
package/dist/string-table.d.ts
CHANGED
|
@@ -6,6 +6,14 @@ export declare class StringTable {
|
|
|
6
6
|
private strings;
|
|
7
7
|
private index;
|
|
8
8
|
readonly NULL_INDEX = -1;
|
|
9
|
+
/**
|
|
10
|
+
* Reconstruct a StringTable from a flat array as produced by `getAll()`.
|
|
11
|
+
*
|
|
12
|
+
* Used by the parser-worker → main thread transport so a complete table
|
|
13
|
+
* round-trips without re-interning each string at every call site.
|
|
14
|
+
* The first slot must be the canonical empty string at index 0.
|
|
15
|
+
*/
|
|
16
|
+
static fromArray(strings: string[]): StringTable;
|
|
9
17
|
get count(): number;
|
|
10
18
|
/**
|
|
11
19
|
* Get string by index
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"string-table.d.ts","sourceRoot":"","sources":["../src/string-table.ts"],"names":[],"mappings":"AAIA;;;GAGG;AAEH,qBAAa,WAAW;IACtB,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,KAAK,CAA2C;IAExD,QAAQ,CAAC,UAAU,MAAM;IAEzB,IAAI,KAAK,IAAI,MAAM,CAElB;IAED;;OAEG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;IAOxB;;OAEG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM;IAgBhD;;OAEG;IACH,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAI3B;;OAEG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAI9B;;OAEG;IACH,MAAM,IAAI,MAAM,EAAE;CAGnB"}
|
|
1
|
+
{"version":3,"file":"string-table.d.ts","sourceRoot":"","sources":["../src/string-table.ts"],"names":[],"mappings":"AAIA;;;GAGG;AAEH,qBAAa,WAAW;IACtB,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,KAAK,CAA2C;IAExD,QAAQ,CAAC,UAAU,MAAM;IAEzB;;;;;;OAMG;IACH,MAAM,CAAC,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,WAAW;IAchD,IAAI,KAAK,IAAI,MAAM,CAElB;IAED;;OAEG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;IAOxB;;OAEG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM;IAgBhD;;OAEG;IACH,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAI3B;;OAEG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAI9B;;OAEG;IACH,MAAM,IAAI,MAAM,EAAE;CAGnB"}
|
package/dist/string-table.js
CHANGED
|
@@ -9,6 +9,26 @@ export class StringTable {
|
|
|
9
9
|
strings = [''];
|
|
10
10
|
index = new Map([['', 0]]);
|
|
11
11
|
NULL_INDEX = -1;
|
|
12
|
+
/**
|
|
13
|
+
* Reconstruct a StringTable from a flat array as produced by `getAll()`.
|
|
14
|
+
*
|
|
15
|
+
* Used by the parser-worker → main thread transport so a complete table
|
|
16
|
+
* round-trips without re-interning each string at every call site.
|
|
17
|
+
* The first slot must be the canonical empty string at index 0.
|
|
18
|
+
*/
|
|
19
|
+
static fromArray(strings) {
|
|
20
|
+
const table = new StringTable();
|
|
21
|
+
table.strings = strings.length > 0 && strings[0] === '' ? strings.slice() : ['', ...strings];
|
|
22
|
+
table.index = new Map();
|
|
23
|
+
for (let i = 0; i < table.strings.length; i++) {
|
|
24
|
+
// First occurrence wins so duplicate inputs (rare but possible
|
|
25
|
+
// after manual concatenation) don't shadow the canonical index.
|
|
26
|
+
if (!table.index.has(table.strings[i])) {
|
|
27
|
+
table.index.set(table.strings[i], i);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return table;
|
|
31
|
+
}
|
|
12
32
|
get count() {
|
|
13
33
|
return this.strings.length;
|
|
14
34
|
}
|
package/dist/string-table.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"string-table.js","sourceRoot":"","sources":["../src/string-table.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D;;;GAGG;AAEH,MAAM,OAAO,WAAW;IACd,OAAO,GAAa,CAAC,EAAE,CAAC,CAAC;IACzB,KAAK,GAAwB,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAE/C,UAAU,GAAG,CAAC,CAAC,CAAC;IAEzB,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;IAC7B,CAAC;IAED;;OAEG;IACH,GAAG,CAAC,GAAW;QACb,IAAI,GAAG,GAAG,CAAC,IAAI,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;YAC1C,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,KAAgC;QACrC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YAC1C,OAAO,IAAI,CAAC,UAAU,CAAC;QACzB,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACvC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC3B,OAAO,QAAQ,CAAC;QAClB,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;QACrC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACzB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QAChC,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED;;OAEG;IACH,GAAG,CAAC,KAAa;QACf,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC;IAED;;OAEG;IACH,OAAO,CAAC,KAAa;QACnB,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;IACrC,CAAC;IAED;;OAEG;IACH,MAAM;QACJ,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC;IAC3B,CAAC;CACF"}
|
|
1
|
+
{"version":3,"file":"string-table.js","sourceRoot":"","sources":["../src/string-table.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D;;;GAGG;AAEH,MAAM,OAAO,WAAW;IACd,OAAO,GAAa,CAAC,EAAE,CAAC,CAAC;IACzB,KAAK,GAAwB,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAE/C,UAAU,GAAG,CAAC,CAAC,CAAC;IAEzB;;;;;;OAMG;IACH,MAAM,CAAC,SAAS,CAAC,OAAiB;QAChC,MAAM,KAAK,GAAG,IAAI,WAAW,EAAE,CAAC;QAChC,KAAK,CAAC,OAAO,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,OAAO,CAAC,CAAC;QAC7F,KAAK,CAAC,KAAK,GAAG,IAAI,GAAG,EAAE,CAAC;QACxB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC9C,+DAA+D;YAC/D,gEAAgE;YAChE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBACvC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YACvC,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;IAC7B,CAAC;IAED;;OAEG;IACH,GAAG,CAAC,GAAW;QACb,IAAI,GAAG,GAAG,CAAC,IAAI,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;YAC1C,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,KAAgC;QACrC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YAC1C,OAAO,IAAI,CAAC,UAAU,CAAC;QACzB,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACvC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC3B,OAAO,QAAQ,CAAC;QAClB,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;QACrC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACzB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QAChC,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED;;OAEG;IACH,GAAG,CAAC,KAAa;QACf,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC;IAED;;OAEG;IACH,OAAO,CAAC,KAAa;QACnB,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;IACrC,CAAC;IAED;;OAEG;IACH,MAAM;QACJ,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC;IAC3B,CAAC;CACF"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns true when `TextDecoder.decode()` accepts a SAB-backed view in
|
|
3
|
+
* this realm. Cached after first call.
|
|
4
|
+
*
|
|
5
|
+
* Exported so call sites can short-circuit explicit copies (e.g. when
|
|
6
|
+
* they already know the view is SAB-backed and want to allocate a single
|
|
7
|
+
* scratch buffer for a whole batch).
|
|
8
|
+
*/
|
|
9
|
+
export declare function textDecoderAcceptsSab(): boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Reset the detection cache. Tests only — production callers should never
|
|
12
|
+
* need to invalidate the result because the answer is fixed for the
|
|
13
|
+
* lifetime of the realm.
|
|
14
|
+
*/
|
|
15
|
+
export declare function __resetSabDecodeCache(): void;
|
|
16
|
+
/**
|
|
17
|
+
* Decode a UTF-8 byte range from `view` into a string. Safe to call on
|
|
18
|
+
* `SharedArrayBuffer`-backed views in any realm.
|
|
19
|
+
*
|
|
20
|
+
* The optional `start`/`end` parameters mirror `Uint8Array.subarray`.
|
|
21
|
+
* Calling without them decodes the entire view.
|
|
22
|
+
*/
|
|
23
|
+
export declare function safeUtf8Decode(view: Uint8Array, start?: number, end?: number): string;
|
|
24
|
+
//# sourceMappingURL=utf8-decode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utf8-decode.d.ts","sourceRoot":"","sources":["../src/utf8-decode.ts"],"names":[],"mappings":"AAmCA;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,IAAI,OAAO,CAa/C;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,IAAI,IAAI,CAE5C;AAiBD;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAkBrF"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
|
+
/**
|
|
5
|
+
* SAB-safe wrapper around `TextDecoder.decode()`.
|
|
6
|
+
*
|
|
7
|
+
* Both Firefox and Chromium reject `TextDecoder.decode(view)` when `view`
|
|
8
|
+
* is backed by a `SharedArrayBuffer` (Spectre timing-attack mitigation).
|
|
9
|
+
* The parser intentionally hands the source bytes around as a SAB so the
|
|
10
|
+
* parser worker, geometry workers, and main-thread on-demand extractors
|
|
11
|
+
* all read the same memory zero-copy — which means every decode of a
|
|
12
|
+
* subarray of the source needs to be SAB-aware.
|
|
13
|
+
*
|
|
14
|
+
* Strategy:
|
|
15
|
+
* 1. Detect the runtime's SAB-decode policy lazily, once. The result is
|
|
16
|
+
* stable for the lifetime of the realm.
|
|
17
|
+
* 2. When the runtime accepts SAB views, decode straight off the source
|
|
18
|
+
* (zero-copy, ~10 ns per call).
|
|
19
|
+
* 3. When it rejects, copy the requested subarray into a thread-local
|
|
20
|
+
* scratch `Uint8Array` first, then decode. The scratch buffer grows
|
|
21
|
+
* to the largest seen subarray and is reused, so the GC pressure is
|
|
22
|
+
* bounded even for million-entity files.
|
|
23
|
+
*
|
|
24
|
+
* Performance: the typical IFC entity decode is 50–500 bytes, so the copy
|
|
25
|
+
* path is microseconds per call. The hot batch decode path
|
|
26
|
+
* (`columnar-parser-attributes.ts`) already routes through scratch
|
|
27
|
+
* buffers, so only the per-entity attribute reads + schema detection +
|
|
28
|
+
* tokenizer fallback go through this helper.
|
|
29
|
+
*/
|
|
30
|
+
const sharedDecoder = new TextDecoder();
|
|
31
|
+
let acceptsSabCache = null;
|
|
32
|
+
/**
|
|
33
|
+
* Returns true when `TextDecoder.decode()` accepts a SAB-backed view in
|
|
34
|
+
* this realm. Cached after first call.
|
|
35
|
+
*
|
|
36
|
+
* Exported so call sites can short-circuit explicit copies (e.g. when
|
|
37
|
+
* they already know the view is SAB-backed and want to allocate a single
|
|
38
|
+
* scratch buffer for a whole batch).
|
|
39
|
+
*/
|
|
40
|
+
export function textDecoderAcceptsSab() {
|
|
41
|
+
if (acceptsSabCache !== null)
|
|
42
|
+
return acceptsSabCache;
|
|
43
|
+
if (typeof SharedArrayBuffer === 'undefined') {
|
|
44
|
+
acceptsSabCache = true; // No SAB exists, so the question is moot.
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
try {
|
|
48
|
+
sharedDecoder.decode(new Uint8Array(new SharedArrayBuffer(8)));
|
|
49
|
+
acceptsSabCache = true;
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
acceptsSabCache = false;
|
|
53
|
+
}
|
|
54
|
+
return acceptsSabCache;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Reset the detection cache. Tests only — production callers should never
|
|
58
|
+
* need to invalidate the result because the answer is fixed for the
|
|
59
|
+
* lifetime of the realm.
|
|
60
|
+
*/
|
|
61
|
+
export function __resetSabDecodeCache() {
|
|
62
|
+
acceptsSabCache = null;
|
|
63
|
+
}
|
|
64
|
+
let scratchBuffer = null;
|
|
65
|
+
/**
|
|
66
|
+
* Ensure the realm-local scratch buffer can hold `byteLength` bytes,
|
|
67
|
+
* doubling on growth to amortise reallocation cost.
|
|
68
|
+
*/
|
|
69
|
+
function ensureScratch(byteLength) {
|
|
70
|
+
if (scratchBuffer === null || scratchBuffer.length < byteLength) {
|
|
71
|
+
let cap = scratchBuffer?.length ?? 4096;
|
|
72
|
+
while (cap < byteLength)
|
|
73
|
+
cap *= 2;
|
|
74
|
+
scratchBuffer = new Uint8Array(cap);
|
|
75
|
+
}
|
|
76
|
+
return scratchBuffer;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Decode a UTF-8 byte range from `view` into a string. Safe to call on
|
|
80
|
+
* `SharedArrayBuffer`-backed views in any realm.
|
|
81
|
+
*
|
|
82
|
+
* The optional `start`/`end` parameters mirror `Uint8Array.subarray`.
|
|
83
|
+
* Calling without them decodes the entire view.
|
|
84
|
+
*/
|
|
85
|
+
export function safeUtf8Decode(view, start, end) {
|
|
86
|
+
const sub = (start === undefined && end === undefined)
|
|
87
|
+
? view
|
|
88
|
+
: view.subarray(start ?? 0, end ?? view.length);
|
|
89
|
+
if (textDecoderAcceptsSab()) {
|
|
90
|
+
return sharedDecoder.decode(sub);
|
|
91
|
+
}
|
|
92
|
+
// SAB rejected — copy into scratch. `Uint8Array.set` accepts SAB-backed
|
|
93
|
+
// sources without restriction (the Spectre mitigation only fires inside
|
|
94
|
+
// string-producing APIs like TextDecoder), so this gives us an
|
|
95
|
+
// ArrayBuffer-backed view with the same bytes.
|
|
96
|
+
const len = sub.length;
|
|
97
|
+
if (len === 0)
|
|
98
|
+
return '';
|
|
99
|
+
const scratch = ensureScratch(len);
|
|
100
|
+
scratch.set(sub);
|
|
101
|
+
return sharedDecoder.decode(scratch.subarray(0, len));
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=utf8-decode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utf8-decode.js","sourceRoot":"","sources":["../src/utf8-decode.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,MAAM,aAAa,GAAG,IAAI,WAAW,EAAE,CAAC;AAExC,IAAI,eAAe,GAAmB,IAAI,CAAC;AAE3C;;;;;;;GAOG;AACH,MAAM,UAAU,qBAAqB;IACnC,IAAI,eAAe,KAAK,IAAI;QAAE,OAAO,eAAe,CAAC;IACrD,IAAI,OAAO,iBAAiB,KAAK,WAAW,EAAE,CAAC;QAC7C,eAAe,GAAG,IAAI,CAAC,CAAC,0CAA0C;QAClE,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC;QACH,aAAa,CAAC,MAAM,CAAC,IAAI,UAAU,CAAC,IAAI,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/D,eAAe,GAAG,IAAI,CAAC;IACzB,CAAC;IAAC,MAAM,CAAC;QACP,eAAe,GAAG,KAAK,CAAC;IAC1B,CAAC;IACD,OAAO,eAAe,CAAC;AACzB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,qBAAqB;IACnC,eAAe,GAAG,IAAI,CAAC;AACzB,CAAC;AAED,IAAI,aAAa,GAAsB,IAAI,CAAC;AAE5C;;;GAGG;AACH,SAAS,aAAa,CAAC,UAAkB;IACvC,IAAI,aAAa,KAAK,IAAI,IAAI,aAAa,CAAC,MAAM,GAAG,UAAU,EAAE,CAAC;QAChE,IAAI,GAAG,GAAG,aAAa,EAAE,MAAM,IAAI,IAAI,CAAC;QACxC,OAAO,GAAG,GAAG,UAAU;YAAE,GAAG,IAAI,CAAC,CAAC;QAClC,aAAa,GAAG,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC;IACtC,CAAC;IACD,OAAO,aAAa,CAAC;AACvB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAAC,IAAgB,EAAE,KAAc,EAAE,GAAY;IAC3E,MAAM,GAAG,GAAG,CAAC,KAAK,KAAK,SAAS,IAAI,GAAG,KAAK,SAAS,CAAC;QACpD,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC,EAAE,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC;IAElD,IAAI,qBAAqB,EAAE,EAAE,CAAC;QAC5B,OAAO,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACnC,CAAC;IAED,wEAAwE;IACxE,wEAAwE;IACxE,+DAA+D;IAC/D,+CAA+C;IAC/C,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC;IACvB,IAAI,GAAG,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACzB,MAAM,OAAO,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;IACnC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACjB,OAAO,aAAa,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;AACxD,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ifc-lite/data",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.17.0",
|
|
4
4
|
"description": "Columnar data structures for IFC-Lite",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -43,6 +43,7 @@
|
|
|
43
43
|
"dev": "pnpm exec tsc --watch",
|
|
44
44
|
"test": "vitest run",
|
|
45
45
|
"generate:epsg-index": "tsx ../../scripts/generate-epsg-index.ts",
|
|
46
|
-
"augment:epsg-proj4": "tsx ../../scripts/augment-epsg-proj4.ts"
|
|
46
|
+
"augment:epsg-proj4": "tsx ../../scripts/augment-epsg-proj4.ts",
|
|
47
|
+
"generate:ifc-schema": "tsx scripts/generate-ifc-schema.ts"
|
|
47
48
|
}
|
|
48
49
|
}
|