Comparing version 1.0.1 to 2.0.0
@@ -11,4 +11,4 @@ "use strict"; | ||
var wrapDisplayName = function (BaseComponent, wrapperName) { | ||
return wrapperName + "(" + getDisplayName(BaseComponent) + ")"; | ||
return "".concat(wrapperName, "(").concat(getDisplayName(BaseComponent), ")"); | ||
}; | ||
exports.wrapDisplayName = wrapDisplayName; |
@@ -8,25 +8,17 @@ "use strict"; | ||
function useAsObservable(value, operator) { | ||
var isInitial = (0, react_1.useRef)(true); | ||
var subjectRef = (0, react_1.useRef)(new rxjs_1.BehaviorSubject(value)); | ||
var observableRef = (0, react_1.useRef)(); | ||
if (!observableRef.current) { | ||
var observable = subjectRef.current.asObservable(); | ||
observableRef.current = operator ? observable.pipe(operator) : observable; | ||
} | ||
var _a = (0, react_1.useMemo)(function () { | ||
var subject = new rxjs_1.BehaviorSubject(value); | ||
var observable = subject.asObservable(); | ||
return [operator ? observable.pipe(operator) : observable, subject]; | ||
}, []), observable = _a[0], subject = _a[1]; | ||
(0, useIsomorphicEffect_1.useIsomorphicEffect)(function () { | ||
if (isInitial.current) { | ||
isInitial.current = false; | ||
} | ||
else { | ||
// emit only on update | ||
subjectRef.current.next(value); | ||
} | ||
subject.next(value); | ||
}, [value]); | ||
(0, useIsomorphicEffect_1.useIsomorphicEffect)(function () { | ||
(0, react_1.useEffect)(function () { | ||
return function () { | ||
return subjectRef.current.complete(); | ||
subject.complete(); | ||
}; | ||
}, []); | ||
return observableRef.current; | ||
return observable; | ||
} | ||
exports.useAsObservable = useAsObservable; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.useMemoObservable = exports.useObservable = void 0; | ||
var rxjs_1 = require("rxjs"); | ||
var react_1 = require("react"); | ||
var useIsomorphicEffect_1 = require("./useIsomorphicEffect"); | ||
var useAsObservable_1 = require("./useAsObservable"); | ||
var operators_1 = require("rxjs/operators"); | ||
var shim_1 = require("use-sync-external-store/shim"); | ||
function getValue(value) { | ||
return typeof value === 'function' ? value() : value; | ||
} | ||
function useObservable(observable, initialValue) { | ||
var subscription = (0, react_1.useRef)(); | ||
var isInitial = (0, react_1.useRef)(true); | ||
var _a = (0, react_1.useState)(function () { | ||
var isSync = true; | ||
var syncVal = getValue(initialValue); | ||
subscription.current = observable.subscribe(function (nextVal) { | ||
if (isSync) { | ||
syncVal = nextVal; | ||
} | ||
else { | ||
setState(nextVal); | ||
} | ||
}); | ||
isSync = false; | ||
return syncVal; | ||
}), value = _a[0], setState = _a[1]; | ||
(0, useIsomorphicEffect_1.useIsomorphicEffect)(function () { | ||
// when the observable changes after initial (possibly sync render) | ||
if (!isInitial.current) { | ||
subscription.current = observable.subscribe(function (nextVal) { return setState(nextVal); }); | ||
} | ||
isInitial.current = false; | ||
return function () { | ||
if (subscription.current) { | ||
subscription.current.unsubscribe(); | ||
subscription.current = undefined; | ||
} | ||
function useObservableSubscription(observable) { | ||
var store = (0, react_1.useMemo)(function () { | ||
var currentValue; | ||
return { | ||
// Note: this works because the given observable always emits a value synchronously by concat-ing the given initialValue | ||
getCurrentValue: function () { return currentValue; }, | ||
subscribe: function (callback) { | ||
var subscription = observable.subscribe(function (value) { | ||
currentValue = value; | ||
callback(value); | ||
}); | ||
return function () { | ||
subscription.unsubscribe(); | ||
}; | ||
}, | ||
}; | ||
}, [observable]); | ||
return value; | ||
return (0, shim_1.useSyncExternalStore)(store.subscribe, store.getCurrentValue); | ||
} | ||
function useObservable(observable, initialValue) { | ||
return useObservableSubscription((0, useAsObservable_1.useAsObservable)(observable, (0, rxjs_1.pipe)((0, operators_1.distinctUntilChanged)(), (0, operators_1.switchMap)(function (observable) { | ||
return (0, rxjs_1.merge)((0, rxjs_1.defer)(function () { return (0, rxjs_1.of)(getValue(initialValue)); }), observable); | ||
})))); | ||
} | ||
exports.useObservable = useObservable; | ||
@@ -42,0 +37,0 @@ function useMemoObservable(observableOrFactory, deps, initialValue) { |
@@ -15,3 +15,7 @@ "use strict"; | ||
if (k2 === undefined) k2 = k; | ||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); | ||
var desc = Object.getOwnPropertyDescriptor(m, k); | ||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { | ||
desc = { enumerable: true, get: function() { return m[k]; } }; | ||
} | ||
Object.defineProperty(o, k2, desc); | ||
}) : (function(o, m, k, k2) { | ||
@@ -18,0 +22,0 @@ if (k2 === undefined) k2 = k; |
import { BehaviorSubject } from 'rxjs'; | ||
import { useRef } from 'react'; | ||
import { useEffect, useMemo } from 'react'; | ||
import { useIsomorphicEffect } from './useIsomorphicEffect'; | ||
export function useAsObservable(value, operator) { | ||
const isInitial = useRef(true); | ||
const subjectRef = useRef(new BehaviorSubject(value)); | ||
const observableRef = useRef(); | ||
if (!observableRef.current) { | ||
const observable = subjectRef.current.asObservable(); | ||
observableRef.current = operator ? observable.pipe(operator) : observable; | ||
} | ||
const [observable, subject] = useMemo(() => { | ||
const subject = new BehaviorSubject(value); | ||
const observable = subject.asObservable(); | ||
return [operator ? observable.pipe(operator) : observable, subject]; | ||
}, []); | ||
useIsomorphicEffect(() => { | ||
if (isInitial.current) { | ||
isInitial.current = false; | ||
} | ||
else { | ||
// emit only on update | ||
subjectRef.current.next(value); | ||
} | ||
subject.next(value); | ||
}, [value]); | ||
useIsomorphicEffect(() => { | ||
useEffect(() => { | ||
return () => { | ||
return subjectRef.current.complete(); | ||
subject.complete(); | ||
}; | ||
}, []); | ||
return observableRef.current; | ||
return observable; | ||
} |
@@ -1,40 +0,33 @@ | ||
import { useMemo, useRef, useState } from 'react'; | ||
import { useIsomorphicEffect } from './useIsomorphicEffect'; | ||
import { defer, merge, of, pipe } from 'rxjs'; | ||
import { useMemo } from 'react'; | ||
import { useAsObservable } from './useAsObservable'; | ||
import { distinctUntilChanged, switchMap } from 'rxjs/operators'; | ||
import { useSyncExternalStore } from 'use-sync-external-store/shim'; | ||
function getValue(value) { | ||
return typeof value === 'function' ? value() : value; | ||
} | ||
export function useObservable(observable, initialValue) { | ||
const subscription = useRef(); | ||
const isInitial = useRef(true); | ||
const [value, setState] = useState(() => { | ||
let isSync = true; | ||
let syncVal = getValue(initialValue); | ||
subscription.current = observable.subscribe(nextVal => { | ||
if (isSync) { | ||
syncVal = nextVal; | ||
} | ||
else { | ||
setState(nextVal); | ||
} | ||
}); | ||
isSync = false; | ||
return syncVal; | ||
}); | ||
useIsomorphicEffect(() => { | ||
// when the observable changes after initial (possibly sync render) | ||
if (!isInitial.current) { | ||
subscription.current = observable.subscribe(nextVal => setState(nextVal)); | ||
} | ||
isInitial.current = false; | ||
return () => { | ||
if (subscription.current) { | ||
subscription.current.unsubscribe(); | ||
subscription.current = undefined; | ||
} | ||
function useObservableSubscription(observable) { | ||
const store = useMemo(() => { | ||
let currentValue; | ||
return { | ||
// Note: this works because the given observable always emits a value synchronously by concat-ing the given initialValue | ||
getCurrentValue: () => currentValue, | ||
subscribe: (callback) => { | ||
const subscription = observable.subscribe(value => { | ||
currentValue = value; | ||
callback(value); | ||
}); | ||
return () => { | ||
subscription.unsubscribe(); | ||
}; | ||
}, | ||
}; | ||
}, [observable]); | ||
return value; | ||
return useSyncExternalStore(store.subscribe, store.getCurrentValue); | ||
} | ||
export function useObservable(observable, initialValue) { | ||
return useObservableSubscription(useAsObservable(observable, pipe(distinctUntilChanged(), switchMap(observable => merge(defer(() => of(getValue(initialValue))), observable))))); | ||
} | ||
export function useMemoObservable(observableOrFactory, deps, initialValue) { | ||
return useObservable(useMemo(() => getValue(observableOrFactory), deps), initialValue); | ||
} |
@@ -8,3 +8,3 @@ var getDisplayName = function (Component) { | ||
export var wrapDisplayName = function (BaseComponent, wrapperName) { | ||
return wrapperName + "(" + getDisplayName(BaseComponent) + ")"; | ||
return "".concat(wrapperName, "(").concat(getDisplayName(BaseComponent), ")"); | ||
}; |
import { BehaviorSubject } from 'rxjs'; | ||
import { useRef } from 'react'; | ||
import { useEffect, useMemo } from 'react'; | ||
import { useIsomorphicEffect } from './useIsomorphicEffect'; | ||
export function useAsObservable(value, operator) { | ||
var isInitial = useRef(true); | ||
var subjectRef = useRef(new BehaviorSubject(value)); | ||
var observableRef = useRef(); | ||
if (!observableRef.current) { | ||
var observable = subjectRef.current.asObservable(); | ||
observableRef.current = operator ? observable.pipe(operator) : observable; | ||
} | ||
var _a = useMemo(function () { | ||
var subject = new BehaviorSubject(value); | ||
var observable = subject.asObservable(); | ||
return [operator ? observable.pipe(operator) : observable, subject]; | ||
}, []), observable = _a[0], subject = _a[1]; | ||
useIsomorphicEffect(function () { | ||
if (isInitial.current) { | ||
isInitial.current = false; | ||
} | ||
else { | ||
// emit only on update | ||
subjectRef.current.next(value); | ||
} | ||
subject.next(value); | ||
}, [value]); | ||
useIsomorphicEffect(function () { | ||
useEffect(function () { | ||
return function () { | ||
return subjectRef.current.complete(); | ||
subject.complete(); | ||
}; | ||
}, []); | ||
return observableRef.current; | ||
return observable; | ||
} |
@@ -1,40 +0,35 @@ | ||
import { useMemo, useRef, useState } from 'react'; | ||
import { useIsomorphicEffect } from './useIsomorphicEffect'; | ||
import { defer, merge, of, pipe } from 'rxjs'; | ||
import { useMemo } from 'react'; | ||
import { useAsObservable } from './useAsObservable'; | ||
import { distinctUntilChanged, switchMap } from 'rxjs/operators'; | ||
import { useSyncExternalStore } from 'use-sync-external-store/shim'; | ||
function getValue(value) { | ||
return typeof value === 'function' ? value() : value; | ||
} | ||
export function useObservable(observable, initialValue) { | ||
var subscription = useRef(); | ||
var isInitial = useRef(true); | ||
var _a = useState(function () { | ||
var isSync = true; | ||
var syncVal = getValue(initialValue); | ||
subscription.current = observable.subscribe(function (nextVal) { | ||
if (isSync) { | ||
syncVal = nextVal; | ||
} | ||
else { | ||
setState(nextVal); | ||
} | ||
}); | ||
isSync = false; | ||
return syncVal; | ||
}), value = _a[0], setState = _a[1]; | ||
useIsomorphicEffect(function () { | ||
// when the observable changes after initial (possibly sync render) | ||
if (!isInitial.current) { | ||
subscription.current = observable.subscribe(function (nextVal) { return setState(nextVal); }); | ||
} | ||
isInitial.current = false; | ||
return function () { | ||
if (subscription.current) { | ||
subscription.current.unsubscribe(); | ||
subscription.current = undefined; | ||
} | ||
function useObservableSubscription(observable) { | ||
var store = useMemo(function () { | ||
var currentValue; | ||
return { | ||
// Note: this works because the given observable always emits a value synchronously by concat-ing the given initialValue | ||
getCurrentValue: function () { return currentValue; }, | ||
subscribe: function (callback) { | ||
var subscription = observable.subscribe(function (value) { | ||
currentValue = value; | ||
callback(value); | ||
}); | ||
return function () { | ||
subscription.unsubscribe(); | ||
}; | ||
}, | ||
}; | ||
}, [observable]); | ||
return value; | ||
return useSyncExternalStore(store.subscribe, store.getCurrentValue); | ||
} | ||
export function useObservable(observable, initialValue) { | ||
return useObservableSubscription(useAsObservable(observable, pipe(distinctUntilChanged(), switchMap(function (observable) { | ||
return merge(defer(function () { return of(getValue(initialValue)); }), observable); | ||
})))); | ||
} | ||
export function useMemoObservable(observableOrFactory, deps, initialValue) { | ||
return useObservable(useMemo(function () { return getValue(observableOrFactory); }, deps), initialValue); | ||
} |
{ | ||
"name": "react-rx", | ||
"version": "1.0.1", | ||
"version": "2.0.0", | ||
"description": "React + RxJS = <3", | ||
@@ -28,3 +28,3 @@ "main": "dist/cjs/index.js", | ||
"peerDependencies": { | ||
"react": "^16.8 || ^17", | ||
"react": "^16.8 || ^17 || ^18", | ||
"rxjs": "^6.5 || ^7" | ||
@@ -39,2 +39,3 @@ }, | ||
"@types/react-dom": "^17.0.1", | ||
"@types/use-sync-external-store": "^0.0.3", | ||
"@typescript-eslint/eslint-plugin": "^4.15.2", | ||
@@ -53,2 +54,3 @@ "@typescript-eslint/parser": "^4.15.2", | ||
"react-test-renderer": "^17.0.1", | ||
"use-sync-external-store": "^1.2.0", | ||
"rimraf": "^3.0.2", | ||
@@ -55,0 +57,0 @@ "rxjs": "^6.5.5", |
@@ -1,3 +0,3 @@ | ||
import {BehaviorSubject, Observable, Subject} from 'rxjs' | ||
import {useRef} from 'react' | ||
import {BehaviorSubject, Observable} from 'rxjs' | ||
import {useEffect, useMemo} from 'react' | ||
import {useIsomorphicEffect} from './useIsomorphicEffect' | ||
@@ -20,25 +20,20 @@ | ||
): Observable<T | K> { | ||
const isInitial = useRef(true) | ||
const subjectRef = useRef<Subject<T>>(new BehaviorSubject(value)) | ||
const observableRef = useRef<Observable<T | K>>() | ||
if (!observableRef.current) { | ||
const observable = subjectRef.current.asObservable() | ||
observableRef.current = operator ? observable.pipe(operator) : observable | ||
} | ||
const [observable, subject] = useMemo(() => { | ||
const subject = new BehaviorSubject(value) | ||
const observable = subject.asObservable() | ||
return [operator ? observable.pipe(operator) : observable, subject] | ||
}, []) | ||
useIsomorphicEffect(() => { | ||
if (isInitial.current) { | ||
isInitial.current = false | ||
} else { | ||
// emit only on update | ||
subjectRef.current.next(value) | ||
} | ||
subject.next(value) | ||
}, [value]) | ||
useIsomorphicEffect(() => { | ||
useEffect(() => { | ||
return () => { | ||
return subjectRef.current.complete() | ||
subject.complete() | ||
} | ||
}, []) | ||
return observableRef.current | ||
return observable | ||
} |
@@ -1,4 +0,6 @@ | ||
import {Observable, Subscription} from 'rxjs' | ||
import {DependencyList, useMemo, useRef, useState} from 'react' | ||
import {useIsomorphicEffect} from './useIsomorphicEffect' | ||
import {defer, merge, Observable, of, pipe} from 'rxjs' | ||
import {DependencyList, useMemo} from 'react' | ||
import {useAsObservable} from './useAsObservable' | ||
import {distinctUntilChanged, switchMap} from 'rxjs/operators' | ||
import {useSyncExternalStore} from 'use-sync-external-store/shim' | ||
@@ -9,2 +11,22 @@ function getValue<T>(value: T): T extends () => infer U ? U : T { | ||
function useObservableSubscription<T>(observable: Observable<T>): T { | ||
const store = useMemo(() => { | ||
let currentValue: T | ||
return { | ||
// Note: this works because the given observable always emits a value synchronously by concat-ing the given initialValue | ||
getCurrentValue: () => currentValue, | ||
subscribe: (callback: (value: T) => void) => { | ||
const subscription = observable.subscribe(value => { | ||
currentValue = value | ||
callback(value) | ||
}) | ||
return () => { | ||
subscription.unsubscribe() | ||
} | ||
}, | ||
} | ||
}, [observable]) | ||
return useSyncExternalStore(store.subscribe, store.getCurrentValue) | ||
} | ||
export function useObservable<T>(observable: Observable<T>): T | undefined | ||
@@ -14,33 +36,16 @@ export function useObservable<T>(observable: Observable<T>, initialValue: T): T | ||
export function useObservable<T>(observable: Observable<T>, initialValue?: T | (() => T)) { | ||
const subscription = useRef<Subscription>() | ||
const isInitial = useRef(true) | ||
const [value, setState] = useState(() => { | ||
let isSync = true | ||
let syncVal = getValue(initialValue) | ||
subscription.current = observable.subscribe(nextVal => { | ||
if (isSync) { | ||
syncVal = nextVal | ||
} else { | ||
setState(nextVal) | ||
} | ||
}) | ||
isSync = false | ||
return syncVal | ||
}) | ||
useIsomorphicEffect(() => { | ||
// when the observable changes after initial (possibly sync render) | ||
if (!isInitial.current) { | ||
subscription.current = observable.subscribe(nextVal => setState(nextVal)) | ||
} | ||
isInitial.current = false | ||
return () => { | ||
if (subscription.current) { | ||
subscription.current.unsubscribe() | ||
subscription.current = undefined | ||
} | ||
} | ||
}, [observable]) | ||
return value | ||
return useObservableSubscription( | ||
useAsObservable( | ||
observable, | ||
pipe( | ||
distinctUntilChanged(), | ||
switchMap(observable => | ||
merge( | ||
defer(() => of(getValue(initialValue))), | ||
observable, | ||
), | ||
), | ||
), | ||
), | ||
) | ||
} | ||
@@ -47,0 +52,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
0
75963
25
1206