@lwrjs/client-modules 0.17.2-alpha.9 → 0.18.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.
@@ -1,2 +1,2 @@
1
- const e=[];let o;const n=globalThis.LWR;n.define||n.env?globalThis.LWR=Object.freeze({define:n.define,env:n.env}):delete globalThis.LWR;const t={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({data:o})=>{const n=JSON.parse(o);if("moduleUpdate"===n.eventType){const{oldHash:o,newHash:t,module:{specifier:a}}=n.payload;for(let n=0;n<e.length;n++){if(null!==(0,e[n])({name:a,oldHash:o,newHash:t}))break}}})))},appMetadata:function(){const{appId:e,bootstrapModule:o,rootComponent:t,rootComponents:a}=n;return{appId:e,bootstrapModule:o,rootComponent:t,rootComponents:a}}(),addServerDataCallback:function(e){}};export{t as services};
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
@@ -12,19 +12,21 @@ function hydrateComponentProxy(customElement, Ctor, props) {
12
12
  }
13
13
  // </hydrateComponentProxy>
14
14
  const shouldYield = (() => {
15
+ const globalThisLWR = globalThis;
16
+ const { SSREnabled } = (globalThisLWR.LWR && globalThisLWR.LWR.env) || {};
15
17
  // eslint-disable-next-line lwr/no-unguarded-apis
16
- if (!globalThis.performance) {
18
+ if (!globalThis.performance || !SSREnabled) {
17
19
  return () => false;
18
20
  }
19
21
  // Break up hydration tasks into timed batches.
20
22
  // Borrowed from https://tinyurl.com/5b4fw7eb
21
- const HYDRATION_TASK_BATCH_DURATION = 50;
23
+ const TASK_BATCH_DURATION = 50;
22
24
  // eslint-disable-next-line lwr/no-unguarded-apis
23
25
  let timeOfLastYield = globalThis.performance.now();
24
26
  return () => {
25
27
  // eslint-disable-next-line lwr/no-unguarded-apis
26
28
  const now = globalThis.performance.now();
27
- if (now - timeOfLastYield > HYDRATION_TASK_BATCH_DURATION) {
29
+ if (now - timeOfLastYield > TASK_BATCH_DURATION) {
28
30
  timeOfLastYield = now;
29
31
  return true;
30
32
  }
@@ -72,49 +74,49 @@ export function init(rootModules, serverData = {}) {
72
74
  return;
73
75
  }
74
76
  logOperationStart({ id: INIT });
75
- let index = 0;
76
- // eslint-disable-next-line lwr/no-unguarded-apis
77
- const document = globalThis.document;
78
- for (const [specifier, ctor] of rootModules) {
79
- const elementName = toKebabCase(specifier);
80
- // initialize and inject the root module into the LWR Root or DOM if it is missing
77
+ (async () => {
78
+ let index = 0;
81
79
  // eslint-disable-next-line lwr/no-unguarded-apis
82
- if (!document.body.querySelector(elementName)) {
83
- logOperationStart({ id: INIT_MODULE, specifier, specifierIndex: ++index });
84
- // this is for SPA like routes (one component at the root level) utilizing the lwr-root directive
85
- const component = initializeWebComponent(elementName, ctor);
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
86
90
  // eslint-disable-next-line lwr/no-unguarded-apis
87
- const container = document.querySelector('[lwr-root]');
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);
99
+ logOperationEnd({
100
+ id: INIT_MODULE,
101
+ specifier,
102
+ specifierIndex,
103
+ metadata: { renderMode: 'spa' },
104
+ });
105
+ continue;
106
+ }
107
+ // the page has been rendered or SSR'd, and each component needs to initialized(or hydrated)
88
108
  // eslint-disable-next-line lwr/no-unguarded-apis
89
- container ? container.appendChild(component) : document.body.appendChild(component);
90
- logOperationEnd({
91
- id: INIT_MODULE,
92
- specifier,
93
- specifierIndex: index,
94
- metadata: { renderMode: 'spa' },
95
- });
96
- continue;
97
- }
98
- // the page has been rendered or SSR'd, and each component needs to initialized(or hydrated)
99
- // eslint-disable-next-line lwr/no-unguarded-apis
100
- const elements = document.querySelectorAll(elementName);
101
- (async () => {
102
- const specifierIndex = ++index;
109
+ const elements = document.querySelectorAll(elementName);
103
110
  for (const element of elements) {
104
111
  logOperationStart({ id: INIT_MODULE, specifier, specifierIndex });
105
112
  const propsId = element.dataset.lwrPropsId;
106
113
  // hydrate SSR'd components
107
114
  if (propsId) {
108
- if (shouldYield()) {
109
- // Yield to the main thread during long hydration tasks
110
- // eslint-disable-next-line no-await-in-loop
111
- await yieldToMainThread();
112
- }
113
115
  hydrateComponentProxy(element, ctor, serverData[propsId] || {});
114
116
  logOperationEnd({
115
117
  id: INIT_MODULE,
116
118
  specifier,
117
- specifierIndex: index,
119
+ specifierIndex,
118
120
  metadata: { renderMode: 'ssr' },
119
121
  });
120
122
  continue;
@@ -133,11 +135,14 @@ export function init(rootModules, serverData = {}) {
133
135
  }
134
136
  }
135
137
  // save the children
136
- while (element.firstChild) {
137
- component.appendChild(element.firstChild);
138
+ while (element.childNodes.length > 0) {
139
+ component.appendChild(element.childNodes[0]);
138
140
  }
139
141
  // swap the element out with the initialized component
140
- element.replaceWith(component);
142
+ const parent = element.parentElement;
143
+ if (parent) {
144
+ parent.replaceChild(component, element);
145
+ }
141
146
  logOperationEnd({
142
147
  id: INIT_MODULE,
143
148
  specifier,
@@ -145,8 +150,8 @@ export function init(rootModules, serverData = {}) {
145
150
  metadata: { renderMode: 'csr' },
146
151
  });
147
152
  }
148
- })();
149
- }
153
+ }
154
+ })();
150
155
  logOperationEnd({ id: INIT });
151
156
  logOperationStart({ id: BOOTSTRAP_END });
152
157
  }
@@ -35,7 +35,7 @@ function getDetail(specifier, metadata) {
35
35
  // Fallback to the Performance API if there is no custom dispatcher
36
36
  export function logOperationStart({ id, specifier, specifierIndex, metadata }) {
37
37
  if (customDispatcher) {
38
- customDispatcher({ id, phase: Phase.Start, specifier, metadata });
38
+ customDispatcher({ id, phase: Phase.Start, specifier, metadata, specifierIndex });
39
39
  return;
40
40
  }
41
41
  if (isPerfSupported) {
@@ -49,7 +49,7 @@ export function logOperationStart({ id, specifier, specifierIndex, metadata }) {
49
49
  /* istanbul ignore next */
50
50
  export function logOperationEnd({ id, specifier, specifierIndex, metadata }) {
51
51
  if (customDispatcher) {
52
- customDispatcher({ id, phase: Phase.End, specifier, metadata });
52
+ customDispatcher({ id, phase: Phase.End, specifier, metadata, specifierIndex });
53
53
  }
54
54
  else if (isPerfSupported) {
55
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
 
@@ -19,20 +19,25 @@ function hydrateComponentProxy(customElement, Ctor, props) {
19
19
  // </hydrateComponentProxy>
20
20
 
21
21
  const shouldYield = (() => {
22
+ const globalThisLWR = globalThis;
23
+ const {
24
+ SSREnabled
25
+ } = globalThisLWR.LWR && globalThisLWR.LWR.env || {};
26
+
22
27
  // eslint-disable-next-line lwr/no-unguarded-apis
23
- if (!globalThis.performance) {
28
+ if (!globalThis.performance || !SSREnabled) {
24
29
  return () => false;
25
30
  }
26
31
 
27
32
  // Break up hydration tasks into timed batches.
28
33
  // Borrowed from https://tinyurl.com/5b4fw7eb
29
- const HYDRATION_TASK_BATCH_DURATION = 50;
34
+ const TASK_BATCH_DURATION = 50;
30
35
  // eslint-disable-next-line lwr/no-unguarded-apis
31
36
  let timeOfLastYield = globalThis.performance.now();
32
37
  return () => {
33
38
  // eslint-disable-next-line lwr/no-unguarded-apis
34
39
  const now = globalThis.performance.now();
35
- if (now - timeOfLastYield > HYDRATION_TASK_BATCH_DURATION) {
40
+ if (now - timeOfLastYield > TASK_BATCH_DURATION) {
36
41
  timeOfLastYield = now;
37
42
  return true;
38
43
  }
@@ -86,43 +91,48 @@ export function init(rootModules, serverData = {}) {
86
91
  logOperationStart({
87
92
  id: INIT
88
93
  });
89
- let index = 0;
90
- // eslint-disable-next-line lwr/no-unguarded-apis
91
- const document = globalThis.document;
92
- for (const [specifier, ctor] of rootModules) {
93
- const elementName = toKebabCase(specifier);
94
-
95
- // initialize and inject the root module into the LWR Root or DOM if it is missing
94
+ (async () => {
95
+ let index = 0;
96
96
  // eslint-disable-next-line lwr/no-unguarded-apis
97
- if (!document.body.querySelector(elementName)) {
98
- logOperationStart({
99
- id: INIT_MODULE,
100
- specifier,
101
- specifierIndex: ++index
102
- });
103
-
104
- // this is for SPA like routes (one component at the root level) utilizing the lwr-root directive
105
- const component = initializeWebComponent(elementName, ctor);
106
- // eslint-disable-next-line lwr/no-unguarded-apis
107
- const container = document.querySelector('[lwr-root]');
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);
106
+
107
+ // initialize and inject the root module into the LWR Root or DOM if it is missing
108
108
  // eslint-disable-next-line lwr/no-unguarded-apis
109
- container ? container.appendChild(component) : document.body.appendChild(component);
110
- logOperationEnd({
111
- id: INIT_MODULE,
112
- specifier,
113
- specifierIndex: index,
114
- metadata: {
115
- renderMode: 'spa'
116
- }
117
- });
118
- continue;
119
- }
109
+ if (!document.body.querySelector(elementName)) {
110
+ logOperationStart({
111
+ id: INIT_MODULE,
112
+ specifier,
113
+ specifierIndex
114
+ });
120
115
 
121
- // the page has been rendered or SSR'd, and each component needs to initialized(or hydrated)
122
- // eslint-disable-next-line lwr/no-unguarded-apis
123
- const elements = document.querySelectorAll(elementName);
124
- (async () => {
125
- const specifierIndex = ++index;
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);
122
+ logOperationEnd({
123
+ id: INIT_MODULE,
124
+ specifier,
125
+ specifierIndex,
126
+ metadata: {
127
+ renderMode: 'spa'
128
+ }
129
+ });
130
+ continue;
131
+ }
132
+
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);
126
136
  for (const element of elements) {
127
137
  logOperationStart({
128
138
  id: INIT_MODULE,
@@ -133,16 +143,11 @@ export function init(rootModules, serverData = {}) {
133
143
 
134
144
  // hydrate SSR'd components
135
145
  if (propsId) {
136
- if (shouldYield()) {
137
- // Yield to the main thread during long hydration tasks
138
- // eslint-disable-next-line no-await-in-loop
139
- await yieldToMainThread();
140
- }
141
146
  hydrateComponentProxy(element, ctor, serverData[propsId] || {});
142
147
  logOperationEnd({
143
148
  id: INIT_MODULE,
144
149
  specifier,
145
- specifierIndex: index,
150
+ specifierIndex,
146
151
  metadata: {
147
152
  renderMode: 'ssr'
148
153
  }
@@ -169,12 +174,15 @@ export function init(rootModules, serverData = {}) {
169
174
  }
170
175
 
171
176
  // save the children
172
- while (element.firstChild) {
173
- component.appendChild(element.firstChild);
177
+ while (element.childNodes.length > 0) {
178
+ component.appendChild(element.childNodes[0]);
174
179
  }
175
180
 
176
181
  // swap the element out with the initialized component
177
- element.replaceWith(component);
182
+ const parent = element.parentElement;
183
+ if (parent) {
184
+ parent.replaceChild(component, element);
185
+ }
178
186
  logOperationEnd({
179
187
  id: INIT_MODULE,
180
188
  specifier,
@@ -184,8 +192,8 @@ export function init(rootModules, serverData = {}) {
184
192
  }
185
193
  });
186
194
  }
187
- })();
188
- }
195
+ }
196
+ })();
189
197
  logOperationEnd({
190
198
  id: INIT
191
199
  });