# Pipeline Package Specification ## Overview The Pipeline package provides a robust implementation of the pipeline pattern, allowing for the sequential processing of tasks through a series of stages. It integrates deeply with our Route, Bus, and Queue packages while maintaining Laravel compatibility. > **Related Documentation** > - See [Laravel Compatibility Roadmap](laravel_compatibility_roadmap.md) for implementation status > - See [Foundation Integration Guide](foundation_integration_guide.md) for integration patterns > - See [Testing Guide](testing_guide.md) for testing approaches > - See [Getting Started Guide](getting_started.md) for development setup > - See [Contracts Package Specification](contracts_package_specification.md) for pipeline contracts ## Core Features ### 1. Pipeline Base ```dart /// Core pipeline class with conditional execution class Pipeline with Conditionable> { final Container _container; final List> _pipes; TPassable? _passable; String _method = 'handle'; Pipeline(this._container, [List>? pipes]) : _pipes = pipes ?? []; /// Sends an object through the pipeline Pipeline send(TPassable passable) { _passable = passable; return this; } /// Sets the stages of the pipeline Pipeline through(List pipes) { for (var pipe in pipes) { if (pipe is String) { // Resolve from container _pipes.add(_container.make(pipe)); } else if (pipe is Type) { _pipes.add(_container.make(pipe)); } else if (pipe is Pipe) { _pipes.add(pipe); } else if (pipe is Function) { _pipes.add(FunctionPipe(pipe)); } } return this; } /// Sets the method to call on the pipes Pipeline via(String method) { _method = method; return this; } /// Process the pipeline to final result Future then( FutureOr Function(TPassable) destination ) async { var pass = _passable; if (pass == null) { throw PipelineException('No passable object provided'); } // Build pipeline var pipeline = _pipes.fold( destination, (next, pipe) => (passable) => _container.call(() => pipe.handle(passable, next)) ); // Execute pipeline return await pipeline(pass); } } ``` ### 2. Middleware Pipeline ```dart /// HTTP middleware pipeline with route integration class MiddlewarePipeline extends Pipeline { final Router _router; MiddlewarePipeline(Container container, this._router) : super(container); /// Adds route-specific middleware MiddlewarePipeline throughRoute(Route route) { // Get global middleware var middleware = _router.middleware; // Add route middleware if (route.middleware.isNotEmpty) { middleware.addAll( route.middleware.map((m) => _container.make(m)) ); } // Add route group middleware if (route.group != null) { middleware.addAll(route.group!.middleware); } return through(middleware); } /// Processes request through middleware Future process( Request request, FutureOr Function(Request) destination ) { return send(request) .when(() => shouldProcessMiddleware(request)) .then(destination); } /// Checks if middleware should be processed bool shouldProcessMiddleware(Request request) { return !request.attributes.containsKey('skip_middleware'); } } ``` ### 3. Bus Pipeline ```dart /// Command bus pipeline with handler resolution class BusPipeline extends Pipeline { final CommandBus _bus; BusPipeline(Container container, this._bus) : super(container); /// Processes command through pipeline Future process( TCommand command, [Handler? handler] ) { // Resolve handler handler ??= _resolveHandler(command); return send(command).then((cmd) => handler!.handle(cmd) as Future ); } /// Resolves command handler Handler _resolveHandler(TCommand command) { if (command is Command) { return _container.make(command.handler); } var handlerType = _bus.handlers[TCommand]; if (handlerType == null) { throw HandlerNotFoundException( 'No handler found for ${TCommand}' ); } return _container.make(handlerType); } } ``` ### 4. Job Pipeline ```dart /// Queue job pipeline with middleware class JobPipeline extends Pipeline { final QueueManager _queue; JobPipeline(Container container, this._queue) : super(container); /// Processes job through pipeline Future process(Job job) { return send(job) .through(_queue.middleware) .then((j) => j.handle()); } /// Adds rate limiting JobPipeline withRateLimit(int maxAttempts, Duration timeout) { return through([ RateLimitedPipe(maxAttempts, timeout) ]); } /// Prevents overlapping jobs JobPipeline withoutOverlapping() { return through([WithoutOverlappingPipe()]); } } ``` ### 5. Pipeline Hub ```dart /// Manages application pipelines class PipelineHub { final Container _container; final Map _pipelines = {}; final List _defaults = []; PipelineHub(this._container); /// Gets or creates a pipeline Pipeline pipeline(String name) { return _pipelines.putIfAbsent( name, () => Pipeline(_container, [..._defaults]) ); } /// Gets middleware pipeline MiddlewarePipeline middleware() { return pipeline('middleware') as MiddlewarePipeline; } /// Gets bus pipeline BusPipeline bus() { return pipeline('bus') as BusPipeline; } /// Gets job pipeline JobPipeline job() { return pipeline('job') as JobPipeline; } /// Sets default pipes void defaults(List pipes) { _defaults.addAll(pipes); } } ``` ## Integration Examples ### 1. Route Integration ```dart // In RouteServiceProvider void boot() { router.middleware([ StartSession::class, VerifyCsrfToken::class ]); router.group(['middleware' => ['auth']], () { router.get('/dashboard', DashboardController); }); } // In Router Future dispatch(Request request) { var route = matchRoute(request); return container.make() .throughRoute(route) .process(request, (req) => route.handle(req)); } ``` ### 2. Command Bus Integration ```dart // In CommandBus Future dispatch(Command command) { return container.make() .through([ TransactionPipe(), ValidationPipe(), AuthorizationPipe() ]) .process(command); } // Usage class CreateOrder implements Command { @override Type get handler => CreateOrderHandler; } var order = await bus.dispatch( CreateOrder(items: items) ); ``` ### 3. Queue Integration ```dart // In QueueWorker Future process(Job job) { return container.make() .withRateLimit(3, Duration(minutes: 1)) .withoutOverlapping() .process(job); } // Usage class ProcessPayment implements Job { @override Future handle() async { // Process payment } } await queue.push(ProcessPayment( orderId: order.id )); ``` ## Testing ```dart void main() { group('Middleware Pipeline', () { test('processes route middleware', () async { var pipeline = MiddlewarePipeline(container, router); var route = Route('/test', middleware: ['auth']); var response = await pipeline .throughRoute(route) .process(request, handler); verify(() => auth.handle(any, any)).called(1); }); }); group('Bus Pipeline', () { test('resolves and executes handler', () async { var pipeline = BusPipeline(container, bus); var command = CreateOrder(items: items); var result = await pipeline.process(command); expect(result, isA()); verify(() => handler.handle(command)).called(1); }); }); } ``` ## Next Steps 1. Add more middleware types 2. Enhance bus pipeline features 3. Add job pipeline features 4. Improve testing coverage 5. Add performance optimizations Would you like me to enhance any other package specifications? ## Development Guidelines ### 1. Getting Started Before implementing pipeline features: 1. Review [Getting Started Guide](getting_started.md) 2. Check [Laravel Compatibility Roadmap](laravel_compatibility_roadmap.md) 3. Follow [Testing Guide](testing_guide.md) 4. Use [Foundation Integration Guide](foundation_integration_guide.md) 5. Understand [Contracts Package Specification](contracts_package_specification.md) ### 2. Implementation Process For each pipeline feature: 1. Write tests following [Testing Guide](testing_guide.md) 2. Implement following Laravel patterns 3. Document following [Getting Started Guide](getting_started.md#documentation) 4. Integrate following [Foundation Integration Guide](foundation_integration_guide.md) ### 3. Quality Requirements All implementations must: 1. Pass all tests (see [Testing Guide](testing_guide.md)) 2. Meet Laravel compatibility requirements 3. Follow integration patterns (see [Foundation Integration Guide](foundation_integration_guide.md)) 4. Implement required contracts (see [Contracts Package Specification](contracts_package_specification.md)) ### 4. Integration Considerations When implementing pipelines: 1. Follow patterns in [Foundation Integration Guide](foundation_integration_guide.md) 2. Ensure Laravel compatibility per [Laravel Compatibility Roadmap](laravel_compatibility_roadmap.md) 3. Use testing approaches from [Testing Guide](testing_guide.md) 4. Follow development setup in [Getting Started Guide](getting_started.md) 5. Implement all contracts from [Contracts Package Specification](contracts_package_specification.md) ### 5. Performance Guidelines Pipeline system must: 1. Handle nested pipelines efficiently 2. Minimize memory usage in long pipelines 3. Support async operations 4. Scale with number of stages 5. Meet performance targets in [Laravel Compatibility Roadmap](laravel_compatibility_roadmap.md#performance-benchmarks) ### 6. Testing Requirements Pipeline tests must: 1. Cover all pipeline types 2. Test stage ordering 3. Verify error handling 4. Check conditional execution 5. Follow patterns in [Testing Guide](testing_guide.md) ### 7. Documentation Requirements Pipeline documentation must: 1. Explain pipeline patterns 2. Show integration examples 3. Cover error handling 4. Include performance tips 5. Follow standards in [Getting Started Guide](getting_started.md#documentation)