master
${ noResults }
6 Commits (7adf93ca5741986d3c5c2bd9aa6550044fe5949f)
| Author | SHA1 | Message | Date |
|---|---|---|---|
|
|
7adf93ca57 |
Prefs as schema-based core + lowercase App.* surface
Two structural changes that were overdue and got bundled because
they touched the same set of files.
## Prefs is now a schema, not a fixed shape
Previously every preference had to be declared in a closed
`PrefsCapabilities` interface (`languages`, `locales`, `currencies`,
`themes`, `densities`, `motions`, `timezones`, `unitSystems`). Adding
a new pref required forking `$libs/prefs` — bad framework design.
The redesign replaces the fixed shape with a schema:
PrefsSchema = Record<string, PrefsDimension<TIntent, TEffective>>
Each dimension owns its own validator (`validate`), environment-fed
resolver (`resolve`) and optional sibling-derived value (`derive`).
The engine is generic over the schema and iterates it; it knows
nothing about "locale" or "theme" specifically.
Built-in dimensions live in `arts/prefs/dimensions/*` (locale,
language, theme, density, motion, timezone, currency, unit-system,
direction, plus boolean / enum / string / number primitives). The
`standardPrefsDimensions(catalog)` preset composes the canonical
set; apps spread it and add their own:
const schema = {
...standardPrefsDimensions({ languages, locales, currencies }),
sidebarCollapsed: booleanDimension({ default: false }),
notificationLevel: enumDimension(
['all', 'mentions', 'none'] as const,
{ default: 'mentions' }
)
};
Active surface exposes one slot per schema key with uniform verbs:
App.prefs.locale.get()
App.prefs.locale.set('es-ES')
App.prefs.locale.clear()
App.prefs.locale.onChange((v) => …)
App.prefs.sidebarCollapsed.set(true)
`setIntent('locale', value)` stays available as a low-level pass-
through (storage bridge consumes it generically) but UI code uses
the dimension surface.
## Lowercase core surface
`App.Logger`, `App.Bus`, `App.Timers`, `App.Orca`, `App.Prefs` are
gone. The "PascalCase for core, lowercase for services" rule was
visual signalling against JS convention, no technical benefit, and
created an asymmetry on the same object. All core members are now
lowercase, matching services:
App.logger
App.bus
App.timers
App.orca
App.prefs
`createPrefsStorageBridge` keeps its old responsibilities; sources
helpers (`prefsLocaleSource`, …) are gone — the dimension API
replaces them.
## What changed
- `$libs/prefs`: fully generic schema-based types + resolver. Old
fixed `PrefsCapabilities` / `PrefsIntent` / `PrefsEffective`
removed; replaced by `PrefsDimension`, `PrefsSchema`,
`PrefsEffectiveOf<S>`, `PrefsIntentOf<S>`.
- `arts/prefs`: engine + active wrapper rewritten to schema. Per-
dimension active surface auto-built from schema keys. Sources file
deleted (replaced by dimension surface). New
`arts/prefs/dimensions/*` and `arts/prefs/standard.ts`. Storage
bridge made schema-generic.
- `arts/active-app`: lowercase `CoreServices` / `ActiveAppCore`,
`prefs?: ActiveAppPrefsOptions<S>` root option carrying the
schema. `defineActivePrefs` deleted (prefs is core, not service).
`lang` / `format` / `frontend` factories migrated to read
`core.prefs.<dim>` directly via defensive `readSlot()` helpers
(each dimension is optional from the factory's POV; if the app's
schema omits one, the integration degrades gracefully).
- Presets, demos, web routes, README docstrings, `check-aliases.mjs`
guards, marketing snippets all migrated.
- Tests: `engine-prefs`, `active-prefs`, `storage-bridge`,
`resolve-prefs`, `validate-intent`, `prefs-consumer-wiring`,
`service-factories` rewritten for the schema-based API.
`sources.test.ts` deleted (sources file is gone).
## Verification
- `npm run check`: 0 errors, 0 warnings (1527 files).
- `npm test`: 1645 tests across 139 files, all green.
- `node scripts/check-aliases.mjs`: clean (lowercase enforced for
every member of `App.*`, including `Logger`/`Bus`/`Timers`/`Orca`/
`Prefs` which now flag as forbidden capitals).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
5 months ago |
|
|
48404bb037 |
Move setBus/getBus to $bus; the bus owns the propagation pattern
The Svelte-context bridge `setBus(bus)` / `getBus()` previously lived in
arts/active-app/bus-context.svelte.ts. That placement was wrong: the
helper does not depend on App, doesn't know about services, and serves
any consumer holding an EngineBus — including isolated test buses or
secondary buses for embedded sub-trees. Its semantic owner is the bus.
Moves:
arts/active-app/bus-context.svelte.ts -> arts/bus/svelte/context.svelte.ts
AappBusNoContextError -> BusNoContextError (libs/bus)
APP_ERR_BUS_NO_CONTEXT (code) -> BUS_ERR_NO_CONTEXT
APP_BUS_CONTEXT_KEY (string constant) -> Symbol inside the helper
`setBus` / `getBus` are re-exported from the `$bus` barrel; no consumer
needs to know the file path. Imports change from `$active-app` to `$bus`:
-import { setBus } from '$active-app';
+import { setBus } from '$bus';
The dropped surface area in arts/active-app:
- bus-context.svelte.ts (file)
- APP_BUS_CONTEXT_KEY (consts)
- APP_ERR_BUS, APP_ERR_BUS_NO_CONTEXT, APP_ERROR_MSG_BUS_NO_CONTEXT (errors)
- AappBusNoContextError class + isAappBusNoContextError guard
- setBus/getBus/AappBusNoContextError/isAappBusNoContextError barrel exports
Verification: 1347/1347 vitest tests still pass; the demo's +layout
imports from $bus and the page renders all 11 cards with sign-in working
and zero console/page errors.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
5 months ago |
|
|
eb6001fae4 |
Reduce App core to Logger/Bus/Timers/Orca; everything else is opt-in services
Big-bang replacement of the active-app composition: legacy uppercase surface
(App.Lang, App.Cache, App.Format, App.Frontend, App.Dom, App.Storage, App.Http)
removed entirely. All non-core artifacts are now opt-in via services schema:
services: { cache: defineActiveCache(), lang: defineActiveLang(...), ... }
Schema services are exposed as lowercase properties (App.cache, App.lang, …)
with end-to-end type safety; accessing a service the schema didn't declare
is a compile error.
Three import paths split for honest tree-shaking:
$active-app createActiveApp + core types/errors/bus-context
$active-app/services defineActive* / defineEngine* factories
$active-app/presets applyCache* / applyPerm* / applyStandardOrca
Service factories declare core deps (logger/bus/timers/orca) and sibling
service deps (e.g. format wires localeSource from lang automatically when
both are declared). The builder validates names, computes topological order,
detects cycles, builds immediates eagerly, and exposes lazy proxies that
materialise on first access. factory.create() runs inside untrack so
subscriptions wired during construction (e.g. lang.onLocaleChange) cannot
crash the outer reactive scope when triggered from a $derived.
Reactions to lifecycle events (cache.clear on revoke / identity change,
perm.invalidate on identity change) move from internal bus subscriptions
inside arts to opt-in orca presets registered by the application:
applyStandardOrca(App) // or cherry-pick individual apply* functions
Also lands a working showcase at /demo wiring 10 of 12 services
(everything except auth/connections, which need a real server) plus a
mocked perm fetcher and a real http client against jsonplaceholder.
Misc cleanup along the way:
- libs/cache/{key,policy,scope}.ts: missing CACHE_VALIDATION_MESSAGES
imports (the throw paths were never covered by tests, so the bug
only surfaced via the demo)
- All arts READMEs scrubbed of autoInvalidateOn / APP_EVENT_USER_*
references; bus README rewritten around the orca-preset model
- refactorizacion.md moved out of src/ into docs/
Verification: 1347/1347 vitest tests passing, demo loads and exercises
all wired services in a real browser with zero console errors.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
5 months ago |
|
|
64ab1f0b63 |
Big-bang: remove legacy translators, App.createActiveX(), APP_EVENT_*, autoInvalidate*
Completes step 3 of the active-app refactor. The orca-based service
schema model is now the single supported path; the legacy
auto-reactive ecosystem is gone.
Removed:
- arts/active-app/integrations/session-translator.ts and auth-cache.ts
(their purpose is replaced by orca presets in arts/active-app/presets/).
- arts/connection/bus-session-source.ts (canonical session events
flow through SESSION_EVENT_* directly).
- libs/active-app/ entirely. Its contents (consts, errors, events
reduced to APP_EVENT_DISPOSE_STARTING) consolidated into
arts/active-app/{consts,errors,events}.ts. The libs layer no longer
has anything app-specific.
- From arts/cache:
- bus / autoInvalidateOn options on ActiveCacheOptions.
- wireAutoInvalidation internal subscription.
- CACHE_AUTO_INVALIDATE_* constants and types.
- From arts/perm:
- bus / autoInvalidateOn options on ActivePermsOptions.
- wireAutoInvalidation internal subscription.
- PERM_AUTO_INVALIDATE_* constants and types.
- From arts/connection:
- bus option in EngineConnectionsOptions.
- shouldWireBusSessionSource helper.
- The "reacts to canonical app identity bus events" test that
depended on the deleted bus-session-source.
- From arts/active-app/active-app.svelte.ts:
- createSiumEngine() / createActiveSession() / createActiveConnections() /
createActivePerms() / createActiveAuth() factory methods.
- App.Sess / App.Perms / App.Auth getters and the singleton
guards (Sess !== undefined etc.).
- APP_ORCHESTRATION_* preset system, resolveActiveAppOrchestration,
STANDARD_ORCHESTRATION_TRANSLATORS, all five translator handles.
- APP_ERROR_ALREADY_CREATED_* / APP_ERROR_CREATE_PERM_ENDPOINT_REQUIRED
constants (orphan after factory removal).
- From arts/active-app/test:
- ecosystem.integration.test.ts (9 monolithic tests, ~1900 lines).
- session-translator.test.ts.
- create-sium-engine.test.ts.
- From libs/active-app/test:
- events.test.ts (covered the deleted publishers and the legacy
APP_USER_IDENTITY_* causes).
- APP_EVENT_USER_IDENTITY_CHANGED, APP_EVENT_TENANT_SWITCHED,
APP_EVENT_PERMISSIONS_REFRESH_REQUESTED,
APP_EVENT_CACHE_INVALIDATE_REQUESTED, APP_EVENT_CONNECTIVITY_CHANGED
(only DISPOSE_STARTING survives).
- Their associated payload interfaces and the
APP_USER_IDENTITY_CAUSE_* constants.
- publishAppUserIdentityChanged / publishAppPermsRefreshRequested /
publishAppCacheInvalidateRequested / publishAppTenantSwitched /
publishAppConnectivityChanged. publishAppDisposeStarting and the
new onAppDisposeStarting helper remain.
Final shape of arts/active-app/:
- active-app.svelte.ts: builds Logger, Lang, Format, Frontend, Dom,
Storage, Http, Timers, Bus, Orca, Cache, then the schema services
via buildServiceBuilders. dispose() publishes DISPOSE_STARTING and
tears everything down in reverse construction order.
- services.ts, service-builder.ts, service-factories/, presets/,
bus-context.svelte.ts, consts.ts, errors.ts, events.ts, types.ts,
index.ts (public barrel exposing every define*, applyStandardOrca,
types and errors).
Suite: 1374 tests pass. The reduction from the prior 1408 reflects the
deleted legacy tests; coverage of the new model is comprehensive
(schema-declarative.test.ts, service-builder.test.ts,
service-factories.test.ts, presets.test.ts, active-app.test.ts core,
plus the existing per-art suites).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
5 months ago |
|
|
7f2577c8da |
Rename permissions→perm, formats→format; consolidate sium error infra
Two more module renames flipping the direction of the previous pass: - arts/permissions, libs/permissions, svrs/permissions, libs/svrs/permissions.ts → arts/perm, libs/perm, svrs/perm, libs/svrs/perm.ts. Alias: $permissions → $perm. Constants: PERMISSION_* → PERM_*. Wire: 'permissions::*' → 'perm::*'. Module value: 'perm'. Class names: Permission*Error → Perm*Error. Helper functions: permissionDecisionKey → permDecisionKey (and similar). - arts/formats → arts/format (with the four sub-modules currency, numbers, units, dates carried along). Alias: $formats → $format. Constants: FORMATS_* → FORMAT_*. Wire: 'formats::*' → 'format::*'. Class names: Formats*Error → Format*Error. Both follow the auth/http/dom precedent: short word as the canonical name. The earlier full-word forms (permissions, formats) created asymmetric prefixes (PERMISSION_* singular, PERMISSIONS_REFRESH plural) that were already showing as drift in this commit's call sites. Plus a fix to sium error structure that was carried over from the previous audit round but never fully consolidated: - arts/sium/errors.ts now owns the full error infra: SIUM_ERR seed, all SIUM_ERR_* codes, SIUM_ERROR_MESSAGES catalog, error classes (SiumValidationError, SiumAsyncSchemaError, SiumDiscriminatedUnionError), guards and the SIUM_ERROR_MESSAGES type. The legacy SIUM_ERRORS string catalog stays for the few non-thrown sites until those are migrated. - arts/sium/consts.ts no longer carries error codes — only module identifier and diagnostic events. - arts/sium/core/types.ts no longer carries error classes — only schema types. - All call sites in arts/sium/core/* and arts/sium/types/* now import the error classes from `../errors` instead of `../core/types` / `../consts`. This is the canonical pattern documented in conventions.md rule 6: all of a module's error infrastructure lives in a single errors.ts file; consts.ts is for module configuration that has nothing to do with errors. Sium is now compliant; the rest of the modules will follow in subsequent commits. All 1334 tests pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
5 months ago |
|
|
4db6bd2b3b |
Rename modules from 4-letter aliases to full English words
Drops the 4-letter alias convention in favour of a single homogeneous
naming axis: full English words across filesystem, alias, wire format
and constants.
Module renames:
- arts/aapp → arts/active-app (libs/aapp also)
- arts/buss → arts/bus (libs/buss also)
- arts/cach → arts/cache (libs/cach + svrs/cach also)
- arts/conn → arts/connection
- arts/fend → arts/frontend
- arts/fmts → arts/formats (curr→currency, nums→numbers, unts→units)
- arts/logr → arts/logger (libs/logr also)
- arts/perm → arts/permissions (libs/perm + svrs/perm also)
- arts/sess → arts/session
- arts/stor → arts/storage
- arts/timr → arts/timer (libs/timers → libs/timer)
Modules left as-is: auth, dom, errs, http, lang, sium (already match
their canonical name or are proper names).
Special case: `aapp` could not become `app` because `$app` is reserved
by SvelteKit (`$app/stores`, `$app/navigation`, ...). Compromise:
- Filesystem and alias use `active-app` / `$active-app`.
- Constants and class names use `App` / `APP_*` (no `active-` prefix).
The `active-` prefix only disambiguates the alias from SvelteKit's
namespace; the module is App.
Special case: `permissions` keeps the plural for filesystem/alias/wire
but constants and classes use the singular `PERMISSION_*` /
`Permission*` because they describe the concept ("a permission
effect"), not the module collection.
Constants follow the new module name in caps: `STORAGE_*`, `BUS_*`,
`CACHE_*`, `CONNECTION_*`, `FORMATS_*`, `LOGGER_*`, `SESSION_*`,
`TIMER_*`, etc. Module values: `STORAGE_MODULE = 'storage'`,
`BUS_MODULE = 'bus'`, `APP_MODULE = 'app'`,
`PERMISSION_MODULE = 'permissions'`, etc.
Wire/code format moved accordingly: `'storage::*'`, `'bus::*'`,
`'session::*'`, `'permissions::*'`, etc. Diagnostic event values
updated: `'storage.error'`, `'bus.event.published'`,
`'connection.auth_failed'`, etc. App events use `'app.*'`:
`AAPP_EVENT_* → APP_EVENT_*` with values `'app.user.identity.changed'`.
Class renames (where they used the abbreviation):
- AappAlreadyCreatedError → AppAlreadyCreatedError
- BussError* → BusError* (where applicable)
- Cach* → Cache*
- Conn* → Connection* (e.g. ConnDisposedError → ConnectionDisposedError;
ConnConnection* collapsed to Connection*)
- Logr*Error → Logger*Error
- Sess* → Session* (SessInvalidSessionError → SessionInvalidError)
- Stor* → Storage*
- Timr* → Timer* (TimrInactiveTimerError → TimerInactiveError)
- AuthCachPort → AuthCachePort
- AuthClientCach* → AuthClientCache*
- AuthPermPort → AuthPermissionsPort
Property renames in option types:
- `cach?:` → `cache?:` in AuthClient options
- `logr:` → `logger:` in svrs/auth ports
- `timr:` → `timer:` in svrs/auth ports
`docs/conventions.md` rewritten:
- Rule 1 dropped the 4-letter alias mandate; lists the full English
module names and special-cases active-app, lang, sium, permissions.
- Rule 2 documents the new constant prefix convention and its two
exceptions (APP_* for active-app, PERMISSION_* singular for
permissions).
- Rule 6 codifies that all error infrastructure (codes, messages,
classes, guards) lives in a single `errors.ts` per module —
removing the `consts.ts` / `errors.ts` split for error-related
symbols.
`libs/errs` adds `ErrorMessages` type so every module can declare its
catalog as `<MOD>_ERROR_MESSAGES: ErrorMessages` instead of repeating
the `Readonly<Record<ErrCode, string | (...args) => string>>` shape.
Storage migrated as the first proof of the canonical pattern.
All 1334 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
5 months ago |