@wireai/activation 0.7.0 → 0.8.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/CHANGELOG.md +35 -0
- package/dist/analytics/index.d.mts +8 -4
- package/dist/analytics/index.d.ts +8 -4
- package/dist/analytics/index.js +83 -11
- package/dist/analytics/index.js.map +1 -1
- package/dist/analytics/index.mjs +83 -11
- package/dist/analytics/index.mjs.map +1 -1
- package/dist/{currentSession-BJBB7i4-.d.mts → currentSession-d9CrBxwe.d.mts} +9 -1
- package/dist/{currentSession-CxnP7gAa.d.ts → currentSession-f7LWcdWG.d.ts} +9 -1
- package/dist/index.d.mts +69 -5
- package/dist/index.d.ts +69 -5
- package/dist/index.js +56 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +53 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/analytics/analyticsFacade.ts +55 -10
- package/src/context/deviceId.ts +43 -0
- package/src/device/deviceContext.ts +14 -1
- package/src/device/deviceModel.ts +93 -0
- package/src/index.ts +2 -0
|
@@ -39,7 +39,15 @@ type DeviceContext = {
|
|
|
39
39
|
osVersion?: string;
|
|
40
40
|
/** Android device brand (e.g. "samsung"). Android only. */
|
|
41
41
|
brand?: string;
|
|
42
|
-
/**
|
|
42
|
+
/**
|
|
43
|
+
* Device model. On Android it is read directly from `Platform.constants.Model` (e.g. "SM-G991B").
|
|
44
|
+
* iOS `Platform.constants` exposes NO model, so on iOS it is a BEST-EFFORT read of `expo-device`'s
|
|
45
|
+
* `modelName` ("iPhone 14 Pro"), falling back to `modelId` ("iPhone15,2") — dependency-free via a
|
|
46
|
+
* guarded require (see device/deviceModel.ts). ASYMMETRY: without `expo-device` installed, iOS
|
|
47
|
+
* `model` is omitted (there is no dependency-free iOS model in the already-used RN surface, and the
|
|
48
|
+
* kit will not add a native dep for it); Android needs no extra module. Not PII (a device class,
|
|
49
|
+
* not a unique id), so it changes no privacy-label declaration.
|
|
50
|
+
*/
|
|
43
51
|
model?: string;
|
|
44
52
|
/** iOS interface idiom ("phone" | "pad" | …), when reported. iOS only. */
|
|
45
53
|
interfaceIdiom?: string;
|
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 { 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-
|
|
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-
|
|
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-d9CrBxwe.mjs';
|
|
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-d9CrBxwe.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';
|
|
@@ -849,7 +849,7 @@ declare const attributionMetadata: (a: OnboardingAttribution) => {
|
|
|
849
849
|
* Analytics must never be able to break onboarding.
|
|
850
850
|
*/
|
|
851
851
|
/** A `require`-like resolver. Injectable in tests; production uses the guarded runtime require. */
|
|
852
|
-
type OptionalRequire = (moduleName: string) => unknown;
|
|
852
|
+
type OptionalRequire$1 = (moduleName: string) => unknown;
|
|
853
853
|
/**
|
|
854
854
|
* Detect the host app version, preferring `expo-constants` (`expoConfig.version`, then
|
|
855
855
|
* `nativeAppVersion`) and finally `expo-application` (`nativeApplicationVersion`). Returns the
|
|
@@ -858,7 +858,40 @@ type OptionalRequire = (moduleName: string) => unknown;
|
|
|
858
858
|
* `requireModule` is injectable so tests can exercise the "found" path without the native modules;
|
|
859
859
|
* production defaults to the guarded runtime require above.
|
|
860
860
|
*/
|
|
861
|
-
declare const detectAppVersion: (requireModule?: OptionalRequire) => string | undefined;
|
|
861
|
+
declare const detectAppVersion: (requireModule?: OptionalRequire$1) => string | undefined;
|
|
862
|
+
|
|
863
|
+
/**
|
|
864
|
+
* deviceModel — best-effort, DEPENDENCY-FREE detection of the device MODEL on iOS.
|
|
865
|
+
*
|
|
866
|
+
* WHY this exists (the asymmetry it closes): `collectDeviceContext` already reports `device.model`
|
|
867
|
+
* on Android straight from `Platform.constants.Model` (e.g. "SM-G991B"), but iOS `Platform.constants`
|
|
868
|
+
* exposes NO model — only `osVersion` / `interfaceIdiom`. So the analytics `by_model` breakdown was
|
|
869
|
+
* Android-only. This module fills the iOS gap with the SAME zero-dependency technique the kit already
|
|
870
|
+
* uses for `appVersion` (see device/appVersion.ts): a GUARDED, VARIABLE-specifier `require` of the
|
|
871
|
+
* common Expo `expo-device` module. If the host has it, iOS gets a model out of the box; if not, the
|
|
872
|
+
* require simply throws and is swallowed and iOS `model` stays omitted — nothing is forced, nothing
|
|
873
|
+
* is added to `package.json`, and a host without `expo-device` never fails to bundle.
|
|
874
|
+
*
|
|
875
|
+
* WHY it is NOT PII: `expo-device`'s `modelName` ("iPhone 14 Pro") and `modelId` ("iPhone15,2") are a
|
|
876
|
+
* device CLASS shared by millions of units — the same privacy category as the Android `Model` the kit
|
|
877
|
+
* already sends. It is NOT a unique device id / IDFA / fingerprint, so surfacing it changes no App
|
|
878
|
+
* Privacy / Data Safety declaration (identical guarantee to the rest of deviceContext). It deliberately
|
|
879
|
+
* does NOT read `expo-device`'s `deviceName` (that is the user-set name, e.g. "Malik's iPhone", and IS
|
|
880
|
+
* personal data).
|
|
881
|
+
*
|
|
882
|
+
* NEVER THROWS: every read is guarded; a missing/odd value yields `undefined`, never an exception.
|
|
883
|
+
*/
|
|
884
|
+
/** A `require`-like resolver. Injectable in tests; production uses the guarded runtime require. */
|
|
885
|
+
type OptionalRequire = (moduleName: string) => unknown;
|
|
886
|
+
/**
|
|
887
|
+
* Detect the device model via `expo-device`, preferring the human-readable `modelName`
|
|
888
|
+
* ("iPhone 14 Pro") and falling back to the identifier `modelId` ("iPhone15,2"). Returns the first
|
|
889
|
+
* real string, or `undefined` when `expo-device` is absent. Pure and never throws.
|
|
890
|
+
*
|
|
891
|
+
* `requireModule` is injectable so tests can exercise the "found" path without the native module;
|
|
892
|
+
* production defaults to the guarded runtime require above.
|
|
893
|
+
*/
|
|
894
|
+
declare const detectNativeModel: (requireModule?: OptionalRequire) => string | undefined;
|
|
862
895
|
|
|
863
896
|
/** Max accepted user-id length. Longer strings are truncated (never rejected). Keep in sync
|
|
864
897
|
* with the server's `USER_ID_MAX_LENGTH` (analytics/events.py). */
|
|
@@ -906,6 +939,37 @@ type IdentifyOnboardingOptions = {
|
|
|
906
939
|
*/
|
|
907
940
|
declare const identifyOnboarding: (opts: IdentifyOnboardingOptions) => Promise<boolean>;
|
|
908
941
|
|
|
942
|
+
/**
|
|
943
|
+
* deviceId — mint a stable, NON-PII, per-install device id the kit owns when the host supplies
|
|
944
|
+
* none. This is the headline of "device fully automatic": the analytics façade auto-mints ONE id,
|
|
945
|
+
* persists it via the host's `storage` abstraction, and reuses it on every subsequent open — so
|
|
946
|
+
* `user_context.device_key` is ALWAYS present and the server's review/questionnaire gating +
|
|
947
|
+
* A/B stickiness (both key on `device_key`) work out of the box, with zero host wiring.
|
|
948
|
+
*
|
|
949
|
+
* WHY it is NOT PII and adds NO dependency (the kit's hard rules):
|
|
950
|
+
* The id is a random token generated from `Date.now()` + `Math.random()` — it carries NO hardware
|
|
951
|
+
* identifier, NO IDFA/GAID, NO fingerprint. It is a first-party per-install correlation key, the
|
|
952
|
+
* same privacy category as a first-party cookie: it groups a single install's sessions and cannot
|
|
953
|
+
* identify a person or be joined across apps. There is NO `uuid` (or any) dependency — a
|
|
954
|
+
* time+random scheme is sufficient because the id is minted ONCE and then persisted, so global
|
|
955
|
+
* uniqueness across the fleet is not required (a per-install collision is astronomically unlikely
|
|
956
|
+
* and inconsequential — worst case two installs share a bucket).
|
|
957
|
+
*
|
|
958
|
+
* A host that wants its OWN device id still wins: pass `WireUserContext.deviceKey` and the kit uses
|
|
959
|
+
* that verbatim and never mints/persists an auto id.
|
|
960
|
+
*/
|
|
961
|
+
/** Prefix so an auto-minted id is visibly the kit's (distinguishable from a host-supplied `deviceKey`). */
|
|
962
|
+
declare const AUTO_DEVICE_ID_PREFIX = "wdev_";
|
|
963
|
+
/** The storage key the façade persists the auto-minted id under (namespaced per `appId`). */
|
|
964
|
+
declare const deviceIdStorageKey: (appId?: string) => string;
|
|
965
|
+
/**
|
|
966
|
+
* Mint a fresh per-install device id. Dependency-free (`Date.now()` + `Math.random()`), never
|
|
967
|
+
* throws, and returns a NEW value on every call — the façade mints ONCE and persists, so this is
|
|
968
|
+
* called at most once per install (then the persisted value is reused). Two random chunks plus the
|
|
969
|
+
* timestamp keep the token wide enough that a per-install collision is not a practical concern.
|
|
970
|
+
*/
|
|
971
|
+
declare const mintDeviceId: () => string;
|
|
972
|
+
|
|
909
973
|
/** The canonical event name for an app-open. A trigger keys off this exact string. */
|
|
910
974
|
declare const SESSION_STARTED_EVENT: "app.session_started";
|
|
911
975
|
/** Options for {@link reportSessionStart}. Everything except `target` is optional so a pre-auth
|
|
@@ -1132,4 +1196,4 @@ interface UseLifecycleEventsOptions {
|
|
|
1132
1196
|
*/
|
|
1133
1197
|
declare const useLifecycleEvents: (config: LifecycleConfig | undefined, options?: UseLifecycleEventsOptions) => void;
|
|
1134
1198
|
|
|
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 };
|
|
1199
|
+
export { AUTO_DEVICE_ID_PREFIX, 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, detectNativeModel, deviceIdStorageKey, featuresCacheKey, featuresEqual, fetchWireFeatures, firstOpenStorageKey, identifyOnboarding, isFeaturesFresh, isOnboardingEnabled, mergeTheme, mintDeviceId, 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 { 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-
|
|
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-
|
|
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-f7LWcdWG.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-f7LWcdWG.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';
|
|
@@ -849,7 +849,7 @@ declare const attributionMetadata: (a: OnboardingAttribution) => {
|
|
|
849
849
|
* Analytics must never be able to break onboarding.
|
|
850
850
|
*/
|
|
851
851
|
/** A `require`-like resolver. Injectable in tests; production uses the guarded runtime require. */
|
|
852
|
-
type OptionalRequire = (moduleName: string) => unknown;
|
|
852
|
+
type OptionalRequire$1 = (moduleName: string) => unknown;
|
|
853
853
|
/**
|
|
854
854
|
* Detect the host app version, preferring `expo-constants` (`expoConfig.version`, then
|
|
855
855
|
* `nativeAppVersion`) and finally `expo-application` (`nativeApplicationVersion`). Returns the
|
|
@@ -858,7 +858,40 @@ type OptionalRequire = (moduleName: string) => unknown;
|
|
|
858
858
|
* `requireModule` is injectable so tests can exercise the "found" path without the native modules;
|
|
859
859
|
* production defaults to the guarded runtime require above.
|
|
860
860
|
*/
|
|
861
|
-
declare const detectAppVersion: (requireModule?: OptionalRequire) => string | undefined;
|
|
861
|
+
declare const detectAppVersion: (requireModule?: OptionalRequire$1) => string | undefined;
|
|
862
|
+
|
|
863
|
+
/**
|
|
864
|
+
* deviceModel — best-effort, DEPENDENCY-FREE detection of the device MODEL on iOS.
|
|
865
|
+
*
|
|
866
|
+
* WHY this exists (the asymmetry it closes): `collectDeviceContext` already reports `device.model`
|
|
867
|
+
* on Android straight from `Platform.constants.Model` (e.g. "SM-G991B"), but iOS `Platform.constants`
|
|
868
|
+
* exposes NO model — only `osVersion` / `interfaceIdiom`. So the analytics `by_model` breakdown was
|
|
869
|
+
* Android-only. This module fills the iOS gap with the SAME zero-dependency technique the kit already
|
|
870
|
+
* uses for `appVersion` (see device/appVersion.ts): a GUARDED, VARIABLE-specifier `require` of the
|
|
871
|
+
* common Expo `expo-device` module. If the host has it, iOS gets a model out of the box; if not, the
|
|
872
|
+
* require simply throws and is swallowed and iOS `model` stays omitted — nothing is forced, nothing
|
|
873
|
+
* is added to `package.json`, and a host without `expo-device` never fails to bundle.
|
|
874
|
+
*
|
|
875
|
+
* WHY it is NOT PII: `expo-device`'s `modelName` ("iPhone 14 Pro") and `modelId` ("iPhone15,2") are a
|
|
876
|
+
* device CLASS shared by millions of units — the same privacy category as the Android `Model` the kit
|
|
877
|
+
* already sends. It is NOT a unique device id / IDFA / fingerprint, so surfacing it changes no App
|
|
878
|
+
* Privacy / Data Safety declaration (identical guarantee to the rest of deviceContext). It deliberately
|
|
879
|
+
* does NOT read `expo-device`'s `deviceName` (that is the user-set name, e.g. "Malik's iPhone", and IS
|
|
880
|
+
* personal data).
|
|
881
|
+
*
|
|
882
|
+
* NEVER THROWS: every read is guarded; a missing/odd value yields `undefined`, never an exception.
|
|
883
|
+
*/
|
|
884
|
+
/** A `require`-like resolver. Injectable in tests; production uses the guarded runtime require. */
|
|
885
|
+
type OptionalRequire = (moduleName: string) => unknown;
|
|
886
|
+
/**
|
|
887
|
+
* Detect the device model via `expo-device`, preferring the human-readable `modelName`
|
|
888
|
+
* ("iPhone 14 Pro") and falling back to the identifier `modelId` ("iPhone15,2"). Returns the first
|
|
889
|
+
* real string, or `undefined` when `expo-device` is absent. Pure and never throws.
|
|
890
|
+
*
|
|
891
|
+
* `requireModule` is injectable so tests can exercise the "found" path without the native module;
|
|
892
|
+
* production defaults to the guarded runtime require above.
|
|
893
|
+
*/
|
|
894
|
+
declare const detectNativeModel: (requireModule?: OptionalRequire) => string | undefined;
|
|
862
895
|
|
|
863
896
|
/** Max accepted user-id length. Longer strings are truncated (never rejected). Keep in sync
|
|
864
897
|
* with the server's `USER_ID_MAX_LENGTH` (analytics/events.py). */
|
|
@@ -906,6 +939,37 @@ type IdentifyOnboardingOptions = {
|
|
|
906
939
|
*/
|
|
907
940
|
declare const identifyOnboarding: (opts: IdentifyOnboardingOptions) => Promise<boolean>;
|
|
908
941
|
|
|
942
|
+
/**
|
|
943
|
+
* deviceId — mint a stable, NON-PII, per-install device id the kit owns when the host supplies
|
|
944
|
+
* none. This is the headline of "device fully automatic": the analytics façade auto-mints ONE id,
|
|
945
|
+
* persists it via the host's `storage` abstraction, and reuses it on every subsequent open — so
|
|
946
|
+
* `user_context.device_key` is ALWAYS present and the server's review/questionnaire gating +
|
|
947
|
+
* A/B stickiness (both key on `device_key`) work out of the box, with zero host wiring.
|
|
948
|
+
*
|
|
949
|
+
* WHY it is NOT PII and adds NO dependency (the kit's hard rules):
|
|
950
|
+
* The id is a random token generated from `Date.now()` + `Math.random()` — it carries NO hardware
|
|
951
|
+
* identifier, NO IDFA/GAID, NO fingerprint. It is a first-party per-install correlation key, the
|
|
952
|
+
* same privacy category as a first-party cookie: it groups a single install's sessions and cannot
|
|
953
|
+
* identify a person or be joined across apps. There is NO `uuid` (or any) dependency — a
|
|
954
|
+
* time+random scheme is sufficient because the id is minted ONCE and then persisted, so global
|
|
955
|
+
* uniqueness across the fleet is not required (a per-install collision is astronomically unlikely
|
|
956
|
+
* and inconsequential — worst case two installs share a bucket).
|
|
957
|
+
*
|
|
958
|
+
* A host that wants its OWN device id still wins: pass `WireUserContext.deviceKey` and the kit uses
|
|
959
|
+
* that verbatim and never mints/persists an auto id.
|
|
960
|
+
*/
|
|
961
|
+
/** Prefix so an auto-minted id is visibly the kit's (distinguishable from a host-supplied `deviceKey`). */
|
|
962
|
+
declare const AUTO_DEVICE_ID_PREFIX = "wdev_";
|
|
963
|
+
/** The storage key the façade persists the auto-minted id under (namespaced per `appId`). */
|
|
964
|
+
declare const deviceIdStorageKey: (appId?: string) => string;
|
|
965
|
+
/**
|
|
966
|
+
* Mint a fresh per-install device id. Dependency-free (`Date.now()` + `Math.random()`), never
|
|
967
|
+
* throws, and returns a NEW value on every call — the façade mints ONCE and persists, so this is
|
|
968
|
+
* called at most once per install (then the persisted value is reused). Two random chunks plus the
|
|
969
|
+
* timestamp keep the token wide enough that a per-install collision is not a practical concern.
|
|
970
|
+
*/
|
|
971
|
+
declare const mintDeviceId: () => string;
|
|
972
|
+
|
|
909
973
|
/** The canonical event name for an app-open. A trigger keys off this exact string. */
|
|
910
974
|
declare const SESSION_STARTED_EVENT: "app.session_started";
|
|
911
975
|
/** Options for {@link reportSessionStart}. Everything except `target` is optional so a pre-auth
|
|
@@ -1132,4 +1196,4 @@ interface UseLifecycleEventsOptions {
|
|
|
1132
1196
|
*/
|
|
1133
1197
|
declare const useLifecycleEvents: (config: LifecycleConfig | undefined, options?: UseLifecycleEventsOptions) => void;
|
|
1134
1198
|
|
|
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 };
|
|
1199
|
+
export { AUTO_DEVICE_ID_PREFIX, 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, detectNativeModel, deviceIdStorageKey, featuresCacheKey, featuresEqual, fetchWireFeatures, firstOpenStorageKey, identifyOnboarding, isFeaturesFresh, isOnboardingEnabled, mergeTheme, mintDeviceId, 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.js
CHANGED
|
@@ -2405,6 +2405,47 @@ var detectAppVersion = (requireModule = runtimeRequire) => {
|
|
|
2405
2405
|
return void 0;
|
|
2406
2406
|
};
|
|
2407
2407
|
|
|
2408
|
+
// src/device/deviceModel.ts
|
|
2409
|
+
var coerceModel = (value) => {
|
|
2410
|
+
if (typeof value !== "string") return void 0;
|
|
2411
|
+
const trimmed = value.trim();
|
|
2412
|
+
return trimmed.length > 0 ? trimmed : void 0;
|
|
2413
|
+
};
|
|
2414
|
+
var runtimeRequire2 = (moduleName) => {
|
|
2415
|
+
try {
|
|
2416
|
+
if (typeof __require !== "function") return void 0;
|
|
2417
|
+
return __require(moduleName);
|
|
2418
|
+
} catch {
|
|
2419
|
+
return void 0;
|
|
2420
|
+
}
|
|
2421
|
+
};
|
|
2422
|
+
var interop2 = (mod) => {
|
|
2423
|
+
if (!mod || typeof mod !== "object") return void 0;
|
|
2424
|
+
const def = mod.default;
|
|
2425
|
+
if (def && typeof def === "object") return def;
|
|
2426
|
+
return mod;
|
|
2427
|
+
};
|
|
2428
|
+
var safeInterop2 = (requireModule, moduleName) => {
|
|
2429
|
+
try {
|
|
2430
|
+
return interop2(requireModule(moduleName));
|
|
2431
|
+
} catch {
|
|
2432
|
+
return void 0;
|
|
2433
|
+
}
|
|
2434
|
+
};
|
|
2435
|
+
var detectNativeModel = (requireModule = runtimeRequire2) => {
|
|
2436
|
+
try {
|
|
2437
|
+
const device = safeInterop2(requireModule, "expo-device");
|
|
2438
|
+
if (device) {
|
|
2439
|
+
const modelName = coerceModel(device.modelName);
|
|
2440
|
+
if (modelName) return modelName;
|
|
2441
|
+
const modelId = coerceModel(device.modelId);
|
|
2442
|
+
if (modelId) return modelId;
|
|
2443
|
+
}
|
|
2444
|
+
} catch {
|
|
2445
|
+
}
|
|
2446
|
+
return void 0;
|
|
2447
|
+
};
|
|
2448
|
+
|
|
2408
2449
|
// src/device/deviceContext.ts
|
|
2409
2450
|
var deriveFormFactor = (iosIdiom, width, height) => {
|
|
2410
2451
|
if (iosIdiom === "pad") return "tablet";
|
|
@@ -2451,6 +2492,8 @@ var collectDeviceContext = () => {
|
|
|
2451
2492
|
ctx.interfaceIdiom = idiom;
|
|
2452
2493
|
iosIdiom = idiom;
|
|
2453
2494
|
}
|
|
2495
|
+
const iosModel = detectNativeModel();
|
|
2496
|
+
if (iosModel) ctx.model = iosModel;
|
|
2454
2497
|
}
|
|
2455
2498
|
} catch {
|
|
2456
2499
|
}
|
|
@@ -3299,6 +3342,15 @@ var resolveUserContext = (ctx = {}, opts = {}) => {
|
|
|
3299
3342
|
return result;
|
|
3300
3343
|
};
|
|
3301
3344
|
|
|
3345
|
+
// src/context/deviceId.ts
|
|
3346
|
+
var AUTO_DEVICE_ID_PREFIX = "wdev_";
|
|
3347
|
+
var deviceIdStorageKey = (appId) => `wireai:analytics:deviceKey:${appId != null ? appId : "default"}`;
|
|
3348
|
+
var randomChunk = () => Math.floor(Math.random() * 4294967296).toString(36).padStart(6, "0");
|
|
3349
|
+
var mintDeviceId = () => {
|
|
3350
|
+
const time = Date.now().toString(36);
|
|
3351
|
+
return `${AUTO_DEVICE_ID_PREFIX}${time}_${randomChunk()}${randomChunk()}`;
|
|
3352
|
+
};
|
|
3353
|
+
|
|
3302
3354
|
// src/session-analytics/reportSessionStart.ts
|
|
3303
3355
|
var SESSION_STARTED_EVENT = "app.session_started";
|
|
3304
3356
|
var _emitted = /* @__PURE__ */ new Set();
|
|
@@ -3798,6 +3850,7 @@ var useLifecycleEvents = (config, options = {}) => {
|
|
|
3798
3850
|
}, []);
|
|
3799
3851
|
};
|
|
3800
3852
|
|
|
3853
|
+
exports.AUTO_DEVICE_ID_PREFIX = AUTO_DEVICE_ID_PREFIX;
|
|
3801
3854
|
exports.AnimatedSparkle = AnimatedSparkle;
|
|
3802
3855
|
exports.BACKGROUND_SESSION_MS = BACKGROUND_SESSION_MS;
|
|
3803
3856
|
exports.CardHandoff = CardHandoff;
|
|
@@ -3838,6 +3891,8 @@ exports.defaultOnboardingTheme = defaultOnboardingTheme;
|
|
|
3838
3891
|
exports.defaultWireFeatures = defaultWireFeatures;
|
|
3839
3892
|
exports.deriveAnswers = deriveAnswers;
|
|
3840
3893
|
exports.detectAppVersion = detectAppVersion;
|
|
3894
|
+
exports.detectNativeModel = detectNativeModel;
|
|
3895
|
+
exports.deviceIdStorageKey = deviceIdStorageKey;
|
|
3841
3896
|
exports.featuresCacheKey = featuresCacheKey;
|
|
3842
3897
|
exports.featuresEqual = featuresEqual;
|
|
3843
3898
|
exports.fetchWireFeatures = fetchWireFeatures;
|
|
@@ -3851,6 +3906,7 @@ exports.isWireScalar = isWireScalar;
|
|
|
3851
3906
|
exports.loadPersistedSession = loadPersistedSession;
|
|
3852
3907
|
exports.makeSessionId = makeSessionId;
|
|
3853
3908
|
exports.mergeTheme = mergeTheme;
|
|
3909
|
+
exports.mintDeviceId = mintDeviceId;
|
|
3854
3910
|
exports.motionSpec = motionSpec_exports;
|
|
3855
3911
|
exports.namespaceExtra = namespaceExtra;
|
|
3856
3912
|
exports.onboardingComponents = onboardingComponents;
|