@wireai/activation 0.11.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 (58) hide show
  1. package/AGENTS.md +51 -0
  2. package/CHANGELOG.md +58 -3
  3. package/INTEGRATION_PROMPT.md +13 -1
  4. package/README.md +73 -0
  5. package/dist/analytics/index.d.mts +17 -6
  6. package/dist/analytics/index.d.ts +17 -6
  7. package/dist/analytics/index.js +130 -35
  8. package/dist/analytics/index.js.map +1 -1
  9. package/dist/analytics/index.mjs +126 -36
  10. package/dist/analytics/index.mjs.map +1 -1
  11. package/dist/{currentSession-DdnUq2HQ.d.ts → currentSession-D6RiVtc8.d.ts} +88 -30
  12. package/dist/{currentSession-C0_odnIW.d.mts → currentSession-DsSDHqor.d.mts} +88 -30
  13. package/dist/index.d.mts +236 -36
  14. package/dist/index.d.ts +236 -36
  15. package/dist/index.js +281 -20
  16. package/dist/index.js.map +1 -1
  17. package/dist/index.mjs +269 -21
  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 +49 -6
  22. package/dist/questionnaire/index.js.map +1 -1
  23. package/dist/questionnaire/index.mjs +49 -6
  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 +73 -8
  28. package/dist/reviews/index.js.map +1 -1
  29. package/dist/reviews/index.mjs +73 -8
  30. package/dist/reviews/index.mjs.map +1 -1
  31. package/dist/{transport-BGW9uXZJ.d.mts → transport-CF_eHwzC.d.mts} +15 -1
  32. package/dist/{transport-jUJd5kxu.d.ts → transport-DsRe4epC.d.ts} +15 -1
  33. package/llms.txt +1 -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 +41 -20
  38. package/src/analytics/currentSession.ts +83 -0
  39. package/src/analytics/eventQueue.ts +9 -1
  40. package/src/analytics/index.ts +20 -1
  41. package/src/analytics/reportClientEvent.ts +38 -0
  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 +18 -0
  46. package/src/index.ts +45 -1
  47. package/src/questionnaire/runtime.ts +12 -2
  48. package/src/questionnaire/useQuestionnaireGate.ts +9 -7
  49. package/src/revenuecat/index.ts +55 -0
  50. package/src/revenuecat/purchaseEvents.ts +167 -0
  51. package/src/revenuecat/revenueCatBridge.ts +221 -0
  52. package/src/revenuecat/types.ts +95 -0
  53. package/src/reviews/runtime.ts +92 -1
  54. package/src/reviews/transport.ts +21 -2
  55. package/src/reviews/useReviewGate.ts +12 -7
  56. package/src/session-analytics/lifecycle.ts +9 -2
  57. package/src/session-analytics/reportSessionStart.ts +15 -4
  58. package/src/session-analytics/useLifecycleEvents.ts +28 -2
@@ -730,6 +730,7 @@ var requestStoreReview = async (store) => {
730
730
  };
731
731
 
732
732
  // src/analytics/reportClientEvent.ts
733
+ var makeSessionId = () => `wire_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;
733
734
  var buildEventsRequest = (target, events) => {
734
735
  if (!(target == null ? void 0 : target.serverUrl) || events.length === 0) return null;
735
736
  try {
@@ -742,6 +743,35 @@ var buildEventsRequest = (target, events) => {
742
743
  }
743
744
  };
744
745
 
746
+ // src/analytics/currentSession.ts
747
+ var CURRENT_SESSION_ID_SLOT = /* @__PURE__ */ Symbol.for(
748
+ "@wireai/activation:currentSessionId"
749
+ );
750
+ var globalSlot = globalThis;
751
+ var getCurrentSessionId = () => globalSlot[CURRENT_SESSION_ID_SLOT];
752
+ var warnInDev = (message) => {
753
+ if (typeof __DEV__ !== "undefined" && __DEV__ && typeof console !== "undefined" && console.warn) {
754
+ console.warn(message);
755
+ return true;
756
+ }
757
+ return false;
758
+ };
759
+ 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.";
760
+ var MINT_WARNED_SLOT = /* @__PURE__ */ Symbol.for(
761
+ "@wireai/activation:currentSessionIdMintWarned"
762
+ );
763
+ var warnSlot = globalThis;
764
+ var ensureCurrentSessionId = () => {
765
+ const existing = globalSlot[CURRENT_SESSION_ID_SLOT];
766
+ if (typeof existing === "string" && existing.length > 0) return existing;
767
+ const minted = makeSessionId();
768
+ globalSlot[CURRENT_SESSION_ID_SLOT] = minted;
769
+ if (!warnSlot[MINT_WARNED_SLOT] && warnInDev(MINT_WARNING)) {
770
+ warnSlot[MINT_WARNED_SLOT] = true;
771
+ }
772
+ return minted;
773
+ };
774
+
745
775
  // src/reviews/transport.ts
746
776
  var submitReview = (target, review) => {
747
777
  if (!(target == null ? void 0 : target.serverUrl)) return;
@@ -779,13 +809,15 @@ var fetchReviewDecision = async (target, options = {}) => {
779
809
  }
780
810
  };
781
811
  var reportAppEvent = (target, name, options = {}) => {
812
+ var _a;
782
813
  if (!(target == null ? void 0 : target.serverUrl) || !name) return;
783
814
  try {
815
+ const supplied = (_a = options.sessionId) != null ? _a : "";
784
816
  const event = {
785
817
  event_type: "app_event",
786
- question_key: name
818
+ question_key: name,
819
+ session_id: supplied.trim().length > 0 ? supplied : ensureCurrentSessionId()
787
820
  };
788
- if (options.sessionId) event.session_id = options.sessionId;
789
821
  if (options.deviceKey) event.user_context = { device_key: options.deviceKey };
790
822
  if (options.meta && Object.keys(options.meta).length > 0) {
791
823
  event.meta = JSON.stringify(options.meta);
@@ -1252,6 +1284,7 @@ var sameDecision = (a, b) => {
1252
1284
  var reviewSeenKey = (id, version) => version ? `wire_review_${id}_${version}_seen` : `wire_review_${id}_seen`;
1253
1285
  var reviewLastShownKey = (id) => `wire_review_${id}_last`;
1254
1286
  var reviewSessionsKey = (id) => `wire_review_${id}_sessions`;
1287
+ var reviewSessionOpenKey = (id) => `wire_review_${id}_open`;
1255
1288
  var resolveStorage = (override) => override != null ? override : getCoachmarkStorage();
1256
1289
  var readInt = (storage, key) => {
1257
1290
  if (!storage) return 0;
@@ -1270,6 +1303,40 @@ var writeInt = (storage, key, value) => {
1270
1303
  } catch {
1271
1304
  }
1272
1305
  };
1306
+ var readStr = (storage, key) => {
1307
+ if (!storage) return void 0;
1308
+ try {
1309
+ const raw = storage.getItem(key);
1310
+ return typeof raw === "string" && raw.length > 0 ? raw : void 0;
1311
+ } catch {
1312
+ return void 0;
1313
+ }
1314
+ };
1315
+ var PROCESS_OPEN_ID_SLOT = /* @__PURE__ */ Symbol.for("@wireai/activation:processOpenId");
1316
+ var openIdGlobal = globalThis;
1317
+ var currentOpenId = () => {
1318
+ const live = getCurrentSessionId();
1319
+ if (live) return live;
1320
+ const existing = openIdGlobal[PROCESS_OPEN_ID_SLOT];
1321
+ if (existing) return existing;
1322
+ const created = makeSessionId();
1323
+ openIdGlobal[PROCESS_OPEN_ID_SLOT] = created;
1324
+ return created;
1325
+ };
1326
+ var bumpSessionCount = (storage, sessionsKey, openKey, openId = currentOpenId()) => {
1327
+ const lastOpen = readStr(storage, openKey);
1328
+ const stored = readInt(storage, sessionsKey);
1329
+ if (lastOpen === openId) return stored > 0 ? stored : 1;
1330
+ const next = stored + 1;
1331
+ writeInt(storage, sessionsKey, next);
1332
+ if (storage) {
1333
+ try {
1334
+ storage.setItem(openKey, openId);
1335
+ } catch {
1336
+ }
1337
+ }
1338
+ return next;
1339
+ };
1273
1340
 
1274
1341
  // src/reviews/useReviewGate.ts
1275
1342
  var useStableValue2 = (value, isEqual) => {
@@ -1296,12 +1363,10 @@ var useReviewGate = ({
1296
1363
  const seenKey = reviewSeenKey(config.id, config.oncePerVersion === false ? void 0 : config.appVersion);
1297
1364
  const lastKey = reviewLastShownKey(config.id);
1298
1365
  const sessionsKey = reviewSessionsKey(config.id);
1299
- const sessions = useState(() => {
1300
- const store = resolveStorage(storage);
1301
- const next = readInt(store, sessionsKey) + 1;
1302
- writeInt(store, sessionsKey, next);
1303
- return next;
1304
- })[0];
1366
+ const sessionOpenKey = reviewSessionOpenKey(config.id);
1367
+ const sessions = useState(
1368
+ () => bumpSessionCount(resolveStorage(storage), sessionsKey, sessionOpenKey)
1369
+ )[0];
1305
1370
  const hasServerDecision = decision != null;
1306
1371
  const timeoutMs = config.timeoutFallbackMs;
1307
1372
  const waits = !hasServerDecision && timeoutMs != null && timeoutMs > 0;