@ngneat/loadoff
Version:
<p align="center"> <img width="20%" height="20%" src="./logo.svg"> </p>
129 lines (121 loc) • 3.52 kB
JavaScript
import { defer, BehaviorSubject, pipe, of } from 'rxjs';
import { finalize, map, startWith, catchError, tap, scan } from 'rxjs/operators';
function loadingTracker(tracker) {
return function (source) {
return defer(() => {
tracker.next(true);
return source;
}).pipe(finalize(() => tracker.next(false)));
};
}
function loadingFor(...keys) {
const result = {};
for (const key of keys) {
const subject = new BehaviorSubject(false);
result[key] = {
inProgress$: subject.asObservable(),
track() {
return loadingTracker(subject);
},
};
}
return result;
}
class AsyncState {
constructor(state = {}) {
this.res = undefined;
this.error = undefined;
this.loading = true;
this.success = false;
this.complete = false;
Object.assign(this, state);
}
}
function createAsyncState(state = {}) {
return new AsyncState(state);
}
function createSyncState(res) {
return new AsyncState({
loading: false,
complete: true,
res,
});
}
function isSuccess(state) {
return state.success;
}
function hasError(state) {
return !!state.error;
}
function isComplete(state) {
return state.complete;
}
function isLoading(state) {
return state.loading;
}
function toAsyncState() {
return pipe(map((res) => {
return new AsyncState({
res,
loading: false,
complete: true,
success: true,
});
}), startWith(new AsyncState()), catchError((error) => {
console.error(error);
return of(new AsyncState({
error,
loading: false,
complete: true,
}));
}));
}
function createAsyncStore() {
const store = new BehaviorSubject(new AsyncState());
function update(data) {
let resolved = data;
if (typeof data === 'function') {
resolved = data(store.getValue().res);
}
store.next(new AsyncState({
res: resolved,
loading: false,
complete: true,
success: true,
}));
}
return {
value$: store.asObservable(),
getValue: store.getValue(),
update,
track() {
return pipe(tap({
next(data) {
update(data);
},
error(err) {
store.next(new AsyncState({
error: err,
loading: false,
complete: true,
}));
},
}));
},
};
}
/**
* Operator that retains the previous response on a new emission of an AsyncState item.
* This can be useful for implementing a refresh mechanism, where you want to keep displaying the old value while fetching a new value
*/
function retainResponse(startWithValue = createAsyncState()) {
return pipe(startWith(startWithValue), scan((acc, val) => new AsyncState(Object.assign(Object.assign({}, val), { res: val.success ? val.res : acc.res }))));
}
function someLoading() {
return map(states => states.some(s => s.loading));
}
/**
* Generated bundle index. Do not edit.
*/
export { AsyncState, createAsyncState, createAsyncStore, createSyncState, hasError, isComplete, isLoading, isSuccess, loadingFor, retainResponse, someLoading, toAsyncState };
//# sourceMappingURL=ngneat-loadoff.mjs.map