Skip to content

Commit 37a0d7c

Browse files
committed
temp
1 parent 2fe609f commit 37a0d7c

File tree

4 files changed

+52
-83
lines changed

4 files changed

+52
-83
lines changed

apps/meteor/client/lib/cachedCollections/Cursor.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -580,7 +580,7 @@ export class Cursor<T extends { _id: string }, TOptions extends Options<T>, TPro
580580
// else.
581581
if (this.reactive) {
582582
qid = this.collection.claimNextQueryId();
583-
this.collection._queries[qid] = query;
583+
this.collection.queries.set(qid, query);
584584
}
585585

586586
query.results = this._getRawObjects({ ordered });
@@ -653,7 +653,7 @@ export class Cursor<T extends { _id: string }, TOptions extends Options<T>, TPro
653653
collection: this.collection,
654654
stop: () => {
655655
if (this.reactive) {
656-
delete this.collection._queries[qid];
656+
this.collection.queries.delete(qid);
657657
}
658658
},
659659
isReady: false,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
export interface IDocumentMapStore<T extends { _id: string }> {
2+
readonly records: T[];
3+
has(_id: T['_id']): boolean;
4+
get(_id: T['_id']): T | undefined;
5+
find<U extends T>(predicate: (record: T) => record is U): U | undefined;
6+
find(predicate: (record: T) => boolean): T | undefined;
7+
filter<U extends T>(predicate: (record: T) => record is U): U[];
8+
filter(predicate: (record: T) => boolean): T[];
9+
replaceAll(records: T[]): void;
10+
}

apps/meteor/client/lib/cachedCollections/LocalCollection.ts

+38-71
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import type { StoreApi, UseBoundStore } from 'zustand';
44

55
import { Cursor, type DispatchTransform } from './Cursor';
66
import { DiffSequence } from './DiffSequence';
7+
import type { IDocumentMapStore } from './IDocumentMapStore';
78
import { IdMap } from './IdMap';
89
import { Matcher } from './Matcher';
910
import type { Options } from './MinimongoCollection';
@@ -180,25 +181,18 @@ export class LocalCollection<T extends { _id: string }> implements ILocalCollect
180181

181182
private nextQueryIdCounter = 1;
182183

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>>();
191185

192186
// null if not saving originals; an IdMap from id to original document value
193187
// if saving originals. See comments before saveOriginals().
194188
private _savedOriginals: IdMap<T['_id'], T | undefined> | null = null;
195189

196190
paused = false;
197191

198-
constructor(protected store: UseBoundStore<StoreApi<{ records: T[] }>>) {}
192+
constructor(protected store: UseBoundStore<StoreApi<IDocumentMapStore<T>>>) {}
199193

200194
private has(id: T['_id']) {
201-
return this.store.getState().records.some((record) => record._id === id);
195+
return this.store.getState().has(id);
202196
}
203197

204198
private get(id: T['_id']) {
@@ -240,10 +234,6 @@ export class LocalCollection<T extends { _id: string }> implements ILocalCollect
240234
return `${this.nextQueryIdCounter++}` as QueryId;
241235
}
242236

243-
getAllQueryIds() {
244-
return Object.keys(this._queries) as QueryId[];
245-
}
246-
247237
find(selector: Filter<T> | T['_id'] = {}, options?: Options<T>) {
248238
return new Cursor(this, selector, options);
249239
}
@@ -290,12 +280,10 @@ export class LocalCollection<T extends { _id: string }> implements ILocalCollect
290280
insert(doc: T, callback?: (error: Error | null, id: T['_id']) => void) {
291281
doc = clone(doc);
292282
const id = this.prepareInsert(doc);
293-
const queriesToRecompute = new Set<QueryId>();
283+
const queriesToRecompute = new Set<Query<T, Options<T>, any>>();
294284

295285
// 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()) {
299287
if (query.dirty) {
300288
continue;
301289
}
@@ -304,17 +292,15 @@ export class LocalCollection<T extends { _id: string }> implements ILocalCollect
304292

305293
if (matchResult.result) {
306294
if (query.cursor.skip || query.cursor.limit) {
307-
queriesToRecompute.add(qid);
295+
queriesToRecompute.add(query);
308296
} else {
309297
this._insertInResultsSync(query, doc);
310298
}
311299
}
312300
}
313301

314-
queriesToRecompute.forEach((qid) => {
315-
if (this._queries[qid]) {
316-
this._recomputeResults(this._queries[qid]);
317-
}
302+
queriesToRecompute.forEach((query) => {
303+
this._recomputeResults(query);
318304
});
319305

320306
this._observeQueue.drain();
@@ -326,12 +312,10 @@ export class LocalCollection<T extends { _id: string }> implements ILocalCollect
326312
async insertAsync(doc: T, callback?: (error: Error | null, id: T['_id']) => void) {
327313
doc = clone(doc);
328314
const id = this.prepareInsert(doc);
329-
const queriesToRecompute = new Set<QueryId>();
315+
const queriesToRecompute = new Set<Query<T, Options<T>, any>>();
330316

331317
// 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()) {
335319
if (query.dirty) {
336320
continue;
337321
}
@@ -340,18 +324,16 @@ export class LocalCollection<T extends { _id: string }> implements ILocalCollect
340324

341325
if (matchResult.result) {
342326
if (query.cursor.skip || query.cursor.limit) {
343-
queriesToRecompute.add(qid);
327+
queriesToRecompute.add(query);
344328
} else {
345329
// eslint-disable-next-line no-await-in-loop
346330
await this._insertInResultsAsync(query, doc);
347331
}
348332
}
349333
}
350334

351-
queriesToRecompute.forEach((qid) => {
352-
if (this._queries[qid]) {
353-
this._recomputeResults(this._queries[qid]);
354-
}
335+
queriesToRecompute.forEach((query) => {
336+
this._recomputeResults(query);
355337
});
356338

357339
await this._observeQueue.drain();
@@ -372,26 +354,23 @@ export class LocalCollection<T extends { _id: string }> implements ILocalCollect
372354
this.paused = true;
373355

374356
// 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()) {
377358
query.resultsSnapshot = clone(query.results);
378-
});
359+
}
379360
}
380361

381362
clearResultQueries(callback?: (error: Error | null, result: number) => void) {
382363
const result = this.count();
383364

384365
this.clear();
385366

386-
this.getAllQueryIds().forEach((qid) => {
387-
const query = this._queries[qid];
388-
367+
for (const query of this.queries.values()) {
389368
if (query.ordered) {
390369
query.results = [];
391370
} else {
392371
(query.results as IdMap<T['_id'], T>).clear();
393372
}
394-
});
373+
}
395374

396375
this.deferCallback(callback, null, result);
397376

@@ -414,11 +393,9 @@ export class LocalCollection<T extends { _id: string }> implements ILocalCollect
414393
for (const removeId of remove) {
415394
const removeDoc = this.get(removeId)!;
416395

417-
this.getAllQueryIds().forEach((qid) => {
418-
const query = this._queries[qid];
419-
396+
for (const [qid, query] of this.queries.entries()) {
420397
if (query.dirty) {
421-
return;
398+
continue;
422399
}
423400

424401
if (query.matcher.documentMatches(removeDoc).result) {
@@ -428,7 +405,7 @@ export class LocalCollection<T extends { _id: string }> implements ILocalCollect
428405
queryRemove.add({ qid, doc: removeDoc });
429406
}
430407
}
431-
});
408+
}
432409

433410
this._saveOriginal(removeId, removeDoc);
434411
this.delete(removeId);
@@ -449,15 +426,15 @@ export class LocalCollection<T extends { _id: string }> implements ILocalCollect
449426

450427
// run live query callbacks _after_ we've removed the documents.
451428
queryRemove.forEach((remove) => {
452-
const query = this._queries[remove.qid];
429+
const query = this.queries.get(remove.qid);
453430

454431
if (query) {
455432
this._removeFromResultsSync(query, remove.doc);
456433
}
457434
});
458435

459436
queriesToRecompute.forEach((qid) => {
460-
const query = this._queries[qid];
437+
const query = this.queries.get(qid);
461438

462439
if (query) {
463440
this._recomputeResults(query);
@@ -485,15 +462,15 @@ export class LocalCollection<T extends { _id: string }> implements ILocalCollect
485462

486463
// run live query callbacks _after_ we've removed the documents.
487464
for (const remove of queryRemove) {
488-
const query = this._queries[remove.qid];
465+
const query = this.queries.get(remove.qid);
489466

490467
if (query) {
491468
// eslint-disable-next-line no-await-in-loop
492469
await this._removeFromResultsAsync(query, remove.doc);
493470
}
494471
}
495472
queriesToRecompute.forEach((qid) => {
496-
const query = this._queries[qid];
473+
const query = this.queries.get(qid);
497474

498475
if (query) {
499476
this._recomputeResults(query);
@@ -523,9 +500,7 @@ export class LocalCollection<T extends { _id: string }> implements ILocalCollect
523500
// observer methods won't actually fire when we trigger them.
524501
this.paused = false;
525502

526-
this.getAllQueryIds().forEach((qid) => {
527-
const query = this._queries[qid];
528-
503+
for (const query of this.queries.values()) {
529504
if (query.dirty) {
530505
query.dirty = false;
531506

@@ -541,7 +516,7 @@ export class LocalCollection<T extends { _id: string }> implements ILocalCollect
541516
}
542517

543518
query.resultsSnapshot = null;
544-
});
519+
}
545520
}
546521

547522
async resumeObserversServer() {
@@ -594,9 +569,7 @@ export class LocalCollection<T extends { _id: string }> implements ILocalCollect
594569
const docMap = new IdMap<T['_id'], T>();
595570
const idsMatched = this._idsMatchedBySelector(selector);
596571

597-
this.getAllQueryIds().forEach((qid) => {
598-
const query = this._queries[qid];
599-
572+
for (const [qid, query] of this.queries.entries()) {
600573
if ((query.cursor.skip || query.cursor.limit) && !this.paused) {
601574
// Catch the case of a reactive `count()` on a cursor with skip
602575
// or limit, which registers an unordered observe. This is a
@@ -605,7 +578,7 @@ export class LocalCollection<T extends { _id: string }> implements ILocalCollect
605578
// sets and other queries.
606579
if (!!query.results && !Array.isArray(query.results)) {
607580
qidToOriginalResults[qid] = query.results.clone();
608-
return;
581+
continue;
609582
}
610583

611584
if (!Array.isArray(query.results)) {
@@ -630,7 +603,7 @@ export class LocalCollection<T extends { _id: string }> implements ILocalCollect
630603

631604
qidToOriginalResults[qid] = query.results.map(memoizedCloneIfNeeded);
632605
}
633-
});
606+
}
634607

635608
return qidToOriginalResults;
636609
}
@@ -730,7 +703,7 @@ export class LocalCollection<T extends { _id: string }> implements ILocalCollect
730703
});
731704

732705
(Object.keys(recomputeQids) as QueryId[]).forEach((qid) => {
733-
const query = this._queries[qid];
706+
const query = this.queries.get(qid);
734707

735708
if (query) {
736709
this._recomputeResults(query, qidToOriginalResults[qid]);
@@ -832,7 +805,7 @@ export class LocalCollection<T extends { _id: string }> implements ILocalCollect
832805
});
833806

834807
recomputeQids.forEach((qid) => {
835-
const query = this._queries[qid];
808+
const query = this.queries.get(qid);
836809
if (query) {
837810
this._recomputeResults(query, qidToOriginalResults[qid]);
838811
}
@@ -979,11 +952,9 @@ export class LocalCollection<T extends { _id: string }> implements ILocalCollect
979952
_getMatchedDocAndModify(doc: T) {
980953
const matchedBefore = new Map<QueryId, boolean>();
981954

982-
this.getAllQueryIds().forEach((qid) => {
983-
const query = this._queries[qid];
984-
955+
for (const [qid, query] of this.queries.entries()) {
985956
if (query.dirty) {
986-
return;
957+
continue;
987958
}
988959

989960
if (query.ordered) {
@@ -993,7 +964,7 @@ export class LocalCollection<T extends { _id: string }> implements ILocalCollect
993964
// can just do a direct lookup.
994965
matchedBefore.set(qid, (query.results as IdMap<T['_id'], T>).has(doc._id));
995966
}
996-
});
967+
}
997968

998969
return matchedBefore;
999970
}
@@ -1007,9 +978,7 @@ export class LocalCollection<T extends { _id: string }> implements ILocalCollect
1007978

1008979
const recomputeQids = new Set<QueryId>();
1009980

1010-
for (const qid of this.getAllQueryIds()) {
1011-
const query = this._queries[qid];
1012-
981+
for (const [qid, query] of this.queries.entries()) {
1013982
if (query.dirty) {
1014983
continue;
1015984
}
@@ -1048,9 +1017,7 @@ export class LocalCollection<T extends { _id: string }> implements ILocalCollect
10481017
this.set(doc);
10491018

10501019
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()) {
10541021
if (query.dirty) {
10551022
continue;
10561023
}
@@ -1116,7 +1083,7 @@ export class LocalCollection<T extends { _id: string }> implements ILocalCollect
11161083
}
11171084

11181085
recomputeAllResults() {
1119-
for (const query of Object.values(this._queries)) {
1086+
for (const query of this.queries.values()) {
11201087
this._recomputeResults(query);
11211088
}
11221089
}

apps/meteor/client/lib/cachedCollections/MinimongoCollection.ts

+2-10
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type { Filter, Hint, Sort } from 'mongodb';
33
import { create } from 'zustand';
44

55
import type { DispatchTransform } from './Cursor';
6+
import type { IDocumentMapStore } from './IDocumentMapStore';
67
import { LocalCollection } from './LocalCollection';
78

89
export type Transform<T> = ((doc: T) => any) | null | undefined;
@@ -33,19 +34,10 @@ export type Options<T> = {
3334
transform?: Transform<T> | undefined;
3435
};
3536

36-
interface IDocumentMapStore<T extends { _id: string }> {
37-
records: T[];
38-
get(_id: T['_id']): T | undefined;
39-
find<U extends T>(predicate: (record: T) => record is U): U | undefined;
40-
find(predicate: (record: T) => boolean): T | undefined;
41-
filter<U extends T>(predicate: (record: T) => record is U): U[];
42-
filter(predicate: (record: T) => boolean): T[];
43-
replaceAll(records: T[]): void;
44-
}
45-
4637
export class MinimongoCollection<T extends { _id: string }> extends Mongo.Collection<T> {
4738
readonly use = create<IDocumentMapStore<T>>()((set, get) => ({
4839
records: [],
40+
has: (id: T['_id']) => get().records.some((record) => record._id === id),
4941
get: (id: T['_id']) => get().records.find((record) => record._id === id),
5042
find: (predicate: (record: T) => boolean) => get().records.find(predicate),
5143
filter: (predicate: (record: T) => boolean) => get().records.filter(predicate),

0 commit comments

Comments
 (0)