Skip to content

Vanilla API (exported from ./vanilla)

tsx
import {
  create,
  subscribe,
  getSnapshot,
  ref,
  devtools,
  produce,
  proxy,
} from '@shined/reactive/vanilla'

create

tsx
import { create } from '@shined/reactive'

const store = create(initialState, options)

// const countStore = create({ count: 1 })

InitialState

An object that represents the initial state of the store.

It can be any pure object, or non-serializable state wrapped in ref function.
tsx
const store = create({
  name: 'Bob',
  refObj: ref({ form: new FormData() }),
})

Options (optional)

It's has no options currently, but it may be added in the future.

Returns

Returns a object with the following properties (usually called store)

tsx
const { mutate, restore, subscribe } = store;

store.mutate

A mutable State Proxy, same type with initial state, whose changes will trigger subscribers.

store.subscribe(listener, options?, selector?)

A method to subscribe to state changes.

tsx
store.subscribe((changes, _version) => {
  console.log('changes', changes)
})
Type Definitions
tsx
export type StoreSubscriber<State extends object> = (
  /**
   * Callback to be called when state changes.
   */
  listener: SubscribeCallback<State>,
  /**
   * Whether to sync the listener with the current state.
   */
  sync?: boolean,
  /**
   * Selector to select a slice of the state.
   */
  selector?: ObjSelector<State>
) => () => void

export type SubscribeCallback<State> = (changes: ChangeItem<State>, version?: number) => void

export type ChangeItem<State> = {
  props: PropertyKey[]
  propsPath: string
  previous: unknown
  current: unknown
  snapshot: State
}

export type ObjSelector<State> =
  | ((state: State) => State)
  | (<StoreSlice extends object>(state: State) => StoreSlice)

store.restore()

A method to restore the store to the initial state.

tsx
store.restore()

subscribe

A method to subscribe to state changes, the first param should be a State Proxy.

tsx
subscribe(store.mutate, (changes, version) => {})
subscribe(store.mutate.user.name, (changes, version) => {})
Type Definitions
tsx
export type ChangeItem<State> = {
  props: PropertyKey[]
  propsPath: string
  previous: unknown
  current: unknown
  snapshot: State
}

export type SubscribeCallback<State> = (changes: ChangeItem<State>, version?: number) => void

export function subscribe<State extends object>(
  proxyState: State,
  callback: SubscribeCallback<State>,
  notifyInSync?: boolean
): () => void

getSnapshot

A method to get a snapshot of the current state to consume. Param should be a State Proxy (created by proxy).

tsx
const state = getSnapshot(store.mutate)
const hobbiesState = getSnapshot(store.mutate.hobbies)
Type Definitions
tsx
export function getSnapshot<State extends object>(proxyState: State): State

ref

A function to allow non-serializable state in initial state.

tsx
const store = create({
  name: 'Bob',
  tableRef: ref({ table: null }),
})

WARNING

You should change the ref object property, NOT the ref object itself.

tsx
const changeTableRef = () => {
  // ❌ It's not correct to modify the ref object itself
  // store.mutate.tableRef = { table: document.querySelector('#table') }

  // ✅ It's correct to modify the ref object property
  store.mutate.tableRef.table = document.querySelector('#table')
}

devtools

A function to integrate with Redux DevTools. Just wrapper store in it, enable is true by default.

tsx
const store = create({ count: 1 })

devtools(store, { name: 'CountStore', enable: true })
Type Definitions
tsx
/** redux devtool options, if set, will enable redux devtool */
export type DevtoolsOptions = DeepExpandType<
  {
    /* name of the store, will be displayed as title in devtool switch panel */
    name: string
    /** @default true */
    enable?: boolean
  } & ExtConfig
>

produce

An alternative to immer's produce, but it require pure object as initial state, NOT support circular reference.

tsx
const nextState = produce(store.mutate, (draft) => {
  draft.count += 1
  draft.user.name = 'Alice'
})
Type Definitions
tsx
export function produce<State extends object>(
  obj: State,
  draftHandler: (draft: State) => void
): State

proxy

An internal function to create a State Proxy (like store.mutate) recursively, itself and its properties are all Proxied State.

WARNING

It's internal and NOT recommended to use directly, use create instead.

tsx
const proxyState = proxy({ count: 1, user: { name: 'Bob' } })
proxyState.count += 1
proxyState.user.name = 'Alice'
Type Definitions
tsx
export function proxy<State extends object>(
  initState: State,
  parentProps: PropertyKey[] = []
): State

Released under the MIT License.