Compare commits

...

64 commits

Author SHA1 Message Date
anatoly
fcdff7577a on to 0.1.23 2025-05-04 16:56:19 -04:00
Anatoly
984979b347
Merge pull request #139 from jwr/fixed-logging
fix parameters of goog.log functions to prevent compiler warnings
2025-05-04 16:48:36 -04:00
Jan Rychter
2f4d1a3581 fix parameters of goog.log functions to prevent compiler warnings 2025-04-30 15:36:35 +09:00
anatoly
2bca9089b8 including clj-kondo fix 2025-01-31 12:58:10 -05:00
Anatoly
656af38802
Merge pull request #138 from NoahTheDuke/nb/fix-clj-kondo-config-3
Fix clj-kondo config, part 3: Remove wrapping atom from clj-kondo hook
2025-01-31 12:56:51 -05:00
Noah Bogart
bfd7adf98f Remove wrapping atom from clj-kondo hook 2025-01-29 14:58:39 -05:00
anatoly
08173bc6a1 0.1.20
includes clj-kondo config fix #137
2024-11-04 10:22:00 -05:00
Anatoly
3fc6c58cd6
Merge pull request #137 from NoahTheDuke/nb/fix-clj-kondo-config-2
Fix clj-kondo config, part 2
2024-11-04 10:19:54 -05:00
Noah Bogart
ccaf99910c clj-kondo: Fix docstrings 2024-10-23 15:12:07 -04:00
Noah Bogart
9c588f68c2 clj-kondo: lint defstate as atom 2024-10-23 14:53:41 -04:00
Anatoly
f16d7004ee
Merge pull request #134 from tolitius/dependabot/maven/org.clojure-clojure-1.11.2
Bump org.clojure:clojure from 1.11.1 to 1.11.2
2024-08-22 21:29:37 -04:00
dependabot[bot]
3caea10121
Bump org.clojure:clojure from 1.11.1 to 1.11.2
Bumps [org.clojure:clojure](https://github.com/clojure/clojure) from 1.11.1 to 1.11.2.
- [Changelog](https://github.com/clojure/clojure/blob/master/changes.md)
- [Commits](https://github.com/clojure/clojure/compare/clojure-1.11.1...clojure-1.11.2)

---
updated-dependencies:
- dependency-name: org.clojure:clojure
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-22 02:54:08 +00:00
anatoly
fb09fef496 on to 0.1.19 2024-08-21 22:53:31 -04:00
Anatoly
b89b930ec2
Merge pull request #133 from NoahTheDuke/nb/fix-clj-kondo-config
Update defstate clj-kondo hook to return a var
2024-08-21 22:43:40 -04:00
Noah Bogart
4065f5df36 Update defstate clj-kondo hook to return a var 2024-07-11 11:41:52 -04:00
Anatoly
632977ff41
update the "Structure and Interpretation of Computer Programs" link 2024-07-01 13:45:07 -04:00
anatoly
5275023b38 add deps.edn 2024-03-05 22:49:19 -05:00
anatoly
ad6ca6fb5e up to 0.1.18 2024-03-04 18:43:40 -05:00
Anatoly
eff4c04f21
Merge pull request #130 from rajcspsg/issue_128
Add clojure-kondo for mount.defstate
2024-03-04 18:39:28 -05:00
Rajkumar Natarajan
5df6c941f7 incorporate the review comments for .clj-kondo 2024-03-02 15:15:55 -08:00
Rajkumar Natarajan
098b56d14f Add clojure-kondo for mount.defstate 2023-05-30 13:47:07 -07:00
Anatoly
58e2ded430
[doc]: remove the broken travis ci link 2023-04-15 23:00:17 -04:00
anatoly
8a3fc385a2 update changelog: 0.1.17 2022-12-19 15:20:16 -05:00
anatoly
2d050e9055 fix: swap-states non string rollback
thanks to @egg-juxt for bringing it up
2022-12-19 15:17:38 -05:00
Anatoly
b77f504cfd
Merge pull request #122 from rgkirch/patch-1
Update README.md
2021-11-24 16:23:40 -05:00
rgkirch
5ac52b725b
Update README.md 2021-11-20 16:46:43 -05:00
Anatoly
c85da6149c
docs: update license year 2020-09-10 20:12:54 -04:00
anatoly
6cf5390a44 up cljs-repl version for examples 2020-07-31 20:27:04 -04:00
anatoly
bc3924aedf add yang dep for examples 2020-07-30 16:30:29 -04:00
Anatoly
5d992042e4
Merge pull request #114 from dijonkitchen/patch-1
docs: make wording clearer
2019-12-26 09:39:10 -05:00
JC
83542e56a7
docs: make wording clearer
Uses same order 

Uses semantic linefeed for the section: https://rhodesmill.org/brandon/2012/one-sentence-per-line/
2019-12-25 06:16:53 -08:00
anatoly
232df7a8a3 .travis: force openjdk8 2019-08-20 23:19:55 -04:00
Anatoly
10dbbaa40b
Merge pull request #110 from dgr/tweak-composables
Update `only` and `except` single-arity parameter names.
2019-08-20 23:09:53 -04:00
Dave Roberts
5b26fb6092 Update only and except single-arity parameter names.
The single-arity parameter names for the `only` and `except` functions
did not match the same parameters in the dual-arity versions of the
same functions. This makes both arities use the same name for the same
parameter.
2019-08-13 10:38:22 -05:00
Anatoly
e9f9dfca14
[docs]: add clarification about "load-config" fn 2019-07-09 16:28:22 -04:00
Anatoly
348297ee11
[docs]: (create-conn) rephrase clarification 2019-07-09 10:28:49 -04:00
Anatoly
52831f6b3e
[docs]: add fn "create-conn" clarification 2019-07-09 09:51:44 -04:00
Anatoly
9666d3f372
Merge pull request #109 from cloojure/patch-1
Update differences-from-component.md
2019-04-11 20:12:43 -04:00
Alan Thompson
5564e367e7
Update differences-from-component.md
small typo
2019-04-11 15:36:53 -07:00
anatoly
f65ed6a266 add change log for 0.1.16 2019-01-28 10:43:58 -05:00
anatoly
6dafae195d release 0.1.16 2019-01-28 10:36:02 -05:00
Anatoly
5fab543501
Merge pull request #107 from krajj7/fix_106
prevent reloading of mount.core ns - fix https://github.com/tolitius/mount/issues/106
2019-01-28 10:32:51 -05:00
krajj7
2ba3c60995 synced project.clj version with build.boot 2019-01-26 13:13:28 +01:00
krajj7
fb52f79396 prevent reloading of mount.core ns - fix https://github.com/tolitius/mount/issues/106 2019-01-26 13:13:28 +01:00
anatoly
c5f3e4cdf8 #104: current-state should return Derefable on :cljc 2019-01-04 13:00:53 -05:00
anatoly
76e9a71a13 release 0.1.15 2018-12-04 12:15:38 -05:00
Anatoly
8de6b09989
Merge pull request #101 from arichiardi/silent-new-cljs-warning
Silent *logger* warning in latest ClojureScript
2018-11-03 22:05:14 -04:00
Andrea Richiardi
884a2b2d87
Fix project.clj version to match boot's 2018-11-03 17:10:03 -07:00
Andrea Richiardi
c2687d1b9f
Silent *logger* warning in latest ClojureScript
The latest version is a bit stricter and emits a warning for ear-muffed vars
with no ^:dynamic.
2018-11-03 17:07:15 -07:00
Anatoly
17112646f1
[docs]: <! ed badge tags 2018-11-01 18:16:43 -04:00
Anatoly
d9c4f621cd
[docs]: update a link to Alan J. Perlis quote 2018-10-26 11:48:41 -04:00
anatoly
ed1c9944f6 npm: update package.json version
also remove circle.yml
2018-10-26 08:54:42 -04:00
anatoly
e07d7d6aad onto 0.1.15-SNAPSHOT 2018-10-25 22:36:17 -04:00
Anatoly
686b79e03f
[docs]: change feedback channels format 2018-10-25 22:35:25 -04:00
Anatoly
2ff032c8b3
[docs]: add clojar shileds badge 2018-10-25 22:32:26 -04:00
Anatoly
244d834c46
[docs]: reduce slack icon 2018-10-25 22:23:57 -04:00
Anatoly
0ff5fe106c
[docs]: add travis and release badges 2018-10-25 21:52:27 -04:00
anatoly
bb23747273 switch form circle to travis 2018-10-25 19:48:40 -04:00
anatoly
2d5566ae86 release 0.1.14 2018-10-25 18:35:55 -04:00
anatoly
1acd4feb4c #100 cljs: throw js/Error not just a string 2018-10-25 15:45:41 -04:00
Anatoly
c210cc486c
docs: toc add "Disable Lazy Start" sub section 2018-10-12 14:39:01 -04:00
Anatoly
4f8384763b
docs: toc link to "cljc mode" 2018-10-12 14:33:50 -04:00
anatoly
6e848d1ee4 #99 and #95: add ^{:on-lazy-start :throw} 2018-10-12 14:22:49 -04:00
anatoly
db38d8cacd onto 0.1.14-SNAPSHOT 2018-08-07 23:28:29 -04:00
24 changed files with 387 additions and 81 deletions

1
.clj-kondo/config.edn Normal file
View file

@ -0,0 +1 @@
{:config-paths ["../resources/clj-kondo.exports/mount/mount/"]}

6
.gitignore vendored
View file

@ -1,7 +1,10 @@
/target
/classes
/checkouts
pom.xml
.cpcache/
.rebel_readline_history
cljs-test-runner-out
node_modules
pom.xml.asc
.repl*
dev/resources/public/js/*
@ -18,3 +21,4 @@ doo-index.html
/.nrepl-history
.cljs_rhino_repl/
out/
.clj-kondo/.cache

26
.travis.yml Normal file
View file

@ -0,0 +1,26 @@
sudo: false
language: java
script:
- boot test
- boot test-cljs
- boot test-cljs-advanced
install:
- mkdir -p ~/bin
- export PATH=~/bin:$PATH
- curl -L https://github.com/boot-clj/boot-bin/releases/download/latest/boot.sh -o ~/bin/boot
- chmod +x ~/bin/boot
jdk: openjdk8
env:
matrix:
- BOOT_CLOJURE_VERSION=1.8.0
global:
- JAVA_OPTS="-Xms512m -Xmx2048m"
jdk:
- openjdk8
cache:
directories:
- $HOME/.m2
- $HOME/.boot/cache/bin
- $HOME/.boot/cache/lib
- $HOME/bin

View file

@ -1,3 +1,28 @@
## 0.1.19
###### Wed Aug 21 22:43:40 2024 -0400
* add `clojure-kondo`
## 0.1.17
###### Mon Dec 19 15:17:21 2022 -0500
* 2d050e9 fix: swap-states non string rollback (thanks to [egg-juxt](https://github.com/egg-juxt))
## 0.1.16
###### Mon Jan 28 10:34:26 2019 -0500
* fb52f79 prevent reloading of mount.core ns ([106](https://github.com/tolitius/mount/issues/106))
* c5f3e4c current-state should return Derefable on :cljc ([104](https://github.com/tolitius/mount/issues/104))
* c2687d1 silent `*logger*` warning in latest ClojureScript([101](https://github.com/tolitius/mount/issues/101))
* bb23747 switch form circle to travis
## 0.1.14
###### Thu Oct 25 18:34:22 2018 -0400
* cljs: throw js/Error not just a string ([#100](https://github.com/tolitius/mount/issues/100))
* add ^{:on-lazy-start :throw} ([#95](https://github.com/tolitius/mount/issues/95) and [#99](https://github.com/tolitius/mount/issues/99))
* self hosted ClojureScript support ([#85](https://github.com/tolitius/mount/issues/85) and [#97](https://github.com/tolitius/mount/issues/97))
## 0.1.12
###### Sat Feb 10 14:53:04 2018 -0500

31
Makefile Normal file
View file

@ -0,0 +1,31 @@
.PHONY: clean test jar tag outdated install deploy tree repl
clean:
rm -rf target
rm -rf classes
jar: clean test tag
clojure -A:jar
test: clean
clojure -X:test :patterns '[".*"]' # clojure tests
# clojure -Atest-cljs -r ".*test.self.host.*" # clojure script tests
# run "j8; boot test-cljs" until running cljs tests via deps.edn is fixed
outdated:
clojure -M:outdated
tag:
clojure -A:tag
install: jar
clojure -A:install
deploy: jar
clojure -A:deploy
tree:
mvn dependency:tree
repl:
clojure -A:dev -A:repl

View file

@ -1,19 +1,13 @@
> I think that it's _extraordinarily important_ that we in computer science keep fun in computing
_**Alan J. Perlis** from [Structure and Interpretation of Computer Programs](https://mitpress.mit.edu/sicp/full-text/book/book-Z-H-3.html)_
_**Alan J. Perlis** from [Structure and Interpretation of Computer Programs](https://web.mit.edu/6.001/6.037/sicp.pdf)_
# mount <img src="doc/img/mount-logo.png" width="70px">
[![<! release](https://img.shields.io/badge/dynamic/json.svg?label=release&url=https%3A%2F%2Fclojars.org%2Fmount%2Flatest-version.json&query=version&colorB=blue)](https://github.com/tolitius/mount/releases)
[![<! clojars](https://img.shields.io/clojars/v/mount.svg)](https://clojars.org/mount)
module | branch | status
----------|----------|----------
mount | `master` | [![Circle CI](https://circleci.com/gh/tolitius/mount/tree/master.png?style=svg)](https://circleci.com/gh/tolitius/mount/tree/master)
###### _any_ questions or feedback: [`#mount`](https://clojurians.slack.com/messages/mount/) clojurians slack channel <img src="doc/img/slack-icon.png" width="15px"> (or just [open an issue](https://github.com/tolitius/mount/issues))
[![Clojars Project](http://clojars.org/mount/latest-version.svg)](http://clojars.org/mount)
> <img src="doc/img/slack-icon.png" width="30px"> _any_ questions or feedback: [`#mount`](https://clojurians.slack.com/messages/mount/) clojurians slack channel (or just [open an issue](https://github.com/tolitius/mount/issues))
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
- [Why?](#why)
@ -34,6 +28,8 @@ _**Alan J. Perlis** from [Structure and Interpretation of Computer Programs](htt
- [Swapping States with States](#swapping-states-with-states)
- [Stop an Application Except Certain States](#stop-an-application-except-certain-states)
- [ClojureScript is Clojure](doc/clojurescript.md#managing-state-in-clojurescript)
- [cljc mode](#cljc-mode)
- [Disable Lazy Start](#disable-lazy-start)
- [Packaging](#packaging)
- [Affected States](#affected-states)
- [Recompiling Namespaces with Running States](#recompiling-namespaces-with-running-states)
@ -94,7 +90,7 @@ Creating state is easy:
(defstate conn :start (create-conn))
```
where the `create-conn` function is defined elsewhere, can be right above it.
where the `create-conn` function creates a connection (for example to a database) and is defined elsewhere, can be right above it.
In case this state needs to be cleaned / destroyed between reloads, there is also `:stop`
@ -107,7 +103,7 @@ That is pretty much it. But wait, there is more.. this state is _a top level bei
`required` by other namespaces or in REPL:
```clojure
dev=> (require '[app.nyse :refer [conn]])
dev=> (require '[app.db :refer [conn]])
nil
dev=> conn
#object[datomic.peer.LocalConnection 0x1661a4eb "datomic.peer.LocalConnection@1661a4eb"]
@ -176,8 +172,9 @@ this `config`, being top level, can be used in other namespaces, including the o
(defstate conn :start (create-connection config))
```
[here](dev/clj/app/www.clj#L32)
is an example of a web server that "depends" on a similar `config`.
[here](dev/clj/app/www.clj#L32) is an example of a web server that "depends" on a similar `config`.
###### _(the example `load-config` function above comes from [cprop](https://github.com/tolitius/cprop), but could of course be a custom function that loads configuration from a file)_
## Value of values
@ -408,7 +405,7 @@ The `start-with-states` function takes values in a form of `{:start fn :stop fn}
```
`start-with-states` takes a map of states with their substitutes. For example `#'app.nyse/db` here is the real deal (remote) DB that is being
substituted with `#(connect test-config)` function, which could endup being anything, a map, an in memory DB, etc.
substituted with `#(connect test-config)` function, which could end up being anything, a map, an in memory DB, etc.
The `:stop` functions of substitutes can be anything, and could refer to the original state references. As in the example above: `db` and `publisher`
are real references. They would need to be accessible from the namespace of course, so you might need to `(:require [app.neo :refer [db]])`
@ -551,6 +548,56 @@ Mount detected that `#'dev/won't-be-here-long` was deleted, hence:
<< stopping.. #'dev/won't-be-here-long (it was deleted)
```
## `cljc` mode
By default mount states are kept under var references. While it works for Clojure, it falls short in the land of ClojureScript since, especially during an `:advanced` compilation, var names get compressed + ClojureScript does not support reified vars.
To support both Clojure and ClojureScript mount has a `cljc` mode which is well documented in [here](doc/clojurescript.md#managing-state-in-clojurescript), and can be enabled by `(mount/in-cljc-mode)`.
### Disable Lazy Start
When in `cljc` mode, mount states that are not started by `(mount/start a b c)`, or that are not transitive states: i.e. not `:require`d at the time `(mount/start)` is called, will start lazily whenever they are dereferenced:
```clojure
=> (mount/in-cljc-mode)
:cljc
=> (defstate db-connection :start (println "connecting")
:stop (println "disconnecting..."))
=> db-connection
#object[mount.core.DerefableState 0x546b9d51 {:status :pending, :val nil}]
dev=> (mount/running-states)
#{}
dev=> @db-connection ;; db-connection will start here when deref'ed even though it was not started explicitly
connecting
dev=> (mount/running-states)
#{"#'dev/db-connection"}
```
This can be quite handy as it allows certain app states to start lazily.
However there are cases when it is best to fail in case a certain state is deref'ed while it was not yet started. This is possible by marking such states with `^{:on-lazy-start :throw}` metadata:
```clojure
=> (defstate ^{:on-lazy-start :throw} db-connection :start (do (println "connecting") 42)
:stop (println "disconnecting..."))
=> @db-connection ;; this will throw since db connection is deref'ed before it was started
java.lang.RuntimeException: :on-lazy-start is set to :throw i.e. (defstate {:on-lazy-start :throw} #'dev/db-connection...) and #'dev/db-connection state was not explicitly started before it was deref'ed (i.e. @#'dev/db-connection)
=> (mount/start #'dev/db-connection)
connecting
{:started ["#'dev/db-connection"]}
=> @db-connection
42
```
## Packaging
Since `mount` relies on the Clojure/Script Compiler to learn about all the application states, before `mount/start` is called all the namespaces that have `defstate`s need to be compiled.
@ -814,7 +861,7 @@ The documentation is [here](doc/runtime-arguments.md#passing-runtime-arguments).
## License
Copyright © 2017 tolitius
Copyright © 2020 tolitius
Distributed under the Eclipse Public License either version 1.0 or (at
your option) any later version.

2
boot.properties Normal file
View file

@ -0,0 +1,2 @@
BOOT_VERSION=2.7.1
BOOT_CLOJURE_VERSION=1.10.1

View file

@ -1,8 +1,18 @@
(def +version+ "0.1.13")
(def +version+ "0.1.18")
;; -- since boot is no more, this file will go away
;; -- once deps.edn "learns" how to run all cljs tests
;; j8; boot test
;; j8; boot test-cljs
;; j8; boot test-cljs-advanced
;; j8; boot -v build-jar push-snapshot
;; j8; boot -v build-jar push-release
(set-env!
:source-paths #{"src"}
:dependencies '[;; mount brings _no dependencies_, everything here is for
:resource-paths #{"resources"}
:dependencies '[;; mount brings _NO DEPENDENCIES_, everything here is for
;; mount dev, examples apps and tests
[org.clojure/clojure "1.8.0" :scope "provided"]
@ -13,6 +23,7 @@
[cheshire "5.5.0" :scope "provided"]
[hiccups "0.3.0" :scope "provided" :exclusions [org.clojure/clojurescript]]
[com.andrewmcveigh/cljs-time "0.3.14" :scope "provided"]
[tolitius/yang "0.1.9" :scope "provided"]
[ch.qos.logback/logback-classic "1.1.3" :scope "provided"]
[org.clojure/tools.logging "0.3.1" :scope "provided"]
[robert/hooke "1.3.0" :scope "provided"]
@ -33,11 +44,12 @@
;; boot cljs
[adzerk/boot-cljs "1.7.228-1" :scope "test"]
[adzerk/boot-cljs-repl "0.3.0" :scope "test"]
[adzerk/boot-cljs-repl "0.4.0" :scope "test"]
[cider/piggieback "0.3.9" :scope "test" :exclusions [org.clojure/clojurescript]]
[weasel "0.7.0" :scope "test" :exclusions [org.clojure/clojurescript]]
[nrepl "0.4.5" :scope "test"]
[pandeiro/boot-http "0.7.1-SNAPSHOT" :scope "test"]
[tolitius/boot-stripper "0.1.0-SNAPSHOT" :scope "test"]
[com.cemerick/piggieback "0.2.1" :scope "test" :exclusions [org.clojure/clojurescript]]
[weasel "0.7.0" :scope "test" :exclusions [org.clojure/clojurescript]]
[adzerk/boot-reload "0.4.8" :scope "test"]
[crisptrutski/boot-cljs-test "0.2.1-SNAPSHOT" :scope "test"]])
@ -132,7 +144,8 @@
(task-options!
tcs/test-cljs {:js-env :phantom}
push {:ensure-branch nil}
push {; :ensure-clean nil
:ensure-branch nil}
pom {:project 'mount
:version +version+
:description "managing Clojure and ClojureScript app state since (reset)"

View file

@ -1,17 +0,0 @@
machine:
java:
version: oraclejdk8
environment:
_JAVA_OPTIONS: "-Xms512m -Xmx2048m"
dependencies:
pre:
- wget https://github.com/boot-clj/boot-bin/releases/download/latest/boot.sh
- mv boot.sh boot && chmod a+x boot && sudo mv boot /usr/local/bin
test:
override:
- boot test
- boot test-cljs
- boot test-cljs-advanced
- lein do clean, test2junit

52
deps.edn Normal file
View file

@ -0,0 +1,52 @@
{:paths ["src" "resources"]
:deps {} ;; deps no deps
:aliases {:dev {:extra-deps {metosin/jsonista {:mvn/version "0.3.8"}
com.datomic/datomic-free {:mvn/version "0.9.5359"
:exclusions [joda-time/joda-time]}
org.clojure/tools.nrepl {:mvn/version "0.2.12"}
org.clojure/tools.namespace {:mvn/version "0.2.11"}
cheshire/cheshire {:mvn/version "5.5.0"}
compojure/compojure {:mvn/version "1.5.0"}
ring/ring-jetty-adapter {:mvn/version "1.1.0"}
robert/hooke {:mvn/version "1.3.0"}
proto-repl/proto-repl {:mvn/version "0.3.1"}
proto-repl-charts/proto-repl-charts {:mvn/version "0.3.2"}
nrepl/nrepl {:mvn/version "0.7.0"}}}
:test {:extra-paths ["test/core" "test/clj" "test/cljs" "test/resources"]
:extra-deps {com.datomic/datomic-free {:mvn/version "0.9.5359"
:exclusions [joda-time/joda-time]}
org.clojure/tools.nrepl {:mvn/version "0.2.12"}
robert/hooke {:mvn/version "1.3.0"}
org.clojure/tools.logging {:mvn/version "1.3.0"}
io.github.cognitect-labs/test-runner {:git/url "https://github.com/cognitect-labs/test-runner.git"
:sha "e7660458ce25bc4acb4ccc3e2415aae0a4907198"}}
:main-opts ["-m" "cognitect.test-runner"]
:exec-fn cognitect.test-runner.api/test}
:test-cljs {:extra-paths ["test/core" "test/cljs" "test/resources"]
:extra-deps {org.clojure/clojure {:mvn/version "1.8.0"}
org.clojure/clojurescript {:mvn/version "1.7.228"}
com.andrewmcveigh/cljs-time {:mvn/version "0.3.14"}
hiccups/hiccups {:mvn/version "0.3.0"}
datascript/datascript {:mvn/version "0.15.0"}
olical/cljs-test-runner {:mvn/version "3.8.1"}}
:main-opts ["-m" "cljs-test-runner.main"]}
:repl {:extra-paths ["dev/clj"]
:extra-deps {cider/cider-nrepl {:mvn/version "0.22.4"}
org.clojure/tools.logging {:mvn/version "1.2.4"}
com.bhauman/rebel-readline {:mvn/version "0.1.4"}}
:main-opts ["-e" "(require 'dev)(in-ns 'dev)"
"-m" "nrepl.cmdline" "--middleware" "[cider.nrepl/cider-middleware]"
"-i" "-f" "rebel-readline.main/-main"]}
:outdated {:extra-deps {olical/depot {:mvn/version "2.0.1"}}
:main-opts ["-m" "depot.outdated.main" "-a" "outdated"]}
:tag {:extra-deps {tolitius/tag {:mvn/version "0.1.7"}}
:main-opts ["-m" "tag.core" "tolitius/mount" "managing Clojure and ClojureScript app state since (reset)"]}
:jar {:extra-deps {seancorfield/depstar {:mvn/version "1.1.128"}}
:extra-paths ["target/about"]
:main-opts ["-m" "hf.depstar.jar" "target/mount.jar" "--exclude" "clojure/core/specs/alpha.*"]}
:deploy {:extra-deps {deps-deploy/deps-deploy {:mvn/version "RELEASE"}}
:main-opts ["-m" "deps-deploy.deps-deploy" "deploy" "target/mount.jar"]}
:install {:extra-deps {deps-deploy/deps-deploy {:mvn/version "RELEASE"}}
:main-opts ["-m" "deps-deploy.deps-deploy" "install" "target/mount.jar"]}}}

View file

@ -1,7 +1,6 @@
(ns dev
(:require [clojure.pprint :refer [pprint]]
[clojure.tools.namespace.repl :as tn]
[boot.core :refer [load-data-readers!]]
[mount.core :as mount :refer [defstate]]
[mount.tools.graph :refer [states-with-deps]]
[app.utils.logging :refer [with-logging-status]]
@ -41,4 +40,11 @@
(tn/refresh :after 'dev/go))
(mount/in-clj-mode)
(defn load-data-readers!
"Refresh *data-readers* with readers from newly acquired dependencies."
[]
(#'clojure.core/load-data-readers)
(set! *data-readers* (.getRawRoot #'*data-readers*)))
(load-data-readers!)

View file

@ -1,5 +1,5 @@
(ns proto-play
(:require [mount.tools.graph :as mount]
(:require [mount.tools.graph :as mg]
[proto-repl-charts.graph :as proto]))
(defn mount->proto [graph]
@ -10,6 +10,6 @@
{}
graph))
(->> (mount/states-with-deps)
(->> (mg/states-with-deps)
mount->proto
(proto/graph "a proto graph of mount states"))

View file

@ -94,7 +94,7 @@ the same with or without Mount: there are no extra mental steps.
### Objects vs. Namespaces
One thing that feels a bit "unClojure" about Component is "Objects". Objects everywhere, and Objects for everything.
This is how Component "separates explicit dependencies" and "clears the bounaries".
This is how Component "separates explicit dependencies" and "clears the boundaries".
This is also how an Object Oriented language does it, which does not leave a lot of room for functions:
with Component most of the functions are _methods_ which is an important distinction.
@ -146,9 +146,13 @@ no "ceremony".
Mount uses namespaces and vars where Component uses records and protocols.
Component manages protocols and records, and in order to do that it requires a whole app buyin, which makes it a _framework_.
Component manages records and protocols,
and in order to do that it requires a whole app buy-in,
which makes it a _framework_.
Mount does not need to manage namespaces and vars, since it is very well managed by the Clojure Compiler, which makes it a _library_.
Mount does not need to manage namespaces and vars,
since it is very well managed by the Clojure Compiler,
which makes it a _library_.
## What Component does better

View file

@ -1,6 +1,6 @@
{
"name": "@tolitius/mount",
"version": "0.1.12",
"version": "0.1.16",
"license": "EPL-1.0",
"homepage": "https://github.com/tolitius/mount",
"repository": {
@ -8,14 +8,16 @@
"url": "https://github.com/tolitius/mount"
},
"author": {
"name" : "tolitius",
"url" : "http://www.dotkam.com"
}
,
"name": "tolitius",
"url": "http://www.dotkam.com"
},
"files": [
"src/*"
],
"directories": {
"lib": "src"
},
"dependencies": {
"ws": "^8.16.0"
}
}

45
pom.xml Normal file
View file

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
<groupId>mount</groupId>
<artifactId>mount</artifactId>
<version>0.1.23</version>
<name>mount</name>
<description>managing Clojure and ClojureScript app state since (reset)</description>
<url>https://github.com/tolitius/mount</url>
<licenses>
<license>
<name>Eclipse Public License</name>
<url>http://www.eclipse.org/legal/epl-v10.html</url>
</license>
</licenses>
<developers>
<developer>
<name>tolitius</name>
</developer>
</developers>
<scm>
<url>https://github.com/tolitius/mount</url>
<connection>scm:git:git://github.com/tolitius/mount.git</connection>
<developerConnection>scm:git:ssh://git@github.com/tolitius/mount.git</developerConnection>
<tag>HEAD</tag>
</scm>
<dependencies>
<dependency>
<groupId>org.clojure</groupId>
<artifactId>clojure</artifactId>
<version>1.11.2</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<sourceDirectory>src</sourceDirectory>
</build>
<repositories>
<repository>
<id>clojars</id>
<url>https://repo.clojars.org/</url>
</repository>
</repositories>
</project>

View file

@ -1,4 +1,4 @@
(defproject mount "0.1.12-SNAPSHOT"
(defproject mount "0.1.17"
:description "managing Clojure and ClojureScript app state since (reset)"
:url "https://github.com/tolitius/mount"
:license {:name "Eclipse Public License"

View file

@ -0,0 +1,3 @@
{:linters {:mount/defstate {:level :warning}}
:hooks {:analyze-call {mount.core/defstate hooks.defstate/defstate
mount.core/defstate! hooks.defstate/defstate}}}

View file

@ -0,0 +1,39 @@
(ns hooks.defstate
(:require [clj-kondo.hooks-api :as api]))
(defn defstate [{:keys [node]}]
(let [[n & args] (next (:children node))
[docs args] (if (string? (api/sexpr (first args)))
[(first args) (next args)]
[nil args])
m (when-let [m (first (:meta n))]
(api/sexpr m))
m (if (map? m) m {})
ks (cond-> (take 1 args)
(> (count args) 2) (conj (nth args 2)))
invalid-key (first (remove (comp (partial contains? #{:start :stop}) api/sexpr) ks))]
(cond
invalid-key
(api/reg-finding!
{:message (str "lifecycle functions can only contain `:start` and `:stop`. illegal function found: " (api/sexpr invalid-key))
:type :mount/defstate
:row (:row (meta invalid-key))
:col (:col (meta invalid-key))})
(not (contains? (set (map api/sexpr ks)) :start))
(throw (ex-info "lifecycle functions must include `:start`" {}))
((complement contains?) #{2 4} (count args))
(throw (ex-info "lifecycle functions must consist of no more than 2 pair forms: `:start` and `:stop`" {}))
(and (contains? m :on-reload) (not (contains? #{:noop :stop} (:on-reload m))))
(api/reg-finding!
{:message "metadata `:on-reload` key can only have value of `noop` or `stop`"
:type :mount/defstate
:row (:row (meta n))
:col (:col (meta n))})
:else
{:node (api/list-node
(cond-> [(api/token-node 'def) n]
docs (conj docs)
true (conj (api/list-node
(list*
(api/token-node 'do)
args)))))})))

View file

@ -1,4 +1,5 @@
(ns mount.core
#?(:clj {:clojure.tools.namespace.repl/load false}) ; prevent reloading of this ns
#?(:clj (:require [mount.tools.macro :refer [on-error throw-runtime] :as macro]
[mount.tools.macrovich :refer [deftime]]
[mount.tools.logger :refer [log]]
@ -17,10 +18,6 @@
(defonce ^:private meta-state (atom {}))
(defonce ^:private running (atom {})) ;; to clean dirty states on redefs
;; supporting tools.namespace: (disable-reload!)
#?(:clj
(alter-meta! *ns* assoc ::load false)) ;; to exclude the dependency
(defn- make-state-seq [state]
(or (:order (@meta-state state))
(swap! state-seq inc)))
@ -60,17 +57,6 @@
(stop))
(swap! running dissoc state)))
#?(:clj
(defn current-state [state]
(let [{:keys [inst var]} (@meta-state state)]
(if (= @mode :cljc)
@inst
(var-get var))))
:cljs
(defn current-state [state]
(-> (@meta-state state) :inst deref)))
#?(:clj
(defn alter-state! [{:keys [var inst]} value]
(if (= @mode :cljc)
@ -126,9 +112,12 @@
(#?(:clj deref
:cljs -deref)
[_]
(let [{:keys [status inst] :as state} (@meta-state name)]
(let [{:keys [status var inst] :as state} (@meta-state name)]
(when-not (:started status)
(up name state (atom #{})))
(if (= :throw (-> var meta :on-lazy-start))
(throw-runtime (str ":on-lazy-start is set to :throw i.e. (defstate {:on-lazy-start :throw} " name "...) "
"and " name " state was not explicitly started before it was deref'ed (i.e. @" name ")"))
(up name state (atom #{}))))
@inst))
#?(:clj clojure.lang.IPending
:cljs IPending)
@ -137,6 +126,17 @@
[_]
(boolean ((running-states) name))))
#?(:clj
(defn current-state [state]
(let [{:keys [var]} (@meta-state state)]
(if (= @mode :cljc)
(->DerefableState state)
(var-get var))))
:cljs
(defn current-state [state]
(-> (@meta-state state) :inst deref)))
(defn on-reload-meta [s-var]
(or (-> s-var meta :on-reload)
:restart)) ;; restart by default on ns reload
@ -284,7 +284,7 @@
(if-not (empty? fs) ;; (mount/start) vs. (mount/start #{}) vs. (mount/start #{1 2 3})
(apply start fs)
{:started #{}})
(let [states (or (seq states)
(let [states (or (->> states (map var-to-str) seq)
(all-without-subs))]
{:started (bring states up <)}))))
@ -294,7 +294,7 @@
(if-not (empty? fs) ;; (mount/stop) vs. (mount/stop #{}) vs. (mount/stop #{1 2 3})
(apply stop fs)
{:stopped #{}})
(let [states (or (seq states)
(let [states (or (->> states (map var-to-str) seq)
(find-all-states))
_ (dorun (map unsub states)) ;; unmark substitutions marked by "start-with" / "swap-states"
stopped (bring states down >)]
@ -308,8 +308,8 @@
set))
(defn only
([states]
(only (find-all-states) states))
([these]
(only (find-all-states) these))
([states these]
(intersection (mapset var-to-str these)
(mapset var-to-str states))))
@ -322,8 +322,8 @@
states))
(defn except
([states]
(except (find-all-states) states))
([these]
(except (find-all-states) these))
([states these]
(remove (mapset var-to-str these)
(mapset var-to-str states))))

View file

@ -3,10 +3,10 @@
(:import [goog.debug Console])]))
#?(:cljs
(defonce *logger*
(defonce ^:dynamic *logger*
(do
(.setCapturing (Console.) true)
(glog/getLogger "mount"))))
(glog/getLogger "mount" nil))))
#?(:clj
(defn log [msg & _]
@ -15,6 +15,6 @@
#?(:cljs
(defn log [msg & level]
(case (first level)
:error (glog/error *logger* msg)
(glog/info *logger* msg))))
:error (glog/error *logger* msg nil)
(glog/info *logger* msg nil))))

View file

@ -16,7 +16,7 @@
:cljs (try ~f
(catch :default t#
(if ~fail?
(throw (~'str ~msg " " t#))
(throw (js/Error (~'str ~msg " " t#)))
{:f-failed (ex-info ~msg {} t#)})))))
(defmacro throw-runtime [msg]

View file

@ -6,8 +6,9 @@
(defn entity [conn id]
(d/entity (d/db conn) id))
(defn touch [conn results]
(defn touch
"takes 'entity ids' results from a query
e.g. '#{[272678883689461] [272678883689462] [272678883689459] [272678883689457]}'"
[conn results]
(let [e (partial entity conn)]
(map #(-> % first e d/touch) results)))

View file

@ -109,6 +109,16 @@
(is (= 42 (dval conn)))
(mount/stop)))
(testing "swap-states should swap states on start and rollback on stop"
(let [states (swap-states {#'tapp.nyse/conn swap-conn})]
(is (= states (#'mount.core/find-all-states)))
(mount/start #'tapp.nyse/conn)
(is (= 42 (dval conn)))
(mount/stop #'tapp.nyse/conn)
(mount/start #'tapp.nyse/conn)
(is (instance? datomic.peer.LocalConnection (dval conn)))
(mount/stop)))
(testing "swap-states should swap states with states and return only states that it is given"
(let [t-states #{"#'is.not/here" #'mount.test.composable-fns/test-conn #'tapp.nyse/conn}
states (swap-states t-states {#'tapp.nyse/conn swap-conn

View file

@ -5,12 +5,24 @@
mount.test.fun-with-values
mount.test.private-fun
mount.test.printing
mount.test.parts
mount.test.cleanup-dirty-states
mount.test.stop-except
mount.test.start-without
mount.test.start-with
mount.test.start-with-states
))
(t/run-tests
'mount.test.fun-with-values
'mount.test.private-fun
'mount.test.printing
'mount.test.parts
'mount.test.cleanup-dirty-states
;; 'mount.test.stop-except ;; TODO: can't run with deps.edn (due to "WebSocket is not defined")
;; 'mount.test.start-with ;; boot, lein have no problems
;; 'mount.test.start-with-states ;; most likely somm misconfigured in node..
'mount.test.start-without
)
(defn run-tests []