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/dist/engine.d.mts CHANGED
@@ -2970,6 +2970,17 @@ declare function createHistoryFiller(base: Omit<FillHistoryViewportOptions, 'isS
2970
2970
  * loaded (`mayHaveOlder`), and it is the same event that already re-derives
2971
2971
  * `runKey` — so the view treats it as a new row either way.
2972
2972
  *
2973
+ * One row per FILE, not per run. A file indexed and later indexed again (a
2974
+ * re-upload, an explicit Reindex, a retry after a failure) has several RUNS in
2975
+ * the transcript, each opened by its own "A new file has just been uploaded"
2976
+ * pass. They are attributed as separate groups (mixing their passes would let an
2977
+ * old failure be painted over by a new success, or a new run inherit an old
2978
+ * stop), but only the NEWEST run of a file is rendered once the older ones have
2979
+ * settled. Two green "Indexed" rows for one file read as a duplicate, not as
2980
+ * history, and a superseded run's verdict is not the file's state. An older run
2981
+ * that is still working stays visible until it settles, so a double dispatch is
2982
+ * never hidden while both chains are live and its Stop button stays reachable.
2983
+ *
2973
2984
  * The group deliberately reports no authoritative pass TOTAL. History is paged
2974
2985
  * newest-first, so any total computed from loaded messages is a lower bound that
2975
2986
  * a later scroll-up would contradict. It reports STATE (indexing / indexed /
@@ -3004,12 +3015,13 @@ type IndexingGroup = {
3004
3015
  * surprised out of. */
3005
3016
  key: string;
3006
3017
  /** Identity of this ROW: one indexing RUN of that file. A file indexed on
3007
- * Monday and re-indexed on Wednesday is two runs, and collapsing them into
3008
- * one row erased Monday's from Monday's place in the conversation, claimed
3009
- * its passes for Wednesday, and let Monday's failure be overwritten by
3010
- * Wednesday's success. Named after the run's FIRST loaded pass (see where it
3011
- * is assigned below), so passes appended to the run and other runs appearing
3012
- * on either side of it never rename a row already on screen.
3018
+ * Monday and re-indexed on Wednesday is two runs, and merging them into one
3019
+ * group claimed Monday's passes for Wednesday and let Monday's failure be
3020
+ * overwritten by Wednesday's success. They stay separate groups; what the
3021
+ * view gets is only the newest of them once the rest have settled (see the
3022
+ * file docstring). Named after the run's FIRST loaded pass (see where it is
3023
+ * assigned below), so passes appended to the run and other runs appearing on
3024
+ * either side of it never rename a row already on screen.
3013
3025
  *
3014
3026
  * This is the RENDER key, and only that. It is renamed when the run's true
3015
3027
  * first pass finally loads — routine while a worker-driven chain is running,
@@ -3245,12 +3257,6 @@ declare function parseIndexingLabel(content: string): {
3245
3257
  continued: boolean;
3246
3258
  isReindex: boolean;
3247
3259
  } | null;
3248
- /**
3249
- * Collapse background-indexing turns into per-file groups.
3250
- *
3251
- * Messages that are not background-indexing pass through untouched, at their
3252
- * original positions and with their original indices.
3253
- */
3254
3260
  declare function buildChatDisplayList(messages: ChatMessage[], opts?: BuildDisplayListOptions): DisplayEntry[];
3255
3261
 
3256
3262
  /**
package/dist/engine.d.ts CHANGED
@@ -2970,6 +2970,17 @@ declare function createHistoryFiller(base: Omit<FillHistoryViewportOptions, 'isS
2970
2970
  * loaded (`mayHaveOlder`), and it is the same event that already re-derives
2971
2971
  * `runKey` — so the view treats it as a new row either way.
2972
2972
  *
2973
+ * One row per FILE, not per run. A file indexed and later indexed again (a
2974
+ * re-upload, an explicit Reindex, a retry after a failure) has several RUNS in
2975
+ * the transcript, each opened by its own "A new file has just been uploaded"
2976
+ * pass. They are attributed as separate groups (mixing their passes would let an
2977
+ * old failure be painted over by a new success, or a new run inherit an old
2978
+ * stop), but only the NEWEST run of a file is rendered once the older ones have
2979
+ * settled. Two green "Indexed" rows for one file read as a duplicate, not as
2980
+ * history, and a superseded run's verdict is not the file's state. An older run
2981
+ * that is still working stays visible until it settles, so a double dispatch is
2982
+ * never hidden while both chains are live and its Stop button stays reachable.
2983
+ *
2973
2984
  * The group deliberately reports no authoritative pass TOTAL. History is paged
2974
2985
  * newest-first, so any total computed from loaded messages is a lower bound that
2975
2986
  * a later scroll-up would contradict. It reports STATE (indexing / indexed /
@@ -3004,12 +3015,13 @@ type IndexingGroup = {
3004
3015
  * surprised out of. */
3005
3016
  key: string;
3006
3017
  /** Identity of this ROW: one indexing RUN of that file. A file indexed on
3007
- * Monday and re-indexed on Wednesday is two runs, and collapsing them into
3008
- * one row erased Monday's from Monday's place in the conversation, claimed
3009
- * its passes for Wednesday, and let Monday's failure be overwritten by
3010
- * Wednesday's success. Named after the run's FIRST loaded pass (see where it
3011
- * is assigned below), so passes appended to the run and other runs appearing
3012
- * on either side of it never rename a row already on screen.
3018
+ * Monday and re-indexed on Wednesday is two runs, and merging them into one
3019
+ * group claimed Monday's passes for Wednesday and let Monday's failure be
3020
+ * overwritten by Wednesday's success. They stay separate groups; what the
3021
+ * view gets is only the newest of them once the rest have settled (see the
3022
+ * file docstring). Named after the run's FIRST loaded pass (see where it is
3023
+ * assigned below), so passes appended to the run and other runs appearing on
3024
+ * either side of it never rename a row already on screen.
3013
3025
  *
3014
3026
  * This is the RENDER key, and only that. It is renamed when the run's true
3015
3027
  * first pass finally loads — routine while a worker-driven chain is running,
@@ -3245,12 +3257,6 @@ declare function parseIndexingLabel(content: string): {
3245
3257
  continued: boolean;
3246
3258
  isReindex: boolean;
3247
3259
  } | null;
3248
- /**
3249
- * Collapse background-indexing turns into per-file groups.
3250
- *
3251
- * Messages that are not background-indexing pass through untouched, at their
3252
- * original positions and with their original indices.
3253
- */
3254
3260
  declare function buildChatDisplayList(messages: ChatMessage[], opts?: BuildDisplayListOptions): DisplayEntry[];
3255
3261
 
3256
3262
  /**
package/dist/engine.mjs CHANGED
@@ -7918,6 +7918,29 @@ function isHiddenPass(m) {
7918
7918
  }
7919
7919
  return !!m.isPending;
7920
7920
  }
7921
+ function overlayRunRecordVerdict(grp, rec, liveIndexKeys) {
7922
+ if (!grp.members.length || grp.status === "active" || grp.cancelling) return;
7923
+ if (rec.status === "working" || typeof rec.started !== "number") return;
7924
+ if (liveIndexKeys[grp.key] || liveIndexKeys[canonIndexKey(grp.key)]) return;
7925
+ var firstTs = grp.members[0].msg._ts;
7926
+ var lastTs = grp.members[grp.members.length - 1].msg._ts;
7927
+ if (typeof lastTs !== "number" || typeof firstTs !== "number") return;
7928
+ if (rec.started > lastTs) return;
7929
+ var when = typeof rec.finished === "number" ? rec.finished : void 0;
7930
+ if (when === void 0) return;
7931
+ if (when < firstTs) return;
7932
+ if (when < lastTs - 5e3) return;
7933
+ if (rec.status === "error" || rec.status === "cancelled") {
7934
+ grp.status = rec.status;
7935
+ } else if (rec.status === "done") {
7936
+ grp.status = "done";
7937
+ } else {
7938
+ return;
7939
+ }
7940
+ grp.finished = true;
7941
+ grp.resolving = false;
7942
+ grp.resolvingReason = void 0;
7943
+ }
7921
7944
  function buildChatDisplayList(messages, opts) {
7922
7945
  var list = Array.isArray(messages) ? messages : [];
7923
7946
  var liveIndexKeys = opts && opts.liveIndexKeys || {};
@@ -8125,6 +8148,15 @@ function buildChatDisplayList(messages, opts) {
8125
8148
  grp.resolving = false;
8126
8149
  }
8127
8150
  }
8151
+ var superseded = {};
8152
+ for (var sk in runsOfKey) {
8153
+ var srs = runsOfKey[sk];
8154
+ for (var sri = 0; sri < srs.length - 1; sri++) {
8155
+ var sgp = groups[srs[sri]];
8156
+ if (!sgp || sgp.status === "active" || sgp.cancelling) continue;
8157
+ superseded[srs[sri]] = true;
8158
+ }
8159
+ }
8128
8160
  var stubList = [];
8129
8161
  var runStubs = opts && opts.runStubs;
8130
8162
  if (runStubs) {
@@ -8233,6 +8265,7 @@ function buildChatDisplayList(messages, opts) {
8233
8265
  suppressAnchor[order[ti2]] = true;
8234
8266
  tg.runKey = "run:" + (tg.path || tg.key) + "#" + trec.started;
8235
8267
  stubList.push({ started: trec.started, group: tg });
8268
+ overlayRunRecordVerdict(tg, trec, liveIndexKeys);
8236
8269
  }
8237
8270
  }
8238
8271
  stubList.sort(function(a, b) {
@@ -8253,7 +8286,7 @@ function buildChatDisplayList(messages, opts) {
8253
8286
  out.push({ kind: "message", msg: list[j], index: j });
8254
8287
  continue;
8255
8288
  }
8256
- if (groups[r].anchorIndex === j && !suppressAnchor[r]) {
8289
+ if (groups[r].anchorIndex === j && !suppressAnchor[r] && !superseded[r]) {
8257
8290
  out.push({ kind: "indexing", group: groups[r], index: j });
8258
8291
  }
8259
8292
  }