Skip to content

oj v0.2.25

Choose a tag to compare

@github-actions github-actions released this 12 Oct 16:28
· 194 commits to main since this release
cfe498b

Fixed

  • A dependency bump can no longer wedge the dev server through the deps preseed. oj replays each environment's previously optimized dep ids into optimizeDeps.include (so plugin-injected deps don't force a mid-session re-optimize and restart), but an id whose package still exists while its exports map no longer answers that subpath makes Vite's optimizer throw — unresolvable ids only warn — and the failing optimize is the very step that would have aged the id out, so every later boot failed the same way (the preseed child exited, and in-host the custom dev environment's configureServer could hang plugin host init indefinitely). The replayed set is now bounded by install state the way Vite bounds its own metadata: the snapshot records the same lockfile hash Vite keys _metadata.json by, and ids from another install state are dropped at every door (reading prior metadata, merging, folding), costing the one discovery session Vite itself pays after a dependency change. If an optimize still fails with replayed ids folded in under the same install state, the child now drops that environment's replayed set, heals the snapshot (the plugin host folds the same file), and retries once as a discovery session. Snapshots from before this change carry no recorded install state and are discarded once.
  • An SSR or TanStack Start request arriving while the SSR plugin host is still initializing now waits the init out instead of failing after one hook window (20s) with plugin host still initializing after 20s running transform. A large vite config can take longer than that to boot, and under Vite a request can never fail this way: the server socket only opens after plugin init completes. Watcher events still skip a pre-init host and replay at its init.

Changed

  • Elapsed time alone no longer fails plugin work anywhere, matching Vite, which runs config loads, plugin hooks and the dep optimizer with no timeout at all. The init wait, every plugin hook, config extraction, the dep pre-bundle and the pending-dep route gate are now unbounded; slow work logs progress (a "still running (Ns)…" line every 30s, probe lines on long hooks) instead of dying on a timer. What actually distinguishes dead from slow is what fails work now: the host process dying, and a liveness probe met with total engine silence — a no-op export is pinged each probe window (20s), which a parked event loop answers instantly, so only an isolate blocked in native code or spinning in synchronous JS is declared gone (and the next call revives it; under Vite the same plugin hangs the server forever). A synchronously wedged hook therefore costs one respawn instead of being terminated in place — the trade for never killing a healthy slow hook. The timeout env knobs died with their timers: OJ_PLUGIN_TIMEOUT, OJ_PLUGIN_INIT_TIMEOUT, OJ_EXTRACT_TIMEOUT, OJ_OPTIMIZE_TIMEOUT and OJ_PRESEED_TIMEOUT are gone (the preseed child keeps a fixed 300s kill bound — orphan hygiene for a never-fatal background optimization, not a work deadline; the boot warning about an uninitialized host prints at a fixed 300s). A boot that used to 500 or degrade at a knob's default now behaves like Vite: it takes as long as it takes, visibly.