https://github.com/alloc/ople
Event-driven, observable data flow for React 💥👀
https://github.com/alloc/ople
data-flow event-driven observable reactjs state-management
Last synced: about 2 months ago
JSON representation
Event-driven, observable data flow for React 💥👀
- Host: GitHub
- URL: https://github.com/alloc/ople
- Owner: alloc
- Created: 2020-05-31T14:20:10.000Z (almost 5 years ago)
- Default Branch: master
- Last Pushed: 2023-10-16T17:31:56.000Z (over 1 year ago)
- Last Synced: 2024-09-16T18:39:59.058Z (7 months ago)
- Topics: data-flow, event-driven, observable, reactjs, state-management
- Language: TypeScript
- Homepage:
- Size: 1010 KB
- Stars: 9
- Watchers: 4
- Forks: 0
- Open Issues: 13
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# ople
[](https://www.npmjs.com/package/ople)
[](https://travis-ci.org/alloc/ople)
[](https://codecov.io/gh/alloc/ople)
[](https://bundlephobia.com/result?p=ople)
[](https://github.com/prettier/prettier)
[](https://paypal.me/alecdotbiz)Event-driven, observable data flow for React 💥👀
**Features**
- Transparent observability for seamless, reactive data flow
- Automatic disposal of event listeners and `auto` reactions
- Compatible with all [`wana`](https://github.com/alloc/wana) functions
- Mixins for sharable behavior (inspired by React hooks)
- Strict type safety with TypeScript
- Objects are readonly outside their initializer
- Objects have built-in event emitting
- Highly minifiable code
- Concise, distilled APIÂ
## Usage
The `createOple` function constructs an Ople object, which is both observable
and readonly to React components. Expose methods for React components to call,
and expose events for React components to subscribe to.```tsx
import {createOple, auto} from 'ople'// Pass an initializer function to receive a state object,
// a set function, and an emit function.
const state = createOple((self, set, emit) => {
// The state is mutable.
self.a = 1// The state is observable.
auto(() => {
console.log('a:', self.a)
})// The set function is a shortcut for `Object.assign(self, {...})`
set({ b: 1, c: 1 })// The set function converts every getter into an observable getter (unless a setter exists).
set({
get sum() {
return self.a + self.b + self.c
}
})
auto(() => {
console.log('sum:', self.sum)
})// The set function is the recommended way of declaring methods.
set({
// Methods declared with `set` are wrapped to disable implicit observation
// and to set the Ople context until the method returns.
add(key: string, n: number) {
self[key] += n// The emit function is a shortcut for `self.emit(...)`
emit('add', key, n)
}
})// Subscribe to your own events or the events of another Ople object.
// Your listeners are removed when the built-in `dispose` method is called.
self.on({
add(key, n) {
console.log('add:', key, n)
}
})
})// The state is observable outside the initializer, too.
auto(() => {
console.log('b:', state.b)
})state.add('b', 2)
// Clean up any side effects.
state.dispose()
```Â
## Classes
If you like creating objects with `new` syntax or you prefer storing your methods
on a prototype for efficiency, you can create an `Ople` subclass. For more info,
see the [Classes](./docs/classes.md) page.Â
## Mixins
As an alternative to classes (which limit you to a single superclass), you can
use "mixin functions" to share behavior between your Ople objects. Mixins should
be very familiar to anyone who uses React hooks. Just remember, mixins are **NOT**
subject to the same rules as React hooks. For example, mixins can be called from
within `if` blocks. The **only rule** of mixins is that you should only ever call
them from within an Ople context (eg: inside a `createOple` initializer).For more info, see the [Mixins](./docs/mixins.md) page.
Â
## FAQ
These questions are common for beginners to ask. If you have a question not yet
listed here, feel free to open a pull request, and I'll add an answer to it.- **Why are Ople objects readonly outside their initializer?**
To keep mutations local to the state they are acting upon. This makes it
easy to remember which module contains the code you are concerned with.
It also encourages you to declare reusable methods instead of duplicating
logic across your project. Your methods will be implicitly bound to their
local state, which means you won't have to manually `.bind` them before
using them as React element props (eg: `onClick`).