Add polyfills for new Set methods (union, intersection, difference, symmetricDifference, isSubsetOf, isSupersetOf, isDisjointFrom)#110
Conversation
…ce, symmetricDifference, isSubsetOf, isSupersetOf, isDisjointFrom) Co-authored-by: mattcosta7 <8616962+mattcosta7@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Adds an ES2024 Set-methods polyfill module so consumers can safely use the newly-baseline Set APIs (e.g. union, intersection) in browsers like Safari 16.4 that lack native support, and registers it in the library’s aggregated polyfill entrypoint.
Changes:
- Added
src/set-methods.tsimplementingunion,intersection,difference,symmetricDifference,isSubsetOf,isSupersetOf,isDisjointFromplusisSupported()/isPolyfilled()/apply(). - Registered the new polyfill under
polyfillsinsrc/index.ts. - Added
test/set-methods.jswith unit tests for the exported implementations.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| src/set-methods.ts | New polyfill module implementing and installing the ES2024 Set methods. |
| src/index.ts | Registers setMethods in the global polyfills list. |
| test/set-methods.js | Adds tests for the new Set-method implementations. |
Comments suppressed due to low confidence (3)
src/set-methods.ts:101
isSupported()only checks property existence via'name' in Set.prototype, which can return true even if a non-function value is present (or something is inherited). This can causeapply()to be skipped while the methods still aren't callable. Consider also checkingtypeof Set.prototype.union === 'function'(and the rest) like the other polyfills do.
export function isSupported(): boolean {
return (
'union' in Set.prototype &&
'intersection' in Set.prototype &&
'difference' in Set.prototype &&
'symmetricDifference' in Set.prototype &&
'isSubsetOf' in Set.prototype &&
'isSupersetOf' in Set.prototype &&
'isDisjointFrom' in Set.prototype
)
src/set-methods.ts:129
apply()installs all 7 methods whenever any of them are missing. In environments with partial native support, this will overwrite the native implementations (and potentially change behavior/perf). Prefer installing each method only if it's missing (similar toiterator-helpers.ts), so native methods are preserved.
export function apply(): void {
if (!isSupported()) {
Object.assign(Set.prototype, {
union,
intersection,
difference,
symmetricDifference,
isSubsetOf,
isSupersetOf,
isDisjointFrom,
})
test/set-methods.js:23
- Tests currently exercise the exported functions via
.call(...)but don't verifyapply()actually installs the methods onSet.prototype(e.g.,new Set([1]).union(...)) or thatisPolyfilled()becomes true after applying. Adding at least one prototype-level test would cover the primary integration path.
it('has standard isSupported, isPolyfilled, apply API', () => {
expect(isSupported).to.be.a('function')
expect(isPolyfilled).to.be.a('function')
expect(apply).to.be.a('function')
expect(isSupported()).to.be.a('boolean')
expect(isPolyfilled()).to.equal(false)
})
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const proto = Set.prototype as unknown as Record<string, unknown> | ||
| return ( | ||
| 'union' in Set.prototype && | ||
| proto['union'] === union && |
There was a problem hiding this comment.
We are not adding this check: proto['union'] === union && to isSupported. Is that intended?
There was a problem hiding this comment.
yep, I believe that's right, if I understand it correctly?
isSupported supports both polyfilled and not, so it should cover both cases (once the polyfill is applied), while isPolyfilled validates whether the support came from the polyfill applied or by built in support (which I think for us is everything but safari 16 or 17)
There was a problem hiding this comment.
Oh I see, yeah that makes sense!
Safari 16.4 lacks support for the seven newly-baseline
Setmethods available in ES2024/TypeScript'ses2024lib. This adds polyfills so they can be used safely today.Changes
src/set-methods.ts— New polyfill module implementing all seven methods against aSetLike<T>interface (has,keys,size) per TC39 spec, including spec-aligned optimizations (e.g.isSubsetOfshort-circuits whenthis.size > other.size;isDisjointFromiterates the smaller set). Follows the standardisSupported()/isPolyfilled()/apply()pattern.src/index.ts— RegisterssetMethodsalongside existing polyfills.test/set-methods.js— Tests for all seven methods covering common cases and edge cases (empty sets, disjoint sets, identical sets).Usage
Warning
Firewall rules blocked me from connecting to one or more addresses (expand for details)
I tried to connect to the following addresses, but was blocked by firewall rules:
accounts.google.com/proc/self/exe /proc/self/exe --type=utility --utility-sub-type=network.mojom.NetworkService --lang=en-US --service-sandbox-type=none --disable-dev-shm-usage --use-angle=swiftshader-webgl --mute-audio --crashpad-handler-pid=4006 --enable-crash-reporter=, --noerrdialogs --user-data-dir=/tmp/puppeteer_dev_chrome_profile-z0xwaJ --change-stack-guard-on-fork=enable --shared-files=v8_context_snapshot_data:100 --field-trial-handle=3,i,16526546639982034433,11159440813740539228,262144 --enable-features=PdfOopif --disable-features=AcceptCHFrame,IsolateSandboxedIframes,MediaRouter,OptimizationHints,PaintHolding,ProcessPerSiteUpToMainFrameThreshold,Translate --variations-seed-version --trace-process-track-uuid=3190708989122997041(dns block)/opt/google/chrome/chrome /usr/bin/google-chrome-stable --allow-pre-commit-input --disable-REDACTED-networking --disable-REDACTED-timer-throttling --disable-REDACTEDing-occluded-windows --disable-breakpad --disable-client-side-phishing-detection --disable-component-extensions-with-REDACTED-pages --disable-crash-reporter --disable-default-apps --disable-dev-shm-usage --disable-extensions --disable-hang-monitor --disable-infobars --disable-ipc-flooding-protection --disable-popup-blocking --disable-prompt-on-repost --disable-renderer-REDACTEDing --disable-search-engine-choice-screen --disable-sync(dns block)/proc/self/exe /proc/self/exe --type=utility --utility-sub-type=network.mojom.NetworkService --lang=en-US --service-sandbox-type=none --disable-dev-shm-usage --use-angle=swiftshader-webgl --mute-audio --crashpad-handler-pid=4258 --enable-crash-reporter=, --noerrdialogs --user-data-dir=/tmp/puppeteer_dev_chrome_profile-IkdZcd --change-stack-guard-on-fork=enable --shared-files=v8_context_snapshot_data:100 --field-trial-handle=3,i,4382833278840495840,8209209942178505960,262144 --enable-features=PdfOopif --disable-features=AcceptCHFrame,IsolateSandboxedIframes,MediaRouter,OptimizationHints,PaintHolding,ProcessPerSiteUpToMainFrameThreshold,Translate --variations-seed-version --trace-process-track-uuid=3190708989122997041(dns block)api.openweathermap.org/home/REDACTED/work/_temp/ghcca-node/node/bin/node node /home/REDACTED/.npm/_npx/60193c364be7f30b/node_modules/.bin/wtr test/set-methods.js --node-resolve(dns block)clients2.google.com/proc/self/exe /proc/self/exe --type=utility --utility-sub-type=network.mojom.NetworkService --lang=en-US --service-sandbox-type=none --disable-dev-shm-usage --use-angle=swiftshader-webgl --mute-audio --crashpad-handler-pid=4006 --enable-crash-reporter=, --noerrdialogs --user-data-dir=/tmp/puppeteer_dev_chrome_profile-z0xwaJ --change-stack-guard-on-fork=enable --shared-files=v8_context_snapshot_data:100 --field-trial-handle=3,i,16526546639982034433,11159440813740539228,262144 --enable-features=PdfOopif --disable-features=AcceptCHFrame,IsolateSandboxedIframes,MediaRouter,OptimizationHints,PaintHolding,ProcessPerSiteUpToMainFrameThreshold,Translate --variations-seed-version --trace-process-track-uuid=3190708989122997041(dns block)/opt/google/chrome/chrome /usr/bin/google-chrome-stable --allow-pre-commit-input --disable-REDACTED-networking --disable-REDACTED-timer-throttling --disable-REDACTEDing-occluded-windows --disable-breakpad --disable-client-side-phishing-detection --disable-component-extensions-with-REDACTED-pages --disable-crash-reporter --disable-default-apps --disable-dev-shm-usage --disable-extensions --disable-hang-monitor --disable-infobars --disable-ipc-flooding-protection --disable-popup-blocking --disable-prompt-on-repost --disable-renderer-REDACTEDing --disable-search-engine-choice-screen --disable-sync(dns block)/proc/self/exe /proc/self/exe --type=utility --utility-sub-type=network.mojom.NetworkService --lang=en-US --service-sandbox-type=none --disable-dev-shm-usage --use-angle=swiftshader-webgl --mute-audio --crashpad-handler-pid=4258 --enable-crash-reporter=, --noerrdialogs --user-data-dir=/tmp/puppeteer_dev_chrome_profile-IkdZcd --change-stack-guard-on-fork=enable --shared-files=v8_context_snapshot_data:100 --field-trial-handle=3,i,4382833278840495840,8209209942178505960,262144 --enable-features=PdfOopif --disable-features=AcceptCHFrame,IsolateSandboxedIframes,MediaRouter,OptimizationHints,PaintHolding,ProcessPerSiteUpToMainFrameThreshold,Translate --variations-seed-version --trace-process-track-uuid=3190708989122997041(dns block)safebrowsingohttpgateway.googleapis.com/proc/self/exe /proc/self/exe --type=utility --utility-sub-type=network.mojom.NetworkService --lang=en-US --service-sandbox-type=none --disable-dev-shm-usage --use-angle=swiftshader-webgl --mute-audio --crashpad-handler-pid=4006 --enable-crash-reporter=, --noerrdialogs --user-data-dir=/tmp/puppeteer_dev_chrome_profile-z0xwaJ --change-stack-guard-on-fork=enable --shared-files=v8_context_snapshot_data:100 --field-trial-handle=3,i,16526546639982034433,11159440813740539228,262144 --enable-features=PdfOopif --disable-features=AcceptCHFrame,IsolateSandboxedIframes,MediaRouter,OptimizationHints,PaintHolding,ProcessPerSiteUpToMainFrameThreshold,Translate --variations-seed-version --trace-process-track-uuid=3190708989122997041(dns block)/opt/google/chrome/chrome /usr/bin/google-chrome-stable --allow-pre-commit-input --disable-REDACTED-networking --disable-REDACTED-timer-throttling --disable-REDACTEDing-occluded-windows --disable-breakpad --disable-client-side-phishing-detection --disable-component-extensions-with-REDACTED-pages --disable-crash-reporter --disable-default-apps --disable-dev-shm-usage --disable-extensions --disable-hang-monitor --disable-infobars --disable-ipc-flooding-protection --disable-popup-blocking --disable-prompt-on-repost --disable-renderer-REDACTEDing --disable-search-engine-choice-screen --disable-sync(dns block)/proc/self/exe /proc/self/exe --type=utility --utility-sub-type=network.mojom.NetworkService --lang=en-US --service-sandbox-type=none --disable-dev-shm-usage --use-angle=swiftshader-webgl --mute-audio --crashpad-handler-pid=4258 --enable-crash-reporter=, --noerrdialogs --user-data-dir=/tmp/puppeteer_dev_chrome_profile-IkdZcd --change-stack-guard-on-fork=enable --shared-files=v8_context_snapshot_data:100 --field-trial-handle=3,i,4382833278840495840,8209209942178505960,262144 --enable-features=PdfOopif --disable-features=AcceptCHFrame,IsolateSandboxedIframes,MediaRouter,OptimizationHints,PaintHolding,ProcessPerSiteUpToMainFrameThreshold,Translate --variations-seed-version --trace-process-track-uuid=3190708989122997041(dns block)www.google.com/proc/self/exe /proc/self/exe --type=utility --utility-sub-type=network.mojom.NetworkService --lang=en-US --service-sandbox-type=none --disable-dev-shm-usage --use-angle=swiftshader-webgl --mute-audio --crashpad-handler-pid=4006 --enable-crash-reporter=, --noerrdialogs --user-data-dir=/tmp/puppeteer_dev_chrome_profile-z0xwaJ --change-stack-guard-on-fork=enable --shared-files=v8_context_snapshot_data:100 --field-trial-handle=3,i,16526546639982034433,11159440813740539228,262144 --enable-features=PdfOopif --disable-features=AcceptCHFrame,IsolateSandboxedIframes,MediaRouter,OptimizationHints,PaintHolding,ProcessPerSiteUpToMainFrameThreshold,Translate --variations-seed-version --trace-process-track-uuid=3190708989122997041(dns block)/opt/google/chrome/chrome /usr/bin/google-chrome-stable --allow-pre-commit-input --disable-REDACTED-networking --disable-REDACTED-timer-throttling --disable-REDACTEDing-occluded-windows --disable-breakpad --disable-client-side-phishing-detection --disable-component-extensions-with-REDACTED-pages --disable-crash-reporter --disable-default-apps --disable-dev-shm-usage --disable-extensions --disable-hang-monitor --disable-infobars --disable-ipc-flooding-protection --disable-popup-blocking --disable-prompt-on-repost --disable-renderer-REDACTEDing --disable-search-engine-choice-screen --disable-sync(dns block)/proc/self/exe /proc/self/exe --type=utility --utility-sub-type=network.mojom.NetworkService --lang=en-US --service-sandbox-type=none --disable-dev-shm-usage --use-angle=swiftshader-webgl --mute-audio --crashpad-handler-pid=4258 --enable-crash-reporter=, --noerrdialogs --user-data-dir=/tmp/puppeteer_dev_chrome_profile-IkdZcd --change-stack-guard-on-fork=enable --shared-files=v8_context_snapshot_data:100 --field-trial-handle=3,i,4382833278840495840,8209209942178505960,262144 --enable-features=PdfOopif --disable-features=AcceptCHFrame,IsolateSandboxedIframes,MediaRouter,OptimizationHints,PaintHolding,ProcessPerSiteUpToMainFrameThreshold,Translate --variations-seed-version --trace-process-track-uuid=3190708989122997041(dns block)If you need me to access, download, or install something from one of these locations, you can either:
Original prompt
Setmethods #109💡 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.