@larscom/ngrx-signals-storage
Version:
Save signal state (@ngrx/signals) to localstorage/sessionstorage and restore the state on page load (with SSR support).
83 lines (78 loc) • 2.71 kB
JavaScript
import { isPlatformServer } from '@angular/common';
import { inject, effect, PLATFORM_ID } from '@angular/core';
import { signalStoreFeature, withHooks, getState, patchState } from '@ngrx/signals';
const defaultConfig = {
excludeKeys: [],
serialize: (state) => JSON.stringify(state),
deserialize: (state) => JSON.parse(state),
saveIf: (state) => true,
error: (error) => console.error(error)
};
/**
* The `withStorage` function that lets you save the state to localstorage/sessionstorage
* and rehydrate the state upon page load.
*
* @param key the key under which the state should be saved into `Storage`
* @param storage function that returns an implementation of the `Storage` interface, like: `sessionStorage` or `localStorage`
*
* @example
* export const CounterStore = signalStore(
* withState({
* count: 0
* }),
* withStorage('myKey', () => sessionStorage)
* )
*/
function withStorage(key, storage, config) {
return signalStoreFeature(withHooks({
onInit(store, platformId = inject(PLATFORM_ID)) {
if (isPlatformServer(platformId)) {
return;
}
const cfg = { ...defaultConfig, ...config };
const item = getFromStorage(key, storage(), cfg);
const stateFromStorage = item ? cfg.deserialize(item) : null;
if (stateFromStorage != null) {
const stateSignalKeys = Object.keys(store);
const state = stateSignalKeys.reduce((state, key) => {
const value = stateFromStorage[key];
return value !== undefined
? {
...state,
[key]: value
}
: state;
}, getState(store));
patchState(store, state);
}
effect(() => {
const state = structuredClone(getState(store));
try {
if (cfg.saveIf(state)) {
cfg.excludeKeys.forEach((key) => {
delete state[key];
});
storage().setItem(key, cfg.serialize(state));
}
}
catch (e) {
cfg.error(e);
}
});
}
}));
}
function getFromStorage(key, storage, cfg) {
try {
return storage.getItem(key);
}
catch (e) {
cfg.error(e);
return null;
}
}
/**
* Generated bundle index. Do not edit.
*/
export { withStorage };
//# sourceMappingURL=larscom-ngrx-signals-storage.mjs.map