diff --git a/ext/node/polyfills/async_hooks.ts b/ext/node/polyfills/async_hooks.ts index d60334346b..ea0bfb9442 100644 --- a/ext/node/polyfills/async_hooks.ts +++ b/ext/node/polyfills/async_hooks.ts @@ -316,6 +316,17 @@ export class AsyncLocalStorage { ); Scope.enter(frame); } + + static bind(fn: (...args: unknown[]) => unknown) { + return AsyncResource.bind(fn); + } + + static snapshot() { + return AsyncLocalStorage.bind(( + cb: (...args: unknown[]) => unknown, + ...args: unknown[] + ) => cb(...args)); + } } export function executionAsyncId() { diff --git a/tests/unit_node/async_hooks_test.ts b/tests/unit_node/async_hooks_test.ts index 076d14b54d..2ed197c2da 100644 --- a/tests/unit_node/async_hooks_test.ts +++ b/tests/unit_node/async_hooks_test.ts @@ -94,3 +94,34 @@ Deno.test(async function enterWith() { assertEquals(await deferred.promise, { x: 2 }); assertEquals(await deferred1.promise, { x: 1 }); }); + +Deno.test(async function snapshot() { + const als = new AsyncLocalStorage(); + const deferred = Promise.withResolvers(); + + als.run(null, () => { + const snapshot = AsyncLocalStorage.snapshot(); + als.run({ x: 1 }, () => { + deferred.resolve(snapshot(() => als.getStore())); + }); + }); + + assertEquals(await deferred.promise, null); +}); + +Deno.test(async function bind() { + const als = new AsyncLocalStorage(); + const deferred = Promise.withResolvers(); + + const bound = als.run(null, () => { + return AsyncLocalStorage.bind(() => { + deferred.resolve(als.getStore()); + }); + }); + + als.run({ x: 1 }, () => { + bound(); + }); + + assertEquals(await deferred.promise, null); +});