Skip to content

Commit 8c375bd

Browse files
authored
fix(runtime): prevent watchers from prematurely firing in custom elements build (#2971)
- wait for a component to be defined in the CustomElementsRegistry before setting the isWatchReady flag
1 parent cd7ef54 commit 8c375bd

File tree

4 files changed

+10
-5
lines changed

4 files changed

+10
-5
lines changed

package-lock.json

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/declarations/stencil-public-compiler.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -291,8 +291,8 @@ export interface ConfigExtras {
291291

292292
/**
293293
* When a component is first attached to the DOM, this setting will wait a single tick before
294-
* rendering. This worksaround an Angular issue, where Angular attaches the elements before
295-
* settings their initial state, leading to double renders and unnecesary event dispatchs.
294+
* rendering. This works around an Angular issue, where Angular attaches the elements before
295+
* settings their initial state, leading to double renders and unnecessary event dispatches.
296296
* Defaults to `false`.
297297
*/
298298
initializeNextTick?: boolean;

src/runtime/initialize-component.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export const initializeComponent = async (elm: d.HostElement, hostRef: d.HostRef
3030
throw new Error(`Constructor for "${cmpMeta.$tagName$}#${hostRef.$modeName$}" was not found`);
3131
}
3232
if (BUILD.member && !Cstr.isProxied) {
33-
// we'eve never proxied this Constructor before
33+
// we've never proxied this Constructor before
3434
// let's add the getters/setters to its prototype before
3535
// the first time we create an instance of the implementation
3636
if (BUILD.watchCallback) {
@@ -68,7 +68,11 @@ export const initializeComponent = async (elm: d.HostElement, hostRef: d.HostRef
6868
} else {
6969
// sync constructor component
7070
Cstr = elm.constructor as any;
71-
hostRef.$flags$ |= HOST_FLAGS.isWatchReady | HOST_FLAGS.hasInitializedComponent;
71+
hostRef.$flags$ |= HOST_FLAGS.hasInitializedComponent;
72+
// wait for the CustomElementRegistry to mark the component as ready before setting `isWatchReady`. Otherwise,
73+
// watchers may fire prematurely if `customElements.get()`/`customElements.whenDefined()` resolves _before_
74+
// Stencil has completed instantiating the component.
75+
customElements.whenDefined(cmpMeta.$tagName$).then(() => hostRef.$flags$ |= HOST_FLAGS.isWatchReady)
7276
}
7377

7478
if (BUILD.style && Cstr.style) {

src/runtime/runtime-constants.ts

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export const enum PROXY_FLAGS {
1010
}
1111

1212
export const enum PLATFORM_FLAGS {
13+
// designates a node in the DOM as being actively moved by the runtime
1314
isTmpDisconnected = 1 << 0,
1415
appLoaded = 1 << 1,
1516
queueSync = 1 << 2,

0 commit comments

Comments
 (0)