You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

53 lines
1.6 KiB

import type { SyncStorageAdapter } from '../types';
import { BROWSER_EVENT_STORAGE, STORAGE_ADAPTER_LOCAL } from '../consts';
function getLocalStorage(): Storage | null {
if (typeof window === 'undefined') return null;
return window.localStorage;
}
/**
* `localStorage` adapter. Singleton — the underlying store is process-wide,
* so multiple `EngineStorage` instances over `localAdapter` write to the
* same backend.
*
* `onChange` subscribes to the `storage` event for cross-tab sync. The event
* does **not** fire in the originating tab; intra-tab sync is handled by the
* EntryBus inside `EngineStorage`.
*
* SSR-safe: every method is a no-op outside the browser. Reads return `null`
* so consumers fall back to defaults.
*/
export const localAdapter: SyncStorageAdapter = {
name: STORAGE_ADAPTER_LOCAL,
getItem(key) {
return getLocalStorage()?.getItem(key) ?? null;
},
setItem(key, value) {
getLocalStorage()?.setItem(key, value);
},
removeItem(key) {
getLocalStorage()?.removeItem(key);
},
onChange: (fn) => {
if (typeof window === 'undefined') return () => {};
let storage: Storage;
try {
const resolved = getLocalStorage();
if (resolved === null) return () => {};
storage = resolved;
} catch {
return () => {};
}
const listener = (event: StorageEvent): void => {
// Filter out events from sessionStorage / clearAll (key === null).
if (event.storageArea !== storage) return;
if (event.key === null) return;
fn(event.key, event.newValue);
};
window.addEventListener(BROWSER_EVENT_STORAGE, listener);
return () => window.removeEventListener(BROWSER_EVENT_STORAGE, listener);
}
};

Powered by TurnKey Linux.