@strav/queue 1.0.0-alpha.4 → 1.0.0-alpha.6

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@strav/queue",
3
- "version": "1.0.0-alpha.4",
3
+ "version": "1.0.0-alpha.6",
4
4
  "description": "Strav queue layer — Job + JobRegistry + dispatch contract; backends ship as drivers",
5
5
  "type": "module",
6
6
  "main": "./src/index.ts",
@@ -19,9 +19,9 @@
19
19
  "access": "public"
20
20
  },
21
21
  "dependencies": {
22
- "@strav/cli": "1.0.0-alpha.4",
23
- "@strav/database": "1.0.0-alpha.4",
24
- "@strav/kernel": "1.0.0-alpha.4"
22
+ "@strav/cli": "1.0.0-alpha.6",
23
+ "@strav/database": "1.0.0-alpha.6",
24
+ "@strav/kernel": "1.0.0-alpha.6"
25
25
  },
26
26
  "peerDependencies": {
27
27
  "@types/bun": ">=1.3.14"
@@ -138,7 +138,10 @@ export class DatabaseQueue implements Queue {
138
138
  ) VALUES (
139
139
  $1, $2, $3, $4::jsonb, 0, $5, ${availableAtFragment}, now(), now()
140
140
  )`,
141
- [jobId, queue, jobClass.jobName, JSON.stringify(payload), maxAttempts],
141
+ // `payload` defaults to `{}` for jobs that don't take input — without
142
+ // this fallback `JSON.stringify(undefined)` yields `undefined`, which
143
+ // arrives as NULL and trips the column's NOT NULL constraint.
144
+ [jobId, queue, jobClass.jobName, JSON.stringify(payload ?? {}), maxAttempts],
142
145
  )
143
146
  return jobId
144
147
  }
package/src/worker.ts CHANGED
@@ -237,6 +237,11 @@ export class Worker {
237
237
  * claim is durable + safe against concurrent Workers.
238
238
  */
239
239
  private async claim(): Promise<JobRow | null> {
240
+ // Bun.SQL 1.3.x's positional bind path doesn't auto-wrap JS arrays as
241
+ // Postgres array literals — passing `string[]` to a `::text[]` parameter
242
+ // arrives as the joined string ("default") and Postgres rejects it as a
243
+ // malformed array literal. Format the literal explicitly: `{"a","b"}`.
244
+ const queuesLiteral = `{${this.queues.map((q) => `"${q.replace(/"/g, '\\"')}"`).join(',')}}`
240
245
  return this.db.transaction(async (tx) => {
241
246
  const row = await tx.queryOne<JobRow>(
242
247
  `SELECT id, queue, job_name, payload, attempts, max_attempts
@@ -247,9 +252,15 @@ export class Worker {
247
252
  ORDER BY id
248
253
  LIMIT 1
249
254
  FOR UPDATE SKIP LOCKED`,
250
- [this.queues],
255
+ [queuesLiteral],
251
256
  )
252
257
  if (!row) return null
258
+ // Bun.SQL 1.3.x returns jsonb as a raw string from the positional
259
+ // bind path — parse it back so JobContext.payload is the original
260
+ // object the job dispatched.
261
+ if (typeof row.payload === 'string') {
262
+ row.payload = JSON.parse(row.payload)
263
+ }
253
264
  await tx.execute(
254
265
  `UPDATE "strav_jobs"
255
266
  SET reserved_at = now(), attempts = attempts + 1, updated_at = now()