refactor: remove root node and npm workflow deps

This commit is contained in:
2026-03-07 21:19:14 -08:00
parent f0418c6e56
commit d0c11d347b
32 changed files with 215 additions and 299 deletions

View File

@@ -1,4 +1,4 @@
import type { DatabaseSync } from 'node:sqlite';
import type { DatabaseSync } from './sqlite';
const ROLLUP_STATE_KEY = 'last_rollup_sample_ms';
const DAILY_MS = 86_400_000;

View File

@@ -1,4 +1,4 @@
import type { DatabaseSync } from 'node:sqlite';
import type { DatabaseSync } from './sqlite';
import type {
ImmersionSessionRollupRow,
SessionSummaryQueryRow,
@@ -44,7 +44,7 @@ export function getSessionTimeline(
cards_mined AS cardsMined
FROM imm_session_telemetry
WHERE session_id = ?
ORDER BY sample_ms DESC
ORDER BY sample_ms DESC, telemetry_id DESC
LIMIT ?
`);
return prepared.all(sessionId, limit) as unknown as SessionTimelineRow[];
@@ -56,8 +56,8 @@ export function getQueryHints(db: DatabaseSync): {
} {
const sessions = db.prepare('SELECT COUNT(*) AS total FROM imm_sessions');
const active = db.prepare('SELECT COUNT(*) AS total FROM imm_sessions WHERE ended_at_ms IS NULL');
const totalSessions = Number(sessions.get()?.total ?? 0);
const activeSessions = Number(active.get()?.total ?? 0);
const totalSessions = Number((sessions.get() as { total?: number } | null)?.total ?? 0);
const activeSessions = Number((active.get() as { total?: number } | null)?.total ?? 0);
return { totalSessions, activeSessions };
}

View File

@@ -1,5 +1,5 @@
import crypto from 'node:crypto';
import type { DatabaseSync } from 'node:sqlite';
import type { DatabaseSync } from './sqlite';
import { createInitialSessionState } from './reducer';
import { SESSION_STATUS_ACTIVE, SESSION_STATUS_ENDED } from './types';
import type { SessionState } from './types';

View File

@@ -0,0 +1,20 @@
import Database = require('libsql');
export { Database };
export interface DatabaseRunResult {
changes: number;
lastInsertRowid: number | bigint;
}
export interface DatabaseStatement {
run(...params: unknown[]): DatabaseRunResult;
get(...params: unknown[]): unknown;
all(...params: unknown[]): unknown[];
}
export interface DatabaseSync {
prepare(source: string): DatabaseStatement;
exec(source: string): DatabaseSync;
close(): DatabaseSync;
}

View File

@@ -3,7 +3,7 @@ import fs from 'node:fs';
import os from 'node:os';
import path from 'node:path';
import test from 'node:test';
import type { DatabaseSync as NodeDatabaseSync } from 'node:sqlite';
import { Database } from './sqlite';
import { finalizeSessionRecord, startSessionRecord } from './session';
import {
createTrackerPreparedStatements,
@@ -13,22 +13,6 @@ import {
} from './storage';
import { EVENT_SUBTITLE_LINE, SESSION_STATUS_ENDED, SOURCE_TYPE_LOCAL } from './types';
type DatabaseSyncCtor = typeof NodeDatabaseSync;
const DatabaseSync: DatabaseSyncCtor | null = (() => {
try {
return (require('node:sqlite') as { DatabaseSync?: DatabaseSyncCtor }).DatabaseSync ?? null;
} catch {
return null;
}
})();
const testIfSqlite = DatabaseSync ? test : test.skip;
if (!DatabaseSync) {
console.warn(
'Skipping SQLite-backed immersion tracker storage/session tests in this runtime; run `bun run test:immersion:sqlite` for real DB coverage.',
);
}
function makeDbPath(): string {
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'subminer-imm-storage-session-'));
return path.join(dir, 'immersion.sqlite');
@@ -41,9 +25,9 @@ function cleanupDbPath(dbPath: string): void {
}
}
testIfSqlite('ensureSchema creates immersion core tables', () => {
test('ensureSchema creates immersion core tables', () => {
const dbPath = makeDbPath();
const db = new DatabaseSync!(dbPath);
const db = new Database(dbPath);
try {
ensureSchema(db);
@@ -77,9 +61,9 @@ testIfSqlite('ensureSchema creates immersion core tables', () => {
}
});
testIfSqlite('start/finalize session updates ended_at and status', () => {
test('start/finalize session updates ended_at and status', () => {
const dbPath = makeDbPath();
const db = new DatabaseSync!(dbPath);
const db = new Database(dbPath);
try {
ensureSchema(db);
@@ -111,9 +95,9 @@ testIfSqlite('start/finalize session updates ended_at and status', () => {
}
});
testIfSqlite('executeQueuedWrite inserts event and telemetry rows', () => {
test('executeQueuedWrite inserts event and telemetry rows', () => {
const dbPath = makeDbPath();
const db = new DatabaseSync!(dbPath);
const db = new Database(dbPath);
try {
ensureSchema(db);
@@ -178,9 +162,9 @@ testIfSqlite('executeQueuedWrite inserts event and telemetry rows', () => {
}
});
testIfSqlite('executeQueuedWrite inserts and upserts word and kanji rows', () => {
test('executeQueuedWrite inserts and upserts word and kanji rows', () => {
const dbPath = makeDbPath();
const db = new DatabaseSync!(dbPath);
const db = new Database(dbPath);
try {
ensureSchema(db);

View File

@@ -1,4 +1,4 @@
import type { DatabaseSync } from 'node:sqlite';
import type { DatabaseSync } from './sqlite';
import { SCHEMA_VERSION } from './types';
import type { QueuedWrite, VideoMetadata } from './types';
@@ -13,7 +13,7 @@ function hasColumn(db: DatabaseSync, tableName: string, columnName: string): boo
return db
.prepare(`PRAGMA table_info(${tableName})`)
.all()
.some((row) => (row as { name: string }).name === columnName);
.some((row: unknown) => (row as { name: string }).name === columnName);
}
function addColumnIfMissing(db: DatabaseSync, tableName: string, columnName: string): void {