mirror of https://github.com/AMT-Cheif/drift.git
Add web compatibility information to web page
This commit is contained in:
parent
ff41de2a6b
commit
ec5927bc2a
|
@ -93,6 +93,25 @@ targets:
|
|||
- "lib/snippets/**"
|
||||
- "tool/snippets.dart"
|
||||
|
||||
worker:
|
||||
dependencies: ['$default']
|
||||
auto_apply_builders: false
|
||||
sources:
|
||||
- "web/worker.dart"
|
||||
builders:
|
||||
build_web_compilers:entrypoint:
|
||||
options:
|
||||
compiler: dart2js
|
||||
build_web_compilers:dart2js_archive_extractor:
|
||||
enabled: false
|
||||
|
||||
dart2js_archives:
|
||||
auto_apply_builders: false
|
||||
dependencies: [":$default", ":worker"]
|
||||
builders:
|
||||
build_web_compilers:dart2js_archive_extractor:
|
||||
enabled: true
|
||||
|
||||
$default:
|
||||
dependencies: [":codegen", ":syntax_highlighting"]
|
||||
builders:
|
||||
|
@ -100,6 +119,9 @@ targets:
|
|||
release_options:
|
||||
environment: "preview"
|
||||
build_web_compilers:entrypoint:
|
||||
generate_for:
|
||||
exclude:
|
||||
- "web/worker.dart"
|
||||
release_options:
|
||||
# Turn of null assertions for release builds, it looks like this
|
||||
# makes generated code slightly smaller.
|
||||
|
@ -116,15 +138,18 @@ targets:
|
|||
enabled: false
|
||||
json_serializable:
|
||||
enabled: false
|
||||
build_web_compilers:dart2js_archive_extractor:
|
||||
enabled: false
|
||||
sources:
|
||||
- "lib/**"
|
||||
- "pages/**"
|
||||
- "templates/**"
|
||||
- "web/**"
|
||||
- "$package$"
|
||||
- "pubspec.yaml"
|
||||
- "theme.yaml"
|
||||
- "website.yaml"
|
||||
include:
|
||||
- "lib/**"
|
||||
- "pages/**"
|
||||
- "templates/**"
|
||||
- "web/**"
|
||||
- "$package$"
|
||||
- "pubspec.yaml"
|
||||
- "theme.yaml"
|
||||
- "website.yaml"
|
||||
|
||||
# Snippets referencing public API members from this package will get dartdoc links
|
||||
# embedded in them.
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
import 'package:drift/drift.dart';
|
||||
import 'package:drift/wasm.dart';
|
||||
import 'package:drift/web/worker.dart';
|
||||
import 'package:sqlite3/wasm.dart';
|
||||
|
||||
void main() {
|
||||
driftWorkerMain(() {
|
||||
return LazyDatabase(() async {
|
||||
// You can use a different OPFS path here is you need more than one
|
||||
// persisted database in your app.
|
||||
final fileSystem = await OpfsFileSystem.loadFromStorage('my_database');
|
||||
|
||||
final sqlite3 = await WasmSqlite3.loadFromUrl(
|
||||
// Uri where you're hosting the wasm bundle for sqlite3
|
||||
Uri.parse('/sqlite3.wasm'),
|
||||
environment: SqliteEnvironment(fileSystem: fileSystem),
|
||||
);
|
||||
|
||||
// The path here should always be `database` since that is the only file
|
||||
// persisted by the OPFS file system.
|
||||
return WasmDatabase(sqlite3: sqlite3, path: 'database');
|
||||
});
|
||||
});
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
import 'package:drift/drift.dart';
|
||||
import 'package:drift/wasm.dart';
|
||||
import 'package:sqlite3/wasm.dart';
|
||||
|
||||
QueryExecutor connect() {
|
||||
return LazyDatabase(() async {
|
||||
// Create virtual filesystem for sqlite3 implemented over blobs stored in an
|
||||
// IndexedDB database (named `my_app` here).
|
||||
final fs = await IndexedDbFileSystem.open(dbName: 'my_app');
|
||||
|
||||
final sqlite3 = await WasmSqlite3.loadFromUrl(
|
||||
Uri.parse('sqlite3.wasm'),
|
||||
environment: SqliteEnvironment(fileSystem: fs),
|
||||
);
|
||||
|
||||
// Then, open a database:
|
||||
return WasmDatabase(sqlite3: sqlite3, path: '/app.db');
|
||||
});
|
||||
}
|
|
@ -6,9 +6,20 @@ template: layouts/docs/single
|
|||
path: web/
|
||||
---
|
||||
|
||||
You can experimentally use drift in Dart webapps. Drift web supports
|
||||
You can experimentally use drift in Dart webapps. Drift web supports
|
||||
Flutter Web, AngularDart, plain `dart:html` or any other web framework.
|
||||
|
||||
## Compatibility check
|
||||
|
||||
To quickly check which storage implementation drift would chose, the drift worker is also embedded
|
||||
on this page. You can click on this button to see the results.
|
||||
|
||||
<button class="btn btn-light" id="drift-compat-btn">Check compatibility</button>
|
||||
|
||||
<pre id="drift-compat-results">
|
||||
Compatibility check not started yet
|
||||
</pre>
|
||||
|
||||
## Getting started
|
||||
|
||||
From a perspective of the Dart code used, drift on the web is similar to drift on other platforms.
|
||||
|
@ -261,9 +272,6 @@ Instead, grab a sqlite3.wasm file from the [releases](https://github.com/simolus
|
|||
|
||||
With this setup, sqlite3 can be used on the web without an external library:
|
||||
|
||||
{% assign snippets = 'package:drift_docs/snippets/engines/web_wasm.dart.excerpt.json' | readString | json_decode %}
|
||||
{% include "blocks/snippet" snippets = snippets %}
|
||||
|
||||
This snippet also works in a service worker.
|
||||
|
||||
If you're running into any issues with the new backend, please post them [here](https://github.com/simolus3/sqlite3.dart/issues).
|
||||
|
|
|
@ -79,8 +79,6 @@ write the worker yourself and compile it to JavaScript.
|
|||
|
||||
The worker's source could be put into `web/database_worker.dart` and have a structure like the following:
|
||||
|
||||
{% assign worker = 'package:drift_docs/snippets/engines/new_worker.dart.excerpt.json' | readString | json_decode %}
|
||||
|
||||
{% include "blocks/snippet" snippets = worker %}
|
||||
|
||||
Drift will detect whether the worker is running as a shared or as a dedicated worker and call the callback to open the
|
||||
|
@ -119,8 +117,6 @@ when in doubt, `DriftWorkerMode.dedicatedInShared` is a good default.
|
|||
|
||||
To spawn and connect to such a web worker, drift provides the `connectToDriftWorker` method:
|
||||
|
||||
{% assign snippets = 'package:drift_docs/snippets/engines/new_connect.dart.excerpt.json' | readString | json_decode %}
|
||||
|
||||
{% include "blocks/snippet" snippets = snippets name = "approach1" %}
|
||||
|
||||
The returned `DatabaseConnection` can be passed to the constructor of a generated database class.
|
||||
|
|
|
@ -17,7 +17,7 @@ dependencies:
|
|||
version: ^0.0.12
|
||||
# used in snippets
|
||||
http: ^0.13.5
|
||||
sqlite3: ^1.11.0
|
||||
sqlite3: ^2.0.0-dev
|
||||
# Fake path_provider for snippets
|
||||
path_provider:
|
||||
path: assets/path_provider
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
{% if page.path == '/search' %}
|
||||
<link rel="stylesheet" href="/search.css">
|
||||
{% endif -%}
|
||||
{% if page.path == 'web/' %}
|
||||
<script defer src="compatibility.dart.js"></script>
|
||||
{% endif %}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
../../extras/assets/sqlite3.wasm
|
|
@ -0,0 +1,30 @@
|
|||
import 'dart:html';
|
||||
|
||||
import 'package:drift/wasm.dart';
|
||||
|
||||
void main() async {
|
||||
final btn = querySelector('#drift-compat-btn')!;
|
||||
final results = querySelector('#drift-compat-results')!;
|
||||
|
||||
await for (final click in btn.onClick) {
|
||||
btn.attributes['disabled'] = 'true';
|
||||
results.innerText = '';
|
||||
|
||||
try {
|
||||
final db = await WasmDatabase.open(
|
||||
databaseName: 'test_db',
|
||||
sqlite3Uri: Uri.parse('/sqlite3.wasm'),
|
||||
driftWorkerUri: Uri.parse('/worker.dart.js'),
|
||||
);
|
||||
|
||||
results.innerText += '''
|
||||
Chosen implementation: ${db.chosenImplementation}
|
||||
Features missing: ${db.missingFeatures}
|
||||
''';
|
||||
} catch (e, s) {
|
||||
results.innerText += 'Error: $e, Trace: \n$s';
|
||||
} finally {
|
||||
btn.attributes.remove('disabled');
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
import 'package:drift/wasm.dart';
|
||||
|
||||
void main() {
|
||||
WasmDatabase.workerMainForOpen();
|
||||
}
|
|
@ -63,15 +63,19 @@ Future<WasmDatabaseResult> openWasmDatabase({
|
|||
StreamQueue(port.onMessage.map(WasmInitializationMessage.read));
|
||||
|
||||
// First, the shared worker will tell us which features it supports.
|
||||
final sharedFeatures = await sharedMessages.next as SharedWorkerStatus;
|
||||
final sharedFeatures =
|
||||
await sharedMessages.nextNoError as SharedWorkerStatus;
|
||||
missingFeatures.addAll(sharedFeatures.missingFeatures);
|
||||
|
||||
// Can we use the shared OPFS implementation?
|
||||
if (sharedFeatures.canSpawnDedicatedWorkers &&
|
||||
sharedFeatures.dedicatedWorkersCanUseOpfs) {
|
||||
return connect(
|
||||
WasmStorageImplementation.opfsShared, (msg) => msg.sendToPort(port));
|
||||
} else if (sharedFeatures.canUseIndexedDb) {
|
||||
return connect(WasmStorageImplementation.sharedIndexedDb,
|
||||
(msg) => msg.sendToPort(port));
|
||||
} else {
|
||||
missingFeatures.addAll(sharedFeatures.missingFeatures);
|
||||
await sharedMessages.cancel();
|
||||
port.close();
|
||||
}
|
||||
|
@ -86,7 +90,7 @@ Future<WasmDatabaseResult> openWasmDatabase({
|
|||
dedicatedWorker.onMessage.map(WasmInitializationMessage.read));
|
||||
|
||||
final status =
|
||||
await workerMessages.next as DedicatedWorkerCompatibilityResult;
|
||||
await workerMessages.nextNoError as DedicatedWorkerCompatibilityResult;
|
||||
missingFeatures.addAll(status.missingFeatures);
|
||||
|
||||
if (status.supportsNestedWorkers &&
|
||||
|
@ -112,3 +116,15 @@ Future<WasmDatabaseResult> openWasmDatabase({
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
extension on StreamQueue<WasmInitializationMessage> {
|
||||
Future<WasmInitializationMessage> get nextNoError {
|
||||
return next.then((value) {
|
||||
if (value is WorkerError) {
|
||||
throw value;
|
||||
}
|
||||
|
||||
return value;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,21 +3,15 @@
|
|||
import 'dart:async';
|
||||
import 'dart:html';
|
||||
|
||||
import 'package:drift/drift.dart';
|
||||
import 'package:drift/remote.dart';
|
||||
import 'package:drift/wasm.dart';
|
||||
import 'package:js/js_util.dart';
|
||||
import 'package:sqlite3/wasm.dart';
|
||||
|
||||
import '../channel.dart';
|
||||
import 'protocol.dart';
|
||||
import 'shared.dart';
|
||||
|
||||
class DedicatedDriftWorker {
|
||||
final DedicatedWorkerGlobalScope self;
|
||||
|
||||
/// Running drift servers by the name of the database they're serving.
|
||||
final Map<String, DriftServer> _servers = {};
|
||||
final DriftServerController _servers = DriftServerController();
|
||||
|
||||
DedicatedDriftWorker(this.self);
|
||||
|
||||
|
@ -42,29 +36,7 @@ class DedicatedDriftWorker {
|
|||
hasProperty(globalThis, 'SharedArrayBuffer'),
|
||||
).sendToClient(self);
|
||||
case ServeDriftDatabase():
|
||||
final server = _servers.putIfAbsent(message.databaseName, () {
|
||||
return DriftServer(LazyDatabase(() async {
|
||||
final sqlite3 =
|
||||
await WasmSqlite3.loadFromUrl(message.sqlite3WasmUri);
|
||||
|
||||
final vfs = await switch (message.storage) {
|
||||
WasmStorageImplementation.opfsShared =>
|
||||
SimpleOpfsFileSystem.loadFromStorage(
|
||||
'/drift_db/${message.databaseName}'),
|
||||
WasmStorageImplementation.opfsLocks => _loadLockedWasmVfs(),
|
||||
WasmStorageImplementation.unsafeIndexedDb =>
|
||||
IndexedDbFileSystem.open(dbName: message.databaseName),
|
||||
WasmStorageImplementation.inMemory =>
|
||||
Future.value(InMemoryFileSystem()),
|
||||
};
|
||||
|
||||
sqlite3.registerVirtualFileSystem(vfs, makeDefault: true);
|
||||
|
||||
return WasmDatabase(sqlite3: sqlite3, path: '/database');
|
||||
}));
|
||||
});
|
||||
|
||||
server.serve(message.port.channel());
|
||||
_servers.serve(message);
|
||||
case StartFileSystemServer(sqlite3Options: final options):
|
||||
final worker = await VfsWorker.create(options);
|
||||
await worker.start();
|
||||
|
@ -72,17 +44,4 @@ class DedicatedDriftWorker {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Future<WasmVfs> _loadLockedWasmVfs() async {
|
||||
// Create SharedArrayBuffers to synchronize requests
|
||||
final options = WasmVfs.createOptions();
|
||||
final worker = Worker(Uri.base.toString());
|
||||
|
||||
StartFileSystemServer(options).sendToWorker(worker);
|
||||
|
||||
// Wait for the server worker to report that it's ready
|
||||
await worker.onMessage.first;
|
||||
|
||||
return WasmVfs(workerOptions: options);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,10 +62,12 @@ final class SharedWorkerStatus extends WasmInitializationMessage {
|
|||
|
||||
final bool canSpawnDedicatedWorkers;
|
||||
final bool dedicatedWorkersCanUseOpfs;
|
||||
final bool canUseIndexedDb;
|
||||
|
||||
SharedWorkerStatus({
|
||||
required this.canSpawnDedicatedWorkers,
|
||||
required this.dedicatedWorkersCanUseOpfs,
|
||||
required this.canUseIndexedDb,
|
||||
});
|
||||
|
||||
factory SharedWorkerStatus.fromJsPayload(Object payload) {
|
||||
|
@ -74,6 +76,7 @@ final class SharedWorkerStatus extends WasmInitializationMessage {
|
|||
return SharedWorkerStatus(
|
||||
canSpawnDedicatedWorkers: data[0],
|
||||
dedicatedWorkersCanUseOpfs: data[1],
|
||||
canUseIndexedDb: data[2],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -82,22 +85,21 @@ final class SharedWorkerStatus extends WasmInitializationMessage {
|
|||
sender.sendTyped(type, [
|
||||
canSpawnDedicatedWorkers,
|
||||
dedicatedWorkersCanUseOpfs,
|
||||
canUseIndexedDb
|
||||
]);
|
||||
}
|
||||
|
||||
Iterable<MissingBrowserFeature> get missingFeatures sync* {
|
||||
if (!canSpawnDedicatedWorkers) {
|
||||
yield MissingBrowserFeature.dedicatedWorkersInSharedWorkers;
|
||||
}
|
||||
|
||||
if (!dedicatedWorkersCanUseOpfs) {
|
||||
} else if (!dedicatedWorkersCanUseOpfs) {
|
||||
yield MissingBrowserFeature.fileSystemAccess;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A message sent by a worker when an error occurred.
|
||||
final class WorkerError extends WasmInitializationMessage {
|
||||
final class WorkerError extends WasmInitializationMessage implements Exception {
|
||||
static const type = 'Error';
|
||||
|
||||
final String error;
|
||||
|
@ -112,6 +114,11 @@ final class WorkerError extends WasmInitializationMessage {
|
|||
void _send(_PostMessage sender) {
|
||||
sender.sendTyped(type, error);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'Error in worker: $error';
|
||||
}
|
||||
}
|
||||
|
||||
/// Instructs a dedicated or shared worker to serve a drift database connection
|
||||
|
|
|
@ -1,6 +1,15 @@
|
|||
import 'dart:html';
|
||||
|
||||
import 'package:drift/drift.dart';
|
||||
import 'package:drift/remote.dart';
|
||||
import 'package:drift/wasm.dart';
|
||||
import 'package:js/js_util.dart';
|
||||
// ignore: implementation_imports
|
||||
import 'package:sqlite3/src/wasm/js_interop/file_system_access.dart';
|
||||
import 'package:sqlite3/wasm.dart';
|
||||
|
||||
import '../channel.dart';
|
||||
import 'protocol.dart';
|
||||
|
||||
/// Checks whether the OPFS API is likely to be correctly implemented in the
|
||||
/// current browser.
|
||||
|
@ -48,3 +57,47 @@ Future<bool> checkOpfsSupport() async {
|
|||
Future<bool> checkIndexedDbSupport() async {
|
||||
return true;
|
||||
}
|
||||
|
||||
class DriftServerController {
|
||||
/// Running drift servers by the name of the database they're serving.
|
||||
final Map<String, DriftServer> _servers = {};
|
||||
|
||||
void serve(ServeDriftDatabase message) {
|
||||
final server = _servers.putIfAbsent(message.databaseName, () {
|
||||
return DriftServer(LazyDatabase(() async {
|
||||
final sqlite3 = await WasmSqlite3.loadFromUrl(message.sqlite3WasmUri);
|
||||
|
||||
final vfs = await switch (message.storage) {
|
||||
WasmStorageImplementation.opfsShared =>
|
||||
SimpleOpfsFileSystem.loadFromStorage(
|
||||
'/drift_db/${message.databaseName}'),
|
||||
WasmStorageImplementation.opfsLocks => _loadLockedWasmVfs(),
|
||||
WasmStorageImplementation.unsafeIndexedDb ||
|
||||
WasmStorageImplementation.sharedIndexedDb =>
|
||||
IndexedDbFileSystem.open(dbName: message.databaseName),
|
||||
WasmStorageImplementation.inMemory =>
|
||||
Future.value(InMemoryFileSystem()),
|
||||
};
|
||||
|
||||
sqlite3.registerVirtualFileSystem(vfs, makeDefault: true);
|
||||
|
||||
return WasmDatabase(sqlite3: sqlite3, path: '/database');
|
||||
}));
|
||||
});
|
||||
|
||||
server.serve(message.port.channel());
|
||||
}
|
||||
|
||||
Future<WasmVfs> _loadLockedWasmVfs() async {
|
||||
// Create SharedArrayBuffers to synchronize requests
|
||||
final options = WasmVfs.createOptions();
|
||||
final worker = Worker(Uri.base.toString());
|
||||
|
||||
StartFileSystemServer(options).sendToWorker(worker);
|
||||
|
||||
// Wait for the server worker to report that it's ready
|
||||
await worker.onMessage.first;
|
||||
|
||||
return WasmVfs(workerOptions: options);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import 'package:drift/wasm.dart';
|
|||
import 'package:js/js_util.dart';
|
||||
|
||||
import 'protocol.dart';
|
||||
import 'shared.dart';
|
||||
|
||||
class SharedDriftWorker {
|
||||
final SharedWorkerGlobalScope self;
|
||||
|
@ -15,6 +16,8 @@ class SharedDriftWorker {
|
|||
Worker? _dedicatedWorker;
|
||||
Future<SharedWorkerStatus>? _featureDetection;
|
||||
|
||||
final DriftServerController _servers = DriftServerController();
|
||||
|
||||
SharedDriftWorker(this.self);
|
||||
|
||||
void start() {
|
||||
|
@ -30,8 +33,8 @@ class SharedDriftWorker {
|
|||
try {
|
||||
final result = await detectionFuture;
|
||||
result.sendToPort(clientPort);
|
||||
} catch (e) {
|
||||
WorkerError(e.toString()).sendToPort(clientPort);
|
||||
} catch (e, s) {
|
||||
WorkerError(e.toString() + s.toString()).sendToPort(clientPort);
|
||||
}
|
||||
|
||||
clientPort.onMessage
|
||||
|
@ -43,6 +46,12 @@ class SharedDriftWorker {
|
|||
final message = WasmInitializationMessage.read(event);
|
||||
|
||||
switch (message) {
|
||||
case ServeDriftDatabase(
|
||||
storage: WasmStorageImplementation.sharedIndexedDb
|
||||
):
|
||||
// The shared indexed db implementation can be hosted directly in this
|
||||
// worker.
|
||||
_servers.serve(message);
|
||||
case ServeDriftDatabase():
|
||||
// Forward the request to the worker - this will also transfer the
|
||||
// port which means that the shared worker is not involved in the
|
||||
|
@ -60,17 +69,19 @@ class SharedDriftWorker {
|
|||
Future<SharedWorkerStatus> _startFeatureDetection() async {
|
||||
// First, let's see if this shared worker can spawn dedicated workers.
|
||||
final hasWorker = hasProperty(self, 'Worker');
|
||||
final canUseIndexedDb = await checkIndexedDbSupport();
|
||||
|
||||
if (!hasWorker) {
|
||||
return SharedWorkerStatus(
|
||||
canSpawnDedicatedWorkers: false,
|
||||
dedicatedWorkersCanUseOpfs: false,
|
||||
canUseIndexedDb: canUseIndexedDb,
|
||||
);
|
||||
} else {
|
||||
final worker = _dedicatedWorker = Worker(Uri.base.toString());
|
||||
|
||||
// Ask the worker about the storage implementations it can support.
|
||||
worker.postMessage(DedicatedWorkerCompatibilityCheck());
|
||||
DedicatedWorkerCompatibilityCheck().sendToWorker(worker);
|
||||
|
||||
final completer = Completer<SharedWorkerStatus>();
|
||||
StreamSubscription? messageSubscription, errorSubscription;
|
||||
|
@ -80,6 +91,7 @@ class SharedDriftWorker {
|
|||
completer.complete(SharedWorkerStatus(
|
||||
canSpawnDedicatedWorkers: true,
|
||||
dedicatedWorkersCanUseOpfs: result,
|
||||
canUseIndexedDb: canUseIndexedDb,
|
||||
));
|
||||
|
||||
messageSubscription?.cancel();
|
||||
|
|
|
@ -215,6 +215,8 @@ enum WasmStorageImplementation {
|
|||
/// [cross-origin isolation]: https://developer.mozilla.org/en-US/docs/Web/API/crossOriginIsolated
|
||||
opfsLocks,
|
||||
|
||||
sharedIndexedDb,
|
||||
|
||||
/// Uses the asynchronous IndexedDB API outside of any worker to persist data.
|
||||
///
|
||||
/// Unlike [opfsShared] or [opfsLocks], this storage implementation can't
|
||||
|
|
|
@ -15,7 +15,7 @@ dependencies:
|
|||
js: ^0.6.3
|
||||
meta: ^1.3.0
|
||||
stream_channel: ^2.1.0
|
||||
sqlite3: ^2.0.0-dev
|
||||
sqlite3: ^2.0.0-dev.1
|
||||
|
||||
dev_dependencies:
|
||||
archive: ^3.3.1
|
||||
|
@ -37,7 +37,3 @@ dev_dependencies:
|
|||
shelf: ^1.3.0
|
||||
stack_trace: ^1.10.0
|
||||
test_descriptor: ^2.0.1
|
||||
|
||||
dependency_overrides:
|
||||
sqlite3:
|
||||
path: /home/simon/src/sqlite3.dart/sqlite3
|
||||
|
|
|
@ -39,7 +39,3 @@ dev_dependencies:
|
|||
|
||||
flutter:
|
||||
uses-material-design: true
|
||||
|
||||
dependency_overrides:
|
||||
sqlite3:
|
||||
path: /home/simon/src/sqlite3.dart/sqlite3
|
||||
|
|
Loading…
Reference in New Issue