{"id":13801245,"url":"https://github.com/weavejester/reagi","last_synced_at":"2025-09-01T02:39:56.542Z","repository":{"id":8429347,"uuid":"10017707","full_name":"weavejester/reagi","owner":"weavejester","description":"An FRP library for Clojure and ClojureScript","archived":false,"fork":false,"pushed_at":"2016-03-04T19:50:04.000Z","size":1351,"stargazers_count":230,"open_issues_count":4,"forks_count":13,"subscribers_count":17,"default_branch":"master","last_synced_at":"2025-07-19T18:34:36.617Z","etag":null,"topics":[],"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/weavejester.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}},"created_at":"2013-05-12T18:34:52.000Z","updated_at":"2025-06-05T18:09:52.000Z","dependencies_parsed_at":"2022-07-30T00:47:59.473Z","dependency_job_id":null,"html_url":"https://github.com/weavejester/reagi","commit_stats":null,"previous_names":[],"tags_count":33,"template":false,"template_full_name":null,"purl":"pkg:github/weavejester/reagi","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/weavejester%2Freagi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/weavejester%2Freagi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/weavejester%2Freagi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/weavejester%2Freagi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/weavejester","download_url":"https://codeload.github.com/weavejester/reagi/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/weavejester%2Freagi/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273067824,"owners_count":25039905,"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-09-01T02:00:09.058Z","response_time":120,"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":[],"created_at":"2024-08-04T00:01:20.877Z","updated_at":"2025-09-01T02:39:56.523Z","avatar_url":"https://github.com/weavejester.png","language":"Clojure","readme":"# Reagi\n\n[![Build Status](https://travis-ci.org/weavejester/reagi.png?branch=master)](https://travis-ci.org/weavejester/reagi)\n\nReagi is an [FRP][1] library for Clojure and ClojureScript, built on\ntop of [core.async][2]. It provides tools to model and manipulation\nvalues that change over time.\n\n[1]: http://en.wikipedia.org/wiki/Functional_reactive_programming\n[2]: https://github.com/clojure/core.async\n\n## Installation\n\nAdd the following dependency to your `project.clj` file:\n\n    [reagi \"0.10.1\"]\n\n## Overview\n\nReagi introduces two new reference types, behaviors and event streams,\nwhich are collectively known as signals.\n\n```clojure\nuser=\u003e (require '[reagi.core :as r])\nnil\n```\n\nA behavior models continuous change, and is evaluated each time you\ndereference it.\n\n```clojure\nuser=\u003e (def t (r/behavior (System/currentTimeMillis)))\n#'user/t\nuser=\u003e @t\n1380475144266\nuser=\u003e @t\n1380475175587\n```\n\nAn event stream models a series of discrete changes. Events must be\nexpicitly delivered to the stream. Dereferencing the event stream\nreturns the last value pushed onto the stream.\n\n```clojure\nuser=\u003e (def e (r/events))\n#'user/e\nuser=\u003e (r/deliver e 1)\n#\u003cEvents@66d278af: 1\u003e\nuser=\u003e @e\n1\n```\n\nIf the event stream is empty (i.e. unrealized), dereferencing it will\nblock the running thread, much like a promise.\n\nUnlike promises, event streams can have more than one value delivered\nto them, and may be constructed with an initial value:\n\n```clojure\nuser=\u003e (def e (r/events 1))\n#'user/e\nuser=\u003e @e\n1\n```\n\nReagi provides a number of functions for transforming event streams,\nwhich mimic many of the standard Clojure functions for dealing with\nseqs:\n\n```clojure\nuser=\u003e (def incremented (r/map inc e))\n#'user/m\nuser=\u003e (r/deliver e 2)\n#\u003cEvents@66d278af: 2\u003e\nuser=\u003e @incremented\n3\n```\n\nFor a full list, see the [API docs](http://weavejester.github.io/reagi/reagi.core.html).\n\nEvent streams can interoperate with core.async channels using `port`\nand `subscribe`. The `port` function returns a write-only stream that\nwill deliver values to the stream:\n\n```clojure\nuser=\u003e (\u003e!! (r/port e) 3)\ntrue\nuser=\u003e @e\n3\n```\n\nThe `subscribe` function allows an existing channel to be registered\nas an output for the stream.\n\n```clojure\nuser=\u003e (def ch (async/chan 1))\n#'user/ch\nuser=\u003e (r/subscribe e ch)\n#\u003cManyToManyChannel clojure.core.async.impl.channels.ManyToManyChannel@3b4df45f\u003e\nuser=\u003e (r/deliver e 4)\n#\u003cEvents@66d278af: 4\u003e\nuser=\u003e (\u003c!! ch)\n4\n```\n\nNote that this may cause the source stream to block if you don't\nconsume the items in the channel, or provide a sufficient buffer.\n\nBehaviors can be converted to event streams by sampling them at a\nspecified interval in milliseconds:\n\n```clojure\nuser=\u003e (def et (r/sample 1000 t))\n#'user/et\nuser=\u003e @et\n1380475969885\n```\n\nSignals can be completed with the `completed` function, which acts in\na similar fashion to `clojure.core/reduced`. Signals that are\ncompleted will always deref to the same value. Any values pushed to a\ncompleted event stream will be ignored.\n\n```clojure\nuser=\u003e (def e (r/events))\n#'user/e\nuser=\u003e (r/deliver e (r/completed 1))\n#\u003cEvents@66d278af: 1\u003e\nuser=\u003e (r/deliver e 2)\n#\u003cEvents@66d278af: 1\u003e\nuser=\u003e @e\n1\nuser=\u003e (r/complete? e)\ntrue\n```\n\n\n## Documentation\n\n* [API Docs](http://weavejester.github.io/reagi/reagi.core.html)\n\n\n## Differences in ClojureScript version\n\nThe ClojureScript version of Reagi has two main differences from the\nClojure version:\n\n1. Trying to deref an unrealized stream blocks the current thread in\n   Clojure, but returned js/undefined in ClojureScript.\n\n2. Event streams that fall out of scope in Clojure are automatically\n   cleaned up. In ClojureScript, the `reagi.core/dispose` function\n   must be manually called on streams before they fall out of scope.\n\n\n## License\n\nCopyright © 2014 James Reeves\n\nDistributed under the Eclipse Public License, the same as Clojure.\n","funding_links":[],"categories":["Awesome ClojureScript"],"sub_categories":["Reactive Programming"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fweavejester%2Freagi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fweavejester%2Freagi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fweavejester%2Freagi/lists"}