libshv-js 3.1.6 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,24 @@
1
+ # vim: sw=2
2
+ name: Publish
3
+
4
+ on:
5
+ push:
6
+ branches: [ "main" ]
7
+
8
+ jobs:
9
+ test:
10
+ name: Publish new version
11
+ runs-on: ubuntu-22.04
12
+ steps:
13
+ - uses: actions/checkout@v3
14
+
15
+ - name: Setup node
16
+ uses: actions/setup-node@v4
17
+ with:
18
+ node-version: '20.x'
19
+ registry-url: 'https://registry.npmjs.org'
20
+
21
+ - name: Publish
22
+ run: npm publish
23
+ env:
24
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "libshv-js",
3
- "version": "3.1.6",
3
+ "version": "3.2.0",
4
4
  "description": "Typescript implementation of libshv",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1"
package/src/chainpack.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import {utf8ToString} from './cpon';
2
- import {type RpcValue, type RpcValueType, type DateTime, Decimal, Double, IMap, Int, MetaMap, RpcValueWithMetaData, ShvMap, UInt, withOffset} from './rpcvalue';
2
+ import {type RpcValue, type RpcValueType, type DateTime, Decimal, Double, type IMap, Int, type MetaMap, RpcValueWithMetaData, type ShvMap, UInt, withOffset, shvMapType} from './rpcvalue';
3
3
  import {UnpackContext, PackContext} from './cpcontext';
4
4
 
5
5
  enum PackingSchema {
@@ -297,19 +297,24 @@ class ChainPackReader {
297
297
  }
298
298
 
299
299
  readMetaMap() {
300
- return this.implReadMap(MetaMap);
300
+ return this.implReadMap('metamap');
301
301
  }
302
302
 
303
303
  readMap() {
304
- return this.implReadMap(ShvMap);
304
+ return this.implReadMap('map');
305
305
  }
306
306
 
307
307
  readIMap() {
308
- return this.implReadMap(IMap);
308
+ return this.implReadMap('imap');
309
309
  }
310
310
 
311
- private implReadMap<MapType extends MetaMap | ShvMap | IMap>(MapTypeCtor: new () => MapType) {
312
- const map = new MapTypeCtor();
311
+ private implReadMap(map_type: 'map'): ShvMap;
312
+ private implReadMap(map_type: 'imap'): IMap;
313
+ private implReadMap(map_type: 'metamap'): MetaMap;
314
+ private implReadMap(map_type: 'map' | 'imap' | 'metamap') {
315
+ const map: ShvMap | IMap | MetaMap = {
316
+ [shvMapType]: map_type,
317
+ };
313
318
  while (true) {
314
319
  const b = this.ctx.peekByte();
315
320
  if (b as PackingSchema === PackingSchema.Term) {
@@ -318,14 +323,14 @@ class ChainPackReader {
318
323
  }
319
324
  const key = this.read();
320
325
  const val = this.read();
321
- if (map instanceof MetaMap && typeof key === 'string') {
322
- map.value[key] = val;
323
- } else if (map instanceof MetaMap && key instanceof Int) {
324
- map.value[Number(key)] = val;
325
- } else if (map instanceof ShvMap && typeof key === 'string') {
326
- map.value[key] = val;
327
- } else if (map instanceof IMap && key instanceof Int) {
328
- map.value[Number(key)] = val;
326
+ if (map[shvMapType] === 'metamap' && typeof key === 'string') {
327
+ map[key] = val;
328
+ } else if (map[shvMapType] === 'metamap' && key instanceof Int) {
329
+ map[Number(key)] = val;
330
+ } else if (map[shvMapType] === 'map' && typeof key === 'string') {
331
+ map[key] = val;
332
+ } else if (map[shvMapType] === 'imap' && key instanceof Int) {
333
+ map[Number(key)] = val;
329
334
  } else {
330
335
  throw new TypeError('Malformed map, invalid key');
331
336
  }
@@ -371,15 +376,21 @@ class ChainPackWriter {
371
376
  case Array.isArray(rpc_val):
372
377
  this.writeList(rpc_val);
373
378
  break;
374
- case rpc_val instanceof IMap:
375
- this.writeIMap(rpc_val);
376
- break;
377
- case rpc_val instanceof ShvMap:
378
- this.writeMap(rpc_val);
379
- break;
380
379
  case rpc_val instanceof Date:
381
380
  this.writeDateTime(rpc_val);
382
381
  break;
382
+ case rpc_val instanceof Double:
383
+ throw new Error('writing doubles not implemented');
384
+ case typeof rpc_val === 'object':
385
+ switch (rpc_val[shvMapType]) {
386
+ case 'imap':
387
+ this.writeIMap(rpc_val);
388
+ break;
389
+ case 'map':
390
+ this.writeMap(rpc_val);
391
+ break;
392
+ }
393
+ break;
383
394
  default:
384
395
  console.log('Can\'t serialize', rpc_val);
385
396
  throw new Error('Can\'t serialize');
@@ -545,19 +556,19 @@ class ChainPackWriter {
545
556
  }
546
557
 
547
558
  writeMapContent(map: MetaMap | ShvMap | IMap) {
548
- for (const [key, value] of Object.entries(map.value)) {
559
+ for (const [key, value] of Object.entries(map)) {
549
560
  if (value === undefined) {
550
561
  continue;
551
562
  }
552
563
 
553
- if (map instanceof IMap) {
564
+ if (map[shvMapType] === 'imap') {
554
565
  const int_key = Number(key);
555
566
  if (Number.isNaN(int_key)) {
556
567
  throw new TypeError('Invalid NaN IMap key');
557
568
  }
558
569
 
559
570
  this.writeInt(new Int(int_key));
560
- } else if (map instanceof MetaMap) {
571
+ } else if (map[shvMapType] === 'metamap') {
561
572
  const int_key = Number(key);
562
573
  if (Number.isNaN(int_key)) {
563
574
  this.writeJSString(key.toString());
package/src/cpon.ts CHANGED
@@ -1,4 +1,4 @@
1
- import {type RpcValue, type RpcValueType, type DateTime, type List, Decimal, Double, IMap, Int, MetaMap, RpcValueWithMetaData, ShvMap, UInt, withOffset} from './rpcvalue';
1
+ import {type RpcValue, type RpcValueType, type DateTime, type List, Decimal, Double, type IMap, Int, type MetaMap, RpcValueWithMetaData, type ShvMap, UInt, withOffset, shvMapType, isShvMap, isIMap} from './rpcvalue';
2
2
  import {PackContext, UnpackContext} from './cpcontext';
3
3
 
4
4
  const hexify = (byte: number) => {
@@ -412,15 +412,15 @@ class CponReader {
412
412
  }
413
413
 
414
414
  readMetaMap() {
415
- return this.implReadMap(MetaMap, '>'.codePointAt(0)!);
415
+ return this.implReadMap('metamap', '>'.codePointAt(0)!);
416
416
  }
417
417
 
418
418
  readMap() {
419
- return this.implReadMap(ShvMap, '}'.codePointAt(0)!);
419
+ return this.implReadMap('map', '}'.codePointAt(0)!);
420
420
  }
421
421
 
422
422
  readIMap() {
423
- return this.implReadMap(IMap, '}'.codePointAt(0)!);
423
+ return this.implReadMap('imap', '}'.codePointAt(0)!);
424
424
  }
425
425
 
426
426
  readInt() {
@@ -550,8 +550,13 @@ class CponReader {
550
550
  return new Int(is_neg ? -mantisa : mantisa);
551
551
  }
552
552
 
553
- private implReadMap<MapType extends MetaMap | ShvMap | IMap>(MapTypeCtor: new () => MapType, terminator: number) {
554
- const map = new MapTypeCtor();
553
+ private implReadMap(map_type: 'map', terminator: number): ShvMap;
554
+ private implReadMap(map_type: 'imap', terminator: number): IMap;
555
+ private implReadMap(map_type: 'metamap', terminator: number): MetaMap;
556
+ private implReadMap(map_type: 'map' | 'imap' | 'metamap', terminator: number) {
557
+ const map: MetaMap | ShvMap | IMap = {
558
+ [shvMapType]: map_type,
559
+ };
555
560
  this.ctx.getByte(); // eat start
556
561
  while (true) {
557
562
  this.skipWhitespace();
@@ -568,14 +573,14 @@ class CponReader {
568
573
  this.skipWhitespace();
569
574
  const val = this.read();
570
575
 
571
- if (map instanceof MetaMap && typeof key === 'string') {
572
- map.value[key] = val;
573
- } else if (map instanceof MetaMap && (key instanceof UInt || key instanceof Int)) {
574
- map.value[Number(key)] = val;
575
- } else if (map instanceof ShvMap && typeof key === 'string') {
576
- map.value[key] = val;
577
- } else if (map instanceof IMap && (key instanceof UInt || key instanceof Int)) {
578
- map.value[Number(key)] = val;
576
+ if (map[shvMapType] === 'metamap' && typeof key === 'string') {
577
+ map[key] = val;
578
+ } else if (map[shvMapType] === 'metamap' && (key instanceof UInt || key instanceof Int)) {
579
+ map[Number(key)] = val;
580
+ } else if (map[shvMapType] === 'map' && typeof key === 'string') {
581
+ map[key] = val;
582
+ } else if (map[shvMapType] === 'imap' && (key instanceof UInt || key instanceof Int)) {
583
+ map[Number(key)] = val;
579
584
  } else {
580
585
  throw new TypeError('Malformed map, invalid key');
581
586
  }
@@ -625,15 +630,19 @@ class CponWriter {
625
630
  case Array.isArray(rpc_val):
626
631
  this.writeList(rpc_val);
627
632
  break;
628
- case rpc_val instanceof IMap:
629
- this.writeIMap(rpc_val);
630
- break;
631
- case rpc_val instanceof ShvMap:
632
- this.writeMap(rpc_val);
633
- break;
634
633
  case rpc_val instanceof Date:
635
634
  this.writeDateTime(rpc_val);
636
635
  break;
636
+ case typeof rpc_val === 'object':
637
+ switch (rpc_val[shvMapType]) {
638
+ case 'imap':
639
+ this.writeIMap(rpc_val);
640
+ break;
641
+ case 'map':
642
+ this.writeMap(rpc_val);
643
+ break;
644
+ }
645
+ break;
637
646
  default:
638
647
  console.log('Can\'t serialize rpc value', rpc_val);
639
648
  throw new Error('Can\'t serialize rpc value');
@@ -761,7 +770,7 @@ class CponWriter {
761
770
  this.increaseIndentIfNotOneLiner(map);
762
771
  this.doIndentIfNotOneliner(map);
763
772
  let first = true;
764
- for (const [key, value] of Object.entries(map.value)) {
773
+ for (const [key, value] of Object.entries(map)) {
765
774
  if (value === undefined) {
766
775
  continue;
767
776
  }
@@ -771,14 +780,14 @@ class CponWriter {
771
780
  }
772
781
  first = false;
773
782
 
774
- if (map instanceof IMap) {
783
+ if (map[shvMapType] === 'imap') {
775
784
  const int_key = Number(key);
776
785
  if (Number.isNaN(int_key)) {
777
786
  throw new TypeError('Invalid NaN IMap key');
778
787
  }
779
788
 
780
789
  this.writeInt(new Int(int_key));
781
- } else if (map instanceof MetaMap) {
790
+ } else if (map[shvMapType] === 'metamap') {
782
791
  const int_key = Number(key);
783
792
  if (Number.isNaN(int_key)) {
784
793
  this.ctx.putByte('"'.codePointAt(0)!);
@@ -881,10 +890,10 @@ class CponWriter {
881
890
  const keyThreshold = Array.isArray(value) ? 10 : 5;
882
891
 
883
892
  if (Array.isArray(value)) {
884
- return value.length <= keyThreshold && !(value.some(x => Array.isArray(x) || x instanceof ShvMap || x instanceof IMap));
893
+ return value.length <= keyThreshold && !(value.some(x => Array.isArray(x) || isShvMap(x) || isIMap(x)));
885
894
  }
886
895
 
887
- return Object.keys(value.value).length <= keyThreshold && !(Object.values(value.value).some(x => Array.isArray(x) || x instanceof ShvMap || x instanceof IMap));
896
+ return Object.keys(value).length <= keyThreshold && !(Object.values(value).some(x => Array.isArray(x) || isShvMap(x) || isIMap(x)));
888
897
  }
889
898
 
890
899
  private increaseIndentIfNotOneLiner(value: MetaMap | ShvMap | IMap | List) {
package/src/rpcmessage.ts CHANGED
@@ -1,4 +1,4 @@
1
- import {IMap, Int, MetaMap, type RpcValue, RpcValueWithMetaData} from './rpcvalue';
1
+ import {type IMap, Int, isIMap, makeIMap, makeMetaMap, type MetaMap, type RpcValue, RpcValueWithMetaData} from './rpcvalue';
2
2
  import {toCpon} from './cpon';
3
3
  import {toChainPack} from './chainpack';
4
4
 
@@ -30,19 +30,19 @@ enum ErrorCode {
30
30
  NotImplemented = 12,
31
31
  }
32
32
 
33
- type ErrorMap = IMap<{
33
+ export type ErrorMap = {
34
34
  [ERROR_CODE]: Int<ErrorCode>;
35
35
  [ERROR_MESSAGE]?: string;
36
36
  [ERROR_DATA]?: RpcValue;
37
- }>;
37
+ };
38
38
 
39
39
  class RpcError extends Error {
40
40
  constructor(private readonly err_info: ErrorMap) {
41
- super(err_info.value[ERROR_MESSAGE]);
41
+ super(err_info[ERROR_MESSAGE] ?? 'Unknown RpcError');
42
42
  }
43
43
 
44
44
  data() {
45
- return this.err_info.value[ERROR_DATA];
45
+ return this.err_info[ERROR_DATA];
46
46
  }
47
47
  }
48
48
 
@@ -66,12 +66,12 @@ class RpcMessage {
66
66
  meta: MetaMap;
67
67
  constructor(rpc_val?: RpcValue) {
68
68
  if (rpc_val === undefined) {
69
- this.value = new IMap();
70
- this.meta = new MetaMap();
69
+ this.value = makeIMap({});
70
+ this.meta = makeMetaMap({});
71
71
  return;
72
72
  }
73
73
 
74
- if (!(rpc_val instanceof RpcValueWithMetaData && rpc_val.value instanceof IMap)) {
74
+ if (!(rpc_val instanceof RpcValueWithMetaData && isIMap(rpc_val.value))) {
75
75
  throw new TypeError(`RpcMessage initialized with a non-IMap: ${toCpon(rpc_val)}`);
76
76
  }
77
77
 
@@ -96,58 +96,60 @@ class RpcMessage {
96
96
  }
97
97
 
98
98
  requestId(): Int | undefined {
99
- return (this.meta.value[TagRequestId] as Int);
99
+ return (this.meta[TagRequestId] as Int);
100
100
  }
101
101
 
102
102
  setRequestId(id: number | Int) {
103
- this.meta.value[TagRequestId] = new Int(id);
103
+ this.meta[TagRequestId] = new Int(id);
104
104
  }
105
105
 
106
106
  callerIds(): RpcValue[] | undefined {
107
- return this.meta.value[TagCallerIds] as RpcValue[];
107
+ return this.meta[TagCallerIds] as RpcValue[];
108
108
  }
109
109
 
110
110
  setCallerIds(ids: RpcValue[]) {
111
- this.meta.value[TagCallerIds] = ids;
111
+ this.meta[TagCallerIds] = ids;
112
112
  }
113
113
 
114
114
  shvPath(): string | undefined {
115
- return (this.meta.value[TagShvPath] as string);
115
+ return (this.meta[TagShvPath] as string);
116
116
  }
117
117
 
118
118
  setShvPath(val: string) {
119
- this.meta.value[TagShvPath] = val;
119
+ this.meta[TagShvPath] = val;
120
120
  }
121
121
 
122
122
  method(): string | undefined {
123
- return (this.meta.value[TagMethod] as string);
123
+ return (this.meta[TagMethod] as string);
124
124
  }
125
125
 
126
126
  setMethod(val: string) {
127
- this.meta.value[TagMethod] = val;
127
+ this.meta[TagMethod] = val;
128
128
  }
129
129
 
130
130
  params() {
131
- return this.value.value[KeyParams];
131
+ return this.value[KeyParams];
132
132
  }
133
133
 
134
134
  setParams(params: RpcValue) {
135
- this.value.value[KeyParams] = params;
135
+ this.value[KeyParams] = params;
136
136
  }
137
137
 
138
138
  resultOrError() {
139
- if (this.value.value[KeyError] !== undefined) {
140
- if (!(this.value.value[KeyError] instanceof IMap)) {
139
+ if (Object.hasOwn(this.value, KeyError)) {
140
+ if (!isIMap(this.value[KeyError])) {
141
141
  return new ProtocolError('Response had an error, but this error was not a map');
142
142
  }
143
143
 
144
- const error_map = this.value.value[KeyError];
145
- if (error_map.value[ERROR_CODE] === undefined) {
144
+ const error_map = this.value[KeyError];
145
+ if (!(error_map[ERROR_CODE] instanceof Int)) {
146
146
  return new ProtocolError('Response had an error, but this error did not contain at least an error code');
147
147
  }
148
148
 
149
+ const code = error_map[ERROR_CODE];
150
+
149
151
  const ErrorType = (() => {
150
- switch ((this.value.value[KeyError] as ErrorMap).value[ERROR_CODE].value) {
152
+ switch (code.value) {
151
153
  case ErrorCode.InvalidRequest: return InvalidRequest;
152
154
  case ErrorCode.MethodNotFound: return MethodNotFound;
153
155
  case ErrorCode.InvalidParams: return InvalidParams;
@@ -160,25 +162,26 @@ class RpcMessage {
160
162
  case ErrorCode.LoginRequired: return LoginRequired;
161
163
  case ErrorCode.UserIDRequired: return UserIDRequired;
162
164
  case ErrorCode.NotImplemented: return NotImplemented;
165
+ default: return Unknown;
163
166
  }
164
167
  })();
165
168
 
166
- return new ErrorType(this.value.value[KeyError] as ErrorMap);
169
+ return new ErrorType(this.value[KeyError] as unknown as ErrorMap);
167
170
  }
168
171
 
169
- if (Object.hasOwn(this.value.value, KeyResult)) {
170
- return this.value.value[KeyResult];
172
+ if (Object.hasOwn(this.value, KeyResult)) {
173
+ return this.value[KeyResult];
171
174
  }
172
175
 
173
176
  return new ProtocolError('Response included neither result nor error');
174
177
  }
175
178
 
176
179
  setResult(result: RpcValue) {
177
- this.value.value[KeyResult] = result;
180
+ this.value[KeyResult] = result;
178
181
  }
179
182
 
180
183
  setError(error: string) {
181
- this.value.value[KeyError] = error;
184
+ this.value[KeyError] = error;
182
185
  }
183
186
 
184
187
  toCpon() {
package/src/rpcvalue.ts CHANGED
@@ -71,15 +71,19 @@ const withOffset = (date: Date, utc_offset?: number) => {
71
71
  };
72
72
  export type List = RpcValue[];
73
73
 
74
- type ShvMapDefaultType = Record<string, RpcValue | undefined>;
75
- class ShvMap<T extends ShvMapDefaultType = ShvMapDefaultType> {
76
- constructor(public value: T = {} as T) {}
77
- }
74
+ const shvMapType = Symbol('shvMapType');
78
75
 
79
- type IMapDefaultType = Record<number, RpcValue | undefined>;
80
- class IMap<T extends IMapDefaultType = IMapDefaultType> {
81
- constructor(public value: T = {} as T) {}
82
- }
76
+ type IMap<T extends Record<number, RpcValue> = Record<number, any>> = {
77
+ [Key in keyof T]: T[Key];
78
+ } & {
79
+ [shvMapType]: 'imap';
80
+ };
81
+
82
+ type ShvMap<T extends Record<string, RpcValue> = Record<string, any>> = {
83
+ [Key in keyof T]: T[Key];
84
+ } & {
85
+ [shvMapType]: 'map';
86
+ };
83
87
 
84
88
  export type RpcValueType =
85
89
  Null |
@@ -95,12 +99,30 @@ export type RpcValueType =
95
99
  ShvMap |
96
100
  IMap;
97
101
 
98
- class MetaMap {
99
- value: Record<number | string, RpcValue | undefined>;
100
- constructor(obj?: Record<number | string, RpcValue | undefined>) {
101
- this.value = obj ?? {};
102
- }
103
- }
102
+ type MetaMap<T extends Record<string | number, RpcValue> = Record<string | number, RpcValue>> = {
103
+ [Key in keyof T]: T[Key];
104
+ } & {
105
+ [shvMapType]: 'metamap';
106
+ };
107
+
108
+ const isShvMap = (x: RpcValue): x is ShvMap => typeof x === 'object' && (x as ShvMap)[shvMapType] === 'map';
109
+
110
+ const isIMap = (x: RpcValue): x is IMap => typeof x === 'object' && (x as IMap)[shvMapType] === 'imap';
111
+
112
+ const makeMetaMap = <T extends Record<string | number, RpcValue> = Record<string | number, RpcValue>>(x: T = {} as T): MetaMap<T> => ({
113
+ ...x,
114
+ [shvMapType]: 'metamap',
115
+ });
116
+
117
+ const makeIMap = <T extends Record<number, RpcValue> = Record<number, RpcValue>>(x: T = {} as T): IMap<T> => ({
118
+ ...x,
119
+ [shvMapType]: 'imap',
120
+ });
121
+
122
+ const makeMap = <T extends Record<string, RpcValue> = Record<string, RpcValue>>(x: T = {} as T): ShvMap<T> => ({
123
+ ...x,
124
+ [shvMapType]: 'map',
125
+ });
104
126
 
105
127
  class RpcValueWithMetaData {
106
128
  constructor(public value: RpcValueType, public meta: MetaMap) {}
@@ -108,4 +130,4 @@ class RpcValueWithMetaData {
108
130
 
109
131
  export type RpcValue = RpcValueType | RpcValueWithMetaData;
110
132
 
111
- export {Decimal, Double, Int, IMap, MetaMap, RpcValueWithMetaData, ShvMap, UInt, withOffset};
133
+ export {shvMapType, Decimal, Double, type IMap, Int, type MetaMap, RpcValueWithMetaData, type ShvMap, UInt, withOffset, makeMap, makeIMap, makeMetaMap, isIMap, isShvMap};
package/src/ws-client.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import {ChainPackReader, ChainpackProtocolType, ChainPackWriter} from './chainpack';
2
2
  import {type CponReader, CponProtocolType} from './cpon';
3
3
  import {ERROR_MESSAGE, ErrorCode, ERROR_CODE, RpcMessage, type RpcResponse, MethodCallTimeout} from './rpcmessage';
4
- import {type RpcValue, type Null, Int, IMap, ShvMap} from './rpcvalue';
4
+ import {type RpcValue, type Null, Int, type IMap, type ShvMap, makeMap, makeIMap} from './rpcvalue';
5
5
 
6
6
  const DEFAULT_TIMEOUT = 5000;
7
7
 
@@ -115,14 +115,14 @@ class WsClient {
115
115
  this.websocket.addEventListener('open', () => {
116
116
  this.logDebug('CONNECTED');
117
117
  this.callRpcMethod(undefined, 'hello').then(() => {
118
- const params = new ShvMap({
119
- login: new ShvMap({
118
+ const params = makeMap({
119
+ login: makeMap({
120
120
  password: this.password,
121
121
  type: this.loginType,
122
122
  user: this.user,
123
123
  }),
124
- options: new ShvMap({
125
- device: this.mountPoint === 'string' ? new ShvMap({mountPoint: this.mountPoint}) : undefined,
124
+ options: makeMap({
125
+ device: this.mountPoint === 'string' ? makeMap({mountPoint: this.mountPoint}) : undefined,
126
126
  }),
127
127
  });
128
128
  return this.callRpcMethod(undefined, 'login', params);
@@ -196,7 +196,7 @@ class WsClient {
196
196
 
197
197
  const promise = new Promise<RpcResponse>(resolve => {
198
198
  this.rpcHandlers[rq_id] = {resolve, timeout_handle: self.setTimeout(() => {
199
- resolve(new MethodCallTimeout(new IMap({
199
+ resolve(new MethodCallTimeout(makeIMap({
200
200
  [ERROR_CODE]: new Int(ErrorCode.MethodCallTimeout),
201
201
  [ERROR_MESSAGE]: `Shv call timeout after: ${this.timeout} msec.`,
202
202
  })));
@@ -236,7 +236,7 @@ class WsClient {
236
236
  }
237
237
  // If this path:method has not been subscribed on the broker, do it now
238
238
  if (!this.subscriptions.some(val => val.path === path && val.method === method)) {
239
- this.callRpcMethod('.broker/app', 'subscribe', new ShvMap({
239
+ this.callRpcMethod('.broker/app', 'subscribe', makeMap({
240
240
  method, path,
241
241
  })).catch(() => {
242
242
  this.logDebug(`Couldn't subscribe to ${path}, ${method}`);
@@ -261,7 +261,7 @@ class WsClient {
261
261
  if (this.subscriptions.some(val => val.path === path && val.method === method)) {
262
262
  return;
263
263
  }
264
- this.callRpcMethod('.broker/app', 'unsubscribe', new ShvMap({
264
+ this.callRpcMethod('.broker/app', 'unsubscribe', makeMap({
265
265
  method, path,
266
266
  })).catch(() => {
267
267
  this.logDebug(`Couldn't unsubscribe ${path}, ${method}`);
package/src/zod.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  import {z, type ZodType} from 'zod';
2
- import {IMap, Int, type RpcValue, ShvMap} from './rpcvalue';
2
+ import {type IMap, Int, isIMap, isShvMap, type RpcValue, type ShvMap} from './rpcvalue';
3
3
 
4
- export const map = <T extends Record<string, ZodType<any, any, any>>>(schema: T) => z.custom<ShvMap<{[K in keyof T]: z.infer<T[K]>}>>((data: RpcValue) => data instanceof ShvMap && z.object(schema).safeParse(data.value).success);
5
- export const recmap = <T extends ZodType<any, any, any>>(schema: T) => z.custom<ShvMap<Record<string, z.infer<T>>>>((data: RpcValue) => data instanceof ShvMap && z.record(z.string(), schema).safeParse(data.value).success);
6
- 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) => data instanceof IMap && z.object(schema).safeParse(data.value).success);
4
+ export const map = <T extends Record<string, ZodType<any, any, any>>>(schema: T) => z.custom<ShvMap<{[K in keyof T]: z.infer<T[K]>}>>((data: RpcValue) => isShvMap(data) && z.object(schema).safeParse(data).success);
5
+ export const recmap = <T extends ZodType<any, any, any>>(schema: T) => z.custom<ShvMap<Record<string, z.infer<T>>>>((data: RpcValue) => isShvMap(data) && z.record(z.string(), schema).safeParse(data).success);
6
+ 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) && z.object(schema).safeParse(data).success);
7
7
  export const int = () => z.custom<Int>((data: RpcValue) => data instanceof Int);
8
8
 
9
9
  export * from 'zod';
package/deno.json DELETED
@@ -1,8 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "lib": ["dom", "dom.iterable", "deno.window"]
4
- },
5
- "tasks": {
6
- "lint": "deno run --allow-read --allow-write --allow-net --allow-sys --allow-env npm:xo --reporter unix src/*"
7
- }
8
- }