From 3be13d11f3b972171aa0417e3661f32b757a3cb0 Mon Sep 17 00:00:00 2001 From: Damian Pieczynski Date: Tue, 28 Jul 2026 14:47:15 +0200 Subject: [PATCH 1/3] fix(marko-virtual): consolidate Marko e2e into one in-package app, fix test --- .changeset/marko-e2e-consolidation.md | 12 + .gitignore | 5 +- .../marko/chat-pretext/.marko-run/routes.d.ts | 82 --- examples/marko/chat-pretext/e2e/README.md | 17 - examples/marko/chat-pretext/package.json | 2 - .../marko/chat-pretext/playwright.config.ts | 31 - examples/marko/chat-pretext/tsconfig.json | 2 - examples/marko/chat/.marko-run/routes.d.ts | 82 --- examples/marko/chat/e2e/README.md | 14 - examples/marko/chat/package.json | 2 - examples/marko/chat/playwright.config.ts | 31 - examples/marko/chat/tsconfig.json | 2 - examples/marko/dynamic/.marko-run/routes.d.ts | 53 -- examples/marko/dynamic/package.json | 2 - examples/marko/dynamic/playwright.config.ts | 31 - examples/marko/dynamic/tsconfig.json | 2 - examples/marko/fixed/.marko-run/routes.d.ts | 53 -- examples/marko/fixed/package.json | 2 - examples/marko/fixed/playwright.config.ts | 31 - examples/marko/fixed/tsconfig.json | 2 - examples/marko/grid/.marko-run/routes.d.ts | 53 -- examples/marko/grid/package.json | 2 - examples/marko/grid/playwright.config.ts | 31 - examples/marko/grid/tsconfig.json | 2 - .../infinite-scroll/.marko-run/routes.d.ts | 53 -- examples/marko/infinite-scroll/package.json | 2 - .../infinite-scroll/playwright.config.ts | 31 - examples/marko/infinite-scroll/tsconfig.json | 2 - examples/marko/padding/.marko-run/routes.d.ts | 53 -- examples/marko/padding/package.json | 2 - examples/marko/padding/playwright.config.ts | 31 - examples/marko/padding/tsconfig.json | 2 - examples/marko/pretext/.marko-run/routes.d.ts | 53 -- examples/marko/pretext/package.json | 2 - examples/marko/pretext/playwright.config.ts | 31 - examples/marko/pretext/tsconfig.json | 2 - .../scroll-padding/.marko-run/routes.d.ts | 53 -- examples/marko/scroll-padding/package.json | 2 - .../marko/scroll-padding/playwright.config.ts | 31 - examples/marko/scroll-padding/tsconfig.json | 2 - .../smooth-scroll/.marko-run/routes.d.ts | 53 -- examples/marko/smooth-scroll/package.json | 2 - .../marko/smooth-scroll/playwright.config.ts | 31 - examples/marko/smooth-scroll/tsconfig.json | 2 - .../marko/ssr-fetch/.marko-run/routes.d.ts | 53 -- examples/marko/ssr-fetch/package.json | 2 - examples/marko/ssr-fetch/playwright.config.ts | 31 - examples/marko/ssr-fetch/tsconfig.json | 2 - .../marko/ssr-restore/.marko-run/routes.d.ts | 53 -- examples/marko/ssr-restore/package.json | 2 - .../marko/ssr-restore/playwright.config.ts | 31 - examples/marko/ssr-restore/tsconfig.json | 2 - .../marko/ssr-slice/.marko-run/routes.d.ts | 53 -- examples/marko/ssr-slice/package.json | 2 - examples/marko/ssr-slice/playwright.config.ts | 31 - examples/marko/ssr-slice/tsconfig.json | 2 - examples/marko/ssr/.marko-run/routes.d.ts | 53 -- examples/marko/ssr/package.json | 2 - examples/marko/ssr/playwright.config.ts | 31 - examples/marko/ssr/tsconfig.json | 2 - examples/marko/sticky/.marko-run/routes.d.ts | 53 -- examples/marko/sticky/package.json | 2 - examples/marko/sticky/playwright.config.ts | 31 - examples/marko/sticky/tsconfig.json | 2 - examples/marko/table/.marko-run/routes.d.ts | 53 -- examples/marko/table/package.json | 2 - examples/marko/table/playwright.config.ts | 31 - examples/marko/table/tsconfig.json | 2 - .../marko/variable/.marko-run/routes.d.ts | 53 -- examples/marko/variable/package.json | 2 - examples/marko/variable/playwright.config.ts | 31 - examples/marko/variable/tsconfig.json | 2 - .../window-ssr-slice/.marko-run/routes.d.ts | 53 -- examples/marko/window-ssr-slice/package.json | 2 - .../window-ssr-slice/playwright.config.ts | 31 - examples/marko/window-ssr-slice/tsconfig.json | 2 - examples/marko/window/.marko-run/routes.d.ts | 53 -- examples/marko/window/package.json | 2 - examples/marko/window/playwright.config.ts | 31 - examples/marko/window/tsconfig.json | 2 - nx.json | 9 + packages/angular-virtual/package.json | 2 +- packages/angular-virtual/playwright.config.ts | 3 + packages/marko-virtual/e2e/app/README.md | 83 +++ .../e2e/app}/e2e/chat-pretext.spec.ts | 47 +- .../marko-virtual/e2e/app}/e2e/chat.spec.ts | 43 +- .../e2e/app}/e2e/dynamic.spec.ts | 6 +- .../marko-virtual/e2e/app}/e2e/fixed.spec.ts | 6 +- .../marko-virtual/e2e/app}/e2e/grid.spec.ts | 4 +- .../e2e/app}/e2e/infinite-scroll.spec.ts | 6 +- .../e2e/option-gates.spec.ts | 21 +- .../e2e/app}/e2e/padding.spec.ts | 12 +- .../e2e/app}/e2e/pretext.spec.ts | 8 +- .../e2e/app}/e2e/scroll-padding.spec.ts | 6 +- .../e2e/app}/e2e/smooth-scroll.spec.ts | 4 +- .../e2e/app}/e2e/ssr-fetch.spec.ts | 4 +- .../e2e/app}/e2e/ssr-restore.spec.ts | 8 +- .../e2e/app}/e2e/ssr-slice.spec.ts | 27 +- .../marko-virtual/e2e/app}/e2e/ssr.spec.ts | 4 +- .../marko-virtual/e2e/app}/e2e/sticky.spec.ts | 8 +- .../marko-virtual/e2e/app}/e2e/table.spec.ts | 8 +- .../e2e/app}/e2e/variable.spec.ts | 6 +- .../e2e/app}/e2e/window-ssr-slice.spec.ts | 6 +- .../marko-virtual/e2e/app}/e2e/window.spec.ts | 6 +- .../e2e/{option-gates => app}/marko.json | 0 .../e2e/{option-gates => app}/package.json | 18 +- .../e2e/app/playwright.config.ts | 52 ++ .../src/routes/+page.marko | 0 .../e2e/app/src/routes/api/reply/+handler.ts | 5 + .../src/routes/cached/+page.marko | 0 .../app/src/routes/chat-pretext/+page.marko | 2 + .../e2e/app/src/routes/chat/+page.marko | 2 + .../src/routes/debug/+page.marko | 0 .../e2e/app/src/routes/dynamic/+page.marko | 2 + .../src/routes/enabled/+page.marko | 0 .../e2e/app/src/routes/fixed/+page.marko | 2 + .../e2e/app/src/routes/grid/+page.marko | 2 + .../src/routes/infinite-scroll/+page.marko | 2 + .../src/routes/lanes-mode/+page.marko | 0 .../src/routes/measure-element/+page.marko | 0 .../e2e/app/src/routes/padding/+page.marko | 2 + .../e2e/app/src/routes/pretext/+page.marko | 2 + .../src/routes/rtl/+page.marko | 0 .../src/routes/scroll-events/+page.marko | 0 .../src/routes/scroll-margin/+page.marko | 0 .../app/src/routes/scroll-padding/+page.marko | 2 + .../app/src/routes/smooth-scroll/+page.marko | 2 + .../e2e/app/src/routes/ssr-fetch/+page.marko | 2 + .../app/src/routes/ssr-restore/+page.marko | 2 + .../e2e/app/src/routes/ssr-slice/+page.marko | 2 + .../e2e/app/src/routes/ssr/+page.marko | 2 + .../e2e/app/src/routes/sticky/+page.marko | 2 + .../e2e/app/src/routes/table/+page.marko | 2 + .../e2e/app/src/routes/variable/+page.marko | 2 + .../src/routes/window-example/+page.marko | 0 .../src/routes/window-horizontal/+page.marko | 0 .../routes/window-initial-offset/+page.marko | 0 .../src/routes/window-ssr-slice/+page.marko | 2 + .../e2e/app/src/routes/window/+page.marko | 2 + .../e2e/{option-gates => app}/tsconfig.json | 3 +- packages/marko-virtual/e2e/app/vite.config.ts | 26 + .../e2e/option-gates/.marko-run/routes.d.ts | 372 ----------- .../marko-virtual/e2e/option-gates/README.md | 40 -- .../e2e/option-gates/playwright.config.ts | 21 - .../e2e/option-gates/vite.config.ts | 17 - packages/marko-virtual/package.json | 2 +- packages/marko-virtual/tests/options.test.ts | 30 +- packages/react-virtual/package.json | 2 +- packages/react-virtual/playwright.config.ts | 13 +- pnpm-lock.yaml | 581 +++++++++++------- 150 files changed, 781 insertions(+), 2554 deletions(-) create mode 100644 .changeset/marko-e2e-consolidation.md delete mode 100644 examples/marko/chat-pretext/.marko-run/routes.d.ts delete mode 100644 examples/marko/chat-pretext/e2e/README.md delete mode 100644 examples/marko/chat-pretext/playwright.config.ts delete mode 100644 examples/marko/chat/.marko-run/routes.d.ts delete mode 100644 examples/marko/chat/e2e/README.md delete mode 100644 examples/marko/chat/playwright.config.ts delete mode 100644 examples/marko/dynamic/.marko-run/routes.d.ts delete mode 100644 examples/marko/dynamic/playwright.config.ts delete mode 100644 examples/marko/fixed/.marko-run/routes.d.ts delete mode 100644 examples/marko/fixed/playwright.config.ts delete mode 100644 examples/marko/grid/.marko-run/routes.d.ts delete mode 100644 examples/marko/grid/playwright.config.ts delete mode 100644 examples/marko/infinite-scroll/.marko-run/routes.d.ts delete mode 100644 examples/marko/infinite-scroll/playwright.config.ts delete mode 100644 examples/marko/padding/.marko-run/routes.d.ts delete mode 100644 examples/marko/padding/playwright.config.ts delete mode 100644 examples/marko/pretext/.marko-run/routes.d.ts delete mode 100644 examples/marko/pretext/playwright.config.ts delete mode 100644 examples/marko/scroll-padding/.marko-run/routes.d.ts delete mode 100644 examples/marko/scroll-padding/playwright.config.ts delete mode 100644 examples/marko/smooth-scroll/.marko-run/routes.d.ts delete mode 100644 examples/marko/smooth-scroll/playwright.config.ts delete mode 100644 examples/marko/ssr-fetch/.marko-run/routes.d.ts delete mode 100644 examples/marko/ssr-fetch/playwright.config.ts delete mode 100644 examples/marko/ssr-restore/.marko-run/routes.d.ts delete mode 100644 examples/marko/ssr-restore/playwright.config.ts delete mode 100644 examples/marko/ssr-slice/.marko-run/routes.d.ts delete mode 100644 examples/marko/ssr-slice/playwright.config.ts delete mode 100644 examples/marko/ssr/.marko-run/routes.d.ts delete mode 100644 examples/marko/ssr/playwright.config.ts delete mode 100644 examples/marko/sticky/.marko-run/routes.d.ts delete mode 100644 examples/marko/sticky/playwright.config.ts delete mode 100644 examples/marko/table/.marko-run/routes.d.ts delete mode 100644 examples/marko/table/playwright.config.ts delete mode 100644 examples/marko/variable/.marko-run/routes.d.ts delete mode 100644 examples/marko/variable/playwright.config.ts delete mode 100644 examples/marko/window-ssr-slice/.marko-run/routes.d.ts delete mode 100644 examples/marko/window-ssr-slice/playwright.config.ts delete mode 100644 examples/marko/window/.marko-run/routes.d.ts delete mode 100644 examples/marko/window/playwright.config.ts create mode 100644 packages/marko-virtual/e2e/app/README.md rename {examples/marko/chat-pretext => packages/marko-virtual/e2e/app}/e2e/chat-pretext.spec.ts (89%) rename {examples/marko/chat => packages/marko-virtual/e2e/app}/e2e/chat.spec.ts (86%) rename {examples/marko/dynamic => packages/marko-virtual/e2e/app}/e2e/dynamic.spec.ts (97%) rename {examples/marko/fixed => packages/marko-virtual/e2e/app}/e2e/fixed.spec.ts (97%) rename {examples/marko/grid => packages/marko-virtual/e2e/app}/e2e/grid.spec.ts (97%) rename {examples/marko/infinite-scroll => packages/marko-virtual/e2e/app}/e2e/infinite-scroll.spec.ts (96%) rename packages/marko-virtual/e2e/{option-gates => app}/e2e/option-gates.spec.ts (94%) rename {examples/marko/padding => packages/marko-virtual/e2e/app}/e2e/padding.spec.ts (96%) rename {examples/marko/pretext => packages/marko-virtual/e2e/app}/e2e/pretext.spec.ts (97%) rename {examples/marko/scroll-padding => packages/marko-virtual/e2e/app}/e2e/scroll-padding.spec.ts (96%) rename {examples/marko/smooth-scroll => packages/marko-virtual/e2e/app}/e2e/smooth-scroll.spec.ts (96%) rename {examples/marko/ssr-fetch => packages/marko-virtual/e2e/app}/e2e/ssr-fetch.spec.ts (97%) rename {examples/marko/ssr-restore => packages/marko-virtual/e2e/app}/e2e/ssr-restore.spec.ts (96%) rename {examples/marko/ssr-slice => packages/marko-virtual/e2e/app}/e2e/ssr-slice.spec.ts (86%) rename {examples/marko/ssr => packages/marko-virtual/e2e/app}/e2e/ssr.spec.ts (97%) rename {examples/marko/sticky => packages/marko-virtual/e2e/app}/e2e/sticky.spec.ts (97%) rename {examples/marko/table => packages/marko-virtual/e2e/app}/e2e/table.spec.ts (98%) rename {examples/marko/variable => packages/marko-virtual/e2e/app}/e2e/variable.spec.ts (96%) rename {examples/marko/window-ssr-slice => packages/marko-virtual/e2e/app}/e2e/window-ssr-slice.spec.ts (96%) rename {examples/marko/window => packages/marko-virtual/e2e/app}/e2e/window.spec.ts (97%) rename packages/marko-virtual/e2e/{option-gates => app}/marko.json (100%) rename packages/marko-virtual/e2e/{option-gates => app}/package.json (53%) create mode 100644 packages/marko-virtual/e2e/app/playwright.config.ts rename packages/marko-virtual/e2e/{option-gates => app}/src/routes/+page.marko (100%) create mode 100644 packages/marko-virtual/e2e/app/src/routes/api/reply/+handler.ts rename packages/marko-virtual/e2e/{option-gates => app}/src/routes/cached/+page.marko (100%) create mode 100644 packages/marko-virtual/e2e/app/src/routes/chat-pretext/+page.marko create mode 100644 packages/marko-virtual/e2e/app/src/routes/chat/+page.marko rename packages/marko-virtual/e2e/{option-gates => app}/src/routes/debug/+page.marko (100%) create mode 100644 packages/marko-virtual/e2e/app/src/routes/dynamic/+page.marko rename packages/marko-virtual/e2e/{option-gates => app}/src/routes/enabled/+page.marko (100%) create mode 100644 packages/marko-virtual/e2e/app/src/routes/fixed/+page.marko create mode 100644 packages/marko-virtual/e2e/app/src/routes/grid/+page.marko create mode 100644 packages/marko-virtual/e2e/app/src/routes/infinite-scroll/+page.marko rename packages/marko-virtual/e2e/{option-gates => app}/src/routes/lanes-mode/+page.marko (100%) rename packages/marko-virtual/e2e/{option-gates => app}/src/routes/measure-element/+page.marko (100%) create mode 100644 packages/marko-virtual/e2e/app/src/routes/padding/+page.marko create mode 100644 packages/marko-virtual/e2e/app/src/routes/pretext/+page.marko rename packages/marko-virtual/e2e/{option-gates => app}/src/routes/rtl/+page.marko (100%) rename packages/marko-virtual/e2e/{option-gates => app}/src/routes/scroll-events/+page.marko (100%) rename packages/marko-virtual/e2e/{option-gates => app}/src/routes/scroll-margin/+page.marko (100%) create mode 100644 packages/marko-virtual/e2e/app/src/routes/scroll-padding/+page.marko create mode 100644 packages/marko-virtual/e2e/app/src/routes/smooth-scroll/+page.marko create mode 100644 packages/marko-virtual/e2e/app/src/routes/ssr-fetch/+page.marko create mode 100644 packages/marko-virtual/e2e/app/src/routes/ssr-restore/+page.marko create mode 100644 packages/marko-virtual/e2e/app/src/routes/ssr-slice/+page.marko create mode 100644 packages/marko-virtual/e2e/app/src/routes/ssr/+page.marko create mode 100644 packages/marko-virtual/e2e/app/src/routes/sticky/+page.marko create mode 100644 packages/marko-virtual/e2e/app/src/routes/table/+page.marko create mode 100644 packages/marko-virtual/e2e/app/src/routes/variable/+page.marko rename packages/marko-virtual/e2e/{option-gates => app}/src/routes/window-example/+page.marko (100%) rename packages/marko-virtual/e2e/{option-gates => app}/src/routes/window-horizontal/+page.marko (100%) rename packages/marko-virtual/e2e/{option-gates => app}/src/routes/window-initial-offset/+page.marko (100%) create mode 100644 packages/marko-virtual/e2e/app/src/routes/window-ssr-slice/+page.marko create mode 100644 packages/marko-virtual/e2e/app/src/routes/window/+page.marko rename packages/marko-virtual/e2e/{option-gates => app}/tsconfig.json (85%) create mode 100644 packages/marko-virtual/e2e/app/vite.config.ts delete mode 100644 packages/marko-virtual/e2e/option-gates/.marko-run/routes.d.ts delete mode 100644 packages/marko-virtual/e2e/option-gates/README.md delete mode 100644 packages/marko-virtual/e2e/option-gates/playwright.config.ts delete mode 100644 packages/marko-virtual/e2e/option-gates/vite.config.ts diff --git a/.changeset/marko-e2e-consolidation.md b/.changeset/marko-e2e-consolidation.md new file mode 100644 index 000000000..fcf8c26d3 --- /dev/null +++ b/.changeset/marko-e2e-consolidation.md @@ -0,0 +1,12 @@ +--- +'@tanstack/marko-virtual': patch +--- + +Stop publishing the tags build's incremental state: `marko-type-check` writes +`dist/tsconfig.tags.tsbuildinfo`, which the `files` field shipped to npm and nx +cached as part of `dist`. Because `@marko/type-check` always runs incrementally, a +`dist` that carried that file but not `dist/tags` (which `marko.json` points at) +made every subsequent build a silent no-op — exit 0, nothing emitted — and any +consumer then failed to compile with +`ENOENT: no such file or directory, scandir '.../dist/tags'`. The build now removes +the file after emitting, so a build always produces `dist/tags`. diff --git a/.gitignore b/.gitignore index 8b0d0de9e..36fee5501 100644 --- a/.gitignore +++ b/.gitignore @@ -46,4 +46,7 @@ vite.config.ts.timestamp-* test-results/ playwright-report/ *.log -**/*.tsbuildinfo \ No newline at end of file +**/*.tsbuildinfo + +# Marko Run generated route types +.marko-run/ diff --git a/examples/marko/chat-pretext/.marko-run/routes.d.ts b/examples/marko/chat-pretext/.marko-run/routes.d.ts deleted file mode 100644 index 89bb36bd6..000000000 --- a/examples/marko/chat-pretext/.marko-run/routes.d.ts +++ /dev/null @@ -1,82 +0,0 @@ -/* - WARNING: This file is automatically generated and any changes made to it will be overwritten without warning. - Do NOT manually edit this file or your changes will be lost. -*/ - -import { - NotHandled, - NotMatched, - GetPaths, - PostPaths, - GetablePath, - GetableHref, - PostablePath, - PostableHref, - Platform, -} from '@marko/run/namespace' -import type * as Run from '@marko/run' - -declare module '@marko/run' { - interface AppData extends Run.DefineApp<{ - routes: { - '/': { verb: 'get' } - '/api/reply': { verb: 'post' } - } - }> {} -} - -declare module '../src/routes/api/reply/+handler' { - namespace MarkoRun { - export { - NotHandled, - NotMatched, - GetPaths, - PostPaths, - GetablePath, - GetableHref, - PostablePath, - PostableHref, - Platform, - } - export type Route = Run.Routes['/api/reply'] - export type Context = Run.MultiRouteContext - export type Handler = Run.HandlerLike - export type GET = Run.HandlerLike - export type HEAD = Run.HandlerLike - export type POST = Run.HandlerLike - export type PUT = Run.HandlerLike - export type DELETE = Run.HandlerLike - export type PATCH = Run.HandlerLike - export type OPTIONS = Run.HandlerLike - /** @deprecated use `((context, next) => { ... }) satisfies MarkoRun.Handler` instead */ - export const route: Run.HandlerTypeFn - } -} - -declare module '../src/routes/+page.marko' { - namespace MarkoRun { - export { - NotHandled, - NotMatched, - GetPaths, - PostPaths, - GetablePath, - GetableHref, - PostablePath, - PostableHref, - Platform, - } - export type Route = Run.Routes['/'] - export type Context = Run.MultiRouteContext & Marko.Global - export type Handler = Run.HandlerLike - export type GET = Run.HandlerLike - export type HEAD = Run.HandlerLike - export type POST = Run.HandlerLike - export type PUT = Run.HandlerLike - export type DELETE = Run.HandlerLike - export type PATCH = Run.HandlerLike - export type OPTIONS = Run.HandlerLike - /** @deprecated use `((context, next) => { ... }) satisfies MarkoRun.Handler` instead */ - export const route: Run.HandlerTypeFn - } -} diff --git a/examples/marko/chat-pretext/e2e/README.md b/examples/marko/chat-pretext/e2e/README.md deleted file mode 100644 index 785422f27..000000000 --- a/examples/marko/chat-pretext/e2e/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# Chat + Pretext example — browser tests - -In the monorepo: install at the repo root as usual (`pnpm install` — the workspace -brings in this example's `@playwright/test` and `@chenglou/pretext` too). Then, from -this directory (examples/marko/chat-pretext): - - npx playwright install chromium # one-time browser download - npm run test:e2e # starts the dev server itself, runs 9 tests, tears down - -Standalone (this folder copied out of the monorepo): run `pnpm install` (or -`npm install`) inside the folder first, then the same two commands. - -The suite carries the Chat example's seven scroll-behavior gates (calculated heights -must not regress any of them) plus this example's two headline assertions: prepending -history produces NO measurement-correction kick (at most the single intended anchor -compensation), and the streamed reply's growth is delivered through v.resizeItem with -a calculated height that matches the rendered DOM within a pixel. diff --git a/examples/marko/chat-pretext/package.json b/examples/marko/chat-pretext/package.json index 21239ad0f..b465d0690 100644 --- a/examples/marko/chat-pretext/package.json +++ b/examples/marko/chat-pretext/package.json @@ -6,7 +6,6 @@ "dev": "marko-run dev", "build": "marko-run build", "preview": "marko-run preview", - "test:e2e": "playwright test", "test:types": "marko-type-check" }, "dependencies": { @@ -18,7 +17,6 @@ "devDependencies": { "@marko/language-tools": "^2.6.2", "@marko/type-check": "3.1.1", - "@playwright/test": "^1.53.1", "typescript": "5.9.3", "vite": "^6.4.2" } diff --git a/examples/marko/chat-pretext/playwright.config.ts b/examples/marko/chat-pretext/playwright.config.ts deleted file mode 100644 index 8a71d30d8..000000000 --- a/examples/marko/chat-pretext/playwright.config.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { defineConfig } from '@playwright/test' - -// Unique per-example port. CI runs several example e2e suites in parallel, so a -// port shared across examples collides: one suite claims it and the rest either -// fail to start ("port already used") or attach to a different example's app and -// then miss the elements they assert on. Override with MARKO_E2E_PORT to point a -// run at a manually started server. -const PORT = Number(process.env.MARKO_E2E_PORT ?? 4174) -const baseURL = `http://localhost:${PORT}` - -export default defineConfig({ - testDir: './e2e', - timeout: 30_000, - retries: 0, - workers: 1, - use: { - baseURL, - }, - webServer: { - command: `npm run dev -- --port ${PORT}`, - url: baseURL, - // Reuse a manually-started dev server (npm run dev -- --port 4174) if one is - // already up — simpler to debug; CI should start its own. - reuseExistingServer: !process.env.CI, - // Surface the dev server's output in the test terminal so a crashing or - // slow-compiling server is visible instead of a silent stall. - stdout: 'pipe', - stderr: 'pipe', - timeout: 120_000, - }, -}) diff --git a/examples/marko/chat-pretext/tsconfig.json b/examples/marko/chat-pretext/tsconfig.json index ec50a5679..5078ee1e1 100644 --- a/examples/marko/chat-pretext/tsconfig.json +++ b/examples/marko/chat-pretext/tsconfig.json @@ -13,8 +13,6 @@ }, "include": [ "src", - "e2e", - "playwright.config.ts", "vite.config.ts", "../../../packages/marko-virtual/src/tags/**/*" ] diff --git a/examples/marko/chat/.marko-run/routes.d.ts b/examples/marko/chat/.marko-run/routes.d.ts deleted file mode 100644 index 89bb36bd6..000000000 --- a/examples/marko/chat/.marko-run/routes.d.ts +++ /dev/null @@ -1,82 +0,0 @@ -/* - WARNING: This file is automatically generated and any changes made to it will be overwritten without warning. - Do NOT manually edit this file or your changes will be lost. -*/ - -import { - NotHandled, - NotMatched, - GetPaths, - PostPaths, - GetablePath, - GetableHref, - PostablePath, - PostableHref, - Platform, -} from '@marko/run/namespace' -import type * as Run from '@marko/run' - -declare module '@marko/run' { - interface AppData extends Run.DefineApp<{ - routes: { - '/': { verb: 'get' } - '/api/reply': { verb: 'post' } - } - }> {} -} - -declare module '../src/routes/api/reply/+handler' { - namespace MarkoRun { - export { - NotHandled, - NotMatched, - GetPaths, - PostPaths, - GetablePath, - GetableHref, - PostablePath, - PostableHref, - Platform, - } - export type Route = Run.Routes['/api/reply'] - export type Context = Run.MultiRouteContext - export type Handler = Run.HandlerLike - export type GET = Run.HandlerLike - export type HEAD = Run.HandlerLike - export type POST = Run.HandlerLike - export type PUT = Run.HandlerLike - export type DELETE = Run.HandlerLike - export type PATCH = Run.HandlerLike - export type OPTIONS = Run.HandlerLike - /** @deprecated use `((context, next) => { ... }) satisfies MarkoRun.Handler` instead */ - export const route: Run.HandlerTypeFn - } -} - -declare module '../src/routes/+page.marko' { - namespace MarkoRun { - export { - NotHandled, - NotMatched, - GetPaths, - PostPaths, - GetablePath, - GetableHref, - PostablePath, - PostableHref, - Platform, - } - export type Route = Run.Routes['/'] - export type Context = Run.MultiRouteContext & Marko.Global - export type Handler = Run.HandlerLike - export type GET = Run.HandlerLike - export type HEAD = Run.HandlerLike - export type POST = Run.HandlerLike - export type PUT = Run.HandlerLike - export type DELETE = Run.HandlerLike - export type PATCH = Run.HandlerLike - export type OPTIONS = Run.HandlerLike - /** @deprecated use `((context, next) => { ... }) satisfies MarkoRun.Handler` instead */ - export const route: Run.HandlerTypeFn - } -} diff --git a/examples/marko/chat/e2e/README.md b/examples/marko/chat/e2e/README.md deleted file mode 100644 index 5bd6de7d4..000000000 --- a/examples/marko/chat/e2e/README.md +++ /dev/null @@ -1,14 +0,0 @@ -# Chat example — browser tests - -In the monorepo: install at the repo root as usual (`pnpm install` — the workspace -brings in this example's `@playwright/test` too). Then, from this directory -(examples/marko/chat): - - npx playwright install chromium # one-time browser download - npm run test:e2e # starts the dev server itself, runs 7 tests, tears down - -Standalone (this folder copied out of the monorepo): run `pnpm install` (or -`npm install`) inside the folder first, then the same two commands. - -No separate server start needed: playwright.config.ts declares a webServer -(marko-run dev --port 4173) that Playwright boots and stops around the run. diff --git a/examples/marko/chat/package.json b/examples/marko/chat/package.json index e20584c76..2be05a9c8 100644 --- a/examples/marko/chat/package.json +++ b/examples/marko/chat/package.json @@ -6,7 +6,6 @@ "dev": "marko-run dev", "build": "marko-run build", "preview": "marko-run preview", - "test:e2e": "playwright test", "test:types": "marko-type-check" }, "dependencies": { @@ -17,7 +16,6 @@ "devDependencies": { "@marko/language-tools": "^2.6.2", "@marko/type-check": "3.1.1", - "@playwright/test": "^1.53.1", "typescript": "5.9.3", "vite": "^6.4.2" } diff --git a/examples/marko/chat/playwright.config.ts b/examples/marko/chat/playwright.config.ts deleted file mode 100644 index 7e07ec35f..000000000 --- a/examples/marko/chat/playwright.config.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { defineConfig } from '@playwright/test' - -// Unique per-example port. CI runs several example e2e suites in parallel, so a -// port shared across examples collides: one suite claims it and the rest either -// fail to start ("port already used") or attach to a different example's app and -// then miss the elements they assert on. Override with MARKO_E2E_PORT to point a -// run at a manually started server. -const PORT = Number(process.env.MARKO_E2E_PORT ?? 4173) -const baseURL = `http://localhost:${PORT}` - -export default defineConfig({ - testDir: './e2e', - timeout: 30_000, - retries: 0, - workers: 1, - use: { - baseURL, - }, - webServer: { - command: `npm run dev -- --port ${PORT}`, - url: baseURL, - // Reuse a manually-started dev server (npm run dev -- --port 4173) if one is - // already up — simpler to debug; CI should start its own. - reuseExistingServer: !process.env.CI, - // Surface the dev server's output in the test terminal so a crashing or - // slow-compiling server is visible instead of a silent stall. - stdout: 'pipe', - stderr: 'pipe', - timeout: 120_000, - }, -}) diff --git a/examples/marko/chat/tsconfig.json b/examples/marko/chat/tsconfig.json index ec50a5679..5078ee1e1 100644 --- a/examples/marko/chat/tsconfig.json +++ b/examples/marko/chat/tsconfig.json @@ -13,8 +13,6 @@ }, "include": [ "src", - "e2e", - "playwright.config.ts", "vite.config.ts", "../../../packages/marko-virtual/src/tags/**/*" ] diff --git a/examples/marko/dynamic/.marko-run/routes.d.ts b/examples/marko/dynamic/.marko-run/routes.d.ts deleted file mode 100644 index a122bc38a..000000000 --- a/examples/marko/dynamic/.marko-run/routes.d.ts +++ /dev/null @@ -1,53 +0,0 @@ -/* - WARNING: This file is automatically generated and any changes made to it will be overwritten without warning. - Do NOT manually edit this file or your changes will be lost. -*/ - -import { - NotHandled, - NotMatched, - GetPaths, - PostPaths, - GetablePath, - GetableHref, - PostablePath, - PostableHref, - Platform, -} from '@marko/run/namespace' -import type * as Run from '@marko/run' - -declare module '@marko/run' { - interface AppData extends Run.DefineApp<{ - routes: { - '/': { verb: 'get' } - } - }> {} -} - -declare module '../src/routes/+page.marko' { - namespace MarkoRun { - export { - NotHandled, - NotMatched, - GetPaths, - PostPaths, - GetablePath, - GetableHref, - PostablePath, - PostableHref, - Platform, - } - export type Route = Run.Routes['/'] - export type Context = Run.MultiRouteContext & Marko.Global - export type Handler = Run.HandlerLike - export type GET = Run.HandlerLike - export type HEAD = Run.HandlerLike - export type POST = Run.HandlerLike - export type PUT = Run.HandlerLike - export type DELETE = Run.HandlerLike - export type PATCH = Run.HandlerLike - export type OPTIONS = Run.HandlerLike - /** @deprecated use `((context, next) => { ... }) satisfies MarkoRun.Handler` instead */ - export const route: Run.HandlerTypeFn - } -} diff --git a/examples/marko/dynamic/package.json b/examples/marko/dynamic/package.json index bc39035d6..a46155048 100644 --- a/examples/marko/dynamic/package.json +++ b/examples/marko/dynamic/package.json @@ -6,7 +6,6 @@ "dev": "marko-run dev", "build": "marko-run build", "preview": "marko-run preview", - "test:e2e": "playwright test", "test:types": "marko-type-check" }, "dependencies": { @@ -17,7 +16,6 @@ "devDependencies": { "@marko/language-tools": "^2.6.2", "@marko/type-check": "3.1.1", - "@playwright/test": "^1.53.1", "typescript": "5.9.3", "vite": "^6.4.2" } diff --git a/examples/marko/dynamic/playwright.config.ts b/examples/marko/dynamic/playwright.config.ts deleted file mode 100644 index 48af65977..000000000 --- a/examples/marko/dynamic/playwright.config.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { defineConfig } from '@playwright/test' - -// Unique per-example port. CI runs several example e2e suites in parallel, so a -// port shared across examples collides: one suite claims it and the rest either -// fail to start ("port already used") or attach to a different example's app and -// then miss the elements they assert on. Override with MARKO_E2E_PORT to point a -// run at a manually started server. -const PORT = Number(process.env.MARKO_E2E_PORT ?? 4175) -const baseURL = `http://localhost:${PORT}` - -export default defineConfig({ - testDir: './e2e', - timeout: 30_000, - retries: 0, - workers: 1, - use: { - baseURL, - }, - webServer: { - command: `npm run dev -- --port ${PORT}`, - url: baseURL, - // Reuse a manually-started dev server (npm run dev -- --port 4175) if one is - // already up — simpler to debug; CI should start its own. - reuseExistingServer: !process.env.CI, - // Surface the dev server's output in the test terminal so a crashing or - // slow-compiling server is visible instead of a silent stall. - stdout: 'pipe', - stderr: 'pipe', - timeout: 120_000, - }, -}) diff --git a/examples/marko/dynamic/tsconfig.json b/examples/marko/dynamic/tsconfig.json index ec50a5679..5078ee1e1 100644 --- a/examples/marko/dynamic/tsconfig.json +++ b/examples/marko/dynamic/tsconfig.json @@ -13,8 +13,6 @@ }, "include": [ "src", - "e2e", - "playwright.config.ts", "vite.config.ts", "../../../packages/marko-virtual/src/tags/**/*" ] diff --git a/examples/marko/fixed/.marko-run/routes.d.ts b/examples/marko/fixed/.marko-run/routes.d.ts deleted file mode 100644 index a122bc38a..000000000 --- a/examples/marko/fixed/.marko-run/routes.d.ts +++ /dev/null @@ -1,53 +0,0 @@ -/* - WARNING: This file is automatically generated and any changes made to it will be overwritten without warning. - Do NOT manually edit this file or your changes will be lost. -*/ - -import { - NotHandled, - NotMatched, - GetPaths, - PostPaths, - GetablePath, - GetableHref, - PostablePath, - PostableHref, - Platform, -} from '@marko/run/namespace' -import type * as Run from '@marko/run' - -declare module '@marko/run' { - interface AppData extends Run.DefineApp<{ - routes: { - '/': { verb: 'get' } - } - }> {} -} - -declare module '../src/routes/+page.marko' { - namespace MarkoRun { - export { - NotHandled, - NotMatched, - GetPaths, - PostPaths, - GetablePath, - GetableHref, - PostablePath, - PostableHref, - Platform, - } - export type Route = Run.Routes['/'] - export type Context = Run.MultiRouteContext & Marko.Global - export type Handler = Run.HandlerLike - export type GET = Run.HandlerLike - export type HEAD = Run.HandlerLike - export type POST = Run.HandlerLike - export type PUT = Run.HandlerLike - export type DELETE = Run.HandlerLike - export type PATCH = Run.HandlerLike - export type OPTIONS = Run.HandlerLike - /** @deprecated use `((context, next) => { ... }) satisfies MarkoRun.Handler` instead */ - export const route: Run.HandlerTypeFn - } -} diff --git a/examples/marko/fixed/package.json b/examples/marko/fixed/package.json index 9b88af9da..ec16c9912 100644 --- a/examples/marko/fixed/package.json +++ b/examples/marko/fixed/package.json @@ -6,7 +6,6 @@ "dev": "marko-run dev", "build": "marko-run build", "preview": "marko-run preview", - "test:e2e": "playwright test", "test:types": "marko-type-check" }, "dependencies": { @@ -17,7 +16,6 @@ "devDependencies": { "@marko/language-tools": "^2.6.2", "@marko/type-check": "3.1.1", - "@playwright/test": "^1.53.1", "typescript": "5.9.3", "vite": "^6.4.2" } diff --git a/examples/marko/fixed/playwright.config.ts b/examples/marko/fixed/playwright.config.ts deleted file mode 100644 index ed7fa8d7a..000000000 --- a/examples/marko/fixed/playwright.config.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { defineConfig } from '@playwright/test' - -// Unique per-example port. CI runs several example e2e suites in parallel, so a -// port shared across examples collides: one suite claims it and the rest either -// fail to start ("port already used") or attach to a different example's app and -// then miss the elements they assert on. Override with MARKO_E2E_PORT to point a -// run at a manually started server. -const PORT = Number(process.env.MARKO_E2E_PORT ?? 4176) -const baseURL = `http://localhost:${PORT}` - -export default defineConfig({ - testDir: './e2e', - timeout: 30_000, - retries: 0, - workers: 1, - use: { - baseURL, - }, - webServer: { - command: `npm run dev -- --port ${PORT}`, - url: baseURL, - // Reuse a manually-started dev server (npm run dev -- --port 4176) if one is - // already up — simpler to debug; CI should start its own. - reuseExistingServer: !process.env.CI, - // Surface the dev server's output in the test terminal so a crashing or - // slow-compiling server is visible instead of a silent stall. - stdout: 'pipe', - stderr: 'pipe', - timeout: 120_000, - }, -}) diff --git a/examples/marko/fixed/tsconfig.json b/examples/marko/fixed/tsconfig.json index ec50a5679..5078ee1e1 100644 --- a/examples/marko/fixed/tsconfig.json +++ b/examples/marko/fixed/tsconfig.json @@ -13,8 +13,6 @@ }, "include": [ "src", - "e2e", - "playwright.config.ts", "vite.config.ts", "../../../packages/marko-virtual/src/tags/**/*" ] diff --git a/examples/marko/grid/.marko-run/routes.d.ts b/examples/marko/grid/.marko-run/routes.d.ts deleted file mode 100644 index a122bc38a..000000000 --- a/examples/marko/grid/.marko-run/routes.d.ts +++ /dev/null @@ -1,53 +0,0 @@ -/* - WARNING: This file is automatically generated and any changes made to it will be overwritten without warning. - Do NOT manually edit this file or your changes will be lost. -*/ - -import { - NotHandled, - NotMatched, - GetPaths, - PostPaths, - GetablePath, - GetableHref, - PostablePath, - PostableHref, - Platform, -} from '@marko/run/namespace' -import type * as Run from '@marko/run' - -declare module '@marko/run' { - interface AppData extends Run.DefineApp<{ - routes: { - '/': { verb: 'get' } - } - }> {} -} - -declare module '../src/routes/+page.marko' { - namespace MarkoRun { - export { - NotHandled, - NotMatched, - GetPaths, - PostPaths, - GetablePath, - GetableHref, - PostablePath, - PostableHref, - Platform, - } - export type Route = Run.Routes['/'] - export type Context = Run.MultiRouteContext & Marko.Global - export type Handler = Run.HandlerLike - export type GET = Run.HandlerLike - export type HEAD = Run.HandlerLike - export type POST = Run.HandlerLike - export type PUT = Run.HandlerLike - export type DELETE = Run.HandlerLike - export type PATCH = Run.HandlerLike - export type OPTIONS = Run.HandlerLike - /** @deprecated use `((context, next) => { ... }) satisfies MarkoRun.Handler` instead */ - export const route: Run.HandlerTypeFn - } -} diff --git a/examples/marko/grid/package.json b/examples/marko/grid/package.json index dbb60ace8..76c1d8fa2 100644 --- a/examples/marko/grid/package.json +++ b/examples/marko/grid/package.json @@ -6,7 +6,6 @@ "dev": "marko-run dev", "build": "marko-run build", "preview": "marko-run preview", - "test:e2e": "playwright test", "test:types": "marko-type-check" }, "dependencies": { @@ -17,7 +16,6 @@ "devDependencies": { "@marko/language-tools": "^2.6.2", "@marko/type-check": "3.1.1", - "@playwright/test": "^1.53.1", "typescript": "5.9.3", "vite": "^6.4.2" } diff --git a/examples/marko/grid/playwright.config.ts b/examples/marko/grid/playwright.config.ts deleted file mode 100644 index 27041ba8e..000000000 --- a/examples/marko/grid/playwright.config.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { defineConfig } from '@playwright/test' - -// Unique per-example port. CI runs several example e2e suites in parallel, so a -// port shared across examples collides: one suite claims it and the rest either -// fail to start ("port already used") or attach to a different example's app and -// then miss the elements they assert on. Override with MARKO_E2E_PORT to point a -// run at a manually started server. -const PORT = Number(process.env.MARKO_E2E_PORT ?? 4177) -const baseURL = `http://localhost:${PORT}` - -export default defineConfig({ - testDir: './e2e', - timeout: 30_000, - retries: 0, - workers: 1, - use: { - baseURL, - }, - webServer: { - command: `npm run dev -- --port ${PORT}`, - url: baseURL, - // Reuse a manually-started dev server (npm run dev -- --port 4177) if one is - // already up — simpler to debug; CI should start its own. - reuseExistingServer: !process.env.CI, - // Surface the dev server's output in the test terminal so a crashing or - // slow-compiling server is visible instead of a silent stall. - stdout: 'pipe', - stderr: 'pipe', - timeout: 120_000, - }, -}) diff --git a/examples/marko/grid/tsconfig.json b/examples/marko/grid/tsconfig.json index ec50a5679..5078ee1e1 100644 --- a/examples/marko/grid/tsconfig.json +++ b/examples/marko/grid/tsconfig.json @@ -13,8 +13,6 @@ }, "include": [ "src", - "e2e", - "playwright.config.ts", "vite.config.ts", "../../../packages/marko-virtual/src/tags/**/*" ] diff --git a/examples/marko/infinite-scroll/.marko-run/routes.d.ts b/examples/marko/infinite-scroll/.marko-run/routes.d.ts deleted file mode 100644 index a122bc38a..000000000 --- a/examples/marko/infinite-scroll/.marko-run/routes.d.ts +++ /dev/null @@ -1,53 +0,0 @@ -/* - WARNING: This file is automatically generated and any changes made to it will be overwritten without warning. - Do NOT manually edit this file or your changes will be lost. -*/ - -import { - NotHandled, - NotMatched, - GetPaths, - PostPaths, - GetablePath, - GetableHref, - PostablePath, - PostableHref, - Platform, -} from '@marko/run/namespace' -import type * as Run from '@marko/run' - -declare module '@marko/run' { - interface AppData extends Run.DefineApp<{ - routes: { - '/': { verb: 'get' } - } - }> {} -} - -declare module '../src/routes/+page.marko' { - namespace MarkoRun { - export { - NotHandled, - NotMatched, - GetPaths, - PostPaths, - GetablePath, - GetableHref, - PostablePath, - PostableHref, - Platform, - } - export type Route = Run.Routes['/'] - export type Context = Run.MultiRouteContext & Marko.Global - export type Handler = Run.HandlerLike - export type GET = Run.HandlerLike - export type HEAD = Run.HandlerLike - export type POST = Run.HandlerLike - export type PUT = Run.HandlerLike - export type DELETE = Run.HandlerLike - export type PATCH = Run.HandlerLike - export type OPTIONS = Run.HandlerLike - /** @deprecated use `((context, next) => { ... }) satisfies MarkoRun.Handler` instead */ - export const route: Run.HandlerTypeFn - } -} diff --git a/examples/marko/infinite-scroll/package.json b/examples/marko/infinite-scroll/package.json index 796ed24c3..889e3ed07 100644 --- a/examples/marko/infinite-scroll/package.json +++ b/examples/marko/infinite-scroll/package.json @@ -6,7 +6,6 @@ "dev": "marko-run dev", "build": "marko-run build", "preview": "marko-run preview", - "test:e2e": "playwright test", "test:types": "marko-type-check" }, "dependencies": { @@ -17,7 +16,6 @@ "devDependencies": { "@marko/language-tools": "^2.6.2", "@marko/type-check": "3.1.1", - "@playwright/test": "^1.53.1", "typescript": "5.9.3", "vite": "^6.4.2" } diff --git a/examples/marko/infinite-scroll/playwright.config.ts b/examples/marko/infinite-scroll/playwright.config.ts deleted file mode 100644 index 809cd036a..000000000 --- a/examples/marko/infinite-scroll/playwright.config.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { defineConfig } from '@playwright/test' - -// Unique per-example port. CI runs several example e2e suites in parallel, so a -// port shared across examples collides: one suite claims it and the rest either -// fail to start ("port already used") or attach to a different example's app and -// then miss the elements they assert on. Override with MARKO_E2E_PORT to point a -// run at a manually started server. -const PORT = Number(process.env.MARKO_E2E_PORT ?? 4178) -const baseURL = `http://localhost:${PORT}` - -export default defineConfig({ - testDir: './e2e', - timeout: 30_000, - retries: 0, - workers: 1, - use: { - baseURL, - }, - webServer: { - command: `npm run dev -- --port ${PORT}`, - url: baseURL, - // Reuse a manually-started dev server (npm run dev -- --port 4178) if one is - // already up — simpler to debug; CI should start its own. - reuseExistingServer: !process.env.CI, - // Surface the dev server's output in the test terminal so a crashing or - // slow-compiling server is visible instead of a silent stall. - stdout: 'pipe', - stderr: 'pipe', - timeout: 120_000, - }, -}) diff --git a/examples/marko/infinite-scroll/tsconfig.json b/examples/marko/infinite-scroll/tsconfig.json index ec50a5679..5078ee1e1 100644 --- a/examples/marko/infinite-scroll/tsconfig.json +++ b/examples/marko/infinite-scroll/tsconfig.json @@ -13,8 +13,6 @@ }, "include": [ "src", - "e2e", - "playwright.config.ts", "vite.config.ts", "../../../packages/marko-virtual/src/tags/**/*" ] diff --git a/examples/marko/padding/.marko-run/routes.d.ts b/examples/marko/padding/.marko-run/routes.d.ts deleted file mode 100644 index a122bc38a..000000000 --- a/examples/marko/padding/.marko-run/routes.d.ts +++ /dev/null @@ -1,53 +0,0 @@ -/* - WARNING: This file is automatically generated and any changes made to it will be overwritten without warning. - Do NOT manually edit this file or your changes will be lost. -*/ - -import { - NotHandled, - NotMatched, - GetPaths, - PostPaths, - GetablePath, - GetableHref, - PostablePath, - PostableHref, - Platform, -} from '@marko/run/namespace' -import type * as Run from '@marko/run' - -declare module '@marko/run' { - interface AppData extends Run.DefineApp<{ - routes: { - '/': { verb: 'get' } - } - }> {} -} - -declare module '../src/routes/+page.marko' { - namespace MarkoRun { - export { - NotHandled, - NotMatched, - GetPaths, - PostPaths, - GetablePath, - GetableHref, - PostablePath, - PostableHref, - Platform, - } - export type Route = Run.Routes['/'] - export type Context = Run.MultiRouteContext & Marko.Global - export type Handler = Run.HandlerLike - export type GET = Run.HandlerLike - export type HEAD = Run.HandlerLike - export type POST = Run.HandlerLike - export type PUT = Run.HandlerLike - export type DELETE = Run.HandlerLike - export type PATCH = Run.HandlerLike - export type OPTIONS = Run.HandlerLike - /** @deprecated use `((context, next) => { ... }) satisfies MarkoRun.Handler` instead */ - export const route: Run.HandlerTypeFn - } -} diff --git a/examples/marko/padding/package.json b/examples/marko/padding/package.json index dde590ed5..3f7387a67 100644 --- a/examples/marko/padding/package.json +++ b/examples/marko/padding/package.json @@ -6,7 +6,6 @@ "dev": "marko-run dev", "build": "marko-run build", "preview": "marko-run preview", - "test:e2e": "playwright test", "test:types": "marko-type-check" }, "dependencies": { @@ -17,7 +16,6 @@ "devDependencies": { "@marko/language-tools": "^2.6.2", "@marko/type-check": "3.1.1", - "@playwright/test": "^1.53.1", "typescript": "5.9.3", "vite": "^6.4.2" } diff --git a/examples/marko/padding/playwright.config.ts b/examples/marko/padding/playwright.config.ts deleted file mode 100644 index e5f4662ad..000000000 --- a/examples/marko/padding/playwright.config.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { defineConfig } from '@playwright/test' - -// Unique per-example port. CI runs several example e2e suites in parallel, so a -// port shared across examples collides: one suite claims it and the rest either -// fail to start ("port already used") or attach to a different example's app and -// then miss the elements they assert on. Override with MARKO_E2E_PORT to point a -// run at a manually started server. -const PORT = Number(process.env.MARKO_E2E_PORT ?? 4179) -const baseURL = `http://localhost:${PORT}` - -export default defineConfig({ - testDir: './e2e', - timeout: 30_000, - retries: 0, - workers: 1, - use: { - baseURL, - }, - webServer: { - command: `npm run dev -- --port ${PORT}`, - url: baseURL, - // Reuse a manually-started dev server (npm run dev -- --port 4179) if one is - // already up — simpler to debug; CI should start its own. - reuseExistingServer: !process.env.CI, - // Surface the dev server's output in the test terminal so a crashing or - // slow-compiling server is visible instead of a silent stall. - stdout: 'pipe', - stderr: 'pipe', - timeout: 120_000, - }, -}) diff --git a/examples/marko/padding/tsconfig.json b/examples/marko/padding/tsconfig.json index ec50a5679..5078ee1e1 100644 --- a/examples/marko/padding/tsconfig.json +++ b/examples/marko/padding/tsconfig.json @@ -13,8 +13,6 @@ }, "include": [ "src", - "e2e", - "playwright.config.ts", "vite.config.ts", "../../../packages/marko-virtual/src/tags/**/*" ] diff --git a/examples/marko/pretext/.marko-run/routes.d.ts b/examples/marko/pretext/.marko-run/routes.d.ts deleted file mode 100644 index a122bc38a..000000000 --- a/examples/marko/pretext/.marko-run/routes.d.ts +++ /dev/null @@ -1,53 +0,0 @@ -/* - WARNING: This file is automatically generated and any changes made to it will be overwritten without warning. - Do NOT manually edit this file or your changes will be lost. -*/ - -import { - NotHandled, - NotMatched, - GetPaths, - PostPaths, - GetablePath, - GetableHref, - PostablePath, - PostableHref, - Platform, -} from '@marko/run/namespace' -import type * as Run from '@marko/run' - -declare module '@marko/run' { - interface AppData extends Run.DefineApp<{ - routes: { - '/': { verb: 'get' } - } - }> {} -} - -declare module '../src/routes/+page.marko' { - namespace MarkoRun { - export { - NotHandled, - NotMatched, - GetPaths, - PostPaths, - GetablePath, - GetableHref, - PostablePath, - PostableHref, - Platform, - } - export type Route = Run.Routes['/'] - export type Context = Run.MultiRouteContext & Marko.Global - export type Handler = Run.HandlerLike - export type GET = Run.HandlerLike - export type HEAD = Run.HandlerLike - export type POST = Run.HandlerLike - export type PUT = Run.HandlerLike - export type DELETE = Run.HandlerLike - export type PATCH = Run.HandlerLike - export type OPTIONS = Run.HandlerLike - /** @deprecated use `((context, next) => { ... }) satisfies MarkoRun.Handler` instead */ - export const route: Run.HandlerTypeFn - } -} diff --git a/examples/marko/pretext/package.json b/examples/marko/pretext/package.json index dec5fe71b..7a90c4f19 100644 --- a/examples/marko/pretext/package.json +++ b/examples/marko/pretext/package.json @@ -6,7 +6,6 @@ "dev": "marko-run dev", "build": "marko-run build", "preview": "marko-run preview", - "test:e2e": "playwright test", "test:types": "marko-type-check" }, "dependencies": { @@ -18,7 +17,6 @@ "devDependencies": { "@marko/language-tools": "^2.6.2", "@marko/type-check": "3.1.1", - "@playwright/test": "^1.53.1", "typescript": "5.9.3", "vite": "^6.4.2" } diff --git a/examples/marko/pretext/playwright.config.ts b/examples/marko/pretext/playwright.config.ts deleted file mode 100644 index 88942bb2c..000000000 --- a/examples/marko/pretext/playwright.config.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { defineConfig } from '@playwright/test' - -// Unique per-example port. CI runs several example e2e suites in parallel, so a -// port shared across examples collides: one suite claims it and the rest either -// fail to start ("port already used") or attach to a different example's app and -// then miss the elements they assert on. Override with MARKO_E2E_PORT to point a -// run at a manually started server. -const PORT = Number(process.env.MARKO_E2E_PORT ?? 4180) -const baseURL = `http://localhost:${PORT}` - -export default defineConfig({ - testDir: './e2e', - timeout: 30_000, - retries: 0, - workers: 1, - use: { - baseURL, - }, - webServer: { - command: `npm run dev -- --port ${PORT}`, - url: baseURL, - // Reuse a manually-started dev server (npm run dev -- --port 4180) if one is - // already up — simpler to debug; CI should start its own. - reuseExistingServer: !process.env.CI, - // Surface the dev server's output in the test terminal so a crashing or - // slow-compiling server is visible instead of a silent stall. - stdout: 'pipe', - stderr: 'pipe', - timeout: 120_000, - }, -}) diff --git a/examples/marko/pretext/tsconfig.json b/examples/marko/pretext/tsconfig.json index ec50a5679..5078ee1e1 100644 --- a/examples/marko/pretext/tsconfig.json +++ b/examples/marko/pretext/tsconfig.json @@ -13,8 +13,6 @@ }, "include": [ "src", - "e2e", - "playwright.config.ts", "vite.config.ts", "../../../packages/marko-virtual/src/tags/**/*" ] diff --git a/examples/marko/scroll-padding/.marko-run/routes.d.ts b/examples/marko/scroll-padding/.marko-run/routes.d.ts deleted file mode 100644 index a122bc38a..000000000 --- a/examples/marko/scroll-padding/.marko-run/routes.d.ts +++ /dev/null @@ -1,53 +0,0 @@ -/* - WARNING: This file is automatically generated and any changes made to it will be overwritten without warning. - Do NOT manually edit this file or your changes will be lost. -*/ - -import { - NotHandled, - NotMatched, - GetPaths, - PostPaths, - GetablePath, - GetableHref, - PostablePath, - PostableHref, - Platform, -} from '@marko/run/namespace' -import type * as Run from '@marko/run' - -declare module '@marko/run' { - interface AppData extends Run.DefineApp<{ - routes: { - '/': { verb: 'get' } - } - }> {} -} - -declare module '../src/routes/+page.marko' { - namespace MarkoRun { - export { - NotHandled, - NotMatched, - GetPaths, - PostPaths, - GetablePath, - GetableHref, - PostablePath, - PostableHref, - Platform, - } - export type Route = Run.Routes['/'] - export type Context = Run.MultiRouteContext & Marko.Global - export type Handler = Run.HandlerLike - export type GET = Run.HandlerLike - export type HEAD = Run.HandlerLike - export type POST = Run.HandlerLike - export type PUT = Run.HandlerLike - export type DELETE = Run.HandlerLike - export type PATCH = Run.HandlerLike - export type OPTIONS = Run.HandlerLike - /** @deprecated use `((context, next) => { ... }) satisfies MarkoRun.Handler` instead */ - export const route: Run.HandlerTypeFn - } -} diff --git a/examples/marko/scroll-padding/package.json b/examples/marko/scroll-padding/package.json index 6e5d320ca..049c565ae 100644 --- a/examples/marko/scroll-padding/package.json +++ b/examples/marko/scroll-padding/package.json @@ -6,7 +6,6 @@ "dev": "marko-run dev", "build": "marko-run build", "preview": "marko-run preview", - "test:e2e": "playwright test", "test:types": "marko-type-check" }, "dependencies": { @@ -17,7 +16,6 @@ "devDependencies": { "@marko/language-tools": "^2.6.2", "@marko/type-check": "3.1.1", - "@playwright/test": "^1.53.1", "typescript": "5.9.3", "vite": "^6.4.2" } diff --git a/examples/marko/scroll-padding/playwright.config.ts b/examples/marko/scroll-padding/playwright.config.ts deleted file mode 100644 index 9bcdd472c..000000000 --- a/examples/marko/scroll-padding/playwright.config.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { defineConfig } from '@playwright/test' - -// Unique per-example port. CI runs several example e2e suites in parallel, so a -// port shared across examples collides: one suite claims it and the rest either -// fail to start ("port already used") or attach to a different example's app and -// then miss the elements they assert on. Override with MARKO_E2E_PORT to point a -// run at a manually started server. -const PORT = Number(process.env.MARKO_E2E_PORT ?? 4181) -const baseURL = `http://localhost:${PORT}` - -export default defineConfig({ - testDir: './e2e', - timeout: 30_000, - retries: 0, - workers: 1, - use: { - baseURL, - }, - webServer: { - command: `npm run dev -- --port ${PORT}`, - url: baseURL, - // Reuse a manually-started dev server (npm run dev -- --port 4181) if one is - // already up — simpler to debug; CI should start its own. - reuseExistingServer: !process.env.CI, - // Surface the dev server's output in the test terminal so a crashing or - // slow-compiling server is visible instead of a silent stall. - stdout: 'pipe', - stderr: 'pipe', - timeout: 120_000, - }, -}) diff --git a/examples/marko/scroll-padding/tsconfig.json b/examples/marko/scroll-padding/tsconfig.json index ec50a5679..5078ee1e1 100644 --- a/examples/marko/scroll-padding/tsconfig.json +++ b/examples/marko/scroll-padding/tsconfig.json @@ -13,8 +13,6 @@ }, "include": [ "src", - "e2e", - "playwright.config.ts", "vite.config.ts", "../../../packages/marko-virtual/src/tags/**/*" ] diff --git a/examples/marko/smooth-scroll/.marko-run/routes.d.ts b/examples/marko/smooth-scroll/.marko-run/routes.d.ts deleted file mode 100644 index a122bc38a..000000000 --- a/examples/marko/smooth-scroll/.marko-run/routes.d.ts +++ /dev/null @@ -1,53 +0,0 @@ -/* - WARNING: This file is automatically generated and any changes made to it will be overwritten without warning. - Do NOT manually edit this file or your changes will be lost. -*/ - -import { - NotHandled, - NotMatched, - GetPaths, - PostPaths, - GetablePath, - GetableHref, - PostablePath, - PostableHref, - Platform, -} from '@marko/run/namespace' -import type * as Run from '@marko/run' - -declare module '@marko/run' { - interface AppData extends Run.DefineApp<{ - routes: { - '/': { verb: 'get' } - } - }> {} -} - -declare module '../src/routes/+page.marko' { - namespace MarkoRun { - export { - NotHandled, - NotMatched, - GetPaths, - PostPaths, - GetablePath, - GetableHref, - PostablePath, - PostableHref, - Platform, - } - export type Route = Run.Routes['/'] - export type Context = Run.MultiRouteContext & Marko.Global - export type Handler = Run.HandlerLike - export type GET = Run.HandlerLike - export type HEAD = Run.HandlerLike - export type POST = Run.HandlerLike - export type PUT = Run.HandlerLike - export type DELETE = Run.HandlerLike - export type PATCH = Run.HandlerLike - export type OPTIONS = Run.HandlerLike - /** @deprecated use `((context, next) => { ... }) satisfies MarkoRun.Handler` instead */ - export const route: Run.HandlerTypeFn - } -} diff --git a/examples/marko/smooth-scroll/package.json b/examples/marko/smooth-scroll/package.json index fba977764..ea85cd255 100644 --- a/examples/marko/smooth-scroll/package.json +++ b/examples/marko/smooth-scroll/package.json @@ -6,7 +6,6 @@ "dev": "marko-run dev", "build": "marko-run build", "preview": "marko-run preview", - "test:e2e": "playwright test", "test:types": "marko-type-check" }, "dependencies": { @@ -17,7 +16,6 @@ "devDependencies": { "@marko/language-tools": "^2.6.2", "@marko/type-check": "3.1.1", - "@playwright/test": "^1.53.1", "typescript": "5.9.3", "vite": "^6.4.2" } diff --git a/examples/marko/smooth-scroll/playwright.config.ts b/examples/marko/smooth-scroll/playwright.config.ts deleted file mode 100644 index bd49d1253..000000000 --- a/examples/marko/smooth-scroll/playwright.config.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { defineConfig } from '@playwright/test' - -// Unique per-example port. CI runs several example e2e suites in parallel, so a -// port shared across examples collides: one suite claims it and the rest either -// fail to start ("port already used") or attach to a different example's app and -// then miss the elements they assert on. Override with MARKO_E2E_PORT to point a -// run at a manually started server. -const PORT = Number(process.env.MARKO_E2E_PORT ?? 4182) -const baseURL = `http://localhost:${PORT}` - -export default defineConfig({ - testDir: './e2e', - timeout: 30_000, - retries: 0, - workers: 1, - use: { - baseURL, - }, - webServer: { - command: `npm run dev -- --port ${PORT}`, - url: baseURL, - // Reuse a manually-started dev server (npm run dev -- --port 4182) if one is - // already up — simpler to debug; CI should start its own. - reuseExistingServer: !process.env.CI, - // Surface the dev server's output in the test terminal so a crashing or - // slow-compiling server is visible instead of a silent stall. - stdout: 'pipe', - stderr: 'pipe', - timeout: 120_000, - }, -}) diff --git a/examples/marko/smooth-scroll/tsconfig.json b/examples/marko/smooth-scroll/tsconfig.json index ec50a5679..5078ee1e1 100644 --- a/examples/marko/smooth-scroll/tsconfig.json +++ b/examples/marko/smooth-scroll/tsconfig.json @@ -13,8 +13,6 @@ }, "include": [ "src", - "e2e", - "playwright.config.ts", "vite.config.ts", "../../../packages/marko-virtual/src/tags/**/*" ] diff --git a/examples/marko/ssr-fetch/.marko-run/routes.d.ts b/examples/marko/ssr-fetch/.marko-run/routes.d.ts deleted file mode 100644 index a122bc38a..000000000 --- a/examples/marko/ssr-fetch/.marko-run/routes.d.ts +++ /dev/null @@ -1,53 +0,0 @@ -/* - WARNING: This file is automatically generated and any changes made to it will be overwritten without warning. - Do NOT manually edit this file or your changes will be lost. -*/ - -import { - NotHandled, - NotMatched, - GetPaths, - PostPaths, - GetablePath, - GetableHref, - PostablePath, - PostableHref, - Platform, -} from '@marko/run/namespace' -import type * as Run from '@marko/run' - -declare module '@marko/run' { - interface AppData extends Run.DefineApp<{ - routes: { - '/': { verb: 'get' } - } - }> {} -} - -declare module '../src/routes/+page.marko' { - namespace MarkoRun { - export { - NotHandled, - NotMatched, - GetPaths, - PostPaths, - GetablePath, - GetableHref, - PostablePath, - PostableHref, - Platform, - } - export type Route = Run.Routes['/'] - export type Context = Run.MultiRouteContext & Marko.Global - export type Handler = Run.HandlerLike - export type GET = Run.HandlerLike - export type HEAD = Run.HandlerLike - export type POST = Run.HandlerLike - export type PUT = Run.HandlerLike - export type DELETE = Run.HandlerLike - export type PATCH = Run.HandlerLike - export type OPTIONS = Run.HandlerLike - /** @deprecated use `((context, next) => { ... }) satisfies MarkoRun.Handler` instead */ - export const route: Run.HandlerTypeFn - } -} diff --git a/examples/marko/ssr-fetch/package.json b/examples/marko/ssr-fetch/package.json index a22d9e33d..abc0d0075 100644 --- a/examples/marko/ssr-fetch/package.json +++ b/examples/marko/ssr-fetch/package.json @@ -6,7 +6,6 @@ "dev": "marko-run dev", "build": "marko-run build", "preview": "marko-run preview", - "test:e2e": "playwright test", "test:types": "marko-type-check" }, "dependencies": { @@ -17,7 +16,6 @@ "devDependencies": { "@marko/language-tools": "^2.6.2", "@marko/type-check": "3.1.1", - "@playwright/test": "^1.53.1", "typescript": "5.9.3", "vite": "^6.4.2" } diff --git a/examples/marko/ssr-fetch/playwright.config.ts b/examples/marko/ssr-fetch/playwright.config.ts deleted file mode 100644 index eba4cc201..000000000 --- a/examples/marko/ssr-fetch/playwright.config.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { defineConfig } from '@playwright/test' - -// Unique per-example port. CI runs several example e2e suites in parallel, so a -// port shared across examples collides: one suite claims it and the rest either -// fail to start ("port already used") or attach to a different example's app and -// then miss the elements they assert on. Override with MARKO_E2E_PORT to point a -// run at a manually started server. -const PORT = Number(process.env.MARKO_E2E_PORT ?? 4184) -const baseURL = `http://localhost:${PORT}` - -export default defineConfig({ - testDir: './e2e', - timeout: 30_000, - retries: 0, - workers: 1, - use: { - baseURL, - }, - webServer: { - command: `npm run dev -- --port ${PORT}`, - url: baseURL, - // Reuse a manually-started dev server (npm run dev -- --port 4184) if one is - // already up — simpler to debug; CI should start its own. - reuseExistingServer: !process.env.CI, - // Surface the dev server's output in the test terminal so a crashing or - // slow-compiling server is visible instead of a silent stall. - stdout: 'pipe', - stderr: 'pipe', - timeout: 120_000, - }, -}) diff --git a/examples/marko/ssr-fetch/tsconfig.json b/examples/marko/ssr-fetch/tsconfig.json index ec50a5679..5078ee1e1 100644 --- a/examples/marko/ssr-fetch/tsconfig.json +++ b/examples/marko/ssr-fetch/tsconfig.json @@ -13,8 +13,6 @@ }, "include": [ "src", - "e2e", - "playwright.config.ts", "vite.config.ts", "../../../packages/marko-virtual/src/tags/**/*" ] diff --git a/examples/marko/ssr-restore/.marko-run/routes.d.ts b/examples/marko/ssr-restore/.marko-run/routes.d.ts deleted file mode 100644 index a122bc38a..000000000 --- a/examples/marko/ssr-restore/.marko-run/routes.d.ts +++ /dev/null @@ -1,53 +0,0 @@ -/* - WARNING: This file is automatically generated and any changes made to it will be overwritten without warning. - Do NOT manually edit this file or your changes will be lost. -*/ - -import { - NotHandled, - NotMatched, - GetPaths, - PostPaths, - GetablePath, - GetableHref, - PostablePath, - PostableHref, - Platform, -} from '@marko/run/namespace' -import type * as Run from '@marko/run' - -declare module '@marko/run' { - interface AppData extends Run.DefineApp<{ - routes: { - '/': { verb: 'get' } - } - }> {} -} - -declare module '../src/routes/+page.marko' { - namespace MarkoRun { - export { - NotHandled, - NotMatched, - GetPaths, - PostPaths, - GetablePath, - GetableHref, - PostablePath, - PostableHref, - Platform, - } - export type Route = Run.Routes['/'] - export type Context = Run.MultiRouteContext & Marko.Global - export type Handler = Run.HandlerLike - export type GET = Run.HandlerLike - export type HEAD = Run.HandlerLike - export type POST = Run.HandlerLike - export type PUT = Run.HandlerLike - export type DELETE = Run.HandlerLike - export type PATCH = Run.HandlerLike - export type OPTIONS = Run.HandlerLike - /** @deprecated use `((context, next) => { ... }) satisfies MarkoRun.Handler` instead */ - export const route: Run.HandlerTypeFn - } -} diff --git a/examples/marko/ssr-restore/package.json b/examples/marko/ssr-restore/package.json index a88d2be50..c16c17ab9 100644 --- a/examples/marko/ssr-restore/package.json +++ b/examples/marko/ssr-restore/package.json @@ -6,7 +6,6 @@ "dev": "marko-run dev", "build": "marko-run build", "preview": "marko-run preview", - "test:e2e": "playwright test", "test:types": "marko-type-check" }, "dependencies": { @@ -17,7 +16,6 @@ "devDependencies": { "@marko/language-tools": "^2.6.2", "@marko/type-check": "3.1.1", - "@playwright/test": "^1.53.1", "typescript": "5.9.3", "vite": "^6.4.2" } diff --git a/examples/marko/ssr-restore/playwright.config.ts b/examples/marko/ssr-restore/playwright.config.ts deleted file mode 100644 index 5b5d54b6a..000000000 --- a/examples/marko/ssr-restore/playwright.config.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { defineConfig } from '@playwright/test' - -// Unique per-example port. CI runs several example e2e suites in parallel, so a -// port shared across examples collides: one suite claims it and the rest either -// fail to start ("port already used") or attach to a different example's app and -// then miss the elements they assert on. Override with MARKO_E2E_PORT to point a -// run at a manually started server. -const PORT = Number(process.env.MARKO_E2E_PORT ?? 4185) -const baseURL = `http://localhost:${PORT}` - -export default defineConfig({ - testDir: './e2e', - timeout: 30_000, - retries: 0, - workers: 1, - use: { - baseURL, - }, - webServer: { - command: `npm run dev -- --port ${PORT}`, - url: baseURL, - // Reuse a manually-started dev server (npm run dev -- --port 4185) if one is - // already up — simpler to debug; CI should start its own. - reuseExistingServer: !process.env.CI, - // Surface the dev server's output in the test terminal so a crashing or - // slow-compiling server is visible instead of a silent stall. - stdout: 'pipe', - stderr: 'pipe', - timeout: 120_000, - }, -}) diff --git a/examples/marko/ssr-restore/tsconfig.json b/examples/marko/ssr-restore/tsconfig.json index ec50a5679..5078ee1e1 100644 --- a/examples/marko/ssr-restore/tsconfig.json +++ b/examples/marko/ssr-restore/tsconfig.json @@ -13,8 +13,6 @@ }, "include": [ "src", - "e2e", - "playwright.config.ts", "vite.config.ts", "../../../packages/marko-virtual/src/tags/**/*" ] diff --git a/examples/marko/ssr-slice/.marko-run/routes.d.ts b/examples/marko/ssr-slice/.marko-run/routes.d.ts deleted file mode 100644 index a122bc38a..000000000 --- a/examples/marko/ssr-slice/.marko-run/routes.d.ts +++ /dev/null @@ -1,53 +0,0 @@ -/* - WARNING: This file is automatically generated and any changes made to it will be overwritten without warning. - Do NOT manually edit this file or your changes will be lost. -*/ - -import { - NotHandled, - NotMatched, - GetPaths, - PostPaths, - GetablePath, - GetableHref, - PostablePath, - PostableHref, - Platform, -} from '@marko/run/namespace' -import type * as Run from '@marko/run' - -declare module '@marko/run' { - interface AppData extends Run.DefineApp<{ - routes: { - '/': { verb: 'get' } - } - }> {} -} - -declare module '../src/routes/+page.marko' { - namespace MarkoRun { - export { - NotHandled, - NotMatched, - GetPaths, - PostPaths, - GetablePath, - GetableHref, - PostablePath, - PostableHref, - Platform, - } - export type Route = Run.Routes['/'] - export type Context = Run.MultiRouteContext & Marko.Global - export type Handler = Run.HandlerLike - export type GET = Run.HandlerLike - export type HEAD = Run.HandlerLike - export type POST = Run.HandlerLike - export type PUT = Run.HandlerLike - export type DELETE = Run.HandlerLike - export type PATCH = Run.HandlerLike - export type OPTIONS = Run.HandlerLike - /** @deprecated use `((context, next) => { ... }) satisfies MarkoRun.Handler` instead */ - export const route: Run.HandlerTypeFn - } -} diff --git a/examples/marko/ssr-slice/package.json b/examples/marko/ssr-slice/package.json index 9dda2d297..8ef694478 100644 --- a/examples/marko/ssr-slice/package.json +++ b/examples/marko/ssr-slice/package.json @@ -6,7 +6,6 @@ "dev": "marko-run dev", "build": "marko-run build", "preview": "marko-run preview", - "test:e2e": "playwright test", "test:types": "marko-type-check" }, "dependencies": { @@ -17,7 +16,6 @@ "devDependencies": { "@marko/language-tools": "^2.6.2", "@marko/type-check": "3.1.1", - "@playwright/test": "^1.53.1", "typescript": "5.9.3", "vite": "^6.4.2" } diff --git a/examples/marko/ssr-slice/playwright.config.ts b/examples/marko/ssr-slice/playwright.config.ts deleted file mode 100644 index eaefba2ef..000000000 --- a/examples/marko/ssr-slice/playwright.config.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { defineConfig } from '@playwright/test' - -// Unique per-example port. CI runs several example e2e suites in parallel, so a -// port shared across examples collides: one suite claims it and the rest either -// fail to start ("port already used") or attach to a different example's app and -// then miss the elements they assert on. Override with MARKO_E2E_PORT to point a -// run at a manually started server. -const PORT = Number(process.env.MARKO_E2E_PORT ?? 4186) -const baseURL = `http://localhost:${PORT}` - -export default defineConfig({ - testDir: './e2e', - timeout: 30_000, - retries: 0, - workers: 1, - use: { - baseURL, - }, - webServer: { - command: `npm run dev -- --port ${PORT}`, - url: baseURL, - // Reuse a manually-started dev server (npm run dev -- --port 4186) if one is - // already up — simpler to debug; CI should start its own. - reuseExistingServer: !process.env.CI, - // Surface the dev server's output in the test terminal so a crashing or - // slow-compiling server is visible instead of a silent stall. - stdout: 'pipe', - stderr: 'pipe', - timeout: 120_000, - }, -}) diff --git a/examples/marko/ssr-slice/tsconfig.json b/examples/marko/ssr-slice/tsconfig.json index ec50a5679..5078ee1e1 100644 --- a/examples/marko/ssr-slice/tsconfig.json +++ b/examples/marko/ssr-slice/tsconfig.json @@ -13,8 +13,6 @@ }, "include": [ "src", - "e2e", - "playwright.config.ts", "vite.config.ts", "../../../packages/marko-virtual/src/tags/**/*" ] diff --git a/examples/marko/ssr/.marko-run/routes.d.ts b/examples/marko/ssr/.marko-run/routes.d.ts deleted file mode 100644 index a122bc38a..000000000 --- a/examples/marko/ssr/.marko-run/routes.d.ts +++ /dev/null @@ -1,53 +0,0 @@ -/* - WARNING: This file is automatically generated and any changes made to it will be overwritten without warning. - Do NOT manually edit this file or your changes will be lost. -*/ - -import { - NotHandled, - NotMatched, - GetPaths, - PostPaths, - GetablePath, - GetableHref, - PostablePath, - PostableHref, - Platform, -} from '@marko/run/namespace' -import type * as Run from '@marko/run' - -declare module '@marko/run' { - interface AppData extends Run.DefineApp<{ - routes: { - '/': { verb: 'get' } - } - }> {} -} - -declare module '../src/routes/+page.marko' { - namespace MarkoRun { - export { - NotHandled, - NotMatched, - GetPaths, - PostPaths, - GetablePath, - GetableHref, - PostablePath, - PostableHref, - Platform, - } - export type Route = Run.Routes['/'] - export type Context = Run.MultiRouteContext & Marko.Global - export type Handler = Run.HandlerLike - export type GET = Run.HandlerLike - export type HEAD = Run.HandlerLike - export type POST = Run.HandlerLike - export type PUT = Run.HandlerLike - export type DELETE = Run.HandlerLike - export type PATCH = Run.HandlerLike - export type OPTIONS = Run.HandlerLike - /** @deprecated use `((context, next) => { ... }) satisfies MarkoRun.Handler` instead */ - export const route: Run.HandlerTypeFn - } -} diff --git a/examples/marko/ssr/package.json b/examples/marko/ssr/package.json index 59ffb0916..dec9c7bf2 100644 --- a/examples/marko/ssr/package.json +++ b/examples/marko/ssr/package.json @@ -6,7 +6,6 @@ "dev": "marko-run dev", "build": "marko-run build", "preview": "marko-run preview", - "test:e2e": "playwright test", "test:types": "marko-type-check" }, "dependencies": { @@ -17,7 +16,6 @@ "devDependencies": { "@marko/language-tools": "^2.6.2", "@marko/type-check": "3.1.1", - "@playwright/test": "^1.53.1", "typescript": "5.9.3", "vite": "^6.4.2" } diff --git a/examples/marko/ssr/playwright.config.ts b/examples/marko/ssr/playwright.config.ts deleted file mode 100644 index 5be78146f..000000000 --- a/examples/marko/ssr/playwright.config.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { defineConfig } from '@playwright/test' - -// Unique per-example port. CI runs several example e2e suites in parallel, so a -// port shared across examples collides: one suite claims it and the rest either -// fail to start ("port already used") or attach to a different example's app and -// then miss the elements they assert on. Override with MARKO_E2E_PORT to point a -// run at a manually started server. -const PORT = Number(process.env.MARKO_E2E_PORT ?? 4183) -const baseURL = `http://localhost:${PORT}` - -export default defineConfig({ - testDir: './e2e', - timeout: 30_000, - retries: 0, - workers: 1, - use: { - baseURL, - }, - webServer: { - command: `npm run dev -- --port ${PORT}`, - url: baseURL, - // Reuse a manually-started dev server (npm run dev -- --port 4183) if one is - // already up — simpler to debug; CI should start its own. - reuseExistingServer: !process.env.CI, - // Surface the dev server's output in the test terminal so a crashing or - // slow-compiling server is visible instead of a silent stall. - stdout: 'pipe', - stderr: 'pipe', - timeout: 120_000, - }, -}) diff --git a/examples/marko/ssr/tsconfig.json b/examples/marko/ssr/tsconfig.json index ec50a5679..5078ee1e1 100644 --- a/examples/marko/ssr/tsconfig.json +++ b/examples/marko/ssr/tsconfig.json @@ -13,8 +13,6 @@ }, "include": [ "src", - "e2e", - "playwright.config.ts", "vite.config.ts", "../../../packages/marko-virtual/src/tags/**/*" ] diff --git a/examples/marko/sticky/.marko-run/routes.d.ts b/examples/marko/sticky/.marko-run/routes.d.ts deleted file mode 100644 index a122bc38a..000000000 --- a/examples/marko/sticky/.marko-run/routes.d.ts +++ /dev/null @@ -1,53 +0,0 @@ -/* - WARNING: This file is automatically generated and any changes made to it will be overwritten without warning. - Do NOT manually edit this file or your changes will be lost. -*/ - -import { - NotHandled, - NotMatched, - GetPaths, - PostPaths, - GetablePath, - GetableHref, - PostablePath, - PostableHref, - Platform, -} from '@marko/run/namespace' -import type * as Run from '@marko/run' - -declare module '@marko/run' { - interface AppData extends Run.DefineApp<{ - routes: { - '/': { verb: 'get' } - } - }> {} -} - -declare module '../src/routes/+page.marko' { - namespace MarkoRun { - export { - NotHandled, - NotMatched, - GetPaths, - PostPaths, - GetablePath, - GetableHref, - PostablePath, - PostableHref, - Platform, - } - export type Route = Run.Routes['/'] - export type Context = Run.MultiRouteContext & Marko.Global - export type Handler = Run.HandlerLike - export type GET = Run.HandlerLike - export type HEAD = Run.HandlerLike - export type POST = Run.HandlerLike - export type PUT = Run.HandlerLike - export type DELETE = Run.HandlerLike - export type PATCH = Run.HandlerLike - export type OPTIONS = Run.HandlerLike - /** @deprecated use `((context, next) => { ... }) satisfies MarkoRun.Handler` instead */ - export const route: Run.HandlerTypeFn - } -} diff --git a/examples/marko/sticky/package.json b/examples/marko/sticky/package.json index ba976db9e..bbdde8ff0 100644 --- a/examples/marko/sticky/package.json +++ b/examples/marko/sticky/package.json @@ -6,7 +6,6 @@ "dev": "marko-run dev", "build": "marko-run build", "preview": "marko-run preview", - "test:e2e": "playwright test", "test:types": "marko-type-check" }, "dependencies": { @@ -17,7 +16,6 @@ "devDependencies": { "@marko/language-tools": "^2.6.2", "@marko/type-check": "3.1.1", - "@playwright/test": "^1.53.1", "typescript": "5.9.3", "vite": "^6.4.2" } diff --git a/examples/marko/sticky/playwright.config.ts b/examples/marko/sticky/playwright.config.ts deleted file mode 100644 index f6ae6fa19..000000000 --- a/examples/marko/sticky/playwright.config.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { defineConfig } from '@playwright/test' - -// Unique per-example port. CI runs several example e2e suites in parallel, so a -// port shared across examples collides: one suite claims it and the rest either -// fail to start ("port already used") or attach to a different example's app and -// then miss the elements they assert on. Override with MARKO_E2E_PORT to point a -// run at a manually started server. -const PORT = Number(process.env.MARKO_E2E_PORT ?? 4187) -const baseURL = `http://localhost:${PORT}` - -export default defineConfig({ - testDir: './e2e', - timeout: 30_000, - retries: 0, - workers: 1, - use: { - baseURL, - }, - webServer: { - command: `npm run dev -- --port ${PORT}`, - url: baseURL, - // Reuse a manually-started dev server (npm run dev -- --port 4187) if one is - // already up — simpler to debug; CI should start its own. - reuseExistingServer: !process.env.CI, - // Surface the dev server's output in the test terminal so a crashing or - // slow-compiling server is visible instead of a silent stall. - stdout: 'pipe', - stderr: 'pipe', - timeout: 120_000, - }, -}) diff --git a/examples/marko/sticky/tsconfig.json b/examples/marko/sticky/tsconfig.json index ec50a5679..5078ee1e1 100644 --- a/examples/marko/sticky/tsconfig.json +++ b/examples/marko/sticky/tsconfig.json @@ -13,8 +13,6 @@ }, "include": [ "src", - "e2e", - "playwright.config.ts", "vite.config.ts", "../../../packages/marko-virtual/src/tags/**/*" ] diff --git a/examples/marko/table/.marko-run/routes.d.ts b/examples/marko/table/.marko-run/routes.d.ts deleted file mode 100644 index a122bc38a..000000000 --- a/examples/marko/table/.marko-run/routes.d.ts +++ /dev/null @@ -1,53 +0,0 @@ -/* - WARNING: This file is automatically generated and any changes made to it will be overwritten without warning. - Do NOT manually edit this file or your changes will be lost. -*/ - -import { - NotHandled, - NotMatched, - GetPaths, - PostPaths, - GetablePath, - GetableHref, - PostablePath, - PostableHref, - Platform, -} from '@marko/run/namespace' -import type * as Run from '@marko/run' - -declare module '@marko/run' { - interface AppData extends Run.DefineApp<{ - routes: { - '/': { verb: 'get' } - } - }> {} -} - -declare module '../src/routes/+page.marko' { - namespace MarkoRun { - export { - NotHandled, - NotMatched, - GetPaths, - PostPaths, - GetablePath, - GetableHref, - PostablePath, - PostableHref, - Platform, - } - export type Route = Run.Routes['/'] - export type Context = Run.MultiRouteContext & Marko.Global - export type Handler = Run.HandlerLike - export type GET = Run.HandlerLike - export type HEAD = Run.HandlerLike - export type POST = Run.HandlerLike - export type PUT = Run.HandlerLike - export type DELETE = Run.HandlerLike - export type PATCH = Run.HandlerLike - export type OPTIONS = Run.HandlerLike - /** @deprecated use `((context, next) => { ... }) satisfies MarkoRun.Handler` instead */ - export const route: Run.HandlerTypeFn - } -} diff --git a/examples/marko/table/package.json b/examples/marko/table/package.json index 5df299d6c..84f1a4ab4 100644 --- a/examples/marko/table/package.json +++ b/examples/marko/table/package.json @@ -6,7 +6,6 @@ "dev": "marko-run dev", "build": "marko-run build", "preview": "marko-run preview", - "test:e2e": "playwright test", "test:types": "marko-type-check" }, "dependencies": { @@ -17,7 +16,6 @@ "devDependencies": { "@marko/language-tools": "^2.6.2", "@marko/type-check": "3.1.1", - "@playwright/test": "^1.53.1", "typescript": "5.9.3", "vite": "^6.4.2" } diff --git a/examples/marko/table/playwright.config.ts b/examples/marko/table/playwright.config.ts deleted file mode 100644 index dd19f7320..000000000 --- a/examples/marko/table/playwright.config.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { defineConfig } from '@playwright/test' - -// Unique per-example port. CI runs several example e2e suites in parallel, so a -// port shared across examples collides: one suite claims it and the rest either -// fail to start ("port already used") or attach to a different example's app and -// then miss the elements they assert on. Override with MARKO_E2E_PORT to point a -// run at a manually started server. -const PORT = Number(process.env.MARKO_E2E_PORT ?? 4188) -const baseURL = `http://localhost:${PORT}` - -export default defineConfig({ - testDir: './e2e', - timeout: 30_000, - retries: 0, - workers: 1, - use: { - baseURL, - }, - webServer: { - command: `npm run dev -- --port ${PORT}`, - url: baseURL, - // Reuse a manually-started dev server (npm run dev -- --port 4188) if one is - // already up — simpler to debug; CI should start its own. - reuseExistingServer: !process.env.CI, - // Surface the dev server's output in the test terminal so a crashing or - // slow-compiling server is visible instead of a silent stall. - stdout: 'pipe', - stderr: 'pipe', - timeout: 120_000, - }, -}) diff --git a/examples/marko/table/tsconfig.json b/examples/marko/table/tsconfig.json index ec50a5679..5078ee1e1 100644 --- a/examples/marko/table/tsconfig.json +++ b/examples/marko/table/tsconfig.json @@ -13,8 +13,6 @@ }, "include": [ "src", - "e2e", - "playwright.config.ts", "vite.config.ts", "../../../packages/marko-virtual/src/tags/**/*" ] diff --git a/examples/marko/variable/.marko-run/routes.d.ts b/examples/marko/variable/.marko-run/routes.d.ts deleted file mode 100644 index a122bc38a..000000000 --- a/examples/marko/variable/.marko-run/routes.d.ts +++ /dev/null @@ -1,53 +0,0 @@ -/* - WARNING: This file is automatically generated and any changes made to it will be overwritten without warning. - Do NOT manually edit this file or your changes will be lost. -*/ - -import { - NotHandled, - NotMatched, - GetPaths, - PostPaths, - GetablePath, - GetableHref, - PostablePath, - PostableHref, - Platform, -} from '@marko/run/namespace' -import type * as Run from '@marko/run' - -declare module '@marko/run' { - interface AppData extends Run.DefineApp<{ - routes: { - '/': { verb: 'get' } - } - }> {} -} - -declare module '../src/routes/+page.marko' { - namespace MarkoRun { - export { - NotHandled, - NotMatched, - GetPaths, - PostPaths, - GetablePath, - GetableHref, - PostablePath, - PostableHref, - Platform, - } - export type Route = Run.Routes['/'] - export type Context = Run.MultiRouteContext & Marko.Global - export type Handler = Run.HandlerLike - export type GET = Run.HandlerLike - export type HEAD = Run.HandlerLike - export type POST = Run.HandlerLike - export type PUT = Run.HandlerLike - export type DELETE = Run.HandlerLike - export type PATCH = Run.HandlerLike - export type OPTIONS = Run.HandlerLike - /** @deprecated use `((context, next) => { ... }) satisfies MarkoRun.Handler` instead */ - export const route: Run.HandlerTypeFn - } -} diff --git a/examples/marko/variable/package.json b/examples/marko/variable/package.json index d068a6ec8..98b3ac2ba 100644 --- a/examples/marko/variable/package.json +++ b/examples/marko/variable/package.json @@ -6,7 +6,6 @@ "dev": "marko-run dev", "build": "marko-run build", "preview": "marko-run preview", - "test:e2e": "playwright test", "test:types": "marko-type-check" }, "dependencies": { @@ -17,7 +16,6 @@ "devDependencies": { "@marko/language-tools": "^2.6.2", "@marko/type-check": "3.1.1", - "@playwright/test": "^1.53.1", "typescript": "5.9.3", "vite": "^6.4.2" } diff --git a/examples/marko/variable/playwright.config.ts b/examples/marko/variable/playwright.config.ts deleted file mode 100644 index 4cd3039a1..000000000 --- a/examples/marko/variable/playwright.config.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { defineConfig } from '@playwright/test' - -// Unique per-example port. CI runs several example e2e suites in parallel, so a -// port shared across examples collides: one suite claims it and the rest either -// fail to start ("port already used") or attach to a different example's app and -// then miss the elements they assert on. Override with MARKO_E2E_PORT to point a -// run at a manually started server. -const PORT = Number(process.env.MARKO_E2E_PORT ?? 4189) -const baseURL = `http://localhost:${PORT}` - -export default defineConfig({ - testDir: './e2e', - timeout: 30_000, - retries: 0, - workers: 1, - use: { - baseURL, - }, - webServer: { - command: `npm run dev -- --port ${PORT}`, - url: baseURL, - // Reuse a manually-started dev server (npm run dev -- --port 4189) if one is - // already up — simpler to debug; CI should start its own. - reuseExistingServer: !process.env.CI, - // Surface the dev server's output in the test terminal so a crashing or - // slow-compiling server is visible instead of a silent stall. - stdout: 'pipe', - stderr: 'pipe', - timeout: 120_000, - }, -}) diff --git a/examples/marko/variable/tsconfig.json b/examples/marko/variable/tsconfig.json index ec50a5679..5078ee1e1 100644 --- a/examples/marko/variable/tsconfig.json +++ b/examples/marko/variable/tsconfig.json @@ -13,8 +13,6 @@ }, "include": [ "src", - "e2e", - "playwright.config.ts", "vite.config.ts", "../../../packages/marko-virtual/src/tags/**/*" ] diff --git a/examples/marko/window-ssr-slice/.marko-run/routes.d.ts b/examples/marko/window-ssr-slice/.marko-run/routes.d.ts deleted file mode 100644 index a122bc38a..000000000 --- a/examples/marko/window-ssr-slice/.marko-run/routes.d.ts +++ /dev/null @@ -1,53 +0,0 @@ -/* - WARNING: This file is automatically generated and any changes made to it will be overwritten without warning. - Do NOT manually edit this file or your changes will be lost. -*/ - -import { - NotHandled, - NotMatched, - GetPaths, - PostPaths, - GetablePath, - GetableHref, - PostablePath, - PostableHref, - Platform, -} from '@marko/run/namespace' -import type * as Run from '@marko/run' - -declare module '@marko/run' { - interface AppData extends Run.DefineApp<{ - routes: { - '/': { verb: 'get' } - } - }> {} -} - -declare module '../src/routes/+page.marko' { - namespace MarkoRun { - export { - NotHandled, - NotMatched, - GetPaths, - PostPaths, - GetablePath, - GetableHref, - PostablePath, - PostableHref, - Platform, - } - export type Route = Run.Routes['/'] - export type Context = Run.MultiRouteContext & Marko.Global - export type Handler = Run.HandlerLike - export type GET = Run.HandlerLike - export type HEAD = Run.HandlerLike - export type POST = Run.HandlerLike - export type PUT = Run.HandlerLike - export type DELETE = Run.HandlerLike - export type PATCH = Run.HandlerLike - export type OPTIONS = Run.HandlerLike - /** @deprecated use `((context, next) => { ... }) satisfies MarkoRun.Handler` instead */ - export const route: Run.HandlerTypeFn - } -} diff --git a/examples/marko/window-ssr-slice/package.json b/examples/marko/window-ssr-slice/package.json index 47e79677e..9c8ed4559 100644 --- a/examples/marko/window-ssr-slice/package.json +++ b/examples/marko/window-ssr-slice/package.json @@ -6,7 +6,6 @@ "dev": "marko-run dev", "build": "marko-run build", "preview": "marko-run preview", - "test:e2e": "playwright test", "test:types": "marko-type-check" }, "dependencies": { @@ -17,7 +16,6 @@ "devDependencies": { "@marko/language-tools": "^2.6.2", "@marko/type-check": "3.1.1", - "@playwright/test": "^1.53.1", "typescript": "5.9.3", "vite": "^6.4.2" } diff --git a/examples/marko/window-ssr-slice/playwright.config.ts b/examples/marko/window-ssr-slice/playwright.config.ts deleted file mode 100644 index cfc296246..000000000 --- a/examples/marko/window-ssr-slice/playwright.config.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { defineConfig } from '@playwright/test' - -// Unique per-example port. CI runs several example e2e suites in parallel, so a -// port shared across examples collides: one suite claims it and the rest either -// fail to start ("port already used") or attach to a different example's app and -// then miss the elements they assert on. Override with MARKO_E2E_PORT to point a -// run at a manually started server. -const PORT = Number(process.env.MARKO_E2E_PORT ?? 4191) -const baseURL = `http://localhost:${PORT}` - -export default defineConfig({ - testDir: './e2e', - timeout: 30_000, - retries: 0, - workers: 1, - use: { - baseURL, - }, - webServer: { - command: `npm run dev -- --port ${PORT}`, - url: baseURL, - // Reuse a manually-started dev server (npm run dev -- --port 4191) if one is - // already up — simpler to debug; CI should start its own. - reuseExistingServer: !process.env.CI, - // Surface the dev server's output in the test terminal so a crashing or - // slow-compiling server is visible instead of a silent stall. - stdout: 'pipe', - stderr: 'pipe', - timeout: 120_000, - }, -}) diff --git a/examples/marko/window-ssr-slice/tsconfig.json b/examples/marko/window-ssr-slice/tsconfig.json index ec50a5679..5078ee1e1 100644 --- a/examples/marko/window-ssr-slice/tsconfig.json +++ b/examples/marko/window-ssr-slice/tsconfig.json @@ -13,8 +13,6 @@ }, "include": [ "src", - "e2e", - "playwright.config.ts", "vite.config.ts", "../../../packages/marko-virtual/src/tags/**/*" ] diff --git a/examples/marko/window/.marko-run/routes.d.ts b/examples/marko/window/.marko-run/routes.d.ts deleted file mode 100644 index a122bc38a..000000000 --- a/examples/marko/window/.marko-run/routes.d.ts +++ /dev/null @@ -1,53 +0,0 @@ -/* - WARNING: This file is automatically generated and any changes made to it will be overwritten without warning. - Do NOT manually edit this file or your changes will be lost. -*/ - -import { - NotHandled, - NotMatched, - GetPaths, - PostPaths, - GetablePath, - GetableHref, - PostablePath, - PostableHref, - Platform, -} from '@marko/run/namespace' -import type * as Run from '@marko/run' - -declare module '@marko/run' { - interface AppData extends Run.DefineApp<{ - routes: { - '/': { verb: 'get' } - } - }> {} -} - -declare module '../src/routes/+page.marko' { - namespace MarkoRun { - export { - NotHandled, - NotMatched, - GetPaths, - PostPaths, - GetablePath, - GetableHref, - PostablePath, - PostableHref, - Platform, - } - export type Route = Run.Routes['/'] - export type Context = Run.MultiRouteContext & Marko.Global - export type Handler = Run.HandlerLike - export type GET = Run.HandlerLike - export type HEAD = Run.HandlerLike - export type POST = Run.HandlerLike - export type PUT = Run.HandlerLike - export type DELETE = Run.HandlerLike - export type PATCH = Run.HandlerLike - export type OPTIONS = Run.HandlerLike - /** @deprecated use `((context, next) => { ... }) satisfies MarkoRun.Handler` instead */ - export const route: Run.HandlerTypeFn - } -} diff --git a/examples/marko/window/package.json b/examples/marko/window/package.json index 81faf00d3..71c4c711a 100644 --- a/examples/marko/window/package.json +++ b/examples/marko/window/package.json @@ -6,7 +6,6 @@ "dev": "marko-run dev", "build": "marko-run build", "preview": "marko-run preview", - "test:e2e": "playwright test", "test:types": "marko-type-check" }, "dependencies": { @@ -17,7 +16,6 @@ "devDependencies": { "@marko/language-tools": "^2.6.2", "@marko/type-check": "3.1.1", - "@playwright/test": "^1.53.1", "typescript": "5.9.3", "vite": "^6.4.2" } diff --git a/examples/marko/window/playwright.config.ts b/examples/marko/window/playwright.config.ts deleted file mode 100644 index c946c6cd4..000000000 --- a/examples/marko/window/playwright.config.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { defineConfig } from '@playwright/test' - -// Unique per-example port. CI runs several example e2e suites in parallel, so a -// port shared across examples collides: one suite claims it and the rest either -// fail to start ("port already used") or attach to a different example's app and -// then miss the elements they assert on. Override with MARKO_E2E_PORT to point a -// run at a manually started server. -const PORT = Number(process.env.MARKO_E2E_PORT ?? 4190) -const baseURL = `http://localhost:${PORT}` - -export default defineConfig({ - testDir: './e2e', - timeout: 30_000, - retries: 0, - workers: 1, - use: { - baseURL, - }, - webServer: { - command: `npm run dev -- --port ${PORT}`, - url: baseURL, - // Reuse a manually-started dev server (npm run dev -- --port 4190) if one is - // already up — simpler to debug; CI should start its own. - reuseExistingServer: !process.env.CI, - // Surface the dev server's output in the test terminal so a crashing or - // slow-compiling server is visible instead of a silent stall. - stdout: 'pipe', - stderr: 'pipe', - timeout: 120_000, - }, -}) diff --git a/examples/marko/window/tsconfig.json b/examples/marko/window/tsconfig.json index ec50a5679..5078ee1e1 100644 --- a/examples/marko/window/tsconfig.json +++ b/examples/marko/window/tsconfig.json @@ -13,8 +13,6 @@ }, "include": [ "src", - "e2e", - "playwright.config.ts", "vite.config.ts", "../../../packages/marko-virtual/src/tags/**/*" ] diff --git a/nx.json b/nx.json index e75501a02..25fa8ae7c 100644 --- a/nx.json +++ b/nx.json @@ -53,6 +53,15 @@ "dependsOn": ["^build"], "inputs": ["default", "^production"] }, + "test:e2e": { + "cache": true, + "dependsOn": ["^build"], + "inputs": ["default", "^production"], + "outputs": [ + "{projectRoot}/playwright-report", + "{projectRoot}/test-results" + ] + }, "build": { "cache": true, "dependsOn": ["^build"], diff --git a/packages/angular-virtual/package.json b/packages/angular-virtual/package.json index 46a605453..5cf464c5e 100644 --- a/packages/angular-virtual/package.json +++ b/packages/angular-virtual/package.json @@ -46,7 +46,7 @@ "test:build": "publint --strict", "test:types": "tsc", "build": "vite build", - "test:e2e": "../../node_modules/.bin/playwright test" + "test:e2e": "playwright test" }, "dependencies": { "@tanstack/virtual-core": "workspace:*" diff --git a/packages/angular-virtual/playwright.config.ts b/packages/angular-virtual/playwright.config.ts index 617f10405..40c407dfc 100644 --- a/packages/angular-virtual/playwright.config.ts +++ b/packages/angular-virtual/playwright.config.ts @@ -7,6 +7,9 @@ export default defineConfig({ testDir: './e2e/app/test', use: { baseURL, + // Without a trace a CI-only failure is a stack trace with no page state. The + // trace carries screenshots itself. + trace: 'retain-on-failure', }, webServer: { command: `pnpm exec ng serve --host 127.0.0.1 --port ${PORT} --configuration development`, diff --git a/packages/marko-virtual/e2e/app/README.md b/packages/marko-virtual/e2e/app/README.md new file mode 100644 index 000000000..a835116ef --- /dev/null +++ b/packages/marko-virtual/e2e/app/README.md @@ -0,0 +1,83 @@ +# Browser test app (test harness — not a shipped example) + +The whole Marko browser suite: one app, one server, one Playwright config. Each +scenario is a route under src/routes/, and each spec under e2e/ drives its own +route. `npm run test:e2e` builds the app, serves it, runs every spec, tears down. + +Two kinds of route live here: + +- **Option gates** (enabled, rtl, scroll-margin, cached, lanes-mode, + measure-element, debug, scroll-events, window-horizontal, + window-initial-offset, window-example) — deliberately artificial pages, one per + option, asserting the option observably changes behavior. Tier 1 (jsdom + forwarding for every option) lives in the package's options.test.ts, which also + owns anything only observable in dev — core's debug logging is compiled out by + `process.env.NODE_ENV !== 'production'`, so the browser gate for `debug` asserts + only that the option does not disturb rendering. `useAnimationFrameWithResizeObserver` + remains forwarding-only and explicitly UNPROVEN. +- **Example fixtures** (chat, table, ssr-slice, window, …) — thin wrappers that + render the real page from examples/marko/<name>: + + ```marko + import Page from "../../../../../../../examples/marko/fixed/src/routes/+page.marko" + + ``` + + The example is imported, never copied, so the shipped examples are what the + suite actually covers and a fixture cannot drift from the example it tests. + api/reply/+handler.ts is re-exported from the chat example for the same reason + (both chat fixtures POST to an absolute /api/reply, so it is mounted once at the + app root). + +## Why one app + +Each example used to carry its own e2e/, playwright.config.ts and port +(4173–4191): 19 dev servers per CI run, 19 copies of the config, and a build-order +coupling that broke the suite. The examples resolve tags through +`@tanstack/marko-virtual`, whose marko.json points at ./dist/tags, so with the +package unbuilt every page 500s — and because marko-run silently falls back to a +random free port when the requested one is taken, that surfaced only as +`Timed out waiting 120000ms from config.webServer`, with the real error nowhere in +the log. Here the vite aliases resolve the adapter and core to **source**, so the +suite needs no build at all, and nx.json declares `test:e2e` +`dependsOn: ["^build"]` so nothing else can fall into that trap either. + +## Layout constraints + +Relative paths assume exactly this depth: marko.json -> ../../src/tags, vite +aliases -> ../../src/index.ts and ../../../virtual-core/src/index.ts, fixture +imports -> seven levels up to the repo root. Moving this folder means updating all +of them. + +Install is covered by the repo-level `pnpm install` via the workspace glob +`packages/marko-virtual/e2e/*`. A first browser run may need +`npx playwright install chromium`. + +To debug a spec interactively, start `npm run dev -- --port 4199` (HMR) or +`npm run preview` in one terminal and rerun `npm run test:e2e` — it reuses an +already-running server unless CI is set. MARKO_E2E_PORT points a run at another +port. + +## Dependency note (do not re-add `@tanstack/marko-virtual` here) + +This app lives INSIDE packages/marko-virtual. Depending on the ancestor makes +pnpm create node_modules/@tanstack/marko-virtual -> ../../.. — a symlink cycle. +`@marko/vite`'s production-only known-templates scan globs `**/*.marko` following +symlinks with no cycle guard, so any `marko-run build` of an app that links the +package dies with ENAMETOOLONG. The dep is also unnecessary: tags resolve through +the relative taglib path, and the adapter and core through the vite aliases. The +nx graph edge that build ordering and cache invalidation need is declared as +`implicitDependencies` in package.json, which costs no symlink. If a real JS +import from the package is ever needed here, use pnpm's `dependenciesMeta` +injected mode (which packs a copy honoring the `files` field, so e2e/ is excluded +and no cycle forms) instead of a plain workspace dependency. + +Publishing: not affected — the package's `files` field publishes only dist, +marko.json, and README.md, so nothing under e2e/ reaches npm. + +## Known-bug note + +The enabled gate carries a documented 250ms settle wait for an upstream core bug +(end-of-scroll debounce timer surviving observeOffset unsubscription and firing a +stale offset into the live instance). Remove the wait if/when the +cancellable-debounce core fix lands; the spec comment marks the spot. diff --git a/examples/marko/chat-pretext/e2e/chat-pretext.spec.ts b/packages/marko-virtual/e2e/app/e2e/chat-pretext.spec.ts similarity index 89% rename from examples/marko/chat-pretext/e2e/chat-pretext.spec.ts rename to packages/marko-virtual/e2e/app/e2e/chat-pretext.spec.ts index e350eaa7c..a86318595 100644 --- a/examples/marko/chat-pretext/e2e/chat-pretext.spec.ts +++ b/packages/marko-virtual/e2e/app/e2e/chat-pretext.spec.ts @@ -49,10 +49,34 @@ async function waitForPin(page: Page) { .toBeLessThanOrEqual(AT_END_PX) } +async function scrollTop(page: Page): Promise { + return page.locator('.messages').evaluate((el) => el.scrollTop) +} + +// Waits until scrollTop stops moving on its own — after a programmatic jump the +// virtualizer is still measuring the rows that came into view, and a measured size +// above the viewport makes core compensate the offset. A baseline captured mid-settle +// makes the "this action did NOT move the view" assertion race. Same helper as +// chat.spec.ts; the two pages share this shape. +async function waitForScrollSettled(page: Page) { + let previous = Number.NaN + await expect + .poll( + async () => { + const current = await scrollTop(page) + const settled = current === previous + previous = current + return settled + }, + { timeout: 5000, intervals: [100, 100, 100, 150, 150, 200] }, + ) + .toBe(true) +} + test('loads pinned to the newest message with status At latest', async ({ page, }) => { - await page.goto('/') + await page.goto('/chat-pretext') await waitForPin(page) await expect(page.locator('[data-key="message-44"]')).toBeVisible() await expect(page.locator('[data-testid="status"]')).toHaveText('At latest') @@ -62,7 +86,7 @@ test('loads pinned to the newest message with status At latest', async ({ test('followOnAppend keeps the view pinned when a message is added at the end', async ({ page, }) => { - await page.goto('/') + await page.goto('/chat-pretext') await waitForPin(page) await page.locator('[data-testid="add-message"]').click() await expect(page.locator('[data-key="message-45"]')).toBeVisible() @@ -71,7 +95,7 @@ test('followOnAppend keeps the view pinned when a message is added at the end', }) test('does NOT follow appends while reading history', async ({ page }) => { - await page.goto('/') + await page.goto('/chat-pretext') await waitForPin(page) await page.locator('.messages').evaluate((el) => { el.scrollTop = Math.floor(el.scrollHeight / 2) @@ -79,10 +103,11 @@ test('does NOT follow appends while reading history', async ({ page }) => { await expect(page.locator('[data-testid="status"]')).toHaveText( 'Reading history', ) - const before = await page.locator('.messages').evaluate((el) => el.scrollTop) + await waitForScrollSettled(page) + const before = await scrollTop(page) await page.locator('[data-testid="add-message"]').click() await page.waitForTimeout(400) - const after = await page.locator('.messages').evaluate((el) => el.scrollTop) + const after = await scrollTop(page) expect(Math.abs(after - before)).toBeLessThanOrEqual(1) await expect(page.locator('[data-key="message-45"]')).toHaveCount(0) }) @@ -90,7 +115,7 @@ test('does NOT follow appends while reading history', async ({ page }) => { test('prepending history keeps the visible message anchored in place', async ({ page, }) => { - await page.goto('/') + await page.goto('/chat-pretext') await waitForPin(page) // Move to the middle of the thread: well away from the bottom ("reading // history") AND outside the load-ahead auto-trigger zone near the top, so the @@ -143,7 +168,7 @@ test('prepending history keeps the visible message anchored in place', async ({ }) test('scrolling near the top auto-loads older history', async ({ page }) => { - await page.goto('/') + await page.goto('/chat-pretext') await waitForPin(page) await page.waitForTimeout(400) const heightBefore = await page @@ -166,7 +191,7 @@ test('scrolling near the top auto-loads older history', async ({ page }) => { test('Latest returns to the bottom and status flips back to At latest', async ({ page, }) => { - await page.goto('/') + await page.goto('/chat-pretext') await waitForPin(page) await page.locator('.messages').evaluate((el) => { el.scrollTop = 0 @@ -183,7 +208,7 @@ test('Latest returns to the bottom and status flips back to At latest', async ({ test('a reply streamed from the server grows progressively and stays pinned', async ({ page, }) => { - await page.goto('/') + await page.goto('/chat-pretext') await waitForPin(page) const replyResponse = page.waitForResponse( (response) => @@ -208,7 +233,7 @@ test('a reply streamed from the server grows progressively and stays pinned', as test('prepending history causes NO measurement-correction kick', async ({ page, }) => { - await page.goto('/') + await page.goto('/chat-pretext') await waitForPin(page) // Park just OUTSIDE the load-ahead auto-trigger zone (~720px = 1.5 viewport // heights) so the prepend below is click-driven, close enough to the top that a @@ -254,7 +279,7 @@ test('prepending history causes NO measurement-correction kick', async ({ test('the streamed reply grows through v.resizeItem and calculated height matches the DOM', async ({ page, }) => { - await page.goto('/') + await page.goto('/chat-pretext') await waitForPin(page) await page.locator('[data-testid="stream-reply"]').click() const streamed = page.locator('[data-key^="stream-"]') diff --git a/examples/marko/chat/e2e/chat.spec.ts b/packages/marko-virtual/e2e/app/e2e/chat.spec.ts similarity index 86% rename from examples/marko/chat/e2e/chat.spec.ts rename to packages/marko-virtual/e2e/app/e2e/chat.spec.ts index 4c0e1b0f7..14833a524 100644 --- a/examples/marko/chat/e2e/chat.spec.ts +++ b/packages/marko-virtual/e2e/app/e2e/chat.spec.ts @@ -49,10 +49,34 @@ async function waitForPin(page: Page) { .toBeLessThanOrEqual(AT_END_PX) } +async function scrollTop(page: Page): Promise { + return page.locator('.messages').evaluate((el) => el.scrollTop) +} + +// Waits until scrollTop stops moving on its own. After a programmatic jump the +// virtualizer measures the rows that just came into view, and a measured size above +// the viewport makes core compensate the offset — so a baseline captured immediately +// after the jump can still drift by ~100px on its own. Tests that assert "this +// action did NOT move the view" need a quiescent baseline, or they race the settle. +async function waitForScrollSettled(page: Page) { + let previous = Number.NaN + await expect + .poll( + async () => { + const current = await scrollTop(page) + const settled = current === previous + previous = current + return settled + }, + { timeout: 5000, intervals: [100, 100, 100, 150, 150, 200] }, + ) + .toBe(true) +} + test('loads pinned to the newest message with status At latest', async ({ page, }) => { - await page.goto('/') + await page.goto('/chat') await waitForPin(page) await expect(page.locator('[data-key="message-44"]')).toBeVisible() await expect(page.locator('[data-testid="status"]')).toHaveText('At latest') @@ -63,7 +87,7 @@ test('loads pinned to the newest message with status At latest', async ({ test('followOnAppend keeps the view pinned when a message is added at the end', async ({ page, }) => { - await page.goto('/') + await page.goto('/chat') await waitForPin(page) await page.locator('[data-testid="add-message"]').click() await expect(page.locator('[data-key="message-45"]')).toBeVisible() @@ -72,7 +96,7 @@ test('followOnAppend keeps the view pinned when a message is added at the end', }) test('does NOT follow appends while reading history', async ({ page }) => { - await page.goto('/') + await page.goto('/chat') await waitForPin(page) // scroll to the middle of the thread await page.locator('.messages').evaluate((el) => { @@ -81,11 +105,12 @@ test('does NOT follow appends while reading history', async ({ page }) => { await expect(page.locator('[data-testid="status"]')).toHaveText( 'Reading history', ) - const before = await page.locator('.messages').evaluate((el) => el.scrollTop) + await waitForScrollSettled(page) + const before = await scrollTop(page) await page.locator('[data-testid="add-message"]').click() // give any (incorrect) follow a chance to happen, then assert it did not await page.waitForTimeout(400) - const after = await page.locator('.messages').evaluate((el) => el.scrollTop) + const after = await scrollTop(page) expect(Math.abs(after - before)).toBeLessThanOrEqual(1) await expect(page.locator('[data-key="message-45"]')).toHaveCount(0) }) @@ -93,7 +118,7 @@ test('does NOT follow appends while reading history', async ({ page }) => { test('prepending history keeps the visible message anchored in place', async ({ page, }) => { - await page.goto('/') + await page.goto('/chat') await waitForPin(page) // Move to the middle of the thread: well away from the bottom ("reading // history") AND outside the load-ahead auto-trigger zone near the top, so the @@ -146,7 +171,7 @@ test('prepending history keeps the visible message anchored in place', async ({ }) test('scrolling near the top auto-loads older history', async ({ page }) => { - await page.goto('/') + await page.goto('/chat') await waitForPin(page) // wait past the 250ms arming delay await page.waitForTimeout(400) @@ -170,7 +195,7 @@ test('scrolling near the top auto-loads older history', async ({ page }) => { test('Latest returns to the bottom and status flips back to At latest', async ({ page, }) => { - await page.goto('/') + await page.goto('/chat') await waitForPin(page) await page.locator('.messages').evaluate((el) => { el.scrollTop = 0 @@ -187,7 +212,7 @@ test('Latest returns to the bottom and status flips back to At latest', async ({ test('a reply streamed from the server grows progressively and stays pinned', async ({ page, }) => { - await page.goto('/') + await page.goto('/chat') await waitForPin(page) const replyResponse = page.waitForResponse( (response) => diff --git a/examples/marko/dynamic/e2e/dynamic.spec.ts b/packages/marko-virtual/e2e/app/e2e/dynamic.spec.ts similarity index 97% rename from examples/marko/dynamic/e2e/dynamic.spec.ts rename to packages/marko-virtual/e2e/app/e2e/dynamic.spec.ts index 25a8fcefb..6bef74bce 100644 --- a/examples/marko/dynamic/e2e/dynamic.spec.ts +++ b/packages/marko-virtual/e2e/app/e2e/dynamic.spec.ts @@ -37,7 +37,7 @@ test.use({ viewport: { width: 480, height: 800 } }) test('rows render and get real measured heights (not the flat 80px estimate)', async ({ page, }) => { - await page.goto('/') + await page.goto('/dynamic') await expect(page.locator('[data-index="0"]')).toBeVisible() // Text length cycles with idx % 5, so among the first five rows at least two // measured heights must differ — and measured rows should not all sit at the @@ -51,7 +51,7 @@ test('rows render and get real measured heights (not the flat 80px estimate)', a test('measured positions stay contiguous: each row starts where the previous ends', async ({ page, }) => { - await page.goto('/') + await page.goto('/dynamic') await expect(page.locator('[data-index="0"]')).toBeVisible() const rows = await page.$$eval('[data-index]', (els) => els @@ -71,7 +71,7 @@ test('measured positions stay contiguous: each row starts where the previous end }) test('deep scroll re-windows with measured sizes', async ({ page }) => { - await page.goto('/') + await page.goto('/dynamic') await expect(page.locator('[data-index="0"]')).toBeVisible() await page.locator('.scroll-container').evaluate((el) => { el.scrollTop = 500 * 80 diff --git a/examples/marko/fixed/e2e/fixed.spec.ts b/packages/marko-virtual/e2e/app/e2e/fixed.spec.ts similarity index 97% rename from examples/marko/fixed/e2e/fixed.spec.ts rename to packages/marko-virtual/e2e/app/e2e/fixed.spec.ts index dea71d878..062f8dffa 100644 --- a/examples/marko/fixed/e2e/fixed.spec.ts +++ b/packages/marko-virtual/e2e/app/e2e/fixed.spec.ts @@ -31,7 +31,7 @@ test.afterEach(() => { test('rows: initial window renders and deep scroll re-windows', async ({ page, }) => { - await page.goto('/') + await page.goto('/fixed') await expect( page.locator('.scroll-row-container .item', { hasText: /^Row 0$/ }), ).toBeVisible() @@ -49,7 +49,7 @@ test('rows: initial window renders and deep scroll re-windows', async ({ test('columns: initial window renders and horizontal scroll re-windows', async ({ page, }) => { - await page.goto('/') + await page.goto('/fixed') await expect( page.locator('.scroll-col-container .item', { hasText: /^Col 0$/ }), ).toBeVisible() @@ -67,7 +67,7 @@ test('columns: initial window renders and horizontal scroll re-windows', async ( test('grid: two virtualizers share one scroller; 2D scroll re-windows both axes', async ({ page, }) => { - await page.goto('/') + await page.goto('/fixed') await expect( page.locator('.scroll-grid-container .cell', { hasText: /^0,0$/ }), ).toBeVisible() diff --git a/examples/marko/grid/e2e/grid.spec.ts b/packages/marko-virtual/e2e/app/e2e/grid.spec.ts similarity index 97% rename from examples/marko/grid/e2e/grid.spec.ts rename to packages/marko-virtual/e2e/app/e2e/grid.spec.ts index 1678a1f85..c42d972e5 100644 --- a/examples/marko/grid/e2e/grid.spec.ts +++ b/packages/marko-virtual/e2e/app/e2e/grid.spec.ts @@ -29,7 +29,7 @@ test.afterEach(() => { }) test('renders the top-left window of the grid', async ({ page }) => { - await page.goto('/') + await page.goto('/grid') await expect(page.locator('.cell', { hasText: /^0,0$/ })).toBeVisible() const cells = await page.locator('.cell').count() expect(cells).toBeGreaterThan(20) @@ -37,7 +37,7 @@ test('renders the top-left window of the grid', async ({ page }) => { }) test('2D scroll re-windows both axes at once', async ({ page }) => { - await page.goto('/') + await page.goto('/grid') await expect(page.locator('.cell', { hasText: /^0,0$/ })).toBeVisible() await page.locator('.scroll-grid').evaluate((el) => { el.scrollTop = 200 * 40 // mean row size ~40 diff --git a/examples/marko/infinite-scroll/e2e/infinite-scroll.spec.ts b/packages/marko-virtual/e2e/app/e2e/infinite-scroll.spec.ts similarity index 96% rename from examples/marko/infinite-scroll/e2e/infinite-scroll.spec.ts rename to packages/marko-virtual/e2e/app/e2e/infinite-scroll.spec.ts index 547ea5647..5f03a8423 100644 --- a/examples/marko/infinite-scroll/e2e/infinite-scroll.spec.ts +++ b/packages/marko-virtual/e2e/app/e2e/infinite-scroll.spec.ts @@ -32,7 +32,7 @@ test.afterEach(() => { test('reserves all 500 slots upfront while the first page loads', async ({ page, }) => { - await page.goto('/') + await page.goto('/infinite-scroll') // Total size is fixed from the start: 500 x 52 regardless of what is loaded. const wrapperHeight = await page .locator('.scroll-container > div') @@ -48,7 +48,7 @@ test('reserves all 500 slots upfront while the first page loads', async ({ test('scrolling to the edge of loaded rows fetches the next page', async ({ page, }) => { - await page.goto('/') + await page.goto('/infinite-scroll') await expect(page.getByText('20 of 500 rows loaded')).toBeVisible() await page.locator('.scroll-container').evaluate((el) => { el.scrollTop = 18 * 52 // bring the last loaded rows into the window @@ -62,7 +62,7 @@ test('scrolling to the edge of loaded rows fetches the next page', async ({ test('a deep jump shows placeholders, then pages load continuously until the region catches up', async ({ page, }) => { - await page.goto('/') + await page.goto('/infinite-scroll') await expect(page.getByText('20 of 500 rows loaded')).toBeVisible() // Jump far past the loaded region. Unloaded slots render as placeholders // immediately; the edge-trigger then RE-FIRES after every load while the window diff --git a/packages/marko-virtual/e2e/option-gates/e2e/option-gates.spec.ts b/packages/marko-virtual/e2e/app/e2e/option-gates.spec.ts similarity index 94% rename from packages/marko-virtual/e2e/option-gates/e2e/option-gates.spec.ts rename to packages/marko-virtual/e2e/app/e2e/option-gates.spec.ts index 07bde4438..be26112f3 100644 --- a/packages/marko-virtual/e2e/option-gates/e2e/option-gates.spec.ts +++ b/packages/marko-virtual/e2e/app/e2e/option-gates.spec.ts @@ -240,23 +240,22 @@ test('useScrollendEvent + isScrollingResetDelay: scrolling still re-windows (reg await page.waitForSelector('[data-index="0"]') }) -test('debug=true emits core timing logs (a console.info with the memo key)', async ({ - page, -}) => { - const infos: string[] = [] - page.on('console', (message) => { - if (message.type() === 'info') infos.push(message.text()) - }) +test('debug=true does not disturb rendering or windowing', async ({ page }) => { + // The log itself is NOT asserted here. Core writes it from a + // `process.env.NODE_ENV !== 'production'` branch, so it does not exist in the + // production build this suite runs against — and a console.info assertion needs + // no browser anyway. That proof lives in the vitest tier + // (tests/options.test.ts, "debug=true makes core emit its timing logs"). + // What is worth proving in a real browser is that turning the option on does not + // change what the user sees. await page.goto('/debug') await page.waitForSelector('[data-index="0"]') await page.locator('[data-testid="scroller"]').evaluate((el) => { el.scrollTop = 50 * 35 }) await page.waitForFunction(() => !document.querySelector('[data-index="0"]')) - // Core's memo() prints console.info('%c⏱ ... ms', , key) in dev when debug is on. - expect(infos.some((t) => t.includes('⏱') || t.includes('maybeNotify'))).toBe( - true, - ) + // Re-windowed to the scrolled region rather than stalling or blanking. + await expect(page.locator('[data-index="50"]')).toBeVisible() }) test('window-virtualizer horizontal: the page scrolls sideways and the column window follows', async ({ diff --git a/examples/marko/padding/e2e/padding.spec.ts b/packages/marko-virtual/e2e/app/e2e/padding.spec.ts similarity index 96% rename from examples/marko/padding/e2e/padding.spec.ts rename to packages/marko-virtual/e2e/app/e2e/padding.spec.ts index e4424803c..51a56d325 100644 --- a/examples/marko/padding/e2e/padding.spec.ts +++ b/packages/marko-virtual/e2e/app/e2e/padding.spec.ts @@ -33,7 +33,7 @@ test.afterEach(() => { test('paddingStart offsets the first row and first column by 100px', async ({ page, }) => { - await page.goto('/') + await page.goto('/padding') const row0 = page.locator('[data-testid="rows-list"] [data-index="0"]') await expect(row0).toBeVisible() await expect(row0).toHaveAttribute('style', /translateY\(100px\)/) @@ -43,7 +43,7 @@ test('paddingStart offsets the first row and first column by 100px', async ({ }) test('vertical and horizontal lists re-window on scroll', async ({ page }) => { - await page.goto('/') + await page.goto('/padding') await expect( page.locator('[data-testid="rows-list"] [data-index="0"]'), ).toBeVisible() @@ -70,7 +70,7 @@ test('vertical and horizontal lists re-window on scroll', async ({ page }) => { test('grid: first cell offset by 200px on both axes, both index attributes present', async ({ page, }) => { - await page.goto('/') + await page.goto('/padding') const cell = page.locator('[data-row-index="0"][data-column-index="0"]') await expect(cell).toBeVisible() await expect(cell).toHaveAttribute( @@ -82,7 +82,7 @@ test('grid: first cell offset by 200px on both axes, both index attributes prese test('indexAttribute keeps the two grid virtualizers apart under 2D scrolling', async ({ page, }) => { - await page.goto('/') + await page.goto('/padding') await expect( page.locator('[data-row-index="0"][data-column-index="0"]'), ).toBeVisible() @@ -111,7 +111,7 @@ test('indexAttribute keeps the two grid virtualizers apart under 2D scrolling', }) test('scroll-to-index button reaches the halfway row', async ({ page }) => { - await page.goto('/') + await page.goto('/padding') await expect( page.locator('[data-row-index="0"][data-column-index="0"]'), ).toBeVisible() @@ -122,7 +122,7 @@ test('scroll-to-index button reaches the halfway row', async ({ page }) => { test('toggle unmounts and remounts the grid; it keeps working after', async ({ page, }) => { - await page.goto('/') + await page.goto('/padding') await expect(page.locator('[data-testid="grid-list"]')).toBeVisible() await page.locator('[data-testid="toggle"]').click() await expect(page.locator('[data-testid="grid-list"]')).toHaveCount(0) diff --git a/examples/marko/pretext/e2e/pretext.spec.ts b/packages/marko-virtual/e2e/app/e2e/pretext.spec.ts similarity index 97% rename from examples/marko/pretext/e2e/pretext.spec.ts rename to packages/marko-virtual/e2e/app/e2e/pretext.spec.ts index 77a90e66d..5c1ac0256 100644 --- a/examples/marko/pretext/e2e/pretext.spec.ts +++ b/packages/marko-virtual/e2e/app/e2e/pretext.spec.ts @@ -32,7 +32,7 @@ test.afterEach(() => { test('renders a small window of 2000 rows with calculated heights', async ({ page, }) => { - await page.goto('/') + await page.goto('/pretext') await expect(page.locator('[data-index="0"]')).toBeVisible() const stat = await page.locator('[data-testid="stat"]').textContent() const rendered = Number(stat!.split(' ')[0]) @@ -50,7 +50,7 @@ test('renders a small window of 2000 rows with calculated heights', async ({ test('Bottom lands exactly on the last message in one jump', async ({ page, }) => { - await page.goto('/') + await page.goto('/pretext') await expect(page.locator('[data-index="0"]')).toBeVisible() await page.locator('[data-testid="bottom"]').click() const last = page.locator('[data-index="1999"]') @@ -65,7 +65,7 @@ test('Bottom lands exactly on the last message in one jump', async ({ }) test('Middle then Top round-trips cleanly', async ({ page }) => { - await page.goto('/') + await page.goto('/pretext') await expect(page.locator('[data-index="0"]')).toBeVisible() await page.locator('[data-testid="middle"]').click() await expect(page.locator('[data-index="1000"]')).toBeVisible() @@ -77,7 +77,7 @@ test('narrowing the viewport re-measures: rows get taller, total grows', async ( page, }) => { await page.setViewportSize({ width: 900, height: 800 }) - await page.goto('/') + await page.goto('/pretext') await expect(page.locator('[data-index="0"]')).toBeVisible() const beforeTotal = await page .locator('[data-testid="spacer"]') diff --git a/examples/marko/scroll-padding/e2e/scroll-padding.spec.ts b/packages/marko-virtual/e2e/app/e2e/scroll-padding.spec.ts similarity index 96% rename from examples/marko/scroll-padding/e2e/scroll-padding.spec.ts rename to packages/marko-virtual/e2e/app/e2e/scroll-padding.spec.ts index 0ed742bc8..73abfff17 100644 --- a/examples/marko/scroll-padding/e2e/scroll-padding.spec.ts +++ b/packages/marko-virtual/e2e/app/e2e/scroll-padding.spec.ts @@ -38,7 +38,7 @@ async function headerBottom(page: import('@playwright/test').Page) { test('rows start below the sticky header, not underneath it', async ({ page, }) => { - await page.goto('/') + await page.goto('/scroll-padding') const row0 = page.locator('[data-index="0"]') await expect(row0).toBeVisible() const bottom = await headerBottom(page) @@ -49,7 +49,7 @@ test('rows start below the sticky header, not underneath it', async ({ test('scrollToIndex(40) downward aligns to the viewport END (align auto semantics)', async ({ page, }) => { - await page.goto('/') + await page.goto('/scroll-padding') await expect(page.locator('[data-index="0"]')).toBeVisible() await page.locator('[data-testid="scroll-40"]').click() const row = page.locator('[data-index="40"]') @@ -67,7 +67,7 @@ test('scrollToIndex(40) downward aligns to the viewport END (align auto semantic test('then scrollToIndex(20) scrolls BACK and aligns row 20 below the header', async ({ page, }) => { - await page.goto('/') + await page.goto('/scroll-padding') await expect(page.locator('[data-index="0"]')).toBeVisible() await page.locator('[data-testid="scroll-40"]').click() await expect(page.locator('[data-index="40"]')).toBeVisible() diff --git a/examples/marko/smooth-scroll/e2e/smooth-scroll.spec.ts b/packages/marko-virtual/e2e/app/e2e/smooth-scroll.spec.ts similarity index 96% rename from examples/marko/smooth-scroll/e2e/smooth-scroll.spec.ts rename to packages/marko-virtual/e2e/app/e2e/smooth-scroll.spec.ts index 61e24aead..84f7b2538 100644 --- a/examples/marko/smooth-scroll/e2e/smooth-scroll.spec.ts +++ b/packages/marko-virtual/e2e/app/e2e/smooth-scroll.spec.ts @@ -29,7 +29,7 @@ test.afterEach(() => { }) test('Bottom smooth-scrolls all the way to row 9999', async ({ page }) => { - await page.goto('/') + await page.goto('/smooth-scroll') await expect(page.locator('.item', { hasText: /^Row 0$/ })).toBeVisible() await page.getByRole('button', { name: /Bottom/ }).click() // Smooth scrolling over 350000px takes a moment; assert within a row, generously. @@ -40,7 +40,7 @@ test('Bottom smooth-scrolls all the way to row 9999', async ({ page }) => { }) test('Top returns smoothly to row 0', async ({ page }) => { - await page.goto('/') + await page.goto('/smooth-scroll') await expect(page.locator('.item', { hasText: /^Row 0$/ })).toBeVisible() await page.getByRole('button', { name: /Bottom/ }).click() await expect(page.locator('.item', { hasText: /^Row 9999$/ })).toBeVisible({ diff --git a/examples/marko/ssr-fetch/e2e/ssr-fetch.spec.ts b/packages/marko-virtual/e2e/app/e2e/ssr-fetch.spec.ts similarity index 97% rename from examples/marko/ssr-fetch/e2e/ssr-fetch.spec.ts rename to packages/marko-virtual/e2e/app/e2e/ssr-fetch.spec.ts index 4962c9fcc..8576119f7 100644 --- a/examples/marko/ssr-fetch/e2e/ssr-fetch.spec.ts +++ b/packages/marko-virtual/e2e/app/e2e/ssr-fetch.spec.ts @@ -44,7 +44,7 @@ test.afterEach(() => { test('server HTML: empty container, but the fetched rows ARE in the serialized payload', async ({ request, }) => { - const res = await request.get('/') + const res = await request.get('/ssr-fetch') expect(res.ok()).toBe(true) const html = await res.text() // No rows painted (Mode B has no seed)... @@ -58,7 +58,7 @@ test('server HTML: empty container, but the fetched rows ARE in the serialized p test('rows render on the client from the serialized data — no client re-fetch — and the list is live', async ({ page, }) => { - await page.goto('/') + await page.goto('/ssr-fetch') // Mount fills the container with the SERVER-fetched people. await expect( page.locator('.email', { hasText: 'person1@example.com' }), diff --git a/examples/marko/ssr-restore/e2e/ssr-restore.spec.ts b/packages/marko-virtual/e2e/app/e2e/ssr-restore.spec.ts similarity index 96% rename from examples/marko/ssr-restore/e2e/ssr-restore.spec.ts rename to packages/marko-virtual/e2e/app/e2e/ssr-restore.spec.ts index 2ce6871dd..c779e96bc 100644 --- a/examples/marko/ssr-restore/e2e/ssr-restore.spec.ts +++ b/packages/marko-virtual/e2e/app/e2e/ssr-restore.spec.ts @@ -39,7 +39,7 @@ test.afterEach(() => { test('server HTML paints the slice AT THE OFFSET: rows ~#101 present, top rows absent from the markup', async ({ request, }) => { - const res = await request.get('/') + const res = await request.get('/ssr-restore') expect(res.ok()).toBe(true) const html = await res.text() // Rows around the jump target are painted... @@ -57,7 +57,7 @@ test('server HTML paints the slice AT THE OFFSET: rows ~#101 present, top rows a test('on mount the scroll position is restored to the offset and the painted rows line up', async ({ page, }) => { - await page.goto('/') + await page.goto('/ssr-restore') // The jump-target row is VISIBLE (not just present): scroll restore worked. await expect( page.locator('.email', { hasText: 'person101@example.com' }), @@ -71,7 +71,7 @@ test('on mount the scroll position is restored to the offset and the painted row test('the restored list is live: scrolling up re-windows to earlier rows', async ({ page, }) => { - await page.goto('/') + await page.goto('/ssr-restore') await expect( page.locator('.email', { hasText: 'person101@example.com' }), ).toBeVisible() @@ -91,7 +91,7 @@ test('with JavaScript disabled the offset rows exist in the DOM (positioned deep }) => { const context = await browser.newContext({ javaScriptEnabled: false }) const page = await context.newPage() - await page.goto('/') + await page.goto('/ssr-restore') // Two reasons the rows are present but not visible without JS: the out-of-order // stream sits in a hidden wrapper until an inline script swaps it in // (see the ssr-slice spec — the page renders visibly blank without JS), and no diff --git a/examples/marko/ssr-slice/e2e/ssr-slice.spec.ts b/packages/marko-virtual/e2e/app/e2e/ssr-slice.spec.ts similarity index 86% rename from examples/marko/ssr-slice/e2e/ssr-slice.spec.ts rename to packages/marko-virtual/e2e/app/e2e/ssr-slice.spec.ts index b1581d121..885dcf18b 100644 --- a/examples/marko/ssr-slice/e2e/ssr-slice.spec.ts +++ b/packages/marko-virtual/e2e/app/e2e/ssr-slice.spec.ts @@ -37,7 +37,7 @@ test.afterEach(() => { test('server HTML contains the painted slice: first rows present, deep rows absent, real total size', async ({ request, }) => { - const res = await request.get('/') + const res = await request.get('/ssr-slice') expect(res.ok()).toBe(true) const html = await res.text() // The slice is IN the server HTML (rows exist pre-JS)... @@ -59,29 +59,30 @@ test('with JavaScript disabled the painted rows exist in the DOM (streaming swap browser, }) => { // The example uses / with a placeholder, so Marko streams the awaited - // content OUT-OF-ORDER inside a hidden wrapper and swaps it into place with a tiny - // inline script. With JS disabled that swap never runs — and the streamed markup - // has ALSO already hidden the placeholder — so the page renders visibly BLANK - // while the server-painted rows sit complete in the DOM (the view-source test - // proves they are in the HTML). This characterizes the platform contract: - // out-of-order pages are not no-JS pages; fully script-less VISIBLE rows - // would require in-order rendering (no placeholder). + // content OUT-OF-ORDER and swaps it into place with a tiny inline script. With JS + // disabled that swap never runs, so the server-painted rows sit complete in the + // DOM (the view-source test proves they are in the HTML) while the reader is still + // looking at the placeholder. This characterizes the platform contract: + // out-of-order pages are not no-JS pages; script-less VISIBLE rows would + // require in-order rendering (no placeholder). const context = await browser.newContext({ javaScriptEnabled: false }) const page = await context.newPage() - await page.goto('/') + await page.goto('/ssr-slice') expect( await page.locator('.email', { hasText: 'person1@example.com' }).count(), ).toBe(1) expect(await page.locator('.item').count()).toBeGreaterThan(5) - // Placeholder hidden too — nothing is visible without JS. - await expect(page.getByText('Loading people')).toBeHidden() + // The placeholder is what stays on screen: the swap that would replace it is the + // part that needs JS. (The dev server hides it instead — this asserts the + // production behavior, which is the one users get.) + await expect(page.getByText('Loading people')).toBeVisible() await context.close() }) test('client resumes over the server slice and the list is live (scroll re-windows, no re-fetch flash)', async ({ page, }) => { - await page.goto('/') + await page.goto('/ssr-slice') // The server rows are (still) there post-resume. await expect( page.locator('.email', { hasText: 'person1@example.com' }), @@ -116,7 +117,7 @@ test('the awaited slice STREAMS: placeholder flushes first, server-painted rows // fetchPeople() resolves. This is the wire-level proof that a virtualizer // inside a streamed renders its server slice into the mid-stream // chunk (each such chunk resumes independently on the client). - const response = await fetch(baseURL!) + const response = await fetch(`${baseURL}/ssr-slice`) expect(response.ok).toBe(true) const reader = response.body!.getReader() const decoder = new TextDecoder() diff --git a/examples/marko/ssr/e2e/ssr.spec.ts b/packages/marko-virtual/e2e/app/e2e/ssr.spec.ts similarity index 97% rename from examples/marko/ssr/e2e/ssr.spec.ts rename to packages/marko-virtual/e2e/app/e2e/ssr.spec.ts index 3c7e1dda8..dda93dd1d 100644 --- a/examples/marko/ssr/e2e/ssr.spec.ts +++ b/packages/marko-virtual/e2e/app/e2e/ssr.spec.ts @@ -39,7 +39,7 @@ test.afterEach(() => { test('server HTML has an empty container with the trivial (0px) size — no rows painted', async ({ request, }) => { - const res = await request.get('/') + const res = await request.get('/ssr') expect(res.ok()).toBe(true) const html = await res.text() // No rows in the server HTML (row divs carry the item-even/item-odd classes)... @@ -53,7 +53,7 @@ test('server HTML has an empty container with the trivial (0px) size — no rows test('client fills the window on mount and the virtualizer is live (scroll re-windows)', async ({ page, }) => { - await page.goto('/') + await page.goto('/ssr') // Mount fills the empty container. await expect(page.locator('.item', { hasText: /^Row 0$/ })).toBeVisible() const initialCount = await page.locator('.item').count() diff --git a/examples/marko/sticky/e2e/sticky.spec.ts b/packages/marko-virtual/e2e/app/e2e/sticky.spec.ts similarity index 97% rename from examples/marko/sticky/e2e/sticky.spec.ts rename to packages/marko-virtual/e2e/app/e2e/sticky.spec.ts index b76b79f93..bda9fd9db 100644 --- a/examples/marko/sticky/e2e/sticky.spec.ts +++ b/packages/marko-virtual/e2e/app/e2e/sticky.spec.ts @@ -40,7 +40,7 @@ async function pinned(page: Page) { test('loads with the first group header (A) active and pinned at the top', async ({ page, }) => { - await page.goto('/') + await page.goto('/sticky') const active = await pinned(page) await expect(active).toHaveText('A') const list = await page.locator('[data-testid="list"]').boundingBox() @@ -51,7 +51,7 @@ test('loads with the first group header (A) active and pinned at the top', async test('deep inside a group, its header stays pinned though scrolled past', async ({ page, }) => { - await page.goto('/') + await page.goto('/sticky') await pinned(page) // row 0 is header 'A'; 22 'Aaron NN' + 22 'Abby NN' follow. Scroll ~15 rows in: // well past the header's natural 0px position, still inside group A. @@ -74,7 +74,7 @@ test('deep inside a group, its header stays pinned though scrolled past', async test('crossing into the next group hands the pin to its header', async ({ page, }) => { - await page.goto('/') + await page.goto('/sticky') await pinned(page) // group A spans header(1) + Aaron(22) + Abby(22) = 45 rows * 50px = 2250px. // Scroll past that boundary into group B. @@ -88,7 +88,7 @@ test('crossing into the next group hands the pin to its header', async ({ }) test('scrolling far and back returns the pin to A', async ({ page }) => { - await page.goto('/') + await page.goto('/sticky') await pinned(page) await page.locator('[data-testid="list"]').evaluate((el) => { el.scrollTop = 20000 diff --git a/examples/marko/table/e2e/table.spec.ts b/packages/marko-virtual/e2e/app/e2e/table.spec.ts similarity index 98% rename from examples/marko/table/e2e/table.spec.ts rename to packages/marko-virtual/e2e/app/e2e/table.spec.ts index 3854f672a..f6cef772f 100644 --- a/examples/marko/table/e2e/table.spec.ts +++ b/packages/marko-virtual/e2e/app/e2e/table.spec.ts @@ -33,7 +33,7 @@ test.afterEach(() => { test('renders a window of 50k semantic rows with correct flow-compensated positioning', async ({ page, }) => { - await page.goto('/') + await page.goto('/table') const first = page.locator('tbody tr[data-index="0"]') await expect(first).toBeVisible() // far more data than DOM @@ -50,7 +50,7 @@ test('renders a window of 50k semantic rows with correct flow-compensated positi test('deep scroll re-windows and compensation keeps rows visually contiguous', async ({ page, }) => { - await page.goto('/') + await page.goto('/table') await expect(page.locator('tbody tr[data-index="0"]')).toBeVisible() await page.locator('[data-testid="container"]').evaluate((el) => { el.scrollTop = 34 * 25000 @@ -76,7 +76,7 @@ test('deep scroll re-windows and compensation keeps rows visually contiguous', a test('clicking Age sorts ascending, again descending, indicator shown', async ({ page, }) => { - await page.goto('/') + await page.goto('/table') await expect(page.locator('tbody tr[data-index="0"]')).toBeVisible() await page.locator('th[data-col="age"]').click() // ascending: first row holds the minimum age (deterministic data -> 0 exists in 50k) @@ -92,7 +92,7 @@ test('clicking Age sorts ascending, again descending, indicator shown', async ({ test('index vs data: sorting swaps data under a stationary window', async ({ page, }) => { - await page.goto('/') + await page.goto('/table') await expect(page.locator('tbody tr[data-index="0"]')).toBeVisible() // scroll mid-list await page.locator('[data-testid="container"]').evaluate((el) => { diff --git a/examples/marko/variable/e2e/variable.spec.ts b/packages/marko-virtual/e2e/app/e2e/variable.spec.ts similarity index 96% rename from examples/marko/variable/e2e/variable.spec.ts rename to packages/marko-virtual/e2e/app/e2e/variable.spec.ts index 2e6eb9531..5081c7e49 100644 --- a/examples/marko/variable/e2e/variable.spec.ts +++ b/packages/marko-virtual/e2e/app/e2e/variable.spec.ts @@ -34,7 +34,7 @@ const rowSize = (i: number) => 25 + ((i * 17 + 31) % 100) test('row heights follow the estimateSize formula exactly', async ({ page, }) => { - await page.goto('/') + await page.goto('/variable') const row0 = page.locator('.scroll-row .item', { hasText: new RegExp(`^Row 0 — ${rowSize(0)}px$`), }) @@ -46,7 +46,7 @@ test('row heights follow the estimateSize formula exactly', async ({ test('deep scroll re-windows and the formula still holds at index 500', async ({ page, }) => { - await page.goto('/') + await page.goto('/variable') // Offset of index 500 = sum of sizes 0..499; compute it the same way core does. let offset = 0 for (let i = 0; i < 500; i++) offset += rowSize(i) @@ -65,7 +65,7 @@ test('deep scroll re-windows and the formula still holds at index 500', async ({ }) test('columns re-window horizontally', async ({ page }) => { - await page.goto('/') + await page.goto('/variable') await expect( page.locator('.scroll-col .item', { hasText: /^Col 0$/ }), ).toBeVisible() diff --git a/examples/marko/window-ssr-slice/e2e/window-ssr-slice.spec.ts b/packages/marko-virtual/e2e/app/e2e/window-ssr-slice.spec.ts similarity index 96% rename from examples/marko/window-ssr-slice/e2e/window-ssr-slice.spec.ts rename to packages/marko-virtual/e2e/app/e2e/window-ssr-slice.spec.ts index b6b8f13d5..94dcb8455 100644 --- a/examples/marko/window-ssr-slice/e2e/window-ssr-slice.spec.ts +++ b/packages/marko-virtual/e2e/app/e2e/window-ssr-slice.spec.ts @@ -34,7 +34,7 @@ test.afterEach(() => { test('server HTML contains the painted window slice with the real total size', async ({ request, }) => { - const res = await request.get('/') + const res = await request.get('/window-ssr-slice') expect(res.ok()).toBe(true) const html = await res.text() expect(html).toContain('item-even') @@ -57,7 +57,7 @@ test('with JavaScript disabled the painted rows exist in the DOM (streaming swap // the streamed markup as well). const context = await browser.newContext({ javaScriptEnabled: false }) const page = await context.newPage() - await page.goto('/') + await page.goto('/window-ssr-slice') expect( await page.locator('.email', { hasText: 'person1@example.com' }).count(), ).toBe(1) @@ -68,7 +68,7 @@ test('with JavaScript disabled the painted rows exist in the DOM (streaming swap test('client resumes and the window virtualizer is live: page scroll re-windows', async ({ page, }) => { - await page.goto('/') + await page.goto('/window-ssr-slice') await expect( page.locator('.email', { hasText: 'person1@example.com' }), ).toBeVisible() diff --git a/examples/marko/window/e2e/window.spec.ts b/packages/marko-virtual/e2e/app/e2e/window.spec.ts similarity index 97% rename from examples/marko/window/e2e/window.spec.ts rename to packages/marko-virtual/e2e/app/e2e/window.spec.ts index 21ff072df..ba7cc3626 100644 --- a/examples/marko/window/e2e/window.spec.ts +++ b/packages/marko-virtual/e2e/app/e2e/window.spec.ts @@ -32,7 +32,7 @@ test.afterEach(() => { test('rows are positioned after the heading (measured scrollMargin applied)', async ({ page, }) => { - await page.goto('/') + await page.goto('/window') await expect(page.locator('.item', { hasText: /^Row 0$/ })).toBeVisible() // The prose above pushes the list down; row 0 must sit exactly at the list // wrapper's top, not at the page top. @@ -48,7 +48,7 @@ test('rows are positioned after the heading (measured scrollMargin applied)', as test('wrapper height is the margin-free totalSize (10000 x 35)', async ({ page, }) => { - await page.goto('/') + await page.goto('/window') await expect(page.locator('.item', { hasText: /^Row 0$/ })).toBeVisible() const wrapperHeight = await page .locator('div[style*="position: relative"]') @@ -62,7 +62,7 @@ test('wrapper height is the margin-free totalSize (10000 x 35)', async ({ test('deep window scroll re-windows relative to the LIST, not the page top', async ({ page, }) => { - await page.goto('/') + await page.goto('/window') await expect(page.locator('.item', { hasText: /^Row 0$/ })).toBeVisible() const listTop = await page.evaluate(() => { const el = document.querySelector( diff --git a/packages/marko-virtual/e2e/option-gates/marko.json b/packages/marko-virtual/e2e/app/marko.json similarity index 100% rename from packages/marko-virtual/e2e/option-gates/marko.json rename to packages/marko-virtual/e2e/app/marko.json diff --git a/packages/marko-virtual/e2e/option-gates/package.json b/packages/marko-virtual/e2e/app/package.json similarity index 53% rename from packages/marko-virtual/e2e/option-gates/package.json rename to packages/marko-virtual/e2e/app/package.json index fb3637d67..1b77e055d 100644 --- a/packages/marko-virtual/e2e/option-gates/package.json +++ b/packages/marko-virtual/e2e/app/package.json @@ -1,9 +1,11 @@ { - "name": "tanstack-marko-virtual-option-gates", + "name": "tanstack-marko-virtual-e2e", "private": true, "type": "module", "scripts": { "dev": "marko-run dev", + "build": "marko-run build", + "preview": "marko-run preview", "test:e2e": "playwright test", "test:types": "marko-type-check" }, @@ -11,6 +13,20 @@ "@marko/run": "^0.10.0", "marko": "^6.2.2" }, + "nx": { + "implicitDependencies": [ + "@tanstack/marko-virtual" + ], + "targets": { + "test:e2e": { + "inputs": [ + "default", + "^production", + "{workspaceRoot}/examples/marko/**/*" + ] + } + } + }, "devDependencies": { "@marko/language-tools": "^2.6.2", "@marko/type-check": "3.1.1", diff --git a/packages/marko-virtual/e2e/app/playwright.config.ts b/packages/marko-virtual/e2e/app/playwright.config.ts new file mode 100644 index 000000000..a32be6f5f --- /dev/null +++ b/packages/marko-virtual/e2e/app/playwright.config.ts @@ -0,0 +1,52 @@ +import { defineConfig } from '@playwright/test' + +// One app, one server, one config for the whole Marko browser suite. Each scenario +// is a route (`/chat`, `/table`, `/ssr-slice`, the option gates, …) rather than its +// own project: 19 example-local suites meant 19 dev servers, 19 ports and 19 copies +// of this file, and a port that silently moved (marko-run falls back to a random +// free port) surfaced only as a 120s webServer timeout with the real error hidden. +// +// Override to point a run at a manually started server. +const PORT = Number(process.env.MARKO_E2E_PORT ?? 4199) +const baseURL = `http://localhost:${PORT}` + +export default defineConfig({ + testDir: './e2e', + timeout: 60_000, + // No retries: these are scroll/measurement assertions, and a retry that turns + // red into green would hide exactly the timing regressions the suite exists to + // catch. Nx flags a task that passes only on re-run as flaky instead. + retries: 0, + // Serial by design. The specs assert on scroll offsets and measured sizes, which + // are sensitive to machine load; one worker keeps a failure meaningful. The whole + // suite is ~45s, so there is nothing to buy back here. + workers: 1, + use: { + baseURL, + // Without a trace a CI-only failure is a stack trace with no page state, and + // the DOM at the moment the scroll offset went wrong is the entire diagnosis + // for this suite. The trace carries screenshots itself, so no separate + // screenshot setting is needed. + trace: 'retain-on-failure', + }, + webServer: { + // Build and serve, not the dev server. This is the app users deploy: the + // production SSR/resume path, no HMR client injected into the console-error + // assertions, and every route compiled up front so no test pays a cold Marko + // compile mid-assertion (which showed up as intermittent chat and + // window-ssr-slice failures on a cold tree — i.e. on CI). The build is ~2s, and + // it matches how react-virtual's suite runs. Anything that can only be observed + // in dev (core's debug logging is compiled out by NODE_ENV) belongs in the + // vitest tier, not here — see tests/options.test.ts. + command: `npm run build && npm run preview -- --port ${PORT}`, + url: baseURL, + // Reuse a manually-started server if one is already up — `npm run dev -- --port + // 4199` for HMR while writing a spec, or `npm run preview`. CI starts its own. + reuseExistingServer: !process.env.CI, + // Surface the dev server's output in the test terminal so a crashing or + // slow-compiling server is visible instead of a silent stall. + stdout: 'pipe', + stderr: 'pipe', + timeout: 120_000, + }, +}) diff --git a/packages/marko-virtual/e2e/option-gates/src/routes/+page.marko b/packages/marko-virtual/e2e/app/src/routes/+page.marko similarity index 100% rename from packages/marko-virtual/e2e/option-gates/src/routes/+page.marko rename to packages/marko-virtual/e2e/app/src/routes/+page.marko diff --git a/packages/marko-virtual/e2e/app/src/routes/api/reply/+handler.ts b/packages/marko-virtual/e2e/app/src/routes/api/reply/+handler.ts new file mode 100644 index 000000000..1d4103f86 --- /dev/null +++ b/packages/marko-virtual/e2e/app/src/routes/api/reply/+handler.ts @@ -0,0 +1,5 @@ +// The chat fixtures POST to an absolute /api/reply, so the streaming handler is +// mounted once at the app root and shared by both. Re-exported from the chat +// example rather than copied: the example is the single source of truth, so a +// change to its streaming shape is exercised here instead of drifting from it. +export { POST } from '../../../../../../../../examples/marko/chat/src/routes/api/reply/+handler' diff --git a/packages/marko-virtual/e2e/option-gates/src/routes/cached/+page.marko b/packages/marko-virtual/e2e/app/src/routes/cached/+page.marko similarity index 100% rename from packages/marko-virtual/e2e/option-gates/src/routes/cached/+page.marko rename to packages/marko-virtual/e2e/app/src/routes/cached/+page.marko diff --git a/packages/marko-virtual/e2e/app/src/routes/chat-pretext/+page.marko b/packages/marko-virtual/e2e/app/src/routes/chat-pretext/+page.marko new file mode 100644 index 000000000..7ff496970 --- /dev/null +++ b/packages/marko-virtual/e2e/app/src/routes/chat-pretext/+page.marko @@ -0,0 +1,2 @@ +import Page from "../../../../../../../examples/marko/chat-pretext/src/routes/+page.marko" + diff --git a/packages/marko-virtual/e2e/app/src/routes/chat/+page.marko b/packages/marko-virtual/e2e/app/src/routes/chat/+page.marko new file mode 100644 index 000000000..091b05bb0 --- /dev/null +++ b/packages/marko-virtual/e2e/app/src/routes/chat/+page.marko @@ -0,0 +1,2 @@ +import Page from "../../../../../../../examples/marko/chat/src/routes/+page.marko" + diff --git a/packages/marko-virtual/e2e/option-gates/src/routes/debug/+page.marko b/packages/marko-virtual/e2e/app/src/routes/debug/+page.marko similarity index 100% rename from packages/marko-virtual/e2e/option-gates/src/routes/debug/+page.marko rename to packages/marko-virtual/e2e/app/src/routes/debug/+page.marko diff --git a/packages/marko-virtual/e2e/app/src/routes/dynamic/+page.marko b/packages/marko-virtual/e2e/app/src/routes/dynamic/+page.marko new file mode 100644 index 000000000..2354d000a --- /dev/null +++ b/packages/marko-virtual/e2e/app/src/routes/dynamic/+page.marko @@ -0,0 +1,2 @@ +import Page from "../../../../../../../examples/marko/dynamic/src/routes/+page.marko" + diff --git a/packages/marko-virtual/e2e/option-gates/src/routes/enabled/+page.marko b/packages/marko-virtual/e2e/app/src/routes/enabled/+page.marko similarity index 100% rename from packages/marko-virtual/e2e/option-gates/src/routes/enabled/+page.marko rename to packages/marko-virtual/e2e/app/src/routes/enabled/+page.marko diff --git a/packages/marko-virtual/e2e/app/src/routes/fixed/+page.marko b/packages/marko-virtual/e2e/app/src/routes/fixed/+page.marko new file mode 100644 index 000000000..967e44c6f --- /dev/null +++ b/packages/marko-virtual/e2e/app/src/routes/fixed/+page.marko @@ -0,0 +1,2 @@ +import Page from "../../../../../../../examples/marko/fixed/src/routes/+page.marko" + diff --git a/packages/marko-virtual/e2e/app/src/routes/grid/+page.marko b/packages/marko-virtual/e2e/app/src/routes/grid/+page.marko new file mode 100644 index 000000000..941486dd7 --- /dev/null +++ b/packages/marko-virtual/e2e/app/src/routes/grid/+page.marko @@ -0,0 +1,2 @@ +import Page from "../../../../../../../examples/marko/grid/src/routes/+page.marko" + diff --git a/packages/marko-virtual/e2e/app/src/routes/infinite-scroll/+page.marko b/packages/marko-virtual/e2e/app/src/routes/infinite-scroll/+page.marko new file mode 100644 index 000000000..5c72a3d38 --- /dev/null +++ b/packages/marko-virtual/e2e/app/src/routes/infinite-scroll/+page.marko @@ -0,0 +1,2 @@ +import Page from "../../../../../../../examples/marko/infinite-scroll/src/routes/+page.marko" + diff --git a/packages/marko-virtual/e2e/option-gates/src/routes/lanes-mode/+page.marko b/packages/marko-virtual/e2e/app/src/routes/lanes-mode/+page.marko similarity index 100% rename from packages/marko-virtual/e2e/option-gates/src/routes/lanes-mode/+page.marko rename to packages/marko-virtual/e2e/app/src/routes/lanes-mode/+page.marko diff --git a/packages/marko-virtual/e2e/option-gates/src/routes/measure-element/+page.marko b/packages/marko-virtual/e2e/app/src/routes/measure-element/+page.marko similarity index 100% rename from packages/marko-virtual/e2e/option-gates/src/routes/measure-element/+page.marko rename to packages/marko-virtual/e2e/app/src/routes/measure-element/+page.marko diff --git a/packages/marko-virtual/e2e/app/src/routes/padding/+page.marko b/packages/marko-virtual/e2e/app/src/routes/padding/+page.marko new file mode 100644 index 000000000..94b2c9060 --- /dev/null +++ b/packages/marko-virtual/e2e/app/src/routes/padding/+page.marko @@ -0,0 +1,2 @@ +import Page from "../../../../../../../examples/marko/padding/src/routes/+page.marko" + diff --git a/packages/marko-virtual/e2e/app/src/routes/pretext/+page.marko b/packages/marko-virtual/e2e/app/src/routes/pretext/+page.marko new file mode 100644 index 000000000..c1db452b9 --- /dev/null +++ b/packages/marko-virtual/e2e/app/src/routes/pretext/+page.marko @@ -0,0 +1,2 @@ +import Page from "../../../../../../../examples/marko/pretext/src/routes/+page.marko" + diff --git a/packages/marko-virtual/e2e/option-gates/src/routes/rtl/+page.marko b/packages/marko-virtual/e2e/app/src/routes/rtl/+page.marko similarity index 100% rename from packages/marko-virtual/e2e/option-gates/src/routes/rtl/+page.marko rename to packages/marko-virtual/e2e/app/src/routes/rtl/+page.marko diff --git a/packages/marko-virtual/e2e/option-gates/src/routes/scroll-events/+page.marko b/packages/marko-virtual/e2e/app/src/routes/scroll-events/+page.marko similarity index 100% rename from packages/marko-virtual/e2e/option-gates/src/routes/scroll-events/+page.marko rename to packages/marko-virtual/e2e/app/src/routes/scroll-events/+page.marko diff --git a/packages/marko-virtual/e2e/option-gates/src/routes/scroll-margin/+page.marko b/packages/marko-virtual/e2e/app/src/routes/scroll-margin/+page.marko similarity index 100% rename from packages/marko-virtual/e2e/option-gates/src/routes/scroll-margin/+page.marko rename to packages/marko-virtual/e2e/app/src/routes/scroll-margin/+page.marko diff --git a/packages/marko-virtual/e2e/app/src/routes/scroll-padding/+page.marko b/packages/marko-virtual/e2e/app/src/routes/scroll-padding/+page.marko new file mode 100644 index 000000000..ca4d1f8e8 --- /dev/null +++ b/packages/marko-virtual/e2e/app/src/routes/scroll-padding/+page.marko @@ -0,0 +1,2 @@ +import Page from "../../../../../../../examples/marko/scroll-padding/src/routes/+page.marko" + diff --git a/packages/marko-virtual/e2e/app/src/routes/smooth-scroll/+page.marko b/packages/marko-virtual/e2e/app/src/routes/smooth-scroll/+page.marko new file mode 100644 index 000000000..654055e37 --- /dev/null +++ b/packages/marko-virtual/e2e/app/src/routes/smooth-scroll/+page.marko @@ -0,0 +1,2 @@ +import Page from "../../../../../../../examples/marko/smooth-scroll/src/routes/+page.marko" + diff --git a/packages/marko-virtual/e2e/app/src/routes/ssr-fetch/+page.marko b/packages/marko-virtual/e2e/app/src/routes/ssr-fetch/+page.marko new file mode 100644 index 000000000..d75ef75a8 --- /dev/null +++ b/packages/marko-virtual/e2e/app/src/routes/ssr-fetch/+page.marko @@ -0,0 +1,2 @@ +import Page from "../../../../../../../examples/marko/ssr-fetch/src/routes/+page.marko" + diff --git a/packages/marko-virtual/e2e/app/src/routes/ssr-restore/+page.marko b/packages/marko-virtual/e2e/app/src/routes/ssr-restore/+page.marko new file mode 100644 index 000000000..e05ffe4e1 --- /dev/null +++ b/packages/marko-virtual/e2e/app/src/routes/ssr-restore/+page.marko @@ -0,0 +1,2 @@ +import Page from "../../../../../../../examples/marko/ssr-restore/src/routes/+page.marko" + diff --git a/packages/marko-virtual/e2e/app/src/routes/ssr-slice/+page.marko b/packages/marko-virtual/e2e/app/src/routes/ssr-slice/+page.marko new file mode 100644 index 000000000..a22aa3e76 --- /dev/null +++ b/packages/marko-virtual/e2e/app/src/routes/ssr-slice/+page.marko @@ -0,0 +1,2 @@ +import Page from "../../../../../../../examples/marko/ssr-slice/src/routes/+page.marko" + diff --git a/packages/marko-virtual/e2e/app/src/routes/ssr/+page.marko b/packages/marko-virtual/e2e/app/src/routes/ssr/+page.marko new file mode 100644 index 000000000..937f49df6 --- /dev/null +++ b/packages/marko-virtual/e2e/app/src/routes/ssr/+page.marko @@ -0,0 +1,2 @@ +import Page from "../../../../../../../examples/marko/ssr/src/routes/+page.marko" + diff --git a/packages/marko-virtual/e2e/app/src/routes/sticky/+page.marko b/packages/marko-virtual/e2e/app/src/routes/sticky/+page.marko new file mode 100644 index 000000000..dbddcc88d --- /dev/null +++ b/packages/marko-virtual/e2e/app/src/routes/sticky/+page.marko @@ -0,0 +1,2 @@ +import Page from "../../../../../../../examples/marko/sticky/src/routes/+page.marko" + diff --git a/packages/marko-virtual/e2e/app/src/routes/table/+page.marko b/packages/marko-virtual/e2e/app/src/routes/table/+page.marko new file mode 100644 index 000000000..6e6fb9345 --- /dev/null +++ b/packages/marko-virtual/e2e/app/src/routes/table/+page.marko @@ -0,0 +1,2 @@ +import Page from "../../../../../../../examples/marko/table/src/routes/+page.marko" + diff --git a/packages/marko-virtual/e2e/app/src/routes/variable/+page.marko b/packages/marko-virtual/e2e/app/src/routes/variable/+page.marko new file mode 100644 index 000000000..5b3e1a36c --- /dev/null +++ b/packages/marko-virtual/e2e/app/src/routes/variable/+page.marko @@ -0,0 +1,2 @@ +import Page from "../../../../../../../examples/marko/variable/src/routes/+page.marko" + diff --git a/packages/marko-virtual/e2e/option-gates/src/routes/window-example/+page.marko b/packages/marko-virtual/e2e/app/src/routes/window-example/+page.marko similarity index 100% rename from packages/marko-virtual/e2e/option-gates/src/routes/window-example/+page.marko rename to packages/marko-virtual/e2e/app/src/routes/window-example/+page.marko diff --git a/packages/marko-virtual/e2e/option-gates/src/routes/window-horizontal/+page.marko b/packages/marko-virtual/e2e/app/src/routes/window-horizontal/+page.marko similarity index 100% rename from packages/marko-virtual/e2e/option-gates/src/routes/window-horizontal/+page.marko rename to packages/marko-virtual/e2e/app/src/routes/window-horizontal/+page.marko diff --git a/packages/marko-virtual/e2e/option-gates/src/routes/window-initial-offset/+page.marko b/packages/marko-virtual/e2e/app/src/routes/window-initial-offset/+page.marko similarity index 100% rename from packages/marko-virtual/e2e/option-gates/src/routes/window-initial-offset/+page.marko rename to packages/marko-virtual/e2e/app/src/routes/window-initial-offset/+page.marko diff --git a/packages/marko-virtual/e2e/app/src/routes/window-ssr-slice/+page.marko b/packages/marko-virtual/e2e/app/src/routes/window-ssr-slice/+page.marko new file mode 100644 index 000000000..09911d8c0 --- /dev/null +++ b/packages/marko-virtual/e2e/app/src/routes/window-ssr-slice/+page.marko @@ -0,0 +1,2 @@ +import Page from "../../../../../../../examples/marko/window-ssr-slice/src/routes/+page.marko" + diff --git a/packages/marko-virtual/e2e/app/src/routes/window/+page.marko b/packages/marko-virtual/e2e/app/src/routes/window/+page.marko new file mode 100644 index 000000000..0f7446375 --- /dev/null +++ b/packages/marko-virtual/e2e/app/src/routes/window/+page.marko @@ -0,0 +1,2 @@ +import Page from "../../../../../../../examples/marko/window/src/routes/+page.marko" + diff --git a/packages/marko-virtual/e2e/option-gates/tsconfig.json b/packages/marko-virtual/e2e/app/tsconfig.json similarity index 85% rename from packages/marko-virtual/e2e/option-gates/tsconfig.json rename to packages/marko-virtual/e2e/app/tsconfig.json index c27ccaf5c..f4fbd758d 100644 --- a/packages/marko-virtual/e2e/option-gates/tsconfig.json +++ b/packages/marko-virtual/e2e/app/tsconfig.json @@ -16,6 +16,7 @@ "e2e", "playwright.config.ts", "vite.config.ts", - "../../src/tags/**/*" + "../../src/tags/**/*", + "../../../../examples/marko/*/src/**/*" ] } diff --git a/packages/marko-virtual/e2e/app/vite.config.ts b/packages/marko-virtual/e2e/app/vite.config.ts new file mode 100644 index 000000000..33fc4b255 --- /dev/null +++ b/packages/marko-virtual/e2e/app/vite.config.ts @@ -0,0 +1,26 @@ +import { defineConfig } from 'vite' +import marko from '@marko/run/vite' +import path from 'node:path' + +export default defineConfig({ + plugins: [marko() as any], + resolve: { + alias: { + // Run the suite against SOURCE so no build is needed — and so a core or + // adapter fix can be verified by editing src alone. These are path aliases, + // not dependencies: adding @tanstack/marko-virtual to this app's + // package.json would create the pnpm symlink cycle described in README.md. + // + // The adapter alias covers the example fixtures that import the package's JS + // API (sticky's defaultRangeExtractor). Without it the suite would resolve + // that import to dist/ and silently become build-dependent again — which is + // how the previous per-example setup broke: a missing dist/tags surfaced only + // as a 120s webServer timeout. + '@tanstack/marko-virtual': path.resolve(__dirname, '../../src/index.ts'), + '@tanstack/virtual-core': path.resolve( + __dirname, + '../../../virtual-core/src/index.ts', + ), + }, + }, +}) diff --git a/packages/marko-virtual/e2e/option-gates/.marko-run/routes.d.ts b/packages/marko-virtual/e2e/option-gates/.marko-run/routes.d.ts deleted file mode 100644 index 5723c4df6..000000000 --- a/packages/marko-virtual/e2e/option-gates/.marko-run/routes.d.ts +++ /dev/null @@ -1,372 +0,0 @@ -/* - WARNING: This file is automatically generated and any changes made to it will be overwritten without warning. - Do NOT manually edit this file or your changes will be lost. -*/ - -import { - NotHandled, - NotMatched, - GetPaths, - PostPaths, - GetablePath, - GetableHref, - PostablePath, - PostableHref, - Platform, -} from '@marko/run/namespace' -import type * as Run from '@marko/run' - -declare module '@marko/run' { - interface AppData extends Run.DefineApp<{ - routes: { - '/': { verb: 'get' } - '/cached': { verb: 'get' } - '/debug': { verb: 'get' } - '/enabled': { verb: 'get' } - '/lanes-mode': { verb: 'get' } - '/measure-element': { verb: 'get' } - '/rtl': { verb: 'get' } - '/scroll-events': { verb: 'get' } - '/scroll-margin': { verb: 'get' } - '/window-example': { verb: 'get' } - '/window-horizontal': { verb: 'get' } - '/window-initial-offset': { verb: 'get' } - } - }> {} -} - -declare module '../src/routes/+page.marko' { - namespace MarkoRun { - export { - NotHandled, - NotMatched, - GetPaths, - PostPaths, - GetablePath, - GetableHref, - PostablePath, - PostableHref, - Platform, - } - export type Route = Run.Routes['/'] - export type Context = Run.MultiRouteContext & Marko.Global - export type Handler = Run.HandlerLike - export type GET = Run.HandlerLike - export type HEAD = Run.HandlerLike - export type POST = Run.HandlerLike - export type PUT = Run.HandlerLike - export type DELETE = Run.HandlerLike - export type PATCH = Run.HandlerLike - export type OPTIONS = Run.HandlerLike - /** @deprecated use `((context, next) => { ... }) satisfies MarkoRun.Handler` instead */ - export const route: Run.HandlerTypeFn - } -} - -declare module '../src/routes/cached/+page.marko' { - namespace MarkoRun { - export { - NotHandled, - NotMatched, - GetPaths, - PostPaths, - GetablePath, - GetableHref, - PostablePath, - PostableHref, - Platform, - } - export type Route = Run.Routes['/cached'] - export type Context = Run.MultiRouteContext & Marko.Global - export type Handler = Run.HandlerLike - export type GET = Run.HandlerLike - export type HEAD = Run.HandlerLike - export type POST = Run.HandlerLike - export type PUT = Run.HandlerLike - export type DELETE = Run.HandlerLike - export type PATCH = Run.HandlerLike - export type OPTIONS = Run.HandlerLike - /** @deprecated use `((context, next) => { ... }) satisfies MarkoRun.Handler` instead */ - export const route: Run.HandlerTypeFn - } -} - -declare module '../src/routes/debug/+page.marko' { - namespace MarkoRun { - export { - NotHandled, - NotMatched, - GetPaths, - PostPaths, - GetablePath, - GetableHref, - PostablePath, - PostableHref, - Platform, - } - export type Route = Run.Routes['/debug'] - export type Context = Run.MultiRouteContext & Marko.Global - export type Handler = Run.HandlerLike - export type GET = Run.HandlerLike - export type HEAD = Run.HandlerLike - export type POST = Run.HandlerLike - export type PUT = Run.HandlerLike - export type DELETE = Run.HandlerLike - export type PATCH = Run.HandlerLike - export type OPTIONS = Run.HandlerLike - /** @deprecated use `((context, next) => { ... }) satisfies MarkoRun.Handler` instead */ - export const route: Run.HandlerTypeFn - } -} - -declare module '../src/routes/enabled/+page.marko' { - namespace MarkoRun { - export { - NotHandled, - NotMatched, - GetPaths, - PostPaths, - GetablePath, - GetableHref, - PostablePath, - PostableHref, - Platform, - } - export type Route = Run.Routes['/enabled'] - export type Context = Run.MultiRouteContext & Marko.Global - export type Handler = Run.HandlerLike - export type GET = Run.HandlerLike - export type HEAD = Run.HandlerLike - export type POST = Run.HandlerLike - export type PUT = Run.HandlerLike - export type DELETE = Run.HandlerLike - export type PATCH = Run.HandlerLike - export type OPTIONS = Run.HandlerLike - /** @deprecated use `((context, next) => { ... }) satisfies MarkoRun.Handler` instead */ - export const route: Run.HandlerTypeFn - } -} - -declare module '../src/routes/lanes-mode/+page.marko' { - namespace MarkoRun { - export { - NotHandled, - NotMatched, - GetPaths, - PostPaths, - GetablePath, - GetableHref, - PostablePath, - PostableHref, - Platform, - } - export type Route = Run.Routes['/lanes-mode'] - export type Context = Run.MultiRouteContext & Marko.Global - export type Handler = Run.HandlerLike - export type GET = Run.HandlerLike - export type HEAD = Run.HandlerLike - export type POST = Run.HandlerLike - export type PUT = Run.HandlerLike - export type DELETE = Run.HandlerLike - export type PATCH = Run.HandlerLike - export type OPTIONS = Run.HandlerLike - /** @deprecated use `((context, next) => { ... }) satisfies MarkoRun.Handler` instead */ - export const route: Run.HandlerTypeFn - } -} - -declare module '../src/routes/measure-element/+page.marko' { - namespace MarkoRun { - export { - NotHandled, - NotMatched, - GetPaths, - PostPaths, - GetablePath, - GetableHref, - PostablePath, - PostableHref, - Platform, - } - export type Route = Run.Routes['/measure-element'] - export type Context = Run.MultiRouteContext & Marko.Global - export type Handler = Run.HandlerLike - export type GET = Run.HandlerLike - export type HEAD = Run.HandlerLike - export type POST = Run.HandlerLike - export type PUT = Run.HandlerLike - export type DELETE = Run.HandlerLike - export type PATCH = Run.HandlerLike - export type OPTIONS = Run.HandlerLike - /** @deprecated use `((context, next) => { ... }) satisfies MarkoRun.Handler` instead */ - export const route: Run.HandlerTypeFn - } -} - -declare module '../src/routes/rtl/+page.marko' { - namespace MarkoRun { - export { - NotHandled, - NotMatched, - GetPaths, - PostPaths, - GetablePath, - GetableHref, - PostablePath, - PostableHref, - Platform, - } - export type Route = Run.Routes['/rtl'] - export type Context = Run.MultiRouteContext & Marko.Global - export type Handler = Run.HandlerLike - export type GET = Run.HandlerLike - export type HEAD = Run.HandlerLike - export type POST = Run.HandlerLike - export type PUT = Run.HandlerLike - export type DELETE = Run.HandlerLike - export type PATCH = Run.HandlerLike - export type OPTIONS = Run.HandlerLike - /** @deprecated use `((context, next) => { ... }) satisfies MarkoRun.Handler` instead */ - export const route: Run.HandlerTypeFn - } -} - -declare module '../src/routes/scroll-events/+page.marko' { - namespace MarkoRun { - export { - NotHandled, - NotMatched, - GetPaths, - PostPaths, - GetablePath, - GetableHref, - PostablePath, - PostableHref, - Platform, - } - export type Route = Run.Routes['/scroll-events'] - export type Context = Run.MultiRouteContext & Marko.Global - export type Handler = Run.HandlerLike - export type GET = Run.HandlerLike - export type HEAD = Run.HandlerLike - export type POST = Run.HandlerLike - export type PUT = Run.HandlerLike - export type DELETE = Run.HandlerLike - export type PATCH = Run.HandlerLike - export type OPTIONS = Run.HandlerLike - /** @deprecated use `((context, next) => { ... }) satisfies MarkoRun.Handler` instead */ - export const route: Run.HandlerTypeFn - } -} - -declare module '../src/routes/scroll-margin/+page.marko' { - namespace MarkoRun { - export { - NotHandled, - NotMatched, - GetPaths, - PostPaths, - GetablePath, - GetableHref, - PostablePath, - PostableHref, - Platform, - } - export type Route = Run.Routes['/scroll-margin'] - export type Context = Run.MultiRouteContext & Marko.Global - export type Handler = Run.HandlerLike - export type GET = Run.HandlerLike - export type HEAD = Run.HandlerLike - export type POST = Run.HandlerLike - export type PUT = Run.HandlerLike - export type DELETE = Run.HandlerLike - export type PATCH = Run.HandlerLike - export type OPTIONS = Run.HandlerLike - /** @deprecated use `((context, next) => { ... }) satisfies MarkoRun.Handler` instead */ - export const route: Run.HandlerTypeFn - } -} - -declare module '../src/routes/window-example/+page.marko' { - namespace MarkoRun { - export { - NotHandled, - NotMatched, - GetPaths, - PostPaths, - GetablePath, - GetableHref, - PostablePath, - PostableHref, - Platform, - } - export type Route = Run.Routes['/window-example'] - export type Context = Run.MultiRouteContext & Marko.Global - export type Handler = Run.HandlerLike - export type GET = Run.HandlerLike - export type HEAD = Run.HandlerLike - export type POST = Run.HandlerLike - export type PUT = Run.HandlerLike - export type DELETE = Run.HandlerLike - export type PATCH = Run.HandlerLike - export type OPTIONS = Run.HandlerLike - /** @deprecated use `((context, next) => { ... }) satisfies MarkoRun.Handler` instead */ - export const route: Run.HandlerTypeFn - } -} - -declare module '../src/routes/window-horizontal/+page.marko' { - namespace MarkoRun { - export { - NotHandled, - NotMatched, - GetPaths, - PostPaths, - GetablePath, - GetableHref, - PostablePath, - PostableHref, - Platform, - } - export type Route = Run.Routes['/window-horizontal'] - export type Context = Run.MultiRouteContext & Marko.Global - export type Handler = Run.HandlerLike - export type GET = Run.HandlerLike - export type HEAD = Run.HandlerLike - export type POST = Run.HandlerLike - export type PUT = Run.HandlerLike - export type DELETE = Run.HandlerLike - export type PATCH = Run.HandlerLike - export type OPTIONS = Run.HandlerLike - /** @deprecated use `((context, next) => { ... }) satisfies MarkoRun.Handler` instead */ - export const route: Run.HandlerTypeFn - } -} - -declare module '../src/routes/window-initial-offset/+page.marko' { - namespace MarkoRun { - export { - NotHandled, - NotMatched, - GetPaths, - PostPaths, - GetablePath, - GetableHref, - PostablePath, - PostableHref, - Platform, - } - export type Route = Run.Routes['/window-initial-offset'] - export type Context = Run.MultiRouteContext & Marko.Global - export type Handler = Run.HandlerLike - export type GET = Run.HandlerLike - export type HEAD = Run.HandlerLike - export type POST = Run.HandlerLike - export type PUT = Run.HandlerLike - export type DELETE = Run.HandlerLike - export type PATCH = Run.HandlerLike - export type OPTIONS = Run.HandlerLike - /** @deprecated use `((context, next) => { ... }) satisfies MarkoRun.Handler` instead */ - export const route: Run.HandlerTypeFn - } -} diff --git a/packages/marko-virtual/e2e/option-gates/README.md b/packages/marko-virtual/e2e/option-gates/README.md deleted file mode 100644 index 93bcaffc8..000000000 --- a/packages/marko-virtual/e2e/option-gates/README.md +++ /dev/null @@ -1,40 +0,0 @@ -# Option gates (throwaway test harness — not a shipped example) - -Real-Chromium behavioral proofs for the full-parity option batch added in -session 5 (scrollMargin, enabled, isRtl, isScrollingResetDelay, useScrollendEvent, -useAnimationFrameWithResizeObserver, laneAssignmentMode, useCachedMeasurements, -debug, custom measureElement, and the window tag's horizontal + initialOffset), -plus the fixed window example verbatim. One deliberately artificial page per -option under src/routes/, one Playwright spec (e2e/option-gates.spec.ts) that -asserts each option observably changes behavior. Port 4199 (examples use 4173). - -Location: packages/marko-virtual/e2e/option-gates. Relative paths assume exactly -this depth (marko.json -> ../../marko.json, vite alias -> -../../../virtual-core/src/index.ts). - -Install: covered by the repo-level `pnpm install` once the workspace glob -`packages/marko-virtual/e2e/*` is present in pnpm-workspace.yaml (included in -this bundle). First browser run may need `npx playwright install chromium`. - -Run: `npm run test:e2e` from this folder (the config starts the dev server -itself), or start `npm run dev -- --port 4199` manually and rerun to reuse it. - -Dependency note (do not re-add `@tanstack/marko-virtual` here): this package -lives INSIDE packages/marko-virtual. Depending on the ancestor makes pnpm -create node_modules/@tanstack/marko-virtual -> ../../.. — a symlink cycle. -`@marko/vite`'s production-only known-templates scan globs `**/*.marko` -following symlinks with no cycle guard, so any `marko-run build` of an app -that links the package (every example) dies with ENAMETOOLONG. The dep is -also unnecessary: the tags resolve through the relative taglib import above, -and virtual-core through the vite alias. If a real JS import from the package -is ever needed here, use pnpm's `dependenciesMeta` injected mode (which packs -a copy honoring the `files` field, so e2e/ is excluded and no cycle forms) -instead of a plain workspace dependency. - -Publishing: not affected — the package's `files` field publishes only dist, -src/tags, marko.json, and README.md, so nothing under e2e/ reaches npm. - -Known-bug note: the enabled gate carries a documented 250ms settle wait for an -upstream core bug (end-of-scroll debounce timer surviving observeOffset -unsubscription and firing a stale offset into the live instance). Remove the wait -if/when the cancellable-debounce core fix lands; the spec comment marks the spot. diff --git a/packages/marko-virtual/e2e/option-gates/playwright.config.ts b/packages/marko-virtual/e2e/option-gates/playwright.config.ts deleted file mode 100644 index de410b742..000000000 --- a/packages/marko-virtual/e2e/option-gates/playwright.config.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { defineConfig } from '@playwright/test' - -export default defineConfig({ - testDir: './e2e', - timeout: 60_000, - retries: 0, - workers: 1, - use: { - baseURL: 'http://localhost:4199', - }, - webServer: { - command: 'npm run dev -- --port 4199', - url: 'http://localhost:4199', - // Reuse a manually-started dev server (npm run dev -- --port 4199) if one is - // already up — simpler to debug; CI should start its own. - reuseExistingServer: !process.env.CI, - stdout: 'pipe', - stderr: 'pipe', - timeout: 120_000, - }, -}) diff --git a/packages/marko-virtual/e2e/option-gates/vite.config.ts b/packages/marko-virtual/e2e/option-gates/vite.config.ts deleted file mode 100644 index 42b1c6a94..000000000 --- a/packages/marko-virtual/e2e/option-gates/vite.config.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { defineConfig } from 'vite' -import marko from '@marko/run/vite' -import path from 'node:path' - -export default defineConfig({ - plugins: [marko() as any], - resolve: { - alias: { - // Run the gates against virtual-core SOURCE so no core build is needed — - // and so the optional core fix can be gate-verified by editing src alone. - '@tanstack/virtual-core': path.resolve( - __dirname, - '../../../virtual-core/src/index.ts', - ), - }, - }, -}) diff --git a/packages/marko-virtual/package.json b/packages/marko-virtual/package.json index 0283fda4a..66c44af60 100644 --- a/packages/marko-virtual/package.json +++ b/packages/marko-virtual/package.json @@ -55,7 +55,7 @@ "test:lib": "vitest", "test:lib:dev": "pnpm run test:lib --watch", "test:build": "publint --strict", - "build": "vite build && marko-type-check -p tsconfig.tags.json" + "build": "vite build && marko-type-check -p tsconfig.tags.json && premove ./dist/tsconfig.tags.tsbuildinfo" }, "dependencies": { "@tanstack/virtual-core": "workspace:*" diff --git a/packages/marko-virtual/tests/options.test.ts b/packages/marko-virtual/tests/options.test.ts index b67244ac7..44be90a46 100644 --- a/packages/marko-virtual/tests/options.test.ts +++ b/packages/marko-virtual/tests/options.test.ts @@ -7,7 +7,7 @@ // useCachedMeasurements, debug, custom measureElement — plus horizontal and an // initialOffset override on the window tag) is Tier-1 forwarding-tested here; the // behaviorally-observable subset has real-browser gates (see the session record). -import { describe, expect, test } from 'vitest' +import { describe, expect, test, vi } from 'vitest' import { Virtualizer, observeWindowRect, @@ -159,6 +159,34 @@ describe('buildOptions — input to virtual-core option mapping', () => { expect(opts.measureElement).toBeUndefined() }) + test('debug=true makes core emit its timing logs', () => { + // The observable effect of the debug option, not just its forwarding. This used + // to be a browser gate, which was the wrong tier twice over: a console.info + // needs no browser, and core writes it from a + // `process.env.NODE_ENV !== 'production'` branch, so it does not exist in the + // production build the e2e suite serves. Here NODE_ENV is 'test', so the branch + // is live. + const infos: Array = [] + const spy = vi + .spyOn(console, 'info') + .mockImplementation((...args: Array) => { + infos.push(args.map(String).join(' ')) + }) + try { + const v = new Virtualizer( + buildOptions( + { count: 100, getScrollElement: () => null, debug: true }, + noop, + ), + ) + // memo() logs when it computes; getVirtualItems pulls the memoized chain. + v.getVirtualItems() + } finally { + spy.mockRestore() + } + expect(infos.some((t) => t.includes('⏱'))).toBe(true) + }) + test('core merge contract: undefined forwards land on core defaults; provided values stick', () => { // The whole undefined-forwarding design leans on core's setOptions skipping // undefined keys. Characterize that contract against a REAL core instance so a diff --git a/packages/react-virtual/package.json b/packages/react-virtual/package.json index e2af702d6..fee25e15a 100644 --- a/packages/react-virtual/package.json +++ b/packages/react-virtual/package.json @@ -30,7 +30,7 @@ "test:lib:dev": "pnpm run test:lib --watch", "test:build": "publint --strict", "build": "vite build", - "test:e2e": "../../node_modules/.bin/playwright test" + "test:e2e": "playwright test" }, "type": "module", "types": "dist/esm/index.d.ts", diff --git a/packages/react-virtual/playwright.config.ts b/packages/react-virtual/playwright.config.ts index fd53aacba..8ee2fb7cd 100644 --- a/packages/react-virtual/playwright.config.ts +++ b/packages/react-virtual/playwright.config.ts @@ -1,15 +1,24 @@ import { defineConfig } from '@playwright/test' -const PORT = Number(process.env.VITE_SERVER_PORT ?? 5173) +// Not 5173: that is vite's default dev port, and with reuseExistingServer a stray +// `vite dev` from any other project in the tree means the suite silently runs +// against the WRONG app instead of failing. --strictPort below turns a port that is +// genuinely taken into an immediate error rather than a quiet rebind that leaves +// Playwright waiting on a dead URL. +const PORT = Number(process.env.VITE_SERVER_PORT ?? 5273) const baseURL = `http://localhost:${PORT}` export default defineConfig({ testDir: './e2e/app/test', use: { baseURL, + // Without a trace a CI-only failure is a stack trace with no page state, and + // the DOM at the moment a scroll offset went wrong is the whole diagnosis. The + // trace carries screenshots itself. + trace: 'retain-on-failure', }, webServer: { - command: `VITE_SERVER_PORT=${PORT} vite build --config e2e/app/vite.config.ts && VITE_SERVER_PORT=${PORT} vite build --config e2e/app/react-compiler-vite.config.ts && VITE_SERVER_PORT=${PORT} vite preview --config e2e/app/vite.config.ts --port ${PORT}`, + command: `VITE_SERVER_PORT=${PORT} vite build --config e2e/app/vite.config.ts && VITE_SERVER_PORT=${PORT} vite build --config e2e/app/react-compiler-vite.config.ts && VITE_SERVER_PORT=${PORT} vite preview --config e2e/app/vite.config.ts --port ${PORT} --strictPort`, url: `${baseURL}/scroll/`, reuseExistingServer: !process.env.CI, stdout: 'pipe', diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d8654eabd..f241ad001 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -22,10 +22,10 @@ importers: version: 1.56.1 '@tanstack/eslint-config': specifier: 0.3.4 - version: 0.3.4(@typescript-eslint/utils@8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.0(jiti@2.6.1))(typescript@5.9.3) + version: 0.3.4(@typescript-eslint/utils@8.46.2(eslint@9.39.0(jiti@2.6.1)(supports-color@10.2.2))(typescript@5.9.3))(eslint@9.39.0(jiti@2.6.1)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@5.9.3) '@tanstack/vite-config': specifier: 0.4.3 - version: 0.4.3(@types/node@24.9.2)(rollup@4.59.0)(typescript@5.9.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)) + version: 0.4.3(@types/node@24.9.2)(rollup@4.59.0)(supports-color@10.2.2)(typescript@5.9.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)) '@testing-library/jest-dom': specifier: ^6.6.3 version: 6.9.1 @@ -34,10 +34,10 @@ importers: version: 24.9.2 eslint: specifier: ^9.36.0 - version: 9.39.0(jiti@2.6.1) + version: 9.39.0(jiti@2.6.1)(supports-color@10.2.2) jsdom: specifier: ^27.0.0 - version: 27.1.0 + version: 27.1.0(supports-color@10.2.2) knip: specifier: ^5.63.1 version: 5.66.4(@types/node@24.9.2)(typescript@5.9.3) @@ -73,7 +73,7 @@ importers: version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1) vitest: specifier: ^4.1.4 - version: 4.1.4(@types/node@24.9.2)(jsdom@27.1.0)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)) + version: 4.1.4(@types/node@24.9.2)(jsdom@27.1.0(supports-color@10.2.2))(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)) benchmarks: dependencies: @@ -110,7 +110,7 @@ importers: version: 19.2.3(@types/react@19.2.16) '@vitejs/plugin-react': specifier: ^4.5.2 - version: 4.7.0(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)) + version: 4.7.0(supports-color@10.2.2)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)) typescript: specifier: 5.9.3 version: 5.9.3 @@ -159,10 +159,10 @@ importers: devDependencies: '@angular-devkit/build-angular': specifier: ^20.2.0 - version: 20.3.32(@angular/compiler-cli@20.3.26(@angular/compiler@20.3.26)(typescript@5.9.3))(@angular/compiler@20.3.26)(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.26(@angular/animations@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(lightningcss@1.33.0)(typescript@5.9.3)(vitest@4.1.4(@types/node@24.9.2)(jsdom@27.1.0)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)))(yaml@2.8.1) + version: 20.3.32(@angular/compiler-cli@20.3.26(@angular/compiler@20.3.26)(typescript@5.9.3))(@angular/compiler@20.3.26)(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.26(@angular/animations@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(lightningcss@1.33.0)(supports-color@10.2.2)(typescript@5.9.3)(vitest@4.1.4(@types/node@24.9.2)(jsdom@27.1.0(supports-color@10.2.2))(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)))(yaml@2.8.1) '@angular/cli': specifier: ^20.2.0 - version: 20.3.32(@types/node@24.9.2)(chokidar@4.0.3) + version: 20.3.32(@types/node@24.9.2)(chokidar@4.0.3)(supports-color@10.2.2) '@angular/compiler-cli': specifier: ^20.2.0 version: 20.3.26(@angular/compiler@20.3.26)(typescript@5.9.3) @@ -214,10 +214,10 @@ importers: devDependencies: '@angular-devkit/build-angular': specifier: ^20.2.0 - version: 20.3.32(@angular/compiler-cli@20.3.26(@angular/compiler@20.3.26)(typescript@5.9.3))(@angular/compiler@20.3.26)(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.26(@angular/animations@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(lightningcss@1.33.0)(typescript@5.9.3)(vitest@4.1.4(@types/node@24.9.2)(jsdom@27.1.0)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)))(yaml@2.8.1) + version: 20.3.32(@angular/compiler-cli@20.3.26(@angular/compiler@20.3.26)(typescript@5.9.3))(@angular/compiler@20.3.26)(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.26(@angular/animations@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(lightningcss@1.33.0)(typescript@5.9.3)(vitest@4.1.4(@types/node@24.9.2)(jsdom@27.1.0(supports-color@10.2.2))(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)))(yaml@2.8.1) '@angular/cli': specifier: ^20.2.0 - version: 20.3.32(@types/node@24.9.2)(chokidar@4.0.3) + version: 20.3.32(@types/node@24.9.2)(chokidar@4.0.3)(supports-color@10.2.2) '@angular/compiler-cli': specifier: ^20.2.0 version: 20.3.26(@angular/compiler@20.3.26)(typescript@5.9.3) @@ -266,10 +266,10 @@ importers: devDependencies: '@angular-devkit/build-angular': specifier: ^20.2.0 - version: 20.3.32(@angular/compiler-cli@20.3.26(@angular/compiler@20.3.26)(typescript@5.9.3))(@angular/compiler@20.3.26)(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.26(@angular/animations@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(lightningcss@1.33.0)(typescript@5.9.3)(vitest@4.1.4(@types/node@24.9.2)(jsdom@27.1.0)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)))(yaml@2.8.1) + version: 20.3.32(@angular/compiler-cli@20.3.26(@angular/compiler@20.3.26)(typescript@5.9.3))(@angular/compiler@20.3.26)(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.26(@angular/animations@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(lightningcss@1.33.0)(typescript@5.9.3)(vitest@4.1.4(@types/node@24.9.2)(jsdom@27.1.0(supports-color@10.2.2))(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)))(yaml@2.8.1) '@angular/cli': specifier: ^20.2.0 - version: 20.3.32(@types/node@24.9.2)(chokidar@4.0.3) + version: 20.3.32(@types/node@24.9.2)(chokidar@4.0.3)(supports-color@10.2.2) '@angular/compiler-cli': specifier: ^20.2.0 version: 20.3.26(@angular/compiler@20.3.26)(typescript@5.9.3) @@ -321,10 +321,10 @@ importers: devDependencies: '@angular-devkit/build-angular': specifier: ^20.2.0 - version: 20.3.32(@angular/compiler-cli@20.3.26(@angular/compiler@20.3.26)(typescript@5.9.3))(@angular/compiler@20.3.26)(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.26(@angular/animations@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(lightningcss@1.33.0)(typescript@5.9.3)(vitest@4.1.4(@types/node@24.9.2)(jsdom@27.1.0)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)))(yaml@2.8.1) + version: 20.3.32(@angular/compiler-cli@20.3.26(@angular/compiler@20.3.26)(typescript@5.9.3))(@angular/compiler@20.3.26)(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.26(@angular/animations@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(lightningcss@1.33.0)(typescript@5.9.3)(vitest@4.1.4(@types/node@24.9.2)(jsdom@27.1.0(supports-color@10.2.2))(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)))(yaml@2.8.1) '@angular/cli': specifier: ^20.2.0 - version: 20.3.32(@types/node@24.9.2)(chokidar@4.0.3) + version: 20.3.32(@types/node@24.9.2)(chokidar@4.0.3)(supports-color@10.2.2) '@angular/compiler-cli': specifier: ^20.2.0 version: 20.3.26(@angular/compiler@20.3.26)(typescript@5.9.3) @@ -373,10 +373,10 @@ importers: devDependencies: '@angular-devkit/build-angular': specifier: ^20.2.0 - version: 20.3.32(@angular/compiler-cli@20.3.26(@angular/compiler@20.3.26)(typescript@5.9.3))(@angular/compiler@20.3.26)(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.26(@angular/animations@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(lightningcss@1.33.0)(typescript@5.9.3)(vitest@4.1.4(@types/node@24.9.2)(jsdom@27.1.0)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)))(yaml@2.8.1) + version: 20.3.32(@angular/compiler-cli@20.3.26(@angular/compiler@20.3.26)(typescript@5.9.3))(@angular/compiler@20.3.26)(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.26(@angular/animations@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(lightningcss@1.33.0)(typescript@5.9.3)(vitest@4.1.4(@types/node@24.9.2)(jsdom@27.1.0(supports-color@10.2.2))(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)))(yaml@2.8.1) '@angular/cli': specifier: ^20.2.0 - version: 20.3.32(@types/node@24.9.2)(chokidar@4.0.3) + version: 20.3.32(@types/node@24.9.2)(chokidar@4.0.3)(supports-color@10.2.2) '@angular/compiler-cli': specifier: ^20.2.0 version: 20.3.26(@angular/compiler@20.3.26)(typescript@5.9.3) @@ -425,10 +425,10 @@ importers: devDependencies: '@angular-devkit/build-angular': specifier: ^20.2.0 - version: 20.3.32(@angular/compiler-cli@20.3.26(@angular/compiler@20.3.26)(typescript@5.9.3))(@angular/compiler@20.3.26)(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.26(@angular/animations@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(lightningcss@1.33.0)(typescript@5.9.3)(vitest@4.1.4(@types/node@24.9.2)(jsdom@27.1.0)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)))(yaml@2.8.1) + version: 20.3.32(@angular/compiler-cli@20.3.26(@angular/compiler@20.3.26)(typescript@5.9.3))(@angular/compiler@20.3.26)(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.26(@angular/animations@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(lightningcss@1.33.0)(typescript@5.9.3)(vitest@4.1.4(@types/node@24.9.2)(jsdom@27.1.0(supports-color@10.2.2))(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)))(yaml@2.8.1) '@angular/cli': specifier: ^20.2.0 - version: 20.3.32(@types/node@24.9.2)(chokidar@4.0.3) + version: 20.3.32(@types/node@24.9.2)(chokidar@4.0.3)(supports-color@10.2.2) '@angular/compiler-cli': specifier: ^20.2.0 version: 20.3.26(@angular/compiler@20.3.26)(typescript@5.9.3) @@ -480,10 +480,10 @@ importers: devDependencies: '@angular-devkit/build-angular': specifier: ^20.2.0 - version: 20.3.32(@angular/compiler-cli@20.3.26(@angular/compiler@20.3.26)(typescript@5.9.3))(@angular/compiler@20.3.26)(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.26(@angular/animations@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(lightningcss@1.33.0)(typescript@5.9.3)(vitest@4.1.4(@types/node@24.9.2)(jsdom@27.1.0)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)))(yaml@2.8.1) + version: 20.3.32(@angular/compiler-cli@20.3.26(@angular/compiler@20.3.26)(typescript@5.9.3))(@angular/compiler@20.3.26)(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.26(@angular/animations@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(lightningcss@1.33.0)(typescript@5.9.3)(vitest@4.1.4(@types/node@24.9.2)(jsdom@27.1.0(supports-color@10.2.2))(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)))(yaml@2.8.1) '@angular/cli': specifier: ^20.2.0 - version: 20.3.32(@types/node@24.9.2)(chokidar@4.0.3) + version: 20.3.32(@types/node@24.9.2)(chokidar@4.0.3)(supports-color@10.2.2) '@angular/compiler-cli': specifier: ^20.2.0 version: 20.3.26(@angular/compiler@20.3.26)(typescript@5.9.3) @@ -538,10 +538,10 @@ importers: devDependencies: '@angular-devkit/build-angular': specifier: ^20.2.0 - version: 20.3.32(@angular/compiler-cli@20.3.26(@angular/compiler@20.3.26)(typescript@5.9.3))(@angular/compiler@20.3.26)(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.26(@angular/animations@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(lightningcss@1.33.0)(typescript@5.9.3)(vitest@4.1.4(@types/node@24.9.2)(jsdom@27.1.0)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)))(yaml@2.8.1) + version: 20.3.32(@angular/compiler-cli@20.3.26(@angular/compiler@20.3.26)(typescript@5.9.3))(@angular/compiler@20.3.26)(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.26(@angular/animations@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(lightningcss@1.33.0)(typescript@5.9.3)(vitest@4.1.4(@types/node@24.9.2)(jsdom@27.1.0(supports-color@10.2.2))(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)))(yaml@2.8.1) '@angular/cli': specifier: ^20.2.0 - version: 20.3.32(@types/node@24.9.2)(chokidar@4.0.3) + version: 20.3.32(@types/node@24.9.2)(chokidar@4.0.3)(supports-color@10.2.2) '@angular/compiler-cli': specifier: ^20.2.0 version: 20.3.26(@angular/compiler@20.3.26)(typescript@5.9.3) @@ -590,10 +590,10 @@ importers: devDependencies: '@angular-devkit/build-angular': specifier: ^20.2.0 - version: 20.3.32(@angular/compiler-cli@20.3.26(@angular/compiler@20.3.26)(typescript@5.9.3))(@angular/compiler@20.3.26)(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.26(@angular/animations@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(lightningcss@1.33.0)(typescript@5.9.3)(vitest@4.1.4(@types/node@24.9.2)(jsdom@27.1.0)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)))(yaml@2.8.1) + version: 20.3.32(@angular/compiler-cli@20.3.26(@angular/compiler@20.3.26)(typescript@5.9.3))(@angular/compiler@20.3.26)(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.26(@angular/animations@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(lightningcss@1.33.0)(typescript@5.9.3)(vitest@4.1.4(@types/node@24.9.2)(jsdom@27.1.0(supports-color@10.2.2))(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)))(yaml@2.8.1) '@angular/cli': specifier: ^20.2.0 - version: 20.3.32(@types/node@24.9.2)(chokidar@4.0.3) + version: 20.3.32(@types/node@24.9.2)(chokidar@4.0.3)(supports-color@10.2.2) '@angular/compiler-cli': specifier: ^20.2.0 version: 20.3.26(@angular/compiler@20.3.26)(typescript@5.9.3) @@ -642,10 +642,10 @@ importers: devDependencies: '@angular-devkit/build-angular': specifier: ^20.2.0 - version: 20.3.32(@angular/compiler-cli@20.3.26(@angular/compiler@20.3.26)(typescript@5.9.3))(@angular/compiler@20.3.26)(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.26(@angular/animations@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(lightningcss@1.33.0)(typescript@5.9.3)(vitest@4.1.4(@types/node@24.9.2)(jsdom@27.1.0)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)))(yaml@2.8.1) + version: 20.3.32(@angular/compiler-cli@20.3.26(@angular/compiler@20.3.26)(typescript@5.9.3))(@angular/compiler@20.3.26)(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.26(@angular/animations@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(lightningcss@1.33.0)(typescript@5.9.3)(vitest@4.1.4(@types/node@24.9.2)(jsdom@27.1.0(supports-color@10.2.2))(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)))(yaml@2.8.1) '@angular/cli': specifier: ^20.2.0 - version: 20.3.32(@types/node@24.9.2)(chokidar@4.0.3) + version: 20.3.32(@types/node@24.9.2)(chokidar@4.0.3)(supports-color@10.2.2) '@angular/compiler-cli': specifier: ^20.2.0 version: 20.3.26(@angular/compiler@20.3.26)(typescript@5.9.3) @@ -721,9 +721,6 @@ importers: '@marko/type-check': specifier: 3.1.1 version: 3.1.1 - '@playwright/test': - specifier: ^1.53.1 - version: 1.56.1 typescript: specifier: 5.9.3 version: 5.9.3 @@ -752,9 +749,6 @@ importers: '@marko/type-check': specifier: 3.1.1 version: 3.1.1 - '@playwright/test': - specifier: ^1.53.1 - version: 1.56.1 typescript: specifier: 5.9.3 version: 5.9.3 @@ -780,9 +774,6 @@ importers: '@marko/type-check': specifier: 3.1.1 version: 3.1.1 - '@playwright/test': - specifier: ^1.53.1 - version: 1.56.1 typescript: specifier: 5.9.3 version: 5.9.3 @@ -808,9 +799,6 @@ importers: '@marko/type-check': specifier: 3.1.1 version: 3.1.1 - '@playwright/test': - specifier: ^1.53.1 - version: 1.56.1 typescript: specifier: 5.9.3 version: 5.9.3 @@ -836,9 +824,6 @@ importers: '@marko/type-check': specifier: 3.1.1 version: 3.1.1 - '@playwright/test': - specifier: ^1.53.1 - version: 1.56.1 typescript: specifier: 5.9.3 version: 5.9.3 @@ -864,9 +849,6 @@ importers: '@marko/type-check': specifier: 3.1.1 version: 3.1.1 - '@playwright/test': - specifier: ^1.53.1 - version: 1.56.1 typescript: specifier: 5.9.3 version: 5.9.3 @@ -892,9 +874,6 @@ importers: '@marko/type-check': specifier: 3.1.1 version: 3.1.1 - '@playwright/test': - specifier: ^1.53.1 - version: 1.56.1 typescript: specifier: 5.9.3 version: 5.9.3 @@ -923,9 +902,6 @@ importers: '@marko/type-check': specifier: 3.1.1 version: 3.1.1 - '@playwright/test': - specifier: ^1.53.1 - version: 1.56.1 typescript: specifier: 5.9.3 version: 5.9.3 @@ -951,9 +927,6 @@ importers: '@marko/type-check': specifier: 3.1.1 version: 3.1.1 - '@playwright/test': - specifier: ^1.53.1 - version: 1.56.1 typescript: specifier: 5.9.3 version: 5.9.3 @@ -979,9 +952,6 @@ importers: '@marko/type-check': specifier: 3.1.1 version: 3.1.1 - '@playwright/test': - specifier: ^1.53.1 - version: 1.56.1 typescript: specifier: 5.9.3 version: 5.9.3 @@ -1007,9 +977,6 @@ importers: '@marko/type-check': specifier: 3.1.1 version: 3.1.1 - '@playwright/test': - specifier: ^1.53.1 - version: 1.56.1 typescript: specifier: 5.9.3 version: 5.9.3 @@ -1035,9 +1002,6 @@ importers: '@marko/type-check': specifier: 3.1.1 version: 3.1.1 - '@playwright/test': - specifier: ^1.53.1 - version: 1.56.1 typescript: specifier: 5.9.3 version: 5.9.3 @@ -1063,9 +1027,6 @@ importers: '@marko/type-check': specifier: 3.1.1 version: 3.1.1 - '@playwright/test': - specifier: ^1.53.1 - version: 1.56.1 typescript: specifier: 5.9.3 version: 5.9.3 @@ -1091,9 +1052,6 @@ importers: '@marko/type-check': specifier: 3.1.1 version: 3.1.1 - '@playwright/test': - specifier: ^1.53.1 - version: 1.56.1 typescript: specifier: 5.9.3 version: 5.9.3 @@ -1119,9 +1077,6 @@ importers: '@marko/type-check': specifier: 3.1.1 version: 3.1.1 - '@playwright/test': - specifier: ^1.53.1 - version: 1.56.1 typescript: specifier: 5.9.3 version: 5.9.3 @@ -1147,9 +1102,6 @@ importers: '@marko/type-check': specifier: 3.1.1 version: 3.1.1 - '@playwright/test': - specifier: ^1.53.1 - version: 1.56.1 typescript: specifier: 5.9.3 version: 5.9.3 @@ -1175,9 +1127,6 @@ importers: '@marko/type-check': specifier: 3.1.1 version: 3.1.1 - '@playwright/test': - specifier: ^1.53.1 - version: 1.56.1 typescript: specifier: 5.9.3 version: 5.9.3 @@ -1203,9 +1152,6 @@ importers: '@marko/type-check': specifier: 3.1.1 version: 3.1.1 - '@playwright/test': - specifier: ^1.53.1 - version: 1.56.1 typescript: specifier: 5.9.3 version: 5.9.3 @@ -1231,9 +1177,6 @@ importers: '@marko/type-check': specifier: 3.1.1 version: 3.1.1 - '@playwright/test': - specifier: ^1.53.1 - version: 1.56.1 typescript: specifier: 5.9.3 version: 5.9.3 @@ -1606,7 +1549,7 @@ importers: devDependencies: '@sveltejs/vite-plugin-svelte': specifier: ^3.1.2 - version: 3.1.2(svelte@4.2.20)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)) + version: 3.1.2(supports-color@10.2.2)(svelte@4.2.20)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)) '@tsconfig/svelte': specifier: ^5.0.4 version: 5.0.5 @@ -2041,10 +1984,10 @@ importers: devDependencies: '@angular-devkit/build-angular': specifier: ^20.2.0 - version: 20.3.32(@angular/compiler-cli@20.3.26(@angular/compiler@20.3.26)(typescript@5.9.3))(@angular/compiler@20.3.26)(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.26(@angular/animations@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(lightningcss@1.33.0)(typescript@5.9.3)(vitest@4.1.4(@types/node@24.9.2)(jsdom@27.1.0)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)))(yaml@2.8.1) + version: 20.3.32(@angular/compiler-cli@20.3.26(@angular/compiler@20.3.26)(typescript@5.9.3))(@angular/compiler@20.3.26)(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.26(@angular/animations@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(lightningcss@1.33.0)(typescript@5.9.3)(vitest@4.1.4(@types/node@24.9.2)(jsdom@27.1.0(supports-color@10.2.2))(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)))(yaml@2.8.1) '@angular/cli': specifier: ^20.2.0 - version: 20.3.32(@types/node@24.9.2)(chokidar@4.0.3) + version: 20.3.32(@types/node@24.9.2)(chokidar@4.0.3)(supports-color@10.2.2) '@angular/common': specifier: ^20.2.0 version: 20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) @@ -2078,7 +2021,7 @@ importers: devDependencies: '@open-wc/testing': specifier: ^4.0.0 - version: 4.0.0 + version: 4.0.0(supports-color@10.2.2) lit: specifier: ^3.3.0 version: 3.3.1 @@ -2105,7 +2048,7 @@ importers: specifier: ^6.2.2 version: 6.3.15 - packages/marko-virtual/e2e/option-gates: + packages/marko-virtual/e2e/app: dependencies: '@marko/run': specifier: ^0.10.0 @@ -4196,12 +4139,6 @@ packages: '@napi-rs/wasm-runtime@1.0.7': resolution: {integrity: sha512-SeDnOO0Tk7Okiq6DbXmmBODgOAb9dp9gjlphokTUxmt8U3liIP1ZsozBahH69j/RJv+Rfs6IwUKHTgQYJ/HBAw==} - '@napi-rs/wasm-runtime@1.1.6': - resolution: {integrity: sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==} - peerDependencies: - '@emnapi/core': ^1.7.1 - '@emnapi/runtime': ^1.7.1 - '@ngtools/webpack@20.3.32': resolution: {integrity: sha512-a3KWNfv3NEyNHdGusIP/+lfLtjH7L5rcqgouBm6v3t1vHQ4zg2sNgoYIQIJCAJnFI2b080YrP9jh2FqKTCJlug==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} @@ -5092,9 +5029,6 @@ packages: '@tybys/wasm-util@0.10.1': resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} - '@tybys/wasm-util@0.10.3': - resolution: {integrity: sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==} - '@tybys/wasm-util@0.9.0': resolution: {integrity: sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==} @@ -9973,13 +9907,98 @@ snapshots: transitivePeerDependencies: - chokidar - '@angular-devkit/build-angular@20.3.32(@angular/compiler-cli@20.3.26(@angular/compiler@20.3.26)(typescript@5.9.3))(@angular/compiler@20.3.26)(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.26(@angular/animations@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(lightningcss@1.33.0)(typescript@5.9.3)(vitest@4.1.4(@types/node@24.9.2)(jsdom@27.1.0)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)))(yaml@2.8.1)': + '@angular-devkit/build-angular@20.3.32(@angular/compiler-cli@20.3.26(@angular/compiler@20.3.26)(typescript@5.9.3))(@angular/compiler@20.3.26)(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.26(@angular/animations@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(lightningcss@1.33.0)(supports-color@10.2.2)(typescript@5.9.3)(vitest@4.1.4(@types/node@24.9.2)(jsdom@27.1.0(supports-color@10.2.2))(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)))(yaml@2.8.1)': dependencies: '@ampproject/remapping': 2.3.0 '@angular-devkit/architect': 0.2003.32(chokidar@4.0.3) '@angular-devkit/build-webpack': 0.2003.32(chokidar@4.0.3)(webpack-dev-server@5.2.5(webpack@5.105.0(esbuild@0.28.1)))(webpack@5.105.0(esbuild@0.28.1)) '@angular-devkit/core': 20.3.32(chokidar@4.0.3) - '@angular/build': 20.3.32(@angular/compiler-cli@20.3.26(@angular/compiler@20.3.26)(typescript@5.9.3))(@angular/compiler@20.3.26)(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.26(@angular/animations@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(postcss@8.5.12)(terser@5.43.1)(tslib@2.8.1)(typescript@5.9.3)(vitest@4.1.4(@types/node@24.9.2)(jsdom@27.1.0)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)))(yaml@2.8.1) + '@angular/build': 20.3.32(@angular/compiler-cli@20.3.26(@angular/compiler@20.3.26)(typescript@5.9.3))(@angular/compiler@20.3.26)(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.26(@angular/animations@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(postcss@8.5.12)(terser@5.43.1)(tslib@2.8.1)(typescript@5.9.3)(vitest@4.1.4(@types/node@24.9.2)(jsdom@27.1.0(supports-color@10.2.2))(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)))(yaml@2.8.1) + '@angular/compiler-cli': 20.3.26(@angular/compiler@20.3.26)(typescript@5.9.3) + '@babel/core': 7.29.7 + '@babel/generator': 7.28.3 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-split-export-declaration': 7.24.7 + '@babel/plugin-transform-async-generator-functions': 7.28.0(@babel/core@7.29.7) + '@babel/plugin-transform-async-to-generator': 7.27.1(@babel/core@7.29.7) + '@babel/plugin-transform-runtime': 7.28.3(@babel/core@7.29.7) + '@babel/preset-env': 7.28.3(@babel/core@7.29.7) + '@babel/runtime': 7.28.3 + '@discoveryjs/json-ext': 0.6.3 + '@ngtools/webpack': 20.3.32(@angular/compiler-cli@20.3.26(@angular/compiler@20.3.26)(typescript@5.9.3))(typescript@5.9.3)(webpack@5.105.0(esbuild@0.28.1)) + ansi-colors: 4.1.3 + autoprefixer: 10.4.21(postcss@8.5.12) + babel-loader: 10.0.0(@babel/core@7.29.7)(webpack@5.105.0(esbuild@0.28.1)) + browserslist: 4.28.2 + copy-webpack-plugin: 14.0.0(webpack@5.105.0(esbuild@0.28.1)) + css-loader: 7.1.2(webpack@5.105.0(esbuild@0.28.1)) + esbuild-wasm: 0.28.1 + fast-glob: 3.3.3 + http-proxy-middleware: 3.0.7(supports-color@10.2.2) + istanbul-lib-instrument: 6.0.3 + jsonc-parser: 3.3.1 + karma-source-map-support: 1.4.0 + less: 4.4.0 + less-loader: 12.3.0(less@4.4.0)(webpack@5.105.0(esbuild@0.28.1)) + license-webpack-plugin: 4.0.2(webpack@5.105.0(esbuild@0.28.1)) + loader-utils: 3.3.1 + mini-css-extract-plugin: 2.9.4(webpack@5.105.0(esbuild@0.28.1)) + open: 10.2.0 + ora: 8.2.0 + picomatch: 4.0.4 + piscina: 5.2.0 + postcss: 8.5.12 + postcss-loader: 8.1.1(postcss@8.5.12)(typescript@5.9.3)(webpack@5.105.0(esbuild@0.28.1)) + resolve-url-loader: 5.0.0 + rxjs: 7.8.2 + sass: 1.90.0 + sass-loader: 16.0.5(sass@1.90.0)(webpack@5.105.0(esbuild@0.28.1)) + semver: 7.7.2 + source-map-loader: 5.0.0(webpack@5.105.0(esbuild@0.28.1)) + source-map-support: 0.5.21 + terser: 5.43.1 + tree-kill: 1.2.2 + tslib: 2.8.1 + typescript: 5.9.3 + webpack: 5.105.0(esbuild@0.28.1) + webpack-dev-middleware: 7.4.2(webpack@5.105.0(esbuild@0.28.1)) + webpack-dev-server: 5.2.5(supports-color@10.2.2)(webpack@5.105.0(esbuild@0.28.1)) + webpack-merge: 6.0.1 + webpack-subresource-integrity: 5.1.0(webpack@5.105.0(esbuild@0.28.1)) + optionalDependencies: + '@angular/core': 20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1) + '@angular/platform-browser': 20.3.26(@angular/animations@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)) + esbuild: 0.28.1 + transitivePeerDependencies: + - '@angular/compiler' + - '@rspack/core' + - '@swc/core' + - '@types/node' + - bufferutil + - chokidar + - debug + - html-webpack-plugin + - jiti + - lightningcss + - node-sass + - sass-embedded + - stylus + - sugarss + - supports-color + - tsx + - uglify-js + - utf-8-validate + - vitest + - webpack-cli + - yaml + + '@angular-devkit/build-angular@20.3.32(@angular/compiler-cli@20.3.26(@angular/compiler@20.3.26)(typescript@5.9.3))(@angular/compiler@20.3.26)(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.26(@angular/animations@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(lightningcss@1.33.0)(typescript@5.9.3)(vitest@4.1.4(@types/node@24.9.2)(jsdom@27.1.0(supports-color@10.2.2))(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)))(yaml@2.8.1)': + dependencies: + '@ampproject/remapping': 2.3.0 + '@angular-devkit/architect': 0.2003.32(chokidar@4.0.3) + '@angular-devkit/build-webpack': 0.2003.32(chokidar@4.0.3)(webpack-dev-server@5.2.5(webpack@5.105.0(esbuild@0.28.1)))(webpack@5.105.0(esbuild@0.28.1)) + '@angular-devkit/core': 20.3.32(chokidar@4.0.3) + '@angular/build': 20.3.32(@angular/compiler-cli@20.3.26(@angular/compiler@20.3.26)(typescript@5.9.3))(@angular/compiler@20.3.26)(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.26(@angular/animations@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(postcss@8.5.12)(terser@5.43.1)(tslib@2.8.1)(typescript@5.9.3)(vitest@4.1.4(@types/node@24.9.2)(jsdom@27.1.0(supports-color@10.2.2))(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)))(yaml@2.8.1) '@angular/compiler-cli': 20.3.26(@angular/compiler@20.3.26)(typescript@5.9.3) '@babel/core': 7.29.7 '@babel/generator': 7.28.3 @@ -10028,7 +10047,7 @@ snapshots: typescript: 5.9.3 webpack: 5.105.0(esbuild@0.28.1) webpack-dev-middleware: 7.4.2(webpack@5.105.0(esbuild@0.28.1)) - webpack-dev-server: 5.2.5(webpack@5.105.0(esbuild@0.28.1)) + webpack-dev-server: 5.2.5(supports-color@10.2.2)(webpack@5.105.0(esbuild@0.28.1)) webpack-merge: 6.0.1 webpack-subresource-integrity: 5.1.0(webpack@5.105.0(esbuild@0.28.1)) optionalDependencies: @@ -10063,7 +10082,7 @@ snapshots: '@angular-devkit/architect': 0.2003.32(chokidar@4.0.3) rxjs: 7.8.2 webpack: 5.105.0(esbuild@0.28.1) - webpack-dev-server: 5.2.5(webpack@5.105.0(esbuild@0.28.1)) + webpack-dev-server: 5.2.5(supports-color@10.2.2)(webpack@5.105.0(esbuild@0.28.1)) transitivePeerDependencies: - chokidar @@ -10093,7 +10112,7 @@ snapshots: '@angular/core': 20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1) tslib: 2.8.1 - '@angular/build@20.3.32(@angular/compiler-cli@20.3.26(@angular/compiler@20.3.26)(typescript@5.9.3))(@angular/compiler@20.3.26)(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.26(@angular/animations@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(postcss@8.5.12)(terser@5.43.1)(tslib@2.8.1)(typescript@5.9.3)(vitest@4.1.4(@types/node@24.9.2)(jsdom@27.1.0)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)))(yaml@2.8.1)': + '@angular/build@20.3.32(@angular/compiler-cli@20.3.26(@angular/compiler@20.3.26)(typescript@5.9.3))(@angular/compiler@20.3.26)(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.26(@angular/animations@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.26(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.26(@angular/compiler@20.3.26)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(postcss@8.5.12)(terser@5.43.1)(tslib@2.8.1)(typescript@5.9.3)(vitest@4.1.4(@types/node@24.9.2)(jsdom@27.1.0(supports-color@10.2.2))(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)))(yaml@2.8.1)': dependencies: '@ampproject/remapping': 2.3.0 '@angular-devkit/architect': 0.2003.32(chokidar@4.0.3) @@ -10107,7 +10126,7 @@ snapshots: beasties: 0.3.5 browserslist: 4.28.2 esbuild: 0.28.1 - https-proxy-agent: 7.0.6 + https-proxy-agent: 7.0.6(supports-color@10.2.2) istanbul-lib-instrument: 6.0.3 jsonc-parser: 3.3.1 listr2: 9.0.1 @@ -10131,7 +10150,7 @@ snapshots: less: 4.4.0 lmdb: 3.4.2 postcss: 8.5.12 - vitest: 4.1.4(@types/node@24.9.2)(jsdom@27.1.0)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)) + vitest: 4.1.4(@types/node@24.9.2)(jsdom@27.1.0(supports-color@10.2.2))(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)) transitivePeerDependencies: - '@types/node' - chokidar @@ -10145,14 +10164,14 @@ snapshots: - tsx - yaml - '@angular/cli@20.3.32(@types/node@24.9.2)(chokidar@4.0.3)': + '@angular/cli@20.3.32(@types/node@24.9.2)(chokidar@4.0.3)(supports-color@10.2.2)': dependencies: '@angular-devkit/architect': 0.2003.32(chokidar@4.0.3) '@angular-devkit/core': 20.3.32(chokidar@4.0.3) '@angular-devkit/schematics': 20.3.32(chokidar@4.0.3) '@inquirer/prompts': 7.8.2(@types/node@24.9.2) '@listr2/prompt-adapter-inquirer': 3.0.1(@inquirer/prompts@7.8.2(@types/node@24.9.2))(@types/node@24.9.2)(listr2@9.0.1) - '@modelcontextprotocol/sdk': 1.26.0(zod@4.1.13) + '@modelcontextprotocol/sdk': 1.26.0(supports-color@10.2.2)(zod@4.1.13) '@schematics/angular': 20.3.32(chokidar@4.0.3) '@yarnpkg/lockfile': 1.1.0 algoliasearch: 5.35.0 @@ -10160,7 +10179,7 @@ snapshots: jsonc-parser: 3.3.1 listr2: 9.0.1 npm-package-arg: 13.0.0 - pacote: 21.5.1 + pacote: 21.5.1(supports-color@10.2.2) resolve: 1.22.10 semver: 7.7.2 yargs: 18.0.0 @@ -10280,7 +10299,27 @@ snapshots: '@babel/helpers': 7.28.4 '@babel/parser': 7.28.5 '@babel/template': 7.27.2 - '@babel/traverse': 7.28.5 + '@babel/traverse': 7.28.5(supports-color@10.2.2) + '@babel/types': 7.28.5 + '@jridgewell/remapping': 2.3.5 + convert-source-map: 2.0.0 + debug: 4.4.3(supports-color@10.2.2) + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/core@7.28.5(supports-color@10.2.2)': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.7 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5(supports-color@10.2.2)) + '@babel/helpers': 7.28.4 + '@babel/parser': 7.28.5 + '@babel/template': 7.27.2 + '@babel/traverse': 7.28.5(supports-color@10.2.2) '@babel/types': 7.28.5 '@jridgewell/remapping': 2.3.5 convert-source-map: 2.0.0 @@ -10395,7 +10434,7 @@ snapshots: '@babel/helper-module-imports@7.27.1': dependencies: - '@babel/traverse': 7.28.5 + '@babel/traverse': 7.28.5(supports-color@10.2.2) '@babel/types': 7.28.5 transitivePeerDependencies: - supports-color @@ -10407,12 +10446,21 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-module-transforms@7.28.3(@babel/core@7.28.5(supports-color@10.2.2))': + dependencies: + '@babel/core': 7.28.5(supports-color@10.2.2) + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.28.5(supports-color@10.2.2) + transitivePeerDependencies: + - supports-color + '@babel/helper-module-transforms@7.28.3(@babel/core@7.28.5)': dependencies: '@babel/core': 7.28.5 '@babel/helper-module-imports': 7.27.1 '@babel/helper-validator-identifier': 7.28.5 - '@babel/traverse': 7.28.5 + '@babel/traverse': 7.28.5(supports-color@10.2.2) transitivePeerDependencies: - supports-color @@ -10826,11 +10874,21 @@ snapshots: '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 + '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.28.5(supports-color@10.2.2))': + dependencies: + '@babel/core': 7.28.5(supports-color@10.2.2) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.28.5)': dependencies: '@babel/core': 7.28.5 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.28.5(supports-color@10.2.2))': + dependencies: + '@babel/core': 7.28.5(supports-color@10.2.2) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.28.5)': dependencies: '@babel/core': 7.28.5 @@ -11014,7 +11072,7 @@ snapshots: '@babel/parser': 7.29.7 '@babel/types': 7.29.7 - '@babel/traverse@7.28.5': + '@babel/traverse@7.28.5(supports-color@10.2.2)': dependencies: '@babel/code-frame': 7.29.0 '@babel/generator': 7.29.7 @@ -11435,14 +11493,14 @@ snapshots: '@esbuild/win32-x64@0.28.1': optional: true - '@eslint-community/eslint-utils@4.9.0(eslint@9.39.0(jiti@2.6.1))': + '@eslint-community/eslint-utils@4.9.0(eslint@9.39.0(jiti@2.6.1)(supports-color@10.2.2))': dependencies: - eslint: 9.39.0(jiti@2.6.1) + eslint: 9.39.0(jiti@2.6.1)(supports-color@10.2.2) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.2': {} - '@eslint/config-array@0.21.1': + '@eslint/config-array@0.21.1(supports-color@10.2.2)': dependencies: '@eslint/object-schema': 2.1.7 debug: 4.4.3(supports-color@10.2.2) @@ -11458,7 +11516,7 @@ snapshots: dependencies: '@types/json-schema': 7.0.15 - '@eslint/eslintrc@3.3.1': + '@eslint/eslintrc@3.3.1(supports-color@10.2.2)': dependencies: ajv: 6.12.6 debug: 4.4.3(supports-color@10.2.2) @@ -11797,13 +11855,13 @@ snapshots: '@luxass/strip-json-comments': 1.4.0 complain: 1.6.1 he: 1.2.0 - htmljs-parser: 5.10.2 + htmljs-parser: 5.12.1 jsesc: 3.1.0 kleur: 4.1.5 lasso-package-root: 1.0.1 raptor-regexp: 1.0.1 raptor-util: 3.2.0 - relative-import-path: 1.0.0 + relative-import-path: 1.0.1 resolve-from: 5.0.0 self-closing-tags: 1.0.1 source-map-support: 0.5.21 @@ -11929,7 +11987,7 @@ snapshots: '@microsoft/tsdoc@0.15.1': {} - '@modelcontextprotocol/sdk@1.26.0(zod@4.1.13)': + '@modelcontextprotocol/sdk@1.26.0(supports-color@10.2.2)(zod@4.1.13)': dependencies: '@hono/node-server': 1.19.14(hono@4.12.30) ajv: 8.18.0 @@ -11939,7 +11997,7 @@ snapshots: cross-spawn: 7.0.6 eventsource: 3.0.7 eventsource-parser: 3.1.0 - express: 5.2.1 + express: 5.2.1(supports-color@10.2.2) express-rate-limit: 8.5.2(express@5.2.1) hono: 4.12.30 jose: 6.2.3 @@ -12116,13 +12174,6 @@ snapshots: '@tybys/wasm-util': 0.10.1 optional: true - '@napi-rs/wasm-runtime@1.1.6(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)': - dependencies: - '@emnapi/core': 1.11.1 - '@emnapi/runtime': 1.11.1 - '@tybys/wasm-util': 0.10.3 - optional: true - '@ngtools/webpack@20.3.32(@angular/compiler-cli@20.3.26(@angular/compiler@20.3.26)(typescript@5.9.3))(typescript@5.9.3)(webpack@5.105.0(esbuild@0.28.1))': dependencies: '@angular/compiler-cli': 20.3.26(@angular/compiler@20.3.26)(typescript@5.9.3) @@ -12146,8 +12197,8 @@ snapshots: '@npmcli/agent@4.0.2': dependencies: agent-base: 7.1.4 - http-proxy-agent: 7.0.2 - https-proxy-agent: 7.0.6 + http-proxy-agent: 7.0.2(supports-color@10.2.2) + https-proxy-agent: 7.0.6(supports-color@10.2.2) lru-cache: 11.2.2 socks-proxy-agent: 8.0.5 transitivePeerDependencies: @@ -12236,10 +12287,10 @@ snapshots: '@open-wc/dedupe-mixin': 2.0.1 lit: 3.3.1 - '@open-wc/semantic-dom-diff@0.20.1': + '@open-wc/semantic-dom-diff@0.20.1(supports-color@10.2.2)': dependencies: '@types/chai': 4.3.20 - '@web/test-runner-commands': 0.9.0 + '@web/test-runner-commands': 0.9.0(supports-color@10.2.2) transitivePeerDependencies: - bufferutil - supports-color @@ -12251,10 +12302,10 @@ snapshots: lit: 3.3.1 lit-html: 3.3.1 - '@open-wc/testing@4.0.0': + '@open-wc/testing@4.0.0(supports-color@10.2.2)': dependencies: '@esm-bundle/chai': 4.3.4-fix.0 - '@open-wc/semantic-dom-diff': 0.20.1 + '@open-wc/semantic-dom-diff': 0.20.1(supports-color@10.2.2) '@open-wc/testing-helpers': 3.0.1 '@types/chai-dom': 1.11.3 '@types/sinon-chai': 3.2.12 @@ -12564,7 +12615,6 @@ snapshots: dependencies: '@emnapi/core': 1.11.1 '@emnapi/runtime': 1.11.1 - '@napi-rs/wasm-runtime': 1.1.6(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1) optional: true '@rolldown/binding-win32-arm64-msvc@1.1.5': @@ -12721,10 +12771,10 @@ snapshots: transitivePeerDependencies: - supports-color - '@sigstore/tuf@4.0.2': + '@sigstore/tuf@4.0.2(supports-color@10.2.2)': dependencies: '@sigstore/protobuf-specs': 0.5.1 - tuf-js: 4.1.0 + tuf-js: 4.1.0(supports-color@10.2.2) transitivePeerDependencies: - supports-color @@ -12738,11 +12788,11 @@ snapshots: '@standard-schema/spec@1.1.0': {} - '@stylistic/eslint-plugin@5.5.0(eslint@9.39.0(jiti@2.6.1))': + '@stylistic/eslint-plugin@5.5.0(eslint@9.39.0(jiti@2.6.1)(supports-color@10.2.2))': dependencies: - '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.0(jiti@2.6.1)) + '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.0(jiti@2.6.1)(supports-color@10.2.2)) '@typescript-eslint/types': 8.46.2 - eslint: 9.39.0(jiti@2.6.1) + eslint: 9.39.0(jiti@2.6.1)(supports-color@10.2.2) eslint-visitor-keys: 4.2.1 espree: 10.4.0 estraverse: 5.3.0 @@ -12759,6 +12809,15 @@ snapshots: transitivePeerDependencies: - typescript + '@sveltejs/vite-plugin-svelte-inspector@2.1.0(@sveltejs/vite-plugin-svelte@3.1.2(supports-color@10.2.2)(svelte@4.2.20)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)))(supports-color@10.2.2)(svelte@4.2.20)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1))': + dependencies: + '@sveltejs/vite-plugin-svelte': 3.1.2(supports-color@10.2.2)(svelte@4.2.20)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)) + debug: 4.4.3(supports-color@10.2.2) + svelte: 4.2.20 + vite: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1) + transitivePeerDependencies: + - supports-color + '@sveltejs/vite-plugin-svelte-inspector@2.1.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.20)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)))(svelte@4.2.20)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1))': dependencies: '@sveltejs/vite-plugin-svelte': 3.1.2(svelte@4.2.20)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)) @@ -12768,6 +12827,20 @@ snapshots: transitivePeerDependencies: - supports-color + '@sveltejs/vite-plugin-svelte@3.1.2(supports-color@10.2.2)(svelte@4.2.20)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1))': + dependencies: + '@sveltejs/vite-plugin-svelte-inspector': 2.1.0(@sveltejs/vite-plugin-svelte@3.1.2(supports-color@10.2.2)(svelte@4.2.20)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)))(supports-color@10.2.2)(svelte@4.2.20)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)) + debug: 4.4.3(supports-color@10.2.2) + deepmerge: 4.3.1 + kleur: 4.1.5 + magic-string: 0.30.21 + svelte: 4.2.20 + svelte-hmr: 0.16.0(svelte@4.2.20) + vite: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1) + vitefu: 0.2.5(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)) + transitivePeerDependencies: + - supports-color + '@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.20)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1))': dependencies: '@sveltejs/vite-plugin-svelte-inspector': 2.1.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.20)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)))(svelte@4.2.20)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)) @@ -12799,16 +12872,16 @@ snapshots: '@tanstack/table-core': 8.21.3 tslib: 2.8.1 - '@tanstack/eslint-config@0.3.4(@typescript-eslint/utils@8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.0(jiti@2.6.1))(typescript@5.9.3)': + '@tanstack/eslint-config@0.3.4(@typescript-eslint/utils@8.46.2(eslint@9.39.0(jiti@2.6.1)(supports-color@10.2.2))(typescript@5.9.3))(eslint@9.39.0(jiti@2.6.1)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@5.9.3)': dependencies: '@eslint/js': 9.39.0 - '@stylistic/eslint-plugin': 5.5.0(eslint@9.39.0(jiti@2.6.1)) - eslint: 9.39.0(jiti@2.6.1) - eslint-plugin-import-x: 4.16.1(@typescript-eslint/utils@8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.0(jiti@2.6.1)) - eslint-plugin-n: 17.23.1(eslint@9.39.0(jiti@2.6.1))(typescript@5.9.3) + '@stylistic/eslint-plugin': 5.5.0(eslint@9.39.0(jiti@2.6.1)(supports-color@10.2.2)) + eslint: 9.39.0(jiti@2.6.1)(supports-color@10.2.2) + eslint-plugin-import-x: 4.16.1(@typescript-eslint/utils@8.46.2(eslint@9.39.0(jiti@2.6.1)(supports-color@10.2.2))(typescript@5.9.3))(eslint@9.39.0(jiti@2.6.1)(supports-color@10.2.2))(supports-color@10.2.2) + eslint-plugin-n: 17.23.1(eslint@9.39.0(jiti@2.6.1)(supports-color@10.2.2))(typescript@5.9.3) globals: 16.5.0 - typescript-eslint: 8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.9.3) - vue-eslint-parser: 10.2.0(eslint@9.39.0(jiti@2.6.1)) + typescript-eslint: 8.46.2(eslint@9.39.0(jiti@2.6.1)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@5.9.3) + vue-eslint-parser: 10.2.0(eslint@9.39.0(jiti@2.6.1)(supports-color@10.2.2))(supports-color@10.2.2) transitivePeerDependencies: - '@typescript-eslint/utils' - eslint-import-resolver-node @@ -12850,13 +12923,13 @@ snapshots: '@tanstack/table-core@8.21.3': {} - '@tanstack/vite-config@0.4.3(@types/node@24.9.2)(rollup@4.59.0)(typescript@5.9.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1))': + '@tanstack/vite-config@0.4.3(@types/node@24.9.2)(rollup@4.59.0)(supports-color@10.2.2)(typescript@5.9.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1))': dependencies: rollup-plugin-preserve-directives: 0.4.0(rollup@4.59.0) vite: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1) - vite-plugin-dts: 4.2.3(@types/node@24.9.2)(rollup@4.59.0)(typescript@5.9.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)) + vite-plugin-dts: 4.2.3(@types/node@24.9.2)(rollup@4.59.0)(supports-color@10.2.2)(typescript@5.9.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)) vite-plugin-externalize-deps: 0.10.0(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)) - vite-tsconfig-paths: 5.1.4(typescript@5.9.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)) + vite-tsconfig-paths: 5.1.4(supports-color@10.2.2)(typescript@5.9.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)) transitivePeerDependencies: - '@types/node' - rollup @@ -12920,11 +12993,6 @@ snapshots: tslib: 2.8.1 optional: true - '@tybys/wasm-util@0.10.3': - dependencies: - tslib: 2.8.1 - optional: true - '@tybys/wasm-util@0.9.0': dependencies: tslib: 2.8.1 @@ -13157,15 +13225,15 @@ snapshots: dependencies: '@types/node': 24.9.2 - '@typescript-eslint/eslint-plugin@8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.0(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/eslint-plugin@8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.39.0(jiti@2.6.1)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@5.9.3))(eslint@9.39.0(jiti@2.6.1)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/parser': 8.46.2(eslint@9.39.0(jiti@2.6.1)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@5.9.3) '@typescript-eslint/scope-manager': 8.46.2 - '@typescript-eslint/type-utils': 8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/utils': 8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/type-utils': 8.46.2(eslint@9.39.0(jiti@2.6.1)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@5.9.3) + '@typescript-eslint/utils': 8.46.2(eslint@9.39.0(jiti@2.6.1)(supports-color@10.2.2))(typescript@5.9.3) '@typescript-eslint/visitor-keys': 8.46.2 - eslint: 9.39.0(jiti@2.6.1) + eslint: 9.39.0(jiti@2.6.1)(supports-color@10.2.2) graphemer: 1.4.0 ignore: 7.0.5 natural-compare: 1.4.0 @@ -13174,14 +13242,14 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/parser@8.46.2(eslint@9.39.0(jiti@2.6.1)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@5.9.3)': dependencies: '@typescript-eslint/scope-manager': 8.46.2 '@typescript-eslint/types': 8.46.2 '@typescript-eslint/typescript-estree': 8.46.2(typescript@5.9.3) '@typescript-eslint/visitor-keys': 8.46.2 debug: 4.4.3(supports-color@10.2.2) - eslint: 9.39.0(jiti@2.6.1) + eslint: 9.39.0(jiti@2.6.1)(supports-color@10.2.2) typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -13204,13 +13272,13 @@ snapshots: dependencies: typescript: 5.9.3 - '@typescript-eslint/type-utils@8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/type-utils@8.46.2(eslint@9.39.0(jiti@2.6.1)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@5.9.3)': dependencies: '@typescript-eslint/types': 8.46.2 '@typescript-eslint/typescript-estree': 8.46.2(typescript@5.9.3) - '@typescript-eslint/utils': 8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/utils': 8.46.2(eslint@9.39.0(jiti@2.6.1)(supports-color@10.2.2))(typescript@5.9.3) debug: 4.4.3(supports-color@10.2.2) - eslint: 9.39.0(jiti@2.6.1) + eslint: 9.39.0(jiti@2.6.1)(supports-color@10.2.2) ts-api-utils: 2.1.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: @@ -13234,13 +13302,13 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/utils@8.46.2(eslint@9.39.0(jiti@2.6.1)(supports-color@10.2.2))(typescript@5.9.3)': dependencies: - '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.0(jiti@2.6.1)) + '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.0(jiti@2.6.1)(supports-color@10.2.2)) '@typescript-eslint/scope-manager': 8.46.2 '@typescript-eslint/types': 8.46.2 '@typescript-eslint/typescript-estree': 8.46.2(typescript@5.9.3) - eslint: 9.39.0(jiti@2.6.1) + eslint: 9.39.0(jiti@2.6.1)(supports-color@10.2.2) typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -13315,6 +13383,18 @@ snapshots: dependencies: vite: 7.3.6(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1) + '@vitejs/plugin-react@4.7.0(supports-color@10.2.2)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1))': + dependencies: + '@babel/core': 7.28.5(supports-color@10.2.2) + '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.5(supports-color@10.2.2)) + '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.28.5(supports-color@10.2.2)) + '@rolldown/pluginutils': 1.0.0-beta.27 + '@types/babel__core': 7.20.5 + react-refresh: 0.17.0 + vite: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1) + transitivePeerDependencies: + - supports-color + '@vitejs/plugin-react@4.7.0(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1))': dependencies: '@babel/core': 7.28.5 @@ -13424,7 +13504,7 @@ snapshots: '@vue/shared': 3.5.22 estree-walker: 2.0.2 magic-string: 0.30.21 - postcss: 8.5.12 + postcss: 8.5.19 source-map-js: 1.2.1 '@vue/compiler-ssr@3.5.22': @@ -13516,7 +13596,7 @@ snapshots: dependencies: errorstacks: 2.4.1 - '@web/dev-server-core@0.7.5': + '@web/dev-server-core@0.7.5(supports-color@10.2.2)': dependencies: '@types/koa': 2.15.0 '@types/ws': 7.4.7 @@ -13527,9 +13607,9 @@ snapshots: get-stream: 6.0.1 is-stream: 2.0.1 isbinaryfile: 5.0.6 - koa: 2.16.3 + koa: 2.16.3(supports-color@10.2.2) koa-etag: 4.0.0 - koa-send: 5.0.1 + koa-send: 5.0.1(supports-color@10.2.2) koa-static: 5.0.0 lru-cache: 8.0.5 mime-types: 2.1.35 @@ -13546,16 +13626,16 @@ snapshots: '@types/parse5': 6.0.3 parse5: 6.0.1 - '@web/test-runner-commands@0.9.0': + '@web/test-runner-commands@0.9.0(supports-color@10.2.2)': dependencies: - '@web/test-runner-core': 0.13.4 + '@web/test-runner-core': 0.13.4(supports-color@10.2.2) mkdirp: 1.0.4 transitivePeerDependencies: - bufferutil - supports-color - utf-8-validate - '@web/test-runner-core@0.13.4': + '@web/test-runner-core@0.13.4(supports-color@10.2.2)': dependencies: '@babel/code-frame': 7.29.7 '@types/babel__code-frame': 7.0.6 @@ -13565,7 +13645,7 @@ snapshots: '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 '@web/browser-logs': 0.4.1 - '@web/dev-server-core': 0.7.5 + '@web/dev-server-core': 0.7.5(supports-color@10.2.2) chokidar: 4.0.3 cli-cursor: 3.1.0 co-body: 6.2.0 @@ -13950,7 +14030,7 @@ snapshots: inherits: 2.0.4 readable-stream: 3.6.2 - body-parser@1.20.6: + body-parser@1.20.6(supports-color@10.2.2): dependencies: bytes: 3.1.2 content-type: 1.0.5 @@ -13967,7 +14047,7 @@ snapshots: transitivePeerDependencies: - supports-color - body-parser@2.3.0: + body-parser@2.3.0(supports-color@10.2.2): dependencies: bytes: 3.1.2 content-type: 2.0.0 @@ -14650,9 +14730,9 @@ snapshots: escape-string-regexp@4.0.0: {} - eslint-compat-utils@0.5.1(eslint@9.39.0(jiti@2.6.1)): + eslint-compat-utils@0.5.1(eslint@9.39.0(jiti@2.6.1)(supports-color@10.2.2)): dependencies: - eslint: 9.39.0(jiti@2.6.1) + eslint: 9.39.0(jiti@2.6.1)(supports-color@10.2.2) semver: 7.7.3 eslint-import-context@0.1.9(unrs-resolver@1.11.1): @@ -14662,19 +14742,19 @@ snapshots: optionalDependencies: unrs-resolver: 1.11.1 - eslint-plugin-es-x@7.8.0(eslint@9.39.0(jiti@2.6.1)): + eslint-plugin-es-x@7.8.0(eslint@9.39.0(jiti@2.6.1)(supports-color@10.2.2)): dependencies: - '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.0(jiti@2.6.1)) + '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.0(jiti@2.6.1)(supports-color@10.2.2)) '@eslint-community/regexpp': 4.12.2 - eslint: 9.39.0(jiti@2.6.1) - eslint-compat-utils: 0.5.1(eslint@9.39.0(jiti@2.6.1)) + eslint: 9.39.0(jiti@2.6.1)(supports-color@10.2.2) + eslint-compat-utils: 0.5.1(eslint@9.39.0(jiti@2.6.1)(supports-color@10.2.2)) - eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.0(jiti@2.6.1)): + eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.46.2(eslint@9.39.0(jiti@2.6.1)(supports-color@10.2.2))(typescript@5.9.3))(eslint@9.39.0(jiti@2.6.1)(supports-color@10.2.2))(supports-color@10.2.2): dependencies: '@typescript-eslint/types': 8.46.2 comment-parser: 1.4.1 debug: 4.4.3(supports-color@10.2.2) - eslint: 9.39.0(jiti@2.6.1) + eslint: 9.39.0(jiti@2.6.1)(supports-color@10.2.2) eslint-import-context: 0.1.9(unrs-resolver@1.11.1) is-glob: 4.0.3 minimatch: 10.1.1 @@ -14682,16 +14762,16 @@ snapshots: stable-hash-x: 0.2.0 unrs-resolver: 1.11.1 optionalDependencies: - '@typescript-eslint/utils': 8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/utils': 8.46.2(eslint@9.39.0(jiti@2.6.1)(supports-color@10.2.2))(typescript@5.9.3) transitivePeerDependencies: - supports-color - eslint-plugin-n@17.23.1(eslint@9.39.0(jiti@2.6.1))(typescript@5.9.3): + eslint-plugin-n@17.23.1(eslint@9.39.0(jiti@2.6.1)(supports-color@10.2.2))(typescript@5.9.3): dependencies: - '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.0(jiti@2.6.1)) + '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.0(jiti@2.6.1)(supports-color@10.2.2)) enhanced-resolve: 5.18.3 - eslint: 9.39.0(jiti@2.6.1) - eslint-plugin-es-x: 7.8.0(eslint@9.39.0(jiti@2.6.1)) + eslint: 9.39.0(jiti@2.6.1)(supports-color@10.2.2) + eslint-plugin-es-x: 7.8.0(eslint@9.39.0(jiti@2.6.1)(supports-color@10.2.2)) get-tsconfig: 4.13.0 globals: 15.15.0 globrex: 0.1.2 @@ -14715,14 +14795,14 @@ snapshots: eslint-visitor-keys@4.2.1: {} - eslint@9.39.0(jiti@2.6.1): + eslint@9.39.0(jiti@2.6.1)(supports-color@10.2.2): dependencies: - '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.0(jiti@2.6.1)) + '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.0(jiti@2.6.1)(supports-color@10.2.2)) '@eslint-community/regexpp': 4.12.2 - '@eslint/config-array': 0.21.1 + '@eslint/config-array': 0.21.1(supports-color@10.2.2) '@eslint/config-helpers': 0.4.2 '@eslint/core': 0.17.0 - '@eslint/eslintrc': 3.3.1 + '@eslint/eslintrc': 3.3.1(supports-color@10.2.2) '@eslint/js': 9.39.0 '@eslint/plugin-kit': 0.4.1 '@humanfs/node': 0.16.7 @@ -14816,14 +14896,14 @@ snapshots: express-rate-limit@8.5.2(express@5.2.1): dependencies: - express: 5.2.1 + express: 5.2.1(supports-color@10.2.2) ip-address: 10.2.0 - express@4.22.2: + express@4.22.2(supports-color@10.2.2): dependencies: accepts: 1.3.8 array-flatten: 1.1.1 - body-parser: 1.20.6 + body-parser: 1.20.6(supports-color@10.2.2) content-disposition: 0.5.4 content-type: 1.0.5 cookie: 0.7.1 @@ -14833,7 +14913,7 @@ snapshots: encodeurl: 2.0.0 escape-html: 1.0.3 etag: 1.8.1 - finalhandler: 1.3.1 + finalhandler: 1.3.1(supports-color@10.2.2) fresh: 0.5.2 http-errors: 2.0.1 merge-descriptors: 1.0.3 @@ -14845,7 +14925,7 @@ snapshots: qs: 6.15.3 range-parser: 1.2.1 safe-buffer: 5.2.1 - send: 0.19.0 + send: 0.19.0(supports-color@10.2.2) serve-static: 1.16.2 setprototypeof: 1.2.0 statuses: 2.0.2 @@ -14855,10 +14935,10 @@ snapshots: transitivePeerDependencies: - supports-color - express@5.2.1: + express@5.2.1(supports-color@10.2.2): dependencies: accepts: 2.0.0 - body-parser: 2.3.0 + body-parser: 2.3.0(supports-color@10.2.2) content-disposition: 1.1.0 content-type: 1.0.5 cookie: 0.7.1 @@ -14868,7 +14948,7 @@ snapshots: encodeurl: 2.0.0 escape-html: 1.0.3 etag: 1.8.1 - finalhandler: 2.1.1 + finalhandler: 2.1.1(supports-color@10.2.2) fresh: 2.0.0 http-errors: 2.0.1 merge-descriptors: 2.0.0 @@ -14879,7 +14959,7 @@ snapshots: proxy-addr: 2.0.7 qs: 6.15.3 range-parser: 1.2.1 - router: 2.2.0 + router: 2.2.0(supports-color@10.2.2) send: 1.2.1(supports-color@10.2.2) serve-static: 2.2.1(supports-color@10.2.2) statuses: 2.0.2 @@ -14944,7 +15024,7 @@ snapshots: dependencies: to-regex-range: 5.0.1 - finalhandler@1.3.1: + finalhandler@1.3.1(supports-color@10.2.2): dependencies: debug: 2.6.9(supports-color@10.2.2) encodeurl: 2.0.0 @@ -14956,7 +15036,7 @@ snapshots: transitivePeerDependencies: - supports-color - finalhandler@2.1.1: + finalhandler@2.1.1(supports-color@10.2.2): dependencies: debug: 4.4.3(supports-color@10.2.2) encodeurl: 2.0.0 @@ -14986,6 +15066,10 @@ snapshots: flatted@3.3.3: {} + follow-redirects@1.15.11(debug@4.4.3(supports-color@10.2.2)): + optionalDependencies: + debug: 4.4.3(supports-color@10.2.2) + follow-redirects@1.15.11(debug@4.4.3): optionalDependencies: debug: 4.4.3(supports-color@10.2.2) @@ -15209,7 +15293,7 @@ snapshots: http-parser-js@0.5.10: {} - http-proxy-agent@7.0.2: + http-proxy-agent@7.0.2(supports-color@10.2.2): dependencies: agent-base: 7.1.4 debug: 4.4.3(supports-color@10.2.2) @@ -15239,6 +15323,25 @@ snapshots: transitivePeerDependencies: - supports-color + http-proxy-middleware@3.0.7(supports-color@10.2.2): + dependencies: + '@types/http-proxy': 1.17.17 + debug: 4.4.3(supports-color@10.2.2) + http-proxy: 1.18.1(debug@4.4.3(supports-color@10.2.2)) + is-glob: 4.0.3 + is-plain-object: 5.0.0 + micromatch: 4.0.8 + transitivePeerDependencies: + - supports-color + + http-proxy@1.18.1(debug@4.4.3(supports-color@10.2.2)): + dependencies: + eventemitter3: 4.0.7 + follow-redirects: 1.15.11(debug@4.4.3(supports-color@10.2.2)) + requires-port: 1.0.0 + transitivePeerDependencies: + - debug + http-proxy@1.18.1(debug@4.4.3): dependencies: eventemitter3: 4.0.7 @@ -15247,7 +15350,7 @@ snapshots: transitivePeerDependencies: - debug - https-proxy-agent@7.0.6: + https-proxy-agent@7.0.6(supports-color@10.2.2): dependencies: agent-base: 7.1.4 debug: 4.4.3(supports-color@10.2.2) @@ -15499,7 +15602,7 @@ snapshots: dependencies: argparse: 2.0.1 - jsdom@27.1.0: + jsdom@27.1.0(supports-color@10.2.2): dependencies: '@acemir/cssom': 0.9.19 '@asamuzakjp/dom-selector': 6.7.4 @@ -15507,8 +15610,8 @@ snapshots: data-urls: 6.0.0 decimal.js: 10.6.0 html-encoding-sniffer: 4.0.0 - http-proxy-agent: 7.0.2 - https-proxy-agent: 7.0.6 + http-proxy-agent: 7.0.2(supports-color@10.2.2) + https-proxy-agent: 7.0.6(supports-color@10.2.2) is-potential-custom-element-name: 1.0.1 parse5: 8.0.0 saxes: 6.0.0 @@ -15598,7 +15701,7 @@ snapshots: dependencies: etag: 1.8.1 - koa-send@5.0.1: + koa-send@5.0.1(supports-color@10.2.2): dependencies: debug: 4.4.3(supports-color@10.2.2) http-errors: 1.8.1 @@ -15609,11 +15712,11 @@ snapshots: koa-static@5.0.0: dependencies: debug: 3.2.7 - koa-send: 5.0.1 + koa-send: 5.0.1(supports-color@10.2.2) transitivePeerDependencies: - supports-color - koa@2.16.3: + koa@2.16.3(supports-color@10.2.2): dependencies: accepts: 1.3.8 cache-content-type: 1.0.1 @@ -16398,7 +16501,7 @@ snapshots: package-manager-detector@1.5.0: {} - pacote@21.5.1: + pacote@21.5.1(supports-color@10.2.2): dependencies: '@gar/promise-retry': 1.0.3 '@npmcli/git': 7.0.2 @@ -16414,7 +16517,7 @@ snapshots: npm-pick-manifest: 11.0.3 npm-registry-fetch: 19.1.1 proc-log: 6.1.0 - sigstore: 4.1.1 + sigstore: 4.1.1(supports-color@10.2.2) ssri: 13.0.1 tar: 7.5.13 transitivePeerDependencies: @@ -16926,7 +17029,7 @@ snapshots: '@rollup/rollup-win32-x64-msvc': 4.59.0 fsevents: 2.3.3 - router@2.2.0: + router@2.2.0(supports-color@10.2.2): dependencies: debug: 4.4.3(supports-color@10.2.2) depd: 2.0.0 @@ -17017,7 +17120,7 @@ snapshots: semver@7.7.3: {} - send@0.19.0: + send@0.19.0(supports-color@10.2.2): dependencies: debug: 2.6.9(supports-color@10.2.2) depd: 2.0.0 @@ -17059,7 +17162,7 @@ snapshots: seroval@1.3.2: {} - serve-index@1.9.1: + serve-index@1.9.1(supports-color@10.2.2): dependencies: accepts: 1.3.8 batch: 0.6.1 @@ -17076,7 +17179,7 @@ snapshots: encodeurl: 2.0.0 escape-html: 1.0.3 parseurl: 1.3.3 - send: 0.19.0 + send: 0.19.0(supports-color@10.2.2) transitivePeerDependencies: - supports-color @@ -17174,13 +17277,13 @@ snapshots: signal-exit@4.1.0: {} - sigstore@4.1.1: + sigstore@4.1.1(supports-color@10.2.2): dependencies: '@sigstore/bundle': 4.0.0 '@sigstore/core': 3.2.1 '@sigstore/protobuf-specs': 0.5.1 '@sigstore/sign': 4.1.1 - '@sigstore/tuf': 4.0.2 + '@sigstore/tuf': 4.0.2(supports-color@10.2.2) '@sigstore/verify': 3.1.1 transitivePeerDependencies: - supports-color @@ -17272,7 +17375,7 @@ snapshots: spdx-license-ids@3.0.22: {} - spdy-transport@3.0.0: + spdy-transport@3.0.0(supports-color@10.2.2): dependencies: debug: 4.4.3(supports-color@10.2.2) detect-node: 2.1.0 @@ -17283,13 +17386,13 @@ snapshots: transitivePeerDependencies: - supports-color - spdy@4.0.2: + spdy@4.0.2(supports-color@10.2.2): dependencies: debug: 4.4.3(supports-color@10.2.2) handle-thing: 2.0.1 http-deceiver: 1.2.7 select-hose: 2.0.0 - spdy-transport: 3.0.0 + spdy-transport: 3.0.0(supports-color@10.2.2) transitivePeerDependencies: - supports-color @@ -17546,7 +17649,7 @@ snapshots: dependencies: tslib: 1.14.1 - tuf-js@4.1.0: + tuf-js@4.1.0(supports-color@10.2.2): dependencies: '@tufjs/models': 4.1.0 debug: 4.4.3(supports-color@10.2.2) @@ -17573,13 +17676,13 @@ snapshots: typed-assert@1.0.9: {} - typescript-eslint@8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.9.3): + typescript-eslint@8.46.2(eslint@9.39.0(jiti@2.6.1)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@5.9.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.0(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/parser': 8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/eslint-plugin': 8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.39.0(jiti@2.6.1)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@5.9.3))(eslint@9.39.0(jiti@2.6.1)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@5.9.3) + '@typescript-eslint/parser': 8.46.2(eslint@9.39.0(jiti@2.6.1)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@5.9.3) '@typescript-eslint/typescript-estree': 8.46.2(typescript@5.9.3) - '@typescript-eslint/utils': 8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.9.3) - eslint: 9.39.0(jiti@2.6.1) + '@typescript-eslint/utils': 8.46.2(eslint@9.39.0(jiti@2.6.1)(supports-color@10.2.2))(typescript@5.9.3) + eslint: 9.39.0(jiti@2.6.1)(supports-color@10.2.2) typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -17669,7 +17772,7 @@ snapshots: svelte: 4.2.20 vue: 3.5.22(typescript@5.9.3) - vite-plugin-dts@4.2.3(@types/node@24.9.2)(rollup@4.59.0)(typescript@5.9.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)): + vite-plugin-dts@4.2.3(@types/node@24.9.2)(rollup@4.59.0)(supports-color@10.2.2)(typescript@5.9.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)): dependencies: '@microsoft/api-extractor': 7.47.7(@types/node@24.9.2) '@rollup/pluginutils': 5.3.0(rollup@4.59.0) @@ -17707,7 +17810,7 @@ snapshots: transitivePeerDependencies: - supports-color - vite-tsconfig-paths@5.1.4(typescript@5.9.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)): + vite-tsconfig-paths@5.1.4(supports-color@10.2.2)(typescript@5.9.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)): dependencies: debug: 4.4.3(supports-color@10.2.2) globrex: 0.1.2 @@ -17779,7 +17882,7 @@ snapshots: optionalDependencies: vite: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1) - vitest@4.1.4(@types/node@24.9.2)(jsdom@27.1.0)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)): + vitest@4.1.4(@types/node@24.9.2)(jsdom@27.1.0(supports-color@10.2.2))(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)): dependencies: '@vitest/expect': 4.1.4 '@vitest/mocker': 4.1.4(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.0)(lightningcss@1.33.0)(sass@1.90.0)(terser@5.43.1)(yaml@2.8.1)) @@ -17803,7 +17906,7 @@ snapshots: why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 24.9.2 - jsdom: 27.1.0 + jsdom: 27.1.0(supports-color@10.2.2) transitivePeerDependencies: - msw @@ -17813,10 +17916,10 @@ snapshots: dependencies: vue: 3.5.22(typescript@5.9.3) - vue-eslint-parser@10.2.0(eslint@9.39.0(jiti@2.6.1)): + vue-eslint-parser@10.2.0(eslint@9.39.0(jiti@2.6.1)(supports-color@10.2.2))(supports-color@10.2.2): dependencies: debug: 4.4.3(supports-color@10.2.2) - eslint: 9.39.0(jiti@2.6.1) + eslint: 9.39.0(jiti@2.6.1)(supports-color@10.2.2) eslint-scope: 8.4.0 eslint-visitor-keys: 4.2.1 espree: 10.4.0 @@ -17895,7 +17998,7 @@ snapshots: optionalDependencies: webpack: 5.105.0(esbuild@0.28.1) - webpack-dev-server@5.2.5(webpack@5.105.0(esbuild@0.28.1)): + webpack-dev-server@5.2.5(supports-color@10.2.2)(webpack@5.105.0(esbuild@0.28.1)): dependencies: '@types/bonjour': 3.5.13 '@types/connect-history-api-fallback': 1.5.4 @@ -17911,7 +18014,7 @@ snapshots: colorette: 2.0.20 compression: 1.8.1(supports-color@10.2.2) connect-history-api-fallback: 2.0.0 - express: 4.22.2 + express: 4.22.2(supports-color@10.2.2) graceful-fs: 4.2.11 http-proxy-middleware: 2.0.9(@types/express@4.17.25) ipaddr.js: 2.2.0 @@ -17920,9 +18023,9 @@ snapshots: p-retry: 6.2.1 schema-utils: 4.3.3 selfsigned: 5.5.0 - serve-index: 1.9.1 + serve-index: 1.9.1(supports-color@10.2.2) sockjs: 0.3.24 - spdy: 4.0.2 + spdy: 4.0.2(supports-color@10.2.2) webpack-dev-middleware: 7.4.2(webpack@5.105.0(esbuild@0.28.1)) ws: 8.18.3 optionalDependencies: From 815f91bc300af4bf1366216701e55d18607f6494 Mon Sep 17 00:00:00 2001 From: Damian Pieczynski Date: Tue, 28 Jul 2026 15:20:36 +0200 Subject: [PATCH 2/3] fix(marko-virtual): converge chat-pretext "Latest" instead of one-shot scrollToEnd --- .../marko/chat-pretext/src/routes/+page.marko | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/examples/marko/chat-pretext/src/routes/+page.marko b/examples/marko/chat-pretext/src/routes/+page.marko index 34ac6d7c8..349ad0800 100644 --- a/examples/marko/chat-pretext/src/routes/+page.marko +++ b/examples/marko/chat-pretext/src/routes/+page.marko @@ -133,6 +133,14 @@ static function messageHeight(message: Message, viewportWidth: number) { pinnedInitially: false, autoHistoryArmed: false, autoHistoryEnabled: false, + // "Latest" in flight: keep re-pinning until the end is actually reached. A + // single scrollToEnd() can land and then be carried away — e.g. an in-flight + // history prepend (180ms timer) resolving AFTER the jump grows the content + // above the viewport, and if core's offset read is stale at that moment its + // at-end compensation is skipped — so the view strands ~12 rows short with no + // scroll event to recover it. The reactive