@dedot/api 0.18.6 → 0.18.7

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.
@@ -63,23 +63,30 @@ class SubmittableExtrinsicV2 extends BaseSubmittableExtrinsic_js_1.BaseSubmittab
63
63
  };
64
64
  let txFound;
65
65
  let isSearching = false;
66
- let searchQueue = new utils_1.AsyncQueue();
67
- // TODO 1. move the searching logic into a different utility
68
- // 2. properly cancel the work by actually cancel the on-going operations
66
+ const searchQueue = new utils_1.AsyncQueue();
67
+ const finalizedQueue = new utils_1.AsyncQueue();
68
+ const trackedHashes = [];
69
69
  const cancelPendingSearch = () => {
70
70
  searchQueue.clear();
71
71
  };
72
72
  const cancelBodySearch = () => {
73
73
  searchQueue.cancel();
74
74
  };
75
- const startSearching = (block) => {
76
- return searchQueue.enqueue(async () => {
77
- const found = await checkTxIsOnChain(block.hash);
75
+ const startSearching = async (block) => {
76
+ const hash = block.hash;
77
+ if (!trackedHashes.includes(hash)) {
78
+ api.chainHead.holdBlock(hash);
79
+ trackedHashes.push(hash);
80
+ }
81
+ return searchQueue
82
+ .enqueue(async () => {
83
+ const found = await checkTxIsOnChain(hash);
78
84
  if (found) {
79
85
  cancelPendingSearch();
80
86
  }
81
87
  return found;
82
- });
88
+ })
89
+ .catch(() => undefined);
83
90
  };
84
91
  const checkBestBlockIncluded = async (block, bestChainChanged) => {
85
92
  if (bestChainChanged) {
@@ -142,43 +149,56 @@ class SubmittableExtrinsicV2 extends BaseSubmittableExtrinsic_js_1.BaseSubmittab
142
149
  }
143
150
  };
144
151
  const checkFinalizedBlockIncluded = async (block) => {
145
- const inBlock = await checkTxIsOnChain(block.hash);
146
- if (inBlock) {
147
- const { index: txIndex, events, blockHash, blockNumber } = inBlock;
148
- callback(new SubmittableResult_js_1.SubmittableResult({
149
- status: { type: 'Finalized', value: { blockHash, blockNumber, txIndex } },
150
- txHash,
151
- events,
152
- txIndex,
153
- }));
154
- }
155
- else {
156
- // Revalidate the tx, just in-case it becomes invalid along the way
157
- // Context: https://github.com/paritytech/json-rpc-interface-spec/pull/107#issuecomment-1906008814
158
- const validation = await validateTx(block.hash);
159
- if (validation.isOk)
160
- return;
161
- callback(new SubmittableResult_js_1.SubmittableResult({
162
- status: {
163
- type: 'Invalid',
164
- value: { error: `Invalid Tx: ${validation.err.type} - ${validation.err.value.type}` },
165
- },
166
- txHash,
167
- }));
152
+ const hash = block.hash;
153
+ if (!trackedHashes.includes(hash)) {
154
+ api.chainHead.holdBlock(hash);
155
+ trackedHashes.push(hash);
168
156
  }
169
- txUnsub().catch(utils_1.noop);
157
+ finalizedQueue
158
+ .enqueue(async () => {
159
+ const inBlock = await checkTxIsOnChain(hash);
160
+ if (inBlock) {
161
+ const { index: txIndex, events, blockHash, blockNumber } = inBlock;
162
+ callback(new SubmittableResult_js_1.SubmittableResult({
163
+ status: { type: 'Finalized', value: { blockHash, blockNumber, txIndex } },
164
+ txHash,
165
+ events,
166
+ txIndex,
167
+ }));
168
+ }
169
+ else {
170
+ // Revalidate the tx, just in-case it becomes invalid along the way
171
+ // Context: https://github.com/paritytech/json-rpc-interface-spec/pull/107#issuecomment-1906008814
172
+ const validation = await validateTx(hash);
173
+ if (validation.isOk)
174
+ return;
175
+ callback(new SubmittableResult_js_1.SubmittableResult({
176
+ status: {
177
+ type: 'Invalid',
178
+ value: { error: `Invalid Tx: ${validation.err.type} - ${validation.err.value.type}` },
179
+ },
180
+ txHash,
181
+ }));
182
+ }
183
+ txUnsub().catch(utils_1.noop);
184
+ })
185
+ .catch(utils_1.noop);
170
186
  };
187
+ const stopBestBlockTrackingFn = api.on('bestBlock', checkBestBlockIncluded);
188
+ const stopFinalizedBlockTrackingFn = api.on('finalizedBlock', checkFinalizedBlockIncluded);
171
189
  stopBroadcastFn = await api.txBroadcaster.broadcastTx(txHex);
172
190
  callback(new SubmittableResult_js_1.SubmittableResult({
173
191
  status: { type: 'Broadcasting' },
174
192
  txHash,
175
193
  }));
176
- const stopBestBlockTrackingFn = api.on('bestBlock', checkBestBlockIncluded);
177
- const stopFinalizedBlockTrackingFn = api.on('finalizedBlock', checkFinalizedBlockIncluded);
178
194
  const stopTracking = () => {
179
195
  stopBestBlockTrackingFn();
180
196
  stopFinalizedBlockTrackingFn();
181
197
  cancelBodySearch();
198
+ finalizedQueue.cancel();
199
+ trackedHashes.forEach((h) => {
200
+ api.chainHead.releaseBlock(h);
201
+ });
182
202
  };
183
203
  txUnsub = async () => {
184
204
  stopTracking();
@@ -765,5 +765,12 @@ class ChainHead extends JsonRpcGroup_js_1.JsonRpcGroup {
765
765
  this.#cache.clear();
766
766
  this.#archive?.clearCache();
767
767
  }
768
+ holdBlock(hash) {
769
+ this.#ensurePinnedHash(hash);
770
+ this.#blockUsage.use(hash);
771
+ }
772
+ releaseBlock(hash) {
773
+ this.#blockUsage.release(hash);
774
+ }
768
775
  }
769
776
  exports.ChainHead = ChainHead;
@@ -60,23 +60,30 @@ export class SubmittableExtrinsicV2 extends BaseSubmittableExtrinsic {
60
60
  };
61
61
  let txFound;
62
62
  let isSearching = false;
63
- let searchQueue = new AsyncQueue();
64
- // TODO 1. move the searching logic into a different utility
65
- // 2. properly cancel the work by actually cancel the on-going operations
63
+ const searchQueue = new AsyncQueue();
64
+ const finalizedQueue = new AsyncQueue();
65
+ const trackedHashes = [];
66
66
  const cancelPendingSearch = () => {
67
67
  searchQueue.clear();
68
68
  };
69
69
  const cancelBodySearch = () => {
70
70
  searchQueue.cancel();
71
71
  };
72
- const startSearching = (block) => {
73
- return searchQueue.enqueue(async () => {
74
- const found = await checkTxIsOnChain(block.hash);
72
+ const startSearching = async (block) => {
73
+ const hash = block.hash;
74
+ if (!trackedHashes.includes(hash)) {
75
+ api.chainHead.holdBlock(hash);
76
+ trackedHashes.push(hash);
77
+ }
78
+ return searchQueue
79
+ .enqueue(async () => {
80
+ const found = await checkTxIsOnChain(hash);
75
81
  if (found) {
76
82
  cancelPendingSearch();
77
83
  }
78
84
  return found;
79
- });
85
+ })
86
+ .catch(() => undefined);
80
87
  };
81
88
  const checkBestBlockIncluded = async (block, bestChainChanged) => {
82
89
  if (bestChainChanged) {
@@ -139,43 +146,56 @@ export class SubmittableExtrinsicV2 extends BaseSubmittableExtrinsic {
139
146
  }
140
147
  };
141
148
  const checkFinalizedBlockIncluded = async (block) => {
142
- const inBlock = await checkTxIsOnChain(block.hash);
143
- if (inBlock) {
144
- const { index: txIndex, events, blockHash, blockNumber } = inBlock;
145
- callback(new SubmittableResult({
146
- status: { type: 'Finalized', value: { blockHash, blockNumber, txIndex } },
147
- txHash,
148
- events,
149
- txIndex,
150
- }));
151
- }
152
- else {
153
- // Revalidate the tx, just in-case it becomes invalid along the way
154
- // Context: https://github.com/paritytech/json-rpc-interface-spec/pull/107#issuecomment-1906008814
155
- const validation = await validateTx(block.hash);
156
- if (validation.isOk)
157
- return;
158
- callback(new SubmittableResult({
159
- status: {
160
- type: 'Invalid',
161
- value: { error: `Invalid Tx: ${validation.err.type} - ${validation.err.value.type}` },
162
- },
163
- txHash,
164
- }));
149
+ const hash = block.hash;
150
+ if (!trackedHashes.includes(hash)) {
151
+ api.chainHead.holdBlock(hash);
152
+ trackedHashes.push(hash);
165
153
  }
166
- txUnsub().catch(noop);
154
+ finalizedQueue
155
+ .enqueue(async () => {
156
+ const inBlock = await checkTxIsOnChain(hash);
157
+ if (inBlock) {
158
+ const { index: txIndex, events, blockHash, blockNumber } = inBlock;
159
+ callback(new SubmittableResult({
160
+ status: { type: 'Finalized', value: { blockHash, blockNumber, txIndex } },
161
+ txHash,
162
+ events,
163
+ txIndex,
164
+ }));
165
+ }
166
+ else {
167
+ // Revalidate the tx, just in-case it becomes invalid along the way
168
+ // Context: https://github.com/paritytech/json-rpc-interface-spec/pull/107#issuecomment-1906008814
169
+ const validation = await validateTx(hash);
170
+ if (validation.isOk)
171
+ return;
172
+ callback(new SubmittableResult({
173
+ status: {
174
+ type: 'Invalid',
175
+ value: { error: `Invalid Tx: ${validation.err.type} - ${validation.err.value.type}` },
176
+ },
177
+ txHash,
178
+ }));
179
+ }
180
+ txUnsub().catch(noop);
181
+ })
182
+ .catch(noop);
167
183
  };
184
+ const stopBestBlockTrackingFn = api.on('bestBlock', checkBestBlockIncluded);
185
+ const stopFinalizedBlockTrackingFn = api.on('finalizedBlock', checkFinalizedBlockIncluded);
168
186
  stopBroadcastFn = await api.txBroadcaster.broadcastTx(txHex);
169
187
  callback(new SubmittableResult({
170
188
  status: { type: 'Broadcasting' },
171
189
  txHash,
172
190
  }));
173
- const stopBestBlockTrackingFn = api.on('bestBlock', checkBestBlockIncluded);
174
- const stopFinalizedBlockTrackingFn = api.on('finalizedBlock', checkFinalizedBlockIncluded);
175
191
  const stopTracking = () => {
176
192
  stopBestBlockTrackingFn();
177
193
  stopFinalizedBlockTrackingFn();
178
194
  cancelBodySearch();
195
+ finalizedQueue.cancel();
196
+ trackedHashes.forEach((h) => {
197
+ api.chainHead.releaseBlock(h);
198
+ });
179
199
  };
180
200
  txUnsub = async () => {
181
201
  stopTracking();
@@ -87,4 +87,6 @@ export declare class ChainHead extends JsonRpcGroup<ChainHeadEvent> {
87
87
  * ```
88
88
  */
89
89
  clearCache(): void;
90
+ holdBlock(hash: BlockHash): void;
91
+ releaseBlock(hash: BlockHash): void;
90
92
  }
@@ -762,4 +762,11 @@ export class ChainHead extends JsonRpcGroup {
762
762
  this.#cache.clear();
763
763
  this.#archive?.clearCache();
764
764
  }
765
+ holdBlock(hash) {
766
+ this.#ensurePinnedHash(hash);
767
+ this.#blockUsage.use(hash);
768
+ }
769
+ releaseBlock(hash) {
770
+ this.#blockUsage.release(hash);
771
+ }
765
772
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dedot/api",
3
- "version": "0.18.6",
3
+ "version": "0.18.7",
4
4
  "description": "A delightful JavaScript/TypeScript client for Polkadot & Substrate",
5
5
  "author": "Thang X. Vu <thang@dedot.dev>",
6
6
  "homepage": "https://dedot.dev",
@@ -13,13 +13,13 @@
13
13
  "type": "module",
14
14
  "sideEffects": false,
15
15
  "dependencies": {
16
- "@dedot/codecs": "0.18.6",
17
- "@dedot/providers": "0.18.6",
18
- "@dedot/runtime-specs": "0.18.6",
19
- "@dedot/shape": "0.18.6",
20
- "@dedot/storage": "0.18.6",
21
- "@dedot/types": "0.18.6",
22
- "@dedot/utils": "0.18.6"
16
+ "@dedot/codecs": "0.18.7",
17
+ "@dedot/providers": "0.18.7",
18
+ "@dedot/runtime-specs": "0.18.7",
19
+ "@dedot/shape": "0.18.7",
20
+ "@dedot/storage": "0.18.7",
21
+ "@dedot/types": "0.18.7",
22
+ "@dedot/utils": "0.18.7"
23
23
  },
24
24
  "scripts": {
25
25
  "build": "tsc --project tsconfig.build.json && tsc --project tsconfig.build.cjs.json",
@@ -48,7 +48,7 @@
48
48
  "node": ">=18"
49
49
  },
50
50
  "license": "Apache-2.0",
51
- "gitHead": "2ff0200696aa2e42505d30369fe84b2416838791",
51
+ "gitHead": "07f47f75512087407e03f301fc18c2059b3f613a",
52
52
  "module": "./index.js",
53
53
  "types": "./index.d.ts"
54
54
  }