UNPKG

@spartacus/core

Version:

Spartacus - the core framework

74 lines 12.3 kB
import { Injectable } from '@angular/core'; import { of, Subscription } from 'rxjs'; import { map, tap, withLatestFrom } from 'rxjs/operators'; import { StorageSyncType } from '../../state/config/state-config'; import { getStorage, persistToStorage, readFromStorage, } from '../utils/browser-storage'; import * as i0 from "@angular/core"; import * as i1 from "../../window/window-ref"; export class StatePersistenceService { constructor(winRef) { this.winRef = winRef; } /** * Helper to synchronize state to more persistent storage (localStorage, sessionStorage). * It is context aware, so you can keep different state for te same feature based on specified context. * * Eg. cart is valid only under the same base site. So you want to synchronize cart only with the same base site. * Usage for that case: `syncWithStorage({ key: 'cart', state$: activeCartSelector$, context$: this.siteContextParamsService.getValues([BASE_SITE_CONTEXT_ID]), onRead: (state) => setCorrectStateInStore(state) })`. * Active cart for the `electronics` base site will be stored under `spartacus⚿electronics⚿cart` and for apparel under `spartacus⚿apparel⚿cart`. * * On each context change onRead function will be executed with state from storage provided as a parameter. * * Omitting context$ will trigger onRead only once at initialization. * * @param key Key to use in storage for the synchronized state. Should be unique for each feature. * @param state$ State to be saved and later restored. * @param context$ Context for state * @param storageType Storage type to be used to persist state * @param onRead Function to be executed on each storage read after context change * * @returns Subscriptions for reading/writing in storage on context/state change */ syncWithStorage({ key, state$, context$ = of(''), storageType = StorageSyncType.LOCAL_STORAGE, onRead = () => { }, }) { const storage = getStorage(storageType, this.winRef); const subscriptions = new Subscription(); // Do not change order of subscription! Read should happen before write on context change. subscriptions.add(context$ .pipe(map((context) => { return readFromStorage(storage, this.generateKeyWithContext(context, key)); }), tap((state) => onRead(state))) .subscribe()); subscriptions.add(state$.pipe(withLatestFrom(context$)).subscribe(([state, context]) => { persistToStorage(this.generateKeyWithContext(context, key), state, storage); })); return subscriptions; } /** * Helper to read state from persistent storage (localStorage, sessionStorage). * It is useful if you need synchronously access state saved with `syncWithStorage`. * * @param key Key to use in storage for state. Should be unique for each feature. * @param context Context value for state * @param storageType Storage type from to read state * * @returns State from the storage */ readStateFromStorage({ key, context = '', storageType = StorageSyncType.LOCAL_STORAGE, }) { const storage = getStorage(storageType, this.winRef); return readFromStorage(storage, this.generateKeyWithContext(context, key)); } generateKeyWithContext(context, key) { return `spartacus⚿${[] .concat(context) .join('⚿')}${key}`; } } StatePersistenceService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: StatePersistenceService, deps: [{ token: i1.WindowRef }], target: i0.ɵɵFactoryTarget.Injectable }); StatePersistenceService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: StatePersistenceService, providedIn: 'root' }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: StatePersistenceService, decorators: [{ type: Injectable, args: [{ providedIn: 'root', }] }], ctorParameters: function () { return [{ type: i1.WindowRef }]; } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhdGUtcGVyc2lzdGVuY2Uuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2NvcmUvc3JjL3N0YXRlL3NlcnZpY2VzL3N0YXRlLXBlcnNpc3RlbmNlLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQWMsRUFBRSxFQUFFLFlBQVksRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNwRCxPQUFPLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxjQUFjLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUMxRCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFFbEUsT0FBTyxFQUNMLFVBQVUsRUFDVixnQkFBZ0IsRUFDaEIsZUFBZSxHQUNoQixNQUFNLDBCQUEwQixDQUFDOzs7QUFLbEMsTUFBTSxPQUFPLHVCQUF1QjtJQUNsQyxZQUFzQixNQUFpQjtRQUFqQixXQUFNLEdBQU4sTUFBTSxDQUFXO0lBQUcsQ0FBQztJQUUzQzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztPQW1CRztJQUNILGVBQWUsQ0FBSSxFQUNqQixHQUFHLEVBQ0gsTUFBTSxFQUNOLFFBQVEsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQ2pCLFdBQVcsR0FBRyxlQUFlLENBQUMsYUFBYSxFQUMzQyxNQUFNLEdBQUcsR0FBRyxFQUFFLEdBQUUsQ0FBQyxHQU9sQjtRQUNDLE1BQU0sT0FBTyxHQUFHLFVBQVUsQ0FBQyxXQUFXLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBRXJELE1BQU0sYUFBYSxHQUFHLElBQUksWUFBWSxFQUFFLENBQUM7UUFFekMsMEZBQTBGO1FBQzFGLGFBQWEsQ0FBQyxHQUFHLENBQ2YsUUFBUTthQUNMLElBQUksQ0FDSCxHQUFHLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRTtZQUNkLE9BQU8sZUFBZSxDQUNwQixPQUFPLEVBQ1AsSUFBSSxDQUFDLHNCQUFzQixDQUFDLE9BQU8sRUFBRSxHQUFHLENBQUMsQ0FDekIsQ0FBQztRQUNyQixDQUFDLENBQUMsRUFDRixHQUFHLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUM5QjthQUNBLFNBQVMsRUFBRSxDQUNmLENBQUM7UUFFRixhQUFhLENBQUMsR0FBRyxDQUNmLE1BQU0sQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLEVBQUUsRUFBRTtZQUNuRSxnQkFBZ0IsQ0FDZCxJQUFJLENBQUMsc0JBQXNCLENBQUMsT0FBTyxFQUFFLEdBQUcsQ0FBQyxFQUN6QyxLQUFLLEVBQ0wsT0FBTyxDQUNSLENBQUM7UUFDSixDQUFDLENBQUMsQ0FDSCxDQUFDO1FBRUYsT0FBTyxhQUFhLENBQUM7SUFDdkIsQ0FBQztJQUVEOzs7Ozs7Ozs7T0FTRztJQUNILG9CQUFvQixDQUFJLEVBQ3RCLEdBQUcsRUFDSCxPQUFPLEdBQUcsRUFBRSxFQUNaLFdBQVcsR0FBRyxlQUFlLENBQUMsYUFBYSxHQUs1QztRQUNDLE1BQU0sT0FBTyxHQUFHLFVBQVUsQ0FBQyxXQUFXLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBRXJELE9BQU8sZUFBZSxDQUNwQixPQUFPLEVBQ1AsSUFBSSxDQUFDLHNCQUFzQixDQUFDLE9BQU8sRUFBRSxHQUFHLENBQUMsQ0FDekIsQ0FBQztJQUNyQixDQUFDO0lBRVMsc0JBQXNCLENBQzlCLE9BQStCLEVBQy9CLEdBQVc7UUFFWCxPQUFPLGFBQWMsRUFBb0I7YUFDdEMsTUFBTSxDQUFDLE9BQU8sQ0FBQzthQUNmLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxHQUFHLEVBQUUsQ0FBQztJQUN4QixDQUFDOztvSEF0R1UsdUJBQXVCO3dIQUF2Qix1QkFBdUIsY0FGdEIsTUFBTTsyRkFFUCx1QkFBdUI7a0JBSG5DLFVBQVU7bUJBQUM7b0JBQ1YsVUFBVSxFQUFFLE1BQU07aUJBQ25CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgb2YsIFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgbWFwLCB0YXAsIHdpdGhMYXRlc3RGcm9tIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgU3RvcmFnZVN5bmNUeXBlIH0gZnJvbSAnLi4vLi4vc3RhdGUvY29uZmlnL3N0YXRlLWNvbmZpZyc7XG5pbXBvcnQgeyBXaW5kb3dSZWYgfSBmcm9tICcuLi8uLi93aW5kb3cvd2luZG93LXJlZic7XG5pbXBvcnQge1xuICBnZXRTdG9yYWdlLFxuICBwZXJzaXN0VG9TdG9yYWdlLFxuICByZWFkRnJvbVN0b3JhZ2UsXG59IGZyb20gJy4uL3V0aWxzL2Jyb3dzZXItc3RvcmFnZSc7XG5cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnLFxufSlcbmV4cG9ydCBjbGFzcyBTdGF0ZVBlcnNpc3RlbmNlU2VydmljZSB7XG4gIGNvbnN0cnVjdG9yKHByb3RlY3RlZCB3aW5SZWY6IFdpbmRvd1JlZikge31cblxuICAvKipcbiAgICogSGVscGVyIHRvIHN5bmNocm9uaXplIHN0YXRlIHRvIG1vcmUgcGVyc2lzdGVudCBzdG9yYWdlIChsb2NhbFN0b3JhZ2UsIHNlc3Npb25TdG9yYWdlKS5cbiAgICogSXQgaXMgY29udGV4dCBhd2FyZSwgc28geW91IGNhbiBrZWVwIGRpZmZlcmVudCBzdGF0ZSBmb3IgdGUgc2FtZSBmZWF0dXJlIGJhc2VkIG9uIHNwZWNpZmllZCBjb250ZXh0LlxuICAgKlxuICAgKiBFZy4gY2FydCBpcyB2YWxpZCBvbmx5IHVuZGVyIHRoZSBzYW1lIGJhc2Ugc2l0ZS4gU28geW91IHdhbnQgdG8gc3luY2hyb25pemUgY2FydCBvbmx5IHdpdGggdGhlIHNhbWUgYmFzZSBzaXRlLlxuICAgKiBVc2FnZSBmb3IgdGhhdCBjYXNlOiBgc3luY1dpdGhTdG9yYWdlKHsga2V5OiAnY2FydCcsIHN0YXRlJDogYWN0aXZlQ2FydFNlbGVjdG9yJCwgY29udGV4dCQ6IHRoaXMuc2l0ZUNvbnRleHRQYXJhbXNTZXJ2aWNlLmdldFZhbHVlcyhbQkFTRV9TSVRFX0NPTlRFWFRfSURdKSwgb25SZWFkOiAoc3RhdGUpID0+IHNldENvcnJlY3RTdGF0ZUluU3RvcmUoc3RhdGUpIH0pYC5cbiAgICogQWN0aXZlIGNhcnQgZm9yIHRoZSBgZWxlY3Ryb25pY3NgIGJhc2Ugc2l0ZSB3aWxsIGJlIHN0b3JlZCB1bmRlciBgc3BhcnRhY3Vz4pq/ZWxlY3Ryb25pY3Pimr9jYXJ0YCBhbmQgZm9yIGFwcGFyZWwgdW5kZXIgYHNwYXJ0YWN1c+Kav2FwcGFyZWzimr9jYXJ0YC5cbiAgICpcbiAgICogT24gZWFjaCBjb250ZXh0IGNoYW5nZSBvblJlYWQgZnVuY3Rpb24gd2lsbCBiZSBleGVjdXRlZCB3aXRoIHN0YXRlIGZyb20gc3RvcmFnZSBwcm92aWRlZCBhcyBhIHBhcmFtZXRlci5cbiAgICpcbiAgICogT21pdHRpbmcgY29udGV4dCQgd2lsbCB0cmlnZ2VyIG9uUmVhZCBvbmx5IG9uY2UgYXQgaW5pdGlhbGl6YXRpb24uXG4gICAqXG4gICAqIEBwYXJhbSBrZXkgS2V5IHRvIHVzZSBpbiBzdG9yYWdlIGZvciB0aGUgc3luY2hyb25pemVkIHN0YXRlLiBTaG91bGQgYmUgdW5pcXVlIGZvciBlYWNoIGZlYXR1cmUuXG4gICAqIEBwYXJhbSBzdGF0ZSQgU3RhdGUgdG8gYmUgc2F2ZWQgYW5kIGxhdGVyIHJlc3RvcmVkLlxuICAgKiBAcGFyYW0gY29udGV4dCQgQ29udGV4dCBmb3Igc3RhdGVcbiAgICogQHBhcmFtIHN0b3JhZ2VUeXBlIFN0b3JhZ2UgdHlwZSB0byBiZSB1c2VkIHRvIHBlcnNpc3Qgc3RhdGVcbiAgICogQHBhcmFtIG9uUmVhZCBGdW5jdGlvbiB0byBiZSBleGVjdXRlZCBvbiBlYWNoIHN0b3JhZ2UgcmVhZCBhZnRlciBjb250ZXh0IGNoYW5nZVxuICAgKlxuICAgKiBAcmV0dXJucyBTdWJzY3JpcHRpb25zIGZvciByZWFkaW5nL3dyaXRpbmcgaW4gc3RvcmFnZSBvbiBjb250ZXh0L3N0YXRlIGNoYW5nZVxuICAgKi9cbiAgc3luY1dpdGhTdG9yYWdlPFQ+KHtcbiAgICBrZXksXG4gICAgc3RhdGUkLFxuICAgIGNvbnRleHQkID0gb2YoJycpLFxuICAgIHN0b3JhZ2VUeXBlID0gU3RvcmFnZVN5bmNUeXBlLkxPQ0FMX1NUT1JBR0UsXG4gICAgb25SZWFkID0gKCkgPT4ge30sXG4gIH06IHtcbiAgICBrZXk6IHN0cmluZztcbiAgICBzdGF0ZSQ6IE9ic2VydmFibGU8VD47XG4gICAgY29udGV4dCQ/OiBPYnNlcnZhYmxlPHN0cmluZyB8IEFycmF5PHN0cmluZz4+O1xuICAgIHN0b3JhZ2VUeXBlPzogU3RvcmFnZVN5bmNUeXBlO1xuICAgIG9uUmVhZD86IChzdGF0ZUZyb21TdG9yYWdlOiBUIHwgdW5kZWZpbmVkKSA9PiB2b2lkO1xuICB9KTogU3Vic2NyaXB0aW9uIHtcbiAgICBjb25zdCBzdG9yYWdlID0gZ2V0U3RvcmFnZShzdG9yYWdlVHlwZSwgdGhpcy53aW5SZWYpO1xuXG4gICAgY29uc3Qgc3Vic2NyaXB0aW9ucyA9IG5ldyBTdWJzY3JpcHRpb24oKTtcblxuICAgIC8vIERvIG5vdCBjaGFuZ2Ugb3JkZXIgb2Ygc3Vic2NyaXB0aW9uISBSZWFkIHNob3VsZCBoYXBwZW4gYmVmb3JlIHdyaXRlIG9uIGNvbnRleHQgY2hhbmdlLlxuICAgIHN1YnNjcmlwdGlvbnMuYWRkKFxuICAgICAgY29udGV4dCRcbiAgICAgICAgLnBpcGUoXG4gICAgICAgICAgbWFwKChjb250ZXh0KSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gcmVhZEZyb21TdG9yYWdlKFxuICAgICAgICAgICAgICBzdG9yYWdlLFxuICAgICAgICAgICAgICB0aGlzLmdlbmVyYXRlS2V5V2l0aENvbnRleHQoY29udGV4dCwga2V5KVxuICAgICAgICAgICAgKSBhcyBUIHwgdW5kZWZpbmVkO1xuICAgICAgICAgIH0pLFxuICAgICAgICAgIHRhcCgoc3RhdGUpID0+IG9uUmVhZChzdGF0ZSkpXG4gICAgICAgIClcbiAgICAgICAgLnN1YnNjcmliZSgpXG4gICAgKTtcblxuICAgIHN1YnNjcmlwdGlvbnMuYWRkKFxuICAgICAgc3RhdGUkLnBpcGUod2l0aExhdGVzdEZyb20oY29udGV4dCQpKS5zdWJzY3JpYmUoKFtzdGF0ZSwgY29udGV4dF0pID0+IHtcbiAgICAgICAgcGVyc2lzdFRvU3RvcmFnZShcbiAgICAgICAgICB0aGlzLmdlbmVyYXRlS2V5V2l0aENvbnRleHQoY29udGV4dCwga2V5KSxcbiAgICAgICAgICBzdGF0ZSxcbiAgICAgICAgICBzdG9yYWdlXG4gICAgICAgICk7XG4gICAgICB9KVxuICAgICk7XG5cbiAgICByZXR1cm4gc3Vic2NyaXB0aW9ucztcbiAgfVxuXG4gIC8qKlxuICAgKiBIZWxwZXIgdG8gcmVhZCBzdGF0ZSBmcm9tIHBlcnNpc3RlbnQgc3RvcmFnZSAobG9jYWxTdG9yYWdlLCBzZXNzaW9uU3RvcmFnZSkuXG4gICAqIEl0IGlzIHVzZWZ1bCBpZiB5b3UgbmVlZCBzeW5jaHJvbm91c2x5IGFjY2VzcyBzdGF0ZSBzYXZlZCB3aXRoIGBzeW5jV2l0aFN0b3JhZ2VgLlxuICAgKlxuICAgKiBAcGFyYW0ga2V5IEtleSB0byB1c2UgaW4gc3RvcmFnZSBmb3Igc3RhdGUuIFNob3VsZCBiZSB1bmlxdWUgZm9yIGVhY2ggZmVhdHVyZS5cbiAgICogQHBhcmFtIGNvbnRleHQgQ29udGV4dCB2YWx1ZSBmb3Igc3RhdGVcbiAgICogQHBhcmFtIHN0b3JhZ2VUeXBlIFN0b3JhZ2UgdHlwZSBmcm9tIHRvIHJlYWQgc3RhdGVcbiAgICpcbiAgICogQHJldHVybnMgU3RhdGUgZnJvbSB0aGUgc3RvcmFnZVxuICAgKi9cbiAgcmVhZFN0YXRlRnJvbVN0b3JhZ2U8VD4oe1xuICAgIGtleSxcbiAgICBjb250ZXh0ID0gJycsXG4gICAgc3RvcmFnZVR5cGUgPSBTdG9yYWdlU3luY1R5cGUuTE9DQUxfU1RPUkFHRSxcbiAgfToge1xuICAgIGtleTogc3RyaW5nO1xuICAgIGNvbnRleHQ/OiBzdHJpbmcgfCBBcnJheTxzdHJpbmc+O1xuICAgIHN0b3JhZ2VUeXBlPzogU3RvcmFnZVN5bmNUeXBlO1xuICB9KTogVCB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3Qgc3RvcmFnZSA9IGdldFN0b3JhZ2Uoc3RvcmFnZVR5cGUsIHRoaXMud2luUmVmKTtcblxuICAgIHJldHVybiByZWFkRnJvbVN0b3JhZ2UoXG4gICAgICBzdG9yYWdlLFxuICAgICAgdGhpcy5nZW5lcmF0ZUtleVdpdGhDb250ZXh0KGNvbnRleHQsIGtleSlcbiAgICApIGFzIFQgfCB1bmRlZmluZWQ7XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2VuZXJhdGVLZXlXaXRoQ29udGV4dChcbiAgICBjb250ZXh0OiBzdHJpbmcgfCBBcnJheTxzdHJpbmc+LFxuICAgIGtleTogc3RyaW5nXG4gICk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGBzcGFydGFjdXPimr8keyhbXSBhcyBBcnJheTxzdHJpbmc+KVxuICAgICAgLmNvbmNhdChjb250ZXh0KVxuICAgICAgLmpvaW4oJ+KavycpfeKavyR7a2V5fWA7XG4gIH1cbn1cbiJdfQ==