react-rx 1.0.0-beta.6 → 2.0.0

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.
Files changed (128) hide show
  1. package/.idea/compiler.xml +1 -1
  2. package/.idea/inspectionProfiles/Project_Default.xml +1 -0
  3. package/.idea/markdown.xml +9 -0
  4. package/.idea/misc.xml +0 -6
  5. package/dist/cjs/WithObservable.js +3 -3
  6. package/dist/cjs/displayName.js +1 -1
  7. package/dist/cjs/reactiveComponent.js +6 -6
  8. package/dist/cjs/useAsObservable.js +10 -18
  9. package/dist/cjs/useObservable.js +26 -31
  10. package/dist/cjs/useObservableCallback.js +4 -4
  11. package/dist/cjs/useWithObservable.js +2 -2
  12. package/dist/cjs/utils.js +7 -7
  13. package/dist/cjs/withPropsStream.js +8 -4
  14. package/dist/es2015/useAsObservable.js +10 -18
  15. package/dist/es2015/useObservable.js +24 -31
  16. package/dist/esm/displayName.js +1 -1
  17. package/dist/esm/useAsObservable.js +10 -18
  18. package/dist/esm/useObservable.js +26 -31
  19. package/package.json +5 -3
  20. package/src/useAsObservable.ts +13 -18
  21. package/src/useObservable.ts +39 -34
  22. package/.idea/workspace.xml +0 -228
  23. package/jest.config.js +0 -5
  24. package/website/.babelrc +0 -21
  25. package/website/.prettierrc +0 -7
  26. package/website/README.mdx +0 -1
  27. package/website/package.json +0 -84
  28. package/website/src/@types/babel.d.ts +0 -4
  29. package/website/src/@types/mdx.d.ts +0 -11
  30. package/website/src/@types/react-css-burger.d.ts +0 -4
  31. package/website/src/App.tsx +0 -68
  32. package/website/src/components/Header.tsx +0 -118
  33. package/website/src/components/Link.tsx +0 -18
  34. package/website/src/components/LoadPage.tsx +0 -60
  35. package/website/src/components/Sidebar.tsx +0 -88
  36. package/website/src/components/logos/Github.tsx +0 -10
  37. package/website/src/components/logos/React.tsx +0 -27
  38. package/website/src/components/logos/ReactRxLogo.tsx +0 -39
  39. package/website/src/components/logos/RxJs.tsx +0 -69
  40. package/website/src/components/repl/Checkerboard.tsx +0 -25
  41. package/website/src/components/repl/CodeBlock.tsx +0 -147
  42. package/website/src/components/repl/CodeMirror.tsx +0 -37
  43. package/website/src/components/repl/CodeMirrorMode.tsx +0 -67
  44. package/website/src/components/repl/EvalCode.tsx +0 -55
  45. package/website/src/components/repl/Prelude.tsx +0 -50
  46. package/website/src/components/repl/ShowError.tsx +0 -27
  47. package/website/src/components/repl/codemirror-lib.ts +0 -8
  48. package/website/src/components/repl/codemirror-theme.css +0 -131
  49. package/website/src/components/repl/compile/babel.ts +0 -21
  50. package/website/src/components/repl/eval/evalCallback.ts +0 -27
  51. package/website/src/components/repl/eval/evalCode.ts +0 -7
  52. package/website/src/components/repl/eval/evalExpression.ts +0 -4
  53. package/website/src/components/repl/eval/evalReactDomRender.ts +0 -23
  54. package/website/src/components/repl/index.ts +0 -1
  55. package/website/src/components/repl/runMode.ts +0 -42
  56. package/website/src/datastores/location.ts +0 -14
  57. package/website/src/datastores/page.ts +0 -11
  58. package/website/src/datastores/pageTransition.ts +0 -97
  59. package/website/src/entries/main.css +0 -2
  60. package/website/src/entries/main.tsx +0 -6
  61. package/website/src/examples/FizzBuzz/FizzBuzzExample.tsx +0 -39
  62. package/website/src/examples/FizzBuzz/index.tsx +0 -9
  63. package/website/src/examples/_utils/globalScope.ts +0 -45
  64. package/website/src/examples/animation/AnimationExample.tsx +0 -152
  65. package/website/src/examples/animation/easings.ts +0 -0
  66. package/website/src/examples/animation/index.tsx +0 -15
  67. package/website/src/examples/context/Context.example.jsx +0 -67
  68. package/website/src/examples/context/index.tsx +0 -9
  69. package/website/src/examples/errors/Errors.example.jsx +0 -69
  70. package/website/src/examples/errors/index.tsx +0 -9
  71. package/website/src/examples/event-handlers/EventHandlersExample.tsx +0 -48
  72. package/website/src/examples/event-handlers/index.tsx +0 -9
  73. package/website/src/examples/fetch/FetchExample.jsx +0 -43
  74. package/website/src/examples/fetch/a.txt +0 -1
  75. package/website/src/examples/fetch/b.txt +0 -1
  76. package/website/src/examples/fetch/index.tsx +0 -9
  77. package/website/src/examples/form-data/FormDataExample.jsx +0 -119
  78. package/website/src/examples/form-data/index.tsx +0 -12
  79. package/website/src/examples/form-data/storage.ts +0 -27
  80. package/website/src/examples/forward-ref/ForwardRefExample.tsx +0 -55
  81. package/website/src/examples/forward-ref/index.tsx +0 -9
  82. package/website/src/examples/hello-world/HelloWorld.example.jsx +0 -6
  83. package/website/src/examples/hello-world/index.tsx +0 -9
  84. package/website/src/examples/hooks-interop/HooksInterop.example.tsx +0 -42
  85. package/website/src/examples/hooks-interop/index.tsx +0 -9
  86. package/website/src/examples/passthrough-props/PassThroughPropsExample.jsx +0 -57
  87. package/website/src/examples/passthrough-props/index.tsx +0 -11
  88. package/website/src/examples/reactive-state/ReactiveState.example.jsx +0 -43
  89. package/website/src/examples/reactive-state/index.ts +0 -9
  90. package/website/src/examples/readme-examples/README.mdx +0 -0
  91. package/website/src/examples/readme-examples/index.ts +0 -11
  92. package/website/src/examples/shared-state/SharedState.example.tsx +0 -59
  93. package/website/src/examples/shared-state/index.tsx +0 -9
  94. package/website/src/examples/simple/Counter.example.tsx +0 -14
  95. package/website/src/examples/simple/index.tsx +0 -9
  96. package/website/src/examples/sync/Sync.example.tsx +0 -9
  97. package/website/src/examples/sync/index.tsx +0 -9
  98. package/website/src/examples/tick/TickExample.jsx +0 -51
  99. package/website/src/examples/tick/index.ts +0 -9
  100. package/website/src/examples/todo-app/TodoApp.example.tsx +0 -88
  101. package/website/src/examples/todo-app/index.tsx +0 -12
  102. package/website/src/examples/todo-app/storage.ts +0 -27
  103. package/website/src/examples/use-element/UseElementExample.tsx +0 -70
  104. package/website/src/examples/use-element/index.tsx +0 -9
  105. package/website/src/examples/use-observable/search/SearchExample.tsx +0 -82
  106. package/website/src/examples/use-observable/search/index.tsx +0 -8
  107. package/website/src/examples/use-observable/use-observable/UseObservableExample.tsx +0 -70
  108. package/website/src/examples/use-observable/use-observable/index.tsx +0 -9
  109. package/website/src/index.html +0 -10
  110. package/website/src/mdx-components.tsx +0 -74
  111. package/website/src/pages/Api/Api.mdx +0 -134
  112. package/website/src/pages/Api/ApiPage.tsx +0 -25
  113. package/website/src/pages/Examples/Examples.tsx +0 -105
  114. package/website/src/pages/Examples/ExamplesPage.tsx +0 -13
  115. package/website/src/pages/Guide/Guide.mdx +0 -275
  116. package/website/src/pages/Guide/GuidePage.tsx +0 -25
  117. package/website/src/pages/Index/IndexPage.tsx +0 -50
  118. package/website/src/pages/Index/ReactRxReadme.md +0 -20
  119. package/website/src/pages/NotFound.tsx +0 -3
  120. package/website/src/pages/pages.ts +0 -46
  121. package/website/src/pages/styles.tsx +0 -24
  122. package/website/src/theme.ts +0 -61
  123. package/website/src/utils/parseCodeFenceHeader.ts +0 -32
  124. package/website/tsconfig.json +0 -30
  125. package/website/vercel.json +0 -4
  126. package/website/webpack/config.js +0 -5
  127. package/website/webpack/createConfig.js +0 -95
  128. package/website/webpack/mdx-toc-loader.js +0 -38
@@ -1,6 +1,6 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
2
  <project version="4">
3
3
  <component name="TypeScriptCompiler">
4
- <option name="showAllErrors" value="true" />
4
+ <option name="nodeInterpreterTextField" value="node" />
5
5
  </component>
6
6
  </project>
@@ -1,6 +1,7 @@
1
1
  <component name="InspectionProjectProfileManager">
2
2
  <profile version="1.0">
3
3
  <option name="myName" value="Project Default" />
4
+ <inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
4
5
  <inspection_tool class="TypescriptExplicitMemberType" enabled="false" level="INFORMATION" enabled_by_default="false" />
5
6
  </profile>
6
7
  </component>
@@ -0,0 +1,9 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="MarkdownSettings">
4
+ <enabledExtensions>
5
+ <entry key="MermaidLanguageExtension" value="false" />
6
+ <entry key="PlantUMLLanguageExtension" value="false" />
7
+ </enabledExtensions>
8
+ </component>
9
+ </project>
package/.idea/misc.xml CHANGED
@@ -1,6 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="JavaScriptSettings">
4
- <option name="languageLevel" value="ES6" />
5
- </component>
6
- </project>
@@ -4,9 +4,9 @@ exports.WithObservable = void 0;
4
4
  var operators_1 = require("rxjs/operators");
5
5
  var reactiveComponent_1 = require("./reactiveComponent");
6
6
  function createWithObservable() {
7
- return reactiveComponent_1.reactiveComponent(function (props$) {
8
- return props$.pipe(operators_1.distinctUntilChanged(function (props, prevProps) { return props.observable === prevProps.observable; }), operators_1.switchMap(function (props) {
9
- return props.observable.pipe(operators_1.map(function (observableValue) { return props.children(observableValue); }));
7
+ return (0, reactiveComponent_1.reactiveComponent)(function (props$) {
8
+ return props$.pipe((0, operators_1.distinctUntilChanged)(function (props, prevProps) { return props.observable === prevProps.observable; }), (0, operators_1.switchMap)(function (props) {
9
+ return props.observable.pipe((0, operators_1.map)(function (observableValue) { return props.children(observableValue); }));
10
10
  }));
11
11
  });
12
12
  }
@@ -8,6 +8,6 @@ var getDisplayName = function (Component) {
8
8
  return (Component && (Component.displayName || Component.name)) || 'Unknown';
9
9
  };
10
10
  var wrapDisplayName = function (BaseComponent, wrapperName) {
11
- return wrapperName + "(" + getDisplayName(BaseComponent) + ")";
11
+ return "".concat(wrapperName, "(").concat(getDisplayName(BaseComponent), ")");
12
12
  };
13
13
  exports.wrapDisplayName = wrapDisplayName;
@@ -7,14 +7,14 @@ var useObservable_1 = require("./useObservable");
7
7
  var react_1 = require("react");
8
8
  function fromComponent(component) {
9
9
  var wrappedComponent = function (props) {
10
- return react_1.createElement(react_1.Fragment, null, useObservable_1.useObservable(react_1.useRef(component(useAsObservable_1.useAsObservable(props))).current));
10
+ return (0, react_1.createElement)(react_1.Fragment, null, (0, useObservable_1.useObservable)((0, react_1.useRef)(component((0, useAsObservable_1.useAsObservable)(props))).current));
11
11
  };
12
- wrappedComponent.displayName = displayName_1.wrapDisplayName(component, 'reactiveComponent');
12
+ wrappedComponent.displayName = (0, displayName_1.wrapDisplayName)(component, 'reactiveComponent');
13
13
  return wrappedComponent;
14
14
  }
15
15
  function fromObservable(input$) {
16
16
  return function ReactiveComponent() {
17
- return react_1.createElement(react_1.Fragment, null, useObservable_1.useObservable(input$));
17
+ return (0, react_1.createElement)(react_1.Fragment, null, (0, useObservable_1.useObservable)(input$));
18
18
  };
19
19
  }
20
20
  function reactiveComponent(observableOrComponent) {
@@ -24,10 +24,10 @@ function reactiveComponent(observableOrComponent) {
24
24
  }
25
25
  exports.reactiveComponent = reactiveComponent;
26
26
  function forwardRef(component) {
27
- var wrappedComponent = react_1.forwardRef(function (props, ref) {
28
- return react_1.createElement(react_1.Fragment, null, useObservable_1.useObservable(react_1.useRef(component(useAsObservable_1.useAsObservable(props), ref)).current));
27
+ var wrappedComponent = (0, react_1.forwardRef)(function (props, ref) {
28
+ return (0, react_1.createElement)(react_1.Fragment, null, (0, useObservable_1.useObservable)((0, react_1.useRef)(component((0, useAsObservable_1.useAsObservable)(props), ref)).current));
29
29
  });
30
- wrappedComponent.displayName = displayName_1.wrapDisplayName(component, 'reactiveComponent');
30
+ wrappedComponent.displayName = (0, displayName_1.wrapDisplayName)(component, 'reactiveComponent');
31
31
  return wrappedComponent;
32
32
  }
33
33
  exports.forwardRef = forwardRef;
@@ -5,27 +5,19 @@ var rxjs_1 = require("rxjs");
5
5
  var react_1 = require("react");
6
6
  var useIsomorphicEffect_1 = require("./useIsomorphicEffect");
7
7
  function useAsObservable(value, operator) {
8
- var isInitial = react_1.useRef(true);
9
- var subjectRef = react_1.useRef(new rxjs_1.BehaviorSubject(value));
10
- var observableRef = react_1.useRef();
11
- if (!observableRef.current) {
12
- var observable = subjectRef.current.asObservable();
13
- observableRef.current = operator ? observable.pipe(operator) : observable;
14
- }
15
- useIsomorphicEffect_1.useIsomorphicEffect(function () {
16
- if (isInitial.current) {
17
- isInitial.current = false;
18
- }
19
- else {
20
- // emit only on update
21
- subjectRef.current.next(value);
22
- }
8
+ var _a = (0, react_1.useMemo)(function () {
9
+ var subject = new rxjs_1.BehaviorSubject(value);
10
+ var observable = subject.asObservable();
11
+ return [operator ? observable.pipe(operator) : observable, subject];
12
+ }, []), observable = _a[0], subject = _a[1];
13
+ (0, useIsomorphicEffect_1.useIsomorphicEffect)(function () {
14
+ subject.next(value);
23
15
  }, [value]);
24
- useIsomorphicEffect_1.useIsomorphicEffect(function () {
16
+ (0, react_1.useEffect)(function () {
25
17
  return function () {
26
- return subjectRef.current.complete();
18
+ subject.complete();
27
19
  };
28
20
  }, []);
29
- return observableRef.current;
21
+ return observable;
30
22
  }
31
23
  exports.useAsObservable = useAsObservable;
@@ -1,45 +1,40 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.useMemoObservable = exports.useObservable = void 0;
4
+ var rxjs_1 = require("rxjs");
4
5
  var react_1 = require("react");
5
- var useIsomorphicEffect_1 = require("./useIsomorphicEffect");
6
+ var useAsObservable_1 = require("./useAsObservable");
7
+ var operators_1 = require("rxjs/operators");
8
+ var shim_1 = require("use-sync-external-store/shim");
6
9
  function getValue(value) {
7
10
  return typeof value === 'function' ? value() : value;
8
11
  }
9
- function useObservable(observable, initialValue) {
10
- var subscription = react_1.useRef();
11
- var isInitial = react_1.useRef(true);
12
- var _a = react_1.useState(function () {
13
- var isSync = true;
14
- var syncVal = getValue(initialValue);
15
- subscription.current = observable.subscribe(function (nextVal) {
16
- if (isSync) {
17
- syncVal = nextVal;
18
- }
19
- else {
20
- setState(nextVal);
21
- }
22
- });
23
- isSync = false;
24
- return syncVal;
25
- }), value = _a[0], setState = _a[1];
26
- useIsomorphicEffect_1.useIsomorphicEffect(function () {
27
- // when the observable changes after initial (possibly sync render)
28
- if (!isInitial.current) {
29
- subscription.current = observable.subscribe(function (nextVal) { return setState(nextVal); });
30
- }
31
- isInitial.current = false;
32
- return function () {
33
- if (subscription.current) {
34
- subscription.current.unsubscribe();
35
- subscription.current = undefined;
36
- }
12
+ function useObservableSubscription(observable) {
13
+ var store = (0, react_1.useMemo)(function () {
14
+ var currentValue;
15
+ return {
16
+ // Note: this works because the given observable always emits a value synchronously by concat-ing the given initialValue
17
+ getCurrentValue: function () { return currentValue; },
18
+ subscribe: function (callback) {
19
+ var subscription = observable.subscribe(function (value) {
20
+ currentValue = value;
21
+ callback(value);
22
+ });
23
+ return function () {
24
+ subscription.unsubscribe();
25
+ };
26
+ },
37
27
  };
38
28
  }, [observable]);
39
- return value;
29
+ return (0, shim_1.useSyncExternalStore)(store.subscribe, store.getCurrentValue);
30
+ }
31
+ function useObservable(observable, initialValue) {
32
+ return useObservableSubscription((0, useAsObservable_1.useAsObservable)(observable, (0, rxjs_1.pipe)((0, operators_1.distinctUntilChanged)(), (0, operators_1.switchMap)(function (observable) {
33
+ return (0, rxjs_1.merge)((0, rxjs_1.defer)(function () { return (0, rxjs_1.of)(getValue(initialValue)); }), observable);
34
+ }))));
40
35
  }
41
36
  exports.useObservable = useObservable;
42
37
  function useMemoObservable(observableOrFactory, deps, initialValue) {
43
- return useObservable(react_1.useMemo(function () { return getValue(observableOrFactory); }, deps), initialValue);
38
+ return useObservable((0, react_1.useMemo)(function () { return getValue(observableOrFactory); }, deps), initialValue);
44
39
  }
45
40
  exports.useMemoObservable = useMemoObservable;
@@ -6,14 +6,14 @@ var observable_callback_1 = require("observable-callback");
6
6
  var EMPTY_DEPS = [];
7
7
  function useObservableCallback(fn, dependencies) {
8
8
  if (dependencies === void 0) { dependencies = EMPTY_DEPS; }
9
- var callbackRef = react_1.useRef();
9
+ var callbackRef = (0, react_1.useRef)();
10
10
  if (!callbackRef.current) {
11
- callbackRef.current = observable_callback_1.observableCallback();
11
+ callbackRef.current = (0, observable_callback_1.observableCallback)();
12
12
  }
13
13
  var _a = callbackRef.current, calls$ = _a[0], call = _a[1];
14
14
  // eslint-disable-next-line react-hooks/exhaustive-deps
15
- var callback = react_1.useCallback(fn, dependencies);
16
- react_1.useEffect(function () {
15
+ var callback = (0, react_1.useCallback)(fn, dependencies);
16
+ (0, react_1.useEffect)(function () {
17
17
  var subscription = calls$.pipe(callback).subscribe();
18
18
  return function () {
19
19
  subscription.unsubscribe();
@@ -5,7 +5,7 @@ var useObservable_1 = require("./useObservable");
5
5
  var useAsObservable_1 = require("./useAsObservable");
6
6
  function useWithObservable(value, operator) {
7
7
  return operator
8
- ? useObservable_1.useObservable(useAsObservable_1.useAsObservable(value, operator))
9
- : useObservable_1.useObservable(useAsObservable_1.useAsObservable(value));
8
+ ? (0, useObservable_1.useObservable)((0, useAsObservable_1.useAsObservable)(value, operator))
9
+ : (0, useObservable_1.useObservable)((0, useAsObservable_1.useAsObservable)(value));
10
10
  }
11
11
  exports.useWithObservable = useWithObservable;
package/dist/cjs/utils.js CHANGED
@@ -5,26 +5,26 @@ var useAsObservable_1 = require("./useAsObservable");
5
5
  var observable_callback_1 = require("observable-callback");
6
6
  var operators_1 = require("rxjs/operators");
7
7
  var react_1 = require("react");
8
- var createState = function (initialState) { return observable_callback_1.observableCallback(operators_1.startWith(initialState)); };
8
+ var createState = function (initialState) { return (0, observable_callback_1.observableCallback)((0, operators_1.startWith)(initialState)); };
9
9
  function observeState(initial) {
10
- var _a = react_1.useState(initial), value = _a[0], update = _a[1];
11
- return [useAsObservable_1.useAsObservable(value), update];
10
+ var _a = (0, react_1.useState)(initial), value = _a[0], update = _a[1];
11
+ return [(0, useAsObservable_1.useAsObservable)(value), update];
12
12
  }
13
13
  exports.observeState = observeState;
14
14
  function observeCallback(operator) {
15
- var ref = react_1.useRef();
15
+ var ref = (0, react_1.useRef)();
16
16
  if (!ref.current) {
17
- ref.current = operator ? observable_callback_1.observableCallback(operator) : observable_callback_1.observableCallback();
17
+ ref.current = operator ? (0, observable_callback_1.observableCallback)(operator) : (0, observable_callback_1.observableCallback)();
18
18
  }
19
19
  return ref.current;
20
20
  }
21
21
  exports.observeCallback = observeCallback;
22
22
  function observeContext(context) {
23
- return useAsObservable_1.useAsObservable(react_1.useContext(context));
23
+ return (0, useAsObservable_1.useAsObservable)((0, react_1.useContext)(context));
24
24
  }
25
25
  exports.observeContext = observeContext;
26
26
  function observeElement() {
27
- var ref = react_1.useRef();
27
+ var ref = (0, react_1.useRef)();
28
28
  if (!ref.current) {
29
29
  ref.current = createState(null);
30
30
  }
@@ -12,7 +12,11 @@ var __assign = (this && this.__assign) || function () {
12
12
  };
13
13
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
14
14
  if (k2 === undefined) k2 = k;
15
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
15
+ var desc = Object.getOwnPropertyDescriptor(m, k);
16
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
17
+ desc = { enumerable: true, get: function() { return m[k]; } };
18
+ }
19
+ Object.defineProperty(o, k2, desc);
16
20
  }) : (function(o, m, k, k2) {
17
21
  if (k2 === undefined) k2 = k;
18
22
  o[k2] = m[k];
@@ -39,13 +43,13 @@ var reactiveComponent_1 = require("./reactiveComponent");
39
43
  * @deprecated Use reactiveComponent instead
40
44
  */
41
45
  function withPropsStream(observableOrFactory, TargetComponent) {
42
- var ComposedComponent = reactiveComponent_1.reactiveComponent(function (sourceProps$) {
46
+ var ComposedComponent = (0, reactiveComponent_1.reactiveComponent)(function (sourceProps$) {
43
47
  var targetProps$ = typeof observableOrFactory === 'function'
44
48
  ? observableOrFactory(sourceProps$)
45
49
  : observableOrFactory;
46
- return targetProps$.pipe(operators_1.map(function (props) { return React.createElement(TargetComponent, __assign({}, props)); }));
50
+ return targetProps$.pipe((0, operators_1.map)(function (props) { return React.createElement(TargetComponent, __assign({}, props)); }));
47
51
  });
48
- ComposedComponent.displayName = displayName_1.wrapDisplayName(TargetComponent, 'withPropsStream');
52
+ ComposedComponent.displayName = (0, displayName_1.wrapDisplayName)(TargetComponent, 'withPropsStream');
49
53
  return ComposedComponent;
50
54
  }
51
55
  exports.withPropsStream = withPropsStream;
@@ -1,27 +1,19 @@
1
1
  import { BehaviorSubject } from 'rxjs';
2
- import { useRef } from 'react';
2
+ import { useEffect, useMemo } from 'react';
3
3
  import { useIsomorphicEffect } from './useIsomorphicEffect';
4
4
  export function useAsObservable(value, operator) {
5
- const isInitial = useRef(true);
6
- const subjectRef = useRef(new BehaviorSubject(value));
7
- const observableRef = useRef();
8
- if (!observableRef.current) {
9
- const observable = subjectRef.current.asObservable();
10
- observableRef.current = operator ? observable.pipe(operator) : observable;
11
- }
5
+ const [observable, subject] = useMemo(() => {
6
+ const subject = new BehaviorSubject(value);
7
+ const observable = subject.asObservable();
8
+ return [operator ? observable.pipe(operator) : observable, subject];
9
+ }, []);
12
10
  useIsomorphicEffect(() => {
13
- if (isInitial.current) {
14
- isInitial.current = false;
15
- }
16
- else {
17
- // emit only on update
18
- subjectRef.current.next(value);
19
- }
11
+ subject.next(value);
20
12
  }, [value]);
21
- useIsomorphicEffect(() => {
13
+ useEffect(() => {
22
14
  return () => {
23
- return subjectRef.current.complete();
15
+ subject.complete();
24
16
  };
25
17
  }, []);
26
- return observableRef.current;
18
+ return observable;
27
19
  }
@@ -1,39 +1,32 @@
1
- import { useMemo, useRef, useState } from 'react';
2
- import { useIsomorphicEffect } from './useIsomorphicEffect';
1
+ import { defer, merge, of, pipe } from 'rxjs';
2
+ import { useMemo } from 'react';
3
+ import { useAsObservable } from './useAsObservable';
4
+ import { distinctUntilChanged, switchMap } from 'rxjs/operators';
5
+ import { useSyncExternalStore } from 'use-sync-external-store/shim';
3
6
  function getValue(value) {
4
7
  return typeof value === 'function' ? value() : value;
5
8
  }
6
- export function useObservable(observable, initialValue) {
7
- const subscription = useRef();
8
- const isInitial = useRef(true);
9
- const [value, setState] = useState(() => {
10
- let isSync = true;
11
- let syncVal = getValue(initialValue);
12
- subscription.current = observable.subscribe(nextVal => {
13
- if (isSync) {
14
- syncVal = nextVal;
15
- }
16
- else {
17
- setState(nextVal);
18
- }
19
- });
20
- isSync = false;
21
- return syncVal;
22
- });
23
- useIsomorphicEffect(() => {
24
- // when the observable changes after initial (possibly sync render)
25
- if (!isInitial.current) {
26
- subscription.current = observable.subscribe(nextVal => setState(nextVal));
27
- }
28
- isInitial.current = false;
29
- return () => {
30
- if (subscription.current) {
31
- subscription.current.unsubscribe();
32
- subscription.current = undefined;
33
- }
9
+ function useObservableSubscription(observable) {
10
+ const store = useMemo(() => {
11
+ let currentValue;
12
+ return {
13
+ // Note: this works because the given observable always emits a value synchronously by concat-ing the given initialValue
14
+ getCurrentValue: () => currentValue,
15
+ subscribe: (callback) => {
16
+ const subscription = observable.subscribe(value => {
17
+ currentValue = value;
18
+ callback(value);
19
+ });
20
+ return () => {
21
+ subscription.unsubscribe();
22
+ };
23
+ },
34
24
  };
35
25
  }, [observable]);
36
- return value;
26
+ return useSyncExternalStore(store.subscribe, store.getCurrentValue);
27
+ }
28
+ export function useObservable(observable, initialValue) {
29
+ return useObservableSubscription(useAsObservable(observable, pipe(distinctUntilChanged(), switchMap(observable => merge(defer(() => of(getValue(initialValue))), observable)))));
37
30
  }
38
31
  export function useMemoObservable(observableOrFactory, deps, initialValue) {
39
32
  return useObservable(useMemo(() => getValue(observableOrFactory), deps), initialValue);
@@ -5,5 +5,5 @@ var getDisplayName = function (Component) {
5
5
  return (Component && (Component.displayName || Component.name)) || 'Unknown';
6
6
  };
7
7
  export var wrapDisplayName = function (BaseComponent, wrapperName) {
8
- return wrapperName + "(" + getDisplayName(BaseComponent) + ")";
8
+ return "".concat(wrapperName, "(").concat(getDisplayName(BaseComponent), ")");
9
9
  };
@@ -1,27 +1,19 @@
1
1
  import { BehaviorSubject } from 'rxjs';
2
- import { useRef } from 'react';
2
+ import { useEffect, useMemo } from 'react';
3
3
  import { useIsomorphicEffect } from './useIsomorphicEffect';
4
4
  export function useAsObservable(value, operator) {
5
- var isInitial = useRef(true);
6
- var subjectRef = useRef(new BehaviorSubject(value));
7
- var observableRef = useRef();
8
- if (!observableRef.current) {
9
- var observable = subjectRef.current.asObservable();
10
- observableRef.current = operator ? observable.pipe(operator) : observable;
11
- }
5
+ var _a = useMemo(function () {
6
+ var subject = new BehaviorSubject(value);
7
+ var observable = subject.asObservable();
8
+ return [operator ? observable.pipe(operator) : observable, subject];
9
+ }, []), observable = _a[0], subject = _a[1];
12
10
  useIsomorphicEffect(function () {
13
- if (isInitial.current) {
14
- isInitial.current = false;
15
- }
16
- else {
17
- // emit only on update
18
- subjectRef.current.next(value);
19
- }
11
+ subject.next(value);
20
12
  }, [value]);
21
- useIsomorphicEffect(function () {
13
+ useEffect(function () {
22
14
  return function () {
23
- return subjectRef.current.complete();
15
+ subject.complete();
24
16
  };
25
17
  }, []);
26
- return observableRef.current;
18
+ return observable;
27
19
  }
@@ -1,39 +1,34 @@
1
- import { useMemo, useRef, useState } from 'react';
2
- import { useIsomorphicEffect } from './useIsomorphicEffect';
1
+ import { defer, merge, of, pipe } from 'rxjs';
2
+ import { useMemo } from 'react';
3
+ import { useAsObservable } from './useAsObservable';
4
+ import { distinctUntilChanged, switchMap } from 'rxjs/operators';
5
+ import { useSyncExternalStore } from 'use-sync-external-store/shim';
3
6
  function getValue(value) {
4
7
  return typeof value === 'function' ? value() : value;
5
8
  }
6
- export function useObservable(observable, initialValue) {
7
- var subscription = useRef();
8
- var isInitial = useRef(true);
9
- var _a = useState(function () {
10
- var isSync = true;
11
- var syncVal = getValue(initialValue);
12
- subscription.current = observable.subscribe(function (nextVal) {
13
- if (isSync) {
14
- syncVal = nextVal;
15
- }
16
- else {
17
- setState(nextVal);
18
- }
19
- });
20
- isSync = false;
21
- return syncVal;
22
- }), value = _a[0], setState = _a[1];
23
- useIsomorphicEffect(function () {
24
- // when the observable changes after initial (possibly sync render)
25
- if (!isInitial.current) {
26
- subscription.current = observable.subscribe(function (nextVal) { return setState(nextVal); });
27
- }
28
- isInitial.current = false;
29
- return function () {
30
- if (subscription.current) {
31
- subscription.current.unsubscribe();
32
- subscription.current = undefined;
33
- }
9
+ function useObservableSubscription(observable) {
10
+ var store = useMemo(function () {
11
+ var currentValue;
12
+ return {
13
+ // Note: this works because the given observable always emits a value synchronously by concat-ing the given initialValue
14
+ getCurrentValue: function () { return currentValue; },
15
+ subscribe: function (callback) {
16
+ var subscription = observable.subscribe(function (value) {
17
+ currentValue = value;
18
+ callback(value);
19
+ });
20
+ return function () {
21
+ subscription.unsubscribe();
22
+ };
23
+ },
34
24
  };
35
25
  }, [observable]);
36
- return value;
26
+ return useSyncExternalStore(store.subscribe, store.getCurrentValue);
27
+ }
28
+ export function useObservable(observable, initialValue) {
29
+ return useObservableSubscription(useAsObservable(observable, pipe(distinctUntilChanged(), switchMap(function (observable) {
30
+ return merge(defer(function () { return of(getValue(initialValue)); }), observable);
31
+ }))));
37
32
  }
38
33
  export function useMemoObservable(observableOrFactory, deps, initialValue) {
39
34
  return useObservable(useMemo(function () { return getValue(observableOrFactory); }, deps), initialValue);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-rx",
3
- "version": "1.0.0-beta.6",
3
+ "version": "2.0.0",
4
4
  "description": "React + RxJS = <3",
5
5
  "main": "dist/cjs/index.js",
6
6
  "types": "dist/cjs/index.d.ts",
@@ -25,8 +25,8 @@
25
25
  "observable-callback": "^1.0.1"
26
26
  },
27
27
  "peerDependencies": {
28
- "react": ">=16.8",
29
- "rxjs": "^6"
28
+ "react": "^16.8 || ^17 || ^18",
29
+ "rxjs": "^6.5 || ^7"
30
30
  },
31
31
  "devDependencies": {
32
32
  "@testing-library/dom": "^7.29.6",
@@ -35,6 +35,7 @@
35
35
  "@types/jest": "^26.0.20",
36
36
  "@types/react": "^17.0.2",
37
37
  "@types/react-dom": "^17.0.1",
38
+ "@types/use-sync-external-store": "^0.0.3",
38
39
  "@typescript-eslint/eslint-plugin": "^4.15.2",
39
40
  "@typescript-eslint/parser": "^4.15.2",
40
41
  "eslint": "^7.21.0",
@@ -48,6 +49,7 @@
48
49
  "react": "^17.0.1",
49
50
  "react-dom": "^17.0.1",
50
51
  "react-test-renderer": "^17.0.1",
52
+ "use-sync-external-store": "^1.2.0",
51
53
  "rimraf": "^3.0.2",
52
54
  "rxjs": "^6.5.5",
53
55
  "ts-jest": "^26.5.2",
@@ -1,5 +1,5 @@
1
- import {BehaviorSubject, Observable, Subject} from 'rxjs'
2
- import {useRef} from 'react'
1
+ import {BehaviorSubject, Observable} from 'rxjs'
2
+ import {useEffect, useMemo} from 'react'
3
3
  import {useIsomorphicEffect} from './useIsomorphicEffect'
4
4
 
5
5
  /**
@@ -17,27 +17,22 @@ export function useAsObservable<T, K = T>(
17
17
  value: T,
18
18
  operator?: (input: Observable<T>) => Observable<K>,
19
19
  ): Observable<T | K> {
20
- const isInitial = useRef(true)
21
- const subjectRef = useRef<Subject<T>>(new BehaviorSubject(value))
22
- const observableRef = useRef<Observable<T | K>>()
23
- if (!observableRef.current) {
24
- const observable = subjectRef.current.asObservable()
25
- observableRef.current = operator ? observable.pipe(operator) : observable
26
- }
20
+ const [observable, subject] = useMemo(() => {
21
+ const subject = new BehaviorSubject(value)
22
+
23
+ const observable = subject.asObservable()
24
+ return [operator ? observable.pipe(operator) : observable, subject]
25
+ }, [])
27
26
 
28
27
  useIsomorphicEffect(() => {
29
- if (isInitial.current) {
30
- isInitial.current = false
31
- } else {
32
- // emit only on update
33
- subjectRef.current.next(value)
34
- }
28
+ subject.next(value)
35
29
  }, [value])
36
- useIsomorphicEffect(() => {
30
+
31
+ useEffect(() => {
37
32
  return () => {
38
- return subjectRef.current.complete()
33
+ subject.complete()
39
34
  }
40
35
  }, [])
41
36
 
42
- return observableRef.current
37
+ return observable
43
38
  }