import { ReactNode } from 'react'; import { JourneySnapshot } from '@fanfare-io/fanfare-sdk-core/experiences'; import { AccessStatus, CheckoutVerifier, GrantRecord } from '@fanfare-io/fanfare-sdk-core/storefront'; import { ExperienceSource, FanfareMode, ShopifyAdapterConfig } from '../config'; import { ExperienceResolutionError, ShopifyExperienceResolution } from '../resolver'; import { ShopifyCheckoutContext } from '../verifier'; export type { ExperienceSource } from '../config'; /** The fully-resolved config the provider holds and exposes to the internal hooks. */ export interface ResolvedShopifyConfig { organizationId: string; publishableKey: string; mode: FanfareMode; shopify: ShopifyAdapterConfig; experiences: ExperienceSource; } /** * The INTERNAL adapter value. Carried by an internal context and read via the * internal `useShopifyAdapter` hook — NOT a public `useFanfareAdapter`. The * public hooks consume this; integrators never touch it. */ export interface ShopifyAdapterValue { /** The resolved provider config (mode + store + experience source). */ config: ResolvedShopifyConfig; /** * Internal. Live reads in flight for this provider, keyed by request URL; both * consumers share it so simultaneous asks for one product issue one request. * Entries live only until their request settles. */ inFlightResolutions: Map>; /** Internal. Report a settled consumer failure without interrupting resolution. */ reportResolutionError(error: ExperienceResolutionError): void; /** Latest journey snapshot reported by the widget driving the journey. */ snapshot: JourneySnapshot | null; /** Access status derived from the snapshot. */ status: AccessStatus; /** Grant recorded when the shopper cleared the drop (survives reloads). */ grant: GrantRecord | null; reportSnapshot(snapshot: JourneySnapshot): void; recordGrant(grant: GrantRecord): void; clearGrant(): void; /** The internal client-only verifier (the checkout gate consumes it). */ verifier: CheckoutVerifier; /** * Internal cart/checkout-context plumbing. `useFanfareClaim` sets the active * cart here so the filled checkout context has a cartId to pair with. */ setActiveCartId(cartId: string | null): void; /** * Returns the live checkout context `{ credential, distributionId, cartId }` * from internal state, or `null` when any piece is missing (not yet ready). * `credential` = the recorded grant token; `distributionId` = captured from the * journey snapshot; `cartId` = the active cart slot. */ getCheckoutContext(): ShopifyCheckoutContext | null; } export interface FanfareShopifyProviderProps { organizationId: string; publishableKey: string; /** Operating mode. Defaults to `"production"` (real verify + claim via proxy). */ mode?: FanfareMode; shopify: ShopifyAdapterConfig; /** * Where the Shopify→experience mapping comes from. Defaults to * `{ source: "metafield" }`, whose live tier reads the product's `experienceIds` * through the app proxy (`GET {proxyBaseUrl}/experiences/ids-by-handle/{key}`). * All three variants are fully resolved — `"static"` and `"map"` synchronously * by normalized lookup key, `"metafield"` via the preloaded fast path or a live read — by both * `useFanfareExperience` and ``. See `ExperienceSource` for * the full resolution order per source. * Resolution outcomes are `loading | gated | ungated | error`, and `error` is reported through `onResolutionError`. * The resolveExperience override is keyed on presence, not identity — swapping one function for another does not re-resolve. */ experiences?: ExperienceSource; /** * Called once per consumer resolution that fails: lookupKey is the product's * handle or id and reason is the typed cause; two consumers of one product * each receive a call. Supplying a handler replaces the default warn. A * throwing handler is caught and falls through to the warn, never breaking * resolution. When omitted, the SDK warns once per (product, reason) in the * developer console only — nothing reaches Fanfare. A request to an absolute * proxy base that fails before a response is received is reported by the * resolver's once-per-base advisory whether or not a handler is supplied. */ onResolutionError?: (error: ExperienceResolutionError) => void; children: ReactNode; } export declare function FanfareShopifyProvider({ organizationId, publishableKey, mode, shopify, experiences, onResolutionError, children, }: FanfareShopifyProviderProps): import("react/jsx-runtime").JSX.Element; /** * INTERNAL hook over the adapter context. NOT public — the public hooks * (`useFanfareExperience` / `useFanfareGrant` / `useFanfareClaim`) build on it. * Throws when used outside `FanfareShopifyProvider`. */ export declare function useShopifyAdapter(): ShopifyAdapterValue;