@firebase/database 0.13.1 → 0.13.2-canary.13550089f

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,17 @@
1
1
  # Unreleased
2
2
 
3
+ ## 0.13.2
4
+
5
+ ### Patch Changes
6
+
7
+ - [`578dc5836`](https://github.com/firebase/firebase-js-sdk/commit/578dc58365c6c71d8ad01dd8b9dbe829e76de068) [#6273](https://github.com/firebase/firebase-js-sdk/pull/6273) - Fixed issue where `get()` saved results incorrectly for non-default queries.
8
+
9
+ * [`efe2000fc`](https://github.com/firebase/firebase-js-sdk/commit/efe2000fc499e2c85c4e5e0fef6741ff3bad2eb0) [#6363](https://github.com/firebase/firebase-js-sdk/pull/6363) - Extract uuid function into @firebase/util
10
+
11
+ * Updated dependencies [[`efe2000fc`](https://github.com/firebase/firebase-js-sdk/commit/efe2000fc499e2c85c4e5e0fef6741ff3bad2eb0)]:
12
+ - @firebase/util@1.6.2
13
+ - @firebase/component@0.5.16
14
+
3
15
  ## 0.13.1
4
16
 
5
17
  ### Patch Changes
@@ -4,7 +4,7 @@ import { stringify, jsonEval, contains, assert, isNodeSdk, base64, stringToByteA
4
4
  import { Logger, LogLevel } from '@firebase/logger';
5
5
 
6
6
  const name = "@firebase/database";
7
- const version = "0.13.1";
7
+ const version = "0.13.2-canary.13550089f";
8
8
 
9
9
  /**
10
10
  * @license
@@ -1852,7 +1852,7 @@ class WebSocketConnection {
1852
1852
  if (isNodeSdk()) {
1853
1853
  const device = this.nodeAdmin ? 'AdminNode' : 'Node';
1854
1854
  // UA Format: Firebase/<wire_protocol>/<sdk_version>/<platform>/<device>
1855
- const options = {
1855
+ options = {
1856
1856
  headers: {
1857
1857
  'User-Agent': `Firebase/${PROTOCOL_VERSION}/${SDK_VERSION}/${process.platform}/${device}`,
1858
1858
  'X-Firebase-GMPID': this.applicationId || ''
@@ -3010,7 +3010,7 @@ function pathEquals(path, other) {
3010
3010
  return true;
3011
3011
  }
3012
3012
  /**
3013
- * @returns True if this path is a parent (or the same as) other
3013
+ * @returns True if this path is a parent of (or the same as) other
3014
3014
  */
3015
3015
  function pathContains(path, other) {
3016
3016
  let i = path.pieceNum_;
@@ -3180,7 +3180,6 @@ class VisibilityMonitor extends EventEmitter {
3180
3180
  */
3181
3181
  const RECONNECT_MIN_DELAY = 1000;
3182
3182
  const RECONNECT_MAX_DELAY_DEFAULT = 60 * 5 * 1000; // 5 minutes in milliseconds (Case: 1858)
3183
- const GET_CONNECT_TIMEOUT = 3 * 1000;
3184
3183
  const RECONNECT_MAX_DELAY_FOR_ADMINS = 30 * 1000; // 30 seconds for admin clients (likely to be a backend server)
3185
3184
  const RECONNECT_DELAY_MULTIPLIER = 1.3;
3186
3185
  const RECONNECT_DELAY_RESET_TIMEOUT = 30000; // Reset delay back to MIN_DELAY after being connected for 30sec.
@@ -3269,9 +3268,6 @@ class PersistentConnection extends ServerActions {
3269
3268
  onComplete: (message) => {
3270
3269
  const payload = message['d'];
3271
3270
  if (message['s'] === 'ok') {
3272
- this.onDataUpdate_(request['p'], payload,
3273
- /*isMerge*/ false,
3274
- /*tag*/ null);
3275
3271
  deferred.resolve(payload);
3276
3272
  }
3277
3273
  else {
@@ -3282,21 +3278,6 @@ class PersistentConnection extends ServerActions {
3282
3278
  this.outstandingGets_.push(outstandingGet);
3283
3279
  this.outstandingGetCount_++;
3284
3280
  const index = this.outstandingGets_.length - 1;
3285
- if (!this.connected_) {
3286
- setTimeout(() => {
3287
- const get = this.outstandingGets_[index];
3288
- if (get === undefined || outstandingGet !== get) {
3289
- return;
3290
- }
3291
- delete this.outstandingGets_[index];
3292
- this.outstandingGetCount_--;
3293
- if (this.outstandingGetCount_ === 0) {
3294
- this.outstandingGets_ = [];
3295
- }
3296
- this.log_('get ' + index + ' timed out on connection');
3297
- deferred.reject(new Error('Client is offline.'));
3298
- }, GET_CONNECT_TIMEOUT);
3299
- }
3300
3281
  if (this.connected_) {
3301
3282
  this.sendGet_(index);
3302
3283
  }
@@ -3311,7 +3292,7 @@ class PersistentConnection extends ServerActions {
3311
3292
  this.listens.set(pathString, new Map());
3312
3293
  }
3313
3294
  assert(query._queryParams.isDefault() || !query._queryParams.loadsAllData(), 'listen() called for non-default but complete query');
3314
- assert(!this.listens.get(pathString).has(queryId), 'listen() called twice for same path/queryId.');
3295
+ assert(!this.listens.get(pathString).has(queryId), `listen() called twice for same path/queryId.`);
3315
3296
  const listenSpec = {
3316
3297
  onComplete,
3317
3298
  hashFn: currentHashFn,
@@ -9861,6 +9842,30 @@ function syncTreeRemoveEventRegistration(syncTree, query, eventRegistration, can
9861
9842
  }
9862
9843
  return cancelEvents;
9863
9844
  }
9845
+ /**
9846
+ * This function was added to support non-listener queries,
9847
+ * specifically for use in repoGetValue. It sets up all the same
9848
+ * local cache data-structures (SyncPoint + View) that are
9849
+ * needed for listeners without installing an event registration.
9850
+ * If `query` is not `loadsAllData`, it will also provision a tag for
9851
+ * the query so that query results can be merged into the sync
9852
+ * tree using existing logic for tagged listener queries.
9853
+ *
9854
+ * @param syncTree - Synctree to add the query to.
9855
+ * @param query - Query to register
9856
+ * @returns tag as a string if query is not a default query, null if query is not.
9857
+ */
9858
+ function syncTreeRegisterQuery(syncTree, query) {
9859
+ const { syncPoint, serverCache, writesCache, serverCacheComplete } = syncTreeRegisterSyncPoint(query, syncTree);
9860
+ const view = syncPointGetView(syncPoint, query, writesCache, serverCache, serverCacheComplete);
9861
+ if (!syncPoint.views.has(query._queryIdentifier)) {
9862
+ syncPoint.views.set(query._queryIdentifier, view);
9863
+ }
9864
+ if (!query._queryParams.loadsAllData()) {
9865
+ return syncTreeTagForQuery_(syncTree, query);
9866
+ }
9867
+ return null;
9868
+ }
9864
9869
  /**
9865
9870
  * Apply new server data for the specified tagged query.
9866
9871
  *
@@ -9901,11 +9906,11 @@ function syncTreeApplyTaggedQueryMerge(syncTree, path, changedChildren, tag) {
9901
9906
  }
9902
9907
  }
9903
9908
  /**
9904
- * Add an event callback for the specified query.
9905
- *
9906
- * @returns Events to raise.
9909
+ * Creates a new syncpoint for a query and creates a tag if the view doesn't exist.
9910
+ * Extracted from addEventRegistration to allow `repoGetValue` to properly set up the SyncTree
9911
+ * without actually listening on a query.
9907
9912
  */
9908
- function syncTreeAddEventRegistration(syncTree, query, eventRegistration) {
9913
+ function syncTreeRegisterSyncPoint(query, syncTree) {
9909
9914
  const path = query._path;
9910
9915
  let serverCache = null;
9911
9916
  let foundAncestorDefaultView = false;
@@ -9954,6 +9959,22 @@ function syncTreeAddEventRegistration(syncTree, query, eventRegistration) {
9954
9959
  syncTree.tagToQueryMap.set(tag, queryKey);
9955
9960
  }
9956
9961
  const writesCache = writeTreeChildWrites(syncTree.pendingWriteTree_, path);
9962
+ return {
9963
+ syncPoint,
9964
+ writesCache,
9965
+ serverCache,
9966
+ serverCacheComplete,
9967
+ foundAncestorDefaultView,
9968
+ viewAlreadyExists
9969
+ };
9970
+ }
9971
+ /**
9972
+ * Add an event callback for the specified query.
9973
+ *
9974
+ * @returns Events to raise.
9975
+ */
9976
+ function syncTreeAddEventRegistration(syncTree, query, eventRegistration) {
9977
+ const { syncPoint, serverCache, writesCache, serverCacheComplete, viewAlreadyExists, foundAncestorDefaultView } = syncTreeRegisterSyncPoint(query, syncTree);
9957
9978
  let events = syncPointAddEventRegistration(syncPoint, query, eventRegistration, writesCache, serverCache, serverCacheComplete);
9958
9979
  if (!viewAlreadyExists && !foundAncestorDefaultView) {
9959
9980
  const view = syncPointViewForQuery(syncPoint, query);
@@ -11184,9 +11205,25 @@ function repoGetValue(repo, query) {
11184
11205
  }
11185
11206
  return repo.server_.get(query).then(payload => {
11186
11207
  const node = nodeFromJSON(payload).withIndex(query._queryParams.getIndex());
11187
- const events = syncTreeApplyServerOverwrite(repo.serverSyncTree_, query._path, node);
11188
- eventQueueRaiseEventsAtPath(repo.eventQueue_, query._path, events);
11189
- return Promise.resolve(node);
11208
+ // if this is a filtered query, then overwrite at path
11209
+ if (query._queryParams.loadsAllData()) {
11210
+ syncTreeApplyServerOverwrite(repo.serverSyncTree_, query._path, node);
11211
+ }
11212
+ else {
11213
+ // Simulate `syncTreeAddEventRegistration` without events/listener setup.
11214
+ // We do this (along with the syncTreeRemoveEventRegistration` below) so that
11215
+ // `repoGetValue` results have the same cache effects as initial listener(s)
11216
+ // updates.
11217
+ const tag = syncTreeRegisterQuery(repo.serverSyncTree_, query);
11218
+ syncTreeApplyTaggedQueryOverwrite(repo.serverSyncTree_, query._path, node, tag);
11219
+ // Call `syncTreeRemoveEventRegistration` with a null event registration, since there is none.
11220
+ // Note: The below code essentially unregisters the query and cleans up any views/syncpoints temporarily created above.
11221
+ }
11222
+ const cancels = syncTreeRemoveEventRegistration(repo.serverSyncTree_, query, null);
11223
+ if (cancels.length > 0) {
11224
+ repoLog(repo, 'unexpected cancel events in repoGetValue');
11225
+ }
11226
+ return node;
11190
11227
  }, err => {
11191
11228
  repoLog(repo, 'get for query ' + stringify(query) + ' failed: ' + err);
11192
11229
  return Promise.reject(new Error(err));