mirror of
https://github.com/denoland/deno.git
synced 2024-11-23 15:16:54 -05:00
f7556d8962
This reverts commit 71ca61e189
.
Now uses a shared implementation from deno_core.
182 lines
3.9 KiB
TypeScript
182 lines
3.9 KiB
TypeScript
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
|
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
|
|
|
|
// TODO(petamoriken): enable prefer-primordials for node polyfills
|
|
// deno-lint-ignore-file prefer-primordials
|
|
|
|
import { core, primordials } from "ext:core/mod.js";
|
|
import { validateFunction } from "ext:deno_node/internal/validators.mjs";
|
|
import { newAsyncId } from "ext:deno_node/internal/async_hooks.ts";
|
|
|
|
const {
|
|
ObjectDefineProperties,
|
|
ReflectApply,
|
|
FunctionPrototypeBind,
|
|
ArrayPrototypeUnshift,
|
|
ObjectFreeze,
|
|
} = primordials;
|
|
|
|
const {
|
|
AsyncVariable,
|
|
getAsyncContext,
|
|
setAsyncContext,
|
|
} = core;
|
|
|
|
export class AsyncResource {
|
|
type: string;
|
|
#snapshot: unknown;
|
|
#asyncId: number;
|
|
|
|
constructor(type: string) {
|
|
this.type = type;
|
|
this.#snapshot = getAsyncContext();
|
|
this.#asyncId = newAsyncId();
|
|
}
|
|
|
|
asyncId() {
|
|
return this.#asyncId;
|
|
}
|
|
|
|
runInAsyncScope(
|
|
fn: (...args: unknown[]) => unknown,
|
|
thisArg: unknown,
|
|
...args: unknown[]
|
|
) {
|
|
const previousContext = getAsyncContext();
|
|
try {
|
|
setAsyncContext(this.#snapshot);
|
|
return ReflectApply(fn, thisArg, args);
|
|
} finally {
|
|
setAsyncContext(previousContext);
|
|
}
|
|
}
|
|
|
|
emitDestroy() {}
|
|
|
|
bind(fn: (...args: unknown[]) => unknown, thisArg) {
|
|
validateFunction(fn, "fn");
|
|
let bound;
|
|
if (thisArg === undefined) {
|
|
// deno-lint-ignore no-this-alias
|
|
const resource = this;
|
|
bound = function (...args) {
|
|
ArrayPrototypeUnshift(args, fn, this);
|
|
return ReflectApply(resource.runInAsyncScope, resource, args);
|
|
};
|
|
} else {
|
|
bound = FunctionPrototypeBind(this.runInAsyncScope, this, fn, thisArg);
|
|
}
|
|
ObjectDefineProperties(bound, {
|
|
"length": {
|
|
__proto__: null,
|
|
configurable: true,
|
|
enumerable: false,
|
|
value: fn.length,
|
|
writable: false,
|
|
},
|
|
});
|
|
return bound;
|
|
}
|
|
|
|
static bind(
|
|
fn: (...args: unknown[]) => unknown,
|
|
type?: string,
|
|
thisArg?: AsyncResource,
|
|
) {
|
|
type = type || fn.name || "bound-anonymous-fn";
|
|
return (new AsyncResource(type)).bind(fn, thisArg);
|
|
}
|
|
}
|
|
|
|
export class AsyncLocalStorage {
|
|
#variable = new AsyncVariable();
|
|
enabled = false;
|
|
|
|
// deno-lint-ignore no-explicit-any
|
|
run(store: any, callback: any, ...args: any[]): any {
|
|
this.enabled = true;
|
|
const previous = this.#variable.enter(store);
|
|
try {
|
|
return ReflectApply(callback, null, args);
|
|
} finally {
|
|
setAsyncContext(previous);
|
|
}
|
|
}
|
|
|
|
// deno-lint-ignore no-explicit-any
|
|
exit(callback: (...args: unknown[]) => any, ...args: any[]): any {
|
|
if (!this.enabled) {
|
|
return ReflectApply(callback, null, args);
|
|
}
|
|
this.enabled = false;
|
|
try {
|
|
return ReflectApply(callback, null, args);
|
|
} finally {
|
|
this.enabled = true;
|
|
}
|
|
}
|
|
|
|
// deno-lint-ignore no-explicit-any
|
|
getStore(): any {
|
|
if (!this.enabled) {
|
|
return undefined;
|
|
}
|
|
return this.#variable.get();
|
|
}
|
|
|
|
enterWith(store: unknown) {
|
|
this.enabled = true;
|
|
this.#variable.enter(store);
|
|
}
|
|
|
|
disable() {
|
|
this.enabled = false;
|
|
}
|
|
|
|
static bind(fn: (...args: unknown[]) => unknown) {
|
|
return AsyncResource.bind(fn);
|
|
}
|
|
|
|
static snapshot() {
|
|
return AsyncLocalStorage.bind((
|
|
cb: (...args: unknown[]) => unknown,
|
|
...args: unknown[]
|
|
) => ReflectApply(cb, null, args));
|
|
}
|
|
}
|
|
|
|
export function executionAsyncId() {
|
|
return 0;
|
|
}
|
|
|
|
export function triggerAsyncId() {
|
|
return 0;
|
|
}
|
|
|
|
export function executionAsyncResource() {
|
|
return {};
|
|
}
|
|
|
|
export const asyncWrapProviders = ObjectFreeze({ __proto__: null });
|
|
|
|
class AsyncHook {
|
|
enable() {
|
|
}
|
|
|
|
disable() {
|
|
}
|
|
}
|
|
|
|
export function createHook() {
|
|
return new AsyncHook();
|
|
}
|
|
|
|
export default {
|
|
AsyncLocalStorage,
|
|
createHook,
|
|
executionAsyncId,
|
|
triggerAsyncId,
|
|
executionAsyncResource,
|
|
asyncWrapProviders,
|
|
AsyncResource,
|
|
};
|