@checkstack/queue-memory-backend 0.3.12 → 0.3.14

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/CHANGELOG.md CHANGED
@@ -1,5 +1,33 @@
1
1
  # @checkstack/queue-memory-backend
2
2
 
3
+ ## 0.3.14
4
+
5
+ ### Patch Changes
6
+
7
+ - 8d1ef12: ## Downstream consumer bumps for the anomaly detection + cache system rollout
8
+
9
+ Packages on this branch were updated as part of the anomaly detection feature (schema annotations on result fields, plugin metadata for the modular cache system) but were not listed in the upstream changesets.
10
+
11
+ - **`@checkstack/healthcheck-common`** (minor) — new RPC contract additions and schema changes supporting per-field anomaly metadata.
12
+ - **`@checkstack/cache-memory-common`** (minor) — new package providing access rules + plugin metadata for the in-memory cache backend.
13
+ - **healthcheck plugins** (patch) — adopt the new `x-anomaly-*` schema annotations on their result fields so anomaly detection works automatically against their checks. No public API changes.
14
+ - **integration / notification / auth / queue / collector plugins** (patch) — minor internal updates as consumers of upstream API changes (cache plugin registry, schema additions). No public API changes.
15
+
16
+ - Updated dependencies [8d1ef12]
17
+ - Updated dependencies [8d1ef12]
18
+ - @checkstack/common@0.7.0
19
+ - @checkstack/backend-api@0.13.0
20
+ - @checkstack/queue-memory-common@0.1.10
21
+ - @checkstack/queue-api@0.2.14
22
+
23
+ ## 0.3.13
24
+
25
+ ### Patch Changes
26
+
27
+ - Updated dependencies [26d8bae]
28
+ - @checkstack/backend-api@0.12.0
29
+ - @checkstack/queue-api@0.2.13
30
+
3
31
  ## 0.3.12
4
32
 
5
33
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@checkstack/queue-memory-backend",
3
- "version": "0.3.12",
3
+ "version": "0.3.14",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "checkstack": {
@@ -12,10 +12,10 @@
12
12
  "lint:code": "eslint . --max-warnings 0"
13
13
  },
14
14
  "dependencies": {
15
- "@checkstack/backend-api": "0.11.0",
16
- "@checkstack/queue-api": "0.2.11",
17
- "@checkstack/queue-memory-common": "0.1.8",
18
- "@checkstack/common": "0.6.4",
15
+ "@checkstack/backend-api": "0.12.0",
16
+ "@checkstack/queue-api": "0.2.13",
17
+ "@checkstack/queue-memory-common": "0.1.9",
18
+ "@checkstack/common": "0.6.5",
19
19
  "cron-parser": "^4.9.0",
20
20
  "zod": "^4.2.1"
21
21
  },
package/src/benchmark.ts CHANGED
@@ -64,7 +64,7 @@ async function runLoadTest(props: {
64
64
  delayMultiplier: 1,
65
65
  heartbeatIntervalMs: 0,
66
66
  },
67
- testLogger
67
+ testLogger,
68
68
  );
69
69
 
70
70
  const latencies: number[] = [];
@@ -79,7 +79,7 @@ async function runLoadTest(props: {
79
79
  latencies.push(latency);
80
80
  completed++;
81
81
  },
82
- { consumerGroup: "load-test-group", maxRetries: 0 }
82
+ { consumerGroup: "load-test-group", maxRetries: 0 },
83
83
  );
84
84
 
85
85
  const testStart = Date.now();
@@ -166,8 +166,8 @@ async function main() {
166
166
  const parallel = results.find((r) => r.concurrency === 25)!;
167
167
  console.log(
168
168
  `\n✨ Speedup: ${(sequential.durationMs / parallel.durationMs).toFixed(
169
- 1
170
- )}x faster with concurrency=25`
169
+ 1,
170
+ )}x faster with concurrency=25`,
171
171
  );
172
172
 
173
173
  // Test 4: Burst load
@@ -188,7 +188,7 @@ async function main() {
188
188
  });
189
189
  console.log(formatResult(maxResult));
190
190
  console.log(
191
- `\n✨ Max throughput: ${maxResult.jobsPerSecond.toFixed(0)} jobs/sec`
191
+ `\n✨ Max throughput: ${maxResult.jobsPerSecond.toFixed(0)} jobs/sec`,
192
192
  );
193
193
 
194
194
  // Capacity planning guidance
@@ -23,7 +23,7 @@ describe("InMemoryQueue Consumer Groups", () => {
23
23
  delayMultiplier: 0.01, // 100x faster delays for testing
24
24
  heartbeatIntervalMs: 0, // Disable heartbeat during tests
25
25
  },
26
- testLogger
26
+ testLogger,
27
27
  );
28
28
  });
29
29
 
@@ -40,14 +40,14 @@ describe("InMemoryQueue Consumer Groups", () => {
40
40
  async (job) => {
41
41
  received.push(`consumer-1:${job.data}`);
42
42
  },
43
- { consumerGroup: "group-1", maxRetries: 0 }
43
+ { consumerGroup: "group-1", maxRetries: 0 },
44
44
  );
45
45
 
46
46
  await queue.consume(
47
47
  async (job) => {
48
48
  received.push(`consumer-2:${job.data}`);
49
49
  },
50
- { consumerGroup: "group-2", maxRetries: 0 }
50
+ { consumerGroup: "group-2", maxRetries: 0 },
51
51
  );
52
52
 
53
53
  // Enqueue a message
@@ -72,14 +72,14 @@ describe("InMemoryQueue Consumer Groups", () => {
72
72
  async (job) => {
73
73
  received["group-1"].push(job.data);
74
74
  },
75
- { consumerGroup: "group-1", maxRetries: 0 }
75
+ { consumerGroup: "group-1", maxRetries: 0 },
76
76
  );
77
77
 
78
78
  await queue.consume(
79
79
  async (job) => {
80
80
  received["group-2"].push(job.data);
81
81
  },
82
- { consumerGroup: "group-2", maxRetries: 0 }
82
+ { consumerGroup: "group-2", maxRetries: 0 },
83
83
  );
84
84
 
85
85
  // Enqueue multiple messages
@@ -108,14 +108,14 @@ describe("InMemoryQueue Consumer Groups", () => {
108
108
  async (job) => {
109
109
  received["consumer-1"].push(job.data);
110
110
  },
111
- { consumerGroup: "shared-group", maxRetries: 0 }
111
+ { consumerGroup: "shared-group", maxRetries: 0 },
112
112
  );
113
113
 
114
114
  await queue.consume(
115
115
  async (job) => {
116
116
  received["consumer-2"].push(job.data);
117
117
  },
118
- { consumerGroup: "shared-group", maxRetries: 0 }
118
+ { consumerGroup: "shared-group", maxRetries: 0 },
119
119
  );
120
120
 
121
121
  // Enqueue multiple messages
@@ -152,14 +152,14 @@ describe("InMemoryQueue Consumer Groups", () => {
152
152
  async () => {
153
153
  consumer1Count++;
154
154
  },
155
- { consumerGroup: "work-group", maxRetries: 0 }
155
+ { consumerGroup: "work-group", maxRetries: 0 },
156
156
  );
157
157
 
158
158
  await queue.consume(
159
159
  async () => {
160
160
  consumer2Count++;
161
161
  },
162
- { consumerGroup: "work-group", maxRetries: 0 }
162
+ { consumerGroup: "work-group", maxRetries: 0 },
163
163
  );
164
164
 
165
165
  // Single message
@@ -186,7 +186,7 @@ describe("InMemoryQueue Consumer Groups", () => {
186
186
  throw new Error("Simulated failure");
187
187
  }
188
188
  },
189
- { consumerGroup: "retry-group", maxRetries: 3 }
189
+ { consumerGroup: "retry-group", maxRetries: 3 },
190
190
  );
191
191
 
192
192
  await queue.enqueue("test");
@@ -223,7 +223,7 @@ describe("InMemoryQueue Consumer Groups", () => {
223
223
  attempts++;
224
224
  throw new Error("Always fails");
225
225
  },
226
- { consumerGroup: "fail-group", maxRetries: 2 }
226
+ { consumerGroup: "fail-group", maxRetries: 2 },
227
227
  );
228
228
 
229
229
  await queue.enqueue("test");
@@ -246,14 +246,14 @@ describe("InMemoryQueue Consumer Groups", () => {
246
246
  async (job) => {
247
247
  broadcastReceived.push(`broadcast-1:${job.data}`);
248
248
  },
249
- { consumerGroup: "broadcast-1", maxRetries: 0 }
249
+ { consumerGroup: "broadcast-1", maxRetries: 0 },
250
250
  );
251
251
 
252
252
  await queue.consume(
253
253
  async (job) => {
254
254
  broadcastReceived.push(`broadcast-2:${job.data}`);
255
255
  },
256
- { consumerGroup: "broadcast-2", maxRetries: 0 }
256
+ { consumerGroup: "broadcast-2", maxRetries: 0 },
257
257
  );
258
258
 
259
259
  // Work-queue consumers (same group)
@@ -261,14 +261,14 @@ describe("InMemoryQueue Consumer Groups", () => {
261
261
  async (job) => {
262
262
  workQueueReceived.push(`work-1:${job.data}`);
263
263
  },
264
- { consumerGroup: "work-group", maxRetries: 0 }
264
+ { consumerGroup: "work-group", maxRetries: 0 },
265
265
  );
266
266
 
267
267
  await queue.consume(
268
268
  async (job) => {
269
269
  workQueueReceived.push(`work-2:${job.data}`);
270
270
  },
271
- { consumerGroup: "work-group", maxRetries: 0 }
271
+ { consumerGroup: "work-group", maxRetries: 0 },
272
272
  );
273
273
 
274
274
  await queue.enqueue("test-msg");
@@ -285,7 +285,7 @@ describe("InMemoryQueue Consumer Groups", () => {
285
285
  expect(workQueueReceived.length).toBe(1);
286
286
  expect(
287
287
  workQueueReceived[0] === "work-1:test-msg" ||
288
- workQueueReceived[0] === "work-2:test-msg"
288
+ workQueueReceived[0] === "work-2:test-msg",
289
289
  ).toBe(true);
290
290
  });
291
291
  });
@@ -321,7 +321,7 @@ describe("InMemoryQueue Consumer Groups", () => {
321
321
  // Simulate some processing time
322
322
  await new Promise((resolve) => setTimeout(resolve, 50));
323
323
  },
324
- { consumerGroup: "stats-group", maxRetries: 0 }
324
+ { consumerGroup: "stats-group", maxRetries: 0 },
325
325
  );
326
326
 
327
327
  await queue.enqueue("msg-1");
@@ -354,7 +354,7 @@ describe("InMemoryQueue Consumer Groups", () => {
354
354
  async () => {
355
355
  processed = true;
356
356
  },
357
- { consumerGroup: "delay-group", maxRetries: 0 }
357
+ { consumerGroup: "delay-group", maxRetries: 0 },
358
358
  );
359
359
 
360
360
  // Enqueue with 2-second delay (becomes 20ms with delayMultiplier=0.01)
@@ -383,7 +383,7 @@ describe("InMemoryQueue Consumer Groups", () => {
383
383
  async (job) => {
384
384
  processed.push(job.data);
385
385
  },
386
- { consumerGroup: "mixed-delay-group", maxRetries: 0 }
386
+ { consumerGroup: "mixed-delay-group", maxRetries: 0 },
387
387
  );
388
388
 
389
389
  // Enqueue delayed job first (10s delay = 100ms with 0.01 multiplier)
@@ -419,7 +419,7 @@ describe("InMemoryQueue Consumer Groups", () => {
419
419
  async (job) => {
420
420
  processed.push(job.data);
421
421
  },
422
- { consumerGroup: "priority-delay-group", maxRetries: 0 }
422
+ { consumerGroup: "priority-delay-group", maxRetries: 0 },
423
423
  );
424
424
 
425
425
  // Enqueue multiple delayed jobs with same delay but different priorities
@@ -460,7 +460,7 @@ describe("InMemoryQueue Consumer Groups", () => {
460
460
  async (job) => {
461
461
  processed.push(job.data);
462
462
  },
463
- { consumerGroup: "dedup-group", maxRetries: 0 }
463
+ { consumerGroup: "dedup-group", maxRetries: 0 },
464
464
  );
465
465
 
466
466
  // Enqueue job with custom jobId
@@ -488,7 +488,7 @@ describe("InMemoryQueue Consumer Groups", () => {
488
488
  async (job) => {
489
489
  processed.push(job.data);
490
490
  },
491
- { consumerGroup: "different-group", maxRetries: 0 }
491
+ { consumerGroup: "different-group", maxRetries: 0 },
492
492
  );
493
493
 
494
494
  await queue.enqueue("job1", { jobId: "job-1" });
package/src/plugin.ts CHANGED
@@ -25,7 +25,7 @@ const configSchema = z.object({
25
25
  .max(1)
26
26
  .default(1)
27
27
  .describe(
28
- "Delay multiplier (default: 1). Only change for testing purposes - set to 0.01 for 100x faster test execution."
28
+ "Delay multiplier (default: 1). Only change for testing purposes - set to 0.01 for 100x faster test execution.",
29
29
  ),
30
30
  /**
31
31
  * Interval in milliseconds for the heartbeat that checks for ready jobs.
@@ -37,7 +37,7 @@ const configSchema = z.object({
37
37
  .min(0)
38
38
  .default(5000)
39
39
  .describe(
40
- "Heartbeat interval in ms to check for ready jobs (default: 5000). Set to 0 to disable."
40
+ "Heartbeat interval in ms to check for ready jobs (default: 5000). Set to 0 to disable.",
41
41
  ),
42
42
  });
43
43
 
@@ -54,7 +54,7 @@ export class InMemoryQueuePlugin implements QueuePlugin<InMemoryQueueConfig> {
54
54
  createQueue<T>(
55
55
  name: string,
56
56
  config: InMemoryQueueConfig,
57
- logger: Logger
57
+ logger: Logger,
58
58
  ): Queue<T> {
59
59
  return new InMemoryQueue<T>(name, config, logger);
60
60
  }
@@ -22,7 +22,7 @@ function createTestQueue(name: string) {
22
22
  delayMultiplier: 0.01, // Speed up delays for testing
23
23
  heartbeatIntervalMs: 5,
24
24
  },
25
- testLogger
25
+ testLogger,
26
26
  );
27
27
  }
28
28
 
@@ -44,7 +44,7 @@ describe("InMemoryQueue Recurring Jobs", () => {
44
44
  async () => {
45
45
  executionCount++;
46
46
  },
47
- { consumerGroup: "test", maxRetries: 0 }
47
+ { consumerGroup: "test", maxRetries: 0 },
48
48
  );
49
49
 
50
50
  await queue.scheduleRecurring("payload", {
@@ -67,7 +67,7 @@ describe("InMemoryQueue Recurring Jobs", () => {
67
67
  executionCount++;
68
68
  throw new Error("Handler failed");
69
69
  },
70
- { consumerGroup: "test", maxRetries: 0 }
70
+ { consumerGroup: "test", maxRetries: 0 },
71
71
  );
72
72
 
73
73
  await queue.scheduleRecurring("payload", {
@@ -95,7 +95,7 @@ describe("InMemoryQueue Recurring Jobs", () => {
95
95
  }
96
96
  completed = true;
97
97
  },
98
- { consumerGroup: "test", maxRetries: 5 }
98
+ { consumerGroup: "test", maxRetries: 5 },
99
99
  );
100
100
 
101
101
  await queue.scheduleRecurring("payload", {
@@ -118,7 +118,7 @@ describe("InMemoryQueue Recurring Jobs", () => {
118
118
  async () => {
119
119
  executionCount++;
120
120
  },
121
- { consumerGroup: "test", maxRetries: 0 }
121
+ { consumerGroup: "test", maxRetries: 0 },
122
122
  );
123
123
 
124
124
  await queue.scheduleRecurring("payload", {
@@ -145,7 +145,7 @@ describe("InMemoryQueue Recurring Jobs", () => {
145
145
  async (job) => {
146
146
  payloads.push(job.data);
147
147
  },
148
- { consumerGroup: "test", maxRetries: 0 }
148
+ { consumerGroup: "test", maxRetries: 0 },
149
149
  );
150
150
 
151
151
  // Schedule with original payload
@@ -177,7 +177,7 @@ describe("InMemoryQueue Recurring Jobs", () => {
177
177
  async () => {
178
178
  executionCount++;
179
179
  },
180
- { consumerGroup: "test", maxRetries: 0 }
180
+ { consumerGroup: "test", maxRetries: 0 },
181
181
  );
182
182
 
183
183
  // Schedule with a long interval (won't fire again during test)