1import { EventEmitter, UnavailabilityError } from 'expo-modules-core'; 2import ExpoTaskManager from './ExpoTaskManager'; 3const tasks = new Map(); 4function _validateTaskName(taskName) { 5 if (!taskName || typeof taskName !== 'string') { 6 throw new TypeError('`taskName` must be a non-empty string.'); 7 } 8} 9// @needsAudit 10/** 11 * Defines task function. It must be called in the global scope of your JavaScript bundle. 12 * In particular, it cannot be called in any of React lifecycle methods like `componentDidMount`. 13 * This limitation is due to the fact that when the application is launched in the background, 14 * we need to spin up your JavaScript app, run your task and then shut down — no views are mounted 15 * in this scenario. 16 * 17 * @param taskName Name of the task. It must be the same as the name you provided when registering the task. 18 * @param taskExecutor A function that will be invoked when the task with given `taskName` is executed. 19 */ 20export function defineTask(taskName, taskExecutor) { 21 if (!taskName || typeof taskName !== 'string') { 22 console.warn(`TaskManager.defineTask: 'taskName' argument must be a non-empty string.`); 23 return; 24 } 25 if (!taskExecutor || typeof taskExecutor !== 'function') { 26 console.warn(`TaskManager.defineTask: 'task' argument must be a function.`); 27 return; 28 } 29 tasks.set(taskName, taskExecutor); 30} 31// @needsAudit 32/** 33 * Checks whether the task is already defined. 34 * 35 * @param taskName Name of the task. 36 */ 37export function isTaskDefined(taskName) { 38 return tasks.has(taskName); 39} 40// @needsAudit 41/** 42 * Determine whether the task is registered. Registered tasks are stored in a persistent storage and 43 * preserved between sessions. 44 * 45 * @param taskName Name of the task. 46 * @returns A promise which fulfills with a `boolean` value whether or not the task with given name 47 * is already registered. 48 */ 49export async function isTaskRegisteredAsync(taskName) { 50 if (!ExpoTaskManager.isTaskRegisteredAsync) { 51 throw new UnavailabilityError('TaskManager', 'isTaskRegisteredAsync'); 52 } 53 _validateTaskName(taskName); 54 return ExpoTaskManager.isTaskRegisteredAsync(taskName); 55} 56// @needsAudit 57/** 58 * Retrieves `options` associated with the task, that were passed to the function registering the task 59 * (eg. `Location.startLocationUpdatesAsync`). 60 * 61 * @param taskName Name of the task. 62 * @return A promise which fulfills with the `options` object that was passed while registering task 63 * with given name or `null` if task couldn't be found. 64 */ 65export async function getTaskOptionsAsync(taskName) { 66 if (!ExpoTaskManager.getTaskOptionsAsync) { 67 throw new UnavailabilityError('TaskManager', 'getTaskOptionsAsync'); 68 } 69 _validateTaskName(taskName); 70 return ExpoTaskManager.getTaskOptionsAsync(taskName); 71} 72// @needsAudit 73/** 74 * Provides information about tasks registered in the app. 75 * 76 * @returns A promise which fulfills with an array of tasks registered in the app. Example: 77 * ```json 78 * [ 79 * { 80 * taskName: 'location-updates-task-name', 81 * taskType: 'location', 82 * options: { 83 * accuracy: Location.Accuracy.High, 84 * showsBackgroundLocationIndicator: false, 85 * }, 86 * }, 87 * { 88 * taskName: 'geofencing-task-name', 89 * taskType: 'geofencing', 90 * options: { 91 * regions: [...], 92 * }, 93 * }, 94 * ] 95 * ``` 96 */ 97export async function getRegisteredTasksAsync() { 98 if (!ExpoTaskManager.getRegisteredTasksAsync) { 99 throw new UnavailabilityError('TaskManager', 'getRegisteredTasksAsync'); 100 } 101 return ExpoTaskManager.getRegisteredTasksAsync(); 102} 103// @needsAudit 104/** 105 * Unregisters task from the app, so the app will not be receiving updates for that task anymore. 106 * _It is recommended to use methods specialized by modules that registered the task, eg. 107 * [`Location.stopLocationUpdatesAsync`](./location/#expolocationstoplocationupdatesasynctaskname)._ 108 * 109 * @param taskName Name of the task to unregister. 110 * @return A promise which fulfills as soon as the task is unregistered. 111 */ 112export async function unregisterTaskAsync(taskName) { 113 if (!ExpoTaskManager.unregisterTaskAsync) { 114 throw new UnavailabilityError('TaskManager', 'unregisterTaskAsync'); 115 } 116 _validateTaskName(taskName); 117 await ExpoTaskManager.unregisterTaskAsync(taskName); 118} 119// @needsAudit 120/** 121 * Unregisters all tasks registered for the running app. You may want to call this when the user is 122 * signing out and you no longer need to track his location or run any other background tasks. 123 * @return A promise which fulfills as soon as all tasks are completely unregistered. 124 */ 125export async function unregisterAllTasksAsync() { 126 if (!ExpoTaskManager.unregisterAllTasksAsync) { 127 throw new UnavailabilityError('TaskManager', 'unregisterAllTasksAsync'); 128 } 129 await ExpoTaskManager.unregisterAllTasksAsync(); 130} 131if (ExpoTaskManager) { 132 const eventEmitter = new EventEmitter(ExpoTaskManager); 133 eventEmitter.addListener(ExpoTaskManager.EVENT_NAME, async ({ data, error, executionInfo }) => { 134 const { eventId, taskName } = executionInfo; 135 const taskExecutor = tasks.get(taskName); 136 let result = null; 137 if (taskExecutor) { 138 try { 139 // Execute JS task 140 result = await taskExecutor({ data, error, executionInfo }); 141 } 142 catch (error) { 143 console.error(`TaskManager: Task "${taskName}" failed:`, error); 144 } 145 finally { 146 // Notify manager the task is finished. 147 await ExpoTaskManager.notifyTaskFinishedAsync(taskName, { eventId, result }); 148 } 149 } 150 else { 151 console.warn(`TaskManager: Task "${taskName}" has been executed but looks like it is not defined. Please make sure that "TaskManager.defineTask" is called during initialization phase.`); 152 // No tasks defined -> we need to notify about finish anyway. 153 await ExpoTaskManager.notifyTaskFinishedAsync(taskName, { eventId, result }); 154 // We should also unregister such tasks automatically as the task might have been removed 155 // from the app or just renamed - in that case it needs to be registered again (with the new name). 156 await ExpoTaskManager.unregisterTaskAsync(taskName); 157 } 158 }); 159} 160// @needsAudit 161/** 162 * Determine if the `TaskManager` API can be used in this app. 163 * @return A promise fulfills with `true` if the API can be used, and `false` otherwise. 164 * On the web it always returns `false`. 165 */ 166export async function isAvailableAsync() { 167 return await ExpoTaskManager.isAvailableAsync(); 168} 169//# sourceMappingURL=TaskManager.js.map