libshv-js 7.1.6 → 7.1.7
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 +35 -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 +245 -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,36 @@ 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[key] = val;
|
|
96
|
+
}
|
|
97
|
+
else if (map[rpcvalue_1.shvMapType] === 'metamap' && typeof key === 'number') {
|
|
98
|
+
map[key] = val;
|
|
99
|
+
}
|
|
100
|
+
else if (map[rpcvalue_1.shvMapType] === 'map' && typeof key === 'string') {
|
|
101
|
+
map[key] = val;
|
|
102
|
+
}
|
|
103
|
+
else if (map[rpcvalue_1.shvMapType] === 'imap' && typeof key === 'number') {
|
|
104
|
+
map[key] = val;
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
throw new TypeError('Malformed map, invalid key');
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return map;
|
|
111
|
+
}
|
|
82
112
|
/* eslint-disable complexity -- we might simplify this at some point, but it works now */
|
|
83
113
|
read() {
|
|
84
114
|
let meta;
|
|
@@ -285,36 +315,6 @@ class ChainPackReader {
|
|
|
285
315
|
readIMap() {
|
|
286
316
|
return this.implReadMap('imap');
|
|
287
317
|
}
|
|
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
318
|
}
|
|
319
319
|
exports.ChainPackReader = ChainPackReader;
|
|
320
320
|
class ChainPackWriter {
|
|
@@ -426,12 +426,12 @@ class ChainPackWriter {
|
|
|
426
426
|
this.writeUIntDataHelper(BigInt(snum), 'Int');
|
|
427
427
|
}
|
|
428
428
|
writeInt(n) {
|
|
429
|
-
if (
|
|
430
|
-
this.ctx.putByte(
|
|
429
|
+
if (n >= 0 && n < 64) {
|
|
430
|
+
this.ctx.putByte(n + 64);
|
|
431
431
|
return;
|
|
432
432
|
}
|
|
433
433
|
this.ctx.putByte(PackingSchema.Int);
|
|
434
|
-
this.writeIntData(
|
|
434
|
+
this.writeIntData(n);
|
|
435
435
|
}
|
|
436
436
|
writeUInt(n) {
|
|
437
437
|
if (Number(n) < 64) {
|
|
@@ -529,14 +529,14 @@ class ChainPackWriter {
|
|
|
529
529
|
else if (map[rpcvalue_1.shvMapType] === 'metamap') {
|
|
530
530
|
const intKey = Number(key);
|
|
531
531
|
if (Number.isNaN(intKey)) {
|
|
532
|
-
this.writeJSString(key
|
|
532
|
+
this.writeJSString(key);
|
|
533
533
|
}
|
|
534
534
|
else {
|
|
535
535
|
this.writeInt(intKey);
|
|
536
536
|
}
|
|
537
537
|
}
|
|
538
538
|
else {
|
|
539
|
-
this.writeJSString(key
|
|
539
|
+
this.writeJSString(key);
|
|
540
540
|
}
|
|
541
541
|
this.write(value);
|
|
542
542
|
}
|
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,157 @@ 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
|
-
if (
|
|
189
|
-
|
|
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
|
+
// eslint-disable-next-line unicorn/no-computed-property-existence-check
|
|
186
|
+
if (request.value[rpcmessage_1.RPC_MESSAGE_ABORT]) {
|
|
187
|
+
this.abortedRequests.add(requestId);
|
|
188
|
+
if (requestHandler?.options.onAbort !== undefined) {
|
|
189
|
+
requestHandler.options.onAbort();
|
|
191
190
|
}
|
|
191
|
+
}
|
|
192
|
+
// eslint-disable-next-line unicorn/no-computed-property-existence-check
|
|
193
|
+
if (!request.value[rpcmessage_1.RPC_MESSAGE_ABORT] && requestHandler?.options.onProgressQuery !== undefined) {
|
|
194
|
+
const progress = requestHandler.options.onProgressQuery();
|
|
195
|
+
sendDelay(progress instanceof Promise ? await progress : progress);
|
|
196
|
+
}
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
try {
|
|
200
|
+
const shvPath = request.meta[rpcmessage_1.RPC_MESSAGE_SHV_PATH];
|
|
201
|
+
const methodName = request.meta[rpcmessage_1.RPC_MESSAGE_METHOD];
|
|
202
|
+
const unhandledMethod = () => {
|
|
203
|
+
throw new exports.MethodNotFound(`No such path '${shvPath}' or method '${methodName}' or insufficient access rights.`);
|
|
204
|
+
};
|
|
205
|
+
const accessLevel = request.meta[rpcmessage_1.RPC_MESSAGE_ACCESS_LEVEL];
|
|
206
|
+
if (accessLevel === undefined) {
|
|
207
|
+
unhandledMethod();
|
|
192
208
|
return;
|
|
193
209
|
}
|
|
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
|
-
}
|
|
210
|
+
const methods = this.options.onRequest(shvPath);
|
|
211
|
+
if (methods === undefined) {
|
|
212
|
+
unhandledMethod();
|
|
213
|
+
return;
|
|
287
214
|
}
|
|
288
|
-
|
|
289
|
-
const
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
215
|
+
const methodDefinition = (() => {
|
|
216
|
+
const dirEntry = (0, rpcvalue_1.makeIMap)({
|
|
217
|
+
[exports.DIR_NAME]: 'dir',
|
|
218
|
+
[exports.DIR_FLAGS]: 0,
|
|
219
|
+
[exports.DIR_PARAM]: 'DirParam',
|
|
220
|
+
[exports.DIR_RESULT]: 'DirResult',
|
|
221
|
+
[exports.DIR_ACCESS]: (0, access_1.accessLevelFromAccessString)('bws'),
|
|
222
|
+
[exports.DIR_SIGNALS]: (0, rpcvalue_1.makeMap)({}),
|
|
223
|
+
[exports.DIR_EXTRA]: (0, rpcvalue_1.makeMap)({}),
|
|
224
|
+
});
|
|
225
|
+
const lsEntry = (0, rpcvalue_1.makeIMap)({
|
|
226
|
+
[exports.DIR_NAME]: 'ls',
|
|
227
|
+
[exports.DIR_FLAGS]: 0,
|
|
228
|
+
[exports.DIR_PARAM]: 'LsParam',
|
|
229
|
+
[exports.DIR_RESULT]: 'LsResult',
|
|
230
|
+
[exports.DIR_ACCESS]: (0, access_1.accessLevelFromAccessString)('bws'),
|
|
231
|
+
[exports.DIR_SIGNALS]: (0, rpcvalue_1.makeMap)({}),
|
|
232
|
+
[exports.DIR_EXTRA]: (0, rpcvalue_1.makeMap)({}),
|
|
233
|
+
});
|
|
234
|
+
switch (methodName) {
|
|
235
|
+
case 'dir':
|
|
236
|
+
return {
|
|
237
|
+
entry: dirEntry,
|
|
238
|
+
paramValidator: exports.validateDirParam,
|
|
239
|
+
handler(_shvPath, _method, param) {
|
|
240
|
+
const methodsResult = [dirEntry, lsEntry, ...methods.dirEntries.map(method => method.entry)];
|
|
241
|
+
switch (true) {
|
|
242
|
+
case typeof param === 'string':
|
|
243
|
+
return methodsResult.find(method => method[exports.DIR_NAME] === param) ?? false;
|
|
244
|
+
case typeof param === 'boolean':
|
|
245
|
+
case param === undefined:
|
|
246
|
+
console.log('methodsResult', '=', methodsResult);
|
|
247
|
+
return methodsResult;
|
|
248
|
+
}
|
|
249
|
+
},
|
|
250
|
+
};
|
|
251
|
+
case 'ls':
|
|
252
|
+
return {
|
|
253
|
+
entry: lsEntry,
|
|
254
|
+
paramValidator: exports.validateLsParam,
|
|
255
|
+
handler(shvPath) {
|
|
256
|
+
return methods.ls(shvPath);
|
|
257
|
+
},
|
|
258
|
+
};
|
|
301
259
|
default:
|
|
302
|
-
|
|
303
|
-
break;
|
|
260
|
+
return methods.dirEntries.find(method => method.entry[exports.DIR_NAME] === methodName);
|
|
304
261
|
}
|
|
262
|
+
})();
|
|
263
|
+
if (methodDefinition === undefined) {
|
|
264
|
+
unhandledMethod();
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
if (accessLevel < methodDefinition.entry[exports.DIR_ACCESS]) {
|
|
268
|
+
unhandledMethod();
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
const requestParam = request.value[rpcmessage_1.RPC_MESSAGE_PARAMS];
|
|
272
|
+
if (methodDefinition.paramValidator !== undefined && !methodDefinition.paramValidator(requestParam)) {
|
|
273
|
+
throw new exports.InvalidParams(`Unexpected param '${shvPath}:${methodName}': ${(0, cpon_1.toCpon)(requestParam)}`);
|
|
274
|
+
}
|
|
275
|
+
let result = methodDefinition.handler(shvPath, methodName, requestParam, sendDelay);
|
|
276
|
+
if (result instanceof RequestHandler) {
|
|
277
|
+
this.requestHandlers.set(requestId, result);
|
|
278
|
+
result = result.options.result;
|
|
279
|
+
}
|
|
280
|
+
const resultOrError = (0, rpcvalue_1.makeIMap)({
|
|
281
|
+
[rpcmessage_1.RPC_MESSAGE_RESULT]: result instanceof Promise ? await result : result,
|
|
282
|
+
});
|
|
283
|
+
if (!this.abortedRequests.has(requestId)) {
|
|
284
|
+
respond(resultOrError);
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
this.abortedRequests.delete(requestId);
|
|
288
|
+
}
|
|
289
|
+
if (this.requestHandlers.has(requestId)) {
|
|
290
|
+
this.requestHandlers.delete(requestId);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
catch (error) {
|
|
294
|
+
const sendError = (error) => {
|
|
295
|
+
respond((0, rpcvalue_1.makeIMap)({
|
|
296
|
+
[rpcmessage_1.RPC_MESSAGE_ERROR]: error.err_info,
|
|
297
|
+
}));
|
|
298
|
+
};
|
|
299
|
+
switch (true) {
|
|
300
|
+
case error instanceof RpcError:
|
|
301
|
+
sendError(error);
|
|
302
|
+
break;
|
|
303
|
+
case error instanceof Error:
|
|
304
|
+
sendError(new exports.InternalError(error.message));
|
|
305
|
+
break;
|
|
306
|
+
default:
|
|
307
|
+
sendError(new exports.InternalError('Unknown error'));
|
|
308
|
+
break;
|
|
305
309
|
}
|
|
306
310
|
}
|
|
307
311
|
};
|
|
308
312
|
const handleResponse = (response) => {
|
|
309
313
|
const requestId = response.meta[rpcmessage_1.RPC_MESSAGE_REQUEST_ID];
|
|
310
|
-
if (this.rpcHandlers[
|
|
311
|
-
const handler = this.rpcHandlers[
|
|
314
|
+
if (this.rpcHandlers[requestId] !== undefined) {
|
|
315
|
+
const handler = this.rpcHandlers[requestId];
|
|
312
316
|
clearTimeout(handler.timeout_handle);
|
|
317
|
+
// eslint-disable-next-line unicorn/no-computed-property-existence-check
|
|
313
318
|
if (rpcmessage_1.RPC_MESSAGE_DELAY in response.value) {
|
|
314
319
|
if (handler.delayCallback !== undefined) {
|
|
315
320
|
handler.delayCallback(response.value[rpcmessage_1.RPC_MESSAGE_DELAY].value);
|
|
@@ -318,6 +323,7 @@ class WsClient {
|
|
|
318
323
|
return;
|
|
319
324
|
}
|
|
320
325
|
handler.resolve((() => {
|
|
326
|
+
// eslint-disable-next-line unicorn/no-computed-property-existence-check
|
|
321
327
|
if (rpcmessage_1.RPC_MESSAGE_ERROR in response.value) {
|
|
322
328
|
const code = response.value[rpcmessage_1.RPC_MESSAGE_ERROR][rpcmessage_1.ERROR_CODE];
|
|
323
329
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
@@ -340,6 +346,7 @@ class WsClient {
|
|
|
340
346
|
})();
|
|
341
347
|
return new ErrorTypeCtor(response.value[rpcmessage_1.RPC_MESSAGE_ERROR]);
|
|
342
348
|
}
|
|
349
|
+
// eslint-disable-next-line unicorn/no-computed-property-existence-check
|
|
343
350
|
if (rpcmessage_1.RPC_MESSAGE_RESULT in response.value) {
|
|
344
351
|
return response.value[rpcmessage_1.RPC_MESSAGE_RESULT];
|
|
345
352
|
}
|
|
@@ -353,7 +360,7 @@ class WsClient {
|
|
|
353
360
|
}
|
|
354
361
|
})());
|
|
355
362
|
// eslint-disable-next-line @typescript-eslint/no-array-delete, @typescript-eslint/no-dynamic-delete
|
|
356
|
-
delete this.rpcHandlers[
|
|
363
|
+
delete this.rpcHandlers[requestId];
|
|
357
364
|
}
|
|
358
365
|
};
|
|
359
366
|
// eslint-disable-next-line @typescript-eslint/strict-void-return
|
|
@@ -383,6 +390,89 @@ class WsClient {
|
|
|
383
390
|
this.loginProcedure(this.options);
|
|
384
391
|
}
|
|
385
392
|
}
|
|
393
|
+
workflowsProcedure(options) {
|
|
394
|
+
let workflowsObtained = false;
|
|
395
|
+
this.websocket.addEventListener('open', () => {
|
|
396
|
+
this.options.logDebug('CONNECTED');
|
|
397
|
+
const handleConnectionError = (error) => {
|
|
398
|
+
this.logDebug('FAILURE: couldn\'t retrieve workflows', error.message);
|
|
399
|
+
options.onWorkflowsFailed();
|
|
400
|
+
};
|
|
401
|
+
this.callRpcMethod(undefined, 'workflows').then(response => {
|
|
402
|
+
if (response instanceof Error) {
|
|
403
|
+
handleConnectionError(response);
|
|
404
|
+
return;
|
|
405
|
+
}
|
|
406
|
+
workflowsObtained = true;
|
|
407
|
+
options.onWorkflows(response);
|
|
408
|
+
this.close();
|
|
409
|
+
}).catch(() => {
|
|
410
|
+
options.onWorkflowsFailed();
|
|
411
|
+
});
|
|
412
|
+
});
|
|
413
|
+
this.websocket.addEventListener('close', () => {
|
|
414
|
+
this.logDebug('DISCONNECTED');
|
|
415
|
+
if (!workflowsObtained) {
|
|
416
|
+
options.onWorkflowsFailed();
|
|
417
|
+
}
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
loginProcedure(options) {
|
|
421
|
+
this.websocket.addEventListener('open', () => {
|
|
422
|
+
this.options.logDebug('CONNECTED');
|
|
423
|
+
const handleConnectionError = (error) => {
|
|
424
|
+
this.logDebug('FAILURE: couldn\'t perform initial handshake', error.message);
|
|
425
|
+
options.onConnectionFailure(error);
|
|
426
|
+
};
|
|
427
|
+
const handleLoginResponse = (response) => {
|
|
428
|
+
if (response instanceof Error) {
|
|
429
|
+
handleConnectionError(response);
|
|
430
|
+
return;
|
|
431
|
+
}
|
|
432
|
+
this.logDebug('SUCCESS: connected to shv broker');
|
|
433
|
+
options.onConnected();
|
|
434
|
+
this.pingTimerId = setInterval(() => {
|
|
435
|
+
this.sendPing();
|
|
436
|
+
}, options.pingInterval ?? DEFAULT_PING_INTERVAL);
|
|
437
|
+
};
|
|
438
|
+
const makeLoginParams = (loginMap) => (0, rpcvalue_1.makeMap)({
|
|
439
|
+
login: loginMap,
|
|
440
|
+
options: (0, rpcvalue_1.makeMap)({
|
|
441
|
+
device: typeof options.mountPoint === 'string' ? (0, rpcvalue_1.makeMap)({ mountPoint: options.mountPoint }) : undefined,
|
|
442
|
+
}),
|
|
443
|
+
});
|
|
444
|
+
this.callRpcMethod(undefined, 'hello').then(response => {
|
|
445
|
+
if (response instanceof Error) {
|
|
446
|
+
handleConnectionError(response);
|
|
447
|
+
return;
|
|
448
|
+
}
|
|
449
|
+
const makeLoginMap = () => {
|
|
450
|
+
switch (options.login.type) {
|
|
451
|
+
case 'PLAIN':
|
|
452
|
+
return (0, rpcvalue_1.makeMap)({
|
|
453
|
+
password: options.login.password,
|
|
454
|
+
type: options.login.type,
|
|
455
|
+
user: options.login.user,
|
|
456
|
+
});
|
|
457
|
+
case 'TOKEN':
|
|
458
|
+
return (0, rpcvalue_1.makeMap)({
|
|
459
|
+
token: options.login.token,
|
|
460
|
+
type: options.login.type,
|
|
461
|
+
});
|
|
462
|
+
}
|
|
463
|
+
};
|
|
464
|
+
return this.callRpcMethod(undefined, 'login', makeLoginParams(makeLoginMap()));
|
|
465
|
+
}).then(handleLoginResponse).catch(() => {
|
|
466
|
+
this.logDebug('FAILURE: couldn\' connected to shv broker');
|
|
467
|
+
});
|
|
468
|
+
});
|
|
469
|
+
this.websocket.addEventListener('close', () => {
|
|
470
|
+
this.logDebug('DISCONNECTED');
|
|
471
|
+
this.subscriptions.length = 0;
|
|
472
|
+
options.onDisconnected();
|
|
473
|
+
clearInterval(this.pingTimerId);
|
|
474
|
+
});
|
|
475
|
+
}
|
|
386
476
|
callRpcMethod(shvPath, method, params, options) {
|
|
387
477
|
const rqId = this.requestId++;
|
|
388
478
|
const makeRq = (value) => new rpcvalue_1.RpcValueWithMetaData((0, rpcvalue_1.makeMetaMap)({
|
|
@@ -390,7 +480,7 @@ class WsClient {
|
|
|
390
480
|
[rpcmessage_1.RPC_MESSAGE_REQUEST_ID]: rqId,
|
|
391
481
|
[rpcmessage_1.RPC_MESSAGE_METHOD]: method ?? '',
|
|
392
482
|
[rpcmessage_1.RPC_MESSAGE_SHV_PATH]: shvPath ?? '',
|
|
393
|
-
...(options?.requestUserId === true
|
|
483
|
+
...(options?.requestUserId === true && { [rpcmessage_1.RPC_MESSAGE_USER_ID]: '' }),
|
|
394
484
|
}), value);
|
|
395
485
|
let rq = makeRq((0, rpcvalue_1.makeIMap)({
|
|
396
486
|
[rpcmessage_1.RPC_MESSAGE_PARAMS]: params,
|
|
@@ -413,22 +503,23 @@ class WsClient {
|
|
|
413
503
|
return promise;
|
|
414
504
|
}
|
|
415
505
|
sendRpcMessage(rpcMsg) {
|
|
416
|
-
if (this.websocket.readyState
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
dgram[ix++] =
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
506
|
+
if (this.websocket.readyState !== WebSocket.OPEN) {
|
|
507
|
+
return;
|
|
508
|
+
}
|
|
509
|
+
this.logDebug('sending rpc message:', (0, cpon_1.toCpon)(rpcMsg));
|
|
510
|
+
const msgData = new Uint8Array((0, chainpack_1.toChainPack)(rpcMsg));
|
|
511
|
+
const wr = new chainpack_1.ChainPackWriter();
|
|
512
|
+
wr.writeUIntData(msgData.length + 1);
|
|
513
|
+
const dgram = new Uint8Array(wr.ctx.length + 1 + msgData.length);
|
|
514
|
+
let ix = 0;
|
|
515
|
+
for (let i = 0; i < wr.ctx.length; i++) {
|
|
516
|
+
dgram[ix++] = wr.ctx.data[i];
|
|
517
|
+
}
|
|
518
|
+
dgram[ix++] = chainpack_1.CHAINPACK_PROTOCOL_TYPE;
|
|
519
|
+
for (const msgDatum of msgData) {
|
|
520
|
+
dgram[ix++] = msgDatum;
|
|
431
521
|
}
|
|
522
|
+
this.websocket.send(dgram.buffer);
|
|
432
523
|
}
|
|
433
524
|
async getShvApiVersion() {
|
|
434
525
|
if (this.shvApiVersion === undefined) {
|
|
@@ -451,11 +542,11 @@ class WsClient {
|
|
|
451
542
|
const path = ri.path();
|
|
452
543
|
const signal = ri.signal();
|
|
453
544
|
if (this.subscriptions.some(val => val.subscriber === subscriber && val.path === path && val.signal === signal)) {
|
|
454
|
-
this.logDebug(`Already subscribed {
|
|
545
|
+
this.logDebug(`Already subscribed ${path}:${signal} for subscriber ${subscriber}`);
|
|
455
546
|
return;
|
|
456
547
|
}
|
|
457
548
|
// If this path:signal has not been subscribed on the broker, do it now
|
|
458
|
-
if (
|
|
549
|
+
if (this.subscriptions.every(val => !(val.path === path && val.signal === signal))) {
|
|
459
550
|
switch (await this.getShvApiVersion()) {
|
|
460
551
|
case ShvApiVersion.V2: {
|
|
461
552
|
const result = await this.callRpcMethod('.broker/app', 'subscribe', (0, rpcvalue_1.makeMap)({ signal, path }));
|
|
@@ -536,88 +627,5 @@ class WsClient {
|
|
|
536
627
|
}
|
|
537
628
|
this.options.logDebug(...args);
|
|
538
629
|
}
|
|
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
630
|
}
|
|
623
631
|
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.7",
|
|
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.53.2",
|
|
44
44
|
"eslint-formatter-unix": "^9.0.1",
|
|
45
|
-
"eslint-plugin-unicorn": "^
|
|
45
|
+
"eslint-plugin-unicorn": "^68.0.0",
|
|
46
46
|
"typescript": "^6.0.2",
|
|
47
47
|
"typescript-eslint": "^8.46.1"
|
|
48
48
|
}
|