@tscircuit/cli 0.1.2416 → 0.1.2418

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/dist/cli/main.js CHANGED
@@ -1,4 +1,4 @@
1
1
  [diffend] Oversized file quarantined before diffing.
2
2
  name: package/dist/cli/main.js
3
- size: 47765936 bytes
4
- sha256: 14f2124ed15f4d98acf69d15822504e5579c4b4a008fa8a1f69d32acdd699403
3
+ size: 47821031 bytes
4
+ sha256: f62635798b3691e5a8057eeb9784bad9bab73664e82ce9fb31f3a3ccc517cfc3
package/dist/lib/index.js CHANGED
@@ -87226,6 +87226,68 @@ Publish completed with ${uploadResults.succeeded.length} files uploaded and ${up
87226
87226
  return onExit(0);
87227
87227
  };
87228
87228
 
87229
+ // lib/dev/coalesced-file-sync.ts
87230
+ class CoalescedFileSync {
87231
+ sync;
87232
+ onError;
87233
+ delayMs;
87234
+ maxWaitMs;
87235
+ pending = new Set;
87236
+ firstChangeAt = 0;
87237
+ lastChangeAt = 0;
87238
+ timer;
87239
+ running;
87240
+ stopped = false;
87241
+ constructor(sync, onError, delayMs = 250, maxWaitMs = 1000) {
87242
+ this.sync = sync;
87243
+ this.onError = onError;
87244
+ this.delayMs = delayMs;
87245
+ this.maxWaitMs = maxWaitMs;
87246
+ }
87247
+ enqueue(filePath) {
87248
+ if (this.stopped)
87249
+ return;
87250
+ if (this.pending.size === 0)
87251
+ this.firstChangeAt = Date.now();
87252
+ this.lastChangeAt = Date.now();
87253
+ this.pending.add(filePath);
87254
+ this.schedule();
87255
+ }
87256
+ schedule() {
87257
+ clearTimeout(this.timer);
87258
+ if (this.stopped || this.pending.size === 0)
87259
+ return;
87260
+ const due = Math.min(this.lastChangeAt + this.delayMs, this.firstChangeAt + this.maxWaitMs);
87261
+ this.timer = setTimeout(() => this.flush(), Math.max(0, due - Date.now()));
87262
+ }
87263
+ flush() {
87264
+ if (this.running || this.stopped)
87265
+ return;
87266
+ const paths = [...this.pending];
87267
+ this.pending.clear();
87268
+ this.running = (async () => {
87269
+ for (const filePath of paths) {
87270
+ if (this.stopped)
87271
+ break;
87272
+ try {
87273
+ await this.sync(filePath);
87274
+ } catch (error) {
87275
+ this.onError(filePath, error);
87276
+ }
87277
+ }
87278
+ })().finally(() => {
87279
+ this.running = undefined;
87280
+ this.schedule();
87281
+ });
87282
+ }
87283
+ async stop() {
87284
+ this.stopped = true;
87285
+ clearTimeout(this.timer);
87286
+ this.pending.clear();
87287
+ await this.running;
87288
+ }
87289
+ }
87290
+
87229
87291
  // lib/dev/DevServer.ts
87230
87292
  var debug2 = Debug2("tscircuit:devserver");
87231
87293
  var BINARY_FILE_EXTENSIONS2 = new Set([".glb", ".png", ".jpeg", ".jpg"]);
@@ -87269,6 +87331,18 @@ class DevServer {
87269
87331
  filesystemWatcher;
87270
87332
  uploadedNodeModules = new Set;
87271
87333
  autorouterPhaseReached = false;
87334
+ syncedContents = new Map;
87335
+ fileSync = new CoalescedFileSync(async (filePath) => {
87336
+ try {
87337
+ if (fs26.statSync(filePath).isFile()) {
87338
+ await this.handleFileChangedOnFilesystem(filePath);
87339
+ }
87340
+ } catch (error) {
87341
+ if (error.code !== "ENOENT")
87342
+ throw error;
87343
+ await this.handleFileRemovedFromFilesystem(filePath);
87344
+ }
87345
+ }, (filePath, error) => console.error(`Failed to sync ${filePath}:`, error));
87272
87346
  constructor({
87273
87347
  port,
87274
87348
  componentFilePath,
@@ -87323,12 +87397,13 @@ class DevServer {
87323
87397
  this.filesystemWatcher = watch(this.projectDir, {
87324
87398
  persistent: true,
87325
87399
  ignoreInitial: true,
87400
+ atomic: 100,
87326
87401
  ignored: (p) => path32.resolve(p) === process.execPath || shouldIgnorePath(path32.relative(this.projectDir, p), this.ignoredFiles)
87327
87402
  });
87328
- this.filesystemWatcher.on("change", (filePath) => this.handleFileChangedOnFilesystem(filePath));
87329
- this.filesystemWatcher.on("add", (filePath) => this.handleFileChangedOnFilesystem(filePath));
87330
- this.filesystemWatcher.on("unlink", (filePath) => this.handleFileRemovedFromFilesystem(filePath));
87331
- this.filesystemWatcher.on("unlinkDir", (filePath) => this.handleFileRemovedFromFilesystem(filePath));
87403
+ this.filesystemWatcher.on("change", (filePath) => this.fileSync.enqueue(filePath));
87404
+ this.filesystemWatcher.on("add", (filePath) => this.fileSync.enqueue(filePath));
87405
+ this.filesystemWatcher.on("unlink", (filePath) => this.fileSync.enqueue(filePath));
87406
+ this.filesystemWatcher.on("unlinkDir", (filePath) => this.fileSync.enqueue(filePath));
87332
87407
  this.filesystemWatcher.on("rename", (oldPath, newPath) => this.handleFileRename(oldPath, newPath));
87333
87408
  await this.upsertInitialFiles();
87334
87409
  }
@@ -87347,8 +87422,10 @@ class DevServer {
87347
87422
  if (file.binary_content_b64) {
87348
87423
  const decodedContent = Buffer.from(file.binary_content_b64, "base64");
87349
87424
  fs26.writeFileSync(fullPath, decodedContent);
87425
+ this.syncedContents.set(ev.file_path, decodedContent);
87350
87426
  } else {
87351
87427
  fs26.writeFileSync(fullPath, file.text_content ?? "", "utf-8");
87428
+ this.syncedContents.set(ev.file_path, Buffer.from(file.text_content ?? "", "utf-8"));
87352
87429
  }
87353
87430
  }
87354
87431
  async handleFileDeletedEventFromServer(ev) {
@@ -87366,13 +87443,17 @@ class DevServer {
87366
87443
  return;
87367
87444
  this.autorouterPhaseReached = false;
87368
87445
  const filePayload = this.createFileUploadPayload(absoluteFilePath, relativeFilePath);
87446
+ const content = "text_content" in filePayload ? Buffer.from(filePayload.text_content, "utf-8") : filePayload.binary_content;
87447
+ const previous = this.syncedContents.get(relativeFilePath);
87448
+ if (previous?.equals(content))
87449
+ return;
87450
+ await this.checkAndUploadNewNodeModules(absoluteFilePath);
87369
87451
  console.log(kleur_default.green(`Saving: ${relativeFilePath}`));
87370
87452
  await this.postFileUpsert({
87371
87453
  filePath: relativeFilePath,
87372
87454
  initiator: "filesystem_change",
87373
87455
  filePayload
87374
87456
  });
87375
- await this.checkAndUploadNewNodeModules(absoluteFilePath);
87376
87457
  }
87377
87458
  async checkAndUploadNewNodeModules(filePath) {
87378
87459
  const ext = path32.extname(filePath).toLowerCase();
@@ -87432,6 +87513,7 @@ class DevServer {
87432
87513
  return;
87433
87514
  }
87434
87515
  debug2(`Successfully deleted file ${relativeFilePath} from server`);
87516
+ this.syncedContents.delete(relativeFilePath);
87435
87517
  }
87436
87518
  async handleFileRename(oldPath, newPath) {
87437
87519
  const oldRelativePath = path32.relative(this.projectDir, oldPath);
@@ -87507,6 +87589,7 @@ class DevServer {
87507
87589
  initiator,
87508
87590
  binaryContent: filePayload.binary_content
87509
87591
  });
87592
+ this.syncedContents.set(filePath, filePayload.binary_content);
87510
87593
  return;
87511
87594
  }
87512
87595
  await this.fsKy.post("api/files/upsert", {
@@ -87516,6 +87599,7 @@ class DevServer {
87516
87599
  ...filePayload
87517
87600
  }
87518
87601
  });
87602
+ this.syncedContents.set(filePath, Buffer.from(filePayload.text_content, "utf-8"));
87519
87603
  } catch (error) {
87520
87604
  this.logFileUpsertTimeout(error, filePath);
87521
87605
  throw error;
@@ -87575,9 +87659,10 @@ class DevServer {
87575
87659
  });
87576
87660
  }
87577
87661
  async stop() {
87578
- this.httpServer?.close();
87579
87662
  this.eventsWatcher?.stop();
87580
87663
  await this.filesystemWatcher?.close();
87664
+ await this.fileSync.stop();
87665
+ this.httpServer?.close();
87581
87666
  }
87582
87667
  createFileUploadPayload(absoluteFilePath, relativeFilePath) {
87583
87668
  const ext = path32.extname(relativeFilePath).toLowerCase();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tscircuit/cli",
3
- "version": "0.1.2416",
3
+ "version": "0.1.2418",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/tscircuit/cli"
@@ -22,7 +22,7 @@
22
22
  "@tscircuit/fake-snippets": "^0.0.226",
23
23
  "@tscircuit/file-server": "^0.0.32",
24
24
  "@tscircuit/footprinter": "^0.0.445",
25
- "@tscircuit/pcb-spice-pipeline": "https://api.github.com/repos/tscircuit/pcb-spice-pipeline/tarball/63d15671ec68833225132066df317a8d7e4820e7",
25
+ "@tscircuit/pcb-spice-pipeline": "https://github.com/tscircuit/pcb-spice-pipeline/releases/download/v0.1.0/tscircuit-pcb-spice-pipeline-0.1.0.tgz",
26
26
  "@tscircuit/schematic-trace-solver": "^0.0.204",
27
27
  "@types/bun": "^1.2.2",
28
28
  "@types/configstore": "^6.0.2",