{"id":13393158,"url":"https://github.com/clj-commons/manifold","last_synced_at":"2025-12-12T01:19:06.222Z","repository":{"id":14676797,"uuid":"17395880","full_name":"clj-commons/manifold","owner":"clj-commons","description":"A compatibility layer for event-driven abstractions","archived":false,"fork":false,"pushed_at":"2024-05-14T10:10:43.000Z","size":1636,"stargazers_count":1019,"open_issues_count":28,"forks_count":107,"subscribers_count":37,"default_branch":"master","last_synced_at":"2024-10-29T15:01:45.338Z","etag":null,"topics":["async","clojure","future","hacktoberfest","stream","stream-processing"],"latest_commit_sha":null,"homepage":"","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/clj-commons.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2014-03-04T08:53:48.000Z","updated_at":"2024-10-19T03:39:55.000Z","dependencies_parsed_at":"2024-01-08T18:03:37.385Z","dependency_job_id":"2d0a9614-3301-4750-a6ec-03e6fb54992e","html_url":"https://github.com/clj-commons/manifold","commit_stats":{"total_commits":363,"total_committers":45,"mean_commits":8.066666666666666,"dds":"0.49586776859504134","last_synced_commit":"abc37c407be34c1e8c854e89d10405ce2a0570eb"},"previous_names":["ztellman/manifold"],"tags_count":57,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clj-commons%2Fmanifold","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clj-commons%2Fmanifold/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clj-commons%2Fmanifold/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clj-commons%2Fmanifold/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/clj-commons","download_url":"https://codeload.github.com/clj-commons/manifold/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248335134,"owners_count":21086523,"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","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":["async","clojure","future","hacktoberfest","stream","stream-processing"],"created_at":"2024-07-30T17:00:44.293Z","updated_at":"2025-12-12T01:19:01.196Z","avatar_url":"https://github.com/clj-commons.png","language":"Clojure","funding_links":[],"categories":["Clojure","\u003ca name=\"Clojure\"\u003e\u003c/a\u003eClojure"],"sub_categories":[],"readme":"[![Clojars Project](https://img.shields.io/clojars/v/manifold.svg)](https://clojars.org/manifold)\n[![cljdoc badge](https://cljdoc.org/badge/manifold/manifold)](https://cljdoc.org/d/manifold/manifold)\n[![CircleCI](https://circleci.com/gh/clj-commons/manifold.svg?style=svg)](https://circleci.com/gh/clj-commons/manifold)\n![](doc/manifold.png)\n\nManifold provides basic building blocks for asynchronous programming, and can be used as a translation layer between libraries which use similar, but incompatible, abstractions.\n\nManifold provides two core abstractions: **deferreds**, which represent a single asynchronous value, and **streams**, which represent an ordered sequence of asynchronous values.\n\nA detailed discussion of Manifold's rationale can be found [here](doc/rationale.md).  Full documentation can be found [here](https://cljdoc.org/d/manifold/manifold).\n\nLeiningen:\n```clojure\n[manifold \"0.4.3\"]\n```\n\ndeps.edn:\n```clojure\nmanifold/manifold {:mvn/version \"0.4.3\"}\n```\n\n### Deferreds\n\nA deferred in Manifold is similar to a Clojure promise:\n\n```clojure\n\u003e (require '[manifold.deferred :as d])\nnil\n\n\u003e (def d (d/deferred))\n#'d\n\n\u003e (d/success! d :foo)\ntrue\n\n\u003e @d\n:foo\n```\n\nHowever, similar to Clojure's futures, deferreds in Manifold can also represent errors.  Crucially, they also allow for callbacks to be registered, rather than simply blocking on dereferencing.\n\n```clojure\n\u003e (def d (d/deferred))\n#'d\n\n\u003e (d/error! d (Exception. \"boom\"))\ntrue\n\n\u003e @d\nException: boom\n```\n\n```clojure\n\u003e (def d (d/deferred))\n#'d\n\n\u003e (d/on-realized d\n    (fn [x] (println \"success!\" x))\n    (fn [x] (println \"error!\" x)))\n\u003c\u003c ... \u003e\u003e\n\n\u003e (d/success! d :foo)\nsuccess! :foo\ntrue\n```\n\nCallbacks are a useful building block, but they're a painful way to create asynchronous workflows.  In practice, **no one should ever need to use `on-realized`**.  Manifold provides a number of operators for composing over deferred values, [which can be read about here](/doc/deferred.md).\n\n### Streams\n\nManifold's streams provide mechanisms for asynchronous puts and takes, timeouts, and backpressure.  They are compatible with Java's `BlockingQueues`, Clojure's lazy sequences, and core.async's channels.  Methods for converting to and from each are provided.\n\nManifold differentiates between **sources**, which emit messages, and **sinks**, which consume messages.  We can interact with sources using `take!` and `try-take!`, which return deferred values representing the next message.  We can interact with sinks using `put!` and `try-put!`, which return a deferred values which will yield `true` if the put is successful, or `false` otherwise.\n\nWe can create a stream using `(manifold.stream/stream)`:\n\n```clojure\n\u003e (require '[manifold.stream :as s])\nnil\n\u003e (def s (s/stream))\n#'s\n\u003e (s/put! s 1)\n\u003c\u003c ... \u003e\u003e\n\u003e (s/take! s)\n\u003c\u003c 1 \u003e\u003e\n```\n\nA stream is both a sink and a source; any message sent via `put!` can be received via `take!`.  We can also create sinks and sources from other stream representations using `-\u003esink` and `-\u003esource`:\n\n```clojure\n\u003e (require '[clojure.core.async :as a])\nnil\n\u003e (def c (a/chan))\n#'c\n\u003e (def s (s/-\u003esource c))\n#'s\n\u003e (a/go (a/\u003e! c 1))\n#object[clojure.core.async.impl.channels.ManyToManyChannel 0x7...\n\u003e @(s/take! s)\n1\n```\n\nWe can also turn a Manifold stream into a different representation by using `connect` to join them together:\n\n```clojure\n\u003e (def s (s/stream))\n#'s\n\u003e (def c (a/chan))\n#'c\n\u003e (s/connect s c)\nnil\n\u003e (s/put! s 1)\n\u003c\u003c true \u003e\u003e\n\u003e (a/\u003c!! c)\n1\n```\n\nManifold can use any transducer, which are applied via `transform`.  It also provides stream-specific transforms, including `zip`, `reduce`, `buffer`, `batch`, and `throttle`.  [To learn more about streams, go here](/doc/stream.md).\n\n### Clojurescript\n\nA Clojurescript implementation of Manifold can be found here: [dm3/manifold-cljs](https://github.com/dm3/manifold-cljs).\n\n\n### License\n\nCopyright © 2014-2024 Zach Tellman.\n\nDistributed under the MIT License.\n\n### Support\n\nMany thanks to YourKit for supporting Manifold. YourKit supports open source projects with innovative and intelligent tools for monitoring and profiling Java and .NET applications.\n\nYourKit is the creator of \u003ca href=\"https://www.yourkit.com/java/profiler/\"\u003eYourKit Java Profiler\u003c/a\u003e, \u003ca href=\"https://www.yourkit.com/dotnet-profiler/\"\u003eYourKit .NET Profiler\u003c/a\u003e, and \u003ca href=\"https://www.yourkit.com/youmonitor/\"\u003eYourKit YouMonitor\u003c/a\u003e.\n\n![](https://www.yourkit.com/images/yklogo.png)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclj-commons%2Fmanifold","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fclj-commons%2Fmanifold","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclj-commons%2Fmanifold/lists"}