@polkadot-api/json-rpc-provider-proxy 0.2.3 → 0.2.5

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.
@@ -0,0 +1,5 @@
1
+ let count = 0;
2
+ const getOpaqueToken = () => `proxyOpaque${count++}`;
3
+
4
+ export { getOpaqueToken };
5
+ //# sourceMappingURL=get-opaque-token.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-opaque-token.mjs","sources":["../../src/get-opaque-token.ts"],"sourcesContent":["let count = 0\nexport const getOpaqueToken = (): string => `proxyOpaque${count++}`\n"],"names":[],"mappings":"AAAA,IAAI,KAAA,GAAQ,CAAA;AACL,MAAM,cAAA,GAAiB,MAAc,CAAA,WAAA,EAAc,KAAA,EAAO,CAAA;;;;"}
@@ -1,40 +1,106 @@
1
1
  import { jsonRpcMsg } from './json-rpc-message.mjs';
2
+ import { getOpaqueToken } from './get-opaque-token.mjs';
2
3
 
3
- const unfollowMethods = new Set(
4
- ["v1", "unstable"].map((x) => `chainHead_${x}_unfollow`)
5
- );
4
+ const getInternalId = () => `___proxyInternalId__${getOpaqueToken()}`;
6
5
  const getProxy = (toConsumer) => {
7
6
  let state = {
8
7
  type: 1 /* Connecting */,
8
+ activeBroadcasts: /* @__PURE__ */ new Map(),
9
9
  pending: []
10
10
  };
11
11
  const onMsgFromProvider = (msg) => {
12
+ let isActive = true;
12
13
  if (state.type === 0 /* Connected */) {
13
14
  const parsed = JSON.parse(msg);
14
15
  if ("id" in parsed) {
15
- if (state.onGoingRequests.get(parsed.id)?.type === 0 /* ChainHeadFollow */)
16
+ const { id } = parsed;
17
+ if (state.pendingBroadcasts.has(id)) {
18
+ const synToken = state.pendingBroadcasts.get(id);
19
+ const upToken = parsed.result;
20
+ state.pendingBroadcasts.delete(id);
21
+ const activeBroadcast = state.activeBroadcasts.get(synToken);
22
+ if (activeBroadcast)
23
+ state.activeBroadcasts.get(synToken).upToken = upToken;
24
+ else
25
+ state.connection.send(
26
+ jsonRpcMsg({
27
+ id: getInternalId(),
28
+ method: "transaction_v1_stop",
29
+ params: [upToken]
30
+ })
31
+ );
32
+ return;
33
+ }
34
+ isActive = state.onGoingRequests.has(id);
35
+ if ("result" in parsed && state.onGoingRequests.get(id)?.type === 0 /* ChainHeadFollow */)
16
36
  state.activeChainHeads.add(parsed.result);
17
37
  state.onGoingRequests.delete(parsed.id);
18
- } else {
38
+ } else if ("params" in parsed) {
19
39
  const { subscription, result } = parsed.params;
20
40
  if (result?.event === "stop")
21
41
  state.activeChainHeads.delete(subscription);
22
42
  }
23
43
  }
24
- if (state.type !== 2 /* Done */) toConsumer(msg);
44
+ if (isActive && state.type !== 2 /* Done */) toConsumer(msg);
25
45
  };
26
46
  const send = (msg) => {
27
47
  if (state.type === 2 /* Done */) return;
48
+ const parsed = JSON.parse(msg);
49
+ if ("id" in parsed) {
50
+ const { method, id, params } = parsed;
51
+ const [group, , methodName] = method.split("_");
52
+ if (group === "transaction") {
53
+ if (methodName === "stop") {
54
+ const [synToken] = params;
55
+ const active = state.activeBroadcasts.get(synToken);
56
+ state.activeBroadcasts.delete(synToken);
57
+ toConsumer(
58
+ jsonRpcMsg({
59
+ id,
60
+ result: null
61
+ })
62
+ );
63
+ if (state.type === 0 /* Connected */ && active && active.upToken) {
64
+ state.connection.send(
65
+ jsonRpcMsg({
66
+ id,
67
+ method,
68
+ params: [active.upToken]
69
+ })
70
+ );
71
+ }
72
+ return;
73
+ }
74
+ if (methodName === "broadcast") {
75
+ const synToken = getOpaqueToken();
76
+ state.activeBroadcasts.set(synToken, {
77
+ tx: params[0],
78
+ synToken
79
+ });
80
+ if (state.type === 0 /* Connected */) {
81
+ state.pendingBroadcasts.set(id, synToken);
82
+ state.connection.send(msg);
83
+ }
84
+ toConsumer(
85
+ jsonRpcMsg({
86
+ id,
87
+ result: synToken
88
+ })
89
+ );
90
+ return;
91
+ }
92
+ }
93
+ }
28
94
  if (state.type === 1 /* Connecting */) {
29
95
  state.pending.push(msg);
30
96
  return;
31
97
  }
32
- const parsed = JSON.parse(msg);
33
- if (unfollowMethods.has(parsed.method))
98
+ if (parsed.method === "chainHead_v1_unfollow")
34
99
  state.activeChainHeads.delete(parsed.params[0]);
35
100
  if ("id" in parsed) {
36
101
  const { method, id } = parsed;
37
- const ongoingMsg = method.startsWith("chainHead") ? method.endsWith("follow") ? {
102
+ const [group, , methodName] = method.split("_");
103
+ const ongoingMsg = group === "chainHead" ? methodName === "follow" ? {
38
104
  type: 0 /* ChainHeadFollow */,
39
105
  msg
40
106
  } : { type: 1 /* ChainHeadOperation */, id } : { type: 2 /* Other */, msg };
@@ -51,12 +117,15 @@ const getProxy = (toConsumer) => {
51
117
  },
52
118
  connect: (cb) => {
53
119
  if (state.type !== 1 /* Connecting */) throw new Error("Nonesense");
54
- const { pending } = state;
120
+ const { pending, activeBroadcasts } = state;
55
121
  const onGoingRequests = /* @__PURE__ */ new Map();
56
122
  const activeChainHeads = /* @__PURE__ */ new Set();
57
123
  const onHalt = () => {
124
+ const activeBroadcasts2 = state.type !== 2 /* Done */ ? state.activeBroadcasts : /* @__PURE__ */ new Map();
125
+ activeBroadcasts2.forEach((x) => x.upToken = void 0);
58
126
  state = {
59
127
  type: 1 /* Connecting */,
128
+ activeBroadcasts: activeBroadcasts2,
60
129
  pending: []
61
130
  };
62
131
  activeChainHeads.forEach((subscription) => {
@@ -89,9 +158,24 @@ const getProxy = (toConsumer) => {
89
158
  state = {
90
159
  type: 0 /* Connected */,
91
160
  connection: cb(onMsgFromProvider, onHalt),
161
+ activeBroadcasts,
162
+ pendingBroadcasts: /* @__PURE__ */ new Map(),
92
163
  onGoingRequests,
93
164
  activeChainHeads
94
165
  };
166
+ activeBroadcasts.forEach((broadcast) => {
167
+ if (state.type === 0 /* Connected */) {
168
+ const id = getInternalId();
169
+ state.pendingBroadcasts.set(id, broadcast.synToken);
170
+ send(
171
+ jsonRpcMsg({
172
+ id,
173
+ method: "transaction_v1_broadcast",
174
+ params: [broadcast.tx]
175
+ })
176
+ );
177
+ }
178
+ });
95
179
  pending.forEach(send);
96
180
  }
97
181
  };
@@ -1 +1 @@
1
- {"version":3,"file":"get-proxy.mjs","sources":["../../src/get-proxy.ts"],"sourcesContent":["import { JsonRpcConnection } from \"@polkadot-api/json-rpc-provider\"\nimport { ReconnectableJsonRpcConnection } from \"./internal-types\"\nimport { jsonRpcMsg } from \"./json-rpc-message\"\n\nconst enum State {\n Connected,\n Connecting,\n Done,\n}\n\nconst enum OngoingMsgType {\n ChainHeadFollow,\n ChainHeadOperation,\n Other,\n}\ntype OngoingMsg =\n | {\n type: OngoingMsgType.ChainHeadFollow\n msg: string\n }\n | { type: OngoingMsgType.ChainHeadOperation; id: string }\n | { type: OngoingMsgType.Other; msg: string }\n\nconst unfollowMethods = new Set(\n [\"v1\", \"unstable\"].map((x) => `chainHead_${x}_unfollow`),\n)\n\nexport const getProxy: ReconnectableJsonRpcConnection = (\n toConsumer: (msg: string) => void,\n) => {\n let state:\n | {\n type: State.Connected\n connection: JsonRpcConnection\n onGoingRequests: Map<string, OngoingMsg>\n activeChainHeads: Set<string>\n }\n | { type: State.Connecting; pending: Array<string> }\n | { type: State.Done } = {\n type: State.Connecting,\n pending: [],\n }\n\n const onMsgFromProvider = (msg: string) => {\n if (state.type === State.Connected) {\n const parsed = JSON.parse(msg)\n if (\"id\" in parsed) {\n if (\n state.onGoingRequests.get(parsed.id)?.type ===\n OngoingMsgType.ChainHeadFollow\n )\n state.activeChainHeads.add(parsed.result)\n state.onGoingRequests.delete(parsed.id)\n } else {\n const { subscription, result } = parsed.params\n if (result?.event === \"stop\")\n state.activeChainHeads.delete(subscription)\n }\n }\n // If the state is \"Connecting\", then these are messages\n // sent from the `onHalt` function. So, we mus realy them\n if (state.type !== State.Done) toConsumer(msg)\n }\n\n const send = (msg: string) => {\n if (state.type === State.Done) return\n if (state.type === State.Connecting) {\n state.pending.push(msg)\n return\n }\n const parsed = JSON.parse(msg)\n if (unfollowMethods.has(parsed.method))\n state.activeChainHeads.delete(parsed.params[0])\n\n if (\"id\" in parsed) {\n const { method, id } = parsed as { method: string; id: string }\n const ongoingMsg: OngoingMsg = method.startsWith(\"chainHead\")\n ? method.endsWith(\"follow\")\n ? {\n type: OngoingMsgType.ChainHeadFollow,\n msg,\n }\n : { type: OngoingMsgType.ChainHeadOperation, id }\n : { type: OngoingMsgType.Other, msg }\n state.onGoingRequests.set(id, ongoingMsg)\n }\n\n state.connection.send(msg)\n }\n\n return {\n send,\n disconnect: () => {\n if (state.type === State.Done) return\n if (state.type === State.Connected) state.connection.disconnect()\n state = { type: State.Done }\n },\n connect: (cb) => {\n if (state.type !== State.Connecting) throw new Error(\"Nonesense\")\n\n const { pending } = state\n const onGoingRequests = new Map<string, OngoingMsg>()\n const activeChainHeads = new Set<string>()\n const onHalt = () => {\n state = {\n type: State.Connecting,\n pending: [],\n }\n activeChainHeads.forEach((subscription) => {\n // We don't send the messages directy to the consumer\n // b/c they could have disconnected after receiving one\n // of these messages. The `onMsgFromProvider` fn handles that\n onMsgFromProvider(\n jsonRpcMsg({\n params: {\n subscription,\n result: {\n event: \"stop\",\n internal: true,\n },\n },\n }),\n )\n })\n activeChainHeads.clear()\n for (const x of onGoingRequests.values()) {\n if (x.type === OngoingMsgType.ChainHeadOperation)\n onMsgFromProvider(\n jsonRpcMsg({\n id: x.id,\n error: { code: -32603, message: \"Internal error\" },\n internal: true,\n }),\n )\n else send(x.msg)\n }\n onGoingRequests.clear()\n }\n state = {\n type: State.Connected,\n connection: cb(onMsgFromProvider, onHalt),\n onGoingRequests,\n activeChainHeads,\n }\n pending.forEach(send)\n },\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"get-proxy.mjs","sources":["../../src/get-proxy.ts"],"sourcesContent":["import { JsonRpcConnection } from \"@polkadot-api/json-rpc-provider\"\nimport { ReconnectableJsonRpcConnection } from \"./internal-types\"\nimport { jsonRpcMsg } from \"./json-rpc-message\"\nimport { getOpaqueToken } from \"./get-opaque-token\"\n\nconst enum State {\n Connected,\n Connecting,\n Done,\n}\n\nconst enum OngoingMsgType {\n ChainHeadFollow,\n ChainHeadOperation,\n Other,\n}\ntype OngoingMsg =\n | {\n type: OngoingMsgType.ChainHeadFollow\n msg: string\n }\n | { type: OngoingMsgType.ChainHeadOperation; id: string }\n | { type: OngoingMsgType.Other; msg: string }\n\nconst getInternalId = () => `___proxyInternalId__${getOpaqueToken()}`\n\nexport const getProxy: ReconnectableJsonRpcConnection = (\n toConsumer: (msg: string) => void,\n) => {\n let state:\n | {\n type: State.Connected\n connection: JsonRpcConnection\n activeChainHeads: Set<string>\n activeBroadcasts: Map<\n string,\n { tx: string; synToken: string; upToken?: string }\n >\n // the key is the upstream id, the value is the synthetic token\n pendingBroadcasts: Map<string, string>\n\n // These are requests for which their replies should be propagated downstream\n // Therefore, the `pendingBroadcasts` won't be included in here b/c they are synthetic\n onGoingRequests: Map<string, OngoingMsg>\n }\n | {\n type: State.Connecting\n pending: Array<string>\n activeBroadcasts: Map<\n string,\n { tx: string; synToken: string; upToken?: string }\n >\n }\n | { type: State.Done } = {\n type: State.Connecting,\n activeBroadcasts: new Map(),\n pending: [],\n }\n\n const onMsgFromProvider = (msg: string) => {\n let isActive = true\n if (state.type === State.Connected) {\n const parsed = JSON.parse(msg)\n if (\"id\" in parsed) {\n const { id } = parsed\n if (state.pendingBroadcasts.has(id)) {\n const synToken = state.pendingBroadcasts.get(id)!\n const upToken = parsed.result\n state.pendingBroadcasts.delete(id)\n const activeBroadcast = state.activeBroadcasts.get(synToken)\n\n if (activeBroadcast)\n state.activeBroadcasts.get(synToken)!.upToken = upToken\n else\n // The consumer stopped before we got the response\n state.connection.send(\n jsonRpcMsg({\n id: getInternalId(),\n method: \"transaction_v1_stop\",\n params: [upToken],\n }),\n )\n\n return\n }\n\n isActive = state.onGoingRequests.has(id)\n if (\n \"result\" in parsed &&\n state.onGoingRequests.get(id)?.type === OngoingMsgType.ChainHeadFollow\n )\n state.activeChainHeads.add(parsed.result)\n state.onGoingRequests.delete(parsed.id)\n } else if (\"params\" in parsed) {\n const { subscription, result } = parsed.params\n if (result?.event === \"stop\")\n state.activeChainHeads.delete(subscription)\n }\n }\n // If the state is \"Connecting\", then these are messages\n // sent from the `onHalt` function. So, we mus realy them\n if (isActive && state.type !== State.Done) toConsumer(msg)\n }\n\n const send = (msg: string) => {\n if (state.type === State.Done) return\n const parsed = JSON.parse(msg)\n\n // Transaction methods are purely synthetic, so they must be handled separately\n if (\"id\" in parsed) {\n const { method, id, params } = parsed as {\n method: string\n id: string\n params: string[]\n }\n const [group, , methodName] = method.split(\"_\")\n\n if (group === \"transaction\") {\n if (methodName === \"stop\") {\n const [synToken] = params\n const active = state.activeBroadcasts.get(synToken)\n state.activeBroadcasts.delete(synToken)\n toConsumer(\n jsonRpcMsg({\n id,\n result: null,\n }),\n )\n\n if (state.type === State.Connected && active && active.upToken) {\n // The response from this request will be ignored later on\n // because it won't be among the ongoing requests. so, it won't get to downstream\n state.connection.send(\n jsonRpcMsg({\n id,\n method,\n params: [active.upToken],\n }),\n )\n }\n\n // prevents the request from being included into the ongoingRequests\n return\n }\n\n if (methodName === \"broadcast\") {\n const synToken = getOpaqueToken()\n state.activeBroadcasts.set(synToken, {\n tx: params[0],\n synToken,\n })\n\n if (state.type === State.Connected) {\n state.pendingBroadcasts.set(id, synToken)\n state.connection.send(msg)\n }\n\n toConsumer(\n jsonRpcMsg({\n id,\n result: synToken,\n }),\n )\n\n // prevents the request to be tracked with the ongoingRequests\n return\n }\n }\n }\n\n if (state.type === State.Connecting) {\n state.pending.push(msg)\n return\n }\n if (parsed.method === \"chainHead_v1_unfollow\")\n state.activeChainHeads.delete(parsed.params[0])\n\n if (\"id\" in parsed) {\n const { method, id } = parsed as { method: string; id: string }\n const [group, , methodName] = method.split(\"_\")\n\n const ongoingMsg: OngoingMsg =\n group === \"chainHead\"\n ? methodName === \"follow\"\n ? {\n type: OngoingMsgType.ChainHeadFollow,\n msg,\n }\n : { type: OngoingMsgType.ChainHeadOperation, id }\n : { type: OngoingMsgType.Other, msg }\n state.onGoingRequests.set(id, ongoingMsg)\n }\n\n state.connection.send(msg)\n }\n\n return {\n send,\n disconnect: () => {\n if (state.type === State.Done) return\n if (state.type === State.Connected) state.connection.disconnect()\n state = { type: State.Done }\n },\n connect: (cb) => {\n if (state.type !== State.Connecting) throw new Error(\"Nonesense\")\n\n const { pending, activeBroadcasts } = state\n const onGoingRequests = new Map<string, OngoingMsg>()\n const activeChainHeads = new Set<string>()\n const onHalt = () => {\n const activeBroadcasts: Map<\n string,\n { tx: string; synToken: string; upToken?: string }\n > = state.type !== State.Done ? state.activeBroadcasts : new Map()\n activeBroadcasts.forEach((x) => (x.upToken = undefined))\n state = {\n type: State.Connecting,\n activeBroadcasts,\n pending: [],\n }\n activeChainHeads.forEach((subscription) => {\n // We don't send the messages directy to the consumer\n // b/c they could have disconnected after receiving one\n // of these messages. The `onMsgFromProvider` fn handles that\n onMsgFromProvider(\n jsonRpcMsg({\n params: {\n subscription,\n result: {\n event: \"stop\",\n internal: true,\n },\n },\n }),\n )\n })\n activeChainHeads.clear()\n for (const x of onGoingRequests.values()) {\n if (x.type === OngoingMsgType.ChainHeadOperation)\n onMsgFromProvider(\n jsonRpcMsg({\n id: x.id,\n error: { code: -32603, message: \"Internal error\" },\n internal: true,\n }),\n )\n else send(x.msg)\n }\n onGoingRequests.clear()\n }\n state = {\n type: State.Connected,\n connection: cb(onMsgFromProvider, onHalt),\n activeBroadcasts,\n pendingBroadcasts: new Map(),\n onGoingRequests,\n activeChainHeads,\n }\n activeBroadcasts.forEach((broadcast) => {\n if (state.type === State.Connected) {\n const id = getInternalId()\n state.pendingBroadcasts.set(id, broadcast.synToken)\n send(\n jsonRpcMsg({\n id,\n method: \"transaction_v1_broadcast\",\n params: [broadcast.tx],\n }),\n )\n }\n })\n pending.forEach(send)\n },\n }\n}\n"],"names":["activeBroadcasts"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"get-sync-provider.mjs","sources":["../../src/get-sync-provider.ts"],"sourcesContent":["import type { JsonRpcProvider } from \"@polkadot-api/json-rpc-provider\"\nimport { getProxy } from \"./get-proxy\"\nimport { AsyncJsonRpcProvider } from \"./public-types\"\nimport { ConnectableJsonRpcConnection } from \"./internal-types\"\n\nexport const getSyncProvider =\n (input: () => Promise<AsyncJsonRpcProvider>): JsonRpcProvider =>\n (onMessage) => {\n let proxy: ConnectableJsonRpcConnection | null = getProxy(onMessage)\n\n const start = () => {\n input().then(\n (cb) => {\n if (!proxy) {\n try {\n cb(\n () => {},\n () => {},\n ).disconnect()\n } catch (_) {}\n } else\n proxy.connect((onMsg, onHalt) =>\n cb(onMsg, () => {\n onHalt()\n start()\n }),\n )\n },\n () => {\n proxy && setTimeout(start, 0)\n },\n )\n }\n\n start()\n return {\n send: (msg) => {\n proxy?.send(msg)\n },\n disconnect: () => {\n proxy?.disconnect()\n proxy = null\n },\n }\n }\n"],"names":[],"mappings":";;AAKO,MAAM,eACX,GAAA,CAAC,KACD,KAAA,CAAC,SAAc,KAAA;AACb,EAAI,IAAA,KAAA,GAA6C,SAAS,SAAS,CAAA,CAAA;AAEnE,EAAA,MAAM,QAAQ,MAAM;AAClB,IAAA,KAAA,EAAQ,CAAA,IAAA;AAAA,MACN,CAAC,EAAO,KAAA;AACN,QAAA,IAAI,CAAC,KAAO,EAAA;AACV,UAAI,IAAA;AACF,YAAA,EAAA;AAAA,cACE,MAAM;AAAA,eAAC;AAAA,cACP,MAAM;AAAA,eAAC;AAAA,cACP,UAAW,EAAA,CAAA;AAAA,mBACN,CAAG,EAAA;AAAA,WAAC;AAAA,SACf;AACE,UAAM,KAAA,CAAA,OAAA;AAAA,YAAQ,CAAC,KAAA,EAAO,MACpB,KAAA,EAAA,CAAG,OAAO,MAAM;AACd,cAAO,MAAA,EAAA,CAAA;AACP,cAAM,KAAA,EAAA,CAAA;AAAA,aACP,CAAA;AAAA,WACH,CAAA;AAAA,OACJ;AAAA,MACA,MAAM;AACJ,QAAS,KAAA,IAAA,UAAA,CAAW,OAAO,CAAC,CAAA,CAAA;AAAA,OAC9B;AAAA,KACF,CAAA;AAAA,GACF,CAAA;AAEA,EAAM,KAAA,EAAA,CAAA;AACN,EAAO,OAAA;AAAA,IACL,IAAA,EAAM,CAAC,GAAQ,KAAA;AACb,MAAA,KAAA,EAAO,KAAK,GAAG,CAAA,CAAA;AAAA,KACjB;AAAA,IACA,YAAY,MAAM;AAChB,MAAA,KAAA,EAAO,UAAW,EAAA,CAAA;AAClB,MAAQ,KAAA,GAAA,IAAA,CAAA;AAAA,KACV;AAAA,GACF,CAAA;AACF;;;;"}
1
+ {"version":3,"file":"get-sync-provider.mjs","sources":["../../src/get-sync-provider.ts"],"sourcesContent":["import type { JsonRpcProvider } from \"@polkadot-api/json-rpc-provider\"\nimport { getProxy } from \"./get-proxy\"\nimport { AsyncJsonRpcProvider } from \"./public-types\"\nimport { ConnectableJsonRpcConnection } from \"./internal-types\"\n\nexport const getSyncProvider =\n (input: () => Promise<AsyncJsonRpcProvider>): JsonRpcProvider =>\n (onMessage) => {\n let proxy: ConnectableJsonRpcConnection | null = getProxy(onMessage)\n\n const start = () => {\n input().then(\n (cb) => {\n if (!proxy) {\n try {\n cb(\n () => {},\n () => {},\n ).disconnect()\n } catch (_) {}\n } else\n proxy.connect((onMsg, onHalt) =>\n cb(onMsg, () => {\n onHalt()\n start()\n }),\n )\n },\n () => {\n proxy && setTimeout(start, 0)\n },\n )\n }\n\n start()\n return {\n send: (msg) => {\n proxy?.send(msg)\n },\n disconnect: () => {\n proxy?.disconnect()\n proxy = null\n },\n }\n }\n"],"names":[],"mappings":";;AAKO,MAAM,eAAA,GACX,CAAC,KAAA,KACD,CAAC,SAAA,KAAc;AACb,EAAA,IAAI,KAAA,GAA6C,SAAS,SAAS,CAAA;AAEnE,EAAA,MAAM,QAAQ,MAAM;AAClB,IAAA,KAAA,EAAM,CAAE,IAAA;AAAA,MACN,CAAC,EAAA,KAAO;AACN,QAAA,IAAI,CAAC,KAAA,EAAO;AACV,UAAA,IAAI;AACF,YAAA,EAAA;AAAA,cACE,MAAM;AAAA,cAAC,CAAA;AAAA,cACP,MAAM;AAAA,cAAC;AAAA,cACP,UAAA,EAAW;AAAA,UACf,SAAS,CAAA,EAAG;AAAA,UAAC;AAAA,QACf,CAAA;AACE,UAAA,KAAA,CAAM,OAAA;AAAA,YAAQ,CAAC,KAAA,EAAO,MAAA,KACpB,EAAA,CAAG,OAAO,MAAM;AACd,cAAA,MAAA,EAAO;AACP,cAAA,KAAA,EAAM;AAAA,YACR,CAAC;AAAA,WACH;AAAA,MACJ,CAAA;AAAA,MACA,MAAM;AACJ,QAAA,KAAA,IAAS,UAAA,CAAW,OAAO,CAAC,CAAA;AAAA,MAC9B;AAAA,KACF;AAAA,EACF,CAAA;AAEA,EAAA,KAAA,EAAM;AACN,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,CAAC,GAAA,KAAQ;AACb,MAAA,KAAA,EAAO,KAAK,GAAG,CAAA;AAAA,IACjB,CAAA;AAAA,IACA,YAAY,MAAM;AAChB,MAAA,KAAA,EAAO,UAAA,EAAW;AAClB,MAAA,KAAA,GAAQ,IAAA;AAAA,IACV;AAAA,GACF;AACF;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"json-rpc-message.mjs","sources":["../../src/json-rpc-message.ts"],"sourcesContent":["export const jsonRpcMsg = <T extends {}>(msg: T) =>\n JSON.stringify({\n jsonrpc: \"2.0\",\n ...msg,\n })\n"],"names":[],"mappings":"AAAO,MAAM,UAAa,GAAA,CAAe,GACvC,KAAA,IAAA,CAAK,SAAU,CAAA;AAAA,EACb,OAAS,EAAA,KAAA;AAAA,EACT,GAAG,GAAA;AACL,CAAC;;;;"}
1
+ {"version":3,"file":"json-rpc-message.mjs","sources":["../../src/json-rpc-message.ts"],"sourcesContent":["export const jsonRpcMsg = <T extends {}>(msg: T) =>\n JSON.stringify({\n jsonrpc: \"2.0\",\n ...msg,\n })\n"],"names":[],"mappings":"AAAO,MAAM,UAAA,GAAa,CAAe,GAAA,KACvC,IAAA,CAAK,SAAA,CAAU;AAAA,EACb,OAAA,EAAS,KAAA;AAAA,EACT,GAAG;AACL,CAAC;;;;"}
package/dist/index.d.ts CHANGED
@@ -4,4 +4,5 @@ type AsyncJsonRpcProvider = (onMessage: (message: string) => void, onHalt: () =>
4
4
 
5
5
  declare const getSyncProvider: (input: () => Promise<AsyncJsonRpcProvider>) => JsonRpcProvider;
6
6
 
7
- export { type AsyncJsonRpcProvider, getSyncProvider };
7
+ export { getSyncProvider };
8
+ export type { AsyncJsonRpcProvider };
package/dist/index.js CHANGED
@@ -5,41 +5,109 @@ const jsonRpcMsg = (msg) => JSON.stringify({
5
5
  ...msg
6
6
  });
7
7
 
8
- const unfollowMethods = new Set(
9
- ["v1", "unstable"].map((x) => `chainHead_${x}_unfollow`)
10
- );
8
+ let count = 0;
9
+ const getOpaqueToken = () => `proxyOpaque${count++}`;
10
+
11
+ const getInternalId = () => `___proxyInternalId__${getOpaqueToken()}`;
11
12
  const getProxy = (toConsumer) => {
12
13
  let state = {
13
14
  type: 1 /* Connecting */,
15
+ activeBroadcasts: /* @__PURE__ */ new Map(),
14
16
  pending: []
15
17
  };
16
18
  const onMsgFromProvider = (msg) => {
19
+ let isActive = true;
17
20
  if (state.type === 0 /* Connected */) {
18
21
  const parsed = JSON.parse(msg);
19
22
  if ("id" in parsed) {
20
- if (state.onGoingRequests.get(parsed.id)?.type === 0 /* ChainHeadFollow */)
23
+ const { id } = parsed;
24
+ if (state.pendingBroadcasts.has(id)) {
25
+ const synToken = state.pendingBroadcasts.get(id);
26
+ const upToken = parsed.result;
27
+ state.pendingBroadcasts.delete(id);
28
+ const activeBroadcast = state.activeBroadcasts.get(synToken);
29
+ if (activeBroadcast)
30
+ state.activeBroadcasts.get(synToken).upToken = upToken;
31
+ else
32
+ state.connection.send(
33
+ jsonRpcMsg({
34
+ id: getInternalId(),
35
+ method: "transaction_v1_stop",
36
+ params: [upToken]
37
+ })
38
+ );
39
+ return;
40
+ }
41
+ isActive = state.onGoingRequests.has(id);
42
+ if ("result" in parsed && state.onGoingRequests.get(id)?.type === 0 /* ChainHeadFollow */)
21
43
  state.activeChainHeads.add(parsed.result);
22
44
  state.onGoingRequests.delete(parsed.id);
23
- } else {
45
+ } else if ("params" in parsed) {
24
46
  const { subscription, result } = parsed.params;
25
47
  if (result?.event === "stop")
26
48
  state.activeChainHeads.delete(subscription);
27
49
  }
28
50
  }
29
- if (state.type !== 2 /* Done */) toConsumer(msg);
51
+ if (isActive && state.type !== 2 /* Done */) toConsumer(msg);
30
52
  };
31
53
  const send = (msg) => {
32
54
  if (state.type === 2 /* Done */) return;
55
+ const parsed = JSON.parse(msg);
56
+ if ("id" in parsed) {
57
+ const { method, id, params } = parsed;
58
+ const [group, , methodName] = method.split("_");
59
+ if (group === "transaction") {
60
+ if (methodName === "stop") {
61
+ const [synToken] = params;
62
+ const active = state.activeBroadcasts.get(synToken);
63
+ state.activeBroadcasts.delete(synToken);
64
+ toConsumer(
65
+ jsonRpcMsg({
66
+ id,
67
+ result: null
68
+ })
69
+ );
70
+ if (state.type === 0 /* Connected */ && active && active.upToken) {
71
+ state.connection.send(
72
+ jsonRpcMsg({
73
+ id,
74
+ method,
75
+ params: [active.upToken]
76
+ })
77
+ );
78
+ }
79
+ return;
80
+ }
81
+ if (methodName === "broadcast") {
82
+ const synToken = getOpaqueToken();
83
+ state.activeBroadcasts.set(synToken, {
84
+ tx: params[0],
85
+ synToken
86
+ });
87
+ if (state.type === 0 /* Connected */) {
88
+ state.pendingBroadcasts.set(id, synToken);
89
+ state.connection.send(msg);
90
+ }
91
+ toConsumer(
92
+ jsonRpcMsg({
93
+ id,
94
+ result: synToken
95
+ })
96
+ );
97
+ return;
98
+ }
99
+ }
100
+ }
33
101
  if (state.type === 1 /* Connecting */) {
34
102
  state.pending.push(msg);
35
103
  return;
36
104
  }
37
- const parsed = JSON.parse(msg);
38
- if (unfollowMethods.has(parsed.method))
105
+ if (parsed.method === "chainHead_v1_unfollow")
39
106
  state.activeChainHeads.delete(parsed.params[0]);
40
107
  if ("id" in parsed) {
41
108
  const { method, id } = parsed;
42
- const ongoingMsg = method.startsWith("chainHead") ? method.endsWith("follow") ? {
109
+ const [group, , methodName] = method.split("_");
110
+ const ongoingMsg = group === "chainHead" ? methodName === "follow" ? {
43
111
  type: 0 /* ChainHeadFollow */,
44
112
  msg
45
113
  } : { type: 1 /* ChainHeadOperation */, id } : { type: 2 /* Other */, msg };
@@ -56,12 +124,15 @@ const getProxy = (toConsumer) => {
56
124
  },
57
125
  connect: (cb) => {
58
126
  if (state.type !== 1 /* Connecting */) throw new Error("Nonesense");
59
- const { pending } = state;
127
+ const { pending, activeBroadcasts } = state;
60
128
  const onGoingRequests = /* @__PURE__ */ new Map();
61
129
  const activeChainHeads = /* @__PURE__ */ new Set();
62
130
  const onHalt = () => {
131
+ const activeBroadcasts2 = state.type !== 2 /* Done */ ? state.activeBroadcasts : /* @__PURE__ */ new Map();
132
+ activeBroadcasts2.forEach((x) => x.upToken = void 0);
63
133
  state = {
64
134
  type: 1 /* Connecting */,
135
+ activeBroadcasts: activeBroadcasts2,
65
136
  pending: []
66
137
  };
67
138
  activeChainHeads.forEach((subscription) => {
@@ -94,9 +165,24 @@ const getProxy = (toConsumer) => {
94
165
  state = {
95
166
  type: 0 /* Connected */,
96
167
  connection: cb(onMsgFromProvider, onHalt),
168
+ activeBroadcasts,
169
+ pendingBroadcasts: /* @__PURE__ */ new Map(),
97
170
  onGoingRequests,
98
171
  activeChainHeads
99
172
  };
173
+ activeBroadcasts.forEach((broadcast) => {
174
+ if (state.type === 0 /* Connected */) {
175
+ const id = getInternalId();
176
+ state.pendingBroadcasts.set(id, broadcast.synToken);
177
+ send(
178
+ jsonRpcMsg({
179
+ id,
180
+ method: "transaction_v1_broadcast",
181
+ params: [broadcast.tx]
182
+ })
183
+ );
184
+ }
185
+ });
100
186
  pending.forEach(send);
101
187
  }
102
188
  };
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/json-rpc-message.ts","../src/get-proxy.ts","../src/get-sync-provider.ts"],"sourcesContent":["export const jsonRpcMsg = <T extends {}>(msg: T) =>\n JSON.stringify({\n jsonrpc: \"2.0\",\n ...msg,\n })\n","import { JsonRpcConnection } from \"@polkadot-api/json-rpc-provider\"\nimport { ReconnectableJsonRpcConnection } from \"./internal-types\"\nimport { jsonRpcMsg } from \"./json-rpc-message\"\n\nconst enum State {\n Connected,\n Connecting,\n Done,\n}\n\nconst enum OngoingMsgType {\n ChainHeadFollow,\n ChainHeadOperation,\n Other,\n}\ntype OngoingMsg =\n | {\n type: OngoingMsgType.ChainHeadFollow\n msg: string\n }\n | { type: OngoingMsgType.ChainHeadOperation; id: string }\n | { type: OngoingMsgType.Other; msg: string }\n\nconst unfollowMethods = new Set(\n [\"v1\", \"unstable\"].map((x) => `chainHead_${x}_unfollow`),\n)\n\nexport const getProxy: ReconnectableJsonRpcConnection = (\n toConsumer: (msg: string) => void,\n) => {\n let state:\n | {\n type: State.Connected\n connection: JsonRpcConnection\n onGoingRequests: Map<string, OngoingMsg>\n activeChainHeads: Set<string>\n }\n | { type: State.Connecting; pending: Array<string> }\n | { type: State.Done } = {\n type: State.Connecting,\n pending: [],\n }\n\n const onMsgFromProvider = (msg: string) => {\n if (state.type === State.Connected) {\n const parsed = JSON.parse(msg)\n if (\"id\" in parsed) {\n if (\n state.onGoingRequests.get(parsed.id)?.type ===\n OngoingMsgType.ChainHeadFollow\n )\n state.activeChainHeads.add(parsed.result)\n state.onGoingRequests.delete(parsed.id)\n } else {\n const { subscription, result } = parsed.params\n if (result?.event === \"stop\")\n state.activeChainHeads.delete(subscription)\n }\n }\n // If the state is \"Connecting\", then these are messages\n // sent from the `onHalt` function. So, we mus realy them\n if (state.type !== State.Done) toConsumer(msg)\n }\n\n const send = (msg: string) => {\n if (state.type === State.Done) return\n if (state.type === State.Connecting) {\n state.pending.push(msg)\n return\n }\n const parsed = JSON.parse(msg)\n if (unfollowMethods.has(parsed.method))\n state.activeChainHeads.delete(parsed.params[0])\n\n if (\"id\" in parsed) {\n const { method, id } = parsed as { method: string; id: string }\n const ongoingMsg: OngoingMsg = method.startsWith(\"chainHead\")\n ? method.endsWith(\"follow\")\n ? {\n type: OngoingMsgType.ChainHeadFollow,\n msg,\n }\n : { type: OngoingMsgType.ChainHeadOperation, id }\n : { type: OngoingMsgType.Other, msg }\n state.onGoingRequests.set(id, ongoingMsg)\n }\n\n state.connection.send(msg)\n }\n\n return {\n send,\n disconnect: () => {\n if (state.type === State.Done) return\n if (state.type === State.Connected) state.connection.disconnect()\n state = { type: State.Done }\n },\n connect: (cb) => {\n if (state.type !== State.Connecting) throw new Error(\"Nonesense\")\n\n const { pending } = state\n const onGoingRequests = new Map<string, OngoingMsg>()\n const activeChainHeads = new Set<string>()\n const onHalt = () => {\n state = {\n type: State.Connecting,\n pending: [],\n }\n activeChainHeads.forEach((subscription) => {\n // We don't send the messages directy to the consumer\n // b/c they could have disconnected after receiving one\n // of these messages. The `onMsgFromProvider` fn handles that\n onMsgFromProvider(\n jsonRpcMsg({\n params: {\n subscription,\n result: {\n event: \"stop\",\n internal: true,\n },\n },\n }),\n )\n })\n activeChainHeads.clear()\n for (const x of onGoingRequests.values()) {\n if (x.type === OngoingMsgType.ChainHeadOperation)\n onMsgFromProvider(\n jsonRpcMsg({\n id: x.id,\n error: { code: -32603, message: \"Internal error\" },\n internal: true,\n }),\n )\n else send(x.msg)\n }\n onGoingRequests.clear()\n }\n state = {\n type: State.Connected,\n connection: cb(onMsgFromProvider, onHalt),\n onGoingRequests,\n activeChainHeads,\n }\n pending.forEach(send)\n },\n }\n}\n","import type { JsonRpcProvider } from \"@polkadot-api/json-rpc-provider\"\nimport { getProxy } from \"./get-proxy\"\nimport { AsyncJsonRpcProvider } from \"./public-types\"\nimport { ConnectableJsonRpcConnection } from \"./internal-types\"\n\nexport const getSyncProvider =\n (input: () => Promise<AsyncJsonRpcProvider>): JsonRpcProvider =>\n (onMessage) => {\n let proxy: ConnectableJsonRpcConnection | null = getProxy(onMessage)\n\n const start = () => {\n input().then(\n (cb) => {\n if (!proxy) {\n try {\n cb(\n () => {},\n () => {},\n ).disconnect()\n } catch (_) {}\n } else\n proxy.connect((onMsg, onHalt) =>\n cb(onMsg, () => {\n onHalt()\n start()\n }),\n )\n },\n () => {\n proxy && setTimeout(start, 0)\n },\n )\n }\n\n start()\n return {\n send: (msg) => {\n proxy?.send(msg)\n },\n disconnect: () => {\n proxy?.disconnect()\n proxy = null\n },\n }\n }\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/json-rpc-message.ts","../src/get-opaque-token.ts","../src/get-proxy.ts","../src/get-sync-provider.ts"],"sourcesContent":["export const jsonRpcMsg = <T extends {}>(msg: T) =>\n JSON.stringify({\n jsonrpc: \"2.0\",\n ...msg,\n })\n","let count = 0\nexport const getOpaqueToken = (): string => `proxyOpaque${count++}`\n","import { JsonRpcConnection } from \"@polkadot-api/json-rpc-provider\"\nimport { ReconnectableJsonRpcConnection } from \"./internal-types\"\nimport { jsonRpcMsg } from \"./json-rpc-message\"\nimport { getOpaqueToken } from \"./get-opaque-token\"\n\nconst enum State {\n Connected,\n Connecting,\n Done,\n}\n\nconst enum OngoingMsgType {\n ChainHeadFollow,\n ChainHeadOperation,\n Other,\n}\ntype OngoingMsg =\n | {\n type: OngoingMsgType.ChainHeadFollow\n msg: string\n }\n | { type: OngoingMsgType.ChainHeadOperation; id: string }\n | { type: OngoingMsgType.Other; msg: string }\n\nconst getInternalId = () => `___proxyInternalId__${getOpaqueToken()}`\n\nexport const getProxy: ReconnectableJsonRpcConnection = (\n toConsumer: (msg: string) => void,\n) => {\n let state:\n | {\n type: State.Connected\n connection: JsonRpcConnection\n activeChainHeads: Set<string>\n activeBroadcasts: Map<\n string,\n { tx: string; synToken: string; upToken?: string }\n >\n // the key is the upstream id, the value is the synthetic token\n pendingBroadcasts: Map<string, string>\n\n // These are requests for which their replies should be propagated downstream\n // Therefore, the `pendingBroadcasts` won't be included in here b/c they are synthetic\n onGoingRequests: Map<string, OngoingMsg>\n }\n | {\n type: State.Connecting\n pending: Array<string>\n activeBroadcasts: Map<\n string,\n { tx: string; synToken: string; upToken?: string }\n >\n }\n | { type: State.Done } = {\n type: State.Connecting,\n activeBroadcasts: new Map(),\n pending: [],\n }\n\n const onMsgFromProvider = (msg: string) => {\n let isActive = true\n if (state.type === State.Connected) {\n const parsed = JSON.parse(msg)\n if (\"id\" in parsed) {\n const { id } = parsed\n if (state.pendingBroadcasts.has(id)) {\n const synToken = state.pendingBroadcasts.get(id)!\n const upToken = parsed.result\n state.pendingBroadcasts.delete(id)\n const activeBroadcast = state.activeBroadcasts.get(synToken)\n\n if (activeBroadcast)\n state.activeBroadcasts.get(synToken)!.upToken = upToken\n else\n // The consumer stopped before we got the response\n state.connection.send(\n jsonRpcMsg({\n id: getInternalId(),\n method: \"transaction_v1_stop\",\n params: [upToken],\n }),\n )\n\n return\n }\n\n isActive = state.onGoingRequests.has(id)\n if (\n \"result\" in parsed &&\n state.onGoingRequests.get(id)?.type === OngoingMsgType.ChainHeadFollow\n )\n state.activeChainHeads.add(parsed.result)\n state.onGoingRequests.delete(parsed.id)\n } else if (\"params\" in parsed) {\n const { subscription, result } = parsed.params\n if (result?.event === \"stop\")\n state.activeChainHeads.delete(subscription)\n }\n }\n // If the state is \"Connecting\", then these are messages\n // sent from the `onHalt` function. So, we mus realy them\n if (isActive && state.type !== State.Done) toConsumer(msg)\n }\n\n const send = (msg: string) => {\n if (state.type === State.Done) return\n const parsed = JSON.parse(msg)\n\n // Transaction methods are purely synthetic, so they must be handled separately\n if (\"id\" in parsed) {\n const { method, id, params } = parsed as {\n method: string\n id: string\n params: string[]\n }\n const [group, , methodName] = method.split(\"_\")\n\n if (group === \"transaction\") {\n if (methodName === \"stop\") {\n const [synToken] = params\n const active = state.activeBroadcasts.get(synToken)\n state.activeBroadcasts.delete(synToken)\n toConsumer(\n jsonRpcMsg({\n id,\n result: null,\n }),\n )\n\n if (state.type === State.Connected && active && active.upToken) {\n // The response from this request will be ignored later on\n // because it won't be among the ongoing requests. so, it won't get to downstream\n state.connection.send(\n jsonRpcMsg({\n id,\n method,\n params: [active.upToken],\n }),\n )\n }\n\n // prevents the request from being included into the ongoingRequests\n return\n }\n\n if (methodName === \"broadcast\") {\n const synToken = getOpaqueToken()\n state.activeBroadcasts.set(synToken, {\n tx: params[0],\n synToken,\n })\n\n if (state.type === State.Connected) {\n state.pendingBroadcasts.set(id, synToken)\n state.connection.send(msg)\n }\n\n toConsumer(\n jsonRpcMsg({\n id,\n result: synToken,\n }),\n )\n\n // prevents the request to be tracked with the ongoingRequests\n return\n }\n }\n }\n\n if (state.type === State.Connecting) {\n state.pending.push(msg)\n return\n }\n if (parsed.method === \"chainHead_v1_unfollow\")\n state.activeChainHeads.delete(parsed.params[0])\n\n if (\"id\" in parsed) {\n const { method, id } = parsed as { method: string; id: string }\n const [group, , methodName] = method.split(\"_\")\n\n const ongoingMsg: OngoingMsg =\n group === \"chainHead\"\n ? methodName === \"follow\"\n ? {\n type: OngoingMsgType.ChainHeadFollow,\n msg,\n }\n : { type: OngoingMsgType.ChainHeadOperation, id }\n : { type: OngoingMsgType.Other, msg }\n state.onGoingRequests.set(id, ongoingMsg)\n }\n\n state.connection.send(msg)\n }\n\n return {\n send,\n disconnect: () => {\n if (state.type === State.Done) return\n if (state.type === State.Connected) state.connection.disconnect()\n state = { type: State.Done }\n },\n connect: (cb) => {\n if (state.type !== State.Connecting) throw new Error(\"Nonesense\")\n\n const { pending, activeBroadcasts } = state\n const onGoingRequests = new Map<string, OngoingMsg>()\n const activeChainHeads = new Set<string>()\n const onHalt = () => {\n const activeBroadcasts: Map<\n string,\n { tx: string; synToken: string; upToken?: string }\n > = state.type !== State.Done ? state.activeBroadcasts : new Map()\n activeBroadcasts.forEach((x) => (x.upToken = undefined))\n state = {\n type: State.Connecting,\n activeBroadcasts,\n pending: [],\n }\n activeChainHeads.forEach((subscription) => {\n // We don't send the messages directy to the consumer\n // b/c they could have disconnected after receiving one\n // of these messages. The `onMsgFromProvider` fn handles that\n onMsgFromProvider(\n jsonRpcMsg({\n params: {\n subscription,\n result: {\n event: \"stop\",\n internal: true,\n },\n },\n }),\n )\n })\n activeChainHeads.clear()\n for (const x of onGoingRequests.values()) {\n if (x.type === OngoingMsgType.ChainHeadOperation)\n onMsgFromProvider(\n jsonRpcMsg({\n id: x.id,\n error: { code: -32603, message: \"Internal error\" },\n internal: true,\n }),\n )\n else send(x.msg)\n }\n onGoingRequests.clear()\n }\n state = {\n type: State.Connected,\n connection: cb(onMsgFromProvider, onHalt),\n activeBroadcasts,\n pendingBroadcasts: new Map(),\n onGoingRequests,\n activeChainHeads,\n }\n activeBroadcasts.forEach((broadcast) => {\n if (state.type === State.Connected) {\n const id = getInternalId()\n state.pendingBroadcasts.set(id, broadcast.synToken)\n send(\n jsonRpcMsg({\n id,\n method: \"transaction_v1_broadcast\",\n params: [broadcast.tx],\n }),\n )\n }\n })\n pending.forEach(send)\n },\n }\n}\n","import type { JsonRpcProvider } from \"@polkadot-api/json-rpc-provider\"\nimport { getProxy } from \"./get-proxy\"\nimport { AsyncJsonRpcProvider } from \"./public-types\"\nimport { ConnectableJsonRpcConnection } from \"./internal-types\"\n\nexport const getSyncProvider =\n (input: () => Promise<AsyncJsonRpcProvider>): JsonRpcProvider =>\n (onMessage) => {\n let proxy: ConnectableJsonRpcConnection | null = getProxy(onMessage)\n\n const start = () => {\n input().then(\n (cb) => {\n if (!proxy) {\n try {\n cb(\n () => {},\n () => {},\n ).disconnect()\n } catch (_) {}\n } else\n proxy.connect((onMsg, onHalt) =>\n cb(onMsg, () => {\n onHalt()\n start()\n }),\n )\n },\n () => {\n proxy && setTimeout(start, 0)\n },\n )\n }\n\n start()\n return {\n send: (msg) => {\n proxy?.send(msg)\n },\n disconnect: () => {\n proxy?.disconnect()\n proxy = null\n },\n }\n }\n"],"names":["activeBroadcasts"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@polkadot-api/json-rpc-provider-proxy",
3
- "version": "0.2.3",
3
+ "version": "0.2.5",
4
4
  "author": "Josep M Sobrepere (https://github.com/josepot)",
5
5
  "repository": {
6
6
  "type": "git",