@shopify/hydrogen 0.11.0-experimental.0 → 0.11.0-experimental.1
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/dist/esnext/client.d.ts +0 -1
- package/dist/esnext/client.js +0 -1
- package/dist/esnext/components/CartLines/CartLines.d.ts +3 -4
- package/dist/esnext/components/CartLines/CartLines.js +3 -5
- package/dist/esnext/components/CartShopPayButton/CartShopPayButton.client.js +6 -3
- package/dist/esnext/components/Link/Link.client.d.ts +18 -1
- package/dist/esnext/components/Link/Link.client.js +42 -4
- package/dist/esnext/components/Metafield/Metafield.client.d.ts +1 -1
- package/dist/esnext/components/Router/index.d.ts +1 -0
- package/dist/esnext/components/Router/index.js +1 -0
- package/dist/esnext/components/Seo/CollectionSeo.client.js +2 -2
- package/dist/esnext/components/Seo/ProductSeo.client.d.ts +1 -1
- package/dist/esnext/components/Seo/ProductSeo.client.js +4 -8
- package/dist/esnext/components/Seo/types.d.ts +2 -6
- package/dist/esnext/components/ShopPayButton/ShopPayButton.client.d.ts +22 -5
- package/dist/esnext/components/ShopPayButton/ShopPayButton.client.js +45 -12
- package/dist/esnext/components/UnitPrice/UnitPrice.client.d.ts +1 -6
- package/dist/esnext/components/UnitPrice/UnitPrice.client.js +3 -12
- package/dist/esnext/components/index.d.ts +2 -2
- package/dist/esnext/components/index.js +2 -48
- package/dist/esnext/constants.d.ts +1 -0
- package/dist/esnext/constants.js +1 -0
- package/dist/esnext/entry-client.js +3 -4
- package/dist/esnext/entry-server.js +2 -1
- package/dist/esnext/foundation/Helmet/Helmet.client.js +2 -6
- package/dist/esnext/foundation/Router/Router.client.d.ts +12 -0
- package/dist/esnext/foundation/Router/Router.client.js +44 -0
- package/dist/esnext/foundation/ssr-interop.d.ts +29 -0
- package/dist/esnext/foundation/ssr-interop.js +35 -0
- package/dist/esnext/foundation/useQuery/hooks.d.ts +1 -1
- package/dist/esnext/foundation/useQuery/hooks.js +1 -1
- package/dist/esnext/foundation/useServerState/use-server-state.d.ts +2 -1
- package/dist/esnext/foundation/useServerState/use-server-state.js +2 -2
- package/dist/esnext/foundation/useShop/use-shop.js +2 -6
- package/dist/esnext/foundation/useUrl/useUrl.d.ts +1 -1
- package/dist/esnext/foundation/useUrl/useUrl.js +5 -5
- package/dist/esnext/framework/Hydration/Html.js +13 -1
- package/dist/esnext/framework/Hydration/rsc.d.ts +1 -1
- package/dist/esnext/framework/Hydration/rsc.js +4 -4
- package/dist/esnext/framework/plugin.js +2 -0
- package/dist/esnext/framework/plugins/vite-plugin-hydrogen-config.js +1 -1
- package/dist/esnext/framework/plugins/vite-plugin-hydrogen-middleware.js +1 -1
- package/dist/esnext/framework/plugins/vite-plugin-ssr-interop.d.ts +3 -0
- package/dist/esnext/framework/plugins/vite-plugin-ssr-interop.js +13 -0
- package/dist/esnext/handle-event.js +2 -1
- package/dist/esnext/hooks/useNavigate/index.d.ts +1 -0
- package/dist/esnext/hooks/useNavigate/index.js +1 -0
- package/dist/esnext/hooks/useNavigate/useNavigate.d.ts +10 -0
- package/dist/esnext/hooks/useNavigate/useNavigate.js +11 -0
- package/dist/esnext/utilities/error.js +3 -12
- package/dist/esnext/utilities/fetch.js +8 -0
- package/dist/esnext/utilities/log/log.d.ts +4 -3
- package/dist/esnext/utilities/video_parameters.js +4 -0
- package/dist/esnext/version.d.ts +1 -1
- package/dist/esnext/version.js +1 -1
- package/dist/node/constants.d.ts +1 -0
- package/dist/node/constants.js +4 -0
- package/dist/node/foundation/Helmet/Helmet.client.js +2 -6
- package/dist/node/foundation/ssr-interop.d.ts +29 -0
- package/dist/node/foundation/ssr-interop.js +39 -0
- package/dist/node/framework/Hydration/Html.js +13 -1
- package/dist/node/framework/Hydration/rsc.d.ts +1 -1
- package/dist/node/framework/Hydration/rsc.js +4 -4
- package/dist/node/framework/plugin.js +2 -0
- package/dist/node/framework/plugins/vite-plugin-hydrogen-config.js +1 -1
- package/dist/node/framework/plugins/vite-plugin-hydrogen-middleware.js +1 -1
- package/dist/node/framework/plugins/vite-plugin-ssr-interop.d.ts +3 -0
- package/dist/node/framework/plugins/vite-plugin-ssr-interop.js +15 -0
- package/dist/node/handle-event.js +2 -1
- package/dist/node/utilities/log/log.d.ts +4 -3
- package/dist/worker/constants.d.ts +1 -0
- package/dist/worker/constants.js +1 -0
- package/dist/worker/foundation/Helmet/Helmet.client.js +2 -6
- package/dist/worker/foundation/ssr-interop.d.ts +29 -0
- package/dist/worker/foundation/ssr-interop.js +35 -0
- package/dist/worker/handle-event.js +2 -1
- package/dist/worker/utilities/log/log.d.ts +4 -3
- package/package.json +4 -5
- package/vendor/react-server-dom-vite/cjs/react-server-dom-vite-plugin.js +1 -5
- package/vendor/react-server-dom-vite/esm/react-server-dom-vite-client-proxy.js +1 -0
- package/vendor/react-server-dom-vite/esm/react-server-dom-vite-plugin.js +1 -5
- package/dist/esnext/foundation/Router/ServerStateRouter.client.d.ts +0 -6
- package/dist/esnext/foundation/Router/ServerStateRouter.client.js +0 -30
- package/dist/esnext/utilities/meta-env-ssr.d.ts +0 -1
- package/dist/esnext/utilities/meta-env-ssr.js +0 -3
- package/dist/node/foundation/ServerRequestProvider/ServerRequestProvider.d.ts +0 -22
- package/dist/node/foundation/ServerRequestProvider/ServerRequestProvider.js +0 -92
- package/dist/node/foundation/ServerRequestProvider/index.d.ts +0 -1
- package/dist/node/foundation/ServerRequestProvider/index.js +0 -13
- package/dist/node/utilities/meta-env-ssr.d.ts +0 -1
- package/dist/node/utilities/meta-env-ssr.js +0 -6
- package/dist/worker/foundation/ServerRequestProvider/ServerRequestProvider.d.ts +0 -22
- package/dist/worker/foundation/ServerRequestProvider/ServerRequestProvider.js +0 -67
- package/dist/worker/foundation/ServerRequestProvider/index.d.ts +0 -1
- package/dist/worker/foundation/ServerRequestProvider/index.js +0 -1
- package/dist/worker/framework/cache.d.ts +0 -26
- package/dist/worker/framework/cache.js +0 -101
- package/dist/worker/utilities/meta-env-ssr.d.ts +0 -1
- package/dist/worker/utilities/meta-env-ssr.js +0 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const RSC_PATHNAME = "/__rsc";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const RSC_PATHNAME = '/__rsc';
|
|
@@ -1,13 +1,9 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Helmet as ActualHelmet, HelmetData, } from 'react-helmet-async';
|
|
3
|
-
import {
|
|
4
|
-
import { META_ENV_SSR } from '../../utilities/meta-env-ssr';
|
|
3
|
+
import { useEnvContext } from '../ssr-interop';
|
|
5
4
|
const clientHelmetData = new HelmetData({});
|
|
6
5
|
export function Helmet({ children, ...props }) {
|
|
7
|
-
|
|
8
|
-
const helmetData = META_ENV_SSR
|
|
9
|
-
? useServerRequest().ctx.helmet
|
|
10
|
-
: clientHelmetData;
|
|
6
|
+
const helmetData = useEnvContext((req) => req.ctx.helmet, clientHelmetData);
|
|
11
7
|
return (
|
|
12
8
|
// @ts-ignore
|
|
13
9
|
React.createElement(ActualHelmet, { ...props, helmetData: helmetData }, children));
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is used for compatibility between browser and server environments.
|
|
3
|
+
* The browser loads this file as is, without leaking server logic.
|
|
4
|
+
* In the server, this file is transformed by Vite to inject server logic.
|
|
5
|
+
* NOTE: Do not remove SSR-prefixed comments in this file.
|
|
6
|
+
*/
|
|
7
|
+
import type { ServerComponentRequest } from '../framework/Hydration/ServerComponentRequest.server';
|
|
8
|
+
export declare const META_ENV_SSR = false;
|
|
9
|
+
declare type ServerGetter<T> = (request: ServerComponentRequest) => T;
|
|
10
|
+
/**
|
|
11
|
+
* Isomorphic hook to access context data. It gives access to the current request
|
|
12
|
+
* when running on the server, and returns the provided client fallback in the browser.
|
|
13
|
+
* This can be used in server components (RSC) as a Context/Provider replacement. In client
|
|
14
|
+
* components, it uses the server getter in SSR and the client fallback in the browser.
|
|
15
|
+
* @param serverGetter - A function that gets the current server request and returns any
|
|
16
|
+
* desired request property. It only runs in the server (both in RSC and SSR).
|
|
17
|
+
* @param clientFallback - An optional raw value or a React.Context to be consumed that will be
|
|
18
|
+
* returned if the current environment is not the server. Note that, if this is a React.Context,
|
|
19
|
+
* there must be a React.Provider parent in the app tree.
|
|
20
|
+
* @returns A value retrieved from the current server request or a fallback value in the client.
|
|
21
|
+
* The returned type depends on what the server getter returns.
|
|
22
|
+
* @example
|
|
23
|
+
* ```js
|
|
24
|
+
* import {MyClientContext} from './my-client-react-context-provider';
|
|
25
|
+
* useEnvContext(req => req.ctx.myServerContext, MyClientContext)
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export declare function useEnvContext<T>(serverGetter: ServerGetter<T>, clientFallback?: any): T;
|
|
29
|
+
export {};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is used for compatibility between browser and server environments.
|
|
3
|
+
* The browser loads this file as is, without leaking server logic.
|
|
4
|
+
* In the server, this file is transformed by Vite to inject server logic.
|
|
5
|
+
* NOTE: Do not remove SSR-prefixed comments in this file.
|
|
6
|
+
*/
|
|
7
|
+
import { useContext } from 'react';
|
|
8
|
+
//@SSR import {useServerRequest} from './ServerRequestProvider';
|
|
9
|
+
// This is replaced by Vite to import.meta.env.SSR
|
|
10
|
+
export const META_ENV_SSR = false;
|
|
11
|
+
const reactContextType = Symbol.for('react.context');
|
|
12
|
+
/**
|
|
13
|
+
* Isomorphic hook to access context data. It gives access to the current request
|
|
14
|
+
* when running on the server, and returns the provided client fallback in the browser.
|
|
15
|
+
* This can be used in server components (RSC) as a Context/Provider replacement. In client
|
|
16
|
+
* components, it uses the server getter in SSR and the client fallback in the browser.
|
|
17
|
+
* @param serverGetter - A function that gets the current server request and returns any
|
|
18
|
+
* desired request property. It only runs in the server (both in RSC and SSR).
|
|
19
|
+
* @param clientFallback - An optional raw value or a React.Context to be consumed that will be
|
|
20
|
+
* returned if the current environment is not the server. Note that, if this is a React.Context,
|
|
21
|
+
* there must be a React.Provider parent in the app tree.
|
|
22
|
+
* @returns A value retrieved from the current server request or a fallback value in the client.
|
|
23
|
+
* The returned type depends on what the server getter returns.
|
|
24
|
+
* @example
|
|
25
|
+
* ```js
|
|
26
|
+
* import {MyClientContext} from './my-client-react-context-provider';
|
|
27
|
+
* useEnvContext(req => req.ctx.myServerContext, MyClientContext)
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export function useEnvContext(serverGetter, clientFallback) {
|
|
31
|
+
//@SSR if (META_ENV_SSR) return serverGetter(useServerRequest());
|
|
32
|
+
return clientFallback && clientFallback.$$typeof === reactContextType
|
|
33
|
+
? useContext(clientFallback)
|
|
34
|
+
: clientFallback;
|
|
35
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { setContext, setCache } from './framework/runtime';
|
|
2
2
|
import { setConfig } from './framework/config';
|
|
3
3
|
import { renderApiRoute } from './utilities/apiRoutes';
|
|
4
|
+
import { RSC_PATHNAME } from './constants';
|
|
4
5
|
export default async function handleEvent(event, { request, entrypoint, indexTemplate, assetHandler, streamableResponse, dev, cache, context, nonce, }) {
|
|
5
6
|
const url = new URL(request.url);
|
|
6
7
|
/**
|
|
@@ -9,7 +10,7 @@ export default async function handleEvent(event, { request, entrypoint, indexTem
|
|
|
9
10
|
setCache(cache);
|
|
10
11
|
setContext(context);
|
|
11
12
|
setConfig({ dev });
|
|
12
|
-
const isReactHydrationRequest = url.pathname ===
|
|
13
|
+
const isReactHydrationRequest = url.pathname === RSC_PATHNAME;
|
|
13
14
|
const template = typeof indexTemplate === 'function'
|
|
14
15
|
? await indexTemplate(url.toString())
|
|
15
16
|
: indexTemplate;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { ServerComponentRequest } from '../../framework/Hydration/ServerComponentRequest.server';
|
|
2
|
-
/**
|
|
3
|
-
* Use by importing `log` `@shopify/hydrogen
|
|
4
|
-
* component.
|
|
2
|
+
/** The `log` utility is a function that's used for logging debugging, warning, and error information about the application.
|
|
3
|
+
* Use this utility by importing `log` from `@shopify/hydrogen`, or by using a `log` prop passed to each page
|
|
4
|
+
* component. We recommend using the `log` prop passed to each page because it will associated your log to the
|
|
5
|
+
* current request in progress.
|
|
5
6
|
*/
|
|
6
7
|
export interface Logger {
|
|
7
8
|
trace: (...args: Array<any>) => void;
|
package/package.json
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"engines": {
|
|
8
8
|
"node": ">=14"
|
|
9
9
|
},
|
|
10
|
-
"version": "0.11.0-experimental.
|
|
10
|
+
"version": "0.11.0-experimental.1",
|
|
11
11
|
"description": "Modern custom Shopify storefronts",
|
|
12
12
|
"license": "MIT",
|
|
13
13
|
"main": "dist/esnext/index.js",
|
|
@@ -72,7 +72,6 @@
|
|
|
72
72
|
"@types/node-fetch": "^2.5.9",
|
|
73
73
|
"@types/react": "^17.0.3",
|
|
74
74
|
"@types/react-dom": "^17.0.3",
|
|
75
|
-
"@types/react-router-dom": "^5.1.7",
|
|
76
75
|
"@types/ws": "^8.2.0",
|
|
77
76
|
"babel-loader": "^8.2.2",
|
|
78
77
|
"cpy-cli": "3.1.1",
|
|
@@ -85,8 +84,7 @@
|
|
|
85
84
|
"peerDependencies": {
|
|
86
85
|
"react": "0.0.0-experimental-529dc3ce8-20220124",
|
|
87
86
|
"react-dom": "0.0.0-experimental-529dc3ce8-20220124",
|
|
88
|
-
"
|
|
89
|
-
"vite": "^2.7.1"
|
|
87
|
+
"vite": "^2.8.0"
|
|
90
88
|
},
|
|
91
89
|
"dependencies": {
|
|
92
90
|
"@vitejs/plugin-react": "^1.1.1",
|
|
@@ -96,6 +94,7 @@
|
|
|
96
94
|
"es-module-lexer": "^0.9.0",
|
|
97
95
|
"fast-glob": "^3.2.5",
|
|
98
96
|
"graphql": "^16.0.1",
|
|
97
|
+
"history": "^5.2.0",
|
|
99
98
|
"isomorphic-dompurify": "^0.13.0",
|
|
100
99
|
"kolorist": "^1.5.1",
|
|
101
100
|
"magic-string": "^0.25.7",
|
|
@@ -106,5 +105,5 @@
|
|
|
106
105
|
"vite-plugin-inspect": "^0.3.6",
|
|
107
106
|
"web-streams-polyfill": "^3.2.0"
|
|
108
107
|
},
|
|
109
|
-
"gitHead": "
|
|
108
|
+
"gitHead": "8ea40b5e119883ca380406edc123d9cb10ca8650"
|
|
110
109
|
}
|
|
@@ -117,11 +117,7 @@ function ReactFlightVitePlugin() {
|
|
|
117
117
|
importerToRootNested.replace(/\/?$/, path.sep)
|
|
118
118
|
)
|
|
119
119
|
);
|
|
120
|
-
var userGlob = path.join(
|
|
121
|
-
importerToRootPath,
|
|
122
|
-
'src',
|
|
123
|
-
CLIENT_COMPONENT_GLOB
|
|
124
|
-
);
|
|
120
|
+
var userGlob = path.join(importerToRootPath, CLIENT_COMPONENT_GLOB);
|
|
125
121
|
var importers = [[userGlob, userPrefix]];
|
|
126
122
|
clientComponentPaths.forEach(function (componentPath) {
|
|
127
123
|
var libPrefix = componentPath + path.sep;
|
|
@@ -113,11 +113,7 @@ function ReactFlightVitePlugin() {
|
|
|
113
113
|
importerToRootNested.replace(/\/?$/, path.sep)
|
|
114
114
|
)
|
|
115
115
|
);
|
|
116
|
-
var userGlob = path.join(
|
|
117
|
-
importerToRootPath,
|
|
118
|
-
'src',
|
|
119
|
-
CLIENT_COMPONENT_GLOB
|
|
120
|
-
);
|
|
116
|
+
var userGlob = path.join(importerToRootPath, CLIENT_COMPONENT_GLOB);
|
|
121
117
|
var importers = [[userGlob, userPrefix]];
|
|
122
118
|
clientComponentPaths.forEach(function (componentPath) {
|
|
123
119
|
var libPrefix = componentPath + path.sep;
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Since we don't render each <Route> on the client like React Router expects,
|
|
3
|
-
* this listens for changes to `location` and proxies the new pathname to
|
|
4
|
-
* server state, which in turn fetches the correct server component.
|
|
5
|
-
*/
|
|
6
|
-
export declare function ServerStateRouter(): null;
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { useEffect, useState } from 'react';
|
|
2
|
-
import { useLocation } from 'react-router-dom';
|
|
3
|
-
import { useServerState } from '../useServerState';
|
|
4
|
-
/**
|
|
5
|
-
* Since we don't render each <Route> on the client like React Router expects,
|
|
6
|
-
* this listens for changes to `location` and proxies the new pathname to
|
|
7
|
-
* server state, which in turn fetches the correct server component.
|
|
8
|
-
*/
|
|
9
|
-
export function ServerStateRouter() {
|
|
10
|
-
const { setServerState, pending, serverState } = useServerState();
|
|
11
|
-
const [isNavigating, setIsNavigating] = useState(false);
|
|
12
|
-
const location = useLocation();
|
|
13
|
-
useEffect(() => {
|
|
14
|
-
if (serverState.pathname !== location.pathname ||
|
|
15
|
-
serverState.search !== location.search) {
|
|
16
|
-
setIsNavigating(true);
|
|
17
|
-
setServerState({ pathname: location.pathname, search: location.search });
|
|
18
|
-
}
|
|
19
|
-
}, [location.pathname, location.search, setServerState]);
|
|
20
|
-
useEffect(() => {
|
|
21
|
-
/**
|
|
22
|
-
* Indicates navigation has occurred
|
|
23
|
-
*/
|
|
24
|
-
if (isNavigating && !pending) {
|
|
25
|
-
window.scrollTo(0, 0);
|
|
26
|
-
setIsNavigating(false);
|
|
27
|
-
}
|
|
28
|
-
}, [isNavigating, pending]);
|
|
29
|
-
return null;
|
|
30
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const META_ENV_SSR: boolean;
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import type { ServerComponentRequest } from '../../framework/Hydration/ServerComponentRequest.server';
|
|
2
|
-
import type { QueryKey } from '../../types';
|
|
3
|
-
declare type ServerRequestProviderProps = {
|
|
4
|
-
isRSC: boolean;
|
|
5
|
-
request: ServerComponentRequest;
|
|
6
|
-
children: JSX.Element;
|
|
7
|
-
};
|
|
8
|
-
export declare function ServerRequestProvider({ isRSC, request, children, }: ServerRequestProviderProps): JSX.Element;
|
|
9
|
-
export declare function useServerRequest(): ServerComponentRequest;
|
|
10
|
-
declare type RequestCacheResult<T> = {
|
|
11
|
-
data: T;
|
|
12
|
-
error?: never;
|
|
13
|
-
} | {
|
|
14
|
-
data?: never;
|
|
15
|
-
error: Response;
|
|
16
|
-
};
|
|
17
|
-
/**
|
|
18
|
-
* Returns data stored in the request cache.
|
|
19
|
-
* It will throw the promise if data is not ready.
|
|
20
|
-
*/
|
|
21
|
-
export declare function useRequestCacheData<T>(key: QueryKey, fetcher: () => Promise<T>): RequestCacheResult<T>;
|
|
22
|
-
export {};
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
-
}) : (function(o, m, k, k2) {
|
|
6
|
-
if (k2 === undefined) k2 = k;
|
|
7
|
-
o[k2] = m[k];
|
|
8
|
-
}));
|
|
9
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
10
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
11
|
-
}) : function(o, v) {
|
|
12
|
-
o["default"] = v;
|
|
13
|
-
});
|
|
14
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
15
|
-
if (mod && mod.__esModule) return mod;
|
|
16
|
-
var result = {};
|
|
17
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
18
|
-
__setModuleDefault(result, mod);
|
|
19
|
-
return result;
|
|
20
|
-
};
|
|
21
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
-
exports.useRequestCacheData = exports.useServerRequest = exports.ServerRequestProvider = void 0;
|
|
23
|
-
const react_1 = __importStar(require("react"));
|
|
24
|
-
const cache_1 = require("../../framework/cache");
|
|
25
|
-
// Context to inject current request in SSR
|
|
26
|
-
const RequestContextSSR = (0, react_1.createContext)(null);
|
|
27
|
-
// Cache to inject current request in RSC
|
|
28
|
-
function requestCacheRSC() {
|
|
29
|
-
return new Map();
|
|
30
|
-
}
|
|
31
|
-
requestCacheRSC.key = Symbol.for('HYDROGEN_REQUEST');
|
|
32
|
-
function ServerRequestProvider({ isRSC, request, children, }) {
|
|
33
|
-
if (isRSC) {
|
|
34
|
-
// Save the request object in a React cache that is
|
|
35
|
-
// scoped to this current rendering.
|
|
36
|
-
// @ts-ignore
|
|
37
|
-
const requestCache = react_1.default.unstable_getCacheForType(requestCacheRSC);
|
|
38
|
-
requestCache.set(requestCacheRSC.key, request);
|
|
39
|
-
return children;
|
|
40
|
-
}
|
|
41
|
-
// Use a normal provider in SSR to make the request object
|
|
42
|
-
// available in the current rendering.
|
|
43
|
-
return (react_1.default.createElement(RequestContextSSR.Provider, { value: request }, children));
|
|
44
|
-
}
|
|
45
|
-
exports.ServerRequestProvider = ServerRequestProvider;
|
|
46
|
-
function useServerRequest() {
|
|
47
|
-
let request;
|
|
48
|
-
try {
|
|
49
|
-
// Context only works in SSR rendering
|
|
50
|
-
request = (0, react_1.useContext)(RequestContextSSR);
|
|
51
|
-
}
|
|
52
|
-
catch (error) {
|
|
53
|
-
// If normal context failed it means this is not an SSR request.
|
|
54
|
-
// Try getting RSC cache instead:
|
|
55
|
-
// @ts-ignore
|
|
56
|
-
const cache = react_1.default.unstable_getCacheForType(requestCacheRSC);
|
|
57
|
-
request = cache ? cache.get(requestCacheRSC.key) : null;
|
|
58
|
-
}
|
|
59
|
-
if (!request) {
|
|
60
|
-
// @ts-ignore
|
|
61
|
-
if (__DEV__ && typeof jest !== 'undefined') {
|
|
62
|
-
// Unit tests are not wrapped in ServerRequestProvider.
|
|
63
|
-
// This mocks it, instead of providing it in every test.
|
|
64
|
-
return { ctx: {} };
|
|
65
|
-
}
|
|
66
|
-
throw new Error('No ServerRequest Context found');
|
|
67
|
-
}
|
|
68
|
-
return request;
|
|
69
|
-
}
|
|
70
|
-
exports.useServerRequest = useServerRequest;
|
|
71
|
-
/**
|
|
72
|
-
* Returns data stored in the request cache.
|
|
73
|
-
* It will throw the promise if data is not ready.
|
|
74
|
-
*/
|
|
75
|
-
function useRequestCacheData(key, fetcher) {
|
|
76
|
-
const { cache } = useServerRequest().ctx;
|
|
77
|
-
const cacheKey = (0, cache_1.hashKey)(key);
|
|
78
|
-
if (!cache.has(cacheKey)) {
|
|
79
|
-
let data;
|
|
80
|
-
let promise;
|
|
81
|
-
cache.set(cacheKey, () => {
|
|
82
|
-
if (data !== undefined)
|
|
83
|
-
return data;
|
|
84
|
-
if (!promise) {
|
|
85
|
-
promise = fetcher().then((r) => (data = { data: r }), (e) => (data = { error: e }));
|
|
86
|
-
}
|
|
87
|
-
throw promise;
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
return cache.get(cacheKey).call();
|
|
91
|
-
}
|
|
92
|
-
exports.useRequestCacheData = useRequestCacheData;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './ServerRequestProvider';
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
-
}) : (function(o, m, k, k2) {
|
|
6
|
-
if (k2 === undefined) k2 = k;
|
|
7
|
-
o[k2] = m[k];
|
|
8
|
-
}));
|
|
9
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
10
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
11
|
-
};
|
|
12
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
-
__exportStar(require("./ServerRequestProvider"), exports);
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const META_ENV_SSR: boolean;
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import type { ServerComponentRequest } from '../../framework/Hydration/ServerComponentRequest.server';
|
|
2
|
-
import type { QueryKey } from '../../types';
|
|
3
|
-
declare type ServerRequestProviderProps = {
|
|
4
|
-
isRSC: boolean;
|
|
5
|
-
request: ServerComponentRequest;
|
|
6
|
-
children: JSX.Element;
|
|
7
|
-
};
|
|
8
|
-
export declare function ServerRequestProvider({ isRSC, request, children, }: ServerRequestProviderProps): JSX.Element;
|
|
9
|
-
export declare function useServerRequest(): ServerComponentRequest;
|
|
10
|
-
declare type RequestCacheResult<T> = {
|
|
11
|
-
data: T;
|
|
12
|
-
error?: never;
|
|
13
|
-
} | {
|
|
14
|
-
data?: never;
|
|
15
|
-
error: Response;
|
|
16
|
-
};
|
|
17
|
-
/**
|
|
18
|
-
* Returns data stored in the request cache.
|
|
19
|
-
* It will throw the promise if data is not ready.
|
|
20
|
-
*/
|
|
21
|
-
export declare function useRequestCacheData<T>(key: QueryKey, fetcher: () => Promise<T>): RequestCacheResult<T>;
|
|
22
|
-
export {};
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import React, { createContext, useContext } from 'react';
|
|
2
|
-
import { hashKey } from '../../framework/cache';
|
|
3
|
-
// Context to inject current request in SSR
|
|
4
|
-
const RequestContextSSR = createContext(null);
|
|
5
|
-
// Cache to inject current request in RSC
|
|
6
|
-
function requestCacheRSC() {
|
|
7
|
-
return new Map();
|
|
8
|
-
}
|
|
9
|
-
requestCacheRSC.key = Symbol.for('HYDROGEN_REQUEST');
|
|
10
|
-
export function ServerRequestProvider({ isRSC, request, children, }) {
|
|
11
|
-
if (isRSC) {
|
|
12
|
-
// Save the request object in a React cache that is
|
|
13
|
-
// scoped to this current rendering.
|
|
14
|
-
// @ts-ignore
|
|
15
|
-
const requestCache = React.unstable_getCacheForType(requestCacheRSC);
|
|
16
|
-
requestCache.set(requestCacheRSC.key, request);
|
|
17
|
-
return children;
|
|
18
|
-
}
|
|
19
|
-
// Use a normal provider in SSR to make the request object
|
|
20
|
-
// available in the current rendering.
|
|
21
|
-
return (React.createElement(RequestContextSSR.Provider, { value: request }, children));
|
|
22
|
-
}
|
|
23
|
-
export function useServerRequest() {
|
|
24
|
-
let request;
|
|
25
|
-
try {
|
|
26
|
-
// Context only works in SSR rendering
|
|
27
|
-
request = useContext(RequestContextSSR);
|
|
28
|
-
}
|
|
29
|
-
catch (error) {
|
|
30
|
-
// If normal context failed it means this is not an SSR request.
|
|
31
|
-
// Try getting RSC cache instead:
|
|
32
|
-
// @ts-ignore
|
|
33
|
-
const cache = React.unstable_getCacheForType(requestCacheRSC);
|
|
34
|
-
request = cache ? cache.get(requestCacheRSC.key) : null;
|
|
35
|
-
}
|
|
36
|
-
if (!request) {
|
|
37
|
-
// @ts-ignore
|
|
38
|
-
if (__DEV__ && typeof jest !== 'undefined') {
|
|
39
|
-
// Unit tests are not wrapped in ServerRequestProvider.
|
|
40
|
-
// This mocks it, instead of providing it in every test.
|
|
41
|
-
return { ctx: {} };
|
|
42
|
-
}
|
|
43
|
-
throw new Error('No ServerRequest Context found');
|
|
44
|
-
}
|
|
45
|
-
return request;
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* Returns data stored in the request cache.
|
|
49
|
-
* It will throw the promise if data is not ready.
|
|
50
|
-
*/
|
|
51
|
-
export function useRequestCacheData(key, fetcher) {
|
|
52
|
-
const { cache } = useServerRequest().ctx;
|
|
53
|
-
const cacheKey = hashKey(key);
|
|
54
|
-
if (!cache.has(cacheKey)) {
|
|
55
|
-
let data;
|
|
56
|
-
let promise;
|
|
57
|
-
cache.set(cacheKey, () => {
|
|
58
|
-
if (data !== undefined)
|
|
59
|
-
return data;
|
|
60
|
-
if (!promise) {
|
|
61
|
-
promise = fetcher().then((r) => (data = { data: r }), (e) => (data = { error: e }));
|
|
62
|
-
}
|
|
63
|
-
throw promise;
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
return cache.get(cacheKey).call();
|
|
67
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './ServerRequestProvider';
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './ServerRequestProvider';
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import type { CacheOptions, QueryKey } from '../types';
|
|
2
|
-
export declare function generateCacheControlHeader(options: CacheOptions): string;
|
|
3
|
-
/**
|
|
4
|
-
* Use a preview header during development.
|
|
5
|
-
* TODO: Support an override of this to force the cache
|
|
6
|
-
* header to be present during dev. ENV var maybe?
|
|
7
|
-
*/
|
|
8
|
-
export declare function getCacheControlHeader({ dev }: {
|
|
9
|
-
dev?: boolean;
|
|
10
|
-
}): "cache-control-preview" | "cache-control";
|
|
11
|
-
export declare function hashKey(key: QueryKey): string;
|
|
12
|
-
/**
|
|
13
|
-
* Get an item from the cache. If a match is found, returns a tuple
|
|
14
|
-
* containing the `JSON.parse` version of the response as well
|
|
15
|
-
* as the response itself so it can be checked for staleness.
|
|
16
|
-
*/
|
|
17
|
-
export declare function getItemFromCache(key: QueryKey): Promise<undefined | [any, Response]>;
|
|
18
|
-
/**
|
|
19
|
-
* Put an item into the cache.
|
|
20
|
-
*/
|
|
21
|
-
export declare function setItemInCache(key: QueryKey, value: any, userCacheOptions?: CacheOptions): Promise<void>;
|
|
22
|
-
export declare function deleteItemFromCache(key: QueryKey): Promise<void>;
|
|
23
|
-
/**
|
|
24
|
-
* Manually check the response to see if it's stale.
|
|
25
|
-
*/
|
|
26
|
-
export declare function isStale(response: Response): boolean;
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
import { getCache } from './runtime';
|
|
2
|
-
const DEFAULT_SUBREQUEST_CACHE_OPTIONS = {
|
|
3
|
-
maxAge: 1,
|
|
4
|
-
staleWhileRevalidate: 9,
|
|
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(', ');
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* Use a preview header during development.
|
|
18
|
-
* TODO: Support an override of this to force the cache
|
|
19
|
-
* header to be present during dev. ENV var maybe?
|
|
20
|
-
*/
|
|
21
|
-
export function getCacheControlHeader({ dev }) {
|
|
22
|
-
return dev ? 'cache-control-preview' : 'cache-control';
|
|
23
|
-
}
|
|
24
|
-
export function hashKey(key) {
|
|
25
|
-
const rawKey = key instanceof Array ? key : [key];
|
|
26
|
-
/**
|
|
27
|
-
* TODO: Smarter hash
|
|
28
|
-
*/
|
|
29
|
-
return rawKey.map((k) => JSON.stringify(k)).join('');
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* Cache API is weird. We just need a full URL, so we make one up.
|
|
33
|
-
*/
|
|
34
|
-
function getKeyUrl(key) {
|
|
35
|
-
return `https://shopify.dev/?${key}`;
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* Get an item from the cache. If a match is found, returns a tuple
|
|
39
|
-
* containing the `JSON.parse` version of the response as well
|
|
40
|
-
* as the response itself so it can be checked for staleness.
|
|
41
|
-
*/
|
|
42
|
-
export async function getItemFromCache(key) {
|
|
43
|
-
const cache = getCache();
|
|
44
|
-
if (!cache) {
|
|
45
|
-
return;
|
|
46
|
-
}
|
|
47
|
-
const url = getKeyUrl(hashKey(key));
|
|
48
|
-
const request = new Request(url);
|
|
49
|
-
const response = await cache.match(request);
|
|
50
|
-
if (!response)
|
|
51
|
-
return;
|
|
52
|
-
return [await response.json(), response];
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* Put an item into the cache.
|
|
56
|
-
*/
|
|
57
|
-
export async function setItemInCache(key, value, userCacheOptions) {
|
|
58
|
-
const cache = getCache();
|
|
59
|
-
if (!cache) {
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
const url = getKeyUrl(hashKey(key));
|
|
63
|
-
const request = new Request(url);
|
|
64
|
-
const cacheOptions = {
|
|
65
|
-
...DEFAULT_SUBREQUEST_CACHE_OPTIONS,
|
|
66
|
-
...(userCacheOptions !== null && userCacheOptions !== void 0 ? userCacheOptions : {}),
|
|
67
|
-
};
|
|
68
|
-
const headers = new Headers({
|
|
69
|
-
'cache-control': generateCacheControlHeader(cacheOptions),
|
|
70
|
-
});
|
|
71
|
-
const response = new Response(JSON.stringify(value), { headers });
|
|
72
|
-
/**
|
|
73
|
-
* WARNING: Cloudflare's Cache API does not support `stale-while-revalidate`
|
|
74
|
-
* so this implementation will not work as expected on that platform.
|
|
75
|
-
*/
|
|
76
|
-
await cache.put(request, response);
|
|
77
|
-
}
|
|
78
|
-
export async function deleteItemFromCache(key) {
|
|
79
|
-
const cache = getCache();
|
|
80
|
-
if (!cache)
|
|
81
|
-
return;
|
|
82
|
-
const url = getKeyUrl(hashKey(key));
|
|
83
|
-
const request = new Request(url);
|
|
84
|
-
await cache.delete(request);
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* Manually check the response to see if it's stale.
|
|
88
|
-
*/
|
|
89
|
-
export function isStale(response) {
|
|
90
|
-
const responseDate = response.headers.get('date');
|
|
91
|
-
const responseCacheControl = response.headers.get('cache-control');
|
|
92
|
-
if (!responseDate || !responseCacheControl)
|
|
93
|
-
return false;
|
|
94
|
-
const responseMaxAgeMatch = responseCacheControl.match(/max-age=(\d+)/);
|
|
95
|
-
if (!responseMaxAgeMatch)
|
|
96
|
-
return false;
|
|
97
|
-
const responseMaxAge = parseInt(responseMaxAgeMatch[1]);
|
|
98
|
-
const ageInMs = new Date().valueOf() - new Date(responseDate).valueOf();
|
|
99
|
-
const age = ageInMs / 1000;
|
|
100
|
-
return age > responseMaxAge;
|
|
101
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const META_ENV_SSR: any;
|