UNPKG

@hot-updater/react-native

Version:

React Native OTA solution for self-hosted

167 lines (157 loc) 6.05 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.wrap = wrap; var _react = _interopRequireWildcard(require("react")); var _checkForUpdate = require("./checkForUpdate.js"); var _useEventCallback = require("./hooks/useEventCallback.js"); var _native = require("./native.js"); var _store = require("./store.js"); var _jsxRuntime = require("react/jsx-runtime"); function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); } /** * Common options shared between auto and manual update modes */ /** * Configuration with baseURL for standard server-based updates */ /** * Configuration with resolver for custom network operations */ /** * Union type ensuring baseURL and resolver are mutually exclusive */ /** * Internal options after normalization in index.ts * Always has resolver (never baseURL) */ /** * Helper function to handle notifyAppReady flow */ const handleNotifyAppReady = async options => { try { // Always call native notifyAppReady for bundle promotion const nativeResult = (0, _native.notifyAppReady)(); // If resolver.notifyAppReady exists, call it with simplified params if (options.resolver?.notifyAppReady) { await options.resolver.notifyAppReady({ status: nativeResult.status, crashedBundleId: nativeResult.crashedBundleId, requestHeaders: options.requestHeaders, requestTimeout: options.requestTimeout }).catch(e => { console.warn("[HotUpdater] Resolver notifyAppReady failed:", e); }); } options.onNotifyAppReady?.(nativeResult); } catch (e) { console.warn("[HotUpdater] Failed to notify app ready:", e); } }; function wrap(options) { if (options.updateMode === "manual") { return WrappedComponent => { const ManualHOC = props => { (0, _react.useLayoutEffect)(() => { void handleNotifyAppReady(options); }, []); return /*#__PURE__*/(0, _jsxRuntime.jsx)(WrappedComponent, { ...props }); }; return ManualHOC; }; } // updateMode: "auto" const { reloadOnForceUpdate = true, ...restOptions } = options; return WrappedComponent => { const HotUpdaterHOC = props => { const progress = (0, _store.useHotUpdaterStore)(state => state.progress); const [message, setMessage] = (0, _react.useState)(null); const [updateStatus, setUpdateStatus] = (0, _react.useState)("CHECK_FOR_UPDATE"); const initHotUpdater = (0, _useEventCallback.useEventCallback)(async () => { try { setUpdateStatus("CHECK_FOR_UPDATE"); const updateInfo = await (0, _checkForUpdate.checkForUpdate)({ resolver: restOptions.resolver, updateStrategy: restOptions.updateStrategy, requestHeaders: restOptions.requestHeaders, requestTimeout: restOptions.requestTimeout, onError: restOptions.onError }); setMessage(updateInfo?.message ?? null); if (!updateInfo) { restOptions.onUpdateProcessCompleted?.({ status: "UP_TO_DATE", shouldForceUpdate: false, message: null, id: (0, _native.getBundleId)() }); setUpdateStatus("UPDATE_PROCESS_COMPLETED"); return; } if (updateInfo.shouldForceUpdate === false) { void updateInfo.updateBundle().catch(error => { restOptions.onError?.(error); }); restOptions.onUpdateProcessCompleted?.({ id: updateInfo.id, status: updateInfo.status, shouldForceUpdate: updateInfo.shouldForceUpdate, message: updateInfo.message }); setUpdateStatus("UPDATE_PROCESS_COMPLETED"); return; } // Force Update Scenario setUpdateStatus("UPDATING"); const isSuccess = await updateInfo.updateBundle(); if (!isSuccess) { throw new Error("New update was found but failed to download the bundle."); } if (reloadOnForceUpdate) { await (0, _native.reload)(); } restOptions.onUpdateProcessCompleted?.({ id: updateInfo.id, status: updateInfo.status, shouldForceUpdate: updateInfo.shouldForceUpdate, message: updateInfo.message }); setUpdateStatus("UPDATE_PROCESS_COMPLETED"); } catch (error) { restOptions.onError?.(error); setUpdateStatus("UPDATE_PROCESS_COMPLETED"); } }); (0, _react.useEffect)(() => { restOptions.onProgress?.(progress); }, [progress]); // Notify native side that app is ready (JS bundle fully loaded) (0, _react.useLayoutEffect)(() => { void handleNotifyAppReady(restOptions); }, []); // Start update check (0, _react.useLayoutEffect)(() => { initHotUpdater(); }, []); if (restOptions.fallbackComponent && updateStatus !== "UPDATE_PROCESS_COMPLETED") { const Fallback = restOptions.fallbackComponent; return /*#__PURE__*/(0, _jsxRuntime.jsx)(Fallback, { progress: progress, status: updateStatus, message: message }); } return /*#__PURE__*/(0, _jsxRuntime.jsx)(WrappedComponent, { ...props }); }; return HotUpdaterHOC; }; } //# sourceMappingURL=wrap.js.map