@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,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Smart defaults and environment validation for job queue management
|
|
3
|
+
* @module @bloomneo/appkit/queue
|
|
4
|
+
* @file src/queue/defaults.ts
|
|
5
|
+
*
|
|
6
|
+
* @llm-rule WHEN: App startup - need to parse VOILA_QUEUE_* environment variables and detect transports
|
|
7
|
+
* @llm-rule AVOID: Calling multiple times - expensive validation, use lazy loading in get()
|
|
8
|
+
* @llm-rule NOTE: Called once at startup, cached globally for performance like auth/logging modules
|
|
9
|
+
*/
|
|
10
|
+
export interface QueueConfig {
|
|
11
|
+
transport: 'memory' | 'redis' | 'database';
|
|
12
|
+
concurrency: number;
|
|
13
|
+
maxAttempts: number;
|
|
14
|
+
retryDelay: number;
|
|
15
|
+
retryBackoff: 'fixed' | 'exponential';
|
|
16
|
+
defaultPriority: number;
|
|
17
|
+
removeOnComplete: number;
|
|
18
|
+
removeOnFail: number;
|
|
19
|
+
memory: {
|
|
20
|
+
maxJobs: number;
|
|
21
|
+
cleanupInterval: number;
|
|
22
|
+
};
|
|
23
|
+
redis: {
|
|
24
|
+
url: string | null;
|
|
25
|
+
keyPrefix: string;
|
|
26
|
+
maxRetriesPerRequest: number;
|
|
27
|
+
retryDelayOnFailover: number;
|
|
28
|
+
};
|
|
29
|
+
database: {
|
|
30
|
+
url: string | null;
|
|
31
|
+
tableName: string;
|
|
32
|
+
batchSize: number;
|
|
33
|
+
pollInterval: number;
|
|
34
|
+
};
|
|
35
|
+
worker: {
|
|
36
|
+
enabled: boolean;
|
|
37
|
+
gracefulShutdownTimeout: number;
|
|
38
|
+
stalledInterval: number;
|
|
39
|
+
maxStalledCount: number;
|
|
40
|
+
};
|
|
41
|
+
service: {
|
|
42
|
+
name: string;
|
|
43
|
+
version: string;
|
|
44
|
+
environment: string;
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Get smart defaults using direct VOILA_QUEUE_* environment access
|
|
49
|
+
* @llm-rule WHEN: App startup to get production-ready queue configuration
|
|
50
|
+
* @llm-rule AVOID: Calling repeatedly - validates environment each time, expensive operation
|
|
51
|
+
* @llm-rule NOTE: Called once at startup, cached globally for performance
|
|
52
|
+
*/
|
|
53
|
+
export declare function getSmartDefaults(): QueueConfig;
|
|
54
|
+
/**
|
|
55
|
+
* Validate environment variables (like auth module validation)
|
|
56
|
+
* @llm-rule WHEN: App startup to catch configuration errors early
|
|
57
|
+
* @llm-rule AVOID: Skipping validation - invalid config causes silent failures
|
|
58
|
+
*/
|
|
59
|
+
export declare function validateEnvironment(): void;
|
|
60
|
+
/**
|
|
61
|
+
* Gets smart defaults with validation
|
|
62
|
+
* @llm-rule WHEN: App startup to get production-ready queue configuration
|
|
63
|
+
* @llm-rule AVOID: Calling repeatedly - expensive validation, cache the result
|
|
64
|
+
*/
|
|
65
|
+
export declare function getValidatedDefaults(): QueueConfig;
|
|
66
|
+
//# sourceMappingURL=defaults.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../src/queue/defaults.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,WAAW,WAAW;IAE1B,SAAS,EAAE,QAAQ,GAAG,OAAO,GAAG,UAAU,CAAC;IAG3C,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,OAAO,GAAG,aAAa,CAAC;IAGtC,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IAGrB,MAAM,EAAE;QACN,OAAO,EAAE,MAAM,CAAC;QAChB,eAAe,EAAE,MAAM,CAAC;KACzB,CAAC;IAEF,KAAK,EAAE;QACL,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;QACnB,SAAS,EAAE,MAAM,CAAC;QAClB,oBAAoB,EAAE,MAAM,CAAC;QAC7B,oBAAoB,EAAE,MAAM,CAAC;KAC9B,CAAC;IAEF,QAAQ,EAAE;QACR,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;QACnB,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;IAGF,MAAM,EAAE;QACN,OAAO,EAAE,OAAO,CAAC;QACjB,uBAAuB,EAAE,MAAM,CAAC;QAChC,eAAe,EAAE,MAAM,CAAC;QACxB,eAAe,EAAE,MAAM,CAAC;KACzB,CAAC;IAGF,OAAO,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;CACH;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,IAAI,WAAW,CAgE9C;AAmDD;;;;GAIG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAgD1C;AAwCD;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,WAAW,CAGlD"}
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Smart defaults and environment validation for job queue management
|
|
3
|
+
* @module @bloomneo/appkit/queue
|
|
4
|
+
* @file src/queue/defaults.ts
|
|
5
|
+
*
|
|
6
|
+
* @llm-rule WHEN: App startup - need to parse VOILA_QUEUE_* environment variables and detect transports
|
|
7
|
+
* @llm-rule AVOID: Calling multiple times - expensive validation, use lazy loading in get()
|
|
8
|
+
* @llm-rule NOTE: Called once at startup, cached globally for performance like auth/logging modules
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Get smart defaults using direct VOILA_QUEUE_* environment access
|
|
12
|
+
* @llm-rule WHEN: App startup to get production-ready queue configuration
|
|
13
|
+
* @llm-rule AVOID: Calling repeatedly - validates environment each time, expensive operation
|
|
14
|
+
* @llm-rule NOTE: Called once at startup, cached globally for performance
|
|
15
|
+
*/
|
|
16
|
+
export function getSmartDefaults() {
|
|
17
|
+
// Direct environment access with smart defaults (like auth module)
|
|
18
|
+
const nodeEnv = process.env.NODE_ENV || 'development';
|
|
19
|
+
const isProduction = nodeEnv === 'production';
|
|
20
|
+
const isDevelopment = nodeEnv === 'development';
|
|
21
|
+
const isTest = nodeEnv === 'test';
|
|
22
|
+
// Auto-detect transport
|
|
23
|
+
const transport = getTransport();
|
|
24
|
+
// Auto-detect worker mode
|
|
25
|
+
const workerEnabled = getWorkerEnabled(isDevelopment);
|
|
26
|
+
return {
|
|
27
|
+
transport,
|
|
28
|
+
// Core settings - direct env access
|
|
29
|
+
concurrency: parseInt(process.env.VOILA_QUEUE_CONCURRENCY || (isProduction ? '10' : '5')),
|
|
30
|
+
maxAttempts: parseInt(process.env.VOILA_QUEUE_MAX_ATTEMPTS || '3'),
|
|
31
|
+
retryDelay: parseInt(process.env.VOILA_QUEUE_RETRY_DELAY || '5000'),
|
|
32
|
+
retryBackoff: process.env.VOILA_QUEUE_RETRY_BACKOFF || 'exponential',
|
|
33
|
+
// Job management - direct env access
|
|
34
|
+
defaultPriority: parseInt(process.env.VOILA_QUEUE_DEFAULT_PRIORITY || '0'),
|
|
35
|
+
removeOnComplete: parseInt(process.env.VOILA_QUEUE_REMOVE_COMPLETE || (isProduction ? '100' : '10')),
|
|
36
|
+
removeOnFail: parseInt(process.env.VOILA_QUEUE_REMOVE_FAILED || (isProduction ? '500' : '50')),
|
|
37
|
+
// Memory transport config - direct env access
|
|
38
|
+
memory: {
|
|
39
|
+
maxJobs: parseInt(process.env.VOILA_QUEUE_MEMORY_MAX_JOBS || (isDevelopment ? '1000' : '100')),
|
|
40
|
+
cleanupInterval: parseInt(process.env.VOILA_QUEUE_MEMORY_CLEANUP || '30000'),
|
|
41
|
+
},
|
|
42
|
+
// Redis transport config - direct env access
|
|
43
|
+
redis: {
|
|
44
|
+
url: process.env.REDIS_URL || null,
|
|
45
|
+
keyPrefix: process.env.VOILA_QUEUE_REDIS_PREFIX || 'queue',
|
|
46
|
+
maxRetriesPerRequest: parseInt(process.env.VOILA_QUEUE_REDIS_RETRIES || '3'),
|
|
47
|
+
retryDelayOnFailover: parseInt(process.env.VOILA_QUEUE_REDIS_FAILOVER_DELAY || '100'),
|
|
48
|
+
},
|
|
49
|
+
// Database transport config - direct env access
|
|
50
|
+
database: {
|
|
51
|
+
url: process.env.DATABASE_URL || null,
|
|
52
|
+
tableName: process.env.VOILA_QUEUE_DB_TABLE || 'queue_jobs',
|
|
53
|
+
batchSize: parseInt(process.env.VOILA_QUEUE_DB_BATCH || '50'),
|
|
54
|
+
pollInterval: parseInt(process.env.VOILA_QUEUE_DB_POLL || (isProduction ? '5000' : '2000')),
|
|
55
|
+
},
|
|
56
|
+
// Worker config - direct env access
|
|
57
|
+
worker: {
|
|
58
|
+
enabled: workerEnabled,
|
|
59
|
+
gracefulShutdownTimeout: parseInt(process.env.VOILA_QUEUE_SHUTDOWN_TIMEOUT || '30000'),
|
|
60
|
+
stalledInterval: parseInt(process.env.VOILA_QUEUE_STALLED_INTERVAL || '30000'),
|
|
61
|
+
maxStalledCount: parseInt(process.env.VOILA_QUEUE_MAX_STALLED || '1'),
|
|
62
|
+
},
|
|
63
|
+
// Service identification - direct env access
|
|
64
|
+
service: {
|
|
65
|
+
name: process.env.VOILA_SERVICE_NAME || process.env.npm_package_name || 'app',
|
|
66
|
+
version: process.env.VOILA_SERVICE_VERSION || process.env.npm_package_version || '1.0.0',
|
|
67
|
+
environment: nodeEnv,
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Auto-detect optimal transport based on available environment variables
|
|
73
|
+
* @llm-rule WHEN: Need to determine which transport to use automatically
|
|
74
|
+
* @llm-rule AVOID: Manual transport selection - auto-detection handles most cases correctly
|
|
75
|
+
*/
|
|
76
|
+
function getTransport() {
|
|
77
|
+
// Manual override wins (like auth module pattern)
|
|
78
|
+
const manual = process.env.VOILA_QUEUE_TRANSPORT?.toLowerCase();
|
|
79
|
+
if (manual === 'memory' || manual === 'redis' || manual === 'database') {
|
|
80
|
+
return manual;
|
|
81
|
+
}
|
|
82
|
+
// Auto-detection logic (production-first)
|
|
83
|
+
if (process.env.REDIS_URL) {
|
|
84
|
+
return 'redis'; // Best for production - persistent, distributed
|
|
85
|
+
}
|
|
86
|
+
if (process.env.DATABASE_URL) {
|
|
87
|
+
return 'database'; // Good for simple setups - persistent, familiar
|
|
88
|
+
}
|
|
89
|
+
return 'memory'; // Development fallback - simple, no setup
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Auto-detect if worker mode should be enabled
|
|
93
|
+
* @llm-rule WHEN: Need to determine if this instance should process jobs
|
|
94
|
+
* @llm-rule AVOID: Always enabling workers - can cause resource conflicts
|
|
95
|
+
*/
|
|
96
|
+
function getWorkerEnabled(isDevelopment) {
|
|
97
|
+
// Explicit worker mode setting
|
|
98
|
+
const workerEnv = process.env.VOILA_QUEUE_WORKER;
|
|
99
|
+
if (workerEnv !== undefined) {
|
|
100
|
+
return workerEnv.toLowerCase() === 'true';
|
|
101
|
+
}
|
|
102
|
+
// Auto-detection based on environment
|
|
103
|
+
if (isDevelopment) {
|
|
104
|
+
return true; // Development: process jobs in same process
|
|
105
|
+
}
|
|
106
|
+
// Production: only enable if explicitly set or in worker-specific deployments
|
|
107
|
+
const isWorkerDeployment = process.env.DYNO?.includes('worker') || // Heroku
|
|
108
|
+
process.env.CONTAINER_NAME?.includes('worker') || // Docker
|
|
109
|
+
process.env.SERVICE_NAME?.includes('worker'); // K8s
|
|
110
|
+
return isWorkerDeployment || false;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Validate environment variables (like auth module validation)
|
|
114
|
+
* @llm-rule WHEN: App startup to catch configuration errors early
|
|
115
|
+
* @llm-rule AVOID: Skipping validation - invalid config causes silent failures
|
|
116
|
+
*/
|
|
117
|
+
export function validateEnvironment() {
|
|
118
|
+
// Validate concurrency
|
|
119
|
+
const concurrency = process.env.VOILA_QUEUE_CONCURRENCY;
|
|
120
|
+
if (concurrency && (isNaN(parseInt(concurrency)) || parseInt(concurrency) < 1 || parseInt(concurrency) > 100)) {
|
|
121
|
+
throw new Error(`Invalid VOILA_QUEUE_CONCURRENCY: "${concurrency}". Must be number between 1 and 100`);
|
|
122
|
+
}
|
|
123
|
+
// Validate max attempts
|
|
124
|
+
const maxAttempts = process.env.VOILA_QUEUE_MAX_ATTEMPTS;
|
|
125
|
+
if (maxAttempts && (isNaN(parseInt(maxAttempts)) || parseInt(maxAttempts) < 1 || parseInt(maxAttempts) > 10)) {
|
|
126
|
+
throw new Error(`Invalid VOILA_QUEUE_MAX_ATTEMPTS: "${maxAttempts}". Must be number between 1 and 10`);
|
|
127
|
+
}
|
|
128
|
+
// Validate retry backoff
|
|
129
|
+
const backoff = process.env.VOILA_QUEUE_RETRY_BACKOFF;
|
|
130
|
+
if (backoff && !['fixed', 'exponential'].includes(backoff)) {
|
|
131
|
+
throw new Error(`Invalid VOILA_QUEUE_RETRY_BACKOFF: "${backoff}". Must be: fixed, exponential`);
|
|
132
|
+
}
|
|
133
|
+
// Validate transport selection
|
|
134
|
+
const transport = process.env.VOILA_QUEUE_TRANSPORT;
|
|
135
|
+
if (transport && !['memory', 'redis', 'database'].includes(transport)) {
|
|
136
|
+
throw new Error(`Invalid VOILA_QUEUE_TRANSPORT: "${transport}". Must be: memory, redis, database`);
|
|
137
|
+
}
|
|
138
|
+
// Validate Redis URL if provided
|
|
139
|
+
const redisUrl = process.env.REDIS_URL;
|
|
140
|
+
if (redisUrl && !isValidRedisUrl(redisUrl)) {
|
|
141
|
+
throw new Error(`Invalid REDIS_URL: "${redisUrl}". Must be valid Redis connection string`);
|
|
142
|
+
}
|
|
143
|
+
// Validate Database URL if provided
|
|
144
|
+
const dbUrl = process.env.DATABASE_URL;
|
|
145
|
+
if (dbUrl && !isValidDatabaseUrl(dbUrl)) {
|
|
146
|
+
throw new Error(`Invalid DATABASE_URL: "${dbUrl}". Must be valid database connection string`);
|
|
147
|
+
}
|
|
148
|
+
// Validate worker setting
|
|
149
|
+
const worker = process.env.VOILA_QUEUE_WORKER;
|
|
150
|
+
if (worker && !['true', 'false'].includes(worker.toLowerCase())) {
|
|
151
|
+
throw new Error(`Invalid VOILA_QUEUE_WORKER: "${worker}". Must be: true, false`);
|
|
152
|
+
}
|
|
153
|
+
// Validate numeric values
|
|
154
|
+
validateNumericEnv('VOILA_QUEUE_RETRY_DELAY', 1000, 300000); // 1s to 5min
|
|
155
|
+
validateNumericEnv('VOILA_QUEUE_MEMORY_MAX_JOBS', 100, 100000); // 100 to 100k
|
|
156
|
+
validateNumericEnv('VOILA_QUEUE_DB_POLL', 1000, 60000); // 1s to 1min
|
|
157
|
+
validateNumericEnv('VOILA_QUEUE_SHUTDOWN_TIMEOUT', 5000, 120000); // 5s to 2min
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Validate numeric environment variable
|
|
161
|
+
*/
|
|
162
|
+
function validateNumericEnv(name, min, max) {
|
|
163
|
+
const value = process.env[name];
|
|
164
|
+
if (!value)
|
|
165
|
+
return;
|
|
166
|
+
const num = parseInt(value);
|
|
167
|
+
if (isNaN(num) || num < min || num > max) {
|
|
168
|
+
throw new Error(`Invalid ${name}: "${value}". Must be number between ${min} and ${max}`);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Validate Redis URL format
|
|
173
|
+
*/
|
|
174
|
+
function isValidRedisUrl(url) {
|
|
175
|
+
try {
|
|
176
|
+
const parsed = new URL(url);
|
|
177
|
+
return parsed.protocol === 'redis:' || parsed.protocol === 'rediss:';
|
|
178
|
+
}
|
|
179
|
+
catch {
|
|
180
|
+
return false;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Validate database URL format (like logging module)
|
|
185
|
+
*/
|
|
186
|
+
function isValidDatabaseUrl(url) {
|
|
187
|
+
try {
|
|
188
|
+
const parsed = new URL(url);
|
|
189
|
+
const validProtocols = ['postgres:', 'postgresql:', 'mysql:', 'sqlite:'];
|
|
190
|
+
return validProtocols.includes(parsed.protocol);
|
|
191
|
+
}
|
|
192
|
+
catch {
|
|
193
|
+
return false;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Gets smart defaults with validation
|
|
198
|
+
* @llm-rule WHEN: App startup to get production-ready queue configuration
|
|
199
|
+
* @llm-rule AVOID: Calling repeatedly - expensive validation, cache the result
|
|
200
|
+
*/
|
|
201
|
+
export function getValidatedDefaults() {
|
|
202
|
+
validateEnvironment();
|
|
203
|
+
return getSmartDefaults();
|
|
204
|
+
}
|
|
205
|
+
//# sourceMappingURL=defaults.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defaults.js","sourceRoot":"","sources":["../../src/queue/defaults.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ultra-simple job queuing that just works with automatic transport detection
|
|
3
|
+
* @module @bloomneo/appkit/queue
|
|
4
|
+
* @file src/queue/index.ts
|
|
5
|
+
*
|
|
6
|
+
* @llm-rule WHEN: Building apps that need background job processing
|
|
7
|
+
* @llm-rule AVOID: Complex queue setups with multiple libraries - this handles everything automatically
|
|
8
|
+
* @llm-rule NOTE: Uses queueClass.get() pattern like other modules - get() → queue.add() → queue.process() → done
|
|
9
|
+
* @llm-rule NOTE: Auto-detects transports: Memory (dev) → Redis (REDIS_URL) → Database (DATABASE_URL)
|
|
10
|
+
* @llm-rule NOTE: Common pattern - queueClass.get() → queue.add() → queue.process() → automatic retry + dead letter queue
|
|
11
|
+
*/
|
|
12
|
+
import { type QueueConfig } from './defaults.js';
|
|
13
|
+
export interface JobData {
|
|
14
|
+
[key: string]: any;
|
|
15
|
+
}
|
|
16
|
+
export interface JobOptions {
|
|
17
|
+
priority?: number;
|
|
18
|
+
delay?: number;
|
|
19
|
+
attempts?: number;
|
|
20
|
+
backoff?: 'fixed' | 'exponential';
|
|
21
|
+
removeOnComplete?: number;
|
|
22
|
+
removeOnFail?: number;
|
|
23
|
+
}
|
|
24
|
+
export interface JobHandler<T = JobData> {
|
|
25
|
+
(data: T): Promise<any> | any;
|
|
26
|
+
}
|
|
27
|
+
export interface Queue {
|
|
28
|
+
add<T = JobData>(jobType: string, data: T, options?: JobOptions): Promise<string>;
|
|
29
|
+
process<T = JobData>(jobType: string, handler: JobHandler<T>): void;
|
|
30
|
+
schedule<T = JobData>(jobType: string, data: T, delay: number): Promise<string>;
|
|
31
|
+
pause(jobType?: string): Promise<void>;
|
|
32
|
+
resume(jobType?: string): Promise<void>;
|
|
33
|
+
getStats(jobType?: string): Promise<QueueStats>;
|
|
34
|
+
getJobs(status: JobStatus, jobType?: string): Promise<JobInfo[]>;
|
|
35
|
+
retry(jobId: string): Promise<void>;
|
|
36
|
+
remove(jobId: string): Promise<void>;
|
|
37
|
+
clean(status: JobStatus, grace?: number): Promise<void>;
|
|
38
|
+
close(): Promise<void>;
|
|
39
|
+
}
|
|
40
|
+
export interface QueueStats {
|
|
41
|
+
waiting: number;
|
|
42
|
+
active: number;
|
|
43
|
+
completed: number;
|
|
44
|
+
failed: number;
|
|
45
|
+
delayed: number;
|
|
46
|
+
paused: number;
|
|
47
|
+
}
|
|
48
|
+
export interface JobInfo {
|
|
49
|
+
id: string;
|
|
50
|
+
type: string;
|
|
51
|
+
data: JobData;
|
|
52
|
+
status: JobStatus;
|
|
53
|
+
progress?: number;
|
|
54
|
+
attempts: number;
|
|
55
|
+
maxAttempts: number;
|
|
56
|
+
error?: any;
|
|
57
|
+
createdAt: Date;
|
|
58
|
+
processedAt?: Date;
|
|
59
|
+
completedAt?: Date;
|
|
60
|
+
failedAt?: Date;
|
|
61
|
+
}
|
|
62
|
+
export type JobStatus = 'waiting' | 'active' | 'completed' | 'failed' | 'delayed' | 'paused';
|
|
63
|
+
/**
|
|
64
|
+
* Get queuing instance - the only function you need to learn
|
|
65
|
+
* Transport auto-detection: Memory → Redis → Database based on environment
|
|
66
|
+
* @llm-rule WHEN: Starting any background job operation - this is your main entry point
|
|
67
|
+
* @llm-rule AVOID: Creating QueueClass directly - always use this function
|
|
68
|
+
* @llm-rule NOTE: Typical flow - get() → queue.add() → queue.process() → automatic handling
|
|
69
|
+
*/
|
|
70
|
+
declare function get(overrides?: Partial<QueueConfig>): Queue;
|
|
71
|
+
/**
|
|
72
|
+
* Reset global instance (useful for testing or config changes)
|
|
73
|
+
* @llm-rule WHEN: Testing queuing logic with different configurations
|
|
74
|
+
* @llm-rule AVOID: Using in production - only for tests and development
|
|
75
|
+
*/
|
|
76
|
+
declare function reset(newConfig?: Partial<QueueConfig>): Queue;
|
|
77
|
+
/**
|
|
78
|
+
* Get active transport type for debugging
|
|
79
|
+
* @llm-rule WHEN: Need to see which transport is running (memory, redis, database)
|
|
80
|
+
* @llm-rule AVOID: Using for business logic - this is for debugging only
|
|
81
|
+
*/
|
|
82
|
+
declare function getActiveTransport(): string;
|
|
83
|
+
/**
|
|
84
|
+
* Check if specific transport is active
|
|
85
|
+
* @llm-rule WHEN: Conditionally handling jobs based on transport capability
|
|
86
|
+
* @llm-rule AVOID: Complex transport detection - just add jobs normally, transports auto-handle
|
|
87
|
+
*/
|
|
88
|
+
declare function hasTransport(name: string): boolean;
|
|
89
|
+
/**
|
|
90
|
+
* Get current configuration for debugging
|
|
91
|
+
* @llm-rule WHEN: Debugging queuing setup or checking environment detection
|
|
92
|
+
* @llm-rule AVOID: Using for runtime decisions - configuration is set at startup
|
|
93
|
+
*/
|
|
94
|
+
declare function getConfig(): QueueConfig | null;
|
|
95
|
+
/**
|
|
96
|
+
* Clear all queues and close transports - essential for testing
|
|
97
|
+
* @llm-rule WHEN: Testing queuing logic or app shutdown
|
|
98
|
+
* @llm-rule AVOID: Using in production without graceful shutdown
|
|
99
|
+
*/
|
|
100
|
+
declare function clear(): Promise<void>;
|
|
101
|
+
/**
|
|
102
|
+
* Get health status of queuing system
|
|
103
|
+
* @llm-rule WHEN: Health checks or monitoring dashboard
|
|
104
|
+
* @llm-rule AVOID: Frequent polling - expensive operation for some transports
|
|
105
|
+
*/
|
|
106
|
+
declare function getHealth(): {
|
|
107
|
+
status: 'healthy' | 'degraded' | 'unhealthy';
|
|
108
|
+
transport: string;
|
|
109
|
+
message?: string;
|
|
110
|
+
};
|
|
111
|
+
/**
|
|
112
|
+
* Single queuing export with minimal functionality (like auth module)
|
|
113
|
+
*/
|
|
114
|
+
export declare const queueClass: {
|
|
115
|
+
readonly get: typeof get;
|
|
116
|
+
readonly reset: typeof reset;
|
|
117
|
+
readonly clear: typeof clear;
|
|
118
|
+
readonly getActiveTransport: typeof getActiveTransport;
|
|
119
|
+
readonly hasTransport: typeof hasTransport;
|
|
120
|
+
readonly getConfig: typeof getConfig;
|
|
121
|
+
readonly getHealth: typeof getHealth;
|
|
122
|
+
};
|
|
123
|
+
export {};
|
|
124
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/queue/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ultra-simple job queuing that just works with automatic transport detection
|
|
3
|
+
* @module @bloomneo/appkit/queue
|
|
4
|
+
* @file src/queue/index.ts
|
|
5
|
+
*
|
|
6
|
+
* @llm-rule WHEN: Building apps that need background job processing
|
|
7
|
+
* @llm-rule AVOID: Complex queue setups with multiple libraries - this handles everything automatically
|
|
8
|
+
* @llm-rule NOTE: Uses queueClass.get() pattern like other modules - get() → queue.add() → queue.process() → done
|
|
9
|
+
* @llm-rule NOTE: Auto-detects transports: Memory (dev) → Redis (REDIS_URL) → Database (DATABASE_URL)
|
|
10
|
+
* @llm-rule NOTE: Common pattern - queueClass.get() → queue.add() → queue.process() → automatic retry + dead letter queue
|
|
11
|
+
*/
|
|
12
|
+
import { QueueClass } from './queue.js';
|
|
13
|
+
import { getSmartDefaults } from './defaults.js';
|
|
14
|
+
// Global queuing instance for performance (like auth module)
|
|
15
|
+
let globalQueuing = null;
|
|
16
|
+
/**
|
|
17
|
+
* Get queuing instance - the only function you need to learn
|
|
18
|
+
* Transport auto-detection: Memory → Redis → Database based on environment
|
|
19
|
+
* @llm-rule WHEN: Starting any background job operation - this is your main entry point
|
|
20
|
+
* @llm-rule AVOID: Creating QueueClass directly - always use this function
|
|
21
|
+
* @llm-rule NOTE: Typical flow - get() → queue.add() → queue.process() → automatic handling
|
|
22
|
+
*/
|
|
23
|
+
function get(overrides = {}) {
|
|
24
|
+
// Lazy initialization - parse environment once (like auth)
|
|
25
|
+
if (!globalQueuing) {
|
|
26
|
+
const defaults = getSmartDefaults();
|
|
27
|
+
const config = { ...defaults, ...overrides };
|
|
28
|
+
globalQueuing = new QueueClass(config);
|
|
29
|
+
}
|
|
30
|
+
return globalQueuing;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Reset global instance (useful for testing or config changes)
|
|
34
|
+
* @llm-rule WHEN: Testing queuing logic with different configurations
|
|
35
|
+
* @llm-rule AVOID: Using in production - only for tests and development
|
|
36
|
+
*/
|
|
37
|
+
function reset(newConfig = {}) {
|
|
38
|
+
if (globalQueuing) {
|
|
39
|
+
// Close existing instance gracefully
|
|
40
|
+
globalQueuing.close();
|
|
41
|
+
}
|
|
42
|
+
const defaults = getSmartDefaults();
|
|
43
|
+
const config = { ...defaults, ...newConfig };
|
|
44
|
+
globalQueuing = new QueueClass(config);
|
|
45
|
+
return globalQueuing;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Get active transport type for debugging
|
|
49
|
+
* @llm-rule WHEN: Need to see which transport is running (memory, redis, database)
|
|
50
|
+
* @llm-rule AVOID: Using for business logic - this is for debugging only
|
|
51
|
+
*/
|
|
52
|
+
function getActiveTransport() {
|
|
53
|
+
if (!globalQueuing) {
|
|
54
|
+
return 'none';
|
|
55
|
+
}
|
|
56
|
+
return globalQueuing.getActiveTransport();
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Check if specific transport is active
|
|
60
|
+
* @llm-rule WHEN: Conditionally handling jobs based on transport capability
|
|
61
|
+
* @llm-rule AVOID: Complex transport detection - just add jobs normally, transports auto-handle
|
|
62
|
+
*/
|
|
63
|
+
function hasTransport(name) {
|
|
64
|
+
if (!globalQueuing) {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
return globalQueuing.hasTransport(name);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Get current configuration for debugging
|
|
71
|
+
* @llm-rule WHEN: Debugging queuing setup or checking environment detection
|
|
72
|
+
* @llm-rule AVOID: Using for runtime decisions - configuration is set at startup
|
|
73
|
+
*/
|
|
74
|
+
function getConfig() {
|
|
75
|
+
if (!globalQueuing) {
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
return globalQueuing.getConfig();
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Clear all queues and close transports - essential for testing
|
|
82
|
+
* @llm-rule WHEN: Testing queuing logic or app shutdown
|
|
83
|
+
* @llm-rule AVOID: Using in production without graceful shutdown
|
|
84
|
+
*/
|
|
85
|
+
async function clear() {
|
|
86
|
+
if (globalQueuing) {
|
|
87
|
+
await globalQueuing.close();
|
|
88
|
+
globalQueuing = null;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Get health status of queuing system
|
|
93
|
+
* @llm-rule WHEN: Health checks or monitoring dashboard
|
|
94
|
+
* @llm-rule AVOID: Frequent polling - expensive operation for some transports
|
|
95
|
+
*/
|
|
96
|
+
function getHealth() {
|
|
97
|
+
if (!globalQueuing) {
|
|
98
|
+
return { status: 'unhealthy', transport: 'none', message: 'Queuing not initialized' };
|
|
99
|
+
}
|
|
100
|
+
return globalQueuing.getHealth();
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Single queuing export with minimal functionality (like auth module)
|
|
104
|
+
*/
|
|
105
|
+
export const queueClass = {
|
|
106
|
+
// Core method (like auth.get())
|
|
107
|
+
get,
|
|
108
|
+
// Utility methods
|
|
109
|
+
reset,
|
|
110
|
+
clear,
|
|
111
|
+
getActiveTransport,
|
|
112
|
+
hasTransport,
|
|
113
|
+
getConfig,
|
|
114
|
+
getHealth,
|
|
115
|
+
};
|
|
116
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/queue/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAoB,MAAM,eAAe,CAAC;AAEnE,6DAA6D;AAC7D,IAAI,aAAa,GAAsB,IAAI,CAAC;AA2D5C;;;;;;GAMG;AACH,SAAS,GAAG,CAAC,YAAkC,EAAE;IAC/C,2DAA2D;IAC3D,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,MAAM,QAAQ,GAAG,gBAAgB,EAAE,CAAC;QACpC,MAAM,MAAM,GAAgB,EAAE,GAAG,QAAQ,EAAE,GAAG,SAAS,EAAE,CAAC;QAC1D,aAAa,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;IACzC,CAAC;IAED,OAAO,aAAa,CAAC;AACvB,CAAC;AAED;;;;GAIG;AACH,SAAS,KAAK,CAAC,YAAkC,EAAE;IACjD,IAAI,aAAa,EAAE,CAAC;QAClB,qCAAqC;QACrC,aAAa,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;IAED,MAAM,QAAQ,GAAG,gBAAgB,EAAE,CAAC;IACpC,MAAM,MAAM,GAAgB,EAAE,GAAG,QAAQ,EAAE,GAAG,SAAS,EAAE,CAAC;IAC1D,aAAa,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;IACvC,OAAO,aAAa,CAAC;AACvB,CAAC;AAED;;;;GAIG;AACH,SAAS,kBAAkB;IACzB,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,OAAO,aAAa,CAAC,kBAAkB,EAAE,CAAC;AAC5C,CAAC;AAED;;;;GAIG;AACH,SAAS,YAAY,CAAC,IAAY;IAChC,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,aAAa,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;AAC1C,CAAC;AAED;;;;GAIG;AACH,SAAS,SAAS;IAChB,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,aAAa,CAAC,SAAS,EAAE,CAAC;AACnC,CAAC;AAED;;;;GAIG;AACH,KAAK,UAAU,KAAK;IAClB,IAAI,aAAa,EAAE,CAAC;QAClB,MAAM,aAAa,CAAC,KAAK,EAAE,CAAC;QAC5B,aAAa,GAAG,IAAI,CAAC;IACvB,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,SAAS,SAAS;IAChB,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,yBAAyB,EAAE,CAAC;IACxF,CAAC;IAED,OAAO,aAAa,CAAC,SAAS,EAAE,CAAC;AACnC,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,gCAAgC;IAChC,GAAG;IAEH,kBAAkB;IAClB,KAAK;IACL,KAAK;IACL,kBAAkB;IAClB,YAAY;IACZ,SAAS;IACT,SAAS;CACD,CAAC"}
|