@lwrjs/client-modules 0.17.2-alpha.3 → 0.17.2-alpha.31
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/bundle/prod/lwr/init/init.js +1 -1
- package/build/bundle/prod/lwr/lockerDefine/lockerDefine.js +1 -1
- package/build/bundle/prod/lwr/servicesESM/servicesESM.js +1 -1
- package/build/es/modules/lwr/init/init.js +100 -75
- package/build/es/modules/lwr/profiler/profiler.js +3 -2
- package/build/modules/lwr/hmr/hmr.js +4 -1
- package/build/modules/lwr/init/init.js +128 -93
- package/build/modules/lwr/lockerDefine/lockerDefine.js +232 -75
- package/build/modules/lwr/lockerSandbox/lockerSandbox.js +226 -71
- package/build/modules/lwr/preInit/preInit.js +4 -3
- package/build/modules/lwr/profiler/profiler.js +5 -2
- package/build/modules/lwr/servicesESM/handleStaleModuleESM.js +2 -3
- package/build/modules/lwr/servicesESM/servicesESM.js +4 -0
- package/package.json +6 -6
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=[];let o;const n=globalThis.LWR;
|
|
1
|
+
const e=[];let o;const n=globalThis,t=n.LWR;t.define||t.env?n.LWR=Object.freeze({define:t.define,env:t.env}):delete n.LWR;const a={addLoaderPlugin:()=>{console.warn("API is not supported in ESM format")},handleStaleModule:function(n){e.push(n),o||(o=new WebSocket(`ws://${location.host}`),o.addEventListener("message",(async o=>{const n=o.data,t=JSON.parse(n);if("moduleUpdate"===t.eventType){const{oldHash:o,newHash:n,module:{specifier:a}}=t.payload;for(let t=0;t<e.length;t++){if(null!==(0,e[t])({name:a,oldHash:o,newHash:n}))break}}})))},appMetadata:function(){const{appId:e,bootstrapModule:o,rootComponent:n,rootComponents:a}=t;return{appId:e,bootstrapModule:o,rootComponent:n,rootComponents:a}}(),addServerDataCallback:function(e){}};export{a as services};
|
|
2
2
|
//# sourceMappingURL=servicesESM.js.map
|
|
@@ -1,26 +1,38 @@
|
|
|
1
1
|
import { BOOTSTRAP_END, INIT, INIT_MODULE } from 'lwr/metrics';
|
|
2
2
|
import { logOperationStart, logOperationEnd } from 'lwr/profiler';
|
|
3
3
|
// TODO: This is a temporal workaround until https://github.com/salesforce/lwc/pull/2083 is sorted - tmp
|
|
4
|
+
// eslint-disable-next-line lwr/only-allowed-imports
|
|
4
5
|
import { createElement } from 'lwc';
|
|
5
6
|
// <hydrateComponentProxy> - This code is removed in core
|
|
6
7
|
// Note: a build step uses these comments to strip the code for core.
|
|
8
|
+
// eslint-disable-next-line lwr/only-allowed-imports
|
|
7
9
|
import { hydrateComponent } from 'lwc';
|
|
8
10
|
function hydrateComponentProxy(customElement, Ctor, props) {
|
|
9
11
|
hydrateComponent(customElement, Ctor, props);
|
|
10
12
|
}
|
|
11
13
|
// </hydrateComponentProxy>
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
if (now - timeOfLastYield > HYDRATION_TASK_BATCH_DURATION) {
|
|
19
|
-
timeOfLastYield = now;
|
|
20
|
-
return true;
|
|
14
|
+
const shouldYield = (() => {
|
|
15
|
+
const globalThisLWR = globalThis;
|
|
16
|
+
const { SSREnabled } = (globalThisLWR.LWR && globalThisLWR.LWR.env) || {};
|
|
17
|
+
// eslint-disable-next-line lwr/no-unguarded-apis
|
|
18
|
+
if (!globalThis.performance || !SSREnabled) {
|
|
19
|
+
return () => false;
|
|
21
20
|
}
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
// Break up hydration tasks into timed batches.
|
|
22
|
+
// Borrowed from https://tinyurl.com/5b4fw7eb
|
|
23
|
+
const TASK_BATCH_DURATION = 50;
|
|
24
|
+
// eslint-disable-next-line lwr/no-unguarded-apis
|
|
25
|
+
let timeOfLastYield = globalThis.performance.now();
|
|
26
|
+
return () => {
|
|
27
|
+
// eslint-disable-next-line lwr/no-unguarded-apis
|
|
28
|
+
const now = globalThis.performance.now();
|
|
29
|
+
if (now - timeOfLastYield > TASK_BATCH_DURATION) {
|
|
30
|
+
timeOfLastYield = now;
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
return false;
|
|
34
|
+
};
|
|
35
|
+
})();
|
|
24
36
|
function initializeWebComponent(elementName, Ctor) {
|
|
25
37
|
return createElement(elementName, { is: Ctor });
|
|
26
38
|
}
|
|
@@ -56,84 +68,97 @@ export function getPropFromAttrName(propName) {
|
|
|
56
68
|
* @example - [['x/appRoot', appCtor], ['x/nav', navCtor]]
|
|
57
69
|
*/
|
|
58
70
|
export function init(rootModules, serverData = {}) {
|
|
59
|
-
|
|
71
|
+
// eslint-disable-next-line lwr/no-unguarded-apis
|
|
72
|
+
if (typeof globalThis.customElements === 'undefined' || typeof globalThis.document === 'undefined') {
|
|
60
73
|
logOperationStart({ id: BOOTSTRAP_END });
|
|
61
74
|
return;
|
|
62
75
|
}
|
|
63
76
|
logOperationStart({ id: INIT });
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
const propsId = element.dataset.lwrPropsId;
|
|
87
|
-
// hydrate SSR'd components
|
|
88
|
-
if (propsId) {
|
|
89
|
-
if (shouldYield()) {
|
|
90
|
-
// give room for the browser to render during long hydration tasks
|
|
91
|
-
setTimeout(() => {
|
|
92
|
-
hydrateComponentProxy(element, ctor, serverData[propsId] || {});
|
|
93
|
-
}, 0);
|
|
94
|
-
}
|
|
95
|
-
else {
|
|
96
|
-
hydrateComponentProxy(element, ctor, serverData[propsId] || {});
|
|
97
|
-
}
|
|
77
|
+
(async () => {
|
|
78
|
+
let index = 0;
|
|
79
|
+
// eslint-disable-next-line lwr/no-unguarded-apis
|
|
80
|
+
const document = globalThis.document;
|
|
81
|
+
for (const [specifier, ctor] of rootModules) {
|
|
82
|
+
if (shouldYield()) {
|
|
83
|
+
// Yield to the main thread during long hydration tasks
|
|
84
|
+
// eslint-disable-next-line no-await-in-loop
|
|
85
|
+
await yieldToMainThread();
|
|
86
|
+
}
|
|
87
|
+
const specifierIndex = ++index;
|
|
88
|
+
const elementName = toKebabCase(specifier);
|
|
89
|
+
// initialize and inject the root module into the LWR Root or DOM if it is missing
|
|
90
|
+
// eslint-disable-next-line lwr/no-unguarded-apis
|
|
91
|
+
if (!document.body.querySelector(elementName)) {
|
|
92
|
+
logOperationStart({ id: INIT_MODULE, specifier, specifierIndex });
|
|
93
|
+
// this is for SPA like routes (one component at the root level) utilizing the lwr-root directive
|
|
94
|
+
const component = initializeWebComponent(elementName, ctor);
|
|
95
|
+
// eslint-disable-next-line lwr/no-unguarded-apis
|
|
96
|
+
const container = document.querySelector('[lwr-root]');
|
|
97
|
+
// eslint-disable-next-line lwr/no-unguarded-apis
|
|
98
|
+
container ? container.appendChild(component) : document.body.appendChild(component);
|
|
98
99
|
logOperationEnd({
|
|
99
100
|
id: INIT_MODULE,
|
|
100
101
|
specifier,
|
|
101
|
-
specifierIndex
|
|
102
|
-
metadata: { renderMode: '
|
|
102
|
+
specifierIndex,
|
|
103
|
+
metadata: { renderMode: 'spa' },
|
|
103
104
|
});
|
|
104
105
|
continue;
|
|
105
106
|
}
|
|
106
|
-
//
|
|
107
|
-
//
|
|
108
|
-
|
|
109
|
-
const
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
107
|
+
// the page has been rendered or SSR'd, and each component needs to initialized(or hydrated)
|
|
108
|
+
// eslint-disable-next-line lwr/no-unguarded-apis
|
|
109
|
+
const elements = document.querySelectorAll(elementName);
|
|
110
|
+
for (const element of elements) {
|
|
111
|
+
logOperationStart({ id: INIT_MODULE, specifier, specifierIndex });
|
|
112
|
+
const propsId = element.dataset.lwrPropsId;
|
|
113
|
+
// hydrate SSR'd components
|
|
114
|
+
if (propsId) {
|
|
115
|
+
hydrateComponentProxy(element, ctor, serverData[propsId] || {});
|
|
116
|
+
logOperationEnd({
|
|
117
|
+
id: INIT_MODULE,
|
|
118
|
+
specifier,
|
|
119
|
+
specifierIndex,
|
|
120
|
+
metadata: { renderMode: 'ssr' },
|
|
121
|
+
});
|
|
122
|
+
continue;
|
|
117
123
|
}
|
|
124
|
+
// Note: due to the bug described at the top of this file, each CSR'd custom element
|
|
125
|
+
// must be replaced with the new synthetic constructor. Attributes and children are
|
|
126
|
+
// copied over to the new component.
|
|
127
|
+
const component = initializeWebComponent(elementName, ctor);
|
|
128
|
+
// copy the attributes
|
|
129
|
+
for (const { name, value } of element.attributes) {
|
|
130
|
+
component.setAttribute(name, value);
|
|
131
|
+
const prop = getPropFromAttrName(name);
|
|
132
|
+
if (prop in component) {
|
|
133
|
+
// set attributes as properties for reactivity
|
|
134
|
+
component[prop] = value;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
// save the children
|
|
138
|
+
while (element.childNodes.length > 0) {
|
|
139
|
+
component.appendChild(element.childNodes[0]);
|
|
140
|
+
}
|
|
141
|
+
// swap the element out with the initialized component
|
|
142
|
+
const parent = element.parentElement;
|
|
143
|
+
if (parent) {
|
|
144
|
+
parent.replaceChild(component, element);
|
|
145
|
+
}
|
|
146
|
+
logOperationEnd({
|
|
147
|
+
id: INIT_MODULE,
|
|
148
|
+
specifier,
|
|
149
|
+
specifierIndex,
|
|
150
|
+
metadata: { renderMode: 'csr' },
|
|
151
|
+
});
|
|
118
152
|
}
|
|
119
|
-
// save the children
|
|
120
|
-
while (element.childNodes.length > 0) {
|
|
121
|
-
component.appendChild(element.childNodes[0]);
|
|
122
|
-
}
|
|
123
|
-
// swap the element out with the initialized component
|
|
124
|
-
const parent = element.parentElement;
|
|
125
|
-
if (parent) {
|
|
126
|
-
parent.replaceChild(component, element);
|
|
127
|
-
}
|
|
128
|
-
logOperationEnd({
|
|
129
|
-
id: INIT_MODULE,
|
|
130
|
-
specifier,
|
|
131
|
-
specifierIndex: index,
|
|
132
|
-
metadata: { renderMode: 'csr' },
|
|
133
|
-
});
|
|
134
153
|
}
|
|
135
|
-
}
|
|
154
|
+
})();
|
|
136
155
|
logOperationEnd({ id: INIT });
|
|
137
156
|
logOperationStart({ id: BOOTSTRAP_END });
|
|
138
157
|
}
|
|
158
|
+
// Allows the browser to yield to the main thread during long-running tasks, improving responsiveness.
|
|
159
|
+
async function yieldToMainThread() {
|
|
160
|
+
const scheduler = globalThis.scheduler;
|
|
161
|
+
// eslint-disable-next-line lwr/no-unguarded-apis
|
|
162
|
+
return scheduler?.yield ? scheduler.yield() : new Promise((resolve) => setTimeout(resolve, 0));
|
|
163
|
+
}
|
|
139
164
|
//# sourceMappingURL=init.js.map
|
|
@@ -10,6 +10,7 @@ export function attachDispatcher(dispatcher) {
|
|
|
10
10
|
}
|
|
11
11
|
// Check if the Performance API is available
|
|
12
12
|
// e.g. JSDom (used in Jest) doesn't implement these
|
|
13
|
+
// eslint-disable-next-line
|
|
13
14
|
const perf = globalThis.performance;
|
|
14
15
|
const isPerfSupported = typeof perf !== 'undefined' &&
|
|
15
16
|
typeof perf.mark === 'function' &&
|
|
@@ -34,7 +35,7 @@ function getDetail(specifier, metadata) {
|
|
|
34
35
|
// Fallback to the Performance API if there is no custom dispatcher
|
|
35
36
|
export function logOperationStart({ id, specifier, specifierIndex, metadata }) {
|
|
36
37
|
if (customDispatcher) {
|
|
37
|
-
customDispatcher({ id, phase: Phase.Start, specifier, metadata });
|
|
38
|
+
customDispatcher({ id, phase: Phase.Start, specifier, metadata, specifierIndex });
|
|
38
39
|
return;
|
|
39
40
|
}
|
|
40
41
|
if (isPerfSupported) {
|
|
@@ -48,7 +49,7 @@ export function logOperationStart({ id, specifier, specifierIndex, metadata }) {
|
|
|
48
49
|
/* istanbul ignore next */
|
|
49
50
|
export function logOperationEnd({ id, specifier, specifierIndex, metadata }) {
|
|
50
51
|
if (customDispatcher) {
|
|
51
|
-
customDispatcher({ id, phase: Phase.End, specifier, metadata });
|
|
52
|
+
customDispatcher({ id, phase: Phase.End, specifier, metadata, specifierIndex });
|
|
52
53
|
}
|
|
53
54
|
else if (isPerfSupported) {
|
|
54
55
|
const markName = getMarkName(id, specifier, specifierIndex);
|
|
@@ -32,7 +32,10 @@ function updateStaleModule({ oldModule, newModule, specifier }) {
|
|
|
32
32
|
swapStyle(oldModule.default[0], newModule.default[0]);
|
|
33
33
|
} else {
|
|
34
34
|
console.log(`Swapping JS for module "${specifier}"`);
|
|
35
|
-
swapComponent(oldModule.default, newModule.default);
|
|
35
|
+
const success = swapComponent(oldModule.default, newModule.default);
|
|
36
|
+
if (!success) {
|
|
37
|
+
window.location.reload();
|
|
38
|
+
}
|
|
36
39
|
}
|
|
37
40
|
}
|
|
38
41
|
|
|
@@ -1,29 +1,49 @@
|
|
|
1
|
+
// eslint-disable-next-line lwr/only-allowed-type-imports
|
|
2
|
+
|
|
3
|
+
// eslint-disable-next-line lwr/only-allowed-type-imports
|
|
4
|
+
|
|
1
5
|
import { BOOTSTRAP_END, INIT, INIT_MODULE } from 'lwr/metrics';
|
|
2
6
|
import { logOperationStart, logOperationEnd } from 'lwr/profiler';
|
|
3
7
|
|
|
4
8
|
// TODO: This is a temporal workaround until https://github.com/salesforce/lwc/pull/2083 is sorted - tmp
|
|
9
|
+
// eslint-disable-next-line lwr/only-allowed-imports
|
|
5
10
|
import { createElement } from 'lwc';
|
|
6
11
|
|
|
7
12
|
// <hydrateComponentProxy> - This code is removed in core
|
|
8
13
|
// Note: a build step uses these comments to strip the code for core.
|
|
14
|
+
// eslint-disable-next-line lwr/only-allowed-imports
|
|
9
15
|
import { hydrateComponent } from 'lwc';
|
|
10
16
|
function hydrateComponentProxy(customElement, Ctor, props) {
|
|
11
17
|
hydrateComponent(customElement, Ctor, props);
|
|
12
18
|
}
|
|
13
19
|
// </hydrateComponentProxy>
|
|
14
20
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
return
|
|
21
|
+
const shouldYield = (() => {
|
|
22
|
+
const globalThisLWR = globalThis;
|
|
23
|
+
const {
|
|
24
|
+
SSREnabled
|
|
25
|
+
} = globalThisLWR.LWR && globalThisLWR.LWR.env || {};
|
|
26
|
+
|
|
27
|
+
// eslint-disable-next-line lwr/no-unguarded-apis
|
|
28
|
+
if (!globalThis.performance || !SSREnabled) {
|
|
29
|
+
return () => false;
|
|
24
30
|
}
|
|
25
|
-
|
|
26
|
-
|
|
31
|
+
|
|
32
|
+
// Break up hydration tasks into timed batches.
|
|
33
|
+
// Borrowed from https://tinyurl.com/5b4fw7eb
|
|
34
|
+
const TASK_BATCH_DURATION = 50;
|
|
35
|
+
// eslint-disable-next-line lwr/no-unguarded-apis
|
|
36
|
+
let timeOfLastYield = globalThis.performance.now();
|
|
37
|
+
return () => {
|
|
38
|
+
// eslint-disable-next-line lwr/no-unguarded-apis
|
|
39
|
+
const now = globalThis.performance.now();
|
|
40
|
+
if (now - timeOfLastYield > TASK_BATCH_DURATION) {
|
|
41
|
+
timeOfLastYield = now;
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
return false;
|
|
45
|
+
};
|
|
46
|
+
})();
|
|
27
47
|
function initializeWebComponent(elementName, Ctor) {
|
|
28
48
|
return createElement(elementName, {
|
|
29
49
|
is: Ctor
|
|
@@ -61,7 +81,8 @@ export function getPropFromAttrName(propName) {
|
|
|
61
81
|
* @example - [['x/appRoot', appCtor], ['x/nav', navCtor]]
|
|
62
82
|
*/
|
|
63
83
|
export function init(rootModules, serverData = {}) {
|
|
64
|
-
|
|
84
|
+
// eslint-disable-next-line lwr/no-unguarded-apis
|
|
85
|
+
if (typeof globalThis.customElements === 'undefined' || typeof globalThis.document === 'undefined') {
|
|
65
86
|
logOperationStart({
|
|
66
87
|
id: BOOTSTRAP_END
|
|
67
88
|
});
|
|
@@ -70,106 +91,120 @@ export function init(rootModules, serverData = {}) {
|
|
|
70
91
|
logOperationStart({
|
|
71
92
|
id: INIT
|
|
72
93
|
});
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
// this is for SPA like routes (one component at the root level) utilizing the lwr-root directive
|
|
86
|
-
const component = initializeWebComponent(elementName, ctor);
|
|
87
|
-
const container = document.querySelector('[lwr-root]');
|
|
88
|
-
container ? container.appendChild(component) : document.body.appendChild(component);
|
|
89
|
-
logOperationEnd({
|
|
90
|
-
id: INIT_MODULE,
|
|
91
|
-
specifier,
|
|
92
|
-
specifierIndex: index,
|
|
93
|
-
metadata: {
|
|
94
|
-
renderMode: 'spa'
|
|
95
|
-
}
|
|
96
|
-
});
|
|
97
|
-
continue;
|
|
98
|
-
}
|
|
94
|
+
(async () => {
|
|
95
|
+
let index = 0;
|
|
96
|
+
// eslint-disable-next-line lwr/no-unguarded-apis
|
|
97
|
+
const document = globalThis.document;
|
|
98
|
+
for (const [specifier, ctor] of rootModules) {
|
|
99
|
+
if (shouldYield()) {
|
|
100
|
+
// Yield to the main thread during long hydration tasks
|
|
101
|
+
// eslint-disable-next-line no-await-in-loop
|
|
102
|
+
await yieldToMainThread();
|
|
103
|
+
}
|
|
104
|
+
const specifierIndex = ++index;
|
|
105
|
+
const elementName = toKebabCase(specifier);
|
|
99
106
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
hydrateComponentProxy(element, ctor, serverData[propsId] || {});
|
|
116
|
-
}, 0);
|
|
117
|
-
} else {
|
|
118
|
-
hydrateComponentProxy(element, ctor, serverData[propsId] || {});
|
|
119
|
-
}
|
|
107
|
+
// initialize and inject the root module into the LWR Root or DOM if it is missing
|
|
108
|
+
// eslint-disable-next-line lwr/no-unguarded-apis
|
|
109
|
+
if (!document.body.querySelector(elementName)) {
|
|
110
|
+
logOperationStart({
|
|
111
|
+
id: INIT_MODULE,
|
|
112
|
+
specifier,
|
|
113
|
+
specifierIndex
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
// this is for SPA like routes (one component at the root level) utilizing the lwr-root directive
|
|
117
|
+
const component = initializeWebComponent(elementName, ctor);
|
|
118
|
+
// eslint-disable-next-line lwr/no-unguarded-apis
|
|
119
|
+
const container = document.querySelector('[lwr-root]');
|
|
120
|
+
// eslint-disable-next-line lwr/no-unguarded-apis
|
|
121
|
+
container ? container.appendChild(component) : document.body.appendChild(component);
|
|
120
122
|
logOperationEnd({
|
|
121
123
|
id: INIT_MODULE,
|
|
122
124
|
specifier,
|
|
123
|
-
specifierIndex
|
|
125
|
+
specifierIndex,
|
|
124
126
|
metadata: {
|
|
125
|
-
renderMode: '
|
|
127
|
+
renderMode: 'spa'
|
|
126
128
|
}
|
|
127
129
|
});
|
|
128
130
|
continue;
|
|
129
131
|
}
|
|
130
132
|
|
|
131
|
-
//
|
|
132
|
-
//
|
|
133
|
-
|
|
134
|
-
const
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
if (
|
|
144
|
-
|
|
145
|
-
|
|
133
|
+
// the page has been rendered or SSR'd, and each component needs to initialized(or hydrated)
|
|
134
|
+
// eslint-disable-next-line lwr/no-unguarded-apis
|
|
135
|
+
const elements = document.querySelectorAll(elementName);
|
|
136
|
+
for (const element of elements) {
|
|
137
|
+
logOperationStart({
|
|
138
|
+
id: INIT_MODULE,
|
|
139
|
+
specifier,
|
|
140
|
+
specifierIndex
|
|
141
|
+
});
|
|
142
|
+
const propsId = element.dataset.lwrPropsId;
|
|
143
|
+
|
|
144
|
+
// hydrate SSR'd components
|
|
145
|
+
if (propsId) {
|
|
146
|
+
hydrateComponentProxy(element, ctor, serverData[propsId] || {});
|
|
147
|
+
logOperationEnd({
|
|
148
|
+
id: INIT_MODULE,
|
|
149
|
+
specifier,
|
|
150
|
+
specifierIndex,
|
|
151
|
+
metadata: {
|
|
152
|
+
renderMode: 'ssr'
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
continue;
|
|
146
156
|
}
|
|
147
|
-
}
|
|
148
157
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
component.
|
|
152
|
-
|
|
158
|
+
// Note: due to the bug described at the top of this file, each CSR'd custom element
|
|
159
|
+
// must be replaced with the new synthetic constructor. Attributes and children are
|
|
160
|
+
// copied over to the new component.
|
|
161
|
+
const component = initializeWebComponent(elementName, ctor);
|
|
153
162
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
163
|
+
// copy the attributes
|
|
164
|
+
for (const {
|
|
165
|
+
name,
|
|
166
|
+
value
|
|
167
|
+
} of element.attributes) {
|
|
168
|
+
component.setAttribute(name, value);
|
|
169
|
+
const prop = getPropFromAttrName(name);
|
|
170
|
+
if (prop in component) {
|
|
171
|
+
// set attributes as properties for reactivity
|
|
172
|
+
component[prop] = value;
|
|
173
|
+
}
|
|
165
174
|
}
|
|
166
|
-
|
|
175
|
+
|
|
176
|
+
// save the children
|
|
177
|
+
while (element.childNodes.length > 0) {
|
|
178
|
+
component.appendChild(element.childNodes[0]);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// swap the element out with the initialized component
|
|
182
|
+
const parent = element.parentElement;
|
|
183
|
+
if (parent) {
|
|
184
|
+
parent.replaceChild(component, element);
|
|
185
|
+
}
|
|
186
|
+
logOperationEnd({
|
|
187
|
+
id: INIT_MODULE,
|
|
188
|
+
specifier,
|
|
189
|
+
specifierIndex,
|
|
190
|
+
metadata: {
|
|
191
|
+
renderMode: 'csr'
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
}
|
|
167
195
|
}
|
|
168
|
-
}
|
|
196
|
+
})();
|
|
169
197
|
logOperationEnd({
|
|
170
198
|
id: INIT
|
|
171
199
|
});
|
|
172
200
|
logOperationStart({
|
|
173
201
|
id: BOOTSTRAP_END
|
|
174
202
|
});
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// Allows the browser to yield to the main thread during long-running tasks, improving responsiveness.
|
|
206
|
+
async function yieldToMainThread() {
|
|
207
|
+
const scheduler = globalThis.scheduler;
|
|
208
|
+
// eslint-disable-next-line lwr/no-unguarded-apis
|
|
209
|
+
return scheduler?.yield ? scheduler.yield() : new Promise(resolve => setTimeout(resolve, 0));
|
|
175
210
|
}
|