jm2 0.1.13 → 0.1.14

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jm2",
3
- "version": "0.1.13",
3
+ "version": "0.1.14",
4
4
  "description": "Job Manager 2 - A simple yet powerful job scheduler combining cron and at functionality",
5
5
  "type": "module",
6
6
  "main": "src/cli/index.js",
@@ -133,7 +133,21 @@ export class Scheduler {
133
133
  // Calculate next run time for active jobs
134
134
  let nextRun = null;
135
135
  if (job.status === JobStatus.ACTIVE) {
136
- nextRun = this.calculateNextRun(job, new Date());
136
+ // Check if there's a stored nextRun that is in the past (missed execution)
137
+ const storedNextRun = job.nextRun || job.nextRunISO;
138
+ if (storedNextRun) {
139
+ const storedDate = new Date(storedNextRun);
140
+ const now = new Date();
141
+ // If stored nextRun is in the past and it's a cron job, keep it so tick() will detect it as overdue
142
+ if (storedDate < now && job.type === JobType.CRON) {
143
+ nextRun = storedDate;
144
+ }
145
+ }
146
+
147
+ // If nextRun wasn't set from stored value, calculate a new one
148
+ if (!nextRun) {
149
+ nextRun = this.calculateNextRun(job, new Date());
150
+ }
137
151
  }
138
152
 
139
153
  this.jobs.set(job.id, {
@@ -360,8 +374,9 @@ export class Scheduler {
360
374
  this.logger.info(`Executing overdue job ${jobId} (${job.name || 'unnamed'})`);
361
375
  // Execute immediately without waiting for the normal due jobs check
362
376
  this.executeJob(job);
363
- // Update next run time from now for the next scheduled occurrence
364
- const nextRun = this.calculateNextRun(job, nowDate);
377
+ // Calculate next run from the original scheduled time to maintain cadence
378
+ const originalNextRun = job.nextRun ? new Date(job.nextRun) : new Date();
379
+ const nextRun = this.calculateNextRunAfterExecution(job, originalNextRun);
365
380
  this.updateJobNextRun(jobId, nextRun);
366
381
  }
367
382
  }
@@ -581,6 +596,14 @@ export class Scheduler {
581
596
  ...job,
582
597
  nextRun: job.nextRun ? job.nextRun.toISOString() : null,
583
598
  }));
599
+
600
+ // Safety check: don't persist empty jobs array if we had jobs before
601
+ // This prevents accidental data loss during startup/shutdown
602
+ if (jobsArray.length === 0 && this.jobs.size > 0) {
603
+ this.logger.error('BUG: Attempted to save empty jobs array but jobs Map is not empty!');
604
+ return;
605
+ }
606
+
584
607
  saveJobs(jobsArray);
585
608
  }
586
609