{"id":32181812,"url":"https://github.com/vermilionsands/chromatic","last_synced_at":"2026-07-14T17:36:26.928Z","repository":{"id":57714090,"uuid":"110888991","full_name":"vermilionsands/chromatic","owner":"vermilionsands","description":"Atom-like reference type backed by Hazelcast distributed structures.","archived":false,"fork":false,"pushed_at":"2017-11-27T21:22:44.000Z","size":32,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-21T22:52:47.679Z","etag":null,"topics":["clojure","hazelcast"],"latest_commit_sha":null,"homepage":"","language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"epl-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vermilionsands.png","metadata":{"files":{"readme":"README.md","changelog":null,"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":"2017-11-15T21:33:12.000Z","updated_at":"2017-11-22T22:10:52.000Z","dependencies_parsed_at":"2022-09-26T21:31:12.768Z","dependency_job_id":null,"html_url":"https://github.com/vermilionsands/chromatic","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/vermilionsands/chromatic","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vermilionsands%2Fchromatic","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vermilionsands%2Fchromatic/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vermilionsands%2Fchromatic/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vermilionsands%2Fchromatic/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vermilionsands","download_url":"https://codeload.github.com/vermilionsands/chromatic/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vermilionsands%2Fchromatic/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35472809,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-14T02:00:06.603Z","response_time":114,"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","hazelcast"],"created_at":"2025-10-21T22:52:40.545Z","updated_at":"2026-07-14T17:36:26.922Z","avatar_url":"https://github.com/vermilionsands.png","language":"Clojure","funding_links":[],"categories":[],"sub_categories":[],"readme":"# chromatic\n\nAtom-like reference type, that uses Hazelcast to store it's state in a distributed fashion. \n\n## Dependency\n\n[![Clojars Project](https://img.shields.io/clojars/v/vermilionsands/chromatic.svg)](https://clojars.org/vermilionsands/chromatic)\n\n## Usage\n\nIn REPL:\n```clj\n(require '[vermilionsands.chromatic :as chromatic])\n(import '[com.hazelcast.config Config])\n(import '[com.hazelcast.core Hazelcast])\n\n;; hazelcast instance\n(def hazelcast (Hazelcast/newHazelcastInstance (Config.))\n\n;; distributed atom\n(def hz-atom (chromatic/distributed-atom hazelcast :test-atom 0)\n```\n\nRepeat the above steps in a different REPL (different JVM instance). After that you can use distributed atom like a regular one.  \n\nAtom value after calls to `swap!` and `reset!` in one JVM would be available in another.\n\nIn one REPL:\n```clj\n;; set value in one REPL\n(reset! hz-atom \"my shared value\")\n```\n\nAfter that in another one:\n```clj\n;; check that value is visible\n@hz-atom ;; =\u003e would return \"my shared value\"\n```\n\n## Details\n\n`vermilionsands.chromatic` defines a `HazelcastAtom` type which implements the same interfaces as `clojure.lang.Atom`, as well as a constructor function `distributed-atom`.\n \n##### swap! and reset!\n\n`swap!` is implemented using `compareAndSet` and passes data to `IAtomicReference`. Values need to be serializable.\nFunctions (for swap!) are executed locally and do not need to be serializable.\n\n##### validators\n\nValidator added using `set-validator!` is not shared between instances. Shared validator can be added using \n`set-shared-validator` from `vermilionsands.chromatic/DistributedAtom` protocol. This functions would be \nshared between instances.\n  \n**Note:** validator function has to be present on all JVM instances and has to be serializable.\n    \nValidation is called only on the instance which is changing the data.\n \n##### watches\n \nWatches added using `add-watch` are local (like validator). Shared watches can be added using `add-shared-watch` \nfrom `DistributedAtom` protocol are shared between instances. Functions need to meet the same requirements as shared validators.\n  \nBy default notification that triggers watches is executed only on the instance which is changing the data (like with validation). \nThere is an option to enable global notifications, which would trigger watches on all instances.\n \nIn order to turn on global notifications pass `{:global-notifications true}` to `distributed-atom` function when first atom instance is created.\nThis would create a notification topic that would be used to trigger watches when a change occurs.\n\nNotifications are implemented using `ReliableTopic`. Each notification is a vector od `[old-value new-value]`.  \n \n##### metadata\n\nMetadata is stored on instance and is not shared.\n\n##### misc\n  \n* distributed atom is not partitioned (due to `IAtomicReference` not being partitioned).\n* to free resources when no longer needed call `(destroy! distributed-atom)`. This would destroy all underlying distributed objects\n* when notifications are enabled atom needs to be closed using `.close()` from `java.io.Closeable`\n  Otherwise notification listener would not be removed. \n \n\n## License\n\nCopyright © 2017 vermilionsands\n\nDistributed under the Eclipse Public License either version 1.0 or (at\nyour option) any later version.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvermilionsands%2Fchromatic","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvermilionsands%2Fchromatic","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvermilionsands%2Fchromatic/lists"}