@shopify/hydrogen 0.11.0-experimental.1 → 0.11.1-experimental.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +504 -0
- package/dist/esnext/client.d.ts +1 -1
- package/dist/esnext/client.js +1 -1
- package/dist/esnext/components/AddToCartButton/AddToCartButton.client.d.ts +1 -1
- package/dist/esnext/components/AddToCartButton/AddToCartButton.client.js +11 -2
- package/dist/esnext/components/CartEstimatedCost/CartEstimatedCost.client.js +1 -1
- package/dist/esnext/components/CartLineImage/CartLineImage.client.js +2 -2
- package/dist/esnext/components/CartLinePrice/CartLinePrice.client.d.ts +1 -1
- package/dist/esnext/components/CartLinePrice/CartLinePrice.client.js +1 -1
- package/dist/esnext/components/CartProvider/CartProvider.client.d.ts +2 -2
- package/dist/esnext/components/CartProvider/CartProvider.client.js +1 -1
- package/dist/esnext/components/ExternalVideo/ExternalVideo.d.ts +1 -1
- package/dist/esnext/components/ExternalVideo/ExternalVideo.js +2 -2
- package/dist/esnext/components/Image/Image.d.ts +1 -1
- package/dist/esnext/components/Image/Image.js +9 -9
- package/dist/esnext/components/LocalizationProvider/LocalizationProvider.server.d.ts +13 -4
- package/dist/esnext/components/LocalizationProvider/LocalizationProvider.server.js +5 -3
- package/dist/esnext/components/MediaFile/MediaFile.d.ts +8 -6
- package/dist/esnext/components/MediaFile/MediaFile.js +6 -6
- package/dist/esnext/components/Metafield/Metafield.client.d.ts +1 -1
- package/dist/esnext/components/Metafield/Metafield.client.js +16 -16
- package/dist/esnext/components/ModelViewer/ModelViewer.client.d.ts +1 -1
- package/dist/esnext/components/ModelViewer/ModelViewer.client.js +1 -1
- package/dist/esnext/components/Money/Money.client.d.ts +1 -1
- package/dist/esnext/components/Money/Money.client.js +2 -2
- package/dist/esnext/components/ProductMetafield/ProductMetafield.client.d.ts +3 -1
- package/dist/esnext/components/ProductMetafield/ProductMetafield.client.js +21 -4
- package/dist/esnext/components/ProductPrice/ProductPrice.client.d.ts +5 -3
- package/dist/esnext/components/ProductPrice/ProductPrice.client.js +30 -9
- package/dist/esnext/components/ProductProvider/ProductOptionsProvider.client.d.ts +8 -0
- package/dist/esnext/components/ProductProvider/ProductOptionsProvider.client.js +12 -0
- package/dist/esnext/components/ProductProvider/ProductProvider.client.d.ts +8 -7
- package/dist/esnext/components/ProductProvider/ProductProvider.client.js +9 -35
- package/dist/esnext/components/ProductProvider/context.d.ts +10 -6
- package/dist/esnext/components/ProductProvider/context.js +1 -0
- package/dist/esnext/components/Seo/DefaultPageSeo.client.js +2 -2
- package/dist/esnext/components/Seo/DescriptionSeo.client.js +2 -2
- package/dist/esnext/components/Seo/HomePageSeo.client.js +2 -2
- package/dist/esnext/components/Seo/ImageSeo.client.js +2 -2
- package/dist/esnext/components/Seo/ProductSeo.client.js +5 -3
- package/dist/esnext/components/Seo/TitleSeo.client.js +2 -2
- package/dist/esnext/components/Seo/TwitterSeo.client.js +2 -2
- package/dist/esnext/components/Seo/types.d.ts +1 -1
- package/dist/esnext/components/UnitPrice/UnitPrice.client.d.ts +2 -2
- package/dist/esnext/components/UnitPrice/UnitPrice.client.js +3 -3
- package/dist/esnext/components/Video/Video.d.ts +1 -1
- package/dist/esnext/components/Video/Video.js +3 -3
- package/dist/esnext/components/index.d.ts +0 -8
- package/dist/esnext/components/index.js +0 -8
- package/dist/esnext/entry-client.js +1 -1
- package/dist/esnext/entry-server.d.ts +18 -2
- package/dist/esnext/entry-server.js +347 -329
- package/dist/esnext/foundation/Head/Head.client.d.ts +5 -0
- package/dist/esnext/foundation/Head/Head.client.js +10 -0
- package/dist/esnext/foundation/Head/index.d.ts +1 -0
- package/dist/esnext/foundation/Head/index.js +1 -0
- package/dist/esnext/foundation/ServerRequestProvider/ServerRequestProvider.d.ts +2 -1
- package/dist/esnext/foundation/ServerRequestProvider/ServerRequestProvider.js +43 -4
- package/dist/esnext/foundation/useQuery/hooks.d.ts +11 -3
- package/dist/esnext/foundation/useQuery/hooks.js +21 -5
- package/dist/esnext/framework/CachingStrategy/index.d.ts +10 -0
- package/dist/esnext/framework/CachingStrategy/index.js +96 -0
- package/dist/esnext/framework/Hydration/Html.js +5 -12
- package/dist/esnext/framework/Hydration/ServerComponentRequest.server.d.ts +20 -2
- package/dist/esnext/framework/Hydration/ServerComponentRequest.server.js +51 -2
- package/dist/esnext/framework/Hydration/ServerComponentResponse.server.d.ts +2 -2
- package/dist/esnext/framework/Hydration/ServerComponentResponse.server.js +2 -11
- package/dist/esnext/framework/cache/in-memory.js +6 -5
- package/dist/esnext/framework/cache.d.ts +3 -3
- package/dist/esnext/framework/cache.js +4 -18
- package/dist/esnext/framework/middleware.d.ts +7 -7
- package/dist/esnext/framework/middleware.js +15 -43
- package/dist/esnext/framework/plugin.js +14 -3
- package/dist/esnext/framework/plugins/vite-plugin-hydration-auto-import.d.ts +3 -0
- package/dist/esnext/framework/plugins/vite-plugin-hydration-auto-import.js +38 -0
- package/dist/esnext/framework/plugins/vite-plugin-hydrogen-client-middleware.d.ts +9 -0
- package/dist/esnext/framework/plugins/vite-plugin-hydrogen-client-middleware.js +37 -0
- package/dist/esnext/framework/plugins/vite-plugin-hydrogen-middleware.d.ts +2 -1
- package/dist/esnext/framework/plugins/vite-plugin-hydrogen-middleware.js +3 -1
- package/dist/esnext/framework/plugins/vite-plugin-platform-entry.d.ts +3 -0
- package/dist/esnext/framework/plugins/vite-plugin-platform-entry.js +70 -0
- package/dist/esnext/hooks/useProduct/useProduct.d.ts +150 -1
- package/dist/esnext/hooks/useProduct/useProduct.js +36 -3
- package/dist/esnext/hooks/useProductOptions/types.d.ts +1 -1
- package/dist/esnext/hooks/useProductOptions/useProductOptions.d.ts +1 -1
- package/dist/esnext/hooks/useProductOptions/useProductOptions.js +6 -6
- package/dist/esnext/hooks/useShopQuery/hooks.d.ts +11 -4
- package/dist/esnext/hooks/useShopQuery/hooks.js +6 -3
- package/dist/esnext/index.d.ts +2 -1
- package/dist/esnext/index.js +2 -1
- package/dist/esnext/platforms/node.d.ts +10 -0
- package/dist/esnext/platforms/node.js +38 -0
- package/dist/esnext/platforms/worker-event.d.ts +9 -0
- package/dist/esnext/platforms/worker-event.js +24 -0
- package/dist/esnext/streaming.server.d.ts +17 -7
- package/dist/esnext/streaming.server.js +44 -0
- package/dist/esnext/types.d.ts +25 -25
- package/dist/esnext/utilities/apiRoutes.d.ts +1 -2
- package/dist/esnext/utilities/apiRoutes.js +4 -3
- package/dist/esnext/utilities/bot-ua.d.ts +4 -0
- package/dist/esnext/utilities/bot-ua.js +54 -0
- package/dist/esnext/utilities/fetch.js +1 -26
- package/dist/esnext/utilities/log/index.d.ts +4 -1
- package/dist/esnext/utilities/log/index.js +4 -1
- package/dist/esnext/utilities/log/log-cache-api-status.d.ts +1 -0
- package/dist/esnext/utilities/log/log-cache-api-status.js +9 -0
- package/dist/esnext/utilities/log/log-cache-header.d.ts +10 -0
- package/dist/esnext/utilities/log/log-cache-header.js +30 -0
- package/dist/esnext/utilities/log/log-query-timeline.d.ts +12 -0
- package/dist/esnext/utilities/log/log-query-timeline.js +83 -0
- package/dist/esnext/utilities/log/log.d.ts +11 -8
- package/dist/esnext/utilities/log/log.js +24 -35
- package/dist/esnext/utilities/log/utils.d.ts +3 -0
- package/dist/esnext/utilities/log/utils.js +13 -0
- package/dist/esnext/utilities/template.d.ts +9 -0
- package/dist/esnext/utilities/template.js +23 -0
- package/dist/{worker/foundation/ShopifyProvider/types.js → esnext/utilities/web-api-polyfill.d.ts} +0 -0
- package/dist/esnext/utilities/web-api-polyfill.js +19 -0
- package/dist/esnext/version.d.ts +1 -1
- package/dist/esnext/version.js +1 -1
- package/dist/node/entry-server.d.ts +22 -0
- package/dist/node/entry-server.js +581 -0
- package/dist/node/foundation/ServerRequestProvider/ServerRequestProvider.d.ts +23 -0
- package/dist/node/foundation/ServerRequestProvider/ServerRequestProvider.js +132 -0
- package/dist/node/foundation/ServerRequestProvider/index.d.ts +1 -0
- package/dist/node/foundation/ServerRequestProvider/index.js +13 -0
- package/dist/node/foundation/ServerStateProvider/ServerStateProvider.client.d.ts +25 -0
- package/dist/node/foundation/ServerStateProvider/ServerStateProvider.client.js +68 -0
- package/dist/node/foundation/ServerStateProvider/index.d.ts +2 -0
- package/dist/node/foundation/ServerStateProvider/index.js +6 -0
- package/dist/node/framework/CachingStrategy/index.d.ts +10 -0
- package/dist/node/framework/CachingStrategy/index.js +108 -0
- package/dist/node/framework/Hydration/Html.js +5 -12
- package/dist/node/framework/Hydration/ServerComponentRequest.server.d.ts +20 -2
- package/dist/node/framework/Hydration/ServerComponentRequest.server.js +50 -1
- package/dist/node/framework/Hydration/ServerComponentResponse.server.d.ts +2 -2
- package/dist/node/framework/Hydration/ServerComponentResponse.server.js +2 -11
- package/dist/node/framework/cache/in-memory.js +6 -5
- package/dist/node/framework/cache.d.ts +3 -3
- package/dist/node/framework/cache.js +6 -20
- package/dist/node/framework/middleware.d.ts +7 -7
- package/dist/node/framework/middleware.js +14 -46
- package/dist/node/framework/plugin.js +33 -3
- package/dist/node/framework/plugins/vite-plugin-hydration-auto-import.d.ts +3 -0
- package/dist/node/framework/plugins/vite-plugin-hydration-auto-import.js +43 -0
- package/dist/node/framework/plugins/vite-plugin-hydrogen-client-middleware.d.ts +9 -0
- package/dist/node/framework/plugins/vite-plugin-hydrogen-client-middleware.js +39 -0
- package/dist/node/framework/plugins/vite-plugin-hydrogen-middleware.d.ts +2 -1
- package/dist/node/framework/plugins/vite-plugin-hydrogen-middleware.js +4 -1
- package/dist/node/framework/plugins/vite-plugin-platform-entry.d.ts +3 -0
- package/dist/node/framework/plugins/vite-plugin-platform-entry.js +75 -0
- package/dist/node/streaming.server.d.ts +21 -0
- package/dist/node/streaming.server.js +59 -0
- package/dist/node/types.d.ts +25 -25
- package/dist/node/utilities/apiRoutes.d.ts +1 -2
- package/dist/node/utilities/apiRoutes.js +4 -3
- package/dist/node/utilities/bot-ua.d.ts +4 -0
- package/dist/node/utilities/bot-ua.js +58 -0
- package/dist/node/utilities/defer.d.ts +6 -0
- package/dist/node/utilities/defer.js +18 -0
- package/dist/node/utilities/error.d.ts +1 -0
- package/dist/node/utilities/error.js +10 -0
- package/dist/node/utilities/log/index.d.ts +4 -0
- package/dist/node/utilities/log/index.js +18 -0
- package/dist/node/utilities/log/log-cache-api-status.d.ts +1 -0
- package/dist/node/utilities/log/log-cache-api-status.js +13 -0
- package/dist/node/utilities/log/log-cache-header.d.ts +10 -0
- package/dist/node/utilities/log/log-cache-header.js +35 -0
- package/dist/node/utilities/log/log-query-timeline.d.ts +12 -0
- package/dist/node/utilities/log/log-query-timeline.js +88 -0
- package/dist/node/utilities/log/log.d.ts +11 -8
- package/dist/node/utilities/log/log.js +27 -37
- package/dist/node/utilities/log/utils.d.ts +3 -0
- package/dist/node/utilities/log/utils.js +18 -0
- package/dist/node/utilities/template.d.ts +9 -0
- package/dist/node/utilities/template.js +27 -0
- package/dist/{worker/types.js → node/utilities/web-api-polyfill.d.ts} +0 -0
- package/dist/node/utilities/web-api-polyfill.js +43 -0
- package/package.json +20 -10
- package/web-polyfills.js +1 -0
- package/LICENSE.md +0 -7
- package/dist/esnext/components/CartLineAttributes/CartLineAttributes.client.d.ts +0 -22
- package/dist/esnext/components/CartLineAttributes/CartLineAttributes.client.js +0 -13
- package/dist/esnext/components/CartLineAttributes/index.d.ts +0 -1
- package/dist/esnext/components/CartLineAttributes/index.js +0 -1
- package/dist/esnext/components/CartLineSelectedOptions/CartLineSelectedOptions.client.d.ts +0 -21
- package/dist/esnext/components/CartLineSelectedOptions/CartLineSelectedOptions.client.js +0 -13
- package/dist/esnext/components/CartLineSelectedOptions/index.d.ts +0 -1
- package/dist/esnext/components/CartLineSelectedOptions/index.js +0 -1
- package/dist/esnext/components/SelectedVariantAddToCartButton/SelectedVariantAddToCartButton.client.d.ts +0 -11
- package/dist/esnext/components/SelectedVariantAddToCartButton/SelectedVariantAddToCartButton.client.js +0 -17
- package/dist/esnext/components/SelectedVariantAddToCartButton/index.d.ts +0 -1
- package/dist/esnext/components/SelectedVariantAddToCartButton/index.js +0 -1
- package/dist/esnext/components/SelectedVariantBuyNowButton/SelectedVariantBuyNowButton.d.ts +0 -9
- package/dist/esnext/components/SelectedVariantBuyNowButton/SelectedVariantBuyNowButton.js +0 -17
- package/dist/esnext/components/SelectedVariantBuyNowButton/index.d.ts +0 -1
- package/dist/esnext/components/SelectedVariantBuyNowButton/index.js +0 -1
- package/dist/esnext/components/SelectedVariantImage/SelectedVariantImage.client.d.ts +0 -10
- package/dist/esnext/components/SelectedVariantImage/SelectedVariantImage.client.js +0 -16
- package/dist/esnext/components/SelectedVariantImage/index.d.ts +0 -1
- package/dist/esnext/components/SelectedVariantImage/index.js +0 -1
- package/dist/esnext/components/SelectedVariantMetafield/SelectedVariantMetafield.client.d.ts +0 -15
- package/dist/esnext/components/SelectedVariantMetafield/SelectedVariantMetafield.client.js +0 -24
- package/dist/esnext/components/SelectedVariantMetafield/index.d.ts +0 -1
- package/dist/esnext/components/SelectedVariantMetafield/index.js +0 -1
- package/dist/esnext/components/SelectedVariantPrice/SelectedVariantPrice.client.d.ts +0 -12
- package/dist/esnext/components/SelectedVariantPrice/SelectedVariantPrice.client.js +0 -22
- package/dist/esnext/components/SelectedVariantPrice/index.d.ts +0 -1
- package/dist/esnext/components/SelectedVariantPrice/index.js +0 -1
- package/dist/esnext/components/SelectedVariantShopPayButton/SelectedVariantShopPayButton.client.d.ts +0 -8
- package/dist/esnext/components/SelectedVariantShopPayButton/SelectedVariantShopPayButton.client.js +0 -18
- package/dist/esnext/components/SelectedVariantShopPayButton/index.d.ts +0 -1
- package/dist/esnext/components/SelectedVariantShopPayButton/index.js +0 -1
- package/dist/esnext/components/SelectedVariantUnitPrice/SelectedVariantUnitPrice.client.d.ts +0 -7
- package/dist/esnext/components/SelectedVariantUnitPrice/SelectedVariantUnitPrice.client.js +0 -16
- package/dist/esnext/components/SelectedVariantUnitPrice/index.d.ts +0 -1
- package/dist/esnext/components/SelectedVariantUnitPrice/index.js +0 -1
- package/dist/esnext/foundation/Helmet/Helmet.client.d.ts +0 -10
- package/dist/esnext/foundation/Helmet/Helmet.client.js +0 -10
- package/dist/esnext/foundation/Helmet/index.d.ts +0 -1
- package/dist/esnext/foundation/Helmet/index.js +0 -1
- package/dist/esnext/handle-event.d.ts +0 -23
- package/dist/esnext/handle-event.js +0 -132
- package/dist/esnext/handle-worker-event.d.ts +0 -11
- package/dist/esnext/handle-worker-event.js +0 -14
- package/dist/node/foundation/Helmet/Helmet.client.d.ts +0 -10
- package/dist/node/foundation/Helmet/Helmet.client.js +0 -17
- package/dist/node/foundation/Helmet/index.d.ts +0 -1
- package/dist/node/foundation/Helmet/index.js +0 -5
- package/dist/node/foundation/ssr-interop.d.ts +0 -29
- package/dist/node/foundation/ssr-interop.js +0 -39
- package/dist/node/handle-event.d.ts +0 -23
- package/dist/node/handle-event.js +0 -135
- package/dist/worker/constants.d.ts +0 -1
- package/dist/worker/constants.js +0 -1
- package/dist/worker/foundation/Helmet/Helmet.client.d.ts +0 -10
- package/dist/worker/foundation/Helmet/Helmet.client.js +0 -10
- package/dist/worker/foundation/Helmet/index.d.ts +0 -1
- package/dist/worker/foundation/Helmet/index.js +0 -1
- package/dist/worker/foundation/ShopifyProvider/types.d.ts +0 -15
- package/dist/worker/foundation/ssr-interop.d.ts +0 -29
- package/dist/worker/foundation/ssr-interop.js +0 -35
- package/dist/worker/framework/Hydration/ServerComponentRequest.server.d.ts +0 -23
- package/dist/worker/framework/Hydration/ServerComponentRequest.server.js +0 -57
- package/dist/worker/framework/config.d.ts +0 -6
- package/dist/worker/framework/config.js +0 -6
- package/dist/worker/framework/runtime.d.ts +0 -13
- package/dist/worker/framework/runtime.js +0 -27
- package/dist/worker/graphql/types/types.d.ts +0 -5761
- package/dist/worker/graphql/types/types.js +0 -1436
- package/dist/worker/handle-event.d.ts +0 -23
- package/dist/worker/handle-event.js +0 -132
- package/dist/worker/handle-worker-event.d.ts +0 -11
- package/dist/worker/handle-worker-event.js +0 -14
- package/dist/worker/types.d.ts +0 -96
- package/dist/worker/utilities/apiRoutes.d.ts +0 -21
- package/dist/worker/utilities/apiRoutes.js +0 -87
- package/dist/worker/utilities/log/log.d.ts +0 -18
- package/dist/worker/utilities/log/log.js +0 -77
- package/dist/worker/utilities/matchPath.d.ts +0 -10
- package/dist/worker/utilities/matchPath.js +0 -54
- package/dist/worker/utilities/timing.d.ts +0 -7
- package/dist/worker/utilities/timing.js +0 -14
- package/worker.js +0 -1
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Helmet, HelmetData as HeadData, } from 'react-helmet-async';
|
|
3
|
+
import { useEnvContext } from '../ssr-interop';
|
|
4
|
+
const clientHeadData = new HeadData({});
|
|
5
|
+
export function Head({ children, ...props }) {
|
|
6
|
+
const headData = useEnvContext((req) => req.ctx.head, clientHeadData);
|
|
7
|
+
return (
|
|
8
|
+
// @ts-ignore
|
|
9
|
+
React.createElement(Helmet, { ...props, helmetData: headData }, children));
|
|
10
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Head } from './Head.client';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Head } from './Head.client';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ServerComponentRequest } from '../../framework/Hydration/ServerComponentRequest.server';
|
|
1
|
+
import type { PreloadQueriesByURL, ServerComponentRequest } from '../../framework/Hydration/ServerComponentRequest.server';
|
|
2
2
|
import type { QueryKey } from '../../types';
|
|
3
3
|
declare type ServerRequestProviderProps = {
|
|
4
4
|
isRSC: boolean;
|
|
@@ -19,4 +19,5 @@ declare type RequestCacheResult<T> = {
|
|
|
19
19
|
* It will throw the promise if data is not ready.
|
|
20
20
|
*/
|
|
21
21
|
export declare function useRequestCacheData<T>(key: QueryKey, fetcher: () => Promise<T>): RequestCacheResult<T>;
|
|
22
|
+
export declare function preloadRequestCacheData(request: ServerComponentRequest, preloadQueries?: PreloadQueriesByURL): void;
|
|
22
23
|
export {};
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import React, { createContext, useContext } from 'react';
|
|
2
|
+
import { getTime } from '../../utilities/timing';
|
|
2
3
|
import { hashKey } from '../../framework/cache';
|
|
4
|
+
import { collectQueryTimings } from '../../utilities/log';
|
|
3
5
|
// Context to inject current request in SSR
|
|
4
6
|
const RequestContextSSR = createContext(null);
|
|
5
7
|
// Cache to inject current request in RSC
|
|
@@ -49,19 +51,56 @@ export function useServerRequest() {
|
|
|
49
51
|
* It will throw the promise if data is not ready.
|
|
50
52
|
*/
|
|
51
53
|
export function useRequestCacheData(key, fetcher) {
|
|
52
|
-
const
|
|
54
|
+
const request = useServerRequest();
|
|
55
|
+
const cache = request.ctx.cache;
|
|
53
56
|
const cacheKey = hashKey(key);
|
|
54
57
|
if (!cache.has(cacheKey)) {
|
|
55
58
|
let data;
|
|
56
59
|
let promise;
|
|
57
60
|
cache.set(cacheKey, () => {
|
|
58
|
-
if (data !== undefined)
|
|
61
|
+
if (data !== undefined) {
|
|
62
|
+
collectQueryTimings(request, key, 'rendered');
|
|
59
63
|
return data;
|
|
64
|
+
}
|
|
60
65
|
if (!promise) {
|
|
61
|
-
|
|
66
|
+
const startApiTime = getTime();
|
|
67
|
+
promise = fetcher().then((r) => {
|
|
68
|
+
data = { data: r };
|
|
69
|
+
collectQueryTimings(request, key, 'resolved', getTime() - startApiTime);
|
|
70
|
+
}, (e) => (data = { error: e }));
|
|
62
71
|
}
|
|
63
72
|
throw promise;
|
|
64
73
|
});
|
|
65
74
|
}
|
|
66
|
-
|
|
75
|
+
// Making sure the promise has returned data because it can be initated by a preload request,
|
|
76
|
+
// otherwise, we throw the promise
|
|
77
|
+
const result = cache.get(cacheKey).call();
|
|
78
|
+
if (result instanceof Promise)
|
|
79
|
+
throw result;
|
|
80
|
+
return result;
|
|
81
|
+
}
|
|
82
|
+
export function preloadRequestCacheData(request, preloadQueries) {
|
|
83
|
+
const cache = request.ctx.cache;
|
|
84
|
+
preloadQueries === null || preloadQueries === void 0 ? void 0 : preloadQueries.forEach((preloadQuery, cacheKey) => {
|
|
85
|
+
collectQueryTimings(request, preloadQuery.key, 'preload');
|
|
86
|
+
if (!cache.has(cacheKey)) {
|
|
87
|
+
let data;
|
|
88
|
+
let promise;
|
|
89
|
+
cache.set(cacheKey, () => {
|
|
90
|
+
if (data !== undefined) {
|
|
91
|
+
collectQueryTimings(request, preloadQuery.key, 'rendered');
|
|
92
|
+
return data;
|
|
93
|
+
}
|
|
94
|
+
if (!promise) {
|
|
95
|
+
const startApiTime = getTime();
|
|
96
|
+
promise = preloadQuery.fetcher().then((r) => {
|
|
97
|
+
data = { data: r };
|
|
98
|
+
collectQueryTimings(request, preloadQuery.key, 'resolved', getTime() - startApiTime);
|
|
99
|
+
}, (e) => (data = { error: e }));
|
|
100
|
+
}
|
|
101
|
+
return promise;
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
cache.get(cacheKey).call();
|
|
105
|
+
});
|
|
67
106
|
}
|
|
@@ -1,6 +1,14 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { CachingStrategy, PreloadOptions, QueryKey } from '../../types';
|
|
2
2
|
export interface HydrogenUseQueryOptions {
|
|
3
|
-
cache
|
|
3
|
+
/** The [caching strategy](/custom-storefronts/hydrogen/framework/cache#caching-strategies) to help you
|
|
4
|
+
* determine which cache control header to set.
|
|
5
|
+
*/
|
|
6
|
+
cache?: CachingStrategy;
|
|
7
|
+
/** Whether to [preload the query](/custom-storefronts/hydrogen/framework/preloaded-queries).
|
|
8
|
+
* Defaults to `false`. Specify `true` to preload the query for the URL or `'*'`
|
|
9
|
+
* to preload the query for all requests.
|
|
10
|
+
*/
|
|
11
|
+
preload?: PreloadOptions;
|
|
4
12
|
}
|
|
5
13
|
/**
|
|
6
14
|
* The `useQuery` hook is a wrapper around Suspense calls and
|
|
@@ -12,7 +20,7 @@ export declare function useQuery<T>(
|
|
|
12
20
|
key: QueryKey,
|
|
13
21
|
/** An asynchronous query function like `fetch` which returns data. */
|
|
14
22
|
queryFn: () => Promise<T>,
|
|
15
|
-
/**
|
|
23
|
+
/** The options to manage the cache behavior of the sub-request. */
|
|
16
24
|
queryOptions?: HydrogenUseQueryOptions): {
|
|
17
25
|
data?: undefined;
|
|
18
26
|
error: Response;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { deleteItemFromCache, getItemFromCache, isStale, setItemInCache, } from '../../framework/cache';
|
|
1
|
+
import { getLoggerWithContext, collectQueryCacheControlHeaders, collectQueryTimings, } from '../../utilities/log';
|
|
2
|
+
import { deleteItemFromCache, generateSubRequestCacheControlHeader, getItemFromCache, isStale, setItemInCache, } from '../../framework/cache';
|
|
3
3
|
import { runDelayedFunction } from '../../framework/runtime';
|
|
4
|
-
import { useRequestCacheData } from '../ServerRequestProvider';
|
|
4
|
+
import { useRequestCacheData, useServerRequest } from '../ServerRequestProvider';
|
|
5
5
|
/**
|
|
6
6
|
* The `useQuery` hook is a wrapper around Suspense calls and
|
|
7
7
|
* global runtime's Cache if it exists.
|
|
@@ -12,10 +12,20 @@ export function useQuery(
|
|
|
12
12
|
key,
|
|
13
13
|
/** An asynchronous query function like `fetch` which returns data. */
|
|
14
14
|
queryFn,
|
|
15
|
-
/**
|
|
15
|
+
/** The options to manage the cache behavior of the sub-request. */
|
|
16
16
|
queryOptions) {
|
|
17
|
+
const request = useServerRequest();
|
|
17
18
|
const withCacheIdKey = ['__QUERY_CACHE_ID__', ...key];
|
|
18
|
-
|
|
19
|
+
const fetcher = cachedQueryFnBuilder(withCacheIdKey, queryFn, queryOptions);
|
|
20
|
+
collectQueryTimings(request, withCacheIdKey, 'requested');
|
|
21
|
+
if (queryOptions === null || queryOptions === void 0 ? void 0 : queryOptions.preload) {
|
|
22
|
+
request.savePreloadQuery({
|
|
23
|
+
preload: queryOptions === null || queryOptions === void 0 ? void 0 : queryOptions.preload,
|
|
24
|
+
key: withCacheIdKey,
|
|
25
|
+
fetcher,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
return useRequestCacheData(withCacheIdKey, fetcher);
|
|
19
29
|
}
|
|
20
30
|
function cachedQueryFnBuilder(key, queryFn, queryOptions) {
|
|
21
31
|
const resolvedQueryOptions = {
|
|
@@ -25,12 +35,17 @@ function cachedQueryFnBuilder(key, queryFn, queryOptions) {
|
|
|
25
35
|
* Attempt to read the query from cache. If it doesn't exist or if it's stale, regenerate it.
|
|
26
36
|
*/
|
|
27
37
|
async function cachedQueryFn() {
|
|
38
|
+
// Call this hook before running any async stuff
|
|
39
|
+
// to prevent losing the current React cycle.
|
|
40
|
+
const request = useServerRequest();
|
|
41
|
+
const log = getLoggerWithContext(request);
|
|
28
42
|
const cacheResponse = await getItemFromCache(key);
|
|
29
43
|
async function generateNewOutput() {
|
|
30
44
|
return await queryFn();
|
|
31
45
|
}
|
|
32
46
|
if (cacheResponse) {
|
|
33
47
|
const [output, response] = cacheResponse;
|
|
48
|
+
collectQueryCacheControlHeaders(request, key, response.headers.get('cache-control'));
|
|
34
49
|
/**
|
|
35
50
|
* Important: Do this async
|
|
36
51
|
*/
|
|
@@ -62,6 +77,7 @@ function cachedQueryFnBuilder(key, queryFn, queryOptions) {
|
|
|
62
77
|
* Important: Do this async
|
|
63
78
|
*/
|
|
64
79
|
runDelayedFunction(async () => await setItemInCache(key, newOutput, resolvedQueryOptions === null || resolvedQueryOptions === void 0 ? void 0 : resolvedQueryOptions.cache));
|
|
80
|
+
collectQueryCacheControlHeaders(request, key, generateSubRequestCacheControlHeader(resolvedQueryOptions === null || resolvedQueryOptions === void 0 ? void 0 : resolvedQueryOptions.cache));
|
|
65
81
|
return newOutput;
|
|
66
82
|
}
|
|
67
83
|
return cachedQueryFn;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { CachingStrategy, AllCacheOptions, NoStoreStrategy } from '../../types';
|
|
2
|
+
export declare function generateCacheControlHeader(cacheOptions: CachingStrategy): string;
|
|
3
|
+
export declare function NoStore(): NoStoreStrategy;
|
|
4
|
+
export declare function CacheSeconds(overrideOptions?: CachingStrategy): AllCacheOptions;
|
|
5
|
+
export declare function CacheMinutes(overrideOptions?: CachingStrategy): AllCacheOptions;
|
|
6
|
+
export declare function CacheHours(overrideOptions?: CachingStrategy): AllCacheOptions;
|
|
7
|
+
export declare function CacheDays(overrideOptions?: CachingStrategy): AllCacheOptions;
|
|
8
|
+
export declare function CacheWeeks(overrideOptions?: CachingStrategy): AllCacheOptions;
|
|
9
|
+
export declare function CacheMonths(overrideOptions?: CachingStrategy): AllCacheOptions;
|
|
10
|
+
export declare function CacheCustom(overrideOptions: CachingStrategy): AllCacheOptions;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
const PUBLIC = 'public';
|
|
2
|
+
const PRIVATE = 'private';
|
|
3
|
+
const NO_STORE = 'no-store';
|
|
4
|
+
const optionMapping = {
|
|
5
|
+
maxAge: 'max-age',
|
|
6
|
+
staleWhileRevalidate: 'stale-while-revalidate',
|
|
7
|
+
sMaxAge: 's-maxage',
|
|
8
|
+
staleIfError: 'stale-if-error',
|
|
9
|
+
};
|
|
10
|
+
export function generateCacheControlHeader(cacheOptions) {
|
|
11
|
+
const cacheControl = [];
|
|
12
|
+
Object.keys(cacheOptions).forEach((key) => {
|
|
13
|
+
if (key === 'mode') {
|
|
14
|
+
cacheControl.push(cacheOptions[key]);
|
|
15
|
+
}
|
|
16
|
+
else if (optionMapping[key]) {
|
|
17
|
+
cacheControl.push(`${optionMapping[key]}=${cacheOptions[key]}`);
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
return cacheControl.join(', ');
|
|
21
|
+
}
|
|
22
|
+
export function NoStore() {
|
|
23
|
+
return {
|
|
24
|
+
mode: NO_STORE,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
function guardExpirableModeType(overrideOptions) {
|
|
28
|
+
if ((overrideOptions === null || overrideOptions === void 0 ? void 0 : overrideOptions.mode) &&
|
|
29
|
+
(overrideOptions === null || overrideOptions === void 0 ? void 0 : overrideOptions.mode) !== PUBLIC &&
|
|
30
|
+
(overrideOptions === null || overrideOptions === void 0 ? void 0 : overrideOptions.mode) !== PRIVATE) {
|
|
31
|
+
throw Error("'mode' must be either 'public' or 'private'");
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
// 10 seconds
|
|
35
|
+
export function CacheSeconds(overrideOptions) {
|
|
36
|
+
guardExpirableModeType(overrideOptions);
|
|
37
|
+
return {
|
|
38
|
+
mode: PUBLIC,
|
|
39
|
+
maxAge: 1,
|
|
40
|
+
staleWhileRevalidate: 9,
|
|
41
|
+
...overrideOptions,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
// 30 minutes
|
|
45
|
+
export function CacheMinutes(overrideOptions) {
|
|
46
|
+
guardExpirableModeType(overrideOptions);
|
|
47
|
+
return {
|
|
48
|
+
mode: PUBLIC,
|
|
49
|
+
maxAge: 900,
|
|
50
|
+
staleWhileRevalidate: 900,
|
|
51
|
+
...overrideOptions,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
// 1 hour
|
|
55
|
+
export function CacheHours(overrideOptions) {
|
|
56
|
+
guardExpirableModeType(overrideOptions);
|
|
57
|
+
return {
|
|
58
|
+
mode: PUBLIC,
|
|
59
|
+
maxAge: 1800,
|
|
60
|
+
staleWhileRevalidate: 1800,
|
|
61
|
+
...overrideOptions,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
// 1 day
|
|
65
|
+
export function CacheDays(overrideOptions) {
|
|
66
|
+
guardExpirableModeType(overrideOptions);
|
|
67
|
+
return {
|
|
68
|
+
mode: PUBLIC,
|
|
69
|
+
maxAge: 3600,
|
|
70
|
+
staleWhileRevalidate: 82800,
|
|
71
|
+
...overrideOptions,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
// 2 weeks
|
|
75
|
+
export function CacheWeeks(overrideOptions) {
|
|
76
|
+
guardExpirableModeType(overrideOptions);
|
|
77
|
+
return {
|
|
78
|
+
mode: PUBLIC,
|
|
79
|
+
maxAge: 604800,
|
|
80
|
+
staleWhileRevalidate: 604800,
|
|
81
|
+
...overrideOptions,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
// 1 month
|
|
85
|
+
export function CacheMonths(overrideOptions) {
|
|
86
|
+
guardExpirableModeType(overrideOptions);
|
|
87
|
+
return {
|
|
88
|
+
mode: PUBLIC,
|
|
89
|
+
maxAge: 1296000,
|
|
90
|
+
staleWhileRevalidate: 1296000,
|
|
91
|
+
...overrideOptions,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
export function CacheCustom(overrideOptions) {
|
|
95
|
+
return overrideOptions;
|
|
96
|
+
}
|
|
@@ -1,22 +1,15 @@
|
|
|
1
1
|
/// <reference types="vite/client" />
|
|
2
2
|
import React from 'react';
|
|
3
3
|
export function Html({ children, template, htmlAttrs, bodyAttrs }) {
|
|
4
|
-
|
|
5
|
-
const head = template.match(/<head>(.+?)<\/head>/s)[1] || '';
|
|
6
|
-
let devEntryPoint = '';
|
|
4
|
+
let head = template.match(/<head>(.+?)<\/head>/s)[1] || '';
|
|
7
5
|
// @ts-ignore
|
|
8
6
|
if (import.meta.env.DEV) {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
.match(/src="(.*?)">/i)) === null || _a === void 0 ? void 0 : _a[1]) || '';
|
|
13
|
-
if (!devEntryPoint) {
|
|
14
|
-
throw new Error('Could not find entry-client module in index.html');
|
|
15
|
-
}
|
|
7
|
+
// Fix React Refresh for async scripts.
|
|
8
|
+
// https://github.com/vitejs/vite/issues/6759
|
|
9
|
+
head = head.replace(/>(\s*?import[\s\w]+?['"]\/@react-refresh)/, ' async="">$1');
|
|
16
10
|
}
|
|
17
11
|
return (React.createElement("html", { ...htmlAttrs },
|
|
18
12
|
React.createElement("head", { dangerouslySetInnerHTML: { __html: head } }),
|
|
19
13
|
React.createElement("body", { ...bodyAttrs },
|
|
20
|
-
React.createElement("div", { id: "root" }, children)
|
|
21
|
-
import.meta.env.DEV && (React.createElement("script", { type: "module", src: devEntryPoint })))));
|
|
14
|
+
React.createElement("div", { id: "root" }, children))));
|
|
22
15
|
}
|
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
import type { ShopifyContextValue } from '../../foundation/ShopifyProvider/types';
|
|
2
|
-
import type {
|
|
2
|
+
import type { QueryCacheControlHeaders } from '../../utilities/log/log-cache-header';
|
|
3
|
+
import type { QueryTiming } from '../../utilities/log/log-query-timeline';
|
|
4
|
+
import type { PreloadOptions, QueryKey } from '../../types';
|
|
5
|
+
import { HelmetData as HeadData } from 'react-helmet-async';
|
|
6
|
+
export declare type PreloadQueryEntry = {
|
|
7
|
+
key: QueryKey;
|
|
8
|
+
fetcher: () => Promise<unknown>;
|
|
9
|
+
preload?: PreloadOptions;
|
|
10
|
+
};
|
|
11
|
+
export declare type PreloadQueriesByURL = Map<string, PreloadQueryEntry>;
|
|
12
|
+
export declare type AllPreloadQueries = Map<string, PreloadQueriesByURL>;
|
|
3
13
|
/**
|
|
4
14
|
* This augments the `Request` object from the Fetch API:
|
|
5
15
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/Request
|
|
@@ -11,13 +21,21 @@ export declare class ServerComponentRequest extends Request {
|
|
|
11
21
|
cookies: Map<string, string>;
|
|
12
22
|
id: string;
|
|
13
23
|
time: number;
|
|
24
|
+
preloadURL: string;
|
|
14
25
|
ctx: {
|
|
15
26
|
cache: Map<string, any>;
|
|
16
|
-
|
|
27
|
+
head: HeadData;
|
|
17
28
|
shopifyConfig?: ShopifyContextValue;
|
|
29
|
+
queryCacheControl: Array<QueryCacheControlHeaders>;
|
|
30
|
+
queryTimings: Array<QueryTiming>;
|
|
31
|
+
preloadQueries: PreloadQueriesByURL;
|
|
18
32
|
[key: string]: any;
|
|
19
33
|
};
|
|
20
34
|
constructor(input: any);
|
|
21
35
|
constructor(input: RequestInfo, init?: RequestInit);
|
|
22
36
|
private parseCookies;
|
|
37
|
+
isRscRequest(): boolean;
|
|
38
|
+
savePreloadQuery(query: PreloadQueryEntry): void;
|
|
39
|
+
getPreloadQueries(): PreloadQueriesByURL | undefined;
|
|
40
|
+
savePreloadQueries(): void;
|
|
23
41
|
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { getTime } from '../../utilities/timing';
|
|
2
|
-
import {
|
|
2
|
+
import { hashKey } from '../cache';
|
|
3
|
+
import { HelmetData as HeadData } from 'react-helmet-async';
|
|
4
|
+
import { RSC_PATHNAME } from '../../constants';
|
|
3
5
|
let reqCounter = 0; // For debugging
|
|
4
6
|
const generateId = typeof crypto !== 'undefined' &&
|
|
5
7
|
// @ts-ignore
|
|
@@ -7,6 +9,9 @@ const generateId = typeof crypto !== 'undefined' &&
|
|
|
7
9
|
? // @ts-ignore
|
|
8
10
|
() => crypto.randomUUID()
|
|
9
11
|
: () => `req${++reqCounter}`;
|
|
12
|
+
// Stores queries by url or '*'
|
|
13
|
+
const preloadCache = new Map();
|
|
14
|
+
const PRELOAD_ALL = '*';
|
|
10
15
|
/**
|
|
11
16
|
* This augments the `Request` object from the Fetch API:
|
|
12
17
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/Request
|
|
@@ -32,9 +37,15 @@ export class ServerComponentRequest extends Request {
|
|
|
32
37
|
this.id = generateId();
|
|
33
38
|
this.ctx = {
|
|
34
39
|
cache: new Map(),
|
|
35
|
-
|
|
40
|
+
head: new HeadData({}),
|
|
41
|
+
queryCacheControl: [],
|
|
42
|
+
queryTimings: [],
|
|
43
|
+
preloadQueries: new Map(),
|
|
36
44
|
};
|
|
37
45
|
this.cookies = this.parseCookies();
|
|
46
|
+
const referer = this.headers.get('referer');
|
|
47
|
+
this.preloadURL =
|
|
48
|
+
this.isRscRequest() && referer && referer !== '' ? referer : this.url;
|
|
38
49
|
}
|
|
39
50
|
parseCookies() {
|
|
40
51
|
const cookieString = this.headers.get('cookie') || '';
|
|
@@ -42,6 +53,44 @@ export class ServerComponentRequest extends Request {
|
|
|
42
53
|
.split(';')
|
|
43
54
|
.map((chunk) => chunk.trim().split(/=(.+)/)));
|
|
44
55
|
}
|
|
56
|
+
isRscRequest() {
|
|
57
|
+
const url = new URL(this.url);
|
|
58
|
+
return url.pathname === RSC_PATHNAME;
|
|
59
|
+
}
|
|
60
|
+
savePreloadQuery(query) {
|
|
61
|
+
if (typeof query.preload === 'string' && query.preload === PRELOAD_ALL) {
|
|
62
|
+
saveToPreloadAllPreload(query);
|
|
63
|
+
}
|
|
64
|
+
else if (query.preload) {
|
|
65
|
+
this.ctx.preloadQueries.set(hashKey(query.key), query);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
getPreloadQueries() {
|
|
69
|
+
if (preloadCache.has(this.preloadURL)) {
|
|
70
|
+
const combinedPreloadQueries = new Map();
|
|
71
|
+
const urlPreloadCache = preloadCache.get(this.preloadURL);
|
|
72
|
+
mergeMapEntries(combinedPreloadQueries, urlPreloadCache);
|
|
73
|
+
mergeMapEntries(combinedPreloadQueries, preloadCache.get(PRELOAD_ALL));
|
|
74
|
+
return combinedPreloadQueries;
|
|
75
|
+
}
|
|
76
|
+
else if (preloadCache.has(PRELOAD_ALL)) {
|
|
77
|
+
return preloadCache.get(PRELOAD_ALL);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
savePreloadQueries() {
|
|
81
|
+
preloadCache.set(this.preloadURL, this.ctx.preloadQueries);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
function mergeMapEntries(map1, map2) {
|
|
85
|
+
map2 && map2.forEach((v, k) => map1.set(k, v));
|
|
86
|
+
}
|
|
87
|
+
function saveToPreloadAllPreload(query) {
|
|
88
|
+
let setCache = preloadCache.get(PRELOAD_ALL);
|
|
89
|
+
if (!setCache) {
|
|
90
|
+
setCache = new Map();
|
|
91
|
+
}
|
|
92
|
+
setCache === null || setCache === void 0 ? void 0 : setCache.set(hashKey(query.key), query);
|
|
93
|
+
preloadCache.set(PRELOAD_ALL, setCache);
|
|
45
94
|
}
|
|
46
95
|
/**
|
|
47
96
|
* @see https://github.com/frandiox/vitedge/blob/17f3cd943e86d7c0c71a862985ddd6caa2899425/src/node/utils.js#L19-L24
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { CachingStrategy } from '../../types';
|
|
2
2
|
export declare class ServerComponentResponse extends Response {
|
|
3
3
|
private wait;
|
|
4
4
|
private cacheOptions?;
|
|
@@ -16,7 +16,7 @@ export declare class ServerComponentResponse extends Response {
|
|
|
16
16
|
*/
|
|
17
17
|
doNotStream(): void;
|
|
18
18
|
canStream(): boolean;
|
|
19
|
-
cache(options:
|
|
19
|
+
cache(options: CachingStrategy): void;
|
|
20
20
|
get cacheControlHeader(): string;
|
|
21
21
|
writeHead({ status, statusText, headers, }?: {
|
|
22
22
|
status?: number;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { renderToString } from 'react-dom/server';
|
|
2
|
-
import { generateCacheControlHeader } from '../
|
|
2
|
+
import { CacheSeconds, generateCacheControlHeader } from '../CachingStrategy';
|
|
3
3
|
export class ServerComponentResponse extends Response {
|
|
4
4
|
constructor() {
|
|
5
5
|
super(...arguments);
|
|
@@ -23,12 +23,7 @@ export class ServerComponentResponse extends Response {
|
|
|
23
23
|
this.cacheOptions = options;
|
|
24
24
|
}
|
|
25
25
|
get cacheControlHeader() {
|
|
26
|
-
|
|
27
|
-
const options = {
|
|
28
|
-
...DEFAULT_CACHE_OPTIONS,
|
|
29
|
-
...((_a = this.cacheOptions) !== null && _a !== void 0 ? _a : {}),
|
|
30
|
-
};
|
|
31
|
-
return generateCacheControlHeader(options);
|
|
26
|
+
return generateCacheControlHeader(this.cacheOptions || CacheSeconds());
|
|
32
27
|
}
|
|
33
28
|
writeHead({ status, statusText, headers, } = {}) {
|
|
34
29
|
if (status || statusText) {
|
|
@@ -58,7 +53,3 @@ export class ServerComponentResponse extends Response {
|
|
|
58
53
|
return null;
|
|
59
54
|
}
|
|
60
55
|
}
|
|
61
|
-
const DEFAULT_CACHE_OPTIONS = {
|
|
62
|
-
maxAge: 60 * 60,
|
|
63
|
-
staleWhileRevalidate: 23 * 60 * 60,
|
|
64
|
-
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { logCacheApiStatus } from '../../utilities/log';
|
|
1
2
|
/**
|
|
2
3
|
* This is an in-memory implementation of `Cache` that *barely*
|
|
3
4
|
* works and is only meant to be used during development.
|
|
@@ -7,7 +8,7 @@ export class InMemoryCache {
|
|
|
7
8
|
this.store = new Map();
|
|
8
9
|
}
|
|
9
10
|
put(request, response) {
|
|
10
|
-
|
|
11
|
+
logCacheApiStatus('PUT', request.url);
|
|
11
12
|
this.store.set(request.url, {
|
|
12
13
|
value: response,
|
|
13
14
|
date: new Date(),
|
|
@@ -16,7 +17,7 @@ export class InMemoryCache {
|
|
|
16
17
|
match(request) {
|
|
17
18
|
const match = this.store.get(request.url);
|
|
18
19
|
if (!match) {
|
|
19
|
-
|
|
20
|
+
logCacheApiStatus('MISS', request.url);
|
|
20
21
|
return;
|
|
21
22
|
}
|
|
22
23
|
const { value, date } = match;
|
|
@@ -26,7 +27,7 @@ export class InMemoryCache {
|
|
|
26
27
|
const age = (new Date().valueOf() - date) / 1000;
|
|
27
28
|
const isMiss = age > maxAge + swr;
|
|
28
29
|
if (isMiss) {
|
|
29
|
-
|
|
30
|
+
logCacheApiStatus('MISS', request.url);
|
|
30
31
|
this.store.delete(request.url);
|
|
31
32
|
return;
|
|
32
33
|
}
|
|
@@ -34,7 +35,7 @@ export class InMemoryCache {
|
|
|
34
35
|
const headers = new Headers(value.headers);
|
|
35
36
|
headers.set('cache', isStale ? 'STALE' : 'HIT');
|
|
36
37
|
headers.set('date', date.toGMTString());
|
|
37
|
-
|
|
38
|
+
logCacheApiStatus(headers.get('cache'), request.url);
|
|
38
39
|
const response = new Response(value.body, {
|
|
39
40
|
headers,
|
|
40
41
|
});
|
|
@@ -42,6 +43,6 @@ export class InMemoryCache {
|
|
|
42
43
|
}
|
|
43
44
|
delete(request) {
|
|
44
45
|
this.store.delete(request.url);
|
|
45
|
-
|
|
46
|
+
logCacheApiStatus('DELETE', request.url);
|
|
46
47
|
}
|
|
47
48
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export declare function
|
|
1
|
+
import type { QueryKey, CachingStrategy } from '../types';
|
|
2
|
+
export declare function generateSubRequestCacheControlHeader(userCacheOptions?: CachingStrategy): string;
|
|
3
3
|
/**
|
|
4
4
|
* Use a preview header during development.
|
|
5
5
|
* TODO: Support an override of this to force the cache
|
|
@@ -18,7 +18,7 @@ export declare function getItemFromCache(key: QueryKey): Promise<undefined | [an
|
|
|
18
18
|
/**
|
|
19
19
|
* Put an item into the cache.
|
|
20
20
|
*/
|
|
21
|
-
export declare function setItemInCache(key: QueryKey, value: any, userCacheOptions?:
|
|
21
|
+
export declare function setItemInCache(key: QueryKey, value: any, userCacheOptions?: CachingStrategy): Promise<void>;
|
|
22
22
|
export declare function deleteItemFromCache(key: QueryKey): Promise<void>;
|
|
23
23
|
/**
|
|
24
24
|
* Manually check the response to see if it's stale.
|
|
@@ -1,17 +1,7 @@
|
|
|
1
1
|
import { getCache } from './runtime';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
};
|
|
6
|
-
export function generateCacheControlHeader(options) {
|
|
7
|
-
if (options.noStore) {
|
|
8
|
-
return 'no-store';
|
|
9
|
-
}
|
|
10
|
-
return [
|
|
11
|
-
options.private ? 'private' : 'public',
|
|
12
|
-
`max-age=${options.maxAge}`,
|
|
13
|
-
`stale-while-revalidate=${options.staleWhileRevalidate}`,
|
|
14
|
-
].join(', ');
|
|
2
|
+
import { CacheSeconds, generateCacheControlHeader, } from '../framework/CachingStrategy';
|
|
3
|
+
export function generateSubRequestCacheControlHeader(userCacheOptions) {
|
|
4
|
+
return generateCacheControlHeader(userCacheOptions || CacheSeconds());
|
|
15
5
|
}
|
|
16
6
|
/**
|
|
17
7
|
* Use a preview header during development.
|
|
@@ -61,12 +51,8 @@ export async function setItemInCache(key, value, userCacheOptions) {
|
|
|
61
51
|
}
|
|
62
52
|
const url = getKeyUrl(hashKey(key));
|
|
63
53
|
const request = new Request(url);
|
|
64
|
-
const cacheOptions = {
|
|
65
|
-
...DEFAULT_SUBREQUEST_CACHE_OPTIONS,
|
|
66
|
-
...(userCacheOptions !== null && userCacheOptions !== void 0 ? userCacheOptions : {}),
|
|
67
|
-
};
|
|
68
54
|
const headers = new Headers({
|
|
69
|
-
'cache-control':
|
|
55
|
+
'cache-control': generateSubRequestCacheControlHeader(userCacheOptions),
|
|
70
56
|
});
|
|
71
57
|
const response = new Response(JSON.stringify(value), { headers });
|
|
72
58
|
/**
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
import { IncomingMessage, NextFunction } from 'connect';
|
|
2
|
-
import
|
|
3
|
-
import { ViteDevServer } from 'vite';
|
|
4
|
-
import { ShopifyConfig } from '../types';
|
|
1
|
+
import type { IncomingMessage, NextFunction } from 'connect';
|
|
2
|
+
import type { ServerResponse } from 'http';
|
|
3
|
+
import type { ViteDevServer } from 'vite';
|
|
4
|
+
import type { ShopifyConfig } from '../types';
|
|
5
5
|
declare type HydrogenMiddlewareArgs = {
|
|
6
6
|
dev?: boolean;
|
|
7
7
|
shopifyConfig?: ShopifyConfig;
|
|
8
8
|
indexTemplate: string | ((url: string) => Promise<string>);
|
|
9
|
-
getServerEntrypoint: () =>
|
|
9
|
+
getServerEntrypoint: () => any;
|
|
10
10
|
devServer?: ViteDevServer;
|
|
11
11
|
cache?: Cache;
|
|
12
12
|
};
|
|
13
13
|
export declare function graphiqlMiddleware({ shopifyConfig, dev, }: {
|
|
14
14
|
shopifyConfig: ShopifyConfig;
|
|
15
15
|
dev: boolean;
|
|
16
|
-
}): (request: IncomingMessage, response:
|
|
16
|
+
}): (request: IncomingMessage, response: ServerResponse, next: NextFunction) => Promise<void>;
|
|
17
17
|
/**
|
|
18
18
|
* Provides middleware to Node.js Express-like servers. Used by the Hydrogen
|
|
19
19
|
* Vite dev server plugin as well as production Node.js implementation.
|
|
20
20
|
*/
|
|
21
|
-
export declare function hydrogenMiddleware({ dev, cache, indexTemplate, getServerEntrypoint, devServer, }: HydrogenMiddlewareArgs): (request: IncomingMessage, response:
|
|
21
|
+
export declare function hydrogenMiddleware({ dev, cache, indexTemplate, getServerEntrypoint, devServer, }: HydrogenMiddlewareArgs): (request: IncomingMessage, response: ServerResponse, next: NextFunction) => Promise<void>;
|
|
22
22
|
export {};
|