Skip to content

oj v0.2.8

Choose a tag to compare

@github-actions github-actions released this 26 Sep 12:01
· 281 commits to main since this release
2bb35ae

Added

  • OJ_DEBUG_MEM=1 exposes /@oj/debug/gc: a memory-probing instrument that forces a full V8 collection (low_memory_notification) in every live engine, so probes measure retained heap rather than garbage V8 has not collected yet. The symmetric counterpart to forcing GC in a Node server through its inspector (issue #202); 404 unless enabled, never a runtime lever.

Removed

  • oj dev --bundle (the bundled dev mode), which the 0.2.7 notes announced one merge too early: the removal ships in this release. Unbundled dev is the mode Vite has, the mode every fixture and production consumer runs, and the only one the plugin-hook gating work optimizes; the flag and its legacy websocket invalidate frame are gone.

Changed

  • SSR and Start server plugin hooks now gate on the per-plugin filter plan like build and dev (the transform and load RPCs skip modules no plugin's filter can claim), with the plan primed at host handout so the gates run on real filters from the first dispatch. On a 2000-component Start app: -10% process CPU and -33MB footprint on a cold SSR render.
  • Allocation hygiene across the serve path: fewer intermediate copies on hot routes.

Fixed

  • More of the app's Vite configuration is honored where oj previously applied defaults: server.warmup files are pre-transformed at boot, server.fs.deny brace groups expand like Vite's, and optimizeDeps.noDiscovery reaches the optimizer, all from the extracted config instead of being silently dropped (#150).
  • An ES-module dependency served file by file that imports an unbundled CommonJS/UMD sibling (the proj4 -> geographiclib-geodesic shape) strict-linked against exports static analysis cannot see and failed with "does not provide an export named ...". Served ESM dependencies now get the same importer-side CJS interop as app source: named imports and re-exports read off module.exports at runtime, export * as ns builds the interop namespace (Vite leaves that shape uninteroped), and a bare export * from "cjs" warns like Vite that runtime-assigned exports cannot ride a star re-export. Gated on a parse-free specifier scan probed against the interop mapping, so a dependency module pays the rewrite's parse only when one of its imports will actually be rewritten; the star-re-export warning is deduplicated across recompiles, and the dynamic-import helper lands after a hashbang instead of breaking bin-entry deps.
  • TanStack Start apps on a vite that predates rolldown (vite <= 7, no rolldown anywhere in their dependency tree) failed every oj build and dev client bundle with "cannot resolve 'rolldown'", on every oj version. The nix package now vendors the pinned rolldown (~20MB per platform, embedded as OJ_VENDORED_ROLLDOWN and part of the binary's runtime closure), and the Start bundles (oj's own code, written against that version) prefer it over whatever the app's vite pins, falling back to the app's copy on oj builds that vendor nothing. The preference applies only at oj's own rolldown imports (an app importing rolldown itself keeps its lockfile's copy), OJ_VENDORED_ROLLDOWN= (set but empty) opts out entirely, and the vendor's resolved identity (version + path) salts the Start bundle cache key so bundles built by different rolldowns (including an in-place upgrade at the same path) never restore for each other. A vendor that is set but holds no rolldown fails the command loudly instead of silently building with the app's copy. Non-nix builds keep the error, which now names the fallback.