openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
57 lines (56 loc) • 2.12 kB
JavaScript
import { i as resolveGlobalSingleton } from "./global-singleton-Dc_stLtU.js";
import { t as createDeferredCore } from "./deferred-D0La5CRk.js";
import { AsyncLocalStorage } from "node:async_hooks";
//#region src/shared/async-work-scope.ts
const currentWorkScope = resolveGlobalSingleton(Symbol.for("openclaw.asyncWorkScope"), () => new AsyncLocalStorage());
/** Joins cooperating descendants even when their caller returns a cached value first. */
var AsyncWorkScope = class {
constructor() {
this.pending = /* @__PURE__ */ new Set();
this.controller = new AbortController();
this.phase = "open";
}
get signal() {
return this.controller.signal;
}
get isClosing() {
return this.phase !== "open";
}
track(run) {
if (this.phase === "closed") return Promise.reject(/* @__PURE__ */ new Error("Async work scope is closed"));
const operation = createDeferredCore();
this.pending.add(operation.promise);
operation.promise.then(() => this.pending.delete(operation.promise), () => this.pending.delete(operation.promise));
try {
operation.resolve(currentWorkScope.run(this, run));
} catch (error) {
operation.reject(error);
}
return operation.promise;
}
beginClose() {
if (this.phase !== "open") return;
this.phase = "closing";
this.controller.abort();
}
async drain() {
this.beginClose();
while (this.pending.size > 0) await Promise.allSettled(this.pending);
this.phase = "closed";
}
};
/** Outside a managed scope, the returned promise remains the caller's responsibility. */
async function trackAsyncWork(run) {
const scope = currentWorkScope.getStore();
return await (scope ? scope.track(run) : run());
}
/** Captures only work ownership, never the caller's authorization or other async context. */
function captureAsyncWorkTracker() {
const scope = currentWorkScope.getStore();
return async (run) => await (scope ? scope.track(run) : currentWorkScope.exit(run));
}
function getAsyncWorkSignal() {
return currentWorkScope.getStore()?.signal;
}
//#endregion
export { trackAsyncWork as i, captureAsyncWorkTracker as n, getAsyncWorkSignal as r, AsyncWorkScope as t };