Skip to content

Installation

bash
npm install @statesync/valtio @statesync/core

Purpose

@statesync/valtio applies snapshots to a Valtio proxy. Mutates the proxy in place — the reference never changes, so useSnapshot() and subscribe() keep working.

API

createValtioSnapshotApplier(proxy, options?)

OptionTypeDefaultDescription
mode'patch' | 'replace''patch'Apply strategy (see below)
pickKeysReadonlyArray<keyof State>Only update these keys (mutually exclusive with omitKeys)
omitKeysReadonlyArray<keyof State>Protect these keys from updates
toState(data, ctx) => Partial<State>identityMap snapshot data to state shape. ctx contains { proxy }
strictbooleantrueThrow if toState returns a non-object

Proxy interface

The adapter uses a type alias — no valtio import required:

ts
type ValtioProxyLike<State> = State;

Any object created via proxy() satisfies this interface. The adapter mutates the proxy in place — the reference never changes, so existing Valtio subscribers (useSnapshot, subscribe) continue to work.

Apply semantics

ModeBehavior
'patch' (default)proxy[key] = value for each filtered key — direct mutation
'replace'delete proxy[key] for stale keys, then proxy[key] = value — proxy reference stays the same

Why not replace the proxy?

Valtio's reactivity relies on the original proxy reference. Replacing it would break all useSnapshot() hooks. The adapter always mutates in place.

Example

ts
import { createRevisionSync } from '@statesync/core';
import { createValtioSnapshotApplier } from '@statesync/valtio';
import { proxy } from 'valtio';

const state = proxy({
  theme: 'light',
  locale: 'en',
  notifications: true,
  isMenuOpen: false,
});

const applier = createValtioSnapshotApplier(state, {
  mode: 'patch',
  omitKeys: ['isMenuOpen'],
});

const sync = createRevisionSync({
  topic: 'user-prefs',
  subscriber,
  provider,
  applier,
});

await sync.start();

With toState mapping

ts
interface PrefsDTO {
  ui_theme: string;
  ui_locale: string;
}

const applier = createValtioSnapshotApplier(state, {
  toState: (data: PrefsDTO, { proxy }) => ({
    theme: data.ui_theme,
    locale: data.ui_locale,
  }),
});

See also

Released under the MIT License.