Within our integration processes, we have developed templated implementations in our codebase that align well with the "pipe and filter" pattern in my opinion.
These "components" can be structured in the following formats:
class Component1<In, Out, Xin, Xout>
class Component2<Xin, Xout, Yin, Yout>
class Component3<Yin, Yout> // only includes 2 parameters, but could potentially be <Yin, Yout, None, None> for a customized 'None' type
The concept is to enable these components to be "chained" together, allowing for a sequence like this:
const c1 = new Component1<A,B,C,D>(...) // potentially pass parameter types in the constructor? Other alternatives?
const c2 = new Component2<C,D,E,F>(...)
const c3 = new Component3<E,F, None, None>(...)
const chain = c1.andThen(c2).andThen(c3) // The "final" element in the chain will "always" be a component of type <X,Y, None, None>
chain.run() // Uncertain if this is necessary, but to clarify that something executes this chain
I'm struggling to find a "universal" method of constructing these components where the chaining can be "specified" at compile time to restrict which components can connect with others (i.e., the input/output types must align). Therefore, c1
can only be followed by c2
and not by c3
- and no components can be linked after c3
.
Is this a feasible endeavor? Any approaches to achieve something similar?
(For those who are curious: aiming for a similar level of composability as Finagle offers in the Scala realm)