From fd3371611fce862a1e7f55f9cf5ee7770d88f96f Mon Sep 17 00:00:00 2001 From: Will Harney <62956339+wjhsf@users.noreply.github.com> Date: Mon, 19 May 2025 11:46:12 -0400 Subject: [PATCH 1/7] chore: remove structuredClone workaround (#5367) we only support environments where it exists, now --- .../@lwc/template-compiler/src/codegen/codegen.ts | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/packages/@lwc/template-compiler/src/codegen/codegen.ts b/packages/@lwc/template-compiler/src/codegen/codegen.ts index 4972d47654..3cf569a883 100644 --- a/packages/@lwc/template-compiler/src/codegen/codegen.ts +++ b/packages/@lwc/template-compiler/src/codegen/codegen.ts @@ -67,13 +67,6 @@ import type { import type { APIVersion } from '@lwc/shared'; import type { Node } from 'estree'; -// structuredClone is only available in Node 17+ -// https://developer.mozilla.org/en-US/docs/Web/API/structuredClone#browser_compatibility -const doStructuredClone = - typeof structuredClone === 'function' - ? structuredClone - : (obj: any) => JSON.parse(JSON.stringify(obj)); - type RenderPrimitive = | 'iterator' | 'flatten' @@ -649,7 +642,7 @@ export default class CodeGen { if (this.state.config.experimentalComplexExpressions) { // Cloning here is necessary because `this.replace()` is destructive, and we might use the // node later during static content optimization - expression = doStructuredClone(expression); + expression = structuredClone(expression); return bindComplexExpression(expression as ComplexExpression, this); } @@ -659,7 +652,7 @@ export default class CodeGen { // Cloning here is necessary because `this.replace()` is destructive, and we might use the // node later during static content optimization - expression = doStructuredClone(expression); + expression = structuredClone(expression); // TODO [#3370]: when the template expression flag is removed, the // ComplexExpression type should be redefined as an ESTree Node. Doing // so when the flag is still in place results in a cascade of required From 0b7deac54b851e37277758f8d2f9804ea7f96b39 Mon Sep 17 00:00:00 2001 From: Will Harney <62956339+wjhsf@users.noreply.github.com> Date: Tue, 27 May 2025 10:34:18 -0400 Subject: [PATCH 2/7] fix(release): oops shell scripts are relative to cwd (#5368) * fix(release): oops shell scripts are relative to cwd * fix(release): properly handle semver release types previously, specifying "minor" via `yarn release:version minor` would use the literal string "minor" --- scripts/release/publish.sh | 2 +- scripts/release/version.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/release/publish.sh b/scripts/release/publish.sh index cf700cfae8..81a9c6a154 100755 --- a/scripts/release/publish.sh +++ b/scripts/release/publish.sh @@ -36,7 +36,7 @@ if which gh >/dev/null; then git branch -D "$BRANCH" # Wait for CI to complete - ./wait-for-pr.sh "$BRANCH" + . "$(dirname "$0")/wait-for-pr.sh" "$BRANCH" if ! gh pr checks --fail-fast --watch; then echo 'CI failed. Cannot continue with release.' gh pr view "$BRANCH" --web diff --git a/scripts/release/version.sh b/scripts/release/version.sh index d634a84e0b..b6b373999a 100755 --- a/scripts/release/version.sh +++ b/scripts/release/version.sh @@ -38,7 +38,7 @@ if which gh 2>/dev/null 1>/dev/null; then git switch "$BASE_BRANCH" git branch -D "$BRANCH" - ./wait-for-pr.sh "$BRANCH" + . "$(dirname "$0")/wait-for-pr.sh" "$BRANCH" while [ "$(gh pr view "$BRANCH" --json state -q .state)" != 'MERGED' ]; do sleep 3 # Wait for GitHub to auto-merge the PR done From 8bfb9b33ff366329cfb0d95eb1955e3f603936ef Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 27 May 2025 17:36:49 +0000 Subject: [PATCH 3/7] build(deps): bump undici from 6.21.1 to 6.21.3 (#5373) Bumps [undici](https://github.com/nodejs/undici) from 6.21.1 to 6.21.3. - [Release notes](https://github.com/nodejs/undici/releases) - [Commits](https://github.com/nodejs/undici/compare/v6.21.1...v6.21.3) --- updated-dependencies: - dependency-name: undici dependency-version: 6.21.3 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Will Harney <62956339+wjhsf@users.noreply.github.com> --- yarn.lock | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/yarn.lock b/yarn.lock index faf0b98b28..9601eea4c6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1923,11 +1923,9 @@ "@lwc/eslint-plugin-lwc-internal@link:./scripts/eslint-plugin": version "0.0.0" - uid "" "@lwc/test-utils-lwc-internals@link:./scripts/test-utils": version "0.0.0" - uid "" "@napi-rs/wasm-runtime@0.2.4": version "0.2.4" @@ -12187,9 +12185,9 @@ undici-types@~6.21.0: integrity sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ== undici@^6.19.5, undici@^6.20.1: - version "6.21.1" - resolved "https://registry.yarnpkg.com/undici/-/undici-6.21.1.tgz#336025a14162e6837e44ad7b819b35b6c6af0e05" - integrity sha512-q/1rj5D0/zayJB2FraXdaWxbhWiNKDvu8naDT2dl1yTlvJp4BLtOcp2a5BvgGNQpYYJzau7tf1WgKv3b+7mqpQ== + version "6.21.3" + resolved "https://registry.yarnpkg.com/undici/-/undici-6.21.3.tgz#185752ad92c3d0efe7a7d1f6854a50f83b552d7a" + integrity sha512-gBLkYIlEnSp8pFbT64yFgGE6UIB9tAkhukC23PmMDCe5Nd+cRqKxSjw5y54MK2AZMgZfJWMaNE4nYUHgi1XEOw== unicode-canonical-property-names-ecmascript@^2.0.0: version "2.0.1" From c26681609f016f17358f51cbbd846e3494e0fcc7 Mon Sep 17 00:00:00 2001 From: Eugene Kashida Date: Tue, 27 May 2025 17:29:59 -0700 Subject: [PATCH 4/7] test(engine-server): update global attributes spec (#5378) --- .../undeclared/expected.html | 45 ------------------ .../undeclared/modules/x/child/child.html | 17 +------ .../modules/x/component/component.html | 14 ------ .../as-component-prop/with-@api/expected.html | 47 +------------------ .../with-@api/modules/x/child/child.html | 17 +------ .../with-@api/modules/x/child/child.js | 2 +- .../modules/x/component/component.html | 14 ------ .../without-@api-values/expected-ssr.html | 45 ------------------ .../without-@api-values/expected.html | 45 ------------------ .../modules/x/child/child.html | 17 +------ .../modules/x/child/child.js | 2 +- .../modules/x/component/component.html | 14 ------ .../without-@api/expected-ssr.html | 45 ------------------ .../without-@api/expected.html | 45 ------------------ .../without-@api/modules/x/child/child.html | 17 +------ .../without-@api/modules/x/child/child.js | 16 +------ .../modules/x/component/component.html | 14 ------ 17 files changed, 8 insertions(+), 408 deletions(-) diff --git a/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/undeclared/expected.html b/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/undeclared/expected.html index b942d89b02..b77b609cee 100644 --- a/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/undeclared/expected.html +++ b/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/undeclared/expected.html @@ -140,9 +140,6 @@ ariaValueText: foo - - audio: - autocapitalize: @@ -155,21 +152,12 @@ bgColor: - - bgsound: - - - button: - checked: colSpan: - - command: - contentEditable: @@ -179,9 +167,6 @@ datetime: - - details: - dir: foo @@ -194,9 +179,6 @@ exportparts: - - fieldset: - form: @@ -212,9 +194,6 @@ id: foo - - input: - inputmode: @@ -236,18 +215,12 @@ itemtype: - - keygen: - lang: foo loop: - - marquee: - maxLength: @@ -266,18 +239,9 @@ noValidate: - - ol: - open: - - optgroup: - - - option: - readOnly: @@ -293,15 +257,9 @@ rowSpan: - - select: - selected: - - textarea: - title: foo @@ -311,9 +269,6 @@ useMap: - - video: - diff --git a/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/undeclared/modules/x/child/child.html b/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/undeclared/modules/x/child/child.html index 1003ca8148..403c2d918a 100644 --- a/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/undeclared/modules/x/child/child.html +++ b/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/undeclared/modules/x/child/child.html @@ -45,62 +45,47 @@ ariaValueMin: {ariaValueMin} ariaValueNow: {ariaValueNow} ariaValueText: {ariaValueText} - audio: {audio} autocapitalize: {autocapitalize} autofocus: {autofocus} autoplay: {autoplay} bgColor: {bgColor} - bgsound: {bgsound} - button: {button} checked: {checked} colSpan: {colSpan} - command: {command} contentEditable: {contentEditable} crossorigin: {crossorigin} datetime: {datetime} - details: {details} dir: {dir} disabled: {disabled} enterkeyhint: {enterkeyhint} exportparts: {exportparts} - fieldset: {fieldset} form: {form} formaction: {formaction} formnovalidate: {formnovalidate} hidden: {hidden} id: {id} - input: {input} - inputmode: {inputmode} + inputmode: {inputMode} ismap: {ismap} itemid: {itemid} itemprop: {itemprop} itemref: {itemref} itemscope: {itemscope} itemtype: {itemtype} - keygen: {keygen} lang: {lang} loop: {loop} - marquee: {marquee} maxLength: {maxLength} minLength: {minLength} multiple: {multiple} muted: {muted} nonce: {nonce} noValidate: {noValidate} - ol: {ol} open: {open} - optgroup: {optgroup} - option: {option} readOnly: {readOnly} required: {required} reversed: {reversed} role: {role} rowSpan: {rowSpan} - select: {select} selected: {selected} - textarea: {textarea} title: {title} translate: {translate} useMap: {useMap} - video: {video} \ No newline at end of file diff --git a/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/undeclared/modules/x/component/component.html b/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/undeclared/modules/x/component/component.html index c58c67cd3f..e9017fd7b4 100644 --- a/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/undeclared/modules/x/component/component.html +++ b/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/undeclared/modules/x/component/component.html @@ -58,25 +58,19 @@ autofocus={dynamic} autoplay={dynamic} bgcolor={dynamic} - bgsound={dynamic} - button={dynamic} checked={dynamic} colspan={dynamic} - command={dynamic} contenteditable={dynamic} crossorigin={dynamic} datetime={dynamic} - details={dynamic} dir={dynamic} disabled={dynamic} enterkeyhint={dynamic} exportparts={dynamic} - fieldset={dynamic} form={dynamic} formaction={dynamic} formnovalidate={dynamic} id={dynamic} - input={dynamic} inputmode={dynamic} ismap={dynamic} itemid={dynamic} @@ -84,31 +78,23 @@ itemref={dynamic} itemscope={dynamic} itemtype={dynamic} - keygen={dynamic} lang={dynamic} loop={dynamic} - marquee={dynamic} maxlength={dynamic} minlength={dynamic} multiple={dynamic} muted={dynamic} nonce={dynamic} novalidate={dynamic} - ol={dynamic} open={dynamic} - optgroup={dynamic} - option={dynamic} readonly={dynamic} required={dynamic} reversed={dynamic} role={dynamic} rowspan={dynamic} - select={dynamic} selected={dynamic} - textarea={dynamic} title={dynamic} translate={dynamic} usemap={dynamic} - video={dynamic} > \ No newline at end of file diff --git a/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/with-@api/expected.html b/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/with-@api/expected.html index eae746749d..4d6986bbac 100644 --- a/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/with-@api/expected.html +++ b/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/with-@api/expected.html @@ -143,9 +143,6 @@ ariaValueText: foo - - audio: - autocapitalize: foo @@ -158,21 +155,12 @@ bgColor: foo - - bgsound: foo - - - button: foo - checked: foo colSpan: foo - - command: foo - contentEditable: foo @@ -182,9 +170,6 @@ datetime: - - details: foo - dir: foo @@ -200,9 +185,6 @@ exportparts: - - fieldset: foo - form: foo @@ -219,10 +201,7 @@ id: foo - input: foo - - - inputmode: foo + inputmode: ismap: @@ -242,18 +221,12 @@ itemtype: foo - - keygen: foo - lang: foo loop: foo - - marquee: foo - maxLength: foo @@ -272,18 +245,9 @@ noValidate: foo - - ol: foo - open: foo - - optgroup: foo - - - option: foo - readOnly: foo @@ -299,9 +263,6 @@ rowSpan: foo - - select: foo - selected: foo @@ -311,9 +272,6 @@ tabIndex: foo - - textarea: foo - title: foo @@ -323,9 +281,6 @@ useMap: foo - - video: foo - diff --git a/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/with-@api/modules/x/child/child.html b/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/with-@api/modules/x/child/child.html index a254534229..f7157e9818 100644 --- a/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/with-@api/modules/x/child/child.html +++ b/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/with-@api/modules/x/child/child.html @@ -46,65 +46,50 @@ ariaValueMin: {ariaValueMin} ariaValueNow: {ariaValueNow} ariaValueText: {ariaValueText} - audio: {audio} autocapitalize: {autocapitalize} autofocus: {autofocus} autoplay: {autoplay} bgColor: {bgColor} - bgsound: {bgsound} - button: {button} checked: {checked} colSpan: {colSpan} - command: {command} contentEditable: {contentEditable} crossorigin: {crossorigin} datetime: {datetime} - details: {details} dir: {dir} disabled: {disabled} draggable: {draggable} enterkeyhint: {enterkeyhint} exportparts: {exportparts} - fieldset: {fieldset} form: {form} formaction: {formaction} formnovalidate: {formnovalidate} hidden: {hidden} id: {id} - input: {input} - inputmode: {inputmode} + inputmode: {inputMode} ismap: {ismap} itemid: {itemid} itemprop: {itemprop} itemref: {itemref} itemscope: {itemscope} itemtype: {itemtype} - keygen: {keygen} lang: {lang} loop: {loop} - marquee: {marquee} maxLength: {maxLength} minLength: {minLength} multiple: {multiple} muted: {muted} nonce: {nonce} noValidate: {noValidate} - ol: {ol} open: {open} - optgroup: {optgroup} - option: {option} readOnly: {readOnly} required: {required} reversed: {reversed} role: {role} rowSpan: {rowSpan} - select: {select} selected: {selected} spellcheck: {spellcheck} tabIndex: {tabIndex} - textarea: {textarea} title: {title} translate: {translate} useMap: {useMap} - video: {video} diff --git a/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/with-@api/modules/x/child/child.js b/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/with-@api/modules/x/child/child.js index 0c20aee0e7..6518230562 100644 --- a/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/with-@api/modules/x/child/child.js +++ b/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/with-@api/modules/x/child/child.js @@ -74,7 +74,7 @@ export default class extends LightningElement { @api hidden; @api id; @api input; - @api inputmode; + @api inputMode; @api ismap; @api itemid; @api itemprop; diff --git a/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/with-@api/modules/x/component/component.html b/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/with-@api/modules/x/component/component.html index 45db140bcf..285f559f9f 100644 --- a/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/with-@api/modules/x/component/component.html +++ b/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/with-@api/modules/x/component/component.html @@ -51,27 +51,21 @@ autofocus={dynamic} autoplay={dynamic} bgcolor={dynamic} - bgsound={dynamic} - button={dynamic} checked={dynamic} colspan={dynamic} - command={dynamic} contenteditable={dynamic} crossorigin={dynamic} datetime={dynamic} - details={dynamic} dir={dynamic} disabled={dynamic} draggable={dynamic} enterkeyhint={dynamic} exportparts={dynamic} - fieldset={dynamic} form={dynamic} formaction={dynamic} formnovalidate={dynamic} hidden={dynamic} id={dynamic} - input={dynamic} inputmode={dynamic} ismap={dynamic} itemid={dynamic} @@ -79,33 +73,25 @@ itemref={dynamic} itemscope={dynamic} itemtype={dynamic} - keygen={dynamic} lang={dynamic} loop={dynamic} - marquee={dynamic} maxlength={dynamic} minlength={dynamic} multiple={dynamic} muted={dynamic} nonce={dynamic} novalidate={dynamic} - ol={dynamic} open={dynamic} - optgroup={dynamic} - option={dynamic} readonly={dynamic} required={dynamic} reversed={dynamic} role={dynamic} rowspan={dynamic} - select={dynamic} selected={dynamic} spellcheck={dynamic} tabindex={dynamic} - textarea={dynamic} title={dynamic} translate={dynamic} usemap={dynamic} - video={dynamic} > diff --git a/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/without-@api-values/expected-ssr.html b/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/without-@api-values/expected-ssr.html index e5817cd428..917860bb59 100644 --- a/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/without-@api-values/expected-ssr.html +++ b/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/without-@api-values/expected-ssr.html @@ -143,9 +143,6 @@ ariaValueText: parent-value - - audio: child-value - autocapitalize: child-value @@ -158,21 +155,12 @@ bgColor: child-value - - bgsound: child-value - - - button: child-value - checked: child-value colSpan: child-value - - command: child-value - contentEditable: child-value @@ -182,9 +170,6 @@ datetime: child-value - - details: child-value - dir: parent-value @@ -200,9 +185,6 @@ exportparts: child-value - - fieldset: child-value - form: child-value @@ -218,9 +200,6 @@ id: parent-value - - input: child-value - inputmode: child-value @@ -242,18 +221,12 @@ itemtype: child-value - - keygen: child-value - lang: parent-value loop: child-value - - marquee: child-value - maxLength: child-value @@ -272,18 +245,9 @@ noValidate: child-value - - ol: child-value - open: child-value - - optgroup: child-value - - - option: child-value - readOnly: child-value @@ -299,9 +263,6 @@ rowSpan: child-value - - select: child-value - selected: child-value @@ -311,9 +272,6 @@ tabIndex: parent-value - - textarea: child-value - title: parent-value @@ -323,9 +281,6 @@ useMap: child-value - - video: child-value - diff --git a/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/without-@api-values/expected.html b/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/without-@api-values/expected.html index 9102a5ab2f..15f2c3650a 100644 --- a/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/without-@api-values/expected.html +++ b/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/without-@api-values/expected.html @@ -143,9 +143,6 @@ ariaValueText: child-value - - audio: child-value - autocapitalize: child-value @@ -158,21 +155,12 @@ bgColor: child-value - - bgsound: child-value - - - button: child-value - checked: child-value colSpan: child-value - - command: child-value - contentEditable: child-value @@ -182,9 +170,6 @@ datetime: child-value - - details: child-value - dir: child-value @@ -200,9 +185,6 @@ exportparts: child-value - - fieldset: child-value - form: child-value @@ -218,9 +200,6 @@ id: child-value - - input: child-value - inputmode: child-value @@ -242,18 +221,12 @@ itemtype: child-value - - keygen: child-value - lang: child-value loop: child-value - - marquee: child-value - maxLength: child-value @@ -272,18 +245,9 @@ noValidate: child-value - - ol: child-value - open: child-value - - optgroup: child-value - - - option: child-value - readOnly: child-value @@ -299,9 +263,6 @@ rowSpan: child-value - - select: child-value - selected: child-value @@ -311,9 +272,6 @@ tabIndex: child-value - - textarea: child-value - title: child-value @@ -323,9 +281,6 @@ useMap: child-value - - video: child-value - diff --git a/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/without-@api-values/modules/x/child/child.html b/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/without-@api-values/modules/x/child/child.html index a254534229..f7157e9818 100644 --- a/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/without-@api-values/modules/x/child/child.html +++ b/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/without-@api-values/modules/x/child/child.html @@ -46,65 +46,50 @@ ariaValueMin: {ariaValueMin} ariaValueNow: {ariaValueNow} ariaValueText: {ariaValueText} - audio: {audio} autocapitalize: {autocapitalize} autofocus: {autofocus} autoplay: {autoplay} bgColor: {bgColor} - bgsound: {bgsound} - button: {button} checked: {checked} colSpan: {colSpan} - command: {command} contentEditable: {contentEditable} crossorigin: {crossorigin} datetime: {datetime} - details: {details} dir: {dir} disabled: {disabled} draggable: {draggable} enterkeyhint: {enterkeyhint} exportparts: {exportparts} - fieldset: {fieldset} form: {form} formaction: {formaction} formnovalidate: {formnovalidate} hidden: {hidden} id: {id} - input: {input} - inputmode: {inputmode} + inputmode: {inputMode} ismap: {ismap} itemid: {itemid} itemprop: {itemprop} itemref: {itemref} itemscope: {itemscope} itemtype: {itemtype} - keygen: {keygen} lang: {lang} loop: {loop} - marquee: {marquee} maxLength: {maxLength} minLength: {minLength} multiple: {multiple} muted: {muted} nonce: {nonce} noValidate: {noValidate} - ol: {ol} open: {open} - optgroup: {optgroup} - option: {option} readOnly: {readOnly} required: {required} reversed: {reversed} role: {role} rowSpan: {rowSpan} - select: {select} selected: {selected} spellcheck: {spellcheck} tabIndex: {tabIndex} - textarea: {textarea} title: {title} translate: {translate} useMap: {useMap} - video: {video} diff --git a/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/without-@api-values/modules/x/child/child.js b/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/without-@api-values/modules/x/child/child.js index 0a2fdb7444..82e7858fcf 100644 --- a/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/without-@api-values/modules/x/child/child.js +++ b/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/without-@api-values/modules/x/child/child.js @@ -74,7 +74,7 @@ export default class extends LightningElement { hidden = 'child-value'; id = 'child-value'; input = 'child-value'; - inputmode = 'child-value'; + inputMode = 'child-value'; ismap = 'child-value'; itemid = 'child-value'; itemprop = 'child-value'; diff --git a/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/without-@api-values/modules/x/component/component.html b/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/without-@api-values/modules/x/component/component.html index 45db140bcf..285f559f9f 100644 --- a/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/without-@api-values/modules/x/component/component.html +++ b/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/without-@api-values/modules/x/component/component.html @@ -51,27 +51,21 @@ autofocus={dynamic} autoplay={dynamic} bgcolor={dynamic} - bgsound={dynamic} - button={dynamic} checked={dynamic} colspan={dynamic} - command={dynamic} contenteditable={dynamic} crossorigin={dynamic} datetime={dynamic} - details={dynamic} dir={dynamic} disabled={dynamic} draggable={dynamic} enterkeyhint={dynamic} exportparts={dynamic} - fieldset={dynamic} form={dynamic} formaction={dynamic} formnovalidate={dynamic} hidden={dynamic} id={dynamic} - input={dynamic} inputmode={dynamic} ismap={dynamic} itemid={dynamic} @@ -79,33 +73,25 @@ itemref={dynamic} itemscope={dynamic} itemtype={dynamic} - keygen={dynamic} lang={dynamic} loop={dynamic} - marquee={dynamic} maxlength={dynamic} minlength={dynamic} multiple={dynamic} muted={dynamic} nonce={dynamic} novalidate={dynamic} - ol={dynamic} open={dynamic} - optgroup={dynamic} - option={dynamic} readonly={dynamic} required={dynamic} reversed={dynamic} role={dynamic} rowspan={dynamic} - select={dynamic} selected={dynamic} spellcheck={dynamic} tabindex={dynamic} - textarea={dynamic} title={dynamic} translate={dynamic} usemap={dynamic} - video={dynamic} > diff --git a/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/without-@api/expected-ssr.html b/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/without-@api/expected-ssr.html index 18594991e9..8d89c83504 100644 --- a/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/without-@api/expected-ssr.html +++ b/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/without-@api/expected-ssr.html @@ -143,9 +143,6 @@ ariaValueText: foo - - audio: - autocapitalize: @@ -158,21 +155,12 @@ bgColor: - - bgsound: - - - button: - checked: colSpan: - - command: - contentEditable: @@ -182,9 +170,6 @@ datetime: - - details: - dir: foo @@ -200,9 +185,6 @@ exportparts: - - fieldset: - form: @@ -218,9 +200,6 @@ id: foo - - input: - inputmode: @@ -242,18 +221,12 @@ itemtype: - - keygen: - lang: foo loop: - - marquee: - maxLength: @@ -272,18 +245,9 @@ noValidate: - - ol: - open: - - optgroup: - - - option: - readOnly: @@ -299,9 +263,6 @@ rowSpan: - - select: - selected: @@ -311,9 +272,6 @@ tabIndex: foo - - textarea: - title: foo @@ -323,9 +281,6 @@ useMap: - - video: - diff --git a/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/without-@api/expected.html b/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/without-@api/expected.html index 03c3222a10..4dac8178a8 100644 --- a/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/without-@api/expected.html +++ b/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/without-@api/expected.html @@ -143,9 +143,6 @@ ariaValueText: - - audio: - autocapitalize: @@ -158,21 +155,12 @@ bgColor: - - bgsound: - - - button: - checked: colSpan: - - command: - contentEditable: @@ -182,9 +170,6 @@ datetime: - - details: - dir: @@ -200,9 +185,6 @@ exportparts: - - fieldset: - form: @@ -218,9 +200,6 @@ id: - - input: - inputmode: @@ -242,18 +221,12 @@ itemtype: - - keygen: - lang: loop: - - marquee: - maxLength: @@ -272,18 +245,9 @@ noValidate: - - ol: - open: - - optgroup: - - - option: - readOnly: @@ -299,9 +263,6 @@ rowSpan: - - select: - selected: @@ -311,9 +272,6 @@ tabIndex: - - textarea: - title: @@ -323,9 +281,6 @@ useMap: - - video: - diff --git a/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/without-@api/modules/x/child/child.html b/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/without-@api/modules/x/child/child.html index a254534229..f7157e9818 100644 --- a/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/without-@api/modules/x/child/child.html +++ b/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/without-@api/modules/x/child/child.html @@ -46,65 +46,50 @@ ariaValueMin: {ariaValueMin} ariaValueNow: {ariaValueNow} ariaValueText: {ariaValueText} - audio: {audio} autocapitalize: {autocapitalize} autofocus: {autofocus} autoplay: {autoplay} bgColor: {bgColor} - bgsound: {bgsound} - button: {button} checked: {checked} colSpan: {colSpan} - command: {command} contentEditable: {contentEditable} crossorigin: {crossorigin} datetime: {datetime} - details: {details} dir: {dir} disabled: {disabled} draggable: {draggable} enterkeyhint: {enterkeyhint} exportparts: {exportparts} - fieldset: {fieldset} form: {form} formaction: {formaction} formnovalidate: {formnovalidate} hidden: {hidden} id: {id} - input: {input} - inputmode: {inputmode} + inputmode: {inputMode} ismap: {ismap} itemid: {itemid} itemprop: {itemprop} itemref: {itemref} itemscope: {itemscope} itemtype: {itemtype} - keygen: {keygen} lang: {lang} loop: {loop} - marquee: {marquee} maxLength: {maxLength} minLength: {minLength} multiple: {multiple} muted: {muted} nonce: {nonce} noValidate: {noValidate} - ol: {ol} open: {open} - optgroup: {optgroup} - option: {option} readOnly: {readOnly} required: {required} reversed: {reversed} role: {role} rowSpan: {rowSpan} - select: {select} selected: {selected} spellcheck: {spellcheck} tabIndex: {tabIndex} - textarea: {textarea} title: {title} translate: {translate} useMap: {useMap} - video: {video} diff --git a/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/without-@api/modules/x/child/child.js b/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/without-@api/modules/x/child/child.js index bc9b789eeb..2031c035d9 100644 --- a/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/without-@api/modules/x/child/child.js +++ b/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/without-@api/modules/x/child/child.js @@ -53,60 +53,46 @@ export default class extends LightningElement { autofocus; autoplay; bgColor; - bgsound; - button; checked; colSpan; - command; contentEditable; crossorigin; datetime; - details; dir; disabled; draggable; enterkeyhint; exportparts; - fieldset; form; formaction; formnovalidate; hidden; id; - input; - inputmode; + inputMode; ismap; itemid; itemprop; itemref; itemscope; itemtype; - keygen; lang; loop; - marquee; maxLength; minLength; multiple; muted; nonce; noValidate; - ol; open; - optgroup; - option; readOnly; required; reversed; role; rowSpan; - select; selected; spellcheck; tabIndex; - textarea; title; translate; useMap; - video; } diff --git a/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/without-@api/modules/x/component/component.html b/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/without-@api/modules/x/component/component.html index 45db140bcf..285f559f9f 100644 --- a/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/without-@api/modules/x/component/component.html +++ b/packages/@lwc/engine-server/src/__tests__/fixtures/attribute-global-html/as-component-prop/without-@api/modules/x/component/component.html @@ -51,27 +51,21 @@ autofocus={dynamic} autoplay={dynamic} bgcolor={dynamic} - bgsound={dynamic} - button={dynamic} checked={dynamic} colspan={dynamic} - command={dynamic} contenteditable={dynamic} crossorigin={dynamic} datetime={dynamic} - details={dynamic} dir={dynamic} disabled={dynamic} draggable={dynamic} enterkeyhint={dynamic} exportparts={dynamic} - fieldset={dynamic} form={dynamic} formaction={dynamic} formnovalidate={dynamic} hidden={dynamic} id={dynamic} - input={dynamic} inputmode={dynamic} ismap={dynamic} itemid={dynamic} @@ -79,33 +73,25 @@ itemref={dynamic} itemscope={dynamic} itemtype={dynamic} - keygen={dynamic} lang={dynamic} loop={dynamic} - marquee={dynamic} maxlength={dynamic} minlength={dynamic} multiple={dynamic} muted={dynamic} nonce={dynamic} novalidate={dynamic} - ol={dynamic} open={dynamic} - optgroup={dynamic} - option={dynamic} readonly={dynamic} required={dynamic} reversed={dynamic} role={dynamic} rowspan={dynamic} - select={dynamic} selected={dynamic} spellcheck={dynamic} tabindex={dynamic} - textarea={dynamic} title={dynamic} translate={dynamic} usemap={dynamic} - video={dynamic} > From 1a97ed20e8cfa2c8c52d050053f115364e33928c Mon Sep 17 00:00:00 2001 From: gaurav-rk9 Date: Fri, 30 May 2025 12:06:48 +0530 Subject: [PATCH 5/7] feat(ssr): make SSR compiler recognize lwc:on directive (#5377) Make SSR compiler recognize lwc:on directive. Also adds snapshot and hydration tests to verify lwc:on used in SSR context Co-authored-by: Dale Bustad --- .../src/__tests__/fixtures.spec.ts | 1 + .../src/__tests__/fixtures/lwc-on/config.json | 3 +++ .../src/__tests__/fixtures/lwc-on/error.txt | 0 .../__tests__/fixtures/lwc-on/expected.html | 7 ++++++ .../lwc-on/modules/x/lwc-on/lwc-on.html | 3 +++ .../lwc-on/modules/x/lwc-on/lwc-on.js | 12 +++++++++ .../scripts/karma-plugins/hydration-tests.js | 1 + .../directives/lwc-on/index.spec.js | 20 +++++++++++++++ .../directives/lwc-on/x/main/main.html | 3 +++ .../directives/lwc-on/x/main/main.js | 25 +++++++++++++++++++ .../src/__tests__/fixtures.spec.ts | 1 + .../src/compile-template/index.ts | 1 + 12 files changed, 77 insertions(+) create mode 100644 packages/@lwc/engine-server/src/__tests__/fixtures/lwc-on/config.json create mode 100644 packages/@lwc/engine-server/src/__tests__/fixtures/lwc-on/error.txt create mode 100644 packages/@lwc/engine-server/src/__tests__/fixtures/lwc-on/expected.html create mode 100644 packages/@lwc/engine-server/src/__tests__/fixtures/lwc-on/modules/x/lwc-on/lwc-on.html create mode 100644 packages/@lwc/engine-server/src/__tests__/fixtures/lwc-on/modules/x/lwc-on/lwc-on.js create mode 100644 packages/@lwc/integration-karma/test-hydration/directives/lwc-on/index.spec.js create mode 100644 packages/@lwc/integration-karma/test-hydration/directives/lwc-on/x/main/main.html create mode 100644 packages/@lwc/integration-karma/test-hydration/directives/lwc-on/x/main/main.js diff --git a/packages/@lwc/engine-server/src/__tests__/fixtures.spec.ts b/packages/@lwc/engine-server/src/__tests__/fixtures.spec.ts index 30442d190d..14a05b484a 100755 --- a/packages/@lwc/engine-server/src/__tests__/fixtures.spec.ts +++ b/packages/@lwc/engine-server/src/__tests__/fixtures.spec.ts @@ -79,6 +79,7 @@ async function compileFixture({ pluginVirtual(`export { default } from "${entry}";`, input), lwcRollupPlugin({ enableDynamicComponents: true, + enableLwcOn: true, experimentalDynamicComponent: { loader: path.join(__dirname, './utils/custom-loader.js'), strictSpecifier: false, diff --git a/packages/@lwc/engine-server/src/__tests__/fixtures/lwc-on/config.json b/packages/@lwc/engine-server/src/__tests__/fixtures/lwc-on/config.json new file mode 100644 index 0000000000..1b68decbe9 --- /dev/null +++ b/packages/@lwc/engine-server/src/__tests__/fixtures/lwc-on/config.json @@ -0,0 +1,3 @@ +{ + "entry": "x/lwc-on" +} diff --git a/packages/@lwc/engine-server/src/__tests__/fixtures/lwc-on/error.txt b/packages/@lwc/engine-server/src/__tests__/fixtures/lwc-on/error.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/@lwc/engine-server/src/__tests__/fixtures/lwc-on/expected.html b/packages/@lwc/engine-server/src/__tests__/fixtures/lwc-on/expected.html new file mode 100644 index 0000000000..dae22dad95 --- /dev/null +++ b/packages/@lwc/engine-server/src/__tests__/fixtures/lwc-on/expected.html @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/packages/@lwc/engine-server/src/__tests__/fixtures/lwc-on/modules/x/lwc-on/lwc-on.html b/packages/@lwc/engine-server/src/__tests__/fixtures/lwc-on/modules/x/lwc-on/lwc-on.html new file mode 100644 index 0000000000..10042889ff --- /dev/null +++ b/packages/@lwc/engine-server/src/__tests__/fixtures/lwc-on/modules/x/lwc-on/lwc-on.html @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/packages/@lwc/engine-server/src/__tests__/fixtures/lwc-on/modules/x/lwc-on/lwc-on.js b/packages/@lwc/engine-server/src/__tests__/fixtures/lwc-on/modules/x/lwc-on/lwc-on.js new file mode 100644 index 0000000000..e7c5cfb4c4 --- /dev/null +++ b/packages/@lwc/engine-server/src/__tests__/fixtures/lwc-on/modules/x/lwc-on/lwc-on.js @@ -0,0 +1,12 @@ +import { LightningElement } from 'lwc'; + +export default class LwcOn extends LightningElement { + eventListeners = { + click: () => { + console.log('click'); + }, + foo: () => { + console.log('foo'); + }, + }; +} diff --git a/packages/@lwc/integration-karma/scripts/karma-plugins/hydration-tests.js b/packages/@lwc/integration-karma/scripts/karma-plugins/hydration-tests.js index e1135eaeb7..cfa37e6f95 100644 --- a/packages/@lwc/integration-karma/scripts/karma-plugins/hydration-tests.js +++ b/packages/@lwc/integration-karma/scripts/karma-plugins/hydration-tests.js @@ -71,6 +71,7 @@ async function getCompiledModule(dirName, compileForSSR) { strict: true, }, enableDynamicComponents: true, + enableLwcOn: true, enableStaticContentOptimization: !DISABLE_STATIC_CONTENT_OPTIMIZATION, experimentalDynamicDirective: true, }), diff --git a/packages/@lwc/integration-karma/test-hydration/directives/lwc-on/index.spec.js b/packages/@lwc/integration-karma/test-hydration/directives/lwc-on/index.spec.js new file mode 100644 index 0000000000..d9cb0c0ad8 --- /dev/null +++ b/packages/@lwc/integration-karma/test-hydration/directives/lwc-on/index.spec.js @@ -0,0 +1,20 @@ +export default { + props: {}, + snapshot(target) { + const div = target.shadowRoot.querySelector('div'); + + return { + div, + }; + }, + test(target, snapshots) { + const snapshotAfterHydration = this.snapshot(target); + expect(snapshotAfterHydration.div).toBe(snapshots.div); + + // verify handler + snapshotAfterHydration.div.click(); + expect(target.timesClickedHandlerIsExecuted).toBe(1); + snapshotAfterHydration.div.dispatchEvent(new CustomEvent('foo')); + expect(target.timesFooHandlerIsExecuted).toBe(1); + }, +}; diff --git a/packages/@lwc/integration-karma/test-hydration/directives/lwc-on/x/main/main.html b/packages/@lwc/integration-karma/test-hydration/directives/lwc-on/x/main/main.html new file mode 100644 index 0000000000..cabec61e8b --- /dev/null +++ b/packages/@lwc/integration-karma/test-hydration/directives/lwc-on/x/main/main.html @@ -0,0 +1,3 @@ + diff --git a/packages/@lwc/integration-karma/test-hydration/directives/lwc-on/x/main/main.js b/packages/@lwc/integration-karma/test-hydration/directives/lwc-on/x/main/main.js new file mode 100644 index 0000000000..4464d2fd7b --- /dev/null +++ b/packages/@lwc/integration-karma/test-hydration/directives/lwc-on/x/main/main.js @@ -0,0 +1,25 @@ +import { LightningElement, api } from 'lwc'; + +export default class Main extends LightningElement { + _clickedHandlerCounter = 0; + _fooHandlerCounter = 0; + + @api + get timesClickedHandlerIsExecuted() { + return this._clickedHandlerCounter; + } + + @api + get timesFooHandlerIsExecuted() { + return this._fooHandlerCounter; + } + + eventListeners = { + click: function () { + this._clickedHandlerCounter++; + }, + foo: function () { + this._fooHandlerCounter++; + }, + }; +} diff --git a/packages/@lwc/ssr-compiler/src/__tests__/fixtures.spec.ts b/packages/@lwc/ssr-compiler/src/__tests__/fixtures.spec.ts index 82be0af3c0..8c39d7ba7c 100644 --- a/packages/@lwc/ssr-compiler/src/__tests__/fixtures.spec.ts +++ b/packages/@lwc/ssr-compiler/src/__tests__/fixtures.spec.ts @@ -65,6 +65,7 @@ async function compileFixture({ entry, dirname }: { entry: string; dirname: stri targetSSR: true, ssrMode: SSR_MODE, enableDynamicComponents: true, + enableLwcOn: true, // TODO [#3331]: remove usage of lwc:dynamic in 246 experimentalDynamicDirective: true, modules: [{ dir: modulesDir }], diff --git a/packages/@lwc/ssr-compiler/src/compile-template/index.ts b/packages/@lwc/ssr-compiler/src/compile-template/index.ts index 74cc04092a..47b827528d 100644 --- a/packages/@lwc/ssr-compiler/src/compile-template/index.ts +++ b/packages/@lwc/ssr-compiler/src/compile-template/index.ts @@ -89,6 +89,7 @@ export default function compileTemplate( experimentalComputedMemberExpression: options.experimentalComputedMemberExpression, experimentalComplexExpressions: options.experimentalComplexExpressions, enableDynamicComponents: options.enableDynamicComponents, + enableLwcOn: options.enableLwcOn, preserveHtmlComments: options.preserveHtmlComments, enableStaticContentOptimization: options.enableStaticContentOptimization, instrumentation: options.instrumentation, From 32770e52001cc32f53890fc2dfd0327e72a31b65 Mon Sep 17 00:00:00 2001 From: Dale Bustad Date: Tue, 3 Jun 2025 15:54:28 -0700 Subject: [PATCH 6/7] fix(ssr): massive compiled outputs when nested slots are present (#5379) * chore(ssr): move some calculations to compile-time for sleeker output * chore: remove unused types * chore: add mechanism to hoist statements * wip: hoist shadow slot fns * wip: address initial issues with hoisted shadow slot fn * wip: complete non-working solution * chore: comment * wip: new approach with hoisting to top of tmpl fn * fix: invalid slot-fn identifier when lwc:component is used * feat: curry local variables into the shadow slot content fn * chore: comments and some light cleanup * chore: add files that will be immediately deleted * chore: delete files immediately * chore: readability improvement Co-authored-by: Will Harney <62956339+wjhsf@users.noreply.github.com> * fix: excessive verbosity Co-authored-by: Will Harney <62956339+wjhsf@users.noreply.github.com> --------- Co-authored-by: Will Harney <62956339+wjhsf@users.noreply.github.com> --- .../src/compile-template/context.ts | 65 +++++++- .../src/compile-template/index.ts | 26 +++- .../src/compile-template/ir-to-es.ts | 1 + .../transformers/component/slotted-content.ts | 147 ++++++++++++------ .../src/compile-template/types.ts | 18 +++ packages/@lwc/ssr-compiler/src/shared.ts | 49 ------ .../@lwc/ssr-compiler/src/transmogrify.ts | 2 +- packages/@lwc/ssr-runtime/src/index.ts | 1 + packages/@lwc/ssr-runtime/src/render.ts | 13 ++ 9 files changed, 220 insertions(+), 102 deletions(-) diff --git a/packages/@lwc/ssr-compiler/src/compile-template/context.ts b/packages/@lwc/ssr-compiler/src/compile-template/context.ts index 6de3a6b23c..a2208ba6e2 100644 --- a/packages/@lwc/ssr-compiler/src/compile-template/context.ts +++ b/packages/@lwc/ssr-compiler/src/compile-template/context.ts @@ -6,7 +6,7 @@ */ import { ImportManager } from '../imports'; -import type { ImportDeclaration as EsImportDeclaration } from 'estree'; +import type { ImportDeclaration as EsImportDeclaration, Statement as EsStatement } from 'estree'; import type { TemplateOpts, TransformerContext } from './types'; export function createNewContext(templateOptions: TemplateOpts): { @@ -33,6 +33,65 @@ export function createNewContext(templateOptions: TemplateOpts): { } return false; }; + const getLocalVars = () => localVarStack.flatMap((varsSet) => Array.from(varsSet)); + + const hoistedStatements = { + module: [] as EsStatement[], + templateFn: [] as EsStatement[], + }; + const hoistedModuleDedupe = new Set(); + const hoistedTemplateDedupe = new Set(); + + const hoist = { + // Anything added here will be inserted at the top of the compiled template's + // JS module. + module(stmt: EsStatement, optionalDedupeKey?: unknown) { + if (optionalDedupeKey) { + if (hoistedModuleDedupe.has(optionalDedupeKey)) { + return; + } + hoistedModuleDedupe.add(optionalDedupeKey); + } + hoistedStatements.module.push(stmt); + }, + // Anything added here will be inserted at the top of the JavaScript function + // corresponding to the template (typically named `__lwcTmpl`). + templateFn(stmt: EsStatement, optionalDedupeKey?: unknown) { + if (optionalDedupeKey) { + if (hoistedTemplateDedupe.has(optionalDedupeKey)) { + return; + } + hoistedTemplateDedupe.add(optionalDedupeKey); + } + hoistedStatements.templateFn.push(stmt); + }, + }; + + const shadowSlotToFnName = new Map(); + let fnNameUniqueId = 0; + + // At present, we only track shadow-slotted content. This is because the functions + // corresponding to shadow-slotted content are deduped and hoisted to the top of + // the template function, whereas light-dom-slotted content is inlined. It may be + // desirable to also track light-dom-slotted content at some future point in time. + const slots = { + shadow: { + isDuplicate(uniqueNodeId: string) { + return shadowSlotToFnName.has(uniqueNodeId); + }, + register(uniqueNodeId: string, kebabCmpName: string) { + if (slots.shadow.isDuplicate(uniqueNodeId)) { + return shadowSlotToFnName.get(uniqueNodeId)!; + } + const shadowSlotContentFnName = `__lwcGenerateShadowSlottedContent_${kebabCmpName}_${fnNameUniqueId++}`; + shadowSlotToFnName.set(uniqueNodeId, shadowSlotContentFnName); + return shadowSlotContentFnName; + }, + getFnName(uniqueNodeId: string) { + return shadowSlotToFnName.get(uniqueNodeId) ?? null; + }, + }, + }; return { getImports: () => importManager.getImportDeclarations(), @@ -40,7 +99,11 @@ export function createNewContext(templateOptions: TemplateOpts): { pushLocalVars, popLocalVars, isLocalVar, + getLocalVars, templateOptions, + hoist, + hoistedStatements, + slots, import: importManager.add.bind(importManager), siblings: undefined, currentNodeIndex: undefined, diff --git a/packages/@lwc/ssr-compiler/src/compile-template/index.ts b/packages/@lwc/ssr-compiler/src/compile-template/index.ts index 47b827528d..c07acc51b1 100644 --- a/packages/@lwc/ssr-compiler/src/compile-template/index.ts +++ b/packages/@lwc/ssr-compiler/src/compile-template/index.ts @@ -117,7 +117,7 @@ export default function compileTemplate( )?.value?.value; const experimentalComplexExpressions = Boolean(options.experimentalComplexExpressions); - const { addImport, getImports, statements } = templateIrToEsTree(root, { + const { addImport, getImports, statements, cxt } = templateIrToEsTree(root, { preserveComments, experimentalComplexExpressions, }); @@ -126,7 +126,16 @@ export default function compileTemplate( addImport(imports, source); } - let tmplDecl = bExportTemplate(optimizeAdjacentYieldStmts(statements)); + let tmplDecl = bExportTemplate( + optimizeAdjacentYieldStmts([ + // Deep in the compiler, we may choose to hoist statements and declarations + // to the top of the template function. After `templateIrToEsTree`, these + // hoisted statements/declarations are prepended to the template function's + // body. + ...cxt.hoistedStatements.templateFn, + ...statements, + ]) + ); // Ideally, we'd just do ${LWC_VERSION_COMMENT} in the code template, // but placeholders have a special meaning for `esTemplate`. tmplDecl = produce(tmplDecl, (draft) => { @@ -138,7 +147,18 @@ export default function compileTemplate( ]; }); - let program = b.program([...getImports(), tmplDecl], 'module'); + let program = b.program( + [ + // All import declarations come first... + ...getImports(), + // ... followed by any statements or declarations that need to be hoisted + // to the top of the module scope... + ...cxt.hoistedStatements.module, + // ... followed by the template function declaration itself. + tmplDecl, + ], + 'module' + ); addScopeTokenDeclarations(program, filename, options.namespace, options.name); diff --git a/packages/@lwc/ssr-compiler/src/compile-template/ir-to-es.ts b/packages/@lwc/ssr-compiler/src/compile-template/ir-to-es.ts index 8d5fc027f9..76dd5f42a6 100644 --- a/packages/@lwc/ssr-compiler/src/compile-template/ir-to-es.ts +++ b/packages/@lwc/ssr-compiler/src/compile-template/ir-to-es.ts @@ -110,5 +110,6 @@ export function templateIrToEsTree(node: IrNode, contextOpts: TemplateOpts) { addImport: cxt.import, getImports, statements, + cxt, }; } diff --git a/packages/@lwc/ssr-compiler/src/compile-template/transformers/component/slotted-content.ts b/packages/@lwc/ssr-compiler/src/compile-template/transformers/component/slotted-content.ts index 50f2c890de..99421e387b 100644 --- a/packages/@lwc/ssr-compiler/src/compile-template/transformers/component/slotted-content.ts +++ b/packages/@lwc/ssr-compiler/src/compile-template/transformers/component/slotted-content.ts @@ -7,6 +7,7 @@ import { produce } from 'immer'; import { builders as b, is } from 'estree-toolkit'; +import { kebabCaseToCamelCase } from '@lwc/shared'; import { bAttributeValue, optimizeAdjacentYieldStmts } from '../../shared'; import { esTemplate, esTemplateWithYield } from '../../../estemplate'; import { irChildrenToEs, irToEs } from '../../ir-to-es'; @@ -14,11 +15,13 @@ import { isLiteral } from '../../shared'; import { expressionIrToEs } from '../../expression'; import { isNullableOf } from '../../../estree/validators'; import { isLastConcatenatedNode } from '../../adjacent-text-nodes'; -import type { CallExpression as EsCallExpression, Expression as EsExpression } from 'estree'; import type { + CallExpression as EsCallExpression, + Expression as EsExpression, Statement as EsStatement, ExpressionStatement as EsExpressionStatement, + VariableDeclaration as EsVariableDeclaration, } from 'estree'; import type { ChildNode as IrChildNode, @@ -36,51 +39,58 @@ import type { } from '@lwc/template-compiler'; import type { TransformerContext } from '../../types'; -const bGenerateSlottedContent = esTemplateWithYield` - const shadowSlottedContent = ${/* hasShadowSlottedContent */ is.literal} - ? async function* __lwcGenerateSlottedContent(contextfulParent) { - // The 'contextfulParent' variable is shadowed here so that a contextful relationship - // is established between components rendered in slotted content & the "parent" - // component that contains the . - - ${/* shadow slot content */ is.statement} - } - // Avoid creating the object unnecessarily - : null; - - const lightSlottedContentMap = ${/* hasLightSlottedContent */ is.literal} - ? Object.create(null) - // Avoid creating the object unnecessarily - : null; - - // The containing slot treats scoped slotted content differently. - const scopedSlottedContentMap = ${/* hasScopedSlottedContent */ is.literal} - ? Object.create(null) - // Avoid creating the object unnecessarily - : null; - - function addSlottedContent(name, fn, contentMap) { - let contentList = contentMap[name]; - if (contentList) { - contentList.push(fn); - } else { - contentMap[name] = [fn]; - } - } +// This function will be defined once and hoisted to the top of the template function. It'll be +// referenced deeper in the call stack where the function is called or passed as a parameter. +// It is a higher-order function that curries local variables that may be referenced by the +// shadow slot content. +const bGenerateShadowSlottedContent = esTemplateWithYield` + const ${/* function name */ is.identifier} = (${/* local vars */ is.identifier}) => async function* ${/* function name */ 0}(contextfulParent) { + // The 'contextfulParent' variable is shadowed here so that a contextful relationship + // is established between components rendered in slotted content & the "parent" + // component that contains the . + ${/* shadow slot content */ is.statement} + }; +`; +// By passing in the set of local variables (which correspond 1:1 to the variables expected by +// the referenced function), `shadowSlottedContent` will be curried function that can generate +// shadow-slotted content. +const bGenerateShadowSlottedContentRef = esTemplateWithYield` + const shadowSlottedContent = ${/* reference to hoisted fn */ is.identifier}(${/* local vars */ is.identifier}); +`; +const bNullishGenerateShadowSlottedContent = esTemplateWithYield` + const shadowSlottedContent = null; +`; - ${/* light DOM addLightContent statements */ is.expressionStatement} - ${/* scoped slot addLightContent statements */ is.expressionStatement} +const blightSlottedContentMap = esTemplateWithYield` + const ${/* name of the content map */ is.identifier} = Object.create(null); +`; +const bNullishLightSlottedContentMap = esTemplateWithYield` + const ${/* name of the content map */ is.identifier} = null; +`; + +const bGenerateSlottedContent = esTemplateWithYield` + ${/* const shadowSlottedContent = ... */ is.variableDeclaration} + ${/* const lightSlottedContentMap */ is.variableDeclaration} + ${/* const scopedSlottedContentMap */ is.variableDeclaration} + ${/* light DOM addLightContent statements */ is.expressionStatement} + ${/* scoped slot addLightContent statements */ is.expressionStatement} `; // Note that this function name (`__lwcGenerateSlottedContent`) does not need to be scoped even though // it may be repeated multiple times in the same scope, because it's a function _expression_ rather // than a function _declaration_, so it isn't available to be referenced anywhere. const bAddSlottedContent = esTemplate` - addSlottedContent(${/* slot name */ is.expression} ?? "", async function* __lwcGenerateSlottedContent(contextfulParent, ${ - /* scoped slot data variable */ isNullableOf(is.identifier) - }, slotAttributeValue) { - ${/* slot content */ is.statement} - }, ${/* content map */ is.identifier}); + addSlottedContent( + ${/* slot name */ is.expression} ?? "", + async function* __lwcGenerateSlottedContent( + contextfulParent, + ${/* scoped slot data variable */ isNullableOf(is.identifier)}, + slotAttributeValue) + { + ${/* slot content */ is.statement} + }, + ${/* content map */ is.identifier} + ); `; function getShadowSlottedContent(slottableChildren: IrChildNode[], cxt: TransformerContext) { @@ -155,7 +165,7 @@ function getLightSlottedContent(rootNodes: IrChildNode[], cxt: TransformerContex }); const { isSlotted: originalIsSlotted } = cxt; cxt.isSlotted = ancestorIndices.length > 1 || clone.type === 'Slot'; - const slotContent = irToEs(clone, cxt); + const slotContent = optimizeAdjacentYieldStmts(irToEs(clone, cxt)); cxt.isSlotted = originalIsSlotted; results.push( b.expressionStatement( @@ -246,7 +256,7 @@ export function getSlottedContent( bAddSlottedContent( slotName, boundVariable, - irChildrenToEs(child.children, cxt), + optimizeAdjacentYieldStmts(irChildrenToEs(child.children, cxt)), b.identifier('scopedSlottedContentMap') ) ); @@ -254,16 +264,57 @@ export function getSlottedContent( return addLightContentExpr; }); - const hasShadowSlottedContent = b.literal(shadowSlotContent.length > 0); - const hasLightSlottedContent = b.literal(lightSlotContent.length > 0); - const hasScopedSlottedContent = b.literal(scopedSlotContent.length > 0); + const hasShadowSlottedContent = shadowSlotContent.length > 0; + const hasLightSlottedContent = lightSlotContent.length > 0; + const hasScopedSlottedContent = scopedSlotContent.length > 0; cxt.isSlotted = isSlotted; + if (hasShadowSlottedContent || hasLightSlottedContent || hasScopedSlottedContent) { + cxt.import('addSlottedContent'); + } + + // Elsewhere, nodes and their subtrees are cloned. This design decision means that + // the node objects themselves cannot be used as unique identifiers (e.g. as keys + // in a map). However, for a given template, a node's location information does + // uniquely identify that node. + const uniqueNodeId = `${node.name}:${node.location.start}:${node.location.end}`; + + const localVars = cxt.getLocalVars(); + const localVarIds = localVars.map(b.identifier); + + if (hasShadowSlottedContent && !cxt.slots.shadow.isDuplicate(uniqueNodeId)) { + // Colon characters in element name will result in an invalid + // JavaScript identifier if not otherwise accounted for. + const kebabCmpName = kebabCaseToCamelCase(node.name).replace(':', '_'); + const shadowSlotContentFnName = cxt.slots.shadow.register(uniqueNodeId, kebabCmpName); + const shadowSlottedContentFn = bGenerateShadowSlottedContent( + b.identifier(shadowSlotContentFnName), + // If the slot-fn were defined here instead of hoisted to the top of the module, + // the local variables (e.g. from for:each) would be closed-over. When hoisted, + // however, we need to curry these variables. + localVarIds, + shadowSlotContent + ); + cxt.hoist.templateFn(shadowSlottedContentFn, node); + } + + const shadowSlottedContentFn = hasShadowSlottedContent + ? bGenerateShadowSlottedContentRef( + b.identifier(cxt.slots.shadow.getFnName(uniqueNodeId)!), + localVarIds + ) + : bNullishGenerateShadowSlottedContent(); + const lightSlottedContentMap = hasLightSlottedContent + ? blightSlottedContentMap(b.identifier('lightSlottedContentMap')) + : bNullishLightSlottedContentMap(b.identifier('lightSlottedContentMap')); + const scopedSlottedContentMap = hasScopedSlottedContent + ? blightSlottedContentMap(b.identifier('scopedSlottedContentMap')) + : bNullishLightSlottedContentMap(b.identifier('scopedSlottedContentMap')); + return bGenerateSlottedContent( - hasShadowSlottedContent, - shadowSlotContent, - hasLightSlottedContent, - hasScopedSlottedContent, + shadowSlottedContentFn, + lightSlottedContentMap, + scopedSlottedContentMap, lightSlotContent, scopedSlotContent ); diff --git a/packages/@lwc/ssr-compiler/src/compile-template/types.ts b/packages/@lwc/ssr-compiler/src/compile-template/types.ts index f9cd8adcea..73f244a87d 100644 --- a/packages/@lwc/ssr-compiler/src/compile-template/types.ts +++ b/packages/@lwc/ssr-compiler/src/compile-template/types.ts @@ -13,14 +13,32 @@ export type Transformer = ( cxt: TransformerContext ) => EsStatement[]; +export interface SlotMetadataContext { + shadow: { + isDuplicate: (uniqueNodeId: string) => boolean; + register: (uniqueNodeId: string, kebabCmpName: string) => string; + getFnName: (uniqueNodeId: string) => string | null; + }; +} + export interface TransformerContext { pushLocalVars: (vars: string[]) => void; popLocalVars: () => void; isLocalVar: (varName: string | null | undefined) => boolean; + getLocalVars: () => string[]; templateOptions: TemplateOpts; siblings: IrNode[] | undefined; currentNodeIndex: number | undefined; isSlotted?: boolean; + hoistedStatements: { + module: EsStatement[]; + templateFn: EsStatement[]; + }; + hoist: { + module: (stmt: EsStatement, optionalDedupeKey?: unknown) => void; + templateFn: (stmt: EsStatement, optionalDedupeKey?: unknown) => void; + }; + slots: SlotMetadataContext; import: ( imports: string | string[] | Record, source?: string diff --git a/packages/@lwc/ssr-compiler/src/shared.ts b/packages/@lwc/ssr-compiler/src/shared.ts index cd6a390a2a..f5c437fd77 100644 --- a/packages/@lwc/ssr-compiler/src/shared.ts +++ b/packages/@lwc/ssr-compiler/src/shared.ts @@ -9,55 +9,6 @@ import type { Config as TemplateCompilerConfig } from '@lwc/template-compiler'; export type Expression = string; -export type Instruction = - | IEmitTagName - | IEmitStaticString - | IEmitExpression - | IStartConditional - | IEndConditional - | IInvokeConnectedCallback - | IRenderChild - | IHoistImport - | IHoistInstantiation; - -export interface IEmitTagName { - kind: 'emitTagName'; -} - -export interface IEmitStaticString { - kind: 'emitStaticString'; -} - -export interface IEmitExpression { - kind: 'emitExpression'; - expression: Expression; -} - -export interface IStartConditional { - kind: 'startConditional'; -} - -export interface IEndConditional { - kind: 'endConditional'; -} - -export interface IInvokeConnectedCallback { - kind: 'invokeConnectedCallback'; -} - -export interface IRenderChild { - kind: 'renderChild'; - dynamic: Expression | null; -} - -export interface IHoistImport { - kind: 'hoistImport'; -} - -export interface IHoistInstantiation { - kind: 'hoistInstantiation'; -} - export type TemplateTransformOptions = Pick; export type ComponentTransformOptions = Partial< Pick diff --git a/packages/@lwc/ssr-compiler/src/transmogrify.ts b/packages/@lwc/ssr-compiler/src/transmogrify.ts index 0ffb61b26c..10a19acc66 100644 --- a/packages/@lwc/ssr-compiler/src/transmogrify.ts +++ b/packages/@lwc/ssr-compiler/src/transmogrify.ts @@ -21,7 +21,7 @@ export type Visitors = Parameters { const { node } = nodePath; diff --git a/packages/@lwc/ssr-runtime/src/index.ts b/packages/@lwc/ssr-runtime/src/index.ts index d2537bd90f..c65c028725 100644 --- a/packages/@lwc/ssr-runtime/src/index.ts +++ b/packages/@lwc/ssr-runtime/src/index.ts @@ -31,6 +31,7 @@ export { GenerateMarkupAsyncYield, renderAttrs, renderAttrsNoYield, + addSlottedContent, serverSideRenderComponent, // renderComponent is an alias for serverSideRenderComponent serverSideRenderComponent as renderComponent, diff --git a/packages/@lwc/ssr-runtime/src/render.ts b/packages/@lwc/ssr-runtime/src/render.ts index 8b631a52f8..f108286db7 100644 --- a/packages/@lwc/ssr-runtime/src/render.ts +++ b/packages/@lwc/ssr-runtime/src/render.ts @@ -187,6 +187,19 @@ export function fallbackTmplNoYield( } } +export function addSlottedContent( + name: string, + fn: unknown, + contentMap: Record +) { + const contentList = contentMap[name]; + if (contentList) { + contentList.push(fn); + } else { + contentMap[name] = [fn]; + } +} + interface ComponentWithGenerateMarkup extends LightningElementConstructor { [SYMBOL__GENERATE_MARKUP]?: GenerateMarkupVariants; } From 1ff3a21b7a4ce27e884495f7b49e7489ac431447 Mon Sep 17 00:00:00 2001 From: Will Harney <62956339+wjhsf@users.noreply.github.com> Date: Wed, 4 Jun 2025 11:11:01 -0400 Subject: [PATCH 7/7] chore: bump version to 8.20.0 (#5381) * chore: bump version to 8.20.0 * chore(release): wait 3 seconds before checking CI so GitHub has time to get it started, otherwise it will fail immediately --- package.json | 2 +- packages/@lwc/aria-reflection/package.json | 2 +- .../@lwc/babel-plugin-component/package.json | 6 +-- packages/@lwc/compiler/package.json | 14 +++---- packages/@lwc/engine-core/package.json | 8 ++-- packages/@lwc/engine-dom/package.json | 8 ++-- packages/@lwc/engine-server/package.json | 10 ++--- packages/@lwc/errors/package.json | 2 +- packages/@lwc/features/package.json | 4 +- packages/@lwc/integration-karma/package.json | 12 +++--- packages/@lwc/integration-tests/package.json | 6 +-- packages/@lwc/integration-types/package.json | 6 +-- packages/@lwc/module-resolver/package.json | 2 +- .../perf-benchmarks-components/package.json | 4 +- packages/@lwc/perf-benchmarks/package.json | 12 +++--- packages/@lwc/rollup-plugin/package.json | 10 ++--- packages/@lwc/shared/package.json | 2 +- packages/@lwc/signals/package.json | 4 +- packages/@lwc/ssr-client-utils/package.json | 2 +- packages/@lwc/ssr-compiler/package.json | 10 ++--- packages/@lwc/ssr-runtime/package.json | 6 +-- packages/@lwc/style-compiler/package.json | 4 +- packages/@lwc/synthetic-shadow/package.json | 6 +-- packages/@lwc/template-compiler/package.json | 6 +-- packages/@lwc/types/package.json | 4 +- packages/@lwc/wire-service/package.json | 6 +-- packages/lwc/package.json | 38 +++++++++---------- playground/package.json | 6 +-- scripts/release/version.sh | 1 + 29 files changed, 102 insertions(+), 101 deletions(-) diff --git a/package.json b/package.json index b859d6fd0a..e9198fc26c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "lwc-monorepo", - "version": "8.19.1", + "version": "8.20.0", "private": true, "description": "Lightning Web Components", "repository": { diff --git a/packages/@lwc/aria-reflection/package.json b/packages/@lwc/aria-reflection/package.json index 43cd4d749d..3ba1f8c97a 100644 --- a/packages/@lwc/aria-reflection/package.json +++ b/packages/@lwc/aria-reflection/package.json @@ -4,7 +4,7 @@ "You can safely modify dependencies, devDependencies, keywords, etc., but other props will be overwritten." ], "name": "@lwc/aria-reflection", - "version": "8.19.1", + "version": "8.20.0", "description": "ARIA element reflection polyfill for strings", "keywords": [ "aom", diff --git a/packages/@lwc/babel-plugin-component/package.json b/packages/@lwc/babel-plugin-component/package.json index 4d6a541986..ab9a0bc7af 100644 --- a/packages/@lwc/babel-plugin-component/package.json +++ b/packages/@lwc/babel-plugin-component/package.json @@ -4,7 +4,7 @@ "You can safely modify dependencies, devDependencies, keywords, etc., but other props will be overwritten." ], "name": "@lwc/babel-plugin-component", - "version": "8.19.1", + "version": "8.20.0", "description": "Babel plugin to transform a LWC module", "keywords": [ "lwc" @@ -47,8 +47,8 @@ }, "dependencies": { "@babel/helper-module-imports": "7.25.9", - "@lwc/errors": "8.19.1", - "@lwc/shared": "8.19.1", + "@lwc/errors": "8.20.0", + "@lwc/shared": "8.20.0", "line-column": "~1.0.2" }, "devDependencies": { diff --git a/packages/@lwc/compiler/package.json b/packages/@lwc/compiler/package.json index ec12c4bf65..1c441ca584 100644 --- a/packages/@lwc/compiler/package.json +++ b/packages/@lwc/compiler/package.json @@ -4,7 +4,7 @@ "You can safely modify dependencies, devDependencies, keywords, etc., but other props will be overwritten." ], "name": "@lwc/compiler", - "version": "8.19.1", + "version": "8.20.0", "description": "LWC compiler", "keywords": [ "lwc" @@ -52,11 +52,11 @@ "@babel/plugin-transform-class-properties": "7.25.9", "@babel/plugin-transform-object-rest-spread": "7.25.9", "@locker/babel-plugin-transform-unforgeables": "0.22.0", - "@lwc/babel-plugin-component": "8.19.1", - "@lwc/errors": "8.19.1", - "@lwc/shared": "8.19.1", - "@lwc/ssr-compiler": "8.19.1", - "@lwc/style-compiler": "8.19.1", - "@lwc/template-compiler": "8.19.1" + "@lwc/babel-plugin-component": "8.20.0", + "@lwc/errors": "8.20.0", + "@lwc/shared": "8.20.0", + "@lwc/ssr-compiler": "8.20.0", + "@lwc/style-compiler": "8.20.0", + "@lwc/template-compiler": "8.20.0" } } diff --git a/packages/@lwc/engine-core/package.json b/packages/@lwc/engine-core/package.json index 08fc6940ba..3114c77734 100644 --- a/packages/@lwc/engine-core/package.json +++ b/packages/@lwc/engine-core/package.json @@ -4,7 +4,7 @@ "You can safely modify dependencies, devDependencies, keywords, etc., but other props will be overwritten." ], "name": "@lwc/engine-core", - "version": "8.19.1", + "version": "8.20.0", "description": "Core LWC engine APIs.", "keywords": [ "lwc" @@ -46,9 +46,9 @@ } }, "dependencies": { - "@lwc/features": "8.19.1", - "@lwc/shared": "8.19.1", - "@lwc/signals": "8.19.1" + "@lwc/features": "8.20.0", + "@lwc/shared": "8.20.0", + "@lwc/signals": "8.20.0" }, "devDependencies": { "observable-membrane": "2.0.0" diff --git a/packages/@lwc/engine-dom/package.json b/packages/@lwc/engine-dom/package.json index 6846fdb1a5..bcdaca523f 100644 --- a/packages/@lwc/engine-dom/package.json +++ b/packages/@lwc/engine-dom/package.json @@ -4,7 +4,7 @@ "You can safely modify dependencies, devDependencies, keywords, etc., but other props will be overwritten." ], "name": "@lwc/engine-dom", - "version": "8.19.1", + "version": "8.20.0", "description": "Renders LWC components in a DOM environment.", "keywords": [ "lwc" @@ -46,9 +46,9 @@ } }, "devDependencies": { - "@lwc/engine-core": "8.19.1", - "@lwc/shared": "8.19.1", - "@lwc/features": "8.19.1" + "@lwc/engine-core": "8.20.0", + "@lwc/shared": "8.20.0", + "@lwc/features": "8.20.0" }, "lwc": { "modules": [ diff --git a/packages/@lwc/engine-server/package.json b/packages/@lwc/engine-server/package.json index ae887aacbc..7def8207cb 100644 --- a/packages/@lwc/engine-server/package.json +++ b/packages/@lwc/engine-server/package.json @@ -4,7 +4,7 @@ "You can safely modify dependencies, devDependencies, keywords, etc., but other props will be overwritten." ], "name": "@lwc/engine-server", - "version": "8.19.1", + "version": "8.20.0", "description": "Renders LWC components in a server environment.", "keywords": [ "lwc" @@ -46,10 +46,10 @@ } }, "devDependencies": { - "@lwc/engine-core": "8.19.1", - "@lwc/rollup-plugin": "8.19.1", - "@lwc/shared": "8.19.1", - "@lwc/features": "8.19.1", + "@lwc/engine-core": "8.20.0", + "@lwc/rollup-plugin": "8.20.0", + "@lwc/shared": "8.20.0", + "@lwc/features": "8.20.0", "@rollup/plugin-virtual": "^3.0.2", "parse5": "^7.2.1" } diff --git a/packages/@lwc/errors/package.json b/packages/@lwc/errors/package.json index abbf7dacaf..9db4cc7a7d 100644 --- a/packages/@lwc/errors/package.json +++ b/packages/@lwc/errors/package.json @@ -4,7 +4,7 @@ "You can safely modify dependencies, devDependencies, keywords, etc., but other props will be overwritten." ], "name": "@lwc/errors", - "version": "8.19.1", + "version": "8.20.0", "description": "LWC Error Utilities", "keywords": [ "lwc" diff --git a/packages/@lwc/features/package.json b/packages/@lwc/features/package.json index cebf85d1dd..118866560b 100644 --- a/packages/@lwc/features/package.json +++ b/packages/@lwc/features/package.json @@ -4,7 +4,7 @@ "You can safely modify dependencies, devDependencies, keywords, etc., but other props will be overwritten." ], "name": "@lwc/features", - "version": "8.19.1", + "version": "8.20.0", "description": "LWC Features Flags", "keywords": [ "lwc" @@ -46,6 +46,6 @@ } }, "dependencies": { - "@lwc/shared": "8.19.1" + "@lwc/shared": "8.20.0" } } diff --git a/packages/@lwc/integration-karma/package.json b/packages/@lwc/integration-karma/package.json index 98c708a9fa..0f505d3258 100644 --- a/packages/@lwc/integration-karma/package.json +++ b/packages/@lwc/integration-karma/package.json @@ -1,7 +1,7 @@ { "name": "@lwc/integration-karma", "private": true, - "version": "8.19.1", + "version": "8.20.0", "scripts": { "start": "KARMA_MODE=watch karma start ./scripts/karma-configs/test/local.js", "test": "karma start ./scripts/karma-configs/test/local.js --single-run", @@ -21,11 +21,11 @@ "karma-sauce-launcher-fix-firefox": "using a fork to work around https://github.com/karma-runner/karma-sauce-launcher/issues/275" }, "devDependencies": { - "@lwc/compiler": "8.19.1", - "@lwc/engine-dom": "8.19.1", - "@lwc/engine-server": "8.19.1", - "@lwc/rollup-plugin": "8.19.1", - "@lwc/synthetic-shadow": "8.19.1", + "@lwc/compiler": "8.20.0", + "@lwc/engine-dom": "8.20.0", + "@lwc/engine-server": "8.20.0", + "@lwc/rollup-plugin": "8.20.0", + "@lwc/synthetic-shadow": "8.20.0", "@types/jasmine": "^5.1.7", "chokidar": "^4.0.3", "istanbul-lib-coverage": "^3.2.2", diff --git a/packages/@lwc/integration-tests/package.json b/packages/@lwc/integration-tests/package.json index d2fbf5715b..02e4f1d8cc 100644 --- a/packages/@lwc/integration-tests/package.json +++ b/packages/@lwc/integration-tests/package.json @@ -1,7 +1,7 @@ { "name": "@lwc/integration-tests", "private": true, - "version": "8.19.1", + "version": "8.20.0", "scripts": { "build": "node scripts/build.js", "build:dev": "MODE=dev yarn build", @@ -18,7 +18,7 @@ "sauce:prod:ci": "MODE=prod yarn build:prod && MODE=prod ../../../scripts/ci/retry.sh wdio ./scripts/wdio.sauce.conf.js" }, "devDependencies": { - "@lwc/rollup-plugin": "8.19.1", + "@lwc/rollup-plugin": "8.20.0", "@wdio/cli": "^9.9.1", "@wdio/local-runner": "^9.9.1", "@wdio/mocha-framework": "^9.9.0", @@ -27,7 +27,7 @@ "@wdio/static-server-service": "^9.9.0", "deepmerge": "^4.3.1", "dotenv": "^16.5.0", - "lwc": "8.19.1", + "lwc": "8.20.0", "minimist": "^1.2.8", "webdriverio": "^9.0.7" }, diff --git a/packages/@lwc/integration-types/package.json b/packages/@lwc/integration-types/package.json index 11e1ee7a4f..45f66870d0 100644 --- a/packages/@lwc/integration-types/package.json +++ b/packages/@lwc/integration-types/package.json @@ -1,7 +1,7 @@ { "name": "@lwc/integration-types", "private": true, - "version": "8.19.1", + "version": "8.20.0", "description": "Type validation for LWC packages", "type": "module", "scripts": { @@ -9,8 +9,8 @@ "playground": "rollup -c src/playground/rollup.config.js --watch" }, "dependencies": { - "@lwc/rollup-plugin": "8.19.1", - "lwc": "8.19.1" + "@lwc/rollup-plugin": "8.20.0", + "lwc": "8.20.0" }, "devDependencies": { "@rollup/plugin-replace": "^6.0.2", diff --git a/packages/@lwc/module-resolver/package.json b/packages/@lwc/module-resolver/package.json index 9f35d9e0c6..72fa02fa2d 100644 --- a/packages/@lwc/module-resolver/package.json +++ b/packages/@lwc/module-resolver/package.json @@ -4,7 +4,7 @@ "You can safely modify dependencies, devDependencies, keywords, etc., but other props will be overwritten." ], "name": "@lwc/module-resolver", - "version": "8.19.1", + "version": "8.20.0", "description": "Resolves paths for LWC components", "keywords": [ "lwc" diff --git a/packages/@lwc/perf-benchmarks-components/package.json b/packages/@lwc/perf-benchmarks-components/package.json index 68ab5eb234..d970c4de02 100644 --- a/packages/@lwc/perf-benchmarks-components/package.json +++ b/packages/@lwc/perf-benchmarks-components/package.json @@ -1,12 +1,12 @@ { "name": "@lwc/perf-benchmarks-components", - "version": "8.19.1", + "version": "8.20.0", "private": true, "scripts": { "build": "rm -fr dist && rollup -c ./rollup.config.mjs" }, "devDependencies": { - "@lwc/rollup-plugin": "8.19.1" + "@lwc/rollup-plugin": "8.20.0" }, "nx": { "targets": { diff --git a/packages/@lwc/perf-benchmarks/package.json b/packages/@lwc/perf-benchmarks/package.json index d8c0d8ef64..ec6e074496 100644 --- a/packages/@lwc/perf-benchmarks/package.json +++ b/packages/@lwc/perf-benchmarks/package.json @@ -1,6 +1,6 @@ { "name": "@lwc/perf-benchmarks", - "version": "8.19.1", + "version": "8.20.0", "private": true, "scripts": { "build": "rm -fr dist && rollup -c ./rollup.config.mjs && node scripts/build.js && ./scripts/fix-deps.sh", @@ -15,11 +15,11 @@ "Don't forget to add these to fix-deps.sh as well." ], "dependencies": { - "@lwc/engine-dom": "8.19.1", - "@lwc/engine-server": "8.19.1", - "@lwc/perf-benchmarks-components": "8.19.1", - "@lwc/ssr-runtime": "8.19.1", - "@lwc/synthetic-shadow": "8.19.1" + "@lwc/engine-dom": "8.20.0", + "@lwc/engine-server": "8.20.0", + "@lwc/perf-benchmarks-components": "8.20.0", + "@lwc/ssr-runtime": "8.20.0", + "@lwc/synthetic-shadow": "8.20.0" }, "devDependencies": { "@best/cli": "^14.0.0", diff --git a/packages/@lwc/rollup-plugin/package.json b/packages/@lwc/rollup-plugin/package.json index cfc6045c7f..3488aa9028 100644 --- a/packages/@lwc/rollup-plugin/package.json +++ b/packages/@lwc/rollup-plugin/package.json @@ -4,7 +4,7 @@ "You can safely modify dependencies, devDependencies, keywords, etc., but other props will be overwritten." ], "name": "@lwc/rollup-plugin", - "version": "8.19.1", + "version": "8.20.0", "description": "Rollup plugin to compile LWC", "keywords": [ "lwc" @@ -46,13 +46,13 @@ } }, "dependencies": { - "@lwc/compiler": "8.19.1", - "@lwc/module-resolver": "8.19.1", - "@lwc/shared": "8.19.1", + "@lwc/compiler": "8.20.0", + "@lwc/module-resolver": "8.20.0", + "@lwc/shared": "8.20.0", "@rollup/pluginutils": "~5.1.4" }, "devDependencies": { - "@lwc/errors": "8.19.1" + "@lwc/errors": "8.20.0" }, "peerDependencies": { "rollup": "^1.2.0||^2.0.0||^3.0.0||^4.0.0" diff --git a/packages/@lwc/shared/package.json b/packages/@lwc/shared/package.json index b8780c0d65..985a0f1d7d 100644 --- a/packages/@lwc/shared/package.json +++ b/packages/@lwc/shared/package.json @@ -4,7 +4,7 @@ "You can safely modify dependencies, devDependencies, keywords, etc., but other props will be overwritten." ], "name": "@lwc/shared", - "version": "8.19.1", + "version": "8.20.0", "description": "Utilities and methods that are shared across packages", "keywords": [ "lwc" diff --git a/packages/@lwc/signals/package.json b/packages/@lwc/signals/package.json index 7aa52f9f0f..31859c5958 100644 --- a/packages/@lwc/signals/package.json +++ b/packages/@lwc/signals/package.json @@ -4,7 +4,7 @@ "You can safely modify dependencies, devDependencies, keywords, etc., but other props will be overwritten." ], "name": "@lwc/signals", - "version": "8.19.1", + "version": "8.20.0", "description": "Provides the interface to interact with reactivity from outside the framework", "keywords": [ "lwc" @@ -46,6 +46,6 @@ } }, "devDependencies": { - "@lwc/shared": "8.19.1" + "@lwc/shared": "8.20.0" } } diff --git a/packages/@lwc/ssr-client-utils/package.json b/packages/@lwc/ssr-client-utils/package.json index d88c03d529..da844eb971 100644 --- a/packages/@lwc/ssr-client-utils/package.json +++ b/packages/@lwc/ssr-client-utils/package.json @@ -4,7 +4,7 @@ "You can safely modify dependencies, devDependencies, keywords, etc., but other props will be overwritten." ], "name": "@lwc/ssr-client-utils", - "version": "8.19.1", + "version": "8.20.0", "description": "Client-side complement to @lwc/ssr-compiler", "keywords": [ "lwc", diff --git a/packages/@lwc/ssr-compiler/package.json b/packages/@lwc/ssr-compiler/package.json index e333f0cb55..d648b8025f 100644 --- a/packages/@lwc/ssr-compiler/package.json +++ b/packages/@lwc/ssr-compiler/package.json @@ -4,7 +4,7 @@ "You can safely modify dependencies, devDependencies, keywords, etc., but other props will be overwritten." ], "name": "@lwc/ssr-compiler", - "version": "8.19.1", + "version": "8.20.0", "description": "Compile component for use during server-side rendering", "keywords": [ "compiler", @@ -49,9 +49,9 @@ }, "dependencies": { "@babel/types": "7.27.0", - "@lwc/errors": "8.19.1", - "@lwc/shared": "8.19.1", - "@lwc/template-compiler": "8.19.1", + "@lwc/errors": "8.20.0", + "@lwc/shared": "8.20.0", + "@lwc/template-compiler": "8.20.0", "acorn": "8.14.1", "astring": "^1.9.0", "estree-toolkit": "^1.7.12", @@ -59,7 +59,7 @@ "meriyah": "^5.0.0" }, "devDependencies": { - "@lwc/babel-plugin-component": "8.19.1", + "@lwc/babel-plugin-component": "8.20.0", "@types/estree": "^1.0.7" } } diff --git a/packages/@lwc/ssr-runtime/package.json b/packages/@lwc/ssr-runtime/package.json index f26f360d7c..932ed7aba6 100644 --- a/packages/@lwc/ssr-runtime/package.json +++ b/packages/@lwc/ssr-runtime/package.json @@ -4,7 +4,7 @@ "You can safely modify dependencies, devDependencies, keywords, etc., but other props will be overwritten." ], "name": "@lwc/ssr-runtime", - "version": "8.19.1", + "version": "8.20.0", "description": "Runtime complement to @lwc/ssr-compiler", "keywords": [ "lwc", @@ -48,8 +48,8 @@ } }, "devDependencies": { - "@lwc/shared": "8.19.1", - "@lwc/engine-core": "8.19.1", + "@lwc/shared": "8.20.0", + "@lwc/engine-core": "8.20.0", "observable-membrane": "2.0.0" } } diff --git a/packages/@lwc/style-compiler/package.json b/packages/@lwc/style-compiler/package.json index 3e157fde12..a14710d380 100644 --- a/packages/@lwc/style-compiler/package.json +++ b/packages/@lwc/style-compiler/package.json @@ -4,7 +4,7 @@ "You can safely modify dependencies, devDependencies, keywords, etc., but other props will be overwritten." ], "name": "@lwc/style-compiler", - "version": "8.19.1", + "version": "8.20.0", "description": "Transform style sheet to be consumed by the LWC engine", "keywords": [ "lwc" @@ -46,7 +46,7 @@ } }, "dependencies": { - "@lwc/shared": "8.19.1", + "@lwc/shared": "8.20.0", "postcss": "~8.5.3", "postcss-selector-parser": "~7.1.0", "postcss-value-parser": "~4.2.0" diff --git a/packages/@lwc/synthetic-shadow/package.json b/packages/@lwc/synthetic-shadow/package.json index e995e0ff87..8cab250819 100644 --- a/packages/@lwc/synthetic-shadow/package.json +++ b/packages/@lwc/synthetic-shadow/package.json @@ -4,7 +4,7 @@ "You can safely modify dependencies, devDependencies, keywords, etc., but other props will be overwritten." ], "name": "@lwc/synthetic-shadow", - "version": "8.19.1", + "version": "8.20.0", "description": "Synthetic Shadow Root for LWC", "keywords": [ "lwc" @@ -46,8 +46,8 @@ } }, "devDependencies": { - "@lwc/features": "8.19.1", - "@lwc/shared": "8.19.1" + "@lwc/features": "8.20.0", + "@lwc/shared": "8.20.0" }, "lwc": { "modules": [ diff --git a/packages/@lwc/template-compiler/package.json b/packages/@lwc/template-compiler/package.json index 507923dc1a..7511bcfbe5 100644 --- a/packages/@lwc/template-compiler/package.json +++ b/packages/@lwc/template-compiler/package.json @@ -4,7 +4,7 @@ "You can safely modify dependencies, devDependencies, keywords, etc., but other props will be overwritten." ], "name": "@lwc/template-compiler", - "version": "8.19.1", + "version": "8.20.0", "description": "Template compiler package", "keywords": [ "lwc" @@ -46,8 +46,8 @@ } }, "dependencies": { - "@lwc/errors": "8.19.1", - "@lwc/shared": "8.19.1", + "@lwc/errors": "8.20.0", + "@lwc/shared": "8.20.0", "acorn": "~8.14.1", "astring": "~1.9.0", "he": "~1.2.0" diff --git a/packages/@lwc/types/package.json b/packages/@lwc/types/package.json index a9c2fa5a72..cf2666e9cf 100644 --- a/packages/@lwc/types/package.json +++ b/packages/@lwc/types/package.json @@ -4,7 +4,7 @@ "You can safely modify dependencies, devDependencies, keywords, etc., but other props will be overwritten." ], "name": "@lwc/types", - "version": "8.19.1", + "version": "8.20.0", "keywords": [ "lwc", "types", @@ -32,6 +32,6 @@ "*.d.ts" ], "dependencies": { - "@lwc/engine-core": "8.19.1" + "@lwc/engine-core": "8.20.0" } } diff --git a/packages/@lwc/wire-service/package.json b/packages/@lwc/wire-service/package.json index 3f4f4f988f..06de49d602 100644 --- a/packages/@lwc/wire-service/package.json +++ b/packages/@lwc/wire-service/package.json @@ -4,7 +4,7 @@ "You can safely modify dependencies, devDependencies, keywords, etc., but other props will be overwritten." ], "name": "@lwc/wire-service", - "version": "8.19.1", + "version": "8.20.0", "description": "@wire service", "keywords": [ "lwc" @@ -46,8 +46,8 @@ } }, "devDependencies": { - "@lwc/engine-core": "8.19.1", - "@lwc/shared": "8.19.1" + "@lwc/engine-core": "8.20.0", + "@lwc/shared": "8.20.0" }, "lwc": { "modules": [ diff --git a/packages/lwc/package.json b/packages/lwc/package.json index 648a9775b0..85169c07b7 100644 --- a/packages/lwc/package.json +++ b/packages/lwc/package.json @@ -1,6 +1,6 @@ { "name": "lwc", - "version": "8.19.1", + "version": "8.20.0", "description": "Lightning Web Components (LWC)", "homepage": "https://lwc.dev/", "repository": { @@ -21,24 +21,24 @@ "!vitest.config.*" ], "dependencies": { - "@lwc/aria-reflection": "8.19.1", - "@lwc/babel-plugin-component": "8.19.1", - "@lwc/compiler": "8.19.1", - "@lwc/engine-core": "8.19.1", - "@lwc/engine-dom": "8.19.1", - "@lwc/engine-server": "8.19.1", - "@lwc/errors": "8.19.1", - "@lwc/features": "8.19.1", - "@lwc/module-resolver": "8.19.1", - "@lwc/rollup-plugin": "8.19.1", - "@lwc/shared": "8.19.1", - "@lwc/ssr-compiler": "8.19.1", - "@lwc/ssr-runtime": "8.19.1", - "@lwc/style-compiler": "8.19.1", - "@lwc/synthetic-shadow": "8.19.1", - "@lwc/template-compiler": "8.19.1", - "@lwc/types": "8.19.1", - "@lwc/wire-service": "8.19.1" + "@lwc/aria-reflection": "8.20.0", + "@lwc/babel-plugin-component": "8.20.0", + "@lwc/compiler": "8.20.0", + "@lwc/engine-core": "8.20.0", + "@lwc/engine-dom": "8.20.0", + "@lwc/engine-server": "8.20.0", + "@lwc/errors": "8.20.0", + "@lwc/features": "8.20.0", + "@lwc/module-resolver": "8.20.0", + "@lwc/rollup-plugin": "8.20.0", + "@lwc/shared": "8.20.0", + "@lwc/ssr-compiler": "8.20.0", + "@lwc/ssr-runtime": "8.20.0", + "@lwc/style-compiler": "8.20.0", + "@lwc/synthetic-shadow": "8.20.0", + "@lwc/template-compiler": "8.20.0", + "@lwc/types": "8.20.0", + "@lwc/wire-service": "8.20.0" }, "lwc": { "modules": [ diff --git a/playground/package.json b/playground/package.json index 7fe0c1b6f6..70e3b4374e 100644 --- a/playground/package.json +++ b/playground/package.json @@ -1,7 +1,7 @@ { "private": true, "name": "@lwc/playground", - "version": "8.19.1", + "version": "8.20.0", "type": "module", "description": "Playground project to experiment with LWC.", "scripts": { @@ -9,9 +9,9 @@ "build": "NODE_ENV=production rollup -c" }, "devDependencies": { - "@lwc/rollup-plugin": "8.19.1", + "@lwc/rollup-plugin": "8.20.0", "@rollup/plugin-replace": "^6.0.2", - "lwc": "8.19.1", + "lwc": "8.20.0", "rollup": "^4.40.0", "rollup-plugin-livereload": "^2.0.5", "rollup-plugin-serve": "^3.0.0" diff --git a/scripts/release/version.sh b/scripts/release/version.sh index b6b373999a..5924373ec5 100755 --- a/scripts/release/version.sh +++ b/scripts/release/version.sh @@ -38,6 +38,7 @@ if which gh 2>/dev/null 1>/dev/null; then git switch "$BASE_BRANCH" git branch -D "$BRANCH" + sleep 3 # Give GitHub time to start CI before we check it . "$(dirname "$0")/wait-for-pr.sh" "$BRANCH" while [ "$(gh pr view "$BRANCH" --json state -q .state)" != 'MERGED' ]; do sleep 3 # Wait for GitHub to auto-merge the PR