@growth-rail/react 1.0.1
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/dist/index.d.mts +29 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.js +177 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +148 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +46 -0
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import React, { ReactNode } from 'react';
|
|
2
|
+
import { GrowthRailOptions, AppUserType, GrowthRail, ReferrerTriggerButton, ReferrerModalOptions } from '@growth-rail/core';
|
|
3
|
+
export { AppUserType, GrowthRailOptions } from '@growth-rail/core';
|
|
4
|
+
|
|
5
|
+
interface GrowthRailProviderProps extends GrowthRailOptions {
|
|
6
|
+
userId?: string;
|
|
7
|
+
children: ReactNode;
|
|
8
|
+
}
|
|
9
|
+
declare const GrowthRailProvider: React.FC<GrowthRailProviderProps>;
|
|
10
|
+
|
|
11
|
+
interface UseGrowthRailReturn {
|
|
12
|
+
initUser: (userId: string) => Promise<AppUserType>;
|
|
13
|
+
trackReward: (eventName?: string) => Promise<void>;
|
|
14
|
+
showReferralDashboard: (options?: Parameters<typeof GrowthRail.showReferralDashboard>[0]) => void;
|
|
15
|
+
showFloatingButton: (options: Partial<ReferrerTriggerButton>) => void;
|
|
16
|
+
hideFloatingButton: () => void;
|
|
17
|
+
isLoading: boolean;
|
|
18
|
+
error: Error | null;
|
|
19
|
+
}
|
|
20
|
+
declare const useGrowthRail: () => UseGrowthRailReturn;
|
|
21
|
+
|
|
22
|
+
interface ReferralDashboardProps {
|
|
23
|
+
title?: string;
|
|
24
|
+
appearance?: ReferrerModalOptions;
|
|
25
|
+
onLinkCopied?: () => void;
|
|
26
|
+
}
|
|
27
|
+
declare const ReferralDashboard: React.FC<ReferralDashboardProps>;
|
|
28
|
+
|
|
29
|
+
export { GrowthRailProvider, ReferralDashboard, type ReferralDashboardProps, type UseGrowthRailReturn, useGrowthRail };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import React, { ReactNode } from 'react';
|
|
2
|
+
import { GrowthRailOptions, AppUserType, GrowthRail, ReferrerTriggerButton, ReferrerModalOptions } from '@growth-rail/core';
|
|
3
|
+
export { AppUserType, GrowthRailOptions } from '@growth-rail/core';
|
|
4
|
+
|
|
5
|
+
interface GrowthRailProviderProps extends GrowthRailOptions {
|
|
6
|
+
userId?: string;
|
|
7
|
+
children: ReactNode;
|
|
8
|
+
}
|
|
9
|
+
declare const GrowthRailProvider: React.FC<GrowthRailProviderProps>;
|
|
10
|
+
|
|
11
|
+
interface UseGrowthRailReturn {
|
|
12
|
+
initUser: (userId: string) => Promise<AppUserType>;
|
|
13
|
+
trackReward: (eventName?: string) => Promise<void>;
|
|
14
|
+
showReferralDashboard: (options?: Parameters<typeof GrowthRail.showReferralDashboard>[0]) => void;
|
|
15
|
+
showFloatingButton: (options: Partial<ReferrerTriggerButton>) => void;
|
|
16
|
+
hideFloatingButton: () => void;
|
|
17
|
+
isLoading: boolean;
|
|
18
|
+
error: Error | null;
|
|
19
|
+
}
|
|
20
|
+
declare const useGrowthRail: () => UseGrowthRailReturn;
|
|
21
|
+
|
|
22
|
+
interface ReferralDashboardProps {
|
|
23
|
+
title?: string;
|
|
24
|
+
appearance?: ReferrerModalOptions;
|
|
25
|
+
onLinkCopied?: () => void;
|
|
26
|
+
}
|
|
27
|
+
declare const ReferralDashboard: React.FC<ReferralDashboardProps>;
|
|
28
|
+
|
|
29
|
+
export { GrowthRailProvider, ReferralDashboard, type ReferralDashboardProps, type UseGrowthRailReturn, useGrowthRail };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.tsx
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
GrowthRailProvider: () => GrowthRailProvider,
|
|
24
|
+
ReferralDashboard: () => ReferralDashboard,
|
|
25
|
+
useGrowthRail: () => useGrowthRail
|
|
26
|
+
});
|
|
27
|
+
module.exports = __toCommonJS(index_exports);
|
|
28
|
+
|
|
29
|
+
// src/GrowthRailProvider.tsx
|
|
30
|
+
var import_react = require("react");
|
|
31
|
+
var import_core = require("@growth-rail/core");
|
|
32
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
33
|
+
var GrowthRailProvider = ({
|
|
34
|
+
children,
|
|
35
|
+
userId,
|
|
36
|
+
...options
|
|
37
|
+
}) => {
|
|
38
|
+
const [isReady, setIsReady] = (0, import_react.useState)(import_core.GrowthRail.isInitialized());
|
|
39
|
+
const initialized = (0, import_react.useRef)(false);
|
|
40
|
+
(0, import_react.useEffect)(() => {
|
|
41
|
+
if (initialized.current) return;
|
|
42
|
+
initialized.current = true;
|
|
43
|
+
import_core.GrowthRail.init(options);
|
|
44
|
+
if (userId) {
|
|
45
|
+
import_core.GrowthRail.initAppUser(userId).catch(console.error);
|
|
46
|
+
}
|
|
47
|
+
setIsReady(true);
|
|
48
|
+
}, []);
|
|
49
|
+
(0, import_react.useEffect)(() => {
|
|
50
|
+
if (initialized.current && userId && import_core.GrowthRail.getUserId() !== userId) {
|
|
51
|
+
import_core.GrowthRail.initAppUser(userId).catch(console.error);
|
|
52
|
+
}
|
|
53
|
+
}, [userId]);
|
|
54
|
+
if (!isReady) return null;
|
|
55
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children });
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
// src/useGrowthRail.ts
|
|
59
|
+
var import_react2 = require("react");
|
|
60
|
+
var import_core2 = require("@growth-rail/core");
|
|
61
|
+
var useGrowthRail = () => {
|
|
62
|
+
const [isLoading, setIsLoading] = (0, import_react2.useState)(false);
|
|
63
|
+
const [error, setError] = (0, import_react2.useState)(null);
|
|
64
|
+
const initUser = (0, import_react2.useCallback)(async (userId) => {
|
|
65
|
+
setIsLoading(true);
|
|
66
|
+
setError(null);
|
|
67
|
+
try {
|
|
68
|
+
const user = await import_core2.GrowthRail.initAppUser(userId);
|
|
69
|
+
return user;
|
|
70
|
+
} catch (err) {
|
|
71
|
+
const error2 = err instanceof Error ? err : new Error(String(err));
|
|
72
|
+
setError(error2);
|
|
73
|
+
throw error2;
|
|
74
|
+
} finally {
|
|
75
|
+
setIsLoading(false);
|
|
76
|
+
}
|
|
77
|
+
}, []);
|
|
78
|
+
const trackReward = (0, import_react2.useCallback)(async (eventName) => {
|
|
79
|
+
setIsLoading(true);
|
|
80
|
+
setError(null);
|
|
81
|
+
try {
|
|
82
|
+
await import_core2.GrowthRail.trackRewardEvent(eventName);
|
|
83
|
+
} catch (err) {
|
|
84
|
+
const error2 = err instanceof Error ? err : new Error(String(err));
|
|
85
|
+
setError(error2);
|
|
86
|
+
throw error2;
|
|
87
|
+
} finally {
|
|
88
|
+
setIsLoading(false);
|
|
89
|
+
}
|
|
90
|
+
}, []);
|
|
91
|
+
const showReferralDashboard = (0, import_react2.useCallback)((options) => {
|
|
92
|
+
import_core2.GrowthRail.showReferralDashboard(options);
|
|
93
|
+
}, []);
|
|
94
|
+
const showFloatingButton = (0, import_react2.useCallback)((options) => {
|
|
95
|
+
import_core2.GrowthRail.createTriggerButton(options);
|
|
96
|
+
}, []);
|
|
97
|
+
const hideFloatingButton = (0, import_react2.useCallback)(() => {
|
|
98
|
+
import_core2.GrowthRail.destroyTriggerButton();
|
|
99
|
+
}, []);
|
|
100
|
+
return {
|
|
101
|
+
initUser,
|
|
102
|
+
trackReward,
|
|
103
|
+
showReferralDashboard,
|
|
104
|
+
showFloatingButton,
|
|
105
|
+
hideFloatingButton,
|
|
106
|
+
isLoading,
|
|
107
|
+
error
|
|
108
|
+
};
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
// src/ReferralDashboard.tsx
|
|
112
|
+
var import_react3 = require("react");
|
|
113
|
+
var import_core3 = require("@growth-rail/core");
|
|
114
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
115
|
+
var ReferralDashboard = ({
|
|
116
|
+
title,
|
|
117
|
+
appearance = {},
|
|
118
|
+
onLinkCopied
|
|
119
|
+
}) => {
|
|
120
|
+
const containerRef = (0, import_react3.useRef)(null);
|
|
121
|
+
const modalRef = (0, import_react3.useRef)(null);
|
|
122
|
+
(0, import_react3.useEffect)(() => {
|
|
123
|
+
let mounted = true;
|
|
124
|
+
if (!containerRef.current) return;
|
|
125
|
+
import_core3.GrowthRail.ensureUserReady().then((user) => {
|
|
126
|
+
if (!mounted || !containerRef.current) return;
|
|
127
|
+
const deps = {
|
|
128
|
+
isUserReady: () => import_core3.GrowthRail.isUserReady(),
|
|
129
|
+
getReferralLink: () => {
|
|
130
|
+
try {
|
|
131
|
+
return import_core3.GrowthRail.getReferralLink();
|
|
132
|
+
} catch {
|
|
133
|
+
return "";
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
const experience = {
|
|
138
|
+
trigger: user.referrerExperience.trigger,
|
|
139
|
+
modal: {
|
|
140
|
+
...user.referrerExperience.modal,
|
|
141
|
+
...title ? { title } : {},
|
|
142
|
+
...appearance
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
modalRef.current = new import_core3.ReferralModal(deps, experience);
|
|
146
|
+
modalRef.current.show(appearance, containerRef.current);
|
|
147
|
+
}).catch((err) => {
|
|
148
|
+
console.error("GrowthRail: User initialization failed", err);
|
|
149
|
+
});
|
|
150
|
+
return () => {
|
|
151
|
+
mounted = false;
|
|
152
|
+
if (modalRef.current) {
|
|
153
|
+
modalRef.current.hide();
|
|
154
|
+
modalRef.current = null;
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
}, [title, appearance]);
|
|
158
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
159
|
+
"div",
|
|
160
|
+
{
|
|
161
|
+
ref: containerRef,
|
|
162
|
+
style: {
|
|
163
|
+
width: "100%",
|
|
164
|
+
height: "100%",
|
|
165
|
+
minHeight: "400px",
|
|
166
|
+
position: "relative"
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
);
|
|
170
|
+
};
|
|
171
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
172
|
+
0 && (module.exports = {
|
|
173
|
+
GrowthRailProvider,
|
|
174
|
+
ReferralDashboard,
|
|
175
|
+
useGrowthRail
|
|
176
|
+
});
|
|
177
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.tsx","../src/GrowthRailProvider.tsx","../src/useGrowthRail.ts","../src/ReferralDashboard.tsx"],"sourcesContent":["export { GrowthRailProvider } from './GrowthRailProvider';\nexport { useGrowthRail, type UseGrowthRailReturn } from './useGrowthRail';\nexport { \n ReferralDashboard, \n type ReferralDashboardProps,\n} from './ReferralDashboard';\n\nexport type { GrowthRailOptions, AppUserType } from '@growth-rail/core';\n","import React, { useEffect, useRef, useState, ReactNode } from 'react';\nimport { GrowthRail, GrowthRailOptions } from '@growth-rail/core';\n\ninterface GrowthRailProviderProps extends GrowthRailOptions {\n userId?: string;\n children: ReactNode;\n}\n\nexport const GrowthRailProvider: React.FC<GrowthRailProviderProps> = ({ \n children, \n userId,\n ...options \n}) => {\n const [isReady, setIsReady] = useState(GrowthRail.isInitialized());\n const initialized = useRef(false);\n\n useEffect(() => {\n if (initialized.current) return;\n initialized.current = true;\n\n GrowthRail.init(options);\n if (userId) {\n GrowthRail.initAppUser(userId).catch(console.error);\n }\n setIsReady(true);\n }, []);\n\n useEffect(() => {\n if (initialized.current && userId && GrowthRail.getUserId() !== userId) {\n GrowthRail.initAppUser(userId).catch(console.error);\n }\n }, [userId]);\n\n if (!isReady) return null;\n\n return <>{children}</>;\n};\n","import { useState, useCallback } from 'react';\nimport { GrowthRail, AppUserType, ReferrerTriggerButton } from '@growth-rail/core';\n\nexport interface UseGrowthRailReturn {\n initUser: (userId: string) => Promise<AppUserType>;\n trackReward: (eventName?: string) => Promise<void>;\n showReferralDashboard: (options?: Parameters<typeof GrowthRail.showReferralDashboard>[0]) => void;\n showFloatingButton: (options: Partial<ReferrerTriggerButton>) => void;\n hideFloatingButton: () => void;\n isLoading: boolean;\n error: Error | null;\n}\n\nexport const useGrowthRail = (): UseGrowthRailReturn => {\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const initUser = useCallback(async (userId: string) => {\n setIsLoading(true);\n setError(null);\n try {\n const user = await GrowthRail.initAppUser(userId);\n return user;\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n throw error;\n } finally {\n setIsLoading(false);\n }\n }, []);\n\n const trackReward = useCallback(async (eventName?: string) => {\n setIsLoading(true);\n setError(null);\n try {\n await GrowthRail.trackRewardEvent(eventName);\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n throw error;\n } finally {\n setIsLoading(false);\n }\n }, []);\n\n const showReferralDashboard = useCallback((options?: Parameters<typeof GrowthRail.showReferralDashboard>[0]) => {\n GrowthRail.showReferralDashboard(options);\n }, []);\n\n const showFloatingButton = useCallback((options: Partial<ReferrerTriggerButton>) => {\n GrowthRail.createTriggerButton(options);\n }, []);\n\n const hideFloatingButton = useCallback(() => {\n GrowthRail.destroyTriggerButton();\n }, []);\n\n return {\n initUser,\n trackReward,\n showReferralDashboard,\n showFloatingButton,\n hideFloatingButton,\n isLoading,\n error,\n };\n};\n","import React, { useEffect, useRef } from 'react';\nimport { GrowthRail, ReferrerModalOptions, ReferralModal, ReferrerExperience } from '@growth-rail/core';\n\nexport interface ReferralDashboardProps {\n title?: string;\n appearance?: ReferrerModalOptions;\n onLinkCopied?: () => void;\n}\n\nexport const ReferralDashboard: React.FC<ReferralDashboardProps> = ({\n title,\n appearance = {},\n onLinkCopied,\n}) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const modalRef = useRef<ReferralModal | null>(null);\n\n useEffect(() => {\n let mounted = true;\n if (!containerRef.current) return;\n\n GrowthRail.ensureUserReady().then((user) => {\n if (!mounted || !containerRef.current) return;\n\n const deps = {\n isUserReady: () => GrowthRail.isUserReady(),\n getReferralLink: () => {\n try {\n return GrowthRail.getReferralLink();\n } catch {\n return '';\n }\n },\n };\n\n // Construct experience config directly from BE\n const experience: ReferrerExperience = {\n trigger: user.referrerExperience.trigger,\n modal: {\n ...user.referrerExperience.modal,\n ...(title ? { title } : {}),\n ...appearance,\n },\n };\n\n modalRef.current = new ReferralModal(deps, experience);\n modalRef.current.show(appearance, containerRef.current);\n }).catch((err) => {\n console.error('GrowthRail: User initialization failed', err);\n });\n\n return () => {\n mounted = false;\n if (modalRef.current) {\n modalRef.current.hide();\n modalRef.current = null;\n }\n };\n }, [title, appearance]);\n\n return (\n <div \n ref={containerRef} \n style={{ \n width: '100%', \n height: '100%', \n minHeight: '400px',\n position: 'relative' \n }} \n />\n );\n};\n"],"mappings":"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","names":["import_react","import_core","error","import_react","import_core","import_jsx_runtime"]}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
// src/GrowthRailProvider.tsx
|
|
2
|
+
import { useEffect, useRef, useState } from "react";
|
|
3
|
+
import { GrowthRail } from "@growth-rail/core";
|
|
4
|
+
import { Fragment, jsx } from "react/jsx-runtime";
|
|
5
|
+
var GrowthRailProvider = ({
|
|
6
|
+
children,
|
|
7
|
+
userId,
|
|
8
|
+
...options
|
|
9
|
+
}) => {
|
|
10
|
+
const [isReady, setIsReady] = useState(GrowthRail.isInitialized());
|
|
11
|
+
const initialized = useRef(false);
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
if (initialized.current) return;
|
|
14
|
+
initialized.current = true;
|
|
15
|
+
GrowthRail.init(options);
|
|
16
|
+
if (userId) {
|
|
17
|
+
GrowthRail.initAppUser(userId).catch(console.error);
|
|
18
|
+
}
|
|
19
|
+
setIsReady(true);
|
|
20
|
+
}, []);
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
if (initialized.current && userId && GrowthRail.getUserId() !== userId) {
|
|
23
|
+
GrowthRail.initAppUser(userId).catch(console.error);
|
|
24
|
+
}
|
|
25
|
+
}, [userId]);
|
|
26
|
+
if (!isReady) return null;
|
|
27
|
+
return /* @__PURE__ */ jsx(Fragment, { children });
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
// src/useGrowthRail.ts
|
|
31
|
+
import { useState as useState2, useCallback } from "react";
|
|
32
|
+
import { GrowthRail as GrowthRail2 } from "@growth-rail/core";
|
|
33
|
+
var useGrowthRail = () => {
|
|
34
|
+
const [isLoading, setIsLoading] = useState2(false);
|
|
35
|
+
const [error, setError] = useState2(null);
|
|
36
|
+
const initUser = useCallback(async (userId) => {
|
|
37
|
+
setIsLoading(true);
|
|
38
|
+
setError(null);
|
|
39
|
+
try {
|
|
40
|
+
const user = await GrowthRail2.initAppUser(userId);
|
|
41
|
+
return user;
|
|
42
|
+
} catch (err) {
|
|
43
|
+
const error2 = err instanceof Error ? err : new Error(String(err));
|
|
44
|
+
setError(error2);
|
|
45
|
+
throw error2;
|
|
46
|
+
} finally {
|
|
47
|
+
setIsLoading(false);
|
|
48
|
+
}
|
|
49
|
+
}, []);
|
|
50
|
+
const trackReward = useCallback(async (eventName) => {
|
|
51
|
+
setIsLoading(true);
|
|
52
|
+
setError(null);
|
|
53
|
+
try {
|
|
54
|
+
await GrowthRail2.trackRewardEvent(eventName);
|
|
55
|
+
} catch (err) {
|
|
56
|
+
const error2 = err instanceof Error ? err : new Error(String(err));
|
|
57
|
+
setError(error2);
|
|
58
|
+
throw error2;
|
|
59
|
+
} finally {
|
|
60
|
+
setIsLoading(false);
|
|
61
|
+
}
|
|
62
|
+
}, []);
|
|
63
|
+
const showReferralDashboard = useCallback((options) => {
|
|
64
|
+
GrowthRail2.showReferralDashboard(options);
|
|
65
|
+
}, []);
|
|
66
|
+
const showFloatingButton = useCallback((options) => {
|
|
67
|
+
GrowthRail2.createTriggerButton(options);
|
|
68
|
+
}, []);
|
|
69
|
+
const hideFloatingButton = useCallback(() => {
|
|
70
|
+
GrowthRail2.destroyTriggerButton();
|
|
71
|
+
}, []);
|
|
72
|
+
return {
|
|
73
|
+
initUser,
|
|
74
|
+
trackReward,
|
|
75
|
+
showReferralDashboard,
|
|
76
|
+
showFloatingButton,
|
|
77
|
+
hideFloatingButton,
|
|
78
|
+
isLoading,
|
|
79
|
+
error
|
|
80
|
+
};
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
// src/ReferralDashboard.tsx
|
|
84
|
+
import { useEffect as useEffect2, useRef as useRef2 } from "react";
|
|
85
|
+
import { GrowthRail as GrowthRail3, ReferralModal } from "@growth-rail/core";
|
|
86
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
87
|
+
var ReferralDashboard = ({
|
|
88
|
+
title,
|
|
89
|
+
appearance = {},
|
|
90
|
+
onLinkCopied
|
|
91
|
+
}) => {
|
|
92
|
+
const containerRef = useRef2(null);
|
|
93
|
+
const modalRef = useRef2(null);
|
|
94
|
+
useEffect2(() => {
|
|
95
|
+
let mounted = true;
|
|
96
|
+
if (!containerRef.current) return;
|
|
97
|
+
GrowthRail3.ensureUserReady().then((user) => {
|
|
98
|
+
if (!mounted || !containerRef.current) return;
|
|
99
|
+
const deps = {
|
|
100
|
+
isUserReady: () => GrowthRail3.isUserReady(),
|
|
101
|
+
getReferralLink: () => {
|
|
102
|
+
try {
|
|
103
|
+
return GrowthRail3.getReferralLink();
|
|
104
|
+
} catch {
|
|
105
|
+
return "";
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
const experience = {
|
|
110
|
+
trigger: user.referrerExperience.trigger,
|
|
111
|
+
modal: {
|
|
112
|
+
...user.referrerExperience.modal,
|
|
113
|
+
...title ? { title } : {},
|
|
114
|
+
...appearance
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
modalRef.current = new ReferralModal(deps, experience);
|
|
118
|
+
modalRef.current.show(appearance, containerRef.current);
|
|
119
|
+
}).catch((err) => {
|
|
120
|
+
console.error("GrowthRail: User initialization failed", err);
|
|
121
|
+
});
|
|
122
|
+
return () => {
|
|
123
|
+
mounted = false;
|
|
124
|
+
if (modalRef.current) {
|
|
125
|
+
modalRef.current.hide();
|
|
126
|
+
modalRef.current = null;
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
}, [title, appearance]);
|
|
130
|
+
return /* @__PURE__ */ jsx2(
|
|
131
|
+
"div",
|
|
132
|
+
{
|
|
133
|
+
ref: containerRef,
|
|
134
|
+
style: {
|
|
135
|
+
width: "100%",
|
|
136
|
+
height: "100%",
|
|
137
|
+
minHeight: "400px",
|
|
138
|
+
position: "relative"
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
);
|
|
142
|
+
};
|
|
143
|
+
export {
|
|
144
|
+
GrowthRailProvider,
|
|
145
|
+
ReferralDashboard,
|
|
146
|
+
useGrowthRail
|
|
147
|
+
};
|
|
148
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/GrowthRailProvider.tsx","../src/useGrowthRail.ts","../src/ReferralDashboard.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState, ReactNode } from 'react';\nimport { GrowthRail, GrowthRailOptions } from '@growth-rail/core';\n\ninterface GrowthRailProviderProps extends GrowthRailOptions {\n userId?: string;\n children: ReactNode;\n}\n\nexport const GrowthRailProvider: React.FC<GrowthRailProviderProps> = ({ \n children, \n userId,\n ...options \n}) => {\n const [isReady, setIsReady] = useState(GrowthRail.isInitialized());\n const initialized = useRef(false);\n\n useEffect(() => {\n if (initialized.current) return;\n initialized.current = true;\n\n GrowthRail.init(options);\n if (userId) {\n GrowthRail.initAppUser(userId).catch(console.error);\n }\n setIsReady(true);\n }, []);\n\n useEffect(() => {\n if (initialized.current && userId && GrowthRail.getUserId() !== userId) {\n GrowthRail.initAppUser(userId).catch(console.error);\n }\n }, [userId]);\n\n if (!isReady) return null;\n\n return <>{children}</>;\n};\n","import { useState, useCallback } from 'react';\nimport { GrowthRail, AppUserType, ReferrerTriggerButton } from '@growth-rail/core';\n\nexport interface UseGrowthRailReturn {\n initUser: (userId: string) => Promise<AppUserType>;\n trackReward: (eventName?: string) => Promise<void>;\n showReferralDashboard: (options?: Parameters<typeof GrowthRail.showReferralDashboard>[0]) => void;\n showFloatingButton: (options: Partial<ReferrerTriggerButton>) => void;\n hideFloatingButton: () => void;\n isLoading: boolean;\n error: Error | null;\n}\n\nexport const useGrowthRail = (): UseGrowthRailReturn => {\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const initUser = useCallback(async (userId: string) => {\n setIsLoading(true);\n setError(null);\n try {\n const user = await GrowthRail.initAppUser(userId);\n return user;\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n throw error;\n } finally {\n setIsLoading(false);\n }\n }, []);\n\n const trackReward = useCallback(async (eventName?: string) => {\n setIsLoading(true);\n setError(null);\n try {\n await GrowthRail.trackRewardEvent(eventName);\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n throw error;\n } finally {\n setIsLoading(false);\n }\n }, []);\n\n const showReferralDashboard = useCallback((options?: Parameters<typeof GrowthRail.showReferralDashboard>[0]) => {\n GrowthRail.showReferralDashboard(options);\n }, []);\n\n const showFloatingButton = useCallback((options: Partial<ReferrerTriggerButton>) => {\n GrowthRail.createTriggerButton(options);\n }, []);\n\n const hideFloatingButton = useCallback(() => {\n GrowthRail.destroyTriggerButton();\n }, []);\n\n return {\n initUser,\n trackReward,\n showReferralDashboard,\n showFloatingButton,\n hideFloatingButton,\n isLoading,\n error,\n };\n};\n","import React, { useEffect, useRef } from 'react';\nimport { GrowthRail, ReferrerModalOptions, ReferralModal, ReferrerExperience } from '@growth-rail/core';\n\nexport interface ReferralDashboardProps {\n title?: string;\n appearance?: ReferrerModalOptions;\n onLinkCopied?: () => void;\n}\n\nexport const ReferralDashboard: React.FC<ReferralDashboardProps> = ({\n title,\n appearance = {},\n onLinkCopied,\n}) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const modalRef = useRef<ReferralModal | null>(null);\n\n useEffect(() => {\n let mounted = true;\n if (!containerRef.current) return;\n\n GrowthRail.ensureUserReady().then((user) => {\n if (!mounted || !containerRef.current) return;\n\n const deps = {\n isUserReady: () => GrowthRail.isUserReady(),\n getReferralLink: () => {\n try {\n return GrowthRail.getReferralLink();\n } catch {\n return '';\n }\n },\n };\n\n // Construct experience config directly from BE\n const experience: ReferrerExperience = {\n trigger: user.referrerExperience.trigger,\n modal: {\n ...user.referrerExperience.modal,\n ...(title ? { title } : {}),\n ...appearance,\n },\n };\n\n modalRef.current = new ReferralModal(deps, experience);\n modalRef.current.show(appearance, containerRef.current);\n }).catch((err) => {\n console.error('GrowthRail: User initialization failed', err);\n });\n\n return () => {\n mounted = false;\n if (modalRef.current) {\n modalRef.current.hide();\n modalRef.current = null;\n }\n };\n }, [title, appearance]);\n\n return (\n <div \n ref={containerRef} \n style={{ \n width: '100%', \n height: '100%', \n minHeight: '400px',\n position: 'relative' \n }} \n />\n );\n};\n"],"mappings":"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","names":["useState","GrowthRail","error","useEffect","useRef","GrowthRail","jsx"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@growth-rail/react",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "Growth Rail React SDK",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.mjs",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"require": "./dist/index.js",
|
|
12
|
+
"import": "./dist/index.mjs"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "tsup",
|
|
20
|
+
"dev": "tsup --watch",
|
|
21
|
+
"lint": "eslint src/",
|
|
22
|
+
"test": "vitest run",
|
|
23
|
+
"type-check": "tsc --noEmit"
|
|
24
|
+
},
|
|
25
|
+
"peerDependencies": {
|
|
26
|
+
"react": ">=16.8"
|
|
27
|
+
},
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"@growth-rail/core": "workspace:*"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@growth-rail/eslint-config": "*",
|
|
33
|
+
"@growth-rail/tsconfig": "*",
|
|
34
|
+
"@testing-library/dom": "^10.0.0",
|
|
35
|
+
"@testing-library/react": "^16.2.0",
|
|
36
|
+
"@types/react": "^18.0.0",
|
|
37
|
+
"jsdom": "^26.0.0",
|
|
38
|
+
"react": "^18.0.0",
|
|
39
|
+
"tsup": "^8.0.0",
|
|
40
|
+
"typescript": "^5.0.0",
|
|
41
|
+
"vitest": "^1.0.0"
|
|
42
|
+
},
|
|
43
|
+
"publishConfig": {
|
|
44
|
+
"access": "public"
|
|
45
|
+
}
|
|
46
|
+
}
|