@bldrs-ai/conway 0.13.802 → 0.15.836
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 +1 -1
- package/compiled/dependencies/conway-geom/Dist/ConwayGeomWasmNode.js +1 -1
- package/compiled/dependencies/conway-geom/Dist/ConwayGeomWasmNodeMT.js +1 -1
- package/compiled/dependencies/conway-geom/Dist/ConwayGeomWasmWeb.js +1 -1
- package/compiled/dependencies/conway-geom/Dist/ConwayGeomWasmWebMT.js +1 -1
- package/compiled/dependencies/conway-geom/Dist/ConwayGeomWasmWebMT.wasm +0 -0
- package/compiled/dependencies/conway-geom/index.d.ts +2 -0
- package/compiled/dependencies/conway-geom/index.d.ts.map +1 -1
- package/compiled/dependencies/conway-geom/index.js +2 -0
- package/compiled/dependencies/conway-geom/interface/conway_geometry.d.ts +6 -0
- package/compiled/dependencies/conway-geom/interface/conway_geometry.d.ts.map +1 -1
- package/compiled/dependencies/conway-geom/interface/conway_geometry.js +7 -0
- package/compiled/dependencies/conway-geom/interface/parameters/flattened_points.d.ts +6 -0
- package/compiled/dependencies/conway-geom/interface/parameters/flattened_points.d.ts.map +1 -0
- package/compiled/dependencies/conway-geom/interface/parameters/flattened_points.js +1 -0
- package/compiled/dependencies/conway-geom/interface/parameters/params_add_face_to_geometry_simple.d.ts +10 -0
- package/compiled/dependencies/conway-geom/interface/parameters/params_add_face_to_geometry_simple.d.ts.map +1 -0
- package/compiled/dependencies/conway-geom/interface/parameters/params_add_face_to_geometry_simple.js +1 -0
- package/compiled/src/ifc/ifc_geometry_extraction.d.ts +22 -1
- package/compiled/src/ifc/ifc_geometry_extraction.d.ts.map +1 -1
- package/compiled/src/ifc/ifc_geometry_extraction.js +109 -38
- package/compiled/src/ifc/ifc_regression_batch_main.js +258 -101
- package/compiled/src/ifc/ifc_step_model.d.ts +0 -1
- package/compiled/src/ifc/ifc_step_model.d.ts.map +1 -1
- package/compiled/src/ifc/ifc_step_model.js +0 -1
- package/compiled/src/ifc/ifc_step_parser.d.ts +0 -1
- package/compiled/src/ifc/ifc_step_parser.d.ts.map +1 -1
- package/compiled/src/ifc/ifc_step_parser.js +0 -1
- package/compiled/src/version/version.js +1 -1
- package/compiled/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -1
|
@@ -5,36 +5,63 @@ import childProcess from 'child_process';
|
|
|
5
5
|
import { promisify } from 'util';
|
|
6
6
|
import path from 'path';
|
|
7
7
|
import crypto from 'crypto';
|
|
8
|
+
import os from 'os';
|
|
9
|
+
import pLimit from 'p-limit';
|
|
8
10
|
const errorCSVHeader = 'message,count,expressids,file';
|
|
9
11
|
const exec = promisify(childProcess.exec);
|
|
12
|
+
/* eslint-disable require-await */
|
|
10
13
|
/**
|
|
11
|
-
* Safe execute a process command
|
|
14
|
+
* Safe execute a process command with cancellation support.
|
|
12
15
|
*
|
|
13
|
-
* @param command The command to run
|
|
14
|
-
* @
|
|
16
|
+
* @param command The command to run.
|
|
17
|
+
* @param timeoutMs Number of milliseconds to wait before timing out.
|
|
18
|
+
* @return {Promise<RunErrorResults | { type: 'Success', stdout: string, stderr: string }>}
|
|
15
19
|
*/
|
|
16
|
-
async function
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
20
|
+
async function safeExecWithCancellation(command, timeoutMs) {
|
|
21
|
+
return new Promise((resolve) => {
|
|
22
|
+
// Start the child process using childProcess.exec
|
|
23
|
+
const child = childProcess.exec(command, { maxBuffer: STD_OUT_ERR_MAX_BUFFER }, (err, stdout, stderr) => {
|
|
24
|
+
// If the process finishes before the timeout, clear the timer...
|
|
25
|
+
clearTimeout(timeoutHandle);
|
|
26
|
+
if (err) {
|
|
27
|
+
const errResult = err;
|
|
28
|
+
resolve({
|
|
29
|
+
type: 'Failed',
|
|
30
|
+
name: errResult.name,
|
|
31
|
+
message: errResult.message,
|
|
32
|
+
code: errResult.code,
|
|
33
|
+
cmd: errResult.cmd,
|
|
34
|
+
signal: errResult.signal,
|
|
35
|
+
killed: errResult.killed,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
resolve({
|
|
40
|
+
type: 'Success',
|
|
41
|
+
stdout,
|
|
42
|
+
stderr,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
// Set up the timeout promise.
|
|
47
|
+
const timeoutHandle = setTimeout(() => {
|
|
48
|
+
// Timeout occurred: kill the child process.
|
|
49
|
+
child.kill();
|
|
50
|
+
resolve({
|
|
51
|
+
type: 'Failed',
|
|
52
|
+
name: 'TimeoutError',
|
|
53
|
+
message: 'Execution timed out',
|
|
54
|
+
cmd: command,
|
|
55
|
+
killed: true,
|
|
56
|
+
});
|
|
57
|
+
}, timeoutMs);
|
|
58
|
+
// When the child exits naturally, clear the timeout.
|
|
59
|
+
child.on('exit', () => {
|
|
60
|
+
clearTimeout(timeoutHandle);
|
|
61
|
+
});
|
|
62
|
+
});
|
|
37
63
|
}
|
|
64
|
+
/* eslint-enable require-await */
|
|
38
65
|
const SKIP_PARAMS = 2;
|
|
39
66
|
// eslint-disable-next-line no-magic-numbers
|
|
40
67
|
const STD_OUT_ERR_MAX_BUFFER = 64 * 1024 * 1024;
|
|
@@ -76,40 +103,43 @@ function csvSafeStringFileNames(from) {
|
|
|
76
103
|
/**
|
|
77
104
|
* Run the git diff
|
|
78
105
|
*
|
|
79
|
-
* @param
|
|
80
|
-
* @param
|
|
81
|
-
* @param
|
|
82
|
-
* @param
|
|
106
|
+
* @param ifcFolder The folder we want to `cd` into before running git
|
|
107
|
+
* @param outputFolder The folder containing outputs that we compare
|
|
108
|
+
* @param target The Git diff target (branch, commit, etc.)
|
|
109
|
+
* @param diffOutputPath Where we store the CSV diff results (no extension)
|
|
110
|
+
* @param isDryRun If true, reverts changes via git checkout after diff
|
|
83
111
|
*/
|
|
84
|
-
async function runDiff(outputFolder, target, diffOutputPath, isDryRun) {
|
|
112
|
+
async function runDiff(ifcFolder, outputFolder, target, diffOutputPath, isDryRun) {
|
|
85
113
|
const diffOutputFolder = path.dirname(path.resolve(diffOutputPath));
|
|
86
114
|
await fsPromises.mkdir(diffOutputFolder, { recursive: true });
|
|
87
|
-
|
|
88
|
-
|
|
115
|
+
console.log(`ifcFolder: ${ifcFolder}`);
|
|
116
|
+
// 1) Change `cwd` to `ifcFolder`, so we "cd ifcFolder" before running git
|
|
117
|
+
const processResult = await exec(`git diff -r --numstat --minimal ${target} -- ${outputFolder}`, {
|
|
118
|
+
maxBuffer: STD_OUT_ERR_MAX_BUFFER,
|
|
119
|
+
cwd: ifcFolder, // <-- This causes the exec to run in ifcFolder
|
|
120
|
+
});
|
|
121
|
+
const csvDiff = `Added,Removed,File\n${processResult.stdout
|
|
122
|
+
.split('\n')
|
|
123
|
+
.map((line) => line.split('\t').map(csvSafeStringFileNames).join(','))
|
|
124
|
+
.join('\n')}`;
|
|
89
125
|
await fsPromises.writeFile(`${diffOutputPath}.csv`, csvDiff);
|
|
90
126
|
if (isDryRun) {
|
|
91
|
-
|
|
127
|
+
// 2) Also run the checkout in the same `cwd` context
|
|
128
|
+
await exec(`git checkout -- "${outputFolder}"`, { cwd: ifcFolder });
|
|
92
129
|
}
|
|
93
130
|
}
|
|
94
131
|
let totalTime = 0; // To keep track of the running total time
|
|
95
132
|
/**
|
|
96
133
|
* Run a regression test digest for a file.
|
|
97
134
|
*/
|
|
98
|
-
async function runForFile(filePath, outputPath) {
|
|
99
|
-
const MAX_TIMEOUT_MS =
|
|
135
|
+
async function runForFile(filePath, outputPath, maxTimeout) {
|
|
136
|
+
const MAX_TIMEOUT_MS = maxTimeout;
|
|
100
137
|
const startTime = Date.now(); // Start time
|
|
101
138
|
// eslint-disable-next-line max-len
|
|
102
139
|
const safeExecCommand = `node --experimental-specifier-resolution=node ./compiled/src/ifc/ifc_regression_main.js -d "${filePath}" "${outputPath}"`;
|
|
103
140
|
console.log(`Current File: ${filePath}`);
|
|
104
|
-
|
|
105
|
-
const
|
|
106
|
-
resolve({
|
|
107
|
-
type: 'Failed',
|
|
108
|
-
message: 'Execution timed out',
|
|
109
|
-
name: '',
|
|
110
|
-
});
|
|
111
|
-
}, MAX_TIMEOUT_MS));
|
|
112
|
-
const process = await Promise.race([processPromise, timeoutPromise]);
|
|
141
|
+
// Use safeExecWithCancellation, will kill the process if it takes longer than MAX_TIMEOUT_MS.
|
|
142
|
+
const process = await safeExecWithCancellation(safeExecCommand, MAX_TIMEOUT_MS);
|
|
113
143
|
totalTime += Date.now() - startTime;
|
|
114
144
|
console.log(`totalTime: ${totalTime}`);
|
|
115
145
|
if (process.type === 'Failed') {
|
|
@@ -144,8 +174,122 @@ async function runForFile(filePath, outputPath) {
|
|
|
144
174
|
hash: fileHash,
|
|
145
175
|
};
|
|
146
176
|
}
|
|
147
|
-
|
|
148
|
-
|
|
177
|
+
/**
|
|
178
|
+
* Recursively collect all IFC file paths (instead of processing them immediately).
|
|
179
|
+
*/
|
|
180
|
+
async function collectIFCFiles(parentPath, excludeRegex) {
|
|
181
|
+
const ifcFiles = [];
|
|
182
|
+
/**
|
|
183
|
+
* Recursively walk ifc files
|
|
184
|
+
*/
|
|
185
|
+
// eslint-disable-next-line no-shadow, require-jsdoc
|
|
186
|
+
async function recursiveWalk(currentPath) {
|
|
187
|
+
const items = await fsPromises.readdir(currentPath, { withFileTypes: true });
|
|
188
|
+
items.sort((a, b) => (a.name > b.name ? 1 : -1));
|
|
189
|
+
for (const item of items) {
|
|
190
|
+
const resolved = path.join(currentPath, item.name);
|
|
191
|
+
if (excludeRegex && excludeRegex.test(resolved)) {
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
if (item.isDirectory()) {
|
|
195
|
+
await recursiveWalk(resolved);
|
|
196
|
+
}
|
|
197
|
+
else if (path.extname(resolved).toLowerCase() === '.ifc') {
|
|
198
|
+
ifcFiles.push(resolved);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
await recursiveWalk(parentPath);
|
|
203
|
+
return ifcFiles;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* @return {number} percentage of memory used on machine
|
|
207
|
+
*/
|
|
208
|
+
function getSystemMemoryUsagePercent() {
|
|
209
|
+
const total = os.totalmem(); // total system memory in bytes
|
|
210
|
+
const free = os.freemem(); // free system memory in bytes
|
|
211
|
+
const used = total - free;
|
|
212
|
+
/* eslint-disable no-magic-numbers */
|
|
213
|
+
console.log(`total: ${total / 1000 / 1000 / 1000} GB - ` +
|
|
214
|
+
`used: ${used / 1000 / 1000 / 1000} GB - ` +
|
|
215
|
+
`free: ${free / 1000 / 1000 / 1000} GB`);
|
|
216
|
+
return (used / total) * 100;
|
|
217
|
+
/* eslint-enable no-magic-numbers */
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Parallel processing, using p-limit to limit concurrency to number of CPU cores.
|
|
221
|
+
*/
|
|
222
|
+
async function processIFCFilesInParallel(ifcFiles, outputPath, errorLines, fileLines, failedLines, memUtilization, maxTimeout) {
|
|
223
|
+
const concurrencyLimit = os.cpus().length;
|
|
224
|
+
console.log(`Concurrency: ${concurrencyLimit} threads - Max Timeout: ${maxTimeout} ms`);
|
|
225
|
+
const limit = pLimit(concurrencyLimit);
|
|
226
|
+
const taskTimeout = 2000;
|
|
227
|
+
let activeTasks = 0;
|
|
228
|
+
// Create an array of task promises using map (without awaiting immediately)
|
|
229
|
+
const tasks = ifcFiles.map((ifcPath) => limit(async () => {
|
|
230
|
+
// Wait if system memory usage is above 95%
|
|
231
|
+
while (getSystemMemoryUsagePercent() > memUtilization) {
|
|
232
|
+
console.log(`Memory usage > ${memUtilization}%, waiting 2s...`);
|
|
233
|
+
await new Promise((resolve) => setTimeout(resolve, taskTimeout));
|
|
234
|
+
}
|
|
235
|
+
activeTasks++;
|
|
236
|
+
console.log(`Starting task for "${path.basename(ifcPath)}". Active tasks: ${activeTasks}`);
|
|
237
|
+
const fileResults = await runForFile(ifcPath, path.join(outputPath, path.basename(ifcPath, '.ifc')), maxTimeout);
|
|
238
|
+
activeTasks--;
|
|
239
|
+
console.log(`Completed task for "${path.basename(ifcPath)}". Active tasks: ${activeTasks}`);
|
|
240
|
+
return { ifcPath, fileResults };
|
|
241
|
+
}));
|
|
242
|
+
// Wait for all tasks to complete in parallel
|
|
243
|
+
const results = await Promise.all(tasks);
|
|
244
|
+
// Aggregate results
|
|
245
|
+
for (const { ifcPath, fileResults } of results) {
|
|
246
|
+
if (fileResults.type === 'Run') {
|
|
247
|
+
if (fileResults.errorLines) {
|
|
248
|
+
errorLines.push(...fileResults.errorLines);
|
|
249
|
+
}
|
|
250
|
+
fileLines.push(`${csvSafeString(path.basename(ifcPath))},` +
|
|
251
|
+
`${csvSafeString(fileResults.hash ?? '')},` +
|
|
252
|
+
`${fileResults.errorLines?.length ?? 0}\n`);
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
// it's 'Failed'
|
|
256
|
+
failedLines.push(`${csvSafeString(path.basename(ifcPath))},` +
|
|
257
|
+
`${csvSafeString(fileResults.code?.toString() ?? '')},` +
|
|
258
|
+
`${csvSafeString(fileResults.signal ?? '')}\n`);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
// The original recursive approach (unchanged, except it won't be used if -parallel is set)
|
|
263
|
+
/**
|
|
264
|
+
*
|
|
265
|
+
*/
|
|
266
|
+
async function recursiveWalk(parentPath, excludeRegex, outputPath, errorLines, fileLines, failedLines, maxTimeout) {
|
|
267
|
+
const items = await fsPromises.readdir(parentPath, { withFileTypes: true });
|
|
268
|
+
items.sort((a, b) => (a.name > b.name ? 1 : -1));
|
|
269
|
+
for (const item of items) {
|
|
270
|
+
const resolved = path.join(parentPath, item.name);
|
|
271
|
+
if (excludeRegex && excludeRegex.test(resolved)) {
|
|
272
|
+
continue;
|
|
273
|
+
}
|
|
274
|
+
if (item.isDirectory()) {
|
|
275
|
+
await recursiveWalk(resolved, excludeRegex, outputPath, errorLines, fileLines, failedLines, maxTimeout);
|
|
276
|
+
}
|
|
277
|
+
else if (path.extname(resolved).toLowerCase() === '.ifc') {
|
|
278
|
+
const fileResults = await runForFile(resolved, path.join(outputPath, path.basename(resolved, '.ifc')), maxTimeout);
|
|
279
|
+
if (fileResults.type === 'Run') {
|
|
280
|
+
if (fileResults.errorLines !== void 0) {
|
|
281
|
+
errorLines.push(...fileResults.errorLines);
|
|
282
|
+
}
|
|
283
|
+
fileLines.push(`${csvSafeString(path.basename(resolved))},${csvSafeString(fileResults.hash ?? '')},${fileResults.errorLines?.length ?? 0}\n`);
|
|
284
|
+
}
|
|
285
|
+
else {
|
|
286
|
+
failedLines.push(`${csvSafeString(path.basename(resolved))},${csvSafeString(fileResults.code?.toString() ?? '')},${csvSafeString(fileResults.signal ?? '')}\n`);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
// eslint-disable-next-line no-unused-vars
|
|
292
|
+
const args = yargs(process.argv.slice(SKIP_PARAMS))
|
|
149
293
|
.command('$0 <model_folder> <output_folder>', 'Regression test', (yargs2) => {
|
|
150
294
|
yargs2.option('target', {
|
|
151
295
|
describe: 'Git diff target',
|
|
@@ -160,34 +304,70 @@ const args = // eslint-disable-line no-unused-vars
|
|
|
160
304
|
default: false,
|
|
161
305
|
});
|
|
162
306
|
yargs2.option('changes', {
|
|
163
|
-
describe:
|
|
164
|
-
|
|
307
|
+
describe:
|
|
308
|
+
// eslint-disable-next-line max-len
|
|
309
|
+
'Custom output location for the diff output (filepath, should include file name but not extension, the folder will be created if it doesn\'t exist)',
|
|
165
310
|
type: 'string',
|
|
166
311
|
alias: 'c',
|
|
167
312
|
default: '',
|
|
168
313
|
});
|
|
169
314
|
yargs2.option('exclude', {
|
|
170
|
-
describe: '
|
|
315
|
+
describe: 'A file-path exclusion regex filter (javascript syntax)',
|
|
171
316
|
type: 'string',
|
|
172
317
|
alias: 'e',
|
|
173
318
|
default: '',
|
|
174
319
|
});
|
|
320
|
+
yargs2.option('parallel', {
|
|
321
|
+
describe: 'Process IFC files in parallel (limited by CPU cores)',
|
|
322
|
+
type: 'boolean',
|
|
323
|
+
alias: 'p',
|
|
324
|
+
default: false,
|
|
325
|
+
});
|
|
326
|
+
// only relevant if parallel is enabled
|
|
327
|
+
yargs2.option('mem-utilization', {
|
|
328
|
+
// eslint-disable-next-line max-len
|
|
329
|
+
describe: 'Memory utilization threshold percentage for parallel processing (1-100, default: 95)',
|
|
330
|
+
type: 'number',
|
|
331
|
+
alias: 'm',
|
|
332
|
+
default: 95,
|
|
333
|
+
});
|
|
334
|
+
// Validate mem-utilization only if parallel mode is active
|
|
335
|
+
yargs2.check((argv) => {
|
|
336
|
+
if (argv.parallel) {
|
|
337
|
+
const memUtil = argv['mem-utilization'];
|
|
338
|
+
// eslint-disable-next-line no-magic-numbers
|
|
339
|
+
if (typeof memUtil !== 'number' || memUtil < 1 || memUtil > 100) {
|
|
340
|
+
throw new Error('mem-utilization must be a number between 1 and 100');
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
return true;
|
|
344
|
+
});
|
|
345
|
+
yargs2.option('timeout', {
|
|
346
|
+
describe: 'IFC per-file loading timeout in ms (default: 150000)',
|
|
347
|
+
type: 'number',
|
|
348
|
+
alias: 'timeout',
|
|
349
|
+
default: 150000,
|
|
350
|
+
});
|
|
175
351
|
yargs2.positional('model_folder', {
|
|
176
|
-
describe: '
|
|
177
|
-
type: 'string'
|
|
352
|
+
describe: 'Folder containing IFC files, recursively walked',
|
|
353
|
+
type: 'string',
|
|
178
354
|
});
|
|
179
355
|
yargs2.positional('output_folder', {
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
type: 'string'
|
|
356
|
+
describe: 'Folder for manifests/output artifacts (diff CSV goes here unless overridden)',
|
|
357
|
+
type: 'string',
|
|
183
358
|
});
|
|
184
359
|
}, async (argv) => {
|
|
360
|
+
// ---- New: record overall start time
|
|
361
|
+
const overallStart = Date.now();
|
|
185
362
|
const ifcFolder = argv['model_folder'];
|
|
186
363
|
const outputPath = argv['output_folder'];
|
|
187
364
|
let changes = argv['changes'] ?? '';
|
|
188
365
|
const target = argv['target'] ?? '';
|
|
189
366
|
const dryRun = argv['dryrun'] ?? false;
|
|
190
367
|
const excludeFilter = argv['exclude'] ?? '';
|
|
368
|
+
const doParallel = argv['parallel'] ?? false; // <--- read the parallel flag
|
|
369
|
+
const memUtilization = argv['mem-utilization'];
|
|
370
|
+
const maxTimeout = argv['timeout'];
|
|
191
371
|
if (changes.length === 0) {
|
|
192
372
|
changes = path.join(outputPath, 'changes');
|
|
193
373
|
}
|
|
@@ -198,53 +378,30 @@ const args = // eslint-disable-line no-unused-vars
|
|
|
198
378
|
const errorLines = [];
|
|
199
379
|
const fileLines = [];
|
|
200
380
|
const failedLines = [];
|
|
201
|
-
const excludeRegex = excludeFilter.length > 0 ? new RegExp(excludeFilter) :
|
|
202
|
-
|
|
203
|
-
(
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
else {
|
|
227
|
-
// eslint-disable-next-line max-len
|
|
228
|
-
failedLines.push(`${csvSafeString(path.basename(resolved))},${csvSafeString(fileResults.code?.toString() ?? '')},${csvSafeString(fileResults.signal ?? '')}\n`);
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
};
|
|
233
|
-
await recursiveWalk(ifcFolder);
|
|
234
|
-
const manifestFile = await fsPromises.open(mainPath, 'w');
|
|
235
|
-
await manifestFile.writeFile('file,hash,errors\n');
|
|
236
|
-
await manifestFile.writeFile(fileLines);
|
|
237
|
-
await manifestFile.close();
|
|
238
|
-
const errorFile = await fsPromises.open(errorPath, 'w');
|
|
239
|
-
await errorFile.writeFile(`${errorCSVHeader}\n`);
|
|
240
|
-
await errorFile.writeFile(errorLines);
|
|
241
|
-
await errorFile.close();
|
|
242
|
-
const failedFile = await fsPromises.open(failedPath, 'w');
|
|
243
|
-
await failedFile.writeFile('file,code,signal\n');
|
|
244
|
-
await failedFile.writeFile(failedLines);
|
|
245
|
-
await failedFile.close();
|
|
246
|
-
await runDiff(outputPath, target, changes, dryRun);
|
|
247
|
-
// TODO(@nickcastel50) - figure out why this hangs at the end sometimes
|
|
248
|
-
process.exit(0);
|
|
381
|
+
const excludeRegex = excludeFilter.length > 0 ? new RegExp(excludeFilter) : undefined;
|
|
382
|
+
if (doParallel) {
|
|
383
|
+
console.log('Processing in parallel mode...');
|
|
384
|
+
// 1) Collect all IFC files first
|
|
385
|
+
const allIFCFiles = await collectIFCFiles(ifcFolder, excludeRegex);
|
|
386
|
+
// 2) Process them in parallel
|
|
387
|
+
await processIFCFilesInParallel(allIFCFiles, outputPath, errorLines, fileLines, failedLines, memUtilization, maxTimeout);
|
|
388
|
+
}
|
|
389
|
+
else {
|
|
390
|
+
console.log('Processing in serial mode...');
|
|
391
|
+
// eslint-disable-next-line max-len
|
|
392
|
+
await recursiveWalk(ifcFolder, excludeRegex, outputPath, errorLines, fileLines, failedLines, maxTimeout);
|
|
393
|
+
}
|
|
394
|
+
// Write out results
|
|
395
|
+
await fsPromises.writeFile(mainPath, `file,hash,errors\n${fileLines.join('')}`);
|
|
396
|
+
await fsPromises.writeFile(errorPath, `${errorCSVHeader}\n${errorLines.join('')}`);
|
|
397
|
+
await fsPromises.writeFile(failedPath, `file,code,signal\n${failedLines.join('')}`);
|
|
398
|
+
// If user wants a git diff
|
|
399
|
+
await runDiff(ifcFolder, outputPath, target, changes, dryRun);
|
|
400
|
+
// ---- New: log total runtime
|
|
401
|
+
const divisor = 1000;
|
|
402
|
+
const fixedPoint = 2;
|
|
403
|
+
const overallEnd = Date.now();
|
|
404
|
+
const totalSec = ((overallEnd - overallStart) / divisor).toFixed(fixedPoint);
|
|
405
|
+
console.log(`\nAll tasks completed. Total runtime: ${totalSec} seconds.`);
|
|
249
406
|
})
|
|
250
407
|
.help().argv;
|
|
@@ -25,7 +25,6 @@ export default class IfcStepModel extends StepModelBase<EntityTypesIfc> {
|
|
|
25
25
|
* Construct this model given a buffer containing the data and the parsed data index on that,
|
|
26
26
|
* adding the typeIndex on top of that.
|
|
27
27
|
*
|
|
28
|
-
* @param wasmModule
|
|
29
28
|
* @param buffer The buffer to values from.
|
|
30
29
|
* @param elementIndex The parsed index to elements in the STEP.
|
|
31
30
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ifc_step_model.d.ts","sourceRoot":"","sources":["../../../src/ifc/ifc_step_model.ts"],"names":[],"mappings":"AAAA,OAAO,cAAqC,MAAM,iCAAiC,CAAA;AACnF,OAAO,aAAa,MAAM,yBAAyB,CAAA;AAEnD,OAAO,EAAC,cAAc,EAAC,MAAM,6BAA6B,CAAA;AAE1D,OAAO,EAAC,aAAa,EAAC,MAAM,6BAA6B,CAAA;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AACrD,OAAO,sBAAsB,MAAM,6BAA6B,CAAA;AAChE,OAAO,cAAc,MAAM,oBAAoB,CAAA;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAKvD;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,YAAa,SAAQ,aAAa,CAAE,cAAc,CAAE;IAEvE,SAAgB,SAAS,EAAE,aAAa,CAAE,cAAc,CAAE,CAAA;IAC1D,SAAgB,mBAAmB,gCAAyB;IAC5D,SAAgB,QAAQ,mBAA+B;IACvD,SAAgB,YAAY,mBAAqC;IACjE,SAAgB,QAAQ,kBAA4B;IACpD,SAAgB,MAAM,iBAA2B;IACjD,SAAgB,aAAa,iBAAuB;IACpD,SAAgB,SAAS,mBAA+B;IACxD,SAAgB,aAAa,mBAAqC;IAElE
|
|
1
|
+
{"version":3,"file":"ifc_step_model.d.ts","sourceRoot":"","sources":["../../../src/ifc/ifc_step_model.ts"],"names":[],"mappings":"AAAA,OAAO,cAAqC,MAAM,iCAAiC,CAAA;AACnF,OAAO,aAAa,MAAM,yBAAyB,CAAA;AAEnD,OAAO,EAAC,cAAc,EAAC,MAAM,6BAA6B,CAAA;AAE1D,OAAO,EAAC,aAAa,EAAC,MAAM,6BAA6B,CAAA;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AACrD,OAAO,sBAAsB,MAAM,6BAA6B,CAAA;AAChE,OAAO,cAAc,MAAM,oBAAoB,CAAA;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAKvD;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,YAAa,SAAQ,aAAa,CAAE,cAAc,CAAE;IAEvE,SAAgB,SAAS,EAAE,aAAa,CAAE,cAAc,CAAE,CAAA;IAC1D,SAAgB,mBAAmB,gCAAyB;IAC5D,SAAgB,QAAQ,mBAA+B;IACvD,SAAgB,YAAY,mBAAqC;IACjE,SAAgB,QAAQ,kBAA4B;IACpD,SAAgB,MAAM,iBAA2B;IACjD,SAAgB,aAAa,iBAAuB;IACpD,SAAgB,SAAS,mBAA+B;IACxD,SAAgB,aAAa,mBAAqC;IAElE;;;;;;OAMG;gBAEC,MAAM,EAAE,UAAU,EAClB,YAAY,EAAE,cAAc,CAAE,cAAc,CAAE,EAAE;CAKrD"}
|
|
@@ -17,7 +17,6 @@ export default class IfcStepModel extends StepModelBase {
|
|
|
17
17
|
* Construct this model given a buffer containing the data and the parsed data index on that,
|
|
18
18
|
* adding the typeIndex on top of that.
|
|
19
19
|
*
|
|
20
|
-
* @param wasmModule
|
|
21
20
|
* @param buffer The buffer to values from.
|
|
22
21
|
* @param elementIndex The parsed index to elements in the STEP.
|
|
23
22
|
*/
|
|
@@ -20,7 +20,6 @@ export default class IfcStepParser extends StepParser<EntityTypesIfc> {
|
|
|
20
20
|
/**
|
|
21
21
|
* Parse data to the model
|
|
22
22
|
*
|
|
23
|
-
* @param wasmModule A conway-geom wasm module environnment for this.
|
|
24
23
|
* @param input The parsing buffer, set to user data, to read.
|
|
25
24
|
* @return {[ParseResult, IfcStepModel | undefined]} The parse result as well as the model,
|
|
26
25
|
* if it can be extracted.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ifc_step_parser.d.ts","sourceRoot":"","sources":["../../../src/ifc/ifc_step_parser.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,MAAM,2BAA2B,CAAA;AACrD,OAAO,UAAU,EAAE,EAAC,WAAW,EAAC,MAAM,6BAA6B,CAAA;AACnE,OAAO,cAAc,MAAM,iCAAiC,CAAA;AAE5D,OAAO,YAAY,MAAM,kBAAkB,CAAA;AAE3C;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,aAAc,SAAQ,UAAU,CAAE,cAAc,CAAE;IACrE;;OAEG;;IAKH;;;;;OAKG;IACH,gBAAuB,QAAQ,gBAAsB;IAErD
|
|
1
|
+
{"version":3,"file":"ifc_step_parser.d.ts","sourceRoot":"","sources":["../../../src/ifc/ifc_step_parser.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,MAAM,2BAA2B,CAAA;AACrD,OAAO,UAAU,EAAE,EAAC,WAAW,EAAC,MAAM,6BAA6B,CAAA;AACnE,OAAO,cAAc,MAAM,iCAAiC,CAAA;AAE5D,OAAO,YAAY,MAAM,kBAAkB,CAAA;AAE3C;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,aAAc,SAAQ,UAAU,CAAE,cAAc,CAAE;IACrE;;OAEG;;IAKH;;;;;OAKG;IACH,gBAAuB,QAAQ,gBAAsB;IAErD;;;;;;OAMG;IACI,gBAAgB,CACnB,KAAK,EAAE,aAAa,GAAI,CAAC,WAAW,EAAE,YAAY,GAAG,SAAS,CAAC;CAKpE"}
|
|
@@ -14,7 +14,6 @@ export default class IfcStepParser extends StepParser {
|
|
|
14
14
|
/**
|
|
15
15
|
* Parse data to the model
|
|
16
16
|
*
|
|
17
|
-
* @param wasmModule A conway-geom wasm module environnment for this.
|
|
18
17
|
* @param input The parsing buffer, set to user data, to read.
|
|
19
18
|
* @return {[ParseResult, IfcStepModel | undefined]} The parse result as well as the model,
|
|
20
19
|
* if it can be extracted.
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const versionString = 'Conway Web-Ifc Shim v0.
|
|
1
|
+
const versionString = 'Conway Web-Ifc Shim v0.15.836';
|
|
2
2
|
export { versionString };
|