@scpxl/nodejs-framework 1.0.42 → 1.0.43
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/dist/cli/index.js +4 -2
- package/dist/cli/index.js.map +2 -2
- package/dist/websocket/define-subscriber.d.ts +8 -1
- package/dist/websocket/define-subscriber.d.ts.map +1 -1
- package/dist/websocket/define-subscriber.js +2 -1
- package/dist/websocket/define-subscriber.js.map +2 -2
- package/dist/websocket/index.d.ts +4 -0
- package/dist/websocket/index.d.ts.map +1 -1
- package/dist/websocket/index.js +43 -1
- package/dist/websocket/index.js.map +2 -2
- package/dist/websocket/subscriber-middleware.d.ts +52 -0
- package/dist/websocket/subscriber-middleware.d.ts.map +1 -0
- package/dist/websocket/subscriber-middleware.js +200 -0
- package/dist/websocket/subscriber-middleware.js.map +7 -0
- package/dist/websocket/subscriber-utils.d.ts +88 -0
- package/dist/websocket/subscriber-utils.d.ts.map +1 -0
- package/dist/websocket/subscriber-utils.js +227 -0
- package/dist/websocket/subscriber-utils.js.map +7 -0
- package/dist/websocket/websocket-server.d.ts +41 -1
- package/dist/websocket/websocket-server.d.ts.map +1 -1
- package/dist/websocket/websocket-server.js +90 -7
- package/dist/websocket/websocket-server.js.map +2 -2
- package/dist/websocket/websocket.interface.d.ts +7 -0
- package/dist/websocket/websocket.interface.d.ts.map +1 -1
- package/dist/websocket/websocket.interface.js.map +2 -2
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { WebSocketSubscriberDefinition, WebSocketSubscriberHandler, WebSocketSubscriberMatcher } from './websocket.interface.js';
|
|
1
|
+
import type { WebSocketSubscriberDefinition, WebSocketSubscriberHandler, WebSocketSubscriberHandlerContext, WebSocketSubscriberMatcher } from './websocket.interface.js';
|
|
2
2
|
type ChannelConfig = {
|
|
3
3
|
channel: string;
|
|
4
4
|
channels?: never;
|
|
@@ -14,10 +14,17 @@ type MatchConfig = {
|
|
|
14
14
|
channel?: never;
|
|
15
15
|
channels?: never;
|
|
16
16
|
};
|
|
17
|
+
type MiddlewareConfig = Array<{
|
|
18
|
+
name: string;
|
|
19
|
+
onBefore?: (context: WebSocketSubscriberHandlerContext) => boolean | Promise<boolean>;
|
|
20
|
+
onAfter?: (context: WebSocketSubscriberHandlerContext, result: unknown) => void | Promise<void>;
|
|
21
|
+
onError?: (context: WebSocketSubscriberHandlerContext, error: Error) => boolean | Promise<boolean>;
|
|
22
|
+
}>;
|
|
17
23
|
type BaseConfig = {
|
|
18
24
|
name?: string;
|
|
19
25
|
description?: string;
|
|
20
26
|
priority?: number;
|
|
27
|
+
middleware?: MiddlewareConfig;
|
|
21
28
|
handle: WebSocketSubscriberHandler;
|
|
22
29
|
};
|
|
23
30
|
export type DefineWebSocketSubscriberConfig = BaseConfig & (ChannelConfig | ChannelsConfig | MatchConfig);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"define-subscriber.d.ts","sourceRoot":"","sources":["../../src/websocket/define-subscriber.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,6BAA6B,EAC7B,0BAA0B,EAC1B,0BAA0B,EAC3B,MAAM,0BAA0B,CAAC;AAElC,KAAK,aAAa,GAAG;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,KAAK,CAAC;IACjB,KAAK,CAAC,EAAE,KAAK,CAAC;CACf,CAAC;AAEF,KAAK,cAAc,GAAG;IACpB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,KAAK,CAAC;IAChB,KAAK,CAAC,EAAE,KAAK,CAAC;CACf,CAAC;AAEF,KAAK,WAAW,GAAG;IACjB,KAAK,EAAE,0BAA0B,GAAG,0BAA0B,EAAE,CAAC;IACjE,OAAO,CAAC,EAAE,KAAK,CAAC;IAChB,QAAQ,CAAC,EAAE,KAAK,CAAC;CAClB,CAAC;AAEF,KAAK,UAAU,GAAG;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,0BAA0B,CAAC;CACpC,CAAC;AAEF,MAAM,MAAM,+BAA+B,GAAG,UAAU,GAAG,CAAC,aAAa,GAAG,cAAc,GAAG,WAAW,CAAC,CAAC;AAE1G,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,+BAA+B,GAAG,6BAA6B,
|
|
1
|
+
{"version":3,"file":"define-subscriber.d.ts","sourceRoot":"","sources":["../../src/websocket/define-subscriber.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,6BAA6B,EAC7B,0BAA0B,EAC1B,iCAAiC,EACjC,0BAA0B,EAC3B,MAAM,0BAA0B,CAAC;AAElC,KAAK,aAAa,GAAG;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,KAAK,CAAC;IACjB,KAAK,CAAC,EAAE,KAAK,CAAC;CACf,CAAC;AAEF,KAAK,cAAc,GAAG;IACpB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,KAAK,CAAC;IAChB,KAAK,CAAC,EAAE,KAAK,CAAC;CACf,CAAC;AAEF,KAAK,WAAW,GAAG;IACjB,KAAK,EAAE,0BAA0B,GAAG,0BAA0B,EAAE,CAAC;IACjE,OAAO,CAAC,EAAE,KAAK,CAAC;IAChB,QAAQ,CAAC,EAAE,KAAK,CAAC;CAClB,CAAC;AAEF,KAAK,gBAAgB,GAAG,KAAK,CAAC;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,iCAAiC,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACtF,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,iCAAiC,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChG,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,iCAAiC,EAAE,KAAK,EAAE,KAAK,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACpG,CAAC,CAAC;AAEH,KAAK,UAAU,GAAG;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,MAAM,EAAE,0BAA0B,CAAC;CACpC,CAAC;AAEF,MAAM,MAAM,+BAA+B,GAAG,UAAU,GAAG,CAAC,aAAa,GAAG,cAAc,GAAG,WAAW,CAAC,CAAC;AAE1G,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,+BAA+B,GAAG,6BAA6B,CA6BhH"}
|
|
@@ -23,7 +23,8 @@ function defineWebSocketSubscriber(config) {
|
|
|
23
23
|
priority: config.priority,
|
|
24
24
|
channels,
|
|
25
25
|
matchers,
|
|
26
|
-
handle: config.handle
|
|
26
|
+
handle: config.handle,
|
|
27
|
+
middleware: config.middleware
|
|
27
28
|
};
|
|
28
29
|
}
|
|
29
30
|
__name(defineWebSocketSubscriber, "defineWebSocketSubscriber");
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/websocket/define-subscriber.ts"],
|
|
4
|
-
"sourcesContent": ["import type {\n WebSocketSubscriberDefinition,\n WebSocketSubscriberHandler,\n WebSocketSubscriberMatcher,\n} from './websocket.interface.js';\n\ntype ChannelConfig = {\n channel: string;\n channels?: never;\n match?: never;\n};\n\ntype ChannelsConfig = {\n channels: string[];\n channel?: never;\n match?: never;\n};\n\ntype MatchConfig = {\n match: WebSocketSubscriberMatcher | WebSocketSubscriberMatcher[];\n channel?: never;\n channels?: never;\n};\n\ntype BaseConfig = {\n name?: string;\n description?: string;\n priority?: number;\n handle: WebSocketSubscriberHandler;\n};\n\nexport type DefineWebSocketSubscriberConfig = BaseConfig & (ChannelConfig | ChannelsConfig | MatchConfig);\n\nexport function defineWebSocketSubscriber(config: DefineWebSocketSubscriberConfig): WebSocketSubscriberDefinition {\n let matchers: WebSocketSubscriberMatcher[] = [];\n if ('match' in config) {\n const matchConfig = config as MatchConfig & BaseConfig;\n matchers = Array.isArray(matchConfig.match) ? [...matchConfig.match] : [matchConfig.match];\n }\n\n let channels: string[] = [];\n if ('channel' in config) {\n const channelConfig = config as ChannelConfig & BaseConfig;\n channels = [channelConfig.channel];\n } else if ('channels' in config) {\n const channelsConfig = config as ChannelsConfig & BaseConfig;\n channels = [...channelsConfig.channels];\n }\n\n if (channels.length === 0 && matchers.length === 0) {\n throw new Error('defineWebSocketSubscriber requires either channel(s) or a match function.');\n }\n\n return {\n name: config.name,\n description: config.description,\n priority: config.priority,\n channels,\n matchers,\n handle: config.handle,\n };\n}\n"],
|
|
5
|
-
"mappings": ";;
|
|
4
|
+
"sourcesContent": ["import type {\n WebSocketSubscriberDefinition,\n WebSocketSubscriberHandler,\n WebSocketSubscriberHandlerContext,\n WebSocketSubscriberMatcher,\n} from './websocket.interface.js';\n\ntype ChannelConfig = {\n channel: string;\n channels?: never;\n match?: never;\n};\n\ntype ChannelsConfig = {\n channels: string[];\n channel?: never;\n match?: never;\n};\n\ntype MatchConfig = {\n match: WebSocketSubscriberMatcher | WebSocketSubscriberMatcher[];\n channel?: never;\n channels?: never;\n};\n\ntype MiddlewareConfig = Array<{\n name: string;\n onBefore?: (context: WebSocketSubscriberHandlerContext) => boolean | Promise<boolean>;\n onAfter?: (context: WebSocketSubscriberHandlerContext, result: unknown) => void | Promise<void>;\n onError?: (context: WebSocketSubscriberHandlerContext, error: Error) => boolean | Promise<boolean>;\n}>;\n\ntype BaseConfig = {\n name?: string;\n description?: string;\n priority?: number;\n middleware?: MiddlewareConfig;\n handle: WebSocketSubscriberHandler;\n};\n\nexport type DefineWebSocketSubscriberConfig = BaseConfig & (ChannelConfig | ChannelsConfig | MatchConfig);\n\nexport function defineWebSocketSubscriber(config: DefineWebSocketSubscriberConfig): WebSocketSubscriberDefinition {\n let matchers: WebSocketSubscriberMatcher[] = [];\n if ('match' in config) {\n const matchConfig = config as MatchConfig & BaseConfig;\n matchers = Array.isArray(matchConfig.match) ? [...matchConfig.match] : [matchConfig.match];\n }\n\n let channels: string[] = [];\n if ('channel' in config) {\n const channelConfig = config as ChannelConfig & BaseConfig;\n channels = [channelConfig.channel];\n } else if ('channels' in config) {\n const channelsConfig = config as ChannelsConfig & BaseConfig;\n channels = [...channelsConfig.channels];\n }\n\n if (channels.length === 0 && matchers.length === 0) {\n throw new Error('defineWebSocketSubscriber requires either channel(s) or a match function.');\n }\n\n return {\n name: config.name,\n description: config.description,\n priority: config.priority,\n channels,\n matchers,\n handle: config.handle,\n middleware: config.middleware,\n };\n}\n"],
|
|
5
|
+
"mappings": ";;AA0CO,SAAS,0BAA0B,QAAwE;AAChH,MAAI,WAAyC,CAAC;AAC9C,MAAI,WAAW,QAAQ;AACrB,UAAM,cAAc;AACpB,eAAW,MAAM,QAAQ,YAAY,KAAK,IAAI,CAAC,GAAG,YAAY,KAAK,IAAI,CAAC,YAAY,KAAK;AAAA,EAC3F;AAEA,MAAI,WAAqB,CAAC;AAC1B,MAAI,aAAa,QAAQ;AACvB,UAAM,gBAAgB;AACtB,eAAW,CAAC,cAAc,OAAO;AAAA,EACnC,WAAW,cAAc,QAAQ;AAC/B,UAAM,iBAAiB;AACvB,eAAW,CAAC,GAAG,eAAe,QAAQ;AAAA,EACxC;AAEA,MAAI,SAAS,WAAW,KAAK,SAAS,WAAW,GAAG;AAClD,UAAM,IAAI,MAAM,2EAA2E;AAAA,EAC7F;AAEA,SAAO;AAAA,IACL,MAAM,OAAO;AAAA,IACb,aAAa,OAAO;AAAA,IACpB,UAAU,OAAO;AAAA,IACjB;AAAA,IACA;AAAA,IACA,QAAQ,OAAO;AAAA,IACf,YAAY,OAAO;AAAA,EACrB;AACF;AA7BgB;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -8,4 +8,8 @@ export type { WebSocketMessage, WebSocketServiceOptions } from './websocket-serv
|
|
|
8
8
|
export { WebSocketAuthService } from './websocket-auth.js';
|
|
9
9
|
export type { WebSocketAuthResult } from './websocket-auth.js';
|
|
10
10
|
export { defineWebSocketSubscriber } from './define-subscriber.js';
|
|
11
|
+
export { matchByProperty, matchByPropertyPredicate, getNestedProperty, withErrorHandler, withLogging, withRateLimit, withRetry, composeHandlers, withFilter, withValidation, withMetadata, withDebounce, withThrottle, } from './subscriber-utils.js';
|
|
12
|
+
export { executeWithMiddleware } from './subscriber-middleware.js';
|
|
13
|
+
export type { WebSocketSubscriberMiddleware } from './subscriber-middleware.js';
|
|
14
|
+
export { loggingMiddleware, timingMiddleware, validationMiddleware, rateLimitMiddleware, errorRecoveryMiddleware, } from './subscriber-middleware.js';
|
|
11
15
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/websocket/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,6BAA6B,EAAE,MAAM,0BAA0B,CAAC;AACzE,YAAY,EACV,6BAA6B,EAC7B,0BAA0B,EAC1B,iCAAiC,EACjC,0BAA0B,EAC1B,iCAAiC,GAClC,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,OAAO,IAAI,6BAA6B,EAAE,MAAM,6BAA6B,CAAC;AACvF,OAAO,EAAE,OAAO,IAAI,6BAA6B,EAAE,MAAM,6BAA6B,CAAC;AACvF,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,YAAY,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACxF,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,YAAY,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/websocket/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,6BAA6B,EAAE,MAAM,0BAA0B,CAAC;AACzE,YAAY,EACV,6BAA6B,EAC7B,0BAA0B,EAC1B,iCAAiC,EACjC,0BAA0B,EAC1B,iCAAiC,GAClC,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,OAAO,IAAI,6BAA6B,EAAE,MAAM,6BAA6B,CAAC;AACvF,OAAO,EAAE,OAAO,IAAI,6BAA6B,EAAE,MAAM,6BAA6B,CAAC;AACvF,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,YAAY,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACxF,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,YAAY,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AAGnE,OAAO,EACL,eAAe,EACf,wBAAwB,EACxB,iBAAiB,EACjB,gBAAgB,EAChB,WAAW,EACX,aAAa,EACb,SAAS,EACT,eAAe,EACf,UAAU,EACV,cAAc,EACd,YAAY,EACZ,YAAY,EACZ,YAAY,GACb,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,YAAY,EAAE,6BAA6B,EAAE,MAAM,4BAA4B,CAAC;AAChF,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,oBAAoB,EACpB,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,4BAA4B,CAAC"}
|
package/dist/websocket/index.js
CHANGED
|
@@ -4,12 +4,54 @@ import { default as default3 } from "./controller/client/base.js";
|
|
|
4
4
|
import { WebSocketService } from "./websocket-service.js";
|
|
5
5
|
import { WebSocketAuthService } from "./websocket-auth.js";
|
|
6
6
|
import { defineWebSocketSubscriber } from "./define-subscriber.js";
|
|
7
|
+
import {
|
|
8
|
+
matchByProperty,
|
|
9
|
+
matchByPropertyPredicate,
|
|
10
|
+
getNestedProperty,
|
|
11
|
+
withErrorHandler,
|
|
12
|
+
withLogging,
|
|
13
|
+
withRateLimit,
|
|
14
|
+
withRetry,
|
|
15
|
+
composeHandlers,
|
|
16
|
+
withFilter,
|
|
17
|
+
withValidation,
|
|
18
|
+
withMetadata,
|
|
19
|
+
withDebounce,
|
|
20
|
+
withThrottle
|
|
21
|
+
} from "./subscriber-utils.js";
|
|
22
|
+
import { executeWithMiddleware } from "./subscriber-middleware.js";
|
|
23
|
+
import {
|
|
24
|
+
loggingMiddleware,
|
|
25
|
+
timingMiddleware,
|
|
26
|
+
validationMiddleware,
|
|
27
|
+
rateLimitMiddleware,
|
|
28
|
+
errorRecoveryMiddleware
|
|
29
|
+
} from "./subscriber-middleware.js";
|
|
7
30
|
export {
|
|
8
31
|
WebSocketAuthService,
|
|
9
32
|
default3 as WebSocketClientBaseController,
|
|
10
33
|
WebSocketRedisSubscriberEvent,
|
|
11
34
|
default2 as WebSocketServerBaseController,
|
|
12
35
|
WebSocketService,
|
|
13
|
-
|
|
36
|
+
composeHandlers,
|
|
37
|
+
defineWebSocketSubscriber,
|
|
38
|
+
errorRecoveryMiddleware,
|
|
39
|
+
executeWithMiddleware,
|
|
40
|
+
getNestedProperty,
|
|
41
|
+
loggingMiddleware,
|
|
42
|
+
matchByProperty,
|
|
43
|
+
matchByPropertyPredicate,
|
|
44
|
+
rateLimitMiddleware,
|
|
45
|
+
timingMiddleware,
|
|
46
|
+
validationMiddleware,
|
|
47
|
+
withDebounce,
|
|
48
|
+
withErrorHandler,
|
|
49
|
+
withFilter,
|
|
50
|
+
withLogging,
|
|
51
|
+
withMetadata,
|
|
52
|
+
withRateLimit,
|
|
53
|
+
withRetry,
|
|
54
|
+
withThrottle,
|
|
55
|
+
withValidation
|
|
14
56
|
};
|
|
15
57
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/websocket/index.ts"],
|
|
4
|
-
"sourcesContent": ["export type { WebSocketRoute } from './websocket.interface.js';\nexport { WebSocketRedisSubscriberEvent } from './websocket.interface.js';\nexport type {\n WebSocketSubscriberDefinition,\n WebSocketSubscriberHandler,\n WebSocketSubscriberHandlerContext,\n WebSocketSubscriberMatcher,\n WebSocketSubscriberHandlersConfig,\n} from './websocket.interface.js';\nexport { default as WebSocketServerBaseController } from './controller/server/base.js';\nexport { default as WebSocketClientBaseController } from './controller/client/base.js';\nexport { WebSocketService } from './websocket-service.js';\nexport type { WebSocketMessage, WebSocketServiceOptions } from './websocket-service.js';\nexport { WebSocketAuthService } from './websocket-auth.js';\nexport type { WebSocketAuthResult } from './websocket-auth.js';\nexport { defineWebSocketSubscriber } from './define-subscriber.js';\n"],
|
|
5
|
-
"mappings": "AACA,SAAS,qCAAqC;AAQ9C,SAAoB,WAAXA,gBAAgD;AACzD,SAAoB,WAAXA,gBAAgD;AACzD,SAAS,wBAAwB;AAEjC,SAAS,4BAA4B;AAErC,SAAS,iCAAiC;",
|
|
4
|
+
"sourcesContent": ["export type { WebSocketRoute } from './websocket.interface.js';\nexport { WebSocketRedisSubscriberEvent } from './websocket.interface.js';\nexport type {\n WebSocketSubscriberDefinition,\n WebSocketSubscriberHandler,\n WebSocketSubscriberHandlerContext,\n WebSocketSubscriberMatcher,\n WebSocketSubscriberHandlersConfig,\n} from './websocket.interface.js';\nexport { default as WebSocketServerBaseController } from './controller/server/base.js';\nexport { default as WebSocketClientBaseController } from './controller/client/base.js';\nexport { WebSocketService } from './websocket-service.js';\nexport type { WebSocketMessage, WebSocketServiceOptions } from './websocket-service.js';\nexport { WebSocketAuthService } from './websocket-auth.js';\nexport type { WebSocketAuthResult } from './websocket-auth.js';\nexport { defineWebSocketSubscriber } from './define-subscriber.js';\n\n// WebSocket subscriber utilities\nexport {\n matchByProperty,\n matchByPropertyPredicate,\n getNestedProperty,\n withErrorHandler,\n withLogging,\n withRateLimit,\n withRetry,\n composeHandlers,\n withFilter,\n withValidation,\n withMetadata,\n withDebounce,\n withThrottle,\n} from './subscriber-utils.js';\n\n// WebSocket subscriber middleware\nexport { executeWithMiddleware } from './subscriber-middleware.js';\nexport type { WebSocketSubscriberMiddleware } from './subscriber-middleware.js';\nexport {\n loggingMiddleware,\n timingMiddleware,\n validationMiddleware,\n rateLimitMiddleware,\n errorRecoveryMiddleware,\n} from './subscriber-middleware.js';\n"],
|
|
5
|
+
"mappings": "AACA,SAAS,qCAAqC;AAQ9C,SAAoB,WAAXA,gBAAgD;AACzD,SAAoB,WAAXA,gBAAgD;AACzD,SAAS,wBAAwB;AAEjC,SAAS,4BAA4B;AAErC,SAAS,iCAAiC;AAG1C;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGP,SAAS,6BAA6B;AAEtC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;",
|
|
6
6
|
"names": ["default"]
|
|
7
7
|
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { WebSocketSubscriberHandler, WebSocketSubscriberHandlerContext } from './websocket.interface.js';
|
|
2
|
+
/**
|
|
3
|
+
* Middleware that can intercept and modify subscriber handler execution
|
|
4
|
+
*/
|
|
5
|
+
export interface WebSocketSubscriberMiddleware {
|
|
6
|
+
/**
|
|
7
|
+
* Unique identifier for the middleware
|
|
8
|
+
*/
|
|
9
|
+
name: string;
|
|
10
|
+
/**
|
|
11
|
+
* Runs before the handler
|
|
12
|
+
* Return false to skip handler execution
|
|
13
|
+
*/
|
|
14
|
+
onBefore?: (context: WebSocketSubscriberHandlerContext) => boolean | Promise<boolean>;
|
|
15
|
+
/**
|
|
16
|
+
* Runs after successful handler execution
|
|
17
|
+
*/
|
|
18
|
+
onAfter?: (context: WebSocketSubscriberHandlerContext, result: unknown) => void | Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* Runs on handler error
|
|
21
|
+
* Return true to suppress the error, false to rethrow
|
|
22
|
+
*/
|
|
23
|
+
onError?: (context: WebSocketSubscriberHandlerContext, error: Error) => boolean | Promise<boolean>;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Execute middleware pipeline and handler
|
|
27
|
+
* @param handler - The handler to execute
|
|
28
|
+
* @param middleware - Array of middleware to apply
|
|
29
|
+
* @param context - Handler context
|
|
30
|
+
*/
|
|
31
|
+
export declare function executeWithMiddleware(handler: WebSocketSubscriberHandler, middleware: WebSocketSubscriberMiddleware[], context: WebSocketSubscriberHandlerContext): Promise<void>;
|
|
32
|
+
/**
|
|
33
|
+
* Built-in middleware for logging handler execution
|
|
34
|
+
*/
|
|
35
|
+
export declare const loggingMiddleware: (handlerName: string) => WebSocketSubscriberMiddleware;
|
|
36
|
+
/**
|
|
37
|
+
* Built-in middleware for timing handler execution
|
|
38
|
+
*/
|
|
39
|
+
export declare const timingMiddleware: () => WebSocketSubscriberMiddleware;
|
|
40
|
+
/**
|
|
41
|
+
* Built-in middleware for validating message structure
|
|
42
|
+
*/
|
|
43
|
+
export declare const validationMiddleware: (validator: (message: unknown) => void | Promise<void>) => WebSocketSubscriberMiddleware;
|
|
44
|
+
/**
|
|
45
|
+
* Built-in middleware for rate limiting
|
|
46
|
+
*/
|
|
47
|
+
export declare const rateLimitMiddleware: (maxExecutions: number, windowMs: number) => WebSocketSubscriberMiddleware;
|
|
48
|
+
/**
|
|
49
|
+
* Built-in middleware for error handling and recovery
|
|
50
|
+
*/
|
|
51
|
+
export declare const errorRecoveryMiddleware: (maxRetries?: number, _delayMs?: number) => WebSocketSubscriberMiddleware;
|
|
52
|
+
//# sourceMappingURL=subscriber-middleware.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subscriber-middleware.d.ts","sourceRoot":"","sources":["../../src/websocket/subscriber-middleware.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,0BAA0B,EAAE,iCAAiC,EAAE,MAAM,0BAA0B,CAAC;AAG9G;;GAEG;AACH,MAAM,WAAW,6BAA6B;IAC5C;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;;OAGG;IACH,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,iCAAiC,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEtF;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,iCAAiC,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEhG;;;OAGG;IACH,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,iCAAiC,EAAE,KAAK,EAAE,KAAK,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACpG;AAED;;;;;GAKG;AACH,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,0BAA0B,EACnC,UAAU,EAAE,6BAA6B,EAAE,EAC3C,OAAO,EAAE,iCAAiC,GACzC,OAAO,CAAC,IAAI,CAAC,CA8Ef;AAED;;GAEG;AACH,eAAO,MAAM,iBAAiB,GAAI,aAAa,MAAM,KAAG,6BA8BtD,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,gBAAgB,QAAO,6BA4BnC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,oBAAoB,GAC/B,WAAW,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KACpD,6BAiBD,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,mBAAmB,GAAI,eAAe,MAAM,EAAE,UAAU,MAAM,KAAG,6BA8B7E,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,uBAAuB,GAAI,mBAAc,EAAE,iBAAe,KAAG,6BAaxE,CAAC"}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
+
import { Logger } from "../logger/index.js";
|
|
4
|
+
async function executeWithMiddleware(handler, middleware, context) {
|
|
5
|
+
for (const mw of middleware) {
|
|
6
|
+
try {
|
|
7
|
+
const shouldContinue = mw.onBefore ? await mw.onBefore(context) : true;
|
|
8
|
+
if (!shouldContinue) {
|
|
9
|
+
Logger.info({
|
|
10
|
+
message: "Middleware skipped handler execution",
|
|
11
|
+
meta: {
|
|
12
|
+
middleware: mw.name,
|
|
13
|
+
channel: context.channel
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
} catch (error) {
|
|
19
|
+
Logger.error({
|
|
20
|
+
message: "Middleware onBefore failed",
|
|
21
|
+
meta: {
|
|
22
|
+
middleware: mw.name,
|
|
23
|
+
channel: context.channel,
|
|
24
|
+
error: error instanceof Error ? error.message : String(error)
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
throw error;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
let result;
|
|
31
|
+
try {
|
|
32
|
+
result = await handler(context);
|
|
33
|
+
} catch (error) {
|
|
34
|
+
for (const mw of middleware) {
|
|
35
|
+
if (!mw.onError) {
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
try {
|
|
39
|
+
const shouldSuppress = await mw.onError(context, error instanceof Error ? error : new Error(String(error)));
|
|
40
|
+
if (shouldSuppress) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
} catch (mwError) {
|
|
44
|
+
Logger.error({
|
|
45
|
+
message: "Middleware onError failed",
|
|
46
|
+
meta: {
|
|
47
|
+
middleware: mw.name,
|
|
48
|
+
channel: context.channel,
|
|
49
|
+
error: mwError instanceof Error ? mwError.message : String(mwError)
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
throw error;
|
|
55
|
+
}
|
|
56
|
+
for (const mw of middleware) {
|
|
57
|
+
if (!mw.onAfter) {
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
try {
|
|
61
|
+
await mw.onAfter(context, result);
|
|
62
|
+
} catch (error) {
|
|
63
|
+
Logger.error({
|
|
64
|
+
message: "Middleware onAfter failed",
|
|
65
|
+
meta: {
|
|
66
|
+
middleware: mw.name,
|
|
67
|
+
channel: context.channel,
|
|
68
|
+
error: error instanceof Error ? error.message : String(error)
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
__name(executeWithMiddleware, "executeWithMiddleware");
|
|
75
|
+
const loggingMiddleware = /* @__PURE__ */ __name((handlerName) => ({
|
|
76
|
+
name: "logging",
|
|
77
|
+
onBefore: /* @__PURE__ */ __name((context) => {
|
|
78
|
+
Logger.info({
|
|
79
|
+
message: `${handlerName}: Starting execution`,
|
|
80
|
+
meta: {
|
|
81
|
+
channel: context.channel
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
return true;
|
|
85
|
+
}, "onBefore"),
|
|
86
|
+
onAfter: /* @__PURE__ */ __name((context, result) => {
|
|
87
|
+
Logger.info({
|
|
88
|
+
message: `${handlerName}: Completed successfully`,
|
|
89
|
+
meta: {
|
|
90
|
+
channel: context.channel,
|
|
91
|
+
resultType: typeof result
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
}, "onAfter"),
|
|
95
|
+
onError: /* @__PURE__ */ __name((context, error) => {
|
|
96
|
+
Logger.error({
|
|
97
|
+
message: `${handlerName}: Failed`,
|
|
98
|
+
meta: {
|
|
99
|
+
channel: context.channel,
|
|
100
|
+
error: error.message
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
return false;
|
|
104
|
+
}, "onError")
|
|
105
|
+
}), "loggingMiddleware");
|
|
106
|
+
const timingMiddleware = /* @__PURE__ */ __name(() => {
|
|
107
|
+
const startTimes = /* @__PURE__ */ new Map();
|
|
108
|
+
return {
|
|
109
|
+
name: "timing",
|
|
110
|
+
onBefore: /* @__PURE__ */ __name((context) => {
|
|
111
|
+
startTimes.set(context.channel, Date.now());
|
|
112
|
+
return true;
|
|
113
|
+
}, "onBefore"),
|
|
114
|
+
onAfter: /* @__PURE__ */ __name((context) => {
|
|
115
|
+
const startTime = startTimes.get(context.channel);
|
|
116
|
+
if (startTime) {
|
|
117
|
+
const duration = Date.now() - startTime;
|
|
118
|
+
startTimes.delete(context.channel);
|
|
119
|
+
Logger.info({
|
|
120
|
+
message: "Handler execution timing",
|
|
121
|
+
meta: {
|
|
122
|
+
channel: context.channel,
|
|
123
|
+
durationMs: duration
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
}, "onAfter"),
|
|
128
|
+
onError: /* @__PURE__ */ __name((context) => {
|
|
129
|
+
startTimes.delete(context.channel);
|
|
130
|
+
return false;
|
|
131
|
+
}, "onError")
|
|
132
|
+
};
|
|
133
|
+
}, "timingMiddleware");
|
|
134
|
+
const validationMiddleware = /* @__PURE__ */ __name((validator) => ({
|
|
135
|
+
name: "validation",
|
|
136
|
+
onBefore: /* @__PURE__ */ __name(async (context) => {
|
|
137
|
+
try {
|
|
138
|
+
await validator(context.message);
|
|
139
|
+
return true;
|
|
140
|
+
} catch (error) {
|
|
141
|
+
Logger.warn({
|
|
142
|
+
message: "Message validation failed",
|
|
143
|
+
meta: {
|
|
144
|
+
channel: context.channel,
|
|
145
|
+
error: error instanceof Error ? error.message : String(error)
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
throw error;
|
|
149
|
+
}
|
|
150
|
+
}, "onBefore")
|
|
151
|
+
}), "validationMiddleware");
|
|
152
|
+
const rateLimitMiddleware = /* @__PURE__ */ __name((maxExecutions, windowMs) => {
|
|
153
|
+
const executionTimes = /* @__PURE__ */ new Map();
|
|
154
|
+
return {
|
|
155
|
+
name: "rate-limit",
|
|
156
|
+
onBefore: /* @__PURE__ */ __name((context) => {
|
|
157
|
+
const channel = context.channel;
|
|
158
|
+
const now = Date.now();
|
|
159
|
+
const times = executionTimes.get(channel) ?? [];
|
|
160
|
+
const recentTimes = times.filter((t) => now - t < windowMs);
|
|
161
|
+
if (recentTimes.length >= maxExecutions) {
|
|
162
|
+
Logger.warn({
|
|
163
|
+
message: "Rate limit exceeded",
|
|
164
|
+
meta: {
|
|
165
|
+
channel,
|
|
166
|
+
maxExecutions,
|
|
167
|
+
windowMs
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
recentTimes.push(now);
|
|
173
|
+
executionTimes.set(channel, recentTimes);
|
|
174
|
+
return true;
|
|
175
|
+
}, "onBefore")
|
|
176
|
+
};
|
|
177
|
+
}, "rateLimitMiddleware");
|
|
178
|
+
const errorRecoveryMiddleware = /* @__PURE__ */ __name((maxRetries = 3, _delayMs = 1e3) => ({
|
|
179
|
+
name: "error-recovery",
|
|
180
|
+
onError: /* @__PURE__ */ __name(async (context, error) => {
|
|
181
|
+
Logger.warn({
|
|
182
|
+
message: "Handler error, could implement retry logic",
|
|
183
|
+
meta: {
|
|
184
|
+
channel: context.channel,
|
|
185
|
+
error: error.message,
|
|
186
|
+
suggestedRetries: maxRetries
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
return false;
|
|
190
|
+
}, "onError")
|
|
191
|
+
}), "errorRecoveryMiddleware");
|
|
192
|
+
export {
|
|
193
|
+
errorRecoveryMiddleware,
|
|
194
|
+
executeWithMiddleware,
|
|
195
|
+
loggingMiddleware,
|
|
196
|
+
rateLimitMiddleware,
|
|
197
|
+
timingMiddleware,
|
|
198
|
+
validationMiddleware
|
|
199
|
+
};
|
|
200
|
+
//# sourceMappingURL=subscriber-middleware.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/websocket/subscriber-middleware.ts"],
|
|
4
|
+
"sourcesContent": ["import type { WebSocketSubscriberHandler, WebSocketSubscriberHandlerContext } from './websocket.interface.js';\nimport { Logger } from '../logger/index.js';\n\n/**\n * Middleware that can intercept and modify subscriber handler execution\n */\nexport interface WebSocketSubscriberMiddleware {\n /**\n * Unique identifier for the middleware\n */\n name: string;\n\n /**\n * Runs before the handler\n * Return false to skip handler execution\n */\n onBefore?: (context: WebSocketSubscriberHandlerContext) => boolean | Promise<boolean>;\n\n /**\n * Runs after successful handler execution\n */\n onAfter?: (context: WebSocketSubscriberHandlerContext, result: unknown) => void | Promise<void>;\n\n /**\n * Runs on handler error\n * Return true to suppress the error, false to rethrow\n */\n onError?: (context: WebSocketSubscriberHandlerContext, error: Error) => boolean | Promise<boolean>;\n}\n\n/**\n * Execute middleware pipeline and handler\n * @param handler - The handler to execute\n * @param middleware - Array of middleware to apply\n * @param context - Handler context\n */\nexport async function executeWithMiddleware(\n handler: WebSocketSubscriberHandler,\n middleware: WebSocketSubscriberMiddleware[],\n context: WebSocketSubscriberHandlerContext,\n): Promise<void> {\n // Execute \"before\" middleware\n for (const mw of middleware) {\n try {\n const shouldContinue = mw.onBefore ? await mw.onBefore(context) : true;\n if (!shouldContinue) {\n Logger.info({\n message: 'Middleware skipped handler execution',\n meta: {\n middleware: mw.name,\n channel: context.channel,\n },\n });\n return;\n }\n } catch (error) {\n Logger.error({\n message: 'Middleware onBefore failed',\n meta: {\n middleware: mw.name,\n channel: context.channel,\n error: error instanceof Error ? error.message : String(error),\n },\n });\n throw error;\n }\n }\n\n // Execute handler\n let result: unknown;\n try {\n result = await handler(context);\n } catch (error) {\n // Execute \"error\" middleware\n for (const mw of middleware) {\n if (!mw.onError) {\n continue;\n }\n\n try {\n const shouldSuppress = await mw.onError(context, error instanceof Error ? error : new Error(String(error)));\n if (shouldSuppress) {\n return;\n }\n } catch (mwError) {\n Logger.error({\n message: 'Middleware onError failed',\n meta: {\n middleware: mw.name,\n channel: context.channel,\n error: mwError instanceof Error ? mwError.message : String(mwError),\n },\n });\n }\n }\n\n throw error;\n }\n\n // Execute \"after\" middleware\n for (const mw of middleware) {\n if (!mw.onAfter) {\n continue;\n }\n\n try {\n await mw.onAfter(context, result);\n } catch (error) {\n Logger.error({\n message: 'Middleware onAfter failed',\n meta: {\n middleware: mw.name,\n channel: context.channel,\n error: error instanceof Error ? error.message : String(error),\n },\n });\n }\n }\n}\n\n/**\n * Built-in middleware for logging handler execution\n */\nexport const loggingMiddleware = (handlerName: string): WebSocketSubscriberMiddleware => ({\n name: 'logging',\n onBefore: context => {\n Logger.info({\n message: `${handlerName}: Starting execution`,\n meta: {\n channel: context.channel,\n },\n });\n return true;\n },\n onAfter: (context, result) => {\n Logger.info({\n message: `${handlerName}: Completed successfully`,\n meta: {\n channel: context.channel,\n resultType: typeof result,\n },\n });\n },\n onError: (context, error) => {\n Logger.error({\n message: `${handlerName}: Failed`,\n meta: {\n channel: context.channel,\n error: error.message,\n },\n });\n return false; // Don't suppress the error\n },\n});\n\n/**\n * Built-in middleware for timing handler execution\n */\nexport const timingMiddleware = (): WebSocketSubscriberMiddleware => {\n const startTimes = new Map<string, number>();\n\n return {\n name: 'timing',\n onBefore: context => {\n startTimes.set(context.channel, Date.now());\n return true;\n },\n onAfter: context => {\n const startTime = startTimes.get(context.channel);\n if (startTime) {\n const duration = Date.now() - startTime;\n startTimes.delete(context.channel);\n Logger.info({\n message: 'Handler execution timing',\n meta: {\n channel: context.channel,\n durationMs: duration,\n },\n });\n }\n },\n onError: context => {\n startTimes.delete(context.channel);\n return false;\n },\n };\n};\n\n/**\n * Built-in middleware for validating message structure\n */\nexport const validationMiddleware = (\n validator: (message: unknown) => void | Promise<void>,\n): WebSocketSubscriberMiddleware => ({\n name: 'validation',\n onBefore: async context => {\n try {\n await validator(context.message);\n return true;\n } catch (error) {\n Logger.warn({\n message: 'Message validation failed',\n meta: {\n channel: context.channel,\n error: error instanceof Error ? error.message : String(error),\n },\n });\n throw error;\n }\n },\n});\n\n/**\n * Built-in middleware for rate limiting\n */\nexport const rateLimitMiddleware = (maxExecutions: number, windowMs: number): WebSocketSubscriberMiddleware => {\n const executionTimes = new Map<string, number[]>();\n\n return {\n name: 'rate-limit',\n onBefore: context => {\n const channel = context.channel;\n const now = Date.now();\n const times = executionTimes.get(channel) ?? [];\n\n // Remove old entries\n const recentTimes = times.filter(t => now - t < windowMs);\n\n if (recentTimes.length >= maxExecutions) {\n Logger.warn({\n message: 'Rate limit exceeded',\n meta: {\n channel,\n maxExecutions,\n windowMs,\n },\n });\n return false;\n }\n\n recentTimes.push(now);\n executionTimes.set(channel, recentTimes);\n return true;\n },\n };\n};\n\n/**\n * Built-in middleware for error handling and recovery\n */\nexport const errorRecoveryMiddleware = (maxRetries = 3, _delayMs = 1000): WebSocketSubscriberMiddleware => ({\n name: 'error-recovery',\n onError: async (context, error) => {\n Logger.warn({\n message: 'Handler error, could implement retry logic',\n meta: {\n channel: context.channel,\n error: error.message,\n suggestedRetries: maxRetries,\n },\n });\n return false; // Don't suppress - let error bubble up\n },\n});\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import type { WebSocketSubscriberHandler, WebSocketSubscriberHandlerContext, WebSocketSubscriberMatcher } from './websocket.interface.js';
|
|
2
|
+
/**
|
|
3
|
+
* Utility functions for building and composing WebSocket subscriber handlers
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Create a predicate matcher for message properties
|
|
7
|
+
* @param key - The property key to check
|
|
8
|
+
* @param value - The expected value
|
|
9
|
+
*/
|
|
10
|
+
export declare function matchByProperty(key: string, value: unknown): WebSocketSubscriberMatcher;
|
|
11
|
+
/**
|
|
12
|
+
* Create a predicate matcher for message property patterns
|
|
13
|
+
* @param key - The property key to check
|
|
14
|
+
* @param predicate - Function to test the value
|
|
15
|
+
*/
|
|
16
|
+
export declare function matchByPropertyPredicate<_T = unknown>(key: string, predicate: (value: unknown) => boolean): WebSocketSubscriberMatcher;
|
|
17
|
+
/**
|
|
18
|
+
* Safely get nested property from an object
|
|
19
|
+
* @param obj - The object to search
|
|
20
|
+
* @param path - Dot-notation path (e.g., 'user.id' or 'data.items.0.name')
|
|
21
|
+
*/
|
|
22
|
+
export declare function getNestedProperty(obj: any, path: string): unknown;
|
|
23
|
+
/**
|
|
24
|
+
* Wrap a handler with error handling
|
|
25
|
+
* @param handler - The handler to wrap
|
|
26
|
+
* @param onError - Error handler callback
|
|
27
|
+
* @param throwError - Whether to rethrow the error after handling
|
|
28
|
+
*/
|
|
29
|
+
export declare function withErrorHandler<TMessage = any>(handler: WebSocketSubscriberHandler<TMessage>, onError?: (error: Error, context: WebSocketSubscriberHandlerContext<TMessage>) => void | Promise<void>, _throwError?: boolean): WebSocketSubscriberHandler<TMessage>;
|
|
30
|
+
/**
|
|
31
|
+
* Wrap a handler with logging
|
|
32
|
+
* @param handler - The handler to wrap
|
|
33
|
+
* @param handlerName - Name for logging purposes
|
|
34
|
+
*/
|
|
35
|
+
export declare function withLogging<TMessage = any>(handler: WebSocketSubscriberHandler<TMessage>, handlerName?: string): WebSocketSubscriberHandler<TMessage>;
|
|
36
|
+
/**
|
|
37
|
+
* Wrap a handler with rate limiting
|
|
38
|
+
* @param handler - The handler to wrap
|
|
39
|
+
* @param maxExecutions - Max executions allowed
|
|
40
|
+
* @param windowMs - Time window in milliseconds
|
|
41
|
+
* @param onRateLimited - Optional callback when rate limited
|
|
42
|
+
*/
|
|
43
|
+
export declare function withRateLimit<TMessage = any>(handler: WebSocketSubscriberHandler<TMessage>, maxExecutions: number, windowMs: number, onRateLimited?: (context: WebSocketSubscriberHandlerContext<TMessage>) => void | Promise<void>): WebSocketSubscriberHandler<TMessage>;
|
|
44
|
+
/**
|
|
45
|
+
* Wrap a handler with retry logic
|
|
46
|
+
* @param handler - The handler to wrap
|
|
47
|
+
* @param maxRetries - Maximum number of retries
|
|
48
|
+
* @param delayMs - Delay between retries in milliseconds
|
|
49
|
+
* @param backoffMultiplier - Multiplier for exponential backoff (default: 1, no backoff)
|
|
50
|
+
*/
|
|
51
|
+
export declare function withRetry<TMessage = any>(handler: WebSocketSubscriberHandler<TMessage>, maxRetries: number, delayMs: number, backoffMultiplier?: number): WebSocketSubscriberHandler<TMessage>;
|
|
52
|
+
/**
|
|
53
|
+
* Compose multiple handlers into a single handler
|
|
54
|
+
* Executes handlers sequentially, passing context through each one
|
|
55
|
+
* @param handlers - Array of handlers to compose
|
|
56
|
+
*/
|
|
57
|
+
export declare function composeHandlers<TMessage = any>(handlers: WebSocketSubscriberHandler<TMessage>[]): WebSocketSubscriberHandler<TMessage>;
|
|
58
|
+
/**
|
|
59
|
+
* Create a filter handler that conditionally executes based on a predicate
|
|
60
|
+
* @param predicate - Function that returns true if handler should execute
|
|
61
|
+
* @param handler - The handler to execute conditionally
|
|
62
|
+
*/
|
|
63
|
+
export declare function withFilter<TMessage = any>(predicate: (context: WebSocketSubscriberHandlerContext<TMessage>) => boolean | Promise<boolean>, handler: WebSocketSubscriberHandler<TMessage>): WebSocketSubscriberHandler<TMessage>;
|
|
64
|
+
/**
|
|
65
|
+
* Validate message structure before execution
|
|
66
|
+
* @param validator - Function that validates the message and throws if invalid
|
|
67
|
+
* @param handler - The handler to wrap
|
|
68
|
+
*/
|
|
69
|
+
export declare function withValidation<TMessage = any>(validator: (message: TMessage) => void | Promise<void>, handler: WebSocketSubscriberHandler<TMessage>): WebSocketSubscriberHandler<TMessage>;
|
|
70
|
+
/**
|
|
71
|
+
* Add metadata/context to a handler execution
|
|
72
|
+
* @param metadata - Metadata to add to context
|
|
73
|
+
* @param handler - The handler to wrap
|
|
74
|
+
*/
|
|
75
|
+
export declare function withMetadata<TMessage = any>(metadata: Record<string, unknown>, handler: WebSocketSubscriberHandler<TMessage>): WebSocketSubscriberHandler<TMessage>;
|
|
76
|
+
/**
|
|
77
|
+
* Debounce handler execution by channel
|
|
78
|
+
* @param handler - The handler to wrap
|
|
79
|
+
* @param delayMs - Debounce delay in milliseconds
|
|
80
|
+
*/
|
|
81
|
+
export declare function withDebounce<TMessage = any>(handler: WebSocketSubscriberHandler<TMessage>, delayMs: number): WebSocketSubscriberHandler<TMessage>;
|
|
82
|
+
/**
|
|
83
|
+
* Throttle handler execution by channel
|
|
84
|
+
* @param handler - The handler to wrap
|
|
85
|
+
* @param intervalMs - Throttle interval in milliseconds
|
|
86
|
+
*/
|
|
87
|
+
export declare function withThrottle<TMessage = any>(handler: WebSocketSubscriberHandler<TMessage>, intervalMs: number): WebSocketSubscriberHandler<TMessage>;
|
|
88
|
+
//# sourceMappingURL=subscriber-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subscriber-utils.d.ts","sourceRoot":"","sources":["../../src/websocket/subscriber-utils.ts"],"names":[],"mappings":"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"}
|