@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 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(object or array).
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 resolve ( value )
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.2",
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
- "@babel/core": "^7.19.1",
22
- "@babel/preset-env": "^7.19.1",
23
- "babel-loader": "^8.2.5",
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 instanceof Array ) return 'array'
66
- if ( typeof x === 'object' ) return 'object'
67
- return 'simple'
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 ( null )
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 == null ) {
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 ( null )
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 == null ) {
148
- executeCallback[i].done ( 'nulls' )
154
+ if ( value == IGNORE ) {
155
+ executeCallback[i].done ( 'ignore key' )
149
156
  return
150
157
  }
151
158
  if ( value === '$$cancel' ) {
@@ -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
- }) // it Prevent array empty items 2
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
+
@@ -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
- }