Skip to content

feat(rsc): bind accessed member expression value for use server closure#1172

Merged
hi-ogawa merged 127 commits intomainfrom
feat-bind-member-expr
Apr 6, 2026
Merged

feat(rsc): bind accessed member expression value for use server closure#1172
hi-ogawa merged 127 commits intomainfrom
feat-bind-member-expr

Conversation

@hi-ogawa
Copy link
Copy Markdown
Contributor

@hi-ogawa hi-ogawa commented Apr 5, 2026

@hi-ogawa hi-ogawa marked this pull request as ready for review April 6, 2026 04:26
Copy link
Copy Markdown

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

This PR enhances the RSC server-action hoisting transform so closures that reference member-access chains (e.g. config.api.key) bind only the accessed subtree instead of serializing/binding the full root object. This reduces RSC payload size and avoids runtime serialization failures when the root contains non-serializable values.

Changes:

  • Extend scope analysis to track the “outermost bindable” reference node per identifier (identifier vs. non-computed member-expression chain, with callee trimming).
  • Update hoist binding to synthesize partial object literals per root identifier and bind those (while keeping the hoisted function parameter as the root name).
  • Add/refresh fixtures + snapshots and add design notes; update formatter ignore patterns for new *.snap.js files.

Reviewed changes

Copilot reviewed 31 out of 31 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
packages/plugin-rsc/src/transforms/utils.ts Adds a shared DefaultMap helper (moved out of tests).
packages/plugin-rsc/src/transforms/scope.ts Tracks member-expression chains per reference (referenceToNode) and applies callee trimming.
packages/plugin-rsc/src/transforms/scope.test.ts Updates scope serializer to optionally display the tracked reference node; uses shared DefaultMap.
packages/plugin-rsc/src/transforms/hoist.ts Changes bind-var extraction to synthesize partial-object bind expressions for member chains.
packages/plugin-rsc/src/transforms/hoist.test.ts Adds fixture-based snapshot testing for hoist output and updates/clarifies some existing edge-case comments.
packages/plugin-rsc/src/transforms/fixtures/scope/reference-node/member-chain.js New fixture for plain member chain reference-node tracking.
packages/plugin-rsc/src/transforms/fixtures/scope/reference-node/member-chain.js.snap.json Snapshot for plain member chain reference-node tracking.
packages/plugin-rsc/src/transforms/fixtures/scope/reference-node/member-chain-optional.js New fixture for optional-chain boundary behavior.
packages/plugin-rsc/src/transforms/fixtures/scope/reference-node/member-chain-optional.js.snap.json Snapshot for optional-chain boundary behavior.
packages/plugin-rsc/src/transforms/fixtures/scope/reference-node/member-chain-computed.js New fixture for computed-access boundary behavior.
packages/plugin-rsc/src/transforms/fixtures/scope/reference-node/member-chain-computed.js.snap.json Snapshot for computed-access boundary behavior.
packages/plugin-rsc/src/transforms/fixtures/scope/reference-node/member-chain-callee.js New fixture for callee-trimming behavior.
packages/plugin-rsc/src/transforms/fixtures/scope/reference-node/member-chain-callee.js.snap.json Snapshot for callee-trimming behavior.
packages/plugin-rsc/src/transforms/fixtures/hoist/member-chain.js New hoist fixture for partial-object binding of member chains.
packages/plugin-rsc/src/transforms/fixtures/hoist/member-chain.js.snap.js Snapshot for member-chain partial-object binding.
packages/plugin-rsc/src/transforms/fixtures/hoist/member-chain-siblings.js New hoist fixture for merging sibling paths under one root.
packages/plugin-rsc/src/transforms/fixtures/hoist/member-chain-siblings.js.snap.js Snapshot for sibling-path merge binding.
packages/plugin-rsc/src/transforms/fixtures/hoist/member-chain-root.js New hoist fixture where direct root access forces binding the whole root.
packages/plugin-rsc/src/transforms/fixtures/hoist/member-chain-root.js.snap.js Snapshot for root-access override binding.
packages/plugin-rsc/src/transforms/fixtures/hoist/member-chain-optional.js New hoist fixture for optional-chain conservative fallback behavior.
packages/plugin-rsc/src/transforms/fixtures/hoist/member-chain-optional.js.snap.js Snapshot for optional-chain fallback behavior.
packages/plugin-rsc/src/transforms/fixtures/hoist/member-chain-dedupe.js New hoist fixture for prefix dedupe behavior.
packages/plugin-rsc/src/transforms/fixtures/hoist/member-chain-dedupe.js.snap.js Snapshot for prefix-dedupe binding result.
packages/plugin-rsc/src/transforms/fixtures/hoist/member-chain-computed.js New hoist fixture for computed-access conservative fallback behavior.
packages/plugin-rsc/src/transforms/fixtures/hoist/member-chain-computed.js.snap.js Snapshot for computed-access fallback behavior.
packages/plugin-rsc/src/transforms/fixtures/hoist/member-chain-callee.js New hoist fixture verifying callee trimming preserves receiver capture.
packages/plugin-rsc/src/transforms/fixtures/hoist/member-chain-callee.js.snap.js Snapshot for callee-trimming hoist output.
packages/plugin-rsc/src/transforms/fixtures/hoist/member-chain-unsupported.js New hoist fixture covering multiple unsupported patterns.
packages/plugin-rsc/src/transforms/fixtures/hoist/member-chain-unsupported.js.snap.js Snapshot for unsupported-pattern binding behavior.
packages/plugin-rsc/docs/notes/2026-04-05-rsc-member-chain-binding-plan.md Design note documenting the chosen approach and rationale.
packages/plugin-rsc/docs/notes/2026-04-05-member-chain-optional-computed-follow-up.md Follow-up note outlining optional/computed access support considerations.
.oxfmtrc.json Expands ignore pattern to cover *.snap.* (including new *.snap.js).
Comments suppressed due to low confidence (1)

packages/plugin-rsc/src/transforms/scope.test.ts:10

  • Typo in comment: “snaphsot” → “snapshot”.
// - use single markdown as snaphsot? (cf. review-scope-fixtures.ts)

describe('fixtures', () => {

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

Base automatically changed from test-rsc-add-test-for-use-server-binding-and-shadowing to main April 6, 2026 05:25
@hi-ogawa hi-ogawa merged commit 2c4b500 into main Apr 6, 2026
20 checks passed
@hi-ogawa hi-ogawa deleted the feat-bind-member-expr branch April 6, 2026 05:47
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.

server action closures should capture member access paths, not whole objects

2 participants