Custom storage driver (StorageDriver)
Overview
A storage driver (StorageDriver) is an interface dedicated to storing and managing data. It is responsible for:
- Storing and reading data
- Deleting data
- Partitioning data
- Monitoring data changes
For detailed storage API information, see the developer reference for storage.
Core type definitions
StorageContext base class
typescript
class StorageContext {
public id: string;
public feature: string;
}The StorageContext class identifies stored data and its feature.
PDFViewer-related interfaces
typescript
interface PDFViewer {
getInstanceId(): string;
}
interface PDFViewerConstructor {
new(options: {
instanceId: string,
customs: {
storageDriver: StorageDriver;
}
}): PDFViewer;
}Instance ID
The getInstanceId() method returns a unique identifier for the PDFViewer instance. When multiple instances exist, ensure each instance has a unique ID.
StorageDriver interface
typescript
interface StorageDriver {
getAll(context: StorageContext): Promise<Record<string, any>>;
get<T>(context: StorageContext, key: string): Promise<T | null>;
set<T>(context: StorageContext, key: string, value: T): Promise<void>;
removeAll(context: StorageContext): Promise<void>;
remove(context: StorageContext, key: string): Promise<void>;
onChange<T>(callback: (event: StorageDriverChangeEvent<T>) => void): Function;
onRemove(callback: (event: StorageDriverRemoveEvent) => void): Function;
}Core methods:
getAll: Get all data for the given contextget: Get data for a keyset: Set data for a keyremoveAll: Remove all dataremove: Remove data for a keyonChange: Register a data change listeneronRemove: Register a data removal listener
Event interfaces
typescript
interface StorageDriverChangeEvent<T> {
context: StorageContext;
key: string;
oldValue: T;
newValue: T;
}
interface StorageDriverRemoveEvent {
context: StorageContext;
key: string;
}Implement a custom storage driver
Below is an example based on sessionStorage:
typescript
class MyStorageDriver extends StorageDriver {
private readonly eventEmitter = new EventEmitter();
/ 生成存储空间名称
private getSpace(context: StorageContext): string {
return [context.id, context.feature].join('.');
}
/ ... existing code ...
/ 核心存储方法实现
async set<T>(context: StorageContext, key: string, value: T): Promise<void> {
const storageKey = this.generateUniqueKey(context, key);
const oldValueJSON = sessionStorage.getItem(storageKey);
const oldValue = oldValueJSON ? JSON.parse(oldValueJSON) : undefined;
const newValue = JSON.stringify(value);
if (oldValueJSON === newValue) return;
sessionStorage.setItem(storageKey, newValue);
this.emitChangeEvent({
context,
key,
oldValue,
newValue: value
});
}
/ ... existing code ...
}Full implementation
See the MyStorageDriver class implementation above for a complete example. It demonstrates how to:
- Use EventEmitter for events
- Partition stored data
- Emit data change notifications
Use a custom storage driver
When creating a PDFViewer instance, pass your custom StorageDriver through the customs option:
typescript
const storageDriver = new MyStorageDriver();
const pdfViewer = new PDFViewer({
instanceId: 'pdf-viewer-1',
customs: {
storageDriver: storageDriver
}
});Best practices
- Assign a unique
instanceIdto each PDFViewer instance - Choose a storage backend that fits your needs (localStorage, IndexedDB, etc.)
- Partition data so instances do not share or overwrite each other's state