@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.
Files changed (99) hide show
  1. package/dist/esnext/client.d.ts +0 -1
  2. package/dist/esnext/client.js +0 -1
  3. package/dist/esnext/components/CartLines/CartLines.d.ts +3 -4
  4. package/dist/esnext/components/CartLines/CartLines.js +3 -5
  5. package/dist/esnext/components/CartShopPayButton/CartShopPayButton.client.js +6 -3
  6. package/dist/esnext/components/Link/Link.client.d.ts +18 -1
  7. package/dist/esnext/components/Link/Link.client.js +42 -4
  8. package/dist/esnext/components/Metafield/Metafield.client.d.ts +1 -1
  9. package/dist/esnext/components/Router/index.d.ts +1 -0
  10. package/dist/esnext/components/Router/index.js +1 -0
  11. package/dist/esnext/components/Seo/CollectionSeo.client.js +2 -2
  12. package/dist/esnext/components/Seo/ProductSeo.client.d.ts +1 -1
  13. package/dist/esnext/components/Seo/ProductSeo.client.js +4 -8
  14. package/dist/esnext/components/Seo/types.d.ts +2 -6
  15. package/dist/esnext/components/ShopPayButton/ShopPayButton.client.d.ts +22 -5
  16. package/dist/esnext/components/ShopPayButton/ShopPayButton.client.js +45 -12
  17. package/dist/esnext/components/UnitPrice/UnitPrice.client.d.ts +1 -6
  18. package/dist/esnext/components/UnitPrice/UnitPrice.client.js +3 -12
  19. package/dist/esnext/components/index.d.ts +2 -2
  20. package/dist/esnext/components/index.js +2 -48
  21. package/dist/esnext/constants.d.ts +1 -0
  22. package/dist/esnext/constants.js +1 -0
  23. package/dist/esnext/entry-client.js +3 -4
  24. package/dist/esnext/entry-server.js +2 -1
  25. package/dist/esnext/foundation/Helmet/Helmet.client.js +2 -6
  26. package/dist/esnext/foundation/Router/Router.client.d.ts +12 -0
  27. package/dist/esnext/foundation/Router/Router.client.js +44 -0
  28. package/dist/esnext/foundation/ssr-interop.d.ts +29 -0
  29. package/dist/esnext/foundation/ssr-interop.js +35 -0
  30. package/dist/esnext/foundation/useQuery/hooks.d.ts +1 -1
  31. package/dist/esnext/foundation/useQuery/hooks.js +1 -1
  32. package/dist/esnext/foundation/useServerState/use-server-state.d.ts +2 -1
  33. package/dist/esnext/foundation/useServerState/use-server-state.js +2 -2
  34. package/dist/esnext/foundation/useShop/use-shop.js +2 -6
  35. package/dist/esnext/foundation/useUrl/useUrl.d.ts +1 -1
  36. package/dist/esnext/foundation/useUrl/useUrl.js +5 -5
  37. package/dist/esnext/framework/Hydration/Html.js +13 -1
  38. package/dist/esnext/framework/Hydration/rsc.d.ts +1 -1
  39. package/dist/esnext/framework/Hydration/rsc.js +4 -4
  40. package/dist/esnext/framework/plugin.js +2 -0
  41. package/dist/esnext/framework/plugins/vite-plugin-hydrogen-config.js +1 -1
  42. package/dist/esnext/framework/plugins/vite-plugin-hydrogen-middleware.js +1 -1
  43. package/dist/esnext/framework/plugins/vite-plugin-ssr-interop.d.ts +3 -0
  44. package/dist/esnext/framework/plugins/vite-plugin-ssr-interop.js +13 -0
  45. package/dist/esnext/handle-event.js +2 -1
  46. package/dist/esnext/hooks/useNavigate/index.d.ts +1 -0
  47. package/dist/esnext/hooks/useNavigate/index.js +1 -0
  48. package/dist/esnext/hooks/useNavigate/useNavigate.d.ts +10 -0
  49. package/dist/esnext/hooks/useNavigate/useNavigate.js +11 -0
  50. package/dist/esnext/utilities/error.js +3 -12
  51. package/dist/esnext/utilities/fetch.js +8 -0
  52. package/dist/esnext/utilities/log/log.d.ts +4 -3
  53. package/dist/esnext/utilities/video_parameters.js +4 -0
  54. package/dist/esnext/version.d.ts +1 -1
  55. package/dist/esnext/version.js +1 -1
  56. package/dist/node/constants.d.ts +1 -0
  57. package/dist/node/constants.js +4 -0
  58. package/dist/node/foundation/Helmet/Helmet.client.js +2 -6
  59. package/dist/node/foundation/ssr-interop.d.ts +29 -0
  60. package/dist/node/foundation/ssr-interop.js +39 -0
  61. package/dist/node/framework/Hydration/Html.js +13 -1
  62. package/dist/node/framework/Hydration/rsc.d.ts +1 -1
  63. package/dist/node/framework/Hydration/rsc.js +4 -4
  64. package/dist/node/framework/plugin.js +2 -0
  65. package/dist/node/framework/plugins/vite-plugin-hydrogen-config.js +1 -1
  66. package/dist/node/framework/plugins/vite-plugin-hydrogen-middleware.js +1 -1
  67. package/dist/node/framework/plugins/vite-plugin-ssr-interop.d.ts +3 -0
  68. package/dist/node/framework/plugins/vite-plugin-ssr-interop.js +15 -0
  69. package/dist/node/handle-event.js +2 -1
  70. package/dist/node/utilities/log/log.d.ts +4 -3
  71. package/dist/worker/constants.d.ts +1 -0
  72. package/dist/worker/constants.js +1 -0
  73. package/dist/worker/foundation/Helmet/Helmet.client.js +2 -6
  74. package/dist/worker/foundation/ssr-interop.d.ts +29 -0
  75. package/dist/worker/foundation/ssr-interop.js +35 -0
  76. package/dist/worker/handle-event.js +2 -1
  77. package/dist/worker/utilities/log/log.d.ts +4 -3
  78. package/package.json +4 -5
  79. package/vendor/react-server-dom-vite/cjs/react-server-dom-vite-plugin.js +1 -5
  80. package/vendor/react-server-dom-vite/esm/react-server-dom-vite-client-proxy.js +1 -0
  81. package/vendor/react-server-dom-vite/esm/react-server-dom-vite-plugin.js +1 -5
  82. package/dist/esnext/foundation/Router/ServerStateRouter.client.d.ts +0 -6
  83. package/dist/esnext/foundation/Router/ServerStateRouter.client.js +0 -30
  84. package/dist/esnext/utilities/meta-env-ssr.d.ts +0 -1
  85. package/dist/esnext/utilities/meta-env-ssr.js +0 -3
  86. package/dist/node/foundation/ServerRequestProvider/ServerRequestProvider.d.ts +0 -22
  87. package/dist/node/foundation/ServerRequestProvider/ServerRequestProvider.js +0 -92
  88. package/dist/node/foundation/ServerRequestProvider/index.d.ts +0 -1
  89. package/dist/node/foundation/ServerRequestProvider/index.js +0 -13
  90. package/dist/node/utilities/meta-env-ssr.d.ts +0 -1
  91. package/dist/node/utilities/meta-env-ssr.js +0 -6
  92. package/dist/worker/foundation/ServerRequestProvider/ServerRequestProvider.d.ts +0 -22
  93. package/dist/worker/foundation/ServerRequestProvider/ServerRequestProvider.js +0 -67
  94. package/dist/worker/foundation/ServerRequestProvider/index.d.ts +0 -1
  95. package/dist/worker/foundation/ServerRequestProvider/index.js +0 -1
  96. package/dist/worker/framework/cache.d.ts +0 -26
  97. package/dist/worker/framework/cache.js +0 -101
  98. package/dist/worker/utilities/meta-env-ssr.d.ts +0 -1
  99. package/dist/worker/utilities/meta-env-ssr.js +0 -3
@@ -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
+ }
@@ -4,7 +4,7 @@ export interface HydrogenUseQueryOptions {
4
4
  }
5
5
  /**
6
6
  * The `useQuery` hook is a wrapper around Suspense calls and
7
- * global runtime's Cache if it exist.
7
+ * global runtime's Cache if it exists.
8
8
  * It supports Suspense calls on the server and on the client.
9
9
  */
10
10
  export declare function useQuery<T>(
@@ -4,7 +4,7 @@ import { runDelayedFunction } from '../../framework/runtime';
4
4
  import { useRequestCacheData } from '../ServerRequestProvider';
5
5
  /**
6
6
  * The `useQuery` hook is a wrapper around Suspense calls and
7
- * global runtime's Cache if it exist.
7
+ * global runtime's Cache if it exists.
8
8
  * It supports Suspense calls on the server and on the client.
9
9
  */
10
10
  export function useQuery(
@@ -1,3 +1,4 @@
1
+ import { ServerStateContextValue } from '../ServerStateProvider';
1
2
  /**
2
3
  * The `useServerState` hook allows you to [manage server state](/custom-storefronts/hydrogen/framework/server-state) when using Hydrogen as a React Server Component framework.
3
4
  *
@@ -12,4 +13,4 @@
12
13
  * | `pending` | Whether a [transition is pending](https://github.com/reactwg/react-18/discussions/41). |
13
14
  *
14
15
  */
15
- export declare function useServerState(): import("../ServerStateProvider").ServerStateContextValue;
16
+ export declare function useServerState(): ServerStateContextValue;
@@ -1,5 +1,5 @@
1
1
  import { useContext } from 'react';
2
- import { ServerStateContext } from '../ServerStateProvider';
2
+ import { ServerStateContext, } from '../ServerStateProvider';
3
3
  /**
4
4
  * The `useServerState` hook allows you to [manage server state](/custom-storefronts/hydrogen/framework/server-state) when using Hydrogen as a React Server Component framework.
5
5
  *
@@ -16,5 +16,5 @@ import { ServerStateContext } from '../ServerStateProvider';
16
16
  */
17
17
  export function useServerState() {
18
18
  var _a;
19
- return (_a = useContext(ServerStateContext)) !== null && _a !== void 0 ? _a : {};
19
+ return ((_a = useContext(ServerStateContext)) !== null && _a !== void 0 ? _a : {});
20
20
  }
@@ -1,14 +1,10 @@
1
- import { useContext } from 'react';
2
1
  import { ShopifyContext } from '../ShopifyProvider';
3
- import { useServerRequest } from '../ServerRequestProvider';
4
- import { META_ENV_SSR } from '../../utilities/meta-env-ssr';
2
+ import { useEnvContext } from '../ssr-interop';
5
3
  /**
6
4
  * The `useShop` hook provides access to values within `shopify.config.js`. It must be a descendent of a `ShopifyProvider` component.
7
5
  */
8
6
  export function useShop() {
9
- const config = META_ENV_SSR
10
- ? useServerRequest().ctx.shopifyConfig
11
- : useContext(ShopifyContext);
7
+ const config = useEnvContext((req) => req.ctx.shopifyConfig, ShopifyContext);
12
8
  if (!config) {
13
9
  throw new Error('No Shopify Context found');
14
10
  }
@@ -1,4 +1,4 @@
1
1
  /**
2
- * Use to get current url in server or client component.
2
+ * The `useUrl` hook retrieves the current URL in a server or client component.
3
3
  */
4
4
  export declare function useUrl(): URL;
@@ -1,13 +1,13 @@
1
- import { META_ENV_SSR } from '../../utilities/meta-env-ssr';
2
- import { useServerRequest } from '../ServerRequestProvider';
1
+ import { RSC_PATHNAME } from '../../constants';
2
+ import { useEnvContext, META_ENV_SSR } from '../ssr-interop';
3
3
  /**
4
- * Use to get current url in server or client component.
4
+ * The `useUrl` hook retrieves the current URL in a server or client component.
5
5
  */
6
6
  export function useUrl() {
7
7
  var _a, _b;
8
8
  if (META_ENV_SSR) {
9
- const serverUrl = new URL(useServerRequest().url);
10
- if (serverUrl.pathname === '/react') {
9
+ const serverUrl = new URL(useEnvContext((req) => req.url));
10
+ if (serverUrl.pathname === RSC_PATHNAME) {
11
11
  const state = JSON.parse(serverUrl.searchParams.get('state') || '{}');
12
12
  const parsedUrl = `${serverUrl.origin}/${(_a = state.pathname) !== null && _a !== void 0 ? _a : ''}${(_b = state.search) !== null && _b !== void 0 ? _b : ''}`;
13
13
  return new URL(parsedUrl);
@@ -1,10 +1,22 @@
1
1
  /// <reference types="vite/client" />
2
2
  import React from 'react';
3
3
  export function Html({ children, template, htmlAttrs, bodyAttrs }) {
4
+ var _a;
4
5
  const head = template.match(/<head>(.+?)<\/head>/s)[1] || '';
6
+ let devEntryPoint = '';
7
+ // @ts-ignore
8
+ if (import.meta.env.DEV) {
9
+ devEntryPoint =
10
+ ((_a = template
11
+ .substring(template.lastIndexOf('<script type="module"'))
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
+ }
16
+ }
5
17
  return (React.createElement("html", { ...htmlAttrs },
6
18
  React.createElement("head", { dangerouslySetInnerHTML: { __html: head } }),
7
19
  React.createElement("body", { ...bodyAttrs },
8
20
  React.createElement("div", { id: "root" }, children),
9
- import.meta.env.DEV && (React.createElement("script", { type: "module", src: "/src/entry-client.jsx" })))));
21
+ import.meta.env.DEV && (React.createElement("script", { type: "module", src: devEntryPoint })))));
10
22
  }
@@ -8,4 +8,4 @@ declare global {
8
8
  * Note that we'd want to add some other constraints and controls around caching here.
9
9
  */
10
10
  export declare function useServerResponse(state: any): any;
11
- export declare function useRefresh(): (key: string, seededResponse: any) => void;
11
+ export declare function useRefresh(): void;
@@ -5,6 +5,7 @@ import { unstable_getCacheForType, unstable_useCacheRefresh } from 'react';
5
5
  import { createFromFetch, createFromReadableStream,
6
6
  // @ts-ignore
7
7
  } from '@shopify/hydrogen/vendor/react-server-dom-vite';
8
+ import { RSC_PATHNAME } from '../../constants';
8
9
  let rscReader;
9
10
  if (__flight && __flight.length > 0) {
10
11
  const contentLoaded = new Promise((resolve) => document.addEventListener('DOMContentLoaded', resolve));
@@ -59,14 +60,13 @@ export function useServerResponse(state) {
59
60
  window.BOOMR.plugins.Hydrogen.trackSubPageLoadPerformance();
60
61
  }
61
62
  // Request a new flight response.
62
- response = createFromFetch(fetch('/react?state=' + encodeURIComponent(key)));
63
+ response = createFromFetch(fetch(`${RSC_PATHNAME}?state=` + encodeURIComponent(key)));
63
64
  }
65
+ cache.clear();
64
66
  cache.set(key, response);
65
67
  return response;
66
68
  }
67
69
  export function useRefresh() {
68
70
  const refreshCache = unstable_useCacheRefresh();
69
- return function refresh(key, seededResponse) {
70
- refreshCache(createResponseCache, new Map([[key, seededResponse]]));
71
- };
71
+ refreshCache();
72
72
  }
@@ -2,6 +2,7 @@ import hydrogenConfig from './plugins/vite-plugin-hydrogen-config';
2
2
  import hydrogenMiddleware from './plugins/vite-plugin-hydrogen-middleware';
3
3
  // @ts-ignore
4
4
  import rsc from '@shopify/hydrogen/vendor/react-server-dom-vite/plugin';
5
+ import ssrInterop from './plugins/vite-plugin-ssr-interop';
5
6
  import purgeQueryCache from './plugins/vite-plugin-purge-query-cache';
6
7
  import inspect from 'vite-plugin-inspect';
7
8
  import react from '@vitejs/plugin-react';
@@ -12,6 +13,7 @@ export default (shopifyConfig, pluginOptions = {}) => {
12
13
  hydrogenConfig(),
13
14
  hydrogenMiddleware(shopifyConfig, pluginOptions),
14
15
  react(),
16
+ ssrInterop(),
15
17
  rsc({
16
18
  clientComponentPaths: [
17
19
  path.join(path.dirname(require.resolve('@shopify/hydrogen/package.json'))),
@@ -53,7 +53,6 @@ export default () => {
53
53
  */
54
54
  'react',
55
55
  'react-dom',
56
- 'react-router-dom',
57
56
  'react-server-dom-vite/client-proxy',
58
57
  ],
59
58
  },
@@ -62,6 +61,7 @@ export default () => {
62
61
  __WORKER__: !!process.env.WORKER,
63
62
  },
64
63
  envPrefix: ['VITE_', 'PUBLIC_'],
64
+ base: process.env.HYDROGEN_ASSET_BASE_URL,
65
65
  }),
66
66
  // TODO: Remove when react-dom/fizz is fixed
67
67
  generateBundle: process.env.WORKER
@@ -31,7 +31,7 @@ export default (shopifyConfig, pluginOptions) => {
31
31
  dev: true,
32
32
  shopifyConfig,
33
33
  indexTemplate: getIndexTemplate,
34
- getServerEntrypoint: async () => await server.ssrLoadModule('/src/entry-server'),
34
+ getServerEntrypoint: async () => await server.ssrLoadModule(process.env.HYDROGEN_SERVER_ENTRY || '/src/entry-server'),
35
35
  devServer: server,
36
36
  cache: (pluginOptions === null || pluginOptions === void 0 ? void 0 : pluginOptions.devCache)
37
37
  ? new InMemoryCache()
@@ -0,0 +1,3 @@
1
+ import type { Plugin } from 'vite';
2
+ declare const _default: () => Plugin;
3
+ export default _default;
@@ -0,0 +1,13 @@
1
+ export default () => {
2
+ return {
3
+ name: 'vite-plugin-ssr-interop',
4
+ enforce: 'pre',
5
+ transform(code, id, options = {}) {
6
+ if (options.ssr && id.includes('foundation/ssr-interop')) {
7
+ return code
8
+ .replace(/(\s*META_ENV_SSR\s*=\s*)false/, '$1import.meta.env.SSR')
9
+ .replace(/\/\/@SSR\s*/g, '');
10
+ }
11
+ },
12
+ };
13
+ };
@@ -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 === '/react';
13
+ const isReactHydrationRequest = url.pathname === RSC_PATHNAME;
13
14
  const template = typeof indexTemplate === 'function'
14
15
  ? await indexTemplate(url.toString())
15
16
  : indexTemplate;
@@ -0,0 +1 @@
1
+ export { useNavigate } from './useNavigate';
@@ -0,0 +1 @@
1
+ export { useNavigate } from './useNavigate';
@@ -0,0 +1,10 @@
1
+ declare type NavigationOptions = {
2
+ /** Whether to update the state object or URL of the current history entry. Default to false */
3
+ replace?: boolean;
4
+ /** Whether to reload the whole document on navigation */
5
+ reloadDocument?: boolean;
6
+ /** The custom client state with the navigation */
7
+ clientState?: any;
8
+ };
9
+ export declare function useNavigate(): (path: string, options?: NavigationOptions) => void;
10
+ export {};
@@ -0,0 +1,11 @@
1
+ import { useRouter } from '../../foundation/Router/Router.client';
2
+ export function useNavigate() {
3
+ const router = useRouter();
4
+ return (path, options = { replace: false, reloadDocument: false }) => {
5
+ // @todo wait for RSC and then change focus for a11y?
6
+ if (options === null || options === void 0 ? void 0 : options.replace)
7
+ router.history.replace(path, (options === null || options === void 0 ? void 0 : options.clientState) || {});
8
+ else
9
+ router.history.push(path, (options === null || options === void 0 ? void 0 : options.clientState) || {});
10
+ };
11
+ }
@@ -1,15 +1,6 @@
1
1
  export function getErrorMarkup(error) {
2
- return `<script>
3
- import('/@vite/client')
4
- .then(() => {
5
- const err = new Error(\`${error.message}\`);
6
- err.stack = \`${error.stack}\`;
7
- const ErrorOverlay = customElements.get('vite-error-overlay')
8
- // don't open outside vite environment
9
- if (!ErrorOverlay) {return}
10
- console.log(err)
11
- const overlay = new ErrorOverlay(err)
12
- document.body.appendChild(overlay)
13
- })
2
+ return `<script type="module">
3
+ import {ErrorOverlay} from '/@vite/client';
4
+ document.body.appendChild(new ErrorOverlay(${JSON.stringify(error, Object.getOwnPropertyNames(error)).replace(/</g, '\\u003c')}));
14
5
  </script>`;
15
6
  }
@@ -52,6 +52,14 @@ export function graphqlRequestBody(query, variables) {
52
52
  });
53
53
  }
54
54
  export function decodeShopifyId(id) {
55
+ // Start fix: for SFAPI 2022-01. Remove when upgrading to 2022-04
56
+ if (!id.startsWith('gid://')) {
57
+ id =
58
+ typeof btoa !== 'undefined'
59
+ ? btoa(id)
60
+ : Buffer.from(id, 'base64').toString('ascii');
61
+ }
62
+ // End fix
55
63
  if (!id.startsWith('gid://')) {
56
64
  throw new Error('invalid Shopify ID');
57
65
  }
@@ -1,7 +1,8 @@
1
1
  import { ServerComponentRequest } from '../../framework/Hydration/ServerComponentRequest.server';
2
- /** A utility for logging debugging, warning, and error information about the application.
3
- * Use by importing `log` `@shopify/hydrogen` or by using a `log` prop passed to each page
4
- * component. Using the latter is ideal, because it will ty your log to the current request in progress.
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;
@@ -13,6 +13,10 @@ export function addParametersToEmbeddedVideoUrl(url, parameters) {
13
13
  return `${url}?${params}`;
14
14
  }
15
15
  export function useEmbeddedVideoUrl(url, parameters) {
16
+ // Ensure a youtube shortened url is changed to an iFrame compatible embed link.
17
+ // TODO: Fix is needed for SFAPI version 2022-01. Starting 2022-04 embeddedUrl has been marked as deprecated and replaced with
18
+ // embedUrl. When the pinned SFAPI version is 2022-04 line can be removed in favor of changes on PR #455
19
+ url = url.replace(/youtu\.be/, 'www.youtube.com/embed');
16
20
  return useMemo(() => {
17
21
  if (!parameters) {
18
22
  return url;
@@ -1 +1 @@
1
- export declare const LIB_VERSION = "0.11.0-experimental.0";
1
+ export declare const LIB_VERSION = "0.11.0-experimental.1";
@@ -1 +1 @@
1
- export const LIB_VERSION = '0.11.0-experimental.0';
1
+ export const LIB_VERSION = '0.11.0-experimental.1';
@@ -0,0 +1 @@
1
+ export declare const RSC_PATHNAME = "/__rsc";
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RSC_PATHNAME = void 0;
4
+ exports.RSC_PATHNAME = '/__rsc';
@@ -6,14 +6,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.Helmet = void 0;
7
7
  const react_1 = __importDefault(require("react"));
8
8
  const react_helmet_async_1 = require("react-helmet-async");
9
- const ServerRequestProvider_1 = require("../ServerRequestProvider");
10
- const meta_env_ssr_1 = require("../../utilities/meta-env-ssr");
9
+ const ssr_interop_1 = require("../ssr-interop");
11
10
  const clientHelmetData = new react_helmet_async_1.HelmetData({});
12
11
  function Helmet({ children, ...props }) {
13
- // @ts-ignore
14
- const helmetData = meta_env_ssr_1.META_ENV_SSR
15
- ? (0, ServerRequestProvider_1.useServerRequest)().ctx.helmet
16
- : clientHelmetData;
12
+ const helmetData = (0, ssr_interop_1.useEnvContext)((req) => req.ctx.helmet, clientHelmetData);
17
13
  return (
18
14
  // @ts-ignore
19
15
  react_1.default.createElement(react_helmet_async_1.Helmet, { ...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,39 @@
1
+ "use strict";
2
+ /**
3
+ * This file is used for compatibility between browser and server environments.
4
+ * The browser loads this file as is, without leaking server logic.
5
+ * In the server, this file is transformed by Vite to inject server logic.
6
+ * NOTE: Do not remove SSR-prefixed comments in this file.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.useEnvContext = exports.META_ENV_SSR = void 0;
10
+ const react_1 = require("react");
11
+ //@SSR import {useServerRequest} from './ServerRequestProvider';
12
+ // This is replaced by Vite to import.meta.env.SSR
13
+ exports.META_ENV_SSR = false;
14
+ const reactContextType = Symbol.for('react.context');
15
+ /**
16
+ * Isomorphic hook to access context data. It gives access to the current request
17
+ * when running on the server, and returns the provided client fallback in the browser.
18
+ * This can be used in server components (RSC) as a Context/Provider replacement. In client
19
+ * components, it uses the server getter in SSR and the client fallback in the browser.
20
+ * @param serverGetter - A function that gets the current server request and returns any
21
+ * desired request property. It only runs in the server (both in RSC and SSR).
22
+ * @param clientFallback - An optional raw value or a React.Context to be consumed that will be
23
+ * returned if the current environment is not the server. Note that, if this is a React.Context,
24
+ * there must be a React.Provider parent in the app tree.
25
+ * @returns A value retrieved from the current server request or a fallback value in the client.
26
+ * The returned type depends on what the server getter returns.
27
+ * @example
28
+ * ```js
29
+ * import {MyClientContext} from './my-client-react-context-provider';
30
+ * useEnvContext(req => req.ctx.myServerContext, MyClientContext)
31
+ * ```
32
+ */
33
+ function useEnvContext(serverGetter, clientFallback) {
34
+ //@SSR if (META_ENV_SSR) return serverGetter(useServerRequest());
35
+ return clientFallback && clientFallback.$$typeof === reactContextType
36
+ ? (0, react_1.useContext)(clientFallback)
37
+ : clientFallback;
38
+ }
39
+ exports.useEnvContext = useEnvContext;
@@ -7,11 +7,23 @@ exports.Html = void 0;
7
7
  /// <reference types="vite/client" />
8
8
  const react_1 = __importDefault(require("react"));
9
9
  function Html({ children, template, htmlAttrs, bodyAttrs }) {
10
+ var _a;
10
11
  const head = template.match(/<head>(.+?)<\/head>/s)[1] || '';
12
+ let devEntryPoint = '';
13
+ // @ts-ignore
14
+ if (import.meta.env.DEV) {
15
+ devEntryPoint =
16
+ ((_a = template
17
+ .substring(template.lastIndexOf('<script type="module"'))
18
+ .match(/src="(.*?)">/i)) === null || _a === void 0 ? void 0 : _a[1]) || '';
19
+ if (!devEntryPoint) {
20
+ throw new Error('Could not find entry-client module in index.html');
21
+ }
22
+ }
11
23
  return (react_1.default.createElement("html", { ...htmlAttrs },
12
24
  react_1.default.createElement("head", { dangerouslySetInnerHTML: { __html: head } }),
13
25
  react_1.default.createElement("body", { ...bodyAttrs },
14
26
  react_1.default.createElement("div", { id: "root" }, children),
15
- import.meta.env.DEV && (react_1.default.createElement("script", { type: "module", src: "/src/entry-client.jsx" })))));
27
+ import.meta.env.DEV && (react_1.default.createElement("script", { type: "module", src: devEntryPoint })))));
16
28
  }
17
29
  exports.Html = Html;
@@ -8,4 +8,4 @@ declare global {
8
8
  * Note that we'd want to add some other constraints and controls around caching here.
9
9
  */
10
10
  export declare function useServerResponse(state: any): any;
11
- export declare function useRefresh(): (key: string, seededResponse: any) => void;
11
+ export declare function useRefresh(): void;
@@ -6,6 +6,7 @@ exports.useRefresh = exports.useServerResponse = void 0;
6
6
  // @ts-ignore
7
7
  const react_1 = require("react");
8
8
  const react_server_dom_vite_1 = require("@shopify/hydrogen/vendor/react-server-dom-vite");
9
+ const constants_1 = require("../../constants");
9
10
  let rscReader;
10
11
  if (__flight && __flight.length > 0) {
11
12
  const contentLoaded = new Promise((resolve) => document.addEventListener('DOMContentLoaded', resolve));
@@ -60,16 +61,15 @@ function useServerResponse(state) {
60
61
  window.BOOMR.plugins.Hydrogen.trackSubPageLoadPerformance();
61
62
  }
62
63
  // Request a new flight response.
63
- response = (0, react_server_dom_vite_1.createFromFetch)(fetch('/react?state=' + encodeURIComponent(key)));
64
+ response = (0, react_server_dom_vite_1.createFromFetch)(fetch(`${constants_1.RSC_PATHNAME}?state=` + encodeURIComponent(key)));
64
65
  }
66
+ cache.clear();
65
67
  cache.set(key, response);
66
68
  return response;
67
69
  }
68
70
  exports.useServerResponse = useServerResponse;
69
71
  function useRefresh() {
70
72
  const refreshCache = (0, react_1.unstable_useCacheRefresh)();
71
- return function refresh(key, seededResponse) {
72
- refreshCache(createResponseCache, new Map([[key, seededResponse]]));
73
- };
73
+ refreshCache();
74
74
  }
75
75
  exports.useRefresh = useRefresh;
@@ -7,6 +7,7 @@ const vite_plugin_hydrogen_config_1 = __importDefault(require("./plugins/vite-pl
7
7
  const vite_plugin_hydrogen_middleware_1 = __importDefault(require("./plugins/vite-plugin-hydrogen-middleware"));
8
8
  // @ts-ignore
9
9
  const plugin_1 = __importDefault(require("@shopify/hydrogen/vendor/react-server-dom-vite/plugin"));
10
+ const vite_plugin_ssr_interop_1 = __importDefault(require("./plugins/vite-plugin-ssr-interop"));
10
11
  const vite_plugin_purge_query_cache_1 = __importDefault(require("./plugins/vite-plugin-purge-query-cache"));
11
12
  const vite_plugin_inspect_1 = __importDefault(require("vite-plugin-inspect"));
12
13
  const plugin_react_1 = __importDefault(require("@vitejs/plugin-react"));
@@ -17,6 +18,7 @@ exports.default = (shopifyConfig, pluginOptions = {}) => {
17
18
  (0, vite_plugin_hydrogen_config_1.default)(),
18
19
  (0, vite_plugin_hydrogen_middleware_1.default)(shopifyConfig, pluginOptions),
19
20
  (0, plugin_react_1.default)(),
21
+ (0, vite_plugin_ssr_interop_1.default)(),
20
22
  (0, plugin_1.default)({
21
23
  clientComponentPaths: [
22
24
  path_1.default.join(path_1.default.dirname(require.resolve('@shopify/hydrogen/package.json'))),
@@ -55,7 +55,6 @@ exports.default = () => {
55
55
  */
56
56
  'react',
57
57
  'react-dom',
58
- 'react-router-dom',
59
58
  'react-server-dom-vite/client-proxy',
60
59
  ],
61
60
  },
@@ -64,6 +63,7 @@ exports.default = () => {
64
63
  __WORKER__: !!process.env.WORKER,
65
64
  },
66
65
  envPrefix: ['VITE_', 'PUBLIC_'],
66
+ base: process.env.HYDROGEN_ASSET_BASE_URL,
67
67
  }),
68
68
  // TODO: Remove when react-dom/fizz is fixed
69
69
  generateBundle: process.env.WORKER
@@ -36,7 +36,7 @@ exports.default = (shopifyConfig, pluginOptions) => {
36
36
  dev: true,
37
37
  shopifyConfig,
38
38
  indexTemplate: getIndexTemplate,
39
- getServerEntrypoint: async () => await server.ssrLoadModule('/src/entry-server'),
39
+ getServerEntrypoint: async () => await server.ssrLoadModule(process.env.HYDROGEN_SERVER_ENTRY || '/src/entry-server'),
40
40
  devServer: server,
41
41
  cache: (pluginOptions === null || pluginOptions === void 0 ? void 0 : pluginOptions.devCache)
42
42
  ? new in_memory_1.InMemoryCache()
@@ -0,0 +1,3 @@
1
+ import type { Plugin } from 'vite';
2
+ declare const _default: () => Plugin;
3
+ export default _default;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = () => {
4
+ return {
5
+ name: 'vite-plugin-ssr-interop',
6
+ enforce: 'pre',
7
+ transform(code, id, options = {}) {
8
+ if (options.ssr && id.includes('foundation/ssr-interop')) {
9
+ return code
10
+ .replace(/(\s*META_ENV_SSR\s*=\s*)false/, '$1import.meta.env.SSR')
11
+ .replace(/\/\/@SSR\s*/g, '');
12
+ }
13
+ },
14
+ };
15
+ };
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const runtime_1 = require("./framework/runtime");
4
4
  const config_1 = require("./framework/config");
5
5
  const apiRoutes_1 = require("./utilities/apiRoutes");
6
+ const constants_1 = require("./constants");
6
7
  async function handleEvent(event, { request, entrypoint, indexTemplate, assetHandler, streamableResponse, dev, cache, context, nonce, }) {
7
8
  const url = new URL(request.url);
8
9
  /**
@@ -11,7 +12,7 @@ async function handleEvent(event, { request, entrypoint, indexTemplate, assetHan
11
12
  (0, runtime_1.setCache)(cache);
12
13
  (0, runtime_1.setContext)(context);
13
14
  (0, config_1.setConfig)({ dev });
14
- const isReactHydrationRequest = url.pathname === '/react';
15
+ const isReactHydrationRequest = url.pathname === constants_1.RSC_PATHNAME;
15
16
  const template = typeof indexTemplate === 'function'
16
17
  ? await indexTemplate(url.toString())
17
18
  : indexTemplate;
@@ -1,7 +1,8 @@
1
1
  import { ServerComponentRequest } from '../../framework/Hydration/ServerComponentRequest.server';
2
- /** A utility for logging debugging, warning, and error information about the application.
3
- * Use by importing `log` `@shopify/hydrogen` or by using a `log` prop passed to each page
4
- * component. Using the latter is ideal, because it will ty your log to the current request in progress.
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;