UNPKG

vite-plugin-vanjs

Version:

An async first mini meta-framework for VanJS powered by Vite

102 lines (93 loc) 2.53 kB
import isServer from "../setup/isServer.mjs"; import { getTagKey } from "./helpers.mjs"; /** @typedef {typeof import("./types.d.ts").getHeadTags} GetTags */ /** @typedef {typeof import("./types.d.ts").createHeadTags} CreateTags */ /** @typedef {typeof import("./types.d.ts").resetHeadTags} ResetTags */ /** @typedef {typeof import("./types.d.ts").initializeHeadTags} InitializeTags */ /** @typedef {typeof import("./types.d.ts").addMeta} AddMeta */ /** @typedef {typeof import("./types.d.ts").removeMeta} RemoveMeta */ /** @typedef {typeof import("./types.d.ts").Head} HeadComp */ /** * Create a new Map for each request on server * @type {CreateTags} */ const createHeadTags = () => new Map(); /** * Get the current head tags. Use a factory pattern to get the right store * on the server and the client. * @type {GetTags} */ const getHeadTags = (() => { if (isServer) { // On server, create one Map per request scope let serverHeadTags; return () => { if (!serverHeadTags) { serverHeadTags = createHeadTags(); } return serverHeadTags; }; } // On client, use a singleton const clientHeadTags = createHeadTags(); return () => clientHeadTags; })(); /** * Clear all head tags * @type {ResetTags} */ export const resetHeadTags = () => { const tags = getHeadTags(); tags.clear(); }; /** * Initialize the head tags * @type {InitializeTags} */ export const initializeHeadTags = () => { const tags = getHeadTags(); /* istanbul ignore else */ if (!tags.size && !isServer) { Array.from(document.head.children).forEach((tag) => { tags.set(getTagKey(tag), tag); }); } }; /** * Add a new meta tag * @type {AddMeta} */ export const addMeta = (tag) => { if (!tag) return; const tags = getHeadTags(); const key = getTagKey(tag); tags.set(key, tag); }; /** * Remove a new meta tag `van.tags.script({ id })` * or TAGNAME.id key. * Only client side. * @type {RemoveMeta} */ export const removeMeta = (tagOrId) => { if (!tagOrId || isServer) return; const tags = getHeadTags(); const tagIsString = typeof tagOrId === "string"; const key = tagIsString ? tagOrId : getTagKey(tagOrId); const id = tagIsString ? tagOrId.split(".")[1] : tagOrId.id; // istanbul ignore else if (id) { document.getElementById(id)?.remove(); tags.delete(key); } }; /** * Get the head tags * @type {HeadComp} */ export const Head = () => { return () => { const tags = getHeadTags(); return Array.from(tags.values()); }; };