bunnyquery 1.10.0 → 1.10.2

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
@@ -1396,7 +1396,8 @@ function renderInlineLinkHtml(link, opts) {
1396
1396
  if (refreshing) cls.push("is-refreshing");
1397
1397
  if (unavailable) cls.push("is-unavailable");
1398
1398
  if (preview) cls.push("is-image-preview");
1399
- var labelText = (unavailable ? INLINE_LINK_UNAVAILABLE_GLYPH : INLINE_LINK_GLYPH) + " " + link.label + (unavailable ? INLINE_LINK_UNAVAILABLE_SUFFIX : refreshing ? " (fetching...)" : "");
1399
+ var glyphHtml = '<span class="bq-link-glyph" translate="no">' + (unavailable ? INLINE_LINK_UNAVAILABLE_GLYPH : INLINE_LINK_GLYPH) + "</span>";
1400
+ var labelHtml = glyphHtml + escapeInlineHtml(link.label + (unavailable ? INLINE_LINK_UNAVAILABLE_SUFFIX : refreshing ? " (fetching...)" : ""));
1400
1401
  var attrs = ['class="' + cls.join(" ") + '"'];
1401
1402
  if (unavailable) attrs.push('aria-disabled="true"', 'data-bq-unavailable="1"');
1402
1403
  else attrs.push('href="' + escapeInlineHtml(link.href) + '"', 'target="_blank"', 'rel="noopener noreferrer"');
@@ -1407,8 +1408,8 @@ function renderInlineLinkHtml(link, opts) {
1407
1408
  if (link.expiredHref) attrs.push('data-bq-expired-href="' + escapeInlineHtml(link.expiredHref) + '"');
1408
1409
  if (link.remotePath) attrs.push('data-bq-remote-path="' + escapeInlineHtml(link.remotePath) + '"');
1409
1410
  if (link.fullLabel) attrs.push('data-bq-full-label="' + escapeInlineHtml(link.fullLabel) + '"');
1410
- if (!preview) return "<a " + attrs.join(" ") + ">" + escapeInlineHtml(labelText) + "</a>";
1411
- return "<a " + attrs.join(" ") + '><img class="bq-img-preview" alt="' + escapeInlineHtml(full) + '" data-bq-img-path="' + escapeInlineHtml(link.remotePath || "") + '" data-bq-img-type="' + escapeInlineHtml(link.image ? link.image.contentType : "") + '" decoding="async"><span class="bq-loader" data-bq-img-loader="1"></span><span class="bq-img-preview-caption" translate="no">' + escapeInlineHtml(labelText) + "</span></a>";
1411
+ if (!preview) return "<a " + attrs.join(" ") + ">" + labelHtml + "</a>";
1412
+ return "<a " + attrs.join(" ") + '><img class="bq-img-preview" alt="' + escapeInlineHtml(full) + '" data-bq-img-path="' + escapeInlineHtml(link.remotePath || "") + '" data-bq-img-type="' + escapeInlineHtml(link.image ? link.image.contentType : "") + '" decoding="async"><span class="bq-loader" data-bq-img-loader="1"></span><span class="bq-img-preview-caption" translate="no">' + labelHtml + "</span></a>";
1412
1413
  }
1413
1414
 
1414
1415
  // src/engine/image_preview.ts
@@ -7918,6 +7919,29 @@ function isHiddenPass(m) {
7918
7919
  }
7919
7920
  return !!m.isPending;
7920
7921
  }
7922
+ function overlayRunRecordVerdict(grp, rec, liveIndexKeys) {
7923
+ if (!grp.members.length || grp.status === "active" || grp.cancelling) return;
7924
+ if (rec.status === "working" || typeof rec.started !== "number") return;
7925
+ if (liveIndexKeys[grp.key] || liveIndexKeys[canonIndexKey(grp.key)]) return;
7926
+ var firstTs = grp.members[0].msg._ts;
7927
+ var lastTs = grp.members[grp.members.length - 1].msg._ts;
7928
+ if (typeof lastTs !== "number" || typeof firstTs !== "number") return;
7929
+ if (rec.started > lastTs) return;
7930
+ var when = typeof rec.finished === "number" ? rec.finished : void 0;
7931
+ if (when === void 0) return;
7932
+ if (when < firstTs) return;
7933
+ if (when < lastTs - 5e3) return;
7934
+ if (rec.status === "error" || rec.status === "cancelled") {
7935
+ grp.status = rec.status;
7936
+ } else if (rec.status === "done") {
7937
+ grp.status = "done";
7938
+ } else {
7939
+ return;
7940
+ }
7941
+ grp.finished = true;
7942
+ grp.resolving = false;
7943
+ grp.resolvingReason = void 0;
7944
+ }
7921
7945
  function buildChatDisplayList(messages, opts) {
7922
7946
  var list = Array.isArray(messages) ? messages : [];
7923
7947
  var liveIndexKeys = opts && opts.liveIndexKeys || {};
@@ -8125,6 +8149,15 @@ function buildChatDisplayList(messages, opts) {
8125
8149
  grp.resolving = false;
8126
8150
  }
8127
8151
  }
8152
+ var superseded = {};
8153
+ for (var sk in runsOfKey) {
8154
+ var srs = runsOfKey[sk];
8155
+ for (var sri = 0; sri < srs.length - 1; sri++) {
8156
+ var sgp = groups[srs[sri]];
8157
+ if (!sgp || sgp.status === "active" || sgp.cancelling) continue;
8158
+ superseded[srs[sri]] = true;
8159
+ }
8160
+ }
8128
8161
  var stubList = [];
8129
8162
  var runStubs = opts && opts.runStubs;
8130
8163
  if (runStubs) {
@@ -8233,6 +8266,7 @@ function buildChatDisplayList(messages, opts) {
8233
8266
  suppressAnchor[order[ti2]] = true;
8234
8267
  tg.runKey = "run:" + (tg.path || tg.key) + "#" + trec.started;
8235
8268
  stubList.push({ started: trec.started, group: tg });
8269
+ overlayRunRecordVerdict(tg, trec, liveIndexKeys);
8236
8270
  }
8237
8271
  }
8238
8272
  stubList.sort(function(a, b) {
@@ -8253,7 +8287,7 @@ function buildChatDisplayList(messages, opts) {
8253
8287
  out.push({ kind: "message", msg: list[j], index: j });
8254
8288
  continue;
8255
8289
  }
8256
- if (groups[r].anchorIndex === j && !suppressAnchor[r]) {
8290
+ if (groups[r].anchorIndex === j && !suppressAnchor[r] && !superseded[r]) {
8257
8291
  out.push({ kind: "indexing", group: groups[r], index: j });
8258
8292
  }
8259
8293
  }