Skip to content

feat[RSC]: [ENG-8936] Add LiveEdit support for client-side updates using BuilderContext.Provider #4022

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

Open
wants to merge 13 commits into
base: main
Choose a base branch
from

Conversation

yash-builder
Copy link
Contributor

Description:
This PR introduces client-side live editing support by extending the existing context and rendering logic in the SDK.

What changes were made:

  • Added a new BuilderContext.Provider inside EnableEditor to consume a derived state from the builderContextSignal prop in Content.
  • Introduced a LiveEdit wrapper component that:
    • Finds a block by ID from the current context content.
    • Applies updated component options dynamically to render changes in real time.
  • Updated InteractiveElement to conditionally render LiveEdit when in editing mode.
  • Implemented logic to differentiate between editType: 'server' and editType: 'client':
    • For 'server', retain existing behavior—push updates to LRU cache and re-render on the server.
    • For 'client', trigger a context update that re-renders LiveEdit components on the client side.

Why these changes were made:
To support hybrid editing in the SDK where developers can opt into either server-side or client-side editing behavior, depending on the use case.

Additional context:

  • These changes are foundational for enabling smoother, near-instant updates during visual editing sessions—especially when using editType: 'client'.
  • These changes will also require handling on builder-internal

Screenshot
OTW

Copy link

changeset-bot bot commented Apr 11, 2025

⚠️ No Changeset found

Latest commit: 6bacd53

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@yash-builder yash-builder self-assigned this Apr 11, 2025
@yash-builder yash-builder requested a review from samijaber April 11, 2025 00:13
Copy link

gitguardian bot commented Apr 11, 2025

⚠️ GitGuardian has uncovered 1 secret following the scan of your pull request.

Please consider investigating the findings and remediating the incidents. Failure to do so may lead to compromising the associated services or software components.

Since your pull request originates from a forked repository, GitGuardian is not able to associate the secrets uncovered with secret incidents on your GitGuardian dashboard.
Skipping this check run and merging your pull request will create secret incidents on your GitGuardian dashboard.

🔎 Detected hardcoded secret in your pull request
GitGuardian id GitGuardian status Secret Commit Filename
11707119 Triggered Generic High Entropy Secret 6b6b74a packages/sdks/snippets/react/src/routes/blueprints/ProductEditorial.tsx View secret
🛠 Guidelines to remediate hardcoded secrets
  1. Understand the implications of revoking this secret by investigating where it is used in your code.
  2. Replace and store your secret safely. Learn here the best practices.
  3. Revoke and rotate this secret.
  4. If possible, rewrite git history. Rewriting git history is not a trivial act. You might completely break other contributing developers' workflow and you risk accidentally deleting legitimate data.

To avoid such incidents in the future consider


🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.

Copy link

nx-cloud bot commented Apr 11, 2025

View your CI Pipeline Execution ↗ for commit 6bacd53.

Command Status Duration Result
nx test @e2e/qwik-city ✅ Succeeded 10m 34s View ↗
nx test @e2e/nextjs-sdk-next-app ✅ Succeeded 9m 48s View ↗
nx test @e2e/nuxt ✅ Succeeded 9m 23s View ↗
nx test @e2e/angular-16 ✅ Succeeded 7m 43s View ↗
nx test @e2e/angular-16-ssr ✅ Succeeded 7m 38s View ↗
nx test @e2e/remix ✅ Succeeded 7m 29s View ↗
nx test @e2e/svelte ✅ Succeeded 7m 28s View ↗
nx test @e2e/gen1-remix ✅ Succeeded 6m 15s View ↗
Additional runs (36) ✅ Succeeded ... View ↗

☁️ Nx Cloud last updated this comment at 2025-04-16 13:11:23 UTC

@yash-builder yash-builder added the enhancement New feature or request label Apr 14, 2025
…angular error reverted mitosis change. Instead of using spread operator in LiveEdit using assignment operator to handle undefined
@yash-builder yash-builder marked this pull request as ready for review April 16, 2025 05:19
@yash-builder yash-builder changed the title WIP. feat[RSC]: [ENG-8936] Add LiveEdit support for client-side updates using BuilderContext.Provider feat[RSC]: [ENG-8936] Add LiveEdit support for client-side updates using BuilderContext.Provider Apr 16, 2025
@@ -949,7 +949,7 @@ const QWIK_FORCE_RENDER_COUNT_FOR_RENDERING_CUSTOM_COMPONENT_DEFAULT_VALUE =
json: {
post: (json) => {
if (json.name === 'InteractiveElement') {
json.children[0].meta.else.bindings['key'] = {
json.children[0].meta.else.meta.else.bindings['key'] = {
Copy link
Contributor

Choose a reason for hiding this comment

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

Would it be possible to record a loom to explain this bit?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Noted! Will surely record a loom around it before merging this PR

Comment on lines 23 to 37
_findBlockById(
blocks: BuilderBlock[] | undefined,
id: string
): BuilderBlock | null {
if (!blocks) return null;
for (const block of blocks) {
if (block.id === id) return block;

if (block.children) {
const child = this._findBlockById(block.children, id);
if (child) return child;
}
}
return null;
},
Copy link
Contributor

Choose a reason for hiding this comment

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

We could use just findBlockById() instead of having a separate _findBlockById(). Also by removing _findBlockById() we reduce the future possibility of a developer calling state._findBlockById()

Copy link
Contributor

Choose a reason for hiding this comment

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

If _findBlockById() was a private function in useStore then we could keep it.

Comment on lines +53 to +58
const _ = {
a: props.id,
b: props.Wrapper,
c: props.attributes,
d: props.children,
};
Copy link
Contributor

Choose a reason for hiding this comment

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

Would it be possible to record a loom to explain this part?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Noted!

key: newContentValue.id!,
url: window.location.pathname,
});
// console.log('DEBUG: SDK: RECEIEVED editType: ', editType);
Copy link
Contributor

Choose a reason for hiding this comment

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

can remove this

@@ -242,7 +249,7 @@ export default function EnableEditor(props: BuilderEditorProps) {
},
});

setContext(builderContext, props.builderContextSignal);
setContext(builderContext, props.builderContextSignal)
Copy link
Contributor

Choose a reason for hiding this comment

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

nitpick but we can add the ; back

@clyde-builderio
Copy link
Contributor

@yash-builder Would it be possible to add tests for the changes?

Copy link
Contributor

@samijaber samijaber left a comment

Choose a reason for hiding this comment

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

with this change, many existing visual editing tests (like the ones that edit text blocks) should now work on nextjs SDK.

  • For 'client' updates (like editing texts, images): Can we enable those tests for nextjs sdk and make any other changes needed to confirm that editing works as expected?
  • For 'server' updates (like editing Columns, which is an RSC), can we dig into getting those tests working for nextjs SDK too to make sure the server updates also work as expected? I never got around to doing so, but it would be useful as part of this work to make sure all editing works well going forward.

/**
* Whether the component is a React Server Component
*/
isRSC?: boolean;
Copy link
Contributor

Choose a reason for hiding this comment

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

On second thought i would prefer we don't have this type here. Some customers might see this and set it to true in their React Gen1 SDK implementation, and then they'll be confused as to why it doesn't do anything

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Any suggestions on where shall we add the type isRSC? Since we will be needing this type in our builder-internal

Copy link
Contributor

@samijaber samijaber left a comment

Choose a reason for hiding this comment

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

Another note: would be good to see & test whole flow end-to-end for both PRs (webapp + SDK) combined and make sure it works well before merging SDK changes, otherwise those might themselves in an SDK release if someone else has changes queued up.

@yash-builder
Copy link
Contributor Author

@yash-builder Would it be possible to add tests for the changes?

Absolutely

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants