Skip to content

feat: rehydrate lazy-loaded reducers on demand (store.rehydrate) - #28

Open
KAMRONBEK wants to merge 2 commits into
zewish:masterfrom
KAMRONBEK:docs/lazy-loaded-reducers
Open

feat: rehydrate lazy-loaded reducers on demand (store.rehydrate)#28
KAMRONBEK wants to merge 2 commits into
zewish:masterfrom
KAMRONBEK:docs/lazy-loaded-reducers

Conversation

@KAMRONBEK

@KAMRONBEK KAMRONBEK commented Jul 17, 2026

Copy link
Copy Markdown

Adds first-class support for lazy-loaded / injected reducers via a new store.rehydrate(keys?) method. Addresses #26.

In #26 the concern was that injecting a persisted slice races the one-time rehydration: rehydrate() fires once at init, so a reducer injected later misses its stored value and starts from its initial state. This adds an explicit, opt-in way to load it after injection:

rootReducer.inject(lazyPersistedSlice);   // add the reducer
await store.rehydrate(['lazyPersisted']); // load its persisted state + keep persisting it
  • store.rehydrate(keys) reads those keys from storage, dispatches REMEMBER_REHYDRATED, and adds them to the remembered set so they persist from then on. With no arguments it re-reads every currently remembered key.
  • Non-persisted injected slices already worked (they just aren't in rememberedKeys); that case is documented too.

Changes:

  • index.ts — attach store.rehydrate (reuses the existing internal rehydrate); the enhancer returns Object.assign(store, { rehydrate }).
  • types.tsRehydrateFunction + RememberEnhancerStoreExt, set as the enhancer's default Ext so store.rehydrate is typed without extra generics.
  • tests — 3 new cases in index.test.ts; full suite 7812 pass, index.ts 100% covered; typecheck + lint clean.
  • docs — usage/lazy-loaded-reducers documents both cases and is linked in the sidebar.

Verified end-to-end against a real store + async driver: inject a slice, call store.rehydrate([key]), and it loads the persisted value; without the call it stays at its default (the race described in the issue).

A couple of things I'd defer to you:

  • naming (store.rehydrate vs something more scoped), and whether you'd rather it be opt-in behind an option instead of always attached.
  • the on-demand path currently reuses your migrate (identity by default). Happy to skip migrate on store.rehydrate if you'd prefer it only run at init.

I know lazy slices weren't on the roadmap, so if you'd rather not add API surface I'm glad to trim this back to just the docs page.

Adds store.rehydrate(keys?) so an injected/persisted reducer can be loaded
from storage after the store is created. Without it, a reducer injected after
init misses its one-time rehydration and its stored value is dropped.

- index.ts: attach store.rehydrate; it reads the given keys, dispatches
  REMEMBER_REHYDRATED, and adds them to the remembered set so they persist.
- types.ts: RehydrateFunction + RememberEnhancerStoreExt (default enhancer Ext),
  so store.rehydrate is typed without extra generics.
- tests: 3 new cases; full suite 7812 pass, index.ts 100% covered.
- docs: usage/lazy-loaded-reducers documents the API for both cases.
@KAMRONBEK KAMRONBEK changed the title docs: document lazy-loaded (injected) reducers feat: rehydrate lazy-loaded reducers on demand (store.rehydrate) Jul 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant