libshv-js 7.1.6 → 7.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chainpack.d.ts +1 -1
- package/dist/chainpack.js +32 -35
- package/dist/cpcontext.d.ts +1 -1
- package/dist/cpcontext.js +2 -1
- package/dist/cpon.d.ts +5 -5
- package/dist/cpon.js +80 -81
- package/dist/rpcmessage.js +3 -3
- package/dist/rpcvalue.js +3 -3
- package/dist/ws-client.d.ts +2 -2
- package/dist/ws-client.js +243 -237
- package/package.json +3 -3
package/dist/chainpack.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { UnpackContext, PackContext } from './cpcontext';
|
|
|
3
3
|
declare class ChainPackReader {
|
|
4
4
|
ctx: UnpackContext;
|
|
5
5
|
constructor(data: ArrayBuffer | UnpackContext);
|
|
6
|
+
private implReadMap;
|
|
6
7
|
read(): RpcValue;
|
|
7
8
|
readUIntDataHelper(type: 'Int' | 'UInt'): bigint;
|
|
8
9
|
readIntData(): number;
|
|
@@ -11,7 +12,6 @@ declare class ChainPackReader {
|
|
|
11
12
|
readMetaMap(): MetaMap;
|
|
12
13
|
readMap(): ShvMap;
|
|
13
14
|
readIMap(): IMap;
|
|
14
|
-
private implReadMap;
|
|
15
15
|
}
|
|
16
16
|
declare class ChainPackWriter {
|
|
17
17
|
ctx: PackContext;
|
package/dist/chainpack.js
CHANGED
|
@@ -79,6 +79,33 @@ class ChainPackReader {
|
|
|
79
79
|
constructor(data) {
|
|
80
80
|
this.ctx = data instanceof cpcontext_1.UnpackContext ? data : new cpcontext_1.UnpackContext(data);
|
|
81
81
|
}
|
|
82
|
+
implReadMap(mapType) {
|
|
83
|
+
const map = {
|
|
84
|
+
[rpcvalue_1.shvMapType]: mapType,
|
|
85
|
+
};
|
|
86
|
+
while (true) {
|
|
87
|
+
const b = this.ctx.peekByte();
|
|
88
|
+
if (b === PackingSchema.Term) {
|
|
89
|
+
this.ctx.getByte();
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
const key = this.read();
|
|
93
|
+
const val = this.read();
|
|
94
|
+
if ((map[rpcvalue_1.shvMapType] === 'metamap' && typeof key === 'string') ||
|
|
95
|
+
(map[rpcvalue_1.shvMapType] === 'metamap' && typeof key === 'number') ||
|
|
96
|
+
(map[rpcvalue_1.shvMapType] === 'map' && typeof key === 'string')) {
|
|
97
|
+
map[key] = val;
|
|
98
|
+
// eslint-disable-next-line unicorn/no-duplicate-if-branches -- the type system needs this branch
|
|
99
|
+
}
|
|
100
|
+
else if (map[rpcvalue_1.shvMapType] === 'imap' && typeof key === 'number') {
|
|
101
|
+
map[key] = val;
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
throw new TypeError('Malformed map, invalid key');
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return map;
|
|
108
|
+
}
|
|
82
109
|
/* eslint-disable complexity -- we might simplify this at some point, but it works now */
|
|
83
110
|
read() {
|
|
84
111
|
let meta;
|
|
@@ -285,36 +312,6 @@ class ChainPackReader {
|
|
|
285
312
|
readIMap() {
|
|
286
313
|
return this.implReadMap('imap');
|
|
287
314
|
}
|
|
288
|
-
implReadMap(mapType) {
|
|
289
|
-
const map = {
|
|
290
|
-
[rpcvalue_1.shvMapType]: mapType,
|
|
291
|
-
};
|
|
292
|
-
while (true) {
|
|
293
|
-
const b = this.ctx.peekByte();
|
|
294
|
-
if (b === PackingSchema.Term) {
|
|
295
|
-
this.ctx.getByte();
|
|
296
|
-
break;
|
|
297
|
-
}
|
|
298
|
-
const key = this.read();
|
|
299
|
-
const val = this.read();
|
|
300
|
-
if (map[rpcvalue_1.shvMapType] === 'metamap' && typeof key === 'string') {
|
|
301
|
-
map[key] = val;
|
|
302
|
-
}
|
|
303
|
-
else if (map[rpcvalue_1.shvMapType] === 'metamap' && typeof key === 'number') {
|
|
304
|
-
map[Number(key)] = val;
|
|
305
|
-
}
|
|
306
|
-
else if (map[rpcvalue_1.shvMapType] === 'map' && typeof key === 'string') {
|
|
307
|
-
map[key] = val;
|
|
308
|
-
}
|
|
309
|
-
else if (map[rpcvalue_1.shvMapType] === 'imap' && typeof key === 'number') {
|
|
310
|
-
map[Number(key)] = val;
|
|
311
|
-
}
|
|
312
|
-
else {
|
|
313
|
-
throw new TypeError('Malformed map, invalid key');
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
return map;
|
|
317
|
-
}
|
|
318
315
|
}
|
|
319
316
|
exports.ChainPackReader = ChainPackReader;
|
|
320
317
|
class ChainPackWriter {
|
|
@@ -426,12 +423,12 @@ class ChainPackWriter {
|
|
|
426
423
|
this.writeUIntDataHelper(BigInt(snum), 'Int');
|
|
427
424
|
}
|
|
428
425
|
writeInt(n) {
|
|
429
|
-
if (
|
|
430
|
-
this.ctx.putByte(
|
|
426
|
+
if (n >= 0 && n < 64) {
|
|
427
|
+
this.ctx.putByte(n + 64);
|
|
431
428
|
return;
|
|
432
429
|
}
|
|
433
430
|
this.ctx.putByte(PackingSchema.Int);
|
|
434
|
-
this.writeIntData(
|
|
431
|
+
this.writeIntData(n);
|
|
435
432
|
}
|
|
436
433
|
writeUInt(n) {
|
|
437
434
|
if (Number(n) < 64) {
|
|
@@ -529,14 +526,14 @@ class ChainPackWriter {
|
|
|
529
526
|
else if (map[rpcvalue_1.shvMapType] === 'metamap') {
|
|
530
527
|
const intKey = Number(key);
|
|
531
528
|
if (Number.isNaN(intKey)) {
|
|
532
|
-
this.writeJSString(key
|
|
529
|
+
this.writeJSString(key);
|
|
533
530
|
}
|
|
534
531
|
else {
|
|
535
532
|
this.writeInt(intKey);
|
|
536
533
|
}
|
|
537
534
|
}
|
|
538
535
|
else {
|
|
539
|
-
this.writeJSString(key
|
|
536
|
+
this.writeJSString(key);
|
|
540
537
|
}
|
|
541
538
|
this.write(value);
|
|
542
539
|
}
|
package/dist/cpcontext.d.ts
CHANGED
package/dist/cpcontext.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.UnpackContext = exports.PackContext = void 0;
|
|
4
4
|
class UnpackContext {
|
|
5
|
-
index;
|
|
6
5
|
data;
|
|
6
|
+
index;
|
|
7
7
|
constructor(buf) {
|
|
8
8
|
this.data = new Uint8Array(buf);
|
|
9
9
|
this.index = 0;
|
|
@@ -72,6 +72,7 @@ class PackContext {
|
|
|
72
72
|
/* eslint-enable no-bitwise */
|
|
73
73
|
}
|
|
74
74
|
buffer() {
|
|
75
|
+
// eslint-disable-next-line unicorn/no-unsafe-buffer-conversion
|
|
75
76
|
return this.data.buffer.slice(0, this.length);
|
|
76
77
|
}
|
|
77
78
|
}
|
package/dist/cpon.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ declare const utf8ToString: (bytearray: ArrayBuffer) => string;
|
|
|
5
5
|
declare class CponReader {
|
|
6
6
|
ctx: UnpackContext;
|
|
7
7
|
constructor(unpackContext: UnpackContext);
|
|
8
|
+
private implReadMap;
|
|
8
9
|
read(): RpcValue;
|
|
9
10
|
skipWhitespace(): void;
|
|
10
11
|
readDateTime(): DateTime;
|
|
@@ -18,7 +19,6 @@ declare class CponReader {
|
|
|
18
19
|
readIMap(): IMap;
|
|
19
20
|
readInt(): number;
|
|
20
21
|
readNumber(): number | Decimal | UInt<number>;
|
|
21
|
-
private implReadMap;
|
|
22
22
|
}
|
|
23
23
|
declare class CponWriter {
|
|
24
24
|
private readonly indentString?;
|
|
@@ -26,6 +26,10 @@ declare class CponWriter {
|
|
|
26
26
|
ctx: PackContext;
|
|
27
27
|
nestLevel: number;
|
|
28
28
|
constructor(indentString?: string | undefined, oneLiners?: OneLiners);
|
|
29
|
+
private doIndentIfNotOneliner;
|
|
30
|
+
private isOneLiner;
|
|
31
|
+
private increaseIndentIfNotOneLiner;
|
|
32
|
+
private decreaseIndentIfNotOneLiner;
|
|
29
33
|
write(rpcVal: RpcValue): void;
|
|
30
34
|
writeJSString(str: string): void;
|
|
31
35
|
writeBlob(buffer: ArrayBuffer): void;
|
|
@@ -40,10 +44,6 @@ declare class CponWriter {
|
|
|
40
44
|
writeInt(num: Int): void;
|
|
41
45
|
writeDouble(num: Double): void;
|
|
42
46
|
writeDecimal(val: Decimal): void;
|
|
43
|
-
private doIndentIfNotOneliner;
|
|
44
|
-
private isOneLiner;
|
|
45
|
-
private increaseIndentIfNotOneLiner;
|
|
46
|
-
private decreaseIndentIfNotOneLiner;
|
|
47
47
|
}
|
|
48
48
|
export declare enum OneLiners {
|
|
49
49
|
Yes = 0,
|
package/dist/cpon.js
CHANGED
|
@@ -82,6 +82,42 @@ class CponReader {
|
|
|
82
82
|
constructor(unpackContext) {
|
|
83
83
|
this.ctx = unpackContext;
|
|
84
84
|
}
|
|
85
|
+
implReadMap(mapType, terminator) {
|
|
86
|
+
const map = {
|
|
87
|
+
[rpcvalue_1.shvMapType]: mapType,
|
|
88
|
+
};
|
|
89
|
+
this.ctx.getByte(); // eat start
|
|
90
|
+
while (true) {
|
|
91
|
+
this.skipWhitespace();
|
|
92
|
+
const b = this.ctx.peekByte();
|
|
93
|
+
if (b === terminator) {
|
|
94
|
+
this.ctx.getByte();
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
97
|
+
const key = this.read();
|
|
98
|
+
if (key instanceof rpcvalue_1.RpcValueWithMetaData) {
|
|
99
|
+
throw new TypeError('Map/IMap/MetaMap key can\'t have its own MetaData');
|
|
100
|
+
}
|
|
101
|
+
this.skipWhitespace();
|
|
102
|
+
const val = this.read();
|
|
103
|
+
if (map[rpcvalue_1.shvMapType] === 'metamap' && typeof key === 'string') {
|
|
104
|
+
map[key] = val;
|
|
105
|
+
}
|
|
106
|
+
else if (map[rpcvalue_1.shvMapType] === 'metamap' && (key instanceof rpcvalue_1.UInt || typeof key === 'number')) {
|
|
107
|
+
map[Number(key)] = val;
|
|
108
|
+
}
|
|
109
|
+
else if (map[rpcvalue_1.shvMapType] === 'map' && typeof key === 'string') {
|
|
110
|
+
map[key] = val;
|
|
111
|
+
}
|
|
112
|
+
else if (map[rpcvalue_1.shvMapType] === 'imap' && (key instanceof rpcvalue_1.UInt || typeof key === 'number')) {
|
|
113
|
+
map[Number(key)] = val;
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
throw new TypeError('Malformed map, invalid key');
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return map;
|
|
120
|
+
}
|
|
85
121
|
read() {
|
|
86
122
|
let meta;
|
|
87
123
|
this.skipWhitespace();
|
|
@@ -233,40 +269,40 @@ class CponReader {
|
|
|
233
269
|
return date;
|
|
234
270
|
}
|
|
235
271
|
readDateTimeInner() {
|
|
236
|
-
|
|
237
|
-
const year = Number(this.readInt());
|
|
272
|
+
const year = this.readInt();
|
|
238
273
|
let b = this.ctx.getByte();
|
|
239
274
|
if (b !== '-'.codePointAt(0)) {
|
|
240
275
|
throw new TypeError('Malformed year-month separator in DateTime');
|
|
241
276
|
}
|
|
242
|
-
const month =
|
|
277
|
+
const month = this.readInt();
|
|
243
278
|
b = this.ctx.getByte();
|
|
244
279
|
if (b !== '-'.codePointAt(0)) {
|
|
245
280
|
throw new TypeError('Malformed year-month separator in DateTime');
|
|
246
281
|
}
|
|
247
|
-
const day =
|
|
282
|
+
const day = this.readInt();
|
|
248
283
|
b = this.ctx.getByte();
|
|
249
284
|
if (b !== ' '.codePointAt(0) && b !== 'T'.codePointAt(0)) {
|
|
250
285
|
throw new TypeError('Malformed date-time separator in DateTime');
|
|
251
286
|
}
|
|
252
|
-
const hour =
|
|
287
|
+
const hour = this.readInt();
|
|
253
288
|
b = this.ctx.getByte();
|
|
254
289
|
if (b !== ':'.codePointAt(0)) {
|
|
255
290
|
throw new TypeError('Malformed year-month separator in DateTime');
|
|
256
291
|
}
|
|
257
|
-
const min =
|
|
292
|
+
const min = this.readInt();
|
|
258
293
|
b = this.ctx.getByte();
|
|
259
294
|
if (b !== ':'.codePointAt(0)) {
|
|
260
295
|
throw new TypeError('Malformed year-month separator in DateTime');
|
|
261
296
|
}
|
|
262
|
-
const sec =
|
|
297
|
+
const sec = this.readInt();
|
|
263
298
|
let msec = 0;
|
|
264
299
|
b = this.ctx.peekByte();
|
|
265
300
|
if (b === '.'.codePointAt(0)) {
|
|
266
301
|
this.ctx.getByte();
|
|
267
|
-
msec =
|
|
302
|
+
msec = this.readInt();
|
|
268
303
|
}
|
|
269
304
|
b = this.ctx.peekByte();
|
|
305
|
+
let utcOffset = 0;
|
|
270
306
|
if (b === 'Z'.codePointAt(0)) {
|
|
271
307
|
// zulu time
|
|
272
308
|
this.ctx.getByte();
|
|
@@ -275,7 +311,7 @@ class CponReader {
|
|
|
275
311
|
// UTC time offset
|
|
276
312
|
this.ctx.getByte();
|
|
277
313
|
const ix1 = this.ctx.index;
|
|
278
|
-
const val =
|
|
314
|
+
const val = this.readInt();
|
|
279
315
|
const n = this.ctx.index - ix1;
|
|
280
316
|
if (!(n === 2 || n === 4)) {
|
|
281
317
|
throw new TypeError('Malformed TS offset in DateTime.');
|
|
@@ -394,10 +430,8 @@ class CponReader {
|
|
|
394
430
|
// end of string
|
|
395
431
|
break;
|
|
396
432
|
}
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
pctx.putByte(b2);
|
|
400
|
-
}
|
|
433
|
+
const b2 = (unhex(b) * 16) + unhex(this.ctx.getByte());
|
|
434
|
+
pctx.putByte(b2);
|
|
401
435
|
}
|
|
402
436
|
return pctx.buffer();
|
|
403
437
|
}
|
|
@@ -500,7 +534,7 @@ class CponReader {
|
|
|
500
534
|
isNeg = true;
|
|
501
535
|
b = this.ctx.getByte();
|
|
502
536
|
}
|
|
503
|
-
let mantisa =
|
|
537
|
+
let mantisa = this.readInt();
|
|
504
538
|
b = this.ctx.peekByte();
|
|
505
539
|
(() => {
|
|
506
540
|
while (true) {
|
|
@@ -514,7 +548,7 @@ class CponReader {
|
|
|
514
548
|
isDecimal = true;
|
|
515
549
|
this.ctx.getByte();
|
|
516
550
|
const ix1 = this.ctx.index;
|
|
517
|
-
decimals =
|
|
551
|
+
decimals = this.readInt();
|
|
518
552
|
// if(n < 0)
|
|
519
553
|
// UNPACK_ERROR(CCPCP_RC_MALFORMED_INPUT, "Malformed number decimal part.")
|
|
520
554
|
decCnt = this.ctx.index - ix1;
|
|
@@ -529,7 +563,7 @@ class CponReader {
|
|
|
529
563
|
isDecimal = true;
|
|
530
564
|
this.ctx.getByte();
|
|
531
565
|
const ix1 = this.ctx.index;
|
|
532
|
-
exponent =
|
|
566
|
+
exponent = this.readInt();
|
|
533
567
|
if (ix1 === this.ctx.index) {
|
|
534
568
|
throw new TypeError('Malformed number exponential part.');
|
|
535
569
|
}
|
|
@@ -553,42 +587,6 @@ class CponReader {
|
|
|
553
587
|
}
|
|
554
588
|
return isNeg ? -mantisa : mantisa;
|
|
555
589
|
}
|
|
556
|
-
implReadMap(mapType, terminator) {
|
|
557
|
-
const map = {
|
|
558
|
-
[rpcvalue_1.shvMapType]: mapType,
|
|
559
|
-
};
|
|
560
|
-
this.ctx.getByte(); // eat start
|
|
561
|
-
while (true) {
|
|
562
|
-
this.skipWhitespace();
|
|
563
|
-
const b = this.ctx.peekByte();
|
|
564
|
-
if (b === terminator) {
|
|
565
|
-
this.ctx.getByte();
|
|
566
|
-
break;
|
|
567
|
-
}
|
|
568
|
-
const key = this.read();
|
|
569
|
-
if (key instanceof rpcvalue_1.RpcValueWithMetaData) {
|
|
570
|
-
throw new TypeError('Map/IMap/MetaMap key can\'t have its own MetaData');
|
|
571
|
-
}
|
|
572
|
-
this.skipWhitespace();
|
|
573
|
-
const val = this.read();
|
|
574
|
-
if (map[rpcvalue_1.shvMapType] === 'metamap' && typeof key === 'string') {
|
|
575
|
-
map[key] = val;
|
|
576
|
-
}
|
|
577
|
-
else if (map[rpcvalue_1.shvMapType] === 'metamap' && (key instanceof rpcvalue_1.UInt || typeof key === 'number')) {
|
|
578
|
-
map[Number(key)] = val;
|
|
579
|
-
}
|
|
580
|
-
else if (map[rpcvalue_1.shvMapType] === 'map' && typeof key === 'string') {
|
|
581
|
-
map[key] = val;
|
|
582
|
-
}
|
|
583
|
-
else if (map[rpcvalue_1.shvMapType] === 'imap' && (key instanceof rpcvalue_1.UInt || typeof key === 'number')) {
|
|
584
|
-
map[Number(key)] = val;
|
|
585
|
-
}
|
|
586
|
-
else {
|
|
587
|
-
throw new TypeError('Malformed map, invalid key');
|
|
588
|
-
}
|
|
589
|
-
}
|
|
590
|
-
return map;
|
|
591
|
-
}
|
|
592
590
|
}
|
|
593
591
|
exports.CponReader = CponReader;
|
|
594
592
|
class CponWriter {
|
|
@@ -601,6 +599,33 @@ class CponWriter {
|
|
|
601
599
|
this.oneLiners = oneLiners;
|
|
602
600
|
this.ctx = new cpcontext_1.PackContext();
|
|
603
601
|
}
|
|
602
|
+
doIndentIfNotOneliner(map) {
|
|
603
|
+
if (this.indentString === undefined || this.isOneLiner(map)) {
|
|
604
|
+
return;
|
|
605
|
+
}
|
|
606
|
+
this.ctx.putByte('\n'.codePointAt(0));
|
|
607
|
+
this.ctx.writeStringUtf8(this.indentString.repeat(this.nestLevel));
|
|
608
|
+
}
|
|
609
|
+
isOneLiner(value) {
|
|
610
|
+
if (this.oneLiners === OneLiners.No) {
|
|
611
|
+
return false;
|
|
612
|
+
}
|
|
613
|
+
const keyThreshold = Array.isArray(value) ? 10 : 5;
|
|
614
|
+
if (Array.isArray(value)) {
|
|
615
|
+
return value.length <= keyThreshold && value.every(x => !Array.isArray(x) && !(0, rpcvalue_1.isShvMap)(x) && !(0, rpcvalue_1.isIMap)(x));
|
|
616
|
+
}
|
|
617
|
+
return Object.keys(value).length <= keyThreshold && Object.values(value).every(x => (!Array.isArray(x) && !(0, rpcvalue_1.isShvMap)(x) && !(0, rpcvalue_1.isIMap)(x)));
|
|
618
|
+
}
|
|
619
|
+
increaseIndentIfNotOneLiner(value) {
|
|
620
|
+
if (!this.isOneLiner(value)) {
|
|
621
|
+
this.nestLevel++;
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
decreaseIndentIfNotOneLiner(value) {
|
|
625
|
+
if (!this.isOneLiner(value)) {
|
|
626
|
+
this.nestLevel--;
|
|
627
|
+
}
|
|
628
|
+
}
|
|
604
629
|
write(rpcVal) {
|
|
605
630
|
if (rpcVal instanceof rpcvalue_1.RpcValueWithMetaData) {
|
|
606
631
|
this.writeMeta(rpcVal.meta);
|
|
@@ -756,7 +781,7 @@ class CponWriter {
|
|
|
756
781
|
const intKey = Number(key);
|
|
757
782
|
if (Number.isNaN(intKey)) {
|
|
758
783
|
this.ctx.putByte('"'.codePointAt(0));
|
|
759
|
-
this.ctx.writeStringUtf8(key
|
|
784
|
+
this.ctx.writeStringUtf8(key);
|
|
760
785
|
this.ctx.putByte('"'.codePointAt(0));
|
|
761
786
|
}
|
|
762
787
|
else {
|
|
@@ -764,7 +789,7 @@ class CponWriter {
|
|
|
764
789
|
}
|
|
765
790
|
}
|
|
766
791
|
else {
|
|
767
|
-
this.writeJSString(key
|
|
792
|
+
this.writeJSString(key);
|
|
768
793
|
}
|
|
769
794
|
this.ctx.writeStringUtf8(':');
|
|
770
795
|
this.write(value);
|
|
@@ -794,7 +819,7 @@ class CponWriter {
|
|
|
794
819
|
this.ctx.putByte('u'.codePointAt(0));
|
|
795
820
|
}
|
|
796
821
|
writeInt(num) {
|
|
797
|
-
const s =
|
|
822
|
+
const s = num.toString();
|
|
798
823
|
this.ctx.writeStringUtf8(s);
|
|
799
824
|
}
|
|
800
825
|
writeDouble(num) {
|
|
@@ -842,32 +867,6 @@ class CponWriter {
|
|
|
842
867
|
this.ctx.putByte(str.codePointAt(i));
|
|
843
868
|
}
|
|
844
869
|
}
|
|
845
|
-
doIndentIfNotOneliner(map) {
|
|
846
|
-
if (this.indentString !== undefined && !this.isOneLiner(map)) {
|
|
847
|
-
this.ctx.putByte('\n'.codePointAt(0));
|
|
848
|
-
this.ctx.writeStringUtf8(this.indentString.repeat(this.nestLevel));
|
|
849
|
-
}
|
|
850
|
-
}
|
|
851
|
-
isOneLiner(value) {
|
|
852
|
-
if (this.oneLiners === OneLiners.No) {
|
|
853
|
-
return false;
|
|
854
|
-
}
|
|
855
|
-
const keyThreshold = Array.isArray(value) ? 10 : 5;
|
|
856
|
-
if (Array.isArray(value)) {
|
|
857
|
-
return value.length <= keyThreshold && !(value.some(x => Array.isArray(x) || (0, rpcvalue_1.isShvMap)(x) || (0, rpcvalue_1.isIMap)(x)));
|
|
858
|
-
}
|
|
859
|
-
return Object.keys(value).length <= keyThreshold && !(Object.values(value).some(x => Array.isArray(x) || (0, rpcvalue_1.isShvMap)(x) || (0, rpcvalue_1.isIMap)(x)));
|
|
860
|
-
}
|
|
861
|
-
increaseIndentIfNotOneLiner(value) {
|
|
862
|
-
if (!this.isOneLiner(value)) {
|
|
863
|
-
this.nestLevel++;
|
|
864
|
-
}
|
|
865
|
-
}
|
|
866
|
-
decreaseIndentIfNotOneLiner(value) {
|
|
867
|
-
if (!this.isOneLiner(value)) {
|
|
868
|
-
this.nestLevel--;
|
|
869
|
-
}
|
|
870
|
-
}
|
|
871
870
|
}
|
|
872
871
|
exports.CponWriter = CponWriter;
|
|
873
872
|
var OneLiners;
|
package/dist/rpcmessage.js
CHANGED
|
@@ -35,9 +35,9 @@ const implRpcMessage = (message) => typeof message === 'object'
|
|
|
35
35
|
&& 'meta' in message
|
|
36
36
|
&& typeof message.meta === 'object'
|
|
37
37
|
&& message.meta !== null;
|
|
38
|
-
const isSignal = (message) => implRpcMessage(message) && !(exports.RPC_MESSAGE_REQUEST_ID
|
|
38
|
+
const isSignal = (message) => implRpcMessage(message) && !Object.hasOwn(message.meta, exports.RPC_MESSAGE_REQUEST_ID) && Object.hasOwn(message.meta, exports.RPC_MESSAGE_METHOD);
|
|
39
39
|
exports.isSignal = isSignal;
|
|
40
|
-
const isRequest = (message) => implRpcMessage(message) && exports.RPC_MESSAGE_REQUEST_ID
|
|
40
|
+
const isRequest = (message) => implRpcMessage(message) && Object.hasOwn(message.meta, exports.RPC_MESSAGE_REQUEST_ID) && Object.hasOwn(message.meta, exports.RPC_MESSAGE_METHOD);
|
|
41
41
|
exports.isRequest = isRequest;
|
|
42
|
-
const isResponse = (message) => implRpcMessage(message) && exports.RPC_MESSAGE_REQUEST_ID
|
|
42
|
+
const isResponse = (message) => implRpcMessage(message) && Object.hasOwn(message.meta, exports.RPC_MESSAGE_REQUEST_ID) && !Object.hasOwn(message.meta, exports.RPC_MESSAGE_METHOD);
|
|
43
43
|
exports.isResponse = isResponse;
|
package/dist/rpcvalue.js
CHANGED
|
@@ -8,7 +8,7 @@ class UInt {
|
|
|
8
8
|
this.value = u.value;
|
|
9
9
|
return;
|
|
10
10
|
}
|
|
11
|
-
if (u < 0 || !Number.
|
|
11
|
+
if (u < 0 || !Number.isSafeInteger(u)) {
|
|
12
12
|
throw new Error(`Invalid value '${u}' for UInt must a positive integral number`);
|
|
13
13
|
}
|
|
14
14
|
this.value = u;
|
|
@@ -17,7 +17,7 @@ class UInt {
|
|
|
17
17
|
return this.value;
|
|
18
18
|
}
|
|
19
19
|
toString() {
|
|
20
|
-
return
|
|
20
|
+
return this.value.toString();
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
exports.UInt = UInt;
|
|
@@ -32,7 +32,7 @@ class Decimal {
|
|
|
32
32
|
mantisa;
|
|
33
33
|
exponent;
|
|
34
34
|
constructor(mantisa, exponent) {
|
|
35
|
-
if (!Number.
|
|
35
|
+
if (!Number.isSafeInteger(exponent)) {
|
|
36
36
|
throw new TypeError(`Decimal: exponent must be integral (${exponent})`);
|
|
37
37
|
}
|
|
38
38
|
this.mantisa = mantisa;
|
package/dist/ws-client.d.ts
CHANGED
|
@@ -226,6 +226,8 @@ declare class WsClient {
|
|
|
226
226
|
private readonly timeout;
|
|
227
227
|
private shvApiVersion;
|
|
228
228
|
constructor(options: WsClientOptions<MethodHandler>);
|
|
229
|
+
private workflowsProcedure;
|
|
230
|
+
private loginProcedure;
|
|
229
231
|
callRpcMethod(shvPath: '.broker/currentClient', method: 'accessGrantForMethodCall', params: [string, string], options?: CallRpcMethodOptions): RpcRequestPromise<ResultOrError<string>>;
|
|
230
232
|
callRpcMethod(shvPath: '.broker/currentClient', method: 'accessLevelForMethodCall', params: [string, string], options?: CallRpcMethodOptions): RpcRequestPromise<ResultOrError<number>>;
|
|
231
233
|
callRpcMethod(shvPath: string | undefined, method: 'dir', params?: RpcValue, options?: CallRpcMethodOptions): RpcRequestPromise<ResultOrError<DirResult>>;
|
|
@@ -240,7 +242,5 @@ declare class WsClient {
|
|
|
240
242
|
accessLevelForMethodCall(path: string, method: string): RpcRequestPromise<ResultOrError<number>>;
|
|
241
243
|
close(): void;
|
|
242
244
|
protected logDebug(...args: string[]): void;
|
|
243
|
-
private workflowsProcedure;
|
|
244
|
-
private loginProcedure;
|
|
245
245
|
}
|
|
246
246
|
export { WsClient };
|
package/dist/ws-client.js
CHANGED
|
@@ -113,7 +113,7 @@ exports.LoginRequired = createErrorClass(rpcmessage_1.ErrorCode.LoginRequired);
|
|
|
113
113
|
exports.UserIDRequired = createErrorClass(rpcmessage_1.ErrorCode.UserIDRequired);
|
|
114
114
|
exports.NotImplemented = createErrorClass(rpcmessage_1.ErrorCode.NotImplemented);
|
|
115
115
|
/* eslint-enable @typescript-eslint/naming-convention */
|
|
116
|
-
const makeTimeout = (ms, resolve) =>
|
|
116
|
+
const makeTimeout = (ms, resolve) => setTimeout(() => {
|
|
117
117
|
resolve(new exports.MethodCallTimeout((0, rpcvalue_1.makeIMap)({
|
|
118
118
|
[rpcmessage_1.ERROR_CODE]: rpcmessage_1.ErrorCode.MethodCallTimeout,
|
|
119
119
|
[rpcmessage_1.ERROR_MESSAGE]: `Shv call timeout after: ${ms} msec.`,
|
|
@@ -164,152 +164,155 @@ class WsClient {
|
|
|
164
164
|
};
|
|
165
165
|
// eslint-disable-next-line complexity
|
|
166
166
|
const handleRequest = async (request) => {
|
|
167
|
-
if ('onRequest' in this.options) {
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
const progress = requestHandler.options.onProgressQuery();
|
|
190
|
-
sendDelay(progress instanceof Promise ? await progress : progress);
|
|
167
|
+
if (!('onRequest' in this.options)) {
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
const requestId = request.meta[rpcmessage_1.RPC_MESSAGE_REQUEST_ID];
|
|
171
|
+
const respond = (value) => {
|
|
172
|
+
this.sendRpcMessage(new rpcvalue_1.RpcValueWithMetaData((0, rpcvalue_1.makeMetaMap)({
|
|
173
|
+
[rpcmessage_1.RPC_MESSAGE_CALLER_IDS]: request.meta[rpcmessage_1.RPC_MESSAGE_CALLER_IDS],
|
|
174
|
+
[rpcmessage_1.RPC_MESSAGE_REQUEST_ID]: requestId,
|
|
175
|
+
}), value));
|
|
176
|
+
};
|
|
177
|
+
const sendDelay = (progress) => {
|
|
178
|
+
respond((0, rpcvalue_1.makeIMap)({
|
|
179
|
+
[rpcmessage_1.RPC_MESSAGE_DELAY]: new rpcvalue_1.Double(progress),
|
|
180
|
+
}));
|
|
181
|
+
};
|
|
182
|
+
// eslint-disable-next-line unicorn/no-computed-property-existence-check
|
|
183
|
+
if (rpcmessage_1.RPC_MESSAGE_ABORT in request.value) {
|
|
184
|
+
const requestHandler = this.requestHandlers.get(requestId);
|
|
185
|
+
if (request.value[rpcmessage_1.RPC_MESSAGE_ABORT]) {
|
|
186
|
+
this.abortedRequests.add(requestId);
|
|
187
|
+
if (requestHandler?.options.onAbort !== undefined) {
|
|
188
|
+
requestHandler.options.onAbort();
|
|
191
189
|
}
|
|
190
|
+
}
|
|
191
|
+
if (!request.value[rpcmessage_1.RPC_MESSAGE_ABORT] && requestHandler?.options.onProgressQuery !== undefined) {
|
|
192
|
+
const progress = requestHandler.options.onProgressQuery();
|
|
193
|
+
sendDelay(progress instanceof Promise ? await progress : progress);
|
|
194
|
+
}
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
try {
|
|
198
|
+
const shvPath = request.meta[rpcmessage_1.RPC_MESSAGE_SHV_PATH];
|
|
199
|
+
const methodName = request.meta[rpcmessage_1.RPC_MESSAGE_METHOD];
|
|
200
|
+
const unhandledMethod = () => {
|
|
201
|
+
throw new exports.MethodNotFound(`No such path '${shvPath}' or method '${methodName}' or insufficient access rights.`);
|
|
202
|
+
};
|
|
203
|
+
const accessLevel = request.meta[rpcmessage_1.RPC_MESSAGE_ACCESS_LEVEL];
|
|
204
|
+
if (accessLevel === undefined) {
|
|
205
|
+
unhandledMethod();
|
|
192
206
|
return;
|
|
193
207
|
}
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
throw new exports.MethodNotFound(`No such path '${shvPath}' or method '${methodName}' or insufficient access rights.`);
|
|
199
|
-
};
|
|
200
|
-
const accessLevel = request.meta[rpcmessage_1.RPC_MESSAGE_ACCESS_LEVEL];
|
|
201
|
-
if (accessLevel === undefined) {
|
|
202
|
-
unhandledMethod();
|
|
203
|
-
return;
|
|
204
|
-
}
|
|
205
|
-
const methods = this.options.onRequest(shvPath);
|
|
206
|
-
if (methods === undefined) {
|
|
207
|
-
unhandledMethod();
|
|
208
|
-
return;
|
|
209
|
-
}
|
|
210
|
-
const methodDefinition = (() => {
|
|
211
|
-
const dirEntry = (0, rpcvalue_1.makeIMap)({
|
|
212
|
-
[exports.DIR_NAME]: 'dir',
|
|
213
|
-
[exports.DIR_FLAGS]: 0,
|
|
214
|
-
[exports.DIR_PARAM]: 'DirParam',
|
|
215
|
-
[exports.DIR_RESULT]: 'DirResult',
|
|
216
|
-
[exports.DIR_ACCESS]: (0, access_1.accessLevelFromAccessString)('bws'),
|
|
217
|
-
[exports.DIR_SIGNALS]: (0, rpcvalue_1.makeMap)({}),
|
|
218
|
-
[exports.DIR_EXTRA]: (0, rpcvalue_1.makeMap)({}),
|
|
219
|
-
});
|
|
220
|
-
const lsEntry = (0, rpcvalue_1.makeIMap)({
|
|
221
|
-
[exports.DIR_NAME]: 'ls',
|
|
222
|
-
[exports.DIR_FLAGS]: 0,
|
|
223
|
-
[exports.DIR_PARAM]: 'LsParam',
|
|
224
|
-
[exports.DIR_RESULT]: 'LsResult',
|
|
225
|
-
[exports.DIR_ACCESS]: (0, access_1.accessLevelFromAccessString)('bws'),
|
|
226
|
-
[exports.DIR_SIGNALS]: (0, rpcvalue_1.makeMap)({}),
|
|
227
|
-
[exports.DIR_EXTRA]: (0, rpcvalue_1.makeMap)({}),
|
|
228
|
-
});
|
|
229
|
-
switch (methodName) {
|
|
230
|
-
case 'dir':
|
|
231
|
-
return {
|
|
232
|
-
entry: dirEntry,
|
|
233
|
-
paramValidator: exports.validateDirParam,
|
|
234
|
-
handler(_shvPath, _method, param) {
|
|
235
|
-
const methodsResult = [dirEntry, lsEntry, ...methods.dirEntries.map(method => method.entry)];
|
|
236
|
-
switch (true) {
|
|
237
|
-
case typeof param === 'string':
|
|
238
|
-
return methodsResult.find(method => method[exports.DIR_NAME] === param) ?? false;
|
|
239
|
-
case typeof param === 'boolean':
|
|
240
|
-
case param === undefined:
|
|
241
|
-
console.log('methodsResult', '=', methodsResult);
|
|
242
|
-
return methodsResult;
|
|
243
|
-
}
|
|
244
|
-
},
|
|
245
|
-
};
|
|
246
|
-
case 'ls':
|
|
247
|
-
return {
|
|
248
|
-
entry: lsEntry,
|
|
249
|
-
paramValidator: exports.validateLsParam,
|
|
250
|
-
handler(shvPath) {
|
|
251
|
-
return methods.ls(shvPath);
|
|
252
|
-
},
|
|
253
|
-
};
|
|
254
|
-
default:
|
|
255
|
-
return methods.dirEntries.find(method => method.entry[exports.DIR_NAME] === methodName);
|
|
256
|
-
}
|
|
257
|
-
})();
|
|
258
|
-
if (methodDefinition === undefined) {
|
|
259
|
-
unhandledMethod();
|
|
260
|
-
return;
|
|
261
|
-
}
|
|
262
|
-
if (accessLevel < methodDefinition.entry[exports.DIR_ACCESS]) {
|
|
263
|
-
unhandledMethod();
|
|
264
|
-
return;
|
|
265
|
-
}
|
|
266
|
-
const requestParam = request.value[rpcmessage_1.RPC_MESSAGE_PARAMS];
|
|
267
|
-
if (methodDefinition.paramValidator !== undefined && !methodDefinition.paramValidator(requestParam)) {
|
|
268
|
-
throw new exports.InvalidParams(`Unexpected param '${shvPath}:${methodName}': ${(0, cpon_1.toCpon)(requestParam)}`);
|
|
269
|
-
}
|
|
270
|
-
let result = methodDefinition.handler(shvPath, methodName, requestParam, sendDelay);
|
|
271
|
-
if (result instanceof RequestHandler) {
|
|
272
|
-
this.requestHandlers.set(requestId, result);
|
|
273
|
-
result = result.options.result;
|
|
274
|
-
}
|
|
275
|
-
const resultOrError = (0, rpcvalue_1.makeIMap)({
|
|
276
|
-
[rpcmessage_1.RPC_MESSAGE_RESULT]: result instanceof Promise ? await result : result,
|
|
277
|
-
});
|
|
278
|
-
if (!this.abortedRequests.has(requestId)) {
|
|
279
|
-
respond(resultOrError);
|
|
280
|
-
}
|
|
281
|
-
else {
|
|
282
|
-
this.abortedRequests.delete(requestId);
|
|
283
|
-
}
|
|
284
|
-
if (requestId in this.requestHandlers) {
|
|
285
|
-
this.requestHandlers.delete(requestId);
|
|
286
|
-
}
|
|
208
|
+
const methods = this.options.onRequest(shvPath);
|
|
209
|
+
if (methods === undefined) {
|
|
210
|
+
unhandledMethod();
|
|
211
|
+
return;
|
|
287
212
|
}
|
|
288
|
-
|
|
289
|
-
const
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
213
|
+
const methodDefinition = (() => {
|
|
214
|
+
const dirEntry = (0, rpcvalue_1.makeIMap)({
|
|
215
|
+
[exports.DIR_NAME]: 'dir',
|
|
216
|
+
[exports.DIR_FLAGS]: 0,
|
|
217
|
+
[exports.DIR_PARAM]: 'DirParam',
|
|
218
|
+
[exports.DIR_RESULT]: 'DirResult',
|
|
219
|
+
[exports.DIR_ACCESS]: (0, access_1.accessLevelFromAccessString)('bws'),
|
|
220
|
+
[exports.DIR_SIGNALS]: (0, rpcvalue_1.makeMap)({}),
|
|
221
|
+
[exports.DIR_EXTRA]: (0, rpcvalue_1.makeMap)({}),
|
|
222
|
+
});
|
|
223
|
+
const lsEntry = (0, rpcvalue_1.makeIMap)({
|
|
224
|
+
[exports.DIR_NAME]: 'ls',
|
|
225
|
+
[exports.DIR_FLAGS]: 0,
|
|
226
|
+
[exports.DIR_PARAM]: 'LsParam',
|
|
227
|
+
[exports.DIR_RESULT]: 'LsResult',
|
|
228
|
+
[exports.DIR_ACCESS]: (0, access_1.accessLevelFromAccessString)('bws'),
|
|
229
|
+
[exports.DIR_SIGNALS]: (0, rpcvalue_1.makeMap)({}),
|
|
230
|
+
[exports.DIR_EXTRA]: (0, rpcvalue_1.makeMap)({}),
|
|
231
|
+
});
|
|
232
|
+
switch (methodName) {
|
|
233
|
+
case 'dir':
|
|
234
|
+
return {
|
|
235
|
+
entry: dirEntry,
|
|
236
|
+
paramValidator: exports.validateDirParam,
|
|
237
|
+
handler(_shvPath, _method, param) {
|
|
238
|
+
const methodsResult = [dirEntry, lsEntry, ...methods.dirEntries.map(method => method.entry)];
|
|
239
|
+
switch (true) {
|
|
240
|
+
case typeof param === 'string':
|
|
241
|
+
return methodsResult.find(method => method[exports.DIR_NAME] === param) ?? false;
|
|
242
|
+
case typeof param === 'boolean':
|
|
243
|
+
case param === undefined:
|
|
244
|
+
console.log('methodsResult', '=', methodsResult);
|
|
245
|
+
return methodsResult;
|
|
246
|
+
}
|
|
247
|
+
},
|
|
248
|
+
};
|
|
249
|
+
case 'ls':
|
|
250
|
+
return {
|
|
251
|
+
entry: lsEntry,
|
|
252
|
+
paramValidator: exports.validateLsParam,
|
|
253
|
+
handler(shvPath) {
|
|
254
|
+
return methods.ls(shvPath);
|
|
255
|
+
},
|
|
256
|
+
};
|
|
301
257
|
default:
|
|
302
|
-
|
|
303
|
-
break;
|
|
258
|
+
return methods.dirEntries.find(method => method.entry[exports.DIR_NAME] === methodName);
|
|
304
259
|
}
|
|
260
|
+
})();
|
|
261
|
+
if (methodDefinition === undefined) {
|
|
262
|
+
unhandledMethod();
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
if (accessLevel < methodDefinition.entry[exports.DIR_ACCESS]) {
|
|
266
|
+
unhandledMethod();
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
const requestParam = request.value[rpcmessage_1.RPC_MESSAGE_PARAMS];
|
|
270
|
+
if (methodDefinition.paramValidator !== undefined && !methodDefinition.paramValidator(requestParam)) {
|
|
271
|
+
throw new exports.InvalidParams(`Unexpected param '${shvPath}:${methodName}': ${(0, cpon_1.toCpon)(requestParam)}`);
|
|
272
|
+
}
|
|
273
|
+
let result = methodDefinition.handler(shvPath, methodName, requestParam, sendDelay);
|
|
274
|
+
if (result instanceof RequestHandler) {
|
|
275
|
+
this.requestHandlers.set(requestId, result);
|
|
276
|
+
result = result.options.result;
|
|
277
|
+
}
|
|
278
|
+
const resultOrError = (0, rpcvalue_1.makeIMap)({
|
|
279
|
+
[rpcmessage_1.RPC_MESSAGE_RESULT]: result instanceof Promise ? await result : result,
|
|
280
|
+
});
|
|
281
|
+
if (!this.abortedRequests.has(requestId)) {
|
|
282
|
+
respond(resultOrError);
|
|
283
|
+
}
|
|
284
|
+
else {
|
|
285
|
+
this.abortedRequests.delete(requestId);
|
|
286
|
+
}
|
|
287
|
+
if (this.requestHandlers.has(requestId)) {
|
|
288
|
+
this.requestHandlers.delete(requestId);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
catch (error) {
|
|
292
|
+
const sendError = (error) => {
|
|
293
|
+
respond((0, rpcvalue_1.makeIMap)({
|
|
294
|
+
[rpcmessage_1.RPC_MESSAGE_ERROR]: error.err_info,
|
|
295
|
+
}));
|
|
296
|
+
};
|
|
297
|
+
switch (true) {
|
|
298
|
+
case error instanceof RpcError:
|
|
299
|
+
sendError(error);
|
|
300
|
+
break;
|
|
301
|
+
case error instanceof Error:
|
|
302
|
+
sendError(new exports.InternalError(error.message));
|
|
303
|
+
break;
|
|
304
|
+
default:
|
|
305
|
+
sendError(new exports.InternalError('Unknown error'));
|
|
306
|
+
break;
|
|
305
307
|
}
|
|
306
308
|
}
|
|
307
309
|
};
|
|
308
310
|
const handleResponse = (response) => {
|
|
309
311
|
const requestId = response.meta[rpcmessage_1.RPC_MESSAGE_REQUEST_ID];
|
|
310
|
-
if (this.rpcHandlers[
|
|
311
|
-
const handler = this.rpcHandlers[
|
|
312
|
+
if (this.rpcHandlers[requestId] !== undefined) {
|
|
313
|
+
const handler = this.rpcHandlers[requestId];
|
|
312
314
|
clearTimeout(handler.timeout_handle);
|
|
315
|
+
// eslint-disable-next-line unicorn/no-computed-property-existence-check
|
|
313
316
|
if (rpcmessage_1.RPC_MESSAGE_DELAY in response.value) {
|
|
314
317
|
if (handler.delayCallback !== undefined) {
|
|
315
318
|
handler.delayCallback(response.value[rpcmessage_1.RPC_MESSAGE_DELAY].value);
|
|
@@ -318,6 +321,7 @@ class WsClient {
|
|
|
318
321
|
return;
|
|
319
322
|
}
|
|
320
323
|
handler.resolve((() => {
|
|
324
|
+
// eslint-disable-next-line unicorn/no-computed-property-existence-check
|
|
321
325
|
if (rpcmessage_1.RPC_MESSAGE_ERROR in response.value) {
|
|
322
326
|
const code = response.value[rpcmessage_1.RPC_MESSAGE_ERROR][rpcmessage_1.ERROR_CODE];
|
|
323
327
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
@@ -340,6 +344,7 @@ class WsClient {
|
|
|
340
344
|
})();
|
|
341
345
|
return new ErrorTypeCtor(response.value[rpcmessage_1.RPC_MESSAGE_ERROR]);
|
|
342
346
|
}
|
|
347
|
+
// eslint-disable-next-line unicorn/no-computed-property-existence-check
|
|
343
348
|
if (rpcmessage_1.RPC_MESSAGE_RESULT in response.value) {
|
|
344
349
|
return response.value[rpcmessage_1.RPC_MESSAGE_RESULT];
|
|
345
350
|
}
|
|
@@ -353,7 +358,7 @@ class WsClient {
|
|
|
353
358
|
}
|
|
354
359
|
})());
|
|
355
360
|
// eslint-disable-next-line @typescript-eslint/no-array-delete, @typescript-eslint/no-dynamic-delete
|
|
356
|
-
delete this.rpcHandlers[
|
|
361
|
+
delete this.rpcHandlers[requestId];
|
|
357
362
|
}
|
|
358
363
|
};
|
|
359
364
|
// eslint-disable-next-line @typescript-eslint/strict-void-return
|
|
@@ -383,6 +388,89 @@ class WsClient {
|
|
|
383
388
|
this.loginProcedure(this.options);
|
|
384
389
|
}
|
|
385
390
|
}
|
|
391
|
+
workflowsProcedure(options) {
|
|
392
|
+
let workflowsObtained = false;
|
|
393
|
+
this.websocket.addEventListener('open', () => {
|
|
394
|
+
this.options.logDebug('CONNECTED');
|
|
395
|
+
const handleConnectionError = (error) => {
|
|
396
|
+
this.logDebug('FAILURE: couldn\'t retrieve workflows', error.message);
|
|
397
|
+
options.onWorkflowsFailed();
|
|
398
|
+
};
|
|
399
|
+
this.callRpcMethod(undefined, 'workflows').then(response => {
|
|
400
|
+
if (response instanceof Error) {
|
|
401
|
+
handleConnectionError(response);
|
|
402
|
+
return;
|
|
403
|
+
}
|
|
404
|
+
workflowsObtained = true;
|
|
405
|
+
options.onWorkflows(response);
|
|
406
|
+
this.close();
|
|
407
|
+
}).catch(() => {
|
|
408
|
+
options.onWorkflowsFailed();
|
|
409
|
+
});
|
|
410
|
+
});
|
|
411
|
+
this.websocket.addEventListener('close', () => {
|
|
412
|
+
this.logDebug('DISCONNECTED');
|
|
413
|
+
if (!workflowsObtained) {
|
|
414
|
+
options.onWorkflowsFailed();
|
|
415
|
+
}
|
|
416
|
+
});
|
|
417
|
+
}
|
|
418
|
+
loginProcedure(options) {
|
|
419
|
+
this.websocket.addEventListener('open', () => {
|
|
420
|
+
this.options.logDebug('CONNECTED');
|
|
421
|
+
const handleConnectionError = (error) => {
|
|
422
|
+
this.logDebug('FAILURE: couldn\'t perform initial handshake', error.message);
|
|
423
|
+
options.onConnectionFailure(error);
|
|
424
|
+
};
|
|
425
|
+
const handleLoginResponse = (response) => {
|
|
426
|
+
if (response instanceof Error) {
|
|
427
|
+
handleConnectionError(response);
|
|
428
|
+
return;
|
|
429
|
+
}
|
|
430
|
+
this.logDebug('SUCCESS: connected to shv broker');
|
|
431
|
+
options.onConnected();
|
|
432
|
+
this.pingTimerId = setInterval(() => {
|
|
433
|
+
this.sendPing();
|
|
434
|
+
}, options.pingInterval ?? DEFAULT_PING_INTERVAL);
|
|
435
|
+
};
|
|
436
|
+
const makeLoginParams = (loginMap) => (0, rpcvalue_1.makeMap)({
|
|
437
|
+
login: loginMap,
|
|
438
|
+
options: (0, rpcvalue_1.makeMap)({
|
|
439
|
+
device: typeof options.mountPoint === 'string' ? (0, rpcvalue_1.makeMap)({ mountPoint: options.mountPoint }) : undefined,
|
|
440
|
+
}),
|
|
441
|
+
});
|
|
442
|
+
this.callRpcMethod(undefined, 'hello').then(response => {
|
|
443
|
+
if (response instanceof Error) {
|
|
444
|
+
handleConnectionError(response);
|
|
445
|
+
return;
|
|
446
|
+
}
|
|
447
|
+
const makeLoginMap = () => {
|
|
448
|
+
switch (options.login.type) {
|
|
449
|
+
case 'PLAIN':
|
|
450
|
+
return (0, rpcvalue_1.makeMap)({
|
|
451
|
+
password: options.login.password,
|
|
452
|
+
type: options.login.type,
|
|
453
|
+
user: options.login.user,
|
|
454
|
+
});
|
|
455
|
+
case 'TOKEN':
|
|
456
|
+
return (0, rpcvalue_1.makeMap)({
|
|
457
|
+
token: options.login.token,
|
|
458
|
+
type: options.login.type,
|
|
459
|
+
});
|
|
460
|
+
}
|
|
461
|
+
};
|
|
462
|
+
return this.callRpcMethod(undefined, 'login', makeLoginParams(makeLoginMap()));
|
|
463
|
+
}).then(handleLoginResponse).catch(() => {
|
|
464
|
+
this.logDebug('FAILURE: couldn\' connected to shv broker');
|
|
465
|
+
});
|
|
466
|
+
});
|
|
467
|
+
this.websocket.addEventListener('close', () => {
|
|
468
|
+
this.logDebug('DISCONNECTED');
|
|
469
|
+
this.subscriptions.length = 0;
|
|
470
|
+
options.onDisconnected();
|
|
471
|
+
clearInterval(this.pingTimerId);
|
|
472
|
+
});
|
|
473
|
+
}
|
|
386
474
|
callRpcMethod(shvPath, method, params, options) {
|
|
387
475
|
const rqId = this.requestId++;
|
|
388
476
|
const makeRq = (value) => new rpcvalue_1.RpcValueWithMetaData((0, rpcvalue_1.makeMetaMap)({
|
|
@@ -390,7 +478,7 @@ class WsClient {
|
|
|
390
478
|
[rpcmessage_1.RPC_MESSAGE_REQUEST_ID]: rqId,
|
|
391
479
|
[rpcmessage_1.RPC_MESSAGE_METHOD]: method ?? '',
|
|
392
480
|
[rpcmessage_1.RPC_MESSAGE_SHV_PATH]: shvPath ?? '',
|
|
393
|
-
...(options?.requestUserId === true
|
|
481
|
+
...(options?.requestUserId === true && { [rpcmessage_1.RPC_MESSAGE_USER_ID]: '' }),
|
|
394
482
|
}), value);
|
|
395
483
|
let rq = makeRq((0, rpcvalue_1.makeIMap)({
|
|
396
484
|
[rpcmessage_1.RPC_MESSAGE_PARAMS]: params,
|
|
@@ -413,22 +501,23 @@ class WsClient {
|
|
|
413
501
|
return promise;
|
|
414
502
|
}
|
|
415
503
|
sendRpcMessage(rpcMsg) {
|
|
416
|
-
if (this.websocket.readyState
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
dgram[ix++] =
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
504
|
+
if (this.websocket.readyState !== WebSocket.OPEN) {
|
|
505
|
+
return;
|
|
506
|
+
}
|
|
507
|
+
this.logDebug('sending rpc message:', (0, cpon_1.toCpon)(rpcMsg));
|
|
508
|
+
const msgData = new Uint8Array((0, chainpack_1.toChainPack)(rpcMsg));
|
|
509
|
+
const wr = new chainpack_1.ChainPackWriter();
|
|
510
|
+
wr.writeUIntData(msgData.length + 1);
|
|
511
|
+
const dgram = new Uint8Array(wr.ctx.length + 1 + msgData.length);
|
|
512
|
+
let ix = 0;
|
|
513
|
+
for (let i = 0; i < wr.ctx.length; i++) {
|
|
514
|
+
dgram[ix++] = wr.ctx.data[i];
|
|
515
|
+
}
|
|
516
|
+
dgram[ix++] = chainpack_1.CHAINPACK_PROTOCOL_TYPE;
|
|
517
|
+
for (const msgDatum of msgData) {
|
|
518
|
+
dgram[ix++] = msgDatum;
|
|
431
519
|
}
|
|
520
|
+
this.websocket.send(dgram.buffer);
|
|
432
521
|
}
|
|
433
522
|
async getShvApiVersion() {
|
|
434
523
|
if (this.shvApiVersion === undefined) {
|
|
@@ -451,11 +540,11 @@ class WsClient {
|
|
|
451
540
|
const path = ri.path();
|
|
452
541
|
const signal = ri.signal();
|
|
453
542
|
if (this.subscriptions.some(val => val.subscriber === subscriber && val.path === path && val.signal === signal)) {
|
|
454
|
-
this.logDebug(`Already subscribed {
|
|
543
|
+
this.logDebug(`Already subscribed ${path}:${signal} for subscriber ${subscriber}`);
|
|
455
544
|
return;
|
|
456
545
|
}
|
|
457
546
|
// If this path:signal has not been subscribed on the broker, do it now
|
|
458
|
-
if (
|
|
547
|
+
if (this.subscriptions.every(val => !(val.path === path && val.signal === signal))) {
|
|
459
548
|
switch (await this.getShvApiVersion()) {
|
|
460
549
|
case ShvApiVersion.V2: {
|
|
461
550
|
const result = await this.callRpcMethod('.broker/app', 'subscribe', (0, rpcvalue_1.makeMap)({ signal, path }));
|
|
@@ -536,88 +625,5 @@ class WsClient {
|
|
|
536
625
|
}
|
|
537
626
|
this.options.logDebug(...args);
|
|
538
627
|
}
|
|
539
|
-
workflowsProcedure(options) {
|
|
540
|
-
let workflowsObtained = false;
|
|
541
|
-
this.websocket.addEventListener('open', () => {
|
|
542
|
-
this.options.logDebug('CONNECTED');
|
|
543
|
-
const handleConnectionError = (error) => {
|
|
544
|
-
this.logDebug('FAILURE: couldn\'t retrieve workflows', error.message);
|
|
545
|
-
options.onWorkflowsFailed();
|
|
546
|
-
};
|
|
547
|
-
this.callRpcMethod(undefined, 'workflows').then(response => {
|
|
548
|
-
if (response instanceof Error) {
|
|
549
|
-
handleConnectionError(response);
|
|
550
|
-
return;
|
|
551
|
-
}
|
|
552
|
-
workflowsObtained = true;
|
|
553
|
-
options.onWorkflows(response);
|
|
554
|
-
this.close();
|
|
555
|
-
}).catch(() => {
|
|
556
|
-
options.onWorkflowsFailed();
|
|
557
|
-
});
|
|
558
|
-
});
|
|
559
|
-
this.websocket.addEventListener('close', () => {
|
|
560
|
-
this.logDebug('DISCONNECTED');
|
|
561
|
-
if (!workflowsObtained) {
|
|
562
|
-
options.onWorkflowsFailed();
|
|
563
|
-
}
|
|
564
|
-
});
|
|
565
|
-
}
|
|
566
|
-
loginProcedure(options) {
|
|
567
|
-
this.websocket.addEventListener('open', () => {
|
|
568
|
-
this.options.logDebug('CONNECTED');
|
|
569
|
-
const handleConnectionError = (error) => {
|
|
570
|
-
this.logDebug('FAILURE: couldn\'t perform initial handshake', error.message);
|
|
571
|
-
options.onConnectionFailure(error);
|
|
572
|
-
};
|
|
573
|
-
const handleLoginResponse = (response) => {
|
|
574
|
-
if (response instanceof Error) {
|
|
575
|
-
handleConnectionError(response);
|
|
576
|
-
return;
|
|
577
|
-
}
|
|
578
|
-
this.logDebug('SUCCESS: connected to shv broker');
|
|
579
|
-
options.onConnected();
|
|
580
|
-
this.pingTimerId = globalThis.setInterval(() => {
|
|
581
|
-
this.sendPing();
|
|
582
|
-
}, options.pingInterval ?? DEFAULT_PING_INTERVAL);
|
|
583
|
-
};
|
|
584
|
-
const makeLoginParams = (loginMap) => (0, rpcvalue_1.makeMap)({
|
|
585
|
-
login: loginMap,
|
|
586
|
-
options: (0, rpcvalue_1.makeMap)({
|
|
587
|
-
device: typeof options.mountPoint === 'string' ? (0, rpcvalue_1.makeMap)({ mountPoint: options.mountPoint }) : undefined,
|
|
588
|
-
}),
|
|
589
|
-
});
|
|
590
|
-
this.callRpcMethod(undefined, 'hello').then(response => {
|
|
591
|
-
if (response instanceof Error) {
|
|
592
|
-
handleConnectionError(response);
|
|
593
|
-
return;
|
|
594
|
-
}
|
|
595
|
-
const makeLoginMap = () => {
|
|
596
|
-
switch (options.login.type) {
|
|
597
|
-
case 'PLAIN':
|
|
598
|
-
return (0, rpcvalue_1.makeMap)({
|
|
599
|
-
password: options.login.password,
|
|
600
|
-
type: options.login.type,
|
|
601
|
-
user: options.login.user,
|
|
602
|
-
});
|
|
603
|
-
case 'TOKEN':
|
|
604
|
-
return (0, rpcvalue_1.makeMap)({
|
|
605
|
-
token: options.login.token,
|
|
606
|
-
type: options.login.type,
|
|
607
|
-
});
|
|
608
|
-
}
|
|
609
|
-
};
|
|
610
|
-
return this.callRpcMethod(undefined, 'login', makeLoginParams(makeLoginMap()));
|
|
611
|
-
}).then(handleLoginResponse).catch(() => {
|
|
612
|
-
this.logDebug('FAILURE: couldn\' connected to shv broker');
|
|
613
|
-
});
|
|
614
|
-
});
|
|
615
|
-
this.websocket.addEventListener('close', () => {
|
|
616
|
-
this.logDebug('DISCONNECTED');
|
|
617
|
-
this.subscriptions.length = 0;
|
|
618
|
-
options.onDisconnected();
|
|
619
|
-
globalThis.clearInterval(this.pingTimerId);
|
|
620
|
-
});
|
|
621
|
-
}
|
|
622
628
|
}
|
|
623
629
|
exports.WsClient = WsClient;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "libshv-js",
|
|
3
|
-
"version": "7.1.
|
|
3
|
+
"version": "7.1.8",
|
|
4
4
|
"description": "Typescript implementation of libshv",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -40,9 +40,9 @@
|
|
|
40
40
|
"@typescript-eslint/parser": "^8.56.1",
|
|
41
41
|
"@eslint/js": "^10.0.1",
|
|
42
42
|
"eslint": "^10.0.0",
|
|
43
|
-
"eslint-config-xo": "^0.
|
|
43
|
+
"eslint-config-xo": "^0.55.0",
|
|
44
44
|
"eslint-formatter-unix": "^9.0.1",
|
|
45
|
-
"eslint-plugin-unicorn": "^
|
|
45
|
+
"eslint-plugin-unicorn": "^69.0.0",
|
|
46
46
|
"typescript": "^6.0.2",
|
|
47
47
|
"typescript-eslint": "^8.46.1"
|
|
48
48
|
}
|