react-native-update 10.47.0 → 10.48.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/android/jni/Android.mk +2 -0
- package/android/jni/hpatch.c +57 -2
- package/android/lib/arm64-v8a/librnupdate.so +0 -0
- package/android/lib/armeabi-v7a/librnupdate.so +0 -0
- package/android/lib/x86/librnupdate.so +0 -0
- package/android/lib/x86_64/librnupdate.so +0 -0
- package/android/src/main/java/cn/reactnative/modules/update/DownloadTask.java +19 -4
- package/android/src/main/java/cn/reactnative/modules/update/DownloadTaskParams.java +2 -0
- package/android/src/main/java/cn/reactnative/modules/update/ErrorCodes.java +1 -0
- package/android/src/main/java/cn/reactnative/modules/update/NativeUpdateCore.java +12 -0
- package/android/src/main/java/cn/reactnative/modules/update/UpdateContext.java +30 -0
- package/android/src/main/java/cn/reactnative/modules/update/UpdateModuleImpl.java +13 -0
- package/android/src/main/java/cn/reactnative/modules/update/UpdateModuleSupport.java +1 -0
- package/android/src/newarch/cn/reactnative/modules/update/UpdateModule.java +5 -0
- package/android/src/oldarch/cn/reactnative/modules/update/UpdateModule.java +5 -0
- package/cpp/patch_core/error_codes.h +3 -0
- package/cpp/patch_core/hbc_transform.cpp +143 -0
- package/cpp/patch_core/hbc_transform.h +53 -0
- package/cpp/patch_core/hbc_transform_wire.cpp +321 -0
- package/cpp/patch_core/hbc_transform_wire.h +52 -0
- package/cpp/patch_core/patch_core.cpp +126 -4
- package/cpp/patch_core/patch_core.h +5 -0
- package/cpp/patch_core/patch_core_android.cpp +3 -1
- package/cpp/patch_core/tests/fixtures/rawstored.lzma2label.patch.bin +0 -0
- package/cpp/patch_core/tests/fixtures/rawstored.new.bin +0 -0
- package/cpp/patch_core/tests/fixtures/rawstored.old.bin +0 -0
- package/cpp/patch_core/tests/fixtures/v96.hbc +0 -0
- package/cpp/patch_core/tests/fixtures/v96.meta.json +1 -0
- package/cpp/patch_core/tests/fixtures/v96.streampatch.bin +0 -0
- package/cpp/patch_core/tests/fixtures/v96.t.hbc +0 -0
- package/cpp/patch_core/tests/fixtures/v96.tpatch.bin +0 -0
- package/cpp/patch_core/tests/fixtures/v96.tstreampatch.bin +0 -0
- package/cpp/patch_core/tests/fixtures/v96b.hbc +0 -0
- package/cpp/patch_core/tests/fixtures/v98.hbc +0 -0
- package/cpp/patch_core/tests/fixtures/v98.t.hbc +0 -0
- package/cpp/patch_core/tests/fixtures/v98b.hbc +0 -0
- package/cpp/patch_core/tests/fixtures/v98b.t.hbc +0 -0
- package/cpp/patch_core/tests/hbc_transform_test.cpp +229 -0
- package/cpp/patch_core/tests/patch_core_test.cpp +150 -1
- package/cpp/patch_core/update_core_android.cpp +10 -0
- package/harmony/pushy/src/main/cpp/CMakeLists.txt +2 -0
- package/harmony/pushy/src/main/cpp/pushy.cpp +18 -1
- package/harmony/pushy/src/main/ets/DownloadTask.ts +21 -0
- package/harmony/pushy/src/main/ets/NativePatchCore.ts +4 -0
- package/harmony/pushy/src/main/ets/PushyTurboModule.ts +12 -0
- package/harmony/pushy/src/main/ets/UpdateContext.ts +46 -0
- package/harmony/pushy.har +0 -0
- package/ios/RCTPushy/RCTPushy.mm +64 -0
- package/package.json +1 -1
- package/react-native-update.podspec +2 -0
- package/src/NativePushy.ts +1 -0
- package/src/client.ts +46 -0
- package/src/context.ts +4 -0
- package/src/core.ts +4 -0
- package/src/error.ts +1 -0
- package/src/locales/en.ts +2 -0
- package/src/locales/zh.ts +2 -0
- package/src/provider.tsx +9 -0
- package/src/type.ts +2 -0
package/ios/RCTPushy/RCTPushy.mm
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
#import "RCTPushyDownloader.h"
|
|
3
3
|
#import "ZipArchive.h"
|
|
4
4
|
#include "../../cpp/patch_core/archive_patch_core.h"
|
|
5
|
+
#include "../../cpp/patch_core/hbc_transform_wire.h"
|
|
5
6
|
#include "../../cpp/patch_core/error_codes.h"
|
|
6
7
|
#include "../../cpp/patch_core/patch_core.h"
|
|
7
8
|
#include "../../cpp/patch_core/state_core.h"
|
|
@@ -347,6 +348,9 @@ RCT_EXPORT_MODULE(RCTPushy);
|
|
|
347
348
|
ret[@"rolledBackVersion"] = [defaults objectForKey:keyRolledBackMarked];
|
|
348
349
|
ret[@"isFirstTime"] = [defaults objectForKey:keyFirstLoadMarked];
|
|
349
350
|
ret[@"uuid"] = [defaults objectForKey:keyUuid];
|
|
351
|
+
// 原生 patch 内核可消费的 diff 轨道版本(2 = hdiffv2 轨道),
|
|
352
|
+
// JS 随 checkUpdate 以 diffV 上报,服务端按能力门控下发
|
|
353
|
+
ret[@"supportedDiffVersion"] = @(pushy::hbc::kSupportedDiffVersion);
|
|
350
354
|
NSDictionary *pushyInfo = [defaults dictionaryForKey:keyPushyInfo];
|
|
351
355
|
NSString *currentVersion = [pushyInfo objectForKey:paramCurrentVersion];
|
|
352
356
|
ret[@"currentVersion"] = currentVersion;
|
|
@@ -514,6 +518,51 @@ RCT_EXPORT_METHOD(markSuccess:(RCTPromiseResolveBlock)resolve
|
|
|
514
518
|
#endif
|
|
515
519
|
}
|
|
516
520
|
|
|
521
|
+
RCT_EXPORT_METHOD(resetToPackagedBundle:(RCTPromiseResolveBlock)resolve
|
|
522
|
+
rejecter:(RCTPromiseRejectBlock)reject)
|
|
523
|
+
{
|
|
524
|
+
// Reset to the bundle packaged in the binary: wipe the whole update state
|
|
525
|
+
// (so the next launch resolves to the built-in bundle) and delete every
|
|
526
|
+
// downloaded version. Only the client uuid survives — it identifies the
|
|
527
|
+
// install for gray release bucketing and must not change on reset.
|
|
528
|
+
PushyWithStateLock(^{
|
|
529
|
+
NSUserDefaults *defaults = PushyDefaults();
|
|
530
|
+
|
|
531
|
+
// A default-constructed State is exactly the reset state (no current /
|
|
532
|
+
// last version, first_time=false, first_time_ok=true); keep the binary
|
|
533
|
+
// identity so the next launch does not re-trigger the package-updated
|
|
534
|
+
// sync path.
|
|
535
|
+
pushy::state::State state;
|
|
536
|
+
state.package_version = PushyToStdString([RCTPushy packageVersion]);
|
|
537
|
+
state.build_time = PushyToStdString([RCTPushy buildTime]);
|
|
538
|
+
PushyApplyStateToDefaults(defaults, state);
|
|
539
|
+
|
|
540
|
+
for (NSString *key in [defaults dictionaryRepresentation].allKeys) {
|
|
541
|
+
if ([key hasPrefix:keyHashInfo]) {
|
|
542
|
+
[defaults removeObjectForKey:key];
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
[defaults removeObjectForKey:keyFirstLoadMarked];
|
|
546
|
+
[defaults removeObjectForKey:KeyPackageUpdatedMarked];
|
|
547
|
+
ignoreRollback = false;
|
|
548
|
+
});
|
|
549
|
+
|
|
550
|
+
dispatch_async(_fileQueue, ^{
|
|
551
|
+
// maxAgeDays=0 and no versions to keep: remove every downloaded entry.
|
|
552
|
+
pushy::patch::Status status = pushy::patch::CleanupOldEntries(
|
|
553
|
+
PushyToStdString([RCTPushy downloadDir]),
|
|
554
|
+
"",
|
|
555
|
+
"",
|
|
556
|
+
0
|
|
557
|
+
);
|
|
558
|
+
if (!status.ok) {
|
|
559
|
+
RCTLogWarn(@"Pushy reset cleanup error: %s", status.message.c_str());
|
|
560
|
+
}
|
|
561
|
+
});
|
|
562
|
+
|
|
563
|
+
resolve(@true);
|
|
564
|
+
}
|
|
565
|
+
|
|
517
566
|
|
|
518
567
|
|
|
519
568
|
#pragma mark - private
|
|
@@ -742,6 +791,21 @@ RCT_EXPORT_METHOD(markSuccess:(RCTPromiseResolveBlock)resolve
|
|
|
742
791
|
return;
|
|
743
792
|
}
|
|
744
793
|
|
|
794
|
+
// __diff.json 的 hbcTransform 元数据(HBC 变换域 patch,hdiffv2 轨道):
|
|
795
|
+
// 存在时透传给 patch 内核执行 T(origin) → hpatch → T⁻¹;缺失走现状路径。
|
|
796
|
+
NSDictionary *hbcTransform = json[@"hbcTransform"];
|
|
797
|
+
if ([hbcTransform isKindOfClass:[NSDictionary class]]) {
|
|
798
|
+
NSDictionary *meta = hbcTransform[BUNDLE_PATCH_NAME];
|
|
799
|
+
if ([meta isKindOfClass:[NSDictionary class]]) {
|
|
800
|
+
NSError *metaError = nil;
|
|
801
|
+
NSData *metaData = [NSJSONSerialization dataWithJSONObject:meta options:0 error:&metaError];
|
|
802
|
+
if (metaData != nil && metaError == nil) {
|
|
803
|
+
NSString *metaString = [[NSString alloc] initWithData:metaData encoding:NSUTF8StringEncoding];
|
|
804
|
+
options.bundle_hbc_transform_meta = PushyToStdString(metaString);
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
|
|
745
809
|
pushy::patch::Status status = pushy::patch::ApplyPatchFromFileSource(options);
|
|
746
810
|
if (!status.ok) {
|
|
747
811
|
callback(PushyNSErrorFromStatus(status));
|
package/package.json
CHANGED
|
@@ -111,6 +111,8 @@ Pod::Spec.new do |s|
|
|
|
111
111
|
s.subspec 'RCTPushy' do |ss|
|
|
112
112
|
ss.source_files = ['ios/RCTPushy/*.{h,m,mm}',
|
|
113
113
|
'cpp/patch_core/archive_patch_core.{h,cpp}',
|
|
114
|
+
'cpp/patch_core/hbc_transform.{h,cpp}',
|
|
115
|
+
'cpp/patch_core/hbc_transform_wire.{h,cpp}',
|
|
114
116
|
'cpp/patch_core/patch_core.{h,cpp}',
|
|
115
117
|
'cpp/patch_core/state_core.{h,cpp}',
|
|
116
118
|
'android/jni/hpatch.{h,c}',
|
package/src/NativePushy.ts
CHANGED
|
@@ -19,6 +19,7 @@ export interface Spec extends TurboModule {
|
|
|
19
19
|
restartApp(): Promise<void>;
|
|
20
20
|
setNeedUpdate(options: { hash: string }): Promise<void>;
|
|
21
21
|
markSuccess(): Promise<void>;
|
|
22
|
+
resetToPackagedBundle(): Promise<void>;
|
|
22
23
|
downloadPatchFromPpk(options: {
|
|
23
24
|
updateUrl: string;
|
|
24
25
|
hash: string;
|
package/src/client.ts
CHANGED
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
cInfo,
|
|
10
10
|
currentVersion,
|
|
11
11
|
currentVersionInfo,
|
|
12
|
+
supportedDiffVersion,
|
|
12
13
|
isFirstTime,
|
|
13
14
|
isRolledBack,
|
|
14
15
|
packageVersion,
|
|
@@ -572,6 +573,8 @@ export class Pushy {
|
|
|
572
573
|
hash: currentVersion,
|
|
573
574
|
buildTime,
|
|
574
575
|
cInfo,
|
|
576
|
+
// 可消费的 diff 轨道版本(2 = hdiffv2 轨道),服务端据此门控下发
|
|
577
|
+
...(supportedDiffVersion ? { diffV: supportedDiffVersion } : {}),
|
|
575
578
|
...extra,
|
|
576
579
|
};
|
|
577
580
|
if (__DEV__) {
|
|
@@ -948,6 +951,49 @@ export class Pushy {
|
|
|
948
951
|
}
|
|
949
952
|
return PushyModule.restartApp();
|
|
950
953
|
};
|
|
954
|
+
/**
|
|
955
|
+
* Reset to the bundle packaged in the binary: wipes every downloaded update
|
|
956
|
+
* and the whole update state on the native side, so the app loads the
|
|
957
|
+
* built-in bundle on the next launch (or immediately with
|
|
958
|
+
* `{ restart: true }`). The client uuid is preserved.
|
|
959
|
+
*
|
|
960
|
+
* Returns whether the reset actually happened. Like the other update-flow
|
|
961
|
+
* APIs it never throws by default — failures land in lastError/onError with
|
|
962
|
+
* code RESET_FAILED — but the boolean must not be ignored: a false means the
|
|
963
|
+
* app is still running the hot-updated bundle. Set `throwError` to throw.
|
|
964
|
+
*/
|
|
965
|
+
resetToPackagedBundle = async (options?: {
|
|
966
|
+
restart?: boolean;
|
|
967
|
+
}): Promise<boolean> => {
|
|
968
|
+
if (typeof PushyModule.resetToPackagedBundle !== 'function') {
|
|
969
|
+
// The JS layer can arrive via hot update onto an older binary whose
|
|
970
|
+
// native module predates this method.
|
|
971
|
+
const err = new UpdateError(
|
|
972
|
+
this.t('error_reset_not_supported'),
|
|
973
|
+
'RESET_FAILED',
|
|
974
|
+
);
|
|
975
|
+
this.emitError(err, 'errorReset');
|
|
976
|
+
this.throwIfEnabled(err);
|
|
977
|
+
return false;
|
|
978
|
+
}
|
|
979
|
+
try {
|
|
980
|
+
await PushyModule.resetToPackagedBundle();
|
|
981
|
+
} catch (e) {
|
|
982
|
+
const err = toUpdateError(e, 'RESET_FAILED');
|
|
983
|
+
this.emitError(err, 'errorReset');
|
|
984
|
+
this.throwIfEnabled(err);
|
|
985
|
+
return false;
|
|
986
|
+
}
|
|
987
|
+
// The downloaded versions are gone; drop JS bookkeeping referring to them
|
|
988
|
+
// so a stale downloadedHash cannot be switched to.
|
|
989
|
+
sharedState.downloadedHash = undefined;
|
|
990
|
+
sharedState.marked = false;
|
|
991
|
+
this.report({ type: 'reset' });
|
|
992
|
+
if (options?.restart) {
|
|
993
|
+
await this.restartApp();
|
|
994
|
+
}
|
|
995
|
+
return true;
|
|
996
|
+
};
|
|
951
997
|
}
|
|
952
998
|
|
|
953
999
|
// for international users
|
package/src/context.ts
CHANGED
|
@@ -15,6 +15,7 @@ export const defaultContext = {
|
|
|
15
15
|
downloadUpdate: asyncNoop,
|
|
16
16
|
downloadAndInstallApk: asyncNoop,
|
|
17
17
|
restartApp: asyncNoop,
|
|
18
|
+
resetToPackagedBundle: asyncNoop,
|
|
18
19
|
getCurrentVersionInfo: () => Promise.resolve({}),
|
|
19
20
|
parseTestQrCode: () => false,
|
|
20
21
|
currentHash: '',
|
|
@@ -43,6 +44,9 @@ export const UpdateContext = createContext<{
|
|
|
43
44
|
} | null;
|
|
44
45
|
parseTestQrCode: (code: string) => boolean;
|
|
45
46
|
restartApp: () => Promise<void>;
|
|
47
|
+
resetToPackagedBundle: (options?: {
|
|
48
|
+
restart?: boolean;
|
|
49
|
+
}) => Promise<boolean | void>;
|
|
46
50
|
currentHash: string;
|
|
47
51
|
packageVersion: string;
|
|
48
52
|
client?: Pushy | Cresc;
|
package/src/core.ts
CHANGED
|
@@ -65,6 +65,10 @@ export const rolledBackVersion: string = PushyConstants.rolledBackVersion;
|
|
|
65
65
|
export const isRolledBack: boolean = !!rolledBackVersion;
|
|
66
66
|
|
|
67
67
|
export const buildTime: string = PushyConstants.buildTime;
|
|
68
|
+
// 原生 patch 内核可消费的 diff 轨道版本(2 = hdiffv2 轨道:HBC 变换 +
|
|
69
|
+
// 流式容器);旧原生无此常量时为 0(不上报,服务端只发 baseline)
|
|
70
|
+
export const supportedDiffVersion: number =
|
|
71
|
+
PushyConstants.supportedDiffVersion || 0;
|
|
68
72
|
let uuid = PushyConstants.uuid;
|
|
69
73
|
|
|
70
74
|
async function getLocalHashInfo(hash: string) {
|
package/src/error.ts
CHANGED
package/src/locales/en.ts
CHANGED
|
@@ -61,6 +61,8 @@ export default {
|
|
|
61
61
|
error_storage_permission_rejected:
|
|
62
62
|
'Storage permission denied, unable to download the APK',
|
|
63
63
|
error_apk_download_failed: 'Failed to download or install the APK',
|
|
64
|
+
error_reset_not_supported:
|
|
65
|
+
'resetToPackagedBundle is not available in the installed native module. Please rebuild the app with the latest react-native-update.',
|
|
64
66
|
|
|
65
67
|
// Development messages
|
|
66
68
|
dev_debug_disabled:
|
package/src/locales/zh.ts
CHANGED
|
@@ -56,6 +56,8 @@ export default {
|
|
|
56
56
|
error_apk_pending_install: '安装包已下载完成,请在系统安装界面完成安装',
|
|
57
57
|
error_storage_permission_rejected: '存储权限被拒绝,无法下载安装包',
|
|
58
58
|
error_apk_download_failed: '安装包下载或安装失败',
|
|
59
|
+
error_reset_not_supported:
|
|
60
|
+
'当前安装的原生模块不支持 resetToPackagedBundle,请使用最新版 react-native-update 重新打包后再试。',
|
|
59
61
|
|
|
60
62
|
// Development messages
|
|
61
63
|
dev_debug_disabled:
|
package/src/provider.tsx
CHANGED
|
@@ -388,6 +388,13 @@ export const UpdateProvider = ({
|
|
|
388
388
|
return client.restartApp();
|
|
389
389
|
}, [client]);
|
|
390
390
|
|
|
391
|
+
const resetToPackagedBundle = useCallback(
|
|
392
|
+
async (resetOptions?: { restart?: boolean }) => {
|
|
393
|
+
return client.resetToPackagedBundle(resetOptions);
|
|
394
|
+
},
|
|
395
|
+
[client],
|
|
396
|
+
);
|
|
397
|
+
|
|
391
398
|
useEffect(() => {
|
|
392
399
|
if (!assertWeb()) {
|
|
393
400
|
return;
|
|
@@ -438,6 +445,7 @@ export const UpdateProvider = ({
|
|
|
438
445
|
currentVersionInfo,
|
|
439
446
|
parseTestQrCode,
|
|
440
447
|
restartApp,
|
|
448
|
+
resetToPackagedBundle,
|
|
441
449
|
}),
|
|
442
450
|
[
|
|
443
451
|
checkUpdate,
|
|
@@ -452,6 +460,7 @@ export const UpdateProvider = ({
|
|
|
452
460
|
downloadAndInstallApk,
|
|
453
461
|
parseTestQrCode,
|
|
454
462
|
restartApp,
|
|
463
|
+
resetToPackagedBundle,
|
|
455
464
|
],
|
|
456
465
|
);
|
|
457
466
|
|