chore: migrate package manager bun → pnpm + test runner bun:test → Vite+ (vp test)#450
Merged
Merged
Conversation
…te+ (vp test)
Mirrors the staged migration shipped on the `weaverse-builder` repo
(PRs #2360, #2361, #2362, #2363), squashed into one consolidated change
since the SDK monorepo is much smaller (216 tests, 6 packages).
## What changed
### Package manager (Stage 1 equivalent)
- `packageManager`: bun@1.3.11 → pnpm@11.1.2
- `bun.lock` deleted, `pnpm-lock.yaml` generated
- `bunfig.toml` deleted
- New `pnpm-workspace.yaml`:
- `nodeLinker: hoisted` — flat node_modules so transitive deps keep
resolving without explicit declarations (matches bun's behaviour)
- `allowBuilds` — explicit allow-list for postinstall scripts
(esbuild, lefthook, biome, workerd, @parcel/watcher); pnpm 11
blocks them by default as supply-chain hardening
- `verifyDepsBeforeRun: false` — prevents infinite recursion when
turbo invokes nested `pnpm run build` calls
- `catalog:` block aliases `vite` → @voidzero-dev/vite-plus-core,
`vitest` → @voidzero-dev/vite-plus-test, plus `vite-plus` CLI
- `.npmrc`: kept `legacy-peer-deps=true`, added
`verify-deps-before-run=false` mirror for safety
- Root `package.json`:
- scripts: `npm run X` → `pnpm run X`
- new `test:run` script (`vp test --run --bail=1`)
- removed `prepare` script (caused recursive install loops under
pnpm 11; consumers don't need it since this is a private monorepo)
- added `vite`, `vite-plus`, `vitest` devDeps via catalog
### Test runner (Stage 2 equivalent)
- New root `vite.config.ts` with `test:` block (node env, forks pool,
30s timeout, include/exclude patterns relative to cwd so it works
both from repo root and from each package via turbo)
- Per-package `test` scripts: `bun test` → `vp test --run`
(hydrogen, i18n, react, schema, cli — cli's was `echo 'No tests'`
even though it had a real test file)
- All 12 test files ported `from 'bun:test'` → `from 'vitest'`:
- `spyOn` / `mock` aliased locally (`const spyOn = vi.spyOn`,
`const mock = vi.fn`) to keep diffs minimal
- `mock.module(name, factory)` → `vi.mock(name, factory)`
(i18n/__tests__/client.test.ts) — works identically since
vitest hoists `vi.mock` calls
- `mock.restore()` → `vi.restoreAllMocks()` (react data-connector)
- 3 standalone validation scripts that use the `.test.ts` suffix but
contain no `describe`/`it` blocks excluded by name
(core/blah, schema/enhanced-features, schema/type-alignment)
### CI (.github/workflows/check.yml)
- Replaced `oven-sh/setup-bun` + bun cache with `pnpm/action-setup`
+ Node's built-in pnpm cache, keyed on pnpm-lock.yaml
- Added a `test` job running `pnpm run test`
### Tooling
- `lefthook.yml`: `bun run biome` → `pnpm exec biome`
- `scripts/clean.sh`: already handled both lockfiles; no change needed
### Docs (AGENTS.md, CLAUDE.md, ARCHITECTURE.md)
- Command tables rewritten for pnpm
- Test patterns updated to import from `vitest` and use `vi.*` API
## Verification
All passing locally on macOS arm64, Node 20, pnpm 11.1.2:
pnpm install → 184 packages, clean
pnpm run typecheck → 4 packages, clean
pnpm run build → 5 packages, clean
pnpm run test → 6 packages, 13 files, 216 tests passing
pnpm run test:run → same
pnpm run biome → no issues
- paths-ignore: skip docs/md/workflow-only PRs - concurrency: cancel in-progress reviews when new commits land - skip drafts (`if: !pr.draft`) - widen permissions (pull-requests: write, issues: write, actions: read) so the action can actually post sticky comments + track progress - enable use_sticky_comment + track_progress - actions/checkout v4 → v6 Same config that's been running cleanly on `weaverse-builder`. Fixes the silent 'directory mismatch' failure mode we hit on this PR's first review run.
paul-phan
added a commit
that referenced
this pull request
May 19, 2026
…452) Fixes #451. `WeaverseHydrogenRoot` previously resolved `weaverseData` by walking `useMatches()` and returning the deepest match's payload. Because `useMatches()` is tree-global, every `<WeaverseContent />` instance on the same page resolved to the same value — making it impossible for two instances (e.g. a layout-loaded page + a child-loaded page) to render different Weaverse pages on the same URL. This restores the route-scoped primitive via `useLoaderData()` for the `weaverseData` lookup, while keeping the existing `useMatches()`-driven `createWeaverseDataContext` infrastructure untouched (it legitimately needs all matches to build the route-keyed data-connector context). Resolution policy, implemented as a pure helper `pickWeaverseData()`: 1. **Explicit `data` prop** (new — escape hatch + supports the typed `Route.ComponentProps.loaderData` framework-mode pattern). Passing `null` explicitly suppresses rendering. 2. **Own route's loader data** via `useLoaderData()` — the route-scoped primitive that fixes the bug. 3. **Ancestor walk** through `useMatches()` — back-compat fallback for the index-without-loader pattern. `hasWeaverseData` requires the value be defined (not just present), so `{ weaverseData: undefined }` does not short-circuit Tier 2. Back-compat: unmodified themes with zero-prop `<WeaverseContent />` continue to work via Tier 2 — identical render output for the common single-instance case. Index leaves without loaders continue to fall back to ancestor `weaverseData` via Tier 3. Deferred (`Promise`) loaders pass through unchanged. `data?` prop is optional; existing call sites compile unchanged. Pilot template audit: every `<WeaverseContent />` caller has its own loader; no layout-loaded `weaverseData` exists. No pilot changes required. Tests: 21 new selector unit tests covering all three tiers, `weaverseData: undefined` at both Tier 2 and Tier 3, `null`-suppression, deferred loaders, and an explicit #451 regression assertion. Also includes a `chore` commit replacing remaining `bun` references with `pnpm` in the `releasing-weaverse-sdks` skill (follow-up to #450).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Mirrors the staged migration shipped on the
weaverse-builderrepo (PRs #2360, #2361, #2362, #2363), squashed into one consolidated change since the SDK monorepo is much smaller (216 tests, 6 packages).What changed
Package manager (Stage 1 equivalent)
packageManager:bun@1.3.11→pnpm@11.1.2bun.lockdeleted,pnpm-lock.yamlgeneratedbunfig.tomldeletedpnpm-workspace.yaml:nodeLinker: hoisted— flat node_modules so transitive deps keep resolving without explicit declarations (matches bun's behaviour)allowBuilds— explicit allow-list for postinstall scripts (esbuild, lefthook, biome, workerd, @parcel/watcher); pnpm 11 blocks them by default as supply-chain hardeningverifyDepsBeforeRun: false— prevents infinite recursion when turbo invokes nestedpnpm run buildcallscatalog:block aliasesvite→@voidzero-dev/vite-plus-core,vitest→@voidzero-dev/vite-plus-test, plusvite-plusCLI.npmrc: keptlegacy-peer-deps=true, addedverify-deps-before-run=falsemirror for safetypackage.json:npm run X→pnpm run Xtest:runscript (vp test --run --bail=1)preparescript (caused recursive install loops under pnpm 11; this is a private monorepo so consumers don't need it)vite,vite-plus,vitestdevDeps via catalogTest runner (Stage 2 equivalent)
vite.config.tswithtest:block (node env, forks pool, 30s timeout, include/exclude patterns relative to cwd so it works both from repo root and from each package via turbo)testscripts:bun test→vp test --run(hydrogen, i18n, react, schema, cli — cli's wasecho 'No tests'even though it had a real test file)from 'bun:test'→from 'vitest':spyOn/mockaliased locally (const spyOn = vi.spyOn,const mock = vi.fn) to keep diffs minimalmock.module(name, factory)→vi.mock(name, factory)(i18n/__tests__/client.test.ts) — works identically since vitest hoistsvi.mockcallsmock.restore()→vi.restoreAllMocks()(react data-connector).test.tssuffix but contain nodescribe/itblocks excluded by name (core/blah,schema/enhanced-features,schema/type-alignment) — these should probably be renamed in a follow-upCI (
.github/workflows/check.yml)oven-sh/setup-bun+ bun cache withpnpm/action-setup+ Node's built-in pnpm cache, keyed onpnpm-lock.yamltestjob runningpnpm run testTooling
lefthook.yml:bun run biome→pnpm exec biomescripts/clean.sh: already handled both lockfiles; no change neededDocs (
AGENTS.md,CLAUDE.md,ARCHITECTURE.md)vitestand usevi.*APIVerification
All passing locally on macOS arm64, Node 20, pnpm 11.1.2:
pnpm installpnpm run typecheckpnpm run buildpnpm run test(turbo orchestrated)pnpm run test:run(single vp invocation)pnpm run biome