bunderstack 0.23.1 → 0.23.4
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 +24 -0
- package/dist/internal-tables-pg.d.ts.map +1 -1
- package/dist/internal-tables-pg.js +1 -0
- package/dist/internal-tables-pg.js.map +1 -1
- package/dist/internal-tables.d.ts.map +1 -1
- package/dist/internal-tables.js +1 -0
- package/dist/internal-tables.js.map +1 -1
- package/dist/jobs/define.d.ts +15 -6
- package/dist/jobs/define.d.ts.map +1 -1
- package/dist/jobs/define.js +15 -3
- package/dist/jobs/define.js.map +1 -1
- package/dist/jobs/index.d.ts +2 -2
- package/dist/jobs/index.d.ts.map +1 -1
- package/dist/jobs/index.js +1 -1
- package/dist/jobs/index.js.map +1 -1
- package/dist/jobs/worker.d.ts.map +1 -1
- package/dist/jobs/worker.js +182 -39
- package/dist/jobs/worker.js.map +1 -1
- package/package.json +1 -1
- package/skills/migrating-to-bunderstack/SKILL.md +554 -81
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,30 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `bunderstack` will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [0.23.4] - 2026-09-01
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- **Cron scheduler read amplification.** Background workers now hydrate each cron
|
|
10
|
+
watermark once per process and advance it in memory instead of aggregating
|
|
11
|
+
`_bunderstack_jobs` every polling cycle. Cron slots retain their dedupe key
|
|
12
|
+
through terminal status so delayed workers cannot recreate a completed slot.
|
|
13
|
+
The jobs table adds the `bjq_type_run_at` index; applications with committed
|
|
14
|
+
migrations must run their existing `db:generate` command and apply the
|
|
15
|
+
generated migration after upgrading.
|
|
16
|
+
|
|
17
|
+
## [0.23.2] - 2026-08-31
|
|
18
|
+
|
|
19
|
+
### Fixed
|
|
20
|
+
|
|
21
|
+
- **Renewable job leases.** Active handlers renew their fenced lease while
|
|
22
|
+
running, preventing a healthy long-running job from being reclaimed.
|
|
23
|
+
- **Bounded execution.** Jobs may use `leaseDuration`, `maxRuntime`, and
|
|
24
|
+
`ctx.signal`; `timeout` remains a deprecated alias for the lease duration.
|
|
25
|
+
- **Safe observability.** Queue lifecycle events are structured JSON without
|
|
26
|
+
payloads or exception stacks; agent-chat forwards queue cancellation to its
|
|
27
|
+
provider request.
|
|
28
|
+
|
|
5
29
|
## [0.23.1] - 2026-08-31
|
|
6
30
|
|
|
7
31
|
### Changed
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"internal-tables-pg.d.ts","sourceRoot":"","sources":["../src/internal-tables-pg.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmB9B,CAAA;AAED,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAWpC,CAAA;AAED,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"internal-tables-pg.d.ts","sourceRoot":"","sources":["../src/internal-tables-pg.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmB9B,CAAA;AAED,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAWpC,CAAA;AAED,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqB7B,CAAA;AAED,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwB/B,CAAA;AAED,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiBpC,CAAA"}
|
|
@@ -41,6 +41,7 @@ export const bunderstackJobsPg = pgTable('_bunderstack_jobs', {
|
|
|
41
41
|
}, (t) => [
|
|
42
42
|
index('bjq_claim').on(t.status, t.runAt),
|
|
43
43
|
index('bjq_type_status').on(t.type, t.status),
|
|
44
|
+
index('bjq_type_run_at').on(t.type, t.runAt),
|
|
44
45
|
uniqueIndex('bjq_dedupe').on(t.type, t.dedupeKey),
|
|
45
46
|
]);
|
|
46
47
|
export const bunderstackEmailsPg = pgTable('_bunderstack_emails', {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"internal-tables-pg.js","sourceRoot":"","sources":["../src/internal-tables-pg.ts"],"names":[],"mappings":"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","sourcesContent":["// src/internal-tables-pg.ts — Postgres twins of the internal tables. Same\n// table/column names and row shapes as the sqlite originals; timestamps stay\n// integer milliseconds (bigint mode:number) so shared code never branches.\nimport {\n bigint,\n index,\n integer,\n pgTable,\n primaryKey,\n text,\n uniqueIndex,\n} from 'drizzle-orm/pg-core'\n\nexport const bunderstackFilesPg = pgTable(\n 'bunderstack_file_meta',\n {\n fileId: text('file_id').primaryKey(),\n bucket: text('bucket').notNull(),\n ownerId: text('owner_id'),\n scopeJson: text('scope_json'),\n status: text('status').notNull(),\n filename: text('filename'),\n contentType: text('content_type'),\n size: bigint('size', { mode: 'number' }),\n createdAt: bigint('created_at', { mode: 'number' }).notNull(),\n confirmedAt: bigint('confirmed_at', { mode: 'number' }),\n },\n (t) => [\n index('bfm_owner').on(t.ownerId),\n index('bfm_scope').on(t.bucket, t.scopeJson),\n index('bfm_sweep').on(t.status, t.createdAt),\n ],\n)\n\nexport const bunderstackIdempotencyPg = pgTable(\n '_bunderstack_idempotency',\n {\n key: text('key').notNull(),\n tableName: text('table_name').notNull(),\n bodyHash: text('body_hash').notNull(),\n status: integer('status').notNull(),\n response: text('response').notNull(),\n expiresAt: bigint('expires_at', { mode: 'number' }).notNull(),\n },\n (t) => [primaryKey({ columns: [t.key, t.tableName] })],\n)\n\nexport const bunderstackJobsPg = pgTable(\n '_bunderstack_jobs',\n {\n id: text('id').primaryKey(),\n type: text('type').notNull(),\n payloadJson: text('payload_json').notNull(),\n status: text('status').notNull(),\n attempts: integer('attempts').notNull().default(0),\n runAt: bigint('run_at', { mode: 'number' }).notNull(),\n lockedUntil: bigint('locked_until', { mode: 'number' }),\n dedupeKey: text('dedupe_key'),\n lastError: text('last_error'),\n createdAt: bigint('created_at', { mode: 'number' }).notNull(),\n finishedAt: bigint('finished_at', { mode: 'number' }),\n },\n (t) => [\n index('bjq_claim').on(t.status, t.runAt),\n index('bjq_type_status').on(t.type, t.status),\n uniqueIndex('bjq_dedupe').on(t.type, t.dedupeKey),\n ],\n)\n\nexport const bunderstackEmailsPg = pgTable(\n '_bunderstack_emails',\n {\n id: text('id').primaryKey(),\n provider: text('provider').notNull(),\n providerId: text('provider_id'),\n status: text('status').notNull(),\n from: text('from_address').notNull(),\n toJson: text('to_json').notNull(),\n ccJson: text('cc_json').notNull(),\n bccJson: text('bcc_json').notNull(),\n replyTo: text('reply_to'),\n subject: text('subject').notNull(),\n html: text('html'),\n text: text('text'),\n error: text('error'),\n createdAt: bigint('created_at', { mode: 'number' }).notNull(),\n updatedAt: bigint('updated_at', { mode: 'number' }).notNull(),\n },\n (t) => [\n index('bem_created').on(t.createdAt),\n index('bem_status').on(t.status, t.createdAt),\n uniqueIndex('bem_provider_id').on(t.provider, t.providerId),\n ],\n)\n\nexport const bunderstackEmailEventsPg = pgTable(\n '_bunderstack_email_events',\n {\n id: text('id').primaryKey(),\n emailId: text('email_id')\n .notNull()\n .references(() => bunderstackEmailsPg.id, { onDelete: 'cascade' }),\n externalId: text('external_id').notNull(),\n type: text('type').notNull(),\n detailJson: text('detail_json'),\n occurredAt: bigint('occurred_at', { mode: 'number' }).notNull(),\n createdAt: bigint('created_at', { mode: 'number' }).notNull(),\n },\n (t) => [\n uniqueIndex('beev_external').on(t.externalId),\n index('beev_email_time').on(t.emailId, t.occurredAt),\n ],\n)\n"]}
|
|
1
|
+
{"version":3,"file":"internal-tables-pg.js","sourceRoot":"","sources":["../src/internal-tables-pg.ts"],"names":[],"mappings":"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","sourcesContent":["// src/internal-tables-pg.ts — Postgres twins of the internal tables. Same\n// table/column names and row shapes as the sqlite originals; timestamps stay\n// integer milliseconds (bigint mode:number) so shared code never branches.\nimport {\n bigint,\n index,\n integer,\n pgTable,\n primaryKey,\n text,\n uniqueIndex,\n} from 'drizzle-orm/pg-core'\n\nexport const bunderstackFilesPg = pgTable(\n 'bunderstack_file_meta',\n {\n fileId: text('file_id').primaryKey(),\n bucket: text('bucket').notNull(),\n ownerId: text('owner_id'),\n scopeJson: text('scope_json'),\n status: text('status').notNull(),\n filename: text('filename'),\n contentType: text('content_type'),\n size: bigint('size', { mode: 'number' }),\n createdAt: bigint('created_at', { mode: 'number' }).notNull(),\n confirmedAt: bigint('confirmed_at', { mode: 'number' }),\n },\n (t) => [\n index('bfm_owner').on(t.ownerId),\n index('bfm_scope').on(t.bucket, t.scopeJson),\n index('bfm_sweep').on(t.status, t.createdAt),\n ],\n)\n\nexport const bunderstackIdempotencyPg = pgTable(\n '_bunderstack_idempotency',\n {\n key: text('key').notNull(),\n tableName: text('table_name').notNull(),\n bodyHash: text('body_hash').notNull(),\n status: integer('status').notNull(),\n response: text('response').notNull(),\n expiresAt: bigint('expires_at', { mode: 'number' }).notNull(),\n },\n (t) => [primaryKey({ columns: [t.key, t.tableName] })],\n)\n\nexport const bunderstackJobsPg = pgTable(\n '_bunderstack_jobs',\n {\n id: text('id').primaryKey(),\n type: text('type').notNull(),\n payloadJson: text('payload_json').notNull(),\n status: text('status').notNull(),\n attempts: integer('attempts').notNull().default(0),\n runAt: bigint('run_at', { mode: 'number' }).notNull(),\n lockedUntil: bigint('locked_until', { mode: 'number' }),\n dedupeKey: text('dedupe_key'),\n lastError: text('last_error'),\n createdAt: bigint('created_at', { mode: 'number' }).notNull(),\n finishedAt: bigint('finished_at', { mode: 'number' }),\n },\n (t) => [\n index('bjq_claim').on(t.status, t.runAt),\n index('bjq_type_status').on(t.type, t.status),\n index('bjq_type_run_at').on(t.type, t.runAt),\n uniqueIndex('bjq_dedupe').on(t.type, t.dedupeKey),\n ],\n)\n\nexport const bunderstackEmailsPg = pgTable(\n '_bunderstack_emails',\n {\n id: text('id').primaryKey(),\n provider: text('provider').notNull(),\n providerId: text('provider_id'),\n status: text('status').notNull(),\n from: text('from_address').notNull(),\n toJson: text('to_json').notNull(),\n ccJson: text('cc_json').notNull(),\n bccJson: text('bcc_json').notNull(),\n replyTo: text('reply_to'),\n subject: text('subject').notNull(),\n html: text('html'),\n text: text('text'),\n error: text('error'),\n createdAt: bigint('created_at', { mode: 'number' }).notNull(),\n updatedAt: bigint('updated_at', { mode: 'number' }).notNull(),\n },\n (t) => [\n index('bem_created').on(t.createdAt),\n index('bem_status').on(t.status, t.createdAt),\n uniqueIndex('bem_provider_id').on(t.provider, t.providerId),\n ],\n)\n\nexport const bunderstackEmailEventsPg = pgTable(\n '_bunderstack_email_events',\n {\n id: text('id').primaryKey(),\n emailId: text('email_id')\n .notNull()\n .references(() => bunderstackEmailsPg.id, { onDelete: 'cascade' }),\n externalId: text('external_id').notNull(),\n type: text('type').notNull(),\n detailJson: text('detail_json'),\n occurredAt: bigint('occurred_at', { mode: 'number' }).notNull(),\n createdAt: bigint('created_at', { mode: 'number' }).notNull(),\n },\n (t) => [\n uniqueIndex('beev_external').on(t.externalId),\n index('beev_email_time').on(t.emailId, t.occurredAt),\n ],\n)\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"internal-tables.d.ts","sourceRoot":"","sources":["../src/internal-tables.ts"],"names":[],"mappings":"AAoBA,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmB5B,CAAA;AAED,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAWlC,CAAA;AAED,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"internal-tables.d.ts","sourceRoot":"","sources":["../src/internal-tables.ts"],"names":[],"mappings":"AAoBA,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmB5B,CAAA;AAED,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAWlC,CAAA;AAED,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAsB3B,CAAA;AAED,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwB7B,CAAA;AAED,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiBlC,CAAA;AAED,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAMlB,CAAA;AAEV,eAAO,MAAM,oBAAoB,EAAE,WAAW,CAAC,MAAM,CAMnD,CAAA;AAEF,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAMrB,CAAA;AAiBV,0DAA0D;AAC1D,wBAAgB,aAAa,CAAC,EAAE,EAAE,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAExC;AAED,4DAA4D;AAC5D,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAE9C;AAED,qDAAqD;AACrD,wBAAgB,YAAY,CAAC,EAAE,EAAE,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAEvC;AAED,8DAA8D;AAC9D,wBAAgB,cAAc,CAAC,EAAE,EAAE,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAEzC;AAED,4DAA4D;AAC5D,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAE9C;AAED,wBAAgB,kBAAkB,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACxE,MAAM,EAAE,OAAO,GACd,OAAO,GAAG,OAAO,eAAe,CA4BlC"}
|
package/dist/internal-tables.js
CHANGED
|
@@ -42,6 +42,7 @@ export const bunderstackJobs = sqliteTable('_bunderstack_jobs', {
|
|
|
42
42
|
}, (t) => [
|
|
43
43
|
index('bjq_claim').on(t.status, t.runAt),
|
|
44
44
|
index('bjq_type_status').on(t.type, t.status),
|
|
45
|
+
index('bjq_type_run_at').on(t.type, t.runAt),
|
|
45
46
|
// NULL dedupe keys are distinct in both dialects, so keyless jobs never collide.
|
|
46
47
|
uniqueIndex('bjq_dedupe').on(t.type, t.dedupeKey),
|
|
47
48
|
]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"internal-tables.js","sourceRoot":"","sources":["../src/internal-tables.ts"],"names":[],"mappings":"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","sourcesContent":["import { getTableName, is, isTable } from 'drizzle-orm'\nimport { PgDatabase } from 'drizzle-orm/pg-core'\nimport {\n index,\n integer,\n primaryKey,\n sqliteTable,\n text,\n uniqueIndex,\n} from 'drizzle-orm/sqlite-core'\n\nimport { detectDialect } from './dialect'\nimport {\n bunderstackEmailEventsPg,\n bunderstackEmailsPg,\n bunderstackFilesPg,\n bunderstackIdempotencyPg,\n bunderstackJobsPg,\n} from './internal-tables-pg'\n\nexport const bunderstackFiles = sqliteTable(\n 'bunderstack_file_meta',\n {\n fileId: text('file_id').primaryKey(),\n bucket: text('bucket').notNull(),\n ownerId: text('owner_id'),\n scopeJson: text('scope_json'),\n status: text('status').notNull(),\n filename: text('filename'),\n contentType: text('content_type'),\n size: integer('size'),\n createdAt: integer('created_at').notNull(),\n confirmedAt: integer('confirmed_at'),\n },\n (t) => [\n index('bfm_owner').on(t.ownerId),\n index('bfm_scope').on(t.bucket, t.scopeJson),\n index('bfm_sweep').on(t.status, t.createdAt),\n ],\n)\n\nexport const bunderstackIdempotency = sqliteTable(\n '_bunderstack_idempotency',\n {\n key: text('key').notNull(),\n tableName: text('table_name').notNull(),\n bodyHash: text('body_hash').notNull(),\n status: integer('status').notNull(),\n response: text('response').notNull(),\n expiresAt: integer('expires_at').notNull(),\n },\n (t) => [primaryKey({ columns: [t.key, t.tableName] })],\n)\n\nexport const bunderstackJobs = sqliteTable(\n '_bunderstack_jobs',\n {\n id: text('id').primaryKey(),\n type: text('type').notNull(),\n payloadJson: text('payload_json').notNull(),\n status: text('status').notNull(), // pending | running | succeeded | failed\n attempts: integer('attempts').notNull().default(0),\n runAt: integer('run_at').notNull(),\n lockedUntil: integer('locked_until'),\n dedupeKey: text('dedupe_key'),\n lastError: text('last_error'),\n createdAt: integer('created_at').notNull(),\n finishedAt: integer('finished_at'),\n },\n (t) => [\n index('bjq_claim').on(t.status, t.runAt),\n index('bjq_type_status').on(t.type, t.status),\n // NULL dedupe keys are distinct in both dialects, so keyless jobs never collide.\n uniqueIndex('bjq_dedupe').on(t.type, t.dedupeKey),\n ],\n)\n\nexport const bunderstackEmails = sqliteTable(\n '_bunderstack_emails',\n {\n id: text('id').primaryKey(),\n provider: text('provider').notNull(),\n providerId: text('provider_id'),\n status: text('status').notNull(),\n from: text('from_address').notNull(),\n toJson: text('to_json').notNull(),\n ccJson: text('cc_json').notNull(),\n bccJson: text('bcc_json').notNull(),\n replyTo: text('reply_to'),\n subject: text('subject').notNull(),\n html: text('html'),\n text: text('text'),\n error: text('error'),\n createdAt: integer('created_at').notNull(),\n updatedAt: integer('updated_at').notNull(),\n },\n (t) => [\n index('bem_created').on(t.createdAt),\n index('bem_status').on(t.status, t.createdAt),\n uniqueIndex('bem_provider_id').on(t.provider, t.providerId),\n ],\n)\n\nexport const bunderstackEmailEvents = sqliteTable(\n '_bunderstack_email_events',\n {\n id: text('id').primaryKey(),\n emailId: text('email_id')\n .notNull()\n .references(() => bunderstackEmails.id, { onDelete: 'cascade' }),\n externalId: text('external_id').notNull(),\n type: text('type').notNull(),\n detailJson: text('detail_json'),\n occurredAt: integer('occurred_at').notNull(),\n createdAt: integer('created_at').notNull(),\n },\n (t) => [\n uniqueIndex('beev_external').on(t.externalId),\n index('beev_email_time').on(t.emailId, t.occurredAt),\n ],\n)\n\nexport const INTERNAL_TABLES = {\n bunderstackFiles,\n bunderstackIdempotency,\n bunderstackJobs,\n bunderstackEmails,\n bunderstackEmailEvents,\n} as const\n\nexport const INTERNAL_TABLE_NAMES: ReadonlySet<string> = new Set([\n 'bunderstack_file_meta',\n '_bunderstack_idempotency',\n '_bunderstack_jobs',\n '_bunderstack_emails',\n '_bunderstack_email_events',\n])\n\nexport const INTERNAL_TABLES_PG = {\n bunderstackFiles: bunderstackFilesPg,\n bunderstackIdempotency: bunderstackIdempotencyPg,\n bunderstackJobs: bunderstackJobsPg,\n bunderstackEmails: bunderstackEmailsPg,\n bunderstackEmailEvents: bunderstackEmailEventsPg,\n} as const\n\n// Both dialect twins count as \"ours\" for the re-export identity check.\nconst INTERNAL_TABLE_CANDIDATES = new Map<string, readonly unknown[]>([\n [getTableName(bunderstackFiles), [bunderstackFiles, bunderstackFilesPg]],\n [\n getTableName(bunderstackIdempotency),\n [bunderstackIdempotency, bunderstackIdempotencyPg],\n ],\n [getTableName(bunderstackJobs), [bunderstackJobs, bunderstackJobsPg]],\n [getTableName(bunderstackEmails), [bunderstackEmails, bunderstackEmailsPg]],\n [\n getTableName(bunderstackEmailEvents),\n [bunderstackEmailEvents, bunderstackEmailEventsPg],\n ],\n])\n\n/** Internal file-meta table matching the db's dialect. */\nexport function filesTableFor(db: unknown) {\n return is(db, PgDatabase) ? bunderstackFilesPg : bunderstackFiles\n}\n\n/** Internal idempotency table matching the db's dialect. */\nexport function idempotencyTableFor(db: unknown) {\n return is(db, PgDatabase) ? bunderstackIdempotencyPg : bunderstackIdempotency\n}\n\n/** Internal jobs table matching the db's dialect. */\nexport function jobsTableFor(db: unknown) {\n return is(db, PgDatabase) ? bunderstackJobsPg : bunderstackJobs\n}\n\n/** Internal email journal table matching the db's dialect. */\nexport function emailsTableFor(db: unknown) {\n return is(db, PgDatabase) ? bunderstackEmailsPg : bunderstackEmails\n}\n\n/** Internal email event table matching the db's dialect. */\nexport function emailEventsTableFor(db: unknown) {\n return is(db, PgDatabase) ? bunderstackEmailEventsPg : bunderstackEmailEvents\n}\n\nexport function withInternalTables<TSchema extends Record<string, unknown>>(\n schema: TSchema,\n): TSchema & typeof INTERNAL_TABLES {\n const merged = { ...schema } as TSchema & typeof INTERNAL_TABLES\n\n for (const value of Object.values(schema)) {\n if (!isTable(value)) continue\n const name = getTableName(value)\n if (!INTERNAL_TABLE_NAMES.has(name)) continue\n\n const candidates = INTERNAL_TABLE_CANDIDATES.get(name)\n if (candidates?.includes(value)) {\n // Re-exported from bunderstack/schema(-pg) — already in user schema.\n continue\n }\n\n throw new Error(\n `[bunderstack] table name \"${name}\" is reserved by bunderstack`,\n )\n }\n\n const internal =\n detectDialect(schema) === 'pg' ? INTERNAL_TABLES_PG : INTERNAL_TABLES\n for (const [key, table] of Object.entries(internal)) {\n if (!(key in merged)) {\n ;(merged as Record<string, unknown>)[key] = table\n }\n }\n\n return merged\n}\n"]}
|
|
1
|
+
{"version":3,"file":"internal-tables.js","sourceRoot":"","sources":["../src/internal-tables.ts"],"names":[],"mappings":"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","sourcesContent":["import { getTableName, is, isTable } from 'drizzle-orm'\nimport { PgDatabase } from 'drizzle-orm/pg-core'\nimport {\n index,\n integer,\n primaryKey,\n sqliteTable,\n text,\n uniqueIndex,\n} from 'drizzle-orm/sqlite-core'\n\nimport { detectDialect } from './dialect'\nimport {\n bunderstackEmailEventsPg,\n bunderstackEmailsPg,\n bunderstackFilesPg,\n bunderstackIdempotencyPg,\n bunderstackJobsPg,\n} from './internal-tables-pg'\n\nexport const bunderstackFiles = sqliteTable(\n 'bunderstack_file_meta',\n {\n fileId: text('file_id').primaryKey(),\n bucket: text('bucket').notNull(),\n ownerId: text('owner_id'),\n scopeJson: text('scope_json'),\n status: text('status').notNull(),\n filename: text('filename'),\n contentType: text('content_type'),\n size: integer('size'),\n createdAt: integer('created_at').notNull(),\n confirmedAt: integer('confirmed_at'),\n },\n (t) => [\n index('bfm_owner').on(t.ownerId),\n index('bfm_scope').on(t.bucket, t.scopeJson),\n index('bfm_sweep').on(t.status, t.createdAt),\n ],\n)\n\nexport const bunderstackIdempotency = sqliteTable(\n '_bunderstack_idempotency',\n {\n key: text('key').notNull(),\n tableName: text('table_name').notNull(),\n bodyHash: text('body_hash').notNull(),\n status: integer('status').notNull(),\n response: text('response').notNull(),\n expiresAt: integer('expires_at').notNull(),\n },\n (t) => [primaryKey({ columns: [t.key, t.tableName] })],\n)\n\nexport const bunderstackJobs = sqliteTable(\n '_bunderstack_jobs',\n {\n id: text('id').primaryKey(),\n type: text('type').notNull(),\n payloadJson: text('payload_json').notNull(),\n status: text('status').notNull(), // pending | running | succeeded | failed\n attempts: integer('attempts').notNull().default(0),\n runAt: integer('run_at').notNull(),\n lockedUntil: integer('locked_until'),\n dedupeKey: text('dedupe_key'),\n lastError: text('last_error'),\n createdAt: integer('created_at').notNull(),\n finishedAt: integer('finished_at'),\n },\n (t) => [\n index('bjq_claim').on(t.status, t.runAt),\n index('bjq_type_status').on(t.type, t.status),\n index('bjq_type_run_at').on(t.type, t.runAt),\n // NULL dedupe keys are distinct in both dialects, so keyless jobs never collide.\n uniqueIndex('bjq_dedupe').on(t.type, t.dedupeKey),\n ],\n)\n\nexport const bunderstackEmails = sqliteTable(\n '_bunderstack_emails',\n {\n id: text('id').primaryKey(),\n provider: text('provider').notNull(),\n providerId: text('provider_id'),\n status: text('status').notNull(),\n from: text('from_address').notNull(),\n toJson: text('to_json').notNull(),\n ccJson: text('cc_json').notNull(),\n bccJson: text('bcc_json').notNull(),\n replyTo: text('reply_to'),\n subject: text('subject').notNull(),\n html: text('html'),\n text: text('text'),\n error: text('error'),\n createdAt: integer('created_at').notNull(),\n updatedAt: integer('updated_at').notNull(),\n },\n (t) => [\n index('bem_created').on(t.createdAt),\n index('bem_status').on(t.status, t.createdAt),\n uniqueIndex('bem_provider_id').on(t.provider, t.providerId),\n ],\n)\n\nexport const bunderstackEmailEvents = sqliteTable(\n '_bunderstack_email_events',\n {\n id: text('id').primaryKey(),\n emailId: text('email_id')\n .notNull()\n .references(() => bunderstackEmails.id, { onDelete: 'cascade' }),\n externalId: text('external_id').notNull(),\n type: text('type').notNull(),\n detailJson: text('detail_json'),\n occurredAt: integer('occurred_at').notNull(),\n createdAt: integer('created_at').notNull(),\n },\n (t) => [\n uniqueIndex('beev_external').on(t.externalId),\n index('beev_email_time').on(t.emailId, t.occurredAt),\n ],\n)\n\nexport const INTERNAL_TABLES = {\n bunderstackFiles,\n bunderstackIdempotency,\n bunderstackJobs,\n bunderstackEmails,\n bunderstackEmailEvents,\n} as const\n\nexport const INTERNAL_TABLE_NAMES: ReadonlySet<string> = new Set([\n 'bunderstack_file_meta',\n '_bunderstack_idempotency',\n '_bunderstack_jobs',\n '_bunderstack_emails',\n '_bunderstack_email_events',\n])\n\nexport const INTERNAL_TABLES_PG = {\n bunderstackFiles: bunderstackFilesPg,\n bunderstackIdempotency: bunderstackIdempotencyPg,\n bunderstackJobs: bunderstackJobsPg,\n bunderstackEmails: bunderstackEmailsPg,\n bunderstackEmailEvents: bunderstackEmailEventsPg,\n} as const\n\n// Both dialect twins count as \"ours\" for the re-export identity check.\nconst INTERNAL_TABLE_CANDIDATES = new Map<string, readonly unknown[]>([\n [getTableName(bunderstackFiles), [bunderstackFiles, bunderstackFilesPg]],\n [\n getTableName(bunderstackIdempotency),\n [bunderstackIdempotency, bunderstackIdempotencyPg],\n ],\n [getTableName(bunderstackJobs), [bunderstackJobs, bunderstackJobsPg]],\n [getTableName(bunderstackEmails), [bunderstackEmails, bunderstackEmailsPg]],\n [\n getTableName(bunderstackEmailEvents),\n [bunderstackEmailEvents, bunderstackEmailEventsPg],\n ],\n])\n\n/** Internal file-meta table matching the db's dialect. */\nexport function filesTableFor(db: unknown) {\n return is(db, PgDatabase) ? bunderstackFilesPg : bunderstackFiles\n}\n\n/** Internal idempotency table matching the db's dialect. */\nexport function idempotencyTableFor(db: unknown) {\n return is(db, PgDatabase) ? bunderstackIdempotencyPg : bunderstackIdempotency\n}\n\n/** Internal jobs table matching the db's dialect. */\nexport function jobsTableFor(db: unknown) {\n return is(db, PgDatabase) ? bunderstackJobsPg : bunderstackJobs\n}\n\n/** Internal email journal table matching the db's dialect. */\nexport function emailsTableFor(db: unknown) {\n return is(db, PgDatabase) ? bunderstackEmailsPg : bunderstackEmails\n}\n\n/** Internal email event table matching the db's dialect. */\nexport function emailEventsTableFor(db: unknown) {\n return is(db, PgDatabase) ? bunderstackEmailEventsPg : bunderstackEmailEvents\n}\n\nexport function withInternalTables<TSchema extends Record<string, unknown>>(\n schema: TSchema,\n): TSchema & typeof INTERNAL_TABLES {\n const merged = { ...schema } as TSchema & typeof INTERNAL_TABLES\n\n for (const value of Object.values(schema)) {\n if (!isTable(value)) continue\n const name = getTableName(value)\n if (!INTERNAL_TABLE_NAMES.has(name)) continue\n\n const candidates = INTERNAL_TABLE_CANDIDATES.get(name)\n if (candidates?.includes(value)) {\n // Re-exported from bunderstack/schema(-pg) — already in user schema.\n continue\n }\n\n throw new Error(\n `[bunderstack] table name \"${name}\" is reserved by bunderstack`,\n )\n }\n\n const internal =\n detectDialect(schema) === 'pg' ? INTERNAL_TABLES_PG : INTERNAL_TABLES\n for (const [key, table] of Object.entries(internal)) {\n if (!(key in merged)) {\n ;(merged as Record<string, unknown>)[key] = table\n }\n }\n\n return merged\n}\n"]}
|
package/dist/jobs/define.d.ts
CHANGED
|
@@ -4,7 +4,18 @@ import type { EmailFacade } from '../email.js';
|
|
|
4
4
|
import type { StorageFacade } from '../runtime.js';
|
|
5
5
|
import { type CatchUp } from './slots.js';
|
|
6
6
|
export declare const DEFAULT_RETRIES = 3;
|
|
7
|
+
export declare const DEFAULT_LEASE_DURATION_MS = 60000;
|
|
8
|
+
/** @deprecated Use DEFAULT_LEASE_DURATION_MS. */
|
|
7
9
|
export declare const DEFAULT_TIMEOUT_MS = 60000;
|
|
10
|
+
export type BackgroundTiming = {
|
|
11
|
+
/** Lease duration in ms; an expired lease sends the job back to pending. */
|
|
12
|
+
leaseDuration?: number;
|
|
13
|
+
/** Optional cooperative execution deadline in ms. */
|
|
14
|
+
maxRuntime?: number;
|
|
15
|
+
/** @deprecated Use leaseDuration. */
|
|
16
|
+
timeout?: number;
|
|
17
|
+
};
|
|
18
|
+
export declare function leaseDurationFor<T extends BackgroundTiming>(def: T): number;
|
|
8
19
|
export type EnqueueOptions = {
|
|
9
20
|
/** Collapse duplicate enqueues while the queue row is non-terminal. */
|
|
10
21
|
dedupeKey?: string;
|
|
@@ -40,9 +51,11 @@ export type JobContext<TSchema extends Record<string, unknown> = Record<string,
|
|
|
40
51
|
storage: StorageFacade;
|
|
41
52
|
jobs: JobsRuntimeFacade;
|
|
42
53
|
realtime: RealtimeFacade<TSchema>;
|
|
54
|
+
/** Aborted when execution reaches its deadline or the job loses its lease. */
|
|
55
|
+
signal: AbortSignal;
|
|
43
56
|
};
|
|
44
57
|
export type BunderstackJobContext<TSchema extends Record<string, unknown> = Record<string, unknown>, TEnvResult = Record<string, unknown>> = JobContext<TSchema, TEnvResult>;
|
|
45
|
-
export type QueueJobDefinition<TInput, TSchema extends Record<string, unknown> = Record<string, unknown>, TEnvResult = Record<string, unknown>> = {
|
|
58
|
+
export type QueueJobDefinition<TInput, TSchema extends Record<string, unknown> = Record<string, unknown>, TEnvResult = Record<string, unknown>> = BackgroundTiming & {
|
|
46
59
|
kind: 'job';
|
|
47
60
|
/** Standard Schema payload; parsed at enqueue AND before the handler runs. */
|
|
48
61
|
input?: StandardSchemaV1<unknown, TInput>;
|
|
@@ -55,8 +68,6 @@ export type QueueJobDefinition<TInput, TSchema extends Record<string, unknown> =
|
|
|
55
68
|
};
|
|
56
69
|
/** Max simultaneous `running` rows of this type, enforced per worker. */
|
|
57
70
|
concurrency?: number;
|
|
58
|
-
/** Lease duration in ms; an expired lease sends the job back to pending. */
|
|
59
|
-
timeout?: number;
|
|
60
71
|
handler: (input: TInput, ctx: JobContext<TSchema, TEnvResult>) => Promise<void> | void;
|
|
61
72
|
/** Fires once, after the final attempt fails. Errors here are logged, never retried. */
|
|
62
73
|
onFailed?: (input: TInput, error: Error, ctx: JobContext<TSchema, TEnvResult>) => Promise<void> | void;
|
|
@@ -64,7 +75,7 @@ export type QueueJobDefinition<TInput, TSchema extends Record<string, unknown> =
|
|
|
64
75
|
export type CronInvocation = {
|
|
65
76
|
scheduledFor: Date;
|
|
66
77
|
};
|
|
67
|
-
export type CronDefinition<TSchema extends Record<string, unknown> = Record<string, unknown>, TEnvResult = Record<string, unknown>, TSchedule extends string = string> = {
|
|
78
|
+
export type CronDefinition<TSchema extends Record<string, unknown> = Record<string, unknown>, TEnvResult = Record<string, unknown>, TSchedule extends string = string> = BackgroundTiming & {
|
|
68
79
|
kind: 'cron';
|
|
69
80
|
schedule: TSchedule;
|
|
70
81
|
/** Attempts after the first failure. Default 3 (so 4 total attempts). */
|
|
@@ -74,8 +85,6 @@ export type CronDefinition<TSchema extends Record<string, unknown> = Record<stri
|
|
|
74
85
|
baseMs?: number;
|
|
75
86
|
factor?: number;
|
|
76
87
|
};
|
|
77
|
-
/** Lease duration in ms; an expired lease sends the slot back to pending. */
|
|
78
|
-
timeout?: number;
|
|
79
88
|
/** How missed slots are handled on wake. Default 'latest'. */
|
|
80
89
|
catchUp?: CatchUp;
|
|
81
90
|
/** How far back catch-up looks, in ms. Default 1 hour. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"define.d.ts","sourceRoot":"","sources":["../../src/jobs/define.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAE7D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,OAAO,CAAA;AAClC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAC3C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAG/C,OAAO,EAAe,KAAK,OAAO,EAAE,MAAM,SAAS,CAAA;AAEnD,eAAO,MAAM,eAAe,IAAI,CAAA;AAChC,eAAO,MAAM,
|
|
1
|
+
{"version":3,"file":"define.d.ts","sourceRoot":"","sources":["../../src/jobs/define.ts"],"names":[],"mappings":"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"}
|
package/dist/jobs/define.js
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import { parseCron } from './cron.js';
|
|
2
2
|
import { CRON_PREFIX } from './slots.js';
|
|
3
3
|
export const DEFAULT_RETRIES = 3;
|
|
4
|
-
export const
|
|
4
|
+
export const DEFAULT_LEASE_DURATION_MS = 60_000;
|
|
5
|
+
/** @deprecated Use DEFAULT_LEASE_DURATION_MS. */
|
|
6
|
+
export const DEFAULT_TIMEOUT_MS = DEFAULT_LEASE_DURATION_MS;
|
|
7
|
+
export function leaseDurationFor(def) {
|
|
8
|
+
return def.leaseDuration ?? def.timeout ?? DEFAULT_LEASE_DURATION_MS;
|
|
9
|
+
}
|
|
5
10
|
/** Throws when a definition is unusable. Safe to call more than once. */
|
|
6
11
|
export function validateBackgroundDefs(defs) {
|
|
7
12
|
for (const [name, def] of Object.entries(defs)) {
|
|
@@ -15,8 +20,15 @@ export function validateBackgroundDefs(defs) {
|
|
|
15
20
|
(def.retries < 0 || !Number.isInteger(def.retries))) {
|
|
16
21
|
throw new Error(`[bunderstack] background task "${name}": retries must be a non-negative integer`);
|
|
17
22
|
}
|
|
18
|
-
if (def.timeout !== undefined && def.
|
|
19
|
-
throw new Error(`[bunderstack] background task "${name}": timeout
|
|
23
|
+
if (def.timeout !== undefined && def.leaseDuration !== undefined) {
|
|
24
|
+
throw new Error(`[bunderstack] background task "${name}": timeout and leaseDuration cannot both be declared`);
|
|
25
|
+
}
|
|
26
|
+
for (const field of ['timeout', 'leaseDuration', 'maxRuntime']) {
|
|
27
|
+
const value = def[field];
|
|
28
|
+
if (value !== undefined &&
|
|
29
|
+
(!Number.isFinite(value) || !Number.isInteger(value) || value <= 0)) {
|
|
30
|
+
throw new Error(`[bunderstack] background task "${name}": ${field} must be a positive finite integer`);
|
|
31
|
+
}
|
|
20
32
|
}
|
|
21
33
|
if (def.kind === 'cron') {
|
|
22
34
|
parseCron(def.schedule);
|
package/dist/jobs/define.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"define.js","sourceRoot":"","sources":["../../src/jobs/define.ts"],"names":[],"mappings":"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","sourcesContent":["// src/jobs/define.ts — job definition types and the typed builder.\n// `createJobsBuilder` exists purely to carry\n// TSchema/TEnvResult typing into inline callbacks and extracted files.\nimport type { StandardSchemaV1 } from '@standard-schema/spec'\n\nimport type { DbFor } from '../db'\nimport type { EmailFacade } from '../email'\nimport type { StorageFacade } from '../runtime'\n\nimport { parseCron } from './cron'\nimport { CRON_PREFIX, type CatchUp } from './slots'\n\nexport const DEFAULT_RETRIES = 3\nexport const DEFAULT_TIMEOUT_MS = 60_000\n\nexport type EnqueueOptions = {\n /** Collapse duplicate enqueues while the queue row is non-terminal. */\n dedupeKey?: string\n /** Milliseconds from now until the job becomes claimable. */\n delay?: number\n /** Absolute time the job becomes claimable; wins over `delay`. */\n runAt?: Date | number\n}\n\nexport type TickResult = {\n /** Rows moved from pending to running this tick. */\n claimed: number\n /** Handlers that completed successfully. */\n ran: number\n /** Handlers that threw, whether or not they will be retried. */\n failed: number\n}\n\n/**\n * The untyped runtime facade. Job handlers and API context expose this shape;\n * `app.jobs` narrows `enqueue` to the declared job names/payloads.\n */\nexport type JobsRuntimeFacade = {\n enqueue(\n name: string,\n input?: unknown,\n opts?: EnqueueOptions,\n ): Promise<{ id: string }>\n /** Run one poll cycle deterministically (tests). `now` defaults to Date.now(). */\n tick(now?: number): Promise<TickResult>\n}\n\nimport type { RealtimeFacade } from '../realtime/facade'\n\nexport type JobContext<\n TSchema extends Record<string, unknown> = Record<string, unknown>,\n TEnvResult = Record<string, unknown>,\n> = {\n db: DbFor<TSchema>\n env: TEnvResult\n email: EmailFacade\n storage: StorageFacade\n jobs: JobsRuntimeFacade\n realtime: RealtimeFacade<TSchema>\n}\n\nexport type BunderstackJobContext<\n TSchema extends Record<string, unknown> = Record<string, unknown>,\n TEnvResult = Record<string, unknown>,\n> = JobContext<TSchema, TEnvResult>\n\nexport type QueueJobDefinition<\n TInput,\n TSchema extends Record<string, unknown> = Record<string, unknown>,\n TEnvResult = Record<string, unknown>,\n> = {\n kind: 'job'\n /** Standard Schema payload; parsed at enqueue AND before the handler runs. */\n input?: StandardSchemaV1<unknown, TInput>\n /** Attempts after the first failure. Default 3 (so 4 total attempts). */\n retries?: number\n /** Delay before retry N (1-based). Default exponential: 1s, 2s, 4s, … */\n backoff?: ((attempt: number) => number) | { baseMs?: number; factor?: number }\n /** Max simultaneous `running` rows of this type, enforced per worker. */\n concurrency?: number\n /** Lease duration in ms; an expired lease sends the job back to pending. */\n timeout?: number\n handler: (\n input: TInput,\n ctx: JobContext<TSchema, TEnvResult>,\n ) => Promise<void> | void\n /** Fires once, after the final attempt fails. Errors here are logged, never retried. */\n onFailed?: (\n input: TInput,\n error: Error,\n ctx: JobContext<TSchema, TEnvResult>,\n ) => Promise<void> | void\n}\n\nexport type CronInvocation = { scheduledFor: Date }\n\nexport type CronDefinition<\n TSchema extends Record<string, unknown> = Record<string, unknown>,\n TEnvResult = Record<string, unknown>,\n TSchedule extends string = string,\n> = {\n kind: 'cron'\n schedule: TSchedule\n /** Attempts after the first failure. Default 3 (so 4 total attempts). */\n retries?: number\n /** Delay before retry N (1-based). Default exponential: 1s, 2s, 4s, … */\n backoff?: ((attempt: number) => number) | { baseMs?: number; factor?: number }\n /** Lease duration in ms; an expired lease sends the slot back to pending. */\n timeout?: number\n /** How missed slots are handled on wake. Default 'latest'. */\n catchUp?: CatchUp\n /** How far back catch-up looks, in ms. Default 1 hour. */\n catchUpWindow?: number\n handler: (\n invocation: CronInvocation,\n ctx: JobContext<TSchema, TEnvResult>,\n ) => Promise<void> | void\n /** Fires once, after the final attempt fails. Errors here are logged, never retried. */\n onFailed?: (\n invocation: CronInvocation,\n error: Error,\n ctx: JobContext<TSchema, TEnvResult>,\n ) => Promise<void> | void\n}\n\nexport type BackgroundDefinition =\n | QueueJobDefinition<any, any, any>\n | CronDefinition<any, any>\nexport type BackgroundDefs = Record<string, BackgroundDefinition>\n\n/** @deprecated Use QueueJobDefinition. */\nexport type JobDefinition<\n TInput,\n TSchema extends Record<string, unknown> = Record<string, unknown>,\n TEnvResult = Record<string, unknown>,\n> = QueueJobDefinition<TInput, TSchema, TEnvResult>\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type AnyJobDefinition = QueueJobDefinition<any, any, any>\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type AnyBackgroundDefinition =\n | QueueJobDefinition<any, any, any>\n | CronDefinition<any, any, any>\nexport type JobsDefs = BackgroundDefs\n\nexport type QueueJobKeys<TDefs extends BackgroundDefs> = {\n [K in keyof TDefs & string]: TDefs[K] extends QueueJobDefinition<\n any,\n any,\n any\n >\n ? K\n : never\n}[keyof TDefs & string]\n\n/** Throws when a definition is unusable. Safe to call more than once. */\nexport function validateBackgroundDefs(defs: BackgroundDefs): void {\n for (const [name, def] of Object.entries(defs)) {\n if (typeof def.handler !== 'function') {\n throw new Error(`[bunderstack] background task \"${name}\" has no handler`)\n }\n if (def.kind === 'job' && name.startsWith(CRON_PREFIX)) {\n throw new Error(\n `[bunderstack] job \"${name}\": the \"${CRON_PREFIX}\" prefix is reserved for cron tasks`,\n )\n }\n if (\n def.retries !== undefined &&\n (def.retries < 0 || !Number.isInteger(def.retries))\n ) {\n throw new Error(\n `[bunderstack] background task \"${name}\": retries must be a non-negative integer`,\n )\n }\n if (def.timeout !== undefined && def.timeout <= 0) {\n throw new Error(\n `[bunderstack] background task \"${name}\": timeout must be positive`,\n )\n }\n if (def.kind === 'cron') {\n parseCron(def.schedule)\n if ((def as { concurrency?: number }).concurrency !== undefined) {\n throw new Error(\n `[bunderstack] cron \"${name}\": concurrency is not supported for cron tasks — slots are already unique`,\n )\n }\n if (def.catchUpWindow !== undefined && def.catchUpWindow <= 0) {\n throw new Error(\n `[bunderstack] cron \"${name}\": catchUpWindow must be positive`,\n )\n }\n continue\n }\n if (\n def.concurrency !== undefined &&\n (def.concurrency < 1 || !Number.isInteger(def.concurrency))\n ) {\n throw new Error(\n `[bunderstack] job \"${name}\": concurrency must be a positive integer`,\n )\n }\n }\n}\n\n/** @deprecated Use validateBackgroundDefs. */\nexport const validateJobsDefs = validateBackgroundDefs\n\n/**\n * Delay in ms before retry `attempt` (1-based = the attempt that just failed).\n * Jittered by ±20% so a shared outage does not retry every job in lockstep.\n * A caller-supplied backoff function is returned verbatim — the caller owns it.\n */\nexport function backoffMs(\n def: AnyBackgroundDefinition,\n attempt: number,\n): number {\n const b = def.backoff\n if (typeof b === 'function') return b(attempt)\n const baseMs = b?.baseMs ?? 1000\n const factor = b?.factor ?? 2\n const flat = baseMs * factor ** (attempt - 1)\n return Math.round(flat * (0.8 + Math.random() * 0.4))\n}\n\n/**\n * Build the `j` instance bunderstack hands to the config's `jobs` builder\n * callback (and exports for multi-file job setups).\n */\nexport function createJobsBuilder<\n TSchema extends Record<string, unknown>,\n TEnvResult = Record<string, unknown>,\n>() {\n return {\n /** Identity with inference: pins TInput from the schema output. */\n job<TInput = undefined>(\n def: Omit<QueueJobDefinition<TInput, TSchema, TEnvResult>, 'kind'>,\n ): QueueJobDefinition<TInput, TSchema, TEnvResult> {\n return { kind: 'job', ...def }\n },\n cron<const TSchedule extends string>(\n def: Omit<CronDefinition<TSchema, TEnvResult, TSchedule>, 'kind'>,\n ): CronDefinition<TSchema, TEnvResult, TSchedule> {\n parseCron(def.schedule)\n return { kind: 'cron', ...def }\n },\n /** Identity with validation: returns the defs map, typed. */\n define<TDefs extends BackgroundDefs>(defs: TDefs): TDefs {\n validateBackgroundDefs(defs)\n return defs\n },\n }\n}\n\n/** Type of the `j` instance — for builder callbacks declared in separate files. */\nexport type BunderstackJobsBuilder<\n TSchema extends Record<string, unknown>,\n TEnvResult = Record<string, unknown>,\n> = ReturnType<typeof createJobsBuilder<TSchema, TEnvResult>>\n\n// Infers TInput from the JobDefinition's own type argument rather than\n// pattern-matching the (optional, so union-with-undefined) `input` property —\n// A required-property pattern fails structurally because `input` is optional,\n// so infer from the definition's own type argument instead.\ntype JobInputOf<TDef> =\n TDef extends QueueJobDefinition<infer TInput, any, any> ? TInput : undefined\n\n/**\n * `app.jobs`: `enqueue` narrowed to declared names + payloads. `Omit`s the\n * runtime facade's loose `enqueue` first — intersecting two same-named\n * methods instead would make TS treat them as overloaded, so the loose\n * `(name: string, ...)` signature would still accept any name.\n */\nexport type JobsFacade<TDefs extends JobsDefs> = Omit<\n JobsRuntimeFacade,\n 'enqueue'\n> & {\n enqueue<K extends QueueJobKeys<TDefs>>(\n name: K,\n ...rest: JobInputOf<TDefs[K]> extends undefined\n ? [input?: undefined, opts?: EnqueueOptions]\n : [input: JobInputOf<TDefs[K]>, opts?: EnqueueOptions]\n ): Promise<{ id: string }>\n}\n"]}
|
|
1
|
+
{"version":3,"file":"define.js","sourceRoot":"","sources":["../../src/jobs/define.ts"],"names":[],"mappings":"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","sourcesContent":["// src/jobs/define.ts — job definition types and the typed builder.\n// `createJobsBuilder` exists purely to carry\n// TSchema/TEnvResult typing into inline callbacks and extracted files.\nimport type { StandardSchemaV1 } from '@standard-schema/spec'\n\nimport type { DbFor } from '../db'\nimport type { EmailFacade } from '../email'\nimport type { StorageFacade } from '../runtime'\n\nimport { parseCron } from './cron'\nimport { CRON_PREFIX, type CatchUp } from './slots'\n\nexport const DEFAULT_RETRIES = 3\nexport const DEFAULT_LEASE_DURATION_MS = 60_000\n/** @deprecated Use DEFAULT_LEASE_DURATION_MS. */\nexport const DEFAULT_TIMEOUT_MS = DEFAULT_LEASE_DURATION_MS\n\nexport type BackgroundTiming = {\n /** Lease duration in ms; an expired lease sends the job back to pending. */\n leaseDuration?: number\n /** Optional cooperative execution deadline in ms. */\n maxRuntime?: number\n /** @deprecated Use leaseDuration. */\n timeout?: number\n}\n\nexport function leaseDurationFor<T extends BackgroundTiming>(def: T): number {\n return def.leaseDuration ?? def.timeout ?? DEFAULT_LEASE_DURATION_MS\n}\n\nexport type EnqueueOptions = {\n /** Collapse duplicate enqueues while the queue row is non-terminal. */\n dedupeKey?: string\n /** Milliseconds from now until the job becomes claimable. */\n delay?: number\n /** Absolute time the job becomes claimable; wins over `delay`. */\n runAt?: Date | number\n}\n\nexport type TickResult = {\n /** Rows moved from pending to running this tick. */\n claimed: number\n /** Handlers that completed successfully. */\n ran: number\n /** Handlers that threw, whether or not they will be retried. */\n failed: number\n}\n\n/**\n * The untyped runtime facade. Job handlers and API context expose this shape;\n * `app.jobs` narrows `enqueue` to the declared job names/payloads.\n */\nexport type JobsRuntimeFacade = {\n enqueue(\n name: string,\n input?: unknown,\n opts?: EnqueueOptions,\n ): Promise<{ id: string }>\n /** Run one poll cycle deterministically (tests). `now` defaults to Date.now(). */\n tick(now?: number): Promise<TickResult>\n}\n\nimport type { RealtimeFacade } from '../realtime/facade'\n\nexport type JobContext<\n TSchema extends Record<string, unknown> = Record<string, unknown>,\n TEnvResult = Record<string, unknown>,\n> = {\n db: DbFor<TSchema>\n env: TEnvResult\n email: EmailFacade\n storage: StorageFacade\n jobs: JobsRuntimeFacade\n realtime: RealtimeFacade<TSchema>\n /** Aborted when execution reaches its deadline or the job loses its lease. */\n signal: AbortSignal\n}\n\nexport type BunderstackJobContext<\n TSchema extends Record<string, unknown> = Record<string, unknown>,\n TEnvResult = Record<string, unknown>,\n> = JobContext<TSchema, TEnvResult>\n\nexport type QueueJobDefinition<\n TInput,\n TSchema extends Record<string, unknown> = Record<string, unknown>,\n TEnvResult = Record<string, unknown>,\n> = BackgroundTiming & {\n kind: 'job'\n /** Standard Schema payload; parsed at enqueue AND before the handler runs. */\n input?: StandardSchemaV1<unknown, TInput>\n /** Attempts after the first failure. Default 3 (so 4 total attempts). */\n retries?: number\n /** Delay before retry N (1-based). Default exponential: 1s, 2s, 4s, … */\n backoff?: ((attempt: number) => number) | { baseMs?: number; factor?: number }\n /** Max simultaneous `running` rows of this type, enforced per worker. */\n concurrency?: number\n handler: (\n input: TInput,\n ctx: JobContext<TSchema, TEnvResult>,\n ) => Promise<void> | void\n /** Fires once, after the final attempt fails. Errors here are logged, never retried. */\n onFailed?: (\n input: TInput,\n error: Error,\n ctx: JobContext<TSchema, TEnvResult>,\n ) => Promise<void> | void\n}\n\nexport type CronInvocation = { scheduledFor: Date }\n\nexport type CronDefinition<\n TSchema extends Record<string, unknown> = Record<string, unknown>,\n TEnvResult = Record<string, unknown>,\n TSchedule extends string = string,\n> = BackgroundTiming & {\n kind: 'cron'\n schedule: TSchedule\n /** Attempts after the first failure. Default 3 (so 4 total attempts). */\n retries?: number\n /** Delay before retry N (1-based). Default exponential: 1s, 2s, 4s, … */\n backoff?: ((attempt: number) => number) | { baseMs?: number; factor?: number }\n /** How missed slots are handled on wake. Default 'latest'. */\n catchUp?: CatchUp\n /** How far back catch-up looks, in ms. Default 1 hour. */\n catchUpWindow?: number\n handler: (\n invocation: CronInvocation,\n ctx: JobContext<TSchema, TEnvResult>,\n ) => Promise<void> | void\n /** Fires once, after the final attempt fails. Errors here are logged, never retried. */\n onFailed?: (\n invocation: CronInvocation,\n error: Error,\n ctx: JobContext<TSchema, TEnvResult>,\n ) => Promise<void> | void\n}\n\nexport type BackgroundDefinition =\n | QueueJobDefinition<any, any, any>\n | CronDefinition<any, any>\nexport type BackgroundDefs = Record<string, BackgroundDefinition>\n\n/** @deprecated Use QueueJobDefinition. */\nexport type JobDefinition<\n TInput,\n TSchema extends Record<string, unknown> = Record<string, unknown>,\n TEnvResult = Record<string, unknown>,\n> = QueueJobDefinition<TInput, TSchema, TEnvResult>\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type AnyJobDefinition = QueueJobDefinition<any, any, any>\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type AnyBackgroundDefinition =\n | QueueJobDefinition<any, any, any>\n | CronDefinition<any, any, any>\nexport type JobsDefs = BackgroundDefs\n\nexport type QueueJobKeys<TDefs extends BackgroundDefs> = {\n [K in keyof TDefs & string]: TDefs[K] extends QueueJobDefinition<\n any,\n any,\n any\n >\n ? K\n : never\n}[keyof TDefs & string]\n\n/** Throws when a definition is unusable. Safe to call more than once. */\nexport function validateBackgroundDefs(defs: BackgroundDefs): void {\n for (const [name, def] of Object.entries(defs)) {\n if (typeof def.handler !== 'function') {\n throw new Error(`[bunderstack] background task \"${name}\" has no handler`)\n }\n if (def.kind === 'job' && name.startsWith(CRON_PREFIX)) {\n throw new Error(\n `[bunderstack] job \"${name}\": the \"${CRON_PREFIX}\" prefix is reserved for cron tasks`,\n )\n }\n if (\n def.retries !== undefined &&\n (def.retries < 0 || !Number.isInteger(def.retries))\n ) {\n throw new Error(\n `[bunderstack] background task \"${name}\": retries must be a non-negative integer`,\n )\n }\n if (def.timeout !== undefined && def.leaseDuration !== undefined) {\n throw new Error(\n `[bunderstack] background task \"${name}\": timeout and leaseDuration cannot both be declared`,\n )\n }\n for (const field of ['timeout', 'leaseDuration', 'maxRuntime'] as const) {\n const value = def[field]\n if (\n value !== undefined &&\n (!Number.isFinite(value) || !Number.isInteger(value) || value <= 0)\n ) {\n throw new Error(\n `[bunderstack] background task \"${name}\": ${field} must be a positive finite integer`,\n )\n }\n }\n if (def.kind === 'cron') {\n parseCron(def.schedule)\n if ((def as { concurrency?: number }).concurrency !== undefined) {\n throw new Error(\n `[bunderstack] cron \"${name}\": concurrency is not supported for cron tasks — slots are already unique`,\n )\n }\n if (def.catchUpWindow !== undefined && def.catchUpWindow <= 0) {\n throw new Error(\n `[bunderstack] cron \"${name}\": catchUpWindow must be positive`,\n )\n }\n continue\n }\n if (\n def.concurrency !== undefined &&\n (def.concurrency < 1 || !Number.isInteger(def.concurrency))\n ) {\n throw new Error(\n `[bunderstack] job \"${name}\": concurrency must be a positive integer`,\n )\n }\n }\n}\n\n/** @deprecated Use validateBackgroundDefs. */\nexport const validateJobsDefs = validateBackgroundDefs\n\n/**\n * Delay in ms before retry `attempt` (1-based = the attempt that just failed).\n * Jittered by ±20% so a shared outage does not retry every job in lockstep.\n * A caller-supplied backoff function is returned verbatim — the caller owns it.\n */\nexport function backoffMs(\n def: AnyBackgroundDefinition,\n attempt: number,\n): number {\n const b = def.backoff\n if (typeof b === 'function') return b(attempt)\n const baseMs = b?.baseMs ?? 1000\n const factor = b?.factor ?? 2\n const flat = baseMs * factor ** (attempt - 1)\n return Math.round(flat * (0.8 + Math.random() * 0.4))\n}\n\n/**\n * Build the `j` instance bunderstack hands to the config's `jobs` builder\n * callback (and exports for multi-file job setups).\n */\nexport function createJobsBuilder<\n TSchema extends Record<string, unknown>,\n TEnvResult = Record<string, unknown>,\n>() {\n return {\n /** Identity with inference: pins TInput from the schema output. */\n job<TInput = undefined>(\n def: Omit<QueueJobDefinition<TInput, TSchema, TEnvResult>, 'kind'>,\n ): QueueJobDefinition<TInput, TSchema, TEnvResult> {\n return { kind: 'job', ...def }\n },\n cron<const TSchedule extends string>(\n def: Omit<CronDefinition<TSchema, TEnvResult, TSchedule>, 'kind'>,\n ): CronDefinition<TSchema, TEnvResult, TSchedule> {\n parseCron(def.schedule)\n return { kind: 'cron', ...def }\n },\n /** Identity with validation: returns the defs map, typed. */\n define<TDefs extends BackgroundDefs>(defs: TDefs): TDefs {\n validateBackgroundDefs(defs)\n return defs\n },\n }\n}\n\n/** Type of the `j` instance — for builder callbacks declared in separate files. */\nexport type BunderstackJobsBuilder<\n TSchema extends Record<string, unknown>,\n TEnvResult = Record<string, unknown>,\n> = ReturnType<typeof createJobsBuilder<TSchema, TEnvResult>>\n\n// Infers TInput from the JobDefinition's own type argument rather than\n// pattern-matching the (optional, so union-with-undefined) `input` property —\n// A required-property pattern fails structurally because `input` is optional,\n// so infer from the definition's own type argument instead.\ntype JobInputOf<TDef> =\n TDef extends QueueJobDefinition<infer TInput, any, any> ? TInput : undefined\n\n/**\n * `app.jobs`: `enqueue` narrowed to declared names + payloads. `Omit`s the\n * runtime facade's loose `enqueue` first — intersecting two same-named\n * methods instead would make TS treat them as overloaded, so the loose\n * `(name: string, ...)` signature would still accept any name.\n */\nexport type JobsFacade<TDefs extends JobsDefs> = Omit<\n JobsRuntimeFacade,\n 'enqueue'\n> & {\n enqueue<K extends QueueJobKeys<TDefs>>(\n name: K,\n ...rest: JobInputOf<TDefs[K]> extends undefined\n ? [input?: undefined, opts?: EnqueueOptions]\n : [input: JobInputOf<TDefs[K]>, opts?: EnqueueOptions]\n ): Promise<{ id: string }>\n}\n"]}
|
package/dist/jobs/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { createJobsBuilder, validateBackgroundDefs, validateJobsDefs, DEFAULT_RETRIES, DEFAULT_TIMEOUT_MS, } from './define.js';
|
|
2
|
-
export type { AnyJobDefinition, BackgroundDefinition, BackgroundDefs, BunderstackJobContext, BunderstackJobsBuilder, EnqueueOptions, JobContext, JobDefinition, QueueJobDefinition, CronDefinition, CronInvocation, QueueJobKeys, JobsDefs, JobsFacade, JobsRuntimeFacade, } from './define.js';
|
|
1
|
+
export { createJobsBuilder, validateBackgroundDefs, validateJobsDefs, DEFAULT_RETRIES, DEFAULT_LEASE_DURATION_MS, DEFAULT_TIMEOUT_MS, leaseDurationFor, } from './define.js';
|
|
2
|
+
export type { AnyJobDefinition, BackgroundTiming, BackgroundDefinition, BackgroundDefs, BunderstackJobContext, BunderstackJobsBuilder, EnqueueOptions, JobContext, JobDefinition, QueueJobDefinition, CronDefinition, CronInvocation, QueueJobKeys, JobsDefs, JobsFacade, JobsRuntimeFacade, } from './define.js';
|
|
3
3
|
export { enqueueJob } from './queue.js';
|
|
4
4
|
export { createJobRunner } from './worker.js';
|
|
5
5
|
export { startJobWorker } from './runtime.js';
|
package/dist/jobs/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/jobs/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,iBAAiB,EACjB,sBAAsB,EACtB,gBAAgB,EAChB,eAAe,EACf,kBAAkB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/jobs/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,iBAAiB,EACjB,sBAAsB,EACtB,gBAAgB,EAChB,eAAe,EACf,yBAAyB,EACzB,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,UAAU,CAAA;AACjB,YAAY,EACV,gBAAgB,EAChB,gBAAgB,EAChB,oBAAoB,EACpB,cAAc,EACd,qBAAqB,EACrB,sBAAsB,EACtB,cAAc,EACd,UAAU,EACV,aAAa,EACb,kBAAkB,EAClB,cAAc,EACd,cAAc,EACd,YAAY,EACZ,QAAQ,EACR,UAAU,EACV,iBAAiB,GAClB,MAAM,UAAU,CAAA;AACjB,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACpC,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAC1C,YAAY,EACV,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,YAAY,GACb,MAAM,WAAW,CAAA;AAClB,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAA;AAC/C,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AACnE,YAAY,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AACtC,YAAY,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA"}
|
package/dist/jobs/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/jobs/index.ts — module surface consumed by bunderstack.
|
|
2
|
-
export { createJobsBuilder, validateBackgroundDefs, validateJobsDefs, DEFAULT_RETRIES, DEFAULT_TIMEOUT_MS, } from './define.js';
|
|
2
|
+
export { createJobsBuilder, validateBackgroundDefs, validateJobsDefs, DEFAULT_RETRIES, DEFAULT_LEASE_DURATION_MS, DEFAULT_TIMEOUT_MS, leaseDurationFor, } from './define.js';
|
|
3
3
|
export { enqueueJob } from './queue.js';
|
|
4
4
|
export { createJobRunner } from './worker.js';
|
|
5
5
|
export { startJobWorker } from './runtime.js';
|
package/dist/jobs/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/jobs/index.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,OAAO,EACL,iBAAiB,EACjB,sBAAsB,EACtB,gBAAgB,EAChB,eAAe,EACf,kBAAkB,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/jobs/index.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,OAAO,EACL,iBAAiB,EACjB,sBAAsB,EACtB,gBAAgB,EAChB,eAAe,EACf,yBAAyB,EACzB,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,UAAU,CAAA;AAmBjB,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACpC,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAO1C,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAA;AAC/C,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA","sourcesContent":["// src/jobs/index.ts — module surface consumed by bunderstack.\nexport {\n createJobsBuilder,\n validateBackgroundDefs,\n validateJobsDefs,\n DEFAULT_RETRIES,\n DEFAULT_LEASE_DURATION_MS,\n DEFAULT_TIMEOUT_MS,\n leaseDurationFor,\n} from './define'\nexport type {\n AnyJobDefinition,\n BackgroundTiming,\n BackgroundDefinition,\n BackgroundDefs,\n BunderstackJobContext,\n BunderstackJobsBuilder,\n EnqueueOptions,\n JobContext,\n JobDefinition,\n QueueJobDefinition,\n CronDefinition,\n CronInvocation,\n QueueJobKeys,\n JobsDefs,\n JobsFacade,\n JobsRuntimeFacade,\n} from './define'\nexport { enqueueJob } from './queue'\nexport { createJobRunner } from './worker'\nexport { startJobWorker } from './runtime'\nexport type {\n StartWorkerOptions,\n RunWorkerOptions,\n WorkerCycleResult,\n WorkerHandle,\n} from './runtime'\nexport { parseCron, cronMatches } from './cron'\nexport { slotsDue, floorSlot, CRON_PREFIX, SLOT_MS } from './slots'\nexport type { CatchUp } from './slots'\nexport type { TickResult } from './define'\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../../src/jobs/worker.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../../src/jobs/worker.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AACvC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AACnD,OAAO,KAAK,EAEV,QAAQ,EACR,iBAAiB,EACjB,UAAU,EACX,MAAM,UAAU,CAAA;AAqDjB,KAAK,UAAU,GAAG;IAAE,IAAI,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAAA;AAsD1C,wBAAgB,eAAe,CAAC,IAAI,EAAE;IACpC,EAAE,EAAE,KAAK,CAAA;IACT,IAAI,EAAE,QAAQ,CAAA;IACd,4EAA4E;IAC5E,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC5B,MAAM,CAAC,EAAE,iBAAiB,CAAA;CAC3B;eAqgBmB,MAAM,GAAgB,OAAO,CAAC,UAAU,CAAC;iBAnBlC,MAAM,KAAgB,OAAO,CAAC,UAAU,CAAC;iBAa1C,OAAO,CAAC,IAAI,CAAC;iBAYhB,MAAM;;;;;;;;;;;;oBAiEb,SAAS,GACT,SAAS,GACT,WAAW,GACX,QAAQ;;;;;;;qBAQH,iBAAiB;EAIrC"}
|