@danielsimonjr/mathts-workbook 0.4.9 → 0.4.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,567 @@
1
+ import { c as parseWorkbook, d as buildDependencyGraph, f as detectCycles, i as SUPPORTED_CELL_TYPES, l as serializeWorkbook, m as getDependents, n as WorkbookExecutor, p as getAncestors, s as isValidIdentifier } from "./formatter-8ja3r-YP.js";
2
+ import * as mathFunctions from "@danielsimonjr/mathts-functions";
3
+ import { readFileSync, renameSync, unlinkSync, writeFileSync } from "node:fs";
4
+ import { Worker } from "node:worker_threads";
5
+ //#region src/edit.ts
6
+ function cloneWorkbook(wb) {
7
+ return {
8
+ ...wb,
9
+ metadata: { ...wb.metadata },
10
+ runtime: { ...wb.runtime },
11
+ cells: wb.cells.map((c) => ({
12
+ ...c,
13
+ ...c.dependsOn ? { dependsOn: [...c.dependsOn] } : {},
14
+ ...c.metadata ? { metadata: { ...c.metadata } } : {}
15
+ }))
16
+ };
17
+ }
18
+ function assertSupportedType(type) {
19
+ if (!SUPPORTED_CELL_TYPES.includes(type)) throw new Error(`Unsupported cell type '${type}' (supported: ${SUPPORTED_CELL_TYPES.join(", ")})`);
20
+ }
21
+ function indexOfCell(wb, id) {
22
+ const i = wb.cells.findIndex((c) => c.id === id);
23
+ if (i < 0) throw new Error(`No such cell: '${id}'`);
24
+ return i;
25
+ }
26
+ function validateDeps(wb, dependsOn, selfId) {
27
+ const ids = new Set(wb.cells.map((c) => c.id));
28
+ for (const dep of dependsOn) {
29
+ if (dep === selfId) throw new Error(`Cell '${selfId}' cannot depend on itself`);
30
+ if (!ids.has(dep)) throw new Error(`depends_on references unknown cell '${dep}'`);
31
+ }
32
+ return dependsOn;
33
+ }
34
+ function assertNoNewCycle(before, after) {
35
+ if (detectCycles(buildDependencyGraph(before.cells)).length > 0) return;
36
+ const cycles = detectCycles(buildDependencyGraph(after.cells));
37
+ if (cycles.length > 0) throw new Error(`Operation would create a dependency cycle: ${cycles.map((c) => c.join(" -> ")).join("; ")}`);
38
+ }
39
+ function clearResult(cell) {
40
+ delete cell.output;
41
+ delete cell.error;
42
+ }
43
+ function resolveInsertIndex(wb, position) {
44
+ if (!position) return wb.cells.length;
45
+ if (position.at !== void 0) {
46
+ if (!Number.isInteger(position.at) || position.at < 0 || position.at > wb.cells.length) throw new Error(`--at ${position.at} out of range (0..${wb.cells.length})`);
47
+ return position.at;
48
+ }
49
+ if (position.before !== void 0) {
50
+ const i = wb.cells.findIndex((c) => c.id === position.before);
51
+ if (i < 0) throw new Error(`--before: no such cell '${position.before}'`);
52
+ return i;
53
+ }
54
+ if (position.after !== void 0) {
55
+ const i = wb.cells.findIndex((c) => c.id === position.after);
56
+ if (i < 0) throw new Error(`--after: no such cell '${position.after}'`);
57
+ return i + 1;
58
+ }
59
+ return wb.cells.length;
60
+ }
61
+ function addCell(wb, spec, position) {
62
+ if (!isValidIdentifier(spec.id)) throw new Error(`Invalid cell id '${spec.id}': must be an identifier ([A-Za-z_][A-Za-z0-9_]*)`);
63
+ if (wb.cells.some((c) => c.id === spec.id)) throw new Error(`Duplicate cell id '${spec.id}'`);
64
+ assertSupportedType(spec.type);
65
+ const next = cloneWorkbook(wb);
66
+ const cell = {
67
+ id: spec.id,
68
+ type: spec.type,
69
+ content: spec.content ?? ""
70
+ };
71
+ const deps = spec.dependsOn ? validateDeps(next, spec.dependsOn, spec.id) : void 0;
72
+ if (deps && deps.length > 0) cell.dependsOn = deps;
73
+ next.cells.splice(resolveInsertIndex(next, position), 0, cell);
74
+ assertNoNewCycle(wb, next);
75
+ return next;
76
+ }
77
+ function editCell(wb, id, changes) {
78
+ const next = cloneWorkbook(wb);
79
+ const cell = next.cells[indexOfCell(next, id)];
80
+ let touched = false;
81
+ if (changes.type !== void 0) {
82
+ assertSupportedType(changes.type);
83
+ cell.type = changes.type;
84
+ touched = true;
85
+ }
86
+ if (changes.content !== void 0) {
87
+ cell.content = changes.content;
88
+ touched = true;
89
+ }
90
+ if (changes.dependsOn !== void 0) {
91
+ const deps = validateDeps(next, changes.dependsOn, id);
92
+ if (deps.length > 0) cell.dependsOn = deps;
93
+ else delete cell.dependsOn;
94
+ touched = true;
95
+ }
96
+ if (touched) clearResult(cell);
97
+ if (changes.dependsOn !== void 0) assertNoNewCycle(wb, next);
98
+ return next;
99
+ }
100
+ function removeCell(wb, id, options) {
101
+ const next = cloneWorkbook(wb);
102
+ indexOfCell(next, id);
103
+ const dependents = next.cells.filter((c) => (c.dependsOn ?? []).includes(id)).map((c) => c.id);
104
+ if (dependents.length > 0 && !options?.force) throw new Error(`Cell '${id}' has dependents: ${dependents.join(", ")} (use --force to remove and detach)`);
105
+ const changedCells = [];
106
+ for (const c of next.cells) if (c.dependsOn?.includes(id)) {
107
+ c.dependsOn = c.dependsOn.filter((d) => d !== id);
108
+ if (c.dependsOn.length === 0) delete c.dependsOn;
109
+ clearResult(c);
110
+ changedCells.push(c.id);
111
+ }
112
+ next.cells = next.cells.filter((c) => c.id !== id);
113
+ return {
114
+ workbook: next,
115
+ changedCells
116
+ };
117
+ }
118
+ function moveCell(wb, id, position) {
119
+ if (position.before === id || position.after === id) return cloneWorkbook(wb);
120
+ const next = cloneWorkbook(wb);
121
+ const from = indexOfCell(next, id);
122
+ const [cell] = next.cells.splice(from, 1);
123
+ next.cells.splice(resolveInsertIndex(next, position), 0, cell);
124
+ return next;
125
+ }
126
+ function renameCell(wb, oldId, newId) {
127
+ if (oldId === newId) return cloneWorkbook(wb);
128
+ const next = cloneWorkbook(wb);
129
+ const cell = next.cells[indexOfCell(next, oldId)];
130
+ if (!isValidIdentifier(newId)) throw new Error(`Invalid cell id '${newId}': must be an identifier ([A-Za-z_][A-Za-z0-9_]*)`);
131
+ if (next.cells.some((c) => c.id === newId)) throw new Error(`Duplicate cell id '${newId}'`);
132
+ cell.id = newId;
133
+ const reference = new RegExp(`\\b${oldId}\\b`, "g");
134
+ for (const c of next.cells) if (c.dependsOn?.includes(oldId)) {
135
+ c.dependsOn = c.dependsOn.map((d) => d === oldId ? newId : d);
136
+ c.content = c.content.replace(reference, newId);
137
+ }
138
+ return next;
139
+ }
140
+ function setMetadata(wb, changes) {
141
+ const next = cloneWorkbook(wb);
142
+ if (changes.title !== void 0) next.metadata.title = changes.title;
143
+ if (changes.author !== void 0) next.metadata.author = changes.author;
144
+ if (changes.description !== void 0) next.metadata.description = changes.description;
145
+ if (changes.tags !== void 0) next.metadata.tags = changes.tags;
146
+ return next;
147
+ }
148
+ //#endregion
149
+ //#region src/contract.ts
150
+ const SCHEMA_VERSION = {
151
+ major: 1,
152
+ minor: 0
153
+ };
154
+ const VERSION = "0.4.11";
155
+ const COMMAND_NAMES = [
156
+ "run",
157
+ "describe",
158
+ "validate",
159
+ "graph",
160
+ "strip",
161
+ "new",
162
+ "capabilities",
163
+ "templates",
164
+ "cell",
165
+ "serve",
166
+ "functions",
167
+ "meta",
168
+ "import",
169
+ "export"
170
+ ];
171
+ //#endregion
172
+ //#region src/fs-atomic.ts
173
+ let counter = 0;
174
+ const RENAME_ATTEMPTS = 12;
175
+ const LOCK_CODES = /* @__PURE__ */ new Set([
176
+ "EPERM",
177
+ "EBUSY",
178
+ "EACCES"
179
+ ]);
180
+ function sleepSync(ms) {
181
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
182
+ }
183
+ function writeFileAtomic(file, content, options = {}) {
184
+ const rename = options.rename ?? renameSync;
185
+ const sleep = options.sleepMs ?? sleepSync;
186
+ const tmp = `${file}.${process.pid}.${counter++}.tmp`;
187
+ writeFileSync(tmp, content, {
188
+ encoding: "utf-8",
189
+ flag: "wx"
190
+ });
191
+ try {
192
+ for (let attempt = 1;; attempt++) try {
193
+ rename(tmp, file);
194
+ return;
195
+ } catch (error) {
196
+ const code = error.code;
197
+ if (attempt >= RENAME_ATTEMPTS || code === void 0 || !LOCK_CODES.has(code)) throw error;
198
+ sleep(Math.min(10 * attempt, 50));
199
+ }
200
+ } catch (error) {
201
+ try {
202
+ unlinkSync(tmp);
203
+ } catch {}
204
+ throw error;
205
+ }
206
+ }
207
+ //#endregion
208
+ //#region src/session.ts
209
+ function canonicalCell(cell) {
210
+ const meta = cell.metadata ?? {};
211
+ const sortedMeta = {};
212
+ for (const key of Object.keys(meta).sort()) sortedMeta[key] = meta[key];
213
+ return JSON.stringify([
214
+ cell.type,
215
+ cell.content,
216
+ cell.dependsOn ?? [],
217
+ sortedMeta
218
+ ]);
219
+ }
220
+ var Session = class {
221
+ workbook = null;
222
+ path = null;
223
+ dirty = false;
224
+ cache = /* @__PURE__ */ new Map();
225
+ stale = /* @__PURE__ */ new Set();
226
+ require() {
227
+ if (!this.workbook) throw new Error("No workbook open");
228
+ return this.workbook;
229
+ }
230
+ hasValidResult(id) {
231
+ const r = this.cache.get(id);
232
+ return r !== void 0 && (r.status === "success" || r.status === "pass");
233
+ }
234
+ open(path, options) {
235
+ if (this.dirty && !options?.force) throw new Error("Workbook has unsaved changes (open with force to discard)");
236
+ const content = readFileSync(path, "utf-8");
237
+ const parsed = parseWorkbook(content);
238
+ if (!parsed.success) throw new Error(`Parse errors: ${(parsed.errors ?? []).join("; ")}`);
239
+ this.workbook = parsed.workbook;
240
+ this.path = path;
241
+ this.cache.clear();
242
+ this.stale = new Set(this.workbook.cells.map((c) => c.id));
243
+ this.dirty = false;
244
+ }
245
+ commit(next) {
246
+ const old = this.require();
247
+ const oldCanonical = new Map(old.cells.map((c) => [c.id, canonicalCell(c)]));
248
+ const changed = /* @__PURE__ */ new Set();
249
+ for (const cell of next.cells) {
250
+ const prev = oldCanonical.get(cell.id);
251
+ if (prev === void 0 || prev !== canonicalCell(cell)) changed.add(cell.id);
252
+ }
253
+ const graph = buildDependencyGraph(next.cells);
254
+ const affected = new Set(changed);
255
+ for (const id of changed) for (const dep of getDependents(graph, id)) affected.add(dep);
256
+ const survivingIds = new Set(next.cells.map((c) => c.id));
257
+ for (const id of [...this.cache.keys()]) if (!survivingIds.has(id) || affected.has(id)) this.cache.delete(id);
258
+ this.stale = new Set(next.cells.map((c) => c.id).filter((id) => !this.hasValidResult(id)));
259
+ this.workbook = next;
260
+ this.dirty = true;
261
+ }
262
+ addCell(spec, position) {
263
+ this.commit(addCell(this.require(), spec, position));
264
+ }
265
+ editCell(id, changes) {
266
+ this.commit(editCell(this.require(), id, changes));
267
+ }
268
+ removeCell(id, options) {
269
+ const result = removeCell(this.require(), id, options);
270
+ this.commit(result.workbook);
271
+ return result.changedCells;
272
+ }
273
+ moveCell(id, position) {
274
+ this.commit(moveCell(this.require(), id, position));
275
+ }
276
+ renameCell(oldId, newId) {
277
+ this.commit(renameCell(this.require(), oldId, newId));
278
+ }
279
+ setMetadata(changes) {
280
+ this.commit(setMetadata(this.require(), changes));
281
+ }
282
+ async run(only) {
283
+ const wb = this.require();
284
+ const graph = buildDependencyGraph(wb.cells);
285
+ const target = only ? new Set(getAncestors(graph, only)) : new Set(wb.cells.map((c) => c.id));
286
+ const toRun = new Set([...this.stale].filter((id) => target.has(id)));
287
+ const executor = new WorkbookExecutor(wb);
288
+ const seed = /* @__PURE__ */ new Map();
289
+ for (const [id, res] of this.cache) if (res.status === "success" || res.status === "pass") seed.set(id, res.output);
290
+ executor.seedOutputs(seed);
291
+ const events = [];
292
+ executor.on((e) => events.push({
293
+ type: e.type,
294
+ cellId: e.cellId,
295
+ error: e.error
296
+ }));
297
+ const report = await executor.runReport({
298
+ only,
299
+ runIds: toRun
300
+ });
301
+ if (!report.ok && report.cells.some((c) => c.id === "(workbook)")) return {
302
+ result: report,
303
+ events
304
+ };
305
+ for (const cr of report.cells) {
306
+ this.cache.set(cr.id, cr);
307
+ if (cr.status === "success" || cr.status === "pass") this.stale.delete(cr.id);
308
+ }
309
+ const cells = graph.executionOrder.filter((id) => target.has(id)).map((id) => this.cache.get(id)).filter((c) => c !== void 0);
310
+ return {
311
+ result: {
312
+ cells,
313
+ ok: cells.every((c) => c.status === "success" || c.status === "pass")
314
+ },
315
+ events
316
+ };
317
+ }
318
+ staleIds() {
319
+ return [...this.stale];
320
+ }
321
+ save(path) {
322
+ const wb = this.require();
323
+ const target = path ?? this.path;
324
+ if (!target) throw new Error("No path to save to");
325
+ writeFileAtomic(target, serializeWorkbook(wb));
326
+ this.path = target;
327
+ this.dirty = false;
328
+ return target;
329
+ }
330
+ };
331
+ //#endregion
332
+ //#region src/introspect.ts
333
+ let functionsCache;
334
+ function listFunctions() {
335
+ if (functionsCache) return functionsCache;
336
+ const functions = [];
337
+ const constants = [];
338
+ for (const [name, value] of Object.entries(mathFunctions)) if (typeof value === "function") functions.push(name);
339
+ else if (value !== null && typeof value !== "object") constants.push(name);
340
+ functionsCache = {
341
+ functions: functions.sort(),
342
+ constants: constants.sort()
343
+ };
344
+ return functionsCache;
345
+ }
346
+ const CELL_SCHEMAS = {
347
+ code: "MathTS expression; the cell output is its evaluated value",
348
+ markdown: "Markdown text (rendered to HTML on export)",
349
+ equation: "MathTS expression syntax, rendered to MathML on export (display-only)",
350
+ test: "Boolean MathTS expression; true = pass, false = fail",
351
+ data: "A YAML/JSON literal value (e.g. a numeric array)",
352
+ visualization: "YAML chart spec: { type: line|scatter|bar, title?, x: {label?, data}, y: {label?, data} }; data = a dependency cell id (numeric array) or an inline array"
353
+ };
354
+ function capabilitiesInfo() {
355
+ return {
356
+ name: "mtsw",
357
+ version: VERSION,
358
+ schemaVersion: SCHEMA_VERSION,
359
+ cellTypes: {
360
+ supported: [...SUPPORTED_CELL_TYPES],
361
+ deferred: ["tensor", "export"]
362
+ },
363
+ cellSchemas: CELL_SCHEMAS,
364
+ commands: [...COMMAND_NAMES],
365
+ features: {
366
+ json: true,
367
+ write: true,
368
+ runCell: true,
369
+ editCell: true,
370
+ serve: true,
371
+ incremental: true,
372
+ functions: true,
373
+ import: true,
374
+ export: true
375
+ }
376
+ };
377
+ }
378
+ //#endregion
379
+ //#region src/doc.ts
380
+ function describeData(wb) {
381
+ const cells = (wb?.cells ?? []).map((c) => ({
382
+ id: c.id,
383
+ type: c.type,
384
+ content: c.content,
385
+ dependsOn: c.dependsOn ?? [],
386
+ metadata: c.metadata ?? {},
387
+ output: c.output ?? null,
388
+ error: c.error ?? null
389
+ }));
390
+ const graph = wb ? buildDependencyGraph(wb.cells) : void 0;
391
+ const edges = graph ? [...graph.nodes].flatMap(([id, node]) => node.dependencies.map((dep) => ({
392
+ from: dep,
393
+ to: id
394
+ }))) : [];
395
+ const cycles = graph ? detectCycles(graph) : [];
396
+ return {
397
+ version: wb?.version ?? "1.0",
398
+ metadata: wb?.metadata ?? {},
399
+ runtime: wb?.runtime ?? {
400
+ engine: "mathts",
401
+ execution: "reactive"
402
+ },
403
+ cells,
404
+ graph: {
405
+ edges,
406
+ cycles
407
+ }
408
+ };
409
+ }
410
+ //#endregion
411
+ //#region src/rpc.ts
412
+ const CODE = {
413
+ PARSE: -32700,
414
+ INVALID_REQUEST: -32600,
415
+ METHOD_NOT_FOUND: -32601,
416
+ INVALID_PARAMS: -32602,
417
+ INTERNAL: -32603
418
+ };
419
+ function str(value) {
420
+ return typeof value === "string" ? value : void 0;
421
+ }
422
+ async function handleRequest(session, request) {
423
+ const id = request && request.id !== void 0 ? request.id : null;
424
+ const ok = (result, events = [], shutdown = false) => ({
425
+ response: {
426
+ jsonrpc: "2.0",
427
+ id,
428
+ result
429
+ },
430
+ events,
431
+ shutdown
432
+ });
433
+ const fail = (code, message) => ({
434
+ response: {
435
+ jsonrpc: "2.0",
436
+ id,
437
+ error: {
438
+ code,
439
+ message
440
+ }
441
+ },
442
+ events: [],
443
+ shutdown: false
444
+ });
445
+ if (!request || typeof request.method !== "string") return fail(CODE.INVALID_REQUEST, "Invalid request: missing method");
446
+ const p = request.params ?? {};
447
+ const doc = () => describeData(session.workbook ?? void 0);
448
+ try {
449
+ switch (request.method) {
450
+ case "open": {
451
+ const path = str(p.path);
452
+ if (path === void 0) return fail(CODE.INVALID_PARAMS, "open requires params.path");
453
+ session.open(path, { force: p.force === true });
454
+ return ok({
455
+ path: session.path,
456
+ ...doc()
457
+ });
458
+ }
459
+ case "describe": return ok(doc());
460
+ case "validate": {
461
+ const d = doc();
462
+ const problems = d.graph.cycles.map((c) => `Dependency cycle: ${c.join(" -> ")}`);
463
+ return ok({
464
+ ok: problems.length === 0,
465
+ problems,
466
+ cellCount: d.cells.length
467
+ });
468
+ }
469
+ case "graph": return ok(doc().graph);
470
+ case "run": {
471
+ const { result, events } = await session.run(str(p.only));
472
+ return ok(result, events.map((e) => ({
473
+ jsonrpc: "2.0",
474
+ method: "cell/event",
475
+ params: {
476
+ type: e.type,
477
+ cellId: e.cellId,
478
+ error: e.error
479
+ }
480
+ })));
481
+ }
482
+ case "cell/add":
483
+ session.addCell({
484
+ id: str(p.id) ?? "",
485
+ type: str(p.type) ?? "",
486
+ content: str(p.content),
487
+ dependsOn: Array.isArray(p.dependsOn) ? p.dependsOn : void 0
488
+ }, p.position);
489
+ return ok(doc());
490
+ case "cell/edit":
491
+ session.editCell(str(p.id) ?? "", {
492
+ content: str(p.content),
493
+ type: str(p.type),
494
+ dependsOn: Array.isArray(p.dependsOn) ? p.dependsOn : void 0
495
+ });
496
+ return ok(doc());
497
+ case "cell/rm": return ok({
498
+ changedCells: session.removeCell(str(p.id) ?? "", { force: p.force === true }),
499
+ ...doc()
500
+ });
501
+ case "cell/move":
502
+ session.moveCell(str(p.id) ?? "", p.position ?? {});
503
+ return ok(doc());
504
+ case "cell/rename":
505
+ session.renameCell(str(p.oldId) ?? "", str(p.newId) ?? "");
506
+ return ok(doc());
507
+ case "meta/get": return ok(session.workbook?.metadata ?? {});
508
+ case "meta/set":
509
+ session.setMetadata({
510
+ title: str(p.title),
511
+ author: str(p.author),
512
+ description: str(p.description),
513
+ tags: Array.isArray(p.tags) ? p.tags : void 0
514
+ });
515
+ return ok(session.workbook?.metadata ?? {});
516
+ case "save": return ok({ path: session.save(str(p.path)) });
517
+ case "capabilities": return ok(capabilitiesInfo());
518
+ case "functions": return ok(listFunctions());
519
+ case "shutdown": return ok({ ok: true }, [], true);
520
+ default: return fail(CODE.METHOD_NOT_FOUND, `Method not found: ${request.method}`);
521
+ }
522
+ } catch (error) {
523
+ return fail(CODE.INTERNAL, error instanceof Error ? error.message : String(error));
524
+ }
525
+ }
526
+ //#endregion
527
+ //#region src/timeout-runner.ts
528
+ var WorkbookTimeoutError = class extends Error {
529
+ timeoutMs;
530
+ constructor(timeoutMs) {
531
+ super(`workbook execution exceeded ${timeoutMs}ms and was terminated`);
532
+ this.name = "WorkbookTimeoutError";
533
+ this.timeoutMs = timeoutMs;
534
+ }
535
+ };
536
+ function runWorkbookWithTimeout(source, options) {
537
+ const { timeoutMs } = options;
538
+ const workerUrl = new URL("./run-worker.js", import.meta.url);
539
+ return new Promise((resolve, reject) => {
540
+ const worker = new Worker(workerUrl, { workerData: { source } });
541
+ let settled = false;
542
+ const finish = (fn) => {
543
+ if (settled) return;
544
+ settled = true;
545
+ clearTimeout(timer);
546
+ worker.terminate().catch(() => {});
547
+ fn();
548
+ };
549
+ const timer = setTimeout(() => {
550
+ finish(() => reject(new WorkbookTimeoutError(timeoutMs)));
551
+ }, timeoutMs);
552
+ worker.once("message", (msg) => {
553
+ finish(() => {
554
+ if (msg.ok) resolve(msg.report);
555
+ else reject(new Error(msg.error));
556
+ });
557
+ });
558
+ worker.once("error", (error) => {
559
+ finish(() => reject(error));
560
+ });
561
+ worker.once("exit", (code) => {
562
+ finish(() => reject(/* @__PURE__ */ new Error(`workbook worker exited with code ${code} before returning a result`)));
563
+ });
564
+ });
565
+ }
566
+ //#endregion
567
+ export { capabilitiesInfo as a, writeFileAtomic as c, addCell as d, editCell as f, setMetadata as g, renameCell as h, describeData as i, SCHEMA_VERSION as l, removeCell as m, runWorkbookWithTimeout as n, listFunctions as o, moveCell as p, handleRequest as r, Session as s, WorkbookTimeoutError as t, VERSION as u };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@danielsimonjr/mathts-workbook",
3
- "version": "0.4.9",
3
+ "version": "0.4.11",
4
4
  "description": "Scientific workbook runtime for MathTS (.mtsw format)",
5
5
  "author": "Daniel Simon Jr.",
6
6
  "license": "MIT",
@@ -22,8 +22,8 @@
22
22
  "README.md"
23
23
  ],
24
24
  "scripts": {
25
- "build": "tsup && tsc -p tsconfig.dts.json",
26
- "dev": "tsup --watch --onSuccess \"tsc -p tsconfig.dts.json\"",
25
+ "build": "tsdown && tsc -p tsconfig.dts.json",
26
+ "dev": "tsdown --watch --on-success \"tsc -p tsconfig.dts.json\"",
27
27
  "test": "bun test --isolate --timeout 30000",
28
28
  "test:watch": "vitest",
29
29
  "test:coverage": "bun test --isolate --timeout 30000 --coverage",
@@ -31,19 +31,19 @@
31
31
  "lint": "oxlint src",
32
32
  "lint:fix": "oxlint src --fix",
33
33
  "clean": "rm -rf dist",
34
- "build:prod": "tsup --minify --treeshake && tsc -p tsconfig.dts.json"
34
+ "build:prod": "tsdown --minify && tsc -p tsconfig.dts.json"
35
35
  },
36
36
  "dependencies": {
37
- "@danielsimonjr/mathts-core": "^0.17.0",
38
- "@danielsimonjr/mathts-expression": "^0.10.1",
39
- "@danielsimonjr/mathts-functions": "^0.68.1",
40
- "@danielsimonjr/mathts-plot": "^0.4.10",
37
+ "@danielsimonjr/mathts-core": "^0.18.0",
38
+ "@danielsimonjr/mathts-expression": "^0.10.2",
39
+ "@danielsimonjr/mathts-functions": "^0.68.2",
40
+ "@danielsimonjr/mathts-plot": "^0.4.11",
41
41
  "yaml": "^2.3.0"
42
42
  },
43
43
  "devDependencies": {
44
44
  "@types/node": "^26.4.0",
45
45
  "@xmldom/xmldom": "^0.9.12",
46
- "tsup": "^8.0.0",
46
+ "tsdown": "^0.23.0",
47
47
  "typescript": "^7.0.2",
48
48
  "vitest": "^5.0.0"
49
49
  },