diff --git a/src/api/metadatas.ts b/src/api/metadatas.ts index 3f9f6ef..057da58 100644 --- a/src/api/metadatas.ts +++ b/src/api/metadatas.ts @@ -2,6 +2,7 @@ import { getObservableClient } from "@polkadot-api/observable-client" import { V14, V15 } from "@polkadot-api/substrate-bindings" import { createClient } from "@polkadot-api/substrate-client" import { state } from "@react-rxjs/core" +import { createSignal } from "@react-rxjs/utils" import { get, set } from "idb-keyval" import { getSmProvider } from "polkadot-api/sm-provider" import { mapObject } from "polkadot-api/utils" @@ -10,7 +11,6 @@ import { catchError, filter, finalize, - from, map, of, share, @@ -21,13 +21,12 @@ import { } from "rxjs" import { selectedChains$ } from "../ChainPicker" import { chains } from "./smoldot" -import { createSignal } from "@react-rxjs/utils" export const [changeUseCache$, setUseCache] = createSignal() export const useCache$ = state(changeUseCache$, true) -export const metadatas = mapObject(chains, (chain, key) => { - const throughSmoldot$ = from(chain).pipe( +export const metadatas = mapObject(chains, (chain$, key) => { + const throughSmoldot$ = chain$.pipe( map(getSmProvider), map(createClient), map(getObservableClient), diff --git a/src/api/smoldot.ts b/src/api/smoldot.ts index de65414..dc98279 100644 --- a/src/api/smoldot.ts +++ b/src/api/smoldot.ts @@ -1,5 +1,14 @@ import { startFromWorker } from "polkadot-api/smoldot/from-worker" import SmWorker from "polkadot-api/smoldot/worker?worker" +import { + MonoTypeOperatorFunction, + Observable, + ReplaySubject, + combineLatest, + defer, + share, + switchMap, +} from "rxjs" import { Chain } from "smoldot" export const smoldot = startFromWorker(new SmWorker()) @@ -29,25 +38,29 @@ const chainImports = { }, } -export const chains: Record> = Object.fromEntries( +export const chains: Record> = Object.fromEntries( Object.entries(chainImports).flatMap(([key, chains]) => { const { relayChain, ...parachains } = chains - const chainRelayChain = relayChain.then(({ chainSpec }) => - smoldot.addChain({ - chainSpec, - }), - ) + const chainRelayChain = defer(() => + relayChain.then(({ chainSpec }) => + smoldot.addChain({ + chainSpec, + }), + ), + ).pipe(persist()) const parachainChains = Object.entries(parachains).map( ([parachainKey, parachain]) => [ `${key}.${parachainKey}`, - Promise.all([chainRelayChain, parachain]).then( - ([chainRelayChain, parachain]) => + combineLatest([chainRelayChain, parachain]).pipe( + switchMap(([chainRelayChain, parachain]) => smoldot.addChain({ chainSpec: parachain.chainSpec, potentialRelayChains: [chainRelayChain], }), + ), + persist(), ), ] as const, ) @@ -55,3 +68,12 @@ export const chains: Record> = Object.fromEntries( return [[key, chainRelayChain], ...parachainChains] }), ) + +function persist(): MonoTypeOperatorFunction { + return share({ + connector: () => new ReplaySubject(1), + resetOnComplete: false, + resetOnRefCountZero: false, + resetOnError: true, + }) +}