diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 86531d45f58..7529d8eb3b1 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -41,11 +41,13 @@ Each package includes a DESIGN.md file, read that to gain a general understandin These contain domain-specific guidance. Read when performing related tasks: - [TypeScript](./skills/typescript/SKILL.md) — compiler constraints, import/export conventions, decorator usage, testing patterns. +- [Rust](./skills/rust/SKILL.md) — general guidance on performing updates between the crate and package. - [Shipping](./skills/shipping/SKILL.md) — pull request format, change file generation, documentation updates. - [Pull Request](./skills/fast-pull-request/SKILL.md) — generate a pull request description from the branch diff. - [Bug Report](./skills/fast-bug-report/SKILL.md) — generate a bug report issue from conversation context. - [Feature Request](./skills/fast-feature-request/SKILL.md) — generate a feature request issue from conversation context. - [Testing](./skills/testing/SKILL.md) — running tests locally and in CI, writing Playwright fixture tests. +- [Documentation](./skills/documentation/SKILL.md) — adding documentation in code, markdown files in each package/crate, and the website. ## Commands diff --git a/.github/skills/documentation/SKILL.md b/.github/skills/documentation/SKILL.md new file mode 100644 index 00000000000..40e5add3b38 --- /dev/null +++ b/.github/skills/documentation/SKILL.md @@ -0,0 +1,18 @@ +--- +name: documentation +description: Add documentation for contributors and developers. +--- + +Documentation exists in 3 forms, code comments, design/architectural documentation that is made up of markdown files describing code flow and core concepts (such as DESIGN.md), and the documentation website. + +Design/architectural documentation such as DESIGN.md should always be kept up-to-date. + +The website captures the documentation primarily for the `@microsoft/fast-element` package. Other packages are treated as tangential, so testing packages or other utilities should have their own sections. + +The website has been written in 11ty and primarily consists of markdown files. When making changes, ensure that the website has been scanned on whichever latest major version is available. These are organized by folder, so if 1.x/2.x/3.x folders are available, you will update the documentation in the 3.x folder. + +If you are making a breaking change, ensure the migration document has been updated. + +All markdown documentation aside from the package/crate level DESIGN.md files are in that package/crates docs folder. + +Any documentation created for the website should be written with the developer implementing the package in mind, it is not intended for other audiences. diff --git a/.github/skills/rust/SKILL.md b/.github/skills/rust/SKILL.md new file mode 100644 index 00000000000..9ba2133d7c3 --- /dev/null +++ b/.github/skills/rust/SKILL.md @@ -0,0 +1,12 @@ +--- +description: Use this guide when working on Rust changes in the FAST monorepo. +name: rust +--- + +# Working with the Rust crate and the Rust NodeJS CLI + +The primary location for the Rust logic should exist within a crate. If the logic is made accessible in the NodeJS environment via wrapping the crate and using a wasm bindgen, as much as possible any logic that exists in Rust should not be duplicated in JavaScript/TypeScript. + +## Breaking changes + +Understand [semver](https://semver.org/) and check the crate and package version. If the version is currently in a prerelease state, update the APIs with breaking changes as necessary and ensure that any generated pull request descriptions capture this. diff --git a/.github/workflows/ci-validate-platforms.yml b/.github/workflows/ci-validate-platforms.yml index 68615481900..b76f539ef1f 100644 --- a/.github/workflows/ci-validate-platforms.yml +++ b/.github/workflows/ci-validate-platforms.yml @@ -74,11 +74,11 @@ jobs: run: cargo install wasm-pack - name: Build workspaces - run: npx lage build ${{ github.event_name == 'pull_request' && '--since origin/main' || '' }} --allow-no-target-runs + run: npx lage build ${{ github.event_name == 'pull_request' && '--since origin/main' || '' }} --allow-no-target-runs --verbose - name: Install playwright dependencies and browsers run: | npx playwright install --with-deps - name: Run tests in all Packages - run: npx lage test:node test:playwright ${{ github.event_name == 'pull_request' && '--since origin/main' || '' }} --allow-no-target-runs + run: npx lage test:node test:playwright ${{ github.event_name == 'pull_request' && '--since origin/main' || '' }} --allow-no-target-runs --verbose diff --git a/.github/workflows/ci-validate-pr.yml b/.github/workflows/ci-validate-pr.yml index 3e12f8927f9..80612cbecd5 100644 --- a/.github/workflows/ci-validate-pr.yml +++ b/.github/workflows/ci-validate-pr.yml @@ -58,14 +58,14 @@ jobs: run: cargo install wasm-pack - name: Build workspaces - run: npx lage build ${{ github.event_name == 'pull_request' && format('--since origin/{0}', github.event.pull_request.base.ref) || '' }} --allow-no-target-runs + run: npx lage build ${{ github.event_name == 'pull_request' && format('--since origin/{0}', github.event.pull_request.base.ref) || '' }} --allow-no-target-runs --verbose - name: Install playwright dependencies and browsers run: | npx playwright install --with-deps - name: Testing unit tests - run: npx lage test:node test:chromium ${{ github.event_name == 'pull_request' && format('--since origin/{0}', github.event.pull_request.base.ref) || '' }} --allow-no-target-runs + run: npx lage test:node test:chromium ${{ github.event_name == 'pull_request' && format('--since origin/{0}', github.event.pull_request.base.ref) || '' }} --allow-no-target-runs --verbose - name: Testing final validation run: npm run test:validation diff --git a/.github/workflows/ci-webui-integration.yml b/.github/workflows/ci-webui-integration.yml index 2f90b381a41..971b14a0097 100644 --- a/.github/workflows/ci-webui-integration.yml +++ b/.github/workflows/ci-webui-integration.yml @@ -41,7 +41,7 @@ jobs: run: cargo install wasm-pack - name: Build workspaces - run: npm run build + run: npm run build -- --verbose - name: Install Playwright browsers run: npx playwright install --with-deps chromium diff --git a/change/@microsoft-fast-build-182ff259-711c-45c5-8be6-8925f2d78e79.json b/change/@microsoft-fast-build-182ff259-711c-45c5-8be6-8925f2d78e79.json new file mode 100644 index 00000000000..c3fb3846f4c --- /dev/null +++ b/change/@microsoft-fast-build-182ff259-711c-45c5-8be6-8925f2d78e79.json @@ -0,0 +1,7 @@ +{ + "type": "minor", + "comment": "feat: propagate shadowroot attributes", + "packageName": "@microsoft/fast-build", + "email": "7559015+janechu@users.noreply.github.com", + "dependentChangeType": "none" +} diff --git a/change/@microsoft-fast-build-5aac0659-95f9-4cb6-997d-252316b7841c.json b/change/@microsoft-fast-build-5aac0659-95f9-4cb6-997d-252316b7841c.json new file mode 100644 index 00000000000..019c5eb2cb3 --- /dev/null +++ b/change/@microsoft-fast-build-5aac0659-95f9-4cb6-997d-252316b7841c.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "chore: bump packages after failed publish", + "packageName": "@microsoft/fast-build", + "email": "7559015+janechu@users.noreply.github.com", + "dependentChangeType": "none" +} diff --git a/change/@microsoft-fast-build-9d7b843d-87a6-4f82-9db2-039234d8ad6e.json b/change/@microsoft-fast-build-9d7b843d-87a6-4f82-9db2-039234d8ad6e.json new file mode 100644 index 00000000000..4a44098f1cf --- /dev/null +++ b/change/@microsoft-fast-build-9d7b843d-87a6-4f82-9db2-039234d8ad6e.json @@ -0,0 +1,7 @@ +{ + "type": "minor", + "comment": "feat: allow fast-build rendering without state; omitted CLI state no longer probes state.json", + "packageName": "@microsoft/fast-build", + "email": "7559015+janechu@users.noreply.github.com", + "dependentChangeType": "none" +} diff --git a/change/@microsoft-fast-element-0e87a967-3dbb-4010-9c3f-c5dad8ef3532.json b/change/@microsoft-fast-element-0e87a967-3dbb-4010-9c3f-c5dad8ef3532.json index b2f21a220a4..1a9a1169513 100644 --- a/change/@microsoft-fast-element-0e87a967-3dbb-4010-9c3f-c5dad8ef3532.json +++ b/change/@microsoft-fast-element-0e87a967-3dbb-4010-9c3f-c5dad8ef3532.json @@ -1,6 +1,6 @@ { - "type": "major", - "comment": "remove FASTGlobal version tracking", + "type": "prerelease", + "comment": "BREAKING CHANGE: remove FASTGlobal version tracking", "packageName": "@microsoft/fast-element", "email": "7559015+janechu@users.noreply.github.com", "dependentChangeType": "none" diff --git a/change/@microsoft-fast-element-0e87a967-3dbb-4010-9c3f-c5dad8ef3544.json b/change/@microsoft-fast-element-0e87a967-3dbb-4010-9c3f-c5dad8ef3544.json index 08f341524f3..eb1222a40d2 100644 --- a/change/@microsoft-fast-element-0e87a967-3dbb-4010-9c3f-c5dad8ef3544.json +++ b/change/@microsoft-fast-element-0e87a967-3dbb-4010-9c3f-c5dad8ef3544.json @@ -1,6 +1,6 @@ { - "type": "major", - "comment": "Remove hydration view template side effect and unused export paths", + "type": "prerelease", + "comment": "BREAKING CHANGE: remove hydration view template side effect and unused export paths", "packageName": "@microsoft/fast-element", "email": "7559015+janechu@users.noreply.github.com", "dependentChangeType": "none" diff --git a/change/@microsoft-fast-element-106e0dee-a966-4f2d-9d9b-857c10599260.json b/change/@microsoft-fast-element-106e0dee-a966-4f2d-9d9b-857c10599260.json index f021be0f3b6..99420b67557 100644 --- a/change/@microsoft-fast-element-106e0dee-a966-4f2d-9d9b-857c10599260.json +++ b/change/@microsoft-fast-element-106e0dee-a966-4f2d-9d9b-857c10599260.json @@ -1,6 +1,6 @@ { - "type": "minor", - "comment": "Add schema-driven attributeMap and observerMap extension subpaths, optional definition schema, and observerMap schema configuration.", + "type": "prerelease", + "comment": "feat: add schema-driven attributeMap and observerMap extension subpaths, optional definition schema, and observerMap schema configuration.", "packageName": "@microsoft/fast-element", "email": "7559015+janechu@users.noreply.github.com", "dependentChangeType": "none" diff --git a/change/@microsoft-fast-element-5636cb6f-65c6-4c40-b964-d6c4b4b054f6.json b/change/@microsoft-fast-element-158aeac2-32cf-4dfb-9166-0cf6ab1fb196.json similarity index 56% rename from change/@microsoft-fast-element-5636cb6f-65c6-4c40-b964-d6c4b4b054f6.json rename to change/@microsoft-fast-element-158aeac2-32cf-4dfb-9166-0cf6ab1fb196.json index f468ccd0591..c6bf8d1aaec 100644 --- a/change/@microsoft-fast-element-5636cb6f-65c6-4c40-b964-d6c4b4b054f6.json +++ b/change/@microsoft-fast-element-158aeac2-32cf-4dfb-9166-0cf6ab1fb196.json @@ -1,6 +1,6 @@ { "type": "none", - "comment": "chore: replace rollup-plugin-filesize with esbuild bundle size reporting", + "comment": "docs: update the documentation for agents and move relevant code docs into a per-package docs folder", "packageName": "@microsoft/fast-element", "email": "7559015+janechu@users.noreply.github.com", "dependentChangeType": "none" diff --git a/change/@microsoft-fast-element-22265526-9ae0-4996-878d-ec0bd68133c2.json b/change/@microsoft-fast-element-22265526-9ae0-4996-878d-ec0bd68133c2.json index 8d8888a762d..eb26750c8d9 100644 --- a/change/@microsoft-fast-element-22265526-9ae0-4996-878d-ec0bd68133c2.json +++ b/change/@microsoft-fast-element-22265526-9ae0-4996-878d-ec0bd68133c2.json @@ -1,6 +1,6 @@ { - "type": "major", - "comment": "Move optional helpers to dedicated flat fast-element subpath exports such as @microsoft/fast-element/children.js, @microsoft/fast-element/repeat.js, @microsoft/fast-element/two-way.js, @microsoft/fast-element/signal.js, @microsoft/fast-element/attribute-map.js, and @microsoft/fast-element/observer-map.js while keeping controller and definition internals on the root entrypoint.", + "type": "prerelease", + "comment": "BREAKING CHANGE: move optional helpers to dedicated flat fast-element subpath exports such as @microsoft/fast-element/children.js, @microsoft/fast-element/repeat.js, @microsoft/fast-element/two-way.js, @microsoft/fast-element/signal.js, @microsoft/fast-element/attribute-map.js, and @microsoft/fast-element/observer-map.js while keeping controller and definition internals on the root entrypoint.", "packageName": "@microsoft/fast-element", "email": "7559015+janechu@users.noreply.github.com", "dependentChangeType": "none" diff --git a/change/@microsoft-fast-element-3b4bc9ff-fe92-4caa-a471-0f4895fe24b8.json b/change/@microsoft-fast-element-3b4bc9ff-fe92-4caa-a471-0f4895fe24b8.json new file mode 100644 index 00000000000..c4b7b2e2e12 --- /dev/null +++ b/change/@microsoft-fast-element-3b4bc9ff-fe92-4caa-a471-0f4895fe24b8.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "feat: propagate shadowroot attributes from f-template to declarative shadow DOM template", + "packageName": "@microsoft/fast-element", + "email": "7559015+janechu@users.noreply.github.com", + "dependentChangeType": "none" +} diff --git a/change/@microsoft-fast-element-3f6b286b-8276-4142-b903-7306b4c76808.json b/change/@microsoft-fast-element-3f6b286b-8276-4142-b903-7306b4c76808.json index 4acfbf098ef..238f041869a 100644 --- a/change/@microsoft-fast-element-3f6b286b-8276-4142-b903-7306b4c76808.json +++ b/change/@microsoft-fast-element-3f6b286b-8276-4142-b903-7306b4c76808.json @@ -1,6 +1,6 @@ { - "type": "major", - "comment": "Remove the public declarative TemplateElement configuration APIs and make declarative templates use an internal native f-template publisher with explicit hydration opt-in.", + "type": "prerelease", + "comment": "BREAKING CHANGE: remove the public declarative TemplateElement configuration APIs and make declarative templates use an internal native f-template publisher with explicit hydration opt-in.", "packageName": "@microsoft/fast-element", "email": "7559015+janechu@users.noreply.github.com", "dependentChangeType": "none" diff --git a/change/@microsoft-fast-element-61e3e3bd-e227-4449-9ff6-8edc104819d8.json b/change/@microsoft-fast-element-61e3e3bd-e227-4449-9ff6-8edc104819d8.json index d76b41861ae..ba78574e349 100644 --- a/change/@microsoft-fast-element-61e3e3bd-e227-4449-9ff6-8edc104819d8.json +++ b/change/@microsoft-fast-element-61e3e3bd-e227-4449-9ff6-8edc104819d8.json @@ -1,6 +1,6 @@ { - "type": "major", - "comment": "Replace HydratableElementController with automatic prerendered content optimization. When a component connects with an existing shadow root, bindings skip attribute/booleanAttribute DOM updates during initial render while still setting up event listeners, observers, and dependency tracking. Added isPrerendered flag to ElementController and ViewController. Added template-pending guard for defineAsync flow.", + "type": "prerelease", + "comment": "BREAKING CHANGE: replace HydratableElementController with automatic prerendered content optimization. When a component connects with an existing shadow root, bindings skip attribute/booleanAttribute DOM updates during initial render while still setting up event listeners, observers, and dependency tracking. Added isPrerendered flag to ElementController and ViewController. Added template-pending guard for defineAsync flow.", "packageName": "@microsoft/fast-element", "email": "7559015+janechu@users.noreply.github.com", "dependentChangeType": "patch" diff --git a/change/@microsoft-fast-element-61e3e3bd-e227-4449-9ff6-8edc104819d9.json b/change/@microsoft-fast-element-61e3e3bd-e227-4449-9ff6-8edc104819d9.json index dbaec336601..2de2628e1bb 100644 --- a/change/@microsoft-fast-element-61e3e3bd-e227-4449-9ff6-8edc104819d9.json +++ b/change/@microsoft-fast-element-61e3e3bd-e227-4449-9ff6-8edc104819d9.json @@ -1,6 +1,6 @@ { - "type": "major", - "comment": "Move declarative HTML APIs into @microsoft/fast-element/declarative.js, expose schema map helpers from extension subpaths, and remove the @microsoft/fast-html package.", + "type": "prerelease", + "comment": "BREAKING CHANGE: move declarative HTML APIs into @microsoft/fast-element/declarative.js, expose schema map helpers from extension subpaths, and remove the @microsoft/fast-html package.", "packageName": "@microsoft/fast-element", "dependentChangeType": "none", "email": "7559015+janechu@users.noreply.github.com" diff --git a/change/@microsoft-fast-element-69df485f-8d87-42e5-a858-70e27f8988dc.json b/change/@microsoft-fast-element-69df485f-8d87-42e5-a858-70e27f8988dc.json new file mode 100644 index 00000000000..51e92ed0580 --- /dev/null +++ b/change/@microsoft-fast-element-69df485f-8d87-42e5-a858-70e27f8988dc.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "chore: migrate typescript compiltation to typescript/native-preview", + "packageName": "@microsoft/fast-element", + "email": "13071055+chrisdholt@users.noreply.github.com", + "dependentChangeType": "none" +} diff --git a/change/@microsoft-fast-element-6ff0621c-8656-4b37-a6bf-4286c3f40c33.json b/change/@microsoft-fast-element-6ff0621c-8656-4b37-a6bf-4286c3f40c33.json index 3eca6e41519..6a8b5aa24e8 100644 --- a/change/@microsoft-fast-element-6ff0621c-8656-4b37-a6bf-4286c3f40c33.json +++ b/change/@microsoft-fast-element-6ff0621c-8656-4b37-a6bf-4286c3f40c33.json @@ -1,6 +1,6 @@ { - "type": "minor", - "comment": "add declarativeTemplate for auto-resolving markup", + "type": "prerelease", + "comment": "BREAKING CHANGE: add declarativeTemplate for auto-resolving markup", "packageName": "@microsoft/fast-element", "email": "7559015+janechu@users.noreply.github.com", "dependentChangeType": "none" diff --git a/change/@microsoft-fast-element-724d29c9-2cdc-4940-83c1-70ec5d64095e.json b/change/@microsoft-fast-element-724d29c9-2cdc-4940-83c1-70ec5d64095e.json index ae5d908d370..e2539b82121 100644 --- a/change/@microsoft-fast-element-724d29c9-2cdc-4940-83c1-70ec5d64095e.json +++ b/change/@microsoft-fast-element-724d29c9-2cdc-4940-83c1-70ec5d64095e.json @@ -1,6 +1,6 @@ { - "type": "major", - "comment": "Remove ElementStyles.withBehaviors, CSS style behaviors, and CSS bindings in fast-element.", + "type": "prerelease", + "comment": "BREAKING CHANGE: remove ElementStyles.withBehaviors, CSS style behaviors, and CSS bindings in fast-element.", "packageName": "@microsoft/fast-element", "email": "7559015+janechu@users.noreply.github.com", "dependentChangeType": "none" diff --git a/change/@microsoft-fast-element-748c99d5-48b4-4910-bb6c-e62520907383.json b/change/@microsoft-fast-element-748c99d5-48b4-4910-bb6c-e62520907383.json index 4221b946161..9700fc4d085 100644 --- a/change/@microsoft-fast-element-748c99d5-48b4-4910-bb6c-e62520907383.json +++ b/change/@microsoft-fast-element-748c99d5-48b4-4910-bb6c-e62520907383.json @@ -1,6 +1,6 @@ { - "type": "minor", - "comment": "Add extensions array argument to FASTElement.define() and FASTElementDefinition.define()", + "type": "prerelease", + "comment": "feat: add extensions array argument to FASTElement.define() and FASTElementDefinition.define()", "packageName": "@microsoft/fast-element", "email": "7559015+janechu@users.noreply.github.com", "dependentChangeType": "patch" diff --git a/change/@microsoft-fast-element-7e4a9b21-3c8d-4f12-91e0-8a6f2d4cb09b.json b/change/@microsoft-fast-element-7e4a9b21-3c8d-4f12-91e0-8a6f2d4cb09b.json new file mode 100644 index 00000000000..252cbbe998c --- /dev/null +++ b/change/@microsoft-fast-element-7e4a9b21-3c8d-4f12-91e0-8a6f2d4cb09b.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "feat: add ./declarative-syntax.js subpath export exposing declarative HTML syntax constants", + "packageName": "@microsoft/fast-element", + "email": "7559015+janechu@users.noreply.github.com", + "dependentChangeType": "none" +} diff --git a/change/@microsoft-fast-element-8f565910-c32b-471f-8452-2b4d075c7bc7.json b/change/@microsoft-fast-element-8f565910-c32b-471f-8452-2b4d075c7bc7.json index 5a91ebdfadb..ba5ca885094 100644 --- a/change/@microsoft-fast-element-8f565910-c32b-471f-8452-2b4d075c7bc7.json +++ b/change/@microsoft-fast-element-8f565910-c32b-471f-8452-2b4d075c7bc7.json @@ -1,6 +1,6 @@ { - "type": "major", - "comment": "Remove TemplateOptions from fast-element definitions and drop templateOptions-based connection/define waiting.", + "type": "prerelease", + "comment": "BREAKING CHANGE: remove TemplateOptions from fast-element definitions and drop templateOptions-based connection/define waiting.", "packageName": "@microsoft/fast-element", "email": "7559015+janechu@users.noreply.github.com", "dependentChangeType": "none" diff --git a/change/@microsoft-fast-element-9dd7b073-98cc-401b-a04d-0c02bee14306.json b/change/@microsoft-fast-element-9dd7b073-98cc-401b-a04d-0c02bee14306.json index 778fe226aeb..5a796040aaa 100644 --- a/change/@microsoft-fast-element-9dd7b073-98cc-401b-a04d-0c02bee14306.json +++ b/change/@microsoft-fast-element-9dd7b073-98cc-401b-a04d-0c02bee14306.json @@ -1,6 +1,6 @@ { - "type": "major", - "comment": "Simplify hydration markers to data-free sequential format (fe:b, fe:/b, fe:r, fe:/r, fe:e, fe:/e). Replace regex parsing with string equality checks. Single data-fe attribute replaces three old formats. Breaking change: SSR output format changed.", + "type": "prerelease", + "comment": "BREAKING CHANGE: simplify hydration markers to data-free sequential format (fe:b, fe:/b, fe:r, fe:/r, fe:e, fe:/e). Replace regex parsing with string equality checks. Single data-fe attribute replaces three old formats. Breaking change: SSR output format changed.", "packageName": "@microsoft/fast-element", "email": "7559015+janechu@users.noreply.github.com", "dependentChangeType": "none" diff --git a/change/@microsoft-fast-element-a3210470-66d1-4f88-a4e9-009f116b41fc.json b/change/@microsoft-fast-element-a3210470-66d1-4f88-a4e9-009f116b41fc.json index 63171fafaa5..b8e87a97509 100644 --- a/change/@microsoft-fast-element-a3210470-66d1-4f88-a4e9-009f116b41fc.json +++ b/change/@microsoft-fast-element-a3210470-66d1-4f88-a4e9-009f116b41fc.json @@ -1,6 +1,6 @@ { - "type": "major", - "comment": "remove deprecated declarative event e support", + "type": "prerelease", + "comment": "BREAKING CHANGE: remove deprecated declarative event e support", "packageName": "@microsoft/fast-element", "email": "7559015+janechu@users.noreply.github.com", "dependentChangeType": "none" diff --git a/change/@microsoft-fast-element-bf6e1587-06a9-4834-b906-54a625d2b446.json b/change/@microsoft-fast-element-bf6e1587-06a9-4834-b906-54a625d2b446.json index 59017661d0c..1626e54a37b 100644 --- a/change/@microsoft-fast-element-bf6e1587-06a9-4834-b906-54a625d2b446.json +++ b/change/@microsoft-fast-element-bf6e1587-06a9-4834-b906-54a625d2b446.json @@ -1,6 +1,6 @@ { - "type": "major", - "comment": "Make declarative runtime setup lazy and change @microsoft/fast-element/debug.js to require an explicit enableDebug() call.", + "type": "prerelease", + "comment": "BREAKING CHANGE: make declarative runtime setup lazy and change @microsoft/fast-element/debug.js to require an explicit enableDebug() call.", "packageName": "@microsoft/fast-element", "email": "7559015+janechu@users.noreply.github.com", "dependentChangeType": "none" diff --git a/change/@microsoft-fast-element-bfa58c92-2d69-4eea-b132-64dbe65d1663.json b/change/@microsoft-fast-element-bfa58c92-2d69-4eea-b132-64dbe65d1663.json index e068df1b4c9..9ac1d602618 100644 --- a/change/@microsoft-fast-element-bfa58c92-2d69-4eea-b132-64dbe65d1663.json +++ b/change/@microsoft-fast-element-bfa58c92-2d69-4eea-b132-64dbe65d1663.json @@ -1,6 +1,6 @@ { - "type": "minor", - "comment": "feat: modularize hydration and expose lifecycle callbacks via enableHydration() and declarativeTemplate()", + "type": "prerelease", + "comment": "BREAKING CHANGE: modularize hydration and expose lifecycle callbacks via enableHydration() and declarativeTemplate()", "packageName": "@microsoft/fast-element", "email": "7559015+janechu@users.noreply.github.com", "dependentChangeType": "none" diff --git a/change/@microsoft-fast-element-c20e636d-e975-46f4-9e0b-c7b6c8143ef6.json b/change/@microsoft-fast-element-c20e636d-e975-46f4-9e0b-c7b6c8143ef6.json new file mode 100644 index 00000000000..9ef94540ce3 --- /dev/null +++ b/change/@microsoft-fast-element-c20e636d-e975-46f4-9e0b-c7b6c8143ef6.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "feat: change default attribute-name-strategy from none to camelCase", + "packageName": "@microsoft/fast-element", + "email": "7559015+janechu@users.noreply.github.com", + "dependentChangeType": "none" +} diff --git a/change/@microsoft-fast-element-cab755e9-4ef4-4aac-b19a-f507df049e6b.json b/change/@microsoft-fast-element-cab755e9-4ef4-4aac-b19a-f507df049e6b.json index e58ad2d00af..ddecdc48fd6 100644 --- a/change/@microsoft-fast-element-cab755e9-4ef4-4aac-b19a-f507df049e6b.json +++ b/change/@microsoft-fast-element-cab755e9-4ef4-4aac-b19a-f507df049e6b.json @@ -1,6 +1,6 @@ { - "type": "major", - "comment": "Remove defineAsync and composeAsync — define() and compose() now return Promises", + "type": "prerelease", + "comment": "BREAKING CHANGE: remove defineAsync and composeAsync — define() and compose() now return Promises", "packageName": "@microsoft/fast-element", "email": "7559015+janechu@users.noreply.github.com", "dependentChangeType": "patch" diff --git a/change/@microsoft-fast-element-df226ab5-6e68-4362-b8ac-35046f0fc68b.json b/change/@microsoft-fast-element-df226ab5-6e68-4362-b8ac-35046f0fc68b.json index d0346bed7c2..92f3207100d 100644 --- a/change/@microsoft-fast-element-df226ab5-6e68-4362-b8ac-35046f0fc68b.json +++ b/change/@microsoft-fast-element-df226ab5-6e68-4362-b8ac-35046f0fc68b.json @@ -1,6 +1,6 @@ { - "type": "minor", - "comment": "add function-based template resolver sequencing", + "type": "prerelease", + "comment": "BREAKING CHANGE: add function-based template resolver sequencing", "packageName": "@microsoft/fast-element", "email": "7559015+janechu@users.noreply.github.com", "dependentChangeType": "none" diff --git a/change/@microsoft-fast-element-e0df8ba4-3d6c-4d95-a987-c3fcf719d9f6.json b/change/@microsoft-fast-element-e0df8ba4-3d6c-4d95-a987-c3fcf719d9f6.json index 1321d55e579..2690b600117 100644 --- a/change/@microsoft-fast-element-e0df8ba4-3d6c-4d95-a987-c3fcf719d9f6.json +++ b/change/@microsoft-fast-element-e0df8ba4-3d6c-4d95-a987-c3fcf719d9f6.json @@ -1,6 +1,6 @@ { - "type": "major", - "comment": "Remove the built-in globalThis polyfill; fast-element v3 now requires native globalThis", + "type": "prerelease", + "comment": "BREAKING CHANGE: remove the built-in globalThis polyfill; fast-element v3 now requires native globalThis", "packageName": "@microsoft/fast-element", "email": "7559015+janechu@users.noreply.github.com", "dependentChangeType": "patch" diff --git a/change/@microsoft-fast-element-f5c8274a-52ea-4f04-90e2-f51ca033abc1.json b/change/@microsoft-fast-element-f5c8274a-52ea-4f04-90e2-f51ca033abc1.json index f7ca22af047..9c1372dfdc0 100644 --- a/change/@microsoft-fast-element-f5c8274a-52ea-4f04-90e2-f51ca033abc1.json +++ b/change/@microsoft-fast-element-f5c8274a-52ea-4f04-90e2-f51ca033abc1.json @@ -1,6 +1,6 @@ { - "type": "major", - "comment": "fix: remove the fast-kernel multi-kernel modes. Breaking change: FAST no longer supports configuring isolated or version-scoped kernels via the script attribute.", + "type": "prerelease", + "comment": "BREAKING CHANGE: remove the fast-kernel multi-kernel modes. Breaking change: FAST no longer supports configuring isolated or version-scoped kernels via the script attribute.", "packageName": "@microsoft/fast-element", "email": "7559015+janechu@users.noreply.github.com", "dependentChangeType": "none" diff --git a/change/@microsoft-fast-router-de58ce36-92f3-4c7f-86a2-43a66a522f81.json b/change/@microsoft-fast-router-de58ce36-92f3-4c7f-86a2-43a66a522f81.json index 3af1bd0477b..acbc5ac8595 100644 --- a/change/@microsoft-fast-router-de58ce36-92f3-4c7f-86a2-43a66a522f81.json +++ b/change/@microsoft-fast-router-de58ce36-92f3-4c7f-86a2-43a66a522f81.json @@ -1,6 +1,6 @@ { "type": "prerelease", - "comment": "Update imports for styles.js subpath export", + "comment": "minor: update imports for styles.js subpath export", "packageName": "@microsoft/fast-router", "email": "7559015+janechu@users.noreply.github.com", "dependentChangeType": "none" diff --git a/change/@microsoft-fast-router-fea08afa-dc62-4165-bc7d-a65e8be2d2d3.json b/change/@microsoft-fast-router-fea08afa-dc62-4165-bc7d-a65e8be2d2d3.json new file mode 100644 index 00000000000..0cac0e55cdc --- /dev/null +++ b/change/@microsoft-fast-router-fea08afa-dc62-4165-bc7d-a65e8be2d2d3.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "chore: migrate typescript compiltation to typescript/native-preview", + "packageName": "@microsoft/fast-router", + "email": "13071055+chrisdholt@users.noreply.github.com", + "dependentChangeType": "none" +} diff --git a/change/@microsoft-fast-test-harness-7e4a9b22-4d8c-4e12-92f0-9b6f3d4cb19c.json b/change/@microsoft-fast-test-harness-7e4a9b22-4d8c-4e12-92f0-9b6f3d4cb19c.json new file mode 100644 index 00000000000..9d3138a5993 --- /dev/null +++ b/change/@microsoft-fast-test-harness-7e4a9b22-4d8c-4e12-92f0-9b6f3d4cb19c.json @@ -0,0 +1,7 @@ +{ + "type": "minor", + "comment": "fix: migrate build utilities to consume declarative HTML syntax from @microsoft/fast-element", + "packageName": "@microsoft/fast-test-harness", + "email": "7559015+janechu@users.noreply.github.com", + "dependentChangeType": "none" +} diff --git a/change/@microsoft-fast-test-harness-87ac85bb-3986-4dbc-b9c8-16fecdf194b3.json b/change/@microsoft-fast-test-harness-87ac85bb-3986-4dbc-b9c8-16fecdf194b3.json new file mode 100644 index 00000000000..63bbd6eda0a --- /dev/null +++ b/change/@microsoft-fast-test-harness-87ac85bb-3986-4dbc-b9c8-16fecdf194b3.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "chore: prepare package for publish", + "packageName": "@microsoft/fast-test-harness", + "email": "863023+radium-v@users.noreply.github.com", + "dependentChangeType": "none" +} diff --git a/change/@microsoft-fast-test-harness-c2765407-ced6-420a-b45d-af7f9a31c057.json b/change/@microsoft-fast-test-harness-c2765407-ced6-420a-b45d-af7f9a31c057.json new file mode 100644 index 00000000000..03024291dfc --- /dev/null +++ b/change/@microsoft-fast-test-harness-c2765407-ced6-420a-b45d-af7f9a31c057.json @@ -0,0 +1,7 @@ +{ + "type": "minor", + "comment": "feat: enhance SSR renderer and CLI with new template generation capabilities", + "packageName": "@microsoft/fast-test-harness", + "email": "863023+radium-v@users.noreply.github.com", + "dependentChangeType": "none" +} diff --git a/crates/microsoft-fast-build/DESIGN.md b/crates/microsoft-fast-build/DESIGN.md index e8e85d82fd1..cc18d314d15 100644 --- a/crates/microsoft-fast-build/DESIGN.md +++ b/crates/microsoft-fast-build/DESIGN.md @@ -6,7 +6,7 @@ This document explains how the crate works internally: the data flow, the key da ## High-level overview -The crate takes a **FAST declarative HTML template** (a string) and a **JSON state object** and produces static HTML. It does this in a single recursive pass — no AST is built, no DOM is constructed. The template string is scanned byte-by-byte, literal regions are copied verbatim, and directives / bindings are resolved and replaced. +The crate takes a **FAST declarative HTML template** (a string) and an optional **JSON state object** and produces static HTML. Public no-state entry points treat omitted state exactly like an empty object (`{}`). Rendering happens in a single recursive pass — no AST is built, no DOM is constructed. The template string is scanned byte-by-byte, literal regions are copied verbatim, and directives / bindings are resolved and replaced. ``` render_template(template, state_str) @@ -134,7 +134,7 @@ Both binders share the same structure: find the opening delimiter, find the clos ### `render_triple_brace` (`{{{expr}}}`) - Same resolution, but skips HTML escaping — used for injecting raw HTML. -Both return `RenderError::EmptyBinding` for blank expressions, `RenderError::UnclosedBinding`/`UnclosedUnescapedBinding` if no closing delimiter is found, and `RenderError::MissingState` if the expression does not resolve. +Both return `RenderError::EmptyBinding` for blank expressions and `RenderError::UnclosedBinding`/`UnclosedUnescapedBinding` if no closing delimiter is found. If the expression does not resolve in state, the content binding renders an empty string. --- @@ -149,6 +149,12 @@ Both return `RenderError::EmptyBinding` for blank expressions, `RenderError::Unc `get_nested_property` walks a dot-separated path through `JsonValue::Object` and `JsonValue::Array` nodes. Numeric path segments (e.g. `list.0`) are used as array indices. The implementation traverses the tree via references and only clones the final leaf value — no intermediate sub-trees are cloned. The one exception is the synthesised `length` value for arrays, which is returned early as an owned `JsonValue::Number` only when `length` is the final segment (for example, `items.length`). Additional segments after `length` do not resolve and return `None` (for example, `items.length.foo`). +Callers decide how to handle unresolved values: +- Content bindings (`{{expr}}` / `{{{expr}}}`) render an empty string. +- HTML attribute bindings omit the entire attribute. +- `` treats a missing list binding as an empty array and renders zero iterations; present non-array values return `RenderError::NotAnArray`. +- `` evaluates a missing binding as falsy. + ### Loop variable scoping `loop_vars` is a `Vec<(String, JsonValue)>`. Each `` iteration pushes one entry. Because `resolve_value` scans in reverse, the innermost repeat's variable shadows outer ones. Root state is always accessible for any key that is not shadowed. @@ -192,7 +198,7 @@ Because `||` is sought before `&&`, the recursive split on `||` runs first. Each 1. Extracts inner HTML and end position (same as `render_when`). 2. Parses `value="{{item in items}}"` with `parse_repeat_expr` — expects exactly three whitespace-separated tokens where the middle is `"in"`. -3. Resolves the list expression. Returns `RenderError::NotAnArray` if the value is not a `JsonValue::Array`. +3. Resolves the list expression. Missing values are treated as an empty array. Present non-array values return `RenderError::NotAnArray`. 4. For each item in the array, pushes `(var_name, item)` onto a new `loop_vars` vec and calls `render_node` on the inner template. 5. Uses `Iterator::collect::>()` to short-circuit on the first error in any iteration. @@ -228,7 +234,7 @@ A custom element is any opening tag whose name contains a hyphen, excluding `f-w - `aria-*` attributes (e.g. `aria-disabled`) are **converted to their camelCase ARIA property name** using the `attribute_lookup::aria_attr_to_property_key` lookup table (`aria-disabled` → `ariaDisabled`, `aria-valuenow` → `ariaValueNow`). This follows the [ARIA reflection](https://developer.mozilla.org/en-US/docs/Web/API/Element#instance_properties_included_from_aria) convention on `Element`. A static lookup table is used instead of algorithmic conversion because ARIA attribute names do not place dashes at word boundaries (e.g. `aria-valuenow`, not `aria-value-now`). Templates reference the camelCase form: `{{ariaDisabled}}`. - HTML attributes whose property name differs from the attribute name (e.g. `tabindex` → `tabIndex`, `readonly` → `readOnly`) are **converted to their camelCase DOM property name** using the `attribute_lookup::html_attr_to_property_key` lookup table. Attributes whose names already match (e.g. `disabled`, `title`) are not in the table and pass through as-is. - No value (boolean attribute) → `Bool(true)` - - `"{{binding}}"` → resolve from parent state (can be any `JsonValue` type, including arrays and objects) + - `"{{binding}}"` → resolve from parent state (can be any `JsonValue` type, including arrays and objects); if the binding is missing, the child-state value becomes `JsonValue::Null`, which displays as empty content - Value starting with `[` or `{` → parsed as a JSON array or object literal (e.g. `items='["a","b","c"]'` or `config='{"key":"val"}'`). If parsing fails the value falls back to `String`. - Anything else → `String` (plain literal values like `count="42"` are strings; use `count="{{count}}"` to resolve from parent state as a number) 5. **Render the shadow template** by calling `render_node` recursively with the child state as root and a **fresh `HydrationScope`** (always active). The `Locator` is threaded through so nested custom elements are expanded too. @@ -236,7 +242,7 @@ A custom element is any opening tag whose name contains a hyphen, excluding `f-w 7. **Build the outer opening tag** via `build_element_open_tag`, which handles attribute resolution and optionally injects hydration markers. The behaviour differs by context: - **Root custom elements** (`is_entry: true`): handled by `build_entry_element_open_tag`. `{{binding}}` attribute values are resolved from the root state: - **Primitives** (`String`, `Number`, `Bool`) — rendered with the resolved value (HTML-escaped). e.g. `text="{{message}}"` → `text="Hello world"`. - - **Non-primitives** (`Array`, `Object`, `Null`) — stripped. Arrays and objects cannot be meaningfully represented as HTML attribute values; the state is available directly in the element's template via state propagation. Because of this, same-name non-primitive bindings like `list="{{list}}"` are redundant in entry HTML and can be omitted — state propagation provides the value automatically. + - **Non-primitives** (`Array`, `Object`, `Null`) and missing values — stripped. Arrays and objects cannot be meaningfully represented as HTML attribute values; the state is available directly in the element's template via state propagation. Because of this, same-name non-primitive bindings like `list="{{list}}"` are redundant in entry HTML and can be omitted — state propagation provides the value automatically. - **Static attributes** (no binding syntax, e.g. `id="main"`) — passed through unchanged. - **Client-only attrs** (`@event`, `:prop`, attribute directives) — stripped as usual. - No `data-fe` marker is added — root elements at entry level have no parent hydration scope. @@ -249,6 +255,8 @@ A custom element is any opening tag whose name contains a hyphen, excluding `f-w [light DOM children] ``` + The `