Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
42aa651
refactor: convert codebase to typescript
davbrito Oct 26, 2025
08f913d
refactor: add types to library
davbrito Oct 26, 2025
e4915ff
refactor: add type annotations for states and policies in PgBoss class
davbrito Oct 26, 2025
9a3ee92
fix: type errors
davbrito Oct 26, 2025
4abf7ce
feat: build esm only
davbrito Oct 26, 2025
3350785
feat: add package.json#files
davbrito Oct 26, 2025
6ee790e
fix tests coverage
davbrito Oct 27, 2025
886954a
chore: improve test coverage
davbrito Oct 28, 2025
d7ef97f
Merge pull request #623 from davbrito/ts-rewrite
timgit Nov 5, 2025
ac72121
updates
timgit Nov 5, 2025
9fda7f1
consolidate config to package json
timgit Nov 5, 2025
584b89b
align startAfter types
timgit Nov 5, 2025
a3e0d1c
updated examples
timgit Nov 5, 2025
6c1450a
restored readme example with require
timgit Nov 5, 2025
bdfe536
experimental cjs exports
timgit Nov 5, 2025
b857ce1
update tests and types
timgit Nov 6, 2025
eabf583
allowing npx mocha cli for single files
timgit Nov 7, 2025
c6f5c45
simplify async assertion rejects
timgit Nov 7, 2025
6111529
updates the cjs shim comment
timgit Nov 7, 2025
2c9009f
consolidate to named exports
timgit Nov 7, 2025
36e8f6f
updates
timgit Nov 7, 2025
9c43d9b
docs [skip ci]
timgit Nov 7, 2025
e3ce039
updates
timgit Nov 7, 2025
24d6c09
tests
timgit Nov 8, 2025
ff03173
tests
timgit Nov 8, 2025
4cbc4e8
deps
timgit Nov 8, 2025
7c50523
deps fix
timgit Nov 8, 2025
b9a8c0d
tests
timgit Nov 8, 2025
1f0d0e1
update exports
timgit Nov 9, 2025
c6f0cf6
actions step names
timgit Nov 9, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion src/plans.ts
Original file line number Diff line number Diff line change
Expand Up @@ -702,7 +702,6 @@ function insertJobs (schema: string, { table, name, returnId = true }: InsertJob
END as start_after
FROM json_to_recordset($1::json) as x (
id uuid,
name text,
priority integer,
data jsonb,
"startAfter" text,
Expand Down
1 change: 0 additions & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,6 @@ export interface JobWithMetadata<T = object> extends Job<T> {

export interface JobInsert<T = object> {
id?: string;
name: string;
data?: T;
priority?: number;
retryLimit?: number;
Expand Down
8 changes: 2 additions & 6 deletions test/insertTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import * as helper from './testHelper.ts'
import { type PgBoss } from '../src/index.ts'

describe('insert', function () {
it('should create jobs from an array with name only', async function () {
it('should create jobs from an array', async function () {
this.boss = await helper.start(this.bossConfig) as PgBoss

const input = [{ name: this.schema }, { name: this.schema }, { name: this.schema }]
const input = [{}, {}, {}]

await this.boss.insert(this.schema, input)

Expand All @@ -25,7 +25,6 @@ describe('insert', function () {

const input = {
id: randomUUID(),
name: this.schema,
priority: 1,
data: { some: 'data' },
retryLimit: 1,
Expand All @@ -46,7 +45,6 @@ describe('insert', function () {
const job = await this.boss.getJobById(this.schema, input.id)

assert.strictEqual(job.id, input.id, `id input ${input.id} didn't match job ${job.id}`)
assert.strictEqual(job.name, input.name, `name input ${input.name} didn't match job ${job.name}`)
assert.strictEqual(job.priority, input.priority, `priority input ${input.priority} didn't match job ${job.priority}`)
assert.strictEqual(JSON.stringify(job.data), JSON.stringify(input.data), `data input ${input.data} didn't match job ${job.data}`)
assert.strictEqual(job.retryLimit, input.retryLimit, `retryLimit input ${input.retryLimit} didn't match job ${job.retryLimit}`)
Expand All @@ -69,7 +67,6 @@ describe('insert', function () {

const input = {
id: randomUUID(),
name: this.schema,
priority: 1,
data: { some: 'data' },
retryLimit: 1,
Expand Down Expand Up @@ -101,7 +98,6 @@ describe('insert', function () {
const job = await this.boss.getJobById(this.schema, input.id)

assert.strictEqual(job.id, input.id, `id input ${input.id} didn't match job ${job.id}`)
assert.strictEqual(job.name, input.name, `name input ${input.name} didn't match job ${job.name}`)
assert.strictEqual(job.priority, input.priority, `priority input ${input.priority} didn't match job ${job.priority}`)
assert.strictEqual(JSON.stringify(job.data), JSON.stringify(input.data), `data input ${input.data} didn't match job ${job.data}`)
assert.strictEqual(job.retryLimit, input.retryLimit, `retryLimit input ${input.retryLimit} didn't match job ${job.retryLimit}`)
Expand Down
2 changes: 1 addition & 1 deletion test/test-types.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type PgBoss from '../src/index.ts'
import { type PgBoss } from '../src/index.ts'
import type { ConstructorOptions } from '../src/types.ts'

// Extend Mocha's interfaces to include custom properties directly on 'this'
Expand Down
54 changes: 25 additions & 29 deletions test/workTest.ts
Original file line number Diff line number Diff line change
@@ -1,37 +1,33 @@
import { delay } from '../src/tools.ts'
import assert from 'node:assert'
import * as helper from './testHelper.ts'
import { type PgBoss } from '../src/index.ts'
import { JobWithMetadata, type PgBoss } from '../src/index.ts'

describe('work', function () {
it('should fail with no arguments', async function () {
this.boss = await helper.start(this.bossConfig) as PgBoss

assert.rejects(async () => {
Comment thread
timgit marked this conversation as resolved.
Outdated
this.boss = await helper.start(this.bossConfig) as PgBoss
await this.boss.work()
})
})

it('should fail if no callback provided', async function () {
this.boss = await helper.start(this.bossConfig) as PgBoss

assert.rejects(async () => {
this.boss = await helper.start(this.bossConfig) as PgBoss
await this.boss.work('foo')
})
})

it('should fail if options is not an object', async function () {
this.boss = await helper.start(this.bossConfig) as PgBoss

assert.rejects(async () => {
await this.boss.work('foo', () => {}, 'nope')
this.boss = await helper.start(this.bossConfig) as PgBoss
await this.boss.work('foo', async () => {}, 'nope')
})
})

it('offWork should fail without a name', async function () {
this.boss = await helper.start(this.bossConfig) as PgBoss

assert.rejects(async () => {
this.boss = await helper.start(this.bossConfig) as PgBoss
await this.boss.offWork()
})
})
Expand Down Expand Up @@ -64,7 +60,7 @@ describe('work', function () {

await this.boss.send(this.schema)

const workerId = await this.boss.work(this.schema, { pollingIntervalSeconds: 5 }, () => processCount++)
const workerId = await this.boss.work(this.schema, { pollingIntervalSeconds: 5 }, async () => processCount++)

await delay(500)

Expand All @@ -86,7 +82,7 @@ describe('work', function () {

this.boss.work(this.schema, async () => {
receivedCount++
await this.boss.offWork(this.schema)
await this.boss!.offWork(this.schema)
})

await this.boss.send(this.schema)
Expand All @@ -107,7 +103,7 @@ describe('work', function () {

const id = await this.boss.work(this.schema, { pollingIntervalSeconds: 0.5 }, async () => {
receivedCount++
await this.boss.offWork({ id })
await this.boss!.offWork({ id })
})

await delay(2000)
Expand All @@ -125,7 +121,7 @@ describe('work', function () {
}

return new Promise((resolve) => {
this.boss.work(this.schema, { batchSize }, async jobs => {
this.boss!.work(this.schema, { batchSize }, async jobs => {
assert.strictEqual(jobs.length, batchSize)
resolve()
})
Expand All @@ -138,17 +134,17 @@ describe('work', function () {
const jobId = await this.boss.send(this.schema)

await new Promise((resolve) => {
this.boss.work(this.schema, { batchSize: 1 }, async jobs => {
this.boss!.work(this.schema, { batchSize: 1 }, async jobs => {
assert.strictEqual(jobs.length, 1)
resolve()
})
})

await delay(500)

const job = await this.boss.getJobById(this.schema, jobId)
const job = await this.boss.getJobById(this.schema, jobId!)

assert.strictEqual(job.state, 'completed')
assert.strictEqual(job!.state, 'completed')
})

it('returning promise applies backpressure', async function () {
Expand Down Expand Up @@ -183,10 +179,10 @@ describe('work', function () {

await delay(1000)

const job = await this.boss.getJobById(this.schema, jobId)
const job = await this.boss.getJobById(this.schema, jobId!)

assert.strictEqual(job.state, 'completed')
assert.strictEqual(job.output.value, result)
assert.strictEqual(job!.state, 'completed')
assert.strictEqual(job!.output.value, result)
})

it('handler result should be stored in output', async function () {
Expand All @@ -198,10 +194,10 @@ describe('work', function () {

await delay(1000)

const job = await this.boss.getJobById(this.schema, jobId)
const job = await this.boss.getJobById(this.schema, jobId!)

assert.strictEqual(job.state, 'completed')
assert.strictEqual(job.output.something, something)
assert.strictEqual(job!.state, 'completed')
assert.strictEqual(job!.output.something, something)
})

it('job cab be deleted in handler', async function () {
Expand Down Expand Up @@ -230,7 +226,7 @@ describe('work', function () {
await this.boss.send(this.schema)

return new Promise((resolve) => {
this.boss.work(this.schema, { includeMetadata: true }, async ([job]) => {
this.boss!.work(this.schema, { includeMetadata: true }, async ([job]) => {
assert(job.startedOn !== undefined)
resolve()
})
Expand Down Expand Up @@ -262,8 +258,8 @@ describe('work', function () {

await delay(2000)

const job1 = await this.boss.getJobById(this.schema, jobId1)
const job2 = await this.boss.getJobById(this.schema, jobId2)
const job1 = await this.boss.getJobById(this.schema, jobId1!) as JobWithMetadata
const job2 = await this.boss.getJobById(this.schema, jobId2!) as JobWithMetadata

assert.strictEqual(job1.state, 'failed')
assert(job1.output.message.includes('handler execution exceeded'))
Expand All @@ -275,7 +271,7 @@ describe('work', function () {
it('should emit wip event every 2s for workers', async function () {
this.boss = await helper.start(this.bossConfig) as PgBoss

const firstWipEvent = new Promise(resolve => this.boss.once('wip', resolve))
const firstWipEvent = new Promise(resolve => this.boss!.once('wip', resolve))

await this.boss.send(this.schema)

Expand All @@ -287,7 +283,7 @@ describe('work', function () {

assert.strictEqual(wip1.length, 1)

const secondWipEvent = new Promise(resolve => this.boss.once('wip', resolve))
const secondWipEvent = new Promise(resolve => this.boss!.once('wip', resolve))

const wip2 = await secondWipEvent

Expand All @@ -300,7 +296,7 @@ describe('work', function () {
await this.boss.stop({ wait: true })

assert.rejects(async () => {
await this.boss.work(this.schema, async () => {})
await this.boss!.work(this.schema, async () => {})
})
})

Expand Down