feat: better layout in a lot of places
This commit is contained in:
16
lib/cache/cache.ts
vendored
16
lib/cache/cache.ts
vendored
@ -54,7 +54,19 @@ export function expire(id: string, seconds: number) {
|
||||
}
|
||||
}
|
||||
|
||||
export async function set<T extends RedisValue>(id: string, content: T) {
|
||||
type RedisOptions = {
|
||||
expires?: number;
|
||||
};
|
||||
|
||||
export async function set<T extends RedisValue>(
|
||||
id: string,
|
||||
content: T,
|
||||
options?: RedisOptions,
|
||||
) {
|
||||
console.log("[cache] storing ", { id });
|
||||
return await cache.set(id, content);
|
||||
const res = await cache.set(id, content);
|
||||
if (options?.expires) {
|
||||
await expire(id, options.expires);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
46
lib/cache/documents.ts
vendored
46
lib/cache/documents.ts
vendored
@ -1,57 +1,31 @@
|
||||
import { Document } from "@lib/documents.ts";
|
||||
import * as cache from "@lib/cache/cache.ts";
|
||||
|
||||
type DocumentsCache = {
|
||||
lastUpdated: number;
|
||||
documents: Document[];
|
||||
};
|
||||
|
||||
const CACHE_INTERVAL = 5000; // 5 seconds;
|
||||
const CACHE_INTERVAL = 20; // 5 seconds;
|
||||
const CACHE_KEY = "documents";
|
||||
|
||||
export async function getDocuments() {
|
||||
const docs = await cache.get<DocumentsCache>(CACHE_KEY);
|
||||
if (!docs) return;
|
||||
|
||||
if (Date.now() > docs.lastUpdated + CACHE_INTERVAL) {
|
||||
return;
|
||||
}
|
||||
|
||||
return docs.documents;
|
||||
const res = await cache.get<string>(CACHE_KEY);
|
||||
if (res) return JSON.parse(res);
|
||||
return;
|
||||
}
|
||||
|
||||
export function setDocuments(documents: Document[]) {
|
||||
return cache.set(
|
||||
CACHE_KEY,
|
||||
JSON.stringify({
|
||||
lastUpdated: Date.now(),
|
||||
documents,
|
||||
}),
|
||||
JSON.stringify(documents),
|
||||
{ expires: CACHE_INTERVAL },
|
||||
);
|
||||
}
|
||||
|
||||
type DocumentCache = {
|
||||
lastUpdated: number;
|
||||
content: string;
|
||||
};
|
||||
|
||||
export async function getDocument(id: string) {
|
||||
const doc = await cache.get<DocumentCache>(CACHE_KEY + "/" + id);
|
||||
if (!doc) return;
|
||||
|
||||
if (Date.now() > doc.lastUpdated + CACHE_INTERVAL) {
|
||||
return;
|
||||
}
|
||||
|
||||
return doc.content;
|
||||
export function getDocument(id: string) {
|
||||
return cache.get<string>(CACHE_KEY + "/" + id);
|
||||
}
|
||||
|
||||
export async function setDocument(id: string, content: string) {
|
||||
await cache.set(
|
||||
CACHE_KEY + "/" + id,
|
||||
JSON.stringify({
|
||||
lastUpdated: Date.now(),
|
||||
content,
|
||||
}),
|
||||
content,
|
||||
{ expires: CACHE_INTERVAL },
|
||||
);
|
||||
}
|
||||
|
1
lib/cache/image.ts
vendored
1
lib/cache/image.ts
vendored
@ -12,7 +12,6 @@ const CACHE_KEY = "images";
|
||||
|
||||
function getCacheKey({ url: _url, width, height }: ImageCacheOptions) {
|
||||
const url = new URL(_url);
|
||||
|
||||
return `${CACHE_KEY}/${url.hostname}/${url.pathname}/${width}/${height}`
|
||||
.replace(
|
||||
"//",
|
||||
|
@ -25,7 +25,7 @@ export async function getDocuments(): Promise<Document[]> {
|
||||
|
||||
const headers = new Headers();
|
||||
headers.append("Accept", "application/json");
|
||||
|
||||
console.log("[documents] fetching all documents");
|
||||
const response = await fetch(`${SILVERBULLET_SERVER}/index.json`, {
|
||||
headers: headers,
|
||||
});
|
||||
@ -47,6 +47,8 @@ export function createDocument(
|
||||
headers.append("Content-Type", mediaType);
|
||||
}
|
||||
|
||||
console.log("[documents] creating document", { name });
|
||||
|
||||
return fetch(SILVERBULLET_SERVER + "/" + name, {
|
||||
body: content,
|
||||
method: "PUT",
|
||||
@ -58,6 +60,7 @@ export async function getDocument(name: string): Promise<string> {
|
||||
const cachedDocument = await cache.getDocument(name);
|
||||
if (cachedDocument) return cachedDocument;
|
||||
|
||||
console.log("[documents] fetching document", { name });
|
||||
const response = await fetch(SILVERBULLET_SERVER + "/" + name);
|
||||
const text = await response.text();
|
||||
|
||||
|
18
lib/menus.ts
Normal file
18
lib/menus.ts
Normal file
@ -0,0 +1,18 @@
|
||||
export const menu = [
|
||||
{
|
||||
name: "🏡 Home",
|
||||
link: "/",
|
||||
},
|
||||
{
|
||||
name: "🍽️ Recipes",
|
||||
link: "/recipes",
|
||||
},
|
||||
{
|
||||
name: "🍿 Movies",
|
||||
link: "/movies",
|
||||
},
|
||||
{
|
||||
name: "📝 Articles",
|
||||
link: "/articles",
|
||||
},
|
||||
];
|
@ -2,7 +2,7 @@ import { parseDocument, renderMarkdown } from "@lib/documents.ts";
|
||||
import { parse } from "yaml";
|
||||
import { createCrud } from "@lib/crud.ts";
|
||||
import { stringify } from "https://deno.land/std@0.194.0/yaml/stringify.ts";
|
||||
import { formatDate } from "@lib/string.ts";
|
||||
import { extractHashTags, formatDate } from "@lib/string.ts";
|
||||
import { fixRenderedMarkdown } from "@lib/helpers.ts";
|
||||
|
||||
export type Article = {
|
||||
@ -80,10 +80,9 @@ function parseArticle(original: string, id: string): Article {
|
||||
}
|
||||
|
||||
let content = original.slice(range[0], range[1]);
|
||||
const tags = [];
|
||||
for (const [hashtag] of original.matchAll(/\B(\#[a-zA-Z\-]+\b)(?!;)/g)) {
|
||||
tags.push(hashtag.replace(/\#/g, ""));
|
||||
content = content.replace(hashtag, "");
|
||||
const tags = extractHashTags(content);
|
||||
for (const tag of tags) {
|
||||
content = content.replace("#" + tag, "");
|
||||
}
|
||||
|
||||
return {
|
||||
|
@ -1,12 +1,13 @@
|
||||
import { parseDocument, renderMarkdown } from "@lib/documents.ts";
|
||||
import { parse } from "yaml";
|
||||
import { createCrud } from "@lib/crud.ts";
|
||||
import { extractHashTags } from "@lib/string.ts";
|
||||
|
||||
export type Movie = {
|
||||
id: string;
|
||||
name: string;
|
||||
description: string;
|
||||
hashtags: string[];
|
||||
tags: string[];
|
||||
meta: {
|
||||
date: Date;
|
||||
image: string;
|
||||
@ -52,16 +53,15 @@ export function parseMovie(original: string, id: string): Movie {
|
||||
}
|
||||
|
||||
let description = original.slice(range[0], range[1]);
|
||||
const hashtags = [];
|
||||
for (const [hashtag] of original.matchAll(/\B(\#[a-zA-Z]+\b)(?!;)/g)) {
|
||||
hashtags.push(hashtag.replace(/\#/g, ""));
|
||||
description = description.replace(hashtag, "");
|
||||
const tags = extractHashTags(description);
|
||||
for (const tag of tags) {
|
||||
description = description.replace("#" + tag, "");
|
||||
}
|
||||
|
||||
return {
|
||||
id,
|
||||
name,
|
||||
hashtags,
|
||||
tags,
|
||||
description: renderMarkdown(description),
|
||||
meta,
|
||||
};
|
||||
|
@ -15,3 +15,15 @@ export function safeFileName(inputString: string): string {
|
||||
|
||||
return fileName;
|
||||
}
|
||||
|
||||
export function extractHashTags(inputString: string) {
|
||||
const hashtags = [];
|
||||
|
||||
for (
|
||||
const [hashtag] of inputString.matchAll(/(?<!\()\B(\#[a-zA-Z\-]+\b)(?!;)/g)
|
||||
) {
|
||||
hashtags.push(hashtag.replace(/\#/g, ""));
|
||||
}
|
||||
|
||||
return hashtags;
|
||||
}
|
||||
|
Reference in New Issue
Block a user