Automerge backed Markdown editor for the Atmosphere
reams docs boot-loading.md
6.2 kB
Markdown
at main

Boot loading contract #

The initial HTML owns the only full-screen loading UI. Its spinner stays centered and turning, including with reduced motion enabled. The short status below it changes to reflect the blocking stage (account restoration, repository, vault, search wiring, tabs, note, plugins) without changing the screen. The application mounts behind this surface, invisible and inert, so its intermediate empty/editor-loading states cannot flash. Startup errors before React mounts replace the boot surface with a retry message.

Inventory and ownership #

These are the boot checkpoints, not twelve separate screens. Entries marked “background” do not block the first usable view.

Checkpoint Owner Completion / behavior
1. HTML and entry bundle index.html, src/entries/* Boot surface exists before JS; failed module load changes its message.
2. Edition modules and classic WASM src/editions/* Load editor/runtime code; classic initializes subduction WASM.
3. Account restoration (ATProto) src/atproto/account.ts Complete pending OAuth callback or restore session, then select/create vault. Signed-out users use a local space.
4. Repository/space (ATProto) src/atproto/native-repo.ts Open remote or local space; remote initial sync and root discovery finish before the app runtime is built.
5. Runtime and root URL src/app/app-runtime.ts Construct document manager, vault index, workspace and plugin host.
6. Root validation and vault hydration src/App.tsx, src/plugin/vault.ts Validate root, hydrate file index. A bad root triggers a reload with the new root.
7. Search wiring src/services/SearchContext.tsx Start indexer wiring; full indexing is background.
8. Saved tabs src/App.tsx Await workspace.restoreLayout so leaves settle before routing.
9. Initial URL src/App.tsx Route the original hash after restoration; notify on invalid/unreachable URLs.
10. Fallback note src/App.tsx If no leaf remains, open an existing note or create/open Welcome; seed its optional image without blocking the view.
11. Plugins and sidebars src/layout/AppShell.tsx Enable built-ins and stored plugins, restore sidebar leaves, signal layout ready.
12. First view src/plugin/views/markdown-leaf-binding.tsx, src/layout/MainAreaViewContainer.tsx Wait for the active CM6 editor binding or a document error; a non-Markdown view is ready when mounted, or an empty workspace when no leaves remain. Readiness belongs to the current leaf, view and file.

Once checkpoints 11 and 12 complete, onReady in src/app/mount.tsx removes the original boot DOM and reveals the app in one handoff. Loading a different note after startup remains a local editor operation, and search discovery/derived indexing continues in the background. Failure to start the vault or an individual plugin is currently logged and treated as degraded operation, as before; an individual note load error is shown in its view. React render and commit-lifecycle exceptions replace the boot screen with a retry action; event handlers and rejected asynchronous work have their own error handling.

The HTML starts with “Loading application…” before JavaScript runs. Editions report account/repository preparation, App reports vault/search/tabs/note, and AppShell reports plugin activation and the final first-view wait via the typed BootStage labels in src/app/boot-stages.ts. Only the initial loader reads these updates; later document loads keep their local view states.

Previous surfaces removed from startup #

  • index.html already displayed “Opening Reams…”; React used to replace it.
  • src/App.tsx displayed a separate full-height vault “Opening Reams…” page.
  • src/App.tsx then displayed a second, smaller workspace “Opening Reams…” page or exposed the shell early when a leaf appeared before restoration completed.
  • src/layout/MainAreaViewContainer.tsx could show “Open a document to start editing” while the initial leaf was still in flight.
  • src/plugin/views/markdown-leaf-binding.tsx could show “Loading document...” before the initial editor was bound.
  • Built-in and stored plugins could add sidebar views after the shell appeared.

The latter local placeholders still serve later document switches; the boot handoff now waits for their first settled view. UI for account sign-in, settings, file search previews, and background indexing is interaction-scoped and does not take over the boot screen.

Ownership review #

Boot is a projection of existing lifecycles, not a second account, vault, or workspace. The account snapshot and repository own identity and data availability; Vault/FileIndex owns hydrated files; SearchProvider owns indexer wiring; Workspace owns leaves and view selection; PluginLoader owns plugin states; the Markdown binding owns CM6 attachment. The boot callback in src/app/mount.tsx only changes the text of the one HTML screen and removes that screen at handoff. It stores no account or document data.

The React gates (vaultReady, searchInitialized, initialized, pluginsReady, readyView) are ephemeral completion signals for those owners. readyView is tied to the currently selected workspace leaf/view and file identity rather than a persistent "document loaded" record. PluginLoader's in-flight enable promise and import cancellation belong to its plugin lifecycle and protect both StrictMode replay and real remounts; they are not boot stages. BootStage values are presentation labels emitted as work starts, not a state machine that drives work. ATProto repository code reports the semantic account-restored milestone; the edition translates it into a UI label.

If an initialization or React rendering failure prevents handoff, the same surface becomes an error with Retry. It includes the last visible step and the exception message so a repeated failure can be distinguished from a new loading phase. Those are diagnostic clues, not a replacement for the browser console stack; restoring a signed-in account still depends on its own runtime.