pg-boss
pg-boss copied to clipboard
Get working with pglite (working example)
pglite is a fantastic version of postgres compiled to WASM. It is great for tests where you need to spin up databases. It took a bit of work to get pg-boss working with pglite, so I wanted to share what I came up with.
The main thing: I had to construct a sort of custom client. I'm not completely sure why pglite doesn't support some of these client features, not sure if pg-boss would want to add some compatibility or support.
Hopefully this helps people who might be searching for it!
import { PGlite } from "@electric-sql/pglite"
import PgBoss from "pg-boss"
// NOTE: PGlite runs in single-user mode
const db = new PGlite()
const createPlan = PgBoss.getConstructionPlans("infra_pg_boss")
await db.exec(createPlan)
function encodePgArray(arr: any[]): string {
// Only works for string/number/null arrays (sufficient for PgBoss job ids)
return `{${arr
.map((v) => {
if (v === null || v === undefined) return "NULL"
// Escape double quotes and backslashes
if (typeof v === "string")
return `"${v.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`
return String(v)
})
.join(",")}}`
}
const boss = new PgBoss({
db: {
async executeSql(text: string, values: any[] = []) {
let sql = text
if (values && values.length > 0) {
sql = text.replace(/\$(\d+)/g, (_, n) => {
const v = values[Number(n) - 1]
if (v === null || v === undefined) return "NULL"
if (Array.isArray(v)) {
// Encode as Postgres array literal
return `'${encodePgArray(v)}'`
}
if (typeof v === "number") return v.toString()
if (typeof v === "object") {
try {
return `'${JSON.stringify(v).replace(/'/g, "''")}'`
} catch (e) {
return `'${String(v).replace(/'/g, "''")}'`
}
}
return `'${String(v).replace(/'/g, "''")}'`
})
}
const results = await db.exec(sql)
if (
Array.isArray(results) &&
results.length > 0 &&
results[0] !== undefined &&
"rows" in results[0]
) {
return { rows: results[0].rows }
}
return { rows: [] }
},
},
schema: "infra_pg_boss",
})
boss.createQueue("do_the_thing")
boss.send(
"do_the_thing",
{
doTheThing: true,
},
{
singletonKey: "key1",
singletonMinutes: 30,
},
)
boss.send(
"do_the_thing",
{
doTheThing: true,
someOtherParam: 1,
},
{
singletonKey: "key1",
singletonMinutes: 30,
},
)
const jobs1 = await boss.fetch("do_the_thing", {
batchSize: 10,
})
console.log("jobs1", jobs1)
const jobs2 = await boss.fetch("do_the_thing", {
batchSize: 10,
})
console.log("jobs2", jobs2)
console.log("jobs1[0]!.id", jobs1[0]!.id)
await boss.complete("do_the_thing", jobs1[0]!.id)
Can you include some of the error messages you received? I've had issues in the past with other apps (not pg-boss) regarding json parsing which this reminds me of.