1import * as Updates from './Updates'; 2import type { Manifest, UpdatesNativeStateMachineContext } from './Updates.types'; 3import { UpdateInfoType, type CurrentlyRunningInfo, type UpdateInfo } from './UseUpdates.types'; 4 5// The currently running info, constructed from Updates constants 6export const currentlyRunning: CurrentlyRunningInfo = { 7 updateId: Updates.updateId ?? undefined, 8 channel: Updates.channel ?? undefined, 9 createdAt: Updates.createdAt ?? undefined, 10 isEmbeddedLaunch: Updates.isEmbeddedLaunch, 11 isEmergencyLaunch: Updates.isEmergencyLaunch, 12 manifest: Updates.manifest ?? undefined, 13 runtimeVersion: Updates.runtimeVersion ?? undefined, 14}; 15 16// Type for the state managed by useUpdates(). 17// Used internally by this module and not exported publicly. 18export type UseUpdatesStateType = { 19 availableUpdate?: UpdateInfo; 20 downloadedUpdate?: UpdateInfo; 21 checkError?: Error; 22 downloadError?: Error; 23 initializationError?: Error; 24 isUpdateAvailable: boolean; 25 isUpdatePending: boolean; 26 isChecking: boolean; 27 isDownloading: boolean; 28 lastCheckForUpdateTimeSinceRestart?: Date; 29}; 30 31// Constructs an UpdateInfo from a manifest 32export const updateFromManifest: (manifest: NonNullable<Manifest>) => UpdateInfo = (manifest) => { 33 return { 34 type: UpdateInfoType.NEW, 35 updateId: manifest.id ?? '', 36 createdAt: 37 manifest && 'createdAt' in manifest && manifest.createdAt 38 ? new Date(manifest.createdAt) 39 : manifest && 'publishedTime' in manifest && manifest.publishedTime 40 ? new Date(manifest.publishedTime) 41 : // We should never reach this if the manifest is valid and has a commit time, 42 // but leave this in so that createdAt is always defined 43 new Date(0), 44 manifest, 45 }; 46}; 47 48// Default useUpdates() state 49export const defaultUseUpdatesState: UseUpdatesStateType = { 50 isChecking: false, 51 isDownloading: false, 52 isUpdateAvailable: false, 53 isUpdatePending: false, 54}; 55 56// Transform the useUpdates() state based on native state machine context 57export const reduceUpdatesStateFromContext: ( 58 updatesState: UseUpdatesStateType, 59 context: UpdatesNativeStateMachineContext 60) => UseUpdatesStateType = (updatesState, context) => { 61 const availableUpdate = context?.latestManifest 62 ? updateFromManifest(context?.latestManifest) 63 : undefined; 64 const downloadedUpdate = context?.downloadedManifest 65 ? updateFromManifest(context?.downloadedManifest) 66 : undefined; 67 return { 68 ...updatesState, 69 isUpdateAvailable: context.isUpdateAvailable, 70 isUpdatePending: context.isUpdatePending, 71 isChecking: context.isChecking, 72 isDownloading: context.isDownloading, 73 availableUpdate, 74 downloadedUpdate, 75 checkError: context.checkError, 76 downloadError: context.downloadError, 77 lastCheckForUpdateTimeSinceRestart: context.lastCheckForUpdateTime, 78 }; 79}; 80