@wireai/activation 0.3.0 → 0.7.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.
Files changed (75) hide show
  1. package/AGENTS.md +1 -1
  2. package/CHANGELOG.md +57 -0
  3. package/dist/analytics/index.d.mts +15 -2
  4. package/dist/analytics/index.d.ts +15 -2
  5. package/dist/analytics/index.js +224 -14
  6. package/dist/analytics/index.js.map +1 -1
  7. package/dist/analytics/index.mjs +222 -15
  8. package/dist/analytics/index.mjs.map +1 -1
  9. package/dist/coachmarks/index.js +6 -1
  10. package/dist/coachmarks/index.js.map +1 -1
  11. package/dist/coachmarks/index.mjs +6 -1
  12. package/dist/coachmarks/index.mjs.map +1 -1
  13. package/dist/{eventQueue-CA1d8Fmn.d.mts → currentSession-BJBB7i4-.d.mts} +143 -15
  14. package/dist/{eventQueue-CrNB9gzH.d.ts → currentSession-CxnP7gAa.d.ts} +143 -15
  15. package/dist/index.d.mts +40 -39
  16. package/dist/index.d.ts +40 -39
  17. package/dist/index.js +378 -154
  18. package/dist/index.js.map +1 -1
  19. package/dist/index.mjs +370 -156
  20. package/dist/index.mjs.map +1 -1
  21. package/dist/questionnaire/index.d.mts +1 -1
  22. package/dist/questionnaire/index.d.ts +1 -1
  23. package/dist/questionnaire/index.js +29 -5
  24. package/dist/questionnaire/index.js.map +1 -1
  25. package/dist/questionnaire/index.mjs +30 -6
  26. package/dist/questionnaire/index.mjs.map +1 -1
  27. package/dist/reviews/index.d.mts +1 -1
  28. package/dist/reviews/index.d.ts +1 -1
  29. package/dist/reviews/index.js +40 -9
  30. package/dist/reviews/index.js.map +1 -1
  31. package/dist/reviews/index.mjs +42 -11
  32. package/dist/reviews/index.mjs.map +1 -1
  33. package/dist/showcase/index.d.mts +1 -14
  34. package/dist/showcase/index.d.ts +1 -14
  35. package/dist/showcase/index.js +8 -2
  36. package/dist/showcase/index.js.map +1 -1
  37. package/dist/showcase/index.mjs +8 -2
  38. package/dist/showcase/index.mjs.map +1 -1
  39. package/package.json +3 -2
  40. package/src/OnboardingFlow.tsx +8 -4
  41. package/src/WireOnboarding.tsx +12 -6
  42. package/src/analytics/analyticsFacade.ts +86 -10
  43. package/src/analytics/contextEnvelope.ts +13 -7
  44. package/src/analytics/currentSession.ts +35 -0
  45. package/src/analytics/eventQueue.ts +5 -0
  46. package/src/analytics/index.ts +3 -0
  47. package/src/analytics/useAnalytics.ts +7 -1
  48. package/src/analytics/useScreenTracking.ts +23 -1
  49. package/src/cards/InterstitialCard.tsx +1 -1
  50. package/src/cards/NumberStepperCard.tsx +12 -7
  51. package/src/cards/StatusCard.tsx +13 -8
  52. package/src/cards/TextInputCard.tsx +10 -5
  53. package/src/components/AnimatedSparkle.tsx +20 -3
  54. package/src/components/Button.tsx +10 -1
  55. package/src/components/CardHandoff.tsx +2 -6
  56. package/src/components/CardLayout.tsx +16 -10
  57. package/src/components/Illustration.tsx +9 -5
  58. package/src/components/LoadingBlock.tsx +44 -29
  59. package/src/components/LoadingScreen.tsx +3 -2
  60. package/src/components/OnboardingScaffold.tsx +21 -23
  61. package/src/context/userContext.ts +210 -0
  62. package/src/device/appVersion.ts +103 -0
  63. package/src/device/deviceContext.ts +17 -5
  64. package/src/features/WireFeaturesProvider.tsx +7 -2
  65. package/src/identity/userIdentity.ts +5 -0
  66. package/src/index.ts +23 -0
  67. package/src/questionnaire/QuestionnaireGate.tsx +15 -3
  68. package/src/reviews/ReviewGate.tsx +27 -7
  69. package/src/reviews/ReviewModal.tsx +4 -0
  70. package/src/session-analytics/reportSessionStart.ts +7 -0
  71. package/src/session-analytics/useLifecycleEvents.ts +4 -2
  72. package/src/session-analytics/useSessionStart.ts +2 -1
  73. package/src/showcase/FeatureShowcase.tsx +2 -1
  74. package/src/types.ts +6 -5
  75. package/src/components/loaderChrome.ts +0 -28
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 { 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';
3
+ import { o as WireOnboardingProps, p as WireOnboardingConfig, O as OnboardingResult, S as StepValidator, q as OnboardingEvent, u as OnboardingCopy, a as ClientEventTarget, D as DeviceContext, C as ClientEvent, e as EnvelopeSource } from './currentSession-CxnP7gAa.js';
4
+ export { A as AnalyticsEvent, b as ClientEventType, v as DeviceFormFactor, w as EXTRA_KEY_PREFIX, x as OnboardingProgress, R as RESERVED_USER_CONTEXT_KEYS, y as ResolveUserContextOptions, z as ResolvedUserContext, g as WIRE_ONBOARDING_EVENTS, h as WireOnboardingEventName, W as WireUserContext, B as collectDeviceContext, k as getCurrentSessionId, F as hashEmailFnv1a, G as isWireScalar, m as makeSessionId, H as namespaceExtra, r as reportClientEvent, l as reportClientEvents, n as resetCurrentSessionId, I as resolveUserContext, s as setCurrentSessionId, t as toAnalyticsEvent } from './currentSession-CxnP7gAa.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';
@@ -186,8 +186,9 @@ declare const LoadingBlock: React__default.NamedExoticComponent<LoadingBlockProp
186
186
  * WHY a dedicated frame: those slots used to return a bare <LoadingBlock/>, whose flex:1 only
187
187
  * fills whatever the host happened to give it — with no safe area and, if the host didn't
188
188
  * bound it, no height at all (top-anchored). This wraps them in the same SafeAreaView the flow
189
- * uses, so the standalone loaders center exactly like the between-turns loader (which centers
190
- * in the full flow area via the scaffold's loaderChrome offset). One consistent centered look.
189
+ * uses, so the standalone loaders center exactly like the between-turns loader (both fill their
190
+ * parent flex:1 region and center in it — here the SafeAreaView, in the flow the scaffold body).
191
+ * One consistent centered look.
191
192
  */
192
193
 
193
194
  declare const LoadingScreen: React__default.NamedExoticComponent<LoadingBlockProps>;
@@ -825,6 +826,40 @@ declare const attributionMetadata: (a: OnboardingAttribution) => {
825
826
  attribution: Record<string, unknown>;
826
827
  };
827
828
 
829
+ /**
830
+ * appVersion — best-effort, DEPENDENCY-FREE auto-detection of the host app's version string.
831
+ *
832
+ * WHY this exists: analytics segments the funnel `by_app_version`, but that breakdown is only
833
+ * populated when a `device.appVersion` rides the event. `config.appVersion` (see types.ts) has
834
+ * always been the way to supply it — but it is easy for a host to forget, and then the release
835
+ * breakdown is silently empty. This module fills that gap: when the host does NOT pass a version,
836
+ * the kit makes a best-effort read of the app version the host already ships in its Expo config,
837
+ * so the breakdown works out of the box. An explicit `config.appVersion` always WINS over this.
838
+ *
839
+ * WHY it adds NO dependency (the kit's hard rule): `expo-constants` / `expo-application` are read
840
+ * through a GUARDED, VARIABLE-specifier `require`. Passing a variable (not a string literal) keeps
841
+ * Metro/esbuild from statically resolving the module, so a host that does NOT have it installed
842
+ * (e.g. bare React Native) never fails to bundle — the require simply throws at runtime and is
843
+ * swallowed. Nothing is added to `package.json`; nothing is forced on the host.
844
+ *
845
+ * PRIVACY: an app version string is not PII and identifies no user or device, so surfacing it
846
+ * changes no App Privacy / Data Safety declaration (same guarantee as the rest of deviceContext).
847
+ *
848
+ * NEVER THROWS: every read is guarded; a missing/odd value yields `undefined`, never an exception.
849
+ * Analytics must never be able to break onboarding.
850
+ */
851
+ /** A `require`-like resolver. Injectable in tests; production uses the guarded runtime require. */
852
+ type OptionalRequire = (moduleName: string) => unknown;
853
+ /**
854
+ * Detect the host app version, preferring `expo-constants` (`expoConfig.version`, then
855
+ * `nativeAppVersion`) and finally `expo-application` (`nativeApplicationVersion`). Returns the
856
+ * first real string, or `undefined` when none of those are available. Pure and never throws.
857
+ *
858
+ * `requireModule` is injectable so tests can exercise the "found" path without the native modules;
859
+ * production defaults to the guarded runtime require above.
860
+ */
861
+ declare const detectAppVersion: (requireModule?: OptionalRequire) => string | undefined;
862
+
828
863
  /** Max accepted user-id length. Longer strings are truncated (never rejected). Keep in sync
829
864
  * with the server's `USER_ID_MAX_LENGTH` (analytics/events.py). */
830
865
  declare const USER_ID_MAX_LENGTH = 128;
@@ -871,40 +906,6 @@ type IdentifyOnboardingOptions = {
871
906
  */
872
907
  declare const identifyOnboarding: (opts: IdentifyOnboardingOptions) => Promise<boolean>;
873
908
 
874
- /**
875
- * reportSessionStart — the ONE standard emitter for "the user opened the app again".
876
- *
877
- * Every app-open posts a single `app.session_started` event to the Wire analytics backend
878
- * (`POST {serverUrl}/v1/events`). That event does two jobs at once, with ZERO server changes:
879
- *
880
- * 1. SESSION MAPPING. It carries the host's opaque `userId` + a stable `deviceKey`, so the
881
- * backend can group a user's (or a pre-auth device's) opens over time — "when did this
882
- * user last use the app, and how many times". The device_key links the pre-auth opens to
883
- * the user once `userId` arrives (here or via `identifyOnboarding`).
884
- * 2. QUESTIONNAIRE / RETENTION FIRING. It flows into the SAME event stream the server's
885
- * decision engines read, so a questionnaire trigger `{event:"app.session_started", min_count:N}`
886
- * (matched within a session) or a questionnaire `min_sessions:N` (distinct device sessions)
887
- * fires on the user's Nth open with no new server endpoint.
888
- *
889
- * WIRE CONTRACT (server: analytics/events.py + routers/onboarding.py `POST /v1/events`):
890
- * The event is stored as `event_type='app_event'`, `question_key='app.session_started'` — the
891
- * generic app.* namespace the reviews wave shipped. The server's `_event_name(ev)` returns the
892
- * `question_key` for an `app_event`, which is what a trigger's `event` string matches. We do NOT
893
- * send `event_type:'app.session_started'` — that name is not in the server's EVENT_TYPES and
894
- * would be rejected. `device_key` rides in the non-PII `user_context` bucket, where the server's
895
- * `_event_device_key(ev)` reads it to group a device's sessions. `app_id` + `environment` are
896
- * filled server-side from the resolving key (never sent here).
897
- *
898
- * SESSION ID DISTINCTION (important): the `session_id` on this event is a PER-OPEN id (a fresh
899
- * `makeSessionId()` each app-open) — it is NOT the onboarding A2A `contextId`. Onboarding runs
900
- * ONCE (first launch) and owns its own context id; session-start fires on EVERY open, so it needs
901
- * its own per-open id. Grouping over time is done by `device_key`/`user_id`, not by session_id.
902
- *
903
- * Fire-and-forget: like every analytics path in the kit, this never throws into the UI, never
904
- * awaits, and swallows a missing target / bad URL / missing fetch / network error. Analytics must
905
- * never be able to break the app.
906
- */
907
-
908
909
  /** The canonical event name for an app-open. A trigger keys off this exact string. */
909
910
  declare const SESSION_STARTED_EVENT: "app.session_started";
910
911
  /** Options for {@link reportSessionStart}. Everything except `target` is optional so a pre-auth
@@ -1131,4 +1132,4 @@ interface UseLifecycleEventsOptions {
1131
1132
  */
1132
1133
  declare const useLifecycleEvents: (config: LifecycleConfig | undefined, options?: UseLifecycleEventsOptions) => void;
1133
1134
 
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 };
1135
+ 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, detectAppVersion, 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 };