Changelog - 2026-11-04
StorageCodecs.text reads and writes a bare string
New FeatureIn one line. StorageCodecs.text() is a storage codec for a key whose data is a bare string (dark, not "dark"). The default JSON codec cannot read such a key; this one reads and writes it as it is. StorageCodecs.text({ allowed }) also refuses a value outside a list.
tsx
import { StorageCodecs, useStoredState } from '@venizia/ardor';
const THEME = StorageCodecs.text({ allowed: ['light', 'dark'] });
export function ThemeSwitch() {
const { value, setValue } = useStoredState({
key: '@app/store/theme',
defaultValue: 'light',
codec: THEME,
});
return <button onClick={() => setValue(value === 'dark' ? 'light' : 'dark')}>{value}</button>;
}What changed
- A public plain-text codec.
StorageCodecs.text()returns anIStorageCodec<string>. Create it once, outside a component, becauseuseStoredStateasks for a stablecodec. allowed. The codec is typed by the list:StorageCodecs.text({ allowed: ['light', 'dark'] })is anIStorageCodec<'light' | 'dark'>, sosetandsetValuereject another literal at compile time, anduseStoredStategives avalueof that union. A stored text outside the list does not decode, soBrowserStorage.getgives itsfallbackanduseStoredStategives itsdefaultValue. A value outside the list does not encode, soBrowserStorage.setreturnsfalseand leaves the storage as it was. The error names no value, because a stored text can be a token.useStoredStateuses it too. The hook reads the raw stored text through this codec instead of keeping its own, so no second plain-text codec exists. Withallowed, a value outside the list is not stored, andsetValuetreats it like any write the storage refuses: the hook keeps it until the storage next changes.IUseStoredState. It is the type of the hook's two overloads: with acodecthe value type is the codec's, without one it isTValue.- A fallback of another type. With a
codec,BrowserStorage.getaccepts afallbackof another type than the codec's value, such asnull, and answers the union. In the other direction, with acodecthe value ofBrowserStorage.setand thedefaultValueofuseStoredStateare checked against the codec's type instead of widening a literal past it. These are type changes only; nothing changes at run time.
Who is affected
- An app that stores a bare string (a theme name, a language code, a mode) and wrote its own codec for it. You can use
StorageCodecs.text()and delete the codec. - All other apps. No action needed.
See Browser storage and Hooks.