function _getAsyncLocalStorage() { return globalThis.AsyncLocalStorage || globalThis.process?.getBuiltinModule?.("node:async_hooks")?.AsyncLocalStorage; } const _WeakRef = globalThis.WeakRef || class StrongRef { #value; constructor(value) { this.#value = value; } deref() { return this.#value; } }; function createContext(opts = {}) { let currentInstance; let isSingleton = false; const checkConflict = (instance) => { if (currentInstance && currentInstance !== instance) throw new Error("Context conflict"); }; let als; if (opts.asyncContext) { const _AsyncLocalStorage = opts.AsyncLocalStorage || _getAsyncLocalStorage(); if (_AsyncLocalStorage) als = new _AsyncLocalStorage(); else console.warn("[unctx] `AsyncLocalStorage` is not provided."); } const _wrapInstance = (instance) => als && instance !== null && typeof instance === "object" ? { __unctx_weak: new _WeakRef(instance) } : instance; const _unwrapInstance = (store) => store && store.__unctx_weak ? store.__unctx_weak.deref() : store; const _getCurrentInstance = () => { if (als) { const store = als.getStore(); if (store !== void 0) return _unwrapInstance(store); } return currentInstance; }; return { use: () => { const _instance = _getCurrentInstance(); if (_instance === void 0) throw new Error("Context is not available"); return _instance; }, tryUse: () => { return _getCurrentInstance() ?? null; }, set: (instance, replace) => { if (!replace) checkConflict(instance); currentInstance = instance; isSingleton = true; }, unset: () => { currentInstance = void 0; isSingleton = false; }, call: (instance, callback) => { checkConflict(instance); currentInstance = instance; try { return als ? als.run(_wrapInstance(instance), callback) : callback(); } finally { if (!isSingleton) currentInstance = void 0; } }, async callAsync(instance, callback) { currentInstance = instance; const onRestore = () => { currentInstance = instance; }; const onLeave = () => currentInstance === instance ? onRestore : void 0; asyncHandlers.add(onLeave); try { const r = als ? als.run(_wrapInstance(instance), callback) : callback(); if (!isSingleton) currentInstance = void 0; return await r; } finally { asyncHandlers.delete(onLeave); } } }; } function createNamespace(defaultOpts = {}) { const contexts = {}; return { get(key, opts = {}) { if (!contexts[key]) contexts[key] = createContext({ ...defaultOpts, ...opts }); return contexts[key]; } }; } const _globalThis = typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : typeof window !== "undefined" ? window : {}; const globalKey = "__unctx__"; const defaultNamespace = _globalThis[globalKey] || (_globalThis[globalKey] = createNamespace()); const getContext = (key, opts = {}) => defaultNamespace.get(key, opts); const useContext = (key, opts = {}) => getContext(key, opts).use; const asyncHandlersKey = "__unctx_async_handlers__"; const asyncHandlers = _globalThis[asyncHandlersKey] || (_globalThis[asyncHandlersKey] = /* @__PURE__ */ new Set()); function executeAsync(function_) { const restores = []; for (const leaveHandler of asyncHandlers) { const restore = leaveHandler(); if (restore) restores.push(restore); } const restore = () => { for (const restore of restores) restore(); }; let awaitable = function_(); if (awaitable && typeof awaitable === "object" && "catch" in awaitable) awaitable = awaitable.catch((error) => { restore(); throw error; }); return [awaitable, restore]; } function withAsyncContext(function_, transformed) { if (!transformed) console.warn("[unctx] `withAsyncContext` needs transformation for async context support in", function_, "\n", function_.toString()); return function_; } export { createContext, createNamespace, defaultNamespace, executeAsync, getContext, useContext, withAsyncContext };