@bloomneo/appkit 1.2.9
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/LICENSE +21 -0
- package/README.md +902 -0
- package/bin/appkit.js +71 -0
- package/bin/commands/generate.js +1050 -0
- package/bin/templates/backend/README.md.template +39 -0
- package/bin/templates/backend/api.http.template +0 -0
- package/bin/templates/backend/docs/APPKIT_CLI.md +507 -0
- package/bin/templates/backend/docs/APPKIT_COMMENTS_GUIDELINES.md +61 -0
- package/bin/templates/backend/docs/APPKIT_LLM_GUIDE.md +2539 -0
- package/bin/templates/backend/package.json.template +34 -0
- package/bin/templates/backend/src/api/features/welcome/welcome.http.template +29 -0
- package/bin/templates/backend/src/api/features/welcome/welcome.route.ts.template +36 -0
- package/bin/templates/backend/src/api/features/welcome/welcome.service.ts.template +88 -0
- package/bin/templates/backend/src/api/features/welcome/welcome.types.ts.template +18 -0
- package/bin/templates/backend/src/api/lib/api-router.ts.template +84 -0
- package/bin/templates/backend/src/api/server.ts.template +188 -0
- package/bin/templates/backend/tsconfig.api.json.template +24 -0
- package/bin/templates/backend/tsconfig.json.template +40 -0
- package/bin/templates/feature/feature.http.template +63 -0
- package/bin/templates/feature/feature.route.ts.template +36 -0
- package/bin/templates/feature/feature.service.ts.template +81 -0
- package/bin/templates/feature/feature.types.ts.template +23 -0
- package/bin/templates/feature-db/feature.http.template +63 -0
- package/bin/templates/feature-db/feature.model.ts.template +74 -0
- package/bin/templates/feature-db/feature.route.ts.template +58 -0
- package/bin/templates/feature-db/feature.service.ts.template +231 -0
- package/bin/templates/feature-db/feature.types.ts.template +25 -0
- package/bin/templates/feature-db/schema-addition.prisma.template +9 -0
- package/bin/templates/feature-db/seeding/README.md.template +57 -0
- package/bin/templates/feature-db/seeding/feature.seed.js.template +67 -0
- package/bin/templates/feature-user/schema-addition.prisma.template +19 -0
- package/bin/templates/feature-user/user.http.template +157 -0
- package/bin/templates/feature-user/user.model.ts.template +244 -0
- package/bin/templates/feature-user/user.route.ts.template +379 -0
- package/bin/templates/feature-user/user.seed.js.template +182 -0
- package/bin/templates/feature-user/user.service.ts.template +426 -0
- package/bin/templates/feature-user/user.types.ts.template +127 -0
- package/dist/auth/auth.d.ts +182 -0
- package/dist/auth/auth.d.ts.map +1 -0
- package/dist/auth/auth.js +477 -0
- package/dist/auth/auth.js.map +1 -0
- package/dist/auth/defaults.d.ts +104 -0
- package/dist/auth/defaults.d.ts.map +1 -0
- package/dist/auth/defaults.js +374 -0
- package/dist/auth/defaults.js.map +1 -0
- package/dist/auth/index.d.ts +70 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +94 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/cache/cache.d.ts +118 -0
- package/dist/cache/cache.d.ts.map +1 -0
- package/dist/cache/cache.js +249 -0
- package/dist/cache/cache.js.map +1 -0
- package/dist/cache/defaults.d.ts +63 -0
- package/dist/cache/defaults.d.ts.map +1 -0
- package/dist/cache/defaults.js +193 -0
- package/dist/cache/defaults.js.map +1 -0
- package/dist/cache/index.d.ts +101 -0
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/index.js +203 -0
- package/dist/cache/index.js.map +1 -0
- package/dist/cache/strategies/memory.d.ts +138 -0
- package/dist/cache/strategies/memory.d.ts.map +1 -0
- package/dist/cache/strategies/memory.js +348 -0
- package/dist/cache/strategies/memory.js.map +1 -0
- package/dist/cache/strategies/redis.d.ts +105 -0
- package/dist/cache/strategies/redis.d.ts.map +1 -0
- package/dist/cache/strategies/redis.js +318 -0
- package/dist/cache/strategies/redis.js.map +1 -0
- package/dist/config/config.d.ts +62 -0
- package/dist/config/config.d.ts.map +1 -0
- package/dist/config/config.js +107 -0
- package/dist/config/config.js.map +1 -0
- package/dist/config/defaults.d.ts +44 -0
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/defaults.js +217 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/config/index.d.ts +105 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +163 -0
- package/dist/config/index.js.map +1 -0
- package/dist/database/adapters/mongoose.d.ts +106 -0
- package/dist/database/adapters/mongoose.d.ts.map +1 -0
- package/dist/database/adapters/mongoose.js +480 -0
- package/dist/database/adapters/mongoose.js.map +1 -0
- package/dist/database/adapters/prisma.d.ts +106 -0
- package/dist/database/adapters/prisma.d.ts.map +1 -0
- package/dist/database/adapters/prisma.js +494 -0
- package/dist/database/adapters/prisma.js.map +1 -0
- package/dist/database/defaults.d.ts +87 -0
- package/dist/database/defaults.d.ts.map +1 -0
- package/dist/database/defaults.js +271 -0
- package/dist/database/defaults.js.map +1 -0
- package/dist/database/index.d.ts +137 -0
- package/dist/database/index.d.ts.map +1 -0
- package/dist/database/index.js +490 -0
- package/dist/database/index.js.map +1 -0
- package/dist/email/defaults.d.ts +100 -0
- package/dist/email/defaults.d.ts.map +1 -0
- package/dist/email/defaults.js +400 -0
- package/dist/email/defaults.js.map +1 -0
- package/dist/email/email.d.ts +139 -0
- package/dist/email/email.d.ts.map +1 -0
- package/dist/email/email.js +316 -0
- package/dist/email/email.js.map +1 -0
- package/dist/email/index.d.ts +176 -0
- package/dist/email/index.d.ts.map +1 -0
- package/dist/email/index.js +251 -0
- package/dist/email/index.js.map +1 -0
- package/dist/email/strategies/console.d.ts +90 -0
- package/dist/email/strategies/console.d.ts.map +1 -0
- package/dist/email/strategies/console.js +268 -0
- package/dist/email/strategies/console.js.map +1 -0
- package/dist/email/strategies/resend.d.ts +84 -0
- package/dist/email/strategies/resend.d.ts.map +1 -0
- package/dist/email/strategies/resend.js +266 -0
- package/dist/email/strategies/resend.js.map +1 -0
- package/dist/email/strategies/smtp.d.ts +77 -0
- package/dist/email/strategies/smtp.d.ts.map +1 -0
- package/dist/email/strategies/smtp.js +286 -0
- package/dist/email/strategies/smtp.js.map +1 -0
- package/dist/error/defaults.d.ts +40 -0
- package/dist/error/defaults.d.ts.map +1 -0
- package/dist/error/defaults.js +75 -0
- package/dist/error/defaults.js.map +1 -0
- package/dist/error/error.d.ts +140 -0
- package/dist/error/error.d.ts.map +1 -0
- package/dist/error/error.js +200 -0
- package/dist/error/error.js.map +1 -0
- package/dist/error/index.d.ts +145 -0
- package/dist/error/index.d.ts.map +1 -0
- package/dist/error/index.js +145 -0
- package/dist/error/index.js.map +1 -0
- package/dist/event/defaults.d.ts +111 -0
- package/dist/event/defaults.d.ts.map +1 -0
- package/dist/event/defaults.js +378 -0
- package/dist/event/defaults.js.map +1 -0
- package/dist/event/event.d.ts +171 -0
- package/dist/event/event.d.ts.map +1 -0
- package/dist/event/event.js +391 -0
- package/dist/event/event.js.map +1 -0
- package/dist/event/index.d.ts +173 -0
- package/dist/event/index.d.ts.map +1 -0
- package/dist/event/index.js +302 -0
- package/dist/event/index.js.map +1 -0
- package/dist/event/strategies/memory.d.ts +122 -0
- package/dist/event/strategies/memory.d.ts.map +1 -0
- package/dist/event/strategies/memory.js +331 -0
- package/dist/event/strategies/memory.js.map +1 -0
- package/dist/event/strategies/redis.d.ts +115 -0
- package/dist/event/strategies/redis.d.ts.map +1 -0
- package/dist/event/strategies/redis.js +434 -0
- package/dist/event/strategies/redis.js.map +1 -0
- package/dist/index.d.ts +58 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +72 -0
- package/dist/index.js.map +1 -0
- package/dist/logger/defaults.d.ts +67 -0
- package/dist/logger/defaults.d.ts.map +1 -0
- package/dist/logger/defaults.js +213 -0
- package/dist/logger/defaults.js.map +1 -0
- package/dist/logger/index.d.ts +84 -0
- package/dist/logger/index.d.ts.map +1 -0
- package/dist/logger/index.js +101 -0
- package/dist/logger/index.js.map +1 -0
- package/dist/logger/logger.d.ts +165 -0
- package/dist/logger/logger.d.ts.map +1 -0
- package/dist/logger/logger.js +843 -0
- package/dist/logger/logger.js.map +1 -0
- package/dist/logger/transports/console.d.ts +102 -0
- package/dist/logger/transports/console.d.ts.map +1 -0
- package/dist/logger/transports/console.js +276 -0
- package/dist/logger/transports/console.js.map +1 -0
- package/dist/logger/transports/database.d.ts +153 -0
- package/dist/logger/transports/database.d.ts.map +1 -0
- package/dist/logger/transports/database.js +539 -0
- package/dist/logger/transports/database.js.map +1 -0
- package/dist/logger/transports/file.d.ts +146 -0
- package/dist/logger/transports/file.d.ts.map +1 -0
- package/dist/logger/transports/file.js +464 -0
- package/dist/logger/transports/file.js.map +1 -0
- package/dist/logger/transports/http.d.ts +128 -0
- package/dist/logger/transports/http.d.ts.map +1 -0
- package/dist/logger/transports/http.js +401 -0
- package/dist/logger/transports/http.js.map +1 -0
- package/dist/logger/transports/webhook.d.ts +152 -0
- package/dist/logger/transports/webhook.d.ts.map +1 -0
- package/dist/logger/transports/webhook.js +485 -0
- package/dist/logger/transports/webhook.js.map +1 -0
- package/dist/queue/defaults.d.ts +66 -0
- package/dist/queue/defaults.d.ts.map +1 -0
- package/dist/queue/defaults.js +205 -0
- package/dist/queue/defaults.js.map +1 -0
- package/dist/queue/index.d.ts +124 -0
- package/dist/queue/index.d.ts.map +1 -0
- package/dist/queue/index.js +116 -0
- package/dist/queue/index.js.map +1 -0
- package/dist/queue/queue.d.ts +156 -0
- package/dist/queue/queue.d.ts.map +1 -0
- package/dist/queue/queue.js +387 -0
- package/dist/queue/queue.js.map +1 -0
- package/dist/queue/transports/database.d.ts +165 -0
- package/dist/queue/transports/database.d.ts.map +1 -0
- package/dist/queue/transports/database.js +595 -0
- package/dist/queue/transports/database.js.map +1 -0
- package/dist/queue/transports/memory.d.ts +143 -0
- package/dist/queue/transports/memory.d.ts.map +1 -0
- package/dist/queue/transports/memory.js +415 -0
- package/dist/queue/transports/memory.js.map +1 -0
- package/dist/queue/transports/redis.d.ts +203 -0
- package/dist/queue/transports/redis.d.ts.map +1 -0
- package/dist/queue/transports/redis.js +744 -0
- package/dist/queue/transports/redis.js.map +1 -0
- package/dist/security/defaults.d.ts +64 -0
- package/dist/security/defaults.d.ts.map +1 -0
- package/dist/security/defaults.js +159 -0
- package/dist/security/defaults.js.map +1 -0
- package/dist/security/index.d.ts +110 -0
- package/dist/security/index.d.ts.map +1 -0
- package/dist/security/index.js +160 -0
- package/dist/security/index.js.map +1 -0
- package/dist/security/security.d.ts +138 -0
- package/dist/security/security.d.ts.map +1 -0
- package/dist/security/security.js +419 -0
- package/dist/security/security.js.map +1 -0
- package/dist/storage/defaults.d.ts +79 -0
- package/dist/storage/defaults.d.ts.map +1 -0
- package/dist/storage/defaults.js +358 -0
- package/dist/storage/defaults.js.map +1 -0
- package/dist/storage/index.d.ts +153 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +242 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/storage.d.ts +151 -0
- package/dist/storage/storage.d.ts.map +1 -0
- package/dist/storage/storage.js +439 -0
- package/dist/storage/storage.js.map +1 -0
- package/dist/storage/strategies/local.d.ts +117 -0
- package/dist/storage/strategies/local.d.ts.map +1 -0
- package/dist/storage/strategies/local.js +368 -0
- package/dist/storage/strategies/local.js.map +1 -0
- package/dist/storage/strategies/r2.d.ts +130 -0
- package/dist/storage/strategies/r2.d.ts.map +1 -0
- package/dist/storage/strategies/r2.js +470 -0
- package/dist/storage/strategies/r2.js.map +1 -0
- package/dist/storage/strategies/s3.d.ts +121 -0
- package/dist/storage/strategies/s3.d.ts.map +1 -0
- package/dist/storage/strategies/s3.js +461 -0
- package/dist/storage/strategies/s3.js.map +1 -0
- package/dist/util/defaults.d.ts +77 -0
- package/dist/util/defaults.d.ts.map +1 -0
- package/dist/util/defaults.js +193 -0
- package/dist/util/defaults.js.map +1 -0
- package/dist/util/index.d.ts +97 -0
- package/dist/util/index.d.ts.map +1 -0
- package/dist/util/index.js +165 -0
- package/dist/util/index.js.map +1 -0
- package/dist/util/util.d.ts +145 -0
- package/dist/util/util.d.ts.map +1 -0
- package/dist/util/util.js +481 -0
- package/dist/util/util.js.map +1 -0
- package/package.json +234 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-memory queue transport for development and testing
|
|
3
|
+
* @module @bloomneo/appkit/queue
|
|
4
|
+
* @file src/queue/transports/memory.ts
|
|
5
|
+
*
|
|
6
|
+
* @llm-rule WHEN: Development mode or when no Redis/Database available
|
|
7
|
+
* @llm-rule AVOID: Production use - jobs lost on restart, no persistence
|
|
8
|
+
* @llm-rule NOTE: Perfect for development and testing - fast, simple, no external dependencies
|
|
9
|
+
*/
|
|
10
|
+
import type { Transport } from '../queue.js';
|
|
11
|
+
import type { QueueConfig } from '../defaults.js';
|
|
12
|
+
import type { JobData, JobOptions, JobHandler, QueueStats, JobInfo, JobStatus } from '../index.js';
|
|
13
|
+
/**
|
|
14
|
+
* In-memory transport for development and testing
|
|
15
|
+
*/
|
|
16
|
+
export declare class MemoryTransport implements Transport {
|
|
17
|
+
private config;
|
|
18
|
+
private jobs;
|
|
19
|
+
private handlers;
|
|
20
|
+
private paused;
|
|
21
|
+
private processing;
|
|
22
|
+
private schedulerTimer;
|
|
23
|
+
private cleanupTimer;
|
|
24
|
+
private processingLoop;
|
|
25
|
+
/**
|
|
26
|
+
* Creates memory transport with direct config access (like logging pattern)
|
|
27
|
+
* @llm-rule WHEN: Auto-detected as fallback or explicitly configured for development
|
|
28
|
+
* @llm-rule AVOID: Manual memory transport creation - use queuing.get() instead
|
|
29
|
+
*/
|
|
30
|
+
constructor(config: QueueConfig);
|
|
31
|
+
/**
|
|
32
|
+
* Add job to memory queue
|
|
33
|
+
* @llm-rule WHEN: Adding jobs for background processing
|
|
34
|
+
* @llm-rule AVOID: Adding too many jobs - memory transport has limits
|
|
35
|
+
*/
|
|
36
|
+
add(id: string, jobType: string, data: JobData, options: JobOptions): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* Register job processor
|
|
39
|
+
* @llm-rule WHEN: Setting up job handlers for specific job types
|
|
40
|
+
* @llm-rule AVOID: Multiple handlers for same type - overwrites previous handler
|
|
41
|
+
*/
|
|
42
|
+
process<T = JobData>(jobType: string, handler: JobHandler<T>): void;
|
|
43
|
+
/**
|
|
44
|
+
* Schedule job for future execution
|
|
45
|
+
* @llm-rule WHEN: Need delayed job execution (reminders, scheduled tasks)
|
|
46
|
+
* @llm-rule AVOID: Very long delays - memory transport resets on restart
|
|
47
|
+
*/
|
|
48
|
+
schedule(id: string, jobType: string, data: JobData, delay: number): Promise<void>;
|
|
49
|
+
/**
|
|
50
|
+
* Pause queue processing
|
|
51
|
+
* @llm-rule WHEN: Maintenance mode or controlled processing stop
|
|
52
|
+
* @llm-rule AVOID: Pausing without resume - jobs accumulate in memory
|
|
53
|
+
*/
|
|
54
|
+
pause(jobType?: string): Promise<void>;
|
|
55
|
+
/**
|
|
56
|
+
* Resume queue processing
|
|
57
|
+
* @llm-rule WHEN: Resuming after maintenance pause
|
|
58
|
+
* @llm-rule AVOID: Resuming without checking system capacity
|
|
59
|
+
*/
|
|
60
|
+
resume(jobType?: string): Promise<void>;
|
|
61
|
+
/**
|
|
62
|
+
* Get queue statistics
|
|
63
|
+
* @llm-rule WHEN: Monitoring queue health and performance
|
|
64
|
+
* @llm-rule AVOID: Frequent polling - can be expensive with many jobs
|
|
65
|
+
*/
|
|
66
|
+
getStats(jobType?: string): Promise<QueueStats>;
|
|
67
|
+
/**
|
|
68
|
+
* Get jobs by status
|
|
69
|
+
* @llm-rule WHEN: Debugging failed jobs or monitoring specific job states
|
|
70
|
+
* @llm-rule AVOID: Getting all jobs frequently - can impact memory performance
|
|
71
|
+
*/
|
|
72
|
+
getJobs(status: JobStatus, jobType?: string): Promise<JobInfo[]>;
|
|
73
|
+
/**
|
|
74
|
+
* Retry failed job
|
|
75
|
+
* @llm-rule WHEN: Manual retry of failed jobs
|
|
76
|
+
* @llm-rule AVOID: Retrying jobs that will fail again without fixing root cause
|
|
77
|
+
*/
|
|
78
|
+
retry(jobId: string): Promise<void>;
|
|
79
|
+
/**
|
|
80
|
+
* Remove job from queue
|
|
81
|
+
* @llm-rule WHEN: Canceling scheduled jobs or cleanup
|
|
82
|
+
* @llm-rule AVOID: Removing active jobs - can cause inconsistent state
|
|
83
|
+
*/
|
|
84
|
+
remove(jobId: string): Promise<void>;
|
|
85
|
+
/**
|
|
86
|
+
* Clean old jobs by status
|
|
87
|
+
* @llm-rule WHEN: Periodic cleanup to prevent memory growth
|
|
88
|
+
* @llm-rule AVOID: Aggressive cleanup - keep some jobs for debugging
|
|
89
|
+
*/
|
|
90
|
+
clean(status: JobStatus, grace?: number): Promise<void>;
|
|
91
|
+
/**
|
|
92
|
+
* Get transport health status
|
|
93
|
+
* @llm-rule WHEN: Health checks and monitoring
|
|
94
|
+
* @llm-rule AVOID: Complex health logic - memory transport is simple
|
|
95
|
+
*/
|
|
96
|
+
getHealth(): {
|
|
97
|
+
status: 'healthy' | 'degraded' | 'unhealthy';
|
|
98
|
+
message?: string;
|
|
99
|
+
};
|
|
100
|
+
/**
|
|
101
|
+
* Close transport and cleanup resources
|
|
102
|
+
* @llm-rule WHEN: App shutdown or testing cleanup
|
|
103
|
+
* @llm-rule AVOID: Abrupt close - finish processing current jobs first
|
|
104
|
+
*/
|
|
105
|
+
close(): Promise<void>;
|
|
106
|
+
/**
|
|
107
|
+
* Start background processing loop
|
|
108
|
+
*/
|
|
109
|
+
private startProcessing;
|
|
110
|
+
/**
|
|
111
|
+
* Main job processing loop
|
|
112
|
+
*/
|
|
113
|
+
private processJobs;
|
|
114
|
+
/**
|
|
115
|
+
* Promote delayed jobs that are ready to run
|
|
116
|
+
*/
|
|
117
|
+
private promoteDelayedJobs;
|
|
118
|
+
/**
|
|
119
|
+
* Process waiting jobs up to concurrency limit
|
|
120
|
+
*/
|
|
121
|
+
private processWaitingJobs;
|
|
122
|
+
/**
|
|
123
|
+
* Process individual job
|
|
124
|
+
*/
|
|
125
|
+
private processJob;
|
|
126
|
+
/**
|
|
127
|
+
* Calculate retry delay with backoff
|
|
128
|
+
*/
|
|
129
|
+
private calculateRetryDelay;
|
|
130
|
+
/**
|
|
131
|
+
* Setup periodic cleanup
|
|
132
|
+
*/
|
|
133
|
+
private setupCleanup;
|
|
134
|
+
/**
|
|
135
|
+
* Perform automatic cleanup
|
|
136
|
+
*/
|
|
137
|
+
private performCleanup;
|
|
138
|
+
/**
|
|
139
|
+
* Convert MemoryJob to JobInfo
|
|
140
|
+
*/
|
|
141
|
+
private jobToInfo;
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=memory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../../src/queue/transports/memory.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAmBnG;;GAEG;AACH,qBAAa,eAAgB,YAAW,SAAS;IAC/C,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,IAAI,CAAgC;IAC5C,OAAO,CAAC,QAAQ,CAAsC;IACtD,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,UAAU,CAAqB;IAGvC,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,YAAY,CAA+B;IACnD,OAAO,CAAC,cAAc,CAA+B;IAErD;;;;OAIG;gBACS,MAAM,EAAE,WAAW;IAU/B;;;;OAIG;IACG,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBzF;;;;OAIG;IACH,OAAO,CAAC,CAAC,GAAG,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,IAAI;IAInE;;;;OAIG;IACG,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBxF;;;;OAIG;IACG,KAAK,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAW5C;;;;OAIG;IACG,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAS7C;;;;OAIG;IACG,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAerD;;;;OAIG;IACG,OAAO,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAWtE;;;;OAIG;IACG,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBzC;;;;OAIG;IACG,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAa1C;;;;OAIG;IACG,KAAK,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,GAAE,MAA4B,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBlF;;;;OAIG;IACH,SAAS,IAAI;QAAE,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,WAAW,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE;IAe/E;;;;OAIG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAoC5B;;OAEG;IACH,OAAO,CAAC,eAAe;IAIvB;;OAEG;YACW,WAAW;IAezB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAU1B;;OAEG;YACW,kBAAkB;IA4BhC;;OAEG;YACW,UAAU;IAgDxB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAe3B;;OAEG;IACH,OAAO,CAAC,YAAY;IAQpB;;OAEG;YACW,cAAc;IAQ5B;;OAEG;IACH,OAAO,CAAC,SAAS;CAgBlB"}
|
|
@@ -0,0 +1,415 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-memory queue transport for development and testing
|
|
3
|
+
* @module @bloomneo/appkit/queue
|
|
4
|
+
* @file src/queue/transports/memory.ts
|
|
5
|
+
*
|
|
6
|
+
* @llm-rule WHEN: Development mode or when no Redis/Database available
|
|
7
|
+
* @llm-rule AVOID: Production use - jobs lost on restart, no persistence
|
|
8
|
+
* @llm-rule NOTE: Perfect for development and testing - fast, simple, no external dependencies
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* In-memory transport for development and testing
|
|
12
|
+
*/
|
|
13
|
+
export class MemoryTransport {
|
|
14
|
+
config;
|
|
15
|
+
jobs = new Map();
|
|
16
|
+
handlers = new Map();
|
|
17
|
+
paused = new Set();
|
|
18
|
+
processing = new Set();
|
|
19
|
+
// Timers for scheduling and cleanup
|
|
20
|
+
schedulerTimer = null;
|
|
21
|
+
cleanupTimer = null;
|
|
22
|
+
processingLoop = null;
|
|
23
|
+
/**
|
|
24
|
+
* Creates memory transport with direct config access (like logging pattern)
|
|
25
|
+
* @llm-rule WHEN: Auto-detected as fallback or explicitly configured for development
|
|
26
|
+
* @llm-rule AVOID: Manual memory transport creation - use queuing.get() instead
|
|
27
|
+
*/
|
|
28
|
+
constructor(config) {
|
|
29
|
+
this.config = config;
|
|
30
|
+
// Start processing loops if worker enabled
|
|
31
|
+
if (config.worker.enabled) {
|
|
32
|
+
this.startProcessing();
|
|
33
|
+
this.setupCleanup();
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Add job to memory queue
|
|
38
|
+
* @llm-rule WHEN: Adding jobs for background processing
|
|
39
|
+
* @llm-rule AVOID: Adding too many jobs - memory transport has limits
|
|
40
|
+
*/
|
|
41
|
+
async add(id, jobType, data, options) {
|
|
42
|
+
// Check memory limits
|
|
43
|
+
if (this.jobs.size >= this.config.memory.maxJobs) {
|
|
44
|
+
throw new Error(`Memory queue full (${this.config.memory.maxJobs} jobs)`);
|
|
45
|
+
}
|
|
46
|
+
const job = {
|
|
47
|
+
id,
|
|
48
|
+
type: jobType,
|
|
49
|
+
data,
|
|
50
|
+
options,
|
|
51
|
+
status: 'waiting',
|
|
52
|
+
attempts: 0,
|
|
53
|
+
maxAttempts: options.attempts || this.config.maxAttempts,
|
|
54
|
+
createdAt: new Date(),
|
|
55
|
+
runAt: new Date(),
|
|
56
|
+
};
|
|
57
|
+
this.jobs.set(id, job);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Register job processor
|
|
61
|
+
* @llm-rule WHEN: Setting up job handlers for specific job types
|
|
62
|
+
* @llm-rule AVOID: Multiple handlers for same type - overwrites previous handler
|
|
63
|
+
*/
|
|
64
|
+
process(jobType, handler) {
|
|
65
|
+
this.handlers.set(jobType, handler);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Schedule job for future execution
|
|
69
|
+
* @llm-rule WHEN: Need delayed job execution (reminders, scheduled tasks)
|
|
70
|
+
* @llm-rule AVOID: Very long delays - memory transport resets on restart
|
|
71
|
+
*/
|
|
72
|
+
async schedule(id, jobType, data, delay) {
|
|
73
|
+
// Check memory limits
|
|
74
|
+
if (this.jobs.size >= this.config.memory.maxJobs) {
|
|
75
|
+
throw new Error(`Memory queue full (${this.config.memory.maxJobs} jobs)`);
|
|
76
|
+
}
|
|
77
|
+
const job = {
|
|
78
|
+
id,
|
|
79
|
+
type: jobType,
|
|
80
|
+
data,
|
|
81
|
+
options: { attempts: this.config.maxAttempts },
|
|
82
|
+
status: 'delayed',
|
|
83
|
+
attempts: 0,
|
|
84
|
+
maxAttempts: this.config.maxAttempts,
|
|
85
|
+
createdAt: new Date(),
|
|
86
|
+
runAt: new Date(Date.now() + delay),
|
|
87
|
+
};
|
|
88
|
+
this.jobs.set(id, job);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Pause queue processing
|
|
92
|
+
* @llm-rule WHEN: Maintenance mode or controlled processing stop
|
|
93
|
+
* @llm-rule AVOID: Pausing without resume - jobs accumulate in memory
|
|
94
|
+
*/
|
|
95
|
+
async pause(jobType) {
|
|
96
|
+
if (jobType) {
|
|
97
|
+
this.paused.add(jobType);
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
// Pause all by clearing handlers temporarily
|
|
101
|
+
for (const type of this.handlers.keys()) {
|
|
102
|
+
this.paused.add(type);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Resume queue processing
|
|
108
|
+
* @llm-rule WHEN: Resuming after maintenance pause
|
|
109
|
+
* @llm-rule AVOID: Resuming without checking system capacity
|
|
110
|
+
*/
|
|
111
|
+
async resume(jobType) {
|
|
112
|
+
if (jobType) {
|
|
113
|
+
this.paused.delete(jobType);
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
// Resume all
|
|
117
|
+
this.paused.clear();
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Get queue statistics
|
|
122
|
+
* @llm-rule WHEN: Monitoring queue health and performance
|
|
123
|
+
* @llm-rule AVOID: Frequent polling - can be expensive with many jobs
|
|
124
|
+
*/
|
|
125
|
+
async getStats(jobType) {
|
|
126
|
+
const filteredJobs = Array.from(this.jobs.values()).filter(job => !jobType || job.type === jobType);
|
|
127
|
+
return {
|
|
128
|
+
waiting: filteredJobs.filter(job => job.status === 'waiting').length,
|
|
129
|
+
active: filteredJobs.filter(job => job.status === 'active').length,
|
|
130
|
+
completed: filteredJobs.filter(job => job.status === 'completed').length,
|
|
131
|
+
failed: filteredJobs.filter(job => job.status === 'failed').length,
|
|
132
|
+
delayed: filteredJobs.filter(job => job.status === 'delayed').length,
|
|
133
|
+
paused: this.paused.size,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Get jobs by status
|
|
138
|
+
* @llm-rule WHEN: Debugging failed jobs or monitoring specific job states
|
|
139
|
+
* @llm-rule AVOID: Getting all jobs frequently - can impact memory performance
|
|
140
|
+
*/
|
|
141
|
+
async getJobs(status, jobType) {
|
|
142
|
+
return Array.from(this.jobs.values())
|
|
143
|
+
.filter(job => {
|
|
144
|
+
const statusMatch = job.status === status;
|
|
145
|
+
const typeMatch = !jobType || job.type === jobType;
|
|
146
|
+
return statusMatch && typeMatch;
|
|
147
|
+
})
|
|
148
|
+
.map(job => this.jobToInfo(job))
|
|
149
|
+
.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime()); // Newest first
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Retry failed job
|
|
153
|
+
* @llm-rule WHEN: Manual retry of failed jobs
|
|
154
|
+
* @llm-rule AVOID: Retrying jobs that will fail again without fixing root cause
|
|
155
|
+
*/
|
|
156
|
+
async retry(jobId) {
|
|
157
|
+
const job = this.jobs.get(jobId);
|
|
158
|
+
if (!job) {
|
|
159
|
+
throw new Error(`Job ${jobId} not found`);
|
|
160
|
+
}
|
|
161
|
+
if (job.status !== 'failed') {
|
|
162
|
+
throw new Error(`Job ${jobId} is not in failed state`);
|
|
163
|
+
}
|
|
164
|
+
// Reset for retry
|
|
165
|
+
job.status = 'waiting';
|
|
166
|
+
job.attempts = 0;
|
|
167
|
+
job.error = undefined;
|
|
168
|
+
job.failedAt = undefined;
|
|
169
|
+
job.runAt = new Date();
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Remove job from queue
|
|
173
|
+
* @llm-rule WHEN: Canceling scheduled jobs or cleanup
|
|
174
|
+
* @llm-rule AVOID: Removing active jobs - can cause inconsistent state
|
|
175
|
+
*/
|
|
176
|
+
async remove(jobId) {
|
|
177
|
+
const job = this.jobs.get(jobId);
|
|
178
|
+
if (!job) {
|
|
179
|
+
throw new Error(`Job ${jobId} not found`);
|
|
180
|
+
}
|
|
181
|
+
if (job.status === 'active') {
|
|
182
|
+
throw new Error(`Cannot remove active job ${jobId}`);
|
|
183
|
+
}
|
|
184
|
+
this.jobs.delete(jobId);
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Clean old jobs by status
|
|
188
|
+
* @llm-rule WHEN: Periodic cleanup to prevent memory growth
|
|
189
|
+
* @llm-rule AVOID: Aggressive cleanup - keep some jobs for debugging
|
|
190
|
+
*/
|
|
191
|
+
async clean(status, grace = 24 * 60 * 60 * 1000) {
|
|
192
|
+
const cutoff = new Date(Date.now() - grace);
|
|
193
|
+
const toDelete = [];
|
|
194
|
+
for (const [id, job] of this.jobs) {
|
|
195
|
+
if (job.status === status) {
|
|
196
|
+
const jobDate = job.completedAt || job.failedAt || job.createdAt;
|
|
197
|
+
if (jobDate < cutoff) {
|
|
198
|
+
toDelete.push(id);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
for (const id of toDelete) {
|
|
203
|
+
this.jobs.delete(id);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Get transport health status
|
|
208
|
+
* @llm-rule WHEN: Health checks and monitoring
|
|
209
|
+
* @llm-rule AVOID: Complex health logic - memory transport is simple
|
|
210
|
+
*/
|
|
211
|
+
getHealth() {
|
|
212
|
+
const jobCount = this.jobs.size;
|
|
213
|
+
const maxJobs = this.config.memory.maxJobs;
|
|
214
|
+
if (jobCount >= maxJobs) {
|
|
215
|
+
return { status: 'unhealthy', message: 'Memory queue full' };
|
|
216
|
+
}
|
|
217
|
+
if (jobCount >= maxJobs * 0.8) {
|
|
218
|
+
return { status: 'degraded', message: 'Memory queue nearly full' };
|
|
219
|
+
}
|
|
220
|
+
return { status: 'healthy' };
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Close transport and cleanup resources
|
|
224
|
+
* @llm-rule WHEN: App shutdown or testing cleanup
|
|
225
|
+
* @llm-rule AVOID: Abrupt close - finish processing current jobs first
|
|
226
|
+
*/
|
|
227
|
+
async close() {
|
|
228
|
+
// Stop all timers
|
|
229
|
+
if (this.schedulerTimer) {
|
|
230
|
+
clearInterval(this.schedulerTimer);
|
|
231
|
+
this.schedulerTimer = null;
|
|
232
|
+
}
|
|
233
|
+
if (this.cleanupTimer) {
|
|
234
|
+
clearInterval(this.cleanupTimer);
|
|
235
|
+
this.cleanupTimer = null;
|
|
236
|
+
}
|
|
237
|
+
if (this.processingLoop) {
|
|
238
|
+
clearTimeout(this.processingLoop);
|
|
239
|
+
this.processingLoop = null;
|
|
240
|
+
}
|
|
241
|
+
// Wait for current jobs to complete (with timeout)
|
|
242
|
+
const timeout = this.config.worker.gracefulShutdownTimeout;
|
|
243
|
+
const startTime = Date.now();
|
|
244
|
+
while (this.processing.size > 0 && Date.now() - startTime < timeout) {
|
|
245
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
246
|
+
}
|
|
247
|
+
// Clear all data
|
|
248
|
+
this.jobs.clear();
|
|
249
|
+
this.handlers.clear();
|
|
250
|
+
this.paused.clear();
|
|
251
|
+
this.processing.clear();
|
|
252
|
+
}
|
|
253
|
+
// ============================================================================
|
|
254
|
+
// PRIVATE PROCESSING METHODS
|
|
255
|
+
// ============================================================================
|
|
256
|
+
/**
|
|
257
|
+
* Start background processing loop
|
|
258
|
+
*/
|
|
259
|
+
startProcessing() {
|
|
260
|
+
this.processJobs();
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Main job processing loop
|
|
264
|
+
*/
|
|
265
|
+
async processJobs() {
|
|
266
|
+
try {
|
|
267
|
+
// Move delayed jobs to waiting if ready
|
|
268
|
+
this.promoteDelayedJobs();
|
|
269
|
+
// Process waiting jobs
|
|
270
|
+
await this.processWaitingJobs();
|
|
271
|
+
}
|
|
272
|
+
catch (error) {
|
|
273
|
+
console.error('Memory transport processing error:', error.message);
|
|
274
|
+
}
|
|
275
|
+
// Schedule next processing cycle
|
|
276
|
+
this.processingLoop = setTimeout(() => this.processJobs(), 1000);
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Promote delayed jobs that are ready to run
|
|
280
|
+
*/
|
|
281
|
+
promoteDelayedJobs() {
|
|
282
|
+
const now = new Date();
|
|
283
|
+
for (const job of this.jobs.values()) {
|
|
284
|
+
if (job.status === 'delayed' && job.runAt <= now) {
|
|
285
|
+
job.status = 'waiting';
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Process waiting jobs up to concurrency limit
|
|
291
|
+
*/
|
|
292
|
+
async processWaitingJobs() {
|
|
293
|
+
const concurrency = this.config.concurrency;
|
|
294
|
+
const currentActive = this.processing.size;
|
|
295
|
+
if (currentActive >= concurrency) {
|
|
296
|
+
return; // At capacity
|
|
297
|
+
}
|
|
298
|
+
// Get waiting jobs sorted by priority
|
|
299
|
+
const waitingJobs = Array.from(this.jobs.values())
|
|
300
|
+
.filter(job => {
|
|
301
|
+
const isWaiting = job.status === 'waiting';
|
|
302
|
+
const hasHandler = this.handlers.has(job.type);
|
|
303
|
+
const notPaused = !this.paused.has(job.type);
|
|
304
|
+
return isWaiting && hasHandler && notPaused;
|
|
305
|
+
})
|
|
306
|
+
.sort((a, b) => (b.options.priority || 0) - (a.options.priority || 0));
|
|
307
|
+
// Process jobs up to concurrency limit
|
|
308
|
+
const toProcess = waitingJobs.slice(0, concurrency - currentActive);
|
|
309
|
+
for (const job of toProcess) {
|
|
310
|
+
this.processJob(job).catch(error => {
|
|
311
|
+
console.error(`Error processing job ${job.id}:`, error);
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Process individual job
|
|
317
|
+
*/
|
|
318
|
+
async processJob(job) {
|
|
319
|
+
const handler = this.handlers.get(job.type);
|
|
320
|
+
if (!handler) {
|
|
321
|
+
return; // No handler available
|
|
322
|
+
}
|
|
323
|
+
// Mark as processing
|
|
324
|
+
this.processing.add(job.id);
|
|
325
|
+
job.status = 'active';
|
|
326
|
+
job.processedAt = new Date();
|
|
327
|
+
job.attempts++;
|
|
328
|
+
try {
|
|
329
|
+
// Execute job handler
|
|
330
|
+
const result = await handler(job.data);
|
|
331
|
+
// Job completed successfully
|
|
332
|
+
job.status = 'completed';
|
|
333
|
+
job.completedAt = new Date();
|
|
334
|
+
// Store result if needed
|
|
335
|
+
if (result !== undefined) {
|
|
336
|
+
job.result = result;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
catch (error) {
|
|
340
|
+
// Job failed
|
|
341
|
+
job.error = {
|
|
342
|
+
message: error.message,
|
|
343
|
+
stack: error.stack,
|
|
344
|
+
name: error.name,
|
|
345
|
+
};
|
|
346
|
+
if (job.attempts < job.maxAttempts) {
|
|
347
|
+
// Retry with backoff
|
|
348
|
+
job.status = 'waiting';
|
|
349
|
+
job.runAt = this.calculateRetryDelay(job);
|
|
350
|
+
}
|
|
351
|
+
else {
|
|
352
|
+
// Max attempts reached
|
|
353
|
+
job.status = 'failed';
|
|
354
|
+
job.failedAt = new Date();
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
finally {
|
|
358
|
+
// Remove from processing set
|
|
359
|
+
this.processing.delete(job.id);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* Calculate retry delay with backoff
|
|
364
|
+
*/
|
|
365
|
+
calculateRetryDelay(job) {
|
|
366
|
+
const baseDelay = this.config.retryDelay;
|
|
367
|
+
let delay = baseDelay;
|
|
368
|
+
if (this.config.retryBackoff === 'exponential') {
|
|
369
|
+
delay = baseDelay * Math.pow(2, job.attempts - 1);
|
|
370
|
+
}
|
|
371
|
+
// Add jitter (±25%)
|
|
372
|
+
const jitter = delay * 0.25 * (Math.random() - 0.5);
|
|
373
|
+
delay += jitter;
|
|
374
|
+
return new Date(Date.now() + delay);
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Setup periodic cleanup
|
|
378
|
+
*/
|
|
379
|
+
setupCleanup() {
|
|
380
|
+
this.cleanupTimer = setInterval(() => {
|
|
381
|
+
this.performCleanup().catch(error => {
|
|
382
|
+
console.error('Memory transport cleanup error:', error);
|
|
383
|
+
});
|
|
384
|
+
}, this.config.memory.cleanupInterval);
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Perform automatic cleanup
|
|
388
|
+
*/
|
|
389
|
+
async performCleanup() {
|
|
390
|
+
// Clean completed jobs older than 1 hour
|
|
391
|
+
await this.clean('completed', 60 * 60 * 1000);
|
|
392
|
+
// Clean failed jobs older than 24 hours
|
|
393
|
+
await this.clean('failed', 24 * 60 * 60 * 1000);
|
|
394
|
+
}
|
|
395
|
+
/**
|
|
396
|
+
* Convert MemoryJob to JobInfo
|
|
397
|
+
*/
|
|
398
|
+
jobToInfo(job) {
|
|
399
|
+
return {
|
|
400
|
+
id: job.id,
|
|
401
|
+
type: job.type,
|
|
402
|
+
data: job.data,
|
|
403
|
+
status: job.status,
|
|
404
|
+
progress: job.progress,
|
|
405
|
+
attempts: job.attempts,
|
|
406
|
+
maxAttempts: job.maxAttempts,
|
|
407
|
+
error: job.error,
|
|
408
|
+
createdAt: job.createdAt,
|
|
409
|
+
processedAt: job.processedAt,
|
|
410
|
+
completedAt: job.completedAt,
|
|
411
|
+
failedAt: job.failedAt,
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
//# sourceMappingURL=memory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory.js","sourceRoot":"","sources":["../../../src/queue/transports/memory.ts"],"names":[],"mappings":"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"}
|