{"version":3,"file":"react.mjs","names":[],"sources":["../src/createActorKitContext.tsx"],"sourcesContent":["\"use client\";\n\nimport React, {\n  createContext,\n  memo,\n  ReactNode,\n  useCallback,\n  useContext,\n  useEffect,\n  useMemo,\n  useRef,\n  useSyncExternalStore,\n} from \"react\";\nimport { matchesState, StateValueFrom } from \"xstate\";\nimport type { ActorKitClientProps } from \"./createActorKitClient\";\nimport { createActorKitClient } from \"./createActorKitClient\";\nimport type {\n  ActorKitClient,\n  AnyActorKitStateMachine,\n  CallerSnapshotFrom,\n  ClientEventFrom,\n  MatchesProps,\n} from \"./types\";\n\nexport function createActorKitContext<TMachine extends AnyActorKitStateMachine>(\n  actorType: string\n) {\n  const ActorKitContext = createContext<ActorKitClient<TMachine> | null>(null);\n\n  const ProviderFromClient: React.FC<{\n    children: ReactNode;\n    client: ActorKitClient<TMachine>;\n  }> = ({ children, client }) => {\n    return (\n      <ActorKitContext.Provider value={client}>\n        {children}\n      </ActorKitContext.Provider>\n    );\n  };\n\n  const InitialSnapshotContext = createContext<CallerSnapshotFrom<TMachine> | null>(null);\n\n  const Provider: React.FC<\n    {\n      children: ReactNode;\n    } & Omit<ActorKitClientProps<TMachine>, \"actorType\">\n  > = memo((props) => {\n    const clientRef = useRef(\n      createActorKitClient<TMachine>({\n        host: props.host,\n        actorId: props.actorId,\n        accessToken: props.accessToken,\n        checksum: props.checksum,\n        initialSnapshot: props.initialSnapshot,\n        actorType,\n      })\n    );\n    const initializedRef = useRef(false);\n\n    useEffect(() => {\n      if (!initializedRef.current) {\n        initializedRef.current = true;\n        clientRef.current.connect().then(() => {});\n      }\n    }, [initializedRef]);\n\n    return (\n      <InitialSnapshotContext.Provider value={props.initialSnapshot}>\n        <ActorKitContext.Provider value={clientRef.current}>\n          {props.children}\n        </ActorKitContext.Provider>\n      </InitialSnapshotContext.Provider>\n    );\n  });\n\n  function useClient(): ActorKitClient<TMachine> {\n    const client = useContext(ActorKitContext);\n    if (!client) {\n      throw new Error(\n        \"useClient must be used within an ActorKitContext.Provider\"\n      );\n    }\n    return client;\n  }\n\n  const useSelector = <T,>(\n    selector: (snapshot: CallerSnapshotFrom<TMachine>) => T\n  ) => {\n    const client = useClient();\n    const initialSnapshot = useContext(InitialSnapshotContext);\n\n    // Use the initial snapshot for SSR to ensure hydration stability.\n    // The server render uses initialSnapshot, and the client's first render\n    // must return the same value to avoid hydration mismatches.\n    const getServerSnapshot = useMemo(() => {\n      if (!initialSnapshot) return undefined;\n      return () => initialSnapshot;\n    }, [initialSnapshot]);\n\n    return useSyncExternalStoreWithSelector(\n      client.subscribe,\n      client.getState,\n      getServerSnapshot,\n      selector,\n      defaultCompare\n    );\n  };\n\n  function useSend(): (event: ClientEventFrom<TMachine>) => void {\n    const client = useClient();\n    return client.send;\n  }\n\n  function useMatches(stateValue: StateValueFrom<TMachine>): boolean {\n    return useSelector((state) =>\n      matchesState(stateValue, state.value as StateValueFrom<TMachine>)\n    );\n  }\n\n  const Matches: React.FC<MatchesProps<TMachine> & { children: ReactNode }> & {\n    create: (\n      state: StateValueFrom<TMachine>,\n      options?: {\n        and?: StateValueFrom<TMachine>;\n        or?: StateValueFrom<TMachine>;\n        not?: boolean;\n      }\n    ) => React.FC<\n      Omit<MatchesProps<TMachine>, \"state\" | \"and\" | \"or\" | \"not\"> & {\n        children: ReactNode;\n      }\n    >;\n  } = (props) => {\n    const active = useMatches(props.state);\n    const matchesAnd = props.and ? useMatches(props.and) : true;\n    const matchesOr = props.or ? useMatches(props.or) : false;\n    const value =\n      typeof props.initialValueOverride === \"boolean\"\n        ? props.initialValueOverride\n        : (active && matchesAnd) || matchesOr;\n    const finalValue = props.not ? !value : value;\n    return finalValue ? <>{props.children}</> : null;\n  };\n\n  Matches.create = (state, options = {}) => {\n    const Component: React.FC<\n      Omit<MatchesProps<TMachine>, \"state\" | \"and\" | \"or\" | \"not\"> & {\n        children: ReactNode;\n      }\n    > = ({ children, initialValueOverride }) => (\n      <Matches\n        state={state}\n        and={options.and}\n        or={options.or}\n        not={options.not}\n        initialValueOverride={initialValueOverride}\n      >\n        {children}\n      </Matches>\n    );\n    Component.displayName = `MatchesComponent(${state.toString()})`;\n    return Component;\n  };\n\n  return {\n    Provider,\n    ProviderFromClient,\n    useClient,\n    useSelector,\n    useSend,\n    useMatches,\n    Matches,\n  };\n}\n\nfunction useSyncExternalStoreWithSelector<Snapshot, Selection>(\n  subscribe: (onStoreChange: () => void) => () => void,\n  getSnapshot: () => Snapshot,\n  getServerSnapshot: undefined | null | (() => Snapshot),\n  selector: (snapshot: Snapshot) => Selection,\n  isEqual?: (a: Selection, b: Selection) => boolean\n): Selection {\n  const [getSelection, getServerSelection] = useMemo(() => {\n    let hasMemo = false;\n    let memoizedSnapshot: Snapshot;\n    let memoizedSelection: Selection;\n\n    const memoizedSelector = (nextSnapshot: Snapshot) => {\n      if (!hasMemo) {\n        hasMemo = true;\n        memoizedSnapshot = nextSnapshot;\n        memoizedSelection = selector(nextSnapshot);\n        return memoizedSelection;\n      }\n\n      if (Object.is(memoizedSnapshot, nextSnapshot)) {\n        return memoizedSelection;\n      }\n\n      const nextSelection = selector(nextSnapshot);\n\n      if (isEqual && isEqual(memoizedSelection, nextSelection)) {\n        memoizedSnapshot = nextSnapshot;\n        return memoizedSelection;\n      }\n\n      memoizedSnapshot = nextSnapshot;\n      memoizedSelection = nextSelection;\n      return nextSelection;\n    };\n\n    const getSnapshotWithSelector = () => memoizedSelector(getSnapshot());\n    const getServerSnapshotWithSelector = getServerSnapshot\n      ? () => memoizedSelector(getServerSnapshot())\n      : undefined;\n\n    return [getSnapshotWithSelector, getServerSnapshotWithSelector];\n  }, [getSnapshot, getServerSnapshot, selector, isEqual]);\n\n  const subscribeWithSelector = useCallback(\n    (onStoreChange: () => void) => {\n      let previousSelection = getSelection();\n      return subscribe(() => {\n        const nextSelection = getSelection();\n        if (!isEqual || !isEqual(previousSelection, nextSelection)) {\n          previousSelection = nextSelection;\n          onStoreChange();\n        }\n      });\n    },\n    [subscribe, getSelection, isEqual]\n  );\n\n  return useSyncExternalStore(\n    subscribeWithSelector,\n    getSelection,\n    getServerSelection\n  );\n}\n\nfunction defaultCompare<T>(a: T, b: T) {\n  return a === b;\n}\n"],"mappings":"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"}