'use client' import { useState, useEffect } from 'react' import NetworkError from './types/error/network'; import ContentTypeError from './types/error/content_type'; import ImageContent from './types/image'; import Terminal from './types/terminal'; import Text from './types/text'; type ContentType = { content_type: RegExp, path?: RegExp, emit: () => void | Processor, }; type Processor = { process: (response: Response) => Promise, postprocess: (data: T) => undefined, }; function not_match(regex: RegExp | undefined, str: string) { return !(regex ?? /(?:)/).test(str); } function is_type(response: Response, type: ContentType) { if (not_match(type.content_type, response.headers.get('Content-Type')!.split(';')[0])) { return false; } else if (not_match(type.path, window.location.pathname)) { return false; } return true; } export default function Content({ src }: { src: string}) { const [content, set_content] = useState(); const recognized_types: ContentType[] = [{ content_type: /image\/\w+/, emit: () => { set_content(); }, }, { content_type: /application\/octet-stream/, path: /.*\.term/, emit: () => { return { process: (response: Response) => { return response.text(); }, postprocess: (data: string) => { set_content(); } }; } }, { content_type: /(text\/\w+)|(application\/octet-stream)/, emit: () => { return { process: (response: Response) => { return response.text(); }, postprocess: (data: string) => { set_content(); } }; } }]; useEffect(() => { if (content == undefined) { const result = fetch(src) .then(response => { for (const type of recognized_types) { if (is_type(response, type)) { const emitted = type.emit(); if (emitted != undefined) { result.then(emitted.postprocess); return emitted.process(response); } return; } } set_content(); }) .catch(err => { set_content(); }); } }); return content ??

Loading...

; }