faye-redis-ng 1.0.1 → 1.1.0

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/README.md CHANGED
@@ -1,23 +1,26 @@
1
1
  # faye-redis-ng
2
2
 
3
- [![npm version](https://badge.fury.io/js/faye-redis-ng.svg)](https://www.npmjs.com/package/faye-redis-ng)
3
+ ![NPM Version](https://img.shields.io/npm/v/faye-redis-ng)
4
4
  [![Node.js Version](https://img.shields.io/node/v/faye-redis-ng.svg)](https://nodejs.org)
5
- [![CI](https://github.com/YOUR-USERNAME/faye-redis-ng/workflows/CI/badge.svg)](https://github.com/YOUR-USERNAME/faye-redis-ng/actions)
5
+ [![CI](https://github.com/7a6163/faye-redis-node/workflows/CI/badge.svg)](https://github.com/7a6163/faye-redis-node/actions)
6
+ [![codecov](https://codecov.io/gh/7a6163/faye-redis-node/branch/master/graph/badge.svg)](https://codecov.io/gh/7a6163/faye-redis-node)
6
7
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
7
8
 
8
9
  **Next Generation** Redis backend engine for [Faye](http://faye.jcoglan.com) - A modern, maintained fork with Redis v4 support, ES6+ syntax, and automatic reconnection.
9
10
 
10
11
  ## 🎉 What's New in NG (Next Generation)
11
12
 
12
- This is a modernized fork of the original [faye-redis](https://github.com/faye/faye-redis-node) with significant improvements:
13
+ This is a modernized fork of the original [faye-redis](https://github.com/7a6163/faye-redis-node) with significant improvements:
13
14
 
14
15
  ### ✨ Key Improvements
15
16
 
17
+ - ✅ **TypeScript Support** - Full TypeScript rewrite with type definitions
16
18
  - ✅ **Redis v4 Support** - Uses modern Promise-based Redis client API
17
19
  - ✅ **ES6+ Syntax** - Modern JavaScript with classes, async/await, const/let
18
20
  - ✅ **Auto-Reconnection** - Automatic Redis reconnection with exponential backoff
19
21
  - ✅ **Better Error Handling** - Comprehensive error logging and event triggers
20
22
  - ✅ **Node.js 22 LTS** - Updated for latest LTS Node.js version
23
+ - ✅ **Modern Testing** - Vitest with 77%+ code coverage
21
24
  - ✅ **Zero Breaking Changes** - Drop-in replacement for original faye-redis
22
25
 
23
26
  ### 🔄 Why This Fork?
@@ -207,7 +210,7 @@ Contributions are welcome! This is a community-maintained fork. Please:
207
210
 
208
211
  ## Support
209
212
 
210
- - **Issues**: [GitHub Issues](http://github.com/faye/faye-redis-node/issues)
213
+ - **Issues**: [GitHub Issues](http://github.com/7a6163/faye-redis-node/issues)
211
214
  - **Original Project**: [faye-redis](https://github.com/faye/faye-redis-node)
212
215
 
213
216
  ---
@@ -0,0 +1,38 @@
1
+ import type { EngineOptions, FayeMessage, FayeServer, CallbackContext, ClientCallback, ExistsCallback, EmptyCallback } from './types';
2
+ declare class Engine {
3
+ private readonly DEFAULT_HOST;
4
+ private readonly DEFAULT_PORT;
5
+ private readonly DEFAULT_DATABASE;
6
+ private readonly DEFAULT_GC;
7
+ private readonly LOCK_TIMEOUT;
8
+ private _server;
9
+ private _options;
10
+ private _ns;
11
+ private _messageChannel;
12
+ private _closeChannel;
13
+ private _redis;
14
+ private _subscriber;
15
+ private _initialized;
16
+ private _subscriptionsSetUp;
17
+ private _gc;
18
+ constructor(server: FayeServer, options?: EngineOptions);
19
+ private _initializeClients;
20
+ private _reconnectStrategy;
21
+ private _waitForInit;
22
+ static create(server: FayeServer, options?: EngineOptions): Engine;
23
+ disconnect(): Promise<void>;
24
+ createClient(callback: ClientCallback, context: CallbackContext): void;
25
+ clientExists(clientId: string, callback: ExistsCallback, context: CallbackContext): void;
26
+ destroyClient(clientId: string, callback?: EmptyCallback, context?: CallbackContext): void;
27
+ ping(clientId: string): void;
28
+ subscribe(clientId: string, channel: string, callback?: EmptyCallback, context?: CallbackContext): void;
29
+ unsubscribe(clientId: string, channel: string, callback?: EmptyCallback, context?: CallbackContext): void;
30
+ publish(message: FayeMessage, channels: string[]): void;
31
+ emptyQueue(clientId: string): void;
32
+ gc(): void;
33
+ private _withLock;
34
+ }
35
+ export default Engine;
36
+ export { Engine };
37
+ export type { EngineOptions, FayeMessage, FayeServer };
38
+ //# sourceMappingURL=faye-redis.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"faye-redis.d.ts","sourceRoot":"","sources":["../src/faye-redis.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,aAAa,EACb,WAAW,EACX,UAAU,EAEV,eAAe,EACf,cAAc,EACd,cAAc,EACd,aAAa,EACd,MAAM,SAAS,CAAC;AAEjB,cAAM,MAAM;IACV,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAe;IAC5C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAQ;IACrC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAK;IACtC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAM;IACjC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAO;IAEpC,OAAO,CAAC,OAAO,CAAa;IAC5B,OAAO,CAAC,QAAQ,CAAgB;IAChC,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,WAAW,CAA4B;IAC/C,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,mBAAmB,CAAS;IACpC,OAAO,CAAC,GAAG,CAAiB;gBAEhB,MAAM,EAAE,UAAU,EAAE,OAAO,GAAE,aAAkB;YAiB7C,kBAAkB;IA0FhC,OAAO,CAAC,kBAAkB;YAYZ,YAAY;IAM1B,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,MAAM;IAI5D,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAWjC,YAAY,CAAC,QAAQ,EAAE,cAAc,EAAE,OAAO,EAAE,eAAe,GAAG,IAAI;IAqBtE,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,EAAE,OAAO,EAAE,eAAe,GAAG,IAAI;IAWxF,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,aAAa,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,IAAI;IAkC1F,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAc5B,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,aAAa,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,IAAI;IAgBvG,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,aAAa,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,IAAI;IAgBzG,OAAO,CAAC,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI;IA+BvD,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAsBlC,EAAE,IAAI,IAAI;IA0BV,OAAO,CAAC,SAAS;CA+BlB;AAED,eAAe,MAAM,CAAC;AACtB,OAAO,EAAE,MAAM,EAAE,CAAC;AAClB,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC"}
@@ -0,0 +1,336 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Engine = void 0;
4
+ const redis_1 = require("redis");
5
+ class Engine {
6
+ DEFAULT_HOST = 'localhost';
7
+ DEFAULT_PORT = 6379;
8
+ DEFAULT_DATABASE = 0;
9
+ DEFAULT_GC = 60;
10
+ LOCK_TIMEOUT = 120;
11
+ _server;
12
+ _options;
13
+ _ns;
14
+ _messageChannel;
15
+ _closeChannel;
16
+ _redis = null;
17
+ _subscriber = null;
18
+ _initialized = false;
19
+ _subscriptionsSetUp = false;
20
+ _gc;
21
+ constructor(server, options = {}) {
22
+ this._server = server;
23
+ this._options = options;
24
+ this._ns = options.namespace || '';
25
+ this._messageChannel = this._ns + '/notifications/messages';
26
+ this._closeChannel = this._ns + '/notifications/close';
27
+ // Start initialization
28
+ this._initializeClients().catch(err => {
29
+ console.error('Failed to initialize Redis clients:', err);
30
+ });
31
+ const gc = options.gc || this.DEFAULT_GC;
32
+ this._gc = setInterval(() => this.gc(), gc * 1000);
33
+ }
34
+ async _initializeClients() {
35
+ const host = this._options.host || this.DEFAULT_HOST;
36
+ const port = this._options.port || this.DEFAULT_PORT;
37
+ const db = this._options.database || this.DEFAULT_DATABASE;
38
+ const auth = this._options.password;
39
+ const socket = this._options.socket;
40
+ const clientConfig = {
41
+ database: db,
42
+ ...(auth && { password: auth }),
43
+ ...(socket && {
44
+ socket: {
45
+ path: socket,
46
+ reconnectStrategy: this._reconnectStrategy.bind(this)
47
+ }
48
+ }),
49
+ ...(!socket && {
50
+ socket: {
51
+ host,
52
+ port,
53
+ reconnectStrategy: this._reconnectStrategy.bind(this)
54
+ }
55
+ })
56
+ };
57
+ this._redis = (0, redis_1.createClient)(clientConfig);
58
+ this._subscriber = (0, redis_1.createClient)(clientConfig);
59
+ // Set up error handlers
60
+ this._redis.on('error', (err) => {
61
+ console.error('Redis client error:', err);
62
+ this._server.trigger('error', err);
63
+ });
64
+ this._subscriber.on('error', (err) => {
65
+ console.error('Redis subscriber error:', err);
66
+ this._server.trigger('error', err);
67
+ });
68
+ // Handle reconnection events
69
+ this._redis.on('reconnecting', () => {
70
+ console.log('Redis client reconnecting...');
71
+ this._initialized = false;
72
+ });
73
+ this._subscriber.on('reconnecting', () => {
74
+ console.log('Redis subscriber reconnecting...');
75
+ this._initialized = false;
76
+ });
77
+ this._redis.on('ready', () => {
78
+ console.log('Redis client ready');
79
+ this._initialized = true;
80
+ });
81
+ this._subscriber.on('ready', async () => {
82
+ console.log('Redis subscriber ready');
83
+ // Only re-subscribe after reconnection (not on initial connection)
84
+ if (this._subscriptionsSetUp) {
85
+ console.log('Redis subscriber reconnected, re-subscribing...');
86
+ try {
87
+ await this._subscriber.subscribe(this._messageChannel, (message) => {
88
+ this.emptyQueue(message);
89
+ });
90
+ await this._subscriber.subscribe(this._closeChannel, (message) => {
91
+ this._server.trigger('close', message);
92
+ });
93
+ this._initialized = true;
94
+ }
95
+ catch (err) {
96
+ console.error('Error re-subscribing after reconnection:', err);
97
+ }
98
+ }
99
+ });
100
+ await this._redis.connect();
101
+ await this._subscriber.connect();
102
+ // Initial subscription (only once)
103
+ await this._subscriber.subscribe(this._messageChannel, (message) => {
104
+ this.emptyQueue(message);
105
+ });
106
+ await this._subscriber.subscribe(this._closeChannel, (message) => {
107
+ this._server.trigger('close', message);
108
+ });
109
+ this._subscriptionsSetUp = true;
110
+ this._initialized = true;
111
+ }
112
+ _reconnectStrategy(retries) {
113
+ // Exponential backoff with max delay of 10 seconds
114
+ if (retries > 20) {
115
+ // After 20 retries, give up (roughly 2 minutes)
116
+ console.error('Redis reconnection failed after 20 retries');
117
+ return new Error('Max reconnection attempts reached');
118
+ }
119
+ const delay = Math.min(retries * 100, 10000);
120
+ console.log(`Redis reconnecting in ${delay}ms (attempt ${retries})`);
121
+ return delay;
122
+ }
123
+ async _waitForInit() {
124
+ while (!this._initialized) {
125
+ await new Promise(resolve => setTimeout(resolve, 10));
126
+ }
127
+ }
128
+ static create(server, options) {
129
+ return new this(server, options);
130
+ }
131
+ async disconnect() {
132
+ if (this._subscriber) {
133
+ await this._subscriber.unsubscribe();
134
+ await this._subscriber.quit();
135
+ }
136
+ if (this._redis) {
137
+ await this._redis.quit();
138
+ }
139
+ clearInterval(this._gc);
140
+ }
141
+ createClient(callback, context) {
142
+ this._waitForInit().then(async () => {
143
+ const clientId = this._server.generateId();
144
+ const added = await this._redis.zAdd(this._ns + '/clients', {
145
+ score: 0,
146
+ value: clientId
147
+ }, { NX: true });
148
+ if (added === 0) {
149
+ return this.createClient(callback, context);
150
+ }
151
+ this._server.debug('Created new client ?', clientId);
152
+ this.ping(clientId);
153
+ this._server.trigger('handshake', clientId);
154
+ callback.call(context, clientId);
155
+ }).catch(err => {
156
+ console.error('Error creating client:', err);
157
+ });
158
+ }
159
+ clientExists(clientId, callback, context) {
160
+ this._waitForInit().then(async () => {
161
+ const cutoff = new Date().getTime() - (1000 * 1.6 * this._server.timeout);
162
+ const score = await this._redis.zScore(this._ns + '/clients', clientId);
163
+ callback.call(context, score ? parseInt(score.toString(), 10) > cutoff : false);
164
+ }).catch(err => {
165
+ console.error('Error checking client existence:', err);
166
+ callback.call(context, false);
167
+ });
168
+ }
169
+ destroyClient(clientId, callback, context) {
170
+ this._waitForInit().then(async () => {
171
+ const channels = await this._redis.sMembers(this._ns + '/clients/' + clientId + '/channels');
172
+ const multi = this._redis.multi();
173
+ multi.zAdd(this._ns + '/clients', { score: 0, value: clientId });
174
+ for (const channel of channels) {
175
+ multi.sRem(this._ns + '/clients/' + clientId + '/channels', channel);
176
+ multi.sRem(this._ns + '/channels' + channel, clientId);
177
+ }
178
+ multi.del(this._ns + '/clients/' + clientId + '/messages');
179
+ multi.zRem(this._ns + '/clients', clientId);
180
+ multi.publish(this._closeChannel, clientId);
181
+ const results = await multi.exec();
182
+ channels.forEach((channel, i) => {
183
+ if (results[2 * i + 1] !== 1)
184
+ return;
185
+ this._server.trigger('unsubscribe', clientId, channel);
186
+ this._server.debug('Unsubscribed client ? from channel ?', clientId, channel);
187
+ });
188
+ this._server.debug('Destroyed client ?', clientId);
189
+ this._server.trigger('disconnect', clientId);
190
+ if (callback)
191
+ callback.call(context);
192
+ }).catch(err => {
193
+ console.error('Error destroying client:', err);
194
+ if (callback)
195
+ callback.call(context);
196
+ });
197
+ }
198
+ ping(clientId) {
199
+ const timeout = this._server.timeout;
200
+ if (typeof timeout !== 'number')
201
+ return;
202
+ const time = new Date().getTime();
203
+ this._server.debug('Ping ?, ?', clientId, time);
204
+ this._waitForInit().then(async () => {
205
+ await this._redis.zAdd(this._ns + '/clients', { score: time, value: clientId });
206
+ }).catch(err => {
207
+ console.error('Error pinging client:', err);
208
+ });
209
+ }
210
+ subscribe(clientId, channel, callback, context) {
211
+ this._waitForInit().then(async () => {
212
+ const added = await this._redis.sAdd(this._ns + '/clients/' + clientId + '/channels', channel);
213
+ if (added === 1) {
214
+ this._server.trigger('subscribe', clientId, channel);
215
+ }
216
+ await this._redis.sAdd(this._ns + '/channels' + channel, clientId);
217
+ this._server.debug('Subscribed client ? to channel ?', clientId, channel);
218
+ if (callback)
219
+ callback.call(context);
220
+ }).catch(err => {
221
+ console.error('Error subscribing:', err);
222
+ if (callback)
223
+ callback.call(context);
224
+ });
225
+ }
226
+ unsubscribe(clientId, channel, callback, context) {
227
+ this._waitForInit().then(async () => {
228
+ const removed = await this._redis.sRem(this._ns + '/clients/' + clientId + '/channels', channel);
229
+ if (removed === 1) {
230
+ this._server.trigger('unsubscribe', clientId, channel);
231
+ }
232
+ await this._redis.sRem(this._ns + '/channels' + channel, clientId);
233
+ this._server.debug('Unsubscribed client ? from channel ?', clientId, channel);
234
+ if (callback)
235
+ callback.call(context);
236
+ }).catch(err => {
237
+ console.error('Error unsubscribing:', err);
238
+ if (callback)
239
+ callback.call(context);
240
+ });
241
+ }
242
+ publish(message, channels) {
243
+ this._server.debug('Publishing message ?', message);
244
+ this._waitForInit().then(async () => {
245
+ const jsonMessage = JSON.stringify(message);
246
+ const keys = channels.map(c => this._ns + '/channels' + c);
247
+ const clients = await this._redis.sUnion(keys);
248
+ for (const clientId of clients) {
249
+ const queue = this._ns + '/clients/' + clientId + '/messages';
250
+ this._server.debug('Queueing for client ?: ?', clientId, message);
251
+ await this._redis.rPush(queue, jsonMessage);
252
+ await this._redis.publish(this._messageChannel, clientId);
253
+ const exists = await new Promise((resolve) => {
254
+ this.clientExists(clientId, resolve, null);
255
+ });
256
+ if (!exists) {
257
+ await this._redis.del(queue);
258
+ }
259
+ }
260
+ this._server.trigger('publish', message.clientId, message.channel, message.data);
261
+ }).catch(err => {
262
+ console.error('Error publishing:', err);
263
+ });
264
+ }
265
+ emptyQueue(clientId) {
266
+ if (!this._server.hasConnection(clientId))
267
+ return;
268
+ this._waitForInit().then(async () => {
269
+ const key = this._ns + '/clients/' + clientId + '/messages';
270
+ const multi = this._redis.multi();
271
+ multi.lRange(key, 0, -1);
272
+ multi.del(key);
273
+ const results = await multi.exec();
274
+ const jsonMessages = results[0];
275
+ if (jsonMessages && jsonMessages.length > 0) {
276
+ const messages = jsonMessages.map(json => JSON.parse(json));
277
+ this._server.deliver(clientId, messages);
278
+ }
279
+ }).catch(err => {
280
+ console.error('Error emptying queue:', err);
281
+ });
282
+ }
283
+ gc() {
284
+ const timeout = this._server.timeout;
285
+ if (typeof timeout !== 'number')
286
+ return;
287
+ this._withLock('gc', async (releaseLock) => {
288
+ const cutoff = new Date().getTime() - 1000 * 2 * timeout;
289
+ const clients = await this._redis.zRangeByScore(this._ns + '/clients', 0, cutoff);
290
+ if (clients.length === 0) {
291
+ releaseLock();
292
+ return;
293
+ }
294
+ let completed = 0;
295
+ for (const clientId of clients) {
296
+ this.destroyClient(clientId, () => {
297
+ completed++;
298
+ if (completed === clients.length) {
299
+ releaseLock();
300
+ }
301
+ }, this);
302
+ }
303
+ });
304
+ }
305
+ _withLock(lockName, callback) {
306
+ this._waitForInit().then(async () => {
307
+ const lockKey = this._ns + '/locks/' + lockName;
308
+ const currentTime = new Date().getTime();
309
+ const expiry = currentTime + this.LOCK_TIMEOUT * 1000 + 1;
310
+ const releaseLock = async () => {
311
+ if (new Date().getTime() < expiry) {
312
+ await this._redis.del(lockKey);
313
+ }
314
+ };
315
+ const set = await this._redis.setNX(lockKey, expiry.toString());
316
+ if (set) {
317
+ return callback.call(this, releaseLock);
318
+ }
319
+ const timeout = await this._redis.get(lockKey);
320
+ if (!timeout)
321
+ return;
322
+ const lockTimeout = parseInt(timeout, 10);
323
+ if (currentTime < lockTimeout)
324
+ return;
325
+ const oldValue = await this._redis.set(lockKey, expiry.toString(), { GET: true });
326
+ if (oldValue === timeout) {
327
+ callback.call(this, releaseLock);
328
+ }
329
+ }).catch(err => {
330
+ console.error('Error with lock:', err);
331
+ });
332
+ }
333
+ }
334
+ exports.Engine = Engine;
335
+ exports.default = Engine;
336
+ //# sourceMappingURL=faye-redis.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"faye-redis.js","sourceRoot":"","sources":["../src/faye-redis.ts"],"names":[],"mappings":";;;AAAA,iCAAqC;AAYrC,MAAM,MAAM;IACO,YAAY,GAAG,WAAW,CAAC;IAC3B,YAAY,GAAG,IAAI,CAAC;IACpB,gBAAgB,GAAG,CAAC,CAAC;IACrB,UAAU,GAAG,EAAE,CAAC;IAChB,YAAY,GAAG,GAAG,CAAC;IAE5B,OAAO,CAAa;IACpB,QAAQ,CAAgB;IACxB,GAAG,CAAS;IACZ,eAAe,CAAS;IACxB,aAAa,CAAS;IACtB,MAAM,GAAuB,IAAI,CAAC;IAClC,WAAW,GAAuB,IAAI,CAAC;IACvC,YAAY,GAAG,KAAK,CAAC;IACrB,mBAAmB,GAAG,KAAK,CAAC;IAC5B,GAAG,CAAiB;IAE5B,YAAY,MAAkB,EAAE,UAAyB,EAAE;QACzD,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;QACtB,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;QAExB,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,SAAS,IAAI,EAAE,CAAC;QACnC,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,GAAG,GAAG,yBAAyB,CAAC;QAC5D,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,GAAG,GAAG,sBAAsB,CAAC;QAEvD,uBAAuB;QACvB,IAAI,CAAC,kBAAkB,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;YACpC,OAAO,CAAC,KAAK,CAAC,qCAAqC,EAAE,GAAG,CAAC,CAAC;QAC5D,CAAC,CAAC,CAAC;QAEH,MAAM,EAAE,GAAG,OAAO,CAAC,EAAE,IAAI,IAAI,CAAC,UAAU,CAAC;QACzC,IAAI,CAAC,GAAG,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;IACrD,CAAC;IAEO,KAAK,CAAC,kBAAkB;QAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,IAAI,IAAI,CAAC,YAAY,CAAC;QACrD,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,IAAI,IAAI,CAAC,YAAY,CAAC;QACrD,MAAM,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,IAAI,IAAI,CAAC,gBAAgB,CAAC;QAC3D,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;QACpC,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;QAEpC,MAAM,YAAY,GAAG;YACnB,QAAQ,EAAE,EAAE;YACZ,GAAG,CAAC,IAAI,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;YAC/B,GAAG,CAAC,MAAM,IAAI;gBACZ,MAAM,EAAE;oBACN,IAAI,EAAE,MAAM;oBACZ,iBAAiB,EAAE,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC;iBACtD;aACF,CAAC;YACF,GAAG,CAAC,CAAC,MAAM,IAAI;gBACb,MAAM,EAAE;oBACN,IAAI;oBACJ,IAAI;oBACJ,iBAAiB,EAAE,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC;iBACtD;aACF,CAAC;SACH,CAAC;QAEF,IAAI,CAAC,MAAM,GAAG,IAAA,oBAAY,EAAC,YAAY,CAAC,CAAC;QACzC,IAAI,CAAC,WAAW,GAAG,IAAA,oBAAY,EAAC,YAAY,CAAC,CAAC;QAE9C,wBAAwB;QACxB,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAU,EAAE,EAAE;YACrC,OAAO,CAAC,KAAK,CAAC,qBAAqB,EAAE,GAAG,CAAC,CAAC;YAC1C,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QACrC,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAU,EAAE,EAAE;YAC1C,OAAO,CAAC,KAAK,CAAC,yBAAyB,EAAE,GAAG,CAAC,CAAC;YAC9C,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QACrC,CAAC,CAAC,CAAC;QAEH,6BAA6B;QAC7B,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,cAAc,EAAE,GAAG,EAAE;YAClC,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;YAC5C,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;QAC5B,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,cAAc,EAAE,GAAG,EAAE;YACvC,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC;YAChD,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;QAC5B,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;YAC3B,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;YAClC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QAC3B,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,KAAK,IAAI,EAAE;YACtC,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;YACtC,mEAAmE;YACnE,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC;gBAC7B,OAAO,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAC;gBAC/D,IAAI,CAAC;oBACH,MAAM,IAAI,CAAC,WAAY,CAAC,SAAS,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC,OAAO,EAAE,EAAE;wBAClE,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;oBAC3B,CAAC,CAAC,CAAC;oBACH,MAAM,IAAI,CAAC,WAAY,CAAC,SAAS,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,OAAO,EAAE,EAAE;wBAChE,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;oBACzC,CAAC,CAAC,CAAC;oBACH,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;gBAC3B,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,OAAO,CAAC,KAAK,CAAC,0CAA0C,EAAE,GAAG,CAAC,CAAC;gBACjE,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QAC5B,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC;QAEjC,mCAAmC;QACnC,MAAM,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC,OAAO,EAAE,EAAE;YACjE,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QAC3B,CAAC,CAAC,CAAC;QAEH,MAAM,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,OAAO,EAAE,EAAE;YAC/D,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC;QAChC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;IAC3B,CAAC;IAEO,kBAAkB,CAAC,OAAe;QACxC,mDAAmD;QACnD,IAAI,OAAO,GAAG,EAAE,EAAE,CAAC;YACjB,gDAAgD;YAChD,OAAO,CAAC,KAAK,CAAC,4CAA4C,CAAC,CAAC;YAC5D,OAAO,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;QACxD,CAAC;QACD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,GAAG,GAAG,EAAE,KAAK,CAAC,CAAC;QAC7C,OAAO,CAAC,GAAG,CAAC,yBAAyB,KAAK,eAAe,OAAO,GAAG,CAAC,CAAC;QACrE,OAAO,KAAK,CAAC;IACf,CAAC;IAEO,KAAK,CAAC,YAAY;QACxB,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;YAC1B,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;QACxD,CAAC;IACH,CAAC;IAED,MAAM,CAAC,MAAM,CAAC,MAAkB,EAAE,OAAuB;QACvD,OAAO,IAAI,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,CAAC;IAED,KAAK,CAAC,UAAU;QACd,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACrB,MAAM,IAAI,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC;YACrC,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;QAChC,CAAC;QACD,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QAC3B,CAAC;QACD,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC;IAED,YAAY,CAAC,QAAwB,EAAE,OAAwB;QAC7D,IAAI,CAAC,YAAY,EAAE,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;YAClC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;YAC3C,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,MAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,UAAU,EAAE;gBAC3D,KAAK,EAAE,CAAC;gBACR,KAAK,EAAE,QAAQ;aAChB,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;YAEjB,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;gBAChB,OAAO,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAC9C,CAAC;YAED,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,sBAAsB,EAAE,QAAQ,CAAC,CAAC;YACrD,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACpB,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;YAC5C,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QACnC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;YACb,OAAO,CAAC,KAAK,CAAC,wBAAwB,EAAE,GAAG,CAAC,CAAC;QAC/C,CAAC,CAAC,CAAC;IACL,CAAC;IAED,YAAY,CAAC,QAAgB,EAAE,QAAwB,EAAE,OAAwB;QAC/E,IAAI,CAAC,YAAY,EAAE,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;YAClC,MAAM,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE,GAAG,CAAC,IAAI,GAAG,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YAC1E,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,MAAO,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,GAAG,UAAU,EAAE,QAAQ,CAAC,CAAC;YACzE,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QAClF,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;YACb,OAAO,CAAC,KAAK,CAAC,kCAAkC,EAAE,GAAG,CAAC,CAAC;YACvD,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;IACL,CAAC;IAED,aAAa,CAAC,QAAgB,EAAE,QAAwB,EAAE,OAAyB;QACjF,IAAI,CAAC,YAAY,EAAE,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;YAClC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,GAAG,WAAW,GAAG,QAAQ,GAAG,WAAW,CAAC,CAAC;YAE9F,MAAM,KAAK,GAAG,IAAI,CAAC,MAAO,CAAC,KAAK,EAAE,CAAC;YACnC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,UAAU,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;YAEjE,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;gBAC/B,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,WAAW,GAAG,QAAQ,GAAG,WAAW,EAAE,OAAO,CAAC,CAAC;gBACrE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,WAAW,GAAG,OAAO,EAAE,QAAQ,CAAC,CAAC;YACzD,CAAC;YAED,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,GAAG,WAAW,GAAG,QAAQ,GAAG,WAAW,CAAC,CAAC;YAC3D,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,UAAU,EAAE,QAAQ,CAAC,CAAC;YAC5C,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;YAE5C,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC;YAEnC,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,EAAE;gBAC9B,IAAI,OAAO,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC;oBAAE,OAAO;gBACrC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,aAAa,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;gBACvD,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,sCAAsC,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;YAChF,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,oBAAoB,EAAE,QAAQ,CAAC,CAAC;YACnD,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;YAE7C,IAAI,QAAQ;gBAAE,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;YACb,OAAO,CAAC,KAAK,CAAC,0BAA0B,EAAE,GAAG,CAAC,CAAC;YAC/C,IAAI,QAAQ;gBAAE,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;IACL,CAAC;IAED,IAAI,CAAC,QAAgB;QACnB,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;QACrC,IAAI,OAAO,OAAO,KAAK,QAAQ;YAAE,OAAO;QAExC,MAAM,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC;QAElC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;QAChD,IAAI,CAAC,YAAY,EAAE,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;YAClC,MAAM,IAAI,CAAC,MAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,UAAU,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;QACnF,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;YACb,OAAO,CAAC,KAAK,CAAC,uBAAuB,EAAE,GAAG,CAAC,CAAC;QAC9C,CAAC,CAAC,CAAC;IACL,CAAC;IAED,SAAS,CAAC,QAAgB,EAAE,OAAe,EAAE,QAAwB,EAAE,OAAyB;QAC9F,IAAI,CAAC,YAAY,EAAE,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;YAClC,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,MAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,WAAW,GAAG,QAAQ,GAAG,WAAW,EAAE,OAAO,CAAC,CAAC;YAChG,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;gBAChB,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;YACvD,CAAC;YAED,MAAM,IAAI,CAAC,MAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,WAAW,GAAG,OAAO,EAAE,QAAQ,CAAC,CAAC;YACpE,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,kCAAkC,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;YAC1E,IAAI,QAAQ;gBAAE,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;YACb,OAAO,CAAC,KAAK,CAAC,oBAAoB,EAAE,GAAG,CAAC,CAAC;YACzC,IAAI,QAAQ;gBAAE,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;IACL,CAAC;IAED,WAAW,CAAC,QAAgB,EAAE,OAAe,EAAE,QAAwB,EAAE,OAAyB;QAChG,IAAI,CAAC,YAAY,EAAE,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;YAClC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,MAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,WAAW,GAAG,QAAQ,GAAG,WAAW,EAAE,OAAO,CAAC,CAAC;YAClG,IAAI,OAAO,KAAK,CAAC,EAAE,CAAC;gBAClB,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,aAAa,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;YACzD,CAAC;YAED,MAAM,IAAI,CAAC,MAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,WAAW,GAAG,OAAO,EAAE,QAAQ,CAAC,CAAC;YACpE,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,sCAAsC,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;YAC9E,IAAI,QAAQ;gBAAE,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;YACb,OAAO,CAAC,KAAK,CAAC,sBAAsB,EAAE,GAAG,CAAC,CAAC;YAC3C,IAAI,QAAQ;gBAAE,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;IACL,CAAC;IAED,OAAO,CAAC,OAAoB,EAAE,QAAkB;QAC9C,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,sBAAsB,EAAE,OAAO,CAAC,CAAC;QAEpD,IAAI,CAAC,YAAY,EAAE,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;YAClC,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;YAC5C,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,GAAG,WAAW,GAAG,CAAC,CAAC,CAAC;YAE3D,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,MAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAEhD,KAAK,MAAM,QAAQ,IAAI,OAAO,EAAE,CAAC;gBAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,GAAG,WAAW,GAAG,QAAQ,GAAG,WAAW,CAAC;gBAE9D,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,0BAA0B,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;gBAClE,MAAM,IAAI,CAAC,MAAO,CAAC,KAAK,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;gBAC7C,MAAM,IAAI,CAAC,MAAO,CAAC,OAAO,CAAC,IAAI,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAC;gBAE3D,MAAM,MAAM,GAAG,MAAM,IAAI,OAAO,CAAU,CAAC,OAAO,EAAE,EAAE;oBACpD,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;gBAC7C,CAAC,CAAC,CAAC;gBAEH,IAAI,CAAC,MAAM,EAAE,CAAC;oBACZ,MAAM,IAAI,CAAC,MAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;gBAChC,CAAC;YACH,CAAC;YAED,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;QACnF,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;YACb,OAAO,CAAC,KAAK,CAAC,mBAAmB,EAAE,GAAG,CAAC,CAAC;QAC1C,CAAC,CAAC,CAAC;IACL,CAAC;IAED,UAAU,CAAC,QAAgB;QACzB,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,QAAQ,CAAC;YAAE,OAAO;QAElD,IAAI,CAAC,YAAY,EAAE,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;YAClC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,WAAW,GAAG,QAAQ,GAAG,WAAW,CAAC;YAC5D,MAAM,KAAK,GAAG,IAAI,CAAC,MAAO,CAAC,KAAK,EAAE,CAAC;YAEnC,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACzB,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAEf,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC;YACnC,MAAM,YAAY,GAAG,OAAO,CAAC,CAAC,CAAa,CAAC;YAE5C,IAAI,YAAY,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC5C,MAAM,QAAQ,GAAG,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAgB,CAAC,CAAC;gBAC3E,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;YAC3C,CAAC;QACH,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;YACb,OAAO,CAAC,KAAK,CAAC,uBAAuB,EAAE,GAAG,CAAC,CAAC;QAC9C,CAAC,CAAC,CAAC;IACL,CAAC;IAED,EAAE;QACA,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;QACrC,IAAI,OAAO,OAAO,KAAK,QAAQ;YAAE,OAAO;QAExC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE;YACzC,MAAM,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE,GAAG,IAAI,GAAG,CAAC,GAAG,OAAO,CAAC;YAEzD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,MAAO,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,GAAG,UAAU,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;YAEnF,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACzB,WAAW,EAAE,CAAC;gBACd,OAAO;YACT,CAAC;YAED,IAAI,SAAS,GAAG,CAAC,CAAC;YAClB,KAAK,MAAM,QAAQ,IAAI,OAAO,EAAE,CAAC;gBAC/B,IAAI,CAAC,aAAa,CAAC,QAAQ,EAAE,GAAG,EAAE;oBAChC,SAAS,EAAE,CAAC;oBACZ,IAAI,SAAS,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC;wBACjC,WAAW,EAAE,CAAC;oBAChB,CAAC;gBACH,CAAC,EAAE,IAAI,CAAC,CAAC;YACX,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,SAAS,CAAC,QAAgB,EAAE,QAAoD;QACtF,IAAI,CAAC,YAAY,EAAE,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;YAClC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,GAAG,SAAS,GAAG,QAAQ,CAAC;YAChD,MAAM,WAAW,GAAG,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC;YACzC,MAAM,MAAM,GAAG,WAAW,GAAG,IAAI,CAAC,YAAY,GAAG,IAAI,GAAG,CAAC,CAAC;YAE1D,MAAM,WAAW,GAAG,KAAK,IAAmB,EAAE;gBAC5C,IAAI,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE,GAAG,MAAM,EAAE,CAAC;oBAClC,MAAM,IAAI,CAAC,MAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;gBAClC,CAAC;YACH,CAAC,CAAC;YAEF,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,MAAO,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;YACjE,IAAI,GAAG,EAAE,CAAC;gBACR,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;YAC1C,CAAC;YAED,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,MAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAChD,IAAI,CAAC,OAAO;gBAAE,OAAO;YAErB,MAAM,WAAW,GAAG,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YAC1C,IAAI,WAAW,GAAG,WAAW;gBAAE,OAAO;YAEtC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAO,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,QAAQ,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;YACnF,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;gBACzB,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;YACnC,CAAC;QACH,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;YACb,OAAO,CAAC,KAAK,CAAC,kBAAkB,EAAE,GAAG,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;IACL,CAAC;CACF;AAGQ,wBAAM;AADf,kBAAe,MAAM,CAAC"}
@@ -0,0 +1,30 @@
1
+ import { RedisClientType } from 'redis';
2
+ export interface EngineOptions {
3
+ host?: string;
4
+ port?: number;
5
+ password?: string;
6
+ database?: number;
7
+ namespace?: string;
8
+ socket?: string;
9
+ gc?: number;
10
+ }
11
+ export interface FayeMessage {
12
+ clientId?: string;
13
+ channel: string;
14
+ data: any;
15
+ id?: string;
16
+ }
17
+ export interface FayeServer {
18
+ timeout: number;
19
+ generateId(): string;
20
+ debug(...args: any[]): void;
21
+ trigger(event: string, ...args: any[]): void;
22
+ hasConnection(clientId: string): boolean;
23
+ deliver(clientId: string, messages: FayeMessage[]): void;
24
+ }
25
+ export type RedisClient = RedisClientType;
26
+ export type CallbackContext = any;
27
+ export type EmptyCallback = () => void;
28
+ export type ClientCallback = (clientId: string) => void;
29
+ export type ExistsCallback = (exists: boolean) => void;
30
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,OAAO,CAAC;AAExC,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,GAAG,CAAC;IACV,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,IAAI,MAAM,CAAC;IACrB,KAAK,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAC5B,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAC7C,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;IACzC,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC;CAC1D;AAED,MAAM,MAAM,WAAW,GAAG,eAAe,CAAC;AAE1C,MAAM,MAAM,eAAe,GAAG,GAAG,CAAC;AAElC,MAAM,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC;AACvC,MAAM,MAAM,cAAc,GAAG,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;AACxD,MAAM,MAAM,cAAc,GAAG,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC"}
package/dist/types.js ADDED
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/package.json CHANGED
@@ -15,19 +15,36 @@
15
15
  "realtime"
16
16
  ],
17
17
  "license": "MIT",
18
- "version": "1.0.1",
18
+ "version": "1.1.0",
19
19
  "engines": {
20
20
  "node": ">=22.0.0"
21
21
  },
22
- "main": "./faye-redis",
22
+ "main": "./dist/faye-redis.js",
23
+ "types": "./dist/faye-redis.d.ts",
24
+ "files": [
25
+ "dist",
26
+ "src",
27
+ "LICENSE",
28
+ "README.md"
29
+ ],
23
30
  "dependencies": {
24
31
  "redis": "^4.7.0"
25
32
  },
26
33
  "devDependencies": {
27
- "jstest": "^1.0.5"
34
+ "@types/node": "^22.10.5",
35
+ "@vitest/coverage-v8": "^2.1.8",
36
+ "@vitest/ui": "^2.1.8",
37
+ "typescript": "^5.7.2",
38
+ "vitest": "^2.1.8"
28
39
  },
29
40
  "scripts": {
30
- "test": "node spec/runner.js"
41
+ "build": "tsc",
42
+ "build:watch": "tsc --watch",
43
+ "prepublishOnly": "npm run build",
44
+ "test": "vitest run",
45
+ "test:watch": "vitest",
46
+ "test:ui": "vitest --ui",
47
+ "test:coverage": "vitest run --coverage"
31
48
  },
32
49
  "bugs": "http://github.com/7a6163/faye-redis-node/issues",
33
50
  "repository": {