@dedot/api 0.9.2 → 0.9.4
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.
|
@@ -410,7 +410,7 @@ class ChainHead extends JsonRpcGroup_js_1.JsonRpcGroup {
|
|
|
410
410
|
}
|
|
411
411
|
catch (e) {
|
|
412
412
|
if (e instanceof error_js_1.ChainHeadError && e.retryStrategy) {
|
|
413
|
-
return this.#retryOperation(e.retryStrategy, operation);
|
|
413
|
+
return await this.#retryOperation(e.retryStrategy, operation);
|
|
414
414
|
}
|
|
415
415
|
throw e;
|
|
416
416
|
}
|
|
@@ -437,7 +437,7 @@ class ChainHead extends JsonRpcGroup_js_1.JsonRpcGroup {
|
|
|
437
437
|
catch (e) {
|
|
438
438
|
// retry again until success, TODO we might need to limit the number of retries
|
|
439
439
|
if (e instanceof error_js_1.ChainHeadError && e.retryStrategy) {
|
|
440
|
-
return this.#retryOperation(e.retryStrategy, retry);
|
|
440
|
+
return await this.#retryOperation(e.retryStrategy, retry);
|
|
441
441
|
}
|
|
442
442
|
throw e;
|
|
443
443
|
}
|
|
@@ -550,19 +550,33 @@ class ChainHead extends JsonRpcGroup_js_1.JsonRpcGroup {
|
|
|
550
550
|
return this.#cache.get(cacheKey);
|
|
551
551
|
}
|
|
552
552
|
this.#blockUsage.use(hash);
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
553
|
+
let results = [];
|
|
554
|
+
// @ts-ignore a trick internally to check whether a provider is using smoldot connection
|
|
555
|
+
const isSmoldot = typeof this.client.provider['chain'] === 'function';
|
|
556
|
+
if (isSmoldot) {
|
|
557
|
+
const fetchItem = async (item) => {
|
|
558
|
+
const [batch, newDiscardedItems] = await this.#getStorage([item], childTrie ?? null, hash);
|
|
559
|
+
if (newDiscardedItems.length > 0) {
|
|
560
|
+
return fetchItem(item);
|
|
561
|
+
}
|
|
562
|
+
return batch;
|
|
563
|
+
};
|
|
564
|
+
results = (await Promise.all(items.map((one) => fetchItem(one)))).flat();
|
|
565
|
+
}
|
|
566
|
+
else {
|
|
567
|
+
let queryItems = items;
|
|
568
|
+
while (queryItems.length > 0) {
|
|
569
|
+
const [newBatch, newDiscardedItems] = await this.#getStorage(queryItems, childTrie ?? null, hash);
|
|
570
|
+
results.push(...newBatch);
|
|
571
|
+
queryItems = newDiscardedItems;
|
|
572
|
+
}
|
|
559
573
|
}
|
|
560
574
|
this.#cache.set(cacheKey, results);
|
|
561
575
|
return results;
|
|
562
576
|
}
|
|
563
577
|
catch (e) {
|
|
564
578
|
if (e instanceof error_js_1.ChainHeadBlockPrunedError && shouldRetryOnPrunedBlock) {
|
|
565
|
-
return this.storage(items, childTrie);
|
|
579
|
+
return await this.storage(items, childTrie);
|
|
566
580
|
}
|
|
567
581
|
throw e;
|
|
568
582
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.NewStorageQuery = void 0;
|
|
4
|
+
const utils_1 = require("@dedot/utils");
|
|
4
5
|
const BaseStorageQuery_js_1 = require("./BaseStorageQuery.js");
|
|
5
6
|
/**
|
|
6
7
|
* @name NewStorageQuery
|
|
@@ -51,6 +52,11 @@ class NewStorageQuery extends BaseStorageQuery_js_1.BaseStorageQuery {
|
|
|
51
52
|
const best = await this.client.chainHead.bestBlock();
|
|
52
53
|
// Track the latest changes for each key
|
|
53
54
|
const latestChanges = {};
|
|
55
|
+
// Using a queue here to make sure we don't accidentally
|
|
56
|
+
// put a pressure the json-rpc server in-case new blocks stack up too fast
|
|
57
|
+
// in case we send a lot of requests at the same time
|
|
58
|
+
// or the block time is small enough with elastic scaling
|
|
59
|
+
const pullQueue = new utils_1.AsyncQueue();
|
|
54
60
|
// Function to pull storage values and call the callback if there are changes
|
|
55
61
|
const pull = async ({ hash }) => {
|
|
56
62
|
// Query storage using ChainHead API
|
|
@@ -76,9 +82,12 @@ class NewStorageQuery extends BaseStorageQuery_js_1.BaseStorageQuery {
|
|
|
76
82
|
// Initial pull
|
|
77
83
|
await pull(best);
|
|
78
84
|
// Subscribe to best block events
|
|
79
|
-
const unsub = this.client.on('bestBlock',
|
|
85
|
+
const unsub = this.client.on('bestBlock', (block) => {
|
|
86
|
+
pullQueue.enqueue(() => pull(block)).catch(console.error);
|
|
87
|
+
});
|
|
80
88
|
return async () => {
|
|
81
89
|
unsub();
|
|
90
|
+
pullQueue.cancel();
|
|
82
91
|
};
|
|
83
92
|
}
|
|
84
93
|
}
|
|
@@ -407,7 +407,7 @@ export class ChainHead extends JsonRpcGroup {
|
|
|
407
407
|
}
|
|
408
408
|
catch (e) {
|
|
409
409
|
if (e instanceof ChainHeadError && e.retryStrategy) {
|
|
410
|
-
return this.#retryOperation(e.retryStrategy, operation);
|
|
410
|
+
return await this.#retryOperation(e.retryStrategy, operation);
|
|
411
411
|
}
|
|
412
412
|
throw e;
|
|
413
413
|
}
|
|
@@ -434,7 +434,7 @@ export class ChainHead extends JsonRpcGroup {
|
|
|
434
434
|
catch (e) {
|
|
435
435
|
// retry again until success, TODO we might need to limit the number of retries
|
|
436
436
|
if (e instanceof ChainHeadError && e.retryStrategy) {
|
|
437
|
-
return this.#retryOperation(e.retryStrategy, retry);
|
|
437
|
+
return await this.#retryOperation(e.retryStrategy, retry);
|
|
438
438
|
}
|
|
439
439
|
throw e;
|
|
440
440
|
}
|
|
@@ -547,19 +547,33 @@ export class ChainHead extends JsonRpcGroup {
|
|
|
547
547
|
return this.#cache.get(cacheKey);
|
|
548
548
|
}
|
|
549
549
|
this.#blockUsage.use(hash);
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
550
|
+
let results = [];
|
|
551
|
+
// @ts-ignore a trick internally to check whether a provider is using smoldot connection
|
|
552
|
+
const isSmoldot = typeof this.client.provider['chain'] === 'function';
|
|
553
|
+
if (isSmoldot) {
|
|
554
|
+
const fetchItem = async (item) => {
|
|
555
|
+
const [batch, newDiscardedItems] = await this.#getStorage([item], childTrie ?? null, hash);
|
|
556
|
+
if (newDiscardedItems.length > 0) {
|
|
557
|
+
return fetchItem(item);
|
|
558
|
+
}
|
|
559
|
+
return batch;
|
|
560
|
+
};
|
|
561
|
+
results = (await Promise.all(items.map((one) => fetchItem(one)))).flat();
|
|
562
|
+
}
|
|
563
|
+
else {
|
|
564
|
+
let queryItems = items;
|
|
565
|
+
while (queryItems.length > 0) {
|
|
566
|
+
const [newBatch, newDiscardedItems] = await this.#getStorage(queryItems, childTrie ?? null, hash);
|
|
567
|
+
results.push(...newBatch);
|
|
568
|
+
queryItems = newDiscardedItems;
|
|
569
|
+
}
|
|
556
570
|
}
|
|
557
571
|
this.#cache.set(cacheKey, results);
|
|
558
572
|
return results;
|
|
559
573
|
}
|
|
560
574
|
catch (e) {
|
|
561
575
|
if (e instanceof ChainHeadBlockPrunedError && shouldRetryOnPrunedBlock) {
|
|
562
|
-
return this.storage(items, childTrie);
|
|
576
|
+
return await this.storage(items, childTrie);
|
|
563
577
|
}
|
|
564
578
|
throw e;
|
|
565
579
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dedot/api",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.4",
|
|
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.9.
|
|
17
|
-
"@dedot/providers": "0.9.
|
|
18
|
-
"@dedot/runtime-specs": "0.9.
|
|
19
|
-
"@dedot/shape": "0.9.
|
|
20
|
-
"@dedot/storage": "0.9.
|
|
21
|
-
"@dedot/types": "0.9.
|
|
22
|
-
"@dedot/utils": "0.9.
|
|
16
|
+
"@dedot/codecs": "0.9.4",
|
|
17
|
+
"@dedot/providers": "0.9.4",
|
|
18
|
+
"@dedot/runtime-specs": "0.9.4",
|
|
19
|
+
"@dedot/shape": "0.9.4",
|
|
20
|
+
"@dedot/storage": "0.9.4",
|
|
21
|
+
"@dedot/types": "0.9.4",
|
|
22
|
+
"@dedot/utils": "0.9.4"
|
|
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": "
|
|
51
|
+
"gitHead": "1deabbf35425a688e76f1612210bcda3f7bedba3",
|
|
52
52
|
"module": "./index.js",
|
|
53
53
|
"types": "./index.d.ts"
|
|
54
54
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { AsyncQueue } from '@dedot/utils';
|
|
1
2
|
import { BaseStorageQuery } from './BaseStorageQuery.js';
|
|
2
3
|
/**
|
|
3
4
|
* @name NewStorageQuery
|
|
@@ -48,6 +49,11 @@ export class NewStorageQuery extends BaseStorageQuery {
|
|
|
48
49
|
const best = await this.client.chainHead.bestBlock();
|
|
49
50
|
// Track the latest changes for each key
|
|
50
51
|
const latestChanges = {};
|
|
52
|
+
// Using a queue here to make sure we don't accidentally
|
|
53
|
+
// put a pressure the json-rpc server in-case new blocks stack up too fast
|
|
54
|
+
// in case we send a lot of requests at the same time
|
|
55
|
+
// or the block time is small enough with elastic scaling
|
|
56
|
+
const pullQueue = new AsyncQueue();
|
|
51
57
|
// Function to pull storage values and call the callback if there are changes
|
|
52
58
|
const pull = async ({ hash }) => {
|
|
53
59
|
// Query storage using ChainHead API
|
|
@@ -73,9 +79,12 @@ export class NewStorageQuery extends BaseStorageQuery {
|
|
|
73
79
|
// Initial pull
|
|
74
80
|
await pull(best);
|
|
75
81
|
// Subscribe to best block events
|
|
76
|
-
const unsub = this.client.on('bestBlock',
|
|
82
|
+
const unsub = this.client.on('bestBlock', (block) => {
|
|
83
|
+
pullQueue.enqueue(() => pull(block)).catch(console.error);
|
|
84
|
+
});
|
|
77
85
|
return async () => {
|
|
78
86
|
unsub();
|
|
87
|
+
pullQueue.cancel();
|
|
79
88
|
};
|
|
80
89
|
}
|
|
81
90
|
}
|