react-rx 3.0.0-3 → 3.0.0-5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +17 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +52 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +54 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +31 -25
- package/src/__tests__/strictmode.test.ts +1 -1
- package/src/useObservable.ts +4 -2
- package/src/useObservableEvent.ts +28 -18
- package/dist/cjs/__tests__/strictmode.test.d.ts +0 -1
- package/dist/cjs/__tests__/strictmode.test.js +0 -96
- package/dist/cjs/__tests__/useObservable.test.d.ts +0 -1
- package/dist/cjs/__tests__/useObservable.test.js +0 -116
- package/dist/cjs/index.d.ts +0 -2
- package/dist/cjs/index.js +0 -18
- package/dist/cjs/useObservable.d.ts +0 -4
- package/dist/cjs/useObservable.js +0 -48
- package/dist/cjs/useObservableEvent.d.ts +0 -3
- package/dist/cjs/useObservableEvent.js +0 -23
- package/dist/es2015/__tests__/strictmode.test.d.ts +0 -1
- package/dist/es2015/__tests__/strictmode.test.js +0 -58
- package/dist/es2015/__tests__/useObservable.test.d.ts +0 -1
- package/dist/es2015/__tests__/useObservable.test.js +0 -110
- package/dist/es2015/index.d.ts +0 -2
- package/dist/es2015/index.js +0 -2
- package/dist/es2015/useObservable.d.ts +0 -4
- package/dist/es2015/useObservable.js +0 -44
- package/dist/es2015/useObservableEvent.d.ts +0 -3
- package/dist/es2015/useObservableEvent.js +0 -18
- package/dist/esm/__tests__/strictmode.test.d.ts +0 -1
- package/dist/esm/__tests__/strictmode.test.js +0 -94
- package/dist/esm/__tests__/useObservable.test.d.ts +0 -1
- package/dist/esm/__tests__/useObservable.test.js +0 -114
- package/dist/esm/index.d.ts +0 -2
- package/dist/esm/index.js +0 -2
- package/dist/esm/useObservable.d.ts +0 -4
- package/dist/esm/useObservable.js +0 -44
- package/dist/esm/useObservableEvent.d.ts +0 -3
- package/dist/esm/useObservableEvent.js +0 -19
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import {Observable} from 'rxjs'
|
|
2
|
+
|
|
3
|
+
/** @internal */
|
|
4
|
+
export declare type UnboxObservable<T> = T extends Observable<infer U> ? U : never
|
|
5
|
+
|
|
6
|
+
/** @public */
|
|
7
|
+
export declare function useObservable<ObservableType extends Observable<any>>(
|
|
8
|
+
observable: ObservableType,
|
|
9
|
+
initialValue?: UnboxObservable<ObservableType> | (() => UnboxObservable<ObservableType>),
|
|
10
|
+
): UnboxObservable<ObservableType>
|
|
11
|
+
|
|
12
|
+
/** @public */
|
|
13
|
+
export declare function useObservableEvent<T, U>(
|
|
14
|
+
fn: (arg: Observable<T>) => Observable<U>,
|
|
15
|
+
): (arg: T) => void
|
|
16
|
+
|
|
17
|
+
export {}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import {Observable} from 'rxjs'
|
|
2
|
+
|
|
3
|
+
/** @internal */
|
|
4
|
+
export declare type UnboxObservable<T> = T extends Observable<infer U> ? U : never
|
|
5
|
+
|
|
6
|
+
/** @public */
|
|
7
|
+
export declare function useObservable<ObservableType extends Observable<any>>(
|
|
8
|
+
observable: ObservableType,
|
|
9
|
+
initialValue?: UnboxObservable<ObservableType> | (() => UnboxObservable<ObservableType>),
|
|
10
|
+
): UnboxObservable<ObservableType>
|
|
11
|
+
|
|
12
|
+
/** @public */
|
|
13
|
+
export declare function useObservableEvent<T, U>(
|
|
14
|
+
fn: (arg: Observable<T>) => Observable<U>,
|
|
15
|
+
): (arg: T) => void
|
|
16
|
+
|
|
17
|
+
export {}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: !0 });
|
|
3
|
+
var react = require("react"), operators = require("rxjs/operators"), observableCallback = require("observable-callback");
|
|
4
|
+
function getValue(value) {
|
|
5
|
+
return typeof value == "function" ? value() : value;
|
|
6
|
+
}
|
|
7
|
+
const cache = /* @__PURE__ */ new WeakMap();
|
|
8
|
+
function useObservable(observable, initialValue) {
|
|
9
|
+
const initialValueRef = react.useRef(getValue(initialValue));
|
|
10
|
+
react.useEffect(() => {
|
|
11
|
+
initialValueRef.current = getValue(initialValue);
|
|
12
|
+
}, [initialValue]);
|
|
13
|
+
const store = react.useMemo(() => {
|
|
14
|
+
if (!cache.has(observable)) {
|
|
15
|
+
const entry = {
|
|
16
|
+
snapshot: initialValueRef.current
|
|
17
|
+
};
|
|
18
|
+
entry.observable = observable.pipe(
|
|
19
|
+
operators.shareReplay({ refCount: !0, bufferSize: 1 }),
|
|
20
|
+
operators.tap((value) => entry.snapshot = value)
|
|
21
|
+
), entry.subscription = entry.observable.subscribe(), cache.set(observable, entry);
|
|
22
|
+
}
|
|
23
|
+
const instance = cache.get(observable);
|
|
24
|
+
return instance.subscription.closed && (instance.subscription = instance.observable.subscribe()), {
|
|
25
|
+
subscribe: (onStoreChange) => {
|
|
26
|
+
const subscription = instance.observable.subscribe(onStoreChange);
|
|
27
|
+
return instance.subscription.unsubscribe(), () => subscription.unsubscribe();
|
|
28
|
+
},
|
|
29
|
+
getSnapshot: () => instance.snapshot
|
|
30
|
+
};
|
|
31
|
+
}, [observable]);
|
|
32
|
+
return react.useSyncExternalStore(store.subscribe, store.getSnapshot);
|
|
33
|
+
}
|
|
34
|
+
function useObservableEvent(fn) {
|
|
35
|
+
const [[calls$, call]] = react.useState(() => observableCallback.observableCallback()), callback = useEffectEvent(fn);
|
|
36
|
+
return react.useEffect(() => {
|
|
37
|
+
const subscription = calls$.pipe(callback).subscribe();
|
|
38
|
+
return () => subscription.unsubscribe();
|
|
39
|
+
}, [callback, calls$]), call;
|
|
40
|
+
}
|
|
41
|
+
function useEffectEvent(fn) {
|
|
42
|
+
const ref = react.useRef(null);
|
|
43
|
+
return react.useInsertionEffect(() => {
|
|
44
|
+
ref.current = fn;
|
|
45
|
+
}, [fn]), react.useCallback((...args) => {
|
|
46
|
+
const f = ref.current;
|
|
47
|
+
return f(...args);
|
|
48
|
+
}, []);
|
|
49
|
+
}
|
|
50
|
+
exports.useObservable = useObservable;
|
|
51
|
+
exports.useObservableEvent = useObservableEvent;
|
|
52
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/useObservable.ts","../src/useObservableEvent.ts"],"sourcesContent":["import {useEffect, useMemo, useRef, useSyncExternalStore} from 'react'\nimport type {Observable, Subscription} from 'rxjs'\nimport {shareReplay, tap} from 'rxjs/operators'\n\nfunction getValue<T>(value: T): T extends () => infer U ? U : T {\n return typeof value === 'function' ? value() : value\n}\ninterface CacheRecord<T> {\n subscription: Subscription\n observable: Observable<T>\n snapshot: T\n}\n\nconst cache = new WeakMap<Observable<any>, CacheRecord<any>>()\n\n/** @public */\nexport function useObservable<ObservableType extends Observable<any>>(\n observable: ObservableType,\n initialValue?: UnboxObservable<ObservableType> | (() => UnboxObservable<ObservableType>),\n): UnboxObservable<ObservableType> {\n /**\n * Store the initialValue in a ref, as we don't want a changed `initialValue` to trigger a re-subscription.\n * But we also don't want the initialValue to be stale if the observable changes.\n */\n const initialValueRef = useRef(getValue(initialValue) as UnboxObservable<ObservableType>)\n\n /**\n * Ensures that the initialValue is always up-to-date in case the observable changes.\n */\n useEffect(() => {\n initialValueRef.current = getValue(initialValue) as UnboxObservable<ObservableType>\n }, [initialValue])\n\n const store = useMemo(() => {\n if (!cache.has(observable)) {\n const entry: Partial<CacheRecord<UnboxObservable<ObservableType>>> = {\n snapshot: initialValueRef.current,\n }\n entry.observable = observable.pipe(\n shareReplay({refCount: true, bufferSize: 1}),\n tap((value) => (entry.snapshot = value)),\n )\n\n // Eagerly subscribe to sync set `entry.currentValue` to what the observable returns, and keep the observable alive until the component unmounts.\n entry.subscription = entry.observable.subscribe()\n\n cache.set(observable, entry as CacheRecord<UnboxObservable<ObservableType>>)\n }\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const instance = cache.get(observable)!\n if (instance.subscription.closed) {\n instance.subscription = instance.observable.subscribe()\n }\n\n return {\n subscribe: (onStoreChange: () => void) => {\n const subscription = instance.observable.subscribe(onStoreChange)\n instance.subscription.unsubscribe()\n return () => subscription.unsubscribe()\n },\n getSnapshot: () => instance.snapshot,\n }\n }, [observable])\n\n return useSyncExternalStore<UnboxObservable<ObservableType>>(store.subscribe, store.getSnapshot)\n}\n\n/** @internal */\nexport type UnboxObservable<T> = T extends Observable<infer U> ? U : never\n","import {observableCallback} from 'observable-callback'\nimport {useCallback, useEffect, useInsertionEffect, useRef, useState} from 'react'\nimport {type Observable} from 'rxjs'\n\n/** @public */\nexport function useObservableEvent<T, U>(\n fn: (arg: Observable<T>) => Observable<U>,\n): (arg: T) => void {\n const [[calls$, call]] = useState(() => observableCallback<T>())\n\n const callback = useEffectEvent(fn)\n\n useEffect(() => {\n const subscription = calls$.pipe(callback).subscribe()\n return () => subscription.unsubscribe()\n }, [callback, calls$])\n\n return call\n}\n\n/**\n * This is a ponyfill of the upcoming `useEffectEvent` hook that'll arrive in React 19\n */\nfunction useEffectEvent<\n const T extends (\n ...args: // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any[]\n ) => void,\n>(fn: T): T {\n const ref = useRef<T | null>(null)\n useInsertionEffect(() => {\n ref.current = fn\n }, [fn])\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return useCallback((...args: any[]) => {\n const f = ref.current!\n return f(...args)\n }, []) as T\n}\n"],"names":["useRef","useEffect","useMemo","shareReplay","tap","useSyncExternalStore","useState","observableCallback","useInsertionEffect","useCallback"],"mappings":";;;AAIA,SAAS,SAAY,OAA2C;AAC9D,SAAO,OAAO,SAAU,aAAa,MAAA,IAAU;AACjD;AAOA,MAAM,4BAAY;AAGF,SAAA,cACd,YACA,cACiC;AAKjC,QAAM,kBAAkBA,MAAA,OAAO,SAAS,YAAY,CAAoC;AAKxFC,QAAAA,UAAU,MAAM;AACE,oBAAA,UAAU,SAAS,YAAY;AAAA,EAAA,GAC9C,CAAC,YAAY,CAAC;AAEX,QAAA,QAAQC,MAAAA,QAAQ,MAAM;AAC1B,QAAI,CAAC,MAAM,IAAI,UAAU,GAAG;AAC1B,YAAM,QAA+D;AAAA,QACnE,UAAU,gBAAgB;AAAA,MAAA;AAE5B,YAAM,aAAa,WAAW;AAAA,QAC5BC,sBAAY,EAAC,UAAU,IAAM,YAAY,GAAE;AAAA,QAC3CC,UAAAA,IAAI,CAAC,UAAW,MAAM,WAAW,KAAM;AAAA,MACzC,GAGA,MAAM,eAAe,MAAM,WAAW,aAEtC,MAAM,IAAI,YAAY,KAAqD;AAAA,IAC7E;AAEM,UAAA,WAAW,MAAM,IAAI,UAAU;AACjC,WAAA,SAAS,aAAa,WACxB,SAAS,eAAe,SAAS,WAAW,cAGvC;AAAA,MACL,WAAW,CAAC,kBAA8B;AACxC,cAAM,eAAe,SAAS,WAAW,UAAU,aAAa;AAChE,eAAA,SAAS,aAAa,YACf,GAAA,MAAM,aAAa;MAC5B;AAAA,MACA,aAAa,MAAM,SAAS;AAAA,IAAA;AAAA,EAC9B,GACC,CAAC,UAAU,CAAC;AAEf,SAAOC,MAAsD,qBAAA,MAAM,WAAW,MAAM,WAAW;AACjG;AC5DO,SAAS,mBACd,IACkB;AAClB,QAAM,CAAC,CAAC,QAAQ,IAAI,CAAC,IAAIC,MAAS,SAAA,MAAMC,mBAAsB,mBAAA,CAAC,GAEzD,WAAW,eAAe,EAAE;AAElC,SAAAN,MAAA,UAAU,MAAM;AACd,UAAM,eAAe,OAAO,KAAK,QAAQ,EAAE,UAAU;AAC9C,WAAA,MAAM,aAAa;EACzB,GAAA,CAAC,UAAU,MAAM,CAAC,GAEd;AACT;AAKA,SAAS,eAKP,IAAU;AACJ,QAAA,MAAMD,aAAiB,IAAI;AACjC,SAAAQ,MAAA,mBAAmB,MAAM;AACvB,QAAI,UAAU;AAAA,KACb,CAAC,EAAE,CAAC,GAEAC,MAAAA,YAAY,IAAI,SAAgB;AACrC,UAAM,IAAI,IAAI;AACP,WAAA,EAAE,GAAG,IAAI;AAAA,EAClB,GAAG,CAAE,CAAA;AACP;;;"}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { useRef, useEffect, useMemo, useSyncExternalStore, useState, useInsertionEffect, useCallback } from "react";
|
|
2
|
+
import { shareReplay, tap } from "rxjs/operators";
|
|
3
|
+
import { observableCallback } from "observable-callback";
|
|
4
|
+
function getValue(value) {
|
|
5
|
+
return typeof value == "function" ? value() : value;
|
|
6
|
+
}
|
|
7
|
+
const cache = /* @__PURE__ */ new WeakMap();
|
|
8
|
+
function useObservable(observable, initialValue) {
|
|
9
|
+
const initialValueRef = useRef(getValue(initialValue));
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
initialValueRef.current = getValue(initialValue);
|
|
12
|
+
}, [initialValue]);
|
|
13
|
+
const store = useMemo(() => {
|
|
14
|
+
if (!cache.has(observable)) {
|
|
15
|
+
const entry = {
|
|
16
|
+
snapshot: initialValueRef.current
|
|
17
|
+
};
|
|
18
|
+
entry.observable = observable.pipe(
|
|
19
|
+
shareReplay({ refCount: !0, bufferSize: 1 }),
|
|
20
|
+
tap((value) => entry.snapshot = value)
|
|
21
|
+
), entry.subscription = entry.observable.subscribe(), cache.set(observable, entry);
|
|
22
|
+
}
|
|
23
|
+
const instance = cache.get(observable);
|
|
24
|
+
return instance.subscription.closed && (instance.subscription = instance.observable.subscribe()), {
|
|
25
|
+
subscribe: (onStoreChange) => {
|
|
26
|
+
const subscription = instance.observable.subscribe(onStoreChange);
|
|
27
|
+
return instance.subscription.unsubscribe(), () => subscription.unsubscribe();
|
|
28
|
+
},
|
|
29
|
+
getSnapshot: () => instance.snapshot
|
|
30
|
+
};
|
|
31
|
+
}, [observable]);
|
|
32
|
+
return useSyncExternalStore(store.subscribe, store.getSnapshot);
|
|
33
|
+
}
|
|
34
|
+
function useObservableEvent(fn) {
|
|
35
|
+
const [[calls$, call]] = useState(() => observableCallback()), callback = useEffectEvent(fn);
|
|
36
|
+
return useEffect(() => {
|
|
37
|
+
const subscription = calls$.pipe(callback).subscribe();
|
|
38
|
+
return () => subscription.unsubscribe();
|
|
39
|
+
}, [callback, calls$]), call;
|
|
40
|
+
}
|
|
41
|
+
function useEffectEvent(fn) {
|
|
42
|
+
const ref = useRef(null);
|
|
43
|
+
return useInsertionEffect(() => {
|
|
44
|
+
ref.current = fn;
|
|
45
|
+
}, [fn]), useCallback((...args) => {
|
|
46
|
+
const f = ref.current;
|
|
47
|
+
return f(...args);
|
|
48
|
+
}, []);
|
|
49
|
+
}
|
|
50
|
+
export {
|
|
51
|
+
useObservable,
|
|
52
|
+
useObservableEvent
|
|
53
|
+
};
|
|
54
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../src/useObservable.ts","../src/useObservableEvent.ts"],"sourcesContent":["import {useEffect, useMemo, useRef, useSyncExternalStore} from 'react'\nimport type {Observable, Subscription} from 'rxjs'\nimport {shareReplay, tap} from 'rxjs/operators'\n\nfunction getValue<T>(value: T): T extends () => infer U ? U : T {\n return typeof value === 'function' ? value() : value\n}\ninterface CacheRecord<T> {\n subscription: Subscription\n observable: Observable<T>\n snapshot: T\n}\n\nconst cache = new WeakMap<Observable<any>, CacheRecord<any>>()\n\n/** @public */\nexport function useObservable<ObservableType extends Observable<any>>(\n observable: ObservableType,\n initialValue?: UnboxObservable<ObservableType> | (() => UnboxObservable<ObservableType>),\n): UnboxObservable<ObservableType> {\n /**\n * Store the initialValue in a ref, as we don't want a changed `initialValue` to trigger a re-subscription.\n * But we also don't want the initialValue to be stale if the observable changes.\n */\n const initialValueRef = useRef(getValue(initialValue) as UnboxObservable<ObservableType>)\n\n /**\n * Ensures that the initialValue is always up-to-date in case the observable changes.\n */\n useEffect(() => {\n initialValueRef.current = getValue(initialValue) as UnboxObservable<ObservableType>\n }, [initialValue])\n\n const store = useMemo(() => {\n if (!cache.has(observable)) {\n const entry: Partial<CacheRecord<UnboxObservable<ObservableType>>> = {\n snapshot: initialValueRef.current,\n }\n entry.observable = observable.pipe(\n shareReplay({refCount: true, bufferSize: 1}),\n tap((value) => (entry.snapshot = value)),\n )\n\n // Eagerly subscribe to sync set `entry.currentValue` to what the observable returns, and keep the observable alive until the component unmounts.\n entry.subscription = entry.observable.subscribe()\n\n cache.set(observable, entry as CacheRecord<UnboxObservable<ObservableType>>)\n }\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const instance = cache.get(observable)!\n if (instance.subscription.closed) {\n instance.subscription = instance.observable.subscribe()\n }\n\n return {\n subscribe: (onStoreChange: () => void) => {\n const subscription = instance.observable.subscribe(onStoreChange)\n instance.subscription.unsubscribe()\n return () => subscription.unsubscribe()\n },\n getSnapshot: () => instance.snapshot,\n }\n }, [observable])\n\n return useSyncExternalStore<UnboxObservable<ObservableType>>(store.subscribe, store.getSnapshot)\n}\n\n/** @internal */\nexport type UnboxObservable<T> = T extends Observable<infer U> ? U : never\n","import {observableCallback} from 'observable-callback'\nimport {useCallback, useEffect, useInsertionEffect, useRef, useState} from 'react'\nimport {type Observable} from 'rxjs'\n\n/** @public */\nexport function useObservableEvent<T, U>(\n fn: (arg: Observable<T>) => Observable<U>,\n): (arg: T) => void {\n const [[calls$, call]] = useState(() => observableCallback<T>())\n\n const callback = useEffectEvent(fn)\n\n useEffect(() => {\n const subscription = calls$.pipe(callback).subscribe()\n return () => subscription.unsubscribe()\n }, [callback, calls$])\n\n return call\n}\n\n/**\n * This is a ponyfill of the upcoming `useEffectEvent` hook that'll arrive in React 19\n */\nfunction useEffectEvent<\n const T extends (\n ...args: // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any[]\n ) => void,\n>(fn: T): T {\n const ref = useRef<T | null>(null)\n useInsertionEffect(() => {\n ref.current = fn\n }, [fn])\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return useCallback((...args: any[]) => {\n const f = ref.current!\n return f(...args)\n }, []) as T\n}\n"],"names":[],"mappings":";;;AAIA,SAAS,SAAY,OAA2C;AAC9D,SAAO,OAAO,SAAU,aAAa,MAAA,IAAU;AACjD;AAOA,MAAM,4BAAY;AAGF,SAAA,cACd,YACA,cACiC;AAKjC,QAAM,kBAAkB,OAAO,SAAS,YAAY,CAAoC;AAKxF,YAAU,MAAM;AACE,oBAAA,UAAU,SAAS,YAAY;AAAA,EAAA,GAC9C,CAAC,YAAY,CAAC;AAEX,QAAA,QAAQ,QAAQ,MAAM;AAC1B,QAAI,CAAC,MAAM,IAAI,UAAU,GAAG;AAC1B,YAAM,QAA+D;AAAA,QACnE,UAAU,gBAAgB;AAAA,MAAA;AAE5B,YAAM,aAAa,WAAW;AAAA,QAC5B,YAAY,EAAC,UAAU,IAAM,YAAY,GAAE;AAAA,QAC3C,IAAI,CAAC,UAAW,MAAM,WAAW,KAAM;AAAA,MACzC,GAGA,MAAM,eAAe,MAAM,WAAW,aAEtC,MAAM,IAAI,YAAY,KAAqD;AAAA,IAC7E;AAEM,UAAA,WAAW,MAAM,IAAI,UAAU;AACjC,WAAA,SAAS,aAAa,WACxB,SAAS,eAAe,SAAS,WAAW,cAGvC;AAAA,MACL,WAAW,CAAC,kBAA8B;AACxC,cAAM,eAAe,SAAS,WAAW,UAAU,aAAa;AAChE,eAAA,SAAS,aAAa,YACf,GAAA,MAAM,aAAa;MAC5B;AAAA,MACA,aAAa,MAAM,SAAS;AAAA,IAAA;AAAA,EAC9B,GACC,CAAC,UAAU,CAAC;AAEf,SAAO,qBAAsD,MAAM,WAAW,MAAM,WAAW;AACjG;AC5DO,SAAS,mBACd,IACkB;AAClB,QAAM,CAAC,CAAC,QAAQ,IAAI,CAAC,IAAI,SAAS,MAAM,mBAAsB,CAAC,GAEzD,WAAW,eAAe,EAAE;AAElC,SAAA,UAAU,MAAM;AACd,UAAM,eAAe,OAAO,KAAK,QAAQ,EAAE,UAAU;AAC9C,WAAA,MAAM,aAAa;EACzB,GAAA,CAAC,UAAU,MAAM,CAAC,GAEd;AACT;AAKA,SAAS,eAKP,IAAU;AACJ,QAAA,MAAM,OAAiB,IAAI;AACjC,SAAA,mBAAmB,MAAM;AACvB,QAAI,UAAU;AAAA,KACb,CAAC,EAAE,CAAC,GAEA,YAAY,IAAI,SAAgB;AACrC,UAAM,IAAI,IAAI;AACP,WAAA,EAAE,GAAG,IAAI;AAAA,EAClB,GAAG,CAAE,CAAA;AACP;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-rx",
|
|
3
|
-
"version": "3.0.0-
|
|
3
|
+
"version": "3.0.0-5",
|
|
4
4
|
"description": "React + RxJS = <3",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"action",
|
|
@@ -46,9 +46,18 @@
|
|
|
46
46
|
"Cody Olsen <stipsan@gmail.com> (https://github.com/stipsan)"
|
|
47
47
|
],
|
|
48
48
|
"sideEffects": false,
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
|
|
49
|
+
"type": "commonjs",
|
|
50
|
+
"exports": {
|
|
51
|
+
".": {
|
|
52
|
+
"source": "./src/index.ts",
|
|
53
|
+
"import": "./dist/index.mjs",
|
|
54
|
+
"default": "./dist/index.js"
|
|
55
|
+
},
|
|
56
|
+
"./package.json": "./package.json"
|
|
57
|
+
},
|
|
58
|
+
"main": "./dist/index.js",
|
|
59
|
+
"module": "./dist/index.mjs",
|
|
60
|
+
"types": "./dist/index.d.ts",
|
|
52
61
|
"files": [
|
|
53
62
|
"dist",
|
|
54
63
|
"src"
|
|
@@ -58,21 +67,21 @@
|
|
|
58
67
|
"."
|
|
59
68
|
],
|
|
60
69
|
"scripts": {
|
|
61
|
-
"build": "
|
|
62
|
-
"build:es2015": "tsc --module es2015 --target es2015 --outDir dist/es2015",
|
|
63
|
-
"build:esm": "tsc --module es2015 --target es5 --outDir dist/esm",
|
|
64
|
-
"build:cjs": "tsc --module commonjs --target es5 --outDir dist/cjs",
|
|
65
|
-
"clean": "rimraf dist",
|
|
70
|
+
"build": "pkg build --strict --clean --check",
|
|
66
71
|
"dev": "cd website && npm run dev",
|
|
67
|
-
"prepublishOnly": "npm run
|
|
68
|
-
"watch": "run
|
|
72
|
+
"prepublishOnly": "npm run build",
|
|
73
|
+
"watch": "npm run build -- --watch",
|
|
69
74
|
"test": "jest",
|
|
70
75
|
"lint": "eslint --cache ."
|
|
71
76
|
},
|
|
77
|
+
"browserslist": "extends @sanity/browserslist-config",
|
|
78
|
+
"prettier": "@sanity/prettier-config",
|
|
72
79
|
"dependencies": {
|
|
73
80
|
"observable-callback": "^1.0.3"
|
|
74
81
|
},
|
|
75
82
|
"devDependencies": {
|
|
83
|
+
"@sanity/pkg-utils": "^6.9.2",
|
|
84
|
+
"@sanity/prettier-config": "^1.0.2",
|
|
76
85
|
"@sanity/semantic-release-preset": "^2.0.5",
|
|
77
86
|
"@testing-library/dom": "^10.1.0",
|
|
78
87
|
"@testing-library/react": "^16.0.0",
|
|
@@ -80,32 +89,29 @@
|
|
|
80
89
|
"@types/node": "^18.17.5",
|
|
81
90
|
"@types/react": "^18.3.3",
|
|
82
91
|
"@types/react-dom": "^18.3.0",
|
|
83
|
-
"@typescript-eslint/eslint-plugin": "7.12.0",
|
|
84
|
-
"@typescript-eslint/parser": "7.12.0",
|
|
85
|
-
"eslint": "8.57.0",
|
|
86
|
-
"eslint-config-prettier": "9.1.0",
|
|
87
|
-
"eslint-plugin-prettier": "5.1.3",
|
|
88
|
-
"eslint-plugin-react": "7.34.2",
|
|
89
|
-
"eslint-plugin-react-compiler": "
|
|
90
|
-
"eslint-plugin-react-hooks": "4.6.2",
|
|
92
|
+
"@typescript-eslint/eslint-plugin": "^7.12.0",
|
|
93
|
+
"@typescript-eslint/parser": "^7.12.0",
|
|
94
|
+
"eslint": "^8.57.0",
|
|
95
|
+
"eslint-config-prettier": "^9.1.0",
|
|
96
|
+
"eslint-plugin-prettier": "^5.1.3",
|
|
97
|
+
"eslint-plugin-react": "^7.34.2",
|
|
98
|
+
"eslint-plugin-react-compiler": "0.0.0-experimental-51a85ea-20240601",
|
|
99
|
+
"eslint-plugin-react-hooks": "^4.6.2",
|
|
91
100
|
"eslint-plugin-simple-import-sort": "^12.1.0",
|
|
92
101
|
"jest": "^29.6.2",
|
|
93
102
|
"jest-environment-jsdom": "^29.6.2",
|
|
94
103
|
"jsdom": "^20.0.3",
|
|
95
104
|
"npm-run-all": "^4.1.5",
|
|
96
|
-
"prettier": "^
|
|
97
|
-
"prettier-plugin-packagejson": "^2.4.5",
|
|
105
|
+
"prettier": "^3.3.1",
|
|
98
106
|
"react": "^18.3.1",
|
|
99
107
|
"react-dom": "^18.3.1",
|
|
100
108
|
"react-test-renderer": "^18.3.1",
|
|
101
|
-
"rimraf": "^3.0.2",
|
|
102
109
|
"rxjs": "^7.8.1",
|
|
103
110
|
"ts-jest": "^29.1.1",
|
|
104
|
-
"typescript": "4.
|
|
111
|
+
"typescript": "5.4.5"
|
|
105
112
|
},
|
|
106
113
|
"peerDependencies": {
|
|
107
114
|
"react": "^18.3 || >=19.0.0-rc",
|
|
108
115
|
"rxjs": "^7"
|
|
109
|
-
}
|
|
110
|
-
"es2015": "dist/es2015/index.js"
|
|
116
|
+
}
|
|
111
117
|
}
|
|
@@ -4,7 +4,7 @@ import {BehaviorSubject, Observable} from 'rxjs'
|
|
|
4
4
|
|
|
5
5
|
import {useObservable} from '../useObservable'
|
|
6
6
|
|
|
7
|
-
const wait = (ms: number) => new Promise(resolve => setTimeout(resolve, ms))
|
|
7
|
+
const wait = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms))
|
|
8
8
|
|
|
9
9
|
// NOTE: Jest runs NODE_ENV=test by default, which enables development flags for React
|
|
10
10
|
|
package/src/useObservable.ts
CHANGED
|
@@ -13,6 +13,7 @@ interface CacheRecord<T> {
|
|
|
13
13
|
|
|
14
14
|
const cache = new WeakMap<Observable<any>, CacheRecord<any>>()
|
|
15
15
|
|
|
16
|
+
/** @public */
|
|
16
17
|
export function useObservable<ObservableType extends Observable<any>>(
|
|
17
18
|
observable: ObservableType,
|
|
18
19
|
initialValue?: UnboxObservable<ObservableType> | (() => UnboxObservable<ObservableType>),
|
|
@@ -37,7 +38,7 @@ export function useObservable<ObservableType extends Observable<any>>(
|
|
|
37
38
|
}
|
|
38
39
|
entry.observable = observable.pipe(
|
|
39
40
|
shareReplay({refCount: true, bufferSize: 1}),
|
|
40
|
-
tap(value => (entry.snapshot = value)),
|
|
41
|
+
tap((value) => (entry.snapshot = value)),
|
|
41
42
|
)
|
|
42
43
|
|
|
43
44
|
// Eagerly subscribe to sync set `entry.currentValue` to what the observable returns, and keep the observable alive until the component unmounts.
|
|
@@ -64,4 +65,5 @@ export function useObservable<ObservableType extends Observable<any>>(
|
|
|
64
65
|
return useSyncExternalStore<UnboxObservable<ObservableType>>(store.subscribe, store.getSnapshot)
|
|
65
66
|
}
|
|
66
67
|
|
|
67
|
-
|
|
68
|
+
/** @internal */
|
|
69
|
+
export type UnboxObservable<T> = T extends Observable<infer U> ? U : never
|
|
@@ -1,29 +1,39 @@
|
|
|
1
1
|
import {observableCallback} from 'observable-callback'
|
|
2
|
-
import {
|
|
3
|
-
import {Observable} from 'rxjs'
|
|
2
|
+
import {useCallback, useEffect, useInsertionEffect, useRef, useState} from 'react'
|
|
3
|
+
import {type Observable} from 'rxjs'
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
export function useObservableCallback<T, U>(
|
|
5
|
+
/** @public */
|
|
6
|
+
export function useObservableEvent<T, U>(
|
|
8
7
|
fn: (arg: Observable<T>) => Observable<U>,
|
|
9
|
-
dependencies: DependencyList = EMPTY_DEPS,
|
|
10
8
|
): (arg: T) => void {
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
if (!callbackRef.current) {
|
|
14
|
-
callbackRef.current = observableCallback<T>()
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const [calls$, call] = callbackRef.current
|
|
9
|
+
const [[calls$, call]] = useState(() => observableCallback<T>())
|
|
18
10
|
|
|
19
|
-
const callback =
|
|
11
|
+
const callback = useEffectEvent(fn)
|
|
20
12
|
|
|
21
13
|
useEffect(() => {
|
|
22
14
|
const subscription = calls$.pipe(callback).subscribe()
|
|
23
|
-
return () =>
|
|
24
|
-
|
|
25
|
-
}
|
|
26
|
-
}, [calls$, call, callback])
|
|
15
|
+
return () => subscription.unsubscribe()
|
|
16
|
+
}, [callback, calls$])
|
|
27
17
|
|
|
28
18
|
return call
|
|
29
19
|
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* This is a ponyfill of the upcoming `useEffectEvent` hook that'll arrive in React 19
|
|
23
|
+
*/
|
|
24
|
+
function useEffectEvent<
|
|
25
|
+
const T extends (
|
|
26
|
+
...args: // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
27
|
+
any[]
|
|
28
|
+
) => void,
|
|
29
|
+
>(fn: T): T {
|
|
30
|
+
const ref = useRef<T | null>(null)
|
|
31
|
+
useInsertionEffect(() => {
|
|
32
|
+
ref.current = fn
|
|
33
|
+
}, [fn])
|
|
34
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
35
|
+
return useCallback((...args: any[]) => {
|
|
36
|
+
const f = ref.current!
|
|
37
|
+
return f(...args)
|
|
38
|
+
}, []) as T
|
|
39
|
+
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
13
|
-
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
-
function step(op) {
|
|
16
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
-
while (_) try {
|
|
18
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
19
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
-
switch (op[0]) {
|
|
21
|
-
case 0: case 1: t = op; break;
|
|
22
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
-
default:
|
|
26
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
-
if (t[2]) _.ops.pop();
|
|
31
|
-
_.trys.pop(); continue;
|
|
32
|
-
}
|
|
33
|
-
op = body.call(thisArg, _);
|
|
34
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
var react_1 = require("@testing-library/react");
|
|
40
|
-
var react_2 = require("react");
|
|
41
|
-
var rxjs_1 = require("rxjs");
|
|
42
|
-
var useObservable_1 = require("../useObservable");
|
|
43
|
-
var wait = function (ms) { return new Promise(function (resolve) { return setTimeout(resolve, ms); }); };
|
|
44
|
-
// NOTE: Jest runs NODE_ENV=test by default, which enables development flags for React
|
|
45
|
-
test('Strict mode should trigger double mount effects and re-renders', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
46
|
-
function ObservableComponent() {
|
|
47
|
-
(0, react_2.useEffect)(function () {
|
|
48
|
-
mountCount++;
|
|
49
|
-
}, []);
|
|
50
|
-
var observedValue = (0, useObservable_1.useObservable)(observable);
|
|
51
|
-
returnedValues.push(observedValue);
|
|
52
|
-
return (0, react_2.createElement)(react_2.Fragment, null, observedValue);
|
|
53
|
-
}
|
|
54
|
-
var subject, observable, returnedValues, mountCount;
|
|
55
|
-
return __generator(this, function (_a) {
|
|
56
|
-
switch (_a.label) {
|
|
57
|
-
case 0:
|
|
58
|
-
subject = new rxjs_1.BehaviorSubject(0);
|
|
59
|
-
observable = subject.asObservable();
|
|
60
|
-
returnedValues = [];
|
|
61
|
-
mountCount = 0;
|
|
62
|
-
(0, react_1.render)((0, react_2.createElement)(react_2.StrictMode, null, (0, react_2.createElement)(ObservableComponent)));
|
|
63
|
-
expect(mountCount).toEqual(2);
|
|
64
|
-
expect(returnedValues).toEqual([0, 0]);
|
|
65
|
-
return [4 /*yield*/, wait(10)];
|
|
66
|
-
case 1:
|
|
67
|
-
_a.sent();
|
|
68
|
-
(0, react_1.act)(function () { return subject.next(1); });
|
|
69
|
-
expect(returnedValues).toEqual([0, 0, 1, 1]);
|
|
70
|
-
(0, react_1.act)(function () { return subject.next(2); });
|
|
71
|
-
expect(returnedValues).toEqual([0, 0, 1, 1, 2, 2]);
|
|
72
|
-
expect(mountCount).toEqual(2);
|
|
73
|
-
return [2 /*return*/];
|
|
74
|
-
}
|
|
75
|
-
});
|
|
76
|
-
}); });
|
|
77
|
-
test('Strict mode should unsubscribe the source observable on unmount', function () {
|
|
78
|
-
var subscribed = [];
|
|
79
|
-
var unsubscribed = [];
|
|
80
|
-
var nextId = 0;
|
|
81
|
-
var observable = new rxjs_1.Observable(function () {
|
|
82
|
-
var id = nextId++;
|
|
83
|
-
subscribed.push(id);
|
|
84
|
-
return function () {
|
|
85
|
-
unsubscribed.push(id);
|
|
86
|
-
};
|
|
87
|
-
});
|
|
88
|
-
function ObservableComponent() {
|
|
89
|
-
(0, useObservable_1.useObservable)(observable);
|
|
90
|
-
return (0, react_2.createElement)(react_2.Fragment, null);
|
|
91
|
-
}
|
|
92
|
-
var rerender = (0, react_1.render)((0, react_2.createElement)(react_2.StrictMode, null, (0, react_2.createElement)(ObservableComponent))).rerender;
|
|
93
|
-
expect(subscribed).toEqual([0, 1]);
|
|
94
|
-
rerender((0, react_2.createElement)(react_2.StrictMode, null, (0, react_2.createElement)('div')));
|
|
95
|
-
expect(unsubscribed).toEqual([0, 1]);
|
|
96
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
var react_1 = require("@testing-library/react");
|
|
4
|
-
var react_2 = require("react");
|
|
5
|
-
var rxjs_1 = require("rxjs");
|
|
6
|
-
var operators_1 = require("rxjs/operators");
|
|
7
|
-
var useObservable_1 = require("../useObservable");
|
|
8
|
-
test('should subscribe immediately on component mount and unsubscribe on component unmount', function () {
|
|
9
|
-
var subscribed = false;
|
|
10
|
-
var observable = new rxjs_1.Observable(function () {
|
|
11
|
-
subscribed = true;
|
|
12
|
-
return function () {
|
|
13
|
-
subscribed = false;
|
|
14
|
-
};
|
|
15
|
-
});
|
|
16
|
-
expect(subscribed).toBe(false);
|
|
17
|
-
var unmount = (0, react_1.renderHook)(function () { return (0, useObservable_1.useObservable)(observable); }).unmount;
|
|
18
|
-
expect(subscribed).toBe(true);
|
|
19
|
-
unmount();
|
|
20
|
-
expect(subscribed).toBe(false);
|
|
21
|
-
});
|
|
22
|
-
test('should only subscribe once when given same observable on re-renders', function () {
|
|
23
|
-
var subscriptionCount = 0;
|
|
24
|
-
var observable = new rxjs_1.Observable(function () {
|
|
25
|
-
subscriptionCount++;
|
|
26
|
-
});
|
|
27
|
-
expect(subscriptionCount).toBe(0);
|
|
28
|
-
var _a = (0, react_1.renderHook)(function () { return (0, useObservable_1.useObservable)(observable); }), unmount = _a.unmount, rerender = _a.rerender;
|
|
29
|
-
expect(subscriptionCount).toBe(1);
|
|
30
|
-
rerender();
|
|
31
|
-
expect(subscriptionCount).toBe(1);
|
|
32
|
-
unmount();
|
|
33
|
-
(0, react_1.renderHook)(function () { return (0, useObservable_1.useObservable)(observable); });
|
|
34
|
-
expect(subscriptionCount).toBe(2);
|
|
35
|
-
});
|
|
36
|
-
test('should not return undefined during render if initial value is given', function () {
|
|
37
|
-
var observable = (0, rxjs_1.timer)(100).pipe((0, operators_1.mapTo)('emitted value'));
|
|
38
|
-
var returnedValues = [];
|
|
39
|
-
function ObservableComponent() {
|
|
40
|
-
var observedValue = (0, useObservable_1.useObservable)(observable, 'initial value');
|
|
41
|
-
returnedValues.push(observedValue);
|
|
42
|
-
return (0, react_2.createElement)(react_2.Fragment, null, observedValue);
|
|
43
|
-
}
|
|
44
|
-
(0, react_1.render)((0, react_2.createElement)(ObservableComponent));
|
|
45
|
-
expect(returnedValues).toEqual(expect.arrayContaining(['initial value']));
|
|
46
|
-
});
|
|
47
|
-
test('should not return undefined during render if observable is sync', function () {
|
|
48
|
-
var observable = (0, rxjs_1.of)('initial value');
|
|
49
|
-
var returnedValues = [];
|
|
50
|
-
function ObservableComponent() {
|
|
51
|
-
var observedValue = (0, useObservable_1.useObservable)(observable);
|
|
52
|
-
returnedValues.push(observedValue);
|
|
53
|
-
return (0, react_2.createElement)(react_2.Fragment, null, observedValue);
|
|
54
|
-
}
|
|
55
|
-
(0, react_1.render)((0, react_2.createElement)(ObservableComponent));
|
|
56
|
-
expect(returnedValues).toEqual(expect.arrayContaining(['initial value']));
|
|
57
|
-
});
|
|
58
|
-
test('should return undefined during first render if observable is async', function () {
|
|
59
|
-
var observable = (0, rxjs_1.scheduled)('async value', rxjs_1.asyncScheduler);
|
|
60
|
-
var returnedValues = [];
|
|
61
|
-
function ObservableComponent() {
|
|
62
|
-
var observedValue = (0, useObservable_1.useObservable)(observable);
|
|
63
|
-
returnedValues.push(observedValue);
|
|
64
|
-
return (0, react_2.createElement)(react_2.Fragment, null, observedValue);
|
|
65
|
-
}
|
|
66
|
-
(0, react_1.render)((0, react_2.createElement)(ObservableComponent));
|
|
67
|
-
expect(returnedValues).toEqual(expect.arrayContaining([undefined]));
|
|
68
|
-
});
|
|
69
|
-
test('should have sync values from an observable as initial value', function () {
|
|
70
|
-
var observable = (0, rxjs_1.of)('something sync');
|
|
71
|
-
var result = (0, react_1.renderHook)(function () { return (0, useObservable_1.useObservable)(observable); }).result;
|
|
72
|
-
expect(result.current).toBe('something sync');
|
|
73
|
-
});
|
|
74
|
-
test('should have undefined as initial value from delayed observables', function () {
|
|
75
|
-
var _a = (0, react_1.renderHook)(function () {
|
|
76
|
-
return (0, useObservable_1.useObservable)((0, rxjs_1.scheduled)('something async', rxjs_1.asyncScheduler));
|
|
77
|
-
}), result = _a.result, unmount = _a.unmount;
|
|
78
|
-
expect(result.current).toBeUndefined();
|
|
79
|
-
unmount();
|
|
80
|
-
});
|
|
81
|
-
test('should have passed initialValue as initial value from delayed observables', function () {
|
|
82
|
-
var _a = (0, react_1.renderHook)(function () {
|
|
83
|
-
return (0, useObservable_1.useObservable)((0, rxjs_1.scheduled)('something async', rxjs_1.asyncScheduler), 'initial');
|
|
84
|
-
}), result = _a.result, unmount = _a.unmount;
|
|
85
|
-
expect(result.current).toBe('initial');
|
|
86
|
-
unmount();
|
|
87
|
-
});
|
|
88
|
-
test('should update with values from observables', function () {
|
|
89
|
-
var values$ = new rxjs_1.Subject();
|
|
90
|
-
var _a = (0, react_1.renderHook)(function () { return (0, useObservable_1.useObservable)(values$); }), result = _a.result, unmount = _a.unmount;
|
|
91
|
-
expect(result.current).toBe(undefined);
|
|
92
|
-
(0, react_1.act)(function () { return values$.next('something'); });
|
|
93
|
-
expect(result.current).toBe('something');
|
|
94
|
-
(0, react_1.act)(function () { return values$.next('otherthing'); });
|
|
95
|
-
expect(result.current).toBe('otherthing');
|
|
96
|
-
unmount();
|
|
97
|
-
});
|
|
98
|
-
test('should re-subscribe when receiving a new observable', function () {
|
|
99
|
-
var first$ = new rxjs_1.Subject();
|
|
100
|
-
var second$ = new rxjs_1.Subject();
|
|
101
|
-
var current$ = first$;
|
|
102
|
-
var _a = (0, react_1.renderHook)(function () { return (0, useObservable_1.useObservable)(current$, '!!initial!!'); }), result = _a.result, rerender = _a.rerender, unmount = _a.unmount;
|
|
103
|
-
(0, react_1.act)(function () { return first$.next('first 1'); });
|
|
104
|
-
expect(result.current).toBe('first 1');
|
|
105
|
-
current$ = second$;
|
|
106
|
-
rerender();
|
|
107
|
-
// since observable #2 hasn't emitted a value yet, we should use the initial value
|
|
108
|
-
expect(result.current).toBe('!!initial!!');
|
|
109
|
-
// Now we should be subscribed to second$ and it's emission should be returned
|
|
110
|
-
(0, react_1.act)(function () { return second$.next('second 1'); });
|
|
111
|
-
expect(result.current).toBe('second 1');
|
|
112
|
-
// we should no longer be subscribed to the first and ignore any emissions
|
|
113
|
-
(0, react_1.act)(function () { return first$.next('first 2'); });
|
|
114
|
-
expect(result.current).toBe('second 1');
|
|
115
|
-
unmount();
|
|
116
|
-
});
|
package/dist/cjs/index.d.ts
DELETED
package/dist/cjs/index.js
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
-
};
|
|
16
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
__exportStar(require("./useObservable"), exports);
|
|
18
|
-
__exportStar(require("./useObservableEvent"), exports);
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import type { Observable } from 'rxjs';
|
|
2
|
-
export declare function useObservable<ObservableType extends Observable<any>>(observable: ObservableType, initialValue?: UnboxObservable<ObservableType> | (() => UnboxObservable<ObservableType>)): UnboxObservable<ObservableType>;
|
|
3
|
-
declare type UnboxObservable<T> = T extends Observable<infer U> ? U : never;
|
|
4
|
-
export {};
|