react-rx 3.0.0-3 → 3.0.0-4

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.
@@ -14,7 +14,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
14
14
  function verb(n) { return function (v) { return step([n, v]); }; }
15
15
  function step(op) {
16
16
  if (f) throw new TypeError("Generator is already executing.");
17
- while (_) try {
17
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
18
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
19
  if (y = 0, t) op = [op[0] & 2, t.value];
20
20
  switch (op[0]) {
@@ -1,4 +1,4 @@
1
1
  import type { Observable } from 'rxjs';
2
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;
3
+ type UnboxObservable<T> = T extends Observable<infer U> ? U : never;
4
4
  export {};
@@ -1,3 +1,8 @@
1
1
  import { DependencyList } from 'react';
2
2
  import { Observable } from 'rxjs';
3
3
  export declare function useObservableCallback<T, U>(fn: (arg: Observable<T>) => Observable<U>, dependencies?: DependencyList): (arg: T) => void;
4
+ export declare function useObservableEvent<T, U>(fn: (arg: Observable<T>) => Observable<U>): (arg: T) => void;
5
+ /**
6
+ * This is a ponyfill of the upcoming `useEffectEvent` hook that'll arrive in React 19
7
+ */
8
+ export declare function useEffectEvent<const T extends (...args: any[]) => void>(fn: T): T;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.useObservableCallback = void 0;
3
+ exports.useEffectEvent = exports.useObservableEvent = exports.useObservableCallback = void 0;
4
4
  var observable_callback_1 = require("observable-callback");
5
5
  var react_1 = require("react");
6
6
  var EMPTY_DEPS = [];
@@ -21,3 +21,32 @@ function useObservableCallback(fn, dependencies) {
21
21
  return call;
22
22
  }
23
23
  exports.useObservableCallback = useObservableCallback;
24
+ function useObservableEvent(fn) {
25
+ var _a = (0, react_1.useState)(function () { return (0, observable_callback_1.observableCallback)(); })[0], calls$ = _a[0], call = _a[1];
26
+ var callback = useEffectEvent(fn);
27
+ (0, react_1.useEffect)(function () {
28
+ var subscription = calls$.pipe(callback).subscribe();
29
+ return function () { return subscription.unsubscribe(); };
30
+ }, [callback, calls$]);
31
+ return call;
32
+ }
33
+ exports.useObservableEvent = useObservableEvent;
34
+ /**
35
+ * This is a ponyfill of the upcoming `useEffectEvent` hook that'll arrive in React 19
36
+ */
37
+ function useEffectEvent(fn) {
38
+ var ref = (0, react_1.useRef)(null);
39
+ (0, react_1.useInsertionEffect)(function () {
40
+ ref.current = fn;
41
+ }, [fn]);
42
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
43
+ return (0, react_1.useCallback)(function () {
44
+ var args = [];
45
+ for (var _i = 0; _i < arguments.length; _i++) {
46
+ args[_i] = arguments[_i];
47
+ }
48
+ var f = ref.current;
49
+ return f.apply(void 0, args);
50
+ }, []);
51
+ }
52
+ exports.useEffectEvent = useEffectEvent;
@@ -11,7 +11,7 @@ import { act, render } from '@testing-library/react';
11
11
  import { createElement, Fragment, StrictMode, useEffect } from 'react';
12
12
  import { BehaviorSubject, Observable } from 'rxjs';
13
13
  import { useObservable } from '../useObservable';
14
- const wait = (ms) => new Promise(resolve => setTimeout(resolve, ms));
14
+ const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
15
15
  // NOTE: Jest runs NODE_ENV=test by default, which enables development flags for React
16
16
  test('Strict mode should trigger double mount effects and re-renders', () => __awaiter(void 0, void 0, void 0, function* () {
17
17
  const subject = new BehaviorSubject(0);
@@ -1,4 +1,4 @@
1
1
  import type { Observable } from 'rxjs';
2
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;
3
+ type UnboxObservable<T> = T extends Observable<infer U> ? U : never;
4
4
  export {};
@@ -21,7 +21,7 @@ export function useObservable(observable, initialValue) {
21
21
  const entry = {
22
22
  snapshot: initialValueRef.current,
23
23
  };
24
- entry.observable = observable.pipe(shareReplay({ refCount: true, bufferSize: 1 }), tap(value => (entry.snapshot = value)));
24
+ entry.observable = observable.pipe(shareReplay({ refCount: true, bufferSize: 1 }), tap((value) => (entry.snapshot = value)));
25
25
  // Eagerly subscribe to sync set `entry.currentValue` to what the observable returns, and keep the observable alive until the component unmounts.
26
26
  entry.subscription = entry.observable.subscribe();
27
27
  cache.set(observable, entry);
@@ -1,3 +1,8 @@
1
1
  import { DependencyList } from 'react';
2
2
  import { Observable } from 'rxjs';
3
3
  export declare function useObservableCallback<T, U>(fn: (arg: Observable<T>) => Observable<U>, dependencies?: DependencyList): (arg: T) => void;
4
+ export declare function useObservableEvent<T, U>(fn: (arg: Observable<T>) => Observable<U>): (arg: T) => void;
5
+ /**
6
+ * This is a ponyfill of the upcoming `useEffectEvent` hook that'll arrive in React 19
7
+ */
8
+ export declare function useEffectEvent<const T extends (...args: any[]) => void>(fn: T): T;
@@ -1,5 +1,5 @@
1
1
  import { observableCallback } from 'observable-callback';
2
- import { useCallback, useEffect, useRef } from 'react';
2
+ import { useCallback, useEffect, useInsertionEffect, useRef, useState } from 'react';
3
3
  const EMPTY_DEPS = [];
4
4
  export function useObservableCallback(fn, dependencies = EMPTY_DEPS) {
5
5
  const callbackRef = useRef();
@@ -16,3 +16,26 @@ export function useObservableCallback(fn, dependencies = EMPTY_DEPS) {
16
16
  }, [calls$, call, callback]);
17
17
  return call;
18
18
  }
19
+ export function useObservableEvent(fn) {
20
+ const [[calls$, call]] = useState(() => observableCallback());
21
+ const callback = useEffectEvent(fn);
22
+ useEffect(() => {
23
+ const subscription = calls$.pipe(callback).subscribe();
24
+ return () => subscription.unsubscribe();
25
+ }, [callback, calls$]);
26
+ return call;
27
+ }
28
+ /**
29
+ * This is a ponyfill of the upcoming `useEffectEvent` hook that'll arrive in React 19
30
+ */
31
+ export function useEffectEvent(fn) {
32
+ const ref = useRef(null);
33
+ useInsertionEffect(() => {
34
+ ref.current = fn;
35
+ }, [fn]);
36
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
37
+ return useCallback((...args) => {
38
+ const f = ref.current;
39
+ return f(...args);
40
+ }, []);
41
+ }
@@ -13,7 +13,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
13
13
  function verb(n) { return function (v) { return step([n, v]); }; }
14
14
  function step(op) {
15
15
  if (f) throw new TypeError("Generator is already executing.");
16
- while (_) try {
16
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
17
17
  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;
18
18
  if (y = 0, t) op = [op[0] & 2, t.value];
19
19
  switch (op[0]) {
@@ -1,4 +1,4 @@
1
1
  import type { Observable } from 'rxjs';
2
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;
3
+ type UnboxObservable<T> = T extends Observable<infer U> ? U : never;
4
4
  export {};
@@ -1,3 +1,8 @@
1
1
  import { DependencyList } from 'react';
2
2
  import { Observable } from 'rxjs';
3
3
  export declare function useObservableCallback<T, U>(fn: (arg: Observable<T>) => Observable<U>, dependencies?: DependencyList): (arg: T) => void;
4
+ export declare function useObservableEvent<T, U>(fn: (arg: Observable<T>) => Observable<U>): (arg: T) => void;
5
+ /**
6
+ * This is a ponyfill of the upcoming `useEffectEvent` hook that'll arrive in React 19
7
+ */
8
+ export declare function useEffectEvent<const T extends (...args: any[]) => void>(fn: T): T;
@@ -1,5 +1,5 @@
1
1
  import { observableCallback } from 'observable-callback';
2
- import { useCallback, useEffect, useRef } from 'react';
2
+ import { useCallback, useEffect, useInsertionEffect, useRef, useState } from 'react';
3
3
  var EMPTY_DEPS = [];
4
4
  export function useObservableCallback(fn, dependencies) {
5
5
  if (dependencies === void 0) { dependencies = EMPTY_DEPS; }
@@ -17,3 +17,30 @@ export function useObservableCallback(fn, dependencies) {
17
17
  }, [calls$, call, callback]);
18
18
  return call;
19
19
  }
20
+ export function useObservableEvent(fn) {
21
+ var _a = useState(function () { return observableCallback(); })[0], calls$ = _a[0], call = _a[1];
22
+ var callback = useEffectEvent(fn);
23
+ useEffect(function () {
24
+ var subscription = calls$.pipe(callback).subscribe();
25
+ return function () { return subscription.unsubscribe(); };
26
+ }, [callback, calls$]);
27
+ return call;
28
+ }
29
+ /**
30
+ * This is a ponyfill of the upcoming `useEffectEvent` hook that'll arrive in React 19
31
+ */
32
+ export function useEffectEvent(fn) {
33
+ var ref = useRef(null);
34
+ useInsertionEffect(function () {
35
+ ref.current = fn;
36
+ }, [fn]);
37
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
38
+ return useCallback(function () {
39
+ var args = [];
40
+ for (var _i = 0; _i < arguments.length; _i++) {
41
+ args[_i] = arguments[_i];
42
+ }
43
+ var f = ref.current;
44
+ return f.apply(void 0, args);
45
+ }, []);
46
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-rx",
3
- "version": "3.0.0-3",
3
+ "version": "3.0.0-4",
4
4
  "description": "React + RxJS = <3",
5
5
  "keywords": [
6
6
  "action",
@@ -69,10 +69,12 @@
69
69
  "test": "jest",
70
70
  "lint": "eslint --cache ."
71
71
  },
72
+ "prettier": "@sanity/prettier-config",
72
73
  "dependencies": {
73
74
  "observable-callback": "^1.0.3"
74
75
  },
75
76
  "devDependencies": {
77
+ "@sanity/prettier-config": "^1.0.2",
76
78
  "@sanity/semantic-release-preset": "^2.0.5",
77
79
  "@testing-library/dom": "^10.1.0",
78
80
  "@testing-library/react": "^16.0.0",
@@ -80,28 +82,27 @@
80
82
  "@types/node": "^18.17.5",
81
83
  "@types/react": "^18.3.3",
82
84
  "@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": "^0.0.0-experimental-51a85ea-20240601",
90
- "eslint-plugin-react-hooks": "4.6.2",
85
+ "@typescript-eslint/eslint-plugin": "^7.12.0",
86
+ "@typescript-eslint/parser": "^7.12.0",
87
+ "eslint": "^8.57.0",
88
+ "eslint-config-prettier": "^9.1.0",
89
+ "eslint-plugin-prettier": "^5.1.3",
90
+ "eslint-plugin-react": "^7.34.2",
91
+ "eslint-plugin-react-compiler": "0.0.0-experimental-51a85ea-20240601",
92
+ "eslint-plugin-react-hooks": "^4.6.2",
91
93
  "eslint-plugin-simple-import-sort": "^12.1.0",
92
94
  "jest": "^29.6.2",
93
95
  "jest-environment-jsdom": "^29.6.2",
94
96
  "jsdom": "^20.0.3",
95
97
  "npm-run-all": "^4.1.5",
96
- "prettier": "^2.8.8",
97
- "prettier-plugin-packagejson": "^2.4.5",
98
+ "prettier": "^3.3.1",
98
99
  "react": "^18.3.1",
99
100
  "react-dom": "^18.3.1",
100
101
  "react-test-renderer": "^18.3.1",
101
102
  "rimraf": "^3.0.2",
102
103
  "rxjs": "^7.8.1",
103
104
  "ts-jest": "^29.1.1",
104
- "typescript": "4.7.4"
105
+ "typescript": "5.4.5"
105
106
  },
106
107
  "peerDependencies": {
107
108
  "react": "^18.3 || >=19.0.0-rc",
@@ -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
 
@@ -37,7 +37,7 @@ export function useObservable<ObservableType extends Observable<any>>(
37
37
  }
38
38
  entry.observable = observable.pipe(
39
39
  shareReplay({refCount: true, bufferSize: 1}),
40
- tap(value => (entry.snapshot = value)),
40
+ tap((value) => (entry.snapshot = value)),
41
41
  )
42
42
 
43
43
  // Eagerly subscribe to sync set `entry.currentValue` to what the observable returns, and keep the observable alive until the component unmounts.
@@ -1,5 +1,5 @@
1
1
  import {observableCallback} from 'observable-callback'
2
- import {DependencyList, useCallback, useEffect, useRef} from 'react'
2
+ import {DependencyList, useCallback, useEffect, useInsertionEffect, useRef, useState} from 'react'
3
3
  import {Observable} from 'rxjs'
4
4
 
5
5
  const EMPTY_DEPS: DependencyList = []
@@ -27,3 +27,38 @@ export function useObservableCallback<T, U>(
27
27
 
28
28
  return call
29
29
  }
30
+
31
+ export function useObservableEvent<T, U>(
32
+ fn: (arg: Observable<T>) => Observable<U>,
33
+ ): (arg: T) => void {
34
+ const [[calls$, call]] = useState(() => observableCallback<T>())
35
+
36
+ const callback = useEffectEvent(fn)
37
+
38
+ useEffect(() => {
39
+ const subscription = calls$.pipe(callback).subscribe()
40
+ return () => subscription.unsubscribe()
41
+ }, [callback, calls$])
42
+
43
+ return call
44
+ }
45
+
46
+ /**
47
+ * This is a ponyfill of the upcoming `useEffectEvent` hook that'll arrive in React 19
48
+ */
49
+ export function useEffectEvent<
50
+ const T extends (
51
+ ...args: // eslint-disable-next-line @typescript-eslint/no-explicit-any
52
+ any[]
53
+ ) => void,
54
+ >(fn: T): T {
55
+ const ref = useRef<T | null>(null)
56
+ useInsertionEffect(() => {
57
+ ref.current = fn
58
+ }, [fn])
59
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
60
+ return useCallback((...args: any[]) => {
61
+ const f = ref.current!
62
+ return f(...args)
63
+ }, []) as T
64
+ }