import { ReactNode, CSSProperties, RefObject } from 'react'; import { C as CrossdeckOptions } from './types-DfdHJNUG.js'; import { T as TrustToken, a as TrustTokenStatus } from './trust-sji5vuxH.js'; /** * @cross-deck/web/react — React hooks for the Crossdeck SDK. * * Why this exists: `Crossdeck.isEntitled("pro")` is a synchronous cache * read, but the cache populates asynchronously after `getEntitlements()` * lands. React has no way to know the cache changed, so a component * that calls `isEntitled` directly in a render path would show the * empty-cache result forever (until something else triggered a re-render). * * The `useEntitlement` hook below ties cache state to React state via * `onEntitlementsChange`, so the component re-renders the moment the * answer changes. After the first render, every subsequent check is a * sync cache hit — exactly the "microsecond entitlement check" the * SDK promises. * * Side effect: importing this module pulls in `react` as a peer * dependency. Consumers who don't use React shouldn't import it. * * SSR safety: `useEffect` is a no-op during server-side rendering, and * the initial state is conservative (`false` until proven otherwise), * so server output never claims a non-existent entitlement. The hook * hydrates correctly on the client. * * NorthStar §11.4 (reactive bindings): every SDK ships first-class * framework bindings so the canonical snippet stays one line. Web => * React hook here. iOS => `@Observable` SwiftUI wrapper (when iOS SDK * ships). Android => Compose `State` wrapper (when Android * SDK ships). */ interface CrossdeckProviderProps extends Omit { /** * Optional. When defined, the provider calls Crossdeck.identify(userId) * after init and on every change. When the prop flips back to undefined * (logout), the provider calls Crossdeck.reset(). * * Pass your auth library's stable user id directly: * // NextAuth * // Firebase * // Supabase * * Anonymous (pre-login) traffic stays anonymous until userId becomes * defined — the SDK's anonymousId follows the same user record once * identify lands, so attribution survives sign-up. */ userId?: string | null | undefined; children: ReactNode; } declare function CrossdeckProvider(props: CrossdeckProviderProps): ReactNode; /** * Subscribe a React component to a single entitlement key. * * The hook returns the current `isEntitled(key)` value AND keeps it in * sync with the cache. When `getEntitlements()` lands, when a purchase * adds an entitlement, or when `reset()` is called on logout, every * component using this hook re-renders to reflect the change. * * Usage: * * import { useEntitlement } from "@cross-deck/web/react"; * * function ProBadge() { * const isPro = useEntitlement("pro"); * return isPro ? Pro : null; * } * * Note that the hook does NOT call `getEntitlements()` itself — that's * a one-time boot warm-up the consumer is expected to trigger after * `Crossdeck.init()` (typically inside a top-level effect in their * Providers wrapper). Once warmed, every component using this hook * gets the answer for free. * * Pre-init: returns `false`. Calling Crossdeck.init() later doesn't * automatically refresh existing hook instances — but as soon as * something mutates the cache (i.e. after a successful * getEntitlements() call on the new SDK instance), the hook fires. */ declare function useEntitlement(key: string): boolean; /** * Subscribe to the full entitlement list. Returns an array of active * entitlement keys, kept in sync with the cache. Useful for iterating * (e.g. rendering a list of unlocked features in a settings page). * * Same pre-init / SSR semantics as `useEntitlement`. */ declare function useEntitlements(): readonly string[]; interface CrossdeckTrustProps { /** * The project's publishable key (cd_pub_…). Pass it here — the robust, explicit way * (like Stripe / Turnstile) — and no `Crossdeck.init()` / `` is * needed. Omit it and the SDK falls back to the key from `init()`. */ publicKey?: string; /** Called once when the panel mints a token. Pass `t.token` to your gate call. */ onToken?: (t: TrustToken) => void; /** * Called if the panel could not mint (adblocker, offline, our outage, timeout). * INFORMATIONAL — not an error to handle. The signup should still proceed. */ onUnavailable?: (reason: string) => void; /** Class on the wrapper element the panel mounts into. */ className?: string; /** Inline style on the wrapper element. */ style?: CSSProperties; /** id on the wrapper element. */ id?: string; } /** * `` — drop it on your signup form. Renders * the same cross-origin Trust panel every install gets, mints a single-use * attestation, and calls `onToken` with it. SSR-safe (mounts on the client). */ declare function CrossdeckTrust(props: CrossdeckTrustProps): ReactNode; /** * Headless Trust — mount the panel and read the token from React state. * * @example * const { ref, token, status } = useTrustToken(); * return <>
; * // then send `token` to your server; `status` is "pending" | "ready" | "unavailable". */ declare function useTrustToken(opts?: { /** Explicit publishable key (cd_pub_…) — no `init()` needed. Falls back to init's key. */ publicKey?: string; }): { /** Attach to the element the panel should mount into: `
`. */ ref: RefObject; /** The minted token, or null until it mints (or if the panel failed open). */ token: string | null; /** Lifecycle: pending → ready (minted) or unavailable (failed open). */ status: TrustTokenStatus; }; export { CrossdeckProvider, CrossdeckTrust, type CrossdeckTrustProps, TrustTokenStatus, useEntitlement, useEntitlements, useTrustToken };