Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | 1x 1x 88x 88x 88x 88x 88x 88x 88x 100x 100x 88x 98x 14x 14x 14x 14x 14x 98x 88x 88x 88x 88x 88x 88x 89x 89x 88x 43x 43x 88x 87x 87x 87x 88x 67x 67x 88x 128x 128x 88x 16x 16x 88x 33x 33x 88x 2x 2x 88x 17x 17x 88x 17x 17x 88x 35x 19x 35x 6x 6x 6x 6x 6x 35x 13x 13x 13x 13x 13x 13x 19x 35x 88x 97x 97x 88x 7x 4x 4x 4x 4x 4x 4x 4x 4x 7x 88x 87x 87x 88x | import type { DataModel, StorageBase, ValueType } from "../types"; import { StorageEngine } from "../types"; /** @ignore */ export class SessionStorageStrategy implements StorageBase { private prefixKey: string; private memoryCache: Map<string, DataModel<ValueType>> = new Map(); constructor(prefixKey = "HybridWebCache") { this.prefixKey = `${prefixKey.trim()}::`; this.loadMemoryCache(); // Load existing data into memory cache on initialization } private formattedKey(key: string): string { return `${this.prefixKey}${key}`; } private _forEachStorage(callback: (originalKey: string, value: string | null) => void): void { for (let i = 0; i < sessionStorage.length; i++) { const key = sessionStorage.key(i); if (key?.startsWith(this.prefixKey)) { callback(key.replace(this.prefixKey, ""), sessionStorage.getItem(key)); } } } private loadMemoryCache(): void { this.memoryCache.clear(); // Clear existing cache before loading this._forEachStorage((key, value) => { const data: DataModel<ValueType> = JSON.parse(value ?? "{}"); this.memoryCache.set(key, data); }); } /** @internal */ async init(): Promise<void> { return Promise.resolve(); } set<T extends ValueType>(key: string, data: DataModel<T>): Promise<void> { return Promise.resolve(this.setSync(key, data)); } setSync<T extends ValueType>(key: string, data: DataModel<T>): void { sessionStorage.setItem(this.formattedKey(key), JSON.stringify(data)); this.memoryCache.set(key, data); } get<T extends ValueType>(key: string): Promise<DataModel<T> | undefined> { return Promise.resolve(this.getSync(key)); } getSync<T extends ValueType>(key: string): DataModel<T> | undefined { return this.memoryCache.get(key) as DataModel<T>; } getAll<T extends ValueType>(): Promise<Map<string, DataModel<T>> | null> { return Promise.resolve(this.getAllSync<T>()); } getAllSync<T extends ValueType>(): Map<string, DataModel<T>> | null { return this.memoryCache.size > 0 ? (this.memoryCache as Map<string, DataModel<T>>) : null; } has(key: string): Promise<boolean> { return Promise.resolve(this.hasSync(key)); } hasSync(key: string): boolean { return this.memoryCache.has(key); } unset(key?: string): Promise<boolean> { return Promise.resolve(this.unsetSync(key)); } unsetSync(key?: string): boolean { if (this.memoryCache.size === 0) return false; let result = false; if (!key) { const keysToRemove: string[] = []; this._forEachStorage((originalKey, _value) => keysToRemove.push(originalKey)); keysToRemove.forEach((k) => sessionStorage.removeItem(k)); this.memoryCache.clear(); result = true; } else { if (this.hasSync(key)) { const fKey = this.formattedKey(key); sessionStorage.removeItem(fKey); result = this.memoryCache.delete(key); } } return result; } get length(): number { return this.memoryCache.size; } get bytes(): number { if (this.memoryCache.size === 0) return 0; let totalBytes = 0; this._forEachStorage((key, value) => { totalBytes += new TextEncoder().encode(key).length; if (value) { totalBytes += new TextEncoder().encode(value).length; } }); return totalBytes; } get type(): StorageEngine { return StorageEngine.SessionStorage; } } |