@enbox/dwn-sdk-js 0.4.7 → 0.4.9

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.
Files changed (121) hide show
  1. package/dist/browser.mjs +1 -1
  2. package/dist/browser.mjs.map +4 -4
  3. package/dist/esm/generated/precompiled-validators.js +319 -0
  4. package/dist/esm/generated/precompiled-validators.js.map +1 -1
  5. package/dist/esm/src/core/dwn-error.js +1 -0
  6. package/dist/esm/src/core/dwn-error.js.map +1 -1
  7. package/dist/esm/src/index.js +1 -1
  8. package/dist/esm/src/index.js.map +1 -1
  9. package/dist/esm/src/interfaces/messages-subscribe.js.map +1 -1
  10. package/dist/esm/src/protocols/encryption.js +38 -6
  11. package/dist/esm/src/protocols/encryption.js.map +1 -1
  12. package/dist/esm/src/store/index-level-compound.js.map +1 -1
  13. package/dist/esm/src/store/level-wrapper.js +6 -2
  14. package/dist/esm/src/store/level-wrapper.js.map +1 -1
  15. package/dist/esm/src/utils/jws.js.map +1 -1
  16. package/dist/esm/tests/dwn.spec.js +5 -5
  17. package/dist/esm/tests/dwn.spec.js.map +1 -1
  18. package/dist/esm/tests/features/author-delegated-grant.spec.js +16 -16
  19. package/dist/esm/tests/features/author-delegated-grant.spec.js.map +1 -1
  20. package/dist/esm/tests/features/owner-delegated-grant.spec.js +7 -7
  21. package/dist/esm/tests/features/owner-delegated-grant.spec.js.map +1 -1
  22. package/dist/esm/tests/features/permissions.spec.js +8 -8
  23. package/dist/esm/tests/features/permissions.spec.js.map +1 -1
  24. package/dist/esm/tests/features/protocol-composition.spec.js +3 -3
  25. package/dist/esm/tests/features/protocol-composition.spec.js.map +1 -1
  26. package/dist/esm/tests/features/records-prune-cross-protocol.spec.js +5 -5
  27. package/dist/esm/tests/features/records-prune-cross-protocol.spec.js.map +1 -1
  28. package/dist/esm/tests/features/records-prune.spec.js +15 -15
  29. package/dist/esm/tests/features/records-prune.spec.js.map +1 -1
  30. package/dist/esm/tests/features/records-squash.spec.js +9 -9
  31. package/dist/esm/tests/features/records-squash.spec.js.map +1 -1
  32. package/dist/esm/tests/features/records-tags.spec.js +28 -28
  33. package/dist/esm/tests/features/records-tags.spec.js.map +1 -1
  34. package/dist/esm/tests/features/resumable-tasks.spec.js +3 -3
  35. package/dist/esm/tests/features/resumable-tasks.spec.js.map +1 -1
  36. package/dist/esm/tests/fuzz/data-stream.fuzz.spec.js +2 -2
  37. package/dist/esm/tests/fuzz/data-stream.fuzz.spec.js.map +1 -1
  38. package/dist/esm/tests/fuzz/filter.fuzz.spec.js +1 -1
  39. package/dist/esm/tests/fuzz/filter.fuzz.spec.js.map +1 -1
  40. package/dist/esm/tests/fuzz/records-utils.fuzz.spec.js +2 -2
  41. package/dist/esm/tests/fuzz/records-utils.fuzz.spec.js.map +1 -1
  42. package/dist/esm/tests/fuzz/resumable-task-store.fuzz.spec.js +4 -4
  43. package/dist/esm/tests/fuzz/resumable-task-store.fuzz.spec.js.map +1 -1
  44. package/dist/esm/tests/handlers/messages-subscribe.spec.js +16 -16
  45. package/dist/esm/tests/handlers/messages-subscribe.spec.js.map +1 -1
  46. package/dist/esm/tests/handlers/protocols-configure.spec.js +5 -5
  47. package/dist/esm/tests/handlers/protocols-configure.spec.js.map +1 -1
  48. package/dist/esm/tests/handlers/protocols-query.spec.js +11 -11
  49. package/dist/esm/tests/handlers/protocols-query.spec.js.map +1 -1
  50. package/dist/esm/tests/handlers/records-delete.spec.js +22 -22
  51. package/dist/esm/tests/handlers/records-delete.spec.js.map +1 -1
  52. package/dist/esm/tests/handlers/records-query.spec.js +120 -120
  53. package/dist/esm/tests/handlers/records-query.spec.js.map +1 -1
  54. package/dist/esm/tests/handlers/records-read.spec.js +1 -1
  55. package/dist/esm/tests/handlers/records-read.spec.js.map +1 -1
  56. package/dist/esm/tests/handlers/records-subscribe.spec.js +10 -10
  57. package/dist/esm/tests/handlers/records-subscribe.spec.js.map +1 -1
  58. package/dist/esm/tests/handlers/records-write.spec.js +31 -31
  59. package/dist/esm/tests/handlers/records-write.spec.js.map +1 -1
  60. package/dist/esm/tests/interfaces/protocols-configure.spec.js +4 -4
  61. package/dist/esm/tests/interfaces/protocols-configure.spec.js.map +1 -1
  62. package/dist/esm/tests/jose/jws/general.spec.js +4 -4
  63. package/dist/esm/tests/jose/jws/general.spec.js.map +1 -1
  64. package/dist/esm/tests/protocols/encryption.spec.js +94 -3
  65. package/dist/esm/tests/protocols/encryption.spec.js.map +1 -1
  66. package/dist/esm/tests/scenarios/nested-roles.spec.js +1 -1
  67. package/dist/esm/tests/scenarios/nested-roles.spec.js.map +1 -1
  68. package/dist/esm/tests/scenarios/subscriptions.spec.js +28 -28
  69. package/dist/esm/tests/scenarios/subscriptions.spec.js.map +1 -1
  70. package/dist/esm/tests/store/blockstore-mock.spec.js +1 -1
  71. package/dist/esm/tests/store/blockstore-mock.spec.js.map +1 -1
  72. package/dist/esm/tests/store/data-store-level.spec.js +3 -3
  73. package/dist/esm/tests/store/data-store-level.spec.js.map +1 -1
  74. package/dist/esm/tests/store/index-level.spec.js +83 -83
  75. package/dist/esm/tests/store/index-level.spec.js.map +1 -1
  76. package/dist/esm/tests/store/message-store-level.spec.js +2 -2
  77. package/dist/esm/tests/store/message-store-level.spec.js.map +1 -1
  78. package/dist/esm/tests/store/message-store.spec.js +30 -30
  79. package/dist/esm/tests/store/message-store.spec.js.map +1 -1
  80. package/dist/esm/tests/store-dependent-tests.spec.js +5 -0
  81. package/dist/esm/tests/store-dependent-tests.spec.js.map +1 -1
  82. package/dist/esm/tests/utils/data-stream.spec.js +15 -15
  83. package/dist/esm/tests/utils/data-stream.spec.js.map +1 -1
  84. package/dist/esm/tests/utils/encryption.spec.js +1 -1
  85. package/dist/esm/tests/utils/encryption.spec.js.map +1 -1
  86. package/dist/esm/tests/utils/messages.spec.js +8 -8
  87. package/dist/esm/tests/utils/messages.spec.js.map +1 -1
  88. package/dist/esm/tests/utils/secp256k1.spec.js +2 -2
  89. package/dist/esm/tests/utils/secp256k1.spec.js.map +1 -1
  90. package/dist/esm/tests/utils/secp256r1.spec.js +1 -1
  91. package/dist/esm/tests/utils/secp256r1.spec.js.map +1 -1
  92. package/dist/esm/tests/validation/json-schemas/encryption/wrapped-grant-key-envelope.spec.js +43 -0
  93. package/dist/esm/tests/validation/json-schemas/encryption/wrapped-grant-key-envelope.spec.js.map +1 -0
  94. package/dist/types/generated/precompiled-validators.d.ts +16 -0
  95. package/dist/types/generated/precompiled-validators.d.ts.map +1 -1
  96. package/dist/types/src/core/dwn-error.d.ts +1 -0
  97. package/dist/types/src/core/dwn-error.d.ts.map +1 -1
  98. package/dist/types/src/index.d.ts +2 -1
  99. package/dist/types/src/index.d.ts.map +1 -1
  100. package/dist/types/src/interfaces/messages-subscribe.d.ts +1 -2
  101. package/dist/types/src/interfaces/messages-subscribe.d.ts.map +1 -1
  102. package/dist/types/src/protocols/encryption.d.ts +15 -2
  103. package/dist/types/src/protocols/encryption.d.ts.map +1 -1
  104. package/dist/types/src/store/index-level-compound.d.ts +2 -4
  105. package/dist/types/src/store/index-level-compound.d.ts.map +1 -1
  106. package/dist/types/src/store/level-wrapper.d.ts.map +1 -1
  107. package/dist/types/src/types/protocols-types.d.ts +1 -1
  108. package/dist/types/src/types/protocols-types.d.ts.map +1 -1
  109. package/dist/types/src/utils/jws.d.ts +1 -2
  110. package/dist/types/src/utils/jws.d.ts.map +1 -1
  111. package/dist/types/tests/validation/json-schemas/encryption/wrapped-grant-key-envelope.spec.d.ts +2 -0
  112. package/dist/types/tests/validation/json-schemas/encryption/wrapped-grant-key-envelope.spec.d.ts.map +1 -0
  113. package/package.json +4 -4
  114. package/src/core/dwn-error.ts +1 -0
  115. package/src/index.ts +2 -1
  116. package/src/interfaces/messages-subscribe.ts +1 -2
  117. package/src/protocols/encryption.ts +59 -6
  118. package/src/store/index-level-compound.ts +2 -5
  119. package/src/store/level-wrapper.ts +6 -2
  120. package/src/types/protocols-types.ts +2 -1
  121. package/src/utils/jws.ts +1 -2
@@ -53,7 +53,7 @@ describe('IndexLevel', () => {
53
53
  dateCreated, // 1 key
54
54
  });
55
55
  let keys = await ArrayUtility.fromAsyncGenerator(testIndex.db.keys());
56
- expect(keys.length).toBe(5);
56
+ expect(keys).toHaveLength(5);
57
57
  await testIndex.clear();
58
58
  await testIndex.put(tenant, id, {
59
59
  'a': 'b', // 1 key
@@ -62,7 +62,7 @@ describe('IndexLevel', () => {
62
62
  dateCreated, // 1 key
63
63
  });
64
64
  keys = await ArrayUtility.fromAsyncGenerator(testIndex.db.keys());
65
- expect(keys.length).toBe(6);
65
+ expect(keys).toHaveLength(6);
66
66
  });
67
67
  it('should not put anything if aborted beforehand', async () => {
68
68
  const controller = new AbortController();
@@ -75,7 +75,7 @@ describe('IndexLevel', () => {
75
75
  const indexPromise = testIndex.put(tenant, id, index, { signal: controller.signal });
76
76
  await expect(indexPromise).rejects.toThrow('reason');
77
77
  const entries = await testIndex.query(tenant, [{ foo: 'bar' }], { sortProperty: 'id' });
78
- expect(entries.length).toBe(0);
78
+ expect(entries).toHaveLength(0);
79
79
  });
80
80
  });
81
81
  describe('query', () => {
@@ -118,7 +118,7 @@ describe('IndexLevel', () => {
118
118
  'a': 'b',
119
119
  'c': 'e'
120
120
  }], { sortProperty: 'id' });
121
- expect(entries.length).toBe(1);
121
+ expect(entries).toHaveLength(1);
122
122
  expect(entries[0].messageCid).toBe(id3);
123
123
  });
124
124
  it('should return all records if an empty filter array is passed', async () => {
@@ -147,27 +147,27 @@ describe('IndexLevel', () => {
147
147
  const filters = [{ schema: 'schema', published: true }];
148
148
  // query with limit, default (ascending)
149
149
  const results = await testIndex.queryWithIteratorPaging(tenant, filters, { sortProperty: 'val', limit: 2 });
150
- expect(results.length).toBe(2);
150
+ expect(results).toHaveLength(2);
151
151
  expect(results.map(({ messageCid }) => messageCid)).toEqual(['a', 'b']);
152
152
  // query with cursor, default (ascending)
153
153
  const resultsAfterCursor = await testIndex.queryWithIteratorPaging(tenant, filters, { sortProperty: 'val', cursor: IndexLevel.createCursorFromLastArrayItem(results, 'val') });
154
- expect(resultsAfterCursor.length).toBe(2);
154
+ expect(resultsAfterCursor).toHaveLength(2);
155
155
  expect(resultsAfterCursor.map(({ messageCid }) => messageCid)).toEqual(['c', 'd']);
156
156
  // query with limit, explicit ascending
157
157
  const ascResults = await testIndex.queryWithIteratorPaging(tenant, filters, { sortProperty: 'val', limit: 2 });
158
- expect(ascResults.length).toBe(2);
158
+ expect(ascResults).toHaveLength(2);
159
159
  expect(ascResults.map(({ messageCid }) => messageCid)).toEqual(['a', 'b']);
160
160
  // query with cursor, explicit ascending
161
161
  const ascResultsAfterCursor = await testIndex.queryWithIteratorPaging(tenant, filters, { sortProperty: 'val', cursor: IndexLevel.createCursorFromLastArrayItem(ascResults, 'val') });
162
- expect(ascResultsAfterCursor.length).toBe(2);
162
+ expect(ascResultsAfterCursor).toHaveLength(2);
163
163
  expect(ascResultsAfterCursor.map(({ messageCid }) => messageCid)).toEqual(['c', 'd']);
164
164
  // query with limit, descending
165
165
  const descResults = await testIndex.queryWithIteratorPaging(tenant, filters, { sortDirection: SortDirection.Descending, sortProperty: 'val', limit: 2 });
166
- expect(descResults.length).toBe(2);
166
+ expect(descResults).toHaveLength(2);
167
167
  expect(descResults.map(({ messageCid }) => messageCid)).toEqual(['d', 'c']);
168
168
  // query with cursor, descending
169
169
  const descResultsAfterCursor = await testIndex.queryWithIteratorPaging(tenant, filters, { sortDirection: SortDirection.Descending, sortProperty: 'val', cursor: IndexLevel.createCursorFromLastArrayItem(descResults, 'val') });
170
- expect(descResultsAfterCursor.length).toBe(2);
170
+ expect(descResultsAfterCursor).toHaveLength(2);
171
171
  expect(descResultsAfterCursor.map(({ messageCid }) => messageCid)).toEqual(['b', 'a']);
172
172
  });
173
173
  it('returns empty array if sort property is invalid', async () => {
@@ -183,10 +183,10 @@ describe('IndexLevel', () => {
183
183
  const filters = [{ schema: 'schema', published: true }];
184
184
  // control test: return all results
185
185
  const validResults = await testIndex.queryWithIteratorPaging(tenant, filters, { sortProperty: 'val' });
186
- expect(validResults.length).toBe(4);
186
+ expect(validResults).toHaveLength(4);
187
187
  // sort by invalid property returns no results
188
188
  const invalidResults = await testIndex.queryWithIteratorPaging(tenant, filters, { sortProperty: 'invalid' });
189
- expect(invalidResults.length).toBe(0);
189
+ expect(invalidResults).toHaveLength(0);
190
190
  });
191
191
  it('cursor is valid but out of range of matched results', async () => {
192
192
  const testVals = ['b', 'd', 'c']; // a is missing
@@ -206,7 +206,7 @@ describe('IndexLevel', () => {
206
206
  // cursor `e-id` doesn't actually exist, but the value `e` is sorted after to the result set.
207
207
  const cursorE = { messageCid: 'e-id', value: 'e' };
208
208
  const noResults = await testIndex.queryWithIteratorPaging(tenant, filters, { sortProperty: 'val', cursor: cursorE });
209
- expect(noResults.length).toEqual(0);
209
+ expect(noResults).toHaveLength(0);
210
210
  });
211
211
  });
212
212
  describe('array values', () => {
@@ -229,11 +229,11 @@ describe('IndexLevel', () => {
229
229
  }
230
230
  const filterForItemTag = [{ tag: 'item' }];
231
231
  const allResults = await testIndex.queryWithIteratorPaging(tenant, filterForItemTag, { sortProperty: 'id' });
232
- expect(allResults.length).toBe(4);
232
+ expect(allResults).toHaveLength(4);
233
233
  expect(allResults.map(item => item.messageCid)).toEqual(expect.arrayContaining(items.map(item => item.id)));
234
234
  const filterForItem3 = [{ tag: 'item3' }];
235
235
  const item3Results = await testIndex.queryWithIteratorPaging(tenant, filterForItem3, { sortProperty: 'id' });
236
- expect(item3Results.length).toBe(1);
236
+ expect(item3Results).toHaveLength(1);
237
237
  expect(item3Results.map(item => item.messageCid)).toEqual(expect.arrayContaining([items[2].id]));
238
238
  });
239
239
  it('query items with number array values', async () => {
@@ -255,15 +255,15 @@ describe('IndexLevel', () => {
255
255
  }
256
256
  const filterForItemTag = [{ tag: 1 }];
257
257
  const allResults = await testIndex.queryWithIteratorPaging(tenant, filterForItemTag, { sortProperty: 'id' });
258
- expect(allResults.length).toBe(4);
258
+ expect(allResults).toHaveLength(4);
259
259
  expect(allResults.map(item => item.messageCid)).toEqual(expect.arrayContaining(items.map(item => item.id)));
260
260
  const filterForItem3 = [{ tag: 3 }];
261
261
  const item3Results = await testIndex.queryWithIteratorPaging(tenant, filterForItem3, { sortProperty: 'id' });
262
- expect(item3Results.length).toBe(1);
262
+ expect(item3Results).toHaveLength(1);
263
263
  expect(item3Results.map(item => item.messageCid)).toEqual(expect.arrayContaining([items[2].id]));
264
264
  const filterForRange = [{ tag: { gt: 1, lt: 4 } }];
265
265
  const rangeItems = await testIndex.queryWithIteratorPaging(tenant, filterForRange, { sortProperty: 'id' });
266
- expect(rangeItems.length).toBe(2);
266
+ expect(rangeItems).toHaveLength(2);
267
267
  expect(rangeItems.map(item => item.messageCid)).toEqual(expect.arrayContaining([items[1].id, items[2].id]));
268
268
  });
269
269
  });
@@ -281,27 +281,27 @@ describe('IndexLevel', () => {
281
281
  const filters = [{ schema: 'schema', published: true }];
282
282
  // query with limit, default (ascending)
283
283
  const results = await testIndex.queryWithInMemoryPaging(tenant, filters, { sortProperty: 'val', limit: 2 });
284
- expect(results.length).toBe(2);
284
+ expect(results).toHaveLength(2);
285
285
  expect(results.map(({ messageCid }) => messageCid)).toEqual(['a', 'b']);
286
286
  // query with cursor, default (ascending)
287
287
  const resultsAfterCursor = await testIndex.queryWithInMemoryPaging(tenant, filters, { sortProperty: 'val', cursor: IndexLevel.createCursorFromLastArrayItem(results, 'val') });
288
- expect(resultsAfterCursor.length).toBe(2);
288
+ expect(resultsAfterCursor).toHaveLength(2);
289
289
  expect(resultsAfterCursor.map(({ messageCid }) => messageCid)).toEqual(['c', 'd']);
290
290
  // query with limit, explicit ascending
291
291
  const ascResults = await testIndex.queryWithInMemoryPaging(tenant, filters, { sortProperty: 'val', limit: 2 });
292
- expect(ascResults.length).toBe(2);
292
+ expect(ascResults).toHaveLength(2);
293
293
  expect(ascResults.map(({ messageCid }) => messageCid)).toEqual(['a', 'b']);
294
294
  // query with cursor, explicit ascending
295
295
  const ascResultsAfterCursor = await testIndex.queryWithInMemoryPaging(tenant, filters, { sortProperty: 'val', cursor: IndexLevel.createCursorFromLastArrayItem(ascResults, 'val') });
296
- expect(ascResultsAfterCursor.length).toBe(2);
296
+ expect(ascResultsAfterCursor).toHaveLength(2);
297
297
  expect(ascResultsAfterCursor.map(({ messageCid }) => messageCid)).toEqual(['c', 'd']);
298
298
  // query with limit, descending
299
299
  const descResults = await testIndex.queryWithInMemoryPaging(tenant, filters, { sortDirection: SortDirection.Descending, sortProperty: 'val', limit: 2 });
300
- expect(descResults.length).toBe(2);
300
+ expect(descResults).toHaveLength(2);
301
301
  expect(descResults.map(({ messageCid }) => messageCid)).toEqual(['d', 'c']);
302
302
  // query with cursor, descending
303
303
  const descResultsAfterCursor = await testIndex.queryWithInMemoryPaging(tenant, filters, { sortDirection: SortDirection.Descending, sortProperty: 'val', cursor: IndexLevel.createCursorFromLastArrayItem(descResults, 'val') });
304
- expect(descResultsAfterCursor.length).toBe(2);
304
+ expect(descResultsAfterCursor).toHaveLength(2);
305
305
  expect(descResultsAfterCursor.map(({ messageCid }) => messageCid)).toEqual(['b', 'a']);
306
306
  });
307
307
  it('returns empty array if sort property is invalid', async () => {
@@ -317,10 +317,10 @@ describe('IndexLevel', () => {
317
317
  const filters = [{ schema: 'schema', published: true }];
318
318
  // control test: return all results
319
319
  const validResults = await testIndex.queryWithInMemoryPaging(tenant, filters, { sortProperty: 'val', limit: 3 });
320
- expect(validResults.length).toBe(3);
320
+ expect(validResults).toHaveLength(3);
321
321
  // sort by invalid property returns no results
322
322
  const invalidResults = await testIndex.queryWithInMemoryPaging(tenant, filters, { sortProperty: 'invalid' });
323
- expect(invalidResults.length).toBe(0);
323
+ expect(invalidResults).toHaveLength(0);
324
324
  });
325
325
  it('cursor is valid but out of range of matched results', async () => {
326
326
  const testVals = ['b', 'd', 'c', 'a'];
@@ -338,7 +338,7 @@ describe('IndexLevel', () => {
338
338
  expect(allResults.map(({ messageCid }) => messageCid)).toEqual(['b', 'c', 'd']);
339
339
  const cursorE = { messageCid: 'e', value: 'e' }; // after results
340
340
  const noResults = await testIndex.queryWithInMemoryPaging(tenant, filters, { sortProperty: 'val', cursor: cursorE });
341
- expect(noResults.length).toEqual(0);
341
+ expect(noResults).toHaveLength(0);
342
342
  });
343
343
  it('supports range queries', async () => {
344
344
  const id = uuid();
@@ -366,7 +366,7 @@ describe('IndexLevel', () => {
366
366
  }
367
367
  }];
368
368
  const entries = await testIndex.queryWithInMemoryPaging(tenant, filters, { sortProperty: 'id' });
369
- expect(entries.length).toBe(2);
369
+ expect(entries).toHaveLength(2);
370
370
  expect(entries.map(({ messageCid }) => messageCid)).toEqual(expect.arrayContaining([id2, id3]));
371
371
  // only upper bounds
372
372
  const lteFilter = [{
@@ -375,7 +375,7 @@ describe('IndexLevel', () => {
375
375
  }
376
376
  }];
377
377
  const lteReply = await testIndex.queryWithInMemoryPaging(tenant, lteFilter, { sortProperty: 'id' });
378
- expect(lteReply.length).toBe(3);
378
+ expect(lteReply).toHaveLength(3);
379
379
  expect(lteReply.map(({ messageCid }) => messageCid)).toEqual(expect.arrayContaining([id, id2, id3]));
380
380
  });
381
381
  describe('array values', () => {
@@ -398,11 +398,11 @@ describe('IndexLevel', () => {
398
398
  }
399
399
  const filterForItemTag = [{ tag: 'item' }];
400
400
  const allResults = await testIndex.queryWithInMemoryPaging(tenant, filterForItemTag, { sortProperty: 'id' });
401
- expect(allResults.length).toBe(4);
401
+ expect(allResults).toHaveLength(4);
402
402
  expect(allResults.map(item => item.messageCid)).toEqual(expect.arrayContaining(items.map(item => item.id)));
403
403
  const filterForItem3 = [{ tag: 'item3' }];
404
404
  const item3Results = await testIndex.queryWithInMemoryPaging(tenant, filterForItem3, { sortProperty: 'id' });
405
- expect(item3Results.length).toBe(1);
405
+ expect(item3Results).toHaveLength(1);
406
406
  expect(item3Results.map(item => item.messageCid)).toEqual(expect.arrayContaining([items[2].id]));
407
407
  });
408
408
  it('query items with number array values', async () => {
@@ -424,15 +424,15 @@ describe('IndexLevel', () => {
424
424
  }
425
425
  const filterForItemTag = [{ tag: 1 }];
426
426
  const allResults = await testIndex.queryWithInMemoryPaging(tenant, filterForItemTag, { sortProperty: 'id' });
427
- expect(allResults.length).toBe(4);
427
+ expect(allResults).toHaveLength(4);
428
428
  expect(allResults.map(item => item.messageCid)).toEqual(expect.arrayContaining(items.map(item => item.id)));
429
429
  const filterForItem3 = [{ tag: 3 }];
430
430
  const item3Results = await testIndex.queryWithInMemoryPaging(tenant, filterForItem3, { sortProperty: 'id' });
431
- expect(item3Results.length).toBe(1);
431
+ expect(item3Results).toHaveLength(1);
432
432
  expect(item3Results.map(item => item.messageCid)).toEqual(expect.arrayContaining([items[2].id]));
433
433
  const filterForRange = [{ tag: { gt: 1, lt: 4 } }];
434
434
  const rangeItems = await testIndex.queryWithInMemoryPaging(tenant, filterForRange, { sortProperty: 'id' });
435
- expect(rangeItems.length).toBe(2);
435
+ expect(rangeItems).toHaveLength(2);
436
436
  expect(rangeItems.map(item => item.messageCid)).toEqual(expect.arrayContaining([items[1].id, items[2].id]));
437
437
  });
438
438
  });
@@ -447,7 +447,7 @@ describe('IndexLevel', () => {
447
447
  await testIndex.put(tenant, id, doc);
448
448
  const filters = [{ value: 'foo' }];
449
449
  const entries = await testIndex.query(tenant, filters, { sortProperty: 'id' });
450
- expect(entries.length).toBe(0);
450
+ expect(entries).toHaveLength(0);
451
451
  });
452
452
  it('supports OR queries', async () => {
453
453
  const id1 = uuid();
@@ -472,7 +472,7 @@ describe('IndexLevel', () => {
472
472
  a: ['a', 'b']
473
473
  }];
474
474
  const entries = await testIndex.query(tenant, filters, { sortProperty: 'id' });
475
- expect(entries.length).toBe(2);
475
+ expect(entries).toHaveLength(2);
476
476
  expect(entries.map(({ messageCid }) => messageCid)).toContain(id1);
477
477
  expect(entries.map(({ messageCid }) => messageCid)).toContain(id2);
478
478
  });
@@ -491,7 +491,7 @@ describe('IndexLevel', () => {
491
491
  }
492
492
  }];
493
493
  const entries = await testIndex.query(tenant, filters, { sortProperty: 'id' });
494
- expect(entries.length).toBe(5);
494
+ expect(entries).toHaveLength(5);
495
495
  });
496
496
  it('supports prefixed range queries', async () => {
497
497
  const id = uuid();
@@ -506,7 +506,7 @@ describe('IndexLevel', () => {
506
506
  }
507
507
  }];
508
508
  const entries = await testIndex.query(tenant, filters, { sortProperty: 'id' });
509
- expect(entries.length).toBe(1);
509
+ expect(entries).toHaveLength(1);
510
510
  expect(entries.map(({ messageCid }) => messageCid)).toContain(id);
511
511
  });
512
512
  it('supports suffixed range queries', async () => {
@@ -528,7 +528,7 @@ describe('IndexLevel', () => {
528
528
  }
529
529
  }];
530
530
  const entries = await testIndex.query(tenant, filters, { sortProperty: 'id' });
531
- expect(entries.length).toBe(1);
531
+ expect(entries).toHaveLength(1);
532
532
  expect(entries.map(({ messageCid }) => messageCid)).toContain(id1);
533
533
  });
534
534
  it('treats strings differently', async () => {
@@ -548,7 +548,7 @@ describe('IndexLevel', () => {
548
548
  foo: true
549
549
  }];
550
550
  const entries = await testIndex.query(tenant, filters, { sortProperty: 'id' });
551
- expect(entries.length).toBe(1);
551
+ expect(entries).toHaveLength(1);
552
552
  expect(entries.map(({ messageCid }) => messageCid)).toContain(id1);
553
553
  });
554
554
  describe('numbers', () => {
@@ -564,7 +564,7 @@ describe('IndexLevel', () => {
564
564
  digit: testNumbers.at(index)
565
565
  }];
566
566
  const entries = await testIndex.query(tenant, filters, { sortProperty: 'digit' });
567
- expect(entries.length).toBe(1);
567
+ expect(entries).toHaveLength(1);
568
568
  expect(entries.at(0)?.messageCid).toBe(testNumbers.at(index).toString());
569
569
  });
570
570
  it('should not return records that do not match provided number equality filter', async () => {
@@ -574,7 +574,7 @@ describe('IndexLevel', () => {
574
574
  }
575
575
  const filters = [{ digit: 1 }];
576
576
  const entries = await testIndex.query(tenant, filters, { sortProperty: 'digit' });
577
- expect(entries.length).toBe(0);
577
+ expect(entries).toHaveLength(0);
578
578
  });
579
579
  it('supports range queries with positive numbers inclusive', async () => {
580
580
  for (const digit of testNumbers) {
@@ -684,17 +684,17 @@ describe('IndexLevel', () => {
684
684
  const bothFilter = [{ schema: 'schema' }];
685
685
  // control
686
686
  const entries = await testIndex.query(tenant, bothFilter, { sortProperty: 'id' });
687
- expect(entries.length).toBe(2);
687
+ expect(entries).toHaveLength(2);
688
688
  expect(entries.map(({ messageCid }) => messageCid)).toEqual(expect.arrayContaining([itemTrueId, itemFalseId]));
689
689
  const trueFilter = [{ published: true, schema: 'schema' }];
690
690
  // equality true
691
691
  const respTrue = await testIndex.query(tenant, trueFilter, { sortProperty: 'id' });
692
- expect(respTrue.length).toBe(1);
692
+ expect(respTrue).toHaveLength(1);
693
693
  expect(respTrue.map(({ messageCid }) => messageCid)).toEqual(expect.arrayContaining([itemTrueId]));
694
694
  const falseFilter = [{ published: false, schema: 'schema' }];
695
695
  // equality false
696
696
  const respFalse = await testIndex.query(tenant, falseFilter, { sortProperty: 'id' });
697
- expect(respFalse.length).toBe(1);
697
+ expect(respFalse).toHaveLength(1);
698
698
  expect(respFalse.map(({ messageCid }) => messageCid)).toEqual(expect.arrayContaining([itemFalseId]));
699
699
  });
700
700
  });
@@ -707,11 +707,11 @@ describe('IndexLevel', () => {
707
707
  const filters = [{ schema: 'schema' }];
708
708
  // limit results without cursor
709
709
  let ascResults = await testIndex.query(tenant, filters, { sortProperty: 'val', limit: 2 });
710
- expect(ascResults.length).toBe(2);
710
+ expect(ascResults).toHaveLength(2);
711
711
  expect(ascResults.map(({ messageCid }) => messageCid)).toEqual(['a', 'b']);
712
712
  // limit results with a cursor
713
713
  ascResults = await testIndex.query(tenant, filters, { sortProperty: 'val', limit: 2, cursor: IndexLevel.createCursorFromLastArrayItem(ascResults, 'val') });
714
- expect(ascResults.length).toBe(2);
714
+ expect(ascResults).toHaveLength(2);
715
715
  expect(ascResults.map(({ messageCid }) => messageCid)).toEqual(['c', 'd']);
716
716
  });
717
717
  it('can sort by any indexed property', async () => {
@@ -722,19 +722,19 @@ describe('IndexLevel', () => {
722
722
  const filters = [{ schema: 'schema' }];
723
723
  // sort by value ascending
724
724
  const ascResults = await testIndex.query(tenant, filters, { sortProperty: 'val' });
725
- expect(ascResults.length).toBe(testVals.length);
725
+ expect(ascResults).toHaveLength(testVals.length);
726
726
  expect(ascResults.map(({ messageCid }) => messageCid)).toEqual(['a', 'b', 'c', 'd']);
727
727
  // sort by index ascending
728
728
  const ascIndexResults = await testIndex.query(tenant, filters, { sortProperty: 'index' });
729
- expect(ascIndexResults.length).toBe(testVals.length);
729
+ expect(ascIndexResults).toHaveLength(testVals.length);
730
730
  expect(ascIndexResults.map(({ messageCid }) => messageCid)).toEqual(testVals);
731
731
  // sort by value descending
732
732
  const descResults = await testIndex.query(tenant, filters, { sortProperty: 'val', sortDirection: SortDirection.Descending });
733
- expect(descResults.length).toBe(testVals.length);
733
+ expect(descResults).toHaveLength(testVals.length);
734
734
  expect(descResults.map(({ messageCid }) => messageCid)).toEqual(['d', 'c', 'b', 'a']);
735
735
  // sort by index descending
736
736
  const descIndexResults = await testIndex.query(tenant, filters, { sortProperty: 'index', sortDirection: SortDirection.Descending });
737
- expect(descIndexResults.length).toBe(testVals.length);
737
+ expect(descIndexResults).toHaveLength(testVals.length);
738
738
  expect(descIndexResults.map(({ messageCid }) => messageCid)).toEqual([...testVals].reverse());
739
739
  });
740
740
  it('sorts lexicographic', async () => {
@@ -745,11 +745,11 @@ describe('IndexLevel', () => {
745
745
  const filters = [{ schema: 'schema' }];
746
746
  // sort ascending
747
747
  const ascResults = await testIndex.query(tenant, filters, { sortProperty: 'val' });
748
- expect(ascResults.length).toBe(4);
748
+ expect(ascResults).toHaveLength(4);
749
749
  expect(ascResults.map(({ messageCid }) => messageCid)).toEqual(['a', 'b', 'c', 'd']);
750
750
  // sort descending
751
751
  const descResults = await testIndex.query(tenant, filters, { sortProperty: 'val', sortDirection: SortDirection.Descending });
752
- expect(descResults.length).toBe(4);
752
+ expect(descResults).toHaveLength(4);
753
753
  expect(descResults.map(({ messageCid }) => messageCid)).toEqual(['d', 'c', 'b', 'a']);
754
754
  });
755
755
  it('sorts numeric with and without a cursor', async () => {
@@ -760,11 +760,11 @@ describe('IndexLevel', () => {
760
760
  const filters = [{ schema: 'schema' }];
761
761
  // sort ascending
762
762
  const ascResults = await testIndex.query(tenant, filters, { sortProperty: 'val' });
763
- expect(ascResults.length).toBe(testVals.length);
763
+ expect(ascResults).toHaveLength(testVals.length);
764
764
  expect(ascResults.map(({ messageCid }) => messageCid)).toEqual(['-2', '-1', '0', '1', '2', '3', '4']);
765
765
  // sort descending
766
766
  const descResults = await testIndex.query(tenant, filters, { sortProperty: 'val', sortDirection: SortDirection.Descending });
767
- expect(descResults.length).toEqual(testVals.length);
767
+ expect(descResults).toHaveLength(testVals.length);
768
768
  expect(descResults.map(({ messageCid }) => messageCid)).toEqual(['4', '3', '2', '1', '0', '-1', '-2']);
769
769
  });
770
770
  it('sorts range queries with or without a cursor', async () => {
@@ -1009,14 +1009,14 @@ describe('IndexLevel', () => {
1009
1009
  await testIndex.put(tenant, id1, doc1);
1010
1010
  await testIndex.put(tenant, id2, doc2);
1011
1011
  let result = await testIndex.query(tenant, [{ 'a': 'b', 'c': 'e' }], { sortProperty: 'id' });
1012
- expect(result.length).toBe(2);
1012
+ expect(result).toHaveLength(2);
1013
1013
  expect(result.map(({ messageCid }) => messageCid)).toContain(id1);
1014
1014
  await testIndex.delete(tenant, id1);
1015
1015
  result = await testIndex.query(tenant, [{ 'a': 'b', 'c': 'e' }], { sortProperty: 'id' });
1016
- expect(result.length).toBe(1);
1016
+ expect(result).toHaveLength(1);
1017
1017
  await testIndex.delete(tenant, id2);
1018
1018
  const allKeys = await ArrayUtility.fromAsyncGenerator(testIndex.db.keys());
1019
- expect(allKeys.length).toBe(0);
1019
+ expect(allKeys).toHaveLength(0);
1020
1020
  });
1021
1021
  it('should not delete anything if aborted beforehand', async () => {
1022
1022
  const controller = new AbortController();
@@ -1034,7 +1034,7 @@ describe('IndexLevel', () => {
1034
1034
  expect(e).toBe('reason');
1035
1035
  }
1036
1036
  const result = await testIndex.query(tenant, [{ foo: 'bar' }], { sortProperty: 'id' });
1037
- expect(result.length).toBe(1);
1037
+ expect(result).toHaveLength(1);
1038
1038
  expect(result.map(({ messageCid }) => messageCid)).toContain(id);
1039
1039
  });
1040
1040
  it('does nothing when attempting to purge key that does not exist', async () => {
@@ -1049,7 +1049,7 @@ describe('IndexLevel', () => {
1049
1049
  // attempt purge an invalid id
1050
1050
  await testIndex.delete(tenant, 'invalidCid');
1051
1051
  const result = await testIndex.query(tenant, [{ foo: 'bar' }], { sortProperty: 'id' });
1052
- expect(result.length).toBe(1);
1052
+ expect(result).toHaveLength(1);
1053
1053
  expect(result.map(({ messageCid }) => messageCid)).toContain(id);
1054
1054
  });
1055
1055
  });
@@ -1099,7 +1099,7 @@ describe('IndexLevel', () => {
1099
1099
  describe('createCursorFromLastArrayItem', () => {
1100
1100
  it('returns undefined if an empty array is provided', async () => {
1101
1101
  const cursor = IndexLevel.createCursorFromLastArrayItem([], 'someProperty');
1102
- expect(cursor).toBe(undefined);
1102
+ expect(cursor).toBeUndefined();
1103
1103
  });
1104
1104
  it('returns a PaginationCursor for the last item given a valid sort property', async () => {
1105
1105
  const items = [{
@@ -1138,7 +1138,7 @@ describe('IndexLevel', () => {
1138
1138
  it('should encode positive digits and pad with leading zeros', () => {
1139
1139
  const expectedLength = String(Number.MAX_SAFE_INTEGER).length; //16
1140
1140
  const encoded = IndexLevel.encodeNumberValue(100);
1141
- expect(encoded.length).toBe(expectedLength);
1141
+ expect(encoded).toHaveLength(expectedLength);
1142
1142
  expect(encoded).toBe('0000000000000100');
1143
1143
  });
1144
1144
  it('should encode negative digits as an offset with a prefix', () => {
@@ -1146,8 +1146,8 @@ describe('IndexLevel', () => {
1146
1146
  // expected length is maximum padding + the prefix.
1147
1147
  const expectedLength = (expectedPrefix + String(Number.MAX_SAFE_INTEGER)).length; //17
1148
1148
  const encoded = IndexLevel.encodeNumberValue(-100);
1149
- expect(encoded.length).toBe(String(Number.MIN_SAFE_INTEGER).length);
1150
- expect(encoded.length).toBe(expectedLength);
1149
+ expect(encoded).toHaveLength(String(Number.MIN_SAFE_INTEGER).length);
1150
+ expect(encoded).toHaveLength(expectedLength);
1151
1151
  expect(encoded).toBe('!9007199254740891');
1152
1152
  });
1153
1153
  it('should encode digits to sort using lexicographical comparison', () => {
@@ -1232,7 +1232,7 @@ describe('IndexLevel', () => {
1232
1232
  });
1233
1233
  // query using compound index (protocol + protocolPath sorted by messageTimestamp)
1234
1234
  const results = await compoundIndex.query(compoundTenant, [{ protocol: 'https://protocol.xyz', protocolPath: 'chat/message' }], { sortProperty: 'messageTimestamp' });
1235
- expect(results.length).toBe(1);
1235
+ expect(results).toHaveLength(1);
1236
1236
  expect(results[0].messageCid).toBe(id);
1237
1237
  });
1238
1238
  it('should delete compound index entries during delete', async () => {
@@ -1246,12 +1246,12 @@ describe('IndexLevel', () => {
1246
1246
  });
1247
1247
  // verify it exists
1248
1248
  let results = await compoundIndex.query(compoundTenant, [{ protocol: 'https://protocol.xyz', protocolPath: 'chat/message' }], { sortProperty: 'messageTimestamp' });
1249
- expect(results.length).toBe(1);
1249
+ expect(results).toHaveLength(1);
1250
1250
  // delete
1251
1251
  await compoundIndex.delete(compoundTenant, id);
1252
1252
  // verify compound index entries are removed
1253
1253
  results = await compoundIndex.query(compoundTenant, [{ protocol: 'https://protocol.xyz', protocolPath: 'chat/message' }], { sortProperty: 'messageTimestamp' });
1254
- expect(results.length).toBe(0);
1254
+ expect(results).toHaveLength(0);
1255
1255
  });
1256
1256
  it('should skip compound index entries when required properties are missing', async () => {
1257
1257
  const id = uuid();
@@ -1263,7 +1263,7 @@ describe('IndexLevel', () => {
1263
1263
  // the protocol+protocolPath compound index should not have entries
1264
1264
  // query via the schema compound index should still work
1265
1265
  const schemaResults = await compoundIndex.query(compoundTenant, [{ schema: 'https://schema.org/Message' }], { sortProperty: 'dateCreated' });
1266
- expect(schemaResults.length).toBe(1);
1266
+ expect(schemaResults).toHaveLength(1);
1267
1267
  expect(schemaResults[0].messageCid).toBe(id);
1268
1268
  });
1269
1269
  });
@@ -1283,7 +1283,7 @@ describe('IndexLevel', () => {
1283
1283
  });
1284
1284
  }
1285
1285
  const results = await compoundIndex.query(compoundTenant, [{ protocol: 'https://proto.xyz', protocolPath: 'thread/post' }], { sortProperty: 'messageTimestamp' });
1286
- expect(results.length).toBe(3);
1286
+ expect(results).toHaveLength(3);
1287
1287
  expect(results.map(r => r.messageCid)).toEqual(['msg-a', 'msg-b', 'msg-c']);
1288
1288
  });
1289
1289
  it('should return results sorted descending by the sort property', async () => {
@@ -1301,7 +1301,7 @@ describe('IndexLevel', () => {
1301
1301
  });
1302
1302
  }
1303
1303
  const results = await compoundIndex.query(compoundTenant, [{ protocol: 'https://proto.xyz', protocolPath: 'thread/post' }], { sortProperty: 'messageTimestamp', sortDirection: SortDirection.Descending });
1304
- expect(results.length).toBe(3);
1304
+ expect(results).toHaveLength(3);
1305
1305
  expect(results.map(r => r.messageCid)).toEqual(['msg-c', 'msg-b', 'msg-a']);
1306
1306
  });
1307
1307
  it('should support limit', async () => {
@@ -1313,7 +1313,7 @@ describe('IndexLevel', () => {
1313
1313
  });
1314
1314
  }
1315
1315
  const results = await compoundIndex.query(compoundTenant, [{ protocol: 'https://proto.xyz', protocolPath: 'items' }], { sortProperty: 'messageTimestamp', limit: 3 });
1316
- expect(results.length).toBe(3);
1316
+ expect(results).toHaveLength(3);
1317
1317
  expect(results.map(r => r.messageCid)).toEqual(['msg-0', 'msg-1', 'msg-2']);
1318
1318
  });
1319
1319
  it('should support cursor pagination ascending', async () => {
@@ -1326,12 +1326,12 @@ describe('IndexLevel', () => {
1326
1326
  }
1327
1327
  // first page
1328
1328
  const page1 = await compoundIndex.query(compoundTenant, [{ protocol: 'https://proto.xyz', protocolPath: 'items' }], { sortProperty: 'messageTimestamp', limit: 3 });
1329
- expect(page1.length).toBe(3);
1329
+ expect(page1).toHaveLength(3);
1330
1330
  expect(page1.map(r => r.messageCid)).toEqual(['msg-0', 'msg-1', 'msg-2']);
1331
1331
  // second page using cursor
1332
1332
  const cursor = IndexLevel.createCursorFromLastArrayItem(page1, 'messageTimestamp');
1333
1333
  const page2 = await compoundIndex.query(compoundTenant, [{ protocol: 'https://proto.xyz', protocolPath: 'items' }], { sortProperty: 'messageTimestamp', cursor });
1334
- expect(page2.length).toBe(3);
1334
+ expect(page2).toHaveLength(3);
1335
1335
  expect(page2.map(r => r.messageCid)).toEqual(['msg-3', 'msg-4', 'msg-5']);
1336
1336
  });
1337
1337
  it('should support cursor pagination descending', async () => {
@@ -1344,12 +1344,12 @@ describe('IndexLevel', () => {
1344
1344
  }
1345
1345
  // first page descending
1346
1346
  const page1 = await compoundIndex.query(compoundTenant, [{ protocol: 'https://proto.xyz', protocolPath: 'items' }], { sortProperty: 'messageTimestamp', sortDirection: SortDirection.Descending, limit: 3 });
1347
- expect(page1.length).toBe(3);
1347
+ expect(page1).toHaveLength(3);
1348
1348
  expect(page1.map(r => r.messageCid)).toEqual(['msg-5', 'msg-4', 'msg-3']);
1349
1349
  // second page descending using cursor
1350
1350
  const cursor = IndexLevel.createCursorFromLastArrayItem(page1, 'messageTimestamp');
1351
1351
  const page2 = await compoundIndex.query(compoundTenant, [{ protocol: 'https://proto.xyz', protocolPath: 'items' }], { sortProperty: 'messageTimestamp', sortDirection: SortDirection.Descending, cursor });
1352
- expect(page2.length).toBe(3);
1352
+ expect(page2).toHaveLength(3);
1353
1353
  expect(page2.map(r => r.messageCid)).toEqual(['msg-2', 'msg-1', 'msg-0']);
1354
1354
  });
1355
1355
  it('should verify residual filter properties in memory', async () => {
@@ -1365,7 +1365,7 @@ describe('IndexLevel', () => {
1365
1365
  // compound index covers protocol+protocolPath+messageTimestamp but NOT published
1366
1366
  // published should be verified as a residual filter
1367
1367
  const results = await compoundIndex.query(compoundTenant, [{ protocol: 'https://proto.xyz', protocolPath: 'items', published: true }], { sortProperty: 'messageTimestamp' });
1368
- expect(results.length).toBe(2);
1368
+ expect(results).toHaveLength(2);
1369
1369
  expect(results.map(r => r.messageCid)).toEqual(['msg-0', 'msg-2']);
1370
1370
  });
1371
1371
  it('should only return results matching the specific filter values', async () => {
@@ -1387,7 +1387,7 @@ describe('IndexLevel', () => {
1387
1387
  });
1388
1388
  // query for only protocol.xyz + thread/post
1389
1389
  const results = await compoundIndex.query(compoundTenant, [{ protocol: 'https://proto.xyz', protocolPath: 'thread/post' }], { sortProperty: 'messageTimestamp' });
1390
- expect(results.length).toBe(1);
1390
+ expect(results).toHaveLength(1);
1391
1391
  expect(results[0].messageCid).toBe('msg-1');
1392
1392
  });
1393
1393
  it('should fall back to non-compound strategy for OR (multi-filter) queries', async () => {
@@ -1406,7 +1406,7 @@ describe('IndexLevel', () => {
1406
1406
  { protocol: 'https://proto.xyz', protocolPath: 'thread/post' },
1407
1407
  { protocol: 'https://proto.xyz', protocolPath: 'thread/reply' },
1408
1408
  ], { sortProperty: 'messageTimestamp' });
1409
- expect(results.length).toBe(2);
1409
+ expect(results).toHaveLength(2);
1410
1410
  });
1411
1411
  it('should prefer the compound index with the most properties', async () => {
1412
1412
  // both compound indexes could potentially match a query with schema + dateCreated
@@ -1422,11 +1422,11 @@ describe('IndexLevel', () => {
1422
1422
  });
1423
1423
  // query using schema compound index
1424
1424
  const schemaResults = await compoundIndex.query(compoundTenant, [{ schema: 'https://schema.org/Item' }], { sortProperty: 'dateCreated' });
1425
- expect(schemaResults.length).toBe(1);
1425
+ expect(schemaResults).toHaveLength(1);
1426
1426
  expect(schemaResults[0].messageCid).toBe('msg-1');
1427
1427
  // query using protocol+protocolPath compound index
1428
1428
  const protocolResults = await compoundIndex.query(compoundTenant, [{ protocol: 'https://proto.xyz', protocolPath: 'items' }], { sortProperty: 'messageTimestamp' });
1429
- expect(protocolResults.length).toBe(1);
1429
+ expect(protocolResults).toHaveLength(1);
1430
1430
  expect(protocolResults[0].messageCid).toBe('msg-1');
1431
1431
  });
1432
1432
  it('should not use compound index when sort property does not match', async () => {
@@ -1441,7 +1441,7 @@ describe('IndexLevel', () => {
1441
1441
  // this should NOT use the protocol-protocolPath-messageTimestamp compound index
1442
1442
  // it should still return correct results via fallback strategy
1443
1443
  const results = await compoundIndex.query(compoundTenant, [{ protocol: 'https://proto.xyz', protocolPath: 'items' }], { sortProperty: 'dateCreated' });
1444
- expect(results.length).toBe(1);
1444
+ expect(results).toHaveLength(1);
1445
1445
  });
1446
1446
  });
1447
1447
  describe('count()', () => {
@@ -1534,12 +1534,12 @@ describe('IndexLevel', () => {
1534
1534
  }
1535
1535
  // first page
1536
1536
  const page1 = await compoundIndex.query(compoundTenant, [{ schema: 'https://schema.org/Item' }], { sortProperty: 'dateCreated', limit: 3 });
1537
- expect(page1.length).toBe(3);
1537
+ expect(page1).toHaveLength(3);
1538
1538
  expect(page1.map(r => r.messageCid)).toEqual(['msg-0', 'msg-1', 'msg-2']);
1539
1539
  // second page with cursor — this should still use the compound index
1540
1540
  const cursor = IndexLevel.createCursorFromLastArrayItem(page1, 'dateCreated');
1541
1541
  const page2 = await compoundIndex.query(compoundTenant, [{ schema: 'https://schema.org/Item' }], { sortProperty: 'dateCreated', cursor });
1542
- expect(page2.length).toBe(3);
1542
+ expect(page2).toHaveLength(3);
1543
1543
  expect(page2.map(r => r.messageCid)).toEqual(['msg-3', 'msg-4', 'msg-5']);
1544
1544
  });
1545
1545
  });