-
Notifications
You must be signed in to change notification settings - Fork 665
feat: implement return init from lifecycle onMount #2957
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
🦋 Changeset detectedLatest commit: 8cc1c93 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
WalkthroughAdds new test fixtures for lifecycle-tag-property-overwrite-error and lifecycle-tag-return-init. Updates Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Tip 📝 Customizable high-level summaries are now available in beta!You can now customize how CodeRabbit generates the high-level summary in your pull requests — including its content, structure, tone, and formatting.
Example instruction:
Note: This feature is currently in beta for Pro-tier users, and pricing will be announced later. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this 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/runtime-tags/src/dom/dom.ts (1)
400-414: Clarify debug snapshot variable and intentThe new onMount-return handling and debug check logic look sound and align with the described behavior (merge returned props, then fail fast if any existing key’s value changed).
Minor polish: consider renaming
shapshottosnapshoton Line 400/402 for clarity and to avoid confusion when revisiting this code.- let shapshot = undefined; + let snapshot = undefined; @@ - shapshot = Object.assign({}, thisObj); + snapshot = Object.assign({}, thisObj); @@ - for (const [prop, prevVal] of Object.entries(shapshot!)) { + for (const [prop, prevVal] of Object.entries(snapshot!)) {
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (18)
.changeset/eager-pets-grin.mdis excluded by none and included by none.sizes.jsonis excluded by none and included by none.sizes/dom.jsis excluded by none and included by nonepackages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-property-overwrite-error/__snapshots__/csr-sanitized.expected.mdis excluded by!**/__snapshots__/**and included by**/src/**packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-property-overwrite-error/__snapshots__/csr.expected.mdis excluded by!**/__snapshots__/**and included by**/src/**packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-property-overwrite-error/__snapshots__/dom.expected/template.jsis excluded by!**/__snapshots__/**and included by**/src/**packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-property-overwrite-error/__snapshots__/html.expected/template.jsis excluded by!**/__snapshots__/**and included by**/src/**packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-return-init/__snapshots__/.name-cache.jsonis excluded by!**/__snapshots__/**and included by**/src/**packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-return-init/__snapshots__/csr-sanitized.expected.mdis excluded by!**/__snapshots__/**and included by**/src/**packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-return-init/__snapshots__/csr.expected.mdis excluded by!**/__snapshots__/**and included by**/src/**packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-return-init/__snapshots__/dom.expected/template.hydrate.jsis excluded by!**/__snapshots__/**and included by**/src/**packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-return-init/__snapshots__/dom.expected/template.jsis excluded by!**/__snapshots__/**and included by**/src/**packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-return-init/__snapshots__/html.expected/template.jsis excluded by!**/__snapshots__/**and included by**/src/**packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-return-init/__snapshots__/resume-sanitized.expected.mdis excluded by!**/__snapshots__/**and included by**/src/**packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-return-init/__snapshots__/resume.expected.mdis excluded by!**/__snapshots__/**and included by**/src/**packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-return-init/__snapshots__/ssr-sanitized.expected.mdis excluded by!**/__snapshots__/**and included by**/src/**packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-return-init/__snapshots__/ssr.expected.mdis excluded by!**/__snapshots__/**and included by**/src/**packages/runtime-tags/tags/lifecycle.d.markois excluded by none and included by none
📒 Files selected for processing (5)
packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-property-overwrite-error/template.marko(1 hunks)packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-property-overwrite-error/test.ts(1 hunks)packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-return-init/template.marko(1 hunks)packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-return-init/test.ts(1 hunks)packages/runtime-tags/src/dom/dom.ts(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-property-overwrite-error/test.ts (1)
packages/runtime-tags/src/__tests__/utils/resolve.ts (1)
wait(4-8)
🔇 Additional comments (4)
packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-return-init/template.marko (1)
1-13: Fixture correctly exercises return-init lifecycle behaviorThe template cleanly covers the new semantics (onMount returning init props merged into
thisand onUpdate reflecting state), and the DOM wiring via#ref/#incrementmatches the intended test scenario.packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-return-init/test.ts (1)
1-5: Test harness wiring looks consistent
stepsandincrementfollow the existing fixture pattern (container-driven click), and declaration order is fine sinceincrementis a function declaration.packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-property-overwrite-error/template.marko (1)
1-6: Good minimal fixture for overwrite detectionThis compact template is a clear repro for the “mutate existing property in onMount” case and should reliably exercise the new debug error path.
packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-property-overwrite-error/test.ts (1)
1-6: Runtime error test configuration looks appropriateThe
steps+wait(1)pattern, along witherror_runtimeandskip_ssr, fits the intended “expect a client-side lifecycle error” scenario for this fixture.
6863183 to
66d58a2
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/runtime-tags/src/dom/dom.ts (1)
385-393: Fix the type signature foronMountto reflect the return value.The type signature declares
onMount?: (this: unknown) => voidbut Line 404 captures and uses its return value to merge properties into the instance. This type mismatch will cause incorrect type inference.Apply this diff to fix the type signature:
export function _lifecycle( scope: Scope, index: string | number, thisObj: Record<string, unknown> & { - onMount?: (this: unknown) => void; + onMount?: (this: unknown) => Record<string, unknown> | void; onUpdate?: (this: unknown) => void; onDestroy?: (this: unknown) => void; }, ) {
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (18)
.changeset/eager-pets-grin.mdis excluded by none and included by none.sizes.jsonis excluded by none and included by none.sizes/dom.jsis excluded by none and included by nonepackages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-property-overwrite-error/__snapshots__/csr-sanitized.expected.mdis excluded by!**/__snapshots__/**and included by**/src/**packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-property-overwrite-error/__snapshots__/csr.expected.mdis excluded by!**/__snapshots__/**and included by**/src/**packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-property-overwrite-error/__snapshots__/dom.expected/template.jsis excluded by!**/__snapshots__/**and included by**/src/**packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-property-overwrite-error/__snapshots__/html.expected/template.jsis excluded by!**/__snapshots__/**and included by**/src/**packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-return-init/__snapshots__/.name-cache.jsonis excluded by!**/__snapshots__/**and included by**/src/**packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-return-init/__snapshots__/csr-sanitized.expected.mdis excluded by!**/__snapshots__/**and included by**/src/**packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-return-init/__snapshots__/csr.expected.mdis excluded by!**/__snapshots__/**and included by**/src/**packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-return-init/__snapshots__/dom.expected/template.hydrate.jsis excluded by!**/__snapshots__/**and included by**/src/**packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-return-init/__snapshots__/dom.expected/template.jsis excluded by!**/__snapshots__/**and included by**/src/**packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-return-init/__snapshots__/html.expected/template.jsis excluded by!**/__snapshots__/**and included by**/src/**packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-return-init/__snapshots__/resume-sanitized.expected.mdis excluded by!**/__snapshots__/**and included by**/src/**packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-return-init/__snapshots__/resume.expected.mdis excluded by!**/__snapshots__/**and included by**/src/**packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-return-init/__snapshots__/ssr-sanitized.expected.mdis excluded by!**/__snapshots__/**and included by**/src/**packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-return-init/__snapshots__/ssr.expected.mdis excluded by!**/__snapshots__/**and included by**/src/**packages/runtime-tags/tags/lifecycle.d.markois excluded by none and included by none
📒 Files selected for processing (5)
packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-property-overwrite-error/template.marko(1 hunks)packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-property-overwrite-error/test.ts(1 hunks)packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-return-init/template.marko(1 hunks)packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-return-init/test.ts(1 hunks)packages/runtime-tags/src/dom/dom.ts(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
- packages/runtime-tags/src/tests/fixtures/lifecycle-tag-return-init/test.ts
- packages/runtime-tags/src/tests/fixtures/lifecycle-tag-property-overwrite-error/template.marko
- packages/runtime-tags/src/tests/fixtures/lifecycle-tag-return-init/template.marko
🧰 Additional context used
🧬 Code graph analysis (1)
packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-property-overwrite-error/test.ts (1)
packages/runtime-tags/src/__tests__/utils/resolve.ts (1)
wait(4-8)
🔇 Additional comments (2)
packages/runtime-tags/src/dom/dom.ts (1)
406-414: Clarify: validation catches both return-value overwrites AND direct mutations.The validation loop compares the pre-
onMountsnapshot with the post-Object.assignstate, so it will throw an error if:
onMountreturns a property that already exists inthisObj, ORonMountdirectly mutates an existing property (e.g.,this.x = newValue) before returningIf the intent is to only prevent overwrites from the return value, the current logic is too broad. If both cases should be prevented, the error message should clarify this.
Consider whether direct mutations within
onMountshould be allowed. If they should be allowed, the validation needs to comparesnapshotwiththisObjbefore theObject.assign, not after.packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-property-overwrite-error/test.ts (1)
1-6: LGTM!The test configuration correctly sets up a runtime error test case. The
error_runtimeflag indicates an error is expected during execution, andskip_ssris appropriate since lifecycle hooks only run on the client. The minimal steps with a short wait allows the error to be caught by the test harness.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #2957 +/- ##
==========================================
+ Coverage 88.40% 88.69% +0.29%
==========================================
Files 373 373
Lines 46692 46752 +60
Branches 3871 3909 +38
==========================================
+ Hits 41276 41466 +190
+ Misses 5373 5241 -132
- Partials 43 45 +2 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
66d58a2 to
b84587d
Compare
b84587d to
8cc1c93
Compare
There was a problem hiding this 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
♻️ Duplicate comments (1)
packages/runtime-tags/src/dom/dom.ts (1)
400-414: ValidateonMount’s return value beforeObject.assignto avoid surprising mergesRight now
const newProps = thisObj.onMount?.(); Object.assign(thisObj, newProps);will happily merge anything that’s object-coercible: arrays, functions, boxed primitives, etc. That can lead to very non-obvious state (e.g. index keys from arrays/strings) and makes it harder to reason about what shapesthisObjcan take after mount.Given this is user-authored code like:
onMount(() => { // … return someValue; })it would be safer to treat anything other than
undefinedor a plain object as invalid in debug builds, and either:
- Throw a clear error, or
- Ignore the value (and maybe log/warn) rather than merging it.
This also aligns nicely with your overwrite check: it keeps the invariant that only a shallow, plain object of new fields may be added from
onMount, and avoids weird interactions from accidentally returning an array or other non-plain object.Since a similar concern was already raised on a previous revision, this is effectively reinforcing that feedback for the current version of the code.
🧹 Nitpick comments (1)
packages/runtime-tags/src/dom/dom.ts (1)
388-392: Consider tightening lifecyclethistyping to better reflectthisObjRight now the lifecycle handlers are typed as
this: unknown, whilethisObjis aRecord<string, unknown> & { … }. That forces users into casts if they want strongly typed access to the properties you’re now allowingonMountto initialize.Not for this PR, but as a follow-up it may be worth:
- Making
_lifecyclegeneric over the instance shape, and- Typing
thisforonMount/onUpdate/onDestroyas that generic, so the compiler can help more with the “return-init” pattern you’re introducing.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (18)
.changeset/eager-pets-grin.mdis excluded by none and included by none.sizes.jsonis excluded by none and included by none.sizes/dom.jsis excluded by none and included by nonepackages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-property-overwrite-error/__snapshots__/csr-sanitized.expected.mdis excluded by!**/__snapshots__/**and included by**/src/**packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-property-overwrite-error/__snapshots__/csr.expected.mdis excluded by!**/__snapshots__/**and included by**/src/**packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-property-overwrite-error/__snapshots__/dom.expected/template.jsis excluded by!**/__snapshots__/**and included by**/src/**packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-property-overwrite-error/__snapshots__/html.expected/template.jsis excluded by!**/__snapshots__/**and included by**/src/**packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-return-init/__snapshots__/.name-cache.jsonis excluded by!**/__snapshots__/**and included by**/src/**packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-return-init/__snapshots__/csr-sanitized.expected.mdis excluded by!**/__snapshots__/**and included by**/src/**packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-return-init/__snapshots__/csr.expected.mdis excluded by!**/__snapshots__/**and included by**/src/**packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-return-init/__snapshots__/dom.expected/template.hydrate.jsis excluded by!**/__snapshots__/**and included by**/src/**packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-return-init/__snapshots__/dom.expected/template.jsis excluded by!**/__snapshots__/**and included by**/src/**packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-return-init/__snapshots__/html.expected/template.jsis excluded by!**/__snapshots__/**and included by**/src/**packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-return-init/__snapshots__/resume-sanitized.expected.mdis excluded by!**/__snapshots__/**and included by**/src/**packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-return-init/__snapshots__/resume.expected.mdis excluded by!**/__snapshots__/**and included by**/src/**packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-return-init/__snapshots__/ssr-sanitized.expected.mdis excluded by!**/__snapshots__/**and included by**/src/**packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-return-init/__snapshots__/ssr.expected.mdis excluded by!**/__snapshots__/**and included by**/src/**packages/runtime-tags/tags/lifecycle.d.markois excluded by none and included by none
📒 Files selected for processing (5)
packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-property-overwrite-error/template.marko(1 hunks)packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-property-overwrite-error/test.ts(1 hunks)packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-return-init/template.marko(1 hunks)packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-return-init/test.ts(1 hunks)packages/runtime-tags/src/dom/dom.ts(2 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
- packages/runtime-tags/src/tests/fixtures/lifecycle-tag-return-init/test.ts
- packages/runtime-tags/src/tests/fixtures/lifecycle-tag-property-overwrite-error/template.marko
- packages/runtime-tags/src/tests/fixtures/lifecycle-tag-return-init/template.marko
🧰 Additional context used
🧬 Code graph analysis (1)
packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-property-overwrite-error/test.ts (1)
packages/runtime-tags/src/__tests__/utils/resolve.ts (1)
wait(4-8)
🔇 Additional comments (1)
packages/runtime-tags/src/__tests__/fixtures/lifecycle-tag-property-overwrite-error/test.ts (1)
1-6: Fixture wiring looks correct for a runtime-only error caseImport,
stepsshape, and theerror_runtime/skip_ssrflags all match the existing test-fixture pattern for client-only runtime errors; nothing to fix here.
Description
Adds this:
Please verify that all this is good.
Also adds debug validation for property reassignment.
Haven't been able to fix this problem:
Checklist: