-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathStonexModule.ts
More file actions
138 lines (125 loc) · 3.8 KB
/
StonexModule.ts
File metadata and controls
138 lines (125 loc) · 3.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
import { StonexModules, StoreBinder } from '.'
export declare interface PureStonexModule<State = any> {
state?: State,
[property: string]: ((this: StonexModule<State>, ...args: any[]) => any) | State | any,
}
/**
* Special class which contains all information/actions linked with specific state.
* Provide linking store information to your stonex module
* and specific methods which allows to work with `state`.
*
*
* @export
* @class StonexModule
* @template State
*
*
* @example
* class SM extends StonexModule {
* state = {}
* getData = (key) => this.state[key]
* setData = (data) => this.setState(data)
* clear = () => this.resetState()
* }
*
* yourStore.connectModule('sm', SM)
* yourStore.modules.sm.setData({ foo: 'bar' })
*/
export class StonexModule<State = any, MP = any> {
public readonly __STONEXMODULE__ = true
/**
* Current state
*
* @type {State}
* @memberof StonexModule
*/
// @ts-ignore
public readonly state: State = null
/**
* Using inside Stonex store. You shouldn't change it!
*
* @type {string}
* @memberof StonexModule
*/
public readonly moduleName: string = '@STONEX_MODULE'
/**
* Reference to another modules linked to store.
* Bridge to use another modules inside module.
*
* @type {StonexModules<MP>}
* @memberof StonexModule
*/
public readonly modules: StonexModules<MP>
/* tslint:disable:variable-name */
public __initialState: State
/* tslint:enable:variable-name */
/**
* This property is usings inside Stonex as bridge between module and store
*
* *Fake property* - this property more needed for declarations and hints for TS
*
* @type {StonexModules<MP>}
* @memberof StonexModule
*/
private storeBinder: StoreBinder<State, MP>
/**
* Creates an instance of StonexModule.
* Provide linking store information to your stonex module
* And provides specific methods which allows to work with state.
*
* @param {StoreBinder<State, MP>} storeBinder - creates via 'createStoreBinder' function
*
* @memberof StonexModule
*/
constructor (storeBinder: StoreBinder<State, MP>) {
if (!storeBinder) {
throw new Error(
'Stonex Module created but not registered in Stonex Store. \r\n' +
'Please attach all your modules to store')
}
if (!(
storeBinder.getState &&
storeBinder.moduleName &&
storeBinder.modules &&
storeBinder.resetState &&
storeBinder.setState
)) {
throw new Error(
'Stonex Module must be creating via valid StoreBinder. \r\n' +
'When you create a new instance of StonexModule, ' +
'it should receive a object with keys (getState, moduleName, modules, resetState, setState)')
}
Object.assign(this, storeBinder)
}
/**
* Returns current state of stonex module. It is the same as `state` property
*
* @memberof StonexModule
* @returns {State}
*/
public getState = () => this.storeBinder.getState()
/**
* Update state of stonex module
*
* @param {function | State} changes - what needs to update.
* It should be a partial state or callback function with first argument as latest state data
*
* @param {function?} callback - callback function which called when state has been updated
*
* @memberof StonexModule
* @returns {void}
*/
public setState = (
changes: ((state: State) => Partial<State>) | Partial<State>,
callback?: (state: any) => any
) => this.storeBinder.setState(changes, callback)
/**
* Reset state to initial/first value
*
* @param {function} callback - callback function which called when state will been flushed to initial/default value
*
* @memberof StonexModule
* @returns {void}
*/
public resetState = (callback?: (state: State) => any) => this.storeBinder.resetState(callback)
}