@wireai/activation 0.12.0 → 0.12.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.
Files changed (53) hide show
  1. package/AGENTS.md +13 -10
  2. package/CHANGELOG.md +130 -0
  3. package/INTEGRATION_PROMPT.md +14 -3
  4. package/README.md +40 -2
  5. package/dist/analytics/index.d.mts +5 -4
  6. package/dist/analytics/index.d.ts +5 -4
  7. package/dist/analytics/index.js +39 -24
  8. package/dist/analytics/index.js.map +1 -1
  9. package/dist/analytics/index.mjs +39 -24
  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-DsSDHqor.d.mts → currentSession-BlCeDP0f.d.mts} +59 -5
  18. package/dist/{currentSession-D6RiVtc8.d.ts → currentSession-BxEB37xt.d.ts} +59 -5
  19. package/dist/index.d.mts +10 -20
  20. package/dist/index.d.ts +10 -20
  21. package/dist/index.js +301 -187
  22. package/dist/index.js.map +1 -1
  23. package/dist/index.mjs +300 -188
  24. package/dist/index.mjs.map +1 -1
  25. package/dist/questionnaire/index.js +41 -19
  26. package/dist/questionnaire/index.js.map +1 -1
  27. package/dist/questionnaire/index.mjs +41 -19
  28. package/dist/questionnaire/index.mjs.map +1 -1
  29. package/dist/reviews/index.js +41 -19
  30. package/dist/reviews/index.js.map +1 -1
  31. package/dist/reviews/index.mjs +41 -19
  32. package/dist/reviews/index.mjs.map +1 -1
  33. package/dist/showcase/index.js +15 -6
  34. package/dist/showcase/index.js.map +1 -1
  35. package/dist/showcase/index.mjs +15 -6
  36. package/dist/showcase/index.mjs.map +1 -1
  37. package/llms.txt +2 -0
  38. package/package.json +1 -1
  39. package/src/WireOnboarding.tsx +140 -5
  40. package/src/activation/wireActivation.ts +8 -1
  41. package/src/analytics/analyticsFacade.ts +15 -11
  42. package/src/analytics/reportClientEvent.ts +11 -7
  43. package/src/coachmarks/runtime.ts +53 -17
  44. package/src/config/wireConfigFromEnv.ts +46 -2
  45. package/src/context/deviceId.ts +82 -18
  46. package/src/index.ts +9 -1
  47. package/src/questionnaire/runtime.ts +1 -0
  48. package/src/questionnaire/useQuestionnaireGate.ts +8 -3
  49. package/src/reviews/runtime.ts +68 -7
  50. package/src/reviews/useReviewGate.ts +8 -3
  51. package/src/session-analytics/useLifecycleEvents.ts +57 -27
  52. package/src/session-analytics/useSessionStart.ts +37 -1
  53. package/src/types.ts +41 -4
@@ -1091,14 +1091,21 @@ var styles7 = reactNative.StyleSheet.create({
1091
1091
  });
1092
1092
 
1093
1093
  // src/coachmarks/runtime.ts
1094
- var storageSingleton = null;
1095
- var testing = false;
1096
- var getCoachmarkStorage = () => storageSingleton;
1097
- var isCoachmarkTesting = () => testing;
1094
+ var COACHMARK_RUNTIME_SLOT = /* @__PURE__ */ Symbol.for("@wireai/activation:coachmarkRuntime");
1095
+ var runtimeGlobal = globalThis;
1096
+ var coachmarkRuntime = () => {
1097
+ const existing = runtimeGlobal[COACHMARK_RUNTIME_SLOT];
1098
+ if (existing) return existing;
1099
+ const created = { storage: null, testing: false, coachmarksEnabled: true };
1100
+ runtimeGlobal[COACHMARK_RUNTIME_SLOT] = created;
1101
+ return created;
1102
+ };
1103
+ var getCoachmarkStorage = () => coachmarkRuntime().storage;
1104
+ var isCoachmarkTesting = () => coachmarkRuntime().testing;
1098
1105
  var SEEN_VALUE = "1";
1099
1106
  var hasSeenGate = (key, storageOverride, testingOverride) => {
1100
- if (testingOverride != null ? testingOverride : testing) return false;
1101
- const storage = storageOverride != null ? storageOverride : storageSingleton;
1107
+ if (testingOverride != null ? testingOverride : isCoachmarkTesting()) return false;
1108
+ const storage = storageOverride != null ? storageOverride : getCoachmarkStorage();
1102
1109
  if (!storage) return false;
1103
1110
  try {
1104
1111
  return storage.getItem(key) === SEEN_VALUE;
@@ -1107,8 +1114,8 @@ var hasSeenGate = (key, storageOverride, testingOverride) => {
1107
1114
  }
1108
1115
  };
1109
1116
  var markSeenGate = (key, storageOverride, testingOverride) => {
1110
- if (testingOverride != null ? testingOverride : testing) return;
1111
- const storage = storageOverride != null ? storageOverride : storageSingleton;
1117
+ if (testingOverride != null ? testingOverride : isCoachmarkTesting()) return;
1118
+ const storage = storageOverride != null ? storageOverride : getCoachmarkStorage();
1112
1119
  if (!storage) return;
1113
1120
  try {
1114
1121
  storage.setItem(key, SEEN_VALUE);
@@ -1302,6 +1309,20 @@ var getCurrentSessionId = () => globalSlot[CURRENT_SESSION_ID_SLOT];
1302
1309
 
1303
1310
  // src/reviews/runtime.ts
1304
1311
  var resolveStorage = (override) => override != null ? override : getCoachmarkStorage();
1312
+ var NO_STORAGE_WARNED_SLOT = /* @__PURE__ */ Symbol.for(
1313
+ "@wireai/activation:gateStorageWarned"
1314
+ );
1315
+ var gateWarnGlobal = globalThis;
1316
+ var warnMissingGateStorage = (storage, gate) => {
1317
+ if (storage) return;
1318
+ if (gateWarnGlobal[NO_STORAGE_WARNED_SLOT]) return;
1319
+ if (typeof __DEV__ === "undefined" || !__DEV__) return;
1320
+ if (typeof console === "undefined" || !console.warn) return;
1321
+ gateWarnGlobal[NO_STORAGE_WARNED_SLOT] = true;
1322
+ console.warn(
1323
+ `[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.`
1324
+ );
1325
+ };
1305
1326
  var readInt = (storage, key) => {
1306
1327
  if (!storage) return 0;
1307
1328
  try {
@@ -1331,13 +1352,12 @@ var readStr = (storage, key) => {
1331
1352
  var PROCESS_OPEN_ID_SLOT = /* @__PURE__ */ Symbol.for("@wireai/activation:processOpenId");
1332
1353
  var openIdGlobal = globalThis;
1333
1354
  var currentOpenId = () => {
1334
- const live = getCurrentSessionId();
1335
- if (live) return live;
1355
+ var _a;
1336
1356
  const existing = openIdGlobal[PROCESS_OPEN_ID_SLOT];
1337
1357
  if (existing) return existing;
1338
- const created = makeSessionId();
1339
- openIdGlobal[PROCESS_OPEN_ID_SLOT] = created;
1340
- return created;
1358
+ const resolved = (_a = getCurrentSessionId()) != null ? _a : makeSessionId();
1359
+ openIdGlobal[PROCESS_OPEN_ID_SLOT] = resolved;
1360
+ return resolved;
1341
1361
  };
1342
1362
  var bumpSessionCount = (storage, sessionsKey, openKey, openId = currentOpenId()) => {
1343
1363
  const lastOpen = readStr(storage, openKey);
@@ -1378,7 +1398,7 @@ var useQuestionnaireGate = ({
1378
1398
  const config = useStableValue2(configProp, shallowEqual);
1379
1399
  const decision = useStableValue2(decisionProp, (a, b) => sameDecision(a, b));
1380
1400
  const featureEnabled = useResolvedFeatures({ flags: features, config: featuresConfig }).questionnaire.enabled;
1381
- const testing2 = isTesting != null ? isTesting : isCoachmarkTesting();
1401
+ const testing = isTesting != null ? isTesting : isCoachmarkTesting();
1382
1402
  const seenKey = questionnaireSeenKey(
1383
1403
  config.id,
1384
1404
  config.oncePerVersion === false ? void 0 : config.appVersion
@@ -1386,9 +1406,11 @@ var useQuestionnaireGate = ({
1386
1406
  const lastKey = questionnaireLastShownKey(config.id);
1387
1407
  const sessionsKey = questionnaireSessionsKey(config.id);
1388
1408
  const sessionOpenKey = questionnaireSessionOpenKey(config.id);
1389
- const sessions = React8.useState(
1390
- () => bumpSessionCount(resolveStorage(storage), sessionsKey, sessionOpenKey)
1391
- )[0];
1409
+ const sessions = React8.useState(() => {
1410
+ const store = resolveStorage(storage);
1411
+ warnMissingGateStorage(store, "questionnaire");
1412
+ return bumpSessionCount(store, sessionsKey, sessionOpenKey);
1413
+ })[0];
1392
1414
  const hasServerDecision = decision != null;
1393
1415
  const timeoutMs = config.timeoutFallbackMs;
1394
1416
  const waits = !hasServerDecision && timeoutMs != null && timeoutMs > 0;
@@ -1407,7 +1429,7 @@ var useQuestionnaireGate = ({
1407
1429
  visible: false,
1408
1430
  verdict: { fire: false, reason: "feature_disabled" }
1409
1431
  };
1410
- if (testing2)
1432
+ if (testing)
1411
1433
  return {
1412
1434
  visible: true,
1413
1435
  verdict: { fire: true, reason: "testing" }
@@ -1426,7 +1448,7 @@ var useQuestionnaireGate = ({
1426
1448
  return { visible: ready && resolved.fire && !alreadySeen, verdict: resolved };
1427
1449
  }, [
1428
1450
  featureEnabled,
1429
- testing2,
1451
+ testing,
1430
1452
  config,
1431
1453
  decision,
1432
1454
  events,