openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
73 lines (72 loc) • 2.21 kB
JavaScript
import { a as resolveGlobalSingleton } from "./global-singleton-0m-JziJW.mjs";
import { AsyncLocalStorage } from "node:async_hooks";
//#region src/shared/effect-authority.ts
const effectScope = resolveGlobalSingleton(Symbol.for("openclaw.effectAuthority"), () => new AsyncLocalStorage());
/** Host binding: adapters receive initiation and scope restoration, never a mutation capability. */
async function withEffectPreparation(prepare, run) {
if (!prepare) return await run();
let open = true;
const assertOpen = () => {
if (!open) throw new Error("Effect authority is no longer active");
};
const bound = async () => {
assertOpen();
const use = await prepare();
try {
assertOpen();
return {
assertCurrent() {
assertOpen();
use.assertCurrent();
},
initiate(effect) {
return use.initiate(() => {
assertOpen();
return effect();
});
},
release: () => use.release(),
persist: (write) => use.persist((assertCurrent) => write(() => {
assertOpen();
assertCurrent();
}))
};
} catch (error) {
use.release();
throw error;
}
};
try {
return await effectScope.run(bound, run);
} finally {
open = false;
}
}
/** Database writers retain this use through their existing commit/settlement boundary. */
function prepareEffectAuthority() {
return effectScope.getStore()?.() ?? Promise.resolve(void 0);
}
/** Capture before queues; each native request, retry, or disclosure prepares a fresh use. */
function captureEffectAuthority() {
const prepare = effectScope.getStore();
return {
active: prepare !== void 0,
run(run) {
return effectScope.run(prepare, run);
},
async initiate(effect) {
const use = prepare ? await prepare() : void 0;
try {
return use ? use.initiate(effect) : effect();
} finally {
use?.release();
}
}
};
}
/** Independent owners, such as transport crypto maintenance, restore their own scope explicitly. */
function withEffectAuthority(authority, run) {
return authority ? authority.run(run) : effectScope.run(void 0, run);
}
//#endregion
export { withEffectPreparation as i, prepareEffectAuthority as n, withEffectAuthority as r, captureEffectAuthority as t };