( self: unknown[], method: keyof Array<unknown>, wrapValue: (value: any) => unknown, )
| 231 | |
| 232 | // instrument iterators to take ARRAY_ITERATE dependency |
| 233 | function iterator( |
| 234 | self: unknown[], |
| 235 | method: keyof Array<unknown>, |
| 236 | wrapValue: (value: any) => unknown, |
| 237 | ) { |
| 238 | // note that taking ARRAY_ITERATE dependency here is not strictly equivalent |
| 239 | // to calling iterate on the proxied array. |
| 240 | // creating the iterator does not access any array property: |
| 241 | // it is only when .next() is called that length and indexes are accessed. |
| 242 | // pushed to the extreme, an iterator could be created in one effect scope, |
| 243 | // partially iterated in another, then iterated more in yet another. |
| 244 | // given that JS iterator can only be read once, this doesn't seem like |
| 245 | // a plausible use-case, so this tracking simplification seems ok. |
| 246 | const arr = shallowReadArray(self) |
| 247 | const iter = (arr[method] as any)() as IterableIterator<unknown> & { |
| 248 | _next: IterableIterator<unknown>['next'] |
| 249 | } |
| 250 | if (arr !== self && !isShallow(self)) { |
| 251 | iter._next = iter.next |
| 252 | iter.next = () => { |
| 253 | const result = iter._next() |
| 254 | if (!result.done) { |
| 255 | result.value = wrapValue(result.value) |
| 256 | } |
| 257 | return result |
| 258 | } |
| 259 | } |
| 260 | return iter |
| 261 | } |
| 262 | |
| 263 | // in the codebase we enforce es2016, but user code may run in environments |
| 264 | // higher than that |
no test coverage detected