Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
fdc4c4e
fix lint errors
morganchen12 Nov 11, 2025
0b3d4d1
fix missing header
morganchen12 Nov 11, 2025
55524cb
remove file that caused build breakages
morganchen12 Nov 11, 2025
a077cba
fix c++ format error
cherylEnkidu Nov 11, 2025
8e23996
remove duplicate vector
cherylEnkidu Nov 12, 2025
c10da97
fix c++ type error
cherylEnkidu Nov 12, 2025
c2572eb
fix type error 2
cherylEnkidu Nov 12, 2025
770a728
fix more type error
cherylEnkidu Nov 12, 2025
559a355
try solving assertion failure
cherylEnkidu Nov 12, 2025
9035aad
try another flag
cherylEnkidu Nov 13, 2025
e0fe92d
test ASSERT_DEATH on github ci
cherylEnkidu Nov 13, 2025
8b7df8c
test new flag: ABSL_HAVE_EXCEPTIONS
cherylEnkidu Nov 13, 2025
8cce4af
verify behaviour
cherylEnkidu Nov 14, 2025
f83e670
test reverted re2 version
cherylEnkidu Nov 14, 2025
e2e053d
add cmake settings
cherylEnkidu Nov 14, 2025
d462e20
add absl cmake settings
cherylEnkidu Nov 14, 2025
d1f9c98
Merge branch 'feat/pipeline/private-preview' into mc/format
cherylEnkidu Nov 17, 2025
f90bdfe
revert changes
cherylEnkidu Nov 17, 2025
44195b8
fix stack-use-after-scope
cherylEnkidu Nov 17, 2025
0a30c20
remove unnessary changes
cherylEnkidu Nov 17, 2025
af72cd8
enable emulator EXPERIMENTAL_MODE
cherylEnkidu Nov 17, 2025
5721bf9
update emulator version
cherylEnkidu Nov 18, 2025
ac6286e
remove echo
cherylEnkidu Nov 19, 2025
454c75e
rename some expressions
cherylEnkidu Nov 21, 2025
f9c2439
fix broken tests
cherylEnkidu Nov 21, 2025
d63d845
merge in private preview feature branch
cherylEnkidu Nov 24, 2025
31b3944
solve merge error
cherylEnkidu Nov 24, 2025
4d348f7
expose public API of realtime Pipeline
cherylEnkidu Nov 24, 2025
b34463a
add Expression.asBoolean
cherylEnkidu Nov 26, 2025
dfe4976
add tests and format code
cherylEnkidu Nov 26, 2025
9da9f0e
add documentation
cherylEnkidu Nov 26, 2025
01d7430
Update Firestore/Swift/Source/SwiftAPI/Pipeline/Expressions/FunctionE…
cherylEnkidu Nov 26, 2025
233d9d6
Update Firestore/Swift/Source/SwiftAPI/Pipeline/Expressions/FunctionE…
cherylEnkidu Nov 26, 2025
dfc9c5f
format
cherylEnkidu Nov 26, 2025
0dae5a9
Merge branch 'cheryl/AddExprAsBool' into cheryl/realppl1
cherylEnkidu Nov 26, 2025
1a267b1
fix hanging test
cherylEnkidu Nov 28, 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
14 changes: 11 additions & 3 deletions Firestore/Example/Firestore.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -823,6 +823,9 @@
621D620B28F9CE7400D2FA26 /* QueryIntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 621D620928F9CE7400D2FA26 /* QueryIntegrationTests.swift */; };
621D620C28F9CE7400D2FA26 /* QueryIntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 621D620928F9CE7400D2FA26 /* QueryIntegrationTests.swift */; };
623AA12C3481646B0715006D /* string_apple_test.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0EE5300F8233D14025EF0456 /* string_apple_test.mm */; };
6271643C2ED4D5F400D2CD1D /* RealtimePipelineTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6271643B2ED4D5EE00D2CD1D /* RealtimePipelineTests.swift */; };
6271643D2ED4D5F400D2CD1D /* RealtimePipelineTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6271643B2ED4D5EE00D2CD1D /* RealtimePipelineTests.swift */; };
6271643E2ED4D5F400D2CD1D /* RealtimePipelineTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6271643B2ED4D5EE00D2CD1D /* RealtimePipelineTests.swift */; };
627253FDEC6BB5549FE77F4E /* tree_sorted_map_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 549CCA4D20A36DBB00BCEB75 /* tree_sorted_map_test.cc */; };
62B1C1100A8C68D94565916C /* document_overlay_cache_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = FFCA39825D9678A03D1845D0 /* document_overlay_cache_test.cc */; };
62C86789E72E624A27BF6AE5 /* complex_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B32C2DDDEC16F6465317B8AE /* complex_test.cc */; };
Expand Down Expand Up @@ -2143,6 +2146,7 @@
61F72C5520BC48FD001A68CB /* serializer_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = serializer_test.cc; sourceTree = "<group>"; };
620C1427763BA5D3CCFB5A1F /* BridgingHeader.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = BridgingHeader.h; sourceTree = "<group>"; };
621D620928F9CE7400D2FA26 /* QueryIntegrationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QueryIntegrationTests.swift; sourceTree = "<group>"; };
6271643B2ED4D5EE00D2CD1D /* RealtimePipelineTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RealtimePipelineTests.swift; sourceTree = "<group>"; };
62CF8E2E7611B285B46228FE /* Pods-Firestore_IntegrationTests_iOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Firestore_IntegrationTests_iOS.release.xcconfig"; path = "Target Support Files/Pods-Firestore_IntegrationTests_iOS/Pods-Firestore_IntegrationTests_iOS.release.xcconfig"; sourceTree = "<group>"; };
62E54B832A9E910A003347C8 /* IndexingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IndexingTests.swift; sourceTree = "<group>"; };
63136A2371C0C013EC7A540C /* target_index_matcher_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = target_index_matcher_test.cc; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2499,6 +2503,7 @@
861684E49DAC993D153E60D0 /* PipelineTests.swift */,
621D620928F9CE7400D2FA26 /* QueryIntegrationTests.swift */,
128F2B002E254E2C0006327E /* QueryToPipelineTests.swift */,
6271643B2ED4D5EE00D2CD1D /* RealtimePipelineTests.swift */,
4D65F6E69993611D47DC8E7C /* SnapshotListenerSourceTests.swift */,
EFF22EA92C5060A4009A369B /* VectorIntegrationTests.swift */,
);
Expand Down Expand Up @@ -4978,6 +4983,7 @@
655F8647F57E5F2155DFF7B5 /* PipelineTests.swift in Sources */,
621D620C28F9CE7400D2FA26 /* QueryIntegrationTests.swift in Sources */,
128F2B022E254E2C0006327E /* QueryToPipelineTests.swift in Sources */,
6271643E2ED4D5F400D2CD1D /* RealtimePipelineTests.swift in Sources */,
1CFBD4563960D8A20C4679A3 /* SnapshotListenerSourceTests.swift in Sources */,
EE4C4BE7F93366AE6368EE02 /* TestHelper.swift in Sources */,
EFF22EAC2C5060A4009A369B /* VectorIntegrationTests.swift in Sources */,
Expand Down Expand Up @@ -5012,8 +5018,8 @@
E3E6B368A755D892F937DBF7 /* collection_group_test.cc in Sources */,
064689971747DA312770AB7A /* collection_test.cc in Sources */,
1DB3013C5FC736B519CD65A3 /* common.pb.cc in Sources */,
99F97B28DA546D42AB14214B /* comparison_test.cc in Sources */,
555161D6DB2DDC8B57F72A70 /* comparison_test.cc in Sources */,
99F97B28DA546D42AB14214B /* comparison_test.cc in Sources */,
BB5F19878EA5A8D9C7276D40 /* complex_test.cc in Sources */,
7394B5C29C6E524C2AF964E6 /* counting_query_engine.cc in Sources */,
C02A969BF4BB63ABCB531B4B /* create_noop_connectivity_monitor.cc in Sources */,
Expand Down Expand Up @@ -5259,6 +5265,7 @@
C8C2B945D84DD98391145F3F /* PipelineTests.swift in Sources */,
621D620B28F9CE7400D2FA26 /* QueryIntegrationTests.swift in Sources */,
128F2B032E254E2C0006327E /* QueryToPipelineTests.swift in Sources */,
6271643C2ED4D5F400D2CD1D /* RealtimePipelineTests.swift in Sources */,
A0BC30D482B0ABD1A3A24CDC /* SnapshotListenerSourceTests.swift in Sources */,
A78366DBE0BFDE42474A728A /* TestHelper.swift in Sources */,
EFF22EAB2C5060A4009A369B /* VectorIntegrationTests.swift in Sources */,
Expand Down Expand Up @@ -5293,8 +5300,8 @@
1CDA0E10BC669276E0EAA1E8 /* collection_group_test.cc in Sources */,
C87DF880BADEA1CBF8365700 /* collection_test.cc in Sources */,
1D71CA6BBA1E3433F243188E /* common.pb.cc in Sources */,
476AE05E0878007DE1BF5460 /* comparison_test.cc in Sources */,
9C86EEDEA131BFD50255EEF1 /* comparison_test.cc in Sources */,
476AE05E0878007DE1BF5460 /* comparison_test.cc in Sources */,
C5434EF8A0C8B79A71F0784C /* complex_test.cc in Sources */,
DCD83C545D764FB15FD88B02 /* counting_query_engine.cc in Sources */,
ECC433628575AE994C621C54 /* create_noop_connectivity_monitor.cc in Sources */,
Expand Down Expand Up @@ -5822,6 +5829,7 @@
E04CB0D580980748D5DC453F /* PipelineTests.swift in Sources */,
621D620A28F9CE7400D2FA26 /* QueryIntegrationTests.swift in Sources */,
128F2B012E254E2C0006327E /* QueryToPipelineTests.swift in Sources */,
6271643D2ED4D5F400D2CD1D /* RealtimePipelineTests.swift in Sources */,
B00F8D1819EE20C45B660940 /* SnapshotListenerSourceTests.swift in Sources */,
AD34726BFD3461FF64BBD56D /* TestHelper.swift in Sources */,
EFF22EAA2C5060A4009A369B /* VectorIntegrationTests.swift in Sources */,
Expand Down Expand Up @@ -5856,8 +5864,8 @@
4A6B1E0B678E31367A55DC17 /* collection_group_test.cc in Sources */,
BACA9CDF0F2E926926B5F36F /* collection_test.cc in Sources */,
4C66806697D7BCA730FA3697 /* common.pb.cc in Sources */,
C885C84B7549C860784E4E3C /* comparison_test.cc in Sources */,
EC7A44792A5513FBB6F501EE /* comparison_test.cc in Sources */,
C885C84B7549C860784E4E3C /* comparison_test.cc in Sources */,
62C86789E72E624A27BF6AE5 /* complex_test.cc in Sources */,
BDF3A6C121F2773BB3A347A7 /* counting_query_engine.cc in Sources */,
1F4930A8366F74288121F627 /* create_noop_connectivity_monitor.cc in Sources */,
Expand Down
133 changes: 92 additions & 41 deletions Firestore/Swift/Source/ExpressionImplementation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,24 @@ extension Expression {
}

public extension Expression {
func asBoolean() -> BooleanExpression {
switch self {
case let boolExpr as BooleanExpression:
return boolExpr
case let constant as Constant:
return BooleanConstant(constant)
case let field as Field:
return BooleanField(field)
case let funcExpr as FunctionExpression:
return BooleanFunctionExpression(funcExpr)
default:
// This should be unreachable if all expression types are handled.
fatalError(
"Unknown expression type \(Swift.type(of: self)) cannot be converted to BooleanExpression"
)
}
}

func `as`(_ name: String) -> AliasedExpression {
return AliasedExpression(self, name)
}
Expand Down Expand Up @@ -474,38 +492,56 @@ public extension Expression {
}

func arrayContains(_ element: Expression) -> BooleanExpression {
return BooleanExpression(functionName: "array_contains", args: [self, element])
return BooleanFunctionExpression(functionName: "array_contains", args: [self, element])
}

func arrayContains(_ element: Sendable) -> BooleanExpression {
return BooleanExpression(
return BooleanFunctionExpression(
functionName: "array_contains",
args: [self, Helper.sendableToExpr(element)]
)
}

func arrayContainsAll(_ values: [Expression]) -> BooleanExpression {
return BooleanExpression(functionName: "array_contains_all", args: [self, Helper.array(values)])
return BooleanFunctionExpression(
functionName: "array_contains_all",
args: [self, Helper.array(values)]
)
}

func arrayContainsAll(_ values: [Sendable]) -> BooleanExpression {
return BooleanExpression(functionName: "array_contains_all", args: [self, Helper.array(values)])
return BooleanFunctionExpression(
functionName: "array_contains_all",
args: [self, Helper.array(values)]
)
}

func arrayContainsAll(_ arrayExpression: Expression) -> BooleanExpression {
return BooleanExpression(functionName: "array_contains_all", args: [self, arrayExpression])
return BooleanFunctionExpression(
functionName: "array_contains_all",
args: [self, arrayExpression]
)
}

func arrayContainsAny(_ values: [Expression]) -> BooleanExpression {
return BooleanExpression(functionName: "array_contains_any", args: [self, Helper.array(values)])
return BooleanFunctionExpression(
functionName: "array_contains_any",
args: [self, Helper.array(values)]
)
}

func arrayContainsAny(_ values: [Sendable]) -> BooleanExpression {
return BooleanExpression(functionName: "array_contains_any", args: [self, Helper.array(values)])
return BooleanFunctionExpression(
functionName: "array_contains_any",
args: [self, Helper.array(values)]
)
}

func arrayContainsAny(_ arrayExpression: Expression) -> BooleanExpression {
return BooleanExpression(functionName: "array_contains_any", args: [self, arrayExpression])
return BooleanFunctionExpression(
functionName: "array_contains_any",
args: [self, arrayExpression]
)
}

func arrayLength() -> FunctionExpression {
Expand All @@ -532,96 +568,105 @@ public extension Expression {
}

func greaterThan(_ other: Expression) -> BooleanExpression {
return BooleanExpression(functionName: "greater_than", args: [self, other])
return BooleanFunctionExpression(functionName: "greater_than", args: [self, other])
}

func greaterThan(_ other: Sendable) -> BooleanExpression {
let exprOther = Helper.sendableToExpr(other)
return BooleanExpression(functionName: "greater_than", args: [self, exprOther])
return BooleanFunctionExpression(functionName: "greater_than", args: [self, exprOther])
}

func greaterThanOrEqual(_ other: Expression) -> BooleanExpression {
return BooleanExpression(functionName: "greater_than_or_equal", args: [self, other])
return BooleanFunctionExpression(functionName: "greater_than_or_equal", args: [self, other])
}

func greaterThanOrEqual(_ other: Sendable) -> BooleanExpression {
let exprOther = Helper.sendableToExpr(other)
return BooleanExpression(functionName: "greater_than_or_equal", args: [self, exprOther])
return BooleanFunctionExpression(functionName: "greater_than_or_equal", args: [self, exprOther])
}

func lessThan(_ other: Expression) -> BooleanExpression {
return BooleanExpression(functionName: "less_than", args: [self, other])
return BooleanFunctionExpression(functionName: "less_than", args: [self, other])
}

func lessThan(_ other: Sendable) -> BooleanExpression {
let exprOther = Helper.sendableToExpr(other)
return BooleanExpression(functionName: "less_than", args: [self, exprOther])
return BooleanFunctionExpression(functionName: "less_than", args: [self, exprOther])
}

func lessThanOrEqual(_ other: Expression) -> BooleanExpression {
return BooleanExpression(functionName: "less_than_or_equal", args: [self, other])
return BooleanFunctionExpression(functionName: "less_than_or_equal", args: [self, other])
}

func lessThanOrEqual(_ other: Sendable) -> BooleanExpression {
let exprOther = Helper.sendableToExpr(other)
return BooleanExpression(functionName: "less_than_or_equal", args: [self, exprOther])
return BooleanFunctionExpression(functionName: "less_than_or_equal", args: [self, exprOther])
}

func equal(_ other: Expression) -> BooleanExpression {
return BooleanExpression(functionName: "equal", args: [self, other])
return BooleanFunctionExpression(functionName: "equal", args: [self, other])
}

func equal(_ other: Sendable) -> BooleanExpression {
let exprOther = Helper.sendableToExpr(other)
return BooleanExpression(functionName: "equal", args: [self, exprOther])
return BooleanFunctionExpression(functionName: "equal", args: [self, exprOther])
}

func notEqual(_ other: Expression) -> BooleanExpression {
return BooleanExpression(functionName: "not_equal", args: [self, other])
return BooleanFunctionExpression(functionName: "not_equal", args: [self, other])
}

func notEqual(_ other: Sendable) -> BooleanExpression {
return BooleanExpression(functionName: "not_equal", args: [self, Helper.sendableToExpr(other)])
return BooleanFunctionExpression(
functionName: "not_equal",
args: [self, Helper.sendableToExpr(other)]
)
}

func equalAny(_ others: [Expression]) -> BooleanExpression {
return BooleanExpression(functionName: "equal_any", args: [self, Helper.array(others)])
return BooleanFunctionExpression(functionName: "equal_any", args: [self, Helper.array(others)])
}

func equalAny(_ others: [Sendable]) -> BooleanExpression {
return BooleanExpression(functionName: "equal_any", args: [self, Helper.array(others)])
return BooleanFunctionExpression(functionName: "equal_any", args: [self, Helper.array(others)])
}

func equalAny(_ arrayExpression: Expression) -> BooleanExpression {
return BooleanExpression(functionName: "equal_any", args: [self, arrayExpression])
return BooleanFunctionExpression(functionName: "equal_any", args: [self, arrayExpression])
}

func notEqualAny(_ others: [Expression]) -> BooleanExpression {
return BooleanExpression(functionName: "not_equal_any", args: [self, Helper.array(others)])
return BooleanFunctionExpression(
functionName: "not_equal_any",
args: [self, Helper.array(others)]
)
}

func notEqualAny(_ others: [Sendable]) -> BooleanExpression {
return BooleanExpression(functionName: "not_equal_any", args: [self, Helper.array(others)])
return BooleanFunctionExpression(
functionName: "not_equal_any",
args: [self, Helper.array(others)]
)
}

func notEqualAny(_ arrayExpression: Expression) -> BooleanExpression {
return BooleanExpression(functionName: "not_equal_any", args: [self, arrayExpression])
return BooleanFunctionExpression(functionName: "not_equal_any", args: [self, arrayExpression])
}

// MARK: Checks

// --- Added Type Check Operations ---

func exists() -> BooleanExpression {
return BooleanExpression(functionName: "exists", args: [self])
return BooleanFunctionExpression(functionName: "exists", args: [self])
}

func isError() -> BooleanExpression {
return BooleanExpression(functionName: "is_error", args: [self])
return BooleanFunctionExpression(functionName: "is_error", args: [self])
}

func isAbsent() -> BooleanExpression {
return BooleanExpression(functionName: "is_absent", args: [self])
return BooleanFunctionExpression(functionName: "is_absent", args: [self])
}

// --- Added String Operations ---
Expand All @@ -647,63 +692,69 @@ public extension Expression {
}

func like(_ pattern: String) -> BooleanExpression {
return BooleanExpression(functionName: "like", args: [self, Helper.sendableToExpr(pattern)])
return BooleanFunctionExpression(
functionName: "like",
args: [self, Helper.sendableToExpr(pattern)]
)
}

func like(_ pattern: Expression) -> BooleanExpression {
return BooleanExpression(functionName: "like", args: [self, pattern])
return BooleanFunctionExpression(functionName: "like", args: [self, pattern])
}

func regexContains(_ pattern: String) -> BooleanExpression {
return BooleanExpression(
return BooleanFunctionExpression(
functionName: "regex_contains",
args: [self, Helper.sendableToExpr(pattern)]
)
}

func regexContains(_ pattern: Expression) -> BooleanExpression {
return BooleanExpression(functionName: "regex_contains", args: [self, pattern])
return BooleanFunctionExpression(functionName: "regex_contains", args: [self, pattern])
}

func regexMatch(_ pattern: String) -> BooleanExpression {
return BooleanExpression(
return BooleanFunctionExpression(
functionName: "regex_match",
args: [self, Helper.sendableToExpr(pattern)]
)
}

func regexMatch(_ pattern: Expression) -> BooleanExpression {
return BooleanExpression(functionName: "regex_match", args: [self, pattern])
return BooleanFunctionExpression(functionName: "regex_match", args: [self, pattern])
}

func stringContains(_ substring: String) -> BooleanExpression {
return BooleanExpression(
return BooleanFunctionExpression(
functionName: "string_contains",
args: [self, Helper.sendableToExpr(substring)]
)
}

func stringContains(_ expression: Expression) -> BooleanExpression {
return BooleanExpression(functionName: "string_contains", args: [self, expression])
return BooleanFunctionExpression(functionName: "string_contains", args: [self, expression])
}

func startsWith(_ prefix: String) -> BooleanExpression {
return BooleanExpression(
return BooleanFunctionExpression(
functionName: "starts_with",
args: [self, Helper.sendableToExpr(prefix)]
)
}

func startsWith(_ prefix: Expression) -> BooleanExpression {
return BooleanExpression(functionName: "starts_with", args: [self, prefix])
return BooleanFunctionExpression(functionName: "starts_with", args: [self, prefix])
}

func endsWith(_ suffix: String) -> BooleanExpression {
return BooleanExpression(functionName: "ends_with", args: [self, Helper.sendableToExpr(suffix)])
return BooleanFunctionExpression(
functionName: "ends_with",
args: [self, Helper.sendableToExpr(suffix)]
)
}

func endsWith(_ suffix: Expression) -> BooleanExpression {
return BooleanExpression(functionName: "ends_with", args: [self, suffix])
return BooleanFunctionExpression(functionName: "ends_with", args: [self, suffix])
}

func toLower() -> FunctionExpression {
Expand Down
2 changes: 1 addition & 1 deletion Firestore/Swift/Source/PipelineResultChange.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import Foundation

@available(iOS 13, tvOS 13, macOS 10.15, macCatalyst 13, watchOS 7, *)
struct PipelineResultChange: Sendable {
public struct PipelineResultChange: Sendable {
public enum ChangeType {
case added, modified, removed
}
Expand Down
2 changes: 1 addition & 1 deletion Firestore/Swift/Source/SwiftAPI/Firestore+Pipeline.swift
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ import Foundation
///
/// - Returns: A `RealtimePipelineSource` for building a realtime pipeline.
@available(iOS 13, tvOS 13, macOS 10.15, macCatalyst 13, watchOS 7, *)
@nonobjc internal func realtimePipeline() -> RealtimePipelineSource {
@nonobjc func realtimePipeline() -> RealtimePipelineSource {
return RealtimePipelineSource(db: self) { stages, db in
RealtimePipeline(stages: stages, db: db)
}
Expand Down
Loading
Loading