Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
File size: 1,943 Bytes
1bcd186 7d6fc19 1bcd186 7d6fc19 1bcd186 a1a6daf 7d6fc19 cbd723d 7d6fc19 cbd723d 7d6fc19 1bcd186 7d6fc19 1bcd186 7d6fc19 1bcd186 7d6fc19 b95ec8b 7d6fc19 6f93b29 1bcd186 7d6fc19 1bcd186 7d6fc19 6f7beab 7d6fc19 6f7beab 7d6fc19 10c62e9 6f7beab |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
<script lang="ts">
import type { WebSearchSource } from "$lib/types/WebSearch";
import { processTokens, processTokensSync, type Token } from "$lib/utils/marked";
import MarkdownWorker from "$lib/workers/markdownWorker?worker";
import CodeBlock from "../CodeBlock.svelte";
import type { IncomingMessage, OutgoingMessage } from "$lib/workers/markdownWorker";
import { browser } from "$app/environment";
import DOMPurify from "isomorphic-dompurify";
interface Props {
content: string;
sources?: WebSearchSource[];
}
const worker = browser && window.Worker ? new MarkdownWorker() : null;
let { content, sources = [] }: Props = $props();
let tokens: Token[] = $state(processTokensSync(content, sources));
async function processContent(content: string, sources: WebSearchSource[]): Promise<Token[]> {
if (worker) {
return new Promise((resolve) => {
worker.onmessage = (event: MessageEvent<OutgoingMessage>) => {
if (event.data.type !== "processed") {
throw new Error("Invalid message type");
}
resolve(event.data.tokens);
};
worker.postMessage(
JSON.parse(JSON.stringify({ content, sources, type: "process" })) as IncomingMessage
);
});
} else {
return processTokens(content, sources);
}
}
$effect(() => {
if (!browser) {
tokens = processTokensSync(content, sources);
} else {
(async () => {
tokens = await processContent(content, sources);
})();
}
});
DOMPurify.addHook("afterSanitizeAttributes", (node) => {
if (node.tagName === "A") {
node.setAttribute("target", "_blank");
node.setAttribute("rel", "noreferrer");
}
});
</script>
{#each tokens as token}
{#if token.type === "text"}
{#await token.html then html}
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
{@html DOMPurify.sanitize(html)}
{/await}
{:else if token.type === "code"}
<CodeBlock code={token.code} rawCode={token.rawCode} />
{/if}
{/each}
|