react-native-update 10.31.0-beta.1 → 10.31.0-beta.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/.cursor/mcp.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "mcpServers": {
3
3
  "RadonAi": {
4
- "url": "http://127.0.0.1:50274/mcp",
4
+ "url": "http://127.0.0.1:53295/mcp",
5
5
  "type": "http",
6
6
  "headers": {
7
- "nonce": "78c8e940-a1ff-41f3-87e0-8a7860bb0749"
7
+ "nonce": "e61c8e82-c274-465b-b991-2d3541f19dbc"
8
8
  }
9
9
  }
10
10
  }
@@ -35,7 +35,9 @@ public class UpdateModule extends NativePushySpec {
35
35
  final Map<String, Object> constants = new HashMap<>();
36
36
  constants.put("downloadRootDir", updateContext.getRootDir());
37
37
  constants.put("packageVersion", updateContext.getPackageVersion());
38
- constants.put("currentVersion", updateContext.getCurrentVersion());
38
+ String currentVersion = updateContext.getCurrentVersion();
39
+ constants.put("currentVersion", currentVersion);
40
+ constants.put("currentVersionInfo", updateContext.getKv("hash_" + currentVersion));
39
41
  constants.put("buildTime", updateContext.getBuildTime());
40
42
  constants.put("isUsingBundleUrl", updateContext.getIsUsingBundleUrl());
41
43
  boolean isFirstTime = updateContext.isFirstTime();
@@ -48,7 +48,9 @@ public class UpdateModule extends ReactContextBaseJavaModule {
48
48
  final Map<String, Object> constants = new HashMap<>();
49
49
  constants.put("downloadRootDir", updateContext.getRootDir());
50
50
  constants.put("packageVersion", updateContext.getPackageVersion());
51
- constants.put("currentVersion", updateContext.getCurrentVersion());
51
+ String currentVersion = updateContext.getCurrentVersion();
52
+ constants.put("currentVersion", currentVersion);
53
+ constants.put("currentVersionInfo", updateContext.getKv("hash_" + currentVersion));
52
54
  constants.put("buildTime", updateContext.getBuildTime());
53
55
  constants.put("isUsingBundleUrl", updateContext.getIsUsingBundleUrl());
54
56
  boolean isFirstTime = updateContext.isFirstTime();
@@ -32,6 +32,7 @@ getConstants(): Object {
32
32
  const rolledBackVersion = preferencesManager.getSync("rolledBackVersion", "") as string;
33
33
  const uuid = preferencesManager.getSync("uuid", "") as string;
34
34
  const currentVersion = preferencesManager.getSync("currentVersion", "") as string;
35
+ const currentVersionInfo = this.context.getKv(`hash_${currentVersion}`);
35
36
  const buildTime = preferencesManager.getSync("buildTime", "") as string;
36
37
  const isUsingBundleUrl = this.context.getIsUsingBundleUrl();
37
38
  let bundleFlags = bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_REQUESTED_PERMISSION;
@@ -53,6 +54,7 @@ getConstants(): Object {
53
54
 
54
55
  return {
55
56
  downloadRootDir: `${context.filesDir}/_update`,
57
+ currentVersionInfo,
56
58
  packageVersion,
57
59
  currentVersion,
58
60
  buildTime,
@@ -64,13 +66,13 @@ getConstants(): Object {
64
66
  }
65
67
 
66
68
 
67
- async setLocalHashInfo(hash: string, info: string): Promise<boolean> {
69
+ setLocalHashInfo(hash: string, info: string): boolean {
68
70
  logger.debug(TAG, ",call setLocalHashInfo");
69
- return UpdateModuleImpl.setLocalHashInfo(this.context,hash,info);
71
+ return UpdateModuleImpl.setLocalHashInfo(this.context, hash, info);
70
72
  }
71
73
 
72
- async getLocalHashInfo(hash: string): Promise<string> {
73
- return UpdateModuleImpl.getLocalHashInfo(this.context,hash);
74
+ getLocalHashInfo(hash: string): string {
75
+ return UpdateModuleImpl.getLocalHashInfo(this.context, hash);
74
76
  }
75
77
 
76
78
  async setUuid(uuid: string): Promise<boolean> {
@@ -50,8 +50,8 @@ export class UpdateContext {
50
50
  this.preferences.flush();
51
51
  }
52
52
 
53
- public getKv(key: string): string {
54
- return this.preferences.getSync(key, '') as string;
53
+ public getKv(key: string): string {
54
+ return this.preferences.getSync(key, '') as string;
55
55
  }
56
56
 
57
57
  public isFirstTime(): boolean {
@@ -171,27 +171,20 @@ export class UpdateModuleImpl {
171
171
  }
172
172
  }
173
173
 
174
- static async setLocalHashInfo(
174
+ static setLocalHashInfo(
175
175
  updateContext: UpdateContext,
176
176
  hash: string,
177
177
  info: string
178
- ): Promise<boolean> {
179
- if (!this.checkJson(info)) {
180
- await updateContext.setKv(`hash_${hash}`, info);
181
- throw new Error('校验报错:json字符串格式错误');
182
- }
183
- await updateContext.setKv(`hash_${hash}`, info);
178
+ ): boolean {
179
+ updateContext.setKv(`hash_${hash}`, info);
184
180
  return true;
185
181
  }
186
182
 
187
- static async getLocalHashInfo(
183
+ static getLocalHashInfo(
188
184
  updateContext: UpdateContext,
189
185
  hash: string
190
- ): Promise<string> {
191
- const value = await updateContext.getKv(`hash_${hash}`);
192
- if (!this.checkJson(value)) {
193
- throw new Error('校验报错:json字符串格式错误');
194
- }
186
+ ): string {
187
+ const value = updateContext.getKv(`hash_${hash}`);
195
188
  return value;
196
189
  }
197
190
  }
@@ -176,7 +176,9 @@ RCT_EXPORT_MODULE(RCTPushy);
176
176
  ret[@"isFirstTime"] = [defaults objectForKey:keyFirstLoadMarked];
177
177
  ret[@"uuid"] = [defaults objectForKey:keyUuid];
178
178
  NSDictionary *pushyInfo = [defaults dictionaryForKey:keyPushyInfo];
179
- ret[@"currentVersion"] = [pushyInfo objectForKey:paramCurrentVersion];
179
+ NSString *currentVersion = [pushyInfo objectForKey:paramCurrentVersion];
180
+ ret[@"currentVersion"] = currentVersion;
181
+ ret[@"currentVersionInfo"] = [pushyInfo objectForKey:[keyHashInfo stringByAppendingString:currentVersion]];
180
182
 
181
183
  // clear isFirstTimemarked
182
184
  if (ret[@"isFirstTime"]) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-update",
3
- "version": "10.31.0-beta.1",
3
+ "version": "10.31.0-beta.2",
4
4
  "description": "react-native hot update",
5
5
  "main": "src/index",
6
6
  "scripts": {
package/src/client.ts CHANGED
@@ -478,11 +478,7 @@ export class Pushy {
478
478
  log(errorMessage);
479
479
  }
480
480
  } else if (__DEV__) {
481
- log(
482
- `当前是开发环境,无法执行增量式热更新,重启不会生效。
483
- 如果需要在开发环境中测试可生效的全量热更新(但也会在再次重启后重新连接 metro),
484
- 请打开“忽略时间戳”开关再重试。`,
485
- );
481
+ log(this.t('dev_incremental_update_disabled'));
486
482
  succeeded = 'full';
487
483
  }
488
484
  }
package/src/context.ts CHANGED
@@ -18,6 +18,7 @@ export const defaultContext = {
18
18
  parseTestQrCode: () => false,
19
19
  currentHash: '',
20
20
  packageVersion: '',
21
+ currentVersionInfo: {},
21
22
  };
22
23
 
23
24
  export const UpdateContext = createContext<{
@@ -28,11 +29,17 @@ export const UpdateContext = createContext<{
28
29
  dismissError: () => void;
29
30
  downloadUpdate: () => Promise<boolean | void>;
30
31
  downloadAndInstallApk: (url: string) => Promise<void>;
32
+ // @deprecated use currentVersionInfo instead
31
33
  getCurrentVersionInfo: () => Promise<{
32
34
  name?: string;
33
35
  description?: string;
34
36
  metaInfo?: string;
35
37
  }>;
38
+ currentVersionInfo: {
39
+ name?: string;
40
+ description?: string;
41
+ metaInfo?: string;
42
+ } | null;
36
43
  parseTestQrCode: (code: string) => boolean;
37
44
  restartApp: () => Promise<void>;
38
45
  currentHash: string;
package/src/core.ts CHANGED
@@ -30,6 +30,21 @@ const PushyConstants = isTurboModuleEnabled
30
30
  export const downloadRootDir: string = PushyConstants.downloadRootDir;
31
31
  export const packageVersion: string = PushyConstants.packageVersion;
32
32
  export const currentVersion: string = PushyConstants.currentVersion;
33
+
34
+ const currentVersionInfoString: string = PushyConstants.currentVersionInfo;
35
+ let _currentVersionInfo = {};
36
+ if (currentVersionInfoString) {
37
+ try {
38
+ _currentVersionInfo = JSON.parse(currentVersionInfoString);
39
+ } catch (error) {
40
+ console.error(
41
+ 'Failed to parse currentVersionInfo:',
42
+ currentVersionInfoString,
43
+ );
44
+ }
45
+ }
46
+ export const currentVersionInfo = _currentVersionInfo;
47
+
33
48
  export const isFirstTime: boolean = PushyConstants.isFirstTime;
34
49
  export const rolledBackVersion: string = PushyConstants.rolledBackVersion;
35
50
  export const isRolledBack: boolean = typeof rolledBackVersion === 'string';
@@ -45,6 +60,7 @@ async function getLocalHashInfo(hash: string) {
45
60
  return JSON.parse(await PushyModule.getLocalHashInfo(hash));
46
61
  }
47
62
 
63
+ // @deprecated use currentVersionInfo instead
48
64
  export async function getCurrentVersionInfo(): Promise<{
49
65
  name?: string;
50
66
  description?: string;
package/src/locales/en.ts CHANGED
@@ -67,4 +67,8 @@ export default {
67
67
  // More alert messages
68
68
  alert_new_version_found:
69
69
  'New version {{name}} found. Download now?\n{{description}}',
70
+
71
+ // Development environment messages
72
+ dev_incremental_update_disabled:
73
+ 'Currently in development environment, incremental hot update cannot be executed and restart will not take effect. If you need to test effective full hot update in development environment (but will reconnect to metro after restart), please enable "ignore timestamp" switch and retry.',
70
74
  };
package/src/locales/zh.ts CHANGED
@@ -64,4 +64,8 @@ export default {
64
64
  // More alert messages
65
65
  alert_new_version_found:
66
66
  '检查到新的版本{{name}},是否下载?\n{{description}}',
67
+
68
+ // Development environment messages
69
+ dev_incremental_update_disabled:
70
+ '当前是开发环境,无法执行增量式热更新,重启不会生效。如果需要在开发环境中测试可生效的全量热更新(但也会在再次重启后重新连接 metro),请打开"忽略时间戳"开关再重试。',
67
71
  };
package/src/provider.tsx CHANGED
@@ -13,7 +13,7 @@ import {
13
13
  Linking,
14
14
  } from 'react-native';
15
15
  import { Pushy, Cresc, sharedState } from './client';
16
- import { currentVersion, packageVersion, getCurrentVersionInfo } from './core';
16
+ import { currentVersion, packageVersion, getCurrentVersionInfo, currentVersionInfo } from './core';
17
17
  import {
18
18
  CheckResult,
19
19
  MixedCheckResult,
@@ -23,7 +23,7 @@ import {
23
23
  import { UpdateContext } from './context';
24
24
  import { URL } from 'react-native-url-polyfill';
25
25
  import { isInRollout } from './isInRollout';
26
- import { log } from './utils';
26
+ import { assertWeb, log } from './utils';
27
27
 
28
28
  export const UpdateProvider = ({
29
29
  client,
@@ -277,6 +277,9 @@ export const UpdateProvider = ({
277
277
  if (!client.assertDebug('checkUpdate()')) {
278
278
  return;
279
279
  }
280
+ if (!assertWeb()) {
281
+ return;
282
+ }
280
283
  const { checkStrategy, dismissErrorAfter, autoMarkSuccess } = options;
281
284
  if (autoMarkSuccess) {
282
285
  setTimeout(() => {
@@ -351,6 +354,9 @@ export const UpdateProvider = ({
351
354
  }, [client]);
352
355
 
353
356
  useEffect(() => {
357
+ if (!assertWeb()) {
358
+ return;
359
+ }
354
360
  const parseLinking = (url: string | null) => {
355
361
  if (!url) {
356
362
  return;
@@ -394,6 +400,7 @@ export const UpdateProvider = ({
394
400
  progress,
395
401
  downloadAndInstallApk,
396
402
  getCurrentVersionInfo,
403
+ currentVersionInfo,
397
404
  parseTestQrCode,
398
405
  restartApp,
399
406
  }}>
package/src/utils.ts CHANGED
@@ -5,6 +5,8 @@ export function log(...args: any[]) {
5
5
  console.log(i18n.t('dev_log_prefix'), ...args);
6
6
  }
7
7
 
8
+ export const isWeb = Platform.OS === 'web';
9
+
8
10
  export function promiseAny<T>(promises: Promise<T>[]) {
9
11
  return new Promise<T>((resolve, reject) => {
10
12
  let count = 0;
@@ -35,38 +37,37 @@ class EmptyModule {
35
37
  }
36
38
  export const emptyModule = new EmptyModule();
37
39
 
38
- const ping =
39
- Platform.OS === 'web'
40
- ? Promise.resolve
41
- : async (url: string) => {
42
- let pingFinished = false;
43
- return Promise.race([
44
- enhancedFetch(url, {
45
- method: 'HEAD',
40
+ const ping = isWeb
41
+ ? Promise.resolve
42
+ : async (url: string) => {
43
+ let pingFinished = false;
44
+ return Promise.race([
45
+ enhancedFetch(url, {
46
+ method: 'HEAD',
47
+ })
48
+ .then(({ status, statusText, url: finalUrl }) => {
49
+ pingFinished = true;
50
+ if (status === 200) {
51
+ return finalUrl;
52
+ }
53
+ log('ping failed', url, status, statusText);
54
+ throw new Error(i18n.t('error_ping_failed'));
46
55
  })
47
- .then(({ status, statusText, url: finalUrl }) => {
48
- pingFinished = true;
49
- if (status === 200) {
50
- return finalUrl;
51
- }
52
- log('ping failed', url, status, statusText);
53
- throw new Error(i18n.t('error_ping_failed'));
54
- })
55
- .catch(e => {
56
- pingFinished = true;
57
- log('ping error', url, e);
58
- throw e;
59
- }),
60
- new Promise((_, reject) =>
61
- setTimeout(() => {
62
- reject(new Error(i18n.t('error_ping_timeout')));
63
- if (!pingFinished) {
64
- log('ping timeout', url);
65
- }
66
- }, 5000),
67
- ),
68
- ]);
69
- };
56
+ .catch(e => {
57
+ pingFinished = true;
58
+ log('ping error', url, e);
59
+ throw e;
60
+ }),
61
+ new Promise((_, reject) =>
62
+ setTimeout(() => {
63
+ reject(new Error(i18n.t('error_ping_timeout')));
64
+ if (!pingFinished) {
65
+ log('ping timeout', url);
66
+ }
67
+ }, 5000),
68
+ ),
69
+ ]);
70
+ };
70
71
 
71
72
  export function joinUrls(paths: string[], fileName?: string) {
72
73
  if (fileName) {
@@ -91,7 +92,7 @@ export const testUrls = async (urls?: string[]) => {
91
92
  };
92
93
 
93
94
  export const assertWeb = () => {
94
- if (Platform.OS === 'web') {
95
+ if (isWeb) {
95
96
  console.warn(i18n.t('dev_web_not_supported'));
96
97
  return false;
97
98
  }