@wireai/activation 0.14.2 → 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 +144 -0
- package/README.md +23 -9
- 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 +13 -5
- package/dist/coachmarks/index.d.ts +13 -5
- package/dist/coachmarks/index.js +252 -58
- package/dist/coachmarks/index.js.map +1 -1
- package/dist/coachmarks/index.mjs +204 -9
- 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 +282 -48
- package/dist/showcase/index.js.map +1 -1
- package/dist/showcase/index.mjs +248 -12
- 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/metro/index.js +16 -5
- package/package.json +1 -1
- package/src/WireOnboarding.tsx +4 -1
- package/src/coachmarks/GestureHint.tsx +16 -7
- package/src/coachmarks/SpotlightOverlay.tsx +19 -13
- package/src/coachmarks/index.ts +7 -2
- package/src/coachmarks/reanimated.ts +342 -0
- 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/showcase/FeatureShowcase.tsx +25 -9
- package/src/showcase/blazejOnboarding.ts +136 -0
- package/src/showcase/index.ts +8 -4
- package/src/types.ts +10 -4
- package/src/utils/submitResult.ts +17 -9
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import React3, { createContext, useEffect, useMemo, useContext, useSyncExternalStore,
|
|
1
|
+
import React3, { createContext, forwardRef, createElement, useEffect, useMemo, useContext, useSyncExternalStore, useState, useReducer, useRef, useCallback } from 'react';
|
|
2
2
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
3
|
-
import {
|
|
4
|
-
import Animated, { useSharedValue, useReducedMotion, withRepeat, withSequence, withTiming, withDelay, useAnimatedStyle, useAnimatedProps, FadeOut, FadeIn } from 'react-native-reanimated';
|
|
3
|
+
import { View, StyleSheet, useWindowDimensions, Pressable, Text, AccessibilityInfo } from 'react-native';
|
|
5
4
|
|
|
6
5
|
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
7
6
|
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
@@ -87,8 +86,8 @@ var DEFAULT_TIMEOUT_MS = 4e3;
|
|
|
87
86
|
var failOpen = async (storage, key) => {
|
|
88
87
|
var _a;
|
|
89
88
|
if (!storage) return defaultWireFeatures;
|
|
90
|
-
const
|
|
91
|
-
return (_a =
|
|
89
|
+
const cached3 = await readCachedFeatures(storage, key);
|
|
90
|
+
return (_a = cached3 == null ? void 0 : cached3.features) != null ? _a : defaultWireFeatures;
|
|
92
91
|
};
|
|
93
92
|
var fetchWithTimeout = async (url, apiKey, timeoutMs) => {
|
|
94
93
|
const controller = typeof AbortController !== "undefined" ? new AbortController() : void 0;
|
|
@@ -214,9 +213,54 @@ var isCoachmarkTesting = () => coachmarkRuntime().testing;
|
|
|
214
213
|
var coachmarkGateKey = (tourId) => `wire_coachmark_${tourId}_seen`;
|
|
215
214
|
var showcaseGateKey = (showcaseId) => `wire_showcase_${showcaseId}_seen`;
|
|
216
215
|
var SEEN_VALUE = "1";
|
|
216
|
+
var GATE_PROBE_KEY = "wire_gate_probe";
|
|
217
|
+
var ASYNC_GATE_STORAGE_WARNED_SLOT = /* @__PURE__ */ Symbol.for(
|
|
218
|
+
"@wireai/activation:asyncGateStorageWarned"
|
|
219
|
+
);
|
|
220
|
+
var asyncGateWarnGlobal = globalThis;
|
|
221
|
+
var closedGateStorage = Object.freeze({
|
|
222
|
+
getItem: () => SEEN_VALUE,
|
|
223
|
+
setItem: () => {
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
var syncGateAdapters = /* @__PURE__ */ new WeakSet();
|
|
227
|
+
var asyncGateAdapters = /* @__PURE__ */ new WeakSet();
|
|
228
|
+
var warnAsyncGateStorage = () => {
|
|
229
|
+
if (asyncGateWarnGlobal[ASYNC_GATE_STORAGE_WARNED_SLOT]) return;
|
|
230
|
+
if (typeof __DEV__ === "undefined" || !__DEV__) return;
|
|
231
|
+
if (typeof console === "undefined" || !console.warn) return;
|
|
232
|
+
asyncGateWarnGlobal[ASYNC_GATE_STORAGE_WARNED_SLOT] = true;
|
|
233
|
+
console.warn(
|
|
234
|
+
"[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."
|
|
235
|
+
);
|
|
236
|
+
};
|
|
237
|
+
var validateGateStorage = (storage) => {
|
|
238
|
+
if (!storage) return null;
|
|
239
|
+
if (syncGateAdapters.has(storage)) return storage;
|
|
240
|
+
if (asyncGateAdapters.has(storage)) return closedGateStorage;
|
|
241
|
+
let probed;
|
|
242
|
+
try {
|
|
243
|
+
probed = storage.getItem(GATE_PROBE_KEY);
|
|
244
|
+
} catch {
|
|
245
|
+
syncGateAdapters.add(storage);
|
|
246
|
+
return storage;
|
|
247
|
+
}
|
|
248
|
+
if (probed != null && typeof probed.then === "function") {
|
|
249
|
+
asyncGateAdapters.add(storage);
|
|
250
|
+
try {
|
|
251
|
+
probed.then(void 0, () => {
|
|
252
|
+
});
|
|
253
|
+
} catch {
|
|
254
|
+
}
|
|
255
|
+
warnAsyncGateStorage();
|
|
256
|
+
return closedGateStorage;
|
|
257
|
+
}
|
|
258
|
+
syncGateAdapters.add(storage);
|
|
259
|
+
return storage;
|
|
260
|
+
};
|
|
217
261
|
var hasSeenGate = (key, storageOverride, testingOverride) => {
|
|
218
262
|
if (testingOverride != null ? testingOverride : isCoachmarkTesting()) return false;
|
|
219
|
-
const storage = storageOverride != null ? storageOverride : getCoachmarkStorage();
|
|
263
|
+
const storage = validateGateStorage(storageOverride != null ? storageOverride : getCoachmarkStorage());
|
|
220
264
|
if (!storage) return false;
|
|
221
265
|
try {
|
|
222
266
|
return storage.getItem(key) === SEEN_VALUE;
|
|
@@ -226,7 +270,7 @@ var hasSeenGate = (key, storageOverride, testingOverride) => {
|
|
|
226
270
|
};
|
|
227
271
|
var markSeenGate = (key, storageOverride, testingOverride) => {
|
|
228
272
|
if (testingOverride != null ? testingOverride : isCoachmarkTesting()) return;
|
|
229
|
-
const storage = storageOverride != null ? storageOverride : getCoachmarkStorage();
|
|
273
|
+
const storage = validateGateStorage(storageOverride != null ? storageOverride : getCoachmarkStorage());
|
|
230
274
|
if (!storage) return;
|
|
231
275
|
try {
|
|
232
276
|
storage.setItem(key, SEEN_VALUE);
|
|
@@ -367,6 +411,157 @@ var resolveBlurView = (requireModule = runtimeRequire) => {
|
|
|
367
411
|
return void 0;
|
|
368
412
|
}
|
|
369
413
|
};
|
|
414
|
+
var lastKnown = false;
|
|
415
|
+
var useReducedMotion = () => {
|
|
416
|
+
const [reduced, setReduced] = useState(lastKnown);
|
|
417
|
+
useEffect(() => {
|
|
418
|
+
let mounted = true;
|
|
419
|
+
AccessibilityInfo.isReduceMotionEnabled().then((value) => {
|
|
420
|
+
lastKnown = value;
|
|
421
|
+
if (mounted) setReduced(value);
|
|
422
|
+
}).catch(() => {
|
|
423
|
+
});
|
|
424
|
+
const sub = AccessibilityInfo.addEventListener("reduceMotionChanged", (value) => {
|
|
425
|
+
lastKnown = value;
|
|
426
|
+
setReduced(value);
|
|
427
|
+
});
|
|
428
|
+
return () => {
|
|
429
|
+
mounted = false;
|
|
430
|
+
sub == null ? void 0 : sub.remove();
|
|
431
|
+
};
|
|
432
|
+
}, []);
|
|
433
|
+
return reduced;
|
|
434
|
+
};
|
|
435
|
+
|
|
436
|
+
// src/coachmarks/reanimated.ts
|
|
437
|
+
var runtimeRequire2 = (moduleName) => {
|
|
438
|
+
if (moduleName !== "react-native-reanimated") return void 0;
|
|
439
|
+
if (typeof __require !== "function") return void 0;
|
|
440
|
+
try {
|
|
441
|
+
return __require("react-native-reanimated");
|
|
442
|
+
} catch {
|
|
443
|
+
return void 0;
|
|
444
|
+
}
|
|
445
|
+
};
|
|
446
|
+
var useStaticSharedValue = (initial) => {
|
|
447
|
+
const [, bump] = useReducer((n) => n + 1, 0);
|
|
448
|
+
const box = useRef(null);
|
|
449
|
+
if (box.current === null) {
|
|
450
|
+
let current2 = initial;
|
|
451
|
+
box.current = {
|
|
452
|
+
get value() {
|
|
453
|
+
return current2;
|
|
454
|
+
},
|
|
455
|
+
set value(next) {
|
|
456
|
+
if (Object.is(next, current2)) return;
|
|
457
|
+
current2 = next;
|
|
458
|
+
bump();
|
|
459
|
+
}
|
|
460
|
+
};
|
|
461
|
+
}
|
|
462
|
+
return box.current;
|
|
463
|
+
};
|
|
464
|
+
var runWorklet = (factory, fallback) => {
|
|
465
|
+
var _a;
|
|
466
|
+
try {
|
|
467
|
+
return (_a = factory()) != null ? _a : fallback;
|
|
468
|
+
} catch {
|
|
469
|
+
return fallback;
|
|
470
|
+
}
|
|
471
|
+
};
|
|
472
|
+
var StaticAnimatedView = forwardRef(function StaticAnimatedView2({ entering: _entering, exiting: _exiting, children, ...rest }, ref) {
|
|
473
|
+
return createElement(View, { ...rest, ref }, children);
|
|
474
|
+
});
|
|
475
|
+
var staticCreateAnimatedComponent = (component) => function StaticAnimatedComponent({ animatedProps, ...rest }) {
|
|
476
|
+
return createElement(component, { ...rest, ...animatedProps });
|
|
477
|
+
};
|
|
478
|
+
var staticApi = {
|
|
479
|
+
present: false,
|
|
480
|
+
View: StaticAnimatedView,
|
|
481
|
+
createAnimatedComponent: staticCreateAnimatedComponent,
|
|
482
|
+
useSharedValue: useStaticSharedValue,
|
|
483
|
+
useAnimatedStyle: (factory) => runWorklet(factory, {}),
|
|
484
|
+
useAnimatedProps: (factory) => runWorklet(factory, {}),
|
|
485
|
+
useReducedMotion,
|
|
486
|
+
withTiming: (toValue) => toValue,
|
|
487
|
+
withRepeat: (animation) => animation,
|
|
488
|
+
withSequence: (...animations) => {
|
|
489
|
+
var _a;
|
|
490
|
+
return (_a = animations[animations.length - 1]) != null ? _a : 0;
|
|
491
|
+
},
|
|
492
|
+
withDelay: (_ms, animation) => animation,
|
|
493
|
+
fadeIn: () => void 0,
|
|
494
|
+
fadeOut: () => void 0
|
|
495
|
+
};
|
|
496
|
+
var isFunction = (value) => typeof value === "function";
|
|
497
|
+
var isComponent = (value) => typeof value === "function" || !!value && typeof value === "object" && "$$typeof" in value;
|
|
498
|
+
var fromModule = (mod) => {
|
|
499
|
+
var _a, _b;
|
|
500
|
+
if (!mod || typeof mod !== "object") return void 0;
|
|
501
|
+
const ns = mod;
|
|
502
|
+
const def = ns.default && typeof ns.default === "object" ? ns.default : void 0;
|
|
503
|
+
const pick = (name) => {
|
|
504
|
+
var _a2;
|
|
505
|
+
return (_a2 = ns[name]) != null ? _a2 : def == null ? void 0 : def[name];
|
|
506
|
+
};
|
|
507
|
+
const view = (_a = def == null ? void 0 : def.View) != null ? _a : ns.View;
|
|
508
|
+
const createAnimated = (_b = def == null ? void 0 : def.createAnimatedComponent) != null ? _b : ns.createAnimatedComponent;
|
|
509
|
+
const hooks = {
|
|
510
|
+
useSharedValue: pick("useSharedValue"),
|
|
511
|
+
useAnimatedStyle: pick("useAnimatedStyle"),
|
|
512
|
+
useAnimatedProps: pick("useAnimatedProps"),
|
|
513
|
+
useReducedMotion: pick("useReducedMotion"),
|
|
514
|
+
withTiming: pick("withTiming"),
|
|
515
|
+
withRepeat: pick("withRepeat"),
|
|
516
|
+
withSequence: pick("withSequence"),
|
|
517
|
+
withDelay: pick("withDelay")
|
|
518
|
+
};
|
|
519
|
+
const fadeIn = pick("FadeIn");
|
|
520
|
+
const fadeOut = pick("FadeOut");
|
|
521
|
+
if (!isComponent(view) || !isFunction(createAnimated)) return void 0;
|
|
522
|
+
if (Object.values(hooks).some((member) => !isFunction(member))) return void 0;
|
|
523
|
+
if (!fadeIn || !fadeOut) return void 0;
|
|
524
|
+
const api2 = {
|
|
525
|
+
present: true,
|
|
526
|
+
View: view,
|
|
527
|
+
createAnimatedComponent: createAnimated,
|
|
528
|
+
...hooks,
|
|
529
|
+
fadeIn: (durationMs) => fadeIn.duration(durationMs),
|
|
530
|
+
fadeOut: (durationMs) => fadeOut.duration(durationMs)
|
|
531
|
+
};
|
|
532
|
+
return api2;
|
|
533
|
+
};
|
|
534
|
+
var cached2;
|
|
535
|
+
var resolveReanimated = (requireModule = runtimeRequire2) => {
|
|
536
|
+
var _a;
|
|
537
|
+
try {
|
|
538
|
+
if (cached2 === void 0 || requireModule !== runtimeRequire2) {
|
|
539
|
+
const resolved = (_a = fromModule(requireModule("react-native-reanimated"))) != null ? _a : staticApi;
|
|
540
|
+
if (requireModule === runtimeRequire2) cached2 = resolved;
|
|
541
|
+
return resolved;
|
|
542
|
+
}
|
|
543
|
+
return cached2;
|
|
544
|
+
} catch {
|
|
545
|
+
return staticApi;
|
|
546
|
+
}
|
|
547
|
+
};
|
|
548
|
+
var api = () => resolveReanimated();
|
|
549
|
+
var Animated = {
|
|
550
|
+
get View() {
|
|
551
|
+
return api().View;
|
|
552
|
+
},
|
|
553
|
+
createAnimatedComponent: (component) => api().createAnimatedComponent(component)
|
|
554
|
+
};
|
|
555
|
+
var FadeIn = { duration: (durationMs) => api().fadeIn(durationMs) };
|
|
556
|
+
var FadeOut = { duration: (durationMs) => api().fadeOut(durationMs) };
|
|
557
|
+
var useSharedValue = (initial) => api().useSharedValue(initial);
|
|
558
|
+
var useAnimatedStyle = (factory) => api().useAnimatedStyle(factory);
|
|
559
|
+
var useAnimatedProps = (factory) => api().useAnimatedProps(factory);
|
|
560
|
+
var useReducedMotion2 = () => api().useReducedMotion();
|
|
561
|
+
var withTiming = (toValue, config) => api().withTiming(toValue, config);
|
|
562
|
+
var withRepeat = (animation, count, reverse) => api().withRepeat(animation, count, reverse);
|
|
563
|
+
var withSequence = (...animations) => api().withSequence(...animations);
|
|
564
|
+
var withDelay = (ms, animation) => api().withDelay(ms, animation);
|
|
370
565
|
var SWIPE_MS = 700;
|
|
371
566
|
var TAP_MS = 320;
|
|
372
567
|
var SPREAD_MS = 620;
|
|
@@ -428,7 +623,7 @@ var GestureHintComponent = ({
|
|
|
428
623
|
const opacity = useSharedValue(1);
|
|
429
624
|
const pulse = useSharedValue(1);
|
|
430
625
|
const spread = useSharedValue(0);
|
|
431
|
-
const reduced =
|
|
626
|
+
const reduced = useReducedMotion2();
|
|
432
627
|
const isSwipe = type === "swipe_up" || type === "swipe_down" || type === "swipe_left" || type === "swipe_right";
|
|
433
628
|
const isSpread = type === "pinch" || type === "zoom";
|
|
434
629
|
const isTap = type === "tap" || type === "double_tap";
|
|
@@ -598,7 +793,7 @@ var SpotlightOverlayComponent = ({
|
|
|
598
793
|
accentTextColor
|
|
599
794
|
}) => {
|
|
600
795
|
const { height: screenH } = useWindowDimensions();
|
|
601
|
-
const reduced =
|
|
796
|
+
const reduced = useReducedMotion2();
|
|
602
797
|
const theme = useOnboardingTheme();
|
|
603
798
|
const accent = accentColor != null ? accentColor : theme.colors.primary;
|
|
604
799
|
const accentText = accentTextColor != null ? accentTextColor : theme.colors.onPrimary;
|