freshter-logs/common/db.ts
2023-04-28 19:48:34 -04:00

150 lines
4.9 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { catcher, catcher_async, squish_option } from "utils";
import { Conversation, Database, Message, Preset } from "types";
import { Option } from "optionals";
import { URL } from "utils";
const DB_PATH = "./db.json";
export async function get_db_obj(): Promise<Option<Database>> {
const text = await catcher_async(() => Deno.readTextFile(DB_PATH));
const db = text.map(db_text =>
catcher(() => JSON.parse(db_text) as Database)
);
return squish_option(db);
}
export async function get_message(id: string): Promise<Option<Message>> {
return (await get_db_obj()).map(db => db.messages[id]);
}
export async function get_conversation(
id: string
): Promise<Option<Conversation>> {
return (await get_db_obj()).map(db => db.conversations[id]);
}
async function save_db(db: Database) {
await Deno.writeTextFile(DB_PATH, JSON.stringify(db));
}
export function new_conversation(
name: string,
description: string
): Promise<Option<string>> {
return catcher_async(async () => {
const db = (await get_db_obj()).unwrap();
const id = abc_number(db.conversation_id);
db.conversation_id++;
db.conversations[id] = { name, description, messages: [], presets: {} };
db.conversations[id].presets.default = { fg: "black" };
db.conversations[id].presets.page = { fg: "black", bg: "white" };
db.conversations[id].presets.box = { fg: "black", bg: "white" };
await save_db(db);
return id;
});
}
export function add_preset(
name: string,
{ fg, bg, font }: Preset,
conv_id: string
) {
return catcher_async(async () => {
const db = (await get_db_obj()).unwrap();
const conv = db.conversations[conv_id];
if (!conv.presets) {
conv.presets = {};
}
conv.presets[name] = { fg, bg, font };
await save_db(db);
return name;
});
}
export function orphan_message(message: Message): Promise<Option<string>> {
return catcher_async(async () => {
const db = (await get_db_obj()).unwrap();
const id = abc_number(db.message_id);
db.message_id++;
db.messages[id] = message;
await save_db(db);
return id;
});
}
export function message_under(
message: Message,
conv_id: string
): Promise<Option<string>> {
return catcher_async(async () => {
const new_msg_id = (await orphan_message(message)).unwrap();
const db = (await get_db_obj()).unwrap();
if (!db.conversations[conv_id]) {
throw {};
}
db.conversations[conv_id].messages.push(new_msg_id);
await save_db(db);
return new_msg_id;
});
}
function abc_number(n: number): string {
let x = n.toString(26);
for (let i = 25; i >= 0; i--) {
const from = i.toString(26);
const to = (i + 10).toString(36);
x = x.replaceAll(from, to);
}
return x;
}
export async function fetch_db(): Promise<Option<Database>> {
const db_response = await catcher_async(
async () => await fetch(`${URL}/api/db`).then(r => r.json())
);
return db_response.map(db => db.val);
}
// export type Preset = {
// fg: string;
// bg: string;
// font?: string;
// };
//TODO: AS TEMPTING AS IT MIGHT BE, DO NOT JUST HAVE A save_db FUNCTION THAT STORES A SERIALIZED OBJECT
//TODO: THAT IS JUST *BEGGING* FOR CONCURRENCY ERRORS
//TODO: INSTEAD HAVE A SMALL SET OF FUNCTIONS THAT DO SPECIFIC THINGS
//TODO: it might actually be easier to use an actual db
// toy-network on  main [✘!?] via  v17.4.0 took 1m10s
// curl --request PUT localhost:8000/api/conv -d '{"name": "test", "description": "curl test", "fg": "red", "bg": "blue"}'
// "a"⏎
// toy-network on  main [✘!?] via  v17.4.0
// curl --request PUT localhost:8000/api/conv/a -d '{"content": "hello", "font": "Comic Sans MS"}'
// {}⏎
// toy-network on  main [✘!?] via  v17.4.0
// curl --request PUT localhost:8000/api/conv/a -d '{"content": "hello", "font": "Comic Sans MS"}'
// {"val":"c"}⏎
// toy-network on  main [✘!?] via  v17.4.0
// curl --request PUT localhost:8000/api/conv/a -d '{"content": "hello", "font": "Comic Sans MS"}'
// {"val":"c"}⏎
// toy-network on  main [✘!?] via  v17.4.0
// curl --request PUT localhost:8000/api/conv/a -d '{"content": "yay", "font": "cursive", "fg": "rebeccapurple"}'
// {"val":"d"}⏎
// toy-network on  main [✘!?] via  v17.4.0
// curl --request PUT localhost:8000/api/conv/a -d '{"content": "serif", "font": "serif", "fg": "rebeccapurple"}'
// {"val":"e"}⏎
// toy-network on  main [✘!?] via  v17.4.0
// curl --request PUT localhost:8000/api/conv/a -d '{"content": "\\"normal\\"", "fg": "rebeccapurple"}'
// {"val":"f"}⏎
// toy-network on  main [✘!?] via  v17.4.0
// curl --request PUT localhost:8000/api/conv/a -d '{"content": "contrast", "bg": "black", "fg": "white"}'
// {"val":"g"}⏎