@ifc-lite/mcp 0.9.2 → 0.10.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 +32 -1
- package/dist/backend-query.d.ts +41 -0
- package/dist/backend-query.d.ts.map +1 -0
- package/dist/backend-query.js +454 -0
- package/dist/backend-query.js.map +1 -0
- package/dist/headless-backend.d.ts +4 -3
- package/dist/headless-backend.d.ts.map +1 -1
- package/dist/headless-backend.js +26 -212
- package/dist/headless-backend.js.map +1 -1
- package/dist/overlay.d.ts +171 -0
- package/dist/overlay.d.ts.map +1 -0
- package/dist/overlay.js +300 -0
- package/dist/overlay.js.map +1 -0
- package/dist/resources/providers.d.ts.map +1 -1
- package/dist/resources/providers.js +28 -27
- package/dist/resources/providers.js.map +1 -1
- package/dist/schema-tables.d.ts +42 -0
- package/dist/schema-tables.d.ts.map +1 -0
- package/dist/schema-tables.js +75 -0
- package/dist/schema-tables.js.map +1 -0
- package/dist/spatial-tree.d.ts +40 -0
- package/dist/spatial-tree.d.ts.map +1 -0
- package/dist/spatial-tree.js +70 -0
- package/dist/spatial-tree.js.map +1 -0
- package/dist/tools/bsdd.d.ts.map +1 -1
- package/dist/tools/bsdd.js +5 -16
- package/dist/tools/bsdd.js.map +1 -1
- package/dist/tools/clash.d.ts.map +1 -1
- package/dist/tools/clash.js +18 -13
- package/dist/tools/clash.js.map +1 -1
- package/dist/tools/diff-fingerprints.d.ts +110 -0
- package/dist/tools/diff-fingerprints.d.ts.map +1 -0
- package/dist/tools/diff-fingerprints.js +410 -0
- package/dist/tools/diff-fingerprints.js.map +1 -0
- package/dist/tools/diff.d.ts.map +1 -1
- package/dist/tools/diff.js +199 -26
- package/dist/tools/diff.js.map +1 -1
- package/dist/tools/discovery.d.ts.map +1 -1
- package/dist/tools/discovery.js +124 -36
- package/dist/tools/discovery.js.map +1 -1
- package/dist/tools/export.d.ts.map +1 -1
- package/dist/tools/export.js +31 -6
- package/dist/tools/export.js.map +1 -1
- package/dist/tools/mutate.d.ts.map +1 -1
- package/dist/tools/mutate.js +6 -9
- package/dist/tools/mutate.js.map +1 -1
- package/dist/tools/query.d.ts.map +1 -1
- package/dist/tools/query.js +129 -69
- package/dist/tools/query.js.map +1 -1
- package/dist/tools/util.d.ts +36 -7
- package/dist/tools/util.d.ts.map +1 -1
- package/dist/tools/util.js +90 -0
- package/dist/tools/util.js.map +1 -1
- package/dist/tools/validation.d.ts.map +1 -1
- package/dist/tools/validation.js +82 -26
- package/dist/tools/validation.js.map +1 -1
- package/package.json +14 -13
package/dist/overlay.js
ADDED
|
@@ -0,0 +1,300 @@
|
|
|
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
|
+
import { getAttributeNamesAcrossSchemas, getInheritanceChainAcrossSchemas, } from '@ifc-lite/parser';
|
|
5
|
+
/**
|
|
6
|
+
* The model's pending overlay, or `null` when it has none.
|
|
7
|
+
*
|
|
8
|
+
* Null is the answer for every model that was only ever read: the backend
|
|
9
|
+
* creates the view lazily on the first mutation, so an unedited session pays
|
|
10
|
+
* nothing and every caller keeps its original store-only path.
|
|
11
|
+
*/
|
|
12
|
+
export function pendingOverlay(model) {
|
|
13
|
+
return model.backend.pendingOverlay();
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* The same reader, built from the view directly.
|
|
17
|
+
*
|
|
18
|
+
* The backend owns its `MutablePropertyView` and folds the overlay into its own
|
|
19
|
+
* query adapter, so it cannot go through `pendingOverlay` — that would need a
|
|
20
|
+
* `LoadedModel`, which is the registry entry wrapped *around* the backend.
|
|
21
|
+
*/
|
|
22
|
+
export function overlayFromView(view) {
|
|
23
|
+
if (!view || !view.hasPendingChanges())
|
|
24
|
+
return null;
|
|
25
|
+
return new ViewOverlay(view);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* **Everything derived is lazy, and the point lookup does not derive at all.**
|
|
29
|
+
*
|
|
30
|
+
* A fresh `ViewOverlay` is built on every overlay read — that is what keeps it
|
|
31
|
+
* honest, because there is no revision counter on `MutablePropertyView` to cache
|
|
32
|
+
* against and `getMutations().length` is not one (`mutation_undo` splices the
|
|
33
|
+
* history, so a later write can land back on the same length). A stale overlay
|
|
34
|
+
* after a mutation is a correctness bug; rebuilding is not.
|
|
35
|
+
*
|
|
36
|
+
* So the rebuild is made cheap instead. The constructor does no work, each
|
|
37
|
+
* derived collection is computed once per instance on first use, and
|
|
38
|
+
* `createdEntity` — the one called per entity by `entityData` — goes straight to
|
|
39
|
+
* the view's own id map rather than materialising the whole created list.
|
|
40
|
+
* Measured on a 20k-wall model with 2,000 queued creates, a 1,000-id
|
|
41
|
+
* `get_entities_bulk` went from ~1,960ms to ~7ms (median of five), and
|
|
42
|
+
* `getMutations()` (which copies the whole history) is no longer touched unless
|
|
43
|
+
* a payload reports the count.
|
|
44
|
+
*/
|
|
45
|
+
class ViewOverlay {
|
|
46
|
+
view;
|
|
47
|
+
tombstones = null;
|
|
48
|
+
all = null;
|
|
49
|
+
identified = null;
|
|
50
|
+
count = null;
|
|
51
|
+
/** Built on first use and never for a session that asks no relationship
|
|
52
|
+
* question, which is most of them. */
|
|
53
|
+
relationsByType = null;
|
|
54
|
+
constructor(view) {
|
|
55
|
+
this.view = view;
|
|
56
|
+
}
|
|
57
|
+
get deleted() {
|
|
58
|
+
if (!this.tombstones)
|
|
59
|
+
this.tombstones = this.view.getTombstones();
|
|
60
|
+
return this.tombstones;
|
|
61
|
+
}
|
|
62
|
+
get createdAll() {
|
|
63
|
+
if (!this.all)
|
|
64
|
+
this.all = this.view.getNewEntities().map(toCreatedEntity);
|
|
65
|
+
return this.all;
|
|
66
|
+
}
|
|
67
|
+
get created() {
|
|
68
|
+
if (!this.identified)
|
|
69
|
+
this.identified = this.createdAll.filter((entity) => entity.globalId !== '');
|
|
70
|
+
return this.identified;
|
|
71
|
+
}
|
|
72
|
+
get pendingMutations() {
|
|
73
|
+
// `getMutations()` copies the whole history, so it is paid once per overlay
|
|
74
|
+
// and only when something actually reports the number.
|
|
75
|
+
if (this.count === null)
|
|
76
|
+
this.count = this.view.getMutations().length;
|
|
77
|
+
return this.count;
|
|
78
|
+
}
|
|
79
|
+
createdEntity(expressId) {
|
|
80
|
+
// The view already indexes new entities by id; going through `createdAll`
|
|
81
|
+
// here made every `entityData` call O(number of queued creates).
|
|
82
|
+
const raw = this.view.getNewEntity(expressId);
|
|
83
|
+
return raw ? toCreatedEntity(raw) : null;
|
|
84
|
+
}
|
|
85
|
+
attributes(expressId) {
|
|
86
|
+
// Every queued write, not a chosen few. Last write wins, which is what
|
|
87
|
+
// `getAttributeMutationsForEntity` already orders for us.
|
|
88
|
+
const out = new Map();
|
|
89
|
+
for (const { name, value } of this.view.getAttributeMutationsForEntity(expressId)) {
|
|
90
|
+
out.set(name, value);
|
|
91
|
+
}
|
|
92
|
+
return out;
|
|
93
|
+
}
|
|
94
|
+
attributesByEntity() {
|
|
95
|
+
return this.view.getAttributeMutationsByEntity();
|
|
96
|
+
}
|
|
97
|
+
queuedRelations(ifcRelType) {
|
|
98
|
+
if (!this.relationsByType)
|
|
99
|
+
this.relationsByType = indexQueuedRelations(this.createdAll);
|
|
100
|
+
return this.relationsByType.get(ifcRelType.toUpperCase()) ?? [];
|
|
101
|
+
}
|
|
102
|
+
propertySets(expressId) {
|
|
103
|
+
return this.view.getForEntity(expressId);
|
|
104
|
+
}
|
|
105
|
+
quantitySets(expressId) {
|
|
106
|
+
return this.view.getQuantitiesForEntity(expressId);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Group queued `IfcRel…` creates by class, resolved to their two ends.
|
|
111
|
+
*
|
|
112
|
+
* **By attribute name, never by slot.** The two role attributes do sit at slots
|
|
113
|
+
* 4 and 5 for every relationship in the schema, but which of them is the
|
|
114
|
+
* `Relating` end is per-class: `IfcRelAggregates` puts `RelatingObject` at 4,
|
|
115
|
+
* while `IfcRelContainedInSpatialStructure` puts `RelatedElements` there. That
|
|
116
|
+
* is the same hazard as slot 4 being `ObjectType` on an `IfcObject` and
|
|
117
|
+
* `ApplicableOccurrence` on an `IfcTypeObject`, and the same answer:
|
|
118
|
+
* `getAttributeNamesAcrossSchemas` — cross-schema, so a queued IFC2X3 or IFC4X3
|
|
119
|
+
* relationship resolves too (#2003).
|
|
120
|
+
*
|
|
121
|
+
* A relationship whose ends cannot be resolved is skipped rather than guessed —
|
|
122
|
+
* which is also what happens to an IFC2X3 `IfcRelCoversSpaces`, whose slot 4 is
|
|
123
|
+
* `RelatedSpace` where IFC4 has `RelatingSpace`: it has no `Relating…` end under
|
|
124
|
+
* the IFC4 spelling, so it is skipped rather than wired backwards. It is never
|
|
125
|
+
* looked up either, because `queuedRelations` is only ever asked for the five
|
|
126
|
+
* classes in `REL_TYPE_MAP`, and those five carry identical role slots in all
|
|
127
|
+
* three bundled schemas.
|
|
128
|
+
*/
|
|
129
|
+
function indexQueuedRelations(created) {
|
|
130
|
+
const byType = new Map();
|
|
131
|
+
for (const entity of created) {
|
|
132
|
+
const upper = entity.ifcType.toUpperCase();
|
|
133
|
+
if (!upper.startsWith('IFCREL'))
|
|
134
|
+
continue;
|
|
135
|
+
const names = getAttributeNamesAcrossSchemas(entity.ifcType);
|
|
136
|
+
if (names.length === 0)
|
|
137
|
+
continue;
|
|
138
|
+
let relating;
|
|
139
|
+
let related;
|
|
140
|
+
for (let i = 0; i < names.length; i++) {
|
|
141
|
+
// The two prefixes are disjoint — `'Relating'.startsWith('Related')` is
|
|
142
|
+
// false and so is the reverse — so the order of these two tests carries no
|
|
143
|
+
// meaning. An earlier comment here claimed it did.
|
|
144
|
+
if (names[i].startsWith('Related'))
|
|
145
|
+
related ??= refIds(entity.attributes[i]);
|
|
146
|
+
else if (names[i].startsWith('Relating'))
|
|
147
|
+
relating ??= refIds(entity.attributes[i])[0];
|
|
148
|
+
}
|
|
149
|
+
if (relating === undefined || related === undefined || related.length === 0)
|
|
150
|
+
continue;
|
|
151
|
+
const list = byType.get(upper);
|
|
152
|
+
const relation = { relationshipId: entity.expressId, relating, related };
|
|
153
|
+
if (list)
|
|
154
|
+
list.push(relation);
|
|
155
|
+
else
|
|
156
|
+
byType.set(upper, [relation]);
|
|
157
|
+
}
|
|
158
|
+
return byType;
|
|
159
|
+
}
|
|
160
|
+
/** Express ids from an authored `'#42'` reference or a list of them. */
|
|
161
|
+
function refIds(value) {
|
|
162
|
+
if (typeof value === 'string') {
|
|
163
|
+
const id = Number.parseInt(value.trim().slice(1), 10);
|
|
164
|
+
return value.trim().startsWith('#') && Number.isFinite(id) ? [id] : [];
|
|
165
|
+
}
|
|
166
|
+
if (Array.isArray(value))
|
|
167
|
+
return value.flatMap((item) => refIds(item));
|
|
168
|
+
return [];
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Entity count per STEP type key, with the session's queued creates and deletes
|
|
172
|
+
* applied. Created entities are counted under the uppercase key the store uses,
|
|
173
|
+
* so `entity_create('IfcWall')` lands on the same row as the walls already in
|
|
174
|
+
* the file rather than opening a second `IfcWall` row.
|
|
175
|
+
*/
|
|
176
|
+
export function foldedTypeCounts(store, overlay) {
|
|
177
|
+
const counts = new Map();
|
|
178
|
+
for (const [type, ids] of store.entityIndex.byType) {
|
|
179
|
+
let live = ids.length;
|
|
180
|
+
// Only walk the ids when something is actually tombstoned — the type pass is
|
|
181
|
+
// otherwise O(number of types), and a model has millions of entities.
|
|
182
|
+
if (overlay && overlay.deleted.size > 0) {
|
|
183
|
+
for (const id of ids)
|
|
184
|
+
if (overlay.deleted.has(id))
|
|
185
|
+
live--;
|
|
186
|
+
}
|
|
187
|
+
counts.set(type, live);
|
|
188
|
+
}
|
|
189
|
+
for (const entity of overlay?.createdAll ?? []) {
|
|
190
|
+
const key = entity.ifcType.toUpperCase();
|
|
191
|
+
counts.set(key, (counts.get(key) ?? 0) + 1);
|
|
192
|
+
}
|
|
193
|
+
return counts;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* The model's entity count with the session's creates and deletes applied.
|
|
197
|
+
*
|
|
198
|
+
* Adjusts the parser's own total rather than re-summing `byType`, so an unedited
|
|
199
|
+
* model's number is byte-for-byte what it always was.
|
|
200
|
+
*
|
|
201
|
+
* Only tombstones that name a STORE entity are subtracted. A created-then-
|
|
202
|
+
* deleted entity is already absent from `createdAll`, so counting its tombstone
|
|
203
|
+
* too would subtract it a second time and report one entity fewer than the file
|
|
204
|
+
* has (#2012). This also makes a tombstone on an id the store never had — which
|
|
205
|
+
* `entity_delete` rejects, but nothing here relies on that — unable to drive the
|
|
206
|
+
* count below the truth.
|
|
207
|
+
*/
|
|
208
|
+
export function foldedEntityCount(store, overlay) {
|
|
209
|
+
if (!overlay)
|
|
210
|
+
return store.entityCount;
|
|
211
|
+
let deletedFromStore = 0;
|
|
212
|
+
for (const id of overlay.deleted) {
|
|
213
|
+
if (store.entityIndex.byId.has(id) || store.deferredEntityIndex?.has(id))
|
|
214
|
+
deletedFromStore++;
|
|
215
|
+
}
|
|
216
|
+
return store.entityCount + overlay.createdAll.length - deletedFromStore;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* `{ pendingMutations: n }` when any of the sessions has queued edits, `{}`
|
|
220
|
+
* otherwise — spread into a tool payload so an unedited session's shape is
|
|
221
|
+
* untouched.
|
|
222
|
+
*
|
|
223
|
+
* Always a scalar, at every level of every payload. `model_diff` used to publish
|
|
224
|
+
* a `{ base, head }` object under the same name inside `contentDiff`, so one
|
|
225
|
+
* field name meant two shapes depending on where a caller found it; the split is
|
|
226
|
+
* now `pendingMutationsBySide`.
|
|
227
|
+
*/
|
|
228
|
+
export function pendingMutationsField(...overlays) {
|
|
229
|
+
if (overlays.every((overlay) => overlay === null))
|
|
230
|
+
return {};
|
|
231
|
+
return { pendingMutations: overlays.reduce((total, overlay) => total + (overlay?.pendingMutations ?? 0), 0) };
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Read the IfcRoot header of an overlay-created entity.
|
|
235
|
+
*
|
|
236
|
+
* `NewEntity.attributes` is the positional STEP list the caller authored, so
|
|
237
|
+
* slots 0/2/3 are `GlobalId`/`Name`/`Description` **for an `IfcRoot` subtype**
|
|
238
|
+
* in every schema version — that part of the layout is fixed. Nothing further
|
|
239
|
+
* along is: slot 4 is `ObjectType` on an `IfcObject` but `ApplicableOccurrence`
|
|
240
|
+
* on an `IfcTypeObject`, so `objectType` and `PredefinedType` are read from the
|
|
241
|
+
* store for store entities and simply absent for created ones.
|
|
242
|
+
*
|
|
243
|
+
* **The `IfcRoot` half of that sentence is a precondition, not a description**,
|
|
244
|
+
* and `entity_create` accepts any IFC class. Slot 0 of an
|
|
245
|
+
* `IfcPropertySingleValue` is its `Name`, so reading it positionally turned
|
|
246
|
+
* `entity_create('IfcPropertySingleValue', ["'Width'", …])` into an entity whose
|
|
247
|
+
* GlobalId was `Width` — which then joined the cross-model identity list, so
|
|
248
|
+
* `get_entity(global_id: 'Width')` resolved to a property value, `model_diff`
|
|
249
|
+
* reported `Width` as an added entity, and `get_entities_bulk` could call it an
|
|
250
|
+
* ambiguous GlobalId. This is the same hazard `indexQueuedRelations` avoids by
|
|
251
|
+
* resolving relationship ends by attribute name, and the same one the columnar
|
|
252
|
+
* parser hits when it keys an `IfcMaterial` on the Name in slot 0.
|
|
253
|
+
*
|
|
254
|
+
* So the header is read only when the class actually derives from `IfcRoot`,
|
|
255
|
+
* cross-schema (#2003) so an IFC2X3- or IFC4X3-only root is not judged by the
|
|
256
|
+
* IFC4 pin. A class no bundled schema declares has no chain to prove it is a
|
|
257
|
+
* root, so it keeps an empty header — the same deliberate vendor gap
|
|
258
|
+
* `diff-scope.ts` documents, and the safe direction: an unidentified entity is
|
|
259
|
+
* merely unreachable by GlobalId, whereas a wrongly identified one corrupts the
|
|
260
|
+
* identity space every other tool shares.
|
|
261
|
+
*
|
|
262
|
+
* `globalId` also comes back empty when slot 0 holds none — a created
|
|
263
|
+
* `IfcCartesianPoint` has no cross-model identity, and neither has a created
|
|
264
|
+
* root the caller left unidentified. Those are excluded from `created` (nothing
|
|
265
|
+
* can compare or look them up by key) but stay reachable by expressId, because
|
|
266
|
+
* `get_entity(express_id)` on an id this session just handed out must not answer
|
|
267
|
+
* "not found", and they are still counted.
|
|
268
|
+
*/
|
|
269
|
+
function toCreatedEntity(entity) {
|
|
270
|
+
const rooted = getInheritanceChainAcrossSchemas(entity.type).includes('IfcRoot');
|
|
271
|
+
return {
|
|
272
|
+
expressId: entity.expressId,
|
|
273
|
+
ifcType: entity.type,
|
|
274
|
+
globalId: (rooted ? stepText(entity.attributes[0]) : undefined) ?? '',
|
|
275
|
+
name: rooted ? stepText(entity.attributes[2]) : undefined,
|
|
276
|
+
description: rooted ? stepText(entity.attributes[3]) : undefined,
|
|
277
|
+
attributes: entity.attributes,
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Unwrap one authored STEP attribute to plain text.
|
|
282
|
+
*
|
|
283
|
+
* `StoreEditor.addEntity` documents both `"'literal'"` and a bare string as
|
|
284
|
+
* ways to write a string attribute, so the quotes have to come off before the
|
|
285
|
+
* value is hashed — otherwise a created entity could never content-match the
|
|
286
|
+
* same entity read back out of a file. `$` (unset), `*` (derived) and `#42`
|
|
287
|
+
* (a reference) are not text.
|
|
288
|
+
*/
|
|
289
|
+
export function stepText(value) {
|
|
290
|
+
if (typeof value !== 'string')
|
|
291
|
+
return undefined;
|
|
292
|
+
const trimmed = value.trim();
|
|
293
|
+
if (trimmed === '' || trimmed === '$' || trimmed === '*' || trimmed.startsWith('#'))
|
|
294
|
+
return undefined;
|
|
295
|
+
if (trimmed.length >= 2 && trimmed.startsWith("'") && trimmed.endsWith("'")) {
|
|
296
|
+
return trimmed.slice(1, -1).replace(/''/g, "'") || undefined;
|
|
297
|
+
}
|
|
298
|
+
return trimmed;
|
|
299
|
+
}
|
|
300
|
+
//# sourceMappingURL=overlay.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"overlay.js","sourceRoot":"","sources":["../src/overlay.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"providers.d.ts","sourceRoot":"","sources":["../../src/resources/providers.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"providers.d.ts","sourceRoot":"","sources":["../../src/resources/providers.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AA+QnD,wBAAgB,wBAAwB,IAAI,gBAAgB,EAAE,CAW7D"}
|
|
@@ -8,8 +8,10 @@
|
|
|
8
8
|
* provider knows both how to enumerate static resources (so they appear in
|
|
9
9
|
* `resources/list`) and how to resolve dynamic ones via URI matching.
|
|
10
10
|
*/
|
|
11
|
-
import { EntityNode } from '@ifc-lite/query';
|
|
12
11
|
import { extractGeoreferencingOnDemand } from '@ifc-lite/parser';
|
|
12
|
+
import { foldedEntityCount, pendingMutationsField, pendingOverlay } from '../overlay.js';
|
|
13
|
+
import { buildSpatialTree } from '../spatial-tree.js';
|
|
14
|
+
import { findByGlobalId } from '../tools/util.js';
|
|
13
15
|
import { modelAllowed } from '../auth/scope.js';
|
|
14
16
|
const URI_PREFIX = 'ifc-lite://';
|
|
15
17
|
/** Models the caller's scope permits — used to filter per-model resource listings. */
|
|
@@ -49,13 +51,18 @@ class ManifestProvider {
|
|
|
49
51
|
if (!m)
|
|
50
52
|
return [];
|
|
51
53
|
const georef = extractGeoreferencingOnDemand(m.store);
|
|
54
|
+
// Resources are a read surface too, and answer with the same numbers the
|
|
55
|
+
// tools do (#2014) — a manifest that disagrees with `model_info` about how
|
|
56
|
+
// many entities the model has is the defect, whichever number is right.
|
|
57
|
+
const overlay = pendingOverlay(m);
|
|
52
58
|
return [jsonContents(uri, {
|
|
53
59
|
id: m.id,
|
|
54
60
|
name: m.name,
|
|
55
61
|
schema: m.store.schemaVersion,
|
|
56
|
-
entityCount: m.store
|
|
62
|
+
entityCount: foldedEntityCount(m.store, overlay),
|
|
57
63
|
fileSize: m.store.fileSize,
|
|
58
64
|
georeferencing: georef ?? null,
|
|
65
|
+
...pendingMutationsField(overlay),
|
|
59
66
|
})];
|
|
60
67
|
}
|
|
61
68
|
}
|
|
@@ -82,24 +89,28 @@ class EntityProvider {
|
|
|
82
89
|
if (!model)
|
|
83
90
|
return [];
|
|
84
91
|
const gid = decodeURIComponent(m[2]);
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
92
|
+
// `findByGlobalId` + `bim.entity`, so the header agrees with the body: this
|
|
93
|
+
// used to scan the parsed store for the header fields and then fill the rest
|
|
94
|
+
// from `bim.*`, which folds — one payload reporting a stale name beside
|
|
95
|
+
// freshly-written properties (#2014).
|
|
96
|
+
const expressId = findByGlobalId(model, gid);
|
|
97
|
+
if (expressId !== null) {
|
|
98
|
+
const ref = { modelId: model.id, expressId };
|
|
99
|
+
const data = model.bim.entity(ref);
|
|
100
|
+
if (data) {
|
|
91
101
|
return [jsonContents(uri, {
|
|
92
102
|
ref,
|
|
93
|
-
globalId:
|
|
94
|
-
name:
|
|
95
|
-
type:
|
|
96
|
-
description:
|
|
97
|
-
objectType:
|
|
103
|
+
globalId: data.globalId,
|
|
104
|
+
name: data.name,
|
|
105
|
+
type: data.type,
|
|
106
|
+
description: data.description,
|
|
107
|
+
objectType: data.objectType,
|
|
98
108
|
attributes: model.bim.attributes(ref),
|
|
99
109
|
properties: model.bim.properties(ref),
|
|
100
110
|
quantities: model.bim.quantities(ref),
|
|
101
111
|
classifications: model.bim.classifications(ref),
|
|
102
112
|
materials: model.bim.materials(ref),
|
|
113
|
+
...pendingMutationsField(pendingOverlay(model)),
|
|
103
114
|
})];
|
|
104
115
|
}
|
|
105
116
|
}
|
|
@@ -123,22 +134,12 @@ class SpatialTreeProvider {
|
|
|
123
134
|
const m = getAllowedModel(ctx, id);
|
|
124
135
|
if (!m)
|
|
125
136
|
return [];
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
return [jsonContents(uri,
|
|
137
|
+
// The same walk `spatial_hierarchy` uses, so the resource and the tool
|
|
138
|
+
// cannot disagree about the shape of the tree or about which IfcProject it
|
|
139
|
+
// hangs from. `elements` stays off: this resource has never carried it.
|
|
140
|
+
return [jsonContents(uri, buildSpatialTree(m))];
|
|
130
141
|
}
|
|
131
142
|
}
|
|
132
|
-
function buildTreeNode(store, expressId) {
|
|
133
|
-
const node = new EntityNode(store, expressId);
|
|
134
|
-
return {
|
|
135
|
-
expressId,
|
|
136
|
-
globalId: node.globalId,
|
|
137
|
-
type: node.type,
|
|
138
|
-
name: node.name,
|
|
139
|
-
children: node.decomposes().map((c) => buildTreeNode(store, c.expressId)),
|
|
140
|
-
};
|
|
141
|
-
}
|
|
142
143
|
class MaterialsProvider {
|
|
143
144
|
name = 'materials';
|
|
144
145
|
list(ctx) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"providers.js","sourceRoot":"","sources":["../../src/resources/providers.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D;;;;;;GAMG;AAEH,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"providers.js","sourceRoot":"","sources":["../../src/resources/providers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The bundled IFC schema tables, kept per schema rather than merged.
|
|
3
|
+
*
|
|
4
|
+
* The parser's `getAttributeNamesAcrossSchemas` answers from the IFC4 codegen
|
|
5
|
+
* pin whenever the pin knows the class, and from a merged union otherwise —
|
|
6
|
+
* which is the right default for a reader that does not know which schema it is
|
|
7
|
+
* looking at. Two callers here do know: `schema_describe` is told the class, and
|
|
8
|
+
* the query backend is told the model. For them a merged answer can be the wrong
|
|
9
|
+
* schema's answer:
|
|
10
|
+
*
|
|
11
|
+
* - `IfcControl` has five attributes in IFC2X3 and six in IFC4 (which added
|
|
12
|
+
* `Identification`), so subtracting the merged count from an IFC2X3 leaf like
|
|
13
|
+
* `IfcScheduleTimeControl` ate one of the leaf's own attributes.
|
|
14
|
+
* - `IfcRelCoversSpaces` names slot 4 `RelatedSpace` in IFC2X3 and
|
|
15
|
+
* `RelatingSpace` in IFC4, so reading a created one back in an IFC2X3 model
|
|
16
|
+
* reported an attribute name the file will not serialise.
|
|
17
|
+
*
|
|
18
|
+
* Later schemas still win when no schema is named, matching the parser's union.
|
|
19
|
+
*/
|
|
20
|
+
import { type IfcEntityInfo } from '@ifc-lite/data';
|
|
21
|
+
/** One schema's row for a class, or undefined. `schema` is matched case- and
|
|
22
|
+
* punctuation-insensitively, so `Ifc4x3` and `IFC4X3` both resolve. */
|
|
23
|
+
export declare function entityInfoInSchema(type: string, schema: string | undefined): IfcEntityInfo | undefined;
|
|
24
|
+
/**
|
|
25
|
+
* A class's row and the bundled schema that answered for it, later schemas
|
|
26
|
+
* winning — the same precedence the parser's union map applies.
|
|
27
|
+
*/
|
|
28
|
+
export declare function entityInfoAcrossSchemas(type: string): {
|
|
29
|
+
info: IfcEntityInfo;
|
|
30
|
+
schema: string;
|
|
31
|
+
} | undefined;
|
|
32
|
+
/**
|
|
33
|
+
* Attribute names in STEP positional order, preferring the named schema's
|
|
34
|
+
* spelling.
|
|
35
|
+
*
|
|
36
|
+
* Falls back to the parser's cross-schema answer when the model's schema does
|
|
37
|
+
* not declare the class — a vendor extension, or a class the file's declared
|
|
38
|
+
* schema does not have. That fallback is the pre-existing behaviour and is
|
|
39
|
+
* strictly better than nothing.
|
|
40
|
+
*/
|
|
41
|
+
export declare function attributeNamesForSchema(type: string, schema: string | undefined): readonly string[];
|
|
42
|
+
//# sourceMappingURL=schema-tables.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-tables.d.ts","sourceRoot":"","sources":["../src/schema-tables.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAmD,KAAK,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAqBrG;wEACwE;AACxE,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,aAAa,GAAG,SAAS,CAGtG;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAQzG;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,MAAM,EAAE,CAGnG"}
|
|
@@ -0,0 +1,75 @@
|
|
|
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
|
+
* The bundled IFC schema tables, kept per schema rather than merged.
|
|
6
|
+
*
|
|
7
|
+
* The parser's `getAttributeNamesAcrossSchemas` answers from the IFC4 codegen
|
|
8
|
+
* pin whenever the pin knows the class, and from a merged union otherwise —
|
|
9
|
+
* which is the right default for a reader that does not know which schema it is
|
|
10
|
+
* looking at. Two callers here do know: `schema_describe` is told the class, and
|
|
11
|
+
* the query backend is told the model. For them a merged answer can be the wrong
|
|
12
|
+
* schema's answer:
|
|
13
|
+
*
|
|
14
|
+
* - `IfcControl` has five attributes in IFC2X3 and six in IFC4 (which added
|
|
15
|
+
* `Identification`), so subtracting the merged count from an IFC2X3 leaf like
|
|
16
|
+
* `IfcScheduleTimeControl` ate one of the leaf's own attributes.
|
|
17
|
+
* - `IfcRelCoversSpaces` names slot 4 `RelatedSpace` in IFC2X3 and
|
|
18
|
+
* `RelatingSpace` in IFC4, so reading a created one back in an IFC2X3 model
|
|
19
|
+
* reported an attribute name the file will not serialise.
|
|
20
|
+
*
|
|
21
|
+
* Later schemas still win when no schema is named, matching the parser's union.
|
|
22
|
+
*/
|
|
23
|
+
import { ENTITIES_IFC2X3, ENTITIES_IFC4, ENTITIES_IFC4X3 } from '@ifc-lite/data';
|
|
24
|
+
import { getAttributeNamesAcrossSchemas } from '@ifc-lite/parser';
|
|
25
|
+
/** Bundled schemas, oldest first. */
|
|
26
|
+
const SCHEMA_TABLES = [
|
|
27
|
+
['IFC2X3', ENTITIES_IFC2X3],
|
|
28
|
+
['IFC4', ENTITIES_IFC4],
|
|
29
|
+
['IFC4X3', ENTITIES_IFC4X3],
|
|
30
|
+
];
|
|
31
|
+
let bySchema = null;
|
|
32
|
+
function tables() {
|
|
33
|
+
if (!bySchema) {
|
|
34
|
+
bySchema = new Map(SCHEMA_TABLES.map(([schema, list]) => [
|
|
35
|
+
schema,
|
|
36
|
+
new Map(list.map((entity) => [entity.name.toUpperCase(), entity])),
|
|
37
|
+
]));
|
|
38
|
+
}
|
|
39
|
+
return bySchema;
|
|
40
|
+
}
|
|
41
|
+
/** One schema's row for a class, or undefined. `schema` is matched case- and
|
|
42
|
+
* punctuation-insensitively, so `Ifc4x3` and `IFC4X3` both resolve. */
|
|
43
|
+
export function entityInfoInSchema(type, schema) {
|
|
44
|
+
if (!schema)
|
|
45
|
+
return undefined;
|
|
46
|
+
return tables().get(schema.toUpperCase().replace(/[^A-Z0-9]/g, ''))?.get(type.toUpperCase());
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* A class's row and the bundled schema that answered for it, later schemas
|
|
50
|
+
* winning — the same precedence the parser's union map applies.
|
|
51
|
+
*/
|
|
52
|
+
export function entityInfoAcrossSchemas(type) {
|
|
53
|
+
const upper = type.toUpperCase();
|
|
54
|
+
for (let i = SCHEMA_TABLES.length - 1; i >= 0; i--) {
|
|
55
|
+
const schema = SCHEMA_TABLES[i][0];
|
|
56
|
+
const info = tables().get(schema)?.get(upper);
|
|
57
|
+
if (info)
|
|
58
|
+
return { info, schema };
|
|
59
|
+
}
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Attribute names in STEP positional order, preferring the named schema's
|
|
64
|
+
* spelling.
|
|
65
|
+
*
|
|
66
|
+
* Falls back to the parser's cross-schema answer when the model's schema does
|
|
67
|
+
* not declare the class — a vendor extension, or a class the file's declared
|
|
68
|
+
* schema does not have. That fallback is the pre-existing behaviour and is
|
|
69
|
+
* strictly better than nothing.
|
|
70
|
+
*/
|
|
71
|
+
export function attributeNamesForSchema(type, schema) {
|
|
72
|
+
const info = entityInfoInSchema(type, schema);
|
|
73
|
+
return info ? info.attributes : getAttributeNamesAcrossSchemas(type);
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=schema-tables.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-tables.js","sourceRoot":"","sources":["../src/schema-tables.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,eAAe,EAAsB,MAAM,gBAAgB,CAAC;AACrG,OAAO,EAAE,8BAA8B,EAAE,MAAM,kBAAkB,CAAC;AAElE,qCAAqC;AACrC,MAAM,aAAa,GAA+D;IAChF,CAAC,QAAQ,EAAE,eAAe,CAAC;IAC3B,CAAC,MAAM,EAAE,aAAa,CAAC;IACvB,CAAC,QAAQ,EAAE,eAAe,CAAC;CAC5B,CAAC;AAEF,IAAI,QAAQ,GAAmD,IAAI,CAAC;AACpE,SAAS,MAAM;IACb,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,QAAQ,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC;YACvD,MAAM;YACN,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC;SACnE,CAAC,CAAC,CAAC;IACN,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;wEACwE;AACxE,MAAM,UAAU,kBAAkB,CAAC,IAAY,EAAE,MAA0B;IACzE,IAAI,CAAC,MAAM;QAAE,OAAO,SAAS,CAAC;IAC9B,OAAO,MAAM,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;AAC/F,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CAAC,IAAY;IAClD,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IACjC,KAAK,IAAI,CAAC,GAAG,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QACnD,MAAM,MAAM,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACnC,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;QAC9C,IAAI,IAAI;YAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IACpC,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,uBAAuB,CAAC,IAAY,EAAE,MAA0B;IAC9E,MAAM,IAAI,GAAG,kBAAkB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC9C,OAAO,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,8BAA8B,CAAC,IAAI,CAAC,CAAC;AACvE,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The model's spatial tree, in one place.
|
|
3
|
+
*
|
|
4
|
+
* `spatial_hierarchy` and the `ifc-lite://model/{id}/spatial-tree` resource
|
|
5
|
+
* answer the same question and used to answer it with two walks that disagreed:
|
|
6
|
+
* the tool recursed through containment as well as aggregation, the resource did
|
|
7
|
+
* not; the tool fell back to a queued `IfcProject` when the file's was deleted,
|
|
8
|
+
* the resource returned null; and neither carried a visited set, so a cyclic
|
|
9
|
+
* aggregation edge recursed until the stack gave out. A malformed IFC could hang
|
|
10
|
+
* the server rather than be reported.
|
|
11
|
+
*
|
|
12
|
+
* One walk, used by both. Reads go through `m.bim`, so the tree reflects the
|
|
13
|
+
* session's queued and deleted relationships like the rest of the read surface
|
|
14
|
+
* (#2014).
|
|
15
|
+
*/
|
|
16
|
+
import type { LoadedModel } from './context.js';
|
|
17
|
+
/** One node of the spatial tree. `elements` is present only when asked for. */
|
|
18
|
+
export interface SpatialNode {
|
|
19
|
+
expressId: number;
|
|
20
|
+
globalId: string;
|
|
21
|
+
type: string;
|
|
22
|
+
name: string;
|
|
23
|
+
/** Express ids contained in this spatial node (`IfcRelContainedInSpatialStructure`). */
|
|
24
|
+
elements?: number[];
|
|
25
|
+
children: SpatialNode[];
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* The `IfcProject` this tree hangs from, or null.
|
|
29
|
+
*
|
|
30
|
+
* A session can delete the file's project, and can create one — so the answer is
|
|
31
|
+
* "the first live persisted `IfcProject`, else the first queued one". The
|
|
32
|
+
* resource used to consider only the persisted list and return null where the
|
|
33
|
+
* tool succeeded, which is two answers to one question.
|
|
34
|
+
*/
|
|
35
|
+
export declare function spatialRootId(model: LoadedModel): number | null;
|
|
36
|
+
/** The whole tree from {@link spatialRootId}, or null when there is no project. */
|
|
37
|
+
export declare function buildSpatialTree(model: LoadedModel, options?: {
|
|
38
|
+
includeElements?: boolean;
|
|
39
|
+
}): SpatialNode | null;
|
|
40
|
+
//# sourceMappingURL=spatial-tree.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spatial-tree.d.ts","sourceRoot":"","sources":["../src/spatial-tree.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGhD,+EAA+E;AAC/E,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,wFAAwF;IACxF,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,QAAQ,EAAE,WAAW,EAAE,CAAC;CACzB;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,GAAG,IAAI,CAS/D;AAED,mFAAmF;AACnF,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,WAAW,EAClB,OAAO,GAAE;IAAE,eAAe,CAAC,EAAE,OAAO,CAAA;CAAO,GAC1C,WAAW,GAAG,IAAI,CAIpB"}
|