@threadbase-sh/streamer 1.36.2 → 1.36.3
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/cli.cjs +31 -8
- package/dist/cli.cjs.map +1 -1
- package/dist/index.cjs +31 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +31 -8
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -144085,6 +144085,10 @@ var StreamerServer = class {
|
|
|
144085
144085
|
// Set by onConversationChanged while a scan is in-flight; getScanner() does
|
|
144086
144086
|
// a single rescan after the current one completes instead of restarting it.
|
|
144087
144087
|
scannerStale = false;
|
|
144088
|
+
// Single-flight guard for the background disk reconcile: a burst of list
|
|
144089
|
+
// polls during active session writes shares one rescan instead of queueing
|
|
144090
|
+
// a full rescan per request.
|
|
144091
|
+
conversationReconcileInFlight = null;
|
|
144088
144092
|
// Single-flight + TTL guard around scanner.refreshFile (see refreshFileGuarded).
|
|
144089
144093
|
// A live file's mtime is always newer than the snapshot, so an unguarded
|
|
144090
144094
|
// refresh fires on every request and re-parses the whole file from byte 0.
|
|
@@ -145102,9 +145106,9 @@ var StreamerServer = class {
|
|
|
145102
145106
|
* the automatic freshness path when the directory watcher marked the scanner
|
|
145103
145107
|
* stale or shouldRefreshProjectsFromHdd detected disk drift.
|
|
145104
145108
|
*/
|
|
145105
|
-
async reconcileConversationsCacheFromDisk() {
|
|
145109
|
+
async reconcileConversationsCacheFromDisk(onProgress) {
|
|
145106
145110
|
if (!this.cache) return;
|
|
145107
|
-
const scanner = await this.rescanForRefresh();
|
|
145111
|
+
const scanner = await this.rescanForRefresh(onProgress);
|
|
145108
145112
|
const metas = [...scanner.getMetadataCache().values()];
|
|
145109
145113
|
try {
|
|
145110
145114
|
this.cache.upsertFromScannerMeta(metas);
|
|
@@ -145132,6 +145136,18 @@ var StreamerServer = class {
|
|
|
145132
145136
|
);
|
|
145133
145137
|
}
|
|
145134
145138
|
}
|
|
145139
|
+
// Reconcile the cache from disk without blocking the caller. Single-flighted
|
|
145140
|
+
// so a burst of list polls during active session writes shares one rescan
|
|
145141
|
+
// rather than queueing a full rescan each; tracked so close() awaits the
|
|
145142
|
+
// in-flight cache write before shutting the DB.
|
|
145143
|
+
startBackgroundConversationReconcile() {
|
|
145144
|
+
if (this.conversationReconcileInFlight) return;
|
|
145145
|
+
const task = this.reconcileConversationsCacheFromDisk().finally(() => {
|
|
145146
|
+
this.conversationReconcileInFlight = null;
|
|
145147
|
+
});
|
|
145148
|
+
this.conversationReconcileInFlight = task;
|
|
145149
|
+
this.trackCacheWrite(task);
|
|
145150
|
+
}
|
|
145135
145151
|
shouldAutoReconcileConversationList() {
|
|
145136
145152
|
if (!this.cache) return false;
|
|
145137
145153
|
if (this.scannerStale) return true;
|
|
@@ -145149,13 +145165,19 @@ var StreamerServer = class {
|
|
|
145149
145165
|
const providerFilter = url2.searchParams.get("provider") ?? void 0;
|
|
145150
145166
|
const bustCache = url2.searchParams.get("refresh") === "1";
|
|
145151
145167
|
if (this.cache && (bustCache || this.shouldAutoReconcileConversationList())) {
|
|
145152
|
-
|
|
145168
|
+
const canServeStale = !bustCache && this.cache.listConversations({ limit: 0, offset: 0 }).total > 0;
|
|
145169
|
+
if (canServeStale) {
|
|
145170
|
+
this.startBackgroundConversationReconcile();
|
|
145171
|
+
} else {
|
|
145172
|
+
const shouldEmitProgress = createScanProgressThrottle();
|
|
145153
145173
|
await this.withWarmup(
|
|
145154
145174
|
"conversation_refresh",
|
|
145155
|
-
() => this.reconcileConversationsCacheFromDisk()
|
|
145175
|
+
() => this.reconcileConversationsCacheFromDisk((scanned, total2) => {
|
|
145176
|
+
if (shouldEmitProgress(scanned, total2)) {
|
|
145177
|
+
this.wsHub.broadcast({ type: "scan_progress", scanned, total: total2 });
|
|
145178
|
+
}
|
|
145179
|
+
})
|
|
145156
145180
|
);
|
|
145157
|
-
} else {
|
|
145158
|
-
await this.reconcileConversationsCacheFromDisk();
|
|
145159
145181
|
}
|
|
145160
145182
|
}
|
|
145161
145183
|
if (this.cache) {
|
|
@@ -145391,7 +145413,7 @@ var StreamerServer = class {
|
|
|
145391
145413
|
// getFreshScanner() this does NOT discard the warm scanner. scannerReady is
|
|
145392
145414
|
// only ever reassigned to a live scan promise (never nulled mid-scan), so the
|
|
145393
145415
|
// getScanner() anti-infinite-loop guard is preserved.
|
|
145394
|
-
async rescanForRefresh() {
|
|
145416
|
+
async rescanForRefresh(onProgress) {
|
|
145395
145417
|
if (this.scannerReady) await this.scannerReady;
|
|
145396
145418
|
this.scannerStale = false;
|
|
145397
145419
|
if (!this.scanner) {
|
|
@@ -145402,7 +145424,8 @@ var StreamerServer = class {
|
|
|
145402
145424
|
this.scannerReady = scanner.scan({
|
|
145403
145425
|
...this.scanProfiles ? { profiles: this.scanProfiles } : {},
|
|
145404
145426
|
...this.codexScanOpts(),
|
|
145405
|
-
fullRescan: true
|
|
145427
|
+
fullRescan: true,
|
|
145428
|
+
...onProgress ? { onProgress } : {}
|
|
145406
145429
|
});
|
|
145407
145430
|
await this.scannerReady;
|
|
145408
145431
|
return scanner;
|