Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@
"other"
],
"dependencies": {
"@testing-library/dom": "^10.4.0",
"@testing-library/react": "^16.0.1",
"@testing-library/dom": "^10.4.2",
"@testing-library/react": "^16.3.3",
"jsdom": "^25.0.1",
"rehackt": "^0.1.0"
},
Expand All @@ -75,16 +75,16 @@
"@testing-library/user-event": "^14.5.2",
"@tsconfig/recommended": "^1.0.7",
"@types/jsdom": "^21.1.7",
"@types/react": "^18",
"@types/react-dom": "^18",
"@types/react": "^19.3.0",
"@types/react-dom": "^19.3.0",
"concurrently": "^9.0.1",
"expect": "^29.7.0",
"kcd-scripts": "^16.0.0",
"pkg-pr-new": "^0.0.29",
"prettier": "^3.3.3",
"publint": "^0.2.11",
"react": "19.0.0",
"react-dom": "19.0.0",
"react": "19.3.1",
"react-dom": "19.3.1",
"react-error-boundary": "^4.0.13",
"ts-jest-resolver": "^2.0.1",
"tsup": "^8.3.0",
Expand Down
20 changes: 19 additions & 1 deletion src/renderStream/createRenderStream.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,8 @@ export function createRenderStream<

let nextRender: Promise<Render<Snapshot, Q>> | undefined,
resolveNextRender: ((render: Render<Snapshot, Q>) => void) | undefined,
rejectNextRender: ((error: unknown) => void) | undefined
rejectNextRender: ((error: unknown) => void) | undefined,
resolveEffectsFlushed: (() => void) | undefined
function resetNextRender() {
nextRender = undefined
resolveNextRender = undefined
Expand Down Expand Up @@ -240,7 +241,20 @@ export function createRenderStream<
}

let iteratorPosition = 0
/**
* Since React 19.1, effects can run in a later task than their commit.
* `Wrapper` only rerenders on `render` and `rerender`, and parent effects run
* after child effects, so this resolves once all effects of that commit ran.
*/
function nextEffectsFlushed() {
return new Promise<void>(resolve => {
resolveEffectsFlushed = resolve
})
}
function Wrapper({children}: {children: React.ReactNode}) {
React.useEffect(() => {
resolveEffectsFlushed?.()
})
return (
<RenderStreamContextProvider value={renderStreamContext}>
<React.Profiler id="test" onRender={profilerOnRender}>
Expand All @@ -254,6 +268,7 @@ export function createRenderStream<
ui: React.ReactNode,
options?: RenderOptions<any, any, any>,
) => {
const effectsFlushed = nextEffectsFlushed()
const ret = await renderWithoutAct(ui, {
...options,
wrapper: props => {
Expand All @@ -268,9 +283,11 @@ export function createRenderStream<
if (stream.renders.length === 0) {
await stream.waitForNextRender()
}
await effectsFlushed
const origRerender = ret.rerender
ret.rerender = async function rerender(rerenderUi: React.ReactNode) {
const previousRenderCount = stream.renders.length
const rerenderEffectsFlushed = nextEffectsFlushed()
try {
return await origRerender(rerenderUi)
} finally {
Expand All @@ -279,6 +296,7 @@ export function createRenderStream<
if (previousRenderCount === stream.renders.length) {
await stream.waitForNextRender()
}
await rerenderEffectsFlushed
}
}
return ret
Expand Down
14 changes: 10 additions & 4 deletions src/renderWithoutAct.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ import {
// Ideally we'd just use a WeakMap where containers are keys and roots are values.
// We use two variables so that we can bail out in constant time when we render with a new container (most common use case)

const mountedContainers: Set<import('react-dom').Container> = new Set()
const mountedContainers: Set<ReactDOMClient.Container> = new Set()
const mountedRootEntries: Array<{
container: import('react-dom').Container
container: ReactDOMClient.Container
root: ReturnType<typeof createConcurrentRoot>
}> = []

Expand Down Expand Up @@ -187,13 +187,19 @@ async function _renderWithoutAct(
})
}

// `render` and `unmountComponentAtNode` only exist at runtime in React 16/17 and were removed from the React 19 types.
const LegacyReactDOM = ReactDOM as unknown as {
render(element: React.ReactElement, container: ReactDOMClient.Container): void
unmountComponentAtNode(container: ReactDOMClient.Container): boolean
}

function createLegacyRoot(container: ReactDOMClient.Container) {
return {
render(element: React.ReactNode) {
ReactDOM.render(element as unknown as React.ReactElement, container)
LegacyReactDOM.render(element as unknown as React.ReactElement, container)
},
unmount() {
ReactDOM.unmountComponentAtNode(container)
LegacyReactDOM.unmountComponentAtNode(container)
},
}
}
Expand Down
2 changes: 1 addition & 1 deletion tests/polyfill.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ import {TextEncoder, TextDecoder} from 'util'
global.TextEncoder = TextEncoder
global.TextDecoder = TextDecoder

Symbol.dispose = Symbol('Symbol.dispose')
if (!Symbol.dispose) Symbol.dispose = Symbol('Symbol.dispose')
111 changes: 55 additions & 56 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2598,19 +2598,19 @@ __metadata:
languageName: node
linkType: hard

"@testing-library/dom@npm:^10.4.0":
version: 10.4.0
resolution: "@testing-library/dom@npm:10.4.0"
"@testing-library/dom@npm:^10.4.2":
version: 10.4.2
resolution: "@testing-library/dom@npm:10.4.2"
dependencies:
"@babel/code-frame": "npm:^7.10.4"
"@babel/runtime": "npm:^7.12.5"
"@types/aria-query": "npm:^5.0.1"
aria-query: "npm:5.3.0"
chalk: "npm:^4.1.0"
dom-accessibility-api: "npm:^0.5.9"
lz-string: "npm:^1.5.0"
picocolors: "npm:1.1.1"
pretty-format: "npm:^27.0.2"
checksum: 10c0/0352487720ecd433400671e773df0b84b8268fb3fe8e527cdfd7c11b1365b398b4e0eddba6e7e0c85e8d615f48257753283fccec41f6b986fd6c85f15eb5f84f
checksum: 10c0/22c3aded3a54fc4f1a0c54aa75a881bb65e45f0128f3c5c881f9e571e593c6364c036f71b733dd0856ff2ba0debd59106e206f6764ee771dd8ed7cf82ceaa618
languageName: node
linkType: hard

Expand All @@ -2620,22 +2620,22 @@ __metadata:
dependencies:
"@arethetypeswrong/cli": "npm:^0.16.4"
"@jest/globals": "npm:^29.7.0"
"@testing-library/dom": "npm:^10.4.0"
"@testing-library/react": "npm:^16.0.1"
"@testing-library/dom": "npm:^10.4.2"
"@testing-library/react": "npm:^16.3.3"
"@testing-library/user-event": "npm:^14.5.2"
"@tsconfig/recommended": "npm:^1.0.7"
"@types/jsdom": "npm:^21.1.7"
"@types/react": "npm:^18"
"@types/react-dom": "npm:^18"
"@types/react": "npm:^19.3.0"
"@types/react-dom": "npm:^19.3.0"
concurrently: "npm:^9.0.1"
expect: "npm:^29.7.0"
jsdom: "npm:^25.0.1"
kcd-scripts: "npm:^16.0.0"
pkg-pr-new: "npm:^0.0.29"
prettier: "npm:^3.3.3"
publint: "npm:^0.2.11"
react: "npm:19.0.0"
react-dom: "npm:19.0.0"
react: "npm:19.3.1"
react-dom: "npm:19.3.1"
react-error-boundary: "npm:^4.0.13"
rehackt: "npm:^0.1.0"
ts-jest-resolver: "npm:^2.0.1"
Expand All @@ -2649,23 +2649,23 @@ __metadata:
languageName: unknown
linkType: soft

"@testing-library/react@npm:^16.0.1":
version: 16.0.1
resolution: "@testing-library/react@npm:16.0.1"
"@testing-library/react@npm:^16.3.3":
version: 16.3.3
resolution: "@testing-library/react@npm:16.3.3"
dependencies:
"@babel/runtime": "npm:^7.12.5"
peerDependencies:
"@testing-library/dom": ^10.0.0
"@types/react": ^18.0.0
"@types/react-dom": ^18.0.0
react: ^18.0.0
react-dom: ^18.0.0
"@types/react": ^18.0.0 || ^19.0.0
"@types/react-dom": ^18.0.0 || ^19.0.0
react: ^18.0.0 || ^19.0.0
react-dom: ^18.0.0 || ^19.0.0
peerDependenciesMeta:
"@types/react":
optional: true
"@types/react-dom":
optional: true
checksum: 10c0/67d05dec5ad5a2e6f92b6a3234af785435c7bb62bdbf12f3bfc89c9bca0c871a189e88c4ba023ed4cea504704c87c6ac7e86e24a3962df6c521ae89b62f48ff7
checksum: 10c0/87d65cca71a39c93fffa23746a751a7037a4b4e939ea6b234af5188e4bdec96a7568b05000db109b5b76c686899e93a329a594d7e690674e30b35594c87c9e1d
languageName: node
linkType: hard

Expand Down Expand Up @@ -2883,29 +2883,21 @@ __metadata:
languageName: node
linkType: hard

"@types/prop-types@npm:*":
version: 15.7.13
resolution: "@types/prop-types@npm:15.7.13"
checksum: 10c0/1b20fc67281902c6743379960247bc161f3f0406ffc0df8e7058745a85ea1538612109db0406290512947f9632fe9e10e7337bf0ce6338a91d6c948df16a7c61
languageName: node
linkType: hard

"@types/react-dom@npm:^18":
version: 18.3.0
resolution: "@types/react-dom@npm:18.3.0"
dependencies:
"@types/react": "npm:*"
checksum: 10c0/6c90d2ed72c5a0e440d2c75d99287e4b5df3e7b011838cdc03ae5cd518ab52164d86990e73246b9d812eaf02ec351d74e3b4f5bd325bf341e13bf980392fd53b
"@types/react-dom@npm:^19.3.0":
version: 19.3.0
resolution: "@types/react-dom@npm:19.3.0"
peerDependencies:
"@types/react": ^19.3.0
checksum: 10c0/ce0066d28b62bc6afdd17ca84756b8fbe0f6ffc0c8b1e60739abc30e81510da2edbc1007e6ab3d974d30f5a8c25bb0f7de8d7ce09736c909fe84c0f9aed0b946
languageName: node
linkType: hard

"@types/react@npm:*, @types/react@npm:^18":
version: 18.3.11
resolution: "@types/react@npm:18.3.11"
"@types/react@npm:^19.3.0":
version: 19.3.0
resolution: "@types/react@npm:19.3.0"
dependencies:
"@types/prop-types": "npm:*"
csstype: "npm:^3.0.2"
checksum: 10c0/ce80512246ca5bda69db85b9f4f1835189334acfb6b2c4f3eda8cabff1ff1a3ea9ce4f3b895bdbc18c94140aa45592331aa3fdeb557f525c1b048de7ce84fc0e
csstype: "npm:^3.2.2"
checksum: 10c0/fbcabf303f935ca9f36ed2dcf81751cf84744098c5a683c8a62a0fa7edd31714b48d5c46b12fd0014f7f2dfe4d9ec6de428a850748eec719a70294e51029551b
languageName: node
linkType: hard

Expand Down Expand Up @@ -4421,10 +4413,10 @@ __metadata:
languageName: node
linkType: hard

"csstype@npm:^3.0.2":
version: 3.1.3
resolution: "csstype@npm:3.1.3"
checksum: 10c0/80c089d6f7e0c5b2bd83cf0539ab41474198579584fa10d86d0cafe0642202343cbc119e076a0b1aece191989477081415d66c9fefbf3c957fc2fc4b7009f248
"csstype@npm:^3.2.2":
version: 3.2.3
resolution: "csstype@npm:3.2.3"
checksum: 10c0/cd29c51e70fa822f1cecd8641a1445bed7063697469d35633b516e60fe8c1bde04b08f6c5b6022136bb669b64c63d4173af54864510fbb4ee23281801841a3ce
languageName: node
linkType: hard

Expand Down Expand Up @@ -8865,6 +8857,13 @@ __metadata:
languageName: node
linkType: hard

"picocolors@npm:1.1.1":
version: 1.1.1
resolution: "picocolors@npm:1.1.1"
checksum: 10c0/e2e3e8170ab9d7c7421969adaa7e1b31434f789afb9b3f115f6b96d91945041ac3ceb02e9ec6fe6510ff036bcc0bf91e69a1772edc0b707e12b19c0f2d6bcf58
languageName: node
linkType: hard

"picocolors@npm:^1.0.0, picocolors@npm:^1.0.1, picocolors@npm:^1.1.0":
version: 1.1.0
resolution: "picocolors@npm:1.1.0"
Expand Down Expand Up @@ -9169,14 +9168,14 @@ __metadata:
languageName: node
linkType: hard

"react-dom@npm:19.0.0":
version: 19.0.0
resolution: "react-dom@npm:19.0.0"
"react-dom@npm:19.3.1":
version: 19.3.1
resolution: "react-dom@npm:19.3.1"
dependencies:
scheduler: "npm:^0.25.0"
scheduler: "npm:^0.28.0"
peerDependencies:
react: ^19.0.0
checksum: 10c0/a36ce7ab507b237ae2759c984cdaad4af4096d8199fb65b3815c16825e5cfeb7293da790a3fc2184b52bfba7ba3ff31c058c01947aff6fd1a3701632aabaa6a9
react: ^19.3.1
checksum: 10c0/382700916313b2ebc46acee80642f300bb8601eac6a9e7fefade5b8b30e66b05bf3aaa56a3c964589fcd578d27b486e847470c2697d879264e766661ff49fac7
languageName: node
linkType: hard

Expand Down Expand Up @@ -9212,10 +9211,10 @@ __metadata:
languageName: node
linkType: hard

"react@npm:19.0.0":
version: 19.0.0
resolution: "react@npm:19.0.0"
checksum: 10c0/9cad8f103e8e3a16d15cb18a0d8115d8bd9f9e1ce3420310aea381eb42aa0a4f812cf047bb5441349257a05fba8a291515691e3cb51267279b2d2c3253f38471
"react@npm:19.3.1":
version: 19.3.1
resolution: "react@npm:19.3.1"
checksum: 10c0/f0ed036d1223562c09c8347858ca712733ea6e27a30db709ee9c3f3f176d3e9e767afce735d59956addf3d030102e256bba82dea635fc1bdb0e01107e98fef10
languageName: node
linkType: hard

Expand Down Expand Up @@ -9709,10 +9708,10 @@ __metadata:
languageName: node
linkType: hard

"scheduler@npm:^0.25.0":
version: 0.25.0
resolution: "scheduler@npm:0.25.0"
checksum: 10c0/a4bb1da406b613ce72c1299db43759526058fdcc413999c3c3e0db8956df7633acf395cb20eb2303b6a65d658d66b6585d344460abaee8080b4aa931f10eaafe
"scheduler@npm:^0.28.0":
version: 0.28.0
resolution: "scheduler@npm:0.28.0"
checksum: 10c0/783c8e5ce89d41273a02ed6dc0e3d24bd60e05c9e8f7e3adfc6c82e7c69935500d90e343f1ee26d592fc7504e8a2532573c6368def3e93bfe812391fa53efaf4
languageName: node
linkType: hard

Expand Down
Loading