APIs
Types
type State
State is the most fundamental type for the states in ThunkModules.
type ThunkModule<S extends State>
export type ThunkModule<S extends State> = {
name: string // module name. convention: [project-name]/[module].
defaultState: S // default state.
// The rest of the variables are doModule.
// Specifying index-signatures to include all the variables.
[action: string]: ThunkFunc<S> | string | S
}
A ThunkModule represents a self-contained domain state slice implemented within a single file. It encapsulates the module's identity, its initial data structure, and the business logic workflows (thunk functions) that act upon it.
type ThunkFunc<S extends State>
A thunk function in a thunk module. Thunk function is a function returning thunk.
type Thunk
Primitively, Thunk is defined as:
export type Thunk<S extends State> = async (
set: (actionOrID: ThunkFunc | string | null | undefined, data?: Partial<S>) => void,
get: (id?: string | null) => S,
) => void
Thunks can be async functions if needed (ex: fetch data).
set: can be used in the following setting:set(ThunkFunc()): evaluate a thunk function.set(id: string | null | undefined, data: Partial<S>): upsert state ofid(syntax sugar ofset(upsert(id, data))).
get(id?: string | null | undefined): [Guaranteed] get the state ofid(or ensureddefaultIDifidis not present). Create a state with defaultState in moduleState if state does not exist.
Full definition of Thunk is in the Advanced Usage section.
RegisterThunk / useThunk
registerThunk(module)
Register a thunk module.
useThunk(module)
const useThunk = <S extends State, T extends ThunkModule<S>>(module: T, id?: string) => [state: Readonly<S>, doModule: doModule<S, T>, string]
[Guaranteed] Get the state of the id, doModule, and the id. Use ensured defaultID if id is not present. Create a state with defaultState in moduleState if state does not exist.
return: [state, doModule, id].
Module Related
doMod(moduleName)
Get the module operators/functions by module name.
getMod(moduleName)
Get the module state by module name.
Primitive Thunk Functions
upsert(idOrData, data?)
const upsert = <S extends State>(
idOrData: Partial<S> | string | null | undefined,
data?: Partial<S>,
): Thunk<S>
[Guaranteed] Update the data. Create a state with defaultState in moduleState if state does not exist.
Can be used as:
upsert(id, data)upsert(data)(idas ensureddefaultID)
update(idOrData, data?)
const update = <S extends State>(
idOrData: Partial<S> | string | null | undefined,
data?: Partial<S>,
): Thunk<S>
Update the data. No update if id or data is invalid.
Can be used as:
update(id, data)update(data)(idasdefaultID)
remove(id?)
Remove the state. Use defaultID if id is not specified.
init(idOrState?, state?)
[Guaranteed] Initialize the state. Use ensured defaultID if id is not present. Create a state with defaultState in moduleState if state is not specified.
Most of time we don't need to init because upsert, set(id, data), get(id) and useThunk automatically initialize the state if not exist.
Misc
genID(customGenID?)
Generate id for the state. Default mechanism: crypto.randomUUID.
Advanced Usage
The following APIs are for advanced usage.
types
type Thunk
Full definition of Thunk is:
export type Thunk<S extends State> = async (
set: (actionOrID: ThunkFunc | string | null | undefined, data?: Partial<S>) => void,
get: (id?: string) => S,
getOrNull: (id?: string) => S | null | undefined,
dispatch: Dispatch<ActionOrThunk<S>>,
getModuleState: () => ModuleState<S>,
) => void
set: can be used in the following setting:set(ThunkFunc()): calling a thunk function.set(id, data: Partial<S>): upsert state ofid(syntax sugar ofset(upsert(id, data))).
get(id?): [Guaranteed] get the state ofid(or ensureddefaultIDifidis not present). Create a state with defaultState in moduleState if state does not exist.getOrNull(id?): get the state ofid. Get the state ofdefaultIDifidis not present. Returnnullifidor state is not available.dispatch:dispatch(ThunkFunc())(calling a thunk function).getModuleState: get the module state.
type UseThunk
type doModule
type doModule<S extends State, T extends ThunkModule<S>> = {
// @ts-expect-error toThunkFuncMap includes only ThunkFunc<S> | BaseActionFunc
[action in keyof toThunkFuncMap<T>]: VoidReturnType<toThunkFuncMap<T>[action]>
} & Omit<defaultDoModule, keyof toThunkFuncMap<T>>
Functions in doModule already wrap thunk functions with set (dispatch in Redux / useReducer). doModule functions can be directly used. We don't wrap doModule functions with set/dispatch.
type ModuleState
type ModuleState<S extends State> = {
name: string
nodes: NodeStateMap<S>
defaultState: S
defaultID?: string | null
}
type CustomGenID
Module state.
Primitive Thunk Functions
setDefaultID(id: string)
Set default id in module state.
Module State Related
getStateByModule(moduleState, id?)
const getStateByModule = <S extends State>(
moduleState: ModuleState<S>,
id?: string | null,
): Readonly<S>
[Guaranteed] Get the state from module state. id as ensured defaultID if id is not present. Create a state with defaultState in moduleState if state does not exist.
[NOTICE] Used only within thunks or event handles and effect hooks in components. Use useThunk in component rendering.
getStateOrNullByModule(moduleState, id?)
const getStateOrNullByModule = <S extends State>(
moduleState: ModuleState<S>,
id?: string | null,
): Readonly<S | null>
Get the state from module state. Return null if the state does not exist.
getNodeOrNullByModule(moduleState, id?)
const getNodeOrNullByModule = <S extends State>(
moduleState: ModuleState<S>,
id?: string | null,
): Readonly<NodeState<S> | null>
Get the node from module state. Return null if the node does not exist.
getDefaultID(modulestate)
Get defaultID.