{"id":16411353,"url":"https://github.com/gadfly361/re-pollsive","last_synced_at":"2025-10-08T22:23:43.403Z","repository":{"id":62434393,"uuid":"132774196","full_name":"gadfly361/re-pollsive","owner":"gadfly361","description":"Re-pollsive is a clojurescript library that handles polling events for re-frame applications","archived":false,"fork":false,"pushed_at":"2019-09-24T17:14:14.000Z","size":15,"stargazers_count":34,"open_issues_count":0,"forks_count":3,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-10-03T23:54:17.346Z","etag":null,"topics":["poll","polling","pollsive","re-frame","re-pulsive","reagent","repulsive"],"latest_commit_sha":null,"homepage":"","language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gadfly361.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-05-09T15:05:53.000Z","updated_at":"2025-06-04T20:51:37.000Z","dependencies_parsed_at":"2022-11-01T20:45:56.270Z","dependency_job_id":null,"html_url":"https://github.com/gadfly361/re-pollsive","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/gadfly361/re-pollsive","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gadfly361%2Fre-pollsive","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gadfly361%2Fre-pollsive/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gadfly361%2Fre-pollsive/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gadfly361%2Fre-pollsive/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gadfly361","download_url":"https://codeload.github.com/gadfly361/re-pollsive/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gadfly361%2Fre-pollsive/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278717959,"owners_count":26033654,"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-10-07T02:00:06.786Z","response_time":59,"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":["poll","polling","pollsive","re-frame","re-pulsive","reagent","repulsive"],"created_at":"2024-10-11T06:45:14.001Z","updated_at":"2025-10-08T22:23:43.387Z","avatar_url":"https://github.com/gadfly361.png","language":"Clojure","funding_links":[],"categories":[],"sub_categories":[],"readme":"# re-pollsive\n\n\u003e \"Everywhere I look, I see the repulsive sight of hundreds, thousands of revolting little children.\"\n\u003e - Grand High Witch, The Witches\n\nre-pollsive is a library that handles polling events\nfor [re-frame](https://github.com/Day8/re-frame) applications.\n\n```clojure\n[re-pollsive \"0.1.0\"]\n```\n\nAnd in your ns:\n```clojure\n(ns your-ns\n  (:require [re-pollsive.core :as poll]))\n```\n\n# The Problem\n\nWhen you want to poll something, you will likely reach for\njavascript's `setInterval`. However, if you aren't careful, it is easy\nto add a bunch of `setInterval`s scattered throughout your\napplication.  When these `setInterval`s collide, this can lead to\nunexpected and hard to debug behavior.\n\nIn addition, if you are using a hot-reloading tool (such\nas [figwheel](https://github.com/bhauman/lein-figwheel)), you will\nneed to proactively defend against unintended `setInterval`s starting\non reload.\n\n# Re-pollsive's solution\n\nWith re-pollsive, you only set up one `setInterval` when your\napplication starts, by dispatching `::poll/init`.  This will start a\ncounter that counts up *every second*.\n\nRe-pollsive allows you to dynamically define polling rules by\ndispatching `::poll/set-rules`.  An *interval* is defined for each\nrule, and will be tracked against the aforementioned counter.\n\nIn addition, because you are anchoring off of only one `setInterval`,\nyou can freely use hot-reloading tools (such as figwheel) without any\nproblems.\n\n# API\n\n### `::poll/init`\n\n`::poll/init` starts a counter for your polling rules to hang off of.\n\nNote: This needs to be dispatched **only once**, when the application *first* loads.\n\n```clojure\n(re-frame/dispatch-sync [::poll/init])\n```\n\n### `::poll/set-rules`\n\n`::poll/set-rules` takes a vector of hash-maps with the following shape:\n\n| key                       | type                  | default   | required? |\n|---------------------------|-----------------------|-----------|-----------|\n| :interval                 | int (seconds)         |           | **yes**   |\n| :event                    | re-frame event        |           | **yes**   |\n| :poll-when                | re-frame subscription |           | no        |\n| :dispatch-event-on-start? | boolean               | false     | no        |\n\n`:poll-when` is a re-frame subscription vector\n(e.g. `[:should-i-be-polling?]`), and its value should be a boolean.\n`:poll-when` can be used to effectively *start* and *stop* the poller.\nIf you do not supply `:poll-when`, then the poller will always run.\n\n`:dispatch-event-on-start?` is a way to dispatch the event at time 0.\nSay you have an interval of 30, by setting `:dispatch-event-on-start?`\nto true, then the event will dispatch at 0 seconds, 30 seconds, 60\nseconds, etc.  If `:dispatch-event-on-start?` is false, then the event\nwill dispatch at 30 seconds, 60 seconds, etc. (and not at time 0).\n\nHere is an example:\n\n```clojure\n(re-frame/dispatch\n [::poll/set-rules\n  [;; rule #1\n   {:interval                 4\n    :event                    [::events/log \"POLL (every 4 seconds)\"]\n    :poll-when                [::subs/poll?]\n    :dispatch-event-on-start? true}\n\n   ;; rule #2\n   {:interval                 6\n    :event                    [::events/log \"POLL (every 6 seconds)\"]\n    :poll-when                [::subs/poll?]\n    :dispatch-event-on-start? false}\n   ]])\n```\n\n# Usage\n\nCreate a new re-frame application.\n\n```\nlein new re-frame foo\n```\n\nAdd the following to the `:dependencies` vector of your *project.clj*\nfile.\n\n```clojure\n[re-pollsive \"0.1.0\"]\n```\n\nThen require re-pollsive in the core namespace, and add the\n`::poll/init` event.\n\n```clojure\n(ns foo.core\n  (:require [reagent.core :as reagent]\n            [re-frame.core :as re-frame]\n\n            ;; Add this (1 of 2)\n            [re-pollsive.core :as poll]\n\n            [foo.events :as events]\n            [foo.views :as views]\n            [foo.config :as config]\n            ))\n\n(defn dev-setup []\n  (when config/debug?\n    (enable-console-print!)\n    (println \"dev mode\")))\n\n(defn mount-root []\n  (re-frame/clear-subscription-cache!)\n  (reagent/render [views/main-panel]\n                  (.getElementById js/document \"app\")))\n\n(defn ^:export init []\n  (re-frame/dispatch-sync [::events/initialize-db])\n\n  ;; And this (2 of 2)\n  (re-frame/dispatch-sync [::poll/init])\n\n  (dev-setup)\n  (mount-root))\n```\n\nNext, you will need to dispatch a `::poll/set-rules` event somewhere.\nPersonally, I like dispatching this in my routes file (because I may\nwant to handle polling events differently on each page).\n\n# Non-goals\n\n- *A perfectly accurate counter*. The internal counter is not intended\n  to be perfectly accurate. For example, if you set an interval to\n  `30`, expect the event to be dispatched roughly every 30 seconds,\n  but not exactly. In other words, don't use re-pollsive for a clock.\n- *Handling really quick events*.  The choice of having the `:interval`\n  be measured in seconds as opposed to milliseconds was intentional.\n  If you want to dispatch events with millisecond granularity, you are\n  likely better off using a one-off setTimeout.\n\n# Questions\n\nIf you have questions, I can usually be found hanging out in\nthe [clojurians](http://clojurians.net/) #reagent slack channel (my\nhandle is [@gadfly361](https://twitter.com/gadfly361)).\n\n# License\n\nCopyright © 2018 Matthew Jaoudi\n\nDistributed under the The MIT License (MIT).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgadfly361%2Fre-pollsive","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgadfly361%2Fre-pollsive","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgadfly361%2Fre-pollsive/lists"}