2023-12-12 00:58:13 +01:00

78 lines
2.3 KiB
TypeScript

import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
import { createSSRApp, defineComponent, h, markRaw, reactive } from 'vue'
import PageShell from '#components/PageShell.vue'
import { setPageContext } from '#context/usePageContext'
import i18n from '#plugins/i18n'
import pinia from '#plugins/pinia'
import CreateVuetify from '#plugins/vuetify'
import type { Component } from '#types/Component'
import type { PageContext, VikePageContext } from '#types/PageContext'
const vuetify = CreateVuetify(i18n)
function createApp(pageContext: VikePageContext & PageContext, isClient = true) {
let rootComponent: Component
const PageWithWrapper = defineComponent({
data: () => ({
Page: markRaw(pageContext.Page),
pageProps: markRaw(pageContext.pageProps || {}),
isClient,
}),
created() {
// eslint-disable-next-line @typescript-eslint/no-this-alias
rootComponent = this
},
render() {
return h(
PageShell,
{},
{
default: () => {
return h(this.Page, this.pageProps)
},
},
)
},
})
if (isClient) {
pinia.use(piniaPluginPersistedstate)
}
const app = createSSRApp(PageWithWrapper)
app.use(pinia)
app.use(i18n)
app.use(vuetify)
objectAssign(app, {
changePage: (pageContext: VikePageContext & PageContext) => {
Object.assign(pageContextReactive, pageContext)
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
rootComponent.Page = markRaw(pageContext.Page)
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
rootComponent.pageProps = markRaw(pageContext.pageProps || {})
},
})
// When doing Client Routing, we mutate pageContext (see usage of `app.changePage()` in `_default.page.client.js`).
// We therefore use a reactive pageContext.
const pageContextReactive = reactive(pageContext)
// Make pageContext available from any Vue component
setPageContext(app, pageContextReactive)
return { app, i18n }
}
// Same as `Object.assign()` but with type inference
function objectAssign<Obj extends object, ObjAddendum>(
obj: Obj,
objAddendum: ObjAddendum,
): asserts obj is Obj & ObjAddendum {
Object.assign(obj, objAddendum)
}
export { createApp }