brepjs-cad 0.1.0 → 0.2.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 +16 -0
- package/dist/brepjs-cad.cjs +1 -1
- package/dist/brepjs-cad.js +1 -1
- package/dist/cli/main.cjs +59 -52
- package/dist/cli/main.d.ts +1 -0
- package/dist/cli/main.js +61 -55
- package/dist/cli/watch.d.ts +0 -5
- package/dist/{diff-ByiVwVrr.js → diff-DhKrjOVB.js} +48 -25
- package/dist/{diff-4UNdqx4k.cjs → diff-DyOhTrZ3.cjs} +0 -0
- package/dist/disposeShape.d.ts +0 -5
- package/dist/snapshot/registry.cjs +1 -1
- package/dist/snapshot/registry.js +1 -1
- package/dist/snapshot/static.cjs +2 -1
- package/dist/snapshot/static.js +2 -1
- package/dist/verify/report.d.ts +0 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
|
+
|
|
3
|
+
## [0.2.0](https://github.com/andymai/brepjs/compare/brepjs-cad-v0.1.0...brepjs-cad-v0.2.0) (2026-06-04)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* **brepjs-cad:** CLI subcommands + verify hints + gridfinity examples + eval harness ([#1204](https://github.com/andymai/brepjs/issues/1204)) ([4d57198](https://github.com/andymai/brepjs/commit/4d5719874b5f5e685a4f909fd2d2363c0331770b))
|
|
9
|
+
* **brepjs-cad:** rename from brepjs-agent + make npm-publishable (publish held) ([#1201](https://github.com/andymai/brepjs/issues/1201)) ([630bbba](https://github.com/andymai/brepjs/commit/630bbbab4885604bd4d5fb2148584a6572c8d99c))
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
### Bug Fixes
|
|
13
|
+
|
|
14
|
+
* **brepjs-cad:** run CLI via bin symlink + quality pass ([#1206](https://github.com/andymai/brepjs/issues/1206)) ([ac5b1fe](https://github.com/andymai/brepjs/commit/ac5b1feee3c5b424c37716ca06c397f7898838f1))
|
|
15
|
+
* **opencascade:** prevent LTO stripping of custom bindings ([#666](https://github.com/andymai/brepjs/issues/666)) ([977dd75](https://github.com/andymai/brepjs/commit/977dd757e162d6fa47152b14aa31bac4edd9ae82))
|
|
16
|
+
|
|
17
|
+
## Changelog
|
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-DyOhTrZ3.cjs");
|
|
3
3
|
exports.emptyReport = require_diff.emptyReport;
|
|
4
4
|
exports.runChecks = require_diff.runChecks;
|
|
5
5
|
exports.runDiff = require_diff.runDiff;
|
package/dist/brepjs-cad.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as emptyReport, i as runChecks, n as runMeasure, r as runPart,
|
|
1
|
+
import { a as emptyReport, c as serializeReport, i as runChecks, n as runMeasure, r as runPart, t as runDiff } from "./diff-DhKrjOVB.js";
|
|
2
2
|
export { emptyReport, runChecks, runDiff, runMeasure, runPart, serializeReport };
|
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-DyOhTrZ3.cjs");
|
|
4
4
|
let brepjs = require("brepjs");
|
|
5
5
|
let commander = require("commander");
|
|
6
6
|
let node_fs = require("node:fs");
|
|
@@ -97,11 +97,6 @@ function scaffoldPart(name, dir) {
|
|
|
97
97
|
files
|
|
98
98
|
};
|
|
99
99
|
}
|
|
100
|
-
/**
|
|
101
|
-
* Wraps a handler so bursts of rapid calls collapse into a single trailing
|
|
102
|
-
* invocation after `delayMs` of quiet — fs.watch fires twice per save on many
|
|
103
|
-
* platforms, so the model is re-run once rather than per raw event.
|
|
104
|
-
*/
|
|
105
100
|
function debounce(fn, delayMs = 150) {
|
|
106
101
|
let timer;
|
|
107
102
|
const cancel = () => {
|
|
@@ -124,11 +119,6 @@ function debounce(fn, delayMs = 150) {
|
|
|
124
119
|
}
|
|
125
120
|
//#endregion
|
|
126
121
|
//#region src/disposeShape.ts
|
|
127
|
-
/**
|
|
128
|
-
* Release a live WASM-backed kernel shape handle returned by `runPart`.
|
|
129
|
-
* No-op for null/undefined or shapes without a disposer, so callers can pass
|
|
130
|
-
* `result.shape` unconditionally. WASM memory accumulates without this.
|
|
131
|
-
*/
|
|
132
122
|
function disposeShape(shape) {
|
|
133
123
|
const disposer = shape?.[Symbol.dispose];
|
|
134
124
|
if (typeof disposer === "function") disposer.call(shape);
|
|
@@ -139,7 +129,6 @@ function stem(file) {
|
|
|
139
129
|
return (0, node_path.basename)(file).replace(/\.brep\.ts$/, "").replace(/\.ts$/, "");
|
|
140
130
|
}
|
|
141
131
|
async function exportPart(modulePath, formats, outDir) {
|
|
142
|
-
const wantStl = Boolean(formats.stl);
|
|
143
132
|
const { shape, report, step, glb } = await require_diff.runPart(modulePath, {
|
|
144
133
|
step: Boolean(formats.step),
|
|
145
134
|
glb: Boolean(formats.glb)
|
|
@@ -148,34 +137,38 @@ async function exportPart(modulePath, formats, outDir) {
|
|
|
148
137
|
const written = [];
|
|
149
138
|
if (!(require_diff.reportOk(report) && shape !== null)) {
|
|
150
139
|
disposeShape(shape);
|
|
140
|
+
const failures = report.errorInfos.map((e) => e.message);
|
|
151
141
|
return {
|
|
152
142
|
ok: false,
|
|
153
143
|
report,
|
|
154
144
|
written,
|
|
155
|
-
errors: report.errors
|
|
145
|
+
errors: failures.length > 0 ? failures : report.errors
|
|
156
146
|
};
|
|
157
147
|
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
} else errors.push("GLB export produced no data");
|
|
170
|
-
if (wantStl) {
|
|
171
|
-
const r = (0, brepjs.exportSTL)(shape);
|
|
172
|
-
if ((0, brepjs.isOk)(r)) {
|
|
173
|
-
const p = (0, node_path.join)(outDir, `${base}.stl`);
|
|
174
|
-
(0, node_fs.writeFileSync)(p, Buffer.from(await r.value.arrayBuffer()));
|
|
148
|
+
try {
|
|
149
|
+
if (!(0, node_fs.existsSync)(outDir)) (0, node_fs.mkdirSync)(outDir, { recursive: true });
|
|
150
|
+
const base = stem(modulePath);
|
|
151
|
+
if (formats.step) if (step) {
|
|
152
|
+
const p = (0, node_path.join)(outDir, `${base}.step`);
|
|
153
|
+
(0, node_fs.writeFileSync)(p, Buffer.from(step));
|
|
154
|
+
written.push(p);
|
|
155
|
+
} else errors.push("STEP export produced no data");
|
|
156
|
+
if (formats.glb) if (glb) {
|
|
157
|
+
const p = (0, node_path.join)(outDir, `${base}.glb`);
|
|
158
|
+
(0, node_fs.writeFileSync)(p, Buffer.from(glb));
|
|
175
159
|
written.push(p);
|
|
176
|
-
} else errors.push(
|
|
160
|
+
} else errors.push("GLB export produced no data");
|
|
161
|
+
if (formats.stl) {
|
|
162
|
+
const r = (0, brepjs.exportSTL)(shape);
|
|
163
|
+
if ((0, brepjs.isOk)(r)) {
|
|
164
|
+
const p = (0, node_path.join)(outDir, `${base}.stl`);
|
|
165
|
+
(0, node_fs.writeFileSync)(p, Buffer.from(await r.value.arrayBuffer()));
|
|
166
|
+
written.push(p);
|
|
167
|
+
} else errors.push(`STL export: ${r.error.message}`);
|
|
168
|
+
}
|
|
169
|
+
} finally {
|
|
170
|
+
disposeShape(shape);
|
|
177
171
|
}
|
|
178
|
-
disposeShape(shape);
|
|
179
172
|
return {
|
|
180
173
|
ok: errors.length === 0,
|
|
181
174
|
report,
|
|
@@ -201,32 +194,37 @@ var program = new commander.Command();
|
|
|
201
194
|
program.name("brepjs");
|
|
202
195
|
program.command("verify", { isDefault: true }).argument("<file>", "path to a .brep.ts module with a default-exported part function").option("--step <out>", "write the primary STEP artifact to this path").option("--glb <out>", "write a derived GLB preview to this path").option("--json <out>", "write the JSON report to this path").option("--snapshot <dir>", "render iso/front/top/right PNGs to this dir (requires built viewer)").option("--serve", "after verifying, start a preview server and print a ?dir=&file= deep link (stays running)").action(async (file, opts) => {
|
|
203
196
|
const wantStep = Boolean(opts.step) || Boolean(opts.snapshot) || Boolean(opts.serve);
|
|
204
|
-
const { report, step, glb } = await require_diff.runPart((0, node_path.resolve)(file), {
|
|
197
|
+
const { report, step, glb, shape } = await require_diff.runPart((0, node_path.resolve)(file), {
|
|
205
198
|
step: wantStep,
|
|
206
199
|
glb: Boolean(opts.glb)
|
|
207
200
|
});
|
|
208
|
-
const json = require_diff.serializeReport(report);
|
|
209
|
-
if (opts.json) (0, node_fs.writeFileSync)(opts.json, json);
|
|
210
|
-
if (opts.glb && glb) (0, node_fs.writeFileSync)(opts.glb, Buffer.from(glb));
|
|
211
201
|
let stepPath = opts.step;
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
const shoot = await loadSnapshotShoot();
|
|
218
|
-
if (shoot) {
|
|
219
|
-
const { pngs } = await shoot({
|
|
220
|
-
file: stepPath,
|
|
221
|
-
outDir: opts.snapshot
|
|
222
|
-
});
|
|
223
|
-
for (const p of pngs) process.stderr.write(`snapshot: ${p}\n`);
|
|
202
|
+
try {
|
|
203
|
+
if (opts.glb && glb) (0, node_fs.writeFileSync)(opts.glb, Buffer.from(glb));
|
|
204
|
+
if (wantStep && step) {
|
|
205
|
+
stepPath = opts.step ?? (0, node_path.join)((0, node_os.tmpdir)(), `brepjs-cad-${(0, node_path.basename)(file)}.step`);
|
|
206
|
+
(0, node_fs.writeFileSync)(stepPath, Buffer.from(step));
|
|
224
207
|
}
|
|
208
|
+
if (opts.snapshot && stepPath) {
|
|
209
|
+
const shoot = await loadSnapshotShoot();
|
|
210
|
+
if (shoot) {
|
|
211
|
+
const { pngs } = await shoot({
|
|
212
|
+
file: stepPath,
|
|
213
|
+
outDir: opts.snapshot
|
|
214
|
+
});
|
|
215
|
+
for (const p of pngs) process.stderr.write(`snapshot: ${p}\n`);
|
|
216
|
+
}
|
|
217
|
+
} else if (opts.snapshot) process.stderr.write("snapshot skipped: STEP export produced no artifact\n");
|
|
218
|
+
} catch (e) {
|
|
219
|
+
require_diff.pushError(report, { message: `artifact write failed: ${e.message}` });
|
|
220
|
+
} finally {
|
|
221
|
+
disposeShape(shape);
|
|
225
222
|
}
|
|
223
|
+
const json = require_diff.serializeReport(report);
|
|
224
|
+
if (opts.json) (0, node_fs.writeFileSync)(opts.json, json);
|
|
226
225
|
process.stdout.write(json + "\n");
|
|
227
|
-
|
|
228
|
-
if (
|
|
229
|
-
if (opts.serve && stepPath) {
|
|
226
|
+
if (!require_diff.reportOk(report)) process.exitCode = 1;
|
|
227
|
+
if (Boolean(opts.serve) && stepPath !== void 0 && require_diff.reportOk(report) && stepPath) {
|
|
230
228
|
const { serve } = await Promise.resolve().then(() => require("../snapshot/serve.cjs"));
|
|
231
229
|
const { url } = await serve({ file: stepPath });
|
|
232
230
|
process.stderr.write(`viewer: ${url}\n`);
|
|
@@ -312,6 +310,15 @@ program.command("export").argument("<file>", "path to a .brep.ts module").option
|
|
|
312
310
|
}, null, 2) + "\n");
|
|
313
311
|
if (!result.ok) process.exitCode = 1;
|
|
314
312
|
});
|
|
315
|
-
|
|
313
|
+
function isEntrypoint(argv1, moduleUrl) {
|
|
314
|
+
if (!argv1) return false;
|
|
315
|
+
try {
|
|
316
|
+
return (0, node_fs.realpathSync)(argv1) === (0, node_fs.realpathSync)((0, node_url.fileURLToPath)(moduleUrl));
|
|
317
|
+
} catch {
|
|
318
|
+
return false;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
if (isEntrypoint(process.argv[1], {}.url)) program.parseAsync();
|
|
316
322
|
//#endregion
|
|
323
|
+
exports.isEntrypoint = isEntrypoint;
|
|
317
324
|
exports.loadSnapshotShoot = loadSnapshotShoot;
|
package/dist/cli/main.d.ts
CHANGED
package/dist/cli/main.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { n as runMeasure, o as
|
|
2
|
+
import { c as serializeReport, n as runMeasure, o as pushError, r as runPart, s as reportOk, t as runDiff } from "../diff-DhKrjOVB.js";
|
|
3
3
|
import { exportSTL, isOk } from "brepjs";
|
|
4
4
|
import { Command } from "commander";
|
|
5
|
-
import { existsSync, mkdirSync, watch, writeFileSync } from "node:fs";
|
|
5
|
+
import { existsSync, mkdirSync, realpathSync, watch, writeFileSync } from "node:fs";
|
|
6
6
|
import { basename, dirname, join, resolve } from "node:path";
|
|
7
7
|
import { tmpdir } from "node:os";
|
|
8
|
-
import {
|
|
8
|
+
import { fileURLToPath } from "node:url";
|
|
9
9
|
//#region src/cli/scaffold.ts
|
|
10
10
|
function partTemplate(name) {
|
|
11
11
|
return `import { box, cut, unwrap } from 'brepjs';
|
|
@@ -96,11 +96,6 @@ function scaffoldPart(name, dir) {
|
|
|
96
96
|
files
|
|
97
97
|
};
|
|
98
98
|
}
|
|
99
|
-
/**
|
|
100
|
-
* Wraps a handler so bursts of rapid calls collapse into a single trailing
|
|
101
|
-
* invocation after `delayMs` of quiet — fs.watch fires twice per save on many
|
|
102
|
-
* platforms, so the model is re-run once rather than per raw event.
|
|
103
|
-
*/
|
|
104
99
|
function debounce(fn, delayMs = 150) {
|
|
105
100
|
let timer;
|
|
106
101
|
const cancel = () => {
|
|
@@ -123,11 +118,6 @@ function debounce(fn, delayMs = 150) {
|
|
|
123
118
|
}
|
|
124
119
|
//#endregion
|
|
125
120
|
//#region src/disposeShape.ts
|
|
126
|
-
/**
|
|
127
|
-
* Release a live WASM-backed kernel shape handle returned by `runPart`.
|
|
128
|
-
* No-op for null/undefined or shapes without a disposer, so callers can pass
|
|
129
|
-
* `result.shape` unconditionally. WASM memory accumulates without this.
|
|
130
|
-
*/
|
|
131
121
|
function disposeShape(shape) {
|
|
132
122
|
const disposer = shape?.[Symbol.dispose];
|
|
133
123
|
if (typeof disposer === "function") disposer.call(shape);
|
|
@@ -138,7 +128,6 @@ function stem(file) {
|
|
|
138
128
|
return basename(file).replace(/\.brep\.ts$/, "").replace(/\.ts$/, "");
|
|
139
129
|
}
|
|
140
130
|
async function exportPart(modulePath, formats, outDir) {
|
|
141
|
-
const wantStl = Boolean(formats.stl);
|
|
142
131
|
const { shape, report, step, glb } = await runPart(modulePath, {
|
|
143
132
|
step: Boolean(formats.step),
|
|
144
133
|
glb: Boolean(formats.glb)
|
|
@@ -147,34 +136,38 @@ async function exportPart(modulePath, formats, outDir) {
|
|
|
147
136
|
const written = [];
|
|
148
137
|
if (!(reportOk(report) && shape !== null)) {
|
|
149
138
|
disposeShape(shape);
|
|
139
|
+
const failures = report.errorInfos.map((e) => e.message);
|
|
150
140
|
return {
|
|
151
141
|
ok: false,
|
|
152
142
|
report,
|
|
153
143
|
written,
|
|
154
|
-
errors: report.errors
|
|
144
|
+
errors: failures.length > 0 ? failures : report.errors
|
|
155
145
|
};
|
|
156
146
|
}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
} else errors.push("GLB export produced no data");
|
|
169
|
-
if (wantStl) {
|
|
170
|
-
const r = exportSTL(shape);
|
|
171
|
-
if (isOk(r)) {
|
|
172
|
-
const p = join(outDir, `${base}.stl`);
|
|
173
|
-
writeFileSync(p, Buffer.from(await r.value.arrayBuffer()));
|
|
147
|
+
try {
|
|
148
|
+
if (!existsSync(outDir)) mkdirSync(outDir, { recursive: true });
|
|
149
|
+
const base = stem(modulePath);
|
|
150
|
+
if (formats.step) if (step) {
|
|
151
|
+
const p = join(outDir, `${base}.step`);
|
|
152
|
+
writeFileSync(p, Buffer.from(step));
|
|
153
|
+
written.push(p);
|
|
154
|
+
} else errors.push("STEP export produced no data");
|
|
155
|
+
if (formats.glb) if (glb) {
|
|
156
|
+
const p = join(outDir, `${base}.glb`);
|
|
157
|
+
writeFileSync(p, Buffer.from(glb));
|
|
174
158
|
written.push(p);
|
|
175
|
-
} else errors.push(
|
|
159
|
+
} else errors.push("GLB export produced no data");
|
|
160
|
+
if (formats.stl) {
|
|
161
|
+
const r = exportSTL(shape);
|
|
162
|
+
if (isOk(r)) {
|
|
163
|
+
const p = join(outDir, `${base}.stl`);
|
|
164
|
+
writeFileSync(p, Buffer.from(await r.value.arrayBuffer()));
|
|
165
|
+
written.push(p);
|
|
166
|
+
} else errors.push(`STL export: ${r.error.message}`);
|
|
167
|
+
}
|
|
168
|
+
} finally {
|
|
169
|
+
disposeShape(shape);
|
|
176
170
|
}
|
|
177
|
-
disposeShape(shape);
|
|
178
171
|
return {
|
|
179
172
|
ok: errors.length === 0,
|
|
180
173
|
report,
|
|
@@ -200,32 +193,37 @@ var program = new Command();
|
|
|
200
193
|
program.name("brepjs");
|
|
201
194
|
program.command("verify", { isDefault: true }).argument("<file>", "path to a .brep.ts module with a default-exported part function").option("--step <out>", "write the primary STEP artifact to this path").option("--glb <out>", "write a derived GLB preview to this path").option("--json <out>", "write the JSON report to this path").option("--snapshot <dir>", "render iso/front/top/right PNGs to this dir (requires built viewer)").option("--serve", "after verifying, start a preview server and print a ?dir=&file= deep link (stays running)").action(async (file, opts) => {
|
|
202
195
|
const wantStep = Boolean(opts.step) || Boolean(opts.snapshot) || Boolean(opts.serve);
|
|
203
|
-
const { report, step, glb } = await runPart(resolve(file), {
|
|
196
|
+
const { report, step, glb, shape } = await runPart(resolve(file), {
|
|
204
197
|
step: wantStep,
|
|
205
198
|
glb: Boolean(opts.glb)
|
|
206
199
|
});
|
|
207
|
-
const json = serializeReport(report);
|
|
208
|
-
if (opts.json) writeFileSync(opts.json, json);
|
|
209
|
-
if (opts.glb && glb) writeFileSync(opts.glb, Buffer.from(glb));
|
|
210
200
|
let stepPath = opts.step;
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
const shoot = await loadSnapshotShoot();
|
|
217
|
-
if (shoot) {
|
|
218
|
-
const { pngs } = await shoot({
|
|
219
|
-
file: stepPath,
|
|
220
|
-
outDir: opts.snapshot
|
|
221
|
-
});
|
|
222
|
-
for (const p of pngs) process.stderr.write(`snapshot: ${p}\n`);
|
|
201
|
+
try {
|
|
202
|
+
if (opts.glb && glb) writeFileSync(opts.glb, Buffer.from(glb));
|
|
203
|
+
if (wantStep && step) {
|
|
204
|
+
stepPath = opts.step ?? join(tmpdir(), `brepjs-cad-${basename(file)}.step`);
|
|
205
|
+
writeFileSync(stepPath, Buffer.from(step));
|
|
223
206
|
}
|
|
207
|
+
if (opts.snapshot && stepPath) {
|
|
208
|
+
const shoot = await loadSnapshotShoot();
|
|
209
|
+
if (shoot) {
|
|
210
|
+
const { pngs } = await shoot({
|
|
211
|
+
file: stepPath,
|
|
212
|
+
outDir: opts.snapshot
|
|
213
|
+
});
|
|
214
|
+
for (const p of pngs) process.stderr.write(`snapshot: ${p}\n`);
|
|
215
|
+
}
|
|
216
|
+
} else if (opts.snapshot) process.stderr.write("snapshot skipped: STEP export produced no artifact\n");
|
|
217
|
+
} catch (e) {
|
|
218
|
+
pushError(report, { message: `artifact write failed: ${e.message}` });
|
|
219
|
+
} finally {
|
|
220
|
+
disposeShape(shape);
|
|
224
221
|
}
|
|
222
|
+
const json = serializeReport(report);
|
|
223
|
+
if (opts.json) writeFileSync(opts.json, json);
|
|
225
224
|
process.stdout.write(json + "\n");
|
|
226
|
-
|
|
227
|
-
if (
|
|
228
|
-
if (opts.serve && stepPath) {
|
|
225
|
+
if (!reportOk(report)) process.exitCode = 1;
|
|
226
|
+
if (Boolean(opts.serve) && stepPath !== void 0 && reportOk(report) && stepPath) {
|
|
229
227
|
const { serve } = await import("../snapshot/serve.js");
|
|
230
228
|
const { url } = await serve({ file: stepPath });
|
|
231
229
|
process.stderr.write(`viewer: ${url}\n`);
|
|
@@ -311,6 +309,14 @@ program.command("export").argument("<file>", "path to a .brep.ts module").option
|
|
|
311
309
|
}, null, 2) + "\n");
|
|
312
310
|
if (!result.ok) process.exitCode = 1;
|
|
313
311
|
});
|
|
314
|
-
|
|
312
|
+
function isEntrypoint(argv1, moduleUrl) {
|
|
313
|
+
if (!argv1) return false;
|
|
314
|
+
try {
|
|
315
|
+
return realpathSync(argv1) === realpathSync(fileURLToPath(moduleUrl));
|
|
316
|
+
} catch {
|
|
317
|
+
return false;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
if (isEntrypoint(process.argv[1], import.meta.url)) program.parseAsync();
|
|
315
321
|
//#endregion
|
|
316
|
-
export { loadSnapshotShoot };
|
|
322
|
+
export { isEntrypoint, loadSnapshotShoot };
|
package/dist/cli/watch.d.ts
CHANGED
|
@@ -1,9 +1,4 @@
|
|
|
1
1
|
export declare const DEFAULT_DEBOUNCE_MS = 150;
|
|
2
|
-
/**
|
|
3
|
-
* Wraps a handler so bursts of rapid calls collapse into a single trailing
|
|
4
|
-
* invocation after `delayMs` of quiet — fs.watch fires twice per save on many
|
|
5
|
-
* platforms, so the model is re-run once rather than per raw event.
|
|
6
|
-
*/
|
|
7
2
|
export declare function debounce(fn: () => void | Promise<void>, delayMs?: number): {
|
|
8
3
|
trigger: () => void;
|
|
9
4
|
cancel: () => void;
|
|
@@ -10,7 +10,6 @@ function emptyReport() {
|
|
|
10
10
|
hints: []
|
|
11
11
|
};
|
|
12
12
|
}
|
|
13
|
-
/** Record a failure on the report, keeping the flat `errors` string list and structured `errorInfos` in sync. */
|
|
14
13
|
function pushError(r, info) {
|
|
15
14
|
r.errors.push(info.message);
|
|
16
15
|
r.errorInfos.push(info);
|
|
@@ -246,7 +245,6 @@ function isBrepError(v) {
|
|
|
246
245
|
const rec = v;
|
|
247
246
|
return typeof rec["code"] === "string" && typeof rec["message"] === "string";
|
|
248
247
|
}
|
|
249
|
-
/** Pull structured `{ message, code, suggestion }` out of a `BrepError`, a thrown `Error`, or anything. */
|
|
250
248
|
function toErrorInfo(prefix, e) {
|
|
251
249
|
if (isBrepError(e)) return {
|
|
252
250
|
message: `${prefix}: ${e.message}`,
|
|
@@ -261,8 +259,16 @@ function finalize(result) {
|
|
|
261
259
|
return result;
|
|
262
260
|
}
|
|
263
261
|
async function runPart(modulePath, opts = {}) {
|
|
264
|
-
await init();
|
|
265
262
|
const report = emptyReport();
|
|
263
|
+
try {
|
|
264
|
+
await init();
|
|
265
|
+
} catch (e) {
|
|
266
|
+
pushError(report, toErrorInfo("kernel init failed", e));
|
|
267
|
+
return finalize({
|
|
268
|
+
shape: null,
|
|
269
|
+
report
|
|
270
|
+
});
|
|
271
|
+
}
|
|
266
272
|
let mod;
|
|
267
273
|
try {
|
|
268
274
|
mod = await import(modulePath);
|
|
@@ -291,15 +297,16 @@ async function runPart(modulePath, opts = {}) {
|
|
|
291
297
|
});
|
|
292
298
|
}
|
|
293
299
|
let shape;
|
|
294
|
-
if (isResult(out))
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
300
|
+
if (isResult(out)) {
|
|
301
|
+
if (!isOk(out)) {
|
|
302
|
+
pushError(report, toErrorInfo("part returned Err", out.error));
|
|
303
|
+
return finalize({
|
|
304
|
+
shape: null,
|
|
305
|
+
report
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
shape = out.value;
|
|
309
|
+
} else shape = out;
|
|
303
310
|
if (!shape) {
|
|
304
311
|
pushError(report, { message: "part produced no shape" });
|
|
305
312
|
return finalize({
|
|
@@ -449,6 +456,30 @@ function areaOf(shape, errors) {
|
|
|
449
456
|
errors.push(`measureArea: ${a.error.message}`);
|
|
450
457
|
return 0;
|
|
451
458
|
}
|
|
459
|
+
function boundsDelta(a, b, errors) {
|
|
460
|
+
try {
|
|
461
|
+
const ba = getBounds(a);
|
|
462
|
+
const bb = getBounds(b);
|
|
463
|
+
return {
|
|
464
|
+
xMin: bb.xMin - ba.xMin,
|
|
465
|
+
xMax: bb.xMax - ba.xMax,
|
|
466
|
+
yMin: bb.yMin - ba.yMin,
|
|
467
|
+
yMax: bb.yMax - ba.yMax,
|
|
468
|
+
zMin: bb.zMin - ba.zMin,
|
|
469
|
+
zMax: bb.zMax - ba.zMax
|
|
470
|
+
};
|
|
471
|
+
} catch (e) {
|
|
472
|
+
errors.push(`getBounds: ${e.message}`);
|
|
473
|
+
return {
|
|
474
|
+
xMin: 0,
|
|
475
|
+
xMax: 0,
|
|
476
|
+
yMin: 0,
|
|
477
|
+
yMax: 0,
|
|
478
|
+
zMin: 0,
|
|
479
|
+
zMax: 0
|
|
480
|
+
};
|
|
481
|
+
}
|
|
482
|
+
}
|
|
452
483
|
function cutVolume(x, y, errors) {
|
|
453
484
|
try {
|
|
454
485
|
var _usingCtx$1 = _usingCtx();
|
|
@@ -470,21 +501,13 @@ async function runDiff(aPath, bPath) {
|
|
|
470
501
|
const errors = [];
|
|
471
502
|
const a = await runPart(aPath);
|
|
472
503
|
errors.push(...a.report.errors);
|
|
504
|
+
if (!a.shape) return emptyDiff(errors);
|
|
505
|
+
const sa = _usingCtx3.u(a.shape);
|
|
473
506
|
const b = await runPart(bPath);
|
|
474
507
|
errors.push(...b.report.errors);
|
|
475
|
-
if (!
|
|
476
|
-
const sa = _usingCtx3.u(a.shape);
|
|
508
|
+
if (!b.shape) return emptyDiff(errors);
|
|
477
509
|
const sb = _usingCtx3.u(b.shape);
|
|
478
|
-
const
|
|
479
|
-
const bb = getBounds(sb);
|
|
480
|
-
const bboxDelta = {
|
|
481
|
-
xMin: bb.xMin - ba.xMin,
|
|
482
|
-
xMax: bb.xMax - ba.xMax,
|
|
483
|
-
yMin: bb.yMin - ba.yMin,
|
|
484
|
-
yMax: bb.yMax - ba.yMax,
|
|
485
|
-
zMin: bb.zMin - ba.zMin,
|
|
486
|
-
zMax: bb.zMax - ba.zMax
|
|
487
|
-
};
|
|
510
|
+
const bboxDelta = boundsDelta(sa, sb, errors);
|
|
488
511
|
const areaDelta = areaOf(sb, errors) - areaOf(sa, errors);
|
|
489
512
|
let volumeDelta = 0;
|
|
490
513
|
let symmetricDifferenceVolume = 0;
|
|
@@ -506,4 +529,4 @@ async function runDiff(aPath, bPath) {
|
|
|
506
529
|
}
|
|
507
530
|
}
|
|
508
531
|
//#endregion
|
|
509
|
-
export { emptyReport as a, runChecks as i, runMeasure as n,
|
|
532
|
+
export { emptyReport as a, serializeReport as c, runChecks as i, runMeasure as n, pushError as o, runPart as r, reportOk as s, runDiff as t };
|
|
Binary file
|
package/dist/disposeShape.d.ts
CHANGED
|
@@ -1,6 +1 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Release a live WASM-backed kernel shape handle returned by `runPart`.
|
|
3
|
-
* No-op for null/undefined or shapes without a disposer, so callers can pass
|
|
4
|
-
* `result.shape` unconditionally. WASM memory accumulates without this.
|
|
5
|
-
*/
|
|
6
1
|
export declare function disposeShape(shape: unknown): void;
|
|
@@ -31,7 +31,7 @@ async function acquireServer(opts = {}) {
|
|
|
31
31
|
server = await require_snapshot_static.startStaticServer({ port });
|
|
32
32
|
break;
|
|
33
33
|
} catch {}
|
|
34
|
-
if (!server) throw new Error(`no free port in ${ports[0]}..${ports
|
|
34
|
+
if (!server) throw new Error(`no free port in ${ports[0]}..${ports.at(-1)}`);
|
|
35
35
|
const timer = setTimeout(() => void server?.close(), opts.shutdownAfterMs ?? 432e5);
|
|
36
36
|
timer.unref();
|
|
37
37
|
const started = server;
|
|
@@ -30,7 +30,7 @@ async function acquireServer(opts = {}) {
|
|
|
30
30
|
server = await startStaticServer({ port });
|
|
31
31
|
break;
|
|
32
32
|
} catch {}
|
|
33
|
-
if (!server) throw new Error(`no free port in ${ports[0]}..${ports
|
|
33
|
+
if (!server) throw new Error(`no free port in ${ports[0]}..${ports.at(-1)}`);
|
|
34
34
|
const timer = setTimeout(() => void server?.close(), opts.shutdownAfterMs ?? 432e5);
|
|
35
35
|
timer.unref();
|
|
36
36
|
const started = server;
|
package/dist/snapshot/static.cjs
CHANGED
|
@@ -38,7 +38,8 @@ async function sendFile(res, absPath) {
|
|
|
38
38
|
}
|
|
39
39
|
function safeJoin(root, rel) {
|
|
40
40
|
const abs = (0, node_path.resolve)(root, (0, node_path.normalize)(decodeURIComponent(rel.replace(/^\/+/, ""))));
|
|
41
|
-
|
|
41
|
+
if (abs !== root && !abs.startsWith(root + node_path.sep)) return null;
|
|
42
|
+
return abs;
|
|
42
43
|
}
|
|
43
44
|
async function handle(req, res, port) {
|
|
44
45
|
const url = new URL(req.url ?? "/", `http://127.0.0.1:${port}`);
|
package/dist/snapshot/static.js
CHANGED
|
@@ -37,7 +37,8 @@ async function sendFile(res, absPath) {
|
|
|
37
37
|
}
|
|
38
38
|
function safeJoin(root, rel) {
|
|
39
39
|
const abs = resolve(root, normalize(decodeURIComponent(rel.replace(/^\/+/, ""))));
|
|
40
|
-
|
|
40
|
+
if (abs !== root && !abs.startsWith(root + sep)) return null;
|
|
41
|
+
return abs;
|
|
41
42
|
}
|
|
42
43
|
async function handle(req, res, port) {
|
|
43
44
|
const url = new URL(req.url ?? "/", `http://127.0.0.1:${port}`);
|
package/dist/verify/report.d.ts
CHANGED
|
@@ -53,7 +53,6 @@ export interface DiffReport {
|
|
|
53
53
|
errors: string[];
|
|
54
54
|
}
|
|
55
55
|
export declare function emptyReport(): VerifyReport;
|
|
56
|
-
/** Record a failure on the report, keeping the flat `errors` string list and structured `errorInfos` in sync. */
|
|
57
56
|
export declare function pushError(r: VerifyReport, info: ErrorInfo): void;
|
|
58
57
|
export declare function reportOk(r: VerifyReport): boolean;
|
|
59
58
|
/** Synthetic code attached to validity-check failures (validSolid returns a plain string error). */
|