brepjs-cad 0.173.0 → 0.175.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/CHANGELOG.md +14 -0
- package/dist/brepjs-cad.cjs +1 -1
- package/dist/brepjs-cad.js +1 -1
- package/dist/cli/main.cjs +94 -11
- package/dist/cli/main.js +95 -12
- package/dist/cli/watch.d.ts +16 -0
- package/dist/{diff-CRu6Pqyr.js → diff-B1sSWjLa.js} +40 -6
- package/dist/{diff-DDu3OLyd.cjs → diff-DX9zgrss.cjs} +40 -6
- package/dist/loader/brepjsResolve.mjs +148 -13
- package/dist/mcp/server.cjs +2 -2
- package/dist/mcp/server.js +2 -2
- package/dist/verify/runPart.d.ts +5 -0
- package/package.json +3 -3
- package/viewer/dist/assets/{brepjs-D8cjfans.js → brepjs-DzoFdLQN.js} +16 -16
- package/viewer/dist/assets/{index-BxsipSLZ.js → index-CH09YZ3K.js} +1 -1
- package/viewer/dist/assets/{kernelWorker-C-XVFH5P.js → kernelWorker-C7TmNmhp.js} +1 -1
- package/viewer/dist/index.html +1 -1
- package/viewer/dist/wasm/occt-wasm.wasm +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.175.0](https://github.com/andymai/brepjs/compare/brepjs-cad-v0.174.0...brepjs-cad-v0.175.0) (2026-08-26)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* **brepjs-cad:** transpiling loader for multi-file TS/TSX projects + working watch ([#2228](https://github.com/andymai/brepjs/issues/2228)) ([980ead6](https://github.com/andymai/brepjs/commit/980ead6508867c31fcec1fd06a683f03bacb1e6f))
|
|
9
|
+
|
|
10
|
+
## [0.174.0](https://github.com/andymai/brepjs/compare/brepjs-cad-v0.173.0...brepjs-cad-v0.174.0) (2026-08-22)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Features
|
|
14
|
+
|
|
15
|
+
* **families:** route BIM export on a declared archetype, not the family name ([#2222](https://github.com/andymai/brepjs/issues/2222)) ([53c90ae](https://github.com/andymai/brepjs/commit/53c90aef092ad24d11483fc2fbbff99b0e8eb285))
|
|
16
|
+
|
|
3
17
|
## [0.173.0](https://github.com/andymai/brepjs/compare/brepjs-cad-v0.172.0...brepjs-cad-v0.173.0) (2026-08-21)
|
|
4
18
|
|
|
5
19
|
|
package/dist/brepjs-cad.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_diff = require("./diff-
|
|
2
|
+
const require_diff = require("./diff-DX9zgrss.cjs");
|
|
3
3
|
exports.DEFAULT_TOLERANCE_PCT = require_diff.DEFAULT_TOLERANCE_PCT;
|
|
4
4
|
exports.TYPECHECK_CODE = require_diff.TYPECHECK_CODE;
|
|
5
5
|
exports.emptyReport = require_diff.emptyReport;
|
package/dist/brepjs-cad.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as typecheckPart, c as isExpectedDims, d as emptyReport, i as TYPECHECK_CODE, l as pctDelta, m as serializeReport, n as runMeasure, o as DEFAULT_TOLERANCE_PCT, r as runPart, s as evaluateExpected, t as runDiff, u as runChecks } from "./diff-
|
|
1
|
+
import { a as typecheckPart, c as isExpectedDims, d as emptyReport, i as TYPECHECK_CODE, l as pctDelta, m as serializeReport, n as runMeasure, o as DEFAULT_TOLERANCE_PCT, r as runPart, s as evaluateExpected, t as runDiff, u as runChecks } from "./diff-B1sSWjLa.js";
|
|
2
2
|
export { DEFAULT_TOLERANCE_PCT, TYPECHECK_CODE, emptyReport, evaluateExpected, isExpectedDims, pctDelta, runChecks, runDiff, runMeasure, runPart, serializeReport, typecheckPart };
|
package/dist/cli/main.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
-
const require_diff = require("../diff-
|
|
3
|
+
const require_diff = require("../diff-DX9zgrss.cjs");
|
|
4
4
|
let node_url = require("node:url");
|
|
5
5
|
let node_fs = require("node:fs");
|
|
6
6
|
let node_path = require("node:path");
|
|
@@ -117,6 +117,74 @@ function debounce(fn, delayMs = 150) {
|
|
|
117
117
|
cancel
|
|
118
118
|
};
|
|
119
119
|
}
|
|
120
|
+
var SOURCE_FILE_RE = /\.(?:m?[jt]s|[jt]sx)$/;
|
|
121
|
+
function isWatchRelevant(filename) {
|
|
122
|
+
if (filename === void 0 || filename === null) return true;
|
|
123
|
+
const name = filename.toString();
|
|
124
|
+
if (/(?:^|[\\/])tsconfig(?:\..+)?\.json$/.test(name)) return true;
|
|
125
|
+
return SOURCE_FILE_RE.test(name);
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Root the watcher at the project, not the entry's own directory: with the common
|
|
129
|
+
* `src/main.ts` layout, tsconfig.json (whose JSX options change how sources transpile)
|
|
130
|
+
* and `../` imports live one level up. Nearest package.json or tsconfig.json walking up
|
|
131
|
+
* wins; entries with no project marker fall back to their own directory.
|
|
132
|
+
*/
|
|
133
|
+
function watchRootFor(entryPath) {
|
|
134
|
+
const start = (0, node_path.dirname)(entryPath);
|
|
135
|
+
let dir = start;
|
|
136
|
+
for (;;) {
|
|
137
|
+
if ((0, node_fs.existsSync)((0, node_path.join)(dir, "package.json")) || (0, node_fs.existsSync)((0, node_path.join)(dir, "tsconfig.json"))) return dir;
|
|
138
|
+
const parent = (0, node_path.dirname)(dir);
|
|
139
|
+
if (parent === dir) return start;
|
|
140
|
+
dir = parent;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
var IGNORED_DIR_NAMES = /* @__PURE__ */ new Set([
|
|
144
|
+
"node_modules",
|
|
145
|
+
"dist",
|
|
146
|
+
".git"
|
|
147
|
+
]);
|
|
148
|
+
/**
|
|
149
|
+
* Watch a directory tree with one non-recursive `fs.watch` per directory, skipping
|
|
150
|
+
* node_modules/dist/.git and never following symlinks. `fs.watch({recursive})` has no
|
|
151
|
+
* exclusion API, so on a real project it would descend into node_modules — tens of
|
|
152
|
+
* thousands of inotify watches. Whenever an event fires in a directory it is re-scanned,
|
|
153
|
+
* which picks up newly created subdirectories. Returns a stop function.
|
|
154
|
+
*/
|
|
155
|
+
function watchTree(root, onEvent) {
|
|
156
|
+
const watchers = /* @__PURE__ */ new Map();
|
|
157
|
+
const add = (dir) => {
|
|
158
|
+
if (watchers.has(dir)) return;
|
|
159
|
+
try {
|
|
160
|
+
watchers.set(dir, (0, node_fs.watch)(dir, (_event, filename) => {
|
|
161
|
+
scan(dir);
|
|
162
|
+
onEvent(filename);
|
|
163
|
+
}));
|
|
164
|
+
} catch {}
|
|
165
|
+
};
|
|
166
|
+
const scan = (dir) => {
|
|
167
|
+
let entries;
|
|
168
|
+
try {
|
|
169
|
+
entries = (0, node_fs.readdirSync)(dir, { withFileTypes: true });
|
|
170
|
+
} catch {
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
for (const entry of entries) {
|
|
174
|
+
if (!entry.isDirectory() || IGNORED_DIR_NAMES.has(entry.name)) continue;
|
|
175
|
+
const child = (0, node_path.join)(dir, entry.name);
|
|
176
|
+
if (watchers.has(child)) continue;
|
|
177
|
+
add(child);
|
|
178
|
+
scan(child);
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
add(root);
|
|
182
|
+
scan(root);
|
|
183
|
+
return () => {
|
|
184
|
+
for (const watcher of watchers.values()) watcher.close();
|
|
185
|
+
watchers.clear();
|
|
186
|
+
};
|
|
187
|
+
}
|
|
120
188
|
//#endregion
|
|
121
189
|
//#region src/disposeShape.ts
|
|
122
190
|
function disposeShape(shape) {
|
|
@@ -436,9 +504,9 @@ program.command("init").argument("<name>", "part name; scaffolds <name>.brep.ts
|
|
|
436
504
|
});
|
|
437
505
|
program.command("watch").argument("<file>", "path to a .brep.ts module; re-verifies on each save until Ctrl-C").action((file) => {
|
|
438
506
|
const path = (0, node_path.resolve)(file);
|
|
439
|
-
const run = async () => {
|
|
507
|
+
const run = async (fresh) => {
|
|
440
508
|
try {
|
|
441
|
-
const { report, shape } = await require_diff.runPart(path);
|
|
509
|
+
const { report, shape } = await require_diff.runPart(path, { freshImport: fresh });
|
|
442
510
|
try {
|
|
443
511
|
process.stdout.write(require_diff.serializeReport(report) + "\n");
|
|
444
512
|
} finally {
|
|
@@ -448,18 +516,33 @@ program.command("watch").argument("<file>", "path to a .brep.ts module; re-verif
|
|
|
448
516
|
process.stderr.write(`watch run failed: ${e.message}\n`);
|
|
449
517
|
}
|
|
450
518
|
};
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
519
|
+
let inFlight = false;
|
|
520
|
+
let rerunQueued = false;
|
|
521
|
+
const start = (fresh) => {
|
|
522
|
+
inFlight = true;
|
|
523
|
+
run(fresh).finally(() => {
|
|
524
|
+
inFlight = false;
|
|
525
|
+
if (rerunQueued) {
|
|
526
|
+
rerunQueued = false;
|
|
527
|
+
start(true);
|
|
528
|
+
}
|
|
529
|
+
});
|
|
530
|
+
};
|
|
531
|
+
const schedule = () => {
|
|
532
|
+
if (inFlight) {
|
|
533
|
+
rerunQueued = true;
|
|
457
534
|
return;
|
|
458
535
|
}
|
|
459
|
-
|
|
536
|
+
start(true);
|
|
537
|
+
};
|
|
538
|
+
const { trigger } = debounce(schedule, 150);
|
|
539
|
+
process.stderr.write(`watching ${path} (Ctrl-C to stop)\n`);
|
|
540
|
+
start(false);
|
|
541
|
+
const stopWatching = watchTree(watchRootFor(path), (filename) => {
|
|
542
|
+
if (isWatchRelevant(filename)) trigger();
|
|
460
543
|
});
|
|
461
544
|
const stop = () => {
|
|
462
|
-
|
|
545
|
+
stopWatching();
|
|
463
546
|
process.exit(0);
|
|
464
547
|
};
|
|
465
548
|
process.on("SIGINT", stop);
|
package/dist/cli/main.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { f as pushError, h as loadBrep, m as serializeReport, n as runMeasure, p as reportOk, r as runPart, t as runDiff } from "../diff-
|
|
2
|
+
import { f as pushError, h as loadBrep, m as serializeReport, n as runMeasure, p as reportOk, r as runPart, t as runDiff } from "../diff-B1sSWjLa.js";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
|
-
import { existsSync, globSync, mkdirSync, realpathSync, watch, writeFileSync } from "node:fs";
|
|
4
|
+
import { existsSync, globSync, mkdirSync, readdirSync, realpathSync, watch, writeFileSync } from "node:fs";
|
|
5
5
|
import { basename, dirname, join, resolve } from "node:path";
|
|
6
6
|
import { Command } from "commander";
|
|
7
7
|
import { tmpdir } from "node:os";
|
|
@@ -116,6 +116,74 @@ function debounce(fn, delayMs = 150) {
|
|
|
116
116
|
cancel
|
|
117
117
|
};
|
|
118
118
|
}
|
|
119
|
+
var SOURCE_FILE_RE = /\.(?:m?[jt]s|[jt]sx)$/;
|
|
120
|
+
function isWatchRelevant(filename) {
|
|
121
|
+
if (filename === void 0 || filename === null) return true;
|
|
122
|
+
const name = filename.toString();
|
|
123
|
+
if (/(?:^|[\\/])tsconfig(?:\..+)?\.json$/.test(name)) return true;
|
|
124
|
+
return SOURCE_FILE_RE.test(name);
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Root the watcher at the project, not the entry's own directory: with the common
|
|
128
|
+
* `src/main.ts` layout, tsconfig.json (whose JSX options change how sources transpile)
|
|
129
|
+
* and `../` imports live one level up. Nearest package.json or tsconfig.json walking up
|
|
130
|
+
* wins; entries with no project marker fall back to their own directory.
|
|
131
|
+
*/
|
|
132
|
+
function watchRootFor(entryPath) {
|
|
133
|
+
const start = dirname(entryPath);
|
|
134
|
+
let dir = start;
|
|
135
|
+
for (;;) {
|
|
136
|
+
if (existsSync(join(dir, "package.json")) || existsSync(join(dir, "tsconfig.json"))) return dir;
|
|
137
|
+
const parent = dirname(dir);
|
|
138
|
+
if (parent === dir) return start;
|
|
139
|
+
dir = parent;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
var IGNORED_DIR_NAMES = /* @__PURE__ */ new Set([
|
|
143
|
+
"node_modules",
|
|
144
|
+
"dist",
|
|
145
|
+
".git"
|
|
146
|
+
]);
|
|
147
|
+
/**
|
|
148
|
+
* Watch a directory tree with one non-recursive `fs.watch` per directory, skipping
|
|
149
|
+
* node_modules/dist/.git and never following symlinks. `fs.watch({recursive})` has no
|
|
150
|
+
* exclusion API, so on a real project it would descend into node_modules — tens of
|
|
151
|
+
* thousands of inotify watches. Whenever an event fires in a directory it is re-scanned,
|
|
152
|
+
* which picks up newly created subdirectories. Returns a stop function.
|
|
153
|
+
*/
|
|
154
|
+
function watchTree(root, onEvent) {
|
|
155
|
+
const watchers = /* @__PURE__ */ new Map();
|
|
156
|
+
const add = (dir) => {
|
|
157
|
+
if (watchers.has(dir)) return;
|
|
158
|
+
try {
|
|
159
|
+
watchers.set(dir, watch(dir, (_event, filename) => {
|
|
160
|
+
scan(dir);
|
|
161
|
+
onEvent(filename);
|
|
162
|
+
}));
|
|
163
|
+
} catch {}
|
|
164
|
+
};
|
|
165
|
+
const scan = (dir) => {
|
|
166
|
+
let entries;
|
|
167
|
+
try {
|
|
168
|
+
entries = readdirSync(dir, { withFileTypes: true });
|
|
169
|
+
} catch {
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
for (const entry of entries) {
|
|
173
|
+
if (!entry.isDirectory() || IGNORED_DIR_NAMES.has(entry.name)) continue;
|
|
174
|
+
const child = join(dir, entry.name);
|
|
175
|
+
if (watchers.has(child)) continue;
|
|
176
|
+
add(child);
|
|
177
|
+
scan(child);
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
add(root);
|
|
181
|
+
scan(root);
|
|
182
|
+
return () => {
|
|
183
|
+
for (const watcher of watchers.values()) watcher.close();
|
|
184
|
+
watchers.clear();
|
|
185
|
+
};
|
|
186
|
+
}
|
|
119
187
|
//#endregion
|
|
120
188
|
//#region src/disposeShape.ts
|
|
121
189
|
function disposeShape(shape) {
|
|
@@ -435,9 +503,9 @@ program.command("init").argument("<name>", "part name; scaffolds <name>.brep.ts
|
|
|
435
503
|
});
|
|
436
504
|
program.command("watch").argument("<file>", "path to a .brep.ts module; re-verifies on each save until Ctrl-C").action((file) => {
|
|
437
505
|
const path = resolve(file);
|
|
438
|
-
const run = async () => {
|
|
506
|
+
const run = async (fresh) => {
|
|
439
507
|
try {
|
|
440
|
-
const { report, shape } = await runPart(path);
|
|
508
|
+
const { report, shape } = await runPart(path, { freshImport: fresh });
|
|
441
509
|
try {
|
|
442
510
|
process.stdout.write(serializeReport(report) + "\n");
|
|
443
511
|
} finally {
|
|
@@ -447,18 +515,33 @@ program.command("watch").argument("<file>", "path to a .brep.ts module; re-verif
|
|
|
447
515
|
process.stderr.write(`watch run failed: ${e.message}\n`);
|
|
448
516
|
}
|
|
449
517
|
};
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
518
|
+
let inFlight = false;
|
|
519
|
+
let rerunQueued = false;
|
|
520
|
+
const start = (fresh) => {
|
|
521
|
+
inFlight = true;
|
|
522
|
+
run(fresh).finally(() => {
|
|
523
|
+
inFlight = false;
|
|
524
|
+
if (rerunQueued) {
|
|
525
|
+
rerunQueued = false;
|
|
526
|
+
start(true);
|
|
527
|
+
}
|
|
528
|
+
});
|
|
529
|
+
};
|
|
530
|
+
const schedule = () => {
|
|
531
|
+
if (inFlight) {
|
|
532
|
+
rerunQueued = true;
|
|
456
533
|
return;
|
|
457
534
|
}
|
|
458
|
-
|
|
535
|
+
start(true);
|
|
536
|
+
};
|
|
537
|
+
const { trigger } = debounce(schedule, 150);
|
|
538
|
+
process.stderr.write(`watching ${path} (Ctrl-C to stop)\n`);
|
|
539
|
+
start(false);
|
|
540
|
+
const stopWatching = watchTree(watchRootFor(path), (filename) => {
|
|
541
|
+
if (isWatchRelevant(filename)) trigger();
|
|
459
542
|
});
|
|
460
543
|
const stop = () => {
|
|
461
|
-
|
|
544
|
+
stopWatching();
|
|
462
545
|
process.exit(0);
|
|
463
546
|
};
|
|
464
547
|
process.on("SIGINT", stop);
|
package/dist/cli/watch.d.ts
CHANGED
|
@@ -3,3 +3,19 @@ export declare function debounce(fn: () => void | Promise<void>, delayMs?: numbe
|
|
|
3
3
|
trigger: () => void;
|
|
4
4
|
cancel: () => void;
|
|
5
5
|
};
|
|
6
|
+
export declare function isWatchRelevant(filename: string | Buffer | null | undefined): boolean;
|
|
7
|
+
/**
|
|
8
|
+
* Root the watcher at the project, not the entry's own directory: with the common
|
|
9
|
+
* `src/main.ts` layout, tsconfig.json (whose JSX options change how sources transpile)
|
|
10
|
+
* and `../` imports live one level up. Nearest package.json or tsconfig.json walking up
|
|
11
|
+
* wins; entries with no project marker fall back to their own directory.
|
|
12
|
+
*/
|
|
13
|
+
export declare function watchRootFor(entryPath: string): string;
|
|
14
|
+
/**
|
|
15
|
+
* Watch a directory tree with one non-recursive `fs.watch` per directory, skipping
|
|
16
|
+
* node_modules/dist/.git and never following symlinks. `fs.watch({recursive})` has no
|
|
17
|
+
* exclusion API, so on a real project it would descend into node_modules — tens of
|
|
18
|
+
* thousands of inotify watches. Whenever an event fires in a directory it is re-scanned,
|
|
19
|
+
* which picks up newly created subdirectories. Returns a stop function.
|
|
20
|
+
*/
|
|
21
|
+
export declare function watchTree(root: string, onEvent: (filename: string | Buffer | null | undefined) => void): () => void;
|
|
@@ -19,8 +19,9 @@ function toolDir() {
|
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
function loaderUrl(dir) {
|
|
22
|
-
const built = resolve(dir, "dist", "loader", "brepjsResolve.mjs");
|
|
23
22
|
const source = resolve(dir, "src", "loader", "brepjsResolve.mjs");
|
|
23
|
+
const built = resolve(dir, "dist", "loader", "brepjsResolve.mjs");
|
|
24
|
+
if (import.meta.url.startsWith(pathToFileURL(resolve(dir, "src") + "/").href)) return pathToFileURL(source).href;
|
|
24
25
|
return pathToFileURL(existsSync(built) ? built : source).href;
|
|
25
26
|
}
|
|
26
27
|
function registerHook() {
|
|
@@ -696,6 +697,33 @@ function packageRootOf(startDir, name) {
|
|
|
696
697
|
dir = dirname(dir);
|
|
697
698
|
}
|
|
698
699
|
}
|
|
700
|
+
/**
|
|
701
|
+
* JSX options for a part come from the nearest tsconfig.json — the same source the
|
|
702
|
+
* runtime load hook reads — so `--check` and execution agree on the dialect
|
|
703
|
+
* (families projects set `jsx: react-jsx` + `jsxImportSource: brepjs-families`).
|
|
704
|
+
* A `.tsx` part with nothing configured defaults to the automatic runtime.
|
|
705
|
+
*/
|
|
706
|
+
function jsxCompilerOptions(partPath) {
|
|
707
|
+
const out = {};
|
|
708
|
+
const configPath = ts.findConfigFile(dirname(partPath), (f) => ts.sys.fileExists(f));
|
|
709
|
+
if (configPath) {
|
|
710
|
+
const host = {
|
|
711
|
+
...ts.sys,
|
|
712
|
+
onUnRecoverableConfigFileDiagnostic: () => {}
|
|
713
|
+
};
|
|
714
|
+
const parsed = ts.getParsedCommandLineOfConfigFile(configPath, void 0, host);
|
|
715
|
+
if (parsed) {
|
|
716
|
+
for (const key of [
|
|
717
|
+
"jsx",
|
|
718
|
+
"jsxImportSource",
|
|
719
|
+
"jsxFactory",
|
|
720
|
+
"jsxFragmentFactory"
|
|
721
|
+
]) if (parsed.options[key] !== void 0) out[key] = parsed.options[key];
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
if (partPath.endsWith(".tsx") && out.jsx === void 0) out.jsx = ts.JsxEmit.ReactJSX;
|
|
725
|
+
return out;
|
|
726
|
+
}
|
|
699
727
|
var COMPILER_OPTIONS = {
|
|
700
728
|
target: ts.ScriptTarget.ES2022,
|
|
701
729
|
module: ts.ModuleKind.ESNext,
|
|
@@ -747,7 +775,10 @@ function diagnosticToErrorInfo(d) {
|
|
|
747
775
|
*/
|
|
748
776
|
function typecheckPart(partPath, toolDir) {
|
|
749
777
|
const dts = resolveBrepjsTypes(partPath, toolDir);
|
|
750
|
-
const options = {
|
|
778
|
+
const options = {
|
|
779
|
+
...COMPILER_OPTIONS,
|
|
780
|
+
...jsxCompilerOptions(partPath)
|
|
781
|
+
};
|
|
751
782
|
if (dts) options.paths = { brepjs: [dts] };
|
|
752
783
|
const typesRoot = nodeTypesRoot(partPath, toolDir);
|
|
753
784
|
if (typesRoot) {
|
|
@@ -800,12 +831,15 @@ function buildMaterialMap(m, spec) {
|
|
|
800
831
|
}
|
|
801
832
|
return map.size > 0 ? { map } : {};
|
|
802
833
|
}
|
|
803
|
-
|
|
834
|
+
var importGeneration = 0;
|
|
835
|
+
async function loadPart(modulePath, fresh = false) {
|
|
836
|
+
const url = new URL(pathToFileURL(modulePath).href);
|
|
837
|
+
if (fresh) url.searchParams.set("v", String(++importGeneration));
|
|
804
838
|
try {
|
|
805
|
-
return await import(
|
|
839
|
+
return await import(url.href);
|
|
806
840
|
} catch (e) {
|
|
807
841
|
const msg = e instanceof Error ? e.message : String(e);
|
|
808
|
-
if (/\.[mc]?tsx?$/.test(modulePath) && /import statement|file extension/i.test(msg)) throw new Error(`cannot load TypeScript part "${modulePath}": author parts in an ESM project (set "type": "module" in package.json)
|
|
842
|
+
if (/\.[mc]?tsx?$/.test(modulePath) && /import statement|file extension/i.test(msg)) throw new Error(`cannot load TypeScript part "${modulePath}": author parts in an ESM project (set "type": "module" in package.json). (${msg})`, { cause: e });
|
|
809
843
|
throw e;
|
|
810
844
|
}
|
|
811
845
|
}
|
|
@@ -865,7 +899,7 @@ async function runPart(modulePath, opts = {}) {
|
|
|
865
899
|
const { isOk, mesh, exportGlb, exportSTEP } = brep;
|
|
866
900
|
let mod;
|
|
867
901
|
try {
|
|
868
|
-
mod = await loadPart(modulePath);
|
|
902
|
+
mod = await loadPart(modulePath, opts.freshImport);
|
|
869
903
|
} catch (e) {
|
|
870
904
|
pushError(report, toErrorInfo("import failed", e));
|
|
871
905
|
return finalize({
|
|
@@ -21,8 +21,9 @@ function toolDir() {
|
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
function loaderUrl(dir) {
|
|
24
|
-
const built = (0, node_path.resolve)(dir, "dist", "loader", "brepjsResolve.mjs");
|
|
25
24
|
const source = (0, node_path.resolve)(dir, "src", "loader", "brepjsResolve.mjs");
|
|
25
|
+
const built = (0, node_path.resolve)(dir, "dist", "loader", "brepjsResolve.mjs");
|
|
26
|
+
if ({}.url.startsWith((0, node_url.pathToFileURL)((0, node_path.resolve)(dir, "src") + "/").href)) return (0, node_url.pathToFileURL)(source).href;
|
|
26
27
|
return (0, node_url.pathToFileURL)((0, node_fs.existsSync)(built) ? built : source).href;
|
|
27
28
|
}
|
|
28
29
|
function registerHook() {
|
|
@@ -698,6 +699,33 @@ function packageRootOf(startDir, name) {
|
|
|
698
699
|
dir = (0, node_path.dirname)(dir);
|
|
699
700
|
}
|
|
700
701
|
}
|
|
702
|
+
/**
|
|
703
|
+
* JSX options for a part come from the nearest tsconfig.json — the same source the
|
|
704
|
+
* runtime load hook reads — so `--check` and execution agree on the dialect
|
|
705
|
+
* (families projects set `jsx: react-jsx` + `jsxImportSource: brepjs-families`).
|
|
706
|
+
* A `.tsx` part with nothing configured defaults to the automatic runtime.
|
|
707
|
+
*/
|
|
708
|
+
function jsxCompilerOptions(partPath) {
|
|
709
|
+
const out = {};
|
|
710
|
+
const configPath = typescript.default.findConfigFile((0, node_path.dirname)(partPath), (f) => typescript.default.sys.fileExists(f));
|
|
711
|
+
if (configPath) {
|
|
712
|
+
const host = {
|
|
713
|
+
...typescript.default.sys,
|
|
714
|
+
onUnRecoverableConfigFileDiagnostic: () => {}
|
|
715
|
+
};
|
|
716
|
+
const parsed = typescript.default.getParsedCommandLineOfConfigFile(configPath, void 0, host);
|
|
717
|
+
if (parsed) {
|
|
718
|
+
for (const key of [
|
|
719
|
+
"jsx",
|
|
720
|
+
"jsxImportSource",
|
|
721
|
+
"jsxFactory",
|
|
722
|
+
"jsxFragmentFactory"
|
|
723
|
+
]) if (parsed.options[key] !== void 0) out[key] = parsed.options[key];
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
if (partPath.endsWith(".tsx") && out.jsx === void 0) out.jsx = typescript.default.JsxEmit.ReactJSX;
|
|
727
|
+
return out;
|
|
728
|
+
}
|
|
701
729
|
var COMPILER_OPTIONS = {
|
|
702
730
|
target: typescript.default.ScriptTarget.ES2022,
|
|
703
731
|
module: typescript.default.ModuleKind.ESNext,
|
|
@@ -749,7 +777,10 @@ function diagnosticToErrorInfo(d) {
|
|
|
749
777
|
*/
|
|
750
778
|
function typecheckPart(partPath, toolDir) {
|
|
751
779
|
const dts = resolveBrepjsTypes(partPath, toolDir);
|
|
752
|
-
const options = {
|
|
780
|
+
const options = {
|
|
781
|
+
...COMPILER_OPTIONS,
|
|
782
|
+
...jsxCompilerOptions(partPath)
|
|
783
|
+
};
|
|
753
784
|
if (dts) options.paths = { brepjs: [dts] };
|
|
754
785
|
const typesRoot = nodeTypesRoot(partPath, toolDir);
|
|
755
786
|
if (typesRoot) {
|
|
@@ -802,12 +833,15 @@ function buildMaterialMap(m, spec) {
|
|
|
802
833
|
}
|
|
803
834
|
return map.size > 0 ? { map } : {};
|
|
804
835
|
}
|
|
805
|
-
|
|
836
|
+
var importGeneration = 0;
|
|
837
|
+
async function loadPart(modulePath, fresh = false) {
|
|
838
|
+
const url = new URL((0, node_url.pathToFileURL)(modulePath).href);
|
|
839
|
+
if (fresh) url.searchParams.set("v", String(++importGeneration));
|
|
806
840
|
try {
|
|
807
|
-
return await import(
|
|
841
|
+
return await import(url.href);
|
|
808
842
|
} catch (e) {
|
|
809
843
|
const msg = e instanceof Error ? e.message : String(e);
|
|
810
|
-
if (/\.[mc]?tsx?$/.test(modulePath) && /import statement|file extension/i.test(msg)) throw new Error(`cannot load TypeScript part "${modulePath}": author parts in an ESM project (set "type": "module" in package.json)
|
|
844
|
+
if (/\.[mc]?tsx?$/.test(modulePath) && /import statement|file extension/i.test(msg)) throw new Error(`cannot load TypeScript part "${modulePath}": author parts in an ESM project (set "type": "module" in package.json). (${msg})`, { cause: e });
|
|
811
845
|
throw e;
|
|
812
846
|
}
|
|
813
847
|
}
|
|
@@ -867,7 +901,7 @@ async function runPart(modulePath, opts = {}) {
|
|
|
867
901
|
const { isOk, mesh, exportGlb, exportSTEP } = brep;
|
|
868
902
|
let mod;
|
|
869
903
|
try {
|
|
870
|
-
mod = await loadPart(modulePath);
|
|
904
|
+
mod = await loadPart(modulePath, opts.freshImport);
|
|
871
905
|
} catch (e) {
|
|
872
906
|
pushError(report, toErrorInfo("import failed", e));
|
|
873
907
|
return finalize({
|