@domql/utils 2.5.187 → 3.0.0
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.
- package/array.js +26 -13
- package/cache.js +4 -0
- package/component.js +10 -227
- package/cookie.js +27 -24
- package/dist/cjs/array.js +30 -16
- package/dist/cjs/cache.js +26 -0
- package/dist/cjs/component.js +16 -226
- package/dist/cjs/cookie.js +19 -24
- package/dist/cjs/element.js +137 -0
- package/dist/cjs/events.js +37 -0
- package/dist/cjs/extends.js +351 -0
- package/dist/cjs/function.js +2 -4
- package/dist/cjs/if.js +30 -0
- package/dist/cjs/index.js +25 -15
- package/dist/cjs/key.js +6 -1
- package/dist/cjs/keys.js +178 -0
- package/dist/cjs/log.js +1 -2
- package/dist/cjs/methods.js +305 -0
- package/dist/cjs/object.js +89 -237
- package/dist/cjs/props.js +220 -0
- package/dist/cjs/scope.js +28 -0
- package/dist/cjs/state.js +175 -0
- package/dist/cjs/string.js +27 -16
- package/dist/cjs/types.js +2 -4
- package/dist/cjs/update.js +42 -0
- package/dist/esm/array.js +30 -16
- package/dist/esm/cache.js +6 -0
- package/dist/esm/component.js +17 -245
- package/dist/esm/cookie.js +19 -24
- package/dist/esm/element.js +135 -0
- package/dist/esm/events.js +17 -0
- package/dist/esm/extends.js +349 -0
- package/dist/esm/function.js +2 -4
- package/dist/esm/if.js +10 -0
- package/dist/esm/index.js +10 -0
- package/dist/esm/key.js +6 -1
- package/dist/esm/keys.js +158 -0
- package/dist/esm/log.js +1 -2
- package/dist/esm/methods.js +285 -0
- package/dist/esm/object.js +90 -239
- package/dist/esm/props.js +216 -0
- package/dist/esm/scope.js +8 -0
- package/dist/esm/state.js +185 -0
- package/dist/esm/string.js +27 -16
- package/dist/esm/types.js +2 -4
- package/dist/esm/update.js +22 -0
- package/element.js +149 -0
- package/env.js +5 -2
- package/events.js +17 -0
- package/extends.js +425 -0
- package/if.js +14 -0
- package/index.js +10 -0
- package/key.js +6 -0
- package/keys.js +157 -0
- package/log.js +4 -1
- package/methods.js +315 -0
- package/node.js +21 -13
- package/object.js +121 -235
- package/package.json +3 -3
- package/props.js +249 -0
- package/scope.js +8 -0
- package/state.js +208 -0
- package/string.js +66 -30
- package/update.js +27 -0
package/props.js
ADDED
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
import { DOMQ_PROPERTIES, PROPS_METHODS } from './keys.js'
|
|
4
|
+
import { addEventFromProps } from './events.js'
|
|
5
|
+
import { deepClone, deepMerge, exec } from './object.js'
|
|
6
|
+
import { is, isArray, isFunction, isObject, isObjectLike } from './types.js'
|
|
7
|
+
|
|
8
|
+
export const createProps = (element, parent, key) => {
|
|
9
|
+
const { props, __ref: ref } = element
|
|
10
|
+
ref.__propsStack = []
|
|
11
|
+
// if (props !== undefined) ref.__initialProps = props
|
|
12
|
+
if (props) ref.__initialProps = props
|
|
13
|
+
else return {}
|
|
14
|
+
if (!isObjectLike(props)) {
|
|
15
|
+
ref.__propsStack.push(props)
|
|
16
|
+
return {}
|
|
17
|
+
}
|
|
18
|
+
return { ...props }
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function pickupPropsFromElement (element, opts = {}) {
|
|
22
|
+
const cachedKeys = opts.cachedKeys || []
|
|
23
|
+
|
|
24
|
+
for (const key in element) {
|
|
25
|
+
const value = element[key]
|
|
26
|
+
|
|
27
|
+
const hasDefine = isObject(element.define?.[key])
|
|
28
|
+
const hasGlobalDefine = isObject(element.context?.define?.[key])
|
|
29
|
+
const isElement = /^[A-Z]/.test(key) || /^\d+$/.test(key)
|
|
30
|
+
const isBuiltin = DOMQ_PROPERTIES.includes(key)
|
|
31
|
+
|
|
32
|
+
// If it's not a special case, move to props
|
|
33
|
+
if (!isElement && !isBuiltin && !hasDefine && !hasGlobalDefine) {
|
|
34
|
+
element.props[key] = value
|
|
35
|
+
delete element[key]
|
|
36
|
+
cachedKeys.push(key)
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return element
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function pickupElementFromProps (element, opts) {
|
|
44
|
+
const cachedKeys = opts.cachedKeys || []
|
|
45
|
+
|
|
46
|
+
for (const key in element.props) {
|
|
47
|
+
const value = element.props[key]
|
|
48
|
+
|
|
49
|
+
// Handle event handlers
|
|
50
|
+
const isEvent = key.startsWith('on') && key.length > 2
|
|
51
|
+
const isFn = isFunction(value)
|
|
52
|
+
|
|
53
|
+
if (isEvent && isFn) {
|
|
54
|
+
addEventFromProps(key, element)
|
|
55
|
+
delete element.props[key]
|
|
56
|
+
continue
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Skip if key was originally from element
|
|
60
|
+
if (cachedKeys.includes(key)) continue
|
|
61
|
+
|
|
62
|
+
const hasDefine = isObject(element.define?.[key])
|
|
63
|
+
const hasGlobalDefine = isObject(element.context?.define?.[key])
|
|
64
|
+
const isElement = /^[A-Z]/.test(key) || /^\d+$/.test(key)
|
|
65
|
+
const isBuiltin = DOMQ_PROPERTIES.includes(key)
|
|
66
|
+
|
|
67
|
+
// Move qualifying properties back to element root
|
|
68
|
+
if (isElement || isBuiltin || hasDefine || hasGlobalDefine) {
|
|
69
|
+
element[key] = value
|
|
70
|
+
delete element.props[key]
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return element
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Helper function to maintain compatibility with original propertizeElement
|
|
78
|
+
export function propertizeElement (element, opts = {}) {
|
|
79
|
+
const cachedKeys = []
|
|
80
|
+
pickupPropsFromElement(element, { cachedKeys })
|
|
81
|
+
pickupElementFromProps(element, { cachedKeys })
|
|
82
|
+
return element
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export const objectizeStringProperty = propValue => {
|
|
86
|
+
if (is(propValue)('string', 'number')) {
|
|
87
|
+
return { inheritedString: propValue }
|
|
88
|
+
}
|
|
89
|
+
return propValue
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export const propExists = (prop, stack) => {
|
|
93
|
+
if (!prop || !stack.length) return false
|
|
94
|
+
const key = isObject(prop) ? JSON.stringify(prop) : prop
|
|
95
|
+
return stack.some(existing => {
|
|
96
|
+
const existingKey = isObject(existing) ? JSON.stringify(existing) : existing
|
|
97
|
+
return existingKey === key
|
|
98
|
+
})
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export const inheritParentProps = (element, parent) => {
|
|
102
|
+
const { __ref: ref } = element
|
|
103
|
+
const propsStack = ref.__propsStack || []
|
|
104
|
+
const parentProps = parent.props
|
|
105
|
+
|
|
106
|
+
if (!parentProps) return propsStack
|
|
107
|
+
|
|
108
|
+
const matchParentKeyProps = parentProps[element.key]
|
|
109
|
+
const matchParentChildProps = parentProps.childProps
|
|
110
|
+
|
|
111
|
+
// Order matters: key-specific props should be added after childProps
|
|
112
|
+
const ignoreChildProps = element.props?.ignoreChildProps
|
|
113
|
+
if (matchParentChildProps && !ignoreChildProps) {
|
|
114
|
+
const childProps = objectizeStringProperty(matchParentChildProps)
|
|
115
|
+
propsStack.unshift(childProps)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if (matchParentKeyProps) {
|
|
119
|
+
const keyProps = objectizeStringProperty(matchParentKeyProps)
|
|
120
|
+
propsStack.unshift(keyProps)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return propsStack
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export async function update (props, options) {
|
|
127
|
+
const element = this.__element
|
|
128
|
+
await element.update({ props }, options)
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// TODO: check bind with promise
|
|
132
|
+
export function setPropsPrototype (element) {
|
|
133
|
+
const methods = { update: update.bind(element.props), __element: element }
|
|
134
|
+
Object.setPrototypeOf(element.props, methods)
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export const removeDuplicateProps = propsStack => {
|
|
138
|
+
const seen = new Set()
|
|
139
|
+
|
|
140
|
+
return propsStack.filter(prop => {
|
|
141
|
+
if (!prop || PROPS_METHODS.includes(prop)) return false
|
|
142
|
+
const key = isObject(prop) ? JSON.stringify(prop) : prop
|
|
143
|
+
if (seen.has(key)) return false
|
|
144
|
+
seen.add(key)
|
|
145
|
+
return true
|
|
146
|
+
})
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export const syncProps = (propsStack, element, opts) => {
|
|
150
|
+
element.props = propsStack.reduce((mergedProps, v) => {
|
|
151
|
+
if (PROPS_METHODS.includes(v)) return mergedProps
|
|
152
|
+
while (isFunction(v)) v = exec(v, element)
|
|
153
|
+
return deepMerge(mergedProps, deepClone(v, { exclude: PROPS_METHODS }))
|
|
154
|
+
}, {})
|
|
155
|
+
setPropsPrototype(element)
|
|
156
|
+
return element.props
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export const createPropsStack = (element, parent) => {
|
|
160
|
+
const { props, __ref: ref } = element
|
|
161
|
+
|
|
162
|
+
// Start with parent props
|
|
163
|
+
let propsStack = ref.__propsStack || []
|
|
164
|
+
|
|
165
|
+
// Get parent props
|
|
166
|
+
if (parent && parent.props) {
|
|
167
|
+
const parentStack = inheritParentProps(element, parent)
|
|
168
|
+
propsStack = [...parentStack]
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Add current props
|
|
172
|
+
if (isObject(props)) propsStack.push(props)
|
|
173
|
+
else if (props === 'inherit' && parent?.props) propsStack.push(parent.props)
|
|
174
|
+
else if (props) propsStack.push(props)
|
|
175
|
+
|
|
176
|
+
// Add extends props
|
|
177
|
+
if (isArray(ref.__extendsStack)) {
|
|
178
|
+
ref.__extendsStack.forEach(_extends => {
|
|
179
|
+
if (_extends.props && _extends.props !== props) {
|
|
180
|
+
propsStack.push(_extends.props)
|
|
181
|
+
}
|
|
182
|
+
})
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// Remove duplicates and update reference
|
|
186
|
+
ref.__propsStack = removeDuplicateProps(propsStack)
|
|
187
|
+
return ref.__propsStack
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
export const applyProps = (element, parent) => {
|
|
191
|
+
const { __ref: ref } = element
|
|
192
|
+
|
|
193
|
+
// Create a fresh props stack
|
|
194
|
+
const propsStack = createPropsStack(element, parent)
|
|
195
|
+
|
|
196
|
+
// Update the element
|
|
197
|
+
if (propsStack.length) {
|
|
198
|
+
syncProps(propsStack, element)
|
|
199
|
+
} else {
|
|
200
|
+
ref.__propsStack = []
|
|
201
|
+
element.props = {}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
export const initProps = function (element, parent, options) {
|
|
206
|
+
const { __ref: ref } = element
|
|
207
|
+
|
|
208
|
+
if (ref.__if) applyProps(element, parent)
|
|
209
|
+
else {
|
|
210
|
+
try {
|
|
211
|
+
applyProps(element, parent)
|
|
212
|
+
} catch {
|
|
213
|
+
element.props = {}
|
|
214
|
+
ref.__propsStack = []
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
setPropsPrototype(element)
|
|
219
|
+
|
|
220
|
+
return element
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
export const updateProps = (newProps, element, parent) => {
|
|
224
|
+
const { __ref: ref } = element
|
|
225
|
+
const propsStack = ref.__propsStack || []
|
|
226
|
+
|
|
227
|
+
// Create a new array to avoid mutating the original
|
|
228
|
+
let newStack = [...propsStack]
|
|
229
|
+
|
|
230
|
+
// Add parent props first if they exist
|
|
231
|
+
const parentProps = inheritParentProps(element, parent)
|
|
232
|
+
if (parentProps.length) {
|
|
233
|
+
newStack = [...parentProps, ...newStack]
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Add new props if they exist
|
|
237
|
+
if (newProps) {
|
|
238
|
+
newStack = [newProps, ...newStack]
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// Clean up duplicates
|
|
242
|
+
ref.__propsStack = removeDuplicateProps(newStack)
|
|
243
|
+
|
|
244
|
+
if (ref.__propsStack.length) {
|
|
245
|
+
syncProps(ref.__propsStack, element)
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
return element
|
|
249
|
+
}
|
package/scope.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
// Create scope - shared object across the elements to the own or the nearest parent
|
|
4
|
+
export const createScope = (element, parent) => {
|
|
5
|
+
const { __ref: ref } = element
|
|
6
|
+
// If the element doesn't have a scope, initialize it using the parent's scope or the root's scope.
|
|
7
|
+
if (!element.scope) element.scope = parent.scope || ref.root?.scope || {}
|
|
8
|
+
}
|
package/state.js
ADDED
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
import { addProtoToArray } from './array.js'
|
|
4
|
+
import { STATE_METHODS } from './keys.js'
|
|
5
|
+
import {
|
|
6
|
+
deepClone,
|
|
7
|
+
deepMerge,
|
|
8
|
+
execPromise,
|
|
9
|
+
overwriteDeep,
|
|
10
|
+
overwriteShallow
|
|
11
|
+
} from './object.js'
|
|
12
|
+
import {
|
|
13
|
+
is,
|
|
14
|
+
isFunction,
|
|
15
|
+
isObject,
|
|
16
|
+
isObjectLike,
|
|
17
|
+
isString,
|
|
18
|
+
isUndefined
|
|
19
|
+
} from './types.js'
|
|
20
|
+
|
|
21
|
+
export const checkForStateTypes = async element => {
|
|
22
|
+
const { state: orig, props, __ref: ref } = element
|
|
23
|
+
const state = props?.state || orig
|
|
24
|
+
if (isFunction(state)) {
|
|
25
|
+
ref.__state = state
|
|
26
|
+
return await execPromise(state, element)
|
|
27
|
+
} else if (is(state)('string', 'number')) {
|
|
28
|
+
ref.__state = state
|
|
29
|
+
return { value: state }
|
|
30
|
+
} else if (state === true) {
|
|
31
|
+
ref.__state = element.key
|
|
32
|
+
return {}
|
|
33
|
+
} else if (state) {
|
|
34
|
+
ref.__hasRootState = true
|
|
35
|
+
return state
|
|
36
|
+
} else {
|
|
37
|
+
return false
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export const getRootStateInKey = (stateKey, parentState) => {
|
|
42
|
+
if (!stateKey.includes('~/')) return
|
|
43
|
+
const arr = stateKey.split('~/')
|
|
44
|
+
if (arr.length > 1) return parentState.root
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export const getParentStateInKey = (stateKey, parentState) => {
|
|
48
|
+
if (!stateKey.includes('../')) return
|
|
49
|
+
const arr = stateKey.split('../')
|
|
50
|
+
const arrLength = arr.length - 1
|
|
51
|
+
for (let i = 0; i < arrLength; i++) {
|
|
52
|
+
if (!parentState.parent) return null
|
|
53
|
+
parentState = parentState.parent
|
|
54
|
+
}
|
|
55
|
+
return parentState
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export const getChildStateInKey = (stateKey, parentState, options = {}) => {
|
|
59
|
+
const arr = isString(stateKey) ? stateKey.split('/') : [stateKey]
|
|
60
|
+
const arrLength = arr.length - 1
|
|
61
|
+
for (let i = 0; i < arrLength; i++) {
|
|
62
|
+
const childKey = arr[i]
|
|
63
|
+
const grandChildKey = arr[i + 1]
|
|
64
|
+
|
|
65
|
+
if (childKey === '__proto__' || grandChildKey === '__proto__') return
|
|
66
|
+
|
|
67
|
+
let childInParent = parentState[childKey]
|
|
68
|
+
if (!childInParent) childInParent = parentState[childKey] = {} // check for array
|
|
69
|
+
if (!childInParent[grandChildKey]) childInParent[grandChildKey] = {} // check for array
|
|
70
|
+
|
|
71
|
+
stateKey = grandChildKey
|
|
72
|
+
parentState = childInParent
|
|
73
|
+
}
|
|
74
|
+
if (options.returnParent) return parentState
|
|
75
|
+
return parentState[stateKey]
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export const findInheritedState = (element, parent, options = {}) => {
|
|
79
|
+
const ref = element.__ref
|
|
80
|
+
let stateKey = ref.__state
|
|
81
|
+
if (!checkIfInherits(element)) return
|
|
82
|
+
|
|
83
|
+
const rootState = getRootStateInKey(stateKey, parent.state)
|
|
84
|
+
let parentState = parent.state
|
|
85
|
+
|
|
86
|
+
if (rootState) {
|
|
87
|
+
parentState = rootState
|
|
88
|
+
stateKey = stateKey.replaceAll('~/', '')
|
|
89
|
+
} else {
|
|
90
|
+
const findGrandParentState = getParentStateInKey(stateKey, parent.state)
|
|
91
|
+
if (findGrandParentState) {
|
|
92
|
+
parentState = findGrandParentState
|
|
93
|
+
stateKey = stateKey.replaceAll('../', '')
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (!parentState) return
|
|
98
|
+
return getChildStateInKey(stateKey, parentState, options)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export const createInheritedState = (element, parent) => {
|
|
102
|
+
const ref = element.__ref
|
|
103
|
+
const inheritedState = findInheritedState(element, parent)
|
|
104
|
+
if (isUndefined(inheritedState)) return element.state
|
|
105
|
+
|
|
106
|
+
if (is(inheritedState)('object', 'array')) {
|
|
107
|
+
return deepClone(inheritedState)
|
|
108
|
+
} else if (is(inheritedState)('string', 'number', 'boolean')) {
|
|
109
|
+
ref.__stateType = typeof inheritedState
|
|
110
|
+
return { value: inheritedState }
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
console.warn(ref.__state, 'is not present. Replacing with', {})
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export const checkIfInherits = element => {
|
|
117
|
+
const { __ref: ref } = element
|
|
118
|
+
const stateKey = ref?.__state
|
|
119
|
+
if (stateKey && is(stateKey)('number', 'string', 'boolean')) return true
|
|
120
|
+
return false
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export const isState = function (state) {
|
|
124
|
+
if (!isObjectLike(state)) return false
|
|
125
|
+
return Boolean(
|
|
126
|
+
state.update &&
|
|
127
|
+
state.parse &&
|
|
128
|
+
state.clean &&
|
|
129
|
+
state.create &&
|
|
130
|
+
state.parent &&
|
|
131
|
+
state.destroy &&
|
|
132
|
+
state.rootUpdate &&
|
|
133
|
+
state.parentUpdate &&
|
|
134
|
+
state.keys &&
|
|
135
|
+
state.values &&
|
|
136
|
+
state.toggle &&
|
|
137
|
+
state.replace &&
|
|
138
|
+
state.quietUpdate &&
|
|
139
|
+
state.quietReplace &&
|
|
140
|
+
state.add &&
|
|
141
|
+
state.apply &&
|
|
142
|
+
state.applyReplace &&
|
|
143
|
+
state.setByPath &&
|
|
144
|
+
state.setPathCollection &&
|
|
145
|
+
state.removeByPath &&
|
|
146
|
+
state.removePathCollection &&
|
|
147
|
+
state.getByPath &&
|
|
148
|
+
state.applyFunction &&
|
|
149
|
+
state.__element &&
|
|
150
|
+
state.__children
|
|
151
|
+
)
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export const createNestedObjectByKeyPath = (path, value) => {
|
|
155
|
+
if (!path) {
|
|
156
|
+
return value || {}
|
|
157
|
+
}
|
|
158
|
+
const keys = path.split('/')
|
|
159
|
+
const obj = {}
|
|
160
|
+
let ref = obj
|
|
161
|
+
keys.forEach((key, index) => {
|
|
162
|
+
ref[key] = index === keys.length - 1 ? value || {} : {}
|
|
163
|
+
ref = ref[key]
|
|
164
|
+
})
|
|
165
|
+
return obj
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export const applyDependentState = async (element, state) => {
|
|
169
|
+
const { __element } = state //
|
|
170
|
+
const origState = await execPromise(__element?.state, element)
|
|
171
|
+
if (!origState) return
|
|
172
|
+
const dependentState = deepClone(origState, STATE_METHODS)
|
|
173
|
+
const newDepends = { [element.key]: dependentState }
|
|
174
|
+
|
|
175
|
+
const __depends = isObject(origState.__depends)
|
|
176
|
+
? { ...origState.__depends, ...newDepends }
|
|
177
|
+
: newDepends
|
|
178
|
+
|
|
179
|
+
if (Array.isArray(origState)) {
|
|
180
|
+
addProtoToArray(origState, {
|
|
181
|
+
...Object.getPrototypeOf(origState),
|
|
182
|
+
__depends
|
|
183
|
+
})
|
|
184
|
+
} else {
|
|
185
|
+
Object.setPrototypeOf(origState, {
|
|
186
|
+
...Object.getPrototypeOf(origState),
|
|
187
|
+
__depends
|
|
188
|
+
})
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
return dependentState
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
export const overwriteState = (state, obj, options = {}) => {
|
|
195
|
+
const { overwrite } = options
|
|
196
|
+
if (!overwrite) return
|
|
197
|
+
|
|
198
|
+
const shallow = overwrite === 'shallow'
|
|
199
|
+
const merge = overwrite === 'merge'
|
|
200
|
+
|
|
201
|
+
if (merge) {
|
|
202
|
+
deepMerge(state, obj, STATE_METHODS)
|
|
203
|
+
return
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
const overwriteFunc = shallow ? overwriteShallow : overwriteDeep
|
|
207
|
+
overwriteFunc(state, obj, STATE_METHODS)
|
|
208
|
+
}
|
package/string.js
CHANGED
|
@@ -25,34 +25,50 @@ export const trimStringFromSymbols = (str, characters) => {
|
|
|
25
25
|
* @returns {string} The modified string with placeholders replaced by values from the object.
|
|
26
26
|
*/
|
|
27
27
|
const brackRegex = {
|
|
28
|
-
2:
|
|
29
|
-
3:
|
|
28
|
+
2: /{{\s*((?:\.\.\/)*)([\w\d.]+)\s*}}/g,
|
|
29
|
+
3: /{{{(\s*(?:\.\.\/)*)([\w\d.]+)\s*}}}/g
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
const getNestedValue = (obj, path) => {
|
|
33
|
+
return path.split('.').reduce((acc, part) => {
|
|
34
|
+
return acc && acc[part] !== undefined ? acc[part] : undefined
|
|
35
|
+
}, obj)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function replaceLiteralsWithObjectFields (str, state = {}, options = {}) {
|
|
39
|
+
const { bracketsLength = 2 } = options
|
|
40
|
+
const bracketPattern = bracketsLength === 3 ? '{{{' : '{{'
|
|
41
|
+
if (!str.includes(bracketPattern)) return str
|
|
42
|
+
|
|
43
|
+
const reg = brackRegex[bracketsLength]
|
|
44
|
+
const obj = state || {}
|
|
45
|
+
|
|
36
46
|
return str.replace(reg, (_, parentPath, variable) => {
|
|
37
47
|
if (parentPath) {
|
|
38
|
-
const parentLevels = parentPath.match(
|
|
48
|
+
const parentLevels = (parentPath.match(/\.\.\//g) || []).length
|
|
39
49
|
let parentState = obj
|
|
50
|
+
|
|
40
51
|
for (let i = 0; i < parentLevels; i++) {
|
|
52
|
+
if (!parentState || !parentState.parent) return ''
|
|
41
53
|
parentState = parentState.parent
|
|
42
|
-
if (!parentState) {
|
|
43
|
-
return '' // Return an empty string if the parent level doesn't exist
|
|
44
|
-
}
|
|
45
54
|
}
|
|
46
|
-
|
|
47
|
-
|
|
55
|
+
|
|
56
|
+
// If the variable is 'parent', return the value property
|
|
57
|
+
const key = variable.trim()
|
|
58
|
+
if (key === 'parent') {
|
|
59
|
+
return parentState.value !== undefined ? String(parentState.value) : ''
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const value = getNestedValue(parentState, key)
|
|
63
|
+
return value !== undefined ? String(value) : ''
|
|
48
64
|
} else {
|
|
49
|
-
const value = obj
|
|
50
|
-
return value !== undefined ?
|
|
65
|
+
const value = getNestedValue(obj, variable.trim())
|
|
66
|
+
return value !== undefined ? String(value) : ''
|
|
51
67
|
}
|
|
52
68
|
})
|
|
53
69
|
}
|
|
54
70
|
|
|
55
|
-
export const lowercaseFirstLetter =
|
|
71
|
+
export const lowercaseFirstLetter = inputString => {
|
|
56
72
|
return `${inputString.charAt(0).toLowerCase()}${inputString.slice(1)}`
|
|
57
73
|
}
|
|
58
74
|
|
|
@@ -98,7 +114,10 @@ export const findKeyPosition = (str, key) => {
|
|
|
98
114
|
// If braceCount is 0 and we find the end of the object/array
|
|
99
115
|
if (braceCount === 0) {
|
|
100
116
|
endLineNumber = i + 1
|
|
101
|
-
endColumn =
|
|
117
|
+
endColumn =
|
|
118
|
+
lines[i].lastIndexOf('}') !== -1
|
|
119
|
+
? lines[i].lastIndexOf('}') + 2
|
|
120
|
+
: lines[i].length + 1
|
|
102
121
|
break
|
|
103
122
|
}
|
|
104
123
|
}
|
|
@@ -112,7 +131,7 @@ export const findKeyPosition = (str, key) => {
|
|
|
112
131
|
}
|
|
113
132
|
}
|
|
114
133
|
|
|
115
|
-
export const replaceOctalEscapeSequences =
|
|
134
|
+
export const replaceOctalEscapeSequences = str => {
|
|
116
135
|
// Regex to match octal escape sequences
|
|
117
136
|
const octalRegex = /\\([0-7]{1,3})/g
|
|
118
137
|
|
|
@@ -126,23 +145,40 @@ export const replaceOctalEscapeSequences = (str) => {
|
|
|
126
145
|
})
|
|
127
146
|
}
|
|
128
147
|
|
|
129
|
-
export const encodeNewlines =
|
|
130
|
-
return str
|
|
148
|
+
export const encodeNewlines = str => {
|
|
149
|
+
return str
|
|
150
|
+
.split('\n')
|
|
151
|
+
.join('/////n')
|
|
152
|
+
.split('`')
|
|
153
|
+
.join('/////tilde')
|
|
154
|
+
.split('$')
|
|
155
|
+
.join('/////dlrsgn')
|
|
131
156
|
}
|
|
132
157
|
|
|
133
|
-
export const decodeNewlines =
|
|
134
|
-
return encodedStr
|
|
158
|
+
export const decodeNewlines = encodedStr => {
|
|
159
|
+
return encodedStr
|
|
160
|
+
.split('/////n')
|
|
161
|
+
.join('\n')
|
|
162
|
+
.split('/////tilde')
|
|
163
|
+
.join('`')
|
|
164
|
+
.split('/////dlrsgn')
|
|
165
|
+
.join('$')
|
|
135
166
|
}
|
|
136
167
|
|
|
137
|
-
export const customEncodeURIComponent =
|
|
138
|
-
return str
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
168
|
+
export const customEncodeURIComponent = str => {
|
|
169
|
+
return str
|
|
170
|
+
.split('')
|
|
171
|
+
.map(char => {
|
|
172
|
+
if (/[^a-zA-Z0-9\s]/.test(char)) {
|
|
173
|
+
return '%' + char.charCodeAt(0).toString(16).toUpperCase()
|
|
174
|
+
}
|
|
175
|
+
return char
|
|
176
|
+
})
|
|
177
|
+
.join('')
|
|
144
178
|
}
|
|
145
179
|
|
|
146
|
-
export const customDecodeURIComponent =
|
|
147
|
-
return encodedStr.replace(/%[0-9A-Fa-f]{2}/g, match =>
|
|
180
|
+
export const customDecodeURIComponent = encodedStr => {
|
|
181
|
+
return encodedStr.replace(/%[0-9A-Fa-f]{2}/g, match =>
|
|
182
|
+
String.fromCharCode(parseInt(match.slice(1), 16))
|
|
183
|
+
)
|
|
148
184
|
}
|
package/update.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
import { createSnapshotId } from './key.js'
|
|
4
|
+
|
|
5
|
+
const snapshot = {
|
|
6
|
+
snapshotId: createSnapshotId
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const captureSnapshot = (element, options) => {
|
|
10
|
+
const ref = element.__ref
|
|
11
|
+
|
|
12
|
+
const { currentSnapshot, calleeElement } = options
|
|
13
|
+
const isCallee = calleeElement === element
|
|
14
|
+
if (!calleeElement || isCallee) {
|
|
15
|
+
const createdStanpshot = snapshot.snapshotId()
|
|
16
|
+
ref.__currentSnapshot = createdStanpshot
|
|
17
|
+
return [createdStanpshot, element]
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const snapshotOnCallee = calleeElement.__ref.__currentSnapshot
|
|
21
|
+
|
|
22
|
+
if (currentSnapshot < snapshotOnCallee) {
|
|
23
|
+
return [snapshotOnCallee, calleeElement, true]
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return [snapshotOnCallee, calleeElement]
|
|
27
|
+
}
|