@wireai/activation 0.14.1 → 0.14.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.
- package/CHANGELOG.md +26 -0
- package/dist/coachmarks/index.js +69 -6
- package/dist/coachmarks/index.js.map +1 -1
- package/dist/coachmarks/index.mjs +69 -6
- package/dist/coachmarks/index.mjs.map +1 -1
- package/metro/index.js +3 -1
- package/package.json +1 -1
- package/src/coachmarks/SpotlightOverlay.tsx +38 -11
- package/src/coachmarks/expoBlur.ts +135 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,32 @@
|
|
|
3
3
|
All notable changes to `@wireai/activation` (formerly `wireai-onboarding`).
|
|
4
4
|
Historical entries below the rename keep the old package name on purpose.
|
|
5
5
|
|
|
6
|
+
## [0.14.2] - 2026-08-18
|
|
7
|
+
|
|
8
|
+
**PATCH: no public surface gained, lost or renamed a member.** `SpotlightOverlay` keeps its props
|
|
9
|
+
and its export; `expo-blur` stays an OPTIONAL peer.
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- **The coachmarks subpath no longer force-imports its optional peer `expo-blur`.**
|
|
14
|
+
`SpotlightOverlay` did `import { BlurView } from "expo-blur"` at module scope and built its
|
|
15
|
+
animated blur component at module load, and `coachmarks/index.ts` re-exports the overlay with no
|
|
16
|
+
wildcard escape — so importing ANYTHING from `@wireai/activation/coachmarks`, even
|
|
17
|
+
`setCoachmarkStorage`, dragged `expo-blur` in. A host that took the peer's "optional" at its word
|
|
18
|
+
and skipped installing it hit a Metro resolution failure the moment it touched coachmarks, which
|
|
19
|
+
is why the AI Mobile Launcher tiers (and any Expo Go build) could not adopt the capability. The
|
|
20
|
+
peer is now resolved through a guarded lazy require with a string-literal specifier inside a
|
|
21
|
+
try/catch (the same shape as `icons/expoIcons.ts` / `device/appVersion.ts`), and the animated
|
|
22
|
+
component is built once on first render, so the subpath carries no static top-level import of the
|
|
23
|
+
peer.
|
|
24
|
+
- **Degradation, by design:** when `expo-blur` is absent the spotlight drops the frost to an
|
|
25
|
+
equivalent dimmed scrim. The ring, tooltip and gestures behave identically — a missing
|
|
26
|
+
decorative frost never blanks a tour, never crashes, never renders empty.
|
|
27
|
+
- `metro/index.js` `OPTIONAL_MODULES` and `tsup.config.ts` now treat `expo-blur` as a guarded
|
|
28
|
+
optional peer (moved off the static-peer list), so the built `dist/` collects it as optional and
|
|
29
|
+
the metro helper's empty-module safety net covers it for hosts that disable Metro's
|
|
30
|
+
`allowOptionalDependencies`.
|
|
31
|
+
|
|
6
32
|
## [0.14.1] - 2026-08-18
|
|
7
33
|
|
|
8
34
|
Two rulings from the 0.14.0 audit, applied. Both were reproduced there and left for a decision
|
package/dist/coachmarks/index.js
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
var React3 = require('react');
|
|
4
4
|
var jsxRuntime = require('react/jsx-runtime');
|
|
5
|
-
var expoBlur = require('expo-blur');
|
|
6
5
|
var reactNative = require('react-native');
|
|
7
6
|
var Animated = require('react-native-reanimated');
|
|
8
7
|
|
|
@@ -11,7 +10,12 @@ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
|
11
10
|
var React3__default = /*#__PURE__*/_interopDefault(React3);
|
|
12
11
|
var Animated__default = /*#__PURE__*/_interopDefault(Animated);
|
|
13
12
|
|
|
14
|
-
|
|
13
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
14
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
15
|
+
}) : x)(function(x) {
|
|
16
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
17
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
18
|
+
});
|
|
15
19
|
|
|
16
20
|
// src/features/defaults.ts
|
|
17
21
|
var defaultWireFeatures = Object.freeze({
|
|
@@ -90,8 +94,8 @@ var DEFAULT_TIMEOUT_MS = 4e3;
|
|
|
90
94
|
var failOpen = async (storage, key) => {
|
|
91
95
|
var _a;
|
|
92
96
|
if (!storage) return defaultWireFeatures;
|
|
93
|
-
const
|
|
94
|
-
return (_a =
|
|
97
|
+
const cached2 = await readCachedFeatures(storage, key);
|
|
98
|
+
return (_a = cached2 == null ? void 0 : cached2.features) != null ? _a : defaultWireFeatures;
|
|
95
99
|
};
|
|
96
100
|
var fetchWithTimeout = async (url, apiKey, timeoutMs) => {
|
|
97
101
|
const controller = typeof AbortController !== "undefined" ? new AbortController() : void 0;
|
|
@@ -329,6 +333,47 @@ var useOnboardingTheme = () => {
|
|
|
329
333
|
const ctx = React3.useContext(OnboardingThemeContext);
|
|
330
334
|
return ctx != null ? ctx : mergeTheme();
|
|
331
335
|
};
|
|
336
|
+
|
|
337
|
+
// src/coachmarks/expoBlur.ts
|
|
338
|
+
var runtimeRequire = (moduleName) => {
|
|
339
|
+
if (moduleName !== "expo-blur") return void 0;
|
|
340
|
+
if (typeof __require !== "function") return void 0;
|
|
341
|
+
try {
|
|
342
|
+
return require("expo-blur");
|
|
343
|
+
} catch {
|
|
344
|
+
return void 0;
|
|
345
|
+
}
|
|
346
|
+
};
|
|
347
|
+
var interop = (mod) => {
|
|
348
|
+
if (!mod || typeof mod !== "object") return void 0;
|
|
349
|
+
const ns = mod;
|
|
350
|
+
if (ns.BlurView) return ns;
|
|
351
|
+
const def = mod.default;
|
|
352
|
+
if (def && typeof def === "object") return def;
|
|
353
|
+
return ns;
|
|
354
|
+
};
|
|
355
|
+
var asComponent = (value) => {
|
|
356
|
+
if (typeof value === "function") return value;
|
|
357
|
+
if (value && typeof value === "object" && "$$typeof" in value) {
|
|
358
|
+
return value;
|
|
359
|
+
}
|
|
360
|
+
return void 0;
|
|
361
|
+
};
|
|
362
|
+
var cached;
|
|
363
|
+
var resolveBlurView = (requireModule = runtimeRequire) => {
|
|
364
|
+
try {
|
|
365
|
+
if (cached === void 0 || requireModule !== runtimeRequire) {
|
|
366
|
+
const resolved = interop(requireModule("expo-blur"));
|
|
367
|
+
const component = resolved ? asComponent(resolved.BlurView) : void 0;
|
|
368
|
+
if (requireModule === runtimeRequire) cached = component != null ? component : null;
|
|
369
|
+
return component;
|
|
370
|
+
}
|
|
371
|
+
if (cached === null) return void 0;
|
|
372
|
+
return cached;
|
|
373
|
+
} catch {
|
|
374
|
+
return void 0;
|
|
375
|
+
}
|
|
376
|
+
};
|
|
332
377
|
var SWIPE_MS = 700;
|
|
333
378
|
var TAP_MS = 320;
|
|
334
379
|
var SPREAD_MS = 620;
|
|
@@ -543,7 +588,6 @@ var styles = reactNative.StyleSheet.create({
|
|
|
543
588
|
});
|
|
544
589
|
var GestureHint = React3__default.default.memo(GestureHintComponent);
|
|
545
590
|
GestureHint.displayName = "GestureHint";
|
|
546
|
-
var AnimatedBlurView = Animated__default.default.createAnimatedComponent(expoBlur.BlurView);
|
|
547
591
|
var BLUR_INTENSITY = 26;
|
|
548
592
|
var FADE_MS = 280;
|
|
549
593
|
var RING_PADDING = 10;
|
|
@@ -565,6 +609,10 @@ var SpotlightOverlayComponent = ({
|
|
|
565
609
|
const theme = useOnboardingTheme();
|
|
566
610
|
const accent = accentColor != null ? accentColor : theme.colors.primary;
|
|
567
611
|
const accentText = accentTextColor != null ? accentTextColor : theme.colors.onPrimary;
|
|
612
|
+
const AnimatedBlurView = React3.useMemo(() => {
|
|
613
|
+
const BlurView = resolveBlurView();
|
|
614
|
+
return BlurView ? Animated__default.default.createAnimatedComponent(BlurView) : null;
|
|
615
|
+
}, []);
|
|
568
616
|
const showGesture = gesture !== "none" && gesture !== "tap" && gesture !== "double_tap";
|
|
569
617
|
const intensity = Animated.useSharedValue(0);
|
|
570
618
|
const ringScale = Animated.useSharedValue(1);
|
|
@@ -613,13 +661,23 @@ var SpotlightOverlayComponent = ({
|
|
|
613
661
|
entering: Animated.FadeIn.duration(FADE_MS),
|
|
614
662
|
exiting: Animated.FadeOut.duration(FADE_MS),
|
|
615
663
|
children: [
|
|
616
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
664
|
+
AnimatedBlurView ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
617
665
|
AnimatedBlurView,
|
|
618
666
|
{
|
|
619
667
|
tint: "dark",
|
|
620
668
|
animatedProps: blurAnimatedProps,
|
|
621
669
|
style: reactNative.StyleSheet.absoluteFill
|
|
622
670
|
}
|
|
671
|
+
) : (
|
|
672
|
+
// `expo-blur` absent → a plain dimmed scrim stands in for the frost. Same dark backdrop
|
|
673
|
+
// the tour reads against, so the ring, tooltip and gestures behave identically.
|
|
674
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
675
|
+
Animated__default.default.View,
|
|
676
|
+
{
|
|
677
|
+
style: [reactNative.StyleSheet.absoluteFill, styles2.scrim],
|
|
678
|
+
pointerEvents: "none"
|
|
679
|
+
}
|
|
680
|
+
)
|
|
623
681
|
),
|
|
624
682
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
625
683
|
reactNative.Pressable,
|
|
@@ -686,6 +744,11 @@ var styles2 = reactNative.StyleSheet.create({
|
|
|
686
744
|
zIndex: 9999,
|
|
687
745
|
elevation: 9999
|
|
688
746
|
},
|
|
747
|
+
// Fallback backdrop when `expo-blur` is absent. A structural dim (not a brand token), tuned to
|
|
748
|
+
// read like the dark blur at BLUR_INTENSITY so the ring + tooltip keep the same contrast.
|
|
749
|
+
scrim: {
|
|
750
|
+
backgroundColor: "rgba(0, 0, 0, 0.55)"
|
|
751
|
+
},
|
|
689
752
|
ring: {
|
|
690
753
|
position: "absolute",
|
|
691
754
|
borderWidth: 2.5,
|