@nicnocquee/dataqueue 1.25.0 → 1.26.0-beta.20260223202259

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 (59) hide show
  1. package/ai/build-docs-content.ts +96 -0
  2. package/ai/build-llms-full.ts +42 -0
  3. package/ai/docs-content.json +284 -0
  4. package/ai/rules/advanced.md +150 -0
  5. package/ai/rules/basic.md +159 -0
  6. package/ai/rules/react-dashboard.md +83 -0
  7. package/ai/skills/dataqueue-advanced/SKILL.md +370 -0
  8. package/ai/skills/dataqueue-core/SKILL.md +234 -0
  9. package/ai/skills/dataqueue-react/SKILL.md +189 -0
  10. package/dist/cli.cjs +1149 -14
  11. package/dist/cli.cjs.map +1 -1
  12. package/dist/cli.d.cts +66 -1
  13. package/dist/cli.d.ts +66 -1
  14. package/dist/cli.js +1146 -13
  15. package/dist/cli.js.map +1 -1
  16. package/dist/index.cjs +3236 -1237
  17. package/dist/index.cjs.map +1 -1
  18. package/dist/index.d.cts +697 -23
  19. package/dist/index.d.ts +697 -23
  20. package/dist/index.js +3235 -1238
  21. package/dist/index.js.map +1 -1
  22. package/dist/mcp-server.cjs +186 -0
  23. package/dist/mcp-server.cjs.map +1 -0
  24. package/dist/mcp-server.d.cts +32 -0
  25. package/dist/mcp-server.d.ts +32 -0
  26. package/dist/mcp-server.js +175 -0
  27. package/dist/mcp-server.js.map +1 -0
  28. package/migrations/1781200000004_create_cron_schedules_table.sql +33 -0
  29. package/migrations/1781200000005_add_retry_config_to_job_queue.sql +17 -0
  30. package/package.json +24 -21
  31. package/src/backend.ts +170 -5
  32. package/src/backends/postgres.ts +992 -63
  33. package/src/backends/redis-scripts.ts +358 -26
  34. package/src/backends/redis.test.ts +1532 -0
  35. package/src/backends/redis.ts +993 -35
  36. package/src/cli.test.ts +82 -6
  37. package/src/cli.ts +73 -10
  38. package/src/cron.test.ts +126 -0
  39. package/src/cron.ts +40 -0
  40. package/src/db-util.ts +1 -1
  41. package/src/index.test.ts +1034 -11
  42. package/src/index.ts +267 -39
  43. package/src/init-command.test.ts +449 -0
  44. package/src/init-command.ts +709 -0
  45. package/src/install-mcp-command.test.ts +216 -0
  46. package/src/install-mcp-command.ts +185 -0
  47. package/src/install-rules-command.test.ts +218 -0
  48. package/src/install-rules-command.ts +233 -0
  49. package/src/install-skills-command.test.ts +176 -0
  50. package/src/install-skills-command.ts +124 -0
  51. package/src/mcp-server.test.ts +162 -0
  52. package/src/mcp-server.ts +231 -0
  53. package/src/processor.ts +104 -113
  54. package/src/queue.test.ts +465 -0
  55. package/src/queue.ts +34 -252
  56. package/src/supervisor.test.ts +340 -0
  57. package/src/supervisor.ts +177 -0
  58. package/src/types.ts +476 -12
  59. package/LICENSE +0 -21
@@ -0,0 +1,177 @@
1
+ import { QueueBackend } from './backend.js';
2
+ import { setLogContext, log } from './log-context.js';
3
+ import {
4
+ Supervisor,
5
+ SupervisorOptions,
6
+ SupervisorRunResult,
7
+ QueueEmitFn,
8
+ } from './types.js';
9
+
10
+ /**
11
+ * Creates a background supervisor that periodically runs maintenance tasks:
12
+ * reclaiming stuck jobs, cleaning up old jobs/events, and expiring
13
+ * timed-out waitpoint tokens.
14
+ *
15
+ * @param backend - The queue backend (Postgres or Redis) to run maintenance against.
16
+ * @param options - Configuration for intervals, retention, and feature toggles.
17
+ * @param emit - Optional callback to emit events to the queue's EventEmitter.
18
+ * @returns A {@link Supervisor} with `start`, `startInBackground`, `stop`,
19
+ * `stopAndDrain`, and `isRunning` methods.
20
+ */
21
+ export const createSupervisor = (
22
+ backend: QueueBackend,
23
+ options: SupervisorOptions = {},
24
+ emit?: QueueEmitFn,
25
+ ): Supervisor => {
26
+ const {
27
+ intervalMs = 60_000,
28
+ stuckJobsTimeoutMinutes = 10,
29
+ cleanupJobsDaysToKeep = 30,
30
+ cleanupEventsDaysToKeep = 30,
31
+ cleanupBatchSize = 1000,
32
+ reclaimStuckJobs = true,
33
+ expireTimedOutTokens = true,
34
+ onError = (error: Error) =>
35
+ console.error('Supervisor maintenance error:', error),
36
+ verbose = false,
37
+ } = options;
38
+
39
+ let running = false;
40
+ let timeoutId: NodeJS.Timeout | null = null;
41
+ let currentRunPromise: Promise<SupervisorRunResult> | null = null;
42
+
43
+ setLogContext(verbose);
44
+
45
+ /**
46
+ * Executes every maintenance task once, isolating failures so one
47
+ * broken task does not prevent the others from running.
48
+ */
49
+ const runOnce = async (): Promise<SupervisorRunResult> => {
50
+ setLogContext(verbose);
51
+
52
+ const result: SupervisorRunResult = {
53
+ reclaimedJobs: 0,
54
+ cleanedUpJobs: 0,
55
+ cleanedUpEvents: 0,
56
+ expiredTokens: 0,
57
+ };
58
+
59
+ if (reclaimStuckJobs) {
60
+ try {
61
+ result.reclaimedJobs = await backend.reclaimStuckJobs(
62
+ stuckJobsTimeoutMinutes,
63
+ );
64
+ if (result.reclaimedJobs > 0) {
65
+ log(`Supervisor: reclaimed ${result.reclaimedJobs} stuck jobs`);
66
+ }
67
+ } catch (e) {
68
+ const err = e instanceof Error ? e : new Error(String(e));
69
+ onError(err);
70
+ emit?.('error', err);
71
+ }
72
+ }
73
+
74
+ if (cleanupJobsDaysToKeep > 0) {
75
+ try {
76
+ result.cleanedUpJobs = await backend.cleanupOldJobs(
77
+ cleanupJobsDaysToKeep,
78
+ cleanupBatchSize,
79
+ );
80
+ if (result.cleanedUpJobs > 0) {
81
+ log(`Supervisor: cleaned up ${result.cleanedUpJobs} old jobs`);
82
+ }
83
+ } catch (e) {
84
+ const err = e instanceof Error ? e : new Error(String(e));
85
+ onError(err);
86
+ emit?.('error', err);
87
+ }
88
+ }
89
+
90
+ if (cleanupEventsDaysToKeep > 0) {
91
+ try {
92
+ result.cleanedUpEvents = await backend.cleanupOldJobEvents(
93
+ cleanupEventsDaysToKeep,
94
+ cleanupBatchSize,
95
+ );
96
+ if (result.cleanedUpEvents > 0) {
97
+ log(
98
+ `Supervisor: cleaned up ${result.cleanedUpEvents} old job events`,
99
+ );
100
+ }
101
+ } catch (e) {
102
+ const err = e instanceof Error ? e : new Error(String(e));
103
+ onError(err);
104
+ emit?.('error', err);
105
+ }
106
+ }
107
+
108
+ if (expireTimedOutTokens) {
109
+ try {
110
+ result.expiredTokens = await backend.expireTimedOutWaitpoints();
111
+ if (result.expiredTokens > 0) {
112
+ log(`Supervisor: expired ${result.expiredTokens} timed-out tokens`);
113
+ }
114
+ } catch (e) {
115
+ const err = e instanceof Error ? e : new Error(String(e));
116
+ onError(err);
117
+ emit?.('error', err);
118
+ }
119
+ }
120
+
121
+ return result;
122
+ };
123
+
124
+ return {
125
+ start: async () => {
126
+ return runOnce();
127
+ },
128
+
129
+ startInBackground: () => {
130
+ if (running) return;
131
+ log('Supervisor: starting background maintenance loop');
132
+ running = true;
133
+
134
+ const loop = async () => {
135
+ if (!running) return;
136
+ currentRunPromise = runOnce();
137
+ await currentRunPromise;
138
+ currentRunPromise = null;
139
+ if (running) {
140
+ timeoutId = setTimeout(loop, intervalMs);
141
+ }
142
+ };
143
+
144
+ loop();
145
+ },
146
+
147
+ stop: () => {
148
+ running = false;
149
+ if (timeoutId !== null) {
150
+ clearTimeout(timeoutId);
151
+ timeoutId = null;
152
+ }
153
+ log('Supervisor: stopped');
154
+ },
155
+
156
+ stopAndDrain: async (timeoutMs = 30_000) => {
157
+ running = false;
158
+ if (timeoutId !== null) {
159
+ clearTimeout(timeoutId);
160
+ timeoutId = null;
161
+ }
162
+
163
+ if (currentRunPromise) {
164
+ log('Supervisor: draining current maintenance run…');
165
+ await Promise.race([
166
+ currentRunPromise,
167
+ new Promise<void>((resolve) => setTimeout(resolve, timeoutMs)),
168
+ ]);
169
+ currentRunPromise = null;
170
+ }
171
+
172
+ log('Supervisor: drained and stopped');
173
+ },
174
+
175
+ isRunning: () => running,
176
+ };
177
+ };