@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
package/CHANGELOG.md
CHANGED
|
@@ -18,6 +18,41 @@ Historical entries below the rename keep the old package name on purpose.
|
|
|
18
18
|
- Version reset to `0.1.0` to mark the start of the new package line. The GitHub repository
|
|
19
19
|
stays `chohra-med/wireai-onboarding`.
|
|
20
20
|
|
|
21
|
+
## [Unreleased]
|
|
22
|
+
|
|
23
|
+
### Added: "device" is now fully automatic — auto-minted, persisted per-install `device_key`
|
|
24
|
+
|
|
25
|
+
- The analytics façade (`createAnalytics`) now auto-mints a stable, NON-PII per-install `device_key`
|
|
26
|
+
when the host supplies none via `WireUserContext.deviceKey`. It is minted ONCE (`context/deviceId.ts`
|
|
27
|
+
— `mintDeviceId`, dependency-free time+random, no `uuid`), PERSISTED via the host's existing
|
|
28
|
+
`storage` (`WireOnboardingStorage`) under `deviceIdStorageKey(appId)`, and REUSED on every open;
|
|
29
|
+
with no storage it falls back to an in-memory id. Result: `user_context.device_key` is ALWAYS
|
|
30
|
+
present, so the server's review/questionnaire gating + A/B stickiness (both key on `device_key`)
|
|
31
|
+
work out of the box with zero host wiring. A host-supplied `deviceKey` still WINS (and opts out of
|
|
32
|
+
auto-minting). New exports: `mintDeviceId`, `deviceIdStorageKey`, `AUTO_DEVICE_ID_PREFIX`.
|
|
33
|
+
|
|
34
|
+
### Fixed: `WireUserContext.appVersion` now flows into `device.appVersion` (not just `user_context`)
|
|
35
|
+
|
|
36
|
+
- A host that set the app version ONLY inside `userContext` previously got it in
|
|
37
|
+
`user_context.app_version` but left `device.appVersion` on the auto-detected value — and the
|
|
38
|
+
server's `by_app_version` breakdown reads `device.appVersion`. The façade's context-envelope
|
|
39
|
+
provider now feeds `userContext.appVersion ?? config.appVersion` into `buildContextEnvelope`, so an
|
|
40
|
+
explicit `WireUserContext.appVersion` populates BOTH surfaces (explicit still wins over auto-detect).
|
|
41
|
+
|
|
42
|
+
### Added: best-effort iOS `device.model`
|
|
43
|
+
|
|
44
|
+
- `device.model` was Android-only (`Platform.constants.Model`); iOS `Platform.constants` exposes no
|
|
45
|
+
model. `collectDeviceContext` now fills iOS `model` best-effort via `detectNativeModel`
|
|
46
|
+
(`device/deviceModel.ts`), reading `expo-device`'s `modelName`/`modelId` through the SAME guarded,
|
|
47
|
+
variable-specifier require the kit already uses for `appVersion` — so it adds NO dependency and is
|
|
48
|
+
simply omitted when `expo-device` is absent. It reads a device CLASS (not a unique id / not the
|
|
49
|
+
user-set device name), so it changes no App Privacy / Data Safety declaration. ASYMMETRY documented
|
|
50
|
+
in the `DeviceContext.model` TSDoc: without `expo-device`, iOS `model` stays omitted; no native
|
|
51
|
+
dependency is added for it.
|
|
52
|
+
|
|
53
|
+
- Backward compatible: no existing export renamed or removed; zero new dependencies. The one
|
|
54
|
+
behavior change is intentional — events now carry an auto `device_key` when the host omits one.
|
|
55
|
+
|
|
21
56
|
## [0.7.0] — Unreleased
|
|
22
57
|
|
|
23
58
|
### Added: `WireUserContext` — one rich user-context object → every event's `user_context`
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { R as ReportAppEventOptions, r as reportAppEvent } from '../transport-BeO_Brcu.mjs';
|
|
2
|
-
import { W as WireUserContext, E as EventQueueOptions } from '../currentSession-
|
|
3
|
-
export { A as AnalyticsEvent, C as ClientEvent, a as ClientEventTarget, b as ClientEventType, c as ContextEnvelope, d as ContextEnvelopeInput, e as EnvelopeSource, f as EventQueue, g as WIRE_ONBOARDING_EVENTS, h as WireOnboardingEventName, i as buildContextEnvelope, j as createEventQueue, k as getCurrentSessionId, m as makeSessionId, r as reportClientEvent, l as reportClientEvents, n as resetCurrentSessionId, s as setCurrentSessionId, t as toAnalyticsEvent } from '../currentSession-
|
|
2
|
+
import { W as WireUserContext, E as EventQueueOptions } from '../currentSession-d9CrBxwe.mjs';
|
|
3
|
+
export { A as AnalyticsEvent, C as ClientEvent, a as ClientEventTarget, b as ClientEventType, c as ContextEnvelope, d as ContextEnvelopeInput, e as EnvelopeSource, f as EventQueue, g as WIRE_ONBOARDING_EVENTS, h as WireOnboardingEventName, i as buildContextEnvelope, j as createEventQueue, k as getCurrentSessionId, m as makeSessionId, r as reportClientEvent, l as reportClientEvents, n as resetCurrentSessionId, s as setCurrentSessionId, t as toAnalyticsEvent } from '../currentSession-d9CrBxwe.mjs';
|
|
4
4
|
import '../types-A6pTxIZV.mjs';
|
|
5
5
|
import '../types-BKfpdZzX.mjs';
|
|
6
6
|
import '../types-GL_hQ0TN.mjs';
|
|
@@ -123,8 +123,12 @@ type CreateAnalyticsConfig = {
|
|
|
123
123
|
/**
|
|
124
124
|
* The rich {@link WireUserContext} to stamp onto every event's `user_context` (device key, opaque
|
|
125
125
|
* user id, opt-in email, arbitrary `extra`). Passed ONCE here at init; updatable post-mount via
|
|
126
|
-
* {@link Analytics.setUserContext} (e.g. attach `userId`/`userEmail` at login). Optional
|
|
127
|
-
*
|
|
126
|
+
* {@link Analytics.setUserContext} (e.g. attach `userId`/`userEmail` at login). Optional.
|
|
127
|
+
*
|
|
128
|
+
* NOTE on `deviceKey`: you do NOT need to supply one. When omitted, the kit auto-mints a stable,
|
|
129
|
+
* non-PII per-install `device_key`, persists it via `storage`, and reuses it every open (in-memory
|
|
130
|
+
* fallback without storage) — so `user_context.device_key` is ALWAYS present for the server's
|
|
131
|
+
* review/questionnaire gating + A/B stickiness. Supply `deviceKey` only to use your OWN id (it wins).
|
|
128
132
|
*/
|
|
129
133
|
userContext?: WireUserContext;
|
|
130
134
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { R as ReportAppEventOptions, r as reportAppEvent } from '../transport-DLpd1v5_.js';
|
|
2
|
-
import { W as WireUserContext, E as EventQueueOptions } from '../currentSession-
|
|
3
|
-
export { A as AnalyticsEvent, C as ClientEvent, a as ClientEventTarget, b as ClientEventType, c as ContextEnvelope, d as ContextEnvelopeInput, e as EnvelopeSource, f as EventQueue, g as WIRE_ONBOARDING_EVENTS, h as WireOnboardingEventName, i as buildContextEnvelope, j as createEventQueue, k as getCurrentSessionId, m as makeSessionId, r as reportClientEvent, l as reportClientEvents, n as resetCurrentSessionId, s as setCurrentSessionId, t as toAnalyticsEvent } from '../currentSession-
|
|
2
|
+
import { W as WireUserContext, E as EventQueueOptions } from '../currentSession-f7LWcdWG.js';
|
|
3
|
+
export { A as AnalyticsEvent, C as ClientEvent, a as ClientEventTarget, b as ClientEventType, c as ContextEnvelope, d as ContextEnvelopeInput, e as EnvelopeSource, f as EventQueue, g as WIRE_ONBOARDING_EVENTS, h as WireOnboardingEventName, i as buildContextEnvelope, j as createEventQueue, k as getCurrentSessionId, m as makeSessionId, r as reportClientEvent, l as reportClientEvents, n as resetCurrentSessionId, s as setCurrentSessionId, t as toAnalyticsEvent } from '../currentSession-f7LWcdWG.js';
|
|
4
4
|
import '../types-BhpXJGlg.js';
|
|
5
5
|
import '../types-BKfpdZzX.js';
|
|
6
6
|
import '../types-GL_hQ0TN.js';
|
|
@@ -123,8 +123,12 @@ type CreateAnalyticsConfig = {
|
|
|
123
123
|
/**
|
|
124
124
|
* The rich {@link WireUserContext} to stamp onto every event's `user_context` (device key, opaque
|
|
125
125
|
* user id, opt-in email, arbitrary `extra`). Passed ONCE here at init; updatable post-mount via
|
|
126
|
-
* {@link Analytics.setUserContext} (e.g. attach `userId`/`userEmail` at login). Optional
|
|
127
|
-
*
|
|
126
|
+
* {@link Analytics.setUserContext} (e.g. attach `userId`/`userEmail` at login). Optional.
|
|
127
|
+
*
|
|
128
|
+
* NOTE on `deviceKey`: you do NOT need to supply one. When omitted, the kit auto-mints a stable,
|
|
129
|
+
* non-PII per-install `device_key`, persists it via `storage`, and reuses it every open (in-memory
|
|
130
|
+
* fallback without storage) — so `user_context.device_key` is ALWAYS present for the server's
|
|
131
|
+
* review/questionnaire gating + A/B stickiness. Supply `deviceKey` only to use your OWN id (it wins).
|
|
128
132
|
*/
|
|
129
133
|
userContext?: WireUserContext;
|
|
130
134
|
};
|
package/dist/analytics/index.js
CHANGED
|
@@ -214,6 +214,47 @@ var detectAppVersion = (requireModule = runtimeRequire) => {
|
|
|
214
214
|
return void 0;
|
|
215
215
|
};
|
|
216
216
|
|
|
217
|
+
// src/device/deviceModel.ts
|
|
218
|
+
var coerceModel = (value) => {
|
|
219
|
+
if (typeof value !== "string") return void 0;
|
|
220
|
+
const trimmed = value.trim();
|
|
221
|
+
return trimmed.length > 0 ? trimmed : void 0;
|
|
222
|
+
};
|
|
223
|
+
var runtimeRequire2 = (moduleName) => {
|
|
224
|
+
try {
|
|
225
|
+
if (typeof __require !== "function") return void 0;
|
|
226
|
+
return __require(moduleName);
|
|
227
|
+
} catch {
|
|
228
|
+
return void 0;
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
var interop2 = (mod) => {
|
|
232
|
+
if (!mod || typeof mod !== "object") return void 0;
|
|
233
|
+
const def = mod.default;
|
|
234
|
+
if (def && typeof def === "object") return def;
|
|
235
|
+
return mod;
|
|
236
|
+
};
|
|
237
|
+
var safeInterop2 = (requireModule, moduleName) => {
|
|
238
|
+
try {
|
|
239
|
+
return interop2(requireModule(moduleName));
|
|
240
|
+
} catch {
|
|
241
|
+
return void 0;
|
|
242
|
+
}
|
|
243
|
+
};
|
|
244
|
+
var detectNativeModel = (requireModule = runtimeRequire2) => {
|
|
245
|
+
try {
|
|
246
|
+
const device = safeInterop2(requireModule, "expo-device");
|
|
247
|
+
if (device) {
|
|
248
|
+
const modelName = coerceModel(device.modelName);
|
|
249
|
+
if (modelName) return modelName;
|
|
250
|
+
const modelId = coerceModel(device.modelId);
|
|
251
|
+
if (modelId) return modelId;
|
|
252
|
+
}
|
|
253
|
+
} catch {
|
|
254
|
+
}
|
|
255
|
+
return void 0;
|
|
256
|
+
};
|
|
257
|
+
|
|
217
258
|
// src/device/deviceContext.ts
|
|
218
259
|
var deriveFormFactor = (iosIdiom, width, height) => {
|
|
219
260
|
if (iosIdiom === "pad") return "tablet";
|
|
@@ -260,6 +301,8 @@ var collectDeviceContext = () => {
|
|
|
260
301
|
ctx.interfaceIdiom = idiom;
|
|
261
302
|
iosIdiom = idiom;
|
|
262
303
|
}
|
|
304
|
+
const iosModel = detectNativeModel();
|
|
305
|
+
if (iosModel) ctx.model = iosModel;
|
|
263
306
|
}
|
|
264
307
|
} catch {
|
|
265
308
|
}
|
|
@@ -593,20 +636,46 @@ var resolveUserContext = (ctx = {}, opts = {}) => {
|
|
|
593
636
|
return result;
|
|
594
637
|
};
|
|
595
638
|
|
|
639
|
+
// src/context/deviceId.ts
|
|
640
|
+
var AUTO_DEVICE_ID_PREFIX = "wdev_";
|
|
641
|
+
var deviceIdStorageKey = (appId) => `wireai:analytics:deviceKey:${appId != null ? appId : "default"}`;
|
|
642
|
+
var randomChunk = () => Math.floor(Math.random() * 4294967296).toString(36).padStart(6, "0");
|
|
643
|
+
var mintDeviceId = () => {
|
|
644
|
+
const time = Date.now().toString(36);
|
|
645
|
+
return `${AUTO_DEVICE_ID_PREFIX}${time}_${randomChunk()}${randomChunk()}`;
|
|
646
|
+
};
|
|
647
|
+
|
|
596
648
|
// src/analytics/analyticsFacade.ts
|
|
597
649
|
var createAnalytics = (config, options = {}) => {
|
|
598
|
-
var _a, _b, _c, _d;
|
|
650
|
+
var _a, _b, _c, _d, _e;
|
|
599
651
|
const instanceSessionId = (_a = config.sessionId) != null ? _a : makeSessionId();
|
|
600
652
|
const resolveSessionId = () => {
|
|
601
653
|
var _a2, _b2;
|
|
602
654
|
return (_b2 = (_a2 = config.sessionId) != null ? _a2 : getCurrentSessionId()) != null ? _b2 : instanceSessionId;
|
|
603
655
|
};
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
656
|
+
let userContext = { ...(_b = config.userContext) != null ? _b : {} };
|
|
657
|
+
const hostDeviceKeyAtInit = typeof ((_c = config.userContext) == null ? void 0 : _c.deviceKey) === "string" && config.userContext.deviceKey.trim() ? config.userContext.deviceKey.trim() : void 0;
|
|
658
|
+
let autoDeviceKey = mintDeviceId();
|
|
659
|
+
if (config.storage && !hostDeviceKeyAtInit) {
|
|
660
|
+
const storage = config.storage;
|
|
661
|
+
const deviceKey = deviceIdStorageKey(config.appId);
|
|
662
|
+
void storage.getItem(deviceKey).then((saved) => {
|
|
663
|
+
const persisted = typeof saved === "string" && saved.trim() ? saved.trim() : void 0;
|
|
664
|
+
if (persisted) autoDeviceKey = persisted;
|
|
665
|
+
else void storage.setItem(deviceKey, autoDeviceKey).catch(() => {
|
|
666
|
+
});
|
|
667
|
+
}).catch(() => {
|
|
668
|
+
});
|
|
669
|
+
}
|
|
670
|
+
const envelope = () => {
|
|
671
|
+
var _a2;
|
|
672
|
+
return buildContextEnvelope({
|
|
673
|
+
sessionId: resolveSessionId(),
|
|
674
|
+
appVersion: (_a2 = userContext.appVersion) != null ? _a2 : config.appVersion,
|
|
675
|
+
appBuild: config.appBuild,
|
|
676
|
+
networkType: config.networkType
|
|
677
|
+
});
|
|
678
|
+
};
|
|
610
679
|
const queue = createEventQueue({
|
|
611
680
|
target: { serverUrl: config.serverUrl, apiKey: config.apiKey },
|
|
612
681
|
storage: config.storage,
|
|
@@ -614,9 +683,8 @@ var createAnalytics = (config, options = {}) => {
|
|
|
614
683
|
envelope,
|
|
615
684
|
...options
|
|
616
685
|
});
|
|
617
|
-
let
|
|
618
|
-
|
|
619
|
-
const storageKey = `wireai:analytics:userId:${(_d = config.appId) != null ? _d : "default"}`;
|
|
686
|
+
let boundUserId = sanitizeUserId((_d = config.userContext) == null ? void 0 : _d.userId);
|
|
687
|
+
const storageKey = `wireai:analytics:userId:${(_e = config.appId) != null ? _e : "default"}`;
|
|
620
688
|
if (config.storage) {
|
|
621
689
|
void config.storage.getItem(storageKey).then((saved) => {
|
|
622
690
|
if (saved && !boundUserId) boundUserId = saved;
|
|
@@ -625,7 +693,11 @@ var createAnalytics = (config, options = {}) => {
|
|
|
625
693
|
}
|
|
626
694
|
const applyContext = (event) => {
|
|
627
695
|
var _a2;
|
|
628
|
-
const
|
|
696
|
+
const hostDeviceKey = typeof userContext.deviceKey === "string" && userContext.deviceKey.trim() ? userContext.deviceKey : void 0;
|
|
697
|
+
const resolved = resolveUserContext(
|
|
698
|
+
{ ...userContext, deviceKey: hostDeviceKey != null ? hostDeviceKey : autoDeviceKey },
|
|
699
|
+
{ autoAppVersion: config.appVersion }
|
|
700
|
+
);
|
|
629
701
|
if (resolved.userContext) {
|
|
630
702
|
event.user_context = { ...resolved.userContext, ...(_a2 = event.user_context) != null ? _a2 : {} };
|
|
631
703
|
}
|