-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
197 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,197 @@ | ||
## 0.10.3 (2022-09-09) | ||
|
||
- fix: avoid errors on unmounted Suspense components | ||
|
||
## 0.10.2 (2022-09-09) | ||
|
||
- fix: pipeState also enhanced as a React element (#282) | ||
|
||
## 0.10.1 (2022-09-09) | ||
|
||
- fix: re-export types correctly from @rx-state/core | ||
|
||
### utils | ||
|
||
- chore: rename `selfDependant` to `selfDependent` (#272) | ||
|
||
## 0.10.0 (2022-09-09) | ||
|
||
- StateObservables as JSX Elements. | ||
|
||
StateObservables are now also JSX Elements, which lets you use them directly as children of other components. | ||
|
||
```tsx | ||
const count$ = state(interval(1000), 0) | ||
|
||
const App = () => { | ||
const count = useStateObservable(count$) | ||
|
||
return <div>{count}</div> | ||
} | ||
|
||
// Becomes | ||
|
||
const App = () => { | ||
return <div>{count$}</div> | ||
} | ||
``` | ||
|
||
- `.pipeState()`, `withDefault()` | ||
|
||
StateObservables now have a shorthand method `.pipeState(...args)` which works as RxJS `.pipe(`, but it wraps the result into a new state. | ||
|
||
```ts | ||
const newState$ = state( | ||
parent$.pipe( | ||
map(...) | ||
) | ||
) | ||
|
||
// Becomes | ||
const newState$ = parent$.pipeState( | ||
map(...) | ||
) | ||
``` | ||
|
||
`withDefault(value)` is an operator that creates a DefaultedStateObservable. It can be used at the end of `pipeState` to set the default value for that one. | ||
|
||
```ts | ||
const newState$ = state( | ||
parent$.pipe( | ||
map(...) | ||
), | ||
"defaultVal" | ||
) | ||
|
||
// Becomes | ||
const newState$ = parent$.pipeState( | ||
map(...), | ||
withDefault("defaultVal") | ||
) | ||
``` | ||
|
||
- Add additional argument on factory observables to prevent using them in incompatible HOF. | ||
|
||
Previously factory functions had the same signature that was passed into the function. You can use them in higher-order-functions and Typescript will think it's valid: | ||
|
||
```ts | ||
const user$ = state((id: string) => ...); | ||
|
||
const selectedUser$ = state( | ||
selectedId$.pipe( | ||
switchMap(user$) | ||
) | ||
); | ||
``` | ||
|
||
This is problematic because `switchMap` also passes in the number of elements emitted so far as the second argument, and the parametric state will then understand each call as a new instance. | ||
|
||
Now `user$` will have a typescript signature that will prevent it from being used into places that give more parameters than it has, so Typescript will flag this as an error. | ||
|
||
- `sinkSuspense()`, `liftSuspense()` | ||
|
||
These two new operators help deal with SUSPENSE values on the streams, which is useful when the meaning of SUSPENSE is that everything needs to be reset. | ||
|
||
`sinkSuspense()` is an operator that when it receives a SUSPENSE, it will throw it as an error down the stream, which resets all of the observables down below. It will then hold the subscription to the upstream, waiting for a resubscription to happen immediately. If it doesn't happen, then it will unsubscribe from upstream. | ||
|
||
`liftSuspense()` is an operator that when it receives SUSPENSE as an error, it will immediately resubscribe to its upstream, and emit SUSPENSE as a value. | ||
|
||
This allows to avoid dealing with SUSPENSE on the streams that are in-between the one that generates SUSPENSE and the one that needs to receive it. | ||
|
||
```ts | ||
const account$ = accountSwitch$.pipe(switchMapSuspended((v) => fetchAccount(v))) | ||
|
||
const posts$ = account$.pipe( | ||
switchMap((v) => (v === SUSPENSE ? of(SUSPENSE) : fetchPosts(v))), | ||
) | ||
|
||
/// with sinkSuspense | ||
const account$ = accountSwitch$.pipe( | ||
switchMapSuspended((v) => fetchAccount(v)), | ||
sinkSuspense(), | ||
) | ||
|
||
const posts$ = account$.pipe(switchMap((v) => fetchPosts(v))) | ||
``` | ||
|
||
`useStateObservable` is already fitted with `liftSuspense()`, so there's no need to call it on the StateObservables that are to be used in components. | ||
|
||
It's very important to remember that `sinkSuspense` is throwing SUSPENSE values as errors, which means that subscriptions will get closed, in ways that are not always obvious. In most of the cases, it can be solved by using `liftSuspense()`, dealing with that value, and calling `sinkSuspense()` again. Use at your own risk. | ||
|
||
### Fixes | ||
|
||
- Fix observable of promises triggering suspense. | ||
- Fix observables emitting synchronous completes triggering NoSubscribersError on Subscribe | ||
|
||
## 0.9.8 (2022-06-24) | ||
|
||
- Fix asynchronous errors on Subscribe not getting caught on ErrorBoundaries. | ||
|
||
## 0.9.7 (2022-06-14) | ||
|
||
- Fix Subscribe error on immediate unmount when running in React18 StrictMode | ||
|
||
## 0.9.6 (2022-04-29) | ||
|
||
- RemoveSubscribe | ||
|
||
New component that prevents its children from using a parent `<Subscribe>` to manage their subscriptions. | ||
|
||
- improve SUSPENSE types | ||
|
||
## 0.9.5 (2022-04-11) | ||
|
||
- upgrade dependencies (React 18) | ||
|
||
## 0.9.4 (2022-04-04) | ||
|
||
- utils: `toKeySet()` | ||
|
||
Operator that turns an `Observable<KeyChanges<K>>` into an `Observable<Set<K>>` | ||
|
||
- fix useStateObservable on StateObservables that emit synchronously without default value. | ||
- fix partitionByKey not emitting synchronously when a new group came in. | ||
|
||
## 0.9.3 (2022-03-30) | ||
|
||
- utils: Improve performance of `partitionByKey` with a big number of elements (#232) | ||
|
||
BREAKING CHANGE: partitionByKey's key stream now returns deltas `Observable<KeyChanges<K>>` instead of list of keys `Observable<K[]>`. Shouldn't have an impact if the stream was used directly into `combineKeys`. | ||
|
||
- fix Subscribe running in react18 StrictMode (#249) | ||
|
||
## 0.9.2 (2022-03-29) | ||
|
||
- fix React Native build | ||
|
||
## 0.9.1 (2022-03-27) | ||
|
||
- fix types for DefaultedStateObservable | ||
- fix compile error on Next.js 12 | ||
|
||
## 0.9.0 (2022-03-20) | ||
|
||
- `state()`, `useStateObservable()` | ||
|
||
There's a different way of creating and consuming observables now. | ||
|
||
Instead of calling `bind` which returns a hook and a shared observable, `state()` just returns the shared observable. This can be consumed in the components by using the hook `useStateObservable()`. | ||
|
||
```tsx | ||
const [useUser, user$] = bind(fetchUser()); | ||
|
||
const App = () => { | ||
const user = useUser(); | ||
|
||
... | ||
} | ||
|
||
// Becomes | ||
const user$ = state(fetchUser()); | ||
|
||
const App = () => { | ||
const user = useStateObservable(user$); | ||
|
||
... | ||
} | ||
``` |