Repository navigation
v2.0.0
Nano Kit 2.0 🎉
What's new
- DevTools.
@nano_kit/devtoolsis a panel right on the page to inspect your stores: your signals, their values and a log of every change. - Development warnings. In development, the packages warn about common mistakes, like a missing route parameter or a missing translation.
- Tasks on signals. SSR and tests wait only for the data they need, not for every request in flight.
- Smarter dependency injection. Stores are shared between nested contexts unless a context overrides what they depend on. The new
provideAsswaps an implementation, like a mock API in tests. SignalsMapclass. The reactive map now has the familiarMapAPI.- Operators. With static operands they return a plain value, and
pick,textandlatestare new. - intl.
relativetime()picks the unit by itself, from "5 minutes ago" to "yesterday", andformat()messages accept signals. - Preact 11 and SvelteKit 3 are supported.
Upgrading from 1.x
The breaking changes below list everything. The usual edits:
- Node.js 24 or newer is required.
inject(TasksRunner$)withtask(fn)becomestask($signal, fn),waitTasks(pool)becomeswaitTasks($signal), andclient(ssr())orclient(tasks(), hydratable())becomesclient(hydratable()).context.set(token, value)becomescontext.deps.set(token, value). To keep a store per context, provide it in that context.$getMapKey(map, key),setMapKey,deleteMapKeyandclearMapbecomemap.$get(key),map.set,map.deleteandmap.clearof anew SignalsMap().- An operator with static operands returns the value, not an accessor, and
concat($first, ' ', $last)becomestext`${$first} ${$last}`(theftag in the notes below shipped astext). resolvedkeeps a falsy value as data: express an empty state with the type, such asUser | null.- An
effectcreated in a deferred scope body no longer defers: usedeferEffectthere. relativetime()takes a moment instead of a count, and itsunitoption is gone: setlargestUnitandsmallestUnitto one unit to format in it.
Where to start
- 📚 Documentation: guides for every package
- 🛠️ DevTools: install the panel and open it with Alt+Shift+D
- 🤖 Agent Skills: teach your coding agent the Nano Kit API
⚠ BREAKING CHANGES
- store,query:
$getMapKey,setMapKey,deleteMapKey,clearMap,subMapEvent,
fireMapEvent,$$insert,$$clear,$$deletedand theSignalsMapEventand
SignalsMapEventstypes are removed from@nano_kit/store, andSignalsMapis a class to
create withnew, not a type over a plainMap. Thecacheof a query client context is
aShardedSignalsMap: itshas,setanddeletetake a sharded key. - agera,kida:
effectno longer defers when created inside a deferred scope body: use
deferEffectthere.subscribe,listen,observeandsubscribeAnyno longer accept the
noDeferargument. - kida,store,react,svelte-kit:
InjectionContextno longer extendsMap: its values are in the publicdeps
map, socontext.set(token, value)becomescontext.deps.set(token, value). A dependency that
is not provided is no longer created in the context that injects it first, and a context no
longer takes a dependency from above when it overrides what that dependency reads. - intl:
relativetime()takes a moment, a date, a timestamp or a date string,
instead of a count of units, and itsunitoption is gone, so a call that passes it no
longer compiles. Format in one unit withlargestUnitandsmallestUnitset to it, and
format a count of units withIntl.RelativeTimeFormator aplural()message. - kida:
resolvedhands values through verbatim - a falsy source value is data, not a
reset toundefined: emptiness is expressed byTitself (e.g.T | null), and the input type
drops the falsy arm. - kida,store: an operator called with static operands returns the value, not an accessor.
concatis removed, theftag takes its place. - the packages require Node.js 24 or newer.
- kida,store,query: the tasks pool is gone —
TasksPool$,TasksRunner$,tasksRunner,addTask,
waitCurrentTasksandtaskPromiseare removed,waitTaskstakes a signal instead of a pool, and
thetasks()andssr()query settings are removed:hydratable()is the whole SSR setting.
Features
- add development diagnostics with separate development and production builds (#236) (39be996)
- agera,kida,store: add
uninspectedto keep the nodes of a listener out ofinspect, and the old value toUpdateEvent(#262) (83384ce) - agera,kida: add
deferEffectfor effects owned by a deferred scope (#257) (12cb14b) - agera: add
inspectto report graph events in the development build (#237) (07e4290) - agera: call the
inspectlistener with one event object (#264) (f49ec73) - agera: enclose the lifecycle listeners of a node between
FireEventandFireEndEvent(#267) (ef084b7) - agera: report the end of a run with
RunEndEvent, and leaveoldValueout of a first evaluation (#265) (61186e0) - devtools,store: add the DevTools panel (#263) (bc1e51a)
- intl: accept a signal, an accessor or
nullas the value of aformat()message (#286) (4010477) - intl: make
relativetime()take a moment and pick the unit by the distance (#287) (cdf1238) - intl: use a plain string translation for every plural form and match case (#246) (82d45cf)
- kida,store,query: attach tasks to the signals they fill (#222) (841acd1)
- kida,store,react,svelte-kit: create a dependency in the deepest context that provides what it reads, and add
provideAs(#279) (5052174) - kida,store: move
latestfromkidato@nano_kit/store(#296) (f503e28) - kida,store: return a plain result from the operators when every operand is static (#260) (3a8b32f)
- kida: add
latestfor the value of the source that changed last (#231) (84efaed) - kida: attach the
resolvedpromise as a task and hand values through verbatim (#223) (8fabbeb) - kida: export
childto build custom child signals (#250) (8794697) - kida: rename the template tag
ftotext(505d947) - preact,preact-router,preact-ssr: support Preact 11 (#302) (b05c190)
- require Node.js 24 (#268) (c6ed062)
- store,query: replace the signals map functions with the
SignalsMapandIndexedSignalsMapclasses (#261) (c062f06) - svelte-kit: support SvelteKit 3 (#299) (b2c54bb)
Bug Fixes
- agera: drop the development warning about a signal written inside a computed (#266) (21e269b)
- agera: mount a mountable first read on a re-run of a computed that another computed reads (#294) (df898de)
- agera: queue
batchandtriggerwrites onto a running flush instead of draining it (#256) (d6afbdd) - deps: update dependency @astrojs/starlight to ^0.42.0 (#228) (bb5a65c)
- deps: update dependency jotai to v3 (#243) (a6c972f)
- deps: update dependency mobx to v7 (#184) (5c3ff53)
- deps: update dependency starlight-llms-txt to ^0.12.0 (#258) (d52874c)
- deps: update dependency starlight-sidebar-topics to ^0.9.0 (#232) (65da70d)
- intl: do not warn that a
format()message is missing from the translations (#285) (3c12504) - intl: require explicit options next to a fallback in the Intl formatters (#245) (6b3d44e)
- kida: keep
onMountsubscribed when a signal remounts within the unmount delay (#229) (b911d4c) - kida: type
record()anddeepRecord()of aSignalishsource as readable (#295) (ffe5453) - next-router: let a nested
NextNavigationProviderpick up search params below a prerenderable layout (#242) (13a2eb3) - platform-web,svelte-kit: round-trip any value through the cookie storage on the server and in the browser (#289) (8ed53a3)
- platform-web: accept
nullinparseLocalesfor a missingAccept-Languageheader (#244) (1e29516) - platform-web: broadcast
broadcastedwrites and resets while the signal is not observed (#247) (2696386) - platform-web: expire a cookie immediately with
maxAge: 0(#248) (bae248e) - preact: reuse the parent context by default in
HydrationProvider, as React does (#249) (cb2d9e2) - query: drop the development warning about a cache key shard registered twice (#275) (6a0749b)
- query: refetch a query revalidated while its request is in flight (#284) (2c0ed97)
- router,ssr: render the
httpEquivmeta prop as thehttp-equivattribute (#253) (568df71) - router: stop
back()andforward()ofbrowserNavigationfrom throwingIllegal invocation(#290) (f747eaf) - ssr,react-ssr,preact-ssr,svelte-ssr: escape head values and the dehydrated snapshot in the rendered html (#239) (60eefe2)
- ssr: link the stylesheets of a chunk after those of the chunks it imports (#282) (07b0c48)
- svelte-router: re-render
Appwhen the matched page component changes (#241) (0d44ed1) - svelte-router: resolve
getLocation,getNavigation,getPathsandgetCanGoBackthrough the Svelte context (#240) (2e465d3)