Skip to content

Commit

Permalink
fix(runtime): prevent watchers from prematurely firing in custom elem…
Browse files Browse the repository at this point in the history
…ents build (#2971)

- wait for a component to be defined in the CustomElementsRegistry
  before setting the isWatchReady flag
  • Loading branch information
rwaskiewicz committed Jul 21, 2021
1 parent cd7ef54 commit 8c375bd
Show file tree
Hide file tree
Showing 4 changed files with 10 additions and 5 deletions.
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions src/declarations/stencil-public-compiler.ts
Expand Up @@ -291,8 +291,8 @@ export interface ConfigExtras {

/**
* When a component is first attached to the DOM, this setting will wait a single tick before
* rendering. This worksaround an Angular issue, where Angular attaches the elements before
* settings their initial state, leading to double renders and unnecesary event dispatchs.
* rendering. This works around an Angular issue, where Angular attaches the elements before
* settings their initial state, leading to double renders and unnecessary event dispatches.
* Defaults to `false`.
*/
initializeNextTick?: boolean;
Expand Down
8 changes: 6 additions & 2 deletions src/runtime/initialize-component.ts
Expand Up @@ -30,7 +30,7 @@ export const initializeComponent = async (elm: d.HostElement, hostRef: d.HostRef
throw new Error(`Constructor for "${cmpMeta.$tagName$}#${hostRef.$modeName$}" was not found`);
}
if (BUILD.member && !Cstr.isProxied) {
// we'eve never proxied this Constructor before
// we've never proxied this Constructor before
// let's add the getters/setters to its prototype before
// the first time we create an instance of the implementation
if (BUILD.watchCallback) {
Expand Down Expand Up @@ -68,7 +68,11 @@ export const initializeComponent = async (elm: d.HostElement, hostRef: d.HostRef
} else {
// sync constructor component
Cstr = elm.constructor as any;
hostRef.$flags$ |= HOST_FLAGS.isWatchReady | HOST_FLAGS.hasInitializedComponent;
hostRef.$flags$ |= HOST_FLAGS.hasInitializedComponent;
// wait for the CustomElementRegistry to mark the component as ready before setting `isWatchReady`. Otherwise,
// watchers may fire prematurely if `customElements.get()`/`customElements.whenDefined()` resolves _before_
// Stencil has completed instantiating the component.
customElements.whenDefined(cmpMeta.$tagName$).then(() => hostRef.$flags$ |= HOST_FLAGS.isWatchReady)
}

if (BUILD.style && Cstr.style) {
Expand Down
1 change: 1 addition & 0 deletions src/runtime/runtime-constants.ts
Expand Up @@ -10,6 +10,7 @@ export const enum PROXY_FLAGS {
}

export const enum PLATFORM_FLAGS {
// designates a node in the DOM as being actively moved by the runtime
isTmpDisconnected = 1 << 0,
appLoaded = 1 << 1,
queueSync = 1 << 2,
Expand Down

0 comments on commit 8c375bd

Please sign in to comment.