@firebase/database 0.13.10 → 0.14.0

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.
@@ -1250,7 +1250,7 @@ WebSocketConnection.responsesRequiredToBeHealthy = 2;
1250
1250
  WebSocketConnection.healthyTimeout = 30000;
1251
1251
 
1252
1252
  const name = "@firebase/database";
1253
- const version = "0.13.10";
1253
+ const version = "0.14.0";
1254
1254
 
1255
1255
  /**
1256
1256
  * @license
@@ -2266,7 +2266,7 @@ class Connection {
2266
2266
  this.lastSessionId = lastSessionId;
2267
2267
  this.connectionCount = 0;
2268
2268
  this.pendingDataMessages = [];
2269
- this.state_ = 0 /* CONNECTING */;
2269
+ this.state_ = 0 /* RealtimeState.CONNECTING */;
2270
2270
  this.log_ = logWrapper('c:' + this.id + ':');
2271
2271
  this.transportManager_ = new TransportManager(repoInfo_);
2272
2272
  this.log_('Connection created');
@@ -2346,7 +2346,7 @@ class Connection {
2346
2346
  }
2347
2347
  connReceiver_(conn) {
2348
2348
  return (message) => {
2349
- if (this.state_ !== 2 /* DISCONNECTED */) {
2349
+ if (this.state_ !== 2 /* RealtimeState.DISCONNECTED */) {
2350
2350
  if (conn === this.rx_) {
2351
2351
  this.onPrimaryMessageReceived_(message);
2352
2352
  }
@@ -2512,7 +2512,7 @@ class Connection {
2512
2512
  this.sessionId = handshake.s;
2513
2513
  this.repoInfo_.host = host;
2514
2514
  // if we've already closed the connection, then don't bother trying to progress further
2515
- if (this.state_ === 0 /* CONNECTING */) {
2515
+ if (this.state_ === 0 /* RealtimeState.CONNECTING */) {
2516
2516
  this.conn_.start();
2517
2517
  this.onConnectionEstablished_(this.conn_, timestamp);
2518
2518
  if (PROTOCOL_VERSION !== version) {
@@ -2550,7 +2550,7 @@ class Connection {
2550
2550
  this.repoInfo_.host = host;
2551
2551
  // TODO: if we're already "connected", we need to trigger a disconnect at the next layer up.
2552
2552
  // We don't currently support resets after the connection has already been established
2553
- if (this.state_ === 1 /* CONNECTED */) {
2553
+ if (this.state_ === 1 /* RealtimeState.CONNECTED */) {
2554
2554
  this.close();
2555
2555
  }
2556
2556
  else {
@@ -2562,7 +2562,7 @@ class Connection {
2562
2562
  onConnectionEstablished_(conn, timestamp) {
2563
2563
  this.log_('Realtime connection established.');
2564
2564
  this.conn_ = conn;
2565
- this.state_ = 1 /* CONNECTED */;
2565
+ this.state_ = 1 /* RealtimeState.CONNECTED */;
2566
2566
  if (this.onReady_) {
2567
2567
  this.onReady_(timestamp, this.sessionId);
2568
2568
  this.onReady_ = null;
@@ -2581,7 +2581,7 @@ class Connection {
2581
2581
  }
2582
2582
  sendPingOnPrimaryIfNecessary_() {
2583
2583
  // If the connection isn't considered healthy yet, we'll send a noop ping packet request.
2584
- if (!this.isHealthy_ && this.state_ === 1 /* CONNECTED */) {
2584
+ if (!this.isHealthy_ && this.state_ === 1 /* RealtimeState.CONNECTED */) {
2585
2585
  this.log_('sending ping on primary.');
2586
2586
  this.sendData_({ t: 'c', d: { t: PING, d: {} } });
2587
2587
  }
@@ -2602,7 +2602,7 @@ class Connection {
2602
2602
  this.conn_ = null;
2603
2603
  // NOTE: IF you're seeing a Firefox error for this line, I think it might be because it's getting
2604
2604
  // called on window close and RealtimeState.CONNECTING is no longer defined. Just a guess.
2605
- if (!everConnected && this.state_ === 0 /* CONNECTING */) {
2605
+ if (!everConnected && this.state_ === 0 /* RealtimeState.CONNECTING */) {
2606
2606
  this.log_('Realtime connection failed.');
2607
2607
  // Since we failed to connect at all, clear any cached entry for this namespace in case the machine went away
2608
2608
  if (this.repoInfo_.isCacheableHost()) {
@@ -2611,7 +2611,7 @@ class Connection {
2611
2611
  this.repoInfo_.internalHost = this.repoInfo_.host;
2612
2612
  }
2613
2613
  }
2614
- else if (this.state_ === 1 /* CONNECTED */) {
2614
+ else if (this.state_ === 1 /* RealtimeState.CONNECTED */) {
2615
2615
  this.log_('Realtime connection lost.');
2616
2616
  }
2617
2617
  this.close();
@@ -2628,7 +2628,7 @@ class Connection {
2628
2628
  this.close();
2629
2629
  }
2630
2630
  sendData_(data) {
2631
- if (this.state_ !== 1 /* CONNECTED */) {
2631
+ if (this.state_ !== 1 /* RealtimeState.CONNECTED */) {
2632
2632
  throw 'Connection is not connected';
2633
2633
  }
2634
2634
  else {
@@ -2639,9 +2639,9 @@ class Connection {
2639
2639
  * Cleans up this connection, calling the appropriate callbacks
2640
2640
  */
2641
2641
  close() {
2642
- if (this.state_ !== 2 /* DISCONNECTED */) {
2642
+ if (this.state_ !== 2 /* RealtimeState.DISCONNECTED */) {
2643
2643
  this.log_('Closing realtime connection.');
2644
- this.state_ = 2 /* DISCONNECTED */;
2644
+ this.state_ = 2 /* RealtimeState.DISCONNECTED */;
2645
2645
  this.closeConnections_();
2646
2646
  if (this.onDisconnect_) {
2647
2647
  this.onDisconnect_();
@@ -5955,153 +5955,6 @@ class ValueIndex extends Index {
5955
5955
  }
5956
5956
  const VALUE_INDEX = new ValueIndex();
5957
5957
 
5958
- /**
5959
- * @license
5960
- * Copyright 2017 Google LLC
5961
- *
5962
- * Licensed under the Apache License, Version 2.0 (the "License");
5963
- * you may not use this file except in compliance with the License.
5964
- * You may obtain a copy of the License at
5965
- *
5966
- * http://www.apache.org/licenses/LICENSE-2.0
5967
- *
5968
- * Unless required by applicable law or agreed to in writing, software
5969
- * distributed under the License is distributed on an "AS IS" BASIS,
5970
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5971
- * See the License for the specific language governing permissions and
5972
- * limitations under the License.
5973
- */
5974
- // Modeled after base64 web-safe chars, but ordered by ASCII.
5975
- const PUSH_CHARS = '-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz';
5976
- const MIN_PUSH_CHAR = '-';
5977
- const MAX_PUSH_CHAR = 'z';
5978
- const MAX_KEY_LEN = 786;
5979
- /**
5980
- * Fancy ID generator that creates 20-character string identifiers with the
5981
- * following properties:
5982
- *
5983
- * 1. They're based on timestamp so that they sort *after* any existing ids.
5984
- * 2. They contain 72-bits of random data after the timestamp so that IDs won't
5985
- * collide with other clients' IDs.
5986
- * 3. They sort *lexicographically* (so the timestamp is converted to characters
5987
- * that will sort properly).
5988
- * 4. They're monotonically increasing. Even if you generate more than one in
5989
- * the same timestamp, the latter ones will sort after the former ones. We do
5990
- * this by using the previous random bits but "incrementing" them by 1 (only
5991
- * in the case of a timestamp collision).
5992
- */
5993
- const nextPushId = (function () {
5994
- // Timestamp of last push, used to prevent local collisions if you push twice
5995
- // in one ms.
5996
- let lastPushTime = 0;
5997
- // We generate 72-bits of randomness which get turned into 12 characters and
5998
- // appended to the timestamp to prevent collisions with other clients. We
5999
- // store the last characters we generated because in the event of a collision,
6000
- // we'll use those same characters except "incremented" by one.
6001
- const lastRandChars = [];
6002
- return function (now) {
6003
- const duplicateTime = now === lastPushTime;
6004
- lastPushTime = now;
6005
- let i;
6006
- const timeStampChars = new Array(8);
6007
- for (i = 7; i >= 0; i--) {
6008
- timeStampChars[i] = PUSH_CHARS.charAt(now % 64);
6009
- // NOTE: Can't use << here because javascript will convert to int and lose
6010
- // the upper bits.
6011
- now = Math.floor(now / 64);
6012
- }
6013
- assert(now === 0, 'Cannot push at time == 0');
6014
- let id = timeStampChars.join('');
6015
- if (!duplicateTime) {
6016
- for (i = 0; i < 12; i++) {
6017
- lastRandChars[i] = Math.floor(Math.random() * 64);
6018
- }
6019
- }
6020
- else {
6021
- // If the timestamp hasn't changed since last push, use the same random
6022
- // number, except incremented by 1.
6023
- for (i = 11; i >= 0 && lastRandChars[i] === 63; i--) {
6024
- lastRandChars[i] = 0;
6025
- }
6026
- lastRandChars[i]++;
6027
- }
6028
- for (i = 0; i < 12; i++) {
6029
- id += PUSH_CHARS.charAt(lastRandChars[i]);
6030
- }
6031
- assert(id.length === 20, 'nextPushId: Length should be 20.');
6032
- return id;
6033
- };
6034
- })();
6035
- const successor = function (key) {
6036
- if (key === '' + INTEGER_32_MAX) {
6037
- // See https://firebase.google.com/docs/database/web/lists-of-data#data-order
6038
- return MIN_PUSH_CHAR;
6039
- }
6040
- const keyAsInt = tryParseInt(key);
6041
- if (keyAsInt != null) {
6042
- return '' + (keyAsInt + 1);
6043
- }
6044
- const next = new Array(key.length);
6045
- for (let i = 0; i < next.length; i++) {
6046
- next[i] = key.charAt(i);
6047
- }
6048
- if (next.length < MAX_KEY_LEN) {
6049
- next.push(MIN_PUSH_CHAR);
6050
- return next.join('');
6051
- }
6052
- let i = next.length - 1;
6053
- while (i >= 0 && next[i] === MAX_PUSH_CHAR) {
6054
- i--;
6055
- }
6056
- // `successor` was called on the largest possible key, so return the
6057
- // MAX_NAME, which sorts larger than all keys.
6058
- if (i === -1) {
6059
- return MAX_NAME;
6060
- }
6061
- const source = next[i];
6062
- const sourcePlusOne = PUSH_CHARS.charAt(PUSH_CHARS.indexOf(source) + 1);
6063
- next[i] = sourcePlusOne;
6064
- return next.slice(0, i + 1).join('');
6065
- };
6066
- // `key` is assumed to be non-empty.
6067
- const predecessor = function (key) {
6068
- if (key === '' + INTEGER_32_MIN) {
6069
- return MIN_NAME;
6070
- }
6071
- const keyAsInt = tryParseInt(key);
6072
- if (keyAsInt != null) {
6073
- return '' + (keyAsInt - 1);
6074
- }
6075
- const next = new Array(key.length);
6076
- for (let i = 0; i < next.length; i++) {
6077
- next[i] = key.charAt(i);
6078
- }
6079
- // If `key` ends in `MIN_PUSH_CHAR`, the largest key lexicographically
6080
- // smaller than `key`, is `key[0:key.length - 1]`. The next key smaller
6081
- // than that, `predecessor(predecessor(key))`, is
6082
- //
6083
- // `key[0:key.length - 2] + (key[key.length - 1] - 1) + \
6084
- // { MAX_PUSH_CHAR repeated MAX_KEY_LEN - (key.length - 1) times }
6085
- //
6086
- // analogous to increment/decrement for base-10 integers.
6087
- //
6088
- // This works because lexigographic comparison works character-by-character,
6089
- // using length as a tie-breaker if one key is a prefix of the other.
6090
- if (next[next.length - 1] === MIN_PUSH_CHAR) {
6091
- if (next.length === 1) {
6092
- // See https://firebase.google.com/docs/database/web/lists-of-data#orderbykey
6093
- return '' + INTEGER_32_MAX;
6094
- }
6095
- delete next[next.length - 1];
6096
- return next.join('');
6097
- }
6098
- // Replace the last character with it's immediate predecessor, and
6099
- // fill the suffix of the key with MAX_PUSH_CHAR. This is the
6100
- // lexicographically largest possible key smaller than `key`.
6101
- next[next.length - 1] = PUSH_CHARS.charAt(PUSH_CHARS.indexOf(next[next.length - 1]) - 1);
6102
- return next.join('') + MAX_PUSH_CHAR.repeat(MAX_KEY_LEN - next.length);
6103
- };
6104
-
6105
5958
  /**
6106
5959
  * @license
6107
5960
  * Copyright 2017 Google LLC
@@ -6119,24 +5972,24 @@ const predecessor = function (key) {
6119
5972
  * limitations under the License.
6120
5973
  */
6121
5974
  function changeValue(snapshotNode) {
6122
- return { type: "value" /* VALUE */, snapshotNode };
5975
+ return { type: "value" /* ChangeType.VALUE */, snapshotNode };
6123
5976
  }
6124
5977
  function changeChildAdded(childName, snapshotNode) {
6125
- return { type: "child_added" /* CHILD_ADDED */, snapshotNode, childName };
5978
+ return { type: "child_added" /* ChangeType.CHILD_ADDED */, snapshotNode, childName };
6126
5979
  }
6127
5980
  function changeChildRemoved(childName, snapshotNode) {
6128
- return { type: "child_removed" /* CHILD_REMOVED */, snapshotNode, childName };
5981
+ return { type: "child_removed" /* ChangeType.CHILD_REMOVED */, snapshotNode, childName };
6129
5982
  }
6130
5983
  function changeChildChanged(childName, snapshotNode, oldSnap) {
6131
5984
  return {
6132
- type: "child_changed" /* CHILD_CHANGED */,
5985
+ type: "child_changed" /* ChangeType.CHILD_CHANGED */,
6133
5986
  snapshotNode,
6134
5987
  childName,
6135
5988
  oldSnap
6136
5989
  };
6137
5990
  }
6138
5991
  function changeChildMoved(childName, snapshotNode) {
6139
- return { type: "child_moved" /* CHILD_MOVED */, snapshotNode, childName };
5992
+ return { type: "child_moved" /* ChangeType.CHILD_MOVED */, snapshotNode, childName };
6140
5993
  }
6141
5994
 
6142
5995
  /**
@@ -6270,6 +6123,8 @@ class RangedFilter {
6270
6123
  this.index_ = params.getIndex();
6271
6124
  this.startPost_ = RangedFilter.getStartPost_(params);
6272
6125
  this.endPost_ = RangedFilter.getEndPost_(params);
6126
+ this.startIsInclusive_ = !params.startAfterSet_;
6127
+ this.endIsInclusive_ = !params.endBeforeSet_;
6273
6128
  }
6274
6129
  getStartPost() {
6275
6130
  return this.startPost_;
@@ -6278,8 +6133,13 @@ class RangedFilter {
6278
6133
  return this.endPost_;
6279
6134
  }
6280
6135
  matches(node) {
6281
- return (this.index_.compare(this.getStartPost(), node) <= 0 &&
6282
- this.index_.compare(node, this.getEndPost()) <= 0);
6136
+ const isWithinStart = this.startIsInclusive_
6137
+ ? this.index_.compare(this.getStartPost(), node) <= 0
6138
+ : this.index_.compare(this.getStartPost(), node) < 0;
6139
+ const isWithinEnd = this.endIsInclusive_
6140
+ ? this.index_.compare(node, this.getEndPost()) <= 0
6141
+ : this.index_.compare(node, this.getEndPost()) < 0;
6142
+ return isWithinStart && isWithinEnd;
6283
6143
  }
6284
6144
  updateChild(snap, key, newChild, affectedPath, source, optChangeAccumulator) {
6285
6145
  if (!this.matches(new NamedNode(key, newChild))) {
@@ -6357,10 +6217,22 @@ class RangedFilter {
6357
6217
  */
6358
6218
  class LimitedFilter {
6359
6219
  constructor(params) {
6220
+ this.withinDirectionalStart = (node) => this.reverse_ ? this.withinEndPost(node) : this.withinStartPost(node);
6221
+ this.withinDirectionalEnd = (node) => this.reverse_ ? this.withinStartPost(node) : this.withinEndPost(node);
6222
+ this.withinStartPost = (node) => {
6223
+ const compareRes = this.index_.compare(this.rangedFilter_.getStartPost(), node);
6224
+ return this.startIsInclusive_ ? compareRes <= 0 : compareRes < 0;
6225
+ };
6226
+ this.withinEndPost = (node) => {
6227
+ const compareRes = this.index_.compare(node, this.rangedFilter_.getEndPost());
6228
+ return this.endIsInclusive_ ? compareRes <= 0 : compareRes < 0;
6229
+ };
6360
6230
  this.rangedFilter_ = new RangedFilter(params);
6361
6231
  this.index_ = params.getIndex();
6362
6232
  this.limit_ = params.getLimit();
6363
6233
  this.reverse_ = !params.isViewFromLeft();
6234
+ this.startIsInclusive_ = !params.startAfterSet_;
6235
+ this.endIsInclusive_ = !params.endBeforeSet_;
6364
6236
  }
6365
6237
  updateChild(snap, key, newChild, affectedPath, source, optChangeAccumulator) {
6366
6238
  if (!this.rangedFilter_.matches(new NamedNode(key, newChild))) {
@@ -6401,23 +6273,18 @@ class LimitedFilter {
6401
6273
  let count = 0;
6402
6274
  while (iterator.hasNext() && count < this.limit_) {
6403
6275
  const next = iterator.getNext();
6404
- let inRange;
6405
- if (this.reverse_) {
6406
- inRange =
6407
- this.index_.compare(this.rangedFilter_.getStartPost(), next) <= 0;
6276
+ if (!this.withinDirectionalStart(next)) {
6277
+ // if we have not reached the start, skip to the next element
6278
+ continue;
6408
6279
  }
6409
- else {
6410
- inRange =
6411
- this.index_.compare(next, this.rangedFilter_.getEndPost()) <= 0;
6280
+ else if (!this.withinDirectionalEnd(next)) {
6281
+ // if we have reached the end, stop adding elements
6282
+ break;
6412
6283
  }
6413
- if (inRange) {
6284
+ else {
6414
6285
  filtered = filtered.updateImmediateChild(next.name, next.node);
6415
6286
  count++;
6416
6287
  }
6417
- else {
6418
- // if we have reached the end post, we cannot keep adding elemments
6419
- break;
6420
- }
6421
6288
  }
6422
6289
  }
6423
6290
  else {
@@ -6425,32 +6292,19 @@ class LimitedFilter {
6425
6292
  filtered = newSnap.withIndex(this.index_);
6426
6293
  // Don't support priorities on queries
6427
6294
  filtered = filtered.updatePriority(ChildrenNode.EMPTY_NODE);
6428
- let startPost;
6429
- let endPost;
6430
- let cmp;
6431
6295
  let iterator;
6432
6296
  if (this.reverse_) {
6433
6297
  iterator = filtered.getReverseIterator(this.index_);
6434
- startPost = this.rangedFilter_.getEndPost();
6435
- endPost = this.rangedFilter_.getStartPost();
6436
- const indexCompare = this.index_.getCompare();
6437
- cmp = (a, b) => indexCompare(b, a);
6438
6298
  }
6439
6299
  else {
6440
6300
  iterator = filtered.getIterator(this.index_);
6441
- startPost = this.rangedFilter_.getStartPost();
6442
- endPost = this.rangedFilter_.getEndPost();
6443
- cmp = this.index_.getCompare();
6444
6301
  }
6445
6302
  let count = 0;
6446
- let foundStartPost = false;
6447
6303
  while (iterator.hasNext()) {
6448
6304
  const next = iterator.getNext();
6449
- if (!foundStartPost && cmp(startPost, next) <= 0) {
6450
- // start adding
6451
- foundStartPost = true;
6452
- }
6453
- const inRange = foundStartPost && count < this.limit_ && cmp(next, endPost) <= 0;
6305
+ const inRange = count < this.limit_ &&
6306
+ this.withinDirectionalStart(next) &&
6307
+ this.withinDirectionalEnd(next);
6454
6308
  if (inRange) {
6455
6309
  count++;
6456
6310
  }
@@ -6581,10 +6435,10 @@ class QueryParams {
6581
6435
  this.limitSet_ = false;
6582
6436
  this.startSet_ = false;
6583
6437
  this.startNameSet_ = false;
6584
- this.startAfterSet_ = false;
6438
+ this.startAfterSet_ = false; // can only be true if startSet_ is true
6585
6439
  this.endSet_ = false;
6586
6440
  this.endNameSet_ = false;
6587
- this.endBeforeSet_ = false;
6441
+ this.endBeforeSet_ = false; // can only be true if endSet_ is true
6588
6442
  this.limit_ = 0;
6589
6443
  this.viewFrom_ = '';
6590
6444
  this.indexStartValue_ = null;
@@ -6596,12 +6450,6 @@ class QueryParams {
6596
6450
  hasStart() {
6597
6451
  return this.startSet_;
6598
6452
  }
6599
- hasStartAfter() {
6600
- return this.startAfterSet_;
6601
- }
6602
- hasEndBefore() {
6603
- return this.endBeforeSet_;
6604
- }
6605
6453
  /**
6606
6454
  * @returns True if it would return from left.
6607
6455
  */
@@ -6614,7 +6462,7 @@ class QueryParams {
6614
6462
  return this.startSet_;
6615
6463
  }
6616
6464
  else {
6617
- return this.viewFrom_ === "l" /* VIEW_FROM_LEFT */;
6465
+ return this.viewFrom_ === "l" /* WIRE_PROTOCOL_CONSTANTS.VIEW_FROM_LEFT */;
6618
6466
  }
6619
6467
  }
6620
6468
  /**
@@ -6690,10 +6538,12 @@ class QueryParams {
6690
6538
  copy.limitSet_ = this.limitSet_;
6691
6539
  copy.limit_ = this.limit_;
6692
6540
  copy.startSet_ = this.startSet_;
6541
+ copy.startAfterSet_ = this.startAfterSet_;
6693
6542
  copy.indexStartValue_ = this.indexStartValue_;
6694
6543
  copy.startNameSet_ = this.startNameSet_;
6695
6544
  copy.indexStartName_ = this.indexStartName_;
6696
6545
  copy.endSet_ = this.endSet_;
6546
+ copy.endBeforeSet_ = this.endBeforeSet_;
6697
6547
  copy.indexEndValue_ = this.indexEndValue_;
6698
6548
  copy.endNameSet_ = this.endNameSet_;
6699
6549
  copy.indexEndName_ = this.indexEndName_;
@@ -6717,14 +6567,14 @@ function queryParamsLimitToFirst(queryParams, newLimit) {
6717
6567
  const newParams = queryParams.copy();
6718
6568
  newParams.limitSet_ = true;
6719
6569
  newParams.limit_ = newLimit;
6720
- newParams.viewFrom_ = "l" /* VIEW_FROM_LEFT */;
6570
+ newParams.viewFrom_ = "l" /* WIRE_PROTOCOL_CONSTANTS.VIEW_FROM_LEFT */;
6721
6571
  return newParams;
6722
6572
  }
6723
6573
  function queryParamsLimitToLast(queryParams, newLimit) {
6724
6574
  const newParams = queryParams.copy();
6725
6575
  newParams.limitSet_ = true;
6726
6576
  newParams.limit_ = newLimit;
6727
- newParams.viewFrom_ = "r" /* VIEW_FROM_RIGHT */;
6577
+ newParams.viewFrom_ = "r" /* WIRE_PROTOCOL_CONSTANTS.VIEW_FROM_RIGHT */;
6728
6578
  return newParams;
6729
6579
  }
6730
6580
  function queryParamsStartAt(queryParams, indexValue, key) {
@@ -6746,21 +6596,11 @@ function queryParamsStartAt(queryParams, indexValue, key) {
6746
6596
  }
6747
6597
  function queryParamsStartAfter(queryParams, indexValue, key) {
6748
6598
  let params;
6749
- if (queryParams.index_ === KEY_INDEX) {
6750
- if (typeof indexValue === 'string') {
6751
- indexValue = successor(indexValue);
6752
- }
6599
+ if (queryParams.index_ === KEY_INDEX || !!key) {
6753
6600
  params = queryParamsStartAt(queryParams, indexValue, key);
6754
6601
  }
6755
6602
  else {
6756
- let childKey;
6757
- if (key == null) {
6758
- childKey = MAX_NAME;
6759
- }
6760
- else {
6761
- childKey = successor(key);
6762
- }
6763
- params = queryParamsStartAt(queryParams, indexValue, childKey);
6603
+ params = queryParamsStartAt(queryParams, indexValue, MAX_NAME);
6764
6604
  }
6765
6605
  params.startAfterSet_ = true;
6766
6606
  return params;
@@ -6783,22 +6623,12 @@ function queryParamsEndAt(queryParams, indexValue, key) {
6783
6623
  return newParams;
6784
6624
  }
6785
6625
  function queryParamsEndBefore(queryParams, indexValue, key) {
6786
- let childKey;
6787
6626
  let params;
6788
- if (queryParams.index_ === KEY_INDEX) {
6789
- if (typeof indexValue === 'string') {
6790
- indexValue = predecessor(indexValue);
6791
- }
6627
+ if (queryParams.index_ === KEY_INDEX || !!key) {
6792
6628
  params = queryParamsEndAt(queryParams, indexValue, key);
6793
6629
  }
6794
6630
  else {
6795
- if (key == null) {
6796
- childKey = MIN_NAME;
6797
- }
6798
- else {
6799
- childKey = predecessor(key);
6800
- }
6801
- params = queryParamsEndAt(queryParams, indexValue, childKey);
6631
+ params = queryParamsEndAt(queryParams, indexValue, MIN_NAME);
6802
6632
  }
6803
6633
  params.endBeforeSet_ = true;
6804
6634
  return params;
@@ -6820,39 +6650,43 @@ function queryParamsToRestQueryStringParameters(queryParams) {
6820
6650
  }
6821
6651
  let orderBy;
6822
6652
  if (queryParams.index_ === PRIORITY_INDEX) {
6823
- orderBy = "$priority" /* PRIORITY_INDEX */;
6653
+ orderBy = "$priority" /* REST_QUERY_CONSTANTS.PRIORITY_INDEX */;
6824
6654
  }
6825
6655
  else if (queryParams.index_ === VALUE_INDEX) {
6826
- orderBy = "$value" /* VALUE_INDEX */;
6656
+ orderBy = "$value" /* REST_QUERY_CONSTANTS.VALUE_INDEX */;
6827
6657
  }
6828
6658
  else if (queryParams.index_ === KEY_INDEX) {
6829
- orderBy = "$key" /* KEY_INDEX */;
6659
+ orderBy = "$key" /* REST_QUERY_CONSTANTS.KEY_INDEX */;
6830
6660
  }
6831
6661
  else {
6832
6662
  assert(queryParams.index_ instanceof PathIndex, 'Unrecognized index type!');
6833
6663
  orderBy = queryParams.index_.toString();
6834
6664
  }
6835
- qs["orderBy" /* ORDER_BY */] = stringify(orderBy);
6665
+ qs["orderBy" /* REST_QUERY_CONSTANTS.ORDER_BY */] = stringify(orderBy);
6836
6666
  if (queryParams.startSet_) {
6837
- qs["startAt" /* START_AT */] = stringify(queryParams.indexStartValue_);
6667
+ const startParam = queryParams.startAfterSet_
6668
+ ? "startAfter" /* REST_QUERY_CONSTANTS.START_AFTER */
6669
+ : "startAt" /* REST_QUERY_CONSTANTS.START_AT */;
6670
+ qs[startParam] = stringify(queryParams.indexStartValue_);
6838
6671
  if (queryParams.startNameSet_) {
6839
- qs["startAt" /* START_AT */] +=
6840
- ',' + stringify(queryParams.indexStartName_);
6672
+ qs[startParam] += ',' + stringify(queryParams.indexStartName_);
6841
6673
  }
6842
6674
  }
6843
6675
  if (queryParams.endSet_) {
6844
- qs["endAt" /* END_AT */] = stringify(queryParams.indexEndValue_);
6676
+ const endParam = queryParams.endBeforeSet_
6677
+ ? "endBefore" /* REST_QUERY_CONSTANTS.END_BEFORE */
6678
+ : "endAt" /* REST_QUERY_CONSTANTS.END_AT */;
6679
+ qs[endParam] = stringify(queryParams.indexEndValue_);
6845
6680
  if (queryParams.endNameSet_) {
6846
- qs["endAt" /* END_AT */] +=
6847
- ',' + stringify(queryParams.indexEndName_);
6681
+ qs[endParam] += ',' + stringify(queryParams.indexEndName_);
6848
6682
  }
6849
6683
  }
6850
6684
  if (queryParams.limitSet_) {
6851
6685
  if (queryParams.isViewFromLeft()) {
6852
- qs["limitToFirst" /* LIMIT_TO_FIRST */] = queryParams.limit_;
6686
+ qs["limitToFirst" /* REST_QUERY_CONSTANTS.LIMIT_TO_FIRST */] = queryParams.limit_;
6853
6687
  }
6854
6688
  else {
6855
- qs["limitToLast" /* LIMIT_TO_LAST */] = queryParams.limit_;
6689
+ qs["limitToLast" /* REST_QUERY_CONSTANTS.LIMIT_TO_LAST */] = queryParams.limit_;
6856
6690
  }
6857
6691
  }
6858
6692
  return qs;
@@ -6860,35 +6694,39 @@ function queryParamsToRestQueryStringParameters(queryParams) {
6860
6694
  function queryParamsGetQueryObject(queryParams) {
6861
6695
  const obj = {};
6862
6696
  if (queryParams.startSet_) {
6863
- obj["sp" /* INDEX_START_VALUE */] =
6697
+ obj["sp" /* WIRE_PROTOCOL_CONSTANTS.INDEX_START_VALUE */] =
6864
6698
  queryParams.indexStartValue_;
6865
6699
  if (queryParams.startNameSet_) {
6866
- obj["sn" /* INDEX_START_NAME */] =
6700
+ obj["sn" /* WIRE_PROTOCOL_CONSTANTS.INDEX_START_NAME */] =
6867
6701
  queryParams.indexStartName_;
6868
6702
  }
6703
+ obj["sin" /* WIRE_PROTOCOL_CONSTANTS.INDEX_START_IS_INCLUSIVE */] =
6704
+ !queryParams.startAfterSet_;
6869
6705
  }
6870
6706
  if (queryParams.endSet_) {
6871
- obj["ep" /* INDEX_END_VALUE */] = queryParams.indexEndValue_;
6707
+ obj["ep" /* WIRE_PROTOCOL_CONSTANTS.INDEX_END_VALUE */] = queryParams.indexEndValue_;
6872
6708
  if (queryParams.endNameSet_) {
6873
- obj["en" /* INDEX_END_NAME */] = queryParams.indexEndName_;
6709
+ obj["en" /* WIRE_PROTOCOL_CONSTANTS.INDEX_END_NAME */] = queryParams.indexEndName_;
6874
6710
  }
6711
+ obj["ein" /* WIRE_PROTOCOL_CONSTANTS.INDEX_END_IS_INCLUSIVE */] =
6712
+ !queryParams.endBeforeSet_;
6875
6713
  }
6876
6714
  if (queryParams.limitSet_) {
6877
- obj["l" /* LIMIT */] = queryParams.limit_;
6715
+ obj["l" /* WIRE_PROTOCOL_CONSTANTS.LIMIT */] = queryParams.limit_;
6878
6716
  let viewFrom = queryParams.viewFrom_;
6879
6717
  if (viewFrom === '') {
6880
6718
  if (queryParams.isViewFromLeft()) {
6881
- viewFrom = "l" /* VIEW_FROM_LEFT */;
6719
+ viewFrom = "l" /* WIRE_PROTOCOL_CONSTANTS.VIEW_FROM_LEFT */;
6882
6720
  }
6883
6721
  else {
6884
- viewFrom = "r" /* VIEW_FROM_RIGHT */;
6722
+ viewFrom = "r" /* WIRE_PROTOCOL_CONSTANTS.VIEW_FROM_RIGHT */;
6885
6723
  }
6886
6724
  }
6887
- obj["vf" /* VIEW_FROM */] = viewFrom;
6725
+ obj["vf" /* WIRE_PROTOCOL_CONSTANTS.VIEW_FROM */] = viewFrom;
6888
6726
  }
6889
6727
  // For now, priority index is the default, so we only specify if it's some other index
6890
6728
  if (queryParams.index_ !== PRIORITY_INDEX) {
6891
- obj["i" /* INDEX */] = queryParams.index_.toString();
6729
+ obj["i" /* WIRE_PROTOCOL_CONSTANTS.INDEX */] = queryParams.index_.toString();
6892
6730
  }
6893
6731
  return obj;
6894
6732
  }
@@ -7632,16 +7470,16 @@ function eventGeneratorGenerateEventsForChanges(eventGenerator, changes, eventCa
7632
7470
  const events = [];
7633
7471
  const moves = [];
7634
7472
  changes.forEach(change => {
7635
- if (change.type === "child_changed" /* CHILD_CHANGED */ &&
7473
+ if (change.type === "child_changed" /* ChangeType.CHILD_CHANGED */ &&
7636
7474
  eventGenerator.index_.indexedValueChanged(change.oldSnap, change.snapshotNode)) {
7637
7475
  moves.push(changeChildMoved(change.childName, change.snapshotNode));
7638
7476
  }
7639
7477
  });
7640
- eventGeneratorGenerateEventsForType(eventGenerator, events, "child_removed" /* CHILD_REMOVED */, changes, eventRegistrations, eventCache);
7641
- eventGeneratorGenerateEventsForType(eventGenerator, events, "child_added" /* CHILD_ADDED */, changes, eventRegistrations, eventCache);
7642
- eventGeneratorGenerateEventsForType(eventGenerator, events, "child_moved" /* CHILD_MOVED */, moves, eventRegistrations, eventCache);
7643
- eventGeneratorGenerateEventsForType(eventGenerator, events, "child_changed" /* CHILD_CHANGED */, changes, eventRegistrations, eventCache);
7644
- eventGeneratorGenerateEventsForType(eventGenerator, events, "value" /* VALUE */, changes, eventRegistrations, eventCache);
7478
+ eventGeneratorGenerateEventsForType(eventGenerator, events, "child_removed" /* ChangeType.CHILD_REMOVED */, changes, eventRegistrations, eventCache);
7479
+ eventGeneratorGenerateEventsForType(eventGenerator, events, "child_added" /* ChangeType.CHILD_ADDED */, changes, eventRegistrations, eventCache);
7480
+ eventGeneratorGenerateEventsForType(eventGenerator, events, "child_moved" /* ChangeType.CHILD_MOVED */, moves, eventRegistrations, eventCache);
7481
+ eventGeneratorGenerateEventsForType(eventGenerator, events, "child_changed" /* ChangeType.CHILD_CHANGED */, changes, eventRegistrations, eventCache);
7482
+ eventGeneratorGenerateEventsForType(eventGenerator, events, "value" /* ChangeType.VALUE */, changes, eventRegistrations, eventCache);
7645
7483
  return events;
7646
7484
  }
7647
7485
  /**
@@ -8722,31 +8560,31 @@ class ChildChangeAccumulator {
8722
8560
  trackChildChange(change) {
8723
8561
  const type = change.type;
8724
8562
  const childKey = change.childName;
8725
- assert(type === "child_added" /* CHILD_ADDED */ ||
8726
- type === "child_changed" /* CHILD_CHANGED */ ||
8727
- type === "child_removed" /* CHILD_REMOVED */, 'Only child changes supported for tracking');
8563
+ assert(type === "child_added" /* ChangeType.CHILD_ADDED */ ||
8564
+ type === "child_changed" /* ChangeType.CHILD_CHANGED */ ||
8565
+ type === "child_removed" /* ChangeType.CHILD_REMOVED */, 'Only child changes supported for tracking');
8728
8566
  assert(childKey !== '.priority', 'Only non-priority child changes can be tracked.');
8729
8567
  const oldChange = this.changeMap.get(childKey);
8730
8568
  if (oldChange) {
8731
8569
  const oldType = oldChange.type;
8732
- if (type === "child_added" /* CHILD_ADDED */ &&
8733
- oldType === "child_removed" /* CHILD_REMOVED */) {
8570
+ if (type === "child_added" /* ChangeType.CHILD_ADDED */ &&
8571
+ oldType === "child_removed" /* ChangeType.CHILD_REMOVED */) {
8734
8572
  this.changeMap.set(childKey, changeChildChanged(childKey, change.snapshotNode, oldChange.snapshotNode));
8735
8573
  }
8736
- else if (type === "child_removed" /* CHILD_REMOVED */ &&
8737
- oldType === "child_added" /* CHILD_ADDED */) {
8574
+ else if (type === "child_removed" /* ChangeType.CHILD_REMOVED */ &&
8575
+ oldType === "child_added" /* ChangeType.CHILD_ADDED */) {
8738
8576
  this.changeMap.delete(childKey);
8739
8577
  }
8740
- else if (type === "child_removed" /* CHILD_REMOVED */ &&
8741
- oldType === "child_changed" /* CHILD_CHANGED */) {
8578
+ else if (type === "child_removed" /* ChangeType.CHILD_REMOVED */ &&
8579
+ oldType === "child_changed" /* ChangeType.CHILD_CHANGED */) {
8742
8580
  this.changeMap.set(childKey, changeChildRemoved(childKey, oldChange.oldSnap));
8743
8581
  }
8744
- else if (type === "child_changed" /* CHILD_CHANGED */ &&
8745
- oldType === "child_added" /* CHILD_ADDED */) {
8582
+ else if (type === "child_changed" /* ChangeType.CHILD_CHANGED */ &&
8583
+ oldType === "child_added" /* ChangeType.CHILD_ADDED */) {
8746
8584
  this.changeMap.set(childKey, changeChildAdded(childKey, change.snapshotNode));
8747
8585
  }
8748
- else if (type === "child_changed" /* CHILD_CHANGED */ &&
8749
- oldType === "child_changed" /* CHILD_CHANGED */) {
8586
+ else if (type === "child_changed" /* ChangeType.CHILD_CHANGED */ &&
8587
+ oldType === "child_changed" /* ChangeType.CHILD_CHANGED */) {
8750
8588
  this.changeMap.set(childKey, changeChildChanged(childKey, change.snapshotNode, oldChange.oldSnap));
8751
8589
  }
8752
8590
  else {
@@ -11456,7 +11294,7 @@ function repoStartTransaction(repo, path, transactionUpdate, onComplete, unwatch
11456
11294
  else {
11457
11295
  validateFirebaseData('transaction failed: Data returned ', newVal, transaction.path);
11458
11296
  // Mark as run and add to our queue.
11459
- transaction.status = 0 /* RUN */;
11297
+ transaction.status = 0 /* TransactionStatus.RUN */;
11460
11298
  const queueNode = treeSubTree(repo.transactionQueueTree_, path);
11461
11299
  const nodeQueue = treeGetValue(queueNode) || [];
11462
11300
  nodeQueue.push(transaction);
@@ -11514,7 +11352,7 @@ function repoSendReadyTransactions(repo, node = repo.transactionQueueTree_) {
11514
11352
  if (treeGetValue(node)) {
11515
11353
  const queue = repoBuildTransactionQueue(repo, node);
11516
11354
  assert(queue.length > 0, 'Sending zero length transaction queue');
11517
- const allRun = queue.every((transaction) => transaction.status === 0 /* RUN */);
11355
+ const allRun = queue.every((transaction) => transaction.status === 0 /* TransactionStatus.RUN */);
11518
11356
  // If they're all run (and not sent), we can send them. Else, we must wait.
11519
11357
  if (allRun) {
11520
11358
  repoSendTransactionQueue(repo, treeGetPath(node), queue);
@@ -11543,8 +11381,8 @@ function repoSendTransactionQueue(repo, path, queue) {
11543
11381
  const latestHash = latestState.hash();
11544
11382
  for (let i = 0; i < queue.length; i++) {
11545
11383
  const txn = queue[i];
11546
- assert(txn.status === 0 /* RUN */, 'tryToSendTransactionQueue_: items in queue should all be run.');
11547
- txn.status = 1 /* SENT */;
11384
+ assert(txn.status === 0 /* TransactionStatus.RUN */, 'tryToSendTransactionQueue_: items in queue should all be run.');
11385
+ txn.status = 1 /* TransactionStatus.SENT */;
11548
11386
  txn.retryCount++;
11549
11387
  const relativePath = newRelativePath(path, txn.path);
11550
11388
  // If we've gotten to this point, the output snapshot must be defined.
@@ -11565,7 +11403,7 @@ function repoSendTransactionQueue(repo, path, queue) {
11565
11403
  // transactions or sets.
11566
11404
  const callbacks = [];
11567
11405
  for (let i = 0; i < queue.length; i++) {
11568
- queue[i].status = 2 /* COMPLETED */;
11406
+ queue[i].status = 2 /* TransactionStatus.COMPLETED */;
11569
11407
  events = events.concat(syncTreeAckUserWrite(repo.serverSyncTree_, queue[i].currentWriteId));
11570
11408
  if (queue[i].onComplete) {
11571
11409
  // We never unset the output snapshot, and given that this
@@ -11588,18 +11426,18 @@ function repoSendTransactionQueue(repo, path, queue) {
11588
11426
  // transactions are no longer sent. Update their status appropriately.
11589
11427
  if (status === 'datastale') {
11590
11428
  for (let i = 0; i < queue.length; i++) {
11591
- if (queue[i].status === 3 /* SENT_NEEDS_ABORT */) {
11592
- queue[i].status = 4 /* NEEDS_ABORT */;
11429
+ if (queue[i].status === 3 /* TransactionStatus.SENT_NEEDS_ABORT */) {
11430
+ queue[i].status = 4 /* TransactionStatus.NEEDS_ABORT */;
11593
11431
  }
11594
11432
  else {
11595
- queue[i].status = 0 /* RUN */;
11433
+ queue[i].status = 0 /* TransactionStatus.RUN */;
11596
11434
  }
11597
11435
  }
11598
11436
  }
11599
11437
  else {
11600
11438
  warn('transaction at ' + pathToSend.toString() + ' failed: ' + status);
11601
11439
  for (let i = 0; i < queue.length; i++) {
11602
- queue[i].status = 4 /* NEEDS_ABORT */;
11440
+ queue[i].status = 4 /* TransactionStatus.NEEDS_ABORT */;
11603
11441
  queue[i].abortReason = status;
11604
11442
  }
11605
11443
  }
@@ -11643,7 +11481,7 @@ function repoRerunTransactionQueue(repo, queue, path) {
11643
11481
  let events = [];
11644
11482
  // Ignore all of the sets we're going to re-run.
11645
11483
  const txnsToRerun = queue.filter(q => {
11646
- return q.status === 0 /* RUN */;
11484
+ return q.status === 0 /* TransactionStatus.RUN */;
11647
11485
  });
11648
11486
  const setsToIgnore = txnsToRerun.map(q => {
11649
11487
  return q.currentWriteId;
@@ -11653,12 +11491,12 @@ function repoRerunTransactionQueue(repo, queue, path) {
11653
11491
  const relativePath = newRelativePath(path, transaction.path);
11654
11492
  let abortTransaction = false, abortReason;
11655
11493
  assert(relativePath !== null, 'rerunTransactionsUnderNode_: relativePath should not be null.');
11656
- if (transaction.status === 4 /* NEEDS_ABORT */) {
11494
+ if (transaction.status === 4 /* TransactionStatus.NEEDS_ABORT */) {
11657
11495
  abortTransaction = true;
11658
11496
  abortReason = transaction.abortReason;
11659
11497
  events = events.concat(syncTreeAckUserWrite(repo.serverSyncTree_, transaction.currentWriteId, true));
11660
11498
  }
11661
- else if (transaction.status === 0 /* RUN */) {
11499
+ else if (transaction.status === 0 /* TransactionStatus.RUN */) {
11662
11500
  if (transaction.retryCount >= MAX_TRANSACTION_RETRIES) {
11663
11501
  abortTransaction = true;
11664
11502
  abortReason = 'maxretry';
@@ -11701,7 +11539,7 @@ function repoRerunTransactionQueue(repo, queue, path) {
11701
11539
  events = [];
11702
11540
  if (abortTransaction) {
11703
11541
  // Abort.
11704
- queue[i].status = 2 /* COMPLETED */;
11542
+ queue[i].status = 2 /* TransactionStatus.COMPLETED */;
11705
11543
  // Removing a listener can trigger pruning which can muck with
11706
11544
  // mergedData/visibleData (as it prunes data). So defer the unwatcher
11707
11545
  // until we're done.
@@ -11782,7 +11620,7 @@ function repoPruneCompletedTransactionsBelowNode(repo, node) {
11782
11620
  if (queue) {
11783
11621
  let to = 0;
11784
11622
  for (let from = 0; from < queue.length; from++) {
11785
- if (queue[from].status !== 2 /* COMPLETED */) {
11623
+ if (queue[from].status !== 2 /* TransactionStatus.COMPLETED */) {
11786
11624
  queue[to] = queue[from];
11787
11625
  to++;
11788
11626
  }
@@ -11830,16 +11668,16 @@ function repoAbortTransactionsOnNode(repo, node) {
11830
11668
  let events = [];
11831
11669
  let lastSent = -1;
11832
11670
  for (let i = 0; i < queue.length; i++) {
11833
- if (queue[i].status === 3 /* SENT_NEEDS_ABORT */) ;
11834
- else if (queue[i].status === 1 /* SENT */) {
11671
+ if (queue[i].status === 3 /* TransactionStatus.SENT_NEEDS_ABORT */) ;
11672
+ else if (queue[i].status === 1 /* TransactionStatus.SENT */) {
11835
11673
  assert(lastSent === i - 1, 'All SENT items should be at beginning of queue.');
11836
11674
  lastSent = i;
11837
11675
  // Mark transaction for abort when it comes back.
11838
- queue[i].status = 3 /* SENT_NEEDS_ABORT */;
11676
+ queue[i].status = 3 /* TransactionStatus.SENT_NEEDS_ABORT */;
11839
11677
  queue[i].abortReason = 'set';
11840
11678
  }
11841
11679
  else {
11842
- assert(queue[i].status === 0 /* RUN */, 'Unexpected transaction status in abort');
11680
+ assert(queue[i].status === 0 /* TransactionStatus.RUN */, 'Unexpected transaction status in abort');
11843
11681
  // We can abort it immediately.
11844
11682
  queue[i].unwatcher();
11845
11683
  events = events.concat(syncTreeAckUserWrite(repo.serverSyncTree_, queue[i].currentWriteId, true));
@@ -12009,6 +11847,81 @@ const parseDatabaseURL = function (dataURL) {
12009
11847
  };
12010
11848
  };
12011
11849
 
11850
+ /**
11851
+ * @license
11852
+ * Copyright 2017 Google LLC
11853
+ *
11854
+ * Licensed under the Apache License, Version 2.0 (the "License");
11855
+ * you may not use this file except in compliance with the License.
11856
+ * You may obtain a copy of the License at
11857
+ *
11858
+ * http://www.apache.org/licenses/LICENSE-2.0
11859
+ *
11860
+ * Unless required by applicable law or agreed to in writing, software
11861
+ * distributed under the License is distributed on an "AS IS" BASIS,
11862
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11863
+ * See the License for the specific language governing permissions and
11864
+ * limitations under the License.
11865
+ */
11866
+ // Modeled after base64 web-safe chars, but ordered by ASCII.
11867
+ const PUSH_CHARS = '-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz';
11868
+ /**
11869
+ * Fancy ID generator that creates 20-character string identifiers with the
11870
+ * following properties:
11871
+ *
11872
+ * 1. They're based on timestamp so that they sort *after* any existing ids.
11873
+ * 2. They contain 72-bits of random data after the timestamp so that IDs won't
11874
+ * collide with other clients' IDs.
11875
+ * 3. They sort *lexicographically* (so the timestamp is converted to characters
11876
+ * that will sort properly).
11877
+ * 4. They're monotonically increasing. Even if you generate more than one in
11878
+ * the same timestamp, the latter ones will sort after the former ones. We do
11879
+ * this by using the previous random bits but "incrementing" them by 1 (only
11880
+ * in the case of a timestamp collision).
11881
+ */
11882
+ const nextPushId = (function () {
11883
+ // Timestamp of last push, used to prevent local collisions if you push twice
11884
+ // in one ms.
11885
+ let lastPushTime = 0;
11886
+ // We generate 72-bits of randomness which get turned into 12 characters and
11887
+ // appended to the timestamp to prevent collisions with other clients. We
11888
+ // store the last characters we generated because in the event of a collision,
11889
+ // we'll use those same characters except "incremented" by one.
11890
+ const lastRandChars = [];
11891
+ return function (now) {
11892
+ const duplicateTime = now === lastPushTime;
11893
+ lastPushTime = now;
11894
+ let i;
11895
+ const timeStampChars = new Array(8);
11896
+ for (i = 7; i >= 0; i--) {
11897
+ timeStampChars[i] = PUSH_CHARS.charAt(now % 64);
11898
+ // NOTE: Can't use << here because javascript will convert to int and lose
11899
+ // the upper bits.
11900
+ now = Math.floor(now / 64);
11901
+ }
11902
+ assert(now === 0, 'Cannot push at time == 0');
11903
+ let id = timeStampChars.join('');
11904
+ if (!duplicateTime) {
11905
+ for (i = 0; i < 12; i++) {
11906
+ lastRandChars[i] = Math.floor(Math.random() * 64);
11907
+ }
11908
+ }
11909
+ else {
11910
+ // If the timestamp hasn't changed since last push, use the same random
11911
+ // number, except incremented by 1.
11912
+ for (i = 11; i >= 0 && lastRandChars[i] === 63; i--) {
11913
+ lastRandChars[i] = 0;
11914
+ }
11915
+ lastRandChars[i]++;
11916
+ }
11917
+ for (i = 0; i < 12; i++) {
11918
+ id += PUSH_CHARS.charAt(lastRandChars[i]);
11919
+ }
11920
+ assert(id.length === 20, 'nextPushId: Length should be 20.');
11921
+ return id;
11922
+ };
11923
+ })();
11924
+
12012
11925
  /**
12013
11926
  * @license
12014
11927
  * Copyright 2017 Google LLC
@@ -13817,7 +13730,7 @@ function registerDatabase(variant) {
13817
13730
  const authProvider = container.getProvider('auth-internal');
13818
13731
  const appCheckProvider = container.getProvider('app-check-internal');
13819
13732
  return repoManagerDatabaseFromApp(app, authProvider, appCheckProvider, url);
13820
- }, "PUBLIC" /* PUBLIC */).setMultipleInstances(true));
13733
+ }, "PUBLIC" /* ComponentType.PUBLIC */).setMultipleInstances(true));
13821
13734
  registerVersion(name, version, variant);
13822
13735
  // BUILD_TARGET will be replaced by values like esm5, esm2017, cjs5, etc during the compilation
13823
13736
  registerVersion(name, version, 'esm2017');