oqronkit 0.0.1-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. package/README.md +127 -0
  2. package/dist/chunk-I6QFT3MR.mjs +1732 -0
  3. package/dist/chunk-PLN5A6LU.mjs +1447 -0
  4. package/dist/core/config/config-loader.d.ts +3 -0
  5. package/dist/core/config/config-loader.d.ts.map +1 -0
  6. package/dist/core/config/default-config.d.ts +4 -0
  7. package/dist/core/config/default-config.d.ts.map +1 -0
  8. package/dist/core/config/define-config.d.ts +3 -0
  9. package/dist/core/config/define-config.d.ts.map +1 -0
  10. package/dist/core/config/find-up.d.ts +2 -0
  11. package/dist/core/config/find-up.d.ts.map +1 -0
  12. package/dist/core/config/schema.d.ts +306 -0
  13. package/dist/core/config/schema.d.ts.map +1 -0
  14. package/dist/core/context/cron-context.d.ts +14 -0
  15. package/dist/core/context/cron-context.d.ts.map +1 -0
  16. package/dist/core/context/cron-context.interface.d.ts +14 -0
  17. package/dist/core/context/cron-context.interface.d.ts.map +1 -0
  18. package/dist/core/context/job-context.d.ts +22 -0
  19. package/dist/core/context/job-context.d.ts.map +1 -0
  20. package/dist/core/context/schedule-context.d.ts +31 -0
  21. package/dist/core/context/schedule-context.d.ts.map +1 -0
  22. package/dist/core/errors/base.error.d.ts +13 -0
  23. package/dist/core/errors/base.error.d.ts.map +1 -0
  24. package/dist/core/events/event-bus.d.ts +16 -0
  25. package/dist/core/events/event-bus.d.ts.map +1 -0
  26. package/dist/core/index.d.ts +24 -0
  27. package/dist/core/index.d.ts.map +1 -0
  28. package/dist/core/logger/index.d.ts +30 -0
  29. package/dist/core/logger/index.d.ts.map +1 -0
  30. package/dist/core/registry.d.ts +13 -0
  31. package/dist/core/registry.d.ts.map +1 -0
  32. package/dist/core/types/config.types.d.ts +119 -0
  33. package/dist/core/types/config.types.d.ts.map +1 -0
  34. package/dist/core/types/cron.types.d.ts +53 -0
  35. package/dist/core/types/cron.types.d.ts.map +1 -0
  36. package/dist/core/types/db.types.d.ts +32 -0
  37. package/dist/core/types/db.types.d.ts.map +1 -0
  38. package/dist/core/types/index.d.ts +7 -0
  39. package/dist/core/types/index.d.ts.map +1 -0
  40. package/dist/core/types/lock.types.d.ts +7 -0
  41. package/dist/core/types/lock.types.d.ts.map +1 -0
  42. package/dist/core/types/module.types.d.ts +8 -0
  43. package/dist/core/types/module.types.d.ts.map +1 -0
  44. package/dist/core/types/scheduler.types.d.ts +62 -0
  45. package/dist/core/types/scheduler.types.d.ts.map +1 -0
  46. package/dist/cron-V0k1GcxJ.d.mts +102 -0
  47. package/dist/cron-V0k1GcxJ.d.ts +102 -0
  48. package/dist/cron.d.mts +2 -0
  49. package/dist/cron.d.ts +2 -0
  50. package/dist/cron.d.ts.map +1 -0
  51. package/dist/cron.js +215 -0
  52. package/dist/cron.mjs +1 -0
  53. package/dist/db/adapters/memory.adapter.d.ts +25 -0
  54. package/dist/db/adapters/memory.adapter.d.ts.map +1 -0
  55. package/dist/db/adapters/namespaced.adapter.d.ts +26 -0
  56. package/dist/db/adapters/namespaced.adapter.d.ts.map +1 -0
  57. package/dist/db/adapters/sqlite.adapter.d.ts +30 -0
  58. package/dist/db/adapters/sqlite.adapter.d.ts.map +1 -0
  59. package/dist/db/index.d.ts +4 -0
  60. package/dist/db/index.d.ts.map +1 -0
  61. package/dist/index.d.mts +797 -0
  62. package/dist/index.d.ts +32 -0
  63. package/dist/index.d.ts.map +1 -0
  64. package/dist/index.js +2738 -0
  65. package/dist/index.mjs +747 -0
  66. package/dist/lock/adapters/db-lock.adapter.d.ts +17 -0
  67. package/dist/lock/adapters/db-lock.adapter.d.ts.map +1 -0
  68. package/dist/lock/adapters/memory-lock.adapter.d.ts +13 -0
  69. package/dist/lock/adapters/memory-lock.adapter.d.ts.map +1 -0
  70. package/dist/lock/adapters/namespaced-lock.adapter.d.ts +12 -0
  71. package/dist/lock/adapters/namespaced-lock.adapter.d.ts.map +1 -0
  72. package/dist/lock/heartbeat-worker.d.ts +16 -0
  73. package/dist/lock/heartbeat-worker.d.ts.map +1 -0
  74. package/dist/lock/index.d.ts +7 -0
  75. package/dist/lock/index.d.ts.map +1 -0
  76. package/dist/lock/leader-election.d.ts +16 -0
  77. package/dist/lock/leader-election.d.ts.map +1 -0
  78. package/dist/lock/stall-detector.d.ts +23 -0
  79. package/dist/lock/stall-detector.d.ts.map +1 -0
  80. package/dist/scheduler/cron-engine.d.ts +42 -0
  81. package/dist/scheduler/cron-engine.d.ts.map +1 -0
  82. package/dist/scheduler/define-cron.d.ts +36 -0
  83. package/dist/scheduler/define-cron.d.ts.map +1 -0
  84. package/dist/scheduler/define-schedule.d.ts +52 -0
  85. package/dist/scheduler/define-schedule.d.ts.map +1 -0
  86. package/dist/scheduler/expression-parser.d.ts +2 -0
  87. package/dist/scheduler/expression-parser.d.ts.map +1 -0
  88. package/dist/scheduler/index.d.ts +10 -0
  89. package/dist/scheduler/index.d.ts.map +1 -0
  90. package/dist/scheduler/missed-fire.handler.d.ts +8 -0
  91. package/dist/scheduler/missed-fire.handler.d.ts.map +1 -0
  92. package/dist/scheduler/registry-schedule.d.ts +6 -0
  93. package/dist/scheduler/registry-schedule.d.ts.map +1 -0
  94. package/dist/scheduler/registry.d.ts +6 -0
  95. package/dist/scheduler/registry.d.ts.map +1 -0
  96. package/dist/scheduler/schedule-engine.d.ts +36 -0
  97. package/dist/scheduler/schedule-engine.d.ts.map +1 -0
  98. package/dist/scheduler-HRR3UXGE.mjs +1 -0
  99. package/dist/scheduler.d.mts +248 -0
  100. package/dist/scheduler.d.ts +248 -0
  101. package/dist/scheduler.js +1461 -0
  102. package/dist/scheduler.mjs +1 -0
  103. package/dist/server/express.d.ts +9 -0
  104. package/dist/server/express.d.ts.map +1 -0
  105. package/dist/server/fastify.d.ts +9 -0
  106. package/dist/server/fastify.d.ts.map +1 -0
  107. package/dist/server/handlers.d.ts +15 -0
  108. package/dist/server/handlers.d.ts.map +1 -0
  109. package/package.json +59 -0
@@ -0,0 +1,797 @@
1
+ import { z } from 'zod';
2
+ import { Logger } from 'voltlog-io';
3
+ export { Logger } from 'voltlog-io';
4
+ import { EventEmitter } from 'eventemitter3';
5
+ import Database from 'better-sqlite3';
6
+
7
+ /**
8
+ * OqronKit Logger — powered by voltlog-io.
9
+ *
10
+ * Re-exports a configured voltlog-io logger instance.
11
+ * Users can customize via oqron.config.ts `logger` section.
12
+ */
13
+
14
+ interface ChronoLoggerConfig {
15
+ /** Enable/disable logging entirely. Default: true */
16
+ enabled?: boolean;
17
+ /** Minimum log level. Default: 'INFO' */
18
+ level?: string;
19
+ /** Pretty-print with colors/icons for dev. Default: false */
20
+ prettify?: boolean;
21
+ /** Show metadata object in logs. Default: true */
22
+ showMetadata?: boolean;
23
+ /** Custom voltlog-io transport handler */
24
+ handler?: (entry: any) => void | Promise<void>;
25
+ /** Keys to redact from metadata/payload. */
26
+ redact?: string[];
27
+ /** Bring-your-own logger instance (Pino, winston, etc) */
28
+ logger?: any;
29
+ }
30
+ /**
31
+ * Create a OqronKit logger from config.
32
+ * This is the single factory used internally.
33
+ */
34
+ declare function createLogger(config?: ChronoLoggerConfig, context?: Record<string, unknown>): Logger;
35
+
36
+ interface ICronContext {
37
+ readonly id: string;
38
+ readonly log: Logger;
39
+ readonly signal: AbortSignal;
40
+ readonly firedAt: Date;
41
+ readonly scheduleName: string;
42
+ readonly duration: number;
43
+ readonly environment?: string;
44
+ readonly project?: string;
45
+ progress(value: number, label?: string): void;
46
+ getProgress(): number;
47
+ }
48
+
49
+ type MissedFirePolicy = "skip" | "run-once" | "run-all";
50
+ type OverlapPolicy = "skip" | "run" | boolean;
51
+ interface EveryConfig {
52
+ seconds?: number;
53
+ minutes?: number;
54
+ hours?: number;
55
+ }
56
+ interface RetryConfig {
57
+ max: number;
58
+ strategy: "exponential" | "fixed";
59
+ baseDelay: number;
60
+ }
61
+ interface CronHooks {
62
+ beforeRun?: (ctx: ICronContext) => Promise<void> | void;
63
+ afterRun?: (ctx: ICronContext, result: unknown) => Promise<void> | void;
64
+ onError?: (ctx: ICronContext, error: Error) => Promise<void> | void;
65
+ onMissedFire?: (ctx: ICronContext, missedAt: Date) => Promise<void> | void;
66
+ }
67
+ interface CronDefinition {
68
+ name: string;
69
+ expression?: string;
70
+ intervalMs?: number;
71
+ timezone?: string;
72
+ missedFire: MissedFirePolicy;
73
+ overlap: OverlapPolicy;
74
+ guaranteedWorker?: boolean;
75
+ heartbeatMs?: number;
76
+ lockTtlMs?: number;
77
+ timeout?: number;
78
+ tags: string[];
79
+ /** Override global history rolling. `true` = infinite, `false` = none, `number` = max retained jobs. */
80
+ keepHistory?: boolean | number;
81
+ /** Keep specific bounded history length for failed jobs overriding general logic */
82
+ keepFailedHistory?: boolean | number;
83
+ handler: (ctx: ICronContext) => Promise<unknown>;
84
+ hooks?: CronHooks;
85
+ retries?: RetryConfig;
86
+ }
87
+ interface JobRecord {
88
+ id: string;
89
+ scheduleId?: string;
90
+ status: "running" | "completed" | "failed" | "missed" | "dead";
91
+ startedAt: Date;
92
+ completedAt?: Date;
93
+ error?: string;
94
+ result?: string;
95
+ progressPercent?: number;
96
+ progressLabel?: string;
97
+ attempts?: number;
98
+ durationMs?: number;
99
+ }
100
+
101
+ interface ScheduleRecurring {
102
+ frequency: "daily" | "weekly" | "monthly" | "yearly";
103
+ dayOfMonth?: number;
104
+ at?: {
105
+ hour: number;
106
+ minute: number;
107
+ };
108
+ months?: number[];
109
+ }
110
+ interface ScheduleRunAfter {
111
+ days?: number;
112
+ hours?: number;
113
+ minutes?: number;
114
+ seconds?: number;
115
+ }
116
+ interface ScheduleHooks<TPayload = unknown> {
117
+ beforeRun?: (ctx: IScheduleContext<TPayload>) => Promise<void> | void;
118
+ afterRun?: (ctx: IScheduleContext<TPayload>, result: unknown) => Promise<void> | void;
119
+ onError?: (ctx: IScheduleContext<TPayload>, error: Error) => Promise<void> | void;
120
+ onMissedFire?: (ctx: IScheduleContext<TPayload>, missedAt: Date) => Promise<void> | void;
121
+ }
122
+ interface IScheduleContext<TPayload = unknown> {
123
+ name: string;
124
+ firedAt: Date;
125
+ payload: TPayload;
126
+ duration: number;
127
+ environment?: string;
128
+ project?: string;
129
+ log(level: string, message: string, meta?: Record<string, unknown>): void;
130
+ progress(percent: number, label?: string): void;
131
+ }
132
+ interface ScheduleDefinition<TPayload = unknown> {
133
+ name: string;
134
+ runAt?: Date;
135
+ runAfter?: ScheduleRunAfter;
136
+ recurring?: ScheduleRecurring;
137
+ rrule?: string;
138
+ every?: {
139
+ minutes?: number;
140
+ hours?: number;
141
+ seconds?: number;
142
+ };
143
+ timezone?: string;
144
+ missedFire: MissedFirePolicy;
145
+ overlap: OverlapPolicy;
146
+ guaranteedWorker?: boolean;
147
+ heartbeatMs?: number;
148
+ lockTtlMs?: number;
149
+ timeout?: number;
150
+ tags: string[];
151
+ /** Override global history rolling. `true` = infinite, `false` = none, `number` = max retained jobs. */
152
+ keepHistory?: boolean | number;
153
+ /** Keep specific bounded history length for failed jobs overriding general logic */
154
+ keepFailedHistory?: boolean | number;
155
+ condition?: (ctx: IScheduleContext<TPayload>) => Promise<boolean> | boolean;
156
+ handler: (ctx: IScheduleContext<TPayload>) => Promise<unknown>;
157
+ hooks?: ScheduleHooks<TPayload>;
158
+ retries?: RetryConfig;
159
+ payload?: TPayload;
160
+ }
161
+
162
+ interface IOqronAdapter {
163
+ /** Insert or update a schedule definition */
164
+ upsertSchedule(def: CronDefinition | ScheduleDefinition): Promise<void>;
165
+ /** Get schedules that are due to fire (nextRunAt <= now, or never run) */
166
+ getDueSchedules(now: Date, limit: number, prefix?: string): Promise<Pick<CronDefinition | ScheduleDefinition, "name">[]>;
167
+ /** Get all registered schedules and their run metadata */
168
+ getSchedules(prefix?: string): Promise<Array<{
169
+ name: string;
170
+ lastRunAt: Date | null;
171
+ nextRunAt: Date | null;
172
+ }>>;
173
+ /** Update nextRunAt for a schedule */
174
+ updateNextRun(scheduleId: string, nextRunAt: Date | null): Promise<void>;
175
+ /** Record a job execution (insert or update) */
176
+ recordExecution(job: JobRecord): Promise<void>;
177
+ /** Update progress of an active job */
178
+ updateJobProgress(id: string, progressPercent: number, progressLabel?: string): Promise<void>;
179
+ /** Get execution history for a schedule */
180
+ getExecutions(scheduleId: string, opts: {
181
+ limit: number;
182
+ offset: number;
183
+ }): Promise<JobRecord[]>;
184
+ /** Get all jobs currently marked as running */
185
+ getActiveJobs(): Promise<JobRecord[]>;
186
+ /** Clean old execution records */
187
+ cleanOldExecutions(before: Date): Promise<number>;
188
+ /** Roll history based on config settings */
189
+ pruneHistoryForSchedule(scheduleId: string, keepJobHistory: number | boolean, keepFailedJobHistory: number | boolean): Promise<void>;
190
+ }
191
+
192
+ interface ILockAdapter {
193
+ acquire(key: string, ownerId: string, ttlMs: number): Promise<boolean>;
194
+ renew(key: string, ownerId: string, ttlMs: number): Promise<boolean>;
195
+ release(key: string, ownerId: string): Promise<void>;
196
+ isOwner(key: string, ownerId: string): Promise<boolean>;
197
+ }
198
+
199
+ declare const OqronConfigSchema: z.ZodObject<{
200
+ project: z.ZodOptional<z.ZodString>;
201
+ environment: z.ZodDefault<z.ZodString>;
202
+ db: z.ZodOptional<z.ZodUnion<[z.ZodType<IOqronAdapter, z.ZodTypeDef, IOqronAdapter>, z.ZodObject<{
203
+ adapter: z.ZodEnum<["sqlite", "memory", "postgres", "mysql", "mongodb", "redis"]>;
204
+ url: z.ZodOptional<z.ZodString>;
205
+ poolMin: z.ZodDefault<z.ZodNumber>;
206
+ poolMax: z.ZodDefault<z.ZodNumber>;
207
+ tablePrefix: z.ZodDefault<z.ZodString>;
208
+ migrations: z.ZodDefault<z.ZodUnion<[z.ZodEnum<["auto", "manual"]>, z.ZodLiteral<false>]>>;
209
+ ssl: z.ZodDefault<z.ZodBoolean>;
210
+ }, "strip", z.ZodTypeAny, {
211
+ adapter: "sqlite" | "memory" | "postgres" | "mysql" | "mongodb" | "redis";
212
+ poolMin: number;
213
+ poolMax: number;
214
+ tablePrefix: string;
215
+ migrations: false | "auto" | "manual";
216
+ ssl: boolean;
217
+ url?: string | undefined;
218
+ }, {
219
+ adapter: "sqlite" | "memory" | "postgres" | "mysql" | "mongodb" | "redis";
220
+ url?: string | undefined;
221
+ poolMin?: number | undefined;
222
+ poolMax?: number | undefined;
223
+ tablePrefix?: string | undefined;
224
+ migrations?: false | "auto" | "manual" | undefined;
225
+ ssl?: boolean | undefined;
226
+ }>]>>;
227
+ lock: z.ZodOptional<z.ZodUnion<[z.ZodType<ILockAdapter, z.ZodTypeDef, ILockAdapter>, z.ZodObject<{
228
+ adapter: z.ZodEnum<["db", "memory", "redis"]>;
229
+ url: z.ZodOptional<z.ZodString>;
230
+ ttl: z.ZodDefault<z.ZodNumber>;
231
+ retryDelay: z.ZodDefault<z.ZodNumber>;
232
+ retryCount: z.ZodDefault<z.ZodNumber>;
233
+ }, "strip", z.ZodTypeAny, {
234
+ adapter: "memory" | "redis" | "db";
235
+ ttl: number;
236
+ retryDelay: number;
237
+ retryCount: number;
238
+ url?: string | undefined;
239
+ }, {
240
+ adapter: "memory" | "redis" | "db";
241
+ url?: string | undefined;
242
+ ttl?: number | undefined;
243
+ retryDelay?: number | undefined;
244
+ retryCount?: number | undefined;
245
+ }>]>>;
246
+ broker: z.ZodOptional<z.ZodAny>;
247
+ modules: z.ZodDefault<z.ZodArray<z.ZodEnum<["cron", "scheduler", "queue", "workflow", "batch", "webhook", "pipeline"]>, "many">>;
248
+ cron: z.ZodDefault<z.ZodObject<{
249
+ enable: z.ZodDefault<z.ZodBoolean>;
250
+ timezone: z.ZodOptional<z.ZodString>;
251
+ tickInterval: z.ZodDefault<z.ZodNumber>;
252
+ missedFirePolicy: z.ZodDefault<z.ZodEnum<["skip", "run-once", "run-all"]>>;
253
+ maxConcurrentJobs: z.ZodDefault<z.ZodNumber>;
254
+ leaderElection: z.ZodDefault<z.ZodBoolean>;
255
+ keepJobHistory: z.ZodDefault<z.ZodUnion<[z.ZodBoolean, z.ZodNumber]>>;
256
+ keepFailedJobHistory: z.ZodDefault<z.ZodUnion<[z.ZodBoolean, z.ZodNumber]>>;
257
+ }, "strip", z.ZodTypeAny, {
258
+ enable: boolean;
259
+ tickInterval: number;
260
+ missedFirePolicy: "skip" | "run-once" | "run-all";
261
+ maxConcurrentJobs: number;
262
+ leaderElection: boolean;
263
+ keepJobHistory: number | boolean;
264
+ keepFailedJobHistory: number | boolean;
265
+ timezone?: string | undefined;
266
+ }, {
267
+ enable?: boolean | undefined;
268
+ timezone?: string | undefined;
269
+ tickInterval?: number | undefined;
270
+ missedFirePolicy?: "skip" | "run-once" | "run-all" | undefined;
271
+ maxConcurrentJobs?: number | undefined;
272
+ leaderElection?: boolean | undefined;
273
+ keepJobHistory?: number | boolean | undefined;
274
+ keepFailedJobHistory?: number | boolean | undefined;
275
+ }>>;
276
+ scheduler: z.ZodDefault<z.ZodObject<{
277
+ enable: z.ZodDefault<z.ZodBoolean>;
278
+ tickInterval: z.ZodDefault<z.ZodNumber>;
279
+ keepJobHistory: z.ZodDefault<z.ZodUnion<[z.ZodBoolean, z.ZodNumber]>>;
280
+ keepFailedJobHistory: z.ZodDefault<z.ZodUnion<[z.ZodBoolean, z.ZodNumber]>>;
281
+ }, "strip", z.ZodTypeAny, {
282
+ enable: boolean;
283
+ tickInterval: number;
284
+ keepJobHistory: number | boolean;
285
+ keepFailedJobHistory: number | boolean;
286
+ }, {
287
+ enable?: boolean | undefined;
288
+ tickInterval?: number | undefined;
289
+ keepJobHistory?: number | boolean | undefined;
290
+ keepFailedJobHistory?: number | boolean | undefined;
291
+ }>>;
292
+ jobsDir: z.ZodDefault<z.ZodString>;
293
+ tags: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
294
+ worker: z.ZodDefault<z.ZodObject<{
295
+ concurrency: z.ZodDefault<z.ZodNumber>;
296
+ gracefulShutdownMs: z.ZodDefault<z.ZodNumber>;
297
+ }, "strip", z.ZodTypeAny, {
298
+ concurrency: number;
299
+ gracefulShutdownMs: number;
300
+ }, {
301
+ concurrency?: number | undefined;
302
+ gracefulShutdownMs?: number | undefined;
303
+ }>>;
304
+ logger: z.ZodDefault<z.ZodUnion<[z.ZodLiteral<false>, z.ZodObject<{
305
+ enabled: z.ZodDefault<z.ZodBoolean>;
306
+ level: z.ZodDefault<z.ZodString>;
307
+ prettify: z.ZodDefault<z.ZodBoolean>;
308
+ showMetadata: z.ZodDefault<z.ZodBoolean>;
309
+ redact: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
310
+ }, "strip", z.ZodTypeAny, {
311
+ enabled: boolean;
312
+ level: string;
313
+ prettify: boolean;
314
+ showMetadata: boolean;
315
+ redact: string[];
316
+ }, {
317
+ enabled?: boolean | undefined;
318
+ level?: string | undefined;
319
+ prettify?: boolean | undefined;
320
+ showMetadata?: boolean | undefined;
321
+ redact?: string[] | undefined;
322
+ }>]>>;
323
+ telemetry: z.ZodDefault<z.ZodObject<{
324
+ prometheus: z.ZodDefault<z.ZodObject<{
325
+ enabled: z.ZodDefault<z.ZodBoolean>;
326
+ path: z.ZodDefault<z.ZodString>;
327
+ }, "strip", z.ZodTypeAny, {
328
+ path: string;
329
+ enabled: boolean;
330
+ }, {
331
+ path?: string | undefined;
332
+ enabled?: boolean | undefined;
333
+ }>>;
334
+ opentelemetry: z.ZodDefault<z.ZodObject<{
335
+ enabled: z.ZodDefault<z.ZodBoolean>;
336
+ }, "strip", z.ZodTypeAny, {
337
+ enabled: boolean;
338
+ }, {
339
+ enabled?: boolean | undefined;
340
+ }>>;
341
+ }, "strip", z.ZodTypeAny, {
342
+ prometheus: {
343
+ path: string;
344
+ enabled: boolean;
345
+ };
346
+ opentelemetry: {
347
+ enabled: boolean;
348
+ };
349
+ }, {
350
+ prometheus?: {
351
+ path?: string | undefined;
352
+ enabled?: boolean | undefined;
353
+ } | undefined;
354
+ opentelemetry?: {
355
+ enabled?: boolean | undefined;
356
+ } | undefined;
357
+ }>>;
358
+ shutdown: z.ZodDefault<z.ZodObject<{
359
+ enabled: z.ZodDefault<z.ZodBoolean>;
360
+ timeout: z.ZodDefault<z.ZodNumber>;
361
+ signals: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
362
+ }, "strip", z.ZodTypeAny, {
363
+ enabled: boolean;
364
+ timeout: number;
365
+ signals: string[];
366
+ }, {
367
+ enabled?: boolean | undefined;
368
+ timeout?: number | undefined;
369
+ signals?: string[] | undefined;
370
+ }>>;
371
+ }, "strip", z.ZodTypeAny, {
372
+ environment: string;
373
+ cron: {
374
+ enable: boolean;
375
+ tickInterval: number;
376
+ missedFirePolicy: "skip" | "run-once" | "run-all";
377
+ maxConcurrentJobs: number;
378
+ leaderElection: boolean;
379
+ keepJobHistory: number | boolean;
380
+ keepFailedJobHistory: number | boolean;
381
+ timezone?: string | undefined;
382
+ };
383
+ scheduler: {
384
+ enable: boolean;
385
+ tickInterval: number;
386
+ keepJobHistory: number | boolean;
387
+ keepFailedJobHistory: number | boolean;
388
+ };
389
+ modules: ("cron" | "scheduler" | "queue" | "workflow" | "batch" | "webhook" | "pipeline")[];
390
+ jobsDir: string;
391
+ tags: string[];
392
+ worker: {
393
+ concurrency: number;
394
+ gracefulShutdownMs: number;
395
+ };
396
+ logger: false | {
397
+ enabled: boolean;
398
+ level: string;
399
+ prettify: boolean;
400
+ showMetadata: boolean;
401
+ redact: string[];
402
+ };
403
+ telemetry: {
404
+ prometheus: {
405
+ path: string;
406
+ enabled: boolean;
407
+ };
408
+ opentelemetry: {
409
+ enabled: boolean;
410
+ };
411
+ };
412
+ shutdown: {
413
+ enabled: boolean;
414
+ timeout: number;
415
+ signals: string[];
416
+ };
417
+ project?: string | undefined;
418
+ db?: IOqronAdapter | {
419
+ adapter: "sqlite" | "memory" | "postgres" | "mysql" | "mongodb" | "redis";
420
+ poolMin: number;
421
+ poolMax: number;
422
+ tablePrefix: string;
423
+ migrations: false | "auto" | "manual";
424
+ ssl: boolean;
425
+ url?: string | undefined;
426
+ } | undefined;
427
+ lock?: ILockAdapter | {
428
+ adapter: "memory" | "redis" | "db";
429
+ ttl: number;
430
+ retryDelay: number;
431
+ retryCount: number;
432
+ url?: string | undefined;
433
+ } | undefined;
434
+ broker?: any;
435
+ }, {
436
+ project?: string | undefined;
437
+ environment?: string | undefined;
438
+ db?: IOqronAdapter | {
439
+ adapter: "sqlite" | "memory" | "postgres" | "mysql" | "mongodb" | "redis";
440
+ url?: string | undefined;
441
+ poolMin?: number | undefined;
442
+ poolMax?: number | undefined;
443
+ tablePrefix?: string | undefined;
444
+ migrations?: false | "auto" | "manual" | undefined;
445
+ ssl?: boolean | undefined;
446
+ } | undefined;
447
+ lock?: ILockAdapter | {
448
+ adapter: "memory" | "redis" | "db";
449
+ url?: string | undefined;
450
+ ttl?: number | undefined;
451
+ retryDelay?: number | undefined;
452
+ retryCount?: number | undefined;
453
+ } | undefined;
454
+ broker?: any;
455
+ cron?: {
456
+ enable?: boolean | undefined;
457
+ timezone?: string | undefined;
458
+ tickInterval?: number | undefined;
459
+ missedFirePolicy?: "skip" | "run-once" | "run-all" | undefined;
460
+ maxConcurrentJobs?: number | undefined;
461
+ leaderElection?: boolean | undefined;
462
+ keepJobHistory?: number | boolean | undefined;
463
+ keepFailedJobHistory?: number | boolean | undefined;
464
+ } | undefined;
465
+ scheduler?: {
466
+ enable?: boolean | undefined;
467
+ tickInterval?: number | undefined;
468
+ keepJobHistory?: number | boolean | undefined;
469
+ keepFailedJobHistory?: number | boolean | undefined;
470
+ } | undefined;
471
+ modules?: ("cron" | "scheduler" | "queue" | "workflow" | "batch" | "webhook" | "pipeline")[] | undefined;
472
+ jobsDir?: string | undefined;
473
+ tags?: string[] | undefined;
474
+ worker?: {
475
+ concurrency?: number | undefined;
476
+ gracefulShutdownMs?: number | undefined;
477
+ } | undefined;
478
+ logger?: false | {
479
+ enabled?: boolean | undefined;
480
+ level?: string | undefined;
481
+ prettify?: boolean | undefined;
482
+ showMetadata?: boolean | undefined;
483
+ redact?: string[] | undefined;
484
+ } | undefined;
485
+ telemetry?: {
486
+ prometheus?: {
487
+ path?: string | undefined;
488
+ enabled?: boolean | undefined;
489
+ } | undefined;
490
+ opentelemetry?: {
491
+ enabled?: boolean | undefined;
492
+ } | undefined;
493
+ } | undefined;
494
+ shutdown?: {
495
+ enabled?: boolean | undefined;
496
+ timeout?: number | undefined;
497
+ signals?: string[] | undefined;
498
+ } | undefined;
499
+ }>;
500
+ type ValidatedConfig = z.infer<typeof OqronConfigSchema>;
501
+
502
+ type DbAdapterType = "sqlite" | "memory" | "postgres" | "mysql" | "mongodb" | "redis";
503
+ type LockAdapterType = "db" | "memory" | "redis";
504
+ interface OqronConfig {
505
+ /**
506
+ * The name of this project/service (e.g. 'acme-billing-svc')
507
+ */
508
+ project?: string;
509
+ /**
510
+ * Environment isolation.
511
+ * Workers in 'development' will never execute jobs enqueued in 'production'.
512
+ * @default "development"
513
+ */
514
+ environment?: string;
515
+ /**
516
+ * The primary database adapter (State Store).
517
+ * Union of explicit DI or declarative config.
518
+ */
519
+ db?: IOqronAdapter | {
520
+ adapter: DbAdapterType;
521
+ url?: string;
522
+ poolMin?: number;
523
+ poolMax?: number;
524
+ tablePrefix?: string;
525
+ migrations?: "auto" | "manual" | false;
526
+ ssl?: boolean;
527
+ };
528
+ /**
529
+ * The distributed lock adapter for safe concurrency.
530
+ * Union of explicit DI or declarative config.
531
+ */
532
+ lock?: ILockAdapter | {
533
+ adapter: LockAdapterType;
534
+ url?: string;
535
+ ttl?: number;
536
+ retryDelay?: number;
537
+ retryCount?: number;
538
+ };
539
+ /**
540
+ * The high-throughput message broker (optional, for PubSub/Queueing at scale)
541
+ */
542
+ broker?: any;
543
+ /**
544
+ * List of core modules to enable.
545
+ * e.g. ['cron', 'queue', 'workflow', 'batch', 'webhook', 'pipeline']
546
+ * @default []
547
+ */
548
+ modules?: ("cron" | "scheduler" | "queue" | "workflow" | "batch" | "webhook" | "pipeline")[];
549
+ /**
550
+ * Module-specific configs
551
+ */
552
+ cron?: {
553
+ enable?: boolean;
554
+ timezone?: string;
555
+ tickInterval?: number;
556
+ missedFirePolicy?: "skip" | "run-once" | "run-all";
557
+ maxConcurrentJobs?: number;
558
+ leaderElection?: boolean;
559
+ /** Rolling execution history. `true` = infinite, `false` = 0, `number` = keep N */
560
+ keepJobHistory?: boolean | number;
561
+ /** Override for failed tasks. Handled explicitly under errors */
562
+ keepFailedJobHistory?: boolean | number;
563
+ };
564
+ scheduler?: {
565
+ enable?: boolean;
566
+ tickInterval?: number;
567
+ keepJobHistory?: boolean | number;
568
+ keepFailedJobHistory?: boolean | number;
569
+ };
570
+ /**
571
+ * Directory to auto-discover job definition files from.
572
+ * OqronKit.init() scans this directory recursively for .ts/.js files
573
+ * that export definitions and registers them automatically.
574
+ * @default "./src/jobs"
575
+ */
576
+ jobsDir?: string;
577
+ /**
578
+ * Global tags applied to every job processed by this node.
579
+ * @default []
580
+ */
581
+ tags?: string[];
582
+ /**
583
+ * Worker-level configurations
584
+ */
585
+ worker?: {
586
+ /** Number of concurrent jobs this node processes simultaneously */
587
+ concurrency?: number;
588
+ /** Time in ms to wait for active jobs before SIGTERM exits */
589
+ gracefulShutdownMs?: number;
590
+ };
591
+ /**
592
+ * Logger configuration (powered by voltlog-io).
593
+ * Set to `false` to disable logging entirely.
594
+ */
595
+ logger?: ChronoLoggerConfig | false;
596
+ /**
597
+ * Telemetry configuration
598
+ */
599
+ telemetry?: {
600
+ prometheus?: {
601
+ enabled?: boolean;
602
+ path?: string;
603
+ };
604
+ opentelemetry?: {
605
+ enabled?: boolean;
606
+ };
607
+ };
608
+ /**
609
+ * Graceful shutdown configuration
610
+ */
611
+ shutdown?: {
612
+ enabled?: boolean;
613
+ timeout?: number;
614
+ signals?: string[];
615
+ };
616
+ }
617
+
618
+ declare function defineConfig(config: OqronConfig): OqronConfig;
619
+
620
+ type ChronoEventMap = {
621
+ "job:start": [jobId: string, module: string];
622
+ "job:progress": [jobId: string, value: number];
623
+ "job:success": [jobId: string];
624
+ "job:fail": [jobId: string, error: Error];
625
+ "system:ready": [];
626
+ "system:stop": [];
627
+ };
628
+ declare class OqronEventBusClass extends EventEmitter<ChronoEventMap> {
629
+ private static _instance;
630
+ static getInstance(): OqronEventBusClass;
631
+ }
632
+ declare const OqronEventBus: OqronEventBusClass;
633
+
634
+ declare class SqliteAdapter implements IOqronAdapter {
635
+ private readonly db;
636
+ /**
637
+ * @param dbOrPath - Either a `better-sqlite3` Database instance (for testing with `:memory:`)
638
+ * or a file path string. Defaults to `"oqron.sqlite"`.
639
+ */
640
+ constructor(dbOrPath?: Database.Database | string);
641
+ /** Create tables if they don't exist */
642
+ migrate(): void;
643
+ upsertSchedule(def: CronDefinition | ScheduleDefinition): Promise<void>;
644
+ getDueSchedules(now: Date, limit: number, prefix?: string): Promise<Pick<CronDefinition, "name">[]>;
645
+ getSchedules(prefix?: string): Promise<Array<{
646
+ name: string;
647
+ lastRunAt: Date | null;
648
+ nextRunAt: Date | null;
649
+ }>>;
650
+ updateNextRun(scheduleId: string, nextRunAt: Date | null): Promise<void>;
651
+ updateJobProgress(id: string, progressPercent: number, progressLabel?: string): Promise<void>;
652
+ recordExecution(job: JobRecord): Promise<void>;
653
+ getExecutions(scheduleId: string, opts: {
654
+ limit: number;
655
+ offset: number;
656
+ }): Promise<JobRecord[]>;
657
+ getActiveJobs(): Promise<JobRecord[]>;
658
+ cleanOldExecutions(before: Date): Promise<number>;
659
+ pruneHistoryForSchedule(scheduleId: string, keepJobHistory: number | boolean, keepFailedJobHistory: number | boolean): Promise<void>;
660
+ }
661
+
662
+ declare class DbLockAdapter implements ILockAdapter {
663
+ private readonly db;
664
+ private readonly defaultTtl;
665
+ /**
666
+ * @param dbOrPath - Either a `better-sqlite3` Database instance or a file path.
667
+ * When sharing the same SQLite file as SqliteAdapter, pass the same path.
668
+ * @param defaultTtlMs - Default TTL for locks if not provided in acquire (optional)
669
+ */
670
+ constructor(dbOrPath?: Database.Database | string, defaultTtlMs?: number);
671
+ acquire(key: string, ownerId: string, ttlMs?: number): Promise<boolean>;
672
+ renew(key: string, ownerId: string, ttlMs?: number): Promise<boolean>;
673
+ release(key: string, ownerId: string): Promise<void>;
674
+ isOwner(key: string, ownerId: string): Promise<boolean>;
675
+ }
676
+
677
+ /**
678
+ * In-memory lock adapter for single-node dev/testing.
679
+ * Uses a Map + setTimeout-based expiry — NOT suitable for production multi-node.
680
+ */
681
+ declare class MemoryLockAdapter implements ILockAdapter {
682
+ private readonly locks;
683
+ acquire(key: string, ownerId: string, ttlMs: number): Promise<boolean>;
684
+ renew(key: string, ownerId: string, ttlMs: number): Promise<boolean>;
685
+ release(key: string, ownerId: string): Promise<void>;
686
+ isOwner(key: string, ownerId: string): Promise<boolean>;
687
+ }
688
+
689
+ type CronScheduleConfig = {
690
+ expression: string;
691
+ every?: never;
692
+ } | {
693
+ every: EveryConfig;
694
+ expression?: never;
695
+ };
696
+ type DefineCronOptions = CronScheduleConfig & {
697
+ name: string;
698
+ timezone?: string;
699
+ missedFire?: MissedFirePolicy;
700
+ overlap?: OverlapPolicy;
701
+ guaranteedWorker?: boolean;
702
+ heartbeatMs?: number;
703
+ lockTtlMs?: number;
704
+ timeout?: number;
705
+ tags?: string[];
706
+ handler: (ctx: ICronContext) => Promise<unknown>;
707
+ hooks?: CronHooks;
708
+ retries?: RetryConfig;
709
+ };
710
+ /**
711
+ * Define a cron job. Automatically registers it with OqronKit
712
+ * so that `OqronKit.init()` discovers it without manual wiring.
713
+ *
714
+ * @example
715
+ * // Expression-based
716
+ * cron({ name: 'billing', expression: '0 0 1 * *', handler: ... })
717
+ *
718
+ * // Interval-based
719
+ * cron({ name: 'sync', every: { minutes: 15 }, handler: ... })
720
+ */
721
+ declare const cron: (options: DefineCronOptions) => CronDefinition;
722
+
723
+ type EnqueueOptions<TPayload> = {
724
+ runAt?: Date;
725
+ runAfter?: ScheduleRunAfter;
726
+ recurring?: ScheduleRecurring;
727
+ rrule?: string;
728
+ every?: {
729
+ minutes?: number;
730
+ hours?: number;
731
+ seconds?: number;
732
+ };
733
+ payload?: TPayload;
734
+ nameSuffix?: string;
735
+ };
736
+ type ScheduleInstance<TPayload> = ScheduleDefinition<TPayload> & {
737
+ trigger: (opts?: EnqueueOptions<TPayload>) => Promise<void>;
738
+ schedule: (opts?: EnqueueOptions<TPayload>) => Promise<void>;
739
+ cancel: () => Promise<void>;
740
+ };
741
+ type DefineScheduleOptions<TPayload> = {
742
+ name: string;
743
+ runAt?: Date;
744
+ runAfter?: ScheduleRunAfter;
745
+ recurring?: ScheduleRecurring;
746
+ rrule?: string;
747
+ every?: {
748
+ minutes?: number;
749
+ hours?: number;
750
+ seconds?: number;
751
+ };
752
+ timezone?: string;
753
+ missedFire?: MissedFirePolicy;
754
+ overlap?: OverlapPolicy;
755
+ guaranteedWorker?: boolean;
756
+ heartbeatMs?: number;
757
+ lockTtlMs?: number;
758
+ timeout?: number;
759
+ tags?: string[];
760
+ condition?: (ctx: IScheduleContext<TPayload>) => Promise<boolean> | boolean;
761
+ handler: (ctx: IScheduleContext<TPayload>) => Promise<unknown>;
762
+ hooks?: ScheduleHooks<TPayload>;
763
+ payload?: TPayload;
764
+ retries?: RetryConfig;
765
+ };
766
+ /**
767
+ * Define a schedule or a task.
768
+ * Automatically registers it with OqronKit for boot-time loading.
769
+ */
770
+ declare const schedule: <TPayload = unknown>(options: DefineScheduleOptions<TPayload>) => ScheduleInstance<TPayload>;
771
+
772
+ declare const OqronKit: {
773
+ /**
774
+ * Initialize OqronKit: loads config, auto-discovers jobs, and boots modules.
775
+ *
776
+ * @param opts.cwd - Working directory for config file lookup and jobsDir resolution
777
+ * @param opts.config - Explicit config object (skips loadConfig)
778
+ */
779
+ init(opts?: {
780
+ cwd?: string;
781
+ config?: OqronConfig;
782
+ }): Promise<void>;
783
+ /** Gracefully stop all modules */
784
+ stop(): Promise<void>;
785
+ /** Get the current validated config */
786
+ getConfig(): ValidatedConfig;
787
+ /** Get the database adapter (available after init()) */
788
+ getDb(): IOqronAdapter;
789
+ /** Get the lock adapter (available after init()) */
790
+ getLock(): ILockAdapter;
791
+ /** Get the Express router for monitoring */
792
+ expressRouter(): any;
793
+ /** Get the Fastify plugin for monitoring */
794
+ fastifyPlugin(fastify: any, opts: any, done: () => void): void;
795
+ };
796
+
797
+ export { type ChronoLoggerConfig, type CronDefinition, type CronHooks, DbLockAdapter, type DefineCronOptions, type DefineScheduleOptions, type EveryConfig, type ICronContext, type ILockAdapter, type IOqronAdapter, type IScheduleContext, type JobRecord, MemoryLockAdapter, type MissedFirePolicy, OqronEventBus, OqronKit, type OverlapPolicy, type RetryConfig, type ScheduleDefinition, type ScheduleHooks, type ScheduleInstance, type ScheduleRecurring, type ScheduleRunAfter, SqliteAdapter, createLogger, cron, OqronKit as default, defineConfig, schedule };