The deployed page was a bare black screen for minutes with nothing but the tab
spinner to suggest it was not simply broken. Two separate faults.
**No fallback.** `main.tsx` wraps the whole app in
`<Subscribe source$={merge(dynamicBuilder$, …)}>`, and Subscribe's `fallback`
defaults to null — "it will render null until the subscription exists".
`dynamicBuilder$` does not emit until a chain has been followed and its metadata
decoded, so until then the document body is empty. On a slow connection that is
seconds of nothing; on a chain the console cannot read it is forever, and a
visitor cannot tell the two apart. There is now a splash naming the chain and
the endpoint, which escalates at 8s and again at 25s and tells the reader how to
force a different network.
**The default endpoint was the light client.** `defaultSelectedChain` used
LIGHT_CLIENT_ENDPOINT unconditionally, which routes through smoldot — and
smoldot needs a chain spec. The Quantus networks have none
(`hasChainSpecs: false`), so the default asked it to follow a chain it had never
heard of. It now picks AUTO_RPC for any network without chain specs, which is
what the endpoints in quantus.json are for.
This does not make the console work against Quantus. It makes it explain itself
while failing, which it could not do before — the remaining fault is much
deeper and is written up on #1.
Refs #1, #3
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012uDUodEcRbBwNRi3UCmw8f
53 lines
1.8 KiB
TypeScript
53 lines
1.8 KiB
TypeScript
import { dynamicBuilder$, getDefaultChain } from "@/state/chains/chain.state"
|
|
import { RemoveSubscribe, Subscribe } from "@react-rxjs/core"
|
|
import { MultisigExternalSignerModal, PolkaHubProvider } from "polkahub"
|
|
import { StrictMode } from "react"
|
|
import { createRoot } from "react-dom/client"
|
|
import { BrowserRouter } from "react-router-dom"
|
|
import { merge } from "rxjs"
|
|
import App from "./App.tsx"
|
|
import { TooltipProvider } from "./components/ui/tooltip.tsx"
|
|
import "./index.css"
|
|
import { BootSplash } from "./components/BootSplash.tsx"
|
|
import { codeSplit$ } from "./lib/externalState.ts"
|
|
import { explorer$ } from "./pages/Explorer"
|
|
import { polkaHub } from "./state/polkahub.ts"
|
|
import { ThemeProvider } from "./ThemeProvider.tsx"
|
|
|
|
const metrics$ = codeSplit$(() =>
|
|
import("./pages/Metrics/metrics.state.ts").then((r) => r.blockStats$),
|
|
)
|
|
|
|
// Without a fallback, `Subscribe` renders null until `dynamicBuilder$` emits —
|
|
// which is after a chain has been followed and its metadata decoded. On a slow
|
|
// connection that is seconds of empty black page; on a chain the console cannot
|
|
// read, it is forever, and indistinguishable from a crash.
|
|
const initial = getDefaultChain()
|
|
|
|
createRoot(document.getElementById("root")!).render(
|
|
<Subscribe
|
|
fallback={
|
|
<BootSplash
|
|
endpoint={initial.endpoint}
|
|
network={initial.network.display}
|
|
/>
|
|
}
|
|
source$={merge(dynamicBuilder$, explorer$, metrics$)}
|
|
>
|
|
<RemoveSubscribe>
|
|
<StrictMode>
|
|
<ThemeProvider>
|
|
<PolkaHubProvider polkaHub={polkaHub}>
|
|
<BrowserRouter>
|
|
<TooltipProvider delayDuration={500}>
|
|
<App />
|
|
</TooltipProvider>
|
|
</BrowserRouter>
|
|
<MultisigExternalSignerModal />
|
|
</PolkaHubProvider>
|
|
</ThemeProvider>
|
|
</StrictMode>
|
|
</RemoveSubscribe>
|
|
</Subscribe>,
|
|
)
|