@lwrjs/lwc-ssr 0.22.1 → 0.22.2
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/build/cjs/directFetch.cjs +12 -13
- package/build/es/directFetch.js +18 -20
- package/build/es/fetchController.js +59 -64
- package/build/es/renderer.js +1 -6
- package/build/es/resourceProvider.js +3 -4
- package/build/es/serverBootstrapServices.js +0 -3
- package/build/es/viewProvider/index.js +1 -6
- package/package.json +9 -9
|
@@ -66,23 +66,22 @@ async function fetchWithAgent(request, init, forwardedOrigin, coreProxy, span) {
|
|
|
66
66
|
});
|
|
67
67
|
CORE_CLIENTS.set(origin, client);
|
|
68
68
|
}
|
|
69
|
-
|
|
69
|
+
const res = await client.request({
|
|
70
70
|
...init,
|
|
71
71
|
method: init.method || "GET",
|
|
72
72
|
path,
|
|
73
73
|
headers: {...init?.headers, Host: hostHeader},
|
|
74
74
|
servername
|
|
75
|
-
}).then(async (res) => {
|
|
76
|
-
span.setAttributes({coreStatusCode: res.statusCode});
|
|
77
|
-
const bodyBuffer = await res.body.arrayBuffer();
|
|
78
|
-
const body = res.statusCode === 204 || res.statusCode === 205 ? null : bodyBuffer;
|
|
79
|
-
const headers = new Headers();
|
|
80
|
-
for (const [key, value] of Object.entries(res.headers)) {
|
|
81
|
-
if (!value)
|
|
82
|
-
continue;
|
|
83
|
-
const values = Array.isArray(value) ? value : [value];
|
|
84
|
-
values.forEach((v) => headers.append(key, v));
|
|
85
|
-
}
|
|
86
|
-
return new Response(body, {status: res.statusCode, headers});
|
|
87
75
|
});
|
|
76
|
+
span.setAttributes({coreStatusCode: res.statusCode});
|
|
77
|
+
const bodyBuffer = await res.body.arrayBuffer();
|
|
78
|
+
const body = res.statusCode === 204 || res.statusCode === 205 ? null : bodyBuffer;
|
|
79
|
+
const headers = new Headers();
|
|
80
|
+
for (const [key, value] of Object.entries(res.headers)) {
|
|
81
|
+
if (!value)
|
|
82
|
+
continue;
|
|
83
|
+
const values = Array.isArray(value) ? value : [value];
|
|
84
|
+
values.forEach((v) => headers.append(key, v));
|
|
85
|
+
}
|
|
86
|
+
return new Response(body, {status: res.statusCode, headers});
|
|
88
87
|
}
|
package/build/es/directFetch.js
CHANGED
|
@@ -49,8 +49,8 @@ export async function fetchWithAgent(request, init, forwardedOrigin, coreProxy,
|
|
|
49
49
|
});
|
|
50
50
|
CORE_CLIENTS.set(origin, client);
|
|
51
51
|
}
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
// Pool.request returns Promise when no callback; types can resolve to void when options spread from RequestInit
|
|
53
|
+
const res = await client.request({
|
|
54
54
|
...init,
|
|
55
55
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
56
56
|
// @ts-ignore - HttpMethod not available for typecasting :|
|
|
@@ -60,24 +60,22 @@ export async function fetchWithAgent(request, init, forwardedOrigin, coreProxy,
|
|
|
60
60
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
61
61
|
// @ts-ignore - not properly typed >:|
|
|
62
62
|
servername,
|
|
63
|
-
})
|
|
64
|
-
.then(async (res) => {
|
|
65
|
-
// Set the core* attrs early, so the info is not lost if we fallback to CDN
|
|
66
|
-
// With no CDN fallback url=coreUrl and statusCode=coreStatusCode
|
|
67
|
-
span.setAttributes({ coreStatusCode: res.statusCode });
|
|
68
|
-
// convert the response to a fetch Response object
|
|
69
|
-
// downstream consumers expect a Response since it's the standard fetch return object
|
|
70
|
-
// this allows callers to check the response with "instanceof Response"
|
|
71
|
-
const bodyBuffer = await res.body.arrayBuffer();
|
|
72
|
-
const body = res.statusCode === 204 || res.statusCode === 205 ? null : bodyBuffer;
|
|
73
|
-
const headers = new Headers();
|
|
74
|
-
for (const [key, value] of Object.entries(res.headers)) {
|
|
75
|
-
if (!value)
|
|
76
|
-
continue;
|
|
77
|
-
const values = Array.isArray(value) ? value : [value];
|
|
78
|
-
values.forEach((v) => headers.append(key, v));
|
|
79
|
-
}
|
|
80
|
-
return new Response(body, { status: res.statusCode, headers });
|
|
81
63
|
});
|
|
64
|
+
// Set the core* attrs early, so the info is not lost if we fallback to CDN
|
|
65
|
+
// With no CDN fallback url=coreUrl and statusCode=coreStatusCode
|
|
66
|
+
span.setAttributes({ coreStatusCode: res.statusCode });
|
|
67
|
+
// convert the response to a fetch Response object
|
|
68
|
+
// downstream consumers expect a Response since it's the standard fetch return object
|
|
69
|
+
// this allows callers to check the response with "instanceof Response"
|
|
70
|
+
const bodyBuffer = await res.body.arrayBuffer();
|
|
71
|
+
const body = res.statusCode === 204 || res.statusCode === 205 ? null : bodyBuffer;
|
|
72
|
+
const headers = new Headers();
|
|
73
|
+
for (const [key, value] of Object.entries(res.headers)) {
|
|
74
|
+
if (!value)
|
|
75
|
+
continue;
|
|
76
|
+
const values = Array.isArray(value) ? value : [value];
|
|
77
|
+
values.forEach((v) => headers.append(key, v));
|
|
78
|
+
}
|
|
79
|
+
return new Response(body, { status: res.statusCode, headers });
|
|
82
80
|
}
|
|
83
81
|
//# sourceMappingURL=directFetch.js.map
|
|
@@ -13,75 +13,70 @@ import { getFinalRequest } from './utils.js';
|
|
|
13
13
|
* Any new fetch calls (i.e. from other async function calls) would be immediately aborted.
|
|
14
14
|
*/
|
|
15
15
|
export class FetchController {
|
|
16
|
-
killSwitchActivated = false;
|
|
17
|
-
noOpActivated = false;
|
|
18
|
-
abortController;
|
|
19
|
-
headers;
|
|
20
|
-
host;
|
|
21
|
-
coreProxy;
|
|
22
|
-
fetchEndowment;
|
|
23
16
|
constructor(context, coreProxy) {
|
|
17
|
+
this.killSwitchActivated = false;
|
|
18
|
+
this.noOpActivated = false;
|
|
19
|
+
this.controlledFetch = (request, init) => {
|
|
20
|
+
if (this.killSwitchActivated) {
|
|
21
|
+
return this.handleAbortError(request, 'Kill switch was already enabled');
|
|
22
|
+
}
|
|
23
|
+
if (!this.abortController) {
|
|
24
|
+
this.abortController = new AbortController();
|
|
25
|
+
}
|
|
26
|
+
const signal = this.abortController?.signal;
|
|
27
|
+
// Ensure the init object exists and then add the signal to it.
|
|
28
|
+
const updatedInit = {
|
|
29
|
+
...init,
|
|
30
|
+
headers: { ...init?.headers, ...this.headers },
|
|
31
|
+
signal,
|
|
32
|
+
};
|
|
33
|
+
const fetchFunction = this.noOpActivated
|
|
34
|
+
? this.fetchNoOp(request, updatedInit)
|
|
35
|
+
: this.fetchEndowment(request, updatedInit);
|
|
36
|
+
const fetchPromise = fetchFunction.catch((error) => {
|
|
37
|
+
// Check if the error is an AbortError
|
|
38
|
+
const errorMsg = error.message || error;
|
|
39
|
+
if (error && (errorMsg.startsWith('AbortError') || error?.stack.startsWith('AbortError'))) {
|
|
40
|
+
return this.handleAbortError(request, error);
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
// Re-throw the error if it's not an AbortError
|
|
44
|
+
throw error;
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
return fetchPromise;
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* After SSR is complete the kill switch will abort any pending fetch requests.
|
|
51
|
+
*/
|
|
52
|
+
this.activateKillSwitch = () => {
|
|
53
|
+
this.killSwitchActivated = true;
|
|
54
|
+
this.abortController?.abort('AbortError: Kill switch enabled');
|
|
55
|
+
this.abortController = undefined;
|
|
56
|
+
};
|
|
57
|
+
this.deactivateKillSwitch = () => {
|
|
58
|
+
this.killSwitchActivated = false;
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* During SSR renderComponent (which is synchronous) Do not even call any fetch requests
|
|
62
|
+
* since they would not complete before SSR is done.
|
|
63
|
+
*/
|
|
64
|
+
this.activateNoOp = () => {
|
|
65
|
+
this.noOpActivated = true;
|
|
66
|
+
};
|
|
67
|
+
this.deactivateNoOp = () => {
|
|
68
|
+
this.noOpActivated = false;
|
|
69
|
+
};
|
|
70
|
+
this.setFetchRequestContext = (context) => {
|
|
71
|
+
const { abortController, host, headers } = context;
|
|
72
|
+
this.host = host;
|
|
73
|
+
this.headers = headers;
|
|
74
|
+
this.abortController = abortController;
|
|
75
|
+
};
|
|
24
76
|
this.coreProxy = coreProxy;
|
|
25
77
|
this.setFetchRequestContext(context);
|
|
26
78
|
this.fetchEndowment = this.createFetchEndowment();
|
|
27
79
|
}
|
|
28
|
-
controlledFetch = (request, init) => {
|
|
29
|
-
if (this.killSwitchActivated) {
|
|
30
|
-
return this.handleAbortError(request, 'Kill switch was already enabled');
|
|
31
|
-
}
|
|
32
|
-
if (!this.abortController) {
|
|
33
|
-
this.abortController = new AbortController();
|
|
34
|
-
}
|
|
35
|
-
const signal = this.abortController?.signal;
|
|
36
|
-
// Ensure the init object exists and then add the signal to it.
|
|
37
|
-
const updatedInit = {
|
|
38
|
-
...init,
|
|
39
|
-
headers: { ...init?.headers, ...this.headers },
|
|
40
|
-
signal,
|
|
41
|
-
};
|
|
42
|
-
const fetchFunction = this.noOpActivated
|
|
43
|
-
? this.fetchNoOp(request, updatedInit)
|
|
44
|
-
: this.fetchEndowment(request, updatedInit);
|
|
45
|
-
const fetchPromise = fetchFunction.catch((error) => {
|
|
46
|
-
// Check if the error is an AbortError
|
|
47
|
-
const errorMsg = error.message || error;
|
|
48
|
-
if (error && (errorMsg.startsWith('AbortError') || error?.stack.startsWith('AbortError'))) {
|
|
49
|
-
return this.handleAbortError(request, error);
|
|
50
|
-
}
|
|
51
|
-
else {
|
|
52
|
-
// Re-throw the error if it's not an AbortError
|
|
53
|
-
throw error;
|
|
54
|
-
}
|
|
55
|
-
});
|
|
56
|
-
return fetchPromise;
|
|
57
|
-
};
|
|
58
|
-
/**
|
|
59
|
-
* After SSR is complete the kill switch will abort any pending fetch requests.
|
|
60
|
-
*/
|
|
61
|
-
activateKillSwitch = () => {
|
|
62
|
-
this.killSwitchActivated = true;
|
|
63
|
-
this.abortController?.abort('AbortError: Kill switch enabled');
|
|
64
|
-
this.abortController = undefined;
|
|
65
|
-
};
|
|
66
|
-
deactivateKillSwitch = () => {
|
|
67
|
-
this.killSwitchActivated = false;
|
|
68
|
-
};
|
|
69
|
-
/**
|
|
70
|
-
* During SSR renderComponent (which is synchronous) Do not even call any fetch requests
|
|
71
|
-
* since they would not complete before SSR is done.
|
|
72
|
-
*/
|
|
73
|
-
activateNoOp = () => {
|
|
74
|
-
this.noOpActivated = true;
|
|
75
|
-
};
|
|
76
|
-
deactivateNoOp = () => {
|
|
77
|
-
this.noOpActivated = false;
|
|
78
|
-
};
|
|
79
|
-
setFetchRequestContext = (context) => {
|
|
80
|
-
const { abortController, host, headers } = context;
|
|
81
|
-
this.host = host;
|
|
82
|
-
this.headers = headers;
|
|
83
|
-
this.abortController = abortController;
|
|
84
|
-
};
|
|
85
80
|
handleAbortError(request, error) {
|
|
86
81
|
const message = `${String(request)} request was killed. Either the request timed out or it was dispatched during SSR. Async processes are not supported during SSR. For more information, see: https://developer.salesforce.com/docs/platform/lwr/guide/lwr-configure-component-ssr.html.`;
|
|
87
82
|
logger.warn({ label: `Server-side Rendering`, message }, error);
|
package/build/es/renderer.js
CHANGED
|
@@ -22,13 +22,8 @@ export function getRenderer(config, bundleRegistry, resourceRegistry) {
|
|
|
22
22
|
return singleton;
|
|
23
23
|
}
|
|
24
24
|
export class Renderer {
|
|
25
|
-
config;
|
|
26
|
-
bundleRegistry;
|
|
27
|
-
resourceRegistry;
|
|
28
|
-
contextPerEnv;
|
|
29
|
-
pendingRenders;
|
|
30
|
-
globalCache = {};
|
|
31
25
|
constructor(config, bundleRegistry, resourceRegistry) {
|
|
26
|
+
this.globalCache = {};
|
|
32
27
|
this.config = config;
|
|
33
28
|
this.bundleRegistry = bundleRegistry;
|
|
34
29
|
this.resourceRegistry = resourceRegistry;
|
|
@@ -21,11 +21,10 @@ const banner = `/**
|
|
|
21
21
|
*/
|
|
22
22
|
/* LWC SSR Client Utils v${LWC_VERSION} */`;
|
|
23
23
|
export default class SsrResourceProvider {
|
|
24
|
-
name = 'lwc-ssr-client-utils';
|
|
25
|
-
ssrUtilsName = 'register-lwc-style.js';
|
|
26
|
-
versionCache = new Map();
|
|
27
|
-
context;
|
|
28
24
|
constructor(_config, context) {
|
|
25
|
+
this.name = 'lwc-ssr-client-utils';
|
|
26
|
+
this.ssrUtilsName = 'register-lwc-style.js';
|
|
27
|
+
this.versionCache = new Map();
|
|
29
28
|
this.context = context;
|
|
30
29
|
}
|
|
31
30
|
async getResource(resource, environment) {
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import { ViewSpan, getTracer } from '@lwrjs/instrumentation';
|
|
2
2
|
import { LwrApplicationError, LwrError, stringifyError } from '@lwrjs/diagnostics';
|
|
3
3
|
export class ServerBootstrapServices {
|
|
4
|
-
serverDataCallbacks;
|
|
5
|
-
requestHooks;
|
|
6
|
-
_serviceAPI;
|
|
7
4
|
evaluateServerDataHooks(serverData = {}) {
|
|
8
5
|
// now that we have server data, run the server data hooks
|
|
9
6
|
for (const serverDataHook of this.serverDataCallbacks) {
|
|
@@ -4,14 +4,9 @@ import { ViewSpan, getTracer } from '@lwrjs/instrumentation';
|
|
|
4
4
|
import { createHeadMarkup, hashContent, isSpecifier, moduleSpecifierToKebabCase, slugify, } from '@lwrjs/shared-utils';
|
|
5
5
|
import { getRenderer } from '../renderer.js';
|
|
6
6
|
export default class LwcViewProvider extends BaseViewProvider {
|
|
7
|
-
name = 'ssr-view-provider';
|
|
8
|
-
moduleBundler;
|
|
9
|
-
resourceRegistry;
|
|
10
|
-
routes;
|
|
11
|
-
runtimeEnvironment;
|
|
12
|
-
config;
|
|
13
7
|
constructor(_pluginConfig, providerConfig) {
|
|
14
8
|
super();
|
|
9
|
+
this.name = 'ssr-view-provider';
|
|
15
10
|
this.moduleBundler = providerConfig.moduleBundler;
|
|
16
11
|
this.resourceRegistry = providerConfig.resourceRegistry;
|
|
17
12
|
this.routes = [...providerConfig.config.routes, ...providerConfig.config.errorRoutes];
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
7
|
-
"version": "0.22.
|
|
7
|
+
"version": "0.22.2",
|
|
8
8
|
"homepage": "https://developer.salesforce.com/docs/platform/lwr/overview",
|
|
9
9
|
"repository": {
|
|
10
10
|
"type": "git",
|
|
@@ -48,20 +48,20 @@
|
|
|
48
48
|
"package.cjs"
|
|
49
49
|
],
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@lwrjs/config": "0.22.
|
|
52
|
-
"@lwrjs/diagnostics": "0.22.
|
|
53
|
-
"@lwrjs/instrumentation": "0.22.
|
|
54
|
-
"@lwrjs/loader": "0.22.
|
|
55
|
-
"@lwrjs/shared-utils": "0.22.
|
|
51
|
+
"@lwrjs/config": "0.22.2",
|
|
52
|
+
"@lwrjs/diagnostics": "0.22.2",
|
|
53
|
+
"@lwrjs/instrumentation": "0.22.2",
|
|
54
|
+
"@lwrjs/loader": "0.22.2",
|
|
55
|
+
"@lwrjs/shared-utils": "0.22.2",
|
|
56
56
|
"@rollup/plugin-node-resolve": "^15.2.3",
|
|
57
57
|
"@rollup/plugin-terser": "^0.4.4",
|
|
58
58
|
"fs-extra": "^11.2.0",
|
|
59
59
|
"lru-cache": "^10.4.3",
|
|
60
60
|
"rollup": "^2.79.2",
|
|
61
|
-
"undici": "^
|
|
61
|
+
"undici": "^7.0.0"
|
|
62
62
|
},
|
|
63
63
|
"devDependencies": {
|
|
64
|
-
"@lwrjs/types": "0.22.
|
|
64
|
+
"@lwrjs/types": "0.22.2",
|
|
65
65
|
"jest": "29.7.0",
|
|
66
66
|
"memfs": "^4.13.0",
|
|
67
67
|
"ts-jest": "^29.2.6"
|
|
@@ -75,5 +75,5 @@
|
|
|
75
75
|
"volta": {
|
|
76
76
|
"extends": "../../../package.json"
|
|
77
77
|
},
|
|
78
|
-
"gitHead": "
|
|
78
|
+
"gitHead": "30870e466e15e6691d238e75836e9266a45203e3"
|
|
79
79
|
}
|