{"version":3,"file":"react.cjs","names":["interval: ReturnType<typeof setInterval> | null","realtimeSubscribe"],"sources":["../src/react.ts"],"sourcesContent":["import { useEffect, useRef, useState } from \"react\";\nimport type { Inngest } from \"./components/Inngest.ts\";\nimport {\n  getClientSubscriptionToken,\n  subscribe as realtimeSubscribe,\n} from \"./components/realtime/subscribe/index.ts\";\nimport type { Realtime } from \"./components/realtime/types.ts\";\n\nexport type UseRealtimeConnectionStatus =\n  | \"idle\"\n  | \"connecting\"\n  | \"open\"\n  | \"paused\"\n  | \"closed\"\n  | \"error\";\n\nexport type UseRealtimeRunStatus =\n  | \"unknown\"\n  | \"running\"\n  | \"completed\"\n  | \"failed\"\n  | \"cancelled\";\n\nexport type ClientSubscriptionToken = Realtime.Subscribe.ClientToken;\n\ntype TokenFactory = () => Promise<\n  string | ClientSubscriptionToken | Realtime.Subscribe.Token\n>;\ntype UseRealtimePauseReason = \"hidden\" | \"disabled\" | null;\n\n//\n// Extract the topic configs map from a channel input. Returns the full\n// TopicsConfig when the channel is a typed ChannelInstance, otherwise\n// falls back to a broad Record<string, TopicConfig> so data is untyped.\ntype InferTopicConfigs<TChannel extends Realtime.ChannelInput> =\n  TChannel extends Realtime.ChannelInstance<string, infer TTopicConfigs>\n    ? TTopicConfigs\n    : Record<string, Realtime.TopicConfig>;\n\n//\n// Produce the per-topic typed message for a single topic key. When the\n// channel is a typed ChannelInstance and the key matches a known topic,\n// the `data` field is typed to that topic's schema. Otherwise falls\n// back to untyped Realtime.Message.\ntype TopicLatestMessage<\n  TChannel extends Realtime.ChannelInput,\n  TKey extends string,\n  TConfigs = InferTopicConfigs<TChannel>,\n> = TKey extends keyof TConfigs\n  ? Extract<\n      Realtime.Message<string, Pick<TConfigs, TKey & keyof TConfigs>>,\n      { topic: TKey }\n    >\n  : Realtime.Message;\n\n//\n// Map of topic name → last message with per-topic typed data.\n// Falls back to bare Realtime.Message when the channel is a plain string.\ntype MessagesByTopicMap<\n  TChannel extends Realtime.ChannelInput,\n  TTopics extends readonly string[] | undefined,\n> = TTopics extends readonly (infer K extends string)[]\n  ? { [P in K]?: TopicLatestMessage<TChannel, P> }\n  : Record<string, Realtime.Message | undefined>;\n\n//\n// Discriminated union of all messages across subscribed topics. Used for\n// message collections where the user narrows by\n// `msg.topic` to get per-topic typing.\ntype SubscribedMessage<\n  TChannel extends Realtime.ChannelInput,\n  TTopics extends readonly string[] | undefined,\n> = TTopics extends readonly (infer K extends string)[]\n  ? Realtime.Message<\n      string,\n      Pick<InferTopicConfigs<TChannel>, K & keyof InferTopicConfigs<TChannel>>\n    >\n  : Realtime.Message;\n\nexport interface UseRealtimeResult<\n  TChannel extends Realtime.ChannelInput = Realtime.ChannelInput,\n  TTopics extends readonly string[] | undefined = readonly string[] | undefined,\n> {\n  connectionStatus: UseRealtimeConnectionStatus;\n  runStatus: UseRealtimeRunStatus;\n  isPaused: boolean;\n  pauseReason: UseRealtimePauseReason;\n\n  messages: {\n    byTopic: MessagesByTopicMap<TChannel, TTopics>;\n    all: SubscribedMessage<TChannel, TTopics>[];\n    last: SubscribedMessage<TChannel, TTopics> | null;\n    delta: SubscribedMessage<TChannel, TTopics>[];\n  };\n\n  result: unknown;\n  error: Error | null;\n  reset: () => void;\n}\n\nexport interface UseRealtimeOptions<\n  TChannel extends Realtime.ChannelInput = Realtime.ChannelInput,\n  TTopics extends readonly string[] | undefined = readonly string[] | undefined,\n> {\n  //\n  // Spec-style inputs. If `token` is a function and returns a string, both\n  // `channel` and `topics` are required so the hook can construct a token object.\n  channel?: TChannel;\n  topics?: TTopics;\n\n  //\n  // Either a pre-minted subscription token or a token factory that returns\n  // a token key string, a client token from\n  // `getClientSubscriptionToken()`, or a full token object.\n  token?: Realtime.Subscribe.Token | TokenFactory;\n\n  key?: string;\n  enabled?: boolean;\n  bufferInterval?: number;\n\n  //\n  // Validation is enabled by default. Set to false to skip subscriber-side\n  // schema validation for performance-sensitive use cases.\n  validate?: boolean;\n\n  //\n  // Bound the number of messages retained in `messages.all`.\n  // Set to `null` to disable the cap.\n  historyLimit?: number | null;\n\n  //\n  // Override the base URL used for the realtime WebSocket connection.\n  // Normally this is resolved automatically via getClientSubscriptionToken.\n  apiBaseUrl?: string;\n\n  reconnect?: boolean;\n  reconnectMinMs?: number;\n  reconnectMaxMs?: number;\n  pauseOnHidden?: boolean;\n  autoCloseOnTerminal?: boolean;\n}\n\ntype RunLifecycleUpdate = {\n  runStatus?: UseRealtimeRunStatus;\n  result?: unknown;\n};\n\nconst terminalRunStatuses = new Set<UseRealtimeRunStatus>([\n  \"completed\",\n  \"failed\",\n  \"cancelled\",\n]);\n\nconst clampMessages = (\n  prev: Realtime.Message[],\n  next: Realtime.Message[],\n  limit: number | null,\n) => {\n  const merged = [...prev, ...next];\n  if (limit === null) {\n    return merged;\n  }\n\n  if (limit <= 0) {\n    return [];\n  }\n\n  return merged.length > limit ? merged.slice(-limit) : merged;\n};\n\nconst getReconnectDelay = (attempt: number, minMs: number, maxMs: number) => {\n  const jitter = Math.floor(Math.random() * minMs);\n  return Math.min(maxMs, minMs * 2 ** attempt + jitter);\n};\n\nconst toError = (err: unknown) => {\n  return err instanceof Error ? err : new Error(String(err));\n};\n\nconst isSubscriptionToken = (\n  value: ClientSubscriptionToken | Realtime.Subscribe.Token,\n): value is Realtime.Subscribe.Token => {\n  return \"channel\" in value && \"topics\" in value;\n};\n\nconst normalizeRunStatus = (\n  value: unknown,\n): UseRealtimeRunStatus | undefined => {\n  if (typeof value !== \"string\") {\n    return;\n  }\n\n  switch (value.toLowerCase()) {\n    case \"running\":\n    case \"in_progress\":\n      return \"running\";\n    case \"completed\":\n    case \"complete\":\n    case \"succeeded\":\n    case \"success\":\n      return \"completed\";\n    case \"failed\":\n    case \"error\":\n      return \"failed\";\n    case \"cancelled\":\n    case \"canceled\":\n      return \"cancelled\";\n    default:\n      return;\n  }\n};\n\nconst inferRunLifecycleUpdate = (\n  message: Realtime.Message,\n): RunLifecycleUpdate => {\n  if (message.kind !== \"run\") {\n    return {};\n  }\n\n  const data = message.data;\n  if (!data || typeof data !== \"object\") {\n    return {};\n  }\n\n  const obj = data as Record<string, unknown>;\n  const runStatus =\n    normalizeRunStatus(obj.runStatus) ||\n    normalizeRunStatus(obj.status) ||\n    normalizeRunStatus(obj.state);\n\n  if (\"result\" in obj) {\n    return {\n      runStatus,\n      result: obj.result,\n    };\n  }\n\n  if (runStatus === \"completed\" && \"output\" in obj) {\n    return {\n      runStatus,\n      result: obj.output,\n    };\n  }\n\n  return { runStatus };\n};\n\nconst hasDocument = () => typeof document !== \"undefined\";\n\nconst isDocumentVisible = () => {\n  if (!hasDocument()) {\n    return true;\n  }\n\n  return document.visibilityState !== \"hidden\";\n};\n\nconst sleep = (ms: number) =>\n  new Promise<void>((resolve) => {\n    setTimeout(resolve, ms);\n  });\n\nexport const useRealtime = <\n  TChannel extends Realtime.ChannelInput = Realtime.ChannelInput,\n  TTopics extends readonly string[] | undefined = readonly string[] | undefined,\n>({\n  channel,\n  topics,\n  token: tokenInput,\n  key,\n  enabled = true,\n  bufferInterval = 0,\n  validate = true,\n  apiBaseUrl,\n  historyLimit = 100,\n  reconnect = true,\n  reconnectMinMs = 250,\n  reconnectMaxMs = 5_000,\n  pauseOnHidden = true,\n  autoCloseOnTerminal = true,\n}: UseRealtimeOptions<TChannel, TTopics>): UseRealtimeResult<\n  TChannel,\n  TTopics\n> => {\n  const channelKey =\n    typeof channel === \"string\" ? channel : (channel?.name ?? undefined);\n  const topicsKey = topics ? JSON.stringify([...topics]) : \"\";\n  const [allMessages, setAllMessages] = useState<Realtime.Message[]>([]);\n  const [messageDelta, setMessageDelta] = useState<Realtime.Message[]>([]);\n  const [messagesByTopic, setMessagesByTopic] = useState<\n    Record<string, Realtime.Message | undefined>\n  >({});\n  const [lastMessage, setLastMessage] = useState<Realtime.Message | null>(null);\n  const [error, setError] = useState<Error | null>(null);\n  const [connectionStatus, setConnectionStatus] =\n    useState<UseRealtimeConnectionStatus>(\"idle\");\n  const [pauseReason, setPauseReason] = useState<UseRealtimePauseReason>(null);\n  const [runStatus, setRunStatus] = useState<UseRealtimeRunStatus>(\"unknown\");\n  const [result, setResult] = useState<unknown>(undefined);\n  const [isVisible, setIsVisible] = useState(() => isDocumentVisible());\n\n  const subscriptionRef = useRef<Realtime.Subscribe.StreamSubscription | null>(\n    null,\n  );\n  const readerRef =\n    useRef<ReadableStreamDefaultReader<Realtime.Message> | null>(null);\n  const messageBufferRef = useRef<Realtime.Message[]>([]);\n  const bufferIntervalRef = useRef(bufferInterval);\n  const messageLimitRef = useRef(historyLimit);\n  const runStatusRef = useRef(runStatus);\n\n  useEffect(() => {\n    runStatusRef.current = runStatus;\n  }, [runStatus]);\n\n  useEffect(() => {\n    bufferIntervalRef.current = bufferInterval;\n  }, [bufferInterval]);\n\n  useEffect(() => {\n    messageLimitRef.current = historyLimit;\n  }, [historyLimit]);\n\n  useEffect(() => {\n    messageBufferRef.current = [];\n    setAllMessages([]);\n    setMessageDelta([]);\n    setMessagesByTopic({});\n    setLastMessage(null);\n    setResult(undefined);\n    setError(null);\n    runStatusRef.current = \"unknown\";\n    setRunStatus(\"unknown\");\n  }, [channelKey, topicsKey, key]);\n\n  useEffect(() => {\n    if (!pauseOnHidden || !hasDocument()) {\n      return;\n    }\n\n    const onVisibilityChange = () => {\n      setIsVisible(isDocumentVisible());\n    };\n\n    document.addEventListener(\"visibilitychange\", onVisibilityChange);\n    return () => {\n      document.removeEventListener(\"visibilitychange\", onVisibilityChange);\n    };\n  }, [pauseOnHidden]);\n\n  const reset = () => {\n    messageBufferRef.current = [];\n    setAllMessages([]);\n    setMessageDelta([]);\n    setMessagesByTopic({});\n    setLastMessage(null);\n    setResult(undefined);\n    setError(null);\n    runStatusRef.current = \"unknown\";\n    setRunStatus(\"unknown\");\n  };\n\n  const flushBufferedMessages = () => {\n    if (messageBufferRef.current.length === 0) {\n      return;\n    }\n\n    const buffered = [...messageBufferRef.current];\n    messageBufferRef.current = [];\n    setMessageDelta(buffered);\n    setAllMessages((prev) =>\n      clampMessages(prev, buffered, messageLimitRef.current),\n    );\n    setLastMessage(buffered[buffered.length - 1] ?? null);\n  };\n\n  useEffect(() => {\n    let interval: ReturnType<typeof setInterval> | null = null;\n\n    if (bufferInterval <= 0) {\n      flushBufferedMessages();\n    } else {\n      interval = setInterval(() => {\n        flushBufferedMessages();\n      }, bufferInterval);\n    }\n\n    return () => {\n      if (interval) {\n        clearInterval(interval);\n      }\n    };\n  }, [bufferInterval]);\n\n  useEffect(() => {\n    const shouldRun = enabled && (!pauseOnHidden || isVisible);\n    if (!shouldRun) {\n      const nextPauseReason = !enabled\n        ? \"disabled\"\n        : pauseOnHidden && !isVisible\n          ? \"hidden\"\n          : null;\n\n      if (nextPauseReason) {\n        setPauseReason(nextPauseReason);\n        setConnectionStatus(\"paused\");\n      } else {\n        setPauseReason(null);\n        setConnectionStatus(\"idle\");\n      }\n      return;\n    }\n\n    setPauseReason(null);\n\n    let cancelled = false;\n\n    const cleanupConnection = async (reason = \"useRealtime cleanup\") => {\n      flushBufferedMessages();\n\n      const reader = readerRef.current;\n      const sub = subscriptionRef.current;\n\n      readerRef.current = null;\n      subscriptionRef.current = null;\n\n      try {\n        await reader?.cancel();\n      } catch {\n        // no-op\n      }\n\n      try {\n        reader?.releaseLock();\n      } catch {\n        // no-op\n      }\n\n      try {\n        sub?.unsubscribe(reason);\n      } catch {\n        // no-op\n      }\n    };\n\n    const resolveToken = async (): Promise<Realtime.Subscribe.Token> => {\n      if (tokenInput && typeof tokenInput !== \"function\") {\n        return tokenInput;\n      }\n\n      if (typeof tokenInput === \"function\") {\n        const next = await tokenInput();\n        if (typeof next === \"string\") {\n          if (!channel || !topics) {\n            throw new Error(\n              \"useRealtime token() returned a string but channel/topics were not provided\",\n            );\n          }\n\n          return {\n            channel: channel as Realtime.ChannelInput,\n            topics: topics as string[],\n            key: next,\n          } as Realtime.Subscribe.Token;\n        }\n\n        //\n        // Token factory returned an object. If it has channel/topics, it's\n        // a full token; otherwise it's a { key, apiBaseUrl? } shorthand\n        // from a server function.\n        if (isSubscriptionToken(next)) {\n          return next as Realtime.Subscribe.Token;\n        }\n\n        if (!channel || !topics) {\n          throw new Error(\n            \"useRealtime token() returned a key object but channel/topics were not provided\",\n          );\n        }\n\n        return {\n          channel: channel as Realtime.ChannelInput,\n          topics: topics as string[],\n          key: next.key,\n          apiBaseUrl: next.apiBaseUrl,\n        } as Realtime.Subscribe.Token;\n      }\n\n      throw new Error(\"No token provided and no token() handler.\");\n    };\n\n    const applyMessage = (message: Realtime.Message) => {\n      if (message.kind === \"run\") {\n        const lifecycle = inferRunLifecycleUpdate(message);\n\n        if (lifecycle.runStatus) {\n          runStatusRef.current = lifecycle.runStatus;\n          setRunStatus(lifecycle.runStatus);\n        }\n        if (\"result\" in lifecycle) {\n          setResult(lifecycle.result);\n        }\n        return;\n      }\n\n      if (runStatusRef.current === \"unknown\") {\n        runStatusRef.current = \"running\";\n        setRunStatus(\"running\");\n      }\n\n      if (message.topic) {\n        setMessagesByTopic((prev) => ({\n          ...prev,\n          [message.topic as string]: message,\n        }));\n      }\n\n      if (bufferIntervalRef.current === 0) {\n        setMessageDelta([message]);\n        setAllMessages((prev) =>\n          clampMessages(prev, [message], messageLimitRef.current),\n        );\n        setLastMessage(message);\n        return;\n      }\n\n      messageBufferRef.current.push(message);\n    };\n\n    const run = async () => {\n      let reconnectAttempt = 0;\n\n      while (!cancelled) {\n        try {\n          setError(null);\n          setConnectionStatus(\"connecting\");\n\n          const token = await resolveToken();\n          if (cancelled) {\n            break;\n          }\n\n          const stream = (await realtimeSubscribe({\n            ...token,\n            validate,\n            apiBaseUrl: apiBaseUrl ?? token.apiBaseUrl,\n          })) as Realtime.Subscribe.StreamSubscription;\n\n          if (cancelled) {\n            stream.unsubscribe(\"useRealtime cancelled before start\");\n            break;\n          }\n\n          reconnectAttempt = 0;\n          subscriptionRef.current = stream;\n          setConnectionStatus(\"open\");\n\n          if (runStatusRef.current === \"unknown\") {\n            runStatusRef.current = \"running\";\n            setRunStatus(\"running\");\n          }\n\n          const reader = stream.getReader();\n          readerRef.current = reader;\n\n          try {\n            while (!cancelled) {\n              const { done, value } = await reader.read();\n              if (done || cancelled) {\n                break;\n              }\n\n              applyMessage(value);\n\n              if (\n                autoCloseOnTerminal &&\n                terminalRunStatuses.has(runStatusRef.current)\n              ) {\n                stream.unsubscribe(\"Run reached terminal status\");\n                break;\n              }\n            }\n          } finally {\n            try {\n              reader.releaseLock();\n            } catch {\n              // no-op\n            }\n            if (readerRef.current === reader) {\n              readerRef.current = null;\n            }\n          }\n\n          if (cancelled) {\n            break;\n          }\n\n          setConnectionStatus(\"closed\");\n\n          if (\n            autoCloseOnTerminal &&\n            terminalRunStatuses.has(runStatusRef.current)\n          ) {\n            break;\n          }\n\n          if (!reconnect) {\n            break;\n          }\n        } catch (err) {\n          if (cancelled) {\n            break;\n          }\n\n          setError(toError(err));\n          setConnectionStatus(\"error\");\n\n          if (!reconnect) {\n            break;\n          }\n        } finally {\n          await cleanupConnection(\"reconnect cycle cleanup\");\n        }\n\n        if (cancelled || !reconnect) {\n          break;\n        }\n\n        const delay = getReconnectDelay(\n          reconnectAttempt++,\n          reconnectMinMs,\n          reconnectMaxMs,\n        );\n        await sleep(delay);\n      }\n    };\n\n    void run().catch((err) => {\n      if (!cancelled) {\n        setError(toError(err));\n        setConnectionStatus(\"error\");\n      }\n    });\n\n    return () => {\n      cancelled = true;\n      void cleanupConnection(\"useRealtime unmount\");\n      setConnectionStatus((prev) => (prev === \"open\" ? \"closed\" : prev));\n    };\n  }, [\n    apiBaseUrl,\n    autoCloseOnTerminal,\n    channelKey,\n    enabled,\n    isVisible,\n    key,\n    pauseOnHidden,\n    reconnect,\n    reconnectMaxMs,\n    reconnectMinMs,\n    tokenInput,\n    topicsKey,\n    validate,\n  ]);\n  const isPaused = connectionStatus === \"paused\";\n\n  return {\n    connectionStatus,\n    runStatus,\n    isPaused,\n    pauseReason,\n\n    messages: {\n      byTopic: messagesByTopic as MessagesByTopicMap<TChannel, TTopics>,\n      all: allMessages,\n      last: lastMessage,\n      delta: messageDelta,\n    },\n\n    result,\n    error,\n    reset,\n  } as UseRealtimeResult<TChannel, TTopics>;\n};\n\nexport { getClientSubscriptionToken };\nexport type { Inngest };\n"],"mappings":"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"}