Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/safe-context-probe.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"evlog": patch
---

Prevent the Elysia integration from stalling `bun:test` lifecycle hooks by avoiding the side-effecting `AsyncLocalStorage.enterWith()` capability probe on Bun.
5 changes: 4 additions & 1 deletion packages/evlog/src/shared/asyncStorageScope.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,15 @@ export interface AsyncLocalStorageLike<T> {
* Whether this runtime provides a working native `AsyncLocalStorage.enterWith()`.
*
* Cloudflare Workers expose `enterWith` on the prototype but throw when it is
* called, so a `typeof` check alone is not enough — we probe with a call.
* called, so a `typeof` check alone is not enough. Bun implements it natively,
* but probing changes `bun:test`'s active async context, so Bun is detected
* without invoking the method.
*/
export function supportsAsyncLocalStorageEnterWith(
storage: { enterWith?: unknown },
): boolean {
if (typeof storage.enterWith !== 'function') return false
if ('Bun' in globalThis) return true
try {
// Must call as a method — unbound enterWith loses `this` and throws on Node.
const probe = storage as { enterWith: (store: undefined) => void }
Expand Down
14 changes: 13 additions & 1 deletion packages/evlog/test/shared/asyncStorageScope.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { AsyncLocalStorage } from 'node:async_hooks'
import { beforeEach, describe, expect, it } from 'vitest'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { Elysia } from 'elysia'
import { initLogger } from '../../src/logger'
import {
Expand Down Expand Up @@ -52,6 +52,18 @@ async function request(app: { handle: (req: Request) => Promise<Response> }, pat
}

describe('asyncStorageScope', () => {
afterEach(() => {
vi.unstubAllGlobals()
})

it('does not probe enterWith on Bun (#496)', () => {
vi.stubGlobal('Bun', {})
const enterWith = vi.fn()

expect(supportsAsyncLocalStorageEnterWith({ enterWith })).toBe(true)
expect(enterWith).not.toHaveBeenCalled()
})

it('detects native enterWith support', () => {
expect(supportsAsyncLocalStorageEnterWith(new AsyncLocalStorage<string>())).toBe(true)
})
Expand Down
Loading