libshv-js 7.2.0 → 8.0.1

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