1
0
mirror of https://github.com/musix-org/musix-oss synced 2026-05-05 10:06:35 +00:00
This commit is contained in:
MatteZ02
2019-10-10 16:43:04 +03:00
parent 6f6ac8a6fa
commit 50b9bed483
9432 changed files with 1988816 additions and 167 deletions
+15127
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
+44
View File
@@ -0,0 +1,44 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { FirebaseNamespace } from '@firebase/app-types';
import { Database } from './src/api/Database';
import { Query } from './src/api/Query';
import { Reference } from './src/api/Reference';
import { enableLogging } from './src/core/util/util';
import * as types from '@firebase/database-types';
declare const ServerValue: {
TIMESTAMP: {
'.sv': string;
};
};
export declare function registerDatabase(instance: FirebaseNamespace): void;
export { Database, Query, Reference, enableLogging, ServerValue };
export { DataSnapshot } from './src/api/DataSnapshot';
export { OnDisconnect } from './src/api/onDisconnect';
declare module '@firebase/app-types' {
interface FirebaseNamespace {
database?: {
(app?: FirebaseApp): types.FirebaseDatabase;
enableLogging: typeof types.enableLogging;
ServerValue: types.ServerValue;
Database: typeof types.FirebaseDatabase;
};
}
interface FirebaseApp {
database?(databaseURL?: string): types.FirebaseDatabase;
}
}
+15114
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
+89
View File
@@ -0,0 +1,89 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { FirebaseNamespace, FirebaseApp } from '@firebase/app-types';
import { Database } from './src/api/Database';
import { DataSnapshot } from './src/api/DataSnapshot';
import { Query } from './src/api/Query';
import { Reference } from './src/api/Reference';
import { enableLogging } from './src/core/util/util';
import * as INTERNAL from './src/api/internal';
import * as TEST_ACCESS from './src/api/test_access';
import './src/nodePatches';
import * as types from '@firebase/database-types';
declare const ServerValue: {
/**
* A one off register function which returns a database based on the app and
* passed database URL.
*
* @param app A valid FirebaseApp-like object
* @param url A valid Firebase databaseURL
* @param version custom version e.g. firebase-admin version
*/
TIMESTAMP: {
'.sv': string;
};
};
/**
* A one off register function which returns a database based on the app and
* passed database URL.
*
* @param app A valid FirebaseApp-like object
* @param url A valid Firebase databaseURL
* @param version custom version e.g. firebase-admin version
*/
export declare function initStandalone(app: FirebaseApp, url: string, version: string): {
instance: Database;
namespace: {
Reference: typeof Reference;
Query: typeof Query;
Database: typeof Database;
DataSnapshot: typeof DataSnapshot;
enableLogging: (logger_?: boolean | ((a: string) => void), persistent?: boolean) => void;
INTERNAL: typeof INTERNAL;
ServerValue: {
/**
* A one off register function which returns a database based on the app and
* passed database URL.
*
* @param app A valid FirebaseApp-like object
* @param url A valid Firebase databaseURL
* @param version custom version e.g. firebase-admin version
*/
TIMESTAMP: {
'.sv': string;
};
};
TEST_ACCESS: typeof TEST_ACCESS;
};
};
export declare function registerDatabase(instance: FirebaseNamespace): void;
export { Database, Query, Reference, enableLogging, ServerValue };
export { DataSnapshot } from './src/api/DataSnapshot';
export { OnDisconnect } from './src/api/onDisconnect';
declare module '@firebase/app-types' {
interface FirebaseNamespace {
database?: {
(app?: FirebaseApp): types.FirebaseDatabase;
enableLogging: typeof types.enableLogging;
ServerValue: types.ServerValue;
Database: typeof types.FirebaseDatabase;
};
}
interface FirebaseApp {
database?(): types.FirebaseDatabase;
}
}
+99
View File
@@ -0,0 +1,99 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Node } from '../core/snap/Node';
import { Reference } from './Reference';
import { Index } from '../core/snap/indexes/Index';
/**
* Class representing a firebase data snapshot. It wraps a SnapshotNode and
* surfaces the public methods (val, forEach, etc.) we want to expose.
*/
export declare class DataSnapshot {
private readonly node_;
private readonly ref_;
private readonly index_;
/**
* @param {!Node} node_ A SnapshotNode to wrap.
* @param {!Reference} ref_ The ref of the location this snapshot came from.
* @param {!Index} index_ The iteration order for this snapshot
*/
constructor(node_: Node, ref_: Reference, index_: Index);
/**
* Retrieves the snapshot contents as JSON. Returns null if the snapshot is
* empty.
*
* @return {*} JSON representation of the DataSnapshot contents, or null if empty.
*/
val(): any;
/**
* Returns the snapshot contents as JSON, including priorities of node. Suitable for exporting
* the entire node contents.
* @return {*} JSON representation of the DataSnapshot contents, or null if empty.
*/
exportVal(): any;
toJSON(): any;
/**
* Returns whether the snapshot contains a non-null value.
*
* @return {boolean} Whether the snapshot contains a non-null value, or is empty.
*/
exists(): boolean;
/**
* Returns a DataSnapshot of the specified child node's contents.
*
* @param {!string} childPathString Path to a child.
* @return {!DataSnapshot} DataSnapshot for child node.
*/
child(childPathString: string): DataSnapshot;
/**
* Returns whether the snapshot contains a child at the specified path.
*
* @param {!string} childPathString Path to a child.
* @return {boolean} Whether the child exists.
*/
hasChild(childPathString: string): boolean;
/**
* Returns the priority of the object, or null if no priority was set.
*
* @return {string|number|null} The priority.
*/
getPriority(): string | number | null;
/**
* Iterates through child nodes and calls the specified action for each one.
*
* @param {function(!DataSnapshot)} action Callback function to be called
* for each child.
* @return {boolean} True if forEach was canceled by action returning true for
* one of the child nodes.
*/
forEach(action: (d: DataSnapshot) => boolean | void): boolean;
/**
* Returns whether this DataSnapshot has children.
* @return {boolean} True if the DataSnapshot contains 1 or more child nodes.
*/
hasChildren(): boolean;
readonly key: string;
/**
* Returns the number of children for this DataSnapshot.
* @return {number} The number of children that this DataSnapshot contains.
*/
numChildren(): number;
/**
* @return {Reference} The Firebase reference for the location this snapshot's data came from.
*/
getRef(): Reference;
readonly ref: Reference;
}
+73
View File
@@ -0,0 +1,73 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Reference } from './Reference';
import { Repo } from '../core/Repo';
import { FirebaseApp } from '@firebase/app-types';
import { FirebaseService } from '@firebase/app-types/private';
/**
* Class representing a firebase database.
* @implements {FirebaseService}
*/
export declare class Database implements FirebaseService {
private repo_;
INTERNAL: DatabaseInternals;
private root_;
static readonly ServerValue: {
TIMESTAMP: {
'.sv': string;
};
};
/**
* The constructor should not be called by users of our public API.
* @param {!Repo} repo_
*/
constructor(repo_: Repo);
readonly app: FirebaseApp;
/**
* Returns a reference to the root or to the path specified in the provided
* argument.
* @param {string|Reference=} path The relative string path or an existing
* Reference to a database location.
* @throws If a Reference is provided, throws if it does not belong to the
* same project.
* @return {!Reference} Firebase reference.
**/
ref(path?: string): Reference;
ref(path?: Reference): Reference;
/**
* Returns a reference to the root or the path specified in url.
* We throw a exception if the url is not in the same domain as the
* current repo.
* @param {string} url
* @return {!Reference} Firebase reference.
*/
refFromURL(url: string): Reference;
/**
* @param {string} apiName
*/
private checkDeleted_;
goOffline(): void;
goOnline(): void;
}
export declare class DatabaseInternals {
database: Database;
/** @param {!Database} database */
constructor(database: Database);
/** @return {Promise<void>} */
delete(): Promise<void>;
}
+186
View File
@@ -0,0 +1,186 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Path } from '../core/util/Path';
import { Repo } from '../core/Repo';
import { QueryParams } from '../core/view/QueryParams';
import { Reference } from './Reference';
import { DataSnapshot } from './DataSnapshot';
export interface SnapshotCallback {
(a: DataSnapshot, b?: string | null): any;
}
/**
* A Query represents a filter to be applied to a firebase location. This object purely represents the
* query expression (and exposes our public API to build the query). The actual query logic is in ViewBase.js.
*
* Since every Firebase reference is a query, Firebase inherits from this object.
*/
export declare class Query {
repo: Repo;
path: Path;
private queryParams_;
private orderByCalled_;
static __referenceConstructor: any;
constructor(repo: Repo, path: Path, queryParams_: QueryParams, orderByCalled_: boolean);
/**
* Validates start/end values for queries.
* @param {!QueryParams} params
* @private
*/
private static validateQueryEndpoints_;
/**
* Validates that limit* has been called with the correct combination of parameters
* @param {!QueryParams} params
* @private
*/
private static validateLimit_;
/**
* Validates that no other order by call has been made
* @param {!string} fnName
* @private
*/
private validateNoPreviousOrderByCall_;
/**
* @return {!QueryParams}
*/
getQueryParams(): QueryParams;
/**
* @return {!Reference}
*/
getRef(): Reference;
/**
* @param {!string} eventType
* @param {!function(DataSnapshot, string=)} callback
* @param {(function(Error)|Object)=} cancelCallbackOrContext
* @param {Object=} context
* @return {!function(DataSnapshot, string=)}
*/
on(eventType: string, callback: SnapshotCallback, cancelCallbackOrContext?: ((a: Error) => any) | Object | null, context?: Object | null): SnapshotCallback;
/**
* @param {!function(!DataSnapshot)} callback
* @param {?function(Error)} cancelCallback
* @param {?Object} context
* @protected
*/
protected onValueEvent(callback: (a: DataSnapshot) => void, cancelCallback: ((a: Error) => void) | null, context: Object | null): void;
/**
* @param {!Object.<string, !function(!DataSnapshot, ?string)>} callbacks
* @param {?function(Error)} cancelCallback
* @param {?Object} context
* @protected
*/
onChildEvent(callbacks: {
[k: string]: SnapshotCallback;
}, cancelCallback: ((a: Error) => any) | null, context: Object | null): void;
/**
* @param {string=} eventType
* @param {(function(!DataSnapshot, ?string=))=} callback
* @param {Object=} context
*/
off(eventType?: string, callback?: SnapshotCallback, context?: Object | null): void;
/**
* Attaches a listener, waits for the first event, and then removes the listener
* @param {!string} eventType
* @param {!function(!DataSnapshot, string=)} userCallback
* @param failureCallbackOrContext
* @param context
* @return {!firebase.Promise}
*/
once(eventType: string, userCallback?: SnapshotCallback, failureCallbackOrContext?: ((a: Error) => void) | Object | null, context?: Object | null): Promise<DataSnapshot>;
/**
* Set a limit and anchor it to the start of the window.
* @param {!number} limit
* @return {!Query}
*/
limitToFirst(limit: number): Query;
/**
* Set a limit and anchor it to the end of the window.
* @param {!number} limit
* @return {!Query}
*/
limitToLast(limit: number): Query;
/**
* Given a child path, return a new query ordered by the specified grandchild path.
* @param {!string} path
* @return {!Query}
*/
orderByChild(path: string): Query;
/**
* Return a new query ordered by the KeyIndex
* @return {!Query}
*/
orderByKey(): Query;
/**
* Return a new query ordered by the PriorityIndex
* @return {!Query}
*/
orderByPriority(): Query;
/**
* Return a new query ordered by the ValueIndex
* @return {!Query}
*/
orderByValue(): Query;
/**
* @param {number|string|boolean|null} value
* @param {?string=} name
* @return {!Query}
*/
startAt(value?: number | string | boolean | null, name?: string | null): Query;
/**
* @param {number|string|boolean|null} value
* @param {?string=} name
* @return {!Query}
*/
endAt(value?: number | string | boolean | null, name?: string | null): Query;
/**
* Load the selection of children with exactly the specified value, and, optionally,
* the specified name.
* @param {number|string|boolean|null} value
* @param {string=} name
* @return {!Query}
*/
equalTo(value: number | string | boolean | null, name?: string): Query;
/**
* @return {!string} URL for this location.
*/
toString(): string;
toJSON(): string;
/**
* An object representation of the query parameters used by this Query.
* @return {!Object}
*/
queryObject(): Object;
/**
* @return {!string}
*/
queryIdentifier(): string;
/**
* Return true if this query and the provided query are equivalent; otherwise, return false.
* @param {Query} other
* @return {boolean}
*/
isEqual(other: Query): boolean;
/**
* Helper used by .on and .once to extract the context and or cancel arguments.
* @param {!string} fnName The function name (on or once)
* @param {(function(Error)|Object)=} cancelOrContext
* @param {Object=} context
* @return {{cancel: ?function(Error), context: ?Object}}
* @private
*/
private static getCancelAndContextArgs_;
readonly ref: Reference;
}
+106
View File
@@ -0,0 +1,106 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { OnDisconnect } from './onDisconnect';
import { TransactionResult } from './TransactionResult';
import { Query } from './Query';
import { Repo } from '../core/Repo';
import { Path } from '../core/util/Path';
import { Database } from './Database';
import { DataSnapshot } from './DataSnapshot';
export interface ReferenceConstructor {
new (repo: Repo, path: Path): Reference;
}
export declare class Reference extends Query {
then: (a?: any) => Promise<any>;
catch: (a?: Error) => Promise<any>;
/**
* Call options:
* new Reference(Repo, Path) or
* new Reference(url: string, string|RepoManager)
*
* Externally - this is the firebase.database.Reference type.
*
* @param {!Repo} repo
* @param {(!Path)} path
* @extends {Query}
*/
constructor(repo: Repo, path: Path);
/** @return {?string} */
getKey(): string | null;
/**
* @param {!(string|Path)} pathString
* @return {!Reference}
*/
child(pathString: string | Path): Reference;
/** @return {?Reference} */
getParent(): Reference | null;
/** @return {!Reference} */
getRoot(): Reference;
/** @return {!Database} */
databaseProp(): Database;
/**
* @param {*} newVal
* @param {function(?Error)=} onComplete
* @return {!Promise}
*/
set(newVal: any, onComplete?: (a: Error | null) => void): Promise<any>;
/**
* @param {!Object} objectToMerge
* @param {function(?Error)=} onComplete
* @return {!Promise}
*/
update(objectToMerge: Object, onComplete?: (a: Error | null) => void): Promise<any>;
/**
* @param {*} newVal
* @param {string|number|null} newPriority
* @param {function(?Error)=} onComplete
* @return {!Promise}
*/
setWithPriority(newVal: any, newPriority: string | number | null, onComplete?: (a: Error | null) => void): Promise<any>;
/**
* @param {function(?Error)=} onComplete
* @return {!Promise}
*/
remove(onComplete?: (a: Error | null) => void): Promise<any>;
/**
* @param {function(*):*} transactionUpdate
* @param {(function(?Error, boolean, ?DataSnapshot))=} onComplete
* @param {boolean=} applyLocally
* @return {!Promise}
*/
transaction(transactionUpdate: (a: any) => any, onComplete?: (a: Error | null, b: boolean, c: DataSnapshot | null) => void, applyLocally?: boolean): Promise<TransactionResult>;
/**
* @param {string|number|null} priority
* @param {function(?Error)=} onComplete
* @return {!Promise}
*/
setPriority(priority: string | number | null, onComplete?: (a: Error | null) => void): Promise<any>;
/**
* @param {*=} value
* @param {function(?Error)=} onComplete
* @return {!Reference}
*/
push(value?: any, onComplete?: (a: Error | null) => void): Reference;
/**
* @return {!OnDisconnect}
*/
onDisconnect(): OnDisconnect;
readonly database: Database;
readonly key: string | null;
readonly parent: Reference | null;
readonly root: Reference;
}
+30
View File
@@ -0,0 +1,30 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { DataSnapshot } from './DataSnapshot';
export declare class TransactionResult {
committed: boolean;
snapshot: DataSnapshot;
/**
* A type for the resolve value of Firebase.transaction.
* @constructor
* @dict
* @param {boolean} committed
* @param {DataSnapshot} snapshot
*/
constructor(committed: boolean, snapshot: DataSnapshot);
toJSON(): object;
}
+32
View File
@@ -0,0 +1,32 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Reference } from './Reference';
/**
* INTERNAL methods for internal-use only (tests, etc.).
*
* Customers shouldn't use these or else should be aware that they could break at any time.
*
* @const
*/
export declare const forceLongPolling: () => void;
export declare const forceWebSockets: () => void;
export declare const isWebSocketsAvailable: () => boolean;
export declare const setSecurityDebugCallback: (ref: Reference, callback: (a: Object) => void) => void;
export declare const stats: (ref: Reference, showDelta?: boolean) => void;
export declare const statsIncrementCounter: (ref: Reference, metric: string) => void;
export declare const dataUpdateCount: (ref: Reference) => number;
export declare const interceptServerData: (ref: Reference, callback: (a: string, b: any) => void) => void;
+59
View File
@@ -0,0 +1,59 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Repo } from '../core/Repo';
import { Path } from '../core/util/Path';
/**
* @constructor
*/
export declare class OnDisconnect {
private repo_;
private path_;
/**
* @param {!Repo} repo_
* @param {!Path} path_
*/
constructor(repo_: Repo, path_: Path);
/**
* @param {function(?Error)=} onComplete
* @return {!firebase.Promise}
*/
cancel(onComplete?: (a: Error | null) => void): Promise<void>;
/**
* @param {function(?Error)=} onComplete
* @return {!firebase.Promise}
*/
remove(onComplete?: (a: Error | null) => void): Promise<void>;
/**
* @param {*} value
* @param {function(?Error)=} onComplete
* @return {!firebase.Promise}
*/
set(value: any, onComplete?: (a: Error | null) => void): Promise<void>;
/**
* @param {*} value
* @param {number|string|null} priority
* @param {function(?Error)=} onComplete
* @return {!firebase.Promise}
*/
setWithPriority(value: any, priority: number | string | null, onComplete?: (a: Error | null) => void): Promise<void>;
/**
* @param {!Object} objectToMerge
* @param {function(?Error)=} onComplete
* @return {!firebase.Promise}
*/
update(objectToMerge: object, onComplete?: (a: Error | null) => void): Promise<void>;
}
+42
View File
@@ -0,0 +1,42 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { RepoInfo } from '../core/RepoInfo';
import { PersistentConnection } from '../core/PersistentConnection';
import { Connection } from '../realtime/Connection';
import { Query } from './Query';
export declare const DataConnection: typeof PersistentConnection;
export declare const RealTimeConnection: typeof Connection;
/**
* @param {function(): string} newHash
* @return {function()}
*/
export declare const hijackHash: (newHash: () => string) => () => void;
/**
* @type {function(new:RepoInfo, !string, boolean, !string, boolean): undefined}
*/
export declare const ConnectionTarget: typeof RepoInfo;
/**
* @param {!Query} query
* @return {!string}
*/
export declare const queryIdentifier: (query: Query) => string;
/**
* Forces the RepoManager to create Repos that use ReadonlyRestClient instead of PersistentConnection.
*
* @param {boolean} forceRestClient
*/
export declare const forceRestClient: (forceRestClient: boolean) => void;
+42
View File
@@ -0,0 +1,42 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { FirebaseApp } from '@firebase/app-types';
import { FirebaseAuthTokenData } from '@firebase/app-types/private';
/**
* An interface for token fetchers.
*/
export interface AuthTokenProvider {
/**
* @param {boolean} forceRefresh
* @return {!Promise<FirebaseAuthTokenData>}
*/
getToken(forceRefresh: boolean): Promise<FirebaseAuthTokenData>;
addTokenChangeListener(listener: (token: string | null) => void): any;
removeTokenChangeListener(listener: (token: string | null) => void): any;
notifyForInvalidToken(): any;
}
/**
* Abstraction around FirebaseApp's token fetching capabilities.
*/
export declare class FirebaseAuthTokenProvider implements AuthTokenProvider {
private app_;
constructor(app_: FirebaseApp);
getToken(forceRefresh: boolean): Promise<FirebaseAuthTokenData>;
addTokenChangeListener(listener: (token: string | null) => void): void;
removeTokenChangeListener(listener: (token: string | null) => void): void;
notifyForInvalidToken(): void;
}
+77
View File
@@ -0,0 +1,77 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ImmutableTree } from './util/ImmutableTree';
import { Path } from './util/Path';
import { Node, NamedNode } from './snap/Node';
/**
* This class holds a collection of writes that can be applied to nodes in unison. It abstracts away the logic with
* dealing with priority writes and multiple nested writes. At any given path there is only allowed to be one write
* modifying that path. Any write to an existing path or shadowing an existing path will modify that existing write
* to reflect the write added.
*/
export declare class CompoundWrite {
private writeTree_;
constructor(writeTree_: ImmutableTree<Node>);
static Empty: CompoundWrite;
addWrite(path: Path, node: Node): CompoundWrite;
addWrites(path: Path, updates: {
[name: string]: Node;
}): CompoundWrite;
/**
* Will remove a write at the given path and deeper paths. This will <em>not</em> modify a write at a higher
* location, which must be removed by calling this method with that path.
*
* @param path The path at which a write and all deeper writes should be removed
* @return {!CompoundWrite} The new CompoundWrite with the removed path
*/
removeWrite(path: Path): CompoundWrite;
/**
* Returns whether this CompoundWrite will fully overwrite a node at a given location and can therefore be
* considered "complete".
*
* @param path The path to check for
* @return Whether there is a complete write at that path
*/
hasCompleteWrite(path: Path): boolean;
/**
* Returns a node for a path if and only if the node is a "complete" overwrite at that path. This will not aggregate
* writes from deeper paths, but will return child nodes from a more shallow path.
*
* @param path The path to get a complete write
* @return The node if complete at that path, or null otherwise.
*/
getCompleteNode(path: Path): Node | null;
/**
* Returns all children that are guaranteed to be a complete overwrite.
*
* @return A list of all complete children.
*/
getCompleteChildren(): NamedNode[];
childCompoundWrite(path: Path): CompoundWrite;
/**
* Returns true if this CompoundWrite is empty and therefore does not modify any nodes.
* @return Whether this CompoundWrite is empty
*/
isEmpty(): boolean;
/**
* Applies this CompoundWrite to a node. The node is returned with all writes from this CompoundWrite applied to the
* node
* @param node The node to apply this CompoundWrite to
* @return The node with all writes applied
*/
apply(node: Node): Node;
}
@@ -0,0 +1,27 @@
/**
* @license
* Copyright 2019 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { FirebaseApp } from '@firebase/app-types';
import { FirebaseAuthTokenData } from '@firebase/app-types/private';
import { AuthTokenProvider } from './AuthTokenProvider';
export declare class EmulatorAuthTokenProvider implements AuthTokenProvider {
private app_;
constructor(app_: FirebaseApp);
getToken(forceRefresh: boolean): Promise<FirebaseAuthTokenData>;
addTokenChangeListener(listener: (token: string | null) => void): void;
removeTokenChangeListener(listener: (token: string | null) => void): void;
notifyForInvalidToken(): void;
}
+142
View File
@@ -0,0 +1,142 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ServerActions } from './ServerActions';
import { AuthTokenProvider } from './AuthTokenProvider';
import { RepoInfo } from './RepoInfo';
import { Query } from '../api/Query';
/**
* Firebase connection. Abstracts wire protocol and handles reconnecting.
*
* NOTE: All JSON objects sent to the realtime connection must have property names enclosed
* in quotes to make sure the closure compiler does not minify them.
*/
export declare class PersistentConnection extends ServerActions {
private repoInfo_;
private onDataUpdate_;
private onConnectStatus_;
private onServerInfoUpdate_;
private authTokenProvider_;
private authOverride_?;
id: number;
private log_;
private interruptReasons_;
/** Map<path, Map<queryId, ListenSpec>> */
private readonly listens;
private outstandingPuts_;
private outstandingPutCount_;
private onDisconnectRequestQueue_;
private connected_;
private reconnectDelay_;
private maxReconnectDelay_;
private securityDebugCallback_;
lastSessionId: string | null;
private establishConnectionTimer_;
private visible_;
private requestCBHash_;
private requestNumber_;
private realtime_;
private authToken_;
private forceTokenRefresh_;
private invalidAuthTokenCount_;
private firstConnection_;
private lastConnectionAttemptTime_;
private lastConnectionEstablishedTime_;
private static nextPersistentConnectionId_;
/**
* Counter for number of connections created. Mainly used for tagging in the logs
*/
private static nextConnectionId_;
/**
* @implements {ServerActions}
* @param repoInfo_ Data about the namespace we are connecting to
* @param onDataUpdate_ A callback for new data from the server
*/
constructor(repoInfo_: RepoInfo, onDataUpdate_: (a: string, b: any, c: boolean, d: number | null) => void, onConnectStatus_: (a: boolean) => void, onServerInfoUpdate_: (a: any) => void, authTokenProvider_: AuthTokenProvider, authOverride_?: Object | null);
protected sendRequest(action: string, body: any, onResponse?: (a: any) => void): void;
/**
* @inheritDoc
*/
listen(query: Query, currentHashFn: () => string, tag: number | null, onComplete: (a: string, b: any) => void): void;
private sendListen_;
private static warnOnListenWarnings_;
/**
* @inheritDoc
*/
refreshAuthToken(token: string): void;
private reduceReconnectDelayIfAdminCredential_;
/**
* Attempts to authenticate with the given credentials. If the authentication attempt fails, it's triggered like
* a auth revoked (the connection is closed).
*/
tryAuth(): void;
/**
* @inheritDoc
*/
unlisten(query: Query, tag: number | null): void;
private sendUnlisten_;
/**
* @inheritDoc
*/
onDisconnectPut(pathString: string, data: any, onComplete?: (a: string, b: string) => void): void;
/**
* @inheritDoc
*/
onDisconnectMerge(pathString: string, data: any, onComplete?: (a: string, b: string) => void): void;
/**
* @inheritDoc
*/
onDisconnectCancel(pathString: string, onComplete?: (a: string, b: string) => void): void;
private sendOnDisconnect_;
/**
* @inheritDoc
*/
put(pathString: string, data: any, onComplete?: (a: string, b: string) => void, hash?: string): void;
/**
* @inheritDoc
*/
merge(pathString: string, data: any, onComplete: (a: string, b: string | null) => void, hash?: string): void;
putInternal(action: string, pathString: string, data: any, onComplete: (a: string, b: string | null) => void, hash?: string): void;
private sendPut_;
/**
* @inheritDoc
*/
reportStats(stats: {
[k: string]: any;
}): void;
private onDataMessage_;
private onDataPush_;
private onReady_;
private scheduleConnect_;
private onVisible_;
private onOnline_;
private onRealtimeDisconnect_;
private establishConnection_;
interrupt(reason: string): void;
resume(reason: string): void;
private handleTimestamp_;
private cancelSentTransactions_;
private onListenRevoked_;
private removeListen_;
private onAuthRevoked_;
private onSecurityDebugPacket_;
private restoreState_;
/**
* Sends client stats for first connection
*/
private sendConnectStats_;
private shouldReconnect_;
}
+72
View File
@@ -0,0 +1,72 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ServerActions } from './ServerActions';
import { RepoInfo } from './RepoInfo';
import { AuthTokenProvider } from './AuthTokenProvider';
import { Query } from '../api/Query';
/**
* An implementation of ServerActions that communicates with the server via REST requests.
* This is mostly useful for compatibility with crawlers, where we don't want to spin up a full
* persistent connection (using WebSockets or long-polling)
*/
export declare class ReadonlyRestClient extends ServerActions {
private repoInfo_;
private onDataUpdate_;
private authTokenProvider_;
reportStats(stats: {
[k: string]: any;
}): void;
/** @private {function(...[*])} */
private log_;
/**
* We don't actually need to track listens, except to prevent us calling an onComplete for a listen
* that's been removed. :-/
*
* @private {!Object.<string, !Object>}
*/
private listens_;
/**
* @param {!Query} query
* @param {?number=} tag
* @return {string}
* @private
*/
static getListenId_(query: Query, tag?: number | null): string;
/**
* @param {!RepoInfo} repoInfo_ Data about the namespace we are connecting to
* @param {function(string, *, boolean, ?number)} onDataUpdate_ A callback for new data from the server
* @param {AuthTokenProvider} authTokenProvider_
* @implements {ServerActions}
*/
constructor(repoInfo_: RepoInfo, onDataUpdate_: (a: string, b: any, c: boolean, d: number | null) => void, authTokenProvider_: AuthTokenProvider);
/** @inheritDoc */
listen(query: Query, currentHashFn: () => string, tag: number | null, onComplete: (a: string, b: any) => void): void;
/** @inheritDoc */
unlisten(query: Query, tag: number | null): void;
/** @inheritDoc */
refreshAuthToken(token: string): void;
/**
* Performs a REST request to the given path, with the provided query string parameters,
* and any auth credentials we have.
*
* @param {!string} pathString
* @param {!Object.<string, *>} queryStringParameters
* @param {?function(?number, *=)} callback
* @private
*/
private restRequest_;
}
+97
View File
@@ -0,0 +1,97 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Path } from './util/Path';
import { PersistentConnection } from './PersistentConnection';
import { FirebaseApp } from '@firebase/app-types';
import { RepoInfo } from './RepoInfo';
import { Database } from '../api/Database';
import { Query } from '../api/Query';
import { EventRegistration } from './view/EventRegistration';
/**
* A connection to a single data repository.
*/
export declare class Repo {
repoInfo_: RepoInfo;
app: FirebaseApp;
dataUpdateCount: number;
private infoSyncTree_;
private serverSyncTree_;
private stats_;
private statsListener_;
private eventQueue_;
private nextWriteId_;
private server_;
private statsReporter_;
private transactions_init_;
private infoData_;
private abortTransactions_;
private rerunTransactions_;
private interceptServerDataCallback_;
private __database;
/** A list of data pieces and paths to be set when this client disconnects. */
private onDisconnect_;
persistentConnection_: PersistentConnection | null;
constructor(repoInfo_: RepoInfo, forceRestClient: boolean, app: FirebaseApp);
/**
* @return The URL corresponding to the root of this Firebase.
*/
toString(): string;
/**
* @return The namespace represented by the repo.
*/
name(): string;
/**
* @return The time in milliseconds, taking the server offset into account if we have one.
*/
serverTime(): number;
/**
* Generate ServerValues using some variables from the repo object.
*/
generateServerValues(): Object;
/**
* Called by realtime when we get new messages from the server.
*/
private onDataUpdate_;
interceptServerData_(callback: ((a: string, b: any) => any) | null): void;
private onConnectStatus_;
private onServerInfoUpdate_;
private updateInfo_;
private getNextWriteId_;
setWithPriority(path: Path, newVal: any, newPriority: number | string | null, onComplete: ((status: Error | null, errorReason?: string) => void) | null): void;
update(path: Path, childrenToMerge: {
[k: string]: any;
}, onComplete: ((status: Error | null, errorReason?: string) => void) | null): void;
/**
* Applies all of the changes stored up in the onDisconnect_ tree.
*/
private runOnDisconnectEvents_;
onDisconnectCancel(path: Path, onComplete: ((status: Error | null, errorReason?: string) => void) | null): void;
onDisconnectSet(path: Path, value: any, onComplete: ((status: Error | null, errorReason?: string) => void) | null): void;
onDisconnectSetWithPriority(path: Path, value: any, priority: any, onComplete: ((status: Error | null, errorReason?: string) => void) | null): void;
onDisconnectUpdate(path: Path, childrenToMerge: {
[k: string]: any;
}, onComplete: ((status: Error | null, errorReason?: string) => void) | null): void;
addEventCallbackForQuery(query: Query, eventRegistration: EventRegistration): void;
removeEventCallbackForQuery(query: Query, eventRegistration: EventRegistration): void;
interrupt(): void;
resume(): void;
stats(showDelta?: boolean): void;
statsIncrementCounter(metric: string): void;
private log_;
callOnCompleteCallback(callback: ((status: Error | null, errorReason?: string) => void) | null, status: string, errorReason?: string | null): void;
readonly database: Database;
}
+57
View File
@@ -0,0 +1,57 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* A class that holds metadata about a Repo object
*
* @constructor
*/
export declare class RepoInfo {
secure: boolean;
namespace: string;
webSocketOnly: boolean;
persistenceKey: string;
includeNamespaceInQueryParams: boolean;
host: string;
domain: string;
internalHost: string;
/**
* @param {string} host Hostname portion of the url for the repo
* @param {boolean} secure Whether or not this repo is accessed over ssl
* @param {string} namespace The namespace represented by the repo
* @param {boolean} webSocketOnly Whether to prefer websockets over all other transports (used by Nest).
* @param {string=} persistenceKey Override the default session persistence storage key
*/
constructor(host: string, secure: boolean, namespace: string, webSocketOnly: boolean, persistenceKey?: string, includeNamespaceInQueryParams?: boolean);
needsQueryParam(): boolean;
isCacheableHost(): boolean;
isDemoHost(): boolean;
isCustomHost(): boolean;
updateHost(newHost: string): void;
/**
* Returns the websocket URL for this repo
* @param {string} type of connection
* @param {Object} params list
* @return {string} The URL for this repo
*/
connectionURL(type: string, params: {
[k: string]: string;
}): string;
/** @return {string} */
toString(): string;
/** @return {string} */
toURLString(): string;
}
+65
View File
@@ -0,0 +1,65 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { FirebaseApp } from '@firebase/app-types';
import { Repo } from './Repo';
import './Repo_transaction';
import { Database } from '../api/Database';
import { RepoInfo } from './RepoInfo';
/**
* Creates and caches Repo instances.
*/
export declare class RepoManager {
/**
* @private {!Object.<string, Object<string, !fb.core.Repo>>}
*/
private repos_;
/**
* If true, new Repos will be created to use ReadonlyRestClient (for testing purposes).
* @private {boolean}
*/
private useRestClient_;
static getInstance(): RepoManager;
interrupt(): void;
resume(): void;
/**
* This function should only ever be called to CREATE a new database instance.
*
* @param {!FirebaseApp} app
* @return {!Database}
*/
databaseFromApp(app: FirebaseApp, url?: string): Database;
/**
* Remove the repo and make sure it is disconnected.
*
* @param {!Repo} repo
*/
deleteRepo(repo: Repo): void;
/**
* Ensures a repo doesn't already exist and then creates one using the
* provided app.
*
* @param {!RepoInfo} repoInfo The metadata about the Repo
* @param {!FirebaseApp} app
* @return {!Repo} The Repo object for the specified server / repoName.
*/
createRepo(repoInfo: RepoInfo, app: FirebaseApp): Repo;
/**
* Forces us to use ReadonlyRestClient instead of PersistentConnection for new Repos.
* @param {boolean} forceRestClient
*/
forceRestClient(forceRestClient: boolean): void;
}
+33
View File
@@ -0,0 +1,33 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { DataSnapshot } from '../api/DataSnapshot';
import { Path } from './util/Path';
/**
* @enum {number}
*/
export declare enum TransactionStatus {
RUN = 0,
SENT = 1,
COMPLETED = 2,
SENT_NEEDS_ABORT = 3,
NEEDS_ABORT = 4
}
declare module './Repo' {
interface Repo {
startTransaction(path: Path, transactionUpdate: (a: any) => void, onComplete: ((a: Error, b: boolean, c: DataSnapshot) => void) | null, applyLocally: boolean): void;
}
}
+81
View File
@@ -0,0 +1,81 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Query } from '../api/Query';
/**
* Interface defining the set of actions that can be performed against the Firebase server
* (basically corresponds to our wire protocol).
*
* @interface
*/
export declare abstract class ServerActions {
/**
* @param {!Query} query
* @param {function():string} currentHashFn
* @param {?number} tag
* @param {function(string, *)} onComplete
*/
abstract listen(query: Query, currentHashFn: () => string, tag: number | null, onComplete: (a: string, b: any) => void): void;
/**
* Remove a listen.
*
* @param {!Query} query
* @param {?number} tag
*/
abstract unlisten(query: Query, tag: number | null): void;
/**
* @param {string} pathString
* @param {*} data
* @param {function(string, string)=} onComplete
* @param {string=} hash
*/
put(pathString: string, data: any, onComplete?: (a: string, b: string) => void, hash?: string): void;
/**
* @param {string} pathString
* @param {*} data
* @param {function(string, ?string)} onComplete
* @param {string=} hash
*/
merge(pathString: string, data: any, onComplete: (a: string, b: string | null) => void, hash?: string): void;
/**
* Refreshes the auth token for the current connection.
* @param {string} token The authentication token
*/
refreshAuthToken(token: string): void;
/**
* @param {string} pathString
* @param {*} data
* @param {function(string, string)=} onComplete
*/
onDisconnectPut(pathString: string, data: any, onComplete?: (a: string, b: string) => void): void;
/**
* @param {string} pathString
* @param {*} data
* @param {function(string, string)=} onComplete
*/
onDisconnectMerge(pathString: string, data: any, onComplete?: (a: string, b: string) => void): void;
/**
* @param {string} pathString
* @param {function(string, string)=} onComplete
*/
onDisconnectCancel(pathString: string, onComplete?: (a: string, b: string) => void): void;
/**
* @param {Object.<string, *>} stats
*/
reportStats(stats: {
[k: string]: any;
}): void;
}
+28
View File
@@ -0,0 +1,28 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Path } from './util/Path';
import { Node } from './snap/Node';
/**
* Mutable object which basically just stores a reference to the "latest" immutable snapshot.
*
* @constructor
*/
export declare class SnapshotHolder {
private rootNode_;
getNode(path: Path): Node;
updateSnapshot(path: Path, newSnapshotNode: Node): void;
}
+61
View File
@@ -0,0 +1,61 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Path } from './util/Path';
import { Node } from './snap/Node';
/**
* Helper class to store a sparse set of snapshots.
*/
export declare class SparseSnapshotTree {
private value;
private readonly children;
/**
* Gets the node stored at the given path if one exists.
*
* @param path Path to look up snapshot for.
* @return The retrieved node, or null.
*/
find(path: Path): Node | null;
/**
* Stores the given node at the specified path. If there is already a node
* at a shallower path, it merges the new data into that snapshot node.
*
* @param path Path to look up snapshot for.
* @param data The new data, or null.
*/
remember(path: Path, data: Node): void;
/**
* Purge the data at path from the cache.
*
* @param path Path to look up snapshot for.
* @return True if this node should now be removed.
*/
forget(path: Path): boolean;
/**
* Recursively iterates through all of the stored tree and calls the
* callback on each one.
*
* @param prefixPath Path to look up node for.
* @param func The function to invoke for each tree.
*/
forEachTree(prefixPath: Path, func: (a: Path, b: Node) => any): void;
/**
* Iterates through each immediate child and triggers the callback.
*
* @param func The function to invoke for each child.
*/
forEachChild(func: (a: string, b: SparseSnapshotTree) => void): void;
}
+83
View File
@@ -0,0 +1,83 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { View } from './view/View';
import { Operation } from './operation/Operation';
import { WriteTreeRef } from './WriteTree';
import { Query } from '../api/Query';
import { EventRegistration } from './view/EventRegistration';
import { Node } from './snap/Node';
import { Path } from './util/Path';
import { Event } from './view/Event';
import { ReferenceConstructor } from '../api/Reference';
/**
* SyncPoint represents a single location in a SyncTree with 1 or more event registrations, meaning we need to
* maintain 1 or more Views at this location to cache server data and raise appropriate events for server changes
* and user writes (set, transaction, update).
*
* It's responsible for:
* - Maintaining the set of 1 or more views necessary at this location (a SyncPoint with 0 views should be removed).
* - Proxying user / server operations to the views as appropriate (i.e. applyServerOverwrite,
* applyUserOverwrite, etc.)
*/
export declare class SyncPoint {
static __referenceConstructor: ReferenceConstructor;
/**
* The Views being tracked at this location in the tree, stored as a map where the key is a
* queryId and the value is the View for that query.
*
* NOTE: This list will be quite small (usually 1, but perhaps 2 or 3; any more is an odd use case).
*/
private readonly views;
isEmpty(): boolean;
applyOperation(operation: Operation, writesCache: WriteTreeRef, optCompleteServerCache: Node | null): Event[];
/**
* Add an event callback for the specified query.
*
* @param {!Query} query
* @param {!EventRegistration} eventRegistration
* @param {!WriteTreeRef} writesCache
* @param {?Node} serverCache Complete server cache, if we have it.
* @param {boolean} serverCacheComplete
* @return {!Array.<!Event>} Events to raise.
*/
addEventRegistration(query: Query, eventRegistration: EventRegistration, writesCache: WriteTreeRef, serverCache: Node | null, serverCacheComplete: boolean): Event[];
/**
* Remove event callback(s). Return cancelEvents if a cancelError is specified.
*
* If query is the default query, we'll check all views for the specified eventRegistration.
* If eventRegistration is null, we'll remove all callbacks for the specified view(s).
*
* @param {!Query} query
* @param {?EventRegistration} eventRegistration If null, remove all callbacks.
* @param {Error=} cancelError If a cancelError is provided, appropriate cancel events will be returned.
* @return {{removed:!Array.<!Query>, events:!Array.<!Event>}} removed queries and any cancel events
*/
removeEventRegistration(query: Query, eventRegistration: EventRegistration | null, cancelError?: Error): {
removed: Query[];
events: Event[];
};
getQueryViews(): View[];
/**
* @param path The path to the desired complete snapshot
* @return A complete cache, if it exists
*/
getCompleteServerCache(path: Path): Node | null;
viewForQuery(query: Query): View | null;
viewExistsForQuery(query: Query): boolean;
hasCompleteView(): boolean;
getCompleteView(): View | null;
}
+234
View File
@@ -0,0 +1,234 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Path } from './util/Path';
import { Query } from '../api/Query';
import { Node } from './snap/Node';
import { Event } from './view/Event';
import { EventRegistration } from './view/EventRegistration';
/**
* @typedef {{
* startListening: function(
* !Query,
* ?number,
* function():string,
* function(!string, *):!Array.<!Event>
* ):!Array.<!Event>,
*
* stopListening: function(!Query, ?number)
* }}
*/
export interface ListenProvider {
startListening(query: Query, tag: number | null, hashFn: () => string, onComplete: (a: string, b?: any) => Event[]): Event[];
stopListening(a: Query, b: number | null): void;
}
/**
* SyncTree is the central class for managing event callback registration, data caching, views
* (query processing), and event generation. There are typically two SyncTree instances for
* each Repo, one for the normal Firebase data, and one for the .info data.
*
* It has a number of responsibilities, including:
* - Tracking all user event callbacks (registered via addEventRegistration() and removeEventRegistration()).
* - Applying and caching data changes for user set(), transaction(), and update() calls
* (applyUserOverwrite(), applyUserMerge()).
* - Applying and caching data changes for server data changes (applyServerOverwrite(),
* applyServerMerge()).
* - Generating user-facing events for server and user changes (all of the apply* methods
* return the set of events that need to be raised as a result).
* - Maintaining the appropriate set of server listens to ensure we are always subscribed
* to the correct set of paths and queries to satisfy the current set of user event
* callbacks (listens are started/stopped using the provided listenProvider).
*
* NOTE: Although SyncTree tracks event callbacks and calculates events to raise, the actual
* events are returned to the caller rather than raised synchronously.
*
* @constructor
*/
export declare class SyncTree {
private listenProvider_;
/**
* Tree of SyncPoints. There's a SyncPoint at any location that has 1 or more views.
*/
private syncPointTree_;
/**
* A tree of all pending user writes (user-initiated set()'s, transaction()'s, update()'s, etc.).
*/
private pendingWriteTree_;
private readonly tagToQueryMap;
private readonly queryToTagMap;
/**
* @param {!ListenProvider} listenProvider_ Used by SyncTree to start / stop listening
* to server data.
*/
constructor(listenProvider_: ListenProvider);
/**
* Apply the data changes for a user-generated set() or transaction() call.
*
* @return Events to raise.
*/
applyUserOverwrite(path: Path, newData: Node, writeId: number, visible?: boolean): Event[];
/**
* Apply the data from a user-generated update() call
*
* @return Events to raise.
*/
applyUserMerge(path: Path, changedChildren: {
[k: string]: Node;
}, writeId: number): Event[];
/**
* Acknowledge a pending user write that was previously registered with applyUserOverwrite() or applyUserMerge().
*
* @param revert True if the given write failed and needs to be reverted
* @return Events to raise.
*/
ackUserWrite(writeId: number, revert?: boolean): Event[];
/**
* Apply new server data for the specified path..
*
* @return Events to raise.
*/
applyServerOverwrite(path: Path, newData: Node): Event[];
/**
* Apply new server data to be merged in at the specified path.
*
* @return Events to raise.
*/
applyServerMerge(path: Path, changedChildren: {
[k: string]: Node;
}): Event[];
/**
* Apply a listen complete for a query
*
* @return Events to raise.
*/
applyListenComplete(path: Path): Event[];
/**
* Apply new server data for the specified tagged query.
*
* @return Events to raise.
*/
applyTaggedQueryOverwrite(path: Path, snap: Node, tag: number): Event[];
/**
* Apply server data to be merged in for the specified tagged query.
*
* @return Events to raise.
*/
applyTaggedQueryMerge(path: Path, changedChildren: {
[k: string]: Node;
}, tag: number): Event[];
/**
* Apply a listen complete for a tagged query
*
* @return Events to raise.
*/
applyTaggedListenComplete(path: Path, tag: number): Event[];
/**
* Add an event callback for the specified query.
*
* @return Events to raise.
*/
addEventRegistration(query: Query, eventRegistration: EventRegistration): Event[];
/**
* Remove event callback(s).
*
* If query is the default query, we'll check all queries for the specified eventRegistration.
* If eventRegistration is null, we'll remove all callbacks for the specified query/queries.
*
* @param eventRegistration If null, all callbacks are removed.
* @param cancelError If a cancelError is provided, appropriate cancel events will be returned.
* @return Cancel events, if cancelError was provided.
*/
removeEventRegistration(query: Query, eventRegistration: EventRegistration | null, cancelError?: Error): Event[];
/**
* Returns a complete cache, if we have one, of the data at a particular path. The location must have a listener above
* it, but as this is only used by transaction code, that should always be the case anyways.
*
* Note: this method will *include* hidden writes from transaction with applyLocally set to false.
*
* @param path The path to the data we want
* @param writeIdsToExclude A specific set to be excluded
*/
calcCompleteEventCache(path: Path, writeIdsToExclude?: number[]): Node | null;
/**
* This collapses multiple unfiltered views into a single view, since we only need a single
* listener for them.
*/
private collectDistinctViewsForSubTree_;
private removeTags_;
/**
* Normalizes a query to a query we send the server for listening
*
* @return The normalized query
*/
private static queryForListening_;
/**
* For a given new listen, manage the de-duplication of outstanding subscriptions.
*
* @return This method can return events to support synchronous data sources
*/
private setupListener_;
private createListenerForView_;
/**
* Given a query, computes a "queryKey" suitable for use in our queryToTagMap_.
*/
private static makeQueryKey_;
/**
* Given a queryKey (created by makeQueryKey), parse it back into a path and queryId.
*/
private static parseQueryKey_;
/**
* Return the query associated with the given tag, if we have one
*/
private queryKeyForTag_;
/**
* Return the tag associated with the given query.
*/
private tagForQuery_;
/**
* Static tracker for next query tag.
*/
private static nextQueryTag_;
/**
* Static accessor for query tags.
*/
private static getNextQueryTag_;
/**
* A helper method to apply tagged operations
*/
private applyTaggedOperation_;
/**
* A helper method that visits all descendant and ancestor SyncPoints, applying the operation.
*
* NOTES:
* - Descendant SyncPoints will be visited first (since we raise events depth-first).
* - We call applyOperation() on each SyncPoint passing three things:
* 1. A version of the Operation that has been made relative to the SyncPoint location.
* 2. A WriteTreeRef of any writes we have cached at the SyncPoint location.
* 3. A snapshot Node with cached server data, if we have it.
* - We concatenate all of the events returned by each SyncPoint and return the result.
*/
private applyOperationToSyncPoints_;
/**
* Recursive helper for applyOperationToSyncPoints_
*/
private applyOperationHelper_;
/**
* Recursive helper for applyOperationToSyncPoints_
*/
private applyOperationDescendantsHelper_;
}
+295
View File
@@ -0,0 +1,295 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Path } from './util/Path';
import { ChildrenNode } from './snap/ChildrenNode';
import { NamedNode, Node } from './snap/Node';
import { CacheNode } from './view/CacheNode';
import { Index } from './snap/indexes/Index';
/**
* Defines a single user-initiated write operation. May be the result of a set(), transaction(), or update() call. In
* the case of a set() or transaction, snap wil be non-null. In the case of an update(), children will be non-null.
*/
export interface WriteRecord {
writeId: number;
path: Path;
snap?: Node | null;
children?: {
[k: string]: Node;
} | null;
visible: boolean;
}
/**
* WriteTree tracks all pending user-initiated writes and has methods to calculate the result of merging them
* with underlying server data (to create "event cache" data). Pending writes are added with addOverwrite()
* and addMerge(), and removed with removeWrite().
*
* @constructor
*/
export declare class WriteTree {
/**
* A tree tracking the result of applying all visible writes. This does not include transactions with
* applyLocally=false or writes that are completely shadowed by other writes.
*
* @type {!CompoundWrite}
* @private
*/
private visibleWrites_;
/**
* A list of all pending writes, regardless of visibility and shadowed-ness. Used to calculate arbitrary
* sets of the changed data, such as hidden writes (from transactions) or changes with certain writes excluded (also
* used by transactions).
*
* @type {!Array.<!WriteRecord>}
* @private
*/
private allWrites_;
private lastWriteId_;
/**
* Create a new WriteTreeRef for the given path. For use with a new sync point at the given path.
*
* @param {!Path} path
* @return {!WriteTreeRef}
*/
childWrites(path: Path): WriteTreeRef;
/**
* Record a new overwrite from user code.
*
* @param {!Path} path
* @param {!Node} snap
* @param {!number} writeId
* @param {boolean=} visible This is set to false by some transactions. It should be excluded from event caches
*/
addOverwrite(path: Path, snap: Node, writeId: number, visible?: boolean): void;
/**
* Record a new merge from user code.
*
* @param {!Path} path
* @param {!Object.<string, !Node>} changedChildren
* @param {!number} writeId
*/
addMerge(path: Path, changedChildren: {
[k: string]: Node;
}, writeId: number): void;
/**
* @param {!number} writeId
* @return {?WriteRecord}
*/
getWrite(writeId: number): WriteRecord | null;
/**
* Remove a write (either an overwrite or merge) that has been successfully acknowledge by the server. Recalculates
* the tree if necessary. We return true if it may have been visible, meaning views need to reevaluate.
*
* @param {!number} writeId
* @return {boolean} true if the write may have been visible (meaning we'll need to reevaluate / raise
* events as a result).
*/
removeWrite(writeId: number): boolean;
/**
* Return a complete snapshot for the given path if there's visible write data at that path, else null.
* No server data is considered.
*
* @param {!Path} path
* @return {?Node}
*/
getCompleteWriteData(path: Path): Node | null;
/**
* Given optional, underlying server data, and an optional set of constraints (exclude some sets, include hidden
* writes), attempt to calculate a complete snapshot for the given path
*
* @param {!Path} treePath
* @param {?Node} completeServerCache
* @param {Array.<number>=} writeIdsToExclude An optional set to be excluded
* @param {boolean=} includeHiddenWrites Defaults to false, whether or not to layer on writes with visible set to false
* @return {?Node}
*/
calcCompleteEventCache(treePath: Path, completeServerCache: Node | null, writeIdsToExclude?: number[], includeHiddenWrites?: boolean): Node | null;
/**
* With optional, underlying server data, attempt to return a children node of children that we have complete data for.
* Used when creating new views, to pre-fill their complete event children snapshot.
*
* @param {!Path} treePath
* @param {?ChildrenNode} completeServerChildren
* @return {!ChildrenNode}
*/
calcCompleteEventChildren(treePath: Path, completeServerChildren: ChildrenNode | null): Node;
/**
* Given that the underlying server data has updated, determine what, if anything, needs to be
* applied to the event cache.
*
* Possibilities:
*
* 1. No writes are shadowing. Events should be raised, the snap to be applied comes from the server data
*
* 2. Some write is completely shadowing. No events to be raised
*
* 3. Is partially shadowed. Events
*
* Either existingEventSnap or existingServerSnap must exist
*
* @param {!Path} treePath
* @param {!Path} childPath
* @param {?Node} existingEventSnap
* @param {?Node} existingServerSnap
* @return {?Node}
*/
calcEventCacheAfterServerOverwrite(treePath: Path, childPath: Path, existingEventSnap: Node | null, existingServerSnap: Node | null): Node | null;
/**
* Returns a complete child for a given server snap after applying all user writes or null if there is no
* complete child for this ChildKey.
*
* @param {!Path} treePath
* @param {!string} childKey
* @param {!CacheNode} existingServerSnap
* @return {?Node}
*/
calcCompleteChild(treePath: Path, childKey: string, existingServerSnap: CacheNode): Node | null;
/**
* Returns a node if there is a complete overwrite for this path. More specifically, if there is a write at
* a higher path, this will return the child of that write relative to the write and this path.
* Returns null if there is no write at this path.
*/
shadowingWrite(path: Path): Node | null;
/**
* This method is used when processing child remove events on a query. If we can, we pull in children that were outside
* the window, but may now be in the window.
*/
calcIndexedSlice(treePath: Path, completeServerData: Node | null, startPost: NamedNode, count: number, reverse: boolean, index: Index): NamedNode[];
private recordContainsPath_;
/**
* Re-layer the writes and merges into a tree so we can efficiently calculate event snapshots
*/
private resetTree_;
/**
* The default filter used when constructing the tree. Keep everything that's visible.
*/
private static DefaultFilter_;
/**
* Static method. Given an array of WriteRecords, a filter for which ones to include, and a path, construct the tree of
* event data at that path.
*/
private static layerTree_;
}
/**
* A WriteTreeRef wraps a WriteTree and a path, for convenient access to a particular subtree. All of the methods
* just proxy to the underlying WriteTree.
*
* @constructor
*/
export declare class WriteTreeRef {
/**
* The path to this particular write tree ref. Used for calling methods on writeTree_ while exposing a simpler
* interface to callers.
*
* @type {!Path}
* @private
* @const
*/
private readonly treePath_;
/**
* * A reference to the actual tree of write data. All methods are pass-through to the tree, but with the appropriate
* path prefixed.
*
* This lets us make cheap references to points in the tree for sync points without having to copy and maintain all of
* the data.
*
* @type {!WriteTree}
* @private
* @const
*/
private readonly writeTree_;
/**
* @param {!Path} path
* @param {!WriteTree} writeTree
*/
constructor(path: Path, writeTree: WriteTree);
/**
* If possible, returns a complete event cache, using the underlying server data if possible. In addition, can be used
* to get a cache that includes hidden writes, and excludes arbitrary writes. Note that customizing the returned node
* can lead to a more expensive calculation.
*
* @param {?Node} completeServerCache
* @param {Array.<number>=} writeIdsToExclude Optional writes to exclude.
* @param {boolean=} includeHiddenWrites Defaults to false, whether or not to layer on writes with visible set to false
* @return {?Node}
*/
calcCompleteEventCache(completeServerCache: Node | null, writeIdsToExclude?: number[], includeHiddenWrites?: boolean): Node | null;
/**
* If possible, returns a children node containing all of the complete children we have data for. The returned data is a
* mix of the given server data and write data.
*
* @param {?ChildrenNode} completeServerChildren
* @return {!ChildrenNode}
*/
calcCompleteEventChildren(completeServerChildren: ChildrenNode | null): ChildrenNode;
/**
* Given that either the underlying server data has updated or the outstanding writes have updated, determine what,
* if anything, needs to be applied to the event cache.
*
* Possibilities:
*
* 1. No writes are shadowing. Events should be raised, the snap to be applied comes from the server data
*
* 2. Some write is completely shadowing. No events to be raised
*
* 3. Is partially shadowed. Events should be raised
*
* Either existingEventSnap or existingServerSnap must exist, this is validated via an assert
*
* @param {!Path} path
* @param {?Node} existingEventSnap
* @param {?Node} existingServerSnap
* @return {?Node}
*/
calcEventCacheAfterServerOverwrite(path: Path, existingEventSnap: Node | null, existingServerSnap: Node | null): Node | null;
/**
* Returns a node if there is a complete overwrite for this path. More specifically, if there is a write at
* a higher path, this will return the child of that write relative to the write and this path.
* Returns null if there is no write at this path.
*
* @param {!Path} path
* @return {?Node}
*/
shadowingWrite(path: Path): Node | null;
/**
* This method is used when processing child remove events on a query. If we can, we pull in children that were outside
* the window, but may now be in the window
*
* @param {?Node} completeServerData
* @param {!NamedNode} startPost
* @param {!number} count
* @param {boolean} reverse
* @param {!Index} index
* @return {!Array.<!NamedNode>}
*/
calcIndexedSlice(completeServerData: Node | null, startPost: NamedNode, count: number, reverse: boolean, index: Index): NamedNode[];
/**
* Returns a complete child for a given server snap after applying all user writes or null if there is no
* complete child for this ChildKey.
*
* @param {!string} childKey
* @param {!CacheNode} existingServerCache
* @return {?Node}
*/
calcCompleteChild(childKey: string, existingServerCache: CacheNode): Node | null;
/**
* Return a WriteTreeRef for a child.
*
* @param {string} childName
* @return {!WriteTreeRef}
*/
child(childName: string): WriteTreeRef;
}
@@ -0,0 +1,42 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Path } from '../util/Path';
import { Operation, OperationSource, OperationType } from './Operation';
import { ImmutableTree } from '../util/ImmutableTree';
export declare class AckUserWrite implements Operation {
/**@inheritDoc */ path: Path;
/**@inheritDoc */ affectedTree: ImmutableTree<boolean>;
/**@inheritDoc */ revert: boolean;
/** @inheritDoc */
type: OperationType;
/** @inheritDoc */
source: OperationSource;
/**
*
* @param {!Path} path
* @param {!ImmutableTree<!boolean>} affectedTree A tree containing true for each affected path. Affected paths can't overlap.
* @param {!boolean} revert
*/
constructor(
/**@inheritDoc */ path: Path,
/**@inheritDoc */ affectedTree: ImmutableTree<boolean>,
/**@inheritDoc */ revert: boolean);
/**
* @inheritDoc
*/
operationForChild(childName: string): AckUserWrite;
}
@@ -0,0 +1,32 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Path } from '../util/Path';
import { Operation, OperationSource, OperationType } from './Operation';
/**
* @param {!OperationSource} source
* @param {!Path} path
* @constructor
* @implements {Operation}
*/
export declare class ListenComplete implements Operation {
source: OperationSource;
path: Path;
/** @inheritDoc */
type: OperationType;
constructor(source: OperationSource, path: Path);
operationForChild(childName: string): ListenComplete;
}
+46
View File
@@ -0,0 +1,46 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Operation, OperationSource, OperationType } from './Operation';
import { Path } from '../util/Path';
import { ImmutableTree } from '../util/ImmutableTree';
import { Node } from '../snap/Node';
/**
* @param {!OperationSource} source
* @param {!Path} path
* @param {!ImmutableTree.<!Node>} children
* @constructor
* @implements {Operation}
*/
export declare class Merge implements Operation {
/**@inheritDoc */ source: OperationSource;
/**@inheritDoc */ path: Path;
/**@inheritDoc */ children: ImmutableTree<Node>;
/** @inheritDoc */
type: OperationType;
constructor(
/**@inheritDoc */ source: OperationSource,
/**@inheritDoc */ path: Path,
/**@inheritDoc */ children: ImmutableTree<Node>);
/**
* @inheritDoc
*/
operationForChild(childName: string): Operation;
/**
* @inheritDoc
*/
toString(): string;
}
+78
View File
@@ -0,0 +1,78 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Path } from '../util/Path';
/**
*
* @enum
*/
export declare enum OperationType {
OVERWRITE = 0,
MERGE = 1,
ACK_USER_WRITE = 2,
LISTEN_COMPLETE = 3
}
/**
* @interface
*/
export interface Operation {
/**
* @type {!OperationSource}
*/
source: OperationSource;
/**
* @type {!OperationType}
*/
type: OperationType;
/**
* @type {!Path}
*/
path: Path;
/**
* @param {string} childName
* @return {?Operation}
*/
operationForChild(childName: string): Operation | null;
}
/**
* @param {boolean} fromUser
* @param {boolean} fromServer
* @param {?string} queryId
* @param {boolean} tagged
* @constructor
*/
export declare class OperationSource {
fromUser: boolean;
fromServer: boolean;
queryId: string | null;
tagged: boolean;
constructor(fromUser: boolean, fromServer: boolean, queryId: string | null, tagged: boolean);
/**
* @const
* @type {!OperationSource}
*/
static User: OperationSource;
/**
* @const
* @type {!OperationSource}
*/
static Server: OperationSource;
/**
* @param {string} queryId
* @return {!OperationSource}
*/
static forServerTaggedQuery: (queryId: string) => OperationSource;
}
+35
View File
@@ -0,0 +1,35 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Operation, OperationSource, OperationType } from './Operation';
import { Path } from '../util/Path';
import { Node } from '../snap/Node';
/**
* @param {!OperationSource} source
* @param {!Path} path
* @param {!Node} snap
* @constructor
* @implements {Operation}
*/
export declare class Overwrite implements Operation {
source: OperationSource;
path: Path;
snap: Node;
/** @inheritDoc */
type: OperationType;
constructor(source: OperationSource, path: Path, snap: Node);
operationForChild(childName: string): Overwrite;
}
+180
View File
@@ -0,0 +1,180 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { SortedMap, SortedMapIterator } from '../util/SortedMap';
import { Node, NamedNode } from './Node';
import { IndexMap } from './IndexMap';
import { Index } from './indexes/Index';
import { Path } from '../util/Path';
export interface ChildrenNodeConstructor {
new (children_: SortedMap<string, Node>, priorityNode_: Node | null, indexMap_: IndexMap): ChildrenNode;
EMPTY_NODE: ChildrenNode;
}
/**
* ChildrenNode is a class for storing internal nodes in a DataSnapshot
* (i.e. nodes with children). It implements Node and stores the
* list of children in the children property, sorted by child name.
*
* @constructor
* @implements {Node}
*/
export declare class ChildrenNode implements Node {
private readonly children_;
private readonly priorityNode_;
private indexMap_;
private lazyHash_;
static readonly EMPTY_NODE: ChildrenNode;
/**
*
* @param {!SortedMap.<string, !Node>} children_ List of children
* of this node..
* @param {?Node} priorityNode_ The priority of this node (as a snapshot node).
* @param {!IndexMap} indexMap_
*/
constructor(children_: SortedMap<string, Node>, priorityNode_: Node | null, indexMap_: IndexMap);
/** @inheritDoc */
isLeafNode(): boolean;
/** @inheritDoc */
getPriority(): Node;
/** @inheritDoc */
updatePriority(newPriorityNode: Node): Node;
/** @inheritDoc */
getImmediateChild(childName: string): Node;
/** @inheritDoc */
getChild(path: Path): Node;
/** @inheritDoc */
hasChild(childName: string): boolean;
/** @inheritDoc */
updateImmediateChild(childName: string, newChildNode: Node): Node;
/** @inheritDoc */
updateChild(path: Path, newChildNode: Node): Node;
/** @inheritDoc */
isEmpty(): boolean;
/** @inheritDoc */
numChildren(): number;
/**
* @private
* @type {RegExp}
*/
private static INTEGER_REGEXP_;
/** @inheritDoc */
val(exportFormat?: boolean): object;
/** @inheritDoc */
hash(): string;
/** @inheritDoc */
getPredecessorChildName(childName: string, childNode: Node, index: Index): string;
/**
* @param {!Index} indexDefinition
* @return {?string}
*/
getFirstChildName(indexDefinition: Index): string | null;
/**
* @param {!Index} indexDefinition
* @return {?NamedNode}
*/
getFirstChild(indexDefinition: Index): NamedNode | null;
/**
* Given an index, return the key name of the largest value we have, according to that index
* @param {!Index} indexDefinition
* @return {?string}
*/
getLastChildName(indexDefinition: Index): string | null;
/**
* @param {!Index} indexDefinition
* @return {?NamedNode}
*/
getLastChild(indexDefinition: Index): NamedNode | null;
/**
* @inheritDoc
*/
forEachChild(index: Index, action: (key: string, node: Node) => boolean | void): boolean;
/**
* @param {!Index} indexDefinition
* @return {SortedMapIterator}
*/
getIterator(indexDefinition: Index): SortedMapIterator<string | NamedNode, Node, NamedNode>;
/**
*
* @param {!NamedNode} startPost
* @param {!Index} indexDefinition
* @return {!SortedMapIterator}
*/
getIteratorFrom(startPost: NamedNode, indexDefinition: Index): SortedMapIterator<string | NamedNode, Node, NamedNode>;
/**
* @param {!Index} indexDefinition
* @return {!SortedMapIterator}
*/
getReverseIterator(indexDefinition: Index): SortedMapIterator<string | NamedNode, Node, NamedNode>;
/**
* @param {!NamedNode} endPost
* @param {!Index} indexDefinition
* @return {!SortedMapIterator}
*/
getReverseIteratorFrom(endPost: NamedNode, indexDefinition: Index): SortedMapIterator<string | NamedNode, Node, NamedNode>;
/**
* @inheritDoc
*/
compareTo(other: ChildrenNode): number;
/**
* @inheritDoc
*/
withIndex(indexDefinition: Index): Node;
/**
* @inheritDoc
*/
isIndexed(index: Index): boolean;
/**
* @inheritDoc
*/
equals(other: Node): boolean;
/**
* Returns a SortedMap ordered by index, or null if the default (by-key) ordering can be used
* instead.
*
* @private
* @param {!Index} indexDefinition
* @return {?SortedMap.<NamedNode, Node>}
*/
private resolveIndex_;
}
/**
* @constructor
* @extends {ChildrenNode}
* @private
*/
export declare class MaxNode extends ChildrenNode {
constructor();
compareTo(other: Node): number;
equals(other: Node): boolean;
getPriority(): MaxNode;
getImmediateChild(childName: string): ChildrenNode;
isEmpty(): boolean;
}
/**
* Marker that will sort higher than any other snapshot.
* @type {!MAX_NODE}
* @const
*/
export declare const MAX_NODE: MaxNode;
/**
* Document NamedNode extensions
*/
declare module './Node' {
interface NamedNode {
MIN: NamedNode;
MAX: NamedNode;
}
}
+43
View File
@@ -0,0 +1,43 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { NamedNode, Node } from './Node';
import { SortedMap } from '../util/SortedMap';
import { Index } from './indexes/Index';
export declare class IndexMap {
private indexes_;
private indexSet_;
/**
* The default IndexMap for nodes without a priority
*/
static readonly Default: IndexMap;
constructor(indexes_: {
[k: string]: SortedMap<NamedNode, Node> | /*FallbackType*/ object;
}, indexSet_: {
[k: string]: Index;
});
get(indexKey: string): SortedMap<NamedNode, Node> | null;
hasIndex(indexDefinition: Index): boolean;
addIndex(indexDefinition: Index, existingChildren: SortedMap<string, Node>): IndexMap;
/**
* Ensure that this node is properly tracked in any indexes that we're maintaining
*/
addToIndexes(namedNode: NamedNode, existingChildren: SortedMap<string, Node>): IndexMap;
/**
* Create a new IndexMap instance with the given value removed
*/
removeFromIndexes(namedNode: NamedNode, existingChildren: SortedMap<string, Node>): IndexMap;
}
+105
View File
@@ -0,0 +1,105 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Node } from './Node';
import { Path } from '../util/Path';
import { Index } from './indexes/Index';
import { ChildrenNodeConstructor } from './ChildrenNode';
/**
* LeafNode is a class for storing leaf nodes in a DataSnapshot. It
* implements Node and stores the value of the node (a string,
* number, or boolean) accessible via getValue().
*/
export declare class LeafNode implements Node {
private readonly value_;
private priorityNode_;
static __childrenNodeConstructor: ChildrenNodeConstructor;
/**
* The sort order for comparing leaf nodes of different types. If two leaf nodes have
* the same type, the comparison falls back to their value
* @type {Array.<!string>}
* @const
*/
static VALUE_TYPE_ORDER: string[];
private lazyHash_;
/**
* @implements {Node}
* @param {!(string|number|boolean|Object)} value_ The value to store in this leaf node.
* The object type is possible in the event of a deferred value
* @param {!Node=} priorityNode_ The priority of this node.
*/
constructor(value_: string | number | boolean | object, priorityNode_?: Node);
/** @inheritDoc */
isLeafNode(): boolean;
/** @inheritDoc */
getPriority(): Node;
/** @inheritDoc */
updatePriority(newPriorityNode: Node): Node;
/** @inheritDoc */
getImmediateChild(childName: string): Node;
/** @inheritDoc */
getChild(path: Path): Node;
/**
* @inheritDoc
*/
hasChild(): boolean;
/** @inheritDoc */
getPredecessorChildName(childName: String, childNode: Node): null;
/** @inheritDoc */
updateImmediateChild(childName: string, newChildNode: Node): Node;
/** @inheritDoc */
updateChild(path: Path, newChildNode: Node): Node;
/** @inheritDoc */
isEmpty(): boolean;
/** @inheritDoc */
numChildren(): number;
/** @inheritDoc */
forEachChild(index: Index, action: (s: string, n: Node) => void): any;
/**
* @inheritDoc
*/
val(exportFormat?: boolean): Object;
/** @inheritDoc */
hash(): string;
/**
* Returns the value of the leaf node.
* @return {Object|string|number|boolean} The value of the node.
*/
getValue(): object | string | number | boolean;
/**
* @inheritDoc
*/
compareTo(other: Node): number;
/**
* Comparison specifically for two leaf nodes
* @param {!LeafNode} otherLeaf
* @return {!number}
* @private
*/
private compareToLeafNode_;
/**
* @inheritDoc
*/
withIndex(): Node;
/**
* @inheritDoc
*/
isIndexed(): boolean;
/**
* @inheritDoc
*/
equals(other: Node): boolean;
}
+148
View File
@@ -0,0 +1,148 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Path } from '../util/Path';
import { Index } from './indexes/Index';
/**
* Node is an interface defining the common functionality for nodes in
* a DataSnapshot.
*
* @interface
*/
export interface Node {
/**
* Whether this node is a leaf node.
* @return {boolean} Whether this is a leaf node.
*/
isLeafNode(): boolean;
/**
* Gets the priority of the node.
* @return {!Node} The priority of the node.
*/
getPriority(): Node;
/**
* Returns a duplicate node with the new priority.
* @param {!Node} newPriorityNode New priority to set for the node.
* @return {!Node} Node with new priority.
*/
updatePriority(newPriorityNode: Node): Node;
/**
* Returns the specified immediate child, or null if it doesn't exist.
* @param {string} childName The name of the child to retrieve.
* @return {!Node} The retrieved child, or an empty node.
*/
getImmediateChild(childName: string): Node;
/**
* Returns a child by path, or null if it doesn't exist.
* @param {!Path} path The path of the child to retrieve.
* @return {!Node} The retrieved child or an empty node.
*/
getChild(path: Path): Node;
/**
* Returns the name of the child immediately prior to the specified childNode, or null.
* @param {!string} childName The name of the child to find the predecessor of.
* @param {!Node} childNode The node to find the predecessor of.
* @param {!Index} index The index to use to determine the predecessor
* @return {?string} The name of the predecessor child, or null if childNode is the first child.
*/
getPredecessorChildName(childName: String, childNode: Node, index: Index): string | null;
/**
* Returns a duplicate node, with the specified immediate child updated.
* Any value in the node will be removed.
* @param {string} childName The name of the child to update.
* @param {!Node} newChildNode The new child node
* @return {!Node} The updated node.
*/
updateImmediateChild(childName: string, newChildNode: Node): Node;
/**
* Returns a duplicate node, with the specified child updated. Any value will
* be removed.
* @param {!Path} path The path of the child to update.
* @param {!Node} newChildNode The new child node, which may be an empty node
* @return {!Node} The updated node.
*/
updateChild(path: Path, newChildNode: Node): Node;
/**
* True if the immediate child specified exists
* @param {!string} childName
* @return {boolean}
*/
hasChild(childName: string): boolean;
/**
* @return {boolean} True if this node has no value or children.
*/
isEmpty(): boolean;
/**
* @return {number} The number of children of this node.
*/
numChildren(): number;
/**
* Calls action for each child.
* @param {!Index} index
* @param {function(string, !Node)} action Action to be called for
* each child. It's passed the child name and the child node.
* @return {*} The first truthy value return by action, or the last falsey one
*/
forEachChild(index: Index, action: (a: string, b: Node) => void): any;
/**
* @param exportFormat True for export format (also wire protocol format).
* @return Value of this node as JSON.
*/
val(exportFormat?: boolean): unknown;
/**
* @return {string} hash representing the node contents.
*/
hash(): string;
/**
* @param {!Node} other Another node
* @return {!number} -1 for less than, 0 for equal, 1 for greater than other
*/
compareTo(other: Node): number;
/**
* @param {!Node} other
* @return {boolean} Whether or not this snapshot equals other
*/
equals(other: Node): boolean;
/**
* @param {!Index} indexDefinition
* @return {!Node} This node, with the specified index now available
*/
withIndex(indexDefinition: Index): Node;
/**
* @param {!Index} indexDefinition
* @return {boolean}
*/
isIndexed(indexDefinition: Index): boolean;
}
/**
*
* @param {!string} name
* @param {!Node} node
* @constructor
* @struct
*/
export declare class NamedNode {
name: string;
node: Node;
constructor(name: string, node: Node);
/**
*
* @param {!string} name
* @param {!Node} node
* @return {NamedNode}
*/
static Wrap(name: string, node: Node): NamedNode;
}
+34
View File
@@ -0,0 +1,34 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { SortedMap } from '../util/SortedMap';
import { NamedNode } from './Node';
/**
* Takes a list of child nodes and constructs a SortedSet using the given comparison
* function
*
* Uses the algorithm described in the paper linked here:
* http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.46.1458
*
* @template K, V
* @param {Array.<!NamedNode>} childList Unsorted list of children
* @param {function(!NamedNode, !NamedNode):number} cmp The comparison method to be used
* @param {(function(NamedNode):K)=} keyFn An optional function to extract K from a node wrapper, if K's
* type is not NamedNode
* @param {(function(K, K):number)=} mapSortFn An optional override for comparator used by the generated sorted map
* @return {SortedMap.<K, V>}
*/
export declare const buildChildSet: <K, V>(childList: NamedNode[], cmp: (a: NamedNode, b: NamedNode) => number, keyFn?: (a: NamedNode) => K, mapSortFn?: (a: K, b: K) => number) => SortedMap<K, V>;
+19
View File
@@ -0,0 +1,19 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { NamedNode } from './Node';
export declare function NAME_ONLY_COMPARATOR(left: NamedNode, right: NamedNode): number;
export declare function NAME_COMPARATOR(left: string, right: string): number;
+69
View File
@@ -0,0 +1,69 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Node, NamedNode } from '../Node';
import { Comparator } from '../../util/SortedMap';
/**
*
* @constructor
*/
export declare abstract class Index {
/**
* @param {!NamedNode} a
* @param {!NamedNode} b
* @return {number}
*/
abstract compare(a: NamedNode, b: NamedNode): number;
/**
* @param {!Node} node
* @return {boolean}
*/
abstract isDefinedOn(node: Node): boolean;
/**
* @return {function(!NamedNode, !NamedNode):number} A standalone comparison function for
* this index
*/
getCompare(): Comparator<NamedNode>;
/**
* Given a before and after value for a node, determine if the indexed value has changed. Even if they are different,
* it's possible that the changes are isolated to parts of the snapshot that are not indexed.
*
* @param {!Node} oldNode
* @param {!Node} newNode
* @return {boolean} True if the portion of the snapshot being indexed changed between oldNode and newNode
*/
indexedValueChanged(oldNode: Node, newNode: Node): boolean;
/**
* @return {!NamedNode} a node wrapper that will sort equal to or less than
* any other node wrapper, using this index
*/
minPost(): NamedNode;
/**
* @return {!NamedNode} a node wrapper that will sort greater than or equal to
* any other node wrapper, using this index
*/
abstract maxPost(): NamedNode;
/**
* @param {*} indexValue
* @param {string} name
* @return {!NamedNode}
*/
abstract makePost(indexValue: any, name: string): NamedNode;
/**
* @return {!string} String representation for inclusion in a query spec
*/
abstract toString(): string;
}
@@ -0,0 +1,53 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Index } from './Index';
import { Node, NamedNode } from '../Node';
import { ChildrenNode } from '../ChildrenNode';
export declare class KeyIndex extends Index {
static __EMPTY_NODE: ChildrenNode;
/**
* @inheritDoc
*/
compare(a: NamedNode, b: NamedNode): number;
/**
* @inheritDoc
*/
isDefinedOn(node: Node): boolean;
/**
* @inheritDoc
*/
indexedValueChanged(oldNode: Node, newNode: Node): boolean;
/**
* @inheritDoc
*/
minPost(): any;
/**
* @inheritDoc
*/
maxPost(): NamedNode;
/**
* @param {*} indexValue
* @param {string} name
* @return {!NamedNode}
*/
makePost(indexValue: string, name: string): NamedNode;
/**
* @return {!string} String representation for inclusion in a query spec
*/
toString(): string;
}
export declare const KEY_INDEX: KeyIndex;
@@ -0,0 +1,54 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Index } from './Index';
import { NamedNode, Node } from '../Node';
import { Path } from '../../util/Path';
/**
* @param {!Path} indexPath
* @constructor
* @extends {Index}
*/
export declare class PathIndex extends Index {
private indexPath_;
constructor(indexPath_: Path);
/**
* @param {!Node} snap
* @return {!Node}
* @protected
*/
protected extractChild(snap: Node): Node;
/**
* @inheritDoc
*/
isDefinedOn(node: Node): boolean;
/**
* @inheritDoc
*/
compare(a: NamedNode, b: NamedNode): number;
/**
* @inheritDoc
*/
makePost(indexValue: object, name: string): NamedNode;
/**
* @inheritDoc
*/
maxPost(): NamedNode;
/**
* @inheritDoc
*/
toString(): string;
}
@@ -0,0 +1,58 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Index } from './Index';
import { NamedNode, Node } from '../Node';
export declare function setNodeFromJSON(val: (a: any) => Node): void;
export declare function setMaxNode(val: Node): void;
/**
* @constructor
* @extends {Index}
* @private
*/
export declare class PriorityIndex extends Index {
/**
* @inheritDoc
*/
compare(a: NamedNode, b: NamedNode): number;
/**
* @inheritDoc
*/
isDefinedOn(node: Node): boolean;
/**
* @inheritDoc
*/
indexedValueChanged(oldNode: Node, newNode: Node): boolean;
/**
* @inheritDoc
*/
minPost(): NamedNode;
/**
* @inheritDoc
*/
maxPost(): NamedNode;
/**
* @param {*} indexValue
* @param {string} name
* @return {!NamedNode}
*/
makePost(indexValue: any, name: string): NamedNode;
/**
* @return {!string} String representation for inclusion in a query spec
*/
toString(): string;
}
export declare const PRIORITY_INDEX: PriorityIndex;
@@ -0,0 +1,56 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Index } from './Index';
import { NamedNode, Node } from '../Node';
/**
* @constructor
* @extends {Index}
* @private
*/
export declare class ValueIndex extends Index {
/**
* @inheritDoc
*/
compare(a: NamedNode, b: NamedNode): number;
/**
* @inheritDoc
*/
isDefinedOn(node: Node): boolean;
/**
* @inheritDoc
*/
indexedValueChanged(oldNode: Node, newNode: Node): boolean;
/**
* @inheritDoc
*/
minPost(): NamedNode;
/**
* @inheritDoc
*/
maxPost(): NamedNode;
/**
* @param {*} indexValue
* @param {string} name
* @return {!NamedNode}
*/
makePost(indexValue: object, name: string): NamedNode;
/**
* @return {!string} String representation for inclusion in a query spec
*/
toString(): string;
}
export declare const VALUE_INDEX: ValueIndex;
+25
View File
@@ -0,0 +1,25 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Node } from './Node';
/**
* Constructs a snapshot node representing the passed JSON and returns it.
* @param {*} json JSON to create a node for.
* @param {?string|?number=} priority Optional priority to use. This will be ignored if the
* passed JSON contains a .priority property.
* @return {!Node}
*/
export declare function nodeFromJSON(json: any | null, priority?: string | number | null): Node;
+29
View File
@@ -0,0 +1,29 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Node } from './Node';
export declare function setMaxNode(val: Node): void;
/**
* @param {(!string|!number)} priority
* @return {!string}
*/
export declare const priorityHashText: (priority: string | number) => string;
/**
* Validates that a priority snapshot Node is valid.
*
* @param {!Node} priorityNode
*/
export declare const validatePriorityNode: (priorityNode: Node) => void;
@@ -0,0 +1,28 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Tracks a collection of stats.
*
* @constructor
*/
export declare class StatsCollection {
private counters_;
incrementCounter(name: string, amount?: number): void;
get(): {
[k: string]: number;
};
}
+31
View File
@@ -0,0 +1,31 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { StatsCollection } from './StatsCollection';
/**
* Returns the delta from the previous call to get stats.
*
* @param collection_ The collection to "listen" to.
* @constructor
*/
export declare class StatsListener {
private collection_;
private last_;
constructor(collection_: StatsCollection);
get(): {
[k: string]: number;
};
}
+24
View File
@@ -0,0 +1,24 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { StatsCollection } from './StatsCollection';
import { RepoInfo } from '../RepoInfo';
export declare class StatsManager {
private static collections_;
private static reporters_;
static getCollection(repoInfo: RepoInfo): StatsCollection;
static getOrCreateReporter<T>(repoInfo: RepoInfo, creatorFunction: () => T): T;
}
+33
View File
@@ -0,0 +1,33 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { StatsCollection } from './StatsCollection';
import { ServerActions } from '../ServerActions';
/**
* @constructor
*/
export declare class StatsReporter {
private server_;
private statsListener_;
private statsToReport_;
/**
* @param collection
* @param server_
*/
constructor(collection: StatsCollection, server_: ServerActions);
includeStat(stat: string): void;
private reportStats_;
}
@@ -0,0 +1,55 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Wraps a DOM Storage object and:
* - automatically encode objects as JSON strings before storing them to allow us to store arbitrary types.
* - prefixes names with "firebase:" to avoid collisions with app data.
*
* We automatically (see storage.js) create two such wrappers, one for sessionStorage,
* and one for localStorage.
*
* @constructor
*/
export declare class DOMStorageWrapper {
private domStorage_;
private prefix_;
/**
* @param {Storage} domStorage_ The underlying storage object (e.g. localStorage or sessionStorage)
*/
constructor(domStorage_: Storage);
/**
* @param {string} key The key to save the value under
* @param {?Object} value The value being stored, or null to remove the key.
*/
set(key: string, value: any | null): void;
/**
* @param {string} key
* @return {*} The value that was stored under this key, or null
*/
get(key: string): any;
/**
* @param {string} key
*/
remove(key: string): void;
isInMemoryStorage: boolean;
/**
* @param {string} name
* @return {string}
*/
prefixedName_(name: string): string;
toString(): string;
}
@@ -0,0 +1,29 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* An in-memory storage implementation that matches the API of DOMStorageWrapper
* (TODO: create interface for both to implement).
*
* @constructor
*/
export declare class MemoryStorage {
private cache_;
set(key: string, value: any | null): void;
get(key: string): any;
remove(key: string): void;
isInMemoryStorage: boolean;
}
+22
View File
@@ -0,0 +1,22 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { DOMStorageWrapper } from './DOMStorageWrapper';
import { MemoryStorage } from './MemoryStorage';
/** A storage object that lasts across sessions */
export declare const PersistentStorage: DOMStorageWrapper | MemoryStorage;
/** A storage object that only lasts one session */
export declare const SessionStorage: DOMStorageWrapper | MemoryStorage;
+45
View File
@@ -0,0 +1,45 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Base class to be used if you want to emit events. Call the constructor with
* the set of allowed event names.
*/
export declare abstract class EventEmitter {
private allowedEvents_;
private listeners_;
/**
* @param {!Array.<string>} allowedEvents_
*/
constructor(allowedEvents_: Array<string>);
/**
* To be overridden by derived classes in order to fire an initial event when
* somebody subscribes for data.
*
* @param {!string} eventType
* @return {Array.<*>} Array of parameters to trigger initial event with.
*/
abstract getInitialEvent(eventType: string): any[];
/**
* To be called by derived classes to trigger events.
* @param {!string} eventType
* @param {...*} var_args
*/
protected trigger(eventType: string, ...var_args: any[]): void;
on(eventType: string, callback: (a: any) => void, context: any): void;
off(eventType: string, callback: (a: any) => void, context: any): void;
private validateEventType_;
}
+157
View File
@@ -0,0 +1,157 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { SortedMap } from './SortedMap';
import { Path } from './Path';
/**
* A tree with immutable elements.
*/
export declare class ImmutableTree<T> {
readonly value: T | null;
readonly children: SortedMap<string, ImmutableTree<T>>;
static Empty: ImmutableTree<any>;
/**
* @template T
* @param {!Object.<string, !T>} obj
* @return {!ImmutableTree.<!T>}
*/
static fromObject<T>(obj: {
[k: string]: T;
}): ImmutableTree<T>;
/**
* @template T
* @param {?T} value
* @param {SortedMap.<string, !ImmutableTree.<T>>=} children
*/
constructor(value: T | null, children?: SortedMap<string, ImmutableTree<T>>);
/**
* True if the value is empty and there are no children
* @return {boolean}
*/
isEmpty(): boolean;
/**
* Given a path and predicate, return the first node and the path to that node
* where the predicate returns true.
*
* TODO Do a perf test -- If we're creating a bunch of {path: value:} objects
* on the way back out, it may be better to pass down a pathSoFar obj.
*
* @param {!Path} relativePath The remainder of the path
* @param {function(T):boolean} predicate The predicate to satisfy to return a
* node
* @return {?{path:!Path, value:!T}}
*/
findRootMostMatchingPathAndValue(relativePath: Path, predicate: (a: T) => boolean): {
path: Path;
value: T;
} | null;
/**
* Find, if it exists, the shortest subpath of the given path that points a defined
* value in the tree
* @param {!Path} relativePath
* @return {?{path: !Path, value: !T}}
*/
findRootMostValueAndPath(relativePath: Path): {
path: Path;
value: T;
} | null;
/**
* @param {!Path} relativePath
* @return {!ImmutableTree.<T>} The subtree at the given path
*/
subtree(relativePath: Path): ImmutableTree<T>;
/**
* Sets a value at the specified path.
*
* @param {!Path} relativePath Path to set value at.
* @param {?T} toSet Value to set.
* @return {!ImmutableTree.<T>} Resulting tree.
*/
set(relativePath: Path, toSet: T | null): ImmutableTree<T>;
/**
* Removes the value at the specified path.
*
* @param {!Path} relativePath Path to value to remove.
* @return {!ImmutableTree.<T>} Resulting tree.
*/
remove(relativePath: Path): ImmutableTree<T>;
/**
* Gets a value from the tree.
*
* @param {!Path} relativePath Path to get value for.
* @return {?T} Value at path, or null.
*/
get(relativePath: Path): T | null;
/**
* Replace the subtree at the specified path with the given new tree.
*
* @param {!Path} relativePath Path to replace subtree for.
* @param {!ImmutableTree} newTree New tree.
* @return {!ImmutableTree} Resulting tree.
*/
setTree(relativePath: Path, newTree: ImmutableTree<T>): ImmutableTree<T>;
/**
* Performs a depth first fold on this tree. Transforms a tree into a single
* value, given a function that operates on the path to a node, an optional
* current value, and a map of child names to folded subtrees
* @template V
* @param {function(Path, ?T, Object.<string, V>):V} fn
* @return {V}
*/
fold<V>(fn: (path: Path, value: T, children: {
[k: string]: V;
}) => V): V;
/**
* Recursive helper for public-facing fold() method
* @template V
* @param {!Path} pathSoFar
* @param {function(Path, ?T, Object.<string, V>):V} fn
* @return {V}
* @private
*/
private fold_;
/**
* Find the first matching value on the given path. Return the result of applying f to it.
* @template V
* @param {!Path} path
* @param {!function(!Path, !T):?V} f
* @return {?V}
*/
findOnPath<V>(path: Path, f: (path: Path, value: T) => V | null): V | null;
private findOnPath_;
/**
*
* @param {!Path} path
* @param {!function(!Path, !T)} f
* @returns {!ImmutableTree.<T>}
*/
foreachOnPath(path: Path, f: (path: Path, value: T) => void): ImmutableTree<T>;
private foreachOnPath_;
/**
* Calls the given function for each node in the tree that has a value.
*
* @param {function(!Path, !T)} f A function to be called with
* the path from the root of the tree to a node, and the value at that node.
* Called in depth-first order.
*/
foreach(f: (path: Path, value: T) => void): void;
private foreach_;
/**
*
* @param {function(string, !T)} f
*/
foreachChild(f: (name: string, value: T) => void): void;
}
+31
View File
@@ -0,0 +1,31 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Fancy ID generator that creates 20-character string identifiers with the
* following properties:
*
* 1. They're based on timestamp so that they sort *after* any existing ids.
* 2. They contain 72-bits of random data after the timestamp so that IDs won't
* collide with other clients' IDs.
* 3. They sort *lexicographically* (so the timestamp is converted to characters
* that will sort properly).
* 4. They're monotonically increasing. Even if you generate more than one in
* the same timestamp, the latter ones will sort after the former ones. We do
* this by using the previous random bits but "incrementing" them by 1 (only
* in the case of a timestamp collision).
*/
export declare const nextPushId: (now: number) => string;
+40
View File
@@ -0,0 +1,40 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { EventEmitter } from './EventEmitter';
/**
* Monitors online state (as reported by window.online/offline events).
*
* The expectation is that this could have many false positives (thinks we are online
* when we're not), but no false negatives. So we can safely use it to determine when
* we definitely cannot reach the internet.
*
* @extends {EventEmitter}
*/
export declare class OnlineMonitor extends EventEmitter {
private online_;
static getInstance(): OnlineMonitor;
constructor();
/**
* @param {!string} eventType
* @return {Array.<boolean>}
*/
getInitialEvent(eventType: string): boolean[];
/**
* @return {boolean}
*/
currentlyOnline(): boolean;
}
+132
View File
@@ -0,0 +1,132 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* An immutable object representing a parsed path. It's immutable so that you
* can pass them around to other functions without worrying about them changing
* it.
*/
export declare class Path {
private pieces_;
private pieceNum_;
/**
* Singleton to represent an empty path
*
* @const
*/
static readonly Empty: Path;
/**
* @param {string|Array.<string>} pathOrString Path string to parse,
* or another path, or the raw tokens array
* @param {number=} pieceNum
*/
constructor(pathOrString: string | string[], pieceNum?: number);
getFront(): string | null;
/**
* @return {number} The number of segments in this path
*/
getLength(): number;
/**
* @return {!Path}
*/
popFront(): Path;
/**
* @return {?string}
*/
getBack(): string | null;
toString(): string;
toUrlEncodedString(): string;
/**
* Shallow copy of the parts of the path.
*
* @param {number=} begin
* @return {!Array<string>}
*/
slice(begin?: number): string[];
/**
* @return {?Path}
*/
parent(): Path | null;
/**
* @param {string|!Path} childPathObj
* @return {!Path}
*/
child(childPathObj: string | Path): Path;
/**
* @return {boolean} True if there are no segments in this path
*/
isEmpty(): boolean;
/**
* @param {!Path} outerPath
* @param {!Path} innerPath
* @return {!Path} The path from outerPath to innerPath
*/
static relativePath(outerPath: Path, innerPath: Path): Path;
/**
* @param {!Path} left
* @param {!Path} right
* @return {number} -1, 0, 1 if left is less, equal, or greater than the right.
*/
static comparePaths(left: Path, right: Path): number;
/**
*
* @param {Path} other
* @return {boolean} true if paths are the same.
*/
equals(other: Path): boolean;
/**
*
* @param {!Path} other
* @return {boolean} True if this path is a parent (or the same as) other
*/
contains(other: Path): boolean;
}
/**
* Dynamic (mutable) path used to count path lengths.
*
* This class is used to efficiently check paths for valid
* length (in UTF8 bytes) and depth (used in path validation).
*
* Throws Error exception if path is ever invalid.
*
* The definition of a path always begins with '/'.
*/
export declare class ValidationPath {
private errorPrefix_;
/** @type {!Array<string>} */
private parts_;
/** @type {number} Initialize to number of '/' chars needed in path. */
private byteLength_;
/**
* @param {!Path} path Initial Path.
* @param {string} errorPrefix_ Prefix for any error messages.
*/
constructor(path: Path, errorPrefix_: string);
/** @const {number} Maximum key depth. */
static readonly MAX_PATH_DEPTH: number;
/** @const {number} Maximum number of (UTF8) bytes in a Firebase path. */
static readonly MAX_PATH_LENGTH_BYTES: number;
/** @param {string} child */
push(child: string): void;
pop(): void;
private checkValid_;
/**
* String for use in error messages - uses '.' notation for path.
*
* @return {string}
*/
toErrorString(): string;
}
+57
View File
@@ -0,0 +1,57 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { SparseSnapshotTree } from '../SparseSnapshotTree';
import { Node } from '../snap/Node';
/**
* Generate placeholders for deferred values.
* @param {?Object} values
* @return {!Object}
*/
export declare const generateWithValues: (values: {
[k: string]: any;
}) => {
[k: string]: any;
};
/**
* Value to use when firing local events. When writing server values, fire
* local events with an approximate value, otherwise return value as-is.
* @param {(Object|string|number|boolean)} value
* @param {!Object} serverValues
* @return {!(string|number|boolean)}
*/
export declare const resolveDeferredValue: (value: string | number | boolean | {
[k: string]: any;
}, serverValues: {
[k: string]: any;
}) => string | number | boolean;
/**
* Recursively replace all deferred values and priorities in the tree with the
* specified generated replacement values.
* @param {!SparseSnapshotTree} tree
* @param {!Object} serverValues
* @return {!SparseSnapshotTree}
*/
export declare const resolveDeferredValueTree: (tree: SparseSnapshotTree, serverValues: Object) => SparseSnapshotTree;
/**
* Recursively replace all deferred values and priorities in the node with the
* specified generated replacement values. If there are no server values in the node,
* it'll be returned as-is.
* @param {!Node} node
* @param {!Object} serverValues
* @return {!Node}
*/
export declare const resolveDeferredValueSnapshot: (node: Node, serverValues: Object) => Node;
+362
View File
@@ -0,0 +1,362 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Implementation of an immutable SortedMap using a Left-leaning
* Red-Black Tree, adapted from the implementation in Mugs
* (http://mads379.github.com/mugs/) by Mads Hartmann Jensen
* (mads379@gmail.com).
*
* Original paper on Left-leaning Red-Black Trees:
* http://www.cs.princeton.edu/~rs/talks/LLRB/LLRB.pdf
*
* Invariant 1: No red node has a red child
* Invariant 2: Every leaf path has the same number of black nodes
* Invariant 3: Only the left child can be red (left leaning)
*/
export declare type Comparator<K> = (key1: K, key2: K) => number;
/**
* An iterator over an LLRBNode.
*/
export declare class SortedMapIterator<K, V, T> {
private isReverse_;
private resultGenerator_;
/** @private
* @type {Array.<!LLRBNode>}
*/
private nodeStack_;
/**
* @template K, V, T
* @param {LLRBNode|LLRBEmptyNode} node Node to iterate.
* @param {?K} startKey
* @param {function(K, K): number} comparator
* @param {boolean} isReverse_ Whether or not to iterate in reverse
* @param {(function(K, V):T)=} resultGenerator_
*/
constructor(node: LLRBNode<K, V> | LLRBEmptyNode<K, V>, startKey: K | null, comparator: Comparator<K>, isReverse_: boolean, resultGenerator_?: ((k: K, v: V) => T) | null);
getNext(): T;
hasNext(): boolean;
peek(): T;
}
/**
* Represents a node in a Left-leaning Red-Black tree.
*/
export declare class LLRBNode<K, V> {
key: K;
value: V;
color: boolean;
left: LLRBNode<K, V> | LLRBEmptyNode<K, V>;
right: LLRBNode<K, V> | LLRBEmptyNode<K, V>;
/**
* @template K, V
* @param {!K} key Key associated with this node.
* @param {!V} value Value associated with this node.
* @param {?boolean} color Whether this node is red.
* @param {?(LLRBNode|LLRBEmptyNode)=} left Left child.
* @param {?(LLRBNode|LLRBEmptyNode)=} right Right child.
*/
constructor(key: K, value: V, color: boolean | null, left?: LLRBNode<K, V> | LLRBEmptyNode<K, V> | null, right?: LLRBNode<K, V> | LLRBEmptyNode<K, V> | null);
static RED: boolean;
static BLACK: boolean;
/**
* Returns a copy of the current node, optionally replacing pieces of it.
*
* @param {?K} key New key for the node, or null.
* @param {?V} value New value for the node, or null.
* @param {?boolean} color New color for the node, or null.
* @param {?LLRBNode|LLRBEmptyNode} left New left child for the node, or null.
* @param {?LLRBNode|LLRBEmptyNode} right New right child for the node, or null.
* @return {!LLRBNode} The node copy.
*/
copy(key: K | null, value: V | null, color: boolean | null, left: LLRBNode<K, V> | LLRBEmptyNode<K, V> | null, right: LLRBNode<K, V> | LLRBEmptyNode<K, V> | null): LLRBNode<K, V>;
/**
* @return {number} The total number of nodes in the tree.
*/
count(): number;
/**
* @return {boolean} True if the tree is empty.
*/
isEmpty(): boolean;
/**
* Traverses the tree in key order and calls the specified action function
* for each node.
*
* @param {function(!K, !V):*} action Callback function to be called for each
* node. If it returns true, traversal is aborted.
* @return {*} The first truthy value returned by action, or the last falsey
* value returned by action
*/
inorderTraversal(action: (k: K, v: V) => any): boolean;
/**
* Traverses the tree in reverse key order and calls the specified action function
* for each node.
*
* @param {function(!Object, !Object)} action Callback function to be called for each
* node. If it returns true, traversal is aborted.
* @return {*} True if traversal was aborted.
*/
reverseTraversal(action: (k: K, v: V) => void): boolean;
/**
* @return {!Object} The minimum node in the tree.
* @private
*/
private min_;
/**
* @return {!K} The maximum key in the tree.
*/
minKey(): K;
/**
* @return {!K} The maximum key in the tree.
*/
maxKey(): K;
/**
*
* @param {!Object} key Key to insert.
* @param {!Object} value Value to insert.
* @param {Comparator} comparator Comparator.
* @return {!LLRBNode} New tree, with the key/value added.
*/
insert(key: K, value: V, comparator: Comparator<K>): LLRBNode<K, V>;
/**
* @private
* @return {!LLRBNode|LLRBEmptyNode} New tree, with the minimum key removed.
*/
private removeMin_;
/**
* @param {!Object} key The key of the item to remove.
* @param {Comparator} comparator Comparator.
* @return {!LLRBNode|LLRBEmptyNode} New tree, with the specified item removed.
*/
remove(key: K, comparator: Comparator<K>): LLRBNode<K, V> | LLRBEmptyNode<K, V>;
/**
* @private
* @return {boolean} Whether this is a RED node.
*/
isRed_(): boolean;
/**
* @private
* @return {!LLRBNode} New tree after performing any needed rotations.
*/
private fixUp_;
/**
* @private
* @return {!LLRBNode} New tree, after moveRedLeft.
*/
private moveRedLeft_;
/**
* @private
* @return {!LLRBNode} New tree, after moveRedRight.
*/
private moveRedRight_;
/**
* @private
* @return {!LLRBNode} New tree, after rotateLeft.
*/
private rotateLeft_;
/**
* @private
* @return {!LLRBNode} New tree, after rotateRight.
*/
private rotateRight_;
/**
* @private
* @return {!LLRBNode} New tree, after colorFlip.
*/
private colorFlip_;
/**
* For testing.
*
* @private
* @return {boolean} True if all is well.
*/
private checkMaxDepth_;
/**
* @private
* @return {number} Not sure what this returns exactly. :-).
*/
check_(): number;
}
/**
* Represents an empty node (a leaf node in the Red-Black Tree).
*/
export declare class LLRBEmptyNode<K, V> {
key: K;
value: V;
left: LLRBNode<K, V> | LLRBEmptyNode<K, V>;
right: LLRBNode<K, V> | LLRBEmptyNode<K, V>;
color: boolean;
/**
* Returns a copy of the current node.
*
* @return {!LLRBEmptyNode} The node copy.
*/
copy(key: K | null, value: V | null, color: boolean | null, left: LLRBNode<K, V> | LLRBEmptyNode<K, V> | null, right: LLRBNode<K, V> | LLRBEmptyNode<K, V> | null): LLRBEmptyNode<K, V>;
/**
* Returns a copy of the tree, with the specified key/value added.
*
* @param {!K} key Key to be added.
* @param {!V} value Value to be added.
* @param {Comparator} comparator Comparator.
* @return {!LLRBNode} New tree, with item added.
*/
insert(key: K, value: V, comparator: Comparator<K>): LLRBNode<K, V>;
/**
* Returns a copy of the tree, with the specified key removed.
*
* @param {!K} key The key to remove.
* @param {Comparator} comparator Comparator.
* @return {!LLRBEmptyNode} New tree, with item removed.
*/
remove(key: K, comparator: Comparator<K>): LLRBEmptyNode<K, V>;
/**
* @return {number} The total number of nodes in the tree.
*/
count(): number;
/**
* @return {boolean} True if the tree is empty.
*/
isEmpty(): boolean;
/**
* Traverses the tree in key order and calls the specified action function
* for each node.
*
* @param {function(!K, !V):*} action Callback function to be called for each
* node. If it returns true, traversal is aborted.
* @return {boolean} True if traversal was aborted.
*/
inorderTraversal(action: (k: K, v: V) => any): boolean;
/**
* Traverses the tree in reverse key order and calls the specified action function
* for each node.
*
* @param {function(!K, !V)} action Callback function to be called for each
* node. If it returns true, traversal is aborted.
* @return {boolean} True if traversal was aborted.
*/
reverseTraversal(action: (k: K, v: V) => void): boolean;
/**
* @return {null}
*/
minKey(): null;
/**
* @return {null}
*/
maxKey(): null;
/**
* @private
* @return {number} Not sure what this returns exactly. :-).
*/
check_(): number;
/**
* @private
* @return {boolean} Whether this node is red.
*/
isRed_(): boolean;
}
/**
* An immutable sorted map implementation, based on a Left-leaning Red-Black
* tree.
*/
export declare class SortedMap<K, V> {
private comparator_;
private root_;
/**
* Always use the same empty node, to reduce memory.
* @const
*/
static EMPTY_NODE: LLRBEmptyNode<unknown, unknown>;
/**
* @template K, V
* @param {function(K, K):number} comparator_ Key comparator.
* @param {LLRBNode=} root_ (Optional) Root node for the map.
*/
constructor(comparator_: Comparator<K>, root_?: LLRBNode<K, V> | LLRBEmptyNode<K, V>);
/**
* Returns a copy of the map, with the specified key/value added or replaced.
* (TODO: We should perhaps rename this method to 'put')
*
* @param {!K} key Key to be added.
* @param {!V} value Value to be added.
* @return {!SortedMap.<K, V>} New map, with item added.
*/
insert(key: K, value: V): SortedMap<K, V>;
/**
* Returns a copy of the map, with the specified key removed.
*
* @param {!K} key The key to remove.
* @return {!SortedMap.<K, V>} New map, with item removed.
*/
remove(key: K): SortedMap<K, V>;
/**
* Returns the value of the node with the given key, or null.
*
* @param {!K} key The key to look up.
* @return {?V} The value of the node with the given key, or null if the
* key doesn't exist.
*/
get(key: K): V | null;
/**
* Returns the key of the item *before* the specified key, or null if key is the first item.
* @param {K} key The key to find the predecessor of
* @return {?K} The predecessor key.
*/
getPredecessorKey(key: K): K | null;
/**
* @return {boolean} True if the map is empty.
*/
isEmpty(): boolean;
/**
* @return {number} The total number of nodes in the map.
*/
count(): number;
/**
* @return {?K} The minimum key in the map.
*/
minKey(): K | null;
/**
* @return {?K} The maximum key in the map.
*/
maxKey(): K | null;
/**
* Traverses the map in key order and calls the specified action function
* for each key/value pair.
*
* @param {function(!K, !V):*} action Callback function to be called
* for each key/value pair. If action returns true, traversal is aborted.
* @return {*} The first truthy value returned by action, or the last falsey
* value returned by action
*/
inorderTraversal(action: (k: K, v: V) => any): boolean;
/**
* Traverses the map in reverse key order and calls the specified action function
* for each key/value pair.
*
* @param {function(!Object, !Object)} action Callback function to be called
* for each key/value pair. If action returns true, traversal is aborted.
* @return {*} True if the traversal was aborted.
*/
reverseTraversal(action: (k: K, v: V) => void): boolean;
/**
* Returns an iterator over the SortedMap.
* @template T
* @param {(function(K, V):T)=} resultGenerator
* @return {SortedMapIterator.<K, V, T>} The iterator.
*/
getIterator<T>(resultGenerator?: (k: K, v: V) => T): SortedMapIterator<K, V, T>;
getIteratorFrom<T>(key: K, resultGenerator?: (k: K, v: V) => T): SortedMapIterator<K, V, T>;
getReverseIteratorFrom<T>(key: K, resultGenerator?: (k: K, v: V) => T): SortedMapIterator<K, V, T>;
getReverseIterator<T>(resultGenerator?: (k: K, v: V) => T): SortedMapIterator<K, V, T>;
}
+134
View File
@@ -0,0 +1,134 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Path } from './Path';
/**
* Node in a Tree.
*/
export declare class TreeNode<T> {
children: {
[name: string]: TreeNode<T>;
};
childCount: number;
value: T | null;
}
/**
* A light-weight tree, traversable by path. Nodes can have both values and children.
* Nodes are not enumerated (by forEachChild) unless they have a value or non-empty
* children.
*/
export declare class Tree<T> {
private name_;
private parent_;
private node_;
/**
* @template T
* @param {string=} name_ Optional name of the node.
* @param {Tree=} parent_ Optional parent node.
* @param {TreeNode=} node_ Optional node to wrap.
*/
constructor(name_?: string, parent_?: Tree<T> | null, node_?: TreeNode<T>);
/**
* Returns a sub-Tree for the given path.
*
* @param {!(string|Path)} pathObj Path to look up.
* @return {!Tree.<T>} Tree for path.
*/
subTree(pathObj: string | Path): Tree<T>;
/**
* Returns the data associated with this tree node.
*
* @return {?T} The data or null if no data exists.
*/
getValue(): T | null;
/**
* Sets data to this tree node.
*
* @param {!T} value Value to set.
*/
setValue(value: T): void;
/**
* Clears the contents of the tree node (its value and all children).
*/
clear(): void;
/**
* @return {boolean} Whether the tree has any children.
*/
hasChildren(): boolean;
/**
* @return {boolean} Whether the tree is empty (no value or children).
*/
isEmpty(): boolean;
/**
* Calls action for each child of this tree node.
*
* @param {function(!Tree.<T>)} action Action to be called for each child.
*/
forEachChild(action: (tree: Tree<T>) => void): void;
/**
* Does a depth-first traversal of this node's descendants, calling action for each one.
*
* @param {function(!Tree.<T>)} action Action to be called for each child.
* @param {boolean=} includeSelf Whether to call action on this node as well. Defaults to
* false.
* @param {boolean=} childrenFirst Whether to call action on children before calling it on
* parent.
*/
forEachDescendant(action: (tree: Tree<T>) => void, includeSelf?: boolean, childrenFirst?: boolean): void;
/**
* Calls action on each ancestor node.
*
* @param {function(!Tree.<T>)} action Action to be called on each parent; return
* true to abort.
* @param {boolean=} includeSelf Whether to call action on this node as well.
* @return {boolean} true if the action callback returned true.
*/
forEachAncestor(action: (tree: Tree<T>) => unknown, includeSelf?: boolean): boolean;
/**
* Does a depth-first traversal of this node's descendants. When a descendant with a value
* is found, action is called on it and traversal does not continue inside the node.
* Action is *not* called on this node.
*
* @param {function(!Tree.<T>)} action Action to be called for each child.
*/
forEachImmediateDescendantWithValue(action: (tree: Tree<T>) => void): void;
/**
* @return {!Path} The path of this tree node, as a Path.
*/
path(): Path;
/**
* @return {string} The name of the tree node.
*/
name(): string;
/**
* @return {?Tree} The parent tree node, or null if this is the root of the tree.
*/
parent(): Tree<T> | null;
/**
* Adds or removes this child from its parent based on whether it's empty or not.
*
* @private
*/
private updateParents_;
/**
* Adds or removes the passed child to this tree node, depending on whether it's empty.
*
* @param {string} childName The name of the child to update.
* @param {!Tree.<T>} child The child to update.
* @private
*/
private updateChild_;
}
@@ -0,0 +1,30 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { EventEmitter } from './EventEmitter';
/**
* @extends {EventEmitter}
*/
export declare class VisibilityMonitor extends EventEmitter {
private visible_;
static getInstance(): VisibilityMonitor;
constructor();
/**
* @param {!string} eventType
* @return {Array.<boolean>}
*/
getInitialEvent(eventType: string): boolean[];
}
+42
View File
@@ -0,0 +1,42 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Path } from '../Path';
import { RepoInfo } from '../../RepoInfo';
/**
*
* @param {!string} dataURL
* @return {{repoInfo: !RepoInfo, path: !Path}}
*/
export declare const parseRepoInfo: (dataURL: string) => {
repoInfo: RepoInfo;
path: Path;
};
/**
*
* @param {!string} dataURL
* @return {{host: string, port: number, domain: string, subdomain: string, secure: boolean, scheme: string, pathString: string, namespace: string}}
*/
export declare const parseDatabaseURL: (dataURL: string) => {
host: string;
port: number;
domain: string;
subdomain: string;
secure: boolean;
scheme: string;
pathString: string;
namespace: string;
};
+233
View File
@@ -0,0 +1,233 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Query } from '../../api/Query';
/**
* Environment variable for enabling interaction with the Firebase Realtime Database
* emulator. If set, the module will present the endpoint with a fake "owner" credential
* (see EmulatorAuthTokenProvider) instead of one belonging to a real account.
*
* The expected format for this variable is '<HOST>:<PORT>'. The transfer protocol must be
* omitted and will default to 'http'.
*/
export declare const FIREBASE_DATABASE_EMULATOR_HOST_VAR = "FIREBASE_DATABASE_EMULATOR_HOST";
/**
* Returns a locally-unique ID (generated by just incrementing up from 0 each time its called).
* @type {function(): number} Generated ID.
*/
export declare const LUIDGenerator: () => number;
/**
* Sha1 hash of the input string
* @param {!string} str The string to hash
* @return {!string} The resulting hash
*/
export declare const sha1: (str: string) => string;
/**
* Use this for all debug messages in Firebase.
* @type {?function(string)}
*/
export declare let logger: ((a: string) => void) | null;
/**
* The implementation of Firebase.enableLogging (defined here to break dependencies)
* @param {boolean|?function(string)} logger_ A flag to turn on logging, or a custom logger
* @param {boolean=} persistent Whether or not to persist logging settings across refreshes
*/
export declare const enableLogging: (logger_?: boolean | ((a: string) => void), persistent?: boolean) => void;
/**
*
* @param {...(string|Arguments)} var_args
*/
export declare const log: (...var_args: string[]) => void;
/**
* @param {!string} prefix
* @return {function(...[*])}
*/
export declare const logWrapper: (prefix: string) => (...var_args: any[]) => void;
/**
* @param {...string} var_args
*/
export declare const error: (...var_args: string[]) => void;
/**
* @param {...string} var_args
*/
export declare const fatal: (...var_args: string[]) => never;
/**
* @param {...*} var_args
*/
export declare const warn: (...var_args: any[]) => void;
/**
* Logs a warning if the containing page uses https. Called when a call to new Firebase
* does not use https.
*/
export declare const warnIfPageIsSecure: () => void;
/**
* @param {!String} methodName
*/
export declare const warnAboutUnsupportedMethod: (methodName: string) => void;
/**
* Returns true if data is NaN, or +/- Infinity.
* @param {*} data
* @return {boolean}
*/
export declare const isInvalidJSONNumber: (data: any) => boolean;
/**
* @param {function()} fn
*/
export declare const executeWhenDOMReady: (fn: () => void) => void;
/**
* Minimum key name. Invalid for actual data, used as a marker to sort before any valid names
* @type {!string}
*/
export declare const MIN_NAME = "[MIN_NAME]";
/**
* Maximum key name. Invalid for actual data, used as a marker to sort above any valid names
* @type {!string}
*/
export declare const MAX_NAME = "[MAX_NAME]";
/**
* Compares valid Firebase key names, plus min and max name
* @param {!string} a
* @param {!string} b
* @return {!number}
*/
export declare const nameCompare: (a: string, b: string) => number;
/**
* @param {!string} a
* @param {!string} b
* @return {!number} comparison result.
*/
export declare const stringCompare: (a: string, b: string) => number;
/**
* @param {string} key
* @param {Object} obj
* @return {*}
*/
export declare const requireKey: (key: string, obj: {
[k: string]: any;
}) => any;
/**
* @param {*} obj
* @return {string}
*/
export declare const ObjectToUniqueKey: (obj: any) => string;
/**
* Splits a string into a number of smaller segments of maximum size
* @param {!string} str The string
* @param {!number} segsize The maximum number of chars in the string.
* @return {Array.<string>} The string, split into appropriately-sized chunks
*/
export declare const splitStringBySize: (str: string, segsize: number) => string[];
/**
* Apply a function to each (key, value) pair in an object or
* apply a function to each (index, value) pair in an array
* @param obj The object or array to iterate over
* @param fn The function to apply
*/
export declare function each(obj: object, fn: (k: string, v: any) => void): void;
/**
* Like goog.bind, but doesn't bother to create a closure if opt_context is null/undefined.
* @param {function(*)} callback Callback function.
* @param {?Object=} context Optional context to bind to.
* @return {function(*)}
*/
export declare const bindCallback: (callback: (a: any) => void, context?: object) => Function;
/**
* Borrowed from http://hg.secondlife.com/llsd/src/tip/js/typedarray.js (MIT License)
* I made one modification at the end and removed the NaN / Infinity
* handling (since it seemed broken [caused an overflow] and we don't need it). See MJL comments.
* @param {!number} v A double
* @return {string}
*/
export declare const doubleToIEEE754String: (v: number) => string;
/**
* Used to detect if we're in a Chrome content script (which executes in an
* isolated environment where long-polling doesn't work).
* @return {boolean}
*/
export declare const isChromeExtensionContentScript: () => boolean;
/**
* Used to detect if we're in a Windows 8 Store app.
* @return {boolean}
*/
export declare const isWindowsStoreApp: () => boolean;
/**
* Converts a server error code to a Javascript Error
* @param {!string} code
* @param {!Query} query
* @return {Error}
*/
export declare const errorForServerCode: (code: string, query: Query) => Error;
/**
* Used to test for integer-looking strings
* @type {RegExp}
* @private
*/
export declare const INTEGER_REGEXP_: RegExp;
/**
* If the string contains a 32-bit integer, return it. Else return null.
* @param {!string} str
* @return {?number}
*/
export declare const tryParseInt: (str: string) => number;
/**
* Helper to run some code but catch any exceptions and re-throw them later.
* Useful for preventing user callbacks from breaking internal code.
*
* Re-throwing the exception from a setTimeout is a little evil, but it's very
* convenient (we don't have to try to figure out when is a safe point to
* re-throw it), and the behavior seems reasonable:
*
* * If you aren't pausing on exceptions, you get an error in the console with
* the correct stack trace.
* * If you're pausing on all exceptions, the debugger will pause on your
* exception and then again when we rethrow it.
* * If you're only pausing on uncaught exceptions, the debugger will only pause
* on us re-throwing it.
*
* @param {!function()} fn The code to guard.
*/
export declare const exceptionGuard: (fn: () => void) => void;
/**
* Helper function to safely call opt_callback with the specified arguments. It:
* 1. Turns into a no-op if opt_callback is null or undefined.
* 2. Wraps the call inside exceptionGuard to prevent exceptions from breaking our state.
*
* @param {?Function=} callback Optional onComplete callback.
* @param {...*} var_args Arbitrary args to be passed to opt_onComplete
*/
export declare const callUserCallback: (callback?: Function, ...var_args: any[]) => void;
/**
* @return {boolean} true if we think we're currently being crawled.
*/
export declare const beingCrawled: () => boolean;
/**
* Export a property of an object using a getter function.
*
* @param {!Object} object
* @param {string} name
* @param {!function(): *} fnGet
*/
export declare const exportPropGetter: (object: Object, name: string, fnGet: () => any) => void;
/**
* Same as setTimeout() except on Node.JS it will /not/ prevent the process from exiting.
*
* It is removed with clearTimeout() as normal.
*
* @param {Function} fn Function to run.
* @param {number} time Milliseconds to wait before running.
* @return {number|Object} The setTimeout() return value.
*/
export declare const setTimeoutNonBlocking: (fn: Function, time: number) => number | Object;
+108
View File
@@ -0,0 +1,108 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Path, ValidationPath } from './Path';
import { RepoInfo } from '../RepoInfo';
/**
* True for invalid Firebase keys
* @type {RegExp}
* @private
*/
export declare const INVALID_KEY_REGEX_: RegExp;
/**
* True for invalid Firebase paths.
* Allows '/' in paths.
* @type {RegExp}
* @private
*/
export declare const INVALID_PATH_REGEX_: RegExp;
/**
* Maximum number of characters to allow in leaf value
* @type {number}
* @private
*/
export declare const MAX_LEAF_SIZE_: number;
/**
* @param {*} key
* @return {boolean}
*/
export declare const isValidKey: (key: any) => boolean;
/**
* @param {string} pathString
* @return {boolean}
*/
export declare const isValidPathString: (pathString: string) => boolean;
/**
* @param {string} pathString
* @return {boolean}
*/
export declare const isValidRootPathString: (pathString: string) => boolean;
/**
* @param {*} priority
* @return {boolean}
*/
export declare const isValidPriority: (priority: any) => boolean;
/**
* Pre-validate a datum passed as an argument to Firebase function.
*
* @param {string} fnName
* @param {number} argumentNumber
* @param {*} data
* @param {!Path} path
* @param {boolean} optional
*/
export declare const validateFirebaseDataArg: (fnName: string, argumentNumber: number, data: any, path: Path, optional: boolean) => void;
/**
* Validate a data object client-side before sending to server.
*
* @param {string} errorPrefix
* @param {*} data
* @param {!Path|!ValidationPath} path_
*/
export declare const validateFirebaseData: (errorPrefix: string, data: any, path_: Path | ValidationPath) => void;
/**
* Pre-validate paths passed in the firebase function.
*
* @param {string} errorPrefix
* @param {Array<!Path>} mergePaths
*/
export declare const validateFirebaseMergePaths: (errorPrefix: string, mergePaths: Path[]) => void;
/**
* pre-validate an object passed as an argument to firebase function (
* must be an object - e.g. for firebase.update()).
*
* @param {string} fnName
* @param {number} argumentNumber
* @param {*} data
* @param {!Path} path
* @param {boolean} optional
*/
export declare const validateFirebaseMergeDataArg: (fnName: string, argumentNumber: number, data: any, path: Path, optional: boolean) => void;
export declare const validatePriority: (fnName: string, argumentNumber: number, priority: any, optional: boolean) => void;
export declare const validateEventType: (fnName: string, argumentNumber: number, eventType: string, optional: boolean) => void;
export declare const validateKey: (fnName: string, argumentNumber: number, key: string, optional: boolean) => void;
export declare const validatePathString: (fnName: string, argumentNumber: number, pathString: string, optional: boolean) => void;
export declare const validateRootPathString: (fnName: string, argumentNumber: number, pathString: string, optional: boolean) => void;
export declare const validateWritablePath: (fnName: string, path: Path) => void;
export declare const validateUrl: (fnName: string, argumentNumber: number, parsedUrl: {
repoInfo: RepoInfo;
path: Path;
}) => void;
export declare const validateCredential: (fnName: string, argumentNumber: number, cred: any, optional: boolean) => void;
export declare const validateBoolean: (fnName: string, argumentNumber: number, bool: any, optional: boolean) => void;
export declare const validateString: (fnName: string, argumentNumber: number, string: any, optional: boolean) => void;
export declare const validateObject: (fnName: string, argumentNumber: number, obj: any, optional: boolean) => void;
export declare const validateObjectContainsKey: (fnName: string, argumentNumber: number, obj: any, key: string, optional: boolean, opt_type?: string) => void;
+19
View File
@@ -0,0 +1,19 @@
/**
* @license
* Copyright 2019 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/** The semver (www.semver.org) version of the SDK. */
export declare let SDK_VERSION: string;
export declare function setSDKVersion(version: string): void;
+59
View File
@@ -0,0 +1,59 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Node } from '../snap/Node';
import { Path } from '../util/Path';
/**
* A cache node only stores complete children. Additionally it holds a flag whether the node can be considered fully
* initialized in the sense that we know at one point in time this represented a valid state of the world, e.g.
* initialized with data from the server, or a complete overwrite by the client. The filtered flag also tracks
* whether a node potentially had children removed due to a filter.
*/
export declare class CacheNode {
private node_;
private fullyInitialized_;
private filtered_;
/**
* @param {!Node} node_
* @param {boolean} fullyInitialized_
* @param {boolean} filtered_
*/
constructor(node_: Node, fullyInitialized_: boolean, filtered_: boolean);
/**
* Returns whether this node was fully initialized with either server data or a complete overwrite by the client
* @return {boolean}
*/
isFullyInitialized(): boolean;
/**
* Returns whether this node is potentially missing children due to a filter applied to the node
* @return {boolean}
*/
isFiltered(): boolean;
/**
* @param {!Path} path
* @return {boolean}
*/
isCompleteForPath(path: Path): boolean;
/**
* @param {!string} key
* @return {boolean}
*/
isCompleteForChild(key: string): boolean;
/**
* @return {!Node}
*/
getNode(): Node;
}
+74
View File
@@ -0,0 +1,74 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Node } from '../snap/Node';
/**
* @constructor
* @struct
* @param {!string} type The event type
* @param {!Node} snapshotNode The data
* @param {string=} childName The name for this child, if it's a child event
* @param {Node=} oldSnap Used for intermediate processing of child changed events
* @param {string=} prevName The name for the previous child, if applicable
*/
export declare class Change {
type: string;
snapshotNode: Node;
childName?: string;
oldSnap?: Node;
prevName?: string | null;
constructor(type: string, snapshotNode: Node, childName?: string, oldSnap?: Node, prevName?: string | null);
/**
* @param {!Node} snapshot
* @return {!Change}
*/
static valueChange(snapshot: Node): Change;
/**
* @param {string} childKey
* @param {!Node} snapshot
* @return {!Change}
*/
static childAddedChange(childKey: string, snapshot: Node): Change;
/**
* @param {string} childKey
* @param {!Node} snapshot
* @return {!Change}
*/
static childRemovedChange(childKey: string, snapshot: Node): Change;
/**
* @param {string} childKey
* @param {!Node} newSnapshot
* @param {!Node} oldSnapshot
* @return {!Change}
*/
static childChangedChange(childKey: string, newSnapshot: Node, oldSnapshot: Node): Change;
/**
* @param {string} childKey
* @param {!Node} snapshot
* @return {!Change}
*/
static childMovedChange(childKey: string, snapshot: Node): Change;
/** Event type for a child added */
static CHILD_ADDED: string;
/** Event type for a child removed */
static CHILD_REMOVED: string;
/** Event type for a child changed */
static CHILD_CHANGED: string;
/** Event type for a child moved */
static CHILD_MOVED: string;
/** Event type for a value change */
static VALUE: string;
}
@@ -0,0 +1,22 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Change } from './Change';
export declare class ChildChangeAccumulator {
private readonly changeMap;
trackChildChange(change: Change): void;
getChanges(): Change[];
}
@@ -0,0 +1,91 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { NamedNode, Node } from '../snap/Node';
import { Index } from '../snap/indexes/Index';
import { WriteTreeRef } from '../WriteTree';
import { ViewCache } from './ViewCache';
/**
* Since updates to filtered nodes might require nodes to be pulled in from "outside" the node, this interface
* can help to get complete children that can be pulled in.
* A class implementing this interface takes potentially multiple sources (e.g. user writes, server data from
* other views etc.) to try it's best to get a complete child that might be useful in pulling into the view.
*
* @interface
*/
export interface CompleteChildSource {
/**
* @param {!string} childKey
* @return {?Node}
*/
getCompleteChild(childKey: string): Node | null;
/**
* @param {!Index} index
* @param {!NamedNode} child
* @param {boolean} reverse
* @return {?NamedNode}
*/
getChildAfterChild(index: Index, child: NamedNode, reverse: boolean): NamedNode | null;
}
/**
* An implementation of CompleteChildSource that never returns any additional children
*
* @private
* @constructor
* @implements CompleteChildSource
*/
export declare class NoCompleteChildSource_ implements CompleteChildSource {
/**
* @inheritDoc
*/
getCompleteChild(childKey?: string): Node | null;
/**
* @inheritDoc
*/
getChildAfterChild(index?: Index, child?: NamedNode, reverse?: boolean): NamedNode | null;
}
/**
* Singleton instance.
* @const
* @type {!CompleteChildSource}
*/
export declare const NO_COMPLETE_CHILD_SOURCE: NoCompleteChildSource_;
/**
* An implementation of CompleteChildSource that uses a WriteTree in addition to any other server data or
* old event caches available to calculate complete children.
*
*
* @implements CompleteChildSource
*/
export declare class WriteTreeCompleteChildSource implements CompleteChildSource {
private writes_;
private viewCache_;
private optCompleteServerCache_;
/**
* @param {!WriteTreeRef} writes_
* @param {!ViewCache} viewCache_
* @param {?Node} optCompleteServerCache_
*/
constructor(writes_: WriteTreeRef, viewCache_: ViewCache, optCompleteServerCache_?: Node | null);
/**
* @inheritDoc
*/
getCompleteChild(childKey: string): Node | null;
/**
* @inheritDoc
*/
getChildAfterChild(index: Index, child: NamedNode, reverse: boolean): NamedNode | null;
}
+101
View File
@@ -0,0 +1,101 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Path } from '../util/Path';
import { EventRegistration } from './EventRegistration';
import { DataSnapshot } from '../../api/DataSnapshot';
/**
* Encapsulates the data needed to raise an event
* @interface
*/
export interface Event {
/**
* @return {!Path}
*/
getPath(): Path;
/**
* @return {!string}
*/
getEventType(): string;
/**
* @return {!function()}
*/
getEventRunner(): () => void;
/**
* @return {!string}
*/
toString(): string;
}
/**
* Encapsulates the data needed to raise an event
* @implements {Event}
*/
export declare class DataEvent implements Event {
eventType: 'value' | ' child_added' | ' child_changed' | ' child_moved' | ' child_removed';
eventRegistration: EventRegistration;
snapshot: DataSnapshot;
prevName?: string | null;
/**
* @param {!string} eventType One of: value, child_added, child_changed, child_moved, child_removed
* @param {!EventRegistration} eventRegistration The function to call to with the event data. User provided
* @param {!DataSnapshot} snapshot The data backing the event
* @param {?string=} prevName Optional, the name of the previous child for child_* events.
*/
constructor(eventType: 'value' | ' child_added' | ' child_changed' | ' child_moved' | ' child_removed', eventRegistration: EventRegistration, snapshot: DataSnapshot, prevName?: string | null);
/**
* @inheritDoc
*/
getPath(): Path;
/**
* @inheritDoc
*/
getEventType(): string;
/**
* @inheritDoc
*/
getEventRunner(): () => void;
/**
* @inheritDoc
*/
toString(): string;
}
export declare class CancelEvent implements Event {
eventRegistration: EventRegistration;
error: Error;
path: Path;
/**
* @param {EventRegistration} eventRegistration
* @param {Error} error
* @param {!Path} path
*/
constructor(eventRegistration: EventRegistration, error: Error, path: Path);
/**
* @inheritDoc
*/
getPath(): Path;
/**
* @inheritDoc
*/
getEventType(): string;
/**
* @inheritDoc
*/
getEventRunner(): () => void;
/**
* @inheritDoc
*/
toString(): string;
}
+77
View File
@@ -0,0 +1,77 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Node } from '../snap/Node';
import { Change } from './Change';
import { Query } from '../../api/Query';
import { EventRegistration } from './EventRegistration';
import { Event } from './Event';
/**
* An EventGenerator is used to convert "raw" changes (Change) as computed by the
* CacheDiffer into actual events (Event) that can be raised. See generateEventsForChanges()
* for details.
*
* @constructor
*/
export declare class EventGenerator {
private query_;
private index_;
/**
*
* @param {!Query} query_
*/
constructor(query_: Query);
/**
* Given a set of raw changes (no moved events and prevName not specified yet), and a set of
* EventRegistrations that should be notified of these changes, generate the actual events to be raised.
*
* Notes:
* - child_moved events will be synthesized at this time for any child_changed events that affect
* our index.
* - prevName will be calculated based on the index ordering.
*
* @param {!Array.<!Change>} changes
* @param {!Node} eventCache
* @param {!Array.<!EventRegistration>} eventRegistrations
* @return {!Array.<!Event>}
*/
generateEventsForChanges(changes: Change[], eventCache: Node, eventRegistrations: EventRegistration[]): Event[];
/**
* Given changes of a single change type, generate the corresponding events.
*
* @param {!Array.<!Event>} events
* @param {!string} eventType
* @param {!Array.<!Change>} changes
* @param {!Array.<!EventRegistration>} registrations
* @param {!Node} eventCache
* @private
*/
private generateEventsForType_;
/**
* @param {!Change} change
* @param {!Node} eventCache
* @return {!Change}
* @private
*/
private materializeSingleChange_;
/**
* @param {!Change} a
* @param {!Change} b
* @return {number}
* @private
*/
private compareChanges_;
}
+99
View File
@@ -0,0 +1,99 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Path } from '../util/Path';
import { Event } from './Event';
/**
* The event queue serves a few purposes:
* 1. It ensures we maintain event order in the face of event callbacks doing operations that result in more
* events being queued.
* 2. raiseQueuedEvents() handles being called reentrantly nicely. That is, if in the course of raising events,
* raiseQueuedEvents() is called again, the "inner" call will pick up raising events where the "outer" call
* left off, ensuring that the events are still raised synchronously and in order.
* 3. You can use raiseEventsAtPath and raiseEventsForChangedPath to ensure only relevant previously-queued
* events are raised synchronously.
*
* NOTE: This can all go away if/when we move to async events.
*
* @constructor
*/
export declare class EventQueue {
/**
* @private
* @type {!Array.<EventList>}
*/
private eventLists_;
/**
* Tracks recursion depth of raiseQueuedEvents_, for debugging purposes.
* @private
* @type {!number}
*/
private recursionDepth_;
/**
* @param {!Array.<Event>} eventDataList The new events to queue.
*/
queueEvents(eventDataList: Event[]): void;
/**
* Queues the specified events and synchronously raises all events (including previously queued ones)
* for the specified path.
*
* It is assumed that the new events are all for the specified path.
*
* @param {!Path} path The path to raise events for.
* @param {!Array.<Event>} eventDataList The new events to raise.
*/
raiseEventsAtPath(path: Path, eventDataList: Event[]): void;
/**
* Queues the specified events and synchronously raises all events (including previously queued ones) for
* locations related to the specified change path (i.e. all ancestors and descendants).
*
* It is assumed that the new events are all related (ancestor or descendant) to the specified path.
*
* @param {!Path} changedPath The path to raise events for.
* @param {!Array.<!Event>} eventDataList The events to raise
*/
raiseEventsForChangedPath(changedPath: Path, eventDataList: Event[]): void;
/**
* @param {!function(!Path):boolean} predicate
* @private
*/
private raiseQueuedEventsMatchingPredicate_;
}
/**
* @param {!Path} path
* @constructor
*/
export declare class EventList {
private readonly path_;
/**
* @type {!Array.<Event>}
* @private
*/
private events_;
constructor(path_: Path);
/**
* @param {!Event} eventData
*/
add(eventData: Event): void;
/**
* Iterates through the list and raises each event
*/
raise(): void;
/**
* @return {!Path}
*/
getPath(): Path;
}
@@ -0,0 +1,154 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { DataSnapshot } from '../../api/DataSnapshot';
import { DataEvent, CancelEvent, Event } from './Event';
import { Path } from '../util/Path';
import { Change } from './Change';
import { Query } from '../../api/Query';
/**
* An EventRegistration is basically an event type ('value', 'child_added', etc.) and a callback
* to be notified of that type of event.
*
* That said, it can also contain a cancel callback to be notified if the event is canceled. And
* currently, this code is organized around the idea that you would register multiple child_ callbacks
* together, as a single EventRegistration. Though currently we don't do that.
*/
export interface EventRegistration {
/**
* True if this container has a callback to trigger for this event type
* @param {!string} eventType
* @return {boolean}
*/
respondsTo(eventType: string): boolean;
/**
* @param {!Change} change
* @param {!Query} query
* @return {!Event}
*/
createEvent(change: Change, query: Query): Event;
/**
* Given event data, return a function to trigger the user's callback
* @param {!Event} eventData
* @return {function()}
*/
getEventRunner(eventData: Event): () => void;
/**
* @param {!Error} error
* @param {!Path} path
* @return {?CancelEvent}
*/
createCancelEvent(error: Error, path: Path): CancelEvent | null;
/**
* @param {!EventRegistration} other
* @return {boolean}
*/
matches(other: EventRegistration): boolean;
/**
* False basically means this is a "dummy" callback container being used as a sentinel
* to remove all callback containers of a particular type. (e.g. if the user does
* ref.off('value') without specifying a specific callback).
*
* (TODO: Rework this, since it's hacky)
*
* @return {boolean}
*/
hasAnyCallback(): boolean;
}
/**
* Represents registration for 'value' events.
*/
export declare class ValueEventRegistration implements EventRegistration {
private callback_;
private cancelCallback_;
private context_;
/**
* @param {?function(!DataSnapshot)} callback_
* @param {?function(Error)} cancelCallback_
* @param {?Object} context_
*/
constructor(callback_: ((d: DataSnapshot) => void) | null, cancelCallback_: ((e: Error) => void) | null, context_: Object | null);
/**
* @inheritDoc
*/
respondsTo(eventType: string): boolean;
/**
* @inheritDoc
*/
createEvent(change: Change, query: Query): DataEvent;
/**
* @inheritDoc
*/
getEventRunner(eventData: CancelEvent | DataEvent): () => void;
/**
* @inheritDoc
*/
createCancelEvent(error: Error, path: Path): CancelEvent | null;
/**
* @inheritDoc
*/
matches(other: EventRegistration): boolean;
/**
* @inheritDoc
*/
hasAnyCallback(): boolean;
}
/**
* Represents the registration of 1 or more child_xxx events.
*
* Currently, it is always exactly 1 child_xxx event, but the idea is we might let you
* register a group of callbacks together in the future.
*
* @constructor
* @implements {EventRegistration}
*/
export declare class ChildEventRegistration implements EventRegistration {
private callbacks_;
private cancelCallback_;
private context_?;
/**
* @param {?Object.<string, function(!DataSnapshot, ?string=)>} callbacks_
* @param {?function(Error)} cancelCallback_
* @param {Object=} context_
*/
constructor(callbacks_: ({
[k: string]: (d: DataSnapshot, s?: string | null) => void;
}) | null, cancelCallback_: ((e: Error) => void) | null, context_?: Object);
/**
* @inheritDoc
*/
respondsTo(eventType: string): boolean;
/**
* @inheritDoc
*/
createCancelEvent(error: Error, path: Path): CancelEvent | null;
/**
* @inheritDoc
*/
createEvent(change: Change, query: Query): DataEvent;
/**
* @inheritDoc
*/
getEventRunner(eventData: CancelEvent | DataEvent): () => void;
/**
* @inheritDoc
*/
matches(other: EventRegistration): boolean;
/**
* @inheritDoc
*/
hasAnyCallback(): boolean;
}
+170
View File
@@ -0,0 +1,170 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { NodeFilter } from './filter/NodeFilter';
import { Index } from '../snap/indexes/Index';
/**
* This class is an immutable-from-the-public-api struct containing a set of query parameters defining a
* range to be returned for a particular location. It is assumed that validation of parameters is done at the
* user-facing API level, so it is not done here.
* @constructor
*/
export declare class QueryParams {
private limitSet_;
private startSet_;
private startNameSet_;
private endSet_;
private endNameSet_;
private limit_;
private viewFrom_;
private indexStartValue_;
private indexStartName_;
private indexEndValue_;
private indexEndName_;
private index_;
/**
* Wire Protocol Constants
* @const
* @enum {string}
* @private
*/
private static readonly WIRE_PROTOCOL_CONSTANTS_;
/**
* REST Query Constants
* @const
* @enum {string}
* @private
*/
private static readonly REST_QUERY_CONSTANTS_;
/**
* Default, empty query parameters
* @type {!QueryParams}
* @const
*/
static readonly DEFAULT: QueryParams;
/**
* @return {boolean}
*/
hasStart(): boolean;
/**
* @return {boolean} True if it would return from left.
*/
isViewFromLeft(): boolean;
/**
* Only valid to call if hasStart() returns true
* @return {*}
*/
getIndexStartValue(): any;
/**
* Only valid to call if hasStart() returns true.
* Returns the starting key name for the range defined by these query parameters
* @return {!string}
*/
getIndexStartName(): string;
/**
* @return {boolean}
*/
hasEnd(): boolean;
/**
* Only valid to call if hasEnd() returns true.
* @return {*}
*/
getIndexEndValue(): any;
/**
* Only valid to call if hasEnd() returns true.
* Returns the end key name for the range defined by these query parameters
* @return {!string}
*/
getIndexEndName(): string;
/**
* @return {boolean}
*/
hasLimit(): boolean;
/**
* @return {boolean} True if a limit has been set and it has been explicitly anchored
*/
hasAnchoredLimit(): boolean;
/**
* Only valid to call if hasLimit() returns true
* @return {!number}
*/
getLimit(): number;
/**
* @return {!Index}
*/
getIndex(): Index;
/**
* @return {!QueryParams}
* @private
*/
private copy_;
/**
* @param {!number} newLimit
* @return {!QueryParams}
*/
limit(newLimit: number): QueryParams;
/**
* @param {!number} newLimit
* @return {!QueryParams}
*/
limitToFirst(newLimit: number): QueryParams;
/**
* @param {!number} newLimit
* @return {!QueryParams}
*/
limitToLast(newLimit: number): QueryParams;
/**
* @param {*} indexValue
* @param {?string=} key
* @return {!QueryParams}
*/
startAt(indexValue: any, key?: string | null): QueryParams;
/**
* @param {*} indexValue
* @param {?string=} key
* @return {!QueryParams}
*/
endAt(indexValue: any, key?: string | null): QueryParams;
/**
* @param {!Index} index
* @return {!QueryParams}
*/
orderBy(index: Index): QueryParams;
/**
* @return {!Object}
*/
getQueryObject(): Object;
/**
* @return {boolean}
*/
loadsAllData(): boolean;
/**
* @return {boolean}
*/
isDefault(): boolean;
/**
* @return {!NodeFilter}
*/
getNodeFilter(): NodeFilter;
/**
* Returns a set of REST query string parameters representing this query.
*
* @return {!Object.<string,*>} query string parameters
*/
toRestQueryStringParameters(): {
[k: string]: any;
};
}
+97
View File
@@ -0,0 +1,97 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ViewCache } from './ViewCache';
import { Operation } from '../operation/Operation';
import { Change } from './Change';
import { Query } from '../../api/Query';
import { EventRegistration } from './EventRegistration';
import { Node } from '../snap/Node';
import { Path } from '../util/Path';
import { WriteTreeRef } from '../WriteTree';
import { Event } from './Event';
/**
* A view represents a specific location and query that has 1 or more event registrations.
*
* It does several things:
* - Maintains the list of event registrations for this location/query.
* - Maintains a cache of the data visible for this location/query.
* - Applies new operations (via applyOperation), updates the cache, and based on the event
* registrations returns the set of events to be raised.
* @constructor
*/
export declare class View {
private query_;
private processor_;
private viewCache_;
private eventRegistrations_;
private eventGenerator_;
/**
*
* @param {!Query} query_
* @param {!ViewCache} initialViewCache
*/
constructor(query_: Query, initialViewCache: ViewCache);
/**
* @return {!Query}
*/
getQuery(): Query;
/**
* @return {?Node}
*/
getServerCache(): Node | null;
/**
* @param {!Path} path
* @return {?Node}
*/
getCompleteServerCache(path: Path): Node | null;
/**
* @return {boolean}
*/
isEmpty(): boolean;
/**
* @param {!EventRegistration} eventRegistration
*/
addEventRegistration(eventRegistration: EventRegistration): void;
/**
* @param {?EventRegistration} eventRegistration If null, remove all callbacks.
* @param {Error=} cancelError If a cancelError is provided, appropriate cancel events will be returned.
* @return {!Array.<!Event>} Cancel events, if cancelError was provided.
*/
removeEventRegistration(eventRegistration: EventRegistration | null, cancelError?: Error): Event[];
/**
* Applies the given Operation, updates our cache, and returns the appropriate events.
*
* @param {!Operation} operation
* @param {!WriteTreeRef} writesCache
* @param {?Node} completeServerCache
* @return {!Array.<!Event>}
*/
applyOperation(operation: Operation, writesCache: WriteTreeRef, completeServerCache: Node | null): Event[];
/**
* @param {!EventRegistration} registration
* @return {!Array.<!Event>}
*/
getInitialEvents(registration: EventRegistration): Event[];
/**
* @private
* @param {!Array.<!Change>} changes
* @param {!Node} eventCache
* @param {EventRegistration=} eventRegistration
* @return {!Array.<!Event>}
*/
generateEventsForChanges_(changes: Change[], eventCache: Node, eventRegistration?: EventRegistration): Event[];
}
+70
View File
@@ -0,0 +1,70 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { CacheNode } from './CacheNode';
import { Node } from '../snap/Node';
/**
* Stores the data we have cached for a view.
*
* serverSnap is the cached server data, eventSnap is the cached event data (server data plus any local writes).
*
* @constructor
*/
export declare class ViewCache {
private readonly eventCache_;
private readonly serverCache_;
/**
*
* @param {!CacheNode} eventCache_
* @param {!CacheNode} serverCache_
*/
constructor(eventCache_: CacheNode, serverCache_: CacheNode);
/**
* @const
* @type {ViewCache}
*/
static Empty: ViewCache;
/**
* @param {!Node} eventSnap
* @param {boolean} complete
* @param {boolean} filtered
* @return {!ViewCache}
*/
updateEventSnap(eventSnap: Node, complete: boolean, filtered: boolean): ViewCache;
/**
* @param {!Node} serverSnap
* @param {boolean} complete
* @param {boolean} filtered
* @return {!ViewCache}
*/
updateServerSnap(serverSnap: Node, complete: boolean, filtered: boolean): ViewCache;
/**
* @return {!CacheNode}
*/
getEventCache(): CacheNode;
/**
* @return {?Node}
*/
getCompleteEventSnap(): Node | null;
/**
* @return {!CacheNode}
*/
getServerCache(): CacheNode;
/**
* @return {?Node}
*/
getCompleteServerSnap(): Node | null;
}
+166
View File
@@ -0,0 +1,166 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Operation } from '../operation/Operation';
import { ChildChangeAccumulator } from './ChildChangeAccumulator';
import { Change } from './Change';
import { Path } from '../util/Path';
import { ViewCache } from './ViewCache';
import { NodeFilter } from './filter/NodeFilter';
import { WriteTreeRef } from '../WriteTree';
import { Node } from '../snap/Node';
/**
* @constructor
* @struct
*/
export declare class ProcessorResult {
readonly viewCache: ViewCache;
readonly changes: Change[];
/**
* @param {!ViewCache} viewCache
* @param {!Array.<!Change>} changes
*/
constructor(viewCache: ViewCache, changes: Change[]);
}
/**
* @constructor
*/
export declare class ViewProcessor {
private readonly filter_;
/**
* @param {!NodeFilter} filter_
*/
constructor(filter_: NodeFilter);
/**
* @param {!ViewCache} viewCache
*/
assertIndexed(viewCache: ViewCache): void;
/**
* @param {!ViewCache} oldViewCache
* @param {!Operation} operation
* @param {!WriteTreeRef} writesCache
* @param {?Node} completeCache
* @return {!ProcessorResult}
*/
applyOperation(oldViewCache: ViewCache, operation: Operation, writesCache: WriteTreeRef, completeCache: Node | null): ProcessorResult;
/**
* @param {!ViewCache} oldViewCache
* @param {!ViewCache} newViewCache
* @param {!Array.<!Change>} accumulator
* @private
*/
private static maybeAddValueEvent_;
/**
* @param {!ViewCache} viewCache
* @param {!Path} changePath
* @param {!WriteTreeRef} writesCache
* @param {!CompleteChildSource} source
* @param {!ChildChangeAccumulator} accumulator
* @return {!ViewCache}
* @private
*/
private generateEventCacheAfterServerEvent_;
/**
* @param {!ViewCache} oldViewCache
* @param {!Path} changePath
* @param {!Node} changedSnap
* @param {!WriteTreeRef} writesCache
* @param {?Node} completeCache
* @param {boolean} filterServerNode
* @param {!ChildChangeAccumulator} accumulator
* @return {!ViewCache}
* @private
*/
applyServerOverwrite_(oldViewCache: ViewCache, changePath: Path, changedSnap: Node, writesCache: WriteTreeRef, completeCache: Node | null, filterServerNode: boolean, accumulator: ChildChangeAccumulator): ViewCache;
/**
* @param {!ViewCache} oldViewCache
* @param {!Path} changePath
* @param {!Node} changedSnap
* @param {!WriteTreeRef} writesCache
* @param {?Node} completeCache
* @param {!ChildChangeAccumulator} accumulator
* @return {!ViewCache}
* @private
*/
applyUserOverwrite_(oldViewCache: ViewCache, changePath: Path, changedSnap: Node, writesCache: WriteTreeRef, completeCache: Node | null, accumulator: ChildChangeAccumulator): ViewCache;
/**
* @param {!ViewCache} viewCache
* @param {string} childKey
* @return {boolean}
* @private
*/
private static cacheHasChild_;
/**
* @param {!ViewCache} viewCache
* @param {!Path} path
* @param {ImmutableTree.<!Node>} changedChildren
* @param {!WriteTreeRef} writesCache
* @param {?Node} serverCache
* @param {!ChildChangeAccumulator} accumulator
* @return {!ViewCache}
* @private
*/
private applyUserMerge_;
/**
* @param {!Node} node
* @param {ImmutableTree.<!Node>} merge
* @return {!Node}
* @private
*/
private applyMerge_;
/**
* @param {!ViewCache} viewCache
* @param {!Path} path
* @param {!ImmutableTree.<!Node>} changedChildren
* @param {!WriteTreeRef} writesCache
* @param {?Node} serverCache
* @param {boolean} filterServerNode
* @param {!ChildChangeAccumulator} accumulator
* @return {!ViewCache}
* @private
*/
private applyServerMerge_;
/**
* @param {!ViewCache} viewCache
* @param {!Path} ackPath
* @param {!ImmutableTree<!boolean>} affectedTree
* @param {!WriteTreeRef} writesCache
* @param {?Node} completeCache
* @param {!ChildChangeAccumulator} accumulator
* @return {!ViewCache}
* @private
*/
private ackUserWrite_;
/**
* @param {!ViewCache} viewCache
* @param {!Path} path
* @param {!WriteTreeRef} writesCache
* @param {!ChildChangeAccumulator} accumulator
* @return {!ViewCache}
* @private
*/
private listenComplete_;
/**
* @param {!ViewCache} viewCache
* @param {!Path} path
* @param {!WriteTreeRef} writesCache
* @param {?Node} completeServerCache
* @param {!ChildChangeAccumulator} accumulator
* @return {!ViewCache}
* @private
*/
private revertUserWrite_;
}
@@ -0,0 +1,54 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { NodeFilter } from './NodeFilter';
import { Index } from '../../snap/indexes/Index';
import { Path } from '../../util/Path';
import { CompleteChildSource } from '../CompleteChildSource';
import { ChildChangeAccumulator } from '../ChildChangeAccumulator';
import { Node } from '../../snap/Node';
/**
* Doesn't really filter nodes but applies an index to the node and keeps track of any changes
*
* @constructor
* @implements {NodeFilter}
* @param {!Index} index
*/
export declare class IndexedFilter implements NodeFilter {
private readonly index_;
constructor(index_: Index);
updateChild(snap: Node, key: string, newChild: Node, affectedPath: Path, source: CompleteChildSource, optChangeAccumulator: ChildChangeAccumulator | null): Node;
/**
* @inheritDoc
*/
updateFullNode(oldSnap: Node, newSnap: Node, optChangeAccumulator: ChildChangeAccumulator | null): Node;
/**
* @inheritDoc
*/
updatePriority(oldSnap: Node, newPriority: Node): Node;
/**
* @inheritDoc
*/
filtersNodes(): boolean;
/**
* @inheritDoc
*/
getIndexedFilter(): IndexedFilter;
/**
* @inheritDoc
*/
getIndex(): Index;
}
@@ -0,0 +1,94 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Node } from '../../snap/Node';
import { NodeFilter } from './NodeFilter';
import { Index } from '../../snap/indexes/Index';
import { IndexedFilter } from './IndexedFilter';
import { QueryParams } from '../QueryParams';
import { Path } from '../../util/Path';
import { CompleteChildSource } from '../CompleteChildSource';
import { ChildChangeAccumulator } from '../ChildChangeAccumulator';
/**
* Applies a limit and a range to a node and uses RangedFilter to do the heavy lifting where possible
*
* @constructor
* @implements {NodeFilter}
*/
export declare class LimitedFilter implements NodeFilter {
/**
* @const
* @type {RangedFilter}
* @private
*/
private readonly rangedFilter_;
/**
* @const
* @type {!Index}
* @private
*/
private readonly index_;
/**
* @const
* @type {number}
* @private
*/
private readonly limit_;
/**
* @const
* @type {boolean}
* @private
*/
private readonly reverse_;
/**
* @param {!QueryParams} params
*/
constructor(params: QueryParams);
/**
* @inheritDoc
*/
updateChild(snap: Node, key: string, newChild: Node, affectedPath: Path, source: CompleteChildSource, optChangeAccumulator: ChildChangeAccumulator | null): Node;
/**
* @inheritDoc
*/
updateFullNode(oldSnap: Node, newSnap: Node, optChangeAccumulator: ChildChangeAccumulator | null): Node;
/**
* @inheritDoc
*/
updatePriority(oldSnap: Node, newPriority: Node): Node;
/**
* @inheritDoc
*/
filtersNodes(): boolean;
/**
* @inheritDoc
*/
getIndexedFilter(): IndexedFilter;
/**
* @inheritDoc
*/
getIndex(): Index;
/**
* @param {!Node} snap
* @param {string} childKey
* @param {!Node} childSnap
* @param {!CompleteChildSource} source
* @param {?ChildChangeAccumulator} changeAccumulator
* @return {!Node}
* @private
*/
private fullLimitUpdateChild_;
}
@@ -0,0 +1,75 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Node } from '../../snap/Node';
import { Path } from '../../util/Path';
import { CompleteChildSource } from '../CompleteChildSource';
import { ChildChangeAccumulator } from '../ChildChangeAccumulator';
import { Index } from '../../snap/indexes/Index';
/**
* NodeFilter is used to update nodes and complete children of nodes while applying queries on the fly and keeping
* track of any child changes. This class does not track value changes as value changes depend on more
* than just the node itself. Different kind of queries require different kind of implementations of this interface.
* @interface
*/
export interface NodeFilter {
/**
* Update a single complete child in the snap. If the child equals the old child in the snap, this is a no-op.
* The method expects an indexed snap.
*
* @param {!Node} snap
* @param {string} key
* @param {!Node} newChild
* @param {!Path} affectedPath
* @param {!CompleteChildSource} source
* @param {?ChildChangeAccumulator} optChangeAccumulator
* @return {!Node}
*/
updateChild(snap: Node, key: string, newChild: Node, affectedPath: Path, source: CompleteChildSource, optChangeAccumulator: ChildChangeAccumulator | null): Node;
/**
* Update a node in full and output any resulting change from this complete update.
*
* @param {!Node} oldSnap
* @param {!Node} newSnap
* @param {?ChildChangeAccumulator} optChangeAccumulator
* @return {!Node}
*/
updateFullNode(oldSnap: Node, newSnap: Node, optChangeAccumulator: ChildChangeAccumulator | null): Node;
/**
* Update the priority of the root node
*
* @param {!Node} oldSnap
* @param {!Node} newPriority
* @return {!Node}
*/
updatePriority(oldSnap: Node, newPriority: Node): Node;
/**
* Returns true if children might be filtered due to query criteria
*
* @return {boolean}
*/
filtersNodes(): boolean;
/**
* Returns the index filter that this filter uses to get a NodeFilter that doesn't filter any children.
* @return {!NodeFilter}
*/
getIndexedFilter(): NodeFilter;
/**
* Returns the index that this filter uses
* @return {!Index}
*/
getIndex(): Index;
}
@@ -0,0 +1,109 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { IndexedFilter } from './IndexedFilter';
import { NamedNode, Node } from '../../../core/snap/Node';
import { NodeFilter } from './NodeFilter';
import { QueryParams } from '../QueryParams';
import { Index } from '../../snap/indexes/Index';
import { Path } from '../../util/Path';
import { CompleteChildSource } from '../CompleteChildSource';
import { ChildChangeAccumulator } from '../ChildChangeAccumulator';
/**
* Filters nodes by range and uses an IndexFilter to track any changes after filtering the node
*
* @constructor
* @implements {NodeFilter}
*/
export declare class RangedFilter implements NodeFilter {
/**
* @type {!IndexedFilter}
* @const
* @private
*/
private indexedFilter_;
/**
* @const
* @type {!Index}
* @private
*/
private index_;
/**
* @const
* @type {!NamedNode}
* @private
*/
private startPost_;
/**
* @const
* @type {!NamedNode}
* @private
*/
private endPost_;
/**
* @param {!QueryParams} params
*/
constructor(params: QueryParams);
/**
* @return {!NamedNode}
*/
getStartPost(): NamedNode;
/**
* @return {!NamedNode}
*/
getEndPost(): NamedNode;
/**
* @param {!NamedNode} node
* @return {boolean}
*/
matches(node: NamedNode): boolean;
/**
* @inheritDoc
*/
updateChild(snap: Node, key: string, newChild: Node, affectedPath: Path, source: CompleteChildSource, optChangeAccumulator: ChildChangeAccumulator | null): Node;
/**
* @inheritDoc
*/
updateFullNode(oldSnap: Node, newSnap: Node, optChangeAccumulator: ChildChangeAccumulator | null): Node;
/**
* @inheritDoc
*/
updatePriority(oldSnap: Node, newPriority: Node): Node;
/**
* @inheritDoc
*/
filtersNodes(): boolean;
/**
* @inheritDoc
*/
getIndexedFilter(): IndexedFilter;
/**
* @inheritDoc
*/
getIndex(): Index;
/**
* @param {!QueryParams} params
* @return {!NamedNode}
* @private
*/
private static getStartPost_;
/**
* @param {!QueryParams} params
* @return {!NamedNode}
* @private
*/
private static getEndPost_;
}
+17
View File
@@ -0,0 +1,17 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export {};
@@ -0,0 +1,206 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { PacketReceiver } from './polling/PacketReceiver';
import { Transport } from './Transport';
import { RepoInfo } from '../core/RepoInfo';
export declare const FIREBASE_LONGPOLL_START_PARAM = "start";
export declare const FIREBASE_LONGPOLL_CLOSE_COMMAND = "close";
export declare const FIREBASE_LONGPOLL_COMMAND_CB_NAME = "pLPCommand";
export declare const FIREBASE_LONGPOLL_DATA_CB_NAME = "pRTLPCB";
export declare const FIREBASE_LONGPOLL_ID_PARAM = "id";
export declare const FIREBASE_LONGPOLL_PW_PARAM = "pw";
export declare const FIREBASE_LONGPOLL_SERIAL_PARAM = "ser";
export declare const FIREBASE_LONGPOLL_CALLBACK_ID_PARAM = "cb";
export declare const FIREBASE_LONGPOLL_SEGMENT_NUM_PARAM = "seg";
export declare const FIREBASE_LONGPOLL_SEGMENTS_IN_PACKET = "ts";
export declare const FIREBASE_LONGPOLL_DATA_PARAM = "d";
export declare const FIREBASE_LONGPOLL_DISCONN_FRAME_PARAM = "disconn";
export declare const FIREBASE_LONGPOLL_DISCONN_FRAME_REQUEST_PARAM = "dframe";
/**
* This class manages a single long-polling connection.
*
* @constructor
* @implements {Transport}
*/
export declare class BrowserPollConnection implements Transport {
connId: string;
repoInfo: RepoInfo;
transportSessionId?: string;
lastSessionId?: string;
bytesSent: number;
bytesReceived: number;
urlFn: (params: object) => string;
scriptTagHolder: FirebaseIFrameScriptHolder;
myDisconnFrame: HTMLIFrameElement;
curSegmentNum: number;
myPacketOrderer: PacketReceiver;
id: string;
password: string;
private log_;
private stats_;
private everConnected_;
private isClosed_;
private connectTimeoutTimer_;
private onDisconnect_;
/**
* @param {string} connId An identifier for this connection, used for logging
* @param {RepoInfo} repoInfo The info for the endpoint to send data to.
* @param {string=} transportSessionId Optional transportSessionid if we are reconnecting for an existing
* transport session
* @param {string=} lastSessionId Optional lastSessionId if the PersistentConnection has already created a
* connection previously
*/
constructor(connId: string, repoInfo: RepoInfo, transportSessionId?: string, lastSessionId?: string);
/**
*
* @param {function(Object)} onMessage Callback when messages arrive
* @param {function()} onDisconnect Callback with connection lost.
*/
open(onMessage: (msg: Object) => void, onDisconnect: (a?: boolean) => void): void;
/**
* Call this when a handshake has completed successfully and we want to consider the connection established
*/
start(): void;
private static forceAllow_;
/**
* Forces long polling to be considered as a potential transport
*/
static forceAllow(): void;
private static forceDisallow_;
/**
* Forces longpolling to not be considered as a potential transport
*/
static forceDisallow(): void;
static isAvailable(): boolean;
/**
* No-op for polling
*/
markConnectionHealthy(): void;
/**
* Stops polling and cleans up the iframe
* @private
*/
private shutdown_;
/**
* Triggered when this transport is closed
* @private
*/
private onClosed_;
/**
* External-facing close handler. RealTime has requested we shut down. Kill our connection and tell the server
* that we've left.
*/
close(): void;
/**
* Send the JSON object down to the server. It will need to be stringified, base64 encoded, and then
* broken into chunks (since URLs have a small maximum length).
* @param {!Object} data The JSON data to transmit.
*/
send(data: Object): void;
/**
* This is how we notify the server that we're leaving.
* We aren't able to send requests with DHTML on a window close event, but we can
* trigger XHR requests in some browsers (everything but Opera basically).
* @param {!string} id
* @param {!string} pw
*/
addDisconnectPingFrame(id: string, pw: string): void;
/**
* Used to track the bytes received by this client
* @param {*} args
* @private
*/
private incrementIncomingBytes_;
}
export interface IFrameElement extends HTMLIFrameElement {
doc: Document;
}
/*********************************************************************************************
* A wrapper around an iframe that is used as a long-polling script holder.
* @constructor
*********************************************************************************************/
export declare class FirebaseIFrameScriptHolder {
onDisconnect: () => void;
urlFn: (a: object) => string;
outstandingRequests: Set<number>;
pendingSegs: {
seg: number;
ts: number;
d: any;
}[];
currentSerial: number;
sendNewPolls: boolean;
uniqueCallbackIdentifier: number;
myIFrame: IFrameElement;
alive: boolean;
myID: string;
myPW: string;
commandCB: (command: string, ...args: any[]) => void;
onMessageCB: (...args: any[]) => void;
/**
* @param commandCB - The callback to be called when control commands are recevied from the server.
* @param onMessageCB - The callback to be triggered when responses arrive from the server.
* @param onDisconnect - The callback to be triggered when this tag holder is closed
* @param urlFn - A function that provides the URL of the endpoint to send data to.
*/
constructor(commandCB: (command: string, ...args: any[]) => void, onMessageCB: (...args: any[]) => void, onDisconnect: () => void, urlFn: (a: object) => string);
/**
* Each browser has its own funny way to handle iframes. Here we mush them all together into one object that I can
* actually use.
* @private
* @return {Element}
*/
private static createIFrame_;
/**
* Cancel all outstanding queries and remove the frame.
*/
close(): void;
/**
* Actually start the long-polling session by adding the first script tag(s) to the iframe.
* @param {!string} id - The ID of this connection
* @param {!string} pw - The password for this connection
*/
startLongPoll(id: string, pw: string): void;
/**
* This is called any time someone might want a script tag to be added. It adds a script tag when there aren't
* too many outstanding requests and we are still alive.
*
* If there are outstanding packet segments to send, it sends one. If there aren't, it sends a long-poll anyways if
* needed.
*/
private newRequest_;
/**
* Queue a packet for transmission to the server.
* @param segnum - A sequential id for this packet segment used for reassembly
* @param totalsegs - The total number of segments in this packet
* @param data - The data for this segment.
*/
enqueueSegment(segnum: number, totalsegs: number, data: any): void;
/**
* Add a script tag for a regular long-poll request.
* @param {!string} url - The URL of the script tag.
* @param {!number} serial - The serial number of the request.
* @private
*/
private addLongPollTag_;
/**
* Add an arbitrary script tag to the iframe.
* @param {!string} url - The URL for the script tag source.
* @param {!function()} loadCB - A callback to be triggered once the script has loaded.
*/
addTag(url: string, loadCB: () => void): void;
}
+117
View File
@@ -0,0 +1,117 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { RepoInfo } from '../core/RepoInfo';
/**
* Creates a new real-time connection to the server using whichever method works
* best in the current browser.
*
* @constructor
*/
export declare class Connection {
id: string;
private repoInfo_;
private onMessage_;
private onReady_;
private onDisconnect_;
private onKill_;
lastSessionId?: string;
connectionCount: number;
pendingDataMessages: any[];
sessionId: string;
private conn_;
private healthyTimeout_;
private isHealthy_;
private log_;
private primaryResponsesRequired_;
private rx_;
private secondaryConn_;
private secondaryResponsesRequired_;
private state_;
private transportManager_;
private tx_;
/**
* @param {!string} id - an id for this connection
* @param {!RepoInfo} repoInfo_ - the info for the endpoint to connect to
* @param {function(Object)} onMessage_ - the callback to be triggered when a server-push message arrives
* @param {function(number, string)} onReady_ - the callback to be triggered when this connection is ready to send messages.
* @param {function()} onDisconnect_ - the callback to be triggered when a connection was lost
* @param {function(string)} onKill_ - the callback to be triggered when this connection has permanently shut down.
* @param {string=} lastSessionId - last session id in persistent connection. is used to clean up old session in real-time server
*/
constructor(id: string, repoInfo_: RepoInfo, onMessage_: (a: Object) => void, onReady_: (a: number, b: string) => void, onDisconnect_: () => void, onKill_: (a: string) => void, lastSessionId?: string);
/**
* Starts a connection attempt
* @private
*/
private start_;
/**
* @return {!string}
* @private
*/
private nextTransportId_;
private disconnReceiver_;
private connReceiver_;
/**
*
* @param {Object} dataMsg An arbitrary data message to be sent to the server
*/
sendRequest(dataMsg: object): void;
tryCleanupConnection(): void;
private onSecondaryControl_;
private onSecondaryMessageReceived_;
private upgradeIfSecondaryHealthy_;
private proceedWithUpgrade_;
private onPrimaryMessageReceived_;
private onDataMessage_;
private onPrimaryResponse_;
private onControl_;
/**
*
* @param {Object} handshake The handshake data returned from the server
* @private
*/
private onHandshake_;
private tryStartUpgrade_;
private startUpgrade_;
private onReset_;
private onConnectionEstablished_;
private sendPingOnPrimaryIfNecessary_;
private onSecondaryConnectionLost_;
/**
*
* @param {boolean} everConnected Whether or not the connection ever reached a server. Used to determine if
* we should flush the host cache
* @private
*/
private onConnectionLost_;
/**
*
* @param {string} reason
* @private
*/
private onConnectionShutdown_;
private sendData_;
/**
* Cleans up this connection, calling the appropriate callbacks
*/
close(): void;
/**
*
* @private
*/
private closeConnections_;
}
+25
View File
@@ -0,0 +1,25 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export declare const PROTOCOL_VERSION = "5";
export declare const VERSION_PARAM = "v";
export declare const TRANSPORT_SESSION_PARAM = "s";
export declare const REFERER_PARAM = "r";
export declare const FORGE_REF = "f";
export declare const FORGE_DOMAIN = "firebaseio.com";
export declare const LAST_SESSION_PARAM = "ls";
export declare const WEBSOCKET = "websocket";
export declare const LONG_POLLING = "long_polling";
+65
View File
@@ -0,0 +1,65 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { RepoInfo } from '../core/RepoInfo';
export interface TransportConstructor {
new (connId: string, repoInfo: RepoInfo, transportSessionId?: string, lastSessionId?: string): Transport;
isAvailable: () => boolean;
responsesRequiredToBeHealthy?: number;
healthyTimeout?: number;
}
export declare abstract class Transport {
/**
* Bytes received since connection started.
* @type {number}
*/
abstract bytesReceived: number;
/**
* Bytes sent since connection started.
* @type {number}
*/
abstract bytesSent: number;
/**
* An identifier for this connection, used for logging
* @type {string}
*/
abstract connId: string;
/**
*
* @param {string} connId An identifier for this connection, used for logging
* @param {RepoInfo} repoInfo The info for the endpoint to send data to.
* @param {string=} transportSessionId Optional transportSessionId if this is connecting to an existing transport session
* @param {string=} lastSessionId Optional lastSessionId if there was a previous connection
* @interface
*/
constructor(connId: string, repoInfo: RepoInfo, transportSessionId?: string, lastSessionId?: string);
/**
* @param {function(Object)} onMessage Callback when messages arrive
* @param {function()} onDisconnect Callback with connection lost.
*/
abstract open(onMessage: (a: Object) => void, onDisconnect: (a?: boolean) => void): void;
abstract start(): void;
abstract close(): void;
/**
* @param {!Object} data The JSON data to transmit
*/
abstract send(data: Object): void;
abstract markConnectionHealthy(): void;
abstract markConnectionHealthy(): void;
}
export interface TransportConstructor {
new (connId: string, RepoInfo: any, transportSessionId?: string, lastSessionId?: string): any;
}
@@ -0,0 +1,55 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { BrowserPollConnection } from './BrowserPollConnection';
import { WebSocketConnection } from './WebSocketConnection';
import { TransportConstructor } from './Transport';
import { RepoInfo } from '../core/RepoInfo';
/**
* Currently simplistic, this class manages what transport a Connection should use at various stages of its
* lifecycle.
*
* It starts with longpolling in a browser, and httppolling on node. It then upgrades to websockets if
* they are available.
* @constructor
*/
export declare class TransportManager {
private transports_;
/**
* @const
* @type {!Array.<function(new:Transport, string, RepoInfo, string=)>}
*/
static readonly ALL_TRANSPORTS: (typeof BrowserPollConnection | typeof WebSocketConnection)[];
/**
* @param {!RepoInfo} repoInfo Metadata around the namespace we're connecting to
*/
constructor(repoInfo: RepoInfo);
/**
* @param {!RepoInfo} repoInfo
* @private
*/
private initTransports_;
/**
* @return {function(new:Transport, !string, !RepoInfo, string=, string=)} The constructor for the
* initial transport to use
*/
initialTransport(): TransportConstructor;
/**
* @return {?function(new:Transport, function(),function(), string=)} The constructor for the next
* transport, or null
*/
upgradeTransport(): TransportConstructor | null;
}
@@ -0,0 +1,130 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { RepoInfo } from '../core/RepoInfo';
import { Transport } from './Transport';
export declare function setWebSocketImpl(impl: any): void;
/**
* Create a new websocket connection with the given callbacks.
* @constructor
* @implements {Transport}
*/
export declare class WebSocketConnection implements Transport {
connId: string;
keepaliveTimer: number | null;
frames: string[] | null;
totalFrames: number;
bytesSent: number;
bytesReceived: number;
connURL: string;
onDisconnect: (a?: boolean) => void;
onMessage: (msg: Object) => void;
mySock: any | null;
private log_;
private stats_;
private everConnected_;
private isClosed_;
/**
* @param {string} connId identifier for this transport
* @param {RepoInfo} repoInfo The info for the websocket endpoint.
* @param {string=} transportSessionId Optional transportSessionId if this is connecting to an existing transport
* session
* @param {string=} lastSessionId Optional lastSessionId if there was a previous connection
*/
constructor(connId: string, repoInfo: RepoInfo, transportSessionId?: string, lastSessionId?: string);
/**
* @param {RepoInfo} repoInfo The info for the websocket endpoint.
* @param {string=} transportSessionId Optional transportSessionId if this is connecting to an existing transport
* session
* @param {string=} lastSessionId Optional lastSessionId if there was a previous connection
* @return {string} connection url
* @private
*/
private static connectionURL_;
/**
*
* @param onMessage Callback when messages arrive
* @param onDisconnect Callback with connection lost.
*/
open(onMessage: (msg: Object) => void, onDisconnect: (a?: boolean) => void): void;
/**
* No-op for websockets, we don't need to do anything once the connection is confirmed as open
*/
start(): void;
static forceDisallow_: Boolean;
static forceDisallow(): void;
static isAvailable(): boolean;
/**
* Number of response before we consider the connection "healthy."
* @type {number}
*/
static responsesRequiredToBeHealthy: number;
/**
* Time to wait for the connection te become healthy before giving up.
* @type {number}
*/
static healthyTimeout: number;
/**
* Returns true if we previously failed to connect with this transport.
* @return {boolean}
*/
static previouslyFailed(): boolean;
markConnectionHealthy(): void;
private appendFrame_;
/**
* @param {number} frameCount The number of frames we are expecting from the server
* @private
*/
private handleNewFrameCount_;
/**
* Attempts to parse a frame count out of some text. If it can't, assumes a value of 1
* @param {!String} data
* @return {?String} Any remaining data to be process, or null if there is none
* @private
*/
private extractFrameCount_;
/**
* Process a websocket frame that has arrived from the server.
* @param mess The frame data
*/
handleIncomingFrame(mess: {
[k: string]: any;
}): void;
/**
* Send a message to the server
* @param {Object} data The JSON object to transmit
*/
send(data: Object): void;
private shutdown_;
private onClosed_;
/**
* External-facing close handler.
* Close the websocket and kill the connection.
*/
close(): void;
/**
* Kill the current keepalive timer and start a new one, to ensure that it always fires N seconds after
* the last activity.
*/
resetKeepAlive(): void;
/**
* Send a string over the websocket.
*
* @param {string} str String to send.
* @private
*/
private sendString_;
}
@@ -0,0 +1,41 @@
/**
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* This class ensures the packets from the server arrive in order
* This class takes data from the server and ensures it gets passed into the callbacks in order.
* @constructor
*/
export declare class PacketReceiver {
private onMessage_;
pendingResponses: any[];
currentResponseNum: number;
closeAfterResponse: number;
onClose: (() => void) | null;
/**
* @param onMessage_
*/
constructor(onMessage_: (a: Object) => void);
closeAfter(responseNum: number, callback: () => void): void;
/**
* Each message from the server comes with a response number, and an array of data. The responseNumber
* allows us to ensure that we process them in the right order, since we can't be guaranteed that all
* browsers will respond in the same order as the requests we sent
* @param {number} requestNum
* @param {Array} data
*/
handleResponse(requestNum: number, data: any[]): void;
}