@peter.naydenov/walk-async 1.1.0 → 1.3.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/Changelog.md +14 -0
- package/README.md +3 -0
- package/package.json +3 -3
- package/src/main.js +13 -11
- package/test/01-deepCopy.test.js +29 -0
- package/test/02-keyCallback.test.js +41 -0
package/Changelog.md
CHANGED
|
@@ -1,10 +1,24 @@
|
|
|
1
1
|
# Release History
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
|
|
5
|
+
### 1.3.0 ( 2023-09-23)
|
|
6
|
+
- [x] Provide collection containers to callbacks. Extract data during iteration;
|
|
7
|
+
- [x] Fix: Keys with value 'undefined' are not being copied;
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### 1.2.0 ( 2023-09-18)
|
|
12
|
+
- [x] HTML DOM nodes - copy by reference;
|
|
13
|
+
- [ ] Bug: Keys with value 'undefined' are not being copied;
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
4
17
|
### 1.1.0 ( 2022-11-23)
|
|
5
18
|
- [x] Resolving with `Null` and `undefined` from callback functions will be treated as value;
|
|
6
19
|
|
|
7
20
|
|
|
21
|
+
|
|
8
22
|
### 1.0.1 ( 2022-09-19)
|
|
9
23
|
- [x] Fix: Deep copy process is losing object properties that are equal to 'null';
|
|
10
24
|
|
package/README.md
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# Walk-async (@peter.naydenov/walk-async)
|
|
2
2
|
|
|
3
|
+

|
|
4
|
+

|
|
5
|
+
|
|
3
6
|
Creates an immutable copies of javascript data structures(objects, arrays or mixed). Can execute callback functions on every object property(objectCallback) and/or every primitive property(keyCallback). Callbacks can modify result object during the walk process. Mask, filter or substitute values during the copy process.
|
|
4
7
|
|
|
5
8
|
```js
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@peter.naydenov/walk-async",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "Deep copy with fine control during the process. Can be used also as a deep forEach function",
|
|
5
5
|
"main": "src/main.js",
|
|
6
6
|
"scripts": {
|
|
@@ -17,8 +17,8 @@
|
|
|
17
17
|
"ask-for-promise": "1.3.1"
|
|
18
18
|
},
|
|
19
19
|
"devDependencies": {
|
|
20
|
-
"chai": "^4.3.
|
|
21
|
-
"mocha": "^10.
|
|
20
|
+
"chai": "^4.3.8",
|
|
21
|
+
"mocha": "^10.2.0",
|
|
22
22
|
"nyc": "^15.1.0"
|
|
23
23
|
},
|
|
24
24
|
"nyc": {
|
package/src/main.js
CHANGED
|
@@ -22,7 +22,7 @@ function walk ({
|
|
|
22
22
|
data:origin
|
|
23
23
|
, objectCallback = null
|
|
24
24
|
, keyCallback = null
|
|
25
|
-
}) {
|
|
25
|
+
}, ...args ) {
|
|
26
26
|
let
|
|
27
27
|
type = findType ( origin )
|
|
28
28
|
, result
|
|
@@ -31,15 +31,16 @@ function walk ({
|
|
|
31
31
|
, cb = [ keyCallback, objectCallback ]
|
|
32
32
|
, end = askForPromise ()
|
|
33
33
|
;
|
|
34
|
+
|
|
34
35
|
switch ( type ) {
|
|
35
36
|
case 'array' :
|
|
36
37
|
result = []
|
|
37
|
-
copyObject ( origin, result, extend, cb, breadcrumbs )
|
|
38
|
+
copyObject ( origin, result, extend, cb, breadcrumbs, ...args )
|
|
38
39
|
.then ( () => goNext ( extend, result, end ))
|
|
39
40
|
break
|
|
40
41
|
case 'object' :
|
|
41
42
|
result = {}
|
|
42
|
-
copyObject ( origin, result, extend, cb, breadcrumbs )
|
|
43
|
+
copyObject ( origin, result, extend, cb, breadcrumbs, ...args )
|
|
43
44
|
.then ( () => {
|
|
44
45
|
goNext ( extend, result, end )
|
|
45
46
|
})
|
|
@@ -63,6 +64,7 @@ async function goNext ( extend, result, end ) {
|
|
|
63
64
|
|
|
64
65
|
function findType ( x ) {
|
|
65
66
|
if ( x == null ) return 'simple' // null and undefined
|
|
67
|
+
if ( x.nodeType ) return 'simple' // DOM node
|
|
66
68
|
if ( x instanceof Array ) return 'array'
|
|
67
69
|
if ( typeof x === 'object' ) return 'object'
|
|
68
70
|
return 'simple' // number, bigint, string, boolean, symbol, function
|
|
@@ -70,8 +72,8 @@ function findType ( x ) {
|
|
|
70
72
|
|
|
71
73
|
|
|
72
74
|
|
|
73
|
-
async function* generateList ( data, location, ex, cb, breadcrumbs ) {
|
|
74
|
-
yield await copyObject ( data , location, ex, cb, breadcrumbs )
|
|
75
|
+
async function* generateList ( data, location, ex, cb, breadcrumbs, args ) {
|
|
76
|
+
yield await copyObject ( data , location, ex, cb, breadcrumbs, ...args )
|
|
75
77
|
} // generateList func.
|
|
76
78
|
|
|
77
79
|
|
|
@@ -85,7 +87,7 @@ function validateForInsertion ( k, result ) {
|
|
|
85
87
|
|
|
86
88
|
|
|
87
89
|
|
|
88
|
-
function copyObject ( origin, result, extend, cb, breadcrumbs ) {
|
|
90
|
+
function copyObject ( origin, result, extend, cb, breadcrumbs, ...args ) {
|
|
89
91
|
let
|
|
90
92
|
[ keyCallback, objectCallback ] = cb
|
|
91
93
|
, keys = Object.keys ( origin )
|
|
@@ -113,14 +115,14 @@ function copyObject ( origin, result, extend, cb, breadcrumbs ) {
|
|
|
113
115
|
, value : item
|
|
114
116
|
, key : k
|
|
115
117
|
, breadcrumbs : `${breadcrumbs}/${k}`
|
|
116
|
-
})
|
|
118
|
+
}, ...args )
|
|
117
119
|
}
|
|
118
120
|
else {
|
|
119
121
|
objectCallbackTask.done ( '$$cancel' )
|
|
120
122
|
}
|
|
121
123
|
|
|
122
124
|
objectCallbackTask.onComplete ( res => {
|
|
123
|
-
if ( res === '$$cancel' && item
|
|
125
|
+
if ( res === '$$cancel' && origin.hasOwnProperty(item) ) { // deep copy, no callbacks
|
|
124
126
|
keyCallbackTask.done ( '$$noUpdates' )
|
|
125
127
|
return
|
|
126
128
|
}
|
|
@@ -143,7 +145,7 @@ function copyObject ( origin, result, extend, cb, breadcrumbs ) {
|
|
|
143
145
|
, value : item
|
|
144
146
|
, key : k
|
|
145
147
|
, breadcrumbs : `${breadcrumbs}/${k}`
|
|
146
|
-
});
|
|
148
|
+
}, ...args );
|
|
147
149
|
}
|
|
148
150
|
else {
|
|
149
151
|
keyCallbackTask.done ( '$$cancel' )
|
|
@@ -178,14 +180,14 @@ function copyObject ( origin, result, extend, cb, breadcrumbs ) {
|
|
|
178
180
|
const newObject = {};
|
|
179
181
|
if ( resultIsArray && keyNumber ) result.push ( newObject )
|
|
180
182
|
else result[k] = newObject
|
|
181
|
-
extend.push ( generateList( item, newObject, extend, cb, `${breadcrumbs}/${k}
|
|
183
|
+
extend.push ( generateList( item, newObject, extend, cb, `${breadcrumbs}/${k}`, args ) )
|
|
182
184
|
executeCallback[i].done ('object')
|
|
183
185
|
}
|
|
184
186
|
if ( type === 'array' ) {
|
|
185
187
|
const newArray = [];
|
|
186
188
|
if ( resultIsArray && keyNumber ) result.push ( newArray )
|
|
187
189
|
else result[k] = newArray
|
|
188
|
-
extend.push ( generateList( item, newArray, extend, cb, `${breadcrumbs}/${k}
|
|
190
|
+
extend.push ( generateList( item, newArray, extend, cb, `${breadcrumbs}/${k}`, args ) )
|
|
189
191
|
executeCallback[i].done ('array')
|
|
190
192
|
}
|
|
191
193
|
})
|
package/test/01-deepCopy.test.js
CHANGED
|
@@ -83,6 +83,35 @@ describe ( 'Walk-async -> Deep copy', () => {
|
|
|
83
83
|
done ()
|
|
84
84
|
})
|
|
85
85
|
}) // it Data property has value null
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
it ( 'html nodes - copy by reference', done => {
|
|
90
|
+
const data = {
|
|
91
|
+
name : 'Peter'
|
|
92
|
+
, pretendHTML : { nodeType: 1 }
|
|
93
|
+
};
|
|
94
|
+
walk ({ data })
|
|
95
|
+
.then ( r => {
|
|
96
|
+
r.pretendHTML.something = 'hello'
|
|
97
|
+
expect ( data.pretendHTML.something ).to.be.equal ( 'hello' ) // Recognize html nodes and keep them as a reference
|
|
98
|
+
done ()
|
|
99
|
+
})
|
|
100
|
+
}) // html nodes - copy by reference
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
it ( 'Functions type - copy by reference', () => {
|
|
105
|
+
const data = {
|
|
106
|
+
name : 'Peter'
|
|
107
|
+
, func : () => 12
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
walk ({ data })
|
|
111
|
+
.then ( r => {
|
|
112
|
+
expect ( r.func() ).to.be.equal ( 12 )
|
|
113
|
+
})
|
|
114
|
+
}) // it Functions type - copy by reference
|
|
86
115
|
|
|
87
116
|
}) // describe
|
|
88
117
|
|
|
@@ -222,6 +222,47 @@ describe ( 'Walk-async -> keyCallback function', () => {
|
|
|
222
222
|
done ()
|
|
223
223
|
})
|
|
224
224
|
}) // it Copy a function
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
it ( 'Extract collections', done => {
|
|
229
|
+
let
|
|
230
|
+
x = {
|
|
231
|
+
ls : [ 1,2,3 ]
|
|
232
|
+
, name : 'Peter'
|
|
233
|
+
, props : {
|
|
234
|
+
eyeColor: undefined // Use callback and return this exact value
|
|
235
|
+
, age : function age () { return 47 }
|
|
236
|
+
, height : 176
|
|
237
|
+
, sizes : [12,33,12,21]
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
, fnList = []
|
|
241
|
+
, propsCollection = {}
|
|
242
|
+
;
|
|
243
|
+
|
|
244
|
+
function valueFn ({ key, value, resolve }, fn, p ) {
|
|
245
|
+
const isFn = (typeof value === 'function');
|
|
246
|
+
if ( isFn ) fn.push ( value )
|
|
247
|
+
|
|
248
|
+
if ( ['name','eyeColor', 'age'].includes(key) ) p[key] = isFn ? value() : value
|
|
249
|
+
resolve ( value )
|
|
250
|
+
} // valueFn func.
|
|
251
|
+
|
|
252
|
+
walk ({ data:x, keyCallback:valueFn }, fnList, propsCollection )
|
|
253
|
+
.then ( r => {
|
|
254
|
+
expect ( r.props.age() ).to.be.equal ( 47 )
|
|
255
|
+
expect ( fnList.length ).to.be.equal ( 1 )
|
|
256
|
+
expect ( r.props ).to.have.property ( 'eyeColor' )
|
|
257
|
+
|
|
258
|
+
expect ( propsCollection ).to.have.property ( 'name' )
|
|
259
|
+
expect ( propsCollection ).to.have.property ( 'eyeColor' )
|
|
260
|
+
expect ( propsCollection ).to.have.property ( 'age' )
|
|
261
|
+
expect ( propsCollection.age ).to.be.equal ( 47 )
|
|
262
|
+
|
|
263
|
+
done ()
|
|
264
|
+
})
|
|
265
|
+
}) // it Copy a function
|
|
225
266
|
|
|
226
267
|
}) // describe
|
|
227
268
|
|