{"version":3,"file":"plus.cjs","names":[],"sources":["../src/resource.ts","../src/lazy.ts"],"sourcesContent":["/**\n * @fileoverview Async data fetching with caching and Suspense support.\n *\n * The `resource` function creates a reactive data fetcher that:\n * - Cancels no-cache requests when their last owner leaves\n * - Supports Suspense for loading states\n * - Provides caching with TTL and stale-while-revalidate\n * - Handles errors gracefully\n */\n\nimport { createEffect, onCleanup, untrack } from '@fictjs/runtime'\nimport { createSignal, isReactive } from '@fictjs/runtime/advanced'\nimport {\n  __fictGetCurrentSSRSession,\n  __fictIsSSRSessionActive,\n  __fictCreateAsyncSource,\n  __fictIsAsyncConsumer,\n  __fictOwnSuspenseToken,\n  type AsyncSource,\n} from '@fictjs/runtime/internal'\n\n/**\n * The result of reading a resource.\n *\n * @typeParam T - The type of data returned by the fetcher\n */\nexport interface ResourceResult<T> {\n  /** The fetched data, or undefined if not yet loaded or on error */\n  readonly data: T | undefined\n  /** Whether the resource is currently loading (initial fetch or refetch) */\n  readonly loading: boolean\n  /**\n   * Any error that occurred during fetching.\n   * Type is unknown since errors can be any value in JavaScript.\n   */\n  readonly error: unknown\n  /** Manually trigger a refetch of the resource */\n  refresh: () => void\n}\n\n/**\n * Cache configuration options for a resource.\n */\nexport interface ResourceCacheOptions {\n  /**\n   * Caching mode:\n   * - `'memory'`: Cache responses in memory (default)\n   * - `'none'`: No persistent cache; active readers and Suspense retries share work\n   * @default 'memory'\n   */\n  mode?: 'memory' | 'none'\n\n  /**\n   * Memory-cache scope during server-side rendering:\n   * - `'request'`: Isolate entries to the active SSR request (default)\n   * - `'shared'`: Share entries across SSR requests for explicitly public data\n   *\n   * In the browser, memory caching remains scoped to the resource instance.\n   * @default 'request'\n   */\n  scope?: 'request' | 'shared'\n\n  /**\n   * Time-to-live in milliseconds before cached data is considered stale.\n   * @default Infinity\n   */\n  ttlMs?: number\n\n  /**\n   * If true, return stale cached data immediately while refetching in background.\n   * @default false\n   */\n  staleWhileRevalidate?: boolean\n\n  /**\n   * If true, cache error responses as well.\n   * @default false\n   */\n  cacheErrors?: boolean\n\n  /**\n   * Maximum number of cached entries. Least-recently-used entries beyond\n   * this bound are evicted (in-flight entries are never evicted).\n   * @default 256\n   */\n  maxEntries?: number\n}\n\n/**\n * Configuration options for creating a resource.\n *\n * @typeParam T - The type of data returned by the fetcher\n * @typeParam Args - The type of arguments passed to the fetcher\n */\nexport interface ResourceOptions<T, Args> {\n  /**\n   * Custom cache key. Can be a static value or a function that computes\n   * the key from the args. If not provided, args are used as the key.\n   */\n  key?: unknown | ((args: Args) => unknown)\n\n  /**\n   * The fetcher function that performs the async data retrieval.\n   * Receives an AbortController signal for cancellation support.\n   */\n  fetch: (ctx: { signal: AbortSignal }, args: Args) => Promise<T>\n\n  /**\n   * If true, the resource will throw a Suspense token while loading,\n   * enabling React-like Suspense boundaries.\n   * @default false\n   */\n  suspense?: boolean\n\n  /**\n   * Cache configuration options.\n   */\n  cache?: ResourceCacheOptions\n\n  /**\n   * A value or explicitly marked reactive getter that, when changed, resets the resource.\n   * Useful for clearing cache when certain conditions change.\n   */\n  reset?: unknown | (() => unknown)\n}\n\n/**\n * Return type of the resource factory.\n *\n * @typeParam T - The type of data returned by the fetcher\n * @typeParam Args - The type of arguments passed to the fetcher\n */\nexport interface Resource<T, Args> {\n  /**\n   * Read the resource data, triggering a fetch if needed.\n   * Can accept static args or an explicitly marked reactive getter.\n   *\n   * @param argsAccessor - Arguments or an explicitly marked getter returning arguments\n   */\n  read(argsAccessor: (() => Args) | Args): ResourceResult<T>\n\n  /**\n   * Invalidate cached data, causing the next read to refetch.\n   *\n   * @param key - Optional specific key to invalidate. If omitted, invalidates all.\n   */\n  invalidate(key?: unknown): void\n\n  /**\n   * Prefetch data without reading it. Useful for eager loading.\n   *\n   * @param args - Arguments to pass to the fetcher\n   * @param keyOverride - Optional cache key override\n   */\n  prefetch(args: Args, keyOverride?: unknown): void\n\n  /**\n   * Optimistically update cached data for a given args/key.\n   *\n   * @param argsAccessor - Arguments or an explicitly marked getter returning arguments\n   * @param value - New value or updater function\n   * @param options - Optional settings (key override, revalidate)\n   */\n  mutate(\n    argsAccessor: (() => Args) | Args,\n    value: T | ((prev: T | undefined) => T),\n    options?: { key?: unknown; revalidate?: boolean },\n  ): void\n}\n\n/**\n * Resource status values for tracking fetch lifecycle.\n * @internal\n */\nexport type ResourceStatus = 'idle' | 'pending' | 'success' | 'error'\n\n/**\n * Internal cache entry for a resource.\n * Tracks the reactive state and metadata for a single cached fetch.\n *\n * @typeParam T - The type of data returned by the fetcher\n * @typeParam Args - The type of arguments passed to the fetcher\n * @internal\n */\ninterface ResourceEntry<T, Args> {\n  /** Async graph state; cache policy owns its transport and lifetime. */\n  source: AsyncSource<T>\n  /** No-cache work is owned by readers, prefetches and suspended replay. */\n  retain?: () => () => void\n  /** Suspended setup retries retain resolved values until the boundary commits. */\n  replayOwners: number\n  dataProjection?: () => T | undefined\n  loadingProjection?: () => boolean\n  errorProjection?: () => unknown\n  /** Cache invalidation is a policy input, separate from async readiness. */\n  version: ReturnType<typeof createSignal<number>>\n  /** SWR deliberately suppresses loading while a previous value is shown. */\n  revalidating: boolean\n  /** Compatibility facade for synchronous setup reads using legacy replay. */\n  legacyPending: { generation: number; token: PromiseLike<void> } | undefined\n  /** Last used arguments for change detection */\n  lastArgs: Args | undefined\n  /** Last seen version for change detection */\n  lastVersion: number\n  /** Last reset token value for change detection */\n  lastReset: unknown\n  /** Timestamp when the cached value expires */\n  expiresAt: number | undefined\n  /** Currently in-flight fetch promise */\n  inFlight: Promise<void> | undefined\n  /** Args used for the current in-flight request */\n  inFlightArgs: Args | undefined\n  /** AbortController for cancelling in-flight requests */\n  controller: AbortController | undefined\n}\n\nconst defaultCacheOptions: Required<ResourceCacheOptions> = {\n  mode: 'memory',\n  scope: 'request',\n  ttlMs: Number.POSITIVE_INFINITY,\n  staleWhileRevalidate: false,\n  cacheErrors: false,\n  maxEntries: 256,\n}\n\nconst STRUCTURAL_KEY_PREFIX = '\\u0000fict:args:'\n\n/**\n * Deterministic serialization for plain-data args (sorted object keys).\n * Throws on cycles and non-plain objects so the caller can fall back to\n * identity keying.\n */\nfunction stableStringify(value: unknown, seen: WeakSet<object>): string {\n  if (value === null) return 'null'\n  if (value === undefined) return 'undefined'\n  if (typeof value === 'boolean') return value ? 'boolean:true' : 'boolean:false'\n  if (typeof value === 'string') return `string:${JSON.stringify(value)}`\n  if (typeof value === 'bigint') return `bigint:${value.toString()}`\n  if (typeof value === 'number') {\n    if (Number.isNaN(value)) return 'number:NaN'\n    if (Object.is(value, -0)) return 'number:-0'\n    if (value === Number.POSITIVE_INFINITY) return 'number:+Infinity'\n    if (value === Number.NEGATIVE_INFINITY) return 'number:-Infinity'\n    return `number:${String(value)}`\n  }\n  if (typeof value !== 'object') {\n    throw new Error('non-serializable')\n  }\n  if (seen.has(value)) throw new Error('cyclic')\n  seen.add(value)\n  try {\n    if (Object.getOwnPropertySymbols(value).length > 0) {\n      throw new Error('non-serializable')\n    }\n    if (Array.isArray(value)) {\n      const arrayKeys = Object.keys(value)\n      if (\n        arrayKeys.some(key => {\n          const index = Number(key)\n          return (\n            !Number.isInteger(index) || index < 0 || index >= value.length || String(index) !== key\n          )\n        })\n      ) {\n        throw new Error('non-serializable')\n      }\n      const items: string[] = []\n      for (let i = 0; i < value.length; i++) {\n        items.push(\n          Object.prototype.hasOwnProperty.call(value, i)\n            ? stableStringify(value[i], seen)\n            : 'array-hole',\n        )\n      }\n      return `array:[${items.join(',')}]`\n    }\n    const proto = Object.getPrototypeOf(value)\n    if (proto !== Object.prototype && proto !== null) throw new Error('non-plain')\n    const keys = Object.keys(value).sort()\n    return (\n      (proto === null ? 'null-object:{' : 'object:{') +\n      keys\n        .map(\n          key =>\n            JSON.stringify(key) +\n            ':' +\n            stableStringify((value as Record<string, unknown>)[key], seen),\n        )\n        .join(',') +\n      '}'\n    )\n  } finally {\n    seen.delete(value)\n  }\n}\n\n/**\n * Derive a stable cache key for default (key-less) resources. Plain data\n * objects with equal contents share a key, so fresh `{ id }` literals hit\n * the cache instead of growing it; non-plain or cyclic args fall back to\n * identity keying.\n */\nfunction structuralArgsKey(argsValue: unknown): unknown {\n  try {\n    return STRUCTURAL_KEY_PREFIX + stableStringify(argsValue, new WeakSet())\n  } catch {\n    return argsValue\n  }\n}\n\n/**\n * Create a reactive async data resource.\n *\n * Resources handle async data fetching with automatic caching, cancellation,\n * and optional Suspense integration.\n *\n * @param optionsOrFetcher - A fetcher function or full configuration object\n * @returns A resource factory with read, invalidate, and prefetch methods\n *\n * @example\n * ```tsx\n * import { reactive } from 'fict/advanced'\n * import { resource } from 'fict/plus'\n *\n * // Simple fetcher\n * const userResource = resource(\n *   ({ signal }, userId: string) =>\n *     fetch(`/api/users/${userId}`, { signal }).then(r => r.json())\n * )\n *\n * // With full options\n * const postsResource = resource({\n *   fetch: ({ signal }, userId: string) =>\n *     fetch(`/api/users/${userId}/posts`, { signal }).then(r => r.json()),\n *   suspense: true,\n *   cache: {\n *     ttlMs: 60_000,\n *     staleWhileRevalidate: true,\n *   },\n * })\n *\n * // Usage in component\n * function UserProfile({ userId }: { userId: string }) {\n *   const { data, loading, error, refresh } = userResource.read(reactive(() => userId))\n *\n *   if (loading) return <Spinner />\n *   if (error) return <ErrorMessage error={error} />\n *   return <div>{data.name}</div>\n * }\n * ```\n *\n * @public\n */\nexport function resource<T, Args = void>(\n  optionsOrFetcher:\n    | ((ctx: { signal: AbortSignal }, args: Args) => Promise<T>)\n    | ResourceOptions<T, Args>,\n): Resource<T, Args> {\n  const fetcher = typeof optionsOrFetcher === 'function' ? optionsOrFetcher : optionsOrFetcher.fetch\n  const useSuspense = typeof optionsOrFetcher === 'object' && !!optionsOrFetcher.suspense\n  const cacheOptions: ResourceCacheOptions =\n    typeof optionsOrFetcher === 'object' ? (optionsOrFetcher.cache ?? {}) : {}\n  const resolvedCacheOptions = { ...defaultCacheOptions, ...cacheOptions }\n  type Cache = Map<unknown, ResourceEntry<T, Args>>\n  type SSRSession = NonNullable<ReturnType<typeof __fictGetCurrentSSRSession>>\n\n  const sharedCache: Cache = new Map()\n  const requestCaches = new WeakMap<SSRSession, Cache>()\n\n  const resolveCache = (): Cache => {\n    const session = __fictGetCurrentSSRSession()\n    if (resolvedCacheOptions.scope === 'shared') {\n      return sharedCache\n    }\n\n    if (!session) {\n      // An active SSR render without a visible session means its async carrier\n      // was lost or is unavailable (for example in an edge fallback). Never\n      // fall back to process-wide memory for the default request scope.\n      return __fictIsSSRSessionActive() ? new Map() : sharedCache\n    }\n\n    let requestCache = requestCaches.get(session)\n    if (!requestCache) {\n      requestCache = new Map()\n      requestCaches.set(session, requestCache)\n    }\n    return requestCache\n  }\n\n  const readArgs = (argsAccessor: (() => Args) | Args): Args =>\n    isReactive(argsAccessor) ? (argsAccessor as () => Args)() : (argsAccessor as Args)\n\n  const hasCustomKey = typeof optionsOrFetcher === 'object' && optionsOrFetcher.key !== undefined\n\n  const computeKey = (argsAccessor: (() => Args) | Args): unknown => {\n    const argsValue = readArgs(argsAccessor)\n    if (hasCustomKey) {\n      const key = (optionsOrFetcher as ResourceOptions<T, Args>).key\n      return structuralArgsKey(\n        typeof key === 'function' ? (key as (args: Args) => unknown)(argsValue) : key,\n      )\n    }\n    return structuralArgsKey(argsValue)\n  }\n\n  const readResetToken = (): unknown => {\n    if (typeof optionsOrFetcher !== 'object') return undefined\n    const reset = optionsOrFetcher.reset\n    if (isReactive(reset)) {\n      return (reset as () => unknown)()\n    }\n    return reset\n  }\n\n  const evictOverflowEntries = (cache: Cache, protectedEntry?: ResourceEntry<T, Args>) => {\n    const maxEntries = resolvedCacheOptions.maxEntries\n    if (!Number.isFinite(maxEntries) || maxEntries <= 0) return\n    if (cache.size <= maxEntries) return\n    for (const [entryKey, entry] of cache) {\n      if (cache.size <= maxEntries) break\n      // Never evict entries with work in progress.\n      if (entry === protectedEntry || entry.inFlight) continue\n      cache.delete(entryKey)\n      // Settled entries have no transport or upstream subscriptions to release.\n      // Existing readers still own their snapshot, including a cached error;\n      // removing lookup ownership must not turn that snapshot into disposed data.\n    }\n  }\n\n  const ensureEntry = (cache: Cache, key: unknown): ResourceEntry<T, Args> => {\n    let state = cache.get(key)\n    if (state) {\n      // Refresh recency so eviction drops the least-recently-used entries.\n      cache.delete(key)\n      cache.set(key, state)\n      return state\n    }\n    state = {\n      source: __fictCreateAsyncSource<T>(),\n      replayOwners: 0,\n      version: createSignal(0),\n      revalidating: false,\n      legacyPending: undefined,\n      lastArgs: undefined,\n      lastVersion: -1,\n      lastReset: undefined,\n      expiresAt: undefined,\n      inFlight: undefined,\n      inFlightArgs: undefined,\n      controller: undefined,\n    }\n    if (resolvedCacheOptions.mode === 'none') {\n      const entry = state\n      let owners = 0\n      entry.retain = () => {\n        owners++\n        let released = false\n        return () => {\n          if (released) return\n          released = true\n          if (--owners) return\n          // An abort listener may synchronously start a new reader for this key.\n          // Remove lookup ownership before invoking user transport callbacks.\n          if (cache.get(key) === entry) cache.delete(key)\n          try {\n            entry.controller?.abort()\n          } finally {\n            entry.source.dispose()\n          }\n        }\n      }\n    }\n    cache.set(key, state)\n    // The caller may start work on this new entry immediately after return.\n    // Do not evict it in the brief interval before inFlight is assigned.\n    evictOverflowEntries(cache, state)\n    return state\n  }\n\n  const isExpired = (entry: ResourceEntry<T, Args>): boolean => {\n    if (resolvedCacheOptions.mode === 'none') return true\n    if (!Number.isFinite(resolvedCacheOptions.ttlMs)) return false\n    if (entry.expiresAt === undefined) return false\n    return entry.expiresAt <= Date.now()\n  }\n\n  const markExpiry = (entry: ResourceEntry<T, Args>) => {\n    if (resolvedCacheOptions.mode === 'none') {\n      entry.expiresAt = Date.now() - 1\n      return\n    }\n    entry.expiresAt = Number.isFinite(resolvedCacheOptions.ttlMs)\n      ? Date.now() + resolvedCacheOptions.ttlMs\n      : undefined\n  }\n\n  const hasData = (entry: ResourceEntry<T, Args>) => {\n    const state = entry.source.peek()\n    return state.hasValue && state.status !== 'errored'\n  }\n\n  const legacyToken = (entry: ResourceEntry<T, Args>): PromiseLike<void> => {\n    const snapshot = entry.source.peek()\n    if (!snapshot.pending) throw new Error('[fict] Resource has no pending generation.')\n    if (entry.legacyPending?.generation === snapshot.generation) return entry.legacyPending.token\n    const pending = snapshot.pending\n    // This adapter is allocated only for legacy setup reads. The graph's token\n    // never rejects; legacy Suspense expects an error delivered to its handler.\n    const token: PromiseLike<void> = {\n      then: (resolve, reject) =>\n        pending\n          .then(() => {\n            const current = entry.source.peek()\n            if (current.generation === snapshot.generation && current.status === 'errored')\n              throw current.error\n          })\n          .then(resolve, reject),\n    }\n    entry.legacyPending = { generation: snapshot.generation, token }\n    if (entry.retain) {\n      const retain = entry.retain\n      __fictOwnSuspenseToken(token, () => {\n        const release = retain()\n        entry.replayOwners++\n        let released = false\n        return () => {\n          if (released) return\n          released = true\n          entry.replayOwners--\n          release()\n        }\n      })\n    }\n    return token\n  }\n\n  const startFetch = (\n    cache: Cache,\n    entry: ResourceEntry<T, Args>,\n    args: Args,\n    options: { isRevalidating?: boolean; clearValue?: boolean } = {},\n  ) => {\n    const isRevalidating = options.isRevalidating === true\n    // The entry is keyed by request identity, so any in-flight fetch already\n    // serves these args - reuse it instead of abort/restart churn. Callers\n    // that genuinely need a fresh fetch (refresh, mutate) abort explicitly\n    // before calling startFetch.\n    if (entry.inFlight) return\n    entry.controller?.abort()\n    entry.inFlight = undefined\n    const controller = new AbortController()\n    entry.controller = controller\n    entry.revalidating = isRevalidating\n    const currentGen = entry.source.begin(!options.clearValue)\n    entry.legacyPending = undefined\n\n    let request: Promise<T>\n    try {\n      request = Promise.resolve(fetcher({ signal: controller.signal }, args))\n    } catch (err) {\n      request = Promise.reject(err)\n    }\n\n    const fetchPromise = request\n      .then(res => {\n        if (controller.signal.aborted || entry.source.peek().generation !== currentGen) return\n        markExpiry(entry)\n        entry.source.resolve(currentGen, res)\n      })\n      .catch(err => {\n        if (controller.signal.aborted || entry.source.peek().generation !== currentGen) return\n        if (resolvedCacheOptions.cacheErrors) markExpiry(entry)\n        else entry.expiresAt = Date.now() - 1\n        entry.source.reject(currentGen, err)\n      })\n      .finally(() => {\n        if (entry.source.peek().generation !== currentGen || entry.inFlight !== fetchPromise) return\n        entry.inFlight = undefined\n        entry.inFlightArgs = undefined\n        if (entry.controller === controller) {\n          entry.controller = undefined\n        }\n        // A full cache may temporarily retain in-flight entries. Re-apply the\n        // bound once work settles so concurrent prefetches cannot leave it\n        // permanently above maxEntries.\n        evictOverflowEntries(cache)\n      })\n\n    entry.inFlight = fetchPromise\n    entry.inFlightArgs = args\n  }\n\n  const invalidate = (key?: unknown) => {\n    const cache = resolveCache()\n    if (key === undefined) {\n      cache.forEach(entry => {\n        entry.controller?.abort()\n        entry.source.dispose()\n        entry.version(entry.version() + 1)\n        entry.expiresAt = Date.now() - 1\n      })\n      cache.clear()\n      return\n    }\n    const normalizedKey = structuralArgsKey(key)\n    const entry = cache.get(normalizedKey)\n    if (entry) {\n      entry.controller?.abort()\n      entry.source.dispose()\n      entry.version(entry.version() + 1)\n      entry.expiresAt = Date.now() - 1\n      cache.delete(normalizedKey)\n    }\n  }\n\n  function prefetch(args: Args, keyOverride?: unknown) {\n    const cache = resolveCache()\n    const hasKeyOverride = arguments.length >= 2\n    const key = hasKeyOverride ? structuralArgsKey(keyOverride) : computeKey(args)\n    const entry = ensureEntry(cache, key)\n    const usableData = hasData(entry) && !isExpired(entry)\n    if (!usableData) {\n      entry.lastArgs = args\n      entry.lastVersion = entry.version()\n      const release = entry.retain?.()\n      if (release) onCleanup(release)\n      startFetch(cache, entry, args)\n      if (release) void entry.inFlight?.then(release, release)\n    }\n  }\n\n  const mutate = (\n    argsAccessor: (() => Args) | Args,\n    value: T | ((prev: T | undefined) => T),\n    options?: { key?: unknown; revalidate?: boolean },\n  ) => {\n    const cache = resolveCache()\n    const args = readArgs(argsAccessor)\n    const hasKeyOverride = !!options && Object.prototype.hasOwnProperty.call(options, 'key')\n    const key = hasKeyOverride ? structuralArgsKey(options.key) : computeKey(args)\n    const entry = ensureEntry(cache, key)\n    const previous = entry.source.peek()\n    const prevValue =\n      previous.hasValue && previous.status !== 'errored' ? previous.value : undefined\n    const nextValue =\n      typeof value === 'function' ? (value as (prev: T | undefined) => T)(prevValue) : value\n\n    entry.controller?.abort()\n    entry.inFlight = undefined\n    entry.inFlightArgs = undefined\n    const generation = entry.source.begin()\n    entry.revalidating = false\n    entry.source.resolve(generation, nextValue)\n    markExpiry(entry)\n    entry.lastArgs = args\n    entry.lastVersion = entry.version()\n\n    if (options?.revalidate) {\n      entry.version(entry.version() + 1)\n    }\n  }\n\n  return {\n    read(argsAccessor: (() => Args) | Args): ResourceResult<T> {\n      // Capture the active request cache once. Reactive re-runs may happen\n      // after the synchronous SSR session stack has unwound, but they still\n      // belong to the request that created this read.\n      const cache = resolveCache()\n      const entryRef = createSignal<ResourceEntry<T, Args> | null>(null)\n\n      createEffect(() => {\n        const key = computeKey(argsAccessor)\n        const entry = ensureEntry(cache, key)\n        const release = entry.retain?.()\n        if (release) onCleanup(release)\n        entryRef(entry)\n        const args = readArgs(argsAccessor)\n        const currentVersion = entry.version()\n        // Legacy setup retries keep their resolved request values until the\n        // whole boundary commits, including waterfalls of pending reads.\n        const expired = isExpired(entry) && !(entry.replayOwners && hasData(entry))\n        // The cache key is the request identity: a fresh args object that maps\n        // to the same key is the same request, so default-keyed resources never\n        // treat it as a change. Custom-keyed resources can see different args\n        // under one key; compare those structurally, not by reference.\n        const state = entry.source.peek()\n        const neverFetched = state.status === 'uninitialized' && !entry.inFlight\n        const argsChanged = hasCustomKey\n          ? structuralArgsKey(args) !== structuralArgsKey(entry.lastArgs)\n          : false\n        const versionChanged = entry.lastVersion !== currentVersion\n        const resetToken = readResetToken()\n        const resetChanged = entry.lastReset !== resetToken\n        // For stale-while-revalidate: if we have cached data, don't treat expired as requiring immediate refetch\n        // We'll handle the revalidation separately to show stale data without loading state\n        const canUseStaleData =\n          resolvedCacheOptions.staleWhileRevalidate && hasData(entry) && expired\n        const shouldRefetch =\n          neverFetched ||\n          (expired && !canUseStaleData) ||\n          argsChanged ||\n          versionChanged ||\n          resetChanged ||\n          (state.status === 'errored' && !resolvedCacheOptions.cacheErrors)\n\n        entry.lastArgs = args\n        entry.lastVersion = currentVersion\n        entry.lastReset = resetToken\n\n        if (shouldRefetch) {\n          if (entry.inFlight && (argsChanged || versionChanged || resetChanged)) {\n            entry.controller?.abort()\n            entry.inFlight = undefined\n          }\n          if (resetChanged) {\n            entry.expiresAt = Date.now() - 1\n          }\n          startFetch(cache, entry, args as Args, { clearValue: resetChanged })\n        } else if (canUseStaleData && entry.inFlight === undefined) {\n          // stale-while-revalidate: return stale data immediately, refresh in background\n          // Pass isRevalidating=true to avoid showing loading state\n          startFetch(cache, entry, args as Args, { isRevalidating: true })\n        }\n        const releaseTransition = entry.source.trackTransitions()\n        if (releaseTransition) onCleanup(releaseTransition)\n      })\n\n      // Commit the initial reference even when its first read happens during\n      // cleanup, where signals correctly expose stored rather than pending data.\n      untrack(() => entryRef())\n\n      return {\n        get data() {\n          const entry = entryRef()\n          if (!entry) return undefined\n          const reactiveConsumer = __fictIsAsyncConsumer()\n          entry.dataProjection ??= entry.source.derive(() => {\n            const state = entry.source.state()\n            if (\n              useSuspense &&\n              (!state.hasValue || state.status === 'errored') &&\n              (state.pending || state.status === 'errored')\n            )\n              return entry.source.read()\n            return state.hasValue && state.status !== 'errored' ? state.value : undefined\n          })\n          try {\n            return entry.dataProjection()\n          } catch (error) {\n            const state = entry.source.peek()\n            if (!reactiveConsumer) {\n              if (state.pending) throw legacyToken(entry)\n              if (state.status === 'errored') return undefined\n            }\n            throw error\n          }\n        },\n        get loading() {\n          const entry = entryRef()\n          if (!entry) return false\n          entry.loadingProjection ??= entry.source.derive(\n            () => !!entry.source.state().pending && !entry.revalidating,\n          )\n          return entry.loadingProjection()\n        },\n        get error() {\n          const entry = entryRef()\n          if (!entry) return undefined\n          entry.errorProjection ??= entry.source.derive(() => {\n            const state = entry.source.state()\n            return state.status === 'errored' ? state.error : undefined\n          })\n          return entry.errorProjection()\n        },\n        refresh: () => {\n          const entry = entryRef()\n          if (entry) entry.version(entry.version() + 1)\n        },\n      }\n    },\n    invalidate,\n    prefetch,\n    mutate,\n  }\n}\n","/**\n * @fileoverview Lazy component loading with Suspense support.\n *\n * The implementation lives in the runtime's first-party internal protocol so\n * framework and router lazy components share preload, reset, retry, and\n * Suspense semantics.\n */\n\nimport type { Component } from '@fictjs/runtime'\nimport { __fictCreateLazyComponent } from '@fictjs/runtime/internal'\n\n/** Module shape produced by a typical dynamic import. */\nexport interface LazyModule<TProps extends Record<string, unknown>> {\n  default: Component<TProps>\n}\n\n/** Options for lazy loading behavior. */\nexport interface LazyOptions {\n  /** Maximum retry attempts after the initial load. Defaults to `0`. */\n  maxRetries?: number\n  /** Initial exponential-backoff delay in milliseconds. Defaults to `1000`. */\n  retryDelay?: number\n}\n\n/** Component with explicit preload and retry-reset controls. */\nexport interface LazyComponent<TProps extends Record<string, unknown>> extends Component<TProps> {\n  /** Clear a cached failure so the next render or preload starts a new load. */\n  reset: () => void\n  /** Load the component without rendering it. */\n  preload: () => Promise<void>\n}\n\n/**\n * Create a lazy component that suspends while loading.\n *\n * The loader may resolve to a dynamic-import module or directly to a\n * component. Failed loads stay observable until `reset()` is called; optional\n * automatic retries use exponential backoff.\n *\n * @example\n * ```tsx\n * const LazyDashboard = lazy(() => import('./Dashboard'), {\n *   maxRetries: 2,\n *   retryDelay: 250,\n * })\n * ```\n *\n * @public\n */\nexport function lazy<TProps extends Record<string, unknown> = Record<string, unknown>>(\n  loader: () => Promise<LazyModule<TProps> | Component<TProps>>,\n  options: LazyOptions = {},\n): LazyComponent<TProps> {\n  return __fictCreateLazyComponent(loader, options)\n}\n"],"mappings":"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"}