@vanikya/ota-react-native 0.1.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.
Files changed (51) hide show
  1. package/README.md +223 -0
  2. package/android/build.gradle +58 -0
  3. package/android/src/main/AndroidManifest.xml +4 -0
  4. package/android/src/main/java/com/otaupdate/OTAUpdateModule.kt +185 -0
  5. package/android/src/main/java/com/otaupdate/OTAUpdatePackage.kt +16 -0
  6. package/ios/OTAUpdate.m +61 -0
  7. package/ios/OTAUpdate.swift +194 -0
  8. package/lib/commonjs/OTAProvider.js +113 -0
  9. package/lib/commonjs/OTAProvider.js.map +1 -0
  10. package/lib/commonjs/hooks/useOTAUpdate.js +272 -0
  11. package/lib/commonjs/hooks/useOTAUpdate.js.map +1 -0
  12. package/lib/commonjs/index.js +98 -0
  13. package/lib/commonjs/index.js.map +1 -0
  14. package/lib/commonjs/utils/api.js +60 -0
  15. package/lib/commonjs/utils/api.js.map +1 -0
  16. package/lib/commonjs/utils/storage.js +209 -0
  17. package/lib/commonjs/utils/storage.js.map +1 -0
  18. package/lib/commonjs/utils/verification.js +145 -0
  19. package/lib/commonjs/utils/verification.js.map +1 -0
  20. package/lib/module/OTAProvider.js +104 -0
  21. package/lib/module/OTAProvider.js.map +1 -0
  22. package/lib/module/hooks/useOTAUpdate.js +266 -0
  23. package/lib/module/hooks/useOTAUpdate.js.map +1 -0
  24. package/lib/module/index.js +11 -0
  25. package/lib/module/index.js.map +1 -0
  26. package/lib/module/utils/api.js +52 -0
  27. package/lib/module/utils/api.js.map +1 -0
  28. package/lib/module/utils/storage.js +202 -0
  29. package/lib/module/utils/storage.js.map +1 -0
  30. package/lib/module/utils/verification.js +137 -0
  31. package/lib/module/utils/verification.js.map +1 -0
  32. package/lib/typescript/OTAProvider.d.ts +28 -0
  33. package/lib/typescript/OTAProvider.d.ts.map +1 -0
  34. package/lib/typescript/hooks/useOTAUpdate.d.ts +35 -0
  35. package/lib/typescript/hooks/useOTAUpdate.d.ts.map +1 -0
  36. package/lib/typescript/index.d.ts +12 -0
  37. package/lib/typescript/index.d.ts.map +1 -0
  38. package/lib/typescript/utils/api.d.ts +47 -0
  39. package/lib/typescript/utils/api.d.ts.map +1 -0
  40. package/lib/typescript/utils/storage.d.ts +32 -0
  41. package/lib/typescript/utils/storage.d.ts.map +1 -0
  42. package/lib/typescript/utils/verification.d.ts +11 -0
  43. package/lib/typescript/utils/verification.d.ts.map +1 -0
  44. package/ota-update.podspec +21 -0
  45. package/package.json +83 -0
  46. package/src/OTAProvider.tsx +160 -0
  47. package/src/hooks/useOTAUpdate.ts +344 -0
  48. package/src/index.ts +36 -0
  49. package/src/utils/api.ts +99 -0
  50. package/src/utils/storage.ts +249 -0
  51. package/src/utils/verification.ts +167 -0
@@ -0,0 +1,194 @@
1
+ import Foundation
2
+ import CommonCrypto
3
+
4
+ @objc(OTAUpdate)
5
+ class OTAUpdate: NSObject {
6
+
7
+ // MARK: - File System Operations
8
+
9
+ @objc
10
+ func getDocumentDirectory() -> String {
11
+ let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
12
+ return paths[0].path + "/"
13
+ }
14
+
15
+ @objc
16
+ func writeFile(_ path: String, content: String, resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) {
17
+ do {
18
+ try content.write(toFile: path, atomically: true, encoding: .utf8)
19
+ resolver(nil)
20
+ } catch {
21
+ rejecter("WRITE_ERROR", "Failed to write file: \(error.localizedDescription)", error)
22
+ }
23
+ }
24
+
25
+ @objc
26
+ func writeFileBase64(_ path: String, base64Content: String, resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) {
27
+ guard let data = Data(base64Encoded: base64Content) else {
28
+ rejecter("DECODE_ERROR", "Invalid base64 content", nil)
29
+ return
30
+ }
31
+
32
+ do {
33
+ try data.write(to: URL(fileURLWithPath: path))
34
+ resolver(nil)
35
+ } catch {
36
+ rejecter("WRITE_ERROR", "Failed to write file: \(error.localizedDescription)", error)
37
+ }
38
+ }
39
+
40
+ @objc
41
+ func readFile(_ path: String, resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) {
42
+ do {
43
+ let content = try String(contentsOfFile: path, encoding: .utf8)
44
+ resolver(content)
45
+ } catch {
46
+ rejecter("READ_ERROR", "Failed to read file: \(error.localizedDescription)", error)
47
+ }
48
+ }
49
+
50
+ @objc
51
+ func readFileBase64(_ path: String, resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) {
52
+ do {
53
+ let data = try Data(contentsOf: URL(fileURLWithPath: path))
54
+ let base64 = data.base64EncodedString()
55
+ resolver(base64)
56
+ } catch {
57
+ rejecter("READ_ERROR", "Failed to read file: \(error.localizedDescription)", error)
58
+ }
59
+ }
60
+
61
+ @objc
62
+ func deleteFile(_ path: String, resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) {
63
+ do {
64
+ if FileManager.default.fileExists(atPath: path) {
65
+ try FileManager.default.removeItem(atPath: path)
66
+ }
67
+ resolver(nil)
68
+ } catch {
69
+ rejecter("DELETE_ERROR", "Failed to delete file: \(error.localizedDescription)", error)
70
+ }
71
+ }
72
+
73
+ @objc
74
+ func exists(_ path: String, resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) {
75
+ resolver(FileManager.default.fileExists(atPath: path))
76
+ }
77
+
78
+ @objc
79
+ func makeDirectory(_ path: String, resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) {
80
+ do {
81
+ try FileManager.default.createDirectory(atPath: path, withIntermediateDirectories: true, attributes: nil)
82
+ resolver(nil)
83
+ } catch {
84
+ rejecter("MKDIR_ERROR", "Failed to create directory: \(error.localizedDescription)", error)
85
+ }
86
+ }
87
+
88
+ // MARK: - Cryptography
89
+
90
+ @objc
91
+ func calculateSHA256(_ base64Content: String, resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) {
92
+ guard let data = Data(base64Encoded: base64Content) else {
93
+ rejecter("DECODE_ERROR", "Invalid base64 content", nil)
94
+ return
95
+ }
96
+
97
+ var hash = [UInt8](repeating: 0, count: Int(CC_SHA256_DIGEST_LENGTH))
98
+ data.withUnsafeBytes {
99
+ _ = CC_SHA256($0.baseAddress, CC_LONG(data.count), &hash)
100
+ }
101
+
102
+ let hexString = hash.map { String(format: "%02x", $0) }.joined()
103
+ resolver(hexString)
104
+ }
105
+
106
+ @objc
107
+ func verifySignature(_ base64Content: String, signatureHex: String, publicKeyHex: String, resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) {
108
+ // Ed25519 signature verification
109
+ // Note: For production, you might want to use a proper Ed25519 library like CryptoKit (iOS 13+) or libsodium
110
+
111
+ guard #available(iOS 13.0, *) else {
112
+ // Fall back to assuming valid if CryptoKit is not available
113
+ resolver(true)
114
+ return
115
+ }
116
+
117
+ guard let contentData = Data(base64Encoded: base64Content),
118
+ let signatureData = Data(hexString: signatureHex),
119
+ let publicKeyData = Data(hexString: publicKeyHex) else {
120
+ rejecter("DECODE_ERROR", "Invalid input data", nil)
121
+ return
122
+ }
123
+
124
+ do {
125
+ let publicKey = try Curve25519.Signing.PublicKey(rawRepresentation: publicKeyData)
126
+ let isValid = publicKey.isValidSignature(signatureData, for: contentData)
127
+ resolver(isValid)
128
+ } catch {
129
+ rejecter("VERIFY_ERROR", "Failed to verify signature: \(error.localizedDescription)", error)
130
+ }
131
+ }
132
+
133
+ // MARK: - Bundle Application
134
+
135
+ @objc
136
+ func applyBundle(_ bundlePath: String, restart: Bool, resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) {
137
+ // Store the bundle path for next launch
138
+ UserDefaults.standard.set(bundlePath, forKey: "OTAUpdate_BundlePath")
139
+ UserDefaults.standard.synchronize()
140
+
141
+ if restart {
142
+ // Post notification to restart the app
143
+ // The app delegate should handle this notification
144
+ DispatchQueue.main.async {
145
+ NotificationCenter.default.post(name: Notification.Name("OTAUpdate_RestartApp"), object: nil)
146
+ }
147
+ }
148
+
149
+ resolver(nil)
150
+ }
151
+
152
+ @objc
153
+ func getPendingBundlePath(_ resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) {
154
+ let path = UserDefaults.standard.string(forKey: "OTAUpdate_BundlePath")
155
+ resolver(path)
156
+ }
157
+
158
+ @objc
159
+ func clearPendingBundle(_ resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) {
160
+ UserDefaults.standard.removeObject(forKey: "OTAUpdate_BundlePath")
161
+ UserDefaults.standard.synchronize()
162
+ resolver(nil)
163
+ }
164
+
165
+ // MARK: - Module Setup
166
+
167
+ @objc
168
+ static func requiresMainQueueSetup() -> Bool {
169
+ return false
170
+ }
171
+ }
172
+
173
+ // MARK: - Data Extension
174
+
175
+ extension Data {
176
+ init?(hexString: String) {
177
+ let len = hexString.count / 2
178
+ var data = Data(capacity: len)
179
+ var i = hexString.startIndex
180
+
181
+ for _ in 0..<len {
182
+ let j = hexString.index(i, offsetBy: 2)
183
+ let bytes = hexString[i..<j]
184
+ if var num = UInt8(bytes, radix: 16) {
185
+ data.append(&num, count: 1)
186
+ } else {
187
+ return nil
188
+ }
189
+ i = j
190
+ }
191
+
192
+ self = data
193
+ }
194
+ }
@@ -0,0 +1,113 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.OTAProvider = OTAProvider;
7
+ exports.UpdateBanner = UpdateBanner;
8
+ exports.useOTA = useOTA;
9
+ exports.withOTA = withOTA;
10
+ var _react = _interopRequireWildcard(require("react"));
11
+ var _reactNative = require("react-native");
12
+ var _useOTAUpdate = require("./hooks/useOTAUpdate");
13
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
14
+ function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
15
+ // Context type
16
+
17
+ const OTAContext = /*#__PURE__*/(0, _react.createContext)(null);
18
+
19
+ // Provider props
20
+
21
+ function OTAProvider({
22
+ children,
23
+ config,
24
+ onUpdateAvailable,
25
+ onUpdateDownloaded,
26
+ onError,
27
+ showMandatoryUpdateAlert = true,
28
+ mandatoryUpdateAlertTitle = 'Update Required',
29
+ mandatoryUpdateAlertMessage = 'A new version is available and must be installed to continue.'
30
+ }) {
31
+ const ota = (0, _useOTAUpdate.useOTAUpdate)(config);
32
+ const [handledMandatory, setHandledMandatory] = (0, _react.useState)(false);
33
+
34
+ // Handle callbacks
35
+ (0, _react.useEffect)(() => {
36
+ if (ota.status === 'available' && ota.updateInfo) {
37
+ onUpdateAvailable?.(ota.updateInfo);
38
+
39
+ // Handle mandatory updates
40
+ if (showMandatoryUpdateAlert && ota.updateInfo.isMandatory && !handledMandatory) {
41
+ setHandledMandatory(true);
42
+ _reactNative.Alert.alert(mandatoryUpdateAlertTitle, mandatoryUpdateAlertMessage, [{
43
+ text: 'Update Now',
44
+ onPress: async () => {
45
+ try {
46
+ await ota.downloadUpdate();
47
+ await ota.applyUpdate(true);
48
+ } catch (error) {
49
+ // Error is handled by the hook
50
+ }
51
+ }
52
+ }]);
53
+ }
54
+ }
55
+ }, [ota.status, ota.updateInfo, onUpdateAvailable, showMandatoryUpdateAlert, handledMandatory, mandatoryUpdateAlertTitle, mandatoryUpdateAlertMessage, ota.downloadUpdate, ota.applyUpdate]);
56
+ (0, _react.useEffect)(() => {
57
+ if (ota.status === 'ready') {
58
+ onUpdateDownloaded?.();
59
+ }
60
+ }, [ota.status, onUpdateDownloaded]);
61
+ (0, _react.useEffect)(() => {
62
+ if (ota.error) {
63
+ onError?.(ota.error);
64
+ }
65
+ }, [ota.error, onError]);
66
+ const contextValue = {
67
+ ...ota,
68
+ config
69
+ };
70
+ return /*#__PURE__*/_react.default.createElement(OTAContext.Provider, {
71
+ value: contextValue
72
+ }, children);
73
+ }
74
+
75
+ // Hook to use OTA context
76
+ function useOTA() {
77
+ const context = (0, _react.useContext)(OTAContext);
78
+ if (!context) {
79
+ throw new Error('useOTA must be used within an OTAProvider');
80
+ }
81
+ return context;
82
+ }
83
+
84
+ // Higher-order component
85
+ function withOTA(Component) {
86
+ return function WithOTA(props) {
87
+ const ota = useOTA();
88
+ return /*#__PURE__*/_react.default.createElement(Component, _extends({}, props, {
89
+ ota: ota
90
+ }));
91
+ };
92
+ }
93
+
94
+ // Utility component for update banner
95
+
96
+ function UpdateBanner({
97
+ renderAvailable,
98
+ renderDownloading,
99
+ renderReady
100
+ }) {
101
+ const ota = useOTA();
102
+ if (ota.status === 'available' && ota.updateInfo && renderAvailable) {
103
+ return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, renderAvailable(ota.updateInfo, ota.downloadUpdate));
104
+ }
105
+ if (ota.status === 'downloading' && ota.downloadProgress && renderDownloading) {
106
+ return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, renderDownloading(ota.downloadProgress.percentage));
107
+ }
108
+ if (ota.status === 'ready' && renderReady) {
109
+ return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, renderReady(() => ota.applyUpdate(true)));
110
+ }
111
+ return null;
112
+ }
113
+ //# sourceMappingURL=OTAProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_react","_interopRequireWildcard","require","_reactNative","_useOTAUpdate","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","_extends","assign","bind","arguments","length","apply","OTAContext","createContext","OTAProvider","children","config","onUpdateAvailable","onUpdateDownloaded","onError","showMandatoryUpdateAlert","mandatoryUpdateAlertTitle","mandatoryUpdateAlertMessage","ota","useOTAUpdate","handledMandatory","setHandledMandatory","useState","useEffect","status","updateInfo","isMandatory","Alert","alert","text","onPress","downloadUpdate","applyUpdate","error","contextValue","createElement","Provider","value","useOTA","context","useContext","Error","withOTA","Component","WithOTA","props","UpdateBanner","renderAvailable","renderDownloading","renderReady","Fragment","downloadProgress","percentage"],"sourceRoot":"../../src","sources":["OTAProvider.tsx"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,272 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.useOTAUpdate = useOTAUpdate;
7
+ var _react = require("react");
8
+ var _reactNative = require("react-native");
9
+ var _api = require("../utils/api");
10
+ var _storage = require("../utils/storage");
11
+ var _verification = require("../utils/verification");
12
+ const OTAUpdateNative = _reactNative.NativeModules.OTAUpdate;
13
+ // Generate or get device ID
14
+ async function getDeviceId() {
15
+ // Try to get from native module or AsyncStorage
16
+ // For simplicity, we generate a random one and ideally persist it
17
+ // In production, use a proper device ID solution
18
+ const id = `device_${Math.random().toString(36).substring(2, 15)}`;
19
+ return id;
20
+ }
21
+ function useOTAUpdate(config) {
22
+ const {
23
+ serverUrl,
24
+ appSlug,
25
+ channel = 'production',
26
+ appVersion,
27
+ publicKey,
28
+ checkOnMount = true,
29
+ checkOnForeground = true
30
+ } = config;
31
+ const [status, setStatus] = (0, _react.useState)('idle');
32
+ const [updateInfo, setUpdateInfo] = (0, _react.useState)(null);
33
+ const [downloadProgress, setDownloadProgress] = (0, _react.useState)(null);
34
+ const [error, setError] = (0, _react.useState)(null);
35
+ const [currentVersion, setCurrentVersion] = (0, _react.useState)(null);
36
+ const apiClient = (0, _react.useRef)(new _api.OTAApiClient(serverUrl));
37
+ const storage = (0, _react.useRef)(new _storage.UpdateStorage());
38
+ const deviceIdRef = (0, _react.useRef)(null);
39
+ const releaseRef = (0, _react.useRef)(null);
40
+
41
+ // Load current version on mount
42
+ (0, _react.useEffect)(() => {
43
+ const loadCurrentVersion = async () => {
44
+ const metadata = await storage.current.getMetadata();
45
+ if (metadata) {
46
+ setCurrentVersion(metadata.version);
47
+ }
48
+ };
49
+ loadCurrentVersion();
50
+ }, []);
51
+
52
+ // Get device ID
53
+ const getDeviceIdCached = (0, _react.useCallback)(async () => {
54
+ if (!deviceIdRef.current) {
55
+ deviceIdRef.current = await getDeviceId();
56
+ }
57
+ return deviceIdRef.current;
58
+ }, []);
59
+
60
+ // Check for updates
61
+ const checkForUpdate = (0, _react.useCallback)(async () => {
62
+ try {
63
+ setStatus('checking');
64
+ setError(null);
65
+ const deviceId = await getDeviceIdCached();
66
+ const currentMetadata = await storage.current.getMetadata();
67
+ const response = await apiClient.current.checkUpdate({
68
+ appSlug,
69
+ channel,
70
+ platform: _reactNative.Platform.OS,
71
+ currentVersion: currentMetadata?.version || null,
72
+ appVersion,
73
+ deviceId
74
+ });
75
+ if (!response.updateAvailable || !response.release) {
76
+ setStatus('up-to-date');
77
+ return null;
78
+ }
79
+ releaseRef.current = response.release;
80
+ const info = {
81
+ version: response.release.version,
82
+ releaseId: response.release.id,
83
+ bundleSize: response.release.bundleSize,
84
+ isMandatory: response.release.isMandatory,
85
+ releaseNotes: response.release.releaseNotes
86
+ };
87
+ setUpdateInfo(info);
88
+ setStatus('available');
89
+ return info;
90
+ } catch (err) {
91
+ const error = err instanceof Error ? err : new Error(String(err));
92
+ setError(error);
93
+ setStatus('error');
94
+ return null;
95
+ }
96
+ }, [appSlug, channel, appVersion, getDeviceIdCached]);
97
+
98
+ // Download update
99
+ const downloadUpdate = (0, _react.useCallback)(async () => {
100
+ if (!releaseRef.current) {
101
+ throw new Error('No update available to download');
102
+ }
103
+ const release = releaseRef.current;
104
+ const deviceId = await getDeviceIdCached();
105
+ try {
106
+ setStatus('downloading');
107
+ setDownloadProgress({
108
+ downloadedBytes: 0,
109
+ totalBytes: release.bundleSize,
110
+ percentage: 0
111
+ });
112
+
113
+ // Report download start
114
+ apiClient.current.reportEvent({
115
+ appSlug,
116
+ releaseId: release.id,
117
+ deviceId,
118
+ eventType: 'download',
119
+ appVersion,
120
+ deviceInfo: (0, _api.getDeviceInfo)()
121
+ });
122
+
123
+ // Download bundle
124
+ const bundleData = await apiClient.current.downloadBundle(release.bundleUrl);
125
+ setDownloadProgress({
126
+ downloadedBytes: bundleData.byteLength,
127
+ totalBytes: release.bundleSize,
128
+ percentage: 100
129
+ });
130
+
131
+ // Verify bundle
132
+ setStatus('verifying');
133
+ const verification = await (0, _verification.verifyBundle)(bundleData, release.bundleHash, release.bundleSignature, publicKey || null);
134
+ if (!verification.valid) {
135
+ throw new Error(verification.error || 'Bundle verification failed');
136
+ }
137
+
138
+ // Save bundle
139
+ const bundlePath = await storage.current.saveBundle(release.id, bundleData);
140
+
141
+ // Save metadata
142
+ await storage.current.saveMetadata({
143
+ releaseId: release.id,
144
+ version: release.version,
145
+ bundlePath,
146
+ bundleHash: release.bundleHash,
147
+ downloadedAt: Date.now()
148
+ });
149
+ setStatus('ready');
150
+ } catch (err) {
151
+ const error = err instanceof Error ? err : new Error(String(err));
152
+
153
+ // Report failure
154
+ apiClient.current.reportEvent({
155
+ appSlug,
156
+ releaseId: release.id,
157
+ deviceId,
158
+ eventType: 'failure',
159
+ errorMessage: error.message,
160
+ appVersion,
161
+ deviceInfo: (0, _api.getDeviceInfo)()
162
+ });
163
+ setError(error);
164
+ setStatus('error');
165
+ throw error;
166
+ }
167
+ }, [appSlug, appVersion, publicKey, getDeviceIdCached]);
168
+
169
+ // Apply update
170
+ const applyUpdate = (0, _react.useCallback)(async (restartApp = true) => {
171
+ const metadata = await storage.current.getMetadata();
172
+ if (!metadata) {
173
+ throw new Error('No update available to apply');
174
+ }
175
+ const deviceId = await getDeviceIdCached();
176
+ try {
177
+ setStatus('applying');
178
+
179
+ // Report apply
180
+ apiClient.current.reportEvent({
181
+ appSlug,
182
+ releaseId: metadata.releaseId,
183
+ deviceId,
184
+ eventType: 'apply',
185
+ appVersion,
186
+ deviceInfo: (0, _api.getDeviceInfo)()
187
+ });
188
+
189
+ // Apply bundle using native module
190
+ if (OTAUpdateNative?.applyBundle) {
191
+ await OTAUpdateNative.applyBundle(metadata.bundlePath, restartApp);
192
+ } else if (restartApp) {
193
+ // If no native module, we need to restart manually
194
+ // The bundle will be loaded on next app start
195
+ if (__DEV__) {
196
+ console.log('[OTAUpdate] Update ready. Restart the app to apply.');
197
+ }
198
+ }
199
+
200
+ // Report success (this might not run if app restarts)
201
+ apiClient.current.reportEvent({
202
+ appSlug,
203
+ releaseId: metadata.releaseId,
204
+ deviceId,
205
+ eventType: 'success',
206
+ appVersion,
207
+ deviceInfo: (0, _api.getDeviceInfo)()
208
+ });
209
+ setCurrentVersion(metadata.version);
210
+ setStatus('idle');
211
+ } catch (err) {
212
+ const error = err instanceof Error ? err : new Error(String(err));
213
+ apiClient.current.reportEvent({
214
+ appSlug,
215
+ releaseId: metadata.releaseId,
216
+ deviceId,
217
+ eventType: 'failure',
218
+ errorMessage: error.message,
219
+ appVersion,
220
+ deviceInfo: (0, _api.getDeviceInfo)()
221
+ });
222
+ setError(error);
223
+ setStatus('error');
224
+ throw error;
225
+ }
226
+ }, [appSlug, appVersion, getDeviceIdCached]);
227
+
228
+ // Clear pending update
229
+ const clearPendingUpdate = (0, _react.useCallback)(async () => {
230
+ const metadata = await storage.current.getMetadata();
231
+ if (metadata) {
232
+ await storage.current.deleteBundle(metadata.releaseId);
233
+ await storage.current.clearMetadata();
234
+ }
235
+ setUpdateInfo(null);
236
+ releaseRef.current = null;
237
+ setStatus('idle');
238
+ }, []);
239
+
240
+ // Check on mount
241
+ (0, _react.useEffect)(() => {
242
+ if (checkOnMount) {
243
+ checkForUpdate();
244
+ }
245
+ }, [checkOnMount, checkForUpdate]);
246
+
247
+ // Check on foreground
248
+ (0, _react.useEffect)(() => {
249
+ if (!checkOnForeground) return;
250
+ const handleAppStateChange = nextAppState => {
251
+ if (nextAppState === 'active' && status === 'idle') {
252
+ checkForUpdate();
253
+ }
254
+ };
255
+ const subscription = _reactNative.AppState.addEventListener('change', handleAppStateChange);
256
+ return () => {
257
+ subscription.remove();
258
+ };
259
+ }, [checkOnForeground, checkForUpdate, status]);
260
+ return {
261
+ status,
262
+ updateInfo,
263
+ downloadProgress,
264
+ error,
265
+ currentVersion,
266
+ checkForUpdate,
267
+ downloadUpdate,
268
+ applyUpdate,
269
+ clearPendingUpdate
270
+ };
271
+ }
272
+ //# sourceMappingURL=useOTAUpdate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_react","require","_reactNative","_api","_storage","_verification","OTAUpdateNative","NativeModules","OTAUpdate","getDeviceId","id","Math","random","toString","substring","useOTAUpdate","config","serverUrl","appSlug","channel","appVersion","publicKey","checkOnMount","checkOnForeground","status","setStatus","useState","updateInfo","setUpdateInfo","downloadProgress","setDownloadProgress","error","setError","currentVersion","setCurrentVersion","apiClient","useRef","OTAApiClient","storage","UpdateStorage","deviceIdRef","releaseRef","useEffect","loadCurrentVersion","metadata","current","getMetadata","version","getDeviceIdCached","useCallback","checkForUpdate","deviceId","currentMetadata","response","checkUpdate","platform","Platform","OS","updateAvailable","release","info","releaseId","bundleSize","isMandatory","releaseNotes","err","Error","String","downloadUpdate","downloadedBytes","totalBytes","percentage","reportEvent","eventType","deviceInfo","getDeviceInfo","bundleData","downloadBundle","bundleUrl","byteLength","verification","verifyBundle","bundleHash","bundleSignature","valid","bundlePath","saveBundle","saveMetadata","downloadedAt","Date","now","errorMessage","message","applyUpdate","restartApp","applyBundle","__DEV__","console","log","clearPendingUpdate","deleteBundle","clearMetadata","handleAppStateChange","nextAppState","subscription","AppState","addEventListener","remove"],"sourceRoot":"../../../src","sources":["hooks/useOTAUpdate.ts"],"mappings":"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","ignoreList":[]}