Hot Reload (hotReload)
hotReload() lets you pick parts of your app's state that survive a page
refresh.
hotReloadwas written as a debugging aid: reload the page while you work and keep your place. It may be useful more generally, but it has not been tested for production use and is not intended for it.
hotReload(test: PathTestFunction = () => true): void
Call it after registering your initial state. test is called with the name of
each top-level piece of state and returns true for the ones to keep; with no
argument, everything is kept.
import { tosi, hotReload } from 'tosijs'
const { app, prefs } = tosi({
app: { draft: '' },
prefs: { theme: 'system' },
})
// keep prefs across reloads, start app fresh each time
hotReload((name) => name === 'prefs')
The chosen state is saved to
localStorage
when it changes, and on the next load the saved values replace the initial ones.
To reset, run localStorage.removeItem('xin-state') in the console.
Why not to use it for anything serious
- It only keeps what survives
JSON.stringify.localStoragestores strings, so plain data comes back and anything richer does not: an instance of a class returns as a bare object, and aDate,MaporSetdoes not return as itself. - You choose what is kept because not everything can be. A restore replaces each saved piece of state whole, with what came back from storage, so methods on it are gone (functions cannot be stored) and so is any field you have added to your code since the save. Use the test function to keep the pieces that are plain data (preferences, a draft, the current selection) and leave out the ones that carry behaviour. Reset after changing the shape of something you keep.
- There is one save per origin, under the key
xin-state. Two apps served from the same origin that both callhotReloadwill overwrite each other. localStorageis local, not secure, and has arbitrary limits. The data stays on that one browser, anything running on the page can read it, and browsers cap how much you can store.
Saving is debounced, so it is at least not pathologically bad: a burst of changes produces one write.
A production-ready version of this would:
- explicitly serialize and deserialize complex state where appropriate,
- use IndexedDB to avoid the arbitrary limits and to take the work off the main thread, and
- probably encrypt the data where appropriate, using a secret stored in the cloud.
That is not a gap hotReload is waiting to fill. We have built exactly that for
a production app, and every one of those choices (what to serialize and how,
what to encrypt, where the secret lives) belonged to that app. It cannot be made
one-size-fits-all, so tosijs does not try: build it for your app, on top of
observe.
We could ship it with a pluggable storage backend and a pluggable transformation function, but that would leave you writing the two parts that matter and are easy to get wrong. Storing data securely is not something to do through a plug-in you did not need to understand.