diff --git a/.changeset/many-cycles-invite.md b/.changeset/many-cycles-invite.md new file mode 100644 index 0000000000..510bac770c --- /dev/null +++ b/.changeset/many-cycles-invite.md @@ -0,0 +1,5 @@ +--- +'@shopify/hydrogen': patch +--- + +Fix names and URLs shown for HIT/STALE items in the Subrequest Profiler. diff --git a/packages/hydrogen/src/cache/fetch.ts b/packages/hydrogen/src/cache/fetch.ts index d9f7880ed4..dc9c8bcc5e 100644 --- a/packages/hydrogen/src/cache/fetch.ts +++ b/packages/hydrogen/src/cache/fetch.ts @@ -108,9 +108,11 @@ export async function runWithCache( ...(typeof cacheKey === 'string' ? [cacheKey] : cacheKey), ]); - let debugData: DebugInfo; + let cachedDebugInfo: DebugInfo | undefined; + let userDebugInfo: DebugInfo | undefined; + const addDebugData = (info: AddDebugDataParam) => { - debugData = { + userDebugInfo = { displayName: info.displayName, url: info.response?.url, responseInit: { @@ -121,6 +123,20 @@ export async function runWithCache( }; }; + const mergeDebugInfo = () => ({ + ...cachedDebugInfo, + ...debugInfo, + url: + userDebugInfo?.url || + debugInfo?.url || + cachedDebugInfo?.url || + getKeyUrl(key), + displayName: + debugInfo?.displayName || + userDebugInfo?.displayName || + cachedDebugInfo?.displayName, + }); + const logSubRequestEvent = process.env.NODE_ENV === 'development' ? ({ @@ -133,20 +149,19 @@ export async function runWithCache( overrideStartTime?: number; }) => { globalThis.__H2O_LOG_EVENT?.({ + ...mergeDebugInfo(), eventType: 'subrequest', startTime: overrideStartTime || startTime, + endTime: Date.now(), cacheStatus, responsePayload: (result && result[0]) || result, - responseInit: (result && result[1]) || debugData?.responseInit, + responseInit: (result && result[1]) || userDebugInfo?.responseInit, cache: { status: cacheStatus, strategy: generateCacheControlHeader(strategy || {}), key, }, waitUntil, - ...debugInfo, - url: debugData?.url || debugInfo?.url || getKeyUrl(key), - displayName: debugInfo?.displayName || debugData?.displayName, }); } : undefined; @@ -158,11 +173,30 @@ export async function runWithCache( return result; } - const cachedItem = await getItemFromCache(cacheInstance, key); + type CachedItem = { + value: Awaited; + debugInfo?: DebugInfo; + }; + + const storeInCache = (value: CachedItem['value']) => + setItemInCache( + cacheInstance, + key, + { + value, + debugInfo: + process.env.NODE_ENV === 'development' ? mergeDebugInfo() : undefined, + } satisfies CachedItem, + strategy, + ); + + const cachedItem = await getItemFromCache(cacheInstance, key); // console.log('--- Cache', cachedItem ? 'HIT' : 'MISS'); - if (cachedItem) { - const [cachedResult, cacheInfo] = cachedItem; + if (cachedItem && typeof cachedItem[0] !== 'string') { + const [{value: cachedResult, debugInfo}, cacheInfo] = cachedItem; + cachedDebugInfo = debugInfo; + const cacheStatus = isStale(key, cacheInfo) ? 'STALE' : 'HIT'; if (!swrLock.has(key) && cacheStatus === 'STALE') { @@ -175,7 +209,7 @@ export async function runWithCache( const result = await actionFn({addDebugData}); if (shouldCacheResult(result)) { - await setItemInCache(cacheInstance, key, result, strategy); + await storeInCache(result); // Log PUT requests with the revalidate start time logSubRequestEvent?.({ @@ -220,9 +254,9 @@ export async function runWithCache( * Important: Do this async */ if (shouldCacheResult(result)) { - const setItemInCachePromise = Promise.resolve().then(async () => { + const cacheStoringPromise = Promise.resolve().then(async () => { const putStartTime = Date.now(); - await setItemInCache(cacheInstance, key, result, strategy); + await storeInCache(result); logSubRequestEvent?.({ result, cacheStatus: 'PUT', @@ -230,7 +264,7 @@ export async function runWithCache( }); }); - waitUntil?.(setItemInCachePromise); + waitUntil?.(cacheStoringPromise); } return result; diff --git a/packages/hydrogen/src/cache/sub-request.ts b/packages/hydrogen/src/cache/sub-request.ts index d221a0caf5..03ba8b2267 100644 --- a/packages/hydrogen/src/cache/sub-request.ts +++ b/packages/hydrogen/src/cache/sub-request.ts @@ -35,10 +35,10 @@ export function generateSubRequestCacheControlHeader( * as the response itself so it can be checked for staleness. * @private */ -export async function getItemFromCache( +export async function getItemFromCache( cache: Cache, key: string, -): Promise { +): Promise { if (!cache) return; const url = getKeyUrl(key); const request = new Request(url); diff --git a/packages/hydrogen/src/storefront.ts b/packages/hydrogen/src/storefront.ts index ba861fe35c..a390ed769e 100644 --- a/packages/hydrogen/src/storefront.ts +++ b/packages/hydrogen/src/storefront.ts @@ -329,12 +329,12 @@ export function createStorefrontClient( shouldCacheResponse: checkGraphQLErrors, waitUntil, debugInfo: { + requestId: requestInit.headers[STOREFRONT_REQUEST_GROUP_ID_HEADER], + displayName, url, + stackInfo, graphql: graphqlData, - requestId: requestInit.headers[STOREFRONT_REQUEST_GROUP_ID_HEADER], purpose: storefrontHeaders?.purpose, - stackInfo, - displayName, }, });