File size: 6,181 Bytes
502af73
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
/**
 * Frontend Storage Utility
 *
 * Provides a centralized API for storing and retrieving data in browser storage.
 * Supports both sessionStorage and localStorage with type-safe operations.
 *
 * Features:
 * - Type-safe storage operations
 * - Automatic JSON serialization/deserialization
 * - Error handling with fallback values
 * - Namespaced keys to avoid collisions
 * - Support for both session and local storage
 */


/**
 * Storage type enum
 */
export enum StorageType {
	SESSION = "session",
	LOCAL = "local"
}


/**
 * Storage keys enum - Add new keys here
 */
export enum StorageKey {
	// Game state
	GAME_STATE = "trigoGameState",

	// AI settings
	AI_PLAYER_COLOR = "trigoAIPlayerColor",

	// User preferences (examples for future use)
	// THEME = "trigoTheme",
	// LANGUAGE = "trigoLanguage",
	// BOARD_SHAPE = "trigoBoardShape",
	// CAMERA_POSITION = "trigoCameraPosition",
}


/**
 * Storage configuration
 */
interface StorageConfig {
	type: StorageType;
	prefix?: string; // Optional namespace prefix for all keys
}


/**
 * Default configuration
 */
const DEFAULT_CONFIG: StorageConfig = {
	type: StorageType.SESSION,
	prefix: "" // No prefix by default, keys already have 'trigo' prefix
};


/**
 * Get the appropriate storage instance
 */
function getStorage(type: StorageType): Storage {
	return type === StorageType.SESSION ? sessionStorage : localStorage;
}


/**
 * Build full storage key with optional prefix
 */
function buildKey(key: StorageKey, prefix?: string): string {
	return prefix ? `${prefix}${key}` : key;
}


/**
 * Storage Manager Class
 */
export class StorageManager {
	private config: StorageConfig;

	constructor(config: Partial<StorageConfig> = {}) {
		this.config = { ...DEFAULT_CONFIG, ...config };
	}

	/**
	 * Get storage instance based on configuration
	 */
	private getStorageInstance(): Storage {
		return getStorage(this.config.type);
	}

	/**
	 * Set a value in storage
	 * @param key - Storage key
	 * @param value - Value to store (will be JSON stringified)
	 * @returns true if successful, false otherwise
	 */
	set<T>(key: StorageKey, value: T): boolean {
		try {
			const storage = this.getStorageInstance();
			const fullKey = buildKey(key, this.config.prefix);
			const serialized = JSON.stringify(value);
			storage.setItem(fullKey, serialized);
			return true;
		} catch (error) {
			console.warn(`[Storage] Failed to set ${key}:`, error);
			return false;
		}
	}

	/**
	 * Get a value from storage
	 * @param key - Storage key
	 * @param defaultValue - Default value if key doesn't exist or parsing fails
	 * @returns Stored value or default value
	 */
	get<T>(key: StorageKey, defaultValue: T): T {
		try {
			const storage = this.getStorageInstance();
			const fullKey = buildKey(key, this.config.prefix);
			const item = storage.getItem(fullKey);

			if (item === null) {
				return defaultValue;
			}

			return JSON.parse(item) as T;
		} catch (error) {
			console.warn(`[Storage] Failed to get ${key}:`, error);
			return defaultValue;
		}
	}

	/**
	 * Get a string value directly (no JSON parsing)
	 * Useful for simple string values
	 */
	getString(key: StorageKey, defaultValue: string = ""): string {
		try {
			const storage = this.getStorageInstance();
			const fullKey = buildKey(key, this.config.prefix);
			return storage.getItem(fullKey) ?? defaultValue;
		} catch (error) {
			console.warn(`[Storage] Failed to get string ${key}:`, error);
			return defaultValue;
		}
	}

	/**
	 * Set a string value directly (no JSON stringification)
	 * Useful for simple string values
	 */
	setString(key: StorageKey, value: string): boolean {
		try {
			const storage = this.getStorageInstance();
			const fullKey = buildKey(key, this.config.prefix);
			storage.setItem(fullKey, value);
			return true;
		} catch (error) {
			console.warn(`[Storage] Failed to set string ${key}:`, error);
			return false;
		}
	}

	/**
	 * Remove a value from storage
	 * @param key - Storage key
	 * @returns true if successful, false otherwise
	 */
	remove(key: StorageKey): boolean {
		try {
			const storage = this.getStorageInstance();
			const fullKey = buildKey(key, this.config.prefix);
			storage.removeItem(fullKey);
			return true;
		} catch (error) {
			console.warn(`[Storage] Failed to remove ${key}:`, error);
			return false;
		}
	}

	/**
	 * Check if a key exists in storage
	 */
	has(key: StorageKey): boolean {
		try {
			const storage = this.getStorageInstance();
			const fullKey = buildKey(key, this.config.prefix);
			return storage.getItem(fullKey) !== null;
		} catch (error) {
			console.warn(`[Storage] Failed to check ${key}:`, error);
			return false;
		}
	}

	/**
	 * Clear all items from storage
	 * WARNING: This clears ALL items in the storage, not just trigo-related ones
	 */
	clear(): boolean {
		try {
			const storage = this.getStorageInstance();
			storage.clear();
			return true;
		} catch (error) {
			console.warn("[Storage] Failed to clear storage:", error);
			return false;
		}
	}

	/**
	 * Get the current storage type
	 */
	getStorageType(): StorageType {
		return this.config.type;
	}

	/**
	 * Switch storage type
	 */
	setStorageType(type: StorageType): void {
		this.config.type = type;
	}
}


/**
 * Default storage manager instance (sessionStorage)
 */
export const storage = new StorageManager();


/**
 * Local storage manager instance
 * Note: Named localStorageManager to avoid conflict with built-in localStorage
 */
export const localStorageManager = new StorageManager({ type: StorageType.LOCAL });


/**
 * Example helper functions for future use:
 *
 * export function saveTheme(theme: "light" | "dark"): boolean {
 * 	return localStorageManager.setString(StorageKey.THEME, theme);
 * }
 *
 * export function loadTheme(): "light" | "dark" {
 * 	const stored = localStorageManager.getString(StorageKey.THEME);
 * 	return stored === "dark" ? "dark" : "light";
 * }
 *
 * export function saveBoardShape(shape: { x: number; y: number; z: number }): boolean {
 * 	return storage.set(StorageKey.BOARD_SHAPE, shape);
 * }
 *
 * export function loadBoardShape(): { x: number; y: number; z: number } | null {
 * 	return storage.get(StorageKey.BOARD_SHAPE, null);
 * }
 */