@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.
- package/CHANGELOG.md +16 -0
- package/dist/index.esm2017.js +201 -288
- package/dist/index.esm2017.js.map +1 -1
- package/dist/index.esm5.js +225 -307
- package/dist/index.esm5.js.map +1 -1
- package/dist/index.node.cjs.js +225 -307
- package/dist/index.node.cjs.js.map +1 -1
- package/dist/index.standalone.js +222 -304
- package/dist/index.standalone.js.map +1 -1
- package/dist/internal.d.ts +0 -2
- package/dist/node-esm/index.node.esm.js +201 -288
- package/dist/node-esm/index.node.esm.js.map +1 -1
- package/dist/node-esm/src/core/view/QueryParams.d.ts +0 -2
- package/dist/node-esm/src/core/view/filter/LimitedFilter.d.ts +6 -0
- package/dist/node-esm/src/core/view/filter/RangedFilter.d.ts +2 -0
- package/dist/src/core/view/QueryParams.d.ts +0 -2
- package/dist/src/core/view/filter/LimitedFilter.d.ts +6 -0
- package/dist/src/core/view/filter/RangedFilter.d.ts +2 -0
- package/package.json +7 -7
|
@@ -1250,7 +1250,7 @@ WebSocketConnection.responsesRequiredToBeHealthy = 2;
|
|
|
1250
1250
|
WebSocketConnection.healthyTimeout = 30000;
|
|
1251
1251
|
|
|
1252
1252
|
const name = "@firebase/database";
|
|
1253
|
-
const version = "0.
|
|
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
|
-
|
|
6282
|
-
this.index_.compare(
|
|
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
|
-
|
|
6405
|
-
|
|
6406
|
-
|
|
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
|
-
|
|
6411
|
-
|
|
6280
|
+
else if (!this.withinDirectionalEnd(next)) {
|
|
6281
|
+
// if we have reached the end, stop adding elements
|
|
6282
|
+
break;
|
|
6412
6283
|
}
|
|
6413
|
-
|
|
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
|
-
|
|
6450
|
-
|
|
6451
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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[
|
|
6840
|
-
',' + stringify(queryParams.indexStartName_);
|
|
6672
|
+
qs[startParam] += ',' + stringify(queryParams.indexStartName_);
|
|
6841
6673
|
}
|
|
6842
6674
|
}
|
|
6843
6675
|
if (queryParams.endSet_) {
|
|
6844
|
-
|
|
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[
|
|
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');
|