s-m-r-t
Open the s-m-r-t source on GitHub Switch to dark color scheme
← All packages
Web & UI v0.57.40 New

@happyvertical/smrt-svelte

The top-of-stack Svelte integration: AppShell, Provider, rich forms, recipe screens, browser AI, live collections, and permissions.

Source ↗

What it gives you

The top-of-stack Svelte integration: AppShell, Provider, rich forms, recipe screens, browser AI, live collections, and permissions.

  1. 01AppShell composes Provider, ThemeProvider, and the four-edge AdminShell with tenant navigation
  2. 02Recipe screens, a command palette, overview grids, and CSV import and export on their own subpaths
  3. 03Tenant navigation built from the manifest, not hand-written
  4. 04SvelteKit server-to-client collection and message hydration
  5. 05Live-query bindings and browser AI adapters with a warm cache

The UI and Svelte layers share i18n deliberately

smrt-ui owns defineMessages, useI18n, Trans, and template rendering in the browser. smrt-svelte builds the server snapshot with buildI18nSnapshot and passes it through Provider. Put canonical themes under src/themes; src/theme is a legacy alias during migration.

Gate dock tools and page actions at the boundary

ToolDef.gates and composeDockAvailability decide whether an AdminShell dock tool is available before it is shown or invoked. The use:permission action makes the same permission decision in a component; applications can choose hide-only behavior without treating visibility as authorization. The web subpath also adapts live activity feeds and exposes updateAvailable.

Navigation the manifest already describes

tenantNavFromManifest turns a manifest into ordered navigation sections. It drops collections, internal and test classes, and items without a REST list route. It also drops single-table-inheritance subtypes that share a parent collection because the polymorphic endpoint already includes them. Pass permittedResources to filter the resources that a role can see. The filter checks the inheritance chain, so a permitted subtype keeps its applicable base link. Sorted output prevents manifest changes from reordering the sidebar.

How the shell is composed →

AppShell is the composed entry

AppShell on the /app subpath wraps Provider, ThemeProvider, the theme CSS, AdminShell, and TenantNav built from the nav you pass. It is browser-only and lives beside /workspace, so the AdminShell barrel stays free of Provider. A dock snippet receives the data-surface registry, so a host places its assistant there without this package importing smrt-chat. Pass layout and onlayoutchange to own shell layout persistence, or neither to store it in user settings.

How the shell is composed →

Screens derived from recipes

RecipeScreens, ListScreen, DetailScreen, and EditForm on the /screens subpath derive their views from a generated web definition and the resolved field policy. The /cookbook subpath builds AppShell sections and recipe surfaces from a cookbook document. CommandPalette mounts once as a shell slot item and owns the global shortcut. OverviewGrid joins the shell layout edit mode; ImportExport maps CSV columns against collection definitions.

AdminShell replaced the first-generation shells

The public workspace surface is the four-edge AdminShell contract. The earlier WorkspaceShell and RoleShell primitives remain only as migration references. No subpath exports them. Compose new work with AdminShell panels and focus tools. The earlier focus-tool dock stays available on the workspace/legacy subpath during application migration.

How the shell is composed →

Browser AI preloads on a strategy you choose

Provider accepts a preload strategy of none, eager, idle, or on-visible. The default idle strategy schedules work in an idle callback. eager starts immediately, and none defers each adapter until first use. on-visible is manual: the package schedules nothing, and the application starts the preload. Adapters warm sequentially, and one failure does not stop the remaining adapters. A module-level cache keeps each initialized adapter, so navigation does not download a model again.

Calling a local model from a component

useLLM runs inside the Provider and exposes initialize, chat, and unload alongside reactive isReady, isGenerating, currentModel, error, and downloadProgress values. Streaming is delivered through an onToken callback while chat still resolves to the finished string. Unmounting deliberately does not unload the model, because the download is the expensive part.

One language snapshot per render

buildI18nSnapshot resolves server message templates for a locale, including tenant overrides. Provider accepts the result. The browser interpolates variables. A missing key uses the registered English default and then the key itself. Thus, a partly translated application still renders. The matching useI18n store and Trans component are in the UI foundation.

smrt-ui →