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 });
```