libshv-js 3.12.1 → 3.13.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/package.json +3 -2
- package/src/rpcmessage.ts +2 -0
- package/src/ws-client.ts +29 -9
- package/src/zod.ts +0 -1
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "libshv-js",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.13.0",
|
|
4
4
|
"description": "Typescript implementation of libshv",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "echo \"Error: no test specified\" && exit 1",
|
|
7
7
|
"lint": "eslint --format unix src/",
|
|
8
|
-
"fix": "npm run lint -- --fix"
|
|
8
|
+
"fix": "npm run lint -- --fix",
|
|
9
|
+
"typecheck": "tsc --noEmit"
|
|
9
10
|
},
|
|
10
11
|
"author": "Elektroline",
|
|
11
12
|
"repository": {
|
package/src/rpcmessage.ts
CHANGED
|
@@ -4,6 +4,7 @@ export const RPC_MESSAGE_REQUEST_ID = 8;
|
|
|
4
4
|
export const RPC_MESSAGE_SHV_PATH = 9;
|
|
5
5
|
export const RPC_MESSAGE_METHOD = 10;
|
|
6
6
|
export const RPC_MESSAGE_CALLER_IDS = 11;
|
|
7
|
+
export const RPC_MESSAGE_ACCESS_LEVEL = 17;
|
|
7
8
|
|
|
8
9
|
export const RPC_MESSAGE_PARAMS = 1;
|
|
9
10
|
export const RPC_MESSAGE_RESULT = 2;
|
|
@@ -43,6 +44,7 @@ const RpcRequestMetaZod = z.metamap({
|
|
|
43
44
|
[RPC_MESSAGE_REQUEST_ID]: z.number(),
|
|
44
45
|
[RPC_MESSAGE_METHOD]: z.string(),
|
|
45
46
|
[RPC_MESSAGE_SHV_PATH]: z.string(),
|
|
47
|
+
[RPC_MESSAGE_ACCESS_LEVEL]: z.int().gte(0).lte(63).optional(),
|
|
46
48
|
});
|
|
47
49
|
|
|
48
50
|
const RpcRequestValueZod = z.imap({
|
package/src/ws-client.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {ChainPackReader, CHAINPACK_PROTOCOL_TYPE, ChainPackWriter, toChainPack} from './chainpack';
|
|
2
2
|
import {type CponReader, CPON_PROTOCOL_TYPE, toCpon} from './cpon';
|
|
3
|
-
import {ERROR_MESSAGE, ErrorCode, ERROR_CODE, RpcMessageZod, type RpcMessage, isSignal, isRequest, type RpcRequest, isResponse, ERROR_DATA, type ErrorMap, RPC_MESSAGE_METHOD, RPC_MESSAGE_SHV_PATH, RPC_MESSAGE_REQUEST_ID, RPC_MESSAGE_PARAMS, RPC_MESSAGE_ERROR, RPC_MESSAGE_RESULT, RPC_MESSAGE_CALLER_IDS, RpcResponseValue, RPC_MESSAGE_DELAY, RPC_MESSAGE_ABORT, RpcSignal, RpcResponse} from './rpcmessage';
|
|
3
|
+
import {ERROR_MESSAGE, ErrorCode, ERROR_CODE, RpcMessageZod, type RpcMessage, isSignal, isRequest, type RpcRequest, isResponse, ERROR_DATA, type ErrorMap, RPC_MESSAGE_METHOD, RPC_MESSAGE_SHV_PATH, RPC_MESSAGE_REQUEST_ID, RPC_MESSAGE_PARAMS, RPC_MESSAGE_ERROR, RPC_MESSAGE_RESULT, RPC_MESSAGE_CALLER_IDS, RpcResponseValue, RPC_MESSAGE_DELAY, RPC_MESSAGE_ABORT, RpcSignal, RpcResponse, RPC_MESSAGE_ACCESS_LEVEL} from './rpcmessage';
|
|
4
4
|
import {type RpcValue, type Null, type Int, type IMap, type ShvMap, makeMap, makeIMap, RpcValueWithMetaData, makeMetaMap, Double} from './rpcvalue';
|
|
5
5
|
|
|
6
6
|
const DEFAULT_TIMEOUT = 5000;
|
|
@@ -60,6 +60,14 @@ export class RequestHandler {
|
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
+
type RequestHandlerParams = {
|
|
64
|
+
shvPath: string;
|
|
65
|
+
method: string;
|
|
66
|
+
param: RpcValue;
|
|
67
|
+
accessLevel: number;
|
|
68
|
+
delay: (progress: number) => void;
|
|
69
|
+
};
|
|
70
|
+
|
|
63
71
|
type WsClientOptionsLogin = WsClientOptionsCommon & {
|
|
64
72
|
mountPoint?: string;
|
|
65
73
|
login: Login;
|
|
@@ -68,7 +76,7 @@ type WsClientOptionsLogin = WsClientOptionsCommon & {
|
|
|
68
76
|
onConnected: () => void;
|
|
69
77
|
onConnectionFailure: (error: Error) => void;
|
|
70
78
|
onDisconnected: () => void;
|
|
71
|
-
onRequest: (
|
|
79
|
+
onRequest: (request: RequestHandlerParams) => RpcValue | Promise<RpcValue> | RequestHandler;
|
|
72
80
|
};
|
|
73
81
|
|
|
74
82
|
type WsClientOptionsWorkflows = WsClientOptionsCommon & {
|
|
@@ -94,7 +102,7 @@ export const DIR_RESULT = 4;
|
|
|
94
102
|
export const DIR_ACCESS = 5;
|
|
95
103
|
export const DIR_SIGNALS = 6;
|
|
96
104
|
export const DIR_EXTRA = 63;
|
|
97
|
-
type DirResult = Array<IMap<{
|
|
105
|
+
export type DirResult = Array<IMap<{
|
|
98
106
|
[DIR_NAME]: string;
|
|
99
107
|
[DIR_FLAGS]: DirFlags;
|
|
100
108
|
[DIR_PARAM]: string | Null;
|
|
@@ -187,7 +195,7 @@ class WsClient {
|
|
|
187
195
|
delayCallback?: (progress: number) => void;
|
|
188
196
|
timeout_handle: ReturnType<typeof globalThis.setTimeout>;
|
|
189
197
|
}> = [];
|
|
190
|
-
private requestHandlers
|
|
198
|
+
private requestHandlers = new Map<number, RequestHandler>();
|
|
191
199
|
private abortedRequests = new Set<number>();
|
|
192
200
|
private readonly subscriptions: Subscription[] = [];
|
|
193
201
|
private readonly websocket: WebSocket;
|
|
@@ -236,7 +244,7 @@ class WsClient {
|
|
|
236
244
|
};
|
|
237
245
|
|
|
238
246
|
if (RPC_MESSAGE_ABORT in request.value) {
|
|
239
|
-
const requestHandler = this.requestHandlers
|
|
247
|
+
const requestHandler = this.requestHandlers.get(requestId);
|
|
240
248
|
|
|
241
249
|
if (request.value[RPC_MESSAGE_ABORT] === true && requestHandler?.options.onAbort !== undefined) {
|
|
242
250
|
this.abortedRequests.add(requestId);
|
|
@@ -252,9 +260,22 @@ class WsClient {
|
|
|
252
260
|
}
|
|
253
261
|
|
|
254
262
|
try {
|
|
255
|
-
|
|
263
|
+
const shvPath = request.meta[RPC_MESSAGE_SHV_PATH];
|
|
264
|
+
const method = request.meta[RPC_MESSAGE_METHOD];
|
|
265
|
+
const accessLevel = request.meta[RPC_MESSAGE_ACCESS_LEVEL];
|
|
266
|
+
if (accessLevel === undefined) {
|
|
267
|
+
throw new MethodNotFound(`Unknown method ${method} on path ${shvPath}`);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
let result = this.options.onRequest({
|
|
271
|
+
shvPath,
|
|
272
|
+
method,
|
|
273
|
+
param: request.value[RPC_MESSAGE_PARAMS],
|
|
274
|
+
accessLevel,
|
|
275
|
+
delay: sendDelay,
|
|
276
|
+
});
|
|
256
277
|
if (result instanceof RequestHandler) {
|
|
257
|
-
this.requestHandlers
|
|
278
|
+
this.requestHandlers.set(requestId, result);
|
|
258
279
|
result = result.options.result;
|
|
259
280
|
}
|
|
260
281
|
|
|
@@ -269,8 +290,7 @@ class WsClient {
|
|
|
269
290
|
}
|
|
270
291
|
|
|
271
292
|
if (requestId in this.requestHandlers) {
|
|
272
|
-
|
|
273
|
-
delete this.requestHandlers[requestId];
|
|
293
|
+
this.requestHandlers.delete(requestId);
|
|
274
294
|
}
|
|
275
295
|
} catch (error: unknown) {
|
|
276
296
|
const sendError = (error: RpcError) => {
|
package/src/zod.ts
CHANGED
|
@@ -29,7 +29,6 @@ export const map = <T extends Record<string, ZodType<any>>>(schema: T) => implMa
|
|
|
29
29
|
export const imap = <T extends Record<number, ZodType<any>>>(schema: T) => implMakeMapParser(isIMap, 'imap', 'IMap', z.object(schema));
|
|
30
30
|
export const metamap = <T extends Record<string | number, ZodType<any>>>(schema: T) => implMakeMapParser(isMetaMap, 'metamap', 'MetaMap', z.object(schema));
|
|
31
31
|
export const recmap = <T extends ZodType<any>>(schema: T) => implMakeMapParser(val => isShvMap(val) || isIMap(val), 'map', 'ShvMap', z.record(z.any(), schema));
|
|
32
|
-
export const int = () => z.number();
|
|
33
32
|
|
|
34
33
|
export const uint = () => z.instanceof(UInt<number>);
|
|
35
34
|
export const double = () => z.instanceof(Double);
|