@wireai/activation 0.10.0 → 0.12.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.
Files changed (61) hide show
  1. package/AGENTS.md +51 -0
  2. package/CHANGELOG.md +111 -1
  3. package/INTEGRATION_PROMPT.md +13 -1
  4. package/README.md +106 -4
  5. package/dist/analytics/index.d.mts +35 -6
  6. package/dist/analytics/index.d.ts +35 -6
  7. package/dist/analytics/index.js +222 -94
  8. package/dist/analytics/index.js.map +1 -1
  9. package/dist/analytics/index.mjs +214 -95
  10. package/dist/analytics/index.mjs.map +1 -1
  11. package/dist/{currentSession-D0Vq7_VE.d.ts → currentSession-D6RiVtc8.d.ts} +187 -29
  12. package/dist/{currentSession-DdDkprpM.d.mts → currentSession-DsSDHqor.d.mts} +187 -29
  13. package/dist/index.d.mts +236 -82
  14. package/dist/index.d.ts +236 -82
  15. package/dist/index.js +330 -60
  16. package/dist/index.js.map +1 -1
  17. package/dist/index.mjs +314 -61
  18. package/dist/index.mjs.map +1 -1
  19. package/dist/questionnaire/index.d.mts +1 -1
  20. package/dist/questionnaire/index.d.ts +1 -1
  21. package/dist/questionnaire/index.js +59 -8
  22. package/dist/questionnaire/index.js.map +1 -1
  23. package/dist/questionnaire/index.mjs +59 -8
  24. package/dist/questionnaire/index.mjs.map +1 -1
  25. package/dist/reviews/index.d.mts +2 -2
  26. package/dist/reviews/index.d.ts +2 -2
  27. package/dist/reviews/index.js +97 -17
  28. package/dist/reviews/index.js.map +1 -1
  29. package/dist/reviews/index.mjs +97 -17
  30. package/dist/reviews/index.mjs.map +1 -1
  31. package/dist/{transport-Bzb-bcB2.d.mts → transport-CF_eHwzC.d.mts} +15 -16
  32. package/dist/{transport-B31G0Cib.d.ts → transport-DsRe4epC.d.ts} +15 -16
  33. package/llms.txt +9 -0
  34. package/package.json +1 -1
  35. package/src/activation/useWireActivation.ts +12 -1
  36. package/src/activation/wireActivation.ts +36 -24
  37. package/src/analytics/analyticsFacade.ts +113 -29
  38. package/src/analytics/currentSession.ts +83 -0
  39. package/src/analytics/eventQueue.ts +20 -11
  40. package/src/analytics/index.ts +29 -1
  41. package/src/analytics/reportClientEvent.ts +50 -2
  42. package/src/analytics/screenTracking.ts +6 -1
  43. package/src/analytics/useAnalytics.ts +22 -1
  44. package/src/context/deviceId.ts +109 -0
  45. package/src/context/userContext.ts +73 -0
  46. package/src/identity/userIdentity.ts +10 -0
  47. package/src/index.ts +50 -2
  48. package/src/questionnaire/runtime.ts +12 -2
  49. package/src/questionnaire/transport.ts +5 -1
  50. package/src/questionnaire/useQuestionnaireGate.ts +9 -7
  51. package/src/revenuecat/index.ts +55 -0
  52. package/src/revenuecat/purchaseEvents.ts +167 -0
  53. package/src/revenuecat/revenueCatBridge.ts +221 -0
  54. package/src/revenuecat/types.ts +95 -0
  55. package/src/reviews/decision.ts +8 -1
  56. package/src/reviews/runtime.ts +92 -1
  57. package/src/reviews/transport.ts +27 -10
  58. package/src/reviews/useReviewGate.ts +12 -7
  59. package/src/session-analytics/lifecycle.ts +15 -13
  60. package/src/session-analytics/reportSessionStart.ts +15 -4
  61. package/src/session-analytics/useLifecycleEvents.ts +68 -28
@@ -698,7 +698,14 @@ var resolveRules = (config) => {
698
698
  var _a, _b, _c, _d, _e;
699
699
  return {
700
700
  enabled: (_a = config.enabled) != null ? _a : true,
701
- minSessions: (_b = config.minSessions) != null ? _b : 0,
701
+ // FAIL-CLOSED on the first session (behavior change, 0.11.0). An unconfigured host with no
702
+ // server decision must NOT prompt on the very first mount: `minSessions` defaults to 2 so the
703
+ // gate needs at least a second session before the LOCAL rules can fire. This is the client-side
704
+ // floor only — a server `decision` (from `fetchReviewDecision`) still OVERRIDES everything, and a
705
+ // host that genuinely wants first-session prompting can set `minSessions: 1` (or `0`) explicitly.
706
+ // Mirrors the 2026-07-16 incident: a first-session user, no server decision, got the prompt and
707
+ // left 1 star. See `evaluateGate` (`min_sessions` reason) and the CHANGELOG.
708
+ minSessions: (_b = config.minSessions) != null ? _b : 2,
702
709
  minEvents: (_c = config.minEvents) != null ? _c : 0,
703
710
  cooldownDays: (_d = config.cooldownDays) != null ? _d : 0,
704
711
  oncePerVersion: (_e = config.oncePerVersion) != null ? _e : true
@@ -856,7 +863,8 @@ var fetchQuestionnaireDecision = async (target, options = {}) => {
856
863
  const res = await fetch(url, { headers });
857
864
  if (!res || !res.ok) return null;
858
865
  const json = await res.json();
859
- return json != null ? json : null;
866
+ if (!json || typeof json.fire !== "boolean") return null;
867
+ return json;
860
868
  } catch {
861
869
  return null;
862
870
  }
@@ -1276,6 +1284,16 @@ var sameDecision = (a, b) => {
1276
1284
  return a.fire === b.fire && a.reason === b.reason;
1277
1285
  };
1278
1286
 
1287
+ // src/analytics/reportClientEvent.ts
1288
+ var makeSessionId = () => `wire_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;
1289
+
1290
+ // src/analytics/currentSession.ts
1291
+ var CURRENT_SESSION_ID_SLOT = /* @__PURE__ */ Symbol.for(
1292
+ "@wireai/activation:currentSessionId"
1293
+ );
1294
+ var globalSlot = globalThis;
1295
+ var getCurrentSessionId = () => globalSlot[CURRENT_SESSION_ID_SLOT];
1296
+
1279
1297
  // src/reviews/runtime.ts
1280
1298
  var resolveStorage = (override) => override != null ? override : getCoachmarkStorage();
1281
1299
  var readInt = (storage, key) => {
@@ -1295,11 +1313,46 @@ var writeInt = (storage, key, value) => {
1295
1313
  } catch {
1296
1314
  }
1297
1315
  };
1316
+ var readStr = (storage, key) => {
1317
+ if (!storage) return void 0;
1318
+ try {
1319
+ const raw = storage.getItem(key);
1320
+ return typeof raw === "string" && raw.length > 0 ? raw : void 0;
1321
+ } catch {
1322
+ return void 0;
1323
+ }
1324
+ };
1325
+ var PROCESS_OPEN_ID_SLOT = /* @__PURE__ */ Symbol.for("@wireai/activation:processOpenId");
1326
+ var openIdGlobal = globalThis;
1327
+ var currentOpenId = () => {
1328
+ const live = getCurrentSessionId();
1329
+ if (live) return live;
1330
+ const existing = openIdGlobal[PROCESS_OPEN_ID_SLOT];
1331
+ if (existing) return existing;
1332
+ const created = makeSessionId();
1333
+ openIdGlobal[PROCESS_OPEN_ID_SLOT] = created;
1334
+ return created;
1335
+ };
1336
+ var bumpSessionCount = (storage, sessionsKey, openKey, openId = currentOpenId()) => {
1337
+ const lastOpen = readStr(storage, openKey);
1338
+ const stored = readInt(storage, sessionsKey);
1339
+ if (lastOpen === openId) return stored > 0 ? stored : 1;
1340
+ const next = stored + 1;
1341
+ writeInt(storage, sessionsKey, next);
1342
+ if (storage) {
1343
+ try {
1344
+ storage.setItem(openKey, openId);
1345
+ } catch {
1346
+ }
1347
+ }
1348
+ return next;
1349
+ };
1298
1350
 
1299
1351
  // src/questionnaire/runtime.ts
1300
1352
  var questionnaireSeenKey = (id, version) => version ? `wire_questionnaire_${id}_${version}_seen` : `wire_questionnaire_${id}_seen`;
1301
1353
  var questionnaireLastShownKey = (id) => `wire_questionnaire_${id}_last`;
1302
1354
  var questionnaireSessionsKey = (id) => `wire_questionnaire_${id}_sessions`;
1355
+ var questionnaireSessionOpenKey = (id) => `wire_questionnaire_${id}_open`;
1303
1356
 
1304
1357
  // src/questionnaire/useQuestionnaireGate.ts
1305
1358
  var useStableValue2 = (value, isEqual) => {
@@ -1326,12 +1379,10 @@ var useQuestionnaireGate = ({
1326
1379
  );
1327
1380
  const lastKey = questionnaireLastShownKey(config.id);
1328
1381
  const sessionsKey = questionnaireSessionsKey(config.id);
1329
- const sessions = useState(() => {
1330
- const store = resolveStorage(storage);
1331
- const next = readInt(store, sessionsKey) + 1;
1332
- writeInt(store, sessionsKey, next);
1333
- return next;
1334
- })[0];
1382
+ const sessionOpenKey = questionnaireSessionOpenKey(config.id);
1383
+ const sessions = useState(
1384
+ () => bumpSessionCount(resolveStorage(storage), sessionsKey, sessionOpenKey)
1385
+ )[0];
1335
1386
  const hasServerDecision = decision != null;
1336
1387
  const timeoutMs = config.timeoutFallbackMs;
1337
1388
  const waits = !hasServerDecision && timeoutMs != null && timeoutMs > 0;