@ifc-lite/mutations 1.4.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/LICENSE +373 -0
- package/dist/bulk-query-engine.d.ts +138 -0
- package/dist/bulk-query-engine.d.ts.map +1 -0
- package/dist/bulk-query-engine.js +281 -0
- package/dist/bulk-query-engine.js.map +1 -0
- package/dist/change-set.d.ts +73 -0
- package/dist/change-set.d.ts.map +1 -0
- package/dist/change-set.js +178 -0
- package/dist/change-set.js.map +1 -0
- package/dist/csv-connector.d.ts +146 -0
- package/dist/csv-connector.d.ts.map +1 -0
- package/dist/csv-connector.js +305 -0
- package/dist/csv-connector.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/mutable-property-view.d.ts +110 -0
- package/dist/mutable-property-view.d.ts.map +1 -0
- package/dist/mutable-property-view.js +414 -0
- package/dist/mutable-property-view.js.map +1 -0
- package/dist/types.d.ts +114 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +34 -0
- package/dist/types.js.map +1 -0
- package/package.json +50 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CSV Data Connector for bulk property imports
|
|
3
|
+
*
|
|
4
|
+
* Allows importing property data from CSV files and mapping
|
|
5
|
+
* to IFC entities.
|
|
6
|
+
*/
|
|
7
|
+
import type { EntityTable } from '@ifc-lite/data';
|
|
8
|
+
import { PropertyValueType } from '@ifc-lite/data';
|
|
9
|
+
import type { MutablePropertyView } from './mutable-property-view.js';
|
|
10
|
+
import type { Mutation, PropertyValue } from './types.js';
|
|
11
|
+
/**
|
|
12
|
+
* A parsed CSV row
|
|
13
|
+
*/
|
|
14
|
+
export interface CsvRow {
|
|
15
|
+
[column: string]: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Match strategy for linking CSV rows to IFC entities
|
|
19
|
+
*/
|
|
20
|
+
export type MatchStrategy = {
|
|
21
|
+
type: 'globalId';
|
|
22
|
+
column: string;
|
|
23
|
+
} | {
|
|
24
|
+
type: 'expressId';
|
|
25
|
+
column: string;
|
|
26
|
+
} | {
|
|
27
|
+
type: 'name';
|
|
28
|
+
column: string;
|
|
29
|
+
} | {
|
|
30
|
+
type: 'property';
|
|
31
|
+
psetName: string;
|
|
32
|
+
propName: string;
|
|
33
|
+
column: string;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Mapping from CSV column to IFC property
|
|
37
|
+
*/
|
|
38
|
+
export interface PropertyMapping {
|
|
39
|
+
/** CSV column name */
|
|
40
|
+
sourceColumn: string;
|
|
41
|
+
/** Target property set name */
|
|
42
|
+
targetPset: string;
|
|
43
|
+
/** Target property name */
|
|
44
|
+
targetProperty: string;
|
|
45
|
+
/** Value type */
|
|
46
|
+
valueType: PropertyValueType;
|
|
47
|
+
/** Optional value transformation */
|
|
48
|
+
transform?: (value: string) => PropertyValue;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Complete data mapping configuration
|
|
52
|
+
*/
|
|
53
|
+
export interface DataMapping {
|
|
54
|
+
/** How to match CSV rows to IFC entities */
|
|
55
|
+
matchStrategy: MatchStrategy;
|
|
56
|
+
/** Property mappings */
|
|
57
|
+
propertyMappings: PropertyMapping[];
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Result of matching a CSV row to entities
|
|
61
|
+
*/
|
|
62
|
+
export interface MatchResult {
|
|
63
|
+
row: CsvRow;
|
|
64
|
+
rowIndex: number;
|
|
65
|
+
matchedEntityIds: number[];
|
|
66
|
+
confidence: number;
|
|
67
|
+
warnings?: string[];
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Statistics from CSV import
|
|
71
|
+
*/
|
|
72
|
+
export interface ImportStats {
|
|
73
|
+
totalRows: number;
|
|
74
|
+
matchedRows: number;
|
|
75
|
+
unmatchedRows: number;
|
|
76
|
+
mutationsCreated: number;
|
|
77
|
+
errors: string[];
|
|
78
|
+
warnings: string[];
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* CSV parsing options
|
|
82
|
+
*/
|
|
83
|
+
export interface CsvParseOptions {
|
|
84
|
+
/** Delimiter character (default: ',') */
|
|
85
|
+
delimiter?: string;
|
|
86
|
+
/** Has header row (default: true) */
|
|
87
|
+
hasHeader?: boolean;
|
|
88
|
+
/** Skip empty rows (default: true) */
|
|
89
|
+
skipEmpty?: boolean;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* CSV Data Connector
|
|
93
|
+
*/
|
|
94
|
+
export declare class CsvConnector {
|
|
95
|
+
private entities;
|
|
96
|
+
private mutationView;
|
|
97
|
+
private strings;
|
|
98
|
+
constructor(entities: EntityTable, mutationView: MutablePropertyView, strings?: {
|
|
99
|
+
get(idx: number): string;
|
|
100
|
+
} | null);
|
|
101
|
+
/**
|
|
102
|
+
* Parse CSV content into rows
|
|
103
|
+
*/
|
|
104
|
+
parse(content: string, options?: CsvParseOptions): CsvRow[];
|
|
105
|
+
/**
|
|
106
|
+
* Match CSV rows to IFC entities
|
|
107
|
+
*/
|
|
108
|
+
match(rows: CsvRow[], mapping: DataMapping): MatchResult[];
|
|
109
|
+
/**
|
|
110
|
+
* Match a single row to entities
|
|
111
|
+
*/
|
|
112
|
+
private matchRow;
|
|
113
|
+
/**
|
|
114
|
+
* Generate mutations from matched data
|
|
115
|
+
*/
|
|
116
|
+
generateMutations(matches: MatchResult[], mapping: DataMapping): Mutation[];
|
|
117
|
+
/**
|
|
118
|
+
* Import CSV data and apply to entities
|
|
119
|
+
*/
|
|
120
|
+
import(content: string, mapping: DataMapping, options?: CsvParseOptions): ImportStats;
|
|
121
|
+
/**
|
|
122
|
+
* Preview import without applying changes
|
|
123
|
+
*/
|
|
124
|
+
preview(content: string, mapping: DataMapping, options?: CsvParseOptions): {
|
|
125
|
+
rows: CsvRow[];
|
|
126
|
+
matches: MatchResult[];
|
|
127
|
+
estimatedMutations: number;
|
|
128
|
+
};
|
|
129
|
+
/**
|
|
130
|
+
* Parse a single CSV line respecting quoted values
|
|
131
|
+
*/
|
|
132
|
+
private parseCsvLine;
|
|
133
|
+
/**
|
|
134
|
+
* Parse a string value to the appropriate type
|
|
135
|
+
*/
|
|
136
|
+
private parseValue;
|
|
137
|
+
/**
|
|
138
|
+
* Auto-detect column mappings based on column names
|
|
139
|
+
*/
|
|
140
|
+
autoDetectMappings(headers: string[]): PropertyMapping[];
|
|
141
|
+
/**
|
|
142
|
+
* Clean a string to be a valid property name
|
|
143
|
+
*/
|
|
144
|
+
private cleanPropertyName;
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=csv-connector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"csv-connector.d.ts","sourceRoot":"","sources":["../src/csv-connector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,305 @@
|
|
|
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 { PropertyValueType } from '@ifc-lite/data';
|
|
5
|
+
/**
|
|
6
|
+
* CSV Data Connector
|
|
7
|
+
*/
|
|
8
|
+
export class CsvConnector {
|
|
9
|
+
entities;
|
|
10
|
+
mutationView;
|
|
11
|
+
strings;
|
|
12
|
+
constructor(entities, mutationView, strings) {
|
|
13
|
+
this.entities = entities;
|
|
14
|
+
this.mutationView = mutationView;
|
|
15
|
+
this.strings = strings || null;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Parse CSV content into rows
|
|
19
|
+
*/
|
|
20
|
+
parse(content, options = {}) {
|
|
21
|
+
const delimiter = options.delimiter || ',';
|
|
22
|
+
const hasHeader = options.hasHeader !== false;
|
|
23
|
+
const skipEmpty = options.skipEmpty !== false;
|
|
24
|
+
const lines = content.split(/\r?\n/);
|
|
25
|
+
if (lines.length === 0)
|
|
26
|
+
return [];
|
|
27
|
+
// Parse header
|
|
28
|
+
let headers;
|
|
29
|
+
let dataStartIndex;
|
|
30
|
+
if (hasHeader) {
|
|
31
|
+
headers = this.parseCsvLine(lines[0], delimiter);
|
|
32
|
+
dataStartIndex = 1;
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
// Generate column names: col1, col2, etc.
|
|
36
|
+
const firstLine = this.parseCsvLine(lines[0], delimiter);
|
|
37
|
+
headers = firstLine.map((_, i) => `col${i + 1}`);
|
|
38
|
+
dataStartIndex = 0;
|
|
39
|
+
}
|
|
40
|
+
// Parse data rows
|
|
41
|
+
const rows = [];
|
|
42
|
+
for (let i = dataStartIndex; i < lines.length; i++) {
|
|
43
|
+
const line = lines[i].trim();
|
|
44
|
+
if (skipEmpty && !line)
|
|
45
|
+
continue;
|
|
46
|
+
const values = this.parseCsvLine(line, delimiter);
|
|
47
|
+
const row = {};
|
|
48
|
+
for (let j = 0; j < headers.length; j++) {
|
|
49
|
+
row[headers[j]] = values[j] || '';
|
|
50
|
+
}
|
|
51
|
+
rows.push(row);
|
|
52
|
+
}
|
|
53
|
+
return rows;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Match CSV rows to IFC entities
|
|
57
|
+
*/
|
|
58
|
+
match(rows, mapping) {
|
|
59
|
+
return rows.map((row, rowIndex) => this.matchRow(row, rowIndex, mapping.matchStrategy));
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Match a single row to entities
|
|
63
|
+
*/
|
|
64
|
+
matchRow(row, rowIndex, strategy) {
|
|
65
|
+
const matchValue = row[strategy.column];
|
|
66
|
+
const matchedEntityIds = [];
|
|
67
|
+
const warnings = [];
|
|
68
|
+
if (!matchValue || matchValue.trim() === '') {
|
|
69
|
+
warnings.push(`Empty match value in column "${strategy.column}"`);
|
|
70
|
+
return { row, rowIndex, matchedEntityIds, confidence: 0, warnings };
|
|
71
|
+
}
|
|
72
|
+
switch (strategy.type) {
|
|
73
|
+
case 'globalId':
|
|
74
|
+
// Match by GlobalId
|
|
75
|
+
for (let i = 0; i < this.entities.count; i++) {
|
|
76
|
+
const globalIdIdx = this.entities.globalId[i];
|
|
77
|
+
const globalId = this.strings?.get(globalIdIdx) || '';
|
|
78
|
+
if (globalId === matchValue) {
|
|
79
|
+
matchedEntityIds.push(this.entities.expressId[i]);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
break;
|
|
83
|
+
case 'expressId':
|
|
84
|
+
// Match by Express ID
|
|
85
|
+
const expressId = parseInt(matchValue, 10);
|
|
86
|
+
if (!isNaN(expressId)) {
|
|
87
|
+
for (let i = 0; i < this.entities.count; i++) {
|
|
88
|
+
if (this.entities.expressId[i] === expressId) {
|
|
89
|
+
matchedEntityIds.push(expressId);
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
warnings.push(`Invalid Express ID: ${matchValue}`);
|
|
96
|
+
}
|
|
97
|
+
break;
|
|
98
|
+
case 'name':
|
|
99
|
+
// Match by name (case-insensitive)
|
|
100
|
+
const searchName = matchValue.toLowerCase();
|
|
101
|
+
for (let i = 0; i < this.entities.count; i++) {
|
|
102
|
+
const nameIdx = this.entities.name[i];
|
|
103
|
+
const name = (this.strings?.get(nameIdx) || '').toLowerCase();
|
|
104
|
+
if (name === searchName) {
|
|
105
|
+
matchedEntityIds.push(this.entities.expressId[i]);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
break;
|
|
109
|
+
case 'property':
|
|
110
|
+
// Match by existing property value
|
|
111
|
+
// This would require access to the property table
|
|
112
|
+
warnings.push('Property matching not yet implemented');
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
const confidence = matchedEntityIds.length === 1 ? 1 : matchedEntityIds.length > 1 ? 0.5 : 0;
|
|
116
|
+
if (matchedEntityIds.length > 1) {
|
|
117
|
+
warnings.push(`Multiple entities (${matchedEntityIds.length}) matched for value "${matchValue}"`);
|
|
118
|
+
}
|
|
119
|
+
return { row, rowIndex, matchedEntityIds, confidence, warnings };
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Generate mutations from matched data
|
|
123
|
+
*/
|
|
124
|
+
generateMutations(matches, mapping) {
|
|
125
|
+
const mutations = [];
|
|
126
|
+
for (const match of matches) {
|
|
127
|
+
if (match.matchedEntityIds.length === 0)
|
|
128
|
+
continue;
|
|
129
|
+
for (const entityId of match.matchedEntityIds) {
|
|
130
|
+
for (const propMapping of mapping.propertyMappings) {
|
|
131
|
+
const rawValue = match.row[propMapping.sourceColumn];
|
|
132
|
+
if (rawValue === undefined || rawValue === '')
|
|
133
|
+
continue;
|
|
134
|
+
const value = propMapping.transform
|
|
135
|
+
? propMapping.transform(rawValue)
|
|
136
|
+
: this.parseValue(rawValue, propMapping.valueType);
|
|
137
|
+
const mutation = this.mutationView.setProperty(entityId, propMapping.targetPset, propMapping.targetProperty, value, propMapping.valueType);
|
|
138
|
+
mutations.push(mutation);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return mutations;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Import CSV data and apply to entities
|
|
146
|
+
*/
|
|
147
|
+
import(content, mapping, options = {}) {
|
|
148
|
+
const stats = {
|
|
149
|
+
totalRows: 0,
|
|
150
|
+
matchedRows: 0,
|
|
151
|
+
unmatchedRows: 0,
|
|
152
|
+
mutationsCreated: 0,
|
|
153
|
+
errors: [],
|
|
154
|
+
warnings: [],
|
|
155
|
+
};
|
|
156
|
+
try {
|
|
157
|
+
// Parse CSV
|
|
158
|
+
const rows = this.parse(content, options);
|
|
159
|
+
stats.totalRows = rows.length;
|
|
160
|
+
// Match rows to entities
|
|
161
|
+
const matches = this.match(rows, mapping);
|
|
162
|
+
for (const match of matches) {
|
|
163
|
+
if (match.matchedEntityIds.length > 0) {
|
|
164
|
+
stats.matchedRows++;
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
stats.unmatchedRows++;
|
|
168
|
+
}
|
|
169
|
+
if (match.warnings) {
|
|
170
|
+
stats.warnings.push(...match.warnings);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
// Generate and apply mutations
|
|
174
|
+
const mutations = this.generateMutations(matches, mapping);
|
|
175
|
+
stats.mutationsCreated = mutations.length;
|
|
176
|
+
}
|
|
177
|
+
catch (error) {
|
|
178
|
+
stats.errors.push(error instanceof Error ? error.message : 'Unknown error');
|
|
179
|
+
}
|
|
180
|
+
return stats;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Preview import without applying changes
|
|
184
|
+
*/
|
|
185
|
+
preview(content, mapping, options = {}) {
|
|
186
|
+
const rows = this.parse(content, options);
|
|
187
|
+
const matches = this.match(rows, mapping);
|
|
188
|
+
let estimatedMutations = 0;
|
|
189
|
+
for (const match of matches) {
|
|
190
|
+
estimatedMutations += match.matchedEntityIds.length * mapping.propertyMappings.length;
|
|
191
|
+
}
|
|
192
|
+
return { rows, matches, estimatedMutations };
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Parse a single CSV line respecting quoted values
|
|
196
|
+
*/
|
|
197
|
+
parseCsvLine(line, delimiter) {
|
|
198
|
+
const values = [];
|
|
199
|
+
let current = '';
|
|
200
|
+
let inQuotes = false;
|
|
201
|
+
for (let i = 0; i < line.length; i++) {
|
|
202
|
+
const char = line[i];
|
|
203
|
+
if (char === '"') {
|
|
204
|
+
if (inQuotes && line[i + 1] === '"') {
|
|
205
|
+
// Escaped quote
|
|
206
|
+
current += '"';
|
|
207
|
+
i++;
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
inQuotes = !inQuotes;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
else if (char === delimiter && !inQuotes) {
|
|
214
|
+
values.push(current.trim());
|
|
215
|
+
current = '';
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
current += char;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
values.push(current.trim());
|
|
222
|
+
return values;
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Parse a string value to the appropriate type
|
|
226
|
+
*/
|
|
227
|
+
parseValue(value, type) {
|
|
228
|
+
switch (type) {
|
|
229
|
+
case PropertyValueType.Real:
|
|
230
|
+
return parseFloat(value) || 0;
|
|
231
|
+
case PropertyValueType.Integer:
|
|
232
|
+
return parseInt(value, 10) || 0;
|
|
233
|
+
case PropertyValueType.Boolean:
|
|
234
|
+
case PropertyValueType.Logical:
|
|
235
|
+
const lower = value.toLowerCase();
|
|
236
|
+
return lower === 'true' || lower === 'yes' || lower === '1';
|
|
237
|
+
case PropertyValueType.List:
|
|
238
|
+
try {
|
|
239
|
+
return JSON.parse(value);
|
|
240
|
+
}
|
|
241
|
+
catch {
|
|
242
|
+
return value.split(';').map((s) => s.trim());
|
|
243
|
+
}
|
|
244
|
+
default:
|
|
245
|
+
return value;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Auto-detect column mappings based on column names
|
|
250
|
+
*/
|
|
251
|
+
autoDetectMappings(headers) {
|
|
252
|
+
const mappings = [];
|
|
253
|
+
// Common property patterns
|
|
254
|
+
const patterns = [
|
|
255
|
+
{ pattern: /^fire\s*rating$/i, pset: 'Pset_WallCommon', prop: 'FireRating', type: PropertyValueType.String },
|
|
256
|
+
{ pattern: /^load\s*bearing$/i, pset: 'Pset_WallCommon', prop: 'LoadBearing', type: PropertyValueType.Boolean },
|
|
257
|
+
{ pattern: /^is\s*external$/i, pset: 'Pset_WallCommon', prop: 'IsExternal', type: PropertyValueType.Boolean },
|
|
258
|
+
{ pattern: /^acoustic\s*rating$/i, pset: 'Pset_WallCommon', prop: 'AcousticRating', type: PropertyValueType.String },
|
|
259
|
+
{ pattern: /^thermal\s*transmittance$/i, pset: 'Pset_WallCommon', prop: 'ThermalTransmittance', type: PropertyValueType.Real },
|
|
260
|
+
{ pattern: /^manufacturer$/i, pset: 'Pset_ManufacturerTypeInformation', prop: 'Manufacturer', type: PropertyValueType.String },
|
|
261
|
+
{ pattern: /^model\s*reference$/i, pset: 'Pset_ManufacturerTypeInformation', prop: 'ModelReference', type: PropertyValueType.String },
|
|
262
|
+
{ pattern: /^article\s*number$/i, pset: 'Pset_ManufacturerTypeInformation', prop: 'ArticleNumber', type: PropertyValueType.String },
|
|
263
|
+
];
|
|
264
|
+
for (const header of headers) {
|
|
265
|
+
// Skip common ID columns
|
|
266
|
+
if (/^(global\s*id|express\s*id|id|guid)$/i.test(header)) {
|
|
267
|
+
continue;
|
|
268
|
+
}
|
|
269
|
+
// Check against known patterns
|
|
270
|
+
let matched = false;
|
|
271
|
+
for (const { pattern, pset, prop, type } of patterns) {
|
|
272
|
+
if (pattern.test(header)) {
|
|
273
|
+
mappings.push({
|
|
274
|
+
sourceColumn: header,
|
|
275
|
+
targetPset: pset,
|
|
276
|
+
targetProperty: prop,
|
|
277
|
+
valueType: type,
|
|
278
|
+
});
|
|
279
|
+
matched = true;
|
|
280
|
+
break;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
// Default: use as custom property
|
|
284
|
+
if (!matched) {
|
|
285
|
+
mappings.push({
|
|
286
|
+
sourceColumn: header,
|
|
287
|
+
targetPset: 'Pset_Custom',
|
|
288
|
+
targetProperty: this.cleanPropertyName(header),
|
|
289
|
+
valueType: PropertyValueType.String,
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
return mappings;
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Clean a string to be a valid property name
|
|
297
|
+
*/
|
|
298
|
+
cleanPropertyName(name) {
|
|
299
|
+
return name
|
|
300
|
+
.replace(/[^a-zA-Z0-9_]/g, '_')
|
|
301
|
+
.replace(/_+/g, '_')
|
|
302
|
+
.replace(/^_|_$/g, '');
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
//# sourceMappingURL=csv-connector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"csv-connector.js","sourceRoot":"","sources":["../src/csv-connector.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @ifc-lite/mutations - Mutation tracking for IFC data
|
|
3
|
+
*/
|
|
4
|
+
export * from './types.js';
|
|
5
|
+
export { MutablePropertyView, type PropertyExtractor } from './mutable-property-view.js';
|
|
6
|
+
export { ChangeSetManager } from './change-set.js';
|
|
7
|
+
export { BulkQueryEngine, type SelectionCriteria, type BulkAction, type BulkQuery, type BulkQueryPreview, type BulkQueryResult, type PropertyFilter, type FilterOperator, } from './bulk-query-engine.js';
|
|
8
|
+
export { CsvConnector, type CsvRow, type MatchStrategy, type PropertyMapping, type DataMapping, type MatchResult, type ImportStats, type CsvParseOptions, } from './csv-connector.js';
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA;;GAEG;AAEH,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,mBAAmB,EAAE,KAAK,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AACzF,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EACL,eAAe,EACf,KAAK,iBAAiB,EACtB,KAAK,UAAU,EACf,KAAK,SAAS,EACd,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,cAAc,GACpB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,YAAY,EACZ,KAAK,MAAM,EACX,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,eAAe,GACrB,MAAM,oBAAoB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
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
|
+
* @ifc-lite/mutations - Mutation tracking for IFC data
|
|
6
|
+
*/
|
|
7
|
+
export * from './types.js';
|
|
8
|
+
export { MutablePropertyView } from './mutable-property-view.js';
|
|
9
|
+
export { ChangeSetManager } from './change-set.js';
|
|
10
|
+
export { BulkQueryEngine, } from './bulk-query-engine.js';
|
|
11
|
+
export { CsvConnector, } from './csv-connector.js';
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D;;GAEG;AAEH,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,mBAAmB,EAA0B,MAAM,4BAA4B,CAAC;AACzF,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EACL,eAAe,GAQhB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,YAAY,GAQb,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mutable property view - overlay pattern for property mutations
|
|
3
|
+
*
|
|
4
|
+
* This class provides a mutable view over an immutable PropertyTable.
|
|
5
|
+
* Changes are tracked separately and applied on-the-fly during reads.
|
|
6
|
+
*
|
|
7
|
+
* Supports both pre-built property tables and on-demand property extraction
|
|
8
|
+
* for optimal performance with large models.
|
|
9
|
+
*/
|
|
10
|
+
import type { PropertyTable, PropertySet } from '@ifc-lite/data';
|
|
11
|
+
import { PropertyValueType } from '@ifc-lite/data';
|
|
12
|
+
import type { PropertyValue, Mutation } from './types.js';
|
|
13
|
+
/**
|
|
14
|
+
* Function type for on-demand property extraction
|
|
15
|
+
* Allows globalId to be optional to match extractPropertiesOnDemand return type
|
|
16
|
+
*/
|
|
17
|
+
export type PropertyExtractor = (entityId: number) => Array<{
|
|
18
|
+
name: string;
|
|
19
|
+
globalId?: string;
|
|
20
|
+
properties: Array<{
|
|
21
|
+
name: string;
|
|
22
|
+
type: number;
|
|
23
|
+
value: unknown;
|
|
24
|
+
}>;
|
|
25
|
+
}>;
|
|
26
|
+
export declare class MutablePropertyView {
|
|
27
|
+
private baseTable;
|
|
28
|
+
private onDemandExtractor;
|
|
29
|
+
private propertyMutations;
|
|
30
|
+
private deletedPsets;
|
|
31
|
+
private newPsets;
|
|
32
|
+
private mutationHistory;
|
|
33
|
+
private modelId;
|
|
34
|
+
constructor(baseTable: PropertyTable | null, modelId: string);
|
|
35
|
+
/**
|
|
36
|
+
* Set an on-demand property extractor function
|
|
37
|
+
* This is used when properties are extracted lazily from the source buffer
|
|
38
|
+
*/
|
|
39
|
+
setOnDemandExtractor(extractor: PropertyExtractor): void;
|
|
40
|
+
/**
|
|
41
|
+
* Get base properties for an entity (before mutations)
|
|
42
|
+
* Uses on-demand extraction if available, otherwise falls back to base table
|
|
43
|
+
*/
|
|
44
|
+
private getBasePropertiesForEntity;
|
|
45
|
+
/**
|
|
46
|
+
* Get all property sets for an entity, with mutations applied
|
|
47
|
+
*/
|
|
48
|
+
getForEntity(entityId: number): PropertySet[];
|
|
49
|
+
/**
|
|
50
|
+
* Get a specific property value with mutations applied
|
|
51
|
+
*/
|
|
52
|
+
getPropertyValue(entityId: number, psetName: string, propName: string): PropertyValue | null;
|
|
53
|
+
/**
|
|
54
|
+
* Set a property value
|
|
55
|
+
* If the property set doesn't exist, creates it automatically
|
|
56
|
+
* @param skipHistory - If true, don't add to mutation history (used for undo/redo)
|
|
57
|
+
*/
|
|
58
|
+
setProperty(entityId: number, psetName: string, propName: string, value: PropertyValue, valueType?: PropertyValueType, unit?: string, skipHistory?: boolean): Mutation;
|
|
59
|
+
/**
|
|
60
|
+
* Delete a property
|
|
61
|
+
* @param skipHistory - If true, don't add to mutation history (used for undo/redo)
|
|
62
|
+
*/
|
|
63
|
+
deleteProperty(entityId: number, psetName: string, propName: string, skipHistory?: boolean): Mutation | null;
|
|
64
|
+
/**
|
|
65
|
+
* Create a new property set
|
|
66
|
+
*/
|
|
67
|
+
createPropertySet(entityId: number, psetName: string, properties: Array<{
|
|
68
|
+
name: string;
|
|
69
|
+
value: PropertyValue;
|
|
70
|
+
type?: PropertyValueType;
|
|
71
|
+
unit?: string;
|
|
72
|
+
}>): Mutation;
|
|
73
|
+
/**
|
|
74
|
+
* Delete an entire property set
|
|
75
|
+
*/
|
|
76
|
+
deletePropertySet(entityId: number, psetName: string): Mutation;
|
|
77
|
+
/**
|
|
78
|
+
* Get all mutations applied to this view
|
|
79
|
+
*/
|
|
80
|
+
getMutations(): Mutation[];
|
|
81
|
+
/**
|
|
82
|
+
* Get mutations for a specific entity
|
|
83
|
+
*/
|
|
84
|
+
getMutationsForEntity(entityId: number): Mutation[];
|
|
85
|
+
/**
|
|
86
|
+
* Check if an entity has any mutations
|
|
87
|
+
*/
|
|
88
|
+
hasChanges(entityId?: number): boolean;
|
|
89
|
+
/**
|
|
90
|
+
* Get count of modified entities
|
|
91
|
+
*/
|
|
92
|
+
getModifiedEntityCount(): number;
|
|
93
|
+
/**
|
|
94
|
+
* Clear all mutations (reset to base state)
|
|
95
|
+
*/
|
|
96
|
+
clear(): void;
|
|
97
|
+
/**
|
|
98
|
+
* Apply a batch of mutations (e.g., from imported change set)
|
|
99
|
+
*/
|
|
100
|
+
applyMutations(mutations: Mutation[]): void;
|
|
101
|
+
/**
|
|
102
|
+
* Export mutations as JSON
|
|
103
|
+
*/
|
|
104
|
+
exportMutations(): string;
|
|
105
|
+
/**
|
|
106
|
+
* Import mutations from JSON
|
|
107
|
+
*/
|
|
108
|
+
importMutations(json: string): void;
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=mutable-property-view.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mutable-property-view.d.ts","sourceRoot":"","sources":["../src/mutable-property-view.ts"],"names":[],"mappings":"AAIA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAY,MAAM,gBAAgB,CAAC;AAC3E,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,KAAK,EAAE,aAAa,EAAoB,QAAQ,EAAE,MAAM,YAAY,CAAC;AAG5E;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,QAAQ,EAAE,MAAM,KAAK,KAAK,CAAC;IAC1D,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CACnE,CAAC,CAAC;AAEH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,iBAAiB,CAAkC;IAC3D,OAAO,CAAC,iBAAiB,CAA4C;IACrE,OAAO,CAAC,YAAY,CAA0B;IAC9C,OAAO,CAAC,QAAQ,CAAoD;IACpE,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,OAAO,CAAS;gBAEZ,SAAS,EAAE,aAAa,GAAG,IAAI,EAAE,OAAO,EAAE,MAAM;IAK5D;;;OAGG;IACH,oBAAoB,CAAC,SAAS,EAAE,iBAAiB,GAAG,IAAI;IAIxD;;;OAGG;IACH,OAAO,CAAC,0BAA0B;IAqBlC;;OAEG;IACH,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,EAAE;IA2E7C;;OAEG;IACH,gBAAgB,CACd,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GACf,aAAa,GAAG,IAAI;IAiCvB;;;;OAIG;IACH,WAAW,CACT,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,aAAa,EACpB,SAAS,GAAE,iBAA4C,EACvD,IAAI,CAAC,EAAE,MAAM,EACb,WAAW,GAAE,OAAe,GAC3B,QAAQ;IAiFX;;;OAGG;IACH,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,GAAE,OAAe,GAAG,QAAQ,GAAG,IAAI;IA4BnH;;OAEG;IACH,iBAAiB,CACf,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,aAAa,CAAC;QAAC,IAAI,CAAC,EAAE,iBAAiB,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,GACjG,QAAQ;IA6CX;;OAEG;IACH,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,QAAQ;IAgC/D;;OAEG;IACH,YAAY,IAAI,QAAQ,EAAE;IAI1B;;OAEG;IACH,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,EAAE;IAInD;;OAEG;IACH,UAAU,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO;IAOtC;;OAEG;IACH,sBAAsB,IAAI,MAAM;IAQhC;;OAEG;IACH,KAAK,IAAI,IAAI;IAOb;;OAEG;IACH,cAAc,CAAC,SAAS,EAAE,QAAQ,EAAE,GAAG,IAAI;IA+B3C;;OAEG;IACH,eAAe,IAAI,MAAM;IAQzB;;OAEG;IACH,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;CAMpC"}
|