@@ -4,6 +4,7 @@ import type { StoreApi, UseBoundStore } from 'zustand';
4
4
5
5
import { Cursor , type DispatchTransform } from './Cursor' ;
6
6
import { DiffSequence } from './DiffSequence' ;
7
+ import type { IDocumentMapStore } from './IDocumentMapStore' ;
7
8
import { IdMap } from './IdMap' ;
8
9
import { Matcher } from './Matcher' ;
9
10
import type { Options } from './MinimongoCollection' ;
@@ -180,25 +181,18 @@ export class LocalCollection<T extends { _id: string }> implements ILocalCollect
180
181
181
182
private nextQueryIdCounter = 1 ;
182
183
183
- // qid -> live query object. keys:
184
- // ordered: bool. ordered queries have addedBefore/movedBefore callbacks.
185
- // results: array (ordered) or object (unordered) of current results
186
- // (aliased with this._docs!)
187
- // resultsSnapshot: snapshot of results. null if not paused.
188
- // cursor: Cursor object for the query.
189
- // selector, sorter, (callbacks): functions
190
- _queries : Record < QueryId , Query < T , Options < T > , any > > = Object . create ( null ) ;
184
+ readonly queries = new Map < QueryId , Query < T , Options < T > , any > > ( ) ;
191
185
192
186
// null if not saving originals; an IdMap from id to original document value
193
187
// if saving originals. See comments before saveOriginals().
194
188
private _savedOriginals : IdMap < T [ '_id' ] , T | undefined > | null = null ;
195
189
196
190
paused = false ;
197
191
198
- constructor ( protected store : UseBoundStore < StoreApi < { records : T [ ] } > > ) { }
192
+ constructor ( protected store : UseBoundStore < StoreApi < IDocumentMapStore < T > > > ) { }
199
193
200
194
private has ( id : T [ '_id' ] ) {
201
- return this . store . getState ( ) . records . some ( ( record ) => record . _id === id ) ;
195
+ return this . store . getState ( ) . has ( id ) ;
202
196
}
203
197
204
198
private get ( id : T [ '_id' ] ) {
@@ -240,10 +234,6 @@ export class LocalCollection<T extends { _id: string }> implements ILocalCollect
240
234
return `${ this . nextQueryIdCounter ++ } ` as QueryId ;
241
235
}
242
236
243
- getAllQueryIds ( ) {
244
- return Object . keys ( this . _queries ) as QueryId [ ] ;
245
- }
246
-
247
237
find ( selector : Filter < T > | T [ '_id' ] = { } , options ?: Options < T > ) {
248
238
return new Cursor ( this , selector , options ) ;
249
239
}
@@ -290,12 +280,10 @@ export class LocalCollection<T extends { _id: string }> implements ILocalCollect
290
280
insert ( doc : T , callback ?: ( error : Error | null , id : T [ '_id' ] ) => void ) {
291
281
doc = clone ( doc ) ;
292
282
const id = this . prepareInsert ( doc ) ;
293
- const queriesToRecompute = new Set < QueryId > ( ) ;
283
+ const queriesToRecompute = new Set < Query < T , Options < T > , any > > ( ) ;
294
284
295
285
// trigger live queries that match
296
- for ( const qid of this . getAllQueryIds ( ) ) {
297
- const query = this . _queries [ qid ] ;
298
-
286
+ for ( const query of this . queries . values ( ) ) {
299
287
if ( query . dirty ) {
300
288
continue ;
301
289
}
@@ -304,17 +292,15 @@ export class LocalCollection<T extends { _id: string }> implements ILocalCollect
304
292
305
293
if ( matchResult . result ) {
306
294
if ( query . cursor . skip || query . cursor . limit ) {
307
- queriesToRecompute . add ( qid ) ;
295
+ queriesToRecompute . add ( query ) ;
308
296
} else {
309
297
this . _insertInResultsSync ( query , doc ) ;
310
298
}
311
299
}
312
300
}
313
301
314
- queriesToRecompute . forEach ( ( qid ) => {
315
- if ( this . _queries [ qid ] ) {
316
- this . _recomputeResults ( this . _queries [ qid ] ) ;
317
- }
302
+ queriesToRecompute . forEach ( ( query ) => {
303
+ this . _recomputeResults ( query ) ;
318
304
} ) ;
319
305
320
306
this . _observeQueue . drain ( ) ;
@@ -326,12 +312,10 @@ export class LocalCollection<T extends { _id: string }> implements ILocalCollect
326
312
async insertAsync ( doc : T , callback ?: ( error : Error | null , id : T [ '_id' ] ) => void ) {
327
313
doc = clone ( doc ) ;
328
314
const id = this . prepareInsert ( doc ) ;
329
- const queriesToRecompute = new Set < QueryId > ( ) ;
315
+ const queriesToRecompute = new Set < Query < T , Options < T > , any > > ( ) ;
330
316
331
317
// trigger live queries that match
332
- for ( const qid of this . getAllQueryIds ( ) ) {
333
- const query = this . _queries [ qid ] ;
334
-
318
+ for ( const query of this . queries . values ( ) ) {
335
319
if ( query . dirty ) {
336
320
continue ;
337
321
}
@@ -340,18 +324,16 @@ export class LocalCollection<T extends { _id: string }> implements ILocalCollect
340
324
341
325
if ( matchResult . result ) {
342
326
if ( query . cursor . skip || query . cursor . limit ) {
343
- queriesToRecompute . add ( qid ) ;
327
+ queriesToRecompute . add ( query ) ;
344
328
} else {
345
329
// eslint-disable-next-line no-await-in-loop
346
330
await this . _insertInResultsAsync ( query , doc ) ;
347
331
}
348
332
}
349
333
}
350
334
351
- queriesToRecompute . forEach ( ( qid ) => {
352
- if ( this . _queries [ qid ] ) {
353
- this . _recomputeResults ( this . _queries [ qid ] ) ;
354
- }
335
+ queriesToRecompute . forEach ( ( query ) => {
336
+ this . _recomputeResults ( query ) ;
355
337
} ) ;
356
338
357
339
await this . _observeQueue . drain ( ) ;
@@ -372,26 +354,23 @@ export class LocalCollection<T extends { _id: string }> implements ILocalCollect
372
354
this . paused = true ;
373
355
374
356
// Take a snapshot of the query results for each query.
375
- this . getAllQueryIds ( ) . forEach ( ( qid ) => {
376
- const query = this . _queries [ qid ] ;
357
+ for ( const query of this . queries . values ( ) ) {
377
358
query . resultsSnapshot = clone ( query . results ) ;
378
- } ) ;
359
+ }
379
360
}
380
361
381
362
clearResultQueries ( callback ?: ( error : Error | null , result : number ) => void ) {
382
363
const result = this . count ( ) ;
383
364
384
365
this . clear ( ) ;
385
366
386
- this . getAllQueryIds ( ) . forEach ( ( qid ) => {
387
- const query = this . _queries [ qid ] ;
388
-
367
+ for ( const query of this . queries . values ( ) ) {
389
368
if ( query . ordered ) {
390
369
query . results = [ ] ;
391
370
} else {
392
371
( query . results as IdMap < T [ '_id' ] , T > ) . clear ( ) ;
393
372
}
394
- } ) ;
373
+ }
395
374
396
375
this . deferCallback ( callback , null , result ) ;
397
376
@@ -414,11 +393,9 @@ export class LocalCollection<T extends { _id: string }> implements ILocalCollect
414
393
for ( const removeId of remove ) {
415
394
const removeDoc = this . get ( removeId ) ! ;
416
395
417
- this . getAllQueryIds ( ) . forEach ( ( qid ) => {
418
- const query = this . _queries [ qid ] ;
419
-
396
+ for ( const [ qid , query ] of this . queries . entries ( ) ) {
420
397
if ( query . dirty ) {
421
- return ;
398
+ continue ;
422
399
}
423
400
424
401
if ( query . matcher . documentMatches ( removeDoc ) . result ) {
@@ -428,7 +405,7 @@ export class LocalCollection<T extends { _id: string }> implements ILocalCollect
428
405
queryRemove . add ( { qid, doc : removeDoc } ) ;
429
406
}
430
407
}
431
- } ) ;
408
+ }
432
409
433
410
this . _saveOriginal ( removeId , removeDoc ) ;
434
411
this . delete ( removeId ) ;
@@ -449,15 +426,15 @@ export class LocalCollection<T extends { _id: string }> implements ILocalCollect
449
426
450
427
// run live query callbacks _after_ we've removed the documents.
451
428
queryRemove . forEach ( ( remove ) => {
452
- const query = this . _queries [ remove . qid ] ;
429
+ const query = this . queries . get ( remove . qid ) ;
453
430
454
431
if ( query ) {
455
432
this . _removeFromResultsSync ( query , remove . doc ) ;
456
433
}
457
434
} ) ;
458
435
459
436
queriesToRecompute . forEach ( ( qid ) => {
460
- const query = this . _queries [ qid ] ;
437
+ const query = this . queries . get ( qid ) ;
461
438
462
439
if ( query ) {
463
440
this . _recomputeResults ( query ) ;
@@ -485,15 +462,15 @@ export class LocalCollection<T extends { _id: string }> implements ILocalCollect
485
462
486
463
// run live query callbacks _after_ we've removed the documents.
487
464
for ( const remove of queryRemove ) {
488
- const query = this . _queries [ remove . qid ] ;
465
+ const query = this . queries . get ( remove . qid ) ;
489
466
490
467
if ( query ) {
491
468
// eslint-disable-next-line no-await-in-loop
492
469
await this . _removeFromResultsAsync ( query , remove . doc ) ;
493
470
}
494
471
}
495
472
queriesToRecompute . forEach ( ( qid ) => {
496
- const query = this . _queries [ qid ] ;
473
+ const query = this . queries . get ( qid ) ;
497
474
498
475
if ( query ) {
499
476
this . _recomputeResults ( query ) ;
@@ -523,9 +500,7 @@ export class LocalCollection<T extends { _id: string }> implements ILocalCollect
523
500
// observer methods won't actually fire when we trigger them.
524
501
this . paused = false ;
525
502
526
- this . getAllQueryIds ( ) . forEach ( ( qid ) => {
527
- const query = this . _queries [ qid ] ;
528
-
503
+ for ( const query of this . queries . values ( ) ) {
529
504
if ( query . dirty ) {
530
505
query . dirty = false ;
531
506
@@ -541,7 +516,7 @@ export class LocalCollection<T extends { _id: string }> implements ILocalCollect
541
516
}
542
517
543
518
query . resultsSnapshot = null ;
544
- } ) ;
519
+ }
545
520
}
546
521
547
522
async resumeObserversServer ( ) {
@@ -594,9 +569,7 @@ export class LocalCollection<T extends { _id: string }> implements ILocalCollect
594
569
const docMap = new IdMap < T [ '_id' ] , T > ( ) ;
595
570
const idsMatched = this . _idsMatchedBySelector ( selector ) ;
596
571
597
- this . getAllQueryIds ( ) . forEach ( ( qid ) => {
598
- const query = this . _queries [ qid ] ;
599
-
572
+ for ( const [ qid , query ] of this . queries . entries ( ) ) {
600
573
if ( ( query . cursor . skip || query . cursor . limit ) && ! this . paused ) {
601
574
// Catch the case of a reactive `count()` on a cursor with skip
602
575
// or limit, which registers an unordered observe. This is a
@@ -605,7 +578,7 @@ export class LocalCollection<T extends { _id: string }> implements ILocalCollect
605
578
// sets and other queries.
606
579
if ( ! ! query . results && ! Array . isArray ( query . results ) ) {
607
580
qidToOriginalResults [ qid ] = query . results . clone ( ) ;
608
- return ;
581
+ continue ;
609
582
}
610
583
611
584
if ( ! Array . isArray ( query . results ) ) {
@@ -630,7 +603,7 @@ export class LocalCollection<T extends { _id: string }> implements ILocalCollect
630
603
631
604
qidToOriginalResults [ qid ] = query . results . map ( memoizedCloneIfNeeded ) ;
632
605
}
633
- } ) ;
606
+ }
634
607
635
608
return qidToOriginalResults ;
636
609
}
@@ -730,7 +703,7 @@ export class LocalCollection<T extends { _id: string }> implements ILocalCollect
730
703
} ) ;
731
704
732
705
( Object . keys ( recomputeQids ) as QueryId [ ] ) . forEach ( ( qid ) => {
733
- const query = this . _queries [ qid ] ;
706
+ const query = this . queries . get ( qid ) ;
734
707
735
708
if ( query ) {
736
709
this . _recomputeResults ( query , qidToOriginalResults [ qid ] ) ;
@@ -832,7 +805,7 @@ export class LocalCollection<T extends { _id: string }> implements ILocalCollect
832
805
} ) ;
833
806
834
807
recomputeQids . forEach ( ( qid ) => {
835
- const query = this . _queries [ qid ] ;
808
+ const query = this . queries . get ( qid ) ;
836
809
if ( query ) {
837
810
this . _recomputeResults ( query , qidToOriginalResults [ qid ] ) ;
838
811
}
@@ -979,11 +952,9 @@ export class LocalCollection<T extends { _id: string }> implements ILocalCollect
979
952
_getMatchedDocAndModify ( doc : T ) {
980
953
const matchedBefore = new Map < QueryId , boolean > ( ) ;
981
954
982
- this . getAllQueryIds ( ) . forEach ( ( qid ) => {
983
- const query = this . _queries [ qid ] ;
984
-
955
+ for ( const [ qid , query ] of this . queries . entries ( ) ) {
985
956
if ( query . dirty ) {
986
- return ;
957
+ continue ;
987
958
}
988
959
989
960
if ( query . ordered ) {
@@ -993,7 +964,7 @@ export class LocalCollection<T extends { _id: string }> implements ILocalCollect
993
964
// can just do a direct lookup.
994
965
matchedBefore . set ( qid , ( query . results as IdMap < T [ '_id' ] , T > ) . has ( doc . _id ) ) ;
995
966
}
996
- } ) ;
967
+ }
997
968
998
969
return matchedBefore ;
999
970
}
@@ -1007,9 +978,7 @@ export class LocalCollection<T extends { _id: string }> implements ILocalCollect
1007
978
1008
979
const recomputeQids = new Set < QueryId > ( ) ;
1009
980
1010
- for ( const qid of this . getAllQueryIds ( ) ) {
1011
- const query = this . _queries [ qid ] ;
1012
-
981
+ for ( const [ qid , query ] of this . queries . entries ( ) ) {
1013
982
if ( query . dirty ) {
1014
983
continue ;
1015
984
}
@@ -1048,9 +1017,7 @@ export class LocalCollection<T extends { _id: string }> implements ILocalCollect
1048
1017
this . set ( doc ) ;
1049
1018
1050
1019
const recomputeQids : Record < QueryId , boolean > = { } ;
1051
- for ( const qid of this . getAllQueryIds ( ) ) {
1052
- const query = this . _queries [ qid ] ;
1053
-
1020
+ for ( const [ qid , query ] of this . queries . entries ( ) ) {
1054
1021
if ( query . dirty ) {
1055
1022
continue ;
1056
1023
}
@@ -1116,7 +1083,7 @@ export class LocalCollection<T extends { _id: string }> implements ILocalCollect
1116
1083
}
1117
1084
1118
1085
recomputeAllResults ( ) {
1119
- for ( const query of Object . values ( this . _queries ) ) {
1086
+ for ( const query of this . queries . values ( ) ) {
1120
1087
this . _recomputeResults ( query ) ;
1121
1088
}
1122
1089
}
0 commit comments