@wireai/activation 0.11.0 → 0.12.1

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.
Files changed (73) hide show
  1. package/AGENTS.md +62 -8
  2. package/CHANGELOG.md +188 -3
  3. package/INTEGRATION_PROMPT.md +25 -2
  4. package/README.md +112 -1
  5. package/dist/analytics/index.d.mts +18 -6
  6. package/dist/analytics/index.d.ts +18 -6
  7. package/dist/analytics/index.js +151 -41
  8. package/dist/analytics/index.js.map +1 -1
  9. package/dist/analytics/index.mjs +147 -42
  10. package/dist/analytics/index.mjs.map +1 -1
  11. package/dist/coachmarks/index.d.mts +16 -0
  12. package/dist/coachmarks/index.d.ts +16 -0
  13. package/dist/coachmarks/index.js +19 -13
  14. package/dist/coachmarks/index.js.map +1 -1
  15. package/dist/coachmarks/index.mjs +19 -13
  16. package/dist/coachmarks/index.mjs.map +1 -1
  17. package/dist/{currentSession-C0_odnIW.d.mts → currentSession-BlCeDP0f.d.mts} +145 -33
  18. package/dist/{currentSession-DdnUq2HQ.d.ts → currentSession-BxEB37xt.d.ts} +145 -33
  19. package/dist/index.d.mts +243 -53
  20. package/dist/index.d.ts +243 -53
  21. package/dist/index.js +531 -156
  22. package/dist/index.js.map +1 -1
  23. package/dist/index.mjs +517 -157
  24. package/dist/index.mjs.map +1 -1
  25. package/dist/questionnaire/index.d.mts +1 -1
  26. package/dist/questionnaire/index.d.ts +1 -1
  27. package/dist/questionnaire/index.js +79 -14
  28. package/dist/questionnaire/index.js.map +1 -1
  29. package/dist/questionnaire/index.mjs +79 -14
  30. package/dist/questionnaire/index.mjs.map +1 -1
  31. package/dist/reviews/index.d.mts +2 -2
  32. package/dist/reviews/index.d.ts +2 -2
  33. package/dist/reviews/index.js +103 -16
  34. package/dist/reviews/index.js.map +1 -1
  35. package/dist/reviews/index.mjs +103 -16
  36. package/dist/reviews/index.mjs.map +1 -1
  37. package/dist/showcase/index.js +15 -6
  38. package/dist/showcase/index.js.map +1 -1
  39. package/dist/showcase/index.mjs +15 -6
  40. package/dist/showcase/index.mjs.map +1 -1
  41. package/dist/{transport-BGW9uXZJ.d.mts → transport-CF_eHwzC.d.mts} +15 -1
  42. package/dist/{transport-jUJd5kxu.d.ts → transport-DsRe4epC.d.ts} +15 -1
  43. package/llms.txt +3 -0
  44. package/package.json +1 -1
  45. package/src/WireOnboarding.tsx +140 -5
  46. package/src/activation/useWireActivation.ts +12 -1
  47. package/src/activation/wireActivation.ts +44 -25
  48. package/src/analytics/analyticsFacade.ts +54 -29
  49. package/src/analytics/currentSession.ts +83 -0
  50. package/src/analytics/eventQueue.ts +9 -1
  51. package/src/analytics/index.ts +20 -1
  52. package/src/analytics/reportClientEvent.ts +42 -0
  53. package/src/analytics/screenTracking.ts +6 -1
  54. package/src/analytics/useAnalytics.ts +22 -1
  55. package/src/coachmarks/runtime.ts +53 -17
  56. package/src/config/wireConfigFromEnv.ts +46 -2
  57. package/src/context/deviceId.ts +173 -0
  58. package/src/context/userContext.ts +18 -0
  59. package/src/index.ts +54 -2
  60. package/src/questionnaire/runtime.ts +13 -2
  61. package/src/questionnaire/useQuestionnaireGate.ts +11 -4
  62. package/src/revenuecat/index.ts +55 -0
  63. package/src/revenuecat/purchaseEvents.ts +167 -0
  64. package/src/revenuecat/revenueCatBridge.ts +221 -0
  65. package/src/revenuecat/types.ts +95 -0
  66. package/src/reviews/runtime.ts +153 -1
  67. package/src/reviews/transport.ts +21 -2
  68. package/src/reviews/useReviewGate.ts +14 -4
  69. package/src/session-analytics/lifecycle.ts +9 -2
  70. package/src/session-analytics/reportSessionStart.ts +15 -4
  71. package/src/session-analytics/useLifecycleEvents.ts +83 -27
  72. package/src/session-analytics/useSessionStart.ts +37 -1
  73. package/src/types.ts +41 -4
@@ -1085,14 +1085,21 @@ var styles7 = StyleSheet.create({
1085
1085
  });
1086
1086
 
1087
1087
  // src/coachmarks/runtime.ts
1088
- var storageSingleton = null;
1089
- var testing = false;
1090
- var getCoachmarkStorage = () => storageSingleton;
1091
- var isCoachmarkTesting = () => testing;
1088
+ var COACHMARK_RUNTIME_SLOT = /* @__PURE__ */ Symbol.for("@wireai/activation:coachmarkRuntime");
1089
+ var runtimeGlobal = globalThis;
1090
+ var coachmarkRuntime = () => {
1091
+ const existing = runtimeGlobal[COACHMARK_RUNTIME_SLOT];
1092
+ if (existing) return existing;
1093
+ const created = { storage: null, testing: false, coachmarksEnabled: true };
1094
+ runtimeGlobal[COACHMARK_RUNTIME_SLOT] = created;
1095
+ return created;
1096
+ };
1097
+ var getCoachmarkStorage = () => coachmarkRuntime().storage;
1098
+ var isCoachmarkTesting = () => coachmarkRuntime().testing;
1092
1099
  var SEEN_VALUE = "1";
1093
1100
  var hasSeenGate = (key, storageOverride, testingOverride) => {
1094
- if (testingOverride != null ? testingOverride : testing) return false;
1095
- const storage = storageOverride != null ? storageOverride : storageSingleton;
1101
+ if (testingOverride != null ? testingOverride : isCoachmarkTesting()) return false;
1102
+ const storage = storageOverride != null ? storageOverride : getCoachmarkStorage();
1096
1103
  if (!storage) return false;
1097
1104
  try {
1098
1105
  return storage.getItem(key) === SEEN_VALUE;
@@ -1101,8 +1108,8 @@ var hasSeenGate = (key, storageOverride, testingOverride) => {
1101
1108
  }
1102
1109
  };
1103
1110
  var markSeenGate = (key, storageOverride, testingOverride) => {
1104
- if (testingOverride != null ? testingOverride : testing) return;
1105
- const storage = storageOverride != null ? storageOverride : storageSingleton;
1111
+ if (testingOverride != null ? testingOverride : isCoachmarkTesting()) return;
1112
+ const storage = storageOverride != null ? storageOverride : getCoachmarkStorage();
1106
1113
  if (!storage) return;
1107
1114
  try {
1108
1115
  storage.setItem(key, SEEN_VALUE);
@@ -1284,8 +1291,32 @@ var sameDecision = (a, b) => {
1284
1291
  return a.fire === b.fire && a.reason === b.reason;
1285
1292
  };
1286
1293
 
1294
+ // src/analytics/reportClientEvent.ts
1295
+ var makeSessionId = () => `wire_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;
1296
+
1297
+ // src/analytics/currentSession.ts
1298
+ var CURRENT_SESSION_ID_SLOT = /* @__PURE__ */ Symbol.for(
1299
+ "@wireai/activation:currentSessionId"
1300
+ );
1301
+ var globalSlot = globalThis;
1302
+ var getCurrentSessionId = () => globalSlot[CURRENT_SESSION_ID_SLOT];
1303
+
1287
1304
  // src/reviews/runtime.ts
1288
1305
  var resolveStorage = (override) => override != null ? override : getCoachmarkStorage();
1306
+ var NO_STORAGE_WARNED_SLOT = /* @__PURE__ */ Symbol.for(
1307
+ "@wireai/activation:gateStorageWarned"
1308
+ );
1309
+ var gateWarnGlobal = globalThis;
1310
+ var warnMissingGateStorage = (storage, gate) => {
1311
+ if (storage) return;
1312
+ if (gateWarnGlobal[NO_STORAGE_WARNED_SLOT]) return;
1313
+ if (typeof __DEV__ === "undefined" || !__DEV__) return;
1314
+ if (typeof console === "undefined" || !console.warn) return;
1315
+ gateWarnGlobal[NO_STORAGE_WARNED_SLOT] = true;
1316
+ console.warn(
1317
+ `[wireai] the ${gate} gate has no sync storage, so its app-open counter is stuck at 1 and the fail-closed minSessions rule can never be satisfied \u2014 the gate will never fire. Mount CoachmarkProvider with a sync storage adapter at your app root, or pass \`storage\` to the gate.`
1318
+ );
1319
+ };
1289
1320
  var readInt = (storage, key) => {
1290
1321
  if (!storage) return 0;
1291
1322
  try {
@@ -1303,11 +1334,45 @@ var writeInt = (storage, key, value) => {
1303
1334
  } catch {
1304
1335
  }
1305
1336
  };
1337
+ var readStr = (storage, key) => {
1338
+ if (!storage) return void 0;
1339
+ try {
1340
+ const raw = storage.getItem(key);
1341
+ return typeof raw === "string" && raw.length > 0 ? raw : void 0;
1342
+ } catch {
1343
+ return void 0;
1344
+ }
1345
+ };
1346
+ var PROCESS_OPEN_ID_SLOT = /* @__PURE__ */ Symbol.for("@wireai/activation:processOpenId");
1347
+ var openIdGlobal = globalThis;
1348
+ var currentOpenId = () => {
1349
+ var _a;
1350
+ const existing = openIdGlobal[PROCESS_OPEN_ID_SLOT];
1351
+ if (existing) return existing;
1352
+ const resolved = (_a = getCurrentSessionId()) != null ? _a : makeSessionId();
1353
+ openIdGlobal[PROCESS_OPEN_ID_SLOT] = resolved;
1354
+ return resolved;
1355
+ };
1356
+ var bumpSessionCount = (storage, sessionsKey, openKey, openId = currentOpenId()) => {
1357
+ const lastOpen = readStr(storage, openKey);
1358
+ const stored = readInt(storage, sessionsKey);
1359
+ if (lastOpen === openId) return stored > 0 ? stored : 1;
1360
+ const next = stored + 1;
1361
+ writeInt(storage, sessionsKey, next);
1362
+ if (storage) {
1363
+ try {
1364
+ storage.setItem(openKey, openId);
1365
+ } catch {
1366
+ }
1367
+ }
1368
+ return next;
1369
+ };
1306
1370
 
1307
1371
  // src/questionnaire/runtime.ts
1308
1372
  var questionnaireSeenKey = (id, version) => version ? `wire_questionnaire_${id}_${version}_seen` : `wire_questionnaire_${id}_seen`;
1309
1373
  var questionnaireLastShownKey = (id) => `wire_questionnaire_${id}_last`;
1310
1374
  var questionnaireSessionsKey = (id) => `wire_questionnaire_${id}_sessions`;
1375
+ var questionnaireSessionOpenKey = (id) => `wire_questionnaire_${id}_open`;
1311
1376
 
1312
1377
  // src/questionnaire/useQuestionnaireGate.ts
1313
1378
  var useStableValue2 = (value, isEqual) => {
@@ -1327,18 +1392,18 @@ var useQuestionnaireGate = ({
1327
1392
  const config = useStableValue2(configProp, shallowEqual);
1328
1393
  const decision = useStableValue2(decisionProp, (a, b) => sameDecision(a, b));
1329
1394
  const featureEnabled = useResolvedFeatures({ flags: features, config: featuresConfig }).questionnaire.enabled;
1330
- const testing2 = isTesting != null ? isTesting : isCoachmarkTesting();
1395
+ const testing = isTesting != null ? isTesting : isCoachmarkTesting();
1331
1396
  const seenKey = questionnaireSeenKey(
1332
1397
  config.id,
1333
1398
  config.oncePerVersion === false ? void 0 : config.appVersion
1334
1399
  );
1335
1400
  const lastKey = questionnaireLastShownKey(config.id);
1336
1401
  const sessionsKey = questionnaireSessionsKey(config.id);
1402
+ const sessionOpenKey = questionnaireSessionOpenKey(config.id);
1337
1403
  const sessions = useState(() => {
1338
1404
  const store = resolveStorage(storage);
1339
- const next = readInt(store, sessionsKey) + 1;
1340
- writeInt(store, sessionsKey, next);
1341
- return next;
1405
+ warnMissingGateStorage(store, "questionnaire");
1406
+ return bumpSessionCount(store, sessionsKey, sessionOpenKey);
1342
1407
  })[0];
1343
1408
  const hasServerDecision = decision != null;
1344
1409
  const timeoutMs = config.timeoutFallbackMs;
@@ -1358,7 +1423,7 @@ var useQuestionnaireGate = ({
1358
1423
  visible: false,
1359
1424
  verdict: { fire: false, reason: "feature_disabled" }
1360
1425
  };
1361
- if (testing2)
1426
+ if (testing)
1362
1427
  return {
1363
1428
  visible: true,
1364
1429
  verdict: { fire: true, reason: "testing" }
@@ -1377,7 +1442,7 @@ var useQuestionnaireGate = ({
1377
1442
  return { visible: ready && resolved.fire && !alreadySeen, verdict: resolved };
1378
1443
  }, [
1379
1444
  featureEnabled,
1380
- testing2,
1445
+ testing,
1381
1446
  config,
1382
1447
  decision,
1383
1448
  events,