Add autoconnect to ScProvider (#5217)
* Add autoconnect to ScProvider * Add autoconnect flag * remove autoconnect solution and create resubscribe * Satisfy lint * Update packages/rpc-provider/src/substrate-connect/ScProvider.ts Co-authored-by: Jaco <jacogr@gmail.com> Co-authored-by: Jaco <jacogr@gmail.com>
This commit is contained in:
@@ -7,13 +7,15 @@ import type { JsonRpcResponse, ProviderInterface, ProviderInterfaceCallback, Pro
|
||||
import { Chain, createScClient, ScClient, WellKnownChain } from '@substrate/connect';
|
||||
import EventEmitter from 'eventemitter3';
|
||||
|
||||
import { isError, objectSpread } from '@polkadot/util';
|
||||
import { isError, logger, objectSpread } from '@polkadot/util';
|
||||
|
||||
import { RpcCoder } from '../coder';
|
||||
import { healthChecker } from './Health';
|
||||
|
||||
type ResponseCallback = (response: string | Error) => void
|
||||
|
||||
const l = logger('api-substrate-connect');
|
||||
|
||||
// These methods have been taken from:
|
||||
// https://github.com/paritytech/smoldot/blob/17425040ddda47d539556eeaf62b88c4240d1d42/src/json_rpc/methods.rs#L338-L462
|
||||
// It's important to take into account that smoldot is adding support to the new
|
||||
@@ -37,11 +39,19 @@ const scClients = new WeakMap<ScProvider, ScClient>();
|
||||
|
||||
export { WellKnownChain };
|
||||
|
||||
interface ActiveSubs {
|
||||
type: string,
|
||||
method: string,
|
||||
params: any[],
|
||||
callback: ProviderInterfaceCallback
|
||||
}
|
||||
|
||||
export class ScProvider implements ProviderInterface {
|
||||
readonly #coder: RpcCoder = new RpcCoder();
|
||||
readonly #spec: string | WellKnownChain;
|
||||
readonly #sharedSandbox?: ScProvider;
|
||||
readonly #subscriptions: Map<string, [ResponseCallback, { unsubscribeMethod: string; id: string | number }]> = new Map();
|
||||
readonly #resubscribeMethods: Map<string, ActiveSubs> = new Map();
|
||||
readonly #requests: Map<number, ResponseCallback> = new Map();
|
||||
readonly #eventemitter: EventEmitter = new EventEmitter();
|
||||
#chain: Promise<Chain> | null = null;
|
||||
@@ -207,11 +217,17 @@ export class ScProvider implements ProviderInterface {
|
||||
staleSubscriptions.push(s[1]);
|
||||
});
|
||||
cleanup();
|
||||
|
||||
this.#eventemitter.emit('disconnected');
|
||||
} else {
|
||||
killStaleSubscriptions();
|
||||
}
|
||||
|
||||
this.#eventemitter.emit(isReady ? 'connected' : 'disconnected');
|
||||
this.#eventemitter.emit('connected');
|
||||
|
||||
if (this.#resubscribeMethods.size) {
|
||||
this.#resubscribe();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return objectSpread({}, chain, {
|
||||
@@ -233,6 +249,32 @@ export class ScProvider implements ProviderInterface {
|
||||
}
|
||||
}
|
||||
|
||||
#resubscribe = (): void => {
|
||||
const promises: any[] = [];
|
||||
|
||||
this.#resubscribeMethods.forEach((subDetails: ActiveSubs): void => {
|
||||
// only re-create subscriptions which are not in author (only area where
|
||||
// transactions are created, i.e. submissions such as 'author_submitAndWatchExtrinsic'
|
||||
// are not included (and will not be re-broadcast)
|
||||
if (subDetails.type.startsWith('author_')) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const promise: Promise<void> = new Promise((resolve) => {
|
||||
this.subscribe(subDetails.type, subDetails.method, subDetails.params, subDetails.callback).catch((error) => console.log(error));
|
||||
resolve();
|
||||
});
|
||||
|
||||
promises.push(promise);
|
||||
} catch (error) {
|
||||
l.error(error);
|
||||
}
|
||||
});
|
||||
|
||||
Promise.all(promises).catch((err) => l.log(err));
|
||||
};
|
||||
|
||||
async disconnect (): Promise<void> {
|
||||
if (!this.#chain) {
|
||||
return;
|
||||
@@ -322,6 +364,8 @@ export class ScProvider implements ProviderInterface {
|
||||
throw new Error('Invalid unsubscribe method found');
|
||||
}
|
||||
|
||||
this.#resubscribeMethods.set(subscriptionId, { callback, method, params, type });
|
||||
|
||||
this.#subscriptions.set(subscriptionId, [cb, { id, unsubscribeMethod }]);
|
||||
|
||||
return id;
|
||||
|
||||
Reference in New Issue
Block a user