Skip to content
Open
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
d66ddb0
Add PipelineOptions and StructuredPipeline
MarkDuckworth Apr 9, 2025
45688b0
Testing for pipeline options
MarkDuckworth Apr 10, 2025
b3d8c75
Test for error handling in Piplines
MarkDuckworth Aug 25, 2025
281c441
Merge branch 'markduckworth/pipeline-options' into markduckworth/ppl-…
MarkDuckworth Aug 25, 2025
e111ec1
Refactor and test pipeline options implementation
MarkDuckworth Aug 27, 2025
5e9b24d
OptionsUtil test
MarkDuckworth Aug 27, 2025
527131c
Pipeline and stage options. Tangential renames and minor fixes
MarkDuckworth Sep 2, 2025
198f829
Rename and cleanup from api audit
MarkDuckworth Sep 23, 2025
73b0615
Rename and cleanup from api audit
MarkDuckworth Sep 23, 2025
f07a909
Cleanup
MarkDuckworth Sep 24, 2025
f9fef48
Update constant(boolean) to return BooleanExpression
MarkDuckworth Sep 24, 2025
f0cc89b
Add ifError overloads for BooleanExpression
MarkDuckworth Sep 24, 2025
e261a1a
Add abs expression and did formatting
MarkDuckworth Sep 24, 2025
6304b8e
Implemente round with precision and removed Expr#log(base) due to pot…
MarkDuckworth Sep 24, 2025
9f70ee6
Add compile script to package.json for quicker development feedback
MarkDuckworth Sep 24, 2025
bd4efe2
Merge branch 'main' of github.com:firebase/firebase-js-sdk into markd…
MarkDuckworth Sep 24, 2025
e62f29b
Rename esm2017 filenames to esm to match changes in package.json from…
MarkDuckworth Sep 24, 2025
814e268
Fixing circular dependency errors in the build.
MarkDuckworth Sep 26, 2025
4300d65
fixing circular dependency in the build
MarkDuckworth Sep 26, 2025
b78e49c
fixing bundler errors
MarkDuckworth Sep 26, 2025
9695fa4
Fix isNumber implementation
MarkDuckworth Sep 29, 2025
15fc1a7
Merge branch 'main' of github.com:firebase/firebase-js-sdk into markd…
MarkDuckworth Sep 29, 2025
76dca29
Merge branch 'feat/pipelines' of github.com:firebase/firebase-js-sdk …
MarkDuckworth Sep 30, 2025
e9afbe4
fix fishfood build
MarkDuckworth Sep 30, 2025
78e7ae0
Fixing exports
MarkDuckworth Oct 2, 2025
41d8506
Implement concat
MarkDuckworth Oct 2, 2025
5ddc9ce
prettier
MarkDuckworth Oct 2, 2025
2cbd653
error, ifabsent, currenttimestamp, join
MarkDuckworth Oct 2, 2025
c008c06
arraySum and log10
MarkDuckworth Oct 3, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 41 additions & 47 deletions packages/firestore/lite/pipelines/pipelines.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ export type {

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

export { OneOf } from '../../src/util/types';

export {
PipelineResult,
PipelineSnapshot
Expand All @@ -60,94 +62,86 @@ export { Pipeline } from '../../src/lite-api/pipeline';
export { execute } from '../../src/lite-api/pipeline_impl';

export {
Stage,
FindNearestOptions,
AddFields,
Aggregate,
Distinct,
CollectionSource,
CollectionGroupSource,
DatabaseSource,
DocumentsSource,
Where,
FindNearest,
Limit,
Offset,
Select,
Sort,
GenericStage
} from '../../src/lite-api/stage';
StageOptions,
CollectionStageOptions,
CollectionGroupStageOptions,
DatabaseStageOptions,
DocumentsStageOptions,
AddFieldsStageOptions,
RemoveFieldsStageOptions,
SelectStageOptions,
WhereStageOptions,
OffsetStageOptions,
LimitStageOptions,
DistinctStageOptions,
AggregateStageOptions,
FindNearestStageOptions,
ReplaceWithStageOptions,
SampleStageOptions,
UnionStageOptions,
UnnestStageOptions,
SortStageOptions
} from '../../src/lite-api/stage_options';

export {
Expr,
Expression,
field,
and,
array,
arrayOffset,
constant,
add,
subtract,
multiply,
avg,
bitAnd,
substr,
constantVector,
bitLeftShift,
bitNot,
average,
substring,
count,
mapMerge,
mapRemove,
bitOr,
ifError,
isAbsent,
isError,
or,
rand,
bitRightShift,
bitXor,
divide,
isNotNan,
map,
isNotNull,
isNull,
mod,
documentId,
eq,
neq,
lt,
equal,
notEqual,
lessThan,
countIf,
lte,
gt,
gte,
lessThanOrEqual,
greaterThan,
greaterThanOrEqual,
arrayConcat,
arrayContains,
arrayContainsAny,
arrayContainsAll,
arrayLength,
eqAny,
notEqAny,
equalAny,
notEqualAny,
xor,
cond,
conditional,
not,
logicalMaximum,
logicalMinimum,
exists,
isNan,
reverse,
replaceFirst,
replaceAll,
byteLength,
charLength,
like,
regexContains,
regexMatch,
strContains,
stringContains,
startsWith,
endsWith,
toLower,
toUpper,
trim,
strConcat,
stringConcat,
mapGet,
countAll,
minimum,
Expand All @@ -163,17 +157,17 @@ export {
unixSecondsToTimestamp,
timestampToUnixSeconds,
timestampAdd,
timestampSub,
timestampSubtract,
ascending,
descending,
ExprWithAlias,
AliasedExpression,
Field,
Constant,
FunctionExpr,
FunctionExpression,
Ordering,
ExprType,
ExpressionType,
AggregateWithAlias,
Selectable,
BooleanExpr,
BooleanExpression,
AggregateFunction
} from '../../src/lite-api/expressions';
17 changes: 9 additions & 8 deletions packages/firestore/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"author": "Firebase <[email protected]> (https://firebase.google.com/)",
"scripts": {
"bundle": "rollup -c",
"compile": "tsc --emitDeclarationOnly --declaration -p tsconfig.json",
"prebuild": "tsc --emitDeclarationOnly --declaration -p tsconfig.json; yarn api-report",
"build": "run-p --npm-path npm build:lite build:main",
"build:release": "yarn build && yarn typings:public",
Expand Down Expand Up @@ -95,33 +96,33 @@
"require": "./dist/lite/pipelines.node.cjs.js",
"import": "./dist/lite/pipelines.node.mjs"
},
"react-native": "./dist/lite/pipelines.rn.esm2017.js",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

esm2017 to esm renames all come from main

"react-native": "./dist/lite/pipelines.rn.esm.js",
"browser": {
"require": "./dist/lite/pipelines.browser.cjs.js",
"import": "./dist/lite/pipelines.browser.esm2017.js"
"import": "./dist/lite/pipelines.browser.esm.js"
},
"default": "./dist/lite/pipelines.browser.esm2017.js"
"default": "./dist/lite/pipelines.browser.esm.js"
},
"./pipelines": {
"types": "./pipelines/pipelines.d.ts",
"node": {
"require": "./dist/pipelines.node.cjs.js",
"import": "./dist/pipelines.node.mjs"
},
"react-native": "./dist/index.rn.esm2017.js",
"react-native": "./dist/index.rn.esm.js",
"browser": {
"require": "./dist/pipelines.cjs.js",
"import": "./dist/pipelines.esm2017.js"
"import": "./dist/pipelines.esm.js"
},
"default": "./dist/pipelines.esm2017.js"
"default": "./dist/pipelines.esm.js"
},
"./package.json": "./package.json"
},
"main": "dist/node-cjs/index.node.cjs.js",
"main-esm": "dist/node-esm/index.node.mjs",
"react-native": "dist/index.rn.js",
"browser": "dist/index.esm.js",
"module": "dist/index.esm.js",
"browser": "dist/browser-esm2017/index.esm.js",
"module": "dist/browser-esm2017/index.esm.js",
"license": "Apache-2.0",
"files": [
"dist",
Expand Down
4 changes: 2 additions & 2 deletions packages/firestore/rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -178,8 +178,8 @@ const allBuilds = [
output: [
{
dir: 'dist/',
entryFileNames: '[name].esm2017.js',
chunkFileNames: 'common-[hash].esm2017.js',
entryFileNames: '[name].esm.js',
chunkFileNames: 'common-[hash].esm.js',
format: 'es',
sourcemap: true
}
Expand Down
8 changes: 4 additions & 4 deletions packages/firestore/rollup.config.lite.js
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,8 @@ const allBuilds = [
output: [
{
dir: 'dist/lite/',
entryFileNames: '[name].esm2017.js',
chunkFileNames: 'common-[hash].esm2017.js',
entryFileNames: '[name].esm.js',
chunkFileNames: 'common-[hash].esm.js',
format: 'es',
sourcemap: true
}
Expand All @@ -207,8 +207,8 @@ const allBuilds = [
input: ['./lite/index.ts', './lite/pipelines/pipelines.ts'],
output: {
dir: 'dist/lite/',
entryFileNames: '[name].rn.esm2017.js',
chunkFileNames: 'common-[hash].rn.esm2017.js',
entryFileNames: '[name].rn.esm.js',
chunkFileNames: 'common-[hash].rn.esm.js',
format: 'es',
sourcemap: true
},
Expand Down
118 changes: 84 additions & 34 deletions packages/firestore/src/api/pipeline_impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,20 @@

import { Pipeline } from '../api/pipeline';
import { firestoreClientExecutePipeline } from '../core/firestore_client';
import {
StructuredPipeline,
StructuredPipelineOptions
} from '../core/structured_pipeline';
import { Pipeline as LitePipeline } from '../lite-api/pipeline';
import { PipelineResult, PipelineSnapshot } from '../lite-api/pipeline-result';
import { PipelineSource } from '../lite-api/pipeline-source';
import { PipelineExecuteOptions } from '../lite-api/pipeline_options';
import { Stage } from '../lite-api/stage';
import { newUserDataReader } from '../lite-api/user_data_reader';
import {
newUserDataReader,
UserDataReader,
UserDataSource
} from '../lite-api/user_data_reader';
import { cast } from '../util/input_validation';

import { ensureFirestoreConfigured, Firestore } from './database';
Expand Down Expand Up @@ -68,45 +77,86 @@ declare module './database' {
* @param pipeline The pipeline to execute.
* @return A Promise representing the asynchronous pipeline execution.
*/
export function execute(pipeline: LitePipeline): Promise<PipelineSnapshot> {
export function execute(pipeline: LitePipeline): Promise<PipelineSnapshot>;
export function execute(
options: PipelineExecuteOptions
): Promise<PipelineSnapshot>;
export function execute(
pipelineOrOptions: LitePipeline | PipelineExecuteOptions
): Promise<PipelineSnapshot> {
const options: PipelineExecuteOptions = !(
pipelineOrOptions instanceof LitePipeline
)
? pipelineOrOptions
: {
pipeline: pipelineOrOptions
};

const { pipeline, rawOptions, ...rest } = options;

const firestore = cast(pipeline._db, Firestore);
const client = ensureFirestoreConfigured(firestore);
return firestoreClientExecutePipeline(client, pipeline).then(result => {
// Get the execution time from the first result.
// firestoreClientExecutePipeline returns at least one PipelineStreamElement
// even if the returned document set is empty.
const executionTime =
result.length > 0 ? result[0].executionTime?.toTimestamp() : undefined;

const docs = result
// Currently ignore any response from ExecutePipeline that does
// not contain any document data in the `fields` property.
.filter(element => !!element.fields)
.map(
element =>
new PipelineResult(
pipeline._userDataWriter,
element.key?.path
? new DocumentReference(firestore, null, element.key)
: undefined,
element.fields,
element.createTime?.toTimestamp(),
element.updateTime?.toTimestamp()
)
);
const udr = new UserDataReader(
firestore._databaseId,
/* ignoreUndefinedProperties */ true
);
const context = udr.createContext(UserDataSource.Argument, 'execute');

const structuredPipelineOptions = new StructuredPipelineOptions(
rest,
rawOptions
);
structuredPipelineOptions._readUserData(context);

return new PipelineSnapshot(pipeline, docs, executionTime);
});
const structuredPipeline: StructuredPipeline = new StructuredPipeline(
pipeline,
structuredPipelineOptions
);

return firestoreClientExecutePipeline(client, structuredPipeline).then(
result => {
// Get the execution time from the first result.
// firestoreClientExecutePipeline returns at least one PipelineStreamElement
// even if the returned document set is empty.
const executionTime =
result.length > 0 ? result[0].executionTime?.toTimestamp() : undefined;

const docs = result
// Currently ignore any response from ExecutePipeline that does
// not contain any document data in the `fields` property.
.filter(element => !!element.fields)
.map(
element =>
new PipelineResult(
pipeline._userDataWriter,
element.fields!,
element.key?.path
? new DocumentReference(firestore, null, element.key)
: undefined,
element.createTime?.toTimestamp(),
element.updateTime?.toTimestamp()
)
);

return new PipelineSnapshot(pipeline, docs, executionTime);
}
);
}

// Augment the Firestore class with the pipeline() factory method
Firestore.prototype.pipeline = function (): PipelineSource<Pipeline> {
return new PipelineSource<Pipeline>(this._databaseId, (stages: Stage[]) => {
return new Pipeline(
this,
newUserDataReader(this),
new ExpUserDataWriter(this),
stages
);
});
const userDataReader = newUserDataReader(this);
return new PipelineSource<Pipeline>(
this._databaseId,
userDataReader,
(stages: Stage[]) => {
return new Pipeline(
this,
userDataReader,
new ExpUserDataWriter(this),
stages
);
}
);
};
Loading
Loading