Skip to content

Commit

Permalink
New bundle analysis to evaluate useFirestorePipelines vs execute
Browse files Browse the repository at this point in the history
  • Loading branch information
MarkDuckworth committed Nov 25, 2024
1 parent 0750f35 commit ecd931d
Show file tree
Hide file tree
Showing 13 changed files with 1,410 additions and 884 deletions.
31 changes: 16 additions & 15 deletions packages/firestore/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ export { PipelineSource } from './lite-api/pipeline-source';

export { PipelineResult } from './lite-api/pipeline-result';

export { Pipeline, pipeline } from './api/pipeline';
export { Pipeline } from './api/pipeline';

export { useFirestorePipelines } from './api/database_augmentation';
export { useFirestorePipelines, pipeline } from './api/pipeline_impl';

export { execute } from './lite-api/pipeline_impl';

Expand Down Expand Up @@ -61,13 +61,13 @@ export {
arrayContainsAny,
arrayContainsAll,
arrayLength,
inAny,
notInAny,
eqAny,
notEqAny,
xor,
ifFunction,
cond,
not,
logicalMax,
logicalMin,
logicalMaximum,
logicalMinimum,
exists,
isNan,
reverse,
Expand All @@ -92,8 +92,8 @@ export {
avgFunction,
andFunction,
orFunction,
min,
max,
minimum,
maximum,
cosineDistance,
dotProduct,
euclideanDistance,
Expand Down Expand Up @@ -132,16 +132,17 @@ export {
ArrayContainsAny,
ArrayLength,
ArrayElement,
In,
EqAny,
NotEqAny,
IsNan,
Exists,
Not,
And,
Or,
Xor,
If,
LogicalMax,
LogicalMin,
Cond,
LogicalMaximum,
LogicalMinimum,
Reverse,
ReplaceFirst,
ReplaceAll,
Expand All @@ -161,8 +162,8 @@ export {
Count,
Sum,
Avg,
Min,
Max,
Minimum,
Maximum,
CosineDistance,
DotProduct,
EuclideanDistance,
Expand Down
57 changes: 0 additions & 57 deletions packages/firestore/src/api/database_augmentation.ts
Original file line number Diff line number Diff line change
@@ -1,57 +0,0 @@
/**
* @license
* Copyright 2024 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 { Pipeline } from '../lite-api/pipeline';
import { PipelineSource } from '../lite-api/pipeline-source';
import { newUserDataReader } from '../lite-api/user_data_reader';
import { DocumentKey } from '../model/document_key';

import { Firestore } from './database';
import { DocumentReference, Query } from './reference';
import { ExpUserDataWriter } from './user_data_writer';

export function useFirestorePipelines(): void {
Firestore.prototype.pipeline = function (): PipelineSource {
const firestore = this;
return new PipelineSource(
this,
newUserDataReader(firestore),
new ExpUserDataWriter(firestore),
(key: DocumentKey) => {
return new DocumentReference(firestore, null, key);
}
);
};

Query.prototype.pipeline = function (): Pipeline {
let pipeline;
if (this._query.collectionGroup) {
pipeline = this.firestore
.pipeline()
.collectionGroup(this._query.collectionGroup);
} else {
pipeline = this.firestore
.pipeline()
.collection(this._query.path.canonicalString());
}

// TODO(pipeline) convert existing query filters, limits, etc into
// pipeline stages

return pipeline;
};
}
100 changes: 100 additions & 0 deletions packages/firestore/src/api/pipeline-source.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/**
* @license
* Copyright 2024 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 { PipelineSource as LitePipelineSoure } from '../lite-api/pipeline-source';
import {
CollectionGroupSource,
CollectionSource,
DatabaseSource,
DocumentsSource
} from '../lite-api/stage';
import { UserDataReader } from '../lite-api/user_data_reader';
import { AbstractUserDataWriter } from '../lite-api/user_data_writer';
import { DocumentKey } from '../model/document_key';
import { cast } from '../util/input_validation';

import { Firestore } from './database';
import { Pipeline } from './pipeline';
import { DocumentReference } from './reference';

/**
* Represents the source of a Firestore {@link Pipeline}.
* @beta
*/
export class PipelineSource extends LitePipelineSoure {
/**
* @internal
* @private
* @param db
* @param userDataReader
* @param userDataWriter
* @param documentReferenceFactory
*/
// eslint-disable-next-line @typescript-eslint/no-useless-constructor
constructor(
db: Firestore,
userDataReader: UserDataReader,
userDataWriter: AbstractUserDataWriter,
documentReferenceFactory: (id: DocumentKey) => DocumentReference
) {
super(db, userDataReader, userDataWriter, documentReferenceFactory);
}

collection(collectionPath: string): Pipeline {
const db = cast<Firestore>(this.db, Firestore);
return new Pipeline(
db,
this.userDataReader,
this.userDataWriter,
this.documentReferenceFactory,
[new CollectionSource(collectionPath)]
);
}

collectionGroup(collectionId: string): Pipeline {
const db = cast<Firestore>(this.db, Firestore);
return new Pipeline(
db,
this.userDataReader,
this.userDataWriter,
this.documentReferenceFactory,
[new CollectionGroupSource(collectionId)]
);
}

database(): Pipeline {
const db = cast<Firestore>(this.db, Firestore);
return new Pipeline(
db,
this.userDataReader,
this.userDataWriter,
this.documentReferenceFactory,
[new DatabaseSource()]
);
}

documents(docs: DocumentReference[]): Pipeline {
const db = cast<Firestore>(this.db, Firestore);
return new Pipeline(
db,
this.userDataReader,
this.userDataWriter,
this.documentReferenceFactory,
[DocumentsSource.of(docs)]
);
}
}
66 changes: 23 additions & 43 deletions packages/firestore/src/api/pipeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,15 @@
* limitations under the License.
*/

import { firestoreClientExecutePipeline } from '../core/firestore_client';
import { Pipeline as LitePipeline } from '../lite-api/pipeline';
import { PipelineResult } from '../lite-api/pipeline-result';
import { PipelineSource } from '../lite-api/pipeline-source';
import { DocumentData, DocumentReference, Query } from '../lite-api/reference';
import { DocumentData, DocumentReference } from '../lite-api/reference';
import { Stage } from '../lite-api/stage';
import { UserDataReader } from '../lite-api/user_data_reader';
import { AbstractUserDataWriter } from '../lite-api/user_data_writer';
import { DocumentKey } from '../model/document_key';
import { cast } from '../util/input_validation';

import { ensureFirestoreConfigured, Firestore } from './database';
import { Firestore } from './database';

export class Pipeline<
AppModelType = DocumentData
Expand Down Expand Up @@ -61,6 +58,24 @@ export class Pipeline<
);
}

protected newPipeline(
db: Firestore,
userDataReader: UserDataReader,
userDataWriter: AbstractUserDataWriter,
documentReferenceFactory: (id: DocumentKey) => DocumentReference,
stages: Stage[],
converter: unknown = {}
): Pipeline<AppModelType> {
return new Pipeline<AppModelType>(
db,
userDataReader,
userDataWriter,
documentReferenceFactory,
stages,
converter
);
}

/**
* Executes this pipeline and returns a Promise to represent the asynchronous operation.
*
Expand Down Expand Up @@ -93,43 +108,8 @@ export class Pipeline<
* @return A Promise representing the asynchronous pipeline execution.
*/
execute(): Promise<Array<PipelineResult<AppModelType>>> {
const firestore = cast(this._db, Firestore);
const client = ensureFirestoreConfigured(firestore);
return firestoreClientExecutePipeline(client, this).then(result => {
const docs = result.map(
element =>
new PipelineResult<AppModelType>(
this.userDataWriter,
element.key?.path
? this.documentReferenceFactory(element.key)
: undefined,
element.fields,
element.executionTime?.toTimestamp(),
element.createTime?.toTimestamp(),
element.updateTime?.toTimestamp()
//this.converter
)
);

return docs;
});
throw new Error(
'Pipelines not initialized. Your application must call `useFirestorePipelines()` before using Firestore Pipeline features.'
);
}
}

/**
* Experimental Modular API for console testing.
* @param firestore
*/
export function pipeline(firestore: Firestore): PipelineSource;

/**
* Experimental Modular API for console testing.
* @param query
*/
export function pipeline(query: Query): Pipeline;

export function pipeline(
firestoreOrQuery: Firestore | Query
): PipelineSource | Pipeline {
return firestoreOrQuery.pipeline();
}
Loading

0 comments on commit ecd931d

Please sign in to comment.