Repository navigation
Conversation
Discover cacheable methods from server declarations and invalidate client caches when declarations or connection state change. Preserve explicit cache options and reject stale in-flight cache writes.
|
@SaKaNa-Y is attempting to deploy a commit to the NuxtLabs Team on Vercel. A member of the Team first needs to authorize it. |
Clear failed discovery promises so later RPC calls can retry. Preserve newer discovery after invalidation and keep timed-out actions from running. Cover rejection, timeout recovery, and invalidation races over WebSocket and SSE. Align caching documentation with repository terminology.
|
👁️🗨️ Review this pull request with grouped, summarized diffs at: raw result💭 analyzed by {
"headSha": "0fa73c09a88286816f22bd895a7f3a7724665563",
"result": {
"overallSummary": "Fixes automatic RPC client caching, which previously had no effect because the client never populated its cache function list. The client now discovers cacheable methods from the node side, caches static and opted-in query responses by argument hash, and clears the cache on invalidation broadcasts, declaration changes, trust changes, disconnects, or close — while carefully tracking per-call deadlines across discovery retries to avoid dispatching expired calls (which could otherwise duplicate action side effects on retry).",
"groups": [
{
"key": "rpc-cache-core",
"label": "Automatic RPC caching",
"summary": "Implements automatic RPC client caching: the client discovers cacheable methods via a new `devframe:rpc:cacheable-functions` query, caches static/opted-in-query responses by argument hash, and clears its cache on a new `devframe:rpc:cache:invalidate` broadcast, declaration changes, trust changes, disconnects, and close. Each in-flight call keeps its own deadline across discovery retries so an expired call is never dispatched after rediscovery.",
"category": "api",
"filePaths": [
"packages/devframe/src/client/rpc.ts",
"packages/devframe/src/node/host-functions.ts",
"packages/devframe/src/events.ts",
"packages/devframe/src/types/rpc-augments.ts"
],
"critical": true,
"fileNotes": [
{
"path": "packages/devframe/src/client/rpc.ts",
"text": "Core of the fix: per-call deadline tracking across discovery retries, generation counters to ignore late discovery/cache writes after invalidation, and gating cache usage on trust/connection state.",
"critical": true
},
{
"path": "packages/devframe/src/node/host-functions.ts",
"text": "Node side now exposes the eligible-methods query and broadcasts cache invalidation whenever RPC definitions change (register/update)."
}
]
},
{
"key": "cache-tests",
"label": "RPC cache tests",
"summary": "New regression suite (28 tests over WebSocket and SSE) covering discovery, retries, per-call deadlines during invalidation, late responses, explicit function lists, custom serializers, legacy devframes without discovery, trust revocation, and close.",
"category": "tests",
"filePaths": [
"packages/devframe/src/client/rpc-cache.test.ts"
],
"critical": true
},
{
"key": "docs",
"label": "Caching docs",
"summary": "Documents the new `cacheOptions: true` discovery/invalidation behavior and the `devframe:rpc:cache:invalidate` broadcast event.",
"category": "docs",
"filePaths": [
"docs/content/1.guide/11.client.md",
"docs/content/8.references/3.events.md"
]
},
{
"key": "type-snapshots",
"label": "Type snapshot updates",
"summary": "Generated type snapshots regenerated to reflect the new `cacheInvalidate` event and `devframe:rpc:cacheable-functions`/`cache:invalidate` RPC function signatures.",
"category": "other",
"filePaths": [
"tests/__snapshots__/tsnapi/devframe/constants.snapshot.d.ts",
"tests/__snapshots__/tsnapi/devframe/index.snapshot.d.ts"
]
}
],
"schemaVersion": 1,
"source": "llm",
"generatedAt": "2026-10-07T05:37:19.520Z",
"model": "vercel-ai-gateway/anthropic/claude-sonnet-5",
"locale": "en"
}
} |
Keep each call within its original timeout across cache discovery refreshes. Stop expired calls before dispatch while allowing later retries to use the shared discovery result. Cover call and callOptional over WebSocket and SSE. All 28 cache tests and the full suite pass, along with lint, knip, typecheck, and build.
SaKaNa-Y
marked this pull request as ready for review
October 7, 2026 06:51
Contributor
Author
|
The query uses |
This branch has not been 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.
Important
Please take a moment to read this. Thank you!
I should include a brief explanation of the problem in my own words in every PR. If that explanation is missing, please @mention me and do not merge this PR until I have added it. You may also leave this PR unaddressed (because this means I have not fulfilled my responsibilities as the author).
If my explanation is unclear or difficult to follow, please ask me to clarify or provide reproduction steps or supporting evidence.
I welcome suggestions and counterarguments, especially questions about anything I may have overlooked. (Your feedback helps me learn and improve. 🙏)
I hold myself to this standard for every PR, regardless of its size.
Summary
Enabling
cacheOptions: truedoes not prevent repeated server execution for identical RPC calls. This affects static functions and queries declared withcacheable: true. The client creates a cache with an empty function list but never loads the server declarations. As a result, no function qualifies for automatic caching.This change lets the client request eligible function names from an authenticated server endpoint before sending a call. It then caches results by function name and arguments. Static functions and opted-in queries use the cache, while actions and events continue to execute. Explicit function lists and custom serializers remain supported.
The client clears cached results when declarations, connection status, or trust change, and when it closes. The server can also broadcast invalidation after data changes. Late responses cannot restore invalidated cache entries. Servers without the discovery endpoint continue to serve uncached calls.
The change also handles timeouts while the client discovers cacheable functions. If invalidation triggers repeated discovery, expired calls stop before dispatch. This prevents an expired action from executing alongside a later retry. Calls already sent retain their existing timeout behavior. Failed discovery rejects waiting calls, and a later call retries discovery.
Evidence
These results come from the completed verification runs. Tests were not rerun for this description update.
cacheOptions: true. An explicit function list returns the first result twice and executes the server function once.v1.2.3source, all 28 cache regression tests pass. A separate consumer using the packed package passes all 46 checks across WebSocket and SSE. Coverage includes real authentication, disconnects, invalidation, late responses, discovery timeouts, and explicit cache lists.@devframes/hub-ui-onboard. Both failures concerndefaultMessagesand also occur in the baseline CI run.Merge Danger
Door: Two-way. This change can be reverted.
Blast Radius: RPC caching. Automatic caching adds requests to discover eligible functions. Invalidation clears all cached results, including results cached through explicit function lists. The server must broadcast invalidation after changing data that cached queries read.