diff --git a/package-lock.json b/package-lock.json
index afcdf52..ec64c49 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2864,10 +2864,11 @@
"dev": true
},
"node_modules/@types/use-sync-external-store": {
- "version": "0.0.3",
- "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz",
- "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==",
- "dev": true
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz",
+ "integrity": "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@types/yargs": {
"version": "17.0.33",
@@ -6892,7 +6893,7 @@
"use-sync-external-store": "^1.0.0"
},
"devDependencies": {
- "@types/use-sync-external-store": "^0.0.3"
+ "@types/use-sync-external-store": "^0.0.6"
},
"peerDependencies": {
"react": ">=16.8.0",
@@ -8321,7 +8322,7 @@
"version": "file:packages/core",
"requires": {
"@rx-state/core": "0.1.4",
- "@types/use-sync-external-store": "^0.0.3",
+ "@types/use-sync-external-store": "^0.0.6",
"use-sync-external-store": "^1.0.0"
}
},
@@ -8618,9 +8619,9 @@
"dev": true
},
"@types/use-sync-external-store": {
- "version": "0.0.3",
- "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz",
- "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==",
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz",
+ "integrity": "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==",
"dev": true
},
"@types/yargs": {
diff --git a/packages/core/package.json b/packages/core/package.json
index dfbc4b8..08400f1 100644
--- a/packages/core/package.json
+++ b/packages/core/package.json
@@ -53,9 +53,9 @@
],
"dependencies": {
"@rx-state/core": "0.1.4",
- "use-sync-external-store": "^1.0.0"
+ "use-sync-external-store": "^1.4.0"
},
"devDependencies": {
- "@types/use-sync-external-store": "^0.0.3"
+ "@types/use-sync-external-store": "^0.0.6"
}
}
diff --git a/packages/core/src/bind/connectFactoryObservable.test.tsx b/packages/core/src/bind/connectFactoryObservable.test.tsx
index bc9d23f..13575ea 100644
--- a/packages/core/src/bind/connectFactoryObservable.test.tsx
+++ b/packages/core/src/bind/connectFactoryObservable.test.tsx
@@ -84,17 +84,18 @@ describe("connectFactoryObservable", () => {
render()
- vi.waitFor(() => {
- expect(screen.queryByText("Result")).toBeNull()
- expect(screen.queryByText("Waiting")).not.toBeNull()
- })
+ expect(screen.queryByText("Result")).toBeNull()
+ expect(screen.queryByText("Waiting")).not.toBeNull()
await wait(110)
- vi.waitFor(() => {
- expect(screen.queryByText("Result 1")).not.toBeNull()
- expect(screen.queryByText("Waiting")).toBeNull()
- })
+ vi.waitFor(
+ () => {
+ expect(screen.queryByText("Result 1")).not.toBeNull()
+ expect(screen.queryByText("Waiting")).toBeNull()
+ },
+ { timeout: 2000 },
+ )
})
it("synchronously mounts the emitted value if the observable emits synchronously", () => {
@@ -114,10 +115,8 @@ describe("connectFactoryObservable", () => {
render()
- vi.waitFor(() => {
- expect(screen.queryByText("Result 1")).not.toBeNull()
- expect(screen.queryByText("Waiting")).toBeNull()
- })
+ expect(screen.queryByText("Result 1")).not.toBeNull()
+ expect(screen.queryByText("Waiting")).toBeNull()
})
it("doesn't mount the fallback element if the subscription is already active", () => {
@@ -139,10 +138,8 @@ describe("connectFactoryObservable", () => {
source$.next(1)
render()
- vi.waitFor(() => {
- expect(screen.queryByText("Result 1")).not.toBeNull()
- expect(screen.queryByText("Waiting")).toBeNull()
- })
+ expect(screen.queryByText("Result 1")).not.toBeNull()
+ expect(screen.queryByText("Waiting")).toBeNull()
subscription.unsubscribe()
})
@@ -234,7 +231,7 @@ describe("connectFactoryObservable", () => {
const [useDelayedNumber, getDelayedNumber$] = bind((x: number) =>
of(x).pipe(delay(50)),
)
- const Result: React.FC<{ input: number }> = (p) => (
+ const Result: React.FC = (p) => (
Result {useDelayedNumber(p.input)}
)
const TestSuspense: React.FC = () => {
@@ -254,50 +251,38 @@ describe("connectFactoryObservable", () => {
getDelayedNumber$(0).subscribe()
render()
- vi.waitFor(() => {
- expect(screen.queryByText("Result")).toBeNull()
- expect(screen.queryByText("Waiting")).not.toBeNull()
- })
+ expect(screen.queryByText("Result")).toBeNull()
+ expect(screen.queryByText("Waiting")).not.toBeNull()
await componentAct(async () => {
await getDelayedNumber$(0).pipe(first()).toPromise()
await wait(0)
})
- vi.waitFor(() => {
- expect(screen.queryByText("Result 0")).not.toBeNull()
- expect(screen.queryByText("Waiting")).toBeNull()
- })
+ expect(screen.queryByText("Result 0")).not.toBeNull()
+ expect(screen.queryByText("Waiting")).toBeNull()
componentAct(() => {
getDelayedNumber$(1).subscribe()
fireEvent.click(screen.getByText(/increase/i))
})
- vi.waitFor(() => {
- expect(screen.queryByText("Result")).toBeNull()
- expect(screen.queryByText("Waiting")).not.toBeNull()
- })
+ expect(screen.queryByText("Result")).toBeNull()
+ expect(screen.queryByText("Waiting")).not.toBeNull()
await componentAct(async () => {
await wait(60)
})
- vi.waitFor(() => {
- expect(screen.queryByText("Result 1")).not.toBeNull()
- expect(screen.queryByText("Waiting")).toBeNull()
- })
+ expect(screen.queryByText("Result 1")).not.toBeNull()
+ expect(screen.queryByText("Waiting")).toBeNull()
componentAct(() => {
getDelayedNumber$(2).subscribe()
fireEvent.click(screen.getByText(/increase/i))
})
- vi.waitFor(() => {
- expect(screen.queryByText("Result")).toBeNull()
- expect(screen.queryByText("Waiting")).not.toBeNull()
- })
+ expect(screen.queryByText("Result")).toBeNull()
+ expect(screen.queryByText("Waiting")).not.toBeNull()
await componentAct(async () => {
await wait(60)
})
- vi.waitFor(() => {
- expect(screen.queryByText("Result 2")).not.toBeNull()
- expect(screen.queryByText("Waiting")).toBeNull()
- })
+ expect(screen.queryByText("Result 2")).not.toBeNull()
+ expect(screen.queryByText("Waiting")).toBeNull()
})
it("shares the source subscription until the refCount has stayed at zero for the grace-period", async () => {
@@ -439,7 +424,7 @@ describe("connectFactoryObservable", () => {
.pipe(catchError(() => []))
.subscribe()
- const Ok: React.FC<{ ok: boolean }> = ({ ok }) => <>{useOkKo(ok)}>
+ const Ok: React.FC = ({ ok }) => <>{useOkKo(ok)}>
const ErrorComponent = () => {
const [ok, setOk] = useState(true)
@@ -459,20 +444,17 @@ describe("connectFactoryObservable", () => {
,
)
- vi.waitFor(() => {
- expect(screen.queryByText("ALL GOOD")).toBeNull()
- expect(screen.queryByText("Loading...")).not.toBeNull()
- })
+
+ expect(screen.queryByText("ALL GOOD")).toBeNull()
+ expect(screen.queryByText("Loading...")).not.toBeNull()
await componentAct(async () => {
normal$.next("ALL GOOD")
await wait(50)
})
- vi.waitFor(() => {
- expect(screen.queryByText("ALL GOOD")).not.toBeNull()
- expect(screen.queryByText("Loading...")).toBeNull()
- })
+ expect(screen.queryByText("ALL GOOD")).not.toBeNull()
+ expect(screen.queryByText("Loading...")).toBeNull()
expect(errorCallback).not.toHaveBeenCalled()
componentAct(() => {
@@ -688,9 +670,7 @@ describe("connectFactoryObservable", () => {
render()
- vi.waitFor(() => {
- expect(screen.queryByText("Waiting")).not.toBeNull()
- })
+ expect(screen.queryByText("Waiting")).not.toBeNull()
componentAct(() => {
ticks$.next()
})
@@ -859,7 +839,7 @@ describe("connectFactoryObservable", () => {
const [, obs$] = bind(
(key: number) => defer(() => obs$(key)).pipe(take(1)),
(key: number) => key,
- ) as [(key: number) => number, (key: number) => Observable]
+ ) as [(key: number) => number, (key: number) => Observable]
let error = null
obs$(1)
@@ -876,7 +856,7 @@ describe("connectFactoryObservable", () => {
it("does not crash when the factory function self-references its enhanced self", () => {
let nSubscriptions = 0
const [, me$] = bind(
- (key: number): Observable => {
+ (key: number): Observable => {
nSubscriptions++
return defer(() => me$(key)).pipe(
take(1),
diff --git a/packages/core/src/bind/connectObservable.test.tsx b/packages/core/src/bind/connectObservable.test.tsx
index 5970e34..96ca5d8 100644
--- a/packages/core/src/bind/connectObservable.test.tsx
+++ b/packages/core/src/bind/connectObservable.test.tsx
@@ -1,11 +1,13 @@
import {
+ act,
act as componentAct,
fireEvent,
render,
+ renderHook,
screen,
} from "@testing-library/react"
-import { act, renderHook } from "@testing-library/react"
import React, { FC, StrictMode, Suspense, useEffect, useState } from "react"
+import { renderToPipeableStream } from "react-dom/server"
import {
defer,
EMPTY,
@@ -26,7 +28,7 @@ import {
startWith,
switchMapTo,
} from "rxjs/operators"
-import { describe, it, beforeAll, afterAll, expect, vi } from "vitest"
+import { afterAll, beforeAll, describe, expect, it, vi } from "vitest"
import {
bind,
sinkSuspense,
@@ -34,9 +36,8 @@ import {
SUSPENSE,
useStateObservable,
} from "../"
-import { TestErrorBoundary } from "../test-helpers/TestErrorBoundary"
-import { renderToPipeableStream } from "react-dom/server"
import { pipeableStreamToObservable } from "../test-helpers/pipeableStreamToObservable"
+import { TestErrorBoundary } from "../test-helpers/TestErrorBoundary"
const wait = (ms: number) => new Promise((res) => setTimeout(res, ms))
@@ -88,18 +89,18 @@ describe("connectObservable", () => {
render()
- vi.waitFor(() => {
- expect(screen.queryByText("Result")).toBeNull()
- expect(screen.queryByText("Waiting")).not.toBeNull()
- })
+ expect(screen.queryByText("Result")).toBeNull()
+ expect(screen.queryByText("Waiting")).not.toBeNull()
- await wait(330)
-
- vi.waitFor(() => {
- expect(screen.queryByText("Result 1")).not.toBeNull()
- expect(screen.queryByText("Waiting")).toBeNull()
- })
+ await wait(110)
+ vi.waitFor(
+ () => {
+ expect(screen.queryByText("Result 1")).not.toBeNull()
+ expect(screen.queryByText("Waiting")).toBeNull()
+ },
+ { timeout: 2000 },
+ )
sub.unsubscribe()
})
@@ -118,18 +119,18 @@ describe("connectObservable", () => {
render()
- vi.waitFor(() => {
- expect(screen.queryByText("Result")).toBeNull()
- expect(screen.queryByText("Waiting")).not.toBeNull()
- })
+ expect(screen.queryByText("Result")).toBeNull()
+ expect(screen.queryByText("Waiting")).not.toBeNull()
await wait(110)
- vi.waitFor(() => {
- expect(screen.queryByText("Result 1")).not.toBeNull()
- expect(screen.queryByText("Waiting")).toBeNull()
- })
-
+ vi.waitFor(
+ () => {
+ expect(screen.queryByText("Result 1")).not.toBeNull()
+ expect(screen.queryByText("Waiting")).toBeNull()
+ },
+ { timeout: 2000 },
+ )
sub.unsubscribe()
})
@@ -193,9 +194,7 @@ describe("connectObservable", () => {
const [useNumber] = bind(numberStream, 1)
const [useString] = bind(stringStream, "a")
- const BatchComponent: FC<{
- onUpdate: () => void
- }> = ({ onUpdate }) => {
+ const BatchComponent: FC = ({ onUpdate }) => {
const number = useNumber()
const string = useString()
useEffect(onUpdate)
@@ -272,23 +271,17 @@ describe("connectObservable", () => {
render()
- vi.waitFor(() => {
- expect(screen.queryByText("Result 0")).not.toBeNull()
- expect(screen.queryByText("Waiting")).toBeNull()
- })
+ expect(screen.queryByText("Result 0")).not.toBeNull()
+ expect(screen.queryByText("Waiting")).toBeNull()
fireEvent.click(screen.getByText(/Next/i))
- vi.waitFor(() => {
- expect(screen.queryByText("Waiting")).not.toBeNull()
- })
+ expect(screen.queryByText("Waiting")).not.toBeNull()
fireEvent.click(screen.getByText(/Next/i))
- vi.waitFor(() => {
- expect(screen.queryByText("Result 2")).not.toBeNull()
- expect(screen.queryByText("Waiting")).toBeNull()
- })
+ expect(screen.queryByText("Result 2")).not.toBeNull()
+ expect(screen.queryByText("Waiting")).toBeNull()
})
it("keeps in suspense if more than two SUSPENSE are emitted in succesion", async () => {
@@ -318,33 +311,25 @@ describe("connectObservable", () => {
render()
- vi.waitFor(() => {
- expect(screen.queryByText("Result 0")).not.toBeNull()
- expect(screen.queryByText("Waiting")).toBeNull()
- })
+ expect(screen.queryByText("Result 0")).not.toBeNull()
+ expect(screen.queryByText("Waiting")).toBeNull()
fireEvent.click(screen.getByText(/Next/i))
- vi.waitFor(() => {
- expect(screen.queryByText("Waiting")).not.toBeNull()
- })
+ expect(screen.queryByText("Waiting")).not.toBeNull()
fireEvent.click(screen.getByText(/Next/i))
- vi.waitFor(() => {
- expect(screen.queryByText("Waiting")).not.toBeNull()
- })
+ expect(screen.queryByText("Waiting")).not.toBeNull()
fireEvent.click(screen.getByText(/Next/i))
- vi.waitFor(() => {
- expect(screen.queryByText("Result 3")).not.toBeNull()
- expect(screen.queryByText("Waiting")).toBeNull()
- })
+ expect(screen.queryByText("Result 3")).not.toBeNull()
+ expect(screen.queryByText("Waiting")).toBeNull()
})
it("doesn't enter suspense if the observable emits a promise", async () => {
- const subject$ = new Subject>()
+ const subject$ = new Subject()
const [usePromise, promise$] = bind(subject$, null)
const Result: React.FC = () => {
const value = usePromise()
@@ -371,17 +356,13 @@ describe("connectObservable", () => {
render()
- vi.waitFor(() => {
- expect(screen.queryByText("Waiting")).toBeNull()
- expect(screen.queryByText("default")).not.toBeNull()
- })
+ expect(screen.queryByText("Waiting")).toBeNull()
+ expect(screen.queryByText("default")).not.toBeNull()
act(() => subject$.next(new Promise(() => {})))
- vi.waitFor(() => {
- expect(screen.queryByText("Waiting")).toBeNull()
- expect(screen.queryByText("promise")).not.toBeNull()
- })
+ expect(screen.queryByText("Waiting")).toBeNull()
+ expect(screen.queryByText("promise")).not.toBeNull()
})
it("correctly unsubscribes when the Subscribe component gets unmounted", async () => {
@@ -408,10 +389,8 @@ describe("connectObservable", () => {
render()
- vi.waitFor(() => {
- expect(screen.queryByText("Result 0")).toBeNull()
- expect(screen.queryByText("Waiting")).not.toBeNull()
- })
+ expect(screen.queryByText("Result 0")).toBeNull()
+ expect(screen.queryByText("Waiting")).not.toBeNull()
fireEvent.click(screen.getByText(/NextVal/i))
@@ -433,9 +412,7 @@ describe("connectObservable", () => {
await wait(10)
- vi.waitFor(() => {
- expect(screen.queryByText("Waiting")).not.toBeNull()
- })
+ expect(screen.queryByText("Waiting")).not.toBeNull()
fireEvent.click(screen.getByText(/NextVal/i))
@@ -623,20 +600,16 @@ describe("connectObservable", () => {
,
)
- vi.waitFor(() => {
- expect(screen.queryByText("Loading...")).not.toBeNull()
- expect(screen.queryByText("ALL GOOD")).toBeNull()
- })
+ expect(screen.queryByText("Loading...")).not.toBeNull()
+ expect(screen.queryByText("ALL GOOD")).toBeNull()
await componentAct(async () => {
errStream.next("controlled error")
await wait(50)
})
- vi.waitFor(() => {
- expect(screen.queryByText("Loading...")).toBeNull()
- expect(screen.queryByText("ALL GOOD")).toBeNull()
- })
+ expect(screen.queryByText("Loading...")).toBeNull()
+ expect(screen.queryByText("ALL GOOD")).toBeNull()
expect(errorCallback).toHaveBeenCalledWith(
"controlled error",
expect.any(Object),
@@ -655,10 +628,7 @@ describe("connectObservable", () => {
,
)
-
- vi.waitFor(() => {
- expect(screen.queryByText("Loading...")).not.toBeNull()
- })
+ expect(screen.queryByText("Loading...")).not.toBeNull()
await componentAct(async () => {
nextStream.next("ALL GOOD")
@@ -669,9 +639,7 @@ describe("connectObservable", () => {
"controlled error",
expect.any(Object),
)
- vi.waitFor(() => {
- expect(screen.queryByText("ALL GOOD")).not.toBeNull()
- })
+ expect(screen.queryByText("ALL GOOD")).not.toBeNull()
})
it("doesn't throw errors on components that will get unmounted on the next cycle", () => {
@@ -768,18 +736,14 @@ describe("connectObservable", () => {
)
expect(errorCallback).not.toHaveBeenCalled()
- vi.waitFor(() => {
- expect(screen.queryByText("Loading...")).not.toBeNull()
- })
+ expect(screen.queryByText("Loading...")).not.toBeNull()
await componentAct(async () => {
subject.complete()
await wait(100)
})
- vi.waitFor(() => {
- expect(screen.queryByText("Loading...")).toBeNull()
- })
+ expect(screen.queryByText("Loading...")).toBeNull()
expect(errorCallback).toHaveBeenCalled()
})
@@ -882,27 +846,21 @@ describe("connectObservable", () => {
subject$.next(0)
})
- vi.waitFor(() => {
- expect(queryByText("Result 0")).not.toBeNull()
- expect(queryByText("Waiting")).toBeNull()
- })
+ expect(queryByText("Result 0")).not.toBeNull()
+ expect(queryByText("Waiting")).toBeNull()
act(() => {
subject$.next(SUSPENSE)
})
- vi.waitFor(() => {
- expect(queryByText("Waiting")).not.toBeNull()
- })
+ expect(queryByText("Waiting")).not.toBeNull()
act(() => {
subject$.next(1)
})
- vi.waitFor(() => {
- expect(queryByText("Result 1")).not.toBeNull()
- expect(queryByText("Waiting")).toBeNull()
- })
+ expect(queryByText("Result 1")).not.toBeNull()
+ expect(queryByText("Waiting")).toBeNull()
})
it("ignores effects while waiting for the first value", async () => {
@@ -920,33 +878,25 @@ describe("connectObservable", () => {
const { queryByText } = render()
- vi.waitFor(() => {
- expect(queryByText("Waiting")).not.toBeNull()
- })
+ expect(queryByText("Waiting")).not.toBeNull()
await act(async () => {
subject$.next(SUSPENSE)
})
- vi.waitFor(() => {
- expect(queryByText("Waiting")).not.toBeNull()
- })
+ expect(queryByText("Waiting")).not.toBeNull()
await act(async () => {
subject$.next(SUSPENSE)
await wait(10)
subject$.next(SUSPENSE)
})
- vi.waitFor(() => {
- expect(queryByText("Waiting")).not.toBeNull()
- })
+ expect(queryByText("Waiting")).not.toBeNull()
await act(async () => {
subject$.next(1)
})
- vi.waitFor(() => {
- expect(queryByText("Result 1")).not.toBeNull()
- expect(queryByText("Waiting")).toBeNull()
- })
+ expect(queryByText("Result 1")).not.toBeNull()
+ expect(queryByText("Waiting")).toBeNull()
})
it("ignores effects after entering suspense", async () => {
@@ -968,34 +918,26 @@ describe("connectObservable", () => {
subject$.next(0)
})
- vi.waitFor(() => {
- expect(queryByText("Result 0")).not.toBeNull()
- expect(queryByText("Waiting")).toBeNull()
- })
+ expect(queryByText("Result 0")).not.toBeNull()
+ expect(queryByText("Waiting")).toBeNull()
await act(async () => {
subject$.next(SUSPENSE)
})
- vi.waitFor(() => {
- expect(queryByText("Waiting")).not.toBeNull()
- })
+ expect(queryByText("Waiting")).not.toBeNull()
await act(async () => {
subject$.next(SUSPENSE)
await wait(10)
subject$.next(SUSPENSE)
})
- vi.waitFor(() => {
- expect(queryByText("Waiting")).not.toBeNull()
- })
+ expect(queryByText("Waiting")).not.toBeNull()
await act(async () => {
subject$.next(1)
})
- vi.waitFor(() => {
- expect(queryByText("Result 1")).not.toBeNull()
- expect(queryByText("Waiting")).toBeNull()
- })
+ expect(queryByText("Result 1")).not.toBeNull()
+ expect(queryByText("Waiting")).toBeNull()
})
it("emits the default value when an effect is received", () => {
@@ -1005,23 +947,17 @@ describe("connectObservable", () => {
const { queryByText } = render()
- vi.waitFor(() => {
- expect(queryByText("Result 10")).not.toBeNull()
- })
+ expect(queryByText("Result 10")).not.toBeNull()
act(() => {
subject$.next(5)
})
- vi.waitFor(() => {
- expect(queryByText("Result 5")).not.toBeNull()
- })
+ expect(queryByText("Result 5")).not.toBeNull()
act(() => {
subject$.next(SUSPENSE)
})
- vi.waitFor(() => {
- expect(queryByText("Result 10")).not.toBeNull()
- })
+ expect(queryByText("Result 10")).not.toBeNull()
})
describe("The hook on SSR", () => {