@peter.naydenov/walk-async 3.0.5 → 3.0.7

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.
Files changed (3) hide show
  1. package/Changelog.md +11 -0
  2. package/package.json +8 -5
  3. package/src/main.js +51 -29
package/Changelog.md CHANGED
@@ -2,6 +2,17 @@
2
2
 
3
3
 
4
4
 
5
+ ### 3.0.7 (2026-07-07)
6
+ - [x] Fix: 'objectCallback' resolving the root object with a primitive value was crashing on null/undefined or producing broken results;
7
+ - [x] Fix: Own '__proto__' property was replacing the prototype of the copy instead of being copied as a regular property;
8
+
9
+
10
+
11
+ ### 3.0.6 (2026-07-07)
12
+ - [x] Fix: Top-level property named 'root' was flattened into the result or dropped;
13
+
14
+
15
+
5
16
  ### 3.0.5 (2026-05-05)
6
17
  - [x] Dependencies updates. Ask-for-promise to version 3.1.1;
7
18
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@peter.naydenov/walk-async",
3
- "version": "3.0.5",
3
+ "version": "3.0.7",
4
4
  "description": "Deep copy with fine control during the process. Can be used also as a deep forEach function",
5
5
  "main": ".dist/walk-async.umd.js",
6
6
  "type": "module",
@@ -31,13 +31,13 @@
31
31
  "ask-for-promise": "^3.1.1"
32
32
  },
33
33
  "devDependencies": {
34
- "@rollup/plugin-commonjs": "^29.0.2",
34
+ "@rollup/plugin-commonjs": "^29.0.3",
35
35
  "@rollup/plugin-node-resolve": "^16.0.3",
36
36
  "@rollup/plugin-terser": "^1.0.0",
37
37
  "c8": "^11.0.0",
38
38
  "chai": "^6.2.2",
39
- "mocha": "^11.7.5",
40
- "rollup": "^4.60.3",
39
+ "mocha": "^11.7.6",
40
+ "rollup": "^4.62.2",
41
41
  "typescript": "^6.0.3"
42
42
  },
43
43
  "overrides": {
@@ -58,5 +58,8 @@
58
58
  "text-summary"
59
59
  ]
60
60
  },
61
- "browserslist": "> 2%, not dead"
61
+ "browserslist": "> 2%, not dead",
62
+ "allowScripts": {
63
+ "fsevents@2.3.3": true
64
+ }
62
65
  }
package/src/main.js CHANGED
@@ -43,31 +43,50 @@ function walk ({
43
43
  , objectCallback = null
44
44
  , keyCallback = null
45
45
  }, ...args ) {
46
- let
46
+ let
47
47
  type = findType ( origin )
48
48
  , result
49
49
  , extend = []
50
50
  , breadcrumbs = 'root'
51
51
  , cb = [ keyCallback, objectCallback ]
52
52
  , end = askForPromise ()
53
+ , rootTask = askForPromise ()
54
+ , IGNORE = Symbol ( 'ignore___' )
53
55
  ;
54
56
 
55
- switch ( type ) {
56
- case 'array' :
57
- result = []
58
- copyObject ( {root:origin}, result, extend, cb, breadcrumbs, ...args )
59
- .then ( () => goNext ( extend, result, end ))
60
- break
61
- case 'object' :
62
- result = {}
63
- copyObject ( {root:origin}, result, extend, cb, breadcrumbs, ...args )
64
- .then ( () => {
65
- goNext ( extend, result, end )
66
- })
67
- break
68
- case 'simple' :
69
- end.done ( origin )
70
- } // switch type
57
+ if ( type !== 'simple' && objectCallback ) { // Root object callback. Executed before the result is allocated, so it can replace the root with anything.
58
+ objectCallback ({
59
+ resolve : rootTask.done
60
+ , reject : () => rootTask.done ( IGNORE )
61
+ , value : origin
62
+ , key : 'root'
63
+ , breadcrumbs
64
+ }, ...args )
65
+ }
66
+ else rootTask.done ( origin )
67
+
68
+ rootTask.onComplete ( item => {
69
+ if ( item === IGNORE ) {
70
+ end.done ( ( type === 'array' ) ? [] : {} )
71
+ return
72
+ }
73
+ switch ( findType ( item ) ) {
74
+ case 'array' :
75
+ result = []
76
+ copyObject ( item, result, extend, cb, breadcrumbs, ...args )
77
+ .then ( () => goNext ( extend, result, end ))
78
+ break
79
+ case 'object' :
80
+ result = {}
81
+ copyObject ( item, result, extend, cb, breadcrumbs, ...args )
82
+ .then ( () => {
83
+ goNext ( extend, result, end )
84
+ })
85
+ break
86
+ case 'simple' :
87
+ end.done ( item )
88
+ } // switch type
89
+ })
71
90
  return end.promise
72
91
  } // walk func.
73
92
 
@@ -93,7 +112,7 @@ function findType ( x ) {
93
112
 
94
113
 
95
114
  async function* generateList ( data, location, ex, cb, breadcrumbs, args ) {
96
- yield await copyObject ( data , location, ex, cb, breadcrumbs, ...args )
115
+ yield await copyObject ( data , location, ex, cb, breadcrumbs, ...args )
97
116
  } // generateList func.
98
117
 
99
118
 
@@ -107,6 +126,15 @@ function validateForInsertion ( k, result ) {
107
126
 
108
127
 
109
128
 
129
+ // Plain assignment of a '__proto__' key triggers the inherited setter and
130
+ // replaces the prototype of 'target' instead of creating an own property.
131
+ function setKey ( target, k, value ) {
132
+ if ( k === '__proto__' ) Object.defineProperty ( target, k, { value, enumerable:true, writable:true, configurable:true })
133
+ else target[k] = value
134
+ } // setKey func.
135
+
136
+
137
+
110
138
  function copyObject ( origin, result, extend, cb, breadcrumbs, ...args ) {
111
139
  let
112
140
  [ keyCallback, objectCallback ] = cb
@@ -126,8 +154,7 @@ function copyObject ( origin, result, extend, cb, breadcrumbs, ...args ) {
126
154
  , resultIsArray = (findType (result) === 'array')
127
155
  , keyNumber = !isNaN ( k )
128
156
  , IGNORE = Symbol ( 'ignore___' )
129
- , isRoot = (breadcrumbs === 'root' && k === 'root' )
130
- , br = isRoot ? 'root' : `${breadcrumbs}/${k}`
157
+ , br = `${breadcrumbs}/${k}`
131
158
  ;
132
159
 
133
160
  if ( hasObjectCallback ) {
@@ -175,12 +202,7 @@ function copyObject ( origin, result, extend, cb, breadcrumbs, ...args ) {
175
202
  }) // objectCallbackTask complete
176
203
 
177
204
  keyCallbackTask.onComplete ( value => {
178
- if ( isRoot ) {
179
- extend.push ( generateList ( item, result, extend, cb, 'root', args ) )
180
- executeCallback.promises[i].done ( 'root' )
181
- return
182
- }
183
- if ( value == IGNORE ) {
205
+ if ( value == IGNORE ) {
184
206
  executeCallback.promises[i].done ( 'ignore key' )
185
207
  return
186
208
  }
@@ -195,7 +217,7 @@ function copyObject ( origin, result, extend, cb, breadcrumbs, ...args ) {
195
217
  if ( type === 'simple' ) {
196
218
  const canInsert = validateForInsertion ( k, result )
197
219
  if ( canInsert ) result.push ( item )
198
- else result [k] = item
220
+ else setKey ( result, k, item )
199
221
  executeCallback.promises[i].done ('key')
200
222
  return
201
223
  }
@@ -207,14 +229,14 @@ function copyObject ( origin, result, extend, cb, breadcrumbs, ...args ) {
207
229
  if ( type === 'object' ) {
208
230
  const newObject = {};
209
231
  if ( resultIsArray && keyNumber ) result.push ( newObject )
210
- else result[k] = newObject
232
+ else setKey ( result, k, newObject )
211
233
  extend.push ( generateList( item, newObject, extend, cb, br, args ) )
212
234
  executeCallback.promises[i].done ('object')
213
235
  }
214
236
  if ( type === 'array' ) {
215
237
  const newArray = [];
216
238
  if ( resultIsArray && keyNumber ) result.push ( newArray )
217
- else result[k] = newArray
239
+ else setKey ( result, k, newArray )
218
240
  extend.push ( generateList( item, newArray, extend, cb, br, args ) )
219
241
  executeCallback.promises[i].done ('array')
220
242
  }