@taicode/common-server 3.7.7 → 3.7.10
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/output/context/index.d.ts +6 -0
- package/output/context/index.d.ts.map +1 -0
- package/output/context/index.js +14 -0
- package/output/context/index.test.d.ts +2 -0
- package/output/context/index.test.d.ts.map +1 -0
- package/output/context/index.test.js +14 -0
- package/output/index.d.ts +5 -0
- package/output/index.d.ts.map +1 -0
- package/output/index.js +5 -0
- package/output/rate-limiter/index.d.ts +4 -0
- package/output/rate-limiter/index.d.ts.map +1 -0
- package/output/rate-limiter/index.js +3 -0
- package/output/rate-limiter/memory-store.d.ts +12 -0
- package/output/rate-limiter/memory-store.d.ts.map +1 -0
- package/output/rate-limiter/memory-store.js +46 -0
- package/output/rate-limiter/rate-limiter.d.ts +17 -0
- package/output/rate-limiter/rate-limiter.d.ts.map +1 -0
- package/output/rate-limiter/rate-limiter.js +64 -0
- package/output/rate-limiter/types.d.ts +27 -0
- package/output/rate-limiter/types.d.ts.map +1 -0
- package/output/rate-limiter/types.js +1 -0
- package/output/redis-queue/index.d.ts +8 -0
- package/output/redis-queue/index.d.ts.map +1 -0
- package/output/redis-queue/index.js +6 -0
- package/output/redis-queue/redis-queue-batch-consumer.d.ts +97 -0
- package/output/redis-queue/redis-queue-batch-consumer.d.ts.map +1 -0
- package/output/redis-queue/redis-queue-batch-consumer.js +341 -0
- package/output/redis-queue/redis-queue-batch-consumer.test.d.ts +26 -0
- package/output/redis-queue/redis-queue-batch-consumer.test.d.ts.map +1 -0
- package/output/redis-queue/redis-queue-batch-consumer.test.js +341 -0
- package/output/redis-queue/redis-queue-common.d.ts +73 -0
- package/output/redis-queue/redis-queue-common.d.ts.map +1 -0
- package/output/redis-queue/redis-queue-common.js +303 -0
- package/output/redis-queue/redis-queue-common.test.d.ts +19 -0
- package/output/redis-queue/redis-queue-common.test.d.ts.map +1 -0
- package/output/redis-queue/redis-queue-common.test.js +585 -0
- package/output/redis-queue/redis-queue-consumer.d.ts +95 -0
- package/output/redis-queue/redis-queue-consumer.d.ts.map +1 -0
- package/output/redis-queue/redis-queue-consumer.js +327 -0
- package/output/redis-queue/redis-queue-consumer.test.d.ts +26 -0
- package/output/redis-queue/redis-queue-consumer.test.d.ts.map +1 -0
- package/output/redis-queue/redis-queue-consumer.test.js +316 -0
- package/output/redis-queue/redis-queue-provider.d.ts +69 -0
- package/output/redis-queue/redis-queue-provider.d.ts.map +1 -0
- package/output/redis-queue/redis-queue-provider.js +205 -0
- package/output/redis-queue/redis-queue-provider.test.d.ts +28 -0
- package/output/redis-queue/redis-queue-provider.test.d.ts.map +1 -0
- package/output/redis-queue/redis-queue-provider.test.js +149 -0
- package/output/redis-queue/test-helpers.d.ts +112 -0
- package/output/redis-queue/test-helpers.d.ts.map +1 -0
- package/output/redis-queue/test-helpers.js +242 -0
- package/output/redis-queue/test-helpers.test.d.ts +28 -0
- package/output/redis-queue/test-helpers.test.d.ts.map +1 -0
- package/output/redis-queue/test-helpers.test.js +572 -0
- package/output/redis-queue/types.d.ts +146 -0
- package/output/redis-queue/types.d.ts.map +1 -0
- package/output/redis-queue/types.js +1 -0
- package/output/schema/index.d.ts +177 -0
- package/output/schema/index.d.ts.map +1 -0
- package/output/schema/index.js +180 -0
- package/package.json +8 -5
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../source/context/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAEhE,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,iBAAiB,CAAA;CACvB;AAcD,wBAAgB,aAAa,CAAC,OAAO,EAAE,cAAc,GAAG,cAAc,CAErE"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
const fallbackLogger = {
|
|
2
|
+
trace: () => { },
|
|
3
|
+
debug: () => { },
|
|
4
|
+
info: () => { },
|
|
5
|
+
warn: () => { },
|
|
6
|
+
error: () => { },
|
|
7
|
+
fatal: () => { },
|
|
8
|
+
child: () => fallbackLogger,
|
|
9
|
+
level: 'info',
|
|
10
|
+
silent: () => { },
|
|
11
|
+
};
|
|
12
|
+
export function createContext(request) {
|
|
13
|
+
return { log: request.log || fallbackLogger };
|
|
14
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../../source/context/index.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { createContext } from './index.js';
|
|
3
|
+
describe('createContext', () => {
|
|
4
|
+
it('uses the request logger when one is available', () => {
|
|
5
|
+
const log = { info: () => { } };
|
|
6
|
+
const context = createContext({ log });
|
|
7
|
+
expect(context.log).toBe(log);
|
|
8
|
+
});
|
|
9
|
+
it('provides a fallback logger for lightweight test requests', () => {
|
|
10
|
+
const context = createContext({ log: undefined });
|
|
11
|
+
expect(context.log.level).toBe('info');
|
|
12
|
+
expect(() => context.log.info('message')).not.toThrow();
|
|
13
|
+
});
|
|
14
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../source/index.ts"],"names":[],"mappings":"AACA,cAAc,mBAAmB,CAAA;AACjC,cAAc,wBAAwB,CAAA;AACtC,cAAc,yBAAyB,CAAA;AACvC,cAAc,oBAAoB,CAAA"}
|
package/output/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../source/rate-limiter/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,cAAc,mBAAmB,CAAA;AACjC,cAAc,mBAAmB,CAAA"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { RateLimitInfo, RateLimitStore } from './types.js';
|
|
2
|
+
export declare class MemoryRateLimitStore implements RateLimitStore {
|
|
3
|
+
private store;
|
|
4
|
+
private cleanupInterval;
|
|
5
|
+
constructor(cleanupIntervalMs?: number);
|
|
6
|
+
get(key: string): Promise<RateLimitInfo | null>;
|
|
7
|
+
set(key: string, info: RateLimitInfo): Promise<void>;
|
|
8
|
+
delete(key: string): Promise<void>;
|
|
9
|
+
cleanup(): Promise<void>;
|
|
10
|
+
destroy(): void;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=memory-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-store.d.ts","sourceRoot":"","sources":["../../source/rate-limiter/memory-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAO/D,qBAAa,oBAAqB,YAAW,cAAc;IACzD,OAAO,CAAC,KAAK,CAAsC;IACnD,OAAO,CAAC,eAAe,CAA8B;gBAEzC,iBAAiB,SAAQ;IAY/B,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAY/C,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAKpD,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIlC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAS9B,OAAO,IAAI,IAAI;CAOhB"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export class MemoryRateLimitStore {
|
|
2
|
+
store = new Map();
|
|
3
|
+
cleanupInterval = null;
|
|
4
|
+
constructor(cleanupIntervalMs = 60000) {
|
|
5
|
+
// 定期清理过期数据
|
|
6
|
+
this.cleanupInterval = setInterval(() => {
|
|
7
|
+
this.cleanup();
|
|
8
|
+
}, cleanupIntervalMs);
|
|
9
|
+
// 防止内存泄漏
|
|
10
|
+
if (this.cleanupInterval.unref) {
|
|
11
|
+
this.cleanupInterval.unref();
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
async get(key) {
|
|
15
|
+
const entry = this.store.get(key);
|
|
16
|
+
if (!entry)
|
|
17
|
+
return null;
|
|
18
|
+
if (Date.now() > entry.expiresAt) {
|
|
19
|
+
this.store.delete(key);
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
return entry.info;
|
|
23
|
+
}
|
|
24
|
+
async set(key, info) {
|
|
25
|
+
const expiresAt = info.windowEnd.getTime();
|
|
26
|
+
this.store.set(key, { info, expiresAt });
|
|
27
|
+
}
|
|
28
|
+
async delete(key) {
|
|
29
|
+
this.store.delete(key);
|
|
30
|
+
}
|
|
31
|
+
async cleanup() {
|
|
32
|
+
const now = Date.now();
|
|
33
|
+
for (const [key, entry] of this.store.entries()) {
|
|
34
|
+
if (now > entry.expiresAt) {
|
|
35
|
+
this.store.delete(key);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
destroy() {
|
|
40
|
+
if (this.cleanupInterval) {
|
|
41
|
+
clearInterval(this.cleanupInterval);
|
|
42
|
+
this.cleanupInterval = null;
|
|
43
|
+
}
|
|
44
|
+
this.store.clear();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { RateLimitConfig, RateLimitInfo, RateLimiterOptions, RateLimitResult } from './types.js';
|
|
2
|
+
export declare class RateLimiter {
|
|
3
|
+
private store;
|
|
4
|
+
constructor(options?: RateLimiterOptions);
|
|
5
|
+
checkLimit(key: string, config: RateLimitConfig): Promise<RateLimitResult>;
|
|
6
|
+
resetLimit(key: string): Promise<void>;
|
|
7
|
+
getLimitInfo(key: string): Promise<RateLimitInfo | null>;
|
|
8
|
+
/**
|
|
9
|
+
* 检查多个限流键,取最严格的限制
|
|
10
|
+
*/
|
|
11
|
+
checkMultiLimit(keys: string[], config: RateLimitConfig): Promise<RateLimitResult>;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* 创建限流键的辅助函数
|
|
15
|
+
*/
|
|
16
|
+
export declare function createRateLimitKey(prefix: string, ...parts: string[]): string;
|
|
17
|
+
//# sourceMappingURL=rate-limiter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rate-limiter.d.ts","sourceRoot":"","sources":["../../source/rate-limiter/rate-limiter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,kBAAkB,EAAE,eAAe,EAAkB,MAAM,YAAY,CAAA;AAGrH,qBAAa,WAAW;IACtB,OAAO,CAAC,KAAK,CAAgB;gBAEjB,OAAO,GAAE,kBAAuB;IAItC,UAAU,CACd,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,eAAe,GACtB,OAAO,CAAC,eAAe,CAAC;IAoCrB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAItC,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAI9D;;OAEG;IACG,eAAe,CACnB,IAAI,EAAE,MAAM,EAAE,EACd,MAAM,EAAE,eAAe,GACtB,OAAO,CAAC,eAAe,CAAC;CAe5B;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAE7E"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { MemoryRateLimitStore } from './memory-store.js';
|
|
2
|
+
export class RateLimiter {
|
|
3
|
+
store;
|
|
4
|
+
constructor(options = {}) {
|
|
5
|
+
this.store = options.store || new MemoryRateLimitStore();
|
|
6
|
+
}
|
|
7
|
+
async checkLimit(key, config) {
|
|
8
|
+
const now = new Date();
|
|
9
|
+
const windowStart = new Date(now.getTime());
|
|
10
|
+
const windowEnd = new Date(now.getTime() + config.window * 1000);
|
|
11
|
+
// 获取当前计数
|
|
12
|
+
let currentInfo = await this.store.get(key);
|
|
13
|
+
// 如果没有记录,或者窗口已过期,创建新记录
|
|
14
|
+
if (!currentInfo || currentInfo.windowEnd < now) {
|
|
15
|
+
currentInfo = {
|
|
16
|
+
count: 0,
|
|
17
|
+
windowStart,
|
|
18
|
+
windowEnd,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
// 增加计数
|
|
22
|
+
currentInfo.count += 1;
|
|
23
|
+
// 保存到存储
|
|
24
|
+
await this.store.set(key, currentInfo);
|
|
25
|
+
// 计算是否允许
|
|
26
|
+
const allowed = currentInfo.count <= config.limit;
|
|
27
|
+
const remaining = Math.max(0, config.limit - currentInfo.count);
|
|
28
|
+
return {
|
|
29
|
+
allowed,
|
|
30
|
+
remaining,
|
|
31
|
+
resetAt: currentInfo.windowEnd,
|
|
32
|
+
limit: config.limit,
|
|
33
|
+
window: config.window,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
async resetLimit(key) {
|
|
37
|
+
await this.store.delete(key);
|
|
38
|
+
}
|
|
39
|
+
async getLimitInfo(key) {
|
|
40
|
+
return await this.store.get(key);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* 检查多个限流键,取最严格的限制
|
|
44
|
+
*/
|
|
45
|
+
async checkMultiLimit(keys, config) {
|
|
46
|
+
let strictestResult = null;
|
|
47
|
+
for (const key of keys) {
|
|
48
|
+
const result = await this.checkLimit(key, config);
|
|
49
|
+
if (!strictestResult || !result.allowed) {
|
|
50
|
+
strictestResult = result;
|
|
51
|
+
}
|
|
52
|
+
else if (result.remaining < strictestResult.remaining) {
|
|
53
|
+
strictestResult = result;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return strictestResult;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* 创建限流键的辅助函数
|
|
61
|
+
*/
|
|
62
|
+
export function createRateLimitKey(prefix, ...parts) {
|
|
63
|
+
return `rate-limit:${prefix}:${parts.join(':')}`;
|
|
64
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export interface RateLimitInfo {
|
|
2
|
+
count: number;
|
|
3
|
+
windowStart: Date;
|
|
4
|
+
windowEnd: Date;
|
|
5
|
+
}
|
|
6
|
+
export interface RateLimitResult {
|
|
7
|
+
allowed: boolean;
|
|
8
|
+
remaining: number;
|
|
9
|
+
resetAt: Date;
|
|
10
|
+
limit: number;
|
|
11
|
+
window: number;
|
|
12
|
+
}
|
|
13
|
+
export interface RateLimitStore {
|
|
14
|
+
get(key: string): Promise<RateLimitInfo | null>;
|
|
15
|
+
set(key: string, info: RateLimitInfo): Promise<void>;
|
|
16
|
+
delete(key: string): Promise<void>;
|
|
17
|
+
cleanup?(): Promise<void>;
|
|
18
|
+
}
|
|
19
|
+
export interface RateLimitConfig {
|
|
20
|
+
limit: number;
|
|
21
|
+
window: number;
|
|
22
|
+
lockout?: number;
|
|
23
|
+
}
|
|
24
|
+
export interface RateLimiterOptions {
|
|
25
|
+
store?: RateLimitStore;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../source/rate-limiter/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,IAAI,CAAA;IACjB,SAAS,EAAE,IAAI,CAAA;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,IAAI,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAAA;IAC/C,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACpD,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAClC,OAAO,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CAC1B;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,EAAE,cAAc,CAAA;CACvB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { RedisQueueProvider } from './redis-queue-provider.js';
|
|
2
|
+
export { RedisQueueConsumer } from './redis-queue-consumer.js';
|
|
3
|
+
export { RedisQueueBatchConsumer } from './redis-queue-batch-consumer.js';
|
|
4
|
+
export type { RedisQueueProviderConfig, RedisQueueConsumerConfig, BatchConsumerConfig } from './types.js';
|
|
5
|
+
export type { TaskData } from './types.js';
|
|
6
|
+
export type { RedisQueueRegistry } from './types.js';
|
|
7
|
+
export * as test from './test-helpers.js';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../source/redis-queue/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAA;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAA;AAC9D,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAA;AAGzE,YAAY,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAGzG,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAG1C,YAAY,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAGpD,OAAO,KAAK,IAAI,MAAM,mBAAmB,CAAA"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// 核心类导出
|
|
2
|
+
export { RedisQueueProvider } from './redis-queue-provider.js';
|
|
3
|
+
export { RedisQueueConsumer } from './redis-queue-consumer.js';
|
|
4
|
+
export { RedisQueueBatchConsumer } from './redis-queue-batch-consumer.js';
|
|
5
|
+
// 测试辅助函数导出
|
|
6
|
+
export * as test from './test-helpers.js';
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { RedisQueueCommon } from './redis-queue-common.js';
|
|
2
|
+
import type { BatchConsumerConfig, QueueStats, RedisQueueRegistry } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Redis 批量队列消费者
|
|
5
|
+
*
|
|
6
|
+
* 批量消费任务,每次处理多条
|
|
7
|
+
*
|
|
8
|
+
* @template R Registry 类型,默认为 RedisQueueRegistry
|
|
9
|
+
* @template K 队列键名类型
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* // 方式 1: 使用默认 RedisQueueRegistry
|
|
14
|
+
* const consumer = new RedisQueueBatchConsumer('email-queue', {
|
|
15
|
+
* redisUrl: 'redis://localhost:6379',
|
|
16
|
+
* batchSize: 50,
|
|
17
|
+
* handler: async (dataList) => {
|
|
18
|
+
* await sendEmailsBatch(dataList.map(d => d.to))
|
|
19
|
+
* return catchIt(() => {})
|
|
20
|
+
* }
|
|
21
|
+
* })
|
|
22
|
+
*
|
|
23
|
+
* // 方式 2: 使用自定义 Registry
|
|
24
|
+
* interface MyRegistry {
|
|
25
|
+
* 'order-queue': { orderId: string; amount: number }
|
|
26
|
+
* }
|
|
27
|
+
*
|
|
28
|
+
* const consumer = new RedisQueueBatchConsumer<MyRegistry, 'order-queue'>(
|
|
29
|
+
* 'order-queue',
|
|
30
|
+
* {
|
|
31
|
+
* redisUrl: 'redis://localhost:6379',
|
|
32
|
+
* batchSize: 50,
|
|
33
|
+
* handler: async (dataList) => {
|
|
34
|
+
* const total = dataList.reduce((sum, d) => sum + d.amount, 0)
|
|
35
|
+
* logger.info('Total amount:', total)
|
|
36
|
+
* return catchIt(() => {})
|
|
37
|
+
* }
|
|
38
|
+
* }
|
|
39
|
+
* )
|
|
40
|
+
*
|
|
41
|
+
* await consumer.connect() // 自动开始消费
|
|
42
|
+
*
|
|
43
|
+
* // 获取统计信息
|
|
44
|
+
* const stats = await consumer.statistics()
|
|
45
|
+
*
|
|
46
|
+
* // 停止消费
|
|
47
|
+
* consumer.disconnect()
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export declare class RedisQueueBatchConsumer<R extends Record<string, any> = RedisQueueRegistry, K extends keyof R & string = keyof R & string> extends RedisQueueCommon {
|
|
51
|
+
private consumerRunning;
|
|
52
|
+
private consumerInterval;
|
|
53
|
+
private recoveryInterval;
|
|
54
|
+
private processingBatches;
|
|
55
|
+
private processingPromises;
|
|
56
|
+
private readonly config;
|
|
57
|
+
constructor(queueKey: K, config: BatchConsumerConfig<R[K]>);
|
|
58
|
+
protected getLogPrefix(): string;
|
|
59
|
+
/**
|
|
60
|
+
* 连接 Redis 并自动启动消费者
|
|
61
|
+
*/
|
|
62
|
+
connect(): Promise<void>;
|
|
63
|
+
/**
|
|
64
|
+
* 断开 Redis 连接并停止消费者
|
|
65
|
+
* 会等待所有正在处理的批次完成后再断开连接
|
|
66
|
+
*/
|
|
67
|
+
disconnect(): Promise<void>;
|
|
68
|
+
/**
|
|
69
|
+
* 批量处理任务
|
|
70
|
+
*/
|
|
71
|
+
private processBatch;
|
|
72
|
+
/**
|
|
73
|
+
* 启动恢复机制
|
|
74
|
+
*/
|
|
75
|
+
private startRecovery;
|
|
76
|
+
/**
|
|
77
|
+
* 停止恢复机制
|
|
78
|
+
*/
|
|
79
|
+
private stopRecovery;
|
|
80
|
+
/**
|
|
81
|
+
* 启动消费者
|
|
82
|
+
*/
|
|
83
|
+
private startConsumer;
|
|
84
|
+
/**
|
|
85
|
+
* 停止消费者
|
|
86
|
+
*/
|
|
87
|
+
private stopConsumer;
|
|
88
|
+
/**
|
|
89
|
+
* 获取队列统计信息(O(1) 时间复杂度)
|
|
90
|
+
*/
|
|
91
|
+
statistics(): Promise<QueueStats>;
|
|
92
|
+
/**
|
|
93
|
+
* 健康检查
|
|
94
|
+
*/
|
|
95
|
+
health(): Promise<boolean>;
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=redis-queue-batch-consumer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redis-queue-batch-consumer.d.ts","sourceRoot":"","sources":["../../source/redis-queue/redis-queue-batch-consumer.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAC1D,OAAO,KAAK,EAAE,mBAAmB,EAA0B,UAAU,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAE7G;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AACH,qBAAa,uBAAuB,CAClC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,kBAAkB,EAClD,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,GAAG,MAAM,CAAC,GAAG,MAAM,CAC7C,SAAQ,gBAAgB;IACxB,OAAO,CAAC,eAAe,CAAQ;IAC/B,OAAO,CAAC,gBAAgB,CAA8B;IACtD,OAAO,CAAC,gBAAgB,CAA8B;IACtD,OAAO,CAAC,iBAAiB,CAAI;IAC7B,OAAO,CAAC,kBAAkB,CAA2B;IAErD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAOtB;gBAEW,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAuB1D,SAAS,CAAC,YAAY,IAAI,MAAM;IAIhC;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAO9B;;;OAGG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAgBjC;;OAEG;YACW,YAAY;IA2G1B;;OAEG;IACH,OAAO,CAAC,aAAa;IAoBrB;;OAEG;IACH,OAAO,CAAC,YAAY;IAQpB;;OAEG;IACH,OAAO,CAAC,aAAa;IAyErB;;OAEG;IACH,OAAO,CAAC,YAAY;IASpB;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,UAAU,CAAC;IAevC;;OAEG;IACG,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC;CAMjC"}
|