@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
@@ -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);
@@ -1296,6 +1303,20 @@ var getCurrentSessionId = () => globalSlot[CURRENT_SESSION_ID_SLOT];
1296
1303
 
1297
1304
  // src/reviews/runtime.ts
1298
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
+ };
1299
1320
  var readInt = (storage, key) => {
1300
1321
  if (!storage) return 0;
1301
1322
  try {
@@ -1325,13 +1346,12 @@ var readStr = (storage, key) => {
1325
1346
  var PROCESS_OPEN_ID_SLOT = /* @__PURE__ */ Symbol.for("@wireai/activation:processOpenId");
1326
1347
  var openIdGlobal = globalThis;
1327
1348
  var currentOpenId = () => {
1328
- const live = getCurrentSessionId();
1329
- if (live) return live;
1349
+ var _a;
1330
1350
  const existing = openIdGlobal[PROCESS_OPEN_ID_SLOT];
1331
1351
  if (existing) return existing;
1332
- const created = makeSessionId();
1333
- openIdGlobal[PROCESS_OPEN_ID_SLOT] = created;
1334
- return created;
1352
+ const resolved = (_a = getCurrentSessionId()) != null ? _a : makeSessionId();
1353
+ openIdGlobal[PROCESS_OPEN_ID_SLOT] = resolved;
1354
+ return resolved;
1335
1355
  };
1336
1356
  var bumpSessionCount = (storage, sessionsKey, openKey, openId = currentOpenId()) => {
1337
1357
  const lastOpen = readStr(storage, openKey);
@@ -1372,7 +1392,7 @@ var useQuestionnaireGate = ({
1372
1392
  const config = useStableValue2(configProp, shallowEqual);
1373
1393
  const decision = useStableValue2(decisionProp, (a, b) => sameDecision(a, b));
1374
1394
  const featureEnabled = useResolvedFeatures({ flags: features, config: featuresConfig }).questionnaire.enabled;
1375
- const testing2 = isTesting != null ? isTesting : isCoachmarkTesting();
1395
+ const testing = isTesting != null ? isTesting : isCoachmarkTesting();
1376
1396
  const seenKey = questionnaireSeenKey(
1377
1397
  config.id,
1378
1398
  config.oncePerVersion === false ? void 0 : config.appVersion
@@ -1380,9 +1400,11 @@ var useQuestionnaireGate = ({
1380
1400
  const lastKey = questionnaireLastShownKey(config.id);
1381
1401
  const sessionsKey = questionnaireSessionsKey(config.id);
1382
1402
  const sessionOpenKey = questionnaireSessionOpenKey(config.id);
1383
- const sessions = useState(
1384
- () => bumpSessionCount(resolveStorage(storage), sessionsKey, sessionOpenKey)
1385
- )[0];
1403
+ const sessions = useState(() => {
1404
+ const store = resolveStorage(storage);
1405
+ warnMissingGateStorage(store, "questionnaire");
1406
+ return bumpSessionCount(store, sessionsKey, sessionOpenKey);
1407
+ })[0];
1386
1408
  const hasServerDecision = decision != null;
1387
1409
  const timeoutMs = config.timeoutFallbackMs;
1388
1410
  const waits = !hasServerDecision && timeoutMs != null && timeoutMs > 0;
@@ -1401,7 +1423,7 @@ var useQuestionnaireGate = ({
1401
1423
  visible: false,
1402
1424
  verdict: { fire: false, reason: "feature_disabled" }
1403
1425
  };
1404
- if (testing2)
1426
+ if (testing)
1405
1427
  return {
1406
1428
  visible: true,
1407
1429
  verdict: { fire: true, reason: "testing" }
@@ -1420,7 +1442,7 @@ var useQuestionnaireGate = ({
1420
1442
  return { visible: ready && resolved.fire && !alreadySeen, verdict: resolved };
1421
1443
  }, [
1422
1444
  featureEnabled,
1423
- testing2,
1445
+ testing,
1424
1446
  config,
1425
1447
  decision,
1426
1448
  events,