-
-
Notifications
You must be signed in to change notification settings - Fork 64
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[sembast_web] web and js_interop support
- Loading branch information
1 parent
66f80bb
commit 0c1be50
Showing
12 changed files
with
270 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
@TestOn('browser') | ||
library; | ||
|
||
import 'package:idb_shim/idb_client_native_web.dart'; | ||
import 'package:sembast_test/all_jdb_test.dart' as all_jdb_test; | ||
import 'package:sembast_test/all_test.dart'; | ||
import 'package:sembast_test/jdb_test_common.dart'; | ||
import 'package:sembast_test/src/import_jdb.dart'; | ||
import 'package:sembast_test/test_common.dart'; | ||
import 'package:sembast_web/src/jdb_factory_idb.dart'; | ||
import 'package:test/test.dart'; | ||
|
||
Future main() async { | ||
var jdbFactory = JdbFactoryIdb(idbFactoryNative); | ||
var factory = DatabaseFactoryJdb(jdbFactory); | ||
|
||
var testContext = DatabaseTestContextJdb()..factory = factory; | ||
|
||
group('idb_native', () { | ||
defineTests(testContext); | ||
all_jdb_test.defineTests(testContext); | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,7 @@ | ||
## 2.3.0-0 | ||
|
||
* web and js_interop support | ||
|
||
## 2.2.0 | ||
|
||
* Dart 3 only | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import 'package:sembast/sembast.dart'; | ||
import 'package:sembast_web/src/web_interop/sembast_web.dart' as src; | ||
|
||
/// Sembast factory for the Web. | ||
/// | ||
/// Build on top of IndexedDB and localStorage. | ||
DatabaseFactory get databaseFactoryWeb => src.databaseFactoryWeb; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
import 'dart:async'; | ||
import 'dart:js_interop'; | ||
|
||
import 'package:idb_shim/idb_client_native_web.dart'; | ||
import 'package:sembast_web/src/jdb_factory_idb.dart'; | ||
import 'package:sembast_web/src/jdb_import.dart'; | ||
import 'package:sembast_web/src/web_defs.dart'; | ||
import 'package:web/web.dart' as web; | ||
|
||
/// The native jdb factory | ||
var jdbFactoryIdbNative = JdbFactoryWeb(); | ||
|
||
/// The sembast idb native factory with web. | ||
var databaseFactoryWeb = DatabaseFactoryWeb(); | ||
|
||
/// Web jdb factory. | ||
class JdbFactoryWeb extends JdbFactoryIdb { | ||
/// Web jdb factory. | ||
JdbFactoryWeb() : super(idbFactoryNative); | ||
|
||
StreamSubscription? _revisionSubscription; | ||
|
||
@override | ||
void start() { | ||
stop(); | ||
_revisionSubscription = storageRevisionStream.listen((storageRevision) { | ||
var list = databases[storageRevision.name]!; | ||
for (var jdbDatabase in list) { | ||
jdbDatabase.addRevision(storageRevision.revision); | ||
} | ||
}); | ||
} | ||
|
||
@override | ||
void stop() { | ||
_revisionSubscription?.cancel(); | ||
_revisionSubscription = null; | ||
} | ||
|
||
/// Notify other app (web only)) | ||
@override | ||
void notifyRevision(StorageRevision storageRevision) { | ||
addStorageRevision(storageRevision); | ||
} | ||
} | ||
|
||
/// Web factory. | ||
class DatabaseFactoryWeb extends DatabaseFactoryJdb { | ||
/// Web factory. | ||
DatabaseFactoryWeb() : super(jdbFactoryIdbNative); | ||
} | ||
|
||
String _sembastStorageKeyPrefix = 'sembast_web/revision:'; | ||
|
||
/// add a storage revision | ||
void addStorageRevision(StorageRevision storageRevision) { | ||
if (debugStorageNotification) { | ||
print('adding storage revision $storageRevision'); | ||
} | ||
var key = '$_sembastStorageKeyPrefix${storageRevision.name}'; | ||
if (storageRevision.revision != 0) { | ||
web.window.localStorage.setItem(key, storageRevision.revision.toString()); | ||
} else { | ||
web.window.localStorage.removeItem(key); | ||
} | ||
} | ||
|
||
StreamController<StorageRevision>? _storageRevisionController; | ||
|
||
/// Storage revision notification from all tabs | ||
Stream<StorageRevision> get storageRevisionStream { | ||
_storageRevisionController ??= | ||
StreamController<StorageRevision>.broadcast(onListen: () { | ||
web.window.onstorage = (web.StorageEvent event) { | ||
if (debugStorageNotification) { | ||
print('getting ${event.key}: ${event.newValue}'); | ||
} | ||
if (event.key?.startsWith(_sembastStorageKeyPrefix) ?? false) { | ||
var name = event.key!.substring(_sembastStorageKeyPrefix.length); | ||
var revision = | ||
event.newValue == null ? 0 : (int.tryParse(event.newValue!) ?? 0); | ||
_storageRevisionController?.add(StorageRevision(name, revision)); | ||
} | ||
}.toJS; | ||
}, onCancel: () { | ||
web.window.onstorage = null; | ||
_storageRevisionController = null; | ||
}); | ||
return _storageRevisionController!.stream; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export 'sembast_web_stub.dart' | ||
if (dart.library.html) 'sembast_web_impl.dart' | ||
if (dart.library.io) 'sembast_web_io.dart'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import 'package:sembast/sembast.dart'; | ||
import 'package:sembast_web/src/web_interop.dart' as src; | ||
|
||
/// Sembast factory for the Web. | ||
/// | ||
/// Build on top of IndexedDB and localStorage. | ||
DatabaseFactory get databaseFactoryWeb => src.databaseFactoryWeb; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import 'package:sembast/sembast.dart'; | ||
|
||
/// Sembast factory for the Web. | ||
/// | ||
/// Build on top of IndexedDB and localStorage. | ||
DatabaseFactory get databaseFactoryWeb => _stub( | ||
'databaseFactoryWeb not support on Flutter/VM. Use `sembast_sqflite` or `sembast` io implementation'); | ||
|
||
T _stub<T>(String message) { | ||
throw UnimplementedError(message); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import 'package:sembast/sembast.dart'; | ||
|
||
/// Sembast factory for the Web. | ||
/// | ||
/// Build on top of IndexedDB and localStorage. | ||
DatabaseFactory get databaseFactoryWeb => _stub('databaseFactoryWeb'); | ||
|
||
T _stub<T>(String message) { | ||
throw UnimplementedError(message); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
@TestOn('browser') | ||
library; | ||
|
||
import 'package:sembast/sembast.dart'; | ||
import 'package:sembast_web/sembast_web_interop.dart'; | ||
import 'package:sembast_web/src/sembast_import.dart'; | ||
import 'package:test/test.dart'; | ||
import 'package:web/web.dart'; | ||
|
||
import '../multiplatform/idb_jdb_test.dart' as idb_jdb_test; | ||
import '../multiplatform/idb_jdb_test.dart'; | ||
|
||
var testPath = '.dart_tool/sembast_web_interop/databases'; | ||
|
||
Future main() async { | ||
var factory = databaseFactoryWeb; | ||
|
||
group('idb_native', () { | ||
test('doc', () async { | ||
// Declare our store (records are mapd, ids are ints) | ||
var store = intMapStoreFactory.store(); | ||
var factory = databaseFactoryWeb; | ||
|
||
// Open the database | ||
var db = await factory.openDatabase('test'); | ||
|
||
// Add a new record | ||
var key = | ||
await store.add(db, <String, Object?>{'name': 'Table', 'price': 15}); | ||
|
||
// Read the record | ||
var value = await store.record(key).get(db); | ||
|
||
// Print the value | ||
print(value); | ||
|
||
// Close the database | ||
await db.close(); | ||
}); | ||
|
||
test('open', () async { | ||
var store = StoreRef<String, String>.main(); | ||
var record = store.record('key'); | ||
await factory.deleteDatabase('test'); | ||
var db = await factory.openDatabase('test'); | ||
expect(await record.get(db), isNull); | ||
await record.put(db, 'value'); | ||
expect(await record.get(db), 'value'); | ||
await db.close(); | ||
|
||
db = await factory.openDatabase('test'); | ||
await record.put(db, 'value'); | ||
expect(await record.get(db), 'value'); | ||
await db.close(); | ||
}); | ||
|
||
test('storage_notification', () async { | ||
var store = StoreRef<String, String>.main(); | ||
await factory.deleteDatabase('test'); | ||
var db = await factory.openDatabase('test'); | ||
expect(window.localStorage['sembast_web/revision:test'], isNull); | ||
var record = store.record('my_key'); | ||
await record.put(db, 'my_value'); | ||
expect(window.localStorage['sembast_web/revision:test'], '1'); | ||
await db.close(); | ||
expect(window.localStorage['sembast_web/revision:test'], '1'); | ||
// Make sure the storage gets clears on deletion | ||
await factory.deleteDatabase('test'); | ||
expect(window.localStorage['sembast_web/revision:test'], isNull); | ||
}); | ||
|
||
idb_jdb_test.defineTests( | ||
asJdbJactoryIdb(asDatabaseFactoryIdb(databaseFactoryWeb).jdbFactory)); | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
@TestOn('browser') | ||
library; | ||
|
||
import 'package:sembast/sembast.dart'; | ||
import 'package:sembast_web/src/web_interop.dart'; | ||
import 'package:test/test.dart'; | ||
|
||
var testPath = '.dart_tool/sembast_web/databases'; | ||
|
||
Future main() async { | ||
var factory = databaseFactoryWeb; | ||
|
||
group('web', () { | ||
test('notification', () async { | ||
var revisionFuture = storageRevisionStream.first; | ||
var store = StoreRef<String, String>.main(); | ||
var record = store.record('key'); | ||
await factory.deleteDatabase('test'); | ||
var db = await factory.openDatabase('test'); | ||
expect(await record.get(db), isNull); | ||
await record.put(db, 'value'); | ||
expect(await record.get(db), 'value'); | ||
|
||
try { | ||
var storageRevision = | ||
await revisionFuture.timeout(const Duration(seconds: 10)); | ||
expect(storageRevision.name, 'test'); | ||
expect(storageRevision.revision, greaterThanOrEqualTo(1)); | ||
} catch (e) { | ||
print(e); | ||
} | ||
await db.close(); | ||
}); | ||
}); | ||
} |