Skip to content

Comments

Add ES2024/ES2025 polyfills with fixes for reduce bug, groupBy prototype safety, and iterator resilience#105

Merged
mattcosta7 merged 3 commits intomainfrom
copilot/fix-iterator-reduce-polyfill-bug
Feb 20, 2026
Merged

Add ES2024/ES2025 polyfills with fixes for reduce bug, groupBy prototype safety, and iterator resilience#105
mattcosta7 merged 3 commits intomainfrom
copilot/fix-iterator-reduce-polyfill-bug

Conversation

Copy link
Contributor

Copilot AI commented Feb 20, 2026

  • Create initial polyfills (Object.groupBy, Map.groupBy, Promise.try, Iterator helpers)
  • Fix getIteratorPrototype() – use Array iterator chain instead of new GeneratorFunction(...) to avoid CSP eval violation
  • Fix iteratorFrom() – box primitives with Object(obj) so strings and other primitive iterables are accepted
  • Expand isPolyfilled() – check all 11 helper methods (filter, take, drop, flatMap, reduce, toArray, forEach, some, every, find, and map), not just map
  • Add Iterator.from('abc') string test
  • All 60 tests pass, lint clean
Original prompt

Create a pull request in github/browser-support to apply recommended improvements to PR #104 ("Add ES2024 and ES2025 polyfills for Safari 17.0 compatibility").

Goals:

  1. Fix potential Iterator.prototype.reduce polyfill bug:

    • In src/iterator-helpers.ts, the overload implementation currently checks if (arguments.length < 2) to determine whether an initialValue was provided.
    • This is incorrect because the function will always receive at least 2 arguments (reducer is always present in a valid call), so reduce(fn) may be treated like reduce(fn, initialValue) and skip the "use first iterator value as accumulator" behavior.
    • Update the logic to correctly detect when initialValue is not passed and implement expected behavior:
      • If initialValue is omitted: take first iterator value as accumulator; throw TypeError for empty iterator.
      • If initialValue is provided (even if undefined is intentionally provided): use it.
  2. Make Object.groupBy polyfill more robust against prototype pollution / inherited keys:

    • In src/object-groupby.ts, result is currently {} and membership checks are performed with key in result.
    • Improve by using a null-prototype object and/or own-property checks so that keys like __proto__ don’t behave unexpectedly.
    • Ensure typing remains reasonable (may require casting) and behavior remains consistent.
  3. Iterator helpers resilience:

    • Consider the case where getIteratorPrototype() returns null.
    • Update apply() behavior so that chaining still works for iterators produced by helpers when possible.
    • At minimum, ensure the polyfill doesn’t silently fail to install helper methods when IteratorPrototype can’t be discovered; document or implement a fallback.
  4. Update/expand tests to cover the fixes:

    • Add/adjust tests in test/iterator-helpers.js to ensure reduce(fn) without an explicit initial value uses the first element as accumulator and uses correct indices.
    • Add a test for reduce(fn, undefined) to ensure passing an explicit initial value works as expected.
    • Add tests in test/object-groupby.js for keys like "__proto__" to verify results are correct and safe.
  5. Keep within repository conventions:

    • Follow existing pattern: each polyfill exports isSupported, isPolyfilled, apply.
    • Keep ESM import style consistent.
    • Run formatting/lint expectations.

Context:

Reference PR:

This pull request was created from Copilot chat.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

…safety, and iterator resilience

Co-authored-by: mattcosta7 <8616962+mattcosta7@users.noreply.github.com>
@mattcosta7 mattcosta7 marked this pull request as ready for review February 20, 2026 18:54
@mattcosta7 mattcosta7 requested a review from a team as a code owner February 20, 2026 18:54
Copilot AI changed the title [WIP] Fix Iterator.prototype.reduce polyfill bug for Safari compatibility Add ES2024/ES2025 polyfills with fixes for reduce bug, groupBy prototype safety, and iterator resilience Feb 20, 2026
Copilot AI requested a review from mattcosta7 February 20, 2026 18:54
alidusha
alidusha previously approved these changes Feb 20, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds ES2024/ES2025 polyfills (Object.groupBy, Map.groupBy, Promise.try, Iterator helpers/Iterator.from) with Safari-compatibility fixes, plus a corresponding test suite, and wires these polyfills into the library’s exported polyfills set.

Changes:

  • Introduces new polyfill modules for Object.groupBy, Map.groupBy, Promise.try, and Iterator helpers (including a reduce initialValue detection fix + chaining fallback).
  • Adds test coverage for the new polyfills, including reduce() edge cases and __proto__ handling for Object.groupBy.
  • Exports/registers the new polyfills in src/index.ts and updates the lockfile.

Reviewed changes

Copilot reviewed 9 out of 10 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/iterator-helpers.ts Implements iterator helper polyfills, Iterator.from, and reduce fix; adds fallback prototype behavior
src/object-groupby.ts Adds Object.groupBy polyfill using null-prototype result + own-property checks
src/map-groupby.ts Adds Map.groupBy polyfill
src/promise-try.ts Adds Promise.try polyfill
src/index.ts Registers new polyfills in the exported polyfills object
test/iterator-helpers.js Adds iterator helper tests, including reduce() edge cases and chaining
test/object-groupby.js Adds Object.groupBy tests including __proto__ safety
test/map-groupby.js Adds Map.groupBy tests
test/promise-try.js Adds Promise.try tests
package-lock.json Lockfile metadata changes (adds "peer": true flags in several entries)
Comments suppressed due to low confidence (1)

src/iterator-helpers.ts:314

  • isSupported() treats globalThis.Iterator as supported only when typeof IteratorConstructor === 'object' and only checks 'from' in IteratorConstructor. If a native Iterator exists as a function/constructor (or from exists but is non-callable), isSupported() can return false/true incorrectly and impact the library-wide isSupported() signal. Consider allowing function-or-object and verifying typeof IteratorConstructor.from === 'function' (similar to other polyfills in this repo).
  const IteratorConstructor = (globalThis as typeof globalThis & {Iterator?: {from?: unknown}}).Iterator
  return (
    IteratorPrototype !== null &&
    'map' in IteratorPrototype &&
    'filter' in IteratorPrototype &&
    'take' in IteratorPrototype &&
    'drop' in IteratorPrototype &&
    'flatMap' in IteratorPrototype &&
    'reduce' in IteratorPrototype &&
    'toArray' in IteratorPrototype &&
    'forEach' in IteratorPrototype &&
    'some' in IteratorPrototype &&
    'every' in IteratorPrototype &&
    'find' in IteratorPrototype &&
    IteratorConstructor !== undefined &&
    typeof IteratorConstructor === 'object' &&
    IteratorConstructor !== null &&
    'from' in IteratorConstructor
  )

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

…ve iterables in iteratorFrom, complete isPolyfilled check, string Iterator.from test

Co-authored-by: mattcosta7 <8616962+mattcosta7@users.noreply.github.com>
@mattcosta7 mattcosta7 merged commit 1c0d573 into main Feb 20, 2026
5 checks passed
@mattcosta7 mattcosta7 deleted the copilot/fix-iterator-reduce-polyfill-bug branch February 20, 2026 19:33
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.

4 participants