Skip to content

Commit 42ce5d4

Browse files
hi-ogawaOpenCode
andauthored
test(rsc): decrypt cache captures once in use cache example (#1403)
Co-authored-by: Hiroshi Ogawa <[email protected]> Co-authored-by: OpenCode <[email protected]>
1 parent cd829da commit 42ce5d4

2 files changed

Lines changed: 15 additions & 19 deletions

File tree

‎packages/plugin-rsc/examples/use-cache-callable/callable-cache-plugin.ts‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,9 @@ export function callableCachePlugin(): Plugin {
6060
runtime: (value, name, meta) =>
6161
runtime(value, name, getCacheWrapperOptions(meta)),
6262
encode: (value) => `$$encryptCacheCaptures(${value})`,
63-
decode: (value) => `await $$decryptCacheCaptures(${value})`,
63+
// The cache runtime replaces the envelope with decoded captures
64+
// before invoking this private implementation.
65+
decode: (value) => value,
6466
})
6567
if (!result.output.hasChanged()) {
6668
manager.serverReferences.deleteClaim(pluginName, id)
@@ -72,7 +74,7 @@ export function callableCachePlugin(): Plugin {
7274
exportNames: 'names' in result ? result.names : result.exportNames,
7375
})
7476
result.output.prepend(
75-
`import $$cacheWrapper, { encryptCacheCaptures as $$encryptCacheCaptures, decryptCacheCaptures as $$decryptCacheCaptures } from "/src/framework/use-cache-runtime";\n` +
77+
`import $$cacheWrapper, { encryptCacheCaptures as $$encryptCacheCaptures } from "/src/framework/use-cache-runtime";\n` +
7678
`import * as $$ReactServer from "@vitejs/plugin-rsc/react/rsc/server";\n`,
7779
)
7880
return {

‎packages/plugin-rsc/examples/use-cache-callable/src/framework/use-cache-runtime.tsx‎

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -64,24 +64,18 @@ export default function cacheWrapper(
6464
// "use cache static shell + dynamic children props" pattern.
6565
// cf. https://nextjs.org/docs/app/api-reference/directives/use-cache#non-serializable-arguments
6666
const clientTemporaryReferences = createClientTemporaryReferenceSet()
67-
const encodedArguments = await encodeReply(admittedArgs, {
68-
temporaryReferences: clientTemporaryReferences,
69-
})
70-
let encodedCacheArguments = encodedArguments
71-
// Re-encode decrypted captures so cache identity reflects their logical values
72-
// rather than the randomized ciphertext used by the transport arguments.
67+
let executionArguments = admittedArgs
7368
if (captureEnvelope) {
74-
// TODO: On a cache miss, the hoister-generated implementation decrypts the
75-
// original envelope again. A tighter adapter could reuse these captures.
76-
const cacheArguments = [
77-
...(await decryptCacheCaptures(captureEnvelope)),
78-
...admittedArgs.slice(1),
79-
]
80-
encodedCacheArguments = await encodeReply(cacheArguments, {
81-
temporaryReferences: createClientTemporaryReferenceSet(),
82-
})
69+
// Decrypt in the framework runtime so cache identity and execution share
70+
// these values; the transformed implementation only destructures the array.
71+
const captures = await decryptCacheCaptures(captureEnvelope)
72+
const invocationArguments = admittedArgs.slice(1)
73+
executionArguments = [captures, ...invocationArguments]
8374
}
84-
const serializedCacheKey = await replyToCacheKey(encodedCacheArguments)
75+
const encodedArguments = await encodeReply(executionArguments, {
76+
temporaryReferences: clientTemporaryReferences,
77+
})
78+
const serializedCacheKey = await replyToCacheKey(encodedArguments)
8579

8680
// cache `fn` result as stream
8781
// (cache value is promise so that it dedupes concurrent async calls)
@@ -180,7 +174,7 @@ export function encryptCacheCaptures(
180174
}
181175
}
182176

183-
export async function decryptCacheCaptures(
177+
async function decryptCacheCaptures(
184178
envelope: CacheCaptureEnvelope,
185179
): Promise<unknown[]> {
186180
const { encrypted } = envelope

0 commit comments

Comments
 (0)