{"_id":"@braedonsaunders/appkit-jobs","_rev":"4-155f7f9a94a5f2416e5ce40d5bb25180","name":"@braedonsaunders/appkit-jobs","dist-tags":{"latest":"0.2.4"},"versions":{"0.2.1":{"name":"@braedonsaunders/appkit-jobs","version":"0.2.1","keywords":["appkit","application-framework","typescript"],"author":{"name":"Braedon Saunders"},"license":"AGPL-3.0-or-later","_id":"@braedonsaunders/appkit-jobs@0.2.1","maintainers":[{"name":"braedonsaunders","email":"bsaunders@rassaun.com"}],"homepage":"https://github.com/braedonsaunders/appkit/tree/main/packages/jobs#readme","bugs":{"url":"https://github.com/braedonsaunders/appkit/issues"},"dist":{"shasum":"d620ad2587b05ab862e400f136dd450d57110d16","tarball":"https://registry.npmjs.org/@braedonsaunders/appkit-jobs/-/appkit-jobs-0.2.1.tgz","fileCount":71,"integrity":"sha512-T2wdWc0yi1vYgg4y2zNbNfdWVSozEI2NQcQm7w4fhY4RoFAu0rm2oYNApp93PnfJEm2JeBbBJqhfhNzSqyN+qg==","signatures":[{"sig":"MEQCIBk1IZ7QsY9RwE8AyqdjcCEgDA14A5v7QEaZM3K4a54QAiBxCsPyG1xAqR0ztHcS0deijnctmp+HQNtV9eymfslAxQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@braedonsaunders%2fappkit-jobs@0.2.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":262389},"main":"./index.js","type":"module","_from":"file:braedonsaunders-appkit-jobs-0.2.1.tgz","types":"./index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./index.d.ts","import":"./index.js","default":"./index.js"},"./pdf":{"types":"./pdf.d.ts","import":"./pdf.js","default":"./pdf.js"},"./email":{"types":"./email.d.ts","import":"./email.js","default":"./email.js"},"./health":{"types":"./health.d.ts","import":"./health.js","default":"./health.js"},"./capture":{"types":"./capture.d.ts","import":"./capture.js","default":"./capture.js"},"./reports":{"types":"./reports.d.ts","import":"./reports.js","default":"./reports.js"},"./sandbox":{"types":"./sandbox.d.ts","import":"./sandbox.js","default":"./sandbox.js"},"./scripts":{"types":"./scripts.d.ts","import":"./scripts.js","default":"./scripts.js"},"./outbound":{"types":"./outbound.d.ts","import":"./outbound.js","default":"./outbound.js"},"./web-push":{"types":"./web-push.d.ts","import":"./web-push.js","default":"./web-push.js"},"./migration":{"types":"./migration.d.ts","import":"./migration.js","default":"./migration.js"},"./scheduled":{"types":"./scheduled.d.ts","import":"./scheduled.js","default":"./scheduled.js"},"./rate-limit":{"types":"./rate-limit.d.ts","import":"./rate-limit.js","default":"./rate-limit.js"},"./package.json":"./package.json","./notifications":{"types":"./notifications.d.ts","import":"./notifications.js","default":"./notifications.js"}},"_npmUser":{"name":"braedonsaunders","email":"bsaunders@rassaun.com"},"_resolved":"/tmp/6d70340a6678b051317382001de661a2/braedonsaunders-appkit-jobs-0.2.1.tgz","_integrity":"sha512-T2wdWc0yi1vYgg4y2zNbNfdWVSozEI2NQcQm7w4fhY4RoFAu0rm2oYNApp93PnfJEm2JeBbBJqhfhNzSqyN+qg==","repository":{"url":"git+https://github.com/braedonsaunders/appkit.git","type":"git","directory":"packages/jobs"},"_npmVersion":"10.9.8","description":"Production BullMQ runtime and complete reusable queue profiles for email, notifications, PDF, reports, schedules, scripts, migration, capture, and outbound work.","directories":{},"_nodeVersion":"22.23.2","dependencies":{"bullmq":"^5.34.0","ioredis":"^5.4.2","web-push":"^3.6.7","@braedonsaunders/appkit-sync":"^1.1.0","@braedonsaunders/appkit-email-render":"^0.1.1"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/appkit-jobs_0.2.1_1787095204397_0.43309114720774655","host":"s3://npm-registry-packages-npm-production"}},"0.2.2":{"name":"@braedonsaunders/appkit-jobs","version":"0.2.2","keywords":["appkit","application-framework","typescript"],"author":{"name":"Braedon Saunders"},"license":"AGPL-3.0-or-later","_id":"@braedonsaunders/appkit-jobs@0.2.2","maintainers":[{"name":"braedonsaunders","email":"bsaunders@rassaun.com"}],"homepage":"https://github.com/braedonsaunders/appkit/tree/main/packages/jobs#readme","bugs":{"url":"https://github.com/braedonsaunders/appkit/issues"},"dist":{"shasum":"a13b2a56fa6ac609769d6dfae2048aa2aba81112","tarball":"https://registry.npmjs.org/@braedonsaunders/appkit-jobs/-/appkit-jobs-0.2.2.tgz","fileCount":71,"integrity":"sha512-PGcGU0fnL0RwcByKBL3wbdp3LJml7XsGa90FtMlVC5ZbeJ/ByI6JSme2a2pTjRjLbRM0oThoGOoTff769dBAXw==","signatures":[{"sig":"MEUCIQCHzfK4e3/Zd7YsjhC5D8HjlRgAJtkZU/y0cnqE3I/hjAIgYzKgwhgPEM1FTOgzvkVYWInB8js3rnH6E/2fl7hZXJs=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@braedonsaunders%2fappkit-jobs@0.2.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":262425},"main":"./index.js","type":"module","_from":"file:braedonsaunders-appkit-jobs-0.2.2.tgz","types":"./index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./index.d.ts","import":"./index.js","default":"./index.js"},"./pdf":{"types":"./pdf.d.ts","import":"./pdf.js","default":"./pdf.js"},"./email":{"types":"./email.d.ts","import":"./email.js","default":"./email.js"},"./health":{"types":"./health.d.ts","import":"./health.js","default":"./health.js"},"./capture":{"types":"./capture.d.ts","import":"./capture.js","default":"./capture.js"},"./reports":{"types":"./reports.d.ts","import":"./reports.js","default":"./reports.js"},"./sandbox":{"types":"./sandbox.d.ts","import":"./sandbox.js","default":"./sandbox.js"},"./scripts":{"types":"./scripts.d.ts","import":"./scripts.js","default":"./scripts.js"},"./outbound":{"types":"./outbound.d.ts","import":"./outbound.js","default":"./outbound.js"},"./web-push":{"types":"./web-push.d.ts","import":"./web-push.js","default":"./web-push.js"},"./migration":{"types":"./migration.d.ts","import":"./migration.js","default":"./migration.js"},"./scheduled":{"types":"./scheduled.d.ts","import":"./scheduled.js","default":"./scheduled.js"},"./rate-limit":{"types":"./rate-limit.d.ts","import":"./rate-limit.js","default":"./rate-limit.js"},"./package.json":"./package.json","./notifications":{"types":"./notifications.d.ts","import":"./notifications.js","default":"./notifications.js"}},"_npmUser":{"name":"braedonsaunders","email":"bsaunders@rassaun.com"},"_resolved":"/tmp/9c6fbacd7850e138edd968a1293b19fd/braedonsaunders-appkit-jobs-0.2.2.tgz","_integrity":"sha512-PGcGU0fnL0RwcByKBL3wbdp3LJml7XsGa90FtMlVC5ZbeJ/ByI6JSme2a2pTjRjLbRM0oThoGOoTff769dBAXw==","repository":{"url":"git+https://github.com/braedonsaunders/appkit.git","type":"git","directory":"packages/jobs"},"_npmVersion":"10.9.8","description":"Production BullMQ runtime and complete reusable queue profiles for email, notifications, PDF, reports, schedules, scripts, migration, capture, and outbound work.","directories":{},"_nodeVersion":"22.23.2","dependencies":{"bullmq":"^5.34.0","ioredis":"^5.4.2","web-push":"^3.6.7","@braedonsaunders/appkit-egress-proxy":"^0.1.1","@braedonsaunders/appkit-email-render":"^0.1.1"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/appkit-jobs_0.2.2_1787100127908_0.5643781693560863","host":"s3://npm-registry-packages-npm-production"}},"0.2.3":{"name":"@braedonsaunders/appkit-jobs","version":"0.2.3","keywords":["appkit","application-framework","typescript"],"author":{"name":"Braedon Saunders"},"license":"AGPL-3.0-or-later","_id":"@braedonsaunders/appkit-jobs@0.2.3","maintainers":[{"name":"braedonsaunders","email":"bsaunders@rassaun.com"}],"homepage":"https://github.com/braedonsaunders/appkit/tree/main/packages/jobs#readme","bugs":{"url":"https://github.com/braedonsaunders/appkit/issues"},"dist":{"shasum":"5bce7842ed2c6c89df81982d1df31f1160c23c8d","tarball":"https://registry.npmjs.org/@braedonsaunders/appkit-jobs/-/appkit-jobs-0.2.3.tgz","fileCount":71,"integrity":"sha512-floj6/o67WUCgX1Qj448k/ASvEjDPU243CQCy/6j1MJxrGbT+sfeeYG6OrjA+UgZNCNAPNjp0O7UlnNj/fXTmA==","signatures":[{"sig":"MEYCIQCv2Q7HL5tSpZrOU3jNWN4rnTY7mUUfJeHs3V8XCTIH8QIhAIuuKj8yyL+uNAig8h9XShlHaExhNylxRG7FjuQdjqMq","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@braedonsaunders%2fappkit-jobs@0.2.3","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":262425},"main":"./index.js","type":"module","_from":"file:braedonsaunders-appkit-jobs-0.2.3.tgz","types":"./index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./index.d.ts","import":"./index.js","default":"./index.js"},"./pdf":{"types":"./pdf.d.ts","import":"./pdf.js","default":"./pdf.js"},"./email":{"types":"./email.d.ts","import":"./email.js","default":"./email.js"},"./health":{"types":"./health.d.ts","import":"./health.js","default":"./health.js"},"./capture":{"types":"./capture.d.ts","import":"./capture.js","default":"./capture.js"},"./reports":{"types":"./reports.d.ts","import":"./reports.js","default":"./reports.js"},"./sandbox":{"types":"./sandbox.d.ts","import":"./sandbox.js","default":"./sandbox.js"},"./scripts":{"types":"./scripts.d.ts","import":"./scripts.js","default":"./scripts.js"},"./outbound":{"types":"./outbound.d.ts","import":"./outbound.js","default":"./outbound.js"},"./web-push":{"types":"./web-push.d.ts","import":"./web-push.js","default":"./web-push.js"},"./migration":{"types":"./migration.d.ts","import":"./migration.js","default":"./migration.js"},"./scheduled":{"types":"./scheduled.d.ts","import":"./scheduled.js","default":"./scheduled.js"},"./rate-limit":{"types":"./rate-limit.d.ts","import":"./rate-limit.js","default":"./rate-limit.js"},"./package.json":"./package.json","./notifications":{"types":"./notifications.d.ts","import":"./notifications.js","default":"./notifications.js"}},"_npmUser":{"name":"braedonsaunders","email":"bsaunders@rassaun.com"},"_resolved":"/tmp/f661c2df977b19fe2f9ed45ef7e86f8d/braedonsaunders-appkit-jobs-0.2.3.tgz","_integrity":"sha512-floj6/o67WUCgX1Qj448k/ASvEjDPU243CQCy/6j1MJxrGbT+sfeeYG6OrjA+UgZNCNAPNjp0O7UlnNj/fXTmA==","repository":{"url":"git+https://github.com/braedonsaunders/appkit.git","type":"git","directory":"packages/jobs"},"_npmVersion":"10.9.8","description":"Production BullMQ runtime and complete reusable queue profiles for email, notifications, PDF, reports, schedules, scripts, migration, capture, and outbound work.","directories":{},"_nodeVersion":"22.23.2","dependencies":{"bullmq":"^5.34.0","ioredis":"^5.4.2","web-push":"^3.6.7","@braedonsaunders/appkit-egress-proxy":"^0.2.0","@braedonsaunders/appkit-email-render":"^0.1.1"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/appkit-jobs_0.2.3_1789003737831_0.8879905309509852","host":"s3://npm-registry-packages-npm-production"}},"0.2.4":{"name":"@braedonsaunders/appkit-jobs","version":"0.2.4","description":"Production BullMQ runtime and complete reusable queue profiles for email, notifications, PDF, reports, schedules, scripts, migration, capture, and outbound work.","license":"AGPL-3.0-or-later","type":"module","exports":{".":{"types":"./index.d.ts","import":"./index.js","default":"./index.js"},"./health":{"types":"./health.d.ts","import":"./health.js","default":"./health.js"},"./rate-limit":{"types":"./rate-limit.d.ts","import":"./rate-limit.js","default":"./rate-limit.js"},"./notifications":{"types":"./notifications.d.ts","import":"./notifications.js","default":"./notifications.js"},"./email":{"types":"./email.d.ts","import":"./email.js","default":"./email.js"},"./outbound":{"types":"./outbound.d.ts","import":"./outbound.js","default":"./outbound.js"},"./pdf":{"types":"./pdf.d.ts","import":"./pdf.js","default":"./pdf.js"},"./reports":{"types":"./reports.d.ts","import":"./reports.js","default":"./reports.js"},"./scheduled":{"types":"./scheduled.d.ts","import":"./scheduled.js","default":"./scheduled.js"},"./scripts":{"types":"./scripts.d.ts","import":"./scripts.js","default":"./scripts.js"},"./sandbox":{"types":"./sandbox.d.ts","import":"./sandbox.js","default":"./sandbox.js"},"./migration":{"types":"./migration.d.ts","import":"./migration.js","default":"./migration.js"},"./capture":{"types":"./capture.d.ts","import":"./capture.js","default":"./capture.js"},"./web-push":{"types":"./web-push.d.ts","import":"./web-push.js","default":"./web-push.js"},"./package.json":"./package.json"},"main":"./index.js","types":"./index.d.ts","dependencies":{"@braedonsaunders/appkit-egress-proxy":"^0.2.1","@braedonsaunders/appkit-email-render":"^0.1.1","bullmq":"^5.34.0","ioredis":"^5.4.2","web-push":"^3.6.7"},"author":{"name":"Braedon Saunders"},"repository":{"type":"git","url":"git+https://github.com/braedonsaunders/appkit.git","directory":"packages/jobs"},"homepage":"https://github.com/braedonsaunders/appkit/tree/main/packages/jobs#readme","bugs":{"url":"https://github.com/braedonsaunders/appkit/issues"},"engines":{"node":">=22"},"keywords":["appkit","application-framework","typescript"],"_id":"@braedonsaunders/appkit-jobs@0.2.4","_integrity":"sha512-6KuofuiEAq43YYklUKjnIYmHkPow9yIP+SlR2x5zl4+uoawUXfGss5oYh8VV4qYJx5jWObDJ2jWc9qeNaDJ7OA==","_resolved":"/tmp/601c928aa44eefe8a881c17aa2e03d2c/braedonsaunders-appkit-jobs-0.2.4.tgz","_from":"file:braedonsaunders-appkit-jobs-0.2.4.tgz","_nodeVersion":"22.23.2","_npmVersion":"10.9.8","dist":{"integrity":"sha512-6KuofuiEAq43YYklUKjnIYmHkPow9yIP+SlR2x5zl4+uoawUXfGss5oYh8VV4qYJx5jWObDJ2jWc9qeNaDJ7OA==","shasum":"00513b2318f8d1fab56e3f8eb39fdd242a59b750","tarball":"https://registry.npmjs.org/@braedonsaunders/appkit-jobs/-/appkit-jobs-0.2.4.tgz","fileCount":71,"unpackedSize":262425,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@braedonsaunders%2fappkit-jobs@0.2.4","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDdZO343W5SaGWTyqzEFICNIcXYstZ1eYjgYBtjTlZUiAIgQsfUCS+FyITC84vCM/Gc6shxlo26ijLNlhFuLI3oDoc="}]},"_npmUser":{"name":"braedonsaunders","email":"bsaunders@rassaun.com"},"directories":{},"maintainers":[{"name":"braedonsaunders","email":"bsaunders@rassaun.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/appkit-jobs_0.2.4_1789076520077_0.001269317599758013"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-18T23:20:04.296Z","modified":"2026-09-10T21:42:00.590Z","0.2.1":"2026-08-18T23:20:04.549Z","0.2.2":"2026-08-19T00:42:08.070Z","0.2.3":"2026-09-10T01:28:57.978Z","0.2.4":"2026-09-10T21:42:00.224Z"},"bugs":{"url":"https://github.com/braedonsaunders/appkit/issues"},"author":{"name":"Braedon Saunders"},"license":"AGPL-3.0-or-later","homepage":"https://github.com/braedonsaunders/appkit/tree/main/packages/jobs#readme","keywords":["appkit","application-framework","typescript"],"repository":{"type":"git","url":"git+https://github.com/braedonsaunders/appkit.git","directory":"packages/jobs"},"description":"Production BullMQ runtime and complete reusable queue profiles for email, notifications, PDF, reports, schedules, scripts, migration, capture, and outbound work.","maintainers":[{"name":"braedonsaunders","email":"bsaunders@rassaun.com"}],"readme":"# `@braedonsaunders/appkit-jobs`\n\nProduction BullMQ infrastructure and reusable queue contracts for application work that must survive request boundaries.\n\nThe package is lazy by construction. Importing its root or any queue module does not open Redis, create a queue, or start a worker. Applications create one `Jobs` runtime, bind only the queue families they use, and inject their domain processors.\n\n## Queue families\n\n| Entry | Production behavior |\n| --- | --- |\n| `/email` | Validated email payloads, case-insensitive recipient de-duplication, one private job per recipient, deterministic fan-out IDs, five-attempt exponential delivery, and bounded retention. |\n| `/notifications` | Bounded 250-recipient notification batches, 40-job bulk writes, push jobs, deterministic IDs, and the production dispatcher/push worker profiles. |\n| `/pdf` | Record summaries, tenant templates, document versions, working-master previews, books, multi-part bundles, durable artifact targets, email delivery, on-demand waits, payload ceilings, and deterministic in-flight de-duplication. |\n| `/reports` | Both production report contracts: durable schedule/run claims and definition-driven render-and-deliver jobs. Each keeps its original retry and worker profile. |\n| `/scheduled` | The complete eleven-job schedule registry, exact cron/repeat identities, stale-repeat reconciliation, sync-run exclusion, and maintenance de-duplication. |\n| `/outbound` | One isolated automation/event dispatch per job, tenant identity binding, flat scalar event records, and serialized payload limits. |\n| `/scripts` | Scheduled and bulk authored-script runs with no automatic retry for non-idempotent code. |\n| `/sandbox` | Create, refresh, reset, and delete lifecycle jobs with single-attempt safety for partially applied clones. |\n| `/migration` | Full migration, incremental mirror, and attachment passes with long-job retry/retention policy. |\n| `/capture` | Deterministic asynchronous document capture with application-owned queue naming and ID prefix. |\n| `/web-push` | Hardened subscription validation and Web Push delivery. |\n| `/health`, `/rate-limit` | Bounded Redis readiness and atomic fixed-window rate limiting. |\n\nEvery queue module exports its payload types, validation functions, exact queue profile, lazy factory, enqueue methods, and worker binding. Queue names and worker concurrency can be overridden when an existing application must retain an established deployment contract.\n\n## Usage\n\n```ts\nimport { createJobs } from '@braedonsaunders/appkit-jobs'\nimport { createEmailQueue } from '@braedonsaunders/appkit-jobs/email'\nimport { createPdfQueue } from '@braedonsaunders/appkit-jobs/pdf'\nimport { createScheduledQueue } from '@braedonsaunders/appkit-jobs/scheduled'\n\nconst jobs = createJobs({ redisUrl: process.env.REDIS_URL! })\n\nconst email = createEmailQueue(jobs)\nconst pdf = createPdfQueue(jobs)\nconst scheduled = createScheduledQueue(jobs)\n\nawait email.enqueueEmail({\n  to: ['owner@example.com', 'reviewer@example.com'],\n  subject: 'Report ready',\n  html: '<p>Your report is ready.</p>',\n  text: 'Your report is ready.',\n}, { jobId: 'report-ready|run-42' })\n\nconst workers = [\n  email.createWorker(async (job) => deliverEmail(job.data)),\n  pdf.createWorker(async (job) => renderPdf(job.data)),\n  scheduled.createWorker(async (job) => runScheduledTick(job.data)),\n]\n```\n\nThe package owns transport mechanics and safe queue boundaries. Applications still own Redis credentials, provider credentials, data access, authorization, and the processors that execute domain work.\n\n## Compatibility boundaries\n\n- Tenant-scoped job types accept `tenantId`; source-compatible organization-scoped contracts also accept `orgId` where that production contract used it.\n- The two report queue modes share the established `reports` queue name but are separate factories because their payloads and retry delays are intentionally different.\n- Capture queue naming and deterministic ID prefixes are injected so a consuming application can preserve an existing queue without placing domain-specific names in AppKit.\n- Worker factories preserve the source concurrency defaults and accept explicit overrides for deployments that already tuned them.\n","readmeFilename":"README.md"}