@stacksjs/queue 0.70.86 → 0.70.88
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/package.json +1 -1
- package/dist/action.d.ts +0 -46
- package/dist/batch.d.ts +0 -150
- package/dist/circuit-breaker.d.ts +0 -52
- package/dist/dead-letter.d.ts +0 -61
- package/dist/discovery.d.ts +0 -79
- package/dist/envelope.d.ts +0 -89
- package/dist/events.d.ts +0 -138
- package/dist/health.d.ts +0 -85
- package/dist/idempotency.d.ts +0 -39
- package/dist/index.d.ts +0 -184
- package/dist/index.js +0 -31
- package/dist/job-progress.d.ts +0 -53
- package/dist/job.d.ts +0 -150
- package/dist/notifications.d.ts +0 -70
- package/dist/poison.d.ts +0 -53
- package/dist/scheduler-persistence.d.ts +0 -15
- package/dist/scheduler.d.ts +0 -69
- package/dist/testing.d.ts +0 -74
- package/dist/utils.d.ts +0 -13
- package/dist/worker.d.ts +0 -40
package/package.json
CHANGED
package/dist/action.d.ts
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import type { JobOptions } from '@stacksjs/types';
|
|
2
|
-
/*.ts) and dispatch.
|
|
3
|
-
* Inspired by Laravel's dispatchable jobs.
|
|
4
|
-
*
|
|
5
|
-
* @example
|
|
6
|
-
* ```typescript
|
|
7
|
-
* // app/Jobs/SendWelcomeEmail.ts
|
|
8
|
-
* export default new Job({
|
|
9
|
-
* name: 'SendWelcomeEmail',
|
|
10
|
-
* queue: 'emails',
|
|
11
|
-
* tries: 3,
|
|
12
|
-
* backoff: [10, 30, 60],
|
|
13
|
-
*
|
|
14
|
-
* async handle(payload: { email: string }) {
|
|
15
|
-
* await sendEmail(payload.email)
|
|
16
|
-
* },
|
|
17
|
-
* })
|
|
18
|
-
*
|
|
19
|
-
* // Dispatching:
|
|
20
|
-
* import SendWelcomeEmail from '~/app/Jobs/SendWelcomeEmail'
|
|
21
|
-
*
|
|
22
|
-
* await SendWelcomeEmail.dispatch({ email: 'user@example.com' })
|
|
23
|
-
* await SendWelcomeEmail.dispatchIf(user.isNew, { email: user.email })
|
|
24
|
-
* await SendWelcomeEmail.dispatchAfter(60, { email: user.email })
|
|
25
|
-
* await SendWelcomeEmail.dispatchNow({ email: user.email })
|
|
26
|
-
* ```
|
|
27
|
-
*/
|
|
28
|
-
export declare class Job {
|
|
29
|
-
name: JobOptions['name'];
|
|
30
|
-
description: JobOptions['description'];
|
|
31
|
-
action?: JobOptions['action'];
|
|
32
|
-
handle?: JobOptions['handle'];
|
|
33
|
-
queue?: string;
|
|
34
|
-
rate: JobOptions['rate'];
|
|
35
|
-
tries: JobOptions['tries'];
|
|
36
|
-
timeout?: number;
|
|
37
|
-
backoff: JobOptions['backoff'];
|
|
38
|
-
backoffConfig: JobOptions['backoffConfig'];
|
|
39
|
-
enabled: JobOptions['enabled'];
|
|
40
|
-
constructor(options: JobOptions & { queue?: string; timeout?: number });
|
|
41
|
-
dispatch<T = unknown>(payload?: T): Promise<void>;
|
|
42
|
-
dispatchIf<T = unknown>(condition: boolean, payload?: T): Promise<void>;
|
|
43
|
-
dispatchUnless<T = unknown>(condition: boolean, payload?: T): Promise<void>;
|
|
44
|
-
dispatchAfter<T = unknown>(delaySeconds: number, payload?: T): Promise<void>;
|
|
45
|
-
dispatchNow<T = unknown>(payload?: T): Promise<void>;
|
|
46
|
-
}
|
package/dist/batch.d.ts
DELETED
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
import type { Job } from './action';
|
|
2
|
-
export declare function getBatchCallbacks(batchId: string): BatchOptions | undefined;
|
|
3
|
-
/**
|
|
4
|
-
* Record that a job in a batch completed successfully.
|
|
5
|
-
* Called by the worker after a batch job finishes.
|
|
6
|
-
*
|
|
7
|
-
* Uses an atomic decrement on the database so two concurrent workers
|
|
8
|
-
* finishing batch jobs at the same instant don't both read pending=N
|
|
9
|
-
* and both write pending=N-1 — that race used to leave the counter
|
|
10
|
-
* stuck above zero and the batch's `then`/`finally` callbacks never
|
|
11
|
-
* fired. Falls back to read-modify-write (with a debug log) when the
|
|
12
|
-
* driver doesn't expose atomic SQL.
|
|
13
|
-
*/
|
|
14
|
-
export declare function recordBatchJobCompletion(batchId: string): Promise<void>;
|
|
15
|
-
/**
|
|
16
|
-
* Record that a job in a batch failed.
|
|
17
|
-
* Called by the worker when a batch job fails its final attempt.
|
|
18
|
-
*/
|
|
19
|
-
export declare function recordBatchJobFailure(batchId: string, jobId: string, error: Error): Promise<void>;
|
|
20
|
-
/**
|
|
21
|
-
* Check if a batch has been cancelled (used by worker to skip jobs)
|
|
22
|
-
*/
|
|
23
|
-
export declare function isBatchCancelled(batchId: string): Promise<boolean>;
|
|
24
|
-
/**
|
|
25
|
-
* A pending job within a batch (job + optional payload)
|
|
26
|
-
*/
|
|
27
|
-
export declare interface BatchableJob {
|
|
28
|
-
job: Job
|
|
29
|
-
payload?: any
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* Batch record stored in the database
|
|
33
|
-
*/
|
|
34
|
-
export declare interface BatchRecord {
|
|
35
|
-
id: string
|
|
36
|
-
name: string
|
|
37
|
-
total_jobs: number
|
|
38
|
-
pending_jobs: number
|
|
39
|
-
failed_jobs: number
|
|
40
|
-
failed_job_ids: string
|
|
41
|
-
options: string
|
|
42
|
-
cancelled_at: string | null
|
|
43
|
-
created_at: string
|
|
44
|
-
finished_at: string | null
|
|
45
|
-
then_handler?: string | null
|
|
46
|
-
catch_handler?: string | null
|
|
47
|
-
finally_handler?: string | null
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* Batch options for callbacks and behavior
|
|
51
|
-
*/
|
|
52
|
-
export declare interface BatchOptions {
|
|
53
|
-
name?: string
|
|
54
|
-
queue?: string
|
|
55
|
-
allowFailures?: boolean
|
|
56
|
-
thenCallbacks: Array<(batch: PendingBatch | DispatchedBatch) => Promise<void> | void>
|
|
57
|
-
catchCallbacks: Array<(batch: PendingBatch | DispatchedBatch, error: Error) => Promise<void> | void>
|
|
58
|
-
finallyCallbacks: Array<(batch: PendingBatch | DispatchedBatch) => Promise<void> | void>
|
|
59
|
-
progressCallbacks: Array<(batch: PendingBatch | DispatchedBatch) => Promise<void> | void>
|
|
60
|
-
thenHandler?: PersistentBatchHandler
|
|
61
|
-
catchHandler?: PersistentBatchHandler
|
|
62
|
-
finallyHandler?: PersistentBatchHandler
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* Batch status
|
|
66
|
-
*/
|
|
67
|
-
export type BatchStatus = 'pending' | 'processing' | 'completed' | 'failed' | 'cancelled';
|
|
68
|
-
/**
|
|
69
|
-
* Persistent batch handler shape (stacksjs/stacks#1883).
|
|
70
|
-
*
|
|
71
|
-
* Survives worker restart by being JSON-serialized into the
|
|
72
|
-
* `job_batches.then_handler` / `catch_handler` / `finally_handler`
|
|
73
|
-
* columns. The winning worker (the one that flips
|
|
74
|
-
* `pending_jobs = 0 → finished_at`) reads + dispatches these on
|
|
75
|
-
* completion, so a batch that finishes after the dispatching
|
|
76
|
-
* process died still fires its terminal callbacks.
|
|
77
|
-
*
|
|
78
|
-
* Two shapes:
|
|
79
|
-
* - `job` — dispatch a queued job by name; the worker fires
|
|
80
|
-
* the job through `Jobs.dispatch(name, payload)`
|
|
81
|
-
* - `module` — load a module and invoke a named export; payload
|
|
82
|
-
* is passed through. Useful for in-process side-
|
|
83
|
-
* effects that don't warrant their own job (e.g.
|
|
84
|
-
* cleanup helpers, simple notifications).
|
|
85
|
-
*
|
|
86
|
-
* Inline function callbacks (the existing `.then(fn)` API) stay
|
|
87
|
-
* supported as a process-local convenience — they continue to live
|
|
88
|
-
* in the in-memory registry alongside any persistent handler. The
|
|
89
|
-
* winning worker fires both: any in-memory callbacks AND the
|
|
90
|
-
* persistent handler if one was registered.
|
|
91
|
-
*/
|
|
92
|
-
export type PersistentBatchHandler = | { kind: 'job', name: string, payload?: unknown }
|
|
93
|
-
| { kind: 'module', module: string, export: string, payload?: unknown }
|
|
94
|
-
/**
|
|
95
|
-
* PendingBatch - a batch that has been configured but not yet dispatched
|
|
96
|
-
*/
|
|
97
|
-
export declare class PendingBatch {
|
|
98
|
-
constructor(jobs: Array<Job | BatchableJob>);
|
|
99
|
-
name(name: string): this;
|
|
100
|
-
onQueue(queue: string): this;
|
|
101
|
-
allowFailures(): this;
|
|
102
|
-
then(callback: (batch: PendingBatch | DispatchedBatch) => Promise<void> | void): this;
|
|
103
|
-
catch(callback: (batch: PendingBatch | DispatchedBatch, error: Error) => Promise<void> | void): this;
|
|
104
|
-
finally(callback: (batch: PendingBatch | DispatchedBatch) => Promise<void> | void): this;
|
|
105
|
-
progress(callback: (batch: PendingBatch | DispatchedBatch) => Promise<void> | void): this;
|
|
106
|
-
thenHandler(handler: PersistentBatchHandler): this;
|
|
107
|
-
catchHandler(handler: PersistentBatchHandler): this;
|
|
108
|
-
finallyHandler(handler: PersistentBatchHandler): this;
|
|
109
|
-
dispatch(): Promise<DispatchedBatch>;
|
|
110
|
-
getJobs(): BatchableJob[];
|
|
111
|
-
getOptions(): BatchOptions;
|
|
112
|
-
}
|
|
113
|
-
/**
|
|
114
|
-
* DispatchedBatch - a batch that has been dispatched and can be inspected
|
|
115
|
-
*/
|
|
116
|
-
export declare class DispatchedBatch {
|
|
117
|
-
readonly id: string;
|
|
118
|
-
constructor(id: string);
|
|
119
|
-
fresh(): Promise<BatchRecord | null>;
|
|
120
|
-
getName(): Promise<string>;
|
|
121
|
-
totalJobs(): Promise<number>;
|
|
122
|
-
pendingJobs(): Promise<number>;
|
|
123
|
-
failedJobs(): Promise<number>;
|
|
124
|
-
completedJobs(): Promise<number>;
|
|
125
|
-
progress(): Promise<number>;
|
|
126
|
-
finished(): Promise<boolean>;
|
|
127
|
-
cancelled(): Promise<boolean>;
|
|
128
|
-
hasFailures(): Promise<boolean>;
|
|
129
|
-
failedJobIds(): Promise<string[]>;
|
|
130
|
-
cancel(): Promise<void>;
|
|
131
|
-
add(jobs: Array<Job | BatchableJob>): Promise<void>;
|
|
132
|
-
delete(): Promise<void>;
|
|
133
|
-
}
|
|
134
|
-
/**
|
|
135
|
-
* Create a new pending batch
|
|
136
|
-
*
|
|
137
|
-
* @example
|
|
138
|
-
* ```typescript
|
|
139
|
-
* const batch = Batch.create([job1, job2, job3])
|
|
140
|
-
* .name('My Batch')
|
|
141
|
-
* .then(async (_batch) => console.log('Done!'))
|
|
142
|
-
* .dispatch()
|
|
143
|
-
* ```
|
|
144
|
-
*/
|
|
145
|
-
export declare class Batch {
|
|
146
|
-
static create(jobs: Array<Job | BatchableJob>): PendingBatch;
|
|
147
|
-
static find(id: string): Promise<DispatchedBatch | null>;
|
|
148
|
-
static all(): Promise<DispatchedBatch[]>;
|
|
149
|
-
static prune(olderThanHours?: number): Promise<number>;
|
|
150
|
-
}
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Is the queue currently paused? Returns `true` when `paused_at`
|
|
3
|
-
* is set and `resume_at` hasn't passed yet. Also auto-clears the
|
|
4
|
-
* paused state when the cooldown elapses so the next call sees
|
|
5
|
-
* the queue as available again.
|
|
6
|
-
*/
|
|
7
|
-
export declare function isCircuitOpen(queue: string): Promise<boolean>;
|
|
8
|
-
/**
|
|
9
|
-
* Record a successful job. Maintained alongside failure_count so
|
|
10
|
-
* the failure-rate calculation is meaningful. Window resets after
|
|
11
|
-
* `windowSeconds` so an old failure burst doesn't permanently
|
|
12
|
-
* skew the rate.
|
|
13
|
-
*/
|
|
14
|
-
export declare function recordCircuitSuccess(queue: string, config?: CircuitBreakerConfig): Promise<void>;
|
|
15
|
-
/**
|
|
16
|
-
* Record a failed job. After incrementing, evaluates whether the
|
|
17
|
-
* failure rate has crossed the threshold and trips the breaker if
|
|
18
|
-
* so. Returns `true` when this call triggered the trip.
|
|
19
|
-
*/
|
|
20
|
-
export declare function recordCircuitFailure(queue: string, config?: CircuitBreakerConfig): Promise<boolean>;
|
|
21
|
-
/**
|
|
22
|
-
* Manually pause a queue for the given cooldown (default matches
|
|
23
|
-
* the configured `pauseSeconds`). Useful when an operator knows
|
|
24
|
-
* downstream is broken and wants to skip jobs immediately rather
|
|
25
|
-
* than wait for the auto-trip.
|
|
26
|
-
*/
|
|
27
|
-
export declare function pauseQueue(queue: string, pauseSeconds?: number): Promise<void>;
|
|
28
|
-
/**
|
|
29
|
-
* Lift the pause on a queue (manual resume). Workers resume
|
|
30
|
-
* processing on the next poll cycle.
|
|
31
|
-
*/
|
|
32
|
-
export declare function resumeQueue(queue: string): Promise<void>;
|
|
33
|
-
/**
|
|
34
|
-
* Snapshot the current circuit state for every tracked queue.
|
|
35
|
-
* Used by `queue:status` to show paused queues alongside
|
|
36
|
-
* pending/failed counts.
|
|
37
|
-
*/
|
|
38
|
-
export declare function listCircuitState(): Promise<CircuitRow[]>;
|
|
39
|
-
export declare interface CircuitBreakerConfig {
|
|
40
|
-
failureRateThreshold?: number
|
|
41
|
-
windowSeconds?: number
|
|
42
|
-
pauseSeconds?: number
|
|
43
|
-
minObservations?: number
|
|
44
|
-
}
|
|
45
|
-
declare interface CircuitRow {
|
|
46
|
-
queue_name: string
|
|
47
|
-
success_count: number
|
|
48
|
-
failure_count: number
|
|
49
|
-
window_start: string
|
|
50
|
-
paused_at: string | null
|
|
51
|
-
resume_at: string | null
|
|
52
|
-
}
|
package/dist/dead-letter.d.ts
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Move a job from `failed_jobs` into `dead_letter_jobs`. Called
|
|
3
|
-
* by the retry path when a job re-fails, and by the poison/
|
|
4
|
-
* circuit-breaker paths when they intercept a job pre-dispatch.
|
|
5
|
-
*
|
|
6
|
-
* Returns `true` on success, `false` when the DLQ table is missing
|
|
7
|
-
* (caller falls back to today's behavior — leave the row in
|
|
8
|
-
* `failed_jobs`).
|
|
9
|
-
*/
|
|
10
|
-
export declare function moveToDeadLetter(failedJob: {
|
|
11
|
-
uuid?: string
|
|
12
|
-
connection?: string
|
|
13
|
-
queue?: string
|
|
14
|
-
payload?: string
|
|
15
|
-
exception?: string
|
|
16
|
-
failed_at?: string | null
|
|
17
|
-
}, reason: DeadLetterReason, totalFailures?: number): Promise<boolean>;
|
|
18
|
-
export declare function listDeadLetterJobs(filter?: ListDeadLetterFilter): Promise<DeadLetterRecord[]>;
|
|
19
|
-
/**
|
|
20
|
-
* Pull a DLQ row back into the active `jobs` queue. Resets
|
|
21
|
-
* `attempts` to 0 and `reserved_at` to null so the worker picks
|
|
22
|
-
* it up on the next poll cycle. The original DLQ row is deleted
|
|
23
|
-
* after the re-enqueue.
|
|
24
|
-
*
|
|
25
|
-
* Returns `true` when the job was found + re-enqueued, `false`
|
|
26
|
-
* when the id didn't exist OR the DLQ table is missing.
|
|
27
|
-
*/
|
|
28
|
-
export declare function retryDeadLetterJob(id: number): Promise<boolean>;
|
|
29
|
-
/**
|
|
30
|
-
* Delete DLQ rows older than `olderThanDays`. Useful for retention
|
|
31
|
-
* cleanup — apps with high failure volume can prune rows after the
|
|
32
|
-
* configured window. Default 30 days.
|
|
33
|
-
*
|
|
34
|
-
* Returns the number of rows deleted; 0 when the table is missing.
|
|
35
|
-
*/
|
|
36
|
-
export declare function purgeDeadLetterJobs(olderThanDays?: number): Promise<number>;
|
|
37
|
-
export declare interface DeadLetterRecord {
|
|
38
|
-
id: number
|
|
39
|
-
uuid: string
|
|
40
|
-
connection: string
|
|
41
|
-
queue: string
|
|
42
|
-
payload: string
|
|
43
|
-
exception: string
|
|
44
|
-
reason: DeadLetterReason
|
|
45
|
-
total_failures: number
|
|
46
|
-
first_failed_at: string | null
|
|
47
|
-
last_failed_at: string | null
|
|
48
|
-
dead_lettered_at: string
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* List dead-letter rows. Filters compose: `queue` narrows by
|
|
52
|
-
* queue name, `since` filters by `dead_lettered_at` cutoff. Limit
|
|
53
|
-
* defaults to 100 to keep CLI output manageable.
|
|
54
|
-
*/
|
|
55
|
-
export declare interface ListDeadLetterFilter {
|
|
56
|
-
queue?: string
|
|
57
|
-
reason?: DeadLetterReason
|
|
58
|
-
sinceCutoffMs?: number
|
|
59
|
-
limit?: number
|
|
60
|
-
}
|
|
61
|
-
export type DeadLetterReason = 'repeat-failure' | 'poison-detected' | 'circuit-broken' | 'manual';
|
package/dist/discovery.d.ts
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import type { JobOptions } from '@stacksjs/types';
|
|
2
|
-
/**
|
|
3
|
-
* Discover jobs from the app/Jobs directory
|
|
4
|
-
*/
|
|
5
|
-
export declare function discoverJobs(jobsPath?: string): Promise<DiscoveredJob[]>;
|
|
6
|
-
/**
|
|
7
|
-
* Get a job by name from the registry
|
|
8
|
-
*/
|
|
9
|
-
export declare function getJob(name: string): DiscoveredJob | undefined;
|
|
10
|
-
/**
|
|
11
|
-
* Get all discovered jobs
|
|
12
|
-
*/
|
|
13
|
-
export declare function getAllJobs(): DiscoveredJob[];
|
|
14
|
-
/**
|
|
15
|
-
* Get scheduled jobs
|
|
16
|
-
*/
|
|
17
|
-
export declare function getScheduledJobs(): DiscoveredJob[];
|
|
18
|
-
/**
|
|
19
|
-
* Execute a job by name
|
|
20
|
-
*/
|
|
21
|
-
export declare function executeJob<T = any>(name: string, payload?: any): Promise<T>;
|
|
22
|
-
/**
|
|
23
|
-
* Convert discovered job config to bun-queue JobOptions
|
|
24
|
-
*/
|
|
25
|
-
export declare function toJobOptions(job: DiscoveredJob): JobOptions;
|
|
26
|
-
// Global job registry
|
|
27
|
-
export declare const jobRegistry: JobRegistry;
|
|
28
|
-
/**
|
|
29
|
-
* Discovered job metadata
|
|
30
|
-
*/
|
|
31
|
-
export declare interface DiscoveredJob {
|
|
32
|
-
name: string
|
|
33
|
-
path: string
|
|
34
|
-
config: JobConfig
|
|
35
|
-
type: 'class' | 'function'
|
|
36
|
-
module: any
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Job configuration from discovery
|
|
40
|
-
*/
|
|
41
|
-
export declare interface JobConfig {
|
|
42
|
-
name?: string
|
|
43
|
-
description?: string
|
|
44
|
-
queue?: string
|
|
45
|
-
tries?: number
|
|
46
|
-
backoff?: number | number[]
|
|
47
|
-
rate?: string
|
|
48
|
-
timeout?: number
|
|
49
|
-
withoutOverlapping?: boolean
|
|
50
|
-
retries?: number
|
|
51
|
-
retryAfter?: number[]
|
|
52
|
-
schedule?: string
|
|
53
|
-
backoffConfig?: {
|
|
54
|
-
strategy?: 'fixed' | 'exponential' | 'linear'
|
|
55
|
-
initialDelay?: number
|
|
56
|
-
factor?: number
|
|
57
|
-
maxDelay?: number
|
|
58
|
-
jitter?: {
|
|
59
|
-
enabled?: boolean
|
|
60
|
-
factor?: number
|
|
61
|
-
minDelay?: number
|
|
62
|
-
maxDelay?: number
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Job registry for managing discovered jobs
|
|
68
|
-
*/
|
|
69
|
-
declare class JobRegistry {
|
|
70
|
-
register(job: DiscoveredJob): void;
|
|
71
|
-
get(name: string): DiscoveredJob | undefined;
|
|
72
|
-
all(): DiscoveredJob[];
|
|
73
|
-
byQueue(queue: string): DiscoveredJob[];
|
|
74
|
-
scheduled(): DiscoveredJob[];
|
|
75
|
-
has(name: string): boolean;
|
|
76
|
-
clear(): void;
|
|
77
|
-
setInitialized(value: boolean): void;
|
|
78
|
-
isInitialized(): boolean;
|
|
79
|
-
}
|
package/dist/envelope.d.ts
DELETED
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Construct a fresh envelope for an outgoing dispatch. Both drivers
|
|
3
|
-
* call this — single source of truth for the on-the-wire shape.
|
|
4
|
-
*/
|
|
5
|
-
export declare function createEnvelope(jobName: string, payload: unknown, options?: JobEnvelopeOptions): JobEnvelope;
|
|
6
|
-
/**
|
|
7
|
-
* Test-only: clear the warn-once state. Production callers never
|
|
8
|
-
* need this.
|
|
9
|
-
*/
|
|
10
|
-
export declare function clearEnvelopeWarnings(): void;
|
|
11
|
-
/**
|
|
12
|
-
* Parse an opaque value into a `JobEnvelope`. Accepts strings (which
|
|
13
|
-
* are JSON-parsed) or objects (which are inspected directly) —
|
|
14
|
-
* the database driver passes a JSON string; the redis driver passes
|
|
15
|
-
* the already-deserialized object that bun-queue gave back.
|
|
16
|
-
*
|
|
17
|
-
* Returns a discriminated result so caller code doesn't have to
|
|
18
|
-
* pattern-match on the version field. Forward-compatible: an
|
|
19
|
-
* unknown-but-newer version returns `{ ok: false, reason:
|
|
20
|
-
* 'unknown-version' }` so the worker can leave the row for a
|
|
21
|
-
* newer-build worker.
|
|
22
|
-
*/
|
|
23
|
-
export declare function parseEnvelope(raw: unknown): ParsedEnvelope;
|
|
24
|
-
/**
|
|
25
|
-
* Unified job envelope (stacksjs/stacks#1884, Q-6 from #1872).
|
|
26
|
-
*
|
|
27
|
-
* Background: the database and redis queue drivers serialized jobs
|
|
28
|
-
* differently:
|
|
29
|
-
*
|
|
30
|
-
* - database: `{ jobName, payload, options }` JSON-stringified into
|
|
31
|
-
* the `jobs.payload` column
|
|
32
|
-
* - redis: `{ jobName, payload }` passed as bun-queue's `data` arg
|
|
33
|
-
* with options split into bun-queue's second arg
|
|
34
|
-
*
|
|
35
|
-
* Switching `QUEUE_DRIVER` mid-flight orphaned in-flight jobs because
|
|
36
|
-
* the new worker couldn't deserialize the other shape. Fix: one
|
|
37
|
-
* `JobEnvelope` shape, used by every driver's write AND read, with a
|
|
38
|
-
* `envelopeVersion` field so a future shape change can be rolled out
|
|
39
|
-
* without breaking in-flight jobs queued under the previous version.
|
|
40
|
-
*
|
|
41
|
-
* Backward-compat: `parseEnvelope` handles three shapes:
|
|
42
|
-
*
|
|
43
|
-
* 1. **v1 (this version)** — full envelope with `envelopeVersion: 1`
|
|
44
|
-
* 2. **v0 implicit** — pre-fix shape (`{ jobName, payload, options? }`
|
|
45
|
-
* with no `envelopeVersion`). One-shot warn-and-process so the
|
|
46
|
-
* operator knows the migration window is closing.
|
|
47
|
-
* 3. **Laravel legacy** — `{ job: 'App\\Jobs\\Foo', data }` carried
|
|
48
|
-
* over from the database-Laravel-port era. Same warn-and-process.
|
|
49
|
-
*
|
|
50
|
-
* Forward-compat: a `envelopeVersion` newer than `JOB_ENVELOPE_VERSION`
|
|
51
|
-
* is logged and skipped (so a rolling deploy with a newer-shape envelope
|
|
52
|
-
* doesn't crash old workers; they leave the row for the new workers to
|
|
53
|
-
* pick up).
|
|
54
|
-
*/
|
|
55
|
-
/**
|
|
56
|
-
* Current envelope version. Bump when you change the shape of
|
|
57
|
-
* `JobEnvelope` in a way that older workers couldn't deserialize.
|
|
58
|
-
*
|
|
59
|
-
* - v1: jobName + payload + optional options + envelopeVersion +
|
|
60
|
-
* dispatchedAt
|
|
61
|
-
*/
|
|
62
|
-
export declare const JOB_ENVELOPE_VERSION: 1;
|
|
63
|
-
/**
|
|
64
|
-
* Per-job runtime options that travel with the envelope so a worker
|
|
65
|
-
* processing the job knows how to apply them (timeout, retries,
|
|
66
|
-
* backoff). The database driver previously embedded these in the
|
|
67
|
-
* envelope; the redis driver lost them across the wire because they
|
|
68
|
-
* went to bun-queue's separate options arg only.
|
|
69
|
-
*/
|
|
70
|
-
export declare interface JobEnvelopeOptions {
|
|
71
|
-
queue?: string
|
|
72
|
-
timeout?: number
|
|
73
|
-
tries?: number
|
|
74
|
-
backoff?: number | number[]
|
|
75
|
-
}
|
|
76
|
-
export declare interface JobEnvelope {
|
|
77
|
-
jobName: string
|
|
78
|
-
payload: unknown
|
|
79
|
-
options?: JobEnvelopeOptions
|
|
80
|
-
envelopeVersion: number
|
|
81
|
-
dispatchedAt: string
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* Result of attempting to parse an arbitrary input into a
|
|
85
|
-
* `JobEnvelope`. Discriminated so callers don't have to inspect
|
|
86
|
-
* the version field directly.
|
|
87
|
-
*/
|
|
88
|
-
export type ParsedEnvelope = | { ok: true, envelope: JobEnvelope, source: 'v1' | 'v0-implicit' | 'laravel-legacy' }
|
|
89
|
-
| { ok: false, reason: 'malformed' | 'unknown-version' | 'missing-job-name', detail?: string }
|
package/dist/events.d.ts
DELETED
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Get the global queue events instance
|
|
3
|
-
*/
|
|
4
|
-
export declare function getQueueEvents(): QueueEvents;
|
|
5
|
-
/**
|
|
6
|
-
* Subscribe to a queue event
|
|
7
|
-
*
|
|
8
|
-
* @example
|
|
9
|
-
* ```typescript
|
|
10
|
-
* // Listen for job completions
|
|
11
|
-
* onQueueEvent('job:completed', (payload) => {
|
|
12
|
-
* console.log(`Job ${payload.jobId} completed!`)
|
|
13
|
-
* })
|
|
14
|
-
*
|
|
15
|
-
* // Listen for all events
|
|
16
|
-
* onQueueEvent('*', (event, payload) => {
|
|
17
|
-
* console.log(`Event: ${event}`, payload)
|
|
18
|
-
* })
|
|
19
|
-
* ```
|
|
20
|
-
*/
|
|
21
|
-
export declare function onQueueEvent(event: QueueEventType | '*', handler: QueueEventHandler | ((_event: QueueEventType, _payload: QueueEventPayload) => void | Promise<void>)): () => void;
|
|
22
|
-
/**
|
|
23
|
-
* Emit a queue event
|
|
24
|
-
*/
|
|
25
|
-
export declare function emitQueueEvent(event: QueueEventType, payload: Omit<QueueEventPayload, 'timestamp'>): Promise<void>;
|
|
26
|
-
/**
|
|
27
|
-
* Event-aware job wrapper
|
|
28
|
-
*
|
|
29
|
-
* Wraps a job handler to automatically emit events
|
|
30
|
-
*/
|
|
31
|
-
export declare function withEvents<T extends (...args: any[]) => Promise<any>>(queueName: string, handler: T): T;
|
|
32
|
-
/**
|
|
33
|
-
* Queue event listener decorator
|
|
34
|
-
*
|
|
35
|
-
* @example
|
|
36
|
-
* ```typescript
|
|
37
|
-
* class EmailNotifications {
|
|
38
|
-
* @OnQueueEvent('job:completed')
|
|
39
|
-
* async onJobCompleted(payload: QueueEventPayload) {
|
|
40
|
-
* console.log('Job completed:', payload)
|
|
41
|
-
* }
|
|
42
|
-
* }
|
|
43
|
-
* ```
|
|
44
|
-
*/
|
|
45
|
-
export declare function OnQueueEvent(event: QueueEventType): void;
|
|
46
|
-
/**
|
|
47
|
-
* Get or create the global QueueMetrics instance
|
|
48
|
-
*/
|
|
49
|
-
export declare function getGlobalMetrics(): QueueMetrics;
|
|
50
|
-
export declare function getWorkerTracker(): WorkerTracker;
|
|
51
|
-
/**
|
|
52
|
-
* Queue event payload interface
|
|
53
|
-
*/
|
|
54
|
-
export declare interface QueueEventPayload {
|
|
55
|
-
jobId?: string
|
|
56
|
-
queueName?: string
|
|
57
|
-
jobName?: string
|
|
58
|
-
data?: any
|
|
59
|
-
result?: any
|
|
60
|
-
error?: Error
|
|
61
|
-
progress?: number
|
|
62
|
-
timestamp: number
|
|
63
|
-
attemptsMade?: number
|
|
64
|
-
duration?: number
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Worker status tracker
|
|
68
|
-
*
|
|
69
|
-
* Tracks registered workers and their activity for health checks.
|
|
70
|
-
*/
|
|
71
|
-
export declare interface TrackedWorker {
|
|
72
|
-
id: string
|
|
73
|
-
status: 'active' | 'idle' | 'stopped'
|
|
74
|
-
queue: string
|
|
75
|
-
processedCount: number
|
|
76
|
-
failedCount: number
|
|
77
|
-
lastActivityAt: string
|
|
78
|
-
startedAt: string
|
|
79
|
-
}
|
|
80
|
-
/**
|
|
81
|
-
* Queue event types
|
|
82
|
-
*/
|
|
83
|
-
export type QueueEventType = | 'job:added'
|
|
84
|
-
| 'job:processing'
|
|
85
|
-
| 'job:completed'
|
|
86
|
-
| 'job:failed'
|
|
87
|
-
| 'job:retrying'
|
|
88
|
-
| 'job:stalled'
|
|
89
|
-
| 'job:progress'
|
|
90
|
-
| 'queue:paused'
|
|
91
|
-
| 'queue:resumed'
|
|
92
|
-
| 'queue:error'
|
|
93
|
-
| 'worker:started'
|
|
94
|
-
| 'worker:stopped'
|
|
95
|
-
| 'batch:added'
|
|
96
|
-
| 'batch:completed'
|
|
97
|
-
| 'batch:failed';
|
|
98
|
-
/**
|
|
99
|
-
* Queue event handler type
|
|
100
|
-
*/
|
|
101
|
-
export type QueueEventHandler = (_payload: QueueEventPayload) => void | Promise<void>;
|
|
102
|
-
/**
|
|
103
|
-
* Queue events emitter
|
|
104
|
-
*/
|
|
105
|
-
export declare class QueueEvents {
|
|
106
|
-
on(event: QueueEventType, handler: QueueEventHandler): () => void;
|
|
107
|
-
onAny(handler: (event: QueueEventType, payload: QueueEventPayload) => void | Promise<void>): () => void;
|
|
108
|
-
once(event: QueueEventType, handler: QueueEventHandler): () => void;
|
|
109
|
-
emit(event: QueueEventType, payload: Omit<QueueEventPayload, 'timestamp'>): Promise<void>;
|
|
110
|
-
off(event: QueueEventType): void;
|
|
111
|
-
removeAllListeners(): void;
|
|
112
|
-
}
|
|
113
|
-
/**
|
|
114
|
-
* Queue metrics based on events
|
|
115
|
-
*/
|
|
116
|
-
export declare class QueueMetrics {
|
|
117
|
-
constructor();
|
|
118
|
-
getThroughputPerMinute(): number;
|
|
119
|
-
getAverageProcessingTime(): number;
|
|
120
|
-
getMetrics(): {
|
|
121
|
-
counts: { added: number; completed: number; failed: number; processing: number }
|
|
122
|
-
averageDuration: number
|
|
123
|
-
recentErrors: Array<{ error: Error; timestamp: number }>
|
|
124
|
-
throughputPerMinute: number
|
|
125
|
-
};
|
|
126
|
-
reset(): void;
|
|
127
|
-
stop(): void;
|
|
128
|
-
}
|
|
129
|
-
declare class WorkerTracker {
|
|
130
|
-
register(id: string, queue: string): void;
|
|
131
|
-
markActive(id: string): void;
|
|
132
|
-
markIdle(id: string): void;
|
|
133
|
-
recordCompletion(id: string): void;
|
|
134
|
-
recordFailure(id: string): void;
|
|
135
|
-
unregister(id: string): void;
|
|
136
|
-
getAll(): TrackedWorker[];
|
|
137
|
-
clear(): void;
|
|
138
|
-
}
|