UNPKG

@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
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 };