Skip to content

fix(reactivity): collection iteration should inherit iterator instance methods#12644

Merged
edison1105 merged 5 commits intomainfrom
edison/fix/12615
Jan 19, 2026
Merged

fix(reactivity): collection iteration should inherit iterator instance methods#12644
edison1105 merged 5 commits intomainfrom
edison/fix/12615

Conversation

@edison1105
Copy link
Copy Markdown
Member

@edison1105 edison1105 commented Jan 3, 2025

close #12615

Summary by CodeRabbit

  • Refactor

    • Internal change to how iterators are wrapped in the reactivity system while preserving iteration behavior and existing APIs.
  • Tests

    • Added validation that wrapped iterators behave identically to native iterators (iteration protocol and properties).
  • Chores

    • Minor cleanup; no user-facing behavior or public API changes.

Note: No functional or API changes for end users.

✏️ Tip: You can customize this high-level summary in your review settings.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jan 3, 2025

Size Report

Bundles

File Size Gzip Brotli
runtime-dom.global.prod.js 103 kB (-13 B) 39.1 kB (+2 B) 35.2 kB (-17 B)
vue.global.prod.js 161 kB (-13 B) 59.1 kB (+2 B) 52.6 kB (-20 B)

Usages

Name Size Gzip Brotli
createApp (CAPI only) 47 kB (-13 B) 18.4 kB (+1 B) 16.8 kB (+2 B)
createApp 55.1 kB (-13 B) 21.4 kB (+3 B) 19.6 kB (+3 B)
createSSRApp 59.4 kB (-13 B) 23.2 kB (+1 B) 21.1 kB (-7 B)
defineCustomElement 60.7 kB (-13 B) 23.1 kB (+3 B) 21.1 kB (+9 B)
overall 69.5 kB (-13 B) 26.7 kB (+1 B) 24.3 kB (-5 B)

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented Jan 3, 2025

Open in StackBlitz

@vue/compiler-core

pnpm add https://pkg.pr.new/@vue/compiler-core@12644
npm i https://pkg.pr.new/@vue/compiler-core@12644
yarn add https://pkg.pr.new/@vue/compiler-core@12644.tgz

@vue/compiler-dom

pnpm add https://pkg.pr.new/@vue/compiler-dom@12644
npm i https://pkg.pr.new/@vue/compiler-dom@12644
yarn add https://pkg.pr.new/@vue/compiler-dom@12644.tgz

@vue/compiler-sfc

pnpm add https://pkg.pr.new/@vue/compiler-sfc@12644
npm i https://pkg.pr.new/@vue/compiler-sfc@12644
yarn add https://pkg.pr.new/@vue/compiler-sfc@12644.tgz

@vue/compiler-ssr

pnpm add https://pkg.pr.new/@vue/compiler-ssr@12644
npm i https://pkg.pr.new/@vue/compiler-ssr@12644
yarn add https://pkg.pr.new/@vue/compiler-ssr@12644.tgz

@vue/reactivity

pnpm add https://pkg.pr.new/@vue/reactivity@12644
npm i https://pkg.pr.new/@vue/reactivity@12644
yarn add https://pkg.pr.new/@vue/reactivity@12644.tgz

@vue/runtime-core

pnpm add https://pkg.pr.new/@vue/runtime-core@12644
npm i https://pkg.pr.new/@vue/runtime-core@12644
yarn add https://pkg.pr.new/@vue/runtime-core@12644.tgz

@vue/runtime-dom

pnpm add https://pkg.pr.new/@vue/runtime-dom@12644
npm i https://pkg.pr.new/@vue/runtime-dom@12644
yarn add https://pkg.pr.new/@vue/runtime-dom@12644.tgz

@vue/server-renderer

pnpm add https://pkg.pr.new/@vue/server-renderer@12644
npm i https://pkg.pr.new/@vue/server-renderer@12644
yarn add https://pkg.pr.new/@vue/server-renderer@12644.tgz

@vue/shared

pnpm add https://pkg.pr.new/@vue/shared@12644
npm i https://pkg.pr.new/@vue/shared@12644
yarn add https://pkg.pr.new/@vue/shared@12644.tgz

vue

pnpm add https://pkg.pr.new/vue@12644
npm i https://pkg.pr.new/vue@12644
yarn add https://pkg.pr.new/vue@12644.tgz

@vue/compat

pnpm add https://pkg.pr.new/@vue/compat@12644
npm i https://pkg.pr.new/@vue/compat@12644
yarn add https://pkg.pr.new/@vue/compat@12644.tgz

commit: 9c8ebd8

@edison1105 edison1105 added ready to merge The PR is ready to be merged. scope: reactivity 🍰 p2-nice-to-have Priority 2: this is not breaking anything but nice to have it addressed. labels Jan 3, 2025
Comment thread packages/reactivity/src/collectionHandlers.ts Outdated
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jan 9, 2026

📝 Walkthrough

Walkthrough

Iterator wrapper in reactivity was changed to inherit from the original iterator via Object.create(innerIterator) and override only next(), preserving the inner iterator’s prototype and properties while keeping the existing value-wrapping behavior.

Changes

Cohort / File(s) Summary
Iterator wrapper update
packages/reactivity/src/collectionHandlers.ts
Replace literal wrapper with an object created from innerIterator and override next() so prototype properties (including [Symbol.iterator]) are preserved; value wrapping unchanged.
Map iterator tests
packages/reactivity/__tests__/collections/Map.spec.ts
Add test asserting wrapped Map iterator exposes next, Symbol.iterator, that wrapped[Symbol.iterator]() returns itself, and that own prototype properties of the raw iterator are present on the wrapped iterator.

Sequence Diagram(s)

(omitted)

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 I hopped into iterators old and new,
Inherited traits returned in view,
next() still hops, values stay bright,
Prototype friends came back in sight,
A tiny thump — iteration’s true.

🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title clearly describes the main fix: collection iterators now inherit instance methods instead of recreating them, which directly addresses the issue where Map iterators were losing methods.
Linked Issues check ✅ Passed The changes fully address issue #12615 by modifying the iterator wrapper to inherit from innerIterator, ensuring all iterator instance methods are preserved on reactive collections.
Out of Scope Changes check ✅ Passed All changes are directly scoped to fixing the iterator method inheritance issue. The code modification and test addition are both necessary and related to the linked issue.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
packages/reactivity/src/collectionHandlers.ts (1)

56-73: LGTM: iterator wrapper now preserves iterator instance/prototype methods while still wrapping yielded values.
The Object.create(innerIterator) + override next() approach should fix the reported loss of iterator methods after values()/keys()/entries() while keeping innerIterator.next() as the source of truth.

Add a regression test for “iterator methods preserved” without relying on runtime Iterator Helpers.
Consider a unit test that temporarily augments Object.getPrototypeOf(rawMap.values()) with a sentinel method (restore afterward), then asserts reactive(map).values() exposes it and still yields wrapped values.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6049f87 and 1dfe406.

📒 Files selected for processing (1)
  • packages/reactivity/src/collectionHandlers.ts
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: naramdash
Repo: vuejs/core PR: 14058
File: packages/reactivity/src/collectionHandlers.ts:252-271
Timestamp: 2025-11-05T14:53:01.052Z
Learning: In Vue's reactivity system, collection methods that create new collections (like Array's slice(), concat(), filter() and Set's difference(), intersection(), union(), symmetricDifference()) intentionally return raw (non-reactive) collections, not reactive proxies. This is by design - only the values/elements inside can remain reactive if they were originally reactive.
🧬 Code graph analysis (1)
packages/reactivity/src/collectionHandlers.ts (1)
packages/shared/src/general.ts (1)
  • extend (24-24)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: test / e2e-test

@edison1105 edison1105 changed the title feat(reactivity): collection iteration should inherit iterator instance methods fix(reactivity): collection iteration should inherit iterator instance methods Jan 9, 2026
@edison1105 edison1105 added 🔨 p3-minor-bug Priority 3: this fixes a bug, but is an edge case that only affects very specific usage. and removed 🍰 p2-nice-to-have Priority 2: this is not breaking anything but nice to have it addressed. labels Jan 9, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
packages/reactivity/__tests__/collections/Map.spec.ts (1)

475-498: LGTM! Test comprehensively validates iterator property inheritance.

The test correctly validates that the wrapped iterator preserves the prototype chain from the raw iterator, including both named properties and symbols. The checks for next, Symbol.iterator, and the iterable protocol (line 485) are all appropriate.

📋 Optional: Consider testing other iterator methods

While .entries() is tested here, you might also want to verify .values() and .keys() iterators inherit properties correctly, since the original issue #12615 specifically mentioned .values():

// Additional test cases
const valuesIterator = map.values()
expect(typeof valuesIterator.next).toBe('function')
expect(typeof valuesIterator[Symbol.iterator]).toBe('function')

const keysIterator = map.keys()
expect(typeof keysIterator.next).toBe('function')
expect(typeof keysIterator[Symbol.iterator]).toBe('function')

This would provide more comprehensive coverage of all iterator methods affected by the fix.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1dfe406 and f3e90c7.

📒 Files selected for processing (1)
  • packages/reactivity/__tests__/collections/Map.spec.ts
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: naramdash
Repo: vuejs/core PR: 14058
File: packages/reactivity/src/collectionHandlers.ts:252-271
Timestamp: 2025-11-05T14:53:01.052Z
Learning: In Vue's reactivity system, collection methods that create new collections (like Array's slice(), concat(), filter() and Set's difference(), intersection(), union(), symmetricDifference()) intentionally return raw (non-reactive) collections, not reactive proxies. This is by design - only the values/elements inside can remain reactive if they were originally reactive.
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: test / e2e-test

@edison1105
Copy link
Copy Markdown
Member Author

/ecosystem-ci run

@vue-bot
Copy link
Copy Markdown
Contributor

vue-bot commented Jan 19, 2026

📝 Ran ecosystem CI: Open

suite result latest scheduled
pinia success success
quasar success success
nuxt failure failure
radix-vue success success
primevue failure success
vite-plugin-vue success success
vue-i18n failure failure
language-tools failure failure
router success success
test-utils success success
vitepress success success
vant success success
vue-simple-compiler success success
vueuse failure failure
vuetify failure failure
vue-macros failure failure

@edison1105 edison1105 merged commit 3c8b2fc into main Jan 19, 2026
16 checks passed
@edison1105 edison1105 deleted the edison/fix/12615 branch January 19, 2026 00:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🔨 p3-minor-bug Priority 3: this fixes a bug, but is an edge case that only affects very specific usage. ready to merge The PR is ready to be merged. scope: reactivity

Projects

None yet

Development

Successfully merging this pull request may close these issues.

A reactive variable create from the Map data while lost some new functions after use iterator methods like values

3 participants