Properly test for IndexedDB availability

This commit is contained in:
Simon Binder 2023-06-01 13:59:35 +02:00
parent ec5927bc2a
commit 0a052ff338
No known key found for this signature in database
GPG Key ID: 7891917E4147B8C0
3 changed files with 25 additions and 21 deletions

View File

@ -1,11 +1,11 @@
import 'dart:html'; import 'dart:html';
import 'dart:indexed_db'; import 'dart:indexed_db';
import 'dart:js';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
import 'binary_string_conversion.dart'; import 'binary_string_conversion.dart';
import 'wasm_setup/shared.dart';
/// Interface to control how drift should store data on the web. /// Interface to control how drift should store data on the web.
abstract class DriftWebStorage { abstract class DriftWebStorage {
@ -70,25 +70,7 @@ abstract class DriftWebStorage {
/// Attempts to check whether the current browser supports the /// Attempts to check whether the current browser supports the
/// [DriftWebStorage.indexedDb] storage implementation. /// [DriftWebStorage.indexedDb] storage implementation.
static Future<bool> supportsIndexedDb({bool inWebWorker = false}) async { static Future<bool> supportsIndexedDb({bool inWebWorker = false}) async {
var isIndexedDbSupported = false; return checkIndexedDbSupport();
if (inWebWorker && WorkerGlobalScope.instance.indexedDB != null) {
isIndexedDbSupported = true;
} else {
try {
isIndexedDbSupported = IdbFactory.supported;
if (isIndexedDbSupported) {
// Try opening a mock database to check if IndexedDB is really
// available. This avoids the problem with Firefox incorrectly
// reporting IndexedDB as supported in private mode.
final mockDb = await window.indexedDB!.open('drift_mock_db');
mockDb.close();
}
} catch (error) {
isIndexedDbSupported = false;
}
}
return isIndexedDbSupported && context.hasProperty('FileReader');
} }
} }

View File

@ -67,7 +67,8 @@ Future<WasmDatabaseResult> openWasmDatabase({
await sharedMessages.nextNoError as SharedWorkerStatus; await sharedMessages.nextNoError as SharedWorkerStatus;
missingFeatures.addAll(sharedFeatures.missingFeatures); missingFeatures.addAll(sharedFeatures.missingFeatures);
// Can we use the shared OPFS implementation? // Prefer to use the shared worker to host the database if it supports the
// necessary APIs.
if (sharedFeatures.canSpawnDedicatedWorkers && if (sharedFeatures.canSpawnDedicatedWorkers &&
sharedFeatures.dedicatedWorkersCanUseOpfs) { sharedFeatures.dedicatedWorkersCanUseOpfs) {
return connect( return connect(

View File

@ -1,4 +1,5 @@
import 'dart:html'; import 'dart:html';
import 'dart:indexed_db';
import 'package:drift/drift.dart'; import 'package:drift/drift.dart';
import 'package:drift/remote.dart'; import 'package:drift/remote.dart';
@ -54,7 +55,27 @@ Future<bool> checkOpfsSupport() async {
} }
} }
/// Checks whether IndexedDB is working in the current browser by opening a test
/// database.
Future<bool> checkIndexedDbSupport() async { Future<bool> checkIndexedDbSupport() async {
if (!hasProperty(globalThis, 'indexedDB') ||
// FileReader needed to read and write blobs efficiently
!hasProperty(globalThis, 'FileReader')) {
return false;
}
final idb = getProperty<IdbFactory>(globalThis, 'indexedDB');
try {
const name = 'drift_mock_db';
final mockDb = await idb.open(name);
mockDb.close();
idb.deleteDatabase(name);
} catch (error) {
return false;
}
return true; return true;
} }