@hot-updater/react-native 1.0.0-rc.40 → 1.0.0-rc.41
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/lib/commonjs/appReady.js +25 -31
- package/lib/commonjs/appReady.js.map +1 -1
- package/lib/commonjs/checkForUpdate.js +9 -9
- package/lib/commonjs/checkForUpdate.js.map +1 -1
- package/lib/commonjs/error.js +1 -1
- package/lib/commonjs/httpClient.js +1 -1
- package/lib/commonjs/index.js +304 -326
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/init.types.js +6 -0
- package/lib/commonjs/init.types.js.map +1 -0
- package/lib/commonjs/native.js +3 -3
- package/lib/commonjs/pluginHost.js +11 -15
- package/lib/commonjs/pluginHost.js.map +1 -1
- package/lib/commonjs/sdkVersion.js +1 -1
- package/lib/commonjs/wrap.js +7 -16
- package/lib/commonjs/wrap.js.map +1 -1
- package/lib/module/appReady.js +23 -28
- package/lib/module/appReady.js.map +1 -1
- package/lib/module/checkForUpdate.js +10 -10
- package/lib/module/checkForUpdate.js.map +1 -1
- package/lib/module/clientPlugin.js.map +1 -1
- package/lib/module/error.js +1 -1
- package/lib/module/httpClient.js +1 -1
- package/lib/module/index.js +299 -329
- package/lib/module/index.js.map +1 -1
- package/lib/module/init.types.js +4 -0
- package/lib/module/init.types.js.map +1 -0
- package/lib/module/native.js +3 -3
- package/lib/module/pluginHost.js +9 -9
- package/lib/module/pluginHost.js.map +1 -1
- package/lib/module/sdkVersion.js +1 -1
- package/lib/module/wrap.js +7 -15
- package/lib/module/wrap.js.map +1 -1
- package/lib/typescript/commonjs/appReady.d.ts +18 -9
- package/lib/typescript/commonjs/appReady.d.ts.map +1 -1
- package/lib/typescript/commonjs/checkForUpdate.d.ts +5 -3
- package/lib/typescript/commonjs/checkForUpdate.d.ts.map +1 -1
- package/lib/typescript/commonjs/clientPlugin.d.ts +1 -1
- package/lib/typescript/commonjs/clientPlugin.d.ts.map +1 -1
- package/lib/typescript/commonjs/error.d.ts +1 -1
- package/lib/typescript/commonjs/httpClient.d.ts +1 -1
- package/lib/typescript/commonjs/httpClient.d.ts.map +1 -1
- package/lib/typescript/commonjs/index.d.ts +122 -110
- package/lib/typescript/commonjs/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/init.types.d.ts +21 -0
- package/lib/typescript/commonjs/init.types.d.ts.map +1 -0
- package/lib/typescript/commonjs/native.d.ts +3 -3
- package/lib/typescript/commonjs/pluginHost.d.ts +7 -3
- package/lib/typescript/commonjs/pluginHost.d.ts.map +1 -1
- package/lib/typescript/commonjs/sdkVersion.d.ts +1 -1
- package/lib/typescript/commonjs/wrap.d.ts +2 -3
- package/lib/typescript/commonjs/wrap.d.ts.map +1 -1
- package/lib/typescript/commonjs/wrap.types.d.ts +13 -40
- package/lib/typescript/commonjs/wrap.types.d.ts.map +1 -1
- package/lib/typescript/module/appReady.d.ts +18 -9
- package/lib/typescript/module/appReady.d.ts.map +1 -1
- package/lib/typescript/module/checkForUpdate.d.ts +5 -3
- package/lib/typescript/module/checkForUpdate.d.ts.map +1 -1
- package/lib/typescript/module/clientPlugin.d.ts +1 -1
- package/lib/typescript/module/clientPlugin.d.ts.map +1 -1
- package/lib/typescript/module/error.d.ts +1 -1
- package/lib/typescript/module/httpClient.d.ts +1 -1
- package/lib/typescript/module/httpClient.d.ts.map +1 -1
- package/lib/typescript/module/index.d.ts +122 -110
- package/lib/typescript/module/index.d.ts.map +1 -1
- package/lib/typescript/module/init.types.d.ts +21 -0
- package/lib/typescript/module/init.types.d.ts.map +1 -0
- package/lib/typescript/module/native.d.ts +3 -3
- package/lib/typescript/module/pluginHost.d.ts +7 -3
- package/lib/typescript/module/pluginHost.d.ts.map +1 -1
- package/lib/typescript/module/sdkVersion.d.ts +1 -1
- package/lib/typescript/module/wrap.d.ts +2 -3
- package/lib/typescript/module/wrap.d.ts.map +1 -1
- package/lib/typescript/module/wrap.types.d.ts +13 -40
- package/lib/typescript/module/wrap.types.d.ts.map +1 -1
- package/package.json +4 -3
- package/src/appReady.ts +43 -37
- package/src/checkForUpdate.ts +19 -11
- package/src/clientPlugin.ts +3 -0
- package/src/error.ts +1 -1
- package/src/httpClient.ts +1 -1
- package/src/index.ts +344 -422
- package/src/init.types.ts +24 -0
- package/src/native.ts +3 -3
- package/src/pluginHost.ts +16 -11
- package/src/sdkVersion.ts +1 -1
- package/src/wrap.tsx +6 -20
- package/src/wrap.types.ts +18 -45
package/src/appReady.ts
CHANGED
|
@@ -8,11 +8,7 @@ import {
|
|
|
8
8
|
type NotifyAppReadyResult,
|
|
9
9
|
readNotifyAppReady,
|
|
10
10
|
} from "./native";
|
|
11
|
-
import {
|
|
12
|
-
buildPluginEvent,
|
|
13
|
-
dispatchPluginHook,
|
|
14
|
-
emitPluginHook,
|
|
15
|
-
} from "./pluginHost";
|
|
11
|
+
import type { PluginHost } from "./pluginHost";
|
|
16
12
|
|
|
17
13
|
export type NotifyAppReadyOptions = {
|
|
18
14
|
onNotifyAppReady?: (result: NotifyAppReadyResult) => void;
|
|
@@ -21,10 +17,6 @@ export type NotifyAppReadyOptions = {
|
|
|
21
17
|
|
|
22
18
|
type RequestAnimationFrame = (callback: (timestamp: number) => void) => number;
|
|
23
19
|
|
|
24
|
-
let didEmitAppReady = false;
|
|
25
|
-
/** Settles once this runtime's launch was read, whether it was reported or failed. */
|
|
26
|
-
let appReadyRead: Promise<unknown> | null = null;
|
|
27
|
-
|
|
28
20
|
const waitForNextFrame = () =>
|
|
29
21
|
new Promise<void>((resolve) => {
|
|
30
22
|
const requestAnimationFrame = (
|
|
@@ -87,6 +79,7 @@ const toAppReadyResult = (
|
|
|
87
79
|
};
|
|
88
80
|
|
|
89
81
|
const notifyAppReady = async (
|
|
82
|
+
host: PluginHost,
|
|
90
83
|
options: NotifyAppReadyOptions,
|
|
91
84
|
): Promise<NotifyAppReadyResult | undefined> => {
|
|
92
85
|
try {
|
|
@@ -97,10 +90,9 @@ const notifyAppReady = async (
|
|
|
97
90
|
} while (nativeReadResult.pending);
|
|
98
91
|
|
|
99
92
|
const { result, transition } = nativeReadResult;
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}
|
|
93
|
+
host.emitPluginHook("onAppReady", () =>
|
|
94
|
+
toAppReadyResult(result, transition),
|
|
95
|
+
);
|
|
104
96
|
|
|
105
97
|
options.onNotifyAppReady?.(result);
|
|
106
98
|
return result;
|
|
@@ -113,29 +105,43 @@ const notifyAppReady = async (
|
|
|
113
105
|
}
|
|
114
106
|
};
|
|
115
107
|
|
|
116
|
-
/**
|
|
117
|
-
export
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
108
|
+
/** An instance's launch: read once, and reported to the instance's plugins. */
|
|
109
|
+
export interface LaunchReporter {
|
|
110
|
+
/**
|
|
111
|
+
* Reads this launch once native finalizes it and reports it to the
|
|
112
|
+
* plugins, once. It rejects only if `onError` throws.
|
|
113
|
+
*/
|
|
114
|
+
read(
|
|
115
|
+
options: NotifyAppReadyOptions,
|
|
116
|
+
): Promise<NotifyAppReadyResult | undefined>;
|
|
117
|
+
/** Settles once the launch was read, whether it was reported or failed. */
|
|
118
|
+
readonly appReady: Promise<unknown>;
|
|
119
|
+
/**
|
|
120
|
+
* Calls a plugin hook after the instance's `onAppReady`, so plugins see the
|
|
121
|
+
* launch before anything that followed it. The event is built now, from the
|
|
122
|
+
* state it describes, and only when a plugin listens.
|
|
123
|
+
*/
|
|
124
|
+
emit: PluginHost["emitPluginHook"];
|
|
125
|
+
}
|
|
124
126
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
127
|
+
export const createLaunchReporter = (host: PluginHost): LaunchReporter => {
|
|
128
|
+
let launchRead: Promise<NotifyAppReadyResult | undefined> | null = null;
|
|
129
|
+
return {
|
|
130
|
+
read: (options) => {
|
|
131
|
+
launchRead ??= notifyAppReady(host, options);
|
|
132
|
+
return launchRead;
|
|
133
|
+
},
|
|
134
|
+
get appReady() {
|
|
135
|
+
return launchRead ?? Promise.resolve();
|
|
136
|
+
},
|
|
137
|
+
emit: (name, createPayload) => {
|
|
138
|
+
const payload = host.buildPluginEvent(name, createPayload);
|
|
139
|
+
if (payload === null) return;
|
|
140
|
+
if (launchRead === null) {
|
|
141
|
+
host.dispatchPluginHook(name, payload);
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
void launchRead.then(() => host.dispatchPluginHook(name, payload));
|
|
145
|
+
},
|
|
146
|
+
};
|
|
141
147
|
};
|
package/src/checkForUpdate.ts
CHANGED
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
} from "@hot-updater/protocol";
|
|
12
12
|
import { Platform } from "react-native";
|
|
13
13
|
|
|
14
|
-
import {
|
|
14
|
+
import { getRunningReleaseId, type LaunchReporter } from "./appReady";
|
|
15
15
|
import type {
|
|
16
16
|
ReleaseTransitionKind,
|
|
17
17
|
UpdateErrorResource,
|
|
@@ -45,7 +45,6 @@ export interface CheckForUpdateOptions {
|
|
|
45
45
|
* Update strategy
|
|
46
46
|
* - "fingerprint": Use fingerprint hash to check for updates
|
|
47
47
|
* - "appVersion": Use app version to check for updates
|
|
48
|
-
* - Can override the strategy set in HotUpdater.wrap()
|
|
49
48
|
*/
|
|
50
49
|
updateStrategy: "appVersion" | "fingerprint";
|
|
51
50
|
|
|
@@ -75,13 +74,15 @@ export type CheckForUpdateResult = {
|
|
|
75
74
|
readonly transitionKind?: ReleaseTransitionKind;
|
|
76
75
|
/**
|
|
77
76
|
* Updates the bundle.
|
|
78
|
-
* This method is equivalent to `
|
|
77
|
+
* This method is equivalent to `hotUpdater.updateBundle()` but with all required arguments pre-filled.
|
|
79
78
|
*/
|
|
80
79
|
updateBundle: () => Promise<boolean>;
|
|
81
80
|
};
|
|
82
81
|
|
|
83
82
|
export interface InternalCheckForUpdateOptions extends CheckForUpdateOptions {
|
|
84
83
|
client: HotUpdaterHttpClient;
|
|
84
|
+
/** Calls the checking instance's plugin hooks. */
|
|
85
|
+
emit: LaunchReporter["emit"];
|
|
85
86
|
}
|
|
86
87
|
|
|
87
88
|
const sameReceipt = (
|
|
@@ -137,12 +138,13 @@ type UpdateErrorScope = {
|
|
|
137
138
|
* the SDK's JavaScript raised happened in `stage`, fetching `resource`.
|
|
138
139
|
*/
|
|
139
140
|
export const reportUpdateError = (
|
|
141
|
+
emit: LaunchReporter["emit"],
|
|
140
142
|
error: unknown,
|
|
141
143
|
stage: UpdateErrorStage,
|
|
142
144
|
resource: UpdateErrorResource | undefined,
|
|
143
145
|
scope: UpdateErrorScope,
|
|
144
146
|
): void => {
|
|
145
|
-
|
|
147
|
+
emit("onUpdateError", () => {
|
|
146
148
|
const classification = classifyUpdateError(error, stage, resource);
|
|
147
149
|
if (classification === null) return null;
|
|
148
150
|
return {
|
|
@@ -354,7 +356,7 @@ async function checkForReleaseCatalogUpdate(input: {
|
|
|
354
356
|
selection: receipt,
|
|
355
357
|
});
|
|
356
358
|
if (committed && transitionKind === "ADOPT_RELEASE") {
|
|
357
|
-
|
|
359
|
+
options.emit("onUpdateCheck", () => ({
|
|
358
360
|
status: "UNCHANGED",
|
|
359
361
|
channel: receipt.channel,
|
|
360
362
|
bundleId: receipt.bundleId,
|
|
@@ -386,7 +388,7 @@ async function checkForReleaseCatalogUpdate(input: {
|
|
|
386
388
|
status: desired.status,
|
|
387
389
|
});
|
|
388
390
|
if (delivery !== null && desired.bundleId !== input.currentBundleId) {
|
|
389
|
-
|
|
391
|
+
options.emit("onBundleDownloaded", () => ({
|
|
390
392
|
channel: input.targetChannel,
|
|
391
393
|
fromBundleId: input.currentBundleId,
|
|
392
394
|
fromReleaseId,
|
|
@@ -402,7 +404,13 @@ async function checkForReleaseCatalogUpdate(input: {
|
|
|
402
404
|
try {
|
|
403
405
|
return await installSelection();
|
|
404
406
|
} catch (error) {
|
|
405
|
-
reportUpdateError(
|
|
407
|
+
reportUpdateError(
|
|
408
|
+
options.emit,
|
|
409
|
+
error,
|
|
410
|
+
"download",
|
|
411
|
+
"artifact",
|
|
412
|
+
errorScope,
|
|
413
|
+
);
|
|
406
414
|
throw error;
|
|
407
415
|
}
|
|
408
416
|
};
|
|
@@ -413,7 +421,7 @@ async function checkForReleaseCatalogUpdate(input: {
|
|
|
413
421
|
: desired.status === "ROLLBACK"
|
|
414
422
|
? true
|
|
415
423
|
: (release?.shouldForceUpdate ?? false);
|
|
416
|
-
|
|
424
|
+
options.emit("onUpdateCheck", () => ({
|
|
417
425
|
status: "UPDATE_AVAILABLE",
|
|
418
426
|
channel: input.targetChannel,
|
|
419
427
|
fromBundleId: input.currentBundleId,
|
|
@@ -471,7 +479,7 @@ export async function checkForUpdate(
|
|
|
471
479
|
|
|
472
480
|
if (isSwitched && explicitChannel && explicitChannel !== currentChannel) {
|
|
473
481
|
const error = new HotUpdaterError(
|
|
474
|
-
`Runtime channel is already switched to "${currentChannel}". Call
|
|
482
|
+
`Runtime channel is already switched to "${currentChannel}". Call hotUpdater.resetChannel() before checking "${explicitChannel}".`,
|
|
475
483
|
);
|
|
476
484
|
options.onError?.(error);
|
|
477
485
|
throw error;
|
|
@@ -495,7 +503,7 @@ export async function checkForUpdate(
|
|
|
495
503
|
targetChannel,
|
|
496
504
|
});
|
|
497
505
|
if (result === null) {
|
|
498
|
-
|
|
506
|
+
options.emit("onUpdateCheck", () => {
|
|
499
507
|
const releaseId = getRunningReleaseId(currentBundleId, currentChannel);
|
|
500
508
|
return {
|
|
501
509
|
status: "UNCHANGED",
|
|
@@ -508,7 +516,7 @@ export async function checkForUpdate(
|
|
|
508
516
|
}
|
|
509
517
|
return result;
|
|
510
518
|
} catch (error) {
|
|
511
|
-
reportUpdateError(error, "check", "catalog", {
|
|
519
|
+
reportUpdateError(options.emit, error, "check", "catalog", {
|
|
512
520
|
bundleId: currentBundleId,
|
|
513
521
|
channel: targetChannel,
|
|
514
522
|
updateStrategy: options.updateStrategy,
|
package/src/clientPlugin.ts
CHANGED
|
@@ -2,9 +2,12 @@ export {
|
|
|
2
2
|
defineClientPlugin,
|
|
3
3
|
type AppReadyResult,
|
|
4
4
|
type BundleDownloadedInfo,
|
|
5
|
+
type ClientPluginApi,
|
|
6
|
+
type ClientPluginApis,
|
|
5
7
|
type HotUpdaterClientContext,
|
|
6
8
|
type HotUpdaterClientHooks,
|
|
7
9
|
type HotUpdaterClientPlugin,
|
|
10
|
+
type HotUpdaterClientSetup,
|
|
8
11
|
type HotUpdaterClientStorage,
|
|
9
12
|
type ReleaseTransitionKind,
|
|
10
13
|
type UpdateCheckResult,
|
package/src/error.ts
CHANGED
|
@@ -92,7 +92,7 @@ export enum HotUpdaterErrorCode {
|
|
|
92
92
|
/**
|
|
93
93
|
* Bundle is in crashed history and cannot be applied.
|
|
94
94
|
* Thrown when attempting to install a bundle that previously caused a crash.
|
|
95
|
-
* Use
|
|
95
|
+
* Use hotUpdater.clearCrashHistory() to allow retrying this bundle.
|
|
96
96
|
* @retryable false - Bundle was marked as crashed for safety
|
|
97
97
|
*/
|
|
98
98
|
BUNDLE_IN_CRASHED_HISTORY = "BUNDLE_IN_CRASHED_HISTORY",
|
package/src/httpClient.ts
CHANGED
|
@@ -180,7 +180,7 @@ const createSession = (
|
|
|
180
180
|
},
|
|
181
181
|
});
|
|
182
182
|
|
|
183
|
-
/** Creates the private HTTP client
|
|
183
|
+
/** Creates the private HTTP client HotUpdater.init configures. */
|
|
184
184
|
export const createHttpClient = (
|
|
185
185
|
baseURL: HotUpdaterBaseURL,
|
|
186
186
|
onResponse?: (response: UpdateHttpResponse) => void,
|