You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

514 lines
20 KiB

Build runtime infrastructure layer: aapp + 5 new artifacts Adds the application composition root and six new runtime artifacts. lang and logr alone could not cover an app surface — locale propagation, format helpers, frontend preferences, validation, persistence and DOM service all needed independent artifacts that aapp wires together under a single locale source of truth and a shared logger. New artifacts: - aapp: composition root. createActiveApp + createTestApp + App.createSiumEngine + frontend.persist + Storage wiring. - stor: pluggable adapters (local/session/memory/cookie + SSR via cookieAdapter.fromCookies), envelope versioning + migrate + TTL, validate via Standard Schema, intra-tab + cross-tab sync, Storage.clear(), per-entry adapter/namespace overrides. - adom: reactive DOM service. shareViewport opt-in + per-window tracker, dispose(). breakpoints, viewport, attribute writes. - fend: frontend preferences (theme, mode, dir, density, reducedMotion, reducedSound) with auto/clear/isAuto pattern. - fmts: localized formatting (numbers, currency, units, dates) with shared LocaleSource and per-domain auto/clear pattern. - sium: validation engine. Standard Schema interop, Lang/Logger injection, codec/refine/transform, domain types (color/date/time), introspection. Existing artifacts extended: - lang: BCP 47 SupportedLocale (LangBase | base-region), mono lang for monolingual apps, extend() leaf-overwrite warning, EngineLang/ActiveLang naming alignment with the rest of the project (no Instance suffix). - logr: EngineLogger.dispose(), failureThrottleMs anti-cascade for transports, README sync to the per-level filter API (minLevel removed). Cross-cutting: - $locale: shared LocaleSource type consumed by fmts and fend. - arts/README.md: artifact map, dependency graph, naming conventions. - Test pages for every artifact under /test/<artifact>. 733 tests passing; svelte-check clean except 2 pre-existing errors on sium/svelte provider (port pending). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
# aapp — ActiveApp
`aapp` is the application-level composition that wires the runtime artifacts
under a single namespace, with a single locale source of truth and a single
logger.
```ts
import { createActiveApp } from '$aapp';
import { translations } from './lang/schema';
const App = createActiveApp({
lang: { schema: translations, defaultLocale: 'es', fallbackChain: ['en'] },
logger: {
level: LogLevel.INFO,
globalContext: { appVersion: '1.0.0', env: 'prod' },
transports: [consoleTransport()]
},
frontend: { theme: 'base', mode: 'auto', density: 'normal' }
});
App.setLocale('es-MX');
App.Lang.t('common.ok');
App.Formats.currency.format(12.5);
App.Frontend.setTheme('forest');
App.Logger.info('boot', 'app ready');
App.dispose();
```
## What it composes
| Member | Always present | Default when not configured |
| -------------- | -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `App.Logger` | yes | engine default — `level: WARN` + `consoleTransport()`. Pass `{ level: LogLevel.NONE, transports: [] }` for silence |
| `App.Lang` | yes | mono — `t('a.b')` returns `'a.b'`, `t('a.b\|Fallback')` returns `'Fallback'`, and DEV warns once per unresolved path through Logger under `lang.mono` |
| `App.Formats` | yes | real, locale = `DEFAULT_LOCALE` (`'en-US'`) |
| `App.Frontend` | yes | real with default theme/mode/density |
| `App.Dom` | yes | real with default breakpoints |
| `App.Storage` | yes | in-memory adapter (resets on reload). Configure `storage: { adapter: localAdapter }` for real persistence; storage diagnostics are wired through the shared Logger |
| `App.Http` | yes | engine default — `globalThis.fetch`, no `baseUrl`, idempotent-by-default retry, 10s per-attempt timeout. The shared `Logger` is wired automatically; configure `http: { baseUrl, timeout, retry }` |
| `App.Timers` | yes | `ActiveTimers` scheduler owned by App. Used by artifacts that need keyed runtime timers (`sess` auto-refresh, `conn` reconnect/heartbeat/ack) and disposed by `App.dispose()` |
| `App.Cache` | yes | `ActiveCache` backed by memory by default. Configure `cache: { adapter, policies, scopeResolver }` for persistence, custom policies or tenant/actor/permission-aware keys |
| `App.Sess` | no | created lazily through `App.createActiveSession(...)`. Logger is injected automatically; storage, refresh/revoke handlers and HTTP hooks remain explicit so auth policy does not become hidden magic |
| `App.Auth` | no | created lazily through `App.createActiveAuth(...)`. App injects `Http` and `Timers`; the server authority remains `$svrs/auth` |
| `Connections` | no | created lazily through `App.createActiveConnections(...)`. App injects Logger, Timers and a structural session bridge; each connection opts into session behavior independently |
Build runtime infrastructure layer: aapp + 5 new artifacts Adds the application composition root and six new runtime artifacts. lang and logr alone could not cover an app surface — locale propagation, format helpers, frontend preferences, validation, persistence and DOM service all needed independent artifacts that aapp wires together under a single locale source of truth and a shared logger. New artifacts: - aapp: composition root. createActiveApp + createTestApp + App.createSiumEngine + frontend.persist + Storage wiring. - stor: pluggable adapters (local/session/memory/cookie + SSR via cookieAdapter.fromCookies), envelope versioning + migrate + TTL, validate via Standard Schema, intra-tab + cross-tab sync, Storage.clear(), per-entry adapter/namespace overrides. - adom: reactive DOM service. shareViewport opt-in + per-window tracker, dispose(). breakpoints, viewport, attribute writes. - fend: frontend preferences (theme, mode, dir, density, reducedMotion, reducedSound) with auto/clear/isAuto pattern. - fmts: localized formatting (numbers, currency, units, dates) with shared LocaleSource and per-domain auto/clear pattern. - sium: validation engine. Standard Schema interop, Lang/Logger injection, codec/refine/transform, domain types (color/date/time), introspection. Existing artifacts extended: - lang: BCP 47 SupportedLocale (LangBase | base-region), mono lang for monolingual apps, extend() leaf-overwrite warning, EngineLang/ActiveLang naming alignment with the rest of the project (no Instance suffix). - logr: EngineLogger.dispose(), failureThrottleMs anti-cascade for transports, README sync to the per-level filter API (minLevel removed). Cross-cutting: - $locale: shared LocaleSource type consumed by fmts and fend. - arts/README.md: artifact map, dependency graph, naming conventions. - Test pages for every artifact under /test/<artifact>. 733 tests passing; svelte-check clean except 2 pre-existing errors on sium/svelte provider (port pending). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
Server-authoritative engines that have a browser reflector live under
`$svrs/*`: use `$svrs/auth` for `createEngineAuth()` and auth HTTP handlers,
`$svrs/perm` for `createEnginePermissions()` and authorization handlers, and
`$svrs/cach` for `createEngineCache()` in services, repositories or server
load code. `aapp` composes only the active/client side.
Build runtime infrastructure layer: aapp + 5 new artifacts Adds the application composition root and six new runtime artifacts. lang and logr alone could not cover an app surface — locale propagation, format helpers, frontend preferences, validation, persistence and DOM service all needed independent artifacts that aapp wires together under a single locale source of truth and a shared logger. New artifacts: - aapp: composition root. createActiveApp + createTestApp + App.createSiumEngine + frontend.persist + Storage wiring. - stor: pluggable adapters (local/session/memory/cookie + SSR via cookieAdapter.fromCookies), envelope versioning + migrate + TTL, validate via Standard Schema, intra-tab + cross-tab sync, Storage.clear(), per-entry adapter/namespace overrides. - adom: reactive DOM service. shareViewport opt-in + per-window tracker, dispose(). breakpoints, viewport, attribute writes. - fend: frontend preferences (theme, mode, dir, density, reducedMotion, reducedSound) with auto/clear/isAuto pattern. - fmts: localized formatting (numbers, currency, units, dates) with shared LocaleSource and per-domain auto/clear pattern. - sium: validation engine. Standard Schema interop, Lang/Logger injection, codec/refine/transform, domain types (color/date/time), introspection. Existing artifacts extended: - lang: BCP 47 SupportedLocale (LangBase | base-region), mono lang for monolingual apps, extend() leaf-overwrite warning, EngineLang/ActiveLang naming alignment with the rest of the project (no Instance suffix). - logr: EngineLogger.dispose(), failureThrottleMs anti-cascade for transports, README sync to the per-level filter API (minLevel removed). Cross-cutting: - $locale: shared LocaleSource type consumed by fmts and fend. - arts/README.md: artifact map, dependency graph, naming conventions. - Test pages for every artifact under /test/<artifact>. 733 tests passing; svelte-check clean except 2 pre-existing errors on sium/svelte provider (port pending). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
`Sium` is **not** a member of App. Validation is page-scoped — pages with
forms construct their own engine via the one-line `App.createSiumEngine()`
method that wires `App.Lang` and `App.Logger` automatically:
```ts
const sium = App.createSiumEngine();
const result = await sium.validate(LoginSchema, input);
```
Add arts/timr, arts/sess, arts/http; sess actor extension; aapp factory New artifacts: arts/timr — runtime timer scheduler (singleton-per-App, never global). Engine + Active split. Race-safe via (id, key, version) guard against stale native callbacks, async tasks resolving after cancel/replace, interval ticks scheduled after dispose, and ack-style timeouts. Per- entry AbortController; intervals reuse the signal across ticks. awaitTask:true (default, no overlap) vs awaitTask:false (fire-and- forget cadence; failures don't stop the interval — semantic frozen). Recursive setTimeout for intervals. scheduleAt(past) → delay 0 (no error). Fake-clock injectable for deterministic tests. Pure computeBackoffDelay helper. 50 server tests + 7 browser tests + full README + DESIGN_TIMR + interactive test page at /test/timr. arts/sess — session lifecycle with three generics (TUser/TCredential/TData) plus optional SessionActor metadata (kind/source/confidence — orthogonal axis to identity). Tagged AdoptResult/RefreshResult/RevokeResult; never void. Generation guard against stale refresh from local cancel, cross-tab storage events, or re-adopt. onRefresh contract (null=fatal, throw=transient). onRevoke replaces revokeUrl (consumer controls fetch; engine just gets boolean). Default scope: 'global' when onRevoke configured. INITIAL_SESSION sync dispatch on subscribe. BroadcastChannel payload: {type, event, generation} only — never tokens. SSR cookie reader validates invariants. withAutoRefresh helper, 401-retry hook with applyAuth + loop guard, JWT exp helper. 103 tests (60 server + 5 browser + 38 actor/error/etc) + README + DESIGN.md + test page at /test/sess. arts/http — HTTP client with Standard Schema body validation, retry + Retry-After, attempt + total timeout via AbortSignal composition, hooks (beforeRequest/beforeRetry/afterResponse/beforeError), tagged HttpResult. Test page at /test/http. arts/conn — DESIGN_CONN.md only (no implementation yet). aapp: - App.createActiveSession<TUser, TCredential, TData>(opts) factory auto-injects App.Logger; throws SessAlreadyCreatedError on second call. App.Sess getter exposes the active session (undefined until first call). Auto-disposed by App.dispose(). - App.Timers integration deferred to timr Fase 3. libs/days: - toEpochMs(value) — permissive coercion (number | Date | string) → epoch ms. Exposed alongside the existing day/calendar helpers. Other: - sium examples moved to _examples/ (excluded from public surface). - sium-provider.svelte test removed (port pending; tracked elsewhere). - libs/env.ts — DEV flag single source of truth. - Various README touch-ups across artifacts. All artifacts: 1021 server tests + 12 browser tests; svelte-check + ESLint clean. The 9 server "errors" are pre-existing jsdom missing — unrelated. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
Equivalent to `createEngineSium({ lang: App.Lang, logger: App.Logger, locale: App.Lang.getLocale() })`.
Build runtime infrastructure layer: aapp + 5 new artifacts Adds the application composition root and six new runtime artifacts. lang and logr alone could not cover an app surface — locale propagation, format helpers, frontend preferences, validation, persistence and DOM service all needed independent artifacts that aapp wires together under a single locale source of truth and a shared logger. New artifacts: - aapp: composition root. createActiveApp + createTestApp + App.createSiumEngine + frontend.persist + Storage wiring. - stor: pluggable adapters (local/session/memory/cookie + SSR via cookieAdapter.fromCookies), envelope versioning + migrate + TTL, validate via Standard Schema, intra-tab + cross-tab sync, Storage.clear(), per-entry adapter/namespace overrides. - adom: reactive DOM service. shareViewport opt-in + per-window tracker, dispose(). breakpoints, viewport, attribute writes. - fend: frontend preferences (theme, mode, dir, density, reducedMotion, reducedSound) with auto/clear/isAuto pattern. - fmts: localized formatting (numbers, currency, units, dates) with shared LocaleSource and per-domain auto/clear pattern. - sium: validation engine. Standard Schema interop, Lang/Logger injection, codec/refine/transform, domain types (color/date/time), introspection. Existing artifacts extended: - lang: BCP 47 SupportedLocale (LangBase | base-region), mono lang for monolingual apps, extend() leaf-overwrite warning, EngineLang/ActiveLang naming alignment with the rest of the project (no Instance suffix). - logr: EngineLogger.dispose(), failureThrottleMs anti-cascade for transports, README sync to the per-level filter API (minLevel removed). Cross-cutting: - $locale: shared LocaleSource type consumed by fmts and fend. - arts/README.md: artifact map, dependency graph, naming conventions. - Test pages for every artifact under /test/<artifact>. 733 tests passing; svelte-check clean except 2 pre-existing errors on sium/svelte provider (port pending). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
Each call returns a fresh engine. The method takes no arguments — Lang,
Logger and the active locale all flow from App, so there is nothing left to
Add arts/timr, arts/sess, arts/http; sess actor extension; aapp factory New artifacts: arts/timr — runtime timer scheduler (singleton-per-App, never global). Engine + Active split. Race-safe via (id, key, version) guard against stale native callbacks, async tasks resolving after cancel/replace, interval ticks scheduled after dispose, and ack-style timeouts. Per- entry AbortController; intervals reuse the signal across ticks. awaitTask:true (default, no overlap) vs awaitTask:false (fire-and- forget cadence; failures don't stop the interval — semantic frozen). Recursive setTimeout for intervals. scheduleAt(past) → delay 0 (no error). Fake-clock injectable for deterministic tests. Pure computeBackoffDelay helper. 50 server tests + 7 browser tests + full README + DESIGN_TIMR + interactive test page at /test/timr. arts/sess — session lifecycle with three generics (TUser/TCredential/TData) plus optional SessionActor metadata (kind/source/confidence — orthogonal axis to identity). Tagged AdoptResult/RefreshResult/RevokeResult; never void. Generation guard against stale refresh from local cancel, cross-tab storage events, or re-adopt. onRefresh contract (null=fatal, throw=transient). onRevoke replaces revokeUrl (consumer controls fetch; engine just gets boolean). Default scope: 'global' when onRevoke configured. INITIAL_SESSION sync dispatch on subscribe. BroadcastChannel payload: {type, event, generation} only — never tokens. SSR cookie reader validates invariants. withAutoRefresh helper, 401-retry hook with applyAuth + loop guard, JWT exp helper. 103 tests (60 server + 5 browser + 38 actor/error/etc) + README + DESIGN.md + test page at /test/sess. arts/http — HTTP client with Standard Schema body validation, retry + Retry-After, attempt + total timeout via AbortSignal composition, hooks (beforeRequest/beforeRetry/afterResponse/beforeError), tagged HttpResult. Test page at /test/http. arts/conn — DESIGN_CONN.md only (no implementation yet). aapp: - App.createActiveSession<TUser, TCredential, TData>(opts) factory auto-injects App.Logger; throws SessAlreadyCreatedError on second call. App.Sess getter exposes the active session (undefined until first call). Auto-disposed by App.dispose(). - App.Timers integration deferred to timr Fase 3. libs/days: - toEpochMs(value) — permissive coercion (number | Date | string) → epoch ms. Exposed alongside the existing day/calendar helpers. Other: - sium examples moved to _examples/ (excluded from public surface). - sium-provider.svelte test removed (port pending; tracked elsewhere). - libs/env.ts — DEV flag single source of truth. - Various README touch-ups across artifacts. All artifacts: 1021 server tests + 12 browser tests; svelte-check + ESLint clean. The 9 server "errors" are pre-existing jsdom missing — unrelated. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
override at this layer.
The `locale` passed is a **snapshot** of `App.Lang.getLocale()` at the
moment of construction. It is the fallback used when the caller invokes
`sium.resolveIssue(issue)` without an explicit locale; the snapshot does
not react to subsequent `App.setLocale(...)` calls. Pages that need
locale-reactive issue messages either pass `App.Lang.getLocale()` per call
(`sium.resolveIssue(issue, App.Lang.getLocale())`) or rebuild the engine
inside an `$effect` that depends on the locale. If a page needs a custom
Sium engine (different logger category, different locale default, etc.) it
constructs `createEngineSium(...)` directly from `$sium`.
Build runtime infrastructure layer: aapp + 5 new artifacts Adds the application composition root and six new runtime artifacts. lang and logr alone could not cover an app surface — locale propagation, format helpers, frontend preferences, validation, persistence and DOM service all needed independent artifacts that aapp wires together under a single locale source of truth and a shared logger. New artifacts: - aapp: composition root. createActiveApp + createTestApp + App.createSiumEngine + frontend.persist + Storage wiring. - stor: pluggable adapters (local/session/memory/cookie + SSR via cookieAdapter.fromCookies), envelope versioning + migrate + TTL, validate via Standard Schema, intra-tab + cross-tab sync, Storage.clear(), per-entry adapter/namespace overrides. - adom: reactive DOM service. shareViewport opt-in + per-window tracker, dispose(). breakpoints, viewport, attribute writes. - fend: frontend preferences (theme, mode, dir, density, reducedMotion, reducedSound) with auto/clear/isAuto pattern. - fmts: localized formatting (numbers, currency, units, dates) with shared LocaleSource and per-domain auto/clear pattern. - sium: validation engine. Standard Schema interop, Lang/Logger injection, codec/refine/transform, domain types (color/date/time), introspection. Existing artifacts extended: - lang: BCP 47 SupportedLocale (LangBase | base-region), mono lang for monolingual apps, extend() leaf-overwrite warning, EngineLang/ActiveLang naming alignment with the rest of the project (no Instance suffix). - logr: EngineLogger.dispose(), failureThrottleMs anti-cascade for transports, README sync to the per-level filter API (minLevel removed). Cross-cutting: - $locale: shared LocaleSource type consumed by fmts and fend. - arts/README.md: artifact map, dependency graph, naming conventions. - Test pages for every artifact under /test/<artifact>. 733 tests passing; svelte-check clean except 2 pre-existing errors on sium/svelte provider (port pending). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
The method lives on App rather than as a standalone helper because App is
already in scope on every page via context — `App.createSiumEngine()` is
the natural call site.
`Connections` is also lazy, but for the opposite reason: realtime is
application-scoped infrastructure, while the connection map is app-specific and
benefits from call-site generics:
```ts
const Connections = App.createActiveConnections<AppConnections>();
```
Each registry is disposed by `App.dispose()`. Individual connections decide
whether they react to session refresh/expire events via their own `session`
option.
Build runtime infrastructure layer: aapp + 5 new artifacts Adds the application composition root and six new runtime artifacts. lang and logr alone could not cover an app surface — locale propagation, format helpers, frontend preferences, validation, persistence and DOM service all needed independent artifacts that aapp wires together under a single locale source of truth and a shared logger. New artifacts: - aapp: composition root. createActiveApp + createTestApp + App.createSiumEngine + frontend.persist + Storage wiring. - stor: pluggable adapters (local/session/memory/cookie + SSR via cookieAdapter.fromCookies), envelope versioning + migrate + TTL, validate via Standard Schema, intra-tab + cross-tab sync, Storage.clear(), per-entry adapter/namespace overrides. - adom: reactive DOM service. shareViewport opt-in + per-window tracker, dispose(). breakpoints, viewport, attribute writes. - fend: frontend preferences (theme, mode, dir, density, reducedMotion, reducedSound) with auto/clear/isAuto pattern. - fmts: localized formatting (numbers, currency, units, dates) with shared LocaleSource and per-domain auto/clear pattern. - sium: validation engine. Standard Schema interop, Lang/Logger injection, codec/refine/transform, domain types (color/date/time), introspection. Existing artifacts extended: - lang: BCP 47 SupportedLocale (LangBase | base-region), mono lang for monolingual apps, extend() leaf-overwrite warning, EngineLang/ActiveLang naming alignment with the rest of the project (no Instance suffix). - logr: EngineLogger.dispose(), failureThrottleMs anti-cascade for transports, README sync to the per-level filter API (minLevel removed). Cross-cutting: - $locale: shared LocaleSource type consumed by fmts and fend. - arts/README.md: artifact map, dependency graph, naming conventions. - Test pages for every artifact under /test/<artifact>. 733 tests passing; svelte-check clean except 2 pre-existing errors on sium/svelte provider (port pending). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
## What it solves
- **Single locale source.** `App.setLocale('es-MX')` propagates to `Lang`,
`Formats` and `Frontend` through a shared `LocaleSource`. No bridge code per
call site.
- **Single logger.** Built once and piped into `Lang.setLogger` so every
artifact emits structured entries through the same transports (console,
Sentry, Datadog, ...).
- **Uniform call sites.** `App.Lang.t(label)` and `App.Formats.*` always work,
whether or not the caller configured i18n or fmts. No null checks.
- **Single lifecycle.** `App.dispose()` tears down the optional session,
timers, persistence bridge, frontend, dom, formats, storage, lang and logger
in a deterministic order.
Build runtime infrastructure layer: aapp + 5 new artifacts Adds the application composition root and six new runtime artifacts. lang and logr alone could not cover an app surface — locale propagation, format helpers, frontend preferences, validation, persistence and DOM service all needed independent artifacts that aapp wires together under a single locale source of truth and a shared logger. New artifacts: - aapp: composition root. createActiveApp + createTestApp + App.createSiumEngine + frontend.persist + Storage wiring. - stor: pluggable adapters (local/session/memory/cookie + SSR via cookieAdapter.fromCookies), envelope versioning + migrate + TTL, validate via Standard Schema, intra-tab + cross-tab sync, Storage.clear(), per-entry adapter/namespace overrides. - adom: reactive DOM service. shareViewport opt-in + per-window tracker, dispose(). breakpoints, viewport, attribute writes. - fend: frontend preferences (theme, mode, dir, density, reducedMotion, reducedSound) with auto/clear/isAuto pattern. - fmts: localized formatting (numbers, currency, units, dates) with shared LocaleSource and per-domain auto/clear pattern. - sium: validation engine. Standard Schema interop, Lang/Logger injection, codec/refine/transform, domain types (color/date/time), introspection. Existing artifacts extended: - lang: BCP 47 SupportedLocale (LangBase | base-region), mono lang for monolingual apps, extend() leaf-overwrite warning, EngineLang/ActiveLang naming alignment with the rest of the project (no Instance suffix). - logr: EngineLogger.dispose(), failureThrottleMs anti-cascade for transports, README sync to the per-level filter API (minLevel removed). Cross-cutting: - $locale: shared LocaleSource type consumed by fmts and fend. - arts/README.md: artifact map, dependency graph, naming conventions. - Test pages for every artifact under /test/<artifact>. 733 tests passing; svelte-check clean except 2 pre-existing errors on sium/svelte provider (port pending). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
## Composition order
1. **Logger** — `createEngineLogger(options.logger)`. The engine applies its
own defaults when `options.logger` is undefined.
2. **Lang** — real `createActiveLang(...)` when `options.lang.schema` is
provided; mono otherwise. Both wire `Lang.setLogger` to the shared
Logger.
3. **Storage** — built next so Frontend can read persisted preferences
before construction. Storage diagnostics are wired to the shared Logger.
4. **Formats** — built with a `localeSource` derived from Lang.
5. **Dom** — built before Frontend.
6. **Frontend** — receives Dom and the same `localeSource`. When
`frontend.persist` is configured, persisted values seed the initial
options and `onPreferenceChange` is wired to write back to Storage.
7. **Http** — built with the shared `Logger` injected automatically so
request/retry/error events land under category `'http'`. In SvelteKit
`load`, scope to the request via `App.Http.with({ fetch: event.fetch })`.
8. **Timers** — built with the shared `Logger`. This is the App-owned
scheduler used by long-lived runtime tasks; no module-global singleton.
9. **Cache** — built with the shared `Logger`. It is always present with a
memory adapter unless `cache.adapter` is configured. Scopes remain explicit
through each query and can use `cache.scopeResolver`.
10. **Sess** — created lazily via `App.createActiveSession(...)`, not from
`createActiveApp(...)` options. App injects Logger, but the consumer keeps
auth policy explicit (`storage`, `onRefresh`, `onRevoke`, HTTP hooks).
Build runtime infrastructure layer: aapp + 5 new artifacts Adds the application composition root and six new runtime artifacts. lang and logr alone could not cover an app surface — locale propagation, format helpers, frontend preferences, validation, persistence and DOM service all needed independent artifacts that aapp wires together under a single locale source of truth and a shared logger. New artifacts: - aapp: composition root. createActiveApp + createTestApp + App.createSiumEngine + frontend.persist + Storage wiring. - stor: pluggable adapters (local/session/memory/cookie + SSR via cookieAdapter.fromCookies), envelope versioning + migrate + TTL, validate via Standard Schema, intra-tab + cross-tab sync, Storage.clear(), per-entry adapter/namespace overrides. - adom: reactive DOM service. shareViewport opt-in + per-window tracker, dispose(). breakpoints, viewport, attribute writes. - fend: frontend preferences (theme, mode, dir, density, reducedMotion, reducedSound) with auto/clear/isAuto pattern. - fmts: localized formatting (numbers, currency, units, dates) with shared LocaleSource and per-domain auto/clear pattern. - sium: validation engine. Standard Schema interop, Lang/Logger injection, codec/refine/transform, domain types (color/date/time), introspection. Existing artifacts extended: - lang: BCP 47 SupportedLocale (LangBase | base-region), mono lang for monolingual apps, extend() leaf-overwrite warning, EngineLang/ActiveLang naming alignment with the rest of the project (no Instance suffix). - logr: EngineLogger.dispose(), failureThrottleMs anti-cascade for transports, README sync to the per-level filter API (minLevel removed). Cross-cutting: - $locale: shared LocaleSource type consumed by fmts and fend. - arts/README.md: artifact map, dependency graph, naming conventions. - Test pages for every artifact under /test/<artifact>. 733 tests passing; svelte-check clean except 2 pre-existing errors on sium/svelte provider (port pending). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
`dispose()` runs in reverse order.
## Common shapes
### Full multilingual app
```ts
const App = createActiveApp({
lang: { schema, defaultLocale: 'es', fallbackChain: ['en'] },
logger: { level: LogLevel.INFO, transports: [consoleTransport()] },
frontend: { theme: 'base', mode: 'auto' }
});
```
### Monolingual app with fixed currency
```ts
const App = createActiveApp({
formats: { currency: { currency: 'EUR' } },
frontend: { theme: 'base' }
});
App.Formats.currency.format(99.5); // "99,50 €" with default locale
```
`App.Lang` is mono — components calling `App.Lang.t('actions.save|Save')`
render `'Save'` without ever loading a translation table.
### Headless / API surface
```ts
const App = createActiveApp({
logger: { level: LogLevel.WARN, transports: [httpTransport({ url })] }
});
```
Frontend and Dom are still constructed but their browser-only effects (viewport
tracking, attribute writes) no-op in SSR.
## Locale flow
Lang is the single source of truth. Formats and Frontend subscribe to it via a
common `LocaleSource` (`$locale`). The locale value is BCP 47:
```ts
App.setLocale('es'); // bare base
App.setLocale('es-MX'); // exact regional variant
App.setLocale('pt-BR'); // works end-to-end
```
See `$lang/README.md` for the BCP 47 resolution rules in `Lang.t()` /
`Lang.ts()`.
When `lang` is not configured, `App.setLocale` still updates the mono lang's
internal locale and notifies Formats/Frontend — locale switching keeps working.
### SSR locale resolution + hydration
`createActiveApp(...)` does **not** read `navigator.language`. That is a
deliberate decision: reading the navigator on the client while the server
rendered with a different locale produces a hydration mismatch and a
one-frame text flash. Locale is the app's responsibility — resolve it on the
server, pass it as data to the client, and use it as `defaultLocale` when
constructing App.
The canonical SvelteKit pattern:
```ts
// src/web/routes/+layout.server.ts
import type { LayoutServerLoad } from './$types';
const SUPPORTED = ['es', 'en', 'es-MX', 'es-AR', 'en-GB', 'pt-BR'] as const;
const DEFAULT = 'es';
function pickLocale(accept: string | null, supported: readonly string[]): string {
if (!accept) return DEFAULT;
const ranked = accept
.split(',')
.map((entry) => {
const [tag, q] = entry.trim().split(';q=');
return { tag: tag.toLowerCase(), q: q ? Number(q) : 1 };
})
.sort((a, b) => b.q - a.q);
for (const { tag } of ranked) {
// Exact BCP 47 match first, then base.
if (supported.includes(tag)) return tag;
const base = tag.split('-')[0];
if (supported.includes(base)) return base;
}
return DEFAULT;
}
export const load: LayoutServerLoad = ({ request, cookies }) => {
const cookie = cookies.get('locale');
if (cookie && SUPPORTED.includes(cookie)) return { locale: cookie };
const locale = pickLocale(request.headers.get('accept-language'), SUPPORTED);
return { locale };
};
```
```svelte
<!-- src/web/routes/+layout.svelte -->
<script lang="ts">
import { setContext, onDestroy } from 'svelte';
import { createActiveApp } from '$aapp';
import { translations } from '$lib/lang/schema';
let { data, children } = $props();
const App = createActiveApp({
lang: { schema: translations, defaultLocale: data.locale, fallbackChain: ['en'] },
logger: {
/* ... */
}
});
setContext('app', App);
onDestroy(() => App.dispose());
</script>
{@render children()}
```
Server and client agree on the locale on first render — no mismatch, no flash.
To let the user change locale at runtime, persist the choice to a cookie so
the next request re-renders with the same value:
```ts
async function changeLocale(locale: SupportedLocale): Promise<void> {
App.setLocale(locale);
document.cookie = `locale=${locale}; path=/; max-age=31536000; SameSite=Lax`;
}
```
If you genuinely want to honor `navigator.language` on first visit, do it
once in the server load when no cookie exists and no `Accept-Language` is
set — never on the client.
## Storage
`App.Storage` is always present. Without configuration it uses an in-memory
adapter — values exist for the lifetime of the App and never persist. For
real persistence, pass an adapter:
```ts
import { createActiveApp, localAdapter } from '$aapp';
const App = createActiveApp({
storage: { adapter: localAdapter, namespace: 'my-app' }
});
const cart = App.Storage.entry('cart', { items: [] as string[] });
cart.update((p) => ({ ...p, items: [...p.items, 'sku-42'] }));
```
Per-entry overrides let you mix backends — cookies for SSR-readable values,
localStorage for the rest:
```ts
import { createActiveApp, localAdapter, cookieAdapter } from '$aapp';
const App = createActiveApp({
storage: { adapter: localAdapter, namespace: 'my-app' }
});
const locale = App.Storage.entry('locale', 'es', {
adapter: cookieAdapter({ path: '/', maxAge: 31_536_000 }),
namespace: false,
raw: true
});
```
Storage diagnostics are wired automatically through `StorageDiagnostics` and
the shared `App.Logger`; failures include `{ adapter, key, fullKey, op, error }`
in the diagnostic context. See `$stor/README.md` for the full API (adapters,
envelope, versioning, validation).
Build runtime infrastructure layer: aapp + 5 new artifacts Adds the application composition root and six new runtime artifacts. lang and logr alone could not cover an app surface — locale propagation, format helpers, frontend preferences, validation, persistence and DOM service all needed independent artifacts that aapp wires together under a single locale source of truth and a shared logger. New artifacts: - aapp: composition root. createActiveApp + createTestApp + App.createSiumEngine + frontend.persist + Storage wiring. - stor: pluggable adapters (local/session/memory/cookie + SSR via cookieAdapter.fromCookies), envelope versioning + migrate + TTL, validate via Standard Schema, intra-tab + cross-tab sync, Storage.clear(), per-entry adapter/namespace overrides. - adom: reactive DOM service. shareViewport opt-in + per-window tracker, dispose(). breakpoints, viewport, attribute writes. - fend: frontend preferences (theme, mode, dir, density, reducedMotion, reducedSound) with auto/clear/isAuto pattern. - fmts: localized formatting (numbers, currency, units, dates) with shared LocaleSource and per-domain auto/clear pattern. - sium: validation engine. Standard Schema interop, Lang/Logger injection, codec/refine/transform, domain types (color/date/time), introspection. Existing artifacts extended: - lang: BCP 47 SupportedLocale (LangBase | base-region), mono lang for monolingual apps, extend() leaf-overwrite warning, EngineLang/ActiveLang naming alignment with the rest of the project (no Instance suffix). - logr: EngineLogger.dispose(), failureThrottleMs anti-cascade for transports, README sync to the per-level filter API (minLevel removed). Cross-cutting: - $locale: shared LocaleSource type consumed by fmts and fend. - arts/README.md: artifact map, dependency graph, naming conventions. - Test pages for every artifact under /test/<artifact>. 733 tests passing; svelte-check clean except 2 pre-existing errors on sium/svelte provider (port pending). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
### Reactive keys
When the storage key tracks a runed variable (current user, active
workspace, route param), use `App.Storage.dynamicEntry()`:
```svelte
<script lang="ts">
let userId = $state(1);
const profile = App.Storage.dynamicEntry(
() => `user-${userId}:profile`,
() => ({ name: '', cart: [] as string[] })
);
// userId = 2 → profile rebinds to 'user-2:profile' (previous entry
// disposed, onChange listeners migrate automatically).
</script>
```
Must run inside a Svelte component or `$effect.root` scope.
### Cross-tab sync without polling
Wrap any adapter with `withBroadcast` (re-exported from `$aapp`) for
instant cross-tab synchronization through `BroadcastChannel`:
```ts
import { createActiveApp, localAdapter, cookieAdapter, withBroadcast } from '$aapp';
const App = createActiveApp({
storage: {
adapter: withBroadcast(localAdapter, { channel: 'my-app' }),
namespace: 'my-app'
}
});
// Cookies + broadcast = changes propagate across tabs the moment they
// happen (browsers do not emit a native event for cookie mutations).
const session = withBroadcast(cookieAdapter({ path: '/', maxAge: 3600 }), {
channel: 'my-app:session'
});
```
Build runtime infrastructure layer: aapp + 5 new artifacts Adds the application composition root and six new runtime artifacts. lang and logr alone could not cover an app surface — locale propagation, format helpers, frontend preferences, validation, persistence and DOM service all needed independent artifacts that aapp wires together under a single locale source of truth and a shared logger. New artifacts: - aapp: composition root. createActiveApp + createTestApp + App.createSiumEngine + frontend.persist + Storage wiring. - stor: pluggable adapters (local/session/memory/cookie + SSR via cookieAdapter.fromCookies), envelope versioning + migrate + TTL, validate via Standard Schema, intra-tab + cross-tab sync, Storage.clear(), per-entry adapter/namespace overrides. - adom: reactive DOM service. shareViewport opt-in + per-window tracker, dispose(). breakpoints, viewport, attribute writes. - fend: frontend preferences (theme, mode, dir, density, reducedMotion, reducedSound) with auto/clear/isAuto pattern. - fmts: localized formatting (numbers, currency, units, dates) with shared LocaleSource and per-domain auto/clear pattern. - sium: validation engine. Standard Schema interop, Lang/Logger injection, codec/refine/transform, domain types (color/date/time), introspection. Existing artifacts extended: - lang: BCP 47 SupportedLocale (LangBase | base-region), mono lang for monolingual apps, extend() leaf-overwrite warning, EngineLang/ActiveLang naming alignment with the rest of the project (no Instance suffix). - logr: EngineLogger.dispose(), failureThrottleMs anti-cascade for transports, README sync to the per-level filter API (minLevel removed). Cross-cutting: - $locale: shared LocaleSource type consumed by fmts and fend. - arts/README.md: artifact map, dependency graph, naming conventions. - Test pages for every artifact under /test/<artifact>. 733 tests passing; svelte-check clean except 2 pre-existing errors on sium/svelte provider (port pending). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
### Persisting Frontend preferences
Theme, mode, density, dir, reducedMotion, reducedSound can be persisted with
a single flag:
```ts
const App = createActiveApp({
storage: { adapter: localAdapter, namespace: 'my-app' },
frontend: { theme: 'base', persist: true }
});
App.Frontend.setTheme('forest'); // → written to localStorage
// next reload → Frontend reads 'forest' from storage during construction
```
Selective + per-key overrides:
```ts
import { createActiveApp, localAdapter, cookieAdapter } from '$aapp';
const App = createActiveApp({
storage: { adapter: localAdapter, namespace: 'my-app' },
frontend: {
theme: 'base',
persist: {
keys: ['theme', 'density', 'mode'],
overrides: {
// theme to a cookie so the server can render the right palette
theme: { adapter: cookieAdapter({ path: '/' }), namespace: false, raw: true }
}
}
}
});
```
When `persist` is set but no persistent adapter is configured (the default
in-memory adapter is in use), values still flow through Storage — they just
do not survive reload. No warning is emitted; the absence of persistence is
visible in the storage adapter the caller chose.
## State primitive
aapp does **not** include a stores system. Svelte 5 + runes already provide
the primitive: a `.svelte.ts` module with `$state` is your store, scoped to
import graph rather than to a global registry.
```ts
// src/lib/stores/cart.svelte.ts
let items = $state<CartItem[]>([]);
export const cart = {
get items() {
return items;
},
add(item: CartItem) {
items.push(item);
},
clear() {
items = [];
}
};
```
Pages and components import `cart` directly. The "infrastructure" artifacts
(Logger, Lang, Formats, Frontend, Dom) live in App because they are
cross-cutting and need uniform configuration. Domain state (current user,
cart, session, feature flags) is application-specific — putting it under
`App.Stores` would couple the framework to a bucket of unrelated nouns.
For a Pinia/Zustand-style central registry, build it in user space — it does
not belong in `aapp`.
## Testing
Use `createTestApp(options)` instead of `createActiveApp(options)` in unit
tests. Same shape, plus:
- silent logger by default (no console pollution)
- `captureLogs: true` attaches a sink and exposes entries as `App.entries`
Add arts/timr, arts/sess, arts/http; sess actor extension; aapp factory New artifacts: arts/timr — runtime timer scheduler (singleton-per-App, never global). Engine + Active split. Race-safe via (id, key, version) guard against stale native callbacks, async tasks resolving after cancel/replace, interval ticks scheduled after dispose, and ack-style timeouts. Per- entry AbortController; intervals reuse the signal across ticks. awaitTask:true (default, no overlap) vs awaitTask:false (fire-and- forget cadence; failures don't stop the interval — semantic frozen). Recursive setTimeout for intervals. scheduleAt(past) → delay 0 (no error). Fake-clock injectable for deterministic tests. Pure computeBackoffDelay helper. 50 server tests + 7 browser tests + full README + DESIGN_TIMR + interactive test page at /test/timr. arts/sess — session lifecycle with three generics (TUser/TCredential/TData) plus optional SessionActor metadata (kind/source/confidence — orthogonal axis to identity). Tagged AdoptResult/RefreshResult/RevokeResult; never void. Generation guard against stale refresh from local cancel, cross-tab storage events, or re-adopt. onRefresh contract (null=fatal, throw=transient). onRevoke replaces revokeUrl (consumer controls fetch; engine just gets boolean). Default scope: 'global' when onRevoke configured. INITIAL_SESSION sync dispatch on subscribe. BroadcastChannel payload: {type, event, generation} only — never tokens. SSR cookie reader validates invariants. withAutoRefresh helper, 401-retry hook with applyAuth + loop guard, JWT exp helper. 103 tests (60 server + 5 browser + 38 actor/error/etc) + README + DESIGN.md + test page at /test/sess. arts/http — HTTP client with Standard Schema body validation, retry + Retry-After, attempt + total timeout via AbortSignal composition, hooks (beforeRequest/beforeRetry/afterResponse/beforeError), tagged HttpResult. Test page at /test/http. arts/conn — DESIGN_CONN.md only (no implementation yet). aapp: - App.createActiveSession<TUser, TCredential, TData>(opts) factory auto-injects App.Logger; throws SessAlreadyCreatedError on second call. App.Sess getter exposes the active session (undefined until first call). Auto-disposed by App.dispose(). - App.Timers integration deferred to timr Fase 3. libs/days: - toEpochMs(value) — permissive coercion (number | Date | string) → epoch ms. Exposed alongside the existing day/calendar helpers. Other: - sium examples moved to _examples/ (excluded from public surface). - sium-provider.svelte test removed (port pending; tracked elsewhere). - libs/env.ts — DEV flag single source of truth. - Various README touch-ups across artifacts. All artifacts: 1021 server tests + 12 browser tests; svelte-check + ESLint clean. The 9 server "errors" are pre-existing jsdom missing — unrelated. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
`createTestApp` lives at the `$aapp/testing` subpath so it does not ship with
production bundles that import the main `$aapp` barrel:
Build runtime infrastructure layer: aapp + 5 new artifacts Adds the application composition root and six new runtime artifacts. lang and logr alone could not cover an app surface — locale propagation, format helpers, frontend preferences, validation, persistence and DOM service all needed independent artifacts that aapp wires together under a single locale source of truth and a shared logger. New artifacts: - aapp: composition root. createActiveApp + createTestApp + App.createSiumEngine + frontend.persist + Storage wiring. - stor: pluggable adapters (local/session/memory/cookie + SSR via cookieAdapter.fromCookies), envelope versioning + migrate + TTL, validate via Standard Schema, intra-tab + cross-tab sync, Storage.clear(), per-entry adapter/namespace overrides. - adom: reactive DOM service. shareViewport opt-in + per-window tracker, dispose(). breakpoints, viewport, attribute writes. - fend: frontend preferences (theme, mode, dir, density, reducedMotion, reducedSound) with auto/clear/isAuto pattern. - fmts: localized formatting (numbers, currency, units, dates) with shared LocaleSource and per-domain auto/clear pattern. - sium: validation engine. Standard Schema interop, Lang/Logger injection, codec/refine/transform, domain types (color/date/time), introspection. Existing artifacts extended: - lang: BCP 47 SupportedLocale (LangBase | base-region), mono lang for monolingual apps, extend() leaf-overwrite warning, EngineLang/ActiveLang naming alignment with the rest of the project (no Instance suffix). - logr: EngineLogger.dispose(), failureThrottleMs anti-cascade for transports, README sync to the per-level filter API (minLevel removed). Cross-cutting: - $locale: shared LocaleSource type consumed by fmts and fend. - arts/README.md: artifact map, dependency graph, naming conventions. - Test pages for every artifact under /test/<artifact>. 733 tests passing; svelte-check clean except 2 pre-existing errors on sium/svelte provider (port pending). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
```ts
Add arts/timr, arts/sess, arts/http; sess actor extension; aapp factory New artifacts: arts/timr — runtime timer scheduler (singleton-per-App, never global). Engine + Active split. Race-safe via (id, key, version) guard against stale native callbacks, async tasks resolving after cancel/replace, interval ticks scheduled after dispose, and ack-style timeouts. Per- entry AbortController; intervals reuse the signal across ticks. awaitTask:true (default, no overlap) vs awaitTask:false (fire-and- forget cadence; failures don't stop the interval — semantic frozen). Recursive setTimeout for intervals. scheduleAt(past) → delay 0 (no error). Fake-clock injectable for deterministic tests. Pure computeBackoffDelay helper. 50 server tests + 7 browser tests + full README + DESIGN_TIMR + interactive test page at /test/timr. arts/sess — session lifecycle with three generics (TUser/TCredential/TData) plus optional SessionActor metadata (kind/source/confidence — orthogonal axis to identity). Tagged AdoptResult/RefreshResult/RevokeResult; never void. Generation guard against stale refresh from local cancel, cross-tab storage events, or re-adopt. onRefresh contract (null=fatal, throw=transient). onRevoke replaces revokeUrl (consumer controls fetch; engine just gets boolean). Default scope: 'global' when onRevoke configured. INITIAL_SESSION sync dispatch on subscribe. BroadcastChannel payload: {type, event, generation} only — never tokens. SSR cookie reader validates invariants. withAutoRefresh helper, 401-retry hook with applyAuth + loop guard, JWT exp helper. 103 tests (60 server + 5 browser + 38 actor/error/etc) + README + DESIGN.md + test page at /test/sess. arts/http — HTTP client with Standard Schema body validation, retry + Retry-After, attempt + total timeout via AbortSignal composition, hooks (beforeRequest/beforeRetry/afterResponse/beforeError), tagged HttpResult. Test page at /test/http. arts/conn — DESIGN_CONN.md only (no implementation yet). aapp: - App.createActiveSession<TUser, TCredential, TData>(opts) factory auto-injects App.Logger; throws SessAlreadyCreatedError on second call. App.Sess getter exposes the active session (undefined until first call). Auto-disposed by App.dispose(). - App.Timers integration deferred to timr Fase 3. libs/days: - toEpochMs(value) — permissive coercion (number | Date | string) → epoch ms. Exposed alongside the existing day/calendar helpers. Other: - sium examples moved to _examples/ (excluded from public surface). - sium-provider.svelte test removed (port pending; tracked elsewhere). - libs/env.ts — DEV flag single source of truth. - Various README touch-ups across artifacts. All artifacts: 1021 server tests + 12 browser tests; svelte-check + ESLint clean. The 9 server "errors" are pre-existing jsdom missing — unrelated. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
import { createTestApp } from '$aapp/testing';
Build runtime infrastructure layer: aapp + 5 new artifacts Adds the application composition root and six new runtime artifacts. lang and logr alone could not cover an app surface — locale propagation, format helpers, frontend preferences, validation, persistence and DOM service all needed independent artifacts that aapp wires together under a single locale source of truth and a shared logger. New artifacts: - aapp: composition root. createActiveApp + createTestApp + App.createSiumEngine + frontend.persist + Storage wiring. - stor: pluggable adapters (local/session/memory/cookie + SSR via cookieAdapter.fromCookies), envelope versioning + migrate + TTL, validate via Standard Schema, intra-tab + cross-tab sync, Storage.clear(), per-entry adapter/namespace overrides. - adom: reactive DOM service. shareViewport opt-in + per-window tracker, dispose(). breakpoints, viewport, attribute writes. - fend: frontend preferences (theme, mode, dir, density, reducedMotion, reducedSound) with auto/clear/isAuto pattern. - fmts: localized formatting (numbers, currency, units, dates) with shared LocaleSource and per-domain auto/clear pattern. - sium: validation engine. Standard Schema interop, Lang/Logger injection, codec/refine/transform, domain types (color/date/time), introspection. Existing artifacts extended: - lang: BCP 47 SupportedLocale (LangBase | base-region), mono lang for monolingual apps, extend() leaf-overwrite warning, EngineLang/ActiveLang naming alignment with the rest of the project (no Instance suffix). - logr: EngineLogger.dispose(), failureThrottleMs anti-cascade for transports, README sync to the per-level filter API (minLevel removed). Cross-cutting: - $locale: shared LocaleSource type consumed by fmts and fend. - arts/README.md: artifact map, dependency graph, naming conventions. - Test pages for every artifact under /test/<artifact>. 733 tests passing; svelte-check clean except 2 pre-existing errors on sium/svelte provider (port pending). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
const App = createTestApp({ captureLogs: true, lang: { schema } });
App.Logger.warn('auth', 'token expiring');
expect(App.entries).toHaveLength(1);
expect(App.entries[0].category).toBe('auth');
App.dispose();
```
If the caller passes their own `logger.transports`, the capture transport is
appended — both sinks receive every entry.
## API
```ts
interface ActiveAppOptions<S extends LangNode> {
logger?: LoggerOptions;
lang?: { schema: S; defaultLocale?: SupportedLocale; fallbackChain?: SupportedLocale[] };
formats?: Omit<ActiveFormatsOptions, 'locale' | 'localeSource'>;
frontend?: Omit<ActiveFrontendOptions, 'locale' | 'localeSource' | 'dom'> & {
persist?: FrontendPersist;
};
Build runtime infrastructure layer: aapp + 5 new artifacts Adds the application composition root and six new runtime artifacts. lang and logr alone could not cover an app surface — locale propagation, format helpers, frontend preferences, validation, persistence and DOM service all needed independent artifacts that aapp wires together under a single locale source of truth and a shared logger. New artifacts: - aapp: composition root. createActiveApp + createTestApp + App.createSiumEngine + frontend.persist + Storage wiring. - stor: pluggable adapters (local/session/memory/cookie + SSR via cookieAdapter.fromCookies), envelope versioning + migrate + TTL, validate via Standard Schema, intra-tab + cross-tab sync, Storage.clear(), per-entry adapter/namespace overrides. - adom: reactive DOM service. shareViewport opt-in + per-window tracker, dispose(). breakpoints, viewport, attribute writes. - fend: frontend preferences (theme, mode, dir, density, reducedMotion, reducedSound) with auto/clear/isAuto pattern. - fmts: localized formatting (numbers, currency, units, dates) with shared LocaleSource and per-domain auto/clear pattern. - sium: validation engine. Standard Schema interop, Lang/Logger injection, codec/refine/transform, domain types (color/date/time), introspection. Existing artifacts extended: - lang: BCP 47 SupportedLocale (LangBase | base-region), mono lang for monolingual apps, extend() leaf-overwrite warning, EngineLang/ActiveLang naming alignment with the rest of the project (no Instance suffix). - logr: EngineLogger.dispose(), failureThrottleMs anti-cascade for transports, README sync to the per-level filter API (minLevel removed). Cross-cutting: - $locale: shared LocaleSource type consumed by fmts and fend. - arts/README.md: artifact map, dependency graph, naming conventions. - Test pages for every artifact under /test/<artifact>. 733 tests passing; svelte-check clean except 2 pre-existing errors on sium/svelte provider (port pending). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
dom?: ActiveDomProps;
storage?: ActiveAppStorageOptions;
http?: Omit<EngineHttpOptions, 'logger'>;
timers?: Omit<EngineTimersOptions, 'logger'>;
cache?: Omit<ActiveCacheOptions, 'logger'>;
connections?: Omit<ActiveConnectionsOptions, 'logger' | 'timers' | 'session'>;
Build runtime infrastructure layer: aapp + 5 new artifacts Adds the application composition root and six new runtime artifacts. lang and logr alone could not cover an app surface — locale propagation, format helpers, frontend preferences, validation, persistence and DOM service all needed independent artifacts that aapp wires together under a single locale source of truth and a shared logger. New artifacts: - aapp: composition root. createActiveApp + createTestApp + App.createSiumEngine + frontend.persist + Storage wiring. - stor: pluggable adapters (local/session/memory/cookie + SSR via cookieAdapter.fromCookies), envelope versioning + migrate + TTL, validate via Standard Schema, intra-tab + cross-tab sync, Storage.clear(), per-entry adapter/namespace overrides. - adom: reactive DOM service. shareViewport opt-in + per-window tracker, dispose(). breakpoints, viewport, attribute writes. - fend: frontend preferences (theme, mode, dir, density, reducedMotion, reducedSound) with auto/clear/isAuto pattern. - fmts: localized formatting (numbers, currency, units, dates) with shared LocaleSource and per-domain auto/clear pattern. - sium: validation engine. Standard Schema interop, Lang/Logger injection, codec/refine/transform, domain types (color/date/time), introspection. Existing artifacts extended: - lang: BCP 47 SupportedLocale (LangBase | base-region), mono lang for monolingual apps, extend() leaf-overwrite warning, EngineLang/ActiveLang naming alignment with the rest of the project (no Instance suffix). - logr: EngineLogger.dispose(), failureThrottleMs anti-cascade for transports, README sync to the per-level filter API (minLevel removed). Cross-cutting: - $locale: shared LocaleSource type consumed by fmts and fend. - arts/README.md: artifact map, dependency graph, naming conventions. - Test pages for every artifact under /test/<artifact>. 733 tests passing; svelte-check clean except 2 pre-existing errors on sium/svelte provider (port pending). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
}
interface ActiveApp<S extends LangNode = LangNode> {
readonly Logger: EngineLogger;
readonly Lang: ActiveLang<S>;
readonly Formats: ActiveFormats;
readonly Frontend: ActiveFrontend;
readonly Dom: ActiveDom;
readonly Storage: ActiveStorage;
readonly Http: EngineHttp;
readonly Timers: ActiveTimers;
readonly Cache: ActiveCache;
readonly Sess: ActiveSession<unknown, unknown, unknown> | undefined;
Build runtime infrastructure layer: aapp + 5 new artifacts Adds the application composition root and six new runtime artifacts. lang and logr alone could not cover an app surface — locale propagation, format helpers, frontend preferences, validation, persistence and DOM service all needed independent artifacts that aapp wires together under a single locale source of truth and a shared logger. New artifacts: - aapp: composition root. createActiveApp + createTestApp + App.createSiumEngine + frontend.persist + Storage wiring. - stor: pluggable adapters (local/session/memory/cookie + SSR via cookieAdapter.fromCookies), envelope versioning + migrate + TTL, validate via Standard Schema, intra-tab + cross-tab sync, Storage.clear(), per-entry adapter/namespace overrides. - adom: reactive DOM service. shareViewport opt-in + per-window tracker, dispose(). breakpoints, viewport, attribute writes. - fend: frontend preferences (theme, mode, dir, density, reducedMotion, reducedSound) with auto/clear/isAuto pattern. - fmts: localized formatting (numbers, currency, units, dates) with shared LocaleSource and per-domain auto/clear pattern. - sium: validation engine. Standard Schema interop, Lang/Logger injection, codec/refine/transform, domain types (color/date/time), introspection. Existing artifacts extended: - lang: BCP 47 SupportedLocale (LangBase | base-region), mono lang for monolingual apps, extend() leaf-overwrite warning, EngineLang/ActiveLang naming alignment with the rest of the project (no Instance suffix). - logr: EngineLogger.dispose(), failureThrottleMs anti-cascade for transports, README sync to the per-level filter API (minLevel removed). Cross-cutting: - $locale: shared LocaleSource type consumed by fmts and fend. - arts/README.md: artifact map, dependency graph, naming conventions. - Test pages for every artifact under /test/<artifact>. 733 tests passing; svelte-check clean except 2 pre-existing errors on sium/svelte provider (port pending). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
getLocale(): SupportedLocale;
setLocale(locale: SupportedLocale): void;
onLocaleChange(fn: (locale: SupportedLocale) => void): () => void;
createSiumEngine(): EngineSium;
createActiveSession<TUser, TCredential = undefined, TData = undefined>(
options?: Omit<EngineSessionOptions<TUser, TCredential, TData>, 'logger'>
): ActiveSession<TUser, TCredential, TData>;
createActiveConnections<TConnections extends ConnectionMap = ConnectionMap>(
options?: Omit<ActiveConnectionsOptions, 'logger' | 'timers' | 'session'>
): ActiveConnections<TConnections>;
Build runtime infrastructure layer: aapp + 5 new artifacts Adds the application composition root and six new runtime artifacts. lang and logr alone could not cover an app surface — locale propagation, format helpers, frontend preferences, validation, persistence and DOM service all needed independent artifacts that aapp wires together under a single locale source of truth and a shared logger. New artifacts: - aapp: composition root. createActiveApp + createTestApp + App.createSiumEngine + frontend.persist + Storage wiring. - stor: pluggable adapters (local/session/memory/cookie + SSR via cookieAdapter.fromCookies), envelope versioning + migrate + TTL, validate via Standard Schema, intra-tab + cross-tab sync, Storage.clear(), per-entry adapter/namespace overrides. - adom: reactive DOM service. shareViewport opt-in + per-window tracker, dispose(). breakpoints, viewport, attribute writes. - fend: frontend preferences (theme, mode, dir, density, reducedMotion, reducedSound) with auto/clear/isAuto pattern. - fmts: localized formatting (numbers, currency, units, dates) with shared LocaleSource and per-domain auto/clear pattern. - sium: validation engine. Standard Schema interop, Lang/Logger injection, codec/refine/transform, domain types (color/date/time), introspection. Existing artifacts extended: - lang: BCP 47 SupportedLocale (LangBase | base-region), mono lang for monolingual apps, extend() leaf-overwrite warning, EngineLang/ActiveLang naming alignment with the rest of the project (no Instance suffix). - logr: EngineLogger.dispose(), failureThrottleMs anti-cascade for transports, README sync to the per-level filter API (minLevel removed). Cross-cutting: - $locale: shared LocaleSource type consumed by fmts and fend. - arts/README.md: artifact map, dependency graph, naming conventions. - Test pages for every artifact under /test/<artifact>. 733 tests passing; svelte-check clean except 2 pre-existing errors on sium/svelte provider (port pending). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
dispose(): void;
}
```
## Why Sium is out
Sium is a validation library that reaches into per-page data — login forms,
profile editors, signup wizards. Putting it in App would force every page
(including those without forms) to load the entire schema/types/issues machinery
just to use Lang or Formats. Keeping Sium page-scoped means:
- Pages without validation pay nothing for it.
- Each form can use a sium engine tuned to its own needs (custom logger
category, validation context, etc.).
- App stays focused on the runtime contract every page needs.
The standard pattern is one line at the top of the page module:
```ts
const sium = createEngineSium({ lang: App.Lang, logger: App.Logger });
```

Powered by TurnKey Linux.