freshter-logs/common/db.ts

150 lines
4.9 KiB
TypeScript
Raw Normal View History

2023-04-28 19:48:34 -04:00
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"}⏎