refactor(app): migrate main + preload to TypeScript with typed seams (Phase 5d-3c-ii)
Convert the app's main and preload source from .js to .ts (git mv preserves history), adding types where they carry value: the core-consumption seam (BuildIndexOptions/BuildIndexResult, FileInfo), the indexer service/worker factories, and the preload IPC bridge. Module-to-module specifiers use the real .ts extension (mirroring scripts/, since Node type-stripping does not rewrite .js->.ts); the worker's runtime path stays indexer-worker.js because that is the built output. Toolchain: - Add app/tsconfig.json: strict but noImplicitAny:false (the app orchestrates the already-strict core; annotating every SQLite-handle helper is low-value churn) + allowImportingTsExtensions (safe under noEmit). - Add @types/better-sqlite3 for the injected binding. - electron.vite.config.ts inputs -> .ts; refresh the stale CommonJS comment. - typecheck script runs root + app projects. Root tsconfig excludes the app-importing tests (app-*.test.mjs, recap-capture-query.test.mjs) so the lenient app files are not dragged into the strict root program; the app source is covered by app/tsconfig.json instead. See docs/adr/0005. Verified: npm run typecheck (root + app) clean; suite 121/121; electron-vite build emits all 6 main entries + preload with no .ts/node:sqlite residue in the bundles. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
60d47a852e
commit
01a390fa10
@@ -6,7 +6,7 @@ import { tmpdir } from 'node:os';
|
||||
import { join } from 'node:path';
|
||||
|
||||
const require = createRequire(import.meta.url);
|
||||
import { createIndexerService } from '../app/src/main/indexer-service.js';
|
||||
import { createIndexerService } from '../app/src/main/indexer-service.ts';
|
||||
|
||||
function manualTimers() {
|
||||
const timers = new Set();
|
||||
|
||||
@@ -3,7 +3,7 @@ import assert from 'node:assert/strict';
|
||||
import { createRequire } from 'node:module';
|
||||
|
||||
const require = createRequire(import.meta.url);
|
||||
import { createWorkerBuildIndex } from '../app/src/main/indexer-worker-client.js';
|
||||
import { createWorkerBuildIndex } from '../app/src/main/indexer-worker-client.ts';
|
||||
|
||||
test('worker build client resolves build results from a worker thread', async () => {
|
||||
const instances = [];
|
||||
|
||||
@@ -6,7 +6,7 @@ import { tmpdir } from 'node:os';
|
||||
import { join } from 'node:path';
|
||||
|
||||
const require = createRequire(import.meta.url);
|
||||
import { buildIndex } from '../app/src/main/indexer.js';
|
||||
import { buildIndex } from '../app/src/main/indexer.ts';
|
||||
const { DatabaseSync } = require('node:sqlite');
|
||||
|
||||
class TestDatabase {
|
||||
|
||||
@@ -22,7 +22,7 @@ const require = createRequire(import.meta.url);
|
||||
// resolve each bare specifier exactly as the main module sees it (ESM resolution
|
||||
// relative to the main module's directory) and mock that URL. Relative deps are
|
||||
// resolved against the main module URL directly.
|
||||
const mainUrl = new URL('../app/src/main/index.js', import.meta.url);
|
||||
const mainUrl = new URL('../app/src/main/index.ts', import.meta.url);
|
||||
const mainPath = fileURLToPath(mainUrl);
|
||||
const mainDir = fileURLToPath(new URL('.', mainUrl));
|
||||
|
||||
@@ -37,9 +37,9 @@ function esmResolve(specifier) {
|
||||
const ELECTRON_URL = esmResolve('electron');
|
||||
const DATABASE_URL = esmResolve('better-sqlite3');
|
||||
const CHOKIDAR_URL = esmResolve('chokidar');
|
||||
const INDEXER_URL = new URL('./indexer.js', mainUrl).href;
|
||||
const INDEXER_SERVICE_URL = new URL('./indexer-service.js', mainUrl).href;
|
||||
const INDEXER_WORKER_URL = new URL('./indexer-worker-client.js', mainUrl).href;
|
||||
const INDEXER_URL = new URL('./indexer.ts', mainUrl).href;
|
||||
const INDEXER_SERVICE_URL = new URL('./indexer-service.ts', mainUrl).href;
|
||||
const INDEXER_WORKER_URL = new URL('./indexer-worker-client.ts', mainUrl).href;
|
||||
|
||||
let importCounter = 0;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import assert from 'node:assert/strict';
|
||||
import { createRequire } from 'node:module';
|
||||
|
||||
const require = createRequire(import.meta.url);
|
||||
import { buildRecapExportQuery, cleanRecapFilename } from '../app/src/main/recap-capture-query.js';
|
||||
import { buildRecapExportQuery, cleanRecapFilename } from '../app/src/main/recap-capture-query.ts';
|
||||
|
||||
test('recap export query includes the selected recap filename', () => {
|
||||
const query = buildRecapExportQuery({
|
||||
|
||||
Reference in New Issue
Block a user