@peerbit/indexer-tests 3.0.4 → 3.0.6

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.
@@ -0,0 +1,3 @@
1
+ import { type Indices } from "@peerbit/indexer-interface";
2
+ export declare const tieParityTests: (createIndicies: (directory?: string) => Indices | Promise<Indices>) => Mocha.Suite;
3
+ //# sourceMappingURL=tie-parity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tie-parity.d.ts","sourceRoot":"","sources":["../../src/tie-parity.ts"],"names":[],"mappings":"AACA,OAAO,EACN,KAAK,OAAO,EAKZ,MAAM,4BAA4B,CAAC;AAiEpC,eAAO,MAAM,cAAc,GAC1B,gBAAgB,CAAC,SAAS,CAAC,EAAE,MAAM,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,gBAgElE,CAAC"}
@@ -0,0 +1,214 @@
1
+ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
2
+ function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
3
+ var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
4
+ var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
5
+ var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
6
+ var _, done = false;
7
+ for (var i = decorators.length - 1; i >= 0; i--) {
8
+ var context = {};
9
+ for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
10
+ for (var p in contextIn.access) context.access[p] = contextIn.access[p];
11
+ context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
12
+ var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
13
+ if (kind === "accessor") {
14
+ if (result === void 0) continue;
15
+ if (result === null || typeof result !== "object") throw new TypeError("Object expected");
16
+ if (_ = accept(result.get)) descriptor.get = _;
17
+ if (_ = accept(result.set)) descriptor.set = _;
18
+ if (_ = accept(result.init)) initializers.unshift(_);
19
+ }
20
+ else if (_ = accept(result)) {
21
+ if (kind === "field") initializers.unshift(_);
22
+ else descriptor[key] = _;
23
+ }
24
+ }
25
+ if (target) Object.defineProperty(target, contextIn.name, descriptor);
26
+ done = true;
27
+ };
28
+ var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
29
+ var useValue = arguments.length > 2;
30
+ for (var i = 0; i < initializers.length; i++) {
31
+ value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
32
+ }
33
+ return useValue ? value : void 0;
34
+ };
35
+ import { field, variant } from "@dao-xyz/borsh";
36
+ import { Sort, SortDirection, getIdProperty, id, } from "@peerbit/indexer-interface";
37
+ import { expect } from "chai";
38
+ // Cross-backend SORT TIE-BREAK parity: @peerbit/indexer-simple (HashmapIndex) and
39
+ // @peerbit/indexer-sqlite3 must break ties on equal sort keys IDENTICALLY, in the
40
+ // document primary-key id's natural typed order:
41
+ // - string ids -> UTF-8 byte order (sqlite TEXT / BINARY collation)
42
+ // - integer ids -> NUMERIC order (sqlite INTEGER: 2 < 10, not "10" < "2")
43
+ // - Uint8Array ids -> raw-byte memcmp (sqlite BLOB: 0x00 < 0xff, not base64)
44
+ // and REVERSE that id order when the (single) sort field is DESC.
45
+ //
46
+ // Every document shares sortKey=1 so the whole result set is one tie group, which
47
+ // forces the id tie-break for every row. Simple historically ordered ties by
48
+ // INSERTION order (direction-independent), matching neither sqlite nor a stable
49
+ // content order; this suite locks simple == sqlite.
50
+ let StringIdDoc = (() => {
51
+ let _classDecorators = [variant("tie_str")];
52
+ let _classDescriptor;
53
+ let _classExtraInitializers = [];
54
+ let _classThis;
55
+ let _id_decorators;
56
+ let _id_initializers = [];
57
+ let _id_extraInitializers = [];
58
+ let _sortKey_decorators;
59
+ let _sortKey_initializers = [];
60
+ let _sortKey_extraInitializers = [];
61
+ var StringIdDoc = class {
62
+ static { _classThis = this; }
63
+ static {
64
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
65
+ _id_decorators = [id({ type: "string" })];
66
+ _sortKey_decorators = [field({ type: "u32" })];
67
+ __esDecorate(null, null, _id_decorators, { kind: "field", name: "id", static: false, private: false, access: { has: obj => "id" in obj, get: obj => obj.id, set: (obj, value) => { obj.id = value; } }, metadata: _metadata }, _id_initializers, _id_extraInitializers);
68
+ __esDecorate(null, null, _sortKey_decorators, { kind: "field", name: "sortKey", static: false, private: false, access: { has: obj => "sortKey" in obj, get: obj => obj.sortKey, set: (obj, value) => { obj.sortKey = value; } }, metadata: _metadata }, _sortKey_initializers, _sortKey_extraInitializers);
69
+ __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
70
+ StringIdDoc = _classThis = _classDescriptor.value;
71
+ if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
72
+ __runInitializers(_classThis, _classExtraInitializers);
73
+ }
74
+ id = __runInitializers(this, _id_initializers, void 0);
75
+ sortKey = (__runInitializers(this, _id_extraInitializers), __runInitializers(this, _sortKey_initializers, void 0));
76
+ constructor(id) {
77
+ __runInitializers(this, _sortKey_extraInitializers);
78
+ this.id = id;
79
+ this.sortKey = 1;
80
+ }
81
+ };
82
+ return StringIdDoc = _classThis;
83
+ })();
84
+ let BigIntIdDoc = (() => {
85
+ let _classDecorators = [variant("tie_bigint")];
86
+ let _classDescriptor;
87
+ let _classExtraInitializers = [];
88
+ let _classThis;
89
+ let _id_decorators;
90
+ let _id_initializers = [];
91
+ let _id_extraInitializers = [];
92
+ let _sortKey_decorators;
93
+ let _sortKey_initializers = [];
94
+ let _sortKey_extraInitializers = [];
95
+ var BigIntIdDoc = class {
96
+ static { _classThis = this; }
97
+ static {
98
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
99
+ _id_decorators = [id({ type: "u64" })];
100
+ _sortKey_decorators = [field({ type: "u32" })];
101
+ __esDecorate(null, null, _id_decorators, { kind: "field", name: "id", static: false, private: false, access: { has: obj => "id" in obj, get: obj => obj.id, set: (obj, value) => { obj.id = value; } }, metadata: _metadata }, _id_initializers, _id_extraInitializers);
102
+ __esDecorate(null, null, _sortKey_decorators, { kind: "field", name: "sortKey", static: false, private: false, access: { has: obj => "sortKey" in obj, get: obj => obj.sortKey, set: (obj, value) => { obj.sortKey = value; } }, metadata: _metadata }, _sortKey_initializers, _sortKey_extraInitializers);
103
+ __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
104
+ BigIntIdDoc = _classThis = _classDescriptor.value;
105
+ if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
106
+ __runInitializers(_classThis, _classExtraInitializers);
107
+ }
108
+ id = __runInitializers(this, _id_initializers, void 0);
109
+ sortKey = (__runInitializers(this, _id_extraInitializers), __runInitializers(this, _sortKey_initializers, void 0));
110
+ constructor(id) {
111
+ __runInitializers(this, _sortKey_extraInitializers);
112
+ this.id = id;
113
+ this.sortKey = 1;
114
+ }
115
+ };
116
+ return BigIntIdDoc = _classThis;
117
+ })();
118
+ let BytesIdDoc = (() => {
119
+ let _classDecorators = [variant("tie_bytes")];
120
+ let _classDescriptor;
121
+ let _classExtraInitializers = [];
122
+ let _classThis;
123
+ let _id_decorators;
124
+ let _id_initializers = [];
125
+ let _id_extraInitializers = [];
126
+ let _sortKey_decorators;
127
+ let _sortKey_initializers = [];
128
+ let _sortKey_extraInitializers = [];
129
+ var BytesIdDoc = class {
130
+ static { _classThis = this; }
131
+ static {
132
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
133
+ _id_decorators = [id({ type: Uint8Array })];
134
+ _sortKey_decorators = [field({ type: "u32" })];
135
+ __esDecorate(null, null, _id_decorators, { kind: "field", name: "id", static: false, private: false, access: { has: obj => "id" in obj, get: obj => obj.id, set: (obj, value) => { obj.id = value; } }, metadata: _metadata }, _id_initializers, _id_extraInitializers);
136
+ __esDecorate(null, null, _sortKey_decorators, { kind: "field", name: "sortKey", static: false, private: false, access: { has: obj => "sortKey" in obj, get: obj => obj.sortKey, set: (obj, value) => { obj.sortKey = value; } }, metadata: _metadata }, _sortKey_initializers, _sortKey_extraInitializers);
137
+ __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
138
+ BytesIdDoc = _classThis = _classDescriptor.value;
139
+ if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
140
+ __runInitializers(_classThis, _classExtraInitializers);
141
+ }
142
+ id = __runInitializers(this, _id_initializers, void 0);
143
+ sortKey = (__runInitializers(this, _id_extraInitializers), __runInitializers(this, _sortKey_initializers, void 0));
144
+ constructor(id) {
145
+ __runInitializers(this, _sortKey_extraInitializers);
146
+ this.id = id;
147
+ this.sortKey = 1;
148
+ }
149
+ };
150
+ return BytesIdDoc = _classThis;
151
+ })();
152
+ const fmt = (value) => value instanceof Uint8Array
153
+ ? Array.from(value)
154
+ .map((x) => x.toString(16).padStart(2, "0"))
155
+ .join("")
156
+ : String(value);
157
+ export const tieParityTests = (createIndicies) => {
158
+ return describe("sort tie-break parity", () => {
159
+ let indices;
160
+ afterEach(async () => {
161
+ await indices?.stop?.();
162
+ await indices?.drop?.();
163
+ indices = undefined;
164
+ });
165
+ const collect = async (schema, docs) => {
166
+ indices = await createIndicies();
167
+ await indices.start();
168
+ const store = await indices.init({
169
+ schema,
170
+ indexBy: getIdProperty(schema) || ["id"],
171
+ });
172
+ for (const doc of docs) {
173
+ await store.put(doc);
174
+ }
175
+ const order = async (direction) => {
176
+ const results = await store
177
+ .iterate({
178
+ query: [],
179
+ sort: [new Sort({ key: "sortKey", direction })],
180
+ })
181
+ .all();
182
+ return results.map((r) => fmt(r.value.id));
183
+ };
184
+ const asc = await order(SortDirection.ASC);
185
+ const desc = await order(SortDirection.DESC);
186
+ await store.stop?.();
187
+ await indices.stop?.();
188
+ await indices.drop?.();
189
+ indices = undefined;
190
+ return { asc, desc };
191
+ };
192
+ it("orders string-id ties by UTF-8 bytes, both directions", async () => {
193
+ const docs = ["c", "a", "b", "aa", "A", "Z"].map((s) => new StringIdDoc(s));
194
+ const { asc, desc } = await collect(StringIdDoc, docs);
195
+ // UTF-8 byte order: uppercase (A, Z) before lowercase (a, aa, b, c).
196
+ expect(asc).to.deep.equal(["A", "Z", "a", "aa", "b", "c"]);
197
+ expect(desc).to.deep.equal(["c", "b", "aa", "a", "Z", "A"]);
198
+ });
199
+ it("orders bigint-id ties numerically, both directions", async () => {
200
+ const docs = [10n, 2n, 21n, 9n, 100n, 300n].map((n) => new BigIntIdDoc(n));
201
+ const { asc, desc } = await collect(BigIntIdDoc, docs);
202
+ expect(asc).to.deep.equal(["2", "9", "10", "21", "100", "300"]);
203
+ expect(desc).to.deep.equal(["300", "100", "21", "10", "9", "2"]);
204
+ });
205
+ it("orders Uint8Array-id ties by raw bytes, both directions", async () => {
206
+ const docs = [[0xff], [0x00], [0x0a], [0x3e], [0xf8], [0xfb]].map((b) => new BytesIdDoc(new Uint8Array(b)));
207
+ const { asc, desc } = await collect(BytesIdDoc, docs);
208
+ // Raw-byte memcmp: 0x00 < 0x0a < 0x3e < 0xf8 < 0xfb < 0xff.
209
+ expect(asc).to.deep.equal(["00", "0a", "3e", "f8", "fb", "ff"]);
210
+ expect(desc).to.deep.equal(["ff", "fb", "f8", "3e", "0a", "00"]);
211
+ });
212
+ });
213
+ };
214
+ //# sourceMappingURL=tie-parity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tie-parity.js","sourceRoot":"","sources":["../../src/tie-parity.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@peerbit/indexer-tests",
3
- "version": "3.0.4",
3
+ "version": "3.0.6",
4
4
  "description": "Tests document store index engines",
5
5
  "sideEffects": false,
6
6
  "type": "module",
@@ -60,8 +60,8 @@
60
60
  "uint8arrays": "^5.1.0",
61
61
  "benchmark": "^2.1.4",
62
62
  "uuid": "^10.0.0",
63
- "@peerbit/indexer-interface": "3.0.4",
64
- "@peerbit/crypto": "3.1.1",
63
+ "@peerbit/indexer-interface": "3.0.6",
64
+ "@peerbit/crypto": "3.1.2",
65
65
  "@peerbit/time": "3.0.0"
66
66
  },
67
67
  "scripts": {
package/src/index.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  export { tests } from "./tests.js";
2
+ export { tieParityTests } from "./tie-parity.js";
2
3
  export { benchmarks } from "./benchmarks.js";
package/src/tests.ts CHANGED
@@ -816,40 +816,6 @@ export const tests = (
816
816
  expect(responses).to.be.empty;
817
817
  });
818
818
  });
819
- describe("integer", () => {
820
- it("exists", async () => {
821
- await setupDefault();
822
-
823
- const responses = await search(store, {
824
- query: [
825
- new IntegerCompare({
826
- key: "data",
827
- compare: Compare.Equal,
828
- value: 1,
829
- }),
830
- ],
831
- });
832
- expect(responses).to.have.length(1);
833
- expect(responses.map((x) => x.id.primitive)).to.deep.equal([
834
- "1",
835
- ]);
836
- });
837
-
838
- it("does not exist", async () => {
839
- await setupDefault();
840
-
841
- const responses = await search(store, {
842
- query: [
843
- new IntegerCompare({
844
- key: "data",
845
- compare: Compare.Equal,
846
- value: 199,
847
- }),
848
- ],
849
- });
850
- expect(responses).to.be.empty;
851
- });
852
- });
853
819
  });
854
820
 
855
821
  describe("fixed", () => {
@@ -884,40 +850,6 @@ export const tests = (
884
850
  expect(responses).to.be.empty;
885
851
  });
886
852
  });
887
- describe("integer", () => {
888
- it("exists", async () => {
889
- await setupDefault();
890
-
891
- const responses = await search(store, {
892
- query: [
893
- new IntegerCompare({
894
- key: "data",
895
- compare: Compare.Equal,
896
- value: 1,
897
- }),
898
- ],
899
- });
900
- expect(responses).to.have.length(1);
901
- expect(responses.map((x) => x.id.primitive)).to.deep.equal([
902
- "1",
903
- ]);
904
- });
905
-
906
- it("does not exist", async () => {
907
- await setupDefault();
908
-
909
- const responses = await search(store, {
910
- query: [
911
- new IntegerCompare({
912
- key: "data",
913
- compare: Compare.Equal,
914
- value: 199,
915
- }),
916
- ],
917
- });
918
- expect(responses).to.be.empty;
919
- });
920
- });
921
853
  });
922
854
  });
923
855
 
@@ -4116,6 +4048,273 @@ export const tests = (
4116
4048
  expect(await iterator.pending()).to.eq(0);
4117
4049
  });
4118
4050
 
4051
+ it("all after partial next returns only remaining sorted results", async () => {
4052
+ await put(0);
4053
+ await put(1);
4054
+ await put(2);
4055
+
4056
+ const iterator = store.iterate({
4057
+ query: [],
4058
+ sort: [new Sort({ direction: SortDirection.ASC, key: "name" })],
4059
+ });
4060
+
4061
+ expect((await iterator.next(1)).map((x) => x.value.name)).to.deep.equal(
4062
+ ["0"],
4063
+ );
4064
+ expect((await iterator.all()).map((x) => x.value.name)).to.deep.equal([
4065
+ "1",
4066
+ "2",
4067
+ ]);
4068
+ expect(iterator.done()).to.be.true;
4069
+ });
4070
+
4071
+ it("deleting an already yielded sorted result does not skip the next result", async () => {
4072
+ await put(0);
4073
+ await put(1);
4074
+ await put(2);
4075
+
4076
+ const iterator = store.iterate({
4077
+ query: [],
4078
+ sort: [new Sort({ direction: SortDirection.ASC, key: "name" })],
4079
+ });
4080
+
4081
+ expect((await iterator.next(1)).map((x) => x.value.name)).to.deep.equal(
4082
+ ["0"],
4083
+ );
4084
+ await store.del({
4085
+ query: new StringMatch({
4086
+ key: "id",
4087
+ value: "0",
4088
+ method: StringMatchMethod.exact,
4089
+ caseInsensitive: false,
4090
+ }),
4091
+ });
4092
+
4093
+ expect((await iterator.next(2)).map((x) => x.value.name)).to.deep.equal(
4094
+ ["1", "2"],
4095
+ );
4096
+ expect(iterator.done()).to.be.true;
4097
+ });
4098
+
4099
+ it("inserting before an already yielded sorted result does not duplicate it", async () => {
4100
+ await put(1);
4101
+ await put(2);
4102
+
4103
+ const iterator = store.iterate({
4104
+ query: [],
4105
+ sort: [new Sort({ direction: SortDirection.ASC, key: "name" })],
4106
+ });
4107
+
4108
+ expect((await iterator.next(1)).map((x) => x.value.name)).to.deep.equal(
4109
+ ["1"],
4110
+ );
4111
+ await put(0);
4112
+
4113
+ const rest = (await iterator.next(3)).map((x) => x.value.name);
4114
+ expect(new Set(rest).size).to.equal(rest.length);
4115
+ expect(rest).to.not.include("1");
4116
+ expect(rest).to.include("2");
4117
+ });
4118
+
4119
+ it("keeps a mutated iterator open while unseen sorted results remain", async () => {
4120
+ await put(0);
4121
+ await put(2);
4122
+
4123
+ const iterator = store.iterate({
4124
+ query: [],
4125
+ sort: [new Sort({ direction: SortDirection.ASC, key: "name" })],
4126
+ });
4127
+
4128
+ expect((await iterator.next(1)).map((x) => x.value.name)).to.deep.equal(
4129
+ ["0"],
4130
+ );
4131
+ await put(1);
4132
+
4133
+ if (properties.iteratorsMutable) {
4134
+ expect(
4135
+ (await iterator.next(1)).map((x) => x.value.name),
4136
+ ).to.deep.equal(["1"]);
4137
+ expect(iterator.done()).to.be.false;
4138
+ expect(await iterator.pending()).to.equal(1);
4139
+ expect(
4140
+ (await iterator.next(1)).map((x) => x.value.name),
4141
+ ).to.deep.equal(["2"]);
4142
+ } else {
4143
+ expect(
4144
+ (await iterator.next(1)).map((x) => x.value.name),
4145
+ ).to.deep.equal(["2"]);
4146
+ }
4147
+ expect(iterator.done()).to.be.true;
4148
+ });
4149
+
4150
+ it("next Infinity sees inserts after an initially empty page", async () => {
4151
+ const iterator = store.iterate({
4152
+ query: [],
4153
+ sort: [new Sort({ direction: SortDirection.ASC, key: "name" })],
4154
+ });
4155
+
4156
+ expect(await iterator.next(1)).to.deep.equal([]);
4157
+ await put(0);
4158
+
4159
+ const rest = (await iterator.next(Infinity)).map((x) => x.value.name);
4160
+ expect(rest).to.deep.equal(properties.iteratorsMutable ? ["0"] : []);
4161
+ });
4162
+
4163
+ it("keeps an explicitly closed iterator terminal across mutations", async () => {
4164
+ await put(0);
4165
+ const iterator = store.iterate({
4166
+ query: [],
4167
+ sort: [new Sort({ direction: SortDirection.ASC, key: "name" })],
4168
+ });
4169
+
4170
+ await iterator.close();
4171
+ await put(1);
4172
+
4173
+ expect(await iterator.next(1)).to.deep.equal([]);
4174
+ expect(await iterator.all()).to.deep.equal([]);
4175
+ expect(await iterator.pending()).to.equal(0);
4176
+ expect(iterator.done()).to.be.true;
4177
+ });
4178
+
4179
+ it("can continue a mutable iterator after all and a later insert", async () => {
4180
+ await put(0);
4181
+ const iterator = store.iterate({
4182
+ query: [],
4183
+ sort: [new Sort({ direction: SortDirection.ASC, key: "name" })],
4184
+ });
4185
+
4186
+ expect((await iterator.all()).map((x) => x.value.name)).to.deep.equal([
4187
+ "0",
4188
+ ]);
4189
+ await put(1);
4190
+
4191
+ expect((await iterator.next(1)).map((x) => x.value.name)).to.deep.equal(
4192
+ properties.iteratorsMutable ? ["1"] : [],
4193
+ );
4194
+ });
4195
+
4196
+ it("refreshes pending after an exhausted mutable iterator mutates", async () => {
4197
+ const iterator = store.iterate({
4198
+ query: [],
4199
+ sort: [new Sort({ direction: SortDirection.ASC, key: "name" })],
4200
+ });
4201
+
4202
+ expect(await iterator.next(1)).to.deep.equal([]);
4203
+ await put(0);
4204
+
4205
+ expect(await iterator.pending()).to.equal(
4206
+ properties.iteratorsMutable ? 1 : 0,
4207
+ );
4208
+ if (properties.iteratorsMutable) {
4209
+ expect(iterator.done()).to.be.false;
4210
+ expect(
4211
+ (await iterator.next(1)).map((x) => x.value.name),
4212
+ ).to.deep.equal(["0"]);
4213
+ }
4214
+ });
4215
+
4216
+ it("can mark live results delivered outside the iterator as yielded", async () => {
4217
+ if (!properties.iteratorsMutable) {
4218
+ return;
4219
+ }
4220
+
4221
+ await put(0);
4222
+ await put(1);
4223
+ const iterator = store.iterate({
4224
+ query: [],
4225
+ sort: [new Sort({ direction: SortDirection.ASC, key: "name" })],
4226
+ });
4227
+
4228
+ expect((await iterator.next(1)).map((x) => x.value.id)).to.deep.equal([
4229
+ "0",
4230
+ ]);
4231
+ await put(2);
4232
+ expect(iterator.markYielded).to.be.a("function");
4233
+ await iterator.markYielded!([toId("2")]);
4234
+
4235
+ expect(await iterator.pending()).to.equal(1);
4236
+ expect((await iterator.next(2)).map((x) => x.value.id)).to.deep.equal([
4237
+ "1",
4238
+ ]);
4239
+ expect(await iterator.pending()).to.equal(0);
4240
+ expect(iterator.done()).to.be.true;
4241
+ });
4242
+
4243
+ it("tracks filtered updates without duplicates", async () => {
4244
+ if (!properties.iteratorsMutable) {
4245
+ return;
4246
+ }
4247
+
4248
+ await put(0, { name: "match" });
4249
+ await put(1, { name: "miss" });
4250
+ await put(2, { name: "match" });
4251
+ const iterator = store.iterate({
4252
+ query: new StringMatch({
4253
+ key: "name",
4254
+ value: "match",
4255
+ method: StringMatchMethod.exact,
4256
+ caseInsensitive: false,
4257
+ }),
4258
+ sort: [new Sort({ direction: SortDirection.ASC, key: "number" })],
4259
+ });
4260
+
4261
+ expect((await iterator.next(1)).map((x) => x.value.id)).to.deep.equal([
4262
+ "0",
4263
+ ]);
4264
+ await put(1, { name: "match" });
4265
+ await put(2, { name: "miss" });
4266
+ await put(0, { name: "match" });
4267
+ await put(3, { name: "match" });
4268
+
4269
+ expect((await iterator.all()).map((x) => x.value.id)).to.deep.equal([
4270
+ "1",
4271
+ "3",
4272
+ ]);
4273
+ });
4274
+
4275
+ it("rescans beyond 128 yielded rows after a mutation", async () => {
4276
+ if (!properties.iteratorsMutable) {
4277
+ return;
4278
+ }
4279
+
4280
+ for (let i = 0; i < 140; i++) {
4281
+ await put(i);
4282
+ }
4283
+ const iterator = store.iterate({
4284
+ query: [],
4285
+ sort: [new Sort({ direction: SortDirection.ASC, key: "number" })],
4286
+ });
4287
+ expect(await iterator.next(130)).to.have.length(130);
4288
+
4289
+ await store.del({
4290
+ query: new StringMatch({
4291
+ key: "id",
4292
+ value: "0",
4293
+ method: StringMatchMethod.exact,
4294
+ caseInsensitive: false,
4295
+ }),
4296
+ });
4297
+ await put(200);
4298
+
4299
+ expect((await iterator.next(1)).map((x) => x.value.id)).to.deep.equal([
4300
+ "130",
4301
+ ]);
4302
+ const remaining = (await iterator.all()).map((x) => x.value.id);
4303
+ expect(remaining).to.deep.equal([
4304
+ "131",
4305
+ "132",
4306
+ "133",
4307
+ "134",
4308
+ "135",
4309
+ "136",
4310
+ "137",
4311
+ "138",
4312
+ "139",
4313
+ "200",
4314
+ ]);
4315
+ expect(new Set(remaining).size).to.equal(remaining.length);
4316
+ });
4317
+
4119
4318
  describe("close", () => {
4120
4319
  it("by invoking close()", async () => {
4121
4320
  await put(0);