| 251 | // ============================================================================ |
| 252 | |
| 253 | export async function screenshotSpace(engine: VisualNovelEngine): Promise<Space | null> { |
| 254 | // If we already know IndexedDB isn't available, skip |
| 255 | if (engine._indexedDBAvailable === false) { |
| 256 | return null; |
| 257 | } |
| 258 | |
| 259 | if (!engine._screenshotSpace) { |
| 260 | try { |
| 261 | // We use a dedicated IndexedDB Space for screenshots (blobs), so they don't interfere with the main save data. |
| 262 | engine._screenshotSpace = new Space(SpaceAdapter.IndexedDB, { |
| 263 | name: `${Text.friendly(engine.setting('Name') as string)}_Screenshots`, |
| 264 | version: '1', |
| 265 | store: 'screenshots' |
| 266 | } as ConstructorParameters<typeof Space>[1]); |
| 267 | |
| 268 | await engine._screenshotSpace.open(); |
| 269 | engine._indexedDBAvailable = true; |
| 270 | } catch (error) { |
| 271 | console.warn('IndexedDB not available for save screenshots. Save thumbnails will fall back to the scene image:', error); |
| 272 | engine._indexedDBAvailable = false; |
| 273 | return null; |
| 274 | } |
| 275 | } |
| 276 | |
| 277 | return engine._screenshotSpace; |
| 278 | } |
| 279 | |
| 280 | export async function storeAudioBufferPersistent(engine: VisualNovelEngine, key: string, buffer: AudioBuffer): Promise<void> { |
| 281 | const space = await audioBufferSpace(engine); |