Init backend, frontend and DB schema

This commit is contained in:
2024-08-03 10:44:42 +02:00
parent ddd7f7221b
commit 777038e0b4
23 changed files with 1917 additions and 0 deletions

View File

@@ -0,0 +1,20 @@
import { globalStyle } from "@vanilla-extract/css";
globalStyle("html, body", {
margin: 0,
padding: 0,
backgroundColor: "white",
color: "black",
fontFamily: "system-ui, sans-serif",
fontSize: 16,
fontWeight: "normal",
"@media": {
"(prefers-color-scheme: dark)": {
backgroundColor: "black",
color: "white",
},
},
});

View File

@@ -0,0 +1,5 @@
import { render } from "preact";
import "./index.css";
render(<p>Hello World</p>, document.body);

View File

@@ -0,0 +1,63 @@
import { identity } from "effect";
import { useLayoutEffect, useState } from "preact/hooks";
export type Update<T> = T | ((prev: T) => T);
export type Updater<T> = (action: Update<T>) => void;
export interface Store {
readonly count: number;
}
let store: Store = Object.freeze<Store>({
count: 0,
});
// --- STORE IMPLEMENTATION ----------------------------------------------------
class Listener<T> {
private lastState: T;
constructor(
readonly selector: Selector<T>,
readonly setState: (state: T) => void,
) {
this.lastState = selector(store);
}
react() {
const state = this.selector(store);
if (!Object.is(this.lastState, state)) {
this.lastState = state;
this.setState(state);
}
}
}
const listeners = new Set<Listener<any>>();
export type Selector<T> = (store: Store) => T;
function set(action: Partial<Store> | ((store: Store) => Partial<Store>), replace?: false): void;
function set(action: Update<Store>, replace: true): void;
function set(action: Partial<Store> | ((store: Store) => Partial<Store>), replace: boolean = false): void {
const nextPartial = typeof action === "function" ? action(store) : action;
if (Object.is(store, nextPartial)) return;
store = Object.freeze(replace ? nextPartial as Store : Object.assign({}, store, nextPartial));
for (const listener of listeners) {
listener.react();
}
}
export function useStore<T = Store>(selector: Selector<T> = identity as Selector<T>): T {
const [state, setState] = useState(() => selector(store));
useLayoutEffect(() => {
const listener = new Listener(selector, setState);
listeners.add(listener);
return () => listeners.delete(listener);
}, []);
return state;
}