[world-local] Fix package info stored in data dir showing the wrong version#718
[world-local] Fix package info stored in data dir showing the wrong version#718VaguelySerious merged 11 commits intomainfrom
Conversation
Signed-off-by: Peter Wielander <mittgfu@gmail.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
🦋 Changeset detectedLatest commit: d8b514f The changes in this PR will be included in the next version bump. This PR includes changesets to release 15 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
🧪 E2E Test Results❌ Some tests failed Summary
❌ Failed Tests▲ Vercel Production (1 failed)nuxt (1 failed):
🌍 Community Worlds (161 failed)mongodb (40 failed):
redis (40 failed):
starter (41 failed):
turso (40 failed):
Details by Category❌ ▲ Vercel Production
✅ 💻 Local Development
✅ 📦 Local Production
✅ 🐘 Local Postgres
✅ 🪟 Windows
❌ 🌍 Community Worlds
❌ Some E2E test jobs failed:
Check the workflow run for details. |
📊 Benchmark Results
workflow with no steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro | Next.js (Turbopack) | Express workflow with 1 step💻 Local Development
▲ Production (Vercel)
🔍 Observability: Next.js (Turbopack) | Express | Nitro workflow with 10 sequential steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Next.js (Turbopack) | Express | Nitro Promise.all with 10 concurrent steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro | Next.js (Turbopack) | Express Promise.all with 25 concurrent steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Next.js (Turbopack) | Nitro | Express Promise.race with 10 concurrent steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Next.js (Turbopack) | Nitro | Express Promise.race with 25 concurrent steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro | Next.js (Turbopack) | Express Stream Benchmarks (includes TTFB metrics)workflow with stream💻 Local Development
▲ Production (Vercel)
🔍 Observability: Express | Nitro | Next.js (Turbopack) SummaryFastest Framework by WorldWinner determined by most benchmark wins
Fastest World by FrameworkWinner determined by most benchmark wins
Column Definitions
Worlds:
|
| const packageInfo = await getPackageInfo(); | ||
| const currentVersion = parseVersion(packageInfo.version); |
There was a problem hiding this comment.
When getPackageInfo() returns a fallback version of "bundled" (in bundled contexts where package.json is inaccessible), initDataDir() will crash because parseVersion('bundled') throws an error - "bundled" doesn't match the semver regex pattern.
View Details
📝 Patch Details
diff --git a/packages/world-local/src/init.ts b/packages/world-local/src/init.ts
index 7562441..2b9e4e6 100644
--- a/packages/world-local/src/init.ts
+++ b/packages/world-local/src/init.ts
@@ -326,6 +326,13 @@ export async function initDataDir(dataDir: string): Promise<void> {
await ensureDataDir(dataDir);
const packageInfo = await getPackageInfo();
+
+ // In bundled contexts, package.json is not accessible and version is 'bundled'.
+ // Skip version checking in this case since we can't determine the actual version.
+ if (packageInfo.version === 'bundled') {
+ return;
+ }
+
const currentVersion = parseVersion(packageInfo.version);
// Read existing version file
Analysis
parseVersion('bundled') crashes in initDataDir() when package.json is inaccessible
What fails: initDataDir() crashes with Error: Invalid version string: "bundled" when called in bundled contexts where import.meta.url is undefined and package.json cannot be read.
How to reproduce:
// In a bundled context (e.g., Next.js with world-local embedded):
import { createLocalWorld } from '@workflow/world-local';
const world = createLocalWorld({ dataDir: '.workflow-data' });
await world.start(); // Throws: Error: Invalid version string: "bundled"This occurs when:
import.meta.urlis undefined or empty (bundled CJS contexts)getPackageInfo()falls back to returning{ version: 'bundled' }(lines 60-65)initDataDir()callsparseVersion(packageInfo.version)at line 329parseVersion('bundled')throws because 'bundled' doesn't match the semver regex pattern^(\d+)\.(\d+)\.(\d+)(?:-(.+))?$
Result: Application crash with uncaught error during startup, preventing World from initializing in bundled/production contexts.
Expected: initDataDir() should gracefully handle the bundled version case without crashing. In bundled contexts where the actual version cannot be determined, version checking should be skipped.
Fix: Added explicit check for packageInfo.version === 'bundled' in initDataDir() to skip version parsing and checking when the version cannot be determined. This is appropriate for bundled contexts because:
- The directory structure is already ensured to be accessible (via
ensureDataDir()) - Version tracking is a best-effort feature; skipping it in bundled contexts is safe
- Bundled contexts are typically development/testing scenarios where strict version compatibility is less critical
|
|
||
| /** | ||
| * Get the directory path for this module. | ||
| * Works in both ESM (direct usage) and bundled CJS contexts. |
There was a problem hiding this comment.
I'm not understanding how this would work in CJS contexts (also why would it need to?)
There was a problem hiding this comment.
It doesn't, the comment is wrong, whoops
| * In bundled contexts where package.json cannot be read, | ||
| * returns 'bundled' as the version. | ||
| */ | ||
| export async function getPackageInfo(): Promise<PackageInfo> { |
There was a problem hiding this comment.
I wonder if we could leverage require() instead? Not blocking though, I'm fine with this for now and we can see if it causes any real world issues. Just feels a bit brittle to me.
There was a problem hiding this comment.
I think this should overall be replaced by the version solution that's in Pranay's event sourcing PR. We could merge this first if we want, or scrap for re-doing it after Pranay's PR lands
|
|
||
| const currentVersion = parseVersion(PACKAGE_VERSION); | ||
| const packageInfo = await getPackageInfo(); | ||
| const currentVersion = parseVersion(packageInfo.version); |
Minor patch, but since we're already showing the local world package version as the deploymentId, we might as well get it right. Can then later iterate on making this more useful