nuxt
Version:
83 lines (82 loc) • 2.77 kB
JavaScript
import { appRootTag } from "#internal/nuxt.config.mjs";
const ROOT_NODE_REGEX = new RegExp(`^<${appRootTag}[^>]*>([\\s\\S]*)<\\/${appRootTag}>$`);
export function getServerComponentHTML(body) {
const match = body.match(ROOT_NODE_REGEX);
return match?.[1] || body;
}
const SSR_SLOT_TELEPORT_MARKER = /^uid=([^;]*);slot=(.*)$/;
const SSR_CLIENT_TELEPORT_MARKER = /^uid=([^;]*);client=(.*)$/;
const SSR_CLIENT_SLOT_MARKER = /^island-slot=([^;]*);(.*)$/;
export function getSlotIslandResponse(ssrContext) {
if (!ssrContext.islandContext || !Object.keys(ssrContext.islandContext.slots).length) {
return void 0;
}
const response = {};
for (const [name, slot] of Object.entries(ssrContext.islandContext.slots)) {
response[name] = {
...slot,
fallback: ssrContext.teleports?.[`island-fallback=${name}`]
};
}
return response;
}
export function getClientIslandResponse(ssrContext) {
if (!ssrContext.islandContext || !Object.keys(ssrContext.islandContext.components).length) {
return void 0;
}
const response = {};
for (const [clientUid, component] of Object.entries(ssrContext.islandContext.components)) {
const html = ssrContext.teleports?.[clientUid]?.replaceAll("<!--teleport start anchor-->", "") || "";
response[clientUid] = {
...component,
html,
slots: getComponentSlotTeleport(clientUid, ssrContext.teleports ?? {})
};
}
return response;
}
export function getComponentSlotTeleport(clientUid, teleports) {
const entries = Object.entries(teleports);
const slots = {};
for (const [key, value] of entries) {
const match = key.match(SSR_CLIENT_SLOT_MARKER);
if (match) {
const [, id, slot] = match;
if (!slot || clientUid !== id) {
continue;
}
slots[slot] = value;
}
}
return slots;
}
export function replaceIslandTeleports(ssrContext, html) {
const { teleports, islandContext } = ssrContext;
if (islandContext || !teleports) {
return html;
}
for (const key in teleports) {
const matchClientComp = key.match(SSR_CLIENT_TELEPORT_MARKER);
if (matchClientComp) {
const [, uid, clientId] = matchClientComp;
if (!uid || !clientId) {
continue;
}
html = html.replace(new RegExp(` data-island-uid="${uid}" data-island-component="${clientId}"[^>]*>`), (full) => {
return full + teleports[key];
});
continue;
}
const matchSlot = key.match(SSR_SLOT_TELEPORT_MARKER);
if (matchSlot) {
const [, uid, slot] = matchSlot;
if (!uid || !slot) {
continue;
}
html = html.replace(new RegExp(` data-island-uid="${uid}" data-island-slot="${slot}"[^>]*>`), (full) => {
return full + teleports[key];
});
}
}
return html;
}