@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.
@@ -4,7 +4,7 @@ import { stringify, jsonEval, contains, assert, isNodeSdk, stringToByteArray, Sh
4
4
  import { Logger, LogLevel } from '@firebase/logger';
5
5
 
6
6
  const name = "@firebase/database";
7
- const version = "0.13.10";
7
+ const version = "0.14.0";
8
8
 
9
9
  /**
10
10
  * @license
@@ -2262,7 +2262,7 @@ class Connection {
2262
2262
  this.lastSessionId = lastSessionId;
2263
2263
  this.connectionCount = 0;
2264
2264
  this.pendingDataMessages = [];
2265
- this.state_ = 0 /* CONNECTING */;
2265
+ this.state_ = 0 /* RealtimeState.CONNECTING */;
2266
2266
  this.log_ = logWrapper('c:' + this.id + ':');
2267
2267
  this.transportManager_ = new TransportManager(repoInfo_);
2268
2268
  this.log_('Connection created');
@@ -2342,7 +2342,7 @@ class Connection {
2342
2342
  }
2343
2343
  connReceiver_(conn) {
2344
2344
  return (message) => {
2345
- if (this.state_ !== 2 /* DISCONNECTED */) {
2345
+ if (this.state_ !== 2 /* RealtimeState.DISCONNECTED */) {
2346
2346
  if (conn === this.rx_) {
2347
2347
  this.onPrimaryMessageReceived_(message);
2348
2348
  }
@@ -2508,7 +2508,7 @@ class Connection {
2508
2508
  this.sessionId = handshake.s;
2509
2509
  this.repoInfo_.host = host;
2510
2510
  // if we've already closed the connection, then don't bother trying to progress further
2511
- if (this.state_ === 0 /* CONNECTING */) {
2511
+ if (this.state_ === 0 /* RealtimeState.CONNECTING */) {
2512
2512
  this.conn_.start();
2513
2513
  this.onConnectionEstablished_(this.conn_, timestamp);
2514
2514
  if (PROTOCOL_VERSION !== version) {
@@ -2546,7 +2546,7 @@ class Connection {
2546
2546
  this.repoInfo_.host = host;
2547
2547
  // TODO: if we're already "connected", we need to trigger a disconnect at the next layer up.
2548
2548
  // We don't currently support resets after the connection has already been established
2549
- if (this.state_ === 1 /* CONNECTED */) {
2549
+ if (this.state_ === 1 /* RealtimeState.CONNECTED */) {
2550
2550
  this.close();
2551
2551
  }
2552
2552
  else {
@@ -2558,7 +2558,7 @@ class Connection {
2558
2558
  onConnectionEstablished_(conn, timestamp) {
2559
2559
  this.log_('Realtime connection established.');
2560
2560
  this.conn_ = conn;
2561
- this.state_ = 1 /* CONNECTED */;
2561
+ this.state_ = 1 /* RealtimeState.CONNECTED */;
2562
2562
  if (this.onReady_) {
2563
2563
  this.onReady_(timestamp, this.sessionId);
2564
2564
  this.onReady_ = null;
@@ -2577,7 +2577,7 @@ class Connection {
2577
2577
  }
2578
2578
  sendPingOnPrimaryIfNecessary_() {
2579
2579
  // If the connection isn't considered healthy yet, we'll send a noop ping packet request.
2580
- if (!this.isHealthy_ && this.state_ === 1 /* CONNECTED */) {
2580
+ if (!this.isHealthy_ && this.state_ === 1 /* RealtimeState.CONNECTED */) {
2581
2581
  this.log_('sending ping on primary.');
2582
2582
  this.sendData_({ t: 'c', d: { t: PING, d: {} } });
2583
2583
  }
@@ -2598,7 +2598,7 @@ class Connection {
2598
2598
  this.conn_ = null;
2599
2599
  // NOTE: IF you're seeing a Firefox error for this line, I think it might be because it's getting
2600
2600
  // called on window close and RealtimeState.CONNECTING is no longer defined. Just a guess.
2601
- if (!everConnected && this.state_ === 0 /* CONNECTING */) {
2601
+ if (!everConnected && this.state_ === 0 /* RealtimeState.CONNECTING */) {
2602
2602
  this.log_('Realtime connection failed.');
2603
2603
  // Since we failed to connect at all, clear any cached entry for this namespace in case the machine went away
2604
2604
  if (this.repoInfo_.isCacheableHost()) {
@@ -2607,7 +2607,7 @@ class Connection {
2607
2607
  this.repoInfo_.internalHost = this.repoInfo_.host;
2608
2608
  }
2609
2609
  }
2610
- else if (this.state_ === 1 /* CONNECTED */) {
2610
+ else if (this.state_ === 1 /* RealtimeState.CONNECTED */) {
2611
2611
  this.log_('Realtime connection lost.');
2612
2612
  }
2613
2613
  this.close();
@@ -2624,7 +2624,7 @@ class Connection {
2624
2624
  this.close();
2625
2625
  }
2626
2626
  sendData_(data) {
2627
- if (this.state_ !== 1 /* CONNECTED */) {
2627
+ if (this.state_ !== 1 /* RealtimeState.CONNECTED */) {
2628
2628
  throw 'Connection is not connected';
2629
2629
  }
2630
2630
  else {
@@ -2635,9 +2635,9 @@ class Connection {
2635
2635
  * Cleans up this connection, calling the appropriate callbacks
2636
2636
  */
2637
2637
  close() {
2638
- if (this.state_ !== 2 /* DISCONNECTED */) {
2638
+ if (this.state_ !== 2 /* RealtimeState.DISCONNECTED */) {
2639
2639
  this.log_('Closing realtime connection.');
2640
- this.state_ = 2 /* DISCONNECTED */;
2640
+ this.state_ = 2 /* RealtimeState.DISCONNECTED */;
2641
2641
  this.closeConnections_();
2642
2642
  if (this.onDisconnect_) {
2643
2643
  this.onDisconnect_();
@@ -5951,153 +5951,6 @@ class ValueIndex extends Index {
5951
5951
  }
5952
5952
  const VALUE_INDEX = new ValueIndex();
5953
5953
 
5954
- /**
5955
- * @license
5956
- * Copyright 2017 Google LLC
5957
- *
5958
- * Licensed under the Apache License, Version 2.0 (the "License");
5959
- * you may not use this file except in compliance with the License.
5960
- * You may obtain a copy of the License at
5961
- *
5962
- * http://www.apache.org/licenses/LICENSE-2.0
5963
- *
5964
- * Unless required by applicable law or agreed to in writing, software
5965
- * distributed under the License is distributed on an "AS IS" BASIS,
5966
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5967
- * See the License for the specific language governing permissions and
5968
- * limitations under the License.
5969
- */
5970
- // Modeled after base64 web-safe chars, but ordered by ASCII.
5971
- const PUSH_CHARS = '-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz';
5972
- const MIN_PUSH_CHAR = '-';
5973
- const MAX_PUSH_CHAR = 'z';
5974
- const MAX_KEY_LEN = 786;
5975
- /**
5976
- * Fancy ID generator that creates 20-character string identifiers with the
5977
- * following properties:
5978
- *
5979
- * 1. They're based on timestamp so that they sort *after* any existing ids.
5980
- * 2. They contain 72-bits of random data after the timestamp so that IDs won't
5981
- * collide with other clients' IDs.
5982
- * 3. They sort *lexicographically* (so the timestamp is converted to characters
5983
- * that will sort properly).
5984
- * 4. They're monotonically increasing. Even if you generate more than one in
5985
- * the same timestamp, the latter ones will sort after the former ones. We do
5986
- * this by using the previous random bits but "incrementing" them by 1 (only
5987
- * in the case of a timestamp collision).
5988
- */
5989
- const nextPushId = (function () {
5990
- // Timestamp of last push, used to prevent local collisions if you push twice
5991
- // in one ms.
5992
- let lastPushTime = 0;
5993
- // We generate 72-bits of randomness which get turned into 12 characters and
5994
- // appended to the timestamp to prevent collisions with other clients. We
5995
- // store the last characters we generated because in the event of a collision,
5996
- // we'll use those same characters except "incremented" by one.
5997
- const lastRandChars = [];
5998
- return function (now) {
5999
- const duplicateTime = now === lastPushTime;
6000
- lastPushTime = now;
6001
- let i;
6002
- const timeStampChars = new Array(8);
6003
- for (i = 7; i >= 0; i--) {
6004
- timeStampChars[i] = PUSH_CHARS.charAt(now % 64);
6005
- // NOTE: Can't use << here because javascript will convert to int and lose
6006
- // the upper bits.
6007
- now = Math.floor(now / 64);
6008
- }
6009
- assert(now === 0, 'Cannot push at time == 0');
6010
- let id = timeStampChars.join('');
6011
- if (!duplicateTime) {
6012
- for (i = 0; i < 12; i++) {
6013
- lastRandChars[i] = Math.floor(Math.random() * 64);
6014
- }
6015
- }
6016
- else {
6017
- // If the timestamp hasn't changed since last push, use the same random
6018
- // number, except incremented by 1.
6019
- for (i = 11; i >= 0 && lastRandChars[i] === 63; i--) {
6020
- lastRandChars[i] = 0;
6021
- }
6022
- lastRandChars[i]++;
6023
- }
6024
- for (i = 0; i < 12; i++) {
6025
- id += PUSH_CHARS.charAt(lastRandChars[i]);
6026
- }
6027
- assert(id.length === 20, 'nextPushId: Length should be 20.');
6028
- return id;
6029
- };
6030
- })();
6031
- const successor = function (key) {
6032
- if (key === '' + INTEGER_32_MAX) {
6033
- // See https://firebase.google.com/docs/database/web/lists-of-data#data-order
6034
- return MIN_PUSH_CHAR;
6035
- }
6036
- const keyAsInt = tryParseInt(key);
6037
- if (keyAsInt != null) {
6038
- return '' + (keyAsInt + 1);
6039
- }
6040
- const next = new Array(key.length);
6041
- for (let i = 0; i < next.length; i++) {
6042
- next[i] = key.charAt(i);
6043
- }
6044
- if (next.length < MAX_KEY_LEN) {
6045
- next.push(MIN_PUSH_CHAR);
6046
- return next.join('');
6047
- }
6048
- let i = next.length - 1;
6049
- while (i >= 0 && next[i] === MAX_PUSH_CHAR) {
6050
- i--;
6051
- }
6052
- // `successor` was called on the largest possible key, so return the
6053
- // MAX_NAME, which sorts larger than all keys.
6054
- if (i === -1) {
6055
- return MAX_NAME;
6056
- }
6057
- const source = next[i];
6058
- const sourcePlusOne = PUSH_CHARS.charAt(PUSH_CHARS.indexOf(source) + 1);
6059
- next[i] = sourcePlusOne;
6060
- return next.slice(0, i + 1).join('');
6061
- };
6062
- // `key` is assumed to be non-empty.
6063
- const predecessor = function (key) {
6064
- if (key === '' + INTEGER_32_MIN) {
6065
- return MIN_NAME;
6066
- }
6067
- const keyAsInt = tryParseInt(key);
6068
- if (keyAsInt != null) {
6069
- return '' + (keyAsInt - 1);
6070
- }
6071
- const next = new Array(key.length);
6072
- for (let i = 0; i < next.length; i++) {
6073
- next[i] = key.charAt(i);
6074
- }
6075
- // If `key` ends in `MIN_PUSH_CHAR`, the largest key lexicographically
6076
- // smaller than `key`, is `key[0:key.length - 1]`. The next key smaller
6077
- // than that, `predecessor(predecessor(key))`, is
6078
- //
6079
- // `key[0:key.length - 2] + (key[key.length - 1] - 1) + \
6080
- // { MAX_PUSH_CHAR repeated MAX_KEY_LEN - (key.length - 1) times }
6081
- //
6082
- // analogous to increment/decrement for base-10 integers.
6083
- //
6084
- // This works because lexigographic comparison works character-by-character,
6085
- // using length as a tie-breaker if one key is a prefix of the other.
6086
- if (next[next.length - 1] === MIN_PUSH_CHAR) {
6087
- if (next.length === 1) {
6088
- // See https://firebase.google.com/docs/database/web/lists-of-data#orderbykey
6089
- return '' + INTEGER_32_MAX;
6090
- }
6091
- delete next[next.length - 1];
6092
- return next.join('');
6093
- }
6094
- // Replace the last character with it's immediate predecessor, and
6095
- // fill the suffix of the key with MAX_PUSH_CHAR. This is the
6096
- // lexicographically largest possible key smaller than `key`.
6097
- next[next.length - 1] = PUSH_CHARS.charAt(PUSH_CHARS.indexOf(next[next.length - 1]) - 1);
6098
- return next.join('') + MAX_PUSH_CHAR.repeat(MAX_KEY_LEN - next.length);
6099
- };
6100
-
6101
5954
  /**
6102
5955
  * @license
6103
5956
  * Copyright 2017 Google LLC
@@ -6115,24 +5968,24 @@ const predecessor = function (key) {
6115
5968
  * limitations under the License.
6116
5969
  */
6117
5970
  function changeValue(snapshotNode) {
6118
- return { type: "value" /* VALUE */, snapshotNode };
5971
+ return { type: "value" /* ChangeType.VALUE */, snapshotNode };
6119
5972
  }
6120
5973
  function changeChildAdded(childName, snapshotNode) {
6121
- return { type: "child_added" /* CHILD_ADDED */, snapshotNode, childName };
5974
+ return { type: "child_added" /* ChangeType.CHILD_ADDED */, snapshotNode, childName };
6122
5975
  }
6123
5976
  function changeChildRemoved(childName, snapshotNode) {
6124
- return { type: "child_removed" /* CHILD_REMOVED */, snapshotNode, childName };
5977
+ return { type: "child_removed" /* ChangeType.CHILD_REMOVED */, snapshotNode, childName };
6125
5978
  }
6126
5979
  function changeChildChanged(childName, snapshotNode, oldSnap) {
6127
5980
  return {
6128
- type: "child_changed" /* CHILD_CHANGED */,
5981
+ type: "child_changed" /* ChangeType.CHILD_CHANGED */,
6129
5982
  snapshotNode,
6130
5983
  childName,
6131
5984
  oldSnap
6132
5985
  };
6133
5986
  }
6134
5987
  function changeChildMoved(childName, snapshotNode) {
6135
- return { type: "child_moved" /* CHILD_MOVED */, snapshotNode, childName };
5988
+ return { type: "child_moved" /* ChangeType.CHILD_MOVED */, snapshotNode, childName };
6136
5989
  }
6137
5990
 
6138
5991
  /**
@@ -6266,6 +6119,8 @@ class RangedFilter {
6266
6119
  this.index_ = params.getIndex();
6267
6120
  this.startPost_ = RangedFilter.getStartPost_(params);
6268
6121
  this.endPost_ = RangedFilter.getEndPost_(params);
6122
+ this.startIsInclusive_ = !params.startAfterSet_;
6123
+ this.endIsInclusive_ = !params.endBeforeSet_;
6269
6124
  }
6270
6125
  getStartPost() {
6271
6126
  return this.startPost_;
@@ -6274,8 +6129,13 @@ class RangedFilter {
6274
6129
  return this.endPost_;
6275
6130
  }
6276
6131
  matches(node) {
6277
- return (this.index_.compare(this.getStartPost(), node) <= 0 &&
6278
- this.index_.compare(node, this.getEndPost()) <= 0);
6132
+ const isWithinStart = this.startIsInclusive_
6133
+ ? this.index_.compare(this.getStartPost(), node) <= 0
6134
+ : this.index_.compare(this.getStartPost(), node) < 0;
6135
+ const isWithinEnd = this.endIsInclusive_
6136
+ ? this.index_.compare(node, this.getEndPost()) <= 0
6137
+ : this.index_.compare(node, this.getEndPost()) < 0;
6138
+ return isWithinStart && isWithinEnd;
6279
6139
  }
6280
6140
  updateChild(snap, key, newChild, affectedPath, source, optChangeAccumulator) {
6281
6141
  if (!this.matches(new NamedNode(key, newChild))) {
@@ -6353,10 +6213,22 @@ class RangedFilter {
6353
6213
  */
6354
6214
  class LimitedFilter {
6355
6215
  constructor(params) {
6216
+ this.withinDirectionalStart = (node) => this.reverse_ ? this.withinEndPost(node) : this.withinStartPost(node);
6217
+ this.withinDirectionalEnd = (node) => this.reverse_ ? this.withinStartPost(node) : this.withinEndPost(node);
6218
+ this.withinStartPost = (node) => {
6219
+ const compareRes = this.index_.compare(this.rangedFilter_.getStartPost(), node);
6220
+ return this.startIsInclusive_ ? compareRes <= 0 : compareRes < 0;
6221
+ };
6222
+ this.withinEndPost = (node) => {
6223
+ const compareRes = this.index_.compare(node, this.rangedFilter_.getEndPost());
6224
+ return this.endIsInclusive_ ? compareRes <= 0 : compareRes < 0;
6225
+ };
6356
6226
  this.rangedFilter_ = new RangedFilter(params);
6357
6227
  this.index_ = params.getIndex();
6358
6228
  this.limit_ = params.getLimit();
6359
6229
  this.reverse_ = !params.isViewFromLeft();
6230
+ this.startIsInclusive_ = !params.startAfterSet_;
6231
+ this.endIsInclusive_ = !params.endBeforeSet_;
6360
6232
  }
6361
6233
  updateChild(snap, key, newChild, affectedPath, source, optChangeAccumulator) {
6362
6234
  if (!this.rangedFilter_.matches(new NamedNode(key, newChild))) {
@@ -6397,23 +6269,18 @@ class LimitedFilter {
6397
6269
  let count = 0;
6398
6270
  while (iterator.hasNext() && count < this.limit_) {
6399
6271
  const next = iterator.getNext();
6400
- let inRange;
6401
- if (this.reverse_) {
6402
- inRange =
6403
- this.index_.compare(this.rangedFilter_.getStartPost(), next) <= 0;
6272
+ if (!this.withinDirectionalStart(next)) {
6273
+ // if we have not reached the start, skip to the next element
6274
+ continue;
6404
6275
  }
6405
- else {
6406
- inRange =
6407
- this.index_.compare(next, this.rangedFilter_.getEndPost()) <= 0;
6276
+ else if (!this.withinDirectionalEnd(next)) {
6277
+ // if we have reached the end, stop adding elements
6278
+ break;
6408
6279
  }
6409
- if (inRange) {
6280
+ else {
6410
6281
  filtered = filtered.updateImmediateChild(next.name, next.node);
6411
6282
  count++;
6412
6283
  }
6413
- else {
6414
- // if we have reached the end post, we cannot keep adding elemments
6415
- break;
6416
- }
6417
6284
  }
6418
6285
  }
6419
6286
  else {
@@ -6421,32 +6288,19 @@ class LimitedFilter {
6421
6288
  filtered = newSnap.withIndex(this.index_);
6422
6289
  // Don't support priorities on queries
6423
6290
  filtered = filtered.updatePriority(ChildrenNode.EMPTY_NODE);
6424
- let startPost;
6425
- let endPost;
6426
- let cmp;
6427
6291
  let iterator;
6428
6292
  if (this.reverse_) {
6429
6293
  iterator = filtered.getReverseIterator(this.index_);
6430
- startPost = this.rangedFilter_.getEndPost();
6431
- endPost = this.rangedFilter_.getStartPost();
6432
- const indexCompare = this.index_.getCompare();
6433
- cmp = (a, b) => indexCompare(b, a);
6434
6294
  }
6435
6295
  else {
6436
6296
  iterator = filtered.getIterator(this.index_);
6437
- startPost = this.rangedFilter_.getStartPost();
6438
- endPost = this.rangedFilter_.getEndPost();
6439
- cmp = this.index_.getCompare();
6440
6297
  }
6441
6298
  let count = 0;
6442
- let foundStartPost = false;
6443
6299
  while (iterator.hasNext()) {
6444
6300
  const next = iterator.getNext();
6445
- if (!foundStartPost && cmp(startPost, next) <= 0) {
6446
- // start adding
6447
- foundStartPost = true;
6448
- }
6449
- const inRange = foundStartPost && count < this.limit_ && cmp(next, endPost) <= 0;
6301
+ const inRange = count < this.limit_ &&
6302
+ this.withinDirectionalStart(next) &&
6303
+ this.withinDirectionalEnd(next);
6450
6304
  if (inRange) {
6451
6305
  count++;
6452
6306
  }
@@ -6577,10 +6431,10 @@ class QueryParams {
6577
6431
  this.limitSet_ = false;
6578
6432
  this.startSet_ = false;
6579
6433
  this.startNameSet_ = false;
6580
- this.startAfterSet_ = false;
6434
+ this.startAfterSet_ = false; // can only be true if startSet_ is true
6581
6435
  this.endSet_ = false;
6582
6436
  this.endNameSet_ = false;
6583
- this.endBeforeSet_ = false;
6437
+ this.endBeforeSet_ = false; // can only be true if endSet_ is true
6584
6438
  this.limit_ = 0;
6585
6439
  this.viewFrom_ = '';
6586
6440
  this.indexStartValue_ = null;
@@ -6592,12 +6446,6 @@ class QueryParams {
6592
6446
  hasStart() {
6593
6447
  return this.startSet_;
6594
6448
  }
6595
- hasStartAfter() {
6596
- return this.startAfterSet_;
6597
- }
6598
- hasEndBefore() {
6599
- return this.endBeforeSet_;
6600
- }
6601
6449
  /**
6602
6450
  * @returns True if it would return from left.
6603
6451
  */
@@ -6610,7 +6458,7 @@ class QueryParams {
6610
6458
  return this.startSet_;
6611
6459
  }
6612
6460
  else {
6613
- return this.viewFrom_ === "l" /* VIEW_FROM_LEFT */;
6461
+ return this.viewFrom_ === "l" /* WIRE_PROTOCOL_CONSTANTS.VIEW_FROM_LEFT */;
6614
6462
  }
6615
6463
  }
6616
6464
  /**
@@ -6686,10 +6534,12 @@ class QueryParams {
6686
6534
  copy.limitSet_ = this.limitSet_;
6687
6535
  copy.limit_ = this.limit_;
6688
6536
  copy.startSet_ = this.startSet_;
6537
+ copy.startAfterSet_ = this.startAfterSet_;
6689
6538
  copy.indexStartValue_ = this.indexStartValue_;
6690
6539
  copy.startNameSet_ = this.startNameSet_;
6691
6540
  copy.indexStartName_ = this.indexStartName_;
6692
6541
  copy.endSet_ = this.endSet_;
6542
+ copy.endBeforeSet_ = this.endBeforeSet_;
6693
6543
  copy.indexEndValue_ = this.indexEndValue_;
6694
6544
  copy.endNameSet_ = this.endNameSet_;
6695
6545
  copy.indexEndName_ = this.indexEndName_;
@@ -6713,14 +6563,14 @@ function queryParamsLimitToFirst(queryParams, newLimit) {
6713
6563
  const newParams = queryParams.copy();
6714
6564
  newParams.limitSet_ = true;
6715
6565
  newParams.limit_ = newLimit;
6716
- newParams.viewFrom_ = "l" /* VIEW_FROM_LEFT */;
6566
+ newParams.viewFrom_ = "l" /* WIRE_PROTOCOL_CONSTANTS.VIEW_FROM_LEFT */;
6717
6567
  return newParams;
6718
6568
  }
6719
6569
  function queryParamsLimitToLast(queryParams, newLimit) {
6720
6570
  const newParams = queryParams.copy();
6721
6571
  newParams.limitSet_ = true;
6722
6572
  newParams.limit_ = newLimit;
6723
- newParams.viewFrom_ = "r" /* VIEW_FROM_RIGHT */;
6573
+ newParams.viewFrom_ = "r" /* WIRE_PROTOCOL_CONSTANTS.VIEW_FROM_RIGHT */;
6724
6574
  return newParams;
6725
6575
  }
6726
6576
  function queryParamsStartAt(queryParams, indexValue, key) {
@@ -6742,21 +6592,11 @@ function queryParamsStartAt(queryParams, indexValue, key) {
6742
6592
  }
6743
6593
  function queryParamsStartAfter(queryParams, indexValue, key) {
6744
6594
  let params;
6745
- if (queryParams.index_ === KEY_INDEX) {
6746
- if (typeof indexValue === 'string') {
6747
- indexValue = successor(indexValue);
6748
- }
6595
+ if (queryParams.index_ === KEY_INDEX || !!key) {
6749
6596
  params = queryParamsStartAt(queryParams, indexValue, key);
6750
6597
  }
6751
6598
  else {
6752
- let childKey;
6753
- if (key == null) {
6754
- childKey = MAX_NAME;
6755
- }
6756
- else {
6757
- childKey = successor(key);
6758
- }
6759
- params = queryParamsStartAt(queryParams, indexValue, childKey);
6599
+ params = queryParamsStartAt(queryParams, indexValue, MAX_NAME);
6760
6600
  }
6761
6601
  params.startAfterSet_ = true;
6762
6602
  return params;
@@ -6779,22 +6619,12 @@ function queryParamsEndAt(queryParams, indexValue, key) {
6779
6619
  return newParams;
6780
6620
  }
6781
6621
  function queryParamsEndBefore(queryParams, indexValue, key) {
6782
- let childKey;
6783
6622
  let params;
6784
- if (queryParams.index_ === KEY_INDEX) {
6785
- if (typeof indexValue === 'string') {
6786
- indexValue = predecessor(indexValue);
6787
- }
6623
+ if (queryParams.index_ === KEY_INDEX || !!key) {
6788
6624
  params = queryParamsEndAt(queryParams, indexValue, key);
6789
6625
  }
6790
6626
  else {
6791
- if (key == null) {
6792
- childKey = MIN_NAME;
6793
- }
6794
- else {
6795
- childKey = predecessor(key);
6796
- }
6797
- params = queryParamsEndAt(queryParams, indexValue, childKey);
6627
+ params = queryParamsEndAt(queryParams, indexValue, MIN_NAME);
6798
6628
  }
6799
6629
  params.endBeforeSet_ = true;
6800
6630
  return params;
@@ -6816,39 +6646,43 @@ function queryParamsToRestQueryStringParameters(queryParams) {
6816
6646
  }
6817
6647
  let orderBy;
6818
6648
  if (queryParams.index_ === PRIORITY_INDEX) {
6819
- orderBy = "$priority" /* PRIORITY_INDEX */;
6649
+ orderBy = "$priority" /* REST_QUERY_CONSTANTS.PRIORITY_INDEX */;
6820
6650
  }
6821
6651
  else if (queryParams.index_ === VALUE_INDEX) {
6822
- orderBy = "$value" /* VALUE_INDEX */;
6652
+ orderBy = "$value" /* REST_QUERY_CONSTANTS.VALUE_INDEX */;
6823
6653
  }
6824
6654
  else if (queryParams.index_ === KEY_INDEX) {
6825
- orderBy = "$key" /* KEY_INDEX */;
6655
+ orderBy = "$key" /* REST_QUERY_CONSTANTS.KEY_INDEX */;
6826
6656
  }
6827
6657
  else {
6828
6658
  assert(queryParams.index_ instanceof PathIndex, 'Unrecognized index type!');
6829
6659
  orderBy = queryParams.index_.toString();
6830
6660
  }
6831
- qs["orderBy" /* ORDER_BY */] = stringify(orderBy);
6661
+ qs["orderBy" /* REST_QUERY_CONSTANTS.ORDER_BY */] = stringify(orderBy);
6832
6662
  if (queryParams.startSet_) {
6833
- qs["startAt" /* START_AT */] = stringify(queryParams.indexStartValue_);
6663
+ const startParam = queryParams.startAfterSet_
6664
+ ? "startAfter" /* REST_QUERY_CONSTANTS.START_AFTER */
6665
+ : "startAt" /* REST_QUERY_CONSTANTS.START_AT */;
6666
+ qs[startParam] = stringify(queryParams.indexStartValue_);
6834
6667
  if (queryParams.startNameSet_) {
6835
- qs["startAt" /* START_AT */] +=
6836
- ',' + stringify(queryParams.indexStartName_);
6668
+ qs[startParam] += ',' + stringify(queryParams.indexStartName_);
6837
6669
  }
6838
6670
  }
6839
6671
  if (queryParams.endSet_) {
6840
- qs["endAt" /* END_AT */] = stringify(queryParams.indexEndValue_);
6672
+ const endParam = queryParams.endBeforeSet_
6673
+ ? "endBefore" /* REST_QUERY_CONSTANTS.END_BEFORE */
6674
+ : "endAt" /* REST_QUERY_CONSTANTS.END_AT */;
6675
+ qs[endParam] = stringify(queryParams.indexEndValue_);
6841
6676
  if (queryParams.endNameSet_) {
6842
- qs["endAt" /* END_AT */] +=
6843
- ',' + stringify(queryParams.indexEndName_);
6677
+ qs[endParam] += ',' + stringify(queryParams.indexEndName_);
6844
6678
  }
6845
6679
  }
6846
6680
  if (queryParams.limitSet_) {
6847
6681
  if (queryParams.isViewFromLeft()) {
6848
- qs["limitToFirst" /* LIMIT_TO_FIRST */] = queryParams.limit_;
6682
+ qs["limitToFirst" /* REST_QUERY_CONSTANTS.LIMIT_TO_FIRST */] = queryParams.limit_;
6849
6683
  }
6850
6684
  else {
6851
- qs["limitToLast" /* LIMIT_TO_LAST */] = queryParams.limit_;
6685
+ qs["limitToLast" /* REST_QUERY_CONSTANTS.LIMIT_TO_LAST */] = queryParams.limit_;
6852
6686
  }
6853
6687
  }
6854
6688
  return qs;
@@ -6856,35 +6690,39 @@ function queryParamsToRestQueryStringParameters(queryParams) {
6856
6690
  function queryParamsGetQueryObject(queryParams) {
6857
6691
  const obj = {};
6858
6692
  if (queryParams.startSet_) {
6859
- obj["sp" /* INDEX_START_VALUE */] =
6693
+ obj["sp" /* WIRE_PROTOCOL_CONSTANTS.INDEX_START_VALUE */] =
6860
6694
  queryParams.indexStartValue_;
6861
6695
  if (queryParams.startNameSet_) {
6862
- obj["sn" /* INDEX_START_NAME */] =
6696
+ obj["sn" /* WIRE_PROTOCOL_CONSTANTS.INDEX_START_NAME */] =
6863
6697
  queryParams.indexStartName_;
6864
6698
  }
6699
+ obj["sin" /* WIRE_PROTOCOL_CONSTANTS.INDEX_START_IS_INCLUSIVE */] =
6700
+ !queryParams.startAfterSet_;
6865
6701
  }
6866
6702
  if (queryParams.endSet_) {
6867
- obj["ep" /* INDEX_END_VALUE */] = queryParams.indexEndValue_;
6703
+ obj["ep" /* WIRE_PROTOCOL_CONSTANTS.INDEX_END_VALUE */] = queryParams.indexEndValue_;
6868
6704
  if (queryParams.endNameSet_) {
6869
- obj["en" /* INDEX_END_NAME */] = queryParams.indexEndName_;
6705
+ obj["en" /* WIRE_PROTOCOL_CONSTANTS.INDEX_END_NAME */] = queryParams.indexEndName_;
6870
6706
  }
6707
+ obj["ein" /* WIRE_PROTOCOL_CONSTANTS.INDEX_END_IS_INCLUSIVE */] =
6708
+ !queryParams.endBeforeSet_;
6871
6709
  }
6872
6710
  if (queryParams.limitSet_) {
6873
- obj["l" /* LIMIT */] = queryParams.limit_;
6711
+ obj["l" /* WIRE_PROTOCOL_CONSTANTS.LIMIT */] = queryParams.limit_;
6874
6712
  let viewFrom = queryParams.viewFrom_;
6875
6713
  if (viewFrom === '') {
6876
6714
  if (queryParams.isViewFromLeft()) {
6877
- viewFrom = "l" /* VIEW_FROM_LEFT */;
6715
+ viewFrom = "l" /* WIRE_PROTOCOL_CONSTANTS.VIEW_FROM_LEFT */;
6878
6716
  }
6879
6717
  else {
6880
- viewFrom = "r" /* VIEW_FROM_RIGHT */;
6718
+ viewFrom = "r" /* WIRE_PROTOCOL_CONSTANTS.VIEW_FROM_RIGHT */;
6881
6719
  }
6882
6720
  }
6883
- obj["vf" /* VIEW_FROM */] = viewFrom;
6721
+ obj["vf" /* WIRE_PROTOCOL_CONSTANTS.VIEW_FROM */] = viewFrom;
6884
6722
  }
6885
6723
  // For now, priority index is the default, so we only specify if it's some other index
6886
6724
  if (queryParams.index_ !== PRIORITY_INDEX) {
6887
- obj["i" /* INDEX */] = queryParams.index_.toString();
6725
+ obj["i" /* WIRE_PROTOCOL_CONSTANTS.INDEX */] = queryParams.index_.toString();
6888
6726
  }
6889
6727
  return obj;
6890
6728
  }
@@ -7628,16 +7466,16 @@ function eventGeneratorGenerateEventsForChanges(eventGenerator, changes, eventCa
7628
7466
  const events = [];
7629
7467
  const moves = [];
7630
7468
  changes.forEach(change => {
7631
- if (change.type === "child_changed" /* CHILD_CHANGED */ &&
7469
+ if (change.type === "child_changed" /* ChangeType.CHILD_CHANGED */ &&
7632
7470
  eventGenerator.index_.indexedValueChanged(change.oldSnap, change.snapshotNode)) {
7633
7471
  moves.push(changeChildMoved(change.childName, change.snapshotNode));
7634
7472
  }
7635
7473
  });
7636
- eventGeneratorGenerateEventsForType(eventGenerator, events, "child_removed" /* CHILD_REMOVED */, changes, eventRegistrations, eventCache);
7637
- eventGeneratorGenerateEventsForType(eventGenerator, events, "child_added" /* CHILD_ADDED */, changes, eventRegistrations, eventCache);
7638
- eventGeneratorGenerateEventsForType(eventGenerator, events, "child_moved" /* CHILD_MOVED */, moves, eventRegistrations, eventCache);
7639
- eventGeneratorGenerateEventsForType(eventGenerator, events, "child_changed" /* CHILD_CHANGED */, changes, eventRegistrations, eventCache);
7640
- eventGeneratorGenerateEventsForType(eventGenerator, events, "value" /* VALUE */, changes, eventRegistrations, eventCache);
7474
+ eventGeneratorGenerateEventsForType(eventGenerator, events, "child_removed" /* ChangeType.CHILD_REMOVED */, changes, eventRegistrations, eventCache);
7475
+ eventGeneratorGenerateEventsForType(eventGenerator, events, "child_added" /* ChangeType.CHILD_ADDED */, changes, eventRegistrations, eventCache);
7476
+ eventGeneratorGenerateEventsForType(eventGenerator, events, "child_moved" /* ChangeType.CHILD_MOVED */, moves, eventRegistrations, eventCache);
7477
+ eventGeneratorGenerateEventsForType(eventGenerator, events, "child_changed" /* ChangeType.CHILD_CHANGED */, changes, eventRegistrations, eventCache);
7478
+ eventGeneratorGenerateEventsForType(eventGenerator, events, "value" /* ChangeType.VALUE */, changes, eventRegistrations, eventCache);
7641
7479
  return events;
7642
7480
  }
7643
7481
  /**
@@ -8718,31 +8556,31 @@ class ChildChangeAccumulator {
8718
8556
  trackChildChange(change) {
8719
8557
  const type = change.type;
8720
8558
  const childKey = change.childName;
8721
- assert(type === "child_added" /* CHILD_ADDED */ ||
8722
- type === "child_changed" /* CHILD_CHANGED */ ||
8723
- type === "child_removed" /* CHILD_REMOVED */, 'Only child changes supported for tracking');
8559
+ assert(type === "child_added" /* ChangeType.CHILD_ADDED */ ||
8560
+ type === "child_changed" /* ChangeType.CHILD_CHANGED */ ||
8561
+ type === "child_removed" /* ChangeType.CHILD_REMOVED */, 'Only child changes supported for tracking');
8724
8562
  assert(childKey !== '.priority', 'Only non-priority child changes can be tracked.');
8725
8563
  const oldChange = this.changeMap.get(childKey);
8726
8564
  if (oldChange) {
8727
8565
  const oldType = oldChange.type;
8728
- if (type === "child_added" /* CHILD_ADDED */ &&
8729
- oldType === "child_removed" /* CHILD_REMOVED */) {
8566
+ if (type === "child_added" /* ChangeType.CHILD_ADDED */ &&
8567
+ oldType === "child_removed" /* ChangeType.CHILD_REMOVED */) {
8730
8568
  this.changeMap.set(childKey, changeChildChanged(childKey, change.snapshotNode, oldChange.snapshotNode));
8731
8569
  }
8732
- else if (type === "child_removed" /* CHILD_REMOVED */ &&
8733
- oldType === "child_added" /* CHILD_ADDED */) {
8570
+ else if (type === "child_removed" /* ChangeType.CHILD_REMOVED */ &&
8571
+ oldType === "child_added" /* ChangeType.CHILD_ADDED */) {
8734
8572
  this.changeMap.delete(childKey);
8735
8573
  }
8736
- else if (type === "child_removed" /* CHILD_REMOVED */ &&
8737
- oldType === "child_changed" /* CHILD_CHANGED */) {
8574
+ else if (type === "child_removed" /* ChangeType.CHILD_REMOVED */ &&
8575
+ oldType === "child_changed" /* ChangeType.CHILD_CHANGED */) {
8738
8576
  this.changeMap.set(childKey, changeChildRemoved(childKey, oldChange.oldSnap));
8739
8577
  }
8740
- else if (type === "child_changed" /* CHILD_CHANGED */ &&
8741
- oldType === "child_added" /* CHILD_ADDED */) {
8578
+ else if (type === "child_changed" /* ChangeType.CHILD_CHANGED */ &&
8579
+ oldType === "child_added" /* ChangeType.CHILD_ADDED */) {
8742
8580
  this.changeMap.set(childKey, changeChildAdded(childKey, change.snapshotNode));
8743
8581
  }
8744
- else if (type === "child_changed" /* CHILD_CHANGED */ &&
8745
- oldType === "child_changed" /* CHILD_CHANGED */) {
8582
+ else if (type === "child_changed" /* ChangeType.CHILD_CHANGED */ &&
8583
+ oldType === "child_changed" /* ChangeType.CHILD_CHANGED */) {
8746
8584
  this.changeMap.set(childKey, changeChildChanged(childKey, change.snapshotNode, oldChange.oldSnap));
8747
8585
  }
8748
8586
  else {
@@ -11452,7 +11290,7 @@ function repoStartTransaction(repo, path, transactionUpdate, onComplete, unwatch
11452
11290
  else {
11453
11291
  validateFirebaseData('transaction failed: Data returned ', newVal, transaction.path);
11454
11292
  // Mark as run and add to our queue.
11455
- transaction.status = 0 /* RUN */;
11293
+ transaction.status = 0 /* TransactionStatus.RUN */;
11456
11294
  const queueNode = treeSubTree(repo.transactionQueueTree_, path);
11457
11295
  const nodeQueue = treeGetValue(queueNode) || [];
11458
11296
  nodeQueue.push(transaction);
@@ -11510,7 +11348,7 @@ function repoSendReadyTransactions(repo, node = repo.transactionQueueTree_) {
11510
11348
  if (treeGetValue(node)) {
11511
11349
  const queue = repoBuildTransactionQueue(repo, node);
11512
11350
  assert(queue.length > 0, 'Sending zero length transaction queue');
11513
- const allRun = queue.every((transaction) => transaction.status === 0 /* RUN */);
11351
+ const allRun = queue.every((transaction) => transaction.status === 0 /* TransactionStatus.RUN */);
11514
11352
  // If they're all run (and not sent), we can send them. Else, we must wait.
11515
11353
  if (allRun) {
11516
11354
  repoSendTransactionQueue(repo, treeGetPath(node), queue);
@@ -11539,8 +11377,8 @@ function repoSendTransactionQueue(repo, path, queue) {
11539
11377
  const latestHash = latestState.hash();
11540
11378
  for (let i = 0; i < queue.length; i++) {
11541
11379
  const txn = queue[i];
11542
- assert(txn.status === 0 /* RUN */, 'tryToSendTransactionQueue_: items in queue should all be run.');
11543
- txn.status = 1 /* SENT */;
11380
+ assert(txn.status === 0 /* TransactionStatus.RUN */, 'tryToSendTransactionQueue_: items in queue should all be run.');
11381
+ txn.status = 1 /* TransactionStatus.SENT */;
11544
11382
  txn.retryCount++;
11545
11383
  const relativePath = newRelativePath(path, txn.path);
11546
11384
  // If we've gotten to this point, the output snapshot must be defined.
@@ -11561,7 +11399,7 @@ function repoSendTransactionQueue(repo, path, queue) {
11561
11399
  // transactions or sets.
11562
11400
  const callbacks = [];
11563
11401
  for (let i = 0; i < queue.length; i++) {
11564
- queue[i].status = 2 /* COMPLETED */;
11402
+ queue[i].status = 2 /* TransactionStatus.COMPLETED */;
11565
11403
  events = events.concat(syncTreeAckUserWrite(repo.serverSyncTree_, queue[i].currentWriteId));
11566
11404
  if (queue[i].onComplete) {
11567
11405
  // We never unset the output snapshot, and given that this
@@ -11584,18 +11422,18 @@ function repoSendTransactionQueue(repo, path, queue) {
11584
11422
  // transactions are no longer sent. Update their status appropriately.
11585
11423
  if (status === 'datastale') {
11586
11424
  for (let i = 0; i < queue.length; i++) {
11587
- if (queue[i].status === 3 /* SENT_NEEDS_ABORT */) {
11588
- queue[i].status = 4 /* NEEDS_ABORT */;
11425
+ if (queue[i].status === 3 /* TransactionStatus.SENT_NEEDS_ABORT */) {
11426
+ queue[i].status = 4 /* TransactionStatus.NEEDS_ABORT */;
11589
11427
  }
11590
11428
  else {
11591
- queue[i].status = 0 /* RUN */;
11429
+ queue[i].status = 0 /* TransactionStatus.RUN */;
11592
11430
  }
11593
11431
  }
11594
11432
  }
11595
11433
  else {
11596
11434
  warn('transaction at ' + pathToSend.toString() + ' failed: ' + status);
11597
11435
  for (let i = 0; i < queue.length; i++) {
11598
- queue[i].status = 4 /* NEEDS_ABORT */;
11436
+ queue[i].status = 4 /* TransactionStatus.NEEDS_ABORT */;
11599
11437
  queue[i].abortReason = status;
11600
11438
  }
11601
11439
  }
@@ -11639,7 +11477,7 @@ function repoRerunTransactionQueue(repo, queue, path) {
11639
11477
  let events = [];
11640
11478
  // Ignore all of the sets we're going to re-run.
11641
11479
  const txnsToRerun = queue.filter(q => {
11642
- return q.status === 0 /* RUN */;
11480
+ return q.status === 0 /* TransactionStatus.RUN */;
11643
11481
  });
11644
11482
  const setsToIgnore = txnsToRerun.map(q => {
11645
11483
  return q.currentWriteId;
@@ -11649,12 +11487,12 @@ function repoRerunTransactionQueue(repo, queue, path) {
11649
11487
  const relativePath = newRelativePath(path, transaction.path);
11650
11488
  let abortTransaction = false, abortReason;
11651
11489
  assert(relativePath !== null, 'rerunTransactionsUnderNode_: relativePath should not be null.');
11652
- if (transaction.status === 4 /* NEEDS_ABORT */) {
11490
+ if (transaction.status === 4 /* TransactionStatus.NEEDS_ABORT */) {
11653
11491
  abortTransaction = true;
11654
11492
  abortReason = transaction.abortReason;
11655
11493
  events = events.concat(syncTreeAckUserWrite(repo.serverSyncTree_, transaction.currentWriteId, true));
11656
11494
  }
11657
- else if (transaction.status === 0 /* RUN */) {
11495
+ else if (transaction.status === 0 /* TransactionStatus.RUN */) {
11658
11496
  if (transaction.retryCount >= MAX_TRANSACTION_RETRIES) {
11659
11497
  abortTransaction = true;
11660
11498
  abortReason = 'maxretry';
@@ -11697,7 +11535,7 @@ function repoRerunTransactionQueue(repo, queue, path) {
11697
11535
  events = [];
11698
11536
  if (abortTransaction) {
11699
11537
  // Abort.
11700
- queue[i].status = 2 /* COMPLETED */;
11538
+ queue[i].status = 2 /* TransactionStatus.COMPLETED */;
11701
11539
  // Removing a listener can trigger pruning which can muck with
11702
11540
  // mergedData/visibleData (as it prunes data). So defer the unwatcher
11703
11541
  // until we're done.
@@ -11778,7 +11616,7 @@ function repoPruneCompletedTransactionsBelowNode(repo, node) {
11778
11616
  if (queue) {
11779
11617
  let to = 0;
11780
11618
  for (let from = 0; from < queue.length; from++) {
11781
- if (queue[from].status !== 2 /* COMPLETED */) {
11619
+ if (queue[from].status !== 2 /* TransactionStatus.COMPLETED */) {
11782
11620
  queue[to] = queue[from];
11783
11621
  to++;
11784
11622
  }
@@ -11826,16 +11664,16 @@ function repoAbortTransactionsOnNode(repo, node) {
11826
11664
  let events = [];
11827
11665
  let lastSent = -1;
11828
11666
  for (let i = 0; i < queue.length; i++) {
11829
- if (queue[i].status === 3 /* SENT_NEEDS_ABORT */) ;
11830
- else if (queue[i].status === 1 /* SENT */) {
11667
+ if (queue[i].status === 3 /* TransactionStatus.SENT_NEEDS_ABORT */) ;
11668
+ else if (queue[i].status === 1 /* TransactionStatus.SENT */) {
11831
11669
  assert(lastSent === i - 1, 'All SENT items should be at beginning of queue.');
11832
11670
  lastSent = i;
11833
11671
  // Mark transaction for abort when it comes back.
11834
- queue[i].status = 3 /* SENT_NEEDS_ABORT */;
11672
+ queue[i].status = 3 /* TransactionStatus.SENT_NEEDS_ABORT */;
11835
11673
  queue[i].abortReason = 'set';
11836
11674
  }
11837
11675
  else {
11838
- assert(queue[i].status === 0 /* RUN */, 'Unexpected transaction status in abort');
11676
+ assert(queue[i].status === 0 /* TransactionStatus.RUN */, 'Unexpected transaction status in abort');
11839
11677
  // We can abort it immediately.
11840
11678
  queue[i].unwatcher();
11841
11679
  events = events.concat(syncTreeAckUserWrite(repo.serverSyncTree_, queue[i].currentWriteId, true));
@@ -12005,6 +11843,81 @@ const parseDatabaseURL = function (dataURL) {
12005
11843
  };
12006
11844
  };
12007
11845
 
11846
+ /**
11847
+ * @license
11848
+ * Copyright 2017 Google LLC
11849
+ *
11850
+ * Licensed under the Apache License, Version 2.0 (the "License");
11851
+ * you may not use this file except in compliance with the License.
11852
+ * You may obtain a copy of the License at
11853
+ *
11854
+ * http://www.apache.org/licenses/LICENSE-2.0
11855
+ *
11856
+ * Unless required by applicable law or agreed to in writing, software
11857
+ * distributed under the License is distributed on an "AS IS" BASIS,
11858
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11859
+ * See the License for the specific language governing permissions and
11860
+ * limitations under the License.
11861
+ */
11862
+ // Modeled after base64 web-safe chars, but ordered by ASCII.
11863
+ const PUSH_CHARS = '-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz';
11864
+ /**
11865
+ * Fancy ID generator that creates 20-character string identifiers with the
11866
+ * following properties:
11867
+ *
11868
+ * 1. They're based on timestamp so that they sort *after* any existing ids.
11869
+ * 2. They contain 72-bits of random data after the timestamp so that IDs won't
11870
+ * collide with other clients' IDs.
11871
+ * 3. They sort *lexicographically* (so the timestamp is converted to characters
11872
+ * that will sort properly).
11873
+ * 4. They're monotonically increasing. Even if you generate more than one in
11874
+ * the same timestamp, the latter ones will sort after the former ones. We do
11875
+ * this by using the previous random bits but "incrementing" them by 1 (only
11876
+ * in the case of a timestamp collision).
11877
+ */
11878
+ const nextPushId = (function () {
11879
+ // Timestamp of last push, used to prevent local collisions if you push twice
11880
+ // in one ms.
11881
+ let lastPushTime = 0;
11882
+ // We generate 72-bits of randomness which get turned into 12 characters and
11883
+ // appended to the timestamp to prevent collisions with other clients. We
11884
+ // store the last characters we generated because in the event of a collision,
11885
+ // we'll use those same characters except "incremented" by one.
11886
+ const lastRandChars = [];
11887
+ return function (now) {
11888
+ const duplicateTime = now === lastPushTime;
11889
+ lastPushTime = now;
11890
+ let i;
11891
+ const timeStampChars = new Array(8);
11892
+ for (i = 7; i >= 0; i--) {
11893
+ timeStampChars[i] = PUSH_CHARS.charAt(now % 64);
11894
+ // NOTE: Can't use << here because javascript will convert to int and lose
11895
+ // the upper bits.
11896
+ now = Math.floor(now / 64);
11897
+ }
11898
+ assert(now === 0, 'Cannot push at time == 0');
11899
+ let id = timeStampChars.join('');
11900
+ if (!duplicateTime) {
11901
+ for (i = 0; i < 12; i++) {
11902
+ lastRandChars[i] = Math.floor(Math.random() * 64);
11903
+ }
11904
+ }
11905
+ else {
11906
+ // If the timestamp hasn't changed since last push, use the same random
11907
+ // number, except incremented by 1.
11908
+ for (i = 11; i >= 0 && lastRandChars[i] === 63; i--) {
11909
+ lastRandChars[i] = 0;
11910
+ }
11911
+ lastRandChars[i]++;
11912
+ }
11913
+ for (i = 0; i < 12; i++) {
11914
+ id += PUSH_CHARS.charAt(lastRandChars[i]);
11915
+ }
11916
+ assert(id.length === 20, 'nextPushId: Length should be 20.');
11917
+ return id;
11918
+ };
11919
+ })();
11920
+
12008
11921
  /**
12009
11922
  * @license
12010
11923
  * Copyright 2017 Google LLC
@@ -13813,7 +13726,7 @@ function registerDatabase(variant) {
13813
13726
  const authProvider = container.getProvider('auth-internal');
13814
13727
  const appCheckProvider = container.getProvider('app-check-internal');
13815
13728
  return repoManagerDatabaseFromApp(app, authProvider, appCheckProvider, url);
13816
- }, "PUBLIC" /* PUBLIC */).setMultipleInstances(true));
13729
+ }, "PUBLIC" /* ComponentType.PUBLIC */).setMultipleInstances(true));
13817
13730
  registerVersion(name, version, variant);
13818
13731
  // BUILD_TARGET will be replaced by values like esm5, esm2017, cjs5, etc during the compilation
13819
13732
  registerVersion(name, version, 'esm2017');