@ifc-lite/ifcx 1.2.0 → 1.3.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.
@@ -0,0 +1,211 @@
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
+ * Index for fast path lookups across layers.
6
+ */
7
+ export class PathIndex {
8
+ /** Direct UUID lookup */
9
+ byUuid = new Map();
10
+ /** Hierarchical path string lookup */
11
+ byHierarchy = new Map(); // hierarchical path -> uuid
12
+ /** Parent UUID -> (child name -> child UUID) */
13
+ childNameIndex = new Map();
14
+ /**
15
+ * Build index from layers.
16
+ */
17
+ buildIndex(layers) {
18
+ this.clear();
19
+ // First pass: collect all direct path definitions
20
+ for (const layer of layers) {
21
+ for (const [path, nodes] of layer.nodesByPath) {
22
+ // Skip non-UUID paths for now (they're hierarchical references)
23
+ if (path.includes('/'))
24
+ continue;
25
+ let entry = this.byUuid.get(path);
26
+ if (!entry) {
27
+ entry = {
28
+ uuid: path,
29
+ hierarchicalPaths: [],
30
+ definedInLayers: [],
31
+ primaryLayer: layer.id,
32
+ };
33
+ this.byUuid.set(path, entry);
34
+ }
35
+ entry.definedInLayers.push(layer.id);
36
+ // Collect children for building hierarchical index
37
+ for (const node of nodes) {
38
+ if (node.children) {
39
+ let childMap = this.childNameIndex.get(path);
40
+ if (!childMap) {
41
+ childMap = new Map();
42
+ this.childNameIndex.set(path, childMap);
43
+ }
44
+ for (const [childName, childPath] of Object.entries(node.children)) {
45
+ if (childPath && typeof childPath === 'string') {
46
+ childMap.set(childName, childPath);
47
+ }
48
+ }
49
+ }
50
+ }
51
+ }
52
+ }
53
+ // Second pass: build hierarchical path index
54
+ this.buildHierarchicalIndex();
55
+ }
56
+ /**
57
+ * Build hierarchical path index by walking children relationships.
58
+ */
59
+ buildHierarchicalIndex() {
60
+ // For each root node, build full hierarchical paths
61
+ for (const [uuid, entry] of this.byUuid) {
62
+ this.indexHierarchicalPaths(uuid, uuid, []);
63
+ }
64
+ }
65
+ /**
66
+ * Recursively index hierarchical paths for a node.
67
+ */
68
+ indexHierarchicalPaths(rootUuid, currentUuid, pathSegments) {
69
+ const children = this.childNameIndex.get(currentUuid);
70
+ if (!children)
71
+ return;
72
+ for (const [childName, childUuid] of children) {
73
+ const newSegments = [...pathSegments, childName];
74
+ const hierarchicalPath = `${rootUuid}/${newSegments.join('/')}`;
75
+ // Map hierarchical path to UUID
76
+ this.byHierarchy.set(hierarchicalPath, childUuid);
77
+ // Add to entry's hierarchical paths
78
+ const entry = this.byUuid.get(childUuid);
79
+ if (entry) {
80
+ entry.hierarchicalPaths.push(hierarchicalPath);
81
+ }
82
+ // Recurse
83
+ this.indexHierarchicalPaths(rootUuid, childUuid, newSegments);
84
+ }
85
+ }
86
+ /**
87
+ * Resolve a path to its canonical UUID.
88
+ * Accepts both direct UUIDs and hierarchical paths.
89
+ */
90
+ resolvePath(path) {
91
+ // Try direct UUID first
92
+ if (this.byUuid.has(path)) {
93
+ return path;
94
+ }
95
+ // Try hierarchical path
96
+ const resolved = this.byHierarchy.get(path);
97
+ if (resolved) {
98
+ return resolved;
99
+ }
100
+ // Try parsing and walking
101
+ const parsed = parsePath(path);
102
+ if (parsed.segments.length > 0) {
103
+ return this.walkPath(parsed.root, parsed.segments);
104
+ }
105
+ return null;
106
+ }
107
+ /**
108
+ * Walk a path through children relationships.
109
+ */
110
+ walkPath(root, segments) {
111
+ let current = root;
112
+ for (const segment of segments) {
113
+ const children = this.childNameIndex.get(current);
114
+ if (!children)
115
+ return null;
116
+ const next = children.get(segment);
117
+ if (!next)
118
+ return null;
119
+ current = next;
120
+ }
121
+ return current;
122
+ }
123
+ /**
124
+ * Get entry for a UUID.
125
+ */
126
+ getEntry(uuid) {
127
+ return this.byUuid.get(uuid);
128
+ }
129
+ /**
130
+ * Get all UUIDs in the index.
131
+ */
132
+ getAllUuids() {
133
+ return Array.from(this.byUuid.keys());
134
+ }
135
+ /**
136
+ * Get children of a node.
137
+ */
138
+ getChildren(uuid) {
139
+ return this.childNameIndex.get(uuid);
140
+ }
141
+ /**
142
+ * Check if a path exists.
143
+ */
144
+ hasPath(path) {
145
+ return this.resolvePath(path) !== null;
146
+ }
147
+ /**
148
+ * Clear the index.
149
+ */
150
+ clear() {
151
+ this.byUuid.clear();
152
+ this.byHierarchy.clear();
153
+ this.childNameIndex.clear();
154
+ }
155
+ /**
156
+ * Get index statistics.
157
+ */
158
+ getStats() {
159
+ let childRelationships = 0;
160
+ for (const children of this.childNameIndex.values()) {
161
+ childRelationships += children.size;
162
+ }
163
+ return {
164
+ uuidCount: this.byUuid.size,
165
+ hierarchicalCount: this.byHierarchy.size,
166
+ childRelationships,
167
+ };
168
+ }
169
+ }
170
+ /**
171
+ * Parse an IFCX path into components.
172
+ *
173
+ * Examples:
174
+ * "93791d5d-5beb-437b-b8ec-2f1f0ba4bf3b"
175
+ * -> { root: "93791d5d-...", segments: [], isUuid: true }
176
+ *
177
+ * "93791d5d-5beb-437b-b8ec-2f1f0ba4bf3b/My_Wall/Window"
178
+ * -> { root: "93791d5d-...", segments: ["My_Wall", "Window"], isUuid: true }
179
+ */
180
+ export function parsePath(path) {
181
+ const parts = path.split('/');
182
+ const root = parts[0];
183
+ const segments = parts.slice(1).filter((s) => s.length > 0);
184
+ // UUID pattern (simplified - 8-4-4-4-12 hex)
185
+ const isUuid = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(root);
186
+ return {
187
+ root,
188
+ segments,
189
+ isUuid,
190
+ };
191
+ }
192
+ /**
193
+ * Walk a path through composed nodes.
194
+ */
195
+ export function walkComposedPath(root, segments) {
196
+ let current = root;
197
+ for (const segment of segments) {
198
+ const child = current.children.get(segment);
199
+ if (!child)
200
+ return null;
201
+ current = child;
202
+ }
203
+ return current;
204
+ }
205
+ /**
206
+ * Create a new path index.
207
+ */
208
+ export function createPathIndex() {
209
+ return new PathIndex();
210
+ }
211
+ //# sourceMappingURL=path-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path-resolver.js","sourceRoot":"","sources":["../src/path-resolver.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ifc-lite/ifcx",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "description": "IFC5 (IFCX) parser for IFC-Lite",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -12,7 +12,7 @@
12
12
  }
13
13
  },
14
14
  "dependencies": {
15
- "@ifc-lite/data": "^1.1.7"
15
+ "@ifc-lite/data": "^1.3.0"
16
16
  },
17
17
  "devDependencies": {
18
18
  "typescript": "^5.3.0"