summaryrefslogtreecommitdiff
path: root/README.md
diff options
context:
space:
mode:
Diffstat (limited to 'README.md')
-rw-r--r--README.md216
1 files changed, 216 insertions, 0 deletions
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..25ef563
--- /dev/null
+++ b/README.md
@@ -0,0 +1,216 @@
+# EventX
+
+Create scaleable event-driven applications with EventX, inspired by [re-frame](https://github.com/day8/re-frame/). EventX uses zero dependencies and is runtime agnostic, meaning that you can use it in Node, Deno, Bun, browsers, or really anywhere where JavaScript runs.
+
+## Example application
+
+This is an example application that demonstrates how to use the EventX library. It has a single starting point event called `request`, which returns an updated state, which changes the `counter`. When that state changes, the subscriber for the `counter` state fires.
+
+```typescript
+import EventX from "eventx";
+
+type AppState = {
+ counter: number;
+};
+
+const $ = EventX<AppState>({
+ counter: 1,
+});
+
+$.subscribe("$counter", (state) => {
+ console.log("counter changed", state);
+
+ return {
+ state,
+ };
+});
+
+$.subscribe("request", (state) => {
+ return {
+ state: {
+ ...state,
+ counter: state.counter + 1;
+ }
+ }
+});
+
+// Dispatch an event somewhere.
+$.dispatch("request");
+```
+
+## Installation
+
+```shell
+npm i eventx
+```
+
+## Documentation
+
+### State
+
+At the core of your application is state. You start by initiating EventX with some initial state, like so:
+
+```typescript
+import eventx from "eventx";
+
+type AppState = {
+ counter: number;
+};
+
+const $ = eventx<AppState>({
+ counter: 1,
+});
+```
+
+You can model your `AppState` however you like. It does not have to be called `AppState`.
+
+### Events
+
+Events set things in motion. You can dispatch events like so:
+
+```typescript
+$.dispatch("some-event-name");
+```
+
+And, if there's a subscription for that event name, that subscription will then fire. The above example is a data-less event, but you can also dispatch events with data, like so:
+
+```typescript
+$.dispatch("some-event-name", arg1, arg2, arg3);
+```
+
+### Subscriptions
+
+Subscriptions listen to events or changes to state. Each subscription must return a `Response` object.
+
+#### Event subscriptions
+
+You can listen to events like so:
+
+```typescript
+$.subscribe("some-event-name", (state, arg1, arg2, arg3) => {
+ return {
+ state,
+ };
+});
+```
+
+Each subscription has a callback function which gets passed to it the app state and whatever data was passed
+when the event was dispatched. Subscription callbacks must return an `Response` which consists of updated state and/or further event dispatches. If you don't want to update state, just return the same state that the callback got in the first place.
+
+#### State change subscriptions
+
+You can also listen to state changes with subscriptions, which will fire when the listened state changes. You can listen to state changes like so:
+
+```typescript
+$.subscribe("$counter", (state) => {
+ return {
+ state,
+ };
+});
+```
+
+Notable difference here is the `$` prefix in the subscription listener name, which tells EventX what state to look for. Here `$counter` will look for the root-level `counter` key in state. To look for nested state, simply add a dot (`.`) followed by the key name, i.e: `$counter.nestedKey`. Additionally, state change subscriptions do not get any additional data passed to them, only state.
+
+#### Subscribe only once
+
+If you want to subscribe to an event or state change only once, you can use the `$.subscribeOnce` method. This method works similarly to `$.subscribe`, but it will automatically unsubscribe after the first event or state change.
+
+```typescript
+$.subscribeOnce("$counter", (state) => {
+ return {
+ state,
+ };
+});
+```
+
+#### Unsubscribe
+
+If you want to unsubscribe from an event or state change, you can use the `$.unsubscribe` method. This method takes the event or state change name as its argument and removes the subscription.
+
+```typescript
+$.unsubscribe("counter++");
+```
+
+#### Change state
+
+You can change state by returning a new state object, like so:
+
+```typescript
+$.subscribe("counter++", (state) => {
+ return {
+ state: {
+ ...state,
+ counter: state.counter + 1,
+ },
+ };
+});
+```
+
+#### Dispatch events
+
+You can also dispatch events from within subscriptions, like so:
+
+```typescript
+$.subscribe("counter++", (state) => {
+ return {
+ state: {
+ ...state,
+ counter: state.counter + 1,
+ },
+ };
+});
+
+$.subscribe("some-event-name", (state) => {
+ return {
+ state,
+ dispatch: {
+ event: "counter++",
+ },
+ };
+});
+```
+
+Now if `some-event-name` is dispatched, it also dispatches `counter++`. You can also pass data along, like so:
+
+```typescript
+$.subscribe("counter-increase", (state, increase: number) => {
+ return {
+ state: {
+ ...state,
+ counter: state.counter + increase,
+ },
+ };
+});
+
+$.subscribe("some-event-name", (state) => {
+ return {
+ state,
+ dispatch: {
+ event: "counter-increase",
+ args: [5],
+ },
+ };
+});
+```
+
+So now if `some-event-name` is dispatched, it also dispatches `counter-increase` with an increase of 5.
+
+#### Get the subscription count
+
+If you want to get the number of subscriptions for a specific event or state change, you can use the `$.getSubscriptionCount` method. This method takes the event or state change name as its argument and returns the number of subscriptions.
+
+```typescript
+// State change subscriptions
+$.getSubscriptionCount("$counter");
+
+// Event subscriptions
+$.getSubscriptionCount("some-event-name");
+```
+
+#### Get all subscriptions
+
+If you want to get all subscriptions, you can use the `$.subscriptions` method. This method returns an array of all the subscription names.
+
+```typescript
+$.subscriptions();
+```