Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/bcherny/redrock
Typesafe, reactive redux
https://github.com/bcherny/redrock
flux javascript reactive redux rx rxjs typescript
Last synced: 3 months ago
JSON representation
Typesafe, reactive redux
- Host: GitHub
- URL: https://github.com/bcherny/redrock
- Owner: bcherny
- License: mit
- Created: 2016-10-09T08:11:56.000Z (over 8 years ago)
- Default Branch: master
- Last Pushed: 2017-02-26T20:31:55.000Z (almost 8 years ago)
- Last Synced: 2024-10-12T07:34:44.674Z (3 months ago)
- Topics: flux, javascript, reactive, redux, rx, rxjs, typescript
- Language: TypeScript
- Homepage:
- Size: 68.4 KB
- Stars: 14
- Watchers: 4
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE.md
Awesome Lists containing this project
README
[![Build Status][build]](https://circleci.com/gh/bcherny/redrock) [![npm]](https://www.npmjs.com/package/redrock) [![mit]](https://opensource.org/licenses/MIT)
[build]: https://img.shields.io/circleci/project/bcherny/redrock.svg?branch=master&style=flat-square
[npm]: https://img.shields.io/npm/v/redrock.svg?style=flat-square
[mit]: https://img.shields.io/npm/l/redrock.svg?style=flat-square## Highlights
- 100% type-safe:
- Statically guarantees that a reducer is defined for each Action
- Statically guarantees that emitters are called with the correct Action data given their Action name
- Statically guarantees that listeners are called with the correct Action data given their Action name
- Mental model similar to [Redux](https://github.com/reactjs/redux), with several improvements over Redux:
- Store is decoupled from emitter
- Emitters are reactive; in fact, they use [Rx](https://github.com/Reactive-Extensions/RxJS) Observables!
- Listeners are on specific Actions
- Listeners are called with both current and previous values (convenience borrowed from Angular $watch/Object.Observe)## Conceptual Overview
1. Create a redrock `Emitter` with a set of supported `Action`s
2. Register reducers on the emitter (a "reducer" is a mapping from a given `Action` to its side effects)
3. Components in your app `emit()` `Action`s on your emitter
4. `Actions` first trigger side-effects (via their respective reducers), then trigger any callbacks listening on that `Action` (callbacks are registered with `on()`)## Installation
```sh
npm install redrock --save
```## Usage
```ts
import { Emitter } from 'redrock'// Mock store
const store: { [id: number]: boolean } = {}// Enumerate actions
type Actions = {
INCREMENT_COUNTER: number
OPEN_MODAL: boolean
}// Define redrock Emitter
class App extends Emitter { }// Create bus and register reducers (throws a compile time error unless both of these keys are defined, and return values of the right types)
const app = new App({
INCREMENT_COUNTER: ({ id, value }) => {
const previousValue = store[id]
store[id] = value
return previousValue
},
OPEN_MODAL: ({ id, value }) => {
const previousValue = store[id]
store[id] = value
return previousValue
}
})// Listen on an action (throws a compile time error if this event does not exist) (basic)
app.on('OPEN_MODAL')
.subscribe(_ => _.value)// Listen on an action (advanced)
app.on('INCREMENT_COUNTER')
.filter(_ => _.id === 42)
.debounce()
.subscribe(_ => console.log(`Counter incremented from ${_.previousValue} to ${_.value}!`))// Trigger an action (throws a compile time error unless id and value are set, and are of the right types)
app.emit('OPEN_MODAL', { id: 123, value: true })
```## Tests
```sh
npm test
```