Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support withCache in debug-network for workerd #1438

Merged
merged 2 commits into from
Oct 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions .changeset/unlucky-wolves-sing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
'@shopify/hydrogen': patch
---

Calls to `withCache` can now be shown in the `/debug-network` tool when using the Worker runtime. For this to work, use the new `request` parameter in `createWithCache`:

```diff
export default {
fetch(request, env, executionContext) {
// ...
const withCache = createWithCache({
cache,
waitUntil,
+ request,
});
// ...
},
}
```
4 changes: 2 additions & 2 deletions packages/hydrogen/src/cache/fetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ import {
export type CacheKey = string | readonly unknown[];

export type FetchDebugInfo = {
requestId?: string;
graphql?: string;
requestId?: string | null;
graphql?: string | null;
purpose?: string | null;
};

Expand Down
3 changes: 2 additions & 1 deletion packages/hydrogen/src/with-cache.example.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ export default {
const cache = await caches.open('my-cms');
const withCache = createWithCache({
cache,
waitUntil: executionContext.waitUntil,
waitUntil: executionContext.waitUntil.bind(executionContext),
request,
});

// Create a custom utility to query a third-party API:
Expand Down
3 changes: 2 additions & 1 deletion packages/hydrogen/src/with-cache.example.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ export default {
const cache = await caches.open('my-cms');
const withCache = createWithCache({
cache,
waitUntil: executionContext.waitUntil,
waitUntil: executionContext.waitUntil.bind(executionContext),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we losing this context without the bind?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we already use .bind in all our templates so I just updated it here as well.

request,
});

// Create a custom utility to query a third-party API:
Expand Down
28 changes: 23 additions & 5 deletions packages/hydrogen/src/with-cache.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,39 @@
import {type CacheKey, runWithCache} from './cache/fetch';
import type {CachingStrategy} from './cache/strategies';

type CrossRuntimeRequest = {
headers: {
get?: (key: string) => string | null | undefined;
[key: string]: any;
};
};

type CreateWithCacheOptions = {
/** An instance that implements the [Cache API](https://developer.mozilla.org/en-US/docs/Web/API/Cache) */
cache: Cache;
/** The `waitUntil` function is used to keep the current request/response lifecycle alive even after a response has been sent. It should be provided by your platform. */
waitUntil: ExecutionContext['waitUntil'];
/** The `request` object is used to access certain headers for debugging */
request?: CrossRuntimeRequest;
};

function getHeader(key: string, request?: CrossRuntimeRequest) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't request just type Request?

Copy link
Contributor Author

@frandiox frandiox Oct 19, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In Oxygen yes but in Node environments they will be passing IncomingMessage (import type {IncomingMessage} from 'node:http'), I think? And the headers there doesn't have a get function, you just read like in an object.

I assume Bun and Deno probably have similar APIs for requests, either Web-like or Node-like, but maybe with different type name.

const value = request?.headers?.get?.(key) ?? request?.headers?.[key];
return typeof value === 'string' ? value : undefined;
}

/**
* Creates a utility function that executes an asynchronous operation
* like `fetch` and caches the result according to the strategy provided.
* Use this to call any third-party APIs from loaders or actions.
* By default, it uses the `CacheShort` strategy.
*
*/
export function createWithCache<T = unknown>(
options: CreateWithCacheOptions,
): CreateWithCacheReturn<T> {
const {cache, waitUntil} = options;
export function createWithCache<T = unknown>({
cache,
waitUntil,
request,
}: CreateWithCacheOptions): CreateWithCacheReturn<T> {
return function withCache<T = unknown>(
cacheKey: CacheKey,
strategy: CachingStrategy,
Expand All @@ -28,7 +43,10 @@ export function createWithCache<T = unknown>(
strategy,
cacheInstance: cache,
waitUntil,
debugInfo: {},
debugInfo: {
requestId: getHeader('request-id', request),
purpose: getHeader('purpose', request),
},
});
};
}
Expand Down
Loading