@@ -9,22 +9,20 @@ import assetsPn from '../plugins/assets.js';
9
9
import compressionPn from '../plugins/compression.js' ;
10
10
import errorsPn from '../plugins/errors.js' ;
11
11
import exceptionsPn from '../plugins/exceptions.js' ;
12
- import hydratePn from '../plugins/hydrate.js' ;
13
12
import importElementPn from '../plugins/import-element.js' ;
14
13
import liveReloadPn from '../plugins/live-reload.js' ;
15
14
import localePn from '../plugins/locale.js' ;
16
15
import metricsPn from '../plugins/metrics.js' ;
17
16
import podletPn from '../plugins/podlet.js' ;
18
- import scriptPn from '../plugins/script.js' ;
19
17
import timingPn from '../plugins/timing.js' ;
20
18
import validationPn from '../plugins/validation.js' ;
21
19
import lazyPn from '../plugins/lazy.js' ;
22
20
import scriptsPn from '../plugins/scripts.js' ;
23
- import ssrPn from '../plugins/ssr.js' ;
24
- import csrPn from '../plugins/csr.js' ;
25
21
import documentPn from '../plugins/document.js' ;
26
22
import docsPn from '../plugins/docs.js' ;
27
23
import bundlerPn from '../plugins/bundler.js' ;
24
+ import modeSupportPn from '../plugins/mode-support.js' ;
25
+ import hydrateSupportPn from '../plugins/hydrate-support.js' ;
28
26
import { isAbsoluteURL , joinURLPathSegments } from './utils.js' ;
29
27
30
28
const defaults = {
@@ -35,7 +33,7 @@ const defaults = {
35
33
36
34
/**
37
35
* create an intersection type out of fastify instance and its decorated properties
38
- * @typedef {import("fastify").FastifyInstance & { podlet: any, metrics: any, schemas: any, importElement: function, readTranslations: function, script: function, hydrate : function, ssr: function, csr : function } } FastifyInstance
36
+ * @typedef {import("fastify").FastifyInstance & { podlet: any, metrics: any, schemas: any, importElement: function, readTranslations: function, script: function, serverRender : function, clientRender : function } } FastifyInstance
39
37
*/
40
38
41
39
/**
@@ -47,7 +45,7 @@ export default fp(
47
45
/**
48
46
*
49
47
* @param {import("fastify").FastifyInstance } fastify
50
- * @param {{ prefix: string, extensions: import("./resolvers/extensions.js").Extensions, cwd: string, plugins: import("esbuild").Plugin[], config: import("convict").Config, webSocketServer?: import("ws").WebSocketServer, clientWatcher?: import("chokidar").FSWatcher } } options
48
+ * @param {{ prefix? : string, extensions? : import("./resolvers/extensions.js").Extensions, cwd? : string, plugins? : import("esbuild").Plugin[], config: import("convict").Config, webSocketServer?: import("ws").WebSocketServer, clientWatcher?: import("chokidar").FSWatcher } } options
51
49
*/
52
50
async (
53
51
fastify ,
@@ -112,6 +110,12 @@ export default fp(
112
110
fallback,
113
111
development,
114
112
} ) ;
113
+ await f . register ( hydrateSupportPn , {
114
+ enabled : mode === 'hydrate' ,
115
+ base,
116
+ development,
117
+ prefix,
118
+ } ) ;
115
119
await f . register ( lazyPn , { enabled : lazy , base, development, prefix } ) ;
116
120
await f . register ( scriptsPn , {
117
121
enabled : scripts ,
@@ -132,19 +136,12 @@ export default fp(
132
136
await f . register ( assetsPn , { base, cwd } ) ;
133
137
await f . register ( bundlerPn , { cwd, development, plugins } ) ;
134
138
await f . register ( exceptionsPn , { grace, development } ) ;
135
- await f . register ( hydratePn , {
136
- appName : name ,
137
- base : assetBase ,
138
- development,
139
- prefix,
140
- } ) ;
141
- await f . register ( csrPn , {
139
+ await f . register ( modeSupportPn , {
142
140
appName : name ,
143
141
base : assetBase ,
144
142
development,
145
143
prefix,
146
144
} ) ;
147
- await f . register ( ssrPn , { appName : name , base, prefix, development } ) ;
148
145
await f . register ( importElementPn , {
149
146
appName : name ,
150
147
development,
@@ -153,7 +150,6 @@ export default fp(
153
150
} ) ;
154
151
await f . register ( localePn , { locale, cwd } ) ;
155
152
await f . register ( metricsPn ) ;
156
- await f . register ( scriptPn , { development } ) ;
157
153
await f . register ( timingPn , {
158
154
timeAllRoutes,
159
155
groupStatusCodes,
@@ -175,58 +171,34 @@ export default fp(
175
171
// routes
176
172
if ( existsSync ( contentFilePath ) ) {
177
173
const tag = unsafeStatic ( `${ name } -content` ) ;
174
+
175
+ // mount content route
178
176
f . get ( f . podlet . content ( ) , async ( request , reply ) => {
179
177
try {
180
178
const contextConfig = /** @type {FastifyContextConfig } */ (
181
179
reply . context . config
182
180
) ;
183
181
contextConfig . timing = true ;
184
182
185
- if ( mode === 'ssr-only' || mode === 'hydrate' ) {
186
- // import server side component
187
- await f . importElement ( contentFilePath ) ;
188
- }
189
-
183
+ // use developer provided content state function to generate initial content state
190
184
const initialState = JSON . stringify (
191
185
// @ts -ignore
192
186
( await contentStateFn ( request , reply . app . podium . context ) ) || '' ,
193
187
) ;
194
188
195
189
const messages = await f . readTranslations ( ) ;
196
-
197
190
const translations = messages ? JSON . stringify ( messages ) : '' ;
198
191
199
192
// includes ${null} hack for SSR. See https://github.com/lit/lit/issues/2246
200
- const template = html `
201
- < ${ tag } version ="${ version } " locale='${ locale } ' translations='${ translations } '
202
- initial-state='${ initialState } '> </ ${ tag } > ${ null } ` ;
203
- const hydrateSupport =
204
- mode === 'hydrate'
205
- ? f . script (
206
- joinURLPathSegments (
207
- prefix ,
208
- '/_/dynamic/modules/@lit-labs/ssr-client/lit-element-hydrate-support.js' ,
209
- ) ,
210
- { dev : true } ,
211
- )
212
- : '' ;
213
- let markup ;
214
- if ( mode === 'ssr-only' ) {
215
- markup = f . ssr ( 'content' , template ) ;
216
- } else if ( mode === 'csr-only' ) {
217
- markup = f . csr (
218
- 'content' ,
219
- `<${ name } -content version="${ version } " locale='${ locale } ' translations='${ translations } ' initial-state='${ initialState } '></${ name } -content>` ,
220
- ) ;
221
- } else {
222
- markup = f . hydrate ( 'content' , template ) ;
223
- }
193
+ const template = html `< ${ tag } version ="${ version } " locale='${ locale } ' translations='${ translations } ' initial-state='${ initialState } '> </ ${ tag } > ${ null } ` ;
224
194
225
- reply
226
- . type ( 'text/html; charset=utf-8' )
227
- . send ( `${ hydrateSupport } ${ markup } ` ) ;
195
+ reply . type ( 'text/html; charset=utf-8' ) ;
228
196
229
- return reply ;
197
+ if ( mode === 'csr-only' )
198
+ return reply . send ( f . clientRender ( 'content' , template ) ) ;
199
+ // import the custom element for server side use
200
+ await f . importElement ( contentFilePath ) ;
201
+ return reply . send ( f . serverRender ( 'content' , template ) ) ;
230
202
} catch ( err ) {
231
203
f . log . error ( err ) ;
232
204
return reply ;
@@ -236,56 +208,35 @@ export default fp(
236
208
237
209
if ( existsSync ( fallbackFilePath ) ) {
238
210
const tag = unsafeStatic ( `${ name } -fallback` ) ;
211
+
212
+ // mount fallback route
239
213
f . get ( f . podlet . fallback ( ) , async ( request , reply ) => {
240
214
try {
241
215
const contextConfig = /** @type {FastifyContextConfig } */ (
242
216
reply . context . config
243
217
) ;
244
218
contextConfig . timing = true ;
245
219
246
- if ( mode === 'ssr-only' || mode === 'hydrate' ) {
247
- // import server side component
248
- await f . importElement ( fallbackFilePath ) ;
249
- }
250
-
220
+ // use developer provided fallback state function to generate initial fallback state
251
221
const initialState = JSON . stringify (
252
222
// @ts -ignore
253
223
( await fallbackStateFn ( request , reply . app . podium . context ) ) ||
254
224
'' ,
255
225
) ;
256
226
257
227
const messages = await f . readTranslations ( ) ;
258
-
259
228
const translations = messages ? JSON . stringify ( messages ) : '' ;
260
- const template = html `
261
- < ${ tag } version ="${ version } " locale='${ locale } ' translations='${ translations } '
262
- initial-state='${ initialState } '> </ ${ tag } > ${ null } ` ;
263
- const hydrateSupport =
264
- mode === 'hydrate'
265
- ? f . script (
266
- joinURLPathSegments (
267
- prefix ,
268
- '/_/dynamic/modules/@lit-labs/ssr-client/lit-element-hydrate-support.js' ,
269
- ) ,
270
- { dev : true } ,
271
- )
272
- : '' ;
273
- let markup ;
274
- if ( mode !== 'ssr-only' ) {
275
- markup = f . ssr ( 'fallback' , template ) ;
276
- } else if ( mode === 'csr-only' ) {
277
- markup = f . csr (
278
- 'fallback' ,
279
- `<${ name } -fallback version="${ version } " locale='${ locale } ' translations='${ translations } ' initial-state='${ initialState } '></${ name } -fallback>` ,
280
- ) ;
281
- } else {
282
- markup = f . hydrate ( 'fallback' , template ) ;
283
- }
284
- reply
285
- . type ( 'text/html; charset=utf-8' )
286
- . send ( `${ hydrateSupport } ${ markup } ` ) ;
287
229
288
- return reply ;
230
+ // includes ${null} hack for SSR. See https://github.com/lit/lit/issues/2246
231
+ const template = html `< ${ tag } version ="${ version } " locale='${ locale } ' translations='${ translations } ' initial-state='${ initialState } '> </ ${ tag } > ${ null } ` ;
232
+
233
+ reply . type ( 'text/html; charset=utf-8' ) ;
234
+
235
+ if ( mode === 'csr-only' )
236
+ return reply . send ( f . clientRender ( 'fallback' , template ) ) ;
237
+ // import the custom element for server side use
238
+ await f . importElement ( fallbackFilePath ) ;
239
+ return reply . send ( f . serverRender ( 'fallback' , template ) ) ;
289
240
} catch ( err ) {
290
241
f . log . error ( err ) ;
291
242
return reply ;
0 commit comments