Skip to content

Commit 0624dec

Browse files
committed
[dynamicIO] reimplement dynamicIO validation on prerender
This updates the dynamic validation implementation to more closely follow the pattern used in prerenders for dynamicIO + PPR. Now that PPR is the only way to use dynamicIO we only have one implementation and the validation should match it as much as possible.
1 parent 5136f8e commit 0624dec

File tree

3 files changed

+283
-363
lines changed

3 files changed

+283
-363
lines changed

packages/next/src/server/app-render/app-render-prerender-utils.ts

Lines changed: 0 additions & 155 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { InvariantError } from '../../shared/lib/invariant-error'
2-
import { isPrerenderInterruptedError } from './dynamic-rendering'
32

43
/**
54
* This is a utility function to make scheduling sequential tasks that run back to back easier.
@@ -32,95 +31,6 @@ export function prerenderAndAbortInSequentialTasks<R>(
3231
}
3332
}
3433

35-
export function prerenderServerWithPhases(
36-
signal: AbortSignal,
37-
render: () => ReadableStream<Uint8Array>,
38-
finalPhase: () => void
39-
): Promise<ServerPrerenderStreamResult>
40-
export function prerenderServerWithPhases(
41-
signal: AbortSignal,
42-
render: () => ReadableStream<Uint8Array>,
43-
secondPhase: () => void,
44-
finalPhase: () => void
45-
): Promise<ServerPrerenderStreamResult>
46-
export function prerenderServerWithPhases(
47-
signal: AbortSignal,
48-
render: () => ReadableStream<Uint8Array>,
49-
secondPhase: () => void,
50-
thirdPhase: () => void,
51-
...remainingPhases: Array<() => void>
52-
): Promise<ServerPrerenderStreamResult>
53-
export function prerenderServerWithPhases(
54-
signal: AbortSignal,
55-
render: () => ReadableStream<Uint8Array>,
56-
...remainingPhases: Array<() => void>
57-
): Promise<ServerPrerenderStreamResult> {
58-
if (process.env.NEXT_RUNTIME === 'edge') {
59-
throw new InvariantError(
60-
'`prerenderAndAbortInSequentialTasks` should not be called in edge runtime.'
61-
)
62-
} else {
63-
return new Promise((resolve, reject) => {
64-
let result: ServerPrerenderStreamResult
65-
66-
signal.addEventListener(
67-
'abort',
68-
() => {
69-
if (isPrerenderInterruptedError(signal.reason)) {
70-
result.markInterrupted()
71-
} else {
72-
result.markComplete()
73-
}
74-
},
75-
{
76-
once: true,
77-
}
78-
)
79-
80-
setImmediate(() => {
81-
try {
82-
result = new ServerPrerenderStreamResult(render())
83-
} catch (err) {
84-
reject(err)
85-
}
86-
})
87-
88-
function runFinalTask(this: () => void) {
89-
try {
90-
if (result) {
91-
result.markComplete()
92-
this()
93-
}
94-
resolve(result)
95-
} catch (err) {
96-
reject(err)
97-
}
98-
}
99-
100-
function runNextTask(this: () => void) {
101-
try {
102-
if (result) {
103-
result.markPhase()
104-
this()
105-
}
106-
} catch (err) {
107-
reject(err)
108-
}
109-
}
110-
111-
let i = 0
112-
for (; i < remainingPhases.length - 1; i++) {
113-
const phase = remainingPhases[i]
114-
setImmediate(runNextTask.bind(phase))
115-
}
116-
if (remainingPhases[i]) {
117-
const finalPhase = remainingPhases[i]
118-
setImmediate(runFinalTask.bind(finalPhase))
119-
}
120-
})
121-
}
122-
}
123-
12434
const PENDING = 0
12535
const COMPLETE = 1
12636
const INTERRUPTED = 2
@@ -283,71 +193,6 @@ class PhasedStream<T> extends ReadableStream<T> {
283193
}
284194
}
285195

286-
export function prerenderClientWithPhases<T>(
287-
render: () => Promise<T>,
288-
finalPhase: () => void
289-
): Promise<T>
290-
export function prerenderClientWithPhases<T>(
291-
render: () => Promise<T>,
292-
secondPhase: () => void,
293-
finalPhase: () => void
294-
): Promise<T>
295-
export function prerenderClientWithPhases<T>(
296-
render: () => Promise<T>,
297-
secondPhase: () => void,
298-
thirdPhase: () => void,
299-
...remainingPhases: Array<() => void>
300-
): Promise<T>
301-
export function prerenderClientWithPhases<T>(
302-
render: () => Promise<T>,
303-
...remainingPhases: Array<() => void>
304-
): Promise<T> {
305-
if (process.env.NEXT_RUNTIME === 'edge') {
306-
throw new InvariantError(
307-
'`prerenderAndAbortInSequentialTasks` should not be called in edge runtime.'
308-
)
309-
} else {
310-
return new Promise((resolve, reject) => {
311-
let pendingResult: Promise<T>
312-
setImmediate(() => {
313-
try {
314-
pendingResult = render()
315-
pendingResult.catch((err) => reject(err))
316-
} catch (err) {
317-
reject(err)
318-
}
319-
})
320-
321-
function runFinalTask(this: () => void) {
322-
try {
323-
this()
324-
resolve(pendingResult)
325-
} catch (err) {
326-
reject(err)
327-
}
328-
}
329-
330-
function runNextTask(this: () => void) {
331-
try {
332-
this()
333-
} catch (err) {
334-
reject(err)
335-
}
336-
}
337-
338-
let i = 0
339-
for (; i < remainingPhases.length - 1; i++) {
340-
const phase = remainingPhases[i]
341-
setImmediate(runNextTask.bind(phase))
342-
}
343-
if (remainingPhases[i]) {
344-
const finalPhase = remainingPhases[i]
345-
setImmediate(runFinalTask.bind(finalPhase))
346-
}
347-
})
348-
}
349-
}
350-
351196
// React's RSC prerender function will emit an incomplete flight stream when using `prerender`. If the connection
352197
// closes then whatever hanging chunks exist will be errored. This is because prerender (an experimental feature)
353198
// has not yet implemented a concept of resume. For now we will simulate a paused connection by wrapping the stream

0 commit comments

Comments
 (0)