vitrify 0.22.0 → 0.23.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.
- package/dist/bin/cli.js +3 -3
- package/dist/bin/dev.js +3 -3
- package/dist/frameworks/vue/fastify-ssr-plugin.js +54 -18
- package/dist/frameworks/vue/prerender.js +4 -4
- package/dist/frameworks/vue/server.js +2 -1
- package/dist/hooks/index.js +1 -0
- package/dist/index.js +12 -1
- package/dist/plugins/index.js +1 -0
- package/dist/plugins/pinia/index.js +61 -0
- package/dist/plugins/quasar/index.js +7 -8
- package/dist/types/frameworks/vue/fastify-ssr-plugin.d.ts +6 -3
- package/dist/types/frameworks/vue/prerender.d.ts +3 -3
- package/dist/types/frameworks/vue/server.d.ts +4 -4
- package/dist/types/hooks/index.d.ts +2 -0
- package/dist/types/index.d.ts +2 -2
- package/dist/types/plugins/index.d.ts +1 -0
- package/dist/types/plugins/pinia/index.d.ts +5 -0
- package/dist/types/plugins/quasar/index.d.ts +2 -2
- package/dist/types/vitrify-config.d.ts +73 -11
- package/package.json +33 -22
- package/src/node/bin/cli.ts +13 -7
- package/src/node/bin/dev.ts +7 -4
- package/src/node/frameworks/vue/fastify-ssr-plugin.ts +81 -27
- package/src/node/frameworks/vue/prerender.ts +6 -6
- package/src/node/frameworks/vue/server.ts +8 -2
- package/src/node/hooks/index.ts +19 -0
- package/src/node/index.ts +16 -4
- package/src/node/plugins/index.ts +1 -0
- package/src/node/plugins/pinia/index.ts +96 -0
- package/src/node/plugins/quasar/index.ts +13 -15
- package/src/node/vitrify-config.ts +104 -19
- package/src/vite/vue/RootComponent.vue +1 -1
- package/src/vite/vue/main.ts +52 -22
- package/src/vite/vue/ssr/app.ts +3 -2
- package/src/vite/vue/ssr/entry-server.ts +22 -41
- package/src/vite/vue/ssr/prerender.ts +2 -2
package/dist/bin/cli.js
CHANGED
|
@@ -20,7 +20,6 @@ cli
|
|
|
20
20
|
const { build } = await import('./build.js');
|
|
21
21
|
let appDir;
|
|
22
22
|
let prerender;
|
|
23
|
-
let onRendered;
|
|
24
23
|
if (options.appDir) {
|
|
25
24
|
if (options.appDir.slice(-1) !== '/')
|
|
26
25
|
options.appDir += '/';
|
|
@@ -75,7 +74,7 @@ cli
|
|
|
75
74
|
outDir: fileURLToPath(new URL('ssr/server/', baseOutDir))
|
|
76
75
|
});
|
|
77
76
|
({ prerender } = await import(new URL('ssr/server/prerender.mjs', baseOutDir).pathname));
|
|
78
|
-
const { template, manifest, render, getRoutes, onRendered } = await loadSSRAssets({
|
|
77
|
+
const { template, manifest, render, getRoutes, onRendered, onTemplateRendered } = await loadSSRAssets({
|
|
79
78
|
mode: 'ssg',
|
|
80
79
|
distDir: baseOutDir
|
|
81
80
|
});
|
|
@@ -86,7 +85,8 @@ cli
|
|
|
86
85
|
manifest,
|
|
87
86
|
render,
|
|
88
87
|
routes,
|
|
89
|
-
onRendered
|
|
88
|
+
onRendered,
|
|
89
|
+
onTemplateRendered
|
|
90
90
|
});
|
|
91
91
|
break;
|
|
92
92
|
default:
|
package/dist/bin/dev.js
CHANGED
|
@@ -75,7 +75,7 @@ ssr, framework = 'vue', host, appDir, publicDir, vite }) {
|
|
|
75
75
|
let setup;
|
|
76
76
|
let app;
|
|
77
77
|
let server;
|
|
78
|
-
let
|
|
78
|
+
let onTemplateRendered;
|
|
79
79
|
let vitrifyConfig;
|
|
80
80
|
console.log(`Development mode: ${ssr ? ssr : 'csr'}`);
|
|
81
81
|
if (ssr) {
|
|
@@ -83,7 +83,7 @@ ssr, framework = 'vue', host, appDir, publicDir, vite }) {
|
|
|
83
83
|
? fileURLToPath(new URL('src/vite/fastify/entry.ts', cliDir))
|
|
84
84
|
: fileURLToPath(new URL(`src/vite/${framework}/ssr/app.ts`, cliDir));
|
|
85
85
|
const environment = vite.environments.ssr;
|
|
86
|
-
({ setup,
|
|
86
|
+
({ setup, onTemplateRendered, vitrifyConfig } =
|
|
87
87
|
// @ts-expect-error missing types
|
|
88
88
|
await environment.runner.import(entryUrl));
|
|
89
89
|
// console.log(module)
|
|
@@ -112,7 +112,7 @@ ssr, framework = 'vue', host, appDir, publicDir, vite }) {
|
|
|
112
112
|
await app.register(fastifySsrPlugin, {
|
|
113
113
|
appDir,
|
|
114
114
|
mode: 'development',
|
|
115
|
-
|
|
115
|
+
onTemplateRendered,
|
|
116
116
|
host
|
|
117
117
|
});
|
|
118
118
|
}
|
|
@@ -3,6 +3,8 @@ import { readFileSync } from 'fs';
|
|
|
3
3
|
import { fileURLToPath } from 'url';
|
|
4
4
|
import { addOrReplaceAppDiv, appendToBody, appendToHead } from '../../helpers/utils.js';
|
|
5
5
|
import { getAppDir } from '../../app-urls.js';
|
|
6
|
+
import { stringify } from 'devalue';
|
|
7
|
+
import stringifyObject from 'stringify-object';
|
|
6
8
|
const fastifySsrPlugin = async (fastify, options) => {
|
|
7
9
|
options.baseUrl = options.baseUrl || '/';
|
|
8
10
|
options.mode = options.mode || process.env.MODE || import.meta.env.MODE;
|
|
@@ -49,11 +51,12 @@ const fastifySsrPlugin = async (fastify, options) => {
|
|
|
49
51
|
manifest = {};
|
|
50
52
|
}
|
|
51
53
|
const html = await renderHtml({
|
|
52
|
-
|
|
53
|
-
|
|
54
|
+
req,
|
|
55
|
+
res,
|
|
54
56
|
url: url ?? '/',
|
|
55
57
|
provide,
|
|
56
58
|
onRendered: options.onRendered,
|
|
59
|
+
onTemplateRendered: options.onTemplateRendered,
|
|
57
60
|
template,
|
|
58
61
|
manifest,
|
|
59
62
|
render
|
|
@@ -84,15 +87,16 @@ const fastifySsrPlugin = async (fastify, options) => {
|
|
|
84
87
|
fastify.get(`${options.baseUrl}*`, async (req, res) => {
|
|
85
88
|
const url = req.raw.url?.replace(options.baseUrl, '/');
|
|
86
89
|
const provide = options.provide ? await options.provide(req, res) : {};
|
|
87
|
-
const { template, manifest, render, onRendered } = await loadSSRAssets({
|
|
90
|
+
const { template, manifest, render, onRendered, onTemplateRendered } = await loadSSRAssets({
|
|
88
91
|
distDir: new URL('./dist/', options.appDir)
|
|
89
92
|
});
|
|
90
93
|
const html = await renderHtml({
|
|
91
|
-
|
|
92
|
-
|
|
94
|
+
req,
|
|
95
|
+
res,
|
|
93
96
|
url: url ?? '/',
|
|
94
97
|
provide,
|
|
95
98
|
onRendered,
|
|
99
|
+
onTemplateRendered,
|
|
96
100
|
template,
|
|
97
101
|
manifest,
|
|
98
102
|
render
|
|
@@ -107,19 +111,50 @@ const renderTemplate = ({ template, initialStateScript, appHtml, preloadLinks })
|
|
|
107
111
|
return appendToHead(preloadLinks, appendToBody(initialStateScript, addOrReplaceAppDiv(appHtml, template)));
|
|
108
112
|
};
|
|
109
113
|
const renderHtml = async (options) => {
|
|
114
|
+
const ssrContextOnRendered = [];
|
|
110
115
|
const ssrContext = {
|
|
111
|
-
req: options.
|
|
112
|
-
res: options.
|
|
113
|
-
provide: options.provide
|
|
116
|
+
req: options.req,
|
|
117
|
+
res: options.res,
|
|
118
|
+
provide: options.provide,
|
|
119
|
+
initialState: {},
|
|
120
|
+
_modules: new Set(),
|
|
121
|
+
_meta: {},
|
|
122
|
+
__qMetaList: [],
|
|
123
|
+
onRenderedList: ssrContextOnRendered,
|
|
124
|
+
onRendered: (fn) => {
|
|
125
|
+
ssrContextOnRendered.push(fn);
|
|
126
|
+
}
|
|
114
127
|
};
|
|
115
128
|
const onRendered = options.onRendered ?? [];
|
|
116
|
-
const
|
|
117
|
-
|
|
118
|
-
|
|
129
|
+
const onTemplateRendered = options.onTemplateRendered ?? [];
|
|
130
|
+
const { html: appHtml, preloadLinks, app } = await options.render(options.url, options.manifest, ssrContext);
|
|
131
|
+
if (ssrContextOnRendered?.length) {
|
|
132
|
+
for (const ssrFunction of ssrContextOnRendered) {
|
|
133
|
+
await ssrFunction();
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
if (onRendered?.length) {
|
|
137
|
+
for (const ssrFunction of onRendered) {
|
|
138
|
+
await ssrFunction({ app, ssrContext });
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
// if (!ssrContext.initialState) ssrContext.initialState = {}
|
|
119
142
|
ssrContext.initialState.provide = options.provide;
|
|
143
|
+
const ssrContextInitialStateStringified = {};
|
|
144
|
+
for (const key in ssrContext.initialState) {
|
|
145
|
+
if (key === 'provide') {
|
|
146
|
+
ssrContextInitialStateStringified[key] = JSON.stringify(ssrContext.initialState.provide);
|
|
147
|
+
}
|
|
148
|
+
else if (key === 'piniaColada') {
|
|
149
|
+
ssrContextInitialStateStringified[key] = JSON.stringify(ssrContext.initialState.piniaColada);
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
ssrContextInitialStateStringified[key] = stringify(ssrContext.initialState[key]);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
120
155
|
const initialStateScript = `
|
|
121
156
|
<script>
|
|
122
|
-
__INITIAL_STATE__ =
|
|
157
|
+
__INITIAL_STATE__ = ${stringifyObject(ssrContextInitialStateStringified)}
|
|
123
158
|
</script>`;
|
|
124
159
|
let html = renderTemplate({
|
|
125
160
|
template: options.template,
|
|
@@ -127,9 +162,9 @@ const renderHtml = async (options) => {
|
|
|
127
162
|
initialStateScript,
|
|
128
163
|
preloadLinks
|
|
129
164
|
});
|
|
130
|
-
if (
|
|
131
|
-
for (const ssrFunction of
|
|
132
|
-
html = ssrFunction(html, ssrContext);
|
|
165
|
+
if (onTemplateRendered?.length) {
|
|
166
|
+
for (const ssrFunction of onTemplateRendered) {
|
|
167
|
+
html = await ssrFunction({ html, ssrContext });
|
|
133
168
|
}
|
|
134
169
|
}
|
|
135
170
|
return html;
|
|
@@ -140,7 +175,7 @@ const loadSSRAssets = async ({ mode, distDir } = {
|
|
|
140
175
|
const appDir = getAppDir(new URL(import.meta.url));
|
|
141
176
|
const baseOutDir = distDir || new URL('dist/', appDir);
|
|
142
177
|
let templatePath, manifestPath, entryServerPath;
|
|
143
|
-
const
|
|
178
|
+
const vitrifyHooksPath = fileURLToPath(new URL('ssr/server/virtual_vitrify-hooks.mjs', baseOutDir));
|
|
144
179
|
if (mode === 'ssg') {
|
|
145
180
|
templatePath = fileURLToPath(new URL('static/index.html', baseOutDir));
|
|
146
181
|
manifestPath = fileURLToPath(new URL('static/.vite/ssr-manifest.json', baseOutDir));
|
|
@@ -156,13 +191,14 @@ const loadSSRAssets = async ({ mode, distDir } = {
|
|
|
156
191
|
const manifest = JSON.parse(readFileSync(manifestPath).toString());
|
|
157
192
|
const entryServer = await import(entryServerPath);
|
|
158
193
|
const { render, getRoutes } = entryServer;
|
|
159
|
-
const onRendered =
|
|
194
|
+
const { onTemplateRendered, onRendered } = await import(vitrifyHooksPath);
|
|
160
195
|
return {
|
|
161
196
|
template,
|
|
162
197
|
manifest,
|
|
163
198
|
render,
|
|
164
199
|
getRoutes,
|
|
165
|
-
onRendered
|
|
200
|
+
onRendered,
|
|
201
|
+
onTemplateRendered
|
|
166
202
|
};
|
|
167
203
|
}
|
|
168
204
|
catch (e) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { existsSync, promises as fs, mkdirSync } from 'fs';
|
|
2
2
|
import { routesToPaths } from '../../helpers/routes.js';
|
|
3
3
|
import { renderHtml } from './fastify-ssr-plugin.js';
|
|
4
|
-
export const prerender = async ({ outDir, template, manifest, render, routes,
|
|
4
|
+
export const prerender = async ({ outDir, template, manifest, render, routes, onTemplateRendered }) => {
|
|
5
5
|
const promises = [];
|
|
6
6
|
const paths = routesToPaths(routes).filter((i) => !i.includes(':') && !i.includes('*'));
|
|
7
7
|
const beasties = new (await import('beasties')).default({
|
|
@@ -23,10 +23,10 @@ export const prerender = async ({ outDir, template, manifest, render, routes, on
|
|
|
23
23
|
manifest,
|
|
24
24
|
provide: {},
|
|
25
25
|
render,
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
req: { headers: {}, url },
|
|
27
|
+
res: {},
|
|
28
28
|
template,
|
|
29
|
-
|
|
29
|
+
onTemplateRendered
|
|
30
30
|
});
|
|
31
31
|
html = await beasties.process(html);
|
|
32
32
|
promises.push(fs.writeFile(outDir + filename, html, 'utf-8'));
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import fastify from 'fastify';
|
|
2
|
-
export const createApp = ({ onSetup, appDir, baseUrl, fastifyPlugin, onRendered, vitrifyDir, mode }) => {
|
|
2
|
+
export const createApp = ({ onSetup, appDir, baseUrl, fastifyPlugin, onRendered, onTemplateRendered, vitrifyDir, mode }) => {
|
|
3
3
|
const app = fastify({
|
|
4
4
|
logger: {
|
|
5
5
|
transport: {
|
|
@@ -13,6 +13,7 @@ export const createApp = ({ onSetup, appDir, baseUrl, fastifyPlugin, onRendered,
|
|
|
13
13
|
appDir,
|
|
14
14
|
vitrifyDir,
|
|
15
15
|
onRendered,
|
|
16
|
+
onTemplateRendered,
|
|
16
17
|
mode
|
|
17
18
|
});
|
|
18
19
|
if (onSetup?.length) {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/index.js
CHANGED
|
@@ -37,7 +37,7 @@ const manualChunkNames = [
|
|
|
37
37
|
'server'
|
|
38
38
|
];
|
|
39
39
|
const moduleChunks = {
|
|
40
|
-
vue: ['vue', '@vue', 'vue-router'],
|
|
40
|
+
vue: ['vue', '@vue', 'vue-router', 'pinia', '@pinia/colada', '@vue/devtools'],
|
|
41
41
|
quasar: ['quasar'],
|
|
42
42
|
atQuasar: ['@quasar']
|
|
43
43
|
};
|
|
@@ -209,7 +209,9 @@ export const baseConfig = async ({ ssr, appDir, publicDir, base = '/', command =
|
|
|
209
209
|
}
|
|
210
210
|
let onBootHooks;
|
|
211
211
|
let onRenderedHooks;
|
|
212
|
+
let onTemplateRenderedHooks;
|
|
212
213
|
let onMountedHooks;
|
|
214
|
+
let onAppCreatedHooks;
|
|
213
215
|
let onSetupFiles;
|
|
214
216
|
let globalCss = [];
|
|
215
217
|
let staticImports;
|
|
@@ -270,7 +272,10 @@ export const baseConfig = async ({ ssr, appDir, publicDir, base = '/', command =
|
|
|
270
272
|
config: (config, env) => {
|
|
271
273
|
onBootHooks = config.vitrify?.hooks?.onBoot || [];
|
|
272
274
|
onRenderedHooks = config.vitrify?.hooks?.onRendered || [];
|
|
275
|
+
onTemplateRenderedHooks =
|
|
276
|
+
config.vitrify?.hooks?.onTemplateRendered || [];
|
|
273
277
|
onMountedHooks = config.vitrify?.hooks?.onMounted || [];
|
|
278
|
+
onAppCreatedHooks = config.vitrify?.hooks?.onAppCreated || [];
|
|
274
279
|
onSetupFiles = config?.vitrify?.hooks?.onSetup || [];
|
|
275
280
|
globalCss = config.vitrify?.globalCss || [];
|
|
276
281
|
staticImports = config.vitrify?.staticImports || {};
|
|
@@ -310,6 +315,12 @@ export const baseConfig = async ({ ssr, appDir, publicDir, base = '/', command =
|
|
|
310
315
|
export const onRendered = [${onRenderedHooks
|
|
311
316
|
.map((fn) => `${String(fn)}`)
|
|
312
317
|
.join(', ')}]
|
|
318
|
+
export const onTemplateRendered = [${onTemplateRenderedHooks
|
|
319
|
+
.map((fn) => `${String(fn)}`)
|
|
320
|
+
.join(', ')}]
|
|
321
|
+
export const onAppCreated = [${onAppCreatedHooks
|
|
322
|
+
.map((fn) => `${String(fn)}`)
|
|
323
|
+
.join(', ')}]
|
|
313
324
|
export const onSetup = []
|
|
314
325
|
${onSetupFiles
|
|
315
326
|
.map((url, index) => {
|
package/dist/plugins/index.js
CHANGED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
const piniaonAppCreated = async ({ app, ctx, initialState, ssrContext }) => {
|
|
2
|
+
const { createPinia } = await import('pinia');
|
|
3
|
+
const pinia = createPinia();
|
|
4
|
+
ctx.pinia = pinia;
|
|
5
|
+
app.use(pinia);
|
|
6
|
+
// SSR Client
|
|
7
|
+
if (initialState?.pinia)
|
|
8
|
+
pinia.state.value = initialState.pinia;
|
|
9
|
+
// SSR Server
|
|
10
|
+
if (ssrContext)
|
|
11
|
+
ssrContext.pinia = pinia;
|
|
12
|
+
};
|
|
13
|
+
const piniaOnRenderedHook = ({ app, ssrContext }) => {
|
|
14
|
+
// SSR Server
|
|
15
|
+
if (ssrContext?.initialState && ssrContext.pinia) {
|
|
16
|
+
ssrContext.initialState.pinia = ssrContext.pinia.state.value;
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
const piniaColadaonAppCreated = async ({ app, ctx, initialState }) => {
|
|
20
|
+
if (ctx?.pinia) {
|
|
21
|
+
const { PiniaColada, useQueryCache, hydrateQueryCache } = await import('@pinia/colada');
|
|
22
|
+
app.use(PiniaColada);
|
|
23
|
+
// SSR Client
|
|
24
|
+
if (initialState?.piniaColada) {
|
|
25
|
+
hydrateQueryCache(useQueryCache(ctx.pinia), initialState.piniaColada);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
const piniaColadaOnRenderedHook = async ({ app, ssrContext }) => {
|
|
30
|
+
// SSR Server
|
|
31
|
+
if (ssrContext?.initialState && ssrContext.pinia) {
|
|
32
|
+
const { useQueryCache, serializeQueryCache } = await import('@pinia/colada');
|
|
33
|
+
// Delete to prevent Non-POJO error
|
|
34
|
+
if (ssrContext.initialState.pinia?._pc_query) {
|
|
35
|
+
delete ssrContext.initialState.pinia._pc_query;
|
|
36
|
+
}
|
|
37
|
+
ssrContext.initialState.piniaColada = serializeQueryCache(useQueryCache(ssrContext.pinia));
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
export const PiniaPlugin = async ({ ssr = false, pwa = false, options = {} }) => {
|
|
41
|
+
const onAppCreated = [piniaonAppCreated];
|
|
42
|
+
const onRendered = [piniaOnRenderedHook];
|
|
43
|
+
if (options.colada) {
|
|
44
|
+
onAppCreated.push(piniaColadaonAppCreated);
|
|
45
|
+
onRendered.push(piniaColadaOnRenderedHook);
|
|
46
|
+
}
|
|
47
|
+
return {
|
|
48
|
+
plugins: [],
|
|
49
|
+
config: {
|
|
50
|
+
vitrify: {
|
|
51
|
+
ssr: {
|
|
52
|
+
serverModules: ['@pinia/colada']
|
|
53
|
+
},
|
|
54
|
+
hooks: {
|
|
55
|
+
onAppCreated,
|
|
56
|
+
onRendered
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { fileURLToPath } from 'url';
|
|
2
2
|
import { findDepPkgJsonPath } from 'vitefu';
|
|
3
3
|
import { QuasarResolver } from 'unplugin-vue-components/resolvers';
|
|
4
|
-
export const injectSsrContext = (html, ssrContext) => html
|
|
4
|
+
export const injectSsrContext = ({ html, ssrContext }) => html
|
|
5
5
|
.replace(/(<html[^>]*)(>)/i, (found, start, end) => {
|
|
6
6
|
let matches;
|
|
7
7
|
matches = found.match(/\sdir\s*=\s*['"]([^'"]*)['"]/i);
|
|
@@ -12,12 +12,12 @@ export const injectSsrContext = (html, ssrContext) => html
|
|
|
12
12
|
if (matches) {
|
|
13
13
|
start = start.replace(matches[0], '');
|
|
14
14
|
}
|
|
15
|
-
return `${start} ${ssrContext
|
|
15
|
+
return `${start} ${ssrContext?._meta.htmlAttrs || ''} ${end}`;
|
|
16
16
|
})
|
|
17
|
-
.replace(/(<head[^>]*)(>)/i, (_, start, end) => `${start}${end}${ssrContext
|
|
18
|
-
.replace(/(<\/head>)/i, (_, tag) => `${ssrContext
|
|
17
|
+
.replace(/(<head[^>]*)(>)/i, (_, start, end) => `${start}${end}${ssrContext?._meta.headTags || ''}`)
|
|
18
|
+
.replace(/(<\/head>)/i, (_, tag) => `${ssrContext?._meta.resourceStyles || ''}${ssrContext?._meta.endingHeadTags || ''}${tag}`)
|
|
19
19
|
.replace(/(<body[^>]*)(>)/i, (found, start, end) => {
|
|
20
|
-
let classes = ssrContext
|
|
20
|
+
let classes = ssrContext?._meta.bodyClasses || '';
|
|
21
21
|
const matches = found.match(/\sclass\s*=\s*['"]([^'"]*)['"]/i);
|
|
22
22
|
if (matches) {
|
|
23
23
|
if (matches[1].length > 0) {
|
|
@@ -25,7 +25,7 @@ export const injectSsrContext = (html, ssrContext) => html
|
|
|
25
25
|
}
|
|
26
26
|
start = start.replace(matches[0], '');
|
|
27
27
|
}
|
|
28
|
-
return `${start} class="${classes.trim()}" ${ssrContext
|
|
28
|
+
return `${start} class="${classes.trim()}" ${ssrContext?._meta.bodyAttrs || ''}${end}${ssrContext?._meta.bodyTags || ''}`;
|
|
29
29
|
});
|
|
30
30
|
export const QuasarPlugin = async ({ ssr = false, pwa = false, options }) => {
|
|
31
31
|
let plugins = [];
|
|
@@ -119,7 +119,7 @@ export const QuasarPlugin = async ({ ssr = false, pwa = false, options }) => {
|
|
|
119
119
|
hooks: {
|
|
120
120
|
onBoot: onBootHooks,
|
|
121
121
|
onMounted: onMountedHooks,
|
|
122
|
-
|
|
122
|
+
onTemplateRendered: [injectSsrContext]
|
|
123
123
|
},
|
|
124
124
|
sass: quasarConf.disableSass
|
|
125
125
|
? undefined
|
|
@@ -224,4 +224,3 @@ export const QuasarPlugin = async ({ ssr = false, pwa = false, options }) => {
|
|
|
224
224
|
}
|
|
225
225
|
};
|
|
226
226
|
};
|
|
227
|
-
export default QuasarPlugin;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { FastifyPluginAsync, FastifyRequest, FastifyReply } from 'fastify';
|
|
2
2
|
import type { ViteDevServer } from 'vite';
|
|
3
|
-
import type { OnRenderedHook } from '../../vitrify-config.js';
|
|
3
|
+
import type { OnRenderedHook, OnTemplateRenderedHook } from '../../vitrify-config.js';
|
|
4
4
|
type ProvideFn = (req: FastifyRequest, res: FastifyReply) => Promise<Record<string, unknown | {
|
|
5
5
|
value: unknown;
|
|
6
6
|
}>>;
|
|
@@ -10,6 +10,7 @@ export interface FastifySsrOptions {
|
|
|
10
10
|
vitrifyDir?: URL;
|
|
11
11
|
vite?: ViteDevServer;
|
|
12
12
|
onRendered?: OnRenderedHook[];
|
|
13
|
+
onTemplateRendered?: OnTemplateRenderedHook[];
|
|
13
14
|
appDir?: URL;
|
|
14
15
|
publicDir?: URL;
|
|
15
16
|
mode?: string;
|
|
@@ -18,13 +19,14 @@ export interface FastifySsrOptions {
|
|
|
18
19
|
declare const fastifySsrPlugin: FastifyPluginAsync<FastifySsrOptions>;
|
|
19
20
|
declare const renderHtml: (options: {
|
|
20
21
|
url: string;
|
|
21
|
-
|
|
22
|
+
req: FastifyRequest | {
|
|
22
23
|
headers: Record<string, unknown>;
|
|
23
24
|
url: string;
|
|
24
25
|
};
|
|
25
|
-
|
|
26
|
+
res: FastifyReply | Record<string, unknown>;
|
|
26
27
|
provide: Record<string, unknown>;
|
|
27
28
|
onRendered?: OnRenderedHook[];
|
|
29
|
+
onTemplateRendered?: OnTemplateRenderedHook[];
|
|
28
30
|
template: string;
|
|
29
31
|
manifest: Record<string, unknown>;
|
|
30
32
|
render: any;
|
|
@@ -38,6 +40,7 @@ declare const loadSSRAssets: ({ mode, distDir }?: {
|
|
|
38
40
|
render: any;
|
|
39
41
|
getRoutes: any;
|
|
40
42
|
onRendered: any;
|
|
43
|
+
onTemplateRendered: any;
|
|
41
44
|
}>;
|
|
42
45
|
export { fastifySsrPlugin, renderHtml, loadSSRAssets };
|
|
43
46
|
export type FastifySsrPlugin = typeof fastifySsrPlugin;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { OnTemplateRenderedHook } from 'src/node/vitrify-config.js';
|
|
2
2
|
import { type RouteRecordRaw } from 'vue-router';
|
|
3
|
-
export declare const prerender: ({ outDir, template, manifest, render, routes,
|
|
3
|
+
export declare const prerender: ({ outDir, template, manifest, render, routes, onTemplateRendered }: {
|
|
4
4
|
outDir: string;
|
|
5
5
|
template: string;
|
|
6
6
|
manifest: Record<string, unknown>;
|
|
7
7
|
render: unknown;
|
|
8
8
|
routes: RouteRecordRaw[];
|
|
9
|
-
|
|
9
|
+
onTemplateRendered: OnTemplateRenderedHook[];
|
|
10
10
|
}) => Promise<void[]>;
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { OnRenderedHook, OnSetupHook } from '../../vitrify-config.js';
|
|
1
|
+
import type { OnTemplateRenderedHook, OnSetupHook, OnRenderedHook } from '../../vitrify-config.js';
|
|
3
2
|
import type { FastifyCsrPlugin } from './fastify-csr-plugin.js';
|
|
4
3
|
import type { FastifySsrPlugin } from './fastify-ssr-plugin.js';
|
|
5
|
-
export declare const createApp: ({ onSetup, appDir, baseUrl, fastifyPlugin, onRendered, vitrifyDir, mode }: {
|
|
4
|
+
export declare const createApp: ({ onSetup, appDir, baseUrl, fastifyPlugin, onRendered, onTemplateRendered, vitrifyDir, mode }: {
|
|
6
5
|
onSetup: OnSetupHook[];
|
|
7
6
|
appDir: URL;
|
|
8
7
|
baseUrl?: string;
|
|
9
8
|
fastifyPlugin: FastifySsrPlugin | FastifyCsrPlugin;
|
|
10
9
|
onRendered?: OnRenderedHook[];
|
|
10
|
+
onTemplateRendered?: OnTemplateRenderedHook[];
|
|
11
11
|
vitrifyDir?: URL;
|
|
12
12
|
mode: string;
|
|
13
|
-
}) => FastifyInstance<import("http").Server<typeof import("http").IncomingMessage, typeof import("http").ServerResponse>, import("http").IncomingMessage, import("http").ServerResponse<import("http").IncomingMessage>, import("fastify").FastifyBaseLogger, import("fastify").FastifyTypeProviderDefault> & PromiseLike<FastifyInstance<import("http").Server<typeof import("http").IncomingMessage, typeof import("http").ServerResponse>, import("http").IncomingMessage, import("http").ServerResponse<import("http").IncomingMessage>, import("fastify").FastifyBaseLogger, import("fastify").FastifyTypeProviderDefault>> & {
|
|
13
|
+
}) => import("fastify").FastifyInstance<import("http").Server<typeof import("http").IncomingMessage, typeof import("http").ServerResponse>, import("http").IncomingMessage, import("http").ServerResponse<import("http").IncomingMessage>, import("fastify").FastifyBaseLogger, import("fastify").FastifyTypeProviderDefault> & PromiseLike<import("fastify").FastifyInstance<import("http").Server<typeof import("http").IncomingMessage, typeof import("http").ServerResponse>, import("http").IncomingMessage, import("http").ServerResponse<import("http").IncomingMessage>, import("fastify").FastifyBaseLogger, import("fastify").FastifyTypeProviderDefault>> & {
|
|
14
14
|
__linterBrands: "SafePromiseLike";
|
|
15
15
|
};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import type { OnBootHook, onAppCreatedHook, OnMountedHook, OnRenderedHook, OnTemplateRenderedHook, OnSetupFile, OnSetupHook } from '../vitrify-config.js';
|
|
2
|
+
export { OnBootHook, onAppCreatedHook, OnMountedHook, OnRenderedHook, OnTemplateRenderedHook, OnSetupFile, OnSetupHook };
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { InlineConfig } from 'vite';
|
|
2
|
-
import type {
|
|
2
|
+
import type { VitrifyConfig, VitrifyConfigAsync, VitrifyCommands, VitrifyModes, VitrifyUIFrameworks, VitrifySSRModes, OnBootHook } from './vitrify-config.js';
|
|
3
3
|
import type { VitrifyContext } from './bin/run.js';
|
|
4
4
|
import type { VitrifyPlugin } from './plugins/index.js';
|
|
5
5
|
export declare const VIRTUAL_MODULES: string[];
|
|
@@ -16,4 +16,4 @@ export declare const baseConfig: ({ ssr, appDir, publicDir, base, command, mode,
|
|
|
16
16
|
}) => Promise<InlineConfig>;
|
|
17
17
|
export declare const vitrifyDir: URL;
|
|
18
18
|
export { prerender } from './frameworks/vue/prerender.js';
|
|
19
|
-
export type { VitrifyConfig, VitrifyConfigAsync, VitrifyPlugin, VitrifyContext,
|
|
19
|
+
export type { VitrifyConfig, VitrifyConfigAsync, VitrifyPlugin, VitrifyContext, OnBootHook };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { OnTemplateRenderedHook } from '../../vitrify-config.js';
|
|
1
2
|
import type { VitrifyPlugin } from '../index.js';
|
|
2
3
|
import { type QuasarFonts, type QuasarComponents, type QuasarDirectives, type QuasarIconSets, type QuasarPlugins, type GlobalQuasarIconMapFn, type QuasarIconSet } from 'quasar';
|
|
3
4
|
export interface QuasarPluginOptions {
|
|
@@ -12,6 +13,5 @@ export interface QuasarPluginOptions {
|
|
|
12
13
|
extras?: (QuasarIconSets | QuasarFonts)[];
|
|
13
14
|
disableSass?: boolean;
|
|
14
15
|
}
|
|
15
|
-
export declare const injectSsrContext:
|
|
16
|
+
export declare const injectSsrContext: OnTemplateRenderedHook;
|
|
16
17
|
export declare const QuasarPlugin: VitrifyPlugin<QuasarPluginOptions>;
|
|
17
|
-
export default QuasarPlugin;
|
|
@@ -1,28 +1,82 @@
|
|
|
1
1
|
import type { Alias, UserConfig as ViteUserConfig, ViteDevServer } from 'vite';
|
|
2
2
|
import type { ComponentInternalInstance } from '@vue/runtime-core';
|
|
3
|
-
import type { FastifyInstance, FastifyServerOptions } from 'fastify';
|
|
3
|
+
import type { FastifyInstance, FastifyReply, FastifyRequest, FastifyServerOptions } from 'fastify';
|
|
4
4
|
import type { VitePWAOptions } from 'vite-plugin-pwa';
|
|
5
5
|
import type { Options as unpluginVueComponentsOptions } from 'unplugin-vue-components';
|
|
6
6
|
import type { UserConfig as UnoCSSUserConfig } from '@unocss/core';
|
|
7
|
-
import { VitrifyPlugin } from './plugins/index.js';
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
import type { VitrifyPlugin } from './plugins/index.js';
|
|
8
|
+
import type { Router } from 'vue-router';
|
|
9
|
+
import type { App } from '@vue/runtime-core';
|
|
10
|
+
import type { Pinia } from 'pinia';
|
|
11
|
+
import type { _UseQueryEntryNodeValueSerialized } from '@pinia/colada/index.js';
|
|
12
|
+
export type SSRContext = {
|
|
13
|
+
req: FastifyRequest | {
|
|
14
|
+
headers: Record<string, unknown>;
|
|
15
|
+
url: string;
|
|
16
|
+
};
|
|
17
|
+
res: FastifyReply | Record<string, unknown>;
|
|
18
|
+
provide: Record<string, unknown>;
|
|
19
|
+
initialState: {
|
|
20
|
+
provide?: Record<string, unknown>;
|
|
21
|
+
pinia?: Record<string, unknown>;
|
|
22
|
+
piniaColada?: Record<string, _UseQueryEntryNodeValueSerialized>;
|
|
23
|
+
[key: string]: unknown;
|
|
24
|
+
};
|
|
25
|
+
pinia?: Pinia;
|
|
26
|
+
_modules: Set<unknown>;
|
|
27
|
+
_meta: Record<string, any>;
|
|
28
|
+
__qMetaList: unknown[];
|
|
29
|
+
/**
|
|
30
|
+
* Required for Quasar
|
|
31
|
+
*/
|
|
32
|
+
onRenderedList: (() => unknown)[];
|
|
33
|
+
onRendered: (fn: () => unknown) => void;
|
|
34
|
+
/**
|
|
35
|
+
* Vue internals
|
|
36
|
+
*/
|
|
37
|
+
modules?: Map<unknown, unknown>;
|
|
38
|
+
transports?: Record<string, unknown>;
|
|
39
|
+
[key: string]: unknown;
|
|
40
|
+
};
|
|
41
|
+
export type onAppCreatedHook = ({ app, router, ctx, initialState, ssrContext }: {
|
|
42
|
+
app: App;
|
|
43
|
+
router: Router;
|
|
44
|
+
ctx: {
|
|
45
|
+
pinia?: Pinia;
|
|
46
|
+
[key: string]: unknown;
|
|
47
|
+
};
|
|
48
|
+
initialState: {
|
|
49
|
+
provide?: Record<string, unknown>;
|
|
50
|
+
pinia?: Record<string, unknown>;
|
|
51
|
+
piniaColada?: Record<string, _UseQueryEntryNodeValueSerialized>;
|
|
52
|
+
[key: string]: unknown;
|
|
53
|
+
};
|
|
54
|
+
ssrContext?: SSRContext;
|
|
12
55
|
}) => Promise<void> | void;
|
|
13
56
|
export type OnBootHook = ({ app, ssrContext, staticImports }: {
|
|
14
|
-
app:
|
|
15
|
-
ssrContext:
|
|
57
|
+
app: App;
|
|
58
|
+
ssrContext: SSRContext;
|
|
16
59
|
staticImports?: Record<string, any>;
|
|
17
60
|
}) => Promise<void> | void;
|
|
18
61
|
export type OnMountedHook = (instance: ComponentInternalInstance) => Promise<void> | void;
|
|
19
62
|
export type StaticImports = Record<string, string[]>;
|
|
20
|
-
export type
|
|
21
|
-
export type OnRenderedHook = (html: string, ssrContext: Record<string, any>) => string;
|
|
63
|
+
export type OnSetupFile = URL;
|
|
22
64
|
export type OnSetupHook = (fastify: FastifyInstance, options?: {
|
|
23
65
|
vite?: ViteDevServer;
|
|
24
66
|
}) => any;
|
|
25
|
-
export type
|
|
67
|
+
export type Render = (url: string, manifest: Record<string, unknown>, ssrContext: SSRContext, renderToString: (app: App, ctx?: Record<string, any>) => Promise<string>) => Promise<{
|
|
68
|
+
html: string;
|
|
69
|
+
preloadLinks: string;
|
|
70
|
+
app: App;
|
|
71
|
+
}>;
|
|
72
|
+
export type OnRenderedHook = ({ app, ssrContext }: {
|
|
73
|
+
app: App;
|
|
74
|
+
ssrContext?: SSRContext;
|
|
75
|
+
}) => Promise<void> | void;
|
|
76
|
+
export type OnTemplateRenderedHook = ({ html, ssrContext }: {
|
|
77
|
+
html: string;
|
|
78
|
+
ssrContext?: SSRContext;
|
|
79
|
+
}) => Promise<string> | string;
|
|
26
80
|
export interface VitrifyConfig extends ViteUserConfig {
|
|
27
81
|
vitrify?: {
|
|
28
82
|
lang?: string;
|
|
@@ -55,6 +109,14 @@ export interface VitrifyConfig extends ViteUserConfig {
|
|
|
55
109
|
* Functions which run after rendering the app (SSR)
|
|
56
110
|
*/
|
|
57
111
|
onRendered?: OnRenderedHook[];
|
|
112
|
+
/**
|
|
113
|
+
* Functions which run after rendering the template (SSR)
|
|
114
|
+
*/
|
|
115
|
+
onTemplateRendered?: OnTemplateRenderedHook[];
|
|
116
|
+
/**
|
|
117
|
+
* Functions which run directly after initializing the application
|
|
118
|
+
*/
|
|
119
|
+
onAppCreated?: onAppCreatedHook[];
|
|
58
120
|
};
|
|
59
121
|
/**
|
|
60
122
|
* Global SASS variables
|