react-native-update 10.28.1 → 10.28.2
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/package.json +2 -3
- package/src/client.ts +67 -57
- package/src/provider.tsx +11 -4
- package/src/type.ts +1 -0
- package/src/utils.ts +2 -1
- package/android/.project +0 -28
- package/android/bin/.project +0 -34
- package/android/bin/.settings/org.eclipse.buildship.core.prefs +0 -13
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-update",
|
|
3
|
-
"version": "10.28.
|
|
3
|
+
"version": "10.28.2",
|
|
4
4
|
"description": "react-native hot update",
|
|
5
5
|
"main": "src/index",
|
|
6
6
|
"scripts": {
|
|
@@ -74,6 +74,5 @@
|
|
|
74
74
|
"react-native": "0.73",
|
|
75
75
|
"ts-jest": "^29.2.5",
|
|
76
76
|
"typescript": "^5.6.3"
|
|
77
|
-
}
|
|
78
|
-
"packageManager": "yarn@1.22.21+sha1.1959a18351b811cdeedbd484a8f86c3cc3bbaf72"
|
|
77
|
+
}
|
|
79
78
|
}
|
package/src/client.ts
CHANGED
|
@@ -61,6 +61,31 @@ const defaultClientOptions: ClientOptions = {
|
|
|
61
61
|
throwError: false,
|
|
62
62
|
};
|
|
63
63
|
|
|
64
|
+
export const sharedState: {
|
|
65
|
+
progressHandlers: Record<string, EmitterSubscription>;
|
|
66
|
+
downloadedHash?: string;
|
|
67
|
+
apkStatus: 'downloading' | 'downloaded' | null;
|
|
68
|
+
marked: boolean;
|
|
69
|
+
applyingUpdate: boolean;
|
|
70
|
+
} = {
|
|
71
|
+
progressHandlers: {},
|
|
72
|
+
downloadedHash: undefined,
|
|
73
|
+
apkStatus: null,
|
|
74
|
+
marked: false,
|
|
75
|
+
applyingUpdate: false,
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
const assertHash = (hash: string) => {
|
|
79
|
+
if (!sharedState.downloadedHash) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
if (hash !== sharedState.downloadedHash) {
|
|
83
|
+
log(`use downloaded hash ${sharedState.downloadedHash} first`);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
return true;
|
|
87
|
+
};
|
|
88
|
+
|
|
64
89
|
// for China users
|
|
65
90
|
export class Pushy {
|
|
66
91
|
options = defaultClientOptions;
|
|
@@ -68,13 +93,6 @@ export class Pushy {
|
|
|
68
93
|
lastChecking?: number;
|
|
69
94
|
lastRespJson?: Promise<any>;
|
|
70
95
|
|
|
71
|
-
static progressHandlers: Record<string, EmitterSubscription> = {};
|
|
72
|
-
static downloadedHash?: string;
|
|
73
|
-
|
|
74
|
-
static apkStatus: 'downloading' | 'downloaded' | null = null;
|
|
75
|
-
|
|
76
|
-
static marked = false;
|
|
77
|
-
static applyingUpdate = false;
|
|
78
96
|
version = cInfo.rnu;
|
|
79
97
|
loggerPromise = (() => {
|
|
80
98
|
let resolve: (value?: unknown) => void = () => {};
|
|
@@ -152,16 +170,6 @@ export class Pushy {
|
|
|
152
170
|
getCheckUrl = (endpoint: string = this.options.server!.main) => {
|
|
153
171
|
return `${endpoint}/checkUpdate/${this.options.appKey}`;
|
|
154
172
|
};
|
|
155
|
-
static assertHash = (hash: string) => {
|
|
156
|
-
if (!this.downloadedHash) {
|
|
157
|
-
return;
|
|
158
|
-
}
|
|
159
|
-
if (hash !== this.downloadedHash) {
|
|
160
|
-
log(`use downloaded hash ${Pushy.downloadedHash} first`);
|
|
161
|
-
return;
|
|
162
|
-
}
|
|
163
|
-
return true;
|
|
164
|
-
};
|
|
165
173
|
assertDebug = () => {
|
|
166
174
|
if (__DEV__ && !this.options.debug) {
|
|
167
175
|
console.info(
|
|
@@ -172,10 +180,10 @@ export class Pushy {
|
|
|
172
180
|
return true;
|
|
173
181
|
};
|
|
174
182
|
markSuccess = () => {
|
|
175
|
-
if (
|
|
183
|
+
if (sharedState.marked || __DEV__ || !isFirstTime) {
|
|
176
184
|
return;
|
|
177
185
|
}
|
|
178
|
-
|
|
186
|
+
sharedState.marked = true;
|
|
179
187
|
PushyModule.markSuccess();
|
|
180
188
|
this.report({ type: 'markSuccess' });
|
|
181
189
|
};
|
|
@@ -183,9 +191,9 @@ export class Pushy {
|
|
|
183
191
|
if (!assertDev('switchVersion()')) {
|
|
184
192
|
return;
|
|
185
193
|
}
|
|
186
|
-
if (
|
|
194
|
+
if (assertHash(hash) && !sharedState.applyingUpdate) {
|
|
187
195
|
log('switchVersion: ' + hash);
|
|
188
|
-
|
|
196
|
+
sharedState.applyingUpdate = true;
|
|
189
197
|
return PushyModule.reloadUpdate({ hash });
|
|
190
198
|
}
|
|
191
199
|
};
|
|
@@ -194,7 +202,7 @@ export class Pushy {
|
|
|
194
202
|
if (!assertDev('switchVersionLater()')) {
|
|
195
203
|
return;
|
|
196
204
|
}
|
|
197
|
-
if (
|
|
205
|
+
if (assertHash(hash)) {
|
|
198
206
|
log('switchVersionLater: ' + hash);
|
|
199
207
|
return PushyModule.setNeedUpdate({ hash });
|
|
200
208
|
}
|
|
@@ -349,18 +357,18 @@ export class Pushy {
|
|
|
349
357
|
log(`rolledback hash ${rolledBackVersion}, ignored`);
|
|
350
358
|
return;
|
|
351
359
|
}
|
|
352
|
-
if (
|
|
353
|
-
log(`duplicated downloaded hash ${
|
|
354
|
-
return
|
|
360
|
+
if (sharedState.downloadedHash === hash) {
|
|
361
|
+
log(`duplicated downloaded hash ${sharedState.downloadedHash}, ignored`);
|
|
362
|
+
return sharedState.downloadedHash;
|
|
355
363
|
}
|
|
356
|
-
if (
|
|
364
|
+
if (sharedState.progressHandlers[hash]) {
|
|
357
365
|
return;
|
|
358
366
|
}
|
|
359
367
|
const patchStartTime = Date.now();
|
|
360
368
|
if (onDownloadProgress) {
|
|
361
369
|
// @ts-expect-error harmony not in existing platforms
|
|
362
370
|
if (Platform.OS === 'harmony') {
|
|
363
|
-
|
|
371
|
+
sharedState.progressHandlers[hash] = DeviceEventEmitter.addListener(
|
|
364
372
|
'RCTPushyDownloadProgress',
|
|
365
373
|
progressData => {
|
|
366
374
|
if (progressData.hash === hash) {
|
|
@@ -369,14 +377,15 @@ export class Pushy {
|
|
|
369
377
|
},
|
|
370
378
|
);
|
|
371
379
|
} else {
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
+
sharedState.progressHandlers[hash] =
|
|
381
|
+
pushyNativeEventEmitter.addListener(
|
|
382
|
+
'RCTPushyDownloadProgress',
|
|
383
|
+
progressData => {
|
|
384
|
+
if (progressData.hash === hash) {
|
|
385
|
+
onDownloadProgress(progressData);
|
|
386
|
+
}
|
|
387
|
+
},
|
|
388
|
+
);
|
|
380
389
|
}
|
|
381
390
|
}
|
|
382
391
|
let succeeded = '';
|
|
@@ -444,9 +453,9 @@ export class Pushy {
|
|
|
444
453
|
}
|
|
445
454
|
}
|
|
446
455
|
}
|
|
447
|
-
if (
|
|
448
|
-
|
|
449
|
-
delete
|
|
456
|
+
if (sharedState.progressHandlers[hash]) {
|
|
457
|
+
sharedState.progressHandlers[hash].remove();
|
|
458
|
+
delete sharedState.progressHandlers[hash];
|
|
450
459
|
}
|
|
451
460
|
if (__DEV__) {
|
|
452
461
|
return hash;
|
|
@@ -482,7 +491,7 @@ export class Pushy {
|
|
|
482
491
|
description,
|
|
483
492
|
metaInfo,
|
|
484
493
|
});
|
|
485
|
-
|
|
494
|
+
sharedState.downloadedHash = hash;
|
|
486
495
|
return hash;
|
|
487
496
|
};
|
|
488
497
|
downloadAndInstallApk = async (
|
|
@@ -492,10 +501,10 @@ export class Pushy {
|
|
|
492
501
|
if (Platform.OS !== 'android') {
|
|
493
502
|
return;
|
|
494
503
|
}
|
|
495
|
-
if (
|
|
504
|
+
if (sharedState.apkStatus === 'downloading') {
|
|
496
505
|
return;
|
|
497
506
|
}
|
|
498
|
-
if (
|
|
507
|
+
if (sharedState.apkStatus === 'downloaded') {
|
|
499
508
|
this.report({ type: 'errorInstallApk' });
|
|
500
509
|
this.throwIfEnabled(new Error('errorInstallApk'));
|
|
501
510
|
return;
|
|
@@ -516,35 +525,36 @@ export class Pushy {
|
|
|
516
525
|
return;
|
|
517
526
|
}
|
|
518
527
|
}
|
|
519
|
-
|
|
528
|
+
sharedState.apkStatus = 'downloading';
|
|
520
529
|
this.report({ type: 'downloadingApk' });
|
|
521
530
|
const progressKey = 'downloadingApk';
|
|
522
531
|
if (onDownloadProgress) {
|
|
523
|
-
if (
|
|
524
|
-
|
|
532
|
+
if (sharedState.progressHandlers[progressKey]) {
|
|
533
|
+
sharedState.progressHandlers[progressKey].remove();
|
|
525
534
|
}
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
535
|
+
sharedState.progressHandlers[progressKey] =
|
|
536
|
+
pushyNativeEventEmitter.addListener(
|
|
537
|
+
'RCTPushyDownloadProgress',
|
|
538
|
+
(progressData: ProgressData) => {
|
|
539
|
+
if (progressData.hash === progressKey) {
|
|
540
|
+
onDownloadProgress(progressData);
|
|
541
|
+
}
|
|
542
|
+
},
|
|
543
|
+
);
|
|
534
544
|
}
|
|
535
545
|
await PushyModule.downloadAndInstallApk({
|
|
536
546
|
url,
|
|
537
547
|
target: 'update.apk',
|
|
538
548
|
hash: progressKey,
|
|
539
549
|
}).catch(() => {
|
|
540
|
-
|
|
550
|
+
sharedState.apkStatus = null;
|
|
541
551
|
this.report({ type: 'errorDownloadAndInstallApk' });
|
|
542
552
|
this.throwIfEnabled(new Error('errorDownloadAndInstallApk'));
|
|
543
553
|
});
|
|
544
|
-
|
|
545
|
-
if (
|
|
546
|
-
|
|
547
|
-
delete
|
|
554
|
+
sharedState.apkStatus = 'downloaded';
|
|
555
|
+
if (sharedState.progressHandlers[progressKey]) {
|
|
556
|
+
sharedState.progressHandlers[progressKey].remove();
|
|
557
|
+
delete sharedState.progressHandlers[progressKey];
|
|
548
558
|
}
|
|
549
559
|
};
|
|
550
560
|
restartApp = async () => {
|
package/src/provider.tsx
CHANGED
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
Platform,
|
|
13
13
|
Linking,
|
|
14
14
|
} from 'react-native';
|
|
15
|
-
import { Pushy, Cresc } from './client';
|
|
15
|
+
import { Pushy, Cresc, sharedState } from './client';
|
|
16
16
|
import { currentVersion, packageVersion, getCurrentVersionInfo } from './core';
|
|
17
17
|
import { CheckResult, ProgressData, UpdateTestPayload } from './type';
|
|
18
18
|
import { UpdateContext } from './context';
|
|
@@ -171,7 +171,7 @@ export const UpdateProvider = ({
|
|
|
171
171
|
return;
|
|
172
172
|
}
|
|
173
173
|
const rollout = info.config?.rollout?.[packageVersion];
|
|
174
|
-
if (rollout) {
|
|
174
|
+
if (info.update && rollout) {
|
|
175
175
|
if (!isInRollout(rollout)) {
|
|
176
176
|
log(`not in ${rollout}% rollout, ignored`);
|
|
177
177
|
return;
|
|
@@ -182,8 +182,15 @@ export const UpdateProvider = ({
|
|
|
182
182
|
updateInfoRef.current = info;
|
|
183
183
|
setUpdateInfo(info);
|
|
184
184
|
if (info.expired) {
|
|
185
|
+
if (
|
|
186
|
+
options.onPackageExpired &&
|
|
187
|
+
(await options.onPackageExpired(info)) === false
|
|
188
|
+
) {
|
|
189
|
+
log('onPackageExpired returned false, skipping');
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
185
192
|
const { downloadUrl } = info;
|
|
186
|
-
if (downloadUrl &&
|
|
193
|
+
if (downloadUrl && sharedState.apkStatus === null) {
|
|
187
194
|
if (options.updateStrategy === 'silentAndNow') {
|
|
188
195
|
if (Platform.OS === 'android' && downloadUrl.endsWith('.apk')) {
|
|
189
196
|
downloadAndInstallApk(downloadUrl);
|
|
@@ -234,7 +241,7 @@ export const UpdateProvider = ({
|
|
|
234
241
|
client,
|
|
235
242
|
alertError,
|
|
236
243
|
throwErrorIfEnabled,
|
|
237
|
-
options
|
|
244
|
+
options,
|
|
238
245
|
alertUpdate,
|
|
239
246
|
downloadAndInstallApk,
|
|
240
247
|
downloadUpdate,
|
package/src/type.ts
CHANGED
|
@@ -92,6 +92,7 @@ export interface ClientOptions {
|
|
|
92
92
|
beforeCheckUpdate?: () => Promise<boolean>;
|
|
93
93
|
beforeDownloadUpdate?: (info: CheckResult) => Promise<boolean>;
|
|
94
94
|
afterDownloadUpdate?: (info: CheckResult) => Promise<boolean>;
|
|
95
|
+
onPackageExpired?: (info: CheckResult) => Promise<boolean>;
|
|
95
96
|
}
|
|
96
97
|
|
|
97
98
|
export interface UpdateTestPayload {
|
package/src/utils.ts
CHANGED
|
@@ -62,7 +62,7 @@ const ping =
|
|
|
62
62
|
if (!pingFinished) {
|
|
63
63
|
log('ping timeout', url);
|
|
64
64
|
}
|
|
65
|
-
},
|
|
65
|
+
}, 5000),
|
|
66
66
|
),
|
|
67
67
|
]);
|
|
68
68
|
};
|
|
@@ -81,6 +81,7 @@ export const testUrls = async (urls?: string[]) => {
|
|
|
81
81
|
try {
|
|
82
82
|
const ret = await promiseAny(urls.map(ping));
|
|
83
83
|
if (ret) {
|
|
84
|
+
log('ping success, use url:', ret);
|
|
84
85
|
return ret;
|
|
85
86
|
}
|
|
86
87
|
} catch {}
|
package/android/.project
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<projectDescription>
|
|
3
|
-
<name>react-native-update</name>
|
|
4
|
-
<comment>Project react-native-update created by Buildship.</comment>
|
|
5
|
-
<projects>
|
|
6
|
-
</projects>
|
|
7
|
-
<buildSpec>
|
|
8
|
-
<buildCommand>
|
|
9
|
-
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
|
|
10
|
-
<arguments>
|
|
11
|
-
</arguments>
|
|
12
|
-
</buildCommand>
|
|
13
|
-
</buildSpec>
|
|
14
|
-
<natures>
|
|
15
|
-
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
|
|
16
|
-
</natures>
|
|
17
|
-
<filteredResources>
|
|
18
|
-
<filter>
|
|
19
|
-
<id>1727963310481</id>
|
|
20
|
-
<name></name>
|
|
21
|
-
<type>30</type>
|
|
22
|
-
<matcher>
|
|
23
|
-
<id>org.eclipse.core.resources.regexFilterMatcher</id>
|
|
24
|
-
<arguments>node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
|
|
25
|
-
</matcher>
|
|
26
|
-
</filter>
|
|
27
|
-
</filteredResources>
|
|
28
|
-
</projectDescription>
|
package/android/bin/.project
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<projectDescription>
|
|
3
|
-
<name>react-native-update</name>
|
|
4
|
-
<comment>Project react-native-update created by Buildship.</comment>
|
|
5
|
-
<projects>
|
|
6
|
-
</projects>
|
|
7
|
-
<buildSpec>
|
|
8
|
-
<buildCommand>
|
|
9
|
-
<name>org.eclipse.jdt.core.javabuilder</name>
|
|
10
|
-
<arguments>
|
|
11
|
-
</arguments>
|
|
12
|
-
</buildCommand>
|
|
13
|
-
<buildCommand>
|
|
14
|
-
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
|
|
15
|
-
<arguments>
|
|
16
|
-
</arguments>
|
|
17
|
-
</buildCommand>
|
|
18
|
-
</buildSpec>
|
|
19
|
-
<natures>
|
|
20
|
-
<nature>org.eclipse.jdt.core.javanature</nature>
|
|
21
|
-
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
|
|
22
|
-
</natures>
|
|
23
|
-
<filteredResources>
|
|
24
|
-
<filter>
|
|
25
|
-
<id>1727963310481</id>
|
|
26
|
-
<name></name>
|
|
27
|
-
<type>30</type>
|
|
28
|
-
<matcher>
|
|
29
|
-
<id>org.eclipse.core.resources.regexFilterMatcher</id>
|
|
30
|
-
<arguments>node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
|
|
31
|
-
</matcher>
|
|
32
|
-
</filter>
|
|
33
|
-
</filteredResources>
|
|
34
|
-
</projectDescription>
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
arguments=--init-script /var/folders/l6/0fn3x28s5s585ld3p04gsy1h0000gn/T/db3b08fc4a9ef609cb16b96b200fa13e563f396e9bb1ed0905fdab7bc3bc513b.gradle --init-script /var/folders/l6/0fn3x28s5s585ld3p04gsy1h0000gn/T/52cde0cfcf3e28b8b7510e992210d9614505e0911af0c190bd590d7158574963.gradle
|
|
2
|
-
auto.sync=false
|
|
3
|
-
build.scans.enabled=false
|
|
4
|
-
connection.gradle.distribution=GRADLE_DISTRIBUTION(VERSION(8.9))
|
|
5
|
-
connection.project.dir=
|
|
6
|
-
eclipse.preferences.version=1
|
|
7
|
-
gradle.user.home=
|
|
8
|
-
java.home=/Users/sunny/.sdkman/candidates/java/17.0.9-zulu/zulu-17.jdk/Contents/Home
|
|
9
|
-
jvm.arguments=
|
|
10
|
-
offline.mode=false
|
|
11
|
-
override.workspace.settings=true
|
|
12
|
-
show.console.view=true
|
|
13
|
-
show.executions.view=true
|