@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.
@@ -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,CA4BhH"}
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": ";;AAiCO,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,EACjB;AACF;AA5BgB;",
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"}
@@ -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
- defineWebSocketSubscriber
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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"}