nativescript-matrix-sdk
Version:
Native Matrix SDK integration for NativeScript
291 lines (233 loc) • 8.32 kB
Markdown
# NativeScript Matrix SDK Documentation
## Table of Contents
1. [Architecture](#architecture)
2. [Core Components](#core-components)
3. [API Reference](#api-reference)
4. [Platform-Specific Implementation](#platform-specific-implementation)
5. [Performance Optimizations](#performance-optimizations)
6. [Security](#security)
7. [Error Handling](#error-handling)
8. [Best Practices](#best-practices)
## Architecture
The SDK is built with a layered architecture designed for performance and maintainability:
### Layer Structure
```
┌─────────────────────┐
│ Public API │ MatrixSDK, MatrixClient interfaces
├─────────────────────┤
│ Core Services │ Authentication, Messaging, Rooms
├─────────────────────┤
│ Optimizations │ Caching, Batching, Memory Management
├─────────────────────┤
│ Platform Adapters │ iOS/Android Native SDK Integration
└─────────────────────┘
```
### Key Components
- **MatrixSDK**: Main entry point and client factory
- **MatrixClient**: Core client interface
- **TransactionManager**: Message delivery and retry handling
- **OptimizationsRegistry**: Performance optimization management
- **Platform Implementations**: Native SDK wrappers
## Core Components
### MatrixClient
The main interface for Matrix operations:
```typescript
interface MatrixClient {
// Authentication
initialize(homeserverUrl: string, accessToken: string): Promise<void>;
login(homeserverUrl: string, username: string, password: string, deviceName?: string): Promise<{userId: string, accessToken: string}>;
loginWithSSO(homeserverUrl: string, callbackUrl: string): Promise<{userId: string, accessToken: string}>;
register(homeserverUrl: string, username: string, password: string, deviceName?: string): Promise<{userId: string, accessToken: string}>;
// Messaging
sendMessage(chatId: string, content: string): Promise<MatrixMessage>;
getMessages(chatId: string, options?: MessageOptions): Promise<MessageResult>;
addReaction(chatId: string, messageId: string, reaction: string): Promise<void>;
// File Operations
sendFile(chatId: string, localFilePath: string, options?: FileSendOptions): Promise<MatrixMessage>;
downloadFile(messageId: string, destinationPath: string, onProgress?: (progress: TransferProgress) => void): Promise<string>;
// Room Management
getChats(serverId?: string): Promise<MatrixChat[]>;
joinChat(chatId: string): Promise<void>;
leaveChat(chatId: string): Promise<void>;
// Encryption
enableEncryption(roomId: string): Promise<void>;
isEncryptionEnabled(roomId: string): Promise<boolean>;
getUserDevices(userId: string): Promise<DeviceKeyInfo[]>;
setDeviceVerification(userId: string, deviceId: string, status: DeviceVerificationStatus): Promise<void>;
// Events & Presence
startListening(): Promise<void>;
stopListening(): Promise<void>;
addEventListener(eventType: MatrixEventType, listener: MatrixEventListener): void;
removeEventListener(eventType: MatrixEventType, listener: MatrixEventListener): void;
// Transaction Management
sendMessageWithTransaction(roomId: string, content: string, contentType: string, options?: SendMessageOptions): Promise<string>;
retryTransaction(localId: string): Promise<boolean>;
cancelTransaction(localId: string): Promise<boolean>;
}
```
### TransactionManager
Handles message delivery with persistence and retry support:
```typescript
interface TransactionManager {
sendMessageWithTransaction(roomId: string, content: string, contentType: string, options?: SendMessageOptions): Promise<string>;
sendFileWithTransaction(roomId: string, filePath: string, caption: string, contentType: string, options?: SendMessageOptions): Promise<string>;
retryTransaction(localId: string): Promise<boolean>;
cancelTransaction(localId: string): Promise<boolean>;
getPendingTransactions(): Map<string, PendingTransaction>;
getPendingTransactionsForChat(chatId: string): Map<string, PendingTransaction>;
}
```
## Platform-Specific Implementation
### iOS Implementation
Uses the Matrix iOS SDK:
```typescript
class MatrixIOSClient implements MatrixClient {
private nativeClient: MXRestClient;
private rooms: Map<string, MXRoom>;
// Implementation details...
}
```
### Android Implementation
Uses the Matrix Android SDK:
```typescript
class MatrixAndroidClient implements MatrixClient {
private nativeClient: org.matrix.android.sdk.api.Matrix;
private rooms: Map<string, org.matrix.android.sdk.api.session.room.Room>;
// Implementation details...
}
```
## Performance Optimizations
### Caching
```typescript
const cache = new MatrixLRUCache<MessageResult>(20);
cache.set(roomId, messages);
const cachedMessages = cache.get(roomId);
```
### Batch Operations
```typescript
const batchHandler = new BatchOperationHandler();
await batchHandler.addToBatch('sendMessages', message, async (messages) => {
// Process batch of messages
});
```
### Memory Management
```typescript
const memoryOptimizer = new MatrixMemoryOptimizer();
memoryOptimizer.registerCache('messages', messageCache, 5);
if (memoryOptimizer.isMemoryLow()) {
// Handle low memory condition
}
```
## Security
### End-to-End Encryption
```typescript
// Enable encryption
await client.enableEncryption(roomId);
// Verify devices
const devices = await client.getUserDevices(userId);
await client.setDeviceVerification(userId, deviceId, DeviceVerificationStatus.VERIFIED);
// Backup keys
const recoveryKey = await client.createKeyBackup();
await client.restoreKeyBackup(recoveryKey);
```
### Best Practices
1. **API Keys & Secrets**
- Use 128-byte environment secrets
- Never hardcode credentials
- Implement secure storage
2. **Error Handling**
- Always catch and handle errors
- Use MatrixError types
- Implement proper retry logic
3. **Memory Management**
- Monitor memory usage
- Implement cleanup handlers
- Use appropriate cache sizes
## Error Handling
### Error Types
```typescript
enum MatrixErrorType {
INITIALIZATION = 'initialization',
AUTHENTICATION = 'authentication',
NETWORK = 'network',
SYNC = 'sync',
ROOM = 'room',
EVENT = 'event',
ENCRYPTION = 'encryption',
USER = 'user',
PERMISSION = 'permission',
UNKNOWN = 'unknown'
}
```
### Error Handling Example
```typescript
try {
await client.sendMessage(roomId, content);
} catch (error) {
if (error instanceof MatrixError) {
switch (error.type) {
case MatrixErrorType.NETWORK:
// Handle network error
break;
case MatrixErrorType.ENCRYPTION:
// Handle encryption error
break;
// ... handle other cases
}
}
}
```
## Best Practices
1. **Initialization**
```typescript
// Initialize early
await client.initialize(homeserverUrl, accessToken);
// Start listening for events
await client.startListening();
```
2. **Memory Management**
```typescript
// Register cleanup handlers
Application.on(Application.exitEvent, () => {
client.cleanup();
});
```
3. **Error Handling**
```typescript
// Implement proper error handling
try {
await client.sendMessage(roomId, content);
} catch (error) {
if (error instanceof MatrixError) {
// Handle specific error types
}
}
```
4. **Event Handling**
```typescript
// Use event buffering for better performance
client.addEventListener(MatrixEventType.MESSAGE_RECEIVED, (event) => {
eventOptimizer.bufferEvent('message', event, (events) => {
// Process batch of events
});
});
```
5. **Transaction Management**
```typescript
// Use transaction support for important operations
const localId = await client.sendMessageWithTransaction(
roomId,
content,
'text',
{
retryOptions: {
maxRetries: 3,
baseDelay: 1000
}
}
);
```
For more detailed information about specific topics, please refer to:
- [Performance Optimizations](OPTIMIZATIONS.md)
- [Security Guide](SECURITY.md)
- [Contributing Guidelines](CONTRIBUTING.md)