diff --git a/package-lock.json b/package-lock.json index c7bf806..3e86177 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "@josepot/react-rxjs", - "version": "0.0.1", + "version": "0.1.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index c8095dd..652081e 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "version": "0.0.1", + "version": "0.1.0", "repository": { "type": "git", "url": "git+https://github.com/josepot/react-rxjs.git" diff --git a/src/connectFactoryObservable.ts b/src/connectFactoryObservable.ts index 4affd96..43908f2 100644 --- a/src/connectFactoryObservable.ts +++ b/src/connectFactoryObservable.ts @@ -2,20 +2,18 @@ import { Observable } from "rxjs" import { useEffect, useState } from "react" import reactOperator from "./react-operator" import { batchUpdates } from "./batch-updates" +import { + StaticObservableOptions, + defaultStaticOptions, +} from "./connectObservable" -export interface ConnectFactoryObservableOptions { - suspenseTime?: number - gracePeriod?: number -} - -interface FactoryObservableOptions { +interface FactoryObservableOptions extends StaticObservableOptions { suspenseTime: number - subscriptionGraceTime: number } -const defaultOptions: FactoryObservableOptions = { +const defaultOptions: FactoryObservableOptions = { + ...defaultStaticOptions, suspenseTime: 200, - subscriptionGraceTime: 100, } export function connectFactoryObservable< @@ -25,10 +23,10 @@ export function connectFactoryObservable< >( getObservable: (...args: A) => Observable, initialValue: I, - options_?: Partial, + options?: Partial>, ): [(...args: A) => O | I, (...args: A) => Observable] { - const { suspenseTime, subscriptionGraceTime } = { - ...options_, + const { suspenseTime, unsubscribeGraceTime, compare } = { + ...options, ...defaultOptions, } const cache = new Map>() @@ -44,7 +42,8 @@ export function connectFactoryObservable< const reactObservable$ = reactOperator( getObservable(...input), initialValue, - subscriptionGraceTime, + unsubscribeGraceTime, + compare, () => { cache.delete(key) }, diff --git a/src/connectObservable.ts b/src/connectObservable.ts index 3293954..500f968 100644 --- a/src/connectObservable.ts +++ b/src/connectObservable.ts @@ -3,12 +3,30 @@ import { useEffect, useState } from "react" import reactOperator from "./react-operator" import batchUpdates from "./batch-updates" +export interface StaticObservableOptions { + unsubscribeGraceTime: number + compare: (a: T, b: T) => boolean +} +export const defaultStaticOptions: StaticObservableOptions = { + unsubscribeGraceTime: 100, + compare: (a, b) => a === b, +} + export function connectObservable( observable: Observable, initialValue: IO, - gracePeriod?: number, + options?: Partial>, ) { - const reactObservable$ = reactOperator(observable, initialValue, gracePeriod) + const { unsubscribeGraceTime, compare } = { + ...options, + ...defaultStaticOptions, + } + const reactObservable$ = reactOperator( + observable, + initialValue, + unsubscribeGraceTime, + compare, + ) const useStaticObservable = () => { const [value, setValue] = useState( diff --git a/src/react-operator.ts b/src/react-operator.ts index e6d88de..a1f79d7 100644 --- a/src/react-operator.ts +++ b/src/react-operator.ts @@ -1,14 +1,15 @@ import { Observable, ReplaySubject, Subscription } from "rxjs" +import { distinctUntilChanged } from "rxjs/operators" export interface ReactObservable extends Observable { getCurrentValue: () => O | IO } -const DEFAULT_GRACE_PERIOD = 100 const reactOperator = ( source$: Observable, initialValue: I, - gracePeriod: number = DEFAULT_GRACE_PERIOD, + gracePeriod: number, + compare: (a: T | I, b: T) => boolean, teardown?: () => void, ): ReactObservable => { let subject: ReplaySubject | undefined @@ -26,7 +27,7 @@ const reactOperator = ( if (!subject || hasError) { hasError = false subject = new ReplaySubject(1) - subscription = source$.subscribe({ + subscription = distinctUntilChanged(compare)(source$).subscribe({ next(value) { currentValue = value subject!.next(value)