@domql/utils 2.29.64 → 2.29.66
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/component.js +18 -18
- package/dist/cjs/component.js +2 -1
- package/dist/cjs/object.js +2 -1
- package/dist/esm/component.js +2 -1
- package/dist/esm/object.js +2 -1
- package/object.js +372 -372
- package/package.json +2 -2
package/object.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
'use strict'
|
|
2
2
|
|
|
3
|
-
import { window } from
|
|
3
|
+
import { window } from './globals.js'
|
|
4
4
|
import {
|
|
5
5
|
isFunction,
|
|
6
6
|
isObjectLike,
|
|
@@ -10,12 +10,12 @@ import {
|
|
|
10
10
|
is,
|
|
11
11
|
isUndefined,
|
|
12
12
|
isDate,
|
|
13
|
-
isNull
|
|
14
|
-
} from
|
|
15
|
-
import { mergeAndCloneIfArray, mergeArray } from
|
|
16
|
-
import { stringIncludesAny } from
|
|
17
|
-
import { isDOMNode } from
|
|
18
|
-
import { isNotProduction } from
|
|
13
|
+
isNull
|
|
14
|
+
} from './types.js'
|
|
15
|
+
import { mergeAndCloneIfArray, mergeArray } from './array.js'
|
|
16
|
+
import { stringIncludesAny } from './string.js'
|
|
17
|
+
import { isDOMNode } from './node.js'
|
|
18
|
+
import { isNotProduction } from './env.js'
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
21
|
* Executes a function with the specified context and parameters.
|
|
@@ -31,7 +31,7 @@ import { isNotProduction } from "./env.js";
|
|
|
31
31
|
* @returns {any|Promise} - The result or a Promise to the result
|
|
32
32
|
*/
|
|
33
33
|
export function exec(param, element, state, context) {
|
|
34
|
-
if (!element) element = this
|
|
34
|
+
if (!element) element = this
|
|
35
35
|
if (isFunction(param)) {
|
|
36
36
|
try {
|
|
37
37
|
// Call the function with the specified context and parameters
|
|
@@ -40,77 +40,77 @@ export function exec(param, element, state, context) {
|
|
|
40
40
|
element,
|
|
41
41
|
state || element.state,
|
|
42
42
|
context || element.context
|
|
43
|
-
)
|
|
43
|
+
)
|
|
44
44
|
|
|
45
45
|
// Handle promises
|
|
46
|
-
if (result && typeof result.then ===
|
|
46
|
+
if (result && typeof result.then === 'function') {
|
|
47
47
|
// This magic allows the function to be awaited if called with await
|
|
48
48
|
// but still work reasonably when called without await
|
|
49
|
-
return result
|
|
49
|
+
return result
|
|
50
50
|
}
|
|
51
|
-
return result
|
|
51
|
+
return result
|
|
52
52
|
} catch (e) {
|
|
53
|
-
element.log(param)
|
|
54
|
-
element.warn(
|
|
53
|
+
element.log(param)
|
|
54
|
+
element.warn('Error executing function', e)
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
|
-
return param
|
|
57
|
+
return param
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
export const map = (obj, extention, element) => {
|
|
61
61
|
for (const e in extention) {
|
|
62
|
-
obj[e] = exec(extention[e], element)
|
|
62
|
+
obj[e] = exec(extention[e], element)
|
|
63
63
|
}
|
|
64
|
-
}
|
|
64
|
+
}
|
|
65
65
|
|
|
66
66
|
export const merge = (element, obj, excludeFrom = []) => {
|
|
67
67
|
for (const e in obj) {
|
|
68
|
-
const hasOwnProperty = Object.prototype.hasOwnProperty.call(obj, e)
|
|
69
|
-
if (!hasOwnProperty || excludeFrom.includes(e) || e.startsWith(
|
|
70
|
-
continue
|
|
71
|
-
const elementProp = element[e]
|
|
72
|
-
const objProp = obj[e]
|
|
68
|
+
const hasOwnProperty = Object.prototype.hasOwnProperty.call(obj, e)
|
|
69
|
+
if (!hasOwnProperty || excludeFrom.includes(e) || e.startsWith('__'))
|
|
70
|
+
continue
|
|
71
|
+
const elementProp = element[e]
|
|
72
|
+
const objProp = obj[e]
|
|
73
73
|
if (elementProp === undefined) {
|
|
74
|
-
element[e] = objProp
|
|
74
|
+
element[e] = objProp
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
|
-
return element
|
|
78
|
-
}
|
|
77
|
+
return element
|
|
78
|
+
}
|
|
79
79
|
|
|
80
80
|
export const deepMerge = (element, extend, excludeFrom = []) => {
|
|
81
81
|
for (const e in extend) {
|
|
82
|
-
const hasOwnProperty = Object.prototype.hasOwnProperty.call(extend, e)
|
|
83
|
-
if (!hasOwnProperty || excludeFrom.includes(e) || e.startsWith(
|
|
84
|
-
continue
|
|
85
|
-
const elementProp = element[e]
|
|
86
|
-
const extendProp = extend[e]
|
|
82
|
+
const hasOwnProperty = Object.prototype.hasOwnProperty.call(extend, e)
|
|
83
|
+
if (!hasOwnProperty || excludeFrom.includes(e) || e.startsWith('__'))
|
|
84
|
+
continue
|
|
85
|
+
const elementProp = element[e]
|
|
86
|
+
const extendProp = extend[e]
|
|
87
87
|
if (isObjectLike(elementProp) && isObjectLike(extendProp)) {
|
|
88
|
-
deepMerge(elementProp, extendProp, excludeFrom)
|
|
88
|
+
deepMerge(elementProp, extendProp, excludeFrom)
|
|
89
89
|
} else if (elementProp === undefined) {
|
|
90
|
-
element[e] = extendProp
|
|
90
|
+
element[e] = extendProp
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
|
-
return element
|
|
94
|
-
}
|
|
93
|
+
return element
|
|
94
|
+
}
|
|
95
95
|
|
|
96
96
|
export const clone = (obj, excludeFrom = []) => {
|
|
97
|
-
const o = {}
|
|
97
|
+
const o = {}
|
|
98
98
|
for (const prop in obj) {
|
|
99
|
-
const hasOwnProperty = Object.prototype.hasOwnProperty.call(obj, prop)
|
|
100
|
-
if (!hasOwnProperty || excludeFrom.includes(prop) || prop.startsWith(
|
|
101
|
-
continue
|
|
102
|
-
o[prop] = obj[prop]
|
|
99
|
+
const hasOwnProperty = Object.prototype.hasOwnProperty.call(obj, prop)
|
|
100
|
+
if (!hasOwnProperty || excludeFrom.includes(prop) || prop.startsWith('__'))
|
|
101
|
+
continue
|
|
102
|
+
o[prop] = obj[prop]
|
|
103
103
|
}
|
|
104
|
-
return o
|
|
105
|
-
}
|
|
104
|
+
return o
|
|
105
|
+
}
|
|
106
106
|
|
|
107
107
|
// Merge array, but exclude keys listed in 'excl'z
|
|
108
108
|
export const mergeArrayExclude = (arr, exclude = []) => {
|
|
109
109
|
return arr.reduce(
|
|
110
110
|
(acc, curr) => deepMerge(acc, deepClone(curr, { exclude })),
|
|
111
111
|
{}
|
|
112
|
-
)
|
|
113
|
-
}
|
|
112
|
+
)
|
|
113
|
+
}
|
|
114
114
|
/**
|
|
115
115
|
* Enhanced deep clone function that combines features from multiple implementations
|
|
116
116
|
* @param {any} obj - Object to clone
|
|
@@ -130,19 +130,19 @@ export const deepClone = (obj, options = {}) => {
|
|
|
130
130
|
cleanNull = false,
|
|
131
131
|
window: targetWindow,
|
|
132
132
|
visited = new WeakMap(),
|
|
133
|
-
handleExtend = false
|
|
134
|
-
} = options
|
|
133
|
+
handleExtend = false
|
|
134
|
+
} = options
|
|
135
135
|
|
|
136
|
-
const contentWindow = targetWindow || window || globalThis
|
|
136
|
+
const contentWindow = targetWindow || window || globalThis
|
|
137
137
|
|
|
138
138
|
// Handle non-object types and special cases
|
|
139
139
|
if (!isObjectLike(obj) || isDOMNode(obj)) {
|
|
140
|
-
return obj
|
|
140
|
+
return obj
|
|
141
141
|
}
|
|
142
142
|
|
|
143
143
|
// Handle circular references
|
|
144
144
|
if (visited.has(obj)) {
|
|
145
|
-
return visited.get(obj)
|
|
145
|
+
return visited.get(obj)
|
|
146
146
|
}
|
|
147
147
|
|
|
148
148
|
// Create appropriate container based on type and window context
|
|
@@ -152,249 +152,249 @@ export const deepClone = (obj, options = {}) => {
|
|
|
152
152
|
: new contentWindow.Object()
|
|
153
153
|
: isArray(obj)
|
|
154
154
|
? []
|
|
155
|
-
: {}
|
|
155
|
+
: {}
|
|
156
156
|
|
|
157
157
|
// Store the clone to handle circular references
|
|
158
|
-
visited.set(obj, clone)
|
|
158
|
+
visited.set(obj, clone)
|
|
159
159
|
|
|
160
160
|
// Clone properties
|
|
161
161
|
for (const key in obj) {
|
|
162
|
-
if (!Object.prototype.hasOwnProperty.call(obj, key)) continue
|
|
162
|
+
if (!Object.prototype.hasOwnProperty.call(obj, key)) continue
|
|
163
163
|
|
|
164
164
|
// Skip excluded properties
|
|
165
|
-
if (exclude.includes(key) || key.startsWith(
|
|
166
|
-
continue
|
|
165
|
+
if (exclude.includes(key) || key.startsWith('__') || key === '__proto__')
|
|
166
|
+
continue
|
|
167
167
|
|
|
168
|
-
const value = obj[key]
|
|
168
|
+
const value = obj[key]
|
|
169
169
|
|
|
170
170
|
// Skip based on cleanup options
|
|
171
171
|
if ((cleanUndefined && isUndefined(value)) || (cleanNull && isNull(value)))
|
|
172
|
-
continue
|
|
172
|
+
continue
|
|
173
173
|
|
|
174
174
|
// Handle special cases
|
|
175
175
|
if (isDOMNode(value)) {
|
|
176
|
-
clone[key] = value
|
|
177
|
-
continue
|
|
176
|
+
clone[key] = value
|
|
177
|
+
continue
|
|
178
178
|
}
|
|
179
179
|
|
|
180
180
|
// Handle 'extend' array if enabled
|
|
181
|
-
if (handleExtend && key ===
|
|
182
|
-
clone[key] = mergeArray(value, exclude)
|
|
183
|
-
continue
|
|
181
|
+
if (handleExtend && key === 'extend' && isArray(value)) {
|
|
182
|
+
clone[key] = mergeArray(value, exclude)
|
|
183
|
+
continue
|
|
184
184
|
}
|
|
185
185
|
|
|
186
186
|
// Handle functions in cross-frame scenario
|
|
187
187
|
if (isFunction(value) && options.window) {
|
|
188
|
-
clone[key] = contentWindow.eval(
|
|
189
|
-
continue
|
|
188
|
+
clone[key] = contentWindow.eval('(' + value.toString() + ')')
|
|
189
|
+
continue
|
|
190
190
|
}
|
|
191
191
|
|
|
192
192
|
// Recursively clone objects
|
|
193
193
|
if (isObjectLike(value)) {
|
|
194
|
-
if (!Object.prototype.hasOwnProperty.call(obj, key)) continue
|
|
194
|
+
if (!Object.prototype.hasOwnProperty.call(obj, key)) continue
|
|
195
195
|
|
|
196
196
|
clone[key] = deepClone(value, {
|
|
197
197
|
...options,
|
|
198
|
-
visited
|
|
199
|
-
})
|
|
198
|
+
visited
|
|
199
|
+
})
|
|
200
200
|
} else {
|
|
201
|
-
clone[key] = value
|
|
201
|
+
clone[key] = value
|
|
202
202
|
}
|
|
203
203
|
}
|
|
204
204
|
|
|
205
|
-
return clone
|
|
206
|
-
}
|
|
205
|
+
return clone
|
|
206
|
+
}
|
|
207
207
|
|
|
208
208
|
/**
|
|
209
209
|
* Stringify object
|
|
210
210
|
*/
|
|
211
211
|
export const deepStringify = (obj, stringified = {}) => {
|
|
212
212
|
if (obj.node || obj.__ref || obj.parent || obj.__element || obj.parse) {
|
|
213
|
-
(obj.__element || obj.parent?.__element).warn(
|
|
214
|
-
|
|
213
|
+
;(obj.__element || obj.parent?.__element).warn(
|
|
214
|
+
'Trying to clone element or state at',
|
|
215
215
|
obj
|
|
216
|
-
)
|
|
217
|
-
obj = obj.parse?.()
|
|
216
|
+
)
|
|
217
|
+
obj = obj.parse?.()
|
|
218
218
|
}
|
|
219
219
|
|
|
220
220
|
for (const prop in obj) {
|
|
221
|
-
const objProp = obj[prop]
|
|
221
|
+
const objProp = obj[prop]
|
|
222
222
|
if (isFunction(objProp)) {
|
|
223
|
-
stringified[prop] = objProp.toString()
|
|
223
|
+
stringified[prop] = objProp.toString()
|
|
224
224
|
} else if (isObject(objProp)) {
|
|
225
|
-
stringified[prop] = {}
|
|
226
|
-
deepStringify(objProp, stringified[prop])
|
|
225
|
+
stringified[prop] = {}
|
|
226
|
+
deepStringify(objProp, stringified[prop])
|
|
227
227
|
} else if (isArray(objProp)) {
|
|
228
|
-
stringified[prop] = []
|
|
228
|
+
stringified[prop] = []
|
|
229
229
|
objProp.forEach((v, i) => {
|
|
230
230
|
if (isObject(v)) {
|
|
231
|
-
stringified[prop][i] = {}
|
|
232
|
-
deepStringify(v, stringified[prop][i])
|
|
231
|
+
stringified[prop][i] = {}
|
|
232
|
+
deepStringify(v, stringified[prop][i])
|
|
233
233
|
} else if (isFunction(v)) {
|
|
234
|
-
stringified[prop][i] = v.toString()
|
|
234
|
+
stringified[prop][i] = v.toString()
|
|
235
235
|
} else {
|
|
236
|
-
stringified[prop][i] = v
|
|
236
|
+
stringified[prop][i] = v
|
|
237
237
|
}
|
|
238
|
-
})
|
|
238
|
+
})
|
|
239
239
|
} else {
|
|
240
|
-
stringified[prop] = objProp
|
|
240
|
+
stringified[prop] = objProp
|
|
241
241
|
}
|
|
242
242
|
}
|
|
243
|
-
return stringified
|
|
244
|
-
}
|
|
243
|
+
return stringified
|
|
244
|
+
}
|
|
245
245
|
|
|
246
|
-
const MAX_DEPTH = 100
|
|
246
|
+
const MAX_DEPTH = 100 // Adjust this value as needed
|
|
247
247
|
export const deepStringifyWithMaxDepth = (
|
|
248
248
|
obj,
|
|
249
249
|
stringified = {},
|
|
250
250
|
depth = 0,
|
|
251
|
-
path =
|
|
251
|
+
path = ''
|
|
252
252
|
) => {
|
|
253
253
|
if (depth > MAX_DEPTH) {
|
|
254
254
|
console.warn(
|
|
255
255
|
`Maximum depth exceeded at path: ${path}. Possible circular reference.`
|
|
256
|
-
)
|
|
257
|
-
return
|
|
256
|
+
)
|
|
257
|
+
return '[MAX_DEPTH_EXCEEDED]'
|
|
258
258
|
}
|
|
259
259
|
|
|
260
260
|
for (const prop in obj) {
|
|
261
|
-
const currentPath = path ? `${path}.${prop}` : prop
|
|
262
|
-
const objProp = obj[prop]
|
|
261
|
+
const currentPath = path ? `${path}.${prop}` : prop
|
|
262
|
+
const objProp = obj[prop]
|
|
263
263
|
|
|
264
264
|
if (isFunction(objProp)) {
|
|
265
|
-
stringified[prop] = objProp.toString()
|
|
265
|
+
stringified[prop] = objProp.toString()
|
|
266
266
|
} else if (isObject(objProp)) {
|
|
267
|
-
stringified[prop] = {}
|
|
267
|
+
stringified[prop] = {}
|
|
268
268
|
deepStringifyWithMaxDepth(
|
|
269
269
|
objProp,
|
|
270
270
|
stringified[prop],
|
|
271
271
|
depth + 1,
|
|
272
272
|
currentPath
|
|
273
|
-
)
|
|
273
|
+
)
|
|
274
274
|
} else if (isArray(objProp)) {
|
|
275
|
-
stringified[prop] = []
|
|
275
|
+
stringified[prop] = []
|
|
276
276
|
objProp.forEach((v, i) => {
|
|
277
|
-
const itemPath = `${currentPath}[${i}]
|
|
277
|
+
const itemPath = `${currentPath}[${i}]`
|
|
278
278
|
if (isObject(v)) {
|
|
279
|
-
stringified[prop][i] = {}
|
|
279
|
+
stringified[prop][i] = {}
|
|
280
280
|
deepStringifyWithMaxDepth(
|
|
281
281
|
v,
|
|
282
282
|
stringified[prop][i],
|
|
283
283
|
depth + 1,
|
|
284
284
|
itemPath
|
|
285
|
-
)
|
|
285
|
+
)
|
|
286
286
|
} else if (isFunction(v)) {
|
|
287
|
-
stringified[prop][i] = v.toString()
|
|
287
|
+
stringified[prop][i] = v.toString()
|
|
288
288
|
} else {
|
|
289
|
-
stringified[prop][i] = v
|
|
289
|
+
stringified[prop][i] = v
|
|
290
290
|
}
|
|
291
|
-
})
|
|
291
|
+
})
|
|
292
292
|
} else {
|
|
293
|
-
stringified[prop] = objProp
|
|
293
|
+
stringified[prop] = objProp
|
|
294
294
|
}
|
|
295
295
|
}
|
|
296
|
-
return stringified
|
|
297
|
-
}
|
|
296
|
+
return stringified
|
|
297
|
+
}
|
|
298
298
|
|
|
299
299
|
export const objectToString = (obj = {}, indent = 0) => {
|
|
300
300
|
// Handle empty object case
|
|
301
|
-
if (obj === null || typeof obj !==
|
|
302
|
-
return String(obj)
|
|
301
|
+
if (obj === null || typeof obj !== 'object') {
|
|
302
|
+
return String(obj)
|
|
303
303
|
}
|
|
304
304
|
|
|
305
305
|
// Handle empty object case
|
|
306
306
|
if (Object.keys(obj).length === 0) {
|
|
307
|
-
return
|
|
307
|
+
return '{}'
|
|
308
308
|
}
|
|
309
309
|
|
|
310
|
-
const spaces =
|
|
311
|
-
let str =
|
|
310
|
+
const spaces = ' '.repeat(indent)
|
|
311
|
+
let str = '{\n'
|
|
312
312
|
|
|
313
313
|
for (const [key, value] of Object.entries(obj)) {
|
|
314
314
|
const keyNotAllowdChars = stringIncludesAny(key, [
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
])
|
|
330
|
-
const stringedKey = keyNotAllowdChars ? `'${key}'` : key
|
|
331
|
-
str += `${spaces} ${stringedKey}:
|
|
315
|
+
'&',
|
|
316
|
+
'*',
|
|
317
|
+
'-',
|
|
318
|
+
':',
|
|
319
|
+
'%',
|
|
320
|
+
'{',
|
|
321
|
+
'}',
|
|
322
|
+
'>',
|
|
323
|
+
'<',
|
|
324
|
+
'@',
|
|
325
|
+
'.',
|
|
326
|
+
'/',
|
|
327
|
+
'!',
|
|
328
|
+
' '
|
|
329
|
+
])
|
|
330
|
+
const stringedKey = keyNotAllowdChars ? `'${key}'` : key
|
|
331
|
+
str += `${spaces} ${stringedKey}: `
|
|
332
332
|
|
|
333
333
|
if (isArray(value)) {
|
|
334
|
-
str +=
|
|
334
|
+
str += '[\n'
|
|
335
335
|
for (const element of value) {
|
|
336
336
|
if (isObjectLike(element) && element !== null) {
|
|
337
|
-
str += `${spaces} ${objectToString(element, indent + 2)},\n
|
|
337
|
+
str += `${spaces} ${objectToString(element, indent + 2)},\n`
|
|
338
338
|
} else if (isString(element)) {
|
|
339
|
-
str += `${spaces} '${element}',\n
|
|
339
|
+
str += `${spaces} '${element}',\n`
|
|
340
340
|
} else {
|
|
341
|
-
str += `${spaces} ${element},\n
|
|
341
|
+
str += `${spaces} ${element},\n`
|
|
342
342
|
}
|
|
343
343
|
}
|
|
344
|
-
str += `${spaces} ]
|
|
344
|
+
str += `${spaces} ]`
|
|
345
345
|
} else if (isObjectLike(value)) {
|
|
346
|
-
str += objectToString(value, indent + 1)
|
|
346
|
+
str += objectToString(value, indent + 1)
|
|
347
347
|
} else if (isString(value)) {
|
|
348
|
-
str += stringIncludesAny(value, [
|
|
348
|
+
str += stringIncludesAny(value, ['\n', "'"])
|
|
349
349
|
? `\`${value}\``
|
|
350
|
-
: `'${value}'
|
|
350
|
+
: `'${value}'`
|
|
351
351
|
} else {
|
|
352
|
-
str += value
|
|
352
|
+
str += value
|
|
353
353
|
}
|
|
354
354
|
|
|
355
|
-
str +=
|
|
355
|
+
str += ',\n'
|
|
356
356
|
}
|
|
357
357
|
|
|
358
|
-
str += `${spaces}}
|
|
359
|
-
return str
|
|
360
|
-
}
|
|
358
|
+
str += `${spaces}}`
|
|
359
|
+
return str
|
|
360
|
+
}
|
|
361
361
|
|
|
362
362
|
/**
|
|
363
363
|
* Stringify object
|
|
364
364
|
*/
|
|
365
365
|
export const detachFunctionsFromObject = (obj, detached = {}) => {
|
|
366
366
|
for (const prop in obj) {
|
|
367
|
-
const objProp = obj[prop]
|
|
368
|
-
if (isFunction(objProp)) continue
|
|
367
|
+
const objProp = obj[prop]
|
|
368
|
+
if (isFunction(objProp)) continue
|
|
369
369
|
else if (isObject(objProp)) {
|
|
370
|
-
detached[prop] = {}
|
|
371
|
-
deepStringify(objProp, detached[prop])
|
|
370
|
+
detached[prop] = {}
|
|
371
|
+
deepStringify(objProp, detached[prop])
|
|
372
372
|
} else if (isArray(objProp)) {
|
|
373
|
-
detached[prop] = []
|
|
373
|
+
detached[prop] = []
|
|
374
374
|
objProp.forEach((v, i) => {
|
|
375
|
-
if (isFunction(v)) return
|
|
375
|
+
if (isFunction(v)) return
|
|
376
376
|
if (isObject(v)) {
|
|
377
|
-
detached[prop][i] = {}
|
|
378
|
-
detachFunctionsFromObject(v, detached[prop][i])
|
|
377
|
+
detached[prop][i] = {}
|
|
378
|
+
detachFunctionsFromObject(v, detached[prop][i])
|
|
379
379
|
} else {
|
|
380
|
-
detached[prop][i] = v
|
|
380
|
+
detached[prop][i] = v
|
|
381
381
|
}
|
|
382
|
-
})
|
|
382
|
+
})
|
|
383
383
|
} else {
|
|
384
|
-
detached[prop] = objProp
|
|
384
|
+
detached[prop] = objProp
|
|
385
385
|
}
|
|
386
386
|
}
|
|
387
|
-
return detached
|
|
388
|
-
}
|
|
387
|
+
return detached
|
|
388
|
+
}
|
|
389
389
|
|
|
390
390
|
export const hasFunction = (str) => {
|
|
391
|
-
if (!str) return false
|
|
391
|
+
if (!str) return false
|
|
392
392
|
|
|
393
|
-
const trimmed = str.trim().replace(/\n\s*/g,
|
|
393
|
+
const trimmed = str.trim().replace(/\n\s*/g, ' ').trim()
|
|
394
394
|
|
|
395
|
-
if (trimmed ===
|
|
396
|
-
if (trimmed ===
|
|
397
|
-
if (trimmed ===
|
|
395
|
+
if (trimmed === '') return false
|
|
396
|
+
if (trimmed === '{}') return false
|
|
397
|
+
if (trimmed === '[]') return false
|
|
398
398
|
|
|
399
399
|
const patterns = [
|
|
400
400
|
/^\(\s*\{[^}]*\}\s*\)\s*=>/,
|
|
@@ -402,211 +402,211 @@ export const hasFunction = (str) => {
|
|
|
402
402
|
/^function[\s(]/,
|
|
403
403
|
/^async\s+/,
|
|
404
404
|
/^\(\s*function/,
|
|
405
|
-
/^[a-zA-Z_$][a-zA-Z0-9_$]*\s
|
|
406
|
-
]
|
|
405
|
+
/^[a-zA-Z_$][a-zA-Z0-9_$]*\s*=>/
|
|
406
|
+
]
|
|
407
407
|
|
|
408
|
-
const isClass = str.startsWith(
|
|
409
|
-
const isFunction = patterns.some((pattern) => pattern.test(trimmed))
|
|
410
|
-
const isObjectLiteral = trimmed.startsWith(
|
|
411
|
-
const isArrayLiteral = trimmed.startsWith(
|
|
412
|
-
const isJSONLike = /^["[{]/.test(trimmed) && !trimmed.includes(
|
|
408
|
+
const isClass = str.startsWith('class')
|
|
409
|
+
const isFunction = patterns.some((pattern) => pattern.test(trimmed))
|
|
410
|
+
const isObjectLiteral = trimmed.startsWith('{') && !trimmed.includes('=>')
|
|
411
|
+
const isArrayLiteral = trimmed.startsWith('[')
|
|
412
|
+
const isJSONLike = /^["[{]/.test(trimmed) && !trimmed.includes('=>')
|
|
413
413
|
|
|
414
414
|
return (
|
|
415
415
|
(isFunction || isClass) &&
|
|
416
416
|
!isObjectLiteral &&
|
|
417
417
|
!isArrayLiteral &&
|
|
418
418
|
!isJSONLike
|
|
419
|
-
)
|
|
420
|
-
}
|
|
419
|
+
)
|
|
420
|
+
}
|
|
421
421
|
|
|
422
422
|
export const deepDestringify = (obj, destringified = {}) => {
|
|
423
423
|
for (const prop in obj) {
|
|
424
|
-
const hasOwnProperty = Object.prototype.hasOwnProperty.call(obj, prop)
|
|
425
|
-
if (!hasOwnProperty) continue
|
|
424
|
+
const hasOwnProperty = Object.prototype.hasOwnProperty.call(obj, prop)
|
|
425
|
+
if (!hasOwnProperty) continue
|
|
426
426
|
|
|
427
|
-
const objProp = obj[prop]
|
|
427
|
+
const objProp = obj[prop]
|
|
428
428
|
|
|
429
429
|
if (isString(objProp)) {
|
|
430
430
|
if (hasFunction(objProp)) {
|
|
431
431
|
try {
|
|
432
|
-
const evalProp = window.eval(`(${objProp})`)
|
|
433
|
-
destringified[prop] = evalProp
|
|
432
|
+
const evalProp = window.eval(`(${objProp})`)
|
|
433
|
+
destringified[prop] = evalProp
|
|
434
434
|
} catch (e) {
|
|
435
|
-
if (e) destringified[prop] = objProp
|
|
435
|
+
if (e) destringified[prop] = objProp
|
|
436
436
|
}
|
|
437
437
|
} else {
|
|
438
|
-
destringified[prop] = objProp
|
|
438
|
+
destringified[prop] = objProp
|
|
439
439
|
}
|
|
440
440
|
} else if (isArray(objProp)) {
|
|
441
|
-
destringified[prop] = []
|
|
441
|
+
destringified[prop] = []
|
|
442
442
|
objProp.forEach((arrProp) => {
|
|
443
443
|
if (isString(arrProp)) {
|
|
444
444
|
if (hasFunction(arrProp)) {
|
|
445
445
|
try {
|
|
446
|
-
const evalProp = window.eval(`(${arrProp})`)
|
|
447
|
-
destringified[prop].push(evalProp)
|
|
446
|
+
const evalProp = window.eval(`(${arrProp})`)
|
|
447
|
+
destringified[prop].push(evalProp)
|
|
448
448
|
} catch (e) {
|
|
449
|
-
if (e) destringified[prop].push(arrProp)
|
|
449
|
+
if (e) destringified[prop].push(arrProp)
|
|
450
450
|
}
|
|
451
451
|
} else {
|
|
452
|
-
destringified[prop].push(arrProp)
|
|
452
|
+
destringified[prop].push(arrProp)
|
|
453
453
|
}
|
|
454
454
|
} else if (isObject(arrProp)) {
|
|
455
|
-
destringified[prop].push(deepDestringify(arrProp))
|
|
455
|
+
destringified[prop].push(deepDestringify(arrProp))
|
|
456
456
|
} else {
|
|
457
|
-
destringified[prop].push(arrProp)
|
|
457
|
+
destringified[prop].push(arrProp)
|
|
458
458
|
}
|
|
459
|
-
})
|
|
459
|
+
})
|
|
460
460
|
} else if (isObject(objProp)) {
|
|
461
|
-
destringified[prop] = deepDestringify(objProp, destringified[prop])
|
|
461
|
+
destringified[prop] = deepDestringify(objProp, destringified[prop])
|
|
462
462
|
} else {
|
|
463
|
-
destringified[prop] = objProp
|
|
463
|
+
destringified[prop] = objProp
|
|
464
464
|
}
|
|
465
465
|
}
|
|
466
|
-
return destringified
|
|
467
|
-
}
|
|
466
|
+
return destringified
|
|
467
|
+
}
|
|
468
468
|
|
|
469
469
|
export const stringToObject = (str, opts = { verbose: true }) => {
|
|
470
470
|
try {
|
|
471
|
-
return str ? window.eval(
|
|
471
|
+
return str ? window.eval('(' + str + ')') : {} // eslint-disable-line
|
|
472
472
|
} catch (e) {
|
|
473
|
-
if (opts.verbose) console.warn(e)
|
|
474
|
-
if (opts.errorCallback) opts.errorCallback(e)
|
|
473
|
+
if (opts.verbose) console.warn(e)
|
|
474
|
+
if (opts.errorCallback) opts.errorCallback(e)
|
|
475
475
|
}
|
|
476
|
-
}
|
|
476
|
+
}
|
|
477
477
|
|
|
478
478
|
export const diffObjects = (original, objToDiff, cache) => {
|
|
479
479
|
for (const e in objToDiff) {
|
|
480
|
-
if (e ===
|
|
480
|
+
if (e === 'ref') continue
|
|
481
481
|
|
|
482
|
-
const originalProp = original[e]
|
|
483
|
-
const objToDiffProp = objToDiff[e]
|
|
482
|
+
const originalProp = original[e]
|
|
483
|
+
const objToDiffProp = objToDiff[e]
|
|
484
484
|
|
|
485
485
|
if (isObject(originalProp) && isObject(objToDiffProp)) {
|
|
486
|
-
cache[e] = {}
|
|
487
|
-
diff(originalProp, objToDiffProp, cache[e])
|
|
486
|
+
cache[e] = {}
|
|
487
|
+
diff(originalProp, objToDiffProp, cache[e])
|
|
488
488
|
} else if (objToDiffProp !== undefined) {
|
|
489
|
-
cache[e] = objToDiffProp
|
|
489
|
+
cache[e] = objToDiffProp
|
|
490
490
|
}
|
|
491
491
|
}
|
|
492
|
-
return cache
|
|
493
|
-
}
|
|
492
|
+
return cache
|
|
493
|
+
}
|
|
494
494
|
|
|
495
495
|
export const diffArrays = (original, objToDiff, cache) => {
|
|
496
496
|
if (original.length !== objToDiff.length) {
|
|
497
|
-
cache = objToDiff
|
|
497
|
+
cache = objToDiff
|
|
498
498
|
} else {
|
|
499
|
-
const diffArr = []
|
|
499
|
+
const diffArr = []
|
|
500
500
|
for (let i = 0; i < original.length; i++) {
|
|
501
|
-
const diffObj = diff(original[i], objToDiff[i])
|
|
501
|
+
const diffObj = diff(original[i], objToDiff[i])
|
|
502
502
|
if (Object.keys(diffObj).length > 0) {
|
|
503
|
-
diffArr.push(diffObj)
|
|
503
|
+
diffArr.push(diffObj)
|
|
504
504
|
}
|
|
505
505
|
}
|
|
506
506
|
if (diffArr.length > 0) {
|
|
507
|
-
cache = diffArr
|
|
507
|
+
cache = diffArr
|
|
508
508
|
}
|
|
509
509
|
}
|
|
510
|
-
return cache
|
|
511
|
-
}
|
|
510
|
+
return cache
|
|
511
|
+
}
|
|
512
512
|
|
|
513
513
|
export const diff = (original, objToDiff, cache = {}) => {
|
|
514
514
|
if (isArray(original) && isArray(objToDiff)) {
|
|
515
|
-
cache = []
|
|
516
|
-
diffArrays(original, objToDiff, cache)
|
|
515
|
+
cache = []
|
|
516
|
+
diffArrays(original, objToDiff, cache)
|
|
517
517
|
} else {
|
|
518
|
-
diffObjects(original, objToDiff, cache)
|
|
518
|
+
diffObjects(original, objToDiff, cache)
|
|
519
519
|
}
|
|
520
520
|
|
|
521
|
-
return cache
|
|
522
|
-
}
|
|
521
|
+
return cache
|
|
522
|
+
}
|
|
523
523
|
|
|
524
524
|
export const hasOwnProperty = (o, ...args) =>
|
|
525
|
-
Object.prototype.hasOwnProperty.call(o, ...args)
|
|
525
|
+
Object.prototype.hasOwnProperty.call(o, ...args)
|
|
526
526
|
|
|
527
|
-
export const isEmpty = (o) => Object.keys(o).length === 0
|
|
527
|
+
export const isEmpty = (o) => Object.keys(o).length === 0
|
|
528
528
|
|
|
529
|
-
export const isEmptyObject = (o) => isObject(o) && isEmpty(o)
|
|
529
|
+
export const isEmptyObject = (o) => isObject(o) && isEmpty(o)
|
|
530
530
|
|
|
531
|
-
export const makeObjectWithoutPrototype = () => Object.create(null)
|
|
531
|
+
export const makeObjectWithoutPrototype = () => Object.create(null)
|
|
532
532
|
|
|
533
533
|
// by mattphillips
|
|
534
534
|
// https://github.com/mattphillips/deep-object-diff/blob/main/src/diff.js
|
|
535
535
|
export const deepDiff = (lhs, rhs) => {
|
|
536
|
-
if (lhs === rhs) return {}
|
|
536
|
+
if (lhs === rhs) return {}
|
|
537
537
|
|
|
538
|
-
if (!isObjectLike(lhs) || !isObjectLike(rhs)) return rhs
|
|
538
|
+
if (!isObjectLike(lhs) || !isObjectLike(rhs)) return rhs
|
|
539
539
|
|
|
540
540
|
const deletedValues = Object.keys(lhs).reduce((acc, key) => {
|
|
541
541
|
if (!hasOwnProperty(rhs, key)) {
|
|
542
|
-
acc[key] = undefined
|
|
542
|
+
acc[key] = undefined
|
|
543
543
|
}
|
|
544
544
|
|
|
545
|
-
return acc
|
|
546
|
-
}, makeObjectWithoutPrototype())
|
|
545
|
+
return acc
|
|
546
|
+
}, makeObjectWithoutPrototype())
|
|
547
547
|
|
|
548
548
|
if (isDate(lhs) || isDate(rhs)) {
|
|
549
|
-
if (lhs.valueOf() === rhs.valueOf()) return {}
|
|
550
|
-
return rhs
|
|
549
|
+
if (lhs.valueOf() === rhs.valueOf()) return {}
|
|
550
|
+
return rhs
|
|
551
551
|
}
|
|
552
552
|
|
|
553
553
|
return Object.keys(rhs).reduce((acc, key) => {
|
|
554
554
|
if (!hasOwnProperty(lhs, key)) {
|
|
555
|
-
acc[key] = rhs[key]
|
|
556
|
-
return acc
|
|
555
|
+
acc[key] = rhs[key]
|
|
556
|
+
return acc
|
|
557
557
|
}
|
|
558
558
|
|
|
559
|
-
const difference = diff(lhs[key], rhs[key])
|
|
559
|
+
const difference = diff(lhs[key], rhs[key])
|
|
560
560
|
|
|
561
561
|
if (
|
|
562
562
|
isEmptyObject(difference) &&
|
|
563
563
|
!isDate(difference) &&
|
|
564
564
|
(isEmptyObject(lhs[key]) || !isEmptyObject(rhs[key]))
|
|
565
565
|
) {
|
|
566
|
-
return acc
|
|
566
|
+
return acc
|
|
567
567
|
}
|
|
568
568
|
|
|
569
|
-
acc[key] = difference
|
|
570
|
-
return acc
|
|
571
|
-
}, deletedValues)
|
|
572
|
-
}
|
|
569
|
+
acc[key] = difference
|
|
570
|
+
return acc
|
|
571
|
+
}, deletedValues)
|
|
572
|
+
}
|
|
573
573
|
|
|
574
574
|
/**
|
|
575
575
|
* Overwrites object properties with another
|
|
576
576
|
*/
|
|
577
577
|
export const overwrite = (element, params, opts = {}) => {
|
|
578
|
-
const { __ref: ref } = element
|
|
579
|
-
const excl = opts.exclude || []
|
|
580
|
-
const allowUnderscore = opts.preventUnderscore
|
|
581
|
-
const preventCaching = opts.preventCaching
|
|
578
|
+
const { __ref: ref } = element
|
|
579
|
+
const excl = opts.exclude || []
|
|
580
|
+
const allowUnderscore = opts.preventUnderscore
|
|
581
|
+
const preventCaching = opts.preventCaching
|
|
582
582
|
|
|
583
583
|
for (const e in params) {
|
|
584
|
-
if (excl.includes(e) || (!allowUnderscore && e.startsWith(
|
|
584
|
+
if (excl.includes(e) || (!allowUnderscore && e.startsWith('__'))) continue
|
|
585
585
|
|
|
586
|
-
const elementProp = element[e]
|
|
587
|
-
const paramsProp = params[e]
|
|
586
|
+
const elementProp = element[e]
|
|
587
|
+
const paramsProp = params[e]
|
|
588
588
|
|
|
589
589
|
if (paramsProp !== undefined) {
|
|
590
|
-
element[e] = paramsProp
|
|
590
|
+
element[e] = paramsProp
|
|
591
591
|
if (ref && !preventCaching) {
|
|
592
|
-
ref.__cache[e] = elementProp
|
|
592
|
+
ref.__cache[e] = elementProp
|
|
593
593
|
}
|
|
594
594
|
if (isObject(opts.diff)) {
|
|
595
|
-
diff[e] = elementProp
|
|
595
|
+
diff[e] = elementProp
|
|
596
596
|
}
|
|
597
597
|
}
|
|
598
598
|
}
|
|
599
599
|
|
|
600
|
-
return element
|
|
601
|
-
}
|
|
600
|
+
return element
|
|
601
|
+
}
|
|
602
602
|
|
|
603
603
|
export const overwriteShallow = (obj, params, excludeFrom = []) => {
|
|
604
604
|
for (const e in params) {
|
|
605
|
-
if (excludeFrom.includes(e) || e.startsWith(
|
|
606
|
-
obj[e] = params[e]
|
|
605
|
+
if (excludeFrom.includes(e) || e.startsWith('__')) continue
|
|
606
|
+
obj[e] = params[e]
|
|
607
607
|
}
|
|
608
|
-
return obj
|
|
609
|
-
}
|
|
608
|
+
return obj
|
|
609
|
+
}
|
|
610
610
|
|
|
611
611
|
/**
|
|
612
612
|
* Overwrites DEEPLY object properties with another
|
|
@@ -617,8 +617,8 @@ export const overwriteDeep = (
|
|
|
617
617
|
opts = {},
|
|
618
618
|
visited = new WeakMap()
|
|
619
619
|
) => {
|
|
620
|
-
const excl = opts.exclude || []
|
|
621
|
-
const forcedExclude = opts.preventForce ? [] : [
|
|
620
|
+
const excl = opts.exclude || []
|
|
621
|
+
const forcedExclude = opts.preventForce ? [] : ['node', 'window']
|
|
622
622
|
|
|
623
623
|
if (
|
|
624
624
|
!isObjectLike(obj) ||
|
|
@@ -626,53 +626,53 @@ export const overwriteDeep = (
|
|
|
626
626
|
isDOMNode(obj) ||
|
|
627
627
|
isDOMNode(params)
|
|
628
628
|
) {
|
|
629
|
-
return params
|
|
629
|
+
return params
|
|
630
630
|
}
|
|
631
631
|
|
|
632
|
-
if (visited.has(obj)) return visited.get(obj)
|
|
633
|
-
visited.set(obj, obj)
|
|
632
|
+
if (visited.has(obj)) return visited.get(obj)
|
|
633
|
+
visited.set(obj, obj)
|
|
634
634
|
|
|
635
635
|
for (const e in params) {
|
|
636
|
-
if (!Object.hasOwnProperty.call(params, e)) continue
|
|
637
|
-
if (excl.includes(e) || (forcedExclude && e.startsWith(
|
|
636
|
+
if (!Object.hasOwnProperty.call(params, e)) continue
|
|
637
|
+
if (excl.includes(e) || (forcedExclude && e.startsWith('__'))) continue
|
|
638
638
|
|
|
639
|
-
const objProp = obj[e]
|
|
640
|
-
const paramsProp = params[e]
|
|
639
|
+
const objProp = obj[e]
|
|
640
|
+
const paramsProp = params[e]
|
|
641
641
|
|
|
642
642
|
if (isDOMNode(paramsProp)) {
|
|
643
|
-
obj[e] = paramsProp
|
|
643
|
+
obj[e] = paramsProp
|
|
644
644
|
} else if (isObjectLike(objProp) && isObjectLike(paramsProp)) {
|
|
645
|
-
obj[e] = overwriteDeep(objProp, paramsProp, opts, visited)
|
|
645
|
+
obj[e] = overwriteDeep(objProp, paramsProp, opts, visited)
|
|
646
646
|
} else if (paramsProp !== undefined) {
|
|
647
|
-
obj[e] = paramsProp
|
|
647
|
+
obj[e] = paramsProp
|
|
648
648
|
}
|
|
649
649
|
}
|
|
650
650
|
|
|
651
|
-
return obj
|
|
652
|
-
}
|
|
651
|
+
return obj
|
|
652
|
+
}
|
|
653
653
|
|
|
654
654
|
/**
|
|
655
655
|
* Overwrites object properties with another
|
|
656
656
|
*/
|
|
657
657
|
export const mergeIfExisted = (a, b) => {
|
|
658
|
-
if (isObjectLike(a) && isObjectLike(b)) return deepMerge(a, b)
|
|
659
|
-
return a || b
|
|
660
|
-
}
|
|
658
|
+
if (isObjectLike(a) && isObjectLike(b)) return deepMerge(a, b)
|
|
659
|
+
return a || b
|
|
660
|
+
}
|
|
661
661
|
|
|
662
662
|
/**
|
|
663
663
|
* Overwrites object properties with another
|
|
664
664
|
*/
|
|
665
665
|
export const flattenRecursive = (param, prop, stack = []) => {
|
|
666
|
-
const objectized = mergeAndCloneIfArray(param)
|
|
667
|
-
stack.push(objectized)
|
|
666
|
+
const objectized = mergeAndCloneIfArray(param)
|
|
667
|
+
stack.push(objectized)
|
|
668
668
|
|
|
669
|
-
const extendOfExtend = objectized[prop]
|
|
670
|
-
if (extendOfExtend) flattenRecursive(extendOfExtend, prop, stack)
|
|
669
|
+
const extendOfExtend = objectized[prop]
|
|
670
|
+
if (extendOfExtend) flattenRecursive(extendOfExtend, prop, stack)
|
|
671
671
|
|
|
672
|
-
delete objectized[prop]
|
|
672
|
+
delete objectized[prop]
|
|
673
673
|
|
|
674
|
-
return stack
|
|
675
|
-
}
|
|
674
|
+
return stack
|
|
675
|
+
}
|
|
676
676
|
|
|
677
677
|
/**
|
|
678
678
|
* Recursively compares two values to determine if they are deeply equal.
|
|
@@ -711,257 +711,257 @@ export const flattenRecursive = (param, prop, stack = []) => {
|
|
|
711
711
|
export const isEqualDeep = (param, element, visited = new Set()) => {
|
|
712
712
|
// Check if both values are non-null objects
|
|
713
713
|
if (
|
|
714
|
-
typeof param !==
|
|
715
|
-
typeof element !==
|
|
714
|
+
typeof param !== 'object' ||
|
|
715
|
+
typeof element !== 'object' ||
|
|
716
716
|
param === null ||
|
|
717
717
|
element === null
|
|
718
718
|
) {
|
|
719
|
-
return param === element
|
|
719
|
+
return param === element // Compare non-object values directly
|
|
720
720
|
}
|
|
721
721
|
|
|
722
722
|
// Check for circular references
|
|
723
723
|
if (visited.has(param) || visited.has(element)) {
|
|
724
|
-
return true
|
|
724
|
+
return true // Assume equality to break the circular reference
|
|
725
725
|
}
|
|
726
726
|
|
|
727
|
-
visited.add(param)
|
|
728
|
-
visited.add(element)
|
|
727
|
+
visited.add(param)
|
|
728
|
+
visited.add(element)
|
|
729
729
|
|
|
730
|
-
const keysParam = Object.keys(param)
|
|
731
|
-
const keysElement = Object.keys(element)
|
|
730
|
+
const keysParam = Object.keys(param)
|
|
731
|
+
const keysElement = Object.keys(element)
|
|
732
732
|
|
|
733
733
|
// Check if both objects have the same number of properties
|
|
734
734
|
if (keysParam.length !== keysElement.length) {
|
|
735
|
-
return false
|
|
735
|
+
return false
|
|
736
736
|
}
|
|
737
737
|
|
|
738
738
|
// Check if all properties in param also exist in element
|
|
739
739
|
for (const key of keysParam) {
|
|
740
740
|
if (!keysElement.includes(key)) {
|
|
741
|
-
return false
|
|
741
|
+
return false
|
|
742
742
|
}
|
|
743
743
|
|
|
744
|
-
const paramProp = param[key]
|
|
745
|
-
const elementProp = element[key]
|
|
744
|
+
const paramProp = param[key]
|
|
745
|
+
const elementProp = element[key]
|
|
746
746
|
|
|
747
747
|
// Recursively check property values
|
|
748
748
|
if (!isEqualDeep(paramProp, elementProp, visited)) {
|
|
749
|
-
return false
|
|
749
|
+
return false
|
|
750
750
|
}
|
|
751
751
|
}
|
|
752
752
|
|
|
753
|
-
return true
|
|
754
|
-
}
|
|
753
|
+
return true
|
|
754
|
+
}
|
|
755
755
|
|
|
756
|
-
export const deepContains = (obj1, obj2, ignoredKeys = [
|
|
757
|
-
if (obj1 === obj2) return true
|
|
758
|
-
if (!isObjectLike(obj1) || !isObjectLike(obj2)) return false
|
|
759
|
-
if (isDOMNode(obj1) || isDOMNode(obj2)) return obj1 === obj2
|
|
756
|
+
export const deepContains = (obj1, obj2, ignoredKeys = ['node', '__ref']) => {
|
|
757
|
+
if (obj1 === obj2) return true
|
|
758
|
+
if (!isObjectLike(obj1) || !isObjectLike(obj2)) return false
|
|
759
|
+
if (isDOMNode(obj1) || isDOMNode(obj2)) return obj1 === obj2
|
|
760
760
|
|
|
761
|
-
const stack = [[obj1, obj2]]
|
|
762
|
-
const visited = new WeakSet()
|
|
761
|
+
const stack = [[obj1, obj2]]
|
|
762
|
+
const visited = new WeakSet()
|
|
763
763
|
|
|
764
764
|
while (stack.length > 0) {
|
|
765
|
-
const [current1, current2] = stack.pop()
|
|
765
|
+
const [current1, current2] = stack.pop()
|
|
766
766
|
|
|
767
|
-
if (visited.has(current1)) continue
|
|
768
|
-
visited.add(current1)
|
|
767
|
+
if (visited.has(current1)) continue
|
|
768
|
+
visited.add(current1)
|
|
769
769
|
|
|
770
770
|
const keys1 = Object.keys(current1).filter(
|
|
771
771
|
(key) => !ignoredKeys.includes(key)
|
|
772
|
-
)
|
|
772
|
+
)
|
|
773
773
|
const keys2 = Object.keys(current2).filter(
|
|
774
774
|
(key) => !ignoredKeys.includes(key)
|
|
775
|
-
)
|
|
775
|
+
)
|
|
776
776
|
|
|
777
|
-
if (keys1.length !== keys2.length) return false
|
|
777
|
+
if (keys1.length !== keys2.length) return false
|
|
778
778
|
|
|
779
779
|
for (const key of keys1) {
|
|
780
|
-
if (!Object.prototype.hasOwnProperty.call(current2, key)) return false
|
|
780
|
+
if (!Object.prototype.hasOwnProperty.call(current2, key)) return false
|
|
781
781
|
|
|
782
|
-
const value1 = current1[key]
|
|
783
|
-
const value2 = current2[key]
|
|
782
|
+
const value1 = current1[key]
|
|
783
|
+
const value2 = current2[key]
|
|
784
784
|
|
|
785
785
|
if (isDOMNode(value1) || isDOMNode(value2)) {
|
|
786
|
-
if (value1 !== value2) return false
|
|
786
|
+
if (value1 !== value2) return false
|
|
787
787
|
} else if (isObjectLike(value1) && isObjectLike(value2)) {
|
|
788
788
|
if (value1 !== value2) {
|
|
789
|
-
stack.push([value1, value2])
|
|
789
|
+
stack.push([value1, value2])
|
|
790
790
|
}
|
|
791
791
|
} else if (value1 !== value2) {
|
|
792
|
-
return false
|
|
792
|
+
return false
|
|
793
793
|
}
|
|
794
794
|
}
|
|
795
795
|
}
|
|
796
796
|
|
|
797
|
-
return true
|
|
798
|
-
}
|
|
797
|
+
return true
|
|
798
|
+
}
|
|
799
799
|
|
|
800
800
|
export const removeFromObject = (obj, props) => {
|
|
801
|
-
if (props === undefined || props === null) return obj
|
|
802
|
-
if (is(props)(
|
|
803
|
-
delete obj[props]
|
|
801
|
+
if (props === undefined || props === null) return obj
|
|
802
|
+
if (is(props)('string', 'number')) {
|
|
803
|
+
delete obj[props]
|
|
804
804
|
} else if (isArray(props)) {
|
|
805
|
-
props.forEach((prop) => delete obj[prop])
|
|
805
|
+
props.forEach((prop) => delete obj[prop])
|
|
806
806
|
} else {
|
|
807
807
|
throw new Error(
|
|
808
|
-
|
|
809
|
-
)
|
|
808
|
+
'Invalid input: props must be a string or an array of strings'
|
|
809
|
+
)
|
|
810
810
|
}
|
|
811
|
-
return obj
|
|
812
|
-
}
|
|
811
|
+
return obj
|
|
812
|
+
}
|
|
813
813
|
|
|
814
814
|
export const createObjectWithoutPrototype = (obj) => {
|
|
815
|
-
if (obj === null || typeof obj !==
|
|
816
|
-
return obj
|
|
815
|
+
if (obj === null || typeof obj !== 'object') {
|
|
816
|
+
return obj // Return the value if obj is not an object
|
|
817
817
|
}
|
|
818
818
|
|
|
819
|
-
const newObj = Object.create(null)
|
|
819
|
+
const newObj = Object.create(null) // Create an object without prototype
|
|
820
820
|
|
|
821
821
|
for (const key in obj) {
|
|
822
822
|
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
823
|
-
newObj[key] = createObjectWithoutPrototype(obj[key])
|
|
823
|
+
newObj[key] = createObjectWithoutPrototype(obj[key]) // Recursively copy each property
|
|
824
824
|
}
|
|
825
825
|
}
|
|
826
826
|
|
|
827
|
-
return newObj
|
|
828
|
-
}
|
|
827
|
+
return newObj
|
|
828
|
+
}
|
|
829
829
|
|
|
830
830
|
export const createNestedObject = (arr, lastValue) => {
|
|
831
|
-
const nestedObject = {}
|
|
831
|
+
const nestedObject = {}
|
|
832
832
|
|
|
833
833
|
if (arr.length === 0) {
|
|
834
|
-
return lastValue
|
|
834
|
+
return lastValue
|
|
835
835
|
}
|
|
836
836
|
|
|
837
837
|
arr.reduce((obj, value, index) => {
|
|
838
838
|
if (!obj[value]) {
|
|
839
|
-
obj[value] = {}
|
|
839
|
+
obj[value] = {}
|
|
840
840
|
}
|
|
841
841
|
if (index === arr.length - 1 && lastValue !== undefined) {
|
|
842
|
-
obj[value] = lastValue
|
|
842
|
+
obj[value] = lastValue
|
|
843
843
|
}
|
|
844
|
-
return obj[value]
|
|
845
|
-
}, nestedObject)
|
|
844
|
+
return obj[value]
|
|
845
|
+
}, nestedObject)
|
|
846
846
|
|
|
847
|
-
return nestedObject
|
|
848
|
-
}
|
|
847
|
+
return nestedObject
|
|
848
|
+
}
|
|
849
849
|
|
|
850
850
|
export const removeNestedKeyByPath = (obj, path) => {
|
|
851
851
|
if (!Array.isArray(path)) {
|
|
852
|
-
throw new Error(
|
|
852
|
+
throw new Error('Path must be an array.')
|
|
853
853
|
}
|
|
854
854
|
|
|
855
|
-
let current = obj
|
|
855
|
+
let current = obj
|
|
856
856
|
|
|
857
857
|
for (let i = 0; i < path.length - 1; i++) {
|
|
858
858
|
if (current[path[i]] === undefined) {
|
|
859
|
-
return
|
|
859
|
+
return // Path does not exist, so nothing to remove.
|
|
860
860
|
}
|
|
861
|
-
current = current[path[i]]
|
|
861
|
+
current = current[path[i]]
|
|
862
862
|
}
|
|
863
863
|
|
|
864
|
-
const lastKey = path[path.length - 1]
|
|
864
|
+
const lastKey = path[path.length - 1]
|
|
865
865
|
if (current && Object.hasOwnProperty.call(current, lastKey)) {
|
|
866
|
-
delete current[lastKey]
|
|
866
|
+
delete current[lastKey]
|
|
867
867
|
}
|
|
868
|
-
}
|
|
868
|
+
}
|
|
869
869
|
|
|
870
870
|
export const setInObjectByPath = (obj, path, value) => {
|
|
871
871
|
if (!Array.isArray(path)) {
|
|
872
|
-
throw new Error(
|
|
872
|
+
throw new Error('Path must be an array.')
|
|
873
873
|
}
|
|
874
874
|
|
|
875
|
-
let current = obj
|
|
875
|
+
let current = obj
|
|
876
876
|
|
|
877
877
|
for (let i = 0; i < path.length - 1; i++) {
|
|
878
878
|
// If the current path segment doesn't exist or isn't an object, create it
|
|
879
|
-
if (!current[path[i]] || typeof current[path[i]] !==
|
|
880
|
-
current[path[i]] = {}
|
|
879
|
+
if (!current[path[i]] || typeof current[path[i]] !== 'object') {
|
|
880
|
+
current[path[i]] = {}
|
|
881
881
|
}
|
|
882
|
-
current = current[path[i]]
|
|
882
|
+
current = current[path[i]]
|
|
883
883
|
}
|
|
884
884
|
|
|
885
|
-
const lastKey = path[path.length - 1]
|
|
886
|
-
current[lastKey] = value
|
|
885
|
+
const lastKey = path[path.length - 1]
|
|
886
|
+
current[lastKey] = value
|
|
887
887
|
|
|
888
|
-
return obj
|
|
889
|
-
}
|
|
888
|
+
return obj
|
|
889
|
+
}
|
|
890
890
|
|
|
891
891
|
export const getInObjectByPath = (obj, path) => {
|
|
892
892
|
if (!Array.isArray(path)) {
|
|
893
|
-
throw new Error(
|
|
893
|
+
throw new Error('Path must be an array.')
|
|
894
894
|
}
|
|
895
895
|
|
|
896
|
-
let current = obj
|
|
896
|
+
let current = obj
|
|
897
897
|
|
|
898
898
|
for (let i = 0; i < path.length; i++) {
|
|
899
899
|
if (current === undefined || current === null) {
|
|
900
|
-
return undefined
|
|
900
|
+
return undefined
|
|
901
901
|
}
|
|
902
|
-
current = current[path[i]]
|
|
902
|
+
current = current[path[i]]
|
|
903
903
|
}
|
|
904
904
|
|
|
905
|
-
return current
|
|
906
|
-
}
|
|
905
|
+
return current
|
|
906
|
+
}
|
|
907
907
|
|
|
908
908
|
export const detectInfiniteLoop = (arr) => {
|
|
909
|
-
const maxRepeats =
|
|
910
|
-
let pattern = []
|
|
911
|
-
let repeatCount = 0
|
|
909
|
+
const maxRepeats = 3 // Maximum allowed repetitions
|
|
910
|
+
let pattern = []
|
|
911
|
+
let repeatCount = 0
|
|
912
912
|
|
|
913
913
|
for (let i = 0; i < arr.length; i++) {
|
|
914
914
|
if (pattern.length < 2) {
|
|
915
915
|
// Build the initial pattern with two consecutive elements
|
|
916
|
-
pattern.push(arr[i])
|
|
916
|
+
pattern.push(arr[i])
|
|
917
917
|
} else {
|
|
918
918
|
// Check if the current element follows the repeating pattern
|
|
919
919
|
if (arr[i] === pattern[i % 2]) {
|
|
920
|
-
repeatCount
|
|
920
|
+
repeatCount++
|
|
921
921
|
} else {
|
|
922
922
|
// If there's a mismatch, reset the pattern and repeat counter
|
|
923
|
-
pattern = [arr[i - 1], arr[i]]
|
|
924
|
-
repeatCount = 1
|
|
923
|
+
pattern = [arr[i - 1], arr[i]]
|
|
924
|
+
repeatCount = 1 // Reset to 1 because we start a new potential pattern
|
|
925
925
|
}
|
|
926
926
|
|
|
927
927
|
// If the pattern repeats more than `maxRepeats`, throw a warning
|
|
928
928
|
if (repeatCount >= maxRepeats * 2) {
|
|
929
929
|
if (isNotProduction()) {
|
|
930
930
|
console.warn(
|
|
931
|
-
|
|
931
|
+
'Warning: Potential infinite loop detected due to repeated sequence:',
|
|
932
932
|
pattern
|
|
933
|
-
)
|
|
933
|
+
)
|
|
934
934
|
}
|
|
935
|
-
return true
|
|
935
|
+
return true
|
|
936
936
|
}
|
|
937
937
|
}
|
|
938
938
|
}
|
|
939
|
-
}
|
|
939
|
+
}
|
|
940
940
|
|
|
941
941
|
export const isCyclic = (obj) => {
|
|
942
|
-
const seenObjects = []
|
|
942
|
+
const seenObjects = []
|
|
943
943
|
|
|
944
944
|
function detect(obj) {
|
|
945
|
-
if (obj && typeof obj ===
|
|
945
|
+
if (obj && typeof obj === 'object') {
|
|
946
946
|
if (seenObjects.indexOf(obj) !== -1) {
|
|
947
|
-
return true
|
|
947
|
+
return true
|
|
948
948
|
}
|
|
949
|
-
seenObjects.push(obj)
|
|
949
|
+
seenObjects.push(obj)
|
|
950
950
|
for (const key in obj) {
|
|
951
951
|
if (Object.hasOwnProperty.call(obj, key) && detect(obj[key])) {
|
|
952
|
-
console.log(obj,
|
|
953
|
-
return true
|
|
952
|
+
console.log(obj, 'cycle at ' + key)
|
|
953
|
+
return true
|
|
954
954
|
}
|
|
955
955
|
}
|
|
956
956
|
}
|
|
957
|
-
return false
|
|
957
|
+
return false
|
|
958
958
|
}
|
|
959
959
|
|
|
960
|
-
return detect(obj)
|
|
961
|
-
}
|
|
960
|
+
return detect(obj)
|
|
961
|
+
}
|
|
962
962
|
|
|
963
963
|
export const excludeKeysFromObject = (obj, excludedKeys) => {
|
|
964
|
-
const result = { ...obj }
|
|
965
|
-
excludedKeys.forEach((key) => delete result[key])
|
|
966
|
-
return result
|
|
967
|
-
}
|
|
964
|
+
const result = { ...obj }
|
|
965
|
+
excludedKeys.forEach((key) => delete result[key])
|
|
966
|
+
return result
|
|
967
|
+
}
|