memorium/lib/helpers.ts

110 lines
2.6 KiB
TypeScript
Raw Normal View History

2023-08-01 17:50:00 +02:00
export function json(content: unknown) {
const headers = new Headers();
headers.append("Content-Type", "application/json");
return new Response(JSON.stringify(content), {
headers,
});
}
2023-08-01 21:35:21 +02:00
export const isValidUrl = (urlString: string) => {
try {
return Boolean(new URL(urlString));
} catch (_e) {
2023-08-01 21:35:21 +02:00
return false;
}
};
export const fixRenderedMarkdown = (content: string) => {
return content.replace("***\n", "---")
.replace("----------------", "---")
.replace("\n---", "---")
.replace(/^(date:[^'\n]*)'|'/gm, (match, p1, p2) => {
if (p1) {
// This is a line starting with date: followed by single quotes
return p1.replace(/'/gm, "");
} else if (p2) {
return "";
} else {
// This is a line with single quotes, but not starting with date:
return match;
}
});
};
export async function fetchStream(url: string, cb: (chunk: string) => void) {
const response = await fetch(url);
const reader = response?.body?.getReader();
if (reader) {
while (true) {
const { done, value } = await reader.read();
if (done) return;
const data = new TextDecoder().decode(value);
data
.split("$")
.filter((d) => d && d.length)
.map((d) => cb(Array.isArray(d) ? d[0] : d));
}
}
}
export function hashString(message: string) {
let hash = 0;
for (let i = 0; i < message.length; i++) {
const char = message.charCodeAt(i);
hash = ((hash << 5) - hash) + char;
hash = hash & hash; // Convert to 32bit integer
}
return hash;
}
export const createStreamResponse = () => {
let controller: ReadableStreamController<ArrayBufferView>;
const body = new ReadableStream({
start(cont) {
controller = cont;
},
});
const response = new Response(body, {
headers: {
"content-type": "text/plain",
"x-content-type-options": "nosniff",
},
});
function cancel() {
controller.close();
}
function enqueue(chunk: string) {
controller?.enqueue(new TextEncoder().encode("$" + chunk));
}
return {
response,
cancel,
enqueue,
};
};
2023-08-04 13:48:12 +02:00
export type StreamResponse = ReturnType<typeof createStreamResponse>;
2023-08-04 13:48:12 +02:00
export function debounce<T extends (...args: Parameters<T>) => void>(
this: ThisParameterType<T>,
fn: T,
delay = 300,
) {
let timer: ReturnType<typeof setTimeout> | undefined;
return (...args: Parameters<T>) => {
clearTimeout(timer);
timer = setTimeout(() => fn.apply(this, args), delay);
};
}
2023-08-29 13:48:52 +02:00
export function parseRating(rating: string | number) {
if (typeof rating === "string") {
return [...rating.matchAll(/⭐/)].length;
}
return rating;
}