From a79d8acd7aebaa81d00ec3bff1a884ef81eb28cb Mon Sep 17 00:00:00 2001 From: terencecho <3916587+terencecho@users.noreply.github.com> Date: Fri, 15 May 2026 21:24:30 -0700 Subject: [PATCH] fix: ship lottieReadiness + guard studio import.meta.env for non-Vite consumers (#861) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Two small fixes that together make `@hyperframes/core` + `@hyperframes/studio` consumable from non-Vite hosts (Next.js / Turbopack, Node, etc.). ### 1. `core`: ship the missing `lottieReadiness` module The `"./runtime/lottie-readiness"` subpath export in `@hyperframes/core` claims to ship at `./dist/runtime/adapters/lottieReadiness.js`, but that file is missing from the published 0.6.6 and 0.6.7 tarballs. Consumers that import the subpath — most notably `@hyperframes/studio`'s `Player.tsx` — fail to resolve the module and break downstream builds. **Root cause:** `packages/core/tsconfig.json` excludes `src/runtime` (those files run in a browser context and are bundled separately into the IIFE artifact). Since nothing in the included tree imports `lottieReadiness.ts`, tsc never emits a compiled output, and the file silently goes missing from the publish. **Fix:** `lottieReadiness.ts` is a pure helper — takes `unknown`, returns `boolean`, no DOM/`window` dependencies. It doesn't belong in `src/runtime/` in the first place; the runtime-exclude rule rightly caught it. Move it to `src/lottieReadiness.ts` so the standard library build picks it up. The subpath export **name** stays `"./runtime/lottie-readiness"` — only the exports map's underlying file path changes — so existing consumers (studio) don't need any code change. ### 2. `studio`: guard `import.meta.env` for non-Vite hosts `packages/studio/src/components/editor/manualEditingAvailability.ts` unconditionally reads `import.meta.env`. That's a Vite-only extension; in plain ESM hosts (Next.js / Turbopack, Node, jest in some configs) `import.meta` exists but `import.meta.env` is `undefined`. Reading any property off undefined throws at module evaluation time, so the studio fails to load the moment a non-Vite host imports anything from `@hyperframes/studio`. Guarded the read so the module is loadable everywhere; outside Vite, every flag falls back to its declared default, preserving Vite behavior. ### Changes **core:** - `mv src/runtime/adapters/lottieReadiness.{ts,test.ts}` → `src/` - Update `src/runtime/adapters/lottie.ts` re-export path - Update `package.json` + `publishConfig.exports` to point at the new dist path (`./dist/lottieReadiness.{js,d.ts}`) **studio:** - One-line guard in `manualEditingAvailability.ts:30` with explanatory comment ## Test plan - [x] `pnpm typecheck` (core, studio) — clean - [x] `bun run build` (core) — `dist/lottieReadiness.{js,d.ts}` now present - [x] `bunx vitest run` (core) — 862/862 passing - [x] `bun run typecheck` (studio) — clean, resolves moved file via subpath export - [ ] Publish 0.6.8 and verify the tarball contains `dist/lottieReadiness.js` - [ ] Verify a non-Vite ESM consumer (e.g. a Next.js / Turbopack app) imports `@hyperframes/studio` without `import.meta.env` errors 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- packages/core/package.json | 8 ++++---- .../src/{runtime/adapters => }/lottieReadiness.test.ts | 0 .../core/src/{runtime/adapters => }/lottieReadiness.ts | 0 packages/core/src/runtime/adapters/lottie.ts | 2 +- .../src/components/editor/manualEditingAvailability.ts | 7 ++++++- 5 files changed, 11 insertions(+), 6 deletions(-) rename packages/core/src/{runtime/adapters => }/lottieReadiness.test.ts (100%) rename packages/core/src/{runtime/adapters => }/lottieReadiness.ts (100%) diff --git a/packages/core/package.json b/packages/core/package.json index 300251328..fe07d3849 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -31,8 +31,8 @@ }, "./runtime": "./dist/hyperframe.runtime.iife.js", "./runtime/lottie-readiness": { - "import": "./src/runtime/adapters/lottieReadiness.ts", - "types": "./src/runtime/adapters/lottieReadiness.ts" + "import": "./src/lottieReadiness.ts", + "types": "./src/lottieReadiness.ts" }, "./studio-api": { "import": "./src/studio-api/index.ts", @@ -78,8 +78,8 @@ }, "./runtime": "./dist/hyperframe.runtime.iife.js", "./runtime/lottie-readiness": { - "import": "./dist/runtime/adapters/lottieReadiness.js", - "types": "./dist/runtime/adapters/lottieReadiness.d.ts" + "import": "./dist/lottieReadiness.js", + "types": "./dist/lottieReadiness.d.ts" }, "./studio-api": { "import": "./dist/studio-api/index.js", diff --git a/packages/core/src/runtime/adapters/lottieReadiness.test.ts b/packages/core/src/lottieReadiness.test.ts similarity index 100% rename from packages/core/src/runtime/adapters/lottieReadiness.test.ts rename to packages/core/src/lottieReadiness.test.ts diff --git a/packages/core/src/runtime/adapters/lottieReadiness.ts b/packages/core/src/lottieReadiness.ts similarity index 100% rename from packages/core/src/runtime/adapters/lottieReadiness.ts rename to packages/core/src/lottieReadiness.ts diff --git a/packages/core/src/runtime/adapters/lottie.ts b/packages/core/src/runtime/adapters/lottie.ts index 74da88a16..88dc35c52 100644 --- a/packages/core/src/runtime/adapters/lottie.ts +++ b/packages/core/src/runtime/adapters/lottie.ts @@ -1,6 +1,6 @@ import type { RuntimeDeterministicAdapter } from "../types"; import { swallow } from "../diagnostics"; -export { isLottieAnimationLoaded } from "./lottieReadiness"; +export { isLottieAnimationLoaded } from "../../lottieReadiness"; /** * Lottie adapter for HyperFrames diff --git a/packages/studio/src/components/editor/manualEditingAvailability.ts b/packages/studio/src/components/editor/manualEditingAvailability.ts index 5fd276639..345ca8f41 100644 --- a/packages/studio/src/components/editor/manualEditingAvailability.ts +++ b/packages/studio/src/components/editor/manualEditingAvailability.ts @@ -27,7 +27,12 @@ export function resolveStudioBooleanEnvFlag( return fallback; } -const env = import.meta.env as StudioFeatureFlagEnv; +// `import.meta.env` is a Vite-only extension. In non-Vite ESM hosts +// (Next.js / Turbopack, Node, jest in some configs) it's undefined, +// and downstream `env[name]` reads would crash. Fall back to `{}` so +// every flag resolves to its declared default outside Vite. Direct +// property access keeps Vite's compile-time transform happy. +const env = (import.meta.env ?? {}) as StudioFeatureFlagEnv; export const STUDIO_PREVIEW_MANUAL_EDITING_ENABLED = resolveStudioBooleanEnvFlag( env,