Skip to content

Warlock.js 5.39.1

Choose a tag to compare

@hassanzohdy hassanzohdy released this 26 Oct 20:47
· 90 commits to main since this release

Released 2026-10-26.

All 33 packages (@warlock.js/* and create-warlock) move to 5.39.1 together;
keep every family package on the same version. No breaking changes. This is a fix
release for test-run exits, migrations, standalone builds and log channels.


1. Breaking changes

  • None. 5.39.1 has no breaking changes.

2. Test runs exit promptly (core, scheduler)

  • Running schedulers are stopped on shutdown. An app that calls scheduler.start()
    while its modules load (the stock template does this) kept the Vitest main process
    alive after the HTTP test server stopped. Vitest then waited out its 10-second close
    timeout and printed something prevents N Vite servers from exiting. The shutdown of
    the HTTP test server, warlock start and per-worker test teardown now stop every
    running @warlock.js/scheduler scheduler within app.shutdownTimeout.
  • scheduler.shutdown() clears its own cap timer when the jobs finish first, so it
    no longer holds the process open for up to 30 seconds.
  • If the message still appears, a handle the app opens itself (an interval, a socket, a
    queue worker) is keeping the process alive. npx vitest run --reporter=hanging-process
    names it.

3. Migrations close cleanly and never stall silently (core, cascade)

  • warlock migrate releases the migration lock and closes every data source before
    it exits: on success, on failure, with --pending, and on Ctrl+C / SIGTERM (exit
    130 / 143). Shutdown has a bounded wait, so it cannot hang.
  • Connecting to MongoDB is bounded (30 s for server selection) and fails with a clear
    message instead of hanging at Connecting to database. A stalled graceful close falls
    back to a forced close after 10 s.
  • Long migrations report progress. A migration that runs long prints
    still running "<name>", step N of M, <n>s elapsed at 30 s and then every 60 s.
    Migrations are not aborted by default, so a long index build is never left half-applied.
  • Opt-in hard limit. warlock migrate --timeout <seconds> (or
    WARLOCK_MIGRATION_TIMEOUT_MS, in milliseconds) fails a migration that exceeds the limit,
    naming it, and exits 1.
  • Partial failures are explained. A failed migration names the migration and, on
    MongoDB, the step (step 3 of 5). It says that no ledger row was written, how many steps
    were applied, and how to recover: re-running is safe because index creation is
    idempotent, or --rollback starts over.

4. Standalone builds (core)

  • Vite is no longer bundled when the app lists it under devDependencies. Only
    dependencies, optionalDependencies and peerDependencies count as declared by the
    app. This removes about 60 MB of bundled Vite and the rolldown and lightningcss
    native addons from dist/.
  • Build-time tools stay out of the bundle. vite, rolldown, lightningcss,
    esbuild, oxc-parser, @vitejs/* and @babel/* (except @babel/runtime) are never
    bundled or staged when framework code imports them, even when the app lists them under
    dependencies. A third-party library that imports one at module level is still bundled,
    so it keeps working with no node_modules.
  • Aliased native packages are staged under the imported name. A package installed as
    "node-pty": "npm:@lydell/node-pty" is copied to dist/node_modules/node-pty, so the
    import resolves from dist/.
  • Only reachable native packages are staged, and the build warns about a native package
    it could not copy because its os, cpu or libc excludes the build machine.

5. Log channels (logger)

  • LogChannel.ready resolves once the channel's deferred init() has finished. Await
    it before relying on the channel being set up.
  • A channel disposed before its deferred init() ran no longer creates its directory or
    arms the 5-second flush interval afterwards.

6. Upgrade notes

  1. Update the family. Run npx warlock update.
  2. Read what changed. Run npx warlock release-notes --from 5.39.0.
  3. Remove workarounds (if added). Drop any build.external entries for vite,
    rolldown or lightningcss, any manual scheduler.shutdown() call in test teardown,
    and any raised Vitest teardownTimeout added for slow exits.
  4. Set a migration limit (optional). In CI, pass warlock migrate --timeout <seconds>
    if you prefer a failed run to a slow one.