@orion-js/dogs 4.1.10 → 4.1.12
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.cjs +23 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +18 -6
- package/dist/index.d.ts +18 -6
- package/dist/index.js +23 -4
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
package/dist/index.cjs
CHANGED
|
@@ -214,7 +214,14 @@ var JobsRepo = class {
|
|
|
214
214
|
await this.jobs.deleteOne({ _id: jobId, type: "event" });
|
|
215
215
|
}
|
|
216
216
|
async extendLockTime(jobId, extraTime) {
|
|
217
|
-
|
|
217
|
+
await this.updateLockTime(jobId, extraTime);
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Updates the lock time for a job to the specified duration from now.
|
|
221
|
+
* Can be used to both extend or shorten the lock time.
|
|
222
|
+
*/
|
|
223
|
+
async updateLockTime(jobId, lockDuration) {
|
|
224
|
+
const lockedUntil = new Date(Date.now() + lockDuration);
|
|
218
225
|
await this.jobs.updateOne(
|
|
219
226
|
{
|
|
220
227
|
_id: jobId
|
|
@@ -532,8 +539,16 @@ var Executor = class {
|
|
|
532
539
|
__publicField(this, "jobsRepo", __runInitializers(_init4, 8, this)), __runInitializers(_init4, 11, this);
|
|
533
540
|
__publicField(this, "jobsHistoryRepo", __runInitializers(_init4, 12, this)), __runInitializers(_init4, 15, this);
|
|
534
541
|
}
|
|
542
|
+
/**
|
|
543
|
+
* Determines the effective lock time for a job execution.
|
|
544
|
+
* Job-specific lockTime takes precedence over the default lockTime from config.
|
|
545
|
+
*/
|
|
546
|
+
getEffectiveLockTime(job, jobToRun) {
|
|
547
|
+
return job.lockTime ?? jobToRun.lockTime;
|
|
548
|
+
}
|
|
535
549
|
getContext(job, jobToRun, onStale) {
|
|
536
|
-
|
|
550
|
+
const effectiveLockTime = this.getEffectiveLockTime(job, jobToRun);
|
|
551
|
+
let staleTimeout = setTimeout(() => onStale(), effectiveLockTime);
|
|
537
552
|
return {
|
|
538
553
|
definition: job,
|
|
539
554
|
record: jobToRun,
|
|
@@ -634,6 +649,10 @@ var Executor = class {
|
|
|
634
649
|
async executeJob(jobs, jobToRun, respawnWorker) {
|
|
635
650
|
const job = this.getJobDefinition(jobToRun, jobs);
|
|
636
651
|
if (!job) return;
|
|
652
|
+
const effectiveLockTime = this.getEffectiveLockTime(job, jobToRun);
|
|
653
|
+
if (effectiveLockTime !== jobToRun.lockTime) {
|
|
654
|
+
await this.jobsRepo.updateLockTime(jobToRun.jobId, effectiveLockTime);
|
|
655
|
+
}
|
|
637
656
|
const tracer = import_api.trace.getTracer("orionjs.dogs", "1.0");
|
|
638
657
|
await tracer.startActiveSpan(`job.${jobToRun.name}.${jobToRun.executionId}`, async (span) => {
|
|
639
658
|
try {
|
|
@@ -735,7 +754,7 @@ var WorkerService = class {
|
|
|
735
754
|
import_logger4.logger.debug(
|
|
736
755
|
`Running worker loop [w${workerInstance.workerIndex}] for jobs "${names.join(", ")}"...`
|
|
737
756
|
);
|
|
738
|
-
const jobToRun = await this.jobsRepo.getJobAndLock(names, config.
|
|
757
|
+
const jobToRun = await this.jobsRepo.getJobAndLock(names, config.defaultLockTime);
|
|
739
758
|
if (!jobToRun) {
|
|
740
759
|
import_logger4.logger.debug("No job to run");
|
|
741
760
|
return false;
|
|
@@ -817,7 +836,7 @@ var WorkerService = class {
|
|
|
817
836
|
cooldownPeriod: 100,
|
|
818
837
|
pollInterval: 3e3,
|
|
819
838
|
workersCount: 4,
|
|
820
|
-
|
|
839
|
+
defaultLockTime: 30 * 1e3
|
|
821
840
|
};
|
|
822
841
|
const config = {
|
|
823
842
|
...defaultConfig,
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/services/EventsService.ts","../src/repos/JobsRepo.ts","../src/types/JobRecord.ts","../src/services/getNextRunDate.ts","../src/services/WorkerService.ts","../../../node_modules/.pnpm/rambdax@11.3.1/node_modules/rambdax/src/_internals/isInteger.js","../../../node_modules/.pnpm/rambdax@11.3.1/node_modules/rambdax/src/_internals/createPath.js","../../../node_modules/.pnpm/rambdax@11.3.1/node_modules/rambdax/src/_internals/compare.js","../../../node_modules/.pnpm/rambdax@11.3.1/node_modules/rambdax/src/_internals/includes.js","../../../node_modules/.pnpm/rambdax@11.3.1/node_modules/rambdax/src/omit.js","../../../node_modules/.pnpm/rambdax@11.3.1/node_modules/rambdax/src/range.js","../src/services/Executor.ts","../src/repos/JobsHistoryRepo.ts","../src/types/HistoryRecord.ts","../src/service/index.ts","../src/defineJob/index.ts"],"sourcesContent":["import {getInstance} from '@orion-js/services'\nimport {EventsService} from './services/EventsService'\nimport {WorkerService} from './services/WorkerService'\nimport {StartWorkersConfig} from './types/StartConfig'\nimport {ScheduleJobOptions, ScheduleJobsOptions, ScheduleJobsResult} from './types/Events'\nimport {JobsHistoryRepo} from './repos/JobsHistoryRepo'\nimport {JobsRepo} from './repos/JobsRepo'\nimport {SchemaInAnyOrionForm} from '@orion-js/schema'\n\nexport * from './types'\nexport * from './service'\nexport * from './defineJob'\n\nconst workerService = getInstance(WorkerService)\nconst eventsService = getInstance(EventsService)\nconst jobsHistoryRepo = getInstance(JobsHistoryRepo)\nconst jobsRepo = getInstance(JobsRepo)\n\nconst startWorkers = (config: Partial<StartWorkersConfig>) => {\n return workerService.startWorkers(config)\n}\n\n/**\n * @deprecated Use the event job definition.schedule method instead.\n */\nconst scheduleJob = <TParamsSchema extends SchemaInAnyOrionForm = any>(\n options: ScheduleJobOptions<TParamsSchema>,\n) => {\n return eventsService.scheduleJob(options)\n}\n\n/**\n * Schedule multiple jobs at once for better performance.\n * @deprecated Use the event job definition.scheduleJobs method instead.\n */\nconst scheduleJobs = <TParamsSchema extends SchemaInAnyOrionForm = any>(\n jobs: ScheduleJobsOptions<TParamsSchema>,\n): Promise<ScheduleJobsResult> => {\n return eventsService.scheduleJobs(jobs)\n}\n\nexport {startWorkers, scheduleJob, scheduleJobs, jobsHistoryRepo, jobsRepo}\n","import {logger} from '@orion-js/logger'\nimport {Inject, Service} from '@orion-js/services'\nimport {JobsRepo} from '../repos/JobsRepo'\nimport {ScheduleJobOptions, ScheduleJobsOptions, ScheduleJobsResult} from '../types/Events'\nimport {getNextRunDate} from './getNextRunDate'\n\n@Service()\nexport class EventsService {\n @Inject(() => JobsRepo)\n private jobsRepo: JobsRepo\n\n async scheduleJob(options: ScheduleJobOptions) {\n logger.debug('Scheduling job...', options)\n\n await this.jobsRepo.scheduleJob({\n name: options.name,\n priority: options.priority || 100,\n nextRunAt: getNextRunDate(options),\n params: options.params || null,\n uniqueIdentifier: options.uniqueIdentifier,\n })\n }\n\n async scheduleJobs(jobs: ScheduleJobsOptions): Promise<ScheduleJobsResult> {\n logger.debug(`Scheduling ${jobs.length} jobs...`)\n\n const jobRecords = jobs.map(options => ({\n name: options.name,\n priority: options.priority || 100,\n nextRunAt: getNextRunDate(options),\n params: options.params || null,\n uniqueIdentifier: options.uniqueIdentifier,\n }))\n\n return await this.jobsRepo.scheduleJobs(jobRecords)\n }\n}\n","import {generateId} from '@orion-js/helpers'\nimport {logger} from '@orion-js/logger'\nimport {Collection, MongoDB, MongoCollection} from '@orion-js/mongodb'\nimport {ScheduleJobRecordOptions, ScheduleJobsResult} from '../types/Events'\nimport {JobRecord} from '../types/JobRecord'\nimport {JobDefinitionWithName, RecurrentJobDefinition} from '../types/JobsDefinition'\nimport {JobToRun} from '../types/Worker'\nimport {Repository} from '@orion-js/mongodb'\nimport {JobRecordSchema} from '../types/JobRecord'\n\n@Repository()\nexport class JobsRepo {\n @MongoCollection({\n idGeneration: 'uuid',\n name: 'orionjs.jobs_dogs_records',\n schema: JobRecordSchema,\n indexes: [\n {\n keys: {\n jobName: 1,\n priority: -1,\n nextRunAt: 1,\n },\n },\n {\n keys: {\n jobName: 1,\n },\n options: {\n unique: true,\n partialFilterExpression: {type: 'recurrent'},\n },\n },\n {\n keys: {\n uniqueIdentifier: 1,\n },\n options: {\n unique: true,\n sparse: true,\n },\n },\n ],\n })\n jobs: Collection<JobRecord>\n\n async getJobAndLock(jobNames: string[], lockTime: number): Promise<JobToRun> {\n const lockedUntil = new Date(Date.now() + lockTime)\n\n const job = await this.jobs.findOneAndUpdate(\n {\n jobName: {$in: jobNames},\n nextRunAt: {$lte: new Date()},\n $or: [{lockedUntil: {$exists: false}}, {lockedUntil: {$lte: new Date()}}],\n },\n {\n $set: {lockedUntil, lastRunAt: new Date()},\n },\n {\n mongoOptions: {\n sort: {\n priority: -1,\n nextRunAt: 1,\n },\n returnDocument: 'before',\n },\n },\n )\n\n if (!job) return\n\n let tries = job.tries || 1\n\n if (job.lockedUntil) {\n logger.info(`Running job \"${job.jobName}\" that was staled`)\n this.jobs.updateOne(job._id, {$inc: {tries: 1}})\n tries++\n }\n\n return {\n jobId: job._id,\n executionId: generateId(),\n name: job.jobName,\n params: job.params,\n type: job.type,\n tries,\n lockTime,\n priority: job.priority,\n uniqueIdentifier: job.uniqueIdentifier,\n }\n }\n\n async setJobRecordPriority(jobId: string, priority: number) {\n await this.jobs.updateOne(jobId, {$set: {priority}})\n }\n\n async scheduleNextRun(options: {\n jobId: string\n nextRunAt: Date\n addTries: boolean\n priority: number\n }) {\n const updator: MongoDB.UpdateFilter<JobRecord> = {\n $set: {\n nextRunAt: options.nextRunAt,\n priority: options.priority,\n ...(options.addTries ? {} : {tries: 0}),\n },\n $unset: {lockedUntil: ''},\n ...(options.addTries ? {$inc: {tries: 1}} : {}),\n }\n\n await this.jobs.updateOne(options.jobId, updator)\n }\n\n async deleteEventJob(jobId: string) {\n await this.jobs.deleteOne({_id: jobId, type: 'event'})\n }\n\n async extendLockTime(jobId: string, extraTime: number) {\n const lockedUntil = new Date(Date.now() + extraTime)\n await this.jobs.updateOne(\n {\n _id: jobId,\n },\n {\n $set: {lockedUntil},\n },\n )\n }\n\n async unlockAllJobs(): Promise<number> {\n const result = await this.jobs.updateMany(\n {\n lockedUntil: {$exists: true},\n },\n {\n $unset: {lockedUntil: ''},\n },\n )\n\n return result.modifiedCount\n }\n\n async ensureJobRecord(job: JobDefinitionWithName) {\n const result = await this.jobs.upsert(\n {\n jobName: job.name,\n },\n {\n $set: {\n type: job.type,\n priority: (job as RecurrentJobDefinition).priority,\n },\n $setOnInsert: {\n nextRunAt: new Date(),\n },\n },\n )\n\n if (result.upsertedId) {\n logger.debug(`Created job record for \"${job.name}\"`)\n } else {\n logger.debug(`Record for job \"${job.name}\" already exists`)\n }\n }\n\n async scheduleJob(options: ScheduleJobRecordOptions) {\n try {\n await this.jobs.insertOne({\n jobName: options.name,\n uniqueIdentifier: options.uniqueIdentifier,\n params: options.params,\n nextRunAt: options.nextRunAt,\n priority: options.priority,\n type: 'event',\n })\n } catch (error) {\n if (\n error.isValidationError &&\n Object.values(error.validationErrors).includes('notUnique') &&\n options.uniqueIdentifier\n ) {\n logger.info(\n `Job \"${options.name}\" with identifier \"${options.uniqueIdentifier}\" already exists`,\n )\n } else {\n throw error\n }\n }\n }\n\n async scheduleJobs(jobs: ScheduleJobRecordOptions[]): Promise<ScheduleJobsResult> {\n if (jobs.length === 0) {\n return {scheduledCount: 0, skippedCount: 0, errors: []}\n }\n\n // Process each job individually to handle errors properly\n let scheduledCount = 0\n let skippedCount = 0\n const errors: Array<{index: number; error: Error; job: ScheduleJobRecordOptions}> = []\n\n for (let i = 0; i < jobs.length; i++) {\n const job = jobs[i]\n try {\n // Insert directly to get better error handling than the single scheduleJob method\n await this.jobs.insertOne({\n jobName: job.name,\n uniqueIdentifier: job.uniqueIdentifier,\n params: job.params,\n nextRunAt: job.nextRunAt,\n priority: job.priority,\n type: 'event',\n })\n scheduledCount++\n } catch (error) {\n // Check if it's a validation error with uniqueIdentifier constraint\n if (\n error.isValidationError &&\n Object.values(error.validationErrors).includes('notUnique') &&\n job.uniqueIdentifier\n ) {\n logger.info(`Job \"${job.name}\" with identifier \"${job.uniqueIdentifier}\" already exists`)\n skippedCount++\n } else {\n errors.push({\n index: i,\n error: error instanceof Error ? error : new Error(String(error)),\n job,\n })\n }\n }\n }\n\n logger.debug(\n `Scheduled ${scheduledCount} jobs successfully, skipped ${skippedCount}, errors: ${errors.length}`,\n )\n\n return {\n scheduledCount,\n skippedCount,\n errors,\n }\n }\n}\n","import {createEnum, InferSchemaType, schemaWithName} from '@orion-js/schema'\n\nexport const JobRecordSchema = schemaWithName('JobRecord', {\n _id: {type: 'string'},\n jobName: {type: 'string'},\n type: {type: createEnum('JobType', ['recurrent', 'event'])},\n priority: {type: 'number'},\n uniqueIdentifier: {type: 'string', optional: true},\n nextRunAt: {type: 'date'},\n lastRunAt: {type: 'date', optional: true},\n lockedUntil: {type: 'date', optional: true},\n tries: {type: 'number', optional: true},\n params: {type: 'blackbox', optional: true},\n})\n\nexport type JobRecord = InferSchemaType<typeof JobRecordSchema>\n","export type Options = {\n getNextRun?: () => Date\n runIn?: number\n runEvery?: number\n runAt?: Date\n} & {[key: string]: any}\n\nexport const getNextRunDate = (options: Options) => {\n if (options.runIn) {\n return new Date(Date.now() + options.runIn)\n }\n\n if (options.runEvery) {\n return new Date(Date.now() + options.runEvery)\n }\n\n if (options.runAt) {\n return options.runAt\n }\n\n if (options.getNextRun) {\n return options.getNextRun()\n }\n\n return new Date()\n}\n","import {Inject, Service} from '@orion-js/services'\nimport {range} from 'rambdax'\nimport {JobsRepo} from '../repos/JobsRepo'\nimport {JobDefinitionWithName, JobsDefinition} from '../types/JobsDefinition'\nimport {StartWorkersConfig} from '../types/StartConfig'\nimport {sleep} from '@orion-js/helpers'\nimport {Executor} from './Executor'\nimport {WorkerInstance, WorkersInstance} from '../types/Worker'\nimport {logger} from '@orion-js/logger'\n\n@Service()\nexport class WorkerService {\n @Inject(() => JobsRepo)\n private jobsRepo: JobsRepo\n\n @Inject(() => Executor)\n private executor: Executor\n\n getJobNames(jobs: JobsDefinition) {\n return Object.keys(jobs)\n }\n\n getJobs(jobs: JobsDefinition): JobDefinitionWithName[] {\n return Object.keys(jobs).map(name => {\n return {\n name,\n ...jobs[name],\n }\n })\n }\n\n async runWorkerLoop(config: StartWorkersConfig, workerInstance: WorkerInstance) {\n const names = this.getJobNames(config.jobs)\n logger.debug(\n `Running worker loop [w${workerInstance.workerIndex}] for jobs \"${names.join(', ')}\"...`,\n )\n const jobToRun = await this.jobsRepo.getJobAndLock(names, config.lockTime)\n if (!jobToRun) {\n logger.debug('No job to run')\n return false\n }\n\n logger.debug(`Got job [w${workerInstance.workerIndex}] to run:`, jobToRun)\n await this.executor.executeJob(config.jobs, jobToRun, workerInstance.respawn)\n\n return true\n }\n\n async startWorker(config: StartWorkersConfig, workerInstance: WorkerInstance) {\n while (true) {\n if (!workerInstance.running) {\n logger.info(`Got signal to stop. Stopping worker [w${workerInstance.workerIndex}]...`)\n return\n }\n\n try {\n const didRun = await this.runWorkerLoop(config, workerInstance)\n if (!didRun) await sleep(config.pollInterval)\n if (didRun) await sleep(config.cooldownPeriod)\n } catch (error) {\n logger.error('Error in job runner.', {error})\n await sleep(config.pollInterval)\n }\n }\n }\n\n createWorkersInstanceDefinition(config: StartWorkersConfig): WorkersInstance {\n const workersInstance: WorkersInstance = {\n running: true,\n workersCount: config.workersCount,\n workers: [],\n stop: async () => {\n logger.info('Stopping workers...')\n workersInstance.running = false\n const stopingPromises = workersInstance.workers.map(worker => worker.stop())\n await Promise.all(stopingPromises)\n },\n }\n\n return workersInstance\n }\n\n async ensureRecords(config: StartWorkersConfig) {\n const jobs = this.getJobs(config.jobs)\n\n await Promise.all(\n jobs\n .filter(job => job.type === 'recurrent')\n .map(async job => {\n logger.debug(`Ensuring records for job \"${job.name}\"...`)\n await this.jobsRepo.ensureJobRecord(job)\n }),\n )\n }\n\n async startANewWorker(config: StartWorkersConfig, workersInstance: WorkersInstance) {\n const workerIndex = workersInstance.workers.length\n\n logger.info(`Starting worker [w${workerIndex}]`)\n\n const workerInstance: WorkerInstance = {\n running: true,\n workerIndex,\n stop: async () => {\n logger.info(`Stopping worker [w${workerIndex}]...`)\n workerInstance.running = false\n await workerInstance.promise\n },\n respawn: async () => {\n logger.info(`Respawning worker [w${workerIndex}]...`)\n workerInstance.stop()\n await this.startANewWorker(config, workersInstance)\n },\n }\n\n const workerPromise = this.startWorker(config, workerInstance)\n\n workerInstance.promise = workerPromise\n workersInstance.workers.push(workerInstance)\n }\n\n async runWorkers(config: StartWorkersConfig, workersInstance: WorkersInstance) {\n logger.debug('Will ensure records for recurrent jobs')\n await this.ensureRecords(config)\n\n for (const _ of range(0, config.workersCount)) {\n this.startANewWorker(config, workersInstance)\n }\n }\n\n startWorkers(userConfig: Partial<StartWorkersConfig>): WorkersInstance {\n const defaultConfig: StartWorkersConfig = {\n jobs: {},\n cooldownPeriod: 100,\n pollInterval: 3000,\n workersCount: 4,\n lockTime: 30 * 1000,\n }\n\n const config = {\n ...defaultConfig,\n ...userConfig,\n }\n\n setNameToJobs(config.jobs)\n\n const workersInstance = this.createWorkersInstanceDefinition(config)\n logger.debug('Starting workers', config)\n\n this.runWorkers(config, workersInstance)\n\n return workersInstance\n }\n}\n\nfunction setNameToJobs(jobs: JobsDefinition) {\n return Object.keys(jobs).map(name => {\n jobs[name].jobName = name\n })\n}\n","function _isInteger(n){\n return n << 0 === n\n}\n\nexport const isInteger = Number.isInteger || _isInteger\n\n/**\n * Check if `index` is integer even if it is a string.\n */\nexport const isIndexInteger = index => Number.isInteger(Number(index))\n","import { isInteger } from './isInteger.js'\n\nexport function createPath(path, delimiter = '.'){\n return typeof path === 'string' ?\n path.split(delimiter).map(x => isInteger(x) ? Number(x) : x) :\n path\n}\n","export function compare(a, b){\n return String(a) === String(b)\n}\n","import { compare } from './compare.js'\n\nexport function includes(a, list){\n let index = -1\n const { length } = list\n\n while (++index < length)\n if (compare(list[ index ], a))\n return true\n\n return false\n}\n","import { createPath } from './_internals/createPath.js'\nimport { includes } from './_internals/includes.js'\n\nexport function omit(propsToOmit, obj){\n if (arguments.length === 1) return _obj => omit(propsToOmit, _obj)\n\n if (obj === null || obj === undefined)\n return undefined\n\n const propsToOmitValue = createPath(propsToOmit, ',')\n const willReturn = {}\n\n for (const key in obj)\n if (!includes(key, propsToOmitValue))\n willReturn[ key ] = obj[ key ]\n\n return willReturn\n}\n","export function range(start, end){\n if (arguments.length === 1) return _end => range(start, _end)\n\n if (Number.isNaN(Number(start)) || Number.isNaN(Number(end))){\n throw new TypeError('Both arguments to range must be numbers')\n }\n\n if (end < start) return []\n\n const len = end - start\n const willReturn = Array(len)\n\n for (let i = 0; i < len; i++){\n willReturn[ i ] = start + i\n }\n\n return willReturn\n}\n","import {logger, runWithOrionAsyncContext, updateOrionAsyncContext} from '@orion-js/logger'\nimport {Inject, Service} from '@orion-js/services'\nimport {JobsHistoryRepo} from '../repos/JobsHistoryRepo'\nimport {JobsRepo} from '../repos/JobsRepo'\nimport {JobDefinition, JobsDefinition} from '../types/JobsDefinition'\nimport {ExecutionContext, JobToRun} from '../types/Worker'\nimport {getNextRunDate} from './getNextRunDate'\nimport {trace, SpanStatusCode} from '@opentelemetry/api'\nimport {Blackbox} from '@orion-js/schema'\n\n@Service()\nexport class Executor {\n @Inject(() => JobsRepo)\n private readonly jobsRepo: JobsRepo\n\n @Inject(() => JobsHistoryRepo)\n private readonly jobsHistoryRepo: JobsHistoryRepo\n\n getContext(job: JobDefinition, jobToRun: JobToRun, onStale: Function): ExecutionContext {\n let staleTimeout = setTimeout(() => onStale(), jobToRun.lockTime)\n return {\n definition: job,\n record: jobToRun,\n tries: jobToRun.tries || 0,\n clearStaleTimeout: () => clearTimeout(staleTimeout),\n extendLockTime: async (extraTime: number) => {\n clearTimeout(staleTimeout)\n staleTimeout = setTimeout(() => onStale(), extraTime)\n await this.jobsRepo.extendLockTime(jobToRun.jobId, extraTime)\n },\n logger: logger.addMetadata({\n jobName: jobToRun.name,\n jobId: jobToRun.jobId,\n }),\n }\n }\n\n getJobDefinition(jobToRun: JobToRun, jobs: JobsDefinition) {\n const job = jobs[jobToRun.name]\n\n if (jobToRun.type !== job.type) {\n logger.warn(\n `Job record \"${jobToRun.name}\" is \"${jobToRun.type}\" but definition is \"${job.type}\"`,\n )\n return\n }\n\n return job\n }\n\n async onError(error: any, job: JobDefinition, jobToRun: JobToRun, context: ExecutionContext) {\n const scheduleRecurrent = async () => {\n if (job.type === 'recurrent') {\n await this.jobsRepo.scheduleNextRun({\n jobId: jobToRun.jobId,\n nextRunAt: getNextRunDate(job),\n addTries: false,\n priority: job.priority,\n })\n }\n }\n\n if (!job.onError) {\n context.logger.error(`Error executing job \"${jobToRun.name}\"`, {error})\n await scheduleRecurrent()\n return\n }\n context.logger.info(`Error executing job \"${jobToRun.name}\"`, {error})\n\n const result = await job.onError(error, jobToRun.params, context)\n\n if (result.action === 'dismiss') {\n await scheduleRecurrent()\n return\n }\n\n if (result.action === 'retry') {\n await this.jobsRepo.scheduleNextRun({\n jobId: jobToRun.jobId,\n nextRunAt: getNextRunDate(result),\n addTries: true,\n priority: job.type === 'recurrent' ? job.priority : jobToRun.priority,\n })\n }\n }\n\n async saveExecution(options: {\n startedAt: Date\n status: 'stale' | 'error' | 'success'\n errorMessage?: string\n result?: Blackbox\n job: JobDefinition\n jobToRun: JobToRun\n }) {\n const {startedAt, status, errorMessage, result, job, jobToRun} = options\n const endedAt = new Date()\n\n if (job.saveExecutionsFor !== 0) {\n const oneWeek = 1000 * 60 * 60 * 24 * 7\n const saveExecutionsFor = job.saveExecutionsFor || oneWeek\n await this.jobsHistoryRepo.saveExecution({\n jobId: jobToRun.jobId,\n executionId: jobToRun.executionId,\n jobName: jobToRun.name,\n type: jobToRun.type,\n priority: jobToRun.priority,\n tries: jobToRun.tries,\n uniqueIdentifier: jobToRun.uniqueIdentifier,\n startedAt,\n endedAt,\n duration: endedAt.getTime() - startedAt.getTime(),\n expiresAt: new Date(Date.now() + saveExecutionsFor),\n status,\n errorMessage,\n params: jobToRun.params,\n result,\n })\n }\n }\n\n async afterExecutionSuccess(job: JobDefinition, jobToRun: JobToRun, context: ExecutionContext) {\n if (job.type === 'recurrent') {\n context.logger.debug(`Scheduling next run for recurrent job \"${jobToRun.name}\"`)\n await this.jobsRepo.scheduleNextRun({\n jobId: jobToRun.jobId,\n nextRunAt: getNextRunDate(job),\n addTries: false,\n priority: job.priority,\n })\n }\n if (job.type === 'event') {\n context.logger.debug(`Removing event job after success \"${jobToRun.name}\"`)\n await this.jobsRepo.deleteEventJob(jobToRun.jobId)\n }\n }\n\n async executeJob(jobs: JobsDefinition, jobToRun: JobToRun, respawnWorker: Function) {\n const job = this.getJobDefinition(jobToRun, jobs)\n if (!job) return\n\n const tracer = trace.getTracer('orionjs.dogs', '1.0')\n\n await tracer.startActiveSpan(`job.${jobToRun.name}.${jobToRun.executionId}`, async span => {\n try {\n const startedAt = new Date()\n\n const onStale = async () => {\n if (job.onStale) {\n context.logger.info(`Job \"${jobToRun.name}\" is stale`)\n job.onStale(jobToRun.params, context)\n } else {\n context.logger.error(`Job \"${jobToRun.name}\" is stale`)\n }\n\n await this.jobsRepo.setJobRecordPriority(jobToRun.jobId, 0)\n\n respawnWorker()\n\n this.saveExecution({\n startedAt,\n status: 'stale',\n result: null,\n errorMessage: null,\n job,\n jobToRun,\n })\n }\n\n const context = this.getContext(job, jobToRun, onStale)\n\n const extraContext = {\n controllerType: 'job' as const,\n jobName: jobToRun.name,\n params: jobToRun.params,\n }\n\n await runWithOrionAsyncContext(extraContext, async () => {\n try {\n // Inject async context update\n updateOrionAsyncContext({\n jobName: jobToRun.name,\n params: jobToRun.params,\n })\n const result = await job.resolve(jobToRun.params, context)\n context.clearStaleTimeout()\n\n this.saveExecution({\n startedAt,\n status: 'success',\n result: result || null,\n errorMessage: null,\n job,\n jobToRun,\n })\n\n await this.afterExecutionSuccess(job, jobToRun, context)\n } catch (error) {\n context.clearStaleTimeout()\n this.saveExecution({\n startedAt,\n status: 'error',\n result: null,\n errorMessage: (error as Error).message,\n job,\n jobToRun,\n })\n\n await this.onError(error, job, jobToRun, context)\n }\n })\n } catch (error) {\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: error.message,\n })\n throw error\n } finally {\n span.end()\n }\n })\n }\n}\n","import {Collection, MongoCollection, Repository, MongoDB} from '@orion-js/mongodb'\nimport {omit} from 'rambdax'\nimport {HistoryRecord, HistoryRecordSchema} from '../types/HistoryRecord'\n\n@Repository()\nexport class JobsHistoryRepo {\n @MongoCollection({\n name: 'orionjs.jobs_dogs_history',\n idGeneration: 'uuid',\n schema: HistoryRecordSchema,\n indexes: [\n {\n keys: {\n jobName: 1,\n startedAt: 1,\n },\n },\n {\n keys: {\n executionId: 1,\n },\n },\n {\n keys: {\n expiresAt: 1,\n },\n options: {\n expireAfterSeconds: 0,\n },\n },\n ],\n })\n history: Collection<HistoryRecord>\n\n async saveExecution(record: MongoDB.WithoutId<HistoryRecord>) {\n await this.history.upsert(\n {executionId: record.executionId},\n {\n $setOnInsert: {\n status: record.status,\n },\n $set: {\n ...omit(['status'], record),\n },\n },\n )\n }\n\n async getExecutions(jobName: string, limit?: number, skip?: number): Promise<HistoryRecord[]> {\n const cursor = this.history.find({jobName}).sort({startedAt: -1})\n\n if (skip) {\n cursor.skip(skip)\n }\n\n if (limit) {\n cursor.limit(limit)\n }\n\n return await cursor.toArray()\n }\n}\n","import {InferSchemaType, schemaWithName} from '@orion-js/schema'\n\nexport const HistoryRecordSchema = schemaWithName('HistoryRecord', {\n _id: {type: 'string'},\n jobId: {type: 'string'},\n executionId: {type: 'string'},\n jobName: {type: 'string'},\n type: {type: 'string'},\n priority: {type: 'number'},\n tries: {type: 'number'},\n uniqueIdentifier: {type: 'string', optional: true},\n startedAt: {type: 'date'},\n endedAt: {type: 'date'},\n duration: {type: 'number'},\n expiresAt: {type: 'date', optional: true},\n status: {type: 'string', enum: ['success', 'error', 'stale']},\n errorMessage: {type: 'string', optional: true},\n params: {type: 'blackbox', optional: true},\n result: {type: 'any', optional: true},\n})\n\nexport type HistoryRecord = InferSchemaType<typeof HistoryRecordSchema>\n","import {getInstance, Service} from '@orion-js/services'\nimport {createEventJob, defineJob} from '../defineJob'\nimport type {CreateEventJobOptions, JobDefinition, RecurrentJobDefinition} from '../types'\n\n// Define metadata storage using WeakMaps\nconst serviceMetadata = new WeakMap<any, {_serviceType: string}>()\nconst jobsMetadata = new Map<any, Record<string, any>>()\n\nexport function Jobs() {\n return (target: any, context: ClassDecoratorContext<any>) => {\n Service()(target, context)\n\n context.addInitializer(function (this) {\n serviceMetadata.set(this, {_serviceType: 'jobs'})\n })\n }\n}\n\nexport function RecurrentJob(): (\n method: any,\n context: ClassFieldDecoratorContext | ClassMethodDecoratorContext,\n) => any\nexport function RecurrentJob(\n options: Omit<RecurrentJobDefinition, 'resolve' | 'type'>,\n): (method: any, context: ClassMethodDecoratorContext) => any\nexport function RecurrentJob(options = {}) {\n return (method: any, context: ClassFieldDecoratorContext | ClassMethodDecoratorContext) => {\n const propertyKey = String(context.name)\n\n context.addInitializer(function (this) {\n const jobs = jobsMetadata.get(this) || {}\n\n if (context.kind === 'method') {\n jobs[propertyKey] = defineJob({\n ...options,\n type: 'recurrent',\n resolve: this[propertyKey].bind(this),\n })\n }\n\n if (context.kind === 'field') {\n jobs[propertyKey] = this[propertyKey]\n }\n\n jobsMetadata.set(this, jobs)\n })\n\n return method\n }\n}\n\nexport function EventJob(): (\n method: any,\n context: ClassFieldDecoratorContext | ClassMethodDecoratorContext,\n) => any\nexport function EventJob(\n options: Omit<CreateEventJobOptions<any>, 'resolve'>,\n): (method: any, context: ClassMethodDecoratorContext) => any\nexport function EventJob(options = {}) {\n return (method: any, context: ClassFieldDecoratorContext | ClassMethodDecoratorContext) => {\n const propertyKey = String(context.name)\n\n context.addInitializer(function (this) {\n const jobs = jobsMetadata.get(this) || {}\n\n if (context.kind === 'method') {\n jobs[propertyKey] = createEventJob({\n ...options,\n resolve: this[propertyKey].bind(this),\n })\n }\n\n if (context.kind === 'field') {\n jobs[propertyKey] = this[propertyKey]\n }\n\n jobsMetadata.set(this, jobs)\n })\n\n return method\n }\n}\n\nexport function getServiceJobs(target: any): {\n [key: string]: JobDefinition\n} {\n const instance = getInstance(target)\n\n if (!serviceMetadata.has(instance.constructor)) {\n throw new Error('You must pass a class decorated with @Jobs to getServiceJobs')\n }\n\n const instanceMetadata = serviceMetadata.get(instance.constructor)\n if (instanceMetadata._serviceType !== 'jobs') {\n throw new Error('You must pass a class decorated with @Jobs to getServiceJobs')\n }\n\n const jobsMap = jobsMetadata.get(instance) || {}\n\n return jobsMap\n}\n\n/**\n * Logs\n * after event job {\n job1: { type: 'event', resolve: [Function: bound job1] AsyncFunction }\n}\nbefore recurrent job Map(1) {\n ExampleJobsService {} => {\n job1: { type: 'event', resolve: [Function: bound job1] AsyncFunction }\n }\n}\nbefore recurrent job undefined\nafter recurrent job {\n job2: {\n runEvery: 1000,\n type: 'recurrent',\n resolve: [Function: bound job2] AsyncFunction,\n priority: 100\n }\n}\n{\n serviceJobs: {\n job2: {\n runEvery: 1000,\n type: 'recurrent',\n resolve: [Function: bound job2] AsyncFunction,\n priority: 100\n }\n }\n}\n */\n","import {\n CreateEventJobOptions,\n CreateJobOptions,\n CreateRecurrentJobOptions,\n EventJobDefinition,\n JobDefinition,\n RecurrentJobDefinition,\n} from '../types/JobsDefinition'\nimport {scheduleJob, ScheduleJobsResult, scheduleJobs} from '..'\nimport {ScheduleJobOptionsWithoutName} from '../types/Events'\nimport {cleanAndValidate, SchemaInAnyOrionForm} from '@orion-js/schema'\nimport parse from 'parse-duration'\n\nexport function createEventJob<TParamsSchema extends SchemaInAnyOrionForm>(\n options: CreateEventJobOptions<TParamsSchema>,\n): EventJobDefinition<TParamsSchema> {\n const jobDefinition: EventJobDefinition<TParamsSchema> = {\n ...options,\n type: 'event',\n schedule: null,\n scheduleJobs: null,\n }\n\n jobDefinition.schedule = async (scheduleOptions: ScheduleJobOptionsWithoutName<TParamsSchema>) => {\n if (!jobDefinition.jobName) {\n throw new Error('This job has not been registered in the workers')\n }\n\n const params = jobDefinition.params\n ? await cleanAndValidate(jobDefinition.params, scheduleOptions.params)\n : scheduleOptions.params\n\n return await scheduleJob({\n ...scheduleOptions,\n name: jobDefinition.jobName,\n params,\n })\n }\n\n jobDefinition.scheduleJobs = async (\n jobs: Array<ScheduleJobOptionsWithoutName<TParamsSchema>>,\n ): Promise<ScheduleJobsResult> => {\n if (!jobDefinition.jobName) {\n throw new Error('This job has not been registered in the workers')\n }\n\n // Process all job parameters if schema validation is needed\n const processedJobs = await Promise.all(\n jobs.map(async scheduleOptions => {\n const params = jobDefinition.params\n ? await cleanAndValidate(jobDefinition.params, scheduleOptions.params)\n : scheduleOptions.params\n\n return {\n ...scheduleOptions,\n name: jobDefinition.jobName,\n params,\n }\n }),\n )\n\n return await scheduleJobs(processedJobs)\n }\n\n return jobDefinition\n}\n\nexport function createRecurrentJob(options: CreateRecurrentJobOptions): RecurrentJobDefinition {\n const jobDefinition: RecurrentJobDefinition = {\n ...options,\n priority: options.priority ?? 100,\n type: 'recurrent',\n runEvery: typeof options.runEvery === 'string' ? parse(options.runEvery) : options.runEvery,\n }\n\n return jobDefinition\n}\n\n/**\n * @deprecated Use `createEventJob` or `createRecurrentJob` instead.\n */\nexport const defineJob = (\n options: CreateJobOptions & {type: 'event' | 'recurrent'},\n): JobDefinition => {\n return options.type === 'event'\n ? createEventJob(options as any)\n : createRecurrentJob(options as any)\n}\n"],"mappings":"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","names":["import_services","import_logger","import_mongodb","_init","import_services","import_helpers","import_logger","import_services","import_mongodb","import_schema","_init","_jobsRepo_dec","_init","import_logger","_jobsRepo_dec","_init","import_services","import_schema","parse"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/services/EventsService.ts","../src/repos/JobsRepo.ts","../src/types/JobRecord.ts","../src/services/getNextRunDate.ts","../src/services/WorkerService.ts","../../../node_modules/.pnpm/rambdax@11.3.1/node_modules/rambdax/src/_internals/isInteger.js","../../../node_modules/.pnpm/rambdax@11.3.1/node_modules/rambdax/src/_internals/createPath.js","../../../node_modules/.pnpm/rambdax@11.3.1/node_modules/rambdax/src/_internals/compare.js","../../../node_modules/.pnpm/rambdax@11.3.1/node_modules/rambdax/src/_internals/includes.js","../../../node_modules/.pnpm/rambdax@11.3.1/node_modules/rambdax/src/omit.js","../../../node_modules/.pnpm/rambdax@11.3.1/node_modules/rambdax/src/range.js","../src/services/Executor.ts","../src/repos/JobsHistoryRepo.ts","../src/types/HistoryRecord.ts","../src/service/index.ts","../src/defineJob/index.ts"],"sourcesContent":["import {getInstance} from '@orion-js/services'\nimport {EventsService} from './services/EventsService'\nimport {WorkerService} from './services/WorkerService'\nimport {StartWorkersConfig} from './types/StartConfig'\nimport {ScheduleJobOptions, ScheduleJobsOptions, ScheduleJobsResult} from './types/Events'\nimport {JobsHistoryRepo} from './repos/JobsHistoryRepo'\nimport {JobsRepo} from './repos/JobsRepo'\nimport {SchemaInAnyOrionForm} from '@orion-js/schema'\n\nexport * from './types'\nexport * from './service'\nexport * from './defineJob'\n\nconst workerService = getInstance(WorkerService)\nconst eventsService = getInstance(EventsService)\nconst jobsHistoryRepo = getInstance(JobsHistoryRepo)\nconst jobsRepo = getInstance(JobsRepo)\n\nconst startWorkers = (config: StartWorkersConfig) => {\n return workerService.startWorkers(config)\n}\n\n/**\n * @deprecated Use the event job definition.schedule method instead.\n */\nconst scheduleJob = <TParamsSchema extends SchemaInAnyOrionForm = any>(\n options: ScheduleJobOptions<TParamsSchema>,\n) => {\n return eventsService.scheduleJob(options)\n}\n\n/**\n * Schedule multiple jobs at once for better performance.\n * @deprecated Use the event job definition.scheduleJobs method instead.\n */\nconst scheduleJobs = <TParamsSchema extends SchemaInAnyOrionForm = any>(\n jobs: ScheduleJobsOptions<TParamsSchema>,\n): Promise<ScheduleJobsResult> => {\n return eventsService.scheduleJobs(jobs)\n}\n\nexport {startWorkers, scheduleJob, scheduleJobs, jobsHistoryRepo, jobsRepo}\n","import {logger} from '@orion-js/logger'\nimport {Inject, Service} from '@orion-js/services'\nimport {JobsRepo} from '../repos/JobsRepo'\nimport {ScheduleJobOptions, ScheduleJobsOptions, ScheduleJobsResult} from '../types/Events'\nimport {getNextRunDate} from './getNextRunDate'\n\n@Service()\nexport class EventsService {\n @Inject(() => JobsRepo)\n private jobsRepo: JobsRepo\n\n async scheduleJob(options: ScheduleJobOptions) {\n logger.debug('Scheduling job...', options)\n\n await this.jobsRepo.scheduleJob({\n name: options.name,\n priority: options.priority || 100,\n nextRunAt: getNextRunDate(options),\n params: options.params || null,\n uniqueIdentifier: options.uniqueIdentifier,\n })\n }\n\n async scheduleJobs(jobs: ScheduleJobsOptions): Promise<ScheduleJobsResult> {\n logger.debug(`Scheduling ${jobs.length} jobs...`)\n\n const jobRecords = jobs.map(options => ({\n name: options.name,\n priority: options.priority || 100,\n nextRunAt: getNextRunDate(options),\n params: options.params || null,\n uniqueIdentifier: options.uniqueIdentifier,\n }))\n\n return await this.jobsRepo.scheduleJobs(jobRecords)\n }\n}\n","import {generateId} from '@orion-js/helpers'\nimport {logger} from '@orion-js/logger'\nimport {Collection, MongoDB, MongoCollection} from '@orion-js/mongodb'\nimport {ScheduleJobRecordOptions, ScheduleJobsResult} from '../types/Events'\nimport {JobRecord} from '../types/JobRecord'\nimport {JobDefinitionWithName, RecurrentJobDefinition} from '../types/JobsDefinition'\nimport {JobToRun} from '../types/Worker'\nimport {Repository} from '@orion-js/mongodb'\nimport {JobRecordSchema} from '../types/JobRecord'\n\n@Repository()\nexport class JobsRepo {\n @MongoCollection({\n idGeneration: 'uuid',\n name: 'orionjs.jobs_dogs_records',\n schema: JobRecordSchema,\n indexes: [\n {\n keys: {\n jobName: 1,\n priority: -1,\n nextRunAt: 1,\n },\n },\n {\n keys: {\n jobName: 1,\n },\n options: {\n unique: true,\n partialFilterExpression: {type: 'recurrent'},\n },\n },\n {\n keys: {\n uniqueIdentifier: 1,\n },\n options: {\n unique: true,\n sparse: true,\n },\n },\n ],\n })\n jobs: Collection<JobRecord>\n\n async getJobAndLock(jobNames: string[], lockTime: number): Promise<JobToRun> {\n const lockedUntil = new Date(Date.now() + lockTime)\n\n const job = await this.jobs.findOneAndUpdate(\n {\n jobName: {$in: jobNames},\n nextRunAt: {$lte: new Date()},\n $or: [{lockedUntil: {$exists: false}}, {lockedUntil: {$lte: new Date()}}],\n },\n {\n $set: {lockedUntil, lastRunAt: new Date()},\n },\n {\n mongoOptions: {\n sort: {\n priority: -1,\n nextRunAt: 1,\n },\n returnDocument: 'before',\n },\n },\n )\n\n if (!job) return\n\n let tries = job.tries || 1\n\n if (job.lockedUntil) {\n logger.info(`Running job \"${job.jobName}\" that was staled`)\n this.jobs.updateOne(job._id, {$inc: {tries: 1}})\n tries++\n }\n\n return {\n jobId: job._id,\n executionId: generateId(),\n name: job.jobName,\n params: job.params,\n type: job.type,\n tries,\n lockTime,\n priority: job.priority,\n uniqueIdentifier: job.uniqueIdentifier,\n }\n }\n\n async setJobRecordPriority(jobId: string, priority: number) {\n await this.jobs.updateOne(jobId, {$set: {priority}})\n }\n\n async scheduleNextRun(options: {\n jobId: string\n nextRunAt: Date\n addTries: boolean\n priority: number\n }) {\n const updator: MongoDB.UpdateFilter<JobRecord> = {\n $set: {\n nextRunAt: options.nextRunAt,\n priority: options.priority,\n ...(options.addTries ? {} : {tries: 0}),\n },\n $unset: {lockedUntil: ''},\n ...(options.addTries ? {$inc: {tries: 1}} : {}),\n }\n\n await this.jobs.updateOne(options.jobId, updator)\n }\n\n async deleteEventJob(jobId: string) {\n await this.jobs.deleteOne({_id: jobId, type: 'event'})\n }\n\n async extendLockTime(jobId: string, extraTime: number) {\n await this.updateLockTime(jobId, extraTime)\n }\n\n /**\n * Updates the lock time for a job to the specified duration from now.\n * Can be used to both extend or shorten the lock time.\n */\n async updateLockTime(jobId: string, lockDuration: number) {\n const lockedUntil = new Date(Date.now() + lockDuration)\n await this.jobs.updateOne(\n {\n _id: jobId,\n },\n {\n $set: {lockedUntil},\n },\n )\n }\n\n async unlockAllJobs(): Promise<number> {\n const result = await this.jobs.updateMany(\n {\n lockedUntil: {$exists: true},\n },\n {\n $unset: {lockedUntil: ''},\n },\n )\n\n return result.modifiedCount\n }\n\n async ensureJobRecord(job: JobDefinitionWithName) {\n const result = await this.jobs.upsert(\n {\n jobName: job.name,\n },\n {\n $set: {\n type: job.type,\n priority: (job as RecurrentJobDefinition).priority,\n },\n $setOnInsert: {\n nextRunAt: new Date(),\n },\n },\n )\n\n if (result.upsertedId) {\n logger.debug(`Created job record for \"${job.name}\"`)\n } else {\n logger.debug(`Record for job \"${job.name}\" already exists`)\n }\n }\n\n async scheduleJob(options: ScheduleJobRecordOptions) {\n try {\n await this.jobs.insertOne({\n jobName: options.name,\n uniqueIdentifier: options.uniqueIdentifier,\n params: options.params,\n nextRunAt: options.nextRunAt,\n priority: options.priority,\n type: 'event',\n })\n } catch (error) {\n if (\n error.isValidationError &&\n Object.values(error.validationErrors).includes('notUnique') &&\n options.uniqueIdentifier\n ) {\n logger.info(\n `Job \"${options.name}\" with identifier \"${options.uniqueIdentifier}\" already exists`,\n )\n } else {\n throw error\n }\n }\n }\n\n async scheduleJobs(jobs: ScheduleJobRecordOptions[]): Promise<ScheduleJobsResult> {\n if (jobs.length === 0) {\n return {scheduledCount: 0, skippedCount: 0, errors: []}\n }\n\n // Process each job individually to handle errors properly\n let scheduledCount = 0\n let skippedCount = 0\n const errors: Array<{index: number; error: Error; job: ScheduleJobRecordOptions}> = []\n\n for (let i = 0; i < jobs.length; i++) {\n const job = jobs[i]\n try {\n // Insert directly to get better error handling than the single scheduleJob method\n await this.jobs.insertOne({\n jobName: job.name,\n uniqueIdentifier: job.uniqueIdentifier,\n params: job.params,\n nextRunAt: job.nextRunAt,\n priority: job.priority,\n type: 'event',\n })\n scheduledCount++\n } catch (error) {\n // Check if it's a validation error with uniqueIdentifier constraint\n if (\n error.isValidationError &&\n Object.values(error.validationErrors).includes('notUnique') &&\n job.uniqueIdentifier\n ) {\n logger.info(`Job \"${job.name}\" with identifier \"${job.uniqueIdentifier}\" already exists`)\n skippedCount++\n } else {\n errors.push({\n index: i,\n error: error instanceof Error ? error : new Error(String(error)),\n job,\n })\n }\n }\n }\n\n logger.debug(\n `Scheduled ${scheduledCount} jobs successfully, skipped ${skippedCount}, errors: ${errors.length}`,\n )\n\n return {\n scheduledCount,\n skippedCount,\n errors,\n }\n }\n}\n","import {createEnum, InferSchemaType, schemaWithName} from '@orion-js/schema'\n\nexport const JobRecordSchema = schemaWithName('JobRecord', {\n _id: {type: 'string'},\n jobName: {type: 'string'},\n type: {type: createEnum('JobType', ['recurrent', 'event'])},\n priority: {type: 'number'},\n uniqueIdentifier: {type: 'string', optional: true},\n nextRunAt: {type: 'date'},\n lastRunAt: {type: 'date', optional: true},\n lockedUntil: {type: 'date', optional: true},\n tries: {type: 'number', optional: true},\n params: {type: 'blackbox', optional: true},\n})\n\nexport type JobRecord = InferSchemaType<typeof JobRecordSchema>\n","export type Options = {\n getNextRun?: () => Date\n runIn?: number\n runEvery?: number\n runAt?: Date\n} & {[key: string]: any}\n\nexport const getNextRunDate = (options: Options) => {\n if (options.runIn) {\n return new Date(Date.now() + options.runIn)\n }\n\n if (options.runEvery) {\n return new Date(Date.now() + options.runEvery)\n }\n\n if (options.runAt) {\n return options.runAt\n }\n\n if (options.getNextRun) {\n return options.getNextRun()\n }\n\n return new Date()\n}\n","import {Inject, Service} from '@orion-js/services'\nimport {range} from 'rambdax'\nimport {JobsRepo} from '../repos/JobsRepo'\nimport {JobDefinitionWithName, JobsDefinition} from '../types/JobsDefinition'\nimport {StartWorkersConfig} from '../types/StartConfig'\nimport {sleep} from '@orion-js/helpers'\nimport {Executor} from './Executor'\nimport {WorkerInstance, WorkersInstance} from '../types/Worker'\nimport {logger} from '@orion-js/logger'\n\n@Service()\nexport class WorkerService {\n @Inject(() => JobsRepo)\n private jobsRepo: JobsRepo\n\n @Inject(() => Executor)\n private executor: Executor\n\n getJobNames(jobs: JobsDefinition) {\n return Object.keys(jobs)\n }\n\n getJobs(jobs: JobsDefinition): JobDefinitionWithName[] {\n return Object.keys(jobs).map(name => {\n return {\n name,\n ...jobs[name],\n }\n })\n }\n\n async runWorkerLoop(config: StartWorkersConfig, workerInstance: WorkerInstance) {\n const names = this.getJobNames(config.jobs)\n logger.debug(\n `Running worker loop [w${workerInstance.workerIndex}] for jobs \"${names.join(', ')}\"...`,\n )\n const jobToRun = await this.jobsRepo.getJobAndLock(names, config.defaultLockTime)\n if (!jobToRun) {\n logger.debug('No job to run')\n return false\n }\n\n logger.debug(`Got job [w${workerInstance.workerIndex}] to run:`, jobToRun)\n await this.executor.executeJob(config.jobs, jobToRun, workerInstance.respawn)\n\n return true\n }\n\n async startWorker(config: StartWorkersConfig, workerInstance: WorkerInstance) {\n while (true) {\n if (!workerInstance.running) {\n logger.info(`Got signal to stop. Stopping worker [w${workerInstance.workerIndex}]...`)\n return\n }\n\n try {\n const didRun = await this.runWorkerLoop(config, workerInstance)\n if (!didRun) await sleep(config.pollInterval)\n if (didRun) await sleep(config.cooldownPeriod)\n } catch (error) {\n logger.error('Error in job runner.', {error})\n await sleep(config.pollInterval)\n }\n }\n }\n\n createWorkersInstanceDefinition(config: StartWorkersConfig): WorkersInstance {\n const workersInstance: WorkersInstance = {\n running: true,\n workersCount: config.workersCount,\n workers: [],\n stop: async () => {\n logger.info('Stopping workers...')\n workersInstance.running = false\n const stopingPromises = workersInstance.workers.map(worker => worker.stop())\n await Promise.all(stopingPromises)\n },\n }\n\n return workersInstance\n }\n\n async ensureRecords(config: StartWorkersConfig) {\n const jobs = this.getJobs(config.jobs)\n\n await Promise.all(\n jobs\n .filter(job => job.type === 'recurrent')\n .map(async job => {\n logger.debug(`Ensuring records for job \"${job.name}\"...`)\n await this.jobsRepo.ensureJobRecord(job)\n }),\n )\n }\n\n async startANewWorker(config: StartWorkersConfig, workersInstance: WorkersInstance) {\n const workerIndex = workersInstance.workers.length\n\n logger.info(`Starting worker [w${workerIndex}]`)\n\n const workerInstance: WorkerInstance = {\n running: true,\n workerIndex,\n stop: async () => {\n logger.info(`Stopping worker [w${workerIndex}]...`)\n workerInstance.running = false\n await workerInstance.promise\n },\n respawn: async () => {\n logger.info(`Respawning worker [w${workerIndex}]...`)\n workerInstance.stop()\n await this.startANewWorker(config, workersInstance)\n },\n }\n\n const workerPromise = this.startWorker(config, workerInstance)\n\n workerInstance.promise = workerPromise\n workersInstance.workers.push(workerInstance)\n }\n\n async runWorkers(config: StartWorkersConfig, workersInstance: WorkersInstance) {\n logger.debug('Will ensure records for recurrent jobs')\n await this.ensureRecords(config)\n\n for (const _ of range(0, config.workersCount)) {\n this.startANewWorker(config, workersInstance)\n }\n }\n\n startWorkers(userConfig: Partial<StartWorkersConfig>): WorkersInstance {\n const defaultConfig: StartWorkersConfig = {\n jobs: {},\n cooldownPeriod: 100,\n pollInterval: 3000,\n workersCount: 4,\n defaultLockTime: 30 * 1000,\n }\n\n const config = {\n ...defaultConfig,\n ...userConfig,\n }\n\n setNameToJobs(config.jobs)\n\n const workersInstance = this.createWorkersInstanceDefinition(config)\n logger.debug('Starting workers', config)\n\n this.runWorkers(config, workersInstance)\n\n return workersInstance\n }\n}\n\nfunction setNameToJobs(jobs: JobsDefinition) {\n return Object.keys(jobs).map(name => {\n jobs[name].jobName = name\n })\n}\n","function _isInteger(n){\n return n << 0 === n\n}\n\nexport const isInteger = Number.isInteger || _isInteger\n\n/**\n * Check if `index` is integer even if it is a string.\n */\nexport const isIndexInteger = index => Number.isInteger(Number(index))\n","import { isInteger } from './isInteger.js'\n\nexport function createPath(path, delimiter = '.'){\n return typeof path === 'string' ?\n path.split(delimiter).map(x => isInteger(x) ? Number(x) : x) :\n path\n}\n","export function compare(a, b){\n return String(a) === String(b)\n}\n","import { compare } from './compare.js'\n\nexport function includes(a, list){\n let index = -1\n const { length } = list\n\n while (++index < length)\n if (compare(list[ index ], a))\n return true\n\n return false\n}\n","import { createPath } from './_internals/createPath.js'\nimport { includes } from './_internals/includes.js'\n\nexport function omit(propsToOmit, obj){\n if (arguments.length === 1) return _obj => omit(propsToOmit, _obj)\n\n if (obj === null || obj === undefined)\n return undefined\n\n const propsToOmitValue = createPath(propsToOmit, ',')\n const willReturn = {}\n\n for (const key in obj)\n if (!includes(key, propsToOmitValue))\n willReturn[ key ] = obj[ key ]\n\n return willReturn\n}\n","export function range(start, end){\n if (arguments.length === 1) return _end => range(start, _end)\n\n if (Number.isNaN(Number(start)) || Number.isNaN(Number(end))){\n throw new TypeError('Both arguments to range must be numbers')\n }\n\n if (end < start) return []\n\n const len = end - start\n const willReturn = Array(len)\n\n for (let i = 0; i < len; i++){\n willReturn[ i ] = start + i\n }\n\n return willReturn\n}\n","import {logger, runWithOrionAsyncContext, updateOrionAsyncContext} from '@orion-js/logger'\nimport {Inject, Service} from '@orion-js/services'\nimport {JobsHistoryRepo} from '../repos/JobsHistoryRepo'\nimport {JobsRepo} from '../repos/JobsRepo'\nimport {JobDefinition, JobsDefinition} from '../types/JobsDefinition'\nimport {ExecutionContext, JobToRun} from '../types/Worker'\nimport {getNextRunDate} from './getNextRunDate'\nimport {trace, SpanStatusCode} from '@opentelemetry/api'\nimport {Blackbox} from '@orion-js/schema'\n\n@Service()\nexport class Executor {\n @Inject(() => JobsRepo)\n private readonly jobsRepo: JobsRepo\n\n @Inject(() => JobsHistoryRepo)\n private readonly jobsHistoryRepo: JobsHistoryRepo\n\n /**\n * Determines the effective lock time for a job execution.\n * Job-specific lockTime takes precedence over the default lockTime from config.\n */\n getEffectiveLockTime(job: JobDefinition, jobToRun: JobToRun): number {\n return job.lockTime ?? jobToRun.lockTime\n }\n\n getContext(job: JobDefinition, jobToRun: JobToRun, onStale: Function): ExecutionContext {\n const effectiveLockTime = this.getEffectiveLockTime(job, jobToRun)\n let staleTimeout = setTimeout(() => onStale(), effectiveLockTime)\n return {\n definition: job,\n record: jobToRun,\n tries: jobToRun.tries || 0,\n clearStaleTimeout: () => clearTimeout(staleTimeout),\n extendLockTime: async (extraTime: number) => {\n clearTimeout(staleTimeout)\n staleTimeout = setTimeout(() => onStale(), extraTime)\n await this.jobsRepo.extendLockTime(jobToRun.jobId, extraTime)\n },\n logger: logger.addMetadata({\n jobName: jobToRun.name,\n jobId: jobToRun.jobId,\n }),\n }\n }\n\n getJobDefinition(jobToRun: JobToRun, jobs: JobsDefinition) {\n const job = jobs[jobToRun.name]\n\n if (jobToRun.type !== job.type) {\n logger.warn(\n `Job record \"${jobToRun.name}\" is \"${jobToRun.type}\" but definition is \"${job.type}\"`,\n )\n return\n }\n\n return job\n }\n\n async onError(error: any, job: JobDefinition, jobToRun: JobToRun, context: ExecutionContext) {\n const scheduleRecurrent = async () => {\n if (job.type === 'recurrent') {\n await this.jobsRepo.scheduleNextRun({\n jobId: jobToRun.jobId,\n nextRunAt: getNextRunDate(job),\n addTries: false,\n priority: job.priority,\n })\n }\n }\n\n if (!job.onError) {\n context.logger.error(`Error executing job \"${jobToRun.name}\"`, {error})\n await scheduleRecurrent()\n return\n }\n context.logger.info(`Error executing job \"${jobToRun.name}\"`, {error})\n\n const result = await job.onError(error, jobToRun.params, context)\n\n if (result.action === 'dismiss') {\n await scheduleRecurrent()\n return\n }\n\n if (result.action === 'retry') {\n await this.jobsRepo.scheduleNextRun({\n jobId: jobToRun.jobId,\n nextRunAt: getNextRunDate(result),\n addTries: true,\n priority: job.type === 'recurrent' ? job.priority : jobToRun.priority,\n })\n }\n }\n\n async saveExecution(options: {\n startedAt: Date\n status: 'stale' | 'error' | 'success'\n errorMessage?: string\n result?: Blackbox\n job: JobDefinition\n jobToRun: JobToRun\n }) {\n const {startedAt, status, errorMessage, result, job, jobToRun} = options\n const endedAt = new Date()\n\n if (job.saveExecutionsFor !== 0) {\n const oneWeek = 1000 * 60 * 60 * 24 * 7\n const saveExecutionsFor = job.saveExecutionsFor || oneWeek\n await this.jobsHistoryRepo.saveExecution({\n jobId: jobToRun.jobId,\n executionId: jobToRun.executionId,\n jobName: jobToRun.name,\n type: jobToRun.type,\n priority: jobToRun.priority,\n tries: jobToRun.tries,\n uniqueIdentifier: jobToRun.uniqueIdentifier,\n startedAt,\n endedAt,\n duration: endedAt.getTime() - startedAt.getTime(),\n expiresAt: new Date(Date.now() + saveExecutionsFor),\n status,\n errorMessage,\n params: jobToRun.params,\n result,\n })\n }\n }\n\n async afterExecutionSuccess(job: JobDefinition, jobToRun: JobToRun, context: ExecutionContext) {\n if (job.type === 'recurrent') {\n context.logger.debug(`Scheduling next run for recurrent job \"${jobToRun.name}\"`)\n await this.jobsRepo.scheduleNextRun({\n jobId: jobToRun.jobId,\n nextRunAt: getNextRunDate(job),\n addTries: false,\n priority: job.priority,\n })\n }\n if (job.type === 'event') {\n context.logger.debug(`Removing event job after success \"${jobToRun.name}\"`)\n await this.jobsRepo.deleteEventJob(jobToRun.jobId)\n }\n }\n\n async executeJob(jobs: JobsDefinition, jobToRun: JobToRun, respawnWorker: Function) {\n const job = this.getJobDefinition(jobToRun, jobs)\n if (!job) return\n\n // If job has a custom lockTime different from the default, update the database lock\n const effectiveLockTime = this.getEffectiveLockTime(job, jobToRun)\n if (effectiveLockTime !== jobToRun.lockTime) {\n await this.jobsRepo.updateLockTime(jobToRun.jobId, effectiveLockTime)\n }\n\n const tracer = trace.getTracer('orionjs.dogs', '1.0')\n\n await tracer.startActiveSpan(`job.${jobToRun.name}.${jobToRun.executionId}`, async span => {\n try {\n const startedAt = new Date()\n\n const onStale = async () => {\n if (job.onStale) {\n context.logger.info(`Job \"${jobToRun.name}\" is stale`)\n job.onStale(jobToRun.params, context)\n } else {\n context.logger.error(`Job \"${jobToRun.name}\" is stale`)\n }\n\n await this.jobsRepo.setJobRecordPriority(jobToRun.jobId, 0)\n\n respawnWorker()\n\n this.saveExecution({\n startedAt,\n status: 'stale',\n result: null,\n errorMessage: null,\n job,\n jobToRun,\n })\n }\n\n const context = this.getContext(job, jobToRun, onStale)\n\n const extraContext = {\n controllerType: 'job' as const,\n jobName: jobToRun.name,\n params: jobToRun.params,\n }\n\n await runWithOrionAsyncContext(extraContext, async () => {\n try {\n // Inject async context update\n updateOrionAsyncContext({\n jobName: jobToRun.name,\n params: jobToRun.params,\n })\n const result = await job.resolve(jobToRun.params, context)\n context.clearStaleTimeout()\n\n this.saveExecution({\n startedAt,\n status: 'success',\n result: result || null,\n errorMessage: null,\n job,\n jobToRun,\n })\n\n await this.afterExecutionSuccess(job, jobToRun, context)\n } catch (error) {\n context.clearStaleTimeout()\n this.saveExecution({\n startedAt,\n status: 'error',\n result: null,\n errorMessage: (error as Error).message,\n job,\n jobToRun,\n })\n\n await this.onError(error, job, jobToRun, context)\n }\n })\n } catch (error) {\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: error.message,\n })\n throw error\n } finally {\n span.end()\n }\n })\n }\n}\n","import {Collection, MongoCollection, Repository, MongoDB} from '@orion-js/mongodb'\nimport {omit} from 'rambdax'\nimport {HistoryRecord, HistoryRecordSchema} from '../types/HistoryRecord'\n\n@Repository()\nexport class JobsHistoryRepo {\n @MongoCollection({\n name: 'orionjs.jobs_dogs_history',\n idGeneration: 'uuid',\n schema: HistoryRecordSchema,\n indexes: [\n {\n keys: {\n jobName: 1,\n startedAt: 1,\n },\n },\n {\n keys: {\n executionId: 1,\n },\n },\n {\n keys: {\n expiresAt: 1,\n },\n options: {\n expireAfterSeconds: 0,\n },\n },\n ],\n })\n history: Collection<HistoryRecord>\n\n async saveExecution(record: MongoDB.WithoutId<HistoryRecord>) {\n await this.history.upsert(\n {executionId: record.executionId},\n {\n $setOnInsert: {\n status: record.status,\n },\n $set: {\n ...omit(['status'], record),\n },\n },\n )\n }\n\n async getExecutions(jobName: string, limit?: number, skip?: number): Promise<HistoryRecord[]> {\n const cursor = this.history.find({jobName}).sort({startedAt: -1})\n\n if (skip) {\n cursor.skip(skip)\n }\n\n if (limit) {\n cursor.limit(limit)\n }\n\n return await cursor.toArray()\n }\n}\n","import {InferSchemaType, schemaWithName} from '@orion-js/schema'\n\nexport const HistoryRecordSchema = schemaWithName('HistoryRecord', {\n _id: {type: 'string'},\n jobId: {type: 'string'},\n executionId: {type: 'string'},\n jobName: {type: 'string'},\n type: {type: 'string'},\n priority: {type: 'number'},\n tries: {type: 'number'},\n uniqueIdentifier: {type: 'string', optional: true},\n startedAt: {type: 'date'},\n endedAt: {type: 'date'},\n duration: {type: 'number'},\n expiresAt: {type: 'date', optional: true},\n status: {type: 'string', enum: ['success', 'error', 'stale']},\n errorMessage: {type: 'string', optional: true},\n params: {type: 'blackbox', optional: true},\n result: {type: 'any', optional: true},\n})\n\nexport type HistoryRecord = InferSchemaType<typeof HistoryRecordSchema>\n","import {getInstance, Service} from '@orion-js/services'\nimport {createEventJob, defineJob} from '../defineJob'\nimport type {CreateEventJobOptions, JobDefinition, RecurrentJobDefinition} from '../types'\n\n// Define metadata storage using WeakMaps\nconst serviceMetadata = new WeakMap<any, {_serviceType: string}>()\nconst jobsMetadata = new Map<any, Record<string, any>>()\n\nexport function Jobs() {\n return (target: any, context: ClassDecoratorContext<any>) => {\n Service()(target, context)\n\n context.addInitializer(function (this) {\n serviceMetadata.set(this, {_serviceType: 'jobs'})\n })\n }\n}\n\nexport function RecurrentJob(): (\n method: any,\n context: ClassFieldDecoratorContext | ClassMethodDecoratorContext,\n) => any\nexport function RecurrentJob(\n options: Omit<RecurrentJobDefinition, 'resolve' | 'type'>,\n): (method: any, context: ClassMethodDecoratorContext) => any\nexport function RecurrentJob(options = {}) {\n return (method: any, context: ClassFieldDecoratorContext | ClassMethodDecoratorContext) => {\n const propertyKey = String(context.name)\n\n context.addInitializer(function (this) {\n const jobs = jobsMetadata.get(this) || {}\n\n if (context.kind === 'method') {\n jobs[propertyKey] = defineJob({\n ...options,\n type: 'recurrent',\n resolve: this[propertyKey].bind(this),\n })\n }\n\n if (context.kind === 'field') {\n jobs[propertyKey] = this[propertyKey]\n }\n\n jobsMetadata.set(this, jobs)\n })\n\n return method\n }\n}\n\nexport function EventJob(): (\n method: any,\n context: ClassFieldDecoratorContext | ClassMethodDecoratorContext,\n) => any\nexport function EventJob(\n options: Omit<CreateEventJobOptions<any>, 'resolve'>,\n): (method: any, context: ClassMethodDecoratorContext) => any\nexport function EventJob(options = {}) {\n return (method: any, context: ClassFieldDecoratorContext | ClassMethodDecoratorContext) => {\n const propertyKey = String(context.name)\n\n context.addInitializer(function (this) {\n const jobs = jobsMetadata.get(this) || {}\n\n if (context.kind === 'method') {\n jobs[propertyKey] = createEventJob({\n ...options,\n resolve: this[propertyKey].bind(this),\n })\n }\n\n if (context.kind === 'field') {\n jobs[propertyKey] = this[propertyKey]\n }\n\n jobsMetadata.set(this, jobs)\n })\n\n return method\n }\n}\n\nexport function getServiceJobs(target: any): {\n [key: string]: JobDefinition\n} {\n const instance = getInstance(target)\n\n if (!serviceMetadata.has(instance.constructor)) {\n throw new Error('You must pass a class decorated with @Jobs to getServiceJobs')\n }\n\n const instanceMetadata = serviceMetadata.get(instance.constructor)\n if (instanceMetadata._serviceType !== 'jobs') {\n throw new Error('You must pass a class decorated with @Jobs to getServiceJobs')\n }\n\n const jobsMap = jobsMetadata.get(instance) || {}\n\n return jobsMap\n}\n\n/**\n * Logs\n * after event job {\n job1: { type: 'event', resolve: [Function: bound job1] AsyncFunction }\n}\nbefore recurrent job Map(1) {\n ExampleJobsService {} => {\n job1: { type: 'event', resolve: [Function: bound job1] AsyncFunction }\n }\n}\nbefore recurrent job undefined\nafter recurrent job {\n job2: {\n runEvery: 1000,\n type: 'recurrent',\n resolve: [Function: bound job2] AsyncFunction,\n priority: 100\n }\n}\n{\n serviceJobs: {\n job2: {\n runEvery: 1000,\n type: 'recurrent',\n resolve: [Function: bound job2] AsyncFunction,\n priority: 100\n }\n }\n}\n */\n","import {\n CreateEventJobOptions,\n CreateJobOptions,\n CreateRecurrentJobOptions,\n EventJobDefinition,\n JobDefinition,\n RecurrentJobDefinition,\n} from '../types/JobsDefinition'\nimport {scheduleJob, ScheduleJobsResult, scheduleJobs} from '..'\nimport {ScheduleJobOptionsWithoutName} from '../types/Events'\nimport {cleanAndValidate, SchemaInAnyOrionForm} from '@orion-js/schema'\nimport parse from 'parse-duration'\n\nexport function createEventJob<TParamsSchema extends SchemaInAnyOrionForm>(\n options: CreateEventJobOptions<TParamsSchema>,\n): EventJobDefinition<TParamsSchema> {\n const jobDefinition: EventJobDefinition<TParamsSchema> = {\n ...options,\n type: 'event',\n schedule: null,\n scheduleJobs: null,\n }\n\n jobDefinition.schedule = async (scheduleOptions: ScheduleJobOptionsWithoutName<TParamsSchema>) => {\n if (!jobDefinition.jobName) {\n throw new Error('This job has not been registered in the workers')\n }\n\n const params = jobDefinition.params\n ? await cleanAndValidate(jobDefinition.params, scheduleOptions.params)\n : scheduleOptions.params\n\n return await scheduleJob({\n ...scheduleOptions,\n name: jobDefinition.jobName,\n params,\n })\n }\n\n jobDefinition.scheduleJobs = async (\n jobs: Array<ScheduleJobOptionsWithoutName<TParamsSchema>>,\n ): Promise<ScheduleJobsResult> => {\n if (!jobDefinition.jobName) {\n throw new Error('This job has not been registered in the workers')\n }\n\n // Process all job parameters if schema validation is needed\n const processedJobs = await Promise.all(\n jobs.map(async scheduleOptions => {\n const params = jobDefinition.params\n ? await cleanAndValidate(jobDefinition.params, scheduleOptions.params)\n : scheduleOptions.params\n\n return {\n ...scheduleOptions,\n name: jobDefinition.jobName,\n params,\n }\n }),\n )\n\n return await scheduleJobs(processedJobs)\n }\n\n return jobDefinition\n}\n\nexport function createRecurrentJob(options: CreateRecurrentJobOptions): RecurrentJobDefinition {\n const jobDefinition: RecurrentJobDefinition = {\n ...options,\n priority: options.priority ?? 100,\n type: 'recurrent',\n runEvery: typeof options.runEvery === 'string' ? parse(options.runEvery) : options.runEvery,\n }\n\n return jobDefinition\n}\n\n/**\n * @deprecated Use `createEventJob` or `createRecurrentJob` instead.\n */\nexport const defineJob = (\n options: CreateJobOptions & {type: 'event' | 'recurrent'},\n): JobDefinition => {\n return options.type === 'event'\n ? createEventJob(options as any)\n : createRecurrentJob(options as any)\n}\n"],"mappings":"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","names":["import_services","import_logger","import_mongodb","_init","import_services","import_helpers","import_logger","import_services","import_mongodb","import_schema","_init","_jobsRepo_dec","_init","import_logger","_jobsRepo_dec","_init","import_services","import_schema","parse"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -226,6 +226,12 @@ interface BaseJobDefinition {
|
|
|
226
226
|
* This is set automatically when the job is passed to startWorkers.
|
|
227
227
|
*/
|
|
228
228
|
jobName?: string;
|
|
229
|
+
/**
|
|
230
|
+
* Time in milliseconds to lock this specific job for execution.
|
|
231
|
+
* Overrides the defaultLockTime set in startWorkers config.
|
|
232
|
+
* If not set, the defaultLockTime from config will be used.
|
|
233
|
+
*/
|
|
234
|
+
lockTime?: number;
|
|
229
235
|
}
|
|
230
236
|
interface RecurrentJobDefinition extends BaseJobDefinition {
|
|
231
237
|
/**
|
|
@@ -298,22 +304,23 @@ interface StartWorkersConfig {
|
|
|
298
304
|
* Time in milliseconds to wait between each look without results for a job
|
|
299
305
|
* to run at the database. Default is 3000.
|
|
300
306
|
*/
|
|
301
|
-
pollInterval
|
|
307
|
+
pollInterval?: number;
|
|
302
308
|
/**
|
|
303
309
|
* Time in milliseconds to wait too look for a job after a job execution. Default is 100.
|
|
304
310
|
*/
|
|
305
|
-
cooldownPeriod
|
|
311
|
+
cooldownPeriod?: number;
|
|
306
312
|
/**
|
|
307
313
|
* Number of workers to start. Default is 1.
|
|
308
314
|
*/
|
|
309
|
-
workersCount
|
|
315
|
+
workersCount?: number;
|
|
310
316
|
/**
|
|
311
|
-
*
|
|
317
|
+
* Default time in milliseconds to lock a job for execution. Default is 30000 (30 seconds).
|
|
312
318
|
* If a job is locked for longer than this time, it will be considered as failed.
|
|
313
319
|
* This is to prevent a job from being executed multiple times at the same time.
|
|
314
320
|
* You can extend this time inside a job by calling extendLockTime from context.
|
|
321
|
+
* Individual jobs can override this value by setting their own lockTime.
|
|
315
322
|
*/
|
|
316
|
-
|
|
323
|
+
defaultLockTime?: number;
|
|
317
324
|
}
|
|
318
325
|
|
|
319
326
|
declare class JobsHistoryRepo {
|
|
@@ -334,6 +341,11 @@ declare class JobsRepo {
|
|
|
334
341
|
}): Promise<void>;
|
|
335
342
|
deleteEventJob(jobId: string): Promise<void>;
|
|
336
343
|
extendLockTime(jobId: string, extraTime: number): Promise<void>;
|
|
344
|
+
/**
|
|
345
|
+
* Updates the lock time for a job to the specified duration from now.
|
|
346
|
+
* Can be used to both extend or shorten the lock time.
|
|
347
|
+
*/
|
|
348
|
+
updateLockTime(jobId: string, lockDuration: number): Promise<void>;
|
|
337
349
|
unlockAllJobs(): Promise<number>;
|
|
338
350
|
ensureJobRecord(job: JobDefinitionWithName): Promise<void>;
|
|
339
351
|
scheduleJob(options: ScheduleJobRecordOptions): Promise<void>;
|
|
@@ -360,7 +372,7 @@ declare const defineJob: (options: CreateJobOptions & {
|
|
|
360
372
|
|
|
361
373
|
declare const jobsHistoryRepo: JobsHistoryRepo;
|
|
362
374
|
declare const jobsRepo: JobsRepo;
|
|
363
|
-
declare const startWorkers: (config:
|
|
375
|
+
declare const startWorkers: (config: StartWorkersConfig) => WorkersInstance;
|
|
364
376
|
/**
|
|
365
377
|
* @deprecated Use the event job definition.schedule method instead.
|
|
366
378
|
*/
|
package/dist/index.d.ts
CHANGED
|
@@ -226,6 +226,12 @@ interface BaseJobDefinition {
|
|
|
226
226
|
* This is set automatically when the job is passed to startWorkers.
|
|
227
227
|
*/
|
|
228
228
|
jobName?: string;
|
|
229
|
+
/**
|
|
230
|
+
* Time in milliseconds to lock this specific job for execution.
|
|
231
|
+
* Overrides the defaultLockTime set in startWorkers config.
|
|
232
|
+
* If not set, the defaultLockTime from config will be used.
|
|
233
|
+
*/
|
|
234
|
+
lockTime?: number;
|
|
229
235
|
}
|
|
230
236
|
interface RecurrentJobDefinition extends BaseJobDefinition {
|
|
231
237
|
/**
|
|
@@ -298,22 +304,23 @@ interface StartWorkersConfig {
|
|
|
298
304
|
* Time in milliseconds to wait between each look without results for a job
|
|
299
305
|
* to run at the database. Default is 3000.
|
|
300
306
|
*/
|
|
301
|
-
pollInterval
|
|
307
|
+
pollInterval?: number;
|
|
302
308
|
/**
|
|
303
309
|
* Time in milliseconds to wait too look for a job after a job execution. Default is 100.
|
|
304
310
|
*/
|
|
305
|
-
cooldownPeriod
|
|
311
|
+
cooldownPeriod?: number;
|
|
306
312
|
/**
|
|
307
313
|
* Number of workers to start. Default is 1.
|
|
308
314
|
*/
|
|
309
|
-
workersCount
|
|
315
|
+
workersCount?: number;
|
|
310
316
|
/**
|
|
311
|
-
*
|
|
317
|
+
* Default time in milliseconds to lock a job for execution. Default is 30000 (30 seconds).
|
|
312
318
|
* If a job is locked for longer than this time, it will be considered as failed.
|
|
313
319
|
* This is to prevent a job from being executed multiple times at the same time.
|
|
314
320
|
* You can extend this time inside a job by calling extendLockTime from context.
|
|
321
|
+
* Individual jobs can override this value by setting their own lockTime.
|
|
315
322
|
*/
|
|
316
|
-
|
|
323
|
+
defaultLockTime?: number;
|
|
317
324
|
}
|
|
318
325
|
|
|
319
326
|
declare class JobsHistoryRepo {
|
|
@@ -334,6 +341,11 @@ declare class JobsRepo {
|
|
|
334
341
|
}): Promise<void>;
|
|
335
342
|
deleteEventJob(jobId: string): Promise<void>;
|
|
336
343
|
extendLockTime(jobId: string, extraTime: number): Promise<void>;
|
|
344
|
+
/**
|
|
345
|
+
* Updates the lock time for a job to the specified duration from now.
|
|
346
|
+
* Can be used to both extend or shorten the lock time.
|
|
347
|
+
*/
|
|
348
|
+
updateLockTime(jobId: string, lockDuration: number): Promise<void>;
|
|
337
349
|
unlockAllJobs(): Promise<number>;
|
|
338
350
|
ensureJobRecord(job: JobDefinitionWithName): Promise<void>;
|
|
339
351
|
scheduleJob(options: ScheduleJobRecordOptions): Promise<void>;
|
|
@@ -360,7 +372,7 @@ declare const defineJob: (options: CreateJobOptions & {
|
|
|
360
372
|
|
|
361
373
|
declare const jobsHistoryRepo: JobsHistoryRepo;
|
|
362
374
|
declare const jobsRepo: JobsRepo;
|
|
363
|
-
declare const startWorkers: (config:
|
|
375
|
+
declare const startWorkers: (config: StartWorkersConfig) => WorkersInstance;
|
|
364
376
|
/**
|
|
365
377
|
* @deprecated Use the event job definition.schedule method instead.
|
|
366
378
|
*/
|
package/dist/index.js
CHANGED
|
@@ -172,7 +172,14 @@ var JobsRepo = class {
|
|
|
172
172
|
await this.jobs.deleteOne({ _id: jobId, type: "event" });
|
|
173
173
|
}
|
|
174
174
|
async extendLockTime(jobId, extraTime) {
|
|
175
|
-
|
|
175
|
+
await this.updateLockTime(jobId, extraTime);
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Updates the lock time for a job to the specified duration from now.
|
|
179
|
+
* Can be used to both extend or shorten the lock time.
|
|
180
|
+
*/
|
|
181
|
+
async updateLockTime(jobId, lockDuration) {
|
|
182
|
+
const lockedUntil = new Date(Date.now() + lockDuration);
|
|
176
183
|
await this.jobs.updateOne(
|
|
177
184
|
{
|
|
178
185
|
_id: jobId
|
|
@@ -490,8 +497,16 @@ var Executor = class {
|
|
|
490
497
|
__publicField(this, "jobsRepo", __runInitializers(_init4, 8, this)), __runInitializers(_init4, 11, this);
|
|
491
498
|
__publicField(this, "jobsHistoryRepo", __runInitializers(_init4, 12, this)), __runInitializers(_init4, 15, this);
|
|
492
499
|
}
|
|
500
|
+
/**
|
|
501
|
+
* Determines the effective lock time for a job execution.
|
|
502
|
+
* Job-specific lockTime takes precedence over the default lockTime from config.
|
|
503
|
+
*/
|
|
504
|
+
getEffectiveLockTime(job, jobToRun) {
|
|
505
|
+
return job.lockTime ?? jobToRun.lockTime;
|
|
506
|
+
}
|
|
493
507
|
getContext(job, jobToRun, onStale) {
|
|
494
|
-
|
|
508
|
+
const effectiveLockTime = this.getEffectiveLockTime(job, jobToRun);
|
|
509
|
+
let staleTimeout = setTimeout(() => onStale(), effectiveLockTime);
|
|
495
510
|
return {
|
|
496
511
|
definition: job,
|
|
497
512
|
record: jobToRun,
|
|
@@ -592,6 +607,10 @@ var Executor = class {
|
|
|
592
607
|
async executeJob(jobs, jobToRun, respawnWorker) {
|
|
593
608
|
const job = this.getJobDefinition(jobToRun, jobs);
|
|
594
609
|
if (!job) return;
|
|
610
|
+
const effectiveLockTime = this.getEffectiveLockTime(job, jobToRun);
|
|
611
|
+
if (effectiveLockTime !== jobToRun.lockTime) {
|
|
612
|
+
await this.jobsRepo.updateLockTime(jobToRun.jobId, effectiveLockTime);
|
|
613
|
+
}
|
|
595
614
|
const tracer = trace.getTracer("orionjs.dogs", "1.0");
|
|
596
615
|
await tracer.startActiveSpan(`job.${jobToRun.name}.${jobToRun.executionId}`, async (span) => {
|
|
597
616
|
try {
|
|
@@ -693,7 +712,7 @@ var WorkerService = class {
|
|
|
693
712
|
logger4.debug(
|
|
694
713
|
`Running worker loop [w${workerInstance.workerIndex}] for jobs "${names.join(", ")}"...`
|
|
695
714
|
);
|
|
696
|
-
const jobToRun = await this.jobsRepo.getJobAndLock(names, config.
|
|
715
|
+
const jobToRun = await this.jobsRepo.getJobAndLock(names, config.defaultLockTime);
|
|
697
716
|
if (!jobToRun) {
|
|
698
717
|
logger4.debug("No job to run");
|
|
699
718
|
return false;
|
|
@@ -775,7 +794,7 @@ var WorkerService = class {
|
|
|
775
794
|
cooldownPeriod: 100,
|
|
776
795
|
pollInterval: 3e3,
|
|
777
796
|
workersCount: 4,
|
|
778
|
-
|
|
797
|
+
defaultLockTime: 30 * 1e3
|
|
779
798
|
};
|
|
780
799
|
const config = {
|
|
781
800
|
...defaultConfig,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/services/EventsService.ts","../src/repos/JobsRepo.ts","../src/types/JobRecord.ts","../src/services/getNextRunDate.ts","../src/services/WorkerService.ts","../../../node_modules/.pnpm/rambdax@11.3.1/node_modules/rambdax/src/_internals/isInteger.js","../../../node_modules/.pnpm/rambdax@11.3.1/node_modules/rambdax/src/_internals/createPath.js","../../../node_modules/.pnpm/rambdax@11.3.1/node_modules/rambdax/src/_internals/compare.js","../../../node_modules/.pnpm/rambdax@11.3.1/node_modules/rambdax/src/_internals/includes.js","../../../node_modules/.pnpm/rambdax@11.3.1/node_modules/rambdax/src/omit.js","../../../node_modules/.pnpm/rambdax@11.3.1/node_modules/rambdax/src/range.js","../src/services/Executor.ts","../src/repos/JobsHistoryRepo.ts","../src/types/HistoryRecord.ts","../src/service/index.ts","../src/defineJob/index.ts"],"sourcesContent":["import {getInstance} from '@orion-js/services'\nimport {EventsService} from './services/EventsService'\nimport {WorkerService} from './services/WorkerService'\nimport {StartWorkersConfig} from './types/StartConfig'\nimport {ScheduleJobOptions, ScheduleJobsOptions, ScheduleJobsResult} from './types/Events'\nimport {JobsHistoryRepo} from './repos/JobsHistoryRepo'\nimport {JobsRepo} from './repos/JobsRepo'\nimport {SchemaInAnyOrionForm} from '@orion-js/schema'\n\nexport * from './types'\nexport * from './service'\nexport * from './defineJob'\n\nconst workerService = getInstance(WorkerService)\nconst eventsService = getInstance(EventsService)\nconst jobsHistoryRepo = getInstance(JobsHistoryRepo)\nconst jobsRepo = getInstance(JobsRepo)\n\nconst startWorkers = (config: Partial<StartWorkersConfig>) => {\n return workerService.startWorkers(config)\n}\n\n/**\n * @deprecated Use the event job definition.schedule method instead.\n */\nconst scheduleJob = <TParamsSchema extends SchemaInAnyOrionForm = any>(\n options: ScheduleJobOptions<TParamsSchema>,\n) => {\n return eventsService.scheduleJob(options)\n}\n\n/**\n * Schedule multiple jobs at once for better performance.\n * @deprecated Use the event job definition.scheduleJobs method instead.\n */\nconst scheduleJobs = <TParamsSchema extends SchemaInAnyOrionForm = any>(\n jobs: ScheduleJobsOptions<TParamsSchema>,\n): Promise<ScheduleJobsResult> => {\n return eventsService.scheduleJobs(jobs)\n}\n\nexport {startWorkers, scheduleJob, scheduleJobs, jobsHistoryRepo, jobsRepo}\n","import {logger} from '@orion-js/logger'\nimport {Inject, Service} from '@orion-js/services'\nimport {JobsRepo} from '../repos/JobsRepo'\nimport {ScheduleJobOptions, ScheduleJobsOptions, ScheduleJobsResult} from '../types/Events'\nimport {getNextRunDate} from './getNextRunDate'\n\n@Service()\nexport class EventsService {\n @Inject(() => JobsRepo)\n private jobsRepo: JobsRepo\n\n async scheduleJob(options: ScheduleJobOptions) {\n logger.debug('Scheduling job...', options)\n\n await this.jobsRepo.scheduleJob({\n name: options.name,\n priority: options.priority || 100,\n nextRunAt: getNextRunDate(options),\n params: options.params || null,\n uniqueIdentifier: options.uniqueIdentifier,\n })\n }\n\n async scheduleJobs(jobs: ScheduleJobsOptions): Promise<ScheduleJobsResult> {\n logger.debug(`Scheduling ${jobs.length} jobs...`)\n\n const jobRecords = jobs.map(options => ({\n name: options.name,\n priority: options.priority || 100,\n nextRunAt: getNextRunDate(options),\n params: options.params || null,\n uniqueIdentifier: options.uniqueIdentifier,\n }))\n\n return await this.jobsRepo.scheduleJobs(jobRecords)\n }\n}\n","import {generateId} from '@orion-js/helpers'\nimport {logger} from '@orion-js/logger'\nimport {Collection, MongoDB, MongoCollection} from '@orion-js/mongodb'\nimport {ScheduleJobRecordOptions, ScheduleJobsResult} from '../types/Events'\nimport {JobRecord} from '../types/JobRecord'\nimport {JobDefinitionWithName, RecurrentJobDefinition} from '../types/JobsDefinition'\nimport {JobToRun} from '../types/Worker'\nimport {Repository} from '@orion-js/mongodb'\nimport {JobRecordSchema} from '../types/JobRecord'\n\n@Repository()\nexport class JobsRepo {\n @MongoCollection({\n idGeneration: 'uuid',\n name: 'orionjs.jobs_dogs_records',\n schema: JobRecordSchema,\n indexes: [\n {\n keys: {\n jobName: 1,\n priority: -1,\n nextRunAt: 1,\n },\n },\n {\n keys: {\n jobName: 1,\n },\n options: {\n unique: true,\n partialFilterExpression: {type: 'recurrent'},\n },\n },\n {\n keys: {\n uniqueIdentifier: 1,\n },\n options: {\n unique: true,\n sparse: true,\n },\n },\n ],\n })\n jobs: Collection<JobRecord>\n\n async getJobAndLock(jobNames: string[], lockTime: number): Promise<JobToRun> {\n const lockedUntil = new Date(Date.now() + lockTime)\n\n const job = await this.jobs.findOneAndUpdate(\n {\n jobName: {$in: jobNames},\n nextRunAt: {$lte: new Date()},\n $or: [{lockedUntil: {$exists: false}}, {lockedUntil: {$lte: new Date()}}],\n },\n {\n $set: {lockedUntil, lastRunAt: new Date()},\n },\n {\n mongoOptions: {\n sort: {\n priority: -1,\n nextRunAt: 1,\n },\n returnDocument: 'before',\n },\n },\n )\n\n if (!job) return\n\n let tries = job.tries || 1\n\n if (job.lockedUntil) {\n logger.info(`Running job \"${job.jobName}\" that was staled`)\n this.jobs.updateOne(job._id, {$inc: {tries: 1}})\n tries++\n }\n\n return {\n jobId: job._id,\n executionId: generateId(),\n name: job.jobName,\n params: job.params,\n type: job.type,\n tries,\n lockTime,\n priority: job.priority,\n uniqueIdentifier: job.uniqueIdentifier,\n }\n }\n\n async setJobRecordPriority(jobId: string, priority: number) {\n await this.jobs.updateOne(jobId, {$set: {priority}})\n }\n\n async scheduleNextRun(options: {\n jobId: string\n nextRunAt: Date\n addTries: boolean\n priority: number\n }) {\n const updator: MongoDB.UpdateFilter<JobRecord> = {\n $set: {\n nextRunAt: options.nextRunAt,\n priority: options.priority,\n ...(options.addTries ? {} : {tries: 0}),\n },\n $unset: {lockedUntil: ''},\n ...(options.addTries ? {$inc: {tries: 1}} : {}),\n }\n\n await this.jobs.updateOne(options.jobId, updator)\n }\n\n async deleteEventJob(jobId: string) {\n await this.jobs.deleteOne({_id: jobId, type: 'event'})\n }\n\n async extendLockTime(jobId: string, extraTime: number) {\n const lockedUntil = new Date(Date.now() + extraTime)\n await this.jobs.updateOne(\n {\n _id: jobId,\n },\n {\n $set: {lockedUntil},\n },\n )\n }\n\n async unlockAllJobs(): Promise<number> {\n const result = await this.jobs.updateMany(\n {\n lockedUntil: {$exists: true},\n },\n {\n $unset: {lockedUntil: ''},\n },\n )\n\n return result.modifiedCount\n }\n\n async ensureJobRecord(job: JobDefinitionWithName) {\n const result = await this.jobs.upsert(\n {\n jobName: job.name,\n },\n {\n $set: {\n type: job.type,\n priority: (job as RecurrentJobDefinition).priority,\n },\n $setOnInsert: {\n nextRunAt: new Date(),\n },\n },\n )\n\n if (result.upsertedId) {\n logger.debug(`Created job record for \"${job.name}\"`)\n } else {\n logger.debug(`Record for job \"${job.name}\" already exists`)\n }\n }\n\n async scheduleJob(options: ScheduleJobRecordOptions) {\n try {\n await this.jobs.insertOne({\n jobName: options.name,\n uniqueIdentifier: options.uniqueIdentifier,\n params: options.params,\n nextRunAt: options.nextRunAt,\n priority: options.priority,\n type: 'event',\n })\n } catch (error) {\n if (\n error.isValidationError &&\n Object.values(error.validationErrors).includes('notUnique') &&\n options.uniqueIdentifier\n ) {\n logger.info(\n `Job \"${options.name}\" with identifier \"${options.uniqueIdentifier}\" already exists`,\n )\n } else {\n throw error\n }\n }\n }\n\n async scheduleJobs(jobs: ScheduleJobRecordOptions[]): Promise<ScheduleJobsResult> {\n if (jobs.length === 0) {\n return {scheduledCount: 0, skippedCount: 0, errors: []}\n }\n\n // Process each job individually to handle errors properly\n let scheduledCount = 0\n let skippedCount = 0\n const errors: Array<{index: number; error: Error; job: ScheduleJobRecordOptions}> = []\n\n for (let i = 0; i < jobs.length; i++) {\n const job = jobs[i]\n try {\n // Insert directly to get better error handling than the single scheduleJob method\n await this.jobs.insertOne({\n jobName: job.name,\n uniqueIdentifier: job.uniqueIdentifier,\n params: job.params,\n nextRunAt: job.nextRunAt,\n priority: job.priority,\n type: 'event',\n })\n scheduledCount++\n } catch (error) {\n // Check if it's a validation error with uniqueIdentifier constraint\n if (\n error.isValidationError &&\n Object.values(error.validationErrors).includes('notUnique') &&\n job.uniqueIdentifier\n ) {\n logger.info(`Job \"${job.name}\" with identifier \"${job.uniqueIdentifier}\" already exists`)\n skippedCount++\n } else {\n errors.push({\n index: i,\n error: error instanceof Error ? error : new Error(String(error)),\n job,\n })\n }\n }\n }\n\n logger.debug(\n `Scheduled ${scheduledCount} jobs successfully, skipped ${skippedCount}, errors: ${errors.length}`,\n )\n\n return {\n scheduledCount,\n skippedCount,\n errors,\n }\n }\n}\n","import {createEnum, InferSchemaType, schemaWithName} from '@orion-js/schema'\n\nexport const JobRecordSchema = schemaWithName('JobRecord', {\n _id: {type: 'string'},\n jobName: {type: 'string'},\n type: {type: createEnum('JobType', ['recurrent', 'event'])},\n priority: {type: 'number'},\n uniqueIdentifier: {type: 'string', optional: true},\n nextRunAt: {type: 'date'},\n lastRunAt: {type: 'date', optional: true},\n lockedUntil: {type: 'date', optional: true},\n tries: {type: 'number', optional: true},\n params: {type: 'blackbox', optional: true},\n})\n\nexport type JobRecord = InferSchemaType<typeof JobRecordSchema>\n","export type Options = {\n getNextRun?: () => Date\n runIn?: number\n runEvery?: number\n runAt?: Date\n} & {[key: string]: any}\n\nexport const getNextRunDate = (options: Options) => {\n if (options.runIn) {\n return new Date(Date.now() + options.runIn)\n }\n\n if (options.runEvery) {\n return new Date(Date.now() + options.runEvery)\n }\n\n if (options.runAt) {\n return options.runAt\n }\n\n if (options.getNextRun) {\n return options.getNextRun()\n }\n\n return new Date()\n}\n","import {Inject, Service} from '@orion-js/services'\nimport {range} from 'rambdax'\nimport {JobsRepo} from '../repos/JobsRepo'\nimport {JobDefinitionWithName, JobsDefinition} from '../types/JobsDefinition'\nimport {StartWorkersConfig} from '../types/StartConfig'\nimport {sleep} from '@orion-js/helpers'\nimport {Executor} from './Executor'\nimport {WorkerInstance, WorkersInstance} from '../types/Worker'\nimport {logger} from '@orion-js/logger'\n\n@Service()\nexport class WorkerService {\n @Inject(() => JobsRepo)\n private jobsRepo: JobsRepo\n\n @Inject(() => Executor)\n private executor: Executor\n\n getJobNames(jobs: JobsDefinition) {\n return Object.keys(jobs)\n }\n\n getJobs(jobs: JobsDefinition): JobDefinitionWithName[] {\n return Object.keys(jobs).map(name => {\n return {\n name,\n ...jobs[name],\n }\n })\n }\n\n async runWorkerLoop(config: StartWorkersConfig, workerInstance: WorkerInstance) {\n const names = this.getJobNames(config.jobs)\n logger.debug(\n `Running worker loop [w${workerInstance.workerIndex}] for jobs \"${names.join(', ')}\"...`,\n )\n const jobToRun = await this.jobsRepo.getJobAndLock(names, config.lockTime)\n if (!jobToRun) {\n logger.debug('No job to run')\n return false\n }\n\n logger.debug(`Got job [w${workerInstance.workerIndex}] to run:`, jobToRun)\n await this.executor.executeJob(config.jobs, jobToRun, workerInstance.respawn)\n\n return true\n }\n\n async startWorker(config: StartWorkersConfig, workerInstance: WorkerInstance) {\n while (true) {\n if (!workerInstance.running) {\n logger.info(`Got signal to stop. Stopping worker [w${workerInstance.workerIndex}]...`)\n return\n }\n\n try {\n const didRun = await this.runWorkerLoop(config, workerInstance)\n if (!didRun) await sleep(config.pollInterval)\n if (didRun) await sleep(config.cooldownPeriod)\n } catch (error) {\n logger.error('Error in job runner.', {error})\n await sleep(config.pollInterval)\n }\n }\n }\n\n createWorkersInstanceDefinition(config: StartWorkersConfig): WorkersInstance {\n const workersInstance: WorkersInstance = {\n running: true,\n workersCount: config.workersCount,\n workers: [],\n stop: async () => {\n logger.info('Stopping workers...')\n workersInstance.running = false\n const stopingPromises = workersInstance.workers.map(worker => worker.stop())\n await Promise.all(stopingPromises)\n },\n }\n\n return workersInstance\n }\n\n async ensureRecords(config: StartWorkersConfig) {\n const jobs = this.getJobs(config.jobs)\n\n await Promise.all(\n jobs\n .filter(job => job.type === 'recurrent')\n .map(async job => {\n logger.debug(`Ensuring records for job \"${job.name}\"...`)\n await this.jobsRepo.ensureJobRecord(job)\n }),\n )\n }\n\n async startANewWorker(config: StartWorkersConfig, workersInstance: WorkersInstance) {\n const workerIndex = workersInstance.workers.length\n\n logger.info(`Starting worker [w${workerIndex}]`)\n\n const workerInstance: WorkerInstance = {\n running: true,\n workerIndex,\n stop: async () => {\n logger.info(`Stopping worker [w${workerIndex}]...`)\n workerInstance.running = false\n await workerInstance.promise\n },\n respawn: async () => {\n logger.info(`Respawning worker [w${workerIndex}]...`)\n workerInstance.stop()\n await this.startANewWorker(config, workersInstance)\n },\n }\n\n const workerPromise = this.startWorker(config, workerInstance)\n\n workerInstance.promise = workerPromise\n workersInstance.workers.push(workerInstance)\n }\n\n async runWorkers(config: StartWorkersConfig, workersInstance: WorkersInstance) {\n logger.debug('Will ensure records for recurrent jobs')\n await this.ensureRecords(config)\n\n for (const _ of range(0, config.workersCount)) {\n this.startANewWorker(config, workersInstance)\n }\n }\n\n startWorkers(userConfig: Partial<StartWorkersConfig>): WorkersInstance {\n const defaultConfig: StartWorkersConfig = {\n jobs: {},\n cooldownPeriod: 100,\n pollInterval: 3000,\n workersCount: 4,\n lockTime: 30 * 1000,\n }\n\n const config = {\n ...defaultConfig,\n ...userConfig,\n }\n\n setNameToJobs(config.jobs)\n\n const workersInstance = this.createWorkersInstanceDefinition(config)\n logger.debug('Starting workers', config)\n\n this.runWorkers(config, workersInstance)\n\n return workersInstance\n }\n}\n\nfunction setNameToJobs(jobs: JobsDefinition) {\n return Object.keys(jobs).map(name => {\n jobs[name].jobName = name\n })\n}\n","function _isInteger(n){\n return n << 0 === n\n}\n\nexport const isInteger = Number.isInteger || _isInteger\n\n/**\n * Check if `index` is integer even if it is a string.\n */\nexport const isIndexInteger = index => Number.isInteger(Number(index))\n","import { isInteger } from './isInteger.js'\n\nexport function createPath(path, delimiter = '.'){\n return typeof path === 'string' ?\n path.split(delimiter).map(x => isInteger(x) ? Number(x) : x) :\n path\n}\n","export function compare(a, b){\n return String(a) === String(b)\n}\n","import { compare } from './compare.js'\n\nexport function includes(a, list){\n let index = -1\n const { length } = list\n\n while (++index < length)\n if (compare(list[ index ], a))\n return true\n\n return false\n}\n","import { createPath } from './_internals/createPath.js'\nimport { includes } from './_internals/includes.js'\n\nexport function omit(propsToOmit, obj){\n if (arguments.length === 1) return _obj => omit(propsToOmit, _obj)\n\n if (obj === null || obj === undefined)\n return undefined\n\n const propsToOmitValue = createPath(propsToOmit, ',')\n const willReturn = {}\n\n for (const key in obj)\n if (!includes(key, propsToOmitValue))\n willReturn[ key ] = obj[ key ]\n\n return willReturn\n}\n","export function range(start, end){\n if (arguments.length === 1) return _end => range(start, _end)\n\n if (Number.isNaN(Number(start)) || Number.isNaN(Number(end))){\n throw new TypeError('Both arguments to range must be numbers')\n }\n\n if (end < start) return []\n\n const len = end - start\n const willReturn = Array(len)\n\n for (let i = 0; i < len; i++){\n willReturn[ i ] = start + i\n }\n\n return willReturn\n}\n","import {logger, runWithOrionAsyncContext, updateOrionAsyncContext} from '@orion-js/logger'\nimport {Inject, Service} from '@orion-js/services'\nimport {JobsHistoryRepo} from '../repos/JobsHistoryRepo'\nimport {JobsRepo} from '../repos/JobsRepo'\nimport {JobDefinition, JobsDefinition} from '../types/JobsDefinition'\nimport {ExecutionContext, JobToRun} from '../types/Worker'\nimport {getNextRunDate} from './getNextRunDate'\nimport {trace, SpanStatusCode} from '@opentelemetry/api'\nimport {Blackbox} from '@orion-js/schema'\n\n@Service()\nexport class Executor {\n @Inject(() => JobsRepo)\n private readonly jobsRepo: JobsRepo\n\n @Inject(() => JobsHistoryRepo)\n private readonly jobsHistoryRepo: JobsHistoryRepo\n\n getContext(job: JobDefinition, jobToRun: JobToRun, onStale: Function): ExecutionContext {\n let staleTimeout = setTimeout(() => onStale(), jobToRun.lockTime)\n return {\n definition: job,\n record: jobToRun,\n tries: jobToRun.tries || 0,\n clearStaleTimeout: () => clearTimeout(staleTimeout),\n extendLockTime: async (extraTime: number) => {\n clearTimeout(staleTimeout)\n staleTimeout = setTimeout(() => onStale(), extraTime)\n await this.jobsRepo.extendLockTime(jobToRun.jobId, extraTime)\n },\n logger: logger.addMetadata({\n jobName: jobToRun.name,\n jobId: jobToRun.jobId,\n }),\n }\n }\n\n getJobDefinition(jobToRun: JobToRun, jobs: JobsDefinition) {\n const job = jobs[jobToRun.name]\n\n if (jobToRun.type !== job.type) {\n logger.warn(\n `Job record \"${jobToRun.name}\" is \"${jobToRun.type}\" but definition is \"${job.type}\"`,\n )\n return\n }\n\n return job\n }\n\n async onError(error: any, job: JobDefinition, jobToRun: JobToRun, context: ExecutionContext) {\n const scheduleRecurrent = async () => {\n if (job.type === 'recurrent') {\n await this.jobsRepo.scheduleNextRun({\n jobId: jobToRun.jobId,\n nextRunAt: getNextRunDate(job),\n addTries: false,\n priority: job.priority,\n })\n }\n }\n\n if (!job.onError) {\n context.logger.error(`Error executing job \"${jobToRun.name}\"`, {error})\n await scheduleRecurrent()\n return\n }\n context.logger.info(`Error executing job \"${jobToRun.name}\"`, {error})\n\n const result = await job.onError(error, jobToRun.params, context)\n\n if (result.action === 'dismiss') {\n await scheduleRecurrent()\n return\n }\n\n if (result.action === 'retry') {\n await this.jobsRepo.scheduleNextRun({\n jobId: jobToRun.jobId,\n nextRunAt: getNextRunDate(result),\n addTries: true,\n priority: job.type === 'recurrent' ? job.priority : jobToRun.priority,\n })\n }\n }\n\n async saveExecution(options: {\n startedAt: Date\n status: 'stale' | 'error' | 'success'\n errorMessage?: string\n result?: Blackbox\n job: JobDefinition\n jobToRun: JobToRun\n }) {\n const {startedAt, status, errorMessage, result, job, jobToRun} = options\n const endedAt = new Date()\n\n if (job.saveExecutionsFor !== 0) {\n const oneWeek = 1000 * 60 * 60 * 24 * 7\n const saveExecutionsFor = job.saveExecutionsFor || oneWeek\n await this.jobsHistoryRepo.saveExecution({\n jobId: jobToRun.jobId,\n executionId: jobToRun.executionId,\n jobName: jobToRun.name,\n type: jobToRun.type,\n priority: jobToRun.priority,\n tries: jobToRun.tries,\n uniqueIdentifier: jobToRun.uniqueIdentifier,\n startedAt,\n endedAt,\n duration: endedAt.getTime() - startedAt.getTime(),\n expiresAt: new Date(Date.now() + saveExecutionsFor),\n status,\n errorMessage,\n params: jobToRun.params,\n result,\n })\n }\n }\n\n async afterExecutionSuccess(job: JobDefinition, jobToRun: JobToRun, context: ExecutionContext) {\n if (job.type === 'recurrent') {\n context.logger.debug(`Scheduling next run for recurrent job \"${jobToRun.name}\"`)\n await this.jobsRepo.scheduleNextRun({\n jobId: jobToRun.jobId,\n nextRunAt: getNextRunDate(job),\n addTries: false,\n priority: job.priority,\n })\n }\n if (job.type === 'event') {\n context.logger.debug(`Removing event job after success \"${jobToRun.name}\"`)\n await this.jobsRepo.deleteEventJob(jobToRun.jobId)\n }\n }\n\n async executeJob(jobs: JobsDefinition, jobToRun: JobToRun, respawnWorker: Function) {\n const job = this.getJobDefinition(jobToRun, jobs)\n if (!job) return\n\n const tracer = trace.getTracer('orionjs.dogs', '1.0')\n\n await tracer.startActiveSpan(`job.${jobToRun.name}.${jobToRun.executionId}`, async span => {\n try {\n const startedAt = new Date()\n\n const onStale = async () => {\n if (job.onStale) {\n context.logger.info(`Job \"${jobToRun.name}\" is stale`)\n job.onStale(jobToRun.params, context)\n } else {\n context.logger.error(`Job \"${jobToRun.name}\" is stale`)\n }\n\n await this.jobsRepo.setJobRecordPriority(jobToRun.jobId, 0)\n\n respawnWorker()\n\n this.saveExecution({\n startedAt,\n status: 'stale',\n result: null,\n errorMessage: null,\n job,\n jobToRun,\n })\n }\n\n const context = this.getContext(job, jobToRun, onStale)\n\n const extraContext = {\n controllerType: 'job' as const,\n jobName: jobToRun.name,\n params: jobToRun.params,\n }\n\n await runWithOrionAsyncContext(extraContext, async () => {\n try {\n // Inject async context update\n updateOrionAsyncContext({\n jobName: jobToRun.name,\n params: jobToRun.params,\n })\n const result = await job.resolve(jobToRun.params, context)\n context.clearStaleTimeout()\n\n this.saveExecution({\n startedAt,\n status: 'success',\n result: result || null,\n errorMessage: null,\n job,\n jobToRun,\n })\n\n await this.afterExecutionSuccess(job, jobToRun, context)\n } catch (error) {\n context.clearStaleTimeout()\n this.saveExecution({\n startedAt,\n status: 'error',\n result: null,\n errorMessage: (error as Error).message,\n job,\n jobToRun,\n })\n\n await this.onError(error, job, jobToRun, context)\n }\n })\n } catch (error) {\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: error.message,\n })\n throw error\n } finally {\n span.end()\n }\n })\n }\n}\n","import {Collection, MongoCollection, Repository, MongoDB} from '@orion-js/mongodb'\nimport {omit} from 'rambdax'\nimport {HistoryRecord, HistoryRecordSchema} from '../types/HistoryRecord'\n\n@Repository()\nexport class JobsHistoryRepo {\n @MongoCollection({\n name: 'orionjs.jobs_dogs_history',\n idGeneration: 'uuid',\n schema: HistoryRecordSchema,\n indexes: [\n {\n keys: {\n jobName: 1,\n startedAt: 1,\n },\n },\n {\n keys: {\n executionId: 1,\n },\n },\n {\n keys: {\n expiresAt: 1,\n },\n options: {\n expireAfterSeconds: 0,\n },\n },\n ],\n })\n history: Collection<HistoryRecord>\n\n async saveExecution(record: MongoDB.WithoutId<HistoryRecord>) {\n await this.history.upsert(\n {executionId: record.executionId},\n {\n $setOnInsert: {\n status: record.status,\n },\n $set: {\n ...omit(['status'], record),\n },\n },\n )\n }\n\n async getExecutions(jobName: string, limit?: number, skip?: number): Promise<HistoryRecord[]> {\n const cursor = this.history.find({jobName}).sort({startedAt: -1})\n\n if (skip) {\n cursor.skip(skip)\n }\n\n if (limit) {\n cursor.limit(limit)\n }\n\n return await cursor.toArray()\n }\n}\n","import {InferSchemaType, schemaWithName} from '@orion-js/schema'\n\nexport const HistoryRecordSchema = schemaWithName('HistoryRecord', {\n _id: {type: 'string'},\n jobId: {type: 'string'},\n executionId: {type: 'string'},\n jobName: {type: 'string'},\n type: {type: 'string'},\n priority: {type: 'number'},\n tries: {type: 'number'},\n uniqueIdentifier: {type: 'string', optional: true},\n startedAt: {type: 'date'},\n endedAt: {type: 'date'},\n duration: {type: 'number'},\n expiresAt: {type: 'date', optional: true},\n status: {type: 'string', enum: ['success', 'error', 'stale']},\n errorMessage: {type: 'string', optional: true},\n params: {type: 'blackbox', optional: true},\n result: {type: 'any', optional: true},\n})\n\nexport type HistoryRecord = InferSchemaType<typeof HistoryRecordSchema>\n","import {getInstance, Service} from '@orion-js/services'\nimport {createEventJob, defineJob} from '../defineJob'\nimport type {CreateEventJobOptions, JobDefinition, RecurrentJobDefinition} from '../types'\n\n// Define metadata storage using WeakMaps\nconst serviceMetadata = new WeakMap<any, {_serviceType: string}>()\nconst jobsMetadata = new Map<any, Record<string, any>>()\n\nexport function Jobs() {\n return (target: any, context: ClassDecoratorContext<any>) => {\n Service()(target, context)\n\n context.addInitializer(function (this) {\n serviceMetadata.set(this, {_serviceType: 'jobs'})\n })\n }\n}\n\nexport function RecurrentJob(): (\n method: any,\n context: ClassFieldDecoratorContext | ClassMethodDecoratorContext,\n) => any\nexport function RecurrentJob(\n options: Omit<RecurrentJobDefinition, 'resolve' | 'type'>,\n): (method: any, context: ClassMethodDecoratorContext) => any\nexport function RecurrentJob(options = {}) {\n return (method: any, context: ClassFieldDecoratorContext | ClassMethodDecoratorContext) => {\n const propertyKey = String(context.name)\n\n context.addInitializer(function (this) {\n const jobs = jobsMetadata.get(this) || {}\n\n if (context.kind === 'method') {\n jobs[propertyKey] = defineJob({\n ...options,\n type: 'recurrent',\n resolve: this[propertyKey].bind(this),\n })\n }\n\n if (context.kind === 'field') {\n jobs[propertyKey] = this[propertyKey]\n }\n\n jobsMetadata.set(this, jobs)\n })\n\n return method\n }\n}\n\nexport function EventJob(): (\n method: any,\n context: ClassFieldDecoratorContext | ClassMethodDecoratorContext,\n) => any\nexport function EventJob(\n options: Omit<CreateEventJobOptions<any>, 'resolve'>,\n): (method: any, context: ClassMethodDecoratorContext) => any\nexport function EventJob(options = {}) {\n return (method: any, context: ClassFieldDecoratorContext | ClassMethodDecoratorContext) => {\n const propertyKey = String(context.name)\n\n context.addInitializer(function (this) {\n const jobs = jobsMetadata.get(this) || {}\n\n if (context.kind === 'method') {\n jobs[propertyKey] = createEventJob({\n ...options,\n resolve: this[propertyKey].bind(this),\n })\n }\n\n if (context.kind === 'field') {\n jobs[propertyKey] = this[propertyKey]\n }\n\n jobsMetadata.set(this, jobs)\n })\n\n return method\n }\n}\n\nexport function getServiceJobs(target: any): {\n [key: string]: JobDefinition\n} {\n const instance = getInstance(target)\n\n if (!serviceMetadata.has(instance.constructor)) {\n throw new Error('You must pass a class decorated with @Jobs to getServiceJobs')\n }\n\n const instanceMetadata = serviceMetadata.get(instance.constructor)\n if (instanceMetadata._serviceType !== 'jobs') {\n throw new Error('You must pass a class decorated with @Jobs to getServiceJobs')\n }\n\n const jobsMap = jobsMetadata.get(instance) || {}\n\n return jobsMap\n}\n\n/**\n * Logs\n * after event job {\n job1: { type: 'event', resolve: [Function: bound job1] AsyncFunction }\n}\nbefore recurrent job Map(1) {\n ExampleJobsService {} => {\n job1: { type: 'event', resolve: [Function: bound job1] AsyncFunction }\n }\n}\nbefore recurrent job undefined\nafter recurrent job {\n job2: {\n runEvery: 1000,\n type: 'recurrent',\n resolve: [Function: bound job2] AsyncFunction,\n priority: 100\n }\n}\n{\n serviceJobs: {\n job2: {\n runEvery: 1000,\n type: 'recurrent',\n resolve: [Function: bound job2] AsyncFunction,\n priority: 100\n }\n }\n}\n */\n","import {\n CreateEventJobOptions,\n CreateJobOptions,\n CreateRecurrentJobOptions,\n EventJobDefinition,\n JobDefinition,\n RecurrentJobDefinition,\n} from '../types/JobsDefinition'\nimport {scheduleJob, ScheduleJobsResult, scheduleJobs} from '..'\nimport {ScheduleJobOptionsWithoutName} from '../types/Events'\nimport {cleanAndValidate, SchemaInAnyOrionForm} from '@orion-js/schema'\nimport parse from 'parse-duration'\n\nexport function createEventJob<TParamsSchema extends SchemaInAnyOrionForm>(\n options: CreateEventJobOptions<TParamsSchema>,\n): EventJobDefinition<TParamsSchema> {\n const jobDefinition: EventJobDefinition<TParamsSchema> = {\n ...options,\n type: 'event',\n schedule: null,\n scheduleJobs: null,\n }\n\n jobDefinition.schedule = async (scheduleOptions: ScheduleJobOptionsWithoutName<TParamsSchema>) => {\n if (!jobDefinition.jobName) {\n throw new Error('This job has not been registered in the workers')\n }\n\n const params = jobDefinition.params\n ? await cleanAndValidate(jobDefinition.params, scheduleOptions.params)\n : scheduleOptions.params\n\n return await scheduleJob({\n ...scheduleOptions,\n name: jobDefinition.jobName,\n params,\n })\n }\n\n jobDefinition.scheduleJobs = async (\n jobs: Array<ScheduleJobOptionsWithoutName<TParamsSchema>>,\n ): Promise<ScheduleJobsResult> => {\n if (!jobDefinition.jobName) {\n throw new Error('This job has not been registered in the workers')\n }\n\n // Process all job parameters if schema validation is needed\n const processedJobs = await Promise.all(\n jobs.map(async scheduleOptions => {\n const params = jobDefinition.params\n ? await cleanAndValidate(jobDefinition.params, scheduleOptions.params)\n : scheduleOptions.params\n\n return {\n ...scheduleOptions,\n name: jobDefinition.jobName,\n params,\n }\n }),\n )\n\n return await scheduleJobs(processedJobs)\n }\n\n return jobDefinition\n}\n\nexport function createRecurrentJob(options: CreateRecurrentJobOptions): RecurrentJobDefinition {\n const jobDefinition: RecurrentJobDefinition = {\n ...options,\n priority: options.priority ?? 100,\n type: 'recurrent',\n runEvery: typeof options.runEvery === 'string' ? parse(options.runEvery) : options.runEvery,\n }\n\n return jobDefinition\n}\n\n/**\n * @deprecated Use `createEventJob` or `createRecurrentJob` instead.\n */\nexport const defineJob = (\n options: CreateJobOptions & {type: 'event' | 'recurrent'},\n): JobDefinition => {\n return options.type === 'event'\n ? createEventJob(options as any)\n : createRecurrentJob(options as any)\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAQ,eAAAA,oBAAkB;;;ACA1B,SAAQ,UAAAC,eAAa;AACrB,SAAQ,QAAQ,eAAc;;;ACD9B,SAAQ,kBAAiB;AACzB,SAAQ,cAAa;AACrB,SAA6B,uBAAsB;AAKnD,SAAQ,kBAAiB;;;ACPzB,SAAQ,YAA6B,sBAAqB;AAEnD,IAAM,kBAAkB,eAAe,aAAa;AAAA,EACzD,KAAK,EAAC,MAAM,SAAQ;AAAA,EACpB,SAAS,EAAC,MAAM,SAAQ;AAAA,EACxB,MAAM,EAAC,MAAM,WAAW,WAAW,CAAC,aAAa,OAAO,CAAC,EAAC;AAAA,EAC1D,UAAU,EAAC,MAAM,SAAQ;AAAA,EACzB,kBAAkB,EAAC,MAAM,UAAU,UAAU,KAAI;AAAA,EACjD,WAAW,EAAC,MAAM,OAAM;AAAA,EACxB,WAAW,EAAC,MAAM,QAAQ,UAAU,KAAI;AAAA,EACxC,aAAa,EAAC,MAAM,QAAQ,UAAU,KAAI;AAAA,EAC1C,OAAO,EAAC,MAAM,UAAU,UAAU,KAAI;AAAA,EACtC,QAAQ,EAAC,MAAM,YAAY,UAAU,KAAI;AAC3C,CAAC;;;ADbD;AAUA,wBAAC,WAAW,IAEV,aAAC,gBAAgB;AAAA,EACf,cAAc;AAAA,EACd,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,SAAS;AAAA,IACP;AAAA,MACE,MAAM;AAAA,QACJ,SAAS;AAAA,QACT,UAAU;AAAA,QACV,WAAW;AAAA,MACb;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,QACJ,SAAS;AAAA,MACX;AAAA,MACA,SAAS;AAAA,QACP,QAAQ;AAAA,QACR,yBAAyB,EAAC,MAAM,YAAW;AAAA,MAC7C;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,QACJ,kBAAkB;AAAA,MACpB;AAAA,MACA,SAAS;AAAA,QACP,QAAQ;AAAA,QACR,QAAQ;AAAA,MACV;AAAA,IACF;AAAA,EACF;AACF,CAAC;AAhCI,IAAM,WAAN,MAAe;AAAA,EAAf;AAiCL;AAAA;AAAA,EAEA,MAAM,cAAc,UAAoB,UAAqC;AAC3E,UAAM,cAAc,IAAI,KAAK,KAAK,IAAI,IAAI,QAAQ;AAElD,UAAM,MAAM,MAAM,KAAK,KAAK;AAAA,MAC1B;AAAA,QACE,SAAS,EAAC,KAAK,SAAQ;AAAA,QACvB,WAAW,EAAC,MAAM,oBAAI,KAAK,EAAC;AAAA,QAC5B,KAAK,CAAC,EAAC,aAAa,EAAC,SAAS,MAAK,EAAC,GAAG,EAAC,aAAa,EAAC,MAAM,oBAAI,KAAK,EAAC,EAAC,CAAC;AAAA,MAC1E;AAAA,MACA;AAAA,QACE,MAAM,EAAC,aAAa,WAAW,oBAAI,KAAK,EAAC;AAAA,MAC3C;AAAA,MACA;AAAA,QACE,cAAc;AAAA,UACZ,MAAM;AAAA,YACJ,UAAU;AAAA,YACV,WAAW;AAAA,UACb;AAAA,UACA,gBAAgB;AAAA,QAClB;AAAA,MACF;AAAA,IACF;AAEA,QAAI,CAAC,IAAK;AAEV,QAAI,QAAQ,IAAI,SAAS;AAEzB,QAAI,IAAI,aAAa;AACnB,aAAO,KAAK,gBAAgB,IAAI,OAAO,mBAAmB;AAC1D,WAAK,KAAK,UAAU,IAAI,KAAK,EAAC,MAAM,EAAC,OAAO,EAAC,EAAC,CAAC;AAC/C;AAAA,IACF;AAEA,WAAO;AAAA,MACL,OAAO,IAAI;AAAA,MACX,aAAa,WAAW;AAAA,MACxB,MAAM,IAAI;AAAA,MACV,QAAQ,IAAI;AAAA,MACZ,MAAM,IAAI;AAAA,MACV;AAAA,MACA;AAAA,MACA,UAAU,IAAI;AAAA,MACd,kBAAkB,IAAI;AAAA,IACxB;AAAA,EACF;AAAA,EAEA,MAAM,qBAAqB,OAAe,UAAkB;AAC1D,UAAM,KAAK,KAAK,UAAU,OAAO,EAAC,MAAM,EAAC,SAAQ,EAAC,CAAC;AAAA,EACrD;AAAA,EAEA,MAAM,gBAAgB,SAKnB;AACD,UAAM,UAA2C;AAAA,MAC/C,MAAM;AAAA,QACJ,WAAW,QAAQ;AAAA,QACnB,UAAU,QAAQ;AAAA,QAClB,GAAI,QAAQ,WAAW,CAAC,IAAI,EAAC,OAAO,EAAC;AAAA,MACvC;AAAA,MACA,QAAQ,EAAC,aAAa,GAAE;AAAA,MACxB,GAAI,QAAQ,WAAW,EAAC,MAAM,EAAC,OAAO,EAAC,EAAC,IAAI,CAAC;AAAA,IAC/C;AAEA,UAAM,KAAK,KAAK,UAAU,QAAQ,OAAO,OAAO;AAAA,EAClD;AAAA,EAEA,MAAM,eAAe,OAAe;AAClC,UAAM,KAAK,KAAK,UAAU,EAAC,KAAK,OAAO,MAAM,QAAO,CAAC;AAAA,EACvD;AAAA,EAEA,MAAM,eAAe,OAAe,WAAmB;AACrD,UAAM,cAAc,IAAI,KAAK,KAAK,IAAI,IAAI,SAAS;AACnD,UAAM,KAAK,KAAK;AAAA,MACd;AAAA,QACE,KAAK;AAAA,MACP;AAAA,MACA;AAAA,QACE,MAAM,EAAC,YAAW;AAAA,MACpB;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,gBAAiC;AACrC,UAAM,SAAS,MAAM,KAAK,KAAK;AAAA,MAC7B;AAAA,QACE,aAAa,EAAC,SAAS,KAAI;AAAA,MAC7B;AAAA,MACA;AAAA,QACE,QAAQ,EAAC,aAAa,GAAE;AAAA,MAC1B;AAAA,IACF;AAEA,WAAO,OAAO;AAAA,EAChB;AAAA,EAEA,MAAM,gBAAgB,KAA4B;AAChD,UAAM,SAAS,MAAM,KAAK,KAAK;AAAA,MAC7B;AAAA,QACE,SAAS,IAAI;AAAA,MACf;AAAA,MACA;AAAA,QACE,MAAM;AAAA,UACJ,MAAM,IAAI;AAAA,UACV,UAAW,IAA+B;AAAA,QAC5C;AAAA,QACA,cAAc;AAAA,UACZ,WAAW,oBAAI,KAAK;AAAA,QACtB;AAAA,MACF;AAAA,IACF;AAEA,QAAI,OAAO,YAAY;AACrB,aAAO,MAAM,2BAA2B,IAAI,IAAI,GAAG;AAAA,IACrD,OAAO;AACL,aAAO,MAAM,mBAAmB,IAAI,IAAI,kBAAkB;AAAA,IAC5D;AAAA,EACF;AAAA,EAEA,MAAM,YAAY,SAAmC;AACnD,QAAI;AACF,YAAM,KAAK,KAAK,UAAU;AAAA,QACxB,SAAS,QAAQ;AAAA,QACjB,kBAAkB,QAAQ;AAAA,QAC1B,QAAQ,QAAQ;AAAA,QAChB,WAAW,QAAQ;AAAA,QACnB,UAAU,QAAQ;AAAA,QAClB,MAAM;AAAA,MACR,CAAC;AAAA,IACH,SAAS,OAAO;AACd,UACE,MAAM,qBACN,OAAO,OAAO,MAAM,gBAAgB,EAAE,SAAS,WAAW,KAC1D,QAAQ,kBACR;AACA,eAAO;AAAA,UACL,QAAQ,QAAQ,IAAI,sBAAsB,QAAQ,gBAAgB;AAAA,QACpE;AAAA,MACF,OAAO;AACL,cAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,aAAa,MAA+D;AAChF,QAAI,KAAK,WAAW,GAAG;AACrB,aAAO,EAAC,gBAAgB,GAAG,cAAc,GAAG,QAAQ,CAAC,EAAC;AAAA,IACxD;AAGA,QAAI,iBAAiB;AACrB,QAAI,eAAe;AACnB,UAAM,SAA8E,CAAC;AAErF,aAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,YAAM,MAAM,KAAK,CAAC;AAClB,UAAI;AAEF,cAAM,KAAK,KAAK,UAAU;AAAA,UACxB,SAAS,IAAI;AAAA,UACb,kBAAkB,IAAI;AAAA,UACtB,QAAQ,IAAI;AAAA,UACZ,WAAW,IAAI;AAAA,UACf,UAAU,IAAI;AAAA,UACd,MAAM;AAAA,QACR,CAAC;AACD;AAAA,MACF,SAAS,OAAO;AAEd,YACE,MAAM,qBACN,OAAO,OAAO,MAAM,gBAAgB,EAAE,SAAS,WAAW,KAC1D,IAAI,kBACJ;AACA,iBAAO,KAAK,QAAQ,IAAI,IAAI,sBAAsB,IAAI,gBAAgB,kBAAkB;AACxF;AAAA,QACF,OAAO;AACL,iBAAO,KAAK;AAAA,YACV,OAAO;AAAA,YACP,OAAO,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AAAA,YAC/D;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,MACL,aAAa,cAAc,+BAA+B,YAAY,aAAa,OAAO,MAAM;AAAA,IAClG;AAEA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAzOO;AAiCL,oCAhCA,WADW;AAAA,WAAN,wCADP,sBACa;AAAN,4BAAM;;;AEJN,IAAM,iBAAiB,CAAC,YAAqB;AAClD,MAAI,QAAQ,OAAO;AACjB,WAAO,IAAI,KAAK,KAAK,IAAI,IAAI,QAAQ,KAAK;AAAA,EAC5C;AAEA,MAAI,QAAQ,UAAU;AACpB,WAAO,IAAI,KAAK,KAAK,IAAI,IAAI,QAAQ,QAAQ;AAAA,EAC/C;AAEA,MAAI,QAAQ,OAAO;AACjB,WAAO,QAAQ;AAAA,EACjB;AAEA,MAAI,QAAQ,YAAY;AACtB,WAAO,QAAQ,WAAW;AAAA,EAC5B;AAEA,SAAO,oBAAI,KAAK;AAClB;;;AHzBA,8CAAAC;AAMA,6BAAC,QAAQ,IAEP,iBAAC,OAAO,MAAM,QAAQ;AADjB,IAAM,gBAAN,MAAoB;AAAA,EAApB;AAEL,wBAAQ,YAAR,kBAAAA,QAAA,6BAAAA,QAAA;AAAA;AAAA,EAEA,MAAM,YAAY,SAA6B;AAC7C,IAAAC,QAAO,MAAM,qBAAqB,OAAO;AAEzC,UAAM,KAAK,SAAS,YAAY;AAAA,MAC9B,MAAM,QAAQ;AAAA,MACd,UAAU,QAAQ,YAAY;AAAA,MAC9B,WAAW,eAAe,OAAO;AAAA,MACjC,QAAQ,QAAQ,UAAU;AAAA,MAC1B,kBAAkB,QAAQ;AAAA,IAC5B,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,aAAa,MAAwD;AACzE,IAAAA,QAAO,MAAM,cAAc,KAAK,MAAM,UAAU;AAEhD,UAAM,aAAa,KAAK,IAAI,cAAY;AAAA,MACtC,MAAM,QAAQ;AAAA,MACd,UAAU,QAAQ,YAAY;AAAA,MAC9B,WAAW,eAAe,OAAO;AAAA,MACjC,QAAQ,QAAQ,UAAU;AAAA,MAC1B,kBAAkB,QAAQ;AAAA,IAC5B,EAAE;AAEF,WAAO,MAAM,KAAK,SAAS,aAAa,UAAU;AAAA,EACpD;AACF;AA7BOD,SAAA;AAEL,kBAAAA,QAAA,GAAQ,YADR,eADW;AAAA,gBAAN,kBAAAA,QAAA,oBADP,2BACa;AAAN,kBAAAA,QAAA,GAAM;;;AIPb,SAAQ,UAAAE,SAAQ,WAAAC,gBAAc;;;ACA9B,SAAS,WAAW,GAAE;AACpB,SAAO,KAAK,MAAM;AACpB;AAEO,IAAM,YAAY,OAAO,aAAa;;;ACFtC,SAAS,WAAW,MAAM,YAAY,KAAI;AAC/C,SAAO,OAAO,SAAS,WACrB,KAAK,MAAM,SAAS,EAAE,IAAI,OAAK,UAAU,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,IAC3D;AACJ;;;ACNO,SAAS,QAAQ,GAAG,GAAE;AAC3B,SAAO,OAAO,CAAC,MAAM,OAAO,CAAC;AAC/B;;;ACAO,SAAS,SAAS,GAAG,MAAK;AAC/B,MAAI,QAAQ;AACZ,QAAM,EAAE,OAAO,IAAI;AAEnB,SAAO,EAAE,QAAQ;AACf,QAAI,QAAQ,KAAM,KAAM,GAAG,CAAC;AAC1B,aAAO;AAEX,SAAO;AACT;;;ACRO,SAAS,KAAK,aAAa,KAAI;AACpC,MAAI,UAAU,WAAW,EAAG,QAAO,UAAQ,KAAK,aAAa,IAAI;AAEjE,MAAI,QAAQ,QAAQ,QAAQ;AAC1B,WAAO;AAET,QAAM,mBAAmB,WAAW,aAAa,GAAG;AACpD,QAAM,aAAa,CAAC;AAEpB,aAAW,OAAO;AAChB,QAAI,CAAC,SAAS,KAAK,gBAAgB;AACjC,iBAAY,GAAI,IAAI,IAAK,GAAI;AAEjC,SAAO;AACT;;;ACjBO,SAAS,MAAM,OAAO,KAAI;AAC/B,MAAI,UAAU,WAAW,EAAG,QAAO,UAAQ,MAAM,OAAO,IAAI;AAE5D,MAAI,OAAO,MAAM,OAAO,KAAK,CAAC,KAAK,OAAO,MAAM,OAAO,GAAG,CAAC,GAAE;AAC3D,UAAM,IAAI,UAAU,yCAAyC;AAAA,EAC/D;AAEA,MAAI,MAAM,MAAO,QAAO,CAAC;AAEzB,QAAM,MAAM,MAAM;AAClB,QAAM,aAAa,MAAM,GAAG;AAE5B,WAAS,IAAI,GAAG,IAAI,KAAK,KAAI;AAC3B,eAAY,CAAE,IAAI,QAAQ;AAAA,EAC5B;AAEA,SAAO;AACT;;;ANZA,SAAQ,aAAY;;;AOLpB,SAAQ,UAAAC,SAAQ,0BAA0B,+BAA8B;AACxE,SAAQ,UAAAC,SAAQ,WAAAC,gBAAc;;;ACD9B,SAAoB,mBAAAC,kBAAiB,cAAAC,mBAA0B;;;ACA/D,SAAyB,kBAAAC,uBAAqB;AAEvC,IAAM,sBAAsBA,gBAAe,iBAAiB;AAAA,EACjE,KAAK,EAAC,MAAM,SAAQ;AAAA,EACpB,OAAO,EAAC,MAAM,SAAQ;AAAA,EACtB,aAAa,EAAC,MAAM,SAAQ;AAAA,EAC5B,SAAS,EAAC,MAAM,SAAQ;AAAA,EACxB,MAAM,EAAC,MAAM,SAAQ;AAAA,EACrB,UAAU,EAAC,MAAM,SAAQ;AAAA,EACzB,OAAO,EAAC,MAAM,SAAQ;AAAA,EACtB,kBAAkB,EAAC,MAAM,UAAU,UAAU,KAAI;AAAA,EACjD,WAAW,EAAC,MAAM,OAAM;AAAA,EACxB,SAAS,EAAC,MAAM,OAAM;AAAA,EACtB,UAAU,EAAC,MAAM,SAAQ;AAAA,EACzB,WAAW,EAAC,MAAM,QAAQ,UAAU,KAAI;AAAA,EACxC,QAAQ,EAAC,MAAM,UAAU,MAAM,CAAC,WAAW,SAAS,OAAO,EAAC;AAAA,EAC5D,cAAc,EAAC,MAAM,UAAU,UAAU,KAAI;AAAA,EAC7C,QAAQ,EAAC,MAAM,YAAY,UAAU,KAAI;AAAA,EACzC,QAAQ,EAAC,MAAM,OAAO,UAAU,KAAI;AACtC,CAAC;;;ADnBD,+CAAAC;AAIA,+BAACC,YAAW,IAEV,gBAACC,iBAAgB;AAAA,EACf,MAAM;AAAA,EACN,cAAc;AAAA,EACd,QAAQ;AAAA,EACR,SAAS;AAAA,IACP;AAAA,MACE,MAAM;AAAA,QACJ,SAAS;AAAA,QACT,WAAW;AAAA,MACb;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,QACJ,aAAa;AAAA,MACf;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,QACJ,WAAW;AAAA,MACb;AAAA,MACA,SAAS;AAAA,QACP,oBAAoB;AAAA,MACtB;AAAA,IACF;AAAA,EACF;AACF,CAAC;AA1BI,IAAM,kBAAN,MAAsB;AAAA,EAAtB;AA2BL,qDAAAF,QAAA,6BAAAA,QAAA;AAAA;AAAA,EAEA,MAAM,cAAc,QAA0C;AAC5D,UAAM,KAAK,QAAQ;AAAA,MACjB,EAAC,aAAa,OAAO,YAAW;AAAA,MAChC;AAAA,QACE,cAAc;AAAA,UACZ,QAAQ,OAAO;AAAA,QACjB;AAAA,QACA,MAAM;AAAA,UACJ,GAAG,KAAK,CAAC,QAAQ,GAAG,MAAM;AAAA,QAC5B;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,cAAc,SAAiB,OAAgB,MAAyC;AAC5F,UAAM,SAAS,KAAK,QAAQ,KAAK,EAAC,QAAO,CAAC,EAAE,KAAK,EAAC,WAAW,GAAE,CAAC;AAEhE,QAAI,MAAM;AACR,aAAO,KAAK,IAAI;AAAA,IAClB;AAEA,QAAI,OAAO;AACT,aAAO,MAAM,KAAK;AAAA,IACpB;AAEA,WAAO,MAAM,OAAO,QAAQ;AAAA,EAC9B;AACF;AAxDOA,SAAA;AA2BL,kBAAAA,QAAA,cA1BA,cADW;AAAA,kBAAN,kBAAAA,QAAA,sBADP,6BACa;AAAN,kBAAAA,QAAA,GAAM;;;ADEb,SAAQ,OAAO,sBAAqB;AAPpC,0BAAAG,gBAAA,sBAAAC;AAUA,wBAACC,SAAQ,IAEPF,iBAAA,CAACG,QAAO,MAAM,QAAQ,IAGtB,wBAACA,QAAO,MAAM,eAAe;AAJxB,IAAM,WAAN,MAAe;AAAA,EAAf;AAEL,wBAAiB,YAAjB,kBAAAF,QAAA,6BAAAA,QAAA;AAGA,wBAAiB,mBAAjB,kBAAAA,QAAA,8BAAAA,QAAA;AAAA;AAAA,EAEA,WAAW,KAAoB,UAAoB,SAAqC;AACtF,QAAI,eAAe,WAAW,MAAM,QAAQ,GAAG,SAAS,QAAQ;AAChE,WAAO;AAAA,MACL,YAAY;AAAA,MACZ,QAAQ;AAAA,MACR,OAAO,SAAS,SAAS;AAAA,MACzB,mBAAmB,MAAM,aAAa,YAAY;AAAA,MAClD,gBAAgB,OAAO,cAAsB;AAC3C,qBAAa,YAAY;AACzB,uBAAe,WAAW,MAAM,QAAQ,GAAG,SAAS;AACpD,cAAM,KAAK,SAAS,eAAe,SAAS,OAAO,SAAS;AAAA,MAC9D;AAAA,MACA,QAAQG,QAAO,YAAY;AAAA,QACzB,SAAS,SAAS;AAAA,QAClB,OAAO,SAAS;AAAA,MAClB,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,iBAAiB,UAAoB,MAAsB;AACzD,UAAM,MAAM,KAAK,SAAS,IAAI;AAE9B,QAAI,SAAS,SAAS,IAAI,MAAM;AAC9B,MAAAA,QAAO;AAAA,QACL,eAAe,SAAS,IAAI,SAAS,SAAS,IAAI,wBAAwB,IAAI,IAAI;AAAA,MACpF;AACA;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,QAAQ,OAAY,KAAoB,UAAoB,SAA2B;AAC3F,UAAM,oBAAoB,YAAY;AACpC,UAAI,IAAI,SAAS,aAAa;AAC5B,cAAM,KAAK,SAAS,gBAAgB;AAAA,UAClC,OAAO,SAAS;AAAA,UAChB,WAAW,eAAe,GAAG;AAAA,UAC7B,UAAU;AAAA,UACV,UAAU,IAAI;AAAA,QAChB,CAAC;AAAA,MACH;AAAA,IACF;AAEA,QAAI,CAAC,IAAI,SAAS;AAChB,cAAQ,OAAO,MAAM,wBAAwB,SAAS,IAAI,KAAK,EAAC,MAAK,CAAC;AACtE,YAAM,kBAAkB;AACxB;AAAA,IACF;AACA,YAAQ,OAAO,KAAK,wBAAwB,SAAS,IAAI,KAAK,EAAC,MAAK,CAAC;AAErE,UAAM,SAAS,MAAM,IAAI,QAAQ,OAAO,SAAS,QAAQ,OAAO;AAEhE,QAAI,OAAO,WAAW,WAAW;AAC/B,YAAM,kBAAkB;AACxB;AAAA,IACF;AAEA,QAAI,OAAO,WAAW,SAAS;AAC7B,YAAM,KAAK,SAAS,gBAAgB;AAAA,QAClC,OAAO,SAAS;AAAA,QAChB,WAAW,eAAe,MAAM;AAAA,QAChC,UAAU;AAAA,QACV,UAAU,IAAI,SAAS,cAAc,IAAI,WAAW,SAAS;AAAA,MAC/D,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,MAAM,cAAc,SAOjB;AACD,UAAM,EAAC,WAAW,QAAQ,cAAc,QAAQ,KAAK,SAAQ,IAAI;AACjE,UAAM,UAAU,oBAAI,KAAK;AAEzB,QAAI,IAAI,sBAAsB,GAAG;AAC/B,YAAM,UAAU,MAAO,KAAK,KAAK,KAAK;AACtC,YAAM,oBAAoB,IAAI,qBAAqB;AACnD,YAAM,KAAK,gBAAgB,cAAc;AAAA,QACvC,OAAO,SAAS;AAAA,QAChB,aAAa,SAAS;AAAA,QACtB,SAAS,SAAS;AAAA,QAClB,MAAM,SAAS;AAAA,QACf,UAAU,SAAS;AAAA,QACnB,OAAO,SAAS;AAAA,QAChB,kBAAkB,SAAS;AAAA,QAC3B;AAAA,QACA;AAAA,QACA,UAAU,QAAQ,QAAQ,IAAI,UAAU,QAAQ;AAAA,QAChD,WAAW,IAAI,KAAK,KAAK,IAAI,IAAI,iBAAiB;AAAA,QAClD;AAAA,QACA;AAAA,QACA,QAAQ,SAAS;AAAA,QACjB;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,MAAM,sBAAsB,KAAoB,UAAoB,SAA2B;AAC7F,QAAI,IAAI,SAAS,aAAa;AAC5B,cAAQ,OAAO,MAAM,0CAA0C,SAAS,IAAI,GAAG;AAC/E,YAAM,KAAK,SAAS,gBAAgB;AAAA,QAClC,OAAO,SAAS;AAAA,QAChB,WAAW,eAAe,GAAG;AAAA,QAC7B,UAAU;AAAA,QACV,UAAU,IAAI;AAAA,MAChB,CAAC;AAAA,IACH;AACA,QAAI,IAAI,SAAS,SAAS;AACxB,cAAQ,OAAO,MAAM,qCAAqC,SAAS,IAAI,GAAG;AAC1E,YAAM,KAAK,SAAS,eAAe,SAAS,KAAK;AAAA,IACnD;AAAA,EACF;AAAA,EAEA,MAAM,WAAW,MAAsB,UAAoB,eAAyB;AAClF,UAAM,MAAM,KAAK,iBAAiB,UAAU,IAAI;AAChD,QAAI,CAAC,IAAK;AAEV,UAAM,SAAS,MAAM,UAAU,gBAAgB,KAAK;AAEpD,UAAM,OAAO,gBAAgB,OAAO,SAAS,IAAI,IAAI,SAAS,WAAW,IAAI,OAAM,SAAQ;AACzF,UAAI;AACF,cAAM,YAAY,oBAAI,KAAK;AAE3B,cAAM,UAAU,YAAY;AAC1B,cAAI,IAAI,SAAS;AACf,oBAAQ,OAAO,KAAK,QAAQ,SAAS,IAAI,YAAY;AACrD,gBAAI,QAAQ,SAAS,QAAQ,OAAO;AAAA,UACtC,OAAO;AACL,oBAAQ,OAAO,MAAM,QAAQ,SAAS,IAAI,YAAY;AAAA,UACxD;AAEA,gBAAM,KAAK,SAAS,qBAAqB,SAAS,OAAO,CAAC;AAE1D,wBAAc;AAEd,eAAK,cAAc;AAAA,YACjB;AAAA,YACA,QAAQ;AAAA,YACR,QAAQ;AAAA,YACR,cAAc;AAAA,YACd;AAAA,YACA;AAAA,UACF,CAAC;AAAA,QACH;AAEA,cAAM,UAAU,KAAK,WAAW,KAAK,UAAU,OAAO;AAEtD,cAAM,eAAe;AAAA,UACnB,gBAAgB;AAAA,UAChB,SAAS,SAAS;AAAA,UAClB,QAAQ,SAAS;AAAA,QACnB;AAEA,cAAM,yBAAyB,cAAc,YAAY;AACvD,cAAI;AAEF,oCAAwB;AAAA,cACtB,SAAS,SAAS;AAAA,cAClB,QAAQ,SAAS;AAAA,YACnB,CAAC;AACD,kBAAM,SAAS,MAAM,IAAI,QAAQ,SAAS,QAAQ,OAAO;AACzD,oBAAQ,kBAAkB;AAE1B,iBAAK,cAAc;AAAA,cACjB;AAAA,cACA,QAAQ;AAAA,cACR,QAAQ,UAAU;AAAA,cAClB,cAAc;AAAA,cACd;AAAA,cACA;AAAA,YACF,CAAC;AAED,kBAAM,KAAK,sBAAsB,KAAK,UAAU,OAAO;AAAA,UACzD,SAAS,OAAO;AACd,oBAAQ,kBAAkB;AAC1B,iBAAK,cAAc;AAAA,cACjB;AAAA,cACA,QAAQ;AAAA,cACR,QAAQ;AAAA,cACR,cAAe,MAAgB;AAAA,cAC/B;AAAA,cACA;AAAA,YACF,CAAC;AAED,kBAAM,KAAK,QAAQ,OAAO,KAAK,UAAU,OAAO;AAAA,UAClD;AAAA,QACF,CAAC;AAAA,MACH,SAAS,OAAO;AACd,aAAK,UAAU;AAAA,UACb,MAAM,eAAe;AAAA,UACrB,SAAS,MAAM;AAAA,QACjB,CAAC;AACD,cAAM;AAAA,MACR,UAAE;AACA,aAAK,IAAI;AAAA,MACX;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAlNOH,SAAA;AAEL,kBAAAA,QAAA,GAAiB,YADjBD,gBADW;AAKX,kBAAAC,QAAA,GAAiB,mBADjB,sBAJW;AAAA,WAAN,kBAAAA,QAAA,eADP,sBACa;AAAN,kBAAAA,QAAA,GAAM;;;APHb,SAAQ,UAAAI,eAAa;AARrB,mBAAAC,gBAAA,2BAAAC;AAUA,6BAACC,SAAQ,IAEPF,iBAAA,CAACG,QAAO,MAAM,QAAQ,IAGtB,iBAACA,QAAO,MAAM,QAAQ;AAJjB,IAAM,gBAAN,MAAoB;AAAA,EAApB;AAEL,wBAAQ,YAAR,kBAAAF,QAAA,6BAAAA,QAAA;AAGA,wBAAQ,YAAR,kBAAAA,QAAA,8BAAAA,QAAA;AAAA;AAAA,EAEA,YAAY,MAAsB;AAChC,WAAO,OAAO,KAAK,IAAI;AAAA,EACzB;AAAA,EAEA,QAAQ,MAA+C;AACrD,WAAO,OAAO,KAAK,IAAI,EAAE,IAAI,UAAQ;AACnC,aAAO;AAAA,QACL;AAAA,QACA,GAAG,KAAK,IAAI;AAAA,MACd;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,cAAc,QAA4B,gBAAgC;AAC9E,UAAM,QAAQ,KAAK,YAAY,OAAO,IAAI;AAC1C,IAAAG,QAAO;AAAA,MACL,yBAAyB,eAAe,WAAW,eAAe,MAAM,KAAK,IAAI,CAAC;AAAA,IACpF;AACA,UAAM,WAAW,MAAM,KAAK,SAAS,cAAc,OAAO,OAAO,QAAQ;AACzE,QAAI,CAAC,UAAU;AACb,MAAAA,QAAO,MAAM,eAAe;AAC5B,aAAO;AAAA,IACT;AAEA,IAAAA,QAAO,MAAM,aAAa,eAAe,WAAW,aAAa,QAAQ;AACzE,UAAM,KAAK,SAAS,WAAW,OAAO,MAAM,UAAU,eAAe,OAAO;AAE5E,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,YAAY,QAA4B,gBAAgC;AAC5E,WAAO,MAAM;AACX,UAAI,CAAC,eAAe,SAAS;AAC3B,QAAAA,QAAO,KAAK,yCAAyC,eAAe,WAAW,MAAM;AACrF;AAAA,MACF;AAEA,UAAI;AACF,cAAM,SAAS,MAAM,KAAK,cAAc,QAAQ,cAAc;AAC9D,YAAI,CAAC,OAAQ,OAAM,MAAM,OAAO,YAAY;AAC5C,YAAI,OAAQ,OAAM,MAAM,OAAO,cAAc;AAAA,MAC/C,SAAS,OAAO;AACd,QAAAA,QAAO,MAAM,wBAAwB,EAAC,MAAK,CAAC;AAC5C,cAAM,MAAM,OAAO,YAAY;AAAA,MACjC;AAAA,IACF;AAAA,EACF;AAAA,EAEA,gCAAgC,QAA6C;AAC3E,UAAM,kBAAmC;AAAA,MACvC,SAAS;AAAA,MACT,cAAc,OAAO;AAAA,MACrB,SAAS,CAAC;AAAA,MACV,MAAM,YAAY;AAChB,QAAAA,QAAO,KAAK,qBAAqB;AACjC,wBAAgB,UAAU;AAC1B,cAAM,kBAAkB,gBAAgB,QAAQ,IAAI,YAAU,OAAO,KAAK,CAAC;AAC3E,cAAM,QAAQ,IAAI,eAAe;AAAA,MACnC;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,cAAc,QAA4B;AAC9C,UAAM,OAAO,KAAK,QAAQ,OAAO,IAAI;AAErC,UAAM,QAAQ;AAAA,MACZ,KACG,OAAO,SAAO,IAAI,SAAS,WAAW,EACtC,IAAI,OAAM,QAAO;AAChB,QAAAA,QAAO,MAAM,6BAA6B,IAAI,IAAI,MAAM;AACxD,cAAM,KAAK,SAAS,gBAAgB,GAAG;AAAA,MACzC,CAAC;AAAA,IACL;AAAA,EACF;AAAA,EAEA,MAAM,gBAAgB,QAA4B,iBAAkC;AAClF,UAAM,cAAc,gBAAgB,QAAQ;AAE5C,IAAAA,QAAO,KAAK,qBAAqB,WAAW,GAAG;AAE/C,UAAM,iBAAiC;AAAA,MACrC,SAAS;AAAA,MACT;AAAA,MACA,MAAM,YAAY;AAChB,QAAAA,QAAO,KAAK,qBAAqB,WAAW,MAAM;AAClD,uBAAe,UAAU;AACzB,cAAM,eAAe;AAAA,MACvB;AAAA,MACA,SAAS,YAAY;AACnB,QAAAA,QAAO,KAAK,uBAAuB,WAAW,MAAM;AACpD,uBAAe,KAAK;AACpB,cAAM,KAAK,gBAAgB,QAAQ,eAAe;AAAA,MACpD;AAAA,IACF;AAEA,UAAM,gBAAgB,KAAK,YAAY,QAAQ,cAAc;AAE7D,mBAAe,UAAU;AACzB,oBAAgB,QAAQ,KAAK,cAAc;AAAA,EAC7C;AAAA,EAEA,MAAM,WAAW,QAA4B,iBAAkC;AAC7E,IAAAA,QAAO,MAAM,wCAAwC;AACrD,UAAM,KAAK,cAAc,MAAM;AAE/B,eAAW,KAAK,MAAM,GAAG,OAAO,YAAY,GAAG;AAC7C,WAAK,gBAAgB,QAAQ,eAAe;AAAA,IAC9C;AAAA,EACF;AAAA,EAEA,aAAa,YAA0D;AACrE,UAAM,gBAAoC;AAAA,MACxC,MAAM,CAAC;AAAA,MACP,gBAAgB;AAAA,MAChB,cAAc;AAAA,MACd,cAAc;AAAA,MACd,UAAU,KAAK;AAAA,IACjB;AAEA,UAAM,SAAS;AAAA,MACb,GAAG;AAAA,MACH,GAAG;AAAA,IACL;AAEA,kBAAc,OAAO,IAAI;AAEzB,UAAM,kBAAkB,KAAK,gCAAgC,MAAM;AACnE,IAAAA,QAAO,MAAM,oBAAoB,MAAM;AAEvC,SAAK,WAAW,QAAQ,eAAe;AAEvC,WAAO;AAAA,EACT;AACF;AA9IOH,SAAA;AAEL,kBAAAA,QAAA,GAAQ,YADRD,gBADW;AAKX,kBAAAC,QAAA,GAAQ,YADR,eAJW;AAAA,gBAAN,kBAAAA,QAAA,oBADP,2BACa;AAAN,kBAAAA,QAAA,GAAM;AAgJb,SAAS,cAAc,MAAsB;AAC3C,SAAO,OAAO,KAAK,IAAI,EAAE,IAAI,UAAQ;AACnC,SAAK,IAAI,EAAE,UAAU;AAAA,EACvB,CAAC;AACH;;;AU/JA,SAAQ,aAAa,WAAAI,gBAAc;;;ACUnC,SAAQ,wBAA6C;AACrD,OAAO,WAAW;AAEX,SAAS,eACd,SACmC;AACnC,QAAM,gBAAmD;AAAA,IACvD,GAAG;AAAA,IACH,MAAM;AAAA,IACN,UAAU;AAAA,IACV,cAAc;AAAA,EAChB;AAEA,gBAAc,WAAW,OAAO,oBAAkE;AAChG,QAAI,CAAC,cAAc,SAAS;AAC1B,YAAM,IAAI,MAAM,iDAAiD;AAAA,IACnE;AAEA,UAAM,SAAS,cAAc,SACzB,MAAM,iBAAiB,cAAc,QAAQ,gBAAgB,MAAM,IACnE,gBAAgB;AAEpB,WAAO,MAAM,YAAY;AAAA,MACvB,GAAG;AAAA,MACH,MAAM,cAAc;AAAA,MACpB;AAAA,IACF,CAAC;AAAA,EACH;AAEA,gBAAc,eAAe,OAC3B,SACgC;AAChC,QAAI,CAAC,cAAc,SAAS;AAC1B,YAAM,IAAI,MAAM,iDAAiD;AAAA,IACnE;AAGA,UAAM,gBAAgB,MAAM,QAAQ;AAAA,MAClC,KAAK,IAAI,OAAM,oBAAmB;AAChC,cAAM,SAAS,cAAc,SACzB,MAAM,iBAAiB,cAAc,QAAQ,gBAAgB,MAAM,IACnE,gBAAgB;AAEpB,eAAO;AAAA,UACL,GAAG;AAAA,UACH,MAAM,cAAc;AAAA,UACpB;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH;AAEA,WAAO,MAAM,aAAa,aAAa;AAAA,EACzC;AAEA,SAAO;AACT;AAEO,SAAS,mBAAmB,SAA4D;AAC7F,QAAM,gBAAwC;AAAA,IAC5C,GAAG;AAAA,IACH,UAAU,QAAQ,YAAY;AAAA,IAC9B,MAAM;AAAA,IACN,UAAU,OAAO,QAAQ,aAAa,WAAW,MAAM,QAAQ,QAAQ,IAAI,QAAQ;AAAA,EACrF;AAEA,SAAO;AACT;AAKO,IAAM,YAAY,CACvB,YACkB;AAClB,SAAO,QAAQ,SAAS,UACpB,eAAe,OAAc,IAC7B,mBAAmB,OAAc;AACvC;;;ADlFA,IAAM,kBAAkB,oBAAI,QAAqC;AACjE,IAAM,eAAe,oBAAI,IAA8B;AAEhD,SAAS,OAAO;AACrB,SAAO,CAAC,QAAa,YAAwC;AAC3D,IAAAC,SAAQ,EAAE,QAAQ,OAAO;AAEzB,YAAQ,eAAe,WAAgB;AACrC,sBAAgB,IAAI,MAAM,EAAC,cAAc,OAAM,CAAC;AAAA,IAClD,CAAC;AAAA,EACH;AACF;AASO,SAAS,aAAa,UAAU,CAAC,GAAG;AACzC,SAAO,CAAC,QAAa,YAAsE;AACzF,UAAM,cAAc,OAAO,QAAQ,IAAI;AAEvC,YAAQ,eAAe,WAAgB;AACrC,YAAM,OAAO,aAAa,IAAI,IAAI,KAAK,CAAC;AAExC,UAAI,QAAQ,SAAS,UAAU;AAC7B,aAAK,WAAW,IAAI,UAAU;AAAA,UAC5B,GAAG;AAAA,UACH,MAAM;AAAA,UACN,SAAS,KAAK,WAAW,EAAE,KAAK,IAAI;AAAA,QACtC,CAAC;AAAA,MACH;AAEA,UAAI,QAAQ,SAAS,SAAS;AAC5B,aAAK,WAAW,IAAI,KAAK,WAAW;AAAA,MACtC;AAEA,mBAAa,IAAI,MAAM,IAAI;AAAA,IAC7B,CAAC;AAED,WAAO;AAAA,EACT;AACF;AASO,SAAS,SAAS,UAAU,CAAC,GAAG;AACrC,SAAO,CAAC,QAAa,YAAsE;AACzF,UAAM,cAAc,OAAO,QAAQ,IAAI;AAEvC,YAAQ,eAAe,WAAgB;AACrC,YAAM,OAAO,aAAa,IAAI,IAAI,KAAK,CAAC;AAExC,UAAI,QAAQ,SAAS,UAAU;AAC7B,aAAK,WAAW,IAAI,eAAe;AAAA,UACjC,GAAG;AAAA,UACH,SAAS,KAAK,WAAW,EAAE,KAAK,IAAI;AAAA,QACtC,CAAC;AAAA,MACH;AAEA,UAAI,QAAQ,SAAS,SAAS;AAC5B,aAAK,WAAW,IAAI,KAAK,WAAW;AAAA,MACtC;AAEA,mBAAa,IAAI,MAAM,IAAI;AAAA,IAC7B,CAAC;AAED,WAAO;AAAA,EACT;AACF;AAEO,SAAS,eAAe,QAE7B;AACA,QAAM,WAAW,YAAY,MAAM;AAEnC,MAAI,CAAC,gBAAgB,IAAI,SAAS,WAAW,GAAG;AAC9C,UAAM,IAAI,MAAM,8DAA8D;AAAA,EAChF;AAEA,QAAM,mBAAmB,gBAAgB,IAAI,SAAS,WAAW;AACjE,MAAI,iBAAiB,iBAAiB,QAAQ;AAC5C,UAAM,IAAI,MAAM,8DAA8D;AAAA,EAChF;AAEA,QAAM,UAAU,aAAa,IAAI,QAAQ,KAAK,CAAC;AAE/C,SAAO;AACT;;;AfvFA,IAAM,gBAAgBC,aAAY,aAAa;AAC/C,IAAM,gBAAgBA,aAAY,aAAa;AAC/C,IAAM,kBAAkBA,aAAY,eAAe;AACnD,IAAM,WAAWA,aAAY,QAAQ;AAErC,IAAM,eAAe,CAAC,WAAwC;AAC5D,SAAO,cAAc,aAAa,MAAM;AAC1C;AAKA,IAAM,cAAc,CAClB,YACG;AACH,SAAO,cAAc,YAAY,OAAO;AAC1C;AAMA,IAAM,eAAe,CACnB,SACgC;AAChC,SAAO,cAAc,aAAa,IAAI;AACxC;","names":["getInstance","logger","_init","logger","Inject","Service","logger","Inject","Service","MongoCollection","Repository","schemaWithName","_init","Repository","MongoCollection","_jobsRepo_dec","_init","Service","Inject","logger","logger","_jobsRepo_dec","_init","Service","Inject","logger","Service","Service","getInstance"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/services/EventsService.ts","../src/repos/JobsRepo.ts","../src/types/JobRecord.ts","../src/services/getNextRunDate.ts","../src/services/WorkerService.ts","../../../node_modules/.pnpm/rambdax@11.3.1/node_modules/rambdax/src/_internals/isInteger.js","../../../node_modules/.pnpm/rambdax@11.3.1/node_modules/rambdax/src/_internals/createPath.js","../../../node_modules/.pnpm/rambdax@11.3.1/node_modules/rambdax/src/_internals/compare.js","../../../node_modules/.pnpm/rambdax@11.3.1/node_modules/rambdax/src/_internals/includes.js","../../../node_modules/.pnpm/rambdax@11.3.1/node_modules/rambdax/src/omit.js","../../../node_modules/.pnpm/rambdax@11.3.1/node_modules/rambdax/src/range.js","../src/services/Executor.ts","../src/repos/JobsHistoryRepo.ts","../src/types/HistoryRecord.ts","../src/service/index.ts","../src/defineJob/index.ts"],"sourcesContent":["import {getInstance} from '@orion-js/services'\nimport {EventsService} from './services/EventsService'\nimport {WorkerService} from './services/WorkerService'\nimport {StartWorkersConfig} from './types/StartConfig'\nimport {ScheduleJobOptions, ScheduleJobsOptions, ScheduleJobsResult} from './types/Events'\nimport {JobsHistoryRepo} from './repos/JobsHistoryRepo'\nimport {JobsRepo} from './repos/JobsRepo'\nimport {SchemaInAnyOrionForm} from '@orion-js/schema'\n\nexport * from './types'\nexport * from './service'\nexport * from './defineJob'\n\nconst workerService = getInstance(WorkerService)\nconst eventsService = getInstance(EventsService)\nconst jobsHistoryRepo = getInstance(JobsHistoryRepo)\nconst jobsRepo = getInstance(JobsRepo)\n\nconst startWorkers = (config: StartWorkersConfig) => {\n return workerService.startWorkers(config)\n}\n\n/**\n * @deprecated Use the event job definition.schedule method instead.\n */\nconst scheduleJob = <TParamsSchema extends SchemaInAnyOrionForm = any>(\n options: ScheduleJobOptions<TParamsSchema>,\n) => {\n return eventsService.scheduleJob(options)\n}\n\n/**\n * Schedule multiple jobs at once for better performance.\n * @deprecated Use the event job definition.scheduleJobs method instead.\n */\nconst scheduleJobs = <TParamsSchema extends SchemaInAnyOrionForm = any>(\n jobs: ScheduleJobsOptions<TParamsSchema>,\n): Promise<ScheduleJobsResult> => {\n return eventsService.scheduleJobs(jobs)\n}\n\nexport {startWorkers, scheduleJob, scheduleJobs, jobsHistoryRepo, jobsRepo}\n","import {logger} from '@orion-js/logger'\nimport {Inject, Service} from '@orion-js/services'\nimport {JobsRepo} from '../repos/JobsRepo'\nimport {ScheduleJobOptions, ScheduleJobsOptions, ScheduleJobsResult} from '../types/Events'\nimport {getNextRunDate} from './getNextRunDate'\n\n@Service()\nexport class EventsService {\n @Inject(() => JobsRepo)\n private jobsRepo: JobsRepo\n\n async scheduleJob(options: ScheduleJobOptions) {\n logger.debug('Scheduling job...', options)\n\n await this.jobsRepo.scheduleJob({\n name: options.name,\n priority: options.priority || 100,\n nextRunAt: getNextRunDate(options),\n params: options.params || null,\n uniqueIdentifier: options.uniqueIdentifier,\n })\n }\n\n async scheduleJobs(jobs: ScheduleJobsOptions): Promise<ScheduleJobsResult> {\n logger.debug(`Scheduling ${jobs.length} jobs...`)\n\n const jobRecords = jobs.map(options => ({\n name: options.name,\n priority: options.priority || 100,\n nextRunAt: getNextRunDate(options),\n params: options.params || null,\n uniqueIdentifier: options.uniqueIdentifier,\n }))\n\n return await this.jobsRepo.scheduleJobs(jobRecords)\n }\n}\n","import {generateId} from '@orion-js/helpers'\nimport {logger} from '@orion-js/logger'\nimport {Collection, MongoDB, MongoCollection} from '@orion-js/mongodb'\nimport {ScheduleJobRecordOptions, ScheduleJobsResult} from '../types/Events'\nimport {JobRecord} from '../types/JobRecord'\nimport {JobDefinitionWithName, RecurrentJobDefinition} from '../types/JobsDefinition'\nimport {JobToRun} from '../types/Worker'\nimport {Repository} from '@orion-js/mongodb'\nimport {JobRecordSchema} from '../types/JobRecord'\n\n@Repository()\nexport class JobsRepo {\n @MongoCollection({\n idGeneration: 'uuid',\n name: 'orionjs.jobs_dogs_records',\n schema: JobRecordSchema,\n indexes: [\n {\n keys: {\n jobName: 1,\n priority: -1,\n nextRunAt: 1,\n },\n },\n {\n keys: {\n jobName: 1,\n },\n options: {\n unique: true,\n partialFilterExpression: {type: 'recurrent'},\n },\n },\n {\n keys: {\n uniqueIdentifier: 1,\n },\n options: {\n unique: true,\n sparse: true,\n },\n },\n ],\n })\n jobs: Collection<JobRecord>\n\n async getJobAndLock(jobNames: string[], lockTime: number): Promise<JobToRun> {\n const lockedUntil = new Date(Date.now() + lockTime)\n\n const job = await this.jobs.findOneAndUpdate(\n {\n jobName: {$in: jobNames},\n nextRunAt: {$lte: new Date()},\n $or: [{lockedUntil: {$exists: false}}, {lockedUntil: {$lte: new Date()}}],\n },\n {\n $set: {lockedUntil, lastRunAt: new Date()},\n },\n {\n mongoOptions: {\n sort: {\n priority: -1,\n nextRunAt: 1,\n },\n returnDocument: 'before',\n },\n },\n )\n\n if (!job) return\n\n let tries = job.tries || 1\n\n if (job.lockedUntil) {\n logger.info(`Running job \"${job.jobName}\" that was staled`)\n this.jobs.updateOne(job._id, {$inc: {tries: 1}})\n tries++\n }\n\n return {\n jobId: job._id,\n executionId: generateId(),\n name: job.jobName,\n params: job.params,\n type: job.type,\n tries,\n lockTime,\n priority: job.priority,\n uniqueIdentifier: job.uniqueIdentifier,\n }\n }\n\n async setJobRecordPriority(jobId: string, priority: number) {\n await this.jobs.updateOne(jobId, {$set: {priority}})\n }\n\n async scheduleNextRun(options: {\n jobId: string\n nextRunAt: Date\n addTries: boolean\n priority: number\n }) {\n const updator: MongoDB.UpdateFilter<JobRecord> = {\n $set: {\n nextRunAt: options.nextRunAt,\n priority: options.priority,\n ...(options.addTries ? {} : {tries: 0}),\n },\n $unset: {lockedUntil: ''},\n ...(options.addTries ? {$inc: {tries: 1}} : {}),\n }\n\n await this.jobs.updateOne(options.jobId, updator)\n }\n\n async deleteEventJob(jobId: string) {\n await this.jobs.deleteOne({_id: jobId, type: 'event'})\n }\n\n async extendLockTime(jobId: string, extraTime: number) {\n await this.updateLockTime(jobId, extraTime)\n }\n\n /**\n * Updates the lock time for a job to the specified duration from now.\n * Can be used to both extend or shorten the lock time.\n */\n async updateLockTime(jobId: string, lockDuration: number) {\n const lockedUntil = new Date(Date.now() + lockDuration)\n await this.jobs.updateOne(\n {\n _id: jobId,\n },\n {\n $set: {lockedUntil},\n },\n )\n }\n\n async unlockAllJobs(): Promise<number> {\n const result = await this.jobs.updateMany(\n {\n lockedUntil: {$exists: true},\n },\n {\n $unset: {lockedUntil: ''},\n },\n )\n\n return result.modifiedCount\n }\n\n async ensureJobRecord(job: JobDefinitionWithName) {\n const result = await this.jobs.upsert(\n {\n jobName: job.name,\n },\n {\n $set: {\n type: job.type,\n priority: (job as RecurrentJobDefinition).priority,\n },\n $setOnInsert: {\n nextRunAt: new Date(),\n },\n },\n )\n\n if (result.upsertedId) {\n logger.debug(`Created job record for \"${job.name}\"`)\n } else {\n logger.debug(`Record for job \"${job.name}\" already exists`)\n }\n }\n\n async scheduleJob(options: ScheduleJobRecordOptions) {\n try {\n await this.jobs.insertOne({\n jobName: options.name,\n uniqueIdentifier: options.uniqueIdentifier,\n params: options.params,\n nextRunAt: options.nextRunAt,\n priority: options.priority,\n type: 'event',\n })\n } catch (error) {\n if (\n error.isValidationError &&\n Object.values(error.validationErrors).includes('notUnique') &&\n options.uniqueIdentifier\n ) {\n logger.info(\n `Job \"${options.name}\" with identifier \"${options.uniqueIdentifier}\" already exists`,\n )\n } else {\n throw error\n }\n }\n }\n\n async scheduleJobs(jobs: ScheduleJobRecordOptions[]): Promise<ScheduleJobsResult> {\n if (jobs.length === 0) {\n return {scheduledCount: 0, skippedCount: 0, errors: []}\n }\n\n // Process each job individually to handle errors properly\n let scheduledCount = 0\n let skippedCount = 0\n const errors: Array<{index: number; error: Error; job: ScheduleJobRecordOptions}> = []\n\n for (let i = 0; i < jobs.length; i++) {\n const job = jobs[i]\n try {\n // Insert directly to get better error handling than the single scheduleJob method\n await this.jobs.insertOne({\n jobName: job.name,\n uniqueIdentifier: job.uniqueIdentifier,\n params: job.params,\n nextRunAt: job.nextRunAt,\n priority: job.priority,\n type: 'event',\n })\n scheduledCount++\n } catch (error) {\n // Check if it's a validation error with uniqueIdentifier constraint\n if (\n error.isValidationError &&\n Object.values(error.validationErrors).includes('notUnique') &&\n job.uniqueIdentifier\n ) {\n logger.info(`Job \"${job.name}\" with identifier \"${job.uniqueIdentifier}\" already exists`)\n skippedCount++\n } else {\n errors.push({\n index: i,\n error: error instanceof Error ? error : new Error(String(error)),\n job,\n })\n }\n }\n }\n\n logger.debug(\n `Scheduled ${scheduledCount} jobs successfully, skipped ${skippedCount}, errors: ${errors.length}`,\n )\n\n return {\n scheduledCount,\n skippedCount,\n errors,\n }\n }\n}\n","import {createEnum, InferSchemaType, schemaWithName} from '@orion-js/schema'\n\nexport const JobRecordSchema = schemaWithName('JobRecord', {\n _id: {type: 'string'},\n jobName: {type: 'string'},\n type: {type: createEnum('JobType', ['recurrent', 'event'])},\n priority: {type: 'number'},\n uniqueIdentifier: {type: 'string', optional: true},\n nextRunAt: {type: 'date'},\n lastRunAt: {type: 'date', optional: true},\n lockedUntil: {type: 'date', optional: true},\n tries: {type: 'number', optional: true},\n params: {type: 'blackbox', optional: true},\n})\n\nexport type JobRecord = InferSchemaType<typeof JobRecordSchema>\n","export type Options = {\n getNextRun?: () => Date\n runIn?: number\n runEvery?: number\n runAt?: Date\n} & {[key: string]: any}\n\nexport const getNextRunDate = (options: Options) => {\n if (options.runIn) {\n return new Date(Date.now() + options.runIn)\n }\n\n if (options.runEvery) {\n return new Date(Date.now() + options.runEvery)\n }\n\n if (options.runAt) {\n return options.runAt\n }\n\n if (options.getNextRun) {\n return options.getNextRun()\n }\n\n return new Date()\n}\n","import {Inject, Service} from '@orion-js/services'\nimport {range} from 'rambdax'\nimport {JobsRepo} from '../repos/JobsRepo'\nimport {JobDefinitionWithName, JobsDefinition} from '../types/JobsDefinition'\nimport {StartWorkersConfig} from '../types/StartConfig'\nimport {sleep} from '@orion-js/helpers'\nimport {Executor} from './Executor'\nimport {WorkerInstance, WorkersInstance} from '../types/Worker'\nimport {logger} from '@orion-js/logger'\n\n@Service()\nexport class WorkerService {\n @Inject(() => JobsRepo)\n private jobsRepo: JobsRepo\n\n @Inject(() => Executor)\n private executor: Executor\n\n getJobNames(jobs: JobsDefinition) {\n return Object.keys(jobs)\n }\n\n getJobs(jobs: JobsDefinition): JobDefinitionWithName[] {\n return Object.keys(jobs).map(name => {\n return {\n name,\n ...jobs[name],\n }\n })\n }\n\n async runWorkerLoop(config: StartWorkersConfig, workerInstance: WorkerInstance) {\n const names = this.getJobNames(config.jobs)\n logger.debug(\n `Running worker loop [w${workerInstance.workerIndex}] for jobs \"${names.join(', ')}\"...`,\n )\n const jobToRun = await this.jobsRepo.getJobAndLock(names, config.defaultLockTime)\n if (!jobToRun) {\n logger.debug('No job to run')\n return false\n }\n\n logger.debug(`Got job [w${workerInstance.workerIndex}] to run:`, jobToRun)\n await this.executor.executeJob(config.jobs, jobToRun, workerInstance.respawn)\n\n return true\n }\n\n async startWorker(config: StartWorkersConfig, workerInstance: WorkerInstance) {\n while (true) {\n if (!workerInstance.running) {\n logger.info(`Got signal to stop. Stopping worker [w${workerInstance.workerIndex}]...`)\n return\n }\n\n try {\n const didRun = await this.runWorkerLoop(config, workerInstance)\n if (!didRun) await sleep(config.pollInterval)\n if (didRun) await sleep(config.cooldownPeriod)\n } catch (error) {\n logger.error('Error in job runner.', {error})\n await sleep(config.pollInterval)\n }\n }\n }\n\n createWorkersInstanceDefinition(config: StartWorkersConfig): WorkersInstance {\n const workersInstance: WorkersInstance = {\n running: true,\n workersCount: config.workersCount,\n workers: [],\n stop: async () => {\n logger.info('Stopping workers...')\n workersInstance.running = false\n const stopingPromises = workersInstance.workers.map(worker => worker.stop())\n await Promise.all(stopingPromises)\n },\n }\n\n return workersInstance\n }\n\n async ensureRecords(config: StartWorkersConfig) {\n const jobs = this.getJobs(config.jobs)\n\n await Promise.all(\n jobs\n .filter(job => job.type === 'recurrent')\n .map(async job => {\n logger.debug(`Ensuring records for job \"${job.name}\"...`)\n await this.jobsRepo.ensureJobRecord(job)\n }),\n )\n }\n\n async startANewWorker(config: StartWorkersConfig, workersInstance: WorkersInstance) {\n const workerIndex = workersInstance.workers.length\n\n logger.info(`Starting worker [w${workerIndex}]`)\n\n const workerInstance: WorkerInstance = {\n running: true,\n workerIndex,\n stop: async () => {\n logger.info(`Stopping worker [w${workerIndex}]...`)\n workerInstance.running = false\n await workerInstance.promise\n },\n respawn: async () => {\n logger.info(`Respawning worker [w${workerIndex}]...`)\n workerInstance.stop()\n await this.startANewWorker(config, workersInstance)\n },\n }\n\n const workerPromise = this.startWorker(config, workerInstance)\n\n workerInstance.promise = workerPromise\n workersInstance.workers.push(workerInstance)\n }\n\n async runWorkers(config: StartWorkersConfig, workersInstance: WorkersInstance) {\n logger.debug('Will ensure records for recurrent jobs')\n await this.ensureRecords(config)\n\n for (const _ of range(0, config.workersCount)) {\n this.startANewWorker(config, workersInstance)\n }\n }\n\n startWorkers(userConfig: Partial<StartWorkersConfig>): WorkersInstance {\n const defaultConfig: StartWorkersConfig = {\n jobs: {},\n cooldownPeriod: 100,\n pollInterval: 3000,\n workersCount: 4,\n defaultLockTime: 30 * 1000,\n }\n\n const config = {\n ...defaultConfig,\n ...userConfig,\n }\n\n setNameToJobs(config.jobs)\n\n const workersInstance = this.createWorkersInstanceDefinition(config)\n logger.debug('Starting workers', config)\n\n this.runWorkers(config, workersInstance)\n\n return workersInstance\n }\n}\n\nfunction setNameToJobs(jobs: JobsDefinition) {\n return Object.keys(jobs).map(name => {\n jobs[name].jobName = name\n })\n}\n","function _isInteger(n){\n return n << 0 === n\n}\n\nexport const isInteger = Number.isInteger || _isInteger\n\n/**\n * Check if `index` is integer even if it is a string.\n */\nexport const isIndexInteger = index => Number.isInteger(Number(index))\n","import { isInteger } from './isInteger.js'\n\nexport function createPath(path, delimiter = '.'){\n return typeof path === 'string' ?\n path.split(delimiter).map(x => isInteger(x) ? Number(x) : x) :\n path\n}\n","export function compare(a, b){\n return String(a) === String(b)\n}\n","import { compare } from './compare.js'\n\nexport function includes(a, list){\n let index = -1\n const { length } = list\n\n while (++index < length)\n if (compare(list[ index ], a))\n return true\n\n return false\n}\n","import { createPath } from './_internals/createPath.js'\nimport { includes } from './_internals/includes.js'\n\nexport function omit(propsToOmit, obj){\n if (arguments.length === 1) return _obj => omit(propsToOmit, _obj)\n\n if (obj === null || obj === undefined)\n return undefined\n\n const propsToOmitValue = createPath(propsToOmit, ',')\n const willReturn = {}\n\n for (const key in obj)\n if (!includes(key, propsToOmitValue))\n willReturn[ key ] = obj[ key ]\n\n return willReturn\n}\n","export function range(start, end){\n if (arguments.length === 1) return _end => range(start, _end)\n\n if (Number.isNaN(Number(start)) || Number.isNaN(Number(end))){\n throw new TypeError('Both arguments to range must be numbers')\n }\n\n if (end < start) return []\n\n const len = end - start\n const willReturn = Array(len)\n\n for (let i = 0; i < len; i++){\n willReturn[ i ] = start + i\n }\n\n return willReturn\n}\n","import {logger, runWithOrionAsyncContext, updateOrionAsyncContext} from '@orion-js/logger'\nimport {Inject, Service} from '@orion-js/services'\nimport {JobsHistoryRepo} from '../repos/JobsHistoryRepo'\nimport {JobsRepo} from '../repos/JobsRepo'\nimport {JobDefinition, JobsDefinition} from '../types/JobsDefinition'\nimport {ExecutionContext, JobToRun} from '../types/Worker'\nimport {getNextRunDate} from './getNextRunDate'\nimport {trace, SpanStatusCode} from '@opentelemetry/api'\nimport {Blackbox} from '@orion-js/schema'\n\n@Service()\nexport class Executor {\n @Inject(() => JobsRepo)\n private readonly jobsRepo: JobsRepo\n\n @Inject(() => JobsHistoryRepo)\n private readonly jobsHistoryRepo: JobsHistoryRepo\n\n /**\n * Determines the effective lock time for a job execution.\n * Job-specific lockTime takes precedence over the default lockTime from config.\n */\n getEffectiveLockTime(job: JobDefinition, jobToRun: JobToRun): number {\n return job.lockTime ?? jobToRun.lockTime\n }\n\n getContext(job: JobDefinition, jobToRun: JobToRun, onStale: Function): ExecutionContext {\n const effectiveLockTime = this.getEffectiveLockTime(job, jobToRun)\n let staleTimeout = setTimeout(() => onStale(), effectiveLockTime)\n return {\n definition: job,\n record: jobToRun,\n tries: jobToRun.tries || 0,\n clearStaleTimeout: () => clearTimeout(staleTimeout),\n extendLockTime: async (extraTime: number) => {\n clearTimeout(staleTimeout)\n staleTimeout = setTimeout(() => onStale(), extraTime)\n await this.jobsRepo.extendLockTime(jobToRun.jobId, extraTime)\n },\n logger: logger.addMetadata({\n jobName: jobToRun.name,\n jobId: jobToRun.jobId,\n }),\n }\n }\n\n getJobDefinition(jobToRun: JobToRun, jobs: JobsDefinition) {\n const job = jobs[jobToRun.name]\n\n if (jobToRun.type !== job.type) {\n logger.warn(\n `Job record \"${jobToRun.name}\" is \"${jobToRun.type}\" but definition is \"${job.type}\"`,\n )\n return\n }\n\n return job\n }\n\n async onError(error: any, job: JobDefinition, jobToRun: JobToRun, context: ExecutionContext) {\n const scheduleRecurrent = async () => {\n if (job.type === 'recurrent') {\n await this.jobsRepo.scheduleNextRun({\n jobId: jobToRun.jobId,\n nextRunAt: getNextRunDate(job),\n addTries: false,\n priority: job.priority,\n })\n }\n }\n\n if (!job.onError) {\n context.logger.error(`Error executing job \"${jobToRun.name}\"`, {error})\n await scheduleRecurrent()\n return\n }\n context.logger.info(`Error executing job \"${jobToRun.name}\"`, {error})\n\n const result = await job.onError(error, jobToRun.params, context)\n\n if (result.action === 'dismiss') {\n await scheduleRecurrent()\n return\n }\n\n if (result.action === 'retry') {\n await this.jobsRepo.scheduleNextRun({\n jobId: jobToRun.jobId,\n nextRunAt: getNextRunDate(result),\n addTries: true,\n priority: job.type === 'recurrent' ? job.priority : jobToRun.priority,\n })\n }\n }\n\n async saveExecution(options: {\n startedAt: Date\n status: 'stale' | 'error' | 'success'\n errorMessage?: string\n result?: Blackbox\n job: JobDefinition\n jobToRun: JobToRun\n }) {\n const {startedAt, status, errorMessage, result, job, jobToRun} = options\n const endedAt = new Date()\n\n if (job.saveExecutionsFor !== 0) {\n const oneWeek = 1000 * 60 * 60 * 24 * 7\n const saveExecutionsFor = job.saveExecutionsFor || oneWeek\n await this.jobsHistoryRepo.saveExecution({\n jobId: jobToRun.jobId,\n executionId: jobToRun.executionId,\n jobName: jobToRun.name,\n type: jobToRun.type,\n priority: jobToRun.priority,\n tries: jobToRun.tries,\n uniqueIdentifier: jobToRun.uniqueIdentifier,\n startedAt,\n endedAt,\n duration: endedAt.getTime() - startedAt.getTime(),\n expiresAt: new Date(Date.now() + saveExecutionsFor),\n status,\n errorMessage,\n params: jobToRun.params,\n result,\n })\n }\n }\n\n async afterExecutionSuccess(job: JobDefinition, jobToRun: JobToRun, context: ExecutionContext) {\n if (job.type === 'recurrent') {\n context.logger.debug(`Scheduling next run for recurrent job \"${jobToRun.name}\"`)\n await this.jobsRepo.scheduleNextRun({\n jobId: jobToRun.jobId,\n nextRunAt: getNextRunDate(job),\n addTries: false,\n priority: job.priority,\n })\n }\n if (job.type === 'event') {\n context.logger.debug(`Removing event job after success \"${jobToRun.name}\"`)\n await this.jobsRepo.deleteEventJob(jobToRun.jobId)\n }\n }\n\n async executeJob(jobs: JobsDefinition, jobToRun: JobToRun, respawnWorker: Function) {\n const job = this.getJobDefinition(jobToRun, jobs)\n if (!job) return\n\n // If job has a custom lockTime different from the default, update the database lock\n const effectiveLockTime = this.getEffectiveLockTime(job, jobToRun)\n if (effectiveLockTime !== jobToRun.lockTime) {\n await this.jobsRepo.updateLockTime(jobToRun.jobId, effectiveLockTime)\n }\n\n const tracer = trace.getTracer('orionjs.dogs', '1.0')\n\n await tracer.startActiveSpan(`job.${jobToRun.name}.${jobToRun.executionId}`, async span => {\n try {\n const startedAt = new Date()\n\n const onStale = async () => {\n if (job.onStale) {\n context.logger.info(`Job \"${jobToRun.name}\" is stale`)\n job.onStale(jobToRun.params, context)\n } else {\n context.logger.error(`Job \"${jobToRun.name}\" is stale`)\n }\n\n await this.jobsRepo.setJobRecordPriority(jobToRun.jobId, 0)\n\n respawnWorker()\n\n this.saveExecution({\n startedAt,\n status: 'stale',\n result: null,\n errorMessage: null,\n job,\n jobToRun,\n })\n }\n\n const context = this.getContext(job, jobToRun, onStale)\n\n const extraContext = {\n controllerType: 'job' as const,\n jobName: jobToRun.name,\n params: jobToRun.params,\n }\n\n await runWithOrionAsyncContext(extraContext, async () => {\n try {\n // Inject async context update\n updateOrionAsyncContext({\n jobName: jobToRun.name,\n params: jobToRun.params,\n })\n const result = await job.resolve(jobToRun.params, context)\n context.clearStaleTimeout()\n\n this.saveExecution({\n startedAt,\n status: 'success',\n result: result || null,\n errorMessage: null,\n job,\n jobToRun,\n })\n\n await this.afterExecutionSuccess(job, jobToRun, context)\n } catch (error) {\n context.clearStaleTimeout()\n this.saveExecution({\n startedAt,\n status: 'error',\n result: null,\n errorMessage: (error as Error).message,\n job,\n jobToRun,\n })\n\n await this.onError(error, job, jobToRun, context)\n }\n })\n } catch (error) {\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: error.message,\n })\n throw error\n } finally {\n span.end()\n }\n })\n }\n}\n","import {Collection, MongoCollection, Repository, MongoDB} from '@orion-js/mongodb'\nimport {omit} from 'rambdax'\nimport {HistoryRecord, HistoryRecordSchema} from '../types/HistoryRecord'\n\n@Repository()\nexport class JobsHistoryRepo {\n @MongoCollection({\n name: 'orionjs.jobs_dogs_history',\n idGeneration: 'uuid',\n schema: HistoryRecordSchema,\n indexes: [\n {\n keys: {\n jobName: 1,\n startedAt: 1,\n },\n },\n {\n keys: {\n executionId: 1,\n },\n },\n {\n keys: {\n expiresAt: 1,\n },\n options: {\n expireAfterSeconds: 0,\n },\n },\n ],\n })\n history: Collection<HistoryRecord>\n\n async saveExecution(record: MongoDB.WithoutId<HistoryRecord>) {\n await this.history.upsert(\n {executionId: record.executionId},\n {\n $setOnInsert: {\n status: record.status,\n },\n $set: {\n ...omit(['status'], record),\n },\n },\n )\n }\n\n async getExecutions(jobName: string, limit?: number, skip?: number): Promise<HistoryRecord[]> {\n const cursor = this.history.find({jobName}).sort({startedAt: -1})\n\n if (skip) {\n cursor.skip(skip)\n }\n\n if (limit) {\n cursor.limit(limit)\n }\n\n return await cursor.toArray()\n }\n}\n","import {InferSchemaType, schemaWithName} from '@orion-js/schema'\n\nexport const HistoryRecordSchema = schemaWithName('HistoryRecord', {\n _id: {type: 'string'},\n jobId: {type: 'string'},\n executionId: {type: 'string'},\n jobName: {type: 'string'},\n type: {type: 'string'},\n priority: {type: 'number'},\n tries: {type: 'number'},\n uniqueIdentifier: {type: 'string', optional: true},\n startedAt: {type: 'date'},\n endedAt: {type: 'date'},\n duration: {type: 'number'},\n expiresAt: {type: 'date', optional: true},\n status: {type: 'string', enum: ['success', 'error', 'stale']},\n errorMessage: {type: 'string', optional: true},\n params: {type: 'blackbox', optional: true},\n result: {type: 'any', optional: true},\n})\n\nexport type HistoryRecord = InferSchemaType<typeof HistoryRecordSchema>\n","import {getInstance, Service} from '@orion-js/services'\nimport {createEventJob, defineJob} from '../defineJob'\nimport type {CreateEventJobOptions, JobDefinition, RecurrentJobDefinition} from '../types'\n\n// Define metadata storage using WeakMaps\nconst serviceMetadata = new WeakMap<any, {_serviceType: string}>()\nconst jobsMetadata = new Map<any, Record<string, any>>()\n\nexport function Jobs() {\n return (target: any, context: ClassDecoratorContext<any>) => {\n Service()(target, context)\n\n context.addInitializer(function (this) {\n serviceMetadata.set(this, {_serviceType: 'jobs'})\n })\n }\n}\n\nexport function RecurrentJob(): (\n method: any,\n context: ClassFieldDecoratorContext | ClassMethodDecoratorContext,\n) => any\nexport function RecurrentJob(\n options: Omit<RecurrentJobDefinition, 'resolve' | 'type'>,\n): (method: any, context: ClassMethodDecoratorContext) => any\nexport function RecurrentJob(options = {}) {\n return (method: any, context: ClassFieldDecoratorContext | ClassMethodDecoratorContext) => {\n const propertyKey = String(context.name)\n\n context.addInitializer(function (this) {\n const jobs = jobsMetadata.get(this) || {}\n\n if (context.kind === 'method') {\n jobs[propertyKey] = defineJob({\n ...options,\n type: 'recurrent',\n resolve: this[propertyKey].bind(this),\n })\n }\n\n if (context.kind === 'field') {\n jobs[propertyKey] = this[propertyKey]\n }\n\n jobsMetadata.set(this, jobs)\n })\n\n return method\n }\n}\n\nexport function EventJob(): (\n method: any,\n context: ClassFieldDecoratorContext | ClassMethodDecoratorContext,\n) => any\nexport function EventJob(\n options: Omit<CreateEventJobOptions<any>, 'resolve'>,\n): (method: any, context: ClassMethodDecoratorContext) => any\nexport function EventJob(options = {}) {\n return (method: any, context: ClassFieldDecoratorContext | ClassMethodDecoratorContext) => {\n const propertyKey = String(context.name)\n\n context.addInitializer(function (this) {\n const jobs = jobsMetadata.get(this) || {}\n\n if (context.kind === 'method') {\n jobs[propertyKey] = createEventJob({\n ...options,\n resolve: this[propertyKey].bind(this),\n })\n }\n\n if (context.kind === 'field') {\n jobs[propertyKey] = this[propertyKey]\n }\n\n jobsMetadata.set(this, jobs)\n })\n\n return method\n }\n}\n\nexport function getServiceJobs(target: any): {\n [key: string]: JobDefinition\n} {\n const instance = getInstance(target)\n\n if (!serviceMetadata.has(instance.constructor)) {\n throw new Error('You must pass a class decorated with @Jobs to getServiceJobs')\n }\n\n const instanceMetadata = serviceMetadata.get(instance.constructor)\n if (instanceMetadata._serviceType !== 'jobs') {\n throw new Error('You must pass a class decorated with @Jobs to getServiceJobs')\n }\n\n const jobsMap = jobsMetadata.get(instance) || {}\n\n return jobsMap\n}\n\n/**\n * Logs\n * after event job {\n job1: { type: 'event', resolve: [Function: bound job1] AsyncFunction }\n}\nbefore recurrent job Map(1) {\n ExampleJobsService {} => {\n job1: { type: 'event', resolve: [Function: bound job1] AsyncFunction }\n }\n}\nbefore recurrent job undefined\nafter recurrent job {\n job2: {\n runEvery: 1000,\n type: 'recurrent',\n resolve: [Function: bound job2] AsyncFunction,\n priority: 100\n }\n}\n{\n serviceJobs: {\n job2: {\n runEvery: 1000,\n type: 'recurrent',\n resolve: [Function: bound job2] AsyncFunction,\n priority: 100\n }\n }\n}\n */\n","import {\n CreateEventJobOptions,\n CreateJobOptions,\n CreateRecurrentJobOptions,\n EventJobDefinition,\n JobDefinition,\n RecurrentJobDefinition,\n} from '../types/JobsDefinition'\nimport {scheduleJob, ScheduleJobsResult, scheduleJobs} from '..'\nimport {ScheduleJobOptionsWithoutName} from '../types/Events'\nimport {cleanAndValidate, SchemaInAnyOrionForm} from '@orion-js/schema'\nimport parse from 'parse-duration'\n\nexport function createEventJob<TParamsSchema extends SchemaInAnyOrionForm>(\n options: CreateEventJobOptions<TParamsSchema>,\n): EventJobDefinition<TParamsSchema> {\n const jobDefinition: EventJobDefinition<TParamsSchema> = {\n ...options,\n type: 'event',\n schedule: null,\n scheduleJobs: null,\n }\n\n jobDefinition.schedule = async (scheduleOptions: ScheduleJobOptionsWithoutName<TParamsSchema>) => {\n if (!jobDefinition.jobName) {\n throw new Error('This job has not been registered in the workers')\n }\n\n const params = jobDefinition.params\n ? await cleanAndValidate(jobDefinition.params, scheduleOptions.params)\n : scheduleOptions.params\n\n return await scheduleJob({\n ...scheduleOptions,\n name: jobDefinition.jobName,\n params,\n })\n }\n\n jobDefinition.scheduleJobs = async (\n jobs: Array<ScheduleJobOptionsWithoutName<TParamsSchema>>,\n ): Promise<ScheduleJobsResult> => {\n if (!jobDefinition.jobName) {\n throw new Error('This job has not been registered in the workers')\n }\n\n // Process all job parameters if schema validation is needed\n const processedJobs = await Promise.all(\n jobs.map(async scheduleOptions => {\n const params = jobDefinition.params\n ? await cleanAndValidate(jobDefinition.params, scheduleOptions.params)\n : scheduleOptions.params\n\n return {\n ...scheduleOptions,\n name: jobDefinition.jobName,\n params,\n }\n }),\n )\n\n return await scheduleJobs(processedJobs)\n }\n\n return jobDefinition\n}\n\nexport function createRecurrentJob(options: CreateRecurrentJobOptions): RecurrentJobDefinition {\n const jobDefinition: RecurrentJobDefinition = {\n ...options,\n priority: options.priority ?? 100,\n type: 'recurrent',\n runEvery: typeof options.runEvery === 'string' ? parse(options.runEvery) : options.runEvery,\n }\n\n return jobDefinition\n}\n\n/**\n * @deprecated Use `createEventJob` or `createRecurrentJob` instead.\n */\nexport const defineJob = (\n options: CreateJobOptions & {type: 'event' | 'recurrent'},\n): JobDefinition => {\n return options.type === 'event'\n ? createEventJob(options as any)\n : createRecurrentJob(options as any)\n}\n"],"mappings":"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","names":["getInstance","logger","_init","logger","Inject","Service","logger","Inject","Service","MongoCollection","Repository","schemaWithName","_init","Repository","MongoCollection","_jobsRepo_dec","_init","Service","Inject","logger","logger","_jobsRepo_dec","_init","Service","Inject","logger","Service","Service","getInstance"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orion-js/dogs",
|
|
3
|
-
"version": "4.1.
|
|
3
|
+
"version": "4.1.12",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.cjs",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -21,20 +21,20 @@
|
|
|
21
21
|
"dot-object": "^2.1.5",
|
|
22
22
|
"parse-duration": "^2.1.3",
|
|
23
23
|
"@orion-js/helpers": "4.1.4",
|
|
24
|
-
"@orion-js/services": "4.1.4",
|
|
25
24
|
"@orion-js/typed-model": "4.1.7",
|
|
26
|
-
"@orion-js/schema": "4.1.4"
|
|
25
|
+
"@orion-js/schema": "4.1.4",
|
|
26
|
+
"@orion-js/services": "4.1.4"
|
|
27
27
|
},
|
|
28
28
|
"peerDependencies": {
|
|
29
29
|
"@orion-js/logger": "4.1.4",
|
|
30
|
-
"@orion-js/mongodb": "4.1.
|
|
30
|
+
"@orion-js/mongodb": "4.1.10"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"tsup": "^8.0.1",
|
|
34
34
|
"typescript": "^5.4.5",
|
|
35
35
|
"vitest": "^3.0.8",
|
|
36
|
-
"@orion-js/
|
|
37
|
-
"@orion-js/
|
|
36
|
+
"@orion-js/mongodb": "4.1.10",
|
|
37
|
+
"@orion-js/logger": "4.1.4"
|
|
38
38
|
},
|
|
39
39
|
"publishConfig": {
|
|
40
40
|
"access": "public"
|