@peter.naydenov/walk-async 1.0.2 → 1.1.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 +13 -0
- package/README.md +17 -2
- package/package.json +5 -11
- package/src/main.js +16 -9
- package/test/01-deepCopy.test.js +10 -0
- package/test/02-keyCallback.test.js +77 -0
- package/test/03-objectCallback.test.js +55 -1
- package/test/05-bothCallbacks.test.js +56 -0
- package/dist/walk-async.min.js +0 -1
- package/webpack.config.js +0 -26
package/Changelog.md
CHANGED
|
@@ -1,7 +1,20 @@
|
|
|
1
1
|
# Release History
|
|
2
2
|
|
|
3
|
+
|
|
4
|
+
### 1.1.0 ( 2022-11-23)
|
|
5
|
+
- [x] Resolving with `Null` and `undefined` from callback functions will be treated as value;
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### 1.0.1 ( 2022-09-19)
|
|
9
|
+
- [x] Fix: Deep copy process is losing object properties that are equal to 'null';
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
3
13
|
### 1.0.1 ( 2022-09-19)
|
|
4
14
|
- [x] Fix: Deep copy is not working.
|
|
15
|
+
- [ ] Bug: Deep copy process is losing object properties that are equal to 'null';
|
|
16
|
+
|
|
17
|
+
|
|
5
18
|
|
|
6
19
|
### 1.0.0 (2022-09-18)
|
|
7
20
|
- [x] Initial code;
|
package/README.md
CHANGED
|
@@ -24,9 +24,24 @@ It is very simular to [`@peter.naydenov/walk`](https://github.com/PeterNaydenov/
|
|
|
24
24
|
- `walk` can not execute another walk call inside callback functions;
|
|
25
25
|
|
|
26
26
|
|
|
27
|
+
Data structure values must be one of the following data types:
|
|
28
|
+
- string;
|
|
29
|
+
- number;
|
|
30
|
+
- bigint;
|
|
31
|
+
- boolean;
|
|
32
|
+
- symbol;
|
|
33
|
+
- null;
|
|
34
|
+
- undefined;
|
|
35
|
+
- array;
|
|
36
|
+
- object(data only);
|
|
37
|
+
- function;
|
|
38
|
+
|
|
39
|
+
Other data types can compromise the results;
|
|
40
|
+
|
|
41
|
+
|
|
27
42
|
|
|
28
43
|
## кeyCallback
|
|
29
|
-
Function **keyCallback** of the `walk-async` could be used also as a deep '**forEach**' method no matter of the type of the object(
|
|
44
|
+
Function **keyCallback** of the `walk-async` could be used also as a deep '**forEach**' method no matter of the type of the object(objects, array or mixed).
|
|
30
45
|
|
|
31
46
|
```js
|
|
32
47
|
function keyCallbackFn ({ value, key, breadcrumbs, resolve, reject }) {
|
|
@@ -155,7 +170,7 @@ let x = {
|
|
|
155
170
|
};
|
|
156
171
|
function keyFn ({value,key,resolve,reject}) {
|
|
157
172
|
if ( key === 'name' ) reject ()
|
|
158
|
-
else
|
|
173
|
+
else resolve ( value )
|
|
159
174
|
}
|
|
160
175
|
|
|
161
176
|
walk ({
|
package/package.json
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@peter.naydenov/walk-async",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.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": {
|
|
7
7
|
"test": "mocha test",
|
|
8
|
-
"cover": "nyc mocha test"
|
|
9
|
-
"build": "webpack --config ./webpack.config.js"
|
|
8
|
+
"cover": "nyc mocha test"
|
|
10
9
|
},
|
|
11
10
|
"repository": {
|
|
12
11
|
"type": "git",
|
|
@@ -18,14 +17,9 @@
|
|
|
18
17
|
"ask-for-promise": "1.3.1"
|
|
19
18
|
},
|
|
20
19
|
"devDependencies": {
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"chai": "^4.3.6",
|
|
25
|
-
"mocha": "^10.0.0",
|
|
26
|
-
"nyc": "^15.1.0",
|
|
27
|
-
"webpack": "^5.74.0",
|
|
28
|
-
"webpack-cli": "^4.10.0"
|
|
20
|
+
"chai": "^4.3.7",
|
|
21
|
+
"mocha": "^10.1.0",
|
|
22
|
+
"nyc": "^15.1.0"
|
|
29
23
|
},
|
|
30
24
|
"nyc": {
|
|
31
25
|
"include": [
|
package/src/main.js
CHANGED
|
@@ -62,9 +62,10 @@ async function goNext ( extend, result, end ) {
|
|
|
62
62
|
|
|
63
63
|
|
|
64
64
|
function findType ( x ) {
|
|
65
|
-
if ( x
|
|
66
|
-
if (
|
|
67
|
-
return '
|
|
65
|
+
if ( x == null ) return 'simple' // null and undefined
|
|
66
|
+
if ( x instanceof Array ) return 'array'
|
|
67
|
+
if ( typeof x === 'object' ) return 'object'
|
|
68
|
+
return 'simple' // number, bigint, string, boolean, symbol, function
|
|
68
69
|
} // findType func.
|
|
69
70
|
|
|
70
71
|
|
|
@@ -91,6 +92,7 @@ function copyObject ( origin, result, extend, cb, breadcrumbs ) {
|
|
|
91
92
|
, executeCallback = askForPromise ( keys )
|
|
92
93
|
, finish = askForPromise ()
|
|
93
94
|
;
|
|
95
|
+
|
|
94
96
|
keys.forEach ( (k,i) => {
|
|
95
97
|
let
|
|
96
98
|
type = findType(origin[k])
|
|
@@ -101,12 +103,13 @@ function copyObject ( origin, result, extend, cb, breadcrumbs ) {
|
|
|
101
103
|
, finishWithCallbacks = askForPromise ()
|
|
102
104
|
, resultIsArray = (findType (result) === 'array')
|
|
103
105
|
, keyNumber = !isNaN ( k )
|
|
106
|
+
, IGNORE = Symbol ( 'ignore___' )
|
|
104
107
|
;
|
|
105
108
|
|
|
106
109
|
if ( hasObjectCallback ) {
|
|
107
110
|
objectCallback ({
|
|
108
111
|
resolve : objectCallbackTask.done
|
|
109
|
-
, reject : () => objectCallbackTask.done (
|
|
112
|
+
, reject : () => objectCallbackTask.done ( IGNORE )
|
|
110
113
|
, value : item
|
|
111
114
|
, key : k
|
|
112
115
|
, breadcrumbs : `${breadcrumbs}/${k}`
|
|
@@ -117,12 +120,16 @@ function copyObject ( origin, result, extend, cb, breadcrumbs ) {
|
|
|
117
120
|
}
|
|
118
121
|
|
|
119
122
|
objectCallbackTask.onComplete ( res => {
|
|
123
|
+
if ( res === '$$cancel' && item == null ) { // deep copy, no callbacks
|
|
124
|
+
keyCallbackTask.done ( '$$noUpdates' )
|
|
125
|
+
return
|
|
126
|
+
}
|
|
120
127
|
if ( res !== '$$cancel' ) {
|
|
121
128
|
item = res
|
|
122
129
|
type = findType ( item )
|
|
123
130
|
}
|
|
124
|
-
if ( item ==
|
|
125
|
-
executeCallback[i].done ()
|
|
131
|
+
if ( item == IGNORE ) {
|
|
132
|
+
executeCallback[i].done ( 'ignore object' )
|
|
126
133
|
return
|
|
127
134
|
}
|
|
128
135
|
if ( type === 'simple' ) {
|
|
@@ -132,7 +139,7 @@ function copyObject ( origin, result, extend, cb, breadcrumbs ) {
|
|
|
132
139
|
}
|
|
133
140
|
keyCallback ({
|
|
134
141
|
resolve : keyCallbackTask.done
|
|
135
|
-
, reject : () => keyCallbackTask.done (
|
|
142
|
+
, reject : () => keyCallbackTask.done ( IGNORE )
|
|
136
143
|
, value : item
|
|
137
144
|
, key : k
|
|
138
145
|
, breadcrumbs : `${breadcrumbs}/${k}`
|
|
@@ -144,8 +151,8 @@ function copyObject ( origin, result, extend, cb, breadcrumbs ) {
|
|
|
144
151
|
}) // objectCallbackTask complete
|
|
145
152
|
|
|
146
153
|
keyCallbackTask.onComplete ( value => {
|
|
147
|
-
if ( value ==
|
|
148
|
-
executeCallback[i].done ( '
|
|
154
|
+
if ( value == IGNORE ) {
|
|
155
|
+
executeCallback[i].done ( 'ignore key' )
|
|
149
156
|
return
|
|
150
157
|
}
|
|
151
158
|
if ( value === '$$cancel' ) {
|
package/test/01-deepCopy.test.js
CHANGED
|
@@ -73,6 +73,16 @@ describe ( 'Walk-async -> Deep copy', () => {
|
|
|
73
73
|
expect ( r.props ).to.not.have.property ( 'test' )
|
|
74
74
|
})
|
|
75
75
|
}) // it Copy a mixed structure
|
|
76
|
+
|
|
77
|
+
it ( 'Data property has value "null"', done => {
|
|
78
|
+
// Fix: Deep copy process is losing object properties that are equal to 'null'
|
|
79
|
+
const x = { name : null };
|
|
80
|
+
walk ({data:x}).then ( r => {
|
|
81
|
+
expect ( r ).to.have.property ( 'name' )
|
|
82
|
+
expect ( r.name ).to.be.equal ( null )
|
|
83
|
+
done ()
|
|
84
|
+
})
|
|
85
|
+
}) // it Data property has value null
|
|
76
86
|
|
|
77
87
|
}) // describe
|
|
78
88
|
|
|
@@ -145,6 +145,83 @@ describe ( 'Walk-async -> keyCallback function', () => {
|
|
|
145
145
|
expect ( r.group ).to.be.equal ( 'work' )
|
|
146
146
|
})
|
|
147
147
|
}) // it Properties of the array
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
it ( 'Set a value to NULL', done => {
|
|
152
|
+
let
|
|
153
|
+
x = {
|
|
154
|
+
ls : [ 1,2,3 ]
|
|
155
|
+
, name : 'Peter'
|
|
156
|
+
, props : {
|
|
157
|
+
eyeColor: null // Use callback and return this exact value
|
|
158
|
+
, age : 47
|
|
159
|
+
, height : 176
|
|
160
|
+
, sizes : [12,33,12,21]
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
function checkNull ({ value, resolve }) {
|
|
165
|
+
resolve (value)
|
|
166
|
+
} // checkNull func.
|
|
167
|
+
|
|
168
|
+
walk ({ data:x, keyCallback:checkNull })
|
|
169
|
+
.then ( r => {
|
|
170
|
+
expect ( r.props.eyeColor ).to.be.equal ( null )
|
|
171
|
+
done ()
|
|
172
|
+
})
|
|
173
|
+
}) // it set a value to NULL
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
it ( 'Set a value to undefined', done => {
|
|
178
|
+
let
|
|
179
|
+
x = {
|
|
180
|
+
ls : [ 1,2,3 ]
|
|
181
|
+
, name : 'Peter'
|
|
182
|
+
, props : {
|
|
183
|
+
eyeColor: undefined // Use callback and return this exact value
|
|
184
|
+
, age : 47
|
|
185
|
+
, height : 176
|
|
186
|
+
, sizes : [12,33,12,21]
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
function checkNull ({ value, resolve }) {
|
|
191
|
+
resolve(value)
|
|
192
|
+
} // checkNull func.
|
|
193
|
+
|
|
194
|
+
walk ({ data:x, keyCallback:checkNull })
|
|
195
|
+
.then ( r => {
|
|
196
|
+
expect ( r.props.eyeColor ).to.be.equal ( undefined )
|
|
197
|
+
done ()
|
|
198
|
+
})
|
|
199
|
+
}) // it Set a value to undefined
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
it ( 'Copy a function', done => {
|
|
203
|
+
let
|
|
204
|
+
x = {
|
|
205
|
+
ls : [ 1,2,3 ]
|
|
206
|
+
, name : 'Peter'
|
|
207
|
+
, props : {
|
|
208
|
+
eyeColor: undefined // Use callback and return this exact value
|
|
209
|
+
, age : function age () { return 47 }
|
|
210
|
+
, height : 176
|
|
211
|
+
, sizes : [12,33,12,21]
|
|
212
|
+
}
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
function checkNull ({ value, resolve }) {
|
|
216
|
+
resolve ( value )
|
|
217
|
+
} // checkNull func.
|
|
218
|
+
|
|
219
|
+
walk ({ data:x, keyCallback:checkNull })
|
|
220
|
+
.then ( r => {
|
|
221
|
+
expect ( r.props.age() ).to.be.equal ( 47 )
|
|
222
|
+
done ()
|
|
223
|
+
})
|
|
224
|
+
}) // it Copy a function
|
|
148
225
|
|
|
149
226
|
}) // describe
|
|
150
227
|
|
|
@@ -240,7 +240,61 @@ describe ( 'Walk-async -> objectCallback function', () => {
|
|
|
240
240
|
expect ( r.length ).to.be.equal ( 1 )
|
|
241
241
|
expect ( r[0] ).to.be.equal ( 5 )
|
|
242
242
|
})
|
|
243
|
-
|
|
243
|
+
}) // it Prevent array empty items 2
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
it ( 'Set a object to NULL', done => {
|
|
248
|
+
let
|
|
249
|
+
x = {
|
|
250
|
+
ls : [ 1,2,3 ]
|
|
251
|
+
, name : 'Peter'
|
|
252
|
+
, props : {
|
|
253
|
+
eyeColor: 'blue'
|
|
254
|
+
, age : 47
|
|
255
|
+
, height : 176
|
|
256
|
+
, sizes : [12,33,12,21]
|
|
257
|
+
}
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
function objToNull ({value,key, resolve }) {
|
|
261
|
+
if ( key === 'props' ) resolve ( null )
|
|
262
|
+
else resolve (value)
|
|
263
|
+
} // objToNull func.
|
|
264
|
+
|
|
265
|
+
walk ({ data:x, objectCallback:objToNull })
|
|
266
|
+
.then ( r => {
|
|
267
|
+
expect ( r.props ).to.be.equal ( null )
|
|
268
|
+
done ()
|
|
269
|
+
})
|
|
270
|
+
}) // it Set a object to NULL
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
it ( 'Set a object to undefined', done => {
|
|
275
|
+
let
|
|
276
|
+
x = {
|
|
277
|
+
ls : [ 1,2,3 ]
|
|
278
|
+
, name : 'Peter'
|
|
279
|
+
, props : {
|
|
280
|
+
eyeColor: 'blue'
|
|
281
|
+
, age : 47
|
|
282
|
+
, height : 176
|
|
283
|
+
, sizes : [12,33,12,21]
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
|
|
287
|
+
function objToNull ({value,key, resolve }) {
|
|
288
|
+
if ( key === 'props' ) resolve ( undefined )
|
|
289
|
+
else resolve ( value )
|
|
290
|
+
} // objToNull func.
|
|
291
|
+
|
|
292
|
+
walk ({ data:x, objectCallback:objToNull })
|
|
293
|
+
.then ( r => {
|
|
294
|
+
expect ( r.props ).to.be.equal ( undefined )
|
|
295
|
+
done ()
|
|
296
|
+
})
|
|
297
|
+
}) // it Set a object to undefined
|
|
244
298
|
|
|
245
299
|
|
|
246
300
|
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict"
|
|
2
|
+
|
|
3
|
+
const
|
|
4
|
+
chai = require ( 'chai' )
|
|
5
|
+
, expect = chai.expect
|
|
6
|
+
, walk = require ( '../src/main.js' )
|
|
7
|
+
;
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
describe ( 'Walk-async -> Both callbacks together', () => {
|
|
11
|
+
|
|
12
|
+
it ( 'Modify on object and key callback level', () => {
|
|
13
|
+
let
|
|
14
|
+
x = {
|
|
15
|
+
ls : [ 1,2,3 ]
|
|
16
|
+
, name : 'Peter'
|
|
17
|
+
, props : {
|
|
18
|
+
eyeColor: 'blue'
|
|
19
|
+
, age : 47
|
|
20
|
+
, height : 176
|
|
21
|
+
, sizes : [12,33,12,21]
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
;
|
|
25
|
+
|
|
26
|
+
function keysModifier ({value, key, resolve, reject }) {
|
|
27
|
+
if ( key === 'age') reject () // remove 'age'
|
|
28
|
+
else if ( key=== 'eyeColor' ) resolve ( 'xxx' )
|
|
29
|
+
else resolve ( value )
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function objectModifier ({value, key, resolve }) {
|
|
33
|
+
if ( key === 'props' ) {
|
|
34
|
+
const { sizes, ... others } = value // remove 'sizes'
|
|
35
|
+
resolve ( others )
|
|
36
|
+
}
|
|
37
|
+
else resolve ( value )
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
walk ({
|
|
42
|
+
data : x
|
|
43
|
+
, keyCallback : keysModifier
|
|
44
|
+
, objectCallback : objectModifier
|
|
45
|
+
})
|
|
46
|
+
.then ( r => {
|
|
47
|
+
expect ( r.props ).to.not.have.property ( 'age' )
|
|
48
|
+
expect ( r.props ).to.not.have.property ( 'sizes' )
|
|
49
|
+
expect ( r.props.eyeColor ).to.be.equal ( 'xxx' )
|
|
50
|
+
})
|
|
51
|
+
}) // it Modify on object and key callback level
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
}) // describe
|
|
55
|
+
|
|
56
|
+
|
package/dist/walk-async.min.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var walk;(()=>{var e={406:e=>{"use strict";function n(){let e,n;const t=new Promise(((o,t)=>{e=o,n=t}));return{promise:t,done:e,cancel:n,onComplete:o(t)}}function o(e){return function(n){e.then((e=>n(e)))}}e.exports=function(e){let t,r=!1;return e?(t=function(e){let t=e.map((e=>n())),r=t.map((e=>e.promise));return t.promises=r,t.onComplete=o(Promise.all(r)),t}(e),r=!0):t=n(),t.timeout=function(e,n){let t;return t=e?Promise.all(n.promises):n.promise,function(e,r){let s,l=new Promise(((n,o)=>{s=setTimeout((()=>{n(r),Promise.resolve(t)}),e)}));return t.then((()=>clearTimeout(s))),n.onComplete=o(Promise.race([t,l])),n}}(r,t),t}},880:(e,n,o)=>{const t=o(406);async function r(e,n,o){for await(const n of e)await n.next();o.done(n)}function s(e){return e instanceof Array?"array":"object"==typeof e?"object":"simple"}async function*l(e,n,o,t,r){yield await a(e,n,o,t,r)}function a(e,n,o,r,a){let[c,i]=r,u=Object.keys(e),p=t(u),m=t();return u.forEach(((u,m)=>{let d=s(e[u]),f=e[u],$="simple"!==d&&null!=i,y=t(),b=t(),h=t(),k="array"===s(n),v=!isNaN(u);$?i({resolve:y.done,reject:()=>y.done(null),value:f,key:u,breadcrumbs:`${a}/${u}`}):y.done("$$cancel"),y.onComplete((e=>{"$$cancel"!==e&&(f=e,d=s(f)),null!=f?"simple"===d?(c||b.done("$$noUpdates"),c({resolve:b.done,reject:()=>b.done(null),value:f,key:u,breadcrumbs:`${a}/${u}`})):b.done("$$cancel"):p[m].done()})),b.onComplete((e=>{if(null!=e)if("$$cancel"!==e){if("$$noUpdates"!==e&&(f=e,d=s(f)),"simple"===d){const e=function(e,n){return n instanceof Array&&!isNaN(e)}(u,n);return e?n.push(f):n[u]=f,void p[m].done("key")}h.done()}else h.done();else p[m].done("nulls")})),h.onComplete((()=>{if("object"===d){const e={};k&&v?n.push(e):n[u]=e,o.push(l(f,e,o,r,`${a}/${u}`)),p[m].done("object")}if("array"===d){const e=[];k&&v?n.push(e):n[u]=e,o.push(l(f,e,o,r,`${a}/${u}`)),p[m].done("array")}}))})),p.onComplete((e=>m.done())),m.promise}e.exports=function(e){let n,{data:o,objectCallback:l=null,keyCallback:c=null}=e,i=s(o),u=[],p="root",m=[c,l],d=t();switch(i){case"array":n=[],a(o,n,u,m,p).then((()=>r(u,n,d)));break;case"object":n={},a(o,n,u,m,p).then((()=>{r(u,n,d)}));break;case"simple":d.done(o)}return d.promise}}},n={},o=function o(t){var r=n[t];if(void 0!==r)return r.exports;var s=n[t]={exports:{}};return e[t](s,s.exports,o),s.exports}(880);walk=o})();
|
package/webpack.config.js
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
module.exports = {
|
|
4
|
-
entry: './src/main.js'
|
|
5
|
-
, mode: 'production'
|
|
6
|
-
, output: {
|
|
7
|
-
filename: "walk-async.min.js"
|
|
8
|
-
, path: __dirname + "/dist"
|
|
9
|
-
, library: 'walk'
|
|
10
|
-
, libraryTarget: "var"
|
|
11
|
-
, umdNamedDefine : true
|
|
12
|
-
}
|
|
13
|
-
, optimization: {}
|
|
14
|
-
, module: {
|
|
15
|
-
rules: [
|
|
16
|
-
{
|
|
17
|
-
test: /\.js$/
|
|
18
|
-
, exclude: /node_modules/
|
|
19
|
-
, use : {
|
|
20
|
-
loader: 'babel-loader'
|
|
21
|
-
, options : { presets: ['@babel/preset-env']}
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
]
|
|
25
|
-
}
|
|
26
|
-
}
|