@wireai/activation 0.1.0 → 0.2.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 +82 -40
- package/CHANGELOG.md +17 -2
- package/INTEGRATION_PROMPT.md +8 -8
- package/README.md +38 -38
- package/dist/analytics/index.d.mts +92 -0
- package/dist/analytics/index.d.ts +92 -0
- package/dist/analytics/index.js +439 -0
- package/dist/analytics/index.js.map +1 -0
- package/dist/analytics/index.mjs +426 -0
- package/dist/analytics/index.mjs.map +1 -0
- package/dist/coachmarks/index.js.map +1 -1
- package/dist/coachmarks/index.mjs.map +1 -1
- package/dist/decision-BzbiKwk3.d.mts +79 -0
- package/dist/decision-plDEOCkt.d.ts +79 -0
- package/dist/eventQueue-CxKi7Qd5.d.mts +546 -0
- package/dist/eventQueue-rV1dtJJR.d.ts +546 -0
- package/dist/index.d.mts +162 -418
- package/dist/index.d.ts +162 -418
- package/dist/index.js +407 -4
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +402 -5
- package/dist/index.mjs.map +1 -1
- package/dist/questionnaire/index.d.mts +2 -1
- package/dist/questionnaire/index.d.ts +2 -1
- package/dist/questionnaire/index.js.map +1 -1
- package/dist/questionnaire/index.mjs.map +1 -1
- package/dist/reviews/index.d.mts +5 -40
- package/dist/reviews/index.d.ts +5 -40
- package/dist/reviews/index.js.map +1 -1
- package/dist/reviews/index.mjs.map +1 -1
- package/dist/showcase/index.js.map +1 -1
- package/dist/showcase/index.mjs.map +1 -1
- package/dist/transport-BeO_Brcu.d.mts +40 -0
- package/dist/transport-DLpd1v5_.d.ts +40 -0
- package/dist/{decision-Cl8OFYzu.d.mts → types-A6pTxIZV.d.mts} +1 -77
- package/dist/{decision-CFvGY6nP.d.ts → types-BhpXJGlg.d.ts} +1 -77
- package/llms.txt +7 -7
- package/metro/index.d.ts +3 -3
- package/metro/index.js +3 -3
- package/package.json +15 -1
- package/src/analytics/contextEnvelope.ts +72 -0
- package/src/analytics/eventQueue.ts +331 -0
- package/src/analytics/index.ts +47 -0
- package/src/analytics/screenTracking.ts +122 -0
- package/src/analytics/useScreenTracking.ts +48 -0
- package/src/coachmarks/index.ts +2 -2
- package/src/features/WireFeaturesProvider.tsx +1 -1
- package/src/features/index.ts +2 -2
- package/src/index.ts +18 -1
- package/src/questionnaire/index.ts +2 -2
- package/src/reviews/index.ts +2 -2
- package/src/session-analytics/index.ts +20 -0
- package/src/session-analytics/lifecycle.ts +236 -0
- package/src/session-analytics/reportSessionStart.ts +27 -7
- package/src/session-analytics/useLifecycleEvents.ts +184 -0
- package/src/showcase/index.ts +2 -2
- package/src/types.ts +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,230 +1,14 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import React__default, { ReactNode } from 'react';
|
|
3
|
-
import
|
|
4
|
-
|
|
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-rV1dtJJR.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-rV1dtJJR.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
|
-
import { b as WireOnboardingStorage, a as WireFeaturesConfig, W as WireFeatures } from './types-CMuOexw0.js';
|
|
8
|
-
export { D as DEFAULT_SESSION_TTL_MS, L as LoadedSession, O as OnboardingMode, c as clearPersistedSession, l as loadPersistedSession, p as peekPersistedSession, s as savePersistedSession, d as sessionStorageKey } from './types-CMuOexw0.js';
|
|
9
7
|
export { C as CenteredModal, a as CenteredModalHandle, b as CenteredModalProps } from './CenteredModal-Cdgns6--.js';
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
/** Tenant API key (resolves the app server-side). */
|
|
15
|
-
apiKey: string;
|
|
16
|
-
/** Base server URL; the kit appends `/a2a`. */
|
|
17
|
-
serverUrl: string;
|
|
18
|
-
/** App id — passed as the A2A `model` (informational; the key resolves the app). */
|
|
19
|
-
appId: string;
|
|
20
|
-
/**
|
|
21
|
-
* Extra metadata merged into every A2A request (e.g. install attribution).
|
|
22
|
-
* NOTE: the kit reserves `sessionId` (correlation seed) and `supportedComponents`
|
|
23
|
-
* (the renderable card names this device advertises to the backend) — it sets both
|
|
24
|
-
* automatically, so don't override them here.
|
|
25
|
-
*/
|
|
26
|
-
metadata?: Record<string, unknown>;
|
|
27
|
-
/**
|
|
28
|
-
* Host app version string (e.g. "1.4.2"). HOST-INJECTED — the kit adds no dependency to
|
|
29
|
-
* read it; hosts typically pass it from `expo-constants`
|
|
30
|
-
* (`Constants.expoConfig?.version`). Forwarded to the backend on the session metadata and
|
|
31
|
-
* on client events (merged into the `device` snapshot as `device.appVersion`) so analytics
|
|
32
|
-
* can segment the funnel by app version. Optional; omit if unknown.
|
|
33
|
-
*/
|
|
34
|
-
appVersion?: string;
|
|
35
|
-
};
|
|
36
|
-
/**
|
|
37
|
-
* A per-step validator, keyed by a base-question `key` (e.g. `username`). Runs
|
|
38
|
-
* before the answer is sent to the backend. Return `{ ok: false, error }` to
|
|
39
|
-
* block advancing and show the error inline on the card.
|
|
40
|
-
*/
|
|
41
|
-
type StepValidator = (value: string) => Promise<{
|
|
42
|
-
ok: boolean;
|
|
43
|
-
error?: string;
|
|
44
|
-
}>;
|
|
45
|
-
/** Result handed to `onComplete` when the flow reaches its terminal StatusCard. */
|
|
46
|
-
type OnboardingResult = {
|
|
47
|
-
/** Question-key → captured value, derived from the thread. */
|
|
48
|
-
answers: Record<string, unknown>;
|
|
49
|
-
/** The raw message thread, for custom downstream parsing. */
|
|
50
|
-
raw: Message[];
|
|
51
|
-
};
|
|
52
|
-
/**
|
|
53
|
-
* Lifecycle events emitted as the flow runs, for host-side analytics. The kit owns
|
|
54
|
-
* the thread loop, so this is how a host recovers per-turn telemetry it used to get
|
|
55
|
-
* by driving the loop itself.
|
|
56
|
-
* - `started`: the very first message was sent to the backend. Carries `contextId` (the
|
|
57
|
-
* A2A session id). Capture it if you may need to bind a user AFTER the flow
|
|
58
|
-
* finishes (see `identifyOnboarding` and the `userId` prop).
|
|
59
|
-
* - `resumed`: a persisted session was restored after an app kill (fires INSTEAD of
|
|
60
|
-
* `started`, so host funnels don't double-count the same session). Also carries
|
|
61
|
-
* `contextId`. Requires the `storage` prop.
|
|
62
|
-
* - `turn`: a new assistant card arrived (`step` = 1-based index of cards seen).
|
|
63
|
-
* - `error`: the backend errored or the first-card watchdog timed out.
|
|
64
|
-
* - `retry`: a transient failure is being auto-retried (`attempt` = 1-based).
|
|
65
|
-
* - `fallback`: retries are exhausted; the kit degraded to the static `fallbackFlow`
|
|
66
|
-
* (or handed off to `onError`). This is the client-side mirror of the
|
|
67
|
-
* backend's `llm_fallback` reliability event.
|
|
68
|
-
*/
|
|
69
|
-
type OnboardingEvent = {
|
|
70
|
-
type: "started";
|
|
71
|
-
contextId: string;
|
|
72
|
-
} | {
|
|
73
|
-
type: "resumed";
|
|
74
|
-
contextId: string;
|
|
75
|
-
} | {
|
|
76
|
-
type: "turn";
|
|
77
|
-
step: number;
|
|
78
|
-
component?: string;
|
|
79
|
-
} | {
|
|
80
|
-
type: "error";
|
|
81
|
-
reason: "backend" | "timeout";
|
|
82
|
-
} | {
|
|
83
|
-
type: "retry";
|
|
84
|
-
reason: "backend" | "timeout";
|
|
85
|
-
attempt: number;
|
|
86
|
-
} | {
|
|
87
|
-
type: "fallback";
|
|
88
|
-
reason: "backend" | "timeout";
|
|
89
|
-
};
|
|
90
|
-
/**
|
|
91
|
-
* Copy overrides for the kit's built-in (English) strings, so a host can localize
|
|
92
|
-
* the loaders / completion fallback via its own i18n. Any field left unset keeps
|
|
93
|
-
* the kit default.
|
|
94
|
-
*/
|
|
95
|
-
type OnboardingCopy = {
|
|
96
|
-
/** First "thinking" screen, before any card arrives. */
|
|
97
|
-
startingTitle: string;
|
|
98
|
-
startingHint: string;
|
|
99
|
-
/** While the persisted session id is being restored from `storage` (pre-mount gate). */
|
|
100
|
-
restoringTitle: string;
|
|
101
|
-
restoringHint: string;
|
|
102
|
-
/** Between-turns loader, while the next card is generated. */
|
|
103
|
-
thinkingTitle: string;
|
|
104
|
-
thinkingHint: string;
|
|
105
|
-
/** While a per-step validator is running. */
|
|
106
|
-
checkingTitle: string;
|
|
107
|
-
checkingHint: string;
|
|
108
|
-
/** Completion fallback when the backend omits a title/CTA. */
|
|
109
|
-
completeTitle: string;
|
|
110
|
-
completeCta: string;
|
|
111
|
-
};
|
|
112
|
-
type WireOnboardingProps = {
|
|
113
|
-
config: WireOnboardingConfig;
|
|
114
|
-
/** Partial theme merged over the neutral default. */
|
|
115
|
-
theme?: Partial<OnboardingTheme>;
|
|
116
|
-
/** Override the registered cards (defaults to the kit's `onboardingComponents`). */
|
|
117
|
-
components?: wireai_rn.WireAIComponent[];
|
|
118
|
-
/**
|
|
119
|
-
* App-supplied artwork for InterstitialCard, keyed by name. The backend names one
|
|
120
|
-
* via `illustration`; the kit slots the matching node (keeping itself dependency-free).
|
|
121
|
-
*/
|
|
122
|
-
illustrations?: Record<string, React.ReactNode>;
|
|
123
|
-
/** Per-step validators keyed by base-question key, e.g. `{ username: checkUsername }`. */
|
|
124
|
-
validators?: Record<string, StepValidator>;
|
|
125
|
-
/** Fired once the flow reaches its terminal StatusCard. */
|
|
126
|
-
onComplete: (result: OnboardingResult) => void;
|
|
127
|
-
/**
|
|
128
|
-
* Retained for back-compat. NOTE: per-question Skip is now INTERNAL — the kit shows
|
|
129
|
-
* a Skip control only on screens the backend marks `skippable`, and it advances ONE
|
|
130
|
-
* question (it does not exit the flow). This callback is no longer wired to that control.
|
|
131
|
-
*/
|
|
132
|
-
onSkip?: () => void;
|
|
133
|
-
/**
|
|
134
|
-
* Fired on a backend error or first-card timeout, AFTER retries are exhausted.
|
|
135
|
-
* When `fallbackFlow` is NOT supplied and this is provided, the host owns recovery
|
|
136
|
-
* (e.g. navigate to its own static onboarding) instead of the kit's inline retry.
|
|
137
|
-
*/
|
|
138
|
-
onError?: (err: unknown) => void;
|
|
139
|
-
/**
|
|
140
|
-
* Your predefined STATIC onboarding, rendered in place when the AI flow fails and
|
|
141
|
-
* retries are exhausted — so a generation/backend/timeout error degrades to your
|
|
142
|
-
* static flow instead of breaking the app. Takes precedence over `onError`. This
|
|
143
|
-
* is the "it can never break your onboarding" guarantee: supply the same flow you
|
|
144
|
-
* shipped before adding Wire AI and the user always keeps moving.
|
|
145
|
-
*/
|
|
146
|
-
fallbackFlow?: React.ReactNode;
|
|
147
|
-
/**
|
|
148
|
-
* Consecutive failures to auto-retry before degrading to `fallbackFlow`/`onError`.
|
|
149
|
-
* Default 1 (one silent retry, then degrade). 0 = degrade on the first failure.
|
|
150
|
-
*/
|
|
151
|
-
maxRetries?: number;
|
|
152
|
-
/** Lifecycle hook for host-side analytics (started / per-turn / error). */
|
|
153
|
-
onEvent?: (event: OnboardingEvent) => void;
|
|
154
|
-
/**
|
|
155
|
-
* Host-injected, non-PII context the app already knows about the user — signup method,
|
|
156
|
-
* referral source, plan tier, a HASHED user id, etc. Same host-injection philosophy as
|
|
157
|
-
* `storage`: the kit collects nothing here; the host passes what it wants. Forwarded to the
|
|
158
|
-
* backend on the session metadata AND on client events so analytics can segment the funnel.
|
|
159
|
-
*
|
|
160
|
-
* MUST NOT contain PII such as raw emails, names, or phone numbers — pass a hash if you need
|
|
161
|
-
* a user key. Values are limited to primitives (`string | number | boolean`); the server caps
|
|
162
|
-
* key count / size and drops deep nesting. Old servers ignore it (backward compatible).
|
|
163
|
-
*/
|
|
164
|
-
userContext?: Record<string, string | number | boolean>;
|
|
165
|
-
/**
|
|
166
|
-
* The host's own user id, so onboarding sessions can be reconciled to real users later
|
|
167
|
-
* (console sessions ↔ your user table / GA4 users). First-class alongside `userContext`.
|
|
168
|
-
*
|
|
169
|
-
* An OPAQUE PSEUDONYMOUS string YOU own — your internal user id, NOT an email/name/phone.
|
|
170
|
-
* Trimmed and capped at 128 chars (longer is truncated). **No PII.**
|
|
171
|
-
*
|
|
172
|
-
* LATE BINDING: users often register DURING or AFTER onboarding, so this is fully optional
|
|
173
|
-
* and can arrive late:
|
|
174
|
-
* - present at MOUNT → rides the A2A session-start metadata (server binds it at session start);
|
|
175
|
-
* - CHANGES mid-session (e.g. the user just registered) → the kit emits an `identify` event
|
|
176
|
-
* that attaches the id to the LIVE session;
|
|
177
|
-
* - available only AFTER completion → capture the `contextId` from the `started`/`resumed`
|
|
178
|
-
* `onEvent` while the flow runs, then call `identifyOnboarding({ contextId, userId })` once
|
|
179
|
-
* the user registers. Completion clears the persisted session, so the captured `contextId`
|
|
180
|
-
* is the reliable post-flow handle.
|
|
181
|
-
*
|
|
182
|
-
* Backward compatible: omit it and nothing changes; old servers ignore the extra field.
|
|
183
|
-
*/
|
|
184
|
-
userId?: string;
|
|
185
|
-
/** Localized overrides for the kit's built-in English strings. */
|
|
186
|
-
copy?: Partial<OnboardingCopy>;
|
|
187
|
-
/**
|
|
188
|
-
* Approximate total number of screens, if known (e.g. the backend screen budget).
|
|
189
|
-
* Paces the progress bar as `step / approxScreens` (capped, never shown as a
|
|
190
|
-
* number) instead of the asymptotic default. A backend-supplied `progress.total`
|
|
191
|
-
* takes precedence when present.
|
|
192
|
-
*/
|
|
193
|
-
approxScreens?: number;
|
|
194
|
-
/** First message that kicks off the backend flow. Default `"start"`. */
|
|
195
|
-
startMessage?: string;
|
|
196
|
-
/** Ms to wait for the first card before showing the error/retry state. Default 15000. */
|
|
197
|
-
startTimeoutMs?: number;
|
|
198
|
-
/**
|
|
199
|
-
* Host-injected storage for session-id persistence (AsyncStorage-compatible subset:
|
|
200
|
-
* pass `@react-native-async-storage/async-storage` as-is, or a small MMKV wrapper).
|
|
201
|
-
* When set, the kit caches its session id so an app KILL mid-onboarding resumes the
|
|
202
|
-
* SAME backend session instead of minting a new one — keeping the analytics funnel's
|
|
203
|
-
* `started` count honest (no phantom drops). Omit for the previous per-mount behavior.
|
|
204
|
-
* This persists the kit's own correlation seed only — never answers.
|
|
205
|
-
*/
|
|
206
|
-
storage?: WireOnboardingStorage;
|
|
207
|
-
/**
|
|
208
|
-
* How long a persisted session id stays resumable, in ms. Default 3 600 000 (1h),
|
|
209
|
-
* matching the backend's session TTL. Only meaningful with `storage`.
|
|
210
|
-
*/
|
|
211
|
-
sessionTtlMs?: number;
|
|
212
|
-
/**
|
|
213
|
-
* Override the storage key (default `wireai:session:<config.appId>`). Scope it
|
|
214
|
-
* per-user (e.g. append a user id) if one device can run onboarding for multiple
|
|
215
|
-
* accounts mid-flow. Only meaningful with `storage`.
|
|
216
|
-
*/
|
|
217
|
-
persistKey?: string;
|
|
218
|
-
};
|
|
219
|
-
/** Backend-supplied progress, read off `response.props.progress` when present. */
|
|
220
|
-
type OnboardingProgress = {
|
|
221
|
-
step: number;
|
|
222
|
-
total: number;
|
|
223
|
-
/** Base-question key for the CURRENT screen, when known (used to pick a validator). */
|
|
224
|
-
key?: string;
|
|
225
|
-
/** Whether the CURRENT screen may be skipped (backend-marked; default false → no Skip shown). */
|
|
226
|
-
skippable?: boolean;
|
|
227
|
-
};
|
|
8
|
+
import { WireAIComponent, Message, WireAIResponse } from 'wireai-rn';
|
|
9
|
+
import { a as WireFeaturesConfig, W as WireFeatures, b as WireOnboardingStorage } from './types-CMuOexw0.js';
|
|
10
|
+
export { D as DEFAULT_SESSION_TTL_MS, L as LoadedSession, O as OnboardingMode, c as clearPersistedSession, l as loadPersistedSession, p as peekPersistedSession, s as savePersistedSession, d as sessionStorageKey } from './types-CMuOexw0.js';
|
|
11
|
+
import 'react-native';
|
|
228
12
|
|
|
229
13
|
/**
|
|
230
14
|
* WireOnboarding — the public host component. Drop it into a screen and it runs
|
|
@@ -764,160 +548,6 @@ declare const InterstitialCard: WireAIComponent;
|
|
|
764
548
|
|
|
765
549
|
declare const onboardingComponents: WireAIComponent[];
|
|
766
550
|
|
|
767
|
-
/**
|
|
768
|
-
* deviceContext — collect a small, privacy-label-neutral snapshot of the device so
|
|
769
|
-
* onboarding analytics can segment the funnel (platform / form factor / locale) WITHOUT
|
|
770
|
-
* adding a single dependency to the kit or changing a host app's App Privacy / Data Safety
|
|
771
|
-
* declarations.
|
|
772
|
-
*
|
|
773
|
-
* HARD RULE (why this file has no imports beyond React Native built-ins):
|
|
774
|
-
* The kit stays dependency-free. Everything here comes from `Platform`, `Dimensions`,
|
|
775
|
-
* `I18nManager`, and the standard `Intl` global. There are NO advertising IDs, NO
|
|
776
|
-
* `getUniqueId`/IDFA/GAID/fingerprinting APIs, and nothing that would require a new
|
|
777
|
-
* privacy-label entry. A host can adopt this without touching its store declarations.
|
|
778
|
-
*
|
|
779
|
-
* DEFENSIVE BY DESIGN: `collectDeviceContext()` never throws. Every read is guarded and
|
|
780
|
-
* a missing/unavailable field is simply omitted (Hermes may ship without full `Intl`,
|
|
781
|
-
* `Platform.constants` differs per OS and RN version, etc.). Analytics must never be able
|
|
782
|
-
* to break onboarding.
|
|
783
|
-
*/
|
|
784
|
-
|
|
785
|
-
/** Coarse device class. iOS uses the reported interface idiom; else a screen-size heuristic. */
|
|
786
|
-
type DeviceFormFactor = "phone" | "tablet";
|
|
787
|
-
/**
|
|
788
|
-
* A privacy-label-neutral device snapshot. ALL fields except `platform` are optional and are
|
|
789
|
-
* omitted when unavailable. Nothing here identifies a user or device uniquely.
|
|
790
|
-
*/
|
|
791
|
-
type DeviceContext = {
|
|
792
|
-
/** `Platform.OS` — "ios" | "android" | "windows" | "macos" | "web". Always present. */
|
|
793
|
-
platform: typeof Platform.OS;
|
|
794
|
-
/** OS version string (iOS `osVersion`/`Platform.Version`, Android `Release`). */
|
|
795
|
-
osVersion?: string;
|
|
796
|
-
/** Android device brand (e.g. "samsung"). Android only. */
|
|
797
|
-
brand?: string;
|
|
798
|
-
/** Android device model (e.g. "SM-G991B"). Android only. */
|
|
799
|
-
model?: string;
|
|
800
|
-
/** iOS interface idiom ("phone" | "pad" | …), when reported. iOS only. */
|
|
801
|
-
interfaceIdiom?: string;
|
|
802
|
-
/** Derived device class. */
|
|
803
|
-
formFactor?: DeviceFormFactor;
|
|
804
|
-
/** `Dimensions.get('screen')` width in dp. */
|
|
805
|
-
screenWidth?: number;
|
|
806
|
-
/** `Dimensions.get('screen')` height in dp. */
|
|
807
|
-
screenHeight?: number;
|
|
808
|
-
/** Screen pixel density (`scale`). */
|
|
809
|
-
screenScale?: number;
|
|
810
|
-
/** Right-to-left layout (`I18nManager.isRTL`). */
|
|
811
|
-
isRTL?: boolean;
|
|
812
|
-
/** Resolved locale (e.g. "en-US"), from `Intl` when available. */
|
|
813
|
-
locale?: string;
|
|
814
|
-
/** IANA time zone (e.g. "Europe/Berlin"), from `Intl` when available. */
|
|
815
|
-
timeZone?: string;
|
|
816
|
-
/**
|
|
817
|
-
* Host app version (e.g. "1.4.2). HOST-INJECTED — NOT collected here. `WireOnboarding`
|
|
818
|
-
* merges `config.appVersion` into the snapshot; `collectDeviceContext()` never sets it.
|
|
819
|
-
* Hosts typically pass it from `expo-constants` (the kit itself adds no dependency).
|
|
820
|
-
*/
|
|
821
|
-
appVersion?: string;
|
|
822
|
-
};
|
|
823
|
-
/**
|
|
824
|
-
* Collect the device snapshot. Pure, synchronous, and never throws — call it once per
|
|
825
|
-
* onboarding session. Missing fields are omitted rather than sent as null/undefined so the
|
|
826
|
-
* payload (and the server's stored dict) stays compact.
|
|
827
|
-
*/
|
|
828
|
-
declare const collectDeviceContext: () => DeviceContext;
|
|
829
|
-
|
|
830
|
-
/**
|
|
831
|
-
* reportClientEvent — forward DEVICE-ONLY onboarding events to the Wire AI analytics
|
|
832
|
-
* backend (`POST {serverUrl}/v1/events`), completing the funnel for events the server
|
|
833
|
-
* can't observe on its own.
|
|
834
|
-
*
|
|
835
|
-
* The backend already records the server-observable funnel during the A2A flow
|
|
836
|
-
* (`session_started`, `screen_shown`, `answer_submitted`, `completed`, `llm_fallback`,
|
|
837
|
-
* and even `screen_skipped` — it derives that from the kit's skip sentinel). The one
|
|
838
|
-
* event no server request can capture is `dropped`: the user closing the app / unmounting
|
|
839
|
-
* the flow without finishing. That's what this reporter is for.
|
|
840
|
-
*
|
|
841
|
-
* Contract (server: routers/onboarding.py → analytics/events.py):
|
|
842
|
-
* POST {serverUrl}/v1/events
|
|
843
|
-
* Authorization: Bearer {apiKey}
|
|
844
|
-
* { "events": [ { event_type, session_id, screen_index?, component?, question_key?,
|
|
845
|
-
* latency_ms?, meta?, device?, user_context? } ] }
|
|
846
|
-
* The server fills `app_id` + `environment` from the resolving key (never send app_id),
|
|
847
|
-
* and silently skips malformed events — one bad payload never fails the batch.
|
|
848
|
-
*
|
|
849
|
-
* ⚠️ Correlation: `session_id` MUST equal the A2A `contextId` the server uses to key the
|
|
850
|
-
* server-side events, or the funnel report (which groups by `session_id`) treats this as a
|
|
851
|
-
* phantom session. See `makeSessionId` + WireOnboarding for how the kit seeds it.
|
|
852
|
-
*
|
|
853
|
-
* Fire-and-forget: this never throws into the UI and never awaits — analytics must never
|
|
854
|
-
* be able to break onboarding.
|
|
855
|
-
*/
|
|
856
|
-
|
|
857
|
-
/** Event types a CLIENT may report. The rest of the funnel is server-side; sending those
|
|
858
|
-
* here would double-count. `screen_skipped` is included for completeness, but the kit does
|
|
859
|
-
* NOT emit it — the backend already derives it from the skip sentinel (see OnboardingFlow).
|
|
860
|
-
* `client_fallback` is emitted by the kit when the AI flow degrades to the static fallback,
|
|
861
|
-
* so the dashboard's fallback-rate counts the whole-flow case (distinct from the server's
|
|
862
|
-
* per-turn `llm_fallback`). The server back-fills a `session_started` for it if unseen.
|
|
863
|
-
* This is the SINGLE fallback signal — hosts must NOT also report their own.
|
|
864
|
-
* `identify` binds the host's opaque `user_id` to this `session_id` (late binding — the user
|
|
865
|
-
* registered during/after onboarding). It carries no funnel weight; the server maps the
|
|
866
|
-
* session to the user and back-fills a `session_started` if it never saw the session. */
|
|
867
|
-
type ClientEventType = "screen_skipped" | "dropped" | "client_fallback" | "identify";
|
|
868
|
-
/** One client-reported event. Mirrors the server's `OnboardingEvent` (client-settable fields). */
|
|
869
|
-
type ClientEvent = {
|
|
870
|
-
event_type: ClientEventType;
|
|
871
|
-
/** Must match the server-side A2A contextId for this onboarding (see makeSessionId). */
|
|
872
|
-
session_id: string;
|
|
873
|
-
/** 0-based index of the screen the event refers to (matches server `screen_shown`). */
|
|
874
|
-
screen_index?: number;
|
|
875
|
-
component?: string;
|
|
876
|
-
question_key?: string;
|
|
877
|
-
latency_ms?: number;
|
|
878
|
-
/** JSON-stringified extras; the server stores it verbatim. */
|
|
879
|
-
meta?: string;
|
|
880
|
-
/**
|
|
881
|
-
* Privacy-label-neutral device snapshot (platform / form factor / locale / host appVersion).
|
|
882
|
-
* Sent as an object; the server sanitizes + persists it and derives a coarse country. Old
|
|
883
|
-
* servers ignore this unknown field — fully backward compatible. See device/deviceContext.ts.
|
|
884
|
-
*/
|
|
885
|
-
device?: DeviceContext;
|
|
886
|
-
/**
|
|
887
|
-
* Host-injected, non-PII context (signup method, referral, plan, hashed user id). Old servers
|
|
888
|
-
* ignore it. MUST NOT contain PII like raw emails — see the README `userContext` section.
|
|
889
|
-
*/
|
|
890
|
-
user_context?: Record<string, string | number | boolean>;
|
|
891
|
-
/**
|
|
892
|
-
* The host's OPAQUE PSEUDONYMOUS user id (their internal id, NOT an email/name). Required on
|
|
893
|
-
* `identify`, optional (rides along) on other events. Trimmed + capped at 128 chars host-side.
|
|
894
|
-
* Lets the backend reconcile onboarding sessions to real users. Old servers ignore it.
|
|
895
|
-
*/
|
|
896
|
-
user_id?: string;
|
|
897
|
-
};
|
|
898
|
-
/** Where to POST. Derived from `WireOnboardingConfig` (`serverUrl` + `apiKey`). */
|
|
899
|
-
type ClientEventTarget = {
|
|
900
|
-
/** Base server URL (same as `WireOnboardingConfig.serverUrl`); `/v1/events` is appended. */
|
|
901
|
-
serverUrl: string;
|
|
902
|
-
/** Tenant API key; sent as `Authorization: Bearer`. */
|
|
903
|
-
apiKey: string;
|
|
904
|
-
};
|
|
905
|
-
/**
|
|
906
|
-
* A unique-per-onboarding session id. Used both as the client event `session_id` AND as the
|
|
907
|
-
* seed the kit forwards to the backend so the SERVER adopts it as the A2A `contextId` — making
|
|
908
|
-
* client and server agree (see WireOnboarding + the SDK-correlation note in the kit docs).
|
|
909
|
-
* No crypto dependency: timestamp + random is collision-safe for a single device's onboarding.
|
|
910
|
-
*/
|
|
911
|
-
declare const makeSessionId: () => string;
|
|
912
|
-
/**
|
|
913
|
-
* POST one or more client events, fire-and-forget. A missing/invalid target, a build error,
|
|
914
|
-
* a missing `fetch`, or a network failure is swallowed — the call returns immediately and the
|
|
915
|
-
* request (if any) runs in the background.
|
|
916
|
-
*/
|
|
917
|
-
declare const reportClientEvents: (target: ClientEventTarget | undefined, events: ClientEvent[]) => void;
|
|
918
|
-
/** Convenience single-event wrapper around {@link reportClientEvents}. */
|
|
919
|
-
declare const reportClientEvent: (target: ClientEventTarget | undefined, event: ClientEvent) => void;
|
|
920
|
-
|
|
921
551
|
/**
|
|
922
552
|
* OnboardingFlow — the inner engine. Mirrors the proven production-app usage of the SDK
|
|
923
553
|
* (useWireAIThread + useWireAIAction + ComponentRenderer) and layers on the kit's
|
|
@@ -1034,7 +664,7 @@ declare const useWireFeatures: (config?: WireFeaturesConfig) => WireFeatures;
|
|
|
1034
664
|
*
|
|
1035
665
|
* NOTE on the built npm subpaths: React context is shared across the kit's subpath entries in the
|
|
1036
666
|
* SOURCE-consumption path (the monorepo apps) and in this test suite — one module instance, one
|
|
1037
|
-
* context. If you consume the built
|
|
667
|
+
* context. If you consume the built `@wireai/activation/*` subpaths as separate bundles, pass the
|
|
1038
668
|
* resolved flags (or a `featuresConfig`) to each surface explicitly instead of relying on context.
|
|
1039
669
|
*/
|
|
1040
670
|
|
|
@@ -1156,46 +786,6 @@ type OnboardingFlagOptions = {
|
|
|
1156
786
|
};
|
|
1157
787
|
declare const isOnboardingEnabled: (opts?: OnboardingFlagOptions) => boolean;
|
|
1158
788
|
|
|
1159
|
-
/**
|
|
1160
|
-
* Canonical analytics names for the onboarding funnel. The kit already emits a typed
|
|
1161
|
-
* `OnboardingEvent` (`started | turn | error | retry | fallback`) — but one app logged them as
|
|
1162
|
-
* `onboarding_*` and another as `AI_ONBOARDING_*`, so the same funnel reads differently per app.
|
|
1163
|
-
* This maps the kit event to ONE canonical `wire_onboarding_*` name + params, and the app logs
|
|
1164
|
-
* it through whatever transport it already has (Firebase, Amplitude, console). The app still
|
|
1165
|
-
* owns the logger; only the NAMES are standardized.
|
|
1166
|
-
*
|
|
1167
|
-
* <WireOnboarding
|
|
1168
|
-
* onEvent={(e) => { const a = toAnalyticsEvent(e); logEvent(a.name, a.params); }}
|
|
1169
|
-
* onComplete={(r) => { logEvent(WIRE_ONBOARDING_EVENTS.completed, { answers: Object.keys(r.answers).length }); persist(r); }}
|
|
1170
|
-
* />
|
|
1171
|
-
*
|
|
1172
|
-
* `completed` has no kit `OnboardingEvent` (the kit signals completion via `onComplete`, not
|
|
1173
|
-
* `onEvent`) — the app logs it explicitly on `onComplete` using the constant below, so the
|
|
1174
|
-
* funnel name stays canonical.
|
|
1175
|
-
*/
|
|
1176
|
-
|
|
1177
|
-
declare const WIRE_ONBOARDING_EVENTS: {
|
|
1178
|
-
readonly started: "wire_onboarding_started";
|
|
1179
|
-
/** A persisted session was restored after an app kill (fires instead of `started`). */
|
|
1180
|
-
readonly resumed: "wire_onboarding_resumed";
|
|
1181
|
-
readonly turn: "wire_onboarding_turn";
|
|
1182
|
-
readonly error: "wire_onboarding_error";
|
|
1183
|
-
readonly retry: "wire_onboarding_retry";
|
|
1184
|
-
readonly fallback: "wire_onboarding_fallback";
|
|
1185
|
-
/** Logged by the host on `onComplete` (no matching kit `OnboardingEvent`). */
|
|
1186
|
-
readonly completed: "wire_onboarding_completed";
|
|
1187
|
-
};
|
|
1188
|
-
type WireOnboardingEventName = (typeof WIRE_ONBOARDING_EVENTS)[keyof typeof WIRE_ONBOARDING_EVENTS];
|
|
1189
|
-
type AnalyticsEvent = {
|
|
1190
|
-
name: WireOnboardingEventName;
|
|
1191
|
-
params?: Record<string, unknown>;
|
|
1192
|
-
};
|
|
1193
|
-
/**
|
|
1194
|
-
* Map a kit `OnboardingEvent` to its canonical `{ name, params }`. Exhaustive over the union
|
|
1195
|
-
* (the `never` default makes a new event type a compile error here — intentional).
|
|
1196
|
-
*/
|
|
1197
|
-
declare const toAnalyticsEvent: (event: OnboardingEvent) => AnalyticsEvent;
|
|
1198
|
-
|
|
1199
789
|
/**
|
|
1200
790
|
* attribution — forward install/ad attribution to the onboarding agent so it can tailor the
|
|
1201
791
|
* first question by acquisition source (e.g. a paid-campaign install vs an organic one). The
|
|
@@ -1347,6 +937,15 @@ interface ReportSessionStartOptions {
|
|
|
1347
937
|
meta?: Record<string, unknown>;
|
|
1348
938
|
/** Set `false` to bypass the once-per-open guard (default on). See {@link resetSessionStartGuard}. */
|
|
1349
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;
|
|
1350
949
|
}
|
|
1351
950
|
/** Test-only: forget every emitted session id so a unit test starts from a clean guard. */
|
|
1352
951
|
declare const resetSessionStartGuard: () => void;
|
|
@@ -1387,4 +986,149 @@ interface UseSessionStartOptions {
|
|
|
1387
986
|
*/
|
|
1388
987
|
declare const useSessionStart: (config: SessionStartConfig | undefined, options?: UseSessionStartOptions) => void;
|
|
1389
988
|
|
|
1390
|
-
|
|
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 };
|