@pezkuwi/rpc-core 16.5.5 → 16.5.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (152) hide show
  1. package/LICENSE +201 -0
  2. package/build/LICENSE +201 -0
  3. package/build/README.md +3 -0
  4. package/build/bundle.d.ts +1 -1
  5. package/build/bundle.js +411 -0
  6. package/build/cjs/bundle.d.ts +91 -0
  7. package/build/cjs/bundle.js +417 -0
  8. package/build/cjs/index.d.ts +2 -0
  9. package/build/cjs/index.js +5 -0
  10. package/build/cjs/package.json +3 -0
  11. package/build/cjs/packageDetect.d.ts +1 -0
  12. package/build/cjs/packageDetect.js +7 -0
  13. package/build/cjs/packageInfo.d.ts +6 -0
  14. package/build/cjs/packageInfo.js +4 -0
  15. package/build/cjs/types/base.d.ts +22 -0
  16. package/build/cjs/types/base.js +2 -0
  17. package/build/cjs/types/index.d.ts +2 -0
  18. package/build/cjs/types/index.js +5 -0
  19. package/build/cjs/types/jsonrpc.d.ts +2 -0
  20. package/build/cjs/types/jsonrpc.js +2 -0
  21. package/build/cjs/util/drr.d.ts +15 -0
  22. package/build/cjs/util/drr.js +31 -0
  23. package/build/cjs/util/index.d.ts +3 -0
  24. package/build/cjs/util/index.js +6 -0
  25. package/build/cjs/util/memo.d.ts +6 -0
  26. package/build/cjs/util/memo.js +18 -0
  27. package/build/cjs/util/refCountDelay.d.ts +3 -0
  28. package/build/cjs/util/refCountDelay.js +40 -0
  29. package/build/index.js +2 -0
  30. package/build/package.json +209 -0
  31. package/build/packageDetect.js +5 -0
  32. package/build/packageInfo.js +1 -0
  33. package/build/types/base.js +1 -0
  34. package/build/types/index.js +2 -0
  35. package/build/types/jsonrpc.js +1 -0
  36. package/build/util/drr.js +28 -0
  37. package/build/util/index.js +3 -0
  38. package/build/util/memo.js +15 -0
  39. package/build/util/refCountDelay.js +37 -0
  40. package/build-deno/README.md +3 -0
  41. package/build-deno/bundle.ts +532 -0
  42. package/build-deno/checkTypes.manual.ts +2 -0
  43. package/build-deno/index.ts +4 -0
  44. package/build-deno/mod.ts +2 -0
  45. package/build-deno/packageDetect.ts +9 -0
  46. package/build-deno/packageInfo.ts +3 -0
  47. package/build-deno/types/base.ts +26 -0
  48. package/build-deno/types/index.ts +4 -0
  49. package/build-deno/types/jsonrpc.ts +4 -0
  50. package/build-deno/util/drr.ts +50 -0
  51. package/build-deno/util/index.ts +4 -0
  52. package/build-deno/util/memo.ts +30 -0
  53. package/build-deno/util/refCountDelay.ts +43 -0
  54. package/build-tsc/bundle.d.ts +91 -0
  55. package/build-tsc/index.d.ts +2 -0
  56. package/build-tsc/packageDetect.d.ts +1 -0
  57. package/build-tsc/packageInfo.d.ts +6 -0
  58. package/build-tsc/types/base.d.ts +22 -0
  59. package/build-tsc/types/index.d.ts +2 -0
  60. package/build-tsc/types/jsonrpc.d.ts +2 -0
  61. package/build-tsc/util/drr.d.ts +15 -0
  62. package/build-tsc/util/index.d.ts +3 -0
  63. package/build-tsc/util/memo.d.ts +6 -0
  64. package/build-tsc/util/refCountDelay.d.ts +3 -0
  65. package/build-tsc-cjs/bundle.js +417 -0
  66. package/build-tsc-cjs/index.js +5 -0
  67. package/build-tsc-cjs/packageDetect.js +7 -0
  68. package/build-tsc-cjs/packageInfo.js +4 -0
  69. package/build-tsc-cjs/types/base.js +2 -0
  70. package/build-tsc-cjs/types/index.js +5 -0
  71. package/build-tsc-cjs/types/jsonrpc.js +2 -0
  72. package/build-tsc-cjs/util/drr.js +31 -0
  73. package/build-tsc-cjs/util/index.js +6 -0
  74. package/build-tsc-cjs/util/memo.js +18 -0
  75. package/build-tsc-cjs/util/refCountDelay.js +40 -0
  76. package/build-tsc-esm/bundle.js +411 -0
  77. package/build-tsc-esm/index.js +2 -0
  78. package/build-tsc-esm/packageDetect.js +5 -0
  79. package/build-tsc-esm/packageInfo.js +1 -0
  80. package/build-tsc-esm/types/base.js +1 -0
  81. package/build-tsc-esm/types/index.js +2 -0
  82. package/build-tsc-esm/types/jsonrpc.js +1 -0
  83. package/build-tsc-esm/util/drr.js +28 -0
  84. package/build-tsc-esm/util/index.js +3 -0
  85. package/build-tsc-esm/util/memo.js +15 -0
  86. package/build-tsc-esm/util/refCountDelay.js +37 -0
  87. package/bundle.d.ts +91 -0
  88. package/bundle.js +411 -0
  89. package/cjs/bundle.d.ts +91 -0
  90. package/cjs/bundle.js +417 -0
  91. package/cjs/index.d.ts +2 -0
  92. package/cjs/index.js +5 -0
  93. package/cjs/package.json +3 -0
  94. package/cjs/packageDetect.d.ts +1 -0
  95. package/cjs/packageDetect.js +7 -0
  96. package/cjs/packageInfo.d.ts +6 -0
  97. package/cjs/packageInfo.js +4 -0
  98. package/cjs/types/base.d.ts +22 -0
  99. package/cjs/types/base.js +2 -0
  100. package/cjs/types/index.d.ts +2 -0
  101. package/cjs/types/index.js +5 -0
  102. package/cjs/types/jsonrpc.d.ts +2 -0
  103. package/cjs/types/jsonrpc.js +2 -0
  104. package/cjs/util/drr.d.ts +15 -0
  105. package/cjs/util/drr.js +31 -0
  106. package/cjs/util/index.d.ts +3 -0
  107. package/cjs/util/index.js +6 -0
  108. package/cjs/util/memo.d.ts +6 -0
  109. package/cjs/util/memo.js +18 -0
  110. package/cjs/util/refCountDelay.d.ts +3 -0
  111. package/cjs/util/refCountDelay.js +40 -0
  112. package/index.d.ts +2 -0
  113. package/index.js +2 -0
  114. package/package.json +186 -12
  115. package/packageDetect.d.ts +1 -0
  116. package/packageDetect.js +5 -0
  117. package/packageInfo.d.ts +6 -0
  118. package/packageInfo.js +1 -0
  119. package/src/bundle.ts +2 -2
  120. package/src/cached.spec.ts +1 -1
  121. package/src/checkTypes.manual.ts +1 -1
  122. package/src/index.spec.ts +1 -1
  123. package/src/index.ts +1 -1
  124. package/src/methodSend.spec.ts +1 -1
  125. package/src/mod.ts +1 -1
  126. package/src/packageDetect.ts +2 -2
  127. package/src/packageInfo.ts +3 -3
  128. package/src/replay.spec.ts +1 -1
  129. package/src/types/base.ts +1 -1
  130. package/src/types/index.ts +1 -1
  131. package/src/types/jsonrpc.ts +1 -1
  132. package/src/util/drr.spec.ts +1 -1
  133. package/src/util/drr.ts +1 -1
  134. package/src/util/index.ts +1 -1
  135. package/src/util/memo.ts +1 -1
  136. package/src/util/refCountDelay.ts +1 -1
  137. package/tsconfig.build.tsbuildinfo +1 -1
  138. package/tsconfig.spec.tsbuildinfo +1 -0
  139. package/types/base.d.ts +22 -0
  140. package/types/base.js +1 -0
  141. package/types/index.d.ts +2 -0
  142. package/types/index.js +2 -0
  143. package/types/jsonrpc.d.ts +2 -0
  144. package/types/jsonrpc.js +1 -0
  145. package/util/drr.d.ts +15 -0
  146. package/util/drr.js +28 -0
  147. package/util/index.d.ts +3 -0
  148. package/util/index.js +3 -0
  149. package/util/memo.d.ts +6 -0
  150. package/util/memo.js +15 -0
  151. package/util/refCountDelay.d.ts +3 -0
  152. package/util/refCountDelay.js +37 -0
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.drr = drr;
4
+ const rxjs_1 = require("rxjs");
5
+ const util_1 = require("@pezkuwi/util");
6
+ const refCountDelay_js_1 = require("./refCountDelay.js");
7
+ function CMP(a, b) {
8
+ return (0, util_1.stringify)({ t: a }) === (0, util_1.stringify)({ t: b });
9
+ }
10
+ function ERR(error) {
11
+ throw error;
12
+ }
13
+ function NOOP() {
14
+ // empty
15
+ }
16
+ /**
17
+ * Shorthand for distinctUntilChanged(), publishReplay(1) and refCount().
18
+ *
19
+ * @ignore
20
+ * @internal
21
+ */
22
+ function drr({ delay, skipChange = false, skipTimeout = false } = {}) {
23
+ return (source$) => source$.pipe((0, rxjs_1.catchError)(ERR), skipChange
24
+ ? (0, rxjs_1.tap)(NOOP)
25
+ : (0, rxjs_1.distinctUntilChanged)(CMP),
26
+ // eslint-disable-next-line deprecation/deprecation
27
+ (0, rxjs_1.publishReplay)(1), skipTimeout
28
+ // eslint-disable-next-line deprecation/deprecation
29
+ ? (0, rxjs_1.refCount)()
30
+ : (0, refCountDelay_js_1.refCountDelay)(delay));
31
+ }
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ tslib_1.__exportStar(require("./drr.js"), exports);
5
+ tslib_1.__exportStar(require("./memo.js"), exports);
6
+ tslib_1.__exportStar(require("./refCountDelay.js"), exports);
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.memo = memo;
4
+ const rxjs_1 = require("rxjs");
5
+ const util_1 = require("@pezkuwi/util");
6
+ const drr_js_1 = require("./drr.js");
7
+ /** @internal */
8
+ function memo(instanceId, inner) {
9
+ const options = { getInstanceId: () => instanceId };
10
+ const cached = (0, util_1.memoize)((...params) => new rxjs_1.Observable((observer) => {
11
+ const subscription = inner(...params).subscribe(observer);
12
+ return () => {
13
+ cached.unmemoize(...params);
14
+ subscription.unsubscribe();
15
+ };
16
+ }).pipe((0, drr_js_1.drr)()), options);
17
+ return cached;
18
+ }
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.refCountDelay = refCountDelay;
4
+ const rxjs_1 = require("rxjs");
5
+ /** @internal */
6
+ function refCountDelay(delay = 1750) {
7
+ return (source) => {
8
+ // state: 0 = disconnected, 1 = disconnecting, 2 = connecting, 3 = connected
9
+ let [state, refCount, connection, scheduler] = [0, 0, rxjs_1.Subscription.EMPTY, rxjs_1.Subscription.EMPTY];
10
+ return new rxjs_1.Observable((ob) => {
11
+ source.subscribe(ob);
12
+ if (refCount++ === 0) {
13
+ if (state === 1) {
14
+ scheduler.unsubscribe();
15
+ }
16
+ else {
17
+ // eslint-disable-next-line deprecation/deprecation
18
+ connection = source.connect();
19
+ }
20
+ state = 3;
21
+ }
22
+ return () => {
23
+ if (--refCount === 0) {
24
+ if (state === 2) {
25
+ state = 0;
26
+ scheduler.unsubscribe();
27
+ }
28
+ else {
29
+ // state === 3
30
+ state = 1;
31
+ scheduler = rxjs_1.asapScheduler.schedule(() => {
32
+ state = 0;
33
+ connection.unsubscribe();
34
+ }, delay);
35
+ }
36
+ }
37
+ };
38
+ });
39
+ };
40
+ }
@@ -0,0 +1,411 @@
1
+ import { Observable, publishReplay, refCount } from 'rxjs';
2
+ import { LRUCache } from '@pezkuwi/rpc-provider';
3
+ import { rpcDefinitions } from '@pezkuwi/types';
4
+ import { unwrapStorageSi } from '@pezkuwi/types/util';
5
+ import { hexToU8a, isFunction, isNull, isUndefined, lazyMethod, logger, memoize, objectSpread, u8aConcat, u8aToU8a } from '@pezkuwi/util';
6
+ import { drr, refCountDelay } from './util/index.js';
7
+ export { packageInfo } from './packageInfo.js';
8
+ export * from './util/index.js';
9
+ const l = logger('rpc-core');
10
+ const EMPTY_META = {
11
+ fallback: undefined,
12
+ modifier: { isOptional: true },
13
+ type: {
14
+ asMap: { linked: { isTrue: false } },
15
+ isMap: false
16
+ }
17
+ };
18
+ const RPC_CORE_DEFAULT_CAPACITY = 1024 * 10 * 10;
19
+ /** @internal */
20
+ function logErrorMessage(method, { noErrorLog, params, type }, error) {
21
+ if (noErrorLog) {
22
+ return;
23
+ }
24
+ l.error(`${method}(${params.map(({ isOptional, name, type }) => `${name}${isOptional ? '?' : ''}: ${type}`).join(', ')}): ${type}:: ${error.message}`);
25
+ }
26
+ function isTreatAsHex(key) {
27
+ // :code is problematic - it does not have the length attached, which is
28
+ // unlike all other storage entries where it is indeed properly encoded
29
+ return ['0x3a636f6465'].includes(key.toHex());
30
+ }
31
+ /**
32
+ * @name Rpc
33
+ * @summary The API may use a HTTP or WebSockets provider.
34
+ * @description It allows for querying a Pezkuwi Client Node.
35
+ * WebSockets provider is recommended since HTTP provider only supports basic querying.
36
+ *
37
+ * ```mermaid
38
+ * graph LR;
39
+ * A[Api] --> |WebSockets| B[WsProvider];
40
+ * B --> |endpoint| C[ws://127.0.0.1:9944]
41
+ * ```
42
+ *
43
+ * @example
44
+ * <BR>
45
+ *
46
+ * ```javascript
47
+ * import Rpc from '@pezkuwi/rpc-core';
48
+ * import { WsProvider } from '@pezkuwi/rpc-provider/ws';
49
+ *
50
+ * const provider = new WsProvider('ws://127.0.0.1:9944');
51
+ * const rpc = new Rpc(provider);
52
+ * ```
53
+ */
54
+ export class RpcCore {
55
+ #instanceId;
56
+ #isPedantic;
57
+ #registryDefault;
58
+ #storageCache;
59
+ #storageCacheHits = 0;
60
+ #getBlockRegistry;
61
+ #getBlockHash;
62
+ mapping = new Map();
63
+ provider;
64
+ sections = [];
65
+ /**
66
+ * @constructor
67
+ * Default constructor for the core RPC handler
68
+ * @param {Registry} registry Type Registry
69
+ * @param {ProviderInterface} options.provider An API provider using any of the supported providers (HTTP, SC or WebSocket)
70
+ * @param {number} [options.rpcCacheCapacity] Custom size of the rpc LRUCache capacity. Defaults to `RPC_CORE_DEFAULT_CAPACITY` (1024 * 10 * 10)
71
+ */
72
+ constructor(instanceId, registry, { isPedantic = true, provider, rpcCacheCapacity, ttl, userRpc = {} }) {
73
+ if (!provider || !isFunction(provider.send)) {
74
+ throw new Error('Expected Provider to API create');
75
+ }
76
+ this.#instanceId = instanceId;
77
+ this.#isPedantic = isPedantic;
78
+ this.#registryDefault = registry;
79
+ this.provider = provider;
80
+ const sectionNames = Object.keys(rpcDefinitions);
81
+ // these are the base keys (i.e. part of jsonrpc)
82
+ this.sections.push(...sectionNames);
83
+ this.#storageCache = new LRUCache(rpcCacheCapacity || RPC_CORE_DEFAULT_CAPACITY, ttl);
84
+ // decorate all interfaces, defined and user on this instance
85
+ this.addUserInterfaces(userRpc);
86
+ }
87
+ /**
88
+ * @description Returns the connected status of a provider
89
+ */
90
+ get isConnected() {
91
+ return this.provider.isConnected;
92
+ }
93
+ /**
94
+ * @description Manually connect from the attached provider
95
+ */
96
+ connect() {
97
+ return this.provider.connect();
98
+ }
99
+ /**
100
+ * @description Manually disconnect from the attached provider
101
+ */
102
+ async disconnect() {
103
+ return this.provider.disconnect();
104
+ }
105
+ /**
106
+ * @description Returns the underlying core stats, including those from teh provider
107
+ */
108
+ get stats() {
109
+ const stats = this.provider.stats;
110
+ return stats
111
+ ? {
112
+ ...stats,
113
+ core: {
114
+ cacheHits: this.#storageCacheHits,
115
+ cacheSize: this.#storageCache.length
116
+ }
117
+ }
118
+ : undefined;
119
+ }
120
+ /**
121
+ * @description Sets a registry swap (typically from Api)
122
+ */
123
+ setRegistrySwap(registrySwap) {
124
+ this.#getBlockRegistry = memoize(registrySwap, {
125
+ getInstanceId: () => this.#instanceId
126
+ });
127
+ }
128
+ /**
129
+ * @description Sets a function to resolve block hash from block number
130
+ */
131
+ setResolveBlockHash(resolveBlockHash) {
132
+ this.#getBlockHash = memoize(resolveBlockHash, {
133
+ getInstanceId: () => this.#instanceId
134
+ });
135
+ }
136
+ addUserInterfaces(userRpc) {
137
+ // add any extra user-defined sections
138
+ this.sections.push(...Object.keys(userRpc).filter((k) => !this.sections.includes(k)));
139
+ for (let s = 0, scount = this.sections.length; s < scount; s++) {
140
+ const section = this.sections[s];
141
+ const defs = objectSpread({}, rpcDefinitions[section], userRpc[section]);
142
+ const methods = Object.keys(defs);
143
+ for (let m = 0, mcount = methods.length; m < mcount; m++) {
144
+ const method = methods[m];
145
+ const def = defs[method];
146
+ const jsonrpc = def.endpoint || `${section}_${method}`;
147
+ if (!this.mapping.has(jsonrpc)) {
148
+ const isSubscription = !!def.pubsub;
149
+ if (!this[section]) {
150
+ this[section] = {};
151
+ }
152
+ this.mapping.set(jsonrpc, objectSpread({}, def, { isSubscription, jsonrpc, method, section }));
153
+ lazyMethod(this[section], method, () => isSubscription
154
+ ? this._createMethodSubscribe(section, method, def)
155
+ : this._createMethodSend(section, method, def));
156
+ }
157
+ }
158
+ }
159
+ }
160
+ _memomize(creator, def) {
161
+ const memoOpts = { getInstanceId: () => this.#instanceId };
162
+ const memoized = memoize(creator(true), memoOpts);
163
+ memoized.raw = memoize(creator(false), memoOpts);
164
+ memoized.meta = def;
165
+ return memoized;
166
+ }
167
+ _formatResult(isScale, registry, blockHash, method, def, params, result) {
168
+ return isScale
169
+ ? this._formatOutput(registry, blockHash, method, def, params, result)
170
+ : result;
171
+ }
172
+ _createMethodSend(section, method, def) {
173
+ const rpcName = def.endpoint || `${section}_${method}`;
174
+ const hashIndex = def.params.findIndex(({ isHistoric }) => isHistoric);
175
+ let memoized = null;
176
+ // execute the RPC call, doing a registry swap for historic as applicable
177
+ const callWithRegistry = async (isScale, values) => {
178
+ const blockId = hashIndex === -1
179
+ ? null
180
+ : values[hashIndex];
181
+ const blockHash = blockId && def.params[hashIndex].type === 'BlockNumber'
182
+ ? await this.#getBlockHash?.(blockId)
183
+ : blockId;
184
+ const { registry } = isScale && blockHash && this.#getBlockRegistry
185
+ ? await this.#getBlockRegistry(u8aToU8a(blockHash))
186
+ : { registry: this.#registryDefault };
187
+ const params = this._formatParams(registry, null, def, values);
188
+ // only cache .at(<blockHash>) queries, e.g. where valid blockHash was supplied
189
+ const result = await this.provider.send(rpcName, params.map((p) => p.toJSON()), !!blockHash);
190
+ return this._formatResult(isScale, registry, blockHash, method, def, params, result);
191
+ };
192
+ const creator = (isScale) => (...values) => {
193
+ const isDelayed = isScale && hashIndex !== -1 && !!values[hashIndex];
194
+ return new Observable((observer) => {
195
+ callWithRegistry(isScale, values)
196
+ .then((value) => {
197
+ observer.next(value);
198
+ observer.complete();
199
+ })
200
+ .catch((error) => {
201
+ logErrorMessage(method, def, error);
202
+ observer.error(error);
203
+ observer.complete();
204
+ });
205
+ return () => {
206
+ // delete old results from cache
207
+ if (isScale) {
208
+ memoized?.unmemoize(...values);
209
+ }
210
+ else {
211
+ memoized?.raw.unmemoize(...values);
212
+ }
213
+ };
214
+ }).pipe(
215
+ // eslint-disable-next-line deprecation/deprecation
216
+ publishReplay(1), // create a Replay(1)
217
+ isDelayed
218
+ ? refCountDelay() // Unsubscribe after delay
219
+ // eslint-disable-next-line deprecation/deprecation
220
+ : refCount());
221
+ };
222
+ memoized = this._memomize(creator, def);
223
+ return memoized;
224
+ }
225
+ // create a subscriptor, it subscribes once and resolves with the id as subscribe
226
+ _createSubscriber({ paramsJson, subName, subType, update }, errorHandler) {
227
+ return new Promise((resolve, reject) => {
228
+ this.provider
229
+ .subscribe(subType, subName, paramsJson, update)
230
+ .then(resolve)
231
+ .catch((error) => {
232
+ errorHandler(error);
233
+ reject(error);
234
+ });
235
+ });
236
+ }
237
+ _createMethodSubscribe(section, method, def) {
238
+ const [updateType, subMethod, unsubMethod] = def.pubsub;
239
+ const subName = `${section}_${subMethod}`;
240
+ const unsubName = `${section}_${unsubMethod}`;
241
+ const subType = `${section}_${updateType}`;
242
+ let memoized = null;
243
+ const creator = (isScale) => (...values) => {
244
+ return new Observable((observer) => {
245
+ // Have at least an empty promise, as used in the unsubscribe
246
+ let subscriptionPromise = Promise.resolve(null);
247
+ const registry = this.#registryDefault;
248
+ const errorHandler = (error) => {
249
+ logErrorMessage(method, def, error);
250
+ observer.error(error);
251
+ };
252
+ try {
253
+ const params = this._formatParams(registry, null, def, values);
254
+ const update = (error, result) => {
255
+ if (error) {
256
+ logErrorMessage(method, def, error);
257
+ return;
258
+ }
259
+ try {
260
+ observer.next(this._formatResult(isScale, registry, null, method, def, params, result));
261
+ }
262
+ catch (error) {
263
+ observer.error(error);
264
+ }
265
+ };
266
+ subscriptionPromise = this._createSubscriber({ paramsJson: params.map((p) => p.toJSON()), subName, subType, update }, errorHandler);
267
+ }
268
+ catch (error) {
269
+ errorHandler(error);
270
+ }
271
+ // Teardown logic
272
+ return () => {
273
+ // Delete from cache, so old results don't hang around
274
+ if (isScale) {
275
+ memoized?.unmemoize(...values);
276
+ }
277
+ else {
278
+ memoized?.raw.unmemoize(...values);
279
+ }
280
+ // Unsubscribe from provider
281
+ subscriptionPromise
282
+ .then((subscriptionId) => isNull(subscriptionId)
283
+ ? Promise.resolve(false)
284
+ : this.provider.unsubscribe(subType, unsubName, subscriptionId))
285
+ .catch((error) => logErrorMessage(method, def, error));
286
+ };
287
+ }).pipe(drr());
288
+ };
289
+ memoized = this._memomize(creator, def);
290
+ return memoized;
291
+ }
292
+ _formatParams(registry, blockHash, def, inputs) {
293
+ const count = inputs.length;
294
+ const reqCount = def.params.filter(({ isOptional }) => !isOptional).length;
295
+ if (count < reqCount || count > def.params.length) {
296
+ throw new Error(`Expected ${def.params.length} parameters${reqCount === def.params.length ? '' : ` (${def.params.length - reqCount} optional)`}, ${count} found instead`);
297
+ }
298
+ const params = new Array(count);
299
+ for (let i = 0; i < count; i++) {
300
+ params[i] = registry.createTypeUnsafe(def.params[i].type, [inputs[i]], { blockHash });
301
+ }
302
+ return params;
303
+ }
304
+ _formatOutput(registry, blockHash, method, rpc, params, result) {
305
+ if (rpc.type === 'StorageData') {
306
+ const key = params[0];
307
+ return this._formatStorageData(registry, blockHash, key, result);
308
+ }
309
+ else if (rpc.type === 'StorageChangeSet') {
310
+ const keys = params[0];
311
+ return keys
312
+ ? this._formatStorageSet(registry, result.block, keys, result.changes)
313
+ : registry.createType('StorageChangeSet', result);
314
+ }
315
+ else if (rpc.type === 'Vec<StorageChangeSet>') {
316
+ const jsonSet = result;
317
+ const count = jsonSet.length;
318
+ const mapped = new Array(count);
319
+ for (let i = 0; i < count; i++) {
320
+ const { block, changes } = jsonSet[i];
321
+ mapped[i] = [
322
+ registry.createType('BlockHash', block),
323
+ this._formatStorageSet(registry, block, params[0], changes)
324
+ ];
325
+ }
326
+ // we only query at a specific block, not a range - flatten
327
+ return method === 'queryStorageAt'
328
+ ? mapped[0][1]
329
+ : mapped;
330
+ }
331
+ return registry.createTypeUnsafe(rpc.type, [result], { blockHash });
332
+ }
333
+ _formatStorageData(registry, blockHash, key, value) {
334
+ const isEmpty = isNull(value);
335
+ // we convert to Uint8Array since it maps to the raw encoding, all
336
+ // data will be correctly encoded (incl. numbers, excl. :code)
337
+ const input = isEmpty
338
+ ? null
339
+ : isTreatAsHex(key)
340
+ ? value
341
+ : u8aToU8a(value);
342
+ return this._newType(registry, blockHash, key, input, isEmpty);
343
+ }
344
+ _formatStorageSet(registry, blockHash, keys, changes) {
345
+ // For StorageChangeSet, the changes has the [key, value] mappings
346
+ const count = keys.length;
347
+ const withCache = count !== 1;
348
+ const values = new Array(count);
349
+ // multiple return values (via state.storage subscription), decode the
350
+ // values one at a time, all based on the supplied query types
351
+ for (let i = 0; i < count; i++) {
352
+ values[i] = this._formatStorageSetEntry(registry, blockHash, keys[i], changes, withCache, i);
353
+ }
354
+ return values;
355
+ }
356
+ _formatStorageSetEntry(registry, blockHash, key, changes, withCache, entryIndex) {
357
+ const hexKey = key.toHex();
358
+ const found = changes.find(([key]) => key === hexKey);
359
+ const isNotFound = isUndefined(found);
360
+ // if we don't find the value, this is our fallback
361
+ // - in the case of an array of values, fill the hole from the cache
362
+ // - if a single result value, don't fill - it is not an update hole
363
+ // - fallback to an empty option in all cases
364
+ if (isNotFound && withCache) {
365
+ const cached = this.#storageCache.get(hexKey);
366
+ if (cached) {
367
+ this.#storageCacheHits++;
368
+ return cached;
369
+ }
370
+ }
371
+ const value = isNotFound
372
+ ? null
373
+ : found[1];
374
+ const isEmpty = isNull(value);
375
+ const input = isEmpty || isTreatAsHex(key)
376
+ ? value
377
+ : u8aToU8a(value);
378
+ const codec = this._newType(registry, blockHash, key, input, isEmpty, entryIndex);
379
+ this._setToCache(hexKey, codec);
380
+ return codec;
381
+ }
382
+ _setToCache(key, value) {
383
+ this.#storageCache.set(key, value);
384
+ }
385
+ _newType(registry, blockHash, key, input, isEmpty, entryIndex = -1) {
386
+ // single return value (via state.getStorage), decode the value based on the
387
+ // outputType that we have specified. Fallback to Raw on nothing
388
+ const type = key.meta ? registry.createLookupType(unwrapStorageSi(key.meta.type)) : (key.outputType || 'Raw');
389
+ const meta = key.meta || EMPTY_META;
390
+ const entryNum = entryIndex === -1
391
+ ? ''
392
+ : ` entry ${entryIndex}:`;
393
+ try {
394
+ return registry.createTypeUnsafe(type, [
395
+ isEmpty
396
+ ? meta.fallback
397
+ // For old-style Linkage, we add an empty linkage at the end
398
+ ? type.includes('Linkage<')
399
+ ? u8aConcat(hexToU8a(meta.fallback.toHex()), new Uint8Array(2))
400
+ : hexToU8a(meta.fallback.toHex())
401
+ : undefined
402
+ : meta.modifier.isOptional
403
+ ? registry.createTypeUnsafe(type, [input], { blockHash, isPedantic: this.#isPedantic })
404
+ : input
405
+ ], { blockHash, isFallback: isEmpty && !!meta.fallback, isOptional: meta.modifier.isOptional, isPedantic: this.#isPedantic && !meta.modifier.isOptional });
406
+ }
407
+ catch (error) {
408
+ throw new Error(`Unable to decode storage ${key.section || 'unknown'}.${key.method || 'unknown'}:${entryNum}: ${error.message}`);
409
+ }
410
+ }
411
+ }
@@ -0,0 +1,2 @@
1
+ import './packageDetect.js';
2
+ export * from './bundle.js';
@@ -0,0 +1,5 @@
1
+ import { packageInfo as providerInfo } from '@pezkuwi/rpc-provider/packageInfo';
2
+ import { packageInfo as typesInfo } from '@pezkuwi/types/packageInfo';
3
+ import { detectPackage } from '@pezkuwi/util';
4
+ import { packageInfo } from './packageInfo.js';
5
+ detectPackage(packageInfo, null, [providerInfo, typesInfo]);
@@ -0,0 +1 @@
1
+ export const packageInfo = { name: '@pezkuwi/rpc-core', path: (import.meta && import.meta.url) ? new URL(import.meta.url).pathname.substring(0, new URL(import.meta.url).pathname.lastIndexOf('/') + 1) : 'auto', type: 'esm', version: '16.5.8' };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ export * from '@pezkuwi/rpc-core/types/jsonrpc';
2
+ export * from './base.js';
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,28 @@
1
+ import { catchError, distinctUntilChanged, publishReplay, refCount, tap } from 'rxjs';
2
+ import { stringify } from '@pezkuwi/util';
3
+ import { refCountDelay } from './refCountDelay.js';
4
+ function CMP(a, b) {
5
+ return stringify({ t: a }) === stringify({ t: b });
6
+ }
7
+ function ERR(error) {
8
+ throw error;
9
+ }
10
+ function NOOP() {
11
+ // empty
12
+ }
13
+ /**
14
+ * Shorthand for distinctUntilChanged(), publishReplay(1) and refCount().
15
+ *
16
+ * @ignore
17
+ * @internal
18
+ */
19
+ export function drr({ delay, skipChange = false, skipTimeout = false } = {}) {
20
+ return (source$) => source$.pipe(catchError(ERR), skipChange
21
+ ? tap(NOOP)
22
+ : distinctUntilChanged(CMP),
23
+ // eslint-disable-next-line deprecation/deprecation
24
+ publishReplay(1), skipTimeout
25
+ // eslint-disable-next-line deprecation/deprecation
26
+ ? refCount()
27
+ : refCountDelay(delay));
28
+ }
@@ -0,0 +1,3 @@
1
+ export * from './drr.js';
2
+ export * from './memo.js';
3
+ export * from './refCountDelay.js';
@@ -0,0 +1,15 @@
1
+ import { Observable } from 'rxjs';
2
+ import { memoize } from '@pezkuwi/util';
3
+ import { drr } from './drr.js';
4
+ /** @internal */
5
+ export function memo(instanceId, inner) {
6
+ const options = { getInstanceId: () => instanceId };
7
+ const cached = memoize((...params) => new Observable((observer) => {
8
+ const subscription = inner(...params).subscribe(observer);
9
+ return () => {
10
+ cached.unmemoize(...params);
11
+ subscription.unsubscribe();
12
+ };
13
+ }).pipe(drr()), options);
14
+ return cached;
15
+ }
@@ -0,0 +1,37 @@
1
+ import { asapScheduler, Observable, Subscription } from 'rxjs';
2
+ /** @internal */
3
+ export function refCountDelay(delay = 1750) {
4
+ return (source) => {
5
+ // state: 0 = disconnected, 1 = disconnecting, 2 = connecting, 3 = connected
6
+ let [state, refCount, connection, scheduler] = [0, 0, Subscription.EMPTY, Subscription.EMPTY];
7
+ return new Observable((ob) => {
8
+ source.subscribe(ob);
9
+ if (refCount++ === 0) {
10
+ if (state === 1) {
11
+ scheduler.unsubscribe();
12
+ }
13
+ else {
14
+ // eslint-disable-next-line deprecation/deprecation
15
+ connection = source.connect();
16
+ }
17
+ state = 3;
18
+ }
19
+ return () => {
20
+ if (--refCount === 0) {
21
+ if (state === 2) {
22
+ state = 0;
23
+ scheduler.unsubscribe();
24
+ }
25
+ else {
26
+ // state === 3
27
+ state = 1;
28
+ scheduler = asapScheduler.schedule(() => {
29
+ state = 0;
30
+ connection.unsubscribe();
31
+ }, delay);
32
+ }
33
+ }
34
+ };
35
+ });
36
+ };
37
+ }