@staticduo/opencode-scheduler 1.3.4 → 1.3.5

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.
Files changed (2) hide show
  1. package/dist/index.js +48 -5
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -12524,22 +12524,36 @@ function temporaryPath(path) {
12524
12524
  }
12525
12525
  function atomicReplace(path, content, mode, fileSystem) {
12526
12526
  const temporary = temporaryPath(path);
12527
+ let primaryError;
12527
12528
  try {
12528
12529
  fileSystem.writeFile(temporary, content, { mode });
12529
12530
  fileSystem.chmod(temporary, mode);
12530
12531
  fileSystem.rename(temporary, path);
12531
12532
  fileSystem.chmod(path, mode);
12533
+ } catch (error45) {
12534
+ primaryError = error45;
12535
+ throw error45;
12532
12536
  } finally {
12533
- removeNode(temporary, fileSystem);
12537
+ if (primaryError)
12538
+ bestEffort(() => removeNode(temporary, fileSystem));
12539
+ else
12540
+ removeNode(temporary, fileSystem);
12534
12541
  }
12535
12542
  }
12536
12543
  function atomicSymlink(path, target, fileSystem) {
12537
12544
  const temporary = temporaryPath(path);
12545
+ let primaryError;
12538
12546
  try {
12539
12547
  fileSystem.symlink(target, temporary);
12540
12548
  fileSystem.rename(temporary, path);
12549
+ } catch (error45) {
12550
+ primaryError = error45;
12551
+ throw error45;
12541
12552
  } finally {
12542
- removeNode(temporary, fileSystem);
12553
+ if (primaryError)
12554
+ bestEffort(() => removeNode(temporary, fileSystem));
12555
+ else
12556
+ removeNode(temporary, fileSystem);
12543
12557
  }
12544
12558
  }
12545
12559
  function removeNode(path, fileSystem) {
@@ -12662,12 +12676,34 @@ function acquireLock(lockRoot, timerUnit, fileSystem, overrides) {
12662
12676
  } catch (error45) {
12663
12677
  if (!isErrorCode(error45, "EEXIST"))
12664
12678
  throw error45;
12679
+ let lockStats;
12680
+ try {
12681
+ lockStats = fileSystem.lstat(lockPath);
12682
+ } catch (inspectError) {
12683
+ if (isErrorCode(inspectError, "ENOENT"))
12684
+ continue;
12685
+ throw inspectError;
12686
+ }
12687
+ if (lockStats.isSymbolicLink()) {
12688
+ throw new Error(`Refusing systemd install lock symlink at ${lockPath}`);
12689
+ }
12690
+ if (!lockStats.isDirectory()) {
12691
+ throw new Error(`Refusing non-directory systemd install lock at ${lockPath}`);
12692
+ }
12665
12693
  const metadata = readLockMetadata(lockPath, fileSystem);
12666
- const timestamp = metadata.timestamp ?? fileSystem.lstat(lockPath).mtimeMs;
12694
+ const timestamp = metadata.timestamp ?? lockStats.mtimeMs;
12667
12695
  const oldEnough = options.now() - timestamp >= options.staleAfterMs;
12668
12696
  const ownerAlive = metadata.pid !== undefined && options.isPidAlive(metadata.pid);
12669
12697
  if (oldEnough && !ownerAlive) {
12670
- fileSystem.rm(lockPath, { recursive: true, force: true });
12698
+ const quarantinePath = join(lockRoot, `${timerUnit}.stale-${options.pid}-${options.now()}-${temporaryFileSequence += 1}`);
12699
+ try {
12700
+ fileSystem.rename(lockPath, quarantinePath);
12701
+ } catch (claimError) {
12702
+ if (isErrorCode(claimError, "ENOENT") || isErrorCode(claimError, "EEXIST"))
12703
+ continue;
12704
+ throw claimError;
12705
+ }
12706
+ fileSystem.rm(quarantinePath, { recursive: true, force: true });
12671
12707
  continue;
12672
12708
  }
12673
12709
  if (options.now() - startedAt >= options.timeoutMs) {
@@ -12680,6 +12716,7 @@ function acquireLock(lockRoot, timerUnit, fileSystem, overrides) {
12680
12716
  function installSystemdUnits(request) {
12681
12717
  const fileSystem = request.fileSystem ?? defaultFileSystem;
12682
12718
  const releaseLock = acquireLock(request.lockDir ?? join(request.unitDir, ".opencode-scheduler-locks"), request.timerUnit, fileSystem, request.lock);
12719
+ let primaryError;
12683
12720
  try {
12684
12721
  fileSystem.mkdir(request.unitDir, { recursive: true });
12685
12722
  const servicePath = join(request.unitDir, request.serviceUnit);
@@ -12709,8 +12746,14 @@ function installSystemdUnits(request) {
12709
12746
  bestEffort(() => request.run(`systemctl --user start ${request.timerUnit}`, { stdio: "ignore" }));
12710
12747
  throw error45;
12711
12748
  }
12749
+ } catch (error45) {
12750
+ primaryError = error45;
12751
+ throw error45;
12712
12752
  } finally {
12713
- releaseLock();
12753
+ if (primaryError)
12754
+ bestEffort(releaseLock);
12755
+ else
12756
+ releaseLock();
12714
12757
  }
12715
12758
  }
12716
12759
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@staticduo/opencode-scheduler",
3
- "version": "1.3.4",
3
+ "version": "1.3.5",
4
4
  "description": "OpenCode plugin for scheduling recurring jobs using launchd, systemd, Task Scheduler, or cron fallback",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",