nativescript-matrix-sdk
Version:
Native Matrix SDK integration for NativeScript
181 lines (157 loc) • 6.3 kB
text/typescript
import { isAndroid, isIOS } from '@nativescript/core';
import { MatrixClient, MatrixEventType } from './index.d';
import { MatrixError, MatrixErrorType } from './src/errors';
import { Logger } from './src/logger';
import { optimizationsRegistry, optimizers } from './src/optimizations-registry';
import { OptimizedMatrixClient } from './src/optimized-matrix-client';
// Import platform-specific implementations
import { MatrixIOSClient } from './platforms/ios/matrix-client.ios';
import { MatrixAndroidClient } from './platforms/android/matrix-client.android';
/**
* Matrix SDK class that provides access to the Matrix client
* Uses a factory pattern to create the appropriate client based on platform
*/
export class MatrixSDK {
private static instance: MatrixClient | OptimizedMatrixClient | null = null;
private static useOptimizations = true;
/**
* Enable or disable client-side optimizations
* @param enable - Whether to enable optimizations
*/
static enableOptimizations(enable: boolean): void {
MatrixSDK.useOptimizations = enable;
Logger.info(`[MatrixSDK] Optimizations ${enable ? 'enabled' : 'disabled'}`);
// If we already have an instance and changing optimization setting,
// we need to recreate it with the new setting
if (MatrixSDK.instance && enable !== MatrixSDK.isOptimized()) {
Logger.info('[MatrixSDK] Recreating client instance with new optimization settings');
let platformClient: MatrixClient;
if (MatrixSDK.isOptimized()) {
// Get the underlying client from the optimized wrapper
platformClient = (MatrixSDK.instance as OptimizedMatrixClient).client;
} else {
// The instance is already a platform-specific client
platformClient = MatrixSDK.instance as MatrixClient;
}
// Create new instance with appropriate wrapping
MatrixSDK.instance = enable
? new OptimizedMatrixClient(platformClient)
: platformClient;
}
}
/**
* Check if current client is optimized
* @returns true if using OptimizedMatrixClient
*/
private static isOptimized(): boolean {
return MatrixSDK.instance !== null &&
MatrixSDK.instance instanceof OptimizedMatrixClient;
}
/**
* Configure the optimization settings
* @param cacheConfig - Optional cache configuration
*/
static configureOptimizations(cacheConfig?: Record<string, number>): void {
// Pre-initialize the registry for faster startup
optimizationsRegistry.preInitialize();
// Initialize the optimizations registry with optional config
if (cacheConfig) {
// Create a new registry with custom configuration
const config: Record<string, number> = {};
// Convert config keys to match expected CacheConfig properties
Object.entries(cacheConfig).forEach(([key, value]) => {
// Convert camelCase or other formats to match expected config keys
switch (key.toLowerCase()) {
case 'messages':
case 'roommessages':
case 'room_messages':
config.roomMessages = value;
break;
case 'chats':
case 'rooms':
config.chats = value;
break;
case 'users':
case 'userdata':
case 'user_data':
config.userData = value;
break;
case 'media':
case 'files':
config.media = value;
break;
case 'thumbnails':
case 'thumbs':
case 'previews':
config.thumbnails = value;
break;
default:
Logger.warn(`[MatrixSDK] Unknown cache config key: ${key}`);
}
});
Logger.debug(`[MatrixSDK] Applied custom cache configuration`);
}
// Fully initialize the registry
optimizationsRegistry.initialize();
Logger.info('[MatrixSDK] Optimizations configured');
}
/**
* Get the Matrix client singleton instance
* @returns MatrixClient instance appropriate for the current platform
*/
static getClient(): MatrixClient {
if (!MatrixSDK.instance) {
Logger.info('[MatrixSDK] Creating new Matrix client instance');
// Initialize optimizations
optimizationsRegistry.initialize();
let platformClient: MatrixClient;
if (isIOS) {
Logger.info('[MatrixSDK] Creating iOS client');
platformClient = new MatrixIOSClient();
} else if (isAndroid) {
Logger.info('[MatrixSDK] Creating Android client');
platformClient = new MatrixAndroidClient();
} else {
throw new MatrixError(
'Unsupported platform. MatrixSDK requires iOS or Android.',
MatrixErrorType.INITIALIZATION
);
}
// Apply optimizations if enabled
MatrixSDK.instance = MatrixSDK.useOptimizations
? new OptimizedMatrixClient(platformClient)
: platformClient;
}
// We need to cast here because OptimizedMatrixClient doesn't strictly implement
// MatrixClient interface, but it does have all the required functionality through
// dynamic method forwarding
return MatrixSDK.instance as MatrixClient;
}
/**
* Reset the Matrix client instance
* Useful for logging out or switching accounts
*/
static resetClient(): void {
// Clean up any platform-specific resources
if (MatrixSDK.instance) {
// Cleanup based on client type
if (MatrixSDK.isOptimized()) {
// If optimized client, let it clean up resources
const optimizedClient = MatrixSDK.instance as OptimizedMatrixClient;
if (typeof optimizedClient.logout === 'function') {
// Call logout to perform cleanup but don't wait for result
// since we're already resetting
optimizedClient.logout().catch(e =>
Logger.error('[MatrixSDK] Error during logout cleanup:', e)
);
}
}
}
// Clean up all optimizations
optimizationsRegistry.cleanup();
MatrixSDK.instance = null;
Logger.info('[MatrixSDK] Matrix client instance reset');
}
}
// Export the SDK classes
export { MatrixError, MatrixErrorType, Logger, MatrixEventType, optimizers };