sleepy-socket 0.6.2 → 0.8.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
@@ -154,10 +154,10 @@ Requests are sent over one socket, so responses can come back in a different ord
154
154
  For example, if you fire three requests that take 300ms, 100ms, and 200ms:
155
155
 
156
156
  ```js
157
- import SleepySocketClient, { QUEUE } from 'sleepy-socket'
157
+ import SleepySocketClient, { Queue } from 'sleepy-socket'
158
158
 
159
159
  const client = await SleepySocketClient.connect('localhost', 3000, {
160
- queue: QUEUE.FIFO,
160
+ queue: Queue.Fifo,
161
161
  })
162
162
 
163
163
  const results = []
@@ -170,11 +170,11 @@ await Promise.all([
170
170
  ```
171
171
 
172
172
  The three queue types resolve those promises differently:
173
- - `QUEUE.NONE`: each promise resolves the moment its response arrives, so `results` is `[2, 3, 1]`. This is the default.
174
- - `QUEUE.FIFO`: responses are held back until every earlier request has resolved, so `results` is `[1, 2, 3]`, matching the order you sent them.
175
- - `QUEUE.LIFO`: responses drain from the most recent request backwards, so `results` is `[3, 2, 1]`.
173
+ - `Queue.None`: each promise resolves the moment its response arrives, so `results` is `[2, 3, 1]`. This is the default.
174
+ - `Queue.Fifo`: responses are held back until every earlier request has resolved, so `results` is `[1, 2, 3]`, matching the order you sent them.
175
+ - `Queue.Lifo`: responses drain from the most recent request backwards, so `results` is `[3, 2, 1]`.
176
176
 
177
- `QUEUE.NONE` is the right choice most of the time. `QUEUE.FIFO` is useful when responses have to be applied in the order they were requested.
177
+ `Queue.None` is the right choice most of the time. `Queue.Fifo` is useful when responses have to be applied in the order they were requested.
178
178
 
179
179
  ### Mount Paths
180
180
 
@@ -202,7 +202,7 @@ The parameters are:
202
202
  - `opts`: an optional options object
203
203
 
204
204
  The `opts` object can contain these optional properties:
205
- - `queue`: how responses are handed back, one of `QUEUE.NONE`, `QUEUE.FIFO`, or `QUEUE.LIFO`. Defaults to `QUEUE.NONE`. An unrecognized value throws a `RangeError`.
205
+ - `queue`: how responses are handed back, one of `Queue.None`, `Queue.Fifo`, or `Queue.Lifo`. Defaults to `Queue.None`. An unrecognized value throws a `RangeError`.
206
206
  - `secure`: set to `true` to use `https` and `wss` instead of `http` and `ws`. Defaults to `false`.
207
207
  - `timeout`: how long to wait, in milliseconds, both for the initial connection and for each individual request. Defaults to `30_000`.
208
208
  - `serverTimeout`: how long the client tolerates silence from the server, in milliseconds, before it considers the connection dead and closes it. Defaults to `120_000`.
@@ -254,24 +254,24 @@ All of these are read-only:
254
254
  - `connectionData`: whatever payload the server attached when the connection was established. This is where application data such as an auth token shows up.
255
255
  - `token`: the reclaim token used internally to restore the session after a drop. This is not an application auth token; that would be on `connectionData`.
256
256
  - `queueType`: the configured queue type
257
- - `secure`: whether the connection uses `wss`
257
+ - `isSecure`: whether the connection uses `wss`
258
258
  - `timeout`: the configured request timeout
259
259
  - `serverTimeout`: the configured server silence timeout
260
260
  - `heartbeatInterval`: how often the client sends heartbeats. This is dictated by the server, not configured by you.
261
261
  - `mountPath`: the configured mount path
262
262
 
263
- ### `QUEUE`
263
+ ### `Queue`
264
264
 
265
- Contains the valid values for the `queue` option: `QUEUE.NONE`, `QUEUE.FIFO`, and `QUEUE.LIFO`.
265
+ Contains the valid values for the `queue` option: `Queue.None`, `Queue.Fifo`, and `Queue.Lifo`.
266
266
 
267
- ### `TYPES`
267
+ ### `MessageType`
268
268
 
269
- Contains the message type names used on the wire: `TYPES.WELCOME`, `TYPES.HEARTBEAT`, `TYPES.REQUEST`, `TYPES.RESPONSE`, and `TYPES.NOTIFICATION`. A response message's `type` is always `TYPES.RESPONSE`, and a notification's is always `TYPES.NOTIFICATION`.
269
+ Contains the message type names used on the wire: `MessageType.Welcome`, `MessageType.Heartbeat`, `MessageType.Request`, `MessageType.Response`, and `MessageType.Notification`. A response message's `type` is always `MessageType.Response`, and a notification's is always `MessageType.Notification`.
270
270
 
271
271
  ## Errors
272
272
 
273
273
  Most failures surface as thrown errors or rejected promises:
274
- - `Invalid queue type: <value>`: a `RangeError` thrown by `connect()` when `queue` isn't a valid `QUEUE` value. This is thrown before any network call is made.
274
+ - `Invalid queue type: <value>`: a `RangeError` thrown by `connect()` when `queue` isn't a valid `Queue` value. This is thrown before any network call is made.
275
275
  - `Connection failed.`: the connection couldn't be established
276
276
  - `Connection timed out.`: the connection wasn't established within `timeout` milliseconds
277
277
  - `opts.headers must be a Headers instance`: a `TypeError` thrown when a request's `headers` option isn't a `Headers` object
@@ -0,0 +1,79 @@
1
+ import { MessageType } from './messages.js';
2
+ export * from './messages.js';
3
+ export * from './utils.js';
4
+ export type TimeoutHandle = ReturnType<typeof setTimeout>;
5
+ export type IntervalHandle = ReturnType<typeof setInterval>;
6
+ export declare const Queue: {
7
+ readonly None: "none";
8
+ readonly Fifo: "fifo";
9
+ readonly Lifo: "lifo";
10
+ };
11
+ export type Queue = typeof Queue[keyof typeof Queue];
12
+ export type ReconnectOptions = {
13
+ minDelay?: number;
14
+ maxDelay?: number;
15
+ factor?: number;
16
+ random?: () => number;
17
+ };
18
+ export type ConnectOptions = {
19
+ queue?: Queue;
20
+ secure?: boolean;
21
+ timeout?: number;
22
+ serverTimeout?: number;
23
+ mountPath?: string;
24
+ reconnect?: ReconnectOptions | false;
25
+ };
26
+ export type RequestOptions = {
27
+ headers?: Headers;
28
+ query?: Record<string, unknown>;
29
+ body?: unknown;
30
+ };
31
+ export type ResponseMessage = {
32
+ id: string;
33
+ clientId: string;
34
+ type: typeof MessageType.Response;
35
+ timestamp: string;
36
+ status: number;
37
+ headers: Record<string, string>;
38
+ body: unknown;
39
+ };
40
+ export type NotificationMessage = {
41
+ id: string;
42
+ clientId: string;
43
+ type: typeof MessageType.Notification;
44
+ timestamp: string;
45
+ event: string;
46
+ headers: Record<string, string>;
47
+ body: unknown;
48
+ };
49
+ export type EventHandler = (payload: NotificationMessage) => void;
50
+ export type TicketData = {
51
+ clientId: string;
52
+ ticket: string;
53
+ data: unknown;
54
+ };
55
+ export default class SleepySocketClient {
56
+ #private;
57
+ get id(): string | null;
58
+ get isConnected(): boolean;
59
+ get isSecure(): boolean;
60
+ get queueType(): Queue;
61
+ get timeout(): number;
62
+ get heartbeatInterval(): number;
63
+ get serverTimeout(): number;
64
+ get token(): string | null;
65
+ get mountPath(): string;
66
+ get socket(): WebSocket | null;
67
+ get connectionData(): unknown;
68
+ static connect(host: string, port: number, opts?: ConnectOptions): Promise<SleepySocketClient>;
69
+ on(event: string, handler: EventHandler): void;
70
+ off(event: string, handler: EventHandler): void;
71
+ close(): Promise<void>;
72
+ head(route: string, opts?: RequestOptions): Promise<ResponseMessage>;
73
+ get(route: string, opts?: RequestOptions): Promise<ResponseMessage>;
74
+ post(route: string, opts?: RequestOptions): Promise<ResponseMessage>;
75
+ put(route: string, opts?: RequestOptions): Promise<ResponseMessage>;
76
+ patch(route: string, opts?: RequestOptions): Promise<ResponseMessage>;
77
+ delete(route: string, opts?: RequestOptions): Promise<ResponseMessage>;
78
+ }
79
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,420 @@
1
+ import { MessageType, createMessage } from './messages.js';
2
+ import { joinRoute } from './utils.js';
3
+ export * from './messages.js';
4
+ export * from './utils.js';
5
+ export const Queue = {
6
+ None: 'none',
7
+ Fifo: 'fifo',
8
+ Lifo: 'lifo',
9
+ };
10
+ const RECONNECT_JITTER = 0.5;
11
+ const JSON_CONTENT_TYPE = 'application/json;charset=utf-8';
12
+ export default class SleepySocketClient {
13
+ #id = null;
14
+ #queueType = Queue.None;
15
+ #ready = false;
16
+ #closing = false;
17
+ #secure = false;
18
+ #timeout = 30_000;
19
+ #serverTimeout = 120_000;
20
+ #heartbeatInterval = 30_000;
21
+ #mountPath = '';
22
+ #host = null;
23
+ #port = null;
24
+ #token = null;
25
+ #socket = null;
26
+ #random = Math.random;
27
+ #livenessTimer = null;
28
+ #heartbeatTimer = null;
29
+ #reconnectTimer = null;
30
+ #reconnectConfig = null;
31
+ #connectionData = null;
32
+ #listeners = new Map();
33
+ #dispatchedMessages = [];
34
+ get id() {
35
+ return this.#id;
36
+ }
37
+ get isConnected() {
38
+ return this.#ready;
39
+ }
40
+ get isSecure() {
41
+ return this.#secure;
42
+ }
43
+ get queueType() {
44
+ return this.#queueType;
45
+ }
46
+ get timeout() {
47
+ return this.#timeout;
48
+ }
49
+ get heartbeatInterval() {
50
+ return this.#heartbeatInterval;
51
+ }
52
+ get serverTimeout() {
53
+ return this.#serverTimeout;
54
+ }
55
+ get token() {
56
+ return this.#token;
57
+ }
58
+ get mountPath() {
59
+ return this.#mountPath;
60
+ }
61
+ get socket() {
62
+ return this.#socket;
63
+ }
64
+ get connectionData() {
65
+ return this.#connectionData;
66
+ }
67
+ static async connect(host, port, opts = {}) {
68
+ if (opts.queue && !Object.values(Queue).includes(opts.queue)) {
69
+ throw new RangeError(`Invalid queue type: ${opts.queue}`);
70
+ }
71
+ const client = new this();
72
+ const reconnect = opts.reconnect && typeof opts.reconnect === 'object'
73
+ ? opts.reconnect
74
+ : {};
75
+ client.#host = host;
76
+ client.#port = port;
77
+ client.#queueType = opts.queue ?? Queue.None;
78
+ client.#secure = opts.secure ?? false;
79
+ client.#timeout = opts.timeout ?? 30_000;
80
+ client.#serverTimeout = opts.serverTimeout ?? 120_000;
81
+ client.#mountPath = opts.mountPath ?? '';
82
+ if (opts.reconnect !== false) {
83
+ client.#reconnectConfig = {
84
+ minDelay: reconnect.minDelay ?? 500,
85
+ maxDelay: reconnect.maxDelay ?? 30_000,
86
+ factor: reconnect.factor ?? 2,
87
+ };
88
+ }
89
+ client.#random = reconnect.random ?? Math.random;
90
+ await client.#establish();
91
+ return client;
92
+ }
93
+ #baseUrl() {
94
+ const protocol = this.#secure ? 'https' : 'http';
95
+ return `${protocol}://${this.#host}:${this.#port}${this.#mountPath}`;
96
+ }
97
+ async #createTicket() {
98
+ const response = await fetch(`${this.#baseUrl()}/ws`, {
99
+ method: 'POST',
100
+ });
101
+ return await response.json();
102
+ }
103
+ async #reclaimTicket() {
104
+ const url = `${this.#baseUrl()}/ws/${this.#id}`;
105
+ const response = await fetch(url, {
106
+ method: 'PUT',
107
+ headers: {
108
+ authorization: `Bearer ${this.#token}`,
109
+ },
110
+ });
111
+ if (!response.ok) {
112
+ return null;
113
+ }
114
+ return await response.json();
115
+ }
116
+ async #requestTicket() {
117
+ if (this.#id && this.#token) {
118
+ const reclaimed = await this.#reclaimTicket();
119
+ if (reclaimed) {
120
+ return reclaimed;
121
+ }
122
+ }
123
+ return this.#createTicket();
124
+ }
125
+ #socketUrl(ticket) {
126
+ const protocol = this.#secure ? 'wss' : 'ws';
127
+ const authority = `${this.#host}:${this.#port}${this.#mountPath}`;
128
+ return `${protocol}://${authority}/ws?ticket=${ticket}`;
129
+ }
130
+ #openSocket(res, succeed, fail) {
131
+ const socket = new WebSocket(this.#socketUrl(res.ticket));
132
+ this.#socket = socket;
133
+ this.#connectionData = res.data;
134
+ const onError = () => fail('Connection failed.');
135
+ const onWelcome = (event) => {
136
+ const message = JSON.parse(event.data);
137
+ socket.removeEventListener('message', onWelcome);
138
+ if (message.type !== MessageType.Welcome) {
139
+ fail('Expected a welcome message.');
140
+ return;
141
+ }
142
+ this.#id = message.clientId;
143
+ this.#token = message.body.token;
144
+ this.#heartbeatInterval = message.body.heartbeatInterval;
145
+ socket.addEventListener('message', ev => this.#handleMessage(ev));
146
+ socket.addEventListener('close', ev => this.#handleClose(ev));
147
+ this.#startHeartbeat();
148
+ this.#armLiveness();
149
+ this.#ready = true;
150
+ succeed();
151
+ };
152
+ socket.addEventListener('open', () => {
153
+ socket.removeEventListener('error', onError);
154
+ socket.addEventListener('message', onWelcome);
155
+ }, { once: true });
156
+ socket.addEventListener('error', onError);
157
+ }
158
+ #establish() {
159
+ return new Promise((resolve, reject) => {
160
+ let settled = false;
161
+ const timer = setTimeout(() => {
162
+ if (settled) {
163
+ return;
164
+ }
165
+ settled = true;
166
+ this.#socket?.close();
167
+ reject(new Error('Connection timed out.'));
168
+ }, this.#timeout);
169
+ const fail = (message) => {
170
+ if (settled) {
171
+ return;
172
+ }
173
+ settled = true;
174
+ clearTimeout(timer);
175
+ reject(new Error(message));
176
+ };
177
+ const succeed = () => {
178
+ if (settled) {
179
+ return;
180
+ }
181
+ settled = true;
182
+ clearTimeout(timer);
183
+ resolve();
184
+ };
185
+ this.#requestTicket()
186
+ .then(ticketData => this.#openSocket(ticketData, succeed, fail))
187
+ .catch(() => fail('Connection failed.'));
188
+ });
189
+ }
190
+ #armLiveness() {
191
+ if (this.#livenessTimer) {
192
+ clearTimeout(this.#livenessTimer);
193
+ }
194
+ this.#livenessTimer = setTimeout(() => {
195
+ this.#socket?.close();
196
+ }, this.serverTimeout);
197
+ }
198
+ #scheduleReconnect(attempt, config) {
199
+ const { minDelay, maxDelay, factor } = config;
200
+ const base = Math.min(minDelay * factor ** attempt, maxDelay);
201
+ const delay = base * (1 + this.#random() * RECONNECT_JITTER);
202
+ this.#reconnectTimer = setTimeout(async () => {
203
+ this.#reconnectTimer = null;
204
+ if (this.#closing) {
205
+ return;
206
+ }
207
+ try {
208
+ await this.#establish();
209
+ }
210
+ catch {
211
+ if (this.#closing) {
212
+ return;
213
+ }
214
+ this.#scheduleReconnect(attempt + 1, config);
215
+ }
216
+ }, delay);
217
+ }
218
+ #startHeartbeat() {
219
+ this.#heartbeatTimer = setInterval(() => {
220
+ const message = createMessage(this.#id, MessageType.Heartbeat);
221
+ this.#socket.send(JSON.stringify(message));
222
+ }, this.#heartbeatInterval);
223
+ }
224
+ #stopHeartbeat() {
225
+ if (this.#heartbeatTimer) {
226
+ clearInterval(this.#heartbeatTimer);
227
+ }
228
+ this.#heartbeatTimer = null;
229
+ }
230
+ #normalizeRequestOpts(opts) {
231
+ if (opts.headers !== undefined && !(opts.headers instanceof Headers)) {
232
+ throw new TypeError('opts.headers must be a Headers instance');
233
+ }
234
+ const headers = opts.headers ?? new Headers();
235
+ const query = opts.query ?? {};
236
+ const body = opts.body ?? null;
237
+ const isJsonBody = body !== null && typeof body === 'object';
238
+ if (isJsonBody && !headers.has('content-type')) {
239
+ headers.set('content-type', JSON_CONTENT_TYPE);
240
+ }
241
+ return {
242
+ headers,
243
+ query,
244
+ body,
245
+ };
246
+ }
247
+ #sendRequest(method, route, opts = {}) {
248
+ if (!this.#ready) {
249
+ throw new Error('Socket is closed');
250
+ }
251
+ const { headers, query, body } = this.#normalizeRequestOpts(opts);
252
+ const fullRoute = joinRoute(this.#mountPath, route);
253
+ const message = createMessage(this.#id, MessageType.Request, {
254
+ method,
255
+ query,
256
+ body,
257
+ route: fullRoute,
258
+ headers: Object.fromEntries(headers),
259
+ });
260
+ return new Promise((resolve, reject) => {
261
+ const timer = setTimeout(() => {
262
+ const index = this.#dispatchedMessages.findIndex(item => item.id === message.id);
263
+ if (index !== -1) {
264
+ this.#dispatchedMessages.splice(index, 1);
265
+ }
266
+ reject(new Error('Request timed out.'));
267
+ }, this.#timeout);
268
+ this.#dispatchedMessages.push({
269
+ id: message.id,
270
+ resolve,
271
+ reject,
272
+ timer,
273
+ ready: false,
274
+ response: null,
275
+ });
276
+ this.#socket.send(JSON.stringify(message));
277
+ });
278
+ }
279
+ #handleClose(event) {
280
+ this.#ready = false;
281
+ this.#stopHeartbeat();
282
+ if (this.#livenessTimer) {
283
+ clearTimeout(this.#livenessTimer);
284
+ }
285
+ for (const entry of this.#dispatchedMessages) {
286
+ clearTimeout(entry.timer);
287
+ entry.reject(new Error('Socket closed.'));
288
+ }
289
+ this.#dispatchedMessages = [];
290
+ this.#socket = null;
291
+ if (this.#closing) {
292
+ return;
293
+ }
294
+ if (!this.#reconnectConfig) {
295
+ if (!event.wasClean) {
296
+ throw new Error(`Socket closed unexpectedly (code: ${event.code}).`);
297
+ }
298
+ return;
299
+ }
300
+ this.#scheduleReconnect(0, this.#reconnectConfig);
301
+ }
302
+ #handleRequest(data) {
303
+ const entry = this.#dispatchedMessages.find(item => item.id === data.id);
304
+ if (!entry) {
305
+ return;
306
+ }
307
+ clearTimeout(entry.timer);
308
+ entry.response = data;
309
+ entry.ready = true;
310
+ this.#drain();
311
+ }
312
+ #handleNotification(data) {
313
+ this.#emit('notification', data);
314
+ }
315
+ #handleMessage(event) {
316
+ this.#armLiveness();
317
+ const data = JSON.parse(event.data);
318
+ switch (data.type) {
319
+ case MessageType.Heartbeat:
320
+ return;
321
+ case MessageType.Response:
322
+ return this.#handleRequest(data);
323
+ case MessageType.Notification:
324
+ return this.#handleNotification(data);
325
+ default:
326
+ throw new RangeError(`Unknown message type: "${data.type}"`);
327
+ }
328
+ }
329
+ #processNone() {
330
+ this.#dispatchedMessages = this.#dispatchedMessages.filter(entry => {
331
+ if (entry.ready) {
332
+ entry.resolve(entry.response);
333
+ }
334
+ return !entry.ready;
335
+ });
336
+ }
337
+ #processFifo() {
338
+ while (this.#dispatchedMessages[0]?.ready) {
339
+ const [entry] = this.#dispatchedMessages.splice(0, 1);
340
+ entry.resolve(entry.response);
341
+ }
342
+ }
343
+ #processLifo() {
344
+ while (this.#dispatchedMessages.at(-1)?.ready) {
345
+ const entry = this.#dispatchedMessages.pop();
346
+ entry.resolve(entry.response);
347
+ }
348
+ }
349
+ #drain() {
350
+ switch (this.#queueType) {
351
+ case Queue.None:
352
+ return this.#processNone();
353
+ case Queue.Fifo:
354
+ return this.#processFifo();
355
+ case Queue.Lifo:
356
+ return this.#processLifo();
357
+ }
358
+ }
359
+ #emit(event, payload) {
360
+ const handlers = this.#listeners.get(event);
361
+ if (!handlers) {
362
+ return;
363
+ }
364
+ for (const handler of handlers) {
365
+ try {
366
+ handler(payload);
367
+ }
368
+ catch (err) {
369
+ console.error(err);
370
+ }
371
+ }
372
+ }
373
+ on(event, handler) {
374
+ if (!this.#listeners.has(event)) {
375
+ this.#listeners.set(event, new Set());
376
+ }
377
+ this.#listeners.get(event).add(handler);
378
+ }
379
+ off(event, handler) {
380
+ this.#listeners.get(event)?.delete(handler);
381
+ }
382
+ async close() {
383
+ if (this.#closing) {
384
+ throw new Error('Socket is closed');
385
+ }
386
+ this.#closing = true;
387
+ this.#ready = false;
388
+ this.#stopHeartbeat();
389
+ if (this.#livenessTimer) {
390
+ clearTimeout(this.#livenessTimer);
391
+ }
392
+ if (this.#reconnectTimer) {
393
+ clearTimeout(this.#reconnectTimer);
394
+ }
395
+ this.#reconnectTimer = null;
396
+ if (this.#socket) {
397
+ await this.#socket.close();
398
+ this.#socket = null;
399
+ }
400
+ }
401
+ head(route, opts = {}) {
402
+ return this.#sendRequest('HEAD', route, opts);
403
+ }
404
+ get(route, opts = {}) {
405
+ return this.#sendRequest('GET', route, opts);
406
+ }
407
+ post(route, opts = {}) {
408
+ return this.#sendRequest('POST', route, opts);
409
+ }
410
+ put(route, opts = {}) {
411
+ return this.#sendRequest('PUT', route, opts);
412
+ }
413
+ patch(route, opts = {}) {
414
+ return this.#sendRequest('PATCH', route, opts);
415
+ }
416
+ delete(route, opts = {}) {
417
+ return this.#sendRequest('DELETE', route, opts);
418
+ }
419
+ }
420
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAEtC,cAAc,eAAe,CAAA;AAC7B,cAAc,YAAY,CAAA;AAK1B,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB,IAAI,EAAE,MAAM;IACZ,IAAI,EAAE,MAAM;IACZ,IAAI,EAAE,MAAM;CACJ,CAAA;AA2EV,MAAM,gBAAgB,GAAG,GAAG,CAAA;AAC5B,MAAM,iBAAiB,GAAG,gCAAgC,CAAA;AAE1D,MAAM,CAAC,OAAO,OAAO,kBAAkB;IACrC,GAAG,GAAkB,IAAI,CAAA;IACzB,UAAU,GAAU,KAAK,CAAC,IAAI,CAAA;IAC9B,MAAM,GAAG,KAAK,CAAA;IACd,QAAQ,GAAG,KAAK,CAAA;IAChB,OAAO,GAAG,KAAK,CAAA;IACf,QAAQ,GAAG,MAAM,CAAA;IACjB,cAAc,GAAG,OAAO,CAAA;IACxB,kBAAkB,GAAG,MAAM,CAAA;IAC3B,UAAU,GAAG,EAAE,CAAA;IACf,KAAK,GAAkB,IAAI,CAAA;IAC3B,KAAK,GAAkB,IAAI,CAAA;IAC3B,MAAM,GAAkB,IAAI,CAAA;IAC5B,OAAO,GAAqB,IAAI,CAAA;IAChC,OAAO,GAAiB,IAAI,CAAC,MAAM,CAAA;IACnC,cAAc,GAAyC,IAAI,CAAA;IAC3D,eAAe,GAA0C,IAAI,CAAA;IAC7D,eAAe,GAAyC,IAAI,CAAA;IAC5D,gBAAgB,GAA2B,IAAI,CAAA;IAC/C,eAAe,GAAY,IAAI,CAAA;IAC/B,UAAU,GAAG,IAAI,GAAG,EAA6B,CAAA;IACjD,mBAAmB,GAAwB,EAAE,CAAA;IAE7C,IAAI,EAAE;QACJ,OAAO,IAAI,CAAC,GAAG,CAAA;IACjB,CAAC;IAED,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,MAAM,CAAA;IACpB,CAAC;IAED,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,OAAO,CAAA;IACrB,CAAC;IAED,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,UAAU,CAAA;IACxB,CAAC;IAED,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,QAAQ,CAAA;IACtB,CAAC;IAED,IAAI,iBAAiB;QACnB,OAAO,IAAI,CAAC,kBAAkB,CAAA;IAChC,CAAC;IAED,IAAI,aAAa;QACf,OAAO,IAAI,CAAC,cAAc,CAAA;IAC5B,CAAC;IAED,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,MAAM,CAAA;IACpB,CAAC;IAED,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,UAAU,CAAA;IACxB,CAAC;IAED,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,OAAO,CAAA;IACrB,CAAC;IAED,IAAI,cAAc;QAChB,OAAO,IAAI,CAAC,eAAe,CAAA;IAC7B,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,OAAO,CAClB,IAAY,EACZ,IAAY,EACZ,OAAuB,EAAE;QAEzB,IAAI,IAAI,CAAC,KAAK,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YAC7D,MAAM,IAAI,UAAU,CAAC,uBAAuB,IAAI,CAAC,KAAK,EAAE,CAAC,CAAA;QAC3D,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,IAAI,EAAE,CAAA;QAEzB,MAAM,SAAS,GACb,IAAI,CAAC,SAAS,IAAI,OAAO,IAAI,CAAC,SAAS,KAAK,QAAQ;YAClD,CAAC,CAAC,IAAI,CAAC,SAAS;YAChB,CAAC,CAAC,EAAE,CAAA;QAER,MAAM,CAAC,KAAK,GAAG,IAAI,CAAA;QACnB,MAAM,CAAC,KAAK,GAAG,IAAI,CAAA;QACnB,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,CAAA;QAC5C,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC,MAAM,IAAI,KAAK,CAAA;QACrC,MAAM,CAAC,QAAQ,GAAG,IAAI,CAAC,OAAO,IAAI,MAAM,CAAA;QACxC,MAAM,CAAC,cAAc,GAAG,IAAI,CAAC,aAAa,IAAI,OAAO,CAAA;QACrD,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC,SAAS,IAAI,EAAE,CAAA;QAExC,IAAI,IAAI,CAAC,SAAS,KAAK,KAAK,EAAE,CAAC;YAC7B,MAAM,CAAC,gBAAgB,GAAG;gBACxB,QAAQ,EAAE,SAAS,CAAC,QAAQ,IAAI,GAAG;gBACnC,QAAQ,EAAE,SAAS,CAAC,QAAQ,IAAI,MAAM;gBACtC,MAAM,EAAE,SAAS,CAAC,MAAM,IAAI,CAAC;aAC9B,CAAA;QACH,CAAC;QAED,MAAM,CAAC,OAAO,GAAG,SAAS,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAA;QAEhD,MAAM,MAAM,CAAC,UAAU,EAAE,CAAA;QAEzB,OAAO,MAAM,CAAA;IACf,CAAC;IAED,QAAQ;QACN,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAA;QAEhD,OAAO,GAAG,QAAQ,MAAM,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,UAAU,EAAE,CAAA;IACtE,CAAC;IAED,KAAK,CAAC,aAAa;QACjB,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE;YACpD,MAAM,EAAE,MAAM;SACf,CAAC,CAAA;QAEF,OAAO,MAAM,QAAQ,CAAC,IAAI,EAAgB,CAAA;IAC5C,CAAC;IAED,KAAK,CAAC,cAAc;QAClB,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,QAAQ,EAAE,OAAO,IAAI,CAAC,GAAG,EAAE,CAAA;QAE/C,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAChC,MAAM,EAAE,KAAK;YACb,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,IAAI,CAAC,MAAM,EAAE;aACvC;SACF,CAAC,CAAA;QAEF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,OAAO,IAAI,CAAA;QACb,CAAC;QAED,OAAO,MAAM,QAAQ,CAAC,IAAI,EAAgB,CAAA;IAC5C,CAAC;IAED,KAAK,CAAC,cAAc;QAClB,IAAI,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAC5B,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,cAAc,EAAE,CAAA;YAE7C,IAAI,SAAS,EAAE,CAAC;gBACd,OAAO,SAAS,CAAA;YAClB,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC,aAAa,EAAE,CAAA;IAC7B,CAAC;IAED,UAAU,CAAE,MAAc;QACxB,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAA;QAC5C,MAAM,SAAS,GAAG,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,UAAU,EAAE,CAAA;QAEjE,OAAO,GAAG,QAAQ,MAAM,SAAS,cAAc,MAAM,EAAE,CAAA;IACzD,CAAC;IAED,WAAW,CACT,GAAe,EACf,OAAmB,EACnB,IAA+B;QAE/B,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAA;QAEzD,IAAI,CAAC,OAAO,GAAG,MAAM,CAAA;QACrB,IAAI,CAAC,eAAe,GAAG,GAAG,CAAC,IAAI,CAAA;QAE/B,MAAM,OAAO,GAAG,GAAS,EAAE,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAA;QAEtD,MAAM,SAAS,GAAG,CAAC,KAAmB,EAAQ,EAAE;YAC9C,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;YAEtC,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAA;YAEhD,IAAI,OAAO,CAAC,IAAI,KAAK,WAAW,CAAC,OAAO,EAAE,CAAC;gBACzC,IAAI,CAAC,6BAA6B,CAAC,CAAA;gBAEnC,OAAM;YACR,CAAC;YAED,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAA;YAC3B,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAA;YAChC,IAAI,CAAC,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAA;YAExD,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC,CAAA;YACjE,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,CAAA;YAE7D,IAAI,CAAC,eAAe,EAAE,CAAA;YACtB,IAAI,CAAC,YAAY,EAAE,CAAA;YAEnB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAA;YAElB,OAAO,EAAE,CAAA;QACX,CAAC,CAAA;QAED,MAAM,CAAC,gBAAgB,CAAC,MAAM,EAAE,GAAG,EAAE;YACnC,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;YAC5C,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAA;QAC/C,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAA;QAElB,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;IAC3C,CAAC;IAED,UAAU;QACR,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,IAAI,OAAO,GAAG,KAAK,CAAA;YAEnB,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;gBAC5B,IAAI,OAAO,EAAE,CAAC;oBACZ,OAAM;gBACR,CAAC;gBAED,OAAO,GAAG,IAAI,CAAA;gBAEd,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,CAAA;gBACrB,MAAM,CAAC,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC,CAAA;YAC5C,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAA;YAEjB,MAAM,IAAI,GAAG,CAAC,OAAe,EAAQ,EAAE;gBACrC,IAAI,OAAO,EAAE,CAAC;oBACZ,OAAM;gBACR,CAAC;gBAED,OAAO,GAAG,IAAI,CAAA;gBAEd,YAAY,CAAC,KAAK,CAAC,CAAA;gBACnB,MAAM,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAA;YAC5B,CAAC,CAAA;YAED,MAAM,OAAO,GAAG,GAAS,EAAE;gBACzB,IAAI,OAAO,EAAE,CAAC;oBACZ,OAAM;gBACR,CAAC;gBAED,OAAO,GAAG,IAAI,CAAA;gBAEd,YAAY,CAAC,KAAK,CAAC,CAAA;gBACnB,OAAO,EAAE,CAAA;YACX,CAAC,CAAA;YAED,IAAI,CAAC,cAAc,EAAE;iBAClB,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;iBAC/D,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,CAAA;QAC5C,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,YAAY;QACV,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,YAAY,CAAC,IAAI,CAAC,cAAc,CAAC,CAAA;QACnC,CAAC;QAED,IAAI,CAAC,cAAc,GAAG,UAAU,CAAC,GAAG,EAAE;YACpC,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,CAAA;QACvB,CAAC,EAAE,IAAI,CAAC,aAAa,CAAC,CAAA;IACxB,CAAC;IAED,kBAAkB,CAAE,OAAe,EAAE,MAAuB;QAC1D,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,CAAA;QAC7C,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,GAAG,MAAM,IAAI,OAAO,EAAE,QAAQ,CAAC,CAAA;QAC7D,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,EAAE,GAAG,gBAAgB,CAAC,CAAA;QAE5D,IAAI,CAAC,eAAe,GAAG,UAAU,CAAC,KAAK,IAAI,EAAE;YAC3C,IAAI,CAAC,eAAe,GAAG,IAAI,CAAA;YAE3B,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAClB,OAAM;YACR,CAAC;YAED,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,UAAU,EAAE,CAAA;YACzB,CAAC;YAAC,MAAM,CAAC;gBACP,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;oBAClB,OAAM;gBACR,CAAC;gBAED,IAAI,CAAC,kBAAkB,CAAC,OAAO,GAAG,CAAC,EAAE,MAAM,CAAC,CAAA;YAC9C,CAAC;QACH,CAAC,EAAE,KAAK,CAAC,CAAA;IACX,CAAC;IAED,eAAe;QACb,IAAI,CAAC,eAAe,GAAG,WAAW,CAAC,GAAG,EAAE;YACtC,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,CAAC,GAAI,EAAE,WAAW,CAAC,SAAS,CAAC,CAAA;YAE/D,IAAI,CAAC,OAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAA;QAC7C,CAAC,EAAE,IAAI,CAAC,kBAAkB,CAAC,CAAA;IAC7B,CAAC;IAED,cAAc;QACZ,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YACzB,aAAa,CAAC,IAAI,CAAC,eAAe,CAAC,CAAA;QACrC,CAAC;QAED,IAAI,CAAC,eAAe,GAAG,IAAI,CAAA;IAC7B,CAAC;IAED,qBAAqB,CAAE,IAAoB;QACzC,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,YAAY,OAAO,CAAC,EAAE,CAAC;YACrE,MAAM,IAAI,SAAS,CAAC,yCAAyC,CAAC,CAAA;QAChE,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,IAAI,OAAO,EAAE,CAAA;QAC7C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,EAAE,CAAA;QAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAA;QAE9B,MAAM,UAAU,GAAG,IAAI,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,CAAA;QAE5D,IAAI,UAAU,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,CAAC;YAC/C,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,iBAAiB,CAAC,CAAA;QAChD,CAAC;QAED,OAAO;YACL,OAAO;YACP,KAAK;YACL,IAAI;SACL,CAAA;IACH,CAAC;IAED,YAAY,CACV,MAAc,EACd,KAAa,EACb,OAAuB,EAAE;QAEzB,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAA;QACrC,CAAC;QAED,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAA;QACjE,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,CAAA;QAEnD,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,CAAC,GAAI,EAAE,WAAW,CAAC,OAAO,EAAE;YAC5D,MAAM;YACN,KAAK;YACL,IAAI;YACJ,KAAK,EAAE,SAAS;YAChB,OAAO,EAAE,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC;SACrC,CAAC,CAAA;QAEF,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;gBAC5B,MAAM,KAAK,GAAG,IAAI,CAAC,mBAAmB,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CACtD,IAAI,CAAC,EAAE,KAAK,OAAO,CAAC,EAAE,CACvB,CAAA;gBAED,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;oBACjB,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAA;gBAC3C,CAAC;gBAED,MAAM,CAAC,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC,CAAA;YACzC,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAA;YAEjB,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC;gBAC5B,EAAE,EAAE,OAAO,CAAC,EAAE;gBACd,OAAO;gBACP,MAAM;gBACN,KAAK;gBACL,KAAK,EAAE,KAAK;gBACZ,QAAQ,EAAE,IAAI;aACf,CAAC,CAAA;YAEF,IAAI,CAAC,OAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAA;QAC7C,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,YAAY,CAAE,KAAiB;QAC7B,IAAI,CAAC,MAAM,GAAG,KAAK,CAAA;QAEnB,IAAI,CAAC,cAAc,EAAE,CAAA;QAErB,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,YAAY,CAAC,IAAI,CAAC,cAAc,CAAC,CAAA;QACnC,CAAC;QAED,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC7C,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;YACzB,KAAK,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAA;QAC3C,CAAC;QAED,IAAI,CAAC,mBAAmB,GAAG,EAAE,CAAA;QAC7B,IAAI,CAAC,OAAO,GAAG,IAAI,CAAA;QAEnB,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,OAAM;QACR,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC3B,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;gBACpB,MAAM,IAAI,KAAK,CAAC,qCAAqC,KAAK,CAAC,IAAI,IAAI,CAAC,CAAA;YACtE,CAAC;YAED,OAAM;QACR,CAAC;QAED,IAAI,CAAC,kBAAkB,CAAC,CAAC,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAA;IACnD,CAAC;IAED,cAAc,CAAE,IAAqB;QACnC,MAAM,KAAK,GAAG,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC,CAAA;QAExE,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAM;QACR,CAAC;QAED,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QAEzB,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAA;QACrB,KAAK,CAAC,KAAK,GAAG,IAAI,CAAA;QAElB,IAAI,CAAC,MAAM,EAAE,CAAA;IACf,CAAC;IAED,mBAAmB,CAAE,IAAyB;QAC5C,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE,IAAI,CAAC,CAAA;IAClC,CAAC;IAED,cAAc,CAAE,KAAmB;QACjC,IAAI,CAAC,YAAY,EAAE,CAAA;QAEnB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QAEnC,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;YAClB,KAAK,WAAW,CAAC,SAAS;gBACxB,OAAM;YAER,KAAK,WAAW,CAAC,QAAQ;gBACvB,OAAO,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAA;YAElC,KAAK,WAAW,CAAC,YAAY;gBAC3B,OAAO,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAA;YAEvC;gBACE,MAAM,IAAI,UAAU,CAAC,0BAA0B,IAAI,CAAC,IAAI,GAAG,CAAC,CAAA;QAChE,CAAC;IACH,CAAC;IAED,YAAY;QACV,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;YACjE,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;gBAChB,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,QAAS,CAAC,CAAA;YAChC,CAAC;YAED,OAAO,CAAC,KAAK,CAAC,KAAK,CAAA;QACrB,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,YAAY;QACV,OAAO,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC;YAC1C,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;YAErD,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,QAAS,CAAC,CAAA;QAChC,CAAC;IACH,CAAC;IAED,YAAY;QACV,OAAO,IAAI,CAAC,mBAAmB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC;YAC9C,MAAM,KAAK,GAAG,IAAI,CAAC,mBAAmB,CAAC,GAAG,EAAE,CAAA;YAE5C,KAAM,CAAC,OAAO,CAAC,KAAM,CAAC,QAAS,CAAC,CAAA;QAClC,CAAC;IACH,CAAC;IAED,MAAM;QACJ,QAAQ,IAAI,CAAC,UAAU,EAAE,CAAC;YACxB,KAAK,KAAK,CAAC,IAAI;gBACb,OAAO,IAAI,CAAC,YAAY,EAAE,CAAA;YAE5B,KAAK,KAAK,CAAC,IAAI;gBACb,OAAO,IAAI,CAAC,YAAY,EAAE,CAAA;YAE5B,KAAK,KAAK,CAAC,IAAI;gBACb,OAAO,IAAI,CAAC,YAAY,EAAE,CAAA;QAC9B,CAAC;IACH,CAAC;IAED,KAAK,CAAE,KAAa,EAAE,OAA4B;QAChD,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;QAE3C,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAM;QACR,CAAC;QAED,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,IAAI,CAAC;gBACH,OAAO,CAAC,OAAO,CAAC,CAAA;YAClB,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;YACpB,CAAC;QACH,CAAC;IACH,CAAC;IAED,EAAE,CAAE,KAAa,EAAE,OAAqB;QACtC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YAChC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,GAAG,EAAE,CAAC,CAAA;QACvC,CAAC;QAED,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;IAC1C,CAAC;IAED,GAAG,CAAE,KAAa,EAAE,OAAqB;QACvC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,CAAA;IAC7C,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAA;QACrC,CAAC;QAED,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAA;QACpB,IAAI,CAAC,MAAM,GAAG,KAAK,CAAA;QAEnB,IAAI,CAAC,cAAc,EAAE,CAAA;QAErB,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,YAAY,CAAC,IAAI,CAAC,cAAc,CAAC,CAAA;QACnC,CAAC;QAED,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YACzB,YAAY,CAAC,IAAI,CAAC,eAAe,CAAC,CAAA;QACpC,CAAC;QAED,IAAI,CAAC,eAAe,GAAG,IAAI,CAAA;QAE3B,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAA;YAE1B,IAAI,CAAC,OAAO,GAAG,IAAI,CAAA;QACrB,CAAC;IACH,CAAC;IAED,IAAI,CAAE,KAAa,EAAE,OAAuB,EAAE;QAC5C,OAAO,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,CAAA;IAC/C,CAAC;IAED,GAAG,CAAE,KAAa,EAAE,OAAuB,EAAE;QAC3C,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,CAAA;IAC9C,CAAC;IAED,IAAI,CAAE,KAAa,EAAE,OAAuB,EAAE;QAC5C,OAAO,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,CAAA;IAC/C,CAAC;IAED,GAAG,CAAE,KAAa,EAAE,OAAuB,EAAE;QAC3C,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,CAAA;IAC9C,CAAC;IAED,KAAK,CAAE,KAAa,EAAE,OAAuB,EAAE;QAC7C,OAAO,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,CAAA;IAChD,CAAC;IAED,MAAM,CAAE,KAAa,EAAE,OAAuB,EAAE;QAC9C,OAAO,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC,CAAA;IACjD,CAAC;CACF"}
@@ -0,0 +1,26 @@
1
+ export declare const MessageType: {
2
+ readonly Welcome: "welcome";
3
+ readonly Heartbeat: "heartbeat";
4
+ readonly Request: "request";
5
+ readonly Response: "response";
6
+ readonly Notification: "notification";
7
+ };
8
+ export type MessageType = typeof MessageType[keyof typeof MessageType];
9
+ export type MessageHeaders = Headers | Record<string, string>;
10
+ export type MessageOptions = {
11
+ id?: string;
12
+ headers?: MessageHeaders;
13
+ body?: unknown;
14
+ [key: string]: unknown;
15
+ };
16
+ export type Message = {
17
+ id: string;
18
+ clientId: string;
19
+ type: MessageType;
20
+ timestamp: string;
21
+ headers: MessageHeaders;
22
+ body: unknown;
23
+ [key: string]: unknown;
24
+ };
25
+ export declare function createMessage(clientId: string, type: MessageType, opts?: MessageOptions): Message;
26
+ //# sourceMappingURL=messages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,WAAW;;;;;;CAMd,CAAA;AAEV,MAAM,MAAM,WAAW,GAAG,OAAO,WAAW,CAAC,MAAM,OAAO,WAAW,CAAC,CAAA;AAEtE,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;AAE7D,MAAM,MAAM,cAAc,GAAG;IAC3B,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,OAAO,CAAC,EAAE,cAAc,CAAA;IACxB,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB,CAAA;AAED,MAAM,MAAM,OAAO,GAAG;IACpB,EAAE,EAAE,MAAM,CAAA;IACV,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,WAAW,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,cAAc,CAAA;IACvB,IAAI,EAAE,OAAO,CAAA;IACb,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB,CAAA;AAED,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,WAAW,EACjB,IAAI,GAAE,cAAmB,GACxB,OAAO,CAUT"}
@@ -0,0 +1,20 @@
1
+ import { id } from './utils.js';
2
+ export const MessageType = {
3
+ Welcome: 'welcome',
4
+ Heartbeat: 'heartbeat',
5
+ Request: 'request',
6
+ Response: 'response',
7
+ Notification: 'notification',
8
+ };
9
+ export function createMessage(clientId, type, opts = {}) {
10
+ return {
11
+ ...opts,
12
+ id: opts.id ?? id(),
13
+ clientId,
14
+ type,
15
+ timestamp: new Date().toISOString(),
16
+ headers: opts.headers ?? new Headers(),
17
+ body: opts.body ?? null,
18
+ };
19
+ }
20
+ //# sourceMappingURL=messages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages.js","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,YAAY,CAAA;AAE/B,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,OAAO,EAAE,SAAS;IAClB,SAAS,EAAE,WAAW;IACtB,OAAO,EAAE,SAAS;IAClB,QAAQ,EAAE,UAAU;IACpB,YAAY,EAAE,cAAc;CACpB,CAAA;AAuBV,MAAM,UAAU,aAAa,CAC3B,QAAgB,EAChB,IAAiB,EACjB,OAAuB,EAAE;IAEzB,OAAO;QACL,GAAG,IAAI;QACP,EAAE,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE;QACnB,QAAQ;QACR,IAAI;QACJ,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,IAAI,OAAO,EAAE;QACtC,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,IAAI;KACxB,CAAA;AACH,CAAC"}
@@ -0,0 +1,6 @@
1
+ export type IdGenerator = () => string;
2
+ export declare const defaultIdGenerator: IdGenerator;
3
+ export declare function joinRoute(...segments: string[]): string;
4
+ export declare function id(): string;
5
+ export declare function setIdGenerator(fn: IdGenerator): void;
6
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GAAG,MAAM,MAAM,CAAA;AAEtC,eAAO,MAAM,kBAAkB,EAAE,WAAuC,CAAA;AAIxE,wBAAgB,SAAS,CAAE,GAAG,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,CAOxD;AAED,wBAAgB,EAAE,IAAK,MAAM,CAE5B;AAED,wBAAgB,cAAc,CAAE,EAAE,EAAE,WAAW,GAAG,IAAI,CAErD"}