{"id":30212283,"url":"https://github.com/parencat/fx","last_synced_at":"2025-12-12T01:21:15.756Z","repository":{"id":60149537,"uuid":"451445398","full_name":"parencat/fx","owner":"parencat","description":null,"archived":false,"fork":false,"pushed_at":"2023-03-01T12:26:40.000Z","size":232,"stargazers_count":4,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-07-11T00:20:04.084Z","etag":null,"topics":["clojure"],"latest_commit_sha":null,"homepage":"https://cljdoc.org/d/io.github.parencat/fx/0.1.2/doc/readme","language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/parencat.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2022-01-24T11:56:34.000Z","updated_at":"2023-07-20T18:40:30.000Z","dependencies_parsed_at":"2023-07-18T23:15:04.855Z","dependency_job_id":null,"html_url":"https://github.com/parencat/fx","commit_stats":{"total_commits":130,"total_committers":3,"mean_commits":"43.333333333333336","dds":"0.023076923076923106","last_synced_commit":"918cbdd831a282fba129e05f742bde83ca767d0e"},"previous_names":["pro-duct/fx"],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/parencat/fx","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/parencat%2Ffx","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/parencat%2Ffx/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/parencat%2Ffx/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/parencat%2Ffx/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/parencat","download_url":"https://codeload.github.com/parencat/fx/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/parencat%2Ffx/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270323579,"owners_count":24564684,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-13T02:00:09.904Z","response_time":66,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["clojure"],"created_at":"2025-08-13T22:01:37.861Z","updated_at":"2025-12-12T01:21:15.724Z","avatar_url":"https://github.com/parencat.png","language":"Clojure","funding_links":[],"categories":[],"sub_categories":[],"readme":"# FX\n\nSet of Duct modules and integrant components for a rapid clojure development.\n\n\n[![Clojars Project](https://img.shields.io/clojars/v/io.github.parencat/fx.svg)](https://clojars.org/io.github.parencat/fx)\n\n## Installation\n\nAssuming you already have a Duct project bootstrapped. \nAdd to your leiningen dependencies:\n\n```clojure\n[io.github.parencat/fx \"0.1.2\"]\n```\n\n## Modules\n\n### `:fx.module/autowire`\n\nAutowire module purpose is to reduce a hassle while configuring your application components. This module will scan your\nproject namespaces. Whenever Autowire will find some ns members (vars or functions)\nwith `:fx/autowire` key in the metadata it will automatically create an integrant key and a configuration map.\n\nTo enable autowire module add this key to your Duct `config.edn` file\n\n```clojure\n{:duct.profile/base\n {:duct.core/project-ns your-project-root-namespace}\n\n ;; other profiles and modules\n\n :fx.module/autowire {}}\n```\n\nYou can limit a number of scanned namespaces by providing a `:root` path for some file or folder\n\n```clojure\n{:duct.profile/base\n {:duct.core/project-ns your-project-root-namespace}\n\n ;; other profiles and modules\n\n :fx.module/autowire {:root your-project-root-namespace/components}}\n```\n\nAfter that you can attach `:fx/autowire` key to any members, e.g.\n\n```clojure\n(ns my-project.core)\n\n(def ^:fx/autowire db-connection\n  (jdbc/get-connection {:connection-uri \"db-uri\"\n                        :dbtype         \"sqlite\"}))\n```\n\nIn this case Autowire will create `:my-project.core/db-connection` component and you can reference and use\nit in other components. Notice that autowired components always has a namespaced keyword as its name \n(to prevent the components name clashes)\n\ne.g.\n\n```clojure\n(let [db (-\u003e (ig/find-derived-1 system :my-project.core/db-connection)\n             (val))]\n  (jdbc/execute! db [\"SELECT * FROM users ...\"]))\n```\n\nAlso, you can specify dependencies for your components as arguments metadata:\n\n```clojure\n(defn ^:fx/autowire get-users [^:my-project.core/db-connection db]\n  (fn []\n    {:status :ok\n     :users  (jdbc/execute! db [\"SELECT * FROM users ...\"])}))\n```\n\nThis kind of dependency injection already built-in into the Duct framework, \nAutowire is just reducing some boilerplate around it.\n\n#### Additional options\n\n`:fx/halt`\n\nBy default, Autowire will create only `ig/init-key` methods for found components. \nIt is possible to create a `ig/halt-key!` method as well. \nAll you need it's to add `:fx/halt` key with the name of component to the metadata \n\n```clojure\n(ns my-project.core\n  (:import\n   [java.sql Connection]))\n\n(def ^:fx/autowire db-connection\n  (jdbc/get-connection {:connection-uri \"db-uri\"\n                        :dbtype         \"sqlite\"}))\n\n(defn close-connection\n  {:fx/autowire true\n   :fx/halt     ::db-connection}\n  [^Connection conn]\n  (.close conn))\n```\n\n`:fx/wrap`\n\nYou can add `:fx/wrap` key to wrap a component in the anonymous function for the later usage.  \nWithout wrapping you'll have to return an anonymous function which holds the dependencies as closures:\n\n```clojure\n(defn ^:fx/autowire get-users \n  [^:my-project.core/db-connection db]\n  (fn [request]\n    {:status  200\n     :headers {\"Content-Type\" \"application/json\"}\n     :body    (jdbc/execute! db [\"SELECT * FROM users ...\"])}))\n```\n\nwith wrapping your component will be initialized with the partially applied function:\n\n```clojure\n(defn ^:fx/autowire ^:fx/wrap get-users\n  [^:my-project.core/db-connection db request]\n  {:status  200\n   :headers {\"Content-Type\" \"application/json\"}\n   :body    (jdbc/execute! db [\"SELECT * FROM users ...\"])})\n```\n\nFor more examples check  `fx.module.stub-functions` and `fx.module.autowire-test` namespaces.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fparencat%2Ffx","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fparencat%2Ffx","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fparencat%2Ffx/lists"}