@peter.naydenov/walk-async 1.0.3 → 1.2.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,5 +1,17 @@
1
1
  # Release History
2
2
 
3
+
4
+
5
+ ### 1.2.0 ( 2023-09-18)
6
+ - [x] HTML DOM nodes - copy by reference;
7
+
8
+
9
+
10
+ ### 1.1.0 ( 2022-11-23)
11
+ - [x] Resolving with `Null` and `undefined` from callback functions will be treated as value;
12
+
13
+
14
+
3
15
  ### 1.0.1 ( 2022-09-19)
4
16
  - [x] Fix: Deep copy process is losing object properties that are equal to 'null';
5
17
 
package/README.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # Walk-async (@peter.naydenov/walk-async)
2
2
 
3
+ ![version](https://img.shields.io/github/package-json/v/peterNaydenov/walk-async)
4
+ ![license](https://img.shields.io/github/license/peterNaydenov/walk-async)
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
@@ -24,9 +27,24 @@ It is very simular to [`@peter.naydenov/walk`](https://github.com/PeterNaydenov/
24
27
  - `walk` can not execute another walk call inside callback functions;
25
28
 
26
29
 
30
+ Data structure values must be one of the following data types:
31
+ - string;
32
+ - number;
33
+ - bigint;
34
+ - boolean;
35
+ - symbol;
36
+ - null;
37
+ - undefined;
38
+ - array;
39
+ - object(data only);
40
+ - function;
41
+
42
+ Other data types can compromise the results;
43
+
44
+
27
45
 
28
46
  ## к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).
47
+ 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
48
 
31
49
  ```js
32
50
  function keyCallbackFn ({ value, key, breadcrumbs, resolve, reject }) {
@@ -155,7 +173,7 @@ let x = {
155
173
  };
156
174
  function keyFn ({value,key,resolve,reject}) {
157
175
  if ( key === 'name' ) reject ()
158
- else resolve ( value )
176
+ else resolve ( value )
159
177
  }
160
178
 
161
179
  walk ({
package/package.json CHANGED
@@ -1,12 +1,11 @@
1
1
  {
2
2
  "name": "@peter.naydenov/walk-async",
3
- "version": "1.0.3",
3
+ "version": "1.2.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.20.2",
22
- "@babel/preset-env": "^7.20.2",
23
- "babel-loader": "^9.1.0",
24
- "chai": "^4.3.7",
25
- "mocha": "^10.1.0",
26
- "nyc": "^15.1.0",
27
- "webpack": "^5.75.0",
28
- "webpack-cli": "^4.10.0"
20
+ "chai": "^4.3.8",
21
+ "mocha": "^10.2.0",
22
+ "nyc": "^15.1.0"
29
23
  },
30
24
  "nyc": {
31
25
  "include": [
package/src/main.js CHANGED
@@ -62,11 +62,11 @@ async function goNext ( extend, result, end ) {
62
62
 
63
63
 
64
64
  function findType ( x ) {
65
- if ( x == null ) return 'simple'
66
- if ( typeof x === 'boolean' ) return 'simple'
65
+ if ( x == null ) return 'simple' // null and undefined
66
+ if ( x.nodeType ) return 'simple' // DOM node
67
67
  if ( x instanceof Array ) return 'array'
68
68
  if ( typeof x === 'object' ) return 'object'
69
- return 'simple'
69
+ return 'simple' // number, bigint, string, boolean, symbol, function
70
70
  } // findType func.
71
71
 
72
72
 
@@ -104,12 +104,13 @@ function copyObject ( origin, result, extend, cb, breadcrumbs ) {
104
104
  , finishWithCallbacks = askForPromise ()
105
105
  , resultIsArray = (findType (result) === 'array')
106
106
  , keyNumber = !isNaN ( k )
107
+ , IGNORE = Symbol ( 'ignore___' )
107
108
  ;
108
109
 
109
110
  if ( hasObjectCallback ) {
110
111
  objectCallback ({
111
112
  resolve : objectCallbackTask.done
112
- , reject : () => objectCallbackTask.done ( null )
113
+ , reject : () => objectCallbackTask.done ( IGNORE )
113
114
  , value : item
114
115
  , key : k
115
116
  , breadcrumbs : `${breadcrumbs}/${k}`
@@ -128,8 +129,8 @@ function copyObject ( origin, result, extend, cb, breadcrumbs ) {
128
129
  item = res
129
130
  type = findType ( item )
130
131
  }
131
- if ( item == null ) {
132
- executeCallback[i].done ()
132
+ if ( item == IGNORE ) {
133
+ executeCallback[i].done ( 'ignore object' )
133
134
  return
134
135
  }
135
136
  if ( type === 'simple' ) {
@@ -139,7 +140,7 @@ function copyObject ( origin, result, extend, cb, breadcrumbs ) {
139
140
  }
140
141
  keyCallback ({
141
142
  resolve : keyCallbackTask.done
142
- , reject : () => keyCallbackTask.done ( null )
143
+ , reject : () => keyCallbackTask.done ( IGNORE )
143
144
  , value : item
144
145
  , key : k
145
146
  , breadcrumbs : `${breadcrumbs}/${k}`
@@ -151,8 +152,8 @@ function copyObject ( origin, result, extend, cb, breadcrumbs ) {
151
152
  }) // objectCallbackTask complete
152
153
 
153
154
  keyCallbackTask.onComplete ( value => {
154
- if ( value == null ) {
155
- executeCallback[i].done ( 'nulls' )
155
+ if ( value == IGNORE ) {
156
+ executeCallback[i].done ( 'ignore key' )
156
157
  return
157
158
  }
158
159
  if ( value === '$$cancel' ) {
@@ -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
 
@@ -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 l,s=new Promise(((n,o)=>{l=setTimeout((()=>{n(r),Promise.resolve(t)}),e)}));return t.then((()=>clearTimeout(l))),n.onComplete=o(Promise.race([t,s])),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 l(e){return null==e||"boolean"==typeof e?"simple":e instanceof Array?"array":"object"==typeof e?"object":"simple"}async function*s(e,n,o,t,r){yield await a(e,n,o,t,r)}function a(e,n,o,r,a){let[i,c]=r,u=Object.keys(e),p=t(u),m=t();return u.forEach(((u,m)=>{let f=l(e[u]),d=e[u],$="simple"!==f&&null!=c,y=t(),b=t(),v=t(),h="array"===l(n),k=!isNaN(u);$?c({resolve:y.done,reject:()=>y.done(null),value:d,key:u,breadcrumbs:`${a}/${u}`}):y.done("$$cancel"),y.onComplete((e=>{if("$$cancel"!==e||null!=d)if("$$cancel"!==e&&(d=e,f=l(d)),null!=d)if("simple"===f){if(!i)return void b.done("$$noUpdates");i({resolve:b.done,reject:()=>b.done(null),value:d,key:u,breadcrumbs:`${a}/${u}`})}else b.done("$$cancel");else p[m].done();else b.done("$$noUpdates")})),b.onComplete((e=>{if(null!=e)if("$$cancel"!==e){if("$$noUpdates"!==e&&(d=e,f=l(d)),"simple"===f){const e=function(e,n){return n instanceof Array&&!isNaN(e)}(u,n);return e?n.push(d):n[u]=d,void p[m].done("key")}v.done()}else v.done();else p[m].done("nulls")})),v.onComplete((()=>{if("object"===f){const e={};h&&k?n.push(e):n[u]=e,o.push(s(d,e,o,r,`${a}/${u}`)),p[m].done("object")}if("array"===f){const e=[];h&&k?n.push(e):n[u]=e,o.push(s(d,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:s=null,keyCallback:i=null}=e,c=l(o),u=[],p="root",m=[i,s],f=t();switch(c){case"array":n=[],a(o,n,u,m,p).then((()=>r(u,n,f)));break;case"object":n={},a(o,n,u,m,p).then((()=>{r(u,n,f)}));break;case"simple":f.done(o)}return f.promise}}},n={},o=function o(t){var r=n[t];if(void 0!==r)return r.exports;var l=n[t]={exports:{}};return e[t](l,l.exports,o),l.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
- }