@wireai/activation 0.12.1 → 0.13.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 +146 -1
- package/README.md +5 -3
- package/dist/analytics/index.d.mts +2 -2
- package/dist/analytics/index.d.ts +2 -2
- package/dist/analytics/index.js +114 -35
- package/dist/analytics/index.js.map +1 -1
- package/dist/analytics/index.mjs +114 -36
- package/dist/analytics/index.mjs.map +1 -1
- package/dist/{currentSession-BxEB37xt.d.ts → currentSession-D7zabMXK.d.ts} +161 -9
- package/dist/{currentSession-BlCeDP0f.d.mts → currentSession-_GynvhzT.d.mts} +161 -9
- package/dist/index.d.mts +5 -15
- package/dist/index.d.ts +5 -15
- package/dist/index.js +232 -135
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +229 -134
- 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 +8 -6
- package/dist/reviews/index.js.map +1 -1
- package/dist/reviews/index.mjs +8 -6
- package/dist/reviews/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/OnboardingFlow.tsx +10 -3
- package/src/WireOnboarding.tsx +115 -32
- package/src/activation/wireActivation.ts +13 -7
- package/src/analytics/analyticsFacade.ts +11 -10
- package/src/analytics/currentSession.ts +6 -20
- package/src/analytics/eventQueue.ts +69 -1
- package/src/analytics/index.ts +1 -1
- package/src/analytics/reportClientEvent.ts +92 -29
- 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/index.ts +6 -4
- package/src/session-analytics/useLifecycleEvents.ts +10 -1
- package/src/types.ts +14 -0
- 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/index.mjs
CHANGED
|
@@ -1006,26 +1006,26 @@ var _OnboardingScaffold = ({
|
|
|
1006
1006
|
children
|
|
1007
1007
|
}) => {
|
|
1008
1008
|
const t = useOnboardingTheme();
|
|
1009
|
-
const
|
|
1009
|
+
const styles17 = useMemo(() => makeStyles(t), [t]);
|
|
1010
1010
|
const hit = { top: 12, bottom: 12, left: 12, right: 12 };
|
|
1011
1011
|
return /* @__PURE__ */ jsxs(
|
|
1012
1012
|
SafeAreaView,
|
|
1013
1013
|
{
|
|
1014
1014
|
edges: ["top", "bottom"],
|
|
1015
|
-
style: [
|
|
1015
|
+
style: [styles17.flex, { backgroundColor: t.colors.background }],
|
|
1016
1016
|
children: [
|
|
1017
|
-
/* @__PURE__ */ jsxs(View, { style: [
|
|
1018
|
-
/* @__PURE__ */ jsx(View, { style:
|
|
1019
|
-
onSkip ? /* @__PURE__ */ jsx(TouchableOpacity, { onPress: onSkip, hitSlop: hit, style:
|
|
1017
|
+
/* @__PURE__ */ jsxs(View, { style: [styles17.header, { paddingHorizontal: t.spacing.md, paddingTop: t.spacing.md }], children: [
|
|
1018
|
+
/* @__PURE__ */ jsx(View, { style: styles17.progressWrap, children: /* @__PURE__ */ jsx(StepProgress, { step, complete, approxScreens }) }),
|
|
1019
|
+
onSkip ? /* @__PURE__ */ jsx(TouchableOpacity, { onPress: onSkip, hitSlop: hit, style: styles17.skip, children: /* @__PURE__ */ jsx(Text, { style: [bodyStyle(t.fonts), { color: t.colors.textMuted }], children: skipLabel }) }) : null
|
|
1020
1020
|
] }),
|
|
1021
1021
|
/* @__PURE__ */ jsx(
|
|
1022
1022
|
View,
|
|
1023
1023
|
{
|
|
1024
|
-
style: [
|
|
1024
|
+
style: [styles17.body, { paddingHorizontal: t.spacing.md, paddingTop: t.spacing.md }],
|
|
1025
1025
|
children
|
|
1026
1026
|
}
|
|
1027
1027
|
),
|
|
1028
|
-
onBack ? /* @__PURE__ */ jsx(View, { style: [
|
|
1028
|
+
onBack ? /* @__PURE__ */ jsx(View, { style: [styles17.footer, { paddingHorizontal: t.spacing.md, paddingBottom: t.spacing.sm }], children: /* @__PURE__ */ jsx(TouchableOpacity, { onPress: onBack, hitSlop: hit, children: /* @__PURE__ */ jsx(Text, { style: [bodyStyle(t.fonts), { color: t.colors.textMuted }], children: backLabel }) }) }) : null
|
|
1029
1029
|
]
|
|
1030
1030
|
}
|
|
1031
1031
|
);
|
|
@@ -1162,10 +1162,10 @@ var _CardLayout = ({
|
|
|
1162
1162
|
titleNode
|
|
1163
1163
|
}) => {
|
|
1164
1164
|
const t = useOnboardingTheme();
|
|
1165
|
-
const
|
|
1165
|
+
const styles17 = useMemo(() => makeStyles2(t), [t]);
|
|
1166
1166
|
const hasHeader = !!title || !!subtitle || !!titleNode;
|
|
1167
|
-
return /* @__PURE__ */ jsxs(KeyboardAvoidingView, { style:
|
|
1168
|
-
hasHeader ? /* @__PURE__ */ jsxs(View, { style:
|
|
1167
|
+
return /* @__PURE__ */ jsxs(KeyboardAvoidingView, { style: styles17.fill, behavior: "padding", children: [
|
|
1168
|
+
hasHeader ? /* @__PURE__ */ jsxs(View, { style: styles17.header, children: [
|
|
1169
1169
|
titleNode != null ? titleNode : title ? /* @__PURE__ */ jsx(Text, { style: [labelStyle(t.fonts), { color: t.colors.text }], children: title }) : null,
|
|
1170
1170
|
subtitle ? /* @__PURE__ */ jsx(
|
|
1171
1171
|
Text,
|
|
@@ -1181,10 +1181,10 @@ var _CardLayout = ({
|
|
|
1181
1181
|
/* @__PURE__ */ jsx(
|
|
1182
1182
|
ScrollView,
|
|
1183
1183
|
{
|
|
1184
|
-
style:
|
|
1184
|
+
style: styles17.fill,
|
|
1185
1185
|
contentContainerStyle: [
|
|
1186
|
-
|
|
1187
|
-
align === "center" &&
|
|
1186
|
+
styles17.scrollContent,
|
|
1187
|
+
align === "center" && styles17.center
|
|
1188
1188
|
],
|
|
1189
1189
|
keyboardShouldPersistTaps: "handled",
|
|
1190
1190
|
keyboardDismissMode: "on-drag",
|
|
@@ -1192,7 +1192,7 @@ var _CardLayout = ({
|
|
|
1192
1192
|
children
|
|
1193
1193
|
}
|
|
1194
1194
|
),
|
|
1195
|
-
footer ? /* @__PURE__ */ jsx(View, { style:
|
|
1195
|
+
footer ? /* @__PURE__ */ jsx(View, { style: styles17.footer, children: footer }) : null
|
|
1196
1196
|
] });
|
|
1197
1197
|
};
|
|
1198
1198
|
var CardLayout = React18.memo(_CardLayout);
|
|
@@ -1474,7 +1474,7 @@ var deriveAnswers = (messages) => {
|
|
|
1474
1474
|
const props = (_a2 = r.props) != null ? _a2 : {};
|
|
1475
1475
|
const progress = props.progress;
|
|
1476
1476
|
const questionText = (_c = (_b = props.title) != null ? _b : props.label) != null ? _c : props.question;
|
|
1477
|
-
const key = (progress == null ? void 0 : progress.key) || questionText;
|
|
1477
|
+
const key = (progress == null ? void 0 : progress.slot_id) || (progress == null ? void 0 : progress.key) || questionText;
|
|
1478
1478
|
const reply = messages[i + 1];
|
|
1479
1479
|
if (key && (reply == null ? void 0 : reply.role) === "user") {
|
|
1480
1480
|
out[key] = tryParse(stripPrefix(reply.content));
|
|
@@ -1495,6 +1495,8 @@ var readProgress = (response) => {
|
|
|
1495
1495
|
step: typeof p.step === "number" ? p.step : void 0,
|
|
1496
1496
|
total: typeof p.total === "number" ? p.total : void 0,
|
|
1497
1497
|
key: typeof p.key === "string" ? p.key : void 0,
|
|
1498
|
+
// Whitelisted the same way as every other field: an old backend simply omits it.
|
|
1499
|
+
slot_id: typeof p.slot_id === "string" ? p.slot_id : void 0,
|
|
1498
1500
|
skippable: typeof p.skippable === "boolean" ? p.skippable : void 0
|
|
1499
1501
|
};
|
|
1500
1502
|
};
|
|
@@ -1512,28 +1514,35 @@ var buildEventsRequest = (target, events) => {
|
|
|
1512
1514
|
return null;
|
|
1513
1515
|
}
|
|
1514
1516
|
};
|
|
1515
|
-
var
|
|
1516
|
-
if (typeof __DEV__ === "undefined" || !__DEV__) return;
|
|
1517
|
-
if (typeof console === "undefined" || !console.warn) return;
|
|
1517
|
+
var readEventsAck = async (res) => {
|
|
1518
1518
|
try {
|
|
1519
1519
|
const json = res == null ? void 0 : res.json;
|
|
1520
|
-
if (typeof json !== "function") return;
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
);
|
|
1527
|
-
}).catch(() => {
|
|
1528
|
-
});
|
|
1520
|
+
if (typeof json !== "function") return void 0;
|
|
1521
|
+
const body = await Promise.resolve(json.call(res));
|
|
1522
|
+
const skipped = body == null ? void 0 : body.skipped;
|
|
1523
|
+
if (typeof skipped !== "number" || !Number.isFinite(skipped)) return void 0;
|
|
1524
|
+
const reasons = Array.isArray(body == null ? void 0 : body.errors) ? body.errors.map((e) => e == null ? void 0 : e.reason).filter((r) => typeof r === "string") : [];
|
|
1525
|
+
return { written: typeof (body == null ? void 0 : body.written) === "number" ? body.written : void 0, skipped, reasons };
|
|
1529
1526
|
} catch {
|
|
1527
|
+
return void 0;
|
|
1530
1528
|
}
|
|
1531
1529
|
};
|
|
1530
|
+
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.");
|
|
1531
|
+
var warnOnSkippedEvents = (res) => {
|
|
1532
|
+
if (typeof __DEV__ === "undefined" || !__DEV__) return;
|
|
1533
|
+
if (typeof console === "undefined" || !console.warn) return;
|
|
1534
|
+
void readEventsAck(res).then((ack) => {
|
|
1535
|
+
if (!ack || ack.skipped <= 0) return;
|
|
1536
|
+
console.warn(describeDiscarded(ack));
|
|
1537
|
+
});
|
|
1538
|
+
};
|
|
1532
1539
|
var reportClientEvents = (target, events) => {
|
|
1533
1540
|
try {
|
|
1534
1541
|
const req = buildEventsRequest(target, events);
|
|
1535
1542
|
if (!req) return;
|
|
1536
|
-
void fetch(req.url, req.init).
|
|
1543
|
+
void fetch(req.url, req.init).then((res) => {
|
|
1544
|
+
warnOnSkippedEvents(res);
|
|
1545
|
+
}).catch(() => {
|
|
1537
1546
|
});
|
|
1538
1547
|
} catch {
|
|
1539
1548
|
}
|
|
@@ -1544,7 +1553,13 @@ var reportClientEventsAwait = async (target, events) => {
|
|
|
1544
1553
|
const req = buildEventsRequest(target, events);
|
|
1545
1554
|
if (!req) return false;
|
|
1546
1555
|
const res = await fetch(req.url, req.init);
|
|
1547
|
-
|
|
1556
|
+
if (!res || !res.ok) return false;
|
|
1557
|
+
const ack = await readEventsAck(res);
|
|
1558
|
+
if (!ack || ack.skipped <= 0) return true;
|
|
1559
|
+
if (typeof __DEV__ !== "undefined" && __DEV__ && typeof console !== "undefined" && console.warn) {
|
|
1560
|
+
console.warn(describeDiscarded(ack));
|
|
1561
|
+
}
|
|
1562
|
+
return false;
|
|
1548
1563
|
} catch {
|
|
1549
1564
|
return false;
|
|
1550
1565
|
}
|
|
@@ -1764,8 +1779,8 @@ var OnboardingFlow = ({
|
|
|
1764
1779
|
(messageId) => {
|
|
1765
1780
|
var _a3;
|
|
1766
1781
|
const base = makeActions(messageId);
|
|
1767
|
-
const
|
|
1768
|
-
const validator =
|
|
1782
|
+
const validators2 = validatorsRef.current;
|
|
1783
|
+
const validator = (_a3 = progress.slot_id ? validators2 == null ? void 0 : validators2[progress.slot_id] : void 0) != null ? _a3 : progress.key ? validators2 == null ? void 0 : validators2[progress.key] : void 0;
|
|
1769
1784
|
if (!validator) return base;
|
|
1770
1785
|
const out = { ...base };
|
|
1771
1786
|
for (const name2 of ANSWER_CALLBACKS) {
|
|
@@ -1790,7 +1805,7 @@ var OnboardingFlow = ({
|
|
|
1790
1805
|
}
|
|
1791
1806
|
return out;
|
|
1792
1807
|
},
|
|
1793
|
-
[makeActions, progress.key]
|
|
1808
|
+
[makeActions, progress.key, progress.slot_id]
|
|
1794
1809
|
);
|
|
1795
1810
|
if (degraded) {
|
|
1796
1811
|
if (fallbackFlow !== void 0) return /* @__PURE__ */ jsx(Fragment, { children: fallbackFlow });
|
|
@@ -2101,7 +2116,7 @@ var _TextInputCard = ({
|
|
|
2101
2116
|
lines = 6
|
|
2102
2117
|
}) => {
|
|
2103
2118
|
const t = useOnboardingTheme();
|
|
2104
|
-
const
|
|
2119
|
+
const styles17 = useMemo(() => makeStyles3(t), [t]);
|
|
2105
2120
|
const { height: screenHeight } = useWindowDimensions();
|
|
2106
2121
|
const [value, setValue] = useState("");
|
|
2107
2122
|
const [submitted, setSubmitted] = useState(false);
|
|
@@ -2128,7 +2143,7 @@ var _TextInputCard = ({
|
|
|
2128
2143
|
disabled: !value.trim() || locked
|
|
2129
2144
|
}
|
|
2130
2145
|
),
|
|
2131
|
-
children: /* @__PURE__ */ jsxs(View, { style:
|
|
2146
|
+
children: /* @__PURE__ */ jsxs(View, { style: styles17.row, children: [
|
|
2132
2147
|
/* @__PURE__ */ jsx(
|
|
2133
2148
|
TextInput,
|
|
2134
2149
|
{
|
|
@@ -2142,7 +2157,7 @@ var _TextInputCard = ({
|
|
|
2142
2157
|
textAlignVertical: multiline ? "top" : "center",
|
|
2143
2158
|
style: [
|
|
2144
2159
|
bodyStyle(t.fonts),
|
|
2145
|
-
|
|
2160
|
+
styles17.input,
|
|
2146
2161
|
{
|
|
2147
2162
|
color: t.colors.text,
|
|
2148
2163
|
backgroundColor: t.colors.surface,
|
|
@@ -2868,7 +2883,7 @@ var _NumberStepperCard = ({
|
|
|
2868
2883
|
onSubmit
|
|
2869
2884
|
}) => {
|
|
2870
2885
|
const t = useOnboardingTheme();
|
|
2871
|
-
const
|
|
2886
|
+
const styles17 = useMemo(() => makeStyles4(t), [t]);
|
|
2872
2887
|
const safeMin = safeNum(min, 1);
|
|
2873
2888
|
const safeMaxRaw = safeNum(max, 30);
|
|
2874
2889
|
const safeMax = safeMaxRaw < safeMin ? safeMin : safeMaxRaw;
|
|
@@ -2892,7 +2907,7 @@ var _NumberStepperCard = ({
|
|
|
2892
2907
|
const atMin = value <= safeMin;
|
|
2893
2908
|
const atMax = value >= safeMax;
|
|
2894
2909
|
const stepBtnStyle = (disabled) => [
|
|
2895
|
-
|
|
2910
|
+
styles17.stepBtn,
|
|
2896
2911
|
{ borderRadius: t.radius.full, backgroundColor: t.colors.background, borderColor: disabled ? t.colors.border : t.colors.primary }
|
|
2897
2912
|
];
|
|
2898
2913
|
return /* @__PURE__ */ jsx(
|
|
@@ -2901,10 +2916,10 @@ var _NumberStepperCard = ({
|
|
|
2901
2916
|
title: label,
|
|
2902
2917
|
align: "center",
|
|
2903
2918
|
footer: /* @__PURE__ */ jsx(Button, { title: submitLabel, onPress: handleSubmit, variant: "primary", disabled: submitted }),
|
|
2904
|
-
children: /* @__PURE__ */ jsxs(View, { style:
|
|
2905
|
-
/* @__PURE__ */ jsxs(View, { style: [
|
|
2919
|
+
children: /* @__PURE__ */ jsxs(View, { style: styles17.wrap, children: [
|
|
2920
|
+
/* @__PURE__ */ jsxs(View, { style: [styles17.stepper, { gap: t.spacing.lg }], children: [
|
|
2906
2921
|
/* @__PURE__ */ jsx(Pressable, { onPress: atMin || submitted ? void 0 : handleDecrement, disabled: atMin || submitted, style: stepBtnStyle(atMin), children: /* @__PURE__ */ jsx(Text, { style: [headingStyle(t.fonts), { color: atMin ? t.colors.textMuted : t.colors.primary }], children: "\u2212" }) }),
|
|
2907
|
-
/* @__PURE__ */ jsxs(View, { style:
|
|
2922
|
+
/* @__PURE__ */ jsxs(View, { style: styles17.valueBox, children: [
|
|
2908
2923
|
/* @__PURE__ */ jsx(Text, { style: [headingStyle(t.fonts), { color: t.colors.primary }], children: String(value) }),
|
|
2909
2924
|
unit ? /* @__PURE__ */ jsx(Text, { style: [captionStyle(t.fonts), { color: t.colors.textMuted }], children: unit }) : null
|
|
2910
2925
|
] }),
|
|
@@ -3311,6 +3326,33 @@ var collectDeviceContext = () => {
|
|
|
3311
3326
|
return ctx;
|
|
3312
3327
|
};
|
|
3313
3328
|
|
|
3329
|
+
// src/identity/identityRecord.ts
|
|
3330
|
+
var IDENTITY_PROVENANCE_SLOT = /* @__PURE__ */ Symbol.for("@wireai/activation:identityProvenance");
|
|
3331
|
+
var provenanceGlobal = globalThis;
|
|
3332
|
+
var provenanceRegistry = () => {
|
|
3333
|
+
const existing = provenanceGlobal[IDENTITY_PROVENANCE_SLOT];
|
|
3334
|
+
if (existing) return existing;
|
|
3335
|
+
const created = { host: /* @__PURE__ */ new Map() };
|
|
3336
|
+
provenanceGlobal[IDENTITY_PROVENANCE_SLOT] = created;
|
|
3337
|
+
return created;
|
|
3338
|
+
};
|
|
3339
|
+
var provenanceKey = (space, scope) => `${space}:${scope != null ? scope : "default"}`;
|
|
3340
|
+
var resolveIdentity = (input) => {
|
|
3341
|
+
var _a2;
|
|
3342
|
+
if (typeof input.value !== "string") return void 0;
|
|
3343
|
+
const value = input.value.trim();
|
|
3344
|
+
if (!value) return void 0;
|
|
3345
|
+
const durable = (_a2 = input.durable) != null ? _a2 : input.source === "host";
|
|
3346
|
+
if (input.source === "host") {
|
|
3347
|
+
provenanceRegistry().host.set(provenanceKey(input.space, input.scope), value);
|
|
3348
|
+
}
|
|
3349
|
+
return { value, space: input.space, source: input.source, durable };
|
|
3350
|
+
};
|
|
3351
|
+
var hostIdentity = (space, scope) => provenanceRegistry().host.get(provenanceKey(space, scope));
|
|
3352
|
+
var resetIdentityProvenance = () => {
|
|
3353
|
+
provenanceRegistry().host.clear();
|
|
3354
|
+
};
|
|
3355
|
+
|
|
3314
3356
|
// src/context/deviceId.ts
|
|
3315
3357
|
var AUTO_DEVICE_ID_PREFIX = "wdev_";
|
|
3316
3358
|
var deviceIdStorageKey = (appId) => `wireai:analytics:deviceKey:${appId != null ? appId : "default"}`;
|
|
@@ -3333,24 +3375,37 @@ var startHydration = (registry, appId, storage, minted) => {
|
|
|
3333
3375
|
const existing = registry.pending.get(appId);
|
|
3334
3376
|
if (existing) return existing;
|
|
3335
3377
|
const slot = deviceIdStorageKey(appId);
|
|
3336
|
-
const
|
|
3378
|
+
const degraded = () => {
|
|
3337
3379
|
var _a2;
|
|
3338
|
-
return (_a2 = registry.keys.get(appId)) != null ? _a2 : minted;
|
|
3380
|
+
return { value: (_a2 = registry.keys.get(appId)) != null ? _a2 : minted, durable: false };
|
|
3339
3381
|
};
|
|
3382
|
+
const adopted = (value) => ({ value, durable: true });
|
|
3340
3383
|
let run;
|
|
3341
3384
|
try {
|
|
3342
3385
|
run = Promise.resolve(storage.getItem(slot)).then((saved) => {
|
|
3343
3386
|
const persisted = typeof saved === "string" && saved.trim() ? saved.trim() : void 0;
|
|
3344
3387
|
if (persisted) {
|
|
3345
3388
|
registry.keys.set(appId, persisted);
|
|
3346
|
-
return persisted;
|
|
3389
|
+
return adopted(persisted);
|
|
3347
3390
|
}
|
|
3348
|
-
return Promise.resolve(storage.setItem(slot, minted)).then(
|
|
3349
|
-
|
|
3391
|
+
return Promise.resolve(storage.setItem(slot, minted)).then(
|
|
3392
|
+
() => {
|
|
3393
|
+
var _a2;
|
|
3394
|
+
return adopted((_a2 = registry.keys.get(appId)) != null ? _a2 : minted);
|
|
3395
|
+
},
|
|
3396
|
+
degraded
|
|
3397
|
+
);
|
|
3398
|
+
}).catch(degraded);
|
|
3350
3399
|
} catch {
|
|
3351
|
-
run = Promise.resolve(
|
|
3400
|
+
run = Promise.resolve(degraded());
|
|
3352
3401
|
}
|
|
3353
3402
|
registry.pending.set(appId, run);
|
|
3403
|
+
void run.then((outcome) => {
|
|
3404
|
+
var _a2;
|
|
3405
|
+
if (outcome.durable) return;
|
|
3406
|
+
(_a2 = registry.pending) == null ? void 0 : _a2.delete(appId);
|
|
3407
|
+
registry.hydrating.delete(appId);
|
|
3408
|
+
});
|
|
3354
3409
|
return run;
|
|
3355
3410
|
};
|
|
3356
3411
|
var resolveAutoDeviceKey = (opts = {}) => {
|
|
@@ -3370,14 +3425,20 @@ var resolveAutoDeviceKey = (opts = {}) => {
|
|
|
3370
3425
|
return (_b = registry.keys.get(appId)) != null ? _b : id;
|
|
3371
3426
|
};
|
|
3372
3427
|
var hydrateAutoDeviceKey = async (opts = {}) => {
|
|
3428
|
+
var _a2, _b;
|
|
3429
|
+
return (_b = (_a2 = await hydrateDeviceIdentity(opts)) == null ? void 0 : _a2.value) != null ? _b : resolveAutoDeviceKey(opts);
|
|
3430
|
+
};
|
|
3431
|
+
var hydrateDeviceIdentity = async (opts = {}) => {
|
|
3373
3432
|
var _a2, _b, _c;
|
|
3374
3433
|
const id = resolveAutoDeviceKey(opts);
|
|
3375
|
-
if (!opts.storage) return id;
|
|
3376
|
-
const registry = autoDeviceKeyRegistry();
|
|
3377
3434
|
const appId = (_a2 = opts.appId) != null ? _a2 : "default";
|
|
3435
|
+
const record = (value, durable) => resolveIdentity({ value, space: "device", source: "auto", durable, scope: appId });
|
|
3436
|
+
if (!opts.storage) return record(id, false);
|
|
3437
|
+
const registry = autoDeviceKeyRegistry();
|
|
3378
3438
|
const pending = (_b = registry.pending) == null ? void 0 : _b.get(appId);
|
|
3379
|
-
if (pending)
|
|
3380
|
-
|
|
3439
|
+
if (!pending) return record((_c = registry.keys.get(appId)) != null ? _c : id, false);
|
|
3440
|
+
const outcome = await pending;
|
|
3441
|
+
return record(outcome.value, outcome.durable);
|
|
3381
3442
|
};
|
|
3382
3443
|
var resetAutoDeviceKeys = () => {
|
|
3383
3444
|
var _a2;
|
|
@@ -3387,6 +3448,15 @@ var resetAutoDeviceKeys = () => {
|
|
|
3387
3448
|
(_a2 = registry.pending) == null ? void 0 : _a2.clear();
|
|
3388
3449
|
};
|
|
3389
3450
|
|
|
3451
|
+
// src/utils/warnInDev.ts
|
|
3452
|
+
var warnInDev = (message) => {
|
|
3453
|
+
if (typeof __DEV__ !== "undefined" && __DEV__ && typeof console !== "undefined" && console.warn) {
|
|
3454
|
+
console.warn(message);
|
|
3455
|
+
return true;
|
|
3456
|
+
}
|
|
3457
|
+
return false;
|
|
3458
|
+
};
|
|
3459
|
+
|
|
3390
3460
|
// src/analytics/currentSession.ts
|
|
3391
3461
|
var CURRENT_SESSION_ID_SLOT = /* @__PURE__ */ Symbol.for(
|
|
3392
3462
|
"@wireai/activation:currentSessionId"
|
|
@@ -3401,13 +3471,6 @@ var getCurrentSessionId = () => globalSlot[CURRENT_SESSION_ID_SLOT];
|
|
|
3401
3471
|
var resetCurrentSessionId = () => {
|
|
3402
3472
|
globalSlot[CURRENT_SESSION_ID_SLOT] = void 0;
|
|
3403
3473
|
};
|
|
3404
|
-
var warnInDev = (message) => {
|
|
3405
|
-
if (typeof __DEV__ !== "undefined" && __DEV__ && typeof console !== "undefined" && console.warn) {
|
|
3406
|
-
console.warn(message);
|
|
3407
|
-
return true;
|
|
3408
|
-
}
|
|
3409
|
-
return false;
|
|
3410
|
-
};
|
|
3411
3474
|
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.";
|
|
3412
3475
|
var MINT_WARNED_SLOT = /* @__PURE__ */ Symbol.for(
|
|
3413
3476
|
"@wireai/activation:currentSessionIdMintWarned"
|
|
@@ -3504,27 +3567,20 @@ var identifyOnboarding = async (opts) => {
|
|
|
3504
3567
|
contextId = stored == null ? void 0 : stored.id;
|
|
3505
3568
|
}
|
|
3506
3569
|
}
|
|
3507
|
-
|
|
3570
|
+
let space = "onboarding";
|
|
3571
|
+
if (!contextId && opts.allowAppSessionFallback) {
|
|
3572
|
+
contextId = getCurrentSessionId();
|
|
3573
|
+
space = "app_session";
|
|
3574
|
+
}
|
|
3508
3575
|
if (!contextId) return false;
|
|
3509
3576
|
reportClientEvent(
|
|
3510
3577
|
{ serverUrl: opts.config.serverUrl, apiKey: opts.config.apiKey },
|
|
3511
3578
|
{ event_type: "identify", session_id: contextId, user_id: userId }
|
|
3512
3579
|
);
|
|
3513
|
-
return
|
|
3580
|
+
return space;
|
|
3514
3581
|
};
|
|
3515
3582
|
|
|
3516
3583
|
// src/context/userContext.ts
|
|
3517
|
-
var RESERVED_USER_CONTEXT_KEYS = [
|
|
3518
|
-
"device_key",
|
|
3519
|
-
"app_version",
|
|
3520
|
-
"app_build",
|
|
3521
|
-
"network_type",
|
|
3522
|
-
"session_count",
|
|
3523
|
-
"returning",
|
|
3524
|
-
"platform",
|
|
3525
|
-
"user_email",
|
|
3526
|
-
"user_email_hashed"
|
|
3527
|
-
];
|
|
3528
3584
|
var EXTRA_KEY_PREFIX = "custom.";
|
|
3529
3585
|
var isWireScalar = (value) => {
|
|
3530
3586
|
const t = typeof value;
|
|
@@ -3605,11 +3661,6 @@ var resolveUserContext = (ctx = {}, opts = {}) => {
|
|
|
3605
3661
|
if (Object.keys(bucket).length > 0) result.userContext = bucket;
|
|
3606
3662
|
return result;
|
|
3607
3663
|
};
|
|
3608
|
-
var warnInDev2 = (message) => {
|
|
3609
|
-
if (typeof __DEV__ !== "undefined" && __DEV__ && typeof console !== "undefined" && console.warn) {
|
|
3610
|
-
console.warn(message);
|
|
3611
|
-
}
|
|
3612
|
-
};
|
|
3613
3664
|
var AUTO_JOIN_HYDRATION_TIMEOUT_MS = 1500;
|
|
3614
3665
|
var WireOnboarding = ({
|
|
3615
3666
|
config,
|
|
@@ -3636,7 +3687,7 @@ var WireOnboarding = ({
|
|
|
3636
3687
|
userId,
|
|
3637
3688
|
autoJoinKey = true
|
|
3638
3689
|
}) => {
|
|
3639
|
-
var _a2, _b, _c;
|
|
3690
|
+
var _a2, _b, _c, _d, _e;
|
|
3640
3691
|
const boundUserId = useMemo(() => sanitizeUserId(userId), [userId]);
|
|
3641
3692
|
const device = useMemo(() => {
|
|
3642
3693
|
const collected = collectDeviceContext();
|
|
@@ -3647,44 +3698,72 @@ var WireOnboarding = ({
|
|
|
3647
3698
|
() => userContextKey ? JSON.parse(userContextKey) : void 0,
|
|
3648
3699
|
[userContextKey]
|
|
3649
3700
|
);
|
|
3650
|
-
const
|
|
3701
|
+
const hostJoinIdentity = useMemo(
|
|
3702
|
+
() => resolveIdentity({
|
|
3703
|
+
value: userContextStable == null ? void 0 : userContextStable.device_key,
|
|
3704
|
+
space: "device",
|
|
3705
|
+
source: "host",
|
|
3706
|
+
scope: config.appId
|
|
3707
|
+
}),
|
|
3708
|
+
[userContextStable, config.appId]
|
|
3709
|
+
);
|
|
3710
|
+
const missingJoinKey = !hostJoinIdentity;
|
|
3651
3711
|
const autoJoinPossible = Boolean(storage) && autoJoinKey !== false;
|
|
3652
3712
|
const wantsAutoJoin = missingJoinKey && autoJoinPossible;
|
|
3653
|
-
const [
|
|
3713
|
+
const [autoJoinOutcome, setAutoJoinOutcome] = useState(void 0);
|
|
3654
3714
|
useEffect(() => {
|
|
3655
|
-
if (!wantsAutoJoin ||
|
|
3715
|
+
if (!wantsAutoJoin || autoJoinOutcome !== void 0 || !storage) return;
|
|
3656
3716
|
let cancelled = false;
|
|
3657
3717
|
const timer = setTimeout(() => {
|
|
3658
|
-
if (!cancelled)
|
|
3718
|
+
if (!cancelled) setAutoJoinOutcome({ key: null, reason: "timeout" });
|
|
3659
3719
|
}, AUTO_JOIN_HYDRATION_TIMEOUT_MS);
|
|
3660
|
-
void
|
|
3720
|
+
void hydrateDeviceIdentity({ appId: config.appId, storage }).then((identity) => {
|
|
3661
3721
|
if (cancelled) return;
|
|
3662
3722
|
clearTimeout(timer);
|
|
3663
|
-
|
|
3723
|
+
setAutoJoinOutcome(
|
|
3724
|
+
(identity == null ? void 0 : identity.durable) ? { key: identity.value } : { key: null, reason: "not-durable" }
|
|
3725
|
+
);
|
|
3664
3726
|
});
|
|
3665
3727
|
return () => {
|
|
3666
3728
|
cancelled = true;
|
|
3667
3729
|
clearTimeout(timer);
|
|
3668
3730
|
};
|
|
3669
|
-
}, [wantsAutoJoin,
|
|
3670
|
-
const injectedJoinKey = wantsAutoJoin
|
|
3671
|
-
const autoJoinPending = wantsAutoJoin &&
|
|
3731
|
+
}, [wantsAutoJoin, autoJoinOutcome, config.appId, storage]);
|
|
3732
|
+
const injectedJoinKey = wantsAutoJoin ? (_a2 = autoJoinOutcome == null ? void 0 : autoJoinOutcome.key) != null ? _a2 : void 0 : void 0;
|
|
3733
|
+
const autoJoinPending = wantsAutoJoin && autoJoinOutcome === void 0;
|
|
3672
3734
|
const effectiveUserContext = useMemo(
|
|
3673
3735
|
() => injectedJoinKey ? { ...userContextStable, ...activationJoinContext(injectedJoinKey) } : userContextStable,
|
|
3674
3736
|
[userContextStable, injectedJoinKey]
|
|
3675
3737
|
);
|
|
3738
|
+
const frozenWireContextRef = useRef(null);
|
|
3739
|
+
if (!autoJoinPending && frozenWireContextRef.current === null) {
|
|
3740
|
+
frozenWireContextRef.current = effectiveUserContext ? JSON.stringify(effectiveUserContext) : "";
|
|
3741
|
+
}
|
|
3742
|
+
const startupUserContextKey = (_b = frozenWireContextRef.current) != null ? _b : "";
|
|
3743
|
+
const startupUserContext = useMemo(
|
|
3744
|
+
() => startupUserContextKey ? JSON.parse(startupUserContextKey) : void 0,
|
|
3745
|
+
[startupUserContextKey]
|
|
3746
|
+
);
|
|
3676
3747
|
const warnMissingJoinKey = missingJoinKey && !injectedJoinKey && !autoJoinPending;
|
|
3677
|
-
const autoJoinReason = autoJoinKey === false ? "you passed autoJoinKey={false}." : !storage ? "it got no `storage` prop, and without persistence its key would be different on every launch, which corrupts min_sessions instead of merely leaving the join empty." : "your `storage` adapter did not answer in time.";
|
|
3748
|
+
const autoJoinReason = autoJoinKey === false ? "you passed autoJoinKey={false}." : !storage ? "it got no `storage` prop, and without persistence its key would be different on every launch, which corrupts min_sessions instead of merely leaving the join empty." : (autoJoinOutcome == null ? void 0 : autoJoinOutcome.key) === null && autoJoinOutcome.reason === "not-durable" ? "your `storage` adapter answered but could not persist the key (the read or the write failed), so the key would be different on every launch, which corrupts min_sessions instead of merely leaving the join empty. Check the adapter you passed as `storage`." : "your `storage` adapter did not answer in time.";
|
|
3678
3749
|
useEffect(() => {
|
|
3679
3750
|
if (!warnMissingJoinKey) return;
|
|
3680
|
-
|
|
3751
|
+
warnInDev(
|
|
3681
3752
|
"[wireai] <WireOnboarding> got no user_context.device_key, so this onboarding session can never be joined to the app's later events and the `activated` funnel will read zero. Pass userContext={activationJoinContext(deviceKey)} \u2014 and if your app owns no device id, userContext={activationJoinContext(resolveAutoDeviceKey({ appId, storage }))} returns the SAME id the analytics side stamps. Never hand-write userContext={{ deviceKey }}. The kit did NOT auto-inject its own key here because " + autoJoinReason
|
|
3682
3753
|
);
|
|
3683
3754
|
}, [warnMissingJoinKey, autoJoinReason]);
|
|
3755
|
+
const hostKeyElsewhere = missingJoinKey ? hostIdentity("device", config.appId) : void 0;
|
|
3756
|
+
const warnHostKeyElsewhere = Boolean(hostKeyElsewhere) && Boolean(injectedJoinKey);
|
|
3757
|
+
useEffect(() => {
|
|
3758
|
+
if (!warnHostKeyElsewhere) return;
|
|
3759
|
+
warnInDev(
|
|
3760
|
+
`[wireai] <WireOnboarding> got no user_context.device_key, so the kit injected its own \u2014 but another surface in this app was constructed WITH a host-supplied device key ("${hostKeyElsewhere}"). Your app events carry that id and this onboarding session carries the kit's, so the two land in disjoint id spaces and the \`activated\` funnel still reads zero. Pass the SAME id here: userContext={activationJoinContext(deviceKey)}.`
|
|
3761
|
+
);
|
|
3762
|
+
}, [warnHostKeyElsewhere, hostKeyElsewhere]);
|
|
3684
3763
|
const misspelledJoinKey = missingJoinKey && typeof (userContextStable == null ? void 0 : userContextStable.deviceKey) === "string" && Boolean(userContextStable.deviceKey.trim());
|
|
3685
3764
|
useEffect(() => {
|
|
3686
3765
|
if (!misspelledJoinKey || !injectedJoinKey) return;
|
|
3687
|
-
|
|
3766
|
+
warnInDev(
|
|
3688
3767
|
"[wireai] <WireOnboarding> got userContext={{ deviceKey }}, which is NOT the wire key \u2014 the server's device lookup reads `device_key`. The kit auto-injected its own device_key so this session is at least self-consistent, but your app's own events carry YOUR id, so the two still will not join and the `activated` funnel stays zero. Pass userContext={activationJoinContext(deviceKey)} instead."
|
|
3689
3768
|
);
|
|
3690
3769
|
}, [misspelledJoinKey, injectedJoinKey]);
|
|
@@ -3713,7 +3792,7 @@ var WireOnboarding = ({
|
|
|
3713
3792
|
},
|
|
3714
3793
|
[storage, storageKey, retainSessionOnComplete, onComplete]
|
|
3715
3794
|
);
|
|
3716
|
-
const sessionId = (
|
|
3795
|
+
const sessionId = (_c = session == null ? void 0 : session.id) != null ? _c : "";
|
|
3717
3796
|
const startupUserIdRef = useRef(boundUserId);
|
|
3718
3797
|
const metadataKey = config.metadata ? JSON.stringify(config.metadata) : "";
|
|
3719
3798
|
const metadataStable = useMemo(() => metadataKey ? JSON.parse(metadataKey) : void 0, [metadataKey]);
|
|
@@ -3737,7 +3816,9 @@ var WireOnboarding = ({
|
|
|
3737
3816
|
// Device snapshot + host-injected user context ride the session-start metadata so the
|
|
3738
3817
|
// backend can segment the funnel. Old servers ignore these unknown keys (backward compat).
|
|
3739
3818
|
device,
|
|
3740
|
-
|
|
3819
|
+
// The FROZEN wire context, never the live one — see the freeze note above. A change here
|
|
3820
|
+
// recreates the A2A adapter and drops `contextId`.
|
|
3821
|
+
...startupUserContext ? { userContext: startupUserContext } : {},
|
|
3741
3822
|
// The session-start user id (from the ref) rides the session-start metadata so the
|
|
3742
3823
|
// server binds the session to a real user at creation. Reading the ref — not
|
|
3743
3824
|
// `boundUserId` — keeps this memo off the userId dependency, so a mid-session change
|
|
@@ -3746,7 +3827,7 @@ var WireOnboarding = ({
|
|
|
3746
3827
|
},
|
|
3747
3828
|
timeoutMs: 6e4
|
|
3748
3829
|
};
|
|
3749
|
-
}, [config.serverUrl, config.appId, config.apiKey, metadataStable, sessionId, componentsStable, device,
|
|
3830
|
+
}, [config.serverUrl, config.appId, config.apiKey, metadataStable, sessionId, componentsStable, device, startupUserContext]);
|
|
3750
3831
|
const reportTarget = useMemo(
|
|
3751
3832
|
() => ({ serverUrl: config.serverUrl, apiKey: config.apiKey }),
|
|
3752
3833
|
[config.serverUrl, config.apiKey]
|
|
@@ -3772,8 +3853,8 @@ var WireOnboarding = ({
|
|
|
3772
3853
|
return /* @__PURE__ */ jsx(OnboardingThemeProvider, { theme, children: /* @__PURE__ */ jsx(
|
|
3773
3854
|
LoadingScreen,
|
|
3774
3855
|
{
|
|
3775
|
-
title: (
|
|
3776
|
-
hint: (
|
|
3856
|
+
title: (_d = copy == null ? void 0 : copy.restoringTitle) != null ? _d : DEFAULT_COPY.restoringTitle,
|
|
3857
|
+
hint: (_e = copy == null ? void 0 : copy.restoringHint) != null ? _e : DEFAULT_COPY.restoringHint
|
|
3777
3858
|
}
|
|
3778
3859
|
) });
|
|
3779
3860
|
}
|
|
@@ -3811,7 +3892,7 @@ function DemoOnboarding({
|
|
|
3811
3892
|
const [open, setOpen] = useState(false);
|
|
3812
3893
|
const [runId, setRunId] = useState(0);
|
|
3813
3894
|
const t = useMemo(() => mergeTheme(theme != null ? theme : {}), [theme]);
|
|
3814
|
-
const
|
|
3895
|
+
const styles17 = useMemo(() => makeStyles5(t), [t]);
|
|
3815
3896
|
const openDemo = useCallback(() => {
|
|
3816
3897
|
setRunId((n) => n + 1);
|
|
3817
3898
|
setOpen(true);
|
|
@@ -3825,7 +3906,7 @@ function DemoOnboarding({
|
|
|
3825
3906
|
[onComplete]
|
|
3826
3907
|
);
|
|
3827
3908
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3828
|
-
renderTrigger ? renderTrigger(openDemo) : /* @__PURE__ */ jsx(Pressable, { onPress: openDemo, style:
|
|
3909
|
+
renderTrigger ? renderTrigger(openDemo) : /* @__PURE__ */ jsx(Pressable, { onPress: openDemo, style: styles17.trigger, accessibilityRole: "button", children: /* @__PURE__ */ jsx(Text, { style: styles17.triggerText, children: label }) }),
|
|
3829
3910
|
/* @__PURE__ */ jsx(
|
|
3830
3911
|
Modal,
|
|
3831
3912
|
{
|
|
@@ -3833,7 +3914,7 @@ function DemoOnboarding({
|
|
|
3833
3914
|
animationType: "slide",
|
|
3834
3915
|
presentationStyle: "fullScreen",
|
|
3835
3916
|
onRequestClose: close,
|
|
3836
|
-
children: /* @__PURE__ */ jsx(View, { style:
|
|
3917
|
+
children: /* @__PURE__ */ jsx(View, { style: styles17.modal, children: config ? /* @__PURE__ */ jsx(
|
|
3837
3918
|
WireOnboarding,
|
|
3838
3919
|
{
|
|
3839
3920
|
config,
|
|
@@ -3846,10 +3927,10 @@ function DemoOnboarding({
|
|
|
3846
3927
|
onError: close
|
|
3847
3928
|
},
|
|
3848
3929
|
runId
|
|
3849
|
-
) : /* @__PURE__ */ jsxs(View, { style:
|
|
3850
|
-
/* @__PURE__ */ jsx(Text, { style:
|
|
3851
|
-
/* @__PURE__ */ jsx(Text, { style:
|
|
3852
|
-
/* @__PURE__ */ jsx(Pressable, { onPress: close, style:
|
|
3930
|
+
) : /* @__PURE__ */ jsxs(View, { style: styles17.notice, children: [
|
|
3931
|
+
/* @__PURE__ */ jsx(Text, { style: styles17.noticeTitle, children: "Wire AI not configured" }),
|
|
3932
|
+
/* @__PURE__ */ jsx(Text, { style: styles17.noticeBody, children: "Set the Wire AI key + server URL (e.g. via wireConfigFromEnv) to demo the AI onboarding here." }),
|
|
3933
|
+
/* @__PURE__ */ jsx(Pressable, { onPress: close, style: styles17.trigger, accessibilityRole: "button", children: /* @__PURE__ */ jsx(Text, { style: styles17.triggerText, children: "Close" }) })
|
|
3853
3934
|
] }) })
|
|
3854
3935
|
}
|
|
3855
3936
|
)
|
|
@@ -3923,20 +4004,6 @@ var themeFromBrand = (input) => {
|
|
|
3923
4004
|
button: { ...base.button, ...extra.button }
|
|
3924
4005
|
};
|
|
3925
4006
|
};
|
|
3926
|
-
var _DoneBlock = ({
|
|
3927
|
-
title = "You're all set",
|
|
3928
|
-
message = "Personalizing your experience\u2026"
|
|
3929
|
-
}) => {
|
|
3930
|
-
const t = useOnboardingTheme();
|
|
3931
|
-
return /* @__PURE__ */ jsxs(View, { style: [styles16.center, { gap: t.spacing.sm, padding: t.spacing.lg }], children: [
|
|
3932
|
-
/* @__PURE__ */ jsx(Text, { style: [headingStyle(t.fonts), { color: t.colors.success, textAlign: "center" }], children: title }),
|
|
3933
|
-
/* @__PURE__ */ jsx(Text, { style: [bodyStyle(t.fonts), { color: t.colors.textMuted, textAlign: "center" }], children: message })
|
|
3934
|
-
] });
|
|
3935
|
-
};
|
|
3936
|
-
var DoneBlock = React18.memo(_DoneBlock);
|
|
3937
|
-
var styles16 = StyleSheet.create({
|
|
3938
|
-
center: { flex: 1, alignItems: "center", justifyContent: "center" }
|
|
3939
|
-
});
|
|
3940
4007
|
|
|
3941
4008
|
// src/motion/centeredModalMotion.ts
|
|
3942
4009
|
var CENTERED_MODAL_ANIM = {
|
|
@@ -4013,25 +4080,25 @@ var _CenteredModal = forwardRef(
|
|
|
4013
4080
|
/* @__PURE__ */ jsx(
|
|
4014
4081
|
Animated.View,
|
|
4015
4082
|
{
|
|
4016
|
-
style: [
|
|
4083
|
+
style: [styles16.backdrop, { opacity: backdropOpacity }],
|
|
4017
4084
|
pointerEvents: "none"
|
|
4018
4085
|
}
|
|
4019
4086
|
),
|
|
4020
4087
|
/* @__PURE__ */ jsx(
|
|
4021
4088
|
Pressable,
|
|
4022
4089
|
{
|
|
4023
|
-
style:
|
|
4090
|
+
style: styles16.fill,
|
|
4024
4091
|
onPress: onBackdrop,
|
|
4025
4092
|
accessibilityRole: "button",
|
|
4026
4093
|
accessibilityLabel: "Dismiss",
|
|
4027
|
-
children: /* @__PURE__ */ jsx(SafeAreaView, { style:
|
|
4028
|
-
}, style:
|
|
4094
|
+
children: /* @__PURE__ */ jsx(SafeAreaView, { style: styles16.center, pointerEvents: "box-none", children: /* @__PURE__ */ jsx(Pressable, { onPress: () => {
|
|
4095
|
+
}, style: styles16.cardWrap, children: /* @__PURE__ */ jsx(
|
|
4029
4096
|
Animated.View,
|
|
4030
4097
|
{
|
|
4031
4098
|
accessibilityViewIsModal: true,
|
|
4032
4099
|
accessibilityRole: "alert",
|
|
4033
4100
|
style: [
|
|
4034
|
-
|
|
4101
|
+
styles16.card,
|
|
4035
4102
|
{
|
|
4036
4103
|
backgroundColor: theme.colors.surface,
|
|
4037
4104
|
borderRadius: theme.radius.lg,
|
|
@@ -4053,7 +4120,7 @@ var _CenteredModal = forwardRef(
|
|
|
4053
4120
|
);
|
|
4054
4121
|
_CenteredModal.displayName = "CenteredModal";
|
|
4055
4122
|
var CenteredModal = React18.memo(_CenteredModal);
|
|
4056
|
-
var
|
|
4123
|
+
var styles16 = StyleSheet.create({
|
|
4057
4124
|
fill: { flex: 1 },
|
|
4058
4125
|
backdrop: { position: "absolute", top: 0, left: 0, right: 0, bottom: 0, backgroundColor: "#000" },
|
|
4059
4126
|
center: { flex: 1, alignItems: "center", justifyContent: "center", padding: 24 },
|
|
@@ -4239,11 +4306,6 @@ var WIRE_ENV_VARS = [
|
|
|
4239
4306
|
"EXPO_PUBLIC_WIREAI_SERVER_URL",
|
|
4240
4307
|
"EXPO_PUBLIC_WIREAI_APP_ID"
|
|
4241
4308
|
];
|
|
4242
|
-
var warnInDev3 = (message) => {
|
|
4243
|
-
if (typeof __DEV__ !== "undefined" && __DEV__ && typeof console !== "undefined" && console.warn) {
|
|
4244
|
-
console.warn(message);
|
|
4245
|
-
}
|
|
4246
|
-
};
|
|
4247
4309
|
var wireConfigFromEnv = (overrides) => {
|
|
4248
4310
|
var _a2, _b, _c, _d, _e;
|
|
4249
4311
|
const apiKey = (_a2 = overrides == null ? void 0 : overrides.apiKey) != null ? _a2 : process.env.EXPO_PUBLIC_WIREAI_API_KEY;
|
|
@@ -4254,7 +4316,7 @@ var wireConfigFromEnv = (overrides) => {
|
|
|
4254
4316
|
apiKey ? void 0 : "EXPO_PUBLIC_WIREAI_API_KEY",
|
|
4255
4317
|
serverUrl ? void 0 : "EXPO_PUBLIC_WIREAI_SERVER_URL"
|
|
4256
4318
|
].filter(Boolean);
|
|
4257
|
-
|
|
4319
|
+
warnInDev(
|
|
4258
4320
|
`[wireai] wireConfigFromEnv() returned null: ${missing.join(" and ")} ${missing.length > 1 ? "are" : "is"} missing. The kit is now FULLY DISABLED (no onboarding, no analytics, no gates) and nothing else will report an error. Set the var(s) in your env / EAS secrets.`
|
|
4259
4321
|
);
|
|
4260
4322
|
return null;
|
|
@@ -4362,15 +4424,17 @@ var resetActivationRevalidation = () => {
|
|
|
4362
4424
|
};
|
|
4363
4425
|
|
|
4364
4426
|
// src/activation/wireActivation.ts
|
|
4365
|
-
var clean =
|
|
4366
|
-
if (typeof value !== "string") return void 0;
|
|
4367
|
-
const trimmed = value.trim();
|
|
4368
|
-
return trimmed.length > 0 ? trimmed : void 0;
|
|
4369
|
-
};
|
|
4427
|
+
var clean = cleanString;
|
|
4370
4428
|
var createWireActivation = (config) => {
|
|
4371
4429
|
var _a2, _b;
|
|
4372
4430
|
const target = { serverUrl: config.serverUrl, apiKey: config.apiKey };
|
|
4373
4431
|
const explicitDeviceKey = (_b = clean(config.deviceKey)) != null ? _b : clean((_a2 = config.userContext) == null ? void 0 : _a2.deviceKey);
|
|
4432
|
+
resolveIdentity({
|
|
4433
|
+
value: explicitDeviceKey,
|
|
4434
|
+
space: "device",
|
|
4435
|
+
source: "host",
|
|
4436
|
+
scope: config.appId
|
|
4437
|
+
});
|
|
4374
4438
|
const autoDeviceKeyOptions = {
|
|
4375
4439
|
appId: config.appId,
|
|
4376
4440
|
// An explicit key opts out of minting AND persisting (unchanged contract).
|
|
@@ -4804,6 +4868,30 @@ var DEFAULTS = {
|
|
|
4804
4868
|
maxRetries: 6
|
|
4805
4869
|
};
|
|
4806
4870
|
var READ_TIMEOUT_MS4 = 1500;
|
|
4871
|
+
var QUEUE_KEY_SLOT = /* @__PURE__ */ Symbol.for("@wireai/activation:eventQueueKeys");
|
|
4872
|
+
var queueKeyGlobal = globalThis;
|
|
4873
|
+
var claimedQueueKeys = () => {
|
|
4874
|
+
const existing = queueKeyGlobal[QUEUE_KEY_SLOT];
|
|
4875
|
+
if (existing) return existing;
|
|
4876
|
+
const created = /* @__PURE__ */ new Set();
|
|
4877
|
+
queueKeyGlobal[QUEUE_KEY_SLOT] = created;
|
|
4878
|
+
return created;
|
|
4879
|
+
};
|
|
4880
|
+
var claimQueueKey = (preferred, explicit) => {
|
|
4881
|
+
const claimed = claimedQueueKeys();
|
|
4882
|
+
if (explicit || !claimed.has(preferred)) {
|
|
4883
|
+
claimed.add(preferred);
|
|
4884
|
+
return preferred;
|
|
4885
|
+
}
|
|
4886
|
+
let ordinal = 2;
|
|
4887
|
+
while (claimed.has(`${preferred}#${ordinal}`)) ordinal++;
|
|
4888
|
+
const key = `${preferred}#${ordinal}`;
|
|
4889
|
+
claimed.add(key);
|
|
4890
|
+
warnInDev(
|
|
4891
|
+
`[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.`
|
|
4892
|
+
);
|
|
4893
|
+
return key;
|
|
4894
|
+
};
|
|
4807
4895
|
var withTimeout4 = (p, ms) => {
|
|
4808
4896
|
let timer;
|
|
4809
4897
|
const timeout = new Promise((resolve) => {
|
|
@@ -4835,7 +4923,8 @@ var createEventQueue = (options) => {
|
|
|
4835
4923
|
var _a2, _b, _c, _d, _e, _f, _g;
|
|
4836
4924
|
const target = options.target;
|
|
4837
4925
|
const storage = options.storage;
|
|
4838
|
-
const
|
|
4926
|
+
const defaultKey = (_b = options.storageKey) != null ? _b : `wireai:evtq:${(_a2 = options.appId) != null ? _a2 : "default"}`;
|
|
4927
|
+
const key = storage ? claimQueueKey(defaultKey, options.storageKey !== void 0) : defaultKey;
|
|
4839
4928
|
const maxSize = (_c = options.maxSize) != null ? _c : DEFAULTS.maxSize;
|
|
4840
4929
|
const batchSize = (_d = options.batchSize) != null ? _d : DEFAULTS.batchSize;
|
|
4841
4930
|
const baseBackoffMs = (_e = options.baseBackoffMs) != null ? _e : DEFAULTS.baseBackoffMs;
|
|
@@ -5025,7 +5114,13 @@ var useLifecycleEvents = (config, options = {}) => {
|
|
|
5025
5114
|
return (cfg == null ? void 0 : cfg.serverUrl) ? { serverUrl: cfg.serverUrl, apiKey: (_a2 = cfg.apiKey) != null ? _a2 : "" } : void 0;
|
|
5026
5115
|
};
|
|
5027
5116
|
const resolveDeviceKey = (cfg, opts) => {
|
|
5028
|
-
|
|
5117
|
+
var _a2;
|
|
5118
|
+
const host = (_a2 = resolveIdentity({
|
|
5119
|
+
value: opts.deviceKey,
|
|
5120
|
+
space: "device",
|
|
5121
|
+
source: "host",
|
|
5122
|
+
scope: cfg == null ? void 0 : cfg.appId
|
|
5123
|
+
})) == null ? void 0 : _a2.value;
|
|
5029
5124
|
if (host) return host;
|
|
5030
5125
|
if (!(cfg == null ? void 0 : cfg.storage)) return void 0;
|
|
5031
5126
|
return resolveAutoDeviceKey({ appId: cfg.appId, storage: cfg.storage });
|
|
@@ -5103,6 +5198,6 @@ var useLifecycleEvents = (config, options = {}) => {
|
|
|
5103
5198
|
}, []);
|
|
5104
5199
|
};
|
|
5105
5200
|
|
|
5106
|
-
export { AUTO_DEVICE_ID_PREFIX, AnimatedSparkle, BACKGROUND_SESSION_MS, CardGridSelectCard, CardHandoff, CenteredModal, ChipSelectCard, CompletionView, DEFAULT_FEATURES_TTL_MS, DEFAULT_SESSION_TTL_MS, DemoOnboarding,
|
|
5201
|
+
export { AUTO_DEVICE_ID_PREFIX, AnimatedSparkle, BACKGROUND_SESSION_MS, CardGridSelectCard, CardHandoff, CenteredModal, ChipSelectCard, CompletionView, DEFAULT_FEATURES_TTL_MS, DEFAULT_SESSION_TTL_MS, DemoOnboarding, EXTRA_KEY_PREFIX, ErrorBlock, FIRST_OPEN_EVENT, IconRegistryProvider, IllustrationProvider, InterstitialCard, LoadingBlock, LoadingScreen, NumberStepperCard, Button as OnboardingButton, OnboardingFlow, OnboardingScaffold, OnboardingThemeProvider, PLAN_TIER_CONTEXT_KEY, SESSION_STARTED_EVENT, SelectionCard, StatusCard, StepProgress, TextInputCard, USER_ID_MAX_LENGTH, WIRE_ENV_VARS, WIRE_ICON_GLYPHS, WIRE_ICON_NAMES, WIRE_ONBOARDING_EVENTS, WIRE_PURCHASE_EVENTS, WireFeaturesProvider, WireIcon, WireOnboarding, activationJoinContext, activeEntitlement, analyticsUserIdStorageKey, attributionMetadata, bumpActivationRevalidation, clearPersistedSession, clearPiiFromContext, clearUserContext, collectDeviceContext, createRevenueCatBridge, createWireActivation, defaultIllustrations, defaultOnboardingTheme, defaultWireFeatures, deriveAnswers, describeEntitlement, describeFailure, describePackage, detectAppVersion, detectNativeModel, deviceIdStorageKey, ensureCurrentSessionId, featuresCacheKey, featuresEqual, fetchWireFeatures, firstOpenStorageKey, getActivationRevalidationVersion, getCurrentSessionId, hashEmailFnv1a, hostIdentity, hydrateAutoDeviceKey, hydrateDeviceIdentity, identifyOnboarding, isFeaturesFresh, isOnboardingEnabled, isUserCancelled, isWireScalar, loadPersistedSession, looksLikeEmail, lookupIconGlyph, makeSessionId, mergeTheme, mintDeviceId, motionSpec_exports as motionSpec, namespaceExtra, onboardingComponents, parseWireFeatures, peekPersistedSession, readCachedFeatures, readProgress, reportClientEvent, reportClientEventAwait, reportClientEvents, reportClientEventsAwait, reportFirstOpen, reportSessionStart, resetActivationRevalidation, resetAutoDeviceKeys, resetCurrentSessionId, resetFirstOpenLatch, resetIdentityProvenance, resetSessionStartGuard, resolveAutoDeviceKey, resolveIdentity, resolvePlanTier, resolveUserContext, sanitizeUserId, savePersistedSession, sessionStorageKey, setCurrentSessionId, subscribeActivationRevalidation, themeFromBrand, toAnalyticsEvent, useActivationRevalidation, useHostIcon, useIllustration, useLifecycleEvents, useOnboardingTheme, useReducedMotion, useResolvedFeatures, useSessionStart, useWireActivation, useWireFeatures, useWireFeaturesContext, wireConfigFromEnv, wireLifecycleEvents, writeCachedFeatures };
|
|
5107
5202
|
//# sourceMappingURL=index.mjs.map
|
|
5108
5203
|
//# sourceMappingURL=index.mjs.map
|