feat: Support async resource dependencies - #6030
Merged
Merged
Conversation
kof
marked this pull request as ready for review
August 7, 2026 17:57
kof
force-pushed
the
agent/async-resource-dependencies-6029
branch
3 times, most recently
from
August 13, 2026 19:36
205916b to
3d74b34
Compare
kof
force-pushed
the
agent/async-resource-dependencies-6029
branch
2 times, most recently
from
August 31, 2026 16:44
2982506 to
57496a9
Compare
kof
force-pushed
the
agent/async-resource-dependencies-6029
branch
from
September 18, 2026 15:47
db469e4 to
c710522
Compare
kof
force-pushed
the
agent/async-resource-dependencies-6029
branch
from
September 22, 2026 17:21
2287ffa to
858b348
Compare
9 tasks
kof
added a commit
that referenced
this pull request
Sep 23, 2026
New resources can fail to show data in the **New variable** dialog because a page-plan refresh cancels their preview request before it finishes. This change keeps explicitly requested previews alive until the dialog releases them. Changing inputs, changing resource type, or closing the dialog cancels obsolete work and prevents old data from showing. Unused page resources remain lazy; a preview still makes an on-demand request when **Load data** is clicked. The dialog stays usable while unrelated page resources are loading. Follow-up to #6030. ### Checklist - [x] Reproduce the cancellation with a regression test that fails before the fix. - [x] Keep dialog previews independent of page resource discovery, using the existing loader, cache, and request versions. - [x] Clear old previews on input changes and release requests on dialog close. - [x] Cover new Current date, Sitemap, HTTP, and existing unbound resources, plus repeated loads and stale responses. - [x] Keep tests for obsolete page-request cancellation and async resource dependencies passing. - [x] Test the unsaved dialog with an unrelated page request pending and a page-plan recalculation. - [x] Clear the old preview when switching resource types or starting an asynchronous body edit. - [x] Review documentation impact: no update needed; this restores the documented preview behavior. - [ ] Confirm GitHub CI passes. ### Verification - The dialog loading, type-switch, and body-edit regression tests failed before their fixes and passed afterward. - 82 focused tests and the settings-panel suite (588 tests) passed. - Builder typecheck and repository lint passed. - With preview retention temporarily disabled, all nine new loader regression cases failed as expected.
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Make
Resource<Document>the lazy document-resolution abstraction shared by Content Engine graphs, generated sites, and Builder previews. Expressions use one async computation interface: referenced resource documents resolve first, independent requests run concurrently, and unused resources stay unloaded.Ref #6029
Ref #6031
Implementation checklist
Define one resource contract for synchronous or asynchronous document resolution.
Resolve explicit roots lazily with memoization, bounded concurrency, cancellation, and structured errors.
Preserve cycle, duplicate, and missing-resource diagnostics.
Extract resource dependencies with the existing expression AST.
Discover consumed resource roots from the current page tree and page metadata.
Generate a lazy request graph for published page data, including independent requests.
Resolve dependency documents before evaluating dependent request expressions.
Integrate dependency-first loading with Builder preview caching and invalidation.
Expose safe Resource bindings in the editor and reject self/indirect cycles.
Adapt REST, GraphQL, Assets, date, and sitemap requests through the same Resource contract.
Cover laziness, chains, shared dependencies, concurrency, invalidation, cancellation, failures, and cycles with fail/pass tests.
Review documentation impact and document dependent Resources in the Data variables guide.
Track collection-item and component-parameter-dependent resources as follow-up Support per-render scoped Resource dependencies #6031.
Regenerate and review affected fixtures.
Resolve action-resource request dependencies when an action is invoked.
Reproduce and fix cached form submissions and multi-root dependency-cycle hangs.
Document uncached form actions and regenerate affected fixtures.
Preserve single and multi-selected content until a cut successfully writes to the clipboard.
Preserve boolean expression values in the search-exclusion checkbox.
Cancel cut deletion if project data changes while preparing or writing the clipboard; cover content/property edits and project switches for single and multi-selection, and document the retry behavior.
Validate pending cuts after the final await, immediately before deletion, and reproduce the queued-update race for single and multi-selection.
Technical direction
The persisted, revisioned
DocumentGraphremains the Content Engine artifact.Resource<Document>is the execution abstraction for obtaining a document; its resolver evaluates only the dependency closure reachable from requested roots. Static and remote documents therefore differ by Resource implementation, not by expression value type.Generated pages always emit a
ResourceRequestGraph. Each node owns its output name, dependencies, and request factory. Roots come from resource variables actually referenced by the current page's metadata, props, actions, or expression children. Unused and off-page resources remain unresolved. The loader still accepts legacy request maps for compatibility.Builder preview uses the same page-root discovery as published generation. Its existing cache remains the lifecycle boundary: cached dependency documents unlock dependent requests, while invalidation removes downstream requests until their inputs resolve again. The separate canvas frame recomputes its local plan from the synchronized cache so rendered expressions receive those documents.
Action requests and their dependencies resolve when a form is submitted. Each submission sends a new action request, bypassing Webstudio's resource cache. Dependency requests still use their configured cache lifetime.
Review simplifications
Resource.resolvealready acceptsDocument | Promise<Document>.Verification
Latest local verification for
bbca6395e3:Previous local verification for
ffbc75b152:Previous local verification for
3eb580697c:Previous local verification for
858b348ad, rebased ontocf606ca4c:858b348adpassed: Main (including all six E2E shards), Visual Regression, Lint PR, and Check submodules.Earlier verification (before this update):
TDD fail/pass evidence includes resolver creation, AST dependency discovery, published graph reachability, dependency-gated request generation, Builder dependency-first planning, Resource editor cycle filtering, page-tree root scoping, off-page action isolation, transitive Resource-only cycle discovery, abort/timeout precedence, server batch limits, and the rebased SSG fixture consuming its lazy Resource.
pnpm checkspassed after rebasing ontoce84ddcf12; it covered workspace tests, typechecks, lint, package boundaries, generated API/docs validation, and fixture link/sync/build.git diff --check.6b8b08a70passed: Main workflow (including all six Builder E2E shards), Visual Regression, Lint PR, and Check submodules.Current behavior and limitations