//#region src/scope/TeggScope.d.ts /** * The per-app scope "bag": a type-free container keyed by per-package symbols. * * Each tegg package defines its own slot {@link symbol} and its own concrete * fallback, and reads/writes ONLY its own slot. No package imports another * package's slot — the bag is the single shared, type-agnostic carrier. The * aggregating "TeggRuntime" convenience that knows the concrete types lives in a * higher layer (plugin/tegg, standalone Runner) where importing metadata + * runtime is legal; it builds the bag and wraps boot/request in * {@link TeggScope.run}. */ export type TeggScopeBag = Map; /** * Type-free, lowest-level async scope container for tegg multi-app isolation. * * It owns ONLY the AsyncLocalStorage, the scope counter, and the strict-mode * escape fuse. It knows nothing about concrete factories/managers — those are * resolved by each package via {@link TeggScope.resolve} / {@link TeggScope.getOr} * against its own slot. */ export declare class TeggScope { #private; /** The bag for the currently active async scope, if any. */ static current(): TeggScopeBag | undefined; /** Run `fn` with `bag` as the active scope. Synchronous or async `fn`. */ static run(bag: TeggScopeBag, fn: () => R): R; /** * Run `fn` in `bag`'s scope when a bag is provided, otherwise run it directly * in whatever scope is already active (the bag may not be established yet during * very early boot). Centralizes the per-app `bag ? run(bag, fn) : fn()` idiom. */ static runMaybe(bag: TeggScopeBag | undefined, fn: () => R): R; /** Create a fresh, empty per-app bag. */ static createBag(): TeggScopeBag; /** * Mark that an explicit per-app scope has been established (boot), tracking the * app's bag so that — while it is the sole live app — no-scope access resolves * to it instead of a separate process-default bag. */ static registerScope(bag: TeggScopeBag): void; /** Mark that a previously-established per-app scope has been torn down (close). */ static unregisterScope(bag: TeggScopeBag): void; /** True when more than one app scope is alive — genuine multi-app mode. */ static get isMultiApp(): boolean; /** Number of live explicit app scopes. */ static get scopeCount(): number; /** * Resolve a lazily-materialized per-app singleton (factory / manager / cache). * * - inside a scope: lazily create via `create()` and memoize in the active bag; * - no scope: lazily create+memoize in the single process-default bag * (single-app lazy default). Under multi-app, hitting the default bag is * reported as an escape (dev throw / prod warn). * * `create()` may reference sibling slots' static facades (e.g. `X.instance`); * because they resolve against the SAME bag, cross-slot dependencies stay * consistent in both scoped and default modes. */ static resolve(slot: symbol, create: () => T, desc: string): T; /** * Read a "set later, may be undefined" slot (e.g. globalGraph, context * callbacks). The active bag (scoped, or the single process-default bag) is the * source of truth; `legacy()` only supplies the initial value before any set. */ static getOr(slot: symbol, legacy: () => T | undefined, desc: string): T | undefined; /** * Write a slot into the active bag (scoped, or the single process-default bag). * Always succeeds; returns true for symmetry with earlier call sites. * * Like {@link TeggScope.resolve} / {@link TeggScope.getOr}, a write that escapes * to the process-default bag under multi-app mode is reported, so a missed * scope wrap that silently mutates shared state is caught instead of leaking. */ static set(slot: symbol, value: unknown): boolean; /** @internal Reset the process-default bag (e.g. between tests). */ static _resetDefaultBag(): void; /** @internal The current process-default bag, if any. */ static _getDefaultBag(): TeggScopeBag | undefined; } //#endregion