libshv-js 3.6.0 → 3.6.2

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.
@@ -14,9 +14,9 @@ on:
14
14
  jobs:
15
15
  check-version-bump:
16
16
  name: Check version bump
17
- runs-on: ubuntu-22.04
17
+ runs-on: ubuntu-latest
18
18
  steps:
19
- - uses: actions/checkout@v3
19
+ - uses: actions/checkout@v4
20
20
  - name: Check if version bumped
21
- uses: del-systems/check-if-version-bumped@v2.0.3
21
+ uses: del-systems/check-if-version-bumped@v2
22
22
 
@@ -14,9 +14,9 @@ on:
14
14
  jobs:
15
15
  type-check:
16
16
  name: Type check
17
- runs-on: ubuntu-22.04
17
+ runs-on: ubuntu-latest
18
18
  steps:
19
- - uses: actions/checkout@v3
19
+ - uses: actions/checkout@v4
20
20
  - name: Install tsc
21
21
  run: npm install
22
22
  - name: Run tsc
@@ -24,9 +24,9 @@ jobs:
24
24
 
25
25
  xo:
26
26
  name: xo
27
- runs-on: ubuntu-22.04
27
+ runs-on: ubuntu-latest
28
28
  steps:
29
- - uses: actions/checkout@v3
29
+ - uses: actions/checkout@v4
30
30
  - name: Install tsc
31
31
  run: npm install
32
32
  - name: Run linters
@@ -8,14 +8,14 @@ on:
8
8
  jobs:
9
9
  test:
10
10
  name: Publish new version
11
- runs-on: ubuntu-22.04
11
+ runs-on: ubuntu-latest
12
12
  steps:
13
- - uses: actions/checkout@v3
13
+ - uses: actions/checkout@v4
14
14
 
15
15
  - name: Setup node
16
16
  uses: actions/setup-node@v4
17
17
  with:
18
- node-version: '20.x'
18
+ node-version: '22.x'
19
19
  registry-url: 'https://registry.npmjs.org'
20
20
 
21
21
  - name: Publish
@@ -14,7 +14,7 @@ on:
14
14
  jobs:
15
15
  test:
16
16
  name: CPON/Chainpack conversions
17
- runs-on: ubuntu-22.04
17
+ runs-on: ubuntu-latest
18
18
  steps:
19
19
  - uses: actions/checkout@v4
20
20
 
@@ -0,0 +1,102 @@
1
+ import xo from "eslint-config-xo";
2
+ import typescriptEslintParser from "@typescript-eslint/parser";
3
+ import eslint from '@eslint/js';
4
+ import tseslint from 'typescript-eslint';
5
+ import unicornPlugin from 'eslint-plugin-unicorn';
6
+
7
+ export default tseslint.config(
8
+ eslint.configs.recommended,
9
+ eslint.configs.recommended,
10
+ ...tseslint.configs.recommendedTypeChecked,
11
+ ...tseslint.configs.stylisticTypeChecked,
12
+ unicornPlugin.configs.recommended,
13
+ ...xo,
14
+ {
15
+ languageOptions: {
16
+ parser: typescriptEslintParser,
17
+ parserOptions: {
18
+ project: "./tsconfig.json",
19
+ },
20
+ },
21
+ rules: {
22
+ "@stylistic/indent": ["error", 4],
23
+ "@stylistic/indent-binary-ops": ["error", 4],
24
+ "@stylistic/max-len": ["off"],
25
+ "@stylistic/multiline-ternary": ["off"],
26
+ "@stylistic/function-paren-newline": ["off"],
27
+ "@typescript-eslint/no-misused-promises": ["error", {
28
+ checksVoidReturn: false
29
+ }],
30
+ "@typescript-eslint/no-unsafe-assignment": ["off"],
31
+ "@typescript-eslint/no-unsafe-call": ["off"],
32
+ "@typescript-eslint/no-unsafe-enum-comparison": ["off"],
33
+ "@typescript-eslint/consistent-type-definitions": ["error",
34
+ "type"
35
+ ],
36
+ "@typescript-eslint/array-type": ["error", {
37
+ default: "array-simple"
38
+ }],
39
+ "@typescript-eslint/naming-convention": ["error",
40
+ {
41
+ "selector": "variableLike",
42
+ "format": ["camelCase"]
43
+ },
44
+ {
45
+ "selector": "variableLike",
46
+ "format": null,
47
+ "modifiers": ["unused"]
48
+ },
49
+ {
50
+ "format": ["camelCase", "UPPER_CASE"],
51
+ "selector": "variable",
52
+ "modifiers": ["const"]
53
+ },
54
+ {
55
+ "format": ["PascalCase"],
56
+ "selector": "variable",
57
+ "modifiers": ["const"],
58
+ "filter": "Validation$|Zod$"
59
+ }
60
+ ],
61
+ "@typescript-eslint/prefer-promise-reject-errors": "off",
62
+ "@typescript-eslint/promise-function-async": "off",
63
+ "@typescript-eslint/strict-boolean-expressions": ["error",
64
+ {
65
+ "allowString": false,
66
+ "allowNumber": false,
67
+ "allowNullableObject": false
68
+ }
69
+ ],
70
+ "@typescript-eslint/triple-slash-reference": "off",
71
+ "capitalized-comments": "off",
72
+ "@stylistic/object-curly-newline": ["error", {
73
+ "ImportDeclaration": "never"
74
+ }],
75
+ "n/file-extension-in-import": "off",
76
+ "promise-function-async": "off",
77
+ "camelcase": "off",
78
+ "default-case": "off",
79
+ "import/extensions": "off",
80
+ "import/no-unassigned-import": "off",
81
+ "no-dupe-class-members": "off",
82
+ "no-negated-condition": "off",
83
+ "no-unused-vars": "off",
84
+ "no-useless-constructor": "off",
85
+ "no-void": ["error", {
86
+ allowAsStatement: true
87
+ }],
88
+ "no-warning-comments": "off",
89
+ "prefer-promise-reject-errors": "off",
90
+ "unicorn/consistent-function-scoping": "off",
91
+ "unicorn/explicit-length-check": "off",
92
+ "unicorn/filename-case": "off",
93
+ "unicorn/no-negated-condition": "off",
94
+ "unicorn/no-useless-undefined": ["error", {
95
+ checkArguments: false
96
+ }],
97
+ "unicorn/prefer-top-level-await": "off",
98
+ "unicorn/switch-case-braces": "off",
99
+ "unicorn/prevent-abbreviations": "off",
100
+ }
101
+ }
102
+ );
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "libshv-js",
3
- "version": "3.6.0",
3
+ "version": "3.6.2",
4
4
  "description": "Typescript implementation of libshv",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1",
7
- "lint": "xo --reporter unix test.ts src/* --extension=vue",
7
+ "lint": "eslint --format unix src/",
8
8
  "fix": "npm run lint -- --fix"
9
9
  },
10
10
  "author": "Elektroline",
@@ -28,10 +28,15 @@
28
28
  "./zod.ts": "./src/zod.ts"
29
29
  },
30
30
  "dependencies": {
31
- "zod": "^3.23.8"
31
+ "zod": "^3.24.2"
32
32
  },
33
33
  "devDependencies": {
34
- "typescript": "^5.5.4",
35
- "xo": "^0.59.3"
34
+ "@typescript-eslint/parser": "^8.27.0",
35
+ "eslint": "^9.22.0",
36
+ "eslint-config-xo": "^0.46.0",
37
+ "eslint-formatter-unix": "^8.40.0",
38
+ "eslint-plugin-unicorn": "^57.0.0",
39
+ "typescript": "^5.8.2",
40
+ "typescript-eslint": "^8.27.0"
36
41
  }
37
42
  }
package/src/chainpack.ts CHANGED
@@ -85,7 +85,7 @@ const significantBitsCount = (num: bigint) => {
85
85
  class ChainPackReader {
86
86
  ctx: UnpackContext;
87
87
 
88
- constructor(data: ArrayBuffer | Uint8Array | UnpackContext) {
88
+ constructor(data: ArrayBuffer | UnpackContext) {
89
89
  this.ctx = data instanceof UnpackContext ? data : new UnpackContext(data);
90
90
  }
91
91
 
@@ -155,9 +155,9 @@ class ChainPackReader {
155
155
  bi >>= 2n;
156
156
 
157
157
  let offset = 0;
158
- if (hasTzOffset) {
158
+ if (hasTzOffset !== 0n) {
159
159
  offset = Number(bi & 0x7Fn);
160
- if (offset & 0x40) {
160
+ if ((offset & 0x40) !== 0) {
161
161
  // sign extension
162
162
  offset -= 128;
163
163
  }
@@ -172,7 +172,7 @@ class ChainPackReader {
172
172
  }
173
173
 
174
174
  let msec = Number(bi);
175
- if (hasNotMsec) {
175
+ if (hasNotMsec !== 0n) {
176
176
  msec *= 1000;
177
177
  }
178
178
 
@@ -216,7 +216,6 @@ class ChainPackReader {
216
216
  case PackingSchema.CString: {
217
217
  // variation of CponReader.readCString()
218
218
  const pctx = new PackContext();
219
- // eslint-disable-next-line no-constant-condition
220
219
  while (true) {
221
220
  let b = this.ctx.getByte();
222
221
  if (b === '\\'.codePointAt(0)) {
@@ -317,7 +316,6 @@ class ChainPackReader {
317
316
 
318
317
  readList() {
319
318
  const lst = [];
320
- // eslint-disable-next-line no-constant-condition
321
319
  while (true) {
322
320
  const b = this.ctx.peekByte();
323
321
  if (b as PackingSchema === PackingSchema.Term) {
@@ -343,14 +341,13 @@ class ChainPackReader {
343
341
  return this.implReadMap('imap');
344
342
  }
345
343
 
346
- private implReadMap(map_type: 'map'): ShvMap;
347
- private implReadMap(map_type: 'imap'): IMap;
348
- private implReadMap(map_type: 'metamap'): MetaMap;
349
- private implReadMap(map_type: 'map' | 'imap' | 'metamap') {
344
+ private implReadMap(mapType: 'map'): ShvMap;
345
+ private implReadMap(mapType: 'imap'): IMap;
346
+ private implReadMap(mapType: 'metamap'): MetaMap;
347
+ private implReadMap(mapType: 'map' | 'imap' | 'metamap') {
350
348
  const map: ShvMap | IMap | MetaMap = {
351
- [shvMapType]: map_type,
349
+ [shvMapType]: mapType,
352
350
  };
353
- // eslint-disable-next-line no-constant-condition
354
351
  while (true) {
355
352
  const b = this.ctx.peekByte();
356
353
  if (b as PackingSchema === PackingSchema.Term) {
@@ -384,55 +381,55 @@ class ChainPackWriter {
384
381
  this.ctx = new PackContext();
385
382
  }
386
383
 
387
- write(rpc_val: RpcValue) {
388
- if (rpc_val instanceof RpcValueWithMetaData) {
389
- this.writeMeta(rpc_val.meta);
390
- rpc_val = rpc_val.value;
384
+ write(rpcVal: RpcValue) {
385
+ if (rpcVal instanceof RpcValueWithMetaData) {
386
+ this.writeMeta(rpcVal.meta);
387
+ rpcVal = rpcVal.value;
391
388
  }
392
389
 
393
390
  switch (true) {
394
- case rpc_val === undefined:
391
+ case rpcVal === undefined:
395
392
  this.ctx.putByte(PackingSchema.Null);
396
393
  break;
397
- case typeof rpc_val === 'boolean':
398
- this.ctx.putByte(rpc_val ? PackingSchema.True : PackingSchema.False);
394
+ case typeof rpcVal === 'boolean':
395
+ this.ctx.putByte(rpcVal ? PackingSchema.True : PackingSchema.False);
399
396
  break;
400
- case typeof rpc_val === 'string':
401
- this.writeJSString(rpc_val);
397
+ case typeof rpcVal === 'string':
398
+ this.writeJSString(rpcVal);
402
399
  break;
403
- case rpc_val instanceof ArrayBuffer:
404
- this.writeBlob(rpc_val);
400
+ case rpcVal instanceof ArrayBuffer:
401
+ this.writeBlob(rpcVal);
405
402
  break;
406
- case rpc_val instanceof UInt:
407
- this.writeUInt(rpc_val);
403
+ case rpcVal instanceof UInt:
404
+ this.writeUInt(rpcVal);
408
405
  break;
409
- case typeof rpc_val === 'number':
410
- this.writeInt(rpc_val);
406
+ case typeof rpcVal === 'number':
407
+ this.writeInt(rpcVal);
411
408
  break;
412
- case rpc_val instanceof Decimal:
413
- this.writeDecimal(rpc_val);
409
+ case rpcVal instanceof Decimal:
410
+ this.writeDecimal(rpcVal);
414
411
  break;
415
- case Array.isArray(rpc_val):
416
- this.writeList(rpc_val);
412
+ case Array.isArray(rpcVal):
413
+ this.writeList(rpcVal);
417
414
  break;
418
- case rpc_val instanceof Date:
419
- this.writeDateTime(rpc_val);
415
+ case rpcVal instanceof Date:
416
+ this.writeDateTime(rpcVal);
420
417
  break;
421
- case rpc_val instanceof Double:
418
+ case rpcVal instanceof Double:
422
419
  throw new Error('writing doubles not implemented');
423
- case typeof rpc_val === 'object':
424
- switch (rpc_val[shvMapType]) {
420
+ case typeof rpcVal === 'object':
421
+ switch (rpcVal[shvMapType]) {
425
422
  case 'imap':
426
- this.writeIMap(rpc_val);
423
+ this.writeIMap(rpcVal);
427
424
  break;
428
425
  case 'map':
429
- this.writeMap(rpc_val);
426
+ this.writeMap(rpcVal);
430
427
  break;
431
428
  }
432
429
 
433
430
  break;
434
431
  default:
435
- console.log('Can\'t serialize', rpc_val);
432
+ console.log('Can\'t serialize', rpcVal);
436
433
  throw new Error('Can\'t serialize');
437
434
  }
438
435
  }
package/src/cpcontext.ts CHANGED
@@ -2,7 +2,7 @@ class UnpackContext {
2
2
  index: number;
3
3
  private readonly data: Uint8Array;
4
4
 
5
- constructor(buf: ArrayBuffer) {
5
+ constructor(buf: ArrayBufferLike) {
6
6
  this.data = new Uint8Array(buf);
7
7
  this.index = 0;
8
8
  }
@@ -45,7 +45,6 @@ const transfer = (source: ArrayBuffer, length: number) => {
45
45
 
46
46
  class PackContext {
47
47
  static CHUNK_LEN = 1024;
48
-
49
48
  data = new Uint8Array(0);
50
49
  length = 0;
51
50
 
package/src/cpon.ts CHANGED
@@ -7,7 +7,7 @@ export const stringifyDate = (dt: DateTime) => {
7
7
  let utcOffset = dt.utc_offset;
8
8
  const localMsec = epochMsec + (60_000 * (utcOffset ?? 0));
9
9
  let res = new Date(localMsec).toISOString();
10
- const rtrim = (localMsec % 1000) ? 1 : 5;
10
+ const rtrim = ((localMsec % 1000) !== 0) ? 1 : 5;
11
11
  res = res.slice(0, Math.max(0, res.length - rtrim));
12
12
 
13
13
  if (utcOffset === undefined || utcOffset === 0) {
@@ -21,7 +21,7 @@ export const stringifyDate = (dt: DateTime) => {
21
21
  }
22
22
 
23
23
  res += (Math.trunc(utcOffset / 60)).toString().padStart(2, '0');
24
- if (utcOffset % 60) {
24
+ if ((utcOffset % 60) !== 0) {
25
25
  res += (utcOffset % 60).toString().padStart(2, '0');
26
26
  }
27
27
  }
@@ -85,8 +85,9 @@ const utf8ToString = (bytearray: ArrayBuffer) => {
85
85
 
86
86
  class CponReader {
87
87
  ctx: UnpackContext;
88
- constructor(unpack_context: UnpackContext) {
89
- this.ctx = unpack_context;
88
+
89
+ constructor(unpackContext: UnpackContext) {
90
+ this.ctx = unpackContext;
90
91
  }
91
92
 
92
93
  read(): RpcValue {
@@ -188,7 +189,6 @@ class CponReader {
188
189
  const KEY_DELIM = ':'.codePointAt(0)!;
189
190
  const FIELD_DELIM = ','.codePointAt(0)!;
190
191
  /* eslint-disable max-depth */
191
- // eslint-disable-next-line no-constant-condition
192
192
  while (true) {
193
193
  let b = this.ctx.peekByte();
194
194
  if (b < 1) {
@@ -202,7 +202,6 @@ class CponReader {
202
202
  b = this.ctx.getByte();
203
203
  if (b === STAR) {
204
204
  // multiline_comment_entered;
205
- // eslint-disable-next-line no-constant-condition
206
205
  while (true) {
207
206
  b = this.ctx.getByte();
208
207
  if (b === STAR) {
@@ -214,7 +213,6 @@ class CponReader {
214
213
  }
215
214
  } else if (b === SLASH) {
216
215
  // to end of line comment entered;
217
- // eslint-disable-next-line no-constant-condition
218
216
  while (true) {
219
217
  b = this.ctx.getByte();
220
218
  if (b === LF) {
@@ -354,7 +352,6 @@ class CponReader {
354
352
  readCString() {
355
353
  const pctx = new PackContext();
356
354
  this.ctx.getByte(); // eat '"'
357
- // eslint-disable-next-line no-constant-condition
358
355
  while (true) {
359
356
  let b = this.ctx.getByte();
360
357
  if (b === '\\'.codePointAt(0)) {
@@ -402,7 +399,6 @@ class CponReader {
402
399
  readBlobEsc() {
403
400
  const pctx = new PackContext();
404
401
  this.ctx.getByte(); // eat '"'
405
- // eslint-disable-next-line no-constant-condition
406
402
  while (true) {
407
403
  let b = this.ctx.getByte();
408
404
  if (b === '\\'.codePointAt(0)) {
@@ -445,7 +441,6 @@ class CponReader {
445
441
  readBlobHex() {
446
442
  const pctx = new PackContext();
447
443
  this.ctx.getByte(); // eat '"'
448
- // eslint-disable-next-line no-constant-condition
449
444
  while (true) {
450
445
  const b = this.ctx.getByte();
451
446
  if (b === '"'.codePointAt(0)) {
@@ -463,7 +458,6 @@ class CponReader {
463
458
  readList() {
464
459
  const lst = [];
465
460
  this.ctx.getByte(); // eat '['
466
- // eslint-disable-next-line no-constant-condition
467
461
  while (true) {
468
462
  this.skipWhitespace();
469
463
  const b = this.ctx.peekByte();
@@ -494,7 +488,7 @@ class CponReader {
494
488
  readInt() {
495
489
  let base = 10;
496
490
  let val = 0;
497
- let neg = 0;
491
+ let neg = false;
498
492
  let n = 0;
499
493
  for (; ; n++) {
500
494
  const b = this.ctx.peekByte();
@@ -509,7 +503,7 @@ class CponReader {
509
503
 
510
504
  this.ctx.getByte();
511
505
  if (b === 45) {
512
- neg = 1;
506
+ neg = true;
513
507
  }
514
508
  } else if (b === 120) { // 'x'
515
509
  if (n === 1 && val !== 0) {
@@ -575,7 +569,6 @@ class CponReader {
575
569
  mantisa = Number(this.readInt());
576
570
  b = this.ctx.peekByte();
577
571
  (() => {
578
- // eslint-disable-next-line no-constant-condition
579
572
  while (true) {
580
573
  switch (b) {
581
574
  case 'u'.codePointAt(0): {
@@ -636,15 +629,14 @@ class CponReader {
636
629
  return isNeg ? -mantisa : mantisa;
637
630
  }
638
631
 
639
- private implReadMap(map_type: 'map', terminator: number): ShvMap;
640
- private implReadMap(map_type: 'imap', terminator: number): IMap;
641
- private implReadMap(map_type: 'metamap', terminator: number): MetaMap;
642
- private implReadMap(map_type: 'map' | 'imap' | 'metamap', terminator: number) {
632
+ private implReadMap(mapType: 'map', terminator: number): ShvMap;
633
+ private implReadMap(mapType: 'imap', terminator: number): IMap;
634
+ private implReadMap(mapType: 'metamap', terminator: number): MetaMap;
635
+ private implReadMap(mapType: 'map' | 'imap' | 'metamap', terminator: number) {
643
636
  const map: MetaMap | ShvMap | IMap = {
644
- [shvMapType]: map_type,
637
+ [shvMapType]: mapType,
645
638
  };
646
639
  this.ctx.getByte(); // eat start
647
- // eslint-disable-next-line no-constant-condition
648
640
  while (true) {
649
641
  this.skipWhitespace();
650
642
  const b = this.ctx.peekByte();
@@ -681,60 +673,61 @@ class CponReader {
681
673
  class CponWriter {
682
674
  ctx: PackContext;
683
675
  nestLevel = 0;
676
+
684
677
  constructor(private readonly indentString?: string) {
685
678
  this.ctx = new PackContext();
686
679
  }
687
680
 
688
- write(rpc_val: RpcValue) {
689
- if (rpc_val instanceof RpcValueWithMetaData) {
690
- this.writeMeta(rpc_val.meta);
691
- rpc_val = rpc_val.value;
681
+ write(rpcVal: RpcValue) {
682
+ if (rpcVal instanceof RpcValueWithMetaData) {
683
+ this.writeMeta(rpcVal.meta);
684
+ rpcVal = rpcVal.value;
692
685
  }
693
686
 
694
687
  switch (true) {
695
- case rpc_val === undefined:
688
+ case rpcVal === undefined:
696
689
  this.ctx.writeStringUtf8('null');
697
690
  break;
698
- case typeof rpc_val === 'boolean':
699
- this.writeBool(rpc_val);
691
+ case typeof rpcVal === 'boolean':
692
+ this.writeBool(rpcVal);
700
693
  break;
701
- case typeof rpc_val === 'string':
702
- this.writeJSString(rpc_val);
694
+ case typeof rpcVal === 'string':
695
+ this.writeJSString(rpcVal);
703
696
  break;
704
- case rpc_val instanceof ArrayBuffer:
705
- this.writeBlob(rpc_val);
697
+ case rpcVal instanceof ArrayBuffer:
698
+ this.writeBlob(rpcVal);
706
699
  break;
707
- case rpc_val instanceof UInt:
708
- this.writeUInt(rpc_val);
700
+ case rpcVal instanceof UInt:
701
+ this.writeUInt(rpcVal);
709
702
  break;
710
- case typeof rpc_val === 'number':
711
- this.writeInt(rpc_val);
703
+ case typeof rpcVal === 'number':
704
+ this.writeInt(rpcVal);
712
705
  break;
713
- case rpc_val instanceof Double:
714
- this.writeDouble(rpc_val);
706
+ case rpcVal instanceof Double:
707
+ this.writeDouble(rpcVal);
715
708
  break;
716
- case rpc_val instanceof Decimal:
717
- this.writeDecimal(rpc_val);
709
+ case rpcVal instanceof Decimal:
710
+ this.writeDecimal(rpcVal);
718
711
  break;
719
- case Array.isArray(rpc_val):
720
- this.writeList(rpc_val);
712
+ case Array.isArray(rpcVal):
713
+ this.writeList(rpcVal);
721
714
  break;
722
- case rpc_val instanceof Date:
723
- this.writeDateTime(rpc_val);
715
+ case rpcVal instanceof Date:
716
+ this.writeDateTime(rpcVal);
724
717
  break;
725
- case typeof rpc_val === 'object':
726
- switch (rpc_val[shvMapType]) {
718
+ case typeof rpcVal === 'object':
719
+ switch (rpcVal[shvMapType]) {
727
720
  case 'imap':
728
- this.writeIMap(rpc_val);
721
+ this.writeIMap(rpcVal);
729
722
  break;
730
723
  case 'map':
731
- this.writeMap(rpc_val);
724
+ this.writeMap(rpcVal);
732
725
  break;
733
726
  }
734
727
 
735
728
  break;
736
729
  default:
737
- console.log('Can\'t serialize rpc value', rpc_val);
730
+ console.log('Can\'t serialize rpc value', rpcVal);
738
731
  throw new Error('Can\'t serialize rpc value');
739
732
  }
740
733
  }
@@ -745,25 +738,25 @@ class CponWriter {
745
738
  const charcode = str.codePointAt(i)!;
746
739
  switch (charcode) {
747
740
  case 0:
748
- this.ctx.writeStringUtf8('\\0');
741
+ this.ctx.writeStringUtf8(String.raw`\0`);
749
742
  break;
750
743
  case '\\'.codePointAt(0):
751
744
  this.ctx.writeStringUtf8('\\\\');
752
745
  break;
753
746
  case '\t'.codePointAt(0):
754
- this.ctx.writeStringUtf8('\\t');
747
+ this.ctx.writeStringUtf8(String.raw`\t`);
755
748
  break;
756
749
  case '\b'.codePointAt(0):
757
- this.ctx.writeStringUtf8('\\b');
750
+ this.ctx.writeStringUtf8(String.raw`\b`);
758
751
  break;
759
752
  case '\r'.codePointAt(0):
760
- this.ctx.writeStringUtf8('\\r');
753
+ this.ctx.writeStringUtf8(String.raw`\r`);
761
754
  break;
762
755
  case '\n'.codePointAt(0):
763
- this.ctx.writeStringUtf8('\\n');
756
+ this.ctx.writeStringUtf8(String.raw`\n`);
764
757
  break;
765
758
  case '"'.codePointAt(0):
766
- this.ctx.writeStringUtf8('\\"');
759
+ this.ctx.writeStringUtf8(String.raw`\"`);
767
760
  break;
768
761
  default:
769
762
  this.ctx.writeCharCodeUtf8(charcode);
@@ -782,16 +775,16 @@ class CponWriter {
782
775
  this.ctx.writeStringUtf8('\\\\');
783
776
  break;
784
777
  case '\t'.codePointAt(0):
785
- this.ctx.writeStringUtf8('\\t');
778
+ this.ctx.writeStringUtf8(String.raw`\t`);
786
779
  break;
787
780
  case '\r'.codePointAt(0):
788
- this.ctx.writeStringUtf8('\\r');
781
+ this.ctx.writeStringUtf8(String.raw`\r`);
789
782
  break;
790
783
  case '\n'.codePointAt(0):
791
- this.ctx.writeStringUtf8('\\n');
784
+ this.ctx.writeStringUtf8(String.raw`\n`);
792
785
  break;
793
786
  case '"'.codePointAt(0):
794
- this.ctx.writeStringUtf8('\\"');
787
+ this.ctx.writeStringUtf8(String.raw`\"`);
795
788
  break;
796
789
  default:
797
790
  if (b >= 32 && b < 127) {
@@ -910,8 +903,8 @@ class CponWriter {
910
903
  }
911
904
 
912
905
  writeDecimal(val: Decimal) {
913
- let mantisa = val.mantisa;
914
- const exponent = val.exponent;
906
+ let {mantisa} = val;
907
+ const {exponent} = val;
915
908
  if (mantisa < 0) {
916
909
  mantisa = -mantisa;
917
910
  this.ctx.putByte('-'.codePointAt(0)!);
package/src/json.ts CHANGED
@@ -2,7 +2,6 @@ import {UnpackContext} from './cpcontext';
2
2
  import {CponReader, stringifyDate} from './cpon';
3
3
  import {Decimal, Double, isIMap, isShvMap, makeIMap, makeMap, makeMetaMap, RpcValueWithMetaData, UInt, type RpcValue} from './rpcvalue';
4
4
 
5
- // eslint-disable-next-line @typescript-eslint/ban-types -- Zod needs the default argument, otherwise it'll infer as UInt<unknown>
6
5
  const decodeMap = (x: object) => makeMap(Object.fromEntries(Object.entries(x).map(([key, value]) => [key, decodeValueJson(value)])));
7
6
 
8
7
  const decodeValueJson = (x: unknown): RpcValue => {
@@ -123,6 +122,7 @@ const encodeValueJson = (x: RpcValue): unknown => {
123
122
  case x instanceof Date:
124
123
  return [JSON_TAG_TYPE, 'DateTime', stringifyDate(x)];
125
124
  case x === undefined:
125
+ // eslint-disable-next-line unicorn/no-null
126
126
  return null;
127
127
  case x instanceof Decimal:
128
128
  case x instanceof UInt:
package/src/rpcvalue.ts CHANGED
@@ -14,7 +14,7 @@ class UInt<T extends number = number> {
14
14
  this.value = u;
15
15
  }
16
16
 
17
- [Symbol.toPrimitive](_hint: string) {
17
+ [Symbol.toPrimitive]() {
18
18
  return this.value;
19
19
  }
20
20
 
@@ -34,6 +34,7 @@ class Double {
34
34
  class Decimal {
35
35
  mantisa: number;
36
36
  exponent: number;
37
+
37
38
  constructor(mantisa: number, exponent: number) {
38
39
  if (!Number.isInteger(exponent)) {
39
40
  throw new TypeError(`Decimal: exponent must be integral (${exponent})`);
@@ -49,9 +50,9 @@ export type Bool = boolean;
49
50
  export type Blob = ArrayBuffer;
50
51
  export type ShvString = string;
51
52
  export type DateTime = Date & {utc_offset?: number};
52
- const withOffset = (date: Date, utc_offset?: number) => {
53
- const clonedDate: DateTime = new Date(date.getTime());
54
- clonedDate.utc_offset = utc_offset;
53
+ const withOffset = (date: Date, utcOffset?: number) => {
54
+ const clonedDate: DateTime = new Date(date);
55
+ clonedDate.utc_offset = utcOffset;
55
56
  return clonedDate;
56
57
  };
57
58
 
@@ -59,12 +60,14 @@ export type List = RpcValue[];
59
60
 
60
61
  const shvMapType = Symbol('shvMapType');
61
62
 
63
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- I can't get rid of this yet
62
64
  type IMap<T extends Record<number, RpcValue> = Record<number, any>> = {
63
65
  [Key in keyof T]: T[Key];
64
66
  } & {
65
67
  [shvMapType]: 'imap';
66
68
  };
67
69
 
70
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- I can't get rid of this yet
68
71
  type ShvMap<T extends Record<string, RpcValue> = Record<string, any>> = {
69
72
  [Key in keyof T]: T[Key];
70
73
  } & {
package/src/ws-client.ts CHANGED
@@ -122,15 +122,12 @@ class NotImplemented extends RpcError {}
122
122
  class WsClient {
123
123
  private requestId = 1;
124
124
  private pingTimerId = -1;
125
-
126
125
  private rpcHandlers: Array<{
127
126
  resolve: RpcResponseResolver;
128
127
  timeout_handle: number;
129
128
  }> = [];
130
-
131
129
  private readonly subscriptions: Subscription[] = [];
132
130
  private readonly websocket: WebSocket;
133
-
134
131
  private readonly options: WsClientOptions;
135
132
  private readonly timeout: number;
136
133
 
@@ -172,6 +169,7 @@ class WsClient {
172
169
  handler.resolve((() => {
173
170
  if (RPC_MESSAGE_ERROR in rpcMsg.value) {
174
171
  const code = rpcMsg.value[RPC_MESSAGE_ERROR][ERROR_CODE] as unknown;
172
+ // eslint-disable-next-line @typescript-eslint/naming-convention
175
173
  const ErrorTypeCtor = (() => {
176
174
  switch (code) {
177
175
  case ErrorCode.InvalidRequest: return InvalidRequest;
@@ -199,7 +197,7 @@ class WsClient {
199
197
 
200
198
  return new ProtocolError('Response included neither result nor error');
201
199
  })());
202
- // eslint-disable-next-line @typescript-eslint/no-array-delete, @typescript-eslint/no-dynamic-delete
200
+ // eslint-disable-next-line @typescript-eslint/no-array-delete
203
201
  delete this.rpcHandlers[Number(requestId)];
204
202
  }
205
203
  }
@@ -217,16 +215,16 @@ class WsClient {
217
215
  }
218
216
  }
219
217
 
220
- callRpcMethod(shv_path: '.broker/currentClient', method: 'accessGrantForMethodCall', params: [string, string]): Promise<ResultOrError<string>>;
221
- callRpcMethod(shv_path: string | undefined, method: 'dir', params?: RpcValue): Promise<ResultOrError<DirResult>>;
222
- callRpcMethod(shv_path: string | undefined, method: 'ls', params?: RpcValue): Promise<ResultOrError<LsResult>>;
223
- callRpcMethod(shv_path: string | undefined, method: string, params?: RpcValue): Promise<ResultOrError>;
224
- callRpcMethod(shv_path: string | undefined, method: string, params?: RpcValue): Promise<ResultOrError> {
218
+ callRpcMethod(shvPath: '.broker/currentClient', method: 'accessGrantForMethodCall', params: [string, string]): Promise<ResultOrError<string>>;
219
+ callRpcMethod(shvPath: string | undefined, method: 'dir', params?: RpcValue): Promise<ResultOrError<DirResult>>;
220
+ callRpcMethod(shvPath: string | undefined, method: 'ls', params?: RpcValue): Promise<ResultOrError<LsResult>>;
221
+ callRpcMethod(shvPath: string | undefined, method: string, params?: RpcValue): Promise<ResultOrError>;
222
+ callRpcMethod(shvPath: string | undefined, method: string, params?: RpcValue): Promise<ResultOrError> {
225
223
  const rqId = this.requestId++;
226
224
  const rq: RpcRequest = new RpcValueWithMetaData(makeMetaMap({
227
225
  [RPC_MESSAGE_REQUEST_ID]: rqId,
228
226
  [RPC_MESSAGE_METHOD]: method ?? '',
229
- [RPC_MESSAGE_SHV_PATH]: shv_path ?? '',
227
+ [RPC_MESSAGE_SHV_PATH]: shvPath ?? '',
230
228
  }), makeIMap({
231
229
  [RPC_MESSAGE_PARAMS]: params,
232
230
  }));
@@ -234,7 +232,7 @@ class WsClient {
234
232
  this.sendRpcMessage(rq);
235
233
 
236
234
  const promise = new Promise<ResultOrError>(resolve => {
237
- this.rpcHandlers[rqId] = {resolve, timeout_handle: self.setTimeout(() => {
235
+ this.rpcHandlers[rqId] = {resolve, timeout_handle: globalThis.setTimeout(() => {
238
236
  resolve(new MethodCallTimeout(makeIMap({
239
237
  [ERROR_CODE]: ErrorCode.MethodCallTimeout,
240
238
  [ERROR_MESSAGE]: `Shv call timeout after: ${this.timeout} msec.`,
@@ -246,10 +244,10 @@ class WsClient {
246
244
  return promise;
247
245
  }
248
246
 
249
- sendRpcMessage(rpc_msg: RpcMessage) {
250
- if (this.websocket && this.websocket.readyState === WebSocket.OPEN) {
251
- this.logDebug('sending rpc message:', toCpon(rpc_msg));
252
- const msgData = new Uint8Array(toChainPack(rpc_msg));
247
+ sendRpcMessage(rpcMsg: RpcMessage) {
248
+ if (this.websocket.readyState === WebSocket.OPEN) {
249
+ this.logDebug('sending rpc message:', toCpon(rpcMsg));
250
+ const msgData = new Uint8Array(toChainPack(rpcMsg));
253
251
 
254
252
  const wr = new ChainPackWriter();
255
253
  wr.writeUIntData(msgData.length + 1);
@@ -354,7 +352,7 @@ class WsClient {
354
352
  options.onWorkflows(response);
355
353
 
356
354
  this.close();
357
- }).catch((_: unknown) => {
355
+ }).catch(() => {
358
356
  options.onWorkflowsFailed();
359
357
  });
360
358
  });
@@ -375,7 +373,7 @@ class WsClient {
375
373
  options.onConnectionFailure(error);
376
374
  };
377
375
 
378
- const handleLoginResponse = (response: any) => {
376
+ const handleLoginResponse = (response: unknown) => {
379
377
  if (response instanceof Error) {
380
378
  handleConnectionError(response);
381
379
  return;
@@ -383,7 +381,7 @@ class WsClient {
383
381
 
384
382
  this.logDebug('SUCCESS: connected to shv broker');
385
383
  options.onConnected();
386
- this.pingTimerId = window.setInterval(() => {
384
+ this.pingTimerId = globalThis.setInterval(() => {
387
385
  this.sendPing();
388
386
  }, options.pingInterval ?? DEFAULT_PING_INTERVAL);
389
387
  };
@@ -427,7 +425,7 @@ class WsClient {
427
425
  this.logDebug('DISCONNECTED');
428
426
  this.subscriptions.length = 0;
429
427
  options.onDisconnected();
430
- window.clearInterval(this.pingTimerId);
428
+ globalThis.clearInterval(this.pingTimerId);
431
429
  });
432
430
  }
433
431
  }
package/src/zod.ts CHANGED
@@ -1,3 +1,4 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
1
2
  import {z, type ZodType} from 'zod';
2
3
  import {Decimal, Double, type IMap, isIMap, isMetaMap, isShvMap, type MetaMap, type RpcValue, type RpcValueType, RpcValueWithMetaData, type ShvMap, UInt} from './rpcvalue';
3
4
 
@@ -6,7 +7,7 @@ export const recmap = <T extends ZodType<any, any, any>>(schema: T) => z.custom<
6
7
  export const imap = <T extends Record<string, ZodType<any, any, any>>>(schema?: T) => z.custom<IMap<{[K in keyof T]: z.infer<T[K]>}>>((data: RpcValue) => isIMap(data) && (schema === undefined || z.object(schema).safeParse(data).success));
7
8
  export const metamap = <T extends Record<string | number, ZodType<any, any, any>>>(schema?: T) => z.custom<MetaMap<{[K in keyof T]: z.infer<T[K]>}>>((data: RpcValue) => isMetaMap(data) && (schema === undefined || z.object(schema).safeParse(data).success));
8
9
  export const int = () => z.number();
9
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-arguments -- Zod needs the default argument, otherwise it'll infer as UInt<unknown>
10
+
10
11
  export const uint = () => z.instanceof(UInt<number>);
11
12
  export const double = () => z.instanceof(Double);
12
13
  export const decimal = () => z.instanceof(Decimal);
package/.xo-config.json DELETED
@@ -1,42 +0,0 @@
1
- {
2
- "space": 4,
3
- "rules": {
4
- "@typescript-eslint/naming-convention": ["error",
5
- {
6
- "selector": "variable",
7
- "format": ["camelCase"]
8
- },
9
- {
10
- "format": ["camelCase", "UPPER_CASE"],
11
- "selector": "variable",
12
- "modifiers": ["const"]
13
- },
14
- {
15
- "format": ["PascalCase"],
16
- "selector": "variable",
17
- "modifiers": ["const"],
18
- "filter": "Ctor$|Validation$|Zod$"
19
- }
20
- ],
21
- "@typescript-eslint/prefer-promise-reject-errors": "off",
22
- "@typescript-eslint/promise-function-async": "off",
23
- "@typescript-eslint/triple-slash-reference": "off",
24
- "capitalized-comments": "off",
25
- "object-curly-newline": ["error", {
26
- "ImportDeclaration": "never"
27
- }],
28
- "n/file-extension-in-import": "off",
29
- "promise-function-async": "off",
30
- "default-case": "off",
31
- "import/extensions": "off",
32
- "import/no-unassigned-import": "off",
33
- "no-warning-comments": "off",
34
- "prefer-promise-reject-errors": "off",
35
- "unicorn/explicit-length-check": "off",
36
- "unicorn/filename-case": "off",
37
- "unicorn/no-negated-condition": "off",
38
- "unicorn/prefer-top-level-await": "off",
39
- "unicorn/switch-case-braces": "off",
40
- "unicorn/prevent-abbreviations": "off"
41
- }
42
- }