@peerbit/indexer-tests 1.1.3 → 1.1.4-03739af

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/tests.ts CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  variant,
8
8
  vec,
9
9
  } from "@dao-xyz/borsh";
10
- import { randomBytes } from "@peerbit/crypto";
10
+ import { randomBytes, sha256Base64Sync } from "@peerbit/crypto";
11
11
  import {
12
12
  And,
13
13
  BoolQuery,
@@ -20,7 +20,6 @@ import {
20
20
  IntegerCompare,
21
21
  IsNull,
22
22
  type IterateOptions,
23
- Nested,
24
23
  Not,
25
24
  Or,
26
25
  Query,
@@ -289,7 +288,7 @@ export const tests = (
289
288
 
290
289
  afterEach(async () => {
291
290
  defaultDocs = [];
292
- await indices?.stop?.();
291
+ await indices?.drop?.();
293
292
  });
294
293
 
295
294
  describe("indexBy", () => {
@@ -492,8 +491,7 @@ export const tests = (
492
491
  });
493
492
  });
494
493
 
495
- /* TMP renable with sqlite support u64
496
- describe("bigint", () => {
494
+ describe("bigint", () => {
497
495
  class DocumentBigintId {
498
496
  @field({ type: "u64" })
499
497
  id: bigint;
@@ -518,7 +516,7 @@ export const tests = (
518
516
  });
519
517
  await testIndex(store, doc);
520
518
  });
521
- }); */
519
+ });
522
520
 
523
521
  describe("by decorator", () => {
524
522
  class DocumentWithDecoratedId {
@@ -913,38 +911,263 @@ export const tests = (
913
911
  @field({ type: vec(Document) })
914
912
  documents: Document[];
915
913
 
916
- constructor(properties?: { documents: Document[] }) {
914
+ constructor(properties?: {
915
+ id?: Uint8Array;
916
+ documents: Document[];
917
+ }) {
917
918
  this.id = randomBytes(32);
918
919
  this.documents = properties?.documents || [];
919
920
  }
920
921
  }
921
922
 
922
- it("can search", async () => {
923
- const out = await setup({ schema: DocumentsVec });
924
- store = out.store;
923
+ class DocumentWithProperty {
924
+ @field({ type: "string" })
925
+ property: string;
925
926
 
926
- const d1 = new DocumentsVec({
927
- documents: [
928
- new Document({ id: uuid(), number: 123n, tags: [] }),
929
- ],
930
- });
931
- await store.put(d1);
932
- await store.put(
933
- new DocumentsVec({
927
+ constructor(property: string) {
928
+ this.property = property;
929
+ }
930
+ }
931
+
932
+ class DocumentsVecWithPropertyDocument {
933
+ @field({ type: Uint8Array })
934
+ id: Uint8Array;
935
+
936
+ @field({ type: "string" })
937
+ property: string;
938
+
939
+ @field({ type: vec(DocumentWithProperty) })
940
+ documents: DocumentWithProperty[];
941
+
942
+ constructor(properties: {
943
+ id?: Uint8Array;
944
+ property: string;
945
+ documents: DocumentWithProperty[];
946
+ }) {
947
+ this.id = randomBytes(32);
948
+ this.property = properties.property;
949
+ this.documents = properties?.documents || [];
950
+ }
951
+ }
952
+
953
+ describe("search", () => {
954
+ let d1: DocumentsVec;
955
+ let d2: DocumentsVec;
956
+ let d3: DocumentsVec;
957
+
958
+ beforeEach(async () => {
959
+ const out = await setup({ schema: DocumentsVec });
960
+ store = out.store;
961
+
962
+ d1 = new DocumentsVec({
963
+ id: new Uint8Array([0]),
964
+ documents: [
965
+ new Document({ id: uuid(), number: 123n, tags: [] }),
966
+ ],
967
+ });
968
+ await store.put(d1);
969
+
970
+ d2 = new DocumentsVec({
971
+ id: new Uint8Array([1]),
934
972
  documents: [
935
973
  new Document({ id: uuid(), number: 124n, tags: [] }),
936
974
  ],
937
- }),
938
- );
975
+ });
939
976
 
940
- const results = await search(store, {
941
- query: new IntegerCompare({
942
- key: ["documents", "number"],
943
- compare: Compare.Equal,
944
- value: d1.documents[0]!.number,
945
- }),
977
+ await store.put(d2);
978
+
979
+ d3 = new DocumentsVec({
980
+ id: new Uint8Array([2]),
981
+ documents: [
982
+ new Document({ id: uuid(), number: 122n, tags: [] }),
983
+ new Document({ id: uuid(), number: 125n, tags: [] }),
984
+ ],
985
+ });
986
+
987
+ await store.put(d3);
988
+ });
989
+
990
+ it("match", async () => {
991
+ // equality
992
+ const results = await search(store, {
993
+ query: new IntegerCompare({
994
+ key: ["documents", "number"],
995
+ compare: Compare.Equal,
996
+ value: d1.documents[0]!.number,
997
+ }),
998
+ });
999
+ expect(results.map((x) => x.value.id)).to.deep.equal([d1.id]);
1000
+ });
1001
+
1002
+ describe("logical", () => {
1003
+ it("and", async () => {
1004
+ // can not be equal to two different things at once
1005
+ let results = await search(store, {
1006
+ query: [
1007
+ new And([
1008
+ new IntegerCompare({
1009
+ key: ["documents", "number"],
1010
+ compare: Compare.Equal,
1011
+ value: 123n,
1012
+ }),
1013
+ new IntegerCompare({
1014
+ key: ["documents", "number"],
1015
+ compare: Compare.Equal,
1016
+ value: 124n,
1017
+ }),
1018
+ ]),
1019
+ ],
1020
+ });
1021
+ expect(results).to.have.length(0);
1022
+
1023
+ // can not be between two different things at once
1024
+ results = await search(store, {
1025
+ query: [
1026
+ new And([
1027
+ new IntegerCompare({
1028
+ key: ["documents", "number"],
1029
+ compare: Compare.Less,
1030
+ value: 1000n,
1031
+ }),
1032
+ new IntegerCompare({
1033
+ key: ["documents", "number"],
1034
+ compare: Compare.Greater,
1035
+ value: 1000n,
1036
+ }),
1037
+ ]),
1038
+ ],
1039
+ });
1040
+ expect(results).to.have.length(0);
1041
+
1042
+ // between one value matches
1043
+ results = await search(store, {
1044
+ query: [
1045
+ new Or([
1046
+ new IntegerCompare({
1047
+ key: ["documents", "number"],
1048
+ compare: Compare.Less,
1049
+ value: 124n,
1050
+ }),
1051
+ new IntegerCompare({
1052
+ key: ["documents", "number"],
1053
+ compare: Compare.GreaterOrEqual,
1054
+ value: 125n,
1055
+ }),
1056
+ ]),
1057
+ ],
1058
+ });
1059
+
1060
+ // because each query is applied separately
1061
+ expect(
1062
+ results.map((x) => sha256Base64Sync(x.value.id)),
1063
+ ).to.have.members([d1.id, d3.id].map(sha256Base64Sync));
1064
+
1065
+ results = await search(store, {
1066
+ query: [
1067
+ new And([
1068
+ new IntegerCompare({
1069
+ key: ["documents", "number"],
1070
+ compare: Compare.Less,
1071
+ value: 124n,
1072
+ }),
1073
+ new IntegerCompare({
1074
+ key: ["documents", "number"],
1075
+ compare: Compare.GreaterOrEqual,
1076
+ value: 123n,
1077
+ }),
1078
+ ]),
1079
+ ],
1080
+ });
1081
+
1082
+ expect(results.map((x) => x.value.id)).to.deep.eq([d1.id]);
1083
+ });
1084
+
1085
+ it("or", async () => {
1086
+ const results3 = await search(store, {
1087
+ query: [
1088
+ new Or([
1089
+ new IntegerCompare({
1090
+ key: ["documents", "number"],
1091
+ compare: Compare.Equal,
1092
+ value: 123n,
1093
+ }),
1094
+ new IntegerCompare({
1095
+ key: ["documents", "number"],
1096
+ compare: Compare.Equal,
1097
+ value: 124n,
1098
+ }),
1099
+ ]),
1100
+ ],
1101
+ });
1102
+
1103
+ expect(
1104
+ results3.map((x) => sha256Base64Sync(x.value.id)),
1105
+ ).to.have.members([
1106
+ sha256Base64Sync(d1.id),
1107
+ sha256Base64Sync(d2.id),
1108
+ ]);
1109
+ });
1110
+
1111
+ it("many or", async () => {
1112
+ let conditions: IntegerCompare[] = [];
1113
+ for (let i = 0; i < 100; i++) {
1114
+ conditions.push(
1115
+ new IntegerCompare({
1116
+ key: ["documents", "number"],
1117
+ compare: Compare.Equal,
1118
+ value: 123n,
1119
+ }),
1120
+ );
1121
+ conditions.push(
1122
+ new IntegerCompare({
1123
+ key: ["documents", "number"],
1124
+ compare: Compare.Equal,
1125
+ value: 124n,
1126
+ }),
1127
+ );
1128
+ }
1129
+ const results3 = await search(store, {
1130
+ query: [new Or(conditions)],
1131
+ });
1132
+
1133
+ expect(
1134
+ results3.map((x) => sha256Base64Sync(x.value.id)),
1135
+ ).to.have.members([
1136
+ sha256Base64Sync(d1.id),
1137
+ sha256Base64Sync(d2.id),
1138
+ ]);
1139
+ });
1140
+
1141
+ it("or arr, or field", async () => {
1142
+ const results3 = await search(store, {
1143
+ query: [
1144
+ new Or([
1145
+ new IntegerCompare({
1146
+ key: ["documents", "number"],
1147
+ compare: Compare.Equal,
1148
+ value: 123n,
1149
+ }),
1150
+ new IntegerCompare({
1151
+ key: ["documents", "number"],
1152
+ compare: Compare.Equal,
1153
+ value: 124n,
1154
+ }),
1155
+ new ByteMatchQuery({
1156
+ key: "id",
1157
+ value: new Uint8Array([1]),
1158
+ }),
1159
+ ]),
1160
+ ],
1161
+ });
1162
+
1163
+ expect(
1164
+ results3.map((x) => sha256Base64Sync(x.value.id)),
1165
+ ).to.have.members([
1166
+ sha256Base64Sync(d1.id),
1167
+ sha256Base64Sync(d2.id),
1168
+ ]);
1169
+ });
946
1170
  });
947
- expect(results.map((x) => x.value.id)).to.deep.equal([d1.id]);
948
1171
  });
949
1172
 
950
1173
  it("update array", async () => {
@@ -1049,6 +1272,384 @@ export const tests = (
1049
1272
  ).length,
1050
1273
  ).to.equal(0);
1051
1274
  });
1275
+
1276
+ it("can use re-use same property name", async () => {
1277
+ const out = await setup({
1278
+ schema: DocumentsVecWithPropertyDocument,
1279
+ });
1280
+ store = out.store;
1281
+
1282
+ const d1 = new DocumentsVecWithPropertyDocument({
1283
+ property: "property 1",
1284
+ documents: [new DocumentWithProperty("nested property 1")],
1285
+ });
1286
+
1287
+ const d2 = new DocumentsVecWithPropertyDocument({
1288
+ property: "property 2",
1289
+ documents: [new DocumentWithProperty("nested property 2")],
1290
+ });
1291
+
1292
+ await store.put(d1);
1293
+ await store.put(d2);
1294
+
1295
+ const results = await search(store, {
1296
+ query: new StringMatch({
1297
+ key: "property",
1298
+ value: "property 1",
1299
+ caseInsensitive: false,
1300
+ }),
1301
+ });
1302
+
1303
+ expect(results).to.have.length(1);
1304
+ expect(results[0].value.property).to.equal("property 1");
1305
+
1306
+ const resultsNested = await search(store, {
1307
+ query: new StringMatch({
1308
+ key: ["documents", "property"],
1309
+ value: "nested property 2",
1310
+ caseInsensitive: false,
1311
+ }),
1312
+ });
1313
+
1314
+ expect(resultsNested).to.have.length(1);
1315
+ expect(resultsNested[0].value.property).to.equal("property 2");
1316
+ });
1317
+ });
1318
+
1319
+ describe("simple value", () => {
1320
+ class ArrayDocument {
1321
+ @field({ type: Uint8Array })
1322
+ id: Uint8Array;
1323
+
1324
+ @field({ type: vec("u32") })
1325
+ array: number[];
1326
+
1327
+ constructor(properties?: { id?: Uint8Array; array: number[] }) {
1328
+ this.id = properties.id || randomBytes(32);
1329
+ this.array = properties?.array || [];
1330
+ }
1331
+ }
1332
+
1333
+ describe("search", () => {
1334
+ let d1: ArrayDocument;
1335
+ let d2: ArrayDocument;
1336
+ let d3: ArrayDocument;
1337
+
1338
+ beforeEach(async () => {
1339
+ const out = await setup({ schema: ArrayDocument });
1340
+ store = out.store;
1341
+
1342
+ d1 = new ArrayDocument({
1343
+ id: new Uint8Array([0]),
1344
+ array: [1],
1345
+ });
1346
+ await store.put(d1);
1347
+
1348
+ d2 = new ArrayDocument({
1349
+ id: new Uint8Array([1]),
1350
+ array: [2],
1351
+ });
1352
+
1353
+ await store.put(d2);
1354
+
1355
+ d3 = new ArrayDocument({
1356
+ id: new Uint8Array([2]),
1357
+ array: [0, 3],
1358
+ });
1359
+
1360
+ await store.put(d3);
1361
+ });
1362
+
1363
+ it("match", async () => {
1364
+ // equality
1365
+ const results = await search(store, {
1366
+ query: new IntegerCompare({
1367
+ key: ["array"],
1368
+ compare: Compare.Equal,
1369
+ value: d1.array[0]!,
1370
+ }),
1371
+ });
1372
+ expect(results.map((x) => x.value.id)).to.deep.equal([d1.id]);
1373
+ });
1374
+
1375
+ describe("logical", () => {
1376
+ it("and", async () => {
1377
+ // can not be equal to two different things at once
1378
+ let results = await search(store, {
1379
+ query: [
1380
+ new And([
1381
+ new IntegerCompare({
1382
+ key: ["array"],
1383
+ compare: Compare.Equal,
1384
+ value: d1.array[0]!,
1385
+ }),
1386
+ new IntegerCompare({
1387
+ key: ["array"],
1388
+ compare: Compare.Equal,
1389
+ value: d2.array[0]!,
1390
+ }),
1391
+ ]),
1392
+ ],
1393
+ });
1394
+ expect(results).to.have.length(0);
1395
+
1396
+ // can not be between two different things at once
1397
+ results = await search(store, {
1398
+ query: [
1399
+ new And([
1400
+ new IntegerCompare({
1401
+ key: ["array"],
1402
+ compare: Compare.Less,
1403
+ value: 1000,
1404
+ }),
1405
+ new IntegerCompare({
1406
+ key: ["array"],
1407
+ compare: Compare.Greater,
1408
+ value: 1000,
1409
+ }),
1410
+ ]),
1411
+ ],
1412
+ });
1413
+ expect(results).to.have.length(0);
1414
+
1415
+ // between one value matches
1416
+ results = await search(store, {
1417
+ query: [
1418
+ new Or([
1419
+ new IntegerCompare({
1420
+ key: ["array"],
1421
+ compare: Compare.Less,
1422
+ value: 2,
1423
+ }),
1424
+ new IntegerCompare({
1425
+ key: ["array"],
1426
+ compare: Compare.GreaterOrEqual,
1427
+ value: 3,
1428
+ }),
1429
+ ]),
1430
+ ],
1431
+ });
1432
+
1433
+ // because each query is applied separately
1434
+ expect(
1435
+ results.map((x) => sha256Base64Sync(x.value.id)),
1436
+ ).to.have.members([d1.id, d3.id].map(sha256Base64Sync));
1437
+
1438
+ results = await search(store, {
1439
+ query: [
1440
+ new And([
1441
+ new IntegerCompare({
1442
+ key: ["array"],
1443
+ compare: Compare.Less,
1444
+ value: 2,
1445
+ }),
1446
+ new IntegerCompare({
1447
+ key: ["array"],
1448
+ compare: Compare.GreaterOrEqual,
1449
+ value: 1,
1450
+ }),
1451
+ ]),
1452
+ ],
1453
+ });
1454
+
1455
+ // using nested path will apply the queries together
1456
+ expect(
1457
+ results.map((x) => sha256Base64Sync(x.value.id)),
1458
+ ).to.have.members([d1.id].map(sha256Base64Sync));
1459
+ });
1460
+
1461
+ it("or", async () => {
1462
+ const results3 = await search(store, {
1463
+ query: [
1464
+ new Or([
1465
+ new IntegerCompare({
1466
+ key: ["array"],
1467
+ compare: Compare.Equal,
1468
+ value: d1.array[0]!,
1469
+ }),
1470
+ new IntegerCompare({
1471
+ key: ["array"],
1472
+ compare: Compare.Equal,
1473
+ value: d3.array[0]!,
1474
+ }),
1475
+ ]),
1476
+ ],
1477
+ });
1478
+
1479
+ expect(
1480
+ results3.map((x) => sha256Base64Sync(x.value.id)),
1481
+ ).to.have.members([
1482
+ sha256Base64Sync(d1.id),
1483
+ sha256Base64Sync(d3.id),
1484
+ ]);
1485
+ });
1486
+
1487
+ it("or array, or field", async () => {
1488
+ const results3 = await search(store, {
1489
+ query: [
1490
+ new Or([
1491
+ new And([
1492
+ new IntegerCompare({
1493
+ key: ["array"],
1494
+ compare: Compare.LessOrEqual,
1495
+ value: 0,
1496
+ }),
1497
+ new IntegerCompare({
1498
+ key: ["array"],
1499
+ compare: Compare.LessOrEqual,
1500
+ value: 1,
1501
+ }),
1502
+ ]),
1503
+ new ByteMatchQuery({
1504
+ key: "id",
1505
+ value: new Uint8Array([0]),
1506
+ }),
1507
+ ]),
1508
+ ],
1509
+ });
1510
+
1511
+ expect(
1512
+ results3.map((x) => sha256Base64Sync(x.value.id)),
1513
+ ).to.have.members([
1514
+ sha256Base64Sync(d1.id),
1515
+ sha256Base64Sync(d3.id),
1516
+ ]);
1517
+ });
1518
+
1519
+ it("or all", async () => {
1520
+ const results = await search(store, {
1521
+ query: [
1522
+ new Or([
1523
+ new Or([
1524
+ new And([
1525
+ new IntegerCompare({
1526
+ key: ["array"],
1527
+ compare: Compare.GreaterOrEqual,
1528
+ value: 0,
1529
+ }),
1530
+ ]),
1531
+ new And([
1532
+ new IntegerCompare({
1533
+ key: ["array"],
1534
+ compare: Compare.GreaterOrEqual,
1535
+ value: 0,
1536
+ }),
1537
+ ]),
1538
+ ]),
1539
+ new IntegerCompare({
1540
+ key: ["array"],
1541
+ compare: Compare.GreaterOrEqual,
1542
+ value: 0,
1543
+ }),
1544
+ ]),
1545
+ ],
1546
+ });
1547
+
1548
+ expect(
1549
+ results.map((x) => sha256Base64Sync(x.value.id)),
1550
+ ).to.have.members([
1551
+ sha256Base64Sync(d1.id),
1552
+ sha256Base64Sync(d2.id),
1553
+ sha256Base64Sync(d3.id),
1554
+ ]);
1555
+ });
1556
+ });
1557
+ });
1558
+
1559
+ it("update array", async () => {
1560
+ const out = await setup({ schema: ArrayDocument });
1561
+ store = out.store;
1562
+
1563
+ const d1 = new ArrayDocument({
1564
+ array: [123],
1565
+ });
1566
+ await store.put(d1);
1567
+
1568
+ d1.array = [124];
1569
+
1570
+ await store.put(d1);
1571
+
1572
+ // should have update results
1573
+ expect(
1574
+ (
1575
+ await search(store, {
1576
+ query: new IntegerCompare({
1577
+ key: ["array"],
1578
+ compare: Compare.Equal,
1579
+ value: 123,
1580
+ }),
1581
+ })
1582
+ ).length,
1583
+ ).to.equal(0);
1584
+
1585
+ expect(
1586
+ (
1587
+ await search(store, {
1588
+ query: new IntegerCompare({
1589
+ key: ["array"],
1590
+ compare: Compare.Equal,
1591
+ value: 124,
1592
+ }),
1593
+ })
1594
+ ).map((x) => x.value.id),
1595
+ ).to.deep.equal([d1.id]);
1596
+ });
1597
+
1598
+ it("put delete put", async () => {
1599
+ const { store } = await setup({ schema: ArrayDocument });
1600
+
1601
+ const d1 = new ArrayDocument({
1602
+ array: [123],
1603
+ });
1604
+
1605
+ await store.put(d1);
1606
+ const [deleted] = await store.del({
1607
+ query: {
1608
+ id: d1.id,
1609
+ },
1610
+ });
1611
+
1612
+ expect(deleted.key).to.deep.equal(d1.id);
1613
+
1614
+ expect(
1615
+ (
1616
+ await search(store, {
1617
+ query: new IntegerCompare({
1618
+ key: ["array"],
1619
+ compare: Compare.Equal,
1620
+ value: 123,
1621
+ }),
1622
+ })
1623
+ ).length,
1624
+ ).to.equal(0);
1625
+
1626
+ d1.array = [124];
1627
+ await store.put(d1);
1628
+
1629
+ expect(
1630
+ (
1631
+ await search(store, {
1632
+ query: new IntegerCompare({
1633
+ key: ["array"],
1634
+ compare: Compare.Equal,
1635
+ value: 124,
1636
+ }),
1637
+ })
1638
+ ).map((x) => x.value.id),
1639
+ ).to.deep.equal([d1.id]);
1640
+
1641
+ expect(
1642
+ (
1643
+ await search(store, {
1644
+ query: new IntegerCompare({
1645
+ key: ["array"],
1646
+ compare: Compare.Equal,
1647
+ value: 123,
1648
+ }),
1649
+ })
1650
+ ).length,
1651
+ ).to.equal(0);
1652
+ });
1052
1653
  });
1053
1654
  });
1054
1655
 
@@ -1134,7 +1735,7 @@ export const tests = (
1134
1735
  new IntegerCompare({
1135
1736
  key: "number",
1136
1737
  compare: Compare.Equal,
1137
- value: 2n,
1738
+ value: 2,
1138
1739
  }),
1139
1740
  ],
1140
1741
  });
@@ -1148,7 +1749,7 @@ export const tests = (
1148
1749
  new IntegerCompare({
1149
1750
  key: "number",
1150
1751
  compare: Compare.Greater,
1151
- value: 2n,
1752
+ value: 2,
1152
1753
  }),
1153
1754
  ],
1154
1755
  });
@@ -1162,7 +1763,7 @@ export const tests = (
1162
1763
  new IntegerCompare({
1163
1764
  key: "number",
1164
1765
  compare: Compare.GreaterOrEqual,
1165
- value: 2n,
1766
+ value: 2,
1166
1767
  }),
1167
1768
  ],
1168
1769
  });
@@ -1180,7 +1781,7 @@ export const tests = (
1180
1781
  new IntegerCompare({
1181
1782
  key: "number",
1182
1783
  compare: Compare.Less,
1183
- value: 2n,
1784
+ value: 2,
1184
1785
  }),
1185
1786
  ],
1186
1787
  });
@@ -1205,6 +1806,20 @@ export const tests = (
1205
1806
  expect(response[0].value.number).to.be.oneOf([1n, 1]);
1206
1807
  expect(response[1].value.number).to.be.oneOf([2n, 2]);
1207
1808
  });
1809
+
1810
+ it("bigint as compare value", async () => {
1811
+ const response = await search(store, {
1812
+ query: [
1813
+ new IntegerCompare({
1814
+ key: "number",
1815
+ compare: Compare.Less,
1816
+ value: 2n,
1817
+ }),
1818
+ ],
1819
+ });
1820
+ expect(response).to.have.length(1);
1821
+ expect(response[0].value.number).to.be.oneOf([1n, 1]);
1822
+ });
1208
1823
  });
1209
1824
 
1210
1825
  describe("bigint", () => {
@@ -1315,6 +1930,19 @@ export const tests = (
1315
1930
  expect(response[0].value.bigint).to.equal(first);
1316
1931
  expect(response[1].value.bigint).to.equal(second);
1317
1932
  });
1933
+
1934
+ it("number as compare value", async () => {
1935
+ const response = await search(store, {
1936
+ query: [
1937
+ new IntegerCompare({
1938
+ key: "bigint",
1939
+ compare: Compare.Greater,
1940
+ value: 1,
1941
+ }),
1942
+ ],
1943
+ });
1944
+ expect(response).to.have.length(3);
1945
+ });
1318
1946
  });
1319
1947
 
1320
1948
  describe("nested", () => {
@@ -1350,6 +1978,31 @@ export const tests = (
1350
1978
  await setup({ schema: DocumentWithNesting });
1351
1979
  });
1352
1980
 
1981
+ it("all", async () => {
1982
+ await store.put(
1983
+ new DocumentWithNesting({
1984
+ id: "1",
1985
+ nested: new Nested({ number: 1n, bool: false }),
1986
+ }),
1987
+ );
1988
+
1989
+ await store.put(
1990
+ new DocumentWithNesting({
1991
+ id: "2",
1992
+ nested: undefined,
1993
+ }),
1994
+ );
1995
+
1996
+ const all = await search(store, {});
1997
+ expect(all).to.have.length(2);
1998
+ expect(all.map((x) => x.id.primitive)).to.have.members([
1999
+ "1",
2000
+ "2",
2001
+ ]);
2002
+ expect(all[0].value.nested).to.be.instanceOf(Nested);
2003
+ expect(all[1].value.nested).to.be.undefined;
2004
+ });
2005
+
1353
2006
  it("number", async () => {
1354
2007
  await store.put(
1355
2008
  new DocumentWithNesting({
@@ -2098,21 +2751,16 @@ export const tests = (
2098
2751
  );
2099
2752
 
2100
2753
  const response = await search(store, {
2101
- query: [
2102
- new Nested({
2103
- path: "array",
2104
- query: new And([
2105
- new StringMatch({
2106
- key: "a",
2107
- value: "hello",
2108
- }),
2109
- new StringMatch({
2110
- key: "b",
2111
- value: "world",
2112
- }),
2113
- ]),
2754
+ query: new And([
2755
+ new StringMatch({
2756
+ key: ["array", "a"],
2757
+ value: "hello",
2114
2758
  }),
2115
- ],
2759
+ new StringMatch({
2760
+ key: ["array", "b"],
2761
+ value: "world",
2762
+ }),
2763
+ ]),
2116
2764
  });
2117
2765
 
2118
2766
  expect(response).to.have.length(1);
@@ -2132,24 +2780,40 @@ export const tests = (
2132
2780
  }),
2133
2781
  ],
2134
2782
  });
2783
+ const doc2 = new NestedMultipleFieldsArrayDocument({
2784
+ id: "2",
2785
+ array: [
2786
+ new NestedMultipleFieldsDocument({
2787
+ a: "hello",
2788
+ b: "värld",
2789
+ }),
2790
+ new NestedMultipleFieldsDocument({
2791
+ a: "hej",
2792
+ b: "world",
2793
+ }),
2794
+ ],
2795
+ });
2796
+
2797
+ const doc3 = new NestedMultipleFieldsArrayDocument({
2798
+ id: "3",
2799
+ array: [
2800
+ new NestedMultipleFieldsDocument({
2801
+ a: "_",
2802
+ b: "_",
2803
+ }),
2804
+ new NestedMultipleFieldsDocument({
2805
+ a: "_",
2806
+ b: "_",
2807
+ }),
2808
+ ],
2809
+ });
2810
+
2135
2811
  await store.put(doc1);
2136
- await store.put(
2137
- new NestedMultipleFieldsArrayDocument({
2138
- id: "2",
2139
- array: [
2140
- new NestedMultipleFieldsDocument({
2141
- a: "hello",
2142
- b: "värld",
2143
- }),
2144
- new NestedMultipleFieldsDocument({
2145
- a: "hej",
2146
- b: "world",
2147
- }),
2148
- ],
2149
- }),
2150
- );
2812
+ await store.put(doc2);
2813
+ await store.put(doc3);
2151
2814
 
2152
- const response = await search(store, {
2815
+ // AND will only yield doc 1 since only doc 1 contains the combination below
2816
+ const responseAnd = await search(store, {
2153
2817
  query: [
2154
2818
  new StringMatch({
2155
2819
  key: ["array", "a"],
@@ -2162,8 +2826,28 @@ export const tests = (
2162
2826
  ],
2163
2827
  });
2164
2828
 
2829
+ expect(responseAnd).to.have.length(1);
2830
+ checkDocument(responseAnd[0].value, doc1);
2831
+
2832
+ // OR will only yield doc 1 and doc 2 since both will fulfill one of two conditions
2833
+ const response = await search(store, {
2834
+ query: [
2835
+ new Or([
2836
+ new StringMatch({
2837
+ key: ["array", "a"],
2838
+ value: "hello",
2839
+ }),
2840
+ new StringMatch({
2841
+ key: ["array", "b"],
2842
+ value: "world",
2843
+ }),
2844
+ ]),
2845
+ ],
2846
+ });
2165
2847
  expect(response).to.have.length(2);
2848
+
2166
2849
  checkDocument(response[0].value, doc1);
2850
+ checkDocument(response[1].value, doc2);
2167
2851
  });
2168
2852
  });
2169
2853
  });
@@ -2695,11 +3379,14 @@ export const tests = (
2695
3379
  });
2696
3380
 
2697
3381
  describe("sort", () => {
2698
- const put = async (id: number, stringId?: string) => {
3382
+ const put = async (
3383
+ id: number,
3384
+ options?: { name?: string; number?: bigint },
3385
+ ) => {
2699
3386
  const doc = new Document({
2700
- id: stringId ?? String(id),
2701
- name: String(id),
2702
- number: BigInt(id),
3387
+ id: String(id),
3388
+ name: options?.name ?? String(id),
3389
+ number: options?.number ?? BigInt(id),
2703
3390
  tags: [],
2704
3391
  });
2705
3392
  const resp = await store.put(doc);
@@ -2868,12 +3555,12 @@ export const tests = (
2868
3555
 
2869
3556
  /* it("no sort is stable", async () => {
2870
3557
  // TODO this test is actually not a good predictor of stability
2871
-
3558
+
2872
3559
  const insertCount = 500;
2873
3560
  for (let i = 0; i < insertCount; i++) {
2874
3561
  await put(i, uuid());
2875
3562
  }
2876
-
3563
+
2877
3564
  const resolvedValues: Set<number> = new Set()
2878
3565
  const batchSize = 123;
2879
3566
  const iterator = store.iterate();
@@ -2899,6 +3586,25 @@ export const tests = (
2899
3586
  await assertIteratorIsDone(iterator);
2900
3587
  });
2901
3588
 
3589
+ it("sort by multiple properties", async () => {
3590
+ await put(0, { name: "a", number: 2n });
3591
+ await put(1, { name: "a", number: 1n });
3592
+
3593
+ await put(2, { name: "b", number: 2n });
3594
+ await put(3, { name: "b", number: 1n });
3595
+
3596
+ const iterator = store.iterate({
3597
+ query: [],
3598
+ sort: [
3599
+ new Sort({ direction: SortDirection.DESC, key: "name" }),
3600
+ new Sort({ direction: SortDirection.ASC, key: "number" }),
3601
+ ],
3602
+ });
3603
+
3604
+ const out = await iterator.all();
3605
+ expect(out.map((x) => x.value.id)).to.deep.equal(["3", "2", "1", "0"]);
3606
+ });
3607
+
2902
3608
  describe("nested", () => {
2903
3609
  it("variants", async () => {
2904
3610
  const doc1 = new Document({
@@ -3397,6 +4103,8 @@ export const tests = (
3397
4103
  });
3398
4104
 
3399
4105
  it("indices", async () => {
4106
+ // TODO make this test more clear and the purpose of each call
4107
+
3400
4108
  let { directory, indices } = await setupDefault();
3401
4109
 
3402
4110
  let subindex = await indices.scope("x");
@@ -3419,7 +4127,11 @@ export const tests = (
3419
4127
 
3420
4128
  await indices.drop();
3421
4129
 
3422
- await store.start();
4130
+ const out = await setup({ schema: Document }, directory);
4131
+ indices = out.indices;
4132
+ await indices.start();
4133
+
4134
+ store = out.store;
3423
4135
 
3424
4136
  expect(await store.getSize()).equal(0);
3425
4137
 
@@ -3428,7 +4140,6 @@ export const tests = (
3428
4140
 
3429
4141
  store = (await setup({ schema: Document }, directory)).store;
3430
4142
 
3431
- await store.start();
3432
4143
  expect(await store.getSize()).equal(0);
3433
4144
  });
3434
4145
  });