remove tests

This commit is contained in:
2025-07-20 20:57:19 +02:00
parent 30b2545f4c
commit 4bf4cf07e3
12 changed files with 0 additions and 2159 deletions

View File

@@ -1,188 +0,0 @@
// ignore_for_file: public_member_api_docs
import 'dart:indexed_db';
import 'dart:js';
import 'package:isar/isar.dart';
import 'package:js/js.dart';
import 'package:js/js_util.dart';
@JS('JSON.stringify')
external String stringify(dynamic value);
@JS('indexedDB.cmp')
external int idbCmp(dynamic value1, dynamic value2);
@JS('Object.keys')
external List<String> objectKeys(dynamic obj);
Map<String, dynamic> jsMapToDart(Object obj) {
final keys = objectKeys(obj);
final map = <String, dynamic>{};
for (final key in keys) {
map[key] = getProperty<dynamic>(obj, key);
}
return map;
}
@JS('Promise')
class Promise {}
extension PromiseX on Promise {
Future<T> wait<T>() => promiseToFuture(this);
}
@JS('openIsar')
external Promise openIsarJs(
String name,
List<dynamic> schemas,
bool relaxedDurability,
);
@JS('IsarTxn')
class IsarTxnJs {
external Promise commit();
external void abort();
external bool get write;
}
@JS('IsarInstance')
class IsarInstanceJs {
external IsarTxnJs beginTxn(bool write);
external IsarCollectionJs getCollection(String name);
external Promise close(bool deleteFromDisk);
}
typedef ChangeCallbackJs = void Function();
typedef ObjectChangeCallbackJs = void Function(Object? object);
typedef QueryChangeCallbackJs = void Function(List<dynamic> results);
typedef StopWatchingJs = JsFunction;
@JS('IsarCollection')
class IsarCollectionJs {
external IsarLinkJs getLink(String name);
external Promise getAll(IsarTxnJs txn, List<Id> ids);
external Promise getAllByIndex(
IsarTxnJs txn,
String indexName,
List<List<dynamic>> values,
);
external Promise putAll(IsarTxnJs txn, List<dynamic> objects);
external Promise deleteAll(IsarTxnJs txn, List<Id> ids);
external Promise deleteAllByIndex(
IsarTxnJs txn,
String indexName,
List<dynamic> keys,
);
external Promise clear(IsarTxnJs txn);
external StopWatchingJs watchLazy(ChangeCallbackJs callback);
external StopWatchingJs watchObject(Id id, ObjectChangeCallbackJs callback);
external StopWatchingJs watchQuery(
QueryJs query,
QueryChangeCallbackJs callback,
);
external StopWatchingJs watchQueryLazy(
QueryJs query,
ChangeCallbackJs callback,
);
}
@JS('IsarLink')
class IsarLinkJs {
external Promise update(
IsarTxnJs txn,
bool backlink,
Id id,
List<Id> addedTargets,
List<Id> deletedTargets,
);
external Promise clear(IsarTxnJs txn, Id id, bool backlink);
}
@JS('IdWhereClause')
@anonymous
class IdWhereClauseJs {
external KeyRange? range;
}
@JS('IndexWhereClause')
@anonymous
class IndexWhereClauseJs {
external String indexName;
external KeyRange? range;
}
@JS('LinkWhereClause')
@anonymous
class LinkWhereClauseJs {
external String linkCollection;
external String linkName;
external bool backlink;
external Id id;
}
@JS('Function')
class FilterJs {
external FilterJs(String id, String obj, String method);
}
@JS('Function')
class SortCmpJs {
external SortCmpJs(String a, String b, String method);
}
@JS('Function')
class DistinctValueJs {
external DistinctValueJs(String obj, String method);
}
@JS('IsarQuery')
class QueryJs {
external QueryJs(
IsarCollectionJs collection,
List<dynamic> whereClauses,
bool whereDistinct,
bool whereAscending,
FilterJs? filter,
SortCmpJs? sortCmp,
DistinctValueJs? distinctValue,
int? offset,
int? limit,
);
external Promise findFirst(IsarTxnJs txn);
external Promise findAll(IsarTxnJs txn);
external Promise deleteFirst(IsarTxnJs txn);
external Promise deleteAll(IsarTxnJs txn);
external Promise min(IsarTxnJs txn, String propertyName);
external Promise max(IsarTxnJs txn, String propertyName);
external Promise sum(IsarTxnJs txn, String propertyName);
external Promise average(IsarTxnJs txn, String propertyName);
external Promise count(IsarTxnJs txn);
}

View File

@@ -1,266 +0,0 @@
// ignore_for_file: public_member_api_docs, invalid_use_of_protected_member
import 'dart:async';
import 'dart:convert';
import 'dart:js';
import 'dart:js_util';
import 'dart:typed_data';
import 'package:isar/isar.dart';
import 'package:isar/src/web/bindings.dart';
import 'package:isar/src/web/isar_impl.dart';
import 'package:isar/src/web/isar_reader_impl.dart';
import 'package:isar/src/web/isar_web.dart';
import 'package:isar/src/web/isar_writer_impl.dart';
import 'package:isar/src/web/query_build.dart';
import 'package:meta/dart2js.dart';
class IsarCollectionImpl<OBJ> extends IsarCollection<OBJ> {
IsarCollectionImpl({
required this.isar,
required this.native,
required this.schema,
});
@override
final IsarImpl isar;
final IsarCollectionJs native;
@override
final CollectionSchema<OBJ> schema;
@override
String get name => schema.name;
late final _offsets = isar.offsets[OBJ]!;
@tryInline
OBJ deserializeObject(Object object) {
final id = getProperty<int>(object, idName);
final reader = IsarReaderImpl(object);
return schema.deserialize(id, reader, _offsets, isar.offsets);
}
@tryInline
List<OBJ?> deserializeObjects(dynamic objects) {
final list = objects as List;
final results = <OBJ?>[];
for (final object in list) {
results.add(object is Object ? deserializeObject(object) : null);
}
return results;
}
@override
Future<List<OBJ?>> getAll(List<Id> ids) {
return isar.getTxn(false, (IsarTxnJs txn) async {
final objects = await native.getAll(txn, ids).wait<List<Object?>>();
return deserializeObjects(objects);
});
}
@override
Future<List<OBJ?>> getAllByIndex(String indexName, List<IndexKey> keys) {
return isar.getTxn(false, (IsarTxnJs txn) async {
final objects = await native
.getAllByIndex(txn, indexName, keys)
.wait<List<Object?>>();
return deserializeObjects(objects);
});
}
@override
List<OBJ?> getAllSync(List<Id> ids) => unsupportedOnWeb();
@override
List<OBJ?> getAllByIndexSync(String indexName, List<IndexKey> keys) =>
unsupportedOnWeb();
@override
Future<List<Id>> putAll(List<OBJ> objects) {
return putAllByIndex(null, objects);
}
@override
List<int> putAllSync(List<OBJ> objects, {bool saveLinks = true}) =>
unsupportedOnWeb();
@override
Future<List<Id>> putAllByIndex(String? indexName, List<OBJ> objects) {
return isar.getTxn(true, (IsarTxnJs txn) async {
final serialized = <Object>[];
for (final object in objects) {
final jsObj = newObject<Object>();
final writer = IsarWriterImpl(jsObj);
schema.serialize(object, writer, _offsets, isar.offsets);
setProperty(jsObj, idName, schema.getId(object));
serialized.add(jsObj);
}
final ids = await native.putAll(txn, serialized).wait<List<dynamic>>();
for (var i = 0; i < objects.length; i++) {
final object = objects[i];
final id = ids[i] as Id;
schema.attach(this, id, object);
}
return ids.cast<Id>().toList();
});
}
@override
List<Id> putAllByIndexSync(
String indexName,
List<OBJ> objects, {
bool saveLinks = true,
}) =>
unsupportedOnWeb();
@override
Future<int> deleteAll(List<Id> ids) async {
await isar.getTxn(true, (IsarTxnJs txn) {
return native.deleteAll(txn, ids).wait<void>();
});
return ids.length;
}
@override
Future<int> deleteAllByIndex(String indexName, List<IndexKey> keys) {
return isar.getTxn(true, (IsarTxnJs txn) {
return native.deleteAllByIndex(txn, indexName, keys).wait();
});
}
@override
int deleteAllSync(List<Id> ids) => unsupportedOnWeb();
@override
int deleteAllByIndexSync(String indexName, List<IndexKey> keys) =>
unsupportedOnWeb();
@override
Future<void> clear() {
return isar.getTxn(true, (IsarTxnJs txn) {
return native.clear(txn).wait();
});
}
@override
void clearSync() => unsupportedOnWeb();
@override
Future<void> importJson(List<Map<String, dynamic>> json) {
return isar.getTxn(true, (IsarTxnJs txn) async {
await native.putAll(txn, json.map(jsify).toList()).wait<dynamic>();
});
}
@override
Future<void> importJsonRaw(Uint8List jsonBytes) {
final json = jsonDecode(const Utf8Decoder().convert(jsonBytes)) as List;
return importJson(json.cast());
}
@override
void importJsonSync(List<Map<String, dynamic>> json) => unsupportedOnWeb();
@override
void importJsonRawSync(Uint8List jsonBytes) => unsupportedOnWeb();
@override
Future<int> count() => where().count();
@override
int countSync() => unsupportedOnWeb();
@override
Future<int> getSize({
bool includeIndexes = false,
bool includeLinks = false,
}) =>
unsupportedOnWeb();
@override
int getSizeSync({
bool includeIndexes = false,
bool includeLinks = false,
}) =>
unsupportedOnWeb();
@override
Stream<void> watchLazy({bool fireImmediately = false}) {
JsFunction? stop;
final controller = StreamController<void>(
onCancel: () {
stop?.apply([]);
},
);
final void Function() callback = allowInterop(() => controller.add(null));
stop = native.watchLazy(callback);
return controller.stream;
}
@override
Stream<OBJ?> watchObject(
Id id, {
bool fireImmediately = false,
bool deserialize = true,
}) {
JsFunction? stop;
final controller = StreamController<OBJ?>(
onCancel: () {
stop?.apply([]);
},
);
final Null Function(Object? obj) callback = allowInterop((Object? obj) {
final object = deserialize && obj != null ? deserializeObject(obj) : null;
controller.add(object);
});
stop = native.watchObject(id, callback);
return controller.stream;
}
@override
Stream<void> watchObjectLazy(Id id, {bool fireImmediately = false}) =>
watchObject(id, deserialize: false);
@override
Query<T> buildQuery<T>({
List<WhereClause> whereClauses = const [],
bool whereDistinct = false,
Sort whereSort = Sort.asc,
FilterOperation? filter,
List<SortProperty> sortBy = const [],
List<DistinctProperty> distinctBy = const [],
int? offset,
int? limit,
String? property,
}) {
return buildWebQuery(
this,
whereClauses,
whereDistinct,
whereSort,
filter,
sortBy,
distinctBy,
offset,
limit,
property,
);
}
@override
Future<void> verify(List<OBJ> objects) => unsupportedOnWeb();
@override
Future<void> verifyLink(
String linkName,
List<int> sourceIds,
List<int> targetIds,
) =>
unsupportedOnWeb();
}

View File

@@ -1,135 +0,0 @@
// ignore_for_file: public_member_api_docs
import 'dart:async';
import 'dart:html';
import 'package:isar/isar.dart';
import 'package:isar/src/web/bindings.dart';
import 'package:isar/src/web/isar_web.dart';
const Symbol _zoneTxn = #zoneTxn;
class IsarImpl extends Isar {
IsarImpl(super.name, this.instance);
final IsarInstanceJs instance;
final offsets = <Type, List<int>>{};
final List<Future<void>> _activeAsyncTxns = [];
@override
final String? directory = null;
void requireNotInTxn() {
if (Zone.current[_zoneTxn] != null) {
throw IsarError(
'Cannot perform this operation from within an active transaction.',
);
}
}
Future<T> _txn<T>(
bool write,
bool silent,
Future<T> Function() callback,
) async {
requireOpen();
requireNotInTxn();
final completer = Completer<void>();
_activeAsyncTxns.add(completer.future);
final txn = instance.beginTxn(write);
final zone = Zone.current.fork(
zoneValues: {_zoneTxn: txn},
);
T result;
try {
result = await zone.run(callback);
await txn.commit().wait<dynamic>();
} catch (e) {
txn.abort();
if (e is DomException) {
if (e.name == DomException.CONSTRAINT) {
throw IsarUniqueViolationError();
} else {
throw IsarError('${e.name}: ${e.message}');
}
} else {
rethrow;
}
} finally {
completer.complete();
_activeAsyncTxns.remove(completer.future);
}
return result;
}
@override
Future<T> txn<T>(Future<T> Function() callback) {
return _txn(false, false, callback);
}
@override
Future<T> writeTxn<T>(Future<T> Function() callback, {bool silent = false}) {
return _txn(true, silent, callback);
}
@override
T txnSync<T>(T Function() callback) => unsupportedOnWeb();
@override
T writeTxnSync<T>(T Function() callback, {bool silent = false}) =>
unsupportedOnWeb();
Future<T> getTxn<T>(bool write, Future<T> Function(IsarTxnJs txn) callback) {
final currentTxn = Zone.current[_zoneTxn] as IsarTxnJs?;
if (currentTxn != null) {
if (write && !currentTxn.write) {
throw IsarError(
'Operation cannot be performed within a read transaction.',
);
}
return callback(currentTxn);
} else if (!write) {
return _txn(false, false, () {
return callback(Zone.current[_zoneTxn] as IsarTxnJs);
});
} else {
throw IsarError('Write operations require an explicit transaction.');
}
}
@override
Future<int> getSize({
bool includeIndexes = false,
bool includeLinks = false,
}) =>
unsupportedOnWeb();
@override
int getSizeSync({
bool includeIndexes = false,
bool includeLinks = false,
}) =>
unsupportedOnWeb();
@override
Future<void> copyToFile(String targetPath) => unsupportedOnWeb();
@override
Future<bool> close({bool deleteFromDisk = false}) async {
requireOpen();
requireNotInTxn();
await Future.wait(_activeAsyncTxns);
await super.close();
await instance.close(deleteFromDisk).wait<dynamic>();
return true;
}
@override
Future<void> verify() => unsupportedOnWeb();
}

View File

@@ -1,75 +0,0 @@
// ignore_for_file: public_member_api_docs
import 'package:isar/isar.dart';
import 'package:isar/src/common/isar_link_base_impl.dart';
import 'package:isar/src/common/isar_link_common.dart';
import 'package:isar/src/common/isar_links_common.dart';
import 'package:isar/src/web/bindings.dart';
import 'package:isar/src/web/isar_collection_impl.dart';
import 'package:isar/src/web/isar_web.dart';
mixin IsarLinkBaseMixin<OBJ> on IsarLinkBaseImpl<OBJ> {
@override
IsarCollectionImpl<dynamic> get sourceCollection =>
super.sourceCollection as IsarCollectionImpl;
@override
IsarCollectionImpl<OBJ> get targetCollection =>
super.targetCollection as IsarCollectionImpl<OBJ>;
@override
late final Id Function(OBJ) getId = targetCollection.schema.getId;
late final String? backlinkLinkName =
sourceCollection.schema.link(linkName).linkName;
late final IsarLinkJs jsLink = backlinkLinkName != null
? targetCollection.native.getLink(backlinkLinkName!)
: sourceCollection.native.getLink(linkName);
@override
Future<void> update({
Iterable<OBJ> link = const [],
Iterable<OBJ> unlink = const [],
bool reset = false,
}) {
final linkList = link.toList();
final unlinkList = unlink.toList();
final containingId = requireAttached();
final backlink = backlinkLinkName != null;
final linkIds = List<Id>.filled(linkList.length, 0);
for (var i = 0; i < linkList.length; i++) {
linkIds[i] = requireGetId(linkList[i]);
}
final unlinkIds = List<Id>.filled(unlinkList.length, 0);
for (var i = 0; i < unlinkList.length; i++) {
unlinkIds[i] = requireGetId(unlinkList[i]);
}
return targetCollection.isar.getTxn(true, (IsarTxnJs txn) async {
if (reset) {
await jsLink.clear(txn, containingId, backlink).wait<dynamic>();
}
return jsLink
.update(txn, backlink, containingId, linkIds, unlinkIds)
.wait();
});
}
@override
void updateSync({
Iterable<OBJ> link = const [],
Iterable<OBJ> unlink = const [],
bool reset = false,
}) =>
unsupportedOnWeb();
}
class IsarLinkImpl<OBJ> extends IsarLinkCommon<OBJ>
with IsarLinkBaseMixin<OBJ> {}
class IsarLinksImpl<OBJ> extends IsarLinksCommon<OBJ>
with IsarLinkBaseMixin<OBJ> {}

View File

@@ -1,347 +0,0 @@
// ignore_for_file: public_member_api_docs
import 'package:isar/isar.dart';
import 'package:js/js_util.dart';
import 'package:meta/dart2js.dart';
const nullNumber = double.negativeInfinity;
const idName = '_id';
final nullDate = DateTime.fromMillisecondsSinceEpoch(0);
class IsarReaderImpl implements IsarReader {
IsarReaderImpl(this.object);
final Object object;
@tryInline
@override
bool readBool(int offset) {
final value = getProperty<dynamic>(object, offset);
return value == 1;
}
@tryInline
@override
bool? readBoolOrNull(int offset) {
final value = getProperty<dynamic>(object, offset);
return value == 0
? false
: value == 1
? true
: null;
}
@tryInline
@override
int readByte(int offset) {
final value = getProperty<dynamic>(object, offset);
return value is int ? value : nullNumber as int;
}
@tryInline
@override
int? readByteOrNull(int offset) {
final value = getProperty<dynamic>(object, offset);
return value is int && value != nullNumber ? value : null;
}
@tryInline
@override
int readInt(int offset) {
final value = getProperty<dynamic>(object, offset);
return value is int ? value : nullNumber as int;
}
@tryInline
@override
int? readIntOrNull(int offset) {
final value = getProperty<dynamic>(object, offset);
return value is int && value != nullNumber ? value : null;
}
@tryInline
@override
double readFloat(int offset) {
final value = getProperty<dynamic>(object, offset);
return value is double ? value : nullNumber;
}
@tryInline
@override
double? readFloatOrNull(int offset) {
final value = getProperty<dynamic>(object, offset);
return value is double && value != nullNumber ? value : null;
}
@tryInline
@override
int readLong(int offset) {
final value = getProperty<dynamic>(object, offset);
return value is int ? value : nullNumber as int;
}
@tryInline
@override
int? readLongOrNull(int offset) {
final value = getProperty<dynamic>(object, offset);
return value is int && value != nullNumber ? value : null;
}
@tryInline
@override
double readDouble(int offset) {
final value = getProperty<dynamic>(object, offset);
return value is double && value != nullNumber ? value : nullNumber;
}
@tryInline
@override
double? readDoubleOrNull(int offset) {
final value = getProperty<dynamic>(object, offset);
return value is double && value != nullNumber ? value : null;
}
@tryInline
@override
DateTime readDateTime(int offset) {
final value = getProperty<dynamic>(object, offset);
return value is int && value != nullNumber
? DateTime.fromMillisecondsSinceEpoch(value, isUtc: true).toLocal()
: nullDate;
}
@tryInline
@override
DateTime? readDateTimeOrNull(int offset) {
final value = getProperty<dynamic>(object, offset);
return value is int && value != nullNumber
? DateTime.fromMillisecondsSinceEpoch(value, isUtc: true).toLocal()
: null;
}
@tryInline
@override
String readString(int offset) {
final value = getProperty<dynamic>(object, offset);
return value is String ? value : '';
}
@tryInline
@override
String? readStringOrNull(int offset) {
final value = getProperty<dynamic>(object, offset);
return value is String ? value : null;
}
@tryInline
@override
T? readObjectOrNull<T>(
int offset,
Deserialize<T> deserialize,
Map<Type, List<int>> allOffsets,
) {
final value = getProperty<dynamic>(object, offset);
if (value is Object) {
final reader = IsarReaderImpl(value);
return deserialize(0, reader, allOffsets[T]!, allOffsets);
} else {
return null;
}
}
@tryInline
@override
List<bool>? readBoolList(int offset) {
final value = getProperty<dynamic>(object, offset);
return value is List ? value.map((e) => e == 1).toList() : null;
}
@tryInline
@override
List<bool?>? readBoolOrNullList(int offset) {
final value = getProperty<dynamic>(object, offset);
return value is List
? value
.map(
(e) => e == 0
? false
: e == 1
? true
: null,
)
.toList()
: null;
}
@tryInline
@override
List<int>? readByteList(int offset) {
final value = getProperty<dynamic>(object, offset);
return value is List
? value.map((e) => e is int ? e : nullNumber as int).toList()
: null;
}
@tryInline
@override
List<int>? readIntList(int offset) {
final value = getProperty<dynamic>(object, offset);
return value is List
? value.map((e) => e is int ? e : nullNumber as int).toList()
: null;
}
@tryInline
@override
List<int?>? readIntOrNullList(int offset) {
final value = getProperty<dynamic>(object, offset);
return value is List
? value.map((e) => e is int && e != nullNumber ? e : null).toList()
: null;
}
@tryInline
@override
List<double>? readFloatList(int offset) {
final value = getProperty<dynamic>(object, offset);
return value is List
? value.map((e) => e is double ? e : nullNumber).toList()
: null;
}
@tryInline
@override
List<double?>? readFloatOrNullList(int offset) {
final value = getProperty<dynamic>(object, offset);
return value is List
? value.map((e) => e is double && e != nullNumber ? e : null).toList()
: null;
}
@tryInline
@override
List<int>? readLongList(int offset) {
final value = getProperty<dynamic>(object, offset);
return value is List
? value.map((e) => e is int ? e : nullNumber as int).toList()
: null;
}
@tryInline
@override
List<int?>? readLongOrNullList(int offset) {
final value = getProperty<dynamic>(object, offset);
return value is List
? value.map((e) => e is int && e != nullNumber ? e : null).toList()
: null;
}
@tryInline
@override
List<double>? readDoubleList(int offset) {
final value = getProperty<dynamic>(object, offset);
return value is List
? value.map((e) => e is double ? e : nullNumber).toList()
: null;
}
@tryInline
@override
List<double?>? readDoubleOrNullList(int offset) {
final value = getProperty<dynamic>(object, offset);
return value is List
? value.map((e) => e is double && e != nullNumber ? e : null).toList()
: null;
}
@tryInline
@override
List<DateTime>? readDateTimeList(int offset) {
final value = getProperty<dynamic>(object, offset);
return value is List
? value
.map(
(e) => e is int && e != nullNumber
? DateTime.fromMillisecondsSinceEpoch(e, isUtc: true)
.toLocal()
: nullDate,
)
.toList()
: null;
}
@tryInline
@override
List<DateTime?>? readDateTimeOrNullList(int offset) {
final value = getProperty<dynamic>(object, offset);
return value is List
? value
.map(
(e) => e is int && e != nullNumber
? DateTime.fromMillisecondsSinceEpoch(e, isUtc: true)
.toLocal()
: null,
)
.toList()
: null;
}
@tryInline
@override
List<String>? readStringList(int offset) {
final value = getProperty<dynamic>(object, offset);
return value is List
? value.map((e) => e is String ? e : '').toList()
: null;
}
@tryInline
@override
List<String?>? readStringOrNullList(int offset) {
final value = getProperty<dynamic>(object, offset);
return value is List
? value.map((e) => e is String ? e : null).toList()
: null;
}
@tryInline
@override
List<T>? readObjectList<T>(
int offset,
Deserialize<T> deserialize,
Map<Type, List<int>> allOffsets,
T defaultValue,
) {
final value = getProperty<dynamic>(object, offset);
return value is List
? value.map((e) {
if (e is Object) {
final reader = IsarReaderImpl(e);
return deserialize(0, reader, allOffsets[T]!, allOffsets);
} else {
return defaultValue;
}
}).toList()
: null;
}
@tryInline
@override
List<T?>? readObjectOrNullList<T>(
int offset,
Deserialize<T> deserialize,
Map<Type, List<int>> allOffsets,
) {
final value = getProperty<dynamic>(object, offset);
return value is List
? value.map((e) {
if (e is Object) {
final reader = IsarReaderImpl(e);
return deserialize(0, reader, allOffsets[T]!, allOffsets);
} else {
return null;
}
}).toList()
: null;
}
}

View File

@@ -1,48 +0,0 @@
// ignore_for_file: unused_field, public_member_api_docs
import 'dart:async';
import 'package:isar/isar.dart';
import 'package:meta/meta.dart';
/// @nodoc
@protected
const Id isarMinId = -9007199254740990;
/// @nodoc
@protected
const Id isarMaxId = 9007199254740991;
/// @nodoc
@protected
const Id isarAutoIncrementId = -9007199254740991;
/// @nodoc
Never unsupportedOnWeb() {
throw UnsupportedError('This operation is not supported for Isar web');
}
class _WebAbi {
static const androidArm = null as dynamic;
static const androidArm64 = null as dynamic;
static const androidIA32 = null as dynamic;
static const androidX64 = null as dynamic;
static const iosArm64 = null as dynamic;
static const iosX64 = null as dynamic;
static const linuxArm64 = null as dynamic;
static const linuxX64 = null as dynamic;
static const macosArm64 = null as dynamic;
static const macosX64 = null as dynamic;
static const windowsArm64 = null as dynamic;
static const windowsX64 = null as dynamic;
}
/// @nodoc
@protected
typedef IsarAbi = _WebAbi;
FutureOr<void> initializeCoreBinary({
Map<IsarAbi, String> libraries = const {},
bool download = false,
}) =>
unsupportedOnWeb();

View File

@@ -1,171 +0,0 @@
// ignore_for_file: public_member_api_docs
import 'package:isar/isar.dart';
import 'package:isar/src/web/isar_reader_impl.dart';
import 'package:js/js_util.dart';
import 'package:meta/dart2js.dart';
class IsarWriterImpl implements IsarWriter {
IsarWriterImpl(this.object);
final Object object;
@tryInline
@override
void writeBool(int offset, bool? value) {
final number = value == true
? 1
: value == false
? 0
: nullNumber;
setProperty(object, offset, number);
}
@tryInline
@override
void writeByte(int offset, int value) {
setProperty(object, offset, value);
}
@tryInline
@override
void writeInt(int offset, int? value) {
setProperty(object, offset, value ?? nullNumber);
}
@tryInline
@override
void writeFloat(int offset, double? value) {
setProperty(object, offset, value ?? nullNumber);
}
@tryInline
@override
void writeLong(int offset, int? value) {
setProperty(object, offset, value ?? nullNumber);
}
@tryInline
@override
void writeDouble(int offset, double? value) {
setProperty(object, offset, value ?? nullNumber);
}
@tryInline
@override
void writeDateTime(int offset, DateTime? value) {
setProperty(
object,
offset,
value?.toUtc().millisecondsSinceEpoch ?? nullNumber,
);
}
@tryInline
@override
void writeString(int offset, String? value) {
setProperty(object, offset, value ?? nullNumber);
}
@tryInline
@override
void writeObject<T>(
int offset,
Map<Type, List<int>> allOffsets,
Serialize<T> serialize,
T? value,
) {
if (value != null) {
final object = newObject<Object>();
final writer = IsarWriterImpl(object);
serialize(value, writer, allOffsets[T]!, allOffsets);
setProperty(this.object, offset, object);
}
}
@tryInline
@override
void writeByteList(int offset, List<int>? values) {
setProperty(object, offset, values ?? nullNumber);
}
@tryInline
@override
void writeBoolList(int offset, List<bool?>? values) {
final list = values
?.map(
(e) => e == false
? 0
: e == true
? 1
: nullNumber,
)
.toList();
setProperty(object, offset, list ?? nullNumber);
}
@tryInline
@override
void writeIntList(int offset, List<int?>? values) {
final list = values?.map((e) => e ?? nullNumber).toList();
setProperty(object, offset, list ?? nullNumber);
}
@tryInline
@override
void writeFloatList(int offset, List<double?>? values) {
final list = values?.map((e) => e ?? nullNumber).toList();
setProperty(object, offset, list ?? nullNumber);
}
@tryInline
@override
void writeLongList(int offset, List<int?>? values) {
final list = values?.map((e) => e ?? nullNumber).toList();
setProperty(object, offset, list ?? nullNumber);
}
@tryInline
@override
void writeDoubleList(int offset, List<double?>? values) {
final list = values?.map((e) => e ?? nullNumber).toList();
setProperty(object, offset, list ?? nullNumber);
}
@tryInline
@override
void writeDateTimeList(int offset, List<DateTime?>? values) {
final list = values
?.map((e) => e?.toUtc().millisecondsSinceEpoch ?? nullNumber)
.toList();
setProperty(object, offset, list ?? nullNumber);
}
@tryInline
@override
void writeStringList(int offset, List<String?>? values) {
final list = values?.map((e) => e ?? nullNumber).toList();
setProperty(object, offset, list ?? nullNumber);
}
@tryInline
@override
void writeObjectList<T>(
int offset,
Map<Type, List<int>> allOffsets,
Serialize<T> serialize,
List<T?>? values,
) {
if (values != null) {
final list = values.map((e) {
if (e != null) {
final object = newObject<Object>();
final writer = IsarWriterImpl(object);
serialize(e, writer, allOffsets[T]!, allOffsets);
return object;
}
}).toList();
setProperty(object, offset, list);
}
}
}

View File

@@ -1,82 +0,0 @@
// ignore_for_file: public_member_api_docs, invalid_use_of_protected_member
import 'dart:html';
//import 'dart:js_util';
import 'package:isar/isar.dart';
/*import 'package:isar/src/common/schemas.dart';
import 'package:isar/src/web/bindings.dart';
import 'package:isar/src/web/isar_collection_impl.dart';
import 'package:isar/src/web/isar_impl.dart';*/
import 'package:isar/src/web/isar_web.dart';
import 'package:meta/meta.dart';
bool _loaded = false;
Future<void> initializeIsarWeb([String? jsUrl]) async {
if (_loaded) {
return;
}
_loaded = true;
final script = ScriptElement();
script.type = 'text/javascript';
// ignore: unsafe_html
script.src = 'https://unpkg.com/isar@${Isar.version}/dist/index.js';
script.async = true;
document.head!.append(script);
await script.onLoad.first.timeout(
const Duration(seconds: 30),
onTimeout: () {
throw IsarError('Failed to load Isar');
},
);
}
@visibleForTesting
void doNotInitializeIsarWeb() {
_loaded = true;
}
Future<Isar> openIsar({
required List<CollectionSchema<dynamic>> schemas,
String? directory,
required String name,
required int maxSizeMiB,
required bool relaxedDurability,
CompactCondition? compactOnLaunch,
}) async {
throw IsarError('Please use Isar 2.5.0 if you need web support. '
'A 3.x version with web support will be released soon.');
/*await initializeIsarWeb();
final schemasJson = getSchemas(schemas).map((e) => e.toJson());
final schemasJs = jsify(schemasJson.toList()) as List<dynamic>;
final instance = await openIsarJs(name, schemasJs, relaxedDurability)
.wait<IsarInstanceJs>();
final isar = IsarImpl(name, instance);
final cols = <Type, IsarCollection<dynamic>>{};
for (final schema in schemas) {
final col = instance.getCollection(schema.name);
schema.toCollection(<OBJ>() {
schema as CollectionSchema<OBJ>;
cols[OBJ] = IsarCollectionImpl<OBJ>(
isar: isar,
native: col,
schema: schema,
);
});
}
isar.attachCollections(cols);
return isar;*/
}
Isar openIsarSync({
required List<CollectionSchema<dynamic>> schemas,
String? directory,
required String name,
required int maxSizeMiB,
required bool relaxedDurability,
CompactCondition? compactOnLaunch,
}) =>
unsupportedOnWeb();

View File

@@ -1,375 +0,0 @@
// ignore_for_file: public_member_api_docs, invalid_use_of_protected_member
import 'dart:indexed_db';
import 'package:isar/isar.dart';
import 'package:isar/src/web/bindings.dart';
import 'package:isar/src/web/isar_collection_impl.dart';
import 'package:isar/src/web/isar_web.dart';
import 'package:isar/src/web/query_impl.dart';
Query<T> buildWebQuery<T, OBJ>(
IsarCollectionImpl<OBJ> col,
List<WhereClause> whereClauses,
bool whereDistinct,
Sort whereSort,
FilterOperation? filter,
List<SortProperty> sortBy,
List<DistinctProperty> distinctBy,
int? offset,
int? limit,
String? property,
) {
final whereClausesJs = whereClauses.map((wc) {
if (wc is IdWhereClause) {
return _buildIdWhereClause(wc);
} else if (wc is IndexWhereClause) {
return _buildIndexWhereClause(col.schema, wc);
} else {
return _buildLinkWhereClause(col, wc as LinkWhereClause);
}
}).toList();
final filterJs = filter != null ? _buildFilter(col.schema, filter) : null;
final sortJs = sortBy.isNotEmpty ? _buildSort(sortBy) : null;
final distinctJs = distinctBy.isNotEmpty ? _buildDistinct(distinctBy) : null;
final queryJs = QueryJs(
col.native,
whereClausesJs,
whereDistinct,
whereSort == Sort.asc,
filterJs,
sortJs,
distinctJs,
offset,
limit,
);
QueryDeserialize<T> deserialize;
//if (property == null) {
deserialize = col.deserializeObject as T Function(Object);
/*} else {
deserialize = (jsObj) => col.schema.deserializeProp(jsObj, property) as T;
}*/
return QueryImpl<T>(col, queryJs, deserialize, property);
}
dynamic _valueToJs(dynamic value) {
if (value == null) {
return double.negativeInfinity;
} else if (value == true) {
return 1;
} else if (value == false) {
return 0;
} else if (value is DateTime) {
return value.toUtc().millisecondsSinceEpoch;
} else if (value is List) {
return value.map(_valueToJs).toList();
} else {
return value;
}
}
IdWhereClauseJs _buildIdWhereClause(IdWhereClause wc) {
return IdWhereClauseJs()
..range = _buildKeyRange(
wc.lower,
wc.upper,
wc.includeLower,
wc.includeUpper,
);
}
IndexWhereClauseJs _buildIndexWhereClause(
CollectionSchema<dynamic> schema,
IndexWhereClause wc,
) {
final index = schema.index(wc.indexName);
final lower = wc.lower?.toList();
final upper = wc.upper?.toList();
if (upper != null) {
while (index.properties.length > upper.length) {
upper.add([]);
}
}
dynamic lowerUnwrapped = wc.lower;
if (index.properties.length == 1 && lower != null) {
lowerUnwrapped = lower.isNotEmpty ? lower[0] : null;
}
dynamic upperUnwrapped = upper;
if (index.properties.length == 1 && upper != null) {
upperUnwrapped = upper.isNotEmpty ? upper[0] : double.infinity;
}
return IndexWhereClauseJs()
..indexName = wc.indexName
..range = _buildKeyRange(
wc.lower != null ? _valueToJs(lowerUnwrapped) : null,
wc.upper != null ? _valueToJs(upperUnwrapped) : null,
wc.includeLower,
wc.includeUpper,
);
}
LinkWhereClauseJs _buildLinkWhereClause(
IsarCollectionImpl<dynamic> col,
LinkWhereClause wc,
) {
// ignore: unused_local_variable
final linkCol = col.isar.getCollectionByNameInternal(wc.linkCollection)!
as IsarCollectionImpl;
//final backlinkLinkName = linkCol.schema.backlinkLinkNames[wc.linkName];
return LinkWhereClauseJs()
..linkCollection = wc.linkCollection
//..linkName = backlinkLinkName ?? wc.linkName
//..backlink = backlinkLinkName != null
..id = wc.id;
}
KeyRange? _buildKeyRange(
dynamic lower,
dynamic upper,
bool includeLower,
bool includeUpper,
) {
if (lower != null) {
if (upper != null) {
final boundsEqual = idbCmp(lower, upper) == 0;
if (boundsEqual) {
if (includeLower && includeUpper) {
return KeyRange.only(lower);
} else {
// empty range
return KeyRange.upperBound(double.negativeInfinity, true);
}
}
return KeyRange.bound(
lower,
upper,
!includeLower,
!includeUpper,
);
} else {
return KeyRange.lowerBound(lower, !includeLower);
}
} else if (upper != null) {
return KeyRange.upperBound(upper, !includeUpper);
}
return null;
}
FilterJs? _buildFilter(
CollectionSchema<dynamic> schema,
FilterOperation filter,
) {
final filterStr = _buildFilterOperation(schema, filter);
if (filterStr != null) {
return FilterJs('id', 'obj', 'return $filterStr');
} else {
return null;
}
}
String? _buildFilterOperation(
CollectionSchema<dynamic> schema,
FilterOperation filter,
) {
if (filter is FilterGroup) {
return _buildFilterGroup(schema, filter);
} else if (filter is LinkFilter) {
unsupportedOnWeb();
} else if (filter is FilterCondition) {
return _buildCondition(schema, filter);
} else {
return null;
}
}
String? _buildFilterGroup(CollectionSchema<dynamic> schema, FilterGroup group) {
final builtConditions = group.filters
.map((op) => _buildFilterOperation(schema, op))
.where((e) => e != null)
.toList();
if (builtConditions.isEmpty) {
return null;
}
if (group.type == FilterGroupType.not) {
return '!(${builtConditions[0]})';
} else if (builtConditions.length == 1) {
return builtConditions[0];
} else if (group.type == FilterGroupType.xor) {
final conditions = builtConditions.join(',');
return 'IsarQuery.xor($conditions)';
} else {
final op = group.type == FilterGroupType.or ? '||' : '&&';
final condition = builtConditions.join(op);
return '($condition)';
}
}
String _buildCondition(
CollectionSchema<dynamic> schema,
FilterCondition condition,
) {
dynamic _prepareFilterValue(dynamic value) {
if (value == null) {
return null;
} else if (value is String) {
return stringify(value);
} else {
return _valueToJs(value);
}
}
final isListOp = condition.type != FilterConditionType.isNull &&
condition.type != FilterConditionType.listLength &&
schema.property(condition.property).type.isList;
final accessor =
condition.property == schema.idName ? 'id' : 'obj.${condition.property}';
final variable = isListOp ? 'e' : accessor;
final cond = _buildConditionInternal(
conditionType: condition.type,
variable: variable,
val1: _prepareFilterValue(condition.value1),
include1: condition.include1,
val2: _prepareFilterValue(condition.value2),
include2: condition.include2,
caseSensitive: condition.caseSensitive,
);
if (isListOp) {
return '(Array.isArray($accessor) && $accessor.some(e => $cond))';
} else {
return cond;
}
}
String _buildConditionInternal({
required FilterConditionType conditionType,
required String variable,
required Object? val1,
required bool include1,
required Object? val2,
required bool include2,
required bool caseSensitive,
}) {
final isNull = '($variable == null || $variable === -Infinity)';
switch (conditionType) {
case FilterConditionType.equalTo:
if (val1 == null) {
return isNull;
} else if (val1 is String && !caseSensitive) {
return '$variable?.toLowerCase() === ${val1.toLowerCase()}';
} else {
return '$variable === $val1';
}
case FilterConditionType.between:
final val = val1 ?? val2;
final lowerOp = include1 ? '>=' : '>';
final upperOp = include2 ? '<=' : '<';
if (val == null) {
return isNull;
} else if ((val1 is String?) && (val2 is String?) && !caseSensitive) {
final lower = val1?.toLowerCase() ?? '-Infinity';
final upper = val2?.toLowerCase() ?? '-Infinity';
final variableLc = '$variable?.toLowerCase() ?? -Infinity';
final lowerCond = 'indexedDB.cmp($variableLc, $lower) $lowerOp 0';
final upperCond = 'indexedDB.cmp($variableLc, $upper) $upperOp 0';
return '($lowerCond && $upperCond)';
} else {
final lowerCond =
'indexedDB.cmp($variable, ${val1 ?? '-Infinity'}) $lowerOp 0';
final upperCond =
'indexedDB.cmp($variable, ${val2 ?? '-Infinity'}) $upperOp 0';
return '($lowerCond && $upperCond)';
}
case FilterConditionType.lessThan:
if (val1 == null) {
if (include1) {
return isNull;
} else {
return 'false';
}
} else {
final op = include1 ? '<=' : '<';
if (val1 is String && !caseSensitive) {
return 'indexedDB.cmp($variable?.toLowerCase() ?? '
'-Infinity, ${val1.toLowerCase()}) $op 0';
} else {
return 'indexedDB.cmp($variable, $val1) $op 0';
}
}
case FilterConditionType.greaterThan:
if (val1 == null) {
if (include1) {
return 'true';
} else {
return '!$isNull';
}
} else {
final op = include1 ? '>=' : '>';
if (val1 is String && !caseSensitive) {
return 'indexedDB.cmp($variable?.toLowerCase() ?? '
'-Infinity, ${val1.toLowerCase()}) $op 0';
} else {
return 'indexedDB.cmp($variable, $val1) $op 0';
}
}
case FilterConditionType.startsWith:
case FilterConditionType.endsWith:
case FilterConditionType.contains:
final op = conditionType == FilterConditionType.startsWith
? 'startsWith'
: conditionType == FilterConditionType.endsWith
? 'endsWith'
: 'includes';
if (val1 is String) {
final isString = 'typeof $variable == "string"';
if (!caseSensitive) {
return '($isString && $variable.toLowerCase() '
'.$op(${val1.toLowerCase()}))';
} else {
return '($isString && $variable.$op($val1))';
}
} else {
throw IsarError('Unsupported type for condition');
}
case FilterConditionType.matches:
throw UnimplementedError();
case FilterConditionType.isNull:
return isNull;
// ignore: no_default_cases
default:
throw UnimplementedError();
}
}
SortCmpJs _buildSort(List<SortProperty> properties) {
final sort = properties.map((e) {
final op = e.sort == Sort.asc ? '' : '-';
return '${op}indexedDB.cmp(a.${e.property} ?? "-Infinity", b.${e.property} '
'?? "-Infinity")';
}).join('||');
return SortCmpJs('a', 'b', 'return $sort');
}
DistinctValueJs _buildDistinct(List<DistinctProperty> properties) {
final distinct = properties.map((e) {
if (e.caseSensitive == false) {
return 'obj.${e.property}?.toLowerCase() ?? "-Infinity"';
} else {
return 'obj.${e.property}?.toString() ?? "-Infinity"';
}
}).join('+');
return DistinctValueJs('obj', 'return $distinct');
}

View File

@@ -1,180 +0,0 @@
// ignore_for_file: public_member_api_docs
import 'dart:async';
import 'dart:convert';
import 'dart:js';
import 'dart:typed_data';
import 'package:isar/isar.dart';
import 'package:isar/src/web/bindings.dart';
import 'package:isar/src/web/isar_collection_impl.dart';
import 'package:isar/src/web/isar_web.dart';
typedef QueryDeserialize<T> = T Function(Object);
class QueryImpl<T> extends Query<T> {
QueryImpl(this.col, this.queryJs, this.deserialize, this.propertyName);
final IsarCollectionImpl<dynamic> col;
final QueryJs queryJs;
final QueryDeserialize<T> deserialize;
final String? propertyName;
@override
Isar get isar => col.isar;
@override
Future<T?> findFirst() {
return col.isar.getTxn(false, (IsarTxnJs txn) async {
final result = await queryJs.findFirst(txn).wait<Object?>();
if (result == null) {
return null;
}
return deserialize(result);
});
}
@override
T? findFirstSync() => unsupportedOnWeb();
@override
Future<List<T>> findAll() {
return col.isar.getTxn(false, (IsarTxnJs txn) async {
final result = await queryJs.findAll(txn).wait<List<dynamic>>();
return result.map((e) => deserialize(e as Object)).toList();
});
}
@override
List<T> findAllSync() => unsupportedOnWeb();
@override
Future<R?> aggregate<R>(AggregationOp op) {
return col.isar.getTxn(false, (IsarTxnJs txn) async {
final property = propertyName ?? col.schema.idName;
num? result;
switch (op) {
case AggregationOp.min:
result = await queryJs.min(txn, property).wait();
break;
case AggregationOp.max:
result = await queryJs.max(txn, property).wait();
break;
case AggregationOp.sum:
result = await queryJs.sum(txn, property).wait();
break;
case AggregationOp.average:
result = await queryJs.average(txn, property).wait();
break;
case AggregationOp.count:
result = await queryJs.count(txn).wait();
break;
// ignore: no_default_cases
default:
throw UnimplementedError();
}
if (result == null) {
return null;
}
if (R == DateTime) {
return DateTime.fromMillisecondsSinceEpoch(result.toInt()).toLocal()
as R;
} else if (R == int) {
return result.toInt() as R;
} else if (R == double) {
return result.toDouble() as R;
} else {
return null;
}
});
}
@override
R? aggregateSync<R>(AggregationOp op) => unsupportedOnWeb();
@override
Future<bool> deleteFirst() {
return col.isar.getTxn(true, (IsarTxnJs txn) {
return queryJs.deleteFirst(txn).wait();
});
}
@override
bool deleteFirstSync() => unsupportedOnWeb();
@override
Future<int> deleteAll() {
return col.isar.getTxn(true, (IsarTxnJs txn) {
return queryJs.deleteAll(txn).wait();
});
}
@override
int deleteAllSync() => unsupportedOnWeb();
@override
Stream<List<T>> watch({bool fireImmediately = false}) {
JsFunction? stop;
final controller = StreamController<List<T>>(
onCancel: () {
stop?.apply([]);
},
);
if (fireImmediately) {
findAll().then(controller.add);
}
final Null Function(List<dynamic> results) callback =
allowInterop((List<dynamic> results) {
controller.add(results.map((e) => deserialize(e as Object)).toList());
});
stop = col.native.watchQuery(queryJs, callback);
return controller.stream;
}
@override
Stream<void> watchLazy({bool fireImmediately = false}) {
JsFunction? stop;
final controller = StreamController<void>(
onCancel: () {
stop?.apply([]);
},
);
final Null Function() callback = allowInterop(() {
controller.add(null);
});
stop = col.native.watchQueryLazy(queryJs, callback);
return controller.stream;
}
@override
Future<R> exportJsonRaw<R>(R Function(Uint8List) callback) async {
return col.isar.getTxn(false, (IsarTxnJs txn) async {
final result = await queryJs.findAll(txn).wait<dynamic>();
final jsonStr = stringify(result);
return callback(const Utf8Encoder().convert(jsonStr));
});
}
@override
Future<List<Map<String, dynamic>>> exportJson() {
return col.isar.getTxn(false, (IsarTxnJs txn) async {
final result = await queryJs.findAll(txn).wait<List<dynamic>>();
return result.map((e) => jsMapToDart(e as Object)).toList();
});
}
@override
R exportJsonRawSync<R>(R Function(Uint8List) callback) => unsupportedOnWeb();
@override
List<Map<String, dynamic>> exportJsonSync({bool primitiveNull = true}) =>
unsupportedOnWeb();
}

View File

@@ -1,5 +0,0 @@
// ignore_for_file: public_member_api_docs
import 'package:isar/src/web/isar_web.dart';
List<String> isarSplitWords(String input) => unsupportedOnWeb();