@polkadot-api/ws-provider 0.7.5 → 0.8.1-canary.527fbf8

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 (52) hide show
  1. package/dist/esm/get-async-provider.mjs +40 -0
  2. package/dist/esm/get-async-provider.mjs.map +1 -0
  3. package/dist/esm/index.mjs +3 -0
  4. package/dist/esm/provider.mjs +84 -0
  5. package/dist/esm/provider.mjs.map +1 -0
  6. package/dist/esm/types.mjs +22 -0
  7. package/dist/esm/types.mjs.map +1 -0
  8. package/dist/esm/with-socket.mjs +114 -0
  9. package/dist/esm/with-socket.mjs.map +1 -0
  10. package/dist/index.d.ts +83 -0
  11. package/dist/index.js +250 -0
  12. package/dist/index.js.map +1 -0
  13. package/package.json +28 -32
  14. package/dist/index/esm/default-provider.mjs +0 -171
  15. package/dist/index/esm/default-provider.mjs.map +0 -1
  16. package/dist/index/esm/follow-enhancer.mjs +0 -91
  17. package/dist/index/esm/follow-enhancer.mjs.map +0 -1
  18. package/dist/index/esm/index.mjs +0 -3
  19. package/dist/index/esm/types-common.mjs +0 -10
  20. package/dist/index/esm/types-common.mjs.map +0 -1
  21. package/dist/index/index.d.ts +0 -48
  22. package/dist/index/index.js +0 -269
  23. package/dist/index/index.js.map +0 -1
  24. package/dist/node/esm/default-provider.mjs +0 -171
  25. package/dist/node/esm/default-provider.mjs.map +0 -1
  26. package/dist/node/esm/follow-enhancer.mjs +0 -91
  27. package/dist/node/esm/follow-enhancer.mjs.map +0 -1
  28. package/dist/node/esm/legacy-provider.mjs +0 -44
  29. package/dist/node/esm/legacy-provider.mjs.map +0 -1
  30. package/dist/node/esm/node.mjs +0 -15
  31. package/dist/node/esm/node.mjs.map +0 -1
  32. package/dist/node/esm/types-common.mjs +0 -10
  33. package/dist/node/esm/types-common.mjs.map +0 -1
  34. package/dist/node/node.d.ts +0 -61
  35. package/dist/node/node.js +0 -319
  36. package/dist/node/node.js.map +0 -1
  37. package/dist/web/esm/default-provider.mjs +0 -171
  38. package/dist/web/esm/default-provider.mjs.map +0 -1
  39. package/dist/web/esm/follow-enhancer.mjs +0 -91
  40. package/dist/web/esm/follow-enhancer.mjs.map +0 -1
  41. package/dist/web/esm/legacy-provider.mjs +0 -44
  42. package/dist/web/esm/legacy-provider.mjs.map +0 -1
  43. package/dist/web/esm/types-common.mjs +0 -10
  44. package/dist/web/esm/types-common.mjs.map +0 -1
  45. package/dist/web/esm/web.mjs +0 -7
  46. package/dist/web/esm/web.mjs.map +0 -1
  47. package/dist/web/web.d.ts +0 -61
  48. package/dist/web/web.js +0 -311
  49. package/dist/web/web.js.map +0 -1
  50. package/node/package.json +0 -10
  51. package/web/package.json +0 -10
  52. /package/dist/{index/esm → esm}/index.mjs.map +0 -0
@@ -0,0 +1,40 @@
1
+ import { noop } from '@polkadot-api/utils';
2
+
3
+ const getAsyncProvider = (input) => (onMessage, _onHalt) => {
4
+ let connection = null;
5
+ let pending = [];
6
+ const done = () => {
7
+ stop();
8
+ onHalt = stop = noop;
9
+ connection = void 0;
10
+ pending = [];
11
+ };
12
+ let onHalt = (e) => {
13
+ done();
14
+ _onHalt(e);
15
+ };
16
+ let stop = input((cb) => {
17
+ stop = noop;
18
+ if (!cb) {
19
+ onHalt();
20
+ } else {
21
+ connection = cb(onMessage, onHalt);
22
+ pending.forEach((x) => connection?.send(x));
23
+ pending = [];
24
+ }
25
+ });
26
+ return {
27
+ send: (msg) => {
28
+ if (connection) connection.send(msg);
29
+ else if (connection === null) pending.push(msg);
30
+ },
31
+ disconnect: () => {
32
+ const x = connection;
33
+ done();
34
+ x?.disconnect();
35
+ }
36
+ };
37
+ };
38
+
39
+ export { getAsyncProvider };
40
+ //# sourceMappingURL=get-async-provider.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-async-provider.mjs","sources":["../../src/get-async-provider.ts"],"sourcesContent":["import {\n JsonRpcConnection,\n JsonRpcRequest,\n} from \"@polkadot-api/json-rpc-provider\"\nimport { InnerJsonRpcProvider } from \"@polkadot-api/json-rpc-provider-proxy\"\nimport { noop } from \"@polkadot-api/utils\"\n\nexport const getAsyncProvider =\n <T = string>(\n input: (\n onResult: (x: InnerJsonRpcProvider<T> | null) => void,\n ) => () => void,\n ): InnerJsonRpcProvider<T> =>\n (onMessage, _onHalt) => {\n // null -> loading\n // undefined -> destroyed\n let connection: JsonRpcConnection<T> | null | undefined = null\n\n let pending: Array<JsonRpcRequest> = []\n const done = () => {\n stop()\n onHalt = stop = noop\n connection = undefined\n pending = []\n }\n let onHalt = (e?: any) => {\n done()\n _onHalt(e)\n }\n\n let stop = input((cb) => {\n stop = noop\n if (!cb) {\n onHalt()\n } else {\n connection = cb(onMessage, onHalt)\n pending.forEach((x) => connection?.send(x))\n pending = []\n }\n })\n\n return {\n send: (msg) => {\n if (connection) connection.send(msg)\n else if (connection === null) pending.push(msg)\n },\n disconnect: () => {\n const x = connection\n done()\n x?.disconnect()\n },\n }\n }\n"],"names":[],"mappings":";;AAOO,MAAM,gBAAA,GACX,CACE,KAAA,KAIF,CAAC,WAAW,OAAA,KAAY;AAGtB,EAAA,IAAI,UAAA,GAAsD,IAAA;AAE1D,EAAA,IAAI,UAAiC,EAAC;AACtC,EAAA,MAAM,OAAO,MAAM;AACjB,IAAA,IAAA,EAAK;AACL,IAAA,MAAA,GAAS,IAAA,GAAO,IAAA;AAChB,IAAA,UAAA,GAAa,MAAA;AACb,IAAA,OAAA,GAAU,EAAC;AAAA,EACb,CAAA;AACA,EAAA,IAAI,MAAA,GAAS,CAAC,CAAA,KAAY;AACxB,IAAA,IAAA,EAAK;AACL,IAAA,OAAA,CAAQ,CAAC,CAAA;AAAA,EACX,CAAA;AAEA,EAAA,IAAI,IAAA,GAAO,KAAA,CAAM,CAAC,EAAA,KAAO;AACvB,IAAA,IAAA,GAAO,IAAA;AACP,IAAA,IAAI,CAAC,EAAA,EAAI;AACP,MAAA,MAAA,EAAO;AAAA,IACT,CAAA,MAAO;AACL,MAAA,UAAA,GAAa,EAAA,CAAG,WAAW,MAAM,CAAA;AACjC,MAAA,OAAA,CAAQ,QAAQ,CAAC,CAAA,KAAM,UAAA,EAAY,IAAA,CAAK,CAAC,CAAC,CAAA;AAC1C,MAAA,OAAA,GAAU,EAAC;AAAA,IACb;AAAA,EACF,CAAC,CAAA;AAED,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,CAAC,GAAA,KAAQ;AACb,MAAA,IAAI,UAAA,EAAY,UAAA,CAAW,IAAA,CAAK,GAAG,CAAA;AAAA,WAAA,IAC1B,UAAA,KAAe,IAAA,EAAM,OAAA,CAAQ,IAAA,CAAK,GAAG,CAAA;AAAA,IAChD,CAAA;AAAA,IACA,YAAY,MAAM;AAChB,MAAA,MAAM,CAAA,GAAI,UAAA;AACV,MAAA,IAAA,EAAK;AACL,MAAA,CAAA,EAAG,UAAA,EAAW;AAAA,IAChB;AAAA,GACF;AACF;;;;"}
@@ -0,0 +1,3 @@
1
+ export { SocketEvents, WsEvent } from './types.mjs';
2
+ export { getWsProvider } from './provider.mjs';
3
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1,84 @@
1
+ import { getSyncProvider } from '@polkadot-api/json-rpc-provider-proxy';
2
+ import { noop } from '@polkadot-api/utils';
3
+ import { WsEvent } from './types.mjs';
4
+ import { withSocket } from './with-socket.mjs';
5
+ import { identity } from 'rxjs';
6
+
7
+ const defaultConfig = {
8
+ onStatusChanged: noop,
9
+ timeout: 5e3,
10
+ heartbeatTimeout: 4e4,
11
+ middleware: identity
12
+ };
13
+ const getWsProvider = (endpoints, config) => {
14
+ const {
15
+ onStatusChanged: _onStatuChanged,
16
+ timeout,
17
+ heartbeatTimeout,
18
+ middleware,
19
+ logger
20
+ } = {
21
+ ...defaultConfig,
22
+ ...config
23
+ };
24
+ const actualEndpoints = Array.isArray(endpoints) ? endpoints : [endpoints];
25
+ const WebsocketClass = config?.websocketClass ?? globalThis.WebSocket;
26
+ if (!WebsocketClass) throw new Error("Missing WebSocket class");
27
+ let idx = 0;
28
+ let switchTo;
29
+ let latestSocket = null;
30
+ let status = { type: WsEvent.CLOSE, event: null };
31
+ let prevUri;
32
+ const onStatusChanged = (x) => _onStatuChanged(status = x);
33
+ const socketProvider = middleware(
34
+ withSocket(
35
+ () => {
36
+ prevUri = latestSocket?.url;
37
+ const uri = switchTo ?? actualEndpoints[idx++ % actualEndpoints.length];
38
+ switchTo = void 0;
39
+ onStatusChanged({
40
+ type: WsEvent.CONNECTING,
41
+ uri
42
+ });
43
+ return [
44
+ latestSocket = new WebsocketClass(uri),
45
+ () => {
46
+ onStatusChanged({
47
+ type: WsEvent.CONNECTED,
48
+ uri
49
+ });
50
+ }
51
+ ];
52
+ },
53
+ heartbeatTimeout,
54
+ timeout,
55
+ logger
56
+ )
57
+ );
58
+ const provider = (onMsg, onHalt) => socketProvider(onMsg, (event) => {
59
+ onStatusChanged({
60
+ type: WsEvent.ERROR,
61
+ event
62
+ });
63
+ onHalt(event);
64
+ });
65
+ const result = getSyncProvider((onReady) => {
66
+ if (!prevUri || latestSocket.url !== prevUri) {
67
+ onReady(provider);
68
+ return noop;
69
+ }
70
+ const token = setTimeout(onReady, 250, provider);
71
+ return () => {
72
+ clearTimeout(token);
73
+ };
74
+ });
75
+ const switchFn = (uri) => {
76
+ if (status.type === WsEvent.CLOSE) return;
77
+ switchTo = uri;
78
+ if (status.type !== WsEvent.ERROR && latestSocket) latestSocket.close();
79
+ };
80
+ return Object.assign(result, { switch: switchFn, getStatus: () => status });
81
+ };
82
+
83
+ export { defaultConfig, getWsProvider };
84
+ //# sourceMappingURL=provider.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.mjs","sources":["../../src/provider.ts"],"sourcesContent":["import {\n getSyncProvider,\n InnerJsonRpcProvider,\n} from \"@polkadot-api/json-rpc-provider-proxy\"\nimport { JsonRpcProvider } from \"@polkadot-api/json-rpc-provider\"\nimport { noop } from \"@polkadot-api/utils\"\nimport {\n StatusChange,\n WsJsonRpcProvider,\n WsEvent,\n SocketLoggerFn,\n WebSocketClass,\n Middleware,\n} from \"./types\"\nimport { withSocket } from \"./with-socket\"\nimport { identity } from \"rxjs\"\n\nexport const defaultConfig: {\n timeout: number\n heartbeatTimeout: number\n middleware: Middleware\n onStatusChanged: (status: StatusChange) => void\n} = {\n onStatusChanged: noop,\n timeout: 5_000,\n heartbeatTimeout: 40_000,\n middleware: identity,\n}\n\nexport const getWsProvider = (\n endpoints: string | Array<string>,\n config?: Partial<{\n onStatusChanged: (status: StatusChange) => void\n timeout: number\n heartbeatTimeout: number\n websocketClass: WebSocketClass\n middleware: Middleware\n logger: SocketLoggerFn\n }>,\n): WsJsonRpcProvider => {\n const {\n onStatusChanged: _onStatuChanged,\n timeout,\n heartbeatTimeout,\n middleware,\n logger,\n } = {\n ...defaultConfig,\n ...config,\n }\n const actualEndpoints = Array.isArray(endpoints) ? endpoints : [endpoints]\n\n const WebsocketClass = config?.websocketClass ?? globalThis.WebSocket\n if (!WebsocketClass) throw new Error(\"Missing WebSocket class\")\n\n let idx = 0\n let switchTo: string | undefined\n let latestSocket: WebSocket | null = null\n let status: StatusChange = { type: WsEvent.CLOSE, event: null }\n let prevUri: string | undefined\n const onStatusChanged = (x: StatusChange) => _onStatuChanged((status = x))\n\n const socketProvider = middleware(\n withSocket(\n () => {\n prevUri = latestSocket?.url\n const uri = switchTo ?? actualEndpoints[idx++ % actualEndpoints.length]\n switchTo = undefined\n onStatusChanged({\n type: WsEvent.CONNECTING,\n uri,\n })\n return [\n (latestSocket = new WebsocketClass(uri)),\n () => {\n onStatusChanged({\n type: WsEvent.CONNECTED,\n uri,\n })\n },\n ]\n },\n heartbeatTimeout,\n timeout,\n logger,\n ),\n )\n\n const provider: InnerJsonRpcProvider = (onMsg, onHalt) =>\n socketProvider(onMsg, (event) => {\n onStatusChanged({\n type: WsEvent.ERROR,\n event,\n })\n onHalt(event)\n })\n\n const result: JsonRpcProvider = getSyncProvider((onReady) => {\n if (!prevUri || latestSocket!.url !== prevUri) {\n onReady(provider)\n return noop\n }\n\n const token = setTimeout(onReady, 250, provider)\n return () => {\n clearTimeout(token)\n }\n })\n\n const switchFn: WsJsonRpcProvider[\"switch\"] = (uri?: string) => {\n if (status.type === WsEvent.CLOSE) return\n switchTo = uri\n if (status.type !== WsEvent.ERROR && latestSocket) latestSocket.close()\n }\n\n return Object.assign(result, { switch: switchFn, getStatus: () => status })\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ var WsEvent = /* @__PURE__ */ ((WsEvent2) => {
2
+ WsEvent2["CONNECTING"] = "CONNECTING";
3
+ WsEvent2["CONNECTED"] = "CONNECTED";
4
+ WsEvent2["ERROR"] = "ERROR";
5
+ WsEvent2["CLOSE"] = "CLOSE";
6
+ return WsEvent2;
7
+ })(WsEvent || {});
8
+ var SocketEvents = /* @__PURE__ */ ((SocketEvents2) => {
9
+ SocketEvents2["CONNECTING"] = "CONNECTING";
10
+ SocketEvents2["CONNECTED"] = "CONNECTED";
11
+ SocketEvents2["TIMEOUT"] = "TIMEOUT";
12
+ SocketEvents2["STALE"] = "STALE";
13
+ SocketEvents2["ERROR"] = "ERROR";
14
+ SocketEvents2["CLOSE"] = "CLOSE";
15
+ SocketEvents2["DISCONNECT"] = "DISCONNECT";
16
+ SocketEvents2["IN"] = "IN";
17
+ SocketEvents2["OUT"] = "OUT";
18
+ return SocketEvents2;
19
+ })(SocketEvents || {});
20
+
21
+ export { SocketEvents, WsEvent };
22
+ //# sourceMappingURL=types.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.mjs","sources":["../../src/types.ts"],"sourcesContent":["import { JsonRpcProvider } from \"@polkadot-api/json-rpc-provider\"\nimport { InnerJsonRpcProvider } from \"@polkadot-api/json-rpc-provider-proxy\"\n\nexport enum WsEvent {\n CONNECTING = \"CONNECTING\",\n CONNECTED = \"CONNECTED\",\n ERROR = \"ERROR\",\n CLOSE = \"CLOSE\",\n}\n\nexport type WsConnecting = {\n type: WsEvent.CONNECTING\n uri: string\n}\nexport type WsConnected = {\n type: WsEvent.CONNECTED\n uri: string\n}\nexport type WsError = {\n type: WsEvent.ERROR\n event: any\n}\nexport type WsClose = {\n type: WsEvent.CLOSE\n event: any\n}\nexport type StatusChange = WsConnecting | WsConnected | WsError | WsClose\nexport type WsJsonRpcProvider = JsonRpcProvider & {\n switch: (uri?: string) => void\n getStatus: () => StatusChange\n}\nexport { type JsonRpcProvider }\n\nexport enum SocketEvents {\n CONNECTING = \"CONNECTING\",\n CONNECTED = \"CONNECTED\",\n TIMEOUT = \"TIMEOUT\",\n STALE = \"STALE\",\n ERROR = \"ERROR\",\n CLOSE = \"CLOSE\",\n DISCONNECT = \"DISCONNECT\",\n IN = \"IN\",\n OUT = \"OUT\",\n}\n\ntype SocketLoggerEvent =\n | { type: SocketEvents.CONNECTING; url: string }\n | { type: SocketEvents.CONNECTED }\n | { type: SocketEvents.DISCONNECT }\n | { type: SocketEvents.ERROR; error: any }\n | { type: SocketEvents.CLOSE }\n | { type: SocketEvents.STALE }\n | { type: SocketEvents.TIMEOUT }\n | { type: SocketEvents.IN; msg: string }\n | { type: SocketEvents.OUT; msg: string }\n\nexport type SocketLoggerFn = (event: SocketLoggerEvent) => void\n\nexport type WebSocketClass = typeof WebSocket\n\nexport type { InnerJsonRpcProvider }\nexport type Middleware = (base: InnerJsonRpcProvider) => InnerJsonRpcProvider\n"],"names":["WsEvent","SocketEvents"],"mappings":"AAGO,IAAK,OAAA,qBAAAA,QAAAA,KAAL;AACL,EAAAA,SAAA,YAAA,CAAA,GAAa,YAAA;AACb,EAAAA,SAAA,WAAA,CAAA,GAAY,WAAA;AACZ,EAAAA,SAAA,OAAA,CAAA,GAAQ,OAAA;AACR,EAAAA,SAAA,OAAA,CAAA,GAAQ,OAAA;AAJE,EAAA,OAAAA,QAAAA;AAAA,CAAA,EAAA,OAAA,IAAA,EAAA;AA8BL,IAAK,YAAA,qBAAAC,aAAAA,KAAL;AACL,EAAAA,cAAA,YAAA,CAAA,GAAa,YAAA;AACb,EAAAA,cAAA,WAAA,CAAA,GAAY,WAAA;AACZ,EAAAA,cAAA,SAAA,CAAA,GAAU,SAAA;AACV,EAAAA,cAAA,OAAA,CAAA,GAAQ,OAAA;AACR,EAAAA,cAAA,OAAA,CAAA,GAAQ,OAAA;AACR,EAAAA,cAAA,OAAA,CAAA,GAAQ,OAAA;AACR,EAAAA,cAAA,YAAA,CAAA,GAAa,YAAA;AACb,EAAAA,cAAA,IAAA,CAAA,GAAK,IAAA;AACL,EAAAA,cAAA,KAAA,CAAA,GAAM,KAAA;AATI,EAAA,OAAAA,aAAAA;AAAA,CAAA,EAAA,YAAA,IAAA,EAAA;;;;"}
@@ -0,0 +1,114 @@
1
+ import { getAsyncProvider } from './get-async-provider.mjs';
2
+ import { SocketEvents, WsEvent } from './types.mjs';
3
+ import { noop } from '@polkadot-api/utils';
4
+
5
+ const withSocket = (getWebsocket, heartbeatTimeout, connectionTimeout, logger) => {
6
+ const logType = logger ? (type) => logger({ type }) : noop;
7
+ const logMsg = logger ? (type, msg) => logger({ type, msg }) : noop;
8
+ return getAsyncProvider((onReady) => {
9
+ const [socket, onConnected] = getWebsocket();
10
+ logger?.({ type: SocketEvents.CONNECTING, url: socket.url });
11
+ let suicide = () => {
12
+ suicide = noop;
13
+ cleanup();
14
+ onReady(null);
15
+ };
16
+ let isFirst = true;
17
+ let heartbeatToken;
18
+ const heartbeat = () => {
19
+ clearTimeout(heartbeatToken);
20
+ const [time, event] = isFirst ? [connectionTimeout, SocketEvents.TIMEOUT] : [heartbeatTimeout, SocketEvents.STALE];
21
+ isFirst = false;
22
+ heartbeatToken = setTimeout(() => {
23
+ logType(event);
24
+ suicide({
25
+ type: WsEvent.ERROR,
26
+ event: { type: "timeout" }
27
+ });
28
+ }, time);
29
+ };
30
+ const stopTimeout = () => {
31
+ clearTimeout(heartbeatToken);
32
+ };
33
+ heartbeat();
34
+ let cleanup = () => {
35
+ stopTimeout();
36
+ };
37
+ const onError = (event) => {
38
+ logger?.({ type: SocketEvents.ERROR, error: event });
39
+ suicide({
40
+ type: WsEvent.ERROR,
41
+ event
42
+ });
43
+ };
44
+ const onClose = (event) => {
45
+ logType(SocketEvents.CLOSE);
46
+ suicide({
47
+ type: WsEvent.CLOSE,
48
+ event
49
+ });
50
+ };
51
+ const disconnect = () => {
52
+ logType(SocketEvents.DISCONNECT);
53
+ cleanup();
54
+ try {
55
+ socket.addEventListener("error", noop, { once: true });
56
+ socket.close();
57
+ } catch {
58
+ }
59
+ };
60
+ const onOpen = () => {
61
+ logType(SocketEvents.CONNECTED);
62
+ onConnected();
63
+ heartbeat();
64
+ socket.removeEventListener("open", onOpen);
65
+ onReady((onMsg, onHalt) => {
66
+ cleanup = () => {
67
+ cleanup = noop;
68
+ stopTimeout();
69
+ socket.removeEventListener("error", onError);
70
+ socket.removeEventListener("ping", heartbeat);
71
+ socket.removeEventListener("message", _onMessage);
72
+ socket.removeEventListener("close", onClose);
73
+ };
74
+ suicide = (e) => {
75
+ suicide = noop;
76
+ cleanup();
77
+ onHalt(e);
78
+ };
79
+ const _onMessage = (e) => {
80
+ heartbeat();
81
+ if (typeof e.data === "string") {
82
+ logMsg(SocketEvents.IN, e.data);
83
+ onMsg(JSON.parse(e.data));
84
+ }
85
+ };
86
+ socket.addEventListener("ping", heartbeat);
87
+ socket.addEventListener("message", _onMessage);
88
+ socket.addEventListener("error", onError);
89
+ socket.addEventListener("close", onClose);
90
+ return {
91
+ send(m) {
92
+ const msg = JSON.stringify(m);
93
+ logMsg(SocketEvents.OUT, msg);
94
+ socket.send(msg);
95
+ },
96
+ disconnect
97
+ };
98
+ });
99
+ };
100
+ cleanup = () => {
101
+ cleanup = noop;
102
+ stopTimeout();
103
+ socket.removeEventListener("error", onError);
104
+ socket.removeEventListener("close", onClose);
105
+ socket.removeEventListener("open", onOpen);
106
+ };
107
+ socket.addEventListener("open", onOpen);
108
+ socket.addEventListener("error", onError);
109
+ return disconnect;
110
+ });
111
+ };
112
+
113
+ export { withSocket };
114
+ //# sourceMappingURL=with-socket.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"with-socket.mjs","sources":["../../src/with-socket.ts"],"sourcesContent":["import { getAsyncProvider } from \"./get-async-provider\"\nimport { SocketEvents, SocketLoggerFn, WsEvent } from \"./types\"\nimport { noop } from \"@polkadot-api/utils\"\n\nexport const withSocket = (\n getWebsocket: () => [WebSocket, () => void],\n heartbeatTimeout: number,\n connectionTimeout: number,\n logger?: SocketLoggerFn,\n) => {\n const logType: (\n type:\n | SocketEvents.TIMEOUT\n | SocketEvents.STALE\n | SocketEvents.CONNECTED\n | SocketEvents.DISCONNECT\n | SocketEvents.CLOSE,\n ) => void = logger ? (type) => logger({ type }) : noop\n const logMsg: (\n type: SocketEvents.IN | SocketEvents.OUT,\n msg: string,\n ) => void = logger ? (type, msg) => logger({ type, msg }) : noop\n\n return getAsyncProvider((onReady) => {\n const [socket, onConnected] = getWebsocket()\n logger?.({ type: SocketEvents.CONNECTING, url: socket.url })\n\n let suicide: (e?: any) => void = () => {\n suicide = noop\n cleanup()\n onReady(null)\n }\n\n let isFirst = true\n let heartbeatToken: number\n const heartbeat = () => {\n clearTimeout(heartbeatToken)\n const [time, event] = isFirst\n ? ([connectionTimeout, SocketEvents.TIMEOUT] as const)\n : ([heartbeatTimeout, SocketEvents.STALE] as const)\n isFirst = false\n heartbeatToken = setTimeout(() => {\n logType(event)\n suicide({\n type: WsEvent.ERROR,\n event: { type: \"timeout\" },\n })\n }, time)\n }\n const stopTimeout = () => {\n clearTimeout(heartbeatToken)\n }\n\n heartbeat()\n\n let cleanup = () => {\n stopTimeout()\n }\n\n const onError = (event: any) => {\n logger?.({ type: SocketEvents.ERROR, error: event })\n suicide({\n type: WsEvent.ERROR,\n event,\n })\n }\n const onClose = (event: any) => {\n logType(SocketEvents.CLOSE)\n suicide({\n type: WsEvent.CLOSE,\n event,\n })\n }\n\n const disconnect = () => {\n logType(SocketEvents.DISCONNECT)\n cleanup()\n try {\n socket.addEventListener(\"error\", noop, { once: true })\n socket.close()\n } catch {}\n }\n\n const onOpen = () => {\n logType(SocketEvents.CONNECTED)\n onConnected()\n heartbeat()\n socket.removeEventListener(\"open\", onOpen)\n onReady((onMsg, onHalt) => {\n cleanup = () => {\n cleanup = noop\n stopTimeout()\n socket.removeEventListener(\"error\", onError)\n socket.removeEventListener(\"ping\", heartbeat)\n socket.removeEventListener(\"message\", _onMessage)\n socket.removeEventListener(\"close\", onClose)\n }\n\n suicide = (e?: any) => {\n suicide = noop\n cleanup()\n onHalt(e)\n }\n\n const _onMessage = (e: MessageEvent) => {\n heartbeat()\n if (typeof e.data === \"string\") {\n logMsg(SocketEvents.IN, e.data)\n onMsg(JSON.parse(e.data))\n }\n }\n\n socket.addEventListener(\"ping\", heartbeat)\n socket.addEventListener(\"message\", _onMessage)\n socket.addEventListener(\"error\", onError)\n socket.addEventListener(\"close\", onClose)\n return {\n send(m) {\n const msg = JSON.stringify(m)\n logMsg(SocketEvents.OUT, msg)\n socket.send(msg)\n },\n disconnect,\n }\n })\n }\n\n cleanup = () => {\n cleanup = noop\n stopTimeout()\n socket.removeEventListener(\"error\", onError)\n socket.removeEventListener(\"close\", onClose)\n socket.removeEventListener(\"open\", onOpen)\n }\n\n socket.addEventListener(\"open\", onOpen)\n socket.addEventListener(\"error\", onError)\n\n return disconnect\n })\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,83 @@
1
+ import { JsonRpcProvider } from '@polkadot-api/json-rpc-provider';
2
+ export { JsonRpcProvider } from '@polkadot-api/json-rpc-provider';
3
+ import { InnerJsonRpcProvider } from '@polkadot-api/json-rpc-provider-proxy';
4
+ export { InnerJsonRpcProvider } from '@polkadot-api/json-rpc-provider-proxy';
5
+
6
+ declare enum WsEvent {
7
+ CONNECTING = "CONNECTING",
8
+ CONNECTED = "CONNECTED",
9
+ ERROR = "ERROR",
10
+ CLOSE = "CLOSE"
11
+ }
12
+ type WsConnecting = {
13
+ type: WsEvent.CONNECTING;
14
+ uri: string;
15
+ };
16
+ type WsConnected = {
17
+ type: WsEvent.CONNECTED;
18
+ uri: string;
19
+ };
20
+ type WsError = {
21
+ type: WsEvent.ERROR;
22
+ event: any;
23
+ };
24
+ type WsClose = {
25
+ type: WsEvent.CLOSE;
26
+ event: any;
27
+ };
28
+ type StatusChange = WsConnecting | WsConnected | WsError | WsClose;
29
+ type WsJsonRpcProvider = JsonRpcProvider & {
30
+ switch: (uri?: string) => void;
31
+ getStatus: () => StatusChange;
32
+ };
33
+
34
+ declare enum SocketEvents {
35
+ CONNECTING = "CONNECTING",
36
+ CONNECTED = "CONNECTED",
37
+ TIMEOUT = "TIMEOUT",
38
+ STALE = "STALE",
39
+ ERROR = "ERROR",
40
+ CLOSE = "CLOSE",
41
+ DISCONNECT = "DISCONNECT",
42
+ IN = "IN",
43
+ OUT = "OUT"
44
+ }
45
+ type SocketLoggerEvent = {
46
+ type: SocketEvents.CONNECTING;
47
+ url: string;
48
+ } | {
49
+ type: SocketEvents.CONNECTED;
50
+ } | {
51
+ type: SocketEvents.DISCONNECT;
52
+ } | {
53
+ type: SocketEvents.ERROR;
54
+ error: any;
55
+ } | {
56
+ type: SocketEvents.CLOSE;
57
+ } | {
58
+ type: SocketEvents.STALE;
59
+ } | {
60
+ type: SocketEvents.TIMEOUT;
61
+ } | {
62
+ type: SocketEvents.IN;
63
+ msg: string;
64
+ } | {
65
+ type: SocketEvents.OUT;
66
+ msg: string;
67
+ };
68
+ type SocketLoggerFn = (event: SocketLoggerEvent) => void;
69
+ type WebSocketClass = typeof WebSocket;
70
+
71
+ type Middleware = (base: InnerJsonRpcProvider) => InnerJsonRpcProvider;
72
+
73
+ declare const getWsProvider: (endpoints: string | Array<string>, config?: Partial<{
74
+ onStatusChanged: (status: StatusChange) => void;
75
+ timeout: number;
76
+ heartbeatTimeout: number;
77
+ websocketClass: WebSocketClass;
78
+ middleware: Middleware;
79
+ logger: SocketLoggerFn;
80
+ }>) => WsJsonRpcProvider;
81
+
82
+ export { SocketEvents, WsEvent, getWsProvider };
83
+ export type { Middleware, SocketLoggerFn, StatusChange, WebSocketClass, WsClose, WsConnected, WsConnecting, WsError, WsJsonRpcProvider };
package/dist/index.js ADDED
@@ -0,0 +1,250 @@
1
+ 'use strict';
2
+
3
+ var jsonRpcProviderProxy = require('@polkadot-api/json-rpc-provider-proxy');
4
+ var utils = require('@polkadot-api/utils');
5
+ var rxjs = require('rxjs');
6
+
7
+ var WsEvent = /* @__PURE__ */ ((WsEvent2) => {
8
+ WsEvent2["CONNECTING"] = "CONNECTING";
9
+ WsEvent2["CONNECTED"] = "CONNECTED";
10
+ WsEvent2["ERROR"] = "ERROR";
11
+ WsEvent2["CLOSE"] = "CLOSE";
12
+ return WsEvent2;
13
+ })(WsEvent || {});
14
+ var SocketEvents = /* @__PURE__ */ ((SocketEvents2) => {
15
+ SocketEvents2["CONNECTING"] = "CONNECTING";
16
+ SocketEvents2["CONNECTED"] = "CONNECTED";
17
+ SocketEvents2["TIMEOUT"] = "TIMEOUT";
18
+ SocketEvents2["STALE"] = "STALE";
19
+ SocketEvents2["ERROR"] = "ERROR";
20
+ SocketEvents2["CLOSE"] = "CLOSE";
21
+ SocketEvents2["DISCONNECT"] = "DISCONNECT";
22
+ SocketEvents2["IN"] = "IN";
23
+ SocketEvents2["OUT"] = "OUT";
24
+ return SocketEvents2;
25
+ })(SocketEvents || {});
26
+
27
+ const getAsyncProvider = (input) => (onMessage, _onHalt) => {
28
+ let connection = null;
29
+ let pending = [];
30
+ const done = () => {
31
+ stop();
32
+ onHalt = stop = utils.noop;
33
+ connection = void 0;
34
+ pending = [];
35
+ };
36
+ let onHalt = (e) => {
37
+ done();
38
+ _onHalt(e);
39
+ };
40
+ let stop = input((cb) => {
41
+ stop = utils.noop;
42
+ if (!cb) {
43
+ onHalt();
44
+ } else {
45
+ connection = cb(onMessage, onHalt);
46
+ pending.forEach((x) => connection?.send(x));
47
+ pending = [];
48
+ }
49
+ });
50
+ return {
51
+ send: (msg) => {
52
+ if (connection) connection.send(msg);
53
+ else if (connection === null) pending.push(msg);
54
+ },
55
+ disconnect: () => {
56
+ const x = connection;
57
+ done();
58
+ x?.disconnect();
59
+ }
60
+ };
61
+ };
62
+
63
+ const withSocket = (getWebsocket, heartbeatTimeout, connectionTimeout, logger) => {
64
+ const logType = logger ? (type) => logger({ type }) : utils.noop;
65
+ const logMsg = logger ? (type, msg) => logger({ type, msg }) : utils.noop;
66
+ return getAsyncProvider((onReady) => {
67
+ const [socket, onConnected] = getWebsocket();
68
+ logger?.({ type: SocketEvents.CONNECTING, url: socket.url });
69
+ let suicide = () => {
70
+ suicide = utils.noop;
71
+ cleanup();
72
+ onReady(null);
73
+ };
74
+ let isFirst = true;
75
+ let heartbeatToken;
76
+ const heartbeat = () => {
77
+ clearTimeout(heartbeatToken);
78
+ const [time, event] = isFirst ? [connectionTimeout, SocketEvents.TIMEOUT] : [heartbeatTimeout, SocketEvents.STALE];
79
+ isFirst = false;
80
+ heartbeatToken = setTimeout(() => {
81
+ logType(event);
82
+ suicide({
83
+ type: WsEvent.ERROR,
84
+ event: { type: "timeout" }
85
+ });
86
+ }, time);
87
+ };
88
+ const stopTimeout = () => {
89
+ clearTimeout(heartbeatToken);
90
+ };
91
+ heartbeat();
92
+ let cleanup = () => {
93
+ stopTimeout();
94
+ };
95
+ const onError = (event) => {
96
+ logger?.({ type: SocketEvents.ERROR, error: event });
97
+ suicide({
98
+ type: WsEvent.ERROR,
99
+ event
100
+ });
101
+ };
102
+ const onClose = (event) => {
103
+ logType(SocketEvents.CLOSE);
104
+ suicide({
105
+ type: WsEvent.CLOSE,
106
+ event
107
+ });
108
+ };
109
+ const disconnect = () => {
110
+ logType(SocketEvents.DISCONNECT);
111
+ cleanup();
112
+ try {
113
+ socket.addEventListener("error", utils.noop, { once: true });
114
+ socket.close();
115
+ } catch {
116
+ }
117
+ };
118
+ const onOpen = () => {
119
+ logType(SocketEvents.CONNECTED);
120
+ onConnected();
121
+ heartbeat();
122
+ socket.removeEventListener("open", onOpen);
123
+ onReady((onMsg, onHalt) => {
124
+ cleanup = () => {
125
+ cleanup = utils.noop;
126
+ stopTimeout();
127
+ socket.removeEventListener("error", onError);
128
+ socket.removeEventListener("ping", heartbeat);
129
+ socket.removeEventListener("message", _onMessage);
130
+ socket.removeEventListener("close", onClose);
131
+ };
132
+ suicide = (e) => {
133
+ suicide = utils.noop;
134
+ cleanup();
135
+ onHalt(e);
136
+ };
137
+ const _onMessage = (e) => {
138
+ heartbeat();
139
+ if (typeof e.data === "string") {
140
+ logMsg(SocketEvents.IN, e.data);
141
+ onMsg(JSON.parse(e.data));
142
+ }
143
+ };
144
+ socket.addEventListener("ping", heartbeat);
145
+ socket.addEventListener("message", _onMessage);
146
+ socket.addEventListener("error", onError);
147
+ socket.addEventListener("close", onClose);
148
+ return {
149
+ send(m) {
150
+ const msg = JSON.stringify(m);
151
+ logMsg(SocketEvents.OUT, msg);
152
+ socket.send(msg);
153
+ },
154
+ disconnect
155
+ };
156
+ });
157
+ };
158
+ cleanup = () => {
159
+ cleanup = utils.noop;
160
+ stopTimeout();
161
+ socket.removeEventListener("error", onError);
162
+ socket.removeEventListener("close", onClose);
163
+ socket.removeEventListener("open", onOpen);
164
+ };
165
+ socket.addEventListener("open", onOpen);
166
+ socket.addEventListener("error", onError);
167
+ return disconnect;
168
+ });
169
+ };
170
+
171
+ const defaultConfig = {
172
+ onStatusChanged: utils.noop,
173
+ timeout: 5e3,
174
+ heartbeatTimeout: 4e4,
175
+ middleware: rxjs.identity
176
+ };
177
+ const getWsProvider = (endpoints, config) => {
178
+ const {
179
+ onStatusChanged: _onStatuChanged,
180
+ timeout,
181
+ heartbeatTimeout,
182
+ middleware,
183
+ logger
184
+ } = {
185
+ ...defaultConfig,
186
+ ...config
187
+ };
188
+ const actualEndpoints = Array.isArray(endpoints) ? endpoints : [endpoints];
189
+ const WebsocketClass = config?.websocketClass ?? globalThis.WebSocket;
190
+ if (!WebsocketClass) throw new Error("Missing WebSocket class");
191
+ let idx = 0;
192
+ let switchTo;
193
+ let latestSocket = null;
194
+ let status = { type: WsEvent.CLOSE, event: null };
195
+ let prevUri;
196
+ const onStatusChanged = (x) => _onStatuChanged(status = x);
197
+ const socketProvider = middleware(
198
+ withSocket(
199
+ () => {
200
+ prevUri = latestSocket?.url;
201
+ const uri = switchTo ?? actualEndpoints[idx++ % actualEndpoints.length];
202
+ switchTo = void 0;
203
+ onStatusChanged({
204
+ type: WsEvent.CONNECTING,
205
+ uri
206
+ });
207
+ return [
208
+ latestSocket = new WebsocketClass(uri),
209
+ () => {
210
+ onStatusChanged({
211
+ type: WsEvent.CONNECTED,
212
+ uri
213
+ });
214
+ }
215
+ ];
216
+ },
217
+ heartbeatTimeout,
218
+ timeout,
219
+ logger
220
+ )
221
+ );
222
+ const provider = (onMsg, onHalt) => socketProvider(onMsg, (event) => {
223
+ onStatusChanged({
224
+ type: WsEvent.ERROR,
225
+ event
226
+ });
227
+ onHalt(event);
228
+ });
229
+ const result = jsonRpcProviderProxy.getSyncProvider((onReady) => {
230
+ if (!prevUri || latestSocket.url !== prevUri) {
231
+ onReady(provider);
232
+ return utils.noop;
233
+ }
234
+ const token = setTimeout(onReady, 250, provider);
235
+ return () => {
236
+ clearTimeout(token);
237
+ };
238
+ });
239
+ const switchFn = (uri) => {
240
+ if (status.type === WsEvent.CLOSE) return;
241
+ switchTo = uri;
242
+ if (status.type !== WsEvent.ERROR && latestSocket) latestSocket.close();
243
+ };
244
+ return Object.assign(result, { switch: switchFn, getStatus: () => status });
245
+ };
246
+
247
+ exports.SocketEvents = SocketEvents;
248
+ exports.WsEvent = WsEvent;
249
+ exports.getWsProvider = getWsProvider;
250
+ //# sourceMappingURL=index.js.map