bunnyquery 1.10.0 → 1.10.1
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/bunnyquery.js +35 -2
- package/dist/engine.cjs +34 -1
- package/dist/engine.cjs.map +1 -1
- package/dist/engine.d.mts +18 -12
- package/dist/engine.d.ts +18 -12
- package/dist/engine.mjs +34 -1
- package/dist/engine.mjs.map +1 -1
- package/package.json +1 -1
- package/src/engine/indexing_groups.ts +86 -7
package/package.json
CHANGED
|
@@ -36,6 +36,17 @@
|
|
|
36
36
|
* loaded (`mayHaveOlder`), and it is the same event that already re-derives
|
|
37
37
|
* `runKey` — so the view treats it as a new row either way.
|
|
38
38
|
*
|
|
39
|
+
* One row per FILE, not per run. A file indexed and later indexed again (a
|
|
40
|
+
* re-upload, an explicit Reindex, a retry after a failure) has several RUNS in
|
|
41
|
+
* the transcript, each opened by its own "A new file has just been uploaded"
|
|
42
|
+
* pass. They are attributed as separate groups (mixing their passes would let an
|
|
43
|
+
* old failure be painted over by a new success, or a new run inherit an old
|
|
44
|
+
* stop), but only the NEWEST run of a file is rendered once the older ones have
|
|
45
|
+
* settled. Two green "Indexed" rows for one file read as a duplicate, not as
|
|
46
|
+
* history, and a superseded run's verdict is not the file's state. An older run
|
|
47
|
+
* that is still working stays visible until it settles, so a double dispatch is
|
|
48
|
+
* never hidden while both chains are live and its Stop button stays reachable.
|
|
49
|
+
*
|
|
39
50
|
* The group deliberately reports no authoritative pass TOTAL. History is paged
|
|
40
51
|
* newest-first, so any total computed from loaded messages is a lower bound that
|
|
41
52
|
* a later scroll-up would contradict. It reports STATE (indexing / indexed /
|
|
@@ -75,12 +86,13 @@ export type IndexingGroup = {
|
|
|
75
86
|
* surprised out of. */
|
|
76
87
|
key: string;
|
|
77
88
|
/** Identity of this ROW: one indexing RUN of that file. A file indexed on
|
|
78
|
-
* Monday and re-indexed on Wednesday is two runs, and
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
89
|
+
* Monday and re-indexed on Wednesday is two runs, and merging them into one
|
|
90
|
+
* group claimed Monday's passes for Wednesday and let Monday's failure be
|
|
91
|
+
* overwritten by Wednesday's success. They stay separate groups; what the
|
|
92
|
+
* view gets is only the newest of them once the rest have settled (see the
|
|
93
|
+
* file docstring). Named after the run's FIRST loaded pass (see where it is
|
|
94
|
+
* assigned below), so passes appended to the run and other runs appearing on
|
|
95
|
+
* either side of it never rename a row already on screen.
|
|
84
96
|
*
|
|
85
97
|
* This is the RENDER key, and only that. It is renamed when the run's true
|
|
86
98
|
* first pass finally loads — routine while a worker-driven chain is running,
|
|
@@ -395,6 +407,48 @@ function isHiddenPass(m: ChatMessage): boolean {
|
|
|
395
407
|
* Messages that are not background-indexing pass through untouched, at their
|
|
396
408
|
* original positions and with their original indices.
|
|
397
409
|
*/
|
|
410
|
+
/**
|
|
411
|
+
* A loaded group reads its state off its newest loaded pass, and for a run the WORKER
|
|
412
|
+
* ended (three failed retries, a stale grant, a cap-out) that pass looks settled: the
|
|
413
|
+
* model answered normally, the failure happened after. The run:: record is the only
|
|
414
|
+
* thing that knows, and until now it was consulted for record-only stubs alone, so
|
|
415
|
+
* the chat row said "Indexed", the files page took that as a verdict and painted the
|
|
416
|
+
* badge green over the record's "error". The record's terminal verdict is laid over
|
|
417
|
+
* the group when it describes THIS run (started no later than the newest loaded pass)
|
|
418
|
+
* and is newer than that pass; visible work and a live queue hit still outrank it.
|
|
419
|
+
*/
|
|
420
|
+
function overlayRunRecordVerdict(
|
|
421
|
+
grp: IndexingGroup,
|
|
422
|
+
rec: RunStubInfo,
|
|
423
|
+
liveIndexKeys: { [key: string]: boolean },
|
|
424
|
+
): void {
|
|
425
|
+
if (!grp.members.length || grp.status === 'active' || grp.cancelling) return;
|
|
426
|
+
if (rec.status === 'working' || typeof rec.started !== 'number') return;
|
|
427
|
+
if (liveIndexKeys[grp.key] || liveIndexKeys[canonIndexKey(grp.key)]) return;
|
|
428
|
+
var firstTs = grp.members[0].msg._ts;
|
|
429
|
+
var lastTs = grp.members[grp.members.length - 1].msg._ts;
|
|
430
|
+
if (typeof lastTs !== 'number' || typeof firstTs !== 'number') return;
|
|
431
|
+
// a record that started after the newest loaded pass is a LATER run, not this one
|
|
432
|
+
if (rec.started > lastTs) return;
|
|
433
|
+
var when = typeof rec.finished === 'number' ? rec.finished : undefined;
|
|
434
|
+
if (when === undefined) return;
|
|
435
|
+
// a record that ENDED before this run began describes a previous run
|
|
436
|
+
if (when < firstTs) return;
|
|
437
|
+
// the record's verdict must be at least as new as the pass it would override
|
|
438
|
+
// (a few seconds of slack: the worker closes the record right after the pass lands)
|
|
439
|
+
if (when < lastTs - 5000) return;
|
|
440
|
+
if (rec.status === 'error' || rec.status === 'cancelled') {
|
|
441
|
+
grp.status = rec.status;
|
|
442
|
+
} else if (rec.status === 'done') {
|
|
443
|
+
grp.status = 'done';
|
|
444
|
+
} else {
|
|
445
|
+
return;
|
|
446
|
+
}
|
|
447
|
+
grp.finished = true;
|
|
448
|
+
grp.resolving = false;
|
|
449
|
+
grp.resolvingReason = undefined;
|
|
450
|
+
}
|
|
451
|
+
|
|
398
452
|
export function buildChatDisplayList(
|
|
399
453
|
messages: ChatMessage[],
|
|
400
454
|
opts?: BuildDisplayListOptions,
|
|
@@ -812,6 +866,28 @@ export function buildChatDisplayList(
|
|
|
812
866
|
}
|
|
813
867
|
}
|
|
814
868
|
|
|
869
|
+
// --- superseded runs -------------------------------------------------------
|
|
870
|
+
// Every run of a file but its newest is history the newest run replaced: the
|
|
871
|
+
// file's state is the newest run's, and a second "Indexed" row for the same
|
|
872
|
+
// file reads as a duplicate (reported as exactly that, for files re-indexed
|
|
873
|
+
// during testing). Such a run keeps its group (its passes stay attributed to
|
|
874
|
+
// it, never demoted to loose "Indexing: ..." bubbles) but draws no row.
|
|
875
|
+
//
|
|
876
|
+
// ONLY once it has settled. An older run that is still working, or still
|
|
877
|
+
// stopping, is live work the user can see the effects of and may want to stop,
|
|
878
|
+
// and hiding it would also hide a double dispatch (two chains reading one file)
|
|
879
|
+
// for as long as both ran. Runs open in walk order, and the walk is request
|
|
880
|
+
// creation order, so the last run of a key is its newest.
|
|
881
|
+
var superseded: { [runId: string]: boolean } = {};
|
|
882
|
+
for (var sk in runsOfKey) {
|
|
883
|
+
var srs = runsOfKey[sk];
|
|
884
|
+
for (var sri = 0; sri < srs.length - 1; sri++) {
|
|
885
|
+
var sgp = groups[srs[sri]];
|
|
886
|
+
if (!sgp || sgp.status === 'active' || sgp.cancelling) continue;
|
|
887
|
+
superseded[srs[sri]] = true;
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
|
|
815
891
|
// --- durable run:: stubs ---------------------------------------------------
|
|
816
892
|
// A run record whose passes are not among the loaded messages still deserves
|
|
817
893
|
// a row: on a fresh open the bg history is deferred, and a run older than the
|
|
@@ -991,6 +1067,7 @@ export function buildChatDisplayList(
|
|
|
991
1067
|
// record-only to loaded-passes keeps its DOM node and its position.
|
|
992
1068
|
tg.runKey = 'run:' + (tg.path || tg.key) + '#' + trec.started;
|
|
993
1069
|
stubList.push({ started: trec.started, group: tg });
|
|
1070
|
+
overlayRunRecordVerdict(tg, trec, liveIndexKeys);
|
|
994
1071
|
}
|
|
995
1072
|
}
|
|
996
1073
|
stubList.sort(function (a, b) { return a.started - b.started; });
|
|
@@ -1015,7 +1092,9 @@ export function buildChatDisplayList(
|
|
|
1015
1092
|
// Every other member of the run is represented by the row at the anchor —
|
|
1016
1093
|
// unless the row is timestamp-anchored (incomplete run with a run::
|
|
1017
1094
|
// record), in which case the flush above already emitted it.
|
|
1018
|
-
|
|
1095
|
+
// ...or the run is superseded, in which case nothing is emitted for it at
|
|
1096
|
+
// all: its members are represented by the newer run's row.
|
|
1097
|
+
if (groups[r].anchorIndex === j && !suppressAnchor[r] && !superseded[r]) {
|
|
1019
1098
|
out.push({ kind: 'indexing', group: groups[r], index: j });
|
|
1020
1099
|
}
|
|
1021
1100
|
}
|