@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/dist/analytics/index.mjs
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import { useRef, useEffect } from 'react';
|
|
2
2
|
import { Platform, Dimensions, I18nManager } from 'react-native';
|
|
3
3
|
|
|
4
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
5
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
6
|
+
}) : x)(function(x) {
|
|
7
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
8
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
9
|
+
});
|
|
10
|
+
|
|
4
11
|
// src/reviews/transport.ts
|
|
5
12
|
var reportAppEvent = (target, name, options = {}) => {
|
|
6
13
|
if (!(target == null ? void 0 : target.serverUrl) || !name) return;
|
|
@@ -155,6 +162,57 @@ var toAnalyticsEvent = (event) => {
|
|
|
155
162
|
}
|
|
156
163
|
}
|
|
157
164
|
};
|
|
165
|
+
|
|
166
|
+
// src/device/appVersion.ts
|
|
167
|
+
var coerceVersion = (value) => {
|
|
168
|
+
if (typeof value !== "string") return void 0;
|
|
169
|
+
const trimmed = value.trim();
|
|
170
|
+
return trimmed.length > 0 ? trimmed : void 0;
|
|
171
|
+
};
|
|
172
|
+
var runtimeRequire = (moduleName) => {
|
|
173
|
+
try {
|
|
174
|
+
if (typeof __require !== "function") return void 0;
|
|
175
|
+
return __require(moduleName);
|
|
176
|
+
} catch {
|
|
177
|
+
return void 0;
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
var interop = (mod) => {
|
|
181
|
+
if (!mod || typeof mod !== "object") return void 0;
|
|
182
|
+
const def = mod.default;
|
|
183
|
+
if (def && typeof def === "object") return def;
|
|
184
|
+
return mod;
|
|
185
|
+
};
|
|
186
|
+
var safeInterop = (requireModule, moduleName) => {
|
|
187
|
+
try {
|
|
188
|
+
return interop(requireModule(moduleName));
|
|
189
|
+
} catch {
|
|
190
|
+
return void 0;
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
var detectAppVersion = (requireModule = runtimeRequire) => {
|
|
194
|
+
try {
|
|
195
|
+
const constants = safeInterop(requireModule, "expo-constants");
|
|
196
|
+
if (constants) {
|
|
197
|
+
const expoConfig = constants.expoConfig;
|
|
198
|
+
if (expoConfig && typeof expoConfig === "object") {
|
|
199
|
+
const fromExpoConfig = coerceVersion(expoConfig.version);
|
|
200
|
+
if (fromExpoConfig) return fromExpoConfig;
|
|
201
|
+
}
|
|
202
|
+
const fromNative = coerceVersion(constants.nativeAppVersion);
|
|
203
|
+
if (fromNative) return fromNative;
|
|
204
|
+
}
|
|
205
|
+
const application = safeInterop(requireModule, "expo-application");
|
|
206
|
+
if (application) {
|
|
207
|
+
const fromApplication = coerceVersion(application.nativeApplicationVersion);
|
|
208
|
+
if (fromApplication) return fromApplication;
|
|
209
|
+
}
|
|
210
|
+
} catch {
|
|
211
|
+
}
|
|
212
|
+
return void 0;
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
// src/device/deviceContext.ts
|
|
158
216
|
var deriveFormFactor = (iosIdiom, width, height) => {
|
|
159
217
|
if (iosIdiom === "pad") return "tablet";
|
|
160
218
|
if (iosIdiom === "phone") return "phone";
|
|
@@ -224,16 +282,20 @@ var collectDeviceContext = () => {
|
|
|
224
282
|
if (resolved.timeZone) ctx.timeZone = resolved.timeZone;
|
|
225
283
|
} catch {
|
|
226
284
|
}
|
|
285
|
+
const appVersion = detectAppVersion();
|
|
286
|
+
if (appVersion) ctx.appVersion = appVersion;
|
|
227
287
|
return ctx;
|
|
228
288
|
};
|
|
229
289
|
|
|
230
290
|
// src/analytics/contextEnvelope.ts
|
|
231
291
|
var buildContextEnvelope = (input = {}) => {
|
|
292
|
+
var _a;
|
|
232
293
|
const device = { ...collectDeviceContext() };
|
|
233
|
-
if (input.appVersion
|
|
294
|
+
if (input.appVersion) device.appVersion = input.appVersion;
|
|
295
|
+
const effectiveAppVersion = (_a = input.appVersion) != null ? _a : device.appVersion;
|
|
234
296
|
const envelope = { device };
|
|
235
297
|
if (input.sessionId) envelope.sessionId = input.sessionId;
|
|
236
|
-
if (
|
|
298
|
+
if (effectiveAppVersion) envelope.appVersion = effectiveAppVersion;
|
|
237
299
|
if (input.appBuild) envelope.appBuild = input.appBuild;
|
|
238
300
|
if (input.networkType) envelope.networkType = input.networkType;
|
|
239
301
|
return envelope;
|
|
@@ -447,6 +509,16 @@ var createEventQueue = (options) => {
|
|
|
447
509
|
return { enqueue, flush, notifyOnline, size };
|
|
448
510
|
};
|
|
449
511
|
|
|
512
|
+
// src/analytics/currentSession.ts
|
|
513
|
+
var _currentSessionId;
|
|
514
|
+
var setCurrentSessionId = (id) => {
|
|
515
|
+
if (typeof id === "string" && id.length > 0) _currentSessionId = id;
|
|
516
|
+
};
|
|
517
|
+
var getCurrentSessionId = () => _currentSessionId;
|
|
518
|
+
var resetCurrentSessionId = () => {
|
|
519
|
+
_currentSessionId = void 0;
|
|
520
|
+
};
|
|
521
|
+
|
|
450
522
|
// src/identity/userIdentity.ts
|
|
451
523
|
var USER_ID_MAX_LENGTH = 128;
|
|
452
524
|
var sanitizeUserId = (raw) => {
|
|
@@ -456,12 +528,79 @@ var sanitizeUserId = (raw) => {
|
|
|
456
528
|
return trimmed.length > USER_ID_MAX_LENGTH ? trimmed.slice(0, USER_ID_MAX_LENGTH) : trimmed;
|
|
457
529
|
};
|
|
458
530
|
|
|
531
|
+
// src/context/userContext.ts
|
|
532
|
+
var EXTRA_KEY_PREFIX = "custom.";
|
|
533
|
+
var isWireScalar = (value) => {
|
|
534
|
+
const t = typeof value;
|
|
535
|
+
if (t === "string" || t === "boolean") return true;
|
|
536
|
+
if (t === "number") return Number.isFinite(value);
|
|
537
|
+
return false;
|
|
538
|
+
};
|
|
539
|
+
var hashEmailFnv1a = (email) => {
|
|
540
|
+
const normalized = email.trim().toLowerCase();
|
|
541
|
+
let hash = 2166136261;
|
|
542
|
+
for (let i = 0; i < normalized.length; i++) {
|
|
543
|
+
hash ^= normalized.charCodeAt(i);
|
|
544
|
+
hash = Math.imul(hash, 16777619);
|
|
545
|
+
}
|
|
546
|
+
return (hash >>> 0).toString(16).padStart(8, "0");
|
|
547
|
+
};
|
|
548
|
+
var cleanString = (value) => {
|
|
549
|
+
if (typeof value !== "string") return void 0;
|
|
550
|
+
const trimmed = value.trim();
|
|
551
|
+
return trimmed.length > 0 ? trimmed : void 0;
|
|
552
|
+
};
|
|
553
|
+
var namespaceExtra = (extra) => {
|
|
554
|
+
const out = {};
|
|
555
|
+
if (!extra || typeof extra !== "object") return out;
|
|
556
|
+
for (const [key, value] of Object.entries(extra)) {
|
|
557
|
+
const cleanKey = cleanString(key);
|
|
558
|
+
if (!cleanKey) continue;
|
|
559
|
+
if (!isWireScalar(value)) continue;
|
|
560
|
+
out[`${EXTRA_KEY_PREFIX}${cleanKey}`] = value;
|
|
561
|
+
}
|
|
562
|
+
return out;
|
|
563
|
+
};
|
|
564
|
+
var resolveUserContext = (ctx = {}, opts = {}) => {
|
|
565
|
+
var _a;
|
|
566
|
+
const result = {};
|
|
567
|
+
const bucket = {};
|
|
568
|
+
const userId = sanitizeUserId(ctx.userId);
|
|
569
|
+
if (userId) result.userId = userId;
|
|
570
|
+
const deviceKey = cleanString(ctx.deviceKey);
|
|
571
|
+
if (deviceKey) {
|
|
572
|
+
result.deviceKey = deviceKey;
|
|
573
|
+
bucket.device_key = deviceKey;
|
|
574
|
+
}
|
|
575
|
+
const appVersion = (_a = cleanString(ctx.appVersion)) != null ? _a : cleanString(opts.autoAppVersion);
|
|
576
|
+
if (appVersion) {
|
|
577
|
+
result.appVersion = appVersion;
|
|
578
|
+
bucket.app_version = appVersion;
|
|
579
|
+
}
|
|
580
|
+
const email = cleanString(ctx.userEmail);
|
|
581
|
+
if (email) {
|
|
582
|
+
if (ctx.hashEmail) {
|
|
583
|
+
bucket.user_email = hashEmailFnv1a(email);
|
|
584
|
+
bucket.user_email_hashed = true;
|
|
585
|
+
} else {
|
|
586
|
+
bucket.user_email = email;
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
Object.assign(bucket, namespaceExtra(ctx.extra));
|
|
590
|
+
if (Object.keys(bucket).length > 0) result.userContext = bucket;
|
|
591
|
+
return result;
|
|
592
|
+
};
|
|
593
|
+
|
|
459
594
|
// src/analytics/analyticsFacade.ts
|
|
460
595
|
var createAnalytics = (config, options = {}) => {
|
|
461
|
-
var _a, _b;
|
|
462
|
-
const
|
|
596
|
+
var _a, _b, _c, _d;
|
|
597
|
+
const instanceSessionId = (_a = config.sessionId) != null ? _a : makeSessionId();
|
|
598
|
+
const resolveSessionId = () => {
|
|
599
|
+
var _a2, _b2;
|
|
600
|
+
return (_b2 = (_a2 = config.sessionId) != null ? _a2 : getCurrentSessionId()) != null ? _b2 : instanceSessionId;
|
|
601
|
+
};
|
|
463
602
|
const envelope = () => buildContextEnvelope({
|
|
464
|
-
sessionId,
|
|
603
|
+
sessionId: resolveSessionId(),
|
|
465
604
|
appVersion: config.appVersion,
|
|
466
605
|
appBuild: config.appBuild,
|
|
467
606
|
networkType: config.networkType
|
|
@@ -473,23 +612,45 @@ var createAnalytics = (config, options = {}) => {
|
|
|
473
612
|
envelope,
|
|
474
613
|
...options
|
|
475
614
|
});
|
|
476
|
-
let
|
|
477
|
-
|
|
615
|
+
let userContext = { ...(_b = config.userContext) != null ? _b : {} };
|
|
616
|
+
let boundUserId = sanitizeUserId((_c = config.userContext) == null ? void 0 : _c.userId);
|
|
617
|
+
const storageKey = `wireai:analytics:userId:${(_d = config.appId) != null ? _d : "default"}`;
|
|
478
618
|
if (config.storage) {
|
|
479
619
|
void config.storage.getItem(storageKey).then((saved) => {
|
|
480
|
-
if (saved) boundUserId = saved;
|
|
620
|
+
if (saved && !boundUserId) boundUserId = saved;
|
|
481
621
|
}).catch(() => {
|
|
482
622
|
});
|
|
483
623
|
}
|
|
624
|
+
const applyContext = (event) => {
|
|
625
|
+
var _a2;
|
|
626
|
+
const resolved = resolveUserContext(userContext, { autoAppVersion: config.appVersion });
|
|
627
|
+
if (resolved.userContext) {
|
|
628
|
+
event.user_context = { ...resolved.userContext, ...(_a2 = event.user_context) != null ? _a2 : {} };
|
|
629
|
+
}
|
|
630
|
+
if (boundUserId && !event.user_id) event.user_id = boundUserId;
|
|
631
|
+
};
|
|
632
|
+
const setUserContext = (partial) => {
|
|
633
|
+
var _a2, _b2;
|
|
634
|
+
if (!partial || typeof partial !== "object") return;
|
|
635
|
+
const mergedExtra = partial.extra || userContext.extra ? { ...(_a2 = userContext.extra) != null ? _a2 : {}, ...(_b2 = partial.extra) != null ? _b2 : {} } : void 0;
|
|
636
|
+
userContext = { ...userContext, ...partial };
|
|
637
|
+
if (mergedExtra) userContext.extra = mergedExtra;
|
|
638
|
+
const uid = sanitizeUserId(partial.userId);
|
|
639
|
+
if (uid) {
|
|
640
|
+
boundUserId = uid;
|
|
641
|
+
if (config.storage) void config.storage.setItem(storageKey, uid).catch(() => {
|
|
642
|
+
});
|
|
643
|
+
}
|
|
644
|
+
};
|
|
484
645
|
const track = (event, props) => {
|
|
485
646
|
if (!event) return;
|
|
486
647
|
const clientEvent = {
|
|
487
648
|
event_type: "app_event",
|
|
488
|
-
session_id:
|
|
649
|
+
session_id: resolveSessionId(),
|
|
489
650
|
question_key: event
|
|
490
651
|
};
|
|
491
652
|
if (props && Object.keys(props).length > 0) clientEvent.meta = JSON.stringify(props);
|
|
492
|
-
|
|
653
|
+
applyContext(clientEvent);
|
|
493
654
|
queue.enqueue(clientEvent);
|
|
494
655
|
};
|
|
495
656
|
const screen = (name, props) => {
|
|
@@ -497,11 +658,11 @@ var createAnalytics = (config, options = {}) => {
|
|
|
497
658
|
const meta = { screen: name, ...props != null ? props : {} };
|
|
498
659
|
const clientEvent = {
|
|
499
660
|
event_type: "app_event",
|
|
500
|
-
session_id:
|
|
661
|
+
session_id: resolveSessionId(),
|
|
501
662
|
question_key: "screen",
|
|
502
663
|
meta: JSON.stringify(meta)
|
|
503
664
|
};
|
|
504
|
-
|
|
665
|
+
applyContext(clientEvent);
|
|
505
666
|
queue.enqueue(clientEvent);
|
|
506
667
|
};
|
|
507
668
|
const identify = (userId, traits) => {
|
|
@@ -514,16 +675,20 @@ var createAnalytics = (config, options = {}) => {
|
|
|
514
675
|
}
|
|
515
676
|
const clientEvent = {
|
|
516
677
|
event_type: "identify",
|
|
517
|
-
|
|
678
|
+
// Reuse the LIVE per-open session id (see `resolveSessionId`) so the server binds identity to
|
|
679
|
+
// the session it already saw instead of back-filling a phantom `session_started`.
|
|
680
|
+
session_id: resolveSessionId(),
|
|
518
681
|
user_id: clean
|
|
519
682
|
};
|
|
520
683
|
if (traits && Object.keys(traits).length > 0) clientEvent.meta = JSON.stringify(traits);
|
|
684
|
+
applyContext(clientEvent);
|
|
521
685
|
queue.enqueue(clientEvent);
|
|
522
686
|
};
|
|
523
687
|
return {
|
|
524
688
|
track,
|
|
525
689
|
screen,
|
|
526
690
|
identify,
|
|
691
|
+
setUserContext,
|
|
527
692
|
flush: queue.flush,
|
|
528
693
|
notifyOnline: queue.notifyOnline,
|
|
529
694
|
size: queue.size
|
|
@@ -540,6 +705,6 @@ var useAnalytics = (config, options = {}) => {
|
|
|
540
705
|
return ref.current;
|
|
541
706
|
};
|
|
542
707
|
|
|
543
|
-
export { WIRE_ONBOARDING_EVENTS, buildContextEnvelope, createAnalytics, createEventQueue, createScreenTracker, getActiveRouteName, makeSessionId, reportAppEvent, reportClientEvent, reportClientEvents, screenTrackingHandler, toAnalyticsEvent, useAnalytics, useScreenTracking };
|
|
708
|
+
export { WIRE_ONBOARDING_EVENTS, buildContextEnvelope, createAnalytics, createEventQueue, createScreenTracker, getActiveRouteName, getCurrentSessionId, makeSessionId, reportAppEvent, reportClientEvent, reportClientEvents, resetCurrentSessionId, screenTrackingHandler, setCurrentSessionId, toAnalyticsEvent, useAnalytics, useScreenTracking };
|
|
544
709
|
//# sourceMappingURL=index.mjs.map
|
|
545
710
|
//# sourceMappingURL=index.mjs.map
|