@wireai/activation 0.1.1 → 0.3.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/dist/index.d.mts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import React__default, { ReactNode } from 'react';
3
- import { e as WireOnboardingProps, f as WireOnboardingConfig, O as OnboardingResult, S as StepValidator, g as OnboardingEvent, h as OnboardingCopy, a as ClientEventTarget, D as DeviceContext } from './analyticsEvent-B8v3BZjM.mjs';
4
- export { A as AnalyticsEvent, C as ClientEvent, b as ClientEventType, i as DeviceFormFactor, j as OnboardingProgress, W as WIRE_ONBOARDING_EVENTS, c as WireOnboardingEventName, k as collectDeviceContext, m as makeSessionId, r as reportClientEvent, d as reportClientEvents, t as toAnalyticsEvent } from './analyticsEvent-B8v3BZjM.mjs';
3
+ import { k as WireOnboardingProps, l as WireOnboardingConfig, O as OnboardingResult, S as StepValidator, n as OnboardingEvent, o as OnboardingCopy, a as ClientEventTarget, D as DeviceContext, C as ClientEvent, e as EnvelopeSource } from './eventQueue-CA1d8Fmn.mjs';
4
+ export { A as AnalyticsEvent, b as ClientEventType, p as DeviceFormFactor, q as OnboardingProgress, W as WIRE_ONBOARDING_EVENTS, g as WireOnboardingEventName, s as collectDeviceContext, m as makeSessionId, r as reportClientEvent, j as reportClientEvents, t as toAnalyticsEvent } from './eventQueue-CA1d8Fmn.mjs';
5
5
  import { O as OnboardingTheme } from './types-BKfpdZzX.mjs';
6
6
  export { a as OnboardingButtonStyle, b as OnboardingColors, c as OnboardingFonts, d as OnboardingRadius, e as OnboardingSpacing } from './types-BKfpdZzX.mjs';
7
7
  export { C as CenteredModal, a as CenteredModalHandle, b as CenteredModalProps } from './CenteredModal-C3qQBHsA.mjs';
@@ -937,6 +937,15 @@ interface ReportSessionStartOptions {
937
937
  meta?: Record<string, unknown>;
938
938
  /** Set `false` to bypass the once-per-open guard (default on). See {@link resetSessionStartGuard}. */
939
939
  once?: boolean;
940
+ /**
941
+ * OPTIONAL transport sink. When provided, the built `app.session_started` event is routed HERE
942
+ * (e.g. the offline-first event queue's `enqueue`) INSTEAD of this emitter's own direct `fetch`,
943
+ * while KEEPING the once-per-open guard above. This is how the lifecycle wiring
944
+ * (`useLifecycleEvents` / `wireLifecycleEvents`) offline-buffers session-start WITHOUT adding a
945
+ * second session emitter: one emitter, one guard, now durable. Omit it for the direct-POST path.
946
+ * A throwing sink is swallowed — analytics must never surface into the UI.
947
+ */
948
+ sink?: (event: ClientEvent) => void;
940
949
  }
941
950
  /** Test-only: forget every emitted session id so a unit test starts from a clean guard. */
942
951
  declare const resetSessionStartGuard: () => void;
@@ -977,4 +986,149 @@ interface UseSessionStartOptions {
977
986
  */
978
987
  declare const useSessionStart: (config: SessionStartConfig | undefined, options?: UseSessionStartOptions) => void;
979
988
 
980
- export { AnimatedSparkle, BACKGROUND_SESSION_MS, type CachedFeatures, CardHandoff, type CardHandoffProps, type CardHandoffVariant, ChipSelectCard, ClientEventTarget, CompletionView, DEFAULT_FEATURES_TTL_MS, DemoOnboarding, type DemoOnboardingProps, DeviceContext, DoneBlock, ErrorBlock, type IdentifyOnboardingOptions, IllustrationProvider, type IllustrationRegistry, InterstitialCard, LoadingBlock, LoadingScreen, NumberStepperCard, type OnboardingAttribution, Button as OnboardingButton, OnboardingCopy, OnboardingEvent, type OnboardingFlagOptions, OnboardingFlow, OnboardingResult, OnboardingScaffold, OnboardingTheme, OnboardingThemeProvider, type ReportSessionStartOptions, type ResolveFeaturesOptions, SESSION_STARTED_EVENT, SelectionCard, type SessionStartConfig, StatusCard, StepProgress, StepValidator, TextInputCard, type ThemeFromBrandInput, USER_ID_MAX_LENGTH, type UseSessionStartOptions, type WireConfigOverrides, WireFeatures, WireFeaturesConfig, WireFeaturesProvider, type WireFeaturesProviderProps, WireOnboarding, WireOnboardingConfig, WireOnboardingProps, WireOnboardingStorage, attributionMetadata, defaultIllustrations, defaultOnboardingTheme, defaultWireFeatures, deriveAnswers, featuresCacheKey, featuresEqual, fetchWireFeatures, identifyOnboarding, isFeaturesFresh, isOnboardingEnabled, mergeTheme, motionSpec, onboardingComponents, parseWireFeatures, readCachedFeatures, readProgress, reportSessionStart, resetSessionStartGuard, sanitizeUserId, themeFromBrand, useIllustration, useOnboardingTheme, useReducedMotion, useResolvedFeatures, useSessionStart, useWireFeatures, useWireFeaturesContext, wireConfigFromEnv, writeCachedFeatures };
989
+ /**
990
+ * lifecycle — the TOP-OF-FUNNEL app lifecycle events that sit ABOVE onboarding: `app.first_open`
991
+ * (once ever per install) and `app.session_started` (per app-open). They compose with, and never
992
+ * duplicate, the events the funnel already records.
993
+ *
994
+ * WHERE THIS FITS (one funnel, no double counting):
995
+ * • `app.first_open` → THIS module, once ever (persisted flag). The in-app "install" proxy.
996
+ * • `app.session_started` → the EXISTING {@link reportSessionStart} emitter (per app-open). This
997
+ * module REUSES it (routed through the offline queue), never re-emits.
998
+ * • onboarding started / completed / activated → ALREADY recorded: the server writes
999
+ * `session_started` + `completed` during the A2A flow, and the client reports `dropped` /
1000
+ * `client_fallback` / `identify` via `reportClientEvent`. This module does NOT touch them —
1001
+ * emitting them here would double-count. It only ADDS the two lifecycle events above them.
1002
+ *
1003
+ * WIRE CONTRACT (identical to `app.session_started`): both lifecycle events are stored as
1004
+ * `event_type='app_event'` with the name in `question_key` (the server's `_event_name` returns
1005
+ * `question_key` for an `app_event`, which a trigger matches). `app.first_open` uses the SAME
1006
+ * `app.*` namespace + the SAME event shape as `app.session_started` — no bespoke `event_type`,
1007
+ * no invented contract. `device_key` rides in the non-PII `user_context` bucket; `app_id` +
1008
+ * `environment` are filled server-side.
1009
+ *
1010
+ * TWO FIRST-CLASS ENTRY POINTS (mirrors reportSessionStart vs useSessionStart):
1011
+ * • `reportFirstOpen(...)` / `wireLifecycleEvents(...)` — pure, React-free, for a host that owns
1012
+ * its own app-open path.
1013
+ * • `useLifecycleEvents(...)` — the batteries-included React hook (in `useLifecycleEvents.ts`).
1014
+ *
1015
+ * OFFLINE-FIRST: pass the Brief-01 event queue's `enqueue` as the `sink` and every lifecycle event
1016
+ * is buffered + persisted + retried instead of a blind fetch. Without a sink they degrade to a
1017
+ * direct fire-and-forget POST.
1018
+ *
1019
+ * PRIVACY (hard rule, same as the rest of the kit): NO GPS/location, NO advertising id. Nothing
1020
+ * here carries a coordinate or an ad id — a host adopting it changes no store privacy declaration.
1021
+ *
1022
+ * FIRE-AND-FORGET: like every analytics path in the kit, nothing here throws into the UI, awaits
1023
+ * in the caller, or hangs the app — storage reads race a short timeout, writes swallow errors.
1024
+ */
1025
+
1026
+ /** The canonical event name for the first-ever app open. Same `app.*` namespace as
1027
+ * {@link SESSION_STARTED_EVENT}; a trigger keys off this exact string. */
1028
+ declare const FIRST_OPEN_EVENT: "app.first_open";
1029
+ /** Storage key for the once-ever first-open flag, e.g. `wireai:first_open:myelino`. Mirrors the
1030
+ * `wireai:<concern>:<appId>` namespacing of {@link sessionStorageKey}. */
1031
+ declare const firstOpenStorageKey: (appId: string) => string;
1032
+ /** Test-only: forget the first-open latch so a unit test starts from a clean process state. */
1033
+ declare const resetFirstOpenLatch: () => void;
1034
+ /** Shared inputs for a lifecycle event. Everything is optional except a transport (`target` for the
1035
+ * direct-POST fallback, or a `sink`). A pre-auth open (no user yet) is a valid device-only event. */
1036
+ interface LifecycleEventInput {
1037
+ /** Where to POST if no `sink` is wired (the tenant transport, same as `WireOnboardingConfig`). */
1038
+ target?: ClientEventTarget;
1039
+ /** Preferred transport: route the built event HERE (the offline queue's `enqueue`). */
1040
+ sink?: (event: ClientEvent) => void;
1041
+ /** The per-open session id. Defaults to a fresh `makeSessionId()`. */
1042
+ sessionId?: string;
1043
+ /** The host's OPAQUE pseudonymous user id (NOT PII). Sanitized + capped; omitted pre-auth. */
1044
+ userId?: string;
1045
+ /** A stable, non-PII device id the host owns. Rides in `user_context.device_key`. */
1046
+ deviceKey?: string;
1047
+ /** The host's local open-counter value. Drives `returning` + "Nth session". */
1048
+ sessionCount?: number;
1049
+ /** Host app version (e.g. "1.4.2"), if cheaply available. */
1050
+ appVersion?: string;
1051
+ /** Platform string (e.g. "ios"), if cheaply available. */
1052
+ platform?: string;
1053
+ /** An optional richer device snapshot (from `collectDeviceContext()`); the hook fills this. */
1054
+ device?: DeviceContext;
1055
+ /** Small non-PII extras, stored as a JSON string in the event `meta`. */
1056
+ meta?: Record<string, unknown>;
1057
+ }
1058
+ /** Options for {@link reportFirstOpen}. Adds the once-ever persistence inputs on top of the shared
1059
+ * lifecycle inputs. Without `storage` it degrades to the in-memory latch (once per process). */
1060
+ interface ReportFirstOpenOptions extends LifecycleEventInput {
1061
+ /** Host persistence (AsyncStorage subset). The once-ever flag lives here — it is what survives an
1062
+ * app kill. Omit it for the documented degraded (in-memory, once-per-process) mode. */
1063
+ storage?: WireOnboardingStorage;
1064
+ /** Tenant/app id — namespaces the persisted flag (`wireai:first_open:<appId>`). */
1065
+ appId?: string;
1066
+ }
1067
+ /**
1068
+ * Emit `app.first_open` EXACTLY ONCE EVER per install. Fire-and-forget; returns immediately.
1069
+ *
1070
+ * • With `storage`: reads the persisted flag (`wireai:first_open:<appId>`). Absent → emit, then
1071
+ * write the flag (survives app kills, so a second launch is a no-op). Present → no-op.
1072
+ * • Race guard: an in-memory latch is set SYNCHRONOUSLY before the async read, so two
1073
+ * near-simultaneous calls fire at most once.
1074
+ * • Without `storage`: degraded mode — fires once per PROCESS via the latch only (documented).
1075
+ */
1076
+ declare const reportFirstOpen: (opts: ReportFirstOpenOptions) => void;
1077
+ /** Options for {@link wireLifecycleEvents}: the shared lifecycle inputs + first-open persistence. */
1078
+ interface WireLifecycleOptions extends ReportFirstOpenOptions {
1079
+ }
1080
+ /**
1081
+ * Wire BOTH lifecycle events in one call for a host that owns its own app-open path (the non-hook
1082
+ * counterpart to {@link useLifecycleEvents}). Fires `app.first_open` (once ever) and one
1083
+ * `app.session_started` for THIS open through the EXISTING {@link reportSessionStart} emitter (so
1084
+ * the once-per-open guard still applies — pass the same `sessionId` and it never double-fires).
1085
+ * Route both through the same `sink` (the offline queue) to buffer them. Fire-and-forget.
1086
+ */
1087
+ declare const wireLifecycleEvents: (opts: WireLifecycleOptions) => void;
1088
+
1089
+ /** Tenant transport + host persistence for the lifecycle wiring. Same creds as `WireOnboardingConfig`. */
1090
+ interface LifecycleConfig {
1091
+ /** Base server URL (same as `WireOnboardingConfig.serverUrl`); `/v1/events` is appended. */
1092
+ serverUrl?: string;
1093
+ /** Tenant API key; sent as `Authorization: Bearer`. */
1094
+ apiKey?: string;
1095
+ /** Host app version (e.g. "1.4.2"), forwarded for release segmentation. Optional. */
1096
+ appVersion?: string;
1097
+ /** Tenant/app id — namespaces the first-open flag AND the hook's internal queue storage key. */
1098
+ appId?: string;
1099
+ /** Host storage (AsyncStorage subset). Enables the persisted once-ever first-open flag AND the
1100
+ * offline durability of the hook's internal queue. Omit it and both degrade to in-memory. */
1101
+ storage?: WireOnboardingStorage;
1102
+ }
1103
+ /** Per-open identity + wiring the host supplies. All optional: a pre-auth open is device-only. */
1104
+ interface UseLifecycleEventsOptions {
1105
+ /** The host's opaque pseudonymous user id (NOT PII). Omitted before the user authenticates. */
1106
+ userId?: string;
1107
+ /** The host's local open-counter value for this open. Drives `returning` + "Nth session". */
1108
+ sessionCount?: number;
1109
+ /** A stable, non-PII device id the host owns. Groups this device's sessions server-side. */
1110
+ deviceKey?: string;
1111
+ /** Small non-PII extras forwarded on the event `meta`. */
1112
+ meta?: Record<string, unknown>;
1113
+ /** Set `false` to disable firing (e.g. behind a consent gate). Default enabled. */
1114
+ enabled?: boolean;
1115
+ /**
1116
+ * Explicit transport sink (e.g. an existing shared `EventQueue.enqueue`). When provided, BOTH
1117
+ * lifecycle events route here and the hook does NOT create its own queue — pass this to share ONE
1118
+ * offline queue across the kit's analytics (screen tracking + lifecycle).
1119
+ */
1120
+ sink?: (event: ClientEvent) => void;
1121
+ /**
1122
+ * Context envelope (or provider) for the hook's internally-created queue. Ignored when `sink` is
1123
+ * supplied (the host's queue owns envelope stamping).
1124
+ */
1125
+ envelope?: EnvelopeSource;
1126
+ }
1127
+ /**
1128
+ * Fire `app.first_open` (once ever) + `app.session_started` (per open), offline-buffered. Returns
1129
+ * nothing — a side-effecting hook. Safe to call with inline options (read through a ref, so
1130
+ * changing `userId`/`sessionCount` never re-fires a session).
1131
+ */
1132
+ declare const useLifecycleEvents: (config: LifecycleConfig | undefined, options?: UseLifecycleEventsOptions) => void;
1133
+
1134
+ export { AnimatedSparkle, BACKGROUND_SESSION_MS, type CachedFeatures, CardHandoff, type CardHandoffProps, type CardHandoffVariant, ChipSelectCard, ClientEvent, ClientEventTarget, CompletionView, DEFAULT_FEATURES_TTL_MS, DemoOnboarding, type DemoOnboardingProps, DeviceContext, DoneBlock, ErrorBlock, FIRST_OPEN_EVENT, type IdentifyOnboardingOptions, IllustrationProvider, type IllustrationRegistry, InterstitialCard, type LifecycleConfig, type LifecycleEventInput, LoadingBlock, LoadingScreen, NumberStepperCard, type OnboardingAttribution, Button as OnboardingButton, OnboardingCopy, OnboardingEvent, type OnboardingFlagOptions, OnboardingFlow, OnboardingResult, OnboardingScaffold, OnboardingTheme, OnboardingThemeProvider, type ReportFirstOpenOptions, type ReportSessionStartOptions, type ResolveFeaturesOptions, SESSION_STARTED_EVENT, SelectionCard, type SessionStartConfig, StatusCard, StepProgress, StepValidator, TextInputCard, type ThemeFromBrandInput, USER_ID_MAX_LENGTH, type UseLifecycleEventsOptions, type UseSessionStartOptions, type WireConfigOverrides, WireFeatures, WireFeaturesConfig, WireFeaturesProvider, type WireFeaturesProviderProps, type WireLifecycleOptions, WireOnboarding, WireOnboardingConfig, WireOnboardingProps, WireOnboardingStorage, attributionMetadata, defaultIllustrations, defaultOnboardingTheme, defaultWireFeatures, deriveAnswers, featuresCacheKey, featuresEqual, fetchWireFeatures, firstOpenStorageKey, identifyOnboarding, isFeaturesFresh, isOnboardingEnabled, mergeTheme, motionSpec, onboardingComponents, parseWireFeatures, readCachedFeatures, readProgress, reportFirstOpen, reportSessionStart, resetFirstOpenLatch, resetSessionStartGuard, sanitizeUserId, themeFromBrand, useIllustration, useLifecycleEvents, useOnboardingTheme, useReducedMotion, useResolvedFeatures, useSessionStart, useWireFeatures, useWireFeaturesContext, wireConfigFromEnv, wireLifecycleEvents, writeCachedFeatures };
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import React__default, { ReactNode } from 'react';
3
- import { e as WireOnboardingProps, f as WireOnboardingConfig, O as OnboardingResult, S as StepValidator, g as OnboardingEvent, h as OnboardingCopy, a as ClientEventTarget, D as DeviceContext } from './analyticsEvent-DvjB92kK.js';
4
- export { A as AnalyticsEvent, C as ClientEvent, b as ClientEventType, i as DeviceFormFactor, j as OnboardingProgress, W as WIRE_ONBOARDING_EVENTS, c as WireOnboardingEventName, k as collectDeviceContext, m as makeSessionId, r as reportClientEvent, d as reportClientEvents, t as toAnalyticsEvent } from './analyticsEvent-DvjB92kK.js';
3
+ import { k as WireOnboardingProps, l as WireOnboardingConfig, O as OnboardingResult, S as StepValidator, n as OnboardingEvent, o as OnboardingCopy, a as ClientEventTarget, D as DeviceContext, C as ClientEvent, e as EnvelopeSource } from './eventQueue-CrNB9gzH.js';
4
+ export { A as AnalyticsEvent, b as ClientEventType, p as DeviceFormFactor, q as OnboardingProgress, W as WIRE_ONBOARDING_EVENTS, g as WireOnboardingEventName, s as collectDeviceContext, m as makeSessionId, r as reportClientEvent, j as reportClientEvents, t as toAnalyticsEvent } from './eventQueue-CrNB9gzH.js';
5
5
  import { O as OnboardingTheme } from './types-BKfpdZzX.js';
6
6
  export { a as OnboardingButtonStyle, b as OnboardingColors, c as OnboardingFonts, d as OnboardingRadius, e as OnboardingSpacing } from './types-BKfpdZzX.js';
7
7
  export { C as CenteredModal, a as CenteredModalHandle, b as CenteredModalProps } from './CenteredModal-Cdgns6--.js';
@@ -937,6 +937,15 @@ interface ReportSessionStartOptions {
937
937
  meta?: Record<string, unknown>;
938
938
  /** Set `false` to bypass the once-per-open guard (default on). See {@link resetSessionStartGuard}. */
939
939
  once?: boolean;
940
+ /**
941
+ * OPTIONAL transport sink. When provided, the built `app.session_started` event is routed HERE
942
+ * (e.g. the offline-first event queue's `enqueue`) INSTEAD of this emitter's own direct `fetch`,
943
+ * while KEEPING the once-per-open guard above. This is how the lifecycle wiring
944
+ * (`useLifecycleEvents` / `wireLifecycleEvents`) offline-buffers session-start WITHOUT adding a
945
+ * second session emitter: one emitter, one guard, now durable. Omit it for the direct-POST path.
946
+ * A throwing sink is swallowed — analytics must never surface into the UI.
947
+ */
948
+ sink?: (event: ClientEvent) => void;
940
949
  }
941
950
  /** Test-only: forget every emitted session id so a unit test starts from a clean guard. */
942
951
  declare const resetSessionStartGuard: () => void;
@@ -977,4 +986,149 @@ interface UseSessionStartOptions {
977
986
  */
978
987
  declare const useSessionStart: (config: SessionStartConfig | undefined, options?: UseSessionStartOptions) => void;
979
988
 
980
- export { AnimatedSparkle, BACKGROUND_SESSION_MS, type CachedFeatures, CardHandoff, type CardHandoffProps, type CardHandoffVariant, ChipSelectCard, ClientEventTarget, CompletionView, DEFAULT_FEATURES_TTL_MS, DemoOnboarding, type DemoOnboardingProps, DeviceContext, DoneBlock, ErrorBlock, type IdentifyOnboardingOptions, IllustrationProvider, type IllustrationRegistry, InterstitialCard, LoadingBlock, LoadingScreen, NumberStepperCard, type OnboardingAttribution, Button as OnboardingButton, OnboardingCopy, OnboardingEvent, type OnboardingFlagOptions, OnboardingFlow, OnboardingResult, OnboardingScaffold, OnboardingTheme, OnboardingThemeProvider, type ReportSessionStartOptions, type ResolveFeaturesOptions, SESSION_STARTED_EVENT, SelectionCard, type SessionStartConfig, StatusCard, StepProgress, StepValidator, TextInputCard, type ThemeFromBrandInput, USER_ID_MAX_LENGTH, type UseSessionStartOptions, type WireConfigOverrides, WireFeatures, WireFeaturesConfig, WireFeaturesProvider, type WireFeaturesProviderProps, WireOnboarding, WireOnboardingConfig, WireOnboardingProps, WireOnboardingStorage, attributionMetadata, defaultIllustrations, defaultOnboardingTheme, defaultWireFeatures, deriveAnswers, featuresCacheKey, featuresEqual, fetchWireFeatures, identifyOnboarding, isFeaturesFresh, isOnboardingEnabled, mergeTheme, motionSpec, onboardingComponents, parseWireFeatures, readCachedFeatures, readProgress, reportSessionStart, resetSessionStartGuard, sanitizeUserId, themeFromBrand, useIllustration, useOnboardingTheme, useReducedMotion, useResolvedFeatures, useSessionStart, useWireFeatures, useWireFeaturesContext, wireConfigFromEnv, writeCachedFeatures };
989
+ /**
990
+ * lifecycle — the TOP-OF-FUNNEL app lifecycle events that sit ABOVE onboarding: `app.first_open`
991
+ * (once ever per install) and `app.session_started` (per app-open). They compose with, and never
992
+ * duplicate, the events the funnel already records.
993
+ *
994
+ * WHERE THIS FITS (one funnel, no double counting):
995
+ * • `app.first_open` → THIS module, once ever (persisted flag). The in-app "install" proxy.
996
+ * • `app.session_started` → the EXISTING {@link reportSessionStart} emitter (per app-open). This
997
+ * module REUSES it (routed through the offline queue), never re-emits.
998
+ * • onboarding started / completed / activated → ALREADY recorded: the server writes
999
+ * `session_started` + `completed` during the A2A flow, and the client reports `dropped` /
1000
+ * `client_fallback` / `identify` via `reportClientEvent`. This module does NOT touch them —
1001
+ * emitting them here would double-count. It only ADDS the two lifecycle events above them.
1002
+ *
1003
+ * WIRE CONTRACT (identical to `app.session_started`): both lifecycle events are stored as
1004
+ * `event_type='app_event'` with the name in `question_key` (the server's `_event_name` returns
1005
+ * `question_key` for an `app_event`, which a trigger matches). `app.first_open` uses the SAME
1006
+ * `app.*` namespace + the SAME event shape as `app.session_started` — no bespoke `event_type`,
1007
+ * no invented contract. `device_key` rides in the non-PII `user_context` bucket; `app_id` +
1008
+ * `environment` are filled server-side.
1009
+ *
1010
+ * TWO FIRST-CLASS ENTRY POINTS (mirrors reportSessionStart vs useSessionStart):
1011
+ * • `reportFirstOpen(...)` / `wireLifecycleEvents(...)` — pure, React-free, for a host that owns
1012
+ * its own app-open path.
1013
+ * • `useLifecycleEvents(...)` — the batteries-included React hook (in `useLifecycleEvents.ts`).
1014
+ *
1015
+ * OFFLINE-FIRST: pass the Brief-01 event queue's `enqueue` as the `sink` and every lifecycle event
1016
+ * is buffered + persisted + retried instead of a blind fetch. Without a sink they degrade to a
1017
+ * direct fire-and-forget POST.
1018
+ *
1019
+ * PRIVACY (hard rule, same as the rest of the kit): NO GPS/location, NO advertising id. Nothing
1020
+ * here carries a coordinate or an ad id — a host adopting it changes no store privacy declaration.
1021
+ *
1022
+ * FIRE-AND-FORGET: like every analytics path in the kit, nothing here throws into the UI, awaits
1023
+ * in the caller, or hangs the app — storage reads race a short timeout, writes swallow errors.
1024
+ */
1025
+
1026
+ /** The canonical event name for the first-ever app open. Same `app.*` namespace as
1027
+ * {@link SESSION_STARTED_EVENT}; a trigger keys off this exact string. */
1028
+ declare const FIRST_OPEN_EVENT: "app.first_open";
1029
+ /** Storage key for the once-ever first-open flag, e.g. `wireai:first_open:myelino`. Mirrors the
1030
+ * `wireai:<concern>:<appId>` namespacing of {@link sessionStorageKey}. */
1031
+ declare const firstOpenStorageKey: (appId: string) => string;
1032
+ /** Test-only: forget the first-open latch so a unit test starts from a clean process state. */
1033
+ declare const resetFirstOpenLatch: () => void;
1034
+ /** Shared inputs for a lifecycle event. Everything is optional except a transport (`target` for the
1035
+ * direct-POST fallback, or a `sink`). A pre-auth open (no user yet) is a valid device-only event. */
1036
+ interface LifecycleEventInput {
1037
+ /** Where to POST if no `sink` is wired (the tenant transport, same as `WireOnboardingConfig`). */
1038
+ target?: ClientEventTarget;
1039
+ /** Preferred transport: route the built event HERE (the offline queue's `enqueue`). */
1040
+ sink?: (event: ClientEvent) => void;
1041
+ /** The per-open session id. Defaults to a fresh `makeSessionId()`. */
1042
+ sessionId?: string;
1043
+ /** The host's OPAQUE pseudonymous user id (NOT PII). Sanitized + capped; omitted pre-auth. */
1044
+ userId?: string;
1045
+ /** A stable, non-PII device id the host owns. Rides in `user_context.device_key`. */
1046
+ deviceKey?: string;
1047
+ /** The host's local open-counter value. Drives `returning` + "Nth session". */
1048
+ sessionCount?: number;
1049
+ /** Host app version (e.g. "1.4.2"), if cheaply available. */
1050
+ appVersion?: string;
1051
+ /** Platform string (e.g. "ios"), if cheaply available. */
1052
+ platform?: string;
1053
+ /** An optional richer device snapshot (from `collectDeviceContext()`); the hook fills this. */
1054
+ device?: DeviceContext;
1055
+ /** Small non-PII extras, stored as a JSON string in the event `meta`. */
1056
+ meta?: Record<string, unknown>;
1057
+ }
1058
+ /** Options for {@link reportFirstOpen}. Adds the once-ever persistence inputs on top of the shared
1059
+ * lifecycle inputs. Without `storage` it degrades to the in-memory latch (once per process). */
1060
+ interface ReportFirstOpenOptions extends LifecycleEventInput {
1061
+ /** Host persistence (AsyncStorage subset). The once-ever flag lives here — it is what survives an
1062
+ * app kill. Omit it for the documented degraded (in-memory, once-per-process) mode. */
1063
+ storage?: WireOnboardingStorage;
1064
+ /** Tenant/app id — namespaces the persisted flag (`wireai:first_open:<appId>`). */
1065
+ appId?: string;
1066
+ }
1067
+ /**
1068
+ * Emit `app.first_open` EXACTLY ONCE EVER per install. Fire-and-forget; returns immediately.
1069
+ *
1070
+ * • With `storage`: reads the persisted flag (`wireai:first_open:<appId>`). Absent → emit, then
1071
+ * write the flag (survives app kills, so a second launch is a no-op). Present → no-op.
1072
+ * • Race guard: an in-memory latch is set SYNCHRONOUSLY before the async read, so two
1073
+ * near-simultaneous calls fire at most once.
1074
+ * • Without `storage`: degraded mode — fires once per PROCESS via the latch only (documented).
1075
+ */
1076
+ declare const reportFirstOpen: (opts: ReportFirstOpenOptions) => void;
1077
+ /** Options for {@link wireLifecycleEvents}: the shared lifecycle inputs + first-open persistence. */
1078
+ interface WireLifecycleOptions extends ReportFirstOpenOptions {
1079
+ }
1080
+ /**
1081
+ * Wire BOTH lifecycle events in one call for a host that owns its own app-open path (the non-hook
1082
+ * counterpart to {@link useLifecycleEvents}). Fires `app.first_open` (once ever) and one
1083
+ * `app.session_started` for THIS open through the EXISTING {@link reportSessionStart} emitter (so
1084
+ * the once-per-open guard still applies — pass the same `sessionId` and it never double-fires).
1085
+ * Route both through the same `sink` (the offline queue) to buffer them. Fire-and-forget.
1086
+ */
1087
+ declare const wireLifecycleEvents: (opts: WireLifecycleOptions) => void;
1088
+
1089
+ /** Tenant transport + host persistence for the lifecycle wiring. Same creds as `WireOnboardingConfig`. */
1090
+ interface LifecycleConfig {
1091
+ /** Base server URL (same as `WireOnboardingConfig.serverUrl`); `/v1/events` is appended. */
1092
+ serverUrl?: string;
1093
+ /** Tenant API key; sent as `Authorization: Bearer`. */
1094
+ apiKey?: string;
1095
+ /** Host app version (e.g. "1.4.2"), forwarded for release segmentation. Optional. */
1096
+ appVersion?: string;
1097
+ /** Tenant/app id — namespaces the first-open flag AND the hook's internal queue storage key. */
1098
+ appId?: string;
1099
+ /** Host storage (AsyncStorage subset). Enables the persisted once-ever first-open flag AND the
1100
+ * offline durability of the hook's internal queue. Omit it and both degrade to in-memory. */
1101
+ storage?: WireOnboardingStorage;
1102
+ }
1103
+ /** Per-open identity + wiring the host supplies. All optional: a pre-auth open is device-only. */
1104
+ interface UseLifecycleEventsOptions {
1105
+ /** The host's opaque pseudonymous user id (NOT PII). Omitted before the user authenticates. */
1106
+ userId?: string;
1107
+ /** The host's local open-counter value for this open. Drives `returning` + "Nth session". */
1108
+ sessionCount?: number;
1109
+ /** A stable, non-PII device id the host owns. Groups this device's sessions server-side. */
1110
+ deviceKey?: string;
1111
+ /** Small non-PII extras forwarded on the event `meta`. */
1112
+ meta?: Record<string, unknown>;
1113
+ /** Set `false` to disable firing (e.g. behind a consent gate). Default enabled. */
1114
+ enabled?: boolean;
1115
+ /**
1116
+ * Explicit transport sink (e.g. an existing shared `EventQueue.enqueue`). When provided, BOTH
1117
+ * lifecycle events route here and the hook does NOT create its own queue — pass this to share ONE
1118
+ * offline queue across the kit's analytics (screen tracking + lifecycle).
1119
+ */
1120
+ sink?: (event: ClientEvent) => void;
1121
+ /**
1122
+ * Context envelope (or provider) for the hook's internally-created queue. Ignored when `sink` is
1123
+ * supplied (the host's queue owns envelope stamping).
1124
+ */
1125
+ envelope?: EnvelopeSource;
1126
+ }
1127
+ /**
1128
+ * Fire `app.first_open` (once ever) + `app.session_started` (per open), offline-buffered. Returns
1129
+ * nothing — a side-effecting hook. Safe to call with inline options (read through a ref, so
1130
+ * changing `userId`/`sessionCount` never re-fires a session).
1131
+ */
1132
+ declare const useLifecycleEvents: (config: LifecycleConfig | undefined, options?: UseLifecycleEventsOptions) => void;
1133
+
1134
+ export { AnimatedSparkle, BACKGROUND_SESSION_MS, type CachedFeatures, CardHandoff, type CardHandoffProps, type CardHandoffVariant, ChipSelectCard, ClientEvent, ClientEventTarget, CompletionView, DEFAULT_FEATURES_TTL_MS, DemoOnboarding, type DemoOnboardingProps, DeviceContext, DoneBlock, ErrorBlock, FIRST_OPEN_EVENT, type IdentifyOnboardingOptions, IllustrationProvider, type IllustrationRegistry, InterstitialCard, type LifecycleConfig, type LifecycleEventInput, LoadingBlock, LoadingScreen, NumberStepperCard, type OnboardingAttribution, Button as OnboardingButton, OnboardingCopy, OnboardingEvent, type OnboardingFlagOptions, OnboardingFlow, OnboardingResult, OnboardingScaffold, OnboardingTheme, OnboardingThemeProvider, type ReportFirstOpenOptions, type ReportSessionStartOptions, type ResolveFeaturesOptions, SESSION_STARTED_EVENT, SelectionCard, type SessionStartConfig, StatusCard, StepProgress, StepValidator, TextInputCard, type ThemeFromBrandInput, USER_ID_MAX_LENGTH, type UseLifecycleEventsOptions, type UseSessionStartOptions, type WireConfigOverrides, WireFeatures, WireFeaturesConfig, WireFeaturesProvider, type WireFeaturesProviderProps, type WireLifecycleOptions, WireOnboarding, WireOnboardingConfig, WireOnboardingProps, WireOnboardingStorage, attributionMetadata, defaultIllustrations, defaultOnboardingTheme, defaultWireFeatures, deriveAnswers, featuresCacheKey, featuresEqual, fetchWireFeatures, firstOpenStorageKey, identifyOnboarding, isFeaturesFresh, isOnboardingEnabled, mergeTheme, motionSpec, onboardingComponents, parseWireFeatures, readCachedFeatures, readProgress, reportFirstOpen, reportSessionStart, resetFirstOpenLatch, resetSessionStartGuard, sanitizeUserId, themeFromBrand, useIllustration, useLifecycleEvents, useOnboardingTheme, useReducedMotion, useResolvedFeatures, useSessionStart, useWireFeatures, useWireFeaturesContext, wireConfigFromEnv, wireLifecycleEvents, writeCachedFeatures };