Skip to content

Commit

Permalink
docs: fix up docs and max all lines to 140 characters
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaelSolati committed Oct 3, 2018
1 parent f01de43 commit 06af76c
Show file tree
Hide file tree
Showing 8 changed files with 190 additions and 122 deletions.
21 changes: 9 additions & 12 deletions src/collection.ts
Expand Up @@ -3,9 +3,8 @@ import { GeoQuery } from './query';
import { findCoordinatesKey, encodeGeohash, encodeGeoDocument } from './utils';

/**
* A `CollectionReference` object can be used for adding documents, getting
* document references, and querying for documents (using the methods
* inherited from `Query`).
* A `GeoCollectionReference` object can be used for adding documents, getting document references, and querying for documents (using the
* methods inherited from `GeoQuery`).
*/
export class GeoCollectionReference extends GeoQuery {
/**
Expand All @@ -19,26 +18,24 @@ export class GeoCollectionReference extends GeoQuery {
}

/**
* Gets a `CollectionReference` instance of the collection used by the
* GeoCollectionReference. Using this object for queries and other
* Gets a `CollectionReference` instance of the collection used by the GeoCollectionReference. Using this object for queries and other
* commands WILL NOT take advantage of GeoFirestore's geo based logic.
*
* @return The `CollectionReference` instance.
*/
get collection(): GeoFirestoreTypes.cloud.CollectionReference | GeoFirestoreTypes.web.CollectionReference {
return this._collection;
}

/**
* Add a new document to this collection with the specified data, assigning
* it a document ID automatically.
* Add a new document to this collection with the specified data, assigning it a document ID automatically.
*
* @param data An Object containing the data for the new document.
* @param customKey The key of the document to use as the location. Otherwise we default to `coordinates`.
* @return A Promise resolved with a `DocumentReference` pointing to the
* newly created document after it has been written to the backend.
* @return A Promise resolved with a `DocumentReference` pointing to the newly created document after it has been written to the backend.
*/
public add(data: DocumentData, customKey?: string): Promise<GeoFirestoreTypes.cloud.DocumentReference> | Promise<GeoFirestoreTypes.web.DocumentReference> {
public add(
data: DocumentData,
customKey?: string
): Promise<GeoFirestoreTypes.cloud.DocumentReference> | Promise<GeoFirestoreTypes.web.DocumentReference> {
if (Object.prototype.toString.call(data) === '[object Object]') {
const locationKey: string = findCoordinatesKey(data, customKey);
const location: GeoFirestoreTypes.cloud.GeoPoint | GeoFirestoreTypes.web.GeoPoint = data[locationKey];
Expand Down
12 changes: 6 additions & 6 deletions src/firestore.ts
Expand Up @@ -3,7 +3,7 @@ import { GeoCollectionReference } from './collection';
import { GeoWriteBatch } from './writeBatch';

/**
* Creates a GeoFirestore instance.
* `GeoFirestore` represents a Firestore Database and is the entry point for all GeoFirestore operations.
*/
export class GeoFirestore {
/**
Expand All @@ -16,19 +16,19 @@ export class GeoFirestore {
}

/**
* Creates a write batch, used for performing multiple writes as a single
* atomic operation.
* Creates a write batch, used for performing multiple writes as a single atomic operation.
*
* @return A new `GeoWriteBatch` instance.
*/
public batch(): GeoWriteBatch {
return new GeoWriteBatch(this._firestore.batch());
}

/**
* Gets a `GeoCollectionReference` instance that refers to the collection at
* the specified path.
* Gets a `GeoCollectionReference` instance that refers to the collection at the specified path.
*
* @param collectionPath A slash-separated path to a collection.
* @return The `GeoCollectionReference` instance.
* @return A new `GeoCollectionReference` instance.
*/
public collection(collectionPath: string): GeoCollectionReference {
return new GeoCollectionReference(this._firestore.collection(collectionPath));
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Expand Up @@ -2,3 +2,4 @@ export * from './collection';
export * from './firestore';
export * from './query';
export * from './querySnapshot';
export * from './interfaces/firestore';
74 changes: 43 additions & 31 deletions src/query.ts
Expand Up @@ -3,19 +3,27 @@ import { GeoQuerySnapshot } from './querySnapshot';
import { validateQueryCriteria, geohashQueries } from './utils';

/**
* A `GeoQuery` refers to a Query which you can read or listen to. You can also
* construct refined `GeoQuery` objects by adding filters and ordering.
* A `GeoQuery` refers to a Query which you can read or listen to. You can also construct refined `GeoQuery` objects by adding filters and
* ordering.
*/
export class GeoQuery {
private _center: GeoFirestoreTypes.cloud.GeoPoint | GeoFirestoreTypes.web.GeoPoint;
private _radius: number;
private _isWeb: boolean;

constructor(private _query: GeoFirestoreTypes.cloud.Query | GeoFirestoreTypes.web.Query, geoQueryCriteria?: GeoFirestoreTypes.QueryCriteria) {
/**
* @param _query The `Query` instance.
* @param geoQueryCriteria The center and radius of geo based queries.
*/
constructor(
private _query: GeoFirestoreTypes.cloud.Query | GeoFirestoreTypes.web.Query,
geoQueryCriteria?: GeoFirestoreTypes.QueryCriteria
) {
if (Object.prototype.toString.call(_query) !== '[object Object]') {
throw new Error('Query must be an instance of a Firestore Query');
}
this._isWeb = Object.prototype.toString.call((_query as GeoFirestoreTypes.web.CollectionReference).firestore.enablePersistence) === '[object Function]';
this._isWeb = Object.prototype.toString
.call((_query as GeoFirestoreTypes.web.CollectionReference).firestore.enablePersistence) === '[object Function]';
if (geoQueryCriteria) {
// Validate and save the query criteria
validateQueryCriteria(geoQueryCriteria);
Expand All @@ -26,39 +34,38 @@ export class GeoQuery {

/**
* Returns the location signifying the center of this query.
*
* @return The GeoPoint signifying the center of this query.
*/
get center(): GeoFirestoreTypes.cloud.GeoPoint | GeoFirestoreTypes.web.GeoPoint {
return this._center;
}

/**
* The `Firestore` for the Firestore database (useful for performing transactions, etc.).
*/
get firestore(): GeoFirestoreTypes.cloud.Firestore | GeoFirestoreTypes.web.Firestore {
return this._query.firestore;
}

/**
* Returns the center and radius of geo based queries as a QueryCriteria object.
*/
get geoQueryCriteria(): GeoFirestoreTypes.QueryCriteria {
return {
center: this._center,
radius: this._radius
};
}

get firestore(): GeoFirestoreTypes.cloud.Firestore | GeoFirestoreTypes.web.Firestore {
return this._query.firestore;
}

/**
* Gets a `Query`, which you can read or listen to, used by the GeoQuery.
* Using this object for queries and other commands WILL NOT take
* Gets a `Query`, which you can read or listen to, used by the GeoQuery. Using this object for queries and other commands WILL NOT take
* advantage of GeoFirestore's geo based logic.
*
* @return The `Query` instance.
*/
get query(): GeoFirestoreTypes.cloud.Query | GeoFirestoreTypes.web.Query {
return this._query;
}

/**
* Returns the radius of this query, in kilometers.
*
* @return The radius of this query, in kilometers.
*/
get radius(): number {
return this._radius;
Expand All @@ -68,10 +75,8 @@ export class GeoQuery {
* Executes the query and returns the results as a GeoQuerySnapshot.
*
* WEB CLIENT ONLY
* Note: By default, get() attempts to provide up-to-date data when possible
* by waiting for data from the server, but it may return cached data or fail
* if you are offline and the server cannot be reached. This behavior can be
* altered via the `GetOptions` parameter.
* Note: By default, get() attempts to provide up-to-date data when possible by waiting for data from the server, but it may return
* cached data or fail if you are offline and the server cannot be reached. This behavior can be altered via the `GetOptions` parameter.
*
* @param options An object to configure the get behavior.
* @return A Promise that will be resolved with the results of the GeoQuery.
Expand All @@ -81,7 +86,8 @@ export class GeoQuery {
const queries = this._generateQuery().map((query) => this._isWeb ? query.get(options) : query.get());
return Promise.all(queries).then(value => new GeoQuerySnapshot(this._joinQueries(value), this.geoQueryCriteria));
} else {
const promise = this._isWeb ? (this._query as GeoFirestoreTypes.web.Query).get(options) : (this._query as GeoFirestoreTypes.web.Query).get();
const promise = this._isWeb ?
(this._query as GeoFirestoreTypes.web.Query).get(options) : (this._query as GeoFirestoreTypes.web.Query).get();
return promise.then((snapshot) => new GeoQuerySnapshot(snapshot));
}
}
Expand All @@ -90,7 +96,8 @@ export class GeoQuery {
* Attaches a listener for `GeoQuerySnapshot` events.
*
* @param onNext A callback to be called every time a new `GeoQuerySnapshot` is available.
* @param onError A callback to be called if the listen fails or is cancelled. Since multuple queries occur only the failed query will cease.
* @param onError A callback to be called if the listen fails or is cancelled. Since multuple queries occur only the failed query will
* cease.
* @return An unsubscribe function that can be called to cancel the snapshot listener.
*/
public onSnapshot(onNext: (snapshot: GeoQuerySnapshot) => void, onError?: (error: Error) => void): () => void {
Expand Down Expand Up @@ -125,12 +132,10 @@ export class GeoQuery {
}

/**
* Creates and returns a new GeoQuery with the additional filter that documents
* must contain the specified field and that its value should satisfy the
* relation constraint provided.
* Creates and returns a new GeoQuery with the additional filter that documents must contain the specified field and that its value
* should satisfy the relation constraint provided.
*
* This function returns a new (immutable) instance of the GeoQuery (rather
* than modify the existing instance) to impose the filter.
* This function returns a new (immutable) instance of the GeoQuery (rather than modify the existing instance) to impose the filter.
*
* @param fieldPath The path to compare
* @param opStr The operation string (e.g "<", "<=", "==", ">", ">=").
Expand All @@ -145,6 +150,11 @@ export class GeoQuery {
return new GeoQuery(this._query.where(fieldPath, opStr, value), this.geoQueryCriteria);
}

/**
* Creates an array of `Query` objects that query the appropriate geohashes based on the radius and center GeoPoint of the query criteria.
*
* @return Array of Queries to search against.
*/
private _generateQuery(): GeoFirestoreTypes.web.Query[] {
// Get the list of geohashes to query
let geohashesToQuery: string[] = geohashQueries(this._center, this._radius * 1000).map(this._queryToString);
Expand All @@ -159,21 +169,23 @@ export class GeoQuery {
});
}

/**
* Merges the results of an array of QuerySnapshots into one QuerySnapshot (like) object.
*
* @param results An array of QuerySnapshots from multiple queries.
* @return A single QuerySnapshot from an array of QuerySnapshots.
*/
private _joinQueries(results: GeoFirestoreTypes.web.QuerySnapshot[]): GeoFirestoreTypes.web.QuerySnapshot {
const docs = [];
let size = 0;
const docChanges = [];

results.forEach((value: GeoFirestoreTypes.web.QuerySnapshot) => {
docs.concat(value.docs);
size += value.size;
docChanges.concat(value.docChanges());
});

return {
docs,
size,
empty: Boolean(size),
docChanges: () => docChanges
} as GeoFirestoreTypes.web.QuerySnapshot;
}
Expand Down
56 changes: 35 additions & 21 deletions src/querySnapshot.ts
Expand Up @@ -9,21 +9,27 @@ import { generateGeoQueryDocumentSnapshot, validateQueryCriteria } from './utils
* properties.
*/
export class GeoQuerySnapshot {
private _docs: GeoFirestoreTypes.QueryDocumentSnapshot[];
private _center: GeoFirestoreTypes.cloud.GeoPoint | GeoFirestoreTypes.web.GeoPoint;
private _radius: number;

constructor(private _querySnapshot: GeoFirestoreTypes.web.QuerySnapshot | GeoFirestoreTypes.cloud.QuerySnapshot, geoQueryCriteria?: GeoFirestoreTypes.QueryCriteria) {
/**
* @param _querySnapshot The `QuerySnapshot` instance.
* @param geoQueryCriteria The center and radius of geo based queries.
*/
constructor(
private _querySnapshot: GeoFirestoreTypes.web.QuerySnapshot | GeoFirestoreTypes.cloud.QuerySnapshot,
geoQueryCriteria?: GeoFirestoreTypes.QueryCriteria
) {
if (geoQueryCriteria) {
// Validate and save the query criteria
validateQueryCriteria(geoQueryCriteria);
this._center = geoQueryCriteria.center;
this._radius = geoQueryCriteria.radius;
}
}

/** An array of all the documents in the GeoQuerySnapshot. */
get docs(): GeoFirestoreTypes.QueryDocumentSnapshot[] {
return (this._querySnapshot as GeoFirestoreTypes.web.QuerySnapshot).docs.reduce((filtered: GeoFirestoreTypes.QueryDocumentSnapshot[], snapshot: GeoFirestoreTypes.web.QueryDocumentSnapshot) => {
this._docs = (this._querySnapshot as GeoFirestoreTypes.web.QuerySnapshot).docs
.reduce((filtered: GeoFirestoreTypes.QueryDocumentSnapshot[], snapshot: GeoFirestoreTypes.web.QueryDocumentSnapshot) => {
const documentSnapshot = generateGeoQueryDocumentSnapshot(snapshot, this._center);
if (this._center && this._radius) {
if (this._radius >= documentSnapshot.distance) {
Expand All @@ -36,38 +42,46 @@ export class GeoQuerySnapshot {
}, []);
}

/** An array of all the documents in the GeoQuerySnapshot. */
get docs(): GeoFirestoreTypes.QueryDocumentSnapshot[] {
return this._docs;
}

/** The number of documents in the GeoQuerySnapshot. */
get size(): number {
return this._querySnapshot.size;
return this._docs.length;
}

/** True if there are no documents in the GeoQuerySnapshot. */
get empty(): boolean {
return this._querySnapshot.empty;
return Boolean(this._docs.length);
}

/**
* Returns an array of the documents changes since the last snapshot. If
* this is the first snapshot, all documents will be in the list as added
* changes.
*
* @returns Array of DocumentChanges.
*/
public docChanges(): GeoFirestoreTypes.DocumentChange[] {
return (this._querySnapshot.docChanges() as GeoFirestoreTypes.web.DocumentChange[]).reduce((filtered: GeoFirestoreTypes.DocumentChange[], change: GeoFirestoreTypes.web.DocumentChange) => {
const documentChange = {
doc: generateGeoQueryDocumentSnapshot(change.doc, this._center),
newIndex: change.newIndex,
oldIndex: change.oldIndex,
type: change.type
};
if (this._center && this._radius) {
if (this._radius >= documentChange.doc.distance) {
return (this._querySnapshot.docChanges() as GeoFirestoreTypes.web.DocumentChange[])
.reduce((filtered: GeoFirestoreTypes.DocumentChange[], change: GeoFirestoreTypes.web.DocumentChange) => {
const documentChange = {
doc: generateGeoQueryDocumentSnapshot(change.doc, this._center),
newIndex: change.newIndex,
oldIndex: change.oldIndex,
type: change.type
};
if (this._center && this._radius) {
if (this._radius >= documentChange.doc.distance) {
filtered.push(documentChange);
}
} else {
filtered.push(documentChange);
}
} else {
filtered.push(documentChange);
}
return filtered;
}, []);
return filtered;
}, []);
}

/**
Expand Down

0 comments on commit 06af76c

Please sign in to comment.