UNPKG

polen

Version:

A framework for delightful GraphQL developer portals

109 lines (90 loc) 3.15 kB
import type { Config } from '#api/api' import { polenVirtual } from '#api/vite/vi' import type { Vite } from '#dep/vite/index' import { type ExistenceDiff, getMutationType, MutationType } from '#lib/mutation-type' import { debugPolen } from '#singletons/debug' import { Fs } from '@wollybeard/kit' import type { Plugin } from 'vite' const viLogo = polenVirtual([`project`, `assets`, `logo.svg`]) const generateDefaultLogo = async () => { return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128" width="128" height="128"> <circle cx="64" cy="64" r="48" fill="none" stroke="black" stroke-width="8"/> </svg>` } export function Branding(config: Config.Config): Plugin { const debug = debugPolen.sub(`vite-plugin:branding`) debug(`initialized`) return { name: `polen:branding`, enforce: `pre`, async buildStart() { this.addWatchFile(config.paths.project.absolute.public.logo) }, async handleHotUpdate({ file, server }) { return await handleWatchedFileChange({ watchedFile: config.paths.project.absolute.public.logo, changedFile: file, moduleId: viLogo.resolved, server, debug: debug, }) }, resolveId(id) { if (id === viLogo.id) { return viLogo.resolved } }, async load(id) { if (id === viLogo.resolved) { const logoFileContent = await Fs.read(config.paths.project.absolute.public.logo) const content = logoFileContent ? logoFileContent : await generateDefaultLogo() const dataUrl = `data:image/svg+xml;base64,${Buffer.from(content).toString(`base64`)}` return `export default ${JSON.stringify(dataUrl)}` } }, } } interface HandleWatchedFileChangeParams { watchedFile: string changedFile: string moduleId: string server: Vite.ViteDevServer debug: (msg: string, data?: any) => void } const handleWatchedFileChange = async ( params: HandleWatchedFileChangeParams, ): Promise<Vite.ModuleNode[] | void> => { const { watchedFile, changedFile, moduleId, server, debug } = params // Check if change is for watched file if (changedFile !== watchedFile) return // Check current existence const existsNow = await Fs.exists(watchedFile) // Check previous existence via module graph const module = server.moduleGraph.getModuleById(moduleId) const existedBefore = !!module // Early return if no mutation if (!existedBefore && !existsNow) { debug(`no mutation detected - file didn't exist before or after`, { file: changedFile }) return } const mutationType = getMutationType({ before: existedBefore, after: existsNow, } as ExistenceDiff) debug(`file ${mutationType}`, { file: changedFile }) switch (mutationType) { case MutationType.Create: // Full reload needed - module never existed server.ws.send({ type: `full-reload`, path: `*`, }) break case MutationType.Update: case MutationType.Delete: // Invalidate module for HMR server.moduleGraph.invalidateModule(module!) // Return empty array to prevent default HMR return [] } }