@domql/state 2.3.82 → 2.3.117

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/ignore.js +6 -0
  2. package/index.js +257 -21
  3. package/package.json +2 -2
package/ignore.js ADDED
@@ -0,0 +1,6 @@
1
+ 'use strict'
2
+
3
+ export const IGNORE_STATE_PARAMS = [
4
+ 'update', 'parse', 'clean', 'create', 'destroy', 'remove', 'apply', 'rootUpdate',
5
+ 'parent', '__element', '__depends', '__ref', '__children', '__root'
6
+ ]
package/index.js CHANGED
@@ -1,44 +1,280 @@
1
1
  'use strict'
2
2
 
3
- import { on } from '@domql/event'
4
- import { deepClone, diff, exec, isFunction, overwriteDeep } from '@domql/utils'
3
+ import { IGNORE_STATE_PARAMS } from './ignore'
5
4
 
6
- export const parseState = function () {
5
+ import { triggerEventOn } from '@domql/event'
6
+ import {
7
+ is,
8
+ isObject,
9
+ exec,
10
+ isFunction,
11
+ isUndefined,
12
+ arrayContainsOtherArray,
13
+ isObjectLike,
14
+ isArray,
15
+ removeFromArray,
16
+ removeFromObject,
17
+ deepClone,
18
+ overwriteShallow,
19
+ overwriteDeep
20
+ } from '@domql/utils'
21
+
22
+ export const parse = function () {
23
+ const state = this
24
+ if (isObject(state)) {
25
+ const obj = {}
26
+ for (const param in state) {
27
+ if (!IGNORE_STATE_PARAMS.includes(param)) {
28
+ obj[param] = state[param]
29
+ }
30
+ }
31
+ return obj
32
+ } else if (isArray(state)) {
33
+ return state.filter(item => !IGNORE_STATE_PARAMS.includes(item))
34
+ }
35
+ }
36
+
37
+ export const clean = function (options = {}) {
7
38
  const state = this
8
- const parseState = {}
9
39
  for (const param in state) {
10
- if (param !== '__element' && param !== 'update' && param !== 'parse') {
11
- parseState[param] = state[param]
40
+ if (!IGNORE_STATE_PARAMS.includes(param)) {
41
+ delete state[param]
12
42
  }
13
43
  }
14
- return parseState
44
+ state.update(state, { skipOverwrite: true, options })
45
+ return state
46
+ }
47
+
48
+ export const destroy = function () {
49
+ const state = this
50
+ const element = state.__element
51
+ delete element.state
52
+ element.state = state.parent
53
+
54
+ if (state.parent) {
55
+ delete state.parent.__children[element.key]
56
+ }
57
+
58
+ if (state.__children) {
59
+ for (const key in state.__children) {
60
+ const child = state.__children[key]
61
+ if (child.state) {
62
+ child.parent = state.parent
63
+ }
64
+ }
65
+ }
66
+
67
+ element.state.update()
68
+ return element.state
69
+ }
70
+
71
+ export const rootUpdate = function (obj, options = {}) {
72
+ const state = this
73
+ if (!state) return
74
+ const rootState = (state.__element.__ref.__root).state
75
+ return rootState.update(obj, options)
15
76
  }
16
77
 
17
78
  export const updateState = function (obj, options = {}) {
18
79
  const state = this
19
80
  const element = state.__element
81
+ const __elementRef = element.__ref
82
+ const parentState = element.parent.state
83
+ state.parent = parentState
20
84
 
21
- const changes = diff(obj, state)
85
+ for (const param in state) {
86
+ if (isUndefined(state[param])) {
87
+ delete state[param]
88
+ }
89
+ }
90
+
91
+ if (!state.__element) {
92
+ create(element, element.parent)
93
+ }
94
+
95
+ const initStateUpdateReturns = triggerEventOn('initStateUpdated', element, obj)
96
+ if (initStateUpdateReturns === false) return element
97
+
98
+ if (!options.skipOverwrite) {
99
+ if (options.shallow) {
100
+ overwriteShallow(state, obj, IGNORE_STATE_PARAMS)
101
+ } else {
102
+ overwriteDeep(state, obj, IGNORE_STATE_PARAMS)
103
+ }
104
+ }
105
+
106
+ const stateKey = __elementRef.__state
107
+ const shouldPropagateState = stateKey && parentState && parentState[stateKey] && !options.stopStatePropagation
108
+ if (shouldPropagateState) {
109
+ const isStringState = (__elementRef.__stateType === 'string')
110
+ const value = isStringState ? state.value : state.parse()
111
+ parentState[stateKey] = value
112
+ parentState.update(value, { skipOverwrite: true, ...options })
113
+ return state
114
+ }
22
115
 
23
- on.updateStateInit(changes, element)
116
+ if (!options.preventUpdate) {
117
+ element.update({}, options)
118
+ } else if (options.preventUpdate === 'recursive') {
119
+ element.update({}, { ...options, preventUpdate: true })
120
+ }
24
121
 
25
- overwriteDeep(changes, state)
26
- if (!options.preventUpdate) element.update()
122
+ if (state.__depends) {
123
+ for (const el in state.__depends) {
124
+ const findElement = state.__depends[el]
125
+ findElement.clean().update(state.parse(), options)
126
+ }
127
+ }
128
+
129
+ if (!options.preventUpdateListener) {
130
+ triggerEventOn('stateUpdated', element, obj)
131
+ }
27
132
 
28
- on.updateState(changes, state, element)
133
+ return state
29
134
  }
30
135
 
31
- export function createState (element, parent) {
32
- let { state } = element
33
- if (!state) return (parent && parent.state) || {}
34
- if (isFunction(state)) state = exec(state, element)
136
+ export const remove = function (key, options) {
137
+ const state = this
138
+ if (isArray(state)) removeFromArray(state, key)
139
+ if (isObject(state)) removeFromObject(state, key)
140
+ return state.update(state, { skipOverwrite: true, options })
141
+ }
35
142
 
36
- state = deepClone(state, ['update', 'parse', '__element'])
37
- state.__element = element
38
- state.parse = parseState
39
- state.update = updateState
143
+ export const apply = function (func, options) {
144
+ const state = this
145
+ if (isFunction(func)) {
146
+ func(state)
147
+ return state.update(state, { skipOverwrite: true, options })
148
+ }
149
+ }
150
+
151
+ const getParentStateInKey = (stateKey, parentState) => {
152
+ const arr = stateKey.split('../')
153
+ const arrLength = arr.length - 1
154
+ for (let i = 0; i < arrLength; i++) {
155
+ if (!parentState.parent) return null
156
+ parentState = parentState.parent
157
+ }
158
+ return parentState
159
+ }
160
+
161
+ const getChildStateInKey = (stateKey, parentState) => {
162
+ const arr = stateKey.split('/')
163
+ const arrLength = arr.length - 1
164
+ for (let i = 0; i < arrLength; i++) {
165
+ const childKey = arr[i]
166
+ const grandChildKey = arr[i + 1]
167
+ const childInParent = parentState[childKey]
168
+ if (childInParent && childInParent[grandChildKey]) {
169
+ stateKey = grandChildKey
170
+ parentState = childInParent
171
+ } else return
172
+ }
173
+ return parentState[stateKey]
174
+ }
175
+
176
+ const createInheritedState = function (element, parent) {
177
+ const __elementRef = element.__ref
178
+ let stateKey = __elementRef.__state
179
+ if (!stateKey) return element.state
180
+
181
+ let parentState = parent.state
182
+ if (stateKey.includes('../')) {
183
+ parentState = getParentStateInKey(stateKey, parent.state)
184
+ stateKey = stateKey.replaceAll('../', '')
185
+ }
186
+ if (!parentState) return {}
187
+
188
+ const keyInParentState = getChildStateInKey(stateKey, parentState)
189
+ if (!keyInParentState) return {}
190
+
191
+ if (is(keyInParentState)('object', 'array')) {
192
+ return deepClone(keyInParentState, IGNORE_STATE_PARAMS)
193
+ } else if (is(keyInParentState)('string', 'number')) {
194
+ __elementRef.__stateType = 'string'
195
+ return { value: keyInParentState }
196
+ }
197
+
198
+ console.warn(stateKey, 'is not present. Replacing with', {})
199
+ return {}
200
+ }
201
+
202
+ export const createState = function (element, parent, opts) {
203
+ const skip = (opts && opts.skip) ? opts.skip : false
204
+ let { state, __ref: __elementRef } = element
205
+
206
+ if (isFunction(state)) element.state = exec(state, element)
207
+
208
+ if (is(state)('string', 'number')) {
209
+ __elementRef.__state = state
210
+ element.state = {}
211
+ }
212
+ if (state === true) {
213
+ __elementRef.__state = element.key
214
+ element.state = {}
215
+ }
216
+
217
+ // trigger `on.stateInit`
218
+ triggerEventOn('stateInit', element)
219
+
220
+ state = element.state = createInheritedState(element, parent)
221
+
222
+ if (!state) {
223
+ if (parent && parent.state) return parent.state
224
+ return {}
225
+ } else {
226
+ __elementRef.__hasRootState = true
227
+ }
228
+
229
+ // reference other state
230
+ // TODO: check why __ref is assigned with element
231
+ // /docs/intro
232
+ const { __ref } = state
233
+ if (__ref) {
234
+ state = deepClone(__ref, IGNORE_STATE_PARAMS)
235
+ if (isObject(__ref.__depends)) {
236
+ __ref.__depends[element.key] = state
237
+ } else __ref.__depends = { [element.key]: state }
238
+ } else {
239
+ state = deepClone(state, IGNORE_STATE_PARAMS)
240
+ }
241
+
242
+ element.state = state
243
+
244
+ // NOTE: Only true when 'onlyResolveExtends' option is set to true
245
+ if (skip) return state
40
246
 
41
- on.createState(state, element)
247
+ applyMethods(element, state)
248
+
249
+ // trigger `on.stateCreated`
250
+ triggerEventOn('stateCreated', element)
42
251
 
43
252
  return state
44
253
  }
254
+
255
+ export const isState = function (state) {
256
+ if (!isObjectLike(state)) return false
257
+ const keys = Object.keys(state)
258
+ return arrayContainsOtherArray(keys, ['update', 'parse', 'clean', 'create', 'parent', 'rootUpdate'])
259
+ }
260
+
261
+ const applyMethods = (element, state) => {
262
+ const __elementRef = element.__ref
263
+
264
+ state.clean = clean
265
+ state.parse = parse
266
+ state.destroy = destroy
267
+ state.update = updateState
268
+ state.rootUpdate = rootUpdate
269
+ state.create = createState
270
+ state.remove = remove
271
+ state.apply = apply
272
+ state.parent = element.parent.state
273
+ state.__element = element
274
+ state.__children = {}
275
+ state.__root = __elementRef.__root ? __elementRef.__root.state : state
276
+
277
+ if (state.parent) state.parent.__children[element.key] = state
278
+ }
279
+
280
+ export default createState
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@domql/state",
3
- "version": "2.3.82",
3
+ "version": "2.3.117",
4
4
  "main": "index.js",
5
5
  "license": "MIT",
6
6
  "dependencies": {
7
7
  "@domql/event": "latest",
8
8
  "@domql/utils": "latest"
9
9
  },
10
- "gitHead": "6d358ffa05e6acdceacc1d053fdb00449610b43a",
10
+ "gitHead": "a6da9bf1846e4a1e26017978cf52112b9d61d484",
11
11
  "source": "index.js"
12
12
  }