@push-rpc/next 2.0.12 → 2.0.13

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.
Files changed (70) hide show
  1. package/dist/client/HttpClient.d.ts +11 -0
  2. package/dist/client/HttpClient.js +84 -0
  3. package/dist/client/HttpClient.js.map +1 -0
  4. package/dist/client/RemoteSubscriptions.d.ts +18 -0
  5. package/dist/client/RemoteSubscriptions.js +120 -0
  6. package/dist/client/RemoteSubscriptions.js.map +1 -0
  7. package/dist/client/RpcClientImpl.d.ts +22 -0
  8. package/dist/client/RpcClientImpl.js +121 -0
  9. package/dist/client/RpcClientImpl.js.map +1 -0
  10. package/dist/client/WebSocketConnection.d.ts +36 -0
  11. package/dist/client/WebSocketConnection.js +161 -0
  12. package/dist/client/WebSocketConnection.js.map +1 -0
  13. package/dist/client/index.d.ts +29 -0
  14. package/dist/client/index.js +39 -0
  15. package/dist/client/index.js.map +1 -0
  16. package/dist/client/remote.d.ts +14 -0
  17. package/dist/client/remote.js +66 -0
  18. package/dist/client/remote.js.map +1 -0
  19. package/dist/index.d.ts +13 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/logger.d.ts +8 -0
  22. package/dist/logger.js +9 -0
  23. package/dist/logger.js.map +1 -0
  24. package/dist/rpc.d.ts +37 -0
  25. package/dist/rpc.js +33 -0
  26. package/dist/rpc.js.map +1 -0
  27. package/dist/server/ConnectionsServer.d.ts +13 -0
  28. package/dist/server/ConnectionsServer.js +72 -0
  29. package/dist/server/ConnectionsServer.js.map +1 -0
  30. package/dist/server/LocalSubscriptions.d.ts +12 -0
  31. package/dist/server/LocalSubscriptions.js +113 -0
  32. package/dist/server/LocalSubscriptions.js.map +1 -0
  33. package/dist/server/RpcServerImpl.d.ts +24 -0
  34. package/dist/server/RpcServerImpl.js +200 -0
  35. package/dist/server/RpcServerImpl.js.map +1 -0
  36. package/dist/server/http.d.ts +9 -0
  37. package/dist/server/http.js +89 -0
  38. package/dist/server/http.js.map +1 -0
  39. package/dist/server/index.d.ts +32 -0
  40. package/dist/server/index.js +33 -0
  41. package/dist/server/index.js.map +1 -0
  42. package/dist/server/local.d.ts +15 -0
  43. package/dist/server/local.js +46 -0
  44. package/dist/server/local.js.map +1 -0
  45. package/dist/utils/cookies.d.ts +7 -0
  46. package/dist/utils/cookies.js +31 -0
  47. package/dist/utils/cookies.js.map +1 -0
  48. package/dist/utils/env.d.ts +6 -0
  49. package/dist/utils/env.js +22 -0
  50. package/dist/utils/env.js.map +1 -0
  51. package/dist/utils/json.d.ts +2 -0
  52. package/dist/utils/json.js +34 -0
  53. package/dist/utils/json.js.map +1 -0
  54. package/dist/utils/middleware.d.ts +2 -0
  55. package/dist/utils/middleware.js +34 -0
  56. package/dist/utils/middleware.js.map +1 -0
  57. package/dist/utils/promises.d.ts +5 -0
  58. package/dist/utils/promises.js +29 -0
  59. package/dist/utils/promises.js.map +1 -0
  60. package/dist/utils/server.d.ts +5 -0
  61. package/dist/utils/server.js +48 -0
  62. package/dist/utils/server.js.map +1 -0
  63. package/dist/utils/throttle.d.ts +4 -0
  64. package/dist/utils/throttle.js +40 -0
  65. package/dist/utils/throttle.js.map +1 -0
  66. package/dist/utils/types.d.ts +1 -0
  67. package/dist/utils/types.js +3 -0
  68. package/dist/utils/types.js.map +1 -0
  69. package/package.json +1 -1
  70. package/package-lock.json +0 -1291
@@ -0,0 +1,11 @@
1
+ export declare class HttpClient {
2
+ private url;
3
+ private clientId;
4
+ private getHeaders;
5
+ constructor(url: string, clientId: string, getHeaders: () => Promise<Record<string, string>>);
6
+ call(itemName: string, params: unknown[], callTimeout: number): Promise<unknown>;
7
+ subscribe(itemName: string, params: unknown[], callTimeout: number): Promise<unknown>;
8
+ unsubscribe(itemName: string, params: unknown[], callTimeout: number): Promise<void>;
9
+ private getItemUrl;
10
+ private httpRequest;
11
+ }
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HttpClient = void 0;
4
+ const rpc_js_1 = require("../rpc.js");
5
+ const json_js_1 = require("../utils/json.js");
6
+ class HttpClient {
7
+ constructor(url, clientId, getHeaders) {
8
+ this.url = url;
9
+ this.clientId = clientId;
10
+ this.getHeaders = getHeaders;
11
+ }
12
+ async call(itemName, params, callTimeout) {
13
+ return this.httpRequest("POST", itemName, params, callTimeout, await this.getHeaders());
14
+ }
15
+ async subscribe(itemName, params, callTimeout) {
16
+ return this.httpRequest("PUT", itemName, params, callTimeout, await this.getHeaders());
17
+ }
18
+ async unsubscribe(itemName, params, callTimeout) {
19
+ await this.httpRequest("PATCH", itemName, params, callTimeout, await this.getHeaders());
20
+ }
21
+ getItemUrl(itemName) {
22
+ return `${this.url}/${itemName}`;
23
+ }
24
+ async httpRequest(method, itemName, params, callTimeout, headers) {
25
+ const itemUrl = this.getItemUrl(itemName);
26
+ try {
27
+ const { signal, finished } = timeoutSignal(callTimeout);
28
+ const response = await fetch(itemUrl, {
29
+ method,
30
+ headers: {
31
+ "Content-Type": "application/json",
32
+ [rpc_js_1.CLIENT_ID_HEADER]: this.clientId,
33
+ ...headers,
34
+ },
35
+ body: (0, json_js_1.safeStringify)(params),
36
+ signal,
37
+ });
38
+ finished();
39
+ if (response.status == 204) {
40
+ return;
41
+ }
42
+ const contentType = response.headers.get("content-type");
43
+ const text = await response.text();
44
+ const res = contentType && contentType.includes("application/json") ? (0, json_js_1.safeParseJson)(text) : text;
45
+ if (response.status < 200 || response.status >= 300) {
46
+ const error = new Error(response.statusText);
47
+ Object.assign(error, { code: response.status });
48
+ if (typeof res == "object") {
49
+ Object.assign(error, res);
50
+ }
51
+ throw error;
52
+ }
53
+ else {
54
+ return res;
55
+ }
56
+ }
57
+ catch (e) {
58
+ if (e.message == "Error" || !e.message) {
59
+ e.message = `Error ${e.code} while ${itemUrl}`;
60
+ }
61
+ if (e.message == "fetch failed" && e.cause) {
62
+ e = e.cause;
63
+ }
64
+ if (e.message?.toLowerCase()?.includes("timeout")) {
65
+ // NodeJS undici http client timeout
66
+ const error = new Error("Timeout");
67
+ Object.assign(error, { code: rpc_js_1.RpcErrors.Timeout });
68
+ throw error;
69
+ }
70
+ throw e;
71
+ }
72
+ }
73
+ }
74
+ exports.HttpClient = HttpClient;
75
+ // AbortSignal.timeout polyfill for RN
76
+ function timeoutSignal(time) {
77
+ const controller = new AbortController();
78
+ const timeout = setTimeout(() => controller.abort(new Error("TimeoutError")), time);
79
+ return {
80
+ signal: controller.signal,
81
+ finished: () => clearTimeout(timeout),
82
+ };
83
+ }
84
+ //# sourceMappingURL=HttpClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HttpClient.js","sourceRoot":"","sources":["../../src/client/HttpClient.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ export declare class RemoteSubscriptions {
2
+ unsubscribe(itemName: string, parameters: unknown[], consumer: (d: unknown) => void): boolean;
3
+ addSubscription(itemName: string, parameters: unknown[], consumer: (d: unknown) => void): void;
4
+ pause(itemName: string, parameters: unknown[]): void;
5
+ unpause(itemName: string, parameters: unknown[]): void;
6
+ flushQueue(itemName: string, parameters: unknown[]): void;
7
+ emptyQueue(itemName: string, parameters: unknown[]): void;
8
+ private removeSubscription;
9
+ getCached(itemName: string, parameters: unknown[]): unknown | undefined;
10
+ consume(itemName: string, parameters: unknown[], data: unknown): void;
11
+ getAllSubscriptions(): Array<[
12
+ itemName: string,
13
+ parameters: unknown[],
14
+ consumers: Array<(d: unknown) => void>
15
+ ]>;
16
+ private getFilterSubscriptions;
17
+ private byItem;
18
+ }
@@ -0,0 +1,120 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RemoteSubscriptions = void 0;
4
+ const json_js_1 = require("../utils/json.js");
5
+ class RemoteSubscriptions {
6
+ constructor() {
7
+ this.byItem = new Map();
8
+ }
9
+ unsubscribe(itemName, parameters, consumer) {
10
+ const parametersKey = getParametersKey(parameters);
11
+ return this.removeSubscription(itemName, parametersKey, consumer);
12
+ }
13
+ addSubscription(itemName, parameters, consumer) {
14
+ const itemSubscriptions = this.byItem.get(itemName) || { byParameters: new Map() };
15
+ this.byItem.set(itemName, itemSubscriptions);
16
+ const parametersKey = getParametersKey(parameters);
17
+ const parameterSubscriptions = itemSubscriptions.byParameters.get(parametersKey) || {
18
+ parameters,
19
+ cached: null,
20
+ consumers: [],
21
+ queue: [],
22
+ };
23
+ itemSubscriptions.byParameters.set(parametersKey, parameterSubscriptions);
24
+ parameterSubscriptions.consumers.push(consumer);
25
+ }
26
+ pause(itemName, parameters) {
27
+ const filterSubscriptions = this.getFilterSubscriptions(itemName, parameters);
28
+ if (!filterSubscriptions)
29
+ return;
30
+ filterSubscriptions.paused = true;
31
+ }
32
+ unpause(itemName, parameters) {
33
+ const filterSubscriptions = this.getFilterSubscriptions(itemName, parameters);
34
+ if (!filterSubscriptions)
35
+ return;
36
+ filterSubscriptions.paused = false;
37
+ }
38
+ flushQueue(itemName, parameters) {
39
+ const filterSubscriptions = this.getFilterSubscriptions(itemName, parameters);
40
+ if (!filterSubscriptions)
41
+ return;
42
+ filterSubscriptions.queue.forEach((data) => {
43
+ filterSubscriptions.cached = data;
44
+ filterSubscriptions.consumers.forEach((consumer) => {
45
+ consumer(data);
46
+ });
47
+ });
48
+ filterSubscriptions.queue = [];
49
+ }
50
+ emptyQueue(itemName, parameters) {
51
+ const filterSubscriptions = this.getFilterSubscriptions(itemName, parameters);
52
+ if (!filterSubscriptions)
53
+ return;
54
+ filterSubscriptions.queue = [];
55
+ }
56
+ removeSubscription(itemName, parametersKey, consumer) {
57
+ const itemSubscriptions = this.byItem.get(itemName);
58
+ if (!itemSubscriptions)
59
+ return false;
60
+ const filterSubscriptions = itemSubscriptions.byParameters.get(parametersKey);
61
+ if (!filterSubscriptions)
62
+ return false;
63
+ const index = filterSubscriptions.consumers.indexOf(consumer);
64
+ if (index == -1)
65
+ return false;
66
+ filterSubscriptions.consumers.splice(index, 1);
67
+ if (!filterSubscriptions.consumers.length) {
68
+ itemSubscriptions.byParameters.delete(parametersKey);
69
+ if (itemSubscriptions.byParameters.size == 0) {
70
+ this.byItem.delete(itemName);
71
+ }
72
+ return true;
73
+ }
74
+ return false;
75
+ }
76
+ getCached(itemName, parameters) {
77
+ const filterSubscriptions = this.getFilterSubscriptions(itemName, parameters);
78
+ if (!filterSubscriptions)
79
+ return;
80
+ return filterSubscriptions.cached;
81
+ }
82
+ consume(itemName, parameters, data) {
83
+ const filterSubscriptions = this.getFilterSubscriptions(itemName, parameters);
84
+ if (!filterSubscriptions)
85
+ return;
86
+ if (filterSubscriptions.paused) {
87
+ filterSubscriptions.queue.push(data);
88
+ }
89
+ else {
90
+ filterSubscriptions.cached = data;
91
+ filterSubscriptions.consumers.forEach((consumer) => {
92
+ consumer(data);
93
+ });
94
+ }
95
+ }
96
+ getAllSubscriptions() {
97
+ const result = [];
98
+ for (const [itemName, itemSubscriptions] of this.byItem) {
99
+ for (const [, parameterSubscriptions] of itemSubscriptions.byParameters) {
100
+ result.push([itemName, parameterSubscriptions.parameters, parameterSubscriptions.consumers]);
101
+ }
102
+ }
103
+ return result;
104
+ }
105
+ getFilterSubscriptions(itemName, parameters) {
106
+ const parametersKey = getParametersKey(parameters);
107
+ const itemSubscriptions = this.byItem.get(itemName);
108
+ if (!itemSubscriptions)
109
+ return;
110
+ const filterSubscriptions = itemSubscriptions.byParameters.get(parametersKey);
111
+ if (!filterSubscriptions)
112
+ return;
113
+ return filterSubscriptions;
114
+ }
115
+ }
116
+ exports.RemoteSubscriptions = RemoteSubscriptions;
117
+ function getParametersKey(parameters) {
118
+ return (0, json_js_1.safeStringify)(parameters);
119
+ }
120
+ //# sourceMappingURL=RemoteSubscriptions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RemoteSubscriptions.js","sourceRoot":"","sources":["../../src/client/RemoteSubscriptions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import { Services } from "../rpc.js";
2
+ import { ServicesWithSubscriptions } from "./remote.js";
3
+ import { ConsumeServicesOptions, RpcClient } from "./index.js";
4
+ export declare class RpcClientImpl<S extends Services<S>> implements RpcClient {
5
+ private readonly options;
6
+ constructor(url: string, options: ConsumeServicesOptions);
7
+ readonly clientId: string;
8
+ private readonly httpClient;
9
+ private readonly remoteSubscriptions;
10
+ private readonly connection;
11
+ isConnected(): boolean;
12
+ close(): Promise<void>;
13
+ _allSubscriptions(): [itemName: string, parameters: unknown[], consumers: (d: unknown) => void][];
14
+ _webSocket(): WebSocket | null;
15
+ createRemote(): ServicesWithSubscriptions<S>;
16
+ connect(): Promise<void>;
17
+ private call;
18
+ private subscribe;
19
+ private unsubscribe;
20
+ private resubscribe;
21
+ private invoke;
22
+ }
@@ -0,0 +1,121 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RpcClientImpl = void 0;
4
+ const rpc_js_1 = require("../rpc.js");
5
+ const HttpClient_js_1 = require("./HttpClient.js");
6
+ const RemoteSubscriptions_js_1 = require("./RemoteSubscriptions.js");
7
+ const WebSocketConnection_js_1 = require("./WebSocketConnection.js");
8
+ const nanoid_1 = require("nanoid");
9
+ const remote_js_1 = require("./remote.js");
10
+ const middleware_js_1 = require("../utils/middleware.js");
11
+ class RpcClientImpl {
12
+ constructor(url, options) {
13
+ this.options = options;
14
+ this.clientId = (0, nanoid_1.nanoid)();
15
+ this.call = (itemName, parameters, callOptions) => {
16
+ return this.invoke(itemName, rpc_js_1.InvocationType.Call, (...parameters) => this.httpClient.call(itemName, parameters, callOptions?.timeout ?? this.options.callTimeout), parameters);
17
+ };
18
+ this.subscribe = async (itemName, parameters, consumer, callOptions) => {
19
+ const cached = this.remoteSubscriptions.getCached(itemName, parameters);
20
+ if (cached !== undefined) {
21
+ consumer(cached);
22
+ }
23
+ // Needs to be awaited b/c resubscribe will make a 2nd request then.
24
+ // Also, server needs the connection to be established before making a subscription
25
+ await this.connection.connect();
26
+ try {
27
+ this.remoteSubscriptions.addSubscription(itemName, parameters, consumer);
28
+ this.remoteSubscriptions.pause(itemName, parameters);
29
+ const data = await this.invoke(itemName, rpc_js_1.InvocationType.Subscribe, (...parameters) => this.httpClient.subscribe(itemName, parameters, callOptions?.timeout ?? this.options.callTimeout), parameters);
30
+ this.remoteSubscriptions.unpause(itemName, parameters);
31
+ this.remoteSubscriptions.consume(itemName, parameters, data);
32
+ this.remoteSubscriptions.flushQueue(itemName, parameters);
33
+ }
34
+ catch (e) {
35
+ this.remoteSubscriptions.unpause(itemName, parameters);
36
+ this.remoteSubscriptions.emptyQueue(itemName, parameters);
37
+ await this.unsubscribe(itemName, parameters, consumer);
38
+ throw e;
39
+ }
40
+ };
41
+ this.unsubscribe = async (itemName, parameters, consumer, callOptions) => {
42
+ const noSubscriptionsLeft = this.remoteSubscriptions.unsubscribe(itemName, parameters, consumer);
43
+ if (noSubscriptionsLeft) {
44
+ await this.invoke(itemName, rpc_js_1.InvocationType.Unsubscribe, (...parameters) => this.httpClient.unsubscribe(itemName, parameters, callOptions?.timeout ?? this.options.callTimeout), parameters);
45
+ }
46
+ };
47
+ this.resubscribe = () => {
48
+ for (const [itemName, params, consumers] of this.remoteSubscriptions.getAllSubscriptions()) {
49
+ this.httpClient
50
+ .subscribe(itemName, params, this.options.callTimeout)
51
+ .then((data) => {
52
+ this.remoteSubscriptions.consume(itemName, params, data);
53
+ })
54
+ .catch((e) => {
55
+ for (const consumer of consumers) {
56
+ this.remoteSubscriptions.unsubscribe(itemName, params, consumer);
57
+ }
58
+ });
59
+ }
60
+ };
61
+ this.httpClient = new HttpClient_js_1.HttpClient(url, this.clientId, options.getHeaders);
62
+ this.remoteSubscriptions = new RemoteSubscriptions_js_1.RemoteSubscriptions();
63
+ this.connection = new WebSocketConnection_js_1.WebSocketConnection(options.getSubscriptionsUrl(url), this.clientId, {
64
+ subscriptions: options.subscriptions,
65
+ errorDelayMaxDuration: options.errorDelayMaxDuration,
66
+ reconnectDelay: options.reconnectDelay,
67
+ pingInterval: options.pingInterval,
68
+ }, (itemName, parameters, data) => {
69
+ const ctx = {
70
+ clientId: this.clientId,
71
+ itemName,
72
+ invocationType: rpc_js_1.InvocationType.Update,
73
+ };
74
+ const next = async (nextData = data, nextParameters = parameters) => this.remoteSubscriptions.consume(itemName, nextParameters, nextData);
75
+ return (0, middleware_js_1.withMiddlewares)(ctx, this.options.notificationsMiddleware, next, data, parameters);
76
+ }, () => {
77
+ this.resubscribe();
78
+ options.onConnected();
79
+ }, () => {
80
+ options.onDisconnected();
81
+ });
82
+ }
83
+ isConnected() {
84
+ return this.connection.isConnected();
85
+ }
86
+ close() {
87
+ return this.connection.close();
88
+ }
89
+ _allSubscriptions() {
90
+ const result = [];
91
+ for (const [itemName, parameters, consumers,] of this.remoteSubscriptions.getAllSubscriptions()) {
92
+ for (const consumer of consumers) {
93
+ result.push([itemName, parameters, consumer]);
94
+ }
95
+ }
96
+ return result;
97
+ }
98
+ _webSocket() {
99
+ return this.connection._webSocket();
100
+ }
101
+ createRemote() {
102
+ return (0, remote_js_1.createRemote)({
103
+ call: this.call,
104
+ subscribe: this.subscribe,
105
+ unsubscribe: this.unsubscribe,
106
+ });
107
+ }
108
+ async connect() {
109
+ await this.connection.connect();
110
+ }
111
+ invoke(itemName, invocationType, next, parameters) {
112
+ const ctx = {
113
+ clientId: this.clientId,
114
+ itemName,
115
+ invocationType: invocationType,
116
+ };
117
+ return (0, middleware_js_1.withMiddlewares)(ctx, this.options.middleware, next, ...parameters);
118
+ }
119
+ }
120
+ exports.RpcClientImpl = RpcClientImpl;
121
+ //# sourceMappingURL=RpcClientImpl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RpcClientImpl.js","sourceRoot":"","sources":["../../src/client/RpcClientImpl.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ export declare class WebSocketConnection {
2
+ private readonly url;
3
+ private readonly clientId;
4
+ private readonly options;
5
+ private readonly consume;
6
+ private readonly onConnected;
7
+ private readonly onDisconnected;
8
+ constructor(url: string, clientId: string, options: {
9
+ subscriptions: boolean;
10
+ reconnectDelay: number;
11
+ errorDelayMaxDuration: number;
12
+ pingInterval: number | null;
13
+ }, consume: (itemName: string, parameters: unknown[], data: unknown) => Promise<unknown>, onConnected: () => void, onDisconnected: () => void);
14
+ private resolveClose;
15
+ close(): Promise<void>;
16
+ private waitConnectionPromise;
17
+ /**
18
+ * Connect to the server, on each disconnect try to disconnect.
19
+ * Resolves at next successful connect. Reconnection loop continues even after resolution
20
+ * Never rejects
21
+ */
22
+ connect(): Promise<void>;
23
+ isConnected(): boolean;
24
+ /**
25
+ * Connect this to server
26
+ *
27
+ * Resolves on successful connection, rejects on connection error or connection timeout
28
+ */
29
+ private establishConnection;
30
+ private socket;
31
+ private disconnectedMark;
32
+ private pingTimeout;
33
+ private heartbeat;
34
+ private receiveSocketMessage;
35
+ _webSocket(): WebSocket | null;
36
+ }
@@ -0,0 +1,161 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WebSocketConnection = void 0;
4
+ const logger_js_1 = require("../logger.js");
5
+ const json_js_1 = require("../utils/json.js");
6
+ const promises_js_1 = require("../utils/promises.js");
7
+ class WebSocketConnection {
8
+ constructor(url, clientId, options, consume, onConnected, onDisconnected) {
9
+ this.url = url;
10
+ this.clientId = clientId;
11
+ this.options = options;
12
+ this.consume = consume;
13
+ this.onConnected = onConnected;
14
+ this.onDisconnected = onDisconnected;
15
+ this.resolveClose = () => { };
16
+ this.socket = null;
17
+ this.disconnectedMark = false;
18
+ this.pingTimeout = null;
19
+ this.clientId = clientId;
20
+ }
21
+ async close() {
22
+ this.disconnectedMark = true;
23
+ if (this.socket) {
24
+ this.socket.close();
25
+ return new Promise((resolve, reject) => {
26
+ this.resolveClose = resolve;
27
+ });
28
+ }
29
+ }
30
+ /**
31
+ * Connect to the server, on each disconnect try to disconnect.
32
+ * Resolves at next successful connect. Reconnection loop continues even after resolution
33
+ * Never rejects
34
+ */
35
+ connect() {
36
+ // no subscriptions support, no need to connect
37
+ if (!this.options.subscriptions) {
38
+ return Promise.resolve();
39
+ }
40
+ // already started connecting
41
+ if (this.waitConnectionPromise)
42
+ return this.waitConnectionPromise;
43
+ // start connection process
44
+ let resolveConnectionPromise;
45
+ let errorDelay = 0;
46
+ this.waitConnectionPromise = new Promise(async (resolve) => {
47
+ resolveConnectionPromise = resolve;
48
+ while (true) {
49
+ // connect, and wait for ...
50
+ await new Promise((resolve) => {
51
+ const connectionPromise = this.establishConnection(() => {
52
+ // 1. ...disconnected
53
+ // recreate promise so new clients will wait for new connection
54
+ this.waitConnectionPromise = new Promise((resolve) => (resolveConnectionPromise = resolve));
55
+ resolve();
56
+ });
57
+ connectionPromise.then(() => {
58
+ // first reconnect after successful connection is done without delay
59
+ errorDelay = 0;
60
+ resolveConnectionPromise();
61
+ }, (e) => {
62
+ logger_js_1.log.warn("Unable to connect WS", e);
63
+ // 2. ... unable to establish connection
64
+ resolve();
65
+ });
66
+ });
67
+ // disconnected while connecting?
68
+ if (this.disconnectedMark) {
69
+ return;
70
+ }
71
+ await (0, promises_js_1.adelay)(this.options.reconnectDelay + errorDelay);
72
+ // disconnected while waiting?
73
+ if (this.disconnectedMark) {
74
+ return;
75
+ }
76
+ errorDelay = Math.round(Math.random() * this.options.errorDelayMaxDuration);
77
+ }
78
+ });
79
+ return this.waitConnectionPromise;
80
+ }
81
+ isConnected() {
82
+ return this.socket !== null;
83
+ }
84
+ /**
85
+ * Connect this to server
86
+ *
87
+ * Resolves on successful connection, rejects on connection error or connection timeout
88
+ */
89
+ async establishConnection(onDisconnected) {
90
+ return new Promise(async (resolve, reject) => {
91
+ try {
92
+ const socket = new WebSocket(this.url, this.clientId);
93
+ let connected = false;
94
+ socket.addEventListener("open", () => {
95
+ this.socket = socket;
96
+ connected = true;
97
+ resolve();
98
+ this.heartbeat();
99
+ this.onConnected();
100
+ });
101
+ socket.addEventListener("ping", () => {
102
+ this.heartbeat();
103
+ });
104
+ socket.addEventListener("close", () => {
105
+ this.socket = null;
106
+ if (connected) {
107
+ onDisconnected();
108
+ this.onDisconnected();
109
+ }
110
+ if (this.pingTimeout) {
111
+ clearTimeout(this.pingTimeout);
112
+ }
113
+ this.resolveClose();
114
+ });
115
+ socket.addEventListener("error", (e) => {
116
+ if (!connected) {
117
+ reject(e);
118
+ }
119
+ try {
120
+ socket.close();
121
+ }
122
+ catch (e) {
123
+ // ignore
124
+ }
125
+ });
126
+ socket.addEventListener("message", (message) => {
127
+ this.receiveSocketMessage(message.data);
128
+ });
129
+ }
130
+ catch (e) {
131
+ reject(e);
132
+ }
133
+ });
134
+ }
135
+ heartbeat() {
136
+ if (this.pingTimeout) {
137
+ clearTimeout(this.pingTimeout);
138
+ }
139
+ if (this.options.pingInterval) {
140
+ this.pingTimeout = setTimeout(() => {
141
+ this.socket?.close();
142
+ }, this.options.pingInterval * 1.5);
143
+ }
144
+ }
145
+ async receiveSocketMessage(rawMessage) {
146
+ try {
147
+ const msg = rawMessage.toString();
148
+ const [itemName, data, ...parameters] = (0, json_js_1.safeParseJson)(msg);
149
+ await this.consume(itemName, parameters, data);
150
+ }
151
+ catch (e) {
152
+ logger_js_1.log.error("Can't handle notification", e);
153
+ }
154
+ }
155
+ // test-only
156
+ _webSocket() {
157
+ return this.socket;
158
+ }
159
+ }
160
+ exports.WebSocketConnection = WebSocketConnection;
161
+ //# sourceMappingURL=WebSocketConnection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WebSocketConnection.js","sourceRoot":"","sources":["../../src/client/WebSocketConnection.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import { RpcContext, Services } from "../rpc.js";
2
+ import { ServicesWithSubscriptions } from "./remote.js";
3
+ import { Middleware } from "../utils/middleware.js";
4
+ export type RpcClient = {
5
+ readonly clientId: string;
6
+ connect(): Promise<void>;
7
+ isConnected(): boolean;
8
+ close(): Promise<void>;
9
+ _allSubscriptions(): Array<any[]>;
10
+ _webSocket(): WebSocket | null;
11
+ };
12
+ export type ConsumeServicesOptions = {
13
+ callTimeout: number;
14
+ reconnectDelay: number;
15
+ errorDelayMaxDuration: number;
16
+ pingInterval: number | null;
17
+ subscriptions: boolean;
18
+ middleware: Middleware<RpcContext>[];
19
+ notificationsMiddleware: Middleware<RpcContext>[];
20
+ connectOnCreate: boolean;
21
+ onConnected: () => void;
22
+ onDisconnected: () => void;
23
+ getHeaders: () => Promise<Record<string, string>>;
24
+ getSubscriptionsUrl(url: string): string;
25
+ };
26
+ export declare function consumeServices<S extends Services<S>>(url: string, overrideOptions?: Partial<ConsumeServicesOptions>): Promise<{
27
+ client: RpcClient;
28
+ remote: ServicesWithSubscriptions<S>;
29
+ }>;