Something went wrong. Try again.
Automerge backed Markdown editor for the Atmosphere
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113import { createRoot } from 'react-dom/client'import { BootErrorBoundary } from './BootErrorBoundary'import { BOOT_STAGE_LABELS } from './boot-stages'
import type { ReamsEditionBootstrap } from '../editions/types'import { applyPwaUpdate, registerPwaUpdates, subscribeToUpdates, updateAvailable } from './pwa-updates'import '../index.css'
export async function mount(edition: ReamsEditionBootstrap): Promise<void> { const started = performance.now() void registerPwaUpdates()
const rootElement = document.getElementById('root')! const appElement = document.createElement('div') appElement.style.visibility = 'hidden' appElement.setAttribute('inert', '') appElement.style.height = '100%' rootElement.appendChild(appElement) let failed = false let opened = false const showError = (error: unknown) => { if (failed) return failed = true console.error('Reams startup failed:', error) const lastStage = rootElement.querySelector('[data-boot-stage]')?.textContent const storageError = error instanceof DOMException && ['SecurityError', 'QuotaExceededError', 'VersionError'].includes(error.name) rootElement.replaceChildren() const screen = document.createElement('main') screen.className = 'reams-boot' screen.setAttribute('role', 'alert') const title = document.createElement('h1') title.textContent = opened ? 'Reams stopped unexpectedly' : storageError ? 'Browser storage is unavailable' : 'Reams could not start' const message = document.createElement('p') message.textContent = opened ? 'The workspace stopped unexpectedly. Recent unsaved edits may not be available after a reload.' : storageError ? 'Check browser storage permissions and try again. Reams has not cleared your local notes.' : 'The application could not finish opening. Reams has not cleared your local notes.' const retry = document.createElement('button') retry.type = 'button' retry.textContent = 'Try again' retry.addEventListener('click', () => location.reload()) screen.append(title, message) if (!opened && lastStage) { const stage = document.createElement('p') stage.textContent = `Last step: ${lastStage}` screen.append(stage) } if (error instanceof Error && error.message.trim()) { const reason = document.createElement('p') reason.textContent = `Reason: ${error.message}` screen.append(reason) } screen.append(retry) const update = document.createElement('button') update.type = 'button' update.textContent = 'Update' const updateFailure = document.createElement('p') updateFailure.setAttribute('role', 'status') updateFailure.hidden = true let updating = false const refreshUpdate = () => { update.hidden = !updating && !updateAvailable() update.disabled = updating retry.disabled = updating update.textContent = updating ? 'Updating…' : 'Update' } update.addEventListener('click', async () => { if (updating) return updating = true updateFailure.hidden = true refreshUpdate() try { await applyPwaUpdate({ workspaceNeverOpened: !opened }) } catch (error) { updateFailure.textContent = error instanceof Error ? error.message : 'Could not apply update' updateFailure.hidden = false } finally { updating = false refreshUpdate() } }) // This terminal recovery surface lives until the page reloads. Updates may // finish downloading after startup has already failed. subscribeToUpdates(refreshUpdate) refreshUpdate() screen.append(update, updateFailure) rootElement.append(screen) } try { const element = await edition.initialize(() => { if (failed) return try { sessionStorage.setItem('reams:workspace-startup-timings', JSON.stringify({ total: Math.round(performance.now() - started) })) } catch { /* optional duration-only boot diagnostics */ } if (new URLSearchParams(location.search).has('benchBreakdown')) performance.mark('reams:boot:visible') // Keep the original HTML loading surface in place through every async // stage, including the first editor mount and plugin activation. appElement.style.visibility = '' appElement.removeAttribute('inert') rootElement.querySelector('.reams-boot')?.remove() opened = true }, stage => { if (failed || opened) return const label = rootElement.querySelector('.reams-boot [data-boot-stage]') if (label) label.textContent = BOOT_STAGE_LABELS[stage] }) createRoot(appElement).render(<BootErrorBoundary onError={showError}>{element}</BootErrorBoundary>) } catch (error) { showError(error) throw error }}