Deprecated compatibility wrapper that provides backward compatibility for applications migrating from legacy Unimodules infrastructure to Expo Modules API
—
Additional utility functions and event emitters for API deprecation management and platform-specific event handling.
Utility function for deprecating APIs with version-based error throwing and comprehensive warning management.
/**
* Used for deprecating values and throwing an error if a given version of Expo has passed
* @param library - Library name for error prefixing
* @param deprecatedAPI - Name of the deprecated API
* @param options - Deprecation configuration options
*/
function deprecate(
library: string,
deprecatedAPI: string,
options?: {
replacement?: string;
currentVersion?: string;
versionToRemove?: string;
}
): void;Usage Examples:
import { deprecate } from "@unimodules/core";
// Basic deprecation warning
function oldFunction() {
deprecate('MyLibrary', 'oldFunction', {
replacement: 'newFunction'
});
// Original implementation
return 'old result';
}
// Version-based deprecation with removal
function deprecatedAPI() {
deprecate('ExpoCamera', 'takePicture', {
replacement: 'takePictureAsync',
currentVersion: '10.0.0',
versionToRemove: '11.0.0'
});
// This will throw an error if current version >= version to remove
}
// Deprecation without replacement
function removedAPI() {
deprecate('ExpoSensors', 'DeviceMotion.addListener', {
currentVersion: '12.0.0',
versionToRemove: '12.0.0'
});
// This will throw a CodedError with code 'ERR_DEPRECATED_API'
}import { deprecate, CodedError } from "@unimodules/core";
class APIManager {
static warnDeprecated(apiName: string, replacement?: string) {
try {
deprecate('APIManager', apiName, {
replacement,
currentVersion: '1.0.0',
versionToRemove: '2.0.0'
});
} catch (error) {
if (error instanceof CodedError && error.code === 'ERR_DEPRECATED_API') {
console.error(`API removed: ${error.message}`);
throw error;
}
}
}
static conditionalDeprecate(condition: boolean, apiName: string) {
if (condition) {
deprecate('APIManager', apiName, {
replacement: `${apiName}Async`,
currentVersion: '3.0.0'
});
}
}
}Platform-specific event emitter for synthetic events that don't originate from native modules.
/**
* Event emitter for platform-specific synthetic events
*/
const SyntheticPlatformEmitter: EventEmitter;Usage Examples:
import { SyntheticPlatformEmitter } from "@unimodules/core";
// Listen to synthetic platform events
const subscription = SyntheticPlatformEmitter.addListener('customEvent', (data) => {
console.log('Received synthetic event:', data);
});
// Emit synthetic events
SyntheticPlatformEmitter.emit('customEvent', {
message: 'Hello from synthetic emitter'
});
// Clean up
subscription.remove();React Native's device event emitter, re-exported for convenience and compatibility.
/**
* React Native's device event emitter for system-level events
* Re-exported from react-native for convenience
*/
const DeviceEventEmitter: DeviceEventEmitterStatic;
/**
* @deprecated Use DeviceEventEmitter instead
* Legacy alias maintained for backward compatibility
*/
const RCTDeviceEventEmitter: DeviceEventEmitterStatic;Usage Examples:
import { DeviceEventEmitter, RCTDeviceEventEmitter } from "@unimodules/core";
// Modern usage
const keyboardSubscription = DeviceEventEmitter.addListener('keyboardDidShow', (event) => {
console.log('Keyboard height:', event.endCoordinates.height);
});
// Legacy usage (deprecated but still works)
const oldSubscription = RCTDeviceEventEmitter.addListener('keyboardDidHide', () => {
console.log('Keyboard hidden');
});
// Clean up
keyboardSubscription.remove();
oldSubscription.remove();import { SyntheticPlatformEmitter, EventEmitter } from "@unimodules/core";
class CustomEventManager {
private static eventQueue: Array<{ name: string; data: any }> = [];
private static isReady = false;
static emit(eventName: string, data: any) {
if (this.isReady) {
SyntheticPlatformEmitter.emit(eventName, data);
} else {
// Queue events until ready
this.eventQueue.push({ name: eventName, data });
}
}
static setReady() {
this.isReady = true;
// Flush queued events
this.eventQueue.forEach(({ name, data }) => {
SyntheticPlatformEmitter.emit(name, data);
});
this.eventQueue = [];
}
static listen(eventName: string, callback: (data: any) => void) {
return SyntheticPlatformEmitter.addListener(eventName, callback);
}
}import { deprecate } from "@unimodules/core";
class DeprecationManager {
private static warnedAPIs = new Set<string>();
static warnOnce(library: string, api: string, options: any = {}) {
const key = `${library}.${api}`;
if (!this.warnedAPIs.has(key)) {
this.warnedAPIs.add(key);
deprecate(library, api, options);
}
}
static resetWarnings() {
this.warnedAPIs.clear();
}
static getWarnedAPIs() {
return Array.from(this.warnedAPIs);
}
}
// Usage
DeprecationManager.warnOnce('MyModule', 'oldMethod', {
replacement: 'newMethod'
});import { EventEmitter, SyntheticPlatformEmitter } from "@unimodules/core";
function createEventEmitter(namespace: string) {
return {
emit: (eventName: string, data: any) => {
SyntheticPlatformEmitter.emit(`${namespace}:${eventName}`, data);
},
addListener: (eventName: string, listener: (data: any) => void) => {
return SyntheticPlatformEmitter.addListener(`${namespace}:${eventName}`, listener);
},
removeAllListeners: (eventName: string) => {
SyntheticPlatformEmitter.removeAllListeners(`${namespace}:${eventName}`);
}
};
}
// Usage
const myEmitter = createEventEmitter('MyModule');
const subscription = myEmitter.addListener('dataUpdate', (data) => {
console.log('Module data:', data);
});
myEmitter.emit('dataUpdate', { value: 42 });interface DeprecateOptions {
replacement?: string;
currentVersion?: string;
versionToRemove?: string;
}
interface DeviceEventEmitterStatic {
addListener: (eventType: string, listener: (data: any) => void) => { remove: () => void };
emit: (eventType: string, ...args: any[]) => void;
removeAllListeners: (eventType: string) => void;
}Install with Tessl CLI
npx tessl i tessl/npm-unimodules--core