v0.5.0
Minor Changes
-
ee8ddab: API wave — field-report driven, panel-validated:
onReady(cb)on the attune handle: register render-critical wiring from
modules the config module must not import (router basepath, i18n) — no more
import cycles. One queue withonLoad(which is now just the first
callback), awaited in registration order beforeload()resolves; callback
errors reject the load asConfigError. Registered after resolve: runs
immediately with a DEV warning; after a failed load: never runs.bindReact(attuned): React binding over an existing core handle, so the
schema can live in a leaf module importable byattunement checkand tests.
attuneReact(options)is unchanged (it is nowbindReact(attune(options))).errorFallback(error, retry): function fallbacks get aretryargument
(currently a full page reload); the default fallback gains a Retry button.
The config boundary now rethrows errors that aren'tConfigError, so app
bugs reach your own error boundary instead of masquerading as config
failures. NewonErrorprop on Provider for Sentry-style reporting.optional(source)exported: failure → undefined → merge/chain falls
through (was a recipe).fromJsonnow defaultscache: "no-store"— a CDN-cached stale config
survives reloads and turns Retry into a loop. Override with
fromJson(url, { cache: "default" })if you serve config with proper
invalidation.- Devtools:
fields?: FieldInfo[]onDevtoolsProps/docsTablebypasses
zod introspection (escape hatch for Valibot/ArkType).
attunementDevtoolsPlugin(config, { storageKey, fields })— second argument
is now an options object (wasstorageKeystring). - CLI:
check --strictturns secret-hygiene warnings into failures;
check --print-fingerprintprints the same hash the running app reports via
fingerprint(). - React entries ship a
"use client"banner. @standard-schema/specmoved todependencies(types-only) — public d.ts
imports it; consumers without a transitive copy previously got TS2307.- Note for type-level consumers:
AttunedgainedonReadyand an internal
_schema— hand-built mocks of the handle need updating.
-
bcb1108: Config fingerprint:
attune()/attuneReact()handles exposefingerprint()
resolving to{ hash, version?, generatedAt? }— a stable FNV-1a hash of the
validated config (key-order independent) plus_version/_generatedAtread
off the raw config when the deploy pipeline stamps them.onLoadreceives the
fingerprint as a second argument for Sentry scope / log prefix wiring.
Patch Changes
-
b205980: First batch of field-report fixes:
- Schema introspection unwraps
z.preprocess— zod 3ZodEffects
(_def.schema) and zod 4 pipes (_def.out) — so the documented
all-strings recipe renders checkboxes/selects in the devtools panel
instead of text inputs. ProviderwithouterrorFallbacknow renders a minimal "Configuration
failed to load." notice instead of a white page; the error message (config
keys, source URLs) shows in dev builds only. PasserrorFallback={null}
for the old behavior.AttunementDevtoolsacceptsposition("bottom-right" default,
"bottom-left", "top-right", "top-left") to dodge TanStack Query devtools
and friends.attunement check --diffwarns when fewer than two files matched instead
of silently skipping the diff.- README: migration-from-hand-rolled-loader section,
onLoadordering
guarantee vs.then(), lazy devtools import as the default pattern,
injectKeyin the Vite snippet, zod-only introspection caveat moved to
the Standard Schema bullet.
- Schema introspection unwraps