Interfaces & Types
TypeScript interface definitions and type declarations
TypeScript Interfaces & Types
Complete reference for all TypeScript interfaces, types, and data structures defined in src/types.ts.
Constants
export const MAX_TIMESTAMP = 86400 * 365; // Max reasonable timestamp: 365 days in seconds
export function errorMessage(e: unknown): string {
return e instanceof Error ? e.message : String(e);
}Literal Union Types
export type UISource = 'sidebar' | 'overlay' | 'window';
export type CloudProviderId = 'gdrive' | 'dropbox';
export type CloudSyncAction = 'upload' | 'download' | 'sync';
export type ExportFormat = 'json' | 'csv';
export type ReconciliationAction = 'update_path' | 'remove_bookmark' | 'search_similar';
export type DuplicateHandling = 'skip' | 'replace' | 'merge';Core Data Interfaces
BookmarkData
The primary data structure representing a single bookmark.
interface BookmarkData {
id: string;
title: string;
timestamp: number;
filepath: string;
description?: string;
createdAt: string; // ISO 8601 timestamp
updatedAt: string; // ISO 8601 timestamp
tags: string[];
}Field Details:
id- Unique identifier generated byDate.now().toString(36) + '-' + counter.toString(36) + '-' + Math.random().toString(36).substring(2)title- Display title (user-provided or auto-generated from filename)timestamp- Playback position in secondsfilepath- Absolute path to media filedescription- Optional user descriptioncreatedAt- ISO 8601 creation timestampupdatedAt- ISO 8601 last modification timestamptags- Array of tag strings
BookmarkUpdatableFields
Fields that can be updated after bookmark creation.
interface BookmarkUpdatableFields {
title?: string;
description?: string;
tags?: string[];
}Note: id, filepath, and createdAt are immutable.
BookmarkDefaults
Auto-populated defaults for new bookmark creation.
interface BookmarkDefaults {
title: string;
description: string;
tags: string[];
timestamp: number;
filepath: string;
}ImportOptions
Configuration for bookmark import operations.
interface ImportOptions {
duplicateHandling?: DuplicateHandling; // 'skip' | 'replace' | 'merge'
preserveIds?: boolean;
}Duplicate Handling:
skip- Skip duplicate bookmarks (default)replace- Replace existing bookmarks with same IDmerge- Merge tags from duplicate bookmarks
Preserve IDs:
true- Keep original bookmark IDs from importfalse- Generate new IDs (default)
ImportResult
Result data from import operations.
interface ImportResult {
success: boolean;
importedCount: number;
skippedCount: number;
errorCount: number;
errors?: string[];
duplicates?: number;
}SortPreferences
User preferences for bookmark sorting.
interface SortPreferences {
sortBy: string;
sortDirection: 'asc' | 'desc';
}CloudCredentials
Authentication credentials for cloud storage providers.
interface CloudCredentials {
apiKey?: string;
accessToken?: string;
clientId?: string;
clientSecret?: string;
refreshToken?: string;
}SyncStats
Statistics from cloud sync operations.
interface SyncStats {
added: number;
updated: number;
conflicts: number;
total: number;
}BackupMetadata
Metadata attached to cloud backups.
interface BackupMetadata {
version: string;
createdAt: string;
totalBookmarks: number;
device: string;
userAgent: string;
}UIMessage
Base message interface for UI communication.
interface UIMessage {
type: string;
payload?: Record<string, unknown>;
sourceUI?: UISource;
}UIToBackendPayloadMap
Payload map for messages sent from UI to Backend.
interface UIToBackendPayloadMap {
UI_READY: { uiType: UISource };
REQUEST_FILE_PATH: undefined;
ADD_BOOKMARK: { title?: string; timestamp?: number; description?: string; tags?: string[] };
DELETE_BOOKMARK: { id: string };
JUMP_TO_BOOKMARK: { id: string };
UPDATE_BOOKMARK: { id: string; data: BookmarkUpdatableFields };
HIDE_OVERLAY: undefined;
IMPORT_BOOKMARKS: { bookmarks: unknown[]; options?: ImportOptions };
EXPORT_BOOKMARKS: { format?: ExportFormat };
CLOUD_SYNC_REQUEST: { action: CloudSyncAction; provider: CloudProviderId; credentials: CloudCredentials };
FILE_RECONCILIATION_REQUEST: { action: ReconciliationAction; bookmarkId: string; newPath?: string; originalPath?: string };
RECONCILE_FILES: undefined;
REQUEST_BOOKMARK_DEFAULTS: undefined;
SAVE_SORT_PREFERENCES: { preferences: SortPreferences };
}BackendToUIPayloadMap
Payload map for messages sent from Backend to UI.
interface BackendToUIPayloadMap {
BOOKMARKS_UPDATED: BookmarkData[];
CURRENT_FILE_PATH: string;
BOOKMARK_ADDED: Record<string, never>;
BOOKMARK_DELETED: Record<string, never>;
BOOKMARK_JUMPED: Record<string, never>;
BOOKMARK_DEFAULTS: BookmarkDefaults;
SORT_PREFERENCES: SortPreferences;
IMPORT_RESULT: ImportResult;
IMPORT_STARTED: undefined;
EXPORT_RESULT: { format: ExportFormat; content: string };
CLOUD_SYNC_RESULT: {
success: boolean;
action: CloudSyncAction;
message?: string;
error?: string;
bookmarks?: BookmarkData[];
backupId?: string;
metadata?: BackupMetadata;
syncStats?: SyncStats;
};
SHOW_CLOUD_SYNC_DIALOG: undefined;
SHOW_FILE_RECONCILIATION_DIALOG: { movedFiles: BookmarkData[] };
FILE_RECONCILIATION_RESULT: {
success: boolean;
action: ReconciliationAction;
bookmarkId: string;
oldPath?: string;
newPath?: string;
originalPath?: string;
similarFiles?: string[];
message?: string;
};
ERROR: { message: string };
}IINA Plugin API Interfaces
IINACore
Core IINA player interface.
interface IINACore {
status: {
path?: string;
currentTime?: number;
metadata?: {
title?: string;
};
};
seek?: (time: number, exact?: boolean) => void;
seekTo?: (seconds: number) => void;
osd?: (message: string) => void;
}IINAConsole
Logging interface.
interface IINAConsole {
log: (message: string) => void;
error: (message: string) => void;
warn: (message: string) => void;
}IINAPreferences
Key-value storage interface.
interface IINAPreferences {
get: (key: string) => string | null;
set: (key: string, value: string) => void;
}IINAMenu
Menu integration interface.
interface IINAMenu {
addItem: (item: any) => void;
item: (title: string, action: () => void) => any;
}IINAEvent
Event system interface.
interface IINAEvent {
on: (event: string, callback: (...args: any[]) => void) => string;
off: (event: string, id: string) => void;
}Note: on() returns a unique ID string for use with off().
IINAUtils
Utility methods.
interface IINAUtils {
ask: (question: string) => boolean;
prompt: (question: string) => string | null;
chooseFile: (title: string, options?: any) => string | null;
}IINAFile
File system interface.
interface IINAFile {
read: (path: string) => string;
write: (path: string, content: string) => void;
exists: (path: string) => boolean;
}IINAUIAPI
Base UI interface for sidebar, overlay, and window.
interface IINAUIAPI {
loadFile: (path: string) => void;
postMessage: (name: string, data?: any) => void;
onMessage: (name: string, callback: (data: any) => void) => void;
}IINASidebar
Sidebar UI interface (extends IINAUIAPI).
type IINASidebar = IINAUIAPI;IINAOverlay
Overlay UI interface with additional controls.
interface IINAOverlay extends IINAUIAPI {
setClickable: (clickable: boolean) => void;
show: () => void;
hide: () => void;
isVisible: () => boolean;
}IINAStandaloneWindow
Standalone window UI interface.
interface IINAStandaloneWindow extends IINAUIAPI {
show: () => void;
}HttpAdapter
HTTP adapter interface that abstracts iina.http for cloud storage.
interface HttpAdapter {
get(
url: string,
options?: { headers?: Record<string, string>; params?: Record<string, string> }
): Promise<{ text: string; statusCode: number }>;
post(
url: string,
options?: {
headers?: Record<string, string>;
data?: any;
params?: Record<string, string>;
}
): Promise<{ text: string; statusCode: number }>;
put(
url: string,
options?: {
headers?: Record<string, string>;
data?: any;
params?: Record<string, string>;
}
): Promise<{ text: string; statusCode: number }>;
patch(
url: string,
options?: {
headers?: Record<string, string>;
data?: any;
params?: Record<string, string>;
}
): Promise<{ text: string; statusCode: number }>;
delete(
url: string,
options?: { headers?: Record<string, string>; params?: Record<string, string> }
): Promise<{ text: string; statusCode: number }>;
}The HttpAdapter mirrors the IINA HTTP module's API shape. The plugin entry point (src/index.ts) builds an HttpAdapter from iina.http.
Runtime Dependencies
IINARuntimeDependencies
Complete dependency injection interface for BookmarkManager.
interface IINARuntimeDependencies {
console: IINAConsole;
core: IINACore;
preferences: IINAPreferences;
menu: IINAMenu;
event: IINAEvent;
sidebar: IINASidebar;
overlay: IINAOverlay;
standaloneWindow: IINAStandaloneWindow;
utils: IINAUtils;
file: IINAFile;
http: HttpAdapter;
}This interface is passed to the BookmarkManager constructor and enables dependency injection for testing and modularity.
Type Safety Notes
All user inputs are sanitized using stripHtmlTags() from src/utils/validation.ts to prevent XSS attacks. This is critical for title, description, and tags fields.
Timestamps are validated to be within 0 and MAX_TIMESTAMP (365 days in seconds). This prevents overflow and ensures reasonable values.
The errorMessage() utility function safely extracts error messages from unknown thrown values, handling both Error objects and primitive values.
Usage Examples
Type-Safe Bookmark Creation
import type { BookmarkData, BookmarkUpdatableFields } from './types';
// Create a new bookmark with type safety
const bookmark: BookmarkData = {
id: generateId(),
title: 'Epic Scene',
timestamp: 1234.5,
filepath: '/Movies/Example.mp4',
description: 'Amazing moment',
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
tags: ['action', 'favorite']
};
// Update with partial type
const updates: BookmarkUpdatableFields = {
title: 'Updated Title',
tags: ['updated']
};Type-Safe Import
import type { ImportOptions, ImportResult } from './types';
const options: ImportOptions = {
duplicateHandling: 'merge',
preserveIds: false
};
const result: ImportResult = await importBookmarks(data, options);
console.log(`Imported: ${result.importedCount}, Skipped: ${result.skippedCount}`);Type-Safe Cloud Sync
import type { CloudCredentials, CloudSyncAction } from './types';
const credentials: CloudCredentials = {
accessToken: 'your-token',
refreshToken: 'your-refresh-token'
};
const action: CloudSyncAction = 'sync';
await cloudSync(action, 'gdrive', credentials);