@m16khb/nestjs-sidequest 0.1.0

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.
@@ -0,0 +1,900 @@
1
+ import { ModuleMetadata, InjectionToken, OptionalFactoryDependency, Type, DynamicModule, OnModuleInit, OnModuleDestroy } from '@nestjs/common';
2
+ import { Job } from 'sidequest';
3
+ export { Job } from 'sidequest';
4
+
5
+ /**
6
+ * 데이터베이스 백엔드 설정
7
+ */
8
+ interface BackendConfig {
9
+ /**
10
+ * 백엔드 드라이버
11
+ * @example '@sidequest/postgres-backend', '@sidequest/mysql-backend', '@sidequest/sqlite-backend', '@sidequest/mongo-backend'
12
+ */
13
+ driver: string;
14
+ /**
15
+ * 연결 설정 (연결 문자열 또는 설정 객체)
16
+ * @example 'postgresql://user:pass@localhost:5432/db'
17
+ */
18
+ config: string | Record<string, unknown>;
19
+ }
20
+ /**
21
+ * 큐 설정
22
+ */
23
+ interface QueueConfig {
24
+ /** 큐 이름 */
25
+ name: string;
26
+ /** 동시 처리 작업 수 (기본값: 10) */
27
+ concurrency?: number;
28
+ /** 우선순위 (높을수록 먼저 처리, 기본값: 50) */
29
+ priority?: number;
30
+ /** 초기 상태 */
31
+ state?: 'active' | 'paused';
32
+ }
33
+ /**
34
+ * 대시보드 설정
35
+ */
36
+ interface DashboardConfig {
37
+ /** 활성화 여부 (기본값: false) */
38
+ enabled?: boolean;
39
+ /** 포트 (기본값: 8678) */
40
+ port?: number;
41
+ /** 경로 (기본값: '/') */
42
+ path?: string;
43
+ /** 기본 인증 */
44
+ auth?: {
45
+ user: string;
46
+ password: string;
47
+ };
48
+ }
49
+ /**
50
+ * 로거 설정
51
+ */
52
+ interface LoggerConfig {
53
+ /** 로그 레벨 */
54
+ level?: 'debug' | 'info' | 'warn' | 'error';
55
+ /** JSON 형식 출력 여부 */
56
+ json?: boolean;
57
+ }
58
+ /**
59
+ * Graceful Shutdown 설정
60
+ */
61
+ interface GracefulShutdownConfig {
62
+ /** 활성화 여부 (기본값: true) */
63
+ enabled?: boolean;
64
+ /** 타임아웃 (ms, 기본값: 30000) */
65
+ timeout?: number;
66
+ }
67
+ /**
68
+ * SidequestModule 옵션
69
+ */
70
+ interface SidequestModuleOptions {
71
+ /**
72
+ * 전역 모듈 여부 (기본값: true)
73
+ */
74
+ isGlobal?: boolean;
75
+ /**
76
+ * 데이터베이스 백엔드 설정
77
+ */
78
+ backend: BackendConfig;
79
+ /**
80
+ * 큐 설정 목록
81
+ */
82
+ queues?: QueueConfig[];
83
+ /**
84
+ * 최대 동시 작업 수 (전체, 기본값: 10)
85
+ */
86
+ maxConcurrentJobs?: number;
87
+ /**
88
+ * 최소 워커 스레드 수 (기본값: CPU 코어 수)
89
+ */
90
+ minThreads?: number;
91
+ /**
92
+ * 최대 워커 스레드 수 (기본값: minThreads * 2)
93
+ */
94
+ maxThreads?: number;
95
+ /**
96
+ * Job 폴링 간격 (ms, 기본값: 100)
97
+ */
98
+ jobPollingInterval?: number;
99
+ /**
100
+ * 오래된 Job 해제 간격 (분, 기본값: 60)
101
+ */
102
+ releaseStaleJobsIntervalMin?: number;
103
+ /**
104
+ * 완료된 Job 정리 간격 (분, 기본값: 60)
105
+ */
106
+ cleanupFinishedJobsIntervalMin?: number;
107
+ /**
108
+ * 로거 설정
109
+ */
110
+ logger?: LoggerConfig;
111
+ /**
112
+ * 대시보드 설정
113
+ */
114
+ dashboard?: DashboardConfig;
115
+ /**
116
+ * Graceful Shutdown 설정
117
+ */
118
+ gracefulShutdown?: GracefulShutdownConfig;
119
+ /**
120
+ * CLS(Continuation Local Storage) 통합 활성화 (기본값: false)
121
+ * nestjs-cls가 설치되어 있어야 함
122
+ */
123
+ enableCls?: boolean;
124
+ }
125
+ /**
126
+ * SidequestModule 비동기 옵션
127
+ */
128
+ interface SidequestModuleAsyncOptions extends Pick<ModuleMetadata, 'imports'> {
129
+ /**
130
+ * 전역 모듈 여부 (기본값: true)
131
+ */
132
+ isGlobal?: boolean;
133
+ /**
134
+ * 팩토리 함수
135
+ */
136
+ useFactory?: (...args: unknown[]) => Promise<SidequestModuleOptions> | SidequestModuleOptions;
137
+ /**
138
+ * 주입할 프로바이더
139
+ */
140
+ inject?: (InjectionToken | OptionalFactoryDependency)[];
141
+ /**
142
+ * 옵션 팩토리 클래스
143
+ */
144
+ useClass?: Type<SidequestOptionsFactory>;
145
+ /**
146
+ * 기존 옵션 팩토리 사용
147
+ */
148
+ useExisting?: Type<SidequestOptionsFactory>;
149
+ }
150
+ /**
151
+ * SidequestModule 옵션 팩토리 인터페이스
152
+ */
153
+ interface SidequestOptionsFactory {
154
+ createSidequestOptions(): Promise<SidequestModuleOptions> | SidequestModuleOptions;
155
+ }
156
+
157
+ /**
158
+ * SidequestModule
159
+ *
160
+ * NestJS에서 Sidequest.js를 사용하기 위한 메인 모듈입니다.
161
+ *
162
+ * @example
163
+ * ```typescript
164
+ * // 동기 설정
165
+ * @Module({
166
+ * imports: [
167
+ * SidequestModule.forRoot({
168
+ * backend: {
169
+ * driver: '@sidequest/postgres-backend',
170
+ * config: process.env.DATABASE_URL,
171
+ * },
172
+ * queues: [
173
+ * { name: 'email', concurrency: 5 },
174
+ * { name: 'report', concurrency: 2 },
175
+ * ],
176
+ * }),
177
+ * ],
178
+ * })
179
+ * export class AppModule {}
180
+ *
181
+ * // 비동기 설정 (ConfigService 사용)
182
+ * @Module({
183
+ * imports: [
184
+ * SidequestModule.forRootAsync({
185
+ * imports: [ConfigModule],
186
+ * useFactory: (config: ConfigService) => ({
187
+ * backend: {
188
+ * driver: '@sidequest/postgres-backend',
189
+ * config: config.get('DATABASE_URL'),
190
+ * },
191
+ * queues: [{ name: 'default' }],
192
+ * }),
193
+ * inject: [ConfigService],
194
+ * }),
195
+ * ],
196
+ * })
197
+ * export class AppModule {}
198
+ * ```
199
+ */
200
+ declare class SidequestModule {
201
+ /**
202
+ * 동기 설정으로 모듈 등록
203
+ */
204
+ static forRoot(options: SidequestModuleOptions): DynamicModule;
205
+ /**
206
+ * 비동기 설정으로 모듈 등록
207
+ */
208
+ static forRootAsync(asyncOptions: SidequestModuleAsyncOptions): DynamicModule;
209
+ /**
210
+ * 큐별 DI 프로바이더 생성
211
+ */
212
+ private static createQueueProviders;
213
+ /**
214
+ * 비동기 프로바이더 생성
215
+ */
216
+ private static createAsyncProviders;
217
+ }
218
+
219
+ /**
220
+ * @Processor 데코레이터 옵션
221
+ */
222
+ interface ProcessorOptions {
223
+ /**
224
+ * 동시 처리 작업 수 (큐 설정 오버라이드)
225
+ */
226
+ concurrency?: number;
227
+ }
228
+ /**
229
+ * 프로세서 메타데이터
230
+ */
231
+ interface ProcessorMetadata {
232
+ /** 큐 이름 */
233
+ queueName: string;
234
+ /** 프로세서 옵션 */
235
+ options?: ProcessorOptions;
236
+ }
237
+ /**
238
+ * @OnJob 데코레이터 옵션
239
+ */
240
+ interface OnJobOptions {
241
+ /**
242
+ * Job 우선순위 (높을수록 먼저 처리)
243
+ */
244
+ priority?: number;
245
+ /**
246
+ * 최대 실행 시간 (ms)
247
+ */
248
+ timeout?: number;
249
+ }
250
+ /**
251
+ * OnJob 핸들러 메타데이터
252
+ */
253
+ interface OnJobMetadata {
254
+ /** Job 이름 */
255
+ jobName: string;
256
+ /** Job 옵션 */
257
+ options?: OnJobOptions;
258
+ }
259
+ /**
260
+ * 등록된 핸들러 정보
261
+ */
262
+ interface RegisteredHandler {
263
+ /** 메서드 이름 */
264
+ methodName: string;
265
+ /** Job 이름 */
266
+ jobName: string;
267
+ /** Job 옵션 */
268
+ options?: OnJobOptions;
269
+ /** 재시도 옵션 */
270
+ retryOptions?: RetryOptions;
271
+ }
272
+ /**
273
+ * 재시도 옵션
274
+ */
275
+ interface RetryOptions {
276
+ /**
277
+ * 최대 시도 횟수 (기본값: 3)
278
+ */
279
+ maxAttempts?: number;
280
+ /**
281
+ * 재시도 지연 시간 (ms, 기본값: 1000)
282
+ */
283
+ delay?: number;
284
+ /**
285
+ * 백오프 전략 (기본값: 'exponential')
286
+ */
287
+ backoff?: 'fixed' | 'exponential';
288
+ }
289
+ /**
290
+ * 등록된 프로세서 정보
291
+ */
292
+ interface RegisteredProcessor {
293
+ /** 큐 이름 */
294
+ queueName: string;
295
+ /** 프로세서 인스턴스 */
296
+ instance: unknown;
297
+ /** 프로세서 클래스 */
298
+ metatype: Function;
299
+ /** 등록된 핸들러 맵 (jobName -> handler) */
300
+ handlers: Map<string, RegisteredHandler>;
301
+ /** 완료 이벤트 핸들러 맵 (jobName -> methodName) */
302
+ completeHandlers: Map<string, string>;
303
+ /** 실패 이벤트 핸들러 맵 (jobName -> methodName) */
304
+ failedHandlers: Map<string, string>;
305
+ }
306
+
307
+ /**
308
+ * 클래스를 Sidequest Job Processor로 지정합니다.
309
+ *
310
+ * @Processor 데코레이터가 붙은 클래스는 모듈 초기화 시 자동으로 스캔되어
311
+ * 해당 큐의 Job 핸들러로 등록됩니다.
312
+ *
313
+ * @param queueName - 처리할 큐 이름
314
+ * @param options - 프로세서 옵션
315
+ *
316
+ * @example
317
+ * ```typescript
318
+ * @Processor('email')
319
+ * export class EmailProcessor {
320
+ * @OnJob('send-welcome-email')
321
+ * async handleWelcomeEmail(job: JobContext) {
322
+ * const { to, subject, body } = job.data;
323
+ * await this.mailer.send({ to, subject, body });
324
+ * }
325
+ * }
326
+ *
327
+ * // 동시성 설정과 함께
328
+ * @Processor('report', { concurrency: 2 })
329
+ * export class ReportProcessor {
330
+ * @OnJob('generate-daily-report')
331
+ * async handleDailyReport(job: JobContext) {
332
+ * // 리포트 생성 로직
333
+ * }
334
+ * }
335
+ * ```
336
+ */
337
+ declare function Processor(queueName: string, options?: ProcessorOptions): ClassDecorator;
338
+
339
+ /**
340
+ * 메서드를 특정 Job 타입의 핸들러로 지정합니다.
341
+ *
342
+ * @Processor 데코레이터가 붙은 클래스 내부에서 사용합니다.
343
+ * 해당 Job이 큐에서 처리될 때 이 메서드가 호출됩니다.
344
+ *
345
+ * @param jobName - Job 이름 (일반적으로 Job 클래스명)
346
+ * @param options - Job 실행 옵션 (우선순위, 타임아웃 등)
347
+ *
348
+ * @example
349
+ * ```typescript
350
+ * @Processor('email')
351
+ * export class EmailProcessor {
352
+ * @OnJob('SendWelcomeEmailJob')
353
+ * async handleWelcomeEmail(job: JobContext) {
354
+ * const { to, subject, body } = job.data;
355
+ * await this.mailer.send({ to, subject, body });
356
+ * }
357
+ *
358
+ * // 우선순위와 타임아웃 설정
359
+ * @OnJob('SendPriorityEmailJob', { priority: 100, timeout: 5000 })
360
+ * async handlePriorityEmail(job: JobContext) {
361
+ * // 우선순위가 높은 이메일 처리
362
+ * }
363
+ * }
364
+ * ```
365
+ */
366
+ declare function OnJob(jobName: string, options?: OnJobOptions): MethodDecorator;
367
+
368
+ /**
369
+ * Job 재시도 정책을 설정합니다.
370
+ *
371
+ * @OnJob 데코레이터와 함께 사용하여 Job 실패 시 재시도 동작을 정의합니다.
372
+ *
373
+ * @param options - 재시도 옵션
374
+ *
375
+ * @example
376
+ * ```typescript
377
+ * @Processor('payment')
378
+ * export class PaymentProcessor {
379
+ * // 고정 지연 재시도
380
+ * @OnJob('ProcessPaymentJob')
381
+ * @Retry({ maxAttempts: 3, delay: 1000 })
382
+ * async handlePayment(job: JobContext) {
383
+ * // 결제 처리 로직
384
+ * }
385
+ *
386
+ * // 지수 백오프 재시도
387
+ * @OnJob('RefundJob')
388
+ * @Retry({ maxAttempts: 5, delay: 500, backoff: 'exponential' })
389
+ * async handleRefund(job: JobContext) {
390
+ * // 환불 처리 로직
391
+ * }
392
+ * }
393
+ * ```
394
+ */
395
+ declare function Retry(options: RetryOptions): MethodDecorator;
396
+
397
+ /**
398
+ * Queue 인스턴스를 주입합니다.
399
+ *
400
+ * SidequestModule.forRoot()에서 등록된 큐를 서비스에 주입받아 사용할 수 있습니다.
401
+ *
402
+ * @param queueName - 주입받을 큐 이름
403
+ *
404
+ * @example
405
+ * ```typescript
406
+ * @Injectable()
407
+ * export class UserService {
408
+ * constructor(
409
+ * @InjectQueue('email') private emailQueue: IQueueService,
410
+ * @InjectQueue('notification') private notificationQueue: IQueueService,
411
+ * ) {}
412
+ *
413
+ * async createUser(email: string, name: string) {
414
+ * // 사용자 생성 로직...
415
+ *
416
+ * // 환영 이메일 발송
417
+ * await this.emailQueue.add(SendWelcomeEmailJob, email, `Welcome, ${name}!`);
418
+ *
419
+ * // 알림 발송
420
+ * await this.notificationQueue.add(SendNotificationJob, email, 'new-user');
421
+ * }
422
+ * }
423
+ * ```
424
+ */
425
+ declare function InjectQueue(queueName: string): ParameterDecorator;
426
+
427
+ /**
428
+ * Job 완료 이벤트 핸들러를 지정합니다.
429
+ *
430
+ * @Processor 클래스 내부에서 사용하며, Job이 성공적으로 완료되면 호출됩니다.
431
+ *
432
+ * @param jobName - 대상 Job 이름 (생략 시 모든 Job에 대해 호출)
433
+ *
434
+ * @example
435
+ * ```typescript
436
+ * @Processor('email')
437
+ * export class EmailProcessor {
438
+ * @OnJob('SendWelcomeEmailJob')
439
+ * async handleWelcomeEmail(job: JobContext) {
440
+ * await this.mailer.send(job.data);
441
+ * }
442
+ *
443
+ * // 특정 Job 완료 이벤트
444
+ * @OnJobComplete('SendWelcomeEmailJob')
445
+ * async onWelcomeEmailComplete(event: JobCompleteEvent) {
446
+ * this.logger.log(`환영 이메일 발송 완료: ${event.result}`);
447
+ * await this.analytics.track('email_sent', { type: 'welcome' });
448
+ * }
449
+ *
450
+ * // 모든 Job 완료 이벤트 (jobName 생략)
451
+ * @OnJobComplete()
452
+ * async onAnyJobComplete(event: JobCompleteEvent) {
453
+ * this.logger.log(`Job 완료: ${event.jobName}`);
454
+ * }
455
+ * }
456
+ * ```
457
+ */
458
+ declare function OnJobComplete(jobName?: string): MethodDecorator;
459
+ /**
460
+ * Job 완료 이벤트 데이터
461
+ */
462
+ interface JobCompleteEvent {
463
+ /** Job 이름 */
464
+ jobName: string;
465
+ /** Job 실행 인자 */
466
+ args: unknown[];
467
+ /** Job 실행 결과 */
468
+ result: unknown;
469
+ }
470
+
471
+ /**
472
+ * Job 실패 이벤트 핸들러를 지정합니다.
473
+ *
474
+ * @Processor 클래스 내부에서 사용하며, Job 실행이 실패하면 호출됩니다.
475
+ * 재시도 횟수를 모두 소진한 후 최종 실패 시에만 호출됩니다.
476
+ *
477
+ * @param jobName - 대상 Job 이름 (생략 시 모든 Job에 대해 호출)
478
+ *
479
+ * @example
480
+ * ```typescript
481
+ * @Processor('payment')
482
+ * export class PaymentProcessor {
483
+ * @OnJob('ProcessPaymentJob')
484
+ * @Retry({ maxAttempts: 3 })
485
+ * async handlePayment(job: JobContext) {
486
+ * await this.paymentService.process(job.data);
487
+ * }
488
+ *
489
+ * // 특정 Job 실패 이벤트
490
+ * @OnJobFailed('ProcessPaymentJob')
491
+ * async onPaymentFailed(event: JobFailedEvent) {
492
+ * this.logger.error(`결제 처리 실패: ${event.error.message}`);
493
+ * await this.alertService.notify('payment-failure', {
494
+ * orderId: event.args[0],
495
+ * error: event.error.message,
496
+ * });
497
+ * }
498
+ *
499
+ * // 모든 Job 실패 이벤트 (jobName 생략)
500
+ * @OnJobFailed()
501
+ * async onAnyJobFailed(event: JobFailedEvent) {
502
+ * this.logger.error(`Job 실패: ${event.jobName}`, event.error);
503
+ * }
504
+ * }
505
+ * ```
506
+ */
507
+ declare function OnJobFailed(jobName?: string): MethodDecorator;
508
+ /**
509
+ * Job 실패 이벤트 데이터
510
+ */
511
+ interface JobFailedEvent {
512
+ /** Job 이름 */
513
+ jobName: string;
514
+ /** Job 실행 인자 */
515
+ args: unknown[];
516
+ /** 발생한 에러 */
517
+ error: Error;
518
+ }
519
+
520
+ /**
521
+ * Queue 서비스 인터페이스
522
+ * @InjectQueue()로 주입되는 객체의 타입
523
+ */
524
+ interface IQueueService {
525
+ /** 큐 이름 */
526
+ readonly name: string;
527
+ /**
528
+ * Job 추가
529
+ *
530
+ * @param JobClass - Job 클래스
531
+ * @param args - Job 실행 인자
532
+ * @returns Job ID
533
+ *
534
+ * @example
535
+ * ```typescript
536
+ * await this.emailQueue.add(SendEmailJob, 'user@example.com', 'Welcome!');
537
+ * ```
538
+ */
539
+ add<T>(JobClass: new (...args: unknown[]) => T, ...args: unknown[]): Promise<string>;
540
+ /**
541
+ * Job 추가 (옵션 포함)
542
+ *
543
+ * @param JobClass - Job 클래스
544
+ * @param options - Job 옵션
545
+ * @param args - Job 실행 인자
546
+ * @returns Job ID
547
+ *
548
+ * @example
549
+ * ```typescript
550
+ * await this.emailQueue.addWithOptions(
551
+ * SendEmailJob,
552
+ * { priority: 10, timeout: 5000 },
553
+ * 'user@example.com',
554
+ * 'Welcome!'
555
+ * );
556
+ * ```
557
+ */
558
+ addWithOptions<T>(JobClass: new (...args: unknown[]) => T, options: JobAddOptions, ...args: unknown[]): Promise<string>;
559
+ /**
560
+ * 예약된 Job 추가
561
+ *
562
+ * @param JobClass - Job 클래스
563
+ * @param scheduledAt - 실행 예정 시간
564
+ * @param args - Job 실행 인자
565
+ * @returns Job ID
566
+ *
567
+ * @example
568
+ * ```typescript
569
+ * const tomorrow = new Date();
570
+ * tomorrow.setDate(tomorrow.getDate() + 1);
571
+ * await this.emailQueue.addScheduled(SendEmailJob, tomorrow, 'user@example.com');
572
+ * ```
573
+ */
574
+ addScheduled<T>(JobClass: new (...args: unknown[]) => T, scheduledAt: Date, ...args: unknown[]): Promise<string>;
575
+ /**
576
+ * Bulk Job 추가
577
+ *
578
+ * @param jobs - Job 목록
579
+ * @returns Job ID 배열
580
+ */
581
+ addBulk<T>(jobs: Array<{
582
+ JobClass: new (...args: unknown[]) => T;
583
+ args: unknown[];
584
+ options?: JobAddOptions;
585
+ }>): Promise<string[]>;
586
+ }
587
+ /**
588
+ * Job 추가 옵션
589
+ */
590
+ interface JobAddOptions {
591
+ /**
592
+ * 우선순위 (높을수록 먼저 처리)
593
+ */
594
+ priority?: number;
595
+ /**
596
+ * 최대 실행 시간 (ms)
597
+ */
598
+ timeout?: number;
599
+ /**
600
+ * 최대 시도 횟수
601
+ */
602
+ maxAttempts?: number;
603
+ /**
604
+ * 재시도 간격 (ms, 기본값: 1000)
605
+ */
606
+ retryDelay?: number;
607
+ /**
608
+ * 백오프 전략
609
+ */
610
+ backoffStrategy?: 'fixed' | 'exponential';
611
+ /**
612
+ * 고유성 키 (중복 방지)
613
+ */
614
+ uniqueKey?: string;
615
+ /**
616
+ * 예약 실행 시간
617
+ */
618
+ scheduledAt?: Date;
619
+ /**
620
+ * 메타데이터 (traceId 등)
621
+ */
622
+ metadata?: Record<string, unknown>;
623
+ }
624
+ /**
625
+ * 에러 데이터
626
+ */
627
+ interface ErrorData {
628
+ /** 에러 이름 */
629
+ name?: string | null;
630
+ /** 에러 메시지 */
631
+ message?: string | null;
632
+ /** 스택 트레이스 */
633
+ stack?: string | null;
634
+ /** 추가 데이터 */
635
+ [key: string]: unknown;
636
+ }
637
+ /**
638
+ * Job 정보
639
+ */
640
+ interface JobInfo {
641
+ /** Job ID */
642
+ id: string;
643
+ /** 큐 이름 */
644
+ queue: string;
645
+ /** Job 이름 */
646
+ name?: string;
647
+ /** 현재 상태 */
648
+ state: JobState;
649
+ /** 시도 횟수 */
650
+ attempt: number;
651
+ /** 최대 시도 횟수 */
652
+ maxAttempts: number;
653
+ /** 실행 인자 */
654
+ args?: unknown[];
655
+ /** 실행 결과 */
656
+ result?: unknown;
657
+ /** 발생한 에러 목록 */
658
+ errors?: ErrorData[] | null;
659
+ /** 생성 시간 */
660
+ insertedAt: Date;
661
+ /** 시도 시간 */
662
+ attemptedAt?: Date;
663
+ /** 완료 시간 */
664
+ completedAt?: Date;
665
+ /** 메타데이터 */
666
+ metadata?: Record<string, unknown>;
667
+ }
668
+ /**
669
+ * Job 상태
670
+ */
671
+ type JobState = 'available' | 'scheduled' | 'executing' | 'completed' | 'failed' | 'discarded' | 'cancelled';
672
+
673
+ type JobClassType = new (...args: unknown[]) => Job;
674
+ /**
675
+ * Sidequest.js API Adapter
676
+ *
677
+ * Sidequest.js의 API를 NestJS와 통합합니다.
678
+ * 실제 sidequest 패키지를 사용하여 Job 처리를 수행합니다.
679
+ */
680
+ declare class SidequestAdapter {
681
+ private readonly logger;
682
+ private isStarted;
683
+ private readonly registeredJobs;
684
+ /**
685
+ * Sidequest 엔진 시작
686
+ */
687
+ start(options: SidequestModuleOptions): Promise<void>;
688
+ /**
689
+ * Sidequest 엔진 종료
690
+ */
691
+ shutdown(): Promise<void>;
692
+ /**
693
+ * Job 클래스 등록
694
+ */
695
+ registerJob(jobName: string, JobClass: JobClassType): void;
696
+ /**
697
+ * Job 추가
698
+ */
699
+ addJob(queueName: string, jobName: string, args: unknown[], options?: JobAddOptions): Promise<string>;
700
+ /**
701
+ * Bulk Job 추가
702
+ */
703
+ addBulkJobs(queueName: string, jobs: Array<{
704
+ jobName: string;
705
+ args: unknown[];
706
+ options?: JobAddOptions;
707
+ }>): Promise<string[]>;
708
+ /**
709
+ * Job 조회
710
+ */
711
+ getJob(jobId: string | number): Promise<JobInfo | undefined>;
712
+ /**
713
+ * 엔진 시작 여부
714
+ */
715
+ get started(): boolean;
716
+ /**
717
+ * 등록된 Job 클래스 반환
718
+ */
719
+ getRegisteredJob(jobName: string): JobClassType | undefined;
720
+ /**
721
+ * 모든 등록된 Job 클래스 반환
722
+ */
723
+ getAllRegisteredJobs(): Map<string, JobClassType>;
724
+ }
725
+
726
+ /**
727
+ * Sidequest 엔진 관리 서비스
728
+ *
729
+ * Sidequest.js 엔진의 라이프사이클을 관리합니다.
730
+ * 모듈 초기화 시 엔진을 시작하고, 종료 시 graceful shutdown을 수행합니다.
731
+ */
732
+ declare class SidequestEngineService implements OnModuleInit, OnModuleDestroy {
733
+ private readonly options;
734
+ private readonly adapter;
735
+ private readonly logger;
736
+ constructor(options: SidequestModuleOptions, adapter: SidequestAdapter);
737
+ /**
738
+ * 모듈 초기화 시 엔진 시작
739
+ */
740
+ onModuleInit(): Promise<void>;
741
+ /**
742
+ * 모듈 종료 시 엔진 종료
743
+ */
744
+ onModuleDestroy(): Promise<void>;
745
+ /**
746
+ * 엔진 시작 여부
747
+ */
748
+ get isStarted(): boolean;
749
+ /**
750
+ * Adapter 인스턴스 반환
751
+ */
752
+ getAdapter(): SidequestAdapter;
753
+ }
754
+
755
+ /**
756
+ * Queue 레지스트리 서비스
757
+ *
758
+ * 큐 인스턴스를 관리하고 @InjectQueue()를 위한 DI 프로바이더를 제공합니다.
759
+ */
760
+ declare class QueueRegistryService {
761
+ private readonly options;
762
+ private readonly adapter;
763
+ private readonly logger;
764
+ private readonly queueServices;
765
+ constructor(options: SidequestModuleOptions, adapter: SidequestAdapter);
766
+ /**
767
+ * 설정된 큐 초기화
768
+ */
769
+ private initializeQueues;
770
+ /**
771
+ * 큐 등록
772
+ */
773
+ registerQueue(config: QueueConfig): void;
774
+ /**
775
+ * 큐 서비스 조회
776
+ */
777
+ getQueue(name: string): IQueueService | undefined;
778
+ /**
779
+ * 큐 서비스 조회 (없으면 에러)
780
+ */
781
+ getQueueOrThrow(name: string): IQueueService;
782
+ /**
783
+ * 모든 큐 조회
784
+ */
785
+ getAllQueues(): Map<string, IQueueService>;
786
+ /**
787
+ * 큐 서비스 인스턴스 생성
788
+ */
789
+ private createQueueService;
790
+ }
791
+
792
+ interface ClsService {
793
+ getId(): string | undefined;
794
+ get<T>(key: string): T | undefined;
795
+ set<T>(key: string, value: T): void;
796
+ run<T>(callback: () => T): T;
797
+ }
798
+ /**
799
+ * CLS(Continuation Local Storage) 통합 서비스
800
+ *
801
+ * nestjs-cls가 설치되어 있을 경우 Job 실행 시 context를 전파합니다.
802
+ * nestjs-cls가 없으면 no-op으로 동작합니다.
803
+ */
804
+ declare class ClsIntegrationService {
805
+ private readonly logger;
806
+ private readonly enabled;
807
+ private clsService;
808
+ constructor(options: SidequestModuleOptions, clsService?: ClsService);
809
+ /**
810
+ * CLS context 내에서 콜백 실행
811
+ */
812
+ runInContext<T>(metadata: Record<string, unknown>, callback: () => Promise<T>): Promise<T>;
813
+ /**
814
+ * 현재 traceId 조회
815
+ */
816
+ getTraceId(): string | undefined;
817
+ /**
818
+ * traceId 설정
819
+ */
820
+ setTraceId(traceId: string): void;
821
+ /**
822
+ * CLS에서 값 조회
823
+ */
824
+ get<T>(key: string): T | undefined;
825
+ /**
826
+ * CLS에 값 설정
827
+ */
828
+ set<T>(key: string, value: T): void;
829
+ /**
830
+ * CLS 통합 활성화 여부
831
+ */
832
+ isEnabled(): boolean;
833
+ }
834
+
835
+ /**
836
+ * Processor 레지스트리 서비스
837
+ *
838
+ * @Processor 데코레이터로 등록된 프로세서와 핸들러를 관리합니다.
839
+ */
840
+ declare class ProcessorRegistryService {
841
+ private readonly clsService?;
842
+ private readonly logger;
843
+ private readonly processors;
844
+ constructor(clsService?: ClsIntegrationService | undefined);
845
+ /**
846
+ * 프로세서 등록
847
+ */
848
+ register(processor: RegisteredProcessor): void;
849
+ /**
850
+ * 프로세서 조회
851
+ */
852
+ getProcessor(queueName: string): RegisteredProcessor | undefined;
853
+ /**
854
+ * 모든 프로세서 조회
855
+ */
856
+ getAllProcessors(): Map<string, RegisteredProcessor>;
857
+ /**
858
+ * Job 핸들러 조회
859
+ */
860
+ getJobHandler(queueName: string, jobName: string): RegisteredHandler | undefined;
861
+ /**
862
+ * Job 완료 핸들러 조회
863
+ */
864
+ getCompleteHandler(queueName: string, jobName: string): string | undefined;
865
+ /**
866
+ * Job 실패 핸들러 조회
867
+ */
868
+ getFailedHandler(queueName: string, jobName: string): string | undefined;
869
+ /**
870
+ * Job 디스패치 (실행)
871
+ *
872
+ * @param queueName - 큐 이름
873
+ * @param jobName - Job 이름
874
+ * @param args - Job 인자
875
+ * @param metadata - Job 메타데이터 (traceId 등)
876
+ */
877
+ dispatch(queueName: string, jobName: string, args: unknown[], metadata?: Record<string, unknown>): Promise<unknown>;
878
+ }
879
+
880
+ /**
881
+ * SidequestModule 상수
882
+ */
883
+ declare const SIDEQUEST_MODULE_OPTIONS: unique symbol;
884
+ declare const SIDEQUEST_ENGINE: unique symbol;
885
+ declare const PROCESSOR_METADATA_KEY: unique symbol;
886
+ declare const ON_JOB_METADATA_KEY: unique symbol;
887
+ declare const RETRY_OPTIONS_METADATA_KEY: unique symbol;
888
+ declare const ON_JOB_COMPLETE_METADATA_KEY: unique symbol;
889
+ declare const ON_JOB_FAILED_METADATA_KEY: unique symbol;
890
+ declare const QUEUE_TOKEN_PREFIX = "SIDEQUEST_QUEUE_";
891
+ /**
892
+ * Queue DI 토큰 생성
893
+ */
894
+ declare function getQueueToken(queueName: string): string;
895
+ declare const DEFAULT_QUEUE_NAME = "default";
896
+ declare const DEFAULT_MAX_ATTEMPTS = 3;
897
+ declare const DEFAULT_TIMEOUT = 30000;
898
+ declare const DEFAULT_CONCURRENCY = 10;
899
+
900
+ export { type BackendConfig, ClsIntegrationService, DEFAULT_CONCURRENCY, DEFAULT_MAX_ATTEMPTS, DEFAULT_QUEUE_NAME, DEFAULT_TIMEOUT, type DashboardConfig, type GracefulShutdownConfig, type IQueueService, InjectQueue, type JobAddOptions, type JobCompleteEvent, type JobFailedEvent, type JobInfo, type JobState, ON_JOB_COMPLETE_METADATA_KEY, ON_JOB_FAILED_METADATA_KEY, ON_JOB_METADATA_KEY, OnJob, OnJobComplete, OnJobFailed, type OnJobMetadata, type OnJobOptions, PROCESSOR_METADATA_KEY, Processor, type ProcessorMetadata, type ProcessorOptions, ProcessorRegistryService, QUEUE_TOKEN_PREFIX, type QueueConfig, QueueRegistryService, RETRY_OPTIONS_METADATA_KEY, type RegisteredHandler, type RegisteredProcessor, Retry, type RetryOptions, SIDEQUEST_ENGINE, SIDEQUEST_MODULE_OPTIONS, SidequestAdapter, SidequestEngineService, SidequestModule, type SidequestModuleAsyncOptions, type SidequestModuleOptions, type SidequestOptionsFactory, getQueueToken };