https://github.com/gadfly361/re-pollsive
Re-pollsive is a clojurescript library that handles polling events for re-frame applications
https://github.com/gadfly361/re-pollsive
poll polling pollsive re-frame re-pulsive reagent repulsive
Last synced: 11 days ago
JSON representation
Re-pollsive is a clojurescript library that handles polling events for re-frame applications
- Host: GitHub
- URL: https://github.com/gadfly361/re-pollsive
- Owner: gadfly361
- License: mit
- Created: 2018-05-09T15:05:53.000Z (over 7 years ago)
- Default Branch: master
- Last Pushed: 2019-09-24T17:14:14.000Z (about 6 years ago)
- Last Synced: 2025-10-03T23:54:17.346Z (16 days ago)
- Topics: poll, polling, pollsive, re-frame, re-pulsive, reagent, repulsive
- Language: Clojure
- Homepage:
- Size: 14.6 KB
- Stars: 34
- Watchers: 2
- Forks: 3
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGES.md
- License: LICENSE
Awesome Lists containing this project
README
# re-pollsive
> "Everywhere I look, I see the repulsive sight of hundreds, thousands of revolting little children."
> - Grand High Witch, The Witchesre-pollsive is a library that handles polling events
for [re-frame](https://github.com/Day8/re-frame) applications.```clojure
[re-pollsive "0.1.0"]
```And in your ns:
```clojure
(ns your-ns
(:require [re-pollsive.core :as poll]))
```# The Problem
When you want to poll something, you will likely reach for
javascript's `setInterval`. However, if you aren't careful, it is easy
to add a bunch of `setInterval`s scattered throughout your
application. When these `setInterval`s collide, this can lead to
unexpected and hard to debug behavior.In addition, if you are using a hot-reloading tool (such
as [figwheel](https://github.com/bhauman/lein-figwheel)), you will
need to proactively defend against unintended `setInterval`s starting
on reload.# Re-pollsive's solution
With re-pollsive, you only set up one `setInterval` when your
application starts, by dispatching `::poll/init`. This will start a
counter that counts up *every second*.Re-pollsive allows you to dynamically define polling rules by
dispatching `::poll/set-rules`. An *interval* is defined for each
rule, and will be tracked against the aforementioned counter.In addition, because you are anchoring off of only one `setInterval`,
you can freely use hot-reloading tools (such as figwheel) without any
problems.# API
### `::poll/init`
`::poll/init` starts a counter for your polling rules to hang off of.
Note: This needs to be dispatched **only once**, when the application *first* loads.
```clojure
(re-frame/dispatch-sync [::poll/init])
```### `::poll/set-rules`
`::poll/set-rules` takes a vector of hash-maps with the following shape:
| key | type | default | required? |
|---------------------------|-----------------------|-----------|-----------|
| :interval | int (seconds) | | **yes** |
| :event | re-frame event | | **yes** |
| :poll-when | re-frame subscription | | no |
| :dispatch-event-on-start? | boolean | false | no |`:poll-when` is a re-frame subscription vector
(e.g. `[:should-i-be-polling?]`), and its value should be a boolean.
`:poll-when` can be used to effectively *start* and *stop* the poller.
If you do not supply `:poll-when`, then the poller will always run.`:dispatch-event-on-start?` is a way to dispatch the event at time 0.
Say you have an interval of 30, by setting `:dispatch-event-on-start?`
to true, then the event will dispatch at 0 seconds, 30 seconds, 60
seconds, etc. If `:dispatch-event-on-start?` is false, then the event
will dispatch at 30 seconds, 60 seconds, etc. (and not at time 0).Here is an example:
```clojure
(re-frame/dispatch
[::poll/set-rules
[;; rule #1
{:interval 4
:event [::events/log "POLL (every 4 seconds)"]
:poll-when [::subs/poll?]
:dispatch-event-on-start? true};; rule #2
{:interval 6
:event [::events/log "POLL (every 6 seconds)"]
:poll-when [::subs/poll?]
:dispatch-event-on-start? false}
]])
```# Usage
Create a new re-frame application.
```
lein new re-frame foo
```Add the following to the `:dependencies` vector of your *project.clj*
file.```clojure
[re-pollsive "0.1.0"]
```Then require re-pollsive in the core namespace, and add the
`::poll/init` event.```clojure
(ns foo.core
(:require [reagent.core :as reagent]
[re-frame.core :as re-frame];; Add this (1 of 2)
[re-pollsive.core :as poll][foo.events :as events]
[foo.views :as views]
[foo.config :as config]
))(defn dev-setup []
(when config/debug?
(enable-console-print!)
(println "dev mode")))(defn mount-root []
(re-frame/clear-subscription-cache!)
(reagent/render [views/main-panel]
(.getElementById js/document "app")))(defn ^:export init []
(re-frame/dispatch-sync [::events/initialize-db]);; And this (2 of 2)
(re-frame/dispatch-sync [::poll/init])(dev-setup)
(mount-root))
```Next, you will need to dispatch a `::poll/set-rules` event somewhere.
Personally, I like dispatching this in my routes file (because I may
want to handle polling events differently on each page).# Non-goals
- *A perfectly accurate counter*. The internal counter is not intended
to be perfectly accurate. For example, if you set an interval to
`30`, expect the event to be dispatched roughly every 30 seconds,
but not exactly. In other words, don't use re-pollsive for a clock.
- *Handling really quick events*. The choice of having the `:interval`
be measured in seconds as opposed to milliseconds was intentional.
If you want to dispatch events with millisecond granularity, you are
likely better off using a one-off setTimeout.# Questions
If you have questions, I can usually be found hanging out in
the [clojurians](http://clojurians.net/) #reagent slack channel (my
handle is [@gadfly361](https://twitter.com/gadfly361)).# License
Copyright © 2018 Matthew Jaoudi
Distributed under the The MIT License (MIT).