Deployed the page to Github Pages.

This commit is contained in:
Batuhan Berk Başoğlu 2024-11-03 21:30:09 -05:00
parent 1d79754e93
commit 2c89899458
Signed by: batuhan-basoglu
SSH key fingerprint: SHA256:kEsnuHX+qbwhxSAXPUQ4ox535wFHu/hIRaa53FzxRpo
62797 changed files with 6551425 additions and 15279 deletions

5
node_modules/@firebase/database/README.md generated vendored Normal file
View file

@ -0,0 +1,5 @@
# @firebase/database
This is the Firebase Realtime Database component of the Firebase JS SDK.
**This package is not intended for direct usage, and should only be used via the officially supported [firebase](https://www.npmjs.com/package/firebase) package.**

14062
node_modules/@firebase/database/dist/index.cjs.js generated vendored Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

14005
node_modules/@firebase/database/dist/index.esm2017.js generated vendored Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

14082
node_modules/@firebase/database/dist/index.node.cjs.js generated vendored Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

14024
node_modules/@firebase/database/dist/index.standalone.js generated vendored Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

2999
node_modules/@firebase/database/dist/internal.d.ts generated vendored Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1 @@
{"type":"module"}

View file

@ -0,0 +1,18 @@
/**
* @license
* Copyright 2021 Google LLC
*
* 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 * from './api.standalone';
export { getDatabase } from './api/Database';

View file

@ -0,0 +1,30 @@
/**
* @license
* Copyright 2021 Google LLC
*
* 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 { Database, EmulatorMockTokenOptions, enableLogging, goOffline, goOnline, forceWebSockets, forceLongPolling, connectDatabaseEmulator } from './api/Database';
export { Query, DatabaseReference, ListenOptions, Unsubscribe, ThenableReference } from './api/Reference';
export { OnDisconnect } from './api/OnDisconnect';
export { DataSnapshot, EventType, IteratedDataSnapshot, QueryConstraint, QueryConstraintType, endAt, endBefore, equalTo, get, limitToFirst, limitToLast, off, onChildAdded, onChildChanged, onChildMoved, onChildRemoved, onDisconnect, onValue, orderByChild, orderByKey, orderByPriority, orderByValue, push, query, ref, refFromURL, remove, set, setPriority, setWithPriority, startAfter, startAt, update, child } from './api/Reference_impl';
export { increment, serverTimestamp } from './api/ServerValue';
export { runTransaction, TransactionOptions, TransactionResult } from './api/Transaction';
export { setSDKVersion as _setSDKVersion } from './core/version';
export { ReferenceImpl as _ReferenceImpl, QueryImpl as _QueryImpl } from './api/Reference_impl';
export { repoManagerDatabaseFromApp as _repoManagerDatabaseFromApp } from './api/Database';
export { validatePathString as _validatePathString, validateWritablePath as _validateWritablePath } from './core/util/validation';
export { UserCallback as _UserCallback } from './core/view/EventRegistration';
export { QueryParams as _QueryParams } from './core/view/QueryParams';
export { hijackHash as _TEST_ACCESS_hijackHash, forceRestClient as _TEST_ACCESS_forceRestClient } from './api/test_access';
export * from './internal/index';

View file

@ -0,0 +1,137 @@
/**
* @license
* Copyright 2020 Google LLC
*
* 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 { _FirebaseService, FirebaseApp } from '@firebase/app';
import { AppCheckInternalComponentName } from '@firebase/app-check-interop-types';
import { FirebaseAuthInternalName } from '@firebase/auth-interop-types';
import { Provider } from '@firebase/component';
import { EmulatorMockTokenOptions } from '@firebase/util';
import { Repo } from '../core/Repo';
import { ReferenceImpl } from './Reference_impl';
export { EmulatorMockTokenOptions } from '@firebase/util';
/**
* This function should only ever be called to CREATE a new database instance.
* @internal
*/
export declare function repoManagerDatabaseFromApp(app: FirebaseApp, authProvider: Provider<FirebaseAuthInternalName>, appCheckProvider?: Provider<AppCheckInternalComponentName>, url?: string, nodeAdmin?: boolean): Database;
/**
* Forces us to use ReadonlyRestClient instead of PersistentConnection for new Repos.
*/
export declare function repoManagerForceRestClient(forceRestClient: boolean): void;
/**
* Class representing a Firebase Realtime Database.
*/
export declare class Database implements _FirebaseService {
_repoInternal: Repo;
/** The {@link @firebase/app#FirebaseApp} associated with this Realtime Database instance. */
readonly app: FirebaseApp;
/** Represents a `Database` instance. */
readonly 'type' = "database";
/** Track if the instance has been used (root or repo accessed) */
_instanceStarted: boolean;
/** Backing state for root_ */
private _rootInternal?;
/** @hideconstructor */
constructor(_repoInternal: Repo,
/** The {@link @firebase/app#FirebaseApp} associated with this Realtime Database instance. */
app: FirebaseApp);
get _repo(): Repo;
get _root(): ReferenceImpl;
_delete(): Promise<void>;
_checkNotDeleted(apiName: string): void;
}
/**
* Force the use of websockets instead of longPolling.
*/
export declare function forceWebSockets(): void;
/**
* Force the use of longPolling instead of websockets. This will be ignored if websocket protocol is used in databaseURL.
*/
export declare function forceLongPolling(): void;
/**
* Returns the instance of the Realtime Database SDK that is associated with the provided
* {@link @firebase/app#FirebaseApp}. Initializes a new instance with default settings if
* no instance exists or if the existing instance uses a custom database URL.
*
* @param app - The {@link @firebase/app#FirebaseApp} instance that the returned Realtime
* Database instance is associated with.
* @param url - The URL of the Realtime Database instance to connect to. If not
* provided, the SDK connects to the default instance of the Firebase App.
* @returns The `Database` instance of the provided app.
*/
export declare function getDatabase(app?: FirebaseApp, url?: string): Database;
/**
* Modify the provided instance to communicate with the Realtime Database
* emulator.
*
* <p>Note: This method must be called before performing any other operation.
*
* @param db - The instance to modify.
* @param host - The emulator host (ex: localhost)
* @param port - The emulator port (ex: 8080)
* @param options.mockUserToken - the mock auth token to use for unit testing Security Rules
*/
export declare function connectDatabaseEmulator(db: Database, host: string, port: number, options?: {
mockUserToken?: EmulatorMockTokenOptions | string;
}): void;
/**
* Disconnects from the server (all Database operations will be completed
* offline).
*
* The client automatically maintains a persistent connection to the Database
* server, which will remain active indefinitely and reconnect when
* disconnected. However, the `goOffline()` and `goOnline()` methods may be used
* to control the client connection in cases where a persistent connection is
* undesirable.
*
* While offline, the client will no longer receive data updates from the
* Database. However, all Database operations performed locally will continue to
* immediately fire events, allowing your application to continue behaving
* normally. Additionally, each operation performed locally will automatically
* be queued and retried upon reconnection to the Database server.
*
* To reconnect to the Database and begin receiving remote events, see
* `goOnline()`.
*
* @param db - The instance to disconnect.
*/
export declare function goOffline(db: Database): void;
/**
* Reconnects to the server and synchronizes the offline Database state
* with the server state.
*
* This method should be used after disabling the active connection with
* `goOffline()`. Once reconnected, the client will transmit the proper data
* and fire the appropriate events so that your client "catches up"
* automatically.
*
* @param db - The instance to reconnect.
*/
export declare function goOnline(db: Database): void;
/**
* Logs debugging information to the console.
*
* @param enabled - Enables logging if `true`, disables logging if `false`.
* @param persistent - Remembers the logging state between page refreshes if
* `true`.
*/
export declare function enableLogging(enabled: boolean, persistent?: boolean): any;
/**
* Logs debugging information to the console.
*
* @param logger - A custom logger function to control how things get logged.
*/
export declare function enableLogging(logger: (message: string) => unknown): any;

View file

@ -0,0 +1,110 @@
/**
* @license
* Copyright 2021 Google LLC
*
* 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';
/**
* The `onDisconnect` class allows you to write or clear data when your client
* disconnects from the Database server. These updates occur whether your
* client disconnects cleanly or not, so you can rely on them to clean up data
* even if a connection is dropped or a client crashes.
*
* The `onDisconnect` class is most commonly used to manage presence in
* applications where it is useful to detect how many clients are connected and
* when other clients disconnect. See
* {@link https://firebase.google.com/docs/database/web/offline-capabilities | Enabling Offline Capabilities in JavaScript}
* for more information.
*
* To avoid problems when a connection is dropped before the requests can be
* transferred to the Database server, these functions should be called before
* writing any data.
*
* Note that `onDisconnect` operations are only triggered once. If you want an
* operation to occur each time a disconnect occurs, you'll need to re-establish
* the `onDisconnect` operations each time you reconnect.
*/
export declare class OnDisconnect {
private _repo;
private _path;
/** @hideconstructor */
constructor(_repo: Repo, _path: Path);
/**
* Cancels all previously queued `onDisconnect()` set or update events for this
* location and all children.
*
* If a write has been queued for this location via a `set()` or `update()` at a
* parent location, the write at this location will be canceled, though writes
* to sibling locations will still occur.
*
* @returns Resolves when synchronization to the server is complete.
*/
cancel(): Promise<void>;
/**
* Ensures the data at this location is deleted when the client is disconnected
* (due to closing the browser, navigating to a new page, or network issues).
*
* @returns Resolves when synchronization to the server is complete.
*/
remove(): Promise<void>;
/**
* Ensures the data at this location is set to the specified value when the
* client is disconnected (due to closing the browser, navigating to a new page,
* or network issues).
*
* `set()` is especially useful for implementing "presence" systems, where a
* value should be changed or cleared when a user disconnects so that they
* appear "offline" to other users. See
* {@link https://firebase.google.com/docs/database/web/offline-capabilities | Enabling Offline Capabilities in JavaScript}
* for more information.
*
* Note that `onDisconnect` operations are only triggered once. If you want an
* operation to occur each time a disconnect occurs, you'll need to re-establish
* the `onDisconnect` operations each time.
*
* @param value - The value to be written to this location on disconnect (can
* be an object, array, string, number, boolean, or null).
* @returns Resolves when synchronization to the Database is complete.
*/
set(value: unknown): Promise<void>;
/**
* Ensures the data at this location is set to the specified value and priority
* when the client is disconnected (due to closing the browser, navigating to a
* new page, or network issues).
*
* @param value - The value to be written to this location on disconnect (can
* be an object, array, string, number, boolean, or null).
* @param priority - The priority to be written (string, number, or null).
* @returns Resolves when synchronization to the Database is complete.
*/
setWithPriority(value: unknown, priority: number | string | null): Promise<void>;
/**
* Writes multiple values at this location when the client is disconnected (due
* to closing the browser, navigating to a new page, or network issues).
*
* The `values` argument contains multiple property-value pairs that will be
* written to the Database together. Each child property can either be a simple
* property (for example, "name") or a relative path (for example, "name/first")
* from the current location to the data to update.
*
* As opposed to the `set()` method, `update()` can be use to selectively update
* only the referenced properties at the current location (instead of replacing
* all the child properties at the current location).
*
* @param values - Object containing multiple values.
* @returns Resolves when synchronization to the Database is complete.
*/
update(values: object): Promise<void>;
}

View file

@ -0,0 +1,122 @@
import { Repo } from '../core/Repo';
import { Path } from '../core/util/Path';
import { QueryContext } from '../core/view/EventRegistration';
/**
* @license
* Copyright 2021 Google LLC
*
* 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 `Query` sorts and filters the data at a Database location so only a subset
* of the child data is included. This can be used to order a collection of
* data by some attribute (for example, height of dinosaurs) as well as to
* restrict a large list of items (for example, chat messages) down to a number
* suitable for synchronizing to the client. Queries are created by chaining
* together one or more of the filter methods defined here.
*
* Just as with a `DatabaseReference`, you can receive data from a `Query` by using the
* `on*()` methods. You will only receive events and `DataSnapshot`s for the
* subset of the data that matches your query.
*
* See {@link https://firebase.google.com/docs/database/web/lists-of-data#sorting_and_filtering_data}
* for more information.
*/
export interface Query extends QueryContext {
/** The `DatabaseReference` for the `Query`'s location. */
readonly ref: DatabaseReference;
/**
* Returns whether or not the current and provided queries represent the same
* location, have the same query parameters, and are from the same instance of
* `FirebaseApp`.
*
* Two `DatabaseReference` objects are equivalent if they represent the same location
* and are from the same instance of `FirebaseApp`.
*
* Two `Query` objects are equivalent if they represent the same location,
* have the same query parameters, and are from the same instance of
* `FirebaseApp`. Equivalent queries share the same sort order, limits, and
* starting and ending points.
*
* @param other - The query to compare against.
* @returns Whether or not the current and provided queries are equivalent.
*/
isEqual(other: Query | null): boolean;
/**
* Returns a JSON-serializable representation of this object.
*
* @returns A JSON-serializable representation of this object.
*/
toJSON(): string;
/**
* Gets the absolute URL for this location.
*
* The `toString()` method returns a URL that is ready to be put into a
* browser, curl command, or a `refFromURL()` call. Since all of those expect
* the URL to be url-encoded, `toString()` returns an encoded URL.
*
* Append '.json' to the returned URL when typed into a browser to download
* JSON-formatted data. If the location is secured (that is, not publicly
* readable), you will get a permission-denied error.
*
* @returns The absolute URL for this location.
*/
toString(): string;
}
/**
* A `DatabaseReference` represents a specific location in your Database and can be used
* for reading or writing data to that Database location.
*
* You can reference the root or child location in your Database by calling
* `ref()` or `ref("child/path")`.
*
* Writing is done with the `set()` method and reading can be done with the
* `on*()` method. See {@link
* https://firebase.google.com/docs/database/web/read-and-write}
*/
export interface DatabaseReference extends Query {
/**
* The last part of the `DatabaseReference`'s path.
*
* For example, `"ada"` is the key for
* `https://<DATABASE_NAME>.firebaseio.com/users/ada`.
*
* The key of a root `DatabaseReference` is `null`.
*/
readonly key: string | null;
/**
* The parent location of a `DatabaseReference`.
*
* The parent of a root `DatabaseReference` is `null`.
*/
readonly parent: DatabaseReference | null;
/** The root `DatabaseReference` of the Database. */
readonly root: DatabaseReference;
}
/**
* A `Promise` that can also act as a `DatabaseReference` when returned by
* {@link push}. The reference is available immediately and the `Promise` resolves
* as the write to the backend completes.
*/
export interface ThenableReference extends DatabaseReference, Pick<Promise<DatabaseReference>, 'then' | 'catch'> {
}
/** A callback that can invoked to remove a listener. */
export declare type Unsubscribe = () => void;
/** An options objects that can be used to customize a listener. */
export interface ListenOptions {
/** Whether to remove the listener after its first invocation. */
readonly onlyOnce?: boolean;
}
export interface ReferenceConstructor {
new (repo: Repo, path: Path): DatabaseReference;
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,30 @@
/**
* @license
* Copyright 2020 Google LLC
*
* 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.
*/
/**
* Returns a placeholder value for auto-populating the current timestamp (time
* since the Unix epoch, in milliseconds) as determined by the Firebase
* servers.
*/
export declare function serverTimestamp(): object;
/**
* Returns a placeholder value that can be used to atomically increment the
* current database value by the provided delta.
*
* @param delta - the amount to modify the current value atomically.
* @returns A placeholder value for modifying data atomically server-side.
*/
export declare function increment(delta: number): object;

View file

@ -0,0 +1,83 @@
/**
* @license
* Copyright 2020 Google LLC
*
* 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 { DatabaseReference } from './Reference';
import { DataSnapshot } from './Reference_impl';
/** An options object to configure transactions. */
export interface TransactionOptions {
/**
* By default, events are raised each time the transaction update function
* runs. So if it is run multiple times, you may see intermediate states. You
* can set this to false to suppress these intermediate states and instead
* wait until the transaction has completed before events are raised.
*/
readonly applyLocally?: boolean;
}
/**
* A type for the resolve value of {@link runTransaction}.
*/
export declare class TransactionResult {
/** Whether the transaction was successfully committed. */
readonly committed: boolean;
/** The resulting data snapshot. */
readonly snapshot: DataSnapshot;
/** @hideconstructor */
constructor(
/** Whether the transaction was successfully committed. */
committed: boolean,
/** The resulting data snapshot. */
snapshot: DataSnapshot);
/** Returns a JSON-serializable representation of this object. */
toJSON(): object;
}
/**
* Atomically modifies the data at this location.
*
* Atomically modify the data at this location. Unlike a normal `set()`, which
* just overwrites the data regardless of its previous value, `runTransaction()` is
* used to modify the existing value to a new value, ensuring there are no
* conflicts with other clients writing to the same location at the same time.
*
* To accomplish this, you pass `runTransaction()` an update function which is
* used to transform the current value into a new value. If another client
* writes to the location before your new value is successfully written, your
* update function will be called again with the new current value, and the
* write will be retried. This will happen repeatedly until your write succeeds
* without conflict or you abort the transaction by not returning a value from
* your update function.
*
* Note: Modifying data with `set()` will cancel any pending transactions at
* that location, so extreme care should be taken if mixing `set()` and
* `runTransaction()` to update the same data.
*
* Note: When using transactions with Security and Firebase Rules in place, be
* aware that a client needs `.read` access in addition to `.write` access in
* order to perform a transaction. This is because the client-side nature of
* transactions requires the client to read the data in order to transactionally
* update it.
*
* @param ref - The location to atomically modify.
* @param transactionUpdate - A developer-supplied function which will be passed
* the current data stored at this location (as a JavaScript object). The
* function should return the new value it would like written (as a JavaScript
* object). If `undefined` is returned (i.e. you return with no arguments) the
* transaction will be aborted and the data at this location will not be
* modified.
* @param options - An options object to configure transactions.
* @returns A `Promise` that can optionally be used instead of the `onComplete`
* callback to handle success and failure.
*/
export declare function runTransaction(ref: DatabaseReference, transactionUpdate: (currentData: any) => unknown, options?: TransactionOptions): Promise<TransactionResult>;

View file

@ -0,0 +1,31 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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 { PersistentConnection } from '../core/PersistentConnection';
import { RepoInfo } from '../core/RepoInfo';
import { Connection } from '../realtime/Connection';
export declare const DataConnection: typeof PersistentConnection;
export declare const RealTimeConnection: typeof Connection;
/**
* @internal
*/
export declare const hijackHash: (newHash: () => string) => () => void;
export declare const ConnectionTarget: typeof RepoInfo;
/**
* Forces the RepoManager to create Repos that use ReadonlyRestClient instead of PersistentConnection.
* @internal
*/
export declare const forceRestClient: (forceRestClient: boolean) => void;

View file

@ -0,0 +1,30 @@
/**
* @license
* Copyright 2021 Google LLC
*
* 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 { AppCheckInternalComponentName, AppCheckTokenListener, AppCheckTokenResult } from '@firebase/app-check-interop-types';
import { Provider } from '@firebase/component';
/**
* Abstraction around AppCheck's token fetching capabilities.
*/
export declare class AppCheckTokenProvider {
private appName_;
private appCheckProvider?;
private appCheck?;
constructor(appName_: string, appCheckProvider?: Provider<AppCheckInternalComponentName>);
getToken(forceRefresh?: boolean): Promise<AppCheckTokenResult>;
addTokenChangeListener(listener: AppCheckTokenListener): void;
notifyForInvalidToken(): void;
}

View file

@ -0,0 +1,49 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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 { FirebaseAuthTokenData } from '@firebase/app-types/private';
import { FirebaseAuthInternalName } from '@firebase/auth-interop-types';
import { Provider } from '@firebase/component';
export interface AuthTokenProvider {
getToken(forceRefresh: boolean): Promise<FirebaseAuthTokenData>;
addTokenChangeListener(listener: (token: string | null) => void): void;
removeTokenChangeListener(listener: (token: string | null) => void): void;
notifyForInvalidToken(): void;
}
/**
* Abstraction around FirebaseApp's token fetching capabilities.
*/
export declare class FirebaseAuthTokenProvider implements AuthTokenProvider {
private appName_;
private firebaseOptions_;
private authProvider_;
private auth_;
constructor(appName_: string, firebaseOptions_: object, authProvider_: Provider<FirebaseAuthInternalName>);
getToken(forceRefresh: boolean): Promise<FirebaseAuthTokenData>;
addTokenChangeListener(listener: (token: string | null) => void): void;
removeTokenChangeListener(listener: (token: string | null) => void): void;
notifyForInvalidToken(): void;
}
export declare class EmulatorTokenProvider implements AuthTokenProvider {
private accessToken;
/** A string that is treated as an admin access token by the RTDB emulator. Used by Admin SDK. */
static OWNER: string;
constructor(accessToken: string);
getToken(forceRefresh: boolean): Promise<FirebaseAuthTokenData>;
addTokenChangeListener(listener: (token: string | null) => void): void;
removeTokenChangeListener(listener: (token: string | null) => void): void;
notifyForInvalidToken(): void;
}

View file

@ -0,0 +1,81 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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 { ImmutableTree } from './util/ImmutableTree';
import { Path } from './util/Path';
/**
* 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 {
writeTree_: ImmutableTree<Node>;
constructor(writeTree_: ImmutableTree<Node>);
static empty(): CompoundWrite;
}
export declare function compoundWriteAddWrite(compoundWrite: CompoundWrite, path: Path, node: Node): CompoundWrite;
export declare function compoundWriteAddWrites(compoundWrite: CompoundWrite, 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 compoundWrite - The CompoundWrite to remove.
* @param path - The path at which a write and all deeper writes should be removed
* @returns The new CompoundWrite with the removed path
*/
export declare function compoundWriteRemoveWrite(compoundWrite: CompoundWrite, path: Path): CompoundWrite;
/**
* Returns whether this CompoundWrite will fully overwrite a node at a given location and can therefore be
* considered "complete".
*
* @param compoundWrite - The CompoundWrite to check.
* @param path - The path to check for
* @returns Whether there is a complete write at that path
*/
export declare function compoundWriteHasCompleteWrite(compoundWrite: CompoundWrite, 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 compoundWrite - The CompoundWrite to get the node from.
* @param path - The path to get a complete write
* @returns The node if complete at that path, or null otherwise.
*/
export declare function compoundWriteGetCompleteNode(compoundWrite: CompoundWrite, path: Path): Node | null;
/**
* Returns all children that are guaranteed to be a complete overwrite.
*
* @param compoundWrite - The CompoundWrite to get children from.
* @returns A list of all complete children.
*/
export declare function compoundWriteGetCompleteChildren(compoundWrite: CompoundWrite): NamedNode[];
export declare function compoundWriteChildCompoundWrite(compoundWrite: CompoundWrite, path: Path): CompoundWrite;
/**
* Returns true if this CompoundWrite is empty and therefore does not modify any nodes.
* @returns Whether this CompoundWrite is empty
*/
export declare function compoundWriteIsEmpty(compoundWrite: CompoundWrite): 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
* @returns The node with all writes applied
*/
export declare function compoundWriteApply(compoundWrite: CompoundWrite, node: Node): Node;

View file

@ -0,0 +1,135 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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 { AppCheckTokenProvider } from './AppCheckTokenProvider';
import { AuthTokenProvider } from './AuthTokenProvider';
import { RepoInfo } from './RepoInfo';
import { ServerActions } from './ServerActions';
import { QueryContext } from './view/EventRegistration';
/**
* 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 applicationId_;
private onDataUpdate_;
private onConnectStatus_;
private onServerInfoUpdate_;
private authTokenProvider_;
private appCheckTokenProvider_;
private authOverride_?;
id: number;
private log_;
private interruptReasons_;
private readonly listens;
private outstandingPuts_;
private outstandingGets_;
private outstandingPutCount_;
private outstandingGetCount_;
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 appCheckToken_;
private forceTokenRefresh_;
private invalidAuthTokenCount_;
private invalidAppCheckTokenCount_;
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_;
/**
* @param repoInfo_ - Data about the namespace we are connecting to
* @param applicationId_ - The Firebase App ID for this project
* @param onDataUpdate_ - A callback for new data from the server
*/
constructor(repoInfo_: RepoInfo, applicationId_: string, onDataUpdate_: (a: string, b: unknown, c: boolean, d: number | null) => void, onConnectStatus_: (a: boolean) => void, onServerInfoUpdate_: (a: unknown) => void, authTokenProvider_: AuthTokenProvider, appCheckTokenProvider_: AppCheckTokenProvider, authOverride_?: object | null);
protected sendRequest(action: string, body: unknown, onResponse?: (a: unknown) => void): void;
get(query: QueryContext): Promise<string>;
listen(query: QueryContext, currentHashFn: () => string, tag: number | null, onComplete: (a: string, b: unknown) => void): void;
private sendGet_;
private sendListen_;
private static warnOnListenWarnings_;
refreshAuthToken(token: string): void;
private reduceReconnectDelayIfAdminCredential_;
refreshAppCheckToken(token: string | null): void;
/**
* 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;
/**
* Attempts to authenticate with the given token. If the authentication
* attempt fails, it's triggered like the token was revoked (the connection is
* closed).
*/
tryAppCheck(): void;
/**
* @inheritDoc
*/
unlisten(query: QueryContext, tag: number | null): void;
private sendUnlisten_;
onDisconnectPut(pathString: string, data: unknown, onComplete?: (a: string, b: string) => void): void;
onDisconnectMerge(pathString: string, data: unknown, onComplete?: (a: string, b: string) => void): void;
onDisconnectCancel(pathString: string, onComplete?: (a: string, b: string) => void): void;
private sendOnDisconnect_;
put(pathString: string, data: unknown, onComplete?: (a: string, b: string) => void, hash?: string): void;
merge(pathString: string, data: unknown, onComplete: (a: string, b: string | null) => void, hash?: string): void;
putInternal(action: string, pathString: string, data: unknown, onComplete: (a: string, b: string | null) => void, hash?: string): void;
private sendPut_;
reportStats(stats: {
[k: string]: unknown;
}): void;
private onDataMessage_;
private onDataPush_;
private onReady_;
private scheduleConnect_;
private initConnection_;
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 onAppCheckRevoked_;
private onSecurityDebugPacket_;
private restoreState_;
/**
* Sends client stats for first connection
*/
private sendConnectStats_;
private shouldReconnect_;
}

View file

@ -0,0 +1,60 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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 { AppCheckTokenProvider } from './AppCheckTokenProvider';
import { AuthTokenProvider } from './AuthTokenProvider';
import { RepoInfo } from './RepoInfo';
import { ServerActions } from './ServerActions';
import { QueryContext } from './view/EventRegistration';
/**
* 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_;
private appCheckTokenProvider_;
reportStats(stats: {
[k: string]: unknown;
}): 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 listens_;
static getListenId_(query: QueryContext, tag?: number | null): string;
/**
* @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: unknown, c: boolean, d: number | null) => void, authTokenProvider_: AuthTokenProvider, appCheckTokenProvider_: AppCheckTokenProvider);
/** @inheritDoc */
listen(query: QueryContext, currentHashFn: () => string, tag: number | null, onComplete: (a: string, b: unknown) => void): void;
/** @inheritDoc */
unlisten(query: QueryContext, tag: number | null): void;
get(query: QueryContext): Promise<string>;
/** @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.
*/
private restRequest_;
}

View file

@ -0,0 +1,144 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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 { ValueEventRegistration } from '../api/Reference_impl';
import { AppCheckTokenProvider } from './AppCheckTokenProvider';
import { AuthTokenProvider } from './AuthTokenProvider';
import { PersistentConnection } from './PersistentConnection';
import { RepoInfo } from './RepoInfo';
import { ServerActions } from './ServerActions';
import { Node } from './snap/Node';
import { SnapshotHolder } from './SnapshotHolder';
import { SparseSnapshotTree } from './SparseSnapshotTree';
import { StatsCollection } from './stats/StatsCollection';
import { StatsListener } from './stats/StatsListener';
import { StatsReporter } from './stats/StatsReporter';
import { SyncTree } from './SyncTree';
import { Indexable } from './util/misc';
import { Path } from './util/Path';
import { Tree } from './util/Tree';
import { EventQueue } from './view/EventQueue';
import { EventRegistration, QueryContext } from './view/EventRegistration';
declare const enum TransactionStatus {
RUN = 0,
SENT = 1,
COMPLETED = 2,
SENT_NEEDS_ABORT = 3,
NEEDS_ABORT = 4
}
interface Transaction {
path: Path;
update: (a: unknown) => unknown;
onComplete: (error: Error | null, committed: boolean, node: Node | null) => void;
status: TransactionStatus;
order: number;
applyLocally: boolean;
retryCount: number;
unwatcher: () => void;
abortReason: string | null;
currentWriteId: number;
currentInputSnapshot: Node | null;
currentOutputSnapshotRaw: Node | null;
currentOutputSnapshotResolved: Node | null;
}
/**
* A connection to a single data repository.
*/
export declare class Repo {
repoInfo_: RepoInfo;
forceRestClient_: boolean;
authTokenProvider_: AuthTokenProvider;
appCheckProvider_: AppCheckTokenProvider;
/** Key for uniquely identifying this repo, used in RepoManager */
readonly key: string;
dataUpdateCount: number;
infoSyncTree_: SyncTree;
serverSyncTree_: SyncTree;
stats_: StatsCollection;
statsListener_: StatsListener | null;
eventQueue_: EventQueue;
nextWriteId_: number;
server_: ServerActions;
statsReporter_: StatsReporter;
infoData_: SnapshotHolder;
interceptServerDataCallback_: ((a: string, b: unknown) => void) | null;
/** A list of data pieces and paths to be set when this client disconnects. */
onDisconnect_: SparseSnapshotTree;
/** Stores queues of outstanding transactions for Firebase locations. */
transactionQueueTree_: Tree<Transaction[]>;
persistentConnection_: PersistentConnection | null;
constructor(repoInfo_: RepoInfo, forceRestClient_: boolean, authTokenProvider_: AuthTokenProvider, appCheckProvider_: AppCheckTokenProvider);
/**
* @returns The URL corresponding to the root of this Firebase.
*/
toString(): string;
}
export declare function repoStart(repo: Repo, appId: string, authOverride?: object): void;
/**
* @returns The time in milliseconds, taking the server offset into account if we have one.
*/
export declare function repoServerTime(repo: Repo): number;
/**
* Generate ServerValues using some variables from the repo object.
*/
export declare function repoGenerateServerValues(repo: Repo): Indexable;
export declare function repoInterceptServerData(repo: Repo, callback: ((a: string, b: unknown) => unknown) | null): void;
/**
* The purpose of `getValue` is to return the latest known value
* satisfying `query`.
*
* This method will first check for in-memory cached values
* belonging to active listeners. If they are found, such values
* are considered to be the most up-to-date.
*
* If the client is not connected, this method will wait until the
* repo has established a connection and then request the value for `query`.
* If the client is not able to retrieve the query result for another reason,
* it reports an error.
*
* @param query - The query to surface a value for.
*/
export declare function repoGetValue(repo: Repo, query: QueryContext, eventRegistration: ValueEventRegistration): Promise<Node>;
export declare function repoSetWithPriority(repo: Repo, path: Path, newVal: unknown, newPriority: number | string | null, onComplete: ((status: Error | null, errorReason?: string) => void) | null): void;
export declare function repoUpdate(repo: Repo, path: Path, childrenToMerge: {
[k: string]: unknown;
}, onComplete: ((status: Error | null, errorReason?: string) => void) | null): void;
export declare function repoOnDisconnectCancel(repo: Repo, path: Path, onComplete: ((status: Error | null, errorReason?: string) => void) | null): void;
export declare function repoOnDisconnectSet(repo: Repo, path: Path, value: unknown, onComplete: ((status: Error | null, errorReason?: string) => void) | null): void;
export declare function repoOnDisconnectSetWithPriority(repo: Repo, path: Path, value: unknown, priority: unknown, onComplete: ((status: Error | null, errorReason?: string) => void) | null): void;
export declare function repoOnDisconnectUpdate(repo: Repo, path: Path, childrenToMerge: {
[k: string]: unknown;
}, onComplete: ((status: Error | null, errorReason?: string) => void) | null): void;
export declare function repoAddEventCallbackForQuery(repo: Repo, query: QueryContext, eventRegistration: EventRegistration): void;
export declare function repoRemoveEventCallbackForQuery(repo: Repo, query: QueryContext, eventRegistration: EventRegistration): void;
export declare function repoInterrupt(repo: Repo): void;
export declare function repoResume(repo: Repo): void;
export declare function repoStats(repo: Repo, showDelta?: boolean): void;
export declare function repoStatsIncrementCounter(repo: Repo, metric: string): void;
export declare function repoCallOnCompleteCallback(repo: Repo, callback: ((status: Error | null, errorReason?: string) => void) | null, status: string, errorReason?: string | null): void;
/**
* Creates a new transaction, adds it to the transactions we're tracking, and
* sends it to the server if possible.
*
* @param path - Path at which to do transaction.
* @param transactionUpdate - Update callback.
* @param onComplete - Completion callback.
* @param unwatcher - Function that will be called when the transaction no longer
* need data updates for `path`.
* @param applyLocally - Whether or not to make intermediate results visible
*/
export declare function repoStartTransaction(repo: Repo, path: Path, transactionUpdate: (a: unknown) => unknown, onComplete: ((error: Error, committed: boolean, node: Node) => void) | null, unwatcher: () => void, applyLocally: boolean): void;
export {};

View file

@ -0,0 +1,56 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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
*/
export declare class RepoInfo {
readonly secure: boolean;
readonly namespace: string;
readonly webSocketOnly: boolean;
readonly nodeAdmin: boolean;
readonly persistenceKey: string;
readonly includeNamespaceInQueryParams: boolean;
readonly isUsingEmulator: boolean;
private _host;
private _domain;
internalHost: string;
/**
* @param host - Hostname portion of the url for the repo
* @param secure - Whether or not this repo is accessed over ssl
* @param namespace - The namespace represented by the repo
* @param webSocketOnly - Whether to prefer websockets over all other transports (used by Nest).
* @param nodeAdmin - Whether this instance uses Admin SDK credentials
* @param persistenceKey - Override the default session persistence storage key
*/
constructor(host: string, secure: boolean, namespace: string, webSocketOnly: boolean, nodeAdmin?: boolean, persistenceKey?: string, includeNamespaceInQueryParams?: boolean, isUsingEmulator?: boolean);
isCacheableHost(): boolean;
isCustomHost(): boolean;
get host(): string;
set host(newHost: string);
toString(): string;
toURLString(): string;
}
/**
* Returns the websocket URL for this repo
* @param repoInfo - RepoInfo object
* @param type - of connection
* @param params - list
* @returns The URL for this repo
*/
export declare function repoInfoConnectionURL(repoInfo: RepoInfo, type: string, params: {
[k: string]: string;
}): string;

View file

@ -0,0 +1,52 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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 { QueryContext } from './view/EventRegistration';
/**
* 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 {
abstract listen(query: QueryContext, currentHashFn: () => string, tag: number | null, onComplete: (a: string, b: unknown) => void): void;
/**
* Remove a listen.
*/
abstract unlisten(query: QueryContext, tag: number | null): void;
/**
* Get the server value satisfying this query.
*/
abstract get(query: QueryContext): Promise<string>;
put(pathString: string, data: unknown, onComplete?: (a: string, b: string) => void, hash?: string): void;
merge(pathString: string, data: unknown, onComplete: (a: string, b: string | null) => void, hash?: string): void;
/**
* Refreshes the auth token for the current connection.
* @param token - The authentication token
*/
refreshAuthToken(token: string): void;
/**
* Refreshes the app check token for the current connection.
* @param token The app check token
*/
refreshAppCheckToken(token: string): void;
onDisconnectPut(pathString: string, data: unknown, onComplete?: (a: string, b: string) => void): void;
onDisconnectMerge(pathString: string, data: unknown, onComplete?: (a: string, b: string) => void): void;
onDisconnectCancel(pathString: string, onComplete?: (a: string, b: string) => void): void;
reportStats(stats: {
[k: string]: unknown;
}): void;
}

View file

@ -0,0 +1,26 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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';
/**
* Mutable object which basically just stores a reference to the "latest" immutable snapshot.
*/
export declare class SnapshotHolder {
private rootNode_;
getNode(path: Path): Node;
updateSnapshot(path: Path, newSnapshotNode: Node): void;
}

View file

@ -0,0 +1,64 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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';
/**
* Helper class to store a sparse set of snapshots.
*/
export interface SparseSnapshotTree {
value: Node | null;
readonly children: Map<string, SparseSnapshotTree>;
}
export declare function newSparseSnapshotTree(): SparseSnapshotTree;
/**
* Gets the node stored at the given path if one exists.
* Only seems to be used in tests.
*
* @param path - Path to look up snapshot for.
* @returns The retrieved node, or null.
*/
export declare function sparseSnapshotTreeFind(sparseSnapshotTree: SparseSnapshotTree, 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.
*/
export declare function sparseSnapshotTreeRemember(sparseSnapshotTree: SparseSnapshotTree, path: Path, data: Node): void;
/**
* Purge the data at path from the cache.
*
* @param path - Path to look up snapshot for.
* @returns True if this node should now be removed.
*/
export declare function sparseSnapshotTreeForget(sparseSnapshotTree: SparseSnapshotTree, 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.
*/
export declare function sparseSnapshotTreeForEachTree(sparseSnapshotTree: SparseSnapshotTree, prefixPath: Path, func: (a: Path, b: Node) => unknown): void;
/**
* Iterates through each immediate child and triggers the callback.
* Only seems to be used in tests.
*
* @param func - The function to invoke for each child.
*/
export declare function sparseSnapshotTreeForEachChild(sparseSnapshotTree: SparseSnapshotTree, func: (a: string, b: SparseSnapshotTree) => void): void;

View file

@ -0,0 +1,91 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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 { ReferenceConstructor } from '../api/Reference';
import { Operation } from './operation/Operation';
import { Node } from './snap/Node';
import { Path } from './util/Path';
import { Event } from './view/Event';
import { EventRegistration, QueryContext } from './view/EventRegistration';
import { View } from './view/View';
import { WriteTreeRef } from './WriteTree';
/**
* 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 {
/**
* 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).
*/
readonly views: Map<string, View>;
}
export declare function syncPointSetReferenceConstructor(val: ReferenceConstructor): void;
export declare function syncPointIsEmpty(syncPoint: SyncPoint): boolean;
export declare function syncPointApplyOperation(syncPoint: SyncPoint, operation: Operation, writesCache: WriteTreeRef, optCompleteServerCache: Node | null): Event[];
/**
* Get a view for the specified query.
*
* @param query - The query to return a view for
* @param writesCache
* @param serverCache
* @param serverCacheComplete
* @returns Events to raise.
*/
export declare function syncPointGetView(syncPoint: SyncPoint, query: QueryContext, writesCache: WriteTreeRef, serverCache: Node | null, serverCacheComplete: boolean): View;
/**
* Add an event callback for the specified query.
*
* @param query
* @param eventRegistration
* @param writesCache
* @param serverCache - Complete server cache, if we have it.
* @param serverCacheComplete
* @returns Events to raise.
*/
export declare function syncPointAddEventRegistration(syncPoint: SyncPoint, query: QueryContext, 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 eventRegistration - If null, remove all callbacks.
* @param cancelError - If a cancelError is provided, appropriate cancel events will be returned.
* @returns removed queries and any cancel events
*/
export declare function syncPointRemoveEventRegistration(syncPoint: SyncPoint, query: QueryContext, eventRegistration: EventRegistration | null, cancelError?: Error): {
removed: QueryContext[];
events: Event[];
};
export declare function syncPointGetQueryViews(syncPoint: SyncPoint): View[];
/**
* @param path - The path to the desired complete snapshot
* @returns A complete cache, if it exists
*/
export declare function syncPointGetCompleteServerCache(syncPoint: SyncPoint, path: Path): Node | null;
export declare function syncPointViewForQuery(syncPoint: SyncPoint, query: QueryContext): View | null;
export declare function syncPointViewExistsForQuery(syncPoint: SyncPoint, query: QueryContext): boolean;
export declare function syncPointHasCompleteView(syncPoint: SyncPoint): boolean;
export declare function syncPointGetCompleteView(syncPoint: SyncPoint): View | null;

View file

@ -0,0 +1,166 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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 { ReferenceConstructor } from '../api/Reference';
import { Node } from './snap/Node';
import { SyncPoint } from './SyncPoint';
import { ImmutableTree } from './util/ImmutableTree';
import { Path } from './util/Path';
import { Event } from './view/Event';
import { EventRegistration, QueryContext } from './view/EventRegistration';
import { WriteTree } from './WriteTree';
export declare function syncTreeSetReferenceConstructor(val: ReferenceConstructor): void;
export interface ListenProvider {
startListening(query: QueryContext, tag: number | null, hashFn: () => string, onComplete: (a: string, b?: unknown) => Event[]): Event[];
stopListening(a: QueryContext, b: number | null): void;
}
export declare function resetSyncTreeTag(): 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.
*
*/
export declare class SyncTree {
listenProvider_: ListenProvider;
/**
* Tree of SyncPoints. There's a SyncPoint at any location that has 1 or more views.
*/
syncPointTree_: ImmutableTree<SyncPoint>;
/**
* A tree of all pending user writes (user-initiated set()'s, transaction()'s, update()'s, etc.).
*/
pendingWriteTree_: WriteTree;
readonly tagToQueryMap: Map<number, string>;
readonly queryToTagMap: Map<string, number>;
/**
* @param 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.
*
* @returns Events to raise.
*/
export declare function syncTreeApplyUserOverwrite(syncTree: SyncTree, path: Path, newData: Node, writeId: number, visible?: boolean): Event[];
/**
* Apply the data from a user-generated update() call
*
* @returns Events to raise.
*/
export declare function syncTreeApplyUserMerge(syncTree: SyncTree, 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
* @returns Events to raise.
*/
export declare function syncTreeAckUserWrite(syncTree: SyncTree, writeId: number, revert?: boolean): Event[];
/**
* Apply new server data for the specified path..
*
* @returns Events to raise.
*/
export declare function syncTreeApplyServerOverwrite(syncTree: SyncTree, path: Path, newData: Node): Event[];
/**
* Apply new server data to be merged in at the specified path.
*
* @returns Events to raise.
*/
export declare function syncTreeApplyServerMerge(syncTree: SyncTree, path: Path, changedChildren: {
[k: string]: Node;
}): Event[];
/**
* Apply a listen complete for a query
*
* @returns Events to raise.
*/
export declare function syncTreeApplyListenComplete(syncTree: SyncTree, path: Path): Event[];
/**
* Apply a listen complete for a tagged query
*
* @returns Events to raise.
*/
export declare function syncTreeApplyTaggedListenComplete(syncTree: SyncTree, path: Path, tag: number): 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.
* @param skipListenerDedup - When performing a `get()`, we don't add any new listeners, so no
* deduping needs to take place. This flag allows toggling of that behavior
* @returns Cancel events, if cancelError was provided.
*/
export declare function syncTreeRemoveEventRegistration(syncTree: SyncTree, query: QueryContext, eventRegistration: EventRegistration | null, cancelError?: Error, skipListenerDedup?: boolean): Event[];
/**
* Apply new server data for the specified tagged query.
*
* @returns Events to raise.
*/
export declare function syncTreeApplyTaggedQueryOverwrite(syncTree: SyncTree, path: Path, snap: Node, tag: number): Event[];
/**
* Apply server data to be merged in for the specified tagged query.
*
* @returns Events to raise.
*/
export declare function syncTreeApplyTaggedQueryMerge(syncTree: SyncTree, path: Path, changedChildren: {
[k: string]: Node;
}, tag: number): Event[];
/**
* Add an event callback for the specified query.
*
* @returns Events to raise.
*/
export declare function syncTreeAddEventRegistration(syncTree: SyncTree, query: QueryContext, eventRegistration: EventRegistration, skipSetupListener?: boolean): Event[];
/**
* Returns a complete cache, if we have one, of the data at a particular path. If the location does not have a
* listener above it, we will get a false "null". This shouldn't be a problem because transactions will always
* have a listener above, and atomic operations would correctly show a jitter of <increment value> ->
* <incremented total> as the write is applied locally and then acknowledged at the server.
*
* 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
*/
export declare function syncTreeCalcCompleteEventCache(syncTree: SyncTree, path: Path, writeIdsToExclude?: number[]): Node;
export declare function syncTreeGetServerValue(syncTree: SyncTree, query: QueryContext): Node | null;
/**
* Return the tag associated with the given query.
*/
export declare function syncTreeTagForQuery(syncTree: SyncTree, query: QueryContext): number | null;

View file

@ -0,0 +1,205 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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 { CompoundWrite } from './CompoundWrite';
import { ChildrenNode } from './snap/ChildrenNode';
import { Index } from './snap/indexes/Index';
import { NamedNode, Node } from './snap/Node';
import { Path } from './util/Path';
import { CacheNode } from './view/CacheNode';
/**
* 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 will 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;
}
/**
* Create a new WriteTreeRef for the given path. For use with a new sync point at the given path.
*
*/
export declare function writeTreeChildWrites(writeTree: WriteTree, path: Path): WriteTreeRef;
/**
* Record a new overwrite from user code.
*
* @param visible - This is set to false by some transactions. It should be excluded from event caches
*/
export declare function writeTreeAddOverwrite(writeTree: WriteTree, path: Path, snap: Node, writeId: number, visible?: boolean): void;
/**
* Record a new merge from user code.
*/
export declare function writeTreeAddMerge(writeTree: WriteTree, path: Path, changedChildren: {
[k: string]: Node;
}, writeId: number): void;
export declare function writeTreeGetWrite(writeTree: WriteTree, 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.
*
* @returns true if the write may have been visible (meaning we'll need to reevaluate / raise
* events as a result).
*/
export declare function writeTreeRemoveWrite(writeTree: WriteTree, 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.
*
*/
export declare function writeTreeGetCompleteWriteData(writeTree: WriteTree, 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 writeIdsToExclude - An optional set to be excluded
* @param includeHiddenWrites - Defaults to false, whether or not to layer on writes with visible set to false
*/
export declare function writeTreeCalcCompleteEventCache(writeTree: WriteTree, 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.
*/
export declare function writeTreeCalcCompleteEventChildren(writeTree: WriteTree, 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
*/
export declare function writeTreeCalcEventCacheAfterServerOverwrite(writeTree: WriteTree, 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.
*/
export declare function writeTreeCalcCompleteChild(writeTree: WriteTree, 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.
*/
export declare function writeTreeShadowingWrite(writeTree: WriteTree, 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.
*/
export declare function writeTreeCalcIndexedSlice(writeTree: WriteTree, treePath: Path, completeServerData: Node | null, startPost: NamedNode, count: number, reverse: boolean, index: Index): NamedNode[];
export declare function newWriteTree(): WriteTree;
/**
* 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().
*/
export interface 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.
*/
visibleWrites: CompoundWrite;
/**
* 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).
*/
allWrites: WriteRecord[];
lastWriteId: number;
}
/**
* 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 writeIdsToExclude - Optional writes to exclude.
* @param includeHiddenWrites - Defaults to false, whether or not to layer on writes with visible set to false
*/
export declare function writeTreeRefCalcCompleteEventCache(writeTreeRef: WriteTreeRef, 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.
*
*/
export declare function writeTreeRefCalcCompleteEventChildren(writeTreeRef: WriteTreeRef, 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
*
*
*/
export declare function writeTreeRefCalcEventCacheAfterServerOverwrite(writeTreeRef: WriteTreeRef, 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.
*
*/
export declare function writeTreeRefShadowingWrite(writeTreeRef: WriteTreeRef, 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
*/
export declare function writeTreeRefCalcIndexedSlice(writeTreeRef: WriteTreeRef, 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.
*/
export declare function writeTreeRefCalcCompleteChild(writeTreeRef: WriteTreeRef, childKey: string, existingServerCache: CacheNode): Node | null;
/**
* Return a WriteTreeRef for a child.
*/
export declare function writeTreeRefChild(writeTreeRef: WriteTreeRef, childName: string): WriteTreeRef;
export declare function newWriteTreeRef(path: Path, writeTree: WriteTree): WriteTreeRef;
/**
* 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.
*
*/
export interface WriteTreeRef {
/**
* The path to this particular write tree ref. Used for calling methods on writeTree_ while exposing a simpler
* interface to callers.
*/
readonly treePath: Path;
/**
* * 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.
*/
readonly writeTree: WriteTree;
}

View file

@ -0,0 +1,36 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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 { Operation, OperationType } from './Operation';
export declare class AckUserWrite implements Operation {
/** @inheritDoc */ path: Path;
/** @inheritDoc */ affectedTree: ImmutableTree<boolean>;
/** @inheritDoc */ revert: boolean;
/** @inheritDoc */
type: OperationType;
/** @inheritDoc */
source: import("./Operation").OperationSource;
/**
* @param affectedTree - A tree containing true for each affected path. Affected paths can't overlap.
*/
constructor(
/** @inheritDoc */ path: Path,
/** @inheritDoc */ affectedTree: ImmutableTree<boolean>,
/** @inheritDoc */ revert: boolean);
operationForChild(childName: string): AckUserWrite;
}

View file

@ -0,0 +1,26 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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';
export declare class ListenComplete implements Operation {
source: OperationSource;
path: Path;
/** @inheritDoc */
type: OperationType;
constructor(source: OperationSource, path: Path);
operationForChild(childName: string): ListenComplete;
}

View file

@ -0,0 +1,33 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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 { ImmutableTree } from '../util/ImmutableTree';
import { Path } from '../util/Path';
import { Operation, OperationSource, OperationType } from './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>);
operationForChild(childName: string): Operation;
toString(): string;
}

View file

@ -0,0 +1,45 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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 {
source: OperationSource;
type: OperationType;
path: Path;
operationForChild(childName: string): Operation | null;
}
export interface OperationSource {
fromUser: boolean;
fromServer: boolean;
queryId: string | null;
tagged: boolean;
}
export declare function newOperationSourceUser(): OperationSource;
export declare function newOperationSourceServer(): OperationSource;
export declare function newOperationSourceServerTaggedQuery(queryId: string): OperationSource;

View file

@ -0,0 +1,28 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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 { Operation, OperationSource, OperationType } from './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;
}

View file

@ -0,0 +1,112 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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 { SortedMap, SortedMapIterator } from '../util/SortedMap';
import { Index } from './indexes/Index';
import { IndexMap } from './IndexMap';
import { NamedNode, Node } from './Node';
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.
*/
export declare class ChildrenNode implements Node {
private readonly children_;
private readonly priorityNode_;
private indexMap_;
private lazyHash_;
static get EMPTY_NODE(): ChildrenNode;
/**
* @param children_ - List of children of this node..
* @param priorityNode_ - The priority of this node (as a snapshot node).
*/
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 static INTEGER_REGEXP_;
/** @inheritDoc */
val(exportFormat?: boolean): object;
/** @inheritDoc */
hash(): string;
/** @inheritDoc */
getPredecessorChildName(childName: string, childNode: Node, index: Index): string;
getFirstChildName(indexDefinition: Index): string | null;
getFirstChild(indexDefinition: Index): NamedNode | null;
/**
* Given an index, return the key name of the largest value we have, according to that index
*/
getLastChildName(indexDefinition: Index): string | null;
getLastChild(indexDefinition: Index): NamedNode | null;
forEachChild(index: Index, action: (key: string, node: Node) => boolean | void): boolean;
getIterator(indexDefinition: Index): SortedMapIterator<string | NamedNode, Node, NamedNode>;
getIteratorFrom(startPost: NamedNode, indexDefinition: Index): SortedMapIterator<string | NamedNode, Node, NamedNode>;
getReverseIterator(indexDefinition: Index): SortedMapIterator<string | NamedNode, Node, NamedNode>;
getReverseIteratorFrom(endPost: NamedNode, indexDefinition: Index): SortedMapIterator<string | NamedNode, Node, NamedNode>;
compareTo(other: ChildrenNode): number;
withIndex(indexDefinition: Index): Node;
isIndexed(index: Index): boolean;
equals(other: Node): boolean;
/**
* Returns a SortedMap ordered by index, or null if the default (by-key) ordering can be used
* instead.
*
*/
private resolveIndex_;
}
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.
*/
export declare const MAX_NODE: MaxNode;
/**
* Document NamedNode extensions
*/
declare module './Node' {
interface NamedNode {
MIN: NamedNode;
MAX: NamedNode;
}
}

View file

@ -0,0 +1,43 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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 { Index } from './indexes/Index';
import { NamedNode, Node } from './Node';
export declare class IndexMap {
private indexes_;
private indexSet_;
/**
* The default IndexMap for nodes without a priority
*/
static get 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;
}

View file

@ -0,0 +1,83 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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 { Indexable } from '../util/misc';
import { Path } from '../util/Path';
import { ChildrenNodeConstructor } from './ChildrenNode';
import { Index } from './indexes/Index';
import { Node } from './Node';
/**
* 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 set __childrenNodeConstructor(val: ChildrenNodeConstructor);
static get __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
*/
static VALUE_TYPE_ORDER: string[];
private lazyHash_;
/**
* @param value_ - The value to store in this leaf node. The object type is
* possible in the event of a deferred value
* @param priorityNode_ - The priority of this node.
*/
constructor(value_: string | number | boolean | Indexable, priorityNode_?: Node);
/** @inheritDoc */
isLeafNode(): boolean;
/** @inheritDoc */
getPriority(): Node;
/** @inheritDoc */
updatePriority(newPriorityNode: Node): Node;
/** @inheritDoc */
getImmediateChild(childName: string): Node;
/** @inheritDoc */
getChild(path: Path): Node;
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): boolean;
val(exportFormat?: boolean): {};
/** @inheritDoc */
hash(): string;
/**
* Returns the value of the leaf node.
* @returns The value of the node.
*/
getValue(): Indexable | string | number | boolean;
compareTo(other: Node): number;
/**
* Comparison specifically for two leaf nodes
*/
private compareToLeafNode_;
withIndex(): Node;
isIndexed(): boolean;
equals(other: Node): boolean;
}

View file

@ -0,0 +1,126 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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.
* @returns Whether this is a leaf node.
*/
isLeafNode(): boolean;
/**
* Gets the priority of the node.
* @returns The priority of the node.
*/
getPriority(): Node;
/**
* Returns a duplicate node with the new priority.
* @param newPriorityNode - New priority to set for the node.
* @returns Node with new priority.
*/
updatePriority(newPriorityNode: Node): Node;
/**
* Returns the specified immediate child, or null if it doesn't exist.
* @param childName - The name of the child to retrieve.
* @returns 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 - The path of the child to retrieve.
* @returns 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 childName - The name of the child to find the predecessor of.
* @param childNode - The node to find the predecessor of.
* @param index - The index to use to determine the predecessor
* @returns 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 childName - The name of the child to update.
* @param newChildNode - The new child node
* @returns 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 - The path of the child to update.
* @param newChildNode - The new child node, which may be an empty node
* @returns The updated node.
*/
updateChild(path: Path, newChildNode: Node): Node;
/**
* True if the immediate child specified exists
*/
hasChild(childName: string): boolean;
/**
* @returns True if this node has no value or children.
*/
isEmpty(): boolean;
/**
* @returns The number of children of this node.
*/
numChildren(): number;
/**
* Calls action for each child.
* @param action - Action to be called for
* each child. It's passed the child name and the child node.
* @returns The first truthy value return by action, or the last falsey one
*/
forEachChild(index: Index, action: (a: string, b: Node) => void): unknown;
/**
* @param exportFormat - True for export format (also wire protocol format).
* @returns Value of this node as JSON.
*/
val(exportFormat?: boolean): unknown;
/**
* @returns hash representing the node contents.
*/
hash(): string;
/**
* @param other - Another node
* @returns -1 for less than, 0 for equal, 1 for greater than other
*/
compareTo(other: Node): number;
/**
* @returns Whether or not this snapshot equals other
*/
equals(other: Node): boolean;
/**
* @returns This node, with the specified index now available
*/
withIndex(indexDefinition: Index): Node;
isIndexed(indexDefinition: Index): boolean;
}
export declare class NamedNode {
name: string;
node: Node;
constructor(name: string, node: Node);
static Wrap(name: string, node: Node): NamedNode;
}

View file

@ -0,0 +1,32 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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
*
* @param childList - Unsorted list of children
* @param cmp - The comparison method to be used
* @param keyFn - An optional function to extract K from a node wrapper, if K's
* type is not NamedNode
* @param mapSortFn - An optional override for comparator used by the generated sorted map
*/
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>;

View file

@ -0,0 +1,19 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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;

View file

@ -0,0 +1,50 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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 { Comparator } from '../../util/SortedMap';
import { Node, NamedNode } from '../Node';
export declare abstract class Index {
abstract compare(a: NamedNode, b: NamedNode): number;
abstract isDefinedOn(node: Node): boolean;
/**
* @returns 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.
*
*
* @returns True if the portion of the snapshot being indexed changed between oldNode and newNode
*/
indexedValueChanged(oldNode: Node, newNode: Node): boolean;
/**
* @returns a node wrapper that will sort equal to or less than
* any other node wrapper, using this index
*/
minPost(): NamedNode;
/**
* @returns a node wrapper that will sort greater than or equal to
* any other node wrapper, using this index
*/
abstract maxPost(): NamedNode;
abstract makePost(indexValue: unknown, name: string): NamedNode;
/**
* @returns String representation for inclusion in a query spec
*/
abstract toString(): string;
}

View file

@ -0,0 +1,34 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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 { ChildrenNode } from '../ChildrenNode';
import { Node, NamedNode } from '../Node';
import { Index } from './Index';
export declare class KeyIndex extends Index {
static get __EMPTY_NODE(): ChildrenNode;
static set __EMPTY_NODE(val: ChildrenNode);
compare(a: NamedNode, b: NamedNode): number;
isDefinedOn(node: Node): boolean;
indexedValueChanged(oldNode: Node, newNode: Node): boolean;
minPost(): any;
maxPost(): NamedNode;
makePost(indexValue: string, name: string): NamedNode;
/**
* @returns String representation for inclusion in a query spec
*/
toString(): string;
}
export declare const KEY_INDEX: KeyIndex;

View file

@ -0,0 +1,29 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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 { NamedNode, Node } from '../Node';
import { Index } from './Index';
export declare class PathIndex extends Index {
private indexPath_;
constructor(indexPath_: Path);
protected extractChild(snap: Node): Node;
isDefinedOn(node: Node): boolean;
compare(a: NamedNode, b: NamedNode): number;
makePost(indexValue: object, name: string): NamedNode;
maxPost(): NamedNode;
toString(): string;
}

View file

@ -0,0 +1,33 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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 { Index } from './Index';
export declare function setNodeFromJSON(val: (a: unknown) => Node): void;
export declare function setMaxNode(val: Node): void;
export declare class PriorityIndex extends Index {
compare(a: NamedNode, b: NamedNode): number;
isDefinedOn(node: Node): boolean;
indexedValueChanged(oldNode: Node, newNode: Node): boolean;
minPost(): NamedNode;
maxPost(): NamedNode;
makePost(indexValue: unknown, name: string): NamedNode;
/**
* @returns String representation for inclusion in a query spec
*/
toString(): string;
}
export declare const PRIORITY_INDEX: PriorityIndex;

View file

@ -0,0 +1,31 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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 { Index } from './Index';
export declare class ValueIndex extends Index {
compare(a: NamedNode, b: NamedNode): number;
isDefinedOn(node: Node): boolean;
indexedValueChanged(oldNode: Node, newNode: Node): boolean;
minPost(): NamedNode;
maxPost(): NamedNode;
makePost(indexValue: object, name: string): NamedNode;
/**
* @returns String representation for inclusion in a query spec
*/
toString(): string;
}
export declare const VALUE_INDEX: ValueIndex;

View file

@ -0,0 +1,24 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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 priority - Optional priority to use. This will be ignored if the
* passed JSON contains a .priority property.
*/
export declare function nodeFromJSON(json: unknown | null, priority?: unknown): Node;

View file

@ -0,0 +1,23 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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;
export declare const priorityHashText: (priority: string | number) => string;
/**
* Validates that a priority snapshot Node is valid.
*/
export declare const validatePriorityNode: (priorityNode: Node) => void;

View file

@ -0,0 +1,26 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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.
*/
export declare class StatsCollection {
private counters_;
incrementCounter(name: string, amount?: number): void;
get(): {
[k: string]: number;
};
}

View file

@ -0,0 +1,30 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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.
*/
export declare class StatsListener {
private collection_;
private last_;
constructor(collection_: StatsCollection);
get(): {
[k: string]: number;
};
}

View file

@ -0,0 +1,20 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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 '../RepoInfo';
import { StatsCollection } from './StatsCollection';
export declare function statsManagerGetCollection(repoInfo: RepoInfo): StatsCollection;
export declare function statsManagerGetOrCreateReporter<T>(repoInfo: RepoInfo, creatorFunction: () => T): T;

View file

@ -0,0 +1,28 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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 { StatsCollection } from './StatsCollection';
export declare class StatsReporter {
private server_;
private statsListener_;
statsToReport_: {
[k: string]: boolean;
};
constructor(collection: StatsCollection, server_: ServerActions);
private reportStats_;
}
export declare function statsReporterIncludeStat(reporter: StatsReporter, stat: string): void;

View file

@ -0,0 +1,46 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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.
*
*/
export declare class DOMStorageWrapper {
private domStorage_;
private prefix_;
/**
* @param domStorage_ - The underlying storage object (e.g. localStorage or sessionStorage)
*/
constructor(domStorage_: Storage);
/**
* @param key - The key to save the value under
* @param value - The value being stored, or null to remove the key.
*/
set(key: string, value: unknown | null): void;
/**
* @returns The value that was stored under this key, or null
*/
get(key: string): unknown;
remove(key: string): void;
isInMemoryStorage: boolean;
prefixedName_(name: string): string;
toString(): string;
}

View file

@ -0,0 +1,27 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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).
*/
export declare class MemoryStorage {
private cache_;
set(key: string, value: unknown | null): void;
get(key: string): unknown;
remove(key: string): void;
isInMemoryStorage: boolean;
}

View file

@ -0,0 +1,22 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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;

View file

@ -0,0 +1,39 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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_;
constructor(allowedEvents_: string[]);
/**
* To be overridden by derived classes in order to fire an initial event when
* somebody subscribes for data.
*
* @returns {Array.<*>} Array of parameters to trigger initial event with.
*/
abstract getInitialEvent(eventType: string): unknown[];
/**
* To be called by derived classes to trigger events.
*/
protected trigger(eventType: string, ...varArgs: unknown[]): void;
on(eventType: string, callback: (a: unknown) => void, context: unknown): void;
off(eventType: string, callback: (a: unknown) => void, context: unknown): void;
private validateEventType_;
}

View file

@ -0,0 +1,117 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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 { SortedMap } from './SortedMap';
/**
* A tree with immutable elements.
*/
export declare class ImmutableTree<T> {
readonly value: T | null;
readonly children: SortedMap<string, ImmutableTree<T>>;
static fromObject<T>(obj: {
[k: string]: T;
}): ImmutableTree<T>;
constructor(value: T | null, children?: SortedMap<string, ImmutableTree<T>>);
/**
* True if the value is empty and there are no children
*/
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 relativePath - The remainder of the path
* @param predicate - The predicate to satisfy to return a node
*/
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
*/
findRootMostValueAndPath(relativePath: Path): {
path: Path;
value: T;
} | null;
/**
* @returns The subtree at the given path
*/
subtree(relativePath: Path): ImmutableTree<T>;
/**
* Sets a value at the specified path.
*
* @param relativePath - Path to set value at.
* @param toSet - Value to set.
* @returns Resulting tree.
*/
set(relativePath: Path, toSet: T | null): ImmutableTree<T>;
/**
* Removes the value at the specified path.
*
* @param relativePath - Path to value to remove.
* @returns Resulting tree.
*/
remove(relativePath: Path): ImmutableTree<T>;
/**
* Gets a value from the tree.
*
* @param relativePath - Path to get value for.
* @returns Value at path, or null.
*/
get(relativePath: Path): T | null;
/**
* Replace the subtree at the specified path with the given new tree.
*
* @param relativePath - Path to replace subtree for.
* @param newTree - New tree.
* @returns 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
*/
fold<V>(fn: (path: Path, value: T, children: {
[k: string]: V;
}) => V): V;
/**
* Recursive helper for public-facing fold() method
*/
private fold_;
/**
* Find the first matching value on the given path. Return the result of applying f to it.
*/
findOnPath<V>(path: Path, f: (path: Path, value: T) => V | null): V | null;
private findOnPath_;
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 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_;
foreachChild(f: (name: string, value: T) => void): void;
}

View file

@ -0,0 +1,33 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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;
export declare const successor: (key: string) => string;
export declare const predecessor: (key: string) => string;

View file

@ -0,0 +1,31 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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.
*/
export declare class OnlineMonitor extends EventEmitter {
private online_;
static getInstance(): OnlineMonitor;
constructor();
getInitialEvent(eventType: string): boolean[];
currentlyOnline(): boolean;
}

View file

@ -0,0 +1,94 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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 {
pieces_: string[];
pieceNum_: number;
/**
* @param pathOrString - Path string to parse, or another path, or the raw
* tokens array
*/
constructor(pathOrString: string | string[], pieceNum?: number);
toString(): string;
}
export declare function newEmptyPath(): Path;
export declare function pathGetFront(path: Path): string | null;
/**
* @returns The number of segments in this path
*/
export declare function pathGetLength(path: Path): number;
export declare function pathPopFront(path: Path): Path;
export declare function pathGetBack(path: Path): string | null;
export declare function pathToUrlEncodedString(path: Path): string;
/**
* Shallow copy of the parts of the path.
*
*/
export declare function pathSlice(path: Path, begin?: number): string[];
export declare function pathParent(path: Path): Path | null;
export declare function pathChild(path: Path, childPathObj: string | Path): Path;
/**
* @returns True if there are no segments in this path
*/
export declare function pathIsEmpty(path: Path): boolean;
/**
* @returns The path from outerPath to innerPath
*/
export declare function newRelativePath(outerPath: Path, innerPath: Path): Path;
/**
* @returns -1, 0, 1 if left is less, equal, or greater than the right.
*/
export declare function pathCompare(left: Path, right: Path): number;
/**
* @returns true if paths are the same.
*/
export declare function pathEquals(path: Path, other: Path): boolean;
/**
* @returns True if this path is a parent of (or the same as) other
*/
export declare function pathContains(path: Path, 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 {
errorPrefix_: string;
parts_: string[];
/** Initialize to number of '/' chars needed in path. */
byteLength_: number;
/**
* @param path - Initial Path.
* @param errorPrefix_ - Prefix for any error messages.
*/
constructor(path: Path, errorPrefix_: string);
}
export declare function validationPathPush(validationPath: ValidationPath, child: string): void;
export declare function validationPathPop(validationPath: ValidationPath): void;
/**
* String for use in error messages - uses '.' notation for path.
*/
export declare function validationPathToErrorString(validationPath: ValidationPath): string;

View file

@ -0,0 +1,56 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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 { SyncTree } from '../SyncTree';
import { Indexable } from './misc';
import { Path } from './Path';
interface ValueProvider {
getImmediateChild(childName: string): ValueProvider;
node(): Node;
}
/**
* Generate placeholders for deferred values.
*/
export declare const generateWithValues: (values: {
[k: string]: unknown;
}) => {
[k: string]: unknown;
};
/**
* Value to use when firing local events. When writing server values, fire
* local events with an approximate value, otherwise return value as-is.
*/
export declare const resolveDeferredLeafValue: (value: string | number | boolean | {
[k: string]: unknown;
}, existingVal: ValueProvider, serverValues: {
[k: string]: unknown;
}) => string | number | boolean;
/**
* Recursively replace all deferred values and priorities in the tree with the
* specified generated replacement values.
* @param path - path to which write is relative
* @param node - new data written at path
* @param syncTree - current data
*/
export declare const resolveDeferredValueTree: (path: Path, node: Node, syncTree: SyncTree, serverValues: Indexable) => Node;
/**
* 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.
*/
export declare const resolveDeferredValueSnapshot: (node: Node, existing: Node, serverValues: Indexable) => Node;
export {};

View file

@ -0,0 +1,324 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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 nodeStack_;
/**
* @param node - Node to iterate.
* @param isReverse_ - Whether or not to iterate in reverse
*/
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>;
/**
* @param key - Key associated with this node.
* @param value - Value associated with this node.
* @param color - Whether this node is red.
* @param left - Left child.
* @param 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 key - New key for the node, or null.
* @param value - New value for the node, or null.
* @param color - New color for the node, or null.
* @param left - New left child for the node, or null.
* @param right - New right child for the node, or null.
* @returns 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>;
/**
* @returns The total number of nodes in the tree.
*/
count(): number;
/**
* @returns True if the tree is empty.
*/
isEmpty(): boolean;
/**
* Traverses the tree in key order and calls the specified action function
* for each node.
*
* @param action - Callback function to be called for each
* node. If it returns true, traversal is aborted.
* @returns The first truthy value returned by action, or the last falsey
* value returned by action
*/
inorderTraversal(action: (k: K, v: V) => unknown): boolean;
/**
* Traverses the tree in reverse key order and calls the specified action function
* for each node.
*
* @param action - Callback function to be called for each
* node. If it returns true, traversal is aborted.
* @returns True if traversal was aborted.
*/
reverseTraversal(action: (k: K, v: V) => void): boolean;
/**
* @returns The minimum node in the tree.
*/
private min_;
/**
* @returns The maximum key in the tree.
*/
minKey(): K;
/**
* @returns The maximum key in the tree.
*/
maxKey(): K;
/**
* @param key - Key to insert.
* @param value - Value to insert.
* @param comparator - Comparator.
* @returns New tree, with the key/value added.
*/
insert(key: K, value: V, comparator: Comparator<K>): LLRBNode<K, V>;
/**
* @returns New tree, with the minimum key removed.
*/
private removeMin_;
/**
* @param key - The key of the item to remove.
* @param comparator - Comparator.
* @returns New tree, with the specified item removed.
*/
remove(key: K, comparator: Comparator<K>): LLRBNode<K, V> | LLRBEmptyNode<K, V>;
/**
* @returns Whether this is a RED node.
*/
isRed_(): boolean;
/**
* @returns New tree after performing any needed rotations.
*/
private fixUp_;
/**
* @returns New tree, after moveRedLeft.
*/
private moveRedLeft_;
/**
* @returns New tree, after moveRedRight.
*/
private moveRedRight_;
/**
* @returns New tree, after rotateLeft.
*/
private rotateLeft_;
/**
* @returns New tree, after rotateRight.
*/
private rotateRight_;
/**
* @returns Newt ree, after colorFlip.
*/
private colorFlip_;
/**
* For testing.
*
* @returns True if all is well.
*/
private checkMaxDepth_;
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.
*
* @returns 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 key - Key to be added.
* @param value - Value to be added.
* @param comparator - Comparator.
* @returns 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 key - The key to remove.
* @param comparator - Comparator.
* @returns New tree, with item removed.
*/
remove(key: K, comparator: Comparator<K>): LLRBEmptyNode<K, V>;
/**
* @returns The total number of nodes in the tree.
*/
count(): number;
/**
* @returns True if the tree is empty.
*/
isEmpty(): boolean;
/**
* Traverses the tree in key order and calls the specified action function
* for each node.
*
* @param action - Callback function to be called for each
* node. If it returns true, traversal is aborted.
* @returns True if traversal was aborted.
*/
inorderTraversal(action: (k: K, v: V) => unknown): boolean;
/**
* Traverses the tree in reverse key order and calls the specified action function
* for each node.
*
* @param action - Callback function to be called for each
* node. If it returns true, traversal is aborted.
* @returns True if traversal was aborted.
*/
reverseTraversal(action: (k: K, v: V) => void): boolean;
minKey(): null;
maxKey(): null;
check_(): number;
/**
* @returns 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.
*/
static EMPTY_NODE: LLRBEmptyNode<unknown, unknown>;
/**
* @param comparator_ - Key comparator.
* @param 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 key - Key to be added.
* @param value - Value to be added.
* @returns 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 key - The key to remove.
* @returns New map, with item removed.
*/
remove(key: K): SortedMap<K, V>;
/**
* Returns the value of the node with the given key, or null.
*
* @param key - The key to look up.
* @returns 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 key - The key to find the predecessor of
* @returns The predecessor key.
*/
getPredecessorKey(key: K): K | null;
/**
* @returns True if the map is empty.
*/
isEmpty(): boolean;
/**
* @returns The total number of nodes in the map.
*/
count(): number;
/**
* @returns The minimum key in the map.
*/
minKey(): K | null;
/**
* @returns 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 action - Callback function to be called
* for each key/value pair. If action returns true, traversal is aborted.
* @returns The first truthy value returned by action, or the last falsey
* value returned by action
*/
inorderTraversal(action: (k: K, v: V) => unknown): boolean;
/**
* Traverses the map in reverse key order and calls the specified action function
* for each key/value pair.
*
* @param action - Callback function to be called
* for each key/value pair. If action returns true, traversal is aborted.
* @returns True if the traversal was aborted.
*/
reverseTraversal(action: (k: K, v: V) => void): boolean;
/**
* Returns an iterator over the SortedMap.
* @returns 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>;
}

View file

@ -0,0 +1,105 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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 interface TreeNode<T> {
children: Record<string, TreeNode<T>>;
childCount: number;
value?: T;
}
/**
* 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> {
readonly name: string;
readonly parent: Tree<T> | null;
node: TreeNode<T>;
/**
* @param name - Optional name of the node.
* @param parent - Optional parent node.
* @param node - Optional node to wrap.
*/
constructor(name?: string, parent?: Tree<T> | null, node?: TreeNode<T>);
}
/**
* Returns a sub-Tree for the given path.
*
* @param pathObj - Path to look up.
* @returns Tree for path.
*/
export declare function treeSubTree<T>(tree: Tree<T>, pathObj: string | Path): Tree<T>;
/**
* Returns the data associated with this tree node.
*
* @returns The data or null if no data exists.
*/
export declare function treeGetValue<T>(tree: Tree<T>): T | undefined;
/**
* Sets data to this tree node.
*
* @param value - Value to set.
*/
export declare function treeSetValue<T>(tree: Tree<T>, value: T | undefined): void;
/**
* @returns Whether the tree has any children.
*/
export declare function treeHasChildren<T>(tree: Tree<T>): boolean;
/**
* @returns Whether the tree is empty (no value or children).
*/
export declare function treeIsEmpty<T>(tree: Tree<T>): boolean;
/**
* Calls action for each child of this tree node.
*
* @param action - Action to be called for each child.
*/
export declare function treeForEachChild<T>(tree: Tree<T>, action: (tree: Tree<T>) => void): void;
/**
* Does a depth-first traversal of this node's descendants, calling action for each one.
*
* @param action - Action to be called for each child.
* @param includeSelf - Whether to call action on this node as well. Defaults to
* false.
* @param childrenFirst - Whether to call action on children before calling it on
* parent.
*/
export declare function treeForEachDescendant<T>(tree: Tree<T>, action: (tree: Tree<T>) => void, includeSelf?: boolean, childrenFirst?: boolean): void;
/**
* Calls action on each ancestor node.
*
* @param action - Action to be called on each parent; return
* true to abort.
* @param includeSelf - Whether to call action on this node as well.
* @returns true if the action callback returned true.
*/
export declare function treeForEachAncestor<T>(tree: Tree<T>, 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 action - Action to be called for each child.
*/
export declare function treeForEachImmediateDescendantWithValue<T>(tree: Tree<T>, action: (tree: Tree<T>) => void): void;
/**
* @returns The path of this tree node, as a Path.
*/
export declare function treeGetPath<T>(tree: Tree<T>): any;

View file

@ -0,0 +1,23 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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';
export declare class VisibilityMonitor extends EventEmitter {
private visible_;
static getInstance(): VisibilityMonitor;
constructor();
getInitialEvent(eventType: string): boolean[];
}

View file

@ -0,0 +1,32 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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 '../../RepoInfo';
import { Path } from '../Path';
export declare const parseRepoInfo: (dataURL: string, nodeAdmin: boolean) => {
repoInfo: RepoInfo;
path: Path;
};
export declare const parseDatabaseURL: (dataURL: string) => {
host: string;
port: number;
domain: string;
subdomain: string;
secure: boolean;
scheme: string;
pathString: string;
namespace: string;
};

View file

@ -0,0 +1,19 @@
/**
* @license
* Copyright 2019 Google LLC
*
* 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 interface Indexable {
[key: string]: unknown;
}

View file

@ -0,0 +1,176 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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 { QueryContext } from '../view/EventRegistration';
/**
* Returns a locally-unique ID (generated by just incrementing up from 0 each time its called).
*/
export declare const LUIDGenerator: () => number;
/**
* Sha1 hash of the input string
* @param str - The string to hash
* @returns {!string} The resulting hash
*/
export declare const sha1: (str: string) => string;
/**
* Use this for all debug messages in Firebase.
*/
export declare let logger: ((a: string) => void) | null;
/**
* The implementation of Firebase.enableLogging (defined here to break dependencies)
* @param logger_ - A flag to turn on logging, or a custom logger
* @param persistent - Whether or not to persist logging settings across refreshes
*/
export declare const enableLogging: (logger_?: boolean | ((a: string) => void), persistent?: boolean) => void;
export declare const log: (...varArgs: unknown[]) => void;
export declare const logWrapper: (prefix: string) => (...varArgs: unknown[]) => void;
export declare const error: (...varArgs: string[]) => void;
export declare const fatal: (...varArgs: string[]) => never;
export declare const warn: (...varArgs: unknown[]) => 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;
export declare const warnAboutUnsupportedMethod: (methodName: string) => void;
/**
* Returns true if data is NaN, or +/- Infinity.
*/
export declare const isInvalidJSONNumber: (data: unknown) => boolean;
export declare const executeWhenDOMReady: (fn: () => void) => void;
/**
* Minimum key name. Invalid for actual data, used as a marker to sort before any valid names
*/
export declare const MIN_NAME = "[MIN_NAME]";
/**
* Maximum key name. Invalid for actual data, used as a marker to sort above any valid names
*/
export declare const MAX_NAME = "[MAX_NAME]";
/**
* Compares valid Firebase key names, plus min and max name
*/
export declare const nameCompare: (a: string, b: string) => number;
/**
* @returns {!number} comparison result.
*/
export declare const stringCompare: (a: string, b: string) => number;
export declare const requireKey: (key: string, obj: {
[k: string]: unknown;
}) => unknown;
export declare const ObjectToUniqueKey: (obj: unknown) => string;
/**
* Splits a string into a number of smaller segments of maximum size
* @param str - The string
* @param segsize - The maximum number of chars in the string.
* @returns 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: unknown) => void): void;
/**
* Like goog.bind, but doesn't bother to create a closure if opt_context is null/undefined.
* @param callback - Callback function.
* @param context - Optional context to bind to.
*
*/
export declare const bindCallback: (callback: (a: unknown) => void, context?: object | null) => (a: unknown) => void;
/**
* 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 v - A double
*
*/
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).
*/
export declare const isChromeExtensionContentScript: () => boolean;
/**
* Used to detect if we're in a Windows 8 Store app.
*/
export declare const isWindowsStoreApp: () => boolean;
/**
* Converts a server error code to a JavaScript Error
*/
export declare function errorForServerCode(code: string, query: QueryContext): Error;
/**
* Used to test for integer-looking strings
*/
export declare const INTEGER_REGEXP_: RegExp;
/**
* For use in keys, the minimum possible 32-bit integer.
*/
export declare const INTEGER_32_MIN = -2147483648;
/**
* For use in keys, the maximum possible 32-bit integer.
*/
export declare const INTEGER_32_MAX = 2147483647;
/**
* If the string contains a 32-bit integer, return it. Else return null.
*/
export declare const tryParseInt: (str: string) => number | null;
/**
* 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 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 callback - Optional onComplete callback.
* @param varArgs - Arbitrary args to be passed to opt_onComplete
*/
export declare const callUserCallback: (callback?: Function | null, ...varArgs: unknown[]) => void;
/**
* @returns {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.
*/
export declare const exportPropGetter: (object: object, name: string, fnGet: () => unknown) => void;
/**
* Same as setTimeout() except on Node.JS it will /not/ prevent the process from exiting.
*
* It is removed with clearTimeout() as normal.
*
* @param fn - Function to run.
* @param time - Milliseconds to wait before running.
* @returns The setTimeout() return value.
*/
export declare const setTimeoutNonBlocking: (fn: () => void, time: number) => number | object;

View file

@ -0,0 +1,70 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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 '../RepoInfo';
import { Path, ValidationPath } from './Path';
/**
* True for invalid Firebase keys
*/
export declare const INVALID_KEY_REGEX_: RegExp;
/**
* True for invalid Firebase paths.
* Allows '/' in paths.
*/
export declare const INVALID_PATH_REGEX_: RegExp;
/**
* Maximum number of characters to allow in leaf value
*/
export declare const MAX_LEAF_SIZE_: number;
export declare const isValidKey: (key: unknown) => boolean;
export declare const isValidPathString: (pathString: string) => boolean;
export declare const isValidRootPathString: (pathString: string) => boolean;
export declare const isValidPriority: (priority: unknown) => boolean;
/**
* Pre-validate a datum passed as an argument to Firebase function.
*/
export declare const validateFirebaseDataArg: (fnName: string, value: unknown, path: Path, optional: boolean) => void;
/**
* Validate a data object client-side before sending to server.
*/
export declare const validateFirebaseData: (errorPrefix: string, data: unknown, path_: Path | ValidationPath) => void;
/**
* Pre-validate paths passed in the firebase function.
*/
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()).
*/
export declare const validateFirebaseMergeDataArg: (fnName: string, data: unknown, path: Path, optional: boolean) => void;
export declare const validatePriority: (fnName: string, priority: unknown, optional: boolean) => void;
export declare const validateKey: (fnName: string, argumentName: string, key: string, optional: boolean) => void;
/**
* @internal
*/
export declare const validatePathString: (fnName: string, argumentName: string, pathString: string, optional: boolean) => void;
export declare const validateRootPathString: (fnName: string, argumentName: string, pathString: string, optional: boolean) => void;
/**
* @internal
*/
export declare const validateWritablePath: (fnName: string, path: Path) => void;
export declare const validateUrl: (fnName: string, parsedUrl: {
repoInfo: RepoInfo;
path: Path;
}) => void;
export declare const validateString: (fnName: string, argumentName: string, string: unknown, optional: boolean) => void;
export declare const validateObject: (fnName: string, argumentName: string, obj: unknown, optional: boolean) => void;
export declare const validateObjectContainsKey: (fnName: string, argumentName: string, obj: unknown, key: string, optional: boolean, optType?: string) => void;

View file

@ -0,0 +1,23 @@
/**
* @license
* Copyright 2019 Google LLC
*
* 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;
/**
* SDK_VERSION should be set before any database instance is created
* @internal
*/
export declare function setSDKVersion(version: string): void;

View file

@ -0,0 +1,41 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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_;
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
*/
isFullyInitialized(): boolean;
/**
* Returns whether this node is potentially missing children due to a filter applied to the node
*/
isFiltered(): boolean;
isCompleteForPath(path: Path): boolean;
isCompleteForChild(key: string): boolean;
getNode(): Node;
}

View file

@ -0,0 +1,46 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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';
export declare const enum ChangeType {
/** Event type for a child added */
CHILD_ADDED = "child_added",
/** Event type for a child removed */
CHILD_REMOVED = "child_removed",
/** Event type for a child changed */
CHILD_CHANGED = "child_changed",
/** Event type for a child moved */
CHILD_MOVED = "child_moved",
/** Event type for a value change */
VALUE = "value"
}
export interface Change {
/** @param type - The event type */
type: ChangeType;
/** @param snapshotNode - The data */
snapshotNode: Node;
/** @param childName - The name for this child, if it's a child even */
childName?: string;
/** @param oldSnap - Used for intermediate processing of child changed events */
oldSnap?: Node;
/** * @param prevName - The name for the previous child, if applicable */
prevName?: string | null;
}
export declare function changeValue(snapshotNode: Node): Change;
export declare function changeChildAdded(childName: string, snapshotNode: Node): Change;
export declare function changeChildRemoved(childName: string, snapshotNode: Node): Change;
export declare function changeChildChanged(childName: string, snapshotNode: Node, oldSnap: Node): Change;
export declare function changeChildMoved(childName: string, snapshotNode: Node): Change;

View file

@ -0,0 +1,22 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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[];
}

View file

@ -0,0 +1,55 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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 '../snap/indexes/Index';
import { NamedNode, Node } from '../snap/Node';
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 {
getCompleteChild(childKey: string): Node | null;
getChildAfterChild(index: Index, child: NamedNode, reverse: boolean): NamedNode | null;
}
/**
* An implementation of CompleteChildSource that never returns any additional children
*/
export declare class NoCompleteChildSource_ implements CompleteChildSource {
getCompleteChild(childKey?: string): Node | null;
getChildAfterChild(index?: Index, child?: NamedNode, reverse?: boolean): NamedNode | null;
}
/**
* Singleton instance.
*/
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.
*/
export declare class WriteTreeCompleteChildSource implements CompleteChildSource {
private writes_;
private viewCache_;
private optCompleteServerCache_;
constructor(writes_: WriteTreeRef, viewCache_: ViewCache, optCompleteServerCache_?: Node | null);
getCompleteChild(childKey: string): Node | null;
getChildAfterChild(index: Index, child: NamedNode, reverse: boolean): NamedNode | null;
}

View file

@ -0,0 +1,64 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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 as ExpDataSnapshot } from '../../api/Reference_impl';
import { Path } from '../util/Path';
import { EventRegistration } from './EventRegistration';
/**
* Encapsulates the data needed to raise an event
* @interface
*/
export interface Event {
getPath(): Path;
getEventType(): string;
getEventRunner(): () => void;
toString(): string;
}
/**
* One of the following strings: "value", "child_added", "child_changed",
* "child_removed", or "child_moved."
*/
export declare type EventType = 'value' | 'child_added' | 'child_changed' | 'child_moved' | 'child_removed';
/**
* Encapsulates the data needed to raise an event
*/
export declare class DataEvent implements Event {
eventType: EventType;
eventRegistration: EventRegistration;
snapshot: ExpDataSnapshot;
prevName?: string | null;
/**
* @param eventType - One of: value, child_added, child_changed, child_moved, child_removed
* @param eventRegistration - The function to call to with the event data. User provided
* @param snapshot - The data backing the event
* @param prevName - Optional, the name of the previous child for child_* events.
*/
constructor(eventType: EventType, eventRegistration: EventRegistration, snapshot: ExpDataSnapshot, prevName?: string | null);
getPath(): Path;
getEventType(): string;
getEventRunner(): () => void;
toString(): string;
}
export declare class CancelEvent implements Event {
eventRegistration: EventRegistration;
error: Error;
path: Path;
constructor(eventRegistration: EventRegistration, error: Error, path: Path);
getPath(): Path;
getEventType(): string;
getEventRunner(): () => void;
toString(): string;
}

View file

@ -0,0 +1,42 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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 '../snap/indexes/Index';
import { Node } from '../snap/Node';
import { Change } from './Change';
import { Event } from './Event';
import { EventRegistration, QueryContext } from './EventRegistration';
/**
* 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.
*
*/
export declare class EventGenerator {
query_: QueryContext;
index_: Index;
constructor(query_: QueryContext);
}
/**
* 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.
*/
export declare function eventGeneratorGenerateEventsForChanges(eventGenerator: EventGenerator, changes: Change[], eventCache: Node, eventRegistrations: EventRegistration[]): Event[];

View file

@ -0,0 +1,67 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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.
*
*/
export declare class EventQueue {
eventLists_: EventList[];
/**
* Tracks recursion depth of raiseQueuedEvents_, for debugging purposes.
*/
recursionDepth_: number;
}
/**
* @param eventDataList - The new events to queue.
*/
export declare function eventQueueQueueEvents(eventQueue: EventQueue, 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 - The path to raise events for.
* @param eventDataList - The new events to raise.
*/
export declare function eventQueueRaiseEventsAtPath(eventQueue: EventQueue, 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 changedPath - The path to raise events for.
* @param eventDataList - The events to raise
*/
export declare function eventQueueRaiseEventsForChangedPath(eventQueue: EventQueue, changedPath: Path, eventDataList: Event[]): void;
interface EventList {
events: Event[];
path: Path;
}
export {};

View file

@ -0,0 +1,87 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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/Reference_impl';
import { Repo } from '../Repo';
import { Path } from '../util/Path';
import { Change } from './Change';
import { CancelEvent, Event } from './Event';
import { QueryParams } from './QueryParams';
/**
* A user callback. Callbacks issues from the Legacy SDK maintain references
* to the original user-issued callbacks, which allows equality
* comparison by reference even though this callbacks are wrapped before
* they can be passed to the firebase@exp SDK.
*
* @internal
*/
export interface UserCallback {
(dataSnapshot: DataSnapshot, previousChildName?: string | null): unknown;
userCallback?: unknown;
context?: object | null;
}
/**
* A wrapper class that converts events from the database@exp SDK to the legacy
* Database SDK. Events are not converted directly as event registration relies
* on reference comparison of the original user callback (see `matches()`) and
* relies on equality of the legacy SDK's `context` object.
*/
export declare class CallbackContext {
private readonly snapshotCallback;
private readonly cancelCallback?;
constructor(snapshotCallback: UserCallback, cancelCallback?: (error: Error) => unknown);
onValue(expDataSnapshot: DataSnapshot, previousChildName?: string | null): void;
onCancel(error: Error): void;
get hasCancelCallback(): boolean;
matches(other: CallbackContext): boolean;
}
export interface QueryContext {
readonly _queryIdentifier: string;
readonly _queryObject: object;
readonly _repo: Repo;
readonly _path: Path;
readonly _queryParams: QueryParams;
}
/**
* 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
*/
respondsTo(eventType: string): boolean;
createEvent(change: Change, query: QueryContext): Event;
/**
* Given event data, return a function to trigger the user's callback
*/
getEventRunner(eventData: Event): () => void;
createCancelEvent(error: Error, path: Path): CancelEvent | null;
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)
*
*/
hasAnyCallback(): boolean;
}

View file

@ -0,0 +1,95 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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 '../snap/indexes/Index';
import { PriorityIndex } from '../snap/indexes/PriorityIndex';
import { NodeFilter } from './filter/NodeFilter';
/**
* 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.
*
* @internal
*/
export declare class QueryParams {
limitSet_: boolean;
startSet_: boolean;
startNameSet_: boolean;
startAfterSet_: boolean;
endSet_: boolean;
endNameSet_: boolean;
endBeforeSet_: boolean;
limit_: number;
viewFrom_: string;
indexStartValue_: unknown | null;
indexStartName_: string;
indexEndValue_: unknown | null;
indexEndName_: string;
index_: PriorityIndex;
hasStart(): boolean;
/**
* @returns True if it would return from left.
*/
isViewFromLeft(): boolean;
/**
* Only valid to call if hasStart() returns true
*/
getIndexStartValue(): unknown;
/**
* Only valid to call if hasStart() returns true.
* Returns the starting key name for the range defined by these query parameters
*/
getIndexStartName(): string;
hasEnd(): boolean;
/**
* Only valid to call if hasEnd() returns true.
*/
getIndexEndValue(): unknown;
/**
* Only valid to call if hasEnd() returns true.
* Returns the end key name for the range defined by these query parameters
*/
getIndexEndName(): string;
hasLimit(): boolean;
/**
* @returns True if a limit has been set and it has been explicitly anchored
*/
hasAnchoredLimit(): boolean;
/**
* Only valid to call if hasLimit() returns true
*/
getLimit(): number;
getIndex(): Index;
loadsAllData(): boolean;
isDefault(): boolean;
copy(): QueryParams;
}
export declare function queryParamsGetNodeFilter(queryParams: QueryParams): NodeFilter;
export declare function queryParamsLimit(queryParams: QueryParams, newLimit: number): QueryParams;
export declare function queryParamsLimitToFirst(queryParams: QueryParams, newLimit: number): QueryParams;
export declare function queryParamsLimitToLast(queryParams: QueryParams, newLimit: number): QueryParams;
export declare function queryParamsStartAt(queryParams: QueryParams, indexValue: unknown, key?: string | null): QueryParams;
export declare function queryParamsStartAfter(queryParams: QueryParams, indexValue: unknown, key?: string | null): QueryParams;
export declare function queryParamsEndAt(queryParams: QueryParams, indexValue: unknown, key?: string | null): QueryParams;
export declare function queryParamsEndBefore(queryParams: QueryParams, indexValue: unknown, key?: string | null): QueryParams;
export declare function queryParamsOrderBy(queryParams: QueryParams, index: Index): QueryParams;
/**
* Returns a set of REST query string parameters representing this query.
*
* @returns query string parameters
*/
export declare function queryParamsToRestQueryStringParameters(queryParams: QueryParams): Record<string, string | number>;
export declare function queryParamsGetQueryObject(queryParams: QueryParams): Record<string, unknown>;

View file

@ -0,0 +1,59 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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 { Node } from '../snap/Node';
import { Path } from '../util/Path';
import { WriteTreeRef } from '../WriteTree';
import { Event } from './Event';
import { EventGenerator } from './EventGenerator';
import { EventRegistration, QueryContext } from './EventRegistration';
import { ViewCache } from './ViewCache';
import { ViewProcessor } from './ViewProcessor';
/**
* 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.
*/
export declare class View {
private query_;
processor_: ViewProcessor;
viewCache_: ViewCache;
eventRegistrations_: EventRegistration[];
eventGenerator_: EventGenerator;
constructor(query_: QueryContext, initialViewCache: ViewCache);
get query(): QueryContext;
}
export declare function viewGetServerCache(view: View): Node | null;
export declare function viewGetCompleteNode(view: View): Node | null;
export declare function viewGetCompleteServerCache(view: View, path: Path): Node | null;
export declare function viewIsEmpty(view: View): boolean;
export declare function viewAddEventRegistration(view: View, eventRegistration: EventRegistration): void;
/**
* @param eventRegistration - If null, remove all callbacks.
* @param cancelError - If a cancelError is provided, appropriate cancel events will be returned.
* @returns Cancel events, if cancelError was provided.
*/
export declare function viewRemoveEventRegistration(view: View, eventRegistration: EventRegistration | null, cancelError?: Error): Event[];
/**
* Applies the given Operation, updates our cache, and returns the appropriate events.
*/
export declare function viewApplyOperation(view: View, operation: Operation, writesCache: WriteTreeRef, completeServerCache: Node | null): Event[];
export declare function viewGetInitialEvents(view: View, registration: EventRegistration): Event[];

View file

@ -0,0 +1,32 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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 { CacheNode } from './CacheNode';
/**
* 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).
*/
export interface ViewCache {
readonly eventCache: CacheNode;
readonly serverCache: CacheNode;
}
export declare function newViewCache(eventCache: CacheNode, serverCache: CacheNode): ViewCache;
export declare function viewCacheUpdateEventSnap(viewCache: ViewCache, eventSnap: Node, complete: boolean, filtered: boolean): ViewCache;
export declare function viewCacheUpdateServerSnap(viewCache: ViewCache, serverSnap: Node, complete: boolean, filtered: boolean): ViewCache;
export declare function viewCacheGetCompleteEventSnap(viewCache: ViewCache): Node | null;
export declare function viewCacheGetCompleteServerSnap(viewCache: ViewCache): Node | null;

View file

@ -0,0 +1,32 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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 { Node } from '../snap/Node';
import { WriteTreeRef } from '../WriteTree';
import { Change } from './Change';
import { NodeFilter } from './filter/NodeFilter';
import { ViewCache } from './ViewCache';
export interface ProcessorResult {
readonly viewCache: ViewCache;
readonly changes: Change[];
}
export interface ViewProcessor {
readonly filter: NodeFilter;
}
export declare function newViewProcessor(filter: NodeFilter): ViewProcessor;
export declare function viewProcessorAssertIndexed(viewProcessor: ViewProcessor, viewCache: ViewCache): void;
export declare function viewProcessorApplyOperation(viewProcessor: ViewProcessor, oldViewCache: ViewCache, operation: Operation, writesCache: WriteTreeRef, completeCache: Node | null): ProcessorResult;

View file

@ -0,0 +1,35 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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 '../../snap/indexes/Index';
import { Node } from '../../snap/Node';
import { Path } from '../../util/Path';
import { ChildChangeAccumulator } from '../ChildChangeAccumulator';
import { CompleteChildSource } from '../CompleteChildSource';
import { NodeFilter } from './NodeFilter';
/**
* Doesn't really filter nodes but applies an index to the node and keeps track of any changes
*/
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;
updateFullNode(oldSnap: Node, newSnap: Node, optChangeAccumulator: ChildChangeAccumulator | null): Node;
updatePriority(oldSnap: Node, newPriority: Node): Node;
filtersNodes(): boolean;
getIndexedFilter(): IndexedFilter;
getIndex(): Index;
}

View file

@ -0,0 +1,47 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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 '../../snap/indexes/Index';
import { Node } from '../../snap/Node';
import { Path } from '../../util/Path';
import { ChildChangeAccumulator } from '../ChildChangeAccumulator';
import { CompleteChildSource } from '../CompleteChildSource';
import { QueryParams } from '../QueryParams';
import { IndexedFilter } from './IndexedFilter';
import { NodeFilter } from './NodeFilter';
/**
* Applies a limit and a range to a node and uses RangedFilter to do the heavy lifting where possible
*/
export declare class LimitedFilter implements NodeFilter {
private readonly rangedFilter_;
private readonly index_;
private readonly limit_;
private readonly reverse_;
private readonly startIsInclusive_;
private readonly endIsInclusive_;
constructor(params: QueryParams);
updateChild(snap: Node, key: string, newChild: Node, affectedPath: Path, source: CompleteChildSource, optChangeAccumulator: ChildChangeAccumulator | null): Node;
updateFullNode(oldSnap: Node, newSnap: Node, optChangeAccumulator: ChildChangeAccumulator | null): Node;
updatePriority(oldSnap: Node, newPriority: Node): Node;
filtersNodes(): boolean;
getIndexedFilter(): IndexedFilter;
getIndex(): Index;
private fullLimitUpdateChild_;
private withinDirectionalStart;
private withinDirectionalEnd;
private withinStartPost;
private withinEndPost;
}

View file

@ -0,0 +1,54 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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 '../../snap/indexes/Index';
import { Node } from '../../snap/Node';
import { Path } from '../../util/Path';
import { ChildChangeAccumulator } from '../ChildChangeAccumulator';
import { CompleteChildSource } from '../CompleteChildSource';
/**
* 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.
*/
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.
*/
updateFullNode(oldSnap: Node, newSnap: Node, optChangeAccumulator: ChildChangeAccumulator | null): Node;
/**
* Update the priority of the root node
*/
updatePriority(oldSnap: Node, newPriority: Node): Node;
/**
* Returns true if children might be filtered due to query criteria
*/
filtersNodes(): boolean;
/**
* Returns the index filter that this filter uses to get a NodeFilter that doesn't filter any children.
*/
getIndexedFilter(): NodeFilter;
/**
* Returns the index that this filter uses
*/
getIndex(): Index;
}

View file

@ -0,0 +1,47 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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 '../../../core/snap/Node';
import { Index } from '../../snap/indexes/Index';
import { Path } from '../../util/Path';
import { ChildChangeAccumulator } from '../ChildChangeAccumulator';
import { CompleteChildSource } from '../CompleteChildSource';
import { QueryParams } from '../QueryParams';
import { IndexedFilter } from './IndexedFilter';
import { NodeFilter } from './NodeFilter';
/**
* Filters nodes by range and uses an IndexFilter to track any changes after filtering the node
*/
export declare class RangedFilter implements NodeFilter {
private indexedFilter_;
private index_;
private startPost_;
private endPost_;
private startIsInclusive_;
private endIsInclusive_;
constructor(params: QueryParams);
getStartPost(): NamedNode;
getEndPost(): NamedNode;
matches(node: NamedNode): boolean;
updateChild(snap: Node, key: string, newChild: Node, affectedPath: Path, source: CompleteChildSource, optChangeAccumulator: ChildChangeAccumulator | null): Node;
updateFullNode(oldSnap: Node, newSnap: Node, optChangeAccumulator: ChildChangeAccumulator | null): Node;
updatePriority(oldSnap: Node, newPriority: Node): Node;
filtersNodes(): boolean;
getIndexedFilter(): IndexedFilter;
getIndex(): Index;
private static getStartPost_;
private static getEndPost_;
}

View file

@ -0,0 +1,28 @@
/**
* Firebase Realtime Database
*
* @packageDocumentation
*/
/**
* @license
* Copyright 2020 Google LLC
*
* 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 { Database } from './api/Database';
export * from './api';
declare module '@firebase/component' {
interface NameServiceMapping {
'database': Database;
}
}

View file

@ -0,0 +1,17 @@
/**
* @license
* Copyright 2021 Google LLC
*
* 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 * from './api';

View file

@ -0,0 +1,17 @@
/**
* @license
* Copyright 2021 Google LLC
*
* 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 * from './api.standalone';

View file

@ -0,0 +1,38 @@
/**
* @license
* Copyright 2023 Google LLC
*
* 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 { FirebaseAppCheckInternal } from '@firebase/app-check-interop-types';
import { FirebaseApp } from '@firebase/app-types';
import { FirebaseAuthInternal } from '@firebase/auth-interop-types';
import { Database } from '../api.standalone';
/**
* Used by console to create a database based on the app,
* passed database URL and a custom auth implementation.
* @internal
* @param app - A valid FirebaseApp-like object
* @param url - A valid Firebase databaseURL
* @param version - custom version e.g. firebase-admin version
* @param customAppCheckImpl - custom app check implementation
* @param customAuthImpl - custom auth implementation
*/
export declare function _initStandalone({ app, url, version, customAuthImpl, customAppCheckImpl, nodeAdmin }: {
app: FirebaseApp;
url: string;
version: string;
customAuthImpl: FirebaseAuthInternal;
customAppCheckImpl?: FirebaseAppCheckInternal;
nodeAdmin?: boolean;
}): Database;

View file

@ -0,0 +1,198 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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 { PacketReceiver } from './polling/PacketReceiver';
import { Transport } from './Transport';
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.
*/
export declare class BrowserPollConnection implements Transport {
connId: string;
repoInfo: RepoInfo;
private applicationId?;
private appCheckToken?;
private authToken?;
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 connId An identifier for this connection, used for logging
* @param repoInfo The info for the endpoint to send data to.
* @param applicationId The Firebase App ID for this project.
* @param appCheckToken The AppCheck token for this client.
* @param authToken The AuthToken to use for this connection.
* @param transportSessionId Optional transportSessionid if we are
* reconnecting for an existing transport session
* @param lastSessionId Optional lastSessionId if the PersistentConnection has
* already created a connection previously
*/
constructor(connId: string, repoInfo: RepoInfo, applicationId?: string, appCheckToken?: string, authToken?: string, transportSessionId?: string, lastSessionId?: string);
/**
* @param onMessage - Callback when messages arrive
* @param onDisconnect - Callback with connection lost.
*/
open(onMessage: (msg: {}) => void, onDisconnect: (a?: boolean) => void): void;
/**
* Call this when a handshake has completed successfully and we want to consider the connection established
*/
start(): void;
static forceAllow_: boolean;
/**
* Forces long polling to be considered as a potential transport
*/
static forceAllow(): void;
static forceDisallow_: boolean;
/**
* 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 shutdown_;
/**
* Triggered when this transport is closed
*/
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 data - The JSON data to transmit.
*/
send(data: {}): 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).
*/
addDisconnectPingFrame(id: string, pw: string): void;
/**
* Used to track the bytes received by this client
*/
private incrementIncomingBytes_;
}
export interface IFrameElement extends HTMLIFrameElement {
doc: Document;
}
/*********************************************************************************************
* A wrapper around an iframe that is used as a long-polling script holder.
*********************************************************************************************/
export declare class FirebaseIFrameScriptHolder {
onDisconnect: () => void;
urlFn: (a: object) => string;
outstandingRequests: Set<number>;
pendingSegs: Array<{
seg: number;
ts: number;
d: unknown;
}>;
currentSerial: number;
sendNewPolls: boolean;
uniqueCallbackIdentifier: number;
myIFrame: IFrameElement;
alive: boolean;
myID: string;
myPW: string;
commandCB: (command: string, ...args: unknown[]) => void;
onMessageCB: (...args: unknown[]) => void;
/**
* @param commandCB - The callback to be called when control commands are received 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: unknown[]) => void, onMessageCB: (...args: unknown[]) => 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 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 id - The ID of this connection
* @param 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: unknown): void;
/**
* Add a script tag for a regular long-poll request.
* @param url - The URL of the script tag.
* @param serial - The serial number of the request.
*/
private addLongPollTag_;
/**
* Add an arbitrary script tag to the iframe.
* @param url - The URL for the script tag source.
* @param loadCB - A callback to be triggered once the script has loaded.
*/
addTag(url: string, loadCB: () => void): void;
}

View file

@ -0,0 +1,102 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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.
*/
export declare class Connection {
id: string;
private repoInfo_;
private applicationId_;
private appCheckToken_;
private authToken_;
private onMessage_;
private onReady_;
private onDisconnect_;
private onKill_;
lastSessionId?: string;
connectionCount: number;
pendingDataMessages: unknown[];
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 id - an id for this connection
* @param repoInfo_ - the info for the endpoint to connect to
* @param applicationId_ - the Firebase App ID for this project
* @param appCheckToken_ - The App Check Token for this device.
* @param authToken_ - The auth token for this session.
* @param onMessage_ - the callback to be triggered when a server-push message arrives
* @param onReady_ - the callback to be triggered when this connection is ready to send messages.
* @param onDisconnect_ - the callback to be triggered when a connection was lost
* @param onKill_ - the callback to be triggered when this connection has permanently shut down.
* @param lastSessionId - last session id in persistent connection. is used to clean up old session in real-time server
*/
constructor(id: string, repoInfo_: RepoInfo, applicationId_: string | undefined, appCheckToken_: string | undefined, authToken_: string | undefined, onMessage_: (a: {}) => void, onReady_: (a: number, b: string) => void, onDisconnect_: () => void, onKill_: (a: string) => void, lastSessionId?: string);
/**
* Starts a connection attempt
*/
private start_;
private nextTransportId_;
private disconnReceiver_;
private connReceiver_;
/**
* @param 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 handshake - The handshake data returned from the server
*/
private onHandshake_;
private tryStartUpgrade_;
private startUpgrade_;
private onReset_;
private onConnectionEstablished_;
private sendPingOnPrimaryIfNecessary_;
private onSecondaryConnectionLost_;
/**
* @param everConnected - Whether or not the connection ever reached a server. Used to determine if
* we should flush the host cache
*/
private onConnectionLost_;
private onConnectionShutdown_;
private sendData_;
/**
* Cleans up this connection, calling the appropriate callbacks
*/
close(): void;
private closeConnections_;
}

View file

@ -0,0 +1,27 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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_RE: RegExp;
export declare const LAST_SESSION_PARAM = "ls";
export declare const APPLICATION_ID_PARAM = "p";
export declare const APP_CHECK_TOKEN_PARAM = "ac";
export declare const WEBSOCKET = "websocket";
export declare const LONG_POLLING = "long_polling";

View file

@ -0,0 +1,58 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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, applicationId?: string, appCheckToken?: string, authToken?: string, transportSessionId?: string, lastSessionId?: string): Transport;
isAvailable: () => boolean;
responsesRequiredToBeHealthy?: number;
healthyTimeout?: number;
}
export declare abstract class Transport {
/**
* Bytes received since connection started.
*/
abstract bytesReceived: number;
/**
* Bytes sent since connection started.
*/
abstract bytesSent: number;
/**
* An identifier for this connection, used for logging
*/
abstract connId: string;
/**
* @param connId - An identifier for this connection, used for logging
* @param repoInfo - The info for the endpoint to send data to.
* @param transportSessionId - Optional transportSessionId if this is connecting to an existing transport session
* @param lastSessionId - Optional lastSessionId if there was a previous connection
* @interface
*/
constructor(connId: string, repoInfo: RepoInfo, transportSessionId?: string, lastSessionId?: string);
/**
* @param onMessage - Callback when messages arrive
* @param onDisconnect - Callback with connection lost.
*/
abstract open(onMessage: (a: {}) => void, onDisconnect: (a?: boolean) => void): void;
abstract start(): void;
abstract close(): void;
/**
* @param data - The JSON data to transmit
*/
abstract send(data: {}): void;
abstract markConnectionHealthy(): void;
abstract markConnectionHealthy(): void;
}

View file

@ -0,0 +1,50 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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 { BrowserPollConnection } from './BrowserPollConnection';
import { TransportConstructor } from './Transport';
import { WebSocketConnection } from './WebSocketConnection';
/**
* 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.
*/
export declare class TransportManager {
private transports_;
static globalTransportInitialized_: boolean;
static get ALL_TRANSPORTS(): (typeof BrowserPollConnection | typeof WebSocketConnection)[];
/**
* Returns whether transport has been selected to ensure WebSocketConnection or BrowserPollConnection are not called after
* TransportManager has already set up transports_
*/
static get IS_TRANSPORT_INITIALIZED(): boolean;
/**
* @param repoInfo - Metadata around the namespace we're connecting to
*/
constructor(repoInfo: RepoInfo);
private initTransports_;
/**
* @returns The constructor for the initial transport to use
*/
initialTransport(): TransportConstructor;
/**
* @returns The constructor for the next transport, or null
*/
upgradeTransport(): TransportConstructor | null;
}

View file

@ -0,0 +1,127 @@
/**
* @license
* Copyright 2017 Google LLC
*
* 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.
*/
export declare class WebSocketConnection implements Transport {
connId: string;
private applicationId?;
private appCheckToken?;
private authToken?;
keepaliveTimer: number | null;
frames: string[] | null;
totalFrames: number;
bytesSent: number;
bytesReceived: number;
connURL: string;
onDisconnect: (a?: boolean) => void;
onMessage: (msg: {}) => void;
mySock: WebSocket | null;
private log_;
private stats_;
private everConnected_;
private isClosed_;
private nodeAdmin;
/**
* @param connId identifier for this transport
* @param repoInfo The info for the websocket endpoint.
* @param applicationId The Firebase App ID for this project.
* @param appCheckToken The App Check Token for this client.
* @param authToken The Auth Token for this client.
* @param transportSessionId Optional transportSessionId if this is connecting
* to an existing transport session
* @param lastSessionId Optional lastSessionId if there was a previous
* connection
*/
constructor(connId: string, repoInfo: RepoInfo, applicationId?: string, appCheckToken?: string, authToken?: string, transportSessionId?: string, lastSessionId?: string);
/**
* @param repoInfo - The info for the websocket endpoint.
* @param transportSessionId - Optional transportSessionId if this is connecting to an existing transport
* session
* @param lastSessionId - Optional lastSessionId if there was a previous connection
* @returns connection url
*/
private static connectionURL_;
/**
* @param onMessage - Callback when messages arrive
* @param onDisconnect - Callback with connection lost.
*/
open(onMessage: (msg: {}) => 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."
*/
static responsesRequiredToBeHealthy: number;
/**
* Time to wait for the connection te become healthy before giving up.
*/
static healthyTimeout: number;
/**
* Returns true if we previously failed to connect with this transport.
*/
static previouslyFailed(): boolean;
markConnectionHealthy(): void;
private appendFrame_;
/**
* @param frameCount - The number of frames we are expecting from the server
*/
private handleNewFrameCount_;
/**
* Attempts to parse a frame count out of some text. If it can't, assumes a value of 1
* @returns Any remaining data to be process, or null if there is none
*/
private extractFrameCount_;
/**
* Process a websocket frame that has arrived from the server.
* @param mess - The frame data
*/
handleIncomingFrame(mess: {
[k: string]: unknown;
}): void;
/**
* Send a message to the server
* @param data - The JSON object to transmit
*/
send(data: {}): 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 str - String to send.
*/
private sendString_;
}

Some files were not shown because too many files have changed in this diff Show more