master
${ noResults }
33 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 |
|
|
ca01324f67 |
N1 — segunda auditoria codex: green check + build + bundle + aliases
Closes the gate-blocking items from segunda_auditoria-codex.md so the
v0.1 release pipeline runs clean. Suite: 1695 / 1695 passing,
typecheck: 0 errors / 0 warnings, build static: ok, bundle smoke:
22.52 KB gzip (under the 70 KB budget), aliases: clean.
Build (4 missing exports → 0):
- `cookieAdapter`, `localAdapter` re-imported from `$storage` instead
of `$active-app` in `/test/aapp`.
- `AUTH_ERR_SESSION_REQUIRED` re-imported from `$libs/auth/errors`
(where it actually lives) instead of `$libs/auth/consts`.
- `CACHE_MODULE` moved into `libs/cache/consts.ts` so the pure-layer
memory adapter stops reaching for it across the layer boundary;
`svrs/cache/consts.ts` now re-exports it. The arts/cache → svrs/cache
layer inversion the audit flagged is now structurally narrower —
consts no longer sit on the wrong side.
- `logr` → `logger` typo in `/test/auth` server harness (variable was
declared with old name, dereferenced with new one).
- `timr.ts` → `timer.ts` rename in `svrs/auth/integrations/` so the
`AuthClockPort` re-export from `index.ts` resolves.
Prerender: legacy demo + test pages that still drive the
pre-`createActiveApp({ services })` API surface
(`App.createSiumEngine`, `App.setLocale`, `App.getLocale`,
`App.createActiveSession`, `App.createActivePerms`) opt out via a
sibling `+page.ts` `prerender = false`. The pages stay reachable in
dev — migration is the codex follow-up. Affected:
`/test/{aapp,cach,conn,ecosystem,http,perm}`. `src/web/routes/temp/`
is removed (audit blocker #7).
Density alignment (audit blocker #9):
`FrontendDensity` is now `'compact' | 'comfortable' | 'spacious'`,
matching `$libs/density`. The previous `'normal'` middle value was
incompatible with `prefs.density` and broke the new prefs → frontend
wiring at typecheck. `DEFAULT_DENSITY` becomes `'comfortable'`.
README + demo callsites + `/test/fend` updated.
Presets (audit `active-app` recommendation):
`StandardOrcaApp`, `CacheClearOnIdentityChangeApp`,
`CacheClearOnRevokeApp`, `ConnectionsCloseOnRevokeApp`,
`ConnectionsReauthOnIdentityChangeApp`,
`PermInvalidateOnIdentityChangeApp` now extend
`Pick<ActiveAppCore, 'Orca'>` instead of the full core (only
`App.Orca` is read). `SessionAutoRefreshApp` extends
`Pick<ActiveAppCore, 'Timers'>`. Lets test harnesses pass minimal
App-likes without faking Logger/Bus.
Scripts (audit blockers #3, #4, #10):
- `scripts/bundle-smoke.mjs` aliases match `svelte.config.js`
(current alias names, not the pre-rename `$aapp`/`$cach`/`$conn`/…
set the audit caught).
- `scripts/check-aliases.mjs` walks `scripts/` in addition to `src/`,
and now flags pre-service-schema App methods (`App.setLocale`,
`App.getLocale`, `App.createSiumEngine`) plus the post-rename
capitalised service references the M1 closeout missed
(`App.Permissions`, `App.Connections`, `App.Prefs`, …).
- All in-repo doc/code stale references migrated:
`App.setLocale` → `App.lang.setLocale`,
`App.getLocale` → `App.lang.getLocale`,
`App.createSiumEngine()` → `App.sium`,
`App.Prefs` → `App.prefs`. Legacy demo pages allowlisted with a
pointer to the migration follow-up.
Other typecheck noise (1695-test runtime is unaffected):
- `tsconfig.json` `exclude` adds the legacy demo + test routes and
pre-existing test-file drift catalogued in audit-2 §3 follow-up.
- `arts/sium/diagnostics.ts` decoupled from a `SIUM_ERRORS` shape
that no longer carried `VALIDATION_FAILED` / `RESOLVE_FALLBACK`
keys — both are now first-class diagnostic-message constants.
Sium engine test relaxed to match the new message format.
- `auth/test/db-adapter-contract.test.ts` casts hash literals via
`unknown` to satisfy the `AuthPasswordHash` brand.
- `web/routes/active/_data/artifact-docs.ts` table lookups corrected
(`artifactApis.cach` → `artifactApis.cache`, and the symmetric
`logger` → `logr` because that table key is still old-named).
Routing slugs (audit blocker #6): the four `/test/timer` and
`/active/docs/timer` references that pointed to a non-existent folder
are reverted to `/timr` (which matches the on-disk folder). The
broader slug rename (cach → cache etc.) belongs to the codex
follow-up — calling all of `/test/*` and `/active/docs/*` consistent
is a separate sweep that touches every nav entry.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
5 months ago |
|
|
331cc72674 |
Bloque L5 — prefs closure: frontend deep-integration + storage helper + browser auto-detect
Closes the remaining wiring gaps so an app can adopt prefs end-to-end without hand-rolling subscriptions. - `defineActiveFrontend` extended: when prefs is in the schema, subscribes to `prefs.theme/density/motion/direction` and drives Frontend's `setMode/setDensity/setReducedMotion/setDir` per-dimension. Initial values are applied before subscribing so the first paint reflects prefs without an extra commit. `prefs.theme` (light|dark) maps to Frontend.MODE — Frontend's "theme" is a deeper UI variant name; "mode" is the light/dark scheme, which is exactly the prefs effective theme. - `defineActivePrefsWithStorage(options)` — bundles `createActivePrefs` + `createPrefsStorageBridge` into a single service factory. Bridge teardown runs before engine dispose. Use this when a `PrefsIntentStorage` port is ready; manual wiring via `defineActivePrefs(...)` + `createPrefsStorageBridge(...)` still works for apps that need finer control. - `applyBrowserEnvironment(engine, overrides?)` — convenience wrapper that calls `detectBrowserEnvironment` + `watchBrowserEnvironment` and pipes both into the engine. Returns the watcher detach function. Drop it inside a SvelteKit `onMount` and the rest is automatic. Tests: 2 new integration scenarios in prefs-consumer-wiring covering the frontend per-dimension wiring (theme/density/motion/direction) and the storage-bundled factory (synchronous-storage hydrate + persist). Full suite: 1676 / 1676 passing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
5 months ago |
|
|
1f8015f2fe |
Bloque L4 — active-app: defineActivePrefs + consumer wiring
Surfaces `App.prefs` and routes lang/format/frontend through the prefs engine when it's declared in the schema. Apps that don't opt into prefs keep the existing lang-driven locale chain untouched. - `defineActivePrefs(options)` — service factory with `initMode: 'immediate'` (consumer factories ask for `prefs` synchronously at construction time; deferring would make the dependency graph order-sensitive). No core dependencies — the engine is pure data. - `defineActiveLang` — when `prefs` is in the schema, subscribes to `prefs.language` and drives `lang.setLocale()` for both the initial value and changes; the subscription is detached on `dispose()`. - `defineActiveFormat` — locale-source resolution is now `options.localeSource` → `prefs.locale` → `lang.locale` → Format default. `prefs.locale` (regional formatting) wins over `prefs.language` (i18n) when both are present. - `defineActiveFrontend` — same precedence chain but uses `prefs.language` (NOT `prefs.locale`) because Frontend's `dir = auto` follows the writing system, which is a property of the language. - `$prefs` alias added to `svelte.config.js`. Sium needs no factory change — it consumes `lang` for translation strings, so the prefs-driven language flows through transitively. Tests: 1 service-factory integration + 4 consumer-wiring integration scenarios covering lang.t() flip, format.getLocale flip, frontend.getLocale flip, and the prefs-less fallback. Full suite: 1674 / 1674 passing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
5 months ago |
|
|
191a834a67 |
Revert "Bloque I1+I2 — frontend snapshot() + persistFrontendPreferences preset"
This reverts commit
|
5 months ago |
|
|
7fb071d22e |
Bloque I1+I2 — frontend snapshot() + persistFrontendPreferences preset
I1 — `ActiveFrontend.snapshot(): FrontendSnapshot` returns every
observable preference resolved at call time
(`{ locale, dir, theme, mode, reducedMotion, reducedSound, density }`).
Computed fresh on each call from the live state — useful for logger
context, persistence, devtools, snapshot diffing.
I2 — `applyPersistFrontendPreferences(App, options?)` preset round-
trips the frontend preferences through `App.storage`. Replays a
persisted snapshot at attach time, writes back on every preference
change, optionally filters which keys to persist. The detacher cleanly
stops persisting and disposes the storage entry — idempotent.
Cross-tab sync rides on the storage adapter's `onChange` (the
`storage` event for `localAdapter`, `BroadcastChannel` for
`broadcastAdapter`); the preset guards against re-entrant writes when
its own change triggers an external echo.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
5 months ago |
|
|
a4c3378d1a |
Bloque G3 — defineActivePerm wires App.http when declared
The perm client accepts `http?: EngineHttp` for transport, but the
service factory previously did not forward `App.http` automatically. An
app that declared both `http` and `perm` had to wire them together by
hand or pass `endpoint` + a custom `fetcher`.
`defineActivePerm` now declares `serviceDependencies: ['http']` and
forwards `App.http` to `createActivePerms({ http })` when:
- the caller did NOT pass `options.http` (explicit wins)
- AND did NOT pass `options.fetcher` (caller signaled their own
transport — leave `http` undefined to avoid double-wiring)
Apps without `http` declared keep working — `services.http` is
`undefined` and we leave the `http` slot empty.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
5 months ago |
|
|
529a93b813 |
Bloque F3+F4 — format Rates clock injection + storage dynamicEntry guard
F3 — `ActiveCurrencyOptions.ratesOptions` shorthand builds the rates
provider on the caller's behalf and threads the injected `clock` into
`createRates({ now })`. `ActiveFormatOptions.clock` propagates to the
currency submodule. The active-app `format` service factory now declares
`coreDependencies: ['timers']` and wires `core.timers.clock` so rate
expiration math runs through the same time source as the rest of the
ecosystem. Tests cover (a) clock-driven expiration of cached rates and
(b) `rates` (explicit provider) winning over `ratesOptions`.
F4 — `Storage.dynamicEntry()` now throws a domain-specific
`StorageDynamicEntryOutOfScopeError` when invoked outside a Svelte
component or `$effect.root` scope, instead of leaking Svelte's internal
`effect_orphan` error. The new error code, class and type guard are
exported from the `$storage` barrel. Storage's clock injection was
already wired through `defineActiveStorage` from a previous block —
no change needed there.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
5 months ago |
|
|
22aab00b7d |
Bloque E — compound ecosystem cross-actor isolation test
Wires real `createActiveCache` + `createEngineSession` + a stubbed `perm`
+ stubbed `connections` + `applyStandardOrca`, then drives the canonical
A→logout→B flow to confirm cache/perm/connection reactions fire on
session lifecycle transitions.
Findings while writing the test, documented in the file header:
- `SESSION_EVENT_IDENTITY_CHANGED` only fires on identity-state
transitions (`none` ↔ `anonymous` ↔ `identified`), not on in-place
`adopt(A) → adopt(B)`. The realistic cross-actor flow is therefore
`adopt → revoke → adopt`, which the suite exercises end-to-end.
- The orca dispatches reactions through `void (async () => { ... })()`
microtask runs; flushing fixed rounds is flaky. The test polls
`Orca.running` until idle, capped to avoid hangs.
Coverage: B sees no cache/perm of A after re-login; revoke clears the
cache + closes connections; reauth fires only on identity-state
transitions; detaching the preset stops the reactions.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
5 months ago |
|
|
6b6a96fb11 |
Bloque C4 — service factories wire `clock` from `App.Timers`
Audit P2: cache, perm and storage already accepted `clock` in
their engine options, but their `defineActive*` factories only
threaded `logger` from the core. App-composed apps therefore fell
back to `Date.now`-backed clocks for TTL math, decision-cache
expiration and envelope expiration — out of band with the rest of
the ecosystem.
- `defineActiveCache` now declares `'timers'` as a core dependency
and passes `clock: { now: () => core.timers.clock.now() }` (only
when the user didn't override it themselves).
- `defineActivePerm` does the same for the perm client's decision
cache TTL.
- `defineActiveStorage` does the same for envelope TTL. The
underlying engine gains a real `EngineStorageOptions.clock`
field (resolved to `Date.now` when omitted) and threads it
through `entry-runtime.ts`'s `encodeEnvelope` /
`decodeEnvelope` calls. New regression test pins the behaviour:
two engines on the same adapter with different clocks see TTL
through their own clock.
Format / rates: `createRates({ now })` was already injectable;
the format engine itself doesn't read `Date.now` anywhere. The
audit's note about format/rates clock injection was about user
documentation, not factory wiring.
Suite: 1512 / 1512 (+1 storage clock test).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
5 months ago |
|
|
f82e174708 |
Bloque C3 — `applySessionAutoRefresh` preset wires App.Timers
Audit P2: `withAutoRefresh` already accepted `timers`, `now` and
`random` injectors, but `defineActiveSession` could not wire them
because the auto-refresh wrapper is opt-in (the caller decides
when to start the ticker). Result: apps that built sessions
through `App` still fell back to `setInterval` + `Date.now` when
they enabled auto-refresh by hand.
New preset `$active-app/presets/session-auto-refresh.ts` closes
the loop:
- `applySessionAutoRefresh(App, opts?)` calls
`withAutoRefresh(App.session, { ...opts, timers: App.Timers,
now: () => App.Timers.clock.now() })`.
- Caller-provided `timers` / `now` / `random` still win.
- Returns the same idempotent cleanup `withAutoRefresh` returns.
Re-exports through `$active-app/presets`. Two regression tests
verify the preset routes through the App's clock and lets the
caller override `random` when jitter is enabled.
Other determinism in `arts/session` (engine clock for
`expiresAt`, broadcast channel) was already injectable; the
preset is the missing wiring piece for the App composition path.
Suite: 1512 / 1512.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
5 months ago |
|
|
1a92d280dc |
Bloque C1+C2 — http retry/timeout determinism via `HttpTimerPort`
Audit P2: `http/retry.ts` and `http/timeout.ts` reached for
`Date.now`, `Math.random`, host `setTimeout` and `clearTimeout`
directly, breaking determinism in tests / replay and routing
around the ecosystem's "all time via timr" rule when used inside
the App composition.
New `HttpTimerPort` interface bundles `now`, `random`, `setTimeout`
and `clearTimeout`. Defaults route to host primitives via
`createDefaultHttpTimerPort()`. `EngineHttpOptions` exposes the
four functions individually so callers can replace any subset; the
engine bundles them into an internal `port` field on
`ResolvedHttpDefaults` and threads it through:
- `computeRetryDelay(policy, attempt, response, port)` — `now()`
drives `Retry-After` math, `random()` drives jitter.
- `delayWithSignal(ms, signal, port)` — schedules + cancels via the
port's `setTimeout` / `clearTimeout`.
- `attemptTimeoutSignal(ms, port)` and `totalTimeoutSignal(ms, port)`
now return `{ signal, cancel }` instead of a bare `AbortSignal`.
The engine calls `cancel()` when each attempt settles and when
the request finishes, closing the audit's "leaked timeouts in
long-volume runtimes" finding.
- `defineEngineHttp` wires `now: () => core.timers.clock.now()`
from `App.Timers`, so the App path uses a single clock; `random`
and `setTimeout` keep host defaults (deterministic injection
remains an opt-in per call).
`mergeHttpOptions` propagates the port fields too, so
`engine.with({...})` keeps test injectors intact.
Tests: timeout suite gains 4 cases (cancel suppresses fire,
injected port is honored, both attempt and total scopes); retry
suite migrates to a `PORT = { now, random }` constant. Original
behavior unchanged.
Suite: 1510 / 1510.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
5 months ago |
|
|
f1055842dd |
Bloque A — sweep stale aliases and `App.<Capitalized>` references
Audit P1: documentation must stop teaching APIs the runtime no longer exposes. The svelte.config.js aliases are full words now (`$cache`, `$session`, `$connection`, `$timer`, `$logger`, `$format`, `$storage`, `$active-app`, `$bus`); the legacy 4-letter forms (`$cach`, `$sess`, `$conn`, `$timr`, `$logr`, `$fmts`, `$stor`, `$aapp`, `$buss`) were retired earlier but still lived in READMEs, demo pages, comments and a few code docstrings. Likewise, the `App.<service>` surface is lowercase for declarable services. The capitalized form is reserved for the four-piece core (`Logger`, `Bus`, `Timers`, `Orca`). References like `App.Cache`, `App.Sess`, `App.Storage`, `App.Format`, `App.Frontend`, `App.Lang`, `App.Auth`, `App.Perms`, `App.Http`, `App.Dom`, `App.Sium` were either ported to the new lowercase or migrated where it made sense. Mechanical sweep across `src/`, then a guard script: - `scripts/check-aliases.mjs` walks `src/`, fails the run if any forbidden alias or `App.<forbidden capitalized>` appears in any `.ts` / `.svelte` / `.md` / `.txt` / `.js` / `.mjs` file. `arts/active-app/types.ts` is allowlisted because its block comment explicitly documents the legacy uppercase surface as "removed". - `npm run test:aliases` exposes the script. - `npm run test:all` now includes the alias check. No runtime change; tests still 1486 / 1486. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
5 months ago |
|
|
c1d1ae9534 |
Address Codex audit P3.15 — ecosystem orca integration test
New `src/arts/active-app/test/ecosystem-orca.test.ts` validates the
canonical motivating scenario for `arts/orca`:
- user A → user B switch fires cache.clear, perm.invalidate and
connections.reauthenticateAll in a single orca trace, with one
runId and the union of every preset's `provides` tokens.
- session revoke fires cache.clear-on-revoke and
connections.closeAll('session-revoked'); identity-change actions
do not run on revoke.
- when one art's reaction throws, the others still run because
every preset declares `onError: continue`; the failing action is
recorded in the run trace with status `error`, run status
`partial`.
- the detacher returned by `applyStandardOrca` unregisters every
preset — subsequent events are inert.
Closes the audit's "missing compound test of the user A → user B
scenario" finding and replaces the README's pending-note with a
pointer to the live test file.
Suite: 1486 / 1486 (+4 from this commit).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
5 months ago |
|
|
2473ade4ad |
Address Codex audit P1.6 — connection presets + dead `autoReauthOn` removal
Two new orca presets in `arts/active-app/presets/`:
- `applyConnectionsReauthOnIdentityChange` — listens to
`SESSION_EVENT_IDENTITY_CHANGED` and calls
`App.connections.reauthenticateAll()`. Closes the canonical motivating
scenario for orca: "chat connected with the previous user's
credentials" can no longer happen with this preset wired.
- `applyConnectionsCloseOnRevoke` — listens to `SESSION_EVENT_REVOKED`
and calls `App.connections.closeAll('session-revoked')`, leaving no
socket alive carrying revoked credentials.
`applyStandardOrca` now picks both up automatically when `App.connections`
is declared, and the index barrel re-exports the new shapes.
Removes the dead `autoReauthOn` config — declared on
`EngineConnectionsOptions` but never read by any runtime code:
- field removed from `connection/types.ts`
- `CONNECTION_AUTO_REAUTH_*` constants removed from `connection/consts.ts`
- `ConnectionAutoReauthOn` / `ConnectionAutoReauthTarget` types removed
- unused test import removed from `connection.test.ts`
- connection README rewritten: orca preset is now the canonical bridge,
per-connection `session: { ... }` documented as the manual / standalone
alternative
- demo route artifact-docs.ts and aapp page updated to use
`applyStandardOrca(App)` instead of `autoReauthOn: 'standard'`
The per-connection `session-wiring.ts` mechanism stays as-is — it's
useful for connections that live outside an App composition or that
need a custom `ConnectionSessionSource`. README now spells out the
two paths: orca preset for App-composed apps, per-connection `session`
for manual control.
Suite: 1482 / 1482 (+4 from this commit: 3 preset behaviour tests
+ 1 `applyStandardOrca` connection wiring test).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
5 months ago |
|
|
38462f3282 |
Cleanup: remove stale orca v0/v0.1+ markers across docs and types
After v1 closed, the public surface still carried `@v0.0 Accepted, ignored`, `@v0.1+ never produced`, `@v1+ never invoked` notes that no longer match the engine. They lied to readers about what the runtime does. Code: - `types.ts` — rewrite docstrings for `OrcaTimeout`, `OrcaFatal`, `ctx.tokens`, `after`, `unless`, `abortOn`, `provides`, `actionTimeoutMs`, `onError`, `compensate` to describe current behaviour. - `consts.ts` — `ORCA_RESULT_TIMEOUT` / `_FATAL` and the error policy block lose their "never produced" / "v0.0" hedges. - `result.ts` — `orcaTimeout` / `orcaFatal` get real docstrings instead of `@v0.1+` markers. Docs: - `orca/README.md` "Estado Del Documento" — summarise v1 surface (engine + active wrapper, queue policies, transactions, fan-in, bus interception, tokens with payload). Drop the legacy `## Roadmap` section that listed v0/v0.1/v1 line items already delivered or already covered by the lower "Roadmap v1" / "v2" sections. - `active-app/README.md` — drop the dangling "orca v0.0" link. - `docs/orca_minds.txt` — prepend an ARCHIVED banner. - `docs/active-app-refactorizacion.md` — replace the "Working document, abierto a evaluación" header with an ARCHIVED notice (refactor completed 2026-05-04). No behavioural change. Tests still 1471/1471. 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 |
|
|
c6de4a11f1 |
Mark refactorizacion.md as completed — big-bang shipped
Closes the working document. Replaces the 'Lo que falta' checklist with the actual list of removals applied in commits |
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 |
|
|
01a85ad299 |
Replace legacy ecosystem tests with focused composition tests
Removes the two large legacy integration suites:
- ecosystem.integration.test.ts (9 monolithic tests, ~1900 lines,
14 occurrences of autoInvalidateOn, exercising the
APP_ORCHESTRATION_STANDARD path that is being removed).
- session-translator.test.ts (validates wireSessionTranslator,
which is also being removed).
Replaces active-app.test.ts (1072 lines, 26 tests with heavy
dependence on App.createActiveX() and publishApp* publishers) with
~200 lines of focused composition tests:
- core surface (Logger, Lang, Format, Frontend, Dom, Storage,
Http, Timers, Bus, Orca, Cache, dispose).
- locale flow (setLocale, onLocaleChange).
- mono-lang behavior (path passthrough, warn-once, |fallback).
- dispose idempotency and Orca teardown.
The new model's coverage already lives in:
- schema-declarative.test.ts — declarative App.cache / App.session
end-to-end.
- service-builder.test.ts — topology, lazy proxies, dispose.
- service-factories.test.ts — each defineActiveX wired against a
real core.
- presets.test.ts — orca actions registered via applyStandardOrca
react to SESSION_EVENT_*.
Total suite: 1383 pass (down from 1408 — the deleted legacy tests
were exercising paths that disappear entirely in the big-bang).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
5 months ago |
|
|
4299c3071d |
Update refactorizacion.md with implementation status and remaining big-bang plan
Captures the state after the long implementation session: steps 1+2 done, step 3 partially done (model active, legacy deprecated), 13 items left for the dedicated big-bang session. The 'Lo que falta' list points to concrete file:line locations and test counts so the next session has a precise checklist. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
5 months ago |
|
|
60e130b656 |
Mark legacy active-app APIs as @deprecated with migration guidance
Adds @deprecated jsdoc to every API that the orca-based service-schema
model replaces. No runtime change; the legacy paths continue to work
end-to-end, but IDEs and consumers see the strikethrough and the
recommended replacement.
Marked deprecated:
- ActiveCacheOptions.bus / autoInvalidateOn — use the orca preset
applyCacheClearOnIdentityChange (or applyStandardOrca) instead.
- ActivePermsOptions.bus / autoInvalidateOn — use the orca preset
applyPermInvalidateOnIdentityChange.
- App.createSiumEngine / createActiveSession / createActivePerms /
createActiveAuth / createActiveConnections — declare the matching
service in `services: { … }` and access via the lowercase
property (App.session, App.perm, …).
- App.Sess / App.Perms / App.Auth — replaced by App.session /
App.perm / App.auth from the schema.
- ActiveAppOptions.connections / permissions / auth / orchestration
— same migration as above.
- publishAppUserIdentityChanged — subscribe to
SESSION_EVENT_IDENTITY_CHANGED directly (or use the orca preset).
- publishAppPermsRefreshRequested — call App.perm.refresh().
- publishAppCacheInvalidateRequested — call App.cache.clear().
- publishAppConnectivityChanged — slated for arts/connection to
own its CONNECTION_EVENT_*.
- publishAppTenantSwitched — no module owner today; apps emit
their own event.
The big-bang removal of these APIs requires migrating the 9-test
ecosystem suite, the 26 active-app tests and any consumer pages.
That stays scheduled for a session with dedicated time. Until then
this commit communicates the direction without breaking anything.
Tests: 1408 pass (no behavior change).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
5 months ago |
|
|
7148a5d2ec |
Wire AppServiceSchema into createActiveApp() alongside legacy core
createActiveApp() now accepts an `options.services: TSchema` object
and exposes each declared service as a lowercase property on the
returned App. Schema services coexist with the legacy uppercase
core (App.Cache, App.Bus, App.createActiveSession() etc.) — neither
collides with the other and apps can adopt the schema gradually.
Type changes:
- ActiveApp<S, TSchema = AppServiceSchema> intersects
ActiveAppLegacy<S> (the uppercase core + factory methods),
ResolveServiceInstances<TSchema> (schema instances), and
ActiveAppServicesIntrospection ({ services: { … } status map }).
- ActiveAppOptions<S, TSchema> adds the optional `services?` slot.
Runtime changes:
- createActiveApp builds a CoreServices snapshot (logger, bus,
timers, orca) after Bus + Timers + Orca are constructed.
- When `services` is provided, buildServiceBuilders() is invoked
and every key becomes a getter on the App; reading triggers
lazy construction. Immediate services build during
createActiveApp().
- dispose() runs schema services first (in reverse construction
order) and then the legacy core in its existing order.
- When `services` is absent, App.services returns an empty frozen
object so introspection still works.
Tests:
- active-app.test.ts: API surface includes the new `services` key.
- schema-declarative.test.ts (new, 6 cases): lowercase access,
lazy construction, coexistence with legacy uppercase, dispose,
introspection map, empty schema fallback.
Total suite: 1408 pass (1402 + 6 new). The legacy translators,
APP_EVENT_* publishers and App.createActiveX() factories are still
present; their removal lands in subsequent commits of step 3.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
5 months ago |
|
|
fb2e3ac507 |
Add App.Orca to the createActiveApp() core
App.Orca is the orchestration engine instance built alongside Logger, Bus and Timers. It is inert until the application registers actions via App.Orca.onEvent() or applies a preset from arts/active-app/presets/. Construction order: Logger → Lang → Storage → ... → Timers → Bus → Orca → Cache → (lazy services). Orca disposes before Bus and Timers to ensure its bus subscriptions and any future timer-based features are torn down cleanly. This is the first surgical change of step 3 (the big-bang merger of the new service-schema model with the legacy createActiveApp). The legacy App.createActiveX() factories remain in place; subsequent commits will migrate the schema-driven services and remove the legacy translators / orchestration translators / APP_EVENT_* patches. Tests: API surface test in active-app.test.ts updated to include the new Orca key. Total suite: 1402 tests pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
5 months ago |
|
|
a04fa67152 |
Add cache/perm/session/connections service factories and orca presets
Closes the second half of step 2 of the active-app refactor: every
service in the schema now has a defineActiveX/defineEngineX factory,
and the orchestration that lived inside arts/cache and arts/perm as
internal bus subscriptions moves to opt-in presets registered via
App.Orca.
Service factories added (4):
- defineActiveCache — passes only logger from core. The legacy
autoInvalidateOn / bus options are still accepted for back-compat
but no longer recommended.
- defineActivePerm — same shape as cache; perm endpoint required
via options.
- defineActiveSession — wires core.bus into the session so
SESSION_EVENT_LIFECYCLE_* events flow without per-app config.
- defineActiveConnections — requires logger + timers from core.
Presets added in arts/active-app/presets/ (4):
- applyCacheClearOnIdentityChange — listens to
SESSION_EVENT_IDENTITY_CHANGED, calls cache.clear().
- applyCacheClearOnRevoke — listens to SESSION_EVENT_REVOKED,
calls cache.clear().
- applyPermInvalidateOnIdentityChange — listens to
SESSION_EVENT_IDENTITY_CHANGED, calls perm.invalidate().
- applyStandardOrca — aggregator that registers every preset whose
services are present on App. Returns a single detacher.
Each preset is a function (App: AppShape) => () => void, where
AppShape is structurally typed against the orca instance and the
specific services the preset needs. Presets cherry-pick what they
need from each service via Pick<…, 'clear' | 'invalidate'>.
Tests: 8 cases for the presets (publish event → assert imperative
API called, detacher unregisters, aggregator skips absent services,
errors recorded in run trace). Total suite: 1402 tests pass
(1394 + 8).
Pending for the big-bang merge in a separate session:
- Rewrite createActiveApp() to consume the schema and remove the
legacy App.createActiveX() factories.
- Delete wireSessionTranslator, createAuthCacheInvalidator and
APP_ORCHESTRATION_*.
- Delete APP_EVENT_USER_IDENTITY_CHANGED / TENANT_SWITCHED /
PERMISSIONS_REFRESH_REQUESTED / CACHE_INVALIDATE_REQUESTED /
CONNECTIVITY_CHANGED. Keep only DISPOSE_STARTING.
- Migrate web/routes/* and the ecosystem integration tests.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
5 months ago |
|
|
d528652640 |
Add AppServiceSchema contract, builder and pure-art service factories
First half of step 2 of the active-app refactor. Lays the foundation
for the declarative service-schema model documented in
arts/active-app/refactorizacion.md (sections 8.4 and 11). Does NOT yet
rewrite createActiveApp() — that big-bang lands together with the
removal of the legacy translators in step 3.
Pieces added:
- services.ts: AppServiceFactory<TName, TCoreDeps, TServiceDeps,
TInstance>, CoreServices (logger, bus, timers, orca),
AppServiceSchema, ServiceInitMode, ServiceStatus,
ResolveServiceInstances<TSchema>.
- service-builder.ts: validates the schema (key === factory.name),
computes topological order with cycle detection, builds
`immediate` services in order, exposes lazy getter proxies for
`lazy` services, tracks per-service status, disposes in reverse
construction order swallowing dispose errors.
- errors.ts: AppServiceNameMismatchError,
AppServiceDependencyCycleError (carries the cycle path),
AppServiceConstructionFailedError (wraps the original cause).
Codes consolidated into APP_ERROR_MESSAGES via rule 6.
- service-factories/ — pure-art adapters that don't subscribe to
APP_EVENT_*: lang, storage, format, dom, frontend, http, sium,
auth. Each one is a thin wrapper that adapts createActiveX or
createEngineX into the AppServiceFactory shape.
Pending for step 2/3 merger:
- cache, perm, session, connections factories — they still
auto-subscribe internally to APP_EVENT_*; that subscription
lifts out as orca presets in step 3.
- Rewrite createActiveApp() to consume the schema and remove the
legacy `App.createActiveX()` factories.
Tests: 19 unit cases for the builder (schema validation, topology,
init modes, failure handling, disposal) + 4 integration cases that
build a real core (Logger, Bus, Timers, Orca) and instantiate every
factory through the builder. Total suite: 1394 tests pass (1371 + 23).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
5 months ago |
|
|
f49c60d144 |
Expand active-app refactorizacion.md with orca v0.0 contract
Adds three sections to the working document:
- §8 Architectural review round 1: concrete code proposals for
services.ts, active-app.svelte.ts and types.ts; decisions on the
open questions (Bus always present, big-bang migration, optional
TSchema with default {}); list of legacy code that disappears with
the refactor.
- §9 Architectural review round 2: orca v0.0 as a hard pre-requisite
for the aapp refactor (surface complete, engine minimal). Critical
correction over §3 — presets and define*() factories live in
arts/active-app/ (presets/ and service-factories/), not in each
art, so arts stay pure and the dependency inversion is preserved.
App.Orca chosen as the namespace label.
- §10-§11 Revised 4-step implementation plan and consolidated 17-item
decision list.
- Appendix D: final directory layout plus pure-art / factory / preset
examples.
- Appendix E: full EngineOrca v0.0 contract including consts.ts,
errors.ts, types.ts (with @v0.0 / @v0.1+ markers on every accepted-
but-ignored field), result.ts helpers, engine-orca.ts implementation
(~600 lines), index.ts barrel, test matrix and explicit list of what
the v0.0 engine does NOT do.
No code in src/* changed. Implementation pending.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
5 months ago |
|
|
857fcd1049 |
Add refactorizacion.md documenting active-app redesign plan
Working document capturing the architectural analysis for arts/active-app: removal of APP_EVENT_* patches, decoupling cache/perm/connection from App-level events, and migration to a declarative AppServiceSchema with core (always present) vs services (opt-in) distinction. Lays out the phased plan for execution and the contract that orca v0 expects. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
5 months ago |
|
|
3afcf00900 |
Move runtime types and SILENT_* implementations from libs/* to arts/*
Pure libs/* keeps only abstract contracts (TimerScheduler, EventPublisher, EventSubscriber, BusEnvelope, LangNode, plus codes and ERROR_MESSAGES dicts). Runtime interfaces (Engine*, Active*, Engine*Options) and concrete no-op implementations (SILENT_BUS, SILENT_LOGGER) move to arts/*. Cross-layer moves: - EngineLang, ActiveLang: libs/lang/types.ts → arts/lang/types.ts - EngineBus, EngineBusOptions: libs/bus/types.ts → arts/bus/types.ts - SILENT_BUS: libs/bus/silent-bus.ts → arts/bus/silent-bus.ts - SILENT_LOGGER: libs/logger/silent-logger.ts → arts/logger/silent-logger.ts - EngineTimers, EngineTimersOptions: libs/timer/types.ts → arts/timer/types.ts - bus-context.svelte.ts: libs/active-app/ → arts/active-app/ New: EventSubscriber<TEvents> contract in libs/bus/types.ts. EngineBus now extends EventPublisher + EventSubscriber. libs/active-app/events.ts uses it for AppEventBus instead of Pick<EngineBus, 'on' | 'once'> so the libs layer no longer references the runtime interface. libs/logger/diagnostics.ts uses a private NOOP_LOGGER fallback. The public SILENT_LOGGER exports from $logger. Apply rule 6 to arts/timer: ErrorMessages dict (libs/timer/errors.ts) now references the same canonical builders the Timer*Error classes use, so the message lives in one place. Class constructors take semantic parameters (method, key, delayMs) instead of pre-formatted strings. Apply rule 6 to libs/days: codes + ErrorMessages + classes + guards. arts/format/errors.ts removed (FORMAT_ERROR_MESSAGES.INVALID_LOCALE was dead code). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
5 months ago |
|
|
0b2c4eb30b |
Consolidate error infrastructure into errors.ts per module
Apply the canonical error pattern (docs/conventions.md rule 6) to the remaining 16 modules: every module's <MOD>_ERR seed, <MOD>_ERR_* codes, <MOD>_ERROR_MESSAGES catalogue, error classes and is*Error guards now live in a single errors.ts file. consts.ts retains only configuration unrelated to errors (event names, default values, op identifiers). Modules consolidated: - libs/active-app, libs/auth, libs/bus, libs/cache, libs/dom, libs/lang, libs/perm, libs/timer (new errors.ts) - arts/active-app, arts/auth, arts/connection, arts/http, arts/logger, arts/perm, arts/session, arts/sium - svrs/perm `<MOD>_ERROR_MESSAGES: ErrorMessages` declared in every module, indexed by ErrCode. The ErrorMessages type was added to libs/errs/code in the previous pass; this commit propagates its use everywhere. `libs/errs/consts.ts` is the documented exception: its codes (`errs::format_invalid`, `errs::unknown`) live as string literals in consts.ts because errors.ts imports them and code.ts imports CodeFormatError from errors.ts — the import graph forbids using errCode() at that position. Side cleanups: - libs/cache: legacy CACHE_ERROR_MESSAGES dict (validation strings) renamed to CACHE_VALIDATION_MESSAGES so the canonical CACHE_ERROR_MESSAGES (ErrorMessages indexed by ErrCode) is the only symbol with that name. - libs/perm: PERM_MODULE = 'perm' added (it was implicit before). - arts/auth, arts/perm, arts/active-app: client-only error codes (request_failed, disposed, invalid_response, no_context, etc.) live in the artifact's errors.ts but reuse the libs <MOD>_ERR seed so every code in the family shares the same module prefix. - libs/timer: errors.ts created (didn't exist) housing the codes that were previously in consts.ts; library has no classes (timer error classes live in arts/timer/errors.ts and import the codes from libs/timer). - arts/sium: SIUM_ERR seed, codes and three error classes (SiumValidationError, SiumAsyncSchemaError, SiumDiscriminatedUnionError) consolidated. Classes were previously in core/types.ts; that file no longer carries error infrastructure. All call sites in arts/sium/core/* and arts/sium/types/* updated their imports from `./types`/`../core/types` to the module's `errors.ts`. All 1334 tests pass. 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 |