@bravemobile/react-native-code-push 12.4.0 → 13.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/CodePush.podspec +14 -1
- package/README.md +4 -1
- package/android/app/build.gradle +7 -0
- package/android/app/src/main/java/com/microsoft/codepush/react/CodePush.java +45 -10
- package/android/app/src/main/java/com/microsoft/codepush/react/CodePushNativeModule.java +82 -98
- package/android/app/src/main/java/com/microsoft/codepush/react/DownloadProgress.java +4 -0
- package/android/app/src/main/java/com/microsoft/codepush/react/DownloadProgressEventDispatcher.java +23 -0
- package/cli/dist/functions/runHermesEmitBinaryCommand.js +50 -26
- package/cli/functions/runHermesEmitBinaryCommand.ts +55 -25
- package/ios/CodePush/CodePush.h +40 -8
- package/ios/CodePush/{CodePush.m → CodePush.mm} +61 -62
- package/ios/CodePush.xcodeproj/project.pbxproj +6 -6
- package/package.json +19 -2
- package/react-native.config.js +3 -1
- package/src/CodePush.js +144 -93
- package/src/native/NativeCodePush.ts +162 -0
- package/src/package-mixins.js +4 -9
- package/src/specs/NativeCodePush.ts +43 -0
- package/android/app/src/main/java/com/microsoft/codepush/react/CodePushDialog.java +0 -102
- package/src/AlertAdapter.js +0 -24
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
objects = {
|
|
8
8
|
|
|
9
9
|
/* Begin PBXBuildFile section */
|
|
10
|
-
13BE3DEE1AC21097009241FE /* CodePush.
|
|
10
|
+
13BE3DEE1AC21097009241FE /* CodePush.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13BE3DED1AC21097009241FE /* CodePush.mm */; };
|
|
11
11
|
1B23B9141BF9267B000BB2F0 /* RCTConvert+CodePushInstallMode.m in Sources */ = {isa = PBXBuildFile; fileRef = 1B23B9131BF9267B000BB2F0 /* RCTConvert+CodePushInstallMode.m */; };
|
|
12
12
|
1B762E901C9A5E9A006EF800 /* CodePushErrorUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 1B762E8F1C9A5E9A006EF800 /* CodePushErrorUtils.m */; };
|
|
13
13
|
1BCC09A71CC19EB700DDC0DD /* RCTConvert+CodePushUpdateState.m in Sources */ = {isa = PBXBuildFile; fileRef = 1BCC09A61CC19EB700DDC0DD /* RCTConvert+CodePushUpdateState.m */; };
|
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
5498D8F61D21F14100B5EB43 /* CodePushUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 5498D8F51D21F14100B5EB43 /* CodePushUtils.m */; };
|
|
83
83
|
54FFEDE01BF550630061DD23 /* CodePushDownloadHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 54FFEDDF1BF550630061DD23 /* CodePushDownloadHandler.m */; };
|
|
84
84
|
6463C82D1EBA0CFB0095B8CD /* CodePushUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 5498D8F51D21F14100B5EB43 /* CodePushUtils.m */; };
|
|
85
|
-
6463C82E1EBA0CFB0095B8CD /* CodePush.
|
|
85
|
+
6463C82E1EBA0CFB0095B8CD /* CodePush.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13BE3DED1AC21097009241FE /* CodePush.mm */; };
|
|
86
86
|
6463C82F1EBA0CFB0095B8CD /* CodePushConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = 81D51F391B6181C2000DA084 /* CodePushConfig.m */; };
|
|
87
87
|
6463C8301EBA0CFB0095B8CD /* CodePushDownloadHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 54FFEDDF1BF550630061DD23 /* CodePushDownloadHandler.m */; };
|
|
88
88
|
6463C8311EBA0CFB0095B8CD /* CodePushErrorUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 1B762E8F1C9A5E9A006EF800 /* CodePushErrorUtils.m */; };
|
|
@@ -125,7 +125,7 @@
|
|
|
125
125
|
/* Begin PBXFileReference section */
|
|
126
126
|
134814201AA4EA6300B7C361 /* libCodePush.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libCodePush.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
|
127
127
|
13BE3DEC1AC21097009241FE /* CodePush.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CodePush.h; path = CodePush/CodePush.h; sourceTree = "<group>"; };
|
|
128
|
-
13BE3DED1AC21097009241FE /* CodePush.
|
|
128
|
+
13BE3DED1AC21097009241FE /* CodePush.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = CodePush.mm; path = CodePush/CodePush.mm; sourceTree = "<group>"; };
|
|
129
129
|
1B23B9131BF9267B000BB2F0 /* RCTConvert+CodePushInstallMode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "RCTConvert+CodePushInstallMode.m"; path = "CodePush/RCTConvert+CodePushInstallMode.m"; sourceTree = "<group>"; };
|
|
130
130
|
1B762E8F1C9A5E9A006EF800 /* CodePushErrorUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CodePushErrorUtils.m; path = CodePush/CodePushErrorUtils.m; sourceTree = "<group>"; };
|
|
131
131
|
1BCC09A61CC19EB700DDC0DD /* RCTConvert+CodePushUpdateState.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "RCTConvert+CodePushUpdateState.m"; path = "CodePush/RCTConvert+CodePushUpdateState.m"; sourceTree = "<group>"; };
|
|
@@ -277,7 +277,7 @@
|
|
|
277
277
|
FF90DEF92C5A808600CA8692 /* PrivacyInfo.xcprivacy */,
|
|
278
278
|
5498D8F51D21F14100B5EB43 /* CodePushUtils.m */,
|
|
279
279
|
13BE3DEC1AC21097009241FE /* CodePush.h */,
|
|
280
|
-
13BE3DED1AC21097009241FE /* CodePush.
|
|
280
|
+
13BE3DED1AC21097009241FE /* CodePush.mm */,
|
|
281
281
|
81D51F391B6181C2000DA084 /* CodePushConfig.m */,
|
|
282
282
|
54FFEDDF1BF550630061DD23 /* CodePushDownloadHandler.m */,
|
|
283
283
|
1B762E8F1C9A5E9A006EF800 /* CodePushErrorUtils.m */,
|
|
@@ -451,7 +451,7 @@
|
|
|
451
451
|
3221E4912C8ABE1400268379 /* SSZipArchive.m in Sources */,
|
|
452
452
|
5421FE311C58AD5A00986A55 /* CodePushTelemetryManager.m in Sources */,
|
|
453
453
|
3221E46F2C8ABE1300268379 /* mz_strm_wzaes.c in Sources */,
|
|
454
|
-
13BE3DEE1AC21097009241FE /* CodePush.
|
|
454
|
+
13BE3DEE1AC21097009241FE /* CodePush.mm in Sources */,
|
|
455
455
|
3221E45D2C8ABE1300268379 /* mz_zip.c in Sources */,
|
|
456
456
|
1B762E901C9A5E9A006EF800 /* CodePushErrorUtils.m in Sources */,
|
|
457
457
|
3221E4832C8ABE1400268379 /* mz_strm_split.c in Sources */,
|
|
@@ -473,7 +473,7 @@
|
|
|
473
473
|
3221E4822C8ABE1400268379 /* mz_strm_buf.c in Sources */,
|
|
474
474
|
3221E45E2C8ABE1300268379 /* mz_zip.c in Sources */,
|
|
475
475
|
6463C82D1EBA0CFB0095B8CD /* CodePushUtils.m in Sources */,
|
|
476
|
-
6463C82E1EBA0CFB0095B8CD /* CodePush.
|
|
476
|
+
6463C82E1EBA0CFB0095B8CD /* CodePush.mm in Sources */,
|
|
477
477
|
6463C82F1EBA0CFB0095B8CD /* CodePushConfig.m in Sources */,
|
|
478
478
|
6463C8301EBA0CFB0095B8CD /* CodePushDownloadHandler.m in Sources */,
|
|
479
479
|
6463C8311EBA0CFB0095B8CD /* CodePushErrorUtils.m in Sources */,
|
package/package.json
CHANGED
|
@@ -1,11 +1,24 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bravemobile/react-native-code-push",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "13.0.0",
|
|
4
4
|
"description": "React Native plugin for the CodePush service",
|
|
5
5
|
"main": "src/CodePush.js",
|
|
6
6
|
"react-native": "src/CodePush.js",
|
|
7
7
|
"source": "src/CodePush.js",
|
|
8
8
|
"types": "typings/react-native-code-push.d.ts",
|
|
9
|
+
"codegenConfig": {
|
|
10
|
+
"name": "RNCodePushSpec",
|
|
11
|
+
"type": "modules",
|
|
12
|
+
"jsSrcsDir": "src/specs",
|
|
13
|
+
"android": {
|
|
14
|
+
"javaPackageName": "com.microsoft.codepush.react"
|
|
15
|
+
},
|
|
16
|
+
"ios": {
|
|
17
|
+
"modulesProvider": {
|
|
18
|
+
"CodePush": "CodePush"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
},
|
|
9
22
|
"homepage": "https://microsoft.github.io/code-push",
|
|
10
23
|
"keywords": [
|
|
11
24
|
"react-native",
|
|
@@ -54,10 +67,11 @@
|
|
|
54
67
|
"setup": "npm install --quiet --no-progress",
|
|
55
68
|
"setup-example-app": "ts-node --project scripts/setupExampleApp/tsconfig.json scripts/setupExampleApp/runSetupExampleApp.ts",
|
|
56
69
|
"setup-expo-example-app": "ts-node --project scripts/setupExampleApp/tsconfig.json scripts/setupExpoExampleApp/runSetupExpoExampleApp.ts",
|
|
70
|
+
"type:src": "tsc --project tsconfig.json --noEmit",
|
|
57
71
|
"type:cli": "npm run --workspace cli typecheck",
|
|
58
72
|
"type:scripts": "tsc --project scripts/tsconfig.json --noEmit",
|
|
59
73
|
"type:e2e": "tsc --project e2e/tsconfig.json --noEmit",
|
|
60
|
-
"typecheck": "npm run type:cli && npm run type:scripts && npm run type:e2e",
|
|
74
|
+
"typecheck": "npm run type:src && npm run type:cli && npm run type:scripts && npm run type:e2e",
|
|
61
75
|
"build:cli": "npm run --workspace cli clean && npm run --workspace cli build",
|
|
62
76
|
"prepack": "npm run build:cli",
|
|
63
77
|
"publish": "npm publish --access=public",
|
|
@@ -94,6 +108,7 @@
|
|
|
94
108
|
"@eslint/js": "^9.13.0",
|
|
95
109
|
"@types/express": "^5.0.6",
|
|
96
110
|
"@types/node": "^18.19.129",
|
|
111
|
+
"@types/react": "19.2.14",
|
|
97
112
|
"@types/semver": "^7.5.8",
|
|
98
113
|
"@types/shelljs": "^0.8.15",
|
|
99
114
|
"@types/yauzl": "^2.10.3",
|
|
@@ -103,6 +118,8 @@
|
|
|
103
118
|
"express": "latest",
|
|
104
119
|
"globals": "^15.11.0",
|
|
105
120
|
"jest": "^29.7.0",
|
|
121
|
+
"react": "19.2.3",
|
|
122
|
+
"react-native": "0.84.1",
|
|
106
123
|
"ts-node": "^10.9.2",
|
|
107
124
|
"typescript": "5.0.4",
|
|
108
125
|
"typescript-eslint": "^8.11.0"
|
package/react-native.config.js
CHANGED
|
@@ -5,7 +5,9 @@ module.exports = {
|
|
|
5
5
|
packageImportPath: "import com.microsoft.codepush.react.CodePush;",
|
|
6
6
|
packageInstance:
|
|
7
7
|
"CodePush.getInstance(getApplicationContext(), BuildConfig.DEBUG)",
|
|
8
|
-
sourceDir: './android/app'
|
|
8
|
+
sourceDir: './android/app',
|
|
9
|
+
libraryName: 'RNCodePushSpec',
|
|
10
|
+
cmakeListsPath: 'build/generated/source/codegen/jni/CMakeLists.txt',
|
|
9
11
|
}
|
|
10
12
|
}
|
|
11
13
|
}
|
package/src/CodePush.js
CHANGED
|
@@ -1,14 +1,46 @@
|
|
|
1
|
-
import { Alert } from "
|
|
2
|
-
import { AppState, Platform } from "react-native";
|
|
1
|
+
import { Alert, AppState, Platform } from "react-native";
|
|
3
2
|
import log from "./logging";
|
|
4
3
|
import hoistStatics from 'hoist-non-react-statics';
|
|
5
4
|
import { SemverVersioning } from './versioning/SemverVersioning'
|
|
6
5
|
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
const NativeCodePushModule = require("./native/NativeCodePush");
|
|
7
|
+
let NativeCodePush = NativeCodePushModule.getNativeCodePush?.() ?? NativeCodePushModule.default;
|
|
8
|
+
const { InstallMode, UpdateState } = NativeCodePushModule;
|
|
9
|
+
let PackageMixins = NativeCodePush ? require("./package-mixins")(NativeCodePush) : null;
|
|
9
10
|
|
|
10
11
|
const DEPLOYMENT_KEY = 'deprecated_deployment_key';
|
|
11
12
|
|
|
13
|
+
function getNativeCodePush() {
|
|
14
|
+
if (!NativeCodePush) {
|
|
15
|
+
const NativeCodePushModule = require("./native/NativeCodePush");
|
|
16
|
+
NativeCodePush = NativeCodePushModule.getNativeCodePush?.() ?? NativeCodePushModule.default;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (NativeCodePush && !PackageMixins) {
|
|
20
|
+
PackageMixins = require("./package-mixins")(NativeCodePush);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return NativeCodePush;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function requireNativeCodePush(callerName) {
|
|
27
|
+
const nativeCodePush = getNativeCodePush();
|
|
28
|
+
if (!nativeCodePush) {
|
|
29
|
+
throw new Error(`The CodePush native module isn't available during ${callerName}.`);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return nativeCodePush;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function requirePackageMixins(callerName) {
|
|
36
|
+
const nativeCodePush = requireNativeCodePush(callerName);
|
|
37
|
+
if (!PackageMixins) {
|
|
38
|
+
PackageMixins = require("./package-mixins")(nativeCodePush);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return PackageMixins;
|
|
42
|
+
}
|
|
43
|
+
|
|
12
44
|
/**
|
|
13
45
|
* @param deviceId {string}
|
|
14
46
|
* @returns {number}
|
|
@@ -67,7 +99,7 @@ async function checkForUpdate(handleBinaryVersionMismatchCallback = null) {
|
|
|
67
99
|
* for their specific deployment and version and which are actually
|
|
68
100
|
* different from the CodePush update they have already installed.
|
|
69
101
|
*/
|
|
70
|
-
const nativeConfig = await getConfiguration();
|
|
102
|
+
const nativeConfig = await getConfiguration("checkForUpdate");
|
|
71
103
|
|
|
72
104
|
// Use dynamically overridden getCurrentPackage() during tests.
|
|
73
105
|
const localPackage = await module.exports.getCurrentPackage();
|
|
@@ -217,8 +249,10 @@ async function checkForUpdate(handleBinaryVersionMismatchCallback = null) {
|
|
|
217
249
|
|
|
218
250
|
return null;
|
|
219
251
|
} else {
|
|
220
|
-
const
|
|
221
|
-
|
|
252
|
+
const nativeCodePush = requireNativeCodePush("checkForUpdate");
|
|
253
|
+
const packageMixins = requirePackageMixins("checkForUpdate");
|
|
254
|
+
const remotePackage = { ...update, ...packageMixins.remote() };
|
|
255
|
+
remotePackage.failedInstall = await nativeCodePush.isFailedUpdate(remotePackage.packageHash);
|
|
222
256
|
return remotePackage;
|
|
223
257
|
}
|
|
224
258
|
}
|
|
@@ -252,13 +286,14 @@ function mapToRemotePackageMetadata(updateInfo) {
|
|
|
252
286
|
|
|
253
287
|
const getConfiguration = (() => {
|
|
254
288
|
let config;
|
|
255
|
-
return async function getConfiguration() {
|
|
289
|
+
return async function getConfiguration(callerName = "getConfiguration") {
|
|
256
290
|
if (config) {
|
|
257
291
|
return config;
|
|
258
292
|
} else if (testConfig) {
|
|
259
293
|
return testConfig;
|
|
260
294
|
} else {
|
|
261
|
-
|
|
295
|
+
const nativeCodePush = requireNativeCodePush(callerName);
|
|
296
|
+
config = await nativeCodePush.getConfiguration();
|
|
262
297
|
return config;
|
|
263
298
|
}
|
|
264
299
|
}
|
|
@@ -269,11 +304,13 @@ async function getCurrentPackage() {
|
|
|
269
304
|
}
|
|
270
305
|
|
|
271
306
|
async function getUpdateMetadata(updateState) {
|
|
272
|
-
|
|
307
|
+
const nativeCodePush = requireNativeCodePush("getUpdateMetadata");
|
|
308
|
+
const packageMixins = requirePackageMixins("getUpdateMetadata");
|
|
309
|
+
let updateMetadata = await nativeCodePush.getUpdateMetadata(updateState || CodePush.UpdateState.RUNNING);
|
|
273
310
|
if (updateMetadata) {
|
|
274
|
-
updateMetadata = { ...
|
|
275
|
-
updateMetadata.failedInstall = await
|
|
276
|
-
updateMetadata.isFirstRun = await
|
|
311
|
+
updateMetadata = { ...packageMixins.local, ...updateMetadata };
|
|
312
|
+
updateMetadata.failedInstall = await nativeCodePush.isFailedUpdate(updateMetadata.packageHash);
|
|
313
|
+
updateMetadata.isFirstRun = await nativeCodePush.isFirstRun(updateMetadata.packageHash);
|
|
277
314
|
}
|
|
278
315
|
return updateMetadata;
|
|
279
316
|
}
|
|
@@ -292,14 +329,21 @@ const notifyApplicationReady = (() => {
|
|
|
292
329
|
})();
|
|
293
330
|
|
|
294
331
|
async function notifyApplicationReadyInternal() {
|
|
295
|
-
|
|
296
|
-
|
|
332
|
+
const nativeCodePush = requireNativeCodePush("notifyApplicationReady");
|
|
333
|
+
await nativeCodePush.notifyApplicationReady();
|
|
334
|
+
const statusReport = await nativeCodePush.getNewStatusReport();
|
|
297
335
|
statusReport && tryReportStatus(statusReport); // Don't wait for this to complete.
|
|
298
336
|
|
|
299
337
|
return statusReport;
|
|
300
338
|
}
|
|
301
339
|
|
|
302
340
|
async function tryReportStatus(statusReport, retryOnAppResume) {
|
|
341
|
+
const nativeCodePush = getNativeCodePush();
|
|
342
|
+
if (!nativeCodePush) {
|
|
343
|
+
retryOnAppResume && retryOnAppResume.remove();
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
346
|
+
|
|
303
347
|
try {
|
|
304
348
|
if (statusReport.appVersion) {
|
|
305
349
|
log(`Reporting binary update (${statusReport.appVersion})`);
|
|
@@ -310,22 +354,27 @@ async function tryReportStatus(statusReport, retryOnAppResume) {
|
|
|
310
354
|
sharedCodePushOptions?.onUpdateSuccess?.(label);
|
|
311
355
|
} else {
|
|
312
356
|
log(`Reporting CodePush update rollback (${label})`);
|
|
313
|
-
await
|
|
357
|
+
await nativeCodePush.setLatestRollbackInfo(statusReport.package.packageHash);
|
|
314
358
|
sharedCodePushOptions?.onUpdateRollback?.(label);
|
|
315
359
|
}
|
|
316
360
|
}
|
|
317
361
|
|
|
318
|
-
|
|
362
|
+
nativeCodePush.recordStatusReported(statusReport);
|
|
319
363
|
retryOnAppResume && retryOnAppResume.remove();
|
|
320
364
|
} catch (e) {
|
|
321
365
|
log(`${e}`)
|
|
322
366
|
log(`Report status failed: ${JSON.stringify(statusReport)}`);
|
|
323
|
-
|
|
367
|
+
nativeCodePush.saveStatusReportForRetry(statusReport);
|
|
324
368
|
// Try again when the app resumes
|
|
325
369
|
if (!retryOnAppResume) {
|
|
326
370
|
const resumeListener = AppState.addEventListener("change", async (newState) => {
|
|
327
371
|
if (newState !== "active") return;
|
|
328
|
-
const
|
|
372
|
+
const refreshedNativeCodePush = getNativeCodePush();
|
|
373
|
+
if (!refreshedNativeCodePush) {
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
const refreshedStatusReport = await refreshedNativeCodePush.getNewStatusReport();
|
|
329
378
|
if (refreshedStatusReport) {
|
|
330
379
|
tryReportStatus(refreshedStatusReport, resumeListener);
|
|
331
380
|
} else {
|
|
@@ -358,7 +407,8 @@ async function shouldUpdateBeIgnored(remotePackage, syncOptions) {
|
|
|
358
407
|
return true;
|
|
359
408
|
}
|
|
360
409
|
|
|
361
|
-
const
|
|
410
|
+
const nativeCodePush = requireNativeCodePush("shouldUpdateBeIgnored");
|
|
411
|
+
const latestRollbackInfo = await nativeCodePush.getLatestRollbackInfo();
|
|
362
412
|
if (!validateLatestRollbackInfo(latestRollbackInfo, remotePackage.packageHash)) {
|
|
363
413
|
log("The latest rollback info is not valid.");
|
|
364
414
|
return true;
|
|
@@ -407,11 +457,15 @@ let testConfig;
|
|
|
407
457
|
function setUpTestDependencies(testSdk, providedTestConfig, testNativeBridge) {
|
|
408
458
|
if (testSdk) module.exports.AcquisitionSdk = testSdk;
|
|
409
459
|
if (providedTestConfig) testConfig = providedTestConfig;
|
|
410
|
-
if (testNativeBridge)
|
|
460
|
+
if (testNativeBridge) {
|
|
461
|
+
NativeCodePush = testNativeBridge;
|
|
462
|
+
PackageMixins = require("./package-mixins")(NativeCodePush);
|
|
463
|
+
}
|
|
411
464
|
}
|
|
412
465
|
|
|
413
466
|
async function restartApp(onlyIfUpdateIsPending = false) {
|
|
414
|
-
|
|
467
|
+
const nativeCodePush = requireNativeCodePush("restartApp");
|
|
468
|
+
nativeCodePush.restartApp(onlyIfUpdateIsPending);
|
|
415
469
|
}
|
|
416
470
|
|
|
417
471
|
// This function allows only one syncInternal operation to proceed at any given time.
|
|
@@ -817,76 +871,73 @@ function codePushify(options = {}) {
|
|
|
817
871
|
}
|
|
818
872
|
}
|
|
819
873
|
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
} else {
|
|
889
|
-
log("The CodePush module doesn't appear to be properly installed. Please double-check that everything is setup correctly.");
|
|
890
|
-
}
|
|
874
|
+
CodePush = codePushify;
|
|
875
|
+
Object.assign(CodePush, {
|
|
876
|
+
checkForUpdate,
|
|
877
|
+
getConfiguration,
|
|
878
|
+
getCurrentPackage,
|
|
879
|
+
getUpdateMetadata,
|
|
880
|
+
log,
|
|
881
|
+
notifyAppReady: notifyApplicationReady,
|
|
882
|
+
notifyApplicationReady,
|
|
883
|
+
restartApp,
|
|
884
|
+
setUpTestDependencies,
|
|
885
|
+
sync,
|
|
886
|
+
disallowRestart: () => {
|
|
887
|
+
const nativeCodePush = requireNativeCodePush("disallowRestart");
|
|
888
|
+
return nativeCodePush.disallow();
|
|
889
|
+
},
|
|
890
|
+
allowRestart: () => {
|
|
891
|
+
const nativeCodePush = requireNativeCodePush("allowRestart");
|
|
892
|
+
return nativeCodePush.allow();
|
|
893
|
+
},
|
|
894
|
+
clearUpdates: () => {
|
|
895
|
+
const nativeCodePush = requireNativeCodePush("clearUpdates");
|
|
896
|
+
return nativeCodePush.clearUpdates();
|
|
897
|
+
},
|
|
898
|
+
InstallMode: {
|
|
899
|
+
IMMEDIATE: InstallMode.IMMEDIATE, // Restart the app immediately
|
|
900
|
+
ON_NEXT_RESTART: InstallMode.ON_NEXT_RESTART, // Don't artificially restart the app. Allow the update to be "picked up" on the next app restart
|
|
901
|
+
ON_NEXT_RESUME: InstallMode.ON_NEXT_RESUME, // Restart the app the next time it is resumed from the background
|
|
902
|
+
ON_NEXT_SUSPEND: InstallMode.ON_NEXT_SUSPEND, // Restart the app _while_ it is in the background,
|
|
903
|
+
// but only after it has been in the background for "minimumBackgroundDuration" seconds (0 by default),
|
|
904
|
+
// so that user context isn't lost unless the app suspension is long enough to not matter
|
|
905
|
+
},
|
|
906
|
+
SyncStatus: {
|
|
907
|
+
UP_TO_DATE: 0, // The running app is up-to-date
|
|
908
|
+
UPDATE_INSTALLED: 1, // The app had an optional/mandatory update that was successfully downloaded and is about to be installed.
|
|
909
|
+
UPDATE_IGNORED: 2, // The app had an optional update and the end-user chose to ignore it
|
|
910
|
+
UNKNOWN_ERROR: 3,
|
|
911
|
+
SYNC_IN_PROGRESS: 4, // There is an ongoing "sync" operation in progress.
|
|
912
|
+
CHECKING_FOR_UPDATE: 5,
|
|
913
|
+
AWAITING_USER_ACTION: 6,
|
|
914
|
+
DOWNLOADING_PACKAGE: 7,
|
|
915
|
+
INSTALLING_UPDATE: 8,
|
|
916
|
+
},
|
|
917
|
+
CheckFrequency: {
|
|
918
|
+
ON_APP_START: 0,
|
|
919
|
+
ON_APP_RESUME: 1,
|
|
920
|
+
MANUAL: 2,
|
|
921
|
+
},
|
|
922
|
+
UpdateState,
|
|
923
|
+
DeploymentStatus: {
|
|
924
|
+
FAILED: "DeploymentFailed",
|
|
925
|
+
SUCCEEDED: "DeploymentSucceeded",
|
|
926
|
+
},
|
|
927
|
+
DEFAULT_UPDATE_DIALOG: {
|
|
928
|
+
appendReleaseDescription: false,
|
|
929
|
+
descriptionPrefix: " Description: ",
|
|
930
|
+
mandatoryContinueButtonLabel: "Continue",
|
|
931
|
+
mandatoryUpdateMessage: "An update is available that must be installed.",
|
|
932
|
+
optionalIgnoreButtonLabel: "Ignore",
|
|
933
|
+
optionalInstallButtonLabel: "Install",
|
|
934
|
+
optionalUpdateMessage: "An update is available. Would you like to install it?",
|
|
935
|
+
title: "Update available",
|
|
936
|
+
},
|
|
937
|
+
DEFAULT_ROLLBACK_RETRY_OPTIONS: {
|
|
938
|
+
delayInHours: 24,
|
|
939
|
+
maxRetryAttempts: 1,
|
|
940
|
+
},
|
|
941
|
+
});
|
|
891
942
|
|
|
892
943
|
module.exports = CodePush;
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { NativeEventEmitter, NativeModules } from 'react-native';
|
|
2
|
+
import { getNativeCodePushTurboModule } from '../specs/NativeCodePush';
|
|
3
|
+
import type { DownloadProgress, Spec as NativeCodePushSpec } from '../specs/NativeCodePush';
|
|
4
|
+
|
|
5
|
+
export const DOWNLOAD_PROGRESS_EVENT_NAME = 'CodePushDownloadProgress';
|
|
6
|
+
|
|
7
|
+
export const InstallMode = Object.freeze({
|
|
8
|
+
IMMEDIATE: 0,
|
|
9
|
+
ON_NEXT_RESTART: 1,
|
|
10
|
+
ON_NEXT_RESUME: 2,
|
|
11
|
+
ON_NEXT_SUSPEND: 3,
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
export const UpdateState = Object.freeze({
|
|
15
|
+
RUNNING: 0,
|
|
16
|
+
PENDING: 1,
|
|
17
|
+
LATEST: 2,
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
type Subscription = {
|
|
21
|
+
remove: () => void;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
type LegacyCodePushModule = {
|
|
25
|
+
addListener?: (eventName: string) => void;
|
|
26
|
+
allow: () => void | Promise<void>;
|
|
27
|
+
clearPendingRestart: () => void | Promise<void>;
|
|
28
|
+
clearUpdates: () => void;
|
|
29
|
+
disallow: () => void | Promise<void>;
|
|
30
|
+
downloadAndReplaceCurrentBundle?: (remoteBundleUrl: string) => void;
|
|
31
|
+
downloadUpdate: (updatePackage: object, notifyProgress: boolean) => Promise<object>;
|
|
32
|
+
getConfiguration: () => Promise<object>;
|
|
33
|
+
getLatestRollbackInfo: () => Promise<object | null>;
|
|
34
|
+
getNewStatusReport: () => Promise<object | string | null>;
|
|
35
|
+
getUpdateMetadata: (updateState: number) => Promise<object | null>;
|
|
36
|
+
installUpdate: (
|
|
37
|
+
updatePackage: object,
|
|
38
|
+
installMode: number,
|
|
39
|
+
minimumBackgroundDuration: number,
|
|
40
|
+
) => Promise<void>;
|
|
41
|
+
isFailedUpdate: (packageHash: string) => Promise<boolean>;
|
|
42
|
+
isFirstRun: (packageHash: string) => Promise<boolean>;
|
|
43
|
+
notifyApplicationReady: () => Promise<void>;
|
|
44
|
+
recordStatusReported: (statusReport: object) => void;
|
|
45
|
+
removeListeners?: (count: number) => void;
|
|
46
|
+
restartApp: (onlyIfUpdateIsPending: boolean) => void | Promise<void>;
|
|
47
|
+
saveStatusReportForRetry: (statusReport: object) => void;
|
|
48
|
+
setLatestRollbackInfo: (packageHash: string) => Promise<void>;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
type CodePushModule = LegacyCodePushModule & {
|
|
52
|
+
onDownloadProgress?: NativeCodePushSpec['onDownloadProgress'];
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
type EventEmitterCapableCodePushModule = LegacyCodePushModule & {
|
|
56
|
+
addListener: NonNullable<LegacyCodePushModule['addListener']>;
|
|
57
|
+
removeListeners: NonNullable<LegacyCodePushModule['removeListeners']>;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
function getTurboModule(): CodePushModule | null {
|
|
61
|
+
return getNativeCodePushTurboModule() as CodePushModule | null;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function getLegacyModule(): LegacyCodePushModule | null {
|
|
65
|
+
return (NativeModules.CodePush ?? null) as LegacyCodePushModule | null;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function getNativeModule(): CodePushModule | null {
|
|
69
|
+
const turboModule = getTurboModule();
|
|
70
|
+
if (turboModule) {
|
|
71
|
+
return turboModule;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return getLegacyModule();
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function normalizeStatusReport(statusReport: object | string | null | undefined) {
|
|
78
|
+
if (!statusReport || typeof statusReport === 'string') {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return statusReport;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function canUseNativeEventEmitter(
|
|
86
|
+
module: LegacyCodePushModule,
|
|
87
|
+
): module is EventEmitterCapableCodePushModule {
|
|
88
|
+
return (
|
|
89
|
+
typeof module.addListener === 'function' &&
|
|
90
|
+
typeof module.removeListeners === 'function'
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function addDownloadProgressListener(
|
|
95
|
+
listener: (progress: DownloadProgress) => void,
|
|
96
|
+
): Subscription {
|
|
97
|
+
const nativeModule = getNativeModule();
|
|
98
|
+
if (!nativeModule) {
|
|
99
|
+
return {
|
|
100
|
+
remove() {},
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const turboModule = getTurboModule();
|
|
105
|
+
if (turboModule?.onDownloadProgress) {
|
|
106
|
+
return turboModule.onDownloadProgress(listener);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const legacyModule = getLegacyModule();
|
|
110
|
+
if (!legacyModule || !canUseNativeEventEmitter(legacyModule)) {
|
|
111
|
+
return {
|
|
112
|
+
remove() {},
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const eventEmitter = new NativeEventEmitter(legacyModule);
|
|
117
|
+
return eventEmitter.addListener(DOWNLOAD_PROGRESS_EVENT_NAME, listener);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function createNativeCodePush() {
|
|
121
|
+
return {
|
|
122
|
+
InstallMode,
|
|
123
|
+
UpdateState,
|
|
124
|
+
addDownloadProgressListener,
|
|
125
|
+
allow: () => getNativeModule()?.allow(),
|
|
126
|
+
clearPendingRestart: () => getNativeModule()?.clearPendingRestart(),
|
|
127
|
+
clearUpdates: () => getNativeModule()?.clearUpdates(),
|
|
128
|
+
disallow: () => getNativeModule()?.disallow(),
|
|
129
|
+
downloadAndReplaceCurrentBundle: (remoteBundleUrl: string) =>
|
|
130
|
+
getNativeModule()?.downloadAndReplaceCurrentBundle?.(remoteBundleUrl),
|
|
131
|
+
downloadUpdate: (updatePackage: object, notifyProgress: boolean) =>
|
|
132
|
+
getNativeModule()?.downloadUpdate(updatePackage, notifyProgress),
|
|
133
|
+
getConfiguration: () => getNativeModule()?.getConfiguration(),
|
|
134
|
+
getLatestRollbackInfo: () => getNativeModule()?.getLatestRollbackInfo(),
|
|
135
|
+
getNewStatusReport: async () =>
|
|
136
|
+
normalizeStatusReport(await getNativeModule()?.getNewStatusReport()),
|
|
137
|
+
getUpdateMetadata: (updateState: number) => getNativeModule()?.getUpdateMetadata(updateState),
|
|
138
|
+
installUpdate: (
|
|
139
|
+
updatePackage: object,
|
|
140
|
+
installMode: number,
|
|
141
|
+
minimumBackgroundDuration: number,
|
|
142
|
+
) => getNativeModule()?.installUpdate(updatePackage, installMode, minimumBackgroundDuration),
|
|
143
|
+
isFailedUpdate: (packageHash: string) => getNativeModule()?.isFailedUpdate(packageHash),
|
|
144
|
+
isFirstRun: (packageHash: string) => getNativeModule()?.isFirstRun(packageHash),
|
|
145
|
+
notifyApplicationReady: () => getNativeModule()?.notifyApplicationReady(),
|
|
146
|
+
recordStatusReported: (statusReport: object) =>
|
|
147
|
+
getNativeModule()?.recordStatusReported(statusReport),
|
|
148
|
+
restartApp: (onlyIfUpdateIsPending: boolean) =>
|
|
149
|
+
getNativeModule()?.restartApp(onlyIfUpdateIsPending),
|
|
150
|
+
saveStatusReportForRetry: (statusReport: object) =>
|
|
151
|
+
getNativeModule()?.saveStatusReportForRetry(statusReport),
|
|
152
|
+
setLatestRollbackInfo: (packageHash: string) =>
|
|
153
|
+
getNativeModule()?.setLatestRollbackInfo(packageHash),
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export function getNativeCodePush() {
|
|
158
|
+
const nativeModule = getNativeModule();
|
|
159
|
+
return nativeModule ? createNativeCodePush() : null;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export default getNativeCodePush();
|
package/src/package-mixins.js
CHANGED
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import { NativeEventEmitter } from "react-native";
|
|
2
|
-
import log from "./logging";
|
|
3
|
-
|
|
4
1
|
// This function is used to augment remote and local
|
|
5
2
|
// package objects with additional functionality/properties
|
|
6
3
|
// beyond what is included in the metadata sent by the server.
|
|
@@ -14,10 +11,8 @@ module.exports = (NativeCodePush) => {
|
|
|
14
11
|
|
|
15
12
|
let downloadProgressSubscription;
|
|
16
13
|
if (downloadProgressCallback) {
|
|
17
|
-
const codePushEventEmitter = new NativeEventEmitter(NativeCodePush);
|
|
18
14
|
// Use event subscription to obtain download progress.
|
|
19
|
-
downloadProgressSubscription =
|
|
20
|
-
"CodePushDownloadProgress",
|
|
15
|
+
downloadProgressSubscription = NativeCodePush.addDownloadProgressListener(
|
|
21
16
|
downloadProgressCallback
|
|
22
17
|
);
|
|
23
18
|
}
|
|
@@ -41,12 +36,12 @@ module.exports = (NativeCodePush) => {
|
|
|
41
36
|
};
|
|
42
37
|
|
|
43
38
|
const local = {
|
|
44
|
-
async install(installMode = NativeCodePush.
|
|
39
|
+
async install(installMode = NativeCodePush.InstallMode.ON_NEXT_RESTART, minimumBackgroundDuration = 0, updateInstalledCallback) {
|
|
45
40
|
const localPackage = this;
|
|
46
41
|
const localPackageCopy = Object.assign({}, localPackage); // In dev mode, React Native deep freezes any object queued over the bridge
|
|
47
42
|
await NativeCodePush.installUpdate(localPackageCopy, installMode, minimumBackgroundDuration);
|
|
48
43
|
updateInstalledCallback && updateInstalledCallback();
|
|
49
|
-
if (installMode == NativeCodePush.
|
|
44
|
+
if (installMode == NativeCodePush.InstallMode.IMMEDIATE) {
|
|
50
45
|
NativeCodePush.restartApp(false);
|
|
51
46
|
} else {
|
|
52
47
|
NativeCodePush.clearPendingRestart();
|
|
@@ -58,4 +53,4 @@ module.exports = (NativeCodePush) => {
|
|
|
58
53
|
};
|
|
59
54
|
|
|
60
55
|
return { local, remote };
|
|
61
|
-
};
|
|
56
|
+
};
|