Skip to content

refactor(limitAsync): move from array to promise category - #2022

Merged
raon0211 merged 1 commit into
mainfrom
work/limitasync-module-migration-269133
Aug 15, 2026
Merged

raon0211 merged 1 commit into
mainfrom
work/limitasync-module-migration-269133

Conversation

@raon0211

Copy link
Copy Markdown
Collaborator

Summary

limitAsync wraps an async function to limit the number of concurrent executions — it is a Promise utility, not an array utility. This PR moves it to the promise category while keeping backward compatibility.

  • Move src/array/limitAsync.ts (+ spec) to src/promise/limitAsync.ts, importing Semaphore locally.
  • Keep a @deprecated alias exported from es-toolkit/array, pointing users to es-toolkit/promise.
  • Explicitly re-export the canonical symbol from the root entry (src/index.ts); without this, limitAsync would be silently dropped from es-toolkit because both export * from './array' and export * from './promise' would provide the name (ambiguous star exports are excluded).
  • Update internal consumers (mapAsync, forEachAsync, filterAsync, flatMapAsync) to import from ../promise/limitAsync.ts so they don't go through the deprecated alias.
  • Move docs in all 4 languages from reference/array to reference/promise; the sidebar is generated from the directory structure, so the page now appears under Promise Utilities. Import examples updated to es-toolkit/promise.

Note: the old docs URL (/reference/array/limitAsync.html) will 404; no redirect was added.

Verification

  • yarn vitest run: 4622 passed, 4 skipped. (The pre-existing local-only check-dist failure — tsdown unable to import its optional unrun dependency — reproduces on a clean checkout and is unrelated.)
  • tsc --noEmit: clean.
  • ESLint on all touched files: 0 errors.

limitAsync wraps an async function to limit concurrent executions, which
makes it a Promise utility rather than an array utility.

- Move src/array/limitAsync.ts (+ spec) to src/promise
- Keep a deprecated alias exported from es-toolkit/array
- Re-export the canonical symbol explicitly from the root entry so the
  name is not dropped by ambiguous star exports
- Move docs (en/ko/ja/zh_hans) under Promise Utilities
@raon0211
raon0211 requested a review from dayongkr as a code owner August 15, 2026 06:45
@vercel

vercel Bot commented Aug 15, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
es-toolkit Ready Ready Preview Aug 15, 2026 6:50am

Request Review

@raon0211
raon0211 merged commit ad4815b into main Aug 15, 2026
12 checks passed
raon0211 added a commit that referenced this pull request Aug 15, 2026
main moved limitAsync from array to promise (#2022), which renamed its
case ids and un-matched the skip-list entries; the PR merge preview
failed node-check on its placeholder-function examples.
raon0211 added a commit that referenced this pull request Aug 16, 2026
* test: add browser compatibility test suite for Chrome 98+/Safari 15.4+ and downlevel builds

Adds two layers of browser-support verification:

1. Static checks on every PR: eslint-plugin-es-x (ES2022+ syntax/builtins)
   and eslint-plugin-compat (Web APIs) fail the lint if src uses anything
   newer than Chrome 98 / Safari 15.4 — the floor currently set by
   structuredClone, Object.hasOwn, and Array.prototype.findLast.

2. Browser runs on main (tests/browser-compat): every JSDoc @example is
   harvested into a runnable case (1,317 generated + 23 manual, with an
   explicit skip list and a completeness gate over all exports), bundled from
   the built dist, and executed in real browsers:
   - native (no transpile, no polyfills): Chrome 98 + WebKit 15.4
   - vite-polyfill / webpack fixtures: Chrome 80 + WebKit 14.1

   Old WebKit builds were purged from the Playwright CDN, so WebKit lanes run
   inside digest-pinned mcr.microsoft.com/playwright images (v1.22.2 for 15.4,
   v1.9.2 for 14.1); old Chrome comes from chromium-browser-snapshots and runs
   in the same Ubuntu 20.04 containers.

Also adds a Browser Support guide in four languages whose Vite/webpack/polyfill
snippets are file-included from the tested fixtures, and fixes incorrect JSDoc
examples surfaced by running all of them (remove/pull/cloneDeep/cloneDeepWith/
cloneWith/transform/partial/partialRight/rest/curry/memoize/flowRight/
unzipWith/toArray/drop).

* style(docs): fix pre-existing lint errors in FpLazySimulation.vue

Changing eslint.config.mjs makes the CI lint job run over the whole
repository instead of only changed files, which surfaced unbraced if
statements in this component.

* fix(browser-compat): keep old headless Chrome alive with a debugging port

Old-style headless Chrome exits immediately after page load unless a
remote debugging server keeps the process alive, so the harness never
got to POST its results in CI. Also surface in-page console output on
stderr and run the WebKit step even when the Chromium step failed.

* fix(browser-compat): polyfill Array.prototype.at for the downlevel tier

Real Chrome 80 / WebKit 14.1 runs caught compat/nthArg calling
Array.prototype.at (Chrome 92+ / Safari 15.4+), which the minimal
polyfill set was missing. Add core-js/actual/array/at and document the
API in the browser-support table.

* docs: drop browser-support from the sidebar guide items

The page stays reachable at /browser-support; it just isn't listed in
the sidebar.

* Revert "docs: drop browser-support from the sidebar guide items"

This reverts commit cccb81d.

* test: add ES2015 legacy tier (Chrome 51+/Safari 10+, ~99.4% coverage)

Adds a vite-legacy fixture built with @vitejs/plugin-legacy: Babel
transpilation (which, unlike esbuild, rewrites the Unicode-property
regexes used by string utilities) plus usage-based core-js injection.
BigInt has no ES2015 representation, so the bigint category and the few
examples passing BigInt values are excluded from this tier via a
generated bigint-free case variant; everything else runs unchanged.

Chrome 51 predates headless mode, so the CI lane runs it headed under
Xvfb inside the same Ubuntu 20.04 Playwright container. Docs now
describe three support tiers with refreshed coverage numbers.

* fix(browser-compat): run the Chrome 51 lane on the bionic image

Chrome 51 links against libgconf-2.so.4, which Ubuntu 20.04 dropped;
the v1.9.2-bionic Playwright image (Ubuntu 18.04) still ships it.

* fix(browser-compat): install GConf/GTK2 for the Chrome 51 lane

The Playwright images only ship the libraries their own browsers need;
Chrome 51 additionally links against libgconf and GTK2. Point the EOL
bionic apt sources at old-releases and install them before launching,
and print any still-missing shared libraries for future diagnosis.

* fix(browser-compat): keep bionic apt sources on archive.ubuntu.com

Ubuntu 18.04 is in ESM, so its packages are still served from
archive.ubuntu.com — the old-releases rewrite pointed at a mirror that
has no bionic Release files.

* fix(compat): compile the Unicode word pattern lazily

compat's words builds its Unicode-property regex from strings at module
load, which no transpiler can rewrite; on pre-Chrome 64 / Safari 11.1
engines merely importing es-toolkit/compat threw a parse-time
SyntaxError, taking the whole bundle down. Compiling it on first call
confines the requirement to the word-splitting functions themselves,
which the browser-support docs now state (Chrome 64+ / Safari 11.1+ for
compat words/camelCase/kebabCase/lowerCase/snakeCase/startCase/
upperCase; the main-module equivalents use a regex literal that Babel
rewrites). Their cases are excluded from the vite-legacy variant.

* test: update bundle size snapshots

* fix(browser-compat): restore the ES2015-tier AbortController polyfill

The merge from main accidentally reverted b412ae79 (legacy.mjs and its
references); the vite-legacy lane failed with the same four
AbortController cases again.

* fix(browser-compat): treat stray async page errors as warnings

Old engines emit occasional uncaught errors from delayed example
callbacks that cannot be attributed to any case (all 1304 cases passed
in Chrome 51 while one 'Illegal invocation' fired between cases).
Per-case failures remain the gate; page-level errors still fail the run
when the harness never completes.

* docs(browser-compat): update the workflow header for the three-tier matrix

* docs(browser-support): simplify the guide and unify the polyfill file

Restructures all four languages around the simpler ko rewrite: support
table, transpilation setup (Vite / webpack+Babel), a single polyfill
file (now including AbortController), and two caveats (plugin-legacy
for pre-ES2017 browsers, and es-toolkit/bigint requiring native
BigInt). The separate legacy.mjs polyfill entry is merged into
minimal.mjs, which every downlevel fixture now shares.

* docs(browser-support): polish the Korean guide and fix a broken link

Smooths the flow of the Korean text (structure unchanged), fixes the
bare [#anchor] link, removes trailing whitespace that failed the
Prettier CI check, and aligns the polyfill section title across the
four languages.

* test(browser-compat): follow limitAsync's move to the promise category

main moved limitAsync from array to promise (#2022), which renamed its
case ids and un-matched the skip-list entries; the PR merge preview
failed node-check on its placeholder-function examples.

* docs(browser-support): inline bundler config essentials and capitalize Webpack

* docs(browser-support): fix Prettier formatting and use realistic Webpack exclude pattern

* test(browser-compat): cover compat entries and entriesIn aliases

* test(browser-compat): cover deepFreeze whose example intentionally throws

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
gwennlbh pushed a commit to cigaleapp/cigale that referenced this pull request Sep 8, 2026
##### [v1.52.0](https://github.com/toss/es-toolkit/blob/HEAD/CHANGELOG.md#Version-v1520)

Released on August 28th, 2026.

- Added the `es-toolkit/iterator` entrypoint, a lazy iterator module with `chunk`,
  `count`, `dropWhile`, `head`, `iterate`, `partition`, `range`, `scan`,
  `takeWhile`, `uniqBy`, and `zip` (\[[#1815](toss/es-toolkit#1815)]), plus `cartesianProduct` (\[[#2031](toss/es-toolkit#2031)]).
  The same functions are also available from `es-toolkit/fp/iterator`.

- Added `defer` and `deferAsync` to `es-toolkit/util`. (\[[#2032](toss/es-toolkit#2032)])

- Added `flowAsync` to `es-toolkit/fp`, a promise-aware left-to-right composition. (\[[#2033](toss/es-toolkit#2033)])

- Added the `EmptyObject`, `IsEqual`, `JSONValue`, `Primitive`, `SetOptional`,
  `SetRequired`, and `UnknownRecord` types. (\[[#2044](toss/es-toolkit#2044)])

- Fixed `merge` to infer the deep merged return type, and exported the `Merge` type. (\[[#1959](toss/es-toolkit#1959)])

- Fixed `omitBy` and `pickBy` to type numeric callback keys as strings, and
  exported the `ObjectKeys` type. (\[[#2037](toss/es-toolkit#2037)])

- Fixed `attempt` and `attemptAsync` to default their error type parameter to `unknown`. (\[[#2052](toss/es-toolkit#2052)])

The following bring `es-toolkit/compat` closer to Lodash. Behavior for the affected
edge cases now matches Lodash, so results may differ if you relied on the previous output.

- Fixed `compat/debounce` to skip the `maxWait` invocation when both `leading` and
  `trailing` are `false`. (\[[#1678](toss/es-toolkit#1678)])

- Fixed `compat/toString` to convert objects with a custom `valueOf`. (\[[#2034](toss/es-toolkit#2034)])

- Fixed `compat/mergeWith` to assign `null` values in array sources. (\[[#1929](toss/es-toolkit#1929)])

- Fixed `compat/has` and `compat/hasIn` to normalize the `-0` path key. (\[[#2035](toss/es-toolkit#2035)])

- Fixed `compat/differenceWith` and `compat/without` to normalize `-0` to `0`. (\[[#2049](toss/es-toolkit#2049)])

- Fixed `compat/findLastIndex` to convert `fromIndex` to an integer. (\[[#2047](toss/es-toolkit#2047)])

- Fixed `compat/xorWith` to match Lodash when no comparator is given. (\[[#2057](toss/es-toolkit#2057)])

- Covered the new iterator entrypoints in the dist and browser compatibility
  checks. (\[[#2030](toss/es-toolkit#2030)])

- Made the agent skills portable when installed on their own. (\[[#2054](toss/es-toolkit#2054)])

- Fixed documentation typos and the Deno install commands. (\[[#2062](toss/es-toolkit#2062)])
##### [v1.51.0](https://github.com/toss/es-toolkit/blob/HEAD/CHANGELOG.md#Version-v1510)

Released on August 17th, 2026.

- Added the `es-toolkit/bigint` entrypoint: `bigint` counterparts of the math
  functions (`sum`, `sumBy`, `max`, `min`, `maxBy`, `minBy`, `clamp`, `inRange`,
  `median`, `medianBy`, `percentile`, `range`, `rangeRight`), kept separate so
  the `number` implementations stay unchanged. (\[[#1966](toss/es-toolkit#1966)])

- Added `dedent`, which removes common leading whitespace from template strings. (\[[#1679](toss/es-toolkit#1679)])

- Added `deepFreeze` for recursively freezing objects. (\[[#1680](toss/es-toolkit#1680)])

- Added `mapValuesAsync` and `mapKeysAsync`. (\[[#1544](toss/es-toolkit#1544)])

- Added `toPascalCaseKeys`, `toKebabCaseKeys`, and `toConstantCaseKeys`,
  completing the object key casing family. (\[[#1984](toss/es-toolkit#1984)])

- Exported the `ToCamelCaseKeys`, `ToPascalCaseKeys`, `ToSnakeCaseKeys`,
  `ToKebabCaseKeys`, and `ToConstantCaseKeys` types. (\[[#1651](toss/es-toolkit#1651)])

- Added a `preserveArrays` option to `flattenObject`. (\[[#974](toss/es-toolkit#974)])

- Fixed `retry` to pass the last error to the `delay` callback (\[[#1759](toss/es-toolkit#1759)]) and to
  throw the last attempt's error without applying a final delay (\[[#1901](toss/es-toolkit#1901)]).

- Fixed `mergeWith` and `toMerged` to handle mixed array/object types
  consistently with `merge`. (\[[#2026](toss/es-toolkit#2026)])

- Fixed `pullAt` to remove the correct elements with negative indices. (\[[#1613](toss/es-toolkit#1613)])

- Fixed `at`, `pullAt`, `orderBy`, and `sortBy` to accept readonly arrays. (\[[#2016](toss/es-toolkit#2016)])

- Moved `limitAsync` from the array to the promise category. (\[[#2022](toss/es-toolkit#2022)])

- Included the NOTICE file in the published npm and JSR packages. (\[[#2020](toss/es-toolkit#2020)])

The following bring `es-toolkit/compat` closer to Lodash. Behavior for the affected
edge cases now matches Lodash, so results may differ if you relied on the previous output.

- Added `entries` and `entriesIn`. (\[[#1874](toss/es-toolkit#1874)])

- Fixed `compat/isMatch` and `compat/isMatchWith` to handle object source
  patterns against primitive and non-plain-object targets like Lodash. (\[[#1432](toss/es-toolkit#1432)])

- Fixed `compat/set` to block `constructor.prototype` paths, preventing
  prototype pollution. (\[[#1904](toss/es-toolkit#1904)])

- Fixed `compat/find` to respect array-like `length` (\[[#1958](toss/es-toolkit#1958)]) and to convert
  `fromIndex` to an integer (\[[#1961](toss/es-toolkit#1961)]), and `compat/indexOf` to convert
  `fromIndex` to an integer when searching for `NaN` (\[[#1951](toss/es-toolkit#1951)]).

- Fixed `compat/orderBy` to resolve unresolved deep paths and nullish elements
  to `undefined` (\[[#2010](toss/es-toolkit#2010)]), to exclude the `length` property from array-like
  values (\[[#2002](toss/es-toolkit#2002)]), and to read the criterion property from primitive values (\[[#1903](toss/es-toolkit#1903)]).

- Fixed `compat/toPath` to split unquoted dotted keys inside brackets. (\[[#1899](toss/es-toolkit#1899)])

- Fixed `compat/omit` to treat a key array as a single deep path. (\[[#1902](toss/es-toolkit#1902)])

- Fixed `compat/map` to make the iteratee optional with an identity default. (\[[#1928](toss/es-toolkit#1928)])

- Fixed `compat/size` to count combined Unicode symbols as single characters. (\[[#1900](toss/es-toolkit#1900)])

- Fixed `compat/intersectionBy` to support number, object, and nullish iteratee
  shorthands (\[[#1993](toss/es-toolkit#1993)]), and `compat/intersectionWith` to apply the comparator
  when deduplicating the first array (\[[#1953](toss/es-toolkit#1953)]).

- Fixed `compat/difference`, `compat/differenceBy`, `compat/uniqBy`, and
  `compat/unionBy` to normalize `-0` to `0`. (\[[#2007](toss/es-toolkit#2007)])

- Fixed `compat/maxBy` and `compat/minBy` to skip nullish iteratee values (\[[#1927](toss/es-toolkit#1927)]),
  and `compat/meanBy` to skip `undefined` values when averaging (\[[#1978](toss/es-toolkit#1978)]).

- Fixed `compat/some`, `compat/template` (\[[#2009](toss/es-toolkit#2009)]), and `compat/fill` (\[[#1952](toss/es-toolkit#1952)])
  to gate guard handling with `isIterateeCall`.

- Fixed `compat/iteratee` to treat a boolean as a property shorthand. (\[[#1941](toss/es-toolkit#1941)])

- Fixed `compat/reverse` to support array-like objects and `arguments`. (\[[#2008](toss/es-toolkit#2008)])

- Fixed `compat/toArray` to convert non-array-like iterables. (\[[#1999](toss/es-toolkit#1999)])

- Fixed `compat/toString` to render nested nullish values like Lodash. (\[[#1992](toss/es-toolkit#1992)])

- Fixed `compat/zipObject` to treat `null` keys and values as empty arrays. (\[[#2005](toss/es-toolkit#2005)])

- Fixed `compat/sampleSize` to clamp the default size to the collection length. (\[[#2003](toss/es-toolkit#2003)])

- Fixed `compat/takeWhile`, `compat/takeRightWhile`, and `compat/uniqBy` to
  support string inputs. (\[[#2004](toss/es-toolkit#2004)])

- Fixed `compat/chunk` to return an empty array for an empty collection with an
  `Infinity` size. (\[[#1995](toss/es-toolkit#1995)])

- Fixed `compat/lastIndexOf` to read holes in sparse arrays as `undefined`. (\[[#1977](toss/es-toolkit#1977)])

- Fixed `compat/last` to return `undefined` for empty array-like inputs. (\[[#1954](toss/es-toolkit#1954)])

- Fixed `compat/pullAll` to return the array as-is when `values` is nullish. (\[[#1962](toss/es-toolkit#1962)])

- Added a browser compatibility test suite. (\[[#2012](toss/es-toolkit#2012)])

- Improved documentation, JSDoc accuracy, tests, and internal refactoring across
  `compat` and the docs site. (\[[#1622](toss/es-toolkit#1622)], \[[#1789](toss/es-toolkit#1789)], \[[#1824](toss/es-toolkit#1824)], \[[#1844](toss/es-toolkit#1844)], \[[#1849](toss/es-toolkit#1849)],
  \[[#1854](toss/es-toolkit#1854)], \[[#1855](toss/es-toolkit#1855)], \[[#1859](toss/es-toolkit#1859)], \[[#1860](toss/es-toolkit#1860)], \[[#1868](toss/es-toolkit#1868)], \[[#1871](toss/es-toolkit#1871)], \[[#1887](toss/es-toolkit#1887)], \[[#1898](toss/es-toolkit#1898)],
  \[[#1933](toss/es-toolkit#1933)], \[[#1939](toss/es-toolkit#1939)], \[[#1947](toss/es-toolkit#1947)], \[[#1950](toss/es-toolkit#1950)], \[[#1955](toss/es-toolkit#1955)], \[[#1956](toss/es-toolkit#1956)], \[[#1957](toss/es-toolkit#1957)], \[[#1960](toss/es-toolkit#1960)],
  \[[#1963](toss/es-toolkit#1963)], \[[#1964](toss/es-toolkit#1964)], \[[#1968](toss/es-toolkit#1968)], \[[#1969](toss/es-toolkit#1969)], \[[#1970](toss/es-toolkit#1970)], \[[#1972](toss/es-toolkit#1972)], \[[#1979](toss/es-toolkit#1979)], \[[#1985](toss/es-toolkit#1985)],
  \[[#2000](toss/es-toolkit#2000)], \[[#2001](toss/es-toolkit#2001)], \[[#2021](toss/es-toolkit#2021)], \[[#2025](toss/es-toolkit#2025)], \[[#2027](toss/es-toolkit#2027)])

We sincerely thank [@Antoliny0919](https://github.com/Antoliny0919), [@D-Sketon](https://github.com/D-Sketon), [@kojesung](https://github.com/kojesung), [@chuenchen309](https://github.com/chuenchen309),
[@mariazuheros](https://github.com/mariazuheros), [@DongEun02](https://github.com/DongEun02), [@raon0211](https://github.com/raon0211), [@sukvvon](https://github.com/sukvvon), [@racgoo](https://github.com/racgoo), [@dayongkr](https://github.com/dayongkr), [@Kropiunig](https://github.com/Kropiunig),
[@ssi02014](https://github.com/ssi02014), [@sarathfrancis90](https://github.com/sarathfrancis90), [@mym0404](https://github.com/mym0404), [@mlnwns](https://github.com/mlnwns), [@kdelay](https://github.com/kdelay), [@gwagjiug](https://github.com/gwagjiug), [@dohwi](https://github.com/dohwi),
[@blro0319](https://github.com/blro0319), [@benedictleejh](https://github.com/benedictleejh), [@amir-rezaei](https://github.com/amir-rezaei), [@ianzone](https://github.com/ianzone), [@sen2y](https://github.com/sen2y), [@rossyman](https://github.com/rossyman),
[@eunwoo-levi](https://github.com/eunwoo-levi), [@ramong26](https://github.com/ramong26), [@Gdm0714](https://github.com/Gdm0714), and everyone else who contributed.
We appreciate your great efforts!

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

This branch was successfully deployed

1 active deployment
Preview — a71fb95a Deployed Aug 15, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant