@firebase/database-compat 0.2.4 → 0.2.5-20220816193712

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # @firebase/database-compat
2
2
 
3
+ ## 0.2.5-20220816193712
4
+
5
+ ### Patch Changes
6
+
7
+ - [`fcd4b8ac3`](https://github.com/firebase/firebase-js-sdk/commit/fcd4b8ac36636a60d83cd3370969ff9192f9e6ad) [#6508](https://github.com/firebase/firebase-js-sdk/pull/6508) - Fixed faulty transaction bug causing filtered index queries to override default queries.
8
+
9
+ - Updated dependencies [[`a5d9e1083`](https://github.com/firebase/firebase-js-sdk/commit/a5d9e10831c2877e9d15c8a33b15557e4251c4de), [`fcd4b8ac3`](https://github.com/firebase/firebase-js-sdk/commit/fcd4b8ac36636a60d83cd3370969ff9192f9e6ad)]:
10
+ - @firebase/database@0.13.5-20220816193712
11
+
3
12
  ## 0.2.4
4
13
 
5
14
  ### Patch Changes
@@ -5,7 +5,7 @@ import { errorPrefix, validateArgCount, validateCallback, validateContextObject,
5
5
  import { Logger } from '@firebase/logger';
6
6
 
7
7
  const name = "@firebase/database-compat";
8
- const version = "0.2.4";
8
+ const version = "0.2.5-20220816193712";
9
9
 
10
10
  /**
11
11
  * @license
@@ -6,7 +6,7 @@ import { __extends } from 'tslib';
6
6
  import { Logger } from '@firebase/logger';
7
7
 
8
8
  var name = "@firebase/database-compat";
9
- var version = "0.2.4";
9
+ var version = "0.2.5-20220816193712";
10
10
 
11
11
  /**
12
12
  * @license
package/dist/index.js CHANGED
@@ -12,7 +12,7 @@ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'defau
12
12
  var firebase__default = /*#__PURE__*/_interopDefaultLegacy(firebase);
13
13
 
14
14
  var name = "@firebase/database-compat";
15
- var version = "0.2.4";
15
+ var version = "0.2.5-20220816193712";
16
16
 
17
17
  /**
18
18
  * @license
@@ -12736,7 +12736,7 @@ function viewProcessorApplyServerMerge(viewProcessor, viewCache, path, changedCh
12736
12736
  });
12737
12737
  viewMergeTree.children.inorderTraversal(function (childKey, childMergeTree) {
12738
12738
  var isUnknownDeepMerge = !viewCache.serverCache.isCompleteForChild(childKey) &&
12739
- childMergeTree.value === undefined;
12739
+ childMergeTree.value === null;
12740
12740
  if (!serverNode.hasChild(childKey) && !isUnknownDeepMerge) {
12741
12741
  var serverChild = viewCache.serverCache
12742
12742
  .getNode()
@@ -13438,9 +13438,12 @@ function syncTreeApplyTaggedListenComplete(syncTree, path, tag) {
13438
13438
  *
13439
13439
  * @param eventRegistration - If null, all callbacks are removed.
13440
13440
  * @param cancelError - If a cancelError is provided, appropriate cancel events will be returned.
13441
+ * @param skipListenerDedup - When performing a `get()`, we don't add any new listeners, so no
13442
+ * deduping needs to take place. This flag allows toggling of that behavior
13441
13443
  * @returns Cancel events, if cancelError was provided.
13442
13444
  */
13443
- function syncTreeRemoveEventRegistration(syncTree, query, eventRegistration, cancelError) {
13445
+ function syncTreeRemoveEventRegistration(syncTree, query, eventRegistration, cancelError, skipListenerDedup) {
13446
+ if (skipListenerDedup === void 0) { skipListenerDedup = false; }
13444
13447
  // Find the syncPoint first. Then deal with whether or not it has matching listeners
13445
13448
  var path = query._path;
13446
13449
  var maybeSyncPoint = syncTree.syncPointTree_.get(path);
@@ -13457,50 +13460,54 @@ function syncTreeRemoveEventRegistration(syncTree, query, eventRegistration, can
13457
13460
  }
13458
13461
  var removed = removedAndEvents.removed;
13459
13462
  cancelEvents = removedAndEvents.events;
13460
- // We may have just removed one of many listeners and can short-circuit this whole process
13461
- // We may also not have removed a default listener, in which case all of the descendant listeners should already be
13462
- // properly set up.
13463
- //
13464
- // Since indexed queries can shadow if they don't have other query constraints, check for loadsAllData(), instead of
13465
- // queryId === 'default'
13466
- var removingDefault = -1 !==
13467
- removed.findIndex(function (query) {
13468
- return query._queryParams.loadsAllData();
13463
+ if (!skipListenerDedup) {
13464
+ /**
13465
+ * We may have just removed one of many listeners and can short-circuit this whole process
13466
+ * We may also not have removed a default listener, in which case all of the descendant listeners should already be
13467
+ * properly set up.
13468
+ */
13469
+ // Since indexed queries can shadow if they don't have other query constraints, check for loadsAllData(), instead of
13470
+ // queryId === 'default'
13471
+ var removingDefault = -1 !==
13472
+ removed.findIndex(function (query) {
13473
+ return query._queryParams.loadsAllData();
13474
+ });
13475
+ var covered = syncTree.syncPointTree_.findOnPath(path, function (relativePath, parentSyncPoint) {
13476
+ return syncPointHasCompleteView(parentSyncPoint);
13469
13477
  });
13470
- var covered = syncTree.syncPointTree_.findOnPath(path, function (relativePath, parentSyncPoint) {
13471
- return syncPointHasCompleteView(parentSyncPoint);
13472
- });
13473
- if (removingDefault && !covered) {
13474
- var subtree = syncTree.syncPointTree_.subtree(path);
13475
- // There are potentially child listeners. Determine what if any listens we need to send before executing the
13476
- // removal
13477
- if (!subtree.isEmpty()) {
13478
- // We need to fold over our subtree and collect the listeners to send
13479
- var newViews = syncTreeCollectDistinctViewsForSubTree_(subtree);
13480
- // Ok, we've collected all the listens we need. Set them up.
13481
- for (var i = 0; i < newViews.length; ++i) {
13482
- var view = newViews[i], newQuery = view.query;
13483
- var listener = syncTreeCreateListenerForView_(syncTree, view);
13484
- syncTree.listenProvider_.startListening(syncTreeQueryForListening_(newQuery), syncTreeTagForQuery_(syncTree, newQuery), listener.hashFn, listener.onComplete);
13478
+ if (removingDefault && !covered) {
13479
+ var subtree = syncTree.syncPointTree_.subtree(path);
13480
+ // There are potentially child listeners. Determine what if any listens we need to send before executing the
13481
+ // removal
13482
+ if (!subtree.isEmpty()) {
13483
+ // We need to fold over our subtree and collect the listeners to send
13484
+ var newViews = syncTreeCollectDistinctViewsForSubTree_(subtree);
13485
+ // Ok, we've collected all the listens we need. Set them up.
13486
+ for (var i = 0; i < newViews.length; ++i) {
13487
+ var view = newViews[i], newQuery = view.query;
13488
+ var listener = syncTreeCreateListenerForView_(syncTree, view);
13489
+ syncTree.listenProvider_.startListening(syncTreeQueryForListening_(newQuery), syncTreeTagForQuery(syncTree, newQuery), listener.hashFn, listener.onComplete);
13490
+ }
13491
+ }
13492
+ // Otherwise there's nothing below us, so nothing we need to start listening on
13493
+ }
13494
+ // If we removed anything and we're not covered by a higher up listen, we need to stop listening on this query
13495
+ // The above block has us covered in terms of making sure we're set up on listens lower in the tree.
13496
+ // Also, note that if we have a cancelError, it's already been removed at the provider level.
13497
+ if (!covered && removed.length > 0 && !cancelError) {
13498
+ // If we removed a default, then we weren't listening on any of the other queries here. Just cancel the one
13499
+ // default. Otherwise, we need to iterate through and cancel each individual query
13500
+ if (removingDefault) {
13501
+ // We don't tag default listeners
13502
+ var defaultTag = null;
13503
+ syncTree.listenProvider_.stopListening(syncTreeQueryForListening_(query), defaultTag);
13504
+ }
13505
+ else {
13506
+ removed.forEach(function (queryToRemove) {
13507
+ var tagToRemove = syncTree.queryToTagMap.get(syncTreeMakeQueryKey_(queryToRemove));
13508
+ syncTree.listenProvider_.stopListening(syncTreeQueryForListening_(queryToRemove), tagToRemove);
13509
+ });
13485
13510
  }
13486
- }
13487
- }
13488
- // If we removed anything and we're not covered by a higher up listen, we need to stop listening on this query
13489
- // The above block has us covered in terms of making sure we're set up on listens lower in the tree.
13490
- // Also, note that if we have a cancelError, it's already been removed at the provider level.
13491
- if (!covered && removed.length > 0 && !cancelError) {
13492
- // If we removed a default, then we weren't listening on any of the other queries here. Just cancel the one
13493
- // default. Otherwise, we need to iterate through and cancel each individual query
13494
- if (removingDefault) {
13495
- // We don't tag default listeners
13496
- var defaultTag = null;
13497
- syncTree.listenProvider_.stopListening(syncTreeQueryForListening_(query), defaultTag);
13498
- }
13499
- else {
13500
- removed.forEach(function (queryToRemove) {
13501
- var tagToRemove = syncTree.queryToTagMap.get(syncTreeMakeQueryKey_(queryToRemove));
13502
- syncTree.listenProvider_.stopListening(syncTreeQueryForListening_(queryToRemove), tagToRemove);
13503
- });
13504
13511
  }
13505
13512
  }
13506
13513
  // Now, clear all of the tags we're tracking for the removed listens
@@ -13508,30 +13515,6 @@ function syncTreeRemoveEventRegistration(syncTree, query, eventRegistration, can
13508
13515
  }
13509
13516
  return cancelEvents;
13510
13517
  }
13511
- /**
13512
- * This function was added to support non-listener queries,
13513
- * specifically for use in repoGetValue. It sets up all the same
13514
- * local cache data-structures (SyncPoint + View) that are
13515
- * needed for listeners without installing an event registration.
13516
- * If `query` is not `loadsAllData`, it will also provision a tag for
13517
- * the query so that query results can be merged into the sync
13518
- * tree using existing logic for tagged listener queries.
13519
- *
13520
- * @param syncTree - Synctree to add the query to.
13521
- * @param query - Query to register
13522
- * @returns tag as a string if query is not a default query, null if query is not.
13523
- */
13524
- function syncTreeRegisterQuery(syncTree, query) {
13525
- var _a = syncTreeRegisterSyncPoint(query, syncTree), syncPoint = _a.syncPoint, serverCache = _a.serverCache, writesCache = _a.writesCache, serverCacheComplete = _a.serverCacheComplete;
13526
- var view = syncPointGetView(syncPoint, query, writesCache, serverCache, serverCacheComplete);
13527
- if (!syncPoint.views.has(query._queryIdentifier)) {
13528
- syncPoint.views.set(query._queryIdentifier, view);
13529
- }
13530
- if (!query._queryParams.loadsAllData()) {
13531
- return syncTreeTagForQuery_(syncTree, query);
13532
- }
13533
- return null;
13534
- }
13535
13518
  /**
13536
13519
  * Apply new server data for the specified tagged query.
13537
13520
  *
@@ -13572,11 +13555,12 @@ function syncTreeApplyTaggedQueryMerge(syncTree, path, changedChildren, tag) {
13572
13555
  }
13573
13556
  }
13574
13557
  /**
13575
- * Creates a new syncpoint for a query and creates a tag if the view doesn't exist.
13576
- * Extracted from addEventRegistration to allow `repoGetValue` to properly set up the SyncTree
13577
- * without actually listening on a query.
13558
+ * Add an event callback for the specified query.
13559
+ *
13560
+ * @returns Events to raise.
13578
13561
  */
13579
- function syncTreeRegisterSyncPoint(query, syncTree) {
13562
+ function syncTreeAddEventRegistration(syncTree, query, eventRegistration, skipSetupListener) {
13563
+ if (skipSetupListener === void 0) { skipSetupListener = false; }
13580
13564
  var path = query._path;
13581
13565
  var serverCache = null;
13582
13566
  var foundAncestorDefaultView = false;
@@ -13625,24 +13609,8 @@ function syncTreeRegisterSyncPoint(query, syncTree) {
13625
13609
  syncTree.tagToQueryMap.set(tag, queryKey);
13626
13610
  }
13627
13611
  var writesCache = writeTreeChildWrites(syncTree.pendingWriteTree_, path);
13628
- return {
13629
- syncPoint: syncPoint,
13630
- writesCache: writesCache,
13631
- serverCache: serverCache,
13632
- serverCacheComplete: serverCacheComplete,
13633
- foundAncestorDefaultView: foundAncestorDefaultView,
13634
- viewAlreadyExists: viewAlreadyExists
13635
- };
13636
- }
13637
- /**
13638
- * Add an event callback for the specified query.
13639
- *
13640
- * @returns Events to raise.
13641
- */
13642
- function syncTreeAddEventRegistration(syncTree, query, eventRegistration) {
13643
- var _a = syncTreeRegisterSyncPoint(query, syncTree), syncPoint = _a.syncPoint, serverCache = _a.serverCache, writesCache = _a.writesCache, serverCacheComplete = _a.serverCacheComplete, viewAlreadyExists = _a.viewAlreadyExists, foundAncestorDefaultView = _a.foundAncestorDefaultView;
13644
13612
  var events = syncPointAddEventRegistration(syncPoint, query, eventRegistration, writesCache, serverCache, serverCacheComplete);
13645
- if (!viewAlreadyExists && !foundAncestorDefaultView) {
13613
+ if (!viewAlreadyExists && !foundAncestorDefaultView && !skipSetupListener) {
13646
13614
  var view = syncPointViewForQuery(syncPoint, query);
13647
13615
  events = events.concat(syncTreeSetupListener_(syncTree, query, view));
13648
13616
  }
@@ -13772,7 +13740,7 @@ function syncTreeApplyOperationDescendantsHelper_(operation, syncPointTree, serv
13772
13740
  }
13773
13741
  function syncTreeCreateListenerForView_(syncTree, view) {
13774
13742
  var query = view.query;
13775
- var tag = syncTreeTagForQuery_(syncTree, query);
13743
+ var tag = syncTreeTagForQuery(syncTree, query);
13776
13744
  return {
13777
13745
  hashFn: function () {
13778
13746
  var cache = viewGetServerCache(view) || ChildrenNode.EMPTY_NODE;
@@ -13800,7 +13768,7 @@ function syncTreeCreateListenerForView_(syncTree, view) {
13800
13768
  /**
13801
13769
  * Return the tag associated with the given query.
13802
13770
  */
13803
- function syncTreeTagForQuery_(syncTree, query) {
13771
+ function syncTreeTagForQuery(syncTree, query) {
13804
13772
  var queryKey = syncTreeMakeQueryKey_(query);
13805
13773
  return syncTree.queryToTagMap.get(queryKey);
13806
13774
  }
@@ -13900,7 +13868,7 @@ function syncTreeGetNextQueryTag_() {
13900
13868
  */
13901
13869
  function syncTreeSetupListener_(syncTree, query, view) {
13902
13870
  var path = query._path;
13903
- var tag = syncTreeTagForQuery_(syncTree, query);
13871
+ var tag = syncTreeTagForQuery(syncTree, query);
13904
13872
  var listener = syncTreeCreateListenerForView_(syncTree, view);
13905
13873
  var events = syncTree.listenProvider_.startListening(syncTreeQueryForListening_(query), tag, listener.hashFn, listener.onComplete);
13906
13874
  var subtree = syncTree.syncPointTree_.subtree(path);
@@ -13931,7 +13899,7 @@ function syncTreeSetupListener_(syncTree, query, view) {
13931
13899
  });
13932
13900
  for (var i = 0; i < queriesToStop.length; ++i) {
13933
13901
  var queryToStop = queriesToStop[i];
13934
- syncTree.listenProvider_.stopListening(syncTreeQueryForListening_(queryToStop), syncTreeTagForQuery_(syncTree, queryToStop));
13902
+ syncTree.listenProvider_.stopListening(syncTreeQueryForListening_(queryToStop), syncTreeTagForQuery(syncTree, queryToStop));
13935
13903
  }
13936
13904
  }
13937
13905
  return events;
@@ -14868,14 +14836,14 @@ function repoGetNextWriteId(repo) {
14868
14836
  * belonging to active listeners. If they are found, such values
14869
14837
  * are considered to be the most up-to-date.
14870
14838
  *
14871
- * If the client is not connected, this method will try to
14872
- * establish a connection and request the value for `query`. If
14873
- * the client is not able to retrieve the query result, it reports
14874
- * an error.
14839
+ * If the client is not connected, this method will wait until the
14840
+ * repo has established a connection and then request the value for `query`.
14841
+ * If the client is not able to retrieve the query result for another reason,
14842
+ * it reports an error.
14875
14843
  *
14876
14844
  * @param query - The query to surface a value for.
14877
14845
  */
14878
- function repoGetValue(repo, query) {
14846
+ function repoGetValue(repo, query, eventRegistration) {
14879
14847
  // Only active queries are cached. There is no persisted cache.
14880
14848
  var cached = syncTreeGetServerValue(repo.serverSyncTree_, query);
14881
14849
  if (cached != null) {
@@ -14883,24 +14851,34 @@ function repoGetValue(repo, query) {
14883
14851
  }
14884
14852
  return repo.server_.get(query).then(function (payload) {
14885
14853
  var node = nodeFromJSON(payload).withIndex(query._queryParams.getIndex());
14886
- // if this is a filtered query, then overwrite at path
14854
+ /**
14855
+ * Below we simulate the actions of an `onlyOnce` `onValue()` event where:
14856
+ * Add an event registration,
14857
+ * Update data at the path,
14858
+ * Raise any events,
14859
+ * Cleanup the SyncTree
14860
+ */
14861
+ syncTreeAddEventRegistration(repo.serverSyncTree_, query, eventRegistration, true);
14862
+ var events;
14887
14863
  if (query._queryParams.loadsAllData()) {
14888
- syncTreeApplyServerOverwrite(repo.serverSyncTree_, query._path, node);
14864
+ events = syncTreeApplyServerOverwrite(repo.serverSyncTree_, query._path, node);
14889
14865
  }
14890
14866
  else {
14891
- // Simulate `syncTreeAddEventRegistration` without events/listener setup.
14892
- // We do this (along with the syncTreeRemoveEventRegistration` below) so that
14893
- // `repoGetValue` results have the same cache effects as initial listener(s)
14894
- // updates.
14895
- var tag = syncTreeRegisterQuery(repo.serverSyncTree_, query);
14896
- syncTreeApplyTaggedQueryOverwrite(repo.serverSyncTree_, query._path, node, tag);
14897
- // Call `syncTreeRemoveEventRegistration` with a null event registration, since there is none.
14898
- // Note: The below code essentially unregisters the query and cleans up any views/syncpoints temporarily created above.
14899
- }
14900
- var cancels = syncTreeRemoveEventRegistration(repo.serverSyncTree_, query, null);
14901
- if (cancels.length > 0) {
14902
- repoLog(repo, 'unexpected cancel events in repoGetValue');
14867
+ var tag = syncTreeTagForQuery(repo.serverSyncTree_, query);
14868
+ events = syncTreeApplyTaggedQueryOverwrite(repo.serverSyncTree_, query._path, node, tag);
14903
14869
  }
14870
+ /*
14871
+ * We need to raise events in the scenario where `get()` is called at a parent path, and
14872
+ * while the `get()` is pending, `onValue` is called at a child location. While get() is waiting
14873
+ * for the data, `onValue` will register a new event. Then, get() will come back, and update the syncTree
14874
+ * and its corresponding serverCache, including the child location where `onValue` is called. Then,
14875
+ * `onValue` will receive the event from the server, but look at the syncTree and see that the data received
14876
+ * from the server is already at the SyncPoint, and so the `onValue` callback will never get fired.
14877
+ * Calling `eventQueueRaiseEventsForChangedPath()` is the correct way to propagate the events and
14878
+ * ensure the corresponding child events will get fired.
14879
+ */
14880
+ eventQueueRaiseEventsForChangedPath(repo.eventQueue_, query._path, events);
14881
+ syncTreeRemoveEventRegistration(repo.serverSyncTree_, query, eventRegistration, null, true);
14904
14882
  return node;
14905
14883
  }, function (err) {
14906
14884
  repoLog(repo, 'get for query ' + util.stringify(query) + ' failed: ' + err);
@@ -16660,7 +16638,9 @@ function update(ref, values) {
16660
16638
  */
16661
16639
  function get(query) {
16662
16640
  query = util.getModularInstance(query);
16663
- return repoGetValue(query._repo, query).then(function (node) {
16641
+ var callbackContext = new CallbackContext(function () { });
16642
+ var container = new ValueEventRegistration(callbackContext);
16643
+ return repoGetValue(query._repo, query, container).then(function (node) {
16664
16644
  return new DataSnapshot$1(node, new ReferenceImpl(query._repo, query._path), query._queryParams.getIndex());
16665
16645
  });
16666
16646
  }