react-native-update 8.2.0 → 8.4.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.
@@ -1,9 +1,6 @@
1
1
  <?xml version="1.0" encoding="utf-8"?>
2
2
  <manifest xmlns:android="http://schemas.android.com/apk/res/android"
3
3
  package="cn.reactnative.modules.update">
4
- <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
5
-
6
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
7
4
  <application>
8
5
  <meta-data android:name="pushy_build_time" android:value="@string/pushy_build_time" />
9
6
  <provider
@@ -0,0 +1,53 @@
1
+ import { logger } from './utils';
2
+
3
+ let currentEndpoint = 'https://update.react-native.cn/api';
4
+ let backupEndpoints: string[] = ['https://update.reactnative.cn/api'];
5
+ let backupEndpointsQueryUrl: string | null = null;
6
+
7
+ export async function updateBackupEndpoints() {
8
+ if (backupEndpointsQueryUrl) {
9
+ try {
10
+ const resp = await fetch(backupEndpointsQueryUrl);
11
+ const remoteEndpoints = await resp.json();
12
+ if (Array.isArray(remoteEndpoints)) {
13
+ backupEndpoints = Array.from(
14
+ new Set([...backupEndpoints, ...remoteEndpoints]),
15
+ );
16
+ logger('fetch remote endpoints:', remoteEndpoints);
17
+ logger('merged backup endpoints:', backupEndpoints);
18
+ }
19
+ } catch (e) {
20
+ logger('fetch remote endpoints failed');
21
+ }
22
+ }
23
+ return backupEndpoints;
24
+ }
25
+
26
+ export function getCheckUrl(APPKEY, endpoint = currentEndpoint) {
27
+ return `${endpoint}/checkUpdate/${APPKEY}`;
28
+ }
29
+
30
+ /**
31
+ * @param {string} main - The main api endpoint
32
+ * @param {string[]} [backups] - The back up endpoints.
33
+ * @param {string} [backupQueryUrl] - An url that return a json file containing an array of endpoint.
34
+ * like: ["https://backup.api/1", "https://backup.api/2"]
35
+ */
36
+ export function setCustomEndpoints({
37
+ main,
38
+ backups,
39
+ backupQueryUrl,
40
+ }: {
41
+ main: string;
42
+ backups?: string[];
43
+ backupQueryUrl?: string;
44
+ }) {
45
+ currentEndpoint = main;
46
+ backupEndpointsQueryUrl = null;
47
+ if (Array.isArray(backups) && backups.length > 0) {
48
+ backupEndpoints = backups;
49
+ }
50
+ if (typeof backupQueryUrl === 'string') {
51
+ backupEndpointsQueryUrl = backupQueryUrl;
52
+ }
53
+ }
package/lib/index.web.js CHANGED
@@ -14,4 +14,5 @@ export const markSuccess = noop;
14
14
  export const downloadAndInstallApk = noop;
15
15
  export const setCustomEndpoints = noop;
16
16
  export const getCurrentVersionInfo = noop;
17
- export const simpleUpdate = noop;
17
+ export const simpleUpdate = (app) => app;
18
+ export const onPushyEvents = noop;
@@ -1,8 +1,7 @@
1
1
  import {
2
- tryBackupEndpoints,
2
+ updateBackupEndpoints,
3
3
  getCheckUrl,
4
4
  setCustomEndpoints,
5
- getReportUrl,
6
5
  } from './endpoint';
7
6
  import {
8
7
  NativeEventEmitter,
@@ -10,62 +9,71 @@ import {
10
9
  Platform,
11
10
  PermissionsAndroid,
12
11
  } from 'react-native';
12
+ import {
13
+ CheckResult,
14
+ EventType,
15
+ ProgressData,
16
+ UpdateAvailableResult,
17
+ UpdateEventsListener,
18
+ } from './type';
19
+ import { assertRelease, logger } from './utils';
13
20
  export { setCustomEndpoints };
14
21
  const {
15
22
  version: v,
16
23
  } = require('react-native/Libraries/Core/ReactNativeVersion');
17
24
  const RNVersion = `${v.major}.${v.minor}.${v.patch}`;
18
25
 
19
- let Pushy = NativeModules.Pushy;
26
+ export const PushyModule = NativeModules.Pushy;
20
27
 
21
- if (!Pushy) {
28
+ if (!PushyModule) {
22
29
  throw new Error('react-native-update模块无法加载,请对照安装文档检查配置。');
23
30
  }
31
+ const PushyConstants = PushyModule;
24
32
 
25
- export const downloadRootDir = Pushy.downloadRootDir;
26
- export const packageVersion = Pushy.packageVersion;
27
- export const currentVersion = Pushy.currentVersion;
28
- export const isFirstTime = Pushy.isFirstTime;
29
- const rolledBackVersion = Pushy.rolledBackVersion;
33
+ export const downloadRootDir = PushyConstants.downloadRootDir;
34
+ export const packageVersion = PushyConstants.packageVersion;
35
+ export const currentVersion = PushyConstants.currentVersion;
36
+ export const isFirstTime = PushyConstants.isFirstTime;
37
+ const rolledBackVersion = PushyConstants.rolledBackVersion;
30
38
  export const isRolledBack = typeof rolledBackVersion === 'string';
31
39
 
32
- export const buildTime = Pushy.buildTime;
33
- let blockUpdate = Pushy.blockUpdate;
34
- let uuid = Pushy.uuid;
40
+ export const buildTime = PushyConstants.buildTime;
41
+ let blockUpdate = PushyConstants.blockUpdate;
42
+ let uuid = PushyConstants.uuid;
35
43
 
36
- if (Platform.OS === 'android' && !Pushy.isUsingBundleUrl) {
44
+ if (Platform.OS === 'android' && !PushyConstants.isUsingBundleUrl) {
37
45
  throw new Error(
38
46
  'react-native-update模块无法加载,请对照文档检查Bundle URL的配置',
39
47
  );
40
48
  }
41
49
 
42
- function setLocalHashInfo(hash, info) {
43
- Pushy.setLocalHashInfo(hash, JSON.stringify(info));
50
+ function setLocalHashInfo(hash: string, info: Record<string, any>) {
51
+ PushyModule.setLocalHashInfo(hash, JSON.stringify(info));
44
52
  }
45
53
 
46
- async function getLocalHashInfo(hash) {
47
- return JSON.parse(await Pushy.getLocalHashInfo(hash));
54
+ async function getLocalHashInfo(hash: string) {
55
+ return JSON.parse(await PushyModule.getLocalHashInfo(hash));
48
56
  }
49
57
 
50
- export async function getCurrentVersionInfo() {
58
+ export async function getCurrentVersionInfo(): Promise<{
59
+ name?: string;
60
+ description?: string;
61
+ metaInfo?: string;
62
+ }> {
51
63
  return currentVersion ? (await getLocalHashInfo(currentVersion)) || {} : {};
52
64
  }
53
65
 
54
- const eventEmitter = new NativeEventEmitter(Pushy);
66
+ const eventEmitter = new NativeEventEmitter(PushyModule);
55
67
 
56
68
  if (!uuid) {
57
69
  uuid = require('nanoid/non-secure').nanoid();
58
- Pushy.setUuid(uuid);
59
- }
60
-
61
- function logger(...args) {
62
- console.log('Pushy: ', ...args);
70
+ PushyModule.setUuid(uuid);
63
71
  }
64
72
 
65
73
  const noop = () => {};
66
- let reporter = noop;
74
+ let reporter: UpdateEventsListener = noop;
67
75
 
68
- export function onEvents(customReporter) {
76
+ export function onPushyEvents(customReporter: UpdateEventsListener) {
69
77
  reporter = customReporter;
70
78
  if (isRolledBack) {
71
79
  report({
@@ -77,7 +85,15 @@ export function onEvents(customReporter) {
77
85
  }
78
86
  }
79
87
 
80
- function report({ type, message = '', data = {} }) {
88
+ function report({
89
+ type,
90
+ message = '',
91
+ data = {},
92
+ }: {
93
+ type: EventType;
94
+ message?: string;
95
+ data?: Record<string, string | number>;
96
+ }) {
81
97
  logger(type + ' ' + message);
82
98
  reporter({
83
99
  type,
@@ -101,19 +117,10 @@ export const cInfo = {
101
117
  uuid,
102
118
  };
103
119
 
104
- function assertRelease() {
105
- if (__DEV__) {
106
- throw new Error('react-native-update 只能在 RELEASE 版本中运行.');
107
- }
108
- }
109
-
110
120
  let lastChecking;
111
121
  const empty = {};
112
- let lastResult;
113
- export async function checkUpdate(APPKEY, isRetry) {
114
- if (typeof APPKEY !== 'string') {
115
- throw new Error('未检查到合法的APPKEY,请查看update.json文件是否正确生成');
116
- }
122
+ let lastResult: CheckResult;
123
+ export async function checkUpdate(APPKEY: string) {
117
124
  assertRelease();
118
125
  const now = Date.now();
119
126
  if (lastResult && lastChecking && now - lastChecking < 1000 * 60) {
@@ -131,40 +138,55 @@ export async function checkUpdate(APPKEY, isRetry) {
131
138
  return lastResult || empty;
132
139
  }
133
140
  report({ type: 'checking' });
141
+ const fetchPayload = {
142
+ method: 'POST',
143
+ headers: {
144
+ Accept: 'application/json',
145
+ 'Content-Type': 'application/json',
146
+ },
147
+ body: JSON.stringify({
148
+ packageVersion,
149
+ hash: currentVersion,
150
+ buildTime,
151
+ cInfo,
152
+ }),
153
+ };
134
154
  let resp;
135
155
  try {
136
- resp = await fetch(getCheckUrl(APPKEY), {
137
- method: 'POST',
138
- headers: {
139
- Accept: 'application/json',
140
- 'Content-Type': 'application/json',
141
- },
142
- body: JSON.stringify({
143
- packageVersion,
144
- hash: currentVersion,
145
- buildTime,
146
- cInfo,
147
- }),
148
- });
156
+ resp = await fetch(getCheckUrl(APPKEY), fetchPayload);
149
157
  } catch (e) {
150
- if (isRetry) {
151
- report({
152
- type: 'errorChecking',
153
- message: '无法连接更新服务器,请检查网络连接后重试',
154
- });
155
- return lastResult || empty;
158
+ report({
159
+ type: 'errorChecking',
160
+ message: '无法连接主更新服务器,尝试备用节点',
161
+ });
162
+ const backupEndpoints = await updateBackupEndpoints();
163
+ if (backupEndpoints) {
164
+ try {
165
+ resp = await Promise.race(
166
+ backupEndpoints.map((endpoint) =>
167
+ fetch(getCheckUrl(APPKEY, endpoint), fetchPayload),
168
+ ),
169
+ );
170
+ } catch {}
156
171
  }
157
- await tryBackupEndpoints();
158
- return checkUpdate(APPKEY, true);
159
172
  }
160
- const result = await resp.json();
161
- lastResult = result;
173
+ if (!resp) {
174
+ report({
175
+ type: 'errorChecking',
176
+ message: '无法连接更新服务器,请检查网络连接后重试',
177
+ });
178
+ return lastResult || empty;
179
+ }
180
+ const result: CheckResult = await resp.json();
162
181
 
182
+ lastResult = result;
183
+ // @ts-ignore
163
184
  checkOperation(result.op);
164
185
 
165
186
  if (resp.status !== 200) {
166
187
  report({
167
188
  type: 'errorChecking',
189
+ //@ts-ignore
168
190
  message: result.message,
169
191
  });
170
192
  }
@@ -172,7 +194,9 @@ export async function checkUpdate(APPKEY, isRetry) {
172
194
  return result;
173
195
  }
174
196
 
175
- function checkOperation(op) {
197
+ function checkOperation(
198
+ op: { type: string; reason: string; duration: number }[],
199
+ ) {
176
200
  if (!Array.isArray(op)) {
177
201
  return;
178
202
  }
@@ -182,14 +206,19 @@ function checkOperation(op) {
182
206
  reason: action.reason,
183
207
  until: Math.round((Date.now() + action.duration) / 1000),
184
208
  };
185
- Pushy.setBlockUpdate(blockUpdate);
209
+ PushyModule.setBlockUpdate(blockUpdate);
186
210
  }
187
211
  });
188
212
  }
189
213
 
190
214
  let downloadingThrottling = false;
191
- let downloadedHash;
192
- export async function downloadUpdate(options, eventListeners) {
215
+ let downloadedHash: string;
216
+ export async function downloadUpdate(
217
+ options: UpdateAvailableResult,
218
+ eventListeners?: {
219
+ onDownloadProgress?: (data: ProgressData) => void;
220
+ },
221
+ ) {
193
222
  assertRelease();
194
223
  if (!options.update) {
195
224
  return;
@@ -229,7 +258,7 @@ export async function downloadUpdate(options, eventListeners) {
229
258
  if (options.diffUrl) {
230
259
  logger('downloading diff');
231
260
  try {
232
- await Pushy.downloadPatchFromPpk({
261
+ await PushyModule.downloadPatchFromPpk({
233
262
  updateUrl: options.diffUrl,
234
263
  hash: options.hash,
235
264
  originHash: currentVersion,
@@ -242,7 +271,7 @@ export async function downloadUpdate(options, eventListeners) {
242
271
  if (!succeeded && options.pdiffUrl) {
243
272
  logger('downloading pdiff');
244
273
  try {
245
- await Pushy.downloadPatchFromPackage({
274
+ await PushyModule.downloadPatchFromPackage({
246
275
  updateUrl: options.pdiffUrl,
247
276
  hash: options.hash,
248
277
  });
@@ -254,7 +283,7 @@ export async function downloadUpdate(options, eventListeners) {
254
283
  if (!succeeded && options.updateUrl) {
255
284
  logger('downloading full patch');
256
285
  try {
257
- await Pushy.downloadFullUpdate({
286
+ await PushyModule.downloadFullUpdate({
258
287
  updateUrl: options.updateUrl,
259
288
  hash: options.hash,
260
289
  });
@@ -276,7 +305,7 @@ export async function downloadUpdate(options, eventListeners) {
276
305
  return options.hash;
277
306
  }
278
307
 
279
- function assertHash(hash) {
308
+ function assertHash(hash: string) {
280
309
  if (!downloadedHash) {
281
310
  logger(`no downloaded hash`);
282
311
  return;
@@ -288,19 +317,19 @@ function assertHash(hash) {
288
317
  return true;
289
318
  }
290
319
 
291
- export function switchVersion(hash) {
320
+ export function switchVersion(hash: string) {
292
321
  assertRelease();
293
322
  if (assertHash(hash)) {
294
323
  logger('switchVersion: ' + hash);
295
- Pushy.reloadUpdate({ hash });
324
+ PushyModule.reloadUpdate({ hash });
296
325
  }
297
326
  }
298
327
 
299
- export function switchVersionLater(hash) {
328
+ export function switchVersionLater(hash: string) {
300
329
  assertRelease();
301
330
  if (assertHash(hash)) {
302
331
  logger('switchVersionLater: ' + hash);
303
- Pushy.setNeedUpdate({ hash });
332
+ PushyModule.setNeedUpdate({ hash });
304
333
  }
305
334
  }
306
335
 
@@ -312,13 +341,22 @@ export function markSuccess() {
312
341
  return;
313
342
  }
314
343
  marked = true;
315
- Pushy.markSuccess();
316
- report(currentVersion, 'success');
344
+ PushyModule.markSuccess();
345
+ report({ type: 'markSuccess' });
317
346
  }
318
347
 
319
- export async function downloadAndInstallApk({ url, onDownloadProgress }) {
320
- logger('downloadAndInstallApk');
321
- if (Platform.OS === 'android' && Platform.Version <= 23) {
348
+ export async function downloadAndInstallApk({
349
+ url,
350
+ onDownloadProgress,
351
+ }: {
352
+ url: string;
353
+ onDownloadProgress?: (data: ProgressData) => void;
354
+ }) {
355
+ if (Platform.OS !== 'android') {
356
+ return;
357
+ }
358
+ report({ type: 'downloadingApk' });
359
+ if (Platform.Version <= 23) {
322
360
  try {
323
361
  const granted = await PermissionsAndroid.request(
324
362
  PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
@@ -335,14 +373,14 @@ export async function downloadAndInstallApk({ url, onDownloadProgress }) {
335
373
  if (onDownloadProgress) {
336
374
  progressHandler = eventEmitter.addListener(
337
375
  'RCTPushyDownloadProgress',
338
- (progressData) => {
376
+ (progressData: ProgressData) => {
339
377
  if (progressData.hash === hash) {
340
378
  onDownloadProgress(progressData);
341
379
  }
342
380
  },
343
381
  );
344
382
  }
345
- await Pushy.downloadAndInstallApk({
383
+ await PushyModule.downloadAndInstallApk({
346
384
  url,
347
385
  target: 'update.apk',
348
386
  hash,
@@ -1,5 +1,11 @@
1
- import React, { Component } from 'react';
2
- import { Platform, Alert, Linking, AppState } from 'react-native';
1
+ import React, { PureComponent, ComponentType } from 'react';
2
+ import {
3
+ Platform,
4
+ Alert,
5
+ Linking,
6
+ AppState,
7
+ NativeEventSubscription,
8
+ } from 'react-native';
3
9
 
4
10
  import {
5
11
  isFirstTime,
@@ -10,16 +16,25 @@ import {
10
16
  switchVersionLater,
11
17
  markSuccess,
12
18
  downloadAndInstallApk,
19
+ onPushyEvents,
13
20
  } from './main';
21
+ import { UpdateEventsListener } from './type';
14
22
 
15
- export function simpleUpdate(WrappedComponent, options = {}) {
16
- const { appKey } = options;
23
+ export function simpleUpdate(
24
+ WrappedComponent: ComponentType,
25
+ options: { appKey?: string; onPushyEvents?: UpdateEventsListener } = {},
26
+ ) {
27
+ const { appKey, onPushyEvents: eventListeners } = options;
17
28
  if (!appKey) {
18
29
  throw new Error('appKey is required for simpleUpdate()');
19
30
  }
31
+ if (typeof eventListeners === 'function') {
32
+ onPushyEvents(eventListeners);
33
+ }
20
34
  return __DEV__
21
35
  ? WrappedComponent
22
- : class AppUpdate extends Component {
36
+ : class AppUpdate extends PureComponent {
37
+ stateListener: NativeEventSubscription;
23
38
  componentDidMount() {
24
39
  if (isRolledBack) {
25
40
  Alert.alert('抱歉', '刚刚更新遭遇错误,已为您恢复到更新前版本');
@@ -70,7 +85,7 @@ export function simpleUpdate(WrappedComponent, options = {}) {
70
85
  checkUpdate = async () => {
71
86
  let info;
72
87
  try {
73
- info = await checkUpdate(appKey);
88
+ info = await checkUpdate(appKey!);
74
89
  } catch (err) {
75
90
  Alert.alert('更新检查失败', err.message);
76
91
  return;
package/lib/type.ts ADDED
@@ -0,0 +1,71 @@
1
+ export interface ExpiredResult {
2
+ upToDate?: false;
3
+ expired: true;
4
+ downloadUrl: string;
5
+ }
6
+
7
+ export interface UpTodateResult {
8
+ expired?: false;
9
+ upToDate: true;
10
+ paused?: 'app' | 'package';
11
+ }
12
+
13
+ export interface UpdateAvailableResult {
14
+ expired?: false;
15
+ upToDate?: false;
16
+ update: true;
17
+ name: string; // version name
18
+ hash: string;
19
+ description: string;
20
+ metaInfo: string;
21
+ pdiffUrl: string;
22
+ diffUrl?: string;
23
+ updateUrl?: string;
24
+ }
25
+
26
+ export type CheckResult =
27
+ | ExpiredResult
28
+ | UpTodateResult
29
+ | UpdateAvailableResult
30
+ | {};
31
+
32
+ export interface ProgressData {
33
+ hash: string;
34
+ received: number;
35
+ total: number;
36
+ }
37
+
38
+ export type EventType =
39
+ | 'rollback'
40
+ | 'errorChecking'
41
+ | 'checking'
42
+ | 'downloading'
43
+ | 'errorUpdate'
44
+ | 'markSuccess'
45
+ | 'downloadingApk'
46
+ | 'rejectStoragePermission'
47
+ | 'errorStoragePermission'
48
+ | 'errowDownloadAndInstallApk';
49
+
50
+ export interface EventData {
51
+ currentVersion: string;
52
+ cInfo: {
53
+ pushy: string;
54
+ rn: string;
55
+ os: string;
56
+ uuid: string;
57
+ };
58
+ packageVersion: string;
59
+ buildTime: number;
60
+ message?: string;
61
+ rolledBackVersion?: string;
62
+ newVersion?: string;
63
+ [key: string]: any;
64
+ }
65
+ export type UpdateEventsListener = ({
66
+ type,
67
+ data,
68
+ }: {
69
+ type: EventType;
70
+ data: EventData;
71
+ }) => void;
package/lib/utils.ts ADDED
@@ -0,0 +1,9 @@
1
+ export function logger(...args: any[]) {
2
+ console.log('Pushy: ', ...args);
3
+ }
4
+
5
+ export function assertRelease() {
6
+ if (__DEV__) {
7
+ throw new Error('react-native-update 只能在 RELEASE 版本中运行.');
8
+ }
9
+ }
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "react-native-update",
3
- "version": "8.2.0",
3
+ "version": "8.4.0",
4
4
  "description": "react-native hot update",
5
- "main": "lib/index.js",
5
+ "main": "lib/index.ts",
6
6
  "scripts": {
7
7
  "prepublish": "yarn submodule",
8
8
  "submodule": "git submodule update --init --recursive",
@@ -25,10 +25,16 @@
25
25
  "url": "https://github.com/reactnativecn/react-native-pushy/issues"
26
26
  },
27
27
  "peerDependencies": {
28
- "react-native": ">=0.27.0"
28
+ "react-native": ">=0.57.0"
29
29
  },
30
30
  "homepage": "https://github.com/reactnativecn/react-native-pushy#readme",
31
31
  "dependencies": {
32
32
  "nanoid": "^3.3.3"
33
+ },
34
+ "devDependencies": {
35
+ "@types/node": "^20.8.9",
36
+ "@types/react": "^18.2.33",
37
+ "react-native": "^0.72.6",
38
+ "typescript": "^5.2.2"
33
39
  }
34
40
  }
package/lib/endpoint.js DELETED
@@ -1,93 +0,0 @@
1
- let currentEndpoint = 'https://update.react-native.cn/api';
2
-
3
- function ping(url, rejectImmediate) {
4
- return new Promise((resolve, reject) => {
5
- const xhr = new XMLHttpRequest();
6
- xhr.onreadystatechange = (e) => {
7
- if (xhr.readyState !== 4) {
8
- return;
9
- }
10
- if (xhr.status === 200) {
11
- resolve(url);
12
- } else {
13
- rejectImmediate ? reject() : setTimeout(reject, 5000);
14
- }
15
- };
16
- xhr.open('HEAD', url);
17
- xhr.send();
18
- xhr.timeout = 5000;
19
- xhr.ontimeout = reject;
20
- });
21
- }
22
-
23
- function logger(...args) {
24
- // console.warn('pushy', ...args);
25
- }
26
-
27
- let backupEndpoints = [];
28
- let backupEndpointsQueryUrl =
29
- 'https://cdn.jsdelivr.net/gh/reactnativecn/react-native-pushy@master/endpoints.json';
30
-
31
- export async function tryBackupEndpoints() {
32
- if (!backupEndpoints.length && !backupEndpointsQueryUrl) {
33
- return;
34
- }
35
- try {
36
- await ping(getStatusUrl(), true);
37
- logger('current endpoint ok');
38
- return;
39
- } catch (e) {
40
- logger('current endpoint failed');
41
- }
42
- if (!backupEndpoints.length && backupEndpointsQueryUrl) {
43
- try {
44
- const resp = await fetch(backupEndpointsQueryUrl);
45
- backupEndpoints = await resp.json();
46
- logger('get remote endpoints:', backupEndpoints);
47
- } catch (e) {
48
- logger('get remote endpoints failed');
49
- return;
50
- }
51
- }
52
- await pickFatestAvailableEndpoint();
53
- }
54
-
55
- async function pickFatestAvailableEndpoint(endpoints = backupEndpoints) {
56
- const fastestEndpoint = await Promise.race(
57
- endpoints.map(pingAndReturnEndpoint),
58
- );
59
- if (typeof fastestEndpoint === 'string') {
60
- logger(`pick endpoint: ${fastestEndpoint}`);
61
- currentEndpoint = fastestEndpoint;
62
- } else {
63
- logger('all remote endpoints failed');
64
- }
65
- }
66
-
67
- async function pingAndReturnEndpoint(endpoint = currentEndpoint) {
68
- return ping(getStatusUrl(endpoint)).then(() => endpoint);
69
- }
70
-
71
- function getStatusUrl(endpoint = currentEndpoint) {
72
- return `${endpoint}/status`;
73
- }
74
-
75
- export function getCheckUrl(APPKEY, endpoint = currentEndpoint) {
76
- return `${endpoint}/checkUpdate/${APPKEY}`;
77
- }
78
-
79
- export function getReportUrl(endpoint = currentEndpoint) {
80
- return `${endpoint}/report`;
81
- }
82
-
83
- export function setCustomEndpoints({ main, backups, backupQueryUrl }) {
84
- currentEndpoint = main;
85
- backupEndpointsQueryUrl = null;
86
- if (Array.isArray(backups) && backups.length > 0) {
87
- backupEndpoints = backups;
88
- pickFatestAvailableEndpoint();
89
- }
90
- if (typeof backupQueryUrl === 'string') {
91
- backupEndpointsQueryUrl = backupQueryUrl;
92
- }
93
- }
package/lib/index.d.ts DELETED
@@ -1,94 +0,0 @@
1
- export const downloadRootDir: string;
2
- export const packageVersion: string;
3
- export const currentVersion: string;
4
- export const isFirstTime: boolean;
5
- export const isRolledBack: boolean;
6
-
7
- export interface ExpiredResult {
8
- upToDate?: false;
9
- expired: true;
10
- downloadUrl: string;
11
- }
12
-
13
- export interface UpTodateResult {
14
- expired?: false;
15
- upToDate: true;
16
- paused?: 'app' | 'package';
17
- }
18
-
19
- export interface UpdateAvailableResult {
20
- expired?: false;
21
- upToDate?: false;
22
- update: true;
23
- name: string; // version name
24
- hash: string;
25
- description: string;
26
- metaInfo: string;
27
- pdiffUrl: string;
28
- diffUrl?: string;
29
- }
30
-
31
- export type CheckResult =
32
- | ExpiredResult
33
- | UpTodateResult
34
- | UpdateAvailableResult;
35
-
36
- export function checkUpdate(appkey: string): Promise<CheckResult>;
37
-
38
- export function downloadUpdate(
39
- info: UpdateAvailableResult,
40
- eventListeners?: {
41
- onDownloadProgress?: (data: ProgressData) => void;
42
- },
43
- ): Promise<undefined | string>;
44
-
45
- export function switchVersion(hash: string): void;
46
-
47
- export function switchVersionLater(hash: string): void;
48
-
49
- export function markSuccess(): void;
50
-
51
- export function downloadAndInstallApk({
52
- url,
53
- onDownloadProgress,
54
- }: {
55
- url: string;
56
- onDownloadProgress?: (data: ProgressData) => void;
57
- }): Promise<void>;
58
-
59
- /**
60
- * @param {string} main - The main api endpoint
61
- * @param {string[]} [backups] - The back up endpoints.
62
- * @param {string} [backupQueryUrl] - An url that return a json file containing an array of endpoint.
63
- * like: ["https://backup.api/1", "https://backup.api/2"]
64
- */
65
- export function setCustomEndpoints({
66
- main,
67
- backups,
68
- backupQueryUrl,
69
- }: {
70
- main: string;
71
- backups?: string[];
72
- backupQueryUrl?: string;
73
- }): void;
74
-
75
- export function getCurrentVersionInfo(): Promise<{
76
- name?: string;
77
- description?: string;
78
- metaInfo?: string;
79
- }>;
80
-
81
- interface ProgressData {
82
- hash: string;
83
- received: number;
84
- total: number;
85
- }
86
-
87
- interface SimpleUpdateOptions {
88
- appKey: string;
89
- }
90
-
91
- export function simpleUpdate(
92
- wrappedComponent: any,
93
- options: SimpleUpdateOptions,
94
- ): any;
File without changes