@vanikya/ota-react-native 0.2.9 → 0.2.11
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/android/build.gradle +13 -1
- package/android/src/main/java/com/otaupdate/OTAUpdateExpoPackage.kt +86 -0
- package/android/src/main/java/com/otaupdate/OTAUpdatePackage.kt +1 -82
- package/app.plugin.js +5 -8
- package/expo-module.config.json +1 -2
- package/lib/commonjs/index.js +1 -1
- package/lib/commonjs/index.js.map +1 -1
- package/lib/module/index.js +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/index.d.ts +1 -1
- package/lib/typescript/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +1 -1
package/android/build.gradle
CHANGED
|
@@ -5,6 +5,12 @@ def safeExtGet(prop, fallback) {
|
|
|
5
5
|
apply plugin: 'com.android.library'
|
|
6
6
|
apply plugin: 'kotlin-android'
|
|
7
7
|
|
|
8
|
+
// Get expo-modules-core if available
|
|
9
|
+
def expoModulesCore = null
|
|
10
|
+
try {
|
|
11
|
+
expoModulesCore = project(':expo-modules-core')
|
|
12
|
+
} catch (Exception ignored) {}
|
|
13
|
+
|
|
8
14
|
android {
|
|
9
15
|
namespace "com.otaupdate"
|
|
10
16
|
|
|
@@ -36,7 +42,7 @@ android {
|
|
|
36
42
|
}
|
|
37
43
|
}
|
|
38
44
|
|
|
39
|
-
|
|
45
|
+
lint {
|
|
40
46
|
abortOnError false
|
|
41
47
|
}
|
|
42
48
|
}
|
|
@@ -51,4 +57,10 @@ dependencies {
|
|
|
51
57
|
implementation "com.facebook.react:react-android:+"
|
|
52
58
|
// ProcessPhoenix for graceful app restart
|
|
53
59
|
implementation "com.jakewharton:process-phoenix:3.0.0"
|
|
60
|
+
|
|
61
|
+
// Expo modules core - needed for ReactNativeHostHandler interface
|
|
62
|
+
// compileOnly so we don't bundle it (it's provided by the app)
|
|
63
|
+
if (expoModulesCore != null) {
|
|
64
|
+
compileOnly expoModulesCore
|
|
65
|
+
}
|
|
54
66
|
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
package com.otaupdate
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.util.Log
|
|
5
|
+
import com.facebook.react.bridge.ReactContext
|
|
6
|
+
import expo.modules.core.interfaces.Package
|
|
7
|
+
import expo.modules.core.interfaces.ReactNativeHostHandler
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Expo Package implementation that provides ReactNativeHostHandler.
|
|
11
|
+
* This is the key integration point for Expo's new architecture (bridgeless mode).
|
|
12
|
+
*
|
|
13
|
+
* In Expo's new architecture, bundle loading doesn't go through DefaultReactNativeHost.getJSBundleFile().
|
|
14
|
+
* Instead, Expo's core scans for packages implementing this interface and calls the handlers.
|
|
15
|
+
*
|
|
16
|
+
* This is exactly how expo-updates works.
|
|
17
|
+
*/
|
|
18
|
+
class OTAUpdateExpoPackage : Package {
|
|
19
|
+
|
|
20
|
+
companion object {
|
|
21
|
+
private const val TAG = "OTAUpdateExpoPackage"
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
override fun createReactNativeHostHandlers(context: Context): List<ReactNativeHostHandler> {
|
|
25
|
+
Log.d(TAG, "=== createReactNativeHostHandlers called ===")
|
|
26
|
+
|
|
27
|
+
val handler = object : ReactNativeHostHandler {
|
|
28
|
+
|
|
29
|
+
override fun getJSBundleFile(useDeveloperSupport: Boolean): String? {
|
|
30
|
+
Log.d(TAG, "=== getJSBundleFile called (useDeveloperSupport=$useDeveloperSupport) ===")
|
|
31
|
+
|
|
32
|
+
// In development mode, let Metro bundler handle it
|
|
33
|
+
if (useDeveloperSupport) {
|
|
34
|
+
Log.d(TAG, "Developer support enabled, using Metro bundler")
|
|
35
|
+
return null
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Get the bundle path from OTAUpdateHelper
|
|
39
|
+
val bundlePath = OTAUpdateHelper.getJSBundleFile(context)
|
|
40
|
+
if (bundlePath != null) {
|
|
41
|
+
Log.d(TAG, "Returning OTA bundle: $bundlePath")
|
|
42
|
+
} else {
|
|
43
|
+
Log.d(TAG, "No OTA bundle, using default")
|
|
44
|
+
}
|
|
45
|
+
return bundlePath
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
override fun getBundleAssetName(useDeveloperSupport: Boolean): String? {
|
|
49
|
+
Log.d(TAG, "=== getBundleAssetName called (useDeveloperSupport=$useDeveloperSupport) ===")
|
|
50
|
+
|
|
51
|
+
// In development mode, use default behavior
|
|
52
|
+
if (useDeveloperSupport) {
|
|
53
|
+
return null
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Check if we have an OTA bundle
|
|
57
|
+
val bundlePath = OTAUpdateHelper.getJSBundleFile(context)
|
|
58
|
+
if (bundlePath != null) {
|
|
59
|
+
// Return null to force React Native to use getJSBundleFile() instead of bundled assets
|
|
60
|
+
Log.d(TAG, "OTA bundle exists, returning null to force getJSBundleFile")
|
|
61
|
+
return null
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// No OTA bundle, use default bundled assets
|
|
65
|
+
return null
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
override fun onWillCreateReactInstance(useDeveloperSupport: Boolean) {
|
|
69
|
+
Log.d(TAG, "=== onWillCreateReactInstance (useDeveloperSupport=$useDeveloperSupport) ===")
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
override fun onDidCreateReactInstance(useDeveloperSupport: Boolean, reactContext: ReactContext) {
|
|
73
|
+
Log.d(TAG, "=== onDidCreateReactInstance ===")
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
override fun onReactInstanceException(useDeveloperSupport: Boolean, exception: Exception) {
|
|
77
|
+
Log.e(TAG, "=== onReactInstanceException ===", exception)
|
|
78
|
+
// If there's an exception with OTA bundle, we could clear it here for recovery
|
|
79
|
+
// For now, just log it
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
Log.d(TAG, "Returning ReactNativeHostHandler")
|
|
84
|
+
return listOf(handler)
|
|
85
|
+
}
|
|
86
|
+
}
|
|
@@ -1,30 +1,11 @@
|
|
|
1
1
|
package com.otaupdate
|
|
2
2
|
|
|
3
|
-
import android.content.Context
|
|
4
|
-
import android.util.Log
|
|
5
3
|
import com.facebook.react.ReactPackage
|
|
6
4
|
import com.facebook.react.bridge.NativeModule
|
|
7
5
|
import com.facebook.react.bridge.ReactApplicationContext
|
|
8
|
-
import com.facebook.react.bridge.ReactContext
|
|
9
6
|
import com.facebook.react.uimanager.ViewManager
|
|
10
|
-
import expo.modules.core.interfaces.Package
|
|
11
|
-
import expo.modules.core.interfaces.ReactNativeHostHandler
|
|
12
7
|
|
|
13
|
-
|
|
14
|
-
* OTAUpdatePackage implements both React Native's ReactPackage and Expo's Package interfaces.
|
|
15
|
-
*
|
|
16
|
-
* The Expo Package interface is critical for bundle loading with Expo's new architecture.
|
|
17
|
-
* It provides ReactNativeHostHandler which allows us to override:
|
|
18
|
-
* - getJSBundleFile: Returns path to downloaded OTA bundle
|
|
19
|
-
* - getBundleAssetName: Returns null when OTA bundle exists to force using getJSBundleFile
|
|
20
|
-
*/
|
|
21
|
-
class OTAUpdatePackage : ReactPackage, Package {
|
|
22
|
-
|
|
23
|
-
companion object {
|
|
24
|
-
private const val TAG = "OTAUpdatePackage"
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// ReactPackage implementation
|
|
8
|
+
class OTAUpdatePackage : ReactPackage {
|
|
28
9
|
override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
|
|
29
10
|
return listOf(OTAUpdateModule(reactContext))
|
|
30
11
|
}
|
|
@@ -32,66 +13,4 @@ class OTAUpdatePackage : ReactPackage, Package {
|
|
|
32
13
|
override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
|
|
33
14
|
return emptyList()
|
|
34
15
|
}
|
|
35
|
-
|
|
36
|
-
// Expo Package implementation - this is the key for Expo new architecture support
|
|
37
|
-
override fun createReactNativeHostHandlers(context: Context): List<ReactNativeHostHandler> {
|
|
38
|
-
Log.d(TAG, "=== createReactNativeHostHandlers called ===")
|
|
39
|
-
|
|
40
|
-
val handler = object : ReactNativeHostHandler {
|
|
41
|
-
|
|
42
|
-
override fun getJSBundleFile(useDeveloperSupport: Boolean): String? {
|
|
43
|
-
Log.d(TAG, "=== getJSBundleFile called (useDeveloperSupport=$useDeveloperSupport) ===")
|
|
44
|
-
|
|
45
|
-
// In development mode, let Metro bundler handle it
|
|
46
|
-
if (useDeveloperSupport) {
|
|
47
|
-
Log.d(TAG, "Developer support enabled, returning null")
|
|
48
|
-
return null
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// Get the bundle path from OTAUpdateHelper
|
|
52
|
-
val bundlePath = OTAUpdateHelper.getJSBundleFile(context)
|
|
53
|
-
Log.d(TAG, "OTAUpdateHelper returned bundle path: $bundlePath")
|
|
54
|
-
return bundlePath
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
override fun getBundleAssetName(useDeveloperSupport: Boolean): String? {
|
|
58
|
-
Log.d(TAG, "=== getBundleAssetName called (useDeveloperSupport=$useDeveloperSupport) ===")
|
|
59
|
-
|
|
60
|
-
// In development mode, use default behavior
|
|
61
|
-
if (useDeveloperSupport) {
|
|
62
|
-
Log.d(TAG, "Developer support enabled, returning null (use default)")
|
|
63
|
-
return null
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// Check if we have an OTA bundle
|
|
67
|
-
val bundlePath = OTAUpdateHelper.getJSBundleFile(context)
|
|
68
|
-
if (bundlePath != null) {
|
|
69
|
-
// Return null to force React Native to use getJSBundleFile instead of bundled assets
|
|
70
|
-
Log.d(TAG, "OTA bundle exists at $bundlePath, returning null to force getJSBundleFile")
|
|
71
|
-
return null
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// No OTA bundle, use default bundled assets
|
|
75
|
-
Log.d(TAG, "No OTA bundle, returning null (use default bundled assets)")
|
|
76
|
-
return null
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
override fun onWillCreateReactInstance(useDeveloperSupport: Boolean) {
|
|
80
|
-
Log.d(TAG, "=== onWillCreateReactInstance called (useDeveloperSupport=$useDeveloperSupport) ===")
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
override fun onDidCreateReactInstance(useDeveloperSupport: Boolean, reactContext: ReactContext) {
|
|
84
|
-
Log.d(TAG, "=== onDidCreateReactInstance called ===")
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
override fun onReactInstanceException(useDeveloperSupport: Boolean, exception: Exception) {
|
|
88
|
-
Log.e(TAG, "=== onReactInstanceException called ===", exception)
|
|
89
|
-
// If there's an exception with OTA bundle, we could clear it here
|
|
90
|
-
// For now, just log the exception
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
Log.d(TAG, "Returning ReactNativeHostHandler")
|
|
95
|
-
return listOf(handler)
|
|
96
|
-
}
|
|
97
16
|
}
|
package/app.plugin.js
CHANGED
|
@@ -4,19 +4,16 @@ const { withAppDelegate } = require('@expo/config-plugins');
|
|
|
4
4
|
* OTA Update Expo Config Plugin
|
|
5
5
|
*
|
|
6
6
|
* This plugin modifies the native code to enable OTA bundle loading:
|
|
7
|
-
* - Android: Uses Expo
|
|
7
|
+
* - Android: Uses Expo Package interface (ReactNativeHostHandler) via expo-module.config.json
|
|
8
|
+
* No MainApplication.kt modification needed!
|
|
8
9
|
* - iOS: Modifies bundleURL() in AppDelegate.swift
|
|
9
|
-
*
|
|
10
|
-
* For Android, the OTAUpdatePackage implements expo.modules.core.interfaces.Package
|
|
11
|
-
* which provides ReactNativeHostHandler to hook into bundle loading.
|
|
12
|
-
* This is registered via expo-module.config.json.
|
|
13
10
|
*/
|
|
14
11
|
|
|
15
12
|
function withOTAUpdateAndroid(config) {
|
|
16
|
-
// Android bundle loading is handled by
|
|
13
|
+
// Android bundle loading is handled by OTAUpdateExpoPackage implementing
|
|
17
14
|
// expo.modules.core.interfaces.Package with ReactNativeHostHandler.
|
|
18
|
-
//
|
|
19
|
-
console.log('[OTAUpdate] Android: Using Expo Package interface
|
|
15
|
+
// This is registered via expo-module.config.json and discovered by Expo automatically.
|
|
16
|
+
console.log('[OTAUpdate] Android: Using Expo Package interface (ReactNativeHostHandler)');
|
|
20
17
|
return config;
|
|
21
18
|
}
|
|
22
19
|
|
package/expo-module.config.json
CHANGED
package/lib/commonjs/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_OTAProvider","require","_OTADebugPanel","_useOTAUpdate","_api","_storage","_verification","VERSION","exports"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,IAAAA,YAAA,GAAAC,OAAA;AAIA,IAAAC,cAAA,GAAAD,OAAA;AAGA,IAAAE,aAAA,GAAAF,OAAA;AAUA,IAAAG,IAAA,GAAAH,OAAA;AAQA,IAAAI,QAAA,GAAAJ,OAAA;AAGA,IAAAK,aAAA,GAAAL,OAAA;AA7BA;;AAIA;;AAGA;;AAUA;;AAoBA;AACO,MAAMM,OAAO,GAAAC,OAAA,CAAAD,OAAA,GAAG,
|
|
1
|
+
{"version":3,"names":["_OTAProvider","require","_OTADebugPanel","_useOTAUpdate","_api","_storage","_verification","VERSION","exports"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,IAAAA,YAAA,GAAAC,OAAA;AAIA,IAAAC,cAAA,GAAAD,OAAA;AAGA,IAAAE,aAAA,GAAAF,OAAA;AAUA,IAAAG,IAAA,GAAAH,OAAA;AAQA,IAAAI,QAAA,GAAAJ,OAAA;AAGA,IAAAK,aAAA,GAAAL,OAAA;AA7BA;;AAIA;;AAGA;;AAUA;;AAoBA;AACO,MAAMM,OAAO,GAAAC,OAAA,CAAAD,OAAA,GAAG,QAAQ","ignoreList":[]}
|
package/lib/module/index.js
CHANGED
|
@@ -10,5 +10,5 @@ export { OTAApiClient, getDeviceInfo } from './utils/api';
|
|
|
10
10
|
export { UpdateStorage, getStorageAdapter } from './utils/storage';
|
|
11
11
|
export { calculateHash, verifyBundleHash, verifySignature, verifyBundle } from './utils/verification';
|
|
12
12
|
// Version info
|
|
13
|
-
export const VERSION = '0.2.
|
|
13
|
+
export const VERSION = '0.2.11';
|
|
14
14
|
//# sourceMappingURL=index.js.map
|
package/lib/module/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["OTAProvider","useOTA","withOTA","UpdateBanner","OTADebugPanel","useOTAUpdate","OTAApiClient","getDeviceInfo","UpdateStorage","getStorageAdapter","calculateHash","verifyBundleHash","verifySignature","verifyBundle","VERSION"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":"AAAA;AACA,SAASA,WAAW,EAAEC,MAAM,EAAEC,OAAO,EAAEC,YAAY,QAAQ,eAAe;AAG1E;AACA,SAASC,aAAa,QAAQ,4BAA4B;;AAE1D;AACA,SAASC,YAAY,QAAQ,sBAAsB;AASnD;AACA,SAASC,YAAY,EAAEC,aAAa,QAAQ,aAAa;AAQzD,SAASC,aAAa,EAAEC,iBAAiB,QAAQ,iBAAiB;AAGlE,SACEC,aAAa,EACbC,gBAAgB,EAChBC,eAAe,EACfC,YAAY,QACP,sBAAsB;AAG7B;AACA,OAAO,MAAMC,OAAO,GAAG,
|
|
1
|
+
{"version":3,"names":["OTAProvider","useOTA","withOTA","UpdateBanner","OTADebugPanel","useOTAUpdate","OTAApiClient","getDeviceInfo","UpdateStorage","getStorageAdapter","calculateHash","verifyBundleHash","verifySignature","verifyBundle","VERSION"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":"AAAA;AACA,SAASA,WAAW,EAAEC,MAAM,EAAEC,OAAO,EAAEC,YAAY,QAAQ,eAAe;AAG1E;AACA,SAASC,aAAa,QAAQ,4BAA4B;;AAE1D;AACA,SAASC,YAAY,QAAQ,sBAAsB;AASnD;AACA,SAASC,YAAY,EAAEC,aAAa,QAAQ,aAAa;AAQzD,SAASC,aAAa,EAAEC,iBAAiB,QAAQ,iBAAiB;AAGlE,SACEC,aAAa,EACbC,gBAAgB,EAChBC,eAAe,EACfC,YAAY,QACP,sBAAsB;AAG7B;AACA,OAAO,MAAMC,OAAO,GAAG,QAAQ","ignoreList":[]}
|
|
@@ -9,5 +9,5 @@ export { UpdateStorage, getStorageAdapter } from './utils/storage';
|
|
|
9
9
|
export type { StoredUpdate, StorageAdapter } from './utils/storage';
|
|
10
10
|
export { calculateHash, verifyBundleHash, verifySignature, verifyBundle, } from './utils/verification';
|
|
11
11
|
export type { VerificationResult } from './utils/verification';
|
|
12
|
-
export declare const VERSION = "0.2.
|
|
12
|
+
export declare const VERSION = "0.2.11";
|
|
13
13
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC3E,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAGzE,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAG3D,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,YAAY,EACV,eAAe,EACf,UAAU,EACV,gBAAgB,EAChB,YAAY,EACZ,kBAAkB,GACnB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC1D,YAAY,EACV,kBAAkB,EAClB,mBAAmB,EACnB,WAAW,EACX,kBAAkB,GACnB,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACnE,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEpE,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,YAAY,GACb,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAG/D,eAAO,MAAM,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC3E,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAGzE,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAG3D,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,YAAY,EACV,eAAe,EACf,UAAU,EACV,gBAAgB,EAChB,YAAY,EACZ,kBAAkB,GACnB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC1D,YAAY,EACV,kBAAkB,EAClB,mBAAmB,EACnB,WAAW,EACX,kBAAkB,GACnB,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACnE,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEpE,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,YAAY,GACb,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAG/D,eAAO,MAAM,OAAO,WAAW,CAAC"}
|
package/package.json
CHANGED
package/src/index.ts
CHANGED