Awesome
Ring
Minimalist and functional javascript state manager.
❤️ Features
- ES6 module.
- Pure functional design.
- View layer agnostic.
- Tiny codebase, very understandable.
- Designed following the principles of UNIX philosophy.
- Very well tested.
- Ridiculously small API. After reading this file you will
understand
Ring
better than me.
💡 Showcase
A counter that increments by one every time the user confirms.
import ring from "https://cdn.jsdelivr.net/gh/marcodpt/ring/index.js"
ring({
init: 0,
register: update => ({
inc: () => update(count => count + 1)
}),
view: (count, {inc}) => {
if (window.confirm(`Count is ${count}. Increment?`)) {
inc()
}
}
})
💯 Examples
📖 API
ring({init, register, view}) => stop
init: _
The initial state
of the ring
. It can be any type of data.
register: (update, dispatch) => events
It is called before initializing the ring
returning the registered
events
.
update: (state => newState) => ()
Receives a setter
to update
the state
and call view
with the
newState
.
dispatch: (event, ...args) => ()
Triggers a call to a registered
event
passing ...args
to the event
.
events: {init, ...events, done}
Events registered
at ring
initialization by the register
function.
init: state => ()
Special event
called at startup.
event: (...args) => ()
The function signature of a user-defined event
can have any name.
done: state => ()
Special event
triggered when stop
is called.
view: (state, events) => ()
Updates the view
of the ring
, it is always called after an update
or when
starting.
stop: () => ()
Returns a function that stops
the ring
.
📦 Projects using this module
If your project is not on the list, submit a pull request, it is a way to increase awareness of your project and this module.
- Merlin: A functional JS framework that values elegance, simplicity and minimalism.
🤝 Contributing
It's a very simple project. Any contribution, any feedback is greatly appreciated.
⭐ Support
If this project was useful to you, consider giving it a star on github, it's a way to increase evidence and attract more contributors.
🙏 Acknowledgment
This work is hugely influenced by these amazing projects:
A huge thank you to all the people who contributed to these projects.
📢 Motivation
I was extremely delighted and impressed with Hyperapp and Raj when I started using them.
But some things started to bother me:
view
receivesdispatch
in Raj, which implies thatactions
are not static, and with each call toview
newactions
are generated.- Hyperapp achieves static
actions
by placing them outside theapp
. Which in my opinion breaks the paradigm of a pure, internal execution environment. - It's hard to know the
state
withindispatch
calls when it involves concurrent asynchronous calls both in Raj and in Hyperapp. - I can't understand Hyperapp's
effects
API to this day. - It's very difficult to separate layout from javascript logic in
Hyperapp's
views
.
What would I want from a state management library?
- The
actions
define staticevents
within theapp
, and these could be called from each other, also functioning as a library. State
updates
must be explicit and always carry the currentstate
value, regardless of the asynchronous sequence of execution.- It will be isolated, tiny, easy to understand and there will be no reason for me to want to modify the API. Without integrating vDom, template engine, routing, and others.
So I decided to try to create my state management library, to serve as a solid foundation for more complex problems.
And I'm happy with the result!