1
+/**
2
+ * Copyright (c) Facebook, Inc. and its affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @flow
8
+ */
9
+
10
+import type {SuspenseBoundaryID} from './ReactDOMServerFormatConfig';
11
+
12
+import {
13
+ createResponseState as createResponseStateImpl,
14
+ pushTextInstance as pushTextInstanceImpl,
15
+ writeStartCompletedSuspenseBoundary as writeStartCompletedSuspenseBoundaryImpl,
16
+ writeStartClientRenderedSuspenseBoundary as writeStartClientRenderedSuspenseBoundaryImpl,
17
+ writeEndCompletedSuspenseBoundary as writeEndCompletedSuspenseBoundaryImpl,
18
+ writeEndClientRenderedSuspenseBoundary as writeEndClientRenderedSuspenseBoundaryImpl,
19
+} from './ReactDOMServerFormatConfig';
20
+
21
+import type {
22
+ Destination,
23
+ Chunk,
24
+ PrecomputedChunk,
25
+} from 'react-server/src/ReactServerStreamConfig';
26
+
27
+export const isPrimaryRenderer = false;
28
+
29
+export type ResponseState = {
30
+ // Keep this in sync with ReactDOMServerFormatConfig
31
+ placeholderPrefix: PrecomputedChunk,
32
+ segmentPrefix: PrecomputedChunk,
33
+ boundaryPrefix: string,
34
+ opaqueIdentifierPrefix: string,
35
+ nextSuspenseID: number,
36
+ nextOpaqueID: number,
37
+ sentCompleteSegmentFunction: boolean,
38
+ sentCompleteBoundaryFunction: boolean,
39
+ sentClientRenderFunction: boolean,
40
+ // This is an extra field for the legacy renderer
41
+ generateStaticMarkup: boolean,
42
+};
43
+
44
+export function createResponseState(
45
+ generateStaticMarkup: boolean,
46
+ identifierPrefix: string | void,
47
+): ResponseState {
48
+ const responseState = createResponseStateImpl(identifierPrefix);
49
+ return {
50
+ // Keep this in sync with ReactDOMServerFormatConfig
51
+ placeholderPrefix: responseState.placeholderPrefix,
52
+ segmentPrefix: responseState.segmentPrefix,
53
+ boundaryPrefix: responseState.boundaryPrefix,
54
+ opaqueIdentifierPrefix: responseState.opaqueIdentifierPrefix,
55
+ nextSuspenseID: responseState.nextSuspenseID,
56
+ nextOpaqueID: responseState.nextOpaqueID,
57
+ sentCompleteSegmentFunction: responseState.sentCompleteSegmentFunction,
58
+ sentCompleteBoundaryFunction: responseState.sentCompleteBoundaryFunction,
59
+ sentClientRenderFunction: responseState.sentClientRenderFunction,
60
+ // This is an extra field for the legacy renderer
61
+ generateStaticMarkup,
62
+ };
63
+}
64
+
65
+export type {
66
+ FormatContext,
67
+ SuspenseBoundaryID,
68
+ OpaqueIDType,
69
+} from './ReactDOMServerFormatConfig';
70
+
71
+export {
72
+ createRootFormatContext,
73
+ getChildFormatContext,
74
+ createSuspenseBoundaryID,
75
+ makeServerID,
76
+ pushEmpty,
77
+ pushStartInstance,
78
+ pushEndInstance,
79
+ writeStartSegment,
80
+ writeEndSegment,
81
+ writeCompletedSegmentInstruction,
82
+ writeCompletedBoundaryInstruction,
83
+ writeClientRenderBoundaryInstruction,
84
+ writeStartPendingSuspenseBoundary,
85
+ writeEndPendingSuspenseBoundary,
86
+ writePlaceholder,
87
+} from './ReactDOMServerFormatConfig';
88
+
89
+import {stringToChunk} from 'react-server/src/ReactServerStreamConfig';
90
+
91
+import escapeTextForBrowser from './escapeTextForBrowser';
92
+
93
+export function pushTextInstance(
94
+ target: Array<Chunk | PrecomputedChunk>,
95
+ text: string,
96
+ responseState: ResponseState,
97
+ assignID: null | SuspenseBoundaryID,
98
+): void {
99
+ if (responseState.generateStaticMarkup) {
100
+ target.push(stringToChunk(escapeTextForBrowser(text)));
101
+ } else {
102
+ pushTextInstanceImpl(target, text, responseState, assignID);
103
+ }
104
+}
105
+
106
+export function writeStartCompletedSuspenseBoundary(
107
+ destination: Destination,
108
+ responseState: ResponseState,
109
+ id: SuspenseBoundaryID,
110
+): boolean {
111
+ if (responseState.generateStaticMarkup) {
112
+ // A completed boundary is done and doesn't need a representation in the HTML
113
+ // if we're not going to be hydrating it.
114
+ return true;
115
+ }
116
+ return writeStartCompletedSuspenseBoundaryImpl(
117
+ destination,
118
+ responseState,
119
+ id,
120
+ );
121
+}
122
+export function writeStartClientRenderedSuspenseBoundary(
123
+ destination: Destination,
124
+ responseState: ResponseState,
125
+ id: SuspenseBoundaryID,
126
+): boolean {
127
+ if (responseState.generateStaticMarkup) {
128
+ // A client rendered boundary is done and doesn't need a representation in the HTML
129
+ // since we'll never hydrate it. This is arguably an error in static generation.
130
+ return true;
131
+ }
132
+ return writeStartClientRenderedSuspenseBoundaryImpl(
133
+ destination,
134
+ responseState,
135
+ id,
136
+ );
137
+}
138
+export function writeEndCompletedSuspenseBoundary(
139
+ destination: Destination,
140
+ responseState: ResponseState,
141
+): boolean {
142
+ if (responseState.generateStaticMarkup) {
143
+ return true;
144
+ }
145
+ return writeEndCompletedSuspenseBoundaryImpl(destination, responseState);
146
+}
147
+export function writeEndClientRenderedSuspenseBoundary(
148
+ destination: Destination,
149
+ responseState: ResponseState,
150
+): boolean {
151
+ if (responseState.generateStaticMarkup) {
152
+ return true;
153
+ }
154
+ return writeEndClientRenderedSuspenseBoundaryImpl(destination, responseState);
155
+}