@igniter-js/jobs 0.1.0 → 0.1.1

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/AGENTS.md CHANGED
@@ -1,557 +1,131 @@
1
- # @igniter-js/jobs - Agent Manual
1
+ # AGENTS.md - @igniter-js/jobs
2
2
 
3
- > **Last Updated:** 2025-01-01
4
- > **Version:** 0.1.0
3
+ > **Last Updated:** 2025-12-15
4
+ > **Version:** 0.0.1 (bootstrap)
5
5
 
6
- ## 1. Package Overview
6
+ This file is the operations manual for AI agents maintaining `@igniter-js/jobs`. Follow these instructions before changing any code.
7
7
 
8
- ### Purpose
8
+ ## 1. Purpose
9
9
 
10
- `@igniter-js/jobs` provides type-safe background job processing for TypeScript applications, powered by BullMQ and Redis. It follows the Igniter Builder API pattern for maximum type safety and developer experience.
10
+ `@igniter-js/jobs` delivers a fluent builder API for background jobs, workers, and queue management. It mirrors the DX of `@igniter-js/store` and `@igniter-js/telemetry`, wraps adapter implementations (BullMQ first, memory for tests), and exposes typed events, scopes, and management APIs.
11
11
 
12
- ### Core Concepts
13
-
14
- | Concept | Description |
15
- |---------|-------------|
16
- | **Queue** | Named container for jobs (e.g., `email`, `notifications`) |
17
- | **Job** | Unit of work with typed payload and handler |
18
- | **Cron Job** | Scheduled job with pattern or interval |
19
- | **Worker** | Process that executes jobs from queues |
20
- | **Scope** | Multi-tenant context (e.g., organization, workspace) |
21
- | **Actor** | Entity that triggered the job (e.g., user, system) |
22
- | **Adapter** | Implementation for queue backend (BullMQ, Memory) |
23
-
24
- ### Package Exports
25
-
26
- ```typescript
27
- // Main entry point
28
- import { IgniterJobs, IgniterQueue, IgniterJobsError } from '@igniter-js/jobs'
29
-
30
- // Adapters
31
- import { BullMQAdapter, MemoryAdapter } from '@igniter-js/jobs/adapters'
32
- ```
33
-
34
- ---
35
-
36
- ## 2. Architecture
37
-
38
- ### File Structure
12
+ ## 2. Directory Map
39
13
 
40
14
  ```
41
15
  packages/jobs/
42
16
  ├── src/
43
- │ ├── index.ts # Main exports
44
- │ ├── types/
45
- ├── index.ts # Type exports
46
- ├── scope.ts # Scope/Actor types
47
- ├── job.ts # Job definition types
48
- │ ├── queue.ts # Queue config types
49
- │ │ ├── events.ts # Event types
50
- │ │ ├── adapter.ts # Adapter interface
51
- │ │ ├── config.ts # Builder state types
52
- │ │ └── worker.ts # Worker types
53
- │ ├── errors/
54
- │ │ ├── index.ts # Error exports
55
- │ │ └── igniter-jobs.error.ts # Error class and codes
56
- │ ├── builders/
57
- │ │ ├── index.ts # Builder exports
58
- │ │ ├── igniter-queue.builder.ts # Queue builder
59
- │ │ ├── igniter-jobs.builder.ts # Jobs builder
60
- │ │ └── igniter-worker.builder.ts # Worker builder
61
- │ ├── core/
62
- │ │ ├── index.ts # Core exports
63
- │ │ └── igniter-jobs.ts # Runtime class
64
- │ └── adapters/
65
- │ ├── index.ts # Adapter exports
66
- │ ├── bullmq.adapter.ts # BullMQ implementation
67
- │ └── memory.adapter.ts # Memory implementation
68
- ├── tests/
69
- │ ├── igniter-queue.builder.test.ts
70
- │ ├── igniter-jobs.builder.test.ts
71
- │ ├── igniter-jobs.runtime.test.ts
72
- │ └── memory.adapter.test.ts
73
- ├── package.json
74
- ├── tsconfig.json
75
- ├── tsup.config.ts
76
- ├── vitest.config.ts
77
- ├── README.md
78
- └── AGENTS.md # This file
79
- ```
17
+ │ ├── adapters/ # Adapter implementations + barrel
18
+ │ ├── builders/ # Fluent builders (jobs, queue, worker)
19
+ │ ├── core/ # Runtime classes & proxies
20
+ │ ├── errors/ # IgniterJobsError hierarchy
21
+ │ ├── types/ # Public type surface (adapter/config/events/queue/worker)
22
+ └── utils/ # Static utility classes (id/prefix helpers)
23
+ ├── AGENTS.md
24
+ # AGENTS.md - @igniter-js/jobs
80
25
 
81
- ### Builder Pattern Flow
26
+ > **Last Updated:** 2025-12-16
27
+ > **Version:** 0.0.1 (bootstrap)
82
28
 
83
- ```
84
- 1. IgniterQueue.create('name')
85
- └─► addJob() / addCron()
86
- └─► build() → IgniterQueueBuiltConfig
87
-
88
- 2. IgniterJobs.create()
89
- └─► withAdapter()
90
- └─► addQueue()
91
- └─► addScope() / addActor()
92
- └─► withDefaults()
93
- └─► build() → IgniterJobsRuntime (with Proxy)
29
+ Operations manual for AI agents maintaining `@igniter-js/jobs`. Read this before changing code.
94
30
 
95
- 3. jobs.queueName.jobName.dispatch(data)
96
- └─► Proxy intercepts access
97
- └─► Returns typed dispatch function
98
- ```
31
+ ## 1. Mission & Scope
99
32
 
100
- ### Proxy-Based API
33
+ `@igniter-js/jobs` provides a fluent, type-safe API for defining queues, jobs, workers, and scheduling. It mirrors `@igniter-js/store` and `@igniter-js/telemetry` patterns, wraps adapters (BullMQ primary, memory for tests), and emits typed telemetry for observability. Scope includes: builders, runtime, adapters, telemetry glue, and docs/tests for everything public.
101
34
 
102
- The runtime uses JavaScript Proxy to provide type-safe access:
35
+ ## 2. Directory Map & Responsibilities
103
36
 
104
- ```typescript
105
- // How it works internally:
106
- jobs.email.sendWelcome.dispatch(data)
107
- │ │ │
108
- │ │ └── Job proxy with dispatch/schedule methods
109
- │ └── Queue proxy returning job proxies
110
- └── Root proxy returning queue proxies
111
37
  ```
112
-
113
- ---
114
-
115
- ## 3. Key Components
116
-
117
- ### 3.1 IgniterQueue Builder
118
-
119
- **Location:** `src/builders/igniter-queue.builder.ts`
120
-
121
- **Purpose:** Define queue configuration with type-safe job definitions.
122
-
123
- **Key Methods:**
124
- - `create(name, options?)` - Initialize builder
125
- - `addJob(name, config)` - Add job with schema and handler
126
- - `addCron(name, config)` - Add cron job
127
- - `build()` - Return frozen config
128
-
129
- **Type Flow:**
130
- ```typescript
131
- IgniterQueue.create('email')
132
- .addJob('send', { schema, handler })
133
- // Jobs type accumulates: { send: {...} }
134
- .build()
135
- // Returns: IgniterQueueBuiltConfig<'email', Jobs>
136
- ```
137
-
138
- ### 3.2 IgniterJobs Builder
139
-
140
- **Location:** `src/builders/igniter-jobs.builder.ts`
141
-
142
- **Purpose:** Create jobs runtime with adapter, context, and queues.
143
-
144
- **Key Methods:**
145
- - `create<Context>()` - Initialize with context type
146
- - `withAdapter(adapter)` - Set queue adapter (required)
147
- - `withContext(factory)` - Set context factory for handlers
148
- - `addQueue(queue)` - Add queue configuration
149
- - `addScope(name, config)` - Define scope type
150
- - `addActor(name, config)` - Define actor type
151
- - `withTelemetry(adapter)` - Enable tracing
152
- - `withDefaults(options)` - Default job options
153
- - `build()` - Return runtime instance
154
-
155
- ### 3.3 IgniterJobs Runtime
156
-
157
- **Location:** `src/core/igniter-jobs.ts`
158
-
159
- **Purpose:** Main runtime class with proxy-based access.
160
-
161
- **Key Properties:**
162
- - `[queueName]` - Queue proxy (via Proxy)
163
- - `job` - Job management methods
164
- - `queue` - Queue management methods
165
- - `subscribe` - Event subscription
166
- - `search` - Search methods
167
- - `worker` - Worker builder access
168
- - `shutdown()` - Graceful shutdown
169
-
170
- ### 3.4 Adapters
171
-
172
- **BullMQ Adapter:** `src/adapters/bullmq.adapter.ts`
173
- - Production-ready with Redis
174
- - Supports all BullMQ features
175
- - Lazy loads BullMQ module
176
-
177
- **Memory Adapter:** `src/adapters/memory.adapter.ts`
178
- - For testing/development
179
- - No external dependencies
180
- - Simulates job processing
181
-
182
- ---
183
-
184
- ## 4. Type System
185
-
186
- ### Core Type Hierarchy
187
-
188
- ```typescript
189
- // Job Definition (queue level)
190
- interface IgniterJobDefinition<TData, TResult, TContext> {
191
- schema: ZodSchema<TData>
192
- handler: IgniterJobHandler<TData, TResult, TContext>
193
- options?: IgniterJobOptions
194
- }
195
-
196
- // Handler Context (passed to handler)
197
- interface IgniterJobHandlerContext<TData, TContext> {
198
- data: TData
199
- context: TContext
200
- job: { id: string; name: string; queue: string; attempt: number }
201
- log: (level, message) => Promise<void>
202
- updateProgress: (progress) => Promise<void>
203
- scope?: IgniterJobScopeEntry
204
- actor?: IgniterJobActorEntry
205
- }
206
-
207
- // Dispatch Options
208
- interface DispatchOptions {
209
- delay?: number
210
- priority?: number
211
- attempts?: number
212
- backoff?: IgniterJobBackoff
213
- jobId?: string
214
- scope?: { type: string; id: string }
215
- actor?: { type: string; id: string }
216
- }
217
- ```
218
-
219
- ### Type Inference Chain
220
-
221
- ```typescript
222
- // 1. Define schema
223
- const schema = z.object({ email: z.string() })
224
- // Type: z.ZodObject<{ email: z.ZodString }>
225
-
226
- // 2. Schema infers handler data type
227
- handler: async ({ data }) => { ... }
228
- // data type: { email: string }
229
-
230
- // 3. Queue builder accumulates job types
231
- .addJob('sendWelcome', { schema, handler })
232
- // Jobs type: { sendWelcome: { data: { email: string } } }
233
-
234
- // 4. Runtime proxy provides typed dispatch
235
- jobs.email.sendWelcome.dispatch({ email: 'x' })
236
- // Argument type: { email: string }
237
- ```
238
-
239
- ---
240
-
241
- ## 5. Error Handling
242
-
243
- ### Error Codes
244
-
245
- **Configuration Errors:**
246
- - `JOBS_MISSING_ADAPTER` - No adapter provided
247
- - `JOBS_INVALID_QUEUE_NAME` - Invalid queue name
248
- - `JOBS_INVALID_JOB_NAME` - Invalid job name
249
- - `JOBS_DUPLICATE_QUEUE` - Queue already registered
250
- - `JOBS_DUPLICATE_JOB` - Job already registered
251
-
252
- **Queue Errors:**
253
- - `JOBS_QUEUE_NOT_FOUND` - Queue doesn't exist
254
- - `JOBS_QUEUE_PAUSED` - Queue is paused
255
- - `JOBS_QUEUE_FAILED_TO_PAUSE` - Pause operation failed
256
-
257
- **Job Errors:**
258
- - `JOBS_JOB_NOT_FOUND` - Job doesn't exist
259
- - `JOBS_JOB_VALIDATION_FAILED` - Payload validation failed
260
- - `JOBS_JOB_HANDLER_FAILED` - Handler threw error
261
- - `JOBS_JOB_TIMEOUT` - Job exceeded timeout
262
-
263
- **Dispatch Errors:**
264
- - `JOBS_DISPATCH_FAILED` - Dispatch operation failed
265
- - `JOBS_SCHEDULE_FAILED` - Schedule operation failed
266
- - `JOBS_INVALID_DISPATCH_PAYLOAD` - Invalid payload
267
-
268
- ### Error Class
269
-
270
- ```typescript
271
- throw new IgniterJobsError({
272
- code: 'JOBS_JOB_NOT_FOUND',
273
- message: `Job "${jobId}" not found in queue "${queue}"`,
274
- statusCode: 404,
275
- details: { jobId, queue },
276
- })
277
- ```
278
-
279
- ---
280
-
281
- ## 6. Development Guidelines
282
-
283
- ### Adding New Features
284
-
285
- 1. **Add Types First**
286
- - Define in appropriate `src/types/*.ts` file
287
- - Export from `src/types/index.ts`
288
- - Export from `src/index.ts` if public
289
-
290
- 2. **Update Builders**
291
- - Add method to builder class
292
- - Update state type if needed
293
- - Maintain fluent return type
294
-
295
- 3. **Update Runtime**
296
- - Implement in `src/core/igniter-jobs.ts`
297
- - Add proxy handling if needed
298
-
299
- 4. **Update Adapter Interface**
300
- - Add method to `IgniterJobsAdapter`
301
- - Implement in BullMQ adapter
302
- - Implement in Memory adapter
303
-
304
- 5. **Add Tests**
305
- - Unit test for builder method
306
- - Integration test for runtime
307
- - Adapter test for implementation
308
-
309
- ### Testing Strategy
310
-
311
- ```bash
312
- # Run all tests
313
- npm test
314
-
315
- # Watch mode
316
- npm run test:watch
317
-
318
- # Coverage
319
- npm run test:coverage
320
- ```
321
-
322
- **Test Files:**
323
- - `tests/igniter-queue.builder.test.ts` - Queue builder
324
- - `tests/igniter-jobs.builder.test.ts` - Jobs builder
325
- - `tests/igniter-jobs.runtime.test.ts` - Integration
326
- - `tests/memory.adapter.test.ts` - Memory adapter
327
-
328
- ### Code Style
329
-
330
- - Use JSDoc for all public APIs
331
- - Follow existing patterns exactly
332
- - No `any` types in public API
333
- - Export types explicitly
334
- - Use `readonly` where appropriate
335
-
336
- ---
337
-
338
- ## 7. Adapter Implementation Guide
339
-
340
- ### Required Methods
341
-
342
- When implementing a new adapter, implement ALL methods from `IgniterJobsAdapter`:
343
-
344
- ```typescript
345
- interface IgniterJobsAdapter {
346
- // Connection
347
- readonly client: unknown
348
-
349
- // Job Operations
350
- dispatch(params: AdapterDispatchParams): Promise<string>
351
- schedule(params: AdapterScheduleParams): Promise<string>
352
- getJob(queue: string, jobId: string): Promise<IgniterJobInfo | null>
353
- getJobState(queue: string, jobId: string): Promise<IgniterJobStatus | null>
354
- getJobProgress(queue: string, jobId: string): Promise<number>
355
- getJobLogs(queue: string, jobId: string): Promise<IgniterJobLog[]>
356
- retryJob(queue: string, jobId: string): Promise<void>
357
- removeJob(queue: string, jobId: string): Promise<void>
358
- promoteJob(queue: string, jobId: string): Promise<void>
359
- moveJob(queue: string, jobId: string, state: string, reason?: string): Promise<void>
360
- retryJobs(queue: string, jobIds: string[]): Promise<void>
361
- removeJobs(queue: string, jobIds: string[]): Promise<void>
362
-
363
- // Queue Operations
364
- getQueue(queue: string): Promise<IgniterQueueInfo>
365
- pauseQueue(queue: string): Promise<void>
366
- resumeQueue(queue: string): Promise<void>
367
- drainQueue(queue: string): Promise<number>
368
- cleanQueue(queue: string, options: IgniterQueueCleanOptions): Promise<number>
369
- obliterateQueue(queue: string, options?: { force?: boolean }): Promise<void>
370
- retryAllFailed(queue: string): Promise<number>
371
- getJobCounts(queue: string): Promise<IgniterJobCounts>
372
- listJobs(queue: string, options?: {...}): Promise<IgniterJobSearchResult[]>
373
- pauseJobType(queue: string, jobName: string): Promise<void>
374
- resumeJobType(queue: string, jobName: string): Promise<void>
375
-
376
- // Events
377
- subscribe(pattern: string, handler: IgniterJobEventHandler): Promise<IgniterJobUnsubscribeFn>
378
-
379
- // Workers
380
- createWorker(config: AdapterWorkerConfig, handler: AdapterJobHandler): Promise<AdapterWorkerHandle>
381
-
382
- // Search
383
- searchJobs(filter: {...}): Promise<IgniterJobSearchResult[]>
384
- searchQueues(filter: {...}): Promise<IgniterQueueInfo[]>
385
-
386
- // Lifecycle
387
- shutdown(): Promise<void>
388
- }
389
- ```
390
-
391
- ---
392
-
393
- ## 8. Common Patterns
394
-
395
- ### Multi-tenant Job Dispatch
396
-
397
- ```typescript
398
- const jobs = IgniterJobs.create()
399
- .withAdapter(adapter)
400
- .addQueue(emailQueue)
401
- .addScope('organization', {
402
- resolver: (id) => db.org.findUnique({ where: { id } }),
403
- })
404
- .addActor('user', {
405
- resolver: (id) => db.user.findUnique({ where: { id } }),
406
- })
407
- .build()
408
-
409
- // Dispatch with scope/actor
410
- await jobs.email.sendWelcome.dispatch(
411
- { email: 'test@example.com' },
412
- {
413
- scope: { type: 'organization', id: 'org-123' },
414
- actor: { type: 'user', id: 'user-456' },
415
- }
416
- )
417
- ```
418
-
419
- ### Job With Progress Updates
420
-
421
- ```typescript
422
- const queue = IgniterQueue.create('exports')
423
- .addJob('generateReport', {
424
- schema: z.object({ reportId: z.string() }),
425
- handler: async ({ data, updateProgress, log }) => {
426
- await updateProgress(10)
427
- await log('info', 'Starting report generation')
428
-
429
- // ... process
430
-
431
- await updateProgress(50)
432
- await log('info', 'Halfway done')
433
-
434
- // ... finish
435
-
436
- await updateProgress(100)
437
- return { success: true }
438
- },
439
- })
440
- .build()
441
- ```
442
-
443
- ### Scheduled Jobs
444
-
445
- ```typescript
446
- // Schedule at specific time
447
- await jobs.email.sendWelcome.schedule({
448
- data: { email: 'test@example.com' },
449
- at: new Date('2025-12-25T00:00:00Z'),
450
- })
451
-
452
- // Schedule with delay
453
- await jobs.email.sendWelcome.schedule({
454
- data: { email: 'test@example.com' },
455
- delay: 60000, // 1 minute
456
- })
457
- ```
458
-
459
- ### Worker with Rate Limiting
460
-
461
- ```typescript
462
- const worker = await jobs.worker
463
- .forQueues(['email'])
464
- .withConcurrency(10)
465
- .withLimiter({
466
- max: 100, // max jobs
467
- duration: 60000, // per minute
468
- })
469
- .withLockDuration(30000)
470
- .onIdle(() => console.log('No jobs to process'))
471
- .start()
472
- ```
473
-
474
- ---
475
-
476
- ## 9. Version History
477
-
478
- ### 0.1.0 (Initial Release)
479
-
480
- - ✅ IgniterQueue builder with addJob/addCron
481
- - ✅ IgniterJobs builder with full configuration
482
- - ✅ IgniterWorker builder with fluent API
483
- - ✅ Proxy-based runtime for type-safe access
484
- - ✅ BullMQ adapter with full feature support
485
- - ✅ Memory adapter for testing
486
- - ✅ Scope and actor support
487
- - ✅ Event subscription system
488
- - ✅ Job and queue search
489
- - ✅ Error codes and classes
490
-
491
- ---
492
-
493
- ## 10. Troubleshooting
494
-
495
- ### Common Issues
496
-
497
- **"JOBS_MISSING_ADAPTER"**
498
- - Ensure `withAdapter()` is called before `build()`
499
- - Check adapter is properly instantiated
500
-
501
- **"JOBS_QUEUE_NOT_FOUND"**
502
- - Queue must be registered with `addQueue()`
503
- - Check queue name spelling
504
-
505
- **"JOBS_JOB_VALIDATION_FAILED"**
506
- - Payload doesn't match Zod schema
507
- - Check `details.issues` for validation errors
508
-
509
- **TypeScript errors on dispatch**
510
- - Ensure queue is added before build
511
- - Check job name exists in queue
512
- - Verify payload matches schema
513
-
514
- ### Debug Tips
515
-
516
- ```typescript
517
- // Enable BullMQ debug logging
518
- process.env.DEBUG = 'bullmq:*'
519
-
520
- // Check job state
521
- const state = await jobs.job.state('queue', 'job-id')
522
- console.log('Job state:', state)
523
-
524
- // Get job logs
525
- const logs = await jobs.job.logs('queue', 'job-id')
526
- console.log('Job logs:', logs)
527
-
528
- // Subscribe to all events
529
- await jobs.subscribe('*', (event) => {
530
- console.log('Event:', event.type, event.data)
531
- })
532
- ```
533
-
534
- ---
535
-
536
- ## 11. Dependencies
537
-
538
- ### Peer Dependencies
539
-
540
- | Package | Version | Purpose |
541
- |---------|---------|---------|
542
- | `bullmq` | `^5.0.0` | Job queue implementation |
543
- | `ioredis` | `^5.0.0` | Redis client |
544
- | `zod` | `^3.0.0` | Schema validation |
545
- | `@igniter-js/telemetry` | `^0.1.0` | Optional tracing |
546
-
547
- ### Dev Dependencies
548
-
549
- | Package | Version | Purpose |
550
- |---------|---------|---------|
551
- | `typescript` | `^5.0.0` | TypeScript compiler |
552
- | `vitest` | `^1.0.0` | Testing framework |
553
- | `tsup` | `^8.0.0` | Build tool |
554
-
555
- ---
556
-
557
- **Remember:** Always follow existing patterns. When in doubt, check how similar features are implemented in `@igniter-js/store` or `@igniter-js/core`.
38
+ packages/jobs/
39
+ ├── src/
40
+ │ ├── adapters/ # Adapter impls + barrel (bullmq, memory); capability parity with @igniter-js/adapter-bullmq
41
+ │ ├── builders/ # Fluent builders: queue, worker, job, cron definitions
42
+ │ ├── core/ # Runtime classes (queue runtime, worker runtime, proxies)
43
+ │ ├── errors/ # IgniterJobsError hierarchy
44
+ │ ├── telemetry/ # Event descriptors + emit helpers (if present)
45
+ │ ├── types/ # Public surface (config, adapter contracts, events, queue/worker types)
46
+ │ └── utils/ # Static helpers (ids, prefixes, validation)
47
+ ├── AGENTS.md # You are here
48
+ ├── CHANGELOG.md # Release notes
49
+ ├── README.md # User-facing docs
50
+ ├── package.json # Package metadata
51
+ ├── tsconfig.json # TS build config
52
+ ├── tsup.config.ts # Build outputs
53
+ └── vitest.config.ts # Test config
54
+ ```
55
+
56
+ ## 3. Architecture Overview
57
+
58
+ - **Builders (immutable):** `.create()` → chain setters → `.build()`. Must copy state, never mutate in-place. Maintain type accumulation for scopes/options like `@igniter-js/store`.
59
+ - **Runtime flow (happy path):**
60
+ 1) User defines queue/worker via builders.
61
+ 2) Adapter (BullMQ) wires queues/workers; memory adapter is for tests.
62
+ 3) Job enqueue → adapter schedules → worker consumes → lifecycle events emit (internal + telemetry).
63
+ 4) Errors bubble as `IgniterJobsError` with codes; runtime logs/telemetry should not crash workers.
64
+ - **Telemetry:** Optional peer; events emitted via lightweight helper (fire-and-forget). Event names `igniter.jobs.<group>.<event>`; attributes prefixed with `ctx.`. No actors; single scope (e.g., queue/workspace) only.
65
+ - **Scheduling:** `queue.addCron()` produces repeatable jobs; advanced scheduling metadata (skip weekends/business hours) attaches via `metadata.advancedScheduling`. BullMQ repeat options must be preserved.
66
+
67
+ ## 4. Design Rules (must-keep)
68
+
69
+ - **Prefixing:** Public classes/types start with `IgniterJobs` (singular `IgniterJob` when appropriate). Utils are static classes.
70
+ - **Type Safety:** No implicit `any` on public API. Use `Prettify` helpers for flattened types. Align with `packages/core/src/types/jobs.interface.ts` and keep parity.
71
+ - **Adapters:** `IgniterJobsAdapter` defines capabilities. BullMQ adapter must keep: rate limiting, scheduling (cron/repeat), retries/backoff, job metadata, progress, bulk ops, management APIs (pause/resume/drain/clean/obliterate), hooks/callbacks. Memory adapter is test-only.
72
+ - **Docs:** TSDoc (English) with examples/edge cases for every exported symbol. Keep README + AGENTS + CHANGELOG in sync with behavior.
73
+ - **Utils:** Keep shared helpers in `src/utils`; add tests. Prefer pure functions or static classes.
74
+ - **Telemetry:** Optional dependency; interface lives in types to avoid hard dependency. Telemetry errors must never fail job execution.
75
+
76
+ ## 5. Component Map (what to touch)
77
+
78
+ - **src/builders/**: Queue builder, worker builder, job definition builder. Ensure immutability and type accumulation. Provide `.withTelemetry()`, `.withAdapter()`, and scheduling helpers.
79
+ - **src/core/**: Runtime wrappers that orchestrate builders + adapters. Handles lifecycle hooks, logging/telemetry, error translation.
80
+ - **src/adapters/**: Adapter implementations + barrel. BullMQ mirrors `@igniter-js/adapter-bullmq`; memory adapter minimal but API-compatible for tests.
81
+ - **src/errors/**: `IgniterJobsError` codes. Add new codes here first; keep messages actionable.
82
+ - **src/telemetry/**: Event descriptors + emit helpers. Keep names stable and attributes prefixed `ctx.`.
83
+ - **src/types/**: Single source of truth for public API (config, events, adapters, queue/worker types). Update before implementation.
84
+ - **src/utils/**: ID generation, prefix handling, validation, backoff helpers. Pure and tested.
85
+
86
+ ## 6. Telemetry Events (contract)
87
+
88
+ - **Namespace:** `igniter.jobs`.
89
+ - **Job events:** `enqueued`, `scheduled`, `started`, `completed`, `failed`, `progress`, `retrying`.
90
+ - **Worker events:** `started`, `stopped`, `idle`, `paused`, `resumed`.
91
+ - **Queue events:** `paused`, `resumed`, `drained`, `cleaned`, `obliterated`.
92
+ - **Attributes:** always include `ctx.job.id`, `ctx.job.queue`, plus duration/progress where applicable. Add `ctx.worker.id` for worker lifecycle.
93
+ - **Behavior:** Emission is best-effort; never throw. Keep helper tolerant (swallow telemetry errors, log if logger available).
94
+
95
+ ## 7. Testing Strategy
96
+
97
+ - `npm test --filter @igniter-js/jobs`
98
+ - `bun test` (if bun is configured in scripts)
99
+ - `npx tsc --noEmit` for types
100
+
101
+ ## 8. Build & Tooling
102
+
103
+ - **Build:** `bun run build` or `npm run build --filter @igniter-js/jobs` (tsup). Outputs ESM + CJS with dts.
104
+ - **Config:** `tsconfig.json` extends shared base; `tsup.config.ts` declares multiple entries if needed; keep barrels aligned.
105
+ - **External deps:** BullMQ/Redis via adapter; avoid pulling heavy deps into core runtime. Telemetry is optional peer.
106
+
107
+ ## 9. Workflow Checklist (per change)
108
+
109
+ 1. Read this AGENTS + `README.md` + relevant code before editing.
110
+ 2. Update types (public surface) first; then implementation; then tests.
111
+ 3. Preserve BullMQ feature parity; log any intentional deltas in CHANGELOG.
112
+ 4. Keep telemetry names/attributes stable; update descriptors + tests if changed.
113
+ 5. Add/adjust TSDoc for every exported symbol and public function.
114
+ 6. Run tests and typecheck (`npm test --filter @igniter-js/jobs`, `npx tsc --noEmit`).
115
+ 7. Update README + AGENTS + CHANGELOG when behavior or API changes.
116
+
117
+ ## 10. Troubleshooting Notes
118
+
119
+ - **Telemetry failures:** Should be swallowed; if tests fail, ensure helper mocks errors without throwing.
120
+ - **Cron/repeat drift:** Verify repeat options passed untouched to BullMQ; advanced scheduling metadata must survive serialization.
121
+ - **Type regressions:** Compare against `packages/core/src/types/jobs.interface.ts`. No `any` leakage in public exports.
122
+ - **Adapter parity gaps:** Cross-check with `packages/adapter-bullmq/src/bullmq.adapter.ts` for missing capabilities.
123
+ - **Flaky integration tests:** Prefer Redis-mock/stub; isolate time-based tests with fake timers.
124
+
125
+ ## 11. References
126
+
127
+ - `packages/core/src/types/jobs.interface.ts` canonical job interfaces.
128
+ - `packages/adapter-bullmq/src/bullmq.adapter.ts` legacy feature set to mirror.
129
+ - `packages/store`, `packages/telemetry` — builder/test patterns and redaction/sampling ideas.
130
+
131
+ Stay consistent, type-safe, and keep docs/tests in lockstep with the code.
package/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ # Changelog - @igniter-js/jobs
2
+
3
+ ## Unreleased
4
+
5
+ - Bootstrap package scaffolding and initial structure for builders, adapters, and types.