react-native-update 10.52.1 → 10.52.3
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/README-CN.md +3 -3
- package/README.md +3 -3
- package/package.json +1 -1
- package/src/client.ts +11 -2
- package/src/permissions.ts +5 -2
- package/src/provider.tsx +2 -1
package/README-CN.md
CHANGED
|
@@ -32,15 +32,15 @@
|
|
|
32
32
|
|
|
33
33
|
### 原生冷启动检测
|
|
34
34
|
|
|
35
|
-
自 10.
|
|
35
|
+
自 10.52.1 起,每次冷启动后数秒会在后台线程执行一次**不依赖 app bundle** 的更新检查(下载、打补丁与状态切换全部在原生侧完成)。它的存在只为一件事:**当前热更版本坏到 JS 起不来时,仍有一条能把修复版拉下来的通路**——常规更新流程仍由应用内的 JS 负责,检查结果会被 JS 侧复用,不会重复请求。
|
|
36
36
|
|
|
37
37
|
几个需要知道的点:
|
|
38
38
|
|
|
39
39
|
- **不阻塞启动**:延迟数秒、跑在后台线程,成果在**下次启动**生效。
|
|
40
40
|
- **是否自动激活取决于你的配置**:`updateStrategy` 为 `silentAndNow` / `silentAndLater` 且未关闭自动检查(`checkStrategy` 不为 `null`)时,原生侧才会把下载好的版本设为下次启动生效;其余情况只下载,激活权仍在 JS。
|
|
41
41
|
- **救砖指令**:控制台可按版本标记「强制启动」,被标记的版本无视上述策略直接在下次启动生效——这是把已被坏版本卡死的设备捞回来的手段。设备本地的崩溃回滚保护仍然优先,已回滚过的版本不会被再装回去。
|
|
42
|
-
- **崩溃时刻救援**(
|
|
43
|
-
-
|
|
42
|
+
- **崩溃时刻救援**(Android 与 iOS):应用在启动阶段死于未捕获的 JS 错误时,SDK 会短暂扣住垂死的进程(数秒、有硬上限),把检查与下载做完——即使版本每次启动零点几秒就崩,也能被换掉。该窗口内下载到的修复版一律设为下次启动生效(JS 已经没有机会做决策了)。崩溃上报不受影响:SDK 以链式方式保存并在结束后调用原有的崩溃处理器。不覆盖:原生(非 JS)崩溃、ANR、OOM 击杀,以及 iOS 上安装了自定义 `RCTSetFatalHandler` 的应用(那时 React Native 不再抛出本机制拦截的异常)。
|
|
43
|
+
- **断点续传**:更新下载在进程死亡后保留进度、下次以 HTTP Range 续传,反复的短命启动也能单调累积进度;紧随中断轮次的下一次启动会跳过延迟立即续传。鸿蒙不需要崩溃时刻扣留:RNOH 下未捕获的 JS 错误不会杀死进程,JS 启动即崩时原生检测照常完成。
|
|
44
44
|
- **可以关闭**:`disableNativeCheck: true`。关闭后每次冷启动少一次后台请求,代价是**放弃上述自愈能力**——被坏热更卡死的设备将无法自动恢复。仅在这次请求本身构成问题时(流量/耗电预算、隐私清单申报、需用户同意后才可联网)才建议关闭。
|
|
45
45
|
|
|
46
46
|
### Diff 算法对比
|
package/README.md
CHANGED
|
@@ -30,15 +30,15 @@ See the docs:
|
|
|
30
30
|
|
|
31
31
|
## Native cold-start check
|
|
32
32
|
|
|
33
|
-
Since 10.
|
|
33
|
+
Since 10.52.1 every cold start runs one background update check a few seconds after launch that **does not depend on the app bundle** — the request, the download, the patch and the version switch all happen natively. It exists for exactly one reason: **when the running update is broken enough that JS never starts, something still has to be able to fetch the fix.** Normal updates remain the JS flow's job; the JS check reuses this result instead of issuing its own request.
|
|
34
34
|
|
|
35
35
|
What to know:
|
|
36
36
|
|
|
37
37
|
- **It never blocks startup**: it is delayed by a few seconds, runs off the main thread, and its result takes effect on the *next* launch.
|
|
38
38
|
- **Whether it activates depends on your configuration**: only with `updateStrategy` set to `silentAndNow` / `silentAndLater` *and* automatic checks left on (`checkStrategy` not `null`) will the native side mark a downloaded version for the next launch. Otherwise it downloads and leaves activation to JS.
|
|
39
39
|
- **Rescue directive**: the dashboard can mark a version "force boot", which activates on the next launch regardless of the strategies above — this is how a fleet stuck on a broken version is recovered. The device-local crash-rollback guard still wins: a version this device already rolled back from is never reinstalled.
|
|
40
|
-
- **Crash-moment rescue** (
|
|
41
|
-
- **Resumable downloads
|
|
40
|
+
- **Crash-moment rescue** (Android & iOS): when the app dies of an uncaught JS error during startup, the SDK briefly holds the dying process (a few seconds, bounded) to finish the check and download — so even a version that crashes a fraction of a second into every launch gets replaced. In that window the downloaded fix is always activated for the next launch, since JS is no longer around to decide. Crash reporters keep working: the SDK chains the previous crash handler and always hands the crash over afterwards. Not covered: native (non-JS) crashes, ANRs, OOM kills, and — on iOS — apps that install a custom `RCTSetFatalHandler` (React Native then no longer raises the exception this rescue intercepts).
|
|
41
|
+
- **Resumable downloads**: update downloads survive process death and resume from where they stopped (HTTP Range), so repeated short-lived launches still make monotonic progress; a launch that follows an interrupted round skips the startup delay and resumes immediately. HarmonyOS does not need the crash-moment hold: an uncaught JS error does not kill the process there, so the native check completes normally even when JS dies on launch.
|
|
42
42
|
- **It can be turned off**: `disableNativeCheck: true` removes one background request per cold start, at the cost of **giving up the recovery above** — a device bricked by a bad update can no longer heal itself. Choose it only when that request is itself the problem (traffic/battery budgets, privacy manifests, consent-gated networking).
|
|
43
43
|
|
|
44
44
|
## Diff Algorithm Comparison
|
package/package.json
CHANGED
package/src/client.ts
CHANGED
|
@@ -76,6 +76,10 @@ const SERVER_PRESETS = {
|
|
|
76
76
|
main: [
|
|
77
77
|
'https://update.react-native.cn/api',
|
|
78
78
|
'https://update.reactnative.cn/api',
|
|
79
|
+
'https://1.rnupdate.online/api',
|
|
80
|
+
'https://2.rnupdate.online/api',
|
|
81
|
+
'https://3.rnupdate.online/api',
|
|
82
|
+
'https://4.rnupdate.online/api',
|
|
79
83
|
],
|
|
80
84
|
queryUrls: [
|
|
81
85
|
'https://gitee.com/sunnylqm/react-native-pushy/raw/master/endpoints.json',
|
|
@@ -1103,7 +1107,11 @@ export class Pushy {
|
|
|
1103
1107
|
callback(payload);
|
|
1104
1108
|
});
|
|
1105
1109
|
};
|
|
1106
|
-
|
|
1110
|
+
// RN >= 0.87 types native event listeners as `(...args: readonly Object[])`,
|
|
1111
|
+
// which a `(data: ProgressData) => void` callback is not assignable to. Take
|
|
1112
|
+
// the raw event and narrow it here so this compiles on every RN version.
|
|
1113
|
+
const onNativeProgress = (event: unknown) => {
|
|
1114
|
+
const progressData = event as ProgressData;
|
|
1107
1115
|
if (progressData.hash === hash) {
|
|
1108
1116
|
dispatchProgress(progressData);
|
|
1109
1117
|
}
|
|
@@ -1325,7 +1333,8 @@ export class Pushy {
|
|
|
1325
1333
|
sharedState.progressHandlers[progressKey] =
|
|
1326
1334
|
pushyNativeEventEmitter.addListener(
|
|
1327
1335
|
'RCTPushyDownloadProgress',
|
|
1328
|
-
(
|
|
1336
|
+
(event: unknown) => {
|
|
1337
|
+
const progressData = event as ProgressData;
|
|
1329
1338
|
if (progressData.hash === progressKey) {
|
|
1330
1339
|
onDownloadProgress(progressData);
|
|
1331
1340
|
}
|
package/src/permissions.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
// RN >= 0.87 (generated types) no longer exports the `PermissionsAndroidStatic`
|
|
2
|
+
// interface, so derive the shape from the exported value instead — that spelling
|
|
3
|
+
// works on every RN version we support.
|
|
4
|
+
import type { PermissionsAndroid as RNPermissionsAndroid } from 'react-native';
|
|
2
5
|
import { emptyModule } from './utils';
|
|
3
6
|
|
|
4
7
|
export const PermissionsAndroid =
|
|
5
|
-
emptyModule as unknown as
|
|
8
|
+
emptyModule as unknown as typeof RNPermissionsAndroid;
|
package/src/provider.tsx
CHANGED
|
@@ -456,7 +456,8 @@ export const UpdateProvider = ({
|
|
|
456
456
|
if (!assertWeb()) {
|
|
457
457
|
return;
|
|
458
458
|
}
|
|
459
|
-
|
|
459
|
+
// RN >= 0.87 widens getInitialURL() to `string | null | undefined`.
|
|
460
|
+
const parseLinking = (url?: string | null) => {
|
|
460
461
|
if (!url) {
|
|
461
462
|
return;
|
|
462
463
|
}
|