fix: add Streamable.from to avoid eager promises#2143
Conversation
|
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎
4 Skipped Deployments
|
There was a problem hiding this comment.
Should we automatically wrap every Streamable.all promise with Streamable.from?
There was a problem hiding this comment.
I found myself wondering if we needed Streamable.all if we had Streamable.from and I think the answer is "yes" given that they have different goals. Streamable.all will combine multiple streamables and keep that stable so that we don't get infinite suspensions in the client side. There's a question of whether we want to be doing that at all, though. I'm wondering if we should remove Streamable.all. Because we shouldn't be creating new streamables in client components, just how we shouldn't be creating promises in client components and because on the server we can use Streamable.from
That being said, you might have a point here about Streamable.all potentially eagerly executing both of these promises. I'll look into it.
There was a problem hiding this comment.
Ok, so I tested it and Streamable.all does trigger the executor, which is problematic.
Also, I remembered that the reason we added Streamable.all was because we wanted to be able to use VIBES components that were "shared" components with Makeswift, which would execute in a client environment.
I'm going to have to re-think Streamable.all but I will do this in a separate PR. cc: @agurtovoy
b873236 to
fad33a3
Compare
⚡️🏠 Lighthouse reportLighthouse ran against https://catalyst-canary-mx1yj5yh7-bigcommerce-platform.vercel.app 🖥️ DesktopWe ran Lighthouse against the changes on a desktop and produced this report. Here's the summary:
📱 MobileWe ran Lighthouse against the changes on a mobile and produced this report. Here's the summary:
|
* fix: switching locales redirects user to the home page (#1990) * chore: add demo section to readme (#1996) * Update translations (#1993) * feat(other): LOCAL-1444 delivery translation * chore(core): create translations patch --------- Co-authored-by: bc-svc-local <bc-svc-local@users.noreply.github.com> * feat: manage locales when creating storefronts from the CLI (#1986) * feat: manage locales * Add changeset --------- Co-authored-by: Nathan Booker <nathan.booker@bigcommerce.com> * feat: add default Tailwind typography styles (#2007) * Update translations (#2004) * feat(other): LOCAL-1444 delivery translation * chore(core): create translations patch --------- Co-authored-by: bc-svc-local <bc-svc-local@users.noreply.github.com> * fix(core): handle registration errors in form (#2006) * chore(release): publish create-catalyst CLI (#2015) * chore: remove scoped version bump * chore(release): publish create-catalyst CLI * feat: add es-419 to list of allowed locale for selecting (#2017) * feat(cli): scaffold package (#2010) * fix(core): show coupon discounts as a separate summary item (#2084) * fix(core): show coupon discounts as a separate summary item * fix: typo in changeset * feat(core): add shipping options to checkout (#1997) * feat(core): add shipping options to checkout * fix: capitalization of Edit * fix: bump vibes * fix: update vibes * fix: remove else and early return * refactor: simplify logic by using a Set for countries * fix: hide forms visually * fix: add no shipping options message * fix: remove reduce and use Set, remove let variable * fix: split mutations * fix: disable complexity rule for Cart * Update translations (#2104) * feat(other): LOCAL-1444 delivery translation * chore(core): create translations patch --------- Co-authored-by: bc-svc-local <bc-svc-local@users.noreply.github.com> * refactor: update signin behavior to use different providers (#2103) * refactor: update signin behavior to use different providers * chore: add additional folders to lint task * feat: Sync Button and DynamicForm with VIBES (#2110) * feat(core): add compare functionality to PLP (#2060) * feat(core): migrate compare page to use soul * feat: hide compare checkbox dynamically * feat: pass in comparable products * fix: add optimistic items * feat: add optimistic to remove * feat: add optimistic to checkbox * fix: sort when added * fix: sort groups and use link to compare * fix: bump vibes components, fix button * fix: remove unused primitves breadcrumbs component * fix: sync vibes components * fix: wrap transitions and call optimistic before setParam * fix: validate with zod variables are correct * fix: expose remove label * fix: await setParam * fix: translate remove label: * fix: use parser and loader for compare * feat: alert when max compare limit is set, disable checkboxes * feat: Sync ProductCard and WishlistItemCard with VIBES (#2112) * feat: Sync Breadcrumbs (#2117) * feat: Add Wishlist VIBES components (#2118) * chore(security): add documentation around CSRF checks (#2114) * fix: set the trustHost value with an env var * chore(core): documentation around CSRF checks within next-auth * feat: Add wishlist translations, transformers, and core components (#2119) * fix(core): revert to ids search param in compare page (#2125) * feat(client): add errorPolicy option to GQL requests (#2124) * feat: add anonymous session with cart tracking (#2111) * refactor(core): abstract cart creation and addition logic (#2126) * feat: Add wishlist modals, actions, and visibility switch (#2120) * Bump next to address CVE (#2132) * feat: Add wishlist modal defs, share button, and action dropdown menu (#2121) * chore: update pnpm to 10.6.5 (#2135) * Update translations (#2133) * feat(other): LOCAL-1444 delivery translation * chore(core): create translations patch --------- Co-authored-by: bc-svc-local <bc-svc-local@users.noreply.github.com> Co-authored-by: Jorge Moya <jorge.moya@bigcommerce.com> * chore: update node to version 22 (#2136) * chore: remove invalid changeset (#2139) * feat: Add wishlist pages (#2122) * fix(core): ignore errors in orders and render products without links (#2141) * fix: add `Streamable.from` to avoid eager promises (#2143) * feat: add Streamable.from * fix: use Streamable.from instead of eager promises * chore: update dependencies to latest minors (#2142) * feat: group 1 update for Soul form components (#2130) * feat(core): add store hash meta tag (#2147) * fix: dedupe default image in PDP (#2162) * feat: group 2 update for Soul form components (#2160) * fix: remove unused components (#2163) --------- Co-authored-by: Aleksey Gurtovoy <agurtovoy@acm.org> Co-authored-by: Chancellor Clark <chancellor.clark@bigcommerce.com> Co-authored-by: bc-svc-local <102379007+bc-svc-local@users.noreply.github.com> Co-authored-by: bc-svc-local <bc-svc-local@users.noreply.github.com> Co-authored-by: Roman Krasinskyi <49246595+RomanKrasinskyi@users.noreply.github.com> Co-authored-by: Nathan Booker <nathan.booker@bigcommerce.com> Co-authored-by: Hunter Garrett <hunter@hunterbecton.com> Co-authored-by: Jorge Moya <jorge.moya@bigcommerce.com> Co-authored-by: Daniel Almaguer <daniel.almaguer@bigcommerce.com> Co-authored-by: Jordan Arldt <jordan.arldt@bigcommerce.com> Co-authored-by: Nathan Booker <bookernath@users.noreply.github.com>
* fix: switching locales redirects user to the home page (#1990) * chore: add demo section to readme (#1996) * Update translations (#1993) * feat(other): LOCAL-1444 delivery translation * chore(core): create translations patch --------- Co-authored-by: bc-svc-local <bc-svc-local@users.noreply.github.com> * feat: manage locales when creating storefronts from the CLI (#1986) * feat: manage locales * Add changeset --------- Co-authored-by: Nathan Booker <nathan.booker@bigcommerce.com> * feat: add default Tailwind typography styles (#2007) * Update translations (#2004) * feat(other): LOCAL-1444 delivery translation * chore(core): create translations patch --------- Co-authored-by: bc-svc-local <bc-svc-local@users.noreply.github.com> * fix(core): handle registration errors in form (#2006) * chore(release): publish create-catalyst CLI (#2015) * chore: remove scoped version bump * chore(release): publish create-catalyst CLI * feat: add es-419 to list of allowed locale for selecting (#2017) * feat(cli): scaffold package (#2010) * fix(core): show coupon discounts as a separate summary item (#2084) * fix(core): show coupon discounts as a separate summary item * fix: typo in changeset * feat(core): add shipping options to checkout (#1997) * feat(core): add shipping options to checkout * fix: capitalization of Edit * fix: bump vibes * fix: update vibes * fix: remove else and early return * refactor: simplify logic by using a Set for countries * fix: hide forms visually * fix: add no shipping options message * fix: remove reduce and use Set, remove let variable * fix: split mutations * fix: disable complexity rule for Cart * Update translations (#2104) * feat(other): LOCAL-1444 delivery translation * chore(core): create translations patch --------- Co-authored-by: bc-svc-local <bc-svc-local@users.noreply.github.com> * refactor: update signin behavior to use different providers (#2103) * refactor: update signin behavior to use different providers * chore: add additional folders to lint task * feat: Sync Button and DynamicForm with VIBES (#2110) * feat(core): add compare functionality to PLP (#2060) * feat(core): migrate compare page to use soul * feat: hide compare checkbox dynamically * feat: pass in comparable products * fix: add optimistic items * feat: add optimistic to remove * feat: add optimistic to checkbox * fix: sort when added * fix: sort groups and use link to compare * fix: bump vibes components, fix button * fix: remove unused primitves breadcrumbs component * fix: sync vibes components * fix: wrap transitions and call optimistic before setParam * fix: validate with zod variables are correct * fix: expose remove label * fix: await setParam * fix: translate remove label: * fix: use parser and loader for compare * feat: alert when max compare limit is set, disable checkboxes * feat: Sync ProductCard and WishlistItemCard with VIBES (#2112) * feat: Sync Breadcrumbs (#2117) * feat: Add Wishlist VIBES components (#2118) * chore(security): add documentation around CSRF checks (#2114) * fix: set the trustHost value with an env var * chore(core): documentation around CSRF checks within next-auth * feat: Add wishlist translations, transformers, and core components (#2119) * fix(core): revert to ids search param in compare page (#2125) * feat(client): add errorPolicy option to GQL requests (#2124) * feat: add anonymous session with cart tracking (#2111) * refactor(core): abstract cart creation and addition logic (#2126) * feat: Add wishlist modals, actions, and visibility switch (#2120) * Bump next to address CVE (#2132) * feat: Add wishlist modal defs, share button, and action dropdown menu (#2121) * chore: update pnpm to 10.6.5 (#2135) * Update translations (#2133) * feat(other): LOCAL-1444 delivery translation * chore(core): create translations patch --------- Co-authored-by: bc-svc-local <bc-svc-local@users.noreply.github.com> Co-authored-by: Jorge Moya <jorge.moya@bigcommerce.com> * chore: update node to version 22 (#2136) * chore: remove invalid changeset (#2139) * feat: Add wishlist pages (#2122) * fix(core): ignore errors in orders and render products without links (#2141) * fix: add `Streamable.from` to avoid eager promises (#2143) * feat: add Streamable.from * fix: use Streamable.from instead of eager promises * chore: update dependencies to latest minors (#2142) * feat: group 1 update for Soul form components (#2130) * feat(core): add store hash meta tag (#2147) * fix: dedupe default image in PDP (#2162) * feat: group 2 update for Soul form components (#2160) * fix: remove unused components (#2163) --------- Co-authored-by: Aleksey Gurtovoy <agurtovoy@acm.org> Co-authored-by: Chancellor Clark <chancellor.clark@bigcommerce.com> Co-authored-by: bc-svc-local <102379007+bc-svc-local@users.noreply.github.com> Co-authored-by: bc-svc-local <bc-svc-local@users.noreply.github.com> Co-authored-by: Roman Krasinskyi <49246595+RomanKrasinskyi@users.noreply.github.com> Co-authored-by: Nathan Booker <nathan.booker@bigcommerce.com> Co-authored-by: Hunter Garrett <hunter@hunterbecton.com> Co-authored-by: Jorge Moya <jorge.moya@bigcommerce.com> Co-authored-by: Daniel Almaguer <daniel.almaguer@bigcommerce.com> Co-authored-by: Jordan Arldt <jordan.arldt@bigcommerce.com> Co-authored-by: Nathan Booker <bookernath@users.noreply.github.com>
What/Why?
Our
Streamablepattern relies on passing promises as props to RSCs and client components. For RSCs, it "pushes down" data fetching so that Next.js will mark particular components as dynamic when using PPR. For client components, it streams the data to the client while triggering a Suspense boundary.For the former case, we were getting the following error:
We believe the reason for this is that promises are eager, not lazy. This means that if we call an async function on an RSC, it will start executing even if the RSC that we pass the promise to hasn't rendered yet. In particular, if the execution calls
cookies(),await searchParamsor other dynamic APIs which throw, it results in the error above.This PR introduces
Streamable.fromwhich abstracts the idea of a "lazy promise", deferring execution until the first.thencall. It usesStreamable.fromanywhere we were calling an async function withoutawaitto avoid the unhandled rejection.Something particular about
Streamable.fromis that it allows us to refer to values via closure directly in the RSC, removing the need for creating async functions when using the streamable pattern. This PR purposefully keeps this out of scope and I plan to address this in a future PR.Furthermore, the implementation of
Streamable.fromis a simple wrapper aroundp-lazy. In a future PR, I intend to remove the dependency onp-lazyand have a custom implementation for lazy promises.This PR is pre-work for the move to PPR +
dynamicIOto better optimize caching and performance of Catalyst.Testing
CleanShot.2025-03-24.at.17.52.10.mp4