mirror of
https://github.com/oven-sh/bun
synced 2026-02-17 06:12:08 +00:00
Compare commits
2 Commits
claude/fix
...
claude/asy
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9d36605331 | ||
|
|
b780b96806 |
@@ -2,7 +2,7 @@ option(WEBKIT_VERSION "The version of WebKit to use")
|
||||
option(WEBKIT_LOCAL "If a local version of WebKit should be used instead of downloading")
|
||||
|
||||
if(NOT WEBKIT_VERSION)
|
||||
set(WEBKIT_VERSION 863778130931e0081a688f48e8479b8ee61b9507)
|
||||
set(WEBKIT_VERSION preview-pr-122-786e646a)
|
||||
endif()
|
||||
|
||||
string(SUBSTRING ${WEBKIT_VERSION} 0 16 WEBKIT_VERSION_PREFIX)
|
||||
|
||||
@@ -36,7 +36,7 @@ JSC::Structure* AsyncContextFrame::createStructure(JSC::VM& vm, JSC::JSGlobalObj
|
||||
|
||||
JSValue AsyncContextFrame::withAsyncContextIfNeeded(JSGlobalObject* globalObject, JSValue callback)
|
||||
{
|
||||
JSValue context = globalObject->m_asyncContextData.get()->getInternalField(0);
|
||||
JSValue context = globalObject->asyncContext();
|
||||
|
||||
// If there is no async context, do not snapshot the callback.
|
||||
if (context.isUndefined()) {
|
||||
@@ -96,16 +96,16 @@ extern "C" JSC::EncodedJSValue AsyncContextFrame__withAsyncContextIfNeeded(JSGlo
|
||||
return jsUndefined(); \
|
||||
auto& vm = global->vm(); \
|
||||
JSValue restoreAsyncContext; \
|
||||
InternalFieldTuple* asyncContextData = nullptr; \
|
||||
bool hasAsyncContext = false; \
|
||||
if (auto* wrapper = jsDynamicCast<AsyncContextFrame*>(functionObject)) { \
|
||||
functionObject = jsCast<JSC::JSObject*>(wrapper->callback.get()); \
|
||||
asyncContextData = global->m_asyncContextData.get(); \
|
||||
restoreAsyncContext = asyncContextData->getInternalField(0); \
|
||||
asyncContextData->putInternalField(vm, 0, wrapper->context.get()); \
|
||||
restoreAsyncContext = global->asyncContext(); \
|
||||
global->setAsyncContext(vm, wrapper->context.get()); \
|
||||
hasAsyncContext = true; \
|
||||
} \
|
||||
auto result = JSC::profiledCall(__VA_ARGS__); \
|
||||
if (asyncContextData) { \
|
||||
asyncContextData->putInternalField(vm, 0, restoreAsyncContext); \
|
||||
if (hasAsyncContext) { \
|
||||
global->setAsyncContext(vm, restoreAsyncContext); \
|
||||
} \
|
||||
return result;
|
||||
|
||||
|
||||
@@ -88,7 +88,7 @@ void JSNextTickQueue::drain(JSC::VM& vm, JSC::JSGlobalObject* globalObject)
|
||||
if (!isEmpty()) {
|
||||
RETURN_IF_EXCEPTION(throwScope, );
|
||||
if (mustResetContext) {
|
||||
globalObject->m_asyncContextData.get()->putInternalField(vm, 0, jsUndefined());
|
||||
globalObject->setAsyncContext(vm, jsUndefined());
|
||||
RETURN_IF_EXCEPTION(throwScope, );
|
||||
}
|
||||
auto* drainFn = internalField(2).get().getObject();
|
||||
|
||||
@@ -22,13 +22,13 @@ static bool call(JSGlobalObject* globalObject, JSValue timerObject, JSValue call
|
||||
auto scope = DECLARE_CATCH_SCOPE(vm);
|
||||
|
||||
JSValue restoreAsyncContext {};
|
||||
JSC::InternalFieldTuple* asyncContextData = nullptr;
|
||||
bool hasAsyncContext = false;
|
||||
|
||||
if (auto* wrapper = jsDynamicCast<AsyncContextFrame*>(callbackValue)) {
|
||||
callbackValue = wrapper->callback.get();
|
||||
asyncContextData = globalObject->m_asyncContextData.get();
|
||||
restoreAsyncContext = asyncContextData->getInternalField(0);
|
||||
asyncContextData->putInternalField(vm, 0, wrapper->context.get());
|
||||
restoreAsyncContext = globalObject->asyncContext();
|
||||
globalObject->setAsyncContext(vm, wrapper->context.get());
|
||||
hasAsyncContext = true;
|
||||
}
|
||||
|
||||
if (auto* promise = jsDynamicCast<JSPromise*>(callbackValue)) {
|
||||
@@ -66,8 +66,8 @@ static bool call(JSGlobalObject* globalObject, JSValue timerObject, JSValue call
|
||||
hadException = true;
|
||||
}
|
||||
|
||||
if (asyncContextData) {
|
||||
asyncContextData->putInternalField(vm, 0, restoreAsyncContext);
|
||||
if (hasAsyncContext) {
|
||||
globalObject->setAsyncContext(vm, restoreAsyncContext);
|
||||
}
|
||||
|
||||
return hadException;
|
||||
|
||||
@@ -789,16 +789,16 @@ void NodeVMGlobalObject::finishCreation(JSC::VM& vm)
|
||||
|
||||
vm.ensureTerminationException();
|
||||
|
||||
// Share the async context data with the parent Zig::GlobalObject.
|
||||
// Delegate async context to the parent Zig::GlobalObject.
|
||||
// This is necessary because AsyncLocalStorage methods (run, getStore, etc.) are defined
|
||||
// in the parent realm and reference the parent's $asyncContext. However, microtask
|
||||
// processing (JSMicrotask.cpp) operates on this NodeVMGlobalObject's m_asyncContextData.
|
||||
// By sharing the same InternalFieldTuple, both the JS code and C++ microtask handling
|
||||
// in the parent realm and reference the parent's $asyncContext. However, C++ code
|
||||
// (JSMicrotask.cpp, etc.) uses this NodeVMGlobalObject's asyncContext() accessor.
|
||||
// By delegating to the parent, both the JS code and C++ async context handling
|
||||
// will operate on the same async context, ensuring proper AsyncLocalStorage behavior
|
||||
// across await boundaries in VM contexts.
|
||||
auto* parentGlobalObject = defaultGlobalObject(this);
|
||||
if (parentGlobalObject && parentGlobalObject->m_asyncContextData) {
|
||||
m_asyncContextData.set(vm, this, parentGlobalObject->m_asyncContextData.get());
|
||||
if (parentGlobalObject) {
|
||||
setAsyncContextDelegateParent(parentGlobalObject);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -358,7 +358,7 @@ static void checkIfNextTickWasCalledDuringMicrotask(JSC::VM& vm)
|
||||
static void cleanupAsyncHooksData(JSC::VM& vm)
|
||||
{
|
||||
auto* globalObject = defaultGlobalObject();
|
||||
globalObject->m_asyncContextData.get()->putInternalField(vm, 0, jsUndefined());
|
||||
globalObject->setAsyncContext(vm, jsUndefined());
|
||||
globalObject->asyncHooksNeedsCleanup = false;
|
||||
if (!globalObject->m_nextTickQueue) {
|
||||
vm.setOnEachMicrotaskTick(&checkIfNextTickWasCalledDuringMicrotask);
|
||||
@@ -1058,7 +1058,7 @@ JSC_DEFINE_HOST_FUNCTION(functionQueueMicrotask,
|
||||
RETURN_IF_EXCEPTION(scope, {});
|
||||
|
||||
auto* globalObject = defaultGlobalObject(lexicalGlobalObject);
|
||||
JSC::JSValue asyncContext = globalObject->m_asyncContextData.get()->getInternalField(0);
|
||||
JSC::JSValue asyncContext = globalObject->asyncContext();
|
||||
auto function = globalObject->performMicrotaskFunction();
|
||||
#if ASSERT_ENABLED
|
||||
ASSERT_WITH_MESSAGE(function, "Invalid microtask function");
|
||||
@@ -1340,6 +1340,23 @@ JSC_DEFINE_HOST_FUNCTION(functionCreateUninitializedArrayBuffer,
|
||||
RELEASE_AND_RETURN(scope, JSValue::encode(JSC::JSArrayBuffer::create(globalObject->vm(), globalObject->arrayBufferStructure(JSC::ArrayBufferSharingMode::Default), WTF::move(arrayBuffer))));
|
||||
}
|
||||
|
||||
JSC_DECLARE_HOST_FUNCTION(functionGetAsyncContext);
|
||||
JSC_DEFINE_HOST_FUNCTION(functionGetAsyncContext,
|
||||
(JSC::JSGlobalObject * globalObject, JSC::CallFrame*))
|
||||
{
|
||||
return JSValue::encode(globalObject->asyncContext());
|
||||
}
|
||||
|
||||
JSC_DECLARE_HOST_FUNCTION(functionSetAsyncContext);
|
||||
JSC_DEFINE_HOST_FUNCTION(functionSetAsyncContext,
|
||||
(JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
|
||||
{
|
||||
auto& vm = globalObject->vm();
|
||||
JSValue value = callFrame->argument(0);
|
||||
globalObject->setAsyncContext(vm, value);
|
||||
return JSValue::encode(value);
|
||||
}
|
||||
|
||||
static inline JSC::EncodedJSValue jsFunctionAddEventListenerBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, Zig::GlobalObject* castedThis)
|
||||
{
|
||||
auto& vm = JSC::getVM(lexicalGlobalObject);
|
||||
@@ -1573,12 +1590,12 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionPerformMicrotask, (JSGlobalObject * globalObj
|
||||
WTF::NakedPtr<JSC::Exception> exceptionPtr;
|
||||
|
||||
JSValue restoreAsyncContext = {};
|
||||
InternalFieldTuple* asyncContextData = nullptr;
|
||||
auto setAsyncContext = callframe->argument(1);
|
||||
if (!setAsyncContext.isUndefined()) {
|
||||
asyncContextData = globalObject->m_asyncContextData.get();
|
||||
restoreAsyncContext = asyncContextData->getInternalField(0);
|
||||
asyncContextData->putInternalField(vm, 0, setAsyncContext);
|
||||
bool hasAsyncContext = false;
|
||||
auto setAsyncContextArg = callframe->argument(1);
|
||||
if (!setAsyncContextArg.isUndefined()) {
|
||||
restoreAsyncContext = globalObject->asyncContext();
|
||||
globalObject->setAsyncContext(vm, setAsyncContextArg);
|
||||
hasAsyncContext = true;
|
||||
}
|
||||
|
||||
size_t argCount = callframe->argumentCount();
|
||||
@@ -1598,8 +1615,8 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionPerformMicrotask, (JSGlobalObject * globalObj
|
||||
|
||||
JSC::profiledCall(globalObject, ProfilingReason::API, job, callData, jsUndefined(), arguments, exceptionPtr);
|
||||
|
||||
if (asyncContextData) {
|
||||
asyncContextData->putInternalField(vm, 0, restoreAsyncContext);
|
||||
if (hasAsyncContext) {
|
||||
globalObject->setAsyncContext(vm, restoreAsyncContext);
|
||||
}
|
||||
|
||||
if (auto* exception = exceptionPtr.get()) {
|
||||
@@ -1640,18 +1657,18 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionPerformMicrotaskVariadic, (JSGlobalObject * g
|
||||
}
|
||||
|
||||
JSValue restoreAsyncContext = {};
|
||||
InternalFieldTuple* asyncContextData = nullptr;
|
||||
auto setAsyncContext = callframe->argument(2);
|
||||
if (!setAsyncContext.isUndefined()) {
|
||||
asyncContextData = globalObject->m_asyncContextData.get();
|
||||
restoreAsyncContext = asyncContextData->getInternalField(0);
|
||||
asyncContextData->putInternalField(vm, 0, setAsyncContext);
|
||||
bool hasAsyncContext = false;
|
||||
auto setAsyncContextArg = callframe->argument(2);
|
||||
if (!setAsyncContextArg.isUndefined()) {
|
||||
restoreAsyncContext = globalObject->asyncContext();
|
||||
globalObject->setAsyncContext(vm, setAsyncContextArg);
|
||||
hasAsyncContext = true;
|
||||
}
|
||||
|
||||
JSC::profiledCall(globalObject, ProfilingReason::API, job, callData, thisValue, arguments, exceptionPtr);
|
||||
|
||||
if (asyncContextData) {
|
||||
asyncContextData->putInternalField(vm, 0, restoreAsyncContext);
|
||||
if (hasAsyncContext) {
|
||||
globalObject->setAsyncContext(vm, restoreAsyncContext);
|
||||
}
|
||||
|
||||
if (auto* exception = exceptionPtr.get()) {
|
||||
@@ -2723,6 +2740,8 @@ void GlobalObject::addBuiltinGlobals(JSC::VM& vm)
|
||||
putDirectBuiltinFunction(vm, this, builtinNames.overridableRequirePrivateName(), commonJSOverridableRequireCodeGenerator(vm), 0);
|
||||
|
||||
putDirectNativeFunction(vm, this, builtinNames.createUninitializedArrayBufferPrivateName(), 1, functionCreateUninitializedArrayBuffer, ImplementationVisibility::Public, NoIntrinsic, PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
|
||||
putDirectNativeFunction(vm, this, builtinNames.getAsyncContextPrivateName(), 0, functionGetAsyncContext, ImplementationVisibility::Public, NoIntrinsic, PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
|
||||
putDirectNativeFunction(vm, this, builtinNames.setAsyncContextPrivateName(), 1, functionSetAsyncContext, ImplementationVisibility::Public, NoIntrinsic, PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
|
||||
putDirectNativeFunction(vm, this, builtinNames.resolveSyncPrivateName(), 1, functionImportMeta__resolveSyncPrivate, ImplementationVisibility::Public, NoIntrinsic, PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
|
||||
putDirectNativeFunction(vm, this, builtinNames.createInternalModuleByIdPrivateName(), 1, InternalModuleRegistry::jsCreateInternalModuleById, ImplementationVisibility::Public, NoIntrinsic, PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
|
||||
|
||||
|
||||
@@ -2734,12 +2734,12 @@ extern "C" JSC::EncodedJSValue Bun__JSValue__call(JSC::JSGlobalObject* globalObj
|
||||
JSC::JSValue jsThisObject = JSValue::decode(thisObject);
|
||||
|
||||
JSValue restoreAsyncContext;
|
||||
InternalFieldTuple* asyncContextData = nullptr;
|
||||
bool hasAsyncContext = false;
|
||||
if (auto* wrapper = jsDynamicCast<AsyncContextFrame*>(jsObject)) {
|
||||
jsObject = jsCast<JSC::JSFunction*>(wrapper->callback.get());
|
||||
asyncContextData = globalObject->m_asyncContextData.get();
|
||||
restoreAsyncContext = asyncContextData->getInternalField(0);
|
||||
asyncContextData->putInternalField(vm, 0, wrapper->context.get());
|
||||
restoreAsyncContext = globalObject->asyncContext();
|
||||
globalObject->setAsyncContext(vm, wrapper->context.get());
|
||||
hasAsyncContext = true;
|
||||
}
|
||||
|
||||
if (!jsThisObject)
|
||||
@@ -2771,8 +2771,8 @@ extern "C" JSC::EncodedJSValue Bun__JSValue__call(JSC::JSGlobalObject* globalObj
|
||||
|
||||
auto result = JSC::profiledCall(globalObject, ProfilingReason::API, jsObject, callData, jsThisObject, argList);
|
||||
|
||||
if (asyncContextData) {
|
||||
asyncContextData->putInternalField(vm, 0, restoreAsyncContext);
|
||||
if (hasAsyncContext) {
|
||||
globalObject->setAsyncContext(vm, restoreAsyncContext);
|
||||
}
|
||||
|
||||
RETURN_IF_EXCEPTION(scope, {});
|
||||
@@ -3524,7 +3524,7 @@ void JSC__JSPromise__rejectOnNextTickWithHandled(JSC::JSPromise* promise, JSC::J
|
||||
auto microtaskFunction = globalObject->performMicrotaskFunction();
|
||||
auto rejectPromiseFunction = globalObject->rejectPromiseFunction();
|
||||
|
||||
auto asyncContext = globalObject->m_asyncContextData.get()->getInternalField(0);
|
||||
auto asyncContext = globalObject->asyncContext();
|
||||
|
||||
#if ASSERT_ENABLED
|
||||
ASSERT_WITH_MESSAGE(microtaskFunction, "Invalid microtask function");
|
||||
@@ -3540,7 +3540,7 @@ void JSC__JSPromise__rejectOnNextTickWithHandled(JSC::JSPromise* promise, JSC::J
|
||||
value = jsUndefined();
|
||||
}
|
||||
|
||||
JSC::QueuedTask task { nullptr, JSC::InternalMicrotask::BunPerformMicrotaskJob, globalObject, microtaskFunction, rejectPromiseFunction, globalObject->m_asyncContextData.get()->getInternalField(0), promise, value };
|
||||
JSC::QueuedTask task { nullptr, JSC::InternalMicrotask::BunPerformMicrotaskJob, globalObject, microtaskFunction, rejectPromiseFunction, asyncContext, promise, value };
|
||||
globalObject->vm().queueMicrotask(WTF::move(task));
|
||||
RETURN_IF_EXCEPTION(scope, );
|
||||
}
|
||||
@@ -5390,7 +5390,7 @@ extern "C" void JSC__JSGlobalObject__queueMicrotaskJob(JSC::JSGlobalObject* arg0
|
||||
Zig::GlobalObject* globalObject = static_cast<Zig::GlobalObject*>(arg0);
|
||||
JSValue microtaskArgs[] = {
|
||||
JSValue::decode(JSValue1),
|
||||
globalObject->m_asyncContextData.get()->getInternalField(0),
|
||||
globalObject->asyncContext(),
|
||||
JSValue::decode(JSValue3),
|
||||
JSValue::decode(JSValue4)
|
||||
};
|
||||
|
||||
2
src/js/builtins.d.ts
vendored
2
src/js/builtins.d.ts
vendored
@@ -439,6 +439,7 @@ declare function $flushAlgorithm(): TODO;
|
||||
declare function $format(): TODO;
|
||||
declare function $fulfillModuleSync(key: string): void;
|
||||
declare function $get(): TODO;
|
||||
declare function $getAsyncContext(): ReadonlyArray<any> | undefined;
|
||||
declare function $getInternalWritableStream(writable: WritableStream): TODO;
|
||||
declare function $handleEvent(): TODO;
|
||||
declare function $hash(): TODO;
|
||||
@@ -531,6 +532,7 @@ declare function $search(): TODO;
|
||||
declare function $searchParams(): TODO;
|
||||
declare function $self(): TODO;
|
||||
declare function $sep(): TODO;
|
||||
declare function $setAsyncContext<T extends ReadonlyArray<any> | undefined>(context: T): T;
|
||||
declare function $setBody(): TODO;
|
||||
declare function $setStatus(): TODO;
|
||||
declare function $setup(): TODO;
|
||||
|
||||
@@ -126,6 +126,7 @@ using namespace JSC;
|
||||
macro(flushAlgorithm) \
|
||||
macro(format) \
|
||||
macro(fulfillModuleSync) \
|
||||
macro(getAsyncContext) \
|
||||
macro(getInternalWritableStream) \
|
||||
macro(handleEvent) \
|
||||
macro(hash) \
|
||||
@@ -230,6 +231,7 @@ using namespace JSC;
|
||||
macro(secure) \
|
||||
macro(self) \
|
||||
macro(sep) \
|
||||
macro(setAsyncContext) \
|
||||
macro(setBody) \
|
||||
macro(setStatus) \
|
||||
macro(setup) \
|
||||
|
||||
@@ -299,8 +299,8 @@ export function initializeNextTickQueue(
|
||||
var callback = tock.callback;
|
||||
var args = tock.args;
|
||||
var frame = tock.frame;
|
||||
var restore = $getInternalField($asyncContext, 0);
|
||||
$putInternalField($asyncContext, 0, frame);
|
||||
var restore = $getAsyncContext();
|
||||
$setAsyncContext(frame);
|
||||
try {
|
||||
if (args === undefined) {
|
||||
callback();
|
||||
@@ -326,7 +326,7 @@ export function initializeNextTickQueue(
|
||||
} catch (e) {
|
||||
reportUncaughtException(e);
|
||||
} finally {
|
||||
$putInternalField($asyncContext, 0, restore);
|
||||
$setAsyncContext(restore);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -353,7 +353,7 @@ export function initializeNextTickQueue(
|
||||
// We want to avoid materializing the args if there are none because it's
|
||||
// a waste of memory and Array.prototype.slice shows up in profiling.
|
||||
args: $argumentCount() > 1 ? args : undefined,
|
||||
frame: $getInternalField($asyncContext, 0),
|
||||
frame: $getAsyncContext(),
|
||||
});
|
||||
$putInternalField(nextTickQueue, 0, 1);
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ export function initializeReadableStream(
|
||||
$putByIdDirectPrivate(this, "readableStreamController", null);
|
||||
this.$bunNativePtr = $getByIdDirectPrivate(underlyingSource, "bunNativePtr") ?? undefined;
|
||||
|
||||
$putByIdDirectPrivate(this, "asyncContext", $getInternalField($asyncContext, 0));
|
||||
$putByIdDirectPrivate(this, "asyncContext", $getAsyncContext());
|
||||
|
||||
const isDirect = underlyingSource.type === "direct";
|
||||
// direct streams are always lazy
|
||||
|
||||
@@ -143,11 +143,11 @@ export function setupReadableStreamDefaultController(
|
||||
const pullAlgorithm = () => $promiseInvokeOrNoopMethod(underlyingSource, pullMethod, [controller]);
|
||||
const cancelAlgorithm = asyncContext
|
||||
? reason => {
|
||||
var prev = $getInternalField($asyncContext, 0);
|
||||
$putInternalField($asyncContext, 0, asyncContext);
|
||||
var prev = $getAsyncContext();
|
||||
$setAsyncContext(asyncContext);
|
||||
// this does not throw, but can returns a rejected promise
|
||||
var result = $promiseInvokeOrNoopMethod(underlyingSource, cancelMethod, [reason]);
|
||||
$putInternalField($asyncContext, 0, prev);
|
||||
$setAsyncContext(prev);
|
||||
return result;
|
||||
}
|
||||
: reason => $promiseInvokeOrNoopMethod(underlyingSource, cancelMethod, [reason]);
|
||||
@@ -1035,8 +1035,8 @@ export function onPullDirectStream(controller: ReadableStreamDirectController) {
|
||||
|
||||
var asyncContext = stream.$asyncContext;
|
||||
if (asyncContext) {
|
||||
var prev = $getInternalField($asyncContext, 0);
|
||||
$putInternalField($asyncContext, 0, asyncContext);
|
||||
var prev = $getAsyncContext();
|
||||
$setAsyncContext(asyncContext);
|
||||
}
|
||||
|
||||
// Direct streams allow $pull to be called multiple times, unlike the spec.
|
||||
@@ -1063,7 +1063,7 @@ export function onPullDirectStream(controller: ReadableStreamDirectController) {
|
||||
controller._deferFlush = controller._deferClose = 0;
|
||||
|
||||
if (asyncContext) {
|
||||
$putInternalField($asyncContext, 0, prev);
|
||||
$setAsyncContext(prev);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -63,14 +63,14 @@ function debugFormatContextValue(value: ReadonlyArray<any> | undefined) {
|
||||
}
|
||||
|
||||
function get(): ReadonlyArray<any> | undefined {
|
||||
$debug("get", debugFormatContextValue($getInternalField($asyncContext, 0)));
|
||||
return $getInternalField($asyncContext, 0);
|
||||
$debug("get", debugFormatContextValue($getAsyncContext()));
|
||||
return $getAsyncContext();
|
||||
}
|
||||
|
||||
function set(contextValue: ReadonlyArray<any> | undefined) {
|
||||
$assert(assertValidAsyncContextArray(contextValue));
|
||||
$debug("set", debugFormatContextValue(contextValue));
|
||||
return $putInternalField($asyncContext, 0, contextValue);
|
||||
return $setAsyncContext(contextValue);
|
||||
}
|
||||
|
||||
class AsyncLocalStorage {
|
||||
|
||||
Reference in New Issue
Block a user