Last active 1753446413

svp revised this gist 1753446412. Go to revision

1 file changed, 83 insertions

local-storage.service.ts(file created)

@@ -0,0 +1,83 @@
1 + import { Injectable } from '@angular/core';
2 + import { fromEvent, merge, Observable, Subject } from 'rxjs';
3 + import { filter, map, startWith } from 'rxjs/operators';
4 +
5 + export interface LocalStorageObject {
6 + name: string;
7 + value: string | null;
8 + }
9 +
10 + const deserializeValue = <T>(value: string): T => {
11 + try {
12 + return JSON.parse(value);
13 + } catch {
14 + return value as unknown as T;
15 + }
16 + };
17 +
18 + @Injectable({
19 + providedIn: 'root',
20 + })
21 + export class LocalStorageService {
22 + private _storage = window.localStorage;
23 +
24 + private _storageUpdateNotifier$ = new Subject<LocalStorageObject | null>();
25 +
26 + storageUpdates$ = this._storageUpdateNotifier$.asObservable();
27 +
28 + initLocalStorage(storageObjs: LocalStorageObject[]): void {
29 + if (this._isLocalStorageEnabled()) {
30 + storageObjs.forEach(({ name, value }) => {
31 + this._storage.setItem(name, value);
32 + });
33 + }
34 + }
35 +
36 + setItem(key: string, value: string): void {
37 + this._storage.setItem(key, value);
38 + this._storageUpdateNotifier$.next({ name: key, value });
39 + }
40 +
41 + getItem(key: string): any {
42 + const retrieved = this._storage.getItem(key);
43 + try {
44 + return deserializeValue(retrieved);
45 + } catch {
46 + return retrieved;
47 + }
48 + }
49 +
50 + removeItem(key: string): void {
51 + this._storage.removeItem(key);
52 + this._storageUpdateNotifier$.next({ name: key, value: null });
53 + }
54 +
55 + clear(): void {
56 + this._storage.clear();
57 + this._storageUpdateNotifier$.next(null);
58 + }
59 +
60 + getUpdatesForKey<T>(key: string): Observable<T> {
61 + return merge(
62 + fromEvent(window, 'storage').pipe(
63 + filter((event: StorageEvent) => event.key === key),
64 + map(data => deserializeValue(data.newValue))
65 + ),
66 + this.storageUpdates$.pipe(
67 + filter(update => update.name === key),
68 + map(update => deserializeValue(update.value))
69 + )
70 + ).pipe(startWith(this.getItem(key) || false));
71 + }
72 +
73 + private _isLocalStorageEnabled(): boolean {
74 + try {
75 + const key = `__storage__test`;
76 + this._storage.setItem(key, null);
77 + this._storage.removeItem(key);
78 + return true;
79 + } catch (e) {
80 + return false;
81 + }
82 + }
83 + }
Newer Older