@rfkit/json-rpc-websocket 0.2.2 → 0.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.
Files changed (2) hide show
  1. package/index.js +1 -885
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -1,885 +1 @@
1
- function encodeUtf8(str) {
2
- const length = str.length;
3
- let ascii = true;
4
- for(let i = 0; i < length; i++)if (str.charCodeAt(i) > 127) {
5
- ascii = false;
6
- break;
7
- }
8
- if (ascii) {
9
- const bytes = new Uint8Array(length);
10
- for(let i = 0; i < length; i++)bytes[i] = str.charCodeAt(i);
11
- return bytes;
12
- }
13
- let bytes = new Uint8Array(2 * length);
14
- let pos = 0;
15
- for(let i = 0; i < length; i++){
16
- let code = str.charCodeAt(i);
17
- if (pos + 4 > bytes.length) {
18
- const newBytes = new Uint8Array(Math.ceil(1.5 * bytes.length));
19
- newBytes.set(bytes);
20
- bytes = newBytes;
21
- }
22
- if (code < 0x80) bytes[pos++] = code;
23
- else if (code < 0x800) {
24
- bytes[pos++] = 0xc0 | code >>> 6;
25
- bytes[pos++] = 0x80 | 0x3f & code;
26
- } else if (code >= 0xd800 && code < 0xdc00) {
27
- if (i + 1 >= length) throw new Error('UTF-8 encode: incomplete surrogate pair');
28
- const code2 = str.charCodeAt(++i);
29
- if (code2 < 0xdc00 || code2 > 0xdfff) throw new Error(`UTF-8 encode: second surrogate character 0x${code2.toString(16)} at index ${i} out of range`);
30
- code = 0x10000 + ((0x3ff & code) << 10) + (0x3ff & code2);
31
- bytes[pos++] = 0xf0 | code >>> 18;
32
- bytes[pos++] = 0x80 | code >>> 12 & 0x3f;
33
- bytes[pos++] = 0x80 | code >>> 6 & 0x3f;
34
- bytes[pos++] = 0x80 | 0x3f & code;
35
- } else {
36
- bytes[pos++] = 0xe0 | code >>> 12;
37
- bytes[pos++] = 0x80 | code >>> 6 & 0x3f;
38
- bytes[pos++] = 0x80 | 0x3f & code;
39
- }
40
- }
41
- return bytes.subarray(0, pos);
42
- }
43
- function decodeUtf8(bytes, start, length) {
44
- const end = start + length;
45
- let ascii = true;
46
- for(let i = start; i < end; i++)if (bytes[i] > 127) {
47
- ascii = false;
48
- break;
49
- }
50
- if (ascii) return String.fromCharCode(...bytes.subarray(start, end));
51
- let str = '';
52
- let i = start;
53
- while(i < end){
54
- const byte1 = bytes[i++];
55
- if (byte1 < 0x80) str += String.fromCharCode(byte1);
56
- else if (byte1 < 0xe0) {
57
- if (i >= end) throw new Error('UTF-8 decode: incomplete 2-byte sequence');
58
- const byte2 = bytes[i++];
59
- str += String.fromCharCode((0x1f & byte1) << 6 | 0x3f & byte2);
60
- } else if (byte1 < 0xf0) {
61
- if (i + 1 >= end) throw new Error('UTF-8 decode: incomplete 3-byte sequence');
62
- const byte2 = bytes[i++];
63
- const byte3 = bytes[i++];
64
- str += String.fromCharCode((0x0f & byte1) << 12 | (0x3f & byte2) << 6 | 0x3f & byte3);
65
- } else {
66
- if (i + 2 >= end) throw new Error('UTF-8 decode: incomplete 4-byte sequence');
67
- const byte2 = bytes[i++];
68
- const byte3 = bytes[i++];
69
- const byte4 = bytes[i++];
70
- let code = (0x07 & byte1) << 18 | (0x3f & byte2) << 12 | (0x3f & byte3) << 6 | 0x3f & byte4;
71
- if (code <= 0xffff) str += String.fromCharCode(code);
72
- else if (code <= 0x10ffff) {
73
- code -= 0x10000;
74
- str += String.fromCharCode(0xd800 | code >>> 10);
75
- str += String.fromCharCode(0xdc00 | 0x3ff & code);
76
- } else throw new Error(`UTF-8 decode: code point 0x${code.toString(16)} exceeds UTF-16 reach`);
77
- }
78
- }
79
- return str;
80
- }
81
- const POW32 = 0x100000000;
82
- function deserialize(array, options) {
83
- let bytes;
84
- if (array instanceof ArrayBuffer) bytes = new Uint8Array(array);
85
- else if (array instanceof Uint8Array) bytes = array;
86
- else if ('object' == typeof array && void 0 !== array.length) bytes = new Uint8Array(array);
87
- else throw new Error('Invalid argument type: Expected a byte array (Array or Uint8Array) to deserialize.');
88
- if (0 === bytes.length) throw new Error('Invalid argument: The byte array to deserialize is empty.');
89
- let pos = 0;
90
- if (null == options ? void 0 : options.multiple) {
91
- const results = [];
92
- while(pos < bytes.length)results.push(read());
93
- return results;
94
- }
95
- return read();
96
- function checkBounds(needed) {
97
- if (pos + needed > bytes.length) throw new Error(`Buffer overflow: trying to read ${needed} bytes at position ${pos}, but only ${bytes.length - pos} bytes available`);
98
- }
99
- function read() {
100
- checkBounds(1);
101
- const byte = bytes[pos++];
102
- if (byte >= 0x00 && byte <= 0x7f) return byte;
103
- if (byte >= 0x80 && byte <= 0x8f) return readMap(byte - 0x80);
104
- if (byte >= 0x90 && byte <= 0x9f) return readArray(byte - 0x90);
105
- if (byte >= 0xa0 && byte <= 0xbf) return readStr(byte - 0xa0);
106
- if (byte >= 0xe0 && byte <= 0xff) return byte - 256;
107
- if (0xc0 === byte) return null;
108
- if (0xc2 === byte) return false;
109
- if (0xc3 === byte) return true;
110
- if (0xc4 === byte) return readBin(-1, 1);
111
- if (0xc5 === byte) return readBin(-1, 2);
112
- if (0xc6 === byte) return readBin(-1, 4);
113
- if (0xc7 === byte) return readExt(-1, 1);
114
- if (0xc8 === byte) return readExt(-1, 2);
115
- if (0xc9 === byte) return readExt(-1, 4);
116
- if (0xd4 === byte) return readExt(1);
117
- if (0xd5 === byte) return readExt(2);
118
- if (0xd6 === byte) return readExt(4);
119
- if (0xd7 === byte) return readExt(8);
120
- if (0xd8 === byte) return readExt(16);
121
- if (0xca === byte) return readFloat(4);
122
- if (0xcb === byte) return readFloat(8);
123
- if (0xcc === byte) return readUInt(1);
124
- if (0xcd === byte) return readUInt(2);
125
- if (0xce === byte) return readUInt(4);
126
- if (0xcf === byte) return readUInt(8);
127
- if (0xd0 === byte) return readInt(1);
128
- if (0xd1 === byte) return readInt(2);
129
- if (0xd2 === byte) return readInt(4);
130
- if (0xd3 === byte) return readInt(8);
131
- if (0xd9 === byte) return readStr(-1, 1);
132
- if (0xda === byte) return readStr(-1, 2);
133
- if (0xdb === byte) return readStr(-1, 4);
134
- if (0xdc === byte) return readArray(-1, 2);
135
- if (0xdd === byte) return readArray(-1, 4);
136
- if (0xde === byte) return readMap(-1, 2);
137
- if (0xdf === byte) return readMap(-1, 4);
138
- if (0xc1 === byte) throw new Error('Invalid byte code 0xc1 found.');
139
- throw new Error(`Invalid byte value '${byte}' at index ${pos - 1} in the MessagePack binary data (length ${bytes.length}): Expecting a range of 0 to 255. This is not a byte array.`);
140
- }
141
- function readInt(count) {
142
- checkBounds(count);
143
- let value = 0;
144
- let first = true;
145
- for(let i = 0; i < count; i++)if (first) {
146
- const byte = bytes[pos++];
147
- value += 0x7f & byte;
148
- if (0x80 & byte) value -= 0x80;
149
- first = false;
150
- } else value = 256 * value + bytes[pos++];
151
- return value;
152
- }
153
- function readUInt(count) {
154
- checkBounds(count);
155
- let value = 0;
156
- for(let i = 0; i < count; i++)value = 256 * value + bytes[pos++];
157
- return value;
158
- }
159
- function readFloat(size) {
160
- checkBounds(size);
161
- const view = new DataView(bytes.buffer, pos + bytes.byteOffset, size);
162
- pos += size;
163
- if (4 === size) return view.getFloat32(0, false);
164
- if (8 === size) return view.getFloat64(0, false);
165
- return 0;
166
- }
167
- function readBin(length, lengthSize) {
168
- const finalLength = length < 0 ? readUInt(lengthSize) : length;
169
- checkBounds(finalLength);
170
- const data = bytes.subarray(pos, pos + finalLength);
171
- pos += finalLength;
172
- return data;
173
- }
174
- function readMap(length, lengthSize) {
175
- const finalLength = length < 0 && void 0 !== lengthSize ? readUInt(lengthSize) : length;
176
- const data = {};
177
- for(let i = 0; i < finalLength; i++){
178
- const key = read();
179
- if ('string' != typeof key) throw new Error(`Invalid map key type: expected string, got ${typeof key}`);
180
- data[key] = read();
181
- }
182
- return data;
183
- }
184
- function readArray(length, lengthSize) {
185
- const finalLength = length < 0 && void 0 !== lengthSize ? readUInt(lengthSize) : length;
186
- const data = [];
187
- for(let i = 0; i < finalLength; i++)data.push(read());
188
- return data;
189
- }
190
- function readStr(length, lengthSize) {
191
- const finalLength = length < 0 && void 0 !== lengthSize ? readUInt(lengthSize) : length;
192
- checkBounds(finalLength);
193
- const str = decodeUtf8(bytes, pos, finalLength);
194
- pos += finalLength;
195
- return str;
196
- }
197
- function readExt(length, lengthSize) {
198
- const finalLength = length < 0 && void 0 !== lengthSize ? readUInt(lengthSize) : length;
199
- checkBounds(1 + finalLength);
200
- const type = readUInt(1);
201
- const data = readBin(finalLength, 0);
202
- if (255 === type) return readExtDate(data);
203
- return {
204
- type,
205
- data
206
- };
207
- }
208
- function readExtDate(data) {
209
- if (4 === data.length) {
210
- const sec = (data[0] << 24 >>> 0) + (data[1] << 16 >>> 0) + (data[2] << 8 >>> 0) + data[3];
211
- return new Date(1000 * sec);
212
- }
213
- if (8 === data.length) {
214
- const ns = (data[0] << 22 >>> 0) + (data[1] << 14 >>> 0) + (data[2] << 6 >>> 0) + (data[3] >>> 2);
215
- const sec = (0x3 & data[3]) * POW32 + (data[4] << 24 >>> 0) + (data[5] << 16 >>> 0) + (data[6] << 8 >>> 0) + data[7];
216
- return new Date(1000 * sec + ns / 1000000);
217
- }
218
- if (12 === data.length) {
219
- const ns = (data[0] << 24 >>> 0) + (data[1] << 16 >>> 0) + (data[2] << 8 >>> 0) + data[3];
220
- pos -= 8;
221
- const sec = readInt(8);
222
- return new Date(1000 * sec + ns / 1000000);
223
- }
224
- throw new Error('Invalid data length for a date value.');
225
- }
226
- }
227
- const serializer_POW32 = 0x100000000;
228
- const MAX_SAFE_INTEGER_HIGH = 0x1fffffffffffff;
229
- function serialize(data, options) {
230
- if ((null == options ? void 0 : options.multiple) && !Array.isArray(data)) throw new Error('Invalid argument type: Expected an Array to serialize multiple values.');
231
- let floatBuffer;
232
- let floatView;
233
- let buffer = new Uint8Array(256);
234
- let length = 0;
235
- if ((null == options ? void 0 : options.multiple) && Array.isArray(data)) for (const item of data)append(item);
236
- else append(data);
237
- return buffer.subarray(0, length);
238
- function append(value, isReplacement = false) {
239
- const type = typeof value;
240
- switch(type){
241
- case 'undefined':
242
- appendNull();
243
- break;
244
- case 'boolean':
245
- appendBoolean(value);
246
- break;
247
- case 'number':
248
- appendNumber(value);
249
- break;
250
- case 'string':
251
- appendString(value);
252
- break;
253
- case 'object':
254
- if (null === value) appendNull();
255
- else if (value instanceof Date) appendDate(value);
256
- else if (Array.isArray(value)) appendArray(value);
257
- else if (value instanceof Uint8Array || value instanceof Uint8ClampedArray) appendBinArray(value);
258
- else if (value instanceof Int8Array || value instanceof Int16Array || value instanceof Uint16Array || value instanceof Int32Array || value instanceof Uint32Array || value instanceof Float32Array || value instanceof Float64Array) appendArray(Array.from(value));
259
- else appendObject(value);
260
- break;
261
- default:
262
- if (!isReplacement && (null == options ? void 0 : options.invalidTypeReplacement)) {
263
- const replacement = 'function' == typeof options.invalidTypeReplacement ? options.invalidTypeReplacement(value) : options.invalidTypeReplacement;
264
- append(replacement, true);
265
- } else throw new Error(`Invalid argument type: The type '${type}' cannot be serialized.`);
266
- }
267
- }
268
- function appendNull() {
269
- appendByte(0xc0);
270
- }
271
- function appendBoolean(value) {
272
- appendByte(value ? 0xc3 : 0xc2);
273
- }
274
- function appendNumber(value) {
275
- if (Number.isFinite(value) && Math.floor(value) === value) {
276
- if (value >= 0 && value <= 0x7f) appendByte(value);
277
- else if (value < 0 && value >= -32) appendByte(value);
278
- else if (value > 0 && value <= 0xff) appendBytes([
279
- 0xcc,
280
- value
281
- ]);
282
- else if (value >= -128 && value <= 0x7f) appendBytes([
283
- 0xd0,
284
- value
285
- ]);
286
- else if (value > 0 && value <= 0xffff) appendBytes([
287
- 0xcd,
288
- value >>> 8,
289
- value
290
- ]);
291
- else if (value >= -32768 && value <= 0x7fff) appendBytes([
292
- 0xd1,
293
- value >>> 8,
294
- value
295
- ]);
296
- else if (value > 0 && value <= 0xffffffff) appendBytes([
297
- 0xce,
298
- value >>> 24,
299
- value >>> 16,
300
- value >>> 8,
301
- value
302
- ]);
303
- else if (value >= -2147483648 && value <= 0x7fffffff) appendBytes([
304
- 0xd2,
305
- value >>> 24,
306
- value >>> 16,
307
- value >>> 8,
308
- value
309
- ]);
310
- else if (value > 0 && value <= MAX_SAFE_INTEGER_HIGH) {
311
- const hi = Math.floor(value / serializer_POW32);
312
- const lo = Math.floor(value % serializer_POW32);
313
- appendBytes([
314
- 0xd3,
315
- hi >>> 24,
316
- hi >>> 16,
317
- hi >>> 8,
318
- hi,
319
- lo >>> 24,
320
- lo >>> 16,
321
- lo >>> 8,
322
- lo
323
- ]);
324
- } else if (value >= -MAX_SAFE_INTEGER_HIGH && value <= -2147483649) {
325
- appendByte(0xd3);
326
- appendInt64(value);
327
- } else value < 0 ? appendBytes([
328
- 0xd3,
329
- 0x80,
330
- 0,
331
- 0,
332
- 0,
333
- 0,
334
- 0,
335
- 0,
336
- 0
337
- ]) : appendBytes([
338
- 0xcf,
339
- 0xff,
340
- 0xff,
341
- 0xff,
342
- 0xff,
343
- 0xff,
344
- 0xff,
345
- 0xff,
346
- 0xff
347
- ]);
348
- } else {
349
- if (!floatView) {
350
- floatBuffer = new ArrayBuffer(8);
351
- floatView = new DataView(floatBuffer);
352
- }
353
- floatView.setFloat64(0, value);
354
- appendByte(0xcb);
355
- appendBytes(new Uint8Array(floatBuffer));
356
- }
357
- }
358
- function appendString(value) {
359
- const bytes = encodeUtf8(value);
360
- const len = bytes.length;
361
- if (len <= 0x1f) appendByte(0xa0 + len);
362
- else if (len <= 0xff) appendBytes([
363
- 0xd9,
364
- len
365
- ]);
366
- else len <= 0xffff ? appendBytes([
367
- 0xda,
368
- len >>> 8,
369
- len
370
- ]) : appendBytes([
371
- 0xdb,
372
- len >>> 24,
373
- len >>> 16,
374
- len >>> 8,
375
- len
376
- ]);
377
- appendBytes(bytes);
378
- }
379
- function appendArray(value) {
380
- const len = value.length;
381
- if (len <= 0xf) appendByte(0x90 + len);
382
- else len <= 0xffff ? appendBytes([
383
- 0xdc,
384
- len >>> 8,
385
- len
386
- ]) : appendBytes([
387
- 0xdd,
388
- len >>> 24,
389
- len >>> 16,
390
- len >>> 8,
391
- len
392
- ]);
393
- for (const item of value)append(item);
394
- }
395
- function appendBinArray(value) {
396
- const len = value.length;
397
- if (len <= 0xff) appendBytes([
398
- 0xc4,
399
- len
400
- ]);
401
- else len <= 0xffff ? appendBytes([
402
- 0xc5,
403
- len >>> 8,
404
- len
405
- ]) : appendBytes([
406
- 0xc6,
407
- len >>> 24,
408
- len >>> 16,
409
- len >>> 8,
410
- len
411
- ]);
412
- appendBytes(value);
413
- }
414
- function appendObject(value) {
415
- let count = 0;
416
- for(const key in value)if (void 0 !== value[key]) count++;
417
- if (count <= 0xf) appendByte(0x80 + count);
418
- else count <= 0xffff ? appendBytes([
419
- 0xde,
420
- count >>> 8,
421
- count
422
- ]) : appendBytes([
423
- 0xdf,
424
- count >>> 24,
425
- count >>> 16,
426
- count >>> 8,
427
- count
428
- ]);
429
- for(const key in value){
430
- const val = value[key];
431
- if (void 0 !== val) {
432
- append(key);
433
- append(val);
434
- }
435
- }
436
- }
437
- function appendDate(value) {
438
- const sec = value.getTime() / 1000;
439
- if (0 === value.getMilliseconds() && sec >= 0 && sec < serializer_POW32) {
440
- const secInt = Math.floor(sec);
441
- appendBytes([
442
- 0xd6,
443
- 0xff,
444
- secInt >>> 24,
445
- secInt >>> 16,
446
- secInt >>> 8,
447
- secInt
448
- ]);
449
- } else if (sec >= 0 && sec < 4 * serializer_POW32) {
450
- const ns = 1000000 * value.getMilliseconds();
451
- const secInt = Math.floor(sec);
452
- const secHigh = Math.floor(secInt / serializer_POW32);
453
- appendBytes([
454
- 0xd7,
455
- 0xff,
456
- ns >>> 22,
457
- ns >>> 14,
458
- ns >>> 6,
459
- ns << 2 >>> 0 | secHigh,
460
- secInt >>> 24,
461
- secInt >>> 16,
462
- secInt >>> 8,
463
- secInt
464
- ]);
465
- } else {
466
- const ns = 1000000 * value.getMilliseconds();
467
- appendBytes([
468
- 0xc7,
469
- 12,
470
- 0xff,
471
- ns >>> 24,
472
- ns >>> 16,
473
- ns >>> 8,
474
- ns
475
- ]);
476
- appendInt64(sec);
477
- }
478
- }
479
- function appendByte(byte) {
480
- if (buffer.length < length + 1) expandBuffer(length + 1);
481
- buffer[length++] = byte;
482
- }
483
- function appendBytes(bytes) {
484
- const needed = length + bytes.length;
485
- if (buffer.length < needed) expandBuffer(needed);
486
- buffer.set(bytes, length);
487
- length += bytes.length;
488
- }
489
- function expandBuffer(minSize) {
490
- let newSize = Math.ceil(1.5 * buffer.length);
491
- while(newSize < minSize)newSize = Math.ceil(1.5 * newSize);
492
- const newBuffer = new Uint8Array(newSize);
493
- newBuffer.set(buffer);
494
- buffer = newBuffer;
495
- }
496
- function appendInt64(num) {
497
- let hi;
498
- let lo;
499
- if (num >= 0) {
500
- hi = Math.floor(num / serializer_POW32);
501
- lo = Math.floor(num % serializer_POW32);
502
- } else {
503
- const absValue = Math.abs(num + 1);
504
- hi = ~Math.floor(absValue / serializer_POW32);
505
- lo = ~Math.floor(absValue % serializer_POW32);
506
- }
507
- appendBytes([
508
- hi >>> 24,
509
- hi >>> 16,
510
- hi >>> 8,
511
- hi,
512
- lo >>> 24,
513
- lo >>> 16,
514
- lo >>> 8,
515
- lo
516
- ]);
517
- }
518
- }
519
- const pack_serialize = serialize;
520
- const pack_deserialize = deserialize;
521
- const encode = serialize;
522
- const decode = deserialize;
523
- const generateHexSegment = ()=>((1 + Math.random()) * 0x10000 | 0).toString(16).substring(1);
524
- const generateUUID = ()=>[
525
- generateHexSegment() + generateHexSegment(),
526
- generateHexSegment(),
527
- generateHexSegment(),
528
- generateHexSegment(),
529
- generateHexSegment() + generateHexSegment() + generateHexSegment()
530
- ].join('-');
531
- var jsonrpc_JsonRpcErrorCode = /*#__PURE__*/ function(JsonRpcErrorCode) {
532
- JsonRpcErrorCode[JsonRpcErrorCode["ParseError"] = -32700] = "ParseError";
533
- JsonRpcErrorCode[JsonRpcErrorCode["InvalidRequest"] = -32600] = "InvalidRequest";
534
- JsonRpcErrorCode[JsonRpcErrorCode["MethodNotFound"] = -32601] = "MethodNotFound";
535
- JsonRpcErrorCode[JsonRpcErrorCode["InvalidParams"] = -32602] = "InvalidParams";
536
- JsonRpcErrorCode[JsonRpcErrorCode["InternalError"] = -32603] = "InternalError";
537
- JsonRpcErrorCode[JsonRpcErrorCode["ServerError"] = -32000] = "ServerError";
538
- JsonRpcErrorCode[JsonRpcErrorCode["Timeout"] = -32001] = "Timeout";
539
- JsonRpcErrorCode[JsonRpcErrorCode["ConnectionClosed"] = -32002] = "ConnectionClosed";
540
- return JsonRpcErrorCode;
541
- }({});
542
- var socket_ConnectionState = /*#__PURE__*/ function(ConnectionState) {
543
- ConnectionState[ConnectionState["Connecting"] = 0] = "Connecting";
544
- ConnectionState[ConnectionState["Open"] = 1] = "Open";
545
- ConnectionState[ConnectionState["Closing"] = 2] = "Closing";
546
- ConnectionState[ConnectionState["Closed"] = 3] = "Closed";
547
- return ConnectionState;
548
- }({});
549
- const SocketEvent = {
550
- Open: 'open',
551
- Close: 'close',
552
- Error: 'error',
553
- Message: 'message',
554
- Reconnecting: 'reconnecting',
555
- Reconnected: 'reconnected',
556
- ReconnectFailed: 'reconnect_failed'
557
- };
558
- function _define_property(obj, key, value) {
559
- if (key in obj) Object.defineProperty(obj, key, {
560
- value: value,
561
- enumerable: true,
562
- configurable: true,
563
- writable: true
564
- });
565
- else obj[key] = value;
566
- return obj;
567
- }
568
- class EventEmitter {
569
- on(event, listener) {
570
- var _this_listeners_get;
571
- if (!this.listeners.has(event)) this.listeners.set(event, new Set());
572
- null === (_this_listeners_get = this.listeners.get(event)) || void 0 === _this_listeners_get || _this_listeners_get.add(listener);
573
- return ()=>this.off(event, listener);
574
- }
575
- once(event, listener) {
576
- const wrapper = (data)=>{
577
- this.off(event, wrapper);
578
- listener(data);
579
- };
580
- return this.on(event, wrapper);
581
- }
582
- off(event, listener) {
583
- const eventListeners = this.listeners.get(event);
584
- if (eventListeners) {
585
- eventListeners.delete(listener);
586
- if (0 === eventListeners.size) this.listeners.delete(event);
587
- }
588
- }
589
- emit(event, data) {
590
- const eventListeners = this.listeners.get(event);
591
- if (eventListeners) for (const listener of eventListeners)try {
592
- listener(data);
593
- } catch (error) {
594
- console.error(`Error in event listener for "${String(event)}":`, error);
595
- }
596
- }
597
- removeAllListeners(event) {
598
- if (event) this.listeners.delete(event);
599
- else this.listeners.clear();
600
- }
601
- listenerCount(event) {
602
- var _this_listeners_get;
603
- return (null === (_this_listeners_get = this.listeners.get(event)) || void 0 === _this_listeners_get ? void 0 : _this_listeners_get.size) ?? 0;
604
- }
605
- constructor(){
606
- _define_property(this, "listeners", new Map());
607
- }
608
- }
609
- function client_define_property(obj, key, value) {
610
- if (key in obj) Object.defineProperty(obj, key, {
611
- value: value,
612
- enumerable: true,
613
- configurable: true,
614
- writable: true
615
- });
616
- else obj[key] = value;
617
- return obj;
618
- }
619
- const DEFAULT_OPTIONS = {
620
- autoReconnect: true,
621
- reconnectInterval: 3000,
622
- maxReconnectAttempts: 5,
623
- defaultTimeout: 15000,
624
- heartbeatInterval: 0,
625
- heartbeatMethod: 'ping',
626
- debug: false
627
- };
628
- class JsonRpcWebSocketClient extends EventEmitter {
629
- get state() {
630
- var _this_ws;
631
- return (null === (_this_ws = this.ws) || void 0 === _this_ws ? void 0 : _this_ws.readyState) ?? socket_ConnectionState.Closed;
632
- }
633
- get isConnected() {
634
- return this.state === socket_ConnectionState.Open;
635
- }
636
- getStats() {
637
- return {
638
- ...this.stats,
639
- pendingRequests: this.pendingRequests.size
640
- };
641
- }
642
- connect() {
643
- if (this.ws && this.ws.readyState === socket_ConnectionState.Connecting) return;
644
- try {
645
- this.ws = new WebSocket(this.options.url, this.options.protocols);
646
- this.ws.binaryType = 'arraybuffer';
647
- this.ws.onopen = this.handleOpen.bind(this);
648
- this.ws.onmessage = this.handleMessage.bind(this);
649
- this.ws.onclose = this.handleClose.bind(this);
650
- this.ws.onerror = this.handleError.bind(this);
651
- } catch (error) {
652
- this.log('Connection error:', error);
653
- this.scheduleReconnect();
654
- }
655
- }
656
- handleOpen(event) {
657
- this.log('Connection opened');
658
- this.reconnectAttempts = 0;
659
- this.startHeartbeat();
660
- this.emit(SocketEvent.Open, event);
661
- }
662
- handleMessage(event) {
663
- try {
664
- const rawData = event.data;
665
- const response = decode(new Uint8Array(rawData));
666
- this.log('Received:', response);
667
- this.stats.responsesReceived++;
668
- if ('error' in response) this.stats.errors++;
669
- if (null !== response.id) {
670
- const streamCallback = this.streamCallbacks.get(response.id);
671
- if (streamCallback) {
672
- streamCallback(response);
673
- this.emit(SocketEvent.Message, {
674
- data: response,
675
- rawData
676
- });
677
- return;
678
- }
679
- const metadata = this.pendingRequests.get(response.id);
680
- if (metadata) {
681
- clearTimeout(metadata.timeoutId);
682
- this.pendingRequests.delete(response.id);
683
- const responseTime = Date.now() - metadata.timestamp;
684
- this.updateResponseTime(responseTime);
685
- if ('error' in response) metadata.reject(new Error(`${response.error.message} (${response.error.code})`));
686
- else metadata.resolve(response.result);
687
- }
688
- }
689
- this.emit(SocketEvent.Message, {
690
- data: response,
691
- rawData
692
- });
693
- } catch (error) {
694
- this.log('Failed to decode message:', error);
695
- }
696
- }
697
- handleClose(event) {
698
- this.log('Connection closed:', event.code, event.reason);
699
- this.stopHeartbeat();
700
- this.emit(SocketEvent.Close, event);
701
- this.rejectAllPendingRequests(new Error('Connection closed'), jsonrpc_JsonRpcErrorCode.ConnectionClosed);
702
- if (this.options.autoReconnect) this.scheduleReconnect();
703
- }
704
- handleError(event) {
705
- this.log('Connection error:', event);
706
- this.emit(SocketEvent.Error, event);
707
- }
708
- scheduleReconnect() {
709
- if (this.reconnectTimeoutId) return;
710
- if (this.reconnectAttempts >= this.options.maxReconnectAttempts) {
711
- this.log('Max reconnect attempts reached');
712
- this.emit(SocketEvent.ReconnectFailed, void 0);
713
- return;
714
- }
715
- this.reconnectAttempts++;
716
- this.stats.reconnectCount++;
717
- this.log(`Reconnecting in ${this.options.reconnectInterval}ms (attempt ${this.reconnectAttempts}/${this.options.maxReconnectAttempts})`);
718
- this.emit(SocketEvent.Reconnecting, {
719
- attempt: this.reconnectAttempts,
720
- maxAttempts: this.options.maxReconnectAttempts
721
- });
722
- this.reconnectTimeoutId = setTimeout(()=>{
723
- this.reconnectTimeoutId = null;
724
- this.connect();
725
- }, this.options.reconnectInterval);
726
- }
727
- startHeartbeat() {
728
- if (this.options.heartbeatInterval <= 0 || null !== this.heartbeatIntervalId) return;
729
- this.heartbeatIntervalId = setInterval(()=>{
730
- if (this.isConnected) this.notify({
731
- method: this.options.heartbeatMethod
732
- }).catch((error)=>{
733
- this.log('Heartbeat failed:', error);
734
- });
735
- }, this.options.heartbeatInterval);
736
- }
737
- stopHeartbeat() {
738
- if (this.heartbeatIntervalId) {
739
- clearInterval(this.heartbeatIntervalId);
740
- this.heartbeatIntervalId = null;
741
- }
742
- }
743
- rejectAllPendingRequests(error, code) {
744
- for (const [id, metadata] of this.pendingRequests){
745
- clearTimeout(metadata.timeoutId);
746
- metadata.reject(error);
747
- }
748
- this.pendingRequests.clear();
749
- }
750
- updateResponseTime(time) {
751
- this.responseTimes.push(time);
752
- if (this.responseTimes.length > 100) this.responseTimes.shift();
753
- this.stats.averageResponseTime = this.responseTimes.reduce((sum, t)=>sum + t, 0) / this.responseTimes.length;
754
- }
755
- async request(options) {
756
- if (!this.isConnected) throw new Error('WebSocket is not connected');
757
- const id = options.id ?? generateUUID();
758
- const request = {
759
- jsonrpc: '2.0',
760
- method: options.method,
761
- params: options.params,
762
- id
763
- };
764
- return new Promise((resolve, reject)=>{
765
- const timeout = options.timeout ?? this.options.defaultTimeout;
766
- const timeoutId = setTimeout(()=>{
767
- this.pendingRequests.delete(id);
768
- this.stats.timeouts++;
769
- reject(new Error(`Request timeout after ${timeout}ms`));
770
- }, timeout);
771
- this.pendingRequests.set(id, {
772
- id,
773
- timestamp: Date.now(),
774
- timeoutId,
775
- resolve: resolve,
776
- reject
777
- });
778
- try {
779
- var _this_ws;
780
- const encoded = encode(request);
781
- null === (_this_ws = this.ws) || void 0 === _this_ws || _this_ws.send(encoded);
782
- this.stats.requestsSent++;
783
- this.log('Sent request:', request);
784
- } catch (error) {
785
- clearTimeout(timeoutId);
786
- this.pendingRequests.delete(id);
787
- reject(error);
788
- }
789
- });
790
- }
791
- async notify(options) {
792
- var _this_ws;
793
- if (!this.isConnected) throw new Error('WebSocket is not connected');
794
- const notification = {
795
- jsonrpc: '2.0',
796
- method: options.method,
797
- params: options.params
798
- };
799
- const encoded = encode(notification);
800
- null === (_this_ws = this.ws) || void 0 === _this_ws || _this_ws.send(encoded);
801
- this.log('Sent notification:', notification);
802
- }
803
- stream(options, callback) {
804
- if (!this.isConnected) throw new Error('WebSocket is not connected');
805
- const id = options.id ?? generateUUID();
806
- const request = {
807
- jsonrpc: '2.0',
808
- method: options.method,
809
- params: options.params,
810
- id
811
- };
812
- let closed = false;
813
- this.streamCallbacks.set(id, callback);
814
- try {
815
- var _this_ws;
816
- const encoded = encode(request);
817
- null === (_this_ws = this.ws) || void 0 === _this_ws || _this_ws.send(encoded);
818
- this.stats.requestsSent++;
819
- this.log('Sent stream request:', request);
820
- } catch (error) {
821
- this.streamCallbacks.delete(id);
822
- throw error;
823
- }
824
- return {
825
- id,
826
- close: ()=>{
827
- if (!closed) {
828
- closed = true;
829
- this.streamCallbacks.delete(id);
830
- this.log('Stream closed:', id);
831
- }
832
- },
833
- get closed () {
834
- return closed;
835
- }
836
- };
837
- }
838
- sendRaw(data) {
839
- var _this_ws;
840
- if (!this.isConnected) throw new Error('WebSocket is not connected');
841
- null === (_this_ws = this.ws) || void 0 === _this_ws || _this_ws.send(data);
842
- this.log('Sent raw data:', data.byteLength, 'bytes');
843
- }
844
- close(code, reason) {
845
- this.options.autoReconnect = false;
846
- if (this.reconnectTimeoutId) {
847
- clearTimeout(this.reconnectTimeoutId);
848
- this.reconnectTimeoutId = null;
849
- }
850
- this.stopHeartbeat();
851
- if (this.ws) {
852
- this.ws.close(code, reason);
853
- this.ws = null;
854
- }
855
- this.rejectAllPendingRequests(new Error('Connection closed by client'), jsonrpc_JsonRpcErrorCode.ConnectionClosed);
856
- this.removeAllListeners();
857
- }
858
- reconnectToUrl(url) {
859
- this.close();
860
- this.options.url = url;
861
- this.options.autoReconnect = true;
862
- this.reconnectAttempts = 0;
863
- this.connect();
864
- }
865
- log(...args) {
866
- if (this.options.debug) console.log('[JsonRpcWebSocket]', ...args);
867
- }
868
- constructor(options){
869
- super(), client_define_property(this, "ws", null), client_define_property(this, "options", void 0), client_define_property(this, "pendingRequests", new Map()), client_define_property(this, "streamCallbacks", new Map()), client_define_property(this, "reconnectAttempts", 0), client_define_property(this, "reconnectTimeoutId", null), client_define_property(this, "heartbeatIntervalId", null), client_define_property(this, "stats", {
870
- requestsSent: 0,
871
- responsesReceived: 0,
872
- timeouts: 0,
873
- errors: 0,
874
- averageResponseTime: 0,
875
- pendingRequests: 0,
876
- reconnectCount: 0
877
- }), client_define_property(this, "responseTimes", []);
878
- this.options = {
879
- ...DEFAULT_OPTIONS,
880
- ...options
881
- };
882
- this.connect();
883
- }
884
- }
885
- export { JsonRpcWebSocketClient, SocketEvent, decode, JsonRpcWebSocketClient as default, pack_deserialize as deserialize, encode, generateUUID, pack_serialize as serialize };
1
+ function encodeUtf8(str){const length=str.length;let ascii=true;for(let i=0;i<length;i++)if(str.charCodeAt(i)>127){ascii=false;break}if(ascii){const bytes=new Uint8Array(length);for(let i=0;i<length;i++)bytes[i]=str.charCodeAt(i);return bytes}let bytes=new Uint8Array(2*length);let pos=0;for(let i=0;i<length;i++){let code=str.charCodeAt(i);if(pos+4>bytes.length){const newBytes=new Uint8Array(Math.ceil(1.5*bytes.length));newBytes.set(bytes);bytes=newBytes}if(code<128)bytes[pos++]=code;else if(code<2048){bytes[pos++]=192|code>>>6;bytes[pos++]=128|63&code}else if(code>=55296&&code<56320){if(i+1>=length)throw new Error("UTF-8 encode: incomplete surrogate pair");const code2=str.charCodeAt(++i);if(code2<56320||code2>57343)throw new Error(`UTF-8 encode: second surrogate character 0x${code2.toString(16)} at index ${i} out of range`);code=65536+((1023&code)<<10)+(1023&code2);bytes[pos++]=240|code>>>18;bytes[pos++]=128|code>>>12&63;bytes[pos++]=128|code>>>6&63;bytes[pos++]=128|63&code}else{bytes[pos++]=224|code>>>12;bytes[pos++]=128|code>>>6&63;bytes[pos++]=128|63&code}}return bytes.subarray(0,pos)}function decodeUtf8(bytes,start,length){const end=start+length;let ascii=true;for(let i=start;i<end;i++)if(bytes[i]>127){ascii=false;break}if(ascii)return String.fromCharCode(...bytes.subarray(start,end));let str="";let i=start;while(i<end){const byte1=bytes[i++];if(byte1<128)str+=String.fromCharCode(byte1);else if(byte1<224){if(i>=end)throw new Error("UTF-8 decode: incomplete 2-byte sequence");const byte2=bytes[i++];str+=String.fromCharCode((31&byte1)<<6|63&byte2)}else if(byte1<240){if(i+1>=end)throw new Error("UTF-8 decode: incomplete 3-byte sequence");const byte2=bytes[i++];const byte3=bytes[i++];str+=String.fromCharCode((15&byte1)<<12|(63&byte2)<<6|63&byte3)}else{if(i+2>=end)throw new Error("UTF-8 decode: incomplete 4-byte sequence");const byte2=bytes[i++];const byte3=bytes[i++];const byte4=bytes[i++];let code=(7&byte1)<<18|(63&byte2)<<12|(63&byte3)<<6|63&byte4;if(code<=65535)str+=String.fromCharCode(code);else if(code<=1114111){code-=65536;str+=String.fromCharCode(55296|code>>>10);str+=String.fromCharCode(56320|1023&code)}else throw new Error(`UTF-8 decode: code point 0x${code.toString(16)} exceeds UTF-16 reach`)}}return str}const POW32=0x100000000;function deserialize(array,options){let bytes;if(array instanceof ArrayBuffer)bytes=new Uint8Array(array);else if(array instanceof Uint8Array)bytes=array;else if("object"==typeof array&&void 0!==array.length)bytes=new Uint8Array(array);else throw new Error("Invalid argument type: Expected a byte array (Array or Uint8Array) to deserialize.");if(0===bytes.length)throw new Error("Invalid argument: The byte array to deserialize is empty.");let pos=0;if(options?.multiple){const results=[];while(pos<bytes.length)results.push(read());return results}return read();function checkBounds(needed){if(pos+needed>bytes.length)throw new Error(`Buffer overflow: trying to read ${needed} bytes at position ${pos}, but only ${bytes.length-pos} bytes available`)}function read(){checkBounds(1);const byte=bytes[pos++];if(byte>=0&&byte<=127)return byte;if(byte>=128&&byte<=143)return readMap(byte-128);if(byte>=144&&byte<=159)return readArray(byte-144);if(byte>=160&&byte<=191)return readStr(byte-160);if(byte>=224&&byte<=255)return byte-256;if(192===byte)return null;if(194===byte)return false;if(195===byte)return true;if(196===byte)return readBin(-1,1);if(197===byte)return readBin(-1,2);if(198===byte)return readBin(-1,4);if(199===byte)return readExt(-1,1);if(200===byte)return readExt(-1,2);if(201===byte)return readExt(-1,4);if(212===byte)return readExt(1);if(213===byte)return readExt(2);if(214===byte)return readExt(4);if(215===byte)return readExt(8);if(216===byte)return readExt(16);if(202===byte)return readFloat(4);if(203===byte)return readFloat(8);if(204===byte)return readUInt(1);if(205===byte)return readUInt(2);if(206===byte)return readUInt(4);if(207===byte)return readUInt(8);if(208===byte)return readInt(1);if(209===byte)return readInt(2);if(210===byte)return readInt(4);if(211===byte)return readInt(8);if(217===byte)return readStr(-1,1);if(218===byte)return readStr(-1,2);if(219===byte)return readStr(-1,4);if(220===byte)return readArray(-1,2);if(221===byte)return readArray(-1,4);if(222===byte)return readMap(-1,2);if(223===byte)return readMap(-1,4);if(193===byte)throw new Error("Invalid byte code 0xc1 found.");throw new Error(`Invalid byte value '${byte}' at index ${pos-1} in the MessagePack binary data (length ${bytes.length}): Expecting a range of 0 to 255. This is not a byte array.`)}function readInt(count){checkBounds(count);let value=0;let first=true;for(let i=0;i<count;i++)if(first){const byte=bytes[pos++];value+=127&byte;if(128&byte)value-=128;first=false}else value=256*value+bytes[pos++];return value}function readUInt(count){checkBounds(count);let value=0;for(let i=0;i<count;i++)value=256*value+bytes[pos++];return value}function readFloat(size){checkBounds(size);const view=new DataView(bytes.buffer,pos+bytes.byteOffset,size);pos+=size;if(4===size)return view.getFloat32(0,false);if(8===size)return view.getFloat64(0,false);return 0}function readBin(length,lengthSize){const finalLength=length<0?readUInt(lengthSize):length;checkBounds(finalLength);const data=bytes.subarray(pos,pos+finalLength);pos+=finalLength;return data}function readMap(length,lengthSize){const finalLength=length<0&&void 0!==lengthSize?readUInt(lengthSize):length;const data={};for(let i=0;i<finalLength;i++){const key=read();if("string"!=typeof key)throw new Error(`Invalid map key type: expected string, got ${typeof key}`);data[key]=read()}return data}function readArray(length,lengthSize){const finalLength=length<0&&void 0!==lengthSize?readUInt(lengthSize):length;const data=[];for(let i=0;i<finalLength;i++)data.push(read());return data}function readStr(length,lengthSize){const finalLength=length<0&&void 0!==lengthSize?readUInt(lengthSize):length;checkBounds(finalLength);const str=decodeUtf8(bytes,pos,finalLength);pos+=finalLength;return str}function readExt(length,lengthSize){const finalLength=length<0&&void 0!==lengthSize?readUInt(lengthSize):length;checkBounds(1+finalLength);const type=readUInt(1);const data=readBin(finalLength,0);if(255===type)return readExtDate(data);return{type,data}}function readExtDate(data){if(4===data.length){const sec=(data[0]<<24>>>0)+(data[1]<<16>>>0)+(data[2]<<8>>>0)+data[3];return new Date(1e3*sec)}if(8===data.length){const ns=(data[0]<<22>>>0)+(data[1]<<14>>>0)+(data[2]<<6>>>0)+(data[3]>>>2);const sec=(3&data[3])*POW32+(data[4]<<24>>>0)+(data[5]<<16>>>0)+(data[6]<<8>>>0)+data[7];return new Date(1e3*sec+ns/1e6)}if(12===data.length){const ns=(data[0]<<24>>>0)+(data[1]<<16>>>0)+(data[2]<<8>>>0)+data[3];pos-=8;const sec=readInt(8);return new Date(1e3*sec+ns/1e6)}throw new Error("Invalid data length for a date value.")}}const serializer_POW32=0x100000000;const MAX_SAFE_INTEGER_HIGH=0x1fffffffffffff;function serialize(data,options){if(options?.multiple&&!Array.isArray(data))throw new Error("Invalid argument type: Expected an Array to serialize multiple values.");let floatBuffer;let floatView;let buffer=new Uint8Array(256);let length=0;if(options?.multiple&&Array.isArray(data))for(const item of data)append(item);else append(data);return buffer.subarray(0,length);function append(value,isReplacement=false){const type=typeof value;switch(type){case"undefined":appendNull();break;case"boolean":appendBoolean(value);break;case"number":appendNumber(value);break;case"string":appendString(value);break;case"object":if(null===value)appendNull();else if(value instanceof Date)appendDate(value);else if(Array.isArray(value))appendArray(value);else if(value instanceof Uint8Array||value instanceof Uint8ClampedArray)appendBinArray(value);else if(value instanceof Int8Array||value instanceof Int16Array||value instanceof Uint16Array||value instanceof Int32Array||value instanceof Uint32Array||value instanceof Float32Array||value instanceof Float64Array)appendArray(Array.from(value));else appendObject(value);break;default:if(!isReplacement&&options?.invalidTypeReplacement){const replacement="function"==typeof options.invalidTypeReplacement?options.invalidTypeReplacement(value):options.invalidTypeReplacement;append(replacement,true)}else throw new Error(`Invalid argument type: The type '${type}' cannot be serialized.`)}}function appendNull(){appendByte(192)}function appendBoolean(value){appendByte(value?195:194)}function appendNumber(value){if(Number.isFinite(value)&&Math.floor(value)===value){if(value>=0&&value<=127)appendByte(value);else if(value<0&&value>=-32)appendByte(value);else if(value>0&&value<=255)appendBytes([204,value]);else if(value>=-128&&value<=127)appendBytes([208,value]);else if(value>0&&value<=65535)appendBytes([205,value>>>8,value]);else if(value>=-32768&&value<=32767)appendBytes([209,value>>>8,value]);else if(value>0&&value<=0xffffffff)appendBytes([206,value>>>24,value>>>16,value>>>8,value]);else if(value>=-0x80000000&&value<=0x7fffffff)appendBytes([210,value>>>24,value>>>16,value>>>8,value]);else if(value>0&&value<=MAX_SAFE_INTEGER_HIGH){const hi=Math.floor(value/serializer_POW32);const lo=Math.floor(value%serializer_POW32);appendBytes([211,hi>>>24,hi>>>16,hi>>>8,hi,lo>>>24,lo>>>16,lo>>>8,lo])}else if(value>=-MAX_SAFE_INTEGER_HIGH&&value<=-0x80000001){appendByte(211);appendInt64(value)}else value<0?appendBytes([211,128,0,0,0,0,0,0,0]):appendBytes([207,255,255,255,255,255,255,255,255])}else{if(!floatView){floatBuffer=new ArrayBuffer(8);floatView=new DataView(floatBuffer)}floatView.setFloat64(0,value);appendByte(203);appendBytes(new Uint8Array(floatBuffer))}}function appendString(value){const bytes=encodeUtf8(value);const len=bytes.length;if(len<=31)appendByte(160+len);else if(len<=255)appendBytes([217,len]);else len<=65535?appendBytes([218,len>>>8,len]):appendBytes([219,len>>>24,len>>>16,len>>>8,len]);appendBytes(bytes)}function appendArray(value){const len=value.length;if(len<=15)appendByte(144+len);else len<=65535?appendBytes([220,len>>>8,len]):appendBytes([221,len>>>24,len>>>16,len>>>8,len]);for(const item of value)append(item)}function appendBinArray(value){const len=value.length;if(len<=255)appendBytes([196,len]);else len<=65535?appendBytes([197,len>>>8,len]):appendBytes([198,len>>>24,len>>>16,len>>>8,len]);appendBytes(value)}function appendObject(value){let count=0;for(const key in value)if(void 0!==value[key])count++;if(count<=15)appendByte(128+count);else count<=65535?appendBytes([222,count>>>8,count]):appendBytes([223,count>>>24,count>>>16,count>>>8,count]);for(const key in value){const val=value[key];if(void 0!==val){append(key);append(val)}}}function appendDate(value){const sec=value.getTime()/1e3;if(0===value.getMilliseconds()&&sec>=0&&sec<serializer_POW32){const secInt=Math.floor(sec);appendBytes([214,255,secInt>>>24,secInt>>>16,secInt>>>8,secInt])}else if(sec>=0&&sec<4*serializer_POW32){const ns=1e6*value.getMilliseconds();const secInt=Math.floor(sec);const secHigh=Math.floor(secInt/serializer_POW32);appendBytes([215,255,ns>>>22,ns>>>14,ns>>>6,ns<<2>>>0|secHigh,secInt>>>24,secInt>>>16,secInt>>>8,secInt])}else{const ns=1e6*value.getMilliseconds();appendBytes([199,12,255,ns>>>24,ns>>>16,ns>>>8,ns]);appendInt64(sec)}}function appendByte(byte){if(buffer.length<length+1)expandBuffer(length+1);buffer[length++]=byte}function appendBytes(bytes){const needed=length+bytes.length;if(buffer.length<needed)expandBuffer(needed);buffer.set(bytes,length);length+=bytes.length}function expandBuffer(minSize){let newSize=Math.ceil(1.5*buffer.length);while(newSize<minSize)newSize=Math.ceil(1.5*newSize);const newBuffer=new Uint8Array(newSize);newBuffer.set(buffer);buffer=newBuffer}function appendInt64(num){let hi;let lo;if(num>=0){hi=Math.floor(num/serializer_POW32);lo=Math.floor(num%serializer_POW32)}else{const absValue=Math.abs(num+1);hi=~Math.floor(absValue/serializer_POW32);lo=~Math.floor(absValue%serializer_POW32)}appendBytes([hi>>>24,hi>>>16,hi>>>8,hi,lo>>>24,lo>>>16,lo>>>8,lo])}}const pack_serialize=serialize;const pack_deserialize=deserialize;const encode=serialize;const decode=deserialize;const generateHexSegment=()=>((1+Math.random())*65536|0).toString(16).substring(1);const generateUUID=()=>[generateHexSegment()+generateHexSegment(),generateHexSegment(),generateHexSegment(),generateHexSegment(),generateHexSegment()+generateHexSegment()+generateHexSegment()].join("-");const generateId=(length=8)=>{let result="";const characters="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";const charactersLength=characters.length;for(let i=0;i<length;i++)result+=characters.charAt(Math.floor(Math.random()*charactersLength));return result};var jsonrpc_JsonRpcErrorCode=/*#__PURE__*/function(JsonRpcErrorCode){JsonRpcErrorCode[JsonRpcErrorCode["ParseError"]=-32700]="ParseError";JsonRpcErrorCode[JsonRpcErrorCode["InvalidRequest"]=-32600]="InvalidRequest";JsonRpcErrorCode[JsonRpcErrorCode["MethodNotFound"]=-32601]="MethodNotFound";JsonRpcErrorCode[JsonRpcErrorCode["InvalidParams"]=-32602]="InvalidParams";JsonRpcErrorCode[JsonRpcErrorCode["InternalError"]=-32603]="InternalError";JsonRpcErrorCode[JsonRpcErrorCode["ServerError"]=-32e3]="ServerError";JsonRpcErrorCode[JsonRpcErrorCode["Timeout"]=-32001]="Timeout";JsonRpcErrorCode[JsonRpcErrorCode["ConnectionClosed"]=-32002]="ConnectionClosed";return JsonRpcErrorCode}({});function createErrorResponse(id,code,message,data){return{jsonrpc:"2.0",error:{code,message,data},id}}function createSuccessResponse(id,result){return{jsonrpc:"2.0",result,id}}function isJsonRpcError(response){return"error"in response}function isJsonRpcSuccess(response){return"result"in response}function isJsonRpcNotification(message){return"method"in message&&!("id"in message)}var socket_ConnectionState=/*#__PURE__*/function(ConnectionState){ConnectionState[ConnectionState["Connecting"]=0]="Connecting";ConnectionState[ConnectionState["Open"]=1]="Open";ConnectionState[ConnectionState["Closing"]=2]="Closing";ConnectionState[ConnectionState["Closed"]=3]="Closed";return ConnectionState}({});const SocketEvent={Open:"open",Close:"close",Error:"error",Message:"message",Reconnecting:"reconnecting",Reconnected:"reconnected",ReconnectFailed:"reconnect_failed"};class EventEmitter{listeners=new Map;on(event,listener){if(!this.listeners.has(event))this.listeners.set(event,new Set);this.listeners.get(event)?.add(listener);return()=>this.off(event,listener)}once(event,listener){const wrapper=data=>{this.off(event,wrapper);listener(data)};return this.on(event,wrapper)}off(event,listener){const eventListeners=this.listeners.get(event);if(eventListeners){eventListeners.delete(listener);if(0===eventListeners.size)this.listeners.delete(event)}}emit(event,data){const eventListeners=this.listeners.get(event);if(eventListeners)for(const listener of eventListeners)try{listener(data)}catch(error){console.error(`Error in event listener for "${String(event)}":`,error)}}removeAllListeners(event){if(event)this.listeners.delete(event);else this.listeners.clear()}listenerCount(event){return this.listeners.get(event)?.size??0}}const DEFAULT_OPTIONS={autoReconnect:true,reconnectInterval:3e3,maxReconnectAttempts:5,defaultTimeout:15e3,heartbeatInterval:0,heartbeatMethod:"ping",debug:false};class JsonRpcWebSocketClient extends EventEmitter{ws=null;options;pendingRequests=new Map;streamCallbacks=new Map;reconnectAttempts=0;reconnectTimeoutId=null;heartbeatIntervalId=null;stats={requestsSent:0,responsesReceived:0,timeouts:0,errors:0,averageResponseTime:0,pendingRequests:0,reconnectCount:0};responseTimes=[];constructor(options){super();this.options={...DEFAULT_OPTIONS,...options};this.connect()}get state(){return this.ws?.readyState??socket_ConnectionState.Closed}get isConnected(){return this.state===socket_ConnectionState.Open}getStats(){return{...this.stats,pendingRequests:this.pendingRequests.size}}connect(){if(this.ws&&this.ws.readyState===socket_ConnectionState.Connecting)return;try{this.ws=new WebSocket(this.options.url,this.options.protocols);this.ws.binaryType="arraybuffer";this.ws.onopen=this.handleOpen.bind(this);this.ws.onmessage=this.handleMessage.bind(this);this.ws.onclose=this.handleClose.bind(this);this.ws.onerror=this.handleError.bind(this)}catch(error){this.log("Connection error:",error);this.scheduleReconnect()}}handleOpen(event){this.log("Connection opened");this.reconnectAttempts=0;this.startHeartbeat();this.emit(SocketEvent.Open,event)}handleMessage(event){try{const rawData=event.data;const response=decode(new Uint8Array(rawData));this.log("Received:",response);this.stats.responsesReceived++;if("error"in response)this.stats.errors++;if(null!==response.id){const streamCallback=this.streamCallbacks.get(response.id);if(streamCallback){streamCallback(response);this.emit(SocketEvent.Message,{data:response,rawData});return}const metadata=this.pendingRequests.get(response.id);if(metadata){clearTimeout(metadata.timeoutId);this.pendingRequests.delete(response.id);const responseTime=Date.now()-metadata.timestamp;this.updateResponseTime(responseTime);if("error"in response)metadata.reject(new Error(`${response.error.message} (${response.error.code})`));else metadata.resolve(response.result)}}this.emit(SocketEvent.Message,{data:response,rawData})}catch(error){this.log("Failed to decode message:",error)}}handleClose(event){this.log("Connection closed:",event.code,event.reason);this.stopHeartbeat();this.emit(SocketEvent.Close,event);this.rejectAllPendingRequests(new Error("Connection closed"),jsonrpc_JsonRpcErrorCode.ConnectionClosed);if(this.options.autoReconnect)this.scheduleReconnect()}handleError(event){this.log("Connection error:",event);this.emit(SocketEvent.Error,event)}scheduleReconnect(){if(this.reconnectTimeoutId)return;if(this.reconnectAttempts>=this.options.maxReconnectAttempts){this.log("Max reconnect attempts reached");this.emit(SocketEvent.ReconnectFailed,void 0);return}this.reconnectAttempts++;this.stats.reconnectCount++;this.log(`Reconnecting in ${this.options.reconnectInterval}ms (attempt ${this.reconnectAttempts}/${this.options.maxReconnectAttempts})`);this.emit(SocketEvent.Reconnecting,{attempt:this.reconnectAttempts,maxAttempts:this.options.maxReconnectAttempts});this.reconnectTimeoutId=setTimeout(()=>{this.reconnectTimeoutId=null;this.connect()},this.options.reconnectInterval)}startHeartbeat(){if(this.options.heartbeatInterval<=0||null!==this.heartbeatIntervalId)return;this.heartbeatIntervalId=setInterval(()=>{if(this.isConnected)this.notify({method:this.options.heartbeatMethod}).catch(error=>{this.log("Heartbeat failed:",error)})},this.options.heartbeatInterval)}stopHeartbeat(){if(this.heartbeatIntervalId){clearInterval(this.heartbeatIntervalId);this.heartbeatIntervalId=null}}rejectAllPendingRequests(error,code){for(const[id,metadata]of this.pendingRequests){clearTimeout(metadata.timeoutId);metadata.reject(error)}this.pendingRequests.clear()}updateResponseTime(time){this.responseTimes.push(time);if(this.responseTimes.length>100)this.responseTimes.shift();this.stats.averageResponseTime=this.responseTimes.reduce((sum,t)=>sum+t,0)/this.responseTimes.length}async request(options){if(!this.isConnected)throw new Error("WebSocket is not connected");const id=options.id??generateUUID();const request={jsonrpc:"2.0",method:options.method,params:options.params,id};return new Promise((resolve,reject)=>{const timeout=options.timeout??this.options.defaultTimeout;const timeoutId=setTimeout(()=>{this.pendingRequests.delete(id);this.stats.timeouts++;reject(new Error(`Request timeout after ${timeout}ms`))},timeout);this.pendingRequests.set(id,{id,timestamp:Date.now(),timeoutId,resolve:resolve,reject});try{const encoded=encode(request);this.ws?.send(encoded);this.stats.requestsSent++;this.log("Sent request:",request)}catch(error){clearTimeout(timeoutId);this.pendingRequests.delete(id);reject(error)}})}async notify(options){if(!this.isConnected)throw new Error("WebSocket is not connected");const notification={jsonrpc:"2.0",method:options.method,params:options.params};const encoded=encode(notification);this.ws?.send(encoded);this.log("Sent notification:",notification)}stream(options,callback){if(!this.isConnected)throw new Error("WebSocket is not connected");const id=options.id??generateUUID();const request={jsonrpc:"2.0",method:options.method,params:options.params,id};let closed=false;this.streamCallbacks.set(id,callback);try{const encoded=encode(request);this.ws?.send(encoded);this.stats.requestsSent++;this.log("Sent stream request:",request)}catch(error){this.streamCallbacks.delete(id);throw error}return{id,close:()=>{if(!closed){closed=true;this.streamCallbacks.delete(id);this.log("Stream closed:",id)}},get closed(){return closed}}}sendRaw(data){if(!this.isConnected)throw new Error("WebSocket is not connected");this.ws?.send(data);this.log("Sent raw data:",data.byteLength,"bytes")}close(code,reason){this.options.autoReconnect=false;if(this.reconnectTimeoutId){clearTimeout(this.reconnectTimeoutId);this.reconnectTimeoutId=null}this.stopHeartbeat();if(this.ws){this.ws.close(code,reason);this.ws=null}this.rejectAllPendingRequests(new Error("Connection closed by client"),jsonrpc_JsonRpcErrorCode.ConnectionClosed);this.removeAllListeners()}reconnectToUrl(url){this.close();this.options.url=url;this.options.autoReconnect=true;this.reconnectAttempts=0;this.connect()}log(...args){if(this.options.debug)console.log("[JsonRpcWebSocket]",...args)}}export{JsonRpcWebSocketClient,SocketEvent,decode,JsonRpcWebSocketClient as default,pack_deserialize as deserialize,encode,generateUUID,pack_serialize as serialize};
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "types": "index.d.ts",
6
6
  "author": "Hxgh",
7
7
  "license": "MIT",
8
- "version": "0.2.2",
8
+ "version": "0.2.4",
9
9
  "private": false,
10
10
  "keywords": [
11
11
  "json-rpc",