@azlib/scheduler 0.2.0
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/LICENSE +201 -0
- package/README.md +108 -0
- package/dist/index.cjs +645 -0
- package/dist/index.d.cts +172 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +172 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +642 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +45 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["createSchedulerService","createSchedulerServiceInternal"],"sources":["../src/core/scheduler-host-binding.ts","../src/core/cron-expression-builder.ts","../src/core/job-execution-store.ts","../src/core/schedule-cursor-store.ts","../src/core/scheduler-cache.ts","../src/core/schedule-parser.ts","../src/core/scheduler-engine.ts","../src/core/scheduler-events.ts","../src/core/scheduler-handler-registry.ts","../src/core/scheduler-job-store.ts","../src/core/scheduler-logger.ts","../src/core/scheduler-runtime.ts","../src/core/scheduler-runtime-config.ts","../src/core/scheduler-service-query.ts","../src/core/scheduler-service-retry.ts","../src/core/scheduler-service.ts","../src/dashboard/queue-queries.ts","../src/dashboard/queue-dashboard-service.ts","../index.ts"],"sourcesContent":["import type { SchedulerHostAdapter } from \"../contracts/scheduler-host.js\";\nimport type { SchedulerService } from \"../contracts/scheduler-types.js\";\n\nexport function bindSchedulerToHost(\n scheduler: SchedulerService,\n host: SchedulerHostAdapter\n): void {\n host.onStart(() => scheduler.start());\n host.onStop(() => scheduler.stop());\n}\n","export const CronWeekday = {\n Sunday: 0,\n Monday: 1,\n Tuesday: 2,\n Wednesday: 3,\n Thursday: 4,\n Friday: 5,\n Saturday: 6,\n} as const;\n\nexport type CronWeekdayValue = (typeof CronWeekday)[keyof typeof CronWeekday];\n\nfunction assertIntegerInRange(label: string, value: number, min: number, max: number): void {\n if (!Number.isInteger(value) || value < min || value > max) {\n throw new Error(`${label} must be an integer between ${min} and ${max}`);\n }\n}\n\nfunction assertPositiveInteger(label: string, value: number): void {\n if (!Number.isInteger(value) || value <= 0) {\n throw new Error(`${label} must be a positive integer`);\n }\n}\n\nfunction assertStepInRange(label: string, value: number, max: number): void {\n assertPositiveInteger(label, value);\n if (value > max) {\n throw new Error(`${label} must be less than or equal to ${max}`);\n }\n}\n\nfunction toSortedCsv(values: number[]): string {\n return [...new Set(values)].sort((left, right) => left - right).join(\",\");\n}\n\nexport class CronExpressionBuilder {\n private minute = \"*\";\n private hour = \"*\";\n private dayOfMonth = \"*\";\n private month = \"*\";\n private dayOfWeek = \"*\";\n\n everyMinute(): this {\n this.minute = \"*\";\n return this;\n }\n\n everyNMinutes(interval: number): this {\n assertStepInRange(\"minute interval\", interval, 59);\n this.minute = `*/${interval}`;\n return this;\n }\n\n atMinute(minute: number): this {\n assertIntegerInRange(\"minute\", minute, 0, 59);\n this.minute = String(minute);\n return this;\n }\n\n atMinutes(minutes: number[]): this {\n if (minutes.length === 0) {\n throw new Error(\"minutes must contain at least one value\");\n }\n minutes.forEach((minute) => assertIntegerInRange(\"minute\", minute, 0, 59));\n this.minute = toSortedCsv(minutes);\n return this;\n }\n\n everyHour(): this {\n this.hour = \"*\";\n return this;\n }\n\n everyNHours(interval: number): this {\n assertStepInRange(\"hour interval\", interval, 23);\n this.hour = `*/${interval}`;\n return this;\n }\n\n atHour(hour: number): this {\n assertIntegerInRange(\"hour\", hour, 0, 23);\n this.hour = String(hour);\n return this;\n }\n\n atHours(hours: number[]): this {\n if (hours.length === 0) {\n throw new Error(\"hours must contain at least one value\");\n }\n hours.forEach((hour) => assertIntegerInRange(\"hour\", hour, 0, 23));\n this.hour = toSortedCsv(hours);\n return this;\n }\n\n onDayOfMonth(day: number): this {\n assertIntegerInRange(\"day of month\", day, 1, 31);\n this.dayOfMonth = String(day);\n return this;\n }\n\n onDaysOfMonth(days: number[]): this {\n if (days.length === 0) {\n throw new Error(\"days must contain at least one value\");\n }\n days.forEach((day) => assertIntegerInRange(\"day of month\", day, 1, 31));\n this.dayOfMonth = toSortedCsv(days);\n return this;\n }\n\n everyNDaysOfMonth(interval: number): this {\n assertStepInRange(\"day-of-month interval\", interval, 31);\n this.dayOfMonth = `*/${interval}`;\n return this;\n }\n\n everyMonth(): this {\n this.month = \"*\";\n return this;\n }\n\n onMonth(month: number): this {\n assertIntegerInRange(\"month\", month, 1, 12);\n this.month = String(month);\n return this;\n }\n\n onMonths(months: number[]): this {\n if (months.length === 0) {\n throw new Error(\"months must contain at least one value\");\n }\n months.forEach((month) => assertIntegerInRange(\"month\", month, 1, 12));\n this.month = toSortedCsv(months);\n return this;\n }\n\n everyNMonths(interval: number): this {\n assertStepInRange(\"month interval\", interval, 12);\n this.month = `*/${interval}`;\n return this;\n }\n\n onWeekday(weekday: CronWeekdayValue): this {\n assertIntegerInRange(\"weekday\", weekday, 0, 6);\n this.dayOfWeek = String(weekday);\n return this;\n }\n\n onWeekdays(weekdays: CronWeekdayValue[]): this {\n if (weekdays.length === 0) {\n throw new Error(\"weekdays must contain at least one value\");\n }\n weekdays.forEach((weekday) => assertIntegerInRange(\"weekday\", weekday, 0, 6));\n this.dayOfWeek = toSortedCsv(weekdays);\n return this;\n }\n\n everyNWeekdays(interval: number): this {\n assertStepInRange(\"weekday interval\", interval, 6);\n this.dayOfWeek = `*/${interval}`;\n return this;\n }\n\n weekdays(): this {\n this.dayOfWeek = \"1-5\";\n return this;\n }\n\n weekends(): this {\n this.dayOfWeek = \"0,6\";\n return this;\n }\n\n dailyAt(hour: number, minute = 0): this {\n this.atHour(hour);\n this.atMinute(minute);\n this.dayOfMonth = \"*\";\n this.month = \"*\";\n this.dayOfWeek = \"*\";\n return this;\n }\n\n weeklyOn(weekday: CronWeekdayValue, hour = 0, minute = 0): this {\n this.atHour(hour);\n this.atMinute(minute);\n this.dayOfWeek = String(weekday);\n this.dayOfMonth = \"*\";\n this.month = \"*\";\n return this;\n }\n\n monthlyOn(dayOfMonth: number, hour = 0, minute = 0): this {\n this.atHour(hour);\n this.atMinute(minute);\n this.onDayOfMonth(dayOfMonth);\n this.month = \"*\";\n this.dayOfWeek = \"*\";\n return this;\n }\n\n build(): string {\n return `${this.minute} ${this.hour} ${this.dayOfMonth} ${this.month} ${this.dayOfWeek}`;\n }\n\n toString(): string {\n return this.build();\n }\n}\n\nexport function createCronExpression(): CronExpressionBuilder {\n return new CronExpressionBuilder();\n}","import type { SchedulerExecutionRecord } from \"../contracts/scheduler-types.js\";\n\nexport interface JobExecutionStore {\n create(record: SchedulerExecutionRecord): SchedulerExecutionRecord;\n update(\n executionId: string,\n patch: Partial<Omit<SchedulerExecutionRecord, \"executionId\">>\n ): SchedulerExecutionRecord | null;\n listByJob(jobId: string): SchedulerExecutionRecord[];\n}\n\nexport function createInMemoryJobExecutionStore(): JobExecutionStore {\n const byExecution = new Map<string, SchedulerExecutionRecord>();\n\n return {\n create(record) {\n byExecution.set(record.executionId, record);\n return record;\n },\n update(executionId, patch) {\n const current = byExecution.get(executionId);\n if (!current) {\n return null;\n }\n const next: SchedulerExecutionRecord = {\n ...current,\n ...patch,\n };\n byExecution.set(executionId, next);\n return next;\n },\n listByJob(jobId) {\n return Array.from(byExecution.values()).filter((item) => item.jobId === jobId);\n },\n };\n}\n","export interface ScheduleCursorRecord {\n jobId: string;\n lastEvaluatedAt: string;\n lastTriggeredAt?: string;\n nextRunAt: string;\n version: number;\n}\n\nexport interface ScheduleCursorStore {\n set(jobId: string, nextRunAt: string, now: string): ScheduleCursorRecord;\n markTriggered(jobId: string, triggeredAt: string): ScheduleCursorRecord | null;\n get(jobId: string): ScheduleCursorRecord | null;\n remove(jobId: string): boolean;\n}\n\nexport function createInMemoryScheduleCursorStore(): ScheduleCursorStore {\n const cursors = new Map<string, ScheduleCursorRecord>();\n\n return {\n set(jobId, nextRunAt, now) {\n const previous = cursors.get(jobId);\n const next: ScheduleCursorRecord = {\n jobId,\n lastEvaluatedAt: now,\n lastTriggeredAt: previous?.lastTriggeredAt,\n nextRunAt,\n version: (previous?.version ?? 0) + 1,\n };\n cursors.set(jobId, next);\n return next;\n },\n markTriggered(jobId, triggeredAt) {\n const current = cursors.get(jobId);\n if (!current) {\n return null;\n }\n const next: ScheduleCursorRecord = {\n ...current,\n lastTriggeredAt: triggeredAt,\n version: current.version + 1,\n };\n cursors.set(jobId, next);\n return next;\n },\n get(jobId) {\n return cursors.get(jobId) ?? null;\n },\n remove(jobId) {\n return cursors.delete(jobId);\n },\n };\n}\n","import { createCache, type Cache } from \"@azlib/cache\";\n\nexport function createSchedulerCache(namespace = \"scheduler-core\"): Cache<string> {\n return createCache<string>({\n mode: \"memory\",\n namespace,\n });\n}\n","import type { ScheduleType } from \"../contracts/scheduler-types.js\";\n\nexport interface ParsedSchedule {\n scheduleType: ScheduleType;\n expression: string;\n timezone: string;\n}\n\nconst CRON_FIELD_PATTERN = /^\\*|\\*\\/\\d+|\\d+|\\d+-\\d+|\\d+(?:,\\d+)*$/;\n\nexport function assertValidTimezone(timezone: string): void {\n try {\n new Intl.DateTimeFormat(\"en-US\", { timeZone: timezone }).format(new Date());\n } catch {\n throw new Error(`Invalid timezone: ${timezone}`);\n }\n}\n\nfunction assertValidCronExpression(expression: string): void {\n const fields = expression.trim().split(/\\s+/);\n if (fields.length !== 5) {\n throw new Error(\"Cron expression must contain 5 fields\");\n }\n\n for (const field of fields) {\n if (!CRON_FIELD_PATTERN.test(field)) {\n throw new Error(`Invalid cron field: ${field}`);\n }\n }\n}\n\nfunction assertValidOnceExpression(expression: string): void {\n const date = new Date(expression);\n if (Number.isNaN(date.getTime())) {\n throw new Error(\"Once schedule expression must be a valid ISO datetime\");\n }\n}\n\nexport function parseSchedule(\n scheduleType: ScheduleType,\n expression: string,\n timezone: string\n): ParsedSchedule {\n assertValidTimezone(timezone);\n\n if (scheduleType === \"cron\") {\n assertValidCronExpression(expression);\n } else {\n assertValidOnceExpression(expression);\n }\n\n return {\n scheduleType,\n expression: expression.trim(),\n timezone,\n };\n}\n\nexport function computeNextRunAt(parsed: ParsedSchedule, now = new Date()): string {\n if (parsed.scheduleType === \"once\") {\n return new Date(parsed.expression).toISOString();\n }\n\n const next = new Date(now);\n next.setUTCSeconds(0, 0);\n next.setUTCMinutes(next.getUTCMinutes() + 1);\n return next.toISOString();\n}\n","import { randomUUID } from \"node:crypto\";\n\nimport type { Cache } from \"@azlib/cache\";\nimport type { QueueService } from \"@azlib/queue\";\n\nimport type { SchedulerJobRecord } from \"../contracts/scheduler-types.js\";\nimport { computeNextRunAt, parseSchedule } from \"./schedule-parser.js\";\nimport type { JobExecutionStore } from \"./job-execution-store.js\";\nimport type { ScheduleCursorStore } from \"./schedule-cursor-store.js\";\nimport type { SchedulerJobStore } from \"./scheduler-job-store.js\";\n\ninterface LoggerLike {\n debug(message: string, meta?: Record<string, unknown>): void;\n info(message: string, meta?: Record<string, unknown>): void;\n warn(message: string, meta?: Record<string, unknown>): void;\n error(message: string, meta?: Record<string, unknown>): void;\n}\n\nexport interface SchedulerEngineDependencies {\n queueService?: QueueService;\n cache?: Cache<string>;\n logger: LoggerLike;\n jobStore: SchedulerJobStore;\n cursorStore: ScheduleCursorStore;\n executionStore: JobExecutionStore;\n tickIntervalMs: number;\n maxDueJobsPerTick: number;\n}\n\nexport interface SchedulerEngine {\n start(): Promise<void>;\n stop(): Promise<void>;\n computeNextRun(job: SchedulerJobRecord, now?: Date): Promise<string>;\n}\n\nexport function createSchedulerEngine(dependencies: SchedulerEngineDependencies): SchedulerEngine {\n let timer: NodeJS.Timeout | undefined;\n\n async function computeNextRun(job: SchedulerJobRecord, now = new Date()): Promise<string> {\n const cacheKey = `scheduler.nextRun.${job.jobId}.${job.schedule.expression}.${job.schedule.timezone}`;\n const cached = await dependencies.cache?.get(cacheKey);\n if (cached?.status === \"hit\" && cached.value) {\n return cached.value;\n }\n\n const parsed = parseSchedule(\n job.schedule.scheduleType,\n job.schedule.expression,\n job.schedule.timezone\n );\n const nextRunAt = computeNextRunAt(parsed, now);\n\n await dependencies.cache?.set(cacheKey, nextRunAt);\n dependencies.cursorStore.set(job.jobId, nextRunAt, now.toISOString());\n\n return nextRunAt;\n }\n\n async function evaluateTick(): Promise<void> {\n const now = new Date();\n const candidates = dependencies\n .jobStore\n .list()\n .filter((job) => job.enabled)\n .slice(0, dependencies.maxDueJobsPerTick);\n\n for (const job of candidates) {\n const nextRunAt = await computeNextRun(job, now);\n if (new Date(nextRunAt).getTime() > now.getTime()) {\n continue;\n }\n\n const executionId = `exec_${randomUUID()}`;\n dependencies.executionStore.create({\n executionId,\n jobId: job.jobId,\n scheduledFor: nextRunAt,\n triggeredAt: now.toISOString(),\n status: \"queued\",\n attemptCount: 0,\n });\n dependencies.cursorStore.markTriggered(job.jobId, now.toISOString());\n\n if (dependencies.queueService) {\n await dependencies.queueService.enqueue({\n idempotencyKey: `scheduler:${job.jobId}:${nextRunAt}`,\n payloadRef: {\n executionId,\n handlerKey: job.handlerKey,\n config: job.config,\n },\n });\n }\n\n dependencies.logger.info(\"scheduler.job.triggered\", {\n executionId,\n jobId: job.jobId,\n scheduledFor: nextRunAt,\n });\n }\n }\n\n return {\n async start() {\n if (timer) {\n return;\n }\n\n dependencies.logger.info(\"scheduler.runtime.started\", {\n tickIntervalMs: dependencies.tickIntervalMs,\n });\n timer = setInterval(() => {\n void evaluateTick().catch((error: unknown) => {\n dependencies.logger.error(\"scheduler.tick.failed\", {\n error: error instanceof Error ? error.message : \"Unknown scheduler error\",\n });\n });\n }, dependencies.tickIntervalMs);\n },\n async stop() {\n if (!timer) {\n return;\n }\n clearInterval(timer);\n timer = undefined;\n dependencies.logger.info(\"scheduler.runtime.stopped\");\n },\n computeNextRun,\n };\n}\n","export type SchedulerEventType =\n | \"job-created\"\n | \"job-updated\"\n | \"job-paused\"\n | \"job-resumed\"\n | \"job-deleted\"\n | \"triggered\"\n | \"skipped\"\n | \"retry\"\n | \"failed\";\n\nexport interface SchedulerEventRecord {\n eventId: string;\n eventType: SchedulerEventType;\n timestamp: string;\n jobId?: string;\n executionId?: string;\n metadata?: Record<string, unknown>;\n}\n\nexport interface SchedulerEventBus {\n emit(event: Omit<SchedulerEventRecord, \"eventId\" | \"timestamp\">): SchedulerEventRecord;\n list(): SchedulerEventRecord[];\n}\n\nexport function createInMemorySchedulerEventBus(): SchedulerEventBus {\n const events: SchedulerEventRecord[] = [];\n\n return {\n emit(event) {\n const record: SchedulerEventRecord = {\n eventId: `evt_${Math.random().toString(36).slice(2, 12)}`,\n timestamp: new Date().toISOString(),\n ...event,\n };\n events.push(record);\n return record;\n },\n list() {\n return [...events];\n },\n };\n}\n","export type SchedulerHandler<TConfig = unknown> = (input: TConfig) => Promise<void>;\n\nexport interface SchedulerHandlerRegistry {\n register<TConfig>(handlerKey: string, handler: SchedulerHandler<TConfig>): void;\n resolve(handlerKey: string): SchedulerHandler | null;\n has(handlerKey: string): boolean;\n}\n\nexport function createSchedulerHandlerRegistry(): SchedulerHandlerRegistry {\n const handlers = new Map<string, SchedulerHandler>();\n\n return {\n register(handlerKey, handler) {\n handlers.set(handlerKey, handler as SchedulerHandler);\n },\n resolve(handlerKey) {\n return handlers.get(handlerKey) ?? null;\n },\n has(handlerKey) {\n return handlers.has(handlerKey);\n },\n };\n}\n","import type { SchedulerJobDefinition, SchedulerJobRecord } from \"../contracts/scheduler-types.js\";\n\nexport interface SchedulerJobStore {\n create(jobId: string, definition: SchedulerJobDefinition): SchedulerJobRecord;\n update(jobId: string, patch: Partial<SchedulerJobDefinition>): SchedulerJobRecord | null;\n setEnabled(jobId: string, enabled: boolean): SchedulerJobRecord | null;\n get(jobId: string): SchedulerJobRecord | null;\n list(): SchedulerJobRecord[];\n remove(jobId: string): boolean;\n}\n\nexport function createInMemorySchedulerJobStore(): SchedulerJobStore {\n const jobs = new Map<string, SchedulerJobRecord>();\n\n return {\n create(jobId, definition) {\n const now = new Date().toISOString();\n const created: SchedulerJobRecord = {\n ...definition,\n jobId,\n enabled: definition.enabled ?? true,\n createdAt: now,\n updatedAt: now,\n };\n jobs.set(jobId, created);\n return created;\n },\n update(jobId, patch) {\n const current = jobs.get(jobId);\n if (!current) {\n return null;\n }\n const updated: SchedulerJobRecord = {\n ...current,\n ...patch,\n updatedAt: new Date().toISOString(),\n };\n jobs.set(jobId, updated);\n return updated;\n },\n setEnabled(jobId, enabled) {\n const current = jobs.get(jobId);\n if (!current) {\n return null;\n }\n const updated: SchedulerJobRecord = {\n ...current,\n enabled,\n updatedAt: new Date().toISOString(),\n };\n jobs.set(jobId, updated);\n return updated;\n },\n get(jobId) {\n return jobs.get(jobId) ?? null;\n },\n list() {\n return Array.from(jobs.values());\n },\n remove(jobId) {\n return jobs.delete(jobId);\n },\n };\n}\n","import { createConsoleTransport, createLogger } from \"@azlib/logger\";\n\nexport interface SchedulerLogger {\n debug(message: string, meta?: Record<string, unknown>): void;\n info(message: string, meta?: Record<string, unknown>): void;\n warn(message: string, meta?: Record<string, unknown>): void;\n error(message: string, meta?: Record<string, unknown>): void;\n}\n\nexport function createSchedulerLogger(): SchedulerLogger {\n return createLogger({\n level: \"info\",\n transports: [createConsoleTransport()],\n });\n}\n","import type { SchedulerEngine } from \"./scheduler-engine.js\";\n\nexport interface SchedulerRuntime {\n start(): Promise<void>;\n stop(): Promise<void>;\n}\n\nexport function createSchedulerRuntime(engine: SchedulerEngine): SchedulerRuntime {\n let started = false;\n\n return {\n async start() {\n if (started) {\n return;\n }\n started = true;\n await engine.start();\n },\n async stop() {\n if (!started) {\n return;\n }\n started = false;\n await engine.stop();\n },\n };\n}\n","import type { SchedulerServiceOptions } from \"../contracts/scheduler-types.js\";\n\nexport function assertRuntimeConfig(options: SchedulerServiceOptions): void {\n if (options.tickIntervalMs !== undefined && options.tickIntervalMs <= 0) {\n throw new Error(\"tickIntervalMs must be greater than 0\");\n }\n if (options.maxDueJobsPerTick !== undefined && options.maxDueJobsPerTick < 1) {\n throw new Error(\"maxDueJobsPerTick must be at least 1\");\n }\n}\n","import type {\n SchedulerExecutionQuery,\n SchedulerExecutionRecord,\n SchedulerJobListItem,\n} from \"../contracts/scheduler-types.js\";\n\nexport function toJobListItem(input: {\n jobId: string;\n name: string;\n enabled: boolean;\n timezone: string;\n nextRunAt?: string;\n}): SchedulerJobListItem {\n return {\n jobId: input.jobId,\n name: input.name,\n enabled: input.enabled,\n timezone: input.timezone,\n nextRunAt: input.nextRunAt,\n };\n}\n\nexport function filterExecutions(\n items: SchedulerExecutionRecord[],\n query?: SchedulerExecutionQuery\n): SchedulerExecutionRecord[] {\n if (!query) {\n return items;\n }\n\n const fromTime = query.from ? new Date(query.from).getTime() : undefined;\n const toTime = query.to ? new Date(query.to).getTime() : undefined;\n\n return items\n .filter((item) => (query.jobId ? item.jobId === query.jobId : true))\n .filter((item) => (query.status ? item.status === query.status : true))\n .filter((item) => {\n if (fromTime === undefined) {\n return true;\n }\n return new Date(item.triggeredAt).getTime() >= fromTime;\n })\n .filter((item) => {\n if (toTime === undefined) {\n return true;\n }\n return new Date(item.triggeredAt).getTime() <= toTime;\n })\n .slice(0, query.limit ?? items.length);\n}\n","import { randomUUID } from \"node:crypto\";\n\nimport type { SchedulerExecutionRecord } from \"../contracts/scheduler-types.js\";\nimport type { JobExecutionStore } from \"./job-execution-store.js\";\n\nexport function retryFailedExecutionById(\n allExecutions: SchedulerExecutionRecord[],\n executionStore: JobExecutionStore,\n executionId: string\n): SchedulerExecutionRecord {\n const target = allExecutions.find((item) => item.executionId === executionId);\n if (!target) {\n throw new Error(`Execution not found: ${executionId}`);\n }\n if (target.status !== \"failed\" && target.status !== \"dead-letter\") {\n throw new Error(\"Only failed or dead-letter executions can be retried\");\n }\n\n const retryExecutionId = `exec_${randomUUID()}`;\n const retry: SchedulerExecutionRecord = {\n ...target,\n executionId: retryExecutionId,\n status: \"queued\",\n attemptCount: target.attemptCount + 1,\n triggeredAt: new Date().toISOString(),\n };\n executionStore.create(retry);\n return retry;\n}\n","import { randomUUID } from \"node:crypto\";\n\nimport type { QueueService } from \"@azlib/queue\";\n\nimport type {\n SchedulerExecutionQuery,\n SchedulerJobDefinition,\n SchedulerService,\n SchedulerServiceOptions,\n} from \"../contracts/scheduler-types.js\";\nimport { createInMemoryJobExecutionStore } from \"./job-execution-store.js\";\nimport { createInMemoryScheduleCursorStore } from \"./schedule-cursor-store.js\";\nimport { createSchedulerCache } from \"./scheduler-cache.js\";\nimport { createSchedulerEngine } from \"./scheduler-engine.js\";\nimport { createInMemorySchedulerEventBus } from \"./scheduler-events.js\";\nimport { createSchedulerHandlerRegistry } from \"./scheduler-handler-registry.js\";\nimport { createInMemorySchedulerJobStore } from \"./scheduler-job-store.js\";\nimport { createSchedulerLogger } from \"./scheduler-logger.js\";\nimport { createSchedulerRuntime } from \"./scheduler-runtime.js\";\nimport { assertRuntimeConfig } from \"./scheduler-runtime-config.js\";\nimport { filterExecutions, toJobListItem } from \"./scheduler-service-query.js\";\nimport { retryFailedExecutionById } from \"./scheduler-service-retry.js\";\n\nexport function createSchedulerService(options: SchedulerServiceOptions): {\n service: SchedulerService;\n handlers: ReturnType<typeof createSchedulerHandlerRegistry>;\n} {\n assertRuntimeConfig(options);\n\n const logger = options.logger ?? createSchedulerLogger();\n const cache = options.cache ?? createSchedulerCache();\n const jobStore = createInMemorySchedulerJobStore();\n const cursorStore = createInMemoryScheduleCursorStore();\n const executionStore = createInMemoryJobExecutionStore();\n const events = createInMemorySchedulerEventBus();\n const handlers = createSchedulerHandlerRegistry();\n\n const queueService: QueueService | undefined = options.queueService;\n\n const engine = createSchedulerEngine({\n queueService,\n cache,\n logger,\n jobStore,\n cursorStore,\n executionStore,\n tickIntervalMs: options.tickIntervalMs ?? 1000,\n maxDueJobsPerTick: options.maxDueJobsPerTick ?? 200,\n });\n\n const runtime = createSchedulerRuntime(engine);\n\n const service: SchedulerService = {\n async registerJob<TConfig>(job: SchedulerJobDefinition<TConfig>) {\n if (!handlers.has(job.handlerKey)) {\n throw new Error(`Unknown handlerKey: ${job.handlerKey}`);\n }\n\n const jobId = `job_${randomUUID()}`;\n const created = jobStore.create(jobId, job);\n const nextRunAt = await engine.computeNextRun(created);\n cursorStore.set(jobId, nextRunAt, new Date().toISOString());\n events.emit({ eventType: \"job-created\", jobId, metadata: { name: job.name } });\n return { jobId };\n },\n\n async updateJob<TConfig>(jobId: string, patch: Partial<SchedulerJobDefinition<TConfig>>) {\n const updated = jobStore.update(jobId, patch as Partial<SchedulerJobDefinition>);\n if (!updated) {\n throw new Error(`Job not found: ${jobId}`);\n }\n\n const nextRunAt = await engine.computeNextRun(updated);\n cursorStore.set(jobId, nextRunAt, new Date().toISOString());\n events.emit({ eventType: \"job-updated\", jobId });\n },\n\n async pauseJob(jobId: string) {\n const updated = jobStore.setEnabled(jobId, false);\n if (!updated) {\n throw new Error(`Job not found: ${jobId}`);\n }\n events.emit({ eventType: \"job-paused\", jobId });\n },\n\n async resumeJob(jobId: string) {\n const updated = jobStore.setEnabled(jobId, true);\n if (!updated) {\n throw new Error(`Job not found: ${jobId}`);\n }\n events.emit({ eventType: \"job-resumed\", jobId });\n },\n\n async deleteJob(jobId: string) {\n const removed = jobStore.remove(jobId);\n cursorStore.remove(jobId);\n if (!removed) {\n throw new Error(`Job not found: ${jobId}`);\n }\n events.emit({ eventType: \"job-deleted\", jobId });\n },\n\n async listJobs() {\n return jobStore.list().map((job) => {\n const cursor = cursorStore.get(job.jobId);\n return toJobListItem({\n jobId: job.jobId,\n name: job.name,\n enabled: job.enabled,\n timezone: job.schedule.timezone,\n nextRunAt: cursor?.nextRunAt,\n });\n });\n },\n\n async listExecutions(query) {\n const all = jobStore\n .list()\n .flatMap((job) => executionStore.listByJob(job.jobId));\n return filterExecutions(all, query);\n },\n\n async retryFailedExecution(executionId: string) {\n const all = jobStore.list().flatMap((job) => executionStore.listByJob(job.jobId));\n const retry = retryFailedExecutionById(all, executionStore, executionId);\n events.emit({\n eventType: \"retry\",\n jobId: retry.jobId,\n executionId: retry.executionId,\n metadata: { previousExecutionId: executionId },\n });\n },\n\n async start() {\n logger.info(\"scheduler.service.start\", { mode: options.mode });\n await runtime.start();\n },\n\n async stop() {\n logger.info(\"scheduler.service.stop\", { mode: options.mode });\n await runtime.stop();\n },\n };\n\n return {\n service,\n handlers,\n };\n}\n","import type { SchedulerService } from \"../contracts/scheduler-types.js\";\n\nexport interface SchedulerDashboardHealth {\n totalJobs: number;\n enabledJobs: number;\n pausedJobs: number;\n failedExecutions: number;\n}\n\nexport async function querySchedulerHealth(\n scheduler: SchedulerService\n): Promise<SchedulerDashboardHealth> {\n const jobs = await scheduler.listJobs();\n const executions = await scheduler.listExecutions({ status: \"failed\" });\n\n return {\n totalJobs: jobs.length,\n enabledJobs: jobs.filter((job) => job.enabled).length,\n pausedJobs: jobs.filter((job) => !job.enabled).length,\n failedExecutions: executions.length,\n };\n}\n\nexport async function querySchedulerItems(scheduler: SchedulerService) {\n const jobs = await scheduler.listJobs();\n const executions = await scheduler.listExecutions({ limit: 100 });\n\n return jobs.map((job) => ({\n ...job,\n executions: executions.filter((execution) => execution.jobId === job.jobId),\n }));\n}\n","import type { SchedulerService } from \"../contracts/scheduler-types.js\";\nimport { querySchedulerHealth, querySchedulerItems } from \"./queue-queries.js\";\n\nexport interface SchedulerDashboardService {\n getHealth(): ReturnType<typeof querySchedulerHealth>;\n listItems(): ReturnType<typeof querySchedulerItems>;\n pauseJob(jobId: string): Promise<void>;\n resumeJob(jobId: string): Promise<void>;\n retryExecution(executionId: string): Promise<void>;\n}\n\nexport function createSchedulerDashboardService(\n scheduler: SchedulerService\n): SchedulerDashboardService {\n return {\n getHealth: () => querySchedulerHealth(scheduler),\n listItems: () => querySchedulerItems(scheduler),\n pauseJob: (jobId) => scheduler.pauseJob(jobId),\n resumeJob: (jobId) => scheduler.resumeJob(jobId),\n retryExecution: (executionId) => scheduler.retryFailedExecution(executionId),\n };\n}\n","import type {\n SchedulerHandlerRegistry,\n SchedulerService,\n SchedulerServiceOptions,\n} from \"./src/contracts/scheduler-types.js\";\nimport { bindSchedulerToHost } from \"./src/core/scheduler-host-binding.js\";\nimport {\n CronWeekday,\n createCronExpression,\n} from \"./src/core/cron-expression-builder.js\";\nimport { createSchedulerService as createSchedulerServiceInternal } from \"./src/core/scheduler-service.js\";\n\nexport type {\n SchedulerHandlerRegistry,\n SchedulerJobDefinition,\n SchedulerJobRecord,\n SchedulerMissedRunPolicy,\n SchedulerMode,\n SchedulerOverlapPolicy,\n SchedulerScheduleConfig,\n SchedulerService,\n SchedulerServiceOptions,\n} from \"./src/contracts/scheduler-types.js\";\nexport type { CronWeekdayValue } from \"./src/core/cron-expression-builder.js\";\nexport type { SchedulerHostAdapter } from \"./src/contracts/scheduler-host.js\";\nexport { bindSchedulerToHost };\nexport { CronWeekday, createCronExpression };\nexport { createSchedulerDashboardService } from \"./src/dashboard/queue-dashboard-service.js\";\n\nexport function createSchedulerService(options: SchedulerServiceOptions): {\n service: SchedulerService;\n handlers: SchedulerHandlerRegistry;\n} {\n return createSchedulerServiceInternal(options);\n}\n"],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@azlib/scheduler",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/hanhn-dev/azlib.git"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist",
|
|
12
|
+
"README.md"
|
|
13
|
+
],
|
|
14
|
+
"sideEffects": false,
|
|
15
|
+
"exports": {
|
|
16
|
+
".": {
|
|
17
|
+
"types": "./dist/index.d.mts",
|
|
18
|
+
"import": "./dist/index.mjs",
|
|
19
|
+
"require": "./dist/index.cjs"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"@azlib/cache": "0.2.0",
|
|
24
|
+
"@azlib/logger": "0.2.0",
|
|
25
|
+
"@azlib/queue": "0.2.1"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@types/node": "^22.10.0",
|
|
29
|
+
"tsdown": "^0.22.1",
|
|
30
|
+
"typescript": "5.5.4",
|
|
31
|
+
"vitest": "^4.1.5",
|
|
32
|
+
"@repo/typescript-config": "0.0.0"
|
|
33
|
+
},
|
|
34
|
+
"publishConfig": {
|
|
35
|
+
"access": "public",
|
|
36
|
+
"registry": "https://registry.npmjs.org"
|
|
37
|
+
},
|
|
38
|
+
"scripts": {
|
|
39
|
+
"build": "rm -rf dist && tsdown",
|
|
40
|
+
"dev": "tsdown --watch",
|
|
41
|
+
"lint": "tsc -p tsconfig.json --noEmit",
|
|
42
|
+
"test": "vitest run",
|
|
43
|
+
"clean": "rm -rf .turbo node_modules dist"
|
|
44
|
+
}
|
|
45
|
+
}
|