Vanilla API (exported from ./vanilla
)
import {
create,
subscribe,
getSnapshot,
ref,
devtools,
produce,
proxy,
} from '@shined/reactive/vanilla'
create
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.
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
)
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.
store.subscribe((changes, _version) => {
console.log('changes', changes)
})
Type Definitions
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.
store.restore()
subscribe
A method to subscribe to state changes, the first param should be a State Proxy.
subscribe(store.mutate, (changes, version) => {})
subscribe(store.mutate.user.name, (changes, version) => {})
Type Definitions
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
).
const state = getSnapshot(store.mutate)
const hobbiesState = getSnapshot(store.mutate.hobbies)
Type Definitions
export function getSnapshot<State extends object>(proxyState: State): State
ref
A function to allow non-serializable state in initial state.
const store = create({
name: 'Bob',
tableRef: ref({ table: null }),
})
WARNING
You should change the ref object property, NOT the ref object itself.
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.
const store = create({ count: 1 })
devtools(store, { name: 'CountStore', enable: true })
Type Definitions
/** 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.
const nextState = produce(store.mutate, (draft) => {
draft.count += 1
draft.user.name = 'Alice'
})
Type Definitions
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.
const proxyState = proxy({ count: 1, user: { name: 'Bob' } })
proxyState.count += 1
proxyState.user.name = 'Alice'
Type Definitions
export function proxy<State extends object>(
initState: State,
parentProps: PropertyKey[] = []
): State