@objectstack/service-job 4.0.4 → 4.1.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/dist/index.cjs +381 -28
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +97 -34
- package/dist/index.d.ts +97 -34
- package/dist/index.js +380 -28
- package/dist/index.js.map +1 -1
- package/package.json +33 -6
- package/.turbo/turbo-build.log +0 -22
- package/CHANGELOG.md +0 -177
- package/src/cron-job-adapter.ts +0 -51
- package/src/index.ts +0 -8
- package/src/interval-job-adapter.test.ts +0 -120
- package/src/interval-job-adapter.ts +0 -130
- package/src/job-service-plugin.ts +0 -65
- package/tsconfig.json +0 -10
package/dist/index.d.cts
CHANGED
|
@@ -33,40 +33,101 @@ declare class IntervalJobAdapter implements IJobService {
|
|
|
33
33
|
private executeJob;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
interface JobEngineLike {
|
|
37
|
+
find(object: string, options?: any): Promise<any[]>;
|
|
38
|
+
insert(object: string, data: any, options?: any): Promise<any>;
|
|
39
|
+
update(object: string, idOrData: any, dataOrOptions?: any, options?: any): Promise<any>;
|
|
40
|
+
delete?(object: string, options?: any): Promise<any>;
|
|
41
|
+
}
|
|
42
|
+
interface JobLoggerLike {
|
|
43
|
+
info(msg: string, meta?: unknown): void;
|
|
44
|
+
warn(msg: string, meta?: unknown): void;
|
|
45
|
+
error?(msg: string, meta?: unknown): void;
|
|
46
|
+
}
|
|
47
|
+
interface DbJobAdapterOptions {
|
|
48
|
+
/** Maximum executions kept in memory per job (default 100) */
|
|
49
|
+
maxExecutions?: number;
|
|
50
|
+
/** Soft cap on sys_job_run rows recorded per job (defaults to none — handled by retention jobs) */
|
|
51
|
+
recordRuns?: boolean;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* DbJobAdapter — IJobService that persists job registry and execution
|
|
55
|
+
* history to ObjectQL while delegating timer mechanics to
|
|
56
|
+
* `IntervalJobAdapter`. Cron is delegated to `CronJobAdapter` callers
|
|
57
|
+
* supplied via {@link withCron}.
|
|
58
|
+
*
|
|
59
|
+
* Persisted side effects:
|
|
60
|
+
* - `schedule(name, …)` upserts a `sys_job` row (active=true)
|
|
61
|
+
* - `cancel(name)` marks the row inactive
|
|
62
|
+
* - every execution writes a `sys_job_run` row
|
|
63
|
+
* - every execution updates `sys_job.last_run_at / last_status / run_count / failure_count`
|
|
64
|
+
*
|
|
65
|
+
* The persistence is best-effort: a DB failure is logged but does not
|
|
66
|
+
* break job execution. This keeps a healthy job system resilient to
|
|
67
|
+
* transient storage hiccups.
|
|
68
|
+
*/
|
|
69
|
+
declare class DbJobAdapter implements IJobService {
|
|
70
|
+
private readonly inner;
|
|
71
|
+
private readonly cron?;
|
|
72
|
+
private readonly engine;
|
|
73
|
+
private readonly logger?;
|
|
74
|
+
private readonly recordRuns;
|
|
75
|
+
constructor(args: {
|
|
76
|
+
engine: JobEngineLike;
|
|
77
|
+
logger?: JobLoggerLike;
|
|
78
|
+
options?: DbJobAdapterOptions;
|
|
79
|
+
cron?: IJobService;
|
|
80
|
+
});
|
|
81
|
+
schedule(name: string, schedule: JobSchedule, handler: JobHandler): Promise<void>;
|
|
82
|
+
cancel(name: string): Promise<void>;
|
|
83
|
+
trigger(name: string, data?: unknown): Promise<void>;
|
|
84
|
+
getExecutions(name: string, limit?: number): Promise<JobExecution[]>;
|
|
85
|
+
listJobs(): Promise<string[]>;
|
|
86
|
+
replay(name: string, data?: unknown): Promise<void>;
|
|
87
|
+
listExecutionsByStatus(status: JobExecution['status'], limit?: number): Promise<JobExecution[]>;
|
|
88
|
+
destroy(): Promise<void>;
|
|
89
|
+
private wrap;
|
|
90
|
+
private startRun;
|
|
91
|
+
private finishRun;
|
|
92
|
+
private upsertJobRow;
|
|
93
|
+
private setActive;
|
|
94
|
+
private bumpJob;
|
|
95
|
+
}
|
|
96
|
+
|
|
36
97
|
/**
|
|
37
98
|
* Configuration options for the JobServicePlugin.
|
|
38
99
|
*/
|
|
39
100
|
interface JobServicePluginOptions {
|
|
40
|
-
/**
|
|
41
|
-
|
|
101
|
+
/**
|
|
102
|
+
* Job adapter type.
|
|
103
|
+
* - 'auto' (default): use DbJobAdapter when objectql engine available, else IntervalJobAdapter
|
|
104
|
+
* - 'db': require objectql; persists schedules and runs to sys_job/sys_job_run
|
|
105
|
+
* - 'interval': in-memory IntervalJobAdapter (legacy, non-durable)
|
|
106
|
+
* - 'cron': in-memory CronJobAdapter using `croner`
|
|
107
|
+
*/
|
|
108
|
+
adapter?: 'auto' | 'db' | 'interval' | 'cron';
|
|
42
109
|
/** Options for the interval job adapter */
|
|
43
110
|
interval?: IntervalJobAdapterOptions;
|
|
111
|
+
/** Options for the DB adapter */
|
|
112
|
+
db?: DbJobAdapterOptions;
|
|
113
|
+
/** Whether to also wire CronJobAdapter for cron schedules (default: true when available) */
|
|
114
|
+
enableCron?: boolean;
|
|
44
115
|
}
|
|
45
116
|
/**
|
|
46
117
|
* JobServicePlugin — Production IJobService implementation.
|
|
47
118
|
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
* ```ts
|
|
53
|
-
* import { ObjectKernel } from '@objectstack/core';
|
|
54
|
-
* import { JobServicePlugin } from '@objectstack/service-job';
|
|
55
|
-
*
|
|
56
|
-
* const kernel = new ObjectKernel();
|
|
57
|
-
* kernel.use(new JobServicePlugin({ adapter: 'interval' }));
|
|
58
|
-
* await kernel.bootstrap();
|
|
59
|
-
*
|
|
60
|
-
* const job = kernel.getService('job');
|
|
61
|
-
* await job.schedule('cleanup', { type: 'interval', intervalMs: 60000 }, handler);
|
|
62
|
-
* ```
|
|
119
|
+
* Default behaviour: registers a `DbJobAdapter` when the ObjectQL engine is
|
|
120
|
+
* available (persisting registry + execution history to `sys_job` and
|
|
121
|
+
* `sys_job_run`), falling back to in-memory `IntervalJobAdapter` otherwise.
|
|
122
|
+
* Cron schedules are routed to `CronJobAdapter` (croner-backed).
|
|
63
123
|
*/
|
|
64
124
|
declare class JobServicePlugin implements Plugin {
|
|
65
125
|
name: string;
|
|
66
126
|
version: string;
|
|
67
127
|
type: string;
|
|
68
128
|
private readonly options;
|
|
69
|
-
private
|
|
129
|
+
private dbAdapter?;
|
|
130
|
+
private intervalAdapter?;
|
|
70
131
|
constructor(options?: JobServicePluginOptions);
|
|
71
132
|
init(ctx: PluginContext): Promise<void>;
|
|
72
133
|
destroy(): Promise<void>;
|
|
@@ -78,27 +139,29 @@ declare class JobServicePlugin implements Plugin {
|
|
|
78
139
|
interface CronJobAdapterOptions {
|
|
79
140
|
/** Timezone for cron expressions (default: 'UTC') */
|
|
80
141
|
timezone?: string;
|
|
142
|
+
/** Maximum execution history per job (default: 100) */
|
|
143
|
+
maxExecutions?: number;
|
|
81
144
|
}
|
|
82
145
|
/**
|
|
83
|
-
* Cron-based job adapter
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
* @example
|
|
89
|
-
* ```ts
|
|
90
|
-
* const scheduler = new CronJobAdapter({ timezone: 'America/New_York' });
|
|
91
|
-
* await scheduler.schedule('nightly-cleanup', { type: 'cron', expression: '0 0 * * *' }, handler);
|
|
92
|
-
* ```
|
|
146
|
+
* Cron-based job adapter implementing IJobService using the `croner`
|
|
147
|
+
* library. Honours per-job timezones, supports the standard 5-field cron
|
|
148
|
+
* syntax, and falls back to setInterval / setTimeout for `interval` and
|
|
149
|
+
* `once` schedule types (so a single CronJobAdapter can serve as the
|
|
150
|
+
* "real" production job runner).
|
|
93
151
|
*/
|
|
94
152
|
declare class CronJobAdapter implements IJobService {
|
|
95
|
-
private readonly
|
|
153
|
+
private readonly defaultTimezone;
|
|
154
|
+
private readonly maxExecutions;
|
|
155
|
+
private readonly jobs;
|
|
96
156
|
constructor(options?: CronJobAdapterOptions);
|
|
97
|
-
schedule(
|
|
98
|
-
cancel(
|
|
99
|
-
trigger(
|
|
100
|
-
getExecutions(
|
|
157
|
+
schedule(name: string, schedule: JobSchedule, handler: JobHandler): Promise<void>;
|
|
158
|
+
cancel(name: string): Promise<void>;
|
|
159
|
+
trigger(name: string, data?: unknown): Promise<void>;
|
|
160
|
+
getExecutions(name: string, limit?: number): Promise<JobExecution[]>;
|
|
101
161
|
listJobs(): Promise<string[]>;
|
|
162
|
+
/** Stop all timers — call from plugin destroy. */
|
|
163
|
+
destroy(): Promise<void>;
|
|
164
|
+
private execute;
|
|
102
165
|
}
|
|
103
166
|
|
|
104
|
-
export { CronJobAdapter, type CronJobAdapterOptions, IntervalJobAdapter, type IntervalJobAdapterOptions, JobServicePlugin, type JobServicePluginOptions };
|
|
167
|
+
export { CronJobAdapter, type CronJobAdapterOptions, DbJobAdapter, type DbJobAdapterOptions, IntervalJobAdapter, type IntervalJobAdapterOptions, type JobEngineLike, type JobLoggerLike, JobServicePlugin, type JobServicePluginOptions };
|
package/dist/index.d.ts
CHANGED
|
@@ -33,40 +33,101 @@ declare class IntervalJobAdapter implements IJobService {
|
|
|
33
33
|
private executeJob;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
interface JobEngineLike {
|
|
37
|
+
find(object: string, options?: any): Promise<any[]>;
|
|
38
|
+
insert(object: string, data: any, options?: any): Promise<any>;
|
|
39
|
+
update(object: string, idOrData: any, dataOrOptions?: any, options?: any): Promise<any>;
|
|
40
|
+
delete?(object: string, options?: any): Promise<any>;
|
|
41
|
+
}
|
|
42
|
+
interface JobLoggerLike {
|
|
43
|
+
info(msg: string, meta?: unknown): void;
|
|
44
|
+
warn(msg: string, meta?: unknown): void;
|
|
45
|
+
error?(msg: string, meta?: unknown): void;
|
|
46
|
+
}
|
|
47
|
+
interface DbJobAdapterOptions {
|
|
48
|
+
/** Maximum executions kept in memory per job (default 100) */
|
|
49
|
+
maxExecutions?: number;
|
|
50
|
+
/** Soft cap on sys_job_run rows recorded per job (defaults to none — handled by retention jobs) */
|
|
51
|
+
recordRuns?: boolean;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* DbJobAdapter — IJobService that persists job registry and execution
|
|
55
|
+
* history to ObjectQL while delegating timer mechanics to
|
|
56
|
+
* `IntervalJobAdapter`. Cron is delegated to `CronJobAdapter` callers
|
|
57
|
+
* supplied via {@link withCron}.
|
|
58
|
+
*
|
|
59
|
+
* Persisted side effects:
|
|
60
|
+
* - `schedule(name, …)` upserts a `sys_job` row (active=true)
|
|
61
|
+
* - `cancel(name)` marks the row inactive
|
|
62
|
+
* - every execution writes a `sys_job_run` row
|
|
63
|
+
* - every execution updates `sys_job.last_run_at / last_status / run_count / failure_count`
|
|
64
|
+
*
|
|
65
|
+
* The persistence is best-effort: a DB failure is logged but does not
|
|
66
|
+
* break job execution. This keeps a healthy job system resilient to
|
|
67
|
+
* transient storage hiccups.
|
|
68
|
+
*/
|
|
69
|
+
declare class DbJobAdapter implements IJobService {
|
|
70
|
+
private readonly inner;
|
|
71
|
+
private readonly cron?;
|
|
72
|
+
private readonly engine;
|
|
73
|
+
private readonly logger?;
|
|
74
|
+
private readonly recordRuns;
|
|
75
|
+
constructor(args: {
|
|
76
|
+
engine: JobEngineLike;
|
|
77
|
+
logger?: JobLoggerLike;
|
|
78
|
+
options?: DbJobAdapterOptions;
|
|
79
|
+
cron?: IJobService;
|
|
80
|
+
});
|
|
81
|
+
schedule(name: string, schedule: JobSchedule, handler: JobHandler): Promise<void>;
|
|
82
|
+
cancel(name: string): Promise<void>;
|
|
83
|
+
trigger(name: string, data?: unknown): Promise<void>;
|
|
84
|
+
getExecutions(name: string, limit?: number): Promise<JobExecution[]>;
|
|
85
|
+
listJobs(): Promise<string[]>;
|
|
86
|
+
replay(name: string, data?: unknown): Promise<void>;
|
|
87
|
+
listExecutionsByStatus(status: JobExecution['status'], limit?: number): Promise<JobExecution[]>;
|
|
88
|
+
destroy(): Promise<void>;
|
|
89
|
+
private wrap;
|
|
90
|
+
private startRun;
|
|
91
|
+
private finishRun;
|
|
92
|
+
private upsertJobRow;
|
|
93
|
+
private setActive;
|
|
94
|
+
private bumpJob;
|
|
95
|
+
}
|
|
96
|
+
|
|
36
97
|
/**
|
|
37
98
|
* Configuration options for the JobServicePlugin.
|
|
38
99
|
*/
|
|
39
100
|
interface JobServicePluginOptions {
|
|
40
|
-
/**
|
|
41
|
-
|
|
101
|
+
/**
|
|
102
|
+
* Job adapter type.
|
|
103
|
+
* - 'auto' (default): use DbJobAdapter when objectql engine available, else IntervalJobAdapter
|
|
104
|
+
* - 'db': require objectql; persists schedules and runs to sys_job/sys_job_run
|
|
105
|
+
* - 'interval': in-memory IntervalJobAdapter (legacy, non-durable)
|
|
106
|
+
* - 'cron': in-memory CronJobAdapter using `croner`
|
|
107
|
+
*/
|
|
108
|
+
adapter?: 'auto' | 'db' | 'interval' | 'cron';
|
|
42
109
|
/** Options for the interval job adapter */
|
|
43
110
|
interval?: IntervalJobAdapterOptions;
|
|
111
|
+
/** Options for the DB adapter */
|
|
112
|
+
db?: DbJobAdapterOptions;
|
|
113
|
+
/** Whether to also wire CronJobAdapter for cron schedules (default: true when available) */
|
|
114
|
+
enableCron?: boolean;
|
|
44
115
|
}
|
|
45
116
|
/**
|
|
46
117
|
* JobServicePlugin — Production IJobService implementation.
|
|
47
118
|
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
* ```ts
|
|
53
|
-
* import { ObjectKernel } from '@objectstack/core';
|
|
54
|
-
* import { JobServicePlugin } from '@objectstack/service-job';
|
|
55
|
-
*
|
|
56
|
-
* const kernel = new ObjectKernel();
|
|
57
|
-
* kernel.use(new JobServicePlugin({ adapter: 'interval' }));
|
|
58
|
-
* await kernel.bootstrap();
|
|
59
|
-
*
|
|
60
|
-
* const job = kernel.getService('job');
|
|
61
|
-
* await job.schedule('cleanup', { type: 'interval', intervalMs: 60000 }, handler);
|
|
62
|
-
* ```
|
|
119
|
+
* Default behaviour: registers a `DbJobAdapter` when the ObjectQL engine is
|
|
120
|
+
* available (persisting registry + execution history to `sys_job` and
|
|
121
|
+
* `sys_job_run`), falling back to in-memory `IntervalJobAdapter` otherwise.
|
|
122
|
+
* Cron schedules are routed to `CronJobAdapter` (croner-backed).
|
|
63
123
|
*/
|
|
64
124
|
declare class JobServicePlugin implements Plugin {
|
|
65
125
|
name: string;
|
|
66
126
|
version: string;
|
|
67
127
|
type: string;
|
|
68
128
|
private readonly options;
|
|
69
|
-
private
|
|
129
|
+
private dbAdapter?;
|
|
130
|
+
private intervalAdapter?;
|
|
70
131
|
constructor(options?: JobServicePluginOptions);
|
|
71
132
|
init(ctx: PluginContext): Promise<void>;
|
|
72
133
|
destroy(): Promise<void>;
|
|
@@ -78,27 +139,29 @@ declare class JobServicePlugin implements Plugin {
|
|
|
78
139
|
interface CronJobAdapterOptions {
|
|
79
140
|
/** Timezone for cron expressions (default: 'UTC') */
|
|
80
141
|
timezone?: string;
|
|
142
|
+
/** Maximum execution history per job (default: 100) */
|
|
143
|
+
maxExecutions?: number;
|
|
81
144
|
}
|
|
82
145
|
/**
|
|
83
|
-
* Cron-based job adapter
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
* @example
|
|
89
|
-
* ```ts
|
|
90
|
-
* const scheduler = new CronJobAdapter({ timezone: 'America/New_York' });
|
|
91
|
-
* await scheduler.schedule('nightly-cleanup', { type: 'cron', expression: '0 0 * * *' }, handler);
|
|
92
|
-
* ```
|
|
146
|
+
* Cron-based job adapter implementing IJobService using the `croner`
|
|
147
|
+
* library. Honours per-job timezones, supports the standard 5-field cron
|
|
148
|
+
* syntax, and falls back to setInterval / setTimeout for `interval` and
|
|
149
|
+
* `once` schedule types (so a single CronJobAdapter can serve as the
|
|
150
|
+
* "real" production job runner).
|
|
93
151
|
*/
|
|
94
152
|
declare class CronJobAdapter implements IJobService {
|
|
95
|
-
private readonly
|
|
153
|
+
private readonly defaultTimezone;
|
|
154
|
+
private readonly maxExecutions;
|
|
155
|
+
private readonly jobs;
|
|
96
156
|
constructor(options?: CronJobAdapterOptions);
|
|
97
|
-
schedule(
|
|
98
|
-
cancel(
|
|
99
|
-
trigger(
|
|
100
|
-
getExecutions(
|
|
157
|
+
schedule(name: string, schedule: JobSchedule, handler: JobHandler): Promise<void>;
|
|
158
|
+
cancel(name: string): Promise<void>;
|
|
159
|
+
trigger(name: string, data?: unknown): Promise<void>;
|
|
160
|
+
getExecutions(name: string, limit?: number): Promise<JobExecution[]>;
|
|
101
161
|
listJobs(): Promise<string[]>;
|
|
162
|
+
/** Stop all timers — call from plugin destroy. */
|
|
163
|
+
destroy(): Promise<void>;
|
|
164
|
+
private execute;
|
|
102
165
|
}
|
|
103
166
|
|
|
104
|
-
export { CronJobAdapter, type CronJobAdapterOptions, IntervalJobAdapter, type IntervalJobAdapterOptions, JobServicePlugin, type JobServicePluginOptions };
|
|
167
|
+
export { CronJobAdapter, type CronJobAdapterOptions, DbJobAdapter, type DbJobAdapterOptions, IntervalJobAdapter, type IntervalJobAdapterOptions, type JobEngineLike, type JobLoggerLike, JobServicePlugin, type JobServicePluginOptions };
|