1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 | 'use strict'
|
7 |
|
8 | const {
|
9 | create: createStore,
|
10 | devTool
|
11 | } = require('bredux')
|
12 | const reducer = require('./reducer')
|
13 | const {
|
14 | SET,
|
15 | UPDATE,
|
16 | DEL,
|
17 | PUSH,
|
18 | PUSH_ALL,
|
19 | POP,
|
20 | SHIFT,
|
21 | POP_ALL,
|
22 | REJECT,
|
23 | FLIP,
|
24 | INCREMENT,
|
25 | DECREMENT
|
26 | } = require('./operations')
|
27 |
|
28 | const { get, set } = require('json-pointer')
|
29 |
|
30 | class ApemanstoreBase {
|
31 | constructor (state, options = {}) {
|
32 | const s = this
|
33 | let {
|
34 | scopeName = '/',
|
35 | store = createStore(reducer, state, [
|
36 | devTool && devTool()
|
37 | ])
|
38 | } = options
|
39 | s._store = store
|
40 | s._scopeName = scopeName
|
41 | }
|
42 |
|
43 | |
44 |
|
45 |
|
46 |
|
47 |
|
48 |
|
49 |
|
50 |
|
51 | $do (operation, field, value, isError = false) {
|
52 | const s = this
|
53 | s._store.dispatch({
|
54 | type: [ s._scopeName, operation ].join(':'),
|
55 | meta: { field: field },
|
56 | payload: value,
|
57 | error: isError
|
58 | })
|
59 | }
|
60 |
|
61 | |
62 |
|
63 |
|
64 |
|
65 |
|
66 | get (field) {
|
67 | const s = this
|
68 | return [
|
69 | field
|
70 | ].reduce((state = {}, key) => state[ key ], s.toJSON())
|
71 | }
|
72 |
|
73 | |
74 |
|
75 |
|
76 |
|
77 |
|
78 | sub (namespace) {
|
79 | const s = this
|
80 | let invalid = /[\/@]/.test(namespace)
|
81 | if (invalid) {
|
82 | throw new Error(`[apemanstore] Invalid scope name: ${namespace}`)
|
83 | }
|
84 | let scopeName = [ s._scopeName, `${namespace}` ].join('/').replace(/^\/\//, '/')
|
85 | let sub = new Apemanstore(null, {
|
86 | scopeName,
|
87 | store: s._store
|
88 | })
|
89 | sub.super = () => s
|
90 | return sub
|
91 | }
|
92 |
|
93 | |
94 |
|
95 |
|
96 |
|
97 | toJSON () {
|
98 | const s = this
|
99 | let state = s._store.getState()
|
100 | let scopeName = s._scopeName
|
101 | return Object.keys(state)
|
102 | .sort()
|
103 | .filter((key) => key.indexOf(scopeName) === 0)
|
104 | .reduce((collapsed, key) => {
|
105 | let subKeys = key.substring(scopeName.length)
|
106 | .split(/\//g)
|
107 | .filter(Boolean)
|
108 | .map((subKey) => `@${subKey}`)
|
109 | let assigning = collapsed
|
110 | for (let subKey of subKeys) {
|
111 | assigning[ subKey ] = assigning[ subKey ] || {}
|
112 | assigning = assigning[ subKey ]
|
113 | }
|
114 | Object.assign(assigning, state[ key ])
|
115 | return collapsed
|
116 | }, {})
|
117 | }
|
118 | }
|
119 |
|
120 |
|
121 | class Apemanstore extends ApemanstoreBase {
|
122 |
|
123 |
|
124 |
|
125 |
|
126 | |
127 |
|
128 |
|
129 |
|
130 |
|
131 | set (field, value) {
|
132 | const s = this
|
133 | let byObject = (arguments.length === 1) && (typeof arguments[ 0 ] === 'object')
|
134 | if (byObject) {
|
135 | Object.keys(arguments[ 0 ]).forEach((field) => {
|
136 | s.set(field, arguments[ 0 ][ field ])
|
137 | })
|
138 | } else {
|
139 | s.$do(SET, field, value)
|
140 | }
|
141 | }
|
142 |
|
143 | |
144 |
|
145 |
|
146 |
|
147 |
|
148 | update (field, value) {
|
149 | const s = this
|
150 | s.$do(UPDATE, field, value)
|
151 | }
|
152 |
|
153 | |
154 |
|
155 |
|
156 |
|
157 |
|
158 | del (field, value) {
|
159 | const s = this
|
160 | s.$do(DEL, field, value)
|
161 | }
|
162 |
|
163 | |
164 |
|
165 |
|
166 |
|
167 |
|
168 | push (field, value) {
|
169 | const s = this
|
170 | s.$do(PUSH, field, value)
|
171 | }
|
172 |
|
173 | |
174 |
|
175 |
|
176 |
|
177 |
|
178 | pushAll (field, value) {
|
179 | const s = this
|
180 | s.$do(PUSH_ALL, field, value)
|
181 | }
|
182 |
|
183 | |
184 |
|
185 |
|
186 |
|
187 |
|
188 | pop (field, value) {
|
189 | const s = this
|
190 | s.$do(POP, field, value)
|
191 | }
|
192 |
|
193 | |
194 |
|
195 |
|
196 |
|
197 |
|
198 | shift (field, value) {
|
199 | const s = this
|
200 | s.$do(SHIFT, field, value)
|
201 | }
|
202 |
|
203 | |
204 |
|
205 |
|
206 |
|
207 |
|
208 | popAll (field, value) {
|
209 | const s = this
|
210 | s.$do(POP_ALL, field, value)
|
211 | }
|
212 |
|
213 | |
214 |
|
215 |
|
216 |
|
217 |
|
218 | reject (field, value) {
|
219 | const s = this
|
220 | s.$do(REJECT, field, value)
|
221 | }
|
222 |
|
223 | |
224 |
|
225 |
|
226 |
|
227 |
|
228 | flip (field, value) {
|
229 | const s = this
|
230 | s.$do(FLIP, field, value)
|
231 | }
|
232 |
|
233 | |
234 |
|
235 |
|
236 |
|
237 |
|
238 | increment (field, value) {
|
239 | const s = this
|
240 | s.$do(INCREMENT, field, value)
|
241 | }
|
242 |
|
243 | |
244 |
|
245 |
|
246 |
|
247 |
|
248 | decrement (field, value) {
|
249 | const s = this
|
250 | s.$do(DECREMENT, field, value)
|
251 | }
|
252 | }
|
253 |
|
254 | module.exports = Apemanstore
|
255 |
|