mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-07 15:52:52 +03:00
93 lines
2.7 KiB
TypeScript
93 lines
2.7 KiB
TypeScript
/**
|
|
* Antigravity GOOGLE_ONE_AI credit balance persistence.
|
|
*
|
|
* Stores last-known credit balances in the `key_value` table so they survive
|
|
* server restarts. The in-memory `creditBalanceCache` in the executor is the
|
|
* primary source at runtime; this module provides the fallback read/write layer.
|
|
*/
|
|
|
|
import { getDbInstance, isBuildPhase, isCloud } from "./core";
|
|
|
|
interface StatementLike<TRow = unknown> {
|
|
get: (...params: unknown[]) => TRow | undefined;
|
|
run: (...params: unknown[]) => { changes?: number };
|
|
all: (...params: unknown[]) => TRow[];
|
|
}
|
|
|
|
interface DbLike {
|
|
prepare: <TRow = unknown>(sql: string) => StatementLike<TRow>;
|
|
}
|
|
|
|
interface KeyValueRow {
|
|
key: string;
|
|
value: string;
|
|
}
|
|
|
|
interface CreditBalanceEntry {
|
|
balance: number;
|
|
updatedAt: string;
|
|
}
|
|
|
|
const NAMESPACE = "antigravityCreditBalance";
|
|
|
|
function parseJson(raw: string): unknown {
|
|
try {
|
|
return JSON.parse(raw);
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Read the persisted credit balance for an accountId.
|
|
* Returns the balance number, or null if not found.
|
|
*/
|
|
export function getPersistedCreditBalance(accountId: string): number | null {
|
|
if (isBuildPhase || isCloud) return null;
|
|
const db = getDbInstance() as unknown as DbLike;
|
|
const row = db
|
|
.prepare("SELECT value FROM key_value WHERE namespace = ? AND key = ?")
|
|
.get(NAMESPACE, accountId) as KeyValueRow | undefined;
|
|
if (!row?.value) return null;
|
|
const parsed = parseJson(row.value) as CreditBalanceEntry | null;
|
|
if (!parsed || typeof parsed.balance !== "number") return null;
|
|
return parsed.balance;
|
|
}
|
|
|
|
/**
|
|
* Read all persisted credit balances.
|
|
* Returns a Map of accountId → balance.
|
|
*/
|
|
export function getAllPersistedCreditBalances(): Map<string, number> {
|
|
const result = new Map<string, number>();
|
|
if (isBuildPhase || isCloud) return result;
|
|
const db = getDbInstance() as unknown as DbLike;
|
|
const rows = db
|
|
.prepare("SELECT key, value FROM key_value WHERE namespace = ?")
|
|
.all(NAMESPACE) as KeyValueRow[];
|
|
for (const row of rows) {
|
|
const parsed = parseJson(row.value) as CreditBalanceEntry | null;
|
|
if (parsed && typeof parsed.balance === "number") {
|
|
result.set(row.key, parsed.balance);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Persist a credit balance for an accountId.
|
|
*/
|
|
export function persistCreditBalance(accountId: string, balance: number): void {
|
|
if (isBuildPhase || isCloud) return;
|
|
const db = getDbInstance() as unknown as DbLike;
|
|
const entry: CreditBalanceEntry = {
|
|
balance,
|
|
updatedAt: new Date().toISOString(),
|
|
};
|
|
db.prepare("INSERT OR REPLACE INTO key_value (namespace, key, value) VALUES (?, ?, ?)").run(
|
|
NAMESPACE,
|
|
accountId,
|
|
JSON.stringify(entry)
|
|
);
|
|
}
|