1
0
mirror of https://gitcode.com/gh_mirrors/re/react-native-pushy.git synced 2025-09-17 12:52:20 +08:00
Code Issues Packages Projects Releases Wiki Activity GitHub Gitee

Compare commits

...

10 Commits

Author SHA1 Message Date
sunnylqm
427b05f3a4 v8.2.0 2023-09-24 21:12:06 +08:00
sunnylqm
73c3dc538c fix: proguard 2023-09-24 21:11:29 +08:00
Sunny Luo
6abc960dac Update README.md 2023-01-11 23:47:21 +08:00
sunnylqm
98b89c422d chore: update example to 0.68.5 2022-11-23 18:44:58 +08:00
sunnylqm
ac60284ae1 v8.1.0 2022-11-23 18:41:48 +08:00
sunnylqm
6c1a4f148c feat: web mock 2022-11-23 18:23:48 +08:00
sunnylqm
e0857d48ad Update index.d.ts 2022-07-05 07:53:03 +08:00
sunnylqm
d9bbaf77aa v8.0.0 2022-07-04 18:16:24 +08:00
sunnylqm
736699a922 Remove update.json import in simpleUpdate 2022-07-04 18:14:51 +08:00
Sunny Luo
91f877dc6d Update README.md 2022-06-13 16:36:00 +08:00
9 changed files with 119 additions and 70 deletions

View File

@@ -12,7 +12,7 @@
},
"dependencies": {
"react": "17.0.2",
"react-native": "0.68.2",
"react-native": "0.68.5",
"react-native-update": "link:../.."
},
"devDependencies": {

View File

@@ -5424,10 +5424,10 @@ progress@^2.0.0:
resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8"
integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==
promise@^8.0.3:
version "8.1.0"
resolved "https://registry.yarnpkg.com/promise/-/promise-8.1.0.tgz#697c25c3dfe7435dd79fcd58c38a135888eaf05e"
integrity sha512-W04AqnILOL/sPRXziNicCjSNRruLAuIHEOVBazepu0545DDNGYHz7ar9ZgZ1fMU8/MA4mVxp5rkBWRi6OXIy3Q==
promise@^8.2.0:
version "8.3.0"
resolved "https://registry.yarnpkg.com/promise/-/promise-8.3.0.tgz#8cb333d1edeb61ef23869fbb8a4ea0279ab60e0a"
integrity sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==
dependencies:
asap "~2.0.6"
@@ -5494,10 +5494,10 @@ react-is@^16.13.1:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
react-native-codegen@^0.0.17:
version "0.0.17"
resolved "https://registry.yarnpkg.com/react-native-codegen/-/react-native-codegen-0.0.17.tgz#83fb814d94061cbd46667f510d2ddba35ffb50ac"
integrity sha512-7GIEUmAemH9uWwB6iYXNNsPoPgH06pxzGRmdBzK98TgFBdYJZ7CBuZFPMe4jmHQTPOkQazKZ/w5O6/71JBixmw==
react-native-codegen@^0.0.18:
version "0.0.18"
resolved "https://registry.yarnpkg.com/react-native-codegen/-/react-native-codegen-0.0.18.tgz#99d6623d65292e8ce3fdb1d133a358caaa2145e7"
integrity sha512-XPI9aVsFy3dvgDZvyGWrFnknNiyb22kg5nHgxa0vjWTH9ENLBgVRZt9A64xHZ8BYihH+gl0p/1JNOCIEUzRPBg==
dependencies:
"@babel/parser" "^7.14.0"
flow-parser "^0.121.0"
@@ -5513,10 +5513,10 @@ react-native-gradle-plugin@^0.0.6:
version "0.0.0"
uid ""
react-native@0.68.2:
version "0.68.2"
resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.68.2.tgz#07547cd31bb9335a7fa4135cfbdc24e067142585"
integrity sha512-qNMz+mdIirCEmlrhapAtAG+SWVx6MAiSfCbFNhfHqiqu1xw1OKXdzIrjaBEPihRC2pcORCoCHduHGQe/Pz9Yuw==
react-native@0.68.5:
version "0.68.5"
resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.68.5.tgz#8ba7389e00b757c59b6ea23bf38303d52367d155"
integrity sha512-t3kiQ/gumFV+0r/NRSIGtYxanjY4da0utFqHgkMcRPJVwXFWC0Fr8YiOeRGYO1dp8EfrSsOjtfWic/inqVYlbQ==
dependencies:
"@jest/create-cache-key-function" "^27.0.1"
"@react-native-community/cli" "^7.0.3"
@@ -5538,9 +5538,9 @@ react-native@0.68.2:
metro-source-map "0.67.0"
nullthrows "^1.1.1"
pretty-format "^26.5.2"
promise "^8.0.3"
promise "^8.2.0"
react-devtools-core "^4.23.0"
react-native-codegen "^0.0.17"
react-native-codegen "^0.0.18"
react-native-gradle-plugin "^0.0.6"
react-refresh "^0.4.0"
react-shallow-renderer "16.14.1"

View File

@@ -9,11 +9,13 @@
### 优势
1. 基于阿里云高速 CDN 分发,对比其他服务器在国外的热更新服务,分发更稳定,更新成功率极高。
2. 基于 bsdiff/hdiff 算法创建的**超小更新包**,通常版本迭代后在 1-10KB 之间,避免数百 KB 的流量消耗
3. 跨越多个版本进行更新时,只需要下载**一个更新包**,不需要逐版本依次更新。
4. 命令行工具&网页双端管理,版本发布过程简单便捷,完全可以集成 CI
5. 支持崩溃回滚,安全可靠
6. meta 信息及开放 API提供更高扩展性
2. 基于 bsdiff/hdiff 算法创建的**超小更新包**,通常版本迭代后在几十 KB 级别(其他全量热更新服务所需流量通常在几十 MB 级别)
3. 始终跟进 RN 最新正式版本,第一时间提供支持。支持 hermes 字节码格式。(暂不支持新架构,会待其相对稳定后跟进)
4. 跨越多个版本进行更新时,只需要下载**一个更新包**,不需要逐版本依次更新
5. 命令行工具 & 网页双端管理,版本发布过程简单便捷,完全可以集成 CI
6. 支持崩溃回滚,安全可靠
7. meta 信息及开放 API提供更高扩展性。
8. 提供付费的专人技术支持。
### 本地开发

View File

@@ -1,2 +1,3 @@
-keepnames class cn.reactnative.modules.update.DownloadTask { *; }
-keepnames class cn.reactnative.modules.update.UpdateModule { *; }
-keepnames class com.facebook.react.ReactInstanceManager { *; }

9
lib/index.d.ts vendored
View File

@@ -84,4 +84,11 @@ interface ProgressData {
total: number;
}
export function simpleUpdate(wrappedComponent: any): any;
interface SimpleUpdateOptions {
appKey: string;
}
export function simpleUpdate(
wrappedComponent: any,
options: SimpleUpdateOptions,
): any;

17
lib/index.web.js Normal file
View File

@@ -0,0 +1,17 @@
export const downloadRootDir = '';
export const packageVersion = '';
export const currentVersion = '';
export const isFirstTime = false;
export const isRolledBack = false;
const noop = () => {};
export const checkUpdate = noop;
export const downloadUpdate = noop;
export const switchVersion = noop;
export const switchVersionLater = noop;
export const markSuccess = noop;
export const downloadAndInstallApk = noop;
export const setCustomEndpoints = noop;
export const getCurrentVersionInfo = noop;
export const simpleUpdate = noop;

View File

@@ -58,34 +58,42 @@ if (!uuid) {
Pushy.setUuid(uuid);
}
function logger(text) {
console.log(`Pushy: ${text}`);
function logger(...args) {
console.log('Pushy: ', ...args);
}
function report(hash, type) {
logger(type);
fetch(getReportUrl(), {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
hash,
type,
const noop = () => {};
let reporter = noop;
export function onEvents(customReporter) {
reporter = customReporter;
if (isRolledBack) {
report({
type: 'rollback',
data: {
rolledBackVersion,
},
});
}
}
function report({ type, message = '', data = {} }) {
logger(type + ' ' + message);
reporter({
type,
data: {
currentVersion,
cInfo,
packageVersion,
buildTime,
}),
}).catch((_e) => {});
message,
...data,
},
});
}
logger('uuid: ' + uuid);
if (isRolledBack) {
report(rolledBackVersion, 'rollback');
}
export const cInfo = {
pushy: require('../package.json').version,
rn: RNVersion,
@@ -99,28 +107,30 @@ function assertRelease() {
}
}
let checkingThrottling = false;
let lastChecking;
const empty = {};
let lastResult;
export async function checkUpdate(APPKEY, isRetry) {
assertRelease();
if (checkingThrottling) {
logger('repeated checking, ignored');
return;
}
checkingThrottling = true;
setTimeout(() => {
checkingThrottling = false;
}, 3000);
if (blockUpdate && blockUpdate.until > Date.now() / 1000) {
throw new Error(
`热更新已暂停,原因:${blockUpdate.reason}。请在"${new Date(
blockUpdate.until * 1000,
).toLocaleString()}"之后重试。`,
);
}
if (typeof APPKEY !== 'string') {
throw new Error('未检查到合法的APPKEY请查看update.json文件是否正确生成');
}
logger('checking update');
assertRelease();
const now = Date.now();
if (lastResult && lastChecking && now - lastChecking < 1000 * 60) {
// logger('repeated checking, ignored');
return lastResult;
}
lastChecking = now;
if (blockUpdate && blockUpdate.until > Date.now() / 1000) {
report({
type: 'errorChecking',
message: `热更新已暂停,原因:${blockUpdate.reason}。请在"${new Date(
blockUpdate.until * 1000,
).toLocaleString()}"之后重试。`,
});
return lastResult || empty;
}
report({ type: 'checking' });
let resp;
try {
resp = await fetch(getCheckUrl(APPKEY), {
@@ -138,16 +148,25 @@ export async function checkUpdate(APPKEY, isRetry) {
});
} catch (e) {
if (isRetry) {
throw new Error('无法连接更新服务器,请检查网络连接后重试');
report({
type: 'errorChecking',
message: '无法连接更新服务器,请检查网络连接后重试',
});
return lastResult || empty;
}
await tryBackupEndpoints(APPKEY);
await tryBackupEndpoints();
return checkUpdate(APPKEY, true);
}
const result = await resp.json();
lastResult = result;
checkOperation(result.op);
if (resp.status !== 200) {
throw new Error(result.message);
report({
type: 'errorChecking',
message: result.message,
});
}
return result;
@@ -206,6 +225,7 @@ export async function downloadUpdate(options, eventListeners) {
}
}
let succeeded = false;
report({ type: 'downloading' });
if (options.diffUrl) {
logger('downloading diff');
try {
@@ -245,8 +265,7 @@ export async function downloadUpdate(options, eventListeners) {
}
progressHandler && progressHandler.remove();
if (!succeeded) {
report(options.hash, 'error');
throw new Error('all update attempts failed');
return report({ type: 'errorUpdate', data: { newVersion: options.hash } });
}
setLocalHashInfo(options.hash, {
name: options.name,
@@ -305,10 +324,10 @@ export async function downloadAndInstallApk({ url, onDownloadProgress }) {
PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
);
if (granted !== PermissionsAndroid.RESULTS.GRANTED) {
return;
return report({ type: 'rejectStoragePermission' });
}
} catch (err) {
console.warn(err);
return report({ type: 'errorStoragePermission' });
}
}
let hash = Date.now().toString();
@@ -327,6 +346,8 @@ export async function downloadAndInstallApk({ url, onDownloadProgress }) {
url,
target: 'update.apk',
hash,
}).catch(() => {
report({ type: 'errowDownloadAndInstallApk' });
});
progressHandler && progressHandler.remove();
}

View File

@@ -12,10 +12,11 @@ import {
downloadAndInstallApk,
} from './main';
import _updateConfig from '../../../update.json';
const { appKey } = _updateConfig[Platform.OS];
export function simpleUpdate(WrappedComponent) {
export function simpleUpdate(WrappedComponent, options = {}) {
const { appKey } = options;
if (!appKey) {
throw new Error('appKey is required for simpleUpdate()');
}
return __DEV__
? WrappedComponent
: class AppUpdate extends Component {

View File

@@ -1,6 +1,6 @@
{
"name": "react-native-update",
"version": "7.4.3",
"version": "8.2.0",
"description": "react-native hot update",
"main": "lib/index.js",
"scripts": {