Sign-in to use app …
149 |${this.user.email}
157 | = (payload?: P) => void
10 |
11 | interface EffectFns {
12 | [key: string]: EffectFn
13 | }
14 |
15 | export interface ModelStore = P['model']
23 |
24 | type ExtractModelsFromPlugins = {
25 | [K in keyof P]: ExtractPluginModel
26 | }
27 |
28 | type KeysOfPluginsWithModels = {
29 | [K in keyof P]: undefined extends ExtractPluginModel ? never : K
30 | }[keyof P]
31 |
32 | type PluginsModels = P extends Plugins ? ExtractModelsFromPlugins
20 | }
21 |
22 | // TODO: constraint to limit reducers + effects with the same name, to the same payload
23 | export interface Model = any, E extends EffectFns = any> {
24 | state: S
25 | reducers: R
26 | effects?: (store: ModelStore) => E
27 | [key: string]: any
28 | }
29 |
30 | type ActionFromModelReducerFn> =
31 | R extends (state: S) => S ? () => void :
32 | R extends (state: S, payload: infer P) => S ? (payload: P) => void : never
33 |
34 | type ActionsFromModelReducerFns> = {
35 | [K in keyof R]: ActionFromModelReducerFn
36 | }
37 |
38 | type ActionFromModelEffectFn, E extends EffectFns> = ActionsFromModelReducerFns & ActionsFromModelEffectFns, E extends EffectFns>(model: Model): Model
--------------------------------------------------------------------------------
/typings/modelStore.d.ts:
--------------------------------------------------------------------------------
1 | import { Model } from './model'
2 | import { Models, ModelsDispatch, ModelsState } from './models'
3 | import { Store, Dispatch } from './store'
4 |
5 | export interface Plugin : never
13 | }
14 |
--------------------------------------------------------------------------------
/typings/persist.d.ts:
--------------------------------------------------------------------------------
1 | import { Action, Store } from './store'
2 |
3 | export interface PersistOptions {
4 | // name sets the state key to use, useful in development to avoid conflict
5 | // with other apps. Default is to use the app location hostname
6 | name: string
7 |
8 | // provide a hook where the serialization could be provided, e.g. by using
9 | // something like https://github.com/KilledByAPixel/JSONCrush. Default is
10 | // the JSON serializer
11 | serializer: {
12 | parse(text: string): any
13 | stringify(value: any): string
14 | }
15 |
16 | // provide a hook where the storage can be replaced. Default is localStorage
17 | storage: {
18 | getItem(name: string): string | null
19 | setItem(name: string, value: string): void
20 | }
21 |
22 | // filter predicate allows control over whether to persist state based on
23 | // the action. Default is to trigger persistence after all actions
24 | filter: (action: Action) => boolean
25 |
26 | // persist allows transforming the state to only persist part of it.
27 | // Default is to persist complete state
28 | persist: (state: S) => Partial
29 |
30 | // delay introduces a delay before the save is performed. If another persist
31 | // is triggered before it expires, the previous persist is cancelled and a
32 | // new one scheduled. This can save doing too many persist operations by
33 | // debouncing the triggering. Default is 0ms
34 | delay: number
35 |
36 | // TODO: version for updates, expiry etc...
37 | }
38 |
39 | export declare function persist(store: T, options?: Partial