open static method

Future<WasmDatabaseResult> open({
  1. required String databaseName,
  2. required Uri sqlite3Uri,
  3. required Uri driftWorkerUri,
  4. FutureOr<Uint8List?> initializeDatabase()?,
  5. WasmDatabaseSetup? localSetup,
})

Opens a database on the web.

Drift will detect features supported by the current browser and picks an appropriate implementation to store data based on those results.

Using this API requires two additional file that you need to copy into the web/ folder of your Flutter or Dart application: A sqlite3.wasm file, which you can get here, and a drift worker, which you can get here.

localSetup will be called to initialize the database only if the database will be opened directly in this JavaScript context. It is likely that the database will actually be opened in a web worker, with drift using communication mechanisms to access the database. As there is no way to send the database over to the main context, localSetup would not be called in that case. Instead, you'd have to compile a custom drift worker with a setup function - see workerMainForOpen for additional information.

For more detailed information, see https://drift.simonbinder.eu/web.

Implementation

static Future<WasmDatabaseResult> open({
  required String databaseName,
  required Uri sqlite3Uri,
  required Uri driftWorkerUri,
  FutureOr<Uint8List?> Function()? initializeDatabase,
  WasmDatabaseSetup? localSetup,
}) async {
  final probed = await probe(
    sqlite3Uri: sqlite3Uri,
    driftWorkerUri: driftWorkerUri,
    databaseName: databaseName,
  );

  // If we have an existing database in storage, we want to keep using that
  // format to avoid data loss (e.g. after a browser update that enables a
  // otherwise preferred storage implementation). In the future, we might want
  // to consider migrating between storage implementations as well.
  final availableImplementations = probed.availableStorages.toList();

  checkExisting:
  for (final (location, name) in probed.existingDatabases) {
    if (name == databaseName) {
      final implementationsForStorage = switch (location) {
        WebStorageApi.indexedDb => const [
            WasmStorageImplementation.sharedIndexedDb,
            WasmStorageImplementation.unsafeIndexedDb
          ],
        WebStorageApi.opfs => const [
            WasmStorageImplementation.opfsShared,
            WasmStorageImplementation.opfsLocks,
          ],
      };

      // If any of the implementations for this location is still availalable,
      // we want to use it instead of another location.
      if (implementationsForStorage.any(availableImplementations.contains)) {
        availableImplementations
            .removeWhere((i) => !implementationsForStorage.contains(i));
        break checkExisting;
      }
    }
  }

  // Enum values are ordered by preferrability, so just pick the best option
  // left.
  availableImplementations.sortBy<num>((element) => element.index);

  final bestImplementation = availableImplementations.firstOrNull ??
      WasmStorageImplementation.inMemory;
  final connection = await probed.open(bestImplementation, databaseName,
      localSetup: localSetup, initializeDatabase: initializeDatabase);

  return WasmDatabaseResult(
      connection, bestImplementation, probed.missingFeatures);
}