vitrify 0.19.1 → 0.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -32,11 +32,6 @@ const fastifySsrPlugin = async (fastify, options) => {
32
32
  try {
33
33
  const url = req.raw.url?.replace(options.baseUrl, '/');
34
34
  const provide = options.provide ? await options.provide(req, res) : {};
35
- const ssrContext = {
36
- req,
37
- res,
38
- provide
39
- };
40
35
  let template = readFileSync(new URL('index.html', frameworkDir)).toString();
41
36
  template = await vite.transformIndexHtml(url, template);
42
37
  const entryUrl = fileURLToPath(new URL('ssr/entry-server.ts', frameworkDir));
@@ -49,39 +44,16 @@ const fastifySsrPlugin = async (fastify, options) => {
49
44
  catch (e) {
50
45
  manifest = {};
51
46
  }
52
- // const cssModules = [entryUrl]
53
- // const matchedModules = componentsModules(cssModules, vite!)
54
- // const css = collectCss({
55
- // mods: matchedModules
56
- // })
57
- const [appHtml, preloadLinks] = await render(url, manifest, ssrContext);
58
- if (!ssrContext.initialState)
59
- ssrContext.initialState = {};
60
- ssrContext.initialState.provide = provide;
61
- const initialStateScript = `
62
- <script>
63
- __INITIAL_STATE__ = '${JSON.stringify(ssrContext.initialState)}'
64
- </script>`;
65
- const renderHtml = (html) => {
66
- return appendToHead(preloadLinks, appendToBody(initialStateScript, addOrReplaceAppDiv(appHtml, html)));
67
- };
68
- let html = renderHtml(template);
69
- // let html = template
70
- // .replace(`<!--app-html-->`, appHtml)
71
- // .replace('<!--product-name-->', options.productName || 'Product name')
72
- // // .replace('<!--dev-ssr-css-->', css)
73
- // .replace(
74
- // '<!--initial-state-->',
75
- // `<script>
76
- // __INITIAL_STATE__ = '${JSON.stringify(ssrContext.initialState)}'
77
- // </script>`
78
- // )
79
- // html = appendToHead(preloadLinks, html)
80
- if (options.onRendered?.length) {
81
- for (const ssrFunction of options.onRendered) {
82
- html = ssrFunction(html, ssrContext);
83
- }
84
- }
47
+ const html = await renderHtml({
48
+ request: req,
49
+ reply: res,
50
+ url: url ?? '/',
51
+ provide,
52
+ onRendered: options.onRendered,
53
+ template,
54
+ manifest,
55
+ render
56
+ });
85
57
  res.code(200);
86
58
  res.type('text/html');
87
59
  res.send(html);
@@ -108,42 +80,55 @@ const fastifySsrPlugin = async (fastify, options) => {
108
80
  fastify.get(`${options.baseUrl}*`, async (req, res) => {
109
81
  const url = req.raw.url?.replace(options.baseUrl, '/');
110
82
  const provide = options.provide ? await options.provide(req, res) : {};
111
- const ssrContext = {
112
- req,
113
- res,
114
- provide
115
- };
116
83
  const template = readFileSync(fileURLToPath(new URL('./dist/ssr/client/index.html', options.appDir))).toString();
117
84
  const manifest = JSON.parse(readFileSync(new URL('./dist/ssr/client/.vite/ssr-manifest.json', options.appDir)).toString());
118
85
  const render = (await import(fileURLToPath(new URL('./dist/ssr/server/entry-server.mjs', options.appDir)))).render;
119
- const [appHtml, preloadLinks] = await render(url, manifest, ssrContext);
120
- if (!ssrContext.initialState)
121
- ssrContext.initialState = {};
122
- ssrContext.initialState.provide = provide;
123
- const initialStateScript = `
124
- <script>
125
- __INITIAL_STATE__ = '${JSON.stringify(ssrContext.initialState)}'
126
- </script>`;
127
- const renderHtml = (html) => {
128
- return appendToHead(preloadLinks, appendToBody(initialStateScript, addOrReplaceAppDiv(appHtml, html)));
129
- };
130
- let html = renderHtml(template);
131
- // let html = template.replace(`<!--app-html-->`, appHtml).replace(
132
- // '<!--initial-state-->',
133
- // `<script>
134
- // __INITIAL_STATE__ = '${JSON.stringify(ssrContext.initialState)}'
135
- // </script>`
136
- // )
137
- // html = appendToHead(preloadLinks, html)
138
- if (options.onRendered?.length) {
139
- for (const ssrFunction of options.onRendered) {
140
- html = ssrFunction(html, ssrContext);
141
- }
142
- }
86
+ const onRendered = (await import(fileURLToPath(new URL('./dist/ssr/server/virtual_vitrify-hooks.mjs', options.appDir)))).onRendered;
87
+ const html = await renderHtml({
88
+ request: req,
89
+ reply: res,
90
+ url: url ?? '/',
91
+ provide,
92
+ onRendered,
93
+ template,
94
+ manifest,
95
+ render
96
+ });
143
97
  res.code(200);
144
98
  res.type('text/html');
145
99
  res.send(html);
146
100
  });
147
101
  }
148
102
  };
149
- export { fastifySsrPlugin };
103
+ const renderTemplate = ({ template, initialStateScript, appHtml, preloadLinks }) => {
104
+ return appendToHead(preloadLinks, appendToBody(initialStateScript, addOrReplaceAppDiv(appHtml, template)));
105
+ };
106
+ const renderHtml = async (options) => {
107
+ const ssrContext = {
108
+ req: options.request,
109
+ res: options.reply,
110
+ provide: options.provide
111
+ };
112
+ const onRendered = options.onRendered ?? [];
113
+ const [appHtml, preloadLinks] = await options.render(options.url, options.manifest, ssrContext);
114
+ if (!ssrContext.initialState)
115
+ ssrContext.initialState = {};
116
+ ssrContext.initialState.provide = options.provide;
117
+ const initialStateScript = `
118
+ <script>
119
+ __INITIAL_STATE__ = '${JSON.stringify(ssrContext.initialState)}'
120
+ </script>`;
121
+ let html = renderTemplate({
122
+ template: options.template,
123
+ appHtml,
124
+ initialStateScript,
125
+ preloadLinks
126
+ });
127
+ if (onRendered?.length) {
128
+ for (const ssrFunction of onRendered) {
129
+ html = ssrFunction(html, ssrContext);
130
+ }
131
+ }
132
+ return html;
133
+ };
134
+ export { fastifySsrPlugin, renderHtml };
@@ -1,6 +1,6 @@
1
1
  import { existsSync, promises as fs, mkdirSync } from 'fs';
2
2
  import { routesToPaths } from '../../helpers/routes.js';
3
- import { appendToHead, addOrReplaceAppDiv } from '../../helpers/utils.js';
3
+ import { renderHtml } from './fastify-ssr-plugin.js';
4
4
  export const prerender = async ({ outDir, templatePath, manifestPath, entryServerPath, onRendered }) => {
5
5
  const promises = [];
6
6
  const template = (await fs.readFile(templatePath)).toString();
@@ -22,18 +22,16 @@ export const prerender = async ({ outDir, templatePath, manifestPath, entryServe
22
22
  }
23
23
  const filename = (url.endsWith('/') ? 'index' : url.replace(/^\//g, '')) + '.html';
24
24
  console.log(`Generating ${filename}`);
25
- const ssrContext = {
26
- req: { headers: {}, url },
27
- res: {}
28
- };
29
- const [appHtml, preloadLinks] = await render(url, manifest, ssrContext);
30
- let html = addOrReplaceAppDiv(appHtml, template);
31
- html = appendToHead(preloadLinks, html);
32
- if (onRendered?.length) {
33
- for (const ssrFunction of onRendered) {
34
- html = ssrFunction(html, ssrContext);
35
- }
36
- }
25
+ let html = await renderHtml({
26
+ url,
27
+ manifest,
28
+ provide: {},
29
+ render,
30
+ request: { headers: {}, url },
31
+ reply: {},
32
+ template,
33
+ onRendered
34
+ });
37
35
  html = await beasties.process(html);
38
36
  promises.push(fs.writeFile(outDir + filename, html, 'utf-8'));
39
37
  }
package/dist/index.js CHANGED
@@ -528,6 +528,7 @@ export const baseConfig = async ({ ssr, appDir, publicDir, base = '/', command =
528
528
  input: [
529
529
  fileURLToPath(new URL('ssr/entry-server.ts', frameworkDir)),
530
530
  fileURLToPath(new URL('ssr/prerender.ts', frameworkDir)),
531
+ fileURLToPath(new URL('ssr/fastify-ssr-plugin.ts', frameworkDir)),
531
532
  fileURLToPath(new URL('ssr/server.ts', frameworkDir))
532
533
  ],
533
534
  external,
@@ -1,11 +1,12 @@
1
1
  import type { FastifyPluginAsync, FastifyRequest, FastifyReply } from 'fastify';
2
2
  import type { ViteDevServer } from 'vite';
3
3
  import type { OnRenderedHook } from '../../vitrify-config.js';
4
+ type ProvideFn = (req: FastifyRequest, res: FastifyReply) => Promise<Record<string, unknown | {
5
+ value: unknown;
6
+ }>>;
4
7
  export interface FastifySsrOptions {
5
8
  baseUrl?: string;
6
- provide?: (req: FastifyRequest, res: FastifyReply) => Promise<Record<string, unknown | {
7
- value: unknown;
8
- }>>;
9
+ provide?: ProvideFn;
9
10
  vitrifyDir?: URL;
10
11
  vite?: ViteDevServer;
11
12
  onRendered?: OnRenderedHook[];
@@ -15,5 +16,18 @@ export interface FastifySsrOptions {
15
16
  host?: string;
16
17
  }
17
18
  declare const fastifySsrPlugin: FastifyPluginAsync<FastifySsrOptions>;
18
- export { fastifySsrPlugin };
19
+ declare const renderHtml: (options: {
20
+ url: string;
21
+ request: FastifyRequest | {
22
+ headers: Record<string, unknown>;
23
+ url: string;
24
+ };
25
+ reply: FastifyReply | Record<string, unknown>;
26
+ provide: Record<string, unknown>;
27
+ onRendered?: OnRenderedHook[];
28
+ template: string;
29
+ manifest: Record<string, unknown>;
30
+ render: any;
31
+ }) => Promise<string>;
32
+ export { fastifySsrPlugin, renderHtml };
19
33
  export type FastifySsrPlugin = typeof fastifySsrPlugin;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vitrify",
3
- "version": "0.19.1",
3
+ "version": "0.20.0",
4
4
  "license": "MIT",
5
5
  "author": "Stefan van Herwijnen",
6
6
  "description": "Vite as your Full Stack development tool",
@@ -91,7 +91,7 @@
91
91
  "@types/ws": "^8.18.1",
92
92
  "@unocss/preset-icons": "^66.0.0",
93
93
  "@vue/runtime-core": "^3.5.13",
94
- "beasties": "^0.3.1",
94
+ "beasties": "^0.3.2",
95
95
  "css": "^3.0.0",
96
96
  "css-to-tailwind-translator": "^1.2.8",
97
97
  "quasar": "^2.18.1",
@@ -101,9 +101,9 @@
101
101
  "vue-router": "^4.5.0"
102
102
  },
103
103
  "peerDependencies": {
104
- "@fastify/static": "^8.1.0",
105
- "fastify": "^5.2.1",
106
- "quasar": "^2.17.7",
104
+ "@fastify/static": "^8.1.1",
105
+ "fastify": "^5.2.2",
106
+ "quasar": "^2.18.1",
107
107
  "vue": "^3.5.13",
108
108
  "vue-router": "^4.5.0"
109
109
  },
@@ -9,12 +9,15 @@ import {
9
9
  } from '../../helpers/utils.js'
10
10
  import type { ViteDevServer } from 'vite'
11
11
  import type { OnRenderedHook } from '../../vitrify-config.js'
12
+
13
+ type ProvideFn = (
14
+ req: FastifyRequest,
15
+ res: FastifyReply
16
+ ) => Promise<Record<string, unknown | { value: unknown }>>
17
+
12
18
  export interface FastifySsrOptions {
13
19
  baseUrl?: string
14
- provide?: (
15
- req: FastifyRequest,
16
- res: FastifyReply
17
- ) => Promise<Record<string, unknown | { value: unknown }>>
20
+ provide?: ProvideFn
18
21
  vitrifyDir?: URL
19
22
  vite?: ViteDevServer
20
23
  // frameworkDir?: URL
@@ -66,12 +69,6 @@ const fastifySsrPlugin: FastifyPluginAsync<FastifySsrOptions> = async (
66
69
  const url = req.raw.url?.replace(options.baseUrl!, '/')
67
70
  const provide = options.provide ? await options.provide(req, res) : {}
68
71
 
69
- const ssrContext: Record<string, any> = {
70
- req,
71
- res,
72
- provide
73
- }
74
-
75
72
  let template = readFileSync(
76
73
  new URL('index.html', frameworkDir)
77
74
  ).toString()
@@ -90,47 +87,16 @@ const fastifySsrPlugin: FastifyPluginAsync<FastifySsrOptions> = async (
90
87
  manifest = {}
91
88
  }
92
89
 
93
- // const cssModules = [entryUrl]
94
- // const matchedModules = componentsModules(cssModules, vite!)
95
- // const css = collectCss({
96
- // mods: matchedModules
97
- // })
98
-
99
- const [appHtml, preloadLinks] = await render(url, manifest, ssrContext)
100
-
101
- if (!ssrContext.initialState) ssrContext.initialState = {}
102
- ssrContext.initialState.provide = provide
103
-
104
- const initialStateScript = `
105
- <script>
106
- __INITIAL_STATE__ = '${JSON.stringify(ssrContext.initialState)}'
107
- </script>`
108
- const renderHtml = (html: string) => {
109
- return appendToHead(
110
- preloadLinks,
111
- appendToBody(initialStateScript, addOrReplaceAppDiv(appHtml, html))
112
- )
113
- }
114
-
115
- let html = renderHtml(template)
116
- // let html = template
117
- // .replace(`<!--app-html-->`, appHtml)
118
- // .replace('<!--product-name-->', options.productName || 'Product name')
119
- // // .replace('<!--dev-ssr-css-->', css)
120
- // .replace(
121
- // '<!--initial-state-->',
122
- // `<script>
123
- // __INITIAL_STATE__ = '${JSON.stringify(ssrContext.initialState)}'
124
- // </script>`
125
- // )
126
-
127
- // html = appendToHead(preloadLinks, html)
128
-
129
- if (options.onRendered?.length) {
130
- for (const ssrFunction of options.onRendered) {
131
- html = ssrFunction(html, ssrContext)
132
- }
133
- }
90
+ const html = await renderHtml({
91
+ request: req,
92
+ reply: res,
93
+ url: url ?? '/',
94
+ provide,
95
+ onRendered: options.onRendered,
96
+ template,
97
+ manifest,
98
+ render
99
+ })
134
100
 
135
101
  res.code(200)
136
102
  res.type('text/html')
@@ -156,11 +122,6 @@ const fastifySsrPlugin: FastifyPluginAsync<FastifySsrOptions> = async (
156
122
  fastify.get(`${options.baseUrl}*`, async (req, res) => {
157
123
  const url = req.raw.url?.replace(options.baseUrl!, '/')
158
124
  const provide = options.provide ? await options.provide(req, res) : {}
159
- const ssrContext: Record<string, any> = {
160
- req,
161
- res,
162
- provide
163
- }
164
125
 
165
126
  const template = readFileSync(
166
127
  fileURLToPath(new URL('./dist/ssr/client/index.html', options.appDir))
@@ -177,46 +138,99 @@ const fastifySsrPlugin: FastifyPluginAsync<FastifySsrOptions> = async (
177
138
  )
178
139
  )
179
140
  ).render
141
+ const onRendered = (
142
+ await import(
143
+ fileURLToPath(
144
+ new URL(
145
+ './dist/ssr/server/virtual_vitrify-hooks.mjs',
146
+ options.appDir
147
+ )
148
+ )
149
+ )
150
+ ).onRendered
151
+
152
+ const html = await renderHtml({
153
+ request: req,
154
+ reply: res,
155
+ url: url ?? '/',
156
+ provide,
157
+ onRendered,
158
+ template,
159
+ manifest,
160
+ render
161
+ })
180
162
 
181
- const [appHtml, preloadLinks] = await render(url, manifest, ssrContext)
163
+ res.code(200)
164
+ res.type('text/html')
165
+ res.send(html)
166
+ })
167
+ }
168
+ }
182
169
 
183
- if (!ssrContext.initialState) ssrContext.initialState = {}
184
- ssrContext.initialState.provide = provide
170
+ const renderTemplate = ({
171
+ template,
172
+ initialStateScript,
173
+ appHtml,
174
+ preloadLinks
175
+ }: {
176
+ template: string
177
+ initialStateScript: string
178
+ appHtml: string
179
+ preloadLinks: string
180
+ }) => {
181
+ return appendToHead(
182
+ preloadLinks,
183
+ appendToBody(initialStateScript, addOrReplaceAppDiv(appHtml, template))
184
+ )
185
+ }
185
186
 
186
- const initialStateScript = `
187
- <script>
188
- __INITIAL_STATE__ = '${JSON.stringify(ssrContext.initialState)}'
189
- </script>`
190
- const renderHtml = (html: string) => {
191
- return appendToHead(
192
- preloadLinks,
193
- appendToBody(initialStateScript, addOrReplaceAppDiv(appHtml, html))
194
- )
195
- }
187
+ const renderHtml = async (options: {
188
+ url: string
189
+ request: FastifyRequest | { headers: Record<string, unknown>; url: string }
190
+ reply: FastifyReply | Record<string, unknown>
191
+ provide: Record<string, unknown>
192
+ onRendered?: OnRenderedHook[]
193
+ template: string
194
+ manifest: Record<string, unknown>
195
+ render: any
196
+ }) => {
197
+ const ssrContext: Record<string, any> = {
198
+ req: options.request,
199
+ res: options.reply,
200
+ provide: options.provide
201
+ }
196
202
 
197
- let html = renderHtml(template)
203
+ const onRendered = options.onRendered ?? []
198
204
 
199
- // let html = template.replace(`<!--app-html-->`, appHtml).replace(
200
- // '<!--initial-state-->',
201
- // `<script>
202
- // __INITIAL_STATE__ = '${JSON.stringify(ssrContext.initialState)}'
203
- // </script>`
204
- // )
205
+ const [appHtml, preloadLinks] = await options.render(
206
+ options.url,
207
+ options.manifest,
208
+ ssrContext
209
+ )
205
210
 
206
- // html = appendToHead(preloadLinks, html)
211
+ if (!ssrContext.initialState) ssrContext.initialState = {}
212
+ ssrContext.initialState.provide = options.provide
207
213
 
208
- if (options.onRendered?.length) {
209
- for (const ssrFunction of options.onRendered) {
210
- html = ssrFunction(html, ssrContext)
211
- }
212
- }
214
+ const initialStateScript = `
215
+ <script>
216
+ __INITIAL_STATE__ = '${JSON.stringify(ssrContext.initialState)}'
217
+ </script>`
213
218
 
214
- res.code(200)
215
- res.type('text/html')
216
- res.send(html)
217
- })
219
+ let html = renderTemplate({
220
+ template: options.template,
221
+ appHtml,
222
+ initialStateScript,
223
+ preloadLinks
224
+ })
225
+
226
+ if (onRendered?.length) {
227
+ for (const ssrFunction of onRendered) {
228
+ html = ssrFunction(html, ssrContext)
229
+ }
218
230
  }
231
+
232
+ return html
219
233
  }
220
234
 
221
- export { fastifySsrPlugin }
235
+ export { fastifySsrPlugin, renderHtml }
222
236
  export type FastifySsrPlugin = typeof fastifySsrPlugin
@@ -1,7 +1,7 @@
1
1
  import { existsSync, promises as fs, mkdirSync } from 'fs'
2
2
  import type { OnRenderedHook } from 'src/node/vitrify-config.js'
3
3
  import { routesToPaths } from '../../helpers/routes.js'
4
- import { appendToHead, addOrReplaceAppDiv } from '../../helpers/utils.js'
4
+ import { renderHtml } from './fastify-ssr-plugin.js'
5
5
 
6
6
  export const prerender = async ({
7
7
  outDir,
@@ -44,21 +44,17 @@ export const prerender = async ({
44
44
  const filename =
45
45
  (url.endsWith('/') ? 'index' : url.replace(/^\//g, '')) + '.html'
46
46
  console.log(`Generating ${filename}`)
47
- const ssrContext = {
48
- req: { headers: {}, url },
49
- res: {}
50
- }
51
- const [appHtml, preloadLinks] = await render(url, manifest, ssrContext)
52
-
53
- let html = addOrReplaceAppDiv(appHtml, template)
54
- html = appendToHead(preloadLinks, html)
55
-
56
- if (onRendered?.length) {
57
- for (const ssrFunction of onRendered) {
58
- html = ssrFunction(html, ssrContext)
59
- }
60
- }
61
47
 
48
+ let html = await renderHtml({
49
+ url,
50
+ manifest,
51
+ provide: {},
52
+ render,
53
+ request: { headers: {}, url },
54
+ reply: {},
55
+ template,
56
+ onRendered
57
+ })
62
58
  html = await beasties.process(html)
63
59
 
64
60
  promises.push(fs.writeFile(outDir + filename, html, 'utf-8'))
package/src/node/index.ts CHANGED
@@ -652,6 +652,7 @@ export const baseConfig = async ({
652
652
  input: [
653
653
  fileURLToPath(new URL('ssr/entry-server.ts', frameworkDir)),
654
654
  fileURLToPath(new URL('ssr/prerender.ts', frameworkDir)),
655
+ fileURLToPath(new URL('ssr/fastify-ssr-plugin.ts', frameworkDir)),
655
656
  fileURLToPath(new URL('ssr/server.ts', frameworkDir))
656
657
  ],
657
658
  external,
@@ -3,7 +3,6 @@ import { getAppDir } from '../../../node/app-urls.js'
3
3
  // import { setup } from 'virtual:fastify-setup'
4
4
  import { onSetup } from 'virtual:vitrify-hooks'
5
5
  import { fastifyCsrPlugin } from './fastify-csr-plugin'
6
- import type { ViteDevServer } from 'vite'
7
6
 
8
7
  // const appDir = getPkgJsonDir(import.meta.url)
9
8
  const getString = (str?: string) => str
@@ -7,12 +7,11 @@ import 'virtual:uno.css'
7
7
 
8
8
  import RootComponent from './RootComponent.vue'
9
9
  interface ssrContext {
10
- ssr: boolean
11
10
  provide?: Record<string, unknown>
12
11
  [key: string]: unknown
13
12
  }
14
13
 
15
- function capitalizeFirstLetter(string) {
14
+ function capitalizeFirstLetter(string: string) {
16
15
  return string.charAt(0).toUpperCase() + string.slice(1)
17
16
  }
18
17
 
@@ -1,11 +1,16 @@
1
- import { createApp } from '../main'
1
+ import { type FastifyReply, type FastifyRequest } from 'fastify'
2
+ import { createApp } from '../main.js'
3
+ import { renderToString as renderToStringVue } from 'vue/server-renderer'
2
4
 
3
- const initializeApp = async (url, ssrContext) => {
4
- const onRenderedList = []
5
+ const initializeApp = async (
6
+ url: string,
7
+ ssrContext: Record<string, unknown>
8
+ ) => {
9
+ const onRenderedList: (() => unknown)[] = []
5
10
  Object.assign(ssrContext, {
6
11
  _modules: new Set(),
7
12
  _meta: {},
8
- onRendered: (fn) => {
13
+ onRendered: (fn: () => unknown) => {
9
14
  onRenderedList.push(fn)
10
15
  }
11
16
  })
@@ -27,28 +32,43 @@ const initializeApp = async (url, ssrContext) => {
27
32
  export const getRoutes = async () =>
28
33
  (
29
34
  await initializeApp('/', {
30
- ssr: false,
31
35
  req: { headers: {}, url: '/' },
32
36
  res: {}
33
37
  })
34
38
  ).routes
35
39
 
36
- export async function render(url, manifest, ssrContext, renderToString) {
40
+ export async function render(
41
+ url: string,
42
+ manifest: Record<string, unknown>,
43
+ ssrContext: {
44
+ request: FastifyRequest | { headers: Record<string, unknown>; url: string }
45
+ reply: FastifyReply | Record<string, unknown>
46
+ provide: Record<string, unknown>
47
+ },
48
+ renderToString: typeof renderToStringVue
49
+ ) {
37
50
  if (!renderToString)
38
51
  renderToString = (await import('vue/server-renderer')).renderToString
39
52
  const { app, router } = await initializeApp(url, ssrContext)
40
53
 
41
- const ctx = {
54
+ const ctx: {
55
+ modules?: Map<unknown, unknown>
56
+ transports?: Record<string, unknown>
57
+ __qMetaList: unknown[]
58
+ } = {
42
59
  __qMetaList: []
43
60
  }
44
61
  const html = await renderToString(app, ctx)
45
62
 
46
- const preloadLinks = renderPreloadLinks(ctx.modules, manifest)
63
+ const preloadLinks = renderPreloadLinks(ctx.modules!, manifest)
47
64
 
48
65
  return [html, preloadLinks]
49
66
  }
50
67
 
51
- function renderPreloadLinks(modules, manifest) {
68
+ function renderPreloadLinks(
69
+ modules: Map<unknown, unknown>,
70
+ manifest: Record<string, unknown>
71
+ ) {
52
72
  let links = ''
53
73
  const seen = new Set()
54
74
  modules.forEach((id) => {
@@ -1,3 +1,6 @@
1
- import { fastifySsrPlugin } from '../../../node/frameworks/vue/fastify-ssr-plugin.js'
1
+ import {
2
+ fastifySsrPlugin,
3
+ renderHtml
4
+ } from '../../../node/frameworks/vue/fastify-ssr-plugin.js'
2
5
 
3
- export { fastifySsrPlugin }
6
+ export { fastifySsrPlugin, renderHtml }