# Design — @suaveplan/test-vite ## Tier and dependency allowlist Tier: **universal-ish-tooling** — runs in Node-build contexts (`vite build`) and Vitest test files. Not browser-runtime. Dependency allowlist (production): - `@suaveplan/error` (workspace) — `defineCodes` + `SuaveplanError` for `TestViteError`. - `@suaveplan/types` (workspace) — `Clock`, `LoggerLike` injection contracts. - `@suaveplan/opentelemetry` (workspace, transitive) — meter wiring via `@opentelemetry/api`. - `@opentelemetry/api` (catalog:observability) — counters + histograms. - `vite` (catalog:build) — `UserConfig` type + `defineConfig` re-imported by factories. - `vitest` (catalog:testing) — `UserConfig` / `defineConfig` from `vitest/config`. - `vite-plugin-dts` (catalog:build) — used inside `createViteLibraryConfig`. - `zod` (catalog:forms) — boundary validation of every public option object. - `tslib` (catalog:build) — helper runtime. Dev-only: `@suaveplan/testing` for `./runner` wrapper, `@opentelemetry/sdk-metrics` for in-memory MeterProvider test setup, `@types/node`, `typescript`, `@vitest/coverage-istanbul`. `vite` / `vitest` / `vite-plugin-dts` are production deps because callers inherit them via this package (matching the upstream convention from the enterprise plan §2). ## Folder layout ``` src/ index.ts # explicit named re-exports vite-library-config/ vite-library-config.ts # createViteLibraryConfig(opts) vite-library-config.md vite-library-config.test.ts vite-app-config/ vite-app-config.ts # createViteAppConfig(opts) vite-app-config.md vite-app-config.test.ts vitest-config/ vitest-config.ts # createVitestConfig(opts) vitest-config.md vitest-config.test.ts vitest-browser-config/ vitest-browser-config.ts # createVitestBrowserConfig(opts) vitest-browser-config.md vitest-browser-config.test.ts browser-environment/ browser-environment.ts # setupBrowserEnvironment browser-environment.md browser-environment.test.ts tree-shake-validator/ tree-shake-validator.ts # verifyTreeShake tree-shake-validator.md tree-shake-validator.test.ts bundle-size-snapshot/ bundle-size-snapshot.ts # snapshotBundleSize bundle-size-snapshot.md bundle-size-snapshot.test.ts port-allocator/ port-allocator.ts # allocate/releasePort port-allocator.md port-allocator.test.ts hmr-tester/ hmr-tester.ts # withHMR hmr-tester.md hmr-tester.test.ts matchers/ matchers.ts # createMatchers matchers.md matchers.test.ts error-codes/ error-codes.ts # TEST_VITE_CODES, TestViteError error-codes.md error-codes.test.ts telemetry/ telemetry.ts # OTel instruments telemetry.md telemetry.test.ts types/ test-vite.types.ts # shared interfaces tests/ setup/ polyfills.ts # in-memory MeterProvider + webcrypto ``` ## Error-code plan `defineCodes("TEST_VITE", [...])` with these codes: - `INVALID_OPTIONS` — Zod parse failure on any factory option object. - `MISSING_ENTRY` — bundle file required by `verifyTreeShake` / `snapshotBundleSize` cannot be read. - `TREE_SHAKE_VIOLATION` — bundle exports a symbol not in `expectedSymbols`. - `SIZE_BUDGET_EXCEEDED` — bundle size exceeds snapshot + tolerance. - `SNAPSHOT_MISSING` — snapshot file not found and `update: false`. - `PORT_EXHAUSTED` — no port in the configured range is available. - `PORT_NOT_HELD` — release of an unheld port. - `HMR_TIMEOUT` — HMR round-trip exceeded timeout. 8 codes — every one is exercised by a test (see spec deltas). ## OTel instrument plan Meter name: `@suaveplan/test-vite`. Instruments: - `test_vite_config_built_total` (counter) — one per factory invocation; attribute `kind` = `vite_library`/`vite_app`/`vitest`/`vitest_browser`. - `test_vite_validator_runs_total` (counter) — one per `verifyTreeShake` or `snapshotBundleSize` call. - `test_vite_validator_violations_total` (counter) — one per detected violation. - `test_vite_port_allocations_total` (counter) — one per successful `allocatePort`. - `test_vite_hmr_round_trip_ms` (histogram) — recorded on every `withHMR` resolution. All wired into a single `telemetry.ts` module with a real MeterProvider asserted in `telemetry.test.ts`. ## Boundary validation Every public factory accepts an options object validated by a Zod schema. Invalid input → `TestViteError(TEST_VITE_CODES.INVALID_OPTIONS, …)` carrying the Zod issue list on `details`. ## Test-runner discipline All `*.test.ts` files import from `@suaveplan/testing/runner` (rule 11). No `vitest` or `bun:test` direct imports. ## File-size budget Every implementation file stays under 300 lines hard / 250 soft. Where logic is dense (`tree-shake-validator`, `bundle-size-snapshot`), shared helpers are extracted into private module-local functions; if necessary they spill into a sibling `.helpers.ts` (still inside the feature folder, with its own `.md`).