@@ -24,8 +24,6 @@ import {
24
24
stringify
25
25
} from '@firebase/util' ;
26
26
27
- import { ValueEventRegistration } from '../api/Reference_impl' ;
28
-
29
27
import { AppCheckTokenProvider } from './AppCheckTokenProvider' ;
30
28
import { AuthTokenProvider } from './AuthTokenProvider' ;
31
29
import { PersistentConnection } from './PersistentConnection' ;
@@ -63,7 +61,7 @@ import {
63
61
syncTreeCalcCompleteEventCache ,
64
62
syncTreeGetServerValue ,
65
63
syncTreeRemoveEventRegistration ,
66
- syncTreeTagForQuery
64
+ syncTreeRegisterQuery
67
65
} from './SyncTree' ;
68
66
import { Indexable } from './util/misc' ;
69
67
import {
@@ -445,6 +443,7 @@ function repoUpdateInfo(repo: Repo, pathString: string, value: unknown): void {
445
443
function repoGetNextWriteId ( repo : Repo ) : number {
446
444
return repo . nextWriteId_ ++ ;
447
445
}
446
+
448
447
/**
449
448
* The purpose of `getValue` is to return the latest known value
450
449
* satisfying `query`.
@@ -453,18 +452,14 @@ function repoGetNextWriteId(repo: Repo): number {
453
452
* belonging to active listeners. If they are found, such values
454
453
* are considered to be the most up-to-date.
455
454
*
456
- * If the client is not connected, this method will wait until the
457
- * repo has established a connection and then request the value for `query`.
458
- * If the client is not able to retrieve the query result for another reason,
459
- * it reports an error.
455
+ * If the client is not connected, this method will try to
456
+ * establish a connection and request the value for `query`. If
457
+ * the client is not able to retrieve the query result, it reports
458
+ * an error.
460
459
*
461
460
* @param query - The query to surface a value for.
462
461
*/
463
- export function repoGetValue (
464
- repo : Repo ,
465
- query : QueryContext ,
466
- eventRegistration : ValueEventRegistration
467
- ) : Promise < Node > {
462
+ export function repoGetValue ( repo : Repo , query : QueryContext ) : Promise < Node > {
468
463
// Only active queries are cached. There is no persisted cache.
469
464
const cached = syncTreeGetServerValue ( repo . serverSyncTree_ , query ) ;
470
465
if ( cached != null ) {
@@ -475,57 +470,32 @@ export function repoGetValue(
475
470
const node = nodeFromJSON ( payload ) . withIndex (
476
471
query . _queryParams . getIndex ( )
477
472
) ;
478
- /**
479
- * Below we simulate the actions of an `onlyOnce` `onValue()` event where:
480
- * Add an event registration,
481
- * Update data at the path,
482
- * Raise any events,
483
- * Cleanup the SyncTree
484
- */
485
- syncTreeAddEventRegistration (
486
- repo . serverSyncTree_ ,
487
- query ,
488
- eventRegistration ,
489
- true
490
- ) ;
491
- let events : Event [ ] ;
473
+ // if this is a filtered query, then overwrite at path
492
474
if ( query . _queryParams . loadsAllData ( ) ) {
493
- events = syncTreeApplyServerOverwrite (
494
- repo . serverSyncTree_ ,
495
- query . _path ,
496
- node
497
- ) ;
475
+ syncTreeApplyServerOverwrite ( repo . serverSyncTree_ , query . _path , node ) ;
498
476
} else {
499
- const tag = syncTreeTagForQuery ( repo . serverSyncTree_ , query ) ;
500
- events = syncTreeApplyTaggedQueryOverwrite (
477
+ // Simulate `syncTreeAddEventRegistration` without events/listener setup.
478
+ // We do this (along with the syncTreeRemoveEventRegistration` below) so that
479
+ // `repoGetValue` results have the same cache effects as initial listener(s)
480
+ // updates.
481
+ const tag = syncTreeRegisterQuery ( repo . serverSyncTree_ , query ) ;
482
+ syncTreeApplyTaggedQueryOverwrite (
501
483
repo . serverSyncTree_ ,
502
484
query . _path ,
503
485
node ,
504
486
tag
505
487
) ;
488
+ // Call `syncTreeRemoveEventRegistration` with a null event registration, since there is none.
489
+ // Note: The below code essentially unregisters the query and cleans up any views/syncpoints temporarily created above.
506
490
}
507
- /*
508
- * We need to raise events in the scenario where `get()` is called at a parent path, and
509
- * while the `get()` is pending, `onValue` is called at a child location. While get() is waiting
510
- * for the data, `onValue` will register a new event. Then, get() will come back, and update the syncTree
511
- * and its corresponding serverCache, including the child location where `onValue` is called. Then,
512
- * `onValue` will receive the event from the server, but look at the syncTree and see that the data received
513
- * from the server is already at the SyncPoint, and so the `onValue` callback will never get fired.
514
- * Calling `eventQueueRaiseEventsForChangedPath()` is the correct way to propagate the events and
515
- * ensure the corresponding child events will get fired.
516
- */
517
- eventQueueRaiseEventsForChangedPath (
518
- repo . eventQueue_ ,
519
- query . _path ,
520
- events
521
- ) ;
522
- syncTreeRemoveEventRegistration (
491
+ const cancels = syncTreeRemoveEventRegistration (
523
492
repo . serverSyncTree_ ,
524
493
query ,
525
- eventRegistration ,
526
- null ,
527
- true
494
+ null
528
495
) ;
496
+ if ( cancels . length > 0 ) {
497
+ repoLog ( repo , 'unexpected cancel events in repoGetValue' ) ;
498
+ }
529
499
return node ;
530
500
} ,
531
501
err => {
@@ -982,7 +952,7 @@ export function repoStartTransaction(
982
952
// Mark as run and add to our queue.
983
953
transaction . status = TransactionStatus . RUN ;
984
954
const queueNode = treeSubTree ( repo . transactionQueueTree_ , path ) ;
985
- const nodeQueue = treeGetValue ( queueNode ) ?? [ ] ;
955
+ const nodeQueue = treeGetValue ( queueNode ) || [ ] ;
986
956
nodeQueue . push ( transaction ) ;
987
957
988
958
treeSetValue ( queueNode , nodeQueue ) ;
@@ -1067,7 +1037,7 @@ function repoSendReadyTransactions(
1067
1037
repoPruneCompletedTransactionsBelowNode ( repo , node ) ;
1068
1038
}
1069
1039
1070
- if ( treeGetValue ( node ) !== undefined ) {
1040
+ if ( treeGetValue ( node ) ) {
1071
1041
const queue = repoBuildTransactionQueue ( repo , node ) ;
1072
1042
assert ( queue . length > 0 , 'Sending zero length transaction queue' ) ;
1073
1043
@@ -1443,7 +1413,7 @@ function repoAggregateTransactionQueuesForNode(
1443
1413
queue : Transaction [ ]
1444
1414
) : void {
1445
1415
const nodeQueue = treeGetValue ( node ) ;
1446
- if ( nodeQueue !== undefined ) {
1416
+ if ( nodeQueue ) {
1447
1417
for ( let i = 0 ; i < nodeQueue . length ; i ++ ) {
1448
1418
queue . push ( nodeQueue [ i ] ) ;
1449
1419
}
@@ -1462,7 +1432,7 @@ function repoPruneCompletedTransactionsBelowNode(
1462
1432
node : Tree < Transaction [ ] >
1463
1433
) : void {
1464
1434
const queue = treeGetValue ( node ) ;
1465
- if ( queue !== undefined ) {
1435
+ if ( queue ) {
1466
1436
let to = 0 ;
1467
1437
for ( let from = 0 ; from < queue . length ; from ++ ) {
1468
1438
if ( queue [ from ] . status !== TransactionStatus . COMPLETED ) {
@@ -1514,7 +1484,7 @@ function repoAbortTransactionsOnNode(
1514
1484
node : Tree < Transaction [ ] >
1515
1485
) : void {
1516
1486
const queue = treeGetValue ( node ) ;
1517
- if ( queue !== undefined ) {
1487
+ if ( queue ) {
1518
1488
// Queue up the callbacks and fire them after cleaning up all of our
1519
1489
// transaction state, since the callback could trigger more transactions
1520
1490
// or sets.
0 commit comments