pmarket-cli
Version:
CLI tool to trade on Polymarket
113 lines (111 loc) • 4.2 kB
JavaScript
import Database from 'better-sqlite3';
import { join } from 'path';
const CACHE_DB = 'cache.db';
const CACHE_TTL_MS = 60 * 60 * 1000; // 1 hour
export class CacheService {
db;
constructor(configService) {
const dbPath = join(configService.getConfigDir(), CACHE_DB);
this.db = new Database(dbPath);
this.initializeSchema();
}
initializeSchema() {
this.db.exec(`
CREATE TABLE IF NOT EXISTS markets (
condition_id TEXT PRIMARY KEY,
question TEXT,
description TEXT,
category TEXT,
end_date_iso TEXT,
active INTEGER,
closed INTEGER,
yes_token_id TEXT,
no_token_id TEXT,
yes_outcome TEXT,
no_outcome TEXT,
cached_at INTEGER
);
CREATE TABLE IF NOT EXISTS cache_metadata (
key TEXT PRIMARY KEY,
value TEXT
);
CREATE INDEX IF NOT EXISTS idx_markets_question ON markets(question);
CREATE INDEX IF NOT EXISTS idx_markets_active ON markets(active, closed);
`);
}
isCacheValid() {
const stmt = this.db.prepare('SELECT value FROM cache_metadata WHERE key = ?');
const row = stmt.get('last_full_refresh');
if (!row) {
return false;
}
const lastRefresh = parseInt(row.value, 10);
return Date.now() - lastRefresh < CACHE_TTL_MS;
}
getCachedMarkets(filter) {
let query = 'SELECT * FROM markets WHERE active = 1 AND closed = 0';
const params = [];
if (filter) {
query += ' AND LOWER(question) LIKE ?';
params.push(`%${filter.toLowerCase()}%`);
}
const stmt = this.db.prepare(query);
return stmt.all(...params);
}
cacheMarkets(markets) {
const insertStmt = this.db.prepare(`
INSERT OR REPLACE INTO markets
(condition_id, question, description, category, end_date_iso, active, closed, yes_token_id, no_token_id, yes_outcome, no_outcome, cached_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
`);
const now = Date.now();
const insertMany = this.db.transaction((markets) => {
for (const market of markets) {
insertStmt.run(market.condition_id, market.question, market.description, market.category, market.end_date_iso, market.active ? 1 : 0, market.closed ? 1 : 0, market.tokens[0]?.token_id ?? '', market.tokens[1]?.token_id ?? '', market.tokens[0]?.outcome ?? 'Yes', market.tokens[1]?.outcome ?? 'No', now);
}
});
insertMany(markets);
const metaStmt = this.db.prepare('INSERT OR REPLACE INTO cache_metadata (key, value) VALUES (?, ?)');
metaStmt.run('last_full_refresh', now.toString());
}
clearCache() {
this.db.exec('DELETE FROM markets');
this.db.exec('DELETE FROM cache_metadata');
}
getMarketCount() {
const stmt = this.db.prepare('SELECT COUNT(*) as count FROM markets');
const row = stmt.get();
return row.count;
}
getCacheAge() {
const stmt = this.db.prepare('SELECT value FROM cache_metadata WHERE key = ?');
const row = stmt.get('last_full_refresh');
if (!row) {
return null;
}
const lastRefresh = parseInt(row.value, 10);
const ageMs = Date.now() - lastRefresh;
const minutes = Math.floor(ageMs / (1000 * 60));
const hours = Math.floor(minutes / 60);
const days = Math.floor(hours / 24);
if (days > 0) {
return `${days} day${days > 1 ? 's' : ''} ago`;
}
else if (hours > 0) {
return `${hours} hour${hours > 1 ? 's' : ''} ago`;
}
else if (minutes > 0) {
return `${minutes} minute${minutes > 1 ? 's' : ''} ago`;
}
else {
return 'just now';
}
}
hasCache() {
return this.getMarketCount() > 0;
}
close() {
this.db.close();
}
}
//# sourceMappingURL=cache.service.js.map