UNPKG

@ledgerhq/live-common

Version:
115 lines 5.18 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getLatestAvailableFirmwareAction = exports.initialState = void 0; const rxjs_1 = require("rxjs"); const operators_1 = require("rxjs/operators"); const getLatestFirmware_1 = require("../tasks/getLatestFirmware"); const getDeviceInfo_1 = require("../tasks/getDeviceInfo"); const core_1 = require("./core"); exports.initialState = { firmwareUpdateContext: null, deviceInfo: null, status: "idle", ...core_1.initialSharedActionState, }; /** * Get the latest available firmware that the device could update to * * @param `deviceId` A device id, or an empty string if device is usb plugged * @returns an Observables that emits the evolution of the state machine until finding (or not) * the latest available firmware. The state is as follow (+ shared state with other actions): * - `firmwareUpdateContext`: the `FirmwareUpdateContext` when retrieved, null otherwise * - `deviceInfo`: the `DeviceInfo` when retrieved, null otherwise * - `status`: the current status of the action: "error" | "no-available-firmware" | "available-firmware" meaning the action has finished * - `error`: an error coming from the business logic, the device or internal. Some error are retried: * `{ type`: "SharedError", retrying: true, ... }` * - `...sharedActionState` */ function getLatestAvailableFirmwareAction({ deviceId, }) { const observable = new rxjs_1.Observable(subscriber => { subscriber.next({ type: "stateUpdate", status: "ongoing", }); (0, getDeviceInfo_1.getDeviceInfoTask)({ deviceId }) .pipe((0, operators_1.switchMap)(event => { if (event.type !== "data") { return (0, rxjs_1.of)(event); } const { deviceInfo } = event; // Update the action state before the next task subscriber.next({ type: "stateUpdate", status: "ongoing", deviceInfo, lockedDevice: false, error: null, }); // Keeps `deviceInfo` in the next event return (0, rxjs_1.forkJoin)([(0, getLatestFirmware_1.getLatestFirmwareTask)({ deviceId, deviceInfo }), (0, rxjs_1.of)(deviceInfo)]).pipe( // Creating a new "event"-like object, extending it with `deviceInfo` (0, operators_1.switchMap)(([event, deviceInfo]) => { return (0, rxjs_1.of)({ ...event, deviceInfo, }); })); })) .subscribe(subscriber); }); return observable.pipe((0, operators_1.scan)((currentState, event) => { switch (event.type) { case "taskError": // Maps firmware already up-to-date task error to `status` "no-available-firmware" if (event.error === "FirmwareUpToDate") { return { ...currentState, firmwareUpdateContext: null, deviceInfo: "deviceInfo" in event ? event.deviceInfo : null, status: "no-available-firmware", }; } return { ...currentState, error: { type: "GetLatestAvailableFirmwareError", name: event.error, }, firmwareUpdateContext: null, deviceInfo: "deviceInfo" in event ? event.deviceInfo : null, status: "error", }; case "data": return { ...currentState, error: null, firmwareUpdateContext: event.firmwareUpdateContext, deviceInfo: event.deviceInfo, status: "available-firmware", }; case "error": { const sharedState = (0, core_1.sharedReducer)({ event, }); return { ...currentState, ...sharedState, firmwareUpdateContext: null, deviceInfo: "deviceInfo" in event ? event.deviceInfo : null, status: sharedState.error?.retrying ? "ongoing" : "error", }; } case "stateUpdate": // Updates only the prop that are defined in the event return { ...currentState, ...(event.lockedDevice !== undefined ? { lockedDevice: event.lockedDevice } : {}), ...(event.deviceInfo !== undefined ? { deviceInfo: event.deviceInfo } : {}), ...(event.status !== undefined ? { status: event.status } : {}), ...(event.error !== undefined ? { error: event.error } : {}), }; } }, exports.initialState)); } exports.getLatestAvailableFirmwareAction = getLatestAvailableFirmwareAction; //# sourceMappingURL=getLatestAvailableFirmware.js.map