@getrheo/react-native-bare 1.0.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/README.md +26 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +197 -0
- package/dist/index.js.map +1 -0
- package/dist/publish-exports.json +6 -0
- package/package.json +73 -0
package/README.md
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# @getrheo/react-native-bare
|
|
2
|
+
|
|
3
|
+
Bare React Native entry for the Rheo SDK. Re-exports `@getrheo/react-native-core` and registers **bare** adapters (`react-native-video`, `react-native-in-app-review`). Do not install alongside `@getrheo/react-native-expo`.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @getrheo/react-native-bare \
|
|
9
|
+
react react-native \
|
|
10
|
+
react-native-permissions react-native-gesture-handler react-native-reanimated \
|
|
11
|
+
react-native-linear-gradient react-native-svg lottie-react-native \
|
|
12
|
+
react-native-vector-icons @react-native-async-storage/async-storage \
|
|
13
|
+
react-native-safe-area-context react-native-in-app-review react-native-video
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Complete native setup for permissions (Info.plist / AndroidManifest) per [react-native-permissions](https://github.com/zoontek/react-native-permissions).
|
|
17
|
+
|
|
18
|
+
**Integrations (not SDK peers):** `react-native-appsflyer`, `react-native-purchases`, `react-native-purchases-ui` — install only when used.
|
|
19
|
+
|
|
20
|
+
## Usage
|
|
21
|
+
|
|
22
|
+
Same API as the Expo flavor (`Flow`, `RheoProvider`, `useFlow`, …). See [`react-native-expo/README.md`](../react-native-expo/README.md) for flow semantics, events, terminal payloads, and production **`apiBaseUrl`** guidance — import from `@getrheo/react-native-bare` instead.
|
|
23
|
+
|
|
24
|
+
## Example
|
|
25
|
+
|
|
26
|
+
[`apps/example-bare`](../../../apps/example-bare) — scaffold `ios/` / `android/` with the RN CLI before running (see example README).
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '@getrheo/react-native-core';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { registerAppReviewAdapter, registerVideoAdapter } from '@getrheo/react-native-core/platform';
|
|
2
|
+
import InAppReview from 'react-native-in-app-review';
|
|
3
|
+
import { useRef, useState, useCallback, useEffect } from 'react';
|
|
4
|
+
import { View, Text } from 'react-native';
|
|
5
|
+
import Video from 'react-native-video';
|
|
6
|
+
import { screenBackgroundPlaybackId } from '@getrheo/contracts';
|
|
7
|
+
import { DEFAULT_PREVIEW_VIEWPORT_WIDTH_PX, resolveImageStyleAtWidth } from '@getrheo/flow-runtime';
|
|
8
|
+
import { ChromeView } from '@getrheo/react-native-core/ui/LayerRendererShared';
|
|
9
|
+
import { mediaAutoPlayOnMount, useMediaPlayback, useMediaPlaySignal } from '@getrheo/react-native-core/ui/mediaPlayback';
|
|
10
|
+
import { mediaLayerOuterLayoutPair, mediaLayerInnerFillStyle } from '@getrheo/react-native-core/ui/styles';
|
|
11
|
+
import { fireMediaOnComplete } from '@getrheo/react-native-core/ui/layers/mediaLayers';
|
|
12
|
+
import { jsx } from 'react/jsx-runtime';
|
|
13
|
+
export * from '@getrheo/react-native-core';
|
|
14
|
+
|
|
15
|
+
// src/registerBareAdapters.ts
|
|
16
|
+
var APP_REVIEW_POST_PROMPT_DELAY_MS = 1500;
|
|
17
|
+
var delay = (ms) => new Promise((resolve) => {
|
|
18
|
+
setTimeout(resolve, ms);
|
|
19
|
+
});
|
|
20
|
+
var bareAppReviewAdapter = {
|
|
21
|
+
requestReview: async (sessionPlatform) => {
|
|
22
|
+
if (sessionPlatform === "web") {
|
|
23
|
+
return { shown: false };
|
|
24
|
+
}
|
|
25
|
+
if (!InAppReview.isAvailable()) {
|
|
26
|
+
return { shown: false };
|
|
27
|
+
}
|
|
28
|
+
try {
|
|
29
|
+
const shown = await InAppReview.RequestInAppReview();
|
|
30
|
+
if (!shown) {
|
|
31
|
+
return { shown: false };
|
|
32
|
+
}
|
|
33
|
+
await delay(APP_REVIEW_POST_PROMPT_DELAY_MS);
|
|
34
|
+
return { shown: true };
|
|
35
|
+
} catch {
|
|
36
|
+
return { shown: false };
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
var backdropLayout = {
|
|
41
|
+
position: "absolute",
|
|
42
|
+
top: 0,
|
|
43
|
+
left: 0,
|
|
44
|
+
right: 0,
|
|
45
|
+
bottom: 0,
|
|
46
|
+
zIndex: 0
|
|
47
|
+
};
|
|
48
|
+
var resizeModeFor = (fit) => {
|
|
49
|
+
if (fit === "contain") return "contain";
|
|
50
|
+
if (fit === "fill") return "stretch";
|
|
51
|
+
return "cover";
|
|
52
|
+
};
|
|
53
|
+
var useBareVideoPlayback = ({
|
|
54
|
+
url,
|
|
55
|
+
layerId,
|
|
56
|
+
shouldAutoplay,
|
|
57
|
+
loopPlay,
|
|
58
|
+
muted,
|
|
59
|
+
onPlayToEnd
|
|
60
|
+
}) => {
|
|
61
|
+
const videoRef = useRef(null);
|
|
62
|
+
const playback = useMediaPlayback();
|
|
63
|
+
const playSignal = useMediaPlaySignal(layerId);
|
|
64
|
+
const completedRef = useRef(false);
|
|
65
|
+
const [paused, setPaused] = useState(!shouldAutoplay || !url);
|
|
66
|
+
const play = useCallback(() => {
|
|
67
|
+
completedRef.current = false;
|
|
68
|
+
setPaused(false);
|
|
69
|
+
videoRef.current?.seek(0);
|
|
70
|
+
}, []);
|
|
71
|
+
useEffect(() => {
|
|
72
|
+
if (!playback) return;
|
|
73
|
+
return playback.register(layerId, { play });
|
|
74
|
+
}, [playback, layerId, play]);
|
|
75
|
+
useEffect(() => {
|
|
76
|
+
setPaused(!shouldAutoplay || !url);
|
|
77
|
+
}, [shouldAutoplay, url]);
|
|
78
|
+
useEffect(() => {
|
|
79
|
+
if (shouldAutoplay || playSignal === 0 || !url) return;
|
|
80
|
+
play();
|
|
81
|
+
}, [playSignal, shouldAutoplay, play, url]);
|
|
82
|
+
const onEnd = useCallback(() => {
|
|
83
|
+
if (loopPlay || completedRef.current) return;
|
|
84
|
+
completedRef.current = true;
|
|
85
|
+
onPlayToEnd?.();
|
|
86
|
+
}, [loopPlay, onPlayToEnd]);
|
|
87
|
+
const onError = useCallback((_e) => {
|
|
88
|
+
setPaused(true);
|
|
89
|
+
}, []);
|
|
90
|
+
return {
|
|
91
|
+
videoRef,
|
|
92
|
+
paused,
|
|
93
|
+
play,
|
|
94
|
+
onEnd,
|
|
95
|
+
onError,
|
|
96
|
+
loopPlay,
|
|
97
|
+
muted
|
|
98
|
+
};
|
|
99
|
+
};
|
|
100
|
+
var BareVideoLayerView = ({ layer, ctx }) => {
|
|
101
|
+
const w = ctx.previewWidthPx ?? DEFAULT_PREVIEW_VIEWPORT_WIDTH_PX;
|
|
102
|
+
const resolvedStyle = resolveImageStyleAtWidth(layer.style, layer.styleBreakpoints, w);
|
|
103
|
+
const url = layer.media ? ctx.mediaMap?.[layer.media.mediaAssetId] : void 0;
|
|
104
|
+
const shouldAutoplay = mediaAutoPlayOnMount(layer);
|
|
105
|
+
const loopPlay = layer.loop !== false;
|
|
106
|
+
const muted = layer.audioEnabled !== true;
|
|
107
|
+
const { videoRef, paused, onEnd, onError, loopPlay: loop, muted: isMuted } = useBareVideoPlayback({
|
|
108
|
+
url,
|
|
109
|
+
layerId: layer.id,
|
|
110
|
+
shouldAutoplay,
|
|
111
|
+
loopPlay,
|
|
112
|
+
muted,
|
|
113
|
+
onPlayToEnd: () => fireMediaOnComplete(ctx, layer)
|
|
114
|
+
});
|
|
115
|
+
const { outerStyle, linearGradient } = mediaLayerOuterLayoutPair(
|
|
116
|
+
resolvedStyle,
|
|
117
|
+
ctx.manifest.theme,
|
|
118
|
+
ctx.theme,
|
|
119
|
+
ctx.branding
|
|
120
|
+
);
|
|
121
|
+
const placeholderBg = ctx.theme === "dark" ? "#18181b" : "#f4f4f5";
|
|
122
|
+
const hasAuthorBg = linearGradient != null || outerStyle.backgroundColor !== void 0;
|
|
123
|
+
const innerStyle = {
|
|
124
|
+
...mediaLayerInnerFillStyle(resolvedStyle),
|
|
125
|
+
borderRadius: outerStyle.borderRadius ?? 10,
|
|
126
|
+
...!hasAuthorBg && !url ? { backgroundColor: placeholderBg } : {}
|
|
127
|
+
};
|
|
128
|
+
const r = innerStyle.borderRadius;
|
|
129
|
+
const resizeMode = resizeModeFor(resolvedStyle?.fit ?? "contain");
|
|
130
|
+
return /* @__PURE__ */ jsx(ChromeView, { style: outerStyle, linearGradient, children: url ? /* @__PURE__ */ jsx(View, { style: innerStyle, children: /* @__PURE__ */ jsx(
|
|
131
|
+
Video,
|
|
132
|
+
{
|
|
133
|
+
ref: videoRef,
|
|
134
|
+
source: { uri: url },
|
|
135
|
+
style: {
|
|
136
|
+
width: "100%",
|
|
137
|
+
height: "100%",
|
|
138
|
+
...r !== void 0 ? { borderRadius: r } : {}
|
|
139
|
+
},
|
|
140
|
+
resizeMode,
|
|
141
|
+
repeat: loop,
|
|
142
|
+
muted: isMuted,
|
|
143
|
+
paused,
|
|
144
|
+
onEnd,
|
|
145
|
+
onError
|
|
146
|
+
}
|
|
147
|
+
) }) : /* @__PURE__ */ jsx(View, { style: [innerStyle, { alignItems: "center", justifyContent: "center" }], children: /* @__PURE__ */ jsx(Text, { style: { color: "#71717a", fontSize: 11 }, children: "No media" }) }) });
|
|
148
|
+
};
|
|
149
|
+
var BareScreenShellVideoBackdrop = ({
|
|
150
|
+
screenId,
|
|
151
|
+
url,
|
|
152
|
+
fill,
|
|
153
|
+
ctx
|
|
154
|
+
}) => {
|
|
155
|
+
const shouldAutoplay = mediaAutoPlayOnMount(fill);
|
|
156
|
+
const loopPlay = fill.loop !== false;
|
|
157
|
+
const muted = fill.audioEnabled !== true;
|
|
158
|
+
const playbackId = screenBackgroundPlaybackId(screenId);
|
|
159
|
+
const { videoRef, paused, onEnd, onError, loopPlay: loop, muted: isMuted } = useBareVideoPlayback({
|
|
160
|
+
url,
|
|
161
|
+
layerId: playbackId,
|
|
162
|
+
shouldAutoplay,
|
|
163
|
+
loopPlay,
|
|
164
|
+
muted,
|
|
165
|
+
onPlayToEnd: () => {
|
|
166
|
+
const mode = fill.onComplete?.mode ?? "none";
|
|
167
|
+
if (mode === "next") ctx.onRespond?.({ kind: "cta", action: "primary" });
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
return /* @__PURE__ */ jsx(View, { style: backdropLayout, pointerEvents: "none", collapsable: false, children: /* @__PURE__ */ jsx(
|
|
171
|
+
Video,
|
|
172
|
+
{
|
|
173
|
+
ref: videoRef,
|
|
174
|
+
source: { uri: url },
|
|
175
|
+
style: {
|
|
176
|
+
width: "100%",
|
|
177
|
+
height: "100%",
|
|
178
|
+
opacity: fill.opacity ?? 1
|
|
179
|
+
},
|
|
180
|
+
resizeMode: resizeModeFor(fill.fit),
|
|
181
|
+
repeat: loop,
|
|
182
|
+
muted: isMuted,
|
|
183
|
+
paused,
|
|
184
|
+
onEnd,
|
|
185
|
+
onError
|
|
186
|
+
}
|
|
187
|
+
) });
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
// src/registerBareAdapters.ts
|
|
191
|
+
registerAppReviewAdapter(bareAppReviewAdapter);
|
|
192
|
+
registerVideoAdapter({
|
|
193
|
+
VideoLayerView: BareVideoLayerView,
|
|
194
|
+
ScreenShellVideoBackdrop: BareScreenShellVideoBackdrop
|
|
195
|
+
});
|
|
196
|
+
//# sourceMappingURL=index.js.map
|
|
197
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/adapters/bareAppReview.ts","../src/adapters/bareVideo.tsx","../src/registerBareAdapters.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import InAppReview from 'react-native-in-app-review';\nimport type { AppReviewAdapter } from '@getrheo/react-native-core/platform';\nimport type { AppReviewRequestResult } from '@getrheo/react-native-core';\n\nconst APP_REVIEW_POST_PROMPT_DELAY_MS = 1500;\n\nconst delay = (ms: number): Promise<void> =>\n new Promise((resolve) => {\n setTimeout(resolve, ms);\n });\n\nexport const bareAppReviewAdapter: AppReviewAdapter = {\n requestReview: async (sessionPlatform: string): Promise<AppReviewRequestResult> => {\n if (sessionPlatform === 'web') {\n return { shown: false };\n }\n\n if (!InAppReview.isAvailable()) {\n return { shown: false };\n }\n\n try {\n const shown = await InAppReview.RequestInAppReview();\n if (!shown) {\n return { shown: false };\n }\n await delay(APP_REVIEW_POST_PROMPT_DELAY_MS);\n return { shown: true };\n } catch {\n return { shown: false };\n }\n },\n};\n","import { useCallback, useEffect, useRef, useState } from 'react';\nimport { Text, View } from 'react-native';\nimport type { ViewStyle } from 'react-native';\nimport Video, { type OnVideoErrorData, type VideoRef } from 'react-native-video';\nimport { screenBackgroundPlaybackId } from '@getrheo/contracts';\nimport { DEFAULT_PREVIEW_VIEWPORT_WIDTH_PX, resolveImageStyleAtWidth } from '@getrheo/flow-runtime';\nimport { ChromeView } from '@getrheo/react-native-core/ui/LayerRendererShared';\nimport {\n mediaAutoPlayOnMount,\n useMediaPlayback,\n useMediaPlaySignal,\n} from '@getrheo/react-native-core/ui/mediaPlayback';\nimport {\n mediaLayerInnerFillStyle,\n mediaLayerOuterLayoutPair,\n} from '@getrheo/react-native-core/ui/styles';\nimport { fireMediaOnComplete } from '@getrheo/react-native-core/ui/layers/mediaLayers';\nimport type {\n ScreenShellVideoBackdropProps,\n VideoLayerViewProps,\n} from '@getrheo/react-native-core/platform';\n\nconst backdropLayout: ViewStyle = {\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n zIndex: 0,\n};\n\nconst resizeModeFor = (\n fit: 'cover' | 'contain' | 'fill' | undefined,\n): 'cover' | 'contain' | 'stretch' => {\n if (fit === 'contain') return 'contain';\n if (fit === 'fill') return 'stretch';\n return 'cover';\n};\n\nconst useBareVideoPlayback = ({\n url,\n layerId,\n shouldAutoplay,\n loopPlay,\n muted,\n onPlayToEnd,\n}: {\n url: string | undefined;\n layerId: string;\n shouldAutoplay: boolean;\n loopPlay: boolean;\n muted: boolean;\n onPlayToEnd?: () => void;\n}) => {\n const videoRef = useRef<VideoRef>(null);\n const playback = useMediaPlayback();\n const playSignal = useMediaPlaySignal(layerId);\n const completedRef = useRef(false);\n const [paused, setPaused] = useState(!shouldAutoplay || !url);\n\n const play = useCallback(() => {\n completedRef.current = false;\n setPaused(false);\n videoRef.current?.seek(0);\n }, []);\n\n useEffect(() => {\n if (!playback) return;\n return playback.register(layerId, { play });\n }, [playback, layerId, play]);\n\n useEffect(() => {\n setPaused(!shouldAutoplay || !url);\n }, [shouldAutoplay, url]);\n\n useEffect(() => {\n if (shouldAutoplay || playSignal === 0 || !url) return;\n play();\n }, [playSignal, shouldAutoplay, play, url]);\n\n const onEnd = useCallback(() => {\n if (loopPlay || completedRef.current) return;\n completedRef.current = true;\n onPlayToEnd?.();\n }, [loopPlay, onPlayToEnd]);\n\n const onError = useCallback((_e: OnVideoErrorData) => {\n setPaused(true);\n }, []);\n\n return {\n videoRef,\n paused,\n play,\n onEnd,\n onError,\n loopPlay,\n muted,\n };\n};\n\nexport const BareVideoLayerView = ({ layer, ctx }: VideoLayerViewProps) => {\n const w = ctx.previewWidthPx ?? DEFAULT_PREVIEW_VIEWPORT_WIDTH_PX;\n const resolvedStyle = resolveImageStyleAtWidth(layer.style, layer.styleBreakpoints, w);\n const url = layer.media ? ctx.mediaMap?.[layer.media.mediaAssetId] : undefined;\n const shouldAutoplay = mediaAutoPlayOnMount(layer);\n const loopPlay = layer.loop !== false;\n const muted = layer.audioEnabled !== true;\n\n const { videoRef, paused, onEnd, onError, loopPlay: loop, muted: isMuted } =\n useBareVideoPlayback({\n url,\n layerId: layer.id,\n shouldAutoplay,\n loopPlay,\n muted,\n onPlayToEnd: () => fireMediaOnComplete(ctx, layer),\n });\n\n const { outerStyle, linearGradient } = mediaLayerOuterLayoutPair(\n resolvedStyle,\n ctx.manifest.theme,\n ctx.theme,\n ctx.branding,\n );\n const placeholderBg = ctx.theme === 'dark' ? '#18181b' : '#f4f4f5';\n const hasAuthorBg =\n linearGradient != null || outerStyle.backgroundColor !== undefined;\n const innerStyle = {\n ...mediaLayerInnerFillStyle(resolvedStyle),\n borderRadius: outerStyle.borderRadius ?? 10,\n ...(!hasAuthorBg && !url ? { backgroundColor: placeholderBg } : {}),\n };\n const r = innerStyle.borderRadius as number | undefined;\n const resizeMode = resizeModeFor(resolvedStyle?.fit ?? 'contain');\n\n return (\n <ChromeView style={outerStyle} linearGradient={linearGradient}>\n {url ? (\n <View style={innerStyle}>\n <Video\n ref={videoRef}\n source={{ uri: url }}\n style={{\n width: '100%',\n height: '100%',\n ...(r !== undefined ? { borderRadius: r } : {}),\n }}\n resizeMode={resizeMode}\n repeat={loop}\n muted={isMuted}\n paused={paused}\n onEnd={onEnd}\n onError={onError}\n />\n </View>\n ) : (\n <View style={[innerStyle, { alignItems: 'center', justifyContent: 'center' }]}>\n <Text style={{ color: '#71717a', fontSize: 11 }}>No media</Text>\n </View>\n )}\n </ChromeView>\n );\n};\n\nexport const BareScreenShellVideoBackdrop = ({\n screenId,\n url,\n fill,\n ctx,\n}: ScreenShellVideoBackdropProps) => {\n const shouldAutoplay = mediaAutoPlayOnMount(fill);\n const loopPlay = fill.loop !== false;\n const muted = fill.audioEnabled !== true;\n const playbackId = screenBackgroundPlaybackId(screenId);\n\n const { videoRef, paused, onEnd, onError, loopPlay: loop, muted: isMuted } =\n useBareVideoPlayback({\n url,\n layerId: playbackId,\n shouldAutoplay,\n loopPlay,\n muted,\n onPlayToEnd: () => {\n const mode = fill.onComplete?.mode ?? 'none';\n if (mode === 'next') ctx.onRespond?.({ kind: 'cta', action: 'primary' });\n },\n });\n\n return (\n <View style={backdropLayout} pointerEvents=\"none\" collapsable={false}>\n <Video\n ref={videoRef}\n source={{ uri: url }}\n style={{\n width: '100%',\n height: '100%',\n opacity: fill.opacity ?? 1,\n }}\n resizeMode={resizeModeFor(fill.fit)}\n repeat={loop}\n muted={isMuted}\n paused={paused}\n onEnd={onEnd}\n onError={onError}\n />\n </View>\n );\n};\n","import { registerAppReviewAdapter, registerVideoAdapter } from '@getrheo/react-native-core/platform';\nimport { bareAppReviewAdapter } from './adapters/bareAppReview.js';\nimport { BareScreenShellVideoBackdrop, BareVideoLayerView } from './adapters/bareVideo.js';\n\nregisterAppReviewAdapter(bareAppReviewAdapter);\nregisterVideoAdapter({\n VideoLayerView: BareVideoLayerView,\n ScreenShellVideoBackdrop: BareScreenShellVideoBackdrop,\n});\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@getrheo/react-native-bare",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"default": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"@getrheo/react-native-core": "1.0.0"
|
|
16
|
+
},
|
|
17
|
+
"peerDependencies": {
|
|
18
|
+
"@react-native-async-storage/async-storage": ">=2",
|
|
19
|
+
"lottie-react-native": "*",
|
|
20
|
+
"react": ">=18",
|
|
21
|
+
"react-native": ">=0.79",
|
|
22
|
+
"react-native-gesture-handler": "*",
|
|
23
|
+
"react-native-in-app-review": "*",
|
|
24
|
+
"react-native-linear-gradient": "*",
|
|
25
|
+
"react-native-permissions": ">=5",
|
|
26
|
+
"react-native-reanimated": "*",
|
|
27
|
+
"react-native-safe-area-context": "*",
|
|
28
|
+
"react-native-svg": "*",
|
|
29
|
+
"react-native-vector-icons": ">=10",
|
|
30
|
+
"react-native-video": "*"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@react-native-async-storage/async-storage": "2.2.0",
|
|
34
|
+
"@types/react": "^19.0.1",
|
|
35
|
+
"lottie-react-native": "^7.2.2",
|
|
36
|
+
"react": "^19.0.0",
|
|
37
|
+
"react-native": "0.83.6",
|
|
38
|
+
"react-native-gesture-handler": "~2.30.1",
|
|
39
|
+
"react-native-in-app-review": "^4.3.3",
|
|
40
|
+
"react-native-linear-gradient": "^2.8.3",
|
|
41
|
+
"react-native-permissions": "^5.5.1",
|
|
42
|
+
"react-native-reanimated": "~4.2.1",
|
|
43
|
+
"react-native-safe-area-context": "~5.6.1",
|
|
44
|
+
"react-native-svg": "15.15.4",
|
|
45
|
+
"react-native-vector-icons": "^10.2.0",
|
|
46
|
+
"react-native-video": "^6.10.2",
|
|
47
|
+
"typescript": "^5.6.3",
|
|
48
|
+
"vitest": "^3.2.6",
|
|
49
|
+
"@getrheo/contracts": "1.0.0",
|
|
50
|
+
"@getrheo/flow-runtime": "1.0.0",
|
|
51
|
+
"@getrheo/react-native-core": "1.0.0",
|
|
52
|
+
"@rheo/config": "0.1.0"
|
|
53
|
+
},
|
|
54
|
+
"license": "MIT",
|
|
55
|
+
"repository": {
|
|
56
|
+
"type": "git",
|
|
57
|
+
"url": "git+https://github.com/madeinusmate/onboardly.git",
|
|
58
|
+
"directory": "packages/sdks/react-native-bare"
|
|
59
|
+
},
|
|
60
|
+
"files": [
|
|
61
|
+
"dist",
|
|
62
|
+
"README.md"
|
|
63
|
+
],
|
|
64
|
+
"publishConfig": {
|
|
65
|
+
"access": "public"
|
|
66
|
+
},
|
|
67
|
+
"scripts": {
|
|
68
|
+
"lint": "eslint .",
|
|
69
|
+
"typecheck": "tsc --noEmit",
|
|
70
|
+
"test": "vitest run --passWithNoTests --config ../react-native-core/vitest.config.ts",
|
|
71
|
+
"build": "node ../../../scripts/build-publishable-package.mjs"
|
|
72
|
+
}
|
|
73
|
+
}
|