Reactive state management library. Manage your application's states, effects, and actions easy way. Make apps more scalable with a unidirectional data-flow.
Every StateController
has the following features:
- Dispatching actions
- Filtering actions
- Adding effects
- Communications among Controllers[
Although they are independents
] - RxJs full features
counter
: Angular Demo | React Demo | Vue Demo
todos
: Angular Demo | React Demo | Vue Demo
import { StateController, Get } from "ajwah-store";
export class CounterState extends StateController<number> {
constructor() {
super(0);
}
inc() {
this.emit(this.state + 1);
}
dec() {
this.emit(this.state - 1);
}
async asyncInc() {
this.dispatch("asyncInc");
await new Promise((resolve) => setTimeout(resolve, 10));
this.inc();
}
get count$() {
return merge(
this.action$.whereType("asyncInc").pipe(mapTo("loading...")),
this.stream$.pipe(map((count) => `${count}`))
);
}
}
const csCtrl = Get(CounterState);
csCtrl.count$.subscribe(console.log);
csCtrl.inc();
csCtrl.dec();
csCtrl.asyncInc();
import { Get } from "ajwah-store";
import { ajwahTest } from "ajwah-test";
import { CounterController } from "./counterController";
describe("Counter state controller: ", () => {
let csCtrl: CounterState;
beforeEach(() => {
csCtrl = Get(CounterState);
});
afterEach(() => {
RemoveController(CounterState);
});
it("initial state", async () => {
await ajwahTest({
build: () => csCtrl.stream$,
verify: (states) => {
expect(states[0]).toEqual(0);
},
});
});
it("increment", async () => {
await ajwahTest({
build: () => csCtrl.stream$,
act: () => {
csCtrl.inc();
},
skip: 1,
verify: (states) => {
expect(states[0]).toEqual(1);
},
});
});
it("decrement", async () => {
await ajwahTest({
build: () => csCtrl.stream$,
act: () => {
csCtrl.dec();
},
skip: 1,
verify: (states) => {
expect(states[0]).toEqual(-1);
},
});
});
it("async increment", async () => {
await ajwahTest({
build: () => csCtrl.stream$,
act: () => {
csCtrl.asyncInc();
},
skip: 1,
wait: 10,
verify: (states) => {
expect(states[0]).toEqual(1);
},
});
});
it("async increment", async () => {
await ajwahTest({
build: () => csCtrl.count$,
act: () => {
csCtrl.asyncInc();
},
skip: 2,
wait: 10,
verify: (states) => {
expect(states[0]).toEqual("loading...");
expect(states[1]).toEqual("1");
},
});
});
});