Something went wrong. Try again.
Monorepo for Tangled tangled.org
Something went wrong. Try again.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859import { browser } from "$app/environment";import { isMarkdownFile } from "$lib/markup/format";import type { MarkupContext } from "$lib/markup/paths";
// hydration re-runs every load, so the browser hands back the server's render// instead of loading the markdown pipeline again
const MARKUP_KEY = "data-markup-key";
// the key is only compared against markup already on this page, so stable and// short is enough, not cryptographicconst digest = (value: string): string => { let hash = 5381; for (let i = 0; i < value.length; i += 1) hash = (hash * 33) ^ value.charCodeAt(i); return (hash >>> 0).toString(36);};
const keyOf = (filename: string, contents: string, ctx: MarkupContext): string => [ digest([ctx.host ?? "", ctx.repo, ctx.ref, ctx.dir ?? "", filename].join("\n")), contents.length.toString(36), digest(contents) ].join(".");
const mark = (key: string, html: string): string => `<div ${MARKUP_KEY}="${key}">${html}</div>`;
// reads back a render this module wrote for the same contents and contextconst rendered = (key: string): string | null => { if (!browser) return null; const node = document.querySelector(`[${MARKUP_KEY}="${key}"]`); return node instanceof HTMLElement ? node.innerHTML : null;};
const render = async ( key: string, contents: string, ctx: MarkupContext): Promise<string | null> => { const reused = rendered(key); if (reused !== null) return mark(key, reused);
const { SOURCE_LIMIT, renderMarkdown } = await import("./markdown"); if (contents.length > SOURCE_LIMIT) return null; const html = await renderMarkdown(contents, ctx); return html === null ? null : mark(key, html);};
export const renderDocument = async ( filename: string, contents: string, ctx: MarkupContext): Promise<string | null> => isMarkdownFile(filename) ? render(keyOf(filename, contents, ctx), contents, ctx) : null;
// like renderDocument, but for content that is always markdown (issue and// comment bodies) rather than a repo file with an extension to sniffexport const renderMarkup = (contents: string, ctx: MarkupContext): Promise<string | null> => render(keyOf("", contents, ctx), contents, ctx);