From b14a53f47516e6aefc09e450d3c4e5b3c090ca9a Mon Sep 17 00:00:00 2001 From: Cedric van Putten Date: Mon, 7 May 2018 18:16:24 +0200 Subject: [PATCH] [expo]: Add missing Updates module (#25549) Expo has created the Updates module since SDK 26 to modify the update mechanism. see https://docs.expo.io/versions/latest/sdk/updates --- types/expo/expo-tests.tsx | 36 +++++++++++++++- types/expo/index.d.ts | 88 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 123 insertions(+), 1 deletion(-) diff --git a/types/expo/expo-tests.tsx b/types/expo/expo-tests.tsx index 36eb5fc22c..fd0d7ad973 100644 --- a/types/expo/expo-tests.tsx +++ b/types/expo/expo-tests.tsx @@ -36,7 +36,8 @@ import { SQLite, Calendar, MailComposer, - Location + Location, + Updates } from 'expo'; const reverseGeocode: Promise = Location.reverseGeocodeAsync({ @@ -744,3 +745,36 @@ async () => { result.status === 'saved'; }; + +async () => { + const updateEventListener: Updates.UpdateEventListener = ({ type, manifest, message }) => { + switch (type) { + case Updates.EventType.DOWNLOAD_STARTED: + case Updates.EventType.DOWNLOAD_PROGRESS: + case Updates.EventType.DOWNLOAD_FINISHED: + case Updates.EventType.NO_UPDATE_AVAILABLE: + case Updates.EventType.ERROR: + return true; + } + }; + + Updates.reload(); + + Updates.reloadFromCache(); + + Updates.addListener(updateEventListener); + + const updateCheckResult = await Updates.checkForUpdateAsync(); + + if (updateCheckResult.isAvailable) { + console.log(updateCheckResult.manifest); + } + + Updates.fetchUpdateAsync(updateEventListener); + + const bundleFetchResult = await Updates.fetchUpdateAsync(); + + if (bundleFetchResult.isNew) { + console.log(bundleFetchResult.manifest); + } +}; diff --git a/types/expo/index.d.ts b/types/expo/index.d.ts index d10ffea9d4..f51d2d13b6 100644 --- a/types/expo/index.d.ts +++ b/types/expo/index.d.ts @@ -2764,3 +2764,91 @@ export namespace MailComposer { ): Promise<{ status: 'sent' | 'saved' | 'cancelled' }>; } // #endregion + +export namespace Updates { + namespace EventType { + /** A new update is available and has started downloading. */ + type DownloadStart = 'downloadStart'; + /** A new update is currently being downloaded and will be stored in the device's cache. */ + type DownloadProgress = 'downloadProgress'; + /** A new update has finished downloading and is now stored in the device's cache. */ + type DownloadFinished = 'downloadFinished'; + /** No updates are available, and the most up-to-date bundle of this experience is already running. */ + type NoUpdateAvailable = 'noUpdateAvailable'; + /** An error occurred trying to fetch the latest update. */ + type Error = 'error'; + + /** A new update is available and has started downloading. */ + const DOWNLOAD_STARTED: DownloadStart; + /** A new update is currently being downloaded and will be stored in the device's cache. */ + const DOWNLOAD_PROGRESS: DownloadProgress; + /** A new update has finished downloading and is now stored in the device's cache. */ + const DOWNLOAD_FINISHED: DownloadFinished; + /** No updates are available, and the most up-to-date bundle of this experience is already running. */ + const NO_UPDATE_AVAILABLE: NoUpdateAvailable; + /** An error occurred trying to fetch the latest update. */ + const ERROR: Error; + } + + interface UpdateCheck { + /** True if an update is available, false if you're already running the most up-to-date JS bundle. */ + isAvailable: boolean; + /** If `isAvailable` is true, the manifest of the available update. Undefined otherwise. */ + manifest?: Constants.Manifest; + } + + interface UpdateBundle { + /** True if the fetched bundle is new (i.e. a different version that the what's currently running). */ + isNew: boolean; + /** Manifest of the fetched update. */ + manifest: Constants.Manifest; + } + + /** An object that is passed into each event listener when a new version is available. */ + interface UpdateEvent { + /** Type of the event */ + type: EventType.DownloadStart + | EventType.DownloadProgress + | EventType.DownloadFinished + | EventType.NoUpdateAvailable + | EventType.Error; + /** If `type === Expo.Updates.EventType.DOWNLOAD_FINISHED`, the manifest of the newly downloaded update. Undefined otherwise. */ + manifest?: Constants.Manifest; + /** If `type === Expo.Updates.EventType.ERROR`, the error message. Undefined otherwise. */ + message?: string; + } + + type UpdateEventListener = (event: UpdateEvent) => any; + + /** + * Invokes a callback when updates-related events occur, + * either on the initial app load or as a result of a call to `Expo.Updates.fetchUpdateAsync`. + */ + function addListener(listener: UpdateEventListener): EventSubscription; + + /** + * Check if a new published version of your project is available. + * Does not actually download the update. + * Rejects if `updates.enabled` is `false` in app.json. + */ + function checkForUpdateAsync(): Promise; + + /** + * Downloads the most recent published version of your experience to the device's local cache. + * Rejects if `updates.enabled` is `false` in app.json. + */ + function fetchUpdateAsync(listener?: UpdateEventListener): Promise; + + /** + * Immediately reloads the current experience. + * This will use your app.json updates configuration to fetch and load the newest available JS supported by the device's Expo environment. + * This is useful for triggering an update of your experience if you have published a new version. + */ + function reload(): void; + + /** + * Immediately reloads the current experience using the most recent cached version. + * This is useful for triggering an update of your experience if you have published and already downloaded a new version. + */ + function reloadFromCache(): void; +}