Skip to content

StorageAdapter

The StorageAdapter interface defines the contract for storage backends. Implement this interface to create custom adapters for cookies, encrypted storage, or any other synchronous backend.

Interface

interface StorageAdapter {
get(key: string): string | null;
set(key: string, value: string): void;
remove(key: string): void;
getAll(): Record<string, string>;
setAll(values: Record<string, string>): void;
clear(): void;
subscribe(callback: (key: string | null) => void): () => void;
}

Methods

get(key)

Retrieves a value by key.

ParameterTypeDescription
keystringThe key to look up
Returnsstring | nullThe value, or null if not found
const value = adapter.get("username");
if (value !== null) {
console.log("Found:", value);
}

set(key, value)

Stores a value.

ParameterTypeDescription
keystringThe key to store under
valuestringThe value to store
adapter.set("username", "Alice");

remove(key)

Removes a value by key.

ParameterTypeDescription
keystringThe key to remove
adapter.remove("username");

getAll()

Retrieves all key-value pairs.

| Returns | Record<string, string> | All stored key-value pairs |

const all = adapter.getAll();
// { "key1": "value1", "key2": "value2" }

setAll(values)

Replaces all stored values. Typically clears existing data first.

ParameterTypeDescription
valuesRecord<string, string>The new key-value pairs
adapter.setAll({ newKey: "newValue" });
// Previous data is cleared

clear()

Removes all stored values.

adapter.clear();
// adapter.getAll() now returns {}

subscribe(callback)

Subscribes to storage changes. Returns an unsubscribe function.

ParameterTypeDescription
callback(key: string | null) => voidCalled when storage changes
Returns() => voidUnsubscribe function

The callback receives:

  • key: string — The specific key that changed
  • key: null — Multiple keys changed (bulk operation)
const unsubscribe = adapter.subscribe((key) => {
if (key === null) {
console.log("Bulk change detected");
} else {
console.log("Key changed:", key);
}
});
// Later: stop listening
unsubscribe();

Built-in Adapters

localStorageAdapter

import { localStorageAdapter } from "@vp-tw/nanostores-storage";

Pre-configured adapter for window.localStorage.

sessionStorageAdapter

import { sessionStorageAdapter } from "@vp-tw/nanostores-storage";

Pre-configured adapter for window.sessionStorage.

createWebStorageAdapter(storage)

import { createWebStorageAdapter } from "@vp-tw/nanostores-storage";
const adapter = createWebStorageAdapter(localStorage);
const adapter = createWebStorageAdapter(sessionStorage);

Factory function to create adapters for any Storage-compatible object.

Creating Custom Adapters

See the Custom Adapters recipe for complete examples.

Minimal Example

import type { StorageAdapter } from "@vp-tw/nanostores-storage";
const data = new Map<string, string>();
const listeners = new Set<(key: string | null) => void>();
const memoryAdapter: StorageAdapter = {
get: (key) => data.get(key) ?? null,
set: (key, value) => {
data.set(key, value);
listeners.forEach((cb) => cb(key));
},
remove: (key) => {
data.delete(key);
listeners.forEach((cb) => cb(key));
},
getAll: () => Object.fromEntries(data),
setAll: (values) => {
data.clear();
Object.entries(values).forEach(([k, v]) => data.set(k, v));
listeners.forEach((cb) => cb(null));
},
clear: () => {
data.clear();
listeners.forEach((cb) => cb(null));
},
subscribe: (callback) => {
listeners.add(callback);
return () => listeners.delete(callback);
},
};

Type Export

import type { StorageAdapter } from "@vp-tw/nanostores-storage";

See Also