@wireai/activation 0.12.2 → 0.13.2
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 +3 -1
- package/CHANGELOG.md +259 -1
- package/README.md +87 -3
- package/dist/analytics/index.d.mts +2 -2
- package/dist/analytics/index.d.ts +2 -2
- package/dist/analytics/index.js +174 -36
- package/dist/analytics/index.js.map +1 -1
- package/dist/analytics/index.mjs +174 -37
- package/dist/analytics/index.mjs.map +1 -1
- package/dist/{currentSession-BlCeDP0f.d.mts → currentSession-ClkLjcJ0.d.mts} +456 -19
- package/dist/{currentSession-BxEB37xt.d.ts → currentSession-DOVZEWJl.d.ts} +456 -19
- package/dist/index.d.mts +197 -16
- package/dist/index.d.ts +197 -16
- package/dist/index.js +1056 -390
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +836 -193
- package/dist/index.mjs.map +1 -1
- package/dist/questionnaire/index.js.map +1 -1
- package/dist/questionnaire/index.mjs.map +1 -1
- package/dist/reviews/index.js +20 -7
- package/dist/reviews/index.js.map +1 -1
- package/dist/reviews/index.mjs +20 -7
- package/dist/reviews/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/OnboardingFlow.tsx +141 -3
- package/src/WireOnboarding.tsx +178 -34
- package/src/activation/wireActivation.ts +13 -7
- package/src/analytics/analyticsEvent.ts +16 -1
- package/src/analytics/analyticsFacade.ts +11 -10
- package/src/analytics/currentSession.ts +6 -20
- package/src/analytics/eventQueue.ts +71 -1
- package/src/analytics/index.ts +1 -1
- package/src/analytics/reportClientEvent.ts +157 -38
- package/src/cards/PermissionCard.tsx +438 -0
- package/src/cards/index.ts +7 -0
- package/src/config/wireConfigFromEnv.ts +1 -10
- package/src/context/deviceId.ts +77 -16
- package/src/context/userContext.ts +4 -15
- package/src/identity/identityRecord.ts +123 -0
- package/src/identity/userIdentity.ts +45 -9
- package/src/illustrations/defaultIllustrations.tsx +44 -3
- package/src/index.ts +44 -4
- package/src/permissions/index.ts +64 -0
- package/src/permissions/permissionCopy.ts +87 -0
- package/src/permissions/permissionEvents.ts +76 -0
- package/src/permissions/permissionMemory.ts +88 -0
- package/src/permissions/placement.ts +88 -0
- package/src/permissions/types.ts +131 -0
- package/src/session/persistedSession.ts +10 -3
- package/src/session-analytics/useLifecycleEvents.ts +10 -1
- package/src/types.ts +77 -1
- package/src/utils/deriveAnswers.ts +6 -2
- package/src/utils/readProgress.ts +4 -0
- package/src/utils/warnInDev.ts +33 -0
- package/src/components/DoneBlock.tsx +0 -37
package/dist/analytics/index.mjs
CHANGED
|
@@ -400,39 +400,63 @@ var init_Constants = __esm({
|
|
|
400
400
|
|
|
401
401
|
// src/analytics/reportClientEvent.ts
|
|
402
402
|
var makeSessionId = () => `wire_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;
|
|
403
|
+
var toWireEvents = (events) => events.map((event) => {
|
|
404
|
+
if (typeof event.ts !== "number") return event;
|
|
405
|
+
const { ts, ...rest } = event;
|
|
406
|
+
if (!Number.isFinite(ts)) return rest;
|
|
407
|
+
try {
|
|
408
|
+
return { ...rest, ts: new Date(ts).toISOString() };
|
|
409
|
+
} catch {
|
|
410
|
+
return rest;
|
|
411
|
+
}
|
|
412
|
+
});
|
|
403
413
|
var buildEventsRequest = (target, events) => {
|
|
404
414
|
if (!(target == null ? void 0 : target.serverUrl) || events.length === 0) return null;
|
|
405
415
|
try {
|
|
406
416
|
const url = `${target.serverUrl.replace(/\/$/, "")}/v1/events`;
|
|
407
417
|
const headers = { "Content-Type": "application/json" };
|
|
408
418
|
if (target.apiKey) headers.Authorization = `Bearer ${target.apiKey}`;
|
|
409
|
-
|
|
419
|
+
const body = JSON.stringify({ events: toWireEvents(events) });
|
|
420
|
+
return { url, init: { method: "POST", headers, body } };
|
|
410
421
|
} catch {
|
|
411
422
|
return null;
|
|
412
423
|
}
|
|
413
424
|
};
|
|
414
|
-
var
|
|
415
|
-
if (typeof __DEV__ === "undefined" || !__DEV__) return;
|
|
416
|
-
if (typeof console === "undefined" || !console.warn) return;
|
|
425
|
+
var readEventsAck = async (res) => {
|
|
417
426
|
try {
|
|
418
427
|
const json = res == null ? void 0 : res.json;
|
|
419
|
-
if (typeof json !== "function") return;
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
+
if (typeof json !== "function") return void 0;
|
|
429
|
+
const body = await Promise.resolve(json.call(res));
|
|
430
|
+
const skipped = body == null ? void 0 : body.skipped;
|
|
431
|
+
if (typeof skipped !== "number" || !Number.isFinite(skipped)) return void 0;
|
|
432
|
+
const reasons = Array.isArray(body == null ? void 0 : body.errors) ? body.errors.map((e) => {
|
|
433
|
+
const entry = e;
|
|
434
|
+
const reason = entry == null ? void 0 : entry.reason;
|
|
435
|
+
if (typeof reason !== "string") return void 0;
|
|
436
|
+
const field = entry == null ? void 0 : entry.field;
|
|
437
|
+
return typeof field === "string" && field.length > 0 ? `${reason} (field: ${field})` : reason;
|
|
438
|
+
}).filter((r) => typeof r === "string") : [];
|
|
439
|
+
return { written: typeof (body == null ? void 0 : body.written) === "number" ? body.written : void 0, skipped, reasons };
|
|
428
440
|
} catch {
|
|
441
|
+
return void 0;
|
|
429
442
|
}
|
|
430
443
|
};
|
|
444
|
+
var describeDiscarded = (ack) => `[wireai] the server ACCEPTED the /v1/events POST but DISCARDED ${ack.skipped} event(s) (skipped in the response body) \u2014 they are gone, not retried. The server reported: skipped=${ack.skipped}${ack.written !== void 0 ? `, written=${ack.written}` : ""}` + (ack.reasons.length > 0 ? `, reasons: ${ack.reasons.join(", ")}.` : ". It gave no reason (the endpoint folds every rejection into one count), so check the server's ingest log for this request rather than guessing.");
|
|
445
|
+
var warnOnSkippedEvents = (res) => {
|
|
446
|
+
if (typeof __DEV__ === "undefined" || !__DEV__) return;
|
|
447
|
+
if (typeof console === "undefined" || !console.warn) return;
|
|
448
|
+
void readEventsAck(res).then((ack) => {
|
|
449
|
+
if (!ack || ack.skipped <= 0) return;
|
|
450
|
+
console.warn(describeDiscarded(ack));
|
|
451
|
+
});
|
|
452
|
+
};
|
|
431
453
|
var reportClientEvents = (target, events) => {
|
|
432
454
|
try {
|
|
433
455
|
const req = buildEventsRequest(target, events);
|
|
434
456
|
if (!req) return;
|
|
435
|
-
void fetch(req.url, req.init).
|
|
457
|
+
void fetch(req.url, req.init).then((res) => {
|
|
458
|
+
warnOnSkippedEvents(res);
|
|
459
|
+
}).catch(() => {
|
|
436
460
|
});
|
|
437
461
|
} catch {
|
|
438
462
|
}
|
|
@@ -443,13 +467,28 @@ var reportClientEventsAwait = async (target, events) => {
|
|
|
443
467
|
const req = buildEventsRequest(target, events);
|
|
444
468
|
if (!req) return false;
|
|
445
469
|
const res = await fetch(req.url, req.init);
|
|
446
|
-
|
|
470
|
+
if (!res || !res.ok) return false;
|
|
471
|
+
const ack = await readEventsAck(res);
|
|
472
|
+
if (!ack || ack.skipped <= 0) return true;
|
|
473
|
+
if (typeof __DEV__ !== "undefined" && __DEV__ && typeof console !== "undefined" && console.warn) {
|
|
474
|
+
console.warn(describeDiscarded(ack));
|
|
475
|
+
}
|
|
476
|
+
return false;
|
|
447
477
|
} catch {
|
|
448
478
|
return false;
|
|
449
479
|
}
|
|
450
480
|
};
|
|
451
481
|
var reportClientEventAwait = (target, event) => reportClientEventsAwait(target, [event]);
|
|
452
482
|
|
|
483
|
+
// src/utils/warnInDev.ts
|
|
484
|
+
var warnInDev = (message) => {
|
|
485
|
+
if (typeof __DEV__ !== "undefined" && __DEV__ && typeof console !== "undefined" && console.warn) {
|
|
486
|
+
console.warn(message);
|
|
487
|
+
return true;
|
|
488
|
+
}
|
|
489
|
+
return false;
|
|
490
|
+
};
|
|
491
|
+
|
|
453
492
|
// src/analytics/currentSession.ts
|
|
454
493
|
var CURRENT_SESSION_ID_SLOT = /* @__PURE__ */ Symbol.for(
|
|
455
494
|
"@wireai/activation:currentSessionId"
|
|
@@ -464,13 +503,6 @@ var getCurrentSessionId = () => globalSlot[CURRENT_SESSION_ID_SLOT];
|
|
|
464
503
|
var resetCurrentSessionId = () => {
|
|
465
504
|
globalSlot[CURRENT_SESSION_ID_SLOT] = void 0;
|
|
466
505
|
};
|
|
467
|
-
var warnInDev = (message) => {
|
|
468
|
-
if (typeof __DEV__ !== "undefined" && __DEV__ && typeof console !== "undefined" && console.warn) {
|
|
469
|
-
console.warn(message);
|
|
470
|
-
return true;
|
|
471
|
-
}
|
|
472
|
-
return false;
|
|
473
|
-
};
|
|
474
506
|
var MINT_WARNING = "[wireai] No app-open session was registered, so a session id was minted for this event (the server drops an event that has no session_id, and still answers 200). Mount useLifecycleEvents at your app root so events correlate to a real app-open.";
|
|
475
507
|
var MINT_WARNED_SLOT = /* @__PURE__ */ Symbol.for(
|
|
476
508
|
"@wireai/activation:currentSessionIdMintWarned"
|
|
@@ -581,6 +613,43 @@ var useScreenTracking = (navigationRef, options = {}) => {
|
|
|
581
613
|
}, [navigationRef]);
|
|
582
614
|
};
|
|
583
615
|
|
|
616
|
+
// src/permissions/permissionEvents.ts
|
|
617
|
+
var WIRE_PERMISSION_EVENTS = {
|
|
618
|
+
/** The priming screen became visible. The denominator for every rate below. */
|
|
619
|
+
screenShown: "wire_permission_screen_shown",
|
|
620
|
+
/** The user tapped the primary, so the OS dialog is about to open. The rationale worked. */
|
|
621
|
+
primerAccepted: "wire_permission_primer_accepted",
|
|
622
|
+
/** The OS granted it. */
|
|
623
|
+
granted: "wire_permission_granted",
|
|
624
|
+
/** The OS refused it (a permanently blocked answer reports here too, with `status: "blocked"`). */
|
|
625
|
+
denied: "wire_permission_denied",
|
|
626
|
+
/** The user took the secondary. The one native prompt was NOT spent. */
|
|
627
|
+
skipped: "wire_permission_skipped",
|
|
628
|
+
/** A blocked user was redirected to the OS settings page. */
|
|
629
|
+
settingsOpened: "wire_permission_settings_opened"
|
|
630
|
+
};
|
|
631
|
+
var permissionEventName = (stage) => {
|
|
632
|
+
switch (stage) {
|
|
633
|
+
case "shown":
|
|
634
|
+
return WIRE_PERMISSION_EVENTS.screenShown;
|
|
635
|
+
case "accepted":
|
|
636
|
+
return WIRE_PERMISSION_EVENTS.primerAccepted;
|
|
637
|
+
case "granted":
|
|
638
|
+
return WIRE_PERMISSION_EVENTS.granted;
|
|
639
|
+
case "denied":
|
|
640
|
+
return WIRE_PERMISSION_EVENTS.denied;
|
|
641
|
+
case "skipped":
|
|
642
|
+
return WIRE_PERMISSION_EVENTS.skipped;
|
|
643
|
+
case "settings":
|
|
644
|
+
return WIRE_PERMISSION_EVENTS.settingsOpened;
|
|
645
|
+
default: {
|
|
646
|
+
const _exhaustive = stage;
|
|
647
|
+
return _exhaustive;
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
};
|
|
651
|
+
var permissionEventProps = (permission, status) => status ? { permission, status } : { permission };
|
|
652
|
+
|
|
584
653
|
// src/analytics/analyticsEvent.ts
|
|
585
654
|
var WIRE_ONBOARDING_EVENTS = {
|
|
586
655
|
started: "wire_onboarding_started",
|
|
@@ -613,6 +682,11 @@ var toAnalyticsEvent = (event) => {
|
|
|
613
682
|
};
|
|
614
683
|
case "fallback":
|
|
615
684
|
return { name: WIRE_ONBOARDING_EVENTS.fallback, params: { reason: event.reason } };
|
|
685
|
+
case "permission":
|
|
686
|
+
return {
|
|
687
|
+
name: permissionEventName(event.stage),
|
|
688
|
+
params: permissionEventProps(event.permission, event.status)
|
|
689
|
+
};
|
|
616
690
|
default: {
|
|
617
691
|
const _exhaustive = event;
|
|
618
692
|
return _exhaustive;
|
|
@@ -818,6 +892,31 @@ var DEFAULTS = {
|
|
|
818
892
|
maxRetries: 6
|
|
819
893
|
};
|
|
820
894
|
var READ_TIMEOUT_MS = 1500;
|
|
895
|
+
var QUEUE_KEY_SLOT = /* @__PURE__ */ Symbol.for("@wireai/activation:eventQueueKeys");
|
|
896
|
+
var queueKeyGlobal = globalThis;
|
|
897
|
+
var claimedQueueKeys = () => {
|
|
898
|
+
const existing = queueKeyGlobal[QUEUE_KEY_SLOT];
|
|
899
|
+
if (existing) return existing;
|
|
900
|
+
const created = /* @__PURE__ */ new Set();
|
|
901
|
+
queueKeyGlobal[QUEUE_KEY_SLOT] = created;
|
|
902
|
+
return created;
|
|
903
|
+
};
|
|
904
|
+
var claimQueueKey = (preferred, explicit) => {
|
|
905
|
+
const claimed = claimedQueueKeys();
|
|
906
|
+
if (explicit || !claimed.has(preferred)) {
|
|
907
|
+
claimed.add(preferred);
|
|
908
|
+
return preferred;
|
|
909
|
+
}
|
|
910
|
+
let ordinal = 2;
|
|
911
|
+
while (claimed.has(`${preferred}#${ordinal}`)) ordinal++;
|
|
912
|
+
const key = `${preferred}#${ordinal}`;
|
|
913
|
+
claimed.add(key);
|
|
914
|
+
warnInDev(
|
|
915
|
+
`[wireai] a second event queue was created for the same appId, and "${preferred}" is already claimed by a live one. Two queues sharing one storage slot overwrite each other's backlog, delete each other's pending events when one drains to empty, and double-send on relaunch, so this queue was given "${key}" instead. Prefer ONE analytics instance per app; if you really need two, pass an explicit \`storageKey\` to each so the slots are yours to reason about.`
|
|
916
|
+
);
|
|
917
|
+
return key;
|
|
918
|
+
};
|
|
919
|
+
var resetEventQueueKeys = () => claimedQueueKeys().clear();
|
|
821
920
|
var withTimeout = (p, ms) => {
|
|
822
921
|
let timer;
|
|
823
922
|
const timeout = new Promise((resolve) => {
|
|
@@ -849,7 +948,8 @@ var createEventQueue = (options) => {
|
|
|
849
948
|
var _a2, _b, _c, _d, _e, _f, _g;
|
|
850
949
|
const target = options.target;
|
|
851
950
|
const storage = options.storage;
|
|
852
|
-
const
|
|
951
|
+
const defaultKey = (_b = options.storageKey) != null ? _b : `wireai:evtq:${(_a2 = options.appId) != null ? _a2 : "default"}`;
|
|
952
|
+
const key = storage ? claimQueueKey(defaultKey, options.storageKey !== void 0) : defaultKey;
|
|
853
953
|
const maxSize = (_c = options.maxSize) != null ? _c : DEFAULTS.maxSize;
|
|
854
954
|
const batchSize = (_d = options.batchSize) != null ? _d : DEFAULTS.batchSize;
|
|
855
955
|
const baseBackoffMs = (_e = options.baseBackoffMs) != null ? _e : DEFAULTS.baseBackoffMs;
|
|
@@ -1100,6 +1200,29 @@ var resolveUserContext = (ctx = {}, opts = {}) => {
|
|
|
1100
1200
|
return result;
|
|
1101
1201
|
};
|
|
1102
1202
|
|
|
1203
|
+
// src/identity/identityRecord.ts
|
|
1204
|
+
var IDENTITY_PROVENANCE_SLOT = /* @__PURE__ */ Symbol.for("@wireai/activation:identityProvenance");
|
|
1205
|
+
var provenanceGlobal = globalThis;
|
|
1206
|
+
var provenanceRegistry = () => {
|
|
1207
|
+
const existing = provenanceGlobal[IDENTITY_PROVENANCE_SLOT];
|
|
1208
|
+
if (existing) return existing;
|
|
1209
|
+
const created = { host: /* @__PURE__ */ new Map() };
|
|
1210
|
+
provenanceGlobal[IDENTITY_PROVENANCE_SLOT] = created;
|
|
1211
|
+
return created;
|
|
1212
|
+
};
|
|
1213
|
+
var provenanceKey = (space, scope) => `${space}:${scope != null ? scope : "default"}`;
|
|
1214
|
+
var resolveIdentity = (input) => {
|
|
1215
|
+
var _a2;
|
|
1216
|
+
if (typeof input.value !== "string") return void 0;
|
|
1217
|
+
const value = input.value.trim();
|
|
1218
|
+
if (!value) return void 0;
|
|
1219
|
+
const durable = (_a2 = input.durable) != null ? _a2 : input.source === "host";
|
|
1220
|
+
{
|
|
1221
|
+
provenanceRegistry().host.set(provenanceKey(input.space, input.scope), value);
|
|
1222
|
+
}
|
|
1223
|
+
return { value, space: input.space, source: input.source, durable };
|
|
1224
|
+
};
|
|
1225
|
+
|
|
1103
1226
|
// src/context/deviceId.ts
|
|
1104
1227
|
var AUTO_DEVICE_ID_PREFIX = "wdev_";
|
|
1105
1228
|
var deviceIdStorageKey = (appId) => `wireai:analytics:deviceKey:${appId != null ? appId : "default"}`;
|
|
@@ -1122,24 +1245,37 @@ var startHydration = (registry, appId, storage, minted) => {
|
|
|
1122
1245
|
const existing = registry.pending.get(appId);
|
|
1123
1246
|
if (existing) return existing;
|
|
1124
1247
|
const slot = deviceIdStorageKey(appId);
|
|
1125
|
-
const
|
|
1248
|
+
const degraded = () => {
|
|
1126
1249
|
var _a2;
|
|
1127
|
-
return (_a2 = registry.keys.get(appId)) != null ? _a2 : minted;
|
|
1250
|
+
return { value: (_a2 = registry.keys.get(appId)) != null ? _a2 : minted, durable: false };
|
|
1128
1251
|
};
|
|
1252
|
+
const adopted = (value) => ({ value, durable: true });
|
|
1129
1253
|
let run;
|
|
1130
1254
|
try {
|
|
1131
1255
|
run = Promise.resolve(storage.getItem(slot)).then((saved) => {
|
|
1132
1256
|
const persisted = typeof saved === "string" && saved.trim() ? saved.trim() : void 0;
|
|
1133
1257
|
if (persisted) {
|
|
1134
1258
|
registry.keys.set(appId, persisted);
|
|
1135
|
-
return persisted;
|
|
1259
|
+
return adopted(persisted);
|
|
1136
1260
|
}
|
|
1137
|
-
return Promise.resolve(storage.setItem(slot, minted)).then(
|
|
1138
|
-
|
|
1261
|
+
return Promise.resolve(storage.setItem(slot, minted)).then(
|
|
1262
|
+
() => {
|
|
1263
|
+
var _a2;
|
|
1264
|
+
return adopted((_a2 = registry.keys.get(appId)) != null ? _a2 : minted);
|
|
1265
|
+
},
|
|
1266
|
+
degraded
|
|
1267
|
+
);
|
|
1268
|
+
}).catch(degraded);
|
|
1139
1269
|
} catch {
|
|
1140
|
-
run = Promise.resolve(
|
|
1270
|
+
run = Promise.resolve(degraded());
|
|
1141
1271
|
}
|
|
1142
1272
|
registry.pending.set(appId, run);
|
|
1273
|
+
void run.then((outcome) => {
|
|
1274
|
+
var _a2;
|
|
1275
|
+
if (outcome.durable) return;
|
|
1276
|
+
(_a2 = registry.pending) == null ? void 0 : _a2.delete(appId);
|
|
1277
|
+
registry.hydrating.delete(appId);
|
|
1278
|
+
});
|
|
1143
1279
|
return run;
|
|
1144
1280
|
};
|
|
1145
1281
|
var resolveAutoDeviceKey = (opts = {}) => {
|
|
@@ -1167,11 +1303,6 @@ var resetAutoDeviceKeys = () => {
|
|
|
1167
1303
|
};
|
|
1168
1304
|
|
|
1169
1305
|
// src/analytics/analyticsFacade.ts
|
|
1170
|
-
var warnInDev2 = (message) => {
|
|
1171
|
-
if (typeof __DEV__ !== "undefined" && __DEV__ && typeof console !== "undefined" && console.warn) {
|
|
1172
|
-
console.warn(message);
|
|
1173
|
-
}
|
|
1174
|
-
};
|
|
1175
1306
|
var createAnalytics = (config, options = {}) => {
|
|
1176
1307
|
var _a2, _b, _c;
|
|
1177
1308
|
const resolveSessionId = () => {
|
|
@@ -1179,13 +1310,19 @@ var createAnalytics = (config, options = {}) => {
|
|
|
1179
1310
|
return (_a3 = config.sessionId) != null ? _a3 : ensureCurrentSessionId();
|
|
1180
1311
|
};
|
|
1181
1312
|
if (config.sessionId) {
|
|
1182
|
-
|
|
1313
|
+
warnInDev(
|
|
1183
1314
|
"[wireai] createAnalytics({ sessionId }) PINS every event from this instance to that one frozen id and opts out of the live per-open session (app.session_started) \u2014 lifecycle analytics collapse onto a single device-scoped id. Remove it unless your host runs its own session lifecycle."
|
|
1184
1315
|
);
|
|
1185
1316
|
}
|
|
1186
1317
|
const detectedAppVersion = detectAppVersion();
|
|
1187
1318
|
let userContext = { ...(_a2 = config.userContext) != null ? _a2 : {} };
|
|
1188
1319
|
const hostDeviceKeyAtInit = typeof ((_b = config.userContext) == null ? void 0 : _b.deviceKey) === "string" && config.userContext.deviceKey.trim() ? config.userContext.deviceKey.trim() : void 0;
|
|
1320
|
+
resolveIdentity({
|
|
1321
|
+
value: hostDeviceKeyAtInit,
|
|
1322
|
+
space: "device",
|
|
1323
|
+
source: "host",
|
|
1324
|
+
scope: config.appId
|
|
1325
|
+
});
|
|
1189
1326
|
const autoDeviceKeyOptions = {
|
|
1190
1327
|
appId: config.appId,
|
|
1191
1328
|
// A host-supplied deviceKey opts out of minting AND persisting (unchanged contract).
|
|
@@ -1231,7 +1368,7 @@ var createAnalytics = (config, options = {}) => {
|
|
|
1231
1368
|
};
|
|
1232
1369
|
const guardUserId = (clean) => {
|
|
1233
1370
|
if (config.allowEmailAsUserId || !looksLikeEmail(clean)) return clean;
|
|
1234
|
-
|
|
1371
|
+
warnInDev(
|
|
1235
1372
|
"[wireai] identify() was called with an email-shaped id. A raw email must NOT be the opaque user_id (PII leak) \u2014 pass it as userContext.userEmail instead. Binding was skipped. Set allowEmailAsUserId:true on createAnalytics if your user id genuinely is an email."
|
|
1236
1373
|
);
|
|
1237
1374
|
return void 0;
|
|
@@ -1330,6 +1467,6 @@ var useAnalytics = (config, options = {}) => {
|
|
|
1330
1467
|
return ref.current;
|
|
1331
1468
|
};
|
|
1332
1469
|
|
|
1333
|
-
export { AUTO_DEVICE_ID_PREFIX, WIRE_ONBOARDING_EVENTS, analyticsUserIdStorageKey, buildContextEnvelope, clearPiiFromContext, clearUserContext, createAnalytics, createEventQueue, createScreenTracker, deviceIdStorageKey, ensureCurrentSessionId, getActiveRouteName, getCurrentSessionId, looksLikeEmail, makeSessionId, reportAppEvent, reportClientEvent, reportClientEventAwait, reportClientEvents, reportClientEventsAwait, resetAutoDeviceKeys, resetCurrentSessionId, resolveAutoDeviceKey, screenTrackingHandler, setCurrentSessionId, toAnalyticsEvent, useAnalytics, useScreenTracking };
|
|
1470
|
+
export { AUTO_DEVICE_ID_PREFIX, WIRE_ONBOARDING_EVENTS, analyticsUserIdStorageKey, buildContextEnvelope, clearPiiFromContext, clearUserContext, createAnalytics, createEventQueue, createScreenTracker, deviceIdStorageKey, ensureCurrentSessionId, getActiveRouteName, getCurrentSessionId, looksLikeEmail, makeSessionId, reportAppEvent, reportClientEvent, reportClientEventAwait, reportClientEvents, reportClientEventsAwait, resetAutoDeviceKeys, resetCurrentSessionId, resetEventQueueKeys, resolveAutoDeviceKey, screenTrackingHandler, setCurrentSessionId, toAnalyticsEvent, useAnalytics, useScreenTracking };
|
|
1334
1471
|
//# sourceMappingURL=index.mjs.map
|
|
1335
1472
|
//# sourceMappingURL=index.mjs.map
|