UNPKG

@aituber-onair/kizuna

Version:

A sophisticated bond system (絆 - Kizuna) for managing relationships between users and AI characters in AITuber OnAir.

139 lines 4.26 kB
/** * StorageProvider - Abstract class for storage providers * * Provides a unified interface for different storage systems * (LocalStorage, IndexedDB, external APIs, etc.) */ /** * Abstract base class for storage providers */ export class StorageProvider { // ============================================================================ // Common utility methods // ============================================================================ /** * Serialize data */ serialize(data) { try { return JSON.stringify(data, this.replacer); } catch (error) { throw new Error(`Failed to serialize data: ${error}`); } } /** * Deserialize data */ deserialize(data) { try { return JSON.parse(data, this.reviver); } catch (error) { throw new Error(`Failed to deserialize data: ${error}`); } } /** * Validate data */ validateKey(key) { if (!key || typeof key !== "string" || key.trim().length === 0) { throw new Error("Invalid key: key must be a non-empty string"); } if (key.length > 256) { throw new Error("Invalid key: key must be less than 256 characters"); } } /** * Get data size (in bytes) */ getDataSize(data) { return new Blob([data]).size; } /** * Generate safe key name */ sanitizeKey(key) { return key.replace(/[^a-zA-Z0-9_\-:.]/g, "_"); } // ============================================================================ // JSON serialization helpers // ============================================================================ /** * Replacer function for JSON.stringify * Properly serializes special objects like Date and Map */ replacer(key, value) { // Process Date objects if (value instanceof Date) { return { __type: "Date", value: value.toISOString(), }; } // Process Map objects if (value instanceof Map) { return { __type: "Map", value: Array.from(value.entries()), }; } // Process Set objects if (value instanceof Set) { return { __type: "Set", value: Array.from(value), }; } return value; } /** * Reviver function for JSON.parse * Restores serialized special objects */ reviver(key, value) { if (typeof value === "object" && value !== null && "__type" in value) { const typedValue = value; switch (typedValue.__type) { case "Date": return new Date(typedValue.value); case "Map": return new Map(typedValue.value); case "Set": return new Set(typedValue.value); } } return value; } } /** * Storage error class */ export class StorageError extends Error { constructor(message, code, originalError) { super(message); this.code = code; this.originalError = originalError; this.name = "StorageError"; } } /** * Storage error codes */ export var StorageErrorCode; (function (StorageErrorCode) { StorageErrorCode["NOT_AVAILABLE"] = "NOT_AVAILABLE"; StorageErrorCode["QUOTA_EXCEEDED"] = "QUOTA_EXCEEDED"; StorageErrorCode["PERMISSION_DENIED"] = "PERMISSION_DENIED"; StorageErrorCode["NETWORK_ERROR"] = "NETWORK_ERROR"; StorageErrorCode["INVALID_KEY"] = "INVALID_KEY"; StorageErrorCode["INVALID_DATA"] = "INVALID_DATA"; StorageErrorCode["SERIALIZATION_ERROR"] = "SERIALIZATION_ERROR"; StorageErrorCode["UNKNOWN_ERROR"] = "UNKNOWN_ERROR"; StorageErrorCode["SAVE_ERROR"] = "SAVE_ERROR"; StorageErrorCode["LOAD_ERROR"] = "LOAD_ERROR"; StorageErrorCode["REMOVE_ERROR"] = "REMOVE_ERROR"; StorageErrorCode["CLEAR_ERROR"] = "CLEAR_ERROR"; StorageErrorCode["INFO_ERROR"] = "INFO_ERROR"; })(StorageErrorCode || (StorageErrorCode = {})); //# sourceMappingURL=StorageProvider.js.map