1 |
|
2 |
|
3 | import { BehaviorSubject, combineLatest, from, map, of, switchMap, tap, toArray } from 'rxjs';
|
4 | import { getAvailableDerives } from '@polkadot/api-derive';
|
5 | import { memo, RpcCore } from '@polkadot/rpc-core';
|
6 | import { WsProvider } from '@polkadot/rpc-provider';
|
7 | import { expandMetadata, TypeRegistry, unwrapStorageType } from '@polkadot/types';
|
8 | import { arrayChunk, arrayFlatten, assert, assertReturn, BN, compactStripLength, lazyMethod, lazyMethods, logger, nextTick, objectSpread, u8aToHex } from '@polkadot/util';
|
9 | import { createSubmittable } from "../submittable/index.js";
|
10 | import { augmentObject } from "../util/augmentObject.js";
|
11 | import { decorateDeriveSections } from "../util/decorate.js";
|
12 | import { extractStorageArgs } from "../util/validate.js";
|
13 | import { Events } from "./Events.js";
|
14 | import { findCall, findError } from "./find.js";
|
15 |
|
16 | const PAGE_SIZE_K = 1000;
|
17 |
|
18 | const PAGE_SIZE_V = 250;
|
19 |
|
20 | const PAGE_SIZE_Q = 50;
|
21 |
|
22 | const l = logger('api/init');
|
23 | let instanceCounter = 0;
|
24 |
|
25 | function getAtQueryFn(api, {
|
26 | method,
|
27 | section
|
28 | }) {
|
29 | return assertReturn(api.rx.query[section] && api.rx.query[section][method], () => `query.${section}.${method} is not available in this version of the metadata`);
|
30 | }
|
31 |
|
32 | export class Decorate extends Events {
|
33 | #instanceId;
|
34 | #registry;
|
35 | #storageGetQ = [];
|
36 | #storageSubQ = []; // HACK Use BN import so decorateDerive works... yes, wtf.
|
37 |
|
38 | __phantom = new BN(0);
|
39 | _consts = {};
|
40 | _errors = {};
|
41 | _events = {};
|
42 | _extrinsicType = 4;
|
43 |
|
44 | _isReady = false;
|
45 | _query = {};
|
46 | _rx = {
|
47 | consts: {},
|
48 | query: {},
|
49 | tx: {}
|
50 | };
|
51 |
|
52 | |
53 |
|
54 |
|
55 |
|
56 |
|
57 |
|
58 |
|
59 |
|
60 |
|
61 |
|
62 |
|
63 |
|
64 |
|
65 |
|
66 |
|
67 |
|
68 |
|
69 |
|
70 | constructor(options, type, decorateMethod) {
|
71 | var _options$source;
|
72 |
|
73 | super();
|
74 | this.#instanceId = `${++instanceCounter}`;
|
75 | this.#registry = ((_options$source = options.source) === null || _options$source === void 0 ? void 0 : _options$source.registry) || options.registry || new TypeRegistry();
|
76 |
|
77 | this._rx.queryAt = (blockHash, knownVersion) => from(this.at(blockHash, knownVersion)).pipe(map(a => a.rx.query));
|
78 |
|
79 | this._rx.registry = this.#registry;
|
80 | const thisProvider = options.source ? options.source._rpcCore.provider.clone() : options.provider || new WsProvider();
|
81 | this._decorateMethod = decorateMethod;
|
82 | this._options = options;
|
83 | this._type = type;
|
84 |
|
85 | this._rpcCore = new RpcCore(this.#instanceId, this.#registry, thisProvider, this._options.rpc);
|
86 | this._isConnected = new BehaviorSubject(this._rpcCore.provider.isConnected);
|
87 | this._rx.hasSubscriptions = this._rpcCore.provider.hasSubscriptions;
|
88 | }
|
89 |
|
90 | |
91 |
|
92 |
|
93 | get registry() {
|
94 | return this.#registry;
|
95 | }
|
96 | |
97 |
|
98 |
|
99 |
|
100 |
|
101 | createType(type, ...params) {
|
102 | return this.#registry.createType(type, ...params);
|
103 | }
|
104 | |
105 |
|
106 |
|
107 |
|
108 |
|
109 | registerTypes(types) {
|
110 | types && this.#registry.register(types);
|
111 | }
|
112 | |
113 |
|
114 |
|
115 |
|
116 |
|
117 | get hasSubscriptions() {
|
118 | return this._rpcCore.provider.hasSubscriptions;
|
119 | }
|
120 | |
121 |
|
122 |
|
123 |
|
124 |
|
125 | get supportMulti() {
|
126 | return this._rpcCore.provider.hasSubscriptions || !!this._rpcCore.state.queryStorageAt;
|
127 | }
|
128 |
|
129 | _emptyDecorated(registry, blockHash) {
|
130 | return {
|
131 | consts: {},
|
132 | errors: {},
|
133 | events: {},
|
134 | query: {},
|
135 | registry,
|
136 | rx: {
|
137 | query: {}
|
138 | },
|
139 | tx: createSubmittable(this._type, this._rx, this._decorateMethod, registry, blockHash)
|
140 | };
|
141 | }
|
142 |
|
143 | _createDecorated(registry, fromEmpty, decoratedApi, blockHash) {
|
144 | if (!decoratedApi) {
|
145 | decoratedApi = this._emptyDecorated(registry.registry, blockHash);
|
146 | }
|
147 |
|
148 | if (fromEmpty || !registry.decoratedMeta) {
|
149 | registry.decoratedMeta = expandMetadata(registry.registry, registry.metadata);
|
150 | }
|
151 |
|
152 | const storage = this._decorateStorage(registry.decoratedMeta, this._decorateMethod, blockHash);
|
153 |
|
154 | const storageRx = this._decorateStorage(registry.decoratedMeta, this._rxDecorateMethod, blockHash);
|
155 |
|
156 | augmentObject('consts', registry.decoratedMeta.consts, decoratedApi.consts, fromEmpty);
|
157 | augmentObject('errors', registry.decoratedMeta.errors, decoratedApi.errors, fromEmpty);
|
158 | augmentObject('events', registry.decoratedMeta.events, decoratedApi.events, fromEmpty);
|
159 | augmentObject('query', storage, decoratedApi.query, fromEmpty);
|
160 | augmentObject('query', storageRx, decoratedApi.rx.query, fromEmpty);
|
161 |
|
162 | decoratedApi.findCall = callIndex => findCall(registry.registry, callIndex);
|
163 |
|
164 | decoratedApi.findError = errorIndex => findError(registry.registry, errorIndex);
|
165 |
|
166 | decoratedApi.queryMulti = blockHash ? this._decorateMultiAt(decoratedApi, this._decorateMethod, blockHash) : this._decorateMulti(this._decorateMethod);
|
167 | decoratedApi.runtimeVersion = registry.runtimeVersion;
|
168 | return {
|
169 | decoratedApi,
|
170 | decoratedMeta: registry.decoratedMeta
|
171 | };
|
172 | }
|
173 |
|
174 | _injectMetadata(registry, fromEmpty = false) {
|
175 |
|
176 | if (fromEmpty || !registry.decoratedApi) {
|
177 | registry.decoratedApi = this._emptyDecorated(registry.registry);
|
178 | }
|
179 |
|
180 | const {
|
181 | decoratedApi,
|
182 | decoratedMeta
|
183 | } = this._createDecorated(registry, fromEmpty, registry.decoratedApi);
|
184 |
|
185 | this._consts = decoratedApi.consts;
|
186 | this._errors = decoratedApi.errors;
|
187 | this._events = decoratedApi.events;
|
188 | this._query = decoratedApi.query;
|
189 | this._rx.query = decoratedApi.rx.query;
|
190 |
|
191 | const tx = this._decorateExtrinsics(decoratedMeta, this._decorateMethod);
|
192 |
|
193 | const rxtx = this._decorateExtrinsics(decoratedMeta, this._rxDecorateMethod);
|
194 |
|
195 | if (fromEmpty || !this._extrinsics) {
|
196 | this._extrinsics = tx;
|
197 | this._rx.tx = rxtx;
|
198 | } else {
|
199 | augmentObject('tx', tx, this._extrinsics, false);
|
200 | augmentObject(null, rxtx, this._rx.tx, false);
|
201 | }
|
202 |
|
203 | augmentObject(null, decoratedMeta.consts, this._rx.consts, fromEmpty);
|
204 | this.emit('decorated');
|
205 | }
|
206 | |
207 |
|
208 |
|
209 |
|
210 |
|
211 |
|
212 | injectMetadata(metadata, fromEmpty, registry) {
|
213 | this._injectMetadata({
|
214 | metadata,
|
215 | registry: registry || this.#registry,
|
216 | runtimeVersion: this.#registry.createType('RuntimeVersionPartial')
|
217 | }, fromEmpty);
|
218 | }
|
219 |
|
220 | _decorateFunctionMeta(input, output) {
|
221 | output.meta = input.meta;
|
222 | output.method = input.method;
|
223 | output.section = input.section;
|
224 | output.toJSON = input.toJSON;
|
225 |
|
226 | if (input.callIndex) {
|
227 | output.callIndex = input.callIndex;
|
228 | }
|
229 |
|
230 | return output;
|
231 | }
|
232 |
|
233 |
|
234 |
|
235 |
|
236 |
|
237 | _filterRpc(methods, additional) {
|
238 |
|
239 | if (Object.keys(additional).length !== 0) {
|
240 | this._rpcCore.addUserInterfaces(additional);
|
241 |
|
242 |
|
243 | this._decorateRpc(this._rpcCore, this._decorateMethod, this._rpc);
|
244 |
|
245 | this._decorateRpc(this._rpcCore, this._rxDecorateMethod, this._rx.rpc);
|
246 | }
|
247 |
|
248 | this._filterRpcMethods(methods);
|
249 | }
|
250 |
|
251 | _filterRpcMethods(exposed) {
|
252 | const hasResults = exposed.length !== 0;
|
253 | const allKnown = [...this._rpcCore.mapping.entries()];
|
254 | const allKeys = [];
|
255 |
|
256 | for (let i = 0; i < allKnown.length; i++) {
|
257 | const [, {
|
258 | alias,
|
259 | endpoint,
|
260 | method,
|
261 | pubsub,
|
262 | section
|
263 | }] = allKnown[i];
|
264 | allKeys.push(`${section}_${method}`);
|
265 |
|
266 | if (pubsub) {
|
267 | allKeys.push(`${section}_${pubsub[1]}`);
|
268 | allKeys.push(`${section}_${pubsub[2]}`);
|
269 | }
|
270 |
|
271 | if (alias) {
|
272 | allKeys.push(...alias);
|
273 | }
|
274 |
|
275 | if (endpoint) {
|
276 | allKeys.push(endpoint);
|
277 | }
|
278 | }
|
279 |
|
280 | const filterKey = k => !allKeys.includes(k);
|
281 |
|
282 | const unknown = exposed.filter(filterKey);
|
283 |
|
284 | if (unknown.length) {
|
285 | l.warn(`RPC methods not decorated: ${unknown.join(', ')}`);
|
286 | }
|
287 |
|
288 |
|
289 |
|
290 | for (let i = 0; i < allKnown.length; i++) {
|
291 | const [k, {
|
292 | method,
|
293 | section
|
294 | }] = allKnown[i];
|
295 |
|
296 | if (hasResults && !exposed.includes(k) && k !== 'rpc_methods') {
|
297 | if (this._rpc[section]) {
|
298 | delete this._rpc[section][method];
|
299 | delete this._rx.rpc[section][method];
|
300 | }
|
301 | }
|
302 | }
|
303 | }
|
304 |
|
305 | _decorateRpc(rpc, decorateMethod, input = {}) {
|
306 | const out = input;
|
307 |
|
308 | const decorateFn = (section, method) => {
|
309 | const source = rpc[section][method];
|
310 | const fn = decorateMethod(source, {
|
311 | methodName: method
|
312 | });
|
313 | fn.meta = source.meta;
|
314 | fn.raw = decorateMethod(source.raw, {
|
315 | methodName: method
|
316 | });
|
317 | return fn;
|
318 | };
|
319 |
|
320 | for (let s = 0; s < rpc.sections.length; s++) {
|
321 | const section = rpc.sections[s];
|
322 |
|
323 | if (!Object.prototype.hasOwnProperty.call(out, section)) {
|
324 | const methods = Object.keys(rpc[section]);
|
325 |
|
326 | const decorateInternal = method => decorateFn(section, method);
|
327 |
|
328 | for (let m = 0; m < methods.length; m++) {
|
329 | const method = methods[m];
|
330 |
|
331 | if (this.hasSubscriptions || !(method.startsWith('subscribe') || method.startsWith('unsubscribe'))) {
|
332 | if (!Object.prototype.hasOwnProperty.call(out, section)) {
|
333 | out[section] = {};
|
334 | }
|
335 |
|
336 | lazyMethod(out[section], method, decorateInternal);
|
337 | }
|
338 | }
|
339 | }
|
340 | }
|
341 |
|
342 | return out;
|
343 | }
|
344 |
|
345 |
|
346 | _decorateMulti(decorateMethod) {
|
347 |
|
348 | return decorateMethod(keys => (this.hasSubscriptions ? this._rpcCore.state.subscribeStorage : this._rpcCore.state.queryStorageAt)(keys.map(args => Array.isArray(args) ? args[0].creator.meta.type.isPlain ? [args[0].creator] : args[0].creator.meta.type.asMap.hashers.length === 1 ? [args[0].creator, args.slice(1)] : [args[0].creator, ...args.slice(1)] : [args.creator])));
|
349 | }
|
350 |
|
351 | _decorateMultiAt(atApi, decorateMethod, blockHash) {
|
352 |
|
353 | return decorateMethod(calls => this._rpcCore.state.queryStorageAt(calls.map(args => {
|
354 | if (Array.isArray(args)) {
|
355 | const {
|
356 | creator
|
357 | } = getAtQueryFn(atApi, args[0].creator);
|
358 | return creator.meta.type.isPlain ? [creator] : creator.meta.type.asMap.hashers.length === 1 ? [creator, args.slice(1)] : [creator, ...args.slice(1)];
|
359 | }
|
360 |
|
361 | return [getAtQueryFn(atApi, args.creator).creator];
|
362 | }), blockHash));
|
363 | }
|
364 |
|
365 | _decorateExtrinsics({
|
366 | tx
|
367 | }, decorateMethod) {
|
368 | const result = createSubmittable(this._type, this._rx, decorateMethod);
|
369 |
|
370 | const lazySection = section => lazyMethods({}, Object.keys(tx[section]), method => this._decorateExtrinsicEntry(tx[section][method], result));
|
371 |
|
372 | const sections = Object.keys(tx);
|
373 |
|
374 | for (let i = 0; i < sections.length; i++) {
|
375 | lazyMethod(result, sections[i], lazySection);
|
376 | }
|
377 |
|
378 | return result;
|
379 | }
|
380 |
|
381 | _decorateExtrinsicEntry(method, creator) {
|
382 | const decorated = (...params) => creator(method(...params));
|
383 |
|
384 |
|
385 | decorated.is = other => method.is(other);
|
386 |
|
387 |
|
388 | return this._decorateFunctionMeta(method, decorated);
|
389 | }
|
390 |
|
391 | _decorateStorage({
|
392 | query,
|
393 | registry
|
394 | }, decorateMethod, blockHash) {
|
395 | const result = {};
|
396 |
|
397 | const lazySection = section => lazyMethods({}, Object.keys(query[section]), method => blockHash ? this._decorateStorageEntryAt(registry, query[section][method], decorateMethod, blockHash) : this._decorateStorageEntry(query[section][method], decorateMethod));
|
398 |
|
399 | const sections = Object.keys(query);
|
400 |
|
401 | for (let i = 0; i < sections.length; i++) {
|
402 | lazyMethod(result, sections[i], lazySection);
|
403 | }
|
404 |
|
405 | return result;
|
406 | }
|
407 |
|
408 | _decorateStorageEntry(creator, decorateMethod) {
|
409 | const getArgs = (args, registry) => extractStorageArgs(registry || this.#registry, creator, args);
|
410 |
|
411 | const getQueryAt = blockHash => from(this.at(blockHash)).pipe(map(api => getAtQueryFn(api, creator)));
|
412 |
|
413 |
|
414 |
|
415 |
|
416 | const decorated = this._decorateStorageCall(creator, decorateMethod);
|
417 |
|
418 | decorated.creator = creator;
|
419 | decorated.at = decorateMethod((blockHash, ...args) => getQueryAt(blockHash).pipe(switchMap(q => q(...args))));
|
420 | decorated.hash = decorateMethod((...args) => this._rpcCore.state.getStorageHash(getArgs(args)));
|
421 |
|
422 | decorated.is = key => key.section === creator.section && key.method === creator.method;
|
423 |
|
424 | decorated.key = (...args) => u8aToHex(compactStripLength(creator(...args))[1]);
|
425 |
|
426 | decorated.keyPrefix = (...args) => u8aToHex(creator.keyPrefix(...args));
|
427 |
|
428 | decorated.range = decorateMethod((range, ...args) => this._decorateStorageRange(decorated, args, range));
|
429 | decorated.size = decorateMethod((...args) => this._rpcCore.state.getStorageSize(getArgs(args)));
|
430 | decorated.sizeAt = decorateMethod((blockHash, ...args) => getQueryAt(blockHash).pipe(switchMap(q => this._rpcCore.state.getStorageSize(getArgs(args, q.creator.meta.registry), blockHash))));
|
431 |
|
432 | if (creator.iterKey && creator.meta.type.isMap) {
|
433 | decorated.entries = decorateMethod(memo(this.#instanceId, (...args) => this._retrieveMapEntries(creator, null, args)));
|
434 | decorated.entriesAt = decorateMethod(memo(this.#instanceId, (blockHash, ...args) => getQueryAt(blockHash).pipe(switchMap(q => this._retrieveMapEntries(q.creator, blockHash, args)))));
|
435 | decorated.entriesPaged = decorateMethod(memo(this.#instanceId, opts => this._retrieveMapEntriesPaged(creator, undefined, opts)));
|
436 | decorated.keys = decorateMethod(memo(this.#instanceId, (...args) => this._retrieveMapKeys(creator, null, args)));
|
437 | decorated.keysAt = decorateMethod(memo(this.#instanceId, (blockHash, ...args) => getQueryAt(blockHash).pipe(switchMap(q => this._retrieveMapKeys(q.creator, blockHash, args)))));
|
438 | decorated.keysPaged = decorateMethod(memo(this.#instanceId, opts => this._retrieveMapKeysPaged(creator, undefined, opts)));
|
439 | }
|
440 |
|
441 | if (this.supportMulti && creator.meta.type.isMap) {
|
442 |
|
443 | decorated.multi = decorateMethod(args => creator.meta.type.asMap.hashers.length === 1 ? this._retrieveMulti(args.map(a => [creator, [a]])) : this._retrieveMulti(args.map(a => [creator, a])));
|
444 | }
|
445 |
|
446 |
|
447 |
|
448 | return this._decorateFunctionMeta(creator, decorated);
|
449 | }
|
450 |
|
451 | _decorateStorageEntryAt(registry, creator, decorateMethod, blockHash) {
|
452 | const getArgs = args => extractStorageArgs(registry, creator, args);
|
453 |
|
454 |
|
455 |
|
456 |
|
457 | const decorated = decorateMethod((...args) => this._rpcCore.state.getStorage(getArgs(args), blockHash));
|
458 | decorated.creator = creator;
|
459 | decorated.hash = decorateMethod((...args) => this._rpcCore.state.getStorageHash(getArgs(args), blockHash));
|
460 |
|
461 | decorated.is = key => key.section === creator.section && key.method === creator.method;
|
462 |
|
463 | decorated.key = (...args) => u8aToHex(compactStripLength(creator(creator.meta.type.isPlain ? undefined : args))[1]);
|
464 |
|
465 | decorated.keyPrefix = (...keys) => u8aToHex(creator.keyPrefix(...keys));
|
466 |
|
467 | decorated.size = decorateMethod((...args) => this._rpcCore.state.getStorageSize(getArgs(args), blockHash));
|
468 |
|
469 | if (creator.iterKey && creator.meta.type.isMap) {
|
470 | decorated.entries = decorateMethod(memo(this.#instanceId, (...args) => this._retrieveMapEntries(creator, blockHash, args)));
|
471 | decorated.entriesPaged = decorateMethod(memo(this.#instanceId, opts => this._retrieveMapEntriesPaged(creator, blockHash, opts)));
|
472 | decorated.keys = decorateMethod(memo(this.#instanceId, (...args) => this._retrieveMapKeys(creator, blockHash, args)));
|
473 | decorated.keysPaged = decorateMethod(memo(this.#instanceId, opts => this._retrieveMapKeysPaged(creator, blockHash, opts)));
|
474 | }
|
475 |
|
476 | if (this.supportMulti && creator.meta.type.isMap) {
|
477 |
|
478 | decorated.multi = decorateMethod(args => creator.meta.type.asMap.hashers.length === 1 ? this._retrieveMulti(args.map(a => [creator, [a]]), blockHash) : this._retrieveMulti(args.map(a => [creator, a]), blockHash));
|
479 | }
|
480 |
|
481 |
|
482 |
|
483 | return this._decorateFunctionMeta(creator, decorated);
|
484 | }
|
485 |
|
486 | _queueStorage(call, queue) {
|
487 | const query = queue === this.#storageSubQ ? this._rpcCore.state.subscribeStorage : this._rpcCore.state.queryStorageAt;
|
488 | let queueIdx = queue.length - 1;
|
489 | let valueIdx = 0;
|
490 | let valueObs;
|
491 |
|
492 | if (queueIdx === -1 || !queue[queueIdx] || queue[queueIdx][1].length === PAGE_SIZE_Q) {
|
493 | queueIdx++;
|
494 | valueObs = from(
|
495 |
|
496 | Promise.resolve().then(() => {
|
497 | const calls = queue[queueIdx][1];
|
498 | delete queue[queueIdx];
|
499 | return calls;
|
500 | })).pipe(switchMap(calls => query(calls)));
|
501 | queue.push([valueObs, [call]]);
|
502 | } else {
|
503 | valueObs = queue[queueIdx][0];
|
504 | valueIdx = queue[queueIdx][1].length;
|
505 | queue[queueIdx][1].push(call);
|
506 | }
|
507 |
|
508 | return valueObs.pipe(map(values => values[valueIdx]));
|
509 | }
|
510 |
|
511 |
|
512 |
|
513 | _decorateStorageCall(creator, decorateMethod) {
|
514 | return decorateMethod((...args) => {
|
515 | const call = extractStorageArgs(this.#registry, creator, args);
|
516 |
|
517 | if (!this.hasSubscriptions) {
|
518 | return this._rpcCore.state.getStorage(call);
|
519 | }
|
520 |
|
521 | return this._queueStorage(call, this.#storageSubQ);
|
522 | }, {
|
523 | methodName: creator.method,
|
524 | overrideNoSub: (...args) => this._queueStorage(extractStorageArgs(this.#registry, creator, args), this.#storageGetQ)
|
525 | });
|
526 | }
|
527 |
|
528 | _decorateStorageRange(decorated, args, range) {
|
529 | const outputType = unwrapStorageType(this.#registry, decorated.creator.meta.type, decorated.creator.meta.modifier.isOptional);
|
530 | return this._rpcCore.state.queryStorage([decorated.key(...args)], ...range).pipe(map(result => result.map(([blockHash, [value]]) => [blockHash, this.createType(outputType, value.isSome ? value.unwrap().toHex() : undefined)])));
|
531 | }
|
532 |
|
533 |
|
534 | _retrieveMulti(keys, blockHash) {
|
535 | if (!keys.length) {
|
536 | return of([]);
|
537 | }
|
538 |
|
539 | const query = this.hasSubscriptions && !blockHash ? this._rpcCore.state.subscribeStorage : this._rpcCore.state.queryStorageAt;
|
540 |
|
541 | if (keys.length <= PAGE_SIZE_V) {
|
542 | return blockHash ? query(keys, blockHash) : query(keys);
|
543 | }
|
544 |
|
545 | return combineLatest(arrayChunk(keys, PAGE_SIZE_V).map(k => blockHash ? query(k, blockHash) : query(k))).pipe(map(arrayFlatten));
|
546 | }
|
547 |
|
548 | _retrieveMapKeys({
|
549 | iterKey,
|
550 | meta,
|
551 | method,
|
552 | section
|
553 | }, at, args) {
|
554 | assert(iterKey && meta.type.isMap, 'keys can only be retrieved on maps');
|
555 | const headKey = iterKey(...args).toHex();
|
556 | const startSubject = new BehaviorSubject(headKey);
|
557 | const query = at ? startKey => this._rpcCore.state.getKeysPaged(headKey, PAGE_SIZE_K, startKey, at) : startKey => this._rpcCore.state.getKeysPaged(headKey, PAGE_SIZE_K, startKey);
|
558 |
|
559 | const setMeta = key => key.setMeta(meta, section, method);
|
560 |
|
561 | return startSubject.pipe(switchMap(query), map(keys => keys.map(setMeta)), tap(keys => nextTick(() => {
|
562 | keys.length === PAGE_SIZE_K ? startSubject.next(keys[PAGE_SIZE_K - 1].toHex()) : startSubject.complete();
|
563 | })), toArray(),
|
564 | map(arrayFlatten));
|
565 | }
|
566 |
|
567 | _retrieveMapKeysPaged({
|
568 | iterKey,
|
569 | meta,
|
570 | method,
|
571 | section
|
572 | }, at, opts) {
|
573 | assert(iterKey && meta.type.isMap, 'keys can only be retrieved on maps');
|
574 |
|
575 | const setMeta = key => key.setMeta(meta, section, method);
|
576 |
|
577 | const query = at ? headKey => this._rpcCore.state.getKeysPaged(headKey, opts.pageSize, opts.startKey || headKey, at) : headKey => this._rpcCore.state.getKeysPaged(headKey, opts.pageSize, opts.startKey || headKey);
|
578 | return query(iterKey(...opts.args).toHex()).pipe(map(keys => keys.map(setMeta)));
|
579 | }
|
580 |
|
581 | _retrieveMapEntries(entry, at, args) {
|
582 | const query = at ? keys => this._rpcCore.state.queryStorageAt(keys, at) : keys => this._rpcCore.state.queryStorageAt(keys);
|
583 | return this._retrieveMapKeys(entry, at, args).pipe(switchMap(keys => keys.length ? combineLatest(arrayChunk(keys, PAGE_SIZE_V).map(query)).pipe(map(valsArr => arrayFlatten(valsArr).map((value, index) => [keys[index], value]))) : of([])));
|
584 | }
|
585 |
|
586 | _retrieveMapEntriesPaged(entry, at, opts) {
|
587 | const query = at ? keys => this._rpcCore.state.queryStorageAt(keys, at) : keys => this._rpcCore.state.queryStorageAt(keys);
|
588 | return this._retrieveMapKeysPaged(entry, at, opts).pipe(switchMap(keys => keys.length ? query(keys).pipe(map(valsArr => valsArr.map((value, index) => [keys[index], value]))) : of([])));
|
589 | }
|
590 |
|
591 | _decorateDeriveRx(decorateMethod) {
|
592 | var _this$_runtimeVersion, _this$_options$typesB, _this$_options$typesB2, _this$_options$typesB3;
|
593 |
|
594 | const specName = (_this$_runtimeVersion = this._runtimeVersion) === null || _this$_runtimeVersion === void 0 ? void 0 : _this$_runtimeVersion.specName.toString();
|
595 |
|
596 | const available = getAvailableDerives(this.#instanceId, this._rx, objectSpread({}, this._options.derives, (_this$_options$typesB = this._options.typesBundle) === null || _this$_options$typesB === void 0 ? void 0 : (_this$_options$typesB2 = _this$_options$typesB.spec) === null || _this$_options$typesB2 === void 0 ? void 0 : (_this$_options$typesB3 = _this$_options$typesB2[specName || '']) === null || _this$_options$typesB3 === void 0 ? void 0 : _this$_options$typesB3.derives));
|
597 | return decorateDeriveSections(decorateMethod, available);
|
598 | }
|
599 |
|
600 | _decorateDerive(decorateMethod) {
|
601 | return decorateDeriveSections(decorateMethod, this._rx.derive);
|
602 | }
|
603 | |
604 |
|
605 |
|
606 |
|
607 |
|
608 |
|
609 | _rxDecorateMethod = method => {
|
610 | return method;
|
611 | };
|
612 | } |
\ | No newline at end of file |