@firebase/database 0.13.9 → 0.13.10-canary.09dfc3aac

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.
@@ -1298,7 +1298,7 @@ var WebSocketConnection = /** @class */ (function () {
1298
1298
  }());
1299
1299
 
1300
1300
  var name = "@firebase/database";
1301
- var version = "0.13.9";
1301
+ var version = "0.13.10-canary.09dfc3aac";
1302
1302
 
1303
1303
  /**
1304
1304
  * @license
@@ -6178,153 +6178,6 @@ var ValueIndex = /** @class */ (function (_super) {
6178
6178
  }(Index));
6179
6179
  var VALUE_INDEX = new ValueIndex();
6180
6180
 
6181
- /**
6182
- * @license
6183
- * Copyright 2017 Google LLC
6184
- *
6185
- * Licensed under the Apache License, Version 2.0 (the "License");
6186
- * you may not use this file except in compliance with the License.
6187
- * You may obtain a copy of the License at
6188
- *
6189
- * http://www.apache.org/licenses/LICENSE-2.0
6190
- *
6191
- * Unless required by applicable law or agreed to in writing, software
6192
- * distributed under the License is distributed on an "AS IS" BASIS,
6193
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6194
- * See the License for the specific language governing permissions and
6195
- * limitations under the License.
6196
- */
6197
- // Modeled after base64 web-safe chars, but ordered by ASCII.
6198
- var PUSH_CHARS = '-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz';
6199
- var MIN_PUSH_CHAR = '-';
6200
- var MAX_PUSH_CHAR = 'z';
6201
- var MAX_KEY_LEN = 786;
6202
- /**
6203
- * Fancy ID generator that creates 20-character string identifiers with the
6204
- * following properties:
6205
- *
6206
- * 1. They're based on timestamp so that they sort *after* any existing ids.
6207
- * 2. They contain 72-bits of random data after the timestamp so that IDs won't
6208
- * collide with other clients' IDs.
6209
- * 3. They sort *lexicographically* (so the timestamp is converted to characters
6210
- * that will sort properly).
6211
- * 4. They're monotonically increasing. Even if you generate more than one in
6212
- * the same timestamp, the latter ones will sort after the former ones. We do
6213
- * this by using the previous random bits but "incrementing" them by 1 (only
6214
- * in the case of a timestamp collision).
6215
- */
6216
- var nextPushId = (function () {
6217
- // Timestamp of last push, used to prevent local collisions if you push twice
6218
- // in one ms.
6219
- var lastPushTime = 0;
6220
- // We generate 72-bits of randomness which get turned into 12 characters and
6221
- // appended to the timestamp to prevent collisions with other clients. We
6222
- // store the last characters we generated because in the event of a collision,
6223
- // we'll use those same characters except "incremented" by one.
6224
- var lastRandChars = [];
6225
- return function (now) {
6226
- var duplicateTime = now === lastPushTime;
6227
- lastPushTime = now;
6228
- var i;
6229
- var timeStampChars = new Array(8);
6230
- for (i = 7; i >= 0; i--) {
6231
- timeStampChars[i] = PUSH_CHARS.charAt(now % 64);
6232
- // NOTE: Can't use << here because javascript will convert to int and lose
6233
- // the upper bits.
6234
- now = Math.floor(now / 64);
6235
- }
6236
- util.assert(now === 0, 'Cannot push at time == 0');
6237
- var id = timeStampChars.join('');
6238
- if (!duplicateTime) {
6239
- for (i = 0; i < 12; i++) {
6240
- lastRandChars[i] = Math.floor(Math.random() * 64);
6241
- }
6242
- }
6243
- else {
6244
- // If the timestamp hasn't changed since last push, use the same random
6245
- // number, except incremented by 1.
6246
- for (i = 11; i >= 0 && lastRandChars[i] === 63; i--) {
6247
- lastRandChars[i] = 0;
6248
- }
6249
- lastRandChars[i]++;
6250
- }
6251
- for (i = 0; i < 12; i++) {
6252
- id += PUSH_CHARS.charAt(lastRandChars[i]);
6253
- }
6254
- util.assert(id.length === 20, 'nextPushId: Length should be 20.');
6255
- return id;
6256
- };
6257
- })();
6258
- var successor = function (key) {
6259
- if (key === '' + INTEGER_32_MAX) {
6260
- // See https://firebase.google.com/docs/database/web/lists-of-data#data-order
6261
- return MIN_PUSH_CHAR;
6262
- }
6263
- var keyAsInt = tryParseInt(key);
6264
- if (keyAsInt != null) {
6265
- return '' + (keyAsInt + 1);
6266
- }
6267
- var next = new Array(key.length);
6268
- for (var i_1 = 0; i_1 < next.length; i_1++) {
6269
- next[i_1] = key.charAt(i_1);
6270
- }
6271
- if (next.length < MAX_KEY_LEN) {
6272
- next.push(MIN_PUSH_CHAR);
6273
- return next.join('');
6274
- }
6275
- var i = next.length - 1;
6276
- while (i >= 0 && next[i] === MAX_PUSH_CHAR) {
6277
- i--;
6278
- }
6279
- // `successor` was called on the largest possible key, so return the
6280
- // MAX_NAME, which sorts larger than all keys.
6281
- if (i === -1) {
6282
- return MAX_NAME;
6283
- }
6284
- var source = next[i];
6285
- var sourcePlusOne = PUSH_CHARS.charAt(PUSH_CHARS.indexOf(source) + 1);
6286
- next[i] = sourcePlusOne;
6287
- return next.slice(0, i + 1).join('');
6288
- };
6289
- // `key` is assumed to be non-empty.
6290
- var predecessor = function (key) {
6291
- if (key === '' + INTEGER_32_MIN) {
6292
- return MIN_NAME;
6293
- }
6294
- var keyAsInt = tryParseInt(key);
6295
- if (keyAsInt != null) {
6296
- return '' + (keyAsInt - 1);
6297
- }
6298
- var next = new Array(key.length);
6299
- for (var i = 0; i < next.length; i++) {
6300
- next[i] = key.charAt(i);
6301
- }
6302
- // If `key` ends in `MIN_PUSH_CHAR`, the largest key lexicographically
6303
- // smaller than `key`, is `key[0:key.length - 1]`. The next key smaller
6304
- // than that, `predecessor(predecessor(key))`, is
6305
- //
6306
- // `key[0:key.length - 2] + (key[key.length - 1] - 1) + \
6307
- // { MAX_PUSH_CHAR repeated MAX_KEY_LEN - (key.length - 1) times }
6308
- //
6309
- // analogous to increment/decrement for base-10 integers.
6310
- //
6311
- // This works because lexigographic comparison works character-by-character,
6312
- // using length as a tie-breaker if one key is a prefix of the other.
6313
- if (next[next.length - 1] === MIN_PUSH_CHAR) {
6314
- if (next.length === 1) {
6315
- // See https://firebase.google.com/docs/database/web/lists-of-data#orderbykey
6316
- return '' + INTEGER_32_MAX;
6317
- }
6318
- delete next[next.length - 1];
6319
- return next.join('');
6320
- }
6321
- // Replace the last character with it's immediate predecessor, and
6322
- // fill the suffix of the key with MAX_PUSH_CHAR. This is the
6323
- // lexicographically largest possible key smaller than `key`.
6324
- next[next.length - 1] = PUSH_CHARS.charAt(PUSH_CHARS.indexOf(next[next.length - 1]) - 1);
6325
- return next.join('') + MAX_PUSH_CHAR.repeat(MAX_KEY_LEN - next.length);
6326
- };
6327
-
6328
6181
  /**
6329
6182
  * @license
6330
6183
  * Copyright 2017 Google LLC
@@ -6494,6 +6347,8 @@ var RangedFilter = /** @class */ (function () {
6494
6347
  this.index_ = params.getIndex();
6495
6348
  this.startPost_ = RangedFilter.getStartPost_(params);
6496
6349
  this.endPost_ = RangedFilter.getEndPost_(params);
6350
+ this.startIsInclusive_ = !params.startAfterSet_;
6351
+ this.endIsInclusive_ = !params.endBeforeSet_;
6497
6352
  }
6498
6353
  RangedFilter.prototype.getStartPost = function () {
6499
6354
  return this.startPost_;
@@ -6502,8 +6357,13 @@ var RangedFilter = /** @class */ (function () {
6502
6357
  return this.endPost_;
6503
6358
  };
6504
6359
  RangedFilter.prototype.matches = function (node) {
6505
- return (this.index_.compare(this.getStartPost(), node) <= 0 &&
6506
- this.index_.compare(node, this.getEndPost()) <= 0);
6360
+ var isWithinStart = this.startIsInclusive_
6361
+ ? this.index_.compare(this.getStartPost(), node) <= 0
6362
+ : this.index_.compare(this.getStartPost(), node) < 0;
6363
+ var isWithinEnd = this.endIsInclusive_
6364
+ ? this.index_.compare(node, this.getEndPost()) <= 0
6365
+ : this.index_.compare(node, this.getEndPost()) < 0;
6366
+ return isWithinStart && isWithinEnd;
6507
6367
  };
6508
6368
  RangedFilter.prototype.updateChild = function (snap, key, newChild, affectedPath, source, optChangeAccumulator) {
6509
6369
  if (!this.matches(new NamedNode(key, newChild))) {
@@ -6582,10 +6442,27 @@ var RangedFilter = /** @class */ (function () {
6582
6442
  */
6583
6443
  var LimitedFilter = /** @class */ (function () {
6584
6444
  function LimitedFilter(params) {
6445
+ var _this = this;
6446
+ this.withinDirectionalStart = function (node) {
6447
+ return _this.reverse_ ? _this.withinEndPost(node) : _this.withinStartPost(node);
6448
+ };
6449
+ this.withinDirectionalEnd = function (node) {
6450
+ return _this.reverse_ ? _this.withinStartPost(node) : _this.withinEndPost(node);
6451
+ };
6452
+ this.withinStartPost = function (node) {
6453
+ var compareRes = _this.index_.compare(_this.rangedFilter_.getStartPost(), node);
6454
+ return _this.startIsInclusive_ ? compareRes <= 0 : compareRes < 0;
6455
+ };
6456
+ this.withinEndPost = function (node) {
6457
+ var compareRes = _this.index_.compare(node, _this.rangedFilter_.getEndPost());
6458
+ return _this.endIsInclusive_ ? compareRes <= 0 : compareRes < 0;
6459
+ };
6585
6460
  this.rangedFilter_ = new RangedFilter(params);
6586
6461
  this.index_ = params.getIndex();
6587
6462
  this.limit_ = params.getLimit();
6588
6463
  this.reverse_ = !params.isViewFromLeft();
6464
+ this.startIsInclusive_ = !params.startAfterSet_;
6465
+ this.endIsInclusive_ = !params.endBeforeSet_;
6589
6466
  }
6590
6467
  LimitedFilter.prototype.updateChild = function (snap, key, newChild, affectedPath, source, optChangeAccumulator) {
6591
6468
  if (!this.rangedFilter_.matches(new NamedNode(key, newChild))) {
@@ -6626,23 +6503,18 @@ var LimitedFilter = /** @class */ (function () {
6626
6503
  var count = 0;
6627
6504
  while (iterator.hasNext() && count < this.limit_) {
6628
6505
  var next = iterator.getNext();
6629
- var inRange = void 0;
6630
- if (this.reverse_) {
6631
- inRange =
6632
- this.index_.compare(this.rangedFilter_.getStartPost(), next) <= 0;
6506
+ if (!this.withinDirectionalStart(next)) {
6507
+ // if we have not reached the start, skip to the next element
6508
+ continue;
6633
6509
  }
6634
- else {
6635
- inRange =
6636
- this.index_.compare(next, this.rangedFilter_.getEndPost()) <= 0;
6510
+ else if (!this.withinDirectionalEnd(next)) {
6511
+ // if we have reached the end, stop adding elements
6512
+ break;
6637
6513
  }
6638
- if (inRange) {
6514
+ else {
6639
6515
  filtered = filtered.updateImmediateChild(next.name, next.node);
6640
6516
  count++;
6641
6517
  }
6642
- else {
6643
- // if we have reached the end post, we cannot keep adding elemments
6644
- break;
6645
- }
6646
6518
  }
6647
6519
  }
6648
6520
  else {
@@ -6650,32 +6522,19 @@ var LimitedFilter = /** @class */ (function () {
6650
6522
  filtered = newSnap.withIndex(this.index_);
6651
6523
  // Don't support priorities on queries
6652
6524
  filtered = filtered.updatePriority(ChildrenNode.EMPTY_NODE);
6653
- var startPost = void 0;
6654
- var endPost = void 0;
6655
- var cmp = void 0;
6656
6525
  var iterator = void 0;
6657
6526
  if (this.reverse_) {
6658
6527
  iterator = filtered.getReverseIterator(this.index_);
6659
- startPost = this.rangedFilter_.getEndPost();
6660
- endPost = this.rangedFilter_.getStartPost();
6661
- var indexCompare_1 = this.index_.getCompare();
6662
- cmp = function (a, b) { return indexCompare_1(b, a); };
6663
6528
  }
6664
6529
  else {
6665
6530
  iterator = filtered.getIterator(this.index_);
6666
- startPost = this.rangedFilter_.getStartPost();
6667
- endPost = this.rangedFilter_.getEndPost();
6668
- cmp = this.index_.getCompare();
6669
6531
  }
6670
6532
  var count = 0;
6671
- var foundStartPost = false;
6672
6533
  while (iterator.hasNext()) {
6673
6534
  var next = iterator.getNext();
6674
- if (!foundStartPost && cmp(startPost, next) <= 0) {
6675
- // start adding
6676
- foundStartPost = true;
6677
- }
6678
- var inRange = foundStartPost && count < this.limit_ && cmp(next, endPost) <= 0;
6535
+ var inRange = count < this.limit_ &&
6536
+ this.withinDirectionalStart(next) &&
6537
+ this.withinDirectionalEnd(next);
6679
6538
  if (inRange) {
6680
6539
  count++;
6681
6540
  }
@@ -6807,10 +6666,10 @@ var QueryParams = /** @class */ (function () {
6807
6666
  this.limitSet_ = false;
6808
6667
  this.startSet_ = false;
6809
6668
  this.startNameSet_ = false;
6810
- this.startAfterSet_ = false;
6669
+ this.startAfterSet_ = false; // can only be true if startSet_ is true
6811
6670
  this.endSet_ = false;
6812
6671
  this.endNameSet_ = false;
6813
- this.endBeforeSet_ = false;
6672
+ this.endBeforeSet_ = false; // can only be true if endSet_ is true
6814
6673
  this.limit_ = 0;
6815
6674
  this.viewFrom_ = '';
6816
6675
  this.indexStartValue_ = null;
@@ -6822,12 +6681,6 @@ var QueryParams = /** @class */ (function () {
6822
6681
  QueryParams.prototype.hasStart = function () {
6823
6682
  return this.startSet_;
6824
6683
  };
6825
- QueryParams.prototype.hasStartAfter = function () {
6826
- return this.startAfterSet_;
6827
- };
6828
- QueryParams.prototype.hasEndBefore = function () {
6829
- return this.endBeforeSet_;
6830
- };
6831
6684
  /**
6832
6685
  * @returns True if it would return from left.
6833
6686
  */
@@ -6916,10 +6769,12 @@ var QueryParams = /** @class */ (function () {
6916
6769
  copy.limitSet_ = this.limitSet_;
6917
6770
  copy.limit_ = this.limit_;
6918
6771
  copy.startSet_ = this.startSet_;
6772
+ copy.startAfterSet_ = this.startAfterSet_;
6919
6773
  copy.indexStartValue_ = this.indexStartValue_;
6920
6774
  copy.startNameSet_ = this.startNameSet_;
6921
6775
  copy.indexStartName_ = this.indexStartName_;
6922
6776
  copy.endSet_ = this.endSet_;
6777
+ copy.endBeforeSet_ = this.endBeforeSet_;
6923
6778
  copy.indexEndValue_ = this.indexEndValue_;
6924
6779
  copy.endNameSet_ = this.endNameSet_;
6925
6780
  copy.indexEndName_ = this.indexEndName_;
@@ -6973,21 +6828,11 @@ function queryParamsStartAt(queryParams, indexValue, key) {
6973
6828
  }
6974
6829
  function queryParamsStartAfter(queryParams, indexValue, key) {
6975
6830
  var params;
6976
- if (queryParams.index_ === KEY_INDEX) {
6977
- if (typeof indexValue === 'string') {
6978
- indexValue = successor(indexValue);
6979
- }
6831
+ if (queryParams.index_ === KEY_INDEX || !!key) {
6980
6832
  params = queryParamsStartAt(queryParams, indexValue, key);
6981
6833
  }
6982
6834
  else {
6983
- var childKey = void 0;
6984
- if (key == null) {
6985
- childKey = MAX_NAME;
6986
- }
6987
- else {
6988
- childKey = successor(key);
6989
- }
6990
- params = queryParamsStartAt(queryParams, indexValue, childKey);
6835
+ params = queryParamsStartAt(queryParams, indexValue, MAX_NAME);
6991
6836
  }
6992
6837
  params.startAfterSet_ = true;
6993
6838
  return params;
@@ -7010,22 +6855,12 @@ function queryParamsEndAt(queryParams, indexValue, key) {
7010
6855
  return newParams;
7011
6856
  }
7012
6857
  function queryParamsEndBefore(queryParams, indexValue, key) {
7013
- var childKey;
7014
6858
  var params;
7015
- if (queryParams.index_ === KEY_INDEX) {
7016
- if (typeof indexValue === 'string') {
7017
- indexValue = predecessor(indexValue);
7018
- }
6859
+ if (queryParams.index_ === KEY_INDEX || !!key) {
7019
6860
  params = queryParamsEndAt(queryParams, indexValue, key);
7020
6861
  }
7021
6862
  else {
7022
- if (key == null) {
7023
- childKey = MIN_NAME;
7024
- }
7025
- else {
7026
- childKey = predecessor(key);
7027
- }
7028
- params = queryParamsEndAt(queryParams, indexValue, childKey);
6863
+ params = queryParamsEndAt(queryParams, indexValue, MIN_NAME);
7029
6864
  }
7030
6865
  params.endBeforeSet_ = true;
7031
6866
  return params;
@@ -7061,17 +6896,21 @@ function queryParamsToRestQueryStringParameters(queryParams) {
7061
6896
  }
7062
6897
  qs["orderBy" /* ORDER_BY */] = util.stringify(orderBy);
7063
6898
  if (queryParams.startSet_) {
7064
- qs["startAt" /* START_AT */] = util.stringify(queryParams.indexStartValue_);
6899
+ var startParam = queryParams.startAfterSet_
6900
+ ? "startAfter" /* START_AFTER */
6901
+ : "startAt" /* START_AT */;
6902
+ qs[startParam] = util.stringify(queryParams.indexStartValue_);
7065
6903
  if (queryParams.startNameSet_) {
7066
- qs["startAt" /* START_AT */] +=
7067
- ',' + util.stringify(queryParams.indexStartName_);
6904
+ qs[startParam] += ',' + util.stringify(queryParams.indexStartName_);
7068
6905
  }
7069
6906
  }
7070
6907
  if (queryParams.endSet_) {
7071
- qs["endAt" /* END_AT */] = util.stringify(queryParams.indexEndValue_);
6908
+ var endParam = queryParams.endBeforeSet_
6909
+ ? "endBefore" /* END_BEFORE */
6910
+ : "endAt" /* END_AT */;
6911
+ qs[endParam] = util.stringify(queryParams.indexEndValue_);
7072
6912
  if (queryParams.endNameSet_) {
7073
- qs["endAt" /* END_AT */] +=
7074
- ',' + util.stringify(queryParams.indexEndName_);
6913
+ qs[endParam] += ',' + util.stringify(queryParams.indexEndName_);
7075
6914
  }
7076
6915
  }
7077
6916
  if (queryParams.limitSet_) {
@@ -7093,12 +6932,16 @@ function queryParamsGetQueryObject(queryParams) {
7093
6932
  obj["sn" /* INDEX_START_NAME */] =
7094
6933
  queryParams.indexStartName_;
7095
6934
  }
6935
+ obj["sin" /* INDEX_START_IS_INCLUSIVE */] =
6936
+ !queryParams.startAfterSet_;
7096
6937
  }
7097
6938
  if (queryParams.endSet_) {
7098
6939
  obj["ep" /* INDEX_END_VALUE */] = queryParams.indexEndValue_;
7099
6940
  if (queryParams.endNameSet_) {
7100
6941
  obj["en" /* INDEX_END_NAME */] = queryParams.indexEndName_;
7101
6942
  }
6943
+ obj["ein" /* INDEX_END_IS_INCLUSIVE */] =
6944
+ !queryParams.endBeforeSet_;
7102
6945
  }
7103
6946
  if (queryParams.limitSet_) {
7104
6947
  obj["l" /* LIMIT */] = queryParams.limit_;
@@ -12372,6 +12215,81 @@ var parseDatabaseURL = function (dataURL) {
12372
12215
  };
12373
12216
  };
12374
12217
 
12218
+ /**
12219
+ * @license
12220
+ * Copyright 2017 Google LLC
12221
+ *
12222
+ * Licensed under the Apache License, Version 2.0 (the "License");
12223
+ * you may not use this file except in compliance with the License.
12224
+ * You may obtain a copy of the License at
12225
+ *
12226
+ * http://www.apache.org/licenses/LICENSE-2.0
12227
+ *
12228
+ * Unless required by applicable law or agreed to in writing, software
12229
+ * distributed under the License is distributed on an "AS IS" BASIS,
12230
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12231
+ * See the License for the specific language governing permissions and
12232
+ * limitations under the License.
12233
+ */
12234
+ // Modeled after base64 web-safe chars, but ordered by ASCII.
12235
+ var PUSH_CHARS = '-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz';
12236
+ /**
12237
+ * Fancy ID generator that creates 20-character string identifiers with the
12238
+ * following properties:
12239
+ *
12240
+ * 1. They're based on timestamp so that they sort *after* any existing ids.
12241
+ * 2. They contain 72-bits of random data after the timestamp so that IDs won't
12242
+ * collide with other clients' IDs.
12243
+ * 3. They sort *lexicographically* (so the timestamp is converted to characters
12244
+ * that will sort properly).
12245
+ * 4. They're monotonically increasing. Even if you generate more than one in
12246
+ * the same timestamp, the latter ones will sort after the former ones. We do
12247
+ * this by using the previous random bits but "incrementing" them by 1 (only
12248
+ * in the case of a timestamp collision).
12249
+ */
12250
+ var nextPushId = (function () {
12251
+ // Timestamp of last push, used to prevent local collisions if you push twice
12252
+ // in one ms.
12253
+ var lastPushTime = 0;
12254
+ // We generate 72-bits of randomness which get turned into 12 characters and
12255
+ // appended to the timestamp to prevent collisions with other clients. We
12256
+ // store the last characters we generated because in the event of a collision,
12257
+ // we'll use those same characters except "incremented" by one.
12258
+ var lastRandChars = [];
12259
+ return function (now) {
12260
+ var duplicateTime = now === lastPushTime;
12261
+ lastPushTime = now;
12262
+ var i;
12263
+ var timeStampChars = new Array(8);
12264
+ for (i = 7; i >= 0; i--) {
12265
+ timeStampChars[i] = PUSH_CHARS.charAt(now % 64);
12266
+ // NOTE: Can't use << here because javascript will convert to int and lose
12267
+ // the upper bits.
12268
+ now = Math.floor(now / 64);
12269
+ }
12270
+ util.assert(now === 0, 'Cannot push at time == 0');
12271
+ var id = timeStampChars.join('');
12272
+ if (!duplicateTime) {
12273
+ for (i = 0; i < 12; i++) {
12274
+ lastRandChars[i] = Math.floor(Math.random() * 64);
12275
+ }
12276
+ }
12277
+ else {
12278
+ // If the timestamp hasn't changed since last push, use the same random
12279
+ // number, except incremented by 1.
12280
+ for (i = 11; i >= 0 && lastRandChars[i] === 63; i--) {
12281
+ lastRandChars[i] = 0;
12282
+ }
12283
+ lastRandChars[i]++;
12284
+ }
12285
+ for (i = 0; i < 12; i++) {
12286
+ id += PUSH_CHARS.charAt(lastRandChars[i]);
12287
+ }
12288
+ util.assert(id.length === 20, 'nextPushId: Length should be 20.');
12289
+ return id;
12290
+ };
12291
+ })();
12292
+
12375
12293
  /**
12376
12294
  * @license
12377
12295
  * Copyright 2017 Google LLC