@wireai/activation 0.14.3 → 0.15.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.
- package/AGENTS.md +1 -1
- package/CHANGELOG.md +73 -0
- package/README.md +11 -7
- package/dist/analytics/index.d.mts +5 -5
- package/dist/analytics/index.d.ts +5 -5
- package/dist/analytics/index.js.map +1 -1
- package/dist/analytics/index.mjs.map +1 -1
- package/dist/coachmarks/index.d.mts +1 -1
- package/dist/coachmarks/index.d.ts +1 -1
- package/dist/coachmarks/index.js +47 -2
- package/dist/coachmarks/index.js.map +1 -1
- package/dist/coachmarks/index.mjs +47 -2
- package/dist/coachmarks/index.mjs.map +1 -1
- package/dist/{currentSession-CW_5Mq4O.d.ts → currentSession-CFSRZ2wg.d.ts} +10 -4
- package/dist/{currentSession-CUvTOchb.d.mts → currentSession-orZy5p1e.d.mts} +10 -4
- package/dist/{decision-Bgo17oH7.d.mts → decision-3vWLuBlO.d.ts} +11 -2
- package/dist/{decision-Bkh_LigV.d.ts → decision-yBj2AyPW.d.mts} +11 -2
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/questionnaire/index.d.mts +3 -3
- package/dist/questionnaire/index.d.ts +3 -3
- package/dist/questionnaire/index.js +48 -3
- package/dist/questionnaire/index.js.map +1 -1
- package/dist/questionnaire/index.mjs +48 -3
- package/dist/questionnaire/index.mjs.map +1 -1
- package/dist/reviews/index.d.mts +10 -6
- package/dist/reviews/index.d.ts +10 -6
- package/dist/reviews/index.js +167 -18
- package/dist/reviews/index.js.map +1 -1
- package/dist/reviews/index.mjs +167 -18
- package/dist/reviews/index.mjs.map +1 -1
- package/dist/showcase/index.d.mts +1 -1
- package/dist/showcase/index.d.ts +1 -1
- package/dist/showcase/index.js +47 -2
- package/dist/showcase/index.js.map +1 -1
- package/dist/showcase/index.mjs +47 -2
- package/dist/showcase/index.mjs.map +1 -1
- package/dist/{transport-j5gFfJhK.d.mts → transport-s5QxA-ci.d.mts} +18 -13
- package/dist/{transport-B_0SgCBe.d.ts → transport-xqqSFqxs.d.ts} +18 -13
- package/dist/{types-Cju-1_jT.d.mts → types-Byx306Kv.d.mts} +25 -10
- package/dist/{types-BcmagF6K.d.mts → types-D_0B0yay.d.mts} +7 -2
- package/dist/{types-BcmagF6K.d.ts → types-D_0B0yay.d.ts} +7 -2
- package/dist/{types-h2BZvl1t.d.ts → types-tdATL5z0.d.ts} +25 -10
- package/package.json +1 -1
- package/src/WireOnboarding.tsx +4 -1
- package/src/coachmarks/runtime.ts +103 -2
- package/src/coachmarks/types.ts +7 -2
- package/src/context/deviceId.ts +32 -0
- package/src/reviews/ReviewGate.tsx +86 -37
- package/src/reviews/decision.ts +11 -1
- package/src/reviews/idempotency.ts +71 -0
- package/src/reviews/index.ts +4 -2
- package/src/reviews/runtime.ts +5 -3
- package/src/reviews/transport.ts +17 -12
- package/src/reviews/types.ts +7 -0
- package/src/types.ts +10 -4
- package/src/utils/submitResult.ts +17 -9
package/dist/reviews/index.d.mts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import React__default from 'react';
|
|
2
|
-
import { R as ReviewGateProps, a as ReviewPresentation, U as UseReviewGateOptions, b as ReviewGateController, c as ReviewDecision, d as ReviewStoreConfig } from '../types-
|
|
3
|
-
export { e as RatingRoute, f as ReviewConfig, g as ReviewDecisionResponse, h as ReviewGateEvent, i as ReviewGateEventName, j as ReviewSubmission, k as ReviewTarget, S as SubmitResult } from '../types-
|
|
2
|
+
import { R as ReviewGateProps, a as ReviewPresentation, U as UseReviewGateOptions, b as ReviewGateController, c as ReviewDecision, d as ReviewStoreConfig } from '../types-Byx306Kv.mjs';
|
|
3
|
+
export { e as RatingRoute, f as ReviewConfig, g as ReviewDecisionResponse, h as ReviewGateEvent, i as ReviewGateEventName, j as ReviewSubmission, k as ReviewTarget, S as SubmitResult } from '../types-Byx306Kv.mjs';
|
|
4
4
|
export { C as ReviewModal, a as ReviewModalHandle, b as ReviewModalProps } from '../CenteredModal-C3qQBHsA.mjs';
|
|
5
|
-
export { G as GateRules, a as GateSignals, b as buildReviewSubmission, d as decideReview, e as evaluateGate, r as resolveRules, c as routeRating } from '../decision-
|
|
5
|
+
export { G as GateRules, a as GateSignals, b as buildReviewSubmission, d as decideReview, e as evaluateGate, r as resolveRules, c as routeRating } from '../decision-yBj2AyPW.mjs';
|
|
6
6
|
import { c as OnboardingFonts } from '../types-BKfpdZzX.mjs';
|
|
7
|
-
export { F as FetchReviewDecisionOptions, R as ReportAppEventOptions, a as ReviewSubmitResult, f as fetchReviewDecision, r as reportAppEvent, s as submitReview } from '../transport-
|
|
8
|
-
import '../types-
|
|
7
|
+
export { F as FetchReviewDecisionOptions, R as ReportAppEventOptions, a as ReviewSubmitResult, f as fetchReviewDecision, r as reportAppEvent, s as submitReview } from '../transport-s5QxA-ci.mjs';
|
|
8
|
+
import '../types-D_0B0yay.mjs';
|
|
9
9
|
import '../types-BpwiRpA8.mjs';
|
|
10
10
|
|
|
11
11
|
/**
|
|
@@ -41,7 +41,11 @@ declare const reviewSessionsKey: (id: string) => string;
|
|
|
41
41
|
*
|
|
42
42
|
* The form NEVER asks for identity (no name / email / contact field): the host already
|
|
43
43
|
* identifies the user via `sessionId` + `meta` (e.g. user_id, device_key), which is all
|
|
44
|
-
* the POST body carries alongside the rating and the free text.
|
|
44
|
+
* the POST body carries alongside the rating and the free text. Since 2026-08-19 the gate also
|
|
45
|
+
* fills in `meta.device_key` from the kit's own per-install id when the host passed none — not for
|
|
46
|
+
* identification, but because it is the unit the server scopes the idempotency key to, and without
|
|
47
|
+
* it the key is discarded. Any non-blank string the host passes still wins verbatim. See
|
|
48
|
+
* `idempotency.ts`.
|
|
45
49
|
*
|
|
46
50
|
* Motion (2026-07-16): the three phases used to swap IN PLACE with no transition. They now
|
|
47
51
|
* ride `ModalPaneHost`, the same pane-slide primitive the questionnaire steps use, and the
|
package/dist/reviews/index.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import React__default from 'react';
|
|
2
|
-
import { R as ReviewGateProps, a as ReviewPresentation, U as UseReviewGateOptions, b as ReviewGateController, c as ReviewDecision, d as ReviewStoreConfig } from '../types-
|
|
3
|
-
export { e as RatingRoute, f as ReviewConfig, g as ReviewDecisionResponse, h as ReviewGateEvent, i as ReviewGateEventName, j as ReviewSubmission, k as ReviewTarget, S as SubmitResult } from '../types-
|
|
2
|
+
import { R as ReviewGateProps, a as ReviewPresentation, U as UseReviewGateOptions, b as ReviewGateController, c as ReviewDecision, d as ReviewStoreConfig } from '../types-tdATL5z0.js';
|
|
3
|
+
export { e as RatingRoute, f as ReviewConfig, g as ReviewDecisionResponse, h as ReviewGateEvent, i as ReviewGateEventName, j as ReviewSubmission, k as ReviewTarget, S as SubmitResult } from '../types-tdATL5z0.js';
|
|
4
4
|
export { C as ReviewModal, a as ReviewModalHandle, b as ReviewModalProps } from '../CenteredModal-Cdgns6--.js';
|
|
5
|
-
export { G as GateRules, a as GateSignals, b as buildReviewSubmission, d as decideReview, e as evaluateGate, r as resolveRules, c as routeRating } from '../decision-
|
|
5
|
+
export { G as GateRules, a as GateSignals, b as buildReviewSubmission, d as decideReview, e as evaluateGate, r as resolveRules, c as routeRating } from '../decision-3vWLuBlO.js';
|
|
6
6
|
import { c as OnboardingFonts } from '../types-BKfpdZzX.js';
|
|
7
|
-
export { F as FetchReviewDecisionOptions, R as ReportAppEventOptions, a as ReviewSubmitResult, f as fetchReviewDecision, r as reportAppEvent, s as submitReview } from '../transport-
|
|
8
|
-
import '../types-
|
|
7
|
+
export { F as FetchReviewDecisionOptions, R as ReportAppEventOptions, a as ReviewSubmitResult, f as fetchReviewDecision, r as reportAppEvent, s as submitReview } from '../transport-xqqSFqxs.js';
|
|
8
|
+
import '../types-D_0B0yay.js';
|
|
9
9
|
import '../types-BpwiRpA8.js';
|
|
10
10
|
|
|
11
11
|
/**
|
|
@@ -41,7 +41,11 @@ declare const reviewSessionsKey: (id: string) => string;
|
|
|
41
41
|
*
|
|
42
42
|
* The form NEVER asks for identity (no name / email / contact field): the host already
|
|
43
43
|
* identifies the user via `sessionId` + `meta` (e.g. user_id, device_key), which is all
|
|
44
|
-
* the POST body carries alongside the rating and the free text.
|
|
44
|
+
* the POST body carries alongside the rating and the free text. Since 2026-08-19 the gate also
|
|
45
|
+
* fills in `meta.device_key` from the kit's own per-install id when the host passed none — not for
|
|
46
|
+
* identification, but because it is the unit the server scopes the idempotency key to, and without
|
|
47
|
+
* it the key is discarded. Any non-blank string the host passes still wins verbatim. See
|
|
48
|
+
* `idempotency.ts`.
|
|
45
49
|
*
|
|
46
50
|
* Motion (2026-07-16): the three phases used to swap IN PLACE with no transition. They now
|
|
47
51
|
* ride `ModalPaneHost`, the same pane-slide primitive the questionnaire steps use, and the
|
package/dist/reviews/index.js
CHANGED
|
@@ -546,6 +546,7 @@ var buildReviewSubmission = (input) => {
|
|
|
546
546
|
if (contact) body.contact = contact;
|
|
547
547
|
if (input.sessionId) body.session_id = input.sessionId;
|
|
548
548
|
if (input.source) body.source = input.source;
|
|
549
|
+
if (input.idempotencyKey) body.idempotency_key = input.idempotencyKey;
|
|
549
550
|
if (input.meta && Object.keys(input.meta).length > 0) body.meta = input.meta;
|
|
550
551
|
return body;
|
|
551
552
|
};
|
|
@@ -563,6 +564,96 @@ var feedbackInputHeights = (fonts, verticalPadding = 0) => {
|
|
|
563
564
|
};
|
|
564
565
|
};
|
|
565
566
|
|
|
567
|
+
// src/context/deviceId.ts
|
|
568
|
+
var AUTO_DEVICE_ID_PREFIX = "wdev_";
|
|
569
|
+
var deviceIdStorageKey = (appId) => `wireai:analytics:deviceKey:${appId != null ? appId : "default"}`;
|
|
570
|
+
var randomChunk = () => Math.floor(Math.random() * 4294967296).toString(36).padStart(6, "0");
|
|
571
|
+
var mintDeviceId = () => {
|
|
572
|
+
const time = Date.now().toString(36);
|
|
573
|
+
return `${AUTO_DEVICE_ID_PREFIX}${time}_${randomChunk()}${randomChunk()}`;
|
|
574
|
+
};
|
|
575
|
+
var AUTO_DEVICE_KEY_SLOT = /* @__PURE__ */ Symbol.for("@wireai/activation:autoDeviceKeys");
|
|
576
|
+
var deviceKeyGlobal = globalThis;
|
|
577
|
+
var autoDeviceKeyRegistry = () => {
|
|
578
|
+
const existing = deviceKeyGlobal[AUTO_DEVICE_KEY_SLOT];
|
|
579
|
+
if (existing) return existing;
|
|
580
|
+
const created = { keys: /* @__PURE__ */ new Map(), hydrating: /* @__PURE__ */ new Set() };
|
|
581
|
+
deviceKeyGlobal[AUTO_DEVICE_KEY_SLOT] = created;
|
|
582
|
+
return created;
|
|
583
|
+
};
|
|
584
|
+
var startHydration = (registry, appId, storage, minted) => {
|
|
585
|
+
if (!registry.pending) registry.pending = /* @__PURE__ */ new Map();
|
|
586
|
+
const existing = registry.pending.get(appId);
|
|
587
|
+
if (existing) return existing;
|
|
588
|
+
const slot = deviceIdStorageKey(appId);
|
|
589
|
+
const degraded = () => {
|
|
590
|
+
var _a;
|
|
591
|
+
return { value: (_a = registry.keys.get(appId)) != null ? _a : minted, durable: false };
|
|
592
|
+
};
|
|
593
|
+
const adopted = (value) => ({ value, durable: true });
|
|
594
|
+
let run;
|
|
595
|
+
try {
|
|
596
|
+
run = Promise.resolve(storage.getItem(slot)).then((saved) => {
|
|
597
|
+
const persisted = typeof saved === "string" && saved.trim() ? saved.trim() : void 0;
|
|
598
|
+
if (persisted) {
|
|
599
|
+
registry.keys.set(appId, persisted);
|
|
600
|
+
return adopted(persisted);
|
|
601
|
+
}
|
|
602
|
+
return Promise.resolve(storage.setItem(slot, minted)).then(
|
|
603
|
+
() => {
|
|
604
|
+
var _a;
|
|
605
|
+
return adopted((_a = registry.keys.get(appId)) != null ? _a : minted);
|
|
606
|
+
},
|
|
607
|
+
degraded
|
|
608
|
+
);
|
|
609
|
+
}).catch(degraded);
|
|
610
|
+
} catch {
|
|
611
|
+
run = Promise.resolve(degraded());
|
|
612
|
+
}
|
|
613
|
+
registry.pending.set(appId, run);
|
|
614
|
+
void run.then((outcome) => {
|
|
615
|
+
var _a;
|
|
616
|
+
if (outcome.durable) return;
|
|
617
|
+
(_a = registry.pending) == null ? void 0 : _a.delete(appId);
|
|
618
|
+
registry.hydrating.delete(appId);
|
|
619
|
+
});
|
|
620
|
+
return run;
|
|
621
|
+
};
|
|
622
|
+
var resolveAutoDeviceKey = (opts = {}) => {
|
|
623
|
+
var _a, _b;
|
|
624
|
+
const registry = autoDeviceKeyRegistry();
|
|
625
|
+
const appId = (_a = opts.appId) != null ? _a : "default";
|
|
626
|
+
let id = registry.keys.get(appId);
|
|
627
|
+
if (!id) {
|
|
628
|
+
id = mintDeviceId();
|
|
629
|
+
registry.keys.set(appId, id);
|
|
630
|
+
}
|
|
631
|
+
const storage = opts.storage;
|
|
632
|
+
if (storage && !registry.hydrating.has(appId)) {
|
|
633
|
+
registry.hydrating.add(appId);
|
|
634
|
+
void startHydration(registry, appId, storage, id);
|
|
635
|
+
}
|
|
636
|
+
return (_b = registry.keys.get(appId)) != null ? _b : id;
|
|
637
|
+
};
|
|
638
|
+
var ambientAutoDeviceKey = () => {
|
|
639
|
+
const registry = autoDeviceKeyRegistry();
|
|
640
|
+
if (registry.keys.size === 0) return resolveAutoDeviceKey();
|
|
641
|
+
if (registry.keys.size > 1) return void 0;
|
|
642
|
+
return [...registry.keys.values()][0];
|
|
643
|
+
};
|
|
644
|
+
|
|
645
|
+
// src/reviews/idempotency.ts
|
|
646
|
+
var REVIEW_IDEMPOTENCY_PREFIX = "rvw_";
|
|
647
|
+
var mintIdempotencyKey = () => `${REVIEW_IDEMPOTENCY_PREFIX}${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;
|
|
648
|
+
var hasDeviceKey = (meta) => {
|
|
649
|
+
const value = meta == null ? void 0 : meta.device_key;
|
|
650
|
+
return typeof value === "string" && value.trim().length > 0;
|
|
651
|
+
};
|
|
652
|
+
var createImpression = () => ({
|
|
653
|
+
idempotencyKey: mintIdempotencyKey(),
|
|
654
|
+
deviceKey: ambientAutoDeviceKey()
|
|
655
|
+
});
|
|
656
|
+
|
|
566
657
|
// src/motion/centeredModalMotion.ts
|
|
567
658
|
var CENTERED_MODAL_ANIM = {
|
|
568
659
|
/** Spring config for the card scale/opacity entrance (mirrors CompletionView's pop). */
|
|
@@ -901,6 +992,27 @@ var _ReviewGate = ({
|
|
|
901
992
|
const resolve = React7.useCallback(() => {
|
|
902
993
|
onResolved == null ? void 0 : onResolved();
|
|
903
994
|
}, [onResolved]);
|
|
995
|
+
const impressionRef = React7__default.default.useRef(null);
|
|
996
|
+
const buildBody = React7.useCallback(
|
|
997
|
+
(input) => {
|
|
998
|
+
let impression = impressionRef.current;
|
|
999
|
+
if (!impression) {
|
|
1000
|
+
impression = createImpression();
|
|
1001
|
+
impressionRef.current = impression;
|
|
1002
|
+
}
|
|
1003
|
+
const merged = { ...meta, ...input.extraMeta };
|
|
1004
|
+
if (!hasDeviceKey(merged) && impression.deviceKey) merged.device_key = impression.deviceKey;
|
|
1005
|
+
return buildReviewSubmission({
|
|
1006
|
+
stars: input.stars,
|
|
1007
|
+
feedbackText: input.feedbackText,
|
|
1008
|
+
suggestion: input.suggestion,
|
|
1009
|
+
sessionId,
|
|
1010
|
+
meta: merged,
|
|
1011
|
+
idempotencyKey: impression.idempotencyKey
|
|
1012
|
+
});
|
|
1013
|
+
},
|
|
1014
|
+
[meta, sessionId]
|
|
1015
|
+
);
|
|
904
1016
|
const postedRef = React7__default.default.useRef(false);
|
|
905
1017
|
const unackedRef = React7__default.default.useRef(null);
|
|
906
1018
|
const postOnce = React7.useCallback(
|
|
@@ -928,12 +1040,11 @@ var _ReviewGate = ({
|
|
|
928
1040
|
}
|
|
929
1041
|
if (postedRef.current || stars < 1) return;
|
|
930
1042
|
postOnce(
|
|
931
|
-
|
|
1043
|
+
buildBody({
|
|
932
1044
|
stars,
|
|
933
1045
|
feedbackText: feedback,
|
|
934
1046
|
suggestion,
|
|
935
|
-
|
|
936
|
-
meta: { ...meta, abandoned: true }
|
|
1047
|
+
extraMeta: { abandoned: true }
|
|
937
1048
|
})
|
|
938
1049
|
);
|
|
939
1050
|
};
|
|
@@ -958,10 +1069,9 @@ var _ReviewGate = ({
|
|
|
958
1069
|
onEvent == null ? void 0 : onEvent({ name: "store_review_requested", id, stars: value });
|
|
959
1070
|
const route = await requestStoreReview(store);
|
|
960
1071
|
postOnce(
|
|
961
|
-
|
|
1072
|
+
buildBody({
|
|
962
1073
|
stars: value,
|
|
963
|
-
|
|
964
|
-
meta: { ...meta, store_route: route }
|
|
1074
|
+
extraMeta: { store_route: route }
|
|
965
1075
|
})
|
|
966
1076
|
);
|
|
967
1077
|
setPhase("thanks");
|
|
@@ -970,24 +1080,18 @@ var _ReviewGate = ({
|
|
|
970
1080
|
setPhase("feedback");
|
|
971
1081
|
}
|
|
972
1082
|
},
|
|
973
|
-
[onEvent, id, store, postOnce,
|
|
1083
|
+
[onEvent, id, store, postOnce, buildBody, resolveWithDelay]
|
|
974
1084
|
);
|
|
975
1085
|
const feedbackReady = feedback.trim().length > 0;
|
|
976
1086
|
const sendFeedback = React7.useCallback(() => {
|
|
977
1087
|
if (!feedbackReady) return;
|
|
978
|
-
const body =
|
|
979
|
-
stars,
|
|
980
|
-
feedbackText: feedback,
|
|
981
|
-
suggestion,
|
|
982
|
-
sessionId,
|
|
983
|
-
meta
|
|
984
|
-
});
|
|
1088
|
+
const body = buildBody({ stars, feedbackText: feedback, suggestion });
|
|
985
1089
|
postOnce(body);
|
|
986
1090
|
onEvent == null ? void 0 : onEvent({ name: "review_feedback_submitted", id, stars });
|
|
987
1091
|
playHaptic("success");
|
|
988
1092
|
setPhase("thanks");
|
|
989
1093
|
resolveWithDelay();
|
|
990
|
-
}, [feedbackReady, stars, feedback, suggestion,
|
|
1094
|
+
}, [feedbackReady, stars, feedback, suggestion, buildBody, postOnce, onEvent, id, resolveWithDelay]);
|
|
991
1095
|
const dismiss = React7.useCallback(() => {
|
|
992
1096
|
setPhase("thanks");
|
|
993
1097
|
resolveWithDelay();
|
|
@@ -1134,9 +1238,54 @@ var coachmarkRuntime = () => {
|
|
|
1134
1238
|
var getCoachmarkStorage = () => coachmarkRuntime().storage;
|
|
1135
1239
|
var isCoachmarkTesting = () => coachmarkRuntime().testing;
|
|
1136
1240
|
var SEEN_VALUE = "1";
|
|
1241
|
+
var GATE_PROBE_KEY = "wire_gate_probe";
|
|
1242
|
+
var ASYNC_GATE_STORAGE_WARNED_SLOT = /* @__PURE__ */ Symbol.for(
|
|
1243
|
+
"@wireai/activation:asyncGateStorageWarned"
|
|
1244
|
+
);
|
|
1245
|
+
var asyncGateWarnGlobal = globalThis;
|
|
1246
|
+
var closedGateStorage = Object.freeze({
|
|
1247
|
+
getItem: () => SEEN_VALUE,
|
|
1248
|
+
setItem: () => {
|
|
1249
|
+
}
|
|
1250
|
+
});
|
|
1251
|
+
var syncGateAdapters = /* @__PURE__ */ new WeakSet();
|
|
1252
|
+
var asyncGateAdapters = /* @__PURE__ */ new WeakSet();
|
|
1253
|
+
var warnAsyncGateStorage = () => {
|
|
1254
|
+
if (asyncGateWarnGlobal[ASYNC_GATE_STORAGE_WARNED_SLOT]) return;
|
|
1255
|
+
if (typeof __DEV__ === "undefined" || !__DEV__) return;
|
|
1256
|
+
if (typeof console === "undefined" || !console.warn) return;
|
|
1257
|
+
asyncGateWarnGlobal[ASYNC_GATE_STORAGE_WARNED_SLOT] = true;
|
|
1258
|
+
console.warn(
|
|
1259
|
+
"[wireai] the gate storage's getItem returned a Promise \u2014 an async adapter (e.g. AsyncStorage) cannot drive the once-per-user gates, so coachmark tours, showcases and the review/questionnaire gates are all DISABLED (fail closed: nothing shows, nothing fires) until a synchronous adapter is provided. Pass a sync adapter (e.g. MMKV: `{ getItem: (k) => mmkv.getString(k) ?? null, setItem: (k, v) => mmkv.set(k, v) }`) to CoachmarkProvider or the gate's `storage` prop."
|
|
1260
|
+
);
|
|
1261
|
+
};
|
|
1262
|
+
var validateGateStorage = (storage) => {
|
|
1263
|
+
if (!storage) return null;
|
|
1264
|
+
if (syncGateAdapters.has(storage)) return storage;
|
|
1265
|
+
if (asyncGateAdapters.has(storage)) return closedGateStorage;
|
|
1266
|
+
let probed;
|
|
1267
|
+
try {
|
|
1268
|
+
probed = storage.getItem(GATE_PROBE_KEY);
|
|
1269
|
+
} catch {
|
|
1270
|
+
syncGateAdapters.add(storage);
|
|
1271
|
+
return storage;
|
|
1272
|
+
}
|
|
1273
|
+
if (probed != null && typeof probed.then === "function") {
|
|
1274
|
+
asyncGateAdapters.add(storage);
|
|
1275
|
+
try {
|
|
1276
|
+
probed.then(void 0, () => {
|
|
1277
|
+
});
|
|
1278
|
+
} catch {
|
|
1279
|
+
}
|
|
1280
|
+
warnAsyncGateStorage();
|
|
1281
|
+
return closedGateStorage;
|
|
1282
|
+
}
|
|
1283
|
+
syncGateAdapters.add(storage);
|
|
1284
|
+
return storage;
|
|
1285
|
+
};
|
|
1137
1286
|
var hasSeenGate = (key, storageOverride, testingOverride) => {
|
|
1138
1287
|
if (testingOverride != null ? testingOverride : isCoachmarkTesting()) return false;
|
|
1139
|
-
const storage = storageOverride != null ? storageOverride : getCoachmarkStorage();
|
|
1288
|
+
const storage = validateGateStorage(storageOverride != null ? storageOverride : getCoachmarkStorage());
|
|
1140
1289
|
if (!storage) return false;
|
|
1141
1290
|
try {
|
|
1142
1291
|
return storage.getItem(key) === SEEN_VALUE;
|
|
@@ -1146,7 +1295,7 @@ var hasSeenGate = (key, storageOverride, testingOverride) => {
|
|
|
1146
1295
|
};
|
|
1147
1296
|
var markSeenGate = (key, storageOverride, testingOverride) => {
|
|
1148
1297
|
if (testingOverride != null ? testingOverride : isCoachmarkTesting()) return;
|
|
1149
|
-
const storage = storageOverride != null ? storageOverride : getCoachmarkStorage();
|
|
1298
|
+
const storage = validateGateStorage(storageOverride != null ? storageOverride : getCoachmarkStorage());
|
|
1150
1299
|
if (!storage) return;
|
|
1151
1300
|
try {
|
|
1152
1301
|
storage.setItem(key, SEEN_VALUE);
|
|
@@ -1333,7 +1482,7 @@ var reviewSeenKey = (id, version) => version ? `wire_review_${id}_${version}_see
|
|
|
1333
1482
|
var reviewLastShownKey = (id) => `wire_review_${id}_last`;
|
|
1334
1483
|
var reviewSessionsKey = (id) => `wire_review_${id}_sessions`;
|
|
1335
1484
|
var reviewSessionOpenKey = (id) => `wire_review_${id}_open`;
|
|
1336
|
-
var resolveStorage = (override) => override != null ? override : getCoachmarkStorage();
|
|
1485
|
+
var resolveStorage = (override) => validateGateStorage(override != null ? override : getCoachmarkStorage());
|
|
1337
1486
|
var NO_STORAGE_WARNED_SLOT = /* @__PURE__ */ Symbol.for(
|
|
1338
1487
|
"@wireai/activation:gateStorageWarned"
|
|
1339
1488
|
);
|