@restate/core
Version:
_Restate_ is a predictable, easy to use, easy to integrate, typesafe state container for [React](https://reactjs.org/).
96 lines (95 loc) • 2.62 kB
JavaScript
import { createDraft, finishDraft } from "immer";
import { Subject, queueScheduler } from "rxjs";
import { observeOn, takeUntil } from "rxjs/operators";
class RestateStore {
_state$;
_close$ = new Subject();
_options;
_middleware = [];
constructor(stateSubject, middleware, options) {
this._state$ = stateSubject;
this._middleware = middleware;
this._options = options;
}
static of(state, middleware, options) {
return new RestateStore(state, middleware, options);
}
_next(updateFunctionOrNextState, trace) {
try {
let useUpdateFunction2 = function(state) {
const ret = createDraft(state);
if (isUpdateFunction) {
const update = updateFunctionOrNextState(ret);
return update == null ? ret : createDraft(update);
} else {
throw new Error("We should not be here");
}
};
var useUpdateFunction = useUpdateFunction2;
const isUpdateFunction = updateFunctionOrNextState instanceof Function;
const nextStateDraft = isUpdateFunction ? useUpdateFunction2(this.state) : createDraft(updateFunctionOrNextState);
recursiveMiddlewareHandler({
middleware: this._middleware,
nextState: nextStateDraft,
currentState: this.state
});
const nextState = finishDraft(nextStateDraft);
const nextStatePackage = {
state: nextState,
trace
};
this._state$.next(nextStatePackage);
return nextStatePackage;
} catch (e) {
console.error(e);
return { state: this._state$.value };
}
}
next(updateFunctionOrNextState, trace) {
this._next(updateFunctionOrNextState, trace);
}
nextAsync(updateFunctionOrNextState, trace) {
setTimeout(() => {
this._next(updateFunctionOrNextState, trace);
}, 0);
}
get state() {
return this._state$.value.state;
}
close() {
this._close$.next("closing the store");
this._close$.complete();
}
get state$() {
return this._state$.pipe(takeUntil(this._close$), observeOn(queueScheduler));
}
get options() {
return this._options;
}
get middleware() {
return this._middleware;
}
}
function recursiveMiddlewareHandler({
middleware,
nextState,
currentState
}) {
if (middleware.length === 0) {
return;
}
const nextMiddleware = middleware[0];
nextMiddleware({
nextState,
currentState
});
const remainingMiddleware = middleware.slice(1, middleware.length);
return recursiveMiddlewareHandler({
middleware: remainingMiddleware,
nextState,
currentState
});
}
export {
RestateStore
};