libshv-js 7.1.13 → 8.0.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.
package/dist/ws-client.js CHANGED
@@ -1,12 +1,9 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.WsClient = exports.NotImplemented = exports.UserIDRequired = exports.LoginRequired = exports.Unknown = exports.MethodCallException = exports.MethodCallCancelled = exports.MethodCallTimeout = exports.ParseError = exports.InternalError = exports.InvalidParams = exports.MethodNotFound = exports.InvalidRequest = exports.DIR_EXTRA = exports.DIR_SIGNALS = exports.DIR_ACCESS = exports.DIR_RESULT = exports.DIR_PARAM = exports.DIR_FLAGS = exports.DIR_NAME = exports.DirFlags = exports.validateDirParam = exports.validateLsParam = exports.RequestHandler = void 0;
4
- const access_1 = require("./access");
5
- const chainpack_1 = require("./chainpack");
6
- const cpon_1 = require("./cpon");
7
- const rpcmessage_1 = require("./rpcmessage");
8
- const rpcvalue_1 = require("./rpcvalue");
9
- const utils_1 = require("./utils");
1
+ import { accessLevelFromAccessString } from './access.js';
2
+ import { ChainPackReader, CHAINPACK_PROTOCOL_TYPE, ChainPackWriter, toChainPack } from './chainpack.js';
3
+ import { CPON_PROTOCOL_TYPE, toCpon } from './cpon.js';
4
+ import { ERROR_MESSAGE, ErrorCode, ERROR_CODE, isSignal, isRequest, isResponse, ERROR_DATA, RPC_MESSAGE_METHOD, RPC_MESSAGE_SHV_PATH, RPC_MESSAGE_REQUEST_ID, RPC_MESSAGE_PARAMS, RPC_MESSAGE_ERROR, RPC_MESSAGE_RESULT, RPC_MESSAGE_CALLER_IDS, RPC_MESSAGE_DELAY, RPC_MESSAGE_ABORT, RPC_MESSAGE_ACCESS_LEVEL, RPC_MESSAGE_USER_ID } from './rpcmessage.js';
5
+ import { makeMap, makeIMap, RpcValueWithMetaData, makeMetaMap, Double } from './rpcvalue.js';
6
+ import { resolveRI } from './utils.js';
10
7
  const DEFAULT_TIMEOUT = 5000;
11
8
  const DEFAULT_PING_INTERVAL = 30 * 1000;
12
9
  const defaultParseMessage = (rpcVal) => {
@@ -15,13 +12,13 @@ const defaultParseMessage = (rpcVal) => {
15
12
  return rpcMsg;
16
13
  };
17
14
  const dataToRpcValue = (buff) => {
18
- const rd = new chainpack_1.ChainPackReader(buff);
15
+ const rd = new ChainPackReader(buff);
19
16
  rd.readUIntData();
20
17
  const proto = rd.ctx.getByte();
21
18
  switch (proto) {
22
- case chainpack_1.CHAINPACK_PROTOCOL_TYPE:
19
+ case CHAINPACK_PROTOCOL_TYPE:
23
20
  break;
24
- case cpon_1.CPON_PROTOCOL_TYPE:
21
+ case CPON_PROTOCOL_TYPE:
25
22
  throw new Error('CPON protocol type is not supported anymore');
26
23
  default:
27
24
  throw new Error(`Unsupported protocol type ${proto}`);
@@ -29,19 +26,16 @@ const dataToRpcValue = (buff) => {
29
26
  const rpcVal = rd.read();
30
27
  return rpcVal;
31
28
  };
32
- class RequestHandler {
29
+ export class RequestHandler {
33
30
  options;
34
31
  constructor(options) {
35
32
  this.options = options;
36
33
  // nothing
37
34
  }
38
35
  }
39
- exports.RequestHandler = RequestHandler;
40
- const validateLsParam = (param) => param === undefined || typeof param === 'string';
41
- exports.validateLsParam = validateLsParam;
42
- const validateDirParam = (param) => param === undefined || typeof param === 'string' || typeof param === 'boolean';
43
- exports.validateDirParam = validateDirParam;
44
- var DirFlags;
36
+ export const validateLsParam = (param) => param === undefined || typeof param === 'string';
37
+ export const validateDirParam = (param) => param === undefined || typeof param === 'string' || typeof param === 'boolean';
38
+ export var DirFlags;
45
39
  (function (DirFlags) {
46
40
  DirFlags[DirFlags["Reserved"] = 1] = "Reserved";
47
41
  DirFlags[DirFlags["Getter"] = 2] = "Getter";
@@ -49,49 +43,49 @@ var DirFlags;
49
43
  DirFlags[DirFlags["LargeResultHint"] = 8] = "LargeResultHint";
50
44
  DirFlags[DirFlags["NotIdempotent"] = 16] = "NotIdempotent";
51
45
  DirFlags[DirFlags["RequiresClientId"] = 32] = "RequiresClientId";
52
- })(DirFlags || (exports.DirFlags = DirFlags = {}));
53
- exports.DIR_NAME = 1;
54
- exports.DIR_FLAGS = 2;
55
- exports.DIR_PARAM = 3;
56
- exports.DIR_RESULT = 4;
57
- exports.DIR_ACCESS = 5;
58
- exports.DIR_SIGNALS = 6;
59
- exports.DIR_EXTRA = 63;
46
+ })(DirFlags || (DirFlags = {}));
47
+ export const DIR_NAME = 1;
48
+ export const DIR_FLAGS = 2;
49
+ export const DIR_PARAM = 3;
50
+ export const DIR_RESULT = 4;
51
+ export const DIR_ACCESS = 5;
52
+ export const DIR_SIGNALS = 6;
53
+ export const DIR_EXTRA = 63;
60
54
  class RpcError extends Error {
61
55
  err_info;
62
56
  constructor(err_info) {
63
57
  const errorCodeToMessage = (code) => {
64
58
  switch (code) {
65
- case rpcmessage_1.ErrorCode.InvalidRequest: return 'InvalidRequest';
66
- case rpcmessage_1.ErrorCode.MethodNotFound: return 'MethodNotFound';
67
- case rpcmessage_1.ErrorCode.InvalidParams: return 'InvalidParams';
68
- case rpcmessage_1.ErrorCode.InternalError: return 'InternalError';
69
- case rpcmessage_1.ErrorCode.ParseError: return 'ParseError';
70
- case rpcmessage_1.ErrorCode.MethodCallTimeout: return 'MethodCallTimeout';
71
- case rpcmessage_1.ErrorCode.MethodCallCancelled: return 'MethodCallCancelled';
72
- case rpcmessage_1.ErrorCode.MethodCallException: return 'MethodCallException';
73
- case rpcmessage_1.ErrorCode.Unknown: return 'Unknown';
74
- case rpcmessage_1.ErrorCode.LoginRequired: return 'LoginRequired';
75
- case rpcmessage_1.ErrorCode.UserIDRequired: return 'UserIDRequired';
76
- case rpcmessage_1.ErrorCode.NotImplemented: return 'NotImplemented';
59
+ case ErrorCode.InvalidRequest: return 'InvalidRequest';
60
+ case ErrorCode.MethodNotFound: return 'MethodNotFound';
61
+ case ErrorCode.InvalidParams: return 'InvalidParams';
62
+ case ErrorCode.InternalError: return 'InternalError';
63
+ case ErrorCode.ParseError: return 'ParseError';
64
+ case ErrorCode.MethodCallTimeout: return 'MethodCallTimeout';
65
+ case ErrorCode.MethodCallCancelled: return 'MethodCallCancelled';
66
+ case ErrorCode.MethodCallException: return 'MethodCallException';
67
+ case ErrorCode.Unknown: return 'Unknown';
68
+ case ErrorCode.LoginRequired: return 'LoginRequired';
69
+ case ErrorCode.UserIDRequired: return 'UserIDRequired';
70
+ case ErrorCode.NotImplemented: return 'NotImplemented';
77
71
  default: return 'Unknown RpcError';
78
72
  }
79
73
  };
80
- super(err_info[rpcmessage_1.ERROR_MESSAGE] ?? `${errorCodeToMessage(err_info[rpcmessage_1.ERROR_CODE])} (${err_info[rpcmessage_1.ERROR_CODE]})`);
74
+ super(err_info[ERROR_MESSAGE] ?? `${errorCodeToMessage(err_info[ERROR_CODE])} (${err_info[ERROR_CODE]})`);
81
75
  this.err_info = err_info;
82
76
  }
83
77
  data() {
84
- return this.err_info[rpcmessage_1.ERROR_DATA];
78
+ return this.err_info[ERROR_DATA];
85
79
  }
86
80
  }
87
81
  const makeErrInfo = (errInfoOrMsg, code) => {
88
82
  if (typeof errInfoOrMsg === 'object') {
89
83
  return errInfoOrMsg;
90
84
  }
91
- return (0, rpcvalue_1.makeIMap)({
92
- [rpcmessage_1.ERROR_CODE]: code,
93
- [rpcmessage_1.ERROR_MESSAGE]: errInfoOrMsg,
94
- [rpcmessage_1.ERROR_DATA]: undefined,
85
+ return makeIMap({
86
+ [ERROR_CODE]: code,
87
+ [ERROR_MESSAGE]: errInfoOrMsg,
88
+ [ERROR_DATA]: undefined,
95
89
  });
96
90
  };
97
91
  const createErrorClass = (code) => class extends RpcError {
@@ -100,24 +94,24 @@ const createErrorClass = (code) => class extends RpcError {
100
94
  }
101
95
  };
102
96
  /* eslint-disable @typescript-eslint/naming-convention -- We want class names like this */
103
- exports.InvalidRequest = createErrorClass(rpcmessage_1.ErrorCode.InvalidRequest);
104
- exports.MethodNotFound = createErrorClass(rpcmessage_1.ErrorCode.MethodNotFound);
105
- exports.InvalidParams = createErrorClass(rpcmessage_1.ErrorCode.InvalidParams);
106
- exports.InternalError = createErrorClass(rpcmessage_1.ErrorCode.InternalError);
107
- exports.ParseError = createErrorClass(rpcmessage_1.ErrorCode.ParseError);
108
- exports.MethodCallTimeout = createErrorClass(rpcmessage_1.ErrorCode.MethodCallTimeout);
109
- exports.MethodCallCancelled = createErrorClass(rpcmessage_1.ErrorCode.MethodCallCancelled);
110
- exports.MethodCallException = createErrorClass(rpcmessage_1.ErrorCode.MethodCallException);
111
- exports.Unknown = createErrorClass(rpcmessage_1.ErrorCode.Unknown);
112
- exports.LoginRequired = createErrorClass(rpcmessage_1.ErrorCode.LoginRequired);
113
- exports.UserIDRequired = createErrorClass(rpcmessage_1.ErrorCode.UserIDRequired);
114
- exports.NotImplemented = createErrorClass(rpcmessage_1.ErrorCode.NotImplemented);
97
+ export const InvalidRequest = createErrorClass(ErrorCode.InvalidRequest);
98
+ export const MethodNotFound = createErrorClass(ErrorCode.MethodNotFound);
99
+ export const InvalidParams = createErrorClass(ErrorCode.InvalidParams);
100
+ export const InternalError = createErrorClass(ErrorCode.InternalError);
101
+ export const ParseError = createErrorClass(ErrorCode.ParseError);
102
+ export const MethodCallTimeout = createErrorClass(ErrorCode.MethodCallTimeout);
103
+ export const MethodCallCancelled = createErrorClass(ErrorCode.MethodCallCancelled);
104
+ export const MethodCallException = createErrorClass(ErrorCode.MethodCallException);
105
+ export const Unknown = createErrorClass(ErrorCode.Unknown);
106
+ export const LoginRequired = createErrorClass(ErrorCode.LoginRequired);
107
+ export const UserIDRequired = createErrorClass(ErrorCode.UserIDRequired);
108
+ export const NotImplemented = createErrorClass(ErrorCode.NotImplemented);
115
109
  /* eslint-enable @typescript-eslint/naming-convention */
116
110
  const makeTimeout = (ms, resolve) => setTimeout(() => {
117
- resolve(new exports.MethodCallTimeout((0, rpcvalue_1.makeIMap)({
118
- [rpcmessage_1.ERROR_CODE]: rpcmessage_1.ErrorCode.MethodCallTimeout,
119
- [rpcmessage_1.ERROR_MESSAGE]: `Shv call timeout after: ${ms} msec.`,
120
- [rpcmessage_1.ERROR_DATA]: undefined,
111
+ resolve(new MethodCallTimeout(makeIMap({
112
+ [ERROR_CODE]: ErrorCode.MethodCallTimeout,
113
+ [ERROR_MESSAGE]: `Shv call timeout after: ${ms} msec.`,
114
+ [ERROR_DATA]: undefined,
121
115
  })));
122
116
  }, ms);
123
117
  class RpcRequestPromise extends Promise {
@@ -155,10 +149,10 @@ class WsClient {
155
149
  this.websocket.binaryType = 'arraybuffer';
156
150
  const handleSignal = (signal) => {
157
151
  for (const sub of this.subscriptions) {
158
- const shvPath = signal.meta[rpcmessage_1.RPC_MESSAGE_SHV_PATH];
159
- const signalName = signal.meta[rpcmessage_1.RPC_MESSAGE_METHOD];
152
+ const shvPath = signal.meta[RPC_MESSAGE_SHV_PATH];
153
+ const signalName = signal.meta[RPC_MESSAGE_METHOD];
160
154
  if (shvPath.startsWith(sub.path) && signalName === sub.signal) {
161
- sub.callback(shvPath, signalName, signal.value[rpcmessage_1.RPC_MESSAGE_PARAMS]);
155
+ sub.callback(shvPath, signalName, signal.value[RPC_MESSAGE_PARAMS]);
162
156
  }
163
157
  }
164
158
  };
@@ -167,40 +161,40 @@ class WsClient {
167
161
  if (!('onRequest' in this.options)) {
168
162
  return;
169
163
  }
170
- const requestId = request.meta[rpcmessage_1.RPC_MESSAGE_REQUEST_ID];
164
+ const requestId = request.meta[RPC_MESSAGE_REQUEST_ID];
171
165
  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,
166
+ this.sendRpcMessage(new RpcValueWithMetaData(makeMetaMap({
167
+ [RPC_MESSAGE_CALLER_IDS]: request.meta[RPC_MESSAGE_CALLER_IDS],
168
+ [RPC_MESSAGE_REQUEST_ID]: requestId,
175
169
  }), value));
176
170
  };
177
171
  const sendDelay = (progress) => {
178
- respond((0, rpcvalue_1.makeIMap)({
179
- [rpcmessage_1.RPC_MESSAGE_DELAY]: new rpcvalue_1.Double(progress),
172
+ respond(makeIMap({
173
+ [RPC_MESSAGE_DELAY]: new Double(progress),
180
174
  }));
181
175
  };
182
176
  // eslint-disable-next-line unicorn/no-computed-property-existence-check
183
- if (rpcmessage_1.RPC_MESSAGE_ABORT in request.value) {
177
+ if (RPC_MESSAGE_ABORT in request.value) {
184
178
  const requestHandler = this.requestHandlers.get(requestId);
185
- if (request.value[rpcmessage_1.RPC_MESSAGE_ABORT]) {
179
+ if (request.value[RPC_MESSAGE_ABORT]) {
186
180
  this.abortedRequests.add(requestId);
187
181
  if (requestHandler?.options.onAbort !== undefined) {
188
182
  requestHandler.options.onAbort();
189
183
  }
190
184
  }
191
- if (!request.value[rpcmessage_1.RPC_MESSAGE_ABORT] && requestHandler?.options.onProgressQuery !== undefined) {
185
+ if (!request.value[RPC_MESSAGE_ABORT] && requestHandler?.options.onProgressQuery !== undefined) {
192
186
  const progress = requestHandler.options.onProgressQuery();
193
187
  sendDelay(progress instanceof Promise ? await progress : progress);
194
188
  }
195
189
  return;
196
190
  }
197
191
  try {
198
- const shvPath = request.meta[rpcmessage_1.RPC_MESSAGE_SHV_PATH];
199
- const methodName = request.meta[rpcmessage_1.RPC_MESSAGE_METHOD];
192
+ const shvPath = request.meta[RPC_MESSAGE_SHV_PATH];
193
+ const methodName = request.meta[RPC_MESSAGE_METHOD];
200
194
  const unhandledMethod = () => {
201
- throw new exports.MethodNotFound(`No such path '${shvPath}' or method '${methodName}' or insufficient access rights.`);
195
+ throw new MethodNotFound(`No such path '${shvPath}' or method '${methodName}' or insufficient access rights.`);
202
196
  };
203
- const accessLevel = request.meta[rpcmessage_1.RPC_MESSAGE_ACCESS_LEVEL];
197
+ const accessLevel = request.meta[RPC_MESSAGE_ACCESS_LEVEL];
204
198
  if (accessLevel === undefined) {
205
199
  unhandledMethod();
206
200
  return;
@@ -211,34 +205,34 @@ class WsClient {
211
205
  return;
212
206
  }
213
207
  const methodDefinition = (() => {
214
- const dirEntry = (0, rpcvalue_1.makeIMap)({
215
- [exports.DIR_NAME]: 'dir',
216
- [exports.DIR_FLAGS]: 0,
217
- [exports.DIR_PARAM]: 'DirParam',
218
- [exports.DIR_RESULT]: 'DirResult',
219
- [exports.DIR_ACCESS]: (0, access_1.accessLevelFromAccessString)('bws'),
220
- [exports.DIR_SIGNALS]: (0, rpcvalue_1.makeMap)({}),
221
- [exports.DIR_EXTRA]: (0, rpcvalue_1.makeMap)({}),
208
+ const dirEntry = makeIMap({
209
+ [DIR_NAME]: 'dir',
210
+ [DIR_FLAGS]: 0,
211
+ [DIR_PARAM]: 'DirParam',
212
+ [DIR_RESULT]: 'DirResult',
213
+ [DIR_ACCESS]: accessLevelFromAccessString('bws'),
214
+ [DIR_SIGNALS]: makeMap({}),
215
+ [DIR_EXTRA]: makeMap({}),
222
216
  });
223
- const lsEntry = (0, rpcvalue_1.makeIMap)({
224
- [exports.DIR_NAME]: 'ls',
225
- [exports.DIR_FLAGS]: 0,
226
- [exports.DIR_PARAM]: 'LsParam',
227
- [exports.DIR_RESULT]: 'LsResult',
228
- [exports.DIR_ACCESS]: (0, access_1.accessLevelFromAccessString)('bws'),
229
- [exports.DIR_SIGNALS]: (0, rpcvalue_1.makeMap)({}),
230
- [exports.DIR_EXTRA]: (0, rpcvalue_1.makeMap)({}),
217
+ const lsEntry = makeIMap({
218
+ [DIR_NAME]: 'ls',
219
+ [DIR_FLAGS]: 0,
220
+ [DIR_PARAM]: 'LsParam',
221
+ [DIR_RESULT]: 'LsResult',
222
+ [DIR_ACCESS]: accessLevelFromAccessString('bws'),
223
+ [DIR_SIGNALS]: makeMap({}),
224
+ [DIR_EXTRA]: makeMap({}),
231
225
  });
232
226
  switch (methodName) {
233
227
  case 'dir':
234
228
  return {
235
229
  entry: dirEntry,
236
- paramValidator: exports.validateDirParam,
230
+ paramValidator: validateDirParam,
237
231
  handler(_shvPath, _method, param) {
238
232
  const methodsResult = [dirEntry, lsEntry, ...methods.dirEntries.map(method => method.entry)];
239
233
  switch (true) {
240
234
  case typeof param === 'string':
241
- return methodsResult.find(method => method[exports.DIR_NAME] === param) ?? false;
235
+ return methodsResult.find(method => method[DIR_NAME] === param) ?? false;
242
236
  case typeof param === 'boolean':
243
237
  case param === undefined:
244
238
  console.log('methodsResult', '=', methodsResult);
@@ -249,34 +243,34 @@ class WsClient {
249
243
  case 'ls':
250
244
  return {
251
245
  entry: lsEntry,
252
- paramValidator: exports.validateLsParam,
246
+ paramValidator: validateLsParam,
253
247
  handler(shvPath) {
254
248
  return methods.ls(shvPath);
255
249
  },
256
250
  };
257
251
  default:
258
- return methods.dirEntries.find(method => method.entry[exports.DIR_NAME] === methodName);
252
+ return methods.dirEntries.find(method => method.entry[DIR_NAME] === methodName);
259
253
  }
260
254
  })();
261
255
  if (methodDefinition === undefined) {
262
256
  unhandledMethod();
263
257
  return;
264
258
  }
265
- if (accessLevel < methodDefinition.entry[exports.DIR_ACCESS]) {
259
+ if (accessLevel < methodDefinition.entry[DIR_ACCESS]) {
266
260
  unhandledMethod();
267
261
  return;
268
262
  }
269
- const requestParam = request.value[rpcmessage_1.RPC_MESSAGE_PARAMS];
263
+ const requestParam = request.value[RPC_MESSAGE_PARAMS];
270
264
  if (methodDefinition.paramValidator !== undefined && !methodDefinition.paramValidator(requestParam)) {
271
- throw new exports.InvalidParams(`Unexpected param '${shvPath}:${methodName}': ${(0, cpon_1.toCpon)(requestParam)}`);
265
+ throw new InvalidParams(`Unexpected param '${shvPath}:${methodName}': ${toCpon(requestParam)}`);
272
266
  }
273
267
  let result = methodDefinition.handler(shvPath, methodName, requestParam, sendDelay);
274
268
  if (result instanceof RequestHandler) {
275
269
  this.requestHandlers.set(requestId, result);
276
270
  result = result.options.result;
277
271
  }
278
- const resultOrError = (0, rpcvalue_1.makeIMap)({
279
- [rpcmessage_1.RPC_MESSAGE_RESULT]: result instanceof Promise ? await result : result,
272
+ const resultOrError = makeIMap({
273
+ [RPC_MESSAGE_RESULT]: result instanceof Promise ? await result : result,
280
274
  });
281
275
  if (!this.abortedRequests.has(requestId)) {
282
276
  respond(resultOrError);
@@ -290,8 +284,8 @@ class WsClient {
290
284
  }
291
285
  catch (error) {
292
286
  const sendError = (error) => {
293
- respond((0, rpcvalue_1.makeIMap)({
294
- [rpcmessage_1.RPC_MESSAGE_ERROR]: error.err_info,
287
+ respond(makeIMap({
288
+ [RPC_MESSAGE_ERROR]: error.err_info,
295
289
  }));
296
290
  };
297
291
  switch (true) {
@@ -299,54 +293,54 @@ class WsClient {
299
293
  sendError(error);
300
294
  break;
301
295
  case error instanceof Error:
302
- sendError(new exports.InternalError(error.message));
296
+ sendError(new InternalError(error.message));
303
297
  break;
304
298
  default:
305
- sendError(new exports.InternalError('Unknown error'));
299
+ sendError(new InternalError('Unknown error'));
306
300
  break;
307
301
  }
308
302
  }
309
303
  };
310
304
  const handleResponse = (response) => {
311
- const requestId = response.meta[rpcmessage_1.RPC_MESSAGE_REQUEST_ID];
305
+ const requestId = response.meta[RPC_MESSAGE_REQUEST_ID];
312
306
  if (this.rpcHandlers[requestId] !== undefined) {
313
307
  const handler = this.rpcHandlers[requestId];
314
308
  clearTimeout(handler.timeout_handle);
315
309
  // eslint-disable-next-line unicorn/no-computed-property-existence-check
316
- if (rpcmessage_1.RPC_MESSAGE_DELAY in response.value) {
310
+ if (RPC_MESSAGE_DELAY in response.value) {
317
311
  if (handler.delayCallback !== undefined) {
318
- handler.delayCallback(response.value[rpcmessage_1.RPC_MESSAGE_DELAY].value);
312
+ handler.delayCallback(response.value[RPC_MESSAGE_DELAY].value);
319
313
  }
320
314
  handler.timeout_handle = makeTimeout(this.timeout, handler.resolve);
321
315
  return;
322
316
  }
323
317
  handler.resolve((() => {
324
318
  // eslint-disable-next-line unicorn/no-computed-property-existence-check
325
- if (rpcmessage_1.RPC_MESSAGE_ERROR in response.value) {
326
- const code = response.value[rpcmessage_1.RPC_MESSAGE_ERROR][rpcmessage_1.ERROR_CODE];
319
+ if (RPC_MESSAGE_ERROR in response.value) {
320
+ const code = response.value[RPC_MESSAGE_ERROR][ERROR_CODE];
327
321
  // eslint-disable-next-line @typescript-eslint/naming-convention
328
322
  const ErrorTypeCtor = (() => {
329
323
  switch (code) {
330
- case rpcmessage_1.ErrorCode.InvalidRequest: return exports.InvalidRequest;
331
- case rpcmessage_1.ErrorCode.MethodNotFound: return exports.MethodNotFound;
332
- case rpcmessage_1.ErrorCode.InvalidParams: return exports.InvalidParams;
333
- case rpcmessage_1.ErrorCode.InternalError: return exports.InternalError;
334
- case rpcmessage_1.ErrorCode.ParseError: return exports.ParseError;
335
- case rpcmessage_1.ErrorCode.MethodCallTimeout: return exports.MethodCallTimeout;
336
- case rpcmessage_1.ErrorCode.MethodCallCancelled: return exports.MethodCallCancelled;
337
- case rpcmessage_1.ErrorCode.MethodCallException: return exports.MethodCallException;
338
- case rpcmessage_1.ErrorCode.Unknown: return exports.Unknown;
339
- case rpcmessage_1.ErrorCode.LoginRequired: return exports.LoginRequired;
340
- case rpcmessage_1.ErrorCode.UserIDRequired: return exports.UserIDRequired;
341
- case rpcmessage_1.ErrorCode.NotImplemented: return exports.NotImplemented;
342
- default: return exports.Unknown;
324
+ case ErrorCode.InvalidRequest: return InvalidRequest;
325
+ case ErrorCode.MethodNotFound: return MethodNotFound;
326
+ case ErrorCode.InvalidParams: return InvalidParams;
327
+ case ErrorCode.InternalError: return InternalError;
328
+ case ErrorCode.ParseError: return ParseError;
329
+ case ErrorCode.MethodCallTimeout: return MethodCallTimeout;
330
+ case ErrorCode.MethodCallCancelled: return MethodCallCancelled;
331
+ case ErrorCode.MethodCallException: return MethodCallException;
332
+ case ErrorCode.Unknown: return Unknown;
333
+ case ErrorCode.LoginRequired: return LoginRequired;
334
+ case ErrorCode.UserIDRequired: return UserIDRequired;
335
+ case ErrorCode.NotImplemented: return NotImplemented;
336
+ default: return Unknown;
343
337
  }
344
338
  })();
345
- return new ErrorTypeCtor(response.value[rpcmessage_1.RPC_MESSAGE_ERROR]);
339
+ return new ErrorTypeCtor(response.value[RPC_MESSAGE_ERROR]);
346
340
  }
347
341
  // eslint-disable-next-line unicorn/no-computed-property-existence-check
348
- if (rpcmessage_1.RPC_MESSAGE_RESULT in response.value) {
349
- return response.value[rpcmessage_1.RPC_MESSAGE_RESULT];
342
+ if (RPC_MESSAGE_RESULT in response.value) {
343
+ return response.value[RPC_MESSAGE_RESULT];
350
344
  }
351
345
  // At this point, the RpcResponse either has:
352
346
  // - no keys, which means that the response has an implicit Null result.
@@ -354,7 +348,7 @@ class WsClient {
354
348
  // https://silicon-heaven.github.io/shv-doc/rpcmessage.html#response
355
349
  const rpcMessageKeys = Object.keys(response.value);
356
350
  if (rpcMessageKeys.length !== 0) {
357
- return new exports.NotImplemented(`Got an RpcResponse with unsupported keys: ${rpcMessageKeys.join(' ')}`);
351
+ return new NotImplemented(`Got an RpcResponse with unsupported keys: ${rpcMessageKeys.join(' ')}`);
358
352
  }
359
353
  })());
360
354
  // eslint-disable-next-line @typescript-eslint/no-array-delete, @typescript-eslint/no-dynamic-delete
@@ -366,14 +360,14 @@ class WsClient {
366
360
  const rpcVal = dataToRpcValue(evt.data);
367
361
  const parseMessage = this.options.parseMessage ?? defaultParseMessage;
368
362
  const rpcMsg = parseMessage(rpcVal);
369
- this.logDebug(`message received: ${(0, cpon_1.toCpon)(rpcMsg)}`);
370
- if ((0, rpcmessage_1.isSignal)(rpcMsg)) {
363
+ this.logDebug(`message received: ${toCpon(rpcMsg)}`);
364
+ if (isSignal(rpcMsg)) {
371
365
  handleSignal(rpcMsg);
372
366
  }
373
- else if ((0, rpcmessage_1.isRequest)(rpcMsg)) {
367
+ else if (isRequest(rpcMsg)) {
374
368
  await handleRequest(rpcMsg);
375
369
  }
376
- else if ((0, rpcmessage_1.isResponse)(rpcMsg)) {
370
+ else if (isResponse(rpcMsg)) {
377
371
  handleResponse(rpcMsg);
378
372
  }
379
373
  });
@@ -433,10 +427,10 @@ class WsClient {
433
427
  this.sendPing();
434
428
  }, options.pingInterval ?? DEFAULT_PING_INTERVAL);
435
429
  };
436
- const makeLoginParams = (loginMap) => (0, rpcvalue_1.makeMap)({
430
+ const makeLoginParams = (loginMap) => makeMap({
437
431
  login: loginMap,
438
- options: (0, rpcvalue_1.makeMap)({
439
- device: typeof options.mountPoint === 'string' ? (0, rpcvalue_1.makeMap)({ mountPoint: options.mountPoint }) : undefined,
432
+ options: makeMap({
433
+ device: typeof options.mountPoint === 'string' ? makeMap({ mountPoint: options.mountPoint }) : undefined,
440
434
  }),
441
435
  });
442
436
  this.callRpcMethod(undefined, 'hello').then(response => {
@@ -447,13 +441,13 @@ class WsClient {
447
441
  const makeLoginMap = () => {
448
442
  switch (options.login.type) {
449
443
  case 'PLAIN':
450
- return (0, rpcvalue_1.makeMap)({
444
+ return makeMap({
451
445
  password: options.login.password,
452
446
  type: options.login.type,
453
447
  user: options.login.user,
454
448
  });
455
449
  case 'TOKEN':
456
- return (0, rpcvalue_1.makeMap)({
450
+ return makeMap({
457
451
  token: options.login.token,
458
452
  type: options.login.type,
459
453
  });
@@ -473,16 +467,19 @@ class WsClient {
473
467
  }
474
468
  callRpcMethod(shvPath, method, params, options) {
475
469
  const rqId = this.requestId++;
476
- const makeRq = (value) => new rpcvalue_1.RpcValueWithMetaData((0, rpcvalue_1.makeMetaMap)({
477
- [rpcmessage_1.RPC_MESSAGE_CALLER_IDS]: undefined,
478
- [rpcmessage_1.RPC_MESSAGE_REQUEST_ID]: rqId,
479
- [rpcmessage_1.RPC_MESSAGE_METHOD]: method ?? '',
480
- [rpcmessage_1.RPC_MESSAGE_SHV_PATH]: shvPath ?? '',
481
- ...(options?.requestUserId === true && { [rpcmessage_1.RPC_MESSAGE_USER_ID]: '' }),
470
+ const makeRq = (value) => new RpcValueWithMetaData(makeMetaMap({
471
+ [RPC_MESSAGE_CALLER_IDS]: undefined,
472
+ [RPC_MESSAGE_REQUEST_ID]: rqId,
473
+ [RPC_MESSAGE_METHOD]: method ?? '',
474
+ [RPC_MESSAGE_SHV_PATH]: shvPath ?? '',
475
+ ...(options?.requestUserId === true && { [RPC_MESSAGE_USER_ID]: '' }),
482
476
  }), value);
483
- let rq = makeRq((0, rpcvalue_1.makeIMap)({
484
- [rpcmessage_1.RPC_MESSAGE_PARAMS]: params,
485
- }));
477
+ // We will not add an explicit null as a param unless the user requests it. Receivers of RpcCalls should
478
+ // generally handle a missing param the same as if the param was Null.
479
+ const paramRaw = params !== undefined || (options?.explicitNullParam ?? false) ? {
480
+ [RPC_MESSAGE_PARAMS]: params,
481
+ } : {};
482
+ let rq = makeRq(makeIMap(paramRaw));
486
483
  if (options?.beforeSendHook !== undefined) {
487
484
  rq = options.beforeSendHook(rq);
488
485
  }
@@ -490,12 +487,12 @@ class WsClient {
490
487
  const promise = new RpcRequestPromise(resolve => {
491
488
  this.rpcHandlers[rqId] = { resolve, timeout_handle: makeTimeout(this.timeout, resolve), delayCallback: options?.delayCallback };
492
489
  }, () => {
493
- this.sendRpcMessage(makeRq((0, rpcvalue_1.makeIMap)({
494
- [rpcmessage_1.RPC_MESSAGE_ABORT]: true,
490
+ this.sendRpcMessage(makeRq(makeIMap({
491
+ [RPC_MESSAGE_ABORT]: true,
495
492
  })));
496
493
  }, () => {
497
- this.sendRpcMessage(makeRq((0, rpcvalue_1.makeIMap)({
498
- [rpcmessage_1.RPC_MESSAGE_ABORT]: false,
494
+ this.sendRpcMessage(makeRq(makeIMap({
495
+ [RPC_MESSAGE_ABORT]: false,
499
496
  })));
500
497
  });
501
498
  return promise;
@@ -504,16 +501,16 @@ class WsClient {
504
501
  if (this.websocket.readyState !== WebSocket.OPEN) {
505
502
  return;
506
503
  }
507
- this.logDebug('sending rpc message:', (0, cpon_1.toCpon)(rpcMsg));
508
- const msgData = new Uint8Array((0, chainpack_1.toChainPack)(rpcMsg));
509
- const wr = new chainpack_1.ChainPackWriter();
504
+ this.logDebug('sending rpc message:', toCpon(rpcMsg));
505
+ const msgData = new Uint8Array(toChainPack(rpcMsg));
506
+ const wr = new ChainPackWriter();
510
507
  wr.writeUIntData(msgData.length + 1);
511
508
  const dgram = new Uint8Array(wr.ctx.length + 1 + msgData.length);
512
509
  let ix = 0;
513
510
  for (let i = 0; i < wr.ctx.length; i++) {
514
511
  dgram[ix++] = wr.ctx.data[i];
515
512
  }
516
- dgram[ix++] = chainpack_1.CHAINPACK_PROTOCOL_TYPE;
513
+ dgram[ix++] = CHAINPACK_PROTOCOL_TYPE;
517
514
  for (const msgDatum of msgData) {
518
515
  dgram[ix++] = msgDatum;
519
516
  }
@@ -536,7 +533,7 @@ class WsClient {
536
533
  return this.shvApiVersion;
537
534
  }
538
535
  async subscribe(subscriber, riGetter, callback) {
539
- const ri = await (0, utils_1.resolveRI)(riGetter);
536
+ const ri = await resolveRI(riGetter);
540
537
  const path = ri.path();
541
538
  const signal = ri.signal();
542
539
  if (this.subscriptions.some(val => val.subscriber === subscriber && val.path === path && val.signal === signal)) {
@@ -547,7 +544,7 @@ class WsClient {
547
544
  if (this.subscriptions.every(val => !(val.path === path && val.signal === signal))) {
548
545
  switch (await this.getShvApiVersion()) {
549
546
  case ShvApiVersion.V2: {
550
- const result = await this.callRpcMethod('.broker/app', 'subscribe', (0, rpcvalue_1.makeMap)({ signal, path }));
547
+ const result = await this.callRpcMethod('.broker/app', 'subscribe', makeMap({ signal, path }));
551
548
  if (result instanceof Error) {
552
549
  this.logDebug(`Couldn't subscribe to ${path}, ${signal}`);
553
550
  }
@@ -575,7 +572,7 @@ class WsClient {
575
572
  });
576
573
  }
577
574
  async unsubscribe(subscriber, riGetter) {
578
- const ri = await (0, utils_1.resolveRI)(riGetter);
575
+ const ri = await resolveRI(riGetter);
579
576
  const path = ri.path();
580
577
  const signal = ri.signal();
581
578
  const idx = this.subscriptions.findIndex(val => val.subscriber === subscriber && val.path === path && val.signal === signal);
@@ -590,14 +587,14 @@ class WsClient {
590
587
  }
591
588
  switch (await this.getShvApiVersion()) {
592
589
  case ShvApiVersion.V2: {
593
- const result = await this.callRpcMethod('.broker/app', 'unsubscribe', (0, rpcvalue_1.makeMap)({ signal, path }));
590
+ const result = await this.callRpcMethod('.broker/app', 'unsubscribe', makeMap({ signal, path }));
594
591
  if (result instanceof Error) {
595
592
  this.logDebug(`Couldn't unsubscribe ${path}, ${signal}`);
596
593
  }
597
594
  break;
598
595
  }
599
596
  case ShvApiVersion.V3: {
600
- const result = await this.callRpcMethod('.broker/currentClient', 'unsubscribe', (0, rpcvalue_1.makeMap)({ ri: ri.asString(), ttl: undefined }));
597
+ const result = await this.callRpcMethod('.broker/currentClient', 'unsubscribe', makeMap({ ri: ri.asString(), ttl: undefined }));
601
598
  if (result instanceof Error) {
602
599
  this.logDebug(`Couldn't unsubscribe ${path}, ${signal}`);
603
600
  }
@@ -626,4 +623,4 @@ class WsClient {
626
623
  this.options.logDebug(...args);
627
624
  }
628
625
  }
629
- exports.WsClient = WsClient;
626
+ export { WsClient };
package/package.json CHANGED
@@ -1,9 +1,10 @@
1
1
  {
2
2
  "name": "libshv-js",
3
- "version": "7.1.13",
3
+ "version": "8.0.0",
4
4
  "description": "Typescript implementation of libshv",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
+ "type": "module",
7
8
  "files": [
8
9
  "dist"
9
10
  ],