expo-updates
Version:
Fetches and manages remotely-hosted assets and updates to your app's JS bundle.
90 lines (78 loc) • 2.99 kB
text/typescript
import ExpoUpdatesModule from './ExpoUpdates';
import type {
UpdatesNativeStateChangeEvent,
UpdatesNativeStateMachineContext,
} from './Updates.types';
export let latestContext = transformNativeStateMachineContext(ExpoUpdatesModule.initialContext);
ExpoUpdatesModule.addListener('Expo.nativeUpdatesStateChangeEvent', _handleNativeStateChangeEvent);
interface UpdatesStateChangeSubscription {
remove(): void;
}
const _updatesStateChangeListeners = new Set<(event: UpdatesNativeStateChangeEvent) => void>();
// Reemits native state change events
function _handleNativeStateChangeEvent(params: any) {
const newParams = typeof params === 'string' ? JSON.parse(params) : { ...params };
const transformedContext = transformNativeStateMachineContext(newParams.context);
// only process state change events if they are in order
if (transformedContext.sequenceNumber <= latestContext.sequenceNumber) {
return;
}
newParams.context = transformedContext;
latestContext = transformedContext;
_updatesStateChangeListeners.forEach((listener) => listener(newParams));
}
/**
* Add listener for state change events
* @hidden
*/
export const addUpdatesStateChangeListener = (
listener: (event: UpdatesNativeStateChangeEvent) => void
): UpdatesStateChangeSubscription => {
_updatesStateChangeListeners.add(listener);
return {
remove() {
_updatesStateChangeListeners.delete(listener);
},
};
};
/**
* Allows JS test to emit a simulated native state change event (used in unit testing)
* @hidden
*/
export const emitTestStateChangeEvent = (event: UpdatesNativeStateChangeEvent) => {
_handleNativeStateChangeEvent(event);
};
/**
* Allows JS test to reset latest context (and sequence number)
* @hidden
*/
export const resetLatestContext = () => {
latestContext = transformNativeStateMachineContext(ExpoUpdatesModule.initialContext);
};
function transformNativeStateMachineContext(
originalNativeContext: UpdatesNativeStateMachineContext & {
latestManifestString?: string;
downloadedManifestString?: string;
lastCheckForUpdateTimeString?: string;
rollbackString?: string;
}
): UpdatesNativeStateMachineContext {
const nativeContext = { ...originalNativeContext };
if (nativeContext.latestManifestString) {
nativeContext.latestManifest = JSON.parse(nativeContext.latestManifestString);
delete nativeContext.latestManifestString;
}
if (nativeContext.downloadedManifestString) {
nativeContext.downloadedManifest = JSON.parse(nativeContext.downloadedManifestString);
delete nativeContext.downloadedManifestString;
}
if (nativeContext.lastCheckForUpdateTimeString) {
nativeContext.lastCheckForUpdateTime = new Date(nativeContext.lastCheckForUpdateTimeString);
delete nativeContext.lastCheckForUpdateTimeString;
}
if (nativeContext.rollbackString) {
nativeContext.rollback = JSON.parse(nativeContext.rollbackString);
delete nativeContext.rollbackString;
}
return nativeContext;
}