bunnyquery 1.5.3 → 1.5.5
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.css +34 -6
- package/bunnyquery.js +113 -27
- package/dist/engine.cjs +11 -10
- package/dist/engine.cjs.map +1 -1
- package/dist/engine.mjs +11 -10
- package/dist/engine.mjs.map +1 -1
- package/package.json +1 -1
- package/src/engine/session.ts +15 -6
- package/src/widget.css +34 -6
package/package.json
CHANGED
package/src/engine/session.ts
CHANGED
|
@@ -774,18 +774,26 @@ export class ChatSession {
|
|
|
774
774
|
var id = this.host.getIdentity();
|
|
775
775
|
var svcId = id.serviceId, plat = id.platform;
|
|
776
776
|
if (!svcId || plat === 'none' || !this.host.isViewMounted()) return;
|
|
777
|
+
// Index messages by _serverItemId ONCE, so the per-entry presence/pending
|
|
778
|
+
// checks below are O(1) instead of a full messages.some() scan each. With a
|
|
779
|
+
// large bg queue (bulk uploads) the old nested scan was O(queue x messages)
|
|
780
|
+
// per drain, and the drain runs once per uploaded file (O(n^3) overall).
|
|
781
|
+
var presentIds: { [id: string]: boolean } = {};
|
|
782
|
+
var pendingIds: { [id: string]: boolean } = {};
|
|
783
|
+
this.state.messages.forEach(function (m) {
|
|
784
|
+
var sid = m._serverItemId;
|
|
785
|
+
if (sid == null) return;
|
|
786
|
+
presentIds[sid] = true;
|
|
787
|
+
if (m.isPending || m.isPendingInProcess || m.isPendingQueued) pendingIds[sid] = true;
|
|
788
|
+
});
|
|
777
789
|
for (var i = this.bgTaskQueue.length - 1; i >= 0; i--) {
|
|
778
790
|
var e = this.bgTaskQueue[i];
|
|
779
791
|
if (e.serviceId !== svcId || e.platform !== plat) continue;
|
|
780
|
-
|
|
781
|
-
var stillPending = this.state.messages.some(function (m) {
|
|
782
|
-
return m._serverItemId === e.id && (m.isPending || m.isPendingInProcess || m.isPendingQueued);
|
|
783
|
-
});
|
|
784
|
-
if (present && !stillPending) this.bgTaskQueue.splice(i, 1);
|
|
792
|
+
if (presentIds[e.id] && !pendingIds[e.id]) this.bgTaskQueue.splice(i, 1);
|
|
785
793
|
}
|
|
786
794
|
this.bgTaskQueue.forEach(function (entry) {
|
|
787
795
|
if (entry.serviceId !== svcId || entry.platform !== plat) return;
|
|
788
|
-
if (
|
|
796
|
+
if (presentIds[entry.id]) return;
|
|
789
797
|
var isRunning = entry.status === 'running';
|
|
790
798
|
var userBubble: ChatMessage = { role: 'user', content: self.host.formatIndexingLabel(entry.filename, entry.mime, entry.size, entry.storagePath, entry.isReindex), isBackgroundTask: true, _serverItemId: entry.id };
|
|
791
799
|
if (isRunning) userBubble.isPendingInProcess = true; else userBubble.isPendingQueued = true;
|
|
@@ -793,6 +801,7 @@ export class ChatSession {
|
|
|
793
801
|
if (isRunning) {
|
|
794
802
|
self.state.messages.push({ role: 'assistant', content: '', isPending: true, isPendingInProcess: true, isBackgroundTask: true, _serverItemId: entry.id });
|
|
795
803
|
}
|
|
804
|
+
presentIds[entry.id] = true; // keep the index consistent with the pushed bubbles
|
|
796
805
|
self.host.notify(); self.updateHistoryCache(); self.host.scrollToBottom(false);
|
|
797
806
|
if (!self.historyItemPolls.has(entry.id) && typeof entry.poll === 'function') {
|
|
798
807
|
self.historyItemPolls.set(entry.id, true);
|
package/src/widget.css
CHANGED
|
@@ -241,14 +241,16 @@
|
|
|
241
241
|
/* ============================================================================
|
|
242
242
|
* AUTH VIEWS (login / signup / forgot / verify / settings)
|
|
243
243
|
* ==========================================================================*/
|
|
244
|
-
/* padded parent that nests a standalone page (login / signup / verify / …)
|
|
244
|
+
/* padded parent that nests a standalone page (login / signup / verify / …).
|
|
245
|
+
Sits below the shared .bq-section-title header (the top-left service badge),
|
|
246
|
+
so the top padding is small — the header supplies the top spacing. */
|
|
245
247
|
.bq-page {
|
|
246
248
|
flex: 1;
|
|
247
249
|
min-height: 0;
|
|
248
250
|
overflow-y: auto;
|
|
249
251
|
display: flex;
|
|
250
252
|
flex-direction: column;
|
|
251
|
-
padding:
|
|
253
|
+
padding: 1rem 1.5rem 2.5rem;
|
|
252
254
|
}
|
|
253
255
|
.bq-settings {
|
|
254
256
|
flex: 1;
|
|
@@ -259,6 +261,15 @@
|
|
|
259
261
|
color: var(--bq-ink);
|
|
260
262
|
}
|
|
261
263
|
|
|
264
|
+
/* full-box loading view: fill the space above the footer and center the bunny */
|
|
265
|
+
.bq-page-loading {
|
|
266
|
+
flex: 1;
|
|
267
|
+
min-height: 0;
|
|
268
|
+
display: flex;
|
|
269
|
+
align-items: center;
|
|
270
|
+
justify-content: center;
|
|
271
|
+
}
|
|
272
|
+
|
|
262
273
|
.bq-page-footer {
|
|
263
274
|
flex-shrink: 0;
|
|
264
275
|
text-align: center;
|
|
@@ -271,6 +282,12 @@
|
|
|
271
282
|
text-decoration: none;
|
|
272
283
|
}
|
|
273
284
|
.bq-page-footer-link:hover { text-decoration: underline; }
|
|
285
|
+
.bq-page-footer-version {
|
|
286
|
+
font-family: var(--bq-mono);
|
|
287
|
+
font-size: 0.7rem;
|
|
288
|
+
color: var(--bq-muted);
|
|
289
|
+
margin-top: 0.25rem;
|
|
290
|
+
}
|
|
274
291
|
|
|
275
292
|
.bq-settings-title {
|
|
276
293
|
font-size: 1.5rem;
|
|
@@ -554,11 +571,11 @@
|
|
|
554
571
|
align-items: center;
|
|
555
572
|
gap: 0.45rem;
|
|
556
573
|
padding: 0.3rem 0.6rem;
|
|
557
|
-
border: 1px solid var(--bq-
|
|
558
|
-
background: var(--bq-
|
|
574
|
+
border: 1px solid var(--bq-main);
|
|
575
|
+
background: var(--bq-main-bg);
|
|
559
576
|
font-size: 0.75rem;
|
|
560
577
|
font-family: var(--bq-mono);
|
|
561
|
-
color: var(--bq-
|
|
578
|
+
color: var(--bq-main);
|
|
562
579
|
max-width: 100%;
|
|
563
580
|
overflow: hidden;
|
|
564
581
|
}
|
|
@@ -603,7 +620,16 @@
|
|
|
603
620
|
margin: 0 auto;
|
|
604
621
|
padding: 1.25rem 0 2rem;
|
|
605
622
|
}
|
|
606
|
-
|
|
623
|
+
/* fill the messages box and center the bunny (matches .bq-history-loading.is-initial).
|
|
624
|
+
Resolves against .bq-messages (position: relative), not the max-width settings wrap. */
|
|
625
|
+
.bq-chat-settings-loading {
|
|
626
|
+
position: absolute;
|
|
627
|
+
inset: 0;
|
|
628
|
+
display: flex;
|
|
629
|
+
align-items: center;
|
|
630
|
+
justify-content: center;
|
|
631
|
+
color: var(--bq-muted);
|
|
632
|
+
}
|
|
607
633
|
|
|
608
634
|
/* chat container + scroll area */
|
|
609
635
|
.bq-chat {
|
|
@@ -751,6 +777,8 @@
|
|
|
751
777
|
.bq-input::placeholder { color: var(--bq-placeholder); }
|
|
752
778
|
.bq-input:focus { outline: none; border-color: var(--bq-ink); }
|
|
753
779
|
.bq-input:disabled { opacity: 0.5; cursor: default; }
|
|
780
|
+
/* Attach button hidden (frozen DB): reclaim the reserved left gutter. */
|
|
781
|
+
.bq-input.bq-input--noattach { padding-left: 0.7rem; }
|
|
754
782
|
.bq-input-row .btn {
|
|
755
783
|
align-self: flex-end;
|
|
756
784
|
min-width: 5.5rem;
|