@monque/core 0.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/README.md ADDED
@@ -0,0 +1,124 @@
1
+ <p align="center">
2
+ <img src="../../assets/logo.svg" width="180" alt="Monque logo" />
3
+ </p>
4
+
5
+ <h1 align="center">@monque/core</h1>
6
+
7
+ <p align="center">MongoDB-backed job scheduler with atomic locking, exponential backoff, and cron scheduling.</p>
8
+
9
+ > [!WARNING]
10
+ > This package is currently in **pre-release**. The public API may change between releases. Expect breaking changes until `1.0.0`.
11
+
12
+ ## Installation
13
+
14
+ Using Bun:
15
+ ```bash
16
+ bun add @monque/core mongodb
17
+ ```
18
+
19
+ Or using npm/yarn/pnpm:
20
+ ```bash
21
+ npm install @monque/core mongodb
22
+ yarn add @monque/core mongodb
23
+ pnpm add @monque/core mongodb
24
+ ```
25
+
26
+ ## Usage
27
+
28
+ ```typescript
29
+ import { Monque } from '@monque/core';
30
+ import { MongoClient } from 'mongodb';
31
+
32
+ const client = new MongoClient('mongodb://localhost:27017');
33
+ await client.connect();
34
+
35
+ const monque = new Monque(client.db('myapp'), {
36
+ collectionName: 'jobs',
37
+ pollInterval: 1000,
38
+ maxRetries: 10,
39
+ defaultConcurrency: 5,
40
+ });
41
+
42
+ await monque.initialize();
43
+
44
+ // Register workers
45
+ monque.worker('send-email', async (job) => {
46
+ await sendEmail(job.data.to, job.data.subject);
47
+ });
48
+
49
+ // Start processing
50
+ monque.start();
51
+
52
+ // Enqueue jobs
53
+ await monque.enqueue('send-email', { to: 'user@example.com', subject: 'Hello' });
54
+
55
+ // Schedule recurring jobs
56
+ await monque.schedule('0 9 * * *', 'daily-report', { type: 'summary' });
57
+
58
+ // Graceful shutdown
59
+ await monque.stop();
60
+ ```
61
+
62
+ ## API
63
+
64
+ ### `new Monque(db, options?)`
65
+
66
+ Creates a new Monque instance.
67
+
68
+ **Options:**
69
+ - `collectionName` - MongoDB collection name (default: `'monque_jobs'`)
70
+ - `pollInterval` - Polling interval in ms (default: `1000`)
71
+ - `maxRetries` - Max retry attempts (default: `10`)
72
+ - `baseRetryInterval` - Base backoff interval in ms (default: `1000`)
73
+ - `shutdownTimeout` - Graceful shutdown timeout in ms (default: `30000`)
74
+ - `defaultConcurrency` - Jobs per worker (default: `5`)
75
+ - `lockTimeout` - Stale job threshold in ms (default: `1800000`)
76
+ - `recoverStaleJobs` - Recover stale jobs on startup (default: `true`)
77
+
78
+ ### Methods
79
+
80
+ - `initialize()` - Set up collection and indexes
81
+ - `enqueue(name, data, options?)` - Enqueue a job
82
+ - `now(name, data)` - Enqueue for immediate processing
83
+ - `schedule(cron, name, data)` - Schedule recurring job
84
+ - `worker(name, handler, options?)` - Register a worker
85
+ - `start()` - Start processing jobs
86
+ - `stop()` - Graceful shutdown
87
+ - `isHealthy()` - Check scheduler health
88
+
89
+ ### Events
90
+
91
+ ```typescript
92
+ monque.on('job:start', (job) => { /* job started */ });
93
+ monque.on('job:complete', ({ job, duration }) => { /* job completed */ });
94
+ monque.on('job:fail', ({ job, error, willRetry }) => { /* job failed */ });
95
+ monque.on('job:error', ({ error, job? }) => { /* unexpected error */ });
96
+ monque.on('stale:recovered', ({ count }) => { /* stale jobs recovered */ });
97
+ ```
98
+
99
+ ## Development
100
+
101
+ ### Running Tests
102
+
103
+ ```bash
104
+ # Run tests once (fresh container each time)
105
+ bun run test
106
+
107
+ # Run tests in watch mode with container reuse (faster iteration)
108
+ bun run test:dev
109
+
110
+ # Or enable reuse globally in your shell profile
111
+ export TESTCONTAINERS_REUSE_ENABLE=true
112
+ bun run test:watch
113
+ ```
114
+
115
+ When `TESTCONTAINERS_REUSE_ENABLE=true`, the MongoDB testcontainer persists between test runs, significantly speeding up local development. Ryuk (the testcontainers cleanup daemon) remains enabled as a safety net for orphaned containers.
116
+
117
+ To manually clean up reusable containers:
118
+ ```bash
119
+ docker ps -q --filter label=org.testcontainers=true | while read -r id; do docker stop "$id"; done
120
+ ```
121
+
122
+ ## License
123
+
124
+ ISC
@@ -0,0 +1,155 @@
1
+
2
+ //#region src/shared/errors.ts
3
+ /**
4
+ * Base error class for all Monque-related errors.
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * try {
9
+ * await monque.enqueue('job', data);
10
+ * } catch (error) {
11
+ * if (error instanceof MonqueError) {
12
+ * console.error('Monque error:', error.message);
13
+ * }
14
+ * }
15
+ * ```
16
+ */
17
+ var MonqueError = class MonqueError extends Error {
18
+ constructor(message) {
19
+ super(message);
20
+ this.name = "MonqueError";
21
+ /* istanbul ignore next -- @preserve captureStackTrace is always available in Node.js */
22
+ if (Error.captureStackTrace) Error.captureStackTrace(this, MonqueError);
23
+ }
24
+ };
25
+ /**
26
+ * Error thrown when an invalid cron expression is provided.
27
+ *
28
+ * @example
29
+ * ```typescript
30
+ * try {
31
+ * await monque.schedule('invalid cron', 'job', data);
32
+ * } catch (error) {
33
+ * if (error instanceof InvalidCronError) {
34
+ * console.error('Invalid expression:', error.expression);
35
+ * }
36
+ * }
37
+ * ```
38
+ */
39
+ var InvalidCronError = class InvalidCronError extends MonqueError {
40
+ constructor(expression, message) {
41
+ super(message);
42
+ this.expression = expression;
43
+ this.name = "InvalidCronError";
44
+ /* istanbul ignore next -- @preserve captureStackTrace is always available in Node.js */
45
+ if (Error.captureStackTrace) Error.captureStackTrace(this, InvalidCronError);
46
+ }
47
+ };
48
+ /**
49
+ * Error thrown when there's a database connection issue.
50
+ *
51
+ * @example
52
+ * ```typescript
53
+ * try {
54
+ * await monque.enqueue('job', data);
55
+ * } catch (error) {
56
+ * if (error instanceof ConnectionError) {
57
+ * console.error('Database connection lost');
58
+ * }
59
+ * }
60
+ * ```
61
+ */
62
+ var ConnectionError = class ConnectionError extends MonqueError {
63
+ constructor(message, options) {
64
+ super(message);
65
+ this.name = "ConnectionError";
66
+ if (options?.cause) this.cause = options.cause;
67
+ /* istanbul ignore next -- @preserve captureStackTrace is always available in Node.js */
68
+ if (Error.captureStackTrace) Error.captureStackTrace(this, ConnectionError);
69
+ }
70
+ };
71
+ /**
72
+ * Error thrown when graceful shutdown times out.
73
+ * Includes information about jobs that were still in progress.
74
+ *
75
+ * @example
76
+ * ```typescript
77
+ * try {
78
+ * await monque.stop();
79
+ * } catch (error) {
80
+ * if (error instanceof ShutdownTimeoutError) {
81
+ * console.error('Incomplete jobs:', error.incompleteJobs.length);
82
+ * }
83
+ * }
84
+ * ```
85
+ */
86
+ var ShutdownTimeoutError = class ShutdownTimeoutError extends MonqueError {
87
+ constructor(message, incompleteJobs) {
88
+ super(message);
89
+ this.incompleteJobs = incompleteJobs;
90
+ this.name = "ShutdownTimeoutError";
91
+ /* istanbul ignore next -- @preserve captureStackTrace is always available in Node.js */
92
+ if (Error.captureStackTrace) Error.captureStackTrace(this, ShutdownTimeoutError);
93
+ }
94
+ };
95
+ /**
96
+ * Error thrown when attempting to register a worker for a job name
97
+ * that already has a registered worker, without explicitly allowing replacement.
98
+ *
99
+ * @example
100
+ * ```typescript
101
+ * try {
102
+ * monque.worker('send-email', handler1);
103
+ * monque.worker('send-email', handler2); // throws
104
+ * } catch (error) {
105
+ * if (error instanceof WorkerRegistrationError) {
106
+ * console.error('Worker already registered for:', error.jobName);
107
+ * }
108
+ * }
109
+ *
110
+ * // To intentionally replace a worker:
111
+ * monque.worker('send-email', handler2, { replace: true });
112
+ * ```
113
+ */
114
+ var WorkerRegistrationError = class WorkerRegistrationError extends MonqueError {
115
+ constructor(message, jobName) {
116
+ super(message);
117
+ this.jobName = jobName;
118
+ this.name = "WorkerRegistrationError";
119
+ /* istanbul ignore next -- @preserve captureStackTrace is always available in Node.js */
120
+ if (Error.captureStackTrace) Error.captureStackTrace(this, WorkerRegistrationError);
121
+ }
122
+ };
123
+
124
+ //#endregion
125
+ Object.defineProperty(exports, 'ConnectionError', {
126
+ enumerable: true,
127
+ get: function () {
128
+ return ConnectionError;
129
+ }
130
+ });
131
+ Object.defineProperty(exports, 'InvalidCronError', {
132
+ enumerable: true,
133
+ get: function () {
134
+ return InvalidCronError;
135
+ }
136
+ });
137
+ Object.defineProperty(exports, 'MonqueError', {
138
+ enumerable: true,
139
+ get: function () {
140
+ return MonqueError;
141
+ }
142
+ });
143
+ Object.defineProperty(exports, 'ShutdownTimeoutError', {
144
+ enumerable: true,
145
+ get: function () {
146
+ return ShutdownTimeoutError;
147
+ }
148
+ });
149
+ Object.defineProperty(exports, 'WorkerRegistrationError', {
150
+ enumerable: true,
151
+ get: function () {
152
+ return WorkerRegistrationError;
153
+ }
154
+ });
155
+ //# sourceMappingURL=errors-BX3oWYfZ.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors-BX3oWYfZ.cjs","names":["expression: string","incompleteJobs: Job[]","jobName: string"],"sources":["../src/shared/errors.ts"],"sourcesContent":["import type { Job } from '@/jobs';\n\n/**\n * Base error class for all Monque-related errors.\n *\n * @example\n * ```typescript\n * try {\n * await monque.enqueue('job', data);\n * } catch (error) {\n * if (error instanceof MonqueError) {\n * console.error('Monque error:', error.message);\n * }\n * }\n * ```\n */\nexport class MonqueError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = 'MonqueError';\n\t\t// Maintains proper stack trace for where our error was thrown (only available on V8)\n\t\t/* istanbul ignore next -- @preserve captureStackTrace is always available in Node.js */\n\t\tif (Error.captureStackTrace) {\n\t\t\tError.captureStackTrace(this, MonqueError);\n\t\t}\n\t}\n}\n\n/**\n * Error thrown when an invalid cron expression is provided.\n *\n * @example\n * ```typescript\n * try {\n * await monque.schedule('invalid cron', 'job', data);\n * } catch (error) {\n * if (error instanceof InvalidCronError) {\n * console.error('Invalid expression:', error.expression);\n * }\n * }\n * ```\n */\nexport class InvalidCronError extends MonqueError {\n\tconstructor(\n\t\tpublic readonly expression: string,\n\t\tmessage: string,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = 'InvalidCronError';\n\t\t/* istanbul ignore next -- @preserve captureStackTrace is always available in Node.js */\n\t\tif (Error.captureStackTrace) {\n\t\t\tError.captureStackTrace(this, InvalidCronError);\n\t\t}\n\t}\n}\n\n/**\n * Error thrown when there's a database connection issue.\n *\n * @example\n * ```typescript\n * try {\n * await monque.enqueue('job', data);\n * } catch (error) {\n * if (error instanceof ConnectionError) {\n * console.error('Database connection lost');\n * }\n * }\n * ```\n */\nexport class ConnectionError extends MonqueError {\n\tconstructor(message: string, options?: { cause?: Error }) {\n\t\tsuper(message);\n\t\tthis.name = 'ConnectionError';\n\t\tif (options?.cause) {\n\t\t\tthis.cause = options.cause;\n\t\t}\n\t\t/* istanbul ignore next -- @preserve captureStackTrace is always available in Node.js */\n\t\tif (Error.captureStackTrace) {\n\t\t\tError.captureStackTrace(this, ConnectionError);\n\t\t}\n\t}\n}\n\n/**\n * Error thrown when graceful shutdown times out.\n * Includes information about jobs that were still in progress.\n *\n * @example\n * ```typescript\n * try {\n * await monque.stop();\n * } catch (error) {\n * if (error instanceof ShutdownTimeoutError) {\n * console.error('Incomplete jobs:', error.incompleteJobs.length);\n * }\n * }\n * ```\n */\nexport class ShutdownTimeoutError extends MonqueError {\n\tconstructor(\n\t\tmessage: string,\n\t\tpublic readonly incompleteJobs: Job[],\n\t) {\n\t\tsuper(message);\n\t\tthis.name = 'ShutdownTimeoutError';\n\t\t/* istanbul ignore next -- @preserve captureStackTrace is always available in Node.js */\n\t\tif (Error.captureStackTrace) {\n\t\t\tError.captureStackTrace(this, ShutdownTimeoutError);\n\t\t}\n\t}\n}\n\n/**\n * Error thrown when attempting to register a worker for a job name\n * that already has a registered worker, without explicitly allowing replacement.\n *\n * @example\n * ```typescript\n * try {\n * monque.worker('send-email', handler1);\n * monque.worker('send-email', handler2); // throws\n * } catch (error) {\n * if (error instanceof WorkerRegistrationError) {\n * console.error('Worker already registered for:', error.jobName);\n * }\n * }\n *\n * // To intentionally replace a worker:\n * monque.worker('send-email', handler2, { replace: true });\n * ```\n */\nexport class WorkerRegistrationError extends MonqueError {\n\tconstructor(\n\t\tmessage: string,\n\t\tpublic readonly jobName: string,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = 'WorkerRegistrationError';\n\t\t/* istanbul ignore next -- @preserve captureStackTrace is always available in Node.js */\n\t\tif (Error.captureStackTrace) {\n\t\t\tError.captureStackTrace(this, WorkerRegistrationError);\n\t\t}\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAgBA,IAAa,cAAb,MAAa,oBAAoB,MAAM;CACtC,YAAY,SAAiB;AAC5B,QAAM,QAAQ;AACd,OAAK,OAAO;;AAGZ,MAAI,MAAM,kBACT,OAAM,kBAAkB,MAAM,YAAY;;;;;;;;;;;;;;;;;AAmB7C,IAAa,mBAAb,MAAa,yBAAyB,YAAY;CACjD,YACC,AAAgBA,YAChB,SACC;AACD,QAAM,QAAQ;EAHE;AAIhB,OAAK,OAAO;;AAEZ,MAAI,MAAM,kBACT,OAAM,kBAAkB,MAAM,iBAAiB;;;;;;;;;;;;;;;;;AAmBlD,IAAa,kBAAb,MAAa,wBAAwB,YAAY;CAChD,YAAY,SAAiB,SAA6B;AACzD,QAAM,QAAQ;AACd,OAAK,OAAO;AACZ,MAAI,SAAS,MACZ,MAAK,QAAQ,QAAQ;;AAGtB,MAAI,MAAM,kBACT,OAAM,kBAAkB,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;AAoBjD,IAAa,uBAAb,MAAa,6BAA6B,YAAY;CACrD,YACC,SACA,AAAgBC,gBACf;AACD,QAAM,QAAQ;EAFE;AAGhB,OAAK,OAAO;;AAEZ,MAAI,MAAM,kBACT,OAAM,kBAAkB,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;AAwBtD,IAAa,0BAAb,MAAa,gCAAgC,YAAY;CACxD,YACC,SACA,AAAgBC,SACf;AACD,QAAM,QAAQ;EAFE;AAGhB,OAAK,OAAO;;AAEZ,MAAI,MAAM,kBACT,OAAM,kBAAkB,MAAM,wBAAwB"}
@@ -0,0 +1,3 @@
1
+ const require_errors = require('./errors-BX3oWYfZ.cjs');
2
+
3
+ exports.ShutdownTimeoutError = require_errors.ShutdownTimeoutError;
@@ -0,0 +1,125 @@
1
+ //#region src/shared/errors.ts
2
+ /**
3
+ * Base error class for all Monque-related errors.
4
+ *
5
+ * @example
6
+ * ```typescript
7
+ * try {
8
+ * await monque.enqueue('job', data);
9
+ * } catch (error) {
10
+ * if (error instanceof MonqueError) {
11
+ * console.error('Monque error:', error.message);
12
+ * }
13
+ * }
14
+ * ```
15
+ */
16
+ var MonqueError = class MonqueError extends Error {
17
+ constructor(message) {
18
+ super(message);
19
+ this.name = "MonqueError";
20
+ /* istanbul ignore next -- @preserve captureStackTrace is always available in Node.js */
21
+ if (Error.captureStackTrace) Error.captureStackTrace(this, MonqueError);
22
+ }
23
+ };
24
+ /**
25
+ * Error thrown when an invalid cron expression is provided.
26
+ *
27
+ * @example
28
+ * ```typescript
29
+ * try {
30
+ * await monque.schedule('invalid cron', 'job', data);
31
+ * } catch (error) {
32
+ * if (error instanceof InvalidCronError) {
33
+ * console.error('Invalid expression:', error.expression);
34
+ * }
35
+ * }
36
+ * ```
37
+ */
38
+ var InvalidCronError = class InvalidCronError extends MonqueError {
39
+ constructor(expression, message) {
40
+ super(message);
41
+ this.expression = expression;
42
+ this.name = "InvalidCronError";
43
+ /* istanbul ignore next -- @preserve captureStackTrace is always available in Node.js */
44
+ if (Error.captureStackTrace) Error.captureStackTrace(this, InvalidCronError);
45
+ }
46
+ };
47
+ /**
48
+ * Error thrown when there's a database connection issue.
49
+ *
50
+ * @example
51
+ * ```typescript
52
+ * try {
53
+ * await monque.enqueue('job', data);
54
+ * } catch (error) {
55
+ * if (error instanceof ConnectionError) {
56
+ * console.error('Database connection lost');
57
+ * }
58
+ * }
59
+ * ```
60
+ */
61
+ var ConnectionError = class ConnectionError extends MonqueError {
62
+ constructor(message, options) {
63
+ super(message);
64
+ this.name = "ConnectionError";
65
+ if (options?.cause) this.cause = options.cause;
66
+ /* istanbul ignore next -- @preserve captureStackTrace is always available in Node.js */
67
+ if (Error.captureStackTrace) Error.captureStackTrace(this, ConnectionError);
68
+ }
69
+ };
70
+ /**
71
+ * Error thrown when graceful shutdown times out.
72
+ * Includes information about jobs that were still in progress.
73
+ *
74
+ * @example
75
+ * ```typescript
76
+ * try {
77
+ * await monque.stop();
78
+ * } catch (error) {
79
+ * if (error instanceof ShutdownTimeoutError) {
80
+ * console.error('Incomplete jobs:', error.incompleteJobs.length);
81
+ * }
82
+ * }
83
+ * ```
84
+ */
85
+ var ShutdownTimeoutError = class ShutdownTimeoutError extends MonqueError {
86
+ constructor(message, incompleteJobs) {
87
+ super(message);
88
+ this.incompleteJobs = incompleteJobs;
89
+ this.name = "ShutdownTimeoutError";
90
+ /* istanbul ignore next -- @preserve captureStackTrace is always available in Node.js */
91
+ if (Error.captureStackTrace) Error.captureStackTrace(this, ShutdownTimeoutError);
92
+ }
93
+ };
94
+ /**
95
+ * Error thrown when attempting to register a worker for a job name
96
+ * that already has a registered worker, without explicitly allowing replacement.
97
+ *
98
+ * @example
99
+ * ```typescript
100
+ * try {
101
+ * monque.worker('send-email', handler1);
102
+ * monque.worker('send-email', handler2); // throws
103
+ * } catch (error) {
104
+ * if (error instanceof WorkerRegistrationError) {
105
+ * console.error('Worker already registered for:', error.jobName);
106
+ * }
107
+ * }
108
+ *
109
+ * // To intentionally replace a worker:
110
+ * monque.worker('send-email', handler2, { replace: true });
111
+ * ```
112
+ */
113
+ var WorkerRegistrationError = class WorkerRegistrationError extends MonqueError {
114
+ constructor(message, jobName) {
115
+ super(message);
116
+ this.jobName = jobName;
117
+ this.name = "WorkerRegistrationError";
118
+ /* istanbul ignore next -- @preserve captureStackTrace is always available in Node.js */
119
+ if (Error.captureStackTrace) Error.captureStackTrace(this, WorkerRegistrationError);
120
+ }
121
+ };
122
+
123
+ //#endregion
124
+ export { WorkerRegistrationError as a, ShutdownTimeoutError as i, InvalidCronError as n, MonqueError as r, ConnectionError as t };
125
+ //# sourceMappingURL=errors-DW20rHWR.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors-DW20rHWR.mjs","names":["expression: string","incompleteJobs: Job[]","jobName: string"],"sources":["../src/shared/errors.ts"],"sourcesContent":["import type { Job } from '@/jobs';\n\n/**\n * Base error class for all Monque-related errors.\n *\n * @example\n * ```typescript\n * try {\n * await monque.enqueue('job', data);\n * } catch (error) {\n * if (error instanceof MonqueError) {\n * console.error('Monque error:', error.message);\n * }\n * }\n * ```\n */\nexport class MonqueError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = 'MonqueError';\n\t\t// Maintains proper stack trace for where our error was thrown (only available on V8)\n\t\t/* istanbul ignore next -- @preserve captureStackTrace is always available in Node.js */\n\t\tif (Error.captureStackTrace) {\n\t\t\tError.captureStackTrace(this, MonqueError);\n\t\t}\n\t}\n}\n\n/**\n * Error thrown when an invalid cron expression is provided.\n *\n * @example\n * ```typescript\n * try {\n * await monque.schedule('invalid cron', 'job', data);\n * } catch (error) {\n * if (error instanceof InvalidCronError) {\n * console.error('Invalid expression:', error.expression);\n * }\n * }\n * ```\n */\nexport class InvalidCronError extends MonqueError {\n\tconstructor(\n\t\tpublic readonly expression: string,\n\t\tmessage: string,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = 'InvalidCronError';\n\t\t/* istanbul ignore next -- @preserve captureStackTrace is always available in Node.js */\n\t\tif (Error.captureStackTrace) {\n\t\t\tError.captureStackTrace(this, InvalidCronError);\n\t\t}\n\t}\n}\n\n/**\n * Error thrown when there's a database connection issue.\n *\n * @example\n * ```typescript\n * try {\n * await monque.enqueue('job', data);\n * } catch (error) {\n * if (error instanceof ConnectionError) {\n * console.error('Database connection lost');\n * }\n * }\n * ```\n */\nexport class ConnectionError extends MonqueError {\n\tconstructor(message: string, options?: { cause?: Error }) {\n\t\tsuper(message);\n\t\tthis.name = 'ConnectionError';\n\t\tif (options?.cause) {\n\t\t\tthis.cause = options.cause;\n\t\t}\n\t\t/* istanbul ignore next -- @preserve captureStackTrace is always available in Node.js */\n\t\tif (Error.captureStackTrace) {\n\t\t\tError.captureStackTrace(this, ConnectionError);\n\t\t}\n\t}\n}\n\n/**\n * Error thrown when graceful shutdown times out.\n * Includes information about jobs that were still in progress.\n *\n * @example\n * ```typescript\n * try {\n * await monque.stop();\n * } catch (error) {\n * if (error instanceof ShutdownTimeoutError) {\n * console.error('Incomplete jobs:', error.incompleteJobs.length);\n * }\n * }\n * ```\n */\nexport class ShutdownTimeoutError extends MonqueError {\n\tconstructor(\n\t\tmessage: string,\n\t\tpublic readonly incompleteJobs: Job[],\n\t) {\n\t\tsuper(message);\n\t\tthis.name = 'ShutdownTimeoutError';\n\t\t/* istanbul ignore next -- @preserve captureStackTrace is always available in Node.js */\n\t\tif (Error.captureStackTrace) {\n\t\t\tError.captureStackTrace(this, ShutdownTimeoutError);\n\t\t}\n\t}\n}\n\n/**\n * Error thrown when attempting to register a worker for a job name\n * that already has a registered worker, without explicitly allowing replacement.\n *\n * @example\n * ```typescript\n * try {\n * monque.worker('send-email', handler1);\n * monque.worker('send-email', handler2); // throws\n * } catch (error) {\n * if (error instanceof WorkerRegistrationError) {\n * console.error('Worker already registered for:', error.jobName);\n * }\n * }\n *\n * // To intentionally replace a worker:\n * monque.worker('send-email', handler2, { replace: true });\n * ```\n */\nexport class WorkerRegistrationError extends MonqueError {\n\tconstructor(\n\t\tmessage: string,\n\t\tpublic readonly jobName: string,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = 'WorkerRegistrationError';\n\t\t/* istanbul ignore next -- @preserve captureStackTrace is always available in Node.js */\n\t\tif (Error.captureStackTrace) {\n\t\t\tError.captureStackTrace(this, WorkerRegistrationError);\n\t\t}\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;AAgBA,IAAa,cAAb,MAAa,oBAAoB,MAAM;CACtC,YAAY,SAAiB;AAC5B,QAAM,QAAQ;AACd,OAAK,OAAO;;AAGZ,MAAI,MAAM,kBACT,OAAM,kBAAkB,MAAM,YAAY;;;;;;;;;;;;;;;;;AAmB7C,IAAa,mBAAb,MAAa,yBAAyB,YAAY;CACjD,YACC,AAAgBA,YAChB,SACC;AACD,QAAM,QAAQ;EAHE;AAIhB,OAAK,OAAO;;AAEZ,MAAI,MAAM,kBACT,OAAM,kBAAkB,MAAM,iBAAiB;;;;;;;;;;;;;;;;;AAmBlD,IAAa,kBAAb,MAAa,wBAAwB,YAAY;CAChD,YAAY,SAAiB,SAA6B;AACzD,QAAM,QAAQ;AACd,OAAK,OAAO;AACZ,MAAI,SAAS,MACZ,MAAK,QAAQ,QAAQ;;AAGtB,MAAI,MAAM,kBACT,OAAM,kBAAkB,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;AAoBjD,IAAa,uBAAb,MAAa,6BAA6B,YAAY;CACrD,YACC,SACA,AAAgBC,gBACf;AACD,QAAM,QAAQ;EAFE;AAGhB,OAAK,OAAO;;AAEZ,MAAI,MAAM,kBACT,OAAM,kBAAkB,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;AAwBtD,IAAa,0BAAb,MAAa,gCAAgC,YAAY;CACxD,YACC,SACA,AAAgBC,SACf;AACD,QAAM,QAAQ;EAFE;AAGhB,OAAK,OAAO;;AAEZ,MAAI,MAAM,kBACT,OAAM,kBAAkB,MAAM,wBAAwB"}
@@ -0,0 +1,3 @@
1
+ import { a as WorkerRegistrationError, i as ShutdownTimeoutError, n as InvalidCronError, r as MonqueError, t as ConnectionError } from "./errors-DW20rHWR.mjs";
2
+
3
+ export { ShutdownTimeoutError };