@anvil-works/anvil-cli 0.3.9 → 0.3.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.
package/dist/index.js CHANGED
@@ -19420,7 +19420,10 @@ var __webpack_exports__ = {};
19420
19420
  const handlers = this.listeners.get(event);
19421
19421
  if (handlers) handlers.forEach((handler)=>{
19422
19422
  try {
19423
- handler(data);
19423
+ const result = handler(data);
19424
+ if (result && "function" == typeof result.catch) result.catch((error)=>{
19425
+ this.onError(String(event), error);
19426
+ });
19424
19427
  } catch (error) {
19425
19428
  this.onError(String(event), error);
19426
19429
  }
@@ -19762,6 +19765,30 @@ var __webpack_exports__ = {};
19762
19765
  throw createGitError.commandFailed("checkout", e.message);
19763
19766
  }
19764
19767
  }
19768
+ async stash(message) {
19769
+ try {
19770
+ const args = [
19771
+ "stash",
19772
+ "push",
19773
+ "--include-untracked"
19774
+ ];
19775
+ if (message) args.push("-m", message);
19776
+ const result = await this.git.raw(args);
19777
+ return !result.includes("No local changes to save");
19778
+ } catch (e) {
19779
+ throw createGitError.commandFailed("stash", e.message);
19780
+ }
19781
+ }
19782
+ async stashPop() {
19783
+ try {
19784
+ await this.git.raw([
19785
+ "stash",
19786
+ "pop"
19787
+ ]);
19788
+ } catch (e) {
19789
+ throw createGitError.commandFailed("stash pop", e.message);
19790
+ }
19791
+ }
19765
19792
  async clean(files) {
19766
19793
  try {
19767
19794
  await this.git.clean(CleanOptions.FORCE, files);
@@ -19809,6 +19836,43 @@ var __webpack_exports__ = {};
19809
19836
  throw createGitError.commandFailed("show", e.message);
19810
19837
  }
19811
19838
  }
19839
+ async push(url, refSpec, force = false) {
19840
+ try {
19841
+ const args = force ? [
19842
+ "push",
19843
+ "--force",
19844
+ url,
19845
+ refSpec
19846
+ ] : [
19847
+ "push",
19848
+ url,
19849
+ refSpec
19850
+ ];
19851
+ await this.git.raw(args);
19852
+ } catch (e) {
19853
+ throw createGitError.commandFailed("push", e.message);
19854
+ }
19855
+ }
19856
+ async rebase(onto) {
19857
+ try {
19858
+ await this.git.raw([
19859
+ "rebase",
19860
+ onto
19861
+ ]);
19862
+ } catch (e) {
19863
+ throw createGitError.commandFailed("rebase", e.message);
19864
+ }
19865
+ }
19866
+ async rebaseAbort() {
19867
+ try {
19868
+ await this.git.raw([
19869
+ "rebase",
19870
+ "--abort"
19871
+ ]);
19872
+ } catch (e) {
19873
+ throw createGitError.commandFailed("rebase --abort", e.message);
19874
+ }
19875
+ }
19812
19876
  async deleteRef(ref) {
19813
19877
  try {
19814
19878
  await this.git.raw([
@@ -21824,7 +21888,13 @@ var __webpack_exports__ = {};
21824
21888
  if (this.reconnectAttempts < this.MAX_RECONNECT_ATTEMPTS) {
21825
21889
  this.reconnectAttempts++;
21826
21890
  logger_logger.verbose(chalk_source.gray(`WebSocket disconnected, reconnecting in ${this.RECONNECT_DELAY / 1000}s (attempt ${this.reconnectAttempts}/${this.MAX_RECONNECT_ATTEMPTS})...`));
21827
- this.reconnectTimer = setTimeout(()=>this.connect(), this.RECONNECT_DELAY);
21891
+ this.reconnectTimer = setTimeout(()=>{
21892
+ this.connect().catch((error)=>{
21893
+ this.emit("error", {
21894
+ error: error instanceof Error ? error : new Error(String(error))
21895
+ });
21896
+ });
21897
+ }, this.RECONNECT_DELAY);
21828
21898
  } else logger_logger.warn(chalk_source.yellow(` WebSocket reconnection failed after ${this.MAX_RECONNECT_ATTEMPTS} attempts. Real-time sync disabled.`));
21829
21899
  });
21830
21900
  this.ws.on("error", (error)=>{
@@ -23495,7 +23565,11 @@ var __webpack_exports__ = {};
23495
23565
  this.hasPendingChanges = true;
23496
23566
  if (this.debounceTimer) clearTimeout(this.debounceTimer);
23497
23567
  if (isFirstChange) logger_logger.progress("sync", "Change detected");
23498
- this.debounceTimer = setTimeout(()=>this.processSaveBatchWithEvents(), this.SAVE_DEBOUNCE_MS);
23568
+ this.debounceTimer = setTimeout(()=>{
23569
+ this.processSaveBatchWithEvents().catch((error)=>{
23570
+ logger_logger.error(`Save failed: ${errors_getErrorMessage(error)}`);
23571
+ });
23572
+ }, this.SAVE_DEBOUNCE_MS);
23499
23573
  }
23500
23574
  async forceSave() {
23501
23575
  if (this.debounceTimer) {
@@ -23862,8 +23936,11 @@ var __webpack_exports__ = {};
23862
23936
  }
23863
23937
  async handleConflict(json_resp, originalFilePaths, retryCount) {
23864
23938
  if (retryCount >= this.MAX_RETRIES) {
23865
- logger_logger.error(`Save failed after ${this.MAX_RETRIES} retries - version conflict`);
23866
- logger_logger.warn("Please resolve conflicts manually or restart anvil sync");
23939
+ logger_logger.error(`Save failed after ${this.MAX_RETRIES} retries due to version conflicts.`);
23940
+ logger_logger.warn("This usually means someone else is editing the app at the same time.");
23941
+ this.emit("max-retries-exceeded", {
23942
+ retries: this.MAX_RETRIES
23943
+ });
23867
23944
  throw createSaveError.maxRetriesExceeded(this.MAX_RETRIES);
23868
23945
  }
23869
23946
  let conflictReason = "Unknown conflict";
@@ -24198,6 +24275,7 @@ var __webpack_exports__ = {};
24198
24275
  this.saveProcessor.on("save-complete", (data)=>this.emit("save-complete", data));
24199
24276
  this.saveProcessor.on("validation-failed", (data)=>this.emit("validation-failed", data));
24200
24277
  this.saveProcessor.on("sync-conflict", (data)=>this.emit("sync-conflict", data));
24278
+ this.saveProcessor.on("max-retries-exceeded", (data)=>this.emit("max-retries-exceeded", data));
24201
24279
  }
24202
24280
  async connectWebSocket() {
24203
24281
  this.wsClient = new WebSocketClient({
@@ -24270,7 +24348,11 @@ var __webpack_exports__ = {};
24270
24348
  this.saveProcessor?.queueSave();
24271
24349
  });
24272
24350
  this.fileWatcher.on("file-change", async ({ event, path: filePath, relativePath })=>{
24273
- await this.handleFileChange(event, filePath, relativePath);
24351
+ try {
24352
+ await this.handleFileChange(event, filePath, relativePath);
24353
+ } catch (error) {
24354
+ logger_logger.error(`Error handling file change for ${relativePath}: ${error.message}`);
24355
+ }
24274
24356
  });
24275
24357
  await this.fileWatcher.start(this.currentBranch);
24276
24358
  await new Promise(()=>{});
@@ -24460,7 +24542,12 @@ var __webpack_exports__ = {};
24460
24542
  }
24461
24543
  const allBranches = data.apps?.flatMap((app)=>app.branches || []) || [];
24462
24544
  const branchExistsOnAnvil = allBranches.some((b)=>b === branchName);
24463
- if (!branchExistsOnAnvil) throw createValidationError.invalidApp(branchName, `Branch '${branchName}' doesn't exist on Anvil yet. Push to Anvil first: git push anvil ${branchName}`);
24545
+ if (!branchExistsOnAnvil) return {
24546
+ behind: 0,
24547
+ ahead: 0,
24548
+ diverged: false,
24549
+ branchMissing: true
24550
+ };
24464
24551
  throw createValidationError.invalidApp(appId, `Anvil server doesn't recognize commit ${commitId.substring(0, 8)} on branch '${branchName}'. Please pull the latest changes from Anvil before starting sync.`);
24465
24552
  } catch (e) {
24466
24553
  if (e.type) throw e;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anvil-works/anvil-cli",
3
- "version": "0.3.9",
3
+ "version": "0.3.11",
4
4
  "description": "CLI tool for developing Anvil apps locally",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -15,6 +15,7 @@
15
15
  },
16
16
  "keywords": [
17
17
  "anvil",
18
+ "watch",
18
19
  "sync",
19
20
  "cli",
20
21
  "git",