radashi-org / radashi

The modern, community-first TypeScript toolkit with all of the fast, readable, and minimal utility functions you need. Type-safe, dependency-free, tree-shakeable, fully tested.
https://radashi.js.org
MIT License
315 stars 25 forks source link

fix(all): be more lenient, reduce memory usage #306

Closed aleclarson closed 2 weeks ago

aleclarson commented 2 weeks ago

[!TIP] The owner of this PR can publish a preview release by commenting /publish in this PR. Afterwards, anyone can try it out by running pnpm add radashi@pr<PR_NUMBER>.

Summary

Make all less strict both at the type level and at runtime, making it closer to Promise.all behavior.

  1. Values are not required to have a then method (e.g. promises and promise-like objects). If no then method exists, the value is used as-is.
  2. I've made the following performance improvements:
    • Avoid heap allocations where possible. Previously, all would create one array per promise when called with an array of promises. In all cases, all would create an additional object upon the resolution of each promise. Upon completion, all would filter the results, which allocated another array, and map the filtered results afterwards, allocating yet another array. For each promise, all would allocate two functions (a then callback and a catch callback).
    • Stop creating an empty object {} and using Array#reduce to populate it. Instead, use spread syntax on the input object, thereby reusing the input object's V8 “hidden class”. Then gradually assign the resolved values to the output object.

Related issue, if any:

For any code change,

Does this PR introduce a breaking change?

No

Bundle impact

Status File Size [^1337] Difference
M src/async/all.ts 559 -66 (-11%)

[^1337]: Function size includes the import dependencies of the function.

radashi-bot commented 2 weeks ago

A stable release 12.2.3 has been published to NPM. :rocket:

To install:

pnpm add radashi@12.2.3

See the changes