From b1fb227b4cfc3cc74d59a2960383a4cb8416ecaf Mon Sep 17 00:00:00 2001 From: Strycher Date: Tue, 21 Jul 2026 04:18:26 -0400 Subject: [PATCH] fix(#363): keep sqlite3 (dart:ffi) out of the web build The VACUUM INTO snapshot import pulled dart:ffi via package:sqlite3, which does not compile on web. Isolate it behind a conditional import (native impl + web stub); the migration is native-only and never runs on web. Co-Authored-By: Claude Opus 4.8 --- lib/storage/drift/db_snapshot_io.dart | 13 +++++++++++++ lib/storage/drift/db_snapshot_web.dart | 6 ++++++ lib/storage/drift/offband_database.dart | 11 ++++------- 3 files changed, 23 insertions(+), 7 deletions(-) create mode 100644 lib/storage/drift/db_snapshot_io.dart create mode 100644 lib/storage/drift/db_snapshot_web.dart diff --git a/lib/storage/drift/db_snapshot_io.dart b/lib/storage/drift/db_snapshot_io.dart new file mode 100644 index 0000000..93123e7 --- /dev/null +++ b/lib/storage/drift/db_snapshot_io.dart @@ -0,0 +1,13 @@ +import 'package:sqlite3/sqlite3.dart'; + +/// Snapshots [source] to [target] with SQLite `VACUUM INTO` (a consistent, +/// transaction-based copy). Native only; isolated in its own file so the +/// `dart:ffi`-backed sqlite3 import never reaches the web build (#363). +void vacuumInto(String source, String target) { + final db = sqlite3.open(source, mode: OpenMode.readOnly); + try { + db.execute("VACUUM INTO '${target.replaceAll("'", "''")}'"); + } finally { + db.close(); + } +} diff --git a/lib/storage/drift/db_snapshot_web.dart b/lib/storage/drift/db_snapshot_web.dart new file mode 100644 index 0000000..2d2c6bf --- /dev/null +++ b/lib/storage/drift/db_snapshot_web.dart @@ -0,0 +1,6 @@ +/// Web stub for [vacuumInto]. The pinned-directory migration is native-only +/// (web uses drift's OPFS/IndexedDB backend and never calls this), so this +/// exists only to keep the conditional import from pulling `dart:ffi` into the +/// web build (#363). +void vacuumInto(String source, String target) => + throw UnsupportedError('vacuumInto is native-only'); diff --git a/lib/storage/drift/offband_database.dart b/lib/storage/drift/offband_database.dart index b35b2d1..42ede68 100644 --- a/lib/storage/drift/offband_database.dart +++ b/lib/storage/drift/offband_database.dart @@ -5,9 +5,11 @@ import 'package:drift_flutter/drift_flutter.dart'; import 'package:flutter/foundation.dart'; import 'package:path/path.dart' as p; import 'package:path_provider/path_provider.dart'; -import 'package:sqlite3/sqlite3.dart'; import '../../utils/app_logger.dart'; +// sqlite3 uses dart:ffi, which is unavailable on web; import the native impl +// only off web so `flutter build web` still compiles (#363). +import 'db_snapshot_web.dart' if (dart.library.io) 'db_snapshot_io.dart'; part 'offband_database.g.dart'; @@ -178,12 +180,7 @@ class OffbandDatabase extends _$OffbandDatabase { @visibleForTesting static void snapshotDatabase(String source, String target) { try { - final db = sqlite3.open(source, mode: OpenMode.readOnly); - try { - db.execute("VACUUM INTO '${target.replaceAll("'", "''")}'"); - } finally { - db.close(); - } + vacuumInto(source, target); final out = File(target); if (!out.existsSync() || out.lengthSync() == 0) { throw StateError('VACUUM INTO produced no output at $target');