@push-rpc/next 2.0.16 → 2.0.18
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/.prettierrc.json +1 -1
- package/dist/client/RemoteSubscriptions.d.ts +8 -1
- package/dist/client/RemoteSubscriptions.js +22 -5
- package/dist/client/RemoteSubscriptions.js.map +1 -1
- package/dist/client/RpcClientImpl.js +8 -1
- package/dist/client/RpcClientImpl.js.map +1 -1
- package/dist/client/index.d.ts +4 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/remote.js +1 -0
- package/dist/client/remote.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/package.json +1 -1
- package/src/client/RemoteSubscriptions.ts +37 -9
- package/src/client/RpcClientImpl.ts +11 -2
- package/src/client/index.ts +5 -1
- package/src/client/remote.ts +13 -12
- package/src/index.ts +1 -1
- package/tests/subscriptions.ts +55 -22
- package/dist/client/ClientCache.d.ts +0 -4
- package/dist/client/ClientCache.js +0 -3
- package/dist/client/ClientCache.js.map +0 -1
- package/src/client/ClientCache.ts +0 -4
package/.prettierrc.json
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { ClientCache } from "./
|
|
1
|
+
import { ClientCache } from "./index";
|
|
2
2
|
export declare class RemoteSubscriptions {
|
|
3
3
|
private cache;
|
|
4
4
|
constructor(cache: ClientCache | null);
|
|
5
5
|
unsubscribe(itemName: string, parameters: unknown[], consumer: (d: unknown) => void): boolean;
|
|
6
|
+
/** Add subscription in pending state */
|
|
6
7
|
addSubscription(itemName: string, parameters: unknown[], consumer: (d: unknown) => void): void;
|
|
7
8
|
pause(itemName: string, parameters: unknown[]): void;
|
|
8
9
|
unpause(itemName: string, parameters: unknown[]): void;
|
|
@@ -11,6 +12,7 @@ export declare class RemoteSubscriptions {
|
|
|
11
12
|
private removeSubscription;
|
|
12
13
|
getCached(itemName: string, parameters: unknown[]): unknown | undefined;
|
|
13
14
|
consume(itemName: string, parameters: unknown[], data: unknown): void;
|
|
15
|
+
getConsumerSubscription(itemName: string, parameters: unknown[], consumer: (d: unknown) => void): ConsumerSubscription | undefined;
|
|
14
16
|
getAllSubscriptions(): Array<[
|
|
15
17
|
itemName: string,
|
|
16
18
|
parameters: unknown[],
|
|
@@ -19,3 +21,8 @@ export declare class RemoteSubscriptions {
|
|
|
19
21
|
private getFilterSubscriptions;
|
|
20
22
|
private byItem;
|
|
21
23
|
}
|
|
24
|
+
type ConsumerSubscription = {
|
|
25
|
+
consumer: (d: unknown) => void;
|
|
26
|
+
completed: boolean;
|
|
27
|
+
};
|
|
28
|
+
export {};
|
|
@@ -11,6 +11,7 @@ class RemoteSubscriptions {
|
|
|
11
11
|
const parametersKey = getParametersKey(parameters);
|
|
12
12
|
return this.removeSubscription(itemName, parametersKey, consumer);
|
|
13
13
|
}
|
|
14
|
+
/** Add subscription in pending state */
|
|
14
15
|
addSubscription(itemName, parameters, consumer) {
|
|
15
16
|
const itemSubscriptions = this.byItem.get(itemName) || { byParameters: new Map() };
|
|
16
17
|
this.byItem.set(itemName, itemSubscriptions);
|
|
@@ -22,7 +23,10 @@ class RemoteSubscriptions {
|
|
|
22
23
|
queue: [],
|
|
23
24
|
};
|
|
24
25
|
itemSubscriptions.byParameters.set(parametersKey, parameterSubscriptions);
|
|
25
|
-
parameterSubscriptions.consumers.push(
|
|
26
|
+
parameterSubscriptions.consumers.push({
|
|
27
|
+
consumer,
|
|
28
|
+
completed: false,
|
|
29
|
+
});
|
|
26
30
|
}
|
|
27
31
|
pause(itemName, parameters) {
|
|
28
32
|
const filterSubscriptions = this.getFilterSubscriptions(itemName, parameters);
|
|
@@ -45,7 +49,9 @@ class RemoteSubscriptions {
|
|
|
45
49
|
this.cache.put(itemName, parameters, data);
|
|
46
50
|
filterSubscriptions.cached = data;
|
|
47
51
|
filterSubscriptions.consumers.forEach((consumer) => {
|
|
48
|
-
consumer
|
|
52
|
+
if (consumer.completed) {
|
|
53
|
+
consumer.consumer(data);
|
|
54
|
+
}
|
|
49
55
|
});
|
|
50
56
|
});
|
|
51
57
|
filterSubscriptions.queue = [];
|
|
@@ -63,7 +69,7 @@ class RemoteSubscriptions {
|
|
|
63
69
|
const filterSubscriptions = itemSubscriptions.byParameters.get(parametersKey);
|
|
64
70
|
if (!filterSubscriptions)
|
|
65
71
|
return false;
|
|
66
|
-
const index = filterSubscriptions.consumers.
|
|
72
|
+
const index = filterSubscriptions.consumers.findIndex((c) => c.consumer == consumer);
|
|
67
73
|
if (index == -1)
|
|
68
74
|
return false;
|
|
69
75
|
filterSubscriptions.consumers.splice(index, 1);
|
|
@@ -94,15 +100,26 @@ class RemoteSubscriptions {
|
|
|
94
100
|
this.cache.put(itemName, parameters, data);
|
|
95
101
|
filterSubscriptions.cached = data;
|
|
96
102
|
filterSubscriptions.consumers.forEach((consumer) => {
|
|
97
|
-
consumer
|
|
103
|
+
if (consumer.completed) {
|
|
104
|
+
consumer.consumer(data);
|
|
105
|
+
}
|
|
98
106
|
});
|
|
99
107
|
}
|
|
100
108
|
}
|
|
109
|
+
getConsumerSubscription(itemName, parameters, consumer) {
|
|
110
|
+
const filterSubscriptions = this.getFilterSubscriptions(itemName, parameters);
|
|
111
|
+
return (filterSubscriptions?.consumers || []).find((c) => c.consumer == consumer);
|
|
112
|
+
}
|
|
101
113
|
getAllSubscriptions() {
|
|
102
114
|
const result = [];
|
|
103
115
|
for (const [itemName, itemSubscriptions] of this.byItem) {
|
|
104
116
|
for (const [, parameterSubscriptions] of itemSubscriptions.byParameters) {
|
|
105
|
-
|
|
117
|
+
const consumers = parameterSubscriptions.consumers
|
|
118
|
+
.filter((c) => c.completed)
|
|
119
|
+
.map((c) => c.consumer);
|
|
120
|
+
if (consumers.length) {
|
|
121
|
+
result.push([itemName, parameterSubscriptions.parameters, consumers]);
|
|
122
|
+
}
|
|
106
123
|
}
|
|
107
124
|
}
|
|
108
125
|
return result;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RemoteSubscriptions.js","sourceRoot":"","sources":["../../src/client/RemoteSubscriptions.ts"],"names":[],"mappings":";;;AAAA,8CAA8C;
|
|
1
|
+
{"version":3,"file":"RemoteSubscriptions.js","sourceRoot":"","sources":["../../src/client/RemoteSubscriptions.ts"],"names":[],"mappings":"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"}
|
|
@@ -20,11 +20,18 @@ class RpcClientImpl {
|
|
|
20
20
|
if (cached !== undefined) {
|
|
21
21
|
consumer(cached);
|
|
22
22
|
}
|
|
23
|
+
// add subscription in pending state to test later if it was unsubscribed during connection wait
|
|
24
|
+
this.remoteSubscriptions.addSubscription(itemName, parameters, consumer);
|
|
23
25
|
// Needs to be awaited b/c resubscribe will make a 2nd request then.
|
|
24
26
|
// Also, server needs the connection to be established before making a subscription
|
|
25
27
|
await this.connection.connect();
|
|
26
28
|
try {
|
|
27
|
-
|
|
29
|
+
// check if already unsubscribed
|
|
30
|
+
const sub = this.remoteSubscriptions.getConsumerSubscription(itemName, parameters, consumer);
|
|
31
|
+
if (!sub)
|
|
32
|
+
return;
|
|
33
|
+
// mark as completed - will resubscribe on reconnects
|
|
34
|
+
sub.completed = true;
|
|
28
35
|
this.remoteSubscriptions.pause(itemName, parameters);
|
|
29
36
|
const data = await this.invoke(itemName, rpc_js_1.InvocationType.Subscribe, (...parameters) => this.httpClient.subscribe(itemName, parameters, callOptions?.timeout ?? this.options.callTimeout), parameters);
|
|
30
37
|
this.remoteSubscriptions.unpause(itemName, parameters);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RpcClientImpl.js","sourceRoot":"","sources":["../../src/client/RpcClientImpl.ts"],"names":[],"mappings":";;;AAAA,sCAA2E;AAC3E,mDAA0C;AAC1C,qEAA4D;AAC5D,qEAA4D;AAC5D,mCAA6B;AAC7B,2CAAmE;AAEnE,
|
|
1
|
+
{"version":3,"file":"RpcClientImpl.js","sourceRoot":"","sources":["../../src/client/RpcClientImpl.ts"],"names":[],"mappings":"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"}
|
package/dist/client/index.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { RpcContext, Services } from "../rpc.js";
|
|
2
2
|
import { ServicesWithSubscriptions } from "./remote.js";
|
|
3
3
|
import { Middleware } from "../utils/middleware.js";
|
|
4
|
-
import { ClientCache } from "./ClientCache";
|
|
5
4
|
export type RpcClient = {
|
|
6
5
|
readonly clientId: string;
|
|
7
6
|
connect(): Promise<void>;
|
|
@@ -10,6 +9,10 @@ export type RpcClient = {
|
|
|
10
9
|
_allSubscriptions(): Array<any[]>;
|
|
11
10
|
_webSocket(): WebSocket | null;
|
|
12
11
|
};
|
|
12
|
+
export type ClientCache = {
|
|
13
|
+
put(itemName: string, parameters: unknown[], value: unknown): void;
|
|
14
|
+
get(itemName: string, parameters: unknown[]): unknown | undefined;
|
|
15
|
+
};
|
|
13
16
|
export type ConsumeServicesOptions = {
|
|
14
17
|
callTimeout: number;
|
|
15
18
|
reconnectDelay: number;
|
package/dist/client/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":";;;AAEA,yDAAgD;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":";;;AAEA,yDAAgD;AAoCzC,KAAK,UAAU,eAAe,CACnC,GAAW,EACX,kBAAmD,EAAE;IAKrD,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAA;IAC5C,CAAC;IAED,MAAM,OAAO,GAAG;QACd,GAAG,cAAc;QACjB,GAAG,eAAe;KACnB,CAAA;IAED,MAAM,MAAM,GAAG,IAAI,gCAAa,CAAI,GAAG,EAAE,OAAO,CAAC,CAAA;IAEjD,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;QAC5B,MAAM,MAAM,CAAC,OAAO,EAAE,CAAA;IACxB,CAAC;IAED,OAAO;QACL,MAAM;QACN,MAAM,EAAE,MAAM,CAAC,YAAY,EAAE;KAC9B,CAAA;AACH,CAAC;AA1BD,0CA0BC;AAED,MAAM,cAAc,GAA2B;IAC7C,WAAW,EAAE,CAAC,GAAG,IAAI;IACrB,cAAc,EAAE,CAAC;IACjB,qBAAqB,EAAE,EAAE,GAAG,IAAI;IAChC,YAAY,EAAE,IAAI,EAAE,sDAAsD;IAC1E,aAAa,EAAE,IAAI;IACnB,UAAU,EAAE,EAAE;IACd,uBAAuB,EAAE,EAAE;IAC3B,eAAe,EAAE,KAAK;IACtB,WAAW,EAAE,GAAG,EAAE;IAClB,CAAC;IACD,cAAc,EAAE,GAAG,EAAE;IACrB,CAAC;IACD,UAAU,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;IAE5B,mBAAmB,CAAC,GAAW;QAC7B,OAAO,GAAG,CAAC,OAAO,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,MAAM,CAAC,CAAA;IACxE,CAAC;IACD,KAAK,EAAE,IAAI;CACZ,CAAA"}
|
package/dist/client/remote.js
CHANGED
|
@@ -18,6 +18,7 @@ function createRemote(hooks, name = "") {
|
|
|
18
18
|
const { params, callOptions } = extractCallOptions(paramsWithCallOptions);
|
|
19
19
|
return hooks.unsubscribe(name, params, consumer, callOptions);
|
|
20
20
|
},
|
|
21
|
+
itemName: name,
|
|
21
22
|
};
|
|
22
23
|
Object.assign(remoteItem, subscription);
|
|
23
24
|
// then add proxy creating subitems
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remote.js","sourceRoot":"","sources":["../../src/client/remote.ts"],"names":[],"mappings":";;;AAAA,sCAAyE;AAEzE,SAAgB,YAAY,CAC1B,KAAkB,EAClB,IAAI,GAAG,EAAE;IAET,6BAA6B;IAC7B,MAAM,UAAU,GAAG,CAAC,GAAG,qBAAgC,EAAE,EAAE;QACzD,MAAM,EAAC,MAAM,EAAE,WAAW,EAAC,GAAG,kBAAkB,CAAC,qBAAqB,CAAC,CAAA;QAEvE,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,CAAA;IAC9C,CAAC,CAAA;IAED,2BAA2B;IAC3B,MAAM,YAAY,GAAG;QACnB,SAAS,EAAE,CAAC,QAA8B,EAAE,GAAG,qBAAgC,EAAE,EAAE;YACjF,MAAM,EAAC,MAAM,EAAE,WAAW,EAAC,GAAG,kBAAkB,CAAC,qBAAqB,CAAC,CAAA;YACvE,OAAO,KAAK,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAA;QAC7D,CAAC;QACD,WAAW,EAAE,CAAC,QAA8B,EAAE,GAAG,qBAAgC,EAAE,EAAE;YACnF,MAAM,EAAC,MAAM,EAAE,WAAW,EAAC,GAAG,kBAAkB,CAAC,qBAAqB,CAAC,CAAA;YACvE,OAAO,KAAK,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAA;QAC/D,CAAC;
|
|
1
|
+
{"version":3,"file":"remote.js","sourceRoot":"","sources":["../../src/client/remote.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ export type { RpcServer, PublishServicesOptions } from "./server/index.js";
|
|
|
6
6
|
export type { HttpServerHooks } from "./server/http.js";
|
|
7
7
|
export { publishServices } from "./server/index.js";
|
|
8
8
|
export type { ServicesWithTriggers } from "./server/local.js";
|
|
9
|
-
export type { RpcClient, ConsumeServicesOptions } from "./client/index.js";
|
|
9
|
+
export type { RpcClient, ConsumeServicesOptions, ClientCache } from "./client/index.js";
|
|
10
10
|
export { consumeServices } from "./client/index.js";
|
|
11
11
|
export type { ServicesWithSubscriptions } from "./client/remote.js";
|
|
12
12
|
export { log, setLogger } from "./logger.js";
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {safeStringify} from "../utils/json.js"
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
import {ClientCache} from "./index"
|
|
3
4
|
|
|
4
5
|
export class RemoteSubscriptions {
|
|
5
|
-
constructor(private cache: ClientCache | null) {
|
|
6
|
-
}
|
|
6
|
+
constructor(private cache: ClientCache | null) {}
|
|
7
7
|
|
|
8
8
|
unsubscribe(itemName: string, parameters: unknown[], consumer: (d: unknown) => void): boolean {
|
|
9
9
|
const parametersKey = getParametersKey(parameters)
|
|
@@ -11,6 +11,7 @@ export class RemoteSubscriptions {
|
|
|
11
11
|
return this.removeSubscription(itemName, parametersKey, consumer)
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
/** Add subscription in pending state */
|
|
14
15
|
addSubscription(itemName: string, parameters: unknown[], consumer: (d: unknown) => void) {
|
|
15
16
|
const itemSubscriptions = this.byItem.get(itemName) || {byParameters: new Map()}
|
|
16
17
|
this.byItem.set(itemName, itemSubscriptions)
|
|
@@ -26,7 +27,10 @@ export class RemoteSubscriptions {
|
|
|
26
27
|
}
|
|
27
28
|
|
|
28
29
|
itemSubscriptions.byParameters.set(parametersKey, parameterSubscriptions)
|
|
29
|
-
parameterSubscriptions.consumers.push(
|
|
30
|
+
parameterSubscriptions.consumers.push({
|
|
31
|
+
consumer,
|
|
32
|
+
completed: false,
|
|
33
|
+
})
|
|
30
34
|
}
|
|
31
35
|
|
|
32
36
|
pause(itemName: string, parameters: unknown[]) {
|
|
@@ -51,7 +55,9 @@ export class RemoteSubscriptions {
|
|
|
51
55
|
if (this.cache) this.cache.put(itemName, parameters, data)
|
|
52
56
|
filterSubscriptions.cached = data
|
|
53
57
|
filterSubscriptions.consumers.forEach((consumer) => {
|
|
54
|
-
consumer
|
|
58
|
+
if (consumer.completed) {
|
|
59
|
+
consumer.consumer(data)
|
|
60
|
+
}
|
|
55
61
|
})
|
|
56
62
|
})
|
|
57
63
|
|
|
@@ -76,7 +82,7 @@ export class RemoteSubscriptions {
|
|
|
76
82
|
const filterSubscriptions = itemSubscriptions.byParameters.get(parametersKey)
|
|
77
83
|
if (!filterSubscriptions) return false
|
|
78
84
|
|
|
79
|
-
const index = filterSubscriptions.consumers.
|
|
85
|
+
const index = filterSubscriptions.consumers.findIndex((c) => c.consumer == consumer)
|
|
80
86
|
if (index == -1) return false
|
|
81
87
|
|
|
82
88
|
filterSubscriptions.consumers.splice(index, 1)
|
|
@@ -111,11 +117,22 @@ export class RemoteSubscriptions {
|
|
|
111
117
|
if (this.cache) this.cache.put(itemName, parameters, data)
|
|
112
118
|
filterSubscriptions.cached = data
|
|
113
119
|
filterSubscriptions.consumers.forEach((consumer) => {
|
|
114
|
-
consumer
|
|
120
|
+
if (consumer.completed) {
|
|
121
|
+
consumer.consumer(data)
|
|
122
|
+
}
|
|
115
123
|
})
|
|
116
124
|
}
|
|
117
125
|
}
|
|
118
126
|
|
|
127
|
+
getConsumerSubscription(
|
|
128
|
+
itemName: string,
|
|
129
|
+
parameters: unknown[],
|
|
130
|
+
consumer: (d: unknown) => void,
|
|
131
|
+
): ConsumerSubscription | undefined {
|
|
132
|
+
const filterSubscriptions = this.getFilterSubscriptions(itemName, parameters)
|
|
133
|
+
return (filterSubscriptions?.consumers || []).find((c) => c.consumer == consumer)
|
|
134
|
+
}
|
|
135
|
+
|
|
119
136
|
getAllSubscriptions(): Array<
|
|
120
137
|
[itemName: string, parameters: unknown[], consumers: Array<(d: unknown) => void>]
|
|
121
138
|
> {
|
|
@@ -123,7 +140,13 @@ export class RemoteSubscriptions {
|
|
|
123
140
|
|
|
124
141
|
for (const [itemName, itemSubscriptions] of this.byItem) {
|
|
125
142
|
for (const [, parameterSubscriptions] of itemSubscriptions.byParameters) {
|
|
126
|
-
|
|
143
|
+
const consumers = parameterSubscriptions.consumers
|
|
144
|
+
.filter((c) => c.completed)
|
|
145
|
+
.map((c) => c.consumer)
|
|
146
|
+
|
|
147
|
+
if (consumers.length) {
|
|
148
|
+
result.push([itemName, parameterSubscriptions.parameters, consumers])
|
|
149
|
+
}
|
|
127
150
|
}
|
|
128
151
|
}
|
|
129
152
|
|
|
@@ -155,12 +178,17 @@ type ItemSubscription = {
|
|
|
155
178
|
type ParametersSubscription = {
|
|
156
179
|
parameters: unknown[]
|
|
157
180
|
cached: unknown
|
|
158
|
-
consumers:
|
|
181
|
+
consumers: ConsumerSubscription[]
|
|
159
182
|
|
|
160
183
|
paused: boolean
|
|
161
184
|
queue: unknown[]
|
|
162
185
|
}
|
|
163
186
|
|
|
187
|
+
type ConsumerSubscription = {
|
|
188
|
+
consumer: (d: unknown) => void
|
|
189
|
+
completed: boolean
|
|
190
|
+
}
|
|
191
|
+
|
|
164
192
|
function getParametersKey(parameters: unknown[]) {
|
|
165
193
|
return safeStringify(parameters)
|
|
166
194
|
}
|
|
@@ -5,7 +5,7 @@ import {WebSocketConnection} from "./WebSocketConnection.js"
|
|
|
5
5
|
import {nanoid} from "nanoid"
|
|
6
6
|
import {createRemote, ServicesWithSubscriptions} from "./remote.js"
|
|
7
7
|
import {ConsumeServicesOptions, RpcClient} from "./index.js"
|
|
8
|
-
import {
|
|
8
|
+
import {withMiddlewares} from "../utils/middleware.js"
|
|
9
9
|
|
|
10
10
|
export class RpcClientImpl<S extends Services<S>> implements RpcClient {
|
|
11
11
|
constructor(
|
|
@@ -128,12 +128,21 @@ export class RpcClientImpl<S extends Services<S>> implements RpcClient {
|
|
|
128
128
|
consumer(cached)
|
|
129
129
|
}
|
|
130
130
|
|
|
131
|
+
// add subscription in pending state to test later if it was unsubscribed during connection wait
|
|
132
|
+
this.remoteSubscriptions.addSubscription(itemName, parameters, consumer)
|
|
133
|
+
|
|
131
134
|
// Needs to be awaited b/c resubscribe will make a 2nd request then.
|
|
132
135
|
// Also, server needs the connection to be established before making a subscription
|
|
133
136
|
await this.connection.connect()
|
|
134
137
|
|
|
135
138
|
try {
|
|
136
|
-
|
|
139
|
+
// check if already unsubscribed
|
|
140
|
+
const sub = this.remoteSubscriptions.getConsumerSubscription(itemName, parameters, consumer)
|
|
141
|
+
if (!sub) return
|
|
142
|
+
|
|
143
|
+
// mark as completed - will resubscribe on reconnects
|
|
144
|
+
sub.completed = true
|
|
145
|
+
|
|
137
146
|
this.remoteSubscriptions.pause(itemName, parameters)
|
|
138
147
|
|
|
139
148
|
const data = await this.invoke(
|
package/src/client/index.ts
CHANGED
|
@@ -2,7 +2,6 @@ import {RpcContext, Services} from "../rpc.js"
|
|
|
2
2
|
import {ServicesWithSubscriptions} from "./remote.js"
|
|
3
3
|
import {RpcClientImpl} from "./RpcClientImpl.js"
|
|
4
4
|
import {Middleware} from "../utils/middleware.js"
|
|
5
|
-
import {ClientCache} from "./ClientCache"
|
|
6
5
|
|
|
7
6
|
export type RpcClient = {
|
|
8
7
|
readonly clientId: string
|
|
@@ -16,6 +15,11 @@ export type RpcClient = {
|
|
|
16
15
|
_webSocket(): WebSocket | null
|
|
17
16
|
}
|
|
18
17
|
|
|
18
|
+
export type ClientCache = {
|
|
19
|
+
put(itemName: string, parameters: unknown[], value: unknown): void
|
|
20
|
+
get(itemName: string, parameters: unknown[]): unknown | undefined
|
|
21
|
+
}
|
|
22
|
+
|
|
19
23
|
export type ConsumeServicesOptions = {
|
|
20
24
|
callTimeout: number
|
|
21
25
|
reconnectDelay: number
|
package/src/client/remote.ts
CHANGED
|
@@ -2,7 +2,7 @@ import {CallOptions, Consumer, RemoteFunction, Services} from "../rpc.js"
|
|
|
2
2
|
|
|
3
3
|
export function createRemote<S extends Services<S>>(
|
|
4
4
|
hooks: RemoteHooks,
|
|
5
|
-
name = ""
|
|
5
|
+
name = "",
|
|
6
6
|
): ServicesWithSubscriptions<S> {
|
|
7
7
|
// start with remote function
|
|
8
8
|
const remoteItem = (...paramsWithCallOptions: unknown[]) => {
|
|
@@ -21,6 +21,7 @@ export function createRemote<S extends Services<S>>(
|
|
|
21
21
|
const {params, callOptions} = extractCallOptions(paramsWithCallOptions)
|
|
22
22
|
return hooks.unsubscribe(name, params, consumer, callOptions)
|
|
23
23
|
},
|
|
24
|
+
itemName: name,
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
Object.assign(remoteItem, subscription)
|
|
@@ -83,13 +84,13 @@ export type RemoteHooks = {
|
|
|
83
84
|
itemName: string,
|
|
84
85
|
parameters: unknown[],
|
|
85
86
|
consumer: (d: unknown) => void,
|
|
86
|
-
callOptions?: CallOptions
|
|
87
|
+
callOptions?: CallOptions,
|
|
87
88
|
): Promise<void>
|
|
88
89
|
unsubscribe(
|
|
89
90
|
itemName: string,
|
|
90
91
|
parameters: unknown[],
|
|
91
92
|
consumer: (d: unknown) => void,
|
|
92
|
-
callOptions?: CallOptions
|
|
93
|
+
callOptions?: CallOptions,
|
|
93
94
|
): Promise<void>
|
|
94
95
|
}
|
|
95
96
|
|
|
@@ -101,15 +102,15 @@ export type AddParameters<
|
|
|
101
102
|
export type ServicesWithSubscriptions<T extends Services<T>> = {
|
|
102
103
|
[K in keyof T]: T[K] extends RemoteFunction
|
|
103
104
|
? AddParameters<T[K], [CallOptions?]> & {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
105
|
+
subscribe(
|
|
106
|
+
consumer: Consumer<T[K]>,
|
|
107
|
+
...parameters: [...Parameters<T[K]>, CallOptions?]
|
|
108
|
+
): Promise<void>
|
|
109
|
+
unsubscribe(
|
|
110
|
+
consumer: Consumer<T[K]>,
|
|
111
|
+
...parameters: [...Parameters<T[K]>, CallOptions?]
|
|
112
|
+
): Promise<void>
|
|
113
|
+
}
|
|
113
114
|
: T[K] extends object
|
|
114
115
|
? ServicesWithSubscriptions<T[K]>
|
|
115
116
|
: never
|
package/src/index.ts
CHANGED
|
@@ -10,7 +10,7 @@ export {publishServices} from "./server/index.js"
|
|
|
10
10
|
|
|
11
11
|
export type {ServicesWithTriggers} from "./server/local.js"
|
|
12
12
|
|
|
13
|
-
export type {RpcClient, ConsumeServicesOptions} from "./client/index.js"
|
|
13
|
+
export type {RpcClient, ConsumeServicesOptions, ClientCache} from "./client/index.js"
|
|
14
14
|
export {consumeServices} from "./client/index.js"
|
|
15
15
|
|
|
16
16
|
export type {ServicesWithSubscriptions} from "./client/remote.js"
|
package/tests/subscriptions.ts
CHANGED
|
@@ -4,6 +4,7 @@ import {adelay} from "../src/utils/promises.js"
|
|
|
4
4
|
import {CallOptions, RpcConnectionContext, RpcErrors} from "../src/index.js"
|
|
5
5
|
import {IncomingMessage} from "http"
|
|
6
6
|
import {CLIENT_ID_HEADER} from "../src/rpc.js"
|
|
7
|
+
import WebSocket from "ws"
|
|
7
8
|
|
|
8
9
|
describe("Subscriptions", () => {
|
|
9
10
|
it("subscribe delivers data", async () => {
|
|
@@ -70,8 +71,7 @@ describe("Subscriptions", () => {
|
|
|
70
71
|
const client = await createTestClient<typeof services>()
|
|
71
72
|
|
|
72
73
|
try {
|
|
73
|
-
await client.item.subscribe(() => {
|
|
74
|
-
})
|
|
74
|
+
await client.item.subscribe(() => {})
|
|
75
75
|
assert.fail("Error expected")
|
|
76
76
|
} catch (e: any) {
|
|
77
77
|
assert.equal(e.message, "AA")
|
|
@@ -90,8 +90,7 @@ describe("Subscriptions", () => {
|
|
|
90
90
|
const remote = await createTestClient<typeof services>()
|
|
91
91
|
|
|
92
92
|
remote.item
|
|
93
|
-
.subscribe(() => {
|
|
94
|
-
})
|
|
93
|
+
.subscribe(() => {})
|
|
95
94
|
.catch((e: any) => {
|
|
96
95
|
// ignored
|
|
97
96
|
})
|
|
@@ -280,8 +279,7 @@ describe("Subscriptions", () => {
|
|
|
280
279
|
|
|
281
280
|
const remote = await createTestClient<typeof server>()
|
|
282
281
|
|
|
283
|
-
await remote.testUnsub.item.subscribe(() => {
|
|
284
|
-
})
|
|
282
|
+
await remote.testUnsub.item.subscribe(() => {})
|
|
285
283
|
|
|
286
284
|
assert.equal(1, testServer?._allSubscriptions().length)
|
|
287
285
|
|
|
@@ -340,10 +338,8 @@ describe("Subscriptions", () => {
|
|
|
340
338
|
|
|
341
339
|
const remote = await createTestClient<typeof services>()
|
|
342
340
|
|
|
343
|
-
const sub1 = () => {
|
|
344
|
-
}
|
|
345
|
-
const sub2 = () => {
|
|
346
|
-
}
|
|
341
|
+
const sub1 = () => {}
|
|
342
|
+
const sub2 = () => {}
|
|
347
343
|
|
|
348
344
|
await remote.item.subscribe(sub1)
|
|
349
345
|
await adelay(20)
|
|
@@ -375,8 +371,7 @@ describe("Subscriptions", () => {
|
|
|
375
371
|
|
|
376
372
|
const remote = await createTestClient<typeof services>()
|
|
377
373
|
|
|
378
|
-
const sub = () => {
|
|
379
|
-
}
|
|
374
|
+
const sub = () => {}
|
|
380
375
|
|
|
381
376
|
await remote.item.subscribe(sub)
|
|
382
377
|
await adelay(20)
|
|
@@ -402,10 +397,8 @@ describe("Subscriptions", () => {
|
|
|
402
397
|
|
|
403
398
|
const remote = await createTestClient<typeof services>()
|
|
404
399
|
|
|
405
|
-
const sub1 = () => {
|
|
406
|
-
}
|
|
407
|
-
const sub2 = () => {
|
|
408
|
-
}
|
|
400
|
+
const sub1 = () => {}
|
|
401
|
+
const sub2 = () => {}
|
|
409
402
|
|
|
410
403
|
await remote.item.subscribe(sub1)
|
|
411
404
|
await adelay(20)
|
|
@@ -439,8 +432,7 @@ describe("Subscriptions", () => {
|
|
|
439
432
|
delivered = r
|
|
440
433
|
}
|
|
441
434
|
|
|
442
|
-
const sub2 = () => {
|
|
443
|
-
}
|
|
435
|
+
const sub2 = () => {}
|
|
444
436
|
|
|
445
437
|
await client.test.item.subscribe(sub1)
|
|
446
438
|
|
|
@@ -469,8 +461,7 @@ describe("Subscriptions", () => {
|
|
|
469
461
|
|
|
470
462
|
const client = await createTestClient<typeof services>()
|
|
471
463
|
|
|
472
|
-
const sub = () => {
|
|
473
|
-
}
|
|
464
|
+
const sub = () => {}
|
|
474
465
|
client.item.subscribe(sub)
|
|
475
466
|
|
|
476
467
|
await adelay(10)
|
|
@@ -483,6 +474,49 @@ describe("Subscriptions", () => {
|
|
|
483
474
|
assert.equal(testServer!._allSubscriptions().length, 0)
|
|
484
475
|
})
|
|
485
476
|
|
|
477
|
+
it("unsubscribe while disconnected bug", async () => {
|
|
478
|
+
const services = await startTestServer({
|
|
479
|
+
item: async () => {
|
|
480
|
+
return 1
|
|
481
|
+
},
|
|
482
|
+
})
|
|
483
|
+
|
|
484
|
+
// delay client connection open by 10ms
|
|
485
|
+
let oldAddEL: typeof WebSocket.prototype.addEventListener
|
|
486
|
+
|
|
487
|
+
oldAddEL = WebSocket.prototype.addEventListener
|
|
488
|
+
WebSocket.prototype.addEventListener = function (eventName: any, callback: any) {
|
|
489
|
+
if (eventName == "open") {
|
|
490
|
+
oldAddEL.apply(this, [
|
|
491
|
+
eventName,
|
|
492
|
+
() => {
|
|
493
|
+
setTimeout(callback, 10)
|
|
494
|
+
},
|
|
495
|
+
])
|
|
496
|
+
|
|
497
|
+
return
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
return oldAddEL.apply(this, [eventName, callback])
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
const client = await createTestClient<typeof services>()
|
|
504
|
+
|
|
505
|
+
const sub = () => {}
|
|
506
|
+
client.item.subscribe(sub)
|
|
507
|
+
|
|
508
|
+
await adelay(10)
|
|
509
|
+
|
|
510
|
+
client.item.unsubscribe(sub)
|
|
511
|
+
|
|
512
|
+
await adelay(40)
|
|
513
|
+
|
|
514
|
+
assert.equal(testClient!._allSubscriptions().length, 0)
|
|
515
|
+
assert.equal(testServer!._allSubscriptions().length, 0)
|
|
516
|
+
|
|
517
|
+
WebSocket.prototype.addEventListener = oldAddEL
|
|
518
|
+
})
|
|
519
|
+
|
|
486
520
|
it("skip unchanged data", async () => {
|
|
487
521
|
const item = {r: "1"}
|
|
488
522
|
|
|
@@ -529,8 +563,7 @@ describe("Subscriptions", () => {
|
|
|
529
563
|
})
|
|
530
564
|
|
|
531
565
|
try {
|
|
532
|
-
await client.test.longOp.subscribe(() => {
|
|
533
|
-
}, new CallOptions({timeout: callTimeout}))
|
|
566
|
+
await client.test.longOp.subscribe(() => {}, new CallOptions({timeout: callTimeout}))
|
|
534
567
|
assert.fail()
|
|
535
568
|
} catch (e: any) {
|
|
536
569
|
assert.equal(e.code, RpcErrors.Timeout)
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ClientCache.js","sourceRoot":"","sources":["../../src/client/ClientCache.ts"],"names":[],"mappings":""}
|