libshv-js 3.1.3 → 3.1.6
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 +5 -3
- package/src/ws-client.ts +34 -7
- package/src/zod.ts +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "libshv-js",
|
|
3
|
-
"version": "3.1.
|
|
3
|
+
"version": "3.1.6",
|
|
4
4
|
"description": "Typescript implementation of libshv",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
@@ -24,9 +24,11 @@
|
|
|
24
24
|
"./ws-client.ts": "./src/ws-client.ts",
|
|
25
25
|
"./zod.ts": "./src/zod.ts"
|
|
26
26
|
},
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"zod": "^3.23.8"
|
|
29
|
+
},
|
|
27
30
|
"devDependencies": {
|
|
28
31
|
"typescript": "^5.5.4",
|
|
29
|
-
"xo": "^0.59.3"
|
|
30
|
-
"zod": "^3.23.8"
|
|
32
|
+
"xo": "^0.59.3"
|
|
31
33
|
}
|
|
32
34
|
}
|
package/src/ws-client.ts
CHANGED
|
@@ -26,6 +26,7 @@ type SubscriptionCallback = (path: string, method: string, param?: RpcValue) =>
|
|
|
26
26
|
type RpcResponseResolver = (rpc_msg: RpcResponse) => void;
|
|
27
27
|
|
|
28
28
|
type Subscription = {
|
|
29
|
+
subscriber: string;
|
|
29
30
|
path: string;
|
|
30
31
|
method: string;
|
|
31
32
|
callback: SubscriptionCallback;
|
|
@@ -135,6 +136,7 @@ class WsClient {
|
|
|
135
136
|
|
|
136
137
|
this.websocket.addEventListener('close', () => {
|
|
137
138
|
this.logDebug('DISCONNECTED');
|
|
139
|
+
this.subscriptions.length = 0;
|
|
138
140
|
this.onDisconnected();
|
|
139
141
|
});
|
|
140
142
|
|
|
@@ -227,20 +229,45 @@ class WsClient {
|
|
|
227
229
|
}
|
|
228
230
|
}
|
|
229
231
|
|
|
230
|
-
subscribe(path: string, method: string, callback: SubscriptionCallback) {
|
|
231
|
-
this.
|
|
232
|
-
method
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
232
|
+
subscribe(subscriber: string, path: string, method: string, callback: SubscriptionCallback) {
|
|
233
|
+
if (this.subscriptions.some(val => val.subscriber === subscriber && val.path === path && val.method === method)) {
|
|
234
|
+
this.logDebug(`Already subscribed {$path}:${method} for subscriber ${subscriber}`);
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
// If this path:method has not been subscribed on the broker, do it now
|
|
238
|
+
if (!this.subscriptions.some(val => val.path === path && val.method === method)) {
|
|
239
|
+
this.callRpcMethod('.broker/app', 'subscribe', new ShvMap({
|
|
240
|
+
method, path,
|
|
241
|
+
})).catch(() => {
|
|
242
|
+
this.logDebug(`Couldn't subscribe to ${path}, ${method}`);
|
|
243
|
+
});
|
|
244
|
+
}
|
|
237
245
|
this.subscriptions.push({
|
|
246
|
+
subscriber,
|
|
238
247
|
path,
|
|
239
248
|
method,
|
|
240
249
|
callback,
|
|
241
250
|
});
|
|
242
251
|
}
|
|
243
252
|
|
|
253
|
+
unsubscribe(subscriber: string, path: string, method: string) {
|
|
254
|
+
const idx = this.subscriptions.findIndex(val => val.subscriber === subscriber && val.path === path && val.method === method);
|
|
255
|
+
if (idx === -1) {
|
|
256
|
+
this.logDebug(`No such subscription ${path}:${method} for subscriber ${subscriber}`);
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
this.subscriptions.splice(idx, 1);
|
|
260
|
+
// Unsubscribe on the broker only if there are no other subscriptions of this path:method
|
|
261
|
+
if (this.subscriptions.some(val => val.path === path && val.method === method)) {
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
this.callRpcMethod('.broker/app', 'unsubscribe', new ShvMap({
|
|
265
|
+
method, path,
|
|
266
|
+
})).catch(() => {
|
|
267
|
+
this.logDebug(`Couldn't unsubscribe ${path}, ${method}`);
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
|
|
244
271
|
close() {
|
|
245
272
|
this.websocket.close();
|
|
246
273
|
}
|
package/src/zod.ts
CHANGED
|
@@ -2,6 +2,7 @@ import {z, type ZodType} from 'zod';
|
|
|
2
2
|
import {IMap, Int, type RpcValue, ShvMap} from './rpcvalue';
|
|
3
3
|
|
|
4
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);
|
|
5
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);
|
|
6
7
|
export const int = () => z.custom<Int>((data: RpcValue) => data instanceof Int);
|
|
7
8
|
|