chore: update v3 release with main#7534
Draft
janechu wants to merge 17 commits into
Draft
Conversation
# Pull Request ## 📖 Description Incorrect links as indicated by #7510, however we are currently on stable 2.x. This change directs the links to the appropriate stable major versioned pages. ### 🎫 Issues See #7510 big thanks to @banzalik for discovering this issue! ## ✅ Checklist ### General - [ ] I have included a change request file using `$ npm run change` - [ ] I have added tests for my changes. - [x] I have tested my changes. - [x] I have updated the project documentation to reflect my changes. - [x] I have read the [CONTRIBUTING](https://github.com/microsoft/fast/blob/main/CONTRIBUTING.md) documentation and followed the [standards](https://github.com/microsoft/fast/blob/main/CODE_OF_CONDUCT.md#our-standards) for this project. (cherry picked from commit 1f4c612)
…nt (#7521) Adds support for propagating host attributes declared on the inner `<template>` of an `<f-template>` definition onto the rendered host element opening tag during SSR. Today the build-time renderer drops every attribute on the source `<template>`, so authors cannot pre-declare host attributes (e.g. `tabindex`, `role`, `aria-*`) on a component's declarative template. After this change, the following template: ```html <f-template name="host-autofocus"> <template tabindex="0"> <span>{{text}}</span> </template> </f-template> ``` Now renders as `<host-autofocus autofocus tabindex="0">…</host-autofocus>` when the author writes `<host-autofocus autofocus></host-autofocus>` — both the author-provided `autofocus` and the template-provided `tabindex="0"` survive SSR. **Resolution rules:** - Static `name="value"`, dynamic `name="{{expr}}"`, and boolean `?name="{{expr}}"` bindings on the template's `<template>` are propagated. - Author-provided host attributes win on conflict (dedupe on lowercased name; `?name` dedupes against bare `name`). - Client-only attribute prefixes are skipped: `@event`, `:property`, `f-ref`, `f-slotted`, `f-children`. - `{{expr}}` resolves against the same state used to render the shadow root; non-primitive / null values are stripped. **Breaking change (prerelease):** `Locator::add_template_with_shadowroot_attrs` was renamed and widened to `add_template_with_attrs(name, content, shadowroot_attrs, host_attrs)`. `Locator::from_template_definitions` is now `pub` and accepts a 3-tuple metadata value `(content, shadowroot_attrs, host_attrs)`. The WASM/JSON shape `templatesMap[name]` now includes a `hostAttributes` array. No external callers existed inside the monorepo. - `crates/microsoft-fast-build/src/directive.rs` is where the actual splice happens. `merge_template_host_attrs` formats and joins filtered attrs before the rightmost `>` of the host opening tag. - The skip list is intentionally hand-rolled (no shared constant with the existing client-side dispatch in `fast-html`); see the `is_client_only_attr` helper for the canonical list. - The host-bindings fixture (`packages/fast-html/test/fixtures/host-bindings`) gained an intentional `autofocus` usage; a `biome-ignore lint/a11y/noAutofocus` HTML comment documents the rationale and survives `npm run build:fixtures` regeneration of `index.html`. - 16 new Rust unit/integration tests in `crates/microsoft-fast-build` (`tests/host_attributes.rs` + `locator.rs` unit tests + 2 WASM tests) — all 87 cargo tests pass. - 1 new Playwright assertion in `packages/fast-html/test/fixtures/host-bindings/host-bindings.spec.ts` verifying both `autofocus` (author) and `tabindex="0"` (propagated) survive SSR + hydration. - Full repo acceptance: `npm run build` ✓, `npm run test` ✓ (301/301 fast-html chromium, no regressions in other fixtures), `npm run biome:check` ✓, `npm run checkchange` ✓. - [x] I have included a change request file using `$ npm run change` - [x] I have added tests for my changes. - [x] I have tested my changes. - [x] I have updated the project documentation to reflect my changes. - [x] I have read the [CONTRIBUTING](https://github.com/microsoft/fast/blob/main/CONTRIBUTING.md) documentation and followed the [standards](https://github.com/microsoft/fast/blob/main/CODE_OF_CONDUCT.md#our-standards) for this project. (cherry picked from commit 89c18a1)
# Pull Request ## 📖 Description Update transitive dependency versions in `package-lock.json`. This is a maintenance chore to pick up patch releases for locked dependencies. Updated packages: - `brace-expansion` 5.0.5 → 5.0.6 - `fast-uri` 3.1.0 → 3.1.2 - `ws` 8.20.0 → 8.20.1 ## ✅ Checklist ### General - [x] I have tested my changes. - [x] I have read the [CONTRIBUTING](https://github.com/microsoft/fast/blob/main/CONTRIBUTING.md) documentation and followed the [standards](https://github.com/microsoft/fast/blob/main/CODE_OF_CONDUCT.md#our-standards) for this project. (cherry picked from commit 0b49158)
…e generation and SSR (#7519) # Pull Request ## 📖 Description Adds support for shadow DOM options (e.g. `delegatesFocus`, `mode`) throughout the test harness template generation and SSR rendering pipeline, so SSR-rendered components produce declarative shadow roots that match their client-side definitions. Also adds a `url` property to `SSRFixture` for tests that need to control the page URL during SSR rendering. Key changes: - Template generation now reads shadow options from component definitions and emits matching `shadowrootmode` / `shadowrootdelegatesfocus` attributes via a pluggable resolver (`resolveShadowOptions`). - SSR rendering propagates shadow options through to the rendered output. - `SSRFixture` gains a `url` option. ## 📑 Test Plan - New unit tests cover the shadow-options resolution path in `generate-templates` and `generate-webui-templates`, plus SSR `render` behavior. - New Playwright spec verifies the `SSRFixture` `url` property. - All existing tests pass locally via `npm run test -w @microsoft/fast-test-harness`. ## ✅ Checklist ### General - [x] I have included a change request file using `$ npm run change` - [x] I have added tests for my changes. - [x] I have tested my changes. - [x] I have updated the project documentation to reflect my changes. - [x] I have read the [CONTRIBUTING](https://github.com/microsoft/fast/blob/main/CONTRIBUTING.md) documentation and followed the [standards](https://github.com/microsoft/fast/blob/main/CODE_OF_CONDUCT.md#our-standards) for this project. (cherry picked from commit d0dc9ba)
Introduces `@microsoft/fast-examples-design-system`, a private, CSS-only design system shared across `examples/*`. The package ships a single stylesheet (`tokens.css`) with semantic, use-site-oriented design tokens — colors, typography, spacing, shape, elevation, and motion — under the `--fast-` prefix.
Color and elevation tokens use the CSS `light-dark()` function, so each declaration carries both its light and dark resolution side by side. Theme is driven by `prefers-color-scheme` by default and can be forced via `<html data-theme="light"|"dark">`. The package contains no JavaScript or TypeScript — consumer apps wire any theme switching themselves with two lines of DOM code.
The todo-app example is updated to consume the package: it pulls in `tokens.css`, replaces hard-coded design values with `var(--fast-*)` references, and statically sets `<html data-theme="light">`. Workspace and package documentation (`examples/DESIGN.md`, `examples/README.md`, `examples/design-system/DESIGN.md`, `examples/design-system/README.md`, `examples/todo-app/README.md`) covers the naming grammar, theme model, authoring guidance for humans and coding agents, and anti-patterns. The repo `copilot-instructions.md` is updated to mention the new package.
Both packages stay `"private": true`; no Beachball change file is required.
- `light-dark()` requires Chrome / Edge 123+, Firefox 120+, or Safari 17.5+ (all shipped 2023–2024). No fallback is shipped — these examples target evergreen browsers.
- Design-system is intentionally CSS-only: no JS / TS exports, no theme runtime, no component layer. Theme switching is delegated to consumer apps.
- The todo-app deliberately does not implement a runtime theme toggle. It hard-codes `<html data-theme="light">` and demonstrates only token consumption. Apps that need a toggle can add one with DOM APIs (`document.documentElement.setAttribute("data-theme", ...)`).
From the repo root:
```bash
npm run build # ✅ all packages build
npx biome check examples/ # ✅ clean
npm run checkchange # ✅ "No change files are needed" (both example packages are private)
```
Manual smoke: `npm start -w examples/todo-app`. The app should render in light theme; the primary action button should style correctly across rest/hover/pressed; the per-row delete button should use the `status-danger-tint-*` variants; focus rings should resolve via the dedicated `ctrl-focus-outer-*` tokens.
- [ ] I have included a change request file using `$ npm run change`
- [ ] I have added tests for my changes.
- [x] I have tested my changes.
- [x] I have updated the project documentation to reflect my changes.
- [x] I have read the [CONTRIBUTING](https://github.com/microsoft/fast/blob/main/CONTRIBUTING.md) documentation and followed the [standards](https://github.com/microsoft/fast/blob/main/CODE_OF_CONDUCT.md#our-standards) for this project.
(cherry picked from commit 9a37161)
# Pull Request ## 📖 Description Adds a new example, `examples/todo-mobx-app/`, that demonstrates how to bridge a MobX state store into FASTElement template bindings. The example introduces two thin, application-scoped decorators that collapse the usual MobX-in-a-web-component boilerplate (a manual `reaction()` per observed field + manual `Observable.notify()` + manual disposer wiring in `disconnectedCallback`) down to two annotations: - `@mobxObservableProperty` — marks a getter on a FASTElement subclass as one whose value comes from a MobX-tracked source. The getter is wrapped with `Observable.track(this, key)` so FAST treats it as a normal observable property in templates. - `@mobxObserver` — class decorator that, on `connectedCallback`, sets up one MobX `reaction` per `@mobxObservableProperty` key. When MobX detects a change, the reaction calls `Observable.notify(this, key)` and FAST re-renders the dependent template bindings. Reactions are disposed on `disconnectedCallback`. The bridge is uni-directional (MobX → FAST). Two-way input bindings (e.g. `<todo-form>`'s draft text) still use plain FAST `@observable` because that state is UI-local and not part of the MobX store. The example app itself is a small Todo application with the typical features (add / toggle / remove / toggle-all / filter / clear-completed / item count) plus localStorage persistence via a `mobx.autorun`. State lives in a singleton `TodoStore` (`makeAutoObservable`) and is shared across all components, so no props need to be passed down — components read directly from the store through `@mobxObservableProperty` getters. A `DESIGN.md` documents the bridge architecture, lifecycle ordering, the rationale for `recycle: false` on the `<todo-list>` repeat directive (otherwise FAST would rebind existing rows to new Todo objects without tearing down their MobX reactions, leaving stale subscriptions), and known gotchas around volatile getters and `useDefineForClassFields`. This is an additive example only — no existing packages or public API are modified. ## 👩💻 Reviewer Notes - The bridge code lives entirely under `examples/todo-mobx-app/src/mobx-integration/`. It is intentionally scoped to the example, not promoted to `@microsoft/fast-element`, so the team can evaluate the pattern before deciding whether to formalize it. - Suggested smoke test: `npm start -w @microsoft/fast-todo-mobx-app-example` (port 9001), then add several todos, toggle some, switch filters, remove an item that was previously in the middle of the list, then toggle a row that took its place — this exercises the `recycle: false` path that ensures per-item MobX reactions are torn down and rebuilt when rows shift. - `examples/todo-mobx-app/tsconfig.json` sets `useDefineForClassFields: false` and `skipLibCheck: true`. The first is required so MobX's `makeAutoObservable(this)` sees constructor-assigned fields (rather than `Object.defineProperty`-defined fields) and can convert them to observables. The second sidesteps a known gap in `mobx@6.13.5`'s `ObservableMap` lib types vs. TypeScript's `esnext` `Map` interface. ## 📑 Test Plan - `npm run build` (full repo): passes; the new package builds in ~1s via `tsgo -p tsconfig.json && vite build` and emits a ~131 KB `www/` bundle. - `npm run biome:check` on the new files: clean. - `npm run checkchange`: no change files required (the example package is `"private": true`, so beachball skips it). - Manual smoke test via Playwright against `npm start -w @microsoft/fast-todo-mobx-app-example`: add 3 todos through the form (verifies action propagation), verify list/stats text update reactively, toggle the middle row (verifies per-item bridge), switch the filter to "completed" (verifies computed view), remove an item and toggle the row that shifted into its slot (verifies `recycle: false` prevents stale reactions), reload the page (verifies localStorage persistence). All scenarios behaved as expected. - No new unit tests added — the example follows the convention of the existing `examples/todo-app/`, which also has no tests of its own. ## ✅ Checklist ### General - [ ] I have included a change request file using `$ npm run change` - [ ] I have added tests for my changes. - [x] I have tested my changes. - [x] I have updated the project documentation to reflect my changes. - [ ] I have read the [CONTRIBUTING](https://github.com/microsoft/fast/blob/main/CONTRIBUTING.md) documentation and followed the [standards](https://github.com/microsoft/fast/blob/main/CODE_OF_CONDUCT.md#our-standards) for this project. ## ⏭ Next Steps If the team likes the pattern, a natural follow-up is to promote `mobx-integration/` into its own optional adapter package (e.g. `@microsoft/fast-element-mobx`) so that other apps can consume the decorators without copy-pasting them. (cherry picked from commit b5af8e1)
# Pull Request ## 📖 Description - add a new `examples/chat-app` workspace that mirrors the `todo-app` example shape while using declarative FAST templates - pre-render the example shell with `@microsoft/fast-build` from `entry.html`, `state.json`, and `templates.html` - demonstrate iframe + `document.write()` streaming for canned assistant replies, including new `chat-message`, `chat-card`, and `chat-suggestion` custom elements - document the example in `README.md` and `DESIGN.md` ## 👩💻 Reviewer Notes - The easiest smoke test is to run the example, send `Hi`, and watch the assistant reply stream in chunk-by-chunk. - `index.html` is generated from the declarative sources by `build-markup.mjs`; if the shell changes, regenerate it with `npm run build -w @microsoft/fast-chat-app-example`. ## 📑 Test Plan - `npm run build` - `npm run build -w @microsoft/fast-chat-app-example` - `npm run test -w @microsoft/fast-chat-app-example` - manual smoke test of the built example with Playwright against a local static server (`Hi` → streamed reply + `How are you?` suggestion) - `npm run test` currently hits unrelated existing Playwright failures in `packages/fast-element/src/components/hydration.pw.spec.ts` (Firefox) and `packages/fast-element/src/platform.pw.spec.ts` (WebKit) ## ✅ Checklist ### General - [ ] I have included a change request file using `$ npm run change` - [ ] I have added tests for my changes. - [x] I have tested my changes. - [x] I have updated the project documentation to reflect my changes. - [x] I have read the [CONTRIBUTING](https://github.com/microsoft/fast/blob/main/CONTRIBUTING.md) documentation and followed the [standards](https://github.com/microsoft/fast/blob/main/CODE_OF_CONDUCT.md#our-standards) for this project. (cherry picked from commit 23cbb24)
Adds a complete, unified Todo example surface to the `examples/` tree that showcases the same UI and behavior across three different rendering strategies, and backs it with a shared end-to-end test suite. What this PR delivers: - **`examples/ssr/webui-todo-app`** — new SSR example built on declarative FAST HTML templates with `@microsoft/webui` prerendering and `@microsoft/fast-html` client-side hydration via `RenderableFASTElement` + `defineAsync` (`defer-and-hydrate`). - **Unified UI across all three todo apps** — `examples/csr/todo-app`, `examples/csr/todo-mobx-app`, and the new SSR app render the same heading, form, filter `<select>`, list, and footer. The MobX app collapsed from five components to one to match the canonical layout while keeping the MobX bridge (singleton store, `makeAutoObservable`, single `autorun`) intact. - **Footer counter row (`X items left · Y completed`)** in every todo app, finally surfacing the previously-unused computed counters on each store / state. - **New `@microsoft/fast-examples-e2e` workspace (`examples/test/`)** with a shared Playwright suite that runs identically against every app via per-project DOM adapters. Specs use the `.pw.spec.ts` suffix so we can add Node `.spec.ts` tests later without collision. - **CI** — `npm run test:e2e` is wired into `ci-validate-pr.yml` as a separate step after the existing unit-test job. - **`@microsoft/webui` bumped to 0.0.6** across the workspace. This supersedes the approach from #7362 and replaces the older imperative `webui-todo-app` example. - Supersedes #7362 A few intentional choices worth a closer look: - **`@volatile` on `DefaultTodoList.activeCount` / `completedCount`** — required because the initial `_todos` array is empty, so without `@volatile` FAST captures the dependency graph only on first evaluation and never subscribes to `item.done` for items added later. Inline comments document this. - **Imperative `syncCounts()` in the SSR app** — same pattern as the existing `syncDescription()` workaround for the fast-html text-binding hydration mismatch. SSR initial render does not include the counter text; it is populated client-side after hydration. - **Adapter design in `examples/test/`** — both CSR apps share `createCsrAdapter()` since their unified UI exposes the same selectors; the SSR app has its own adapter because items are rendered through a nested `<todo-item>` shadow root. See [`examples/test/DESIGN.md`](./examples/test/DESIGN.md) for the contributor guide. - `npm run build` — succeeds for all packages and example workspaces. - `npm run biome:check` — passes. - `CI=1 npm run test:e2e` — **21/21 passing** across all three projects (6 baseline scenarios + 1 new footer-counters scenario × 3 apps). - `npm run test` — `fast-element` and `fast-html` unit tests pass. Pre-existing Firefox flakiness in `fast-test-harness` (page.goto timeouts) is unrelated to this work; Chromium passes 46/46. - `npm run checkchange` — no change file needed (no `packages/*` source edits). - [ ] I have included a change request file using `$ npm run change` - [x] I have added tests for my changes. - [x] I have tested my changes. - [x] I have updated the project documentation to reflect my changes. - [x] I have read the [CONTRIBUTING](https://github.com/microsoft/fast/blob/main/CONTRIBUTING.md) documentation and followed the [standards](https://github.com/microsoft/fast/blob/main/CODE_OF_CONDUCT.md#our-standards) for this project. - Investigate the underlying FAST observation behavior that requires `@volatile` on getters iterating reactive arrays — worth confirming whether this is by design or a bug that should be fixed in `fast-element`. (cherry picked from commit 13916c1)
* fix: update references to "contoso" in documentation and tests * Change files (cherry picked from commit a46f63c)
…upport (#7531) # Pull Request ## 📖 Description Split the single nightly Azure CD job into two coordinated jobs so that **npm credentials never leave the Azure environment**. GitHub Actions packages each non-private workspace into an auditable GitHub release; the existing Azure release template publishes those tarballs to npm and crates.io. GitHub Releases are the source of truth, and `deployed/<tag>` git marker tags track which releases have already been published. ### GitHub Actions side (`cd-github-releases.yml`) - Runs on a nightly cron (`0 8 * * *` UTC, ~12am PST) plus `workflow_dispatch`. Does **not** bump versions or push source changes — version bumps land via ordinary human-authored PRs (e.g., from `npm run bump`). The cron is scheduled ~1 hour before the Azure CD pipeline (09:00 UTC) so any releases this job creates are picked up by that same night's publish run. - Two jobs: 1. **`detect`** runs [`create-github-releases.mjs --check-only`](build/scripts/create-github-releases.mjs). The script walks the workspaces tree (no `npm ci` required), computes `${name}_v${version}` for each non-private workspace, and emits `hasMissingReleases=true` if any of those git tags do not yet exist (uses `git rev-parse refs/tags/<tag>` — no API call). 2. **`release`** runs only when missing releases exist. Installs Node, the Rust toolchain (for `cargo package`), builds, then for every missing release: packs the npm tarball into `publish_artifacts_npm/`, packs the paired Rust crate (where `crates/<crate-name>/Cargo.toml` exists — derived by dropping `@` and replacing `/` with `-` in the npm name) into `publish_artifacts_crates/`, and creates the GitHub release with both assets attached via `gh release create --target <sha>`. The `gh` CLI creates a lightweight `${name}_v${version}` tag atomically with the release, so the release and its tag exist iff each other does — eliminating the orphan-tag risk that an explicit pre-`gh` tag-push would have. ### Azure Pipelines side (`azure-pipelines-cd.yml`) - Cron `0 9 * * *` (09:00 UTC daily; ~1am Pacific in standard time, ~2am during DST) with `always: true` so it still runs on no-op nights — work depends on external GitHub state, not repo commits. - Two stages: 1. **`Check`** runs [`download-github-releases.mjs --check-only`](build/scripts/download-github-releases.mjs). The script lists every git tag matching the beachball-style `${name}_v${version}` pattern that does **not** also have a `deployed/<tag>` counterpart and emits the list via Azure Pipelines `setvariable` output variables (`needsDeployment`, `undeployedTags`). No network calls to npm.org or crates.io. 2. **`Package`** depends on `Check` and runs only when `needsDeployment == 'true'`. Downloads every undeployed release's assets via `gh release download`, sorts them into `publish_artifacts_npm/` (`.tgz`) and `publish_artifacts_crates/` (`.crate`), hands off to `FAST.Release.PipelineTemplate.yml@fastPipelines`, and on success pushes a `deployed/<tag>` marker tag for each release that was just published. The next nightly run sees those markers and skips the corresponding releases. ### Paired npm package / Rust crate versioning - `@microsoft/fast-build` is paired with the `microsoft-fast-build` Rust crate at `crates/microsoft-fast-build/`. This PR bumps that crate from 0.1.0 → 0.7.0 to match the existing npm version. - A new **`postbump` hook** in [`beachball.config.js`](beachball.config.js) automatically rewrites the crate's `Cargo.toml` and `Cargo.lock` whenever `npm run bump` bumps the paired npm package, so PR authors don't have to remember to sync them by hand. The crate name is derived from the npm name by dropping `@` and replacing `/` with `-`; the hook is a no-op for npm packages without a paired crate. - `create-github-releases.mjs` still errors out at release time if the two versions disagree, as a safety net. ### Other changes - Adds [`build/scripts/create-github-releases.mjs`](build/scripts/create-github-releases.mjs) and [`build/scripts/download-github-releases.mjs`](build/scripts/download-github-releases.mjs) — thin Node.js wrappers around `gh`, `npm`, `cargo`, and `git`. No new npm dependencies and no custom GitHub API client. - Updates [`.github/workflows/README.md`](.github/workflows/README.md) to document the new two-stage CD flow. ## 👩💻 Reviewer Notes - **Idempotency is enforced entirely through git tags.** `${name}_v${version}` on the GitHub side, `deployed/${name}_v${version}` on the Azure side. Neither side needs to talk to npm.org or crates.io to decide whether work is required. - **Release tag format matches beachball's existing `${name}_v${version}`** (see `node_modules/beachball/lib/git/generateTag.js`), so the git tag, the GitHub release tag, and the eventual npm publish all share a single identifier. - The GitHub workflow needs the existing `secrets.GH_TOKEN` (same secret already used by `cd-gh-pages.yml`). No new secrets are required on either side. - **Open question on `FAST.Release.PipelineTemplate.yml@fastPipelines`:** the existing template may expect a single `publish_artifacts/` folder rather than the separate `publish_artifacts_npm/` + `publish_artifacts_crates/` layout. If that's the case, either the template or this PR needs a follow-up tweak to bridge the layout difference. ## 📑 Test Plan This change affects scheduled CD only, so it cannot be exercised end-to-end from a PR build. Verified locally: - `npm run format:check` and `npm run checkchange` pass. - `node --check` passes on both new scripts and `beachball.config.js`; `npx @biomejs/biome check` passes too. - `js-yaml` parses both `.github/workflows/cd-github-releases.yml` and `azure-pipelines-cd.yml` without errors. - Smoke run of `create-github-releases.mjs --check-only` against this repo correctly reports the 5 publishable workspaces (one with a paired crate) and `hasMissingReleases=true`. - Smoke run of `download-github-releases.mjs --check-only` against the live `microsoft/fast` repo correctly returns 0 undeployed tags. (After cleaning up some test releases that were created during development, the five publishable workspaces' tags now exist on `origin` and each one has a `deployed/<tag>` marker, so the script correctly reports nothing to publish.) - End-to-end `beachball bump` test: created a `patch` change file for `@microsoft/fast-build`, ran `npx beachball bump`, confirmed the `postbump` hook synced both `crates/microsoft-fast-build/Cargo.toml` and the matching `Cargo.lock` entry from `0.7.0` to `0.7.1` in the same bump commit. - `cargo package --no-verify --allow-dirty --manifest-path crates/microsoft-fast-build/Cargo.toml` produces the expected `microsoft-fast-build-0.7.0.crate` artifact. - `workflow_dispatch` is enabled on the new workflow so it can be triggered manually for the first end-to-end run after merge. ## ✅ Checklist ### General - [ ] I have included a change request file using `$ npm run change` - [x] I have added tests for my changes. - [x] I have tested my changes. - [x] I have updated the project documentation to reflect my changes. - [x] I have read the [CONTRIBUTING](https://github.com/microsoft/fast/blob/main/CONTRIBUTING.md) documentation and followed the [standards](https://github.com/microsoft/fast/blob/main/CODE_OF_CONDUCT.md#our-standards) for this project. > Note on the first checkbox: only `.github/`, `build/scripts/`, `azure-pipelines-cd.yml`, `beachball.config.js`, and `crates/microsoft-fast-build/` are modified. `.github/` is ignored by `beachball.config.js`; `build/` is a private workspace; `azure-pipelines-cd.yml` and `beachball.config.js` are not part of any published workspace; and the crate version bump pairs with the existing `@microsoft/fast-build` 0.7.0 release. `npm run checkchange` confirms no change file is required. ## ⏭ Next Steps - After this merges, manually trigger `cd-github-releases.yml` via `workflow_dispatch` on a quiet day (no pending bumps) to validate the path end-to-end. Then trigger it on a day with pending changes to validate release creation. The Azure pipeline will pick up the resulting GitHub release the following night and the `deployed/<tag>` marker should appear immediately after the publish. From there the nightly cron will keep the cycle going automatically. - Verify whether `FAST.Release.PipelineTemplate.yml@fastPipelines` is happy with the separate `publish_artifacts_npm/` and `publish_artifacts_crates/` folders, or whether a small template tweak is needed (follow-up PR if so). - If desired in a follow-up: add a separate GitHub Actions workflow that emits a Teams/Discord notification when a release is created and again when the Azure publish completes, for easier observability. (cherry picked from commit 9fdd2a5)
# Pull Request ## 📖 Description Removes unused root-level dependencies from the FAST monorepo and replaces `@types/express` with `@types/node`, which more accurately reflects the project's actual runtime environment. **Removed:** - `@types/express` - `esm` - `express` - `glob` - `yargs` **Added:** - `@types/node` Also removes the `overrides` block, which was only needed to pin `glob` transitively through `sucrase` and `read-package-json`. ### 🎫 Issues This PR supersedes #7528, #7529, and #7530. ## 📑 Test Plan All existing tests pass. No functional code was changed as this is a dependency cleanup only. ## ✅ Checklist ### General - [x] I have tested my changes. - [x] I have read the [CONTRIBUTING](https://github.com/microsoft/fast/blob/main/CONTRIBUTING.md) documentation and followed the [standards](https://github.com/microsoft/fast/blob/main/CODE_OF_CONDUCT.md#our-standards) for this project. (cherry picked from commit e92f289)
Adapts cherry-picked commits to work on the v3 release branch where @microsoft/fast-html does not exist as a separate package (its code lives inside @microsoft/fast-element/declarative/): - Drop @microsoft/fast-html-only files from PR #7521 (DESIGN.md / RENDERING.md / package.json) and preserve v3's existing data-fe="N" hydration marker style when merging the new template host attribute propagation logic into crates/microsoft-fast-build/DESIGN.md and the host-bindings fixture (index.html, main.ts). - Convert the autofocus host fixture from PR #7521 to v3's plain Element.define({ template: declarativeTemplate() }) pattern instead of RenderableFASTElement(...).defineAsync({ templateOptions }). - Drop the new SSR example apps from PR #7518 (examples/ssr/chat-app) and PR #7424 (examples/ssr/webui-todo-app). Both rely on the RenderableFASTElement mixin and TemplateElement.options/define APIs that ship in @microsoft/fast-html on main but do not exist on v3. Adapting them would require a substantial rewrite that should be done as a follow-up. - Trim the new E2E suite from PR #7424 to only target the two CSR example apps (csr-todo, csr-todo-mobx). Removes the ssr-webui-todo Playwright project/webServer entry, the ssr-webui-todo adapter, and the webui-todo-app state.json backup/restore in global-setup / global-teardown. - Convert the @microsoft-fast-html-* change files from PRs #7521 and #7424 to drops (no equivalent fast-html package exists on v3). - Update .github/copilot-instructions.md to drop the ssr/chat-app and ssr/webui-todo-app bullets from the Example projects section. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
With `target: ES2022` and no explicit `useDefineForClassFields` setting,
TypeScript defaults the option to `true`. Class fields are then emitted
with `Object.defineProperty(this, ...)` semantics, which install own
data properties on each instance that shadow the prototype getters/setters
installed by FAST's `@observable` decorator.
The practical result is that:
- The `@observable activeFilter` on `DefaultTodoList` no longer notifies
on assignment, so the `<select :value=${twoWay(x => x.todos.activeFilter)}>`
twoWay binding emits the "View=>Model update skipped" warning and
filter changes are dropped.
- `@observable _todos` and `@observable description` (on TodoForm) also
bypass the observation layer, so the footer `activeCount`/`completedCount`
bindings never receive change notifications when items are added,
toggled, or removed.
The sibling `examples/csr/todo-mobx-app` already sets
`useDefineForClassFields: false` for the same reason; align todo-app's
tsconfig.
Verified with `examples/test` Playwright suite (`npm run test:e2e`):
all 14 specs (7 per project, csr-todo + csr-todo-mobx) now pass; the
two previously-failing csr-todo specs (filter and footer counts) are
green.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Restores examples/ssr/chat-app and examples/ssr/webui-todo-app on the
v3 release branch, porting them away from @microsoft/fast-html
(which does not exist on v3) to v3's declarativeTemplate() +
enableHydration() pattern from @microsoft/fast-element.
Port pattern applied to every custom element:
class X extends RenderableFASTElement(FASTElement) // before
-> class X extends FASTElement // after
X.defineAsync({ name, templateOptions: 'defer-and-hydrate' }) // before
-> X.define(
{ name, template: declarativeTemplate() },
[observerMap()],
) // after
TemplateElement.options({...}).config({...}).define(...) // before
-> enableHydration({ hydrationComplete() {...} }) // after
For webui-todo-app, TodoApp.prepare() was previously called from
connectedCallback after webui-driven prerender. That interleaves with
v3 hydration and corrupts the binding pass, so prepare() now runs from
the declarativeTemplate({ elementWillHydrate }) lifecycle callback so
the state is in place before v3 walks the prerendered shadow tree.
webui-todo-app moves from @microsoft/webui --plugin=fast (which emits
the legacy 'data-fe-c-N-M' / 'fe-b$$start$$N$$...' markers consumed
by fast-html) to webui ^0.0.13 with --plugin=fast-v3, which emits the
compact 'data-fe="N"' + '<!--fe:b-->' markers consumed by v3's
hydration.js.
Re-wires examples/test for the ssr-webui-todo Playwright project:
- playwright.config.ts: re-adds the ssr-webui-todo project (port 8081)
and its npm-run webui webServer entry.
- support/adapters/ssr-webui-todo.ts: restored from main.
- support/adapters/index.ts: re-registers the ssr adapter.
- support/global-setup.ts / global-teardown.ts: restore the
state.json backup/restore so SSR tests do not leak state between
runs.
Drive-by v3 fixes for csr/todo-mobx-app so its e2e tests pass on this
branch (broken when cherry-picked because v3 reorganised the API):
- src/todo-app.ts: 'export const app = TodoApp.compose(...)' must now
be awaited - compose() returns a Promise on v3.
- src/todo-app.template.ts and src/todo-form.template.ts: twoWay moved
from '@microsoft/fast-element/binding/two-way.js' to
'@microsoft/fast-element/two-way.js' on v3.
- tsconfig.json: bumped target/module from ES2020 to ES2022 so the
top-level await above type-checks.
Restores the chat-app and webui-todo-app bullets in
.github/copilot-instructions.md; the webui bullet now mentions v3's
declarativeTemplate() + enableHydration() rather than fast-html
hydration.
Validation:
- npm run build (full monorepo): all 7 active workspaces succeed.
- examples/test e2e: 21/21 specs pass (csr-todo 7, csr-todo-mobx 7,
ssr-webui-todo 7).
- npm run biome:check: clean.
- npm run checkchange: no change files required (all 4 affected
example workspaces are private).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…t constructor
declarativeTemplate() previously returned
FASTElementTemplateResolver, which defaults to
FASTElementTemplateResolver<Constructable<HTMLElement>>. When a strict
consumer wrote
MyElement.define(
{ name: 'my-element', template: declarativeTemplate() },
[observerMap()],
);
the template field is typed as ElementViewTemplate<MyElement, any> |
FASTElementTemplateResolver<typeof MyElement> | undefined, but the
return type was the wider HTMLElement-flavoured resolver. Under tsgo
(or any consumer with noImplicitThis enabled) that mismatch caused
overload resolution to fall through to the second
define(type, nameOrDef?, extensions?) overload and report 'name does
not exist in type Constructable<HTMLElement>'.
Make declarativeTemplate generic over TType extends
Constructable<HTMLElement>, with the same default that
FASTElementTemplateResolver uses, so the returned resolver narrows to
the element type at the call site and overload resolution picks the
this:TType overload as intended.
Strips the 'declarativeTemplate() as any' workaround from
examples/ssr/chat-app and examples/ssr/webui-todo-app introduced in
the previous commit on this branch; both example apps build cleanly
under tsgo + vite/esbuild and the full Playwright e2e suite still
passes 21/21.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ylesheets outDir (#7535) * fix: correct output directory structure for generated CSS files * Change files
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Pull Request
📖 Description
Brings
releases/fast-element-v3up to date withmain. Cherry-picks every commit landed onmainafter PR #7507 (the previous v3↔main sync) and adds an adaptation commit so the changes work with the v3 architecture (where@microsoft/fast-htmlis consolidated into@microsoft/fast-elementundersrc/declarative/).Cherry-picked (in chronological order):
<f-template>host attributes onto rendered host elementThe three "applying package updates" beachball commits on
main(ecb12a7,bf54b39,ed616df) were intentionally skipped — v3 maintains its own versioning track (fast-element@3.0.0-rc.1,fast-test-harness@0.0.1) and runs its own publish.Adaptation commit highlights:
examples/ssr/chat-app/(from feat: add chat app example #7518) andexamples/ssr/webui-todo-app/(from feat(examples): unified todo apps with SSR, MobX, and E2E suite #7424) originally relied on theRenderableFASTElement(...)mixin andTemplateElement.options(...).config(...).define({ name: "f-template" })APIs that ship in@microsoft/fast-htmlonmain. On v3 they are rewritten to useElement.define({ template: declarativeTemplate() }, [observerMap()])(from@microsoft/fast-element/declarative.js+@microsoft/fast-element/observer-map.js) plusenableHydration({ hydrationComplete() {…} })(from@microsoft/fast-element/hydration.js). Thewebui-todo-appprepare()step (hydrating items out of the prerendered shadow DOM) is wired into theelementWillHydratelifecycle callback exposed bydeclarativeTemplate(callbacks).--plugin=fast-v3. The webui dev server is invoked withwebui serve --plugin=fast-v3(instead of--plugin=fast), so the prerender emits v3-compatibledata-fe="N"attribute markers and<!--fe:b-->/<!--fe:r-->content markers that v3 hydration recognizes.@microsoft/webuiis pinned to^0.0.13(the first version exposingfast-v3).examples/test/playwright.config.tsre-adds thessr-webui-todoproject +webServerentry, thessr-webui-todoDOM adapter, and thestate.jsonbackup/restore inglobal-setup.ts/global-teardown.ts. Runningnpm run test:e2efromexamples/test/now exercises the full csr-todo + csr-todo-mobx + ssr-webui-todo matrix.host-autofocustest from feat: propagate <f-template> host attributes onto rendered host element #7521 had its URL re-pointed from/fixtures/host-bindings/(main path) to/fixtures/bindings/host/(v3 path).examples/csr/todo-mobx-appis bumped from@microsoft/fast-element@^2.10.4to^3.0.0-rc.1so the example consumes the in-repo v3 build..github/copilot-instructions.mdis updated so the SSR bullet forwebui-todo-appdescribes v3'sdeclarativeTemplate()+enableHydration()flow instead of the fast-html hydration plugin it used on main.change/@microsoft-fast-html-*.jsonfiles from feat: propagate <f-template> host attributes onto rendered host element #7521 and feat(examples): unified todo apps with SSR, MobX, and E2E suite #7424 were dropped (the package no longer exists on v3).crates/microsoft-fast-build/DESIGN.mdwas hand-merged to use v3'sdata-fe="N"/<!--fe:b-->marker style instead of main'sdata-fe-c-{start}-{count}/<!--fe-b$$start$$...$$fe-b-->format. The corresponding Rust changes indirective.rs/locator.rswere auto-merged and confirmed to continue emitting v3-style markers.package-lock.jsonwas regenerated after the adaptation commit so the lockfile reflects the v3 workspace set (including the two ported SSR examples) and the bumpedtodo-mobx-appdependency.Follow-up commits on this branch
fix(examples): set useDefineForClassFields=false in csr/todo-app— without this, vite/esbuild defaulted to TS'starget: ES2022 + experimentalDecoratorssemantics, installing instance own-properties for@observablefields that shadowed the prototype getters/setters, breaking two-way binding (warning: "View=>Model update skipped. To use twoWay binding, the target property must be observable.").feat(examples): port SSR examples to v3 declarative + hydration pattern— re-adds the two SSR example apps removed by the adaptation commit (now ported to v3 patterns described above), restores thessr-webui-todoPlaywright project, and includes drive-by v3 fixes forcsr/todo-mobx-appso its e2e tests pass on this branch:compose()is now async and must be awaited;twoWaymoved from@microsoft/fast-element/binding/two-way.jsto@microsoft/fast-element/two-way.js; tsconfig bumped from ES2020 to ES2022 so the new top-level await type-checks.fix(fast-element): make declarativeTemplate() generic over the element constructor—declarativeTemplate()previously returned a non-genericFASTElementTemplateResolver(defaulting toFASTElementTemplateResolver<Constructable<HTMLElement>>), which mismatched theFASTElementTemplateResolver<typeof MyElement>expected byMyElement.define({ template: … }, [observerMap()])under tsgo/noImplicitThis. The signature now takes<TType extends Constructable<HTMLElement>>so the returned resolver narrows at the call site, and the consumer-facingas anyworkarounds in the SSR examples are removed.Notes for reviewers
tsgo(TypeScript Go preview compiler) initially mis-resolved thedefine<TType extends Constructable<HTMLElement>>(this: TType, …)overload from@microsoft/fast-element/fast-element.jswhen invoked asMyElement.define({ template: declarativeTemplate(), … }, [observerMap()]). The root cause was thatdeclarativeTemplate()returned a non-genericFASTElementTemplateResolver, so its return type was wider than theFASTElementTemplateResolver<typeof MyElement>expected bydefine'stemplatefield. The follow-upfix(fast-element)commit on this branch makesdeclarativeTemplategeneric overTType extends Constructable<HTMLElement>, which restores correct overload resolution under tsgo without any consumer-side casts.📑 Test Plan
Run from the monorepo root on this branch:
npm run build— all v3 workspaces build successfully (fast-build,fast-element,fast-router,fast-test-harness,fast-site,todo-app,todo-mobx-app,chat-app,webui-todo-app).npm run build -w @microsoft/fast-chat-app-example— succeeds.npm run build -w @microsoft/fast-webui-todo-app-example— succeeds.npm run build -w @microsoft/fast-todo-mobx-app-example— succeeds.cd examples/test && npm run test:e2e— 21/21 specs pass (csr-todo: 7/7,csr-todo-mobx: 7/7,ssr-webui-todo: 7/7).npm run test:chromium— passes for@microsoft/fast-element(1410 chromium + 176 declarative chromium tests),@microsoft/fast-test-harness(43 chromium tests + node unit tests), plus router/build tests.npm run biome:check— clean.npm run checkchange— passes; the existing change files on this branch cover the modifiedpackages/*workspaces.✅ Checklist
General
$ npm run change⏭ Next Steps
beachball publish) once this lands so the v3 prerelease versions pick up the cherry-picked features.maincommits the same way; the adaptation patterns (fast-html → declarative subpaths, marker style,--plugin=fast-v3for webui SSR) are documented in the adaptation commit message and this PR description.