@wireai/activation 0.4.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.
- package/AGENTS.md +1 -1
- package/CHANGELOG.md +57 -0
- package/dist/analytics/index.d.mts +15 -2
- package/dist/analytics/index.d.ts +15 -2
- package/dist/analytics/index.js +181 -13
- package/dist/analytics/index.js.map +1 -1
- package/dist/analytics/index.mjs +179 -14
- package/dist/analytics/index.mjs.map +1 -1
- package/dist/{eventQueue-CA1d8Fmn.d.mts → currentSession-BJBB7i4-.d.mts} +143 -15
- package/dist/{eventQueue-CrNB9gzH.d.ts → currentSession-CxnP7gAa.d.ts} +143 -15
- package/dist/index.d.mts +37 -37
- package/dist/index.d.ts +37 -37
- package/dist/index.js +158 -3
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +149 -4
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/WireOnboarding.tsx +4 -3
- package/src/analytics/analyticsFacade.ts +74 -11
- package/src/analytics/contextEnvelope.ts +13 -7
- package/src/analytics/currentSession.ts +35 -0
- package/src/analytics/index.ts +3 -0
- package/src/context/userContext.ts +210 -0
- package/src/device/appVersion.ts +103 -0
- package/src/device/deviceContext.ts +17 -5
- package/src/identity/userIdentity.ts +5 -0
- package/src/index.ts +23 -0
- package/src/session-analytics/reportSessionStart.ts +7 -0
- package/src/session-analytics/useLifecycleEvents.ts +4 -2
- package/src/session-analytics/useSessionStart.ts +2 -1
- package/src/types.ts +6 -5
package/src/index.ts
CHANGED
|
@@ -117,11 +117,34 @@ export type { OnboardingAttribution } from "./attribution/attribution";
|
|
|
117
117
|
// ─── Device context (privacy-label-neutral, dependency-free) ──────────────────
|
|
118
118
|
export { collectDeviceContext } from "./device/deviceContext";
|
|
119
119
|
export type { DeviceContext, DeviceFormFactor } from "./device/deviceContext";
|
|
120
|
+
export { detectAppVersion } from "./device/appVersion";
|
|
120
121
|
|
|
121
122
|
// ─── User identity (opaque pseudonymous id; late binding, dependency-free) ────
|
|
122
123
|
export { identifyOnboarding, sanitizeUserId, USER_ID_MAX_LENGTH } from "./identity/userIdentity";
|
|
123
124
|
export type { IdentifyOnboardingOptions } from "./identity/userIdentity";
|
|
124
125
|
|
|
126
|
+
// ─── Rich user context (one object → every event's user_context; opt-in email PII) ────
|
|
127
|
+
export {
|
|
128
|
+
resolveUserContext,
|
|
129
|
+
namespaceExtra,
|
|
130
|
+
hashEmailFnv1a,
|
|
131
|
+
isWireScalar,
|
|
132
|
+
RESERVED_USER_CONTEXT_KEYS,
|
|
133
|
+
EXTRA_KEY_PREFIX,
|
|
134
|
+
} from "./context/userContext";
|
|
135
|
+
export type {
|
|
136
|
+
WireUserContext,
|
|
137
|
+
ResolvedUserContext,
|
|
138
|
+
ResolveUserContextOptions,
|
|
139
|
+
} from "./context/userContext";
|
|
140
|
+
|
|
141
|
+
// ─── Current per-open session registry (identify/app-events reuse the live session) ───
|
|
142
|
+
export {
|
|
143
|
+
getCurrentSessionId,
|
|
144
|
+
setCurrentSessionId,
|
|
145
|
+
resetCurrentSessionId,
|
|
146
|
+
} from "./analytics/currentSession";
|
|
147
|
+
|
|
125
148
|
// ─── Session mapping (one `app.session_started` per app-open → /v1/events) ─────
|
|
126
149
|
export {
|
|
127
150
|
reportSessionStart,
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
* awaits, and swallows a missing target / bad URL / missing fetch / network error. Analytics must
|
|
32
32
|
* never be able to break the app.
|
|
33
33
|
*/
|
|
34
|
+
import { setCurrentSessionId } from "../analytics/currentSession";
|
|
34
35
|
import { makeSessionId, type ClientEvent, type ClientEventTarget } from "../analytics/reportClientEvent";
|
|
35
36
|
import type { DeviceContext } from "../device/deviceContext";
|
|
36
37
|
import { sanitizeUserId } from "../identity/userIdentity";
|
|
@@ -104,6 +105,12 @@ export const reportSessionStart = (opts: ReportSessionStartOptions): void => {
|
|
|
104
105
|
|
|
105
106
|
const sessionId = opts.sessionId ?? makeSessionId();
|
|
106
107
|
|
|
108
|
+
// Register this open as the CURRENT per-open session so the analytics façade's `identify` /
|
|
109
|
+
// app-events reuse the id the server sees here (via `app.session_started`) instead of minting a
|
|
110
|
+
// fresh one it would back-fill into a phantom session. Idempotent; set before the once-guard so
|
|
111
|
+
// even a guard-deduped repeat keeps the current id pointing at this open.
|
|
112
|
+
setCurrentSessionId(sessionId);
|
|
113
|
+
|
|
107
114
|
// Once-per-open guard: skip a repeat emit for a session id we already sent.
|
|
108
115
|
if (opts.once !== false) {
|
|
109
116
|
if (_emitted.has(sessionId)) return;
|
|
@@ -119,7 +119,8 @@ export const useLifecycleEvents = (
|
|
|
119
119
|
const { config: cfg, options: opts } = latest.current;
|
|
120
120
|
if (opts.enabled !== false) {
|
|
121
121
|
const device = collectDeviceContext();
|
|
122
|
-
|
|
122
|
+
// `device.appVersion` is auto-detected best-effort; an explicit host version always wins.
|
|
123
|
+
if (cfg?.appVersion) device.appVersion = cfg.appVersion;
|
|
123
124
|
reportFirstOpen({
|
|
124
125
|
target: targetOf(cfg),
|
|
125
126
|
sink: resolveSink(),
|
|
@@ -142,7 +143,8 @@ export const useLifecycleEvents = (
|
|
|
142
143
|
if (opts.enabled === false) return;
|
|
143
144
|
if (!cfg?.serverUrl && !opts.sink) return;
|
|
144
145
|
const device = collectDeviceContext();
|
|
145
|
-
|
|
146
|
+
// `device.appVersion` is auto-detected best-effort; an explicit host version always wins.
|
|
147
|
+
if (cfg?.appVersion) device.appVersion = cfg.appVersion;
|
|
146
148
|
reportSessionStart({
|
|
147
149
|
target: targetOf(cfg),
|
|
148
150
|
sink: resolveSink(),
|
|
@@ -72,7 +72,8 @@ export const useSessionStart = (
|
|
|
72
72
|
if (opts.enabled === false) return;
|
|
73
73
|
const target: ClientEventTarget = { serverUrl: cfg.serverUrl, apiKey: cfg.apiKey ?? "" };
|
|
74
74
|
const device = collectDeviceContext();
|
|
75
|
-
|
|
75
|
+
// `device.appVersion` is auto-detected best-effort; an explicit host version always wins.
|
|
76
|
+
if (cfg.appVersion) device.appVersion = cfg.appVersion;
|
|
76
77
|
reportSessionStart({
|
|
77
78
|
target,
|
|
78
79
|
// A fresh per-open id each fire; the emitter's once-guard dedupes within the open.
|
package/src/types.ts
CHANGED
|
@@ -24,11 +24,12 @@ export type WireOnboardingConfig = {
|
|
|
24
24
|
*/
|
|
25
25
|
metadata?: Record<string, unknown>;
|
|
26
26
|
/**
|
|
27
|
-
* Host app version string (e.g. "1.4.2").
|
|
28
|
-
*
|
|
29
|
-
* (`
|
|
30
|
-
*
|
|
31
|
-
*
|
|
27
|
+
* Host app version string (e.g. "1.4.2"). OPTIONAL — when omitted, the kit makes a best-effort
|
|
28
|
+
* auto-detection from `expo-constants` (`Constants.expoConfig?.version` / `nativeAppVersion`) or
|
|
29
|
+
* `expo-application` (`nativeApplicationVersion`) WITHOUT adding a dependency (a host that lacks
|
|
30
|
+
* those modules just gets no version — see device/appVersion.ts). Pass this to override the
|
|
31
|
+
* auto-detected value (it always wins). Forwarded to the backend on the session metadata and on
|
|
32
|
+
* client events (as `device.appVersion`) so analytics can segment the funnel by app version.
|
|
32
33
|
*/
|
|
33
34
|
appVersion?: string;
|
|
34
35
|
};
|