react-native-stallion 2.0.1 → 2.1.0-alpha.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/android/src/main/AndroidManifest.xml +7 -1
- package/android/src/main/java/com/stallion/Stallion.java +16 -1
- package/android/src/main/java/com/stallion/StallionModule.java +8 -6
- package/android/src/main/java/com/stallion/events/StallionEventConstants.java +4 -1
- package/android/src/main/java/com/stallion/networkmanager/StallionStageManager.java +26 -1
- package/android/src/main/java/com/stallion/storage/StallionConfig.java +3 -2
- package/android/src/main/java/com/stallion/utils/ProcessPhoenix.java +100 -0
- package/ios/main/Stallion-Bridging-Header.h +1 -0
- package/ios/main/Stallion.m +2 -0
- package/ios/main/Stallion.swift +7 -1
- package/ios/main/StallionConstants.swift +3 -0
- package/ios/main/StallionModule.m +7 -1
- package/ios/main/StallionObjConstants.h +2 -0
- package/ios/main/StallionObjConstants.m +4 -0
- package/ios/main/StallionSlotManager.m +2 -2
- package/ios/main/StallionStageManager.swift +22 -1
- package/ios/main/StallionSyncHandler.swift +44 -19
- package/package.json +1 -1
- package/src/index.js +1 -1
- package/src/index.js.map +1 -1
- package/src/main/components/common/BackButton/index.js +54 -0
- package/src/main/components/common/BackButton/index.js.map +1 -0
- package/src/main/components/common/CrossButton/index.js +45 -0
- package/src/main/components/common/CrossButton/index.js.map +1 -0
- package/src/main/components/common/Footer/index.js +13 -5
- package/src/main/components/common/Footer/index.js.map +1 -1
- package/src/main/components/common/Footer/styles.js +16 -5
- package/src/main/components/common/Footer/styles.js.map +1 -1
- package/src/main/components/common/Header/index.js +9 -13
- package/src/main/components/common/Header/index.js.map +1 -1
- package/src/main/components/common/Header/styles.js +5 -5
- package/src/main/components/common/Header/styles.js.map +1 -1
- package/src/main/components/modules/listing/components/ConfigView.js +14 -4
- package/src/main/components/modules/listing/components/ConfigView.js.map +1 -1
- package/src/main/components/modules/listing/components/MetaCard.js +5 -4
- package/src/main/components/modules/listing/components/MetaCard.js.map +1 -1
- package/src/main/components/modules/listing/components/SlotView.js +47 -51
- package/src/main/components/modules/listing/components/SlotView.js.map +1 -1
- package/src/main/components/modules/listing/components/styles/index.js +27 -0
- package/src/main/components/modules/listing/components/styles/index.js.map +1 -1
- package/src/main/components/modules/listing/index.js +5 -6
- package/src/main/components/modules/listing/index.js.map +1 -1
- package/src/main/components/modules/listing/styles.js +5 -1
- package/src/main/components/modules/listing/styles.js.map +1 -1
- package/src/main/components/modules/modal/StallionModal.js +3 -3
- package/src/main/components/modules/modal/StallionModal.js.map +1 -1
- package/src/main/components/modules/modal/hooks/useStallionModal.js +6 -1
- package/src/main/components/modules/modal/hooks/useStallionModal.js.map +1 -1
- package/src/main/components/modules/prod/prod.js +1 -7
- package/src/main/components/modules/prod/prod.js.map +1 -1
- package/src/main/components/modules/prod/styles/index.js +4 -1
- package/src/main/components/modules/prod/styles/index.js.map +1 -1
- package/src/main/constants/appConstants.js +7 -3
- package/src/main/constants/appConstants.js.map +1 -1
- package/src/main/constants/colors.js +1 -0
- package/src/main/constants/colors.js.map +1 -1
- package/src/main/state/useStallionEvents.js +4 -1
- package/src/main/state/useStallionEvents.js.map +1 -1
- package/src/main/utils/StallionNativeUtils.js +1 -0
- package/src/main/utils/StallionNativeUtils.js.map +1 -1
- package/src/main/utils/getSize.js +11 -0
- package/src/main/utils/getSize.js.map +1 -0
- package/src/main/utils/useStallionUpdate.js +4 -2
- package/src/main/utils/useStallionUpdate.js.map +1 -1
- package/types/index.d.ts +1 -1
- package/types/index.d.ts.map +1 -1
- package/types/main/components/common/BackButton/index.d.ts +9 -0
- package/types/main/components/common/BackButton/index.d.ts.map +1 -0
- package/types/main/components/common/CrossButton/index.d.ts +9 -0
- package/types/main/components/common/CrossButton/index.d.ts.map +1 -0
- package/types/main/components/common/Footer/index.d.ts.map +1 -1
- package/types/main/components/common/Footer/styles.d.ts +12 -1
- package/types/main/components/common/Footer/styles.d.ts.map +1 -1
- package/types/main/components/common/Header/index.d.ts.map +1 -1
- package/types/main/components/common/Header/styles.d.ts +1 -1
- package/types/main/components/modules/listing/components/ConfigView.d.ts.map +1 -1
- package/types/main/components/modules/listing/components/MetaCard.d.ts.map +1 -1
- package/types/main/components/modules/listing/components/SlotView.d.ts.map +1 -1
- package/types/main/components/modules/listing/components/styles/index.d.ts +27 -0
- package/types/main/components/modules/listing/components/styles/index.d.ts.map +1 -1
- package/types/main/components/modules/listing/index.d.ts.map +1 -1
- package/types/main/components/modules/listing/styles.d.ts +4 -0
- package/types/main/components/modules/listing/styles.d.ts.map +1 -1
- package/types/main/components/modules/modal/StallionModal.d.ts.map +1 -1
- package/types/main/components/modules/modal/hooks/useStallionModal.d.ts +1 -0
- package/types/main/components/modules/modal/hooks/useStallionModal.d.ts.map +1 -1
- package/types/main/components/modules/prod/prod.d.ts.map +1 -1
- package/types/main/components/modules/prod/styles/index.d.ts +3 -0
- package/types/main/components/modules/prod/styles/index.d.ts.map +1 -1
- package/types/main/constants/appConstants.d.ts +7 -4
- package/types/main/constants/appConstants.d.ts.map +1 -1
- package/types/main/constants/colors.d.ts +1 -0
- package/types/main/constants/colors.d.ts.map +1 -1
- package/types/main/state/useStallionEvents.d.ts.map +1 -1
- package/types/main/utils/StallionNativeUtils.d.ts +1 -0
- package/types/main/utils/StallionNativeUtils.d.ts.map +1 -1
- package/types/main/utils/getSize.d.ts +2 -0
- package/types/main/utils/getSize.d.ts.map +1 -0
- package/types/main/utils/useStallionUpdate.d.ts.map +1 -1
|
@@ -2,7 +2,13 @@
|
|
|
2
2
|
package="com.stallion">
|
|
3
3
|
<application>
|
|
4
4
|
<activity
|
|
5
|
-
android:name="com.stallion.
|
|
5
|
+
android:name="com.stallion.utils.StallionErrorActivity">
|
|
6
|
+
</activity>
|
|
7
|
+
<activity
|
|
8
|
+
android:name="com.stallion.utils.ProcessPhoenix"
|
|
9
|
+
android:exported="false"
|
|
10
|
+
android:theme="@android:style/Theme.Translucent.NoTitleBar"
|
|
11
|
+
android:noHistory="true">
|
|
6
12
|
</activity>
|
|
7
13
|
</application>
|
|
8
14
|
</manifest>
|
|
@@ -88,6 +88,7 @@ public class Stallion {
|
|
|
88
88
|
stallionMeta.setStageNewHash(stageTempHash);
|
|
89
89
|
stallionMeta.setStageTempHash("");
|
|
90
90
|
stateManager.syncStallionMeta();
|
|
91
|
+
sendInstallEventStage(stageTempHash);
|
|
91
92
|
} catch (Exception ignored) {}
|
|
92
93
|
}
|
|
93
94
|
}
|
|
@@ -134,6 +135,20 @@ public class Stallion {
|
|
|
134
135
|
}
|
|
135
136
|
}
|
|
136
137
|
|
|
138
|
+
private static void sendInstallEventStage(String releaseHash) {
|
|
139
|
+
try {
|
|
140
|
+
JSONObject eventPayload = new JSONObject();
|
|
141
|
+
eventPayload.put("releaseHash", releaseHash);
|
|
142
|
+
|
|
143
|
+
StallionEventManager.getInstance().sendEvent(
|
|
144
|
+
StallionEventConstants.NativeStageEventTypes.INSTALLED_STAGE.toString(),
|
|
145
|
+
eventPayload
|
|
146
|
+
);
|
|
147
|
+
} catch (Exception e) {
|
|
148
|
+
e.printStackTrace();
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
137
152
|
private static void sendCorruptionEvent(String releaseHash, String folderPath) {
|
|
138
153
|
try {
|
|
139
154
|
JSONObject eventPayload = new JSONObject();
|
|
@@ -170,7 +185,7 @@ public class Stallion {
|
|
|
170
185
|
return bundlePath;
|
|
171
186
|
} else {
|
|
172
187
|
if(isProd) {
|
|
173
|
-
StallionSlotManager.rollbackProd(
|
|
188
|
+
StallionSlotManager.rollbackProd(false, "Corruped file not found" + folderPath);
|
|
174
189
|
sendCorruptionEvent(releaseHash, folderPath);
|
|
175
190
|
} else {
|
|
176
191
|
StallionSlotManager.rollbackStage();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
package com.stallion;
|
|
2
2
|
|
|
3
|
-
import androidx.annotation.NonNull;
|
|
4
3
|
|
|
4
|
+
import androidx.annotation.NonNull;
|
|
5
5
|
import com.facebook.react.bridge.LifecycleEventListener;
|
|
6
6
|
import com.facebook.react.bridge.Promise;
|
|
7
7
|
import com.facebook.react.bridge.ReactApplicationContext;
|
|
@@ -17,6 +17,7 @@ import com.stallion.storage.StallionConfigConstants;
|
|
|
17
17
|
|
|
18
18
|
import com.stallion.storage.StallionMetaConstants;
|
|
19
19
|
import com.stallion.storage.StallionStateManager;
|
|
20
|
+
import com.stallion.utils.ProcessPhoenix;
|
|
20
21
|
|
|
21
22
|
import org.json.JSONArray;
|
|
22
23
|
import org.json.JSONException;
|
|
@@ -46,11 +47,7 @@ public class StallionModule extends ReactContextBaseJavaModule implements Lifecy
|
|
|
46
47
|
public void onHostPause() {}
|
|
47
48
|
|
|
48
49
|
@Override
|
|
49
|
-
public void onHostDestroy() {
|
|
50
|
-
|
|
51
|
-
@Override
|
|
52
|
-
public void onCatalystInstanceDestroy() {
|
|
53
|
-
super.onCatalystInstanceDestroy();
|
|
50
|
+
public void onHostDestroy() {
|
|
54
51
|
stallionStateManager.setIsMounted(false);
|
|
55
52
|
getReactApplicationContext().removeLifecycleEventListener(this);
|
|
56
53
|
}
|
|
@@ -165,4 +162,9 @@ public class StallionModule extends ReactContextBaseJavaModule implements Lifecy
|
|
|
165
162
|
promise.reject("ACKNOWLEDGE_EVENTS_ERROR", "Failed to acknowledge events: " + e.getMessage(), e);
|
|
166
163
|
}
|
|
167
164
|
}
|
|
165
|
+
|
|
166
|
+
@ReactMethod
|
|
167
|
+
public void restart() {
|
|
168
|
+
ProcessPhoenix.triggerRebirth(getReactApplicationContext());
|
|
169
|
+
}
|
|
168
170
|
}
|
|
@@ -25,6 +25,7 @@ public class StallionStageManager {
|
|
|
25
25
|
+ StallionConfigConstants.STAGE_DIRECTORY
|
|
26
26
|
+ StallionConfigConstants.TEMP_FOLDER_SLOT;
|
|
27
27
|
|
|
28
|
+
emitDownloadStartedStage(receivedHash);
|
|
28
29
|
StallionFileDownloader.downloadBundle(
|
|
29
30
|
receivedDownloadUrl,
|
|
30
31
|
downloadPath,
|
|
@@ -32,6 +33,7 @@ public class StallionStageManager {
|
|
|
32
33
|
@Override
|
|
33
34
|
public void onReject(String prefix, String error) {
|
|
34
35
|
promise.reject(prefix, error);
|
|
36
|
+
emitDownloadErrorStage(receivedHash, error);
|
|
35
37
|
}
|
|
36
38
|
|
|
37
39
|
@Override
|
|
@@ -57,7 +59,7 @@ public class StallionStageManager {
|
|
|
57
59
|
try {
|
|
58
60
|
successPayload.put("releaseHash", releaseHash);
|
|
59
61
|
} catch (Exception ignored) { }
|
|
60
|
-
StallionEventManager.getInstance().
|
|
62
|
+
StallionEventManager.getInstance().sendEvent(
|
|
61
63
|
StallionEventConstants.NativeStageEventTypes.DOWNLOAD_COMPLETE_STAGE.toString(),
|
|
62
64
|
successPayload
|
|
63
65
|
);
|
|
@@ -74,4 +76,27 @@ public class StallionStageManager {
|
|
|
74
76
|
successPayload
|
|
75
77
|
);
|
|
76
78
|
}
|
|
79
|
+
|
|
80
|
+
private static void emitDownloadStartedStage(String releaseHash) {
|
|
81
|
+
JSONObject startedPayload = new JSONObject();
|
|
82
|
+
try {
|
|
83
|
+
startedPayload.put("releaseHash", releaseHash);
|
|
84
|
+
} catch (Exception ignored) { }
|
|
85
|
+
StallionEventManager.getInstance().sendEvent(
|
|
86
|
+
StallionEventConstants.NativeStageEventTypes.DOWNLOAD_STARTED_STAGE.toString(),
|
|
87
|
+
startedPayload
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
private static void emitDownloadErrorStage(String releaseHash, String error) {
|
|
92
|
+
JSONObject errorPayload = new JSONObject();
|
|
93
|
+
try {
|
|
94
|
+
errorPayload.put("releaseHash", releaseHash);
|
|
95
|
+
errorPayload.put("meta", error);
|
|
96
|
+
} catch (Exception ignored) { }
|
|
97
|
+
StallionEventManager.getInstance().sendEvent(
|
|
98
|
+
StallionEventConstants.NativeStageEventTypes.DOWNLOAD_ERROR_STAGE.toString(),
|
|
99
|
+
errorPayload
|
|
100
|
+
);
|
|
101
|
+
}
|
|
77
102
|
}
|
|
@@ -24,18 +24,19 @@ public class StallionConfig {
|
|
|
24
24
|
this.sharedPreferences = sharedPreferences;
|
|
25
25
|
Resources res = context.getResources();
|
|
26
26
|
String parentPackageName= context.getPackageName();
|
|
27
|
+
|
|
27
28
|
int stallionProjectIdRes = res.getIdentifier(
|
|
28
29
|
StallionConfigConstants.STALLION_PROJECT_ID_IDENTIFIER,
|
|
29
30
|
"string",
|
|
30
31
|
parentPackageName
|
|
31
32
|
);
|
|
32
|
-
this.projectId = context.getString(stallionProjectIdRes);
|
|
33
|
+
this.projectId = stallionProjectIdRes != 0 ?context.getString(stallionProjectIdRes) : "";
|
|
33
34
|
int stallionAppTokenRes = res.getIdentifier(
|
|
34
35
|
StallionConfigConstants.STALLION_APP_TOKEN_IDENTIFIER,
|
|
35
36
|
"string",
|
|
36
37
|
parentPackageName
|
|
37
38
|
);
|
|
38
|
-
this.appToken = context.getString(stallionAppTokenRes);
|
|
39
|
+
this.appToken = stallionAppTokenRes != 0 ? context.getString(stallionAppTokenRes) : "";
|
|
39
40
|
|
|
40
41
|
// get or generate UID
|
|
41
42
|
String cachedUniqueId = sharedPreferences.getString(
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
package com.stallion.utils;
|
|
2
|
+
|
|
3
|
+
import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
|
|
4
|
+
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
|
|
5
|
+
|
|
6
|
+
import android.app.Activity;
|
|
7
|
+
import android.app.ActivityManager;
|
|
8
|
+
import android.content.Context;
|
|
9
|
+
import android.content.Intent;
|
|
10
|
+
import android.os.Bundle;
|
|
11
|
+
import android.os.Process;
|
|
12
|
+
|
|
13
|
+
import java.util.ArrayList;
|
|
14
|
+
import java.util.Arrays;
|
|
15
|
+
import java.util.List;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Process Phoenix facilitates restarting your application process. This should only be used for
|
|
19
|
+
* things like fundamental state changes in your debug builds (e.g., changing from staging to
|
|
20
|
+
* production).
|
|
21
|
+
* <p>
|
|
22
|
+
* Trigger process recreation by calling {@link #triggerRebirth} with a {@link Context} instance.
|
|
23
|
+
*/
|
|
24
|
+
public final class ProcessPhoenix extends Activity {
|
|
25
|
+
private static final String KEY_RESTART_INTENTS = "phoenix_restart_intents";
|
|
26
|
+
private static final String KEY_MAIN_PROCESS_PID = "phoenix_main_process_pid";
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Call to restart the application process using the {@linkplain Intent#CATEGORY_DEFAULT default}
|
|
30
|
+
* activity as an intent.
|
|
31
|
+
* <p>
|
|
32
|
+
* Behavior of the current process after invoking this method is undefined.
|
|
33
|
+
*/
|
|
34
|
+
public static void triggerRebirth(Context context) {
|
|
35
|
+
triggerRebirth(context, getRestartIntent(context));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Call to restart the application process using the specified intents.
|
|
40
|
+
* <p>
|
|
41
|
+
* Behavior of the current process after invoking this method is undefined.
|
|
42
|
+
*/
|
|
43
|
+
public static void triggerRebirth(Context context, Intent... nextIntents) {
|
|
44
|
+
if (nextIntents.length < 1) {
|
|
45
|
+
throw new IllegalArgumentException("intents cannot be empty");
|
|
46
|
+
}
|
|
47
|
+
// create a new task for the first activity.
|
|
48
|
+
nextIntents[0].addFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK);
|
|
49
|
+
|
|
50
|
+
Intent intent = new Intent(context, ProcessPhoenix.class);
|
|
51
|
+
intent.addFlags(FLAG_ACTIVITY_NEW_TASK); // In case we are called with non-Activity context.
|
|
52
|
+
intent.putParcelableArrayListExtra(KEY_RESTART_INTENTS, new ArrayList<>(Arrays.asList(nextIntents)));
|
|
53
|
+
intent.putExtra(KEY_MAIN_PROCESS_PID, Process.myPid());
|
|
54
|
+
context.startActivity(intent);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
private static Intent getRestartIntent(Context context) {
|
|
58
|
+
String packageName = context.getPackageName();
|
|
59
|
+
Intent defaultIntent = context.getPackageManager().getLaunchIntentForPackage(packageName);
|
|
60
|
+
if (defaultIntent != null) {
|
|
61
|
+
return defaultIntent;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
throw new IllegalStateException("Unable to determine default activity for "
|
|
65
|
+
+ packageName
|
|
66
|
+
+ ". Does an activity specify the DEFAULT category in its intent filter?");
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
@Override protected void onCreate(Bundle savedInstanceState) {
|
|
70
|
+
super.onCreate(savedInstanceState);
|
|
71
|
+
|
|
72
|
+
Process.killProcess(getIntent().getIntExtra(KEY_MAIN_PROCESS_PID, -1)); // Kill original main process
|
|
73
|
+
|
|
74
|
+
ArrayList<Intent> intents = getIntent().getParcelableArrayListExtra(KEY_RESTART_INTENTS);
|
|
75
|
+
startActivities(intents.toArray(new Intent[intents.size()]));
|
|
76
|
+
finish();
|
|
77
|
+
Runtime.getRuntime().exit(0); // Kill kill kill!
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Checks if the current process is a temporary Phoenix Process.
|
|
82
|
+
* This can be used to avoid initialisation of unused resources or to prevent running code that
|
|
83
|
+
* is not multi-process ready.
|
|
84
|
+
*
|
|
85
|
+
* @return true if the current process is a temporary Phoenix Process
|
|
86
|
+
*/
|
|
87
|
+
public static boolean isPhoenixProcess(Context context) {
|
|
88
|
+
int currentPid = Process.myPid();
|
|
89
|
+
ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
|
|
90
|
+
List<ActivityManager.RunningAppProcessInfo> runningProcesses = manager.getRunningAppProcesses();
|
|
91
|
+
if (runningProcesses != null) {
|
|
92
|
+
for (ActivityManager.RunningAppProcessInfo processInfo : runningProcesses) {
|
|
93
|
+
if (processInfo.pid == currentPid && processInfo.processName.endsWith(":phoenix")) {
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
}
|
package/ios/main/Stallion.m
CHANGED
package/ios/main/Stallion.swift
CHANGED
|
@@ -80,8 +80,11 @@ class StallionConstants {
|
|
|
80
80
|
static let EXCEPTION_PROD = "EXCEPTION_PROD"
|
|
81
81
|
}
|
|
82
82
|
public struct NativeEventTypesStage {
|
|
83
|
+
static let DOWNLOAD_STARTED_STAGE = "DOWNLOAD_STARTED_STAGE"
|
|
83
84
|
static let DOWNLOAD_ERROR_STAGE = "DOWNLOAD_ERROR_STAGE"
|
|
84
85
|
static let DOWNLOAD_PROGRESS_STAGE = "DOWNLOAD_PROGRESS_STAGE"
|
|
85
86
|
static let DOWNLOAD_COMPLETE_STAGE = "DOWNLOAD_COMPLETE_STAGE"
|
|
87
|
+
static let INSTALLED_STAGE = "INSTALLED_STAGE"
|
|
88
|
+
static let EXCEPTION_STAGE = "EXCEPTION_STAGE"
|
|
86
89
|
}
|
|
87
90
|
}
|
|
@@ -114,6 +114,7 @@
|
|
|
114
114
|
stallionMeta.stageNewHash = stageTempHash;
|
|
115
115
|
stallionMeta.stageTempHash = @"";
|
|
116
116
|
[stateManager syncStallionMeta];
|
|
117
|
+
[self sendInstallEventStage:stageTempHash];
|
|
117
118
|
} @catch (NSException *exception) {
|
|
118
119
|
NSLog(@"Error mounting new stage bundle: %@", exception.reason);
|
|
119
120
|
}
|
|
@@ -127,7 +128,7 @@
|
|
|
127
128
|
} else {
|
|
128
129
|
[self sendCorruptionEvent:releaseHash folderPath:folderPath];
|
|
129
130
|
if(isProd) {
|
|
130
|
-
[StallionSlotManager rollbackProdWithAutoRollback:
|
|
131
|
+
[StallionSlotManager rollbackProdWithAutoRollback:false errorString:@"Corruped File not found"];
|
|
131
132
|
} else {
|
|
132
133
|
[StallionSlotManager rollbackStage];
|
|
133
134
|
}
|
|
@@ -140,6 +141,11 @@
|
|
|
140
141
|
[[StallionEventHandler sharedInstance] cacheEvent:[StallionObjConstants installed_prod_event] eventPayload:eventPayload];
|
|
141
142
|
}
|
|
142
143
|
|
|
144
|
+
+ (void)sendInstallEventStage:(NSString *)releaseHash {
|
|
145
|
+
NSDictionary *eventPayload = @{[StallionObjConstants release_hash_key]: releaseHash};
|
|
146
|
+
[[StallionEventHandler sharedInstance] cacheEvent:[StallionObjConstants installed_stage_event] eventPayload:eventPayload];
|
|
147
|
+
}
|
|
148
|
+
|
|
143
149
|
+ (void)sendCorruptionEvent:(NSString *)releaseHash folderPath:(NSString *)folderPath {
|
|
144
150
|
NSDictionary *eventPayload = @{
|
|
145
151
|
[StallionObjConstants release_hash_key]: releaseHash,
|
|
@@ -33,6 +33,8 @@
|
|
|
33
33
|
@property (class, nonatomic, readonly) NSString *exception_stage_event;
|
|
34
34
|
@property (class, nonatomic, readonly) NSString *stabilized_prod_event;
|
|
35
35
|
|
|
36
|
+
@property (class, nonatomic, readonly) NSString *installed_stage_event;
|
|
37
|
+
|
|
36
38
|
@property (class, nonatomic, readonly) NSString *release_hash_key;
|
|
37
39
|
|
|
38
40
|
@property (class, nonatomic, readonly) NSString *app_version_cache_key;
|
|
@@ -71,8 +71,8 @@
|
|
|
71
71
|
StallionStateManager *stateManager = [StallionStateManager sharedInstance];
|
|
72
72
|
NSString *baseFolderPath = stateManager.stallionConfig.filesDirectory;
|
|
73
73
|
|
|
74
|
-
NSString *newSlotPath = [NSString stringWithFormat:@"
|
|
75
|
-
NSString *stableSlotPath = [NSString stringWithFormat:@"
|
|
74
|
+
NSString *newSlotPath = [NSString stringWithFormat:@"%@/%@/%@", baseFolderPath, StallionObjConstants.prod_directory, StallionObjConstants.new_folder_slot];
|
|
75
|
+
NSString *stableSlotPath = [NSString stringWithFormat:@"%@/%@/%@", baseFolderPath, StallionObjConstants.prod_directory, StallionObjConstants.stable_folder_slot];
|
|
76
76
|
|
|
77
77
|
[StallionFileManager copyFileOrDirectoryFrom:newSlotPath to:stableSlotPath];
|
|
78
78
|
|
|
@@ -42,6 +42,8 @@ class StallionStageManager: NSObject {
|
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
+
emitDownloadStartedStage(releaseHash: receivedHash)
|
|
46
|
+
|
|
45
47
|
// Start bundle download
|
|
46
48
|
StallionFileDownloader().downloadBundle(
|
|
47
49
|
url: URL(string: receivedDownloadUrl)!,
|
|
@@ -58,17 +60,29 @@ class StallionStageManager: NSObject {
|
|
|
58
60
|
},
|
|
59
61
|
reject: { code, prefix, error in
|
|
60
62
|
let errorMessage = "\(prefix ?? "") \(error?.localizedDescription ?? "Unknown error")"
|
|
63
|
+
emitDownloadErrorStage(releaseHash: receivedHash, error: errorMessage)
|
|
61
64
|
rejectClosure(code, errorMessage, error)
|
|
62
65
|
}
|
|
63
66
|
)
|
|
64
67
|
}
|
|
65
68
|
|
|
66
69
|
// MARK: - Event Emitters
|
|
70
|
+
|
|
71
|
+
private static func emitDownloadErrorStage(releaseHash: String, error: String) {
|
|
72
|
+
let errorPayload: NSDictionary = [
|
|
73
|
+
"releaseHash": releaseHash,
|
|
74
|
+
"meta": error
|
|
75
|
+
]
|
|
76
|
+
Stallion.sendEventToRn(eventName: StallionConstants.NativeEventTypesStage.DOWNOAD_ERROR_STAGE,
|
|
77
|
+
eventBody: errorPayload,
|
|
78
|
+
shouldCache: true
|
|
79
|
+
)
|
|
80
|
+
}
|
|
67
81
|
|
|
68
82
|
private static func emitDownloadSuccessStage(releaseHash: String) {
|
|
69
83
|
let successPayload: NSDictionary = ["releaseHash": releaseHash]
|
|
70
84
|
Stallion.sendEventToRn(eventName: StallionConstants.NativeEventTypesStage.DOWNLOAD_COMPLETE_STAGE,eventBody: successPayload,
|
|
71
|
-
shouldCache:
|
|
85
|
+
shouldCache: true
|
|
72
86
|
)
|
|
73
87
|
}
|
|
74
88
|
|
|
@@ -81,4 +95,11 @@ class StallionStageManager: NSObject {
|
|
|
81
95
|
shouldCache: false
|
|
82
96
|
)
|
|
83
97
|
}
|
|
98
|
+
private static func emitDownloadStartedStage(releaseHash: String) {
|
|
99
|
+
let startedPayload: NSDictionary = ["releaseHash": releaseHash]
|
|
100
|
+
Stallion.sendEventToRn(eventName: StallionConstants.NativeEventTypesStage.DOWNLOAD_STARTED_STAGE,
|
|
101
|
+
eventBody: startedPayload,
|
|
102
|
+
shouldCache: true
|
|
103
|
+
)
|
|
104
|
+
}
|
|
84
105
|
}
|
|
@@ -14,16 +14,25 @@ class StallionSyncHandler {
|
|
|
14
14
|
private static let syncQueue = DispatchQueue(label: "com.stallion.syncQueue")
|
|
15
15
|
|
|
16
16
|
static func sync() {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
var shouldProceed = false
|
|
18
|
+
|
|
19
|
+
syncQueue.sync {
|
|
20
|
+
if !isSyncInProgress {
|
|
21
|
+
isSyncInProgress = true
|
|
22
|
+
shouldProceed = true
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
guard shouldProceed else { return }
|
|
21
27
|
|
|
22
28
|
DispatchQueue.global().async {
|
|
23
29
|
do {
|
|
24
30
|
// Fetch StallionStateManager and StallionConfig
|
|
25
31
|
let stateManager = StallionStateManager.sharedInstance()
|
|
26
|
-
guard let config = stateManager?.stallionConfig else {
|
|
32
|
+
guard let config = stateManager?.stallionConfig else {
|
|
33
|
+
completeSync()
|
|
34
|
+
return
|
|
35
|
+
}
|
|
27
36
|
|
|
28
37
|
// Use appVersion directly from StallionConfig
|
|
29
38
|
let appVersion = config.appVersion ?? ""
|
|
@@ -43,7 +52,7 @@ class StallionSyncHandler {
|
|
|
43
52
|
makeApiCall(payload: requestPayload, appVersion: appVersion)
|
|
44
53
|
|
|
45
54
|
} catch {
|
|
46
|
-
|
|
55
|
+
completeSync()
|
|
47
56
|
emitSyncError(error)
|
|
48
57
|
}
|
|
49
58
|
}
|
|
@@ -62,27 +71,27 @@ class StallionSyncHandler {
|
|
|
62
71
|
// Add tokens
|
|
63
72
|
request.setValue(StallionStateManager.sharedInstance()?.stallionConfig?.appToken, forHTTPHeaderField: StallionConstants.STALLION_APP_TOKEN_KEY)
|
|
64
73
|
request.setValue(StallionStateManager.sharedInstance()?.stallionConfig?.sdkToken, forHTTPHeaderField: StallionConstants.STALLION_SDK_TOKEN_KEY)
|
|
65
|
-
|
|
74
|
+
request.setValue(StallionStateManager.sharedInstance()?.stallionConfig?.uid, forHTTPHeaderField: StallionConstants.STALLION_UID_KEY)
|
|
66
75
|
|
|
67
76
|
// Convert payload to JSON
|
|
68
77
|
do {
|
|
69
78
|
let jsonData = try JSONSerialization.data(withJSONObject: payload, options: [])
|
|
70
79
|
request.httpBody = jsonData
|
|
71
80
|
} catch {
|
|
72
|
-
|
|
81
|
+
completeSync()
|
|
73
82
|
emitSyncError(error)
|
|
74
83
|
return
|
|
75
84
|
}
|
|
76
85
|
|
|
77
86
|
let task = URLSession.shared.dataTask(with: request) { data, response, error in
|
|
78
87
|
if let error = error {
|
|
79
|
-
|
|
88
|
+
completeSync()
|
|
80
89
|
emitSyncError(error)
|
|
81
90
|
return
|
|
82
91
|
}
|
|
83
92
|
|
|
84
93
|
guard let data = data, let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200 else {
|
|
85
|
-
|
|
94
|
+
completeSync()
|
|
86
95
|
let responseError = NSError(domain: "Invalid response from server", code: -2)
|
|
87
96
|
emitSyncError(responseError)
|
|
88
97
|
return
|
|
@@ -91,21 +100,27 @@ class StallionSyncHandler {
|
|
|
91
100
|
// Parse the JSON response
|
|
92
101
|
do {
|
|
93
102
|
if let releaseMeta = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
|
|
94
|
-
|
|
103
|
+
completeSync()
|
|
95
104
|
processReleaseMeta(releaseMeta, appVersion: appVersion)
|
|
96
105
|
} else {
|
|
97
|
-
|
|
106
|
+
completeSync()
|
|
98
107
|
let parsingError = NSError(domain: "Invalid JSON format", code: -3)
|
|
99
108
|
emitSyncError(parsingError)
|
|
100
109
|
}
|
|
101
110
|
} catch {
|
|
102
|
-
|
|
111
|
+
completeSync()
|
|
103
112
|
emitSyncError(error)
|
|
104
113
|
}
|
|
105
114
|
}
|
|
106
115
|
|
|
107
116
|
task.resume()
|
|
108
117
|
}
|
|
118
|
+
|
|
119
|
+
private static func completeSync() {
|
|
120
|
+
syncQueue.sync {
|
|
121
|
+
isSyncInProgress = false
|
|
122
|
+
}
|
|
123
|
+
}
|
|
109
124
|
|
|
110
125
|
private static func processReleaseMeta(_ releaseMeta: [String: Any], appVersion: String) {
|
|
111
126
|
guard let success = releaseMeta["success"] as? Bool, success else { return }
|
|
@@ -152,10 +167,14 @@ class StallionSyncHandler {
|
|
|
152
167
|
guard let stateManager = StallionStateManager.sharedInstance(),
|
|
153
168
|
let config = stateManager.stallionConfig else { return }
|
|
154
169
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
170
|
+
var shouldDownload = false
|
|
171
|
+
syncQueue.sync {
|
|
172
|
+
if !isDownloadInProgress {
|
|
173
|
+
isDownloadInProgress = true
|
|
174
|
+
shouldDownload = true
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
guard shouldDownload else { return }
|
|
159
178
|
|
|
160
179
|
let downloadPath = config.filesDirectory + "/" + StallionConstants.PROD_DIRECTORY + "/" + StallionConstants.TEMP_FOLDER_SLOT
|
|
161
180
|
let projectId = config.projectId ?? ""
|
|
@@ -167,7 +186,7 @@ class StallionSyncHandler {
|
|
|
167
186
|
StallionFileDownloader().downloadBundle(url: fromUrl, downloadDirectory: downloadPath, onProgress: { progress in
|
|
168
187
|
// Handle progress updates if necessary
|
|
169
188
|
}, resolve: { _ in
|
|
170
|
-
|
|
189
|
+
completeDownload()
|
|
171
190
|
stateManager.stallionMeta?.currentProdSlot = SlotStates.newSlot
|
|
172
191
|
stateManager.stallionMeta?.prodTempHash = newReleaseHash
|
|
173
192
|
if let currentProdNewHash = stateManager.stallionMeta?.prodNewHash,
|
|
@@ -177,13 +196,19 @@ class StallionSyncHandler {
|
|
|
177
196
|
stateManager.syncStallionMeta()
|
|
178
197
|
emitDownloadSuccess(releaseHash: newReleaseHash)
|
|
179
198
|
}, reject: { code, prefix, error in
|
|
180
|
-
|
|
199
|
+
completeDownload()
|
|
181
200
|
emitDownloadError(
|
|
182
201
|
releaseHash: newReleaseHash,
|
|
183
202
|
error: "\(String(describing: prefix))\(String(describing: error))"
|
|
184
203
|
)
|
|
185
204
|
})
|
|
186
205
|
}
|
|
206
|
+
|
|
207
|
+
private static func completeDownload() {
|
|
208
|
+
syncQueue.sync {
|
|
209
|
+
isDownloadInProgress = false
|
|
210
|
+
}
|
|
211
|
+
}
|
|
187
212
|
|
|
188
213
|
// MARK: - Event Emission
|
|
189
214
|
|
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -18,7 +18,7 @@ if (StallionNativeModule !== null && StallionNativeModule !== void 0 && Stallion
|
|
|
18
18
|
withStallion = withStallionNoop;
|
|
19
19
|
useStallionModal = useStallionModalNoop;
|
|
20
20
|
}
|
|
21
|
-
export { sync } from './main/utils/StallionNativeUtils';
|
|
21
|
+
export { sync, restart } from './main/utils/StallionNativeUtils';
|
|
22
22
|
export { useStallionUpdate } from './main/utils/useStallionUpdate';
|
|
23
23
|
export const addEventListener = stallionEventEmitter.addEventListener.bind(stallionEventEmitter);
|
|
24
24
|
//# sourceMappingURL=index.js.map
|
package/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["StallionNativeModule","STALLION_DISABLED_ERROR","withStallionNoop","useStallionModalNoop","withStallionMain","useStallionModalMain","stallionEventEmitter","withStallion","useStallionModal","getStallionConfig","console","warn","sync","useStallionUpdate","addEventListener","bind"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":"AAAA,OAAOA,oBAAoB,IACzBC,uBAAuB,QAClB,wBAAwB;;AAE/B;AACA,OAAOC,gBAAgB,MAAM,qBAAqB;AAClD,OAAOC,oBAAoB,MAAM,yBAAyB;;AAE1D;AACA,OAAOC,gBAAgB,MAAM,2BAA2B;AACxD,OAAOC,oBAAoB,MAAM,+BAA+B;AAGhE,SAASC,oBAAoB,QAAQ,mCAAmC;AAExE,OAAO,IAAIC,YAA2B;AACtC,OAAO,IAAIC,gBAAyC;AAEpD,IAAIR,oBAAoB,aAApBA,oBAAoB,eAApBA,oBAAoB,CAAES,iBAAiB,EAAE;EAC3CF,YAAY,GAAGH,gBAAgB;EAC/BI,gBAAgB,GAAGH,oBAAoB;AACzC,CAAC,MAAM;EACLK,OAAO,CAACC,IAAI,CAACV,uBAAuB,CAAC;EACrCM,YAAY,GAAGL,gBAAgB;EAC/BM,gBAAgB,GAAGL,oBAAoB;AACzC;AAEA,SAASS,IAAI,QAAQ,kCAAkC;
|
|
1
|
+
{"version":3,"names":["StallionNativeModule","STALLION_DISABLED_ERROR","withStallionNoop","useStallionModalNoop","withStallionMain","useStallionModalMain","stallionEventEmitter","withStallion","useStallionModal","getStallionConfig","console","warn","sync","restart","useStallionUpdate","addEventListener","bind"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":"AAAA,OAAOA,oBAAoB,IACzBC,uBAAuB,QAClB,wBAAwB;;AAE/B;AACA,OAAOC,gBAAgB,MAAM,qBAAqB;AAClD,OAAOC,oBAAoB,MAAM,yBAAyB;;AAE1D;AACA,OAAOC,gBAAgB,MAAM,2BAA2B;AACxD,OAAOC,oBAAoB,MAAM,+BAA+B;AAGhE,SAASC,oBAAoB,QAAQ,mCAAmC;AAExE,OAAO,IAAIC,YAA2B;AACtC,OAAO,IAAIC,gBAAyC;AAEpD,IAAIR,oBAAoB,aAApBA,oBAAoB,eAApBA,oBAAoB,CAAES,iBAAiB,EAAE;EAC3CF,YAAY,GAAGH,gBAAgB;EAC/BI,gBAAgB,GAAGH,oBAAoB;AACzC,CAAC,MAAM;EACLK,OAAO,CAACC,IAAI,CAACV,uBAAuB,CAAC;EACrCM,YAAY,GAAGL,gBAAgB;EAC/BM,gBAAgB,GAAGL,oBAAoB;AACzC;AAEA,SAASS,IAAI,EAAEC,OAAO,QAAQ,kCAAkC;AAChE,SAASC,iBAAiB,QAAQ,gCAAgC;AAClE,OAAO,MAAMC,gBAAgB,GAC3BT,oBAAoB,CAACS,gBAAgB,CAACC,IAAI,CAACV,oBAAoB,CAAC"}
|