UNPKG

iles

Version:

Vite & Vue powered static site generator with partial hydration

43 lines (42 loc) 1.61 kB
import { computed, ref, inject } from 'vue'; import { routeLocationKey } from 'vue-router'; import { propsFromRoute } from '../props'; import { toReactive } from './reactivity'; export const pageDataKey = Symbol('[iles-page-data]'); function last(arr) { return arr[arr.length - 1]; } function injectFromApp(key, app) { const result = app ? app._context.provides[key] : inject(key); if (!result) throw new Error('Page data not properly injected in app. Are you using it inside an island?'); return result; } const _lastPageChange = ref(new Date()); export const forcePageUpdate = () => { _lastPageChange.value = new Date(); }; export const computedInPage = (fn) => { return computed(() => { _lastPageChange.value; // track dependency to recompute as needed. return fn(); }); }; export function pageFromRoute(route) { return (last(route.matched)?.components?.default || {}); } function reactiveFromFn(fn) { return toReactive(computed(fn)); } export function installPageData(app, siteRef) { const route = injectFromApp(routeLocationKey, app); const page = computedInPage(() => pageFromRoute(route)); const meta = reactiveFromFn(() => page.value.meta || {}); const frontmatter = reactiveFromFn(() => page.value.frontmatter || {}); const props = computedInPage(() => propsFromRoute(route)); const site = toReactive(siteRef); const pageData = { route, page, meta, frontmatter, site, props }; app.provide(pageDataKey, pageData); return pageData; } export function usePage(app) { return injectFromApp(pageDataKey, app); }