@wireai/activation 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +73 -0
- package/CHANGELOG.md +572 -0
- package/INTEGRATION_PROMPT.md +55 -0
- package/LICENSE +21 -0
- package/README.md +923 -0
- package/dist/CenteredModal-C3qQBHsA.d.mts +38 -0
- package/dist/CenteredModal-Cdgns6--.d.ts +38 -0
- package/dist/coachmarks/index.d.mts +352 -0
- package/dist/coachmarks/index.d.ts +352 -0
- package/dist/coachmarks/index.js +944 -0
- package/dist/coachmarks/index.js.map +1 -0
- package/dist/coachmarks/index.mjs +918 -0
- package/dist/coachmarks/index.mjs.map +1 -0
- package/dist/decision-CFvGY6nP.d.ts +228 -0
- package/dist/decision-Cl8OFYzu.d.mts +228 -0
- package/dist/index.d.mts +1390 -0
- package/dist/index.d.ts +1390 -0
- package/dist/index.js +3260 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +3186 -0
- package/dist/index.mjs.map +1 -0
- package/dist/questionnaire/index.d.mts +249 -0
- package/dist/questionnaire/index.d.ts +249 -0
- package/dist/questionnaire/index.js +922 -0
- package/dist/questionnaire/index.js.map +1 -0
- package/dist/questionnaire/index.mjs +906 -0
- package/dist/questionnaire/index.mjs.map +1 -0
- package/dist/reviews/index.d.mts +213 -0
- package/dist/reviews/index.d.ts +213 -0
- package/dist/reviews/index.js +1001 -0
- package/dist/reviews/index.js.map +1 -0
- package/dist/reviews/index.mjs +971 -0
- package/dist/reviews/index.mjs.map +1 -0
- package/dist/showcase/index.d.mts +119 -0
- package/dist/showcase/index.d.ts +119 -0
- package/dist/showcase/index.js +660 -0
- package/dist/showcase/index.js.map +1 -0
- package/dist/showcase/index.mjs +651 -0
- package/dist/showcase/index.mjs.map +1 -0
- package/dist/types-BKfpdZzX.d.mts +84 -0
- package/dist/types-BKfpdZzX.d.ts +84 -0
- package/dist/types-CMuOexw0.d.mts +116 -0
- package/dist/types-CMuOexw0.d.ts +116 -0
- package/dist/types-GL_hQ0TN.d.mts +46 -0
- package/dist/types-GL_hQ0TN.d.ts +46 -0
- package/llms.txt +36 -0
- package/metro/index.d.ts +32 -0
- package/metro/index.js +83 -0
- package/package.json +171 -0
- package/src/DemoOnboarding.tsx +133 -0
- package/src/OnboardingFlow.tsx +504 -0
- package/src/WireOnboarding.tsx +248 -0
- package/src/analytics/analyticsEvent.ts +69 -0
- package/src/analytics/reportClientEvent.ts +119 -0
- package/src/analytics/sendPreview.ts +73 -0
- package/src/attribution/attribution.ts +46 -0
- package/src/cards/ChipSelectCard.tsx +265 -0
- package/src/cards/InterstitialCard.tsx +299 -0
- package/src/cards/NumberStepperCard.tsx +121 -0
- package/src/cards/SelectionCard.tsx +270 -0
- package/src/cards/StatusCard.tsx +170 -0
- package/src/cards/TextInputCard.tsx +147 -0
- package/src/cards/index.ts +23 -0
- package/src/coachmarks/CoachmarkOverlayHost.tsx +44 -0
- package/src/coachmarks/CoachmarkProvider.tsx +108 -0
- package/src/coachmarks/GestureHint.tsx +331 -0
- package/src/coachmarks/SpotlightOverlay.tsx +254 -0
- package/src/coachmarks/coachmarkAnchorRegistry.ts +70 -0
- package/src/coachmarks/coachmarkOverlayStore.ts +63 -0
- package/src/coachmarks/index.ts +62 -0
- package/src/coachmarks/runtime.ts +103 -0
- package/src/coachmarks/selectTourSteps.ts +45 -0
- package/src/coachmarks/types.ts +58 -0
- package/src/coachmarks/useCoachmarkAnchor.ts +49 -0
- package/src/coachmarks/useCoachmarkTour.ts +200 -0
- package/src/components/AnimatedSparkle.tsx +101 -0
- package/src/components/Button.tsx +129 -0
- package/src/components/CardHandoff.tsx +212 -0
- package/src/components/CardLayout.tsx +103 -0
- package/src/components/CenteredModal.tsx +184 -0
- package/src/components/CompletionView.tsx +186 -0
- package/src/components/DoneBlock.tsx +37 -0
- package/src/components/ErrorBlock.tsx +42 -0
- package/src/components/Illustration.tsx +36 -0
- package/src/components/LoadingBlock.tsx +182 -0
- package/src/components/LoadingScreen.tsx +35 -0
- package/src/components/OnboardingScaffold.tsx +105 -0
- package/src/components/StepProgress.tsx +85 -0
- package/src/components/loaderChrome.ts +28 -0
- package/src/config/onboardingFlag.ts +39 -0
- package/src/config/wireConfigFromEnv.ts +52 -0
- package/src/device/deviceContext.ts +158 -0
- package/src/features/WireFeaturesProvider.tsx +81 -0
- package/src/features/cache.ts +92 -0
- package/src/features/defaults.ts +67 -0
- package/src/features/fetchWireFeatures.ts +86 -0
- package/src/features/index.ts +39 -0
- package/src/features/types.ts +61 -0
- package/src/features/useWireFeatures.ts +57 -0
- package/src/identity/userIdentity.ts +100 -0
- package/src/illustrations/defaultIllustrations.tsx +99 -0
- package/src/index.ts +159 -0
- package/src/motion/centeredModalMotion.ts +45 -0
- package/src/motion/motionSpec.ts +133 -0
- package/src/motion/useReducedMotion.ts +43 -0
- package/src/questionnaire/QuestionnaireGate.tsx +235 -0
- package/src/questionnaire/decision.ts +63 -0
- package/src/questionnaire/index.ts +54 -0
- package/src/questionnaire/runtime.ts +20 -0
- package/src/questionnaire/transport.ts +83 -0
- package/src/questionnaire/types.ts +182 -0
- package/src/questionnaire/useQuestionnaireGate.ts +159 -0
- package/src/reviews/ReviewGate.tsx +316 -0
- package/src/reviews/ReviewModal.tsx +13 -0
- package/src/reviews/decision.ts +120 -0
- package/src/reviews/equality.ts +54 -0
- package/src/reviews/expo-store-review.d.ts +16 -0
- package/src/reviews/feedbackForm.ts +41 -0
- package/src/reviews/index.ts +78 -0
- package/src/reviews/presentation.ts +29 -0
- package/src/reviews/runtime.ts +45 -0
- package/src/reviews/storeReview.ts +62 -0
- package/src/reviews/transport.ts +89 -0
- package/src/reviews/types.ts +172 -0
- package/src/reviews/useReviewGate.ts +137 -0
- package/src/session/persistedSession.ts +143 -0
- package/src/session-analytics/index.ts +18 -0
- package/src/session-analytics/reportSessionStart.ts +144 -0
- package/src/session-analytics/useSessionStart.ts +114 -0
- package/src/showcase/FeatureShowcase.tsx +233 -0
- package/src/showcase/index.ts +19 -0
- package/src/showcase/selectShowcaseSlides.ts +45 -0
- package/src/showcase/showcaseColors.ts +91 -0
- package/src/showcase/types.ts +74 -0
- package/src/theme/ThemeContext.tsx +38 -0
- package/src/theme/defaultTheme.ts +70 -0
- package/src/theme/themeFromBrand.ts +93 -0
- package/src/theme/types.ts +88 -0
- package/src/theme/typography.ts +46 -0
- package/src/types.ts +215 -0
- package/src/utils/deriveAnswers.ts +43 -0
- package/src/utils/readProgress.ts +33 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/features/defaults.ts","../../src/features/cache.ts","../../src/features/fetchWireFeatures.ts","../../src/features/useWireFeatures.ts","../../src/features/WireFeaturesProvider.tsx","../../src/coachmarks/runtime.ts","../../src/coachmarks/coachmarkOverlayStore.ts","../../src/theme/defaultTheme.ts","../../src/theme/ThemeContext.tsx","../../src/coachmarks/GestureHint.tsx","../../src/coachmarks/SpotlightOverlay.tsx","../../src/coachmarks/CoachmarkOverlayHost.tsx","../../src/coachmarks/CoachmarkProvider.tsx","../../src/coachmarks/coachmarkAnchorRegistry.ts","../../src/coachmarks/useCoachmarkAnchor.ts","../../src/coachmarks/useCoachmarkTour.ts","../../src/coachmarks/selectTourSteps.ts"],"names":["useRef","useState","useEffect","createContext","useContext","useSyncExternalStore","useMemo","jsxs","View","jsx","useSharedValue","useReducedMotion","withRepeat","withSequence","withTiming","withDelay","useAnimatedStyle","Animated","Fragment","StyleSheet","React","BlurView","useWindowDimensions","useAnimatedProps","styles","FadeIn","FadeOut","Pressable","Text","useCallback","_a","_b","_c"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * The fail-open defaults + a tolerant parser for the server's flags payload.\n *\n * THE CONTRACT: fail-open, never fail-dark. An absent server object, a missing module key, a\n * malformed value, or an unreachable endpoint must resolve to the MOST PERMISSIVE state — every\n * module ON, onboarding `ai` — so a control-plane outage can only ever be more permissive than\n * the dashboard intends. It can never dark a tenant's activation. Matches the server's own\n * documented fail-open default (FEATURES.md: \"local defaults — every module on, onboarding ai\").\n */\nimport type { OnboardingMode, WireFeatures } from \"./types\";\n\n/**\n * ALL ON, onboarding `ai`. Frozen + module-level so its reference is stable across every call\n * (consumers that list resolved flags in an effect dep array never loop on a fresh identity).\n */\nexport const defaultWireFeatures: WireFeatures = Object.freeze({\n coachmarks: Object.freeze({ enabled: true }),\n showcase: Object.freeze({ enabled: true }),\n onboarding: Object.freeze({ mode: \"ai\" as OnboardingMode }),\n review: Object.freeze({ enabled: true }),\n questionnaire: Object.freeze({ enabled: true }),\n announcements: Object.freeze({ enabled: true }),\n}) as WireFeatures;\n\nconst VALID_MODES: readonly OnboardingMode[] = [\"ai\", \"static\", \"off\"];\n\n/** Read a `{ enabled: boolean }` module, defaulting to ON when absent/malformed (fail-open). */\nconst readEnabled = (raw: unknown): { enabled: boolean } => {\n if (raw && typeof raw === \"object\" && typeof (raw as { enabled?: unknown }).enabled === \"boolean\") {\n return { enabled: (raw as { enabled: boolean }).enabled };\n }\n return { enabled: true };\n};\n\n/**\n * Narrow the server's (untrusted) JSON to a complete `WireFeatures`. Every field is filled with\n * its fail-open default when the server omits it or sends the wrong type, so a partial or\n * malformed payload degrades PERMISSIVELY rather than throwing. A non-object input (null, array,\n * string) → the full defaults. Never throws.\n */\nexport const parseWireFeatures = (raw: unknown): WireFeatures => {\n if (!raw || typeof raw !== \"object\" || Array.isArray(raw)) return defaultWireFeatures;\n const src = raw as Record<string, unknown>;\n const modeRaw = (src.onboarding as { mode?: unknown } | undefined)?.mode;\n const mode: OnboardingMode =\n typeof modeRaw === \"string\" && VALID_MODES.includes(modeRaw as OnboardingMode)\n ? (modeRaw as OnboardingMode)\n : \"ai\";\n return {\n coachmarks: readEnabled(src.coachmarks),\n showcase: readEnabled(src.showcase),\n onboarding: { mode },\n review: readEnabled(src.review),\n questionnaire: readEnabled(src.questionnaire),\n announcements: readEnabled(src.announcements),\n };\n};\n\n/** Value-equality of two resolved flags — lets the hook hold a stable reference across churn. */\nexport const featuresEqual = (a: WireFeatures, b: WireFeatures): boolean =>\n a === b ||\n (a.coachmarks.enabled === b.coachmarks.enabled &&\n a.showcase.enabled === b.showcase.enabled &&\n a.onboarding.mode === b.onboarding.mode &&\n a.review.enabled === b.review.enabled &&\n a.questionnaire.enabled === b.questionnaire.enabled &&\n a.announcements.enabled === b.announcements.enabled);\n","/**\n * The last-known-flags cache — persisted through the host's optional `storage`.\n *\n * WHY: the fetch is best-effort and fail-open. When the control plane is unreachable we serve the\n * LAST value we saw rather than snapping to defaults, so a tenant that intentionally disabled a\n * module during an incident keeps it disabled across an outage instead of flapping back on. That\n * is \"stale-while-error\": a fresh cache (< TTL) is trusted, and on a fetch error even a STALE\n * cache is served (any age beats a guess). Every operation is best-effort — a broken/hung storage\n * degrades to defaults, never a throw and never a stuck gate (mirrors persistedSession).\n */\nimport { parseWireFeatures } from \"./defaults\";\nimport type { WireFeatures } from \"./types\";\nimport type { WireOnboardingStorage } from \"../session/persistedSession\";\n\n/**\n * TTL for a cached flags entry, aligned to the server's `Cache-Control: private, max-age=300`.\n * A cache younger than this is \"fresh\"; older is \"stale\" (still served on a fetch error).\n */\nexport const DEFAULT_FEATURES_TTL_MS = 300_000;\n\n/** Ceiling on the storage read so a hung adapter degrades to defaults, never a stuck resolve. */\nconst READ_TIMEOUT_MS = 1_500;\n\n/** Storage key for a tenant's cached flags, e.g. `wireai:features:myelino`. */\nexport const featuresCacheKey = (appId?: string): string =>\n `wireai:features:${appId && appId.length > 0 ? appId : \"default\"}`;\n\n/** A cached flags entry: the resolved flags + the epoch-ms they were fetched. */\nexport interface CachedFeatures {\n features: WireFeatures;\n /** Age of the entry in ms at read time. */\n ageMs: number;\n}\n\nconst withTimeout = <T>(p: Promise<T>, ms: number): Promise<T | undefined> => {\n let timer: ReturnType<typeof setTimeout>;\n const timeout = new Promise<undefined>((resolve) => {\n timer = setTimeout(() => resolve(undefined), ms);\n });\n return Promise.race([p, timeout]).finally(() => clearTimeout(timer));\n};\n\n/** Whether a cache entry is still within the TTL (server max-age aligned). */\nexport const isFeaturesFresh = (ageMs: number, ttlMs: number = DEFAULT_FEATURES_TTL_MS): boolean =>\n ageMs >= 0 && ageMs < ttlMs;\n\n/**\n * Read the cached flags for `key`, or `undefined` when absent/corrupt/timed-out. Returns the\n * value AND its age so a caller can apply a TTL (fresh) or ignore it (stale-while-error). Never\n * throws; never hangs past the read timeout. The stored value is re-parsed through\n * `parseWireFeatures`, so a partially-corrupt entry still degrades fail-open.\n */\nexport const readCachedFeatures = async (\n storage: WireOnboardingStorage,\n key: string,\n): Promise<CachedFeatures | undefined> => {\n let raw: string | null | undefined;\n try {\n raw = await withTimeout(storage.getItem(key), READ_TIMEOUT_MS);\n } catch {\n return undefined;\n }\n if (!raw) return undefined;\n try {\n const parsed: unknown = JSON.parse(raw);\n if (parsed && typeof parsed === \"object\" && typeof (parsed as { ts?: unknown }).ts === \"number\") {\n const ts = (parsed as { ts: number }).ts;\n return {\n features: parseWireFeatures((parsed as { features?: unknown }).features),\n ageMs: Date.now() - ts,\n };\n }\n } catch {\n // Corrupt entry → treat as absent; the caller falls back to defaults / a fresh fetch.\n }\n return undefined;\n};\n\n/** Persist `{ features, ts }` under `key` — fire-and-forget, all errors swallowed. */\nexport const writeCachedFeatures = (\n storage: WireOnboardingStorage,\n key: string,\n features: WireFeatures,\n): void => {\n try {\n void storage\n .setItem(key, JSON.stringify({ features, ts: Date.now() }))\n .catch(() => {});\n } catch {\n // Best-effort: a failed write just means the next launch has no cache to fall back to.\n }\n};\n","/**\n * fetchWireFeatures — read the per-module kill switches from `GET {serverUrl}/v1/features`.\n *\n * Contract (server: chohra-med/wireai-onboarding-server, routers/onboarding.py):\n * GET {serverUrl}/v1/features\n * Authorization: Bearer {apiKey}\n * 200 → { coachmarks:{enabled}, showcase:{enabled}, onboarding:{mode}, review:{enabled},\n * announcements:{enabled} } (Cache-Control: private, max-age=300)\n *\n * THE CONTRACT — fail-open, never fail-dark. Unreachable, timed-out, unauthorized (401),\n * server-error (5xx), or malformed JSON all resolve to the LAST CACHED value, else the\n * all-on defaults. No throw ever reaches the host: this is timeout-capped and swallows every\n * error, exactly like the session's best-effort reads. A control-plane outage can only ever be\n * MORE permissive than the dashboard intends — it can never dark a tenant's activation.\n */\nimport { readCachedFeatures, featuresCacheKey, writeCachedFeatures } from \"./cache\";\nimport { defaultWireFeatures, parseWireFeatures } from \"./defaults\";\nimport type { WireFeatures, WireFeaturesConfig } from \"./types\";\nimport type { WireOnboardingStorage } from \"../session/persistedSession\";\n\nconst DEFAULT_TIMEOUT_MS = 4_000;\n\n/** The fail-open fallback: last cached value (any age — stale-while-error), else defaults. */\nconst failOpen = async (\n storage: WireOnboardingStorage | undefined,\n key: string,\n): Promise<WireFeatures> => {\n if (!storage) return defaultWireFeatures;\n const cached = await readCachedFeatures(storage, key);\n return cached?.features ?? defaultWireFeatures;\n};\n\n/** GET with a hard timeout via AbortController (falls back to no-abort where unsupported). */\nconst fetchWithTimeout = async (\n url: string,\n apiKey: string,\n timeoutMs: number,\n): Promise<Response> => {\n const controller =\n typeof AbortController !== \"undefined\" ? new AbortController() : undefined;\n const timer = setTimeout(() => controller?.abort(), timeoutMs);\n try {\n return await fetch(url, {\n method: \"GET\",\n headers: { Accept: \"application/json\", Authorization: `Bearer ${apiKey}` },\n signal: controller?.signal,\n });\n } finally {\n clearTimeout(timer);\n }\n};\n\n/**\n * Resolve the tenant's feature flags. Attempts the network once; on ANY failure returns the\n * cached value (any age), else the all-on defaults. On success, persists the fresh value to the\n * cache (fire-and-forget) and returns it. Never throws.\n *\n * const flags = await fetchWireFeatures({ serverUrl, apiKey, appId, storage });\n * if (!flags.coachmarks.enabled) { /* skip the tour * / }\n */\nexport const fetchWireFeatures = async (\n config?: WireFeaturesConfig,\n): Promise<WireFeatures> => {\n const key = featuresCacheKey(config?.appId);\n const storage = config?.storage;\n\n // Nothing to fetch (no creds) → cache, else defaults. Lets a host mount the provider before\n // its config is ready without ever darking.\n if (!config?.serverUrl || !config?.apiKey) return failOpen(storage, key);\n\n const url = `${config.serverUrl.replace(/\\/$/, \"\")}/v1/features`;\n const timeoutMs = config.timeoutMs && config.timeoutMs > 0 ? config.timeoutMs : DEFAULT_TIMEOUT_MS;\n\n try {\n const res = await fetchWithTimeout(url, config.apiKey, timeoutMs);\n // 401 (bad/rotated key), 5xx, any non-2xx → last-known, never dark.\n if (!res || !res.ok) return failOpen(storage, key);\n const json: unknown = await res.json(); // throws on malformed body → caught below\n const features = parseWireFeatures(json);\n if (storage) writeCachedFeatures(storage, key, features);\n return features;\n } catch {\n // Timeout/abort, network error, missing fetch, or malformed JSON — all fail open.\n return failOpen(storage, key);\n }\n};\n","/**\n * useWireFeatures — resolve the tenant's feature flags for a component tree, once per mount.\n *\n * Returns the all-on defaults immediately (fail-open), then swaps to the fetched value when the\n * network resolves. When no `serverUrl`+`apiKey` is supplied it never fetches and just returns\n * defaults, so a host that never adopts flags sees ZERO behavior change and ZERO network calls.\n *\n * frequent_rules #11 (unstable inline props): the config is idiomatically passed inline\n * (`config={{ serverUrl, apiKey }}`), a fresh identity every render. We stabilize the fetch key\n * by VALUE so the effect fires once per real credential change, and we only swap the returned\n * flags object when its VALUES change — so a host that lists the returned flags in an effect dep\n * array settles in a bounded number of commits instead of looping (enforced by the canary suite).\n */\nimport { useEffect, useRef, useState } from \"react\";\n\nimport { defaultWireFeatures, featuresEqual } from \"./defaults\";\nimport { fetchWireFeatures } from \"./fetchWireFeatures\";\nimport type { WireFeatures, WireFeaturesConfig } from \"./types\";\n\n/** Hold a stable reference for a value while its CONTENT is unchanged (see reviews/equality.ts). */\nconst useStableValue = <T,>(value: T, isEqual: (a: T, b: T) => boolean): T => {\n const ref = useRef(value);\n if (!isEqual(ref.current, value)) ref.current = value;\n return ref.current;\n};\n\n/** The credential slice that actually drives a refetch — stabilized by value. */\nconst sameFetchKey = (a: WireFeaturesConfig | undefined, b: WireFeaturesConfig | undefined): boolean =>\n a?.serverUrl === b?.serverUrl && a?.apiKey === b?.apiKey && a?.appId === b?.appId;\n\nexport const useWireFeatures = (config?: WireFeaturesConfig): WireFeatures => {\n const stableConfig = useStableValue(config, sameFetchKey);\n const [flags, setFlags] = useState<WireFeatures>(defaultWireFeatures);\n\n const canFetch = !!stableConfig?.serverUrl && !!stableConfig?.apiKey;\n\n useEffect(() => {\n if (!canFetch) {\n // No creds → stay on the all-on defaults (and reset if creds were removed).\n setFlags((prev) => (featuresEqual(prev, defaultWireFeatures) ? prev : defaultWireFeatures));\n return;\n }\n let alive = true;\n // fetchWireFeatures never throws — the .then always runs with a fail-open value.\n void fetchWireFeatures(stableConfig).then((next) => {\n if (!alive) return;\n // Only adopt a NEW reference on a real value change, so a host effect keyed on the\n // returned flags doesn't loop (frequent_rules #11).\n setFlags((prev) => (featuresEqual(prev, next) ? prev : next));\n });\n return () => {\n alive = false;\n };\n }, [canFetch, stableConfig]);\n\n return flags;\n};\n","/**\n * WireFeaturesProvider + useResolvedFeatures — the OPTIONAL one-fetch-serves-all-modules layer.\n *\n * Mount `WireFeaturesProvider` once near your app root with the tenant `config` and it fetches the\n * flags ONCE; every gated surface below it (coachmarks / showcase / reviews) reads the same\n * resolved value from context instead of each fetching its own. It is entirely optional: with no\n * provider, every surface falls back to its own lazy fetch (when given a config) or to the all-on\n * defaults, so modules work with zero setup and a host that never adopts flags is unchanged.\n *\n * NOTE on the built npm subpaths: React context is shared across the kit's subpath entries in the\n * SOURCE-consumption path (the monorepo apps) and in this test suite — one module instance, one\n * context. If you consume the built `wireai-onboarding/*` subpaths as separate bundles, pass the\n * resolved flags (or a `featuresConfig`) to each surface explicitly instead of relying on context.\n */\nimport React, { createContext, useContext, useMemo } from \"react\";\n\nimport { defaultWireFeatures } from \"./defaults\";\nimport { useWireFeatures } from \"./useWireFeatures\";\nimport type { WireFeatures, WireFeaturesConfig } from \"./types\";\n\n/** null = no provider mounted (the signal `useResolvedFeatures` uses to fall back). */\nconst WireFeaturesContext = createContext<WireFeatures | null>(null);\n\nexport interface WireFeaturesProviderProps {\n /** Tenant creds (+ optional storage) to fetch the flags once for the whole tree. */\n config?: WireFeaturesConfig;\n /**\n * Pre-resolved flags to provide directly instead of fetching (e.g. you already have them, or\n * you drive them from your own remote-config). Takes precedence over `config`.\n */\n flags?: WireFeatures;\n children: React.ReactNode;\n}\n\n/**\n * Fetch (or accept) the flags once and broadcast them to descendants. The provider VALUE is\n * memoized (performance rule #6) so a fresh object each render doesn't re-render every consumer.\n */\nexport const WireFeaturesProvider: React.FC<WireFeaturesProviderProps> = ({\n config,\n flags,\n children,\n}) => {\n // Always call the hook (rules of hooks); when `flags` is supplied we pass no config so it\n // never fetches and the explicit flags win below.\n const fetched = useWireFeatures(flags ? undefined : config);\n const value = flags ?? fetched;\n const stable = useMemo(() => value, [value]);\n return <WireFeaturesContext.Provider value={stable}>{children}</WireFeaturesContext.Provider>;\n};\n\nWireFeaturesProvider.displayName = \"WireFeaturesProvider\";\n\n/** Raw context read — `null` when no `WireFeaturesProvider` is mounted above. */\nexport const useWireFeaturesContext = (): WireFeatures | null =>\n useContext(WireFeaturesContext);\n\n/** Options for `useResolvedFeatures`: an explicit override and/or a lazy-fetch config. */\nexport interface ResolveFeaturesOptions {\n /** Explicit flags — win over everything (a surface's own `features` prop). */\n flags?: WireFeatures;\n /** Lazy-fetch config, used ONLY when there is no explicit `flags` and no provider above. */\n config?: WireFeaturesConfig;\n}\n\n/**\n * The resolution every gated surface uses. Precedence:\n * 1. explicit `options.flags` (a surface's own prop) →\n * 2. the nearest `WireFeaturesProvider` (context) →\n * 3. a lazy fetch from `options.config` (serverUrl + apiKey) →\n * 4. the all-on defaults.\n * Always fail-open, always a stable reference for a given value (so it's safe in effect deps).\n */\nexport const useResolvedFeatures = (options?: ResolveFeaturesOptions): WireFeatures => {\n const ctx = useWireFeaturesContext();\n // Only lazily fetch when nothing else provides the flags — otherwise pass no config so the\n // hook stays inert (defaults, no network). The hook is always called (rules of hooks).\n const shouldFetch = !options?.flags && ctx == null;\n const fetched = useWireFeatures(shouldFetch ? options?.config : undefined);\n return options?.flags ?? ctx ?? fetched ?? defaultWireFeatures;\n};\n","/**\n * Module-level runtime for the coachmark engine: the injected sync storage, the\n * global `isTestingCoachmark` flag, and the seen-gate helpers built on top.\n *\n * WHY module singletons (not just context): the tour hooks and the anchor\n * registry are driven imperatively from anywhere in the tree (a screen deep\n * under the navigator), while the storage + testing flag are configured once at\n * the root by `CoachmarkProvider`. Singletons let a hook read the gate without\n * every call site threading the storage through props. The provider is still the\n * single writer — it calls `setCoachmarkStorage` / `setCoachmarkTesting` on mount.\n */\nimport type { CoachmarkStorage } from \"./types\";\n\nlet storageSingleton: CoachmarkStorage | null = null;\nlet testing = false;\n// The coachmarks feature kill switch (from GET /v1/features). Default true = fail-open: with no\n// flags fetched, coachmarks behave exactly as before. CoachmarkProvider writes it from the\n// resolved flags. Disabled → the tour never ARMS and the overlay `show()` is a no-op, so nothing\n// paints and — critically — no once-gate is written, so re-enabling replays the tour correctly.\nlet coachmarksEnabled = true;\n\n/**\n * Set the coachmarks master switch (from the resolved feature flags). Default true (fail-open).\n * Written by CoachmarkProvider; read imperatively by the tour arm + the overlay store.\n */\nexport const setCoachmarksEnabled = (value: boolean): void => {\n coachmarksEnabled = value;\n};\n\n/** Whether the coachmarks module is enabled. False → tours/overlays are silently skipped. */\nexport const areCoachmarksEnabled = (): boolean => coachmarksEnabled;\n\n/** Set (or clear) the injected sync gate storage. Called by CoachmarkProvider. */\nexport const setCoachmarkStorage = (storage: CoachmarkStorage | null): void => {\n storageSingleton = storage;\n};\n\n/** The currently-injected gate storage, or null if no provider is mounted. */\nexport const getCoachmarkStorage = (): CoachmarkStorage | null => storageSingleton;\n\n/**\n * Toggle the global QA replay flag. When true, EVERY seen-gate reads as unseen\n * and every seen-write is suppressed, so every tour + showcase replays on each\n * mount. The app flips ONE boolean to QA the whole coachmark surface.\n */\nexport const setCoachmarkTesting = (value: boolean): void => {\n testing = value;\n};\n\n/** Whether replay-everything QA mode is on. */\nexport const isCoachmarkTesting = (): boolean => testing;\n\n/** Gate key for a tour: `wire_coachmark_<tourId>_seen`. */\nexport const coachmarkGateKey = (tourId: string): string =>\n `wire_coachmark_${tourId}_seen`;\n\n/** Gate key for a feature showcase: `wire_showcase_<id>_seen`. */\nexport const showcaseGateKey = (showcaseId: string): string =>\n `wire_showcase_${showcaseId}_seen`;\n\n/** Marker value written for a seen gate. */\nconst SEEN_VALUE = \"1\";\n\n/**\n * Read a seen gate. Testing mode ALWAYS reports unseen (so everything replays).\n * A missing storage (no provider) also reports unseen — the safe default is to\n * show the hint rather than silently swallow it. `storageOverride` /\n * `testingOverride` let a self-contained component (e.g. FeatureShowcase) pass\n * its own storage without relying on the provider singleton.\n */\nexport const hasSeenGate = (\n key: string,\n storageOverride?: CoachmarkStorage | null,\n testingOverride?: boolean,\n): boolean => {\n if (testingOverride ?? testing) return false;\n const storage = storageOverride ?? storageSingleton;\n if (!storage) return false;\n try {\n return storage.getItem(key) === SEEN_VALUE;\n } catch {\n return false;\n }\n};\n\n/**\n * Mark a gate seen. Suppressed in testing mode (so replay never persists) and a\n * no-op without storage. Best-effort — a throwing adapter never breaks the tour.\n */\nexport const markSeenGate = (\n key: string,\n storageOverride?: CoachmarkStorage | null,\n testingOverride?: boolean,\n): void => {\n if (testingOverride ?? testing) return;\n const storage = storageOverride ?? storageSingleton;\n if (!storage) return;\n try {\n storage.setItem(key, SEEN_VALUE);\n } catch {\n // Best-effort: a failed write just means the hint may show once more.\n }\n};\n","import { useSyncExternalStore } from \"react\";\n\nimport { areCoachmarksEnabled } from \"./runtime\";\nimport type { GestureKind, Placement, TargetRect } from \"./types\";\n\n/**\n * A tiny module-level store for the single active coachmark overlay. The host\n * (CoachmarkOverlayHost, mounted once by CoachmarkProvider at the app root)\n * subscribes and renders whatever is active; the tour controller drives it\n * imperatively via show()/hide(). No React context is needed for the overlay\n * itself — the host reaches the root so the ring can paint above the tab bar.\n *\n * Only ONE overlay is ever active (steps never stack), per the engine's\n * one-overlay-at-a-time rule.\n */\nexport interface CoachmarkOverlayState {\n message: string;\n targetRect: TargetRect | null;\n gesture: GestureKind;\n placement: Placement;\n onEngage: () => void;\n onDismiss: () => void;\n}\n\nlet current: CoachmarkOverlayState | null = null;\nconst listeners = new Set<() => void>();\n\nconst emit = () => {\n for (const listener of listeners) listener();\n};\n\nexport const coachmarkOverlay = {\n show(state: CoachmarkOverlayState) {\n // Feature kill switch: when coachmarks are disabled, a show() request is a silent no-op —\n // no ring paints, and because nothing shows the user can't advance/dismiss a tour, so no\n // once-gate is ever written and re-enabling replays it. hide() still works (see below).\n if (!areCoachmarksEnabled()) return;\n current = state;\n emit();\n },\n hide() {\n if (current === null) return;\n current = null;\n emit();\n },\n subscribe(listener: () => void) {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n getSnapshot(): CoachmarkOverlayState | null {\n return current;\n },\n};\n\n/** Subscribe a component to the active overlay (or null). */\nexport const useCoachmarkOverlay = (): CoachmarkOverlayState | null =>\n useSyncExternalStore(\n coachmarkOverlay.subscribe,\n coachmarkOverlay.getSnapshot,\n coachmarkOverlay.getSnapshot,\n );\n","/**\n * defaultOnboardingTheme — a neutral, light, brand-agnostic baseline. Consumers\n * pass a `Partial<OnboardingTheme>` that is deep-merged over this (see\n * `mergeTheme`), so they only override what differs from neutral.\n */\nimport type { OnboardingTheme } from \"./types\";\n\nexport const defaultOnboardingTheme: OnboardingTheme = {\n colors: {\n background: \"#FFFFFF\",\n surface: \"#F7F7F8\",\n text: \"#101114\",\n textMuted: \"#6B7280\",\n primary: \"#111111\",\n onPrimary: \"#FFFFFF\",\n primarySoft: \"rgba(17,17,17,0.06)\",\n border: \"#E4E4E7\",\n borderStrong: \"#C7C7CC\",\n disabled: \"#EBEBEB\",\n success: \"#16A34A\",\n warning: \"#D97706\",\n error: \"#DC2626\",\n info: \"#2563EB\",\n },\n fonts: {\n regular: undefined,\n medium: undefined,\n bold: undefined,\n baseSize: 16,\n scale: 1,\n },\n radius: {\n sm: 8,\n md: 12,\n lg: 16,\n full: 9999,\n },\n spacing: {\n xs: 4,\n sm: 8,\n md: 16,\n lg: 24,\n xl: 32,\n },\n // Circled (pill) CTA by default; an app can pass `button: { radius: 12 }` for\n // a rounded rectangle, or override height/paddingX to match its design system.\n button: {\n radius: 9999,\n height: 52,\n paddingX: 24,\n },\n};\n\n/**\n * Deep-merge a partial theme over the default. Two levels deep is enough — the\n * theme is intentionally shallow (colors/fonts/radius/spacing), so we merge each\n * known sub-object and leave scalars to overwrite.\n */\nexport const mergeTheme = (\n override?: Partial<OnboardingTheme>,\n): OnboardingTheme => {\n if (!override) return defaultOnboardingTheme;\n return {\n colors: { ...defaultOnboardingTheme.colors, ...override.colors },\n fonts: { ...defaultOnboardingTheme.fonts, ...override.fonts },\n radius: { ...defaultOnboardingTheme.radius, ...override.radius },\n spacing: { ...defaultOnboardingTheme.spacing, ...override.spacing },\n button: { ...defaultOnboardingTheme.button, ...override.button },\n };\n};\n","/**\n * ThemeContext — provides the resolved OnboardingTheme to every shell element and\n * themed card via `useOnboardingTheme()`. WHY a context rather than prop-drilling:\n * the cards are mounted by the SDK's ComponentRenderer (not by us), so we can't\n * pass them props directly — they must read the theme from context.\n */\nimport React, { createContext, useContext, useMemo } from \"react\";\nimport { mergeTheme } from \"./defaultTheme\";\nimport type { OnboardingTheme } from \"./types\";\n\nconst OnboardingThemeContext = createContext<OnboardingTheme | null>(null);\n\nexport type OnboardingThemeProviderProps = {\n /** Partial overrides merged over the neutral default theme. */\n theme?: Partial<OnboardingTheme>;\n children: React.ReactNode;\n};\n\nexport const OnboardingThemeProvider: React.FC<OnboardingThemeProviderProps> = ({\n theme,\n children,\n}) => {\n const resolved = useMemo(() => mergeTheme(theme), [theme]);\n return (\n <OnboardingThemeContext.Provider value={resolved}>\n {children}\n </OnboardingThemeContext.Provider>\n );\n};\n\n/**\n * Read the active theme. Falls back to the default theme when used outside a\n * provider so a stray card never crashes — it just renders neutral.\n */\nexport const useOnboardingTheme = (): OnboardingTheme => {\n const ctx = useContext(OnboardingThemeContext);\n return ctx ?? mergeTheme();\n};\n","import React, { useEffect, useMemo, type ReactNode } from \"react\";\nimport { StyleSheet, View } from \"react-native\";\nimport Animated, {\n useAnimatedStyle,\n useReducedMotion,\n useSharedValue,\n withDelay,\n withRepeat,\n withSequence,\n withTiming,\n} from \"react-native-reanimated\";\n\nimport type { GestureKind } from \"./types\";\n\n/**\n * Abstract gesture pictogram shown beside a coachmark tooltip. Pure reanimated —\n * every animation runs on the UI thread (shared values + worklets), never\n * setState, so it costs nothing on the JS thread. Honors Reduce Motion by\n * dropping the motion loop and rendering the glyph static.\n *\n * NO drawn-hand anatomy. Swipes render the standard two-finger swipe glyph: two\n * rounded vertical capsules (an abstract index + middle finger, slightly\n * different heights) with a short, fading motion track trailing behind them along\n * the swipe axis. The whole glyph is rotated per direction (up/down/left/right)\n * and the capsules slide along the axis, fading, in a UI-thread loop. Pinch/zoom\n * reuse the two-capsule abstraction spreading apart. Tap / double-tap render a\n * minimal pulsing tap-target (ring + dot).\n *\n * Every glyph is a self-drawn primitive built from Views/borders (no vector-icon\n * dependency, like AnimatedSparkle). Pass `renderHand` — the glyph slot — to\n * substitute your own node while keeping the tuned motion. (The name is kept for\n * backward compatibility; despite it, the default is a glyph, not a drawn hand.)\n *\n * NOTE: the coachmark path (SpotlightOverlay) and the showcase path\n * (FeatureShowcase) both SKIP this component for `tap` / `double_tap` — those\n * steps show only the highlight ring + tooltip, no glyph. The tap visual here\n * exists for direct / standalone use.\n */\nexport interface GestureHintProps {\n type: GestureKind;\n /** Overall glyph size in px. */\n size?: number;\n /** Glyph color. Defaults to white (reads on the dark blur backdrop). */\n color?: string;\n /**\n * Provide a custom glyph node in place of the default self-drawn primitive; it\n * inherits the tuned motion (slide+fade for swipes, pulse for tap). Kept as\n * `renderHand` for backward compatibility — despite the name it is just the\n * glyph slot, no longer a drawn hand.\n */\n renderHand?: (props: { size: number; color: string }) => ReactNode;\n}\n\n/** Travel distance for the directional swipe loop (local glyph axis). */\nconst TRAVEL = 26;\nconst SWIPE_MS = 700;\nconst TAP_MS = 320;\nconst SPREAD_MS = 620;\n\n/**\n * Per-direction rotation of the whole glyph. Canonical orientation is \"up\":\n * capsules point up, travel up, motion track trailing below. Rotating the\n * container reorients both the capsules and the track together, and rotates the\n * local translate axis so the same upward loop reads correctly per direction.\n */\nconst GLYPH_ROTATION: Record<string, string> = {\n swipe_up: \"0deg\",\n swipe_down: \"180deg\",\n swipe_left: \"-90deg\",\n swipe_right: \"90deg\",\n};\n\n/**\n * The two-finger abstraction: two rounded vertical capsules side by side with\n * slightly different heights (index taller than middle), aligned at the base —\n * the standard swipe pictogram look. Self-drawn from Views only.\n */\nconst FingerPair: React.FC<{ size: number; color: string }> = ({ size, color }) => {\n const { row, index, middle } = useMemo(() => {\n const w = size * 0.2;\n const r = w / 2;\n return {\n row: { flexDirection: \"row\" as const, alignItems: \"flex-end\" as const, gap: size * 0.08 },\n index: { width: w, height: size * 0.54, borderRadius: r, backgroundColor: color },\n middle: { width: w, height: size * 0.44, borderRadius: r, backgroundColor: color },\n };\n }, [size, color]);\n\n return (\n <View style={row} pointerEvents=\"none\">\n <View style={index} />\n <View style={middle} />\n </View>\n );\n};\n\n/**\n * A short, tapering motion track that sits behind the capsules (below, in the\n * canonical \"up\" orientation) — two slim, fading ticks that shrink and dim with\n * distance. Subtle: it reads as the path the fingers just travelled, not a comet\n * tail. Static (the capsules carry the motion via the slide loop).\n */\nconst MotionTrack: React.FC<{ size: number; color: string }> = ({ size, color }) => {\n const { wrap, tick0, tick1 } = useMemo(() => {\n const h = Math.max(2, size * 0.05);\n return {\n wrap: { alignItems: \"center\" as const, marginTop: size * 0.1, gap: size * 0.06 },\n tick0: {\n width: size * 0.3,\n height: h,\n borderRadius: h / 2,\n backgroundColor: color,\n opacity: 0.4,\n },\n tick1: {\n width: size * 0.18,\n height: h,\n borderRadius: h / 2,\n backgroundColor: color,\n opacity: 0.16,\n },\n };\n }, [size, color]);\n\n return (\n <View style={wrap} pointerEvents=\"none\">\n <View style={tick0} />\n <View style={tick1} />\n </View>\n );\n};\n\nconst GestureHintComponent: React.FC<GestureHintProps> = ({\n type,\n size = 34,\n color = \"white\",\n renderHand,\n}) => {\n const translate = useSharedValue(0);\n const opacity = useSharedValue(1);\n const pulse = useSharedValue(1);\n const spread = useSharedValue(0);\n const reduced = useReducedMotion();\n\n const isSwipe =\n type === \"swipe_up\" ||\n type === \"swipe_down\" ||\n type === \"swipe_left\" ||\n type === \"swipe_right\";\n const isSpread = type === \"pinch\" || type === \"zoom\";\n const isTap = type === \"tap\" || type === \"double_tap\";\n\n useEffect(() => {\n if (type === \"none\" || reduced) return undefined;\n\n if (isTap) {\n pulse.value = withRepeat(\n withSequence(\n withTiming(0.82, { duration: TAP_MS }),\n withTiming(1, { duration: TAP_MS }),\n ),\n -1,\n false,\n );\n opacity.value = withRepeat(\n withSequence(\n withTiming(0.55, { duration: TAP_MS }),\n withTiming(1, { duration: TAP_MS }),\n ),\n -1,\n false,\n );\n return undefined;\n }\n\n if (isSpread) {\n // Two capsules easing apart and back — a minimal pinch/zoom abstraction.\n spread.value = withRepeat(\n withSequence(\n withTiming(size * 0.26, { duration: SPREAD_MS }),\n withTiming(0, { duration: SPREAD_MS }),\n ),\n -1,\n false,\n );\n return undefined;\n }\n\n // Directional swipe: slide the capsules along the local \"up\" axis, fading\n // out, then snap back and repeat. The container rotation (below) reorients\n // this loop per direction, so the local motion is always the same.\n translate.value = withRepeat(\n withSequence(\n withTiming(0, { duration: 0 }),\n withTiming(-TRAVEL, { duration: SWIPE_MS }),\n withDelay(140, withTiming(0, { duration: 0 })),\n ),\n -1,\n false,\n );\n opacity.value = withRepeat(\n withSequence(\n withTiming(1, { duration: SWIPE_MS / 2 }),\n withTiming(0, { duration: SWIPE_MS / 2 }),\n withDelay(140, withTiming(1, { duration: 0 })),\n ),\n -1,\n false,\n );\n return undefined;\n }, [type, reduced, isTap, isSpread, translate, opacity, pulse, spread, size]);\n\n const swipeAnimatedStyle = useAnimatedStyle(() => ({\n opacity: opacity.value,\n transform: [{ translateY: translate.value }],\n }));\n const tapAnimatedStyle = useAnimatedStyle(() => ({\n opacity: opacity.value,\n transform: [{ scale: pulse.value }],\n }));\n const spreadLeftStyle = useAnimatedStyle(() => ({\n transform: [{ translateX: -spread.value }],\n }));\n const spreadRightStyle = useAnimatedStyle(() => ({\n transform: [{ translateX: spread.value }],\n }));\n\n if (type === \"none\") return null;\n\n const customGlyph = renderHand ? renderHand({ size, color }) : null;\n\n if (isSwipe) {\n return (\n <View\n style={{ transform: [{ rotate: GLYPH_ROTATION[type] ?? \"0deg\" }] }}\n pointerEvents=\"none\"\n >\n <View style={styles.swipeStack}>\n <Animated.View style={swipeAnimatedStyle} pointerEvents=\"none\">\n {customGlyph ?? <FingerPair size={size} color={color} />}\n </Animated.View>\n <MotionTrack size={size} color={color} />\n </View>\n </View>\n );\n }\n\n if (isSpread) {\n const w = size * 0.2;\n const capsule = {\n width: w,\n height: size * 0.5,\n borderRadius: w / 2,\n backgroundColor: color,\n };\n return (\n <View style={[styles.spreadRow, { gap: size * 0.12 }]} pointerEvents=\"none\">\n <Animated.View style={spreadLeftStyle}>\n <View style={capsule} />\n </Animated.View>\n <Animated.View style={spreadRightStyle}>\n <View style={capsule} />\n </Animated.View>\n </View>\n );\n }\n\n // tap / double_tap — a minimal pulsing tap-target (ring + center dot).\n const ringSize = size * 0.86;\n const ringBorder = Math.max(2, size * 0.08);\n const dotSize = size * 0.32;\n return (\n <View style={[styles.tapWrap, { width: size, height: size }]} pointerEvents=\"none\">\n {customGlyph ? (\n <Animated.View style={tapAnimatedStyle} pointerEvents=\"none\">\n {customGlyph}\n </Animated.View>\n ) : (\n <>\n <Animated.View\n style={[\n styles.tapRing,\n {\n width: ringSize,\n height: ringSize,\n borderRadius: ringSize / 2,\n borderWidth: ringBorder,\n borderColor: color,\n },\n tapAnimatedStyle,\n ]}\n pointerEvents=\"none\"\n />\n <View\n style={{\n position: \"absolute\",\n width: dotSize,\n height: dotSize,\n borderRadius: dotSize / 2,\n backgroundColor: color,\n }}\n />\n </>\n )}\n </View>\n );\n};\n\nconst styles = StyleSheet.create({\n swipeStack: {\n alignItems: \"center\",\n justifyContent: \"center\",\n },\n spreadRow: {\n flexDirection: \"row\",\n alignItems: \"center\",\n justifyContent: \"center\",\n },\n tapWrap: {\n alignItems: \"center\",\n justifyContent: \"center\",\n },\n tapRing: {\n backgroundColor: \"transparent\",\n },\n});\n\nexport const GestureHint = React.memo(GestureHintComponent);\nGestureHint.displayName = \"GestureHint\";\n\nexport default GestureHint;\n","import { BlurView } from \"expo-blur\";\nimport React, { useEffect, useMemo } from \"react\";\nimport {\n Pressable,\n StyleSheet,\n Text,\n useWindowDimensions,\n View,\n} from \"react-native\";\nimport Animated, {\n FadeIn,\n FadeOut,\n useAnimatedProps,\n useAnimatedStyle,\n useReducedMotion,\n useSharedValue,\n withRepeat,\n withSequence,\n withTiming,\n} from \"react-native-reanimated\";\n\nimport { useOnboardingTheme } from \"../theme/ThemeContext\";\nimport { GestureHint } from \"./GestureHint\";\nimport type { GestureKind, Placement, TargetRect } from \"./types\";\n\nconst AnimatedBlurView = Animated.createAnimatedComponent(BlurView);\n\nconst BLUR_INTENSITY = 26;\nconst FADE_MS = 280;\n/** Breathing room between the highlighted element and the glowing ring. */\nconst RING_PADDING = 10;\n/** Gap between the ring and the tooltip pill. */\nconst TOOLTIP_GAP = 14;\nconst SIDE_MARGIN = 20;\nconst PILL_MAX_WIDTH = 260;\n\nexport interface SpotlightOverlayProps {\n message: string;\n /** Window-space rect of the element to highlight. Null → centered hint (e.g. a scroll gesture). */\n targetRect?: TargetRect | null;\n gesture?: GestureKind;\n placement?: Placement;\n /** Tapping the highlighted target or the pill — advance / act. */\n onEngage: () => void;\n /** Tapping the dimmed backdrop — advance to the next step (ends the tour only on the last step). */\n onDismiss: () => void;\n /** Ring + tooltip color. Defaults to the onboarding theme's `primary`. */\n accentColor?: string;\n /** Tooltip label color. Defaults to the theme's `onPrimary`. */\n accentTextColor?: string;\n}\n\n/**\n * A single coachmark step: the whole screen is frosted with an animated blur,\n * and a bright pulsing ring + tooltip point at one measured target. Mounted at\n * the app root (above the tab bar) via CoachmarkOverlayHost.\n *\n * Performance: one BlurView (mounted only while a step is visible), the ring\n * glow is a single reanimated view, and all animation runs on the UI thread.\n * Reduce Motion drops the pulse.\n */\nconst SpotlightOverlayComponent: React.FC<SpotlightOverlayProps> = ({\n message,\n targetRect,\n gesture = \"none\",\n placement = \"bottom\",\n onEngage,\n onDismiss,\n accentColor,\n accentTextColor,\n}) => {\n const { height: screenH } = useWindowDimensions();\n const reduced = useReducedMotion();\n const theme = useOnboardingTheme();\n\n const accent = accentColor ?? theme.colors.primary;\n const accentText = accentTextColor ?? theme.colors.onPrimary;\n\n // Tap / double-tap steps show ONLY the ring + tooltip — no gesture glyph. The\n // pulsing highlight ring already reads as \"tap here\", so an extra glyph is\n // noise. Every app inherits this centrally, with no config change.\n const showGesture =\n gesture !== \"none\" && gesture !== \"tap\" && gesture !== \"double_tap\";\n\n const intensity = useSharedValue(0);\n const ringScale = useSharedValue(1);\n\n useEffect(() => {\n intensity.value = withTiming(BLUR_INTENSITY, { duration: FADE_MS });\n }, [intensity]);\n\n useEffect(() => {\n if (reduced) return;\n ringScale.value = withRepeat(\n withSequence(\n withTiming(1.06, { duration: 700 }),\n withTiming(1, { duration: 700 }),\n ),\n -1,\n true,\n );\n }, [reduced, ringScale]);\n\n const blurAnimatedProps = useAnimatedProps(() => ({\n intensity: intensity.value,\n }));\n\n const ringAnimatedStyle = useAnimatedStyle(() => ({\n transform: [{ scale: ringScale.value }],\n }));\n\n // Geometry for the ring + tooltip, derived from the measured target.\n const geometry = useMemo(() => {\n if (!targetRect) return null;\n const ringLeft = targetRect.x - RING_PADDING;\n const ringTop = targetRect.y - RING_PADDING;\n const ringW = targetRect.width + RING_PADDING * 2;\n const ringH = targetRect.height + RING_PADDING * 2;\n return {\n ring: {\n left: ringLeft,\n top: ringTop,\n width: ringW,\n height: ringH,\n borderRadius: Math.min(ringW, ringH) / 2,\n },\n // Tooltip above or below the ring depending on placement.\n tooltip:\n placement === \"top\"\n ? { bottom: screenH - ringTop + TOOLTIP_GAP }\n : { top: ringTop + ringH + TOOLTIP_GAP },\n };\n }, [targetRect, placement, screenH]);\n\n return (\n <Animated.View\n style={[StyleSheet.absoluteFill, styles.root]}\n entering={FadeIn.duration(FADE_MS)}\n exiting={FadeOut.duration(FADE_MS)}\n >\n <AnimatedBlurView\n tint=\"dark\"\n animatedProps={blurAnimatedProps}\n style={StyleSheet.absoluteFill}\n />\n\n {/* Tap-the-backdrop to move on (dismisses the tour on the last step). */}\n <Pressable\n style={StyleSheet.absoluteFill}\n onPress={onDismiss}\n accessibilityRole=\"button\"\n accessibilityLabel=\"Next hint\"\n />\n\n {/* Glowing ring over the highlighted target (tap = engage). */}\n {geometry && (\n <Animated.View\n style={[\n styles.ring,\n geometry.ring,\n { borderColor: accent, shadowColor: accent },\n ringAnimatedStyle,\n ]}\n pointerEvents=\"box-none\"\n >\n <Pressable\n style={StyleSheet.absoluteFill}\n onPress={onEngage}\n accessibilityRole=\"button\"\n accessibilityLabel={message}\n />\n </Animated.View>\n )}\n\n {/* Tooltip pill: anchored to the ring, or centered for a target-less hint. */}\n <View\n style={[\n styles.tooltipWrapper,\n geometry\n ? geometry.tooltip\n : { top: screenH * 0.42, alignItems: \"center\" },\n ]}\n pointerEvents=\"box-none\"\n >\n {showGesture && (\n <View style={styles.gestureSlot} pointerEvents=\"none\">\n <GestureHint type={gesture} color={accent} />\n </View>\n )}\n <Pressable\n onPress={onEngage}\n style={[styles.pill, { backgroundColor: accent }]}\n accessibilityRole=\"button\"\n accessibilityLabel={message}\n >\n <Text numberOfLines={3} style={[styles.pillText, { color: accentText }]}>\n {message}\n </Text>\n </Pressable>\n </View>\n </Animated.View>\n );\n};\n\nconst styles = StyleSheet.create({\n // High elevation/zIndex so the whole overlay (incl. the frosted blur) sits\n // above the bottom tab bar on Android, where sibling z-order follows\n // elevation, not tree order.\n root: {\n zIndex: 9999,\n elevation: 9999,\n },\n ring: {\n position: \"absolute\",\n borderWidth: 2.5,\n backgroundColor: \"transparent\",\n shadowOffset: { width: 0, height: 0 },\n shadowOpacity: 0.9,\n shadowRadius: 12,\n elevation: 10,\n },\n tooltipWrapper: {\n position: \"absolute\",\n left: SIDE_MARGIN,\n right: SIDE_MARGIN,\n alignItems: \"center\",\n gap: 10,\n },\n gestureSlot: {\n alignItems: \"center\",\n justifyContent: \"center\",\n },\n pill: {\n maxWidth: PILL_MAX_WIDTH,\n paddingVertical: 12,\n paddingHorizontal: 18,\n borderRadius: 18,\n shadowColor: \"#000\",\n shadowOffset: { width: 0, height: 2 },\n shadowOpacity: 0.25,\n shadowRadius: 6,\n elevation: 6,\n },\n pillText: {\n fontSize: 14,\n fontWeight: \"800\",\n textAlign: \"center\",\n },\n});\n\nexport const SpotlightOverlay = React.memo(SpotlightOverlayComponent);\nSpotlightOverlay.displayName = \"SpotlightOverlay\";\n\nexport default SpotlightOverlay;\n","import React from \"react\";\n\nimport { useCoachmarkOverlay } from \"./coachmarkOverlayStore\";\nimport { SpotlightOverlay } from \"./SpotlightOverlay\";\n\nexport interface CoachmarkOverlayHostProps {\n /** Ring/tooltip accent; defaults to the onboarding theme's `primary`. */\n accentColor?: string;\n /** Text/icon color on the accent surface; defaults to the theme's `onPrimary`. */\n accentTextColor?: string;\n}\n\n/**\n * Mounts once at the app root (rendered by CoachmarkProvider as a sibling of the\n * app tree) so the blur + spotlight paint OVER the bottom tab bar — which\n * react-navigation renders above screen components, out of reach of any\n * screen-level overlay. Renders nothing until a step is active.\n */\nconst CoachmarkOverlayHostComponent: React.FC<CoachmarkOverlayHostProps> = ({\n accentColor,\n accentTextColor,\n}) => {\n const active = useCoachmarkOverlay();\n\n if (!active) return null;\n\n return (\n <SpotlightOverlay\n message={active.message}\n targetRect={active.targetRect}\n gesture={active.gesture}\n placement={active.placement}\n onEngage={active.onEngage}\n onDismiss={active.onDismiss}\n accentColor={accentColor}\n accentTextColor={accentTextColor}\n />\n );\n};\n\nexport const CoachmarkOverlayHost = React.memo(CoachmarkOverlayHostComponent);\nCoachmarkOverlayHost.displayName = \"CoachmarkOverlayHost\";\n\nexport default CoachmarkOverlayHost;\n","import React, { useEffect } from \"react\";\n\nimport { useResolvedFeatures } from \"../features/WireFeaturesProvider\";\nimport type { WireFeatures, WireFeaturesConfig } from \"../features/types\";\nimport { CoachmarkOverlayHost } from \"./CoachmarkOverlayHost\";\nimport {\n getCoachmarkStorage,\n setCoachmarkStorage,\n setCoachmarksEnabled,\n setCoachmarkTesting,\n} from \"./runtime\";\nimport type { CoachmarkStorage } from \"./types\";\n\nexport interface CoachmarkProviderProps {\n /**\n * SYNCHRONOUS gate storage (MMKV-friendly). Reads must not be async or a ring\n * would flash before the \"already seen\" gate resolves. See CoachmarkStorage.\n */\n storage: CoachmarkStorage;\n /**\n * QA replay switch. When true, every seen-gate reads as unseen AND seen-writes\n * are suppressed, so every tour + showcase replays on each mount. Flip ONE\n * boolean to re-see the whole coachmark surface.\n */\n isTestingCoachmark?: boolean;\n /** Ring + tooltip color for every tour. Defaults to the onboarding theme's `primary`. */\n accentColor?: string;\n /**\n * Text/icon color on the accent surface (e.g. the tooltip's CTA label).\n * Defaults to the onboarding theme's `onPrimary`.\n */\n accentTextColor?: string;\n /**\n * OPTIONAL feature-flag wiring. When `flags.coachmarks.enabled` is false, every tour + overlay\n * request becomes a silent no-op (once-gates are NOT consumed, so re-enabling replays). Provide\n * pre-resolved `features`, OR a `featuresConfig` (serverUrl + apiKey) to lazily fetch once, OR\n * mount a `WireFeaturesProvider` above (context is read automatically). Omit all three and\n * coachmarks stay on (fail-open) — zero behavior change for hosts that never adopt flags.\n */\n features?: WireFeatures;\n /** Lazy-fetch config for the flags, used when `features` is absent and no provider is above. */\n featuresConfig?: WireFeaturesConfig;\n children: React.ReactNode;\n}\n\n/**\n * Mount ONCE at the app root — wrap it around (or just inside) your\n * NavigationContainer so the overlay host is a root-level sibling of the whole\n * app tree. That placement is what lets a ring + blur paint ABOVE the bottom tab\n * bar, which react-navigation renders over screen components.\n *\n * It feeds the sync storage + testing flag into the engine's module-level\n * singletons so `useCoachmarkTour` / `useCoachmarkAnchor` work from anywhere in\n * the tree without prop-drilling, then renders the overlay host as a sibling\n * after `children` (the SpotlightOverlay self-positions absolute-fill at\n * zIndex/elevation 9999).\n *\n * The singletons are set during render (not in an effect) so a child's mount\n * effect — which runs BEFORE this parent's effects — already sees the storage\n * when it reads its gate.\n */\nexport const CoachmarkProvider: React.FC<CoachmarkProviderProps> = ({\n storage,\n isTestingCoachmark = false,\n accentColor,\n accentTextColor,\n features,\n featuresConfig,\n children,\n}) => {\n // Resolve the coachmarks kill switch: explicit `features` → context → lazy fetch → all-on.\n const flags = useResolvedFeatures({ flags: features, config: featuresConfig });\n const coachmarksOn = flags.coachmarks.enabled;\n\n // Apply during render so gates + the kill switch are readable before any child effect fires.\n setCoachmarkStorage(storage);\n setCoachmarkTesting(isTestingCoachmark);\n setCoachmarksEnabled(coachmarksOn);\n\n useEffect(() => {\n setCoachmarkStorage(storage);\n setCoachmarkTesting(isTestingCoachmark);\n setCoachmarksEnabled(coachmarksOn);\n return () => {\n // Only clear if THIS provider's storage is still the live singleton — a\n // newer provider that mounted before this one unmounts must not be wiped.\n if (getCoachmarkStorage() === storage) {\n setCoachmarkStorage(null);\n }\n // Restore the fail-open default so a torn-down provider never leaves coachmarks dark.\n setCoachmarksEnabled(true);\n };\n }, [storage, isTestingCoachmark, coachmarksOn]);\n\n return (\n <>\n {children}\n <CoachmarkOverlayHost\n accentColor={accentColor}\n accentTextColor={accentTextColor}\n />\n </>\n );\n};\n\nCoachmarkProvider.displayName = \"CoachmarkProvider\";\n\nexport default CoachmarkProvider;\n","import type { TargetRect } from \"./types\";\n\n/**\n * Maps a coachmark anchor id → a function that measures that element's current\n * window rect. Elements register themselves on mount (via useCoachmarkAnchor)\n * and the tour controller resolves an id to a rect at the moment a step fires.\n *\n * This is the \"app declares WHERE\" half of the engine: the kit owns the\n * measuring/registry mechanics, each app decides which ids exist and pins them\n * to its own components.\n */\nexport type AnchorMeasurer = () => Promise<TargetRect | null>;\n\nconst anchors = new Map<string, AnchorMeasurer>();\n\n/**\n * NOTE: this registry is last-writer-wins — one measurer per id. An `anchorId`\n * MUST be unique across screens that can be mounted simultaneously; if two live\n * screens share an id, the second registration hides the first and unmount order\n * decides who survives. Scope ids per screen (e.g. `feed.filter_icon`) when a\n * component can appear in more than one mounted screen at once.\n */\nexport const coachmarkAnchors = {\n register(id: string, measurer: AnchorMeasurer) {\n anchors.set(id, measurer);\n },\n /**\n * Only clears the id when `measurer` is still the current registration, so a\n * screen unmounting after a newer screen registered the same id does not wipe\n * the live measurer. Omit `measurer` to force-delete regardless.\n */\n unregister(id: string, measurer?: AnchorMeasurer) {\n if (measurer !== undefined && anchors.get(id) !== measurer) return;\n anchors.delete(id);\n },\n get(id: string): AnchorMeasurer | undefined {\n return anchors.get(id);\n },\n /**\n * Resolve an anchor to a rect, retrying briefly while the target lays out\n * (e.g. the first feed post, or a screen just navigated to). Cancellable via\n * `shouldCancel` so a superseded step abandons its retry loop immediately.\n */\n async resolve(\n id: string,\n {\n retries = 6,\n intervalMs = 120,\n shouldCancel,\n }: {\n retries?: number;\n intervalMs?: number;\n /** Abort the retry loop early (e.g. the step was superseded). */\n shouldCancel?: () => boolean;\n } = {},\n ): Promise<TargetRect | null> {\n for (let attempt = 0; attempt <= retries; attempt++) {\n if (shouldCancel?.()) return null;\n const measurer = anchors.get(id);\n if (measurer) {\n const rect = await measurer();\n if (rect && rect.width > 0 && rect.height > 0) return rect;\n }\n if (attempt < retries) {\n await new Promise((resolve) => setTimeout(resolve, intervalMs));\n }\n }\n return null;\n },\n};\n","import { useEffect, useRef } from \"react\";\nimport type { View } from \"react-native\";\n\nimport { coachmarkAnchors } from \"./coachmarkAnchorRegistry\";\nimport type { TargetRect } from \"./types\";\n\n/**\n * Makes any element ringable by a coachmark tour. Attach the returned ref to a\n * plain RN View wrapping the target (use `collapsable={false}` so the native\n * node survives for measurement):\n *\n * const filterAnchor = useCoachmarkAnchor(\"filter_icon\");\n * <View ref={filterAnchor} collapsable={false}>{button}</View>\n *\n * The app decides which ids exist and where they live; the kit measures them at\n * step time via `measureInWindow` (never continuously). Pass `null` to keep the\n * hook's position stable while registering nothing (e.g. a list item that is\n * only an anchor at one index).\n */\nexport const useCoachmarkAnchor = (id: string | null | undefined) => {\n const ref = useRef<View>(null);\n\n useEffect(() => {\n if (!id) return undefined;\n\n const measure = (): Promise<TargetRect | null> =>\n new Promise((resolve) => {\n const node = ref.current;\n if (!node || typeof node.measureInWindow !== \"function\") {\n return resolve(null);\n }\n node.measureInWindow((x, y, width, height) => {\n if (\n [x, y, width, height].some(\n (value) => value == null || Number.isNaN(value),\n )\n ) {\n return resolve(null);\n }\n resolve({ x, y, width, height });\n });\n });\n\n coachmarkAnchors.register(id, measure);\n return () => coachmarkAnchors.unregister(id, measure);\n }, [id]);\n\n return ref;\n};\n","import { useCallback, useEffect, useRef, useState } from \"react\";\n\nimport { coachmarkAnchors } from \"./coachmarkAnchorRegistry\";\nimport { coachmarkOverlay } from \"./coachmarkOverlayStore\";\nimport { areCoachmarksEnabled, coachmarkGateKey, hasSeenGate, markSeenGate } from \"./runtime\";\nimport type { CoachmarkStep } from \"./types\";\n\nexport interface UseCoachmarkTourOptions {\n /**\n * Gate key for the whole tour. The kit reads/writes\n * `wire_coachmark_<tourId>_seen` through the injected CoachmarkStorage so the\n * app never owns the \"seen\" bookkeeping (the global testing flag bypasses it).\n */\n tourId: string;\n /** Run at most once ever (persisted via the gate). Default true. */\n showOnce?: boolean;\n /**\n * Domain gate — the tour only arms while this is true (e.g. hasPosts), and it\n * also drives PAUSE/RESUME: if this flips false mid-tour (e.g. the user tab-\n * switches and the screen loses focus without unmounting) the overlay is\n * hidden but the tour's position is kept, and it resumes on the CURRENT step\n * (re-resolving its anchor) when this returns true. See the hook JSDoc.\n */\n enabled: boolean;\n /** Let passive value land before the first hint. */\n startDelayMs?: number;\n /** Fires once the tour finishes or is skipped (after the gate is written). */\n onComplete?: () => void;\n /**\n * Fires once when a step first becomes visible. It is NOT re-fired when the\n * SAME step resumes after a focus-loss pause (the last-shown step id is\n * tracked in a ref and suppressed), so a tab-switch never inflates\n * impressions. It fires again only when the tour advances to a new step.\n */\n onStepShown?: (id: string) => void;\n onStepEngaged?: (id: string) => void;\n onStepDismissed?: (id: string) => void;\n}\n\nconst DEFAULT_START_DELAY_MS = 3000;\n\n/**\n * Plays an ordered queue of coachmark steps on the current screen through the\n * root SpotlightOverlay (mounted by CoachmarkProvider). Engaging a step (tap the\n * ring/tooltip) advances and fires onStepEngaged. Tapping the backdrop advances\n * to the NEXT step and fires onStepDismissed — a stray tap or a \"not now\" never\n * kills the tour; only a backdrop tap on the LAST step ends it. Both terminal\n * paths (engaging past the end, or dismissing the last step) write the seen gate\n * once and call onComplete, so a finished tour never nags again.\n *\n * Gating lives IN the kit: the tour arms only when `enabled` AND (not `showOnce`\n * OR the `tourId` gate is unseen).\n *\n * PAUSE/RESUME on focus loss: `enabled` is a live gate, not just an arm-once\n * trigger. Once armed, if `enabled` goes false while the tour is in flight\n * (started, not finished) — the classic case being a tab-switch that keeps the\n * screen mounted — the drive effect hides the overlay so a stale rect can't\n * float over the wrong screen, but KEEPS `activeIndex` and does NOT write the\n * seen gate. When `enabled` returns true the effect re-runs (it's in the deps)\n * and re-drives the SAME step, re-resolving its anchor so a moved/relaid-out\n * target is picked up. `onStepShown` is suppressed on that resume (last-shown\n * step id is tracked in a ref) so a pause/resume never double-counts a step.\n *\n * IMPORTANT: `steps` MUST be a stable (memoized) array. If a new array identity\n * is passed on every render the drive effect re-runs and re-shows the current\n * step (wasteful anchor re-resolves / overlay churn), and analytics can\n * double-fire. Memoize it, or pass an inline module-level constant.\n *\n * Preserved engine invariants: step callbacks live in a ref (not effect deps),\n * anchor resolution is cancellable, and finish is idempotent (only one overlay\n * is ever active, the gate is written once).\n */\nexport const useCoachmarkTour = (\n /** Ordered coachmark steps. MUST be stable/memoized — see the note above. */\n steps: CoachmarkStep[],\n {\n tourId,\n showOnce = true,\n enabled,\n startDelayMs = DEFAULT_START_DELAY_MS,\n onComplete,\n onStepShown,\n onStepEngaged,\n onStepDismissed,\n }: UseCoachmarkTourOptions,\n) => {\n const [activeIndex, setActiveIndex] = useState<number | null>(null);\n const startedRef = useRef(false);\n const finishedRef = useRef(false);\n // Id of the step onStepShown last fired for. Lets us re-drive the current\n // step on a focus-loss RESUME without re-firing the impression callback.\n const lastShownStepIdRef = useRef<string | null>(null);\n\n // Keep the latest step callbacks in a ref so parent-recreated inline callbacks\n // don't re-trigger the drive effect (which would re-show the step and\n // double-fire analytics). The drive effect keys only on the step, not these.\n const callbacksRef = useRef({ onStepShown, onStepEngaged, onStepDismissed });\n callbacksRef.current = { onStepShown, onStepEngaged, onStepDismissed };\n\n const finish = useCallback(() => {\n if (finishedRef.current) return;\n finishedRef.current = true;\n if (showOnce) markSeenGate(coachmarkGateKey(tourId));\n coachmarkOverlay.hide();\n setActiveIndex(null);\n onComplete?.();\n }, [onComplete, showOnce, tourId]);\n\n // Arm once, after the delay, when enabled and the gate is unseen.\n useEffect(() => {\n if (!enabled || startedRef.current) return undefined;\n // Feature kill switch: never arm while coachmarks are disabled, so no timer starts, no\n // overlay shows, and the once-gate is NOT consumed — re-enabling replays the tour.\n if (!areCoachmarksEnabled()) return undefined;\n if (showOnce && hasSeenGate(coachmarkGateKey(tourId))) return undefined;\n const timer = setTimeout(() => {\n startedRef.current = true;\n setActiveIndex(0);\n }, startDelayMs);\n return () => clearTimeout(timer);\n }, [enabled, startDelayMs, showOnce, tourId]);\n\n // Drive the active step. Keyed on `enabled` too, so a mid-tour focus loss\n // pauses (hide, keep position) and a return to focus resumes the same step.\n useEffect(() => {\n if (activeIndex === null) return undefined;\n\n // PAUSE: armed but the screen lost focus (enabled flipped false while in\n // flight). Hide the overlay so a stale rect can't float over the wrong\n // screen, but KEEP activeIndex and DON'T write the gate. When enabled\n // returns true this effect re-runs and re-drives the current step below.\n if (!enabled) {\n if (startedRef.current && !finishedRef.current) coachmarkOverlay.hide();\n return undefined;\n }\n\n if (activeIndex >= steps.length) {\n finish();\n return undefined;\n }\n\n const step = steps[activeIndex];\n if (!step) {\n finish();\n return undefined;\n }\n let cancelled = false;\n\n (async () => {\n // Re-resolve the anchor every drive (incl. resume) — rects may have moved\n // while the screen was backgrounded / relaid out.\n const rect = step.anchorId\n ? await coachmarkAnchors.resolve(step.anchorId, {\n shouldCancel: () => cancelled,\n })\n : null;\n if (cancelled) return;\n\n // Fire onStepShown only when the shown step actually changes — a resume\n // of the SAME step (post focus-loss) must not double-count the impression.\n if (lastShownStepIdRef.current !== step.id) {\n lastShownStepIdRef.current = step.id;\n callbacksRef.current.onStepShown?.(step.id);\n }\n coachmarkOverlay.show({\n message: step.message,\n targetRect: rect,\n gesture: step.gesture ?? \"none\",\n placement: step.placement ?? \"bottom\",\n onEngage: () => {\n callbacksRef.current.onStepEngaged?.(step.id);\n step.onEngage?.();\n setActiveIndex((index) => (index ?? 0) + 1);\n },\n onDismiss: () => {\n callbacksRef.current.onStepDismissed?.(step.id);\n // Backdrop tap advances to the next step; only the LAST step's\n // backdrop tap ends the whole tour (the gate is written once, there).\n if (activeIndex >= steps.length - 1) {\n finish();\n } else {\n setActiveIndex((index) => (index ?? 0) + 1);\n }\n },\n });\n })();\n\n return () => {\n cancelled = true;\n };\n }, [activeIndex, steps, finish, enabled]);\n\n // Safety: clear the overlay if the screen unmounts mid-tour.\n useEffect(\n () => () => {\n if (!finishedRef.current) coachmarkOverlay.hide();\n },\n [],\n );\n};\n","/**\n * selectTourSteps — the Phase-3 (AI intent-mapping) seam, stubbed today.\n *\n * The app declares a full catalog of coachmarks (its \"feature map\"). Near-term,\n * the whole catalog plays in its declared order. LATER, the Wire server will\n * emit an ordered `coachmarks: string[]` id list chosen by the user's captured\n * intent (see the package spec §1e / §5), and the app passes it straight here as\n * `selection`. This function is the ONE place that turns a selection into the\n * live ordered step list — so turning AI on is a drop-in with zero app changes:\n *\n * // Phase 1-2 (no AI): full catalog, declared order\n * const steps = selectTourSteps(catalog);\n *\n * // Phase 3 (AI on): server-chosen subset, server order\n * const steps = selectTourSteps(catalog, plan.coachmarks);\n *\n * Contract:\n * - `selection` absent → returns the catalog unchanged (identity/declared order).\n * - `selection` present → returns only catalog entries whose `id` appears in\n * `selection`, ordered by `selection` (unknown ids are skipped; duplicates in\n * `selection` are ignored after the first match).\n *\n * NOTE: routing steps through a catalog + this selector is NOT required today.\n * Declaring an inline, static (module-level or memoized) steps array and passing\n * it straight to `useCoachmarkTour` is a perfectly fine consumer pattern. The\n * catalog + selection route exists to make the app AI-selection-ready — flip to\n * server-chosen ordering later with zero app changes — not as the baseline.\n */\nexport const selectTourSteps = <T extends { id: string }>(\n catalog: T[],\n selection?: string[],\n): T[] => {\n if (!selection) return catalog;\n\n const byId = new Map(catalog.map((item) => [item.id, item]));\n const seen = new Set<string>();\n const ordered: T[] = [];\n for (const id of selection) {\n if (seen.has(id)) continue;\n seen.add(id);\n const item = byId.get(id);\n if (item) ordered.push(item);\n }\n return ordered;\n};\n"]}
|