silent-cronx 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Pradeep Kumar Sheoran, BSG Technologies
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,314 @@
1
+ # SilentCronX
2
+
3
+ SilentCronX is a fast, safe, non-blocking, and reliable background job engine for Node.js.
4
+
5
+ Package: `silent-cronx`
6
+ Developer: Pradeep Kumar Sheoran (Developer)
7
+ Company: BSG Technologies
8
+ Contact / WhatsApp: `+91-8595147850`
9
+ Donation / Support UPI mobile number: `+91-8595147850`
10
+
11
+ Hashtags: `#SilentCronX` `#NodeJS` `#TypeScript` `#Cron` `#BackgroundJobs` `#WorkerThreads` `#BSGTechnologies`
12
+
13
+ ## Features
14
+
15
+ - Cron jobs with 5-field syntax and optional seconds.
16
+ - Delayed jobs, recurring jobs, and one-time background jobs.
17
+ - Queue jobs with concurrency, priority, retry, and backpressure.
18
+ - Worker thread pool for CPU-heavy module-based jobs.
19
+ - Retry with fixed, linear, or exponential backoff.
20
+ - Timeout and cancellation through `AbortSignal`.
21
+ - Prevent-overlap locks with lock TTL.
22
+ - Pause, resume, start, stop, and graceful shutdown.
23
+ - Job status, lifecycle events, logs through your logger, metrics, and health snapshots.
24
+ - In-memory storage adapter plus Redis and Postgres adapter placeholders.
25
+ - ESM, CJS, and TypeScript declaration output through `tsup`.
26
+ - Security-first design: no `eval`, no hidden process behavior, no shell execution by default.
27
+
28
+ ## Installation
29
+
30
+ ```bash
31
+ npm install silent-cronx
32
+ ```
33
+
34
+ ## Basic Cron Job
35
+
36
+ ```ts
37
+ import { createSilentCronX } from "silent-cronx";
38
+
39
+ const cron = createSilentCronX({
40
+ timezone: "Asia/Kolkata",
41
+ maxWorkers: 4,
42
+ defaultTimeout: 30000,
43
+ logger: console,
44
+ });
45
+
46
+ await cron.schedule("daily-report", {
47
+ cron: "0 9 * * *",
48
+ task: async ({ jobId, signal }) => {
49
+ if (signal.aborted) return;
50
+ console.log("Generating daily report...", jobId);
51
+ },
52
+ });
53
+
54
+ cron.start();
55
+ ```
56
+
57
+ ## Delayed Job
58
+
59
+ ```ts
60
+ await cron.delay("send-email", {
61
+ delayMs: 5000,
62
+ payload: {
63
+ userId: 101,
64
+ email: "test@example.com",
65
+ },
66
+ task: async ({ payload }) => {
67
+ console.log("Sending email", payload.email);
68
+ },
69
+ });
70
+ ```
71
+
72
+ ## Recurring Job
73
+
74
+ ```ts
75
+ await cron.every("sync-cache", {
76
+ intervalMs: 60000,
77
+ preventOverlap: true,
78
+ task: async () => {
79
+ await refreshCache();
80
+ },
81
+ });
82
+ ```
83
+
84
+ ## Worker Thread Job
85
+
86
+ Worker jobs should use a module reference. SilentCronX does not serialize or `eval` function source.
87
+
88
+ ```ts
89
+ const result = await cron.runWorker("heavy-csv-processing", {
90
+ payload: { filePath: "./large.csv" },
91
+ timeout: 60000,
92
+ worker: {
93
+ path: new URL("./workers/csvWorker.js", import.meta.url),
94
+ exportName: "processCsv",
95
+ },
96
+ });
97
+ ```
98
+
99
+ ```ts
100
+ // workers/csvWorker.ts
101
+ export async function processCsv({ payload }) {
102
+ return { processed: true, filePath: payload.filePath };
103
+ }
104
+ ```
105
+
106
+ ## Queue Job
107
+
108
+ ```ts
109
+ cron.queue("invoice-queue", {
110
+ concurrency: 5,
111
+ retry: {
112
+ attempts: 3,
113
+ backoff: "exponential",
114
+ delayMs: 1000,
115
+ },
116
+ processor: async ({ payload }) => {
117
+ console.log("Generating invoice", payload.invoiceId);
118
+ },
119
+ });
120
+
121
+ await cron.addJob("invoice-queue", {
122
+ name: "generate-invoice",
123
+ priority: 10,
124
+ payload: { invoiceId: 5001 },
125
+ });
126
+ ```
127
+
128
+ ## Retry Example
129
+
130
+ ```ts
131
+ await cron.runNow("retry-api-call", {
132
+ retry: {
133
+ attempts: 3,
134
+ delayMs: 1000,
135
+ backoff: "exponential",
136
+ shouldRetry: (error) => error instanceof Error,
137
+ },
138
+ task: async () => {
139
+ await callExternalApi();
140
+ },
141
+ });
142
+ ```
143
+
144
+ ## Timeout Example
145
+
146
+ ```ts
147
+ await cron.runNow("limited-job", {
148
+ timeout: 10000,
149
+ task: async ({ signal }) => {
150
+ await doWork({ signal });
151
+ },
152
+ });
153
+ ```
154
+
155
+ ## Prevent Overlapping
156
+
157
+ ```ts
158
+ await cron.schedule("billing-close", {
159
+ cron: "0 * * * *",
160
+ preventOverlap: true,
161
+ task: async () => {
162
+ await closeBillingWindow();
163
+ },
164
+ });
165
+ ```
166
+
167
+ ## Job Cancellation
168
+
169
+ ```ts
170
+ const jobId = await cron.delay("cancel-me", {
171
+ delayMs: 30000,
172
+ task: async () => console.log("will not run"),
173
+ });
174
+
175
+ await cron.cancel(jobId);
176
+ ```
177
+
178
+ ## Graceful Shutdown
179
+
180
+ ```ts
181
+ process.once("SIGINT", async () => {
182
+ await cron.shutdown();
183
+ process.exit(0);
184
+ });
185
+ ```
186
+
187
+ ## Events
188
+
189
+ ```ts
190
+ cron.on("job:started", (event) => {
191
+ console.log("Job started", event.jobId);
192
+ });
193
+
194
+ cron.on("job:success", (event) => {
195
+ console.log("Job success", event.jobId, event.durationMs);
196
+ });
197
+
198
+ cron.on("job:failed", (event) => {
199
+ console.log("Job failed", event.jobId, event.error);
200
+ });
201
+ ```
202
+
203
+ ## Health Status
204
+
205
+ ```ts
206
+ const health = await cron.getHealth();
207
+ console.log(health);
208
+ ```
209
+
210
+ Example response:
211
+
212
+ ```json
213
+ {
214
+ "running": true,
215
+ "scheduledJobs": 10,
216
+ "runningJobs": 2,
217
+ "queuedJobs": 15,
218
+ "workers": {
219
+ "max": 4,
220
+ "busy": 2,
221
+ "idle": 2
222
+ },
223
+ "memory": {
224
+ "storage": "memory"
225
+ }
226
+ }
227
+ ```
228
+
229
+ ## Storage Adapter
230
+
231
+ ```ts
232
+ import type { StorageAdapter } from "silent-cronx";
233
+
234
+ const storage: StorageAdapter = {
235
+ async saveJob(job) {},
236
+ async updateJob(jobId, patch) {},
237
+ async getJob(jobId) {
238
+ return null;
239
+ },
240
+ async listJobs(filter) {
241
+ return [];
242
+ },
243
+ async deleteJob(jobId) {},
244
+ async acquireLock(lockKey, ttlMs) {
245
+ return true;
246
+ },
247
+ async releaseLock(lockKey) {},
248
+ };
249
+
250
+ const cron = createSilentCronX({ storage });
251
+ ```
252
+
253
+ Use Redis or Postgres in production when multiple app instances need shared locks and durable history.
254
+
255
+ ## API Reference
256
+
257
+ - `createSilentCronX(config)`
258
+ - `cron.schedule(name, options)`
259
+ - `cron.delay(name, options)`
260
+ - `cron.every(name, options)`
261
+ - `cron.runNow(name, options)`
262
+ - `cron.runWorker(name, options)`
263
+ - `cron.queue(name, options)`
264
+ - `cron.addJob(queueName, job)`
265
+ - `cron.cancel(jobId)`
266
+ - `cron.pause(jobId)`
267
+ - `cron.resume(jobId)`
268
+ - `cron.getStatus(jobId)`
269
+ - `cron.getJobs()`
270
+ - `cron.getHealth()`
271
+ - `cron.start()`
272
+ - `cron.stop()`
273
+ - `cron.shutdown()`
274
+ - `cron.on(eventName, handler)`
275
+ - `cron.off(eventName, handler)`
276
+
277
+ ## Security Notes
278
+
279
+ SilentCronX is designed to be controllable, observable, auditable, and stoppable. It does not create hidden processes, bypass monitoring tools, execute shell commands by default, use `eval`, or run arbitrary code strings. Validate payloads from users before enqueueing jobs, keep job handlers idempotent, and use persistent storage plus distributed locks for multi-instance deployments.
280
+
281
+ ## Production Checklist
282
+
283
+ - Do not run unknown user code.
284
+ - Do not use `eval`.
285
+ - Use worker threads for CPU-heavy jobs.
286
+ - Set job timeouts.
287
+ - Set retry limits.
288
+ - Prevent overlapping for critical jobs.
289
+ - Use persistent storage for production.
290
+ - Use locks in multi-instance deployment.
291
+ - Log failures.
292
+ - Monitor job health.
293
+ - Gracefully shutdown workers.
294
+ - Keep jobs idempotent.
295
+ - Use queue backpressure.
296
+ - Validate payloads.
297
+
298
+ ## Implementation Guide
299
+
300
+ 1. Create a `createSilentCronX` instance near application startup.
301
+ 2. Register cron, interval, delay, worker, or queue jobs.
302
+ 3. Attach lifecycle event handlers for observability.
303
+ 4. Call `cron.start()` after registration.
304
+ 5. Wire `SIGINT` and `SIGTERM` to `cron.shutdown()`.
305
+ 6. Use Redis/Postgres storage for durable multi-instance workloads.
306
+
307
+ ## Development
308
+
309
+ ```bash
310
+ npm install
311
+ npm run typecheck
312
+ npm run build
313
+ npm run pack:dry
314
+ ```