diff --git a/packages/core/src/internal/BehaviorObservable.ts b/packages/core/src/internal/BehaviorObservable.ts index f62a1c8..fa14757 100644 --- a/packages/core/src/internal/BehaviorObservable.ts +++ b/packages/core/src/internal/BehaviorObservable.ts @@ -3,3 +3,9 @@ import { Observable } from "rxjs" export interface BehaviorObservable extends Observable { getValue: () => any } + +export const enum Action { + Error, + Value, + Suspense, +} diff --git a/packages/core/src/internal/react-enhancer.ts b/packages/core/src/internal/react-enhancer.ts index ecba076..288cb12 100644 --- a/packages/core/src/internal/react-enhancer.ts +++ b/packages/core/src/internal/react-enhancer.ts @@ -1,7 +1,7 @@ import { Observable, noop } from "rxjs" import { take, filter, tap } from "rxjs/operators" import { SUSPENSE } from "../SUSPENSE" -import { BehaviorObservable } from "./BehaviorObservable" +import { BehaviorObservable, Action } from "./BehaviorObservable" import { EMPTY_VALUE } from "./empty-value" const reactEnhancer = (source$: Observable): BehaviorObservable => { @@ -42,9 +42,11 @@ const reactEnhancer = (source$: Observable): BehaviorObservable => { } }) as BehaviorObservable - let promise: any - let error = EMPTY_VALUE - const getValue = () => { + let promise: undefined | { type: Action.Suspense; payload: Promise } + let error: + | typeof EMPTY_VALUE + | { type: Action.Error; payload: any } = EMPTY_VALUE + const getValue = (): { type: Action; payload: any } => { let timeoutToken if (error !== EMPTY_VALUE) { clearTimeout(timeoutToken) @@ -56,25 +58,27 @@ const reactEnhancer = (source$: Observable): BehaviorObservable => { try { return { - type: "v", + type: Action.Value, payload: (source$ as BehaviorObservable).getValue(), } } catch (e) { if (promise) return promise - let value = EMPTY_VALUE + let value: + | typeof EMPTY_VALUE + | { type: Action.Value; payload: T } = EMPTY_VALUE promise = { - type: "s", + type: Action.Suspense, payload: result .pipe( filter((x) => x !== (SUSPENSE as any)), take(1), tap({ next(v) { - value = { type: "v", payload: v } + value = { type: Action.Value, payload: v } }, error(e) { - error = { type: "e", payload: e } + error = { type: Action.Error, payload: e } timeoutToken = setTimeout(() => { error = EMPTY_VALUE }, 50) @@ -99,7 +103,7 @@ const reactEnhancer = (source$: Observable): BehaviorObservable => { return promise } } - result.getValue = getValue as () => T | Promise + result.getValue = getValue return result } diff --git a/packages/core/src/internal/useObservable.ts b/packages/core/src/internal/useObservable.ts index 985eae7..2acfe5d 100644 --- a/packages/core/src/internal/useObservable.ts +++ b/packages/core/src/internal/useObservable.ts @@ -1,12 +1,8 @@ import { useEffect, useReducer } from "react" -import { BehaviorObservable } from "./BehaviorObservable" +import { BehaviorObservable, Action } from "./BehaviorObservable" import { SUSPENSE } from "../SUSPENSE" import { Observable } from "rxjs" -const ERROR: "e" = "e" -const VALUE: "v" = "v" -type Action = "e" | "v" | "s" - const reducer = ( current: { type: Action; payload: any }, action: { type: Action; payload: any }, @@ -47,14 +43,14 @@ export const useObservable = ( dispatch(source$.getValue()) } else { dispatch({ - type: VALUE, + type: Action.Value, payload: value, }) } }, (error) => dispatch({ - type: ERROR, + type: Action.Error, payload: error, }), ) @@ -62,6 +58,6 @@ export const useObservable = ( }, [source$]) const { type, payload } = state - if (type === VALUE) return payload + if (type === Action.Value) return payload throw payload } diff --git a/packages/utils/src/collect.ts b/packages/utils/src/collect.ts index 94c4498..5179e67 100644 --- a/packages/utils/src/collect.ts +++ b/packages/utils/src/collect.ts @@ -7,7 +7,7 @@ import { distinctUntilChanged, skipWhile, } from "rxjs/operators" -import { set, del, collector } from "./internal-utils" +import { CollectorAction, collector } from "./internal-utils" const defaultFilter = (source$: Observable) => source$.pipe(ignoreElements(), startWith(true), endWith(false)) @@ -37,6 +37,12 @@ export const collect = ( return (source$: Observable>) => collector(source$, (o) => - map((x) => ({ t: x ? set : del, k: o.key, v: o }))(enhancer(o)), + map((x) => ({ + t: x + ? (CollectorAction.Set as const) + : (CollectorAction.Delete as const), + k: o.key, + v: o, + }))(enhancer(o)), ) } diff --git a/packages/utils/src/collectValues.ts b/packages/utils/src/collectValues.ts index 30a75cb..120fbc0 100644 --- a/packages/utils/src/collectValues.ts +++ b/packages/utils/src/collectValues.ts @@ -1,6 +1,6 @@ import { Observable, GroupedObservable, OperatorFunction } from "rxjs" import { map, endWith } from "rxjs/operators" -import { set, del, collector } from "./internal-utils" +import { CollectorAction, collector } from "./internal-utils" /** * A pipeable operator that collects all the GroupedObservables emitted by @@ -12,7 +12,7 @@ export const collectValues = (): OperatorFunction< > => (source$: Observable>): Observable> => collector(source$, (inner$) => inner$.pipe( - map((v) => ({ t: set, k: inner$.key, v })), - endWith({ t: del, k: inner$.key }), + map((v) => ({ t: CollectorAction.Set as const, k: inner$.key, v })), + endWith({ t: CollectorAction.Delete, k: inner$.key }), ), ) diff --git a/packages/utils/src/internal-utils.ts b/packages/utils/src/internal-utils.ts index bed7003..a5d8404 100644 --- a/packages/utils/src/internal-utils.ts +++ b/packages/utils/src/internal-utils.ts @@ -37,24 +37,29 @@ export const scanWithDefaultValue = ( return source.pipe(scan(accumulator, seed), defaultStart(seed)) }) -export const set = "s" as const -export const del = "d" as const -export const complete = "c" as const +export const enum CollectorAction { + Set, + Delete, + Complete, +} export const collector = ( source: Observable>, enhancer: ( source: GroupedObservable, - ) => Observable<{ t: "d"; k: K } | { t: "s"; k: K; v: VV }>, + ) => Observable< + | { t: CollectorAction.Delete; k: K } + | { t: CollectorAction.Set; k: K; v: VV } + >, ): Observable> => source.pipe( publish((x) => x.pipe(mergeMap(enhancer), takeUntil(takeLast(1)(x)))), - endWith({ t: complete }), + endWith({ t: CollectorAction.Complete as const }), scanWithDefaultValue( (acc, val) => { - if (val.t === set) { + if (val.t === CollectorAction.Set) { acc.set(val.k, val.v) - } else if (val.t === del) { + } else if (val.t === CollectorAction.Delete) { acc.delete(val.k) } else { acc.clear()