feat: add server and frontend initial - wood chopping
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
import { mkdirSync } from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import { DatabaseSync } from 'node:sqlite';
|
||||
import type { ViewerRecord } from '../sim/world';
|
||||
|
||||
/**
|
||||
* Тонкий слой persist на встроенном node:sqlite — без нативных сборок и
|
||||
* install-скриптов. При необходимости заменяется (better-sqlite3/postgres)
|
||||
* без изменений в остальном коде.
|
||||
*/
|
||||
export class Db {
|
||||
private readonly db: DatabaseSync;
|
||||
|
||||
constructor(dbPath: string) {
|
||||
if (dbPath !== ':memory:') {
|
||||
mkdirSync(path.dirname(dbPath), { recursive: true });
|
||||
}
|
||||
this.db = new DatabaseSync(dbPath);
|
||||
this.db.exec('PRAGMA journal_mode = WAL');
|
||||
this.db.exec(`
|
||||
CREATE TABLE IF NOT EXISTS viewers (
|
||||
channel_id TEXT NOT NULL,
|
||||
user_id TEXT NOT NULL,
|
||||
name TEXT NOT NULL,
|
||||
color TEXT NOT NULL,
|
||||
xp INTEGER NOT NULL DEFAULT 0,
|
||||
logs INTEGER NOT NULL DEFAULT 0,
|
||||
updated_at INTEGER NOT NULL,
|
||||
PRIMARY KEY (channel_id, user_id)
|
||||
)
|
||||
`);
|
||||
}
|
||||
|
||||
loadViewers(channelId: string): ViewerRecord[] {
|
||||
const rows = this.db
|
||||
.prepare('SELECT user_id, name, color, xp, logs FROM viewers WHERE channel_id = ?')
|
||||
.all(channelId) as Array<{ user_id: string; name: string; color: string; xp: number; logs: number }>;
|
||||
return rows.map((r) => ({ userId: r.user_id, name: r.name, color: r.color, xp: r.xp, logs: r.logs }));
|
||||
}
|
||||
|
||||
saveViewer(channelId: string, v: ViewerRecord): void {
|
||||
this.db
|
||||
.prepare(
|
||||
`INSERT INTO viewers (channel_id, user_id, name, color, xp, logs, updated_at)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?)
|
||||
ON CONFLICT(channel_id, user_id) DO UPDATE SET
|
||||
name = excluded.name, color = excluded.color, xp = excluded.xp,
|
||||
logs = excluded.logs, updated_at = excluded.updated_at`,
|
||||
)
|
||||
.run(channelId, v.userId, v.name, v.color, v.xp, v.logs, Date.now());
|
||||
}
|
||||
|
||||
close(): void {
|
||||
this.db.close();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user