@polkadot-api/ws-provider 0.2.1 → 0.3.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.
@@ -1,49 +1,126 @@
1
1
  import { getSyncProvider } from '@polkadot-api/json-rpc-provider-proxy';
2
2
 
3
- const getInternalWsProvider = (WebsocketClass) => (uri, protocols) => getSyncProvider(async () => {
4
- const socket = new WebsocketClass(uri, protocols);
5
- await new Promise((resolve, reject) => {
6
- const onOpen = () => {
7
- resolve();
8
- socket.removeEventListener("error", onError);
9
- };
10
- socket.addEventListener("open", onOpen, { once: true });
11
- const onError = (e) => {
12
- console.error(
13
- `Unable to connect to ${uri}${protocols ? ", protocols: " + protocols : ""}`
3
+ const timeoutError = {
4
+ type: 2 /* ERROR */,
5
+ event: { type: "timeout" }
6
+ };
7
+ const noop = () => {
8
+ };
9
+ const getInternalWsProvider = (WebsocketClass) => {
10
+ return (...args) => {
11
+ let endpoints = [];
12
+ let onStatusChanged = noop;
13
+ if (typeof args[1] === "function") onStatusChanged = args[1];
14
+ if (Array.isArray(args[0]))
15
+ endpoints = args[0].map(
16
+ (x) => typeof x === "string" ? [x] : [x.uri, x.protocol]
14
17
  );
15
- reject(e);
16
- socket.removeEventListener("open", onOpen);
17
- };
18
- socket.addEventListener("error", onError, { once: true });
19
- });
20
- return (onMessage, onHalt) => {
21
- const _onMessage = (e) => {
22
- if (typeof e.data === "string") onMessage(e.data);
23
- };
24
- const innerHalt = (reason) => (e) => {
25
- console.warn(`WS halt (${reason})`);
26
- console.log(e);
27
- onHalt();
28
- };
29
- const onError = innerHalt("err");
30
- const onClose = innerHalt("close");
31
- socket.addEventListener("message", _onMessage);
32
- socket.addEventListener("error", onError);
33
- socket.addEventListener("close", onClose);
34
- return {
35
- send: (msg) => {
36
- socket.send(msg);
37
- },
38
- disconnect: () => {
39
- socket.removeEventListener("message", _onMessage);
40
- socket.removeEventListener("error", onError);
41
- socket.removeEventListener("close", onClose);
42
- socket.close();
43
- }
18
+ else {
19
+ endpoints = [[args[0]]];
20
+ if (args[1] && args[1] !== onStatusChanged)
21
+ endpoints[0][1] = args[1];
22
+ if (args[2]) onStatusChanged = args[2];
23
+ }
24
+ let idx = 0;
25
+ let status;
26
+ let switchTo = null;
27
+ let disconnect = noop;
28
+ const result = getSyncProvider(async () => {
29
+ const [uri, protocols] = switchTo || endpoints[idx++ % endpoints.length];
30
+ switchTo = null;
31
+ const socket = new WebsocketClass(uri, protocols);
32
+ onStatusChanged(
33
+ status = {
34
+ type: 0 /* CONNECTING */,
35
+ uri,
36
+ protocols
37
+ }
38
+ );
39
+ await new Promise((resolve, reject) => {
40
+ const onOpen = () => {
41
+ cleanup();
42
+ resolve();
43
+ };
44
+ const onError = (e) => {
45
+ cleanup();
46
+ console.error(
47
+ `Unable to connect to ${uri}${protocols ? ", protocols: " + protocols : ""}`
48
+ );
49
+ onStatusChanged(
50
+ status = {
51
+ type: e ? 2 /* ERROR */ : 3 /* CLOSE */,
52
+ event: e
53
+ }
54
+ );
55
+ setTimeout(reject, e ? 300 : 0, e);
56
+ };
57
+ const timeoutToken = setTimeout(() => {
58
+ cleanup();
59
+ onStatusChanged(status = timeoutError);
60
+ reject(timeoutError.event);
61
+ }, 3500);
62
+ const cleanup = () => {
63
+ clearTimeout(timeoutToken);
64
+ socket.removeEventListener("error", onError);
65
+ socket.removeEventListener("open", onOpen);
66
+ };
67
+ socket.addEventListener("open", onOpen);
68
+ socket.addEventListener("error", onError);
69
+ disconnect = () => {
70
+ onError(null);
71
+ };
72
+ });
73
+ onStatusChanged(
74
+ status = {
75
+ type: 1 /* CONNECTED */,
76
+ uri,
77
+ protocols
78
+ }
79
+ );
80
+ return (onMessage, onHalt) => {
81
+ const _onMessage = (e) => {
82
+ if (typeof e.data === "string") onMessage(e.data);
83
+ };
84
+ const innerHalt = (reason) => (e) => {
85
+ console.warn(`WS halt (${reason})`);
86
+ onStatusChanged(
87
+ status = {
88
+ type: reason,
89
+ event: e
90
+ }
91
+ );
92
+ onHalt();
93
+ };
94
+ const onError = innerHalt(2 /* ERROR */);
95
+ const onClose = innerHalt(3 /* CLOSE */);
96
+ socket.addEventListener("message", _onMessage);
97
+ socket.addEventListener("error", onError);
98
+ socket.addEventListener("close", onClose);
99
+ disconnect = (withHalt) => {
100
+ disconnect = noop;
101
+ socket.removeEventListener("message", _onMessage);
102
+ socket.removeEventListener("error", onError);
103
+ socket.removeEventListener("close", onClose);
104
+ socket.close();
105
+ if (withHalt) onClose({});
106
+ };
107
+ return {
108
+ send: (msg) => {
109
+ socket.send(msg);
110
+ },
111
+ disconnect
112
+ };
113
+ };
114
+ });
115
+ result.getStatus = () => status;
116
+ result.switch = (...args2) => {
117
+ if (status.type === 3 /* CLOSE */) return;
118
+ if (args2.length) switchTo = args2;
119
+ if (status.type !== 2 /* ERROR */) disconnect(true);
44
120
  };
121
+ return result;
45
122
  };
46
- });
123
+ };
47
124
 
48
125
  export { getInternalWsProvider };
49
126
  //# sourceMappingURL=ws-provider.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"ws-provider.mjs","sources":["../../../src/ws-provider.ts"],"sourcesContent":["import type { JsonRpcProvider } from \"@polkadot-api/json-rpc-provider\"\nimport { getSyncProvider } from \"@polkadot-api/json-rpc-provider-proxy\"\n\nexport const getInternalWsProvider =\n (WebsocketClass: typeof WebSocket) =>\n (uri: string, protocols?: string | string[]): JsonRpcProvider =>\n getSyncProvider(async () => {\n const socket = new WebsocketClass(uri, protocols)\n\n await new Promise<void>((resolve, reject) => {\n const onOpen = () => {\n resolve()\n socket.removeEventListener(\"error\", onError)\n }\n socket.addEventListener(\"open\", onOpen, { once: true })\n\n const onError = (e: Event) => {\n console.error(\n `Unable to connect to ${uri}${\n protocols ? \", protocols: \" + protocols : \"\"\n }`,\n )\n reject(e)\n socket.removeEventListener(\"open\", onOpen)\n }\n socket.addEventListener(\"error\", onError, { once: true })\n })\n\n return (onMessage, onHalt) => {\n const _onMessage = (e: MessageEvent) => {\n if (typeof e.data === \"string\") onMessage(e.data)\n }\n const innerHalt = (reason: string) => (e: any) => {\n console.warn(`WS halt (${reason})`)\n console.log(e)\n onHalt()\n }\n const onError = innerHalt(\"err\")\n const onClose = innerHalt(\"close\")\n\n socket.addEventListener(\"message\", _onMessage)\n socket.addEventListener(\"error\", onError)\n socket.addEventListener(\"close\", onClose)\n\n return {\n send: (msg) => {\n socket.send(msg)\n },\n disconnect: () => {\n socket.removeEventListener(\"message\", _onMessage)\n socket.removeEventListener(\"error\", onError)\n socket.removeEventListener(\"close\", onClose)\n socket.close()\n },\n }\n }\n })\n"],"names":[],"mappings":";;AAGO,MAAM,wBACX,CAAC,cAAA,KACD,CAAC,GAAa,EAAA,SAAA,KACZ,gBAAgB,YAAY;AAC1B,EAAA,MAAM,MAAS,GAAA,IAAI,cAAe,CAAA,GAAA,EAAK,SAAS,CAAA,CAAA;AAEhD,EAAA,MAAM,IAAI,OAAA,CAAc,CAAC,OAAA,EAAS,MAAW,KAAA;AAC3C,IAAA,MAAM,SAAS,MAAM;AACnB,MAAQ,OAAA,EAAA,CAAA;AACR,MAAO,MAAA,CAAA,mBAAA,CAAoB,SAAS,OAAO,CAAA,CAAA;AAAA,KAC7C,CAAA;AACA,IAAA,MAAA,CAAO,iBAAiB,MAAQ,EAAA,MAAA,EAAQ,EAAE,IAAA,EAAM,MAAM,CAAA,CAAA;AAEtD,IAAM,MAAA,OAAA,GAAU,CAAC,CAAa,KAAA;AAC5B,MAAQ,OAAA,CAAA,KAAA;AAAA,QACN,wBAAwB,GAAG,CAAA,EACzB,SAAY,GAAA,eAAA,GAAkB,YAAY,EAC5C,CAAA,CAAA;AAAA,OACF,CAAA;AACA,MAAA,MAAA,CAAO,CAAC,CAAA,CAAA;AACR,MAAO,MAAA,CAAA,mBAAA,CAAoB,QAAQ,MAAM,CAAA,CAAA;AAAA,KAC3C,CAAA;AACA,IAAA,MAAA,CAAO,iBAAiB,OAAS,EAAA,OAAA,EAAS,EAAE,IAAA,EAAM,MAAM,CAAA,CAAA;AAAA,GACzD,CAAA,CAAA;AAED,EAAO,OAAA,CAAC,WAAW,MAAW,KAAA;AAC5B,IAAM,MAAA,UAAA,GAAa,CAAC,CAAoB,KAAA;AACtC,MAAA,IAAI,OAAO,CAAE,CAAA,IAAA,KAAS,QAAU,EAAA,SAAA,CAAU,EAAE,IAAI,CAAA,CAAA;AAAA,KAClD,CAAA;AACA,IAAA,MAAM,SAAY,GAAA,CAAC,MAAmB,KAAA,CAAC,CAAW,KAAA;AAChD,MAAQ,OAAA,CAAA,IAAA,CAAK,CAAY,SAAA,EAAA,MAAM,CAAG,CAAA,CAAA,CAAA,CAAA;AAClC,MAAA,OAAA,CAAQ,IAAI,CAAC,CAAA,CAAA;AACb,MAAO,MAAA,EAAA,CAAA;AAAA,KACT,CAAA;AACA,IAAM,MAAA,OAAA,GAAU,UAAU,KAAK,CAAA,CAAA;AAC/B,IAAM,MAAA,OAAA,GAAU,UAAU,OAAO,CAAA,CAAA;AAEjC,IAAO,MAAA,CAAA,gBAAA,CAAiB,WAAW,UAAU,CAAA,CAAA;AAC7C,IAAO,MAAA,CAAA,gBAAA,CAAiB,SAAS,OAAO,CAAA,CAAA;AACxC,IAAO,MAAA,CAAA,gBAAA,CAAiB,SAAS,OAAO,CAAA,CAAA;AAExC,IAAO,OAAA;AAAA,MACL,IAAA,EAAM,CAAC,GAAQ,KAAA;AACb,QAAA,MAAA,CAAO,KAAK,GAAG,CAAA,CAAA;AAAA,OACjB;AAAA,MACA,YAAY,MAAM;AAChB,QAAO,MAAA,CAAA,mBAAA,CAAoB,WAAW,UAAU,CAAA,CAAA;AAChD,QAAO,MAAA,CAAA,mBAAA,CAAoB,SAAS,OAAO,CAAA,CAAA;AAC3C,QAAO,MAAA,CAAA,mBAAA,CAAoB,SAAS,OAAO,CAAA,CAAA;AAC3C,QAAA,MAAA,CAAO,KAAM,EAAA,CAAA;AAAA,OACf;AAAA,KACF,CAAA;AAAA,GACF,CAAA;AACF,CAAC;;;;"}
1
+ {"version":3,"file":"ws-provider.mjs","sources":["../../../src/ws-provider.ts"],"sourcesContent":["import type { JsonRpcProvider } from \"@polkadot-api/json-rpc-provider\"\nimport { getSyncProvider } from \"@polkadot-api/json-rpc-provider-proxy\"\n\nexport enum WsEvent {\n CONNECTING,\n CONNECTED,\n ERROR,\n CLOSE,\n}\nexport type WsConnecting = {\n type: WsEvent.CONNECTING\n uri: string\n protocols?: string | string[]\n}\nexport type WsConnected = {\n type: WsEvent.CONNECTED\n uri: string\n protocols?: string | 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, protocol?: string[]) => void\n getStatus: () => StatusChange\n}\n\nexport interface GetWsProviderInput {\n (\n uri: string,\n protocols?: string | string[],\n onStatusChanged?: (status: StatusChange) => void,\n ): WsJsonRpcProvider\n (\n uri: string,\n onStatusChanged?: (status: StatusChange) => void,\n ): WsJsonRpcProvider\n (\n endpoints: Array<string | { uri: string; protocol: string[] }>,\n onStatusChanged?: (status: StatusChange) => void,\n ): WsJsonRpcProvider\n}\n\nconst timeoutError: StatusChange = {\n type: WsEvent.ERROR,\n event: { type: \"timeout\" },\n}\n\nconst noop = () => {}\nexport const getInternalWsProvider = (\n WebsocketClass: typeof WebSocket,\n): GetWsProviderInput => {\n return (...args): WsJsonRpcProvider => {\n let endpoints: Array<[string, string | string[]] | [string]> = []\n let onStatusChanged: (status: StatusChange) => void = noop\n\n if (typeof args[1] === \"function\") onStatusChanged = args[1]\n if (Array.isArray(args[0]))\n endpoints = args[0].map((x) =>\n typeof x === \"string\" ? [x] : [x.uri, x.protocol],\n )\n else {\n endpoints = [[args[0]]]\n if (args[1] && args[1] !== onStatusChanged)\n endpoints[0][1] = args[1] as any\n if (args[2]) onStatusChanged = args[2] as any\n }\n let idx = 0\n let status: StatusChange\n let switchTo: [string] | [string, string | string[]] | null = null\n let disconnect: (withHalt?: boolean) => void = noop\n\n const result = getSyncProvider(async () => {\n const [uri, protocols] = switchTo || endpoints[idx++ % endpoints.length]\n switchTo = null\n const socket = new WebsocketClass(uri, protocols)\n onStatusChanged(\n (status = {\n type: WsEvent.CONNECTING,\n uri,\n protocols,\n }),\n )\n\n await new Promise<void>((resolve, reject) => {\n const onOpen = () => {\n cleanup()\n resolve()\n }\n\n const onError = (e: Event | null) => {\n cleanup()\n console.error(\n `Unable to connect to ${uri}${\n protocols ? \", protocols: \" + protocols : \"\"\n }`,\n )\n onStatusChanged(\n (status = {\n type: e ? WsEvent.ERROR : WsEvent.CLOSE,\n event: e,\n }),\n )\n setTimeout(reject, e ? 300 : 0, e)\n }\n\n const timeoutToken = setTimeout(() => {\n cleanup()\n onStatusChanged((status = timeoutError))\n reject(timeoutError.event)\n }, 3_500)\n const cleanup = () => {\n clearTimeout(timeoutToken)\n socket.removeEventListener(\"error\", onError)\n socket.removeEventListener(\"open\", onOpen)\n }\n socket.addEventListener(\"open\", onOpen)\n socket.addEventListener(\"error\", onError)\n disconnect = () => {\n onError(null)\n }\n })\n\n onStatusChanged(\n (status = {\n type: WsEvent.CONNECTED,\n uri,\n protocols,\n }),\n )\n\n return (onMessage, onHalt) => {\n const _onMessage = (e: MessageEvent) => {\n if (typeof e.data === \"string\") onMessage(e.data)\n }\n const innerHalt =\n (reason: WsEvent.CLOSE | WsEvent.ERROR) => (e: any) => {\n console.warn(`WS halt (${reason})`)\n onStatusChanged(\n (status = {\n type: reason,\n event: e,\n }),\n )\n onHalt()\n }\n const onError = innerHalt(WsEvent.ERROR)\n const onClose = innerHalt(WsEvent.CLOSE)\n\n socket.addEventListener(\"message\", _onMessage)\n socket.addEventListener(\"error\", onError)\n socket.addEventListener(\"close\", onClose)\n disconnect = (withHalt) => {\n disconnect = noop\n socket.removeEventListener(\"message\", _onMessage)\n socket.removeEventListener(\"error\", onError)\n socket.removeEventListener(\"close\", onClose)\n socket.close()\n if (withHalt) onClose({})\n }\n\n return {\n send: (msg) => {\n socket.send(msg)\n },\n disconnect,\n }\n }\n }) as WsJsonRpcProvider\n\n result.getStatus = () => status\n result.switch = (...args) => {\n if (status.type === WsEvent.CLOSE) return\n if (args.length) switchTo = args as any\n if (status.type !== WsEvent.ERROR) disconnect(true)\n }\n return result\n }\n}\n"],"names":["args"],"mappings":"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"}
@@ -1,6 +1,44 @@
1
- import * as _polkadot_api_json_rpc_provider from '@polkadot-api/json-rpc-provider';
1
+ import { JsonRpcProvider } from '@polkadot-api/json-rpc-provider';
2
2
  export { JsonRpcProvider } from '@polkadot-api/json-rpc-provider';
3
3
 
4
- declare const getWsProvider: (uri: string, protocols?: string | string[]) => _polkadot_api_json_rpc_provider.JsonRpcProvider;
4
+ declare enum WsEvent {
5
+ CONNECTING = 0,
6
+ CONNECTED = 1,
7
+ ERROR = 2,
8
+ CLOSE = 3
9
+ }
10
+ type WsConnecting = {
11
+ type: WsEvent.CONNECTING;
12
+ uri: string;
13
+ protocols?: string | string[];
14
+ };
15
+ type WsConnected = {
16
+ type: WsEvent.CONNECTED;
17
+ uri: string;
18
+ protocols?: string | 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, protocol?: string[]) => void;
31
+ getStatus: () => StatusChange;
32
+ };
33
+ interface GetWsProviderInput {
34
+ (uri: string, protocols?: string | string[], onStatusChanged?: (status: StatusChange) => void): WsJsonRpcProvider;
35
+ (uri: string, onStatusChanged?: (status: StatusChange) => void): WsJsonRpcProvider;
36
+ (endpoints: Array<string | {
37
+ uri: string;
38
+ protocol: string[];
39
+ }>, onStatusChanged?: (status: StatusChange) => void): WsJsonRpcProvider;
40
+ }
41
+
42
+ declare const getWsProvider: GetWsProviderInput;
5
43
 
6
44
  export { getWsProvider };
package/dist/node/node.js CHANGED
@@ -3,50 +3,127 @@
3
3
  var ws = require('ws');
4
4
  var jsonRpcProviderProxy = require('@polkadot-api/json-rpc-provider-proxy');
5
5
 
6
- const getInternalWsProvider = (WebsocketClass) => (uri, protocols) => jsonRpcProviderProxy.getSyncProvider(async () => {
7
- const socket = new WebsocketClass(uri, protocols);
8
- await new Promise((resolve, reject) => {
9
- const onOpen = () => {
10
- resolve();
11
- socket.removeEventListener("error", onError);
12
- };
13
- socket.addEventListener("open", onOpen, { once: true });
14
- const onError = (e) => {
15
- console.error(
16
- `Unable to connect to ${uri}${protocols ? ", protocols: " + protocols : ""}`
6
+ const timeoutError = {
7
+ type: 2 /* ERROR */,
8
+ event: { type: "timeout" }
9
+ };
10
+ const noop = () => {
11
+ };
12
+ const getInternalWsProvider = (WebsocketClass) => {
13
+ return (...args) => {
14
+ let endpoints = [];
15
+ let onStatusChanged = noop;
16
+ if (typeof args[1] === "function") onStatusChanged = args[1];
17
+ if (Array.isArray(args[0]))
18
+ endpoints = args[0].map(
19
+ (x) => typeof x === "string" ? [x] : [x.uri, x.protocol]
17
20
  );
18
- reject(e);
19
- socket.removeEventListener("open", onOpen);
20
- };
21
- socket.addEventListener("error", onError, { once: true });
22
- });
23
- return (onMessage, onHalt) => {
24
- const _onMessage = (e) => {
25
- if (typeof e.data === "string") onMessage(e.data);
26
- };
27
- const innerHalt = (reason) => (e) => {
28
- console.warn(`WS halt (${reason})`);
29
- console.log(e);
30
- onHalt();
31
- };
32
- const onError = innerHalt("err");
33
- const onClose = innerHalt("close");
34
- socket.addEventListener("message", _onMessage);
35
- socket.addEventListener("error", onError);
36
- socket.addEventListener("close", onClose);
37
- return {
38
- send: (msg) => {
39
- socket.send(msg);
40
- },
41
- disconnect: () => {
42
- socket.removeEventListener("message", _onMessage);
43
- socket.removeEventListener("error", onError);
44
- socket.removeEventListener("close", onClose);
45
- socket.close();
46
- }
21
+ else {
22
+ endpoints = [[args[0]]];
23
+ if (args[1] && args[1] !== onStatusChanged)
24
+ endpoints[0][1] = args[1];
25
+ if (args[2]) onStatusChanged = args[2];
26
+ }
27
+ let idx = 0;
28
+ let status;
29
+ let switchTo = null;
30
+ let disconnect = noop;
31
+ const result = jsonRpcProviderProxy.getSyncProvider(async () => {
32
+ const [uri, protocols] = switchTo || endpoints[idx++ % endpoints.length];
33
+ switchTo = null;
34
+ const socket = new WebsocketClass(uri, protocols);
35
+ onStatusChanged(
36
+ status = {
37
+ type: 0 /* CONNECTING */,
38
+ uri,
39
+ protocols
40
+ }
41
+ );
42
+ await new Promise((resolve, reject) => {
43
+ const onOpen = () => {
44
+ cleanup();
45
+ resolve();
46
+ };
47
+ const onError = (e) => {
48
+ cleanup();
49
+ console.error(
50
+ `Unable to connect to ${uri}${protocols ? ", protocols: " + protocols : ""}`
51
+ );
52
+ onStatusChanged(
53
+ status = {
54
+ type: e ? 2 /* ERROR */ : 3 /* CLOSE */,
55
+ event: e
56
+ }
57
+ );
58
+ setTimeout(reject, e ? 300 : 0, e);
59
+ };
60
+ const timeoutToken = setTimeout(() => {
61
+ cleanup();
62
+ onStatusChanged(status = timeoutError);
63
+ reject(timeoutError.event);
64
+ }, 3500);
65
+ const cleanup = () => {
66
+ clearTimeout(timeoutToken);
67
+ socket.removeEventListener("error", onError);
68
+ socket.removeEventListener("open", onOpen);
69
+ };
70
+ socket.addEventListener("open", onOpen);
71
+ socket.addEventListener("error", onError);
72
+ disconnect = () => {
73
+ onError(null);
74
+ };
75
+ });
76
+ onStatusChanged(
77
+ status = {
78
+ type: 1 /* CONNECTED */,
79
+ uri,
80
+ protocols
81
+ }
82
+ );
83
+ return (onMessage, onHalt) => {
84
+ const _onMessage = (e) => {
85
+ if (typeof e.data === "string") onMessage(e.data);
86
+ };
87
+ const innerHalt = (reason) => (e) => {
88
+ console.warn(`WS halt (${reason})`);
89
+ onStatusChanged(
90
+ status = {
91
+ type: reason,
92
+ event: e
93
+ }
94
+ );
95
+ onHalt();
96
+ };
97
+ const onError = innerHalt(2 /* ERROR */);
98
+ const onClose = innerHalt(3 /* CLOSE */);
99
+ socket.addEventListener("message", _onMessage);
100
+ socket.addEventListener("error", onError);
101
+ socket.addEventListener("close", onClose);
102
+ disconnect = (withHalt) => {
103
+ disconnect = noop;
104
+ socket.removeEventListener("message", _onMessage);
105
+ socket.removeEventListener("error", onError);
106
+ socket.removeEventListener("close", onClose);
107
+ socket.close();
108
+ if (withHalt) onClose({});
109
+ };
110
+ return {
111
+ send: (msg) => {
112
+ socket.send(msg);
113
+ },
114
+ disconnect
115
+ };
116
+ };
117
+ });
118
+ result.getStatus = () => status;
119
+ result.switch = (...args2) => {
120
+ if (status.type === 3 /* CLOSE */) return;
121
+ if (args2.length) switchTo = args2;
122
+ if (status.type !== 2 /* ERROR */) disconnect(true);
47
123
  };
124
+ return result;
48
125
  };
49
- });
126
+ };
50
127
 
51
128
  class WS extends ws.WebSocket {
52
129
  close() {
@@ -1 +1 @@
1
- {"version":3,"file":"node.js","sources":["../../src/ws-provider.ts","../../src/node.ts"],"sourcesContent":["import type { JsonRpcProvider } from \"@polkadot-api/json-rpc-provider\"\nimport { getSyncProvider } from \"@polkadot-api/json-rpc-provider-proxy\"\n\nexport const getInternalWsProvider =\n (WebsocketClass: typeof WebSocket) =>\n (uri: string, protocols?: string | string[]): JsonRpcProvider =>\n getSyncProvider(async () => {\n const socket = new WebsocketClass(uri, protocols)\n\n await new Promise<void>((resolve, reject) => {\n const onOpen = () => {\n resolve()\n socket.removeEventListener(\"error\", onError)\n }\n socket.addEventListener(\"open\", onOpen, { once: true })\n\n const onError = (e: Event) => {\n console.error(\n `Unable to connect to ${uri}${\n protocols ? \", protocols: \" + protocols : \"\"\n }`,\n )\n reject(e)\n socket.removeEventListener(\"open\", onOpen)\n }\n socket.addEventListener(\"error\", onError, { once: true })\n })\n\n return (onMessage, onHalt) => {\n const _onMessage = (e: MessageEvent) => {\n if (typeof e.data === \"string\") onMessage(e.data)\n }\n const innerHalt = (reason: string) => (e: any) => {\n console.warn(`WS halt (${reason})`)\n console.log(e)\n onHalt()\n }\n const onError = innerHalt(\"err\")\n const onClose = innerHalt(\"close\")\n\n socket.addEventListener(\"message\", _onMessage)\n socket.addEventListener(\"error\", onError)\n socket.addEventListener(\"close\", onClose)\n\n return {\n send: (msg) => {\n socket.send(msg)\n },\n disconnect: () => {\n socket.removeEventListener(\"message\", _onMessage)\n socket.removeEventListener(\"error\", onError)\n socket.removeEventListener(\"close\", onClose)\n socket.close()\n },\n }\n }\n })\n","// @ts-ignore\nimport { WebSocket } from \"ws\"\nimport { getInternalWsProvider } from \"./ws-provider\"\nexport type { JsonRpcProvider } from \"@polkadot-api/json-rpc-provider\"\n\nclass WS extends WebSocket {\n close() {\n ;(this as any).terminate()\n }\n}\n\nexport const getWsProvider = getInternalWsProvider(WS as any)\n"],"names":["getSyncProvider","WebSocket"],"mappings":";;;;;AAGO,MAAM,wBACX,CAAC,cAAA,KACD,CAAC,GAAa,EAAA,SAAA,KACZA,qCAAgB,YAAY;AAC1B,EAAA,MAAM,MAAS,GAAA,IAAI,cAAe,CAAA,GAAA,EAAK,SAAS,CAAA,CAAA;AAEhD,EAAA,MAAM,IAAI,OAAA,CAAc,CAAC,OAAA,EAAS,MAAW,KAAA;AAC3C,IAAA,MAAM,SAAS,MAAM;AACnB,MAAQ,OAAA,EAAA,CAAA;AACR,MAAO,MAAA,CAAA,mBAAA,CAAoB,SAAS,OAAO,CAAA,CAAA;AAAA,KAC7C,CAAA;AACA,IAAA,MAAA,CAAO,iBAAiB,MAAQ,EAAA,MAAA,EAAQ,EAAE,IAAA,EAAM,MAAM,CAAA,CAAA;AAEtD,IAAM,MAAA,OAAA,GAAU,CAAC,CAAa,KAAA;AAC5B,MAAQ,OAAA,CAAA,KAAA;AAAA,QACN,wBAAwB,GAAG,CAAA,EACzB,SAAY,GAAA,eAAA,GAAkB,YAAY,EAC5C,CAAA,CAAA;AAAA,OACF,CAAA;AACA,MAAA,MAAA,CAAO,CAAC,CAAA,CAAA;AACR,MAAO,MAAA,CAAA,mBAAA,CAAoB,QAAQ,MAAM,CAAA,CAAA;AAAA,KAC3C,CAAA;AACA,IAAA,MAAA,CAAO,iBAAiB,OAAS,EAAA,OAAA,EAAS,EAAE,IAAA,EAAM,MAAM,CAAA,CAAA;AAAA,GACzD,CAAA,CAAA;AAED,EAAO,OAAA,CAAC,WAAW,MAAW,KAAA;AAC5B,IAAM,MAAA,UAAA,GAAa,CAAC,CAAoB,KAAA;AACtC,MAAA,IAAI,OAAO,CAAE,CAAA,IAAA,KAAS,QAAU,EAAA,SAAA,CAAU,EAAE,IAAI,CAAA,CAAA;AAAA,KAClD,CAAA;AACA,IAAA,MAAM,SAAY,GAAA,CAAC,MAAmB,KAAA,CAAC,CAAW,KAAA;AAChD,MAAQ,OAAA,CAAA,IAAA,CAAK,CAAY,SAAA,EAAA,MAAM,CAAG,CAAA,CAAA,CAAA,CAAA;AAClC,MAAA,OAAA,CAAQ,IAAI,CAAC,CAAA,CAAA;AACb,MAAO,MAAA,EAAA,CAAA;AAAA,KACT,CAAA;AACA,IAAM,MAAA,OAAA,GAAU,UAAU,KAAK,CAAA,CAAA;AAC/B,IAAM,MAAA,OAAA,GAAU,UAAU,OAAO,CAAA,CAAA;AAEjC,IAAO,MAAA,CAAA,gBAAA,CAAiB,WAAW,UAAU,CAAA,CAAA;AAC7C,IAAO,MAAA,CAAA,gBAAA,CAAiB,SAAS,OAAO,CAAA,CAAA;AACxC,IAAO,MAAA,CAAA,gBAAA,CAAiB,SAAS,OAAO,CAAA,CAAA;AAExC,IAAO,OAAA;AAAA,MACL,IAAA,EAAM,CAAC,GAAQ,KAAA;AACb,QAAA,MAAA,CAAO,KAAK,GAAG,CAAA,CAAA;AAAA,OACjB;AAAA,MACA,YAAY,MAAM;AAChB,QAAO,MAAA,CAAA,mBAAA,CAAoB,WAAW,UAAU,CAAA,CAAA;AAChD,QAAO,MAAA,CAAA,mBAAA,CAAoB,SAAS,OAAO,CAAA,CAAA;AAC3C,QAAO,MAAA,CAAA,mBAAA,CAAoB,SAAS,OAAO,CAAA,CAAA;AAC3C,QAAA,MAAA,CAAO,KAAM,EAAA,CAAA;AAAA,OACf;AAAA,KACF,CAAA;AAAA,GACF,CAAA;AACF,CAAC,CAAA;;ACnDL,MAAM,WAAWC,YAAU,CAAA;AAAA,EACzB,KAAQ,GAAA;AACL,IAAC,KAAa,SAAU,EAAA,CAAA;AAAA,GAC3B;AACF,CAAA;AAEa,MAAA,aAAA,GAAgB,sBAAsB,EAAS;;;;"}
1
+ {"version":3,"file":"node.js","sources":["../../src/ws-provider.ts","../../src/node.ts"],"sourcesContent":["import type { JsonRpcProvider } from \"@polkadot-api/json-rpc-provider\"\nimport { getSyncProvider } from \"@polkadot-api/json-rpc-provider-proxy\"\n\nexport enum WsEvent {\n CONNECTING,\n CONNECTED,\n ERROR,\n CLOSE,\n}\nexport type WsConnecting = {\n type: WsEvent.CONNECTING\n uri: string\n protocols?: string | string[]\n}\nexport type WsConnected = {\n type: WsEvent.CONNECTED\n uri: string\n protocols?: string | 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, protocol?: string[]) => void\n getStatus: () => StatusChange\n}\n\nexport interface GetWsProviderInput {\n (\n uri: string,\n protocols?: string | string[],\n onStatusChanged?: (status: StatusChange) => void,\n ): WsJsonRpcProvider\n (\n uri: string,\n onStatusChanged?: (status: StatusChange) => void,\n ): WsJsonRpcProvider\n (\n endpoints: Array<string | { uri: string; protocol: string[] }>,\n onStatusChanged?: (status: StatusChange) => void,\n ): WsJsonRpcProvider\n}\n\nconst timeoutError: StatusChange = {\n type: WsEvent.ERROR,\n event: { type: \"timeout\" },\n}\n\nconst noop = () => {}\nexport const getInternalWsProvider = (\n WebsocketClass: typeof WebSocket,\n): GetWsProviderInput => {\n return (...args): WsJsonRpcProvider => {\n let endpoints: Array<[string, string | string[]] | [string]> = []\n let onStatusChanged: (status: StatusChange) => void = noop\n\n if (typeof args[1] === \"function\") onStatusChanged = args[1]\n if (Array.isArray(args[0]))\n endpoints = args[0].map((x) =>\n typeof x === \"string\" ? [x] : [x.uri, x.protocol],\n )\n else {\n endpoints = [[args[0]]]\n if (args[1] && args[1] !== onStatusChanged)\n endpoints[0][1] = args[1] as any\n if (args[2]) onStatusChanged = args[2] as any\n }\n let idx = 0\n let status: StatusChange\n let switchTo: [string] | [string, string | string[]] | null = null\n let disconnect: (withHalt?: boolean) => void = noop\n\n const result = getSyncProvider(async () => {\n const [uri, protocols] = switchTo || endpoints[idx++ % endpoints.length]\n switchTo = null\n const socket = new WebsocketClass(uri, protocols)\n onStatusChanged(\n (status = {\n type: WsEvent.CONNECTING,\n uri,\n protocols,\n }),\n )\n\n await new Promise<void>((resolve, reject) => {\n const onOpen = () => {\n cleanup()\n resolve()\n }\n\n const onError = (e: Event | null) => {\n cleanup()\n console.error(\n `Unable to connect to ${uri}${\n protocols ? \", protocols: \" + protocols : \"\"\n }`,\n )\n onStatusChanged(\n (status = {\n type: e ? WsEvent.ERROR : WsEvent.CLOSE,\n event: e,\n }),\n )\n setTimeout(reject, e ? 300 : 0, e)\n }\n\n const timeoutToken = setTimeout(() => {\n cleanup()\n onStatusChanged((status = timeoutError))\n reject(timeoutError.event)\n }, 3_500)\n const cleanup = () => {\n clearTimeout(timeoutToken)\n socket.removeEventListener(\"error\", onError)\n socket.removeEventListener(\"open\", onOpen)\n }\n socket.addEventListener(\"open\", onOpen)\n socket.addEventListener(\"error\", onError)\n disconnect = () => {\n onError(null)\n }\n })\n\n onStatusChanged(\n (status = {\n type: WsEvent.CONNECTED,\n uri,\n protocols,\n }),\n )\n\n return (onMessage, onHalt) => {\n const _onMessage = (e: MessageEvent) => {\n if (typeof e.data === \"string\") onMessage(e.data)\n }\n const innerHalt =\n (reason: WsEvent.CLOSE | WsEvent.ERROR) => (e: any) => {\n console.warn(`WS halt (${reason})`)\n onStatusChanged(\n (status = {\n type: reason,\n event: e,\n }),\n )\n onHalt()\n }\n const onError = innerHalt(WsEvent.ERROR)\n const onClose = innerHalt(WsEvent.CLOSE)\n\n socket.addEventListener(\"message\", _onMessage)\n socket.addEventListener(\"error\", onError)\n socket.addEventListener(\"close\", onClose)\n disconnect = (withHalt) => {\n disconnect = noop\n socket.removeEventListener(\"message\", _onMessage)\n socket.removeEventListener(\"error\", onError)\n socket.removeEventListener(\"close\", onClose)\n socket.close()\n if (withHalt) onClose({})\n }\n\n return {\n send: (msg) => {\n socket.send(msg)\n },\n disconnect,\n }\n }\n }) as WsJsonRpcProvider\n\n result.getStatus = () => status\n result.switch = (...args) => {\n if (status.type === WsEvent.CLOSE) return\n if (args.length) switchTo = args as any\n if (status.type !== WsEvent.ERROR) disconnect(true)\n }\n return result\n }\n}\n","// @ts-ignore\nimport { WebSocket } from \"ws\"\nimport { getInternalWsProvider } from \"./ws-provider\"\nexport type { JsonRpcProvider } from \"@polkadot-api/json-rpc-provider\"\n\nclass WS extends WebSocket {\n close() {\n ;(this as any).terminate()\n }\n}\n\nexport const getWsProvider = getInternalWsProvider(WS as any)\n"],"names":["getSyncProvider","args","WebSocket"],"mappings":"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"}
@@ -1,49 +1,126 @@
1
1
  import { getSyncProvider } from '@polkadot-api/json-rpc-provider-proxy';
2
2
 
3
- const getInternalWsProvider = (WebsocketClass) => (uri, protocols) => getSyncProvider(async () => {
4
- const socket = new WebsocketClass(uri, protocols);
5
- await new Promise((resolve, reject) => {
6
- const onOpen = () => {
7
- resolve();
8
- socket.removeEventListener("error", onError);
9
- };
10
- socket.addEventListener("open", onOpen, { once: true });
11
- const onError = (e) => {
12
- console.error(
13
- `Unable to connect to ${uri}${protocols ? ", protocols: " + protocols : ""}`
3
+ const timeoutError = {
4
+ type: 2 /* ERROR */,
5
+ event: { type: "timeout" }
6
+ };
7
+ const noop = () => {
8
+ };
9
+ const getInternalWsProvider = (WebsocketClass) => {
10
+ return (...args) => {
11
+ let endpoints = [];
12
+ let onStatusChanged = noop;
13
+ if (typeof args[1] === "function") onStatusChanged = args[1];
14
+ if (Array.isArray(args[0]))
15
+ endpoints = args[0].map(
16
+ (x) => typeof x === "string" ? [x] : [x.uri, x.protocol]
14
17
  );
15
- reject(e);
16
- socket.removeEventListener("open", onOpen);
17
- };
18
- socket.addEventListener("error", onError, { once: true });
19
- });
20
- return (onMessage, onHalt) => {
21
- const _onMessage = (e) => {
22
- if (typeof e.data === "string") onMessage(e.data);
23
- };
24
- const innerHalt = (reason) => (e) => {
25
- console.warn(`WS halt (${reason})`);
26
- console.log(e);
27
- onHalt();
28
- };
29
- const onError = innerHalt("err");
30
- const onClose = innerHalt("close");
31
- socket.addEventListener("message", _onMessage);
32
- socket.addEventListener("error", onError);
33
- socket.addEventListener("close", onClose);
34
- return {
35
- send: (msg) => {
36
- socket.send(msg);
37
- },
38
- disconnect: () => {
39
- socket.removeEventListener("message", _onMessage);
40
- socket.removeEventListener("error", onError);
41
- socket.removeEventListener("close", onClose);
42
- socket.close();
43
- }
18
+ else {
19
+ endpoints = [[args[0]]];
20
+ if (args[1] && args[1] !== onStatusChanged)
21
+ endpoints[0][1] = args[1];
22
+ if (args[2]) onStatusChanged = args[2];
23
+ }
24
+ let idx = 0;
25
+ let status;
26
+ let switchTo = null;
27
+ let disconnect = noop;
28
+ const result = getSyncProvider(async () => {
29
+ const [uri, protocols] = switchTo || endpoints[idx++ % endpoints.length];
30
+ switchTo = null;
31
+ const socket = new WebsocketClass(uri, protocols);
32
+ onStatusChanged(
33
+ status = {
34
+ type: 0 /* CONNECTING */,
35
+ uri,
36
+ protocols
37
+ }
38
+ );
39
+ await new Promise((resolve, reject) => {
40
+ const onOpen = () => {
41
+ cleanup();
42
+ resolve();
43
+ };
44
+ const onError = (e) => {
45
+ cleanup();
46
+ console.error(
47
+ `Unable to connect to ${uri}${protocols ? ", protocols: " + protocols : ""}`
48
+ );
49
+ onStatusChanged(
50
+ status = {
51
+ type: e ? 2 /* ERROR */ : 3 /* CLOSE */,
52
+ event: e
53
+ }
54
+ );
55
+ setTimeout(reject, e ? 300 : 0, e);
56
+ };
57
+ const timeoutToken = setTimeout(() => {
58
+ cleanup();
59
+ onStatusChanged(status = timeoutError);
60
+ reject(timeoutError.event);
61
+ }, 3500);
62
+ const cleanup = () => {
63
+ clearTimeout(timeoutToken);
64
+ socket.removeEventListener("error", onError);
65
+ socket.removeEventListener("open", onOpen);
66
+ };
67
+ socket.addEventListener("open", onOpen);
68
+ socket.addEventListener("error", onError);
69
+ disconnect = () => {
70
+ onError(null);
71
+ };
72
+ });
73
+ onStatusChanged(
74
+ status = {
75
+ type: 1 /* CONNECTED */,
76
+ uri,
77
+ protocols
78
+ }
79
+ );
80
+ return (onMessage, onHalt) => {
81
+ const _onMessage = (e) => {
82
+ if (typeof e.data === "string") onMessage(e.data);
83
+ };
84
+ const innerHalt = (reason) => (e) => {
85
+ console.warn(`WS halt (${reason})`);
86
+ onStatusChanged(
87
+ status = {
88
+ type: reason,
89
+ event: e
90
+ }
91
+ );
92
+ onHalt();
93
+ };
94
+ const onError = innerHalt(2 /* ERROR */);
95
+ const onClose = innerHalt(3 /* CLOSE */);
96
+ socket.addEventListener("message", _onMessage);
97
+ socket.addEventListener("error", onError);
98
+ socket.addEventListener("close", onClose);
99
+ disconnect = (withHalt) => {
100
+ disconnect = noop;
101
+ socket.removeEventListener("message", _onMessage);
102
+ socket.removeEventListener("error", onError);
103
+ socket.removeEventListener("close", onClose);
104
+ socket.close();
105
+ if (withHalt) onClose({});
106
+ };
107
+ return {
108
+ send: (msg) => {
109
+ socket.send(msg);
110
+ },
111
+ disconnect
112
+ };
113
+ };
114
+ });
115
+ result.getStatus = () => status;
116
+ result.switch = (...args2) => {
117
+ if (status.type === 3 /* CLOSE */) return;
118
+ if (args2.length) switchTo = args2;
119
+ if (status.type !== 2 /* ERROR */) disconnect(true);
44
120
  };
121
+ return result;
45
122
  };
46
- });
123
+ };
47
124
 
48
125
  export { getInternalWsProvider };
49
126
  //# sourceMappingURL=ws-provider.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"ws-provider.mjs","sources":["../../../src/ws-provider.ts"],"sourcesContent":["import type { JsonRpcProvider } from \"@polkadot-api/json-rpc-provider\"\nimport { getSyncProvider } from \"@polkadot-api/json-rpc-provider-proxy\"\n\nexport const getInternalWsProvider =\n (WebsocketClass: typeof WebSocket) =>\n (uri: string, protocols?: string | string[]): JsonRpcProvider =>\n getSyncProvider(async () => {\n const socket = new WebsocketClass(uri, protocols)\n\n await new Promise<void>((resolve, reject) => {\n const onOpen = () => {\n resolve()\n socket.removeEventListener(\"error\", onError)\n }\n socket.addEventListener(\"open\", onOpen, { once: true })\n\n const onError = (e: Event) => {\n console.error(\n `Unable to connect to ${uri}${\n protocols ? \", protocols: \" + protocols : \"\"\n }`,\n )\n reject(e)\n socket.removeEventListener(\"open\", onOpen)\n }\n socket.addEventListener(\"error\", onError, { once: true })\n })\n\n return (onMessage, onHalt) => {\n const _onMessage = (e: MessageEvent) => {\n if (typeof e.data === \"string\") onMessage(e.data)\n }\n const innerHalt = (reason: string) => (e: any) => {\n console.warn(`WS halt (${reason})`)\n console.log(e)\n onHalt()\n }\n const onError = innerHalt(\"err\")\n const onClose = innerHalt(\"close\")\n\n socket.addEventListener(\"message\", _onMessage)\n socket.addEventListener(\"error\", onError)\n socket.addEventListener(\"close\", onClose)\n\n return {\n send: (msg) => {\n socket.send(msg)\n },\n disconnect: () => {\n socket.removeEventListener(\"message\", _onMessage)\n socket.removeEventListener(\"error\", onError)\n socket.removeEventListener(\"close\", onClose)\n socket.close()\n },\n }\n }\n })\n"],"names":[],"mappings":";;AAGO,MAAM,wBACX,CAAC,cAAA,KACD,CAAC,GAAa,EAAA,SAAA,KACZ,gBAAgB,YAAY;AAC1B,EAAA,MAAM,MAAS,GAAA,IAAI,cAAe,CAAA,GAAA,EAAK,SAAS,CAAA,CAAA;AAEhD,EAAA,MAAM,IAAI,OAAA,CAAc,CAAC,OAAA,EAAS,MAAW,KAAA;AAC3C,IAAA,MAAM,SAAS,MAAM;AACnB,MAAQ,OAAA,EAAA,CAAA;AACR,MAAO,MAAA,CAAA,mBAAA,CAAoB,SAAS,OAAO,CAAA,CAAA;AAAA,KAC7C,CAAA;AACA,IAAA,MAAA,CAAO,iBAAiB,MAAQ,EAAA,MAAA,EAAQ,EAAE,IAAA,EAAM,MAAM,CAAA,CAAA;AAEtD,IAAM,MAAA,OAAA,GAAU,CAAC,CAAa,KAAA;AAC5B,MAAQ,OAAA,CAAA,KAAA;AAAA,QACN,wBAAwB,GAAG,CAAA,EACzB,SAAY,GAAA,eAAA,GAAkB,YAAY,EAC5C,CAAA,CAAA;AAAA,OACF,CAAA;AACA,MAAA,MAAA,CAAO,CAAC,CAAA,CAAA;AACR,MAAO,MAAA,CAAA,mBAAA,CAAoB,QAAQ,MAAM,CAAA,CAAA;AAAA,KAC3C,CAAA;AACA,IAAA,MAAA,CAAO,iBAAiB,OAAS,EAAA,OAAA,EAAS,EAAE,IAAA,EAAM,MAAM,CAAA,CAAA;AAAA,GACzD,CAAA,CAAA;AAED,EAAO,OAAA,CAAC,WAAW,MAAW,KAAA;AAC5B,IAAM,MAAA,UAAA,GAAa,CAAC,CAAoB,KAAA;AACtC,MAAA,IAAI,OAAO,CAAE,CAAA,IAAA,KAAS,QAAU,EAAA,SAAA,CAAU,EAAE,IAAI,CAAA,CAAA;AAAA,KAClD,CAAA;AACA,IAAA,MAAM,SAAY,GAAA,CAAC,MAAmB,KAAA,CAAC,CAAW,KAAA;AAChD,MAAQ,OAAA,CAAA,IAAA,CAAK,CAAY,SAAA,EAAA,MAAM,CAAG,CAAA,CAAA,CAAA,CAAA;AAClC,MAAA,OAAA,CAAQ,IAAI,CAAC,CAAA,CAAA;AACb,MAAO,MAAA,EAAA,CAAA;AAAA,KACT,CAAA;AACA,IAAM,MAAA,OAAA,GAAU,UAAU,KAAK,CAAA,CAAA;AAC/B,IAAM,MAAA,OAAA,GAAU,UAAU,OAAO,CAAA,CAAA;AAEjC,IAAO,MAAA,CAAA,gBAAA,CAAiB,WAAW,UAAU,CAAA,CAAA;AAC7C,IAAO,MAAA,CAAA,gBAAA,CAAiB,SAAS,OAAO,CAAA,CAAA;AACxC,IAAO,MAAA,CAAA,gBAAA,CAAiB,SAAS,OAAO,CAAA,CAAA;AAExC,IAAO,OAAA;AAAA,MACL,IAAA,EAAM,CAAC,GAAQ,KAAA;AACb,QAAA,MAAA,CAAO,KAAK,GAAG,CAAA,CAAA;AAAA,OACjB;AAAA,MACA,YAAY,MAAM;AAChB,QAAO,MAAA,CAAA,mBAAA,CAAoB,WAAW,UAAU,CAAA,CAAA;AAChD,QAAO,MAAA,CAAA,mBAAA,CAAoB,SAAS,OAAO,CAAA,CAAA;AAC3C,QAAO,MAAA,CAAA,mBAAA,CAAoB,SAAS,OAAO,CAAA,CAAA;AAC3C,QAAA,MAAA,CAAO,KAAM,EAAA,CAAA;AAAA,OACf;AAAA,KACF,CAAA;AAAA,GACF,CAAA;AACF,CAAC;;;;"}
1
+ {"version":3,"file":"ws-provider.mjs","sources":["../../../src/ws-provider.ts"],"sourcesContent":["import type { JsonRpcProvider } from \"@polkadot-api/json-rpc-provider\"\nimport { getSyncProvider } from \"@polkadot-api/json-rpc-provider-proxy\"\n\nexport enum WsEvent {\n CONNECTING,\n CONNECTED,\n ERROR,\n CLOSE,\n}\nexport type WsConnecting = {\n type: WsEvent.CONNECTING\n uri: string\n protocols?: string | string[]\n}\nexport type WsConnected = {\n type: WsEvent.CONNECTED\n uri: string\n protocols?: string | 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, protocol?: string[]) => void\n getStatus: () => StatusChange\n}\n\nexport interface GetWsProviderInput {\n (\n uri: string,\n protocols?: string | string[],\n onStatusChanged?: (status: StatusChange) => void,\n ): WsJsonRpcProvider\n (\n uri: string,\n onStatusChanged?: (status: StatusChange) => void,\n ): WsJsonRpcProvider\n (\n endpoints: Array<string | { uri: string; protocol: string[] }>,\n onStatusChanged?: (status: StatusChange) => void,\n ): WsJsonRpcProvider\n}\n\nconst timeoutError: StatusChange = {\n type: WsEvent.ERROR,\n event: { type: \"timeout\" },\n}\n\nconst noop = () => {}\nexport const getInternalWsProvider = (\n WebsocketClass: typeof WebSocket,\n): GetWsProviderInput => {\n return (...args): WsJsonRpcProvider => {\n let endpoints: Array<[string, string | string[]] | [string]> = []\n let onStatusChanged: (status: StatusChange) => void = noop\n\n if (typeof args[1] === \"function\") onStatusChanged = args[1]\n if (Array.isArray(args[0]))\n endpoints = args[0].map((x) =>\n typeof x === \"string\" ? [x] : [x.uri, x.protocol],\n )\n else {\n endpoints = [[args[0]]]\n if (args[1] && args[1] !== onStatusChanged)\n endpoints[0][1] = args[1] as any\n if (args[2]) onStatusChanged = args[2] as any\n }\n let idx = 0\n let status: StatusChange\n let switchTo: [string] | [string, string | string[]] | null = null\n let disconnect: (withHalt?: boolean) => void = noop\n\n const result = getSyncProvider(async () => {\n const [uri, protocols] = switchTo || endpoints[idx++ % endpoints.length]\n switchTo = null\n const socket = new WebsocketClass(uri, protocols)\n onStatusChanged(\n (status = {\n type: WsEvent.CONNECTING,\n uri,\n protocols,\n }),\n )\n\n await new Promise<void>((resolve, reject) => {\n const onOpen = () => {\n cleanup()\n resolve()\n }\n\n const onError = (e: Event | null) => {\n cleanup()\n console.error(\n `Unable to connect to ${uri}${\n protocols ? \", protocols: \" + protocols : \"\"\n }`,\n )\n onStatusChanged(\n (status = {\n type: e ? WsEvent.ERROR : WsEvent.CLOSE,\n event: e,\n }),\n )\n setTimeout(reject, e ? 300 : 0, e)\n }\n\n const timeoutToken = setTimeout(() => {\n cleanup()\n onStatusChanged((status = timeoutError))\n reject(timeoutError.event)\n }, 3_500)\n const cleanup = () => {\n clearTimeout(timeoutToken)\n socket.removeEventListener(\"error\", onError)\n socket.removeEventListener(\"open\", onOpen)\n }\n socket.addEventListener(\"open\", onOpen)\n socket.addEventListener(\"error\", onError)\n disconnect = () => {\n onError(null)\n }\n })\n\n onStatusChanged(\n (status = {\n type: WsEvent.CONNECTED,\n uri,\n protocols,\n }),\n )\n\n return (onMessage, onHalt) => {\n const _onMessage = (e: MessageEvent) => {\n if (typeof e.data === \"string\") onMessage(e.data)\n }\n const innerHalt =\n (reason: WsEvent.CLOSE | WsEvent.ERROR) => (e: any) => {\n console.warn(`WS halt (${reason})`)\n onStatusChanged(\n (status = {\n type: reason,\n event: e,\n }),\n )\n onHalt()\n }\n const onError = innerHalt(WsEvent.ERROR)\n const onClose = innerHalt(WsEvent.CLOSE)\n\n socket.addEventListener(\"message\", _onMessage)\n socket.addEventListener(\"error\", onError)\n socket.addEventListener(\"close\", onClose)\n disconnect = (withHalt) => {\n disconnect = noop\n socket.removeEventListener(\"message\", _onMessage)\n socket.removeEventListener(\"error\", onError)\n socket.removeEventListener(\"close\", onClose)\n socket.close()\n if (withHalt) onClose({})\n }\n\n return {\n send: (msg) => {\n socket.send(msg)\n },\n disconnect,\n }\n }\n }) as WsJsonRpcProvider\n\n result.getStatus = () => status\n result.switch = (...args) => {\n if (status.type === WsEvent.CLOSE) return\n if (args.length) switchTo = args as any\n if (status.type !== WsEvent.ERROR) disconnect(true)\n }\n return result\n }\n}\n"],"names":["args"],"mappings":"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"}
package/dist/web/web.d.ts CHANGED
@@ -1,6 +1,44 @@
1
- import * as _polkadot_api_json_rpc_provider from '@polkadot-api/json-rpc-provider';
1
+ import { JsonRpcProvider } from '@polkadot-api/json-rpc-provider';
2
2
  export { JsonRpcProvider } from '@polkadot-api/json-rpc-provider';
3
3
 
4
- declare const getWsProvider: (uri: string, protocols?: string | string[]) => _polkadot_api_json_rpc_provider.JsonRpcProvider;
4
+ declare enum WsEvent {
5
+ CONNECTING = 0,
6
+ CONNECTED = 1,
7
+ ERROR = 2,
8
+ CLOSE = 3
9
+ }
10
+ type WsConnecting = {
11
+ type: WsEvent.CONNECTING;
12
+ uri: string;
13
+ protocols?: string | string[];
14
+ };
15
+ type WsConnected = {
16
+ type: WsEvent.CONNECTED;
17
+ uri: string;
18
+ protocols?: string | 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, protocol?: string[]) => void;
31
+ getStatus: () => StatusChange;
32
+ };
33
+ interface GetWsProviderInput {
34
+ (uri: string, protocols?: string | string[], onStatusChanged?: (status: StatusChange) => void): WsJsonRpcProvider;
35
+ (uri: string, onStatusChanged?: (status: StatusChange) => void): WsJsonRpcProvider;
36
+ (endpoints: Array<string | {
37
+ uri: string;
38
+ protocol: string[];
39
+ }>, onStatusChanged?: (status: StatusChange) => void): WsJsonRpcProvider;
40
+ }
41
+
42
+ declare const getWsProvider: GetWsProviderInput;
5
43
 
6
44
  export { getWsProvider };
package/dist/web/web.js CHANGED
@@ -2,50 +2,127 @@
2
2
 
3
3
  var jsonRpcProviderProxy = require('@polkadot-api/json-rpc-provider-proxy');
4
4
 
5
- const getInternalWsProvider = (WebsocketClass) => (uri, protocols) => jsonRpcProviderProxy.getSyncProvider(async () => {
6
- const socket = new WebsocketClass(uri, protocols);
7
- await new Promise((resolve, reject) => {
8
- const onOpen = () => {
9
- resolve();
10
- socket.removeEventListener("error", onError);
11
- };
12
- socket.addEventListener("open", onOpen, { once: true });
13
- const onError = (e) => {
14
- console.error(
15
- `Unable to connect to ${uri}${protocols ? ", protocols: " + protocols : ""}`
5
+ const timeoutError = {
6
+ type: 2 /* ERROR */,
7
+ event: { type: "timeout" }
8
+ };
9
+ const noop = () => {
10
+ };
11
+ const getInternalWsProvider = (WebsocketClass) => {
12
+ return (...args) => {
13
+ let endpoints = [];
14
+ let onStatusChanged = noop;
15
+ if (typeof args[1] === "function") onStatusChanged = args[1];
16
+ if (Array.isArray(args[0]))
17
+ endpoints = args[0].map(
18
+ (x) => typeof x === "string" ? [x] : [x.uri, x.protocol]
16
19
  );
17
- reject(e);
18
- socket.removeEventListener("open", onOpen);
19
- };
20
- socket.addEventListener("error", onError, { once: true });
21
- });
22
- return (onMessage, onHalt) => {
23
- const _onMessage = (e) => {
24
- if (typeof e.data === "string") onMessage(e.data);
25
- };
26
- const innerHalt = (reason) => (e) => {
27
- console.warn(`WS halt (${reason})`);
28
- console.log(e);
29
- onHalt();
30
- };
31
- const onError = innerHalt("err");
32
- const onClose = innerHalt("close");
33
- socket.addEventListener("message", _onMessage);
34
- socket.addEventListener("error", onError);
35
- socket.addEventListener("close", onClose);
36
- return {
37
- send: (msg) => {
38
- socket.send(msg);
39
- },
40
- disconnect: () => {
41
- socket.removeEventListener("message", _onMessage);
42
- socket.removeEventListener("error", onError);
43
- socket.removeEventListener("close", onClose);
44
- socket.close();
45
- }
20
+ else {
21
+ endpoints = [[args[0]]];
22
+ if (args[1] && args[1] !== onStatusChanged)
23
+ endpoints[0][1] = args[1];
24
+ if (args[2]) onStatusChanged = args[2];
25
+ }
26
+ let idx = 0;
27
+ let status;
28
+ let switchTo = null;
29
+ let disconnect = noop;
30
+ const result = jsonRpcProviderProxy.getSyncProvider(async () => {
31
+ const [uri, protocols] = switchTo || endpoints[idx++ % endpoints.length];
32
+ switchTo = null;
33
+ const socket = new WebsocketClass(uri, protocols);
34
+ onStatusChanged(
35
+ status = {
36
+ type: 0 /* CONNECTING */,
37
+ uri,
38
+ protocols
39
+ }
40
+ );
41
+ await new Promise((resolve, reject) => {
42
+ const onOpen = () => {
43
+ cleanup();
44
+ resolve();
45
+ };
46
+ const onError = (e) => {
47
+ cleanup();
48
+ console.error(
49
+ `Unable to connect to ${uri}${protocols ? ", protocols: " + protocols : ""}`
50
+ );
51
+ onStatusChanged(
52
+ status = {
53
+ type: e ? 2 /* ERROR */ : 3 /* CLOSE */,
54
+ event: e
55
+ }
56
+ );
57
+ setTimeout(reject, e ? 300 : 0, e);
58
+ };
59
+ const timeoutToken = setTimeout(() => {
60
+ cleanup();
61
+ onStatusChanged(status = timeoutError);
62
+ reject(timeoutError.event);
63
+ }, 3500);
64
+ const cleanup = () => {
65
+ clearTimeout(timeoutToken);
66
+ socket.removeEventListener("error", onError);
67
+ socket.removeEventListener("open", onOpen);
68
+ };
69
+ socket.addEventListener("open", onOpen);
70
+ socket.addEventListener("error", onError);
71
+ disconnect = () => {
72
+ onError(null);
73
+ };
74
+ });
75
+ onStatusChanged(
76
+ status = {
77
+ type: 1 /* CONNECTED */,
78
+ uri,
79
+ protocols
80
+ }
81
+ );
82
+ return (onMessage, onHalt) => {
83
+ const _onMessage = (e) => {
84
+ if (typeof e.data === "string") onMessage(e.data);
85
+ };
86
+ const innerHalt = (reason) => (e) => {
87
+ console.warn(`WS halt (${reason})`);
88
+ onStatusChanged(
89
+ status = {
90
+ type: reason,
91
+ event: e
92
+ }
93
+ );
94
+ onHalt();
95
+ };
96
+ const onError = innerHalt(2 /* ERROR */);
97
+ const onClose = innerHalt(3 /* CLOSE */);
98
+ socket.addEventListener("message", _onMessage);
99
+ socket.addEventListener("error", onError);
100
+ socket.addEventListener("close", onClose);
101
+ disconnect = (withHalt) => {
102
+ disconnect = noop;
103
+ socket.removeEventListener("message", _onMessage);
104
+ socket.removeEventListener("error", onError);
105
+ socket.removeEventListener("close", onClose);
106
+ socket.close();
107
+ if (withHalt) onClose({});
108
+ };
109
+ return {
110
+ send: (msg) => {
111
+ socket.send(msg);
112
+ },
113
+ disconnect
114
+ };
115
+ };
116
+ });
117
+ result.getStatus = () => status;
118
+ result.switch = (...args2) => {
119
+ if (status.type === 3 /* CLOSE */) return;
120
+ if (args2.length) switchTo = args2;
121
+ if (status.type !== 2 /* ERROR */) disconnect(true);
46
122
  };
123
+ return result;
47
124
  };
48
- });
125
+ };
49
126
 
50
127
  const getWsProvider = getInternalWsProvider(WebSocket);
51
128
 
@@ -1 +1 @@
1
- {"version":3,"file":"web.js","sources":["../../src/ws-provider.ts","../../src/web.ts"],"sourcesContent":["import type { JsonRpcProvider } from \"@polkadot-api/json-rpc-provider\"\nimport { getSyncProvider } from \"@polkadot-api/json-rpc-provider-proxy\"\n\nexport const getInternalWsProvider =\n (WebsocketClass: typeof WebSocket) =>\n (uri: string, protocols?: string | string[]): JsonRpcProvider =>\n getSyncProvider(async () => {\n const socket = new WebsocketClass(uri, protocols)\n\n await new Promise<void>((resolve, reject) => {\n const onOpen = () => {\n resolve()\n socket.removeEventListener(\"error\", onError)\n }\n socket.addEventListener(\"open\", onOpen, { once: true })\n\n const onError = (e: Event) => {\n console.error(\n `Unable to connect to ${uri}${\n protocols ? \", protocols: \" + protocols : \"\"\n }`,\n )\n reject(e)\n socket.removeEventListener(\"open\", onOpen)\n }\n socket.addEventListener(\"error\", onError, { once: true })\n })\n\n return (onMessage, onHalt) => {\n const _onMessage = (e: MessageEvent) => {\n if (typeof e.data === \"string\") onMessage(e.data)\n }\n const innerHalt = (reason: string) => (e: any) => {\n console.warn(`WS halt (${reason})`)\n console.log(e)\n onHalt()\n }\n const onError = innerHalt(\"err\")\n const onClose = innerHalt(\"close\")\n\n socket.addEventListener(\"message\", _onMessage)\n socket.addEventListener(\"error\", onError)\n socket.addEventListener(\"close\", onClose)\n\n return {\n send: (msg) => {\n socket.send(msg)\n },\n disconnect: () => {\n socket.removeEventListener(\"message\", _onMessage)\n socket.removeEventListener(\"error\", onError)\n socket.removeEventListener(\"close\", onClose)\n socket.close()\n },\n }\n }\n })\n","import { getInternalWsProvider } from \"./ws-provider\"\n\nexport type { JsonRpcProvider } from \"@polkadot-api/json-rpc-provider\"\nexport const getWsProvider = getInternalWsProvider(WebSocket)\n"],"names":["getSyncProvider"],"mappings":";;;;AAGO,MAAM,wBACX,CAAC,cAAA,KACD,CAAC,GAAa,EAAA,SAAA,KACZA,qCAAgB,YAAY;AAC1B,EAAA,MAAM,MAAS,GAAA,IAAI,cAAe,CAAA,GAAA,EAAK,SAAS,CAAA,CAAA;AAEhD,EAAA,MAAM,IAAI,OAAA,CAAc,CAAC,OAAA,EAAS,MAAW,KAAA;AAC3C,IAAA,MAAM,SAAS,MAAM;AACnB,MAAQ,OAAA,EAAA,CAAA;AACR,MAAO,MAAA,CAAA,mBAAA,CAAoB,SAAS,OAAO,CAAA,CAAA;AAAA,KAC7C,CAAA;AACA,IAAA,MAAA,CAAO,iBAAiB,MAAQ,EAAA,MAAA,EAAQ,EAAE,IAAA,EAAM,MAAM,CAAA,CAAA;AAEtD,IAAM,MAAA,OAAA,GAAU,CAAC,CAAa,KAAA;AAC5B,MAAQ,OAAA,CAAA,KAAA;AAAA,QACN,wBAAwB,GAAG,CAAA,EACzB,SAAY,GAAA,eAAA,GAAkB,YAAY,EAC5C,CAAA,CAAA;AAAA,OACF,CAAA;AACA,MAAA,MAAA,CAAO,CAAC,CAAA,CAAA;AACR,MAAO,MAAA,CAAA,mBAAA,CAAoB,QAAQ,MAAM,CAAA,CAAA;AAAA,KAC3C,CAAA;AACA,IAAA,MAAA,CAAO,iBAAiB,OAAS,EAAA,OAAA,EAAS,EAAE,IAAA,EAAM,MAAM,CAAA,CAAA;AAAA,GACzD,CAAA,CAAA;AAED,EAAO,OAAA,CAAC,WAAW,MAAW,KAAA;AAC5B,IAAM,MAAA,UAAA,GAAa,CAAC,CAAoB,KAAA;AACtC,MAAA,IAAI,OAAO,CAAE,CAAA,IAAA,KAAS,QAAU,EAAA,SAAA,CAAU,EAAE,IAAI,CAAA,CAAA;AAAA,KAClD,CAAA;AACA,IAAA,MAAM,SAAY,GAAA,CAAC,MAAmB,KAAA,CAAC,CAAW,KAAA;AAChD,MAAQ,OAAA,CAAA,IAAA,CAAK,CAAY,SAAA,EAAA,MAAM,CAAG,CAAA,CAAA,CAAA,CAAA;AAClC,MAAA,OAAA,CAAQ,IAAI,CAAC,CAAA,CAAA;AACb,MAAO,MAAA,EAAA,CAAA;AAAA,KACT,CAAA;AACA,IAAM,MAAA,OAAA,GAAU,UAAU,KAAK,CAAA,CAAA;AAC/B,IAAM,MAAA,OAAA,GAAU,UAAU,OAAO,CAAA,CAAA;AAEjC,IAAO,MAAA,CAAA,gBAAA,CAAiB,WAAW,UAAU,CAAA,CAAA;AAC7C,IAAO,MAAA,CAAA,gBAAA,CAAiB,SAAS,OAAO,CAAA,CAAA;AACxC,IAAO,MAAA,CAAA,gBAAA,CAAiB,SAAS,OAAO,CAAA,CAAA;AAExC,IAAO,OAAA;AAAA,MACL,IAAA,EAAM,CAAC,GAAQ,KAAA;AACb,QAAA,MAAA,CAAO,KAAK,GAAG,CAAA,CAAA;AAAA,OACjB;AAAA,MACA,YAAY,MAAM;AAChB,QAAO,MAAA,CAAA,mBAAA,CAAoB,WAAW,UAAU,CAAA,CAAA;AAChD,QAAO,MAAA,CAAA,mBAAA,CAAoB,SAAS,OAAO,CAAA,CAAA;AAC3C,QAAO,MAAA,CAAA,mBAAA,CAAoB,SAAS,OAAO,CAAA,CAAA;AAC3C,QAAA,MAAA,CAAO,KAAM,EAAA,CAAA;AAAA,OACf;AAAA,KACF,CAAA;AAAA,GACF,CAAA;AACF,CAAC,CAAA;;ACrDQ,MAAA,aAAA,GAAgB,sBAAsB,SAAS;;;;"}
1
+ {"version":3,"file":"web.js","sources":["../../src/ws-provider.ts","../../src/web.ts"],"sourcesContent":["import type { JsonRpcProvider } from \"@polkadot-api/json-rpc-provider\"\nimport { getSyncProvider } from \"@polkadot-api/json-rpc-provider-proxy\"\n\nexport enum WsEvent {\n CONNECTING,\n CONNECTED,\n ERROR,\n CLOSE,\n}\nexport type WsConnecting = {\n type: WsEvent.CONNECTING\n uri: string\n protocols?: string | string[]\n}\nexport type WsConnected = {\n type: WsEvent.CONNECTED\n uri: string\n protocols?: string | 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, protocol?: string[]) => void\n getStatus: () => StatusChange\n}\n\nexport interface GetWsProviderInput {\n (\n uri: string,\n protocols?: string | string[],\n onStatusChanged?: (status: StatusChange) => void,\n ): WsJsonRpcProvider\n (\n uri: string,\n onStatusChanged?: (status: StatusChange) => void,\n ): WsJsonRpcProvider\n (\n endpoints: Array<string | { uri: string; protocol: string[] }>,\n onStatusChanged?: (status: StatusChange) => void,\n ): WsJsonRpcProvider\n}\n\nconst timeoutError: StatusChange = {\n type: WsEvent.ERROR,\n event: { type: \"timeout\" },\n}\n\nconst noop = () => {}\nexport const getInternalWsProvider = (\n WebsocketClass: typeof WebSocket,\n): GetWsProviderInput => {\n return (...args): WsJsonRpcProvider => {\n let endpoints: Array<[string, string | string[]] | [string]> = []\n let onStatusChanged: (status: StatusChange) => void = noop\n\n if (typeof args[1] === \"function\") onStatusChanged = args[1]\n if (Array.isArray(args[0]))\n endpoints = args[0].map((x) =>\n typeof x === \"string\" ? [x] : [x.uri, x.protocol],\n )\n else {\n endpoints = [[args[0]]]\n if (args[1] && args[1] !== onStatusChanged)\n endpoints[0][1] = args[1] as any\n if (args[2]) onStatusChanged = args[2] as any\n }\n let idx = 0\n let status: StatusChange\n let switchTo: [string] | [string, string | string[]] | null = null\n let disconnect: (withHalt?: boolean) => void = noop\n\n const result = getSyncProvider(async () => {\n const [uri, protocols] = switchTo || endpoints[idx++ % endpoints.length]\n switchTo = null\n const socket = new WebsocketClass(uri, protocols)\n onStatusChanged(\n (status = {\n type: WsEvent.CONNECTING,\n uri,\n protocols,\n }),\n )\n\n await new Promise<void>((resolve, reject) => {\n const onOpen = () => {\n cleanup()\n resolve()\n }\n\n const onError = (e: Event | null) => {\n cleanup()\n console.error(\n `Unable to connect to ${uri}${\n protocols ? \", protocols: \" + protocols : \"\"\n }`,\n )\n onStatusChanged(\n (status = {\n type: e ? WsEvent.ERROR : WsEvent.CLOSE,\n event: e,\n }),\n )\n setTimeout(reject, e ? 300 : 0, e)\n }\n\n const timeoutToken = setTimeout(() => {\n cleanup()\n onStatusChanged((status = timeoutError))\n reject(timeoutError.event)\n }, 3_500)\n const cleanup = () => {\n clearTimeout(timeoutToken)\n socket.removeEventListener(\"error\", onError)\n socket.removeEventListener(\"open\", onOpen)\n }\n socket.addEventListener(\"open\", onOpen)\n socket.addEventListener(\"error\", onError)\n disconnect = () => {\n onError(null)\n }\n })\n\n onStatusChanged(\n (status = {\n type: WsEvent.CONNECTED,\n uri,\n protocols,\n }),\n )\n\n return (onMessage, onHalt) => {\n const _onMessage = (e: MessageEvent) => {\n if (typeof e.data === \"string\") onMessage(e.data)\n }\n const innerHalt =\n (reason: WsEvent.CLOSE | WsEvent.ERROR) => (e: any) => {\n console.warn(`WS halt (${reason})`)\n onStatusChanged(\n (status = {\n type: reason,\n event: e,\n }),\n )\n onHalt()\n }\n const onError = innerHalt(WsEvent.ERROR)\n const onClose = innerHalt(WsEvent.CLOSE)\n\n socket.addEventListener(\"message\", _onMessage)\n socket.addEventListener(\"error\", onError)\n socket.addEventListener(\"close\", onClose)\n disconnect = (withHalt) => {\n disconnect = noop\n socket.removeEventListener(\"message\", _onMessage)\n socket.removeEventListener(\"error\", onError)\n socket.removeEventListener(\"close\", onClose)\n socket.close()\n if (withHalt) onClose({})\n }\n\n return {\n send: (msg) => {\n socket.send(msg)\n },\n disconnect,\n }\n }\n }) as WsJsonRpcProvider\n\n result.getStatus = () => status\n result.switch = (...args) => {\n if (status.type === WsEvent.CLOSE) return\n if (args.length) switchTo = args as any\n if (status.type !== WsEvent.ERROR) disconnect(true)\n }\n return result\n }\n}\n","import { getInternalWsProvider } from \"./ws-provider\"\n\nexport type { JsonRpcProvider } from \"@polkadot-api/json-rpc-provider\"\nexport const getWsProvider = getInternalWsProvider(WebSocket)\n"],"names":["getSyncProvider","args"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@polkadot-api/ws-provider",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "author": "Josep M Sobrepere (https://github.com/josepot)",
5
5
  "repository": {
6
6
  "type": "git",
@@ -33,7 +33,7 @@
33
33
  "dependencies": {
34
34
  "ws": "^8.18.0",
35
35
  "@polkadot-api/json-rpc-provider": "0.0.3",
36
- "@polkadot-api/json-rpc-provider-proxy": "0.2.1"
36
+ "@polkadot-api/json-rpc-provider-proxy": "0.2.2"
37
37
  },
38
38
  "scripts": {
39
39
  "build-core": "tsc --noEmit && rollup -c",