Commiq Docs
Plugins

Persistence

Persist API

@naikidev/commiq-persist provides state persistence and rehydration for commiq stores. It subscribes to state changes, debounce-writes to storage, and hydrates on initialization via replaceState.

Installation

pnpm add @naikidev/commiq-persist
npm install @naikidev/commiq-persist
yarn add @naikidev/commiq-persist
bun add @naikidev/commiq-persist

Basic Usage

import { createStore } from "@naikidev/commiq";
import { persistStore } from "@naikidev/commiq-persist";

const store = createStore({ count: 0 });

const { destroy, hydrated } = persistStore(store, {
  key: "app-state",
});

await hydrated; // state is now loaded from localStorage

Async Storage

Use any storage backend by providing a custom StorageAdapter:

const { destroy, hydrated } = persistStore(store, {
  key: "app-state",
  storage: {
    getItem: async (key) => {
      const res = await fetch(`/api/state/${key}`);
      return res.ok ? await res.text() : null;
    },
    setItem: async (key, value) => {
      await fetch(`/api/state/${key}`, { method: "PUT", body: value });
    },
  },
});

await hydrated;

persistStore(store, options)

Attaches persistence to a store. Returns a handle to destroy the subscription and a promise that resolves when hydration completes.

Options

OptionTypeDefaultDescription
keystringrequiredStorage key
storageStorageAdapterlocalStorageStorage backend
debouncenumber300Debounce delay in ms
serialize(state: S) => stringJSON.stringifyCustom serializer
deserialize(raw: string) => SJSON.parseCustom deserializer

Return Value

PropertyTypeDescription
destroy() => voidCloses the stream listener and cancels pending writes
hydratedPromise<void>Resolves when initial hydration is complete

StorageAdapter

type StorageAdapter = {
  getItem(key: string): string | null | Promise<string | null>;
  setItem(key: string, value: string): void | Promise<void>;
};

Both sync and async implementations are supported. localStorage and sessionStorage conform to this interface natively.

Rehydration Loop Prevention

When persistStore hydrates state, it internally skips writing back to storage. This prevents the hydration → stateChanged → write cycle. No configuration needed.

On this page