Skip to content

Commit

Permalink
pipeline() factory is modular, for bundle size testing
Browse files Browse the repository at this point in the history
  • Loading branch information
MarkDuckworth committed Nov 1, 2024
1 parent fd20eff commit 9bd9a23
Show file tree
Hide file tree
Showing 12 changed files with 289 additions and 141 deletions.
14 changes: 11 additions & 3 deletions common/api-review/firestore-lite.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -1589,6 +1589,14 @@ export class Pipeline<AppModelType = DocumentData> {
where(condition: FilterCondition & Constant): Pipeline<AppModelType>;
}

// @public (undocumented)
export function pipeline(query: Query): Pipeline;

// Warning: (ae-incompatible-release-tags) The symbol "pipeline" is marked as @public, but its signature references "PipelineSource" which is marked as @beta
//
// @public (undocumented)
export function pipeline(firestore: Firestore): PipelineSource;

// @beta
export class PipelineResult<AppModelType = DocumentData> {
/* Excluded from this release type: _ref */
Expand Down Expand Up @@ -2176,8 +2184,8 @@ export function xor(left: FilterExpr, ...right: FilterExpr[]): Xor;

// Warnings were encountered during analysis:
//
// /home/runner/work/firebase-js-sdk/firebase-js-sdk/packages/firestore/dist/lite/index.d.ts:9258:9 - (ae-incompatible-release-tags) The symbol "accumulators" is marked as @public, but its signature references "AccumulatorTarget" which is marked as @beta
// /home/runner/work/firebase-js-sdk/firebase-js-sdk/packages/firestore/dist/lite/index.d.ts:9259:9 - (ae-incompatible-release-tags) The symbol "groups" is marked as @public, but its signature references "Selectable" which is marked as @beta
// /home/runner/work/firebase-js-sdk/firebase-js-sdk/packages/firestore/dist/lite/index.d.ts:9288:9 - (ae-incompatible-release-tags) The symbol "orderings" is marked as @public, but its signature references "Ordering" which is marked as @beta
// /Users/markduckworth/projects/firebase-js-sdk/packages/firestore/dist/lite/index.d.ts:9257:9 - (ae-incompatible-release-tags) The symbol "accumulators" is marked as @public, but its signature references "AccumulatorTarget" which is marked as @beta
// /Users/markduckworth/projects/firebase-js-sdk/packages/firestore/dist/lite/index.d.ts:9258:9 - (ae-incompatible-release-tags) The symbol "groups" is marked as @public, but its signature references "Selectable" which is marked as @beta
// /Users/markduckworth/projects/firebase-js-sdk/packages/firestore/dist/lite/index.d.ts:9287:9 - (ae-incompatible-release-tags) The symbol "orderings" is marked as @public, but its signature references "Ordering" which is marked as @beta

```
58 changes: 43 additions & 15 deletions common/api-review/firestore.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -1073,10 +1073,6 @@ export interface FindNearestOptions {
// @public
export class Firestore {
get app(): FirebaseApp;
// Warning: (ae-incompatible-release-tags) The symbol "pipeline" is marked as @public, but its signature references "PipelineSource" which is marked as @beta
//
// (undocumented)
pipeline: () => PipelineSource;
toJSON(): object;
type: 'firestore-lite' | 'firestore';
}
Expand Down Expand Up @@ -1813,40 +1809,72 @@ export interface PersistentSingleTabManagerSettings {
// @public
export type PersistentTabManager = PersistentSingleTabManager | PersistentMultipleTabManager;

// @public
// @public (undocumented)
export class Pipeline<AppModelType = DocumentData> {
// Warning: (ae-incompatible-release-tags) The symbol "addFields" is marked as @public, but its signature references "Selectable" which is marked as @beta
addFields(...fields: Selectable[]): Pipeline<AppModelType>;
/* Excluded from this release type: __constructor */
// Warning: (ae-incompatible-release-tags) The symbol "aggregate" is marked as @public, but its signature references "AccumulatorTarget" which is marked as @beta
aggregate(...accumulators: AccumulatorTarget[]): Pipeline<AppModelType>;
aggregate(options: {
accumulators: AccumulatorTarget[];
groups?: Array<string | Selectable>;
}): Pipeline<AppModelType>;
/* Excluded from this release type: __constructor */
aggregate(options: { accumulators: AccumulatorTarget[]; groups?: Array<string | Selectable>; }): Pipeline<AppModelType>;
/* Excluded from this release type: __constructor */
// (undocumented)
converter: any;
/* Excluded from this release type: __constructor */
// Warning: (ae-incompatible-release-tags) The symbol "distinct" is marked as @public, but its signature references "Selectable" which is marked as @beta
distinct(...groups: Array<string | Selectable>): Pipeline<AppModelType>;
/* Excluded from this release type: __constructor */
// Warning: (ae-incompatible-release-tags) The symbol "execute" is marked as @public, but its signature references "PipelineResult" which is marked as @beta
execute(): Promise<Array<PipelineResult<AppModelType>>>;
/* Excluded from this release type: __constructor */
// Warning: (ae-incompatible-release-tags) The symbol "findNearest" is marked as @public, but its signature references "FindNearestOptions" which is marked as @beta
//
// (undocumented)
findNearest(options: FindNearestOptions): Pipeline<AppModelType>;
/* Excluded from this release type: __constructor */
genericStage(name: string, params: any[]): Pipeline<AppModelType>;
/* Excluded from this release type: __constructor */
limit(limit: number): Pipeline<AppModelType>;
/* Excluded from this release type: __constructor */
// (undocumented)
liteDb: any;
/* Excluded from this release type: __constructor */
offset(offset: number): Pipeline<AppModelType>;
/* Excluded from this release type: __constructor */
readUserData: any;
/* Excluded from this release type: __constructor */
// Warning: (ae-incompatible-release-tags) The symbol "select" is marked as @public, but its signature references "Selectable" which is marked as @beta
select(...selections: Array<Selectable | string>): Pipeline<AppModelType>;
/* Excluded from this release type: __constructor */
// (undocumented)
selectablesToMap: any;
/* Excluded from this release type: __constructor */
// Warning: (ae-incompatible-release-tags) The symbol "sort" is marked as @public, but its signature references "Ordering" which is marked as @beta
sort(...orderings: Ordering[]): Pipeline<AppModelType>;
/* Excluded from this release type: __constructor */
// (undocumented)
sort(options: { orderings: Ordering[]; }): Pipeline<AppModelType>;
/* Excluded from this release type: __constructor */
// (undocumented)
stages: any;
/* Excluded from this release type: __constructor */
// (undocumented)
sort(options: {
orderings: Ordering[];
}): Pipeline<AppModelType>;
userDataReader: any;
/* Excluded from this release type: __constructor */
// Warning: (ae-incompatible-release-tags) The symbol "where" is marked as @public, but its signature references "FilterCondition" which is marked as @beta
// Warning: (ae-incompatible-release-tags) The symbol "where" is marked as @public, but its signature references "Constant" which is marked as @beta
where(condition: FilterCondition & Constant): Pipeline<AppModelType>;
}

// Warning: (ae-incompatible-release-tags) The symbol "pipeline" is marked as @public, but its signature references "PipelineSource" which is marked as @beta
//
// @public (undocumented)
export function pipeline(firestore: Firestore): PipelineSource;

// @public (undocumented)
export function pipeline(query: Query): Pipeline;

// @beta
export class PipelineResult<AppModelType = DocumentData> {
/* Excluded from this release type: _ref */
Expand Down Expand Up @@ -2464,8 +2492,8 @@ export function xor(left: FilterExpr, ...right: FilterExpr[]): Xor;

// Warnings were encountered during analysis:
//
// /home/runner/work/firebase-js-sdk/firebase-js-sdk/packages/firestore/dist/index.d.ts:10108:9 - (ae-incompatible-release-tags) The symbol "accumulators" is marked as @public, but its signature references "AccumulatorTarget" which is marked as @beta
// /home/runner/work/firebase-js-sdk/firebase-js-sdk/packages/firestore/dist/index.d.ts:10109:9 - (ae-incompatible-release-tags) The symbol "groups" is marked as @public, but its signature references "Selectable" which is marked as @beta
// /home/runner/work/firebase-js-sdk/firebase-js-sdk/packages/firestore/dist/index.d.ts:10138:9 - (ae-incompatible-release-tags) The symbol "orderings" is marked as @public, but its signature references "Ordering" which is marked as @beta
// /Users/markduckworth/projects/firebase-js-sdk/packages/firestore/dist/index.d.ts:10093:26 - (ae-incompatible-release-tags) The symbol "accumulators" is marked as @public, but its signature references "AccumulatorTarget" which is marked as @beta
// /Users/markduckworth/projects/firebase-js-sdk/packages/firestore/dist/index.d.ts:10093:61 - (ae-incompatible-release-tags) The symbol "groups" is marked as @public, but its signature references "Selectable" which is marked as @beta
// /Users/markduckworth/projects/firebase-js-sdk/packages/firestore/dist/index.d.ts:10120:21 - (ae-incompatible-release-tags) The symbol "orderings" is marked as @public, but its signature references "Ordering" which is marked as @beta

```
3 changes: 2 additions & 1 deletion packages/firestore/lite/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,8 @@ export {
updateDoc,
setDoc,
getDoc,
getDocs
getDocs,
pipeline
} from '../src/lite-api/reference_impl';

export {
Expand Down
7 changes: 4 additions & 3 deletions packages/firestore/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@
* limitations under the License.
*/

export { PipelineSource } from './lite-api/pipeline-source';
export { PipelineSource } from './api/pipeline-source';

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

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

export {
Stage,
Expand Down Expand Up @@ -308,7 +308,8 @@ export {
export {
ListenSource,
SnapshotListenOptions,
Unsubscribe
Unsubscribe,
pipeline
} from './api/reference_impl';

export { TransactionOptions } from './api/transaction_options';
Expand Down
18 changes: 1 addition & 17 deletions packages/firestore/src/api/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,13 @@ import {
connectFirestoreEmulator,
Firestore as LiteFirestore
} from '../lite-api/database';
import { PipelineSource } from '../lite-api/pipeline-source';
import { DocumentReference, Query } from '../lite-api/reference';
import { newUserDataReader } from '../lite-api/user_data_reader';
import { Query } from '../lite-api/reference';
import {
indexedDbClearPersistence,
indexedDbStoragePrefix
} from '../local/indexeddb_persistence';
import { LRU_COLLECTION_DISABLED } from '../local/lru_garbage_collector';
import { LRU_MINIMUM_CACHE_SIZE_BYTES } from '../local/lru_garbage_collector_impl';
import { DocumentKey } from '../model/document_key';
import { debugAssert } from '../util/assert';
import { AsyncQueue } from '../util/async_queue';
import { AsyncQueueImpl } from '../util/async_queue_impl';
Expand All @@ -67,7 +64,6 @@ import { Deferred } from '../util/promise';
import { LoadBundleTask } from './bundle';
import { CredentialsProvider } from './credentials';
import { FirestoreSettings, PersistenceSettings } from './settings';
import { ExpUserDataWriter } from './user_data_writer';

export {
connectFirestoreEmulator,
Expand Down Expand Up @@ -108,18 +104,6 @@ export class Firestore extends LiteFirestore {
_online: OnlineComponentProviderFactory;
};

pipeline = (): PipelineSource => {
const firestore = this;
return new PipelineSource(
this,
newUserDataReader(firestore),
new ExpUserDataWriter(firestore),
(key: DocumentKey) => {
return new DocumentReference(firestore, null, key);
}
);
};

/** @hideconstructor */
constructor(
authCredentialsProvider: CredentialsProvider<User>,
Expand Down
88 changes: 88 additions & 0 deletions packages/firestore/src/api/pipeline-source.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// 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 {
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 { Firestore } from './database';
import { Pipeline } from './pipeline';
import { DocumentReference } from './reference';

/**
* Represents the source of a Firestore {@link Pipeline}.
* @beta
*/
export class PipelineSource {
/**
* @internal
* @private
* @param db
* @param userDataReader
* @param userDataWriter
* @param documentReferenceFactory
*/
constructor(
private db: Firestore,
private userDataReader: UserDataReader,
private userDataWriter: AbstractUserDataWriter,
private documentReferenceFactory: (id: DocumentKey) => DocumentReference
) {}

collection(collectionPath: string): Pipeline {
return new Pipeline(
this.db,
this.userDataReader,
this.userDataWriter,
this.documentReferenceFactory,
[new CollectionSource(collectionPath)]
);
}

collectionGroup(collectionId: string): Pipeline {
return new Pipeline(
this.db,
this.userDataReader,
this.userDataWriter,
this.documentReferenceFactory,
[new CollectionGroupSource(collectionId)]
);
}

database(): Pipeline {
return new Pipeline(
this.db,
this.userDataReader,
this.userDataWriter,
this.documentReferenceFactory,
[new DatabaseSource()]
);
}

documents(docs: DocumentReference[]): Pipeline {
return new Pipeline(
this.db,
this.userDataReader,
this.userDataWriter,
this.documentReferenceFactory,
[DocumentsSource.of(docs)]
);
}
}
56 changes: 55 additions & 1 deletion packages/firestore/src/api/reference_impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import {
NextFn,
PartialObserver
} from '../api/observer';
import { Pipeline } from '../api/pipeline';
import { PipelineSource } from '../api/pipeline-source';
import { ListenerDataSource } from '../core/event_manager';
import {
firestoreClientAddSnapshotsInSyncListener,
Expand Down Expand Up @@ -57,9 +59,10 @@ import {
parseUpdateData,
parseUpdateVarargs
} from '../lite-api/user_data_reader';
import { DocumentKey } from '../model/document_key';
import { DeleteMutation, Mutation, Precondition } from '../model/mutation';
import { debugAssert } from '../util/assert';
import { FirestoreError } from '../util/error';
import { Code, FirestoreError } from '../util/error';
import { cast } from '../util/input_validation';

import { ensureFirestoreConfigured, Firestore } from './database';
Expand Down Expand Up @@ -842,3 +845,54 @@ function convertToDocSnapshot<AppModelType, DbModelType extends DocumentData>(
ref.converter
);
}

/**
* @private
* @internal
*/
function _pipeline(query: Query): Pipeline {
let pipeline: Pipeline;
const firestore = cast(query.firestore, Firestore);
if (query._query.collectionGroup) {
pipeline = _pipelineSource(firestore).collectionGroup(
query._query.collectionGroup
);
} else {
pipeline = _pipelineSource(firestore).collection(
query._query.path.canonicalString()
);
}

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

return pipeline;
}

function _pipelineSource(firestore: Firestore): PipelineSource {
return new PipelineSource(
firestore,
newUserDataReader(firestore),
new ExpUserDataWriter(firestore),
(key: DocumentKey) => {
return new DocumentReference(firestore, null, key);
}
);
}

export function pipeline(firestore: Firestore): PipelineSource;
export function pipeline(query: Query): Pipeline;
export function pipeline(
queryOrFirestore: Query | Firestore
): Pipeline | PipelineSource {
if (queryOrFirestore instanceof Query) {
return _pipeline(queryOrFirestore);
} else if (queryOrFirestore instanceof Firestore) {
return _pipelineSource(queryOrFirestore);
}

throw new FirestoreError(
Code.INVALID_ARGUMENT,
'pipeline() requires argument of type Firestore or Query'
);
}
Loading

0 comments on commit 9bd9a23

Please sign in to comment.