fix(svelte) fix svelte
This commit is contained in:
@@ -119,6 +119,20 @@ export class IndexingPipeline {
|
||||
const filesToProcess = [...diff.added, ...diff.modified];
|
||||
let processedFiles = diff.unchanged.length; // unchanged files count as processed
|
||||
|
||||
// Report unchanged files as already processed so the progress bar
|
||||
// immediately reflects real work done (especially on incremental re-index
|
||||
// where most or all files are unchanged).
|
||||
if (processedFiles > 0) {
|
||||
const initialProgress = calculateProgress(
|
||||
processedFiles,
|
||||
totalFiles,
|
||||
0,
|
||||
0,
|
||||
this.embeddingService !== null
|
||||
);
|
||||
this.updateJob(job.id, { processedFiles, progress: initialProgress });
|
||||
}
|
||||
|
||||
for (const [i, file] of filesToProcess.entries()) {
|
||||
const checksum = file.sha || sha256(file.content);
|
||||
|
||||
|
||||
@@ -10,6 +10,46 @@ import type Database from 'better-sqlite3';
|
||||
import type { IndexingJob, NewIndexingJob } from '$lib/types';
|
||||
import type { IndexingPipeline } from './indexing.pipeline.js';
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SQL projection + row mapper (mirrors repository.service.ts pattern)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
const JOB_SELECT = `
|
||||
SELECT id,
|
||||
repository_id AS repositoryId,
|
||||
version_id AS versionId,
|
||||
status, progress,
|
||||
total_files AS totalFiles,
|
||||
processed_files AS processedFiles,
|
||||
error,
|
||||
started_at AS startedAt,
|
||||
completed_at AS completedAt,
|
||||
created_at AS createdAt
|
||||
FROM indexing_jobs`;
|
||||
|
||||
interface RawJob {
|
||||
id: string;
|
||||
repositoryId: string;
|
||||
versionId: string | null;
|
||||
status: 'queued' | 'running' | 'done' | 'failed';
|
||||
progress: number;
|
||||
totalFiles: number;
|
||||
processedFiles: number;
|
||||
error: string | null;
|
||||
startedAt: number | null;
|
||||
completedAt: number | null;
|
||||
createdAt: number;
|
||||
}
|
||||
|
||||
function mapJob(raw: RawJob): IndexingJob {
|
||||
return {
|
||||
...raw,
|
||||
startedAt: raw.startedAt != null ? new Date(raw.startedAt * 1000) : null,
|
||||
completedAt: raw.completedAt != null ? new Date(raw.completedAt * 1000) : null,
|
||||
createdAt: new Date(raw.createdAt * 1000)
|
||||
};
|
||||
}
|
||||
|
||||
export class JobQueue {
|
||||
private isRunning = false;
|
||||
private pipeline: IndexingPipeline | null = null;
|
||||
@@ -30,15 +70,19 @@ export class JobQueue {
|
||||
*/
|
||||
enqueue(repositoryId: string, versionId?: string): IndexingJob {
|
||||
// Return early if there's already an active job for this repo.
|
||||
const active = this.db
|
||||
.prepare<[string], IndexingJob>(
|
||||
`SELECT * FROM indexing_jobs
|
||||
const activeRaw = this.db
|
||||
.prepare<[string], RawJob>(
|
||||
`${JOB_SELECT}
|
||||
WHERE repository_id = ? AND status IN ('queued', 'running')
|
||||
ORDER BY created_at DESC LIMIT 1`
|
||||
)
|
||||
.get(repositoryId);
|
||||
|
||||
if (active) return active;
|
||||
if (activeRaw) {
|
||||
// Ensure the queue is draining even if enqueue was called concurrently.
|
||||
if (!this.isRunning) setImmediate(() => this.processNext());
|
||||
return mapJob(activeRaw);
|
||||
}
|
||||
|
||||
const now = Math.floor(Date.now() / 1000);
|
||||
const job: NewIndexingJob = {
|
||||
@@ -81,9 +125,9 @@ export class JobQueue {
|
||||
setImmediate(() => this.processNext());
|
||||
}
|
||||
|
||||
return this.db
|
||||
.prepare<[string], IndexingJob>(`SELECT * FROM indexing_jobs WHERE id = ?`)
|
||||
.get(job.id)!;
|
||||
return mapJob(
|
||||
this.db.prepare<[string], RawJob>(`${JOB_SELECT} WHERE id = ?`).get(job.id as string)!
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -97,16 +141,17 @@ export class JobQueue {
|
||||
return;
|
||||
}
|
||||
|
||||
const job = this.db
|
||||
.prepare<[], IndexingJob>(
|
||||
`SELECT * FROM indexing_jobs
|
||||
const rawJob = this.db
|
||||
.prepare<[], RawJob>(
|
||||
`${JOB_SELECT}
|
||||
WHERE status = 'queued'
|
||||
ORDER BY created_at ASC LIMIT 1`
|
||||
)
|
||||
.get();
|
||||
|
||||
if (!job) return;
|
||||
if (!rawJob) return;
|
||||
|
||||
const job = mapJob(rawJob);
|
||||
this.isRunning = true;
|
||||
try {
|
||||
await this.pipeline.run(job);
|
||||
@@ -134,11 +179,10 @@ export class JobQueue {
|
||||
* Retrieve a single job by ID.
|
||||
*/
|
||||
getJob(id: string): IndexingJob | null {
|
||||
return (
|
||||
this.db
|
||||
.prepare<[string], IndexingJob>(`SELECT * FROM indexing_jobs WHERE id = ?`)
|
||||
.get(id) ?? null
|
||||
);
|
||||
const raw = this.db
|
||||
.prepare<[string], RawJob>(`${JOB_SELECT} WHERE id = ?`)
|
||||
.get(id);
|
||||
return raw ? mapJob(raw) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -163,10 +207,10 @@ export class JobQueue {
|
||||
}
|
||||
|
||||
const where = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
|
||||
const sql = `SELECT * FROM indexing_jobs ${where} ORDER BY created_at DESC LIMIT ?`;
|
||||
const sql = `${JOB_SELECT} ${where} ORDER BY created_at DESC LIMIT ?`;
|
||||
params.push(limit);
|
||||
|
||||
return this.db.prepare<unknown[], IndexingJob>(sql).all(...params);
|
||||
return (this.db.prepare<unknown[], RawJob>(sql).all(...params) as RawJob[]).map(mapJob);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user