{"version":3,"sources":["../src/core/request-context.ts","../src/core/hook.ts"],"names":["createDefault","als","fallbackContext","isNode","requireFn","ah","getRequestContext","store","runWithRequestContext","fn","_isBrowser","_browserCurrentComponent","getComponent","runWithComponent","component","prev","ctx","hook","factory","label","currentComponent","instance","hooks","hookIndex","value","registerEffectWithComponent","c","e","stopComponentEffects","releaseKeyHandler","setGlobalKeyReleaseHandler","releaseComponentGlobals","key"],"mappings":"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","file":"chunk-WNPDQLT6.mjs","sourcesContent":["import type { ComponentInstance } from './hook'\nimport type { ReactiveEffectLike } from './lifecycle'\n\nexport interface RequestContext {\n    currentComponent: ComponentInstance | null\n    activeEffect: ReactiveEffectLike | undefined\n    effectQueue: Set<ReactiveEffectLike>\n    isFlushPending: boolean\n    isBatching: boolean\n    componentNameStack: string[]\n}\n\nfunction createDefault(): RequestContext {\n    return {\n        currentComponent: null,\n        activeEffect: undefined,\n        effectQueue: new Set(),\n        isFlushPending: false,\n        isBatching: false,\n        componentNameStack: [],\n    }\n}\n\n// Try to load AsyncLocalStorage (Node only). Use a guarded synchronous probe.\ntype ALS = {\n    run<T>(store: RequestContext, fn: () => T): T\n    getStore(): RequestContext | undefined\n}\n\nlet als: ALS | null = null\nconst fallbackContext: RequestContext = createDefault()\n\n// Detection: only load node:async_hooks under Node. Bundlers (tsup) tree-shake the\n// import path if it's behind a typeof check.\nconst isNode = typeof globalThis !== 'undefined'\n    && typeof (globalThis as { process?: { versions?: { node?: string } } }).process?.versions?.node === 'string'\n\nif (isNode) {\n    try {\n        // Use Function constructor to avoid static analysis flagging this import in browser builds.\n        // The isNode guard ensures this only ever executes in Node environments.\n        const requireFn = new Function('return require')() as ((m: string) => unknown) | undefined\n        if (requireFn) {\n            const ah = requireFn('node:async_hooks') as { AsyncLocalStorage: new () => ALS }\n            als = new ah.AsyncLocalStorage()\n        }\n    } catch {\n        // fall through — fallback context used in browser / Edge environments\n    }\n}\n\nexport function getRequestContext(): RequestContext {\n    if (als) {\n        const store = als.getStore()\n        if (store) return store\n    }\n    return fallbackContext\n}\n\nexport function runWithRequestContext<T>(fn: () => T): T {\n    if (als) {\n        return als.run(createDefault(), fn)\n    }\n    return fn()\n}\n\n/** @internal — for tests only */\nexport function __resetFallback(): void {\n    fallbackContext.currentComponent = null\n    fallbackContext.activeEffect = undefined\n    fallbackContext.effectQueue.clear()\n    fallbackContext.isFlushPending = false\n    fallbackContext.isBatching = false\n    fallbackContext.componentNameStack.length = 0\n}\n","\n// Forward type-only import to avoid circular dependency at runtime\nimport type { ReactiveEffectLike } from './lifecycle'\nimport { getRequestContext } from './request-context'\n\nexport interface ComponentInstance {\n    hooks: unknown[]\n    hookIndex: number\n    // Phase 5 hidden-class stabilization: all fields are non-optional with\n    // `null` as the unallocated sentinel. Pre-initializing every slot in the\n    // constructor literal locks the V8 hidden class so all ComponentInstance\n    // objects share one IC entry, instead of transitioning through 4-7 hidden\n    // classes as fields were lazy-added (effects, globalKeys, hookSignatures).\n    hookSignatures: string[] | null\n    prevHookSignatures: string[] | null\n    componentName: string | null\n    /** Effects registered by unsafeEffect() inside this component's render. Stopped on unmount. */\n    effects: ReactiveEffectLike[] | null\n    /** Global registry keys held by this component instance. Decremented on unmount. */\n    globalKeys: string[] | null\n}\n\n// Phase 6A: module-scope currentComponent fast-path (browser only).\n// In SSR, concurrent requests need AsyncLocalStorage isolation — we must\n// NOT use a shared module-scope slot there. Detection is done once at\n// module init so the resolver branch is never hit at call time.\n//\n// Window-shimmed SSR environments (Next.js Edge, Deno --unstable-window,\n// some test runners) define `window` but not `document`. Requiring BOTH\n// globals here keeps us strictly browser-only so SSR cross-request\n// contamination is impossible.\nconst _isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined'\n\n/** Browser-only fast-path: direct module-scope slot, zero function call. */\nlet _browserCurrentComponent: ComponentInstance | null = null\n\nexport function getComponent(): ComponentInstance | null {\n    if (_isBrowser) {\n        return _browserCurrentComponent\n    }\n    return getRequestContext().currentComponent\n}\n\nexport function runWithComponent<T>(component: ComponentInstance, fn: () => T): T {\n    let prev: ComponentInstance | null\n    if (_isBrowser) {\n        prev = _browserCurrentComponent\n        _browserCurrentComponent = component\n    } else {\n        const ctx = getRequestContext()\n        prev = ctx.currentComponent\n        ctx.currentComponent = component\n    }\n    component.hookIndex = 0\n    if (import.meta.env.DEV) {\n        component.prevHookSignatures = component.hookSignatures\n        component.hookSignatures = []\n    }\n    try {\n        return fn()\n    } finally {\n        if (import.meta.env.DEV) {\n            checkHookOrder(component)\n        }\n        if (_isBrowser) {\n            _browserCurrentComponent = prev\n        } else {\n            getRequestContext().currentComponent = prev\n        }\n    }\n}\n\nexport function hook<T>(factory: () => T, label?: string): T {\n    const currentComponent = _isBrowser\n        ? _browserCurrentComponent\n        : getRequestContext().currentComponent\n    if (!currentComponent) {\n        // Outside component: just run factory\n        return factory()\n    }\n\n    const instance = currentComponent\n    const { hooks, hookIndex } = instance\n\n    if (import.meta.env.DEV) {\n        instance.hookSignatures!.push(label ?? factory.name ?? 'use')\n    }\n\n    if (hookIndex < hooks.length) {\n        // Return existing hook\n        instance.hookIndex++\n        return hooks[hookIndex] as T\n    }\n\n    // Create new hook\n    const value = factory()\n    hooks.push(value)\n    instance.hookIndex++\n\n    return value\n}\n\nfunction checkHookOrder(c: ComponentInstance) {\n    if (!c.prevHookSignatures || !c.hookSignatures) return\n    const prev = c.prevHookSignatures\n    const curr = c.hookSignatures\n    const name = c.componentName ?? 'Component'\n    if (prev.length !== curr.length) {\n        console.warn(\n            `[flexium] Hook order changed in ${name}: previous render had ${prev.length} hooks, this render has ${curr.length}. ` +\n            `Hooks must be called in the same order every render.`\n        )\n        return\n    }\n    for (let i = 0; i < curr.length; i++) {\n        if (prev[i] !== curr[i]) {\n            console.warn(\n                `[flexium] Hook order mismatch at index ${i} in ${name}: previous \"${prev[i]}\", this render \"${curr[i]}\".`\n            )\n            return\n        }\n    }\n}\n\n/**\n * Register a reactive effect with the currently rendering component instance so it\n * will be stopped when the component is unmounted.\n */\nexport function registerEffectWithComponent(c: ComponentInstance, e: ReactiveEffectLike) {\n    if (!c.effects) c.effects = []\n    c.effects.push(e)\n}\n\n/**\n * Stop and clear all effects that were registered with the given component instance.\n * Called during component unmount.\n */\nexport function stopComponentEffects(c: ComponentInstance) {\n    if (c.effects) {\n        for (const e of c.effects) e.stop()\n        c.effects.length = 0\n    }\n}\n\n// ---------------------------------------------------------------------------\n// Global registry release handler — late-bound to avoid circular imports.\n// use.ts calls setGlobalKeyReleaseHandler() at module-init time to register\n// the actual implementation; hook.ts never imports from use.ts.\n// ---------------------------------------------------------------------------\n\nlet releaseKeyHandler: ((key: string) => void) | null = null\n\n/**\n * Called by use.ts at module initialization to register the globalRegistry\n * release function without creating a circular import.\n */\nexport function setGlobalKeyReleaseHandler(fn: (key: string) => void): void {\n    releaseKeyHandler = fn\n}\n\n/**\n * Decrement the refCount for every global registry key held by this component\n * and evict any entry whose refCount reaches zero.\n * Called during component unmount, alongside stopComponentEffects().\n */\nexport function releaseComponentGlobals(c: ComponentInstance): void {\n    if (c.globalKeys && releaseKeyHandler) {\n        for (const key of c.globalKeys) releaseKeyHandler(key)\n        c.globalKeys.length = 0\n    }\n}\n"]}