# montar
manage state in typescript. inspired by [tolitius/mount](https://github.com/tolitius/mount) from clojure.
What's this all about? Watch this [video from Stuart Sierra](https://www.youtube.com/watch?v=13cmHf_kt-Q) to learn more about the background of component, mount, and montar.
## Install
```console
$ yarn add -D @digiresilience/montar
```
## Usage
```
import { defState } from "@digiresilience/montar"
```
### Creating State
```
// db.ts
const db = defState("db", {
start: createDbConnection
})
export default db
```
where the createDbConnection function creates a connection (for example to a database) and is defined elsewhere.
### Starting state
```
import { start } from "@digiresilience/montar"
const bootYourApp = async () => {
// .. prepare for app boot
// ..
// boot!
return start()
}
```
### Using State
But wait, there is more.. this state is a top level being, which means it can be simply imported by other namespaces:
For example let's say an app needs a connection above. No problem:
```
// server.ts
import db from "./db"
async function doStuff() {
return db.executeSql("foo")
}
```
Note that before `start()` is called, `db` will be uninitialized and therefore unusable. You must call `start()` before accessing any states.
### Starting/Stopping State
`montar` has start and stop functions that will walk all the states created with `defState` and start / stop them accordingly: i.e. will call their start and stop defined functions.
When testing you might be interested in starting only certain states. You can do this with
- `startOnly(string[])` - only start the given states. WARNING: dependencies are not auto started, so you must ensure all dependencies are passed.
- `startWithout(string[])` - start all states _except_ those passed
### Start and Stop Order
Since dependencies are "injected" by requiring on the namespace level, montar trusts the typescript compiler and node.js runtime to maintain the start and stop order for all the defStates.
The "start" order is then recorded and replayed on each subsequent start
The "stop" order is simply the reverse of the start order.
### Troubleshooting / Debugging
Set the `DEBUG=montar` environment variable for runtime debug logs.
## Differences to mount
montar was created to bring management of top-level application state under
control. It steals greedily from
[tolitius/mount](https://github.com/tolitius/mount) a well-known library in the
clojure and clojurescript community.
The problem solved is: how to load different sub-systems of your application while respecting dependency order? Also, how do achieve this without complicated dependency injection containers that make the code harder to read.
With montar once you define your state, then every other module can import and
use your state without special syntax or wrappers.
montar differs from mount in these ways:
- **start/stop are async** - the start and stop functions are async
- **no var rebinding** - instead we use the little-known [`Proxy`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy)
- this comes with limitations: only functions, arrays, objects can be defined as state. scalars do not work.
- **not concerned with reloading** - in clj/cljs you have the repl and great hot-code reloading (thanks to immutable and persistent data structures). we do not have this in javascript.
## Credits
Copyright © 2020-present [Center for Digital Resilience][cdr]
### Contributors
| [![Abel Luck][abelxluck_avatar]][abelxluck_homepage]
[Abel Luck][abelxluck_homepage] |
| ---------------------------------------------------------------------------------------- |
[abelxluck_homepage]: https://gitlab.com/abelxluck
[abelxluck_avatar]: https://secure.gravatar.com/avatar/0f605397e0ead93a68e1be26dc26481a?s=100&d=identicon
### License
[](https://www.gnu.org/licenses/agpl-3.0.en.html)
GNU AFFERO GENERAL PUBLIC LICENSE
Version 3, 19 November 2007
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see .
[cdrtech]: https://digiresilience.org/tech/
[cdr]: https://digiresilience.org