@shopify/hydrogen 1.0.2 → 1.1.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/dist/esnext/entry-server.js +10 -9
- package/dist/esnext/foundation/Analytics/connectors/PerformanceMetrics/PerformanceMetrics.client.js +4 -2
- package/dist/esnext/foundation/DevTools/components/Heading.js +1 -1
- package/dist/esnext/foundation/DevTools/components/Panels.js +25 -19
- package/dist/esnext/foundation/DevTools/components/Performance.client.js +0 -1
- package/dist/esnext/foundation/DevTools/components/Settings.client.js +1 -4
- package/dist/esnext/foundation/DevTools/components/Table.js +3 -3
- package/dist/esnext/foundation/HydrogenRequest/HydrogenRequest.server.js +1 -3
- package/dist/esnext/foundation/ServerPropsProvider/ServerPropsProvider.js +3 -3
- package/dist/esnext/foundation/fetchSync/ResponseSync.d.ts +14 -0
- package/dist/esnext/foundation/fetchSync/ResponseSync.js +38 -0
- package/dist/esnext/foundation/fetchSync/client/fetchSync.d.ts +2 -2
- package/dist/esnext/foundation/fetchSync/client/fetchSync.js +4 -9
- package/dist/esnext/foundation/fetchSync/server/fetchSync.d.ts +2 -2
- package/dist/esnext/foundation/fetchSync/server/fetchSync.js +5 -11
- package/dist/esnext/framework/graphiql.js +26 -30
- package/dist/esnext/framework/plugins/vite-plugin-platform-entry.js +35 -6
- package/dist/esnext/hooks/useShopQuery/hooks.js +9 -6
- package/dist/esnext/platforms/index.d.ts +1 -0
- package/dist/esnext/platforms/index.js +1 -0
- package/dist/esnext/platforms/node.js +2 -8
- package/dist/esnext/platforms/virtual.d.ts +8 -0
- package/dist/esnext/platforms/virtual.js +14 -0
- package/dist/esnext/platforms/worker.js +7 -7
- package/dist/esnext/version.d.ts +1 -1
- package/dist/esnext/version.js +1 -1
- package/dist/node/framework/graphiql.js +26 -30
- package/dist/node/framework/plugins/vite-plugin-platform-entry.js +35 -6
- package/package.json +6 -1
- package/vendor/react-server-dom-vite/cjs/react-server-dom-vite-plugin.js +26 -12
- package/vendor/react-server-dom-vite/esm/react-server-dom-vite-plugin.js +26 -12
- package/dist/esnext/foundation/fetchSync/types.d.ts +0 -5
- package/dist/esnext/foundation/fetchSync/types.js +0 -1
|
@@ -10,7 +10,6 @@ import { ServerPropsProvider } from './foundation/ServerPropsProvider';
|
|
|
10
10
|
import { isBotUA } from './utilities/bot-ua';
|
|
11
11
|
import { getCache, setCache } from './foundation/runtime';
|
|
12
12
|
import { ssrRenderToPipeableStream, ssrRenderToReadableStream, rscRenderToReadableStream, createFromReadableStream, bufferReadableStream, } from './streaming.server';
|
|
13
|
-
import { RSC_PATHNAME } from './constants';
|
|
14
13
|
import { stripScriptsFromTemplate } from './utilities/template';
|
|
15
14
|
import { setLogger } from './utilities/log/log';
|
|
16
15
|
import { Analytics } from './foundation/Analytics/Analytics.server';
|
|
@@ -110,7 +109,7 @@ export const renderHydrogen = (App) => {
|
|
|
110
109
|
async function processRequest(handleRequest, App, url, request, sessionApi, options, response, hydrogenConfig, revalidate = false) {
|
|
111
110
|
const { dev, nonce, indexTemplate, streamableResponse: nodeResponse } = options;
|
|
112
111
|
const log = getLoggerWithContext(request);
|
|
113
|
-
const isRSCRequest =
|
|
112
|
+
const isRSCRequest = request.isRscRequest();
|
|
114
113
|
const apiRoute = !isRSCRequest && getApiRoute(url, hydrogenConfig.routes);
|
|
115
114
|
// The API Route might have a default export, making it also a server component
|
|
116
115
|
// If it does, only render the API route if the request method is GET
|
|
@@ -123,8 +122,11 @@ async function processRequest(handleRequest, App, url, request, sessionApi, opti
|
|
|
123
122
|
: apiResponse;
|
|
124
123
|
}
|
|
125
124
|
const state = isRSCRequest
|
|
126
|
-
? parseJSON(url.searchParams.get('state') || '{}')
|
|
127
|
-
: {
|
|
125
|
+
? parseJSON(decodeURIComponent(url.searchParams.get('state') || '{}'))
|
|
126
|
+
: {
|
|
127
|
+
pathname: decodeURIComponent(url.pathname),
|
|
128
|
+
search: decodeURIComponent(url.search),
|
|
129
|
+
};
|
|
128
130
|
const rsc = runRSC({ App, state, log, request, response });
|
|
129
131
|
if (isRSCRequest) {
|
|
130
132
|
const buffered = await bufferReadableStream(rsc.readable.getReader());
|
|
@@ -552,13 +554,13 @@ function tagOnWrite(response) {
|
|
|
552
554
|
async function cacheResponse(response, request, chunks, revalidate) {
|
|
553
555
|
const cache = getCache();
|
|
554
556
|
/**
|
|
555
|
-
* Only cache on cachable responses where response
|
|
557
|
+
* Only full page cache on cachable responses where response
|
|
556
558
|
*
|
|
557
559
|
* - have content to cache
|
|
558
560
|
* - have status 200
|
|
559
561
|
* - does not have no-store on cache-control header
|
|
560
562
|
* - does not have set-cookie header
|
|
561
|
-
* - is
|
|
563
|
+
* - is a GET request
|
|
562
564
|
* - does not have a session or does not have an active customer access token
|
|
563
565
|
*/
|
|
564
566
|
if (cache &&
|
|
@@ -566,7 +568,7 @@ async function cacheResponse(response, request, chunks, revalidate) {
|
|
|
566
568
|
response.status === 200 &&
|
|
567
569
|
response.cache().mode !== NO_STORE &&
|
|
568
570
|
!response.headers.has('Set-Cookie') &&
|
|
569
|
-
|
|
571
|
+
/get/i.test(request.method) &&
|
|
570
572
|
!sessionHasCustomerAccessToken(request)) {
|
|
571
573
|
if (revalidate) {
|
|
572
574
|
await saveCacheResponse(response, request, chunks);
|
|
@@ -593,10 +595,9 @@ async function saveCacheResponse(response, request, chunks) {
|
|
|
593
595
|
const cache = getCache();
|
|
594
596
|
if (cache && chunks.length > 0) {
|
|
595
597
|
const { headers, status, statusText } = getResponseOptions(response);
|
|
596
|
-
const url = new URL(request.url);
|
|
597
598
|
headers.set('cache-control', response.cacheControlHeader);
|
|
598
599
|
const currentHeader = headers.get('Content-Type');
|
|
599
|
-
if (!currentHeader &&
|
|
600
|
+
if (!currentHeader && !request.isRscRequest()) {
|
|
600
601
|
headers.set('Content-Type', HTML_CONTENT_TYPE);
|
|
601
602
|
}
|
|
602
603
|
await setItemInCache(request.cacheKey(), new Response(chunks.join(''), {
|
package/dist/esnext/foundation/Analytics/connectors/PerformanceMetrics/PerformanceMetrics.client.js
CHANGED
|
@@ -18,7 +18,7 @@ export function PerformanceMetrics() {
|
|
|
18
18
|
const initTime = new Date().getTime();
|
|
19
19
|
ClientAnalytics.publish(ClientAnalytics.eventNames.PERFORMANCE, true, data);
|
|
20
20
|
const pageData = ClientAnalytics.getPageAnalyticsData();
|
|
21
|
-
const shopId = pageData.shopify
|
|
21
|
+
const shopId = pageData.shopify?.shopId;
|
|
22
22
|
fetch('https://monorail-edge.shopifysvc.com/v1/produce', {
|
|
23
23
|
method: 'post',
|
|
24
24
|
headers: {
|
|
@@ -28,7 +28,9 @@ export function PerformanceMetrics() {
|
|
|
28
28
|
schema_id: 'hydrogen_buyer_performance/2.0',
|
|
29
29
|
payload: {
|
|
30
30
|
...data,
|
|
31
|
-
shop_id: shopId
|
|
31
|
+
shop_id: shopId
|
|
32
|
+
? shopId.substring(shopId.lastIndexOf('/') + 1)
|
|
33
|
+
: '',
|
|
32
34
|
},
|
|
33
35
|
metadata: {
|
|
34
36
|
event_created_at_ms: initTime,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
export function Heading({ linkText, url, children, }) {
|
|
3
|
-
return (React.createElement("span", { style: { display: 'flex', alignItems: 'baseline', padding: '0 0
|
|
3
|
+
return (React.createElement("span", { style: { display: 'flex', alignItems: 'baseline', padding: '0 0 0em' } },
|
|
4
4
|
React.createElement("span", { style: { paddingRight: '0em', flex: 1, fontWeight: 'bold' } },
|
|
5
5
|
children,
|
|
6
6
|
' '),
|
|
@@ -2,6 +2,7 @@ import React, { useState, useEffect } from 'react';
|
|
|
2
2
|
import { ClientAnalytics } from '../../Analytics';
|
|
3
3
|
import { Performance } from './Performance.client';
|
|
4
4
|
import { Settings } from './Settings.client';
|
|
5
|
+
const isComponentPanel = (panel) => panel.component !== undefined;
|
|
5
6
|
export function Panels({ settings }) {
|
|
6
7
|
const [selectedPanel, setSelectedPanel] = useState(0);
|
|
7
8
|
const [navigations, setNavigations] = useState([]);
|
|
@@ -22,36 +23,41 @@ export function Panels({ settings }) {
|
|
|
22
23
|
});
|
|
23
24
|
}, [setNavigations, navigations]);
|
|
24
25
|
const panels = getPanels({ settings, performance: { navigations } });
|
|
25
|
-
const panelComponents = panels.map((obj, index) => (React.createElement("div", { key: obj.content, style: { display: selectedPanel === index ? 'block' : 'none' } }, obj.
|
|
26
|
+
const panelComponents = panels.map((obj, index) => isComponentPanel(obj) ? (React.createElement("div", { key: obj.content, style: { display: selectedPanel === index ? 'block' : 'none' } }, obj.component)) : null);
|
|
26
27
|
return (React.createElement("div", { style: { display: 'flex', height: '100%' } },
|
|
27
|
-
React.createElement("div", { style: { borderRight: '1px solid', padding: '1em 0em' } }, panels.map((
|
|
28
|
+
React.createElement("div", { style: { borderRight: '1px solid', padding: '1em 0em' } }, panels.map((panel, index) => {
|
|
28
29
|
const active = selectedPanel === index;
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
30
|
+
const style = {
|
|
31
|
+
padding: '0em 1.25em',
|
|
32
|
+
fontWeight: 'bold',
|
|
33
|
+
textDecoration: active ? 'underline' : 'none',
|
|
34
|
+
display: 'flex',
|
|
35
|
+
justifyContent: 'space-between',
|
|
36
|
+
alignItems: 'center',
|
|
37
|
+
};
|
|
38
|
+
if (isComponentPanel(panel)) {
|
|
39
|
+
return (React.createElement("button", { key: panel.id, type: "button", style: style, onClick: () => setSelectedPanel(index) },
|
|
40
|
+
React.createElement("span", null, panel.content)));
|
|
41
|
+
}
|
|
42
|
+
return (React.createElement("a", { style: style, target: "_blank", rel: "noreferrer", href: panel.url, key: panel.url },
|
|
43
|
+
panel.content,
|
|
44
|
+
React.createElement("span", null, "\u2197")));
|
|
38
45
|
})),
|
|
39
|
-
React.createElement("div", { style: { padding: '
|
|
40
|
-
}
|
|
41
|
-
function Panel({ children }) {
|
|
42
|
-
return React.createElement("div", null, children);
|
|
46
|
+
React.createElement("div", { style: { padding: '1em', width: '100%' } }, panelComponents[selectedPanel ? selectedPanel : 0])));
|
|
43
47
|
}
|
|
44
48
|
function getPanels({ settings, performance }) {
|
|
45
49
|
const panels = {
|
|
46
50
|
settings: {
|
|
47
51
|
content: 'Settings',
|
|
48
|
-
|
|
49
|
-
icon: '🎛',
|
|
52
|
+
component: React.createElement(Settings, { ...settings }),
|
|
50
53
|
},
|
|
51
54
|
performance: {
|
|
52
55
|
content: 'Performance',
|
|
53
|
-
|
|
54
|
-
|
|
56
|
+
component: React.createElement(Performance, { ...performance }),
|
|
57
|
+
},
|
|
58
|
+
graphiql: {
|
|
59
|
+
content: 'GraphiQL',
|
|
60
|
+
url: '/___graphql',
|
|
55
61
|
},
|
|
56
62
|
};
|
|
57
63
|
return Object.keys(panels).map((key) => {
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { Heading } from './Heading';
|
|
3
2
|
import { Table } from './Table';
|
|
4
3
|
const KEY_MAP = {
|
|
5
4
|
locale: 'Locale',
|
|
@@ -14,7 +13,5 @@ export function Settings(props) {
|
|
|
14
13
|
type: typeof value,
|
|
15
14
|
};
|
|
16
15
|
});
|
|
17
|
-
return
|
|
18
|
-
React.createElement(Heading, null, "Config"),
|
|
19
|
-
React.createElement(Table, { items: items })));
|
|
16
|
+
return React.createElement(Table, { items: items });
|
|
20
17
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
export function Table({ items }) {
|
|
3
|
-
const itemsMarkup = items.map(({ key, value }) => (React.createElement("div", { key: key, style: { display: 'flex' } },
|
|
4
|
-
React.createElement("span", { style: {
|
|
5
|
-
React.createElement("span", { style: { width: '70%', fontFamily: 'monospace'
|
|
3
|
+
const itemsMarkup = items.map(({ key, value }) => (React.createElement("div", { key: key, style: { display: 'flex', paddingBottom: '1em', flexDirection: 'column' } },
|
|
4
|
+
React.createElement("span", { style: { fontWeight: 'bold' } }, key),
|
|
5
|
+
React.createElement("span", { style: { width: '70%', fontFamily: 'monospace' } }, value))));
|
|
6
6
|
return React.createElement("ul", null, itemsMarkup);
|
|
7
7
|
}
|
|
@@ -43,9 +43,7 @@ export class HydrogenRequest extends Request {
|
|
|
43
43
|
}
|
|
44
44
|
this.time = getTime();
|
|
45
45
|
this.id = generateId();
|
|
46
|
-
this.normalizedUrl = this.isRscRequest()
|
|
47
|
-
? normalizeUrl(this.url)
|
|
48
|
-
: this.url;
|
|
46
|
+
this.normalizedUrl = decodeURIComponent(this.isRscRequest() ? normalizeUrl(this.url) : this.url);
|
|
49
47
|
this.ctx = {
|
|
50
48
|
cache: new Map(),
|
|
51
49
|
head: new HeadData({}),
|
|
@@ -13,12 +13,12 @@ export function ServerPropsProvider({ initialServerProps, setServerPropsForRsc,
|
|
|
13
13
|
setServerPropsForRsc((prev) => getNewValue(prev, input, propValue));
|
|
14
14
|
});
|
|
15
15
|
}, [setServerProps, setServerPropsForRsc]);
|
|
16
|
-
const setLocationServerPropsCallback = useCallback((input
|
|
16
|
+
const setLocationServerPropsCallback = useCallback((input) => {
|
|
17
17
|
// Flush the existing user server state when location changes, leaving only the persisted state
|
|
18
18
|
startTransition(() => {
|
|
19
|
-
setServerPropsForRsc(
|
|
19
|
+
setServerPropsForRsc(input);
|
|
20
20
|
setServerProps({});
|
|
21
|
-
setLocationServerProps(
|
|
21
|
+
setLocationServerProps(input);
|
|
22
22
|
});
|
|
23
23
|
}, [setServerProps, setServerPropsForRsc, setLocationServerProps]);
|
|
24
24
|
const getProposedLocationServerPropsCallback = useCallback((input, propValue) => {
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
declare type ResponseSyncInit = [string, ResponseInit];
|
|
2
|
+
export declare class ResponseSync extends Response {
|
|
3
|
+
#private;
|
|
4
|
+
bodyUsed: boolean;
|
|
5
|
+
constructor(init: ResponseSyncInit);
|
|
6
|
+
text(): string;
|
|
7
|
+
json(): any;
|
|
8
|
+
/**
|
|
9
|
+
* @deprecated Access response properties at the top level instead.
|
|
10
|
+
*/
|
|
11
|
+
get response(): this;
|
|
12
|
+
static toSerializable(response: Response): Promise<ResponseSyncInit>;
|
|
13
|
+
}
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { parseJSON } from '../../utilities/parse';
|
|
2
|
+
import { log } from '../../utilities/log';
|
|
3
|
+
export class ResponseSync extends Response {
|
|
4
|
+
bodyUsed = true;
|
|
5
|
+
#text;
|
|
6
|
+
#json;
|
|
7
|
+
constructor(init) {
|
|
8
|
+
super(...init);
|
|
9
|
+
this.#text = init[0];
|
|
10
|
+
}
|
|
11
|
+
// @ts-expect-error Changing inherited types
|
|
12
|
+
text() {
|
|
13
|
+
return this.#text;
|
|
14
|
+
}
|
|
15
|
+
json() {
|
|
16
|
+
return (this.#json ??= parseJSON(this.#text));
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* @deprecated Access response properties at the top level instead.
|
|
20
|
+
*/
|
|
21
|
+
get response() {
|
|
22
|
+
if (__HYDROGEN_DEV__) {
|
|
23
|
+
log.warn(`Property 'response' is deprecated from the result of 'fetchSync'.` +
|
|
24
|
+
` Access response properties at the top level instead.`);
|
|
25
|
+
}
|
|
26
|
+
return this;
|
|
27
|
+
}
|
|
28
|
+
static async toSerializable(response) {
|
|
29
|
+
return [
|
|
30
|
+
await response.text(),
|
|
31
|
+
{
|
|
32
|
+
status: response.status,
|
|
33
|
+
statusText: response.statusText,
|
|
34
|
+
headers: Array.from(response.headers.entries()),
|
|
35
|
+
},
|
|
36
|
+
];
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { ResponseSync } from '../ResponseSync';
|
|
2
2
|
/**
|
|
3
3
|
* Fetch a URL for use in a client component Suspense boundary.
|
|
4
4
|
*/
|
|
5
|
-
export declare function fetchSync(url: string, options?: RequestInit):
|
|
5
|
+
export declare function fetchSync(url: string, options?: RequestInit): ResponseSync;
|
|
6
6
|
/**
|
|
7
7
|
* Preload a URL for use in a client component Suspense boundary.
|
|
8
8
|
* Useful for placing higher in the tree to avoid waterfalls.
|
|
@@ -1,19 +1,14 @@
|
|
|
1
|
-
import { parseJSON } from '../../../utilities/parse';
|
|
2
1
|
import { suspendFunction, preloadFunction } from '../../../utilities/suspense';
|
|
2
|
+
import { ResponseSync } from '../ResponseSync';
|
|
3
3
|
/**
|
|
4
4
|
* Fetch a URL for use in a client component Suspense boundary.
|
|
5
5
|
*/
|
|
6
6
|
export function fetchSync(url, options) {
|
|
7
|
-
const
|
|
7
|
+
const responseSyncInit = suspendFunction([url, options], async () => {
|
|
8
8
|
const response = await globalThis.fetch(new URL(url, window.location.origin), options);
|
|
9
|
-
|
|
10
|
-
return [text, response];
|
|
9
|
+
return ResponseSync.toSerializable(response);
|
|
11
10
|
});
|
|
12
|
-
return
|
|
13
|
-
response,
|
|
14
|
-
json: () => parseJSON(text),
|
|
15
|
-
text: () => text,
|
|
16
|
-
};
|
|
11
|
+
return new ResponseSync(responseSyncInit);
|
|
17
12
|
}
|
|
18
13
|
/**
|
|
19
14
|
* Preload a URL for use in a client component Suspense boundary.
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { type HydrogenUseQueryOptions } from '../../useQuery/hooks';
|
|
2
|
-
import
|
|
2
|
+
import { ResponseSync } from '../ResponseSync';
|
|
3
3
|
/**
|
|
4
4
|
* The `fetchSync` hook makes API requests and is the recommended way to make simple fetch calls on the server and the client.
|
|
5
5
|
* It's designed similar to the [Web API's `fetch`](https://developer.mozilla.org/en-US/docs/Web/API/fetch), only in a way
|
|
6
6
|
* that supports [Suspense](https://reactjs.org/docs/concurrent-mode-suspense.html).
|
|
7
7
|
*/
|
|
8
|
-
export declare function fetchSync(url: string, options?: Omit<RequestInit, 'cache'> & HydrogenUseQueryOptions):
|
|
8
|
+
export declare function fetchSync(url: string, options?: Omit<RequestInit, 'cache'> & HydrogenUseQueryOptions): ResponseSync;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { parseJSON } from '../../../utilities/parse';
|
|
2
1
|
import { useQuery } from '../../useQuery/hooks';
|
|
3
2
|
import { useUrl } from '../../useUrl';
|
|
3
|
+
import { ResponseSync } from '../ResponseSync';
|
|
4
4
|
/**
|
|
5
5
|
* The `fetchSync` hook makes API requests and is the recommended way to make simple fetch calls on the server and the client.
|
|
6
6
|
* It's designed similar to the [Web API's `fetch`](https://developer.mozilla.org/en-US/docs/Web/API/fetch), only in a way
|
|
@@ -10,11 +10,10 @@ export function fetchSync(url, options) {
|
|
|
10
10
|
const { cache, preload, shouldCacheResponse, ...requestInit } = options ?? {};
|
|
11
11
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
12
12
|
const { origin } = useUrl();
|
|
13
|
-
|
|
14
|
-
[url, requestInit], async () => {
|
|
13
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
14
|
+
const { data, error } = useQuery([url, requestInit], async () => {
|
|
15
15
|
const response = await globalThis.fetch(new URL(url, origin), requestInit);
|
|
16
|
-
|
|
17
|
-
return [text, response];
|
|
16
|
+
return ResponseSync.toSerializable(response);
|
|
18
17
|
}, {
|
|
19
18
|
cache,
|
|
20
19
|
preload,
|
|
@@ -23,10 +22,5 @@ export function fetchSync(url, options) {
|
|
|
23
22
|
if (error) {
|
|
24
23
|
throw error;
|
|
25
24
|
}
|
|
26
|
-
|
|
27
|
-
return {
|
|
28
|
-
response,
|
|
29
|
-
json: () => parseJSON(data),
|
|
30
|
-
text: () => data,
|
|
31
|
-
};
|
|
25
|
+
return new ResponseSync(data);
|
|
32
26
|
}
|
|
@@ -1,38 +1,34 @@
|
|
|
1
1
|
export function graphiqlHtml(shop, token, apiVersion) {
|
|
2
|
-
return
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
<
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
></script>
|
|
21
|
-
<script>
|
|
22
|
-
const fetcher = GraphiQL.createFetcher({
|
|
23
|
-
url: 'https://${shop}/api/${apiVersion}/graphql.json',
|
|
24
|
-
headers: {
|
|
2
|
+
return `
|
|
3
|
+
<!DOCTYPE html>
|
|
4
|
+
<html>
|
|
5
|
+
<head>
|
|
6
|
+
<meta charset=utf-8/>
|
|
7
|
+
<meta name="viewport" content="user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, minimal-ui">
|
|
8
|
+
<title>Shopify Storefront API</title>
|
|
9
|
+
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/graphql-playground-react/build/static/css/index.css" />
|
|
10
|
+
<link rel="shortcut icon" href="//cdn.jsdelivr.net/npm/graphql-playground-react/build/favicon.png" />
|
|
11
|
+
<script src="//cdn.jsdelivr.net/npm/graphql-playground-react/build/static/js/middleware.js"></script>
|
|
12
|
+
</head>
|
|
13
|
+
<body>
|
|
14
|
+
<div id="root"></div>
|
|
15
|
+
<script>window.addEventListener('load', function (event) {
|
|
16
|
+
GraphQLPlayground.init(document.getElementById('root'), {
|
|
17
|
+
endpoint:'https://${shop}/api/${apiVersion}/graphql.json',
|
|
18
|
+
settings:{
|
|
19
|
+
'request.globalHeaders': {
|
|
25
20
|
Accept: 'application/json',
|
|
26
21
|
'Content-Type': 'application/graphql',
|
|
27
22
|
'X-Shopify-Storefront-Access-Token': '${token}'
|
|
28
23
|
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
</
|
|
24
|
+
},
|
|
25
|
+
tabs: [{
|
|
26
|
+
endpoint: 'https://${shop}/api/${apiVersion}/graphql.json',
|
|
27
|
+
query: '{ shop { name } }'
|
|
28
|
+
}]
|
|
29
|
+
})
|
|
30
|
+
})</script>
|
|
31
|
+
</body>
|
|
36
32
|
</html>
|
|
37
33
|
`;
|
|
38
34
|
}
|
|
@@ -3,12 +3,16 @@ import { HYDROGEN_DEFAULT_SERVER_ENTRY } from './vite-plugin-hydrogen-middleware
|
|
|
3
3
|
import MagicString from 'magic-string';
|
|
4
4
|
import path from 'path';
|
|
5
5
|
import fs from 'fs';
|
|
6
|
+
import fastGlob from 'fast-glob';
|
|
6
7
|
const SSR_BUNDLE_NAME = 'index.js';
|
|
8
|
+
// Keep this in the outer scope to share it
|
|
9
|
+
// across client <> server builds.
|
|
10
|
+
let clientBuildPath;
|
|
7
11
|
export default () => {
|
|
8
12
|
let config;
|
|
9
13
|
let isESM;
|
|
10
14
|
return {
|
|
11
|
-
name: '
|
|
15
|
+
name: 'hydrogen:platform-entry',
|
|
12
16
|
enforce: 'pre',
|
|
13
17
|
configResolved(_config) {
|
|
14
18
|
config = _config;
|
|
@@ -29,18 +33,43 @@ export default () => {
|
|
|
29
33
|
}
|
|
30
34
|
return null;
|
|
31
35
|
},
|
|
32
|
-
transform(code, id) {
|
|
33
|
-
if (
|
|
36
|
+
async transform(code, id, options) {
|
|
37
|
+
if (config.command === 'build' &&
|
|
38
|
+
options?.ssr &&
|
|
39
|
+
/@shopify\/hydrogen\/.+platforms\/virtual\./.test(normalizePath(id))) {
|
|
34
40
|
const ms = new MagicString(code);
|
|
35
|
-
ms.replace('
|
|
36
|
-
|
|
37
|
-
|
|
41
|
+
ms.replace('__HYDROGEN_ENTRY__', HYDROGEN_DEFAULT_SERVER_ENTRY);
|
|
42
|
+
if (!clientBuildPath) {
|
|
43
|
+
// Default value
|
|
44
|
+
clientBuildPath = normalizePath(path.resolve(config.root, config.build.outDir, '..', 'client'));
|
|
45
|
+
}
|
|
46
|
+
ms.replace('__HYDROGEN_HTML_TEMPLATE__', normalizePath(path.resolve(clientBuildPath, 'index.html')));
|
|
47
|
+
ms.replace('__HYDROGEN_RELATIVE_CLIENT_BUILD__', normalizePath(path.relative(normalizePath(path.resolve(config.root, config.build.outDir)), clientBuildPath)));
|
|
48
|
+
const files = clientBuildPath
|
|
49
|
+
? (await fastGlob('**/*', {
|
|
50
|
+
cwd: clientBuildPath,
|
|
51
|
+
ignore: ['**/index.html', `**/${config.build.assetsDir}/**`],
|
|
52
|
+
})).map((file) => '/' + file)
|
|
53
|
+
: [];
|
|
54
|
+
ms.replace("\\['__HYDROGEN_ASSETS__'\\]", JSON.stringify(files));
|
|
55
|
+
ms.replace('__HYDROGEN_ASSETS_DIR__', config.build.assetsDir);
|
|
56
|
+
ms.replace('__HYDROGEN_ASSETS_BASE_URL__', (process.env.HYDROGEN_ASSET_BASE_URL || '').replace(/\/$/, ''));
|
|
57
|
+
// Remove the poison pill
|
|
58
|
+
ms.replace('throw', '//');
|
|
38
59
|
return {
|
|
39
60
|
code: ms.toString(),
|
|
40
61
|
map: ms.generateMap({ file: id, source: id }),
|
|
41
62
|
};
|
|
42
63
|
}
|
|
43
64
|
},
|
|
65
|
+
buildEnd(err) {
|
|
66
|
+
if (!err && !config.build.ssr && config.command === 'build') {
|
|
67
|
+
// Save outDir from client build in the outer scope in order
|
|
68
|
+
// to read it during the server build. The CLI runs Vite in
|
|
69
|
+
// the same process so the scope is shared across builds.
|
|
70
|
+
clientBuildPath = normalizePath(path.resolve(config.root, config.build.outDir));
|
|
71
|
+
}
|
|
72
|
+
},
|
|
44
73
|
generateBundle(options, bundle) {
|
|
45
74
|
if (config.build.ssr) {
|
|
46
75
|
const [key, value] = Object.entries(bundle).find(([, value]) => value.type === 'chunk' && value.isEntry);
|
|
@@ -40,15 +40,17 @@ export function useShopQuery({ query, variables = {}, cache, preload = false, })
|
|
|
40
40
|
let text;
|
|
41
41
|
let data;
|
|
42
42
|
let useQueryError;
|
|
43
|
+
let response = null;
|
|
43
44
|
try {
|
|
44
|
-
|
|
45
|
+
response = fetchSync(url, {
|
|
45
46
|
...requestInit,
|
|
46
47
|
cache,
|
|
47
48
|
preload,
|
|
48
49
|
shouldCacheResponse,
|
|
49
|
-
})
|
|
50
|
+
});
|
|
51
|
+
text = response.text();
|
|
50
52
|
try {
|
|
51
|
-
data =
|
|
53
|
+
data = response.json();
|
|
52
54
|
}
|
|
53
55
|
catch (error) {
|
|
54
56
|
useQueryError = new Error('Unable to parse response:\n' + text);
|
|
@@ -82,15 +84,16 @@ export function useShopQuery({ query, variables = {}, cache, preload = false, })
|
|
|
82
84
|
*/
|
|
83
85
|
if (data?.errors) {
|
|
84
86
|
const errors = Array.isArray(data.errors) ? data.errors : [data.errors];
|
|
87
|
+
const requestId = response?.headers?.get('x-request-id') ?? '';
|
|
85
88
|
for (const error of errors) {
|
|
86
89
|
if (__HYDROGEN_DEV__ && !__HYDROGEN_TEST__) {
|
|
87
|
-
throw new Error(error.message);
|
|
90
|
+
throw new Error(`Storefront API GraphQL Error: ${error.message}.\nRequest id: ${requestId}`);
|
|
88
91
|
}
|
|
89
92
|
else {
|
|
90
|
-
log.error('GraphQL Error', error);
|
|
93
|
+
log.error('Storefront API GraphQL Error', error, 'Storefront API GraphQL request id', requestId);
|
|
91
94
|
}
|
|
92
95
|
}
|
|
93
|
-
log.error(`GraphQL
|
|
96
|
+
log.error(`Storefront API GraphQL error count: ${errors.length}`);
|
|
94
97
|
}
|
|
95
98
|
if (__HYDROGEN_DEV__ &&
|
|
96
99
|
(log.options().showUnusedQueryProperties ||
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './virtual';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './virtual';
|
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
import '../utilities/web-api-polyfill';
|
|
2
2
|
import path from 'path';
|
|
3
|
-
|
|
4
|
-
// eslint-disable-next-line node/no-missing-import
|
|
5
|
-
import entrypoint from '__SERVER_ENTRY__';
|
|
6
|
-
// @ts-ignore
|
|
7
|
-
// eslint-disable-next-line node/no-missing-import
|
|
8
|
-
import indexTemplate from '__INDEX_TEMPLATE__?raw';
|
|
3
|
+
import { handleRequest, indexTemplate, relativeClientBuildPath } from './virtual';
|
|
9
4
|
import { hydrogenMiddleware } from '../framework/middleware';
|
|
10
5
|
// @ts-ignore
|
|
11
6
|
import serveStatic from 'serve-static';
|
|
@@ -14,13 +9,12 @@ import compression from 'compression';
|
|
|
14
9
|
import bodyParser from 'body-parser';
|
|
15
10
|
import connect from 'connect';
|
|
16
11
|
import { InMemoryCache } from '../framework/cache/in-memory';
|
|
17
|
-
const handleRequest = entrypoint;
|
|
18
12
|
export async function createServer({ cache = new InMemoryCache(), } = {}) {
|
|
19
13
|
// @ts-ignore
|
|
20
14
|
globalThis.Oxygen = { env: process.env };
|
|
21
15
|
const app = connect();
|
|
22
16
|
app.use(compression());
|
|
23
|
-
app.use(serveStatic(path.resolve(__dirname,
|
|
17
|
+
app.use(serveStatic(path.resolve(__dirname, relativeClientBuildPath), {
|
|
24
18
|
index: false,
|
|
25
19
|
}));
|
|
26
20
|
app.use(bodyParser.raw({ type: '*/*' }));
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { RequestHandler } from '../shared-types';
|
|
2
|
+
export declare const handleRequest: RequestHandler;
|
|
3
|
+
export { default as indexTemplate } from '__HYDROGEN_HTML_TEMPLATE__?raw';
|
|
4
|
+
export declare const assets: Set<string>;
|
|
5
|
+
export declare const assetPrefix: string;
|
|
6
|
+
export declare const isAsset: (pathname?: string) => boolean;
|
|
7
|
+
export declare const relativeClientBuildPath: string;
|
|
8
|
+
export declare const assetBasePath: string;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// This file is modified by Vite at build time
|
|
2
|
+
// with user project information and re-exports it.
|
|
3
|
+
// @ts-ignore
|
|
4
|
+
// eslint-disable-next-line node/no-missing-import
|
|
5
|
+
import appEntry from '__HYDROGEN_ENTRY__';
|
|
6
|
+
export const handleRequest = appEntry;
|
|
7
|
+
// eslint-disable-next-line node/no-missing-import
|
|
8
|
+
export { default as indexTemplate } from '__HYDROGEN_HTML_TEMPLATE__?raw';
|
|
9
|
+
export const assets = new Set(['__HYDROGEN_ASSETS__']);
|
|
10
|
+
export const assetPrefix = '/__HYDROGEN_ASSETS_DIR__/';
|
|
11
|
+
export const isAsset = (pathname = '') => pathname.startsWith(assetPrefix) || assets.has(pathname);
|
|
12
|
+
export const relativeClientBuildPath = '__HYDROGEN_RELATIVE_CLIENT_BUILD__';
|
|
13
|
+
export const assetBasePath = '__HYDROGEN_ASSETS_BASE_URL__';
|
|
14
|
+
throw new Error('This file must be overwritten in a Vite plugin');
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
// eslint-disable-next-line node/no-missing-import
|
|
3
|
-
import entrypoint from '__SERVER_ENTRY__';
|
|
4
|
-
// @ts-ignore
|
|
5
|
-
// eslint-disable-next-line node/no-missing-import
|
|
6
|
-
import indexTemplate from '__INDEX_TEMPLATE__?raw';
|
|
7
|
-
const handleRequest = entrypoint;
|
|
1
|
+
import { handleRequest, indexTemplate, isAsset, assetBasePath } from './virtual';
|
|
8
2
|
export default {
|
|
9
3
|
async fetch(request, env, context) {
|
|
4
|
+
// Proxy assets to the CDN. This should be removed
|
|
5
|
+
// once the proxy is implemented in Oxygen itself.
|
|
6
|
+
const url = new URL(request.url);
|
|
7
|
+
if (assetBasePath && isAsset(url.pathname)) {
|
|
8
|
+
return fetch(request.url.replace(url.origin, assetBasePath), request);
|
|
9
|
+
}
|
|
10
10
|
if (!globalThis.Oxygen) {
|
|
11
11
|
globalThis.Oxygen = { env };
|
|
12
12
|
}
|
package/dist/esnext/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const LIB_VERSION = "1.0
|
|
1
|
+
export declare const LIB_VERSION = "1.1.0";
|
package/dist/esnext/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const LIB_VERSION = '1.0
|
|
1
|
+
export const LIB_VERSION = '1.1.0';
|
|
@@ -2,40 +2,36 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.graphiqlHtml = void 0;
|
|
4
4
|
function graphiqlHtml(shop, token, apiVersion) {
|
|
5
|
-
return
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
<
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
></script>
|
|
24
|
-
<script>
|
|
25
|
-
const fetcher = GraphiQL.createFetcher({
|
|
26
|
-
url: 'https://${shop}/api/${apiVersion}/graphql.json',
|
|
27
|
-
headers: {
|
|
5
|
+
return `
|
|
6
|
+
<!DOCTYPE html>
|
|
7
|
+
<html>
|
|
8
|
+
<head>
|
|
9
|
+
<meta charset=utf-8/>
|
|
10
|
+
<meta name="viewport" content="user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, minimal-ui">
|
|
11
|
+
<title>Shopify Storefront API</title>
|
|
12
|
+
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/graphql-playground-react/build/static/css/index.css" />
|
|
13
|
+
<link rel="shortcut icon" href="//cdn.jsdelivr.net/npm/graphql-playground-react/build/favicon.png" />
|
|
14
|
+
<script src="//cdn.jsdelivr.net/npm/graphql-playground-react/build/static/js/middleware.js"></script>
|
|
15
|
+
</head>
|
|
16
|
+
<body>
|
|
17
|
+
<div id="root"></div>
|
|
18
|
+
<script>window.addEventListener('load', function (event) {
|
|
19
|
+
GraphQLPlayground.init(document.getElementById('root'), {
|
|
20
|
+
endpoint:'https://${shop}/api/${apiVersion}/graphql.json',
|
|
21
|
+
settings:{
|
|
22
|
+
'request.globalHeaders': {
|
|
28
23
|
Accept: 'application/json',
|
|
29
24
|
'Content-Type': 'application/graphql',
|
|
30
25
|
'X-Shopify-Storefront-Access-Token': '${token}'
|
|
31
26
|
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
</
|
|
27
|
+
},
|
|
28
|
+
tabs: [{
|
|
29
|
+
endpoint: 'https://${shop}/api/${apiVersion}/graphql.json',
|
|
30
|
+
query: '{ shop { name } }'
|
|
31
|
+
}]
|
|
32
|
+
})
|
|
33
|
+
})</script>
|
|
34
|
+
</body>
|
|
39
35
|
</html>
|
|
40
36
|
`;
|
|
41
37
|
}
|
|
@@ -8,12 +8,16 @@ const vite_plugin_hydrogen_middleware_1 = require("./vite-plugin-hydrogen-middle
|
|
|
8
8
|
const magic_string_1 = __importDefault(require("magic-string"));
|
|
9
9
|
const path_1 = __importDefault(require("path"));
|
|
10
10
|
const fs_1 = __importDefault(require("fs"));
|
|
11
|
+
const fast_glob_1 = __importDefault(require("fast-glob"));
|
|
11
12
|
const SSR_BUNDLE_NAME = 'index.js';
|
|
13
|
+
// Keep this in the outer scope to share it
|
|
14
|
+
// across client <> server builds.
|
|
15
|
+
let clientBuildPath;
|
|
12
16
|
exports.default = () => {
|
|
13
17
|
let config;
|
|
14
18
|
let isESM;
|
|
15
19
|
return {
|
|
16
|
-
name: '
|
|
20
|
+
name: 'hydrogen:platform-entry',
|
|
17
21
|
enforce: 'pre',
|
|
18
22
|
configResolved(_config) {
|
|
19
23
|
config = _config;
|
|
@@ -34,18 +38,43 @@ exports.default = () => {
|
|
|
34
38
|
}
|
|
35
39
|
return null;
|
|
36
40
|
},
|
|
37
|
-
transform(code, id) {
|
|
38
|
-
if (
|
|
41
|
+
async transform(code, id, options) {
|
|
42
|
+
if (config.command === 'build' &&
|
|
43
|
+
options?.ssr &&
|
|
44
|
+
/@shopify\/hydrogen\/.+platforms\/virtual\./.test((0, vite_1.normalizePath)(id))) {
|
|
39
45
|
const ms = new magic_string_1.default(code);
|
|
40
|
-
ms.replace('
|
|
41
|
-
|
|
42
|
-
|
|
46
|
+
ms.replace('__HYDROGEN_ENTRY__', vite_plugin_hydrogen_middleware_1.HYDROGEN_DEFAULT_SERVER_ENTRY);
|
|
47
|
+
if (!clientBuildPath) {
|
|
48
|
+
// Default value
|
|
49
|
+
clientBuildPath = (0, vite_1.normalizePath)(path_1.default.resolve(config.root, config.build.outDir, '..', 'client'));
|
|
50
|
+
}
|
|
51
|
+
ms.replace('__HYDROGEN_HTML_TEMPLATE__', (0, vite_1.normalizePath)(path_1.default.resolve(clientBuildPath, 'index.html')));
|
|
52
|
+
ms.replace('__HYDROGEN_RELATIVE_CLIENT_BUILD__', (0, vite_1.normalizePath)(path_1.default.relative((0, vite_1.normalizePath)(path_1.default.resolve(config.root, config.build.outDir)), clientBuildPath)));
|
|
53
|
+
const files = clientBuildPath
|
|
54
|
+
? (await (0, fast_glob_1.default)('**/*', {
|
|
55
|
+
cwd: clientBuildPath,
|
|
56
|
+
ignore: ['**/index.html', `**/${config.build.assetsDir}/**`],
|
|
57
|
+
})).map((file) => '/' + file)
|
|
58
|
+
: [];
|
|
59
|
+
ms.replace("\\['__HYDROGEN_ASSETS__'\\]", JSON.stringify(files));
|
|
60
|
+
ms.replace('__HYDROGEN_ASSETS_DIR__', config.build.assetsDir);
|
|
61
|
+
ms.replace('__HYDROGEN_ASSETS_BASE_URL__', (process.env.HYDROGEN_ASSET_BASE_URL || '').replace(/\/$/, ''));
|
|
62
|
+
// Remove the poison pill
|
|
63
|
+
ms.replace('throw', '//');
|
|
43
64
|
return {
|
|
44
65
|
code: ms.toString(),
|
|
45
66
|
map: ms.generateMap({ file: id, source: id }),
|
|
46
67
|
};
|
|
47
68
|
}
|
|
48
69
|
},
|
|
70
|
+
buildEnd(err) {
|
|
71
|
+
if (!err && !config.build.ssr && config.command === 'build') {
|
|
72
|
+
// Save outDir from client build in the outer scope in order
|
|
73
|
+
// to read it during the server build. The CLI runs Vite in
|
|
74
|
+
// the same process so the scope is shared across builds.
|
|
75
|
+
clientBuildPath = (0, vite_1.normalizePath)(path_1.default.resolve(config.root, config.build.outDir));
|
|
76
|
+
}
|
|
77
|
+
},
|
|
49
78
|
generateBundle(options, bundle) {
|
|
50
79
|
if (config.build.ssr) {
|
|
51
80
|
const [key, value] = Object.entries(bundle).find(([, value]) => value.type === 'chunk' && value.isEntry);
|
package/package.json
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"engines": {
|
|
8
8
|
"node": ">=14"
|
|
9
9
|
},
|
|
10
|
-
"version": "1.0
|
|
10
|
+
"version": "1.1.0",
|
|
11
11
|
"description": "Modern custom Shopify storefronts",
|
|
12
12
|
"license": "MIT",
|
|
13
13
|
"main": "dist/esnext/index.js",
|
|
@@ -35,6 +35,11 @@
|
|
|
35
35
|
"import": "./dist/esnext/framework/cache/*.js",
|
|
36
36
|
"require": "./dist/node/framework/cache/*.js"
|
|
37
37
|
},
|
|
38
|
+
"./platforms": {
|
|
39
|
+
"types": "./dist/esnext/platforms/virtual.d.ts",
|
|
40
|
+
"import": "./dist/esnext/platforms/virtual.js",
|
|
41
|
+
"require": "./dist/node/platforms/virtual.js"
|
|
42
|
+
},
|
|
38
43
|
"./package.json": "./package.json",
|
|
39
44
|
"./*": "./dist/esnext/*.js"
|
|
40
45
|
},
|
|
@@ -297,6 +297,19 @@ function ReactFlightVitePlugin() {
|
|
|
297
297
|
|
|
298
298
|
return findClientBoundariesForClientBuild(serverBuildEntries, optimizeBoundaries !== false).then(injectGlobs);
|
|
299
299
|
}
|
|
300
|
+
},
|
|
301
|
+
handleHotUpdate: function (_ref2) {
|
|
302
|
+
var modules = _ref2.modules;
|
|
303
|
+
|
|
304
|
+
if (modules.some(function (mod) {
|
|
305
|
+
return mod.meta && mod.meta.isClientComponent;
|
|
306
|
+
})) {
|
|
307
|
+
return modules.filter(function (mod) {
|
|
308
|
+
return !mod.meta || !mod.meta.ssr;
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
return modules;
|
|
300
313
|
}
|
|
301
314
|
};
|
|
302
315
|
}
|
|
@@ -466,9 +479,9 @@ function isDirectImportInServer(originalMod, currentMod, accModInfo) {
|
|
|
466
479
|
exports: []
|
|
467
480
|
};
|
|
468
481
|
lastModImports.forEach(function (mod) {
|
|
469
|
-
mod.variables.forEach(function (
|
|
470
|
-
var name =
|
|
471
|
-
alias =
|
|
482
|
+
mod.variables.forEach(function (_ref3) {
|
|
483
|
+
var name = _ref3[0],
|
|
484
|
+
alias = _ref3[1];
|
|
472
485
|
|
|
473
486
|
if (name === '*' && !alias) {
|
|
474
487
|
var _accModInfo$exports;
|
|
@@ -501,8 +514,8 @@ function isDirectImportInServer(originalMod, currentMod, accModInfo) {
|
|
|
501
514
|
// the original module before marking it as client boundary.
|
|
502
515
|
|
|
503
516
|
return currentMod.meta.imports.some(function (imp) {
|
|
504
|
-
return imp.from === accModInfo.file && (imp.variables || []).some(function (
|
|
505
|
-
var name =
|
|
517
|
+
return imp.from === accModInfo.file && (imp.variables || []).some(function (_ref4) {
|
|
518
|
+
var name = _ref4[0];
|
|
506
519
|
return accModInfo.exports.includes(name);
|
|
507
520
|
});
|
|
508
521
|
});
|
|
@@ -540,12 +553,12 @@ function augmentModuleGraph(moduleGraph, id, code, root, resolveAlias) {
|
|
|
540
553
|
|
|
541
554
|
|
|
542
555
|
var imports = [];
|
|
543
|
-
rawImports.forEach(function (
|
|
544
|
-
var startMod =
|
|
545
|
-
endMod =
|
|
546
|
-
dynamicImportIndex =
|
|
547
|
-
startStatement =
|
|
548
|
-
endStatement =
|
|
556
|
+
rawImports.forEach(function (_ref5) {
|
|
557
|
+
var startMod = _ref5.s,
|
|
558
|
+
endMod = _ref5.e,
|
|
559
|
+
dynamicImportIndex = _ref5.d,
|
|
560
|
+
startStatement = _ref5.ss,
|
|
561
|
+
endStatement = _ref5.se;
|
|
549
562
|
if (dynamicImportIndex !== -1) return; // Skip dynamic imports for now
|
|
550
563
|
|
|
551
564
|
var rawModPath = code.slice(startMod, endMod);
|
|
@@ -593,7 +606,8 @@ function augmentModuleGraph(moduleGraph, id, code, root, resolveAlias) {
|
|
|
593
606
|
assign(currentModule.meta, {
|
|
594
607
|
isFacade: isFacade,
|
|
595
608
|
namedExports: namedExports,
|
|
596
|
-
imports: imports
|
|
609
|
+
imports: imports,
|
|
610
|
+
ssr: true
|
|
597
611
|
});
|
|
598
612
|
}
|
|
599
613
|
|
|
@@ -293,6 +293,19 @@ function ReactFlightVitePlugin() {
|
|
|
293
293
|
|
|
294
294
|
return findClientBoundariesForClientBuild(serverBuildEntries, optimizeBoundaries !== false).then(injectGlobs);
|
|
295
295
|
}
|
|
296
|
+
},
|
|
297
|
+
handleHotUpdate: function (_ref2) {
|
|
298
|
+
var modules = _ref2.modules;
|
|
299
|
+
|
|
300
|
+
if (modules.some(function (mod) {
|
|
301
|
+
return mod.meta && mod.meta.isClientComponent;
|
|
302
|
+
})) {
|
|
303
|
+
return modules.filter(function (mod) {
|
|
304
|
+
return !mod.meta || !mod.meta.ssr;
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
return modules;
|
|
296
309
|
}
|
|
297
310
|
};
|
|
298
311
|
}
|
|
@@ -462,9 +475,9 @@ function isDirectImportInServer(originalMod, currentMod, accModInfo) {
|
|
|
462
475
|
exports: []
|
|
463
476
|
};
|
|
464
477
|
lastModImports.forEach(function (mod) {
|
|
465
|
-
mod.variables.forEach(function (
|
|
466
|
-
var name =
|
|
467
|
-
alias =
|
|
478
|
+
mod.variables.forEach(function (_ref3) {
|
|
479
|
+
var name = _ref3[0],
|
|
480
|
+
alias = _ref3[1];
|
|
468
481
|
|
|
469
482
|
if (name === '*' && !alias) {
|
|
470
483
|
var _accModInfo$exports;
|
|
@@ -497,8 +510,8 @@ function isDirectImportInServer(originalMod, currentMod, accModInfo) {
|
|
|
497
510
|
// the original module before marking it as client boundary.
|
|
498
511
|
|
|
499
512
|
return currentMod.meta.imports.some(function (imp) {
|
|
500
|
-
return imp.from === accModInfo.file && (imp.variables || []).some(function (
|
|
501
|
-
var name =
|
|
513
|
+
return imp.from === accModInfo.file && (imp.variables || []).some(function (_ref4) {
|
|
514
|
+
var name = _ref4[0];
|
|
502
515
|
return accModInfo.exports.includes(name);
|
|
503
516
|
});
|
|
504
517
|
});
|
|
@@ -536,12 +549,12 @@ function augmentModuleGraph(moduleGraph, id, code, root, resolveAlias) {
|
|
|
536
549
|
|
|
537
550
|
|
|
538
551
|
var imports = [];
|
|
539
|
-
rawImports.forEach(function (
|
|
540
|
-
var startMod =
|
|
541
|
-
endMod =
|
|
542
|
-
dynamicImportIndex =
|
|
543
|
-
startStatement =
|
|
544
|
-
endStatement =
|
|
552
|
+
rawImports.forEach(function (_ref5) {
|
|
553
|
+
var startMod = _ref5.s,
|
|
554
|
+
endMod = _ref5.e,
|
|
555
|
+
dynamicImportIndex = _ref5.d,
|
|
556
|
+
startStatement = _ref5.ss,
|
|
557
|
+
endStatement = _ref5.se;
|
|
545
558
|
if (dynamicImportIndex !== -1) return; // Skip dynamic imports for now
|
|
546
559
|
|
|
547
560
|
var rawModPath = code.slice(startMod, endMod);
|
|
@@ -589,7 +602,8 @@ function augmentModuleGraph(moduleGraph, id, code, root, resolveAlias) {
|
|
|
589
602
|
assign(currentModule.meta, {
|
|
590
603
|
isFacade: isFacade,
|
|
591
604
|
namedExports: namedExports,
|
|
592
|
-
imports: imports
|
|
605
|
+
imports: imports,
|
|
606
|
+
ssr: true
|
|
593
607
|
});
|
|
594
608
|
}
|
|
595
609
|
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|