@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
package/dist/index.esm2017.js
CHANGED
|
@@ -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.
|
|
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
|
-
|
|
6278
|
-
this.index_.compare(
|
|
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
|
-
|
|
6401
|
-
|
|
6402
|
-
|
|
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
|
-
|
|
6407
|
-
|
|
6276
|
+
else if (!this.withinDirectionalEnd(next)) {
|
|
6277
|
+
// if we have reached the end, stop adding elements
|
|
6278
|
+
break;
|
|
6408
6279
|
}
|
|
6409
|
-
|
|
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
|
-
|
|
6446
|
-
|
|
6447
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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[
|
|
6836
|
-
',' + stringify(queryParams.indexStartName_);
|
|
6668
|
+
qs[startParam] += ',' + stringify(queryParams.indexStartName_);
|
|
6837
6669
|
}
|
|
6838
6670
|
}
|
|
6839
6671
|
if (queryParams.endSet_) {
|
|
6840
|
-
|
|
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[
|
|
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');
|