versioned-local-storage v1.0.3
Versioned local storage
Problem to be solved:
When working with localStorage you can run in to some issues
- Does the user already have some data in the
localStorage? - If the user has data in
localStorage, is it valid or is it outdated
The goal of the package is to create a wrapper around localStorage that ensures a valid state, matching the current app version.
Installation:
npm i versioned-local-storageThe project is maintained on Gitlab
Api:
Creating an instance
Creating a new storage instance:
// type is `VersionedLocalStorage<null>`
const storage = getVersionedLocalStorage('storageKey').build();Every storage instance starts with version number 0 and type null.
To add a value and type you need to add a new version:
// type is `VersionedLocalStorage<string>`
const storage = getVersionedLocalStorage('storageKey')
.addVersion((oldValue: null) => "some string value")
.build();It is important never to remove versions that have already been in production. If you'd want to change wrap the string in an object you'd have to add a new version:
// type is `VersionedLocalStorage<{ stringValue: string }>`
const storage = getVersionedLocalStorage('storageKey')
.addVersion(() => "some string value")
.addVersion(oldString => ({ stringValue: oldString }))
.build();Say you'd want to make stringValue nullable, typescript won't be able to infer the type by the return value.
You'll need to specify the type explicitly:
// type is `VersionedLocalStorage<{ stringValue?: string }>`
const storage = getVersionedLocalStorage('storageKey')
.addVersion(() => "some string value")
.addVersion(oldString => ({ stringValue: oldString }))
.addVersion<{ stringValue?: string }>(value => value)
.build();Note that in this case, the value doesn't actually have to change
Reading and updating the values
const storage = getVersionedLocalStorage('storageKey')
.addVersion(() => "some string value")
.addVersion(oldString => ({ stringValue: oldString }))
.addVersion<{ stringValue?: string }>()
.build();
console.log(storage.value);
storage.value = {};
storage.value = { stringValue: 'Different string' };Setting the .value attribute updates the localStorage.
But watch out, you should treat the value as immutable, if you update a property in the value it won't update the localStorage.
// wrong:
storage.value.stringValue = 'Different string';
// Right:
storage.value = { stringValue: 'Different string' };Another pitfall is setting a value that has a cyclic reference.
Under the hood, assigning to storage.value stringifies the value and stores it in localStorage.
Because objects with a cyclic reference can't be stringify'ed, you also can't assign such an object to storage.value.
Deprecating a storage key
When you don't need a value anymore you can call .deprecate() instead of .build()
const storage = getVersionedLocalStorage('storageKey')
.addVersion(() => "some string value")
.addVersion(oldString => ({ stringValue: oldString }))
.addVersion<{ stringValue?: string }>()
.deprecate();