@threadbase-sh/streamer 1.59.0 → 1.60.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -6979,7 +6979,7 @@ var ConversationCache = class _ConversationCache {
6979
6979
  "SELECT id, project_path, project_id, last_activity FROM conversation_meta WHERE project_path IS NOT NULL"
6980
6980
  ),
6981
6981
  hasOrphanProjectId: db.prepare(
6982
- "SELECT 1 FROM conversation_meta WHERE project_id IS NULL AND project_path IS NOT NULL LIMIT 1"
6982
+ "SELECT 1 FROM conversation_meta WHERE project_id IS NULL AND project_path IS NOT NULL AND project_path != '' LIMIT 1"
6983
6983
  ),
6984
6984
  popularProjects: db.prepare(
6985
6985
  `SELECT project_path, project_name, COUNT(*) as cnt
@@ -7576,10 +7576,11 @@ var ConversationCache = class _ConversationCache {
7576
7576
  continue;
7577
7577
  }
7578
7578
  const scannerMetaJson = JSON.stringify(m);
7579
+ const projectPath = m.projectPath?.trim() || null;
7579
7580
  this.stmts.upsertFull.run({
7580
7581
  id,
7581
7582
  file_path: canonicalPath,
7582
- project_path: m.projectPath ?? null,
7583
+ project_path: projectPath,
7583
7584
  project_name: m.projectName ?? null,
7584
7585
  title: m.title ?? m.sessionName ?? m.projectName ?? null,
7585
7586
  model: m.model ?? null,
@@ -12026,7 +12027,7 @@ function isScannedSnapshotStale(snapshotTimestamp, fileMtimeMs) {
12026
12027
 
12027
12028
  // src/scanner-manager.ts
12028
12029
  var REFRESH_TTL_MS = 2e3;
12029
- var ScannerManager = class {
12030
+ var ScannerManager = class _ScannerManager {
12030
12031
  constructor(deps) {
12031
12032
  this.deps = deps;
12032
12033
  this.persistenceDisabled = deps.persistenceDisabled;
@@ -12047,6 +12048,12 @@ var ScannerManager = class {
12047
12048
  allScanners = /* @__PURE__ */ new Set();
12048
12049
  stalePaths = /* @__PURE__ */ new Set();
12049
12050
  reconcileInFlight = null;
12051
+ lastAutoFullReconcileAt = 0;
12052
+ // reconcileMode() returns "full" on every poll while a permanent drift
12053
+ // condition holds (e.g. an orphan row) — without a cooldown each poll
12054
+ // re-walks the whole corpus back-to-back. refresh=1 and per-file
12055
+ // reconciles go through other paths and are unaffected.
12056
+ static AUTO_FULL_RECONCILE_COOLDOWN_MS = 6e4;
12050
12057
  refreshInFlight = /* @__PURE__ */ new Map();
12051
12058
  log = getLogger("server");
12052
12059
  /**
@@ -12363,6 +12370,13 @@ var ScannerManager = class {
12363
12370
  // in-flight cache write before shutting the DB.
12364
12371
  startBackgroundReconcile(mode = "full") {
12365
12372
  if (this.reconcileInFlight) return;
12373
+ if (mode === "full") {
12374
+ const now = Date.now();
12375
+ if (now - this.lastAutoFullReconcileAt < _ScannerManager.AUTO_FULL_RECONCILE_COOLDOWN_MS) {
12376
+ return;
12377
+ }
12378
+ this.lastAutoFullReconcileAt = now;
12379
+ }
12366
12380
  const paths = mode === "files" ? this.takeStaleFiles() : [];
12367
12381
  const task = (paths.length > 0 ? this.reconcileStaleFilesFromDisk(paths) : this.reconcileFromDisk()).finally(() => {
12368
12382
  this.reconcileInFlight = null;