Skip to content

Class: Store<Key, Value, CacheDisabled, This>

Defined in: store/src/Store.ts:185

A generic, reactive data storage class that provides a Map-like interface with advanced features such as search, filtering, and sorting. Supports both in-memory caching and persistent storage (LocalStorage in browsers, JSON files in NodeJS via node-localstorage NPM module).

Notes:

  • Performance: Store is optimized for small to medium datasets.
    • For datasets > 1MB, consider increasing the delay option to reduce write frequency.
    • It is NOT recommended for datasets larger than 3MB due to synchronous serialization costs.
    • For one-off operations or standalone scripts, data size is constrained only by available system memory and processing power.
  • RxJS Integration: Built on RxJS for reactive data handling, though no prior RxJS knowledge is required.
  • Storage Behavior:
    • If name is omitted, the instance operates in-memory only and data is not persisted to storage.
    • If cacheDisabled is true, data is not kept in memory; every read/write operation accesses the underlying storage directly.

See

forceUpdateCache$ for cache invalidation across instances.

Examples

Browser Usage 1: use like a map

javascript
import { Store } from '@superutils/store'

const userStore = new Store('users')
userStore.set(1, { name: 'Alice', age: 30 })
const user = userStore.get(1)
console.log(user) // prints: {name: 'Alice', age: 30}

Browser Usage 2:

javascript
import { Store } from '@superutils/store'
import fetch from '@superutils/fetch'

const { products } = await fetch.get('[DUMMYJSON-DOT-COM]/products')
const storage = new Store('products', {
  initialValue: new Map(products.map(p => [p.id, p])) // convert to Map
})

// print product with id `1`
console.log(storage.get(1))

// search for items
const searchResult = storage.search({
  query: { availabilityStatus: 'low' }
})
console.log(searchResult)

NodeJS Usage

javascript
import { Store } from '@superutils/store'
import fetch from '@superutils/fetch'
import { LocalStorage } from 'node-localstorage'

// Add localStorage alternative for NodeJS that reads and writes to JSON files.
// This is not necessary for browsers.
globalThis.localStorage = new LocalStorage('./data', 1e7)

const storage = new Store('products')
const { products } = await fetch.get('[DUMMYJSON-DOT-COM]/products')
// save all items to storage
storage.setAll(
  new Map(products.map(p => [p.id, p])), // convert to Map
)

// print product with id `1`
console.log(storage.get(1))

// search for items
const searchResult = storage.search({
  query: { availabilityStatus: 'low' }
})
console.log(searchResult)

Advanced: onChange and RxJS subject

Internally, Store uses RxJS subject which is exposed as subject$ property. You can use this to subscribe to changes and do additional operations such as logging or sanitization etc.

Alternatively, you can also set the onChange callback which is triggered whenever the subject changes and does not require maintaining a subscription or knowledge of RxJS subject.

javascript
import { Store } from '@superutils/store'

const storage = new Store('my-data')
const sub = storage.subject$.subscribe(data => {
  // Write to the database whenever data changes
  console.log('Saving to database...', data)
})
// unsubscribe from subject
setTimeout(()=> sub.unsubscribe(), 1000)

// add an entry to storage
storage.set('bob', { age: 99, id: 'bob', name: 'Bob' })

Type Parameters

Key

Key

The type of keys stored in the map.

Value

Value

The type of values stored in the map.

CacheDisabled

CacheDisabled extends boolean = false

A literal boolean type indicating whether in-memory caching is disabled.

This

This extends IStore<Key, Value, CacheDisabled> = IStore<Key, Value, CacheDisabled>

A self-referential interface type extending IStore used for accurate method signature inference and type-safe property access. This allows method implementations to reference their return types and other method signatures through the interface definition.

Implements

  • IStore<Key, Value, CacheDisabled>

Constructors

Constructor

new Store<Key, Value, CacheDisabled, This>(name?, options?): Store<Key, Value, CacheDisabled, This>

Defined in: store/src/Store.ts:249

Parameters

name?

This["name"]

options?

Store_Options<Key, Value, CacheDisabled> | null

Returns

Store<Key, Value, CacheDisabled, This>

Properties

cacheDisabled

readonly cacheDisabled: This["cacheDisabled"]

Defined in: store/src/Store.ts:211

Disable in-memory cache and only directly read/write from storage (local storage or JSON fle)

Implementation of

IStore.cacheDisabled


clear

clear: This["clear"]

Defined in: store/src/Store.ts:301

Clear all items

Implementation of

IStore.clear


delay

readonly delay: This["delay"]

Defined in: store/src/Store.ts:213

Debounce/throttle delay duration in milliseconds for writing to storage when caching is enabled.

Increasing this value can improve performance when dealing with large datasets or frequent updates by reducing the number of write operations.

Default: 300

Implementation of

IStore.delay


delayOptions?

readonly optional delayOptions?: This["delayOptions"]

Defined in: store/src/Store.ts:216

Debounce and throttle related options

Implementation of

IStore.delayOptions


delete

delete: This["delete"]

Defined in: store/src/Store.ts:306

Delete one or more items by their respective keys

Implementation of

IStore.delete


filter

filter: This["filter"]

Defined in: store/src/Store.ts:326

Filter items by predicate

Implementation of

IStore.filter


find

find: This["find"]

Defined in: store/src/Store.ts:328

Find an item by predicate or search criteria

Implementation of

IStore.find


get

get: This["get"]

Defined in: store/src/Store.ts:344

Get item by key

Implementation of

IStore.get


getAll

getAll: This["getAll"]

Defined in: store/src/Store.ts:346

Get all items

Param

forceUpdate

(optional) if true and cache is enabled, reads & updates data directly from storage

Default: false

Implementation of

IStore.getAll


has

has: This["has"]

Defined in: store/src/Store.ts:394

Check if key exists

Implementation of

IStore.has


init

init: This["init"]

Defined in: store/src/Store.ts:396

Initializes storage and sets up internal subscriptions.

Manual invocation is not typically necessary, as initialization occurs automatically in one of the following scenarios:

  • During construction, if an initialValue with at least one entry is provided.
  • On the first attempt to read or write data.

Param

initialValue

An optional map to initialize the storage with if it's currently empty.

Returns

true if initialization was successful, or false if the storage was already initialized.

Implementation of

IStore.init


initialized

readonly initialized: This["initialized"] = false

Defined in: store/src/Store.ts:218

Indicates wherether storage has been initialized (init() function invoked).

Implementation of

IStore.initialized


keys

keys: This["keys"]

Defined in: store/src/Store.ts:454

Get all keys

Implementation of

IStore.keys


map

map: This["map"]

Defined in: store/src/Store.ts:456

Map each item on the data to an Array

Implementation of

IStore.map


name

readonly name: This["name"]

Defined in: store/src/Store.ts:220

Storage name. Filename (NodeJS) or property name (browser LocalStorage). If empty string or undefined, data will not be saved to storage and will only work in-memory.

Default: null

Implementation of

IStore.name


onChange?

optional onChange?: This["onChange"]

Defined in: store/src/Store.ts:222

A callback function executed whenever a data change occurs within the storage.

This hook allows for reactive side-effects. If the callback throws an error or returns a rejected Promise, the exception is caught gracefully and redirected to the onError callback with the type Store_OnErrorType.onChange.

Note: Execution of this callback is managed by internal subscriptions and will stop firing once unsubscribe is called.

Implementation of

IStore.onChange


onError?

optional onError?: This["onError"]

Defined in: store/src/Store.ts:224

A global error handler invoked whenever an internal operation fails.

It captures failures in the following areas:

  • Data parsing and serialization (JSON or custom logic).
  • Storage access (e.g., localStorage quota or permission errors).
  • Execution of user-provided callbacks like onChange.

Note: If this handler itself throws an error, the exception is ignored gracefully to prevent application crashes during storage cycles.

Implementation of

IStore.onError


parse?

optional parse?: This["parse"]

Defined in: store/src/Store.ts:226

A callback to customize the deserialization of data read from storage.

This allows you to transform the raw string from the underlying storage back into a Map<Key, Value>. It serves as the functional inverse of stringify.

Fallback Behavior:

  • If this function is not defined, or returns undefined or a non-map value, the system falls back to internal JSON.parse logic.
  • If the function throws an error, it will use and empty map.

Error Triggers:

Implementation of

IStore.parse


read

read: This["read"]

Defined in: store/src/Store.ts:461

Reads and parses data directly from the persistent storage medium.

This operation is synchronous and does not trigger reactive updates via subject$. It is useful for debugging custom parse logic or manual data retrieval.

If instance.parse function is provided and invokation fails, an empty Map will be returned.

Param

dataStr

(optional) A raw string to parse. If omitted, the method fetches the current value associated with the instance name from the underlying storage.

Implementation of

IStore.read


search: This["search"]

Defined in: store/src/Store.ts:494

Search through the stored data (Map<Key, Value>). It supports both a global search (using a string or RegExp) across all properties of an item, and a detailed, field-specific search using a query object.

Param

options

The search criteria. See SearchOptions for available properties.

Returns

A Map or an Array containing the matched items, based on the asMap option.

Example

Search for users in a specific city

javascript
import { Store } from '@superutils/store'

const storage = new Store('users', {
  initialValue: new Map([
    [1, { name: 'John Doe', city: 'New York' }],
    [2, { name: 'Jane Doe', city: 'London' }],
    [3, { name: 'Peter Jones', city: 'New York' }],
  ])
})

const nyUsers = storage.search({ query: { city: 'New York' } })
console.log(nyUsers.size) // 2

Implementation of

IStore.search


set

set: This["set"]

Defined in: store/src/Store.ts:496

Set item by key

Param

key

Param

value

Example

javascript
import { Store } from '@superutils/store'

const store = new Store<string, number>()
store.set('count', 1)
store.set('count', (prevCount = 0) => prevCount + 1)

Implementation of

IStore.set


setAll

setAll: This["setAll"]

Defined in: store/src/Store.ts:506

Set multiple entries at once and/or replace the storage entries

Param

data

(optional) Data to add. Default: new Map()

Param

replace

(optional) Whether to merge with or replace current data.

  • true: replace all entries with data
  • false: merge with current data (existing entries with matching keys will be overwritten)

Default: false

Implementation of

IStore.setAll


sort

sort: This["sort"]

Defined in: store/src/Store.ts:518

Sort items in the storage.

Param

nameOrComparator

Criteria to sort by. Accepts one of the following:

  • function: A comparator function to sort the data.
  • string: A property name of the value object to sort by.
  • true: Sorts the map by its keys.

Param

options

(optional) Sorting options.

Param

options.save

(optional) Whether to save the sorted data back to storage (localStorage/file).

Returns

The sorted Map.

Implementation of

IStore.sort


spaces?

optional spaces?: This["spaces"]

Defined in: store/src/Store.ts:232

Number of spaces to use when stringifying. Default: undefined

Implementation of

IStore.spaces


storage?

readonly optional storage?: This["storage"]

Defined in: store/src/Store.ts:234

LocalStorage or equivalent storage instance to be used as the underlying storage and to read & write from.

Notes:

  • Ignored when name is falsy (in-memory only mode)
  • For NodeJS or equivalent, an instance of LocalStorage from "node-localstoarge" NPM module can be used.
  • A custom storage that implements StorageCompact interface can also be used both in browser and NodeJS.

Fallback behavior:

  • undefined: will attempt to use globalThis.localStorage, if available
  • null, will defer storage check until initialization on first read/write or when init() invoked manually.
    • If storage is undefined or null will attempt to assign globalTihs.localStorage again
    • If storage is still falsy, will throw an error.

Default:

  • browser: localStorage
  • node: undefined (in-memory mode)

Implementation of

IStore.storage


stringify?

optional stringify?: This["stringify"]

Defined in: store/src/Store.ts:236

A callback function to customize the serialization of data before it is written to storage.

This allows you to transform the data Map<Key, Value> into a string format suitable for the underlying storage (e.g., JSON). It serves as the functional inverse of parse.

Use this to sanitize data, remove circular references, or optimize the storage size by only persisting necessary fields.

Fallback Behavior:

  • If this function is not defined, or returns undefined or a non-string value, the system falls back to internal JSON.stringify logic.
  • If the function throws an error, it will use and empty string.

Error Triggers:

Param

data

a map of all values stored in this storage

Returns

string or undefined

Example

Sanitize data before saving

javascript
import { Store } from '@superutils/store'

const stringify = data => {
  // Convert Map to an array of entries, removing sensitive fields
  const entries = Array.from(data).map(([id, user]) => {
    const { password, ...publicData } = user
    return [id, publicData]
  })
  return JSON.stringify(entries)
}
const storage = new Store('users', { stringify })

Implementation of

IStore.stringify


subject$

readonly subject$: This["subject$"]

Defined in: store/src/Store.ts:238

The underlying RxJS subject that serves as the primary reactive interface for observing data modifications.

Its implementation type is determined by the caching strategy:

  • BehaviorSubject: Used when caching is enabled. It maintains the current state and emits it immediately to new subscribers.
  • Subject: Used when caching is disabled. It acts as a pure event pipe, emitting updates only at the moment they occur without retaining an in-memory copy.

Implementation of

IStore.subject$


toArray

toArray: This["toArray"]

Defined in: store/src/Store.ts:529

Convert list of items (Map) to 2D Array

Implementation of

IStore.toArray


toJSON

toJSON: This["toJSON"]

Defined in: store/src/Store.ts:531

Convert list of items (Map) to JSON string of 2D Array

Implementation of

IStore.toJSON


toObject

toObject: This["toObject"]

Defined in: store/src/Store.ts:556

Convert list of items into an object

Implementation of

IStore.toObject


toString

toString: This["toString"]

Defined in: store/src/Store.ts:566

Convert list of items (Map) to JSON string of 2D Array

Implementation of

IStore.toString


type

type: This["type"] = 'map'

Defined in: store/src/Store.ts:245

Indicates type of data parsed as

Default: 'map'

Implementation of

IStore.type


unsubscribe

unsubscribe: This["unsubscribe"]

Defined in: store/src/Store.ts:584

Unsubscribe from all internal subscriptions.

This will result in:

  • Automatic writing to storage being disabled (manual writes via instance.write() will still work).
  • The onChange callback no longer being triggered.
  • The instance stopping listening to force update cache triggers.

Implementation of

IStore.unsubscribe


validate?

optional validate?: This["validate"]

Defined in: store/src/Store.ts:247

A configuration object containing optional validation hooks for specific store operations.

This structure allows for granular control over write operations, enabling you to define custom logic to intercept and prevent invalid state updates.

Behavior:

  • Invoked immediately before the store's internal state is updated.
  • If validation fails (throw error), the operation is aborted and the error is propagated to the caller.
  • The write validator is invoked during every persistence cycle, serving as a final check after operation-specific hooks (e.g., set or delete).
  • For reference-type values (e.g., Objects, Maps, Arrays), validators can be used to mutate the data (e.g., for normalization) before it is committed.
  • thisArg: all validators are bound to the store instance.

Example

javascript
import { createObjectStore } from '@superutils/store'

const settingsStore = createObjectStore({
  name: 'app-settings',
  initialValue: {
    theme: 'light',
    version: '1.0.0',
  },
  validate: {
    set([key, value]) {
      console.log(this.size) // "this" refers to the store instance
      if (key !== 'theme' || ['light', 'dark', 'system'].includes(value)) return

      // throw error to abort operation
      throw new Error(`Invalid theme: ${value}`)
    },
    delete: ([keys]) => {
      if (!keys.includes('version')) return

      throw new Error('The "version" key is protected and cannot be deleted')
    },
  },
})

settingsStore.set('theme', 'system')
console.log(settingsStore.get('theme')) // 'system'
try {
  settingsStore.set('theme', 'invalid') // throws error
} catch (err) {
  console.error(err.message)
}

Implementation of

IStore.validate


values

values: This["values"]

Defined in: store/src/Store.ts:593

Get all values as an array

Implementation of

IStore.values


write

write: This["write"]

Defined in: store/src/Store.ts:595

Write data to the underlying storage (localStorage or file).

Param

data

(optional) Data to write.

  • If provided, it overwrites the storage.
  • If not provided, the current in-memory data is used (if cache is enabled).

Returns

true if the write was successful, false otherwise.

Implementation of

IStore.write


messages

static messages: object

Defined in: store/src/Store.ts:318

invalidJsonEntries

invalidJsonEntries: string = 'Invalid JSON format. Parsed value must be a 2D array representing key-value pairs.'

invalidStorageOptions

invalidStorageOptions: string = 'options.storage: LocalStorage instance or equivalent required. For NodeJS, use `node-localstorage` NPM module.'

validationError

validationError: string = 'Validation failed. Action: '

Accessors

size

Get Signature

get size(): number

Defined in: store/src/Store.ts:228

Get the number of items

Returns

number

Get the number of items

Implementation of

IStore.size

Methods

forceUpdateCache()

static forceUpdateCache(name): void

Defined in: store/src/Store.ts:340

Trigger forced update of cached data from storage.

Parameters

name

string | true | string[]

determines which cache-enabled storage instances to be updated.

  • name (string | string[]): update all instances with a specific name(s)
  • global (true): update all instances globally

See forceUpdateCache$ for more details.

Returns

void