@orion-js/dogs 4.3.4 → 4.3.6

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.d.cts CHANGED
@@ -1,4 +1,3 @@
1
- import * as _orion_js_schema from '@orion-js/schema';
2
1
  import { SchemaInAnyOrionForm, Blackbox, InferSchemaType } from '@orion-js/schema';
3
2
  import { OrionLogger } from '@orion-js/logger';
4
3
  import { Collection, MongoDB } from '@orion-js/mongodb';
@@ -65,115 +64,16 @@ interface ScheduleJobsResult {
65
64
  }>;
66
65
  }
67
66
 
68
- declare const HistoryRecordSchema: {
69
- _id: {
70
- type: "string";
71
- };
72
- jobId: {
73
- type: "string";
74
- };
75
- executionId: {
76
- type: "string";
77
- };
78
- jobName: {
79
- type: "string";
80
- };
81
- type: {
82
- type: "string";
83
- };
84
- priority: {
85
- type: "number";
86
- };
87
- tries: {
88
- type: "number";
89
- };
90
- uniqueIdentifier: {
91
- type: "string";
92
- optional: true;
93
- };
94
- startedAt: {
95
- type: "date";
96
- };
97
- endedAt: {
98
- type: "date";
99
- };
100
- duration: {
101
- type: "number";
102
- };
103
- expiresAt: {
104
- type: "date";
105
- optional: true;
106
- };
107
- status: {
108
- type: "string";
109
- enum: string[];
110
- };
111
- errorMessage: {
112
- type: "string";
113
- optional: true;
114
- };
115
- params: {
116
- type: "blackbox";
117
- optional: true;
118
- };
119
- result: {
120
- type: "any";
121
- optional: true;
122
- };
123
- };
67
+ declare const HistoryRecordSchema: any;
124
68
  type HistoryRecord = InferSchemaType<typeof HistoryRecordSchema>;
125
69
 
126
70
  /**
127
71
  * Enum representing the status of a job record.
128
72
  * - 'pending': Job is active and can be executed (default for existing records)
129
- * - 'maxTriesReached': Job has exhausted all retry attempts and won't be executed
73
+ * - 'maxTriesReached': Event job has exhausted all retry attempts and won't be executed
130
74
  */
131
- declare const JobStatusEnum: _orion_js_schema.FieldType<"pending" | "maxTriesReached">;
132
- declare const JobRecordSchema: {
133
- _id: {
134
- type: "string";
135
- };
136
- jobName: {
137
- type: "string";
138
- };
139
- type: {
140
- type: _orion_js_schema.FieldType<"recurrent" | "event">;
141
- };
142
- priority: {
143
- type: "number";
144
- };
145
- uniqueIdentifier: {
146
- type: "string";
147
- optional: true;
148
- };
149
- nextRunAt: {
150
- type: "date";
151
- };
152
- lastRunAt: {
153
- type: "date";
154
- optional: true;
155
- };
156
- lockedUntil: {
157
- type: "date";
158
- optional: true;
159
- };
160
- tries: {
161
- type: "number";
162
- optional: true;
163
- };
164
- params: {
165
- type: "blackbox";
166
- optional: true;
167
- };
168
- /**
169
- * Status of the job. Optional for backwards compatibility with existing records.
170
- * Records without this field are treated as 'pending'.
171
- */
172
- status: {
173
- type: _orion_js_schema.FieldType<"pending" | "maxTriesReached">;
174
- optional: true;
175
- };
176
- };
75
+ declare const JobStatusEnum: any;
76
+ declare const JobRecordSchema: any;
177
77
  type JobRecord = InferSchemaType<typeof JobRecordSchema>;
178
78
 
179
79
  interface JobToRun {
@@ -249,12 +149,6 @@ interface BaseJobDefinition {
249
149
  * If not set, the defaultLockTime from config will be used.
250
150
  */
251
151
  lockTime?: number;
252
- /**
253
- * Maximum number of tries for this specific job before it is marked as 'maxTriesReached'.
254
- * Overrides the global maxTries set in startWorkers config.
255
- * If not set, the global maxTries from config will be used.
256
- */
257
- maxTries?: number;
258
152
  }
259
153
  interface RecurrentJobDefinition extends BaseJobDefinition {
260
154
  /**
@@ -269,6 +163,14 @@ interface RecurrentJobDefinition extends BaseJobDefinition {
269
163
  * Run every x milliseconds. This will be ignored if getNextRun is defined.
270
164
  */
271
165
  runEvery?: number;
166
+ /**
167
+ * Cron expression used to calculate the next run. Requires timezone.
168
+ */
169
+ cron?: string;
170
+ /**
171
+ * IANA timezone used to calculate cron-based schedules.
172
+ */
173
+ timezone?: string;
272
174
  /**
273
175
  * The priority of the job. Higher is more priority. Default is 100.
274
176
  */
@@ -283,6 +185,12 @@ interface EventJobDefinition<TParamsSchema extends SchemaInAnyOrionForm = any> e
283
185
  * Type of the job.
284
186
  */
285
187
  type: 'event';
188
+ /**
189
+ * Maximum number of tries for this specific event job before it is marked as 'maxTriesReached'.
190
+ * Overrides the global maxTries set in startWorkers config.
191
+ * If not set, the global maxTries from config will be used.
192
+ */
193
+ maxTries?: number;
286
194
  /**
287
195
  * Schedule of the job. Supports optional runIn (milliseconds) or runAt (Date) for delayed execution.
288
196
  */
@@ -306,13 +214,28 @@ interface EventJobDefinition<TParamsSchema extends SchemaInAnyOrionForm = any> e
306
214
  resolve: (params: InferSchemaType<TParamsSchema>, context: ExecutionContext) => Promise<any>;
307
215
  }
308
216
  type CreateEventJobOptions<TParamsSchema extends SchemaInAnyOrionForm = any> = Omit<EventJobDefinition<TParamsSchema>, 'type' | 'schedule' | 'scheduleJobs'>;
309
- type CreateRecurrentJobOptions = Omit<RecurrentJobDefinition, 'type' | 'runEvery'> & {
217
+ type CreateRecurrentJobBaseOptions = Omit<RecurrentJobDefinition, 'type' | 'runEvery' | 'cron' | 'timezone'>;
218
+ type CreateRecurrentJobRunEveryOptions = CreateRecurrentJobBaseOptions & {
310
219
  /**
311
220
  * Run every x milliseconds.
312
221
  * Accepts https://github.com/jkroso/parse-duration strings.
313
222
  */
314
223
  runEvery: number | string;
224
+ cron?: never;
225
+ timezone?: string;
315
226
  };
227
+ type CreateRecurrentJobCronOptions = CreateRecurrentJobBaseOptions & {
228
+ /**
229
+ * Cron expression used to calculate the next run.
230
+ */
231
+ cron: string;
232
+ /**
233
+ * IANA timezone used to calculate cron-based schedules.
234
+ */
235
+ timezone: string;
236
+ runEvery?: never;
237
+ };
238
+ type CreateRecurrentJobOptions = CreateRecurrentJobRunEveryOptions | CreateRecurrentJobCronOptions;
316
239
  type CreateJobOptions<TParamsSchema extends SchemaInAnyOrionForm = any> = CreateEventJobOptions<TParamsSchema> | CreateRecurrentJobOptions;
317
240
  type JobDefinition<TParamsSchema extends SchemaInAnyOrionForm = any> = RecurrentJobDefinition | EventJobDefinition<TParamsSchema>;
318
241
  type JobDefinitionWithName<TParamsSchema extends SchemaInAnyOrionForm = any> = JobDefinition<TParamsSchema> & {
@@ -329,16 +252,16 @@ interface StartWorkersConfig {
329
252
  */
330
253
  jobs: JobsDefinition;
331
254
  /**
332
- * Maximum number of tries for a job before it is marked as 'maxTriesReached'.
333
- * This is a required global default that can be overridden per job definition.
255
+ * Maximum number of tries for an event job before it is marked as 'maxTriesReached'.
256
+ * This is a global default that can be overridden per event job definition.
334
257
  */
335
- maxTries: number;
258
+ maxTries?: number;
336
259
  /**
337
- * Callback invoked when a job reaches its maximum tries limit.
260
+ * Callback invoked when an event job reaches its maximum tries limit.
338
261
  * Use this to notify administrators (e.g., send an email alert).
339
262
  * The job will remain in the database with status 'maxTriesReached'.
340
263
  */
341
- onMaxTriesReached: (job: JobToRun) => Promise<void>;
264
+ onMaxTriesReached?: (job: JobToRun) => Promise<void>;
342
265
  /**
343
266
  * Time in milliseconds to wait between each look without results for a job
344
267
  * to run at the database. Default is 3000.
@@ -380,7 +303,7 @@ declare class JobsRepo {
380
303
  }): Promise<void>;
381
304
  deleteEventJob(jobId: string): Promise<void>;
382
305
  /**
383
- * Marks a job as having reached its maximum tries limit.
306
+ * Marks an event job as having reached its maximum tries limit.
384
307
  * The job will remain in the database but won't be picked up for execution.
385
308
  */
386
309
  markJobAsMaxTriesReached(jobId: string): Promise<void>;
@@ -427,4 +350,4 @@ declare const scheduleJob: <TParamsSchema extends SchemaInAnyOrionForm = any>(op
427
350
  */
428
351
  declare const scheduleJobs: <TParamsSchema extends SchemaInAnyOrionForm = any>(jobs: ScheduleJobsOptions<TParamsSchema>) => Promise<ScheduleJobsResult>;
429
352
 
430
- export { type BaseJobDefinition, type CreateEventJobOptions, type CreateJobOptions, type CreateRecurrentJobOptions, EventJob, type EventJobDefinition, type ExecutionContext, type HistoryRecord, HistoryRecordSchema, type JobDefinition, type JobDefinitionWithName, type JobRecord, JobRecordSchema, type JobRetryResult, type JobRetryResultBase, type JobRetryResultRunAt, type JobRetryResultRunIn, JobStatusEnum, type JobToRun, Jobs, type JobsDefinition, type LogLevels, RecurrentJob, type RecurrentJobDefinition, type ScheduleJobOptions, type ScheduleJobOptionsBase, type ScheduleJobOptionsRunAt, type ScheduleJobOptionsRunIn, type ScheduleJobOptionsWithoutName, type ScheduleJobRecordOptions, type ScheduleJobsOptions, type ScheduleJobsResult, type StartWorkersConfig, type WorkerInstance, type WorkersInstance, createEventJob, createRecurrentJob, defineJob, getServiceJobs, jobsHistoryRepo, jobsRepo, scheduleJob, scheduleJobs, startWorkers };
353
+ export { type BaseJobDefinition, type CreateEventJobOptions, type CreateJobOptions, type CreateRecurrentJobCronOptions, type CreateRecurrentJobOptions, type CreateRecurrentJobRunEveryOptions, EventJob, type EventJobDefinition, type ExecutionContext, type HistoryRecord, HistoryRecordSchema, type JobDefinition, type JobDefinitionWithName, type JobRecord, JobRecordSchema, type JobRetryResult, type JobRetryResultBase, type JobRetryResultRunAt, type JobRetryResultRunIn, JobStatusEnum, type JobToRun, Jobs, type JobsDefinition, type LogLevels, RecurrentJob, type RecurrentJobDefinition, type ScheduleJobOptions, type ScheduleJobOptionsBase, type ScheduleJobOptionsRunAt, type ScheduleJobOptionsRunIn, type ScheduleJobOptionsWithoutName, type ScheduleJobRecordOptions, type ScheduleJobsOptions, type ScheduleJobsResult, type StartWorkersConfig, type WorkerInstance, type WorkersInstance, createEventJob, createRecurrentJob, defineJob, getServiceJobs, jobsHistoryRepo, jobsRepo, scheduleJob, scheduleJobs, startWorkers };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,3 @@
1
- import * as _orion_js_schema from '@orion-js/schema';
2
1
  import { SchemaInAnyOrionForm, Blackbox, InferSchemaType } from '@orion-js/schema';
3
2
  import { OrionLogger } from '@orion-js/logger';
4
3
  import { Collection, MongoDB } from '@orion-js/mongodb';
@@ -65,115 +64,16 @@ interface ScheduleJobsResult {
65
64
  }>;
66
65
  }
67
66
 
68
- declare const HistoryRecordSchema: {
69
- _id: {
70
- type: "string";
71
- };
72
- jobId: {
73
- type: "string";
74
- };
75
- executionId: {
76
- type: "string";
77
- };
78
- jobName: {
79
- type: "string";
80
- };
81
- type: {
82
- type: "string";
83
- };
84
- priority: {
85
- type: "number";
86
- };
87
- tries: {
88
- type: "number";
89
- };
90
- uniqueIdentifier: {
91
- type: "string";
92
- optional: true;
93
- };
94
- startedAt: {
95
- type: "date";
96
- };
97
- endedAt: {
98
- type: "date";
99
- };
100
- duration: {
101
- type: "number";
102
- };
103
- expiresAt: {
104
- type: "date";
105
- optional: true;
106
- };
107
- status: {
108
- type: "string";
109
- enum: string[];
110
- };
111
- errorMessage: {
112
- type: "string";
113
- optional: true;
114
- };
115
- params: {
116
- type: "blackbox";
117
- optional: true;
118
- };
119
- result: {
120
- type: "any";
121
- optional: true;
122
- };
123
- };
67
+ declare const HistoryRecordSchema: any;
124
68
  type HistoryRecord = InferSchemaType<typeof HistoryRecordSchema>;
125
69
 
126
70
  /**
127
71
  * Enum representing the status of a job record.
128
72
  * - 'pending': Job is active and can be executed (default for existing records)
129
- * - 'maxTriesReached': Job has exhausted all retry attempts and won't be executed
73
+ * - 'maxTriesReached': Event job has exhausted all retry attempts and won't be executed
130
74
  */
131
- declare const JobStatusEnum: _orion_js_schema.FieldType<"pending" | "maxTriesReached">;
132
- declare const JobRecordSchema: {
133
- _id: {
134
- type: "string";
135
- };
136
- jobName: {
137
- type: "string";
138
- };
139
- type: {
140
- type: _orion_js_schema.FieldType<"recurrent" | "event">;
141
- };
142
- priority: {
143
- type: "number";
144
- };
145
- uniqueIdentifier: {
146
- type: "string";
147
- optional: true;
148
- };
149
- nextRunAt: {
150
- type: "date";
151
- };
152
- lastRunAt: {
153
- type: "date";
154
- optional: true;
155
- };
156
- lockedUntil: {
157
- type: "date";
158
- optional: true;
159
- };
160
- tries: {
161
- type: "number";
162
- optional: true;
163
- };
164
- params: {
165
- type: "blackbox";
166
- optional: true;
167
- };
168
- /**
169
- * Status of the job. Optional for backwards compatibility with existing records.
170
- * Records without this field are treated as 'pending'.
171
- */
172
- status: {
173
- type: _orion_js_schema.FieldType<"pending" | "maxTriesReached">;
174
- optional: true;
175
- };
176
- };
75
+ declare const JobStatusEnum: any;
76
+ declare const JobRecordSchema: any;
177
77
  type JobRecord = InferSchemaType<typeof JobRecordSchema>;
178
78
 
179
79
  interface JobToRun {
@@ -249,12 +149,6 @@ interface BaseJobDefinition {
249
149
  * If not set, the defaultLockTime from config will be used.
250
150
  */
251
151
  lockTime?: number;
252
- /**
253
- * Maximum number of tries for this specific job before it is marked as 'maxTriesReached'.
254
- * Overrides the global maxTries set in startWorkers config.
255
- * If not set, the global maxTries from config will be used.
256
- */
257
- maxTries?: number;
258
152
  }
259
153
  interface RecurrentJobDefinition extends BaseJobDefinition {
260
154
  /**
@@ -269,6 +163,14 @@ interface RecurrentJobDefinition extends BaseJobDefinition {
269
163
  * Run every x milliseconds. This will be ignored if getNextRun is defined.
270
164
  */
271
165
  runEvery?: number;
166
+ /**
167
+ * Cron expression used to calculate the next run. Requires timezone.
168
+ */
169
+ cron?: string;
170
+ /**
171
+ * IANA timezone used to calculate cron-based schedules.
172
+ */
173
+ timezone?: string;
272
174
  /**
273
175
  * The priority of the job. Higher is more priority. Default is 100.
274
176
  */
@@ -283,6 +185,12 @@ interface EventJobDefinition<TParamsSchema extends SchemaInAnyOrionForm = any> e
283
185
  * Type of the job.
284
186
  */
285
187
  type: 'event';
188
+ /**
189
+ * Maximum number of tries for this specific event job before it is marked as 'maxTriesReached'.
190
+ * Overrides the global maxTries set in startWorkers config.
191
+ * If not set, the global maxTries from config will be used.
192
+ */
193
+ maxTries?: number;
286
194
  /**
287
195
  * Schedule of the job. Supports optional runIn (milliseconds) or runAt (Date) for delayed execution.
288
196
  */
@@ -306,13 +214,28 @@ interface EventJobDefinition<TParamsSchema extends SchemaInAnyOrionForm = any> e
306
214
  resolve: (params: InferSchemaType<TParamsSchema>, context: ExecutionContext) => Promise<any>;
307
215
  }
308
216
  type CreateEventJobOptions<TParamsSchema extends SchemaInAnyOrionForm = any> = Omit<EventJobDefinition<TParamsSchema>, 'type' | 'schedule' | 'scheduleJobs'>;
309
- type CreateRecurrentJobOptions = Omit<RecurrentJobDefinition, 'type' | 'runEvery'> & {
217
+ type CreateRecurrentJobBaseOptions = Omit<RecurrentJobDefinition, 'type' | 'runEvery' | 'cron' | 'timezone'>;
218
+ type CreateRecurrentJobRunEveryOptions = CreateRecurrentJobBaseOptions & {
310
219
  /**
311
220
  * Run every x milliseconds.
312
221
  * Accepts https://github.com/jkroso/parse-duration strings.
313
222
  */
314
223
  runEvery: number | string;
224
+ cron?: never;
225
+ timezone?: string;
315
226
  };
227
+ type CreateRecurrentJobCronOptions = CreateRecurrentJobBaseOptions & {
228
+ /**
229
+ * Cron expression used to calculate the next run.
230
+ */
231
+ cron: string;
232
+ /**
233
+ * IANA timezone used to calculate cron-based schedules.
234
+ */
235
+ timezone: string;
236
+ runEvery?: never;
237
+ };
238
+ type CreateRecurrentJobOptions = CreateRecurrentJobRunEveryOptions | CreateRecurrentJobCronOptions;
316
239
  type CreateJobOptions<TParamsSchema extends SchemaInAnyOrionForm = any> = CreateEventJobOptions<TParamsSchema> | CreateRecurrentJobOptions;
317
240
  type JobDefinition<TParamsSchema extends SchemaInAnyOrionForm = any> = RecurrentJobDefinition | EventJobDefinition<TParamsSchema>;
318
241
  type JobDefinitionWithName<TParamsSchema extends SchemaInAnyOrionForm = any> = JobDefinition<TParamsSchema> & {
@@ -329,16 +252,16 @@ interface StartWorkersConfig {
329
252
  */
330
253
  jobs: JobsDefinition;
331
254
  /**
332
- * Maximum number of tries for a job before it is marked as 'maxTriesReached'.
333
- * This is a required global default that can be overridden per job definition.
255
+ * Maximum number of tries for an event job before it is marked as 'maxTriesReached'.
256
+ * This is a global default that can be overridden per event job definition.
334
257
  */
335
- maxTries: number;
258
+ maxTries?: number;
336
259
  /**
337
- * Callback invoked when a job reaches its maximum tries limit.
260
+ * Callback invoked when an event job reaches its maximum tries limit.
338
261
  * Use this to notify administrators (e.g., send an email alert).
339
262
  * The job will remain in the database with status 'maxTriesReached'.
340
263
  */
341
- onMaxTriesReached: (job: JobToRun) => Promise<void>;
264
+ onMaxTriesReached?: (job: JobToRun) => Promise<void>;
342
265
  /**
343
266
  * Time in milliseconds to wait between each look without results for a job
344
267
  * to run at the database. Default is 3000.
@@ -380,7 +303,7 @@ declare class JobsRepo {
380
303
  }): Promise<void>;
381
304
  deleteEventJob(jobId: string): Promise<void>;
382
305
  /**
383
- * Marks a job as having reached its maximum tries limit.
306
+ * Marks an event job as having reached its maximum tries limit.
384
307
  * The job will remain in the database but won't be picked up for execution.
385
308
  */
386
309
  markJobAsMaxTriesReached(jobId: string): Promise<void>;
@@ -427,4 +350,4 @@ declare const scheduleJob: <TParamsSchema extends SchemaInAnyOrionForm = any>(op
427
350
  */
428
351
  declare const scheduleJobs: <TParamsSchema extends SchemaInAnyOrionForm = any>(jobs: ScheduleJobsOptions<TParamsSchema>) => Promise<ScheduleJobsResult>;
429
352
 
430
- export { type BaseJobDefinition, type CreateEventJobOptions, type CreateJobOptions, type CreateRecurrentJobOptions, EventJob, type EventJobDefinition, type ExecutionContext, type HistoryRecord, HistoryRecordSchema, type JobDefinition, type JobDefinitionWithName, type JobRecord, JobRecordSchema, type JobRetryResult, type JobRetryResultBase, type JobRetryResultRunAt, type JobRetryResultRunIn, JobStatusEnum, type JobToRun, Jobs, type JobsDefinition, type LogLevels, RecurrentJob, type RecurrentJobDefinition, type ScheduleJobOptions, type ScheduleJobOptionsBase, type ScheduleJobOptionsRunAt, type ScheduleJobOptionsRunIn, type ScheduleJobOptionsWithoutName, type ScheduleJobRecordOptions, type ScheduleJobsOptions, type ScheduleJobsResult, type StartWorkersConfig, type WorkerInstance, type WorkersInstance, createEventJob, createRecurrentJob, defineJob, getServiceJobs, jobsHistoryRepo, jobsRepo, scheduleJob, scheduleJobs, startWorkers };
353
+ export { type BaseJobDefinition, type CreateEventJobOptions, type CreateJobOptions, type CreateRecurrentJobCronOptions, type CreateRecurrentJobOptions, type CreateRecurrentJobRunEveryOptions, EventJob, type EventJobDefinition, type ExecutionContext, type HistoryRecord, HistoryRecordSchema, type JobDefinition, type JobDefinitionWithName, type JobRecord, JobRecordSchema, type JobRetryResult, type JobRetryResultBase, type JobRetryResultRunAt, type JobRetryResultRunIn, JobStatusEnum, type JobToRun, Jobs, type JobsDefinition, type LogLevels, RecurrentJob, type RecurrentJobDefinition, type ScheduleJobOptions, type ScheduleJobOptionsBase, type ScheduleJobOptionsRunAt, type ScheduleJobOptionsRunIn, type ScheduleJobOptionsWithoutName, type ScheduleJobRecordOptions, type ScheduleJobsOptions, type ScheduleJobsResult, type StartWorkersConfig, type WorkerInstance, type WorkersInstance, createEventJob, createRecurrentJob, defineJob, getServiceJobs, jobsHistoryRepo, jobsRepo, scheduleJob, scheduleJobs, startWorkers };
package/dist/index.js CHANGED
@@ -124,10 +124,12 @@ var JobsRepo = class {
124
124
  {
125
125
  jobName: { $in: jobNames },
126
126
  nextRunAt: { $lte: /* @__PURE__ */ new Date() },
127
- $or: [{ lockedUntil: { $exists: false } }, { lockedUntil: { $lte: /* @__PURE__ */ new Date() } }],
128
- // Exclude jobs that have reached max tries. Using $ne handles backwards compatibility
129
- // since records without the status field will still match (undefined !== 'maxTriesReached')
130
- status: { $ne: "maxTriesReached" }
127
+ $and: [
128
+ { $or: [{ lockedUntil: { $exists: false } }, { lockedUntil: { $lte: /* @__PURE__ */ new Date() } }] },
129
+ // Exclude event jobs that have reached max tries. Recurrent jobs keep running even
130
+ // if old records still have this status from previous versions.
131
+ { $or: [{ type: { $ne: "event" } }, { status: { $ne: "maxTriesReached" } }] }
132
+ ]
131
133
  },
132
134
  {
133
135
  $set: { lockedUntil, lastRunAt: /* @__PURE__ */ new Date() },
@@ -180,12 +182,12 @@ var JobsRepo = class {
180
182
  await this.jobs.deleteOne({ _id: jobId, type: "event" });
181
183
  }
182
184
  /**
183
- * Marks a job as having reached its maximum tries limit.
185
+ * Marks an event job as having reached its maximum tries limit.
184
186
  * The job will remain in the database but won't be picked up for execution.
185
187
  */
186
188
  async markJobAsMaxTriesReached(jobId) {
187
189
  await this.jobs.updateOne(
188
- { _id: jobId },
190
+ { _id: jobId, type: "event" },
189
191
  {
190
192
  $set: { status: "maxTriesReached" },
191
193
  $unset: { lockedUntil: "" }
@@ -231,6 +233,9 @@ var JobsRepo = class {
231
233
  type: job.type,
232
234
  priority: job.priority
233
235
  },
236
+ $unset: {
237
+ status: ""
238
+ },
234
239
  $setOnInsert: {
235
240
  nextRunAt: /* @__PURE__ */ new Date()
236
241
  }
@@ -310,6 +315,7 @@ JobsRepo = __decorateElement(_init, 0, "JobsRepo", _JobsRepo_decorators, JobsRep
310
315
  __runInitializers(_init, 1, JobsRepo);
311
316
 
312
317
  // src/services/getNextRunDate.ts
318
+ import { CronExpressionParser } from "cron-parser";
313
319
  var getNextRunDate = (options) => {
314
320
  if (options.runIn) {
315
321
  return new Date(Date.now() + options.runIn);
@@ -317,6 +323,15 @@ var getNextRunDate = (options) => {
317
323
  if (options.runEvery) {
318
324
  return new Date(Date.now() + options.runEvery);
319
325
  }
326
+ if (options.cron) {
327
+ if (!options.timezone) {
328
+ throw new Error("Cron recurrent jobs require a timezone");
329
+ }
330
+ return CronExpressionParser.parse(options.cron, {
331
+ currentDate: options.currentDate ?? /* @__PURE__ */ new Date(),
332
+ tz: options.timezone
333
+ }).next().toDate();
334
+ }
320
335
  if (options.runAt) {
321
336
  return options.runAt;
322
337
  }
@@ -543,7 +558,7 @@ var Executor = class {
543
558
  return job;
544
559
  }
545
560
  /**
546
- * Determines the effective max tries for a job.
561
+ * Determines the effective max tries for an event job.
547
562
  * Job-specific maxTries takes precedence over the global maxTries from config.
548
563
  */
549
564
  getEffectiveMaxTries(job, globalMaxTries) {
@@ -551,7 +566,7 @@ var Executor = class {
551
566
  }
552
567
  /**
553
568
  * Handles when a job has reached its maximum retry attempts.
554
- * Marks the job in the database and invokes the onMaxTriesReached callback.
569
+ * Marks the job in the database and invokes the onMaxTriesReached callback when provided.
555
570
  */
556
571
  async handleMaxTriesReached(jobToRun, onMaxTriesReached) {
557
572
  const jobLogger = logger3.addMetadata({
@@ -562,6 +577,7 @@ var Executor = class {
562
577
  `Job "${jobToRun.name}" has exceeded max tries (${jobToRun.tries}). Marking as maxTriesReached.`
563
578
  );
564
579
  await this.jobsRepo.markJobAsMaxTriesReached(jobToRun.jobId);
580
+ if (!onMaxTriesReached) return;
565
581
  try {
566
582
  await onMaxTriesReached(jobToRun);
567
583
  } catch (callbackError) {
@@ -570,7 +586,7 @@ var Executor = class {
570
586
  });
571
587
  }
572
588
  }
573
- async onError(error, job, jobToRun, context, config) {
589
+ async onError(error, job, jobToRun, context) {
574
590
  const scheduleRecurrent = async () => {
575
591
  if (job.type === "recurrent") {
576
592
  await this.jobsRepo.scheduleNextRun({
@@ -651,10 +667,12 @@ var Executor = class {
651
667
  async executeJob(config, jobToRun, respawnWorker) {
652
668
  const job = this.getJobDefinition(jobToRun, config.jobs);
653
669
  if (!job) return;
654
- const effectiveMaxTries = this.getEffectiveMaxTries(job, config.maxTries);
655
- if (jobToRun.tries > effectiveMaxTries) {
656
- await this.handleMaxTriesReached(jobToRun, config.onMaxTriesReached);
657
- return;
670
+ if (job.type === "event") {
671
+ const effectiveMaxTries = this.getEffectiveMaxTries(job, config.maxTries);
672
+ if (typeof effectiveMaxTries === "number" && jobToRun.tries > effectiveMaxTries) {
673
+ await this.handleMaxTriesReached(jobToRun, config.onMaxTriesReached);
674
+ return;
675
+ }
658
676
  }
659
677
  const effectiveLockTime = this.getEffectiveLockTime(job, jobToRun);
660
678
  if (effectiveLockTime !== jobToRun.lockTime) {
@@ -723,7 +741,7 @@ var Executor = class {
723
741
  }).catch((saveError) => {
724
742
  context.logger.error("Error saving failed execution history", { error: saveError });
725
743
  });
726
- await this.onError(error, job, jobToRun, context, config);
744
+ await this.onError(error, job, jobToRun, context);
727
745
  }
728
746
  });
729
747
  } catch (error) {
@@ -910,7 +928,7 @@ var WorkerService = class {
910
928
  }
911
929
  /**
912
930
  * Starts the job workers with the provided configuration.
913
- * @param userConfig - Configuration for the workers. Required fields: jobs, maxTries, onMaxTriesReached
931
+ * @param userConfig - Configuration for the workers. Required field: jobs
914
932
  */
915
933
  startWorkers(userConfig) {
916
934
  const config = {
@@ -943,6 +961,7 @@ import { getInstance, Service as Service4 } from "@orion-js/services";
943
961
 
944
962
  // src/defineJob/index.ts
945
963
  import { cleanAndValidate } from "@orion-js/schema";
964
+ import { CronExpressionParser as CronExpressionParser2 } from "cron-parser";
946
965
  import parse from "parse-duration";
947
966
  function createEventJob(options) {
948
967
  const jobDefinition = {
@@ -981,11 +1000,22 @@ function createEventJob(options) {
981
1000
  return jobDefinition;
982
1001
  }
983
1002
  function createRecurrentJob(options) {
1003
+ const recurrentOptions = {
1004
+ ...options
1005
+ };
1006
+ delete recurrentOptions.maxTries;
1007
+ if ("cron" in recurrentOptions && recurrentOptions.cron && !recurrentOptions.timezone) {
1008
+ throw new Error("Cron recurrent jobs require a timezone");
1009
+ }
1010
+ if ("cron" in recurrentOptions && recurrentOptions.cron) {
1011
+ CronExpressionParser2.parse(recurrentOptions.cron, { tz: recurrentOptions.timezone }).next();
1012
+ }
1013
+ const runEvery = "runEvery" in recurrentOptions ? typeof recurrentOptions.runEvery === "string" ? parse(recurrentOptions.runEvery) : recurrentOptions.runEvery : void 0;
984
1014
  const jobDefinition = {
985
- ...options,
986
- priority: options.priority ?? 100,
1015
+ ...recurrentOptions,
1016
+ priority: recurrentOptions.priority ?? 100,
987
1017
  type: "recurrent",
988
- runEvery: typeof options.runEvery === "string" ? parse(options.runEvery) : options.runEvery
1018
+ runEvery
989
1019
  };
990
1020
  return jobDefinition;
991
1021
  }