                         :fn #(= (::name (:ret %))
                                 (::name (:this (:args %)))))))
 
-(s/def ::stop-fn (s/fspec :args (s/cat :this map? :context map?)
-                          :ret map?
-                          :fn #(= (::name (:ret %))
-                                  (::name (:this (:args %))))))
+(s/def ::stop-fn
+  (s/fspec :args (s/cat :this map? :context map?
+                        :ret map?
+                        :fn #(= (::name (:ret %))
+                                (::name (:this (:args %)))))))
+
+(s/def ::stream stream/stream?)
+
+(s/def ::input-stream-fn
+  (s/fspec :args (s/cat) :ret ::stream))
+
+
+(s/def ::output-stream-fn ::input-stream-fn)
 
 (s/def ::depends-on (s/coll-of keyword? :kind vector? :distinct true))
 (s/def ::component (s/keys :req [::name ::start-fn ::stop-fn]
-                           :opt [::depends-on]))
+                           :opt [::depends-on
+                                 ::input-stream-fn
+                                 ::output-stream-fn]))


(extend-type PersistentArrayMap
  IComponent
  (start! [this context]
    (let [start-fn (::start-fn this)]
      (assoc (start-fn this context)

(ns hellhound.component
  (:require [clojure.spec.alpha     :as s]
            [clojure.spec.gen.alpha :as gen]
            [manifold.stream        :as stream]
            [hellhound.core :as core])
  (:import (clojure.lang PersistentArrayMap)))


;; Protocols
(defprotocol IComponent
  "This protocol defines a very basic component for hellhound system."
  (initialize [component]
    "Returns the initialized component.")

  (start! [component context]
    "Starts the component.")

