react-native-codepush-sdk 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/LICENSE +21 -0
- package/README.md +278 -0
- package/dist/hooks/useFrameworkReady.js +11 -0
- package/dist/index.js +36 -0
- package/dist/services/codepushService.js +164 -0
- package/dist/src/components/UpdateChecker.js +230 -0
- package/dist/src/sdk/CodePushProvider.js +181 -0
- package/dist/src/sdk/CustomCodePush.js +405 -0
- package/dist/src/utils/BundleManager.js +124 -0
- package/dist/types/codepush.js +2 -0
- package/hooks/useFrameworkReady.ts +17 -0
- package/index.ts +10 -0
- package/package.json +72 -0
- package/services/codepushService.ts +181 -0
- package/src/components/UpdateChecker.tsx +303 -0
- package/src/sdk/CodePushProvider.tsx +184 -0
- package/src/sdk/CustomCodePush.ts +526 -0
- package/src/utils/BundleManager.ts +140 -0
- package/types/codepush.ts +44 -0
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const react_1 = __importDefault(require("react"));
|
|
7
|
+
const react_native_1 = require("react-native");
|
|
8
|
+
const CodePushProvider_1 = require("../sdk/CodePushProvider");
|
|
9
|
+
const UpdateChecker = () => {
|
|
10
|
+
const { currentUpdate, availableUpdate, syncStatus, isChecking, isDownloading, isInstalling, checkForUpdate, syncUpdate, rollback, clearUpdates, } = (0, CodePushProvider_1.useCodePush)();
|
|
11
|
+
const getStatusMessage = () => {
|
|
12
|
+
if (isChecking)
|
|
13
|
+
return 'Checking for updates...';
|
|
14
|
+
if (isDownloading)
|
|
15
|
+
return 'Downloading update...';
|
|
16
|
+
if (isInstalling)
|
|
17
|
+
return 'Installing update...';
|
|
18
|
+
if (availableUpdate)
|
|
19
|
+
return 'Update available!';
|
|
20
|
+
return 'App is up to date';
|
|
21
|
+
};
|
|
22
|
+
const getStatusColor = () => {
|
|
23
|
+
if (isChecking || isDownloading || isInstalling)
|
|
24
|
+
return '#007bff';
|
|
25
|
+
if (availableUpdate)
|
|
26
|
+
return '#ffc107';
|
|
27
|
+
return '#28a745';
|
|
28
|
+
};
|
|
29
|
+
const handleRollback = () => {
|
|
30
|
+
react_native_1.Alert.alert('Rollback Update', 'Are you sure you want to rollback to the previous version? This will restart the app.', [
|
|
31
|
+
{ text: 'Cancel', style: 'cancel' },
|
|
32
|
+
{ text: 'Rollback', style: 'destructive', onPress: rollback },
|
|
33
|
+
]);
|
|
34
|
+
};
|
|
35
|
+
const handleClearUpdates = () => {
|
|
36
|
+
react_native_1.Alert.alert('Clear Updates', 'This will remove all downloaded updates and reset to the original app version.', [
|
|
37
|
+
{ text: 'Cancel', style: 'cancel' },
|
|
38
|
+
{ text: 'Clear', style: 'destructive', onPress: clearUpdates },
|
|
39
|
+
]);
|
|
40
|
+
};
|
|
41
|
+
const formatBytes = (bytes) => {
|
|
42
|
+
if (bytes === 0)
|
|
43
|
+
return '0 Bytes';
|
|
44
|
+
const k = 1024;
|
|
45
|
+
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
|
|
46
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
47
|
+
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
|
|
48
|
+
};
|
|
49
|
+
return (react_1.default.createElement(react_native_1.View, { style: styles.container },
|
|
50
|
+
react_1.default.createElement(react_native_1.View, { style: styles.header },
|
|
51
|
+
react_1.default.createElement(react_native_1.Text, { style: styles.title }, "Custom CodePush"),
|
|
52
|
+
react_1.default.createElement(react_native_1.Text, { style: styles.subtitle }, "Over-the-Air Updates")),
|
|
53
|
+
react_1.default.createElement(react_native_1.View, { style: [styles.statusCard, { borderLeftColor: getStatusColor() }] },
|
|
54
|
+
react_1.default.createElement(react_native_1.View, { style: styles.statusHeader },
|
|
55
|
+
react_1.default.createElement(react_native_1.Text, { style: [styles.statusText, { color: getStatusColor() }] }, getStatusMessage()),
|
|
56
|
+
(isChecking || isDownloading || isInstalling) && (react_1.default.createElement(react_native_1.ActivityIndicator, { size: "small", color: getStatusColor() }))),
|
|
57
|
+
(syncStatus === null || syncStatus === void 0 ? void 0 : syncStatus.progress) !== undefined && (react_1.default.createElement(react_native_1.View, { style: styles.progressContainer },
|
|
58
|
+
react_1.default.createElement(react_native_1.View, { style: styles.progressBar },
|
|
59
|
+
react_1.default.createElement(react_native_1.View, { style: [
|
|
60
|
+
styles.progressFill,
|
|
61
|
+
{
|
|
62
|
+
width: `${syncStatus.progress}%`,
|
|
63
|
+
backgroundColor: getStatusColor(),
|
|
64
|
+
},
|
|
65
|
+
] })),
|
|
66
|
+
react_1.default.createElement(react_native_1.Text, { style: styles.progressText },
|
|
67
|
+
Math.round(syncStatus.progress),
|
|
68
|
+
"%")))),
|
|
69
|
+
currentUpdate && (react_1.default.createElement(react_native_1.View, { style: styles.infoCard },
|
|
70
|
+
react_1.default.createElement(react_native_1.Text, { style: styles.cardTitle }, "Current Version"),
|
|
71
|
+
react_1.default.createElement(react_native_1.Text, { style: styles.infoText },
|
|
72
|
+
"Label: ",
|
|
73
|
+
currentUpdate.label),
|
|
74
|
+
react_1.default.createElement(react_native_1.Text, { style: styles.infoText },
|
|
75
|
+
"Version: ",
|
|
76
|
+
currentUpdate.appVersion),
|
|
77
|
+
react_1.default.createElement(react_native_1.Text, { style: styles.infoText },
|
|
78
|
+
"Hash: ",
|
|
79
|
+
currentUpdate.packageHash.substring(0, 8),
|
|
80
|
+
"..."),
|
|
81
|
+
react_1.default.createElement(react_native_1.Text, { style: styles.infoText },
|
|
82
|
+
"Size: ",
|
|
83
|
+
formatBytes(currentUpdate.packageSize)),
|
|
84
|
+
currentUpdate.description && (react_1.default.createElement(react_native_1.Text, { style: styles.infoDescription }, currentUpdate.description)))),
|
|
85
|
+
availableUpdate && (react_1.default.createElement(react_native_1.View, { style: styles.infoCard },
|
|
86
|
+
react_1.default.createElement(react_native_1.Text, { style: styles.cardTitle }, "Available Update"),
|
|
87
|
+
react_1.default.createElement(react_native_1.Text, { style: styles.infoText },
|
|
88
|
+
"Label: ",
|
|
89
|
+
availableUpdate.label),
|
|
90
|
+
react_1.default.createElement(react_native_1.Text, { style: styles.infoText },
|
|
91
|
+
"Version: ",
|
|
92
|
+
availableUpdate.appVersion),
|
|
93
|
+
react_1.default.createElement(react_native_1.Text, { style: styles.infoText },
|
|
94
|
+
"Size: ",
|
|
95
|
+
formatBytes(availableUpdate.packageSize)),
|
|
96
|
+
react_1.default.createElement(react_native_1.Text, { style: [
|
|
97
|
+
styles.infoText,
|
|
98
|
+
{ color: availableUpdate.isMandatory ? '#dc3545' : '#28a745' }
|
|
99
|
+
] }, availableUpdate.isMandatory ? 'Mandatory Update' : 'Optional Update'),
|
|
100
|
+
availableUpdate.description && (react_1.default.createElement(react_native_1.Text, { style: styles.infoDescription }, availableUpdate.description)))),
|
|
101
|
+
react_1.default.createElement(react_native_1.View, { style: styles.buttonContainer },
|
|
102
|
+
react_1.default.createElement(react_native_1.TouchableOpacity, { style: [styles.button, styles.primaryButton], onPress: checkForUpdate, disabled: isChecking },
|
|
103
|
+
react_1.default.createElement(react_native_1.Text, { style: styles.buttonText }, "Check for Updates")),
|
|
104
|
+
availableUpdate && (react_1.default.createElement(react_native_1.TouchableOpacity, { style: [styles.button, styles.successButton], onPress: syncUpdate, disabled: isDownloading || isInstalling },
|
|
105
|
+
react_1.default.createElement(react_native_1.Text, { style: styles.buttonText }, availableUpdate.isMandatory ? 'Install Now (Required)' : 'Install Update'))),
|
|
106
|
+
currentUpdate && (react_1.default.createElement(react_native_1.TouchableOpacity, { style: [styles.button, styles.warningButton], onPress: handleRollback, disabled: isDownloading || isInstalling },
|
|
107
|
+
react_1.default.createElement(react_native_1.Text, { style: styles.buttonText }, "Rollback"))),
|
|
108
|
+
react_1.default.createElement(react_native_1.TouchableOpacity, { style: [styles.button, styles.dangerButton], onPress: handleClearUpdates, disabled: isDownloading || isInstalling },
|
|
109
|
+
react_1.default.createElement(react_native_1.Text, { style: styles.buttonText }, "Clear All Updates")))));
|
|
110
|
+
};
|
|
111
|
+
const styles = react_native_1.StyleSheet.create({
|
|
112
|
+
container: {
|
|
113
|
+
flex: 1,
|
|
114
|
+
padding: 20,
|
|
115
|
+
backgroundColor: '#f8f9fa',
|
|
116
|
+
},
|
|
117
|
+
header: {
|
|
118
|
+
alignItems: 'center',
|
|
119
|
+
marginBottom: 30,
|
|
120
|
+
},
|
|
121
|
+
title: {
|
|
122
|
+
fontSize: 28,
|
|
123
|
+
fontWeight: 'bold',
|
|
124
|
+
color: '#212529',
|
|
125
|
+
marginBottom: 8,
|
|
126
|
+
},
|
|
127
|
+
subtitle: {
|
|
128
|
+
fontSize: 16,
|
|
129
|
+
color: '#6c757d',
|
|
130
|
+
},
|
|
131
|
+
statusCard: {
|
|
132
|
+
backgroundColor: '#ffffff',
|
|
133
|
+
borderRadius: 8,
|
|
134
|
+
padding: 20,
|
|
135
|
+
marginBottom: 20,
|
|
136
|
+
borderLeftWidth: 4,
|
|
137
|
+
shadowColor: '#000',
|
|
138
|
+
shadowOffset: { width: 0, height: 2 },
|
|
139
|
+
shadowOpacity: 0.1,
|
|
140
|
+
shadowRadius: 4,
|
|
141
|
+
elevation: 3,
|
|
142
|
+
},
|
|
143
|
+
statusHeader: {
|
|
144
|
+
flexDirection: 'row',
|
|
145
|
+
justifyContent: 'space-between',
|
|
146
|
+
alignItems: 'center',
|
|
147
|
+
},
|
|
148
|
+
statusText: {
|
|
149
|
+
fontSize: 18,
|
|
150
|
+
fontWeight: '600',
|
|
151
|
+
},
|
|
152
|
+
progressContainer: {
|
|
153
|
+
marginTop: 15,
|
|
154
|
+
flexDirection: 'row',
|
|
155
|
+
alignItems: 'center',
|
|
156
|
+
},
|
|
157
|
+
progressBar: {
|
|
158
|
+
flex: 1,
|
|
159
|
+
height: 8,
|
|
160
|
+
backgroundColor: '#e9ecef',
|
|
161
|
+
borderRadius: 4,
|
|
162
|
+
marginRight: 10,
|
|
163
|
+
},
|
|
164
|
+
progressFill: {
|
|
165
|
+
height: '100%',
|
|
166
|
+
borderRadius: 4,
|
|
167
|
+
},
|
|
168
|
+
progressText: {
|
|
169
|
+
fontSize: 14,
|
|
170
|
+
fontWeight: '500',
|
|
171
|
+
color: '#495057',
|
|
172
|
+
minWidth: 40,
|
|
173
|
+
},
|
|
174
|
+
infoCard: {
|
|
175
|
+
backgroundColor: '#ffffff',
|
|
176
|
+
borderRadius: 8,
|
|
177
|
+
padding: 16,
|
|
178
|
+
marginBottom: 16,
|
|
179
|
+
shadowColor: '#000',
|
|
180
|
+
shadowOffset: { width: 0, height: 1 },
|
|
181
|
+
shadowOpacity: 0.1,
|
|
182
|
+
shadowRadius: 2,
|
|
183
|
+
elevation: 2,
|
|
184
|
+
},
|
|
185
|
+
cardTitle: {
|
|
186
|
+
fontSize: 18,
|
|
187
|
+
fontWeight: '600',
|
|
188
|
+
color: '#212529',
|
|
189
|
+
marginBottom: 12,
|
|
190
|
+
},
|
|
191
|
+
infoText: {
|
|
192
|
+
fontSize: 14,
|
|
193
|
+
color: '#495057',
|
|
194
|
+
marginBottom: 4,
|
|
195
|
+
},
|
|
196
|
+
infoDescription: {
|
|
197
|
+
fontSize: 14,
|
|
198
|
+
color: '#6c757d',
|
|
199
|
+
marginTop: 8,
|
|
200
|
+
fontStyle: 'italic',
|
|
201
|
+
},
|
|
202
|
+
buttonContainer: {
|
|
203
|
+
marginTop: 20,
|
|
204
|
+
},
|
|
205
|
+
button: {
|
|
206
|
+
paddingVertical: 12,
|
|
207
|
+
paddingHorizontal: 20,
|
|
208
|
+
borderRadius: 8,
|
|
209
|
+
marginBottom: 12,
|
|
210
|
+
alignItems: 'center',
|
|
211
|
+
},
|
|
212
|
+
primaryButton: {
|
|
213
|
+
backgroundColor: '#007bff',
|
|
214
|
+
},
|
|
215
|
+
successButton: {
|
|
216
|
+
backgroundColor: '#28a745',
|
|
217
|
+
},
|
|
218
|
+
warningButton: {
|
|
219
|
+
backgroundColor: '#ffc107',
|
|
220
|
+
},
|
|
221
|
+
dangerButton: {
|
|
222
|
+
backgroundColor: '#dc3545',
|
|
223
|
+
},
|
|
224
|
+
buttonText: {
|
|
225
|
+
color: '#ffffff',
|
|
226
|
+
fontSize: 16,
|
|
227
|
+
fontWeight: '600',
|
|
228
|
+
},
|
|
229
|
+
});
|
|
230
|
+
exports.default = UpdateChecker;
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.useCodePush = exports.CodePushProvider = void 0;
|
|
40
|
+
const react_1 = __importStar(require("react"));
|
|
41
|
+
const react_native_1 = require("react-native");
|
|
42
|
+
const CustomCodePush_1 = __importDefault(require("./CustomCodePush"));
|
|
43
|
+
const CodePushContext = (0, react_1.createContext)(undefined);
|
|
44
|
+
const CodePushProvider = ({ children, config, autoCheck = true, checkOnResume = true, }) => {
|
|
45
|
+
const [codePush] = (0, react_1.useState)(() => new CustomCodePush_1.default(config));
|
|
46
|
+
const [currentUpdate, setCurrentUpdate] = (0, react_1.useState)(null);
|
|
47
|
+
const [availableUpdate, setAvailableUpdate] = (0, react_1.useState)(null);
|
|
48
|
+
const [syncStatus, setSyncStatus] = (0, react_1.useState)(null);
|
|
49
|
+
const [isChecking, setIsChecking] = (0, react_1.useState)(false);
|
|
50
|
+
const [isDownloading, setIsDownloading] = (0, react_1.useState)(false);
|
|
51
|
+
const [isInstalling, setIsInstalling] = (0, react_1.useState)(false);
|
|
52
|
+
(0, react_1.useEffect)(() => {
|
|
53
|
+
// Wait for SDK to initialize (load stored package) before updating state
|
|
54
|
+
codePush.initialize()
|
|
55
|
+
.then(async () => {
|
|
56
|
+
await loadCurrentUpdate();
|
|
57
|
+
if (autoCheck) {
|
|
58
|
+
await checkForUpdate();
|
|
59
|
+
}
|
|
60
|
+
})
|
|
61
|
+
.catch(error => {
|
|
62
|
+
console.error('Error initializing CodePush SDK:', error);
|
|
63
|
+
});
|
|
64
|
+
// Set up app state listener for resume checks
|
|
65
|
+
if (checkOnResume) {
|
|
66
|
+
const handleAppStateChange = (nextAppState) => {
|
|
67
|
+
if (nextAppState === 'active') {
|
|
68
|
+
checkForUpdate();
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
const subscription = react_native_1.AppState.addEventListener('change', handleAppStateChange);
|
|
72
|
+
return () => subscription === null || subscription === void 0 ? void 0 : subscription.remove();
|
|
73
|
+
}
|
|
74
|
+
}, []);
|
|
75
|
+
const loadCurrentUpdate = async () => {
|
|
76
|
+
try {
|
|
77
|
+
const current = await codePush.getCurrentPackage();
|
|
78
|
+
setCurrentUpdate(current);
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
console.error('Failed to load current update:', error);
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
const checkForUpdate = async () => {
|
|
85
|
+
if (isChecking)
|
|
86
|
+
return;
|
|
87
|
+
setIsChecking(true);
|
|
88
|
+
try {
|
|
89
|
+
const update = await codePush.checkForUpdate();
|
|
90
|
+
setAvailableUpdate(update);
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
console.error('Failed to check for update:', error);
|
|
94
|
+
}
|
|
95
|
+
finally {
|
|
96
|
+
setIsChecking(false);
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
const syncUpdate = async () => {
|
|
100
|
+
if (!availableUpdate || isDownloading || isInstalling)
|
|
101
|
+
return;
|
|
102
|
+
try {
|
|
103
|
+
const success = await codePush.sync({
|
|
104
|
+
installMode: 'ON_NEXT_RESTART',
|
|
105
|
+
mandatoryInstallMode: 'ON_NEXT_RESTART',
|
|
106
|
+
}, (status) => {
|
|
107
|
+
setSyncStatus(status);
|
|
108
|
+
switch (status.status) {
|
|
109
|
+
case 'DOWNLOADING_PACKAGE':
|
|
110
|
+
setIsDownloading(true);
|
|
111
|
+
setIsInstalling(false);
|
|
112
|
+
break;
|
|
113
|
+
case 'INSTALLING_UPDATE':
|
|
114
|
+
setIsDownloading(false);
|
|
115
|
+
setIsInstalling(true);
|
|
116
|
+
break;
|
|
117
|
+
case 'UPDATE_INSTALLED':
|
|
118
|
+
case 'UP_TO_DATE':
|
|
119
|
+
case 'UNKNOWN_ERROR':
|
|
120
|
+
setIsDownloading(false);
|
|
121
|
+
setIsInstalling(false);
|
|
122
|
+
break;
|
|
123
|
+
}
|
|
124
|
+
}, (progress) => {
|
|
125
|
+
// Handle download progress if needed
|
|
126
|
+
});
|
|
127
|
+
if (success) {
|
|
128
|
+
setAvailableUpdate(null);
|
|
129
|
+
await loadCurrentUpdate();
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
catch (error) {
|
|
133
|
+
console.error('Failed to sync update:', error);
|
|
134
|
+
setIsDownloading(false);
|
|
135
|
+
setIsInstalling(false);
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
const rollback = async () => {
|
|
139
|
+
try {
|
|
140
|
+
await codePush.rollback();
|
|
141
|
+
setCurrentUpdate(null);
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
console.error('Failed to rollback:', error);
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
const clearUpdates = async () => {
|
|
148
|
+
try {
|
|
149
|
+
await codePush.clearUpdates();
|
|
150
|
+
setCurrentUpdate(null);
|
|
151
|
+
setAvailableUpdate(null);
|
|
152
|
+
}
|
|
153
|
+
catch (error) {
|
|
154
|
+
console.error('Failed to clear updates:', error);
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
const contextValue = {
|
|
158
|
+
codePush,
|
|
159
|
+
currentUpdate,
|
|
160
|
+
availableUpdate,
|
|
161
|
+
syncStatus,
|
|
162
|
+
isChecking,
|
|
163
|
+
isDownloading,
|
|
164
|
+
isInstalling,
|
|
165
|
+
checkForUpdate,
|
|
166
|
+
syncUpdate,
|
|
167
|
+
rollback,
|
|
168
|
+
clearUpdates,
|
|
169
|
+
getBundleUrl: () => codePush.getBundleUrl(),
|
|
170
|
+
};
|
|
171
|
+
return (react_1.default.createElement(CodePushContext.Provider, { value: contextValue }, children));
|
|
172
|
+
};
|
|
173
|
+
exports.CodePushProvider = CodePushProvider;
|
|
174
|
+
const useCodePush = () => {
|
|
175
|
+
const context = (0, react_1.useContext)(CodePushContext);
|
|
176
|
+
if (context === undefined) {
|
|
177
|
+
throw new Error('useCodePush must be used within a CodePushProvider');
|
|
178
|
+
}
|
|
179
|
+
return context;
|
|
180
|
+
};
|
|
181
|
+
exports.useCodePush = useCodePush;
|