The SoAI WebUI is a TypeScript browser application built from an explicit edition composition. A persistent application shell owns global navigation, connection state, notifications, tasks, and modal surfaces. Routed pages own only their feature state, rendering, actions, and resource subscriptions.
Composition and routing
browser document
|
+-- critical startup: pre-application browser state
+-- primary entry: main application window
`-- detached entry: selected page
|
v
selected frontend edition
|
v
deterministic bootstrap stages
|
v
services, persistent shell, router
|
v
active page
The critical startup stage performs work required before the application entry. The primary and detached entries select a composition before bootstrap. Each edition selects its own composition, and the dependency direction between editions is one-way. Core pages, translations, and build configuration do not import another edition's implementation.
The application composition root constructs and registers services and pages in deterministic bootstrap stages. Core services have no feature or page dependency, feature domains have no page dependency, and pages use shared feature domains only through their public surfaces.
Persistent shell and routed-page boundary
LayoutShell
|
+-- header, global search, account menus
+-- sidebar and route navigation
+-- task and notification surfaces
+-- connection and global status
+-- modal host
`-- page outlet
|
`-- one active routed page
The shell survives route changes, so connection state, navigation, tasks, notifications, and global modal ownership do not restart with every page. The router resolves access and resource requirements before loading a page. The page outlet prepares the next page, releases the previous page's owned resources immediately before commit, commits the new route and page, then waits for page readiness before revealing it.
Route, access, and resource declarations
| Declaration | Owner | Architectural effect |
|---|---|---|
| Route identity and component loader | Route registry | Maps a stable hash route to its page implementation without import-time page registration. |
| Authentication and ACL actions | Route access policy | Rejects or redirects an inaccessible route before page initialization. The backend repeats authorization for every request. |
| Live resources | Route and page resource contracts | Acquires only the snapshots and subscriptions needed by the active surface, with explicit release on navigation. |
| Sidebar and search metadata | Edition route composition | Projects accessible destinations into navigation and global search without granting access to them. |
| Page actions and responsive placement | Page layout metadata | Keeps action identity stable while the shell moves controls for compact layouts. |
Access declarations control presentation and early routing rather than trust, while management and compatible API boundaries authorize the same operation independently. Removing a page from the sidebar changes navigation visibility only.
State and page lifecycle
| State or transport | Use | Freshness rule |
|---|---|---|
/api/v1/* REST | Finite management reads and mutations. | A successful response commits the command or snapshot owned by that endpoint. A failed mutation does not become optimistic success. |
/api/v1/system/ws | Realtime events, resource snapshots, task and chat progress, and interactive sessions. | After interruption, resources retain the last valid snapshot only as stale and request bounded authoritative recovery. |
/v1/* | Compatible inference requests where a WebUI feature uses that public contract. | Its streaming format remains the compatible protocol and is not converted into the WebUI realtime envelope. |
| Page state | Filters, selection, draft view state, pending controls, and render models owned by one page. | Terminated on navigation unless an explicit account, conversation, or browser persistence service owns it. |
| Shared client state | Session, route, shell, connection, and reusable resource stores. | Owned by Core services and updated transactionally from validated responses or events. |
The WebSocket is the only WebUI realtime transport. It reconnects after recoverable interruption, restores subscriptions, and requests fresh snapshots for registered resources. An unrecognized broadcast can be ignored with bounded diagnostics; a malformed event for a registered resource preserves the last valid state and triggers resynchronization or an explicit degraded state.
The Skills tab keeps account-library operations separate from a conversation's staged selection. Import and deletion take effect immediately; Save applies the draft selection using its revision. WebSocket snapshots reconcile changes across tabs. A conflict leaves the draft available for review, and a disconnect blocks saving until the current selection is known.
Page lifecycle and supersession
A page receives its dependencies from application composition and owns an AbortController for
page-scoped asynchronous work. Rendering produces a deterministic view; page-root action delegation handles user
events after that view is committed. Resource trackers, stream handlers, timers, observers, and interactive
operations register cleanup with the page lifecycle.
Navigation, a newer request, or a replacement snapshot can supersede work without making it an error. Abort signals and sequence ownership prevent late results from updating a page that no longer owns them. Cleanup removes subscriptions and DOM ownership before the next page assumes the outlet.
A missing required service or DOM node fails the affected page boundary. The persistent shell and unrelated pages remain available, and the page renders a stable localized failure state when safe recovery is possible. A partial render or partially wired event surface is not accepted as a successful page.
Rendering and alternate runtimes
Page views use shared DOM and UI primitives. Dynamic HTML crosses the trusted-HTML and sanitizer boundary before it reaches the DOM; URLs, text, labels, and SVG markup have their own validation paths. Icons come from the shared icon system, and user-visible text comes from the selected translation catalog rather than page-local strings.
Feature domains own reusable behavior and expose named public contracts. Pages compose those features but do not reach into another page or a feature's private implementation. This keeps rendering, validation, errors, and transport behavior from drifting into page-specific copies.
Detached pages
Chat, Logs, Terminal, and Hardware can open in separate windows using the same signed-in account and SoAI server.
Closing one of these windows leaves SoAI running. Chat conversations remain saved, and closing the window does not cancel a response or task already running on the server.
Runtime ownership map
- Application entries own critical startup, primary-window, detached-window, and shared entry behavior.
- Edition composition owns the frontend edition contract and selected composition.
- Bootstrap owns service construction, page registration, and ordered startup stages.
- Shell and routing own persistent navigation and page-transition contracts.
- Transport and realtime services own API, WebSocket, and resource state.
- Security services own sanitization and trusted UI boundaries.
- Feature domains own reusable product behavior; routed pages own page behavior and rendering.