Skip to content

Commit 963b75c

Browse files
committed
WIP: fix .priority not defined issue
This took way to long to fix.
1 parent ce93196 commit 963b75c

22 files changed

+149
-68
lines changed

karma.conf.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ module.exports = {
5454

5555
// karma-typescript config
5656
karmaTypescriptConfig: {
57-
tsconfig: `./tsconfig.test.json`
57+
tsconfig: `./tsconfig.test.json`,
58+
coverageOptions: {
59+
instrumentation: false
60+
}
5861
}
5962
}

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
"chai": "^3.5.0",
4141
"child-process-promise": "^2.2.1",
4242
"circular-dependency-plugin": "^3.0.0",
43+
"cross-env": "^5.0.1",
4344
"cz-customizable": "^5.0.0",
4445
"filesize": "^3.5.6",
4546
"git-rev-sync": "^1.9.0",

src/database/api/Query.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,25 @@ import {
1515
import { errorPrefix, validateArgCount, validateCallback, validateContextObject } from "../../utils/validation";
1616
import { ValueEventRegistration, ChildEventRegistration } from "../core/view/EventRegistration";
1717
import { Deferred, attachDummyErrorHandler } from "../../utils/promise";
18-
import { Reference } from "./Reference";
1918
import { Repo } from "../core/Repo";
2019
import { QueryParams } from "../core/view/QueryParams";
2120

21+
let __referenceConstructor: new(repo: Repo, path: Path) => Query;
22+
2223
/**
2324
* A Query represents a filter to be applied to a firebase location. This object purely represents the
2425
* query expression (and exposes our public API to build the query). The actual query logic is in ViewBase.js.
2526
*
2627
* Since every Firebase reference is a query, Firebase inherits from this object.
2728
*/
2829
export class Query {
29-
30+
static set __referenceConstructor(val) {
31+
__referenceConstructor = val;
32+
}
33+
static get __referenceConstructor() {
34+
assert(__referenceConstructor, 'Reference.ts has not been loaded');
35+
return __referenceConstructor;
36+
}
3037
constructor(public repo: Repo, public path: Path, private queryParams_: QueryParams, private orderByCalled_: boolean) {}
3138

3239
/**
@@ -122,7 +129,7 @@ export class Query {
122129
// This is a slight hack. We cannot goog.require('fb.api.Firebase'), since Firebase requires fb.api.Query.
123130
// However, we will always export 'Firebase' to the global namespace, so it's guaranteed to exist by the time this
124131
// method gets called.
125-
return new Reference(this.repo, this.path);
132+
return new Query.__referenceConstructor(this.repo, this.path);
126133
}
127134

128135
/**

src/database/api/Reference.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {
2020
validateCallback,
2121
} from "../../utils/validation";
2222
import { Deferred, attachDummyErrorHandler, PromiseImpl } from "../../utils/promise";
23+
import { SyncPoint } from "../core/SyncPoint";
2324

2425
export class Reference extends Query {
2526
public then;
@@ -294,12 +295,11 @@ export class Reference extends Query {
294295
}
295296
}
296297

297-
Object.defineProperty(Query.prototype, 'getRef', {
298-
value: function() {
299-
validateArgCount('Query.ref', 0, 0, arguments.length);
300-
// This is a slight hack. We cannot goog.require('Firebase'), since Firebase requires Query.
301-
// However, we will always export 'Firebase' to the global namespace, so it's guaranteed to exist by the time this
302-
// method gets called.
303-
return new Reference(this.repo, this.path);
304-
}
305-
});
298+
/**
299+
* Define reference constructor in various modules
300+
*
301+
* We are doing this here to avoid several circular
302+
* dependency issues
303+
*/
304+
Query.__referenceConstructor = Reference;
305+
SyncPoint.__referenceConstructor = Reference;

src/database/core/Repo.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ export class Repo {
3737
statsReporter_;
3838
transactions_init_;
3939
infoData_;
40-
infoSyncTree_;
40+
infoSyncTree_: SyncTree;
4141
onDisconnect_;
4242
abortTransactions_;
4343
rerunTransactions_;
@@ -46,7 +46,7 @@ export class Repo {
4646
database;
4747
dataUpdateCount;
4848
interceptServerDataCallback_;
49-
serverSyncTree_;
49+
serverSyncTree_: SyncTree;
5050

5151
/**
5252
* @param {!RepoInfo} repoInfo

src/database/core/SyncPoint.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
import { Reference } from "../api/Reference";
21
import { CacheNode } from "./view/CacheNode";
32
import { ChildrenNode } from "./snap/ChildrenNode";
43
import { assert } from "../../utils/assert";
54
import { isEmpty, forEach, findValue } from "../../utils/obj";
65
import { ViewCache } from "./view/ViewCache";
76
import { View } from "./view/View";
87

8+
let __referenceConstructor;
9+
910
/**
1011
* SyncPoint represents a single location in a SyncTree with 1 or more event registrations, meaning we need to
1112
* maintain 1 or more Views at this location to cache server data and raise appropriate events for server changes
@@ -15,10 +16,17 @@ import { View } from "./view/View";
1516
* - Maintaining the set of 1 or more views necessary at this location (a SyncPoint with 0 views should be removed).
1617
* - Proxying user / server operations to the views as appropriate (i.e. applyServerOverwrite,
1718
* applyUserOverwrite, etc.)
18-
*
19-
* @constructor
2019
*/
2120
export class SyncPoint {
21+
static set __referenceConstructor(val) {
22+
assert(!__referenceConstructor, '__referenceConstructor has already been defined');
23+
__referenceConstructor = val;
24+
}
25+
static get __referenceConstructor() {
26+
assert(__referenceConstructor, 'Reference.ts has not been loaded');
27+
return __referenceConstructor;
28+
}
29+
2230
views_: object;
2331
constructor() {
2432
/**
@@ -73,8 +81,7 @@ export class SyncPoint {
7381
* @param {boolean} serverCacheComplete
7482
* @return {!Array.<!Event>} Events to raise.
7583
*/
76-
addEventRegistration(query, eventRegistration, writesCache, serverCache,
77-
serverCacheComplete) {
84+
addEventRegistration(query, eventRegistration, writesCache, serverCache, serverCacheComplete) {
7885
var queryId = query.queryIdentifier();
7986
var view = this.views_[queryId];
8087
if (!view) {
@@ -151,7 +158,7 @@ export class SyncPoint {
151158

152159
if (hadCompleteView && !this.hasCompleteView()) {
153160
// We removed our last complete view.
154-
removed.push(new Reference(query.repo, query.path));
161+
removed.push(new SyncPoint.__referenceConstructor(query.repo, query.path));
155162
}
156163

157164
return {removed: removed, events: cancelEvents};

src/database/core/SyncTree.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ export class SyncTree {
322322
* @param {Error=} cancelError If a cancelError is provided, appropriate cancel events will be returned.
323323
* @return {!Array.<!Event>} Cancel events, if cancelError was provided.
324324
*/
325-
removeEventRegistration(query, eventRegistration, cancelError) {
325+
removeEventRegistration(query, eventRegistration, cancelError?) {
326326
// Find the syncPoint first. Then deal with whether or not it has matching listeners
327327
var path = query.path;
328328
var maybeSyncPoint = this.syncPointTree_.get(path);

src/database/core/WriteTree.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ export class WriteTree {
5757
* @param {!Path} path
5858
* @return {!WriteTreeRef}
5959
*/
60-
childWrites(path) {
60+
childWrites(path): WriteTreeRef {
6161
return new WriteTreeRef(path, this);
6262
};
6363

src/database/core/snap/ChildrenNode.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,14 @@ import { Node, NamedNode } from "./Node";
99
import {
1010
validatePriorityNode,
1111
priorityHashText,
12+
setMaxNode
1213
} from "./snap";
13-
import { PRIORITY_INDEX } from "./indexes/PriorityIndex";
14-
import { KEY_INDEX } from "./indexes/KeyIndex";
14+
import { PRIORITY_INDEX, setMaxNode as setPriorityMaxNode } from "./indexes/PriorityIndex";
15+
import { KEY_INDEX, KeyIndex } from "./indexes/KeyIndex";
1516
import { IndexMap } from "./IndexMap";
17+
import { LeafNode } from "./LeafNode";
1618
import { NAME_COMPARATOR } from "./comparators";
19+
import "./indexes/Index";
1720

1821
// TODO: For memory savings, don't store priorityNode_ if it's empty.
1922

@@ -525,4 +528,12 @@ Object.defineProperties(NamedNode, {
525528
MAX: {
526529
value: new NamedNode(MAX_NAME, MAX_NODE)
527530
}
528-
});
531+
});
532+
533+
/**
534+
* Reference Extensions
535+
*/
536+
KeyIndex.__EMPTY_NODE = ChildrenNode.EMPTY_NODE;
537+
LeafNode.__childrenNodeConstructor = ChildrenNode;
538+
setMaxNode(MAX_NODE);
539+
setPriorityMaxNode(MAX_NODE);

src/database/core/snap/IndexMap.ts

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ import { contains, clone, map } from "../../../utils/obj";
44
import { NamedNode } from "./Node";
55
import { PRIORITY_INDEX } from "./indexes/PriorityIndex";
66
import { KEY_INDEX } from "./indexes/KeyIndex";
7-
import { Fallback } from "./indexes/Index";
7+
let _defaultIndexMap;
8+
9+
const fallbackObject = {};
810

911
/**
1012
*
@@ -21,7 +23,14 @@ export class IndexMap {
2123
* @type {!IndexMap}
2224
* @const
2325
*/
24-
static Default = new IndexMap(Fallback, PRIORITY_INDEX);
26+
static get Default() {
27+
assert(fallbackObject && PRIORITY_INDEX, 'ChildrenNode.ts has not been loaded');
28+
_defaultIndexMap = _defaultIndexMap || new IndexMap(
29+
{ '.priority': fallbackObject },
30+
{ '.priority': PRIORITY_INDEX }
31+
);
32+
return _defaultIndexMap;
33+
}
2534

2635
constructor(indexes, indexSet) {
2736
this.indexes_ = indexes;
@@ -36,7 +45,7 @@ export class IndexMap {
3645
var sortedMap = this.indexes_[indexKey];
3746
if (!sortedMap) throw new Error('No index defined for ' + indexKey);
3847

39-
if (sortedMap === Fallback) {
48+
if (sortedMap === fallbackObject) {
4049
// The index exists, but it falls back to just name comparison. Return null so that the calling code uses the
4150
// regular child map
4251
return null;
@@ -74,7 +83,7 @@ export class IndexMap {
7483
if (sawIndexedValue) {
7584
newIndex = buildChildSet(childList, indexDefinition.getCompare());
7685
} else {
77-
newIndex = Fallback;
86+
newIndex = fallbackObject;
7887
}
7988
var indexName = indexDefinition.toString();
8089
var newIndexSet = clone(this.indexSet_);
@@ -96,7 +105,7 @@ export class IndexMap {
96105
var newIndexes = map(this.indexes_, function(indexedChildren, indexName) {
97106
var index = self.indexSet_[indexName];
98107
assert(index, 'Missing index implementation for ' + indexName);
99-
if (indexedChildren === Fallback) {
108+
if (indexedChildren === fallbackObject) {
100109
// Check to see if we need to index everything
101110
if (index.isDefinedOn(namedNode.node)) {
102111
// We need to build this index
@@ -113,7 +122,7 @@ export class IndexMap {
113122
return buildChildSet(childList, index.getCompare());
114123
} else {
115124
// No change, this remains a fallback
116-
return Fallback;
125+
return fallbackObject;
117126
}
118127
} else {
119128
var existingSnap = existingChildren.get(namedNode.name);
@@ -135,7 +144,7 @@ export class IndexMap {
135144
*/
136145
removeFromIndexes(namedNode, existingChildren) {
137146
var newIndexes = map(this.indexes_, function(indexedChildren) {
138-
if (indexedChildren === Fallback) {
147+
if (indexedChildren === fallbackObject) {
139148
// This is the fallback. Just return it, nothing to do in this case
140149
return indexedChildren;
141150
} else {

src/database/core/snap/LeafNode.ts

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,23 @@ import {
77
priorityHashText,
88
validatePriorityNode
99
} from "./snap";
10-
import { ChildrenNode } from "./ChildrenNode";
1110
import { Node } from "./Node";
1211

12+
let __childrenNodeConstructor;
1313

1414
/**
1515
* LeafNode is a class for storing leaf nodes in a DataSnapshot. It
1616
* implements Node and stores the value of the node (a string,
1717
* number, or boolean) accessible via getValue().
1818
*/
1919
export class LeafNode implements Node {
20+
static set __childrenNodeConstructor(val) {
21+
__childrenNodeConstructor = val;
22+
}
23+
static get __childrenNodeConstructor() {
24+
return __childrenNodeConstructor;
25+
}
26+
2027
value_;
2128
priorityNode_;
2229
lazyHash_;
@@ -41,7 +48,7 @@ export class LeafNode implements Node {
4148
* @const
4249
* @type {!Node}
4350
*/
44-
this.priorityNode_ = opt_priorityNode || ChildrenNode.EMPTY_NODE;
51+
this.priorityNode_ = opt_priorityNode || LeafNode.__childrenNodeConstructor.EMPTY_NODE;
4552
validatePriorityNode(this.priorityNode_);
4653

4754
this.lazyHash_ = null;
@@ -78,7 +85,7 @@ export class LeafNode implements Node {
7885
if (childName === '.priority') {
7986
return this.priorityNode_;
8087
} else {
81-
return ChildrenNode.EMPTY_NODE;
88+
return LeafNode.__childrenNodeConstructor.EMPTY_NODE;
8289
}
8390
}
8491

@@ -89,7 +96,7 @@ export class LeafNode implements Node {
8996
} else if (path.getFront() === '.priority') {
9097
return this.priorityNode_;
9198
} else {
92-
return ChildrenNode.EMPTY_NODE;
99+
return LeafNode.__childrenNodeConstructor.EMPTY_NODE;
93100
}
94101
}
95102

@@ -112,7 +119,7 @@ export class LeafNode implements Node {
112119
} else if (newChildNode.isEmpty() && childName !== '.priority') {
113120
return this;
114121
} else {
115-
return ChildrenNode.EMPTY_NODE
122+
return LeafNode.__childrenNodeConstructor.EMPTY_NODE
116123
.updateImmediateChild(childName, newChildNode)
117124
.updatePriority(this.priorityNode_);
118125
}
@@ -129,7 +136,7 @@ export class LeafNode implements Node {
129136
assert(front !== '.priority' || path.getLength() === 1,
130137
'.priority must be the last token in a path');
131138

132-
return this.updateImmediateChild(front, ChildrenNode.EMPTY_NODE.updateChild(path.popFront(), newChildNode));
139+
return this.updateImmediateChild(front, LeafNode.__childrenNodeConstructor.EMPTY_NODE.updateChild(path.popFront(), newChildNode));
133140
}
134141
}
135142

@@ -190,9 +197,9 @@ export class LeafNode implements Node {
190197
* @inheritDoc
191198
*/
192199
compareTo(other) {
193-
if (other === ChildrenNode.EMPTY_NODE) {
200+
if (other === LeafNode.__childrenNodeConstructor.EMPTY_NODE) {
194201
return 1;
195-
} else if (other instanceof ChildrenNode) {
202+
} else if (other instanceof LeafNode.__childrenNodeConstructor) {
196203
return -1;
197204
} else {
198205
assert(other.isLeafNode(), 'Unknown node type');

src/database/core/snap/Node.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Path } from "../util/path";
1+
import { Path } from "../util/Path";
22
import { Index } from "./indexes/Index";
33

44
/**

src/database/core/snap/indexes/Index.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,6 @@ import { MIN_NAME, MAX_NAME } from "../../util/util";
66
* @constructor
77
*/
88
export abstract class Index {
9-
/**
10-
* @typedef {!Object}
11-
*/
12-
static FallbackType;
13-
149
/**
1510
* @param {!NamedNode} a
1611
* @param {!NamedNode} b
@@ -76,5 +71,3 @@ export abstract class Index {
7671
*/
7772
abstract toString(): string;
7873
};
79-
80-
export const Fallback = {};

0 commit comments

Comments
 (0)