map()
Creates a helper for object/record-focused state manipulation.
Signature
ts
function map<T>(options?: MapOptions): (
focus: Focus<Record<string, T> | undefined | null> | Focus<Record<string, T>>
) => FocusMap<T>;Usage
ts
import { store, map } from 'storion/react';
const cacheStore = store({
name: 'cache',
state: { users: {} as Record<string, User> },
setup({ focus }) {
const users = focus('users').as(map());
return {
setUser: (id: string, user: User) => users.set(id, user),
getUser: (id: string) => users.at(id),
removeUser: (id: string) => users.delete(id),
hasUser: (id: string) => users.has(id),
};
},
});Options
autoDispose
Automatically call dispose() on values when they are removed.
- Type:
boolean - Default:
false
ts
const connections = focus('connections').as(map({ autoDispose: true }));
// When values are removed, their dispose() method is called
connections.delete('conn-1'); // value.dispose() called
connections.clear(); // All values disposedMethods
get()
Get the current record.
ts
const allUsers = users.get();at(key)
Get value by key.
ts
const user = users.at('user-123');size()
Get number of entries.
ts
const count = users.size();isEmpty()
Check if record is empty.
ts
if (users.isEmpty()) {
console.log('No users');
}has(key)
Check if key exists.
ts
if (users.has('admin')) {
// ...
}set(key, value)
Set value at key. Accepts direct value, reducer, or Immer-style updater.
ts
// Direct value
users.set('user-1', newUser);
// Reducer (returns new value)
users.set('user-1', prev => ({ ...prev, name: 'Updated' }));
// Immer-style updater (mutates draft)
users.set('user-1', draft => { draft.age++ });
// With built-in reducers
import { increment, merge } from 'storion';
counters.set('visits', increment());
users.set('admin', merge({ role: 'superadmin' }));WARNING
If using a reducer/updater and the key doesn't exist, nothing happens.
delete(...keys)
Delete key(s).
ts
users.delete('user-1');
users.delete('user-1', 'user-2', 'user-3');Returns the number of keys deleted.
deleteWhere(predicate)
Delete keys matching predicate.
ts
const count = users.deleteWhere((user, key) => user.inactive);Returns the number of keys deleted.
clear()
Remove all entries.
ts
users.clear();replace(record)
Replace entire record.
ts
users.replace(newUsersData);keys()
Get all keys.
ts
const userIds = users.keys();values()
Get all values.
ts
const allUsers = users.values();entries()
Get all [key, value] pairs.
ts
const pairs = users.entries();
for (const [id, user] of pairs) {
console.log(id, user.name);
}pick(equality?)
Create a pick selector for fine-grained reactivity.
ts
const data = users.pick('shallow');Return Type
ts
interface FocusMap<T> {
get(): Record<string, T>;
at(key: string): T | undefined;
size(): number;
isEmpty(): boolean;
has(key: string): boolean;
set(key: string, valueOrReducerOrUpdater: T | ((prev: T) => T | void)): void;
delete(...keys: string[]): number;
deleteWhere(predicate: (value: T, key: string) => boolean): number;
clear(): void;
replace(record: Record<string, T>): void;
keys(): string[];
values(): T[];
entries(): [string, T][];
pick(equality?: PickEquality<Record<string, T> | undefined | null>): Record<string, T>;
}See Also
list()- For array collectionsfocus()- Core focus API- Dynamic Nested State - Guide for managing collections