@ooneex/pub-sub 1.2.2 → 1.2.4
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/index.d.ts +1 -3
- package/dist/index.js +11 -24
- package/dist/index.js.map +3 -3
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -67,11 +67,9 @@ import { AppEnv } from "@ooneex/app-env";
|
|
|
67
67
|
import { ScalarType as ScalarType3 } from "@ooneex/types";
|
|
68
68
|
declare class RedisPubSubClient<Data extends Record<string, ScalarType3>> implements IPubSubClient<Data> {
|
|
69
69
|
private readonly env;
|
|
70
|
-
private client;
|
|
70
|
+
private readonly client;
|
|
71
71
|
private subscriber;
|
|
72
72
|
constructor(env: AppEnv, options?: RedisPubSubOptionsType);
|
|
73
|
-
private connect;
|
|
74
|
-
private connectSubscriber;
|
|
75
73
|
publish(config: {
|
|
76
74
|
channel: string;
|
|
77
75
|
data: Data;
|
package/dist/index.js
CHANGED
|
@@ -79,33 +79,18 @@ class RedisPubSubClient {
|
|
|
79
79
|
throw new PubSubException("Redis connection string is required. Please provide a connection string either through the constructor options or set the PUBSUB_REDIS_URL environment variable.", "CONNECTION_FAILED");
|
|
80
80
|
}
|
|
81
81
|
const { connectionString: _, ...userOptions } = options;
|
|
82
|
-
|
|
82
|
+
this.client = new Bun.RedisClient(connectionString, {
|
|
83
83
|
connectionTimeout: 1e4,
|
|
84
|
-
idleTimeout:
|
|
84
|
+
idleTimeout: 0,
|
|
85
85
|
autoReconnect: true,
|
|
86
|
-
maxRetries:
|
|
86
|
+
maxRetries: 10,
|
|
87
87
|
enableOfflineQueue: true,
|
|
88
|
-
enableAutoPipelining: true
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
this.client = new Bun.RedisClient(connectionString, clientOptions);
|
|
92
|
-
}
|
|
93
|
-
async connect() {
|
|
94
|
-
if (!this.client.connected) {
|
|
95
|
-
await this.client.connect();
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
async connectSubscriber() {
|
|
99
|
-
if (!this.subscriber) {
|
|
100
|
-
this.subscriber = await this.client.duplicate();
|
|
101
|
-
}
|
|
102
|
-
if (!this.subscriber.connected) {
|
|
103
|
-
await this.subscriber.connect();
|
|
104
|
-
}
|
|
88
|
+
enableAutoPipelining: true,
|
|
89
|
+
...userOptions
|
|
90
|
+
});
|
|
105
91
|
}
|
|
106
92
|
async publish(config) {
|
|
107
93
|
try {
|
|
108
|
-
await this.connect();
|
|
109
94
|
const message = JSON.stringify(config.data);
|
|
110
95
|
await this.client.publish(config.channel, message);
|
|
111
96
|
} catch (error) {
|
|
@@ -114,8 +99,10 @@ class RedisPubSubClient {
|
|
|
114
99
|
}
|
|
115
100
|
async subscribe(channel, handler) {
|
|
116
101
|
try {
|
|
117
|
-
|
|
118
|
-
|
|
102
|
+
if (!this.subscriber) {
|
|
103
|
+
this.subscriber = await this.client.duplicate();
|
|
104
|
+
}
|
|
105
|
+
await this.subscriber.subscribe(channel, (message, ch) => {
|
|
119
106
|
try {
|
|
120
107
|
const data = JSON.parse(message);
|
|
121
108
|
handler({ data, channel: ch });
|
|
@@ -166,4 +153,4 @@ export {
|
|
|
166
153
|
PubSub
|
|
167
154
|
};
|
|
168
155
|
|
|
169
|
-
//# debugId=
|
|
156
|
+
//# debugId=59C3CF0C0B84473F64756E2164756E21
|
package/dist/index.js.map
CHANGED
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
"import { container, EContainerScope } from \"@ooneex/container\";\nimport type { PubSubClassType } from \"./types\";\n\nexport const decorator = {\n pubSub: (scope: EContainerScope = EContainerScope.Singleton) => {\n return (target: PubSubClassType): void => {\n container.add(target, scope);\n };\n },\n};\n",
|
|
6
6
|
"import type { ScalarType } from \"@ooneex/types\";\nimport type { ServerWebSocket } from \"bun\";\nimport type { IPubSub, IPubSubClient } from \"./types\";\n\nexport abstract class PubSub<Data extends Record<string, ScalarType> = Record<string, ScalarType>>\n implements IPubSub<Data>\n{\n protected ws: ServerWebSocket | undefined;\n\n constructor(protected readonly client: IPubSubClient<Data>) {}\n\n public abstract getChannel(): string | Promise<string>;\n public abstract handler(context: { data: Data; channel: string }): Promise<void> | void;\n\n public async publish(data: Data, options?: { ws?: ServerWebSocket }): Promise<void> {\n this.ws = options?.ws;\n await this.client.publish({\n channel: await this.getChannel(),\n data,\n });\n }\n\n public async subscribe(ws?: ServerWebSocket): Promise<void> {\n this.ws = ws;\n await this.client.subscribe(await this.getChannel(), this.handler.bind(this));\n }\n\n public async unsubscribe(ws?: ServerWebSocket): Promise<void> {\n this.ws = ws;\n await this.client.unsubscribe(await this.getChannel());\n }\n\n public async unsubscribeAll(ws?: ServerWebSocket): Promise<void> {\n this.ws = ws;\n await this.client.unsubscribeAll();\n }\n}\n",
|
|
7
7
|
"import { Exception } from \"@ooneex/exception\";\nimport { HttpStatus } from \"@ooneex/http-status\";\n\nexport class PubSubException extends Exception {\n constructor(message: string, key: string, data: Record<string, unknown> = {}) {\n super(message, {\n key,\n status: HttpStatus.Code.InternalServerError,\n data,\n });\n this.name = \"PubSubException\";\n }\n}\n",
|
|
8
|
-
"import { AppEnv } from \"@ooneex/app-env\";\nimport { inject, injectable } from \"@ooneex/container\";\nimport type { ScalarType } from \"@ooneex/types\";\nimport { PubSubException } from \"./PubSubException\";\nimport type { IPubSubClient, PubSubMessageHandlerType, RedisPubSubOptionsType } from \"./types\";\n\n@injectable()\nexport class RedisPubSubClient<Data extends Record<string, ScalarType>> implements IPubSubClient<Data> {\n private client: Bun.RedisClient;\n private subscriber: Bun.RedisClient | null = null;\n\n constructor(\n @inject(AppEnv) private readonly env: AppEnv,\n options: RedisPubSubOptionsType = {},\n ) {\n const connectionString = options.connectionString || this.env.PUBSUB_REDIS_URL;\n\n if (!connectionString) {\n throw new PubSubException(\n \"Redis connection string is required. Please provide a connection string either through the constructor options or set the PUBSUB_REDIS_URL environment variable.\",\n \"CONNECTION_FAILED\",\n );\n }\n\n const { connectionString: _, ...userOptions } = options;\n\n
|
|
8
|
+
"import { AppEnv } from \"@ooneex/app-env\";\nimport { inject, injectable } from \"@ooneex/container\";\nimport type { ScalarType } from \"@ooneex/types\";\nimport { PubSubException } from \"./PubSubException\";\nimport type { IPubSubClient, PubSubMessageHandlerType, RedisPubSubOptionsType } from \"./types\";\n\n@injectable()\nexport class RedisPubSubClient<Data extends Record<string, ScalarType>> implements IPubSubClient<Data> {\n private readonly client: Bun.RedisClient;\n private subscriber: Bun.RedisClient | null = null;\n\n constructor(\n @inject(AppEnv) private readonly env: AppEnv,\n options: RedisPubSubOptionsType = {},\n ) {\n const connectionString = options.connectionString || this.env.PUBSUB_REDIS_URL;\n\n if (!connectionString) {\n throw new PubSubException(\n \"Redis connection string is required. Please provide a connection string either through the constructor options or set the PUBSUB_REDIS_URL environment variable.\",\n \"CONNECTION_FAILED\",\n );\n }\n\n const { connectionString: _, ...userOptions } = options;\n\n this.client = new Bun.RedisClient(connectionString, {\n // Max time (ms) to wait for initial connection\n connectionTimeout: 10_000,\n // Disable idle timeout to keep connection alive during traffic bursts\n idleTimeout: 0,\n // Automatically reconnect on connection loss\n autoReconnect: true,\n // Max reconnection attempts before giving up\n maxRetries: 10,\n // Queue commands while disconnected, flush on reconnect\n enableOfflineQueue: true,\n // Batch multiple commands into fewer round-trips\n enableAutoPipelining: true,\n ...userOptions,\n });\n }\n\n public async publish(config: { channel: string; data: Data }): Promise<void> {\n try {\n const message = JSON.stringify(config.data);\n await this.client.publish(config.channel, message);\n } catch (error) {\n throw new PubSubException(`Failed to publish message to channel \"${config.channel}\": ${error}`, \"PUBLISH_FAILED\");\n }\n }\n\n public async subscribe(channel: string, handler: PubSubMessageHandlerType<Data>): Promise<void> {\n try {\n if (!this.subscriber) {\n this.subscriber = await this.client.duplicate();\n }\n\n await this.subscriber.subscribe(channel, (message: string, ch: string) => {\n try {\n const data = JSON.parse(message) as Data;\n handler({ data, channel: ch });\n } catch {\n // Ignore malformed messages\n }\n });\n } catch (error) {\n throw new PubSubException(`Failed to subscribe to channel \"${channel}\": ${error}`, \"SUBSCRIBE_FAILED\");\n }\n }\n\n public async unsubscribe(channel: string): Promise<void> {\n try {\n if (!this.subscriber) {\n return;\n }\n\n await this.subscriber.unsubscribe(channel);\n } catch (error) {\n throw new PubSubException(`Failed to unsubscribe from channel \"${channel}\": ${error}`, \"UNSUBSCRIBE_FAILED\");\n }\n }\n\n public async unsubscribeAll(): Promise<void> {\n try {\n if (!this.subscriber) {\n return;\n }\n\n await this.subscriber.unsubscribe();\n } catch (error) {\n throw new PubSubException(`Failed to unsubscribe from all channels: ${error}`, \"UNSUBSCRIBE_ALL_FAILED\");\n }\n }\n\n public close(): void {\n this.subscriber?.close();\n this.subscriber = null;\n this.client.close();\n }\n}\n"
|
|
9
9
|
],
|
|
10
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAGO,IAAM,YAAY;AAAA,EACvB,QAAQ,CAAC,QAAyB,gBAAgB,cAAc;AAAA,IAC9D,OAAO,CAAC,WAAkC;AAAA,MACxC,UAAU,IAAI,QAAQ,KAAK;AAAA;AAAA;AAGjC;;ACLO,MAAe,OAEtB;AAAA,EAGiC;AAAA,EAFrB;AAAA,EAEV,WAAW,CAAoB,QAA6B;AAAA,IAA7B;AAAA;AAAA,OAKlB,QAAO,CAAC,MAAY,SAAmD;AAAA,IAClF,KAAK,KAAK,SAAS;AAAA,IACnB,MAAM,KAAK,OAAO,QAAQ;AAAA,MACxB,SAAS,MAAM,KAAK,WAAW;AAAA,MAC/B;AAAA,IACF,CAAC;AAAA;AAAA,OAGU,UAAS,CAAC,IAAqC;AAAA,IAC1D,KAAK,KAAK;AAAA,IACV,MAAM,KAAK,OAAO,UAAU,MAAM,KAAK,WAAW,GAAG,KAAK,QAAQ,KAAK,IAAI,CAAC;AAAA;AAAA,OAGjE,YAAW,CAAC,IAAqC;AAAA,IAC5D,KAAK,KAAK;AAAA,IACV,MAAM,KAAK,OAAO,YAAY,MAAM,KAAK,WAAW,CAAC;AAAA;AAAA,OAG1C,eAAc,CAAC,IAAqC;AAAA,IAC/D,KAAK,KAAK;AAAA,IACV,MAAM,KAAK,OAAO,eAAe;AAAA;AAErC;;ACpCA;AACA;AAAA;AAEO,MAAM,wBAAwB,UAAU;AAAA,EAC7C,WAAW,CAAC,SAAiB,KAAa,OAAgC,CAAC,GAAG;AAAA,IAC5E,MAAM,SAAS;AAAA,MACb;AAAA,MACA,QAAQ,WAAW,KAAK;AAAA,MACxB;AAAA,IACF,CAAC;AAAA,IACD,KAAK,OAAO;AAAA;AAEhB;;ACZA;AACA;AAMO,MAAM,kBAA0F;AAAA,EAKlE;AAAA,
|
|
11
|
-
"debugId": "
|
|
10
|
+
"mappings": "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",
|
|
11
|
+
"debugId": "59C3CF0C0B84473F64756E2164756E21",
|
|
12
12
|
"names": []
|
|
13
13
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ooneex/pub-sub",
|
|
3
3
|
"description": "Publish-subscribe messaging system for decoupled, event-driven communication between application components with typed event channels",
|
|
4
|
-
"version": "1.2.
|
|
4
|
+
"version": "1.2.4",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
7
7
|
"dist",
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
"test": "bun test tests"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@ooneex/app-env": "^1.
|
|
32
|
-
"@ooneex/container": "^1.5.
|
|
31
|
+
"@ooneex/app-env": "^1.6.0",
|
|
32
|
+
"@ooneex/container": "^1.5.1",
|
|
33
33
|
"@ooneex/exception": "^1.2.9",
|
|
34
34
|
"@ooneex/http-status": "^1.1.11"
|
|
35
35
|
},
|