bunnyquery 1.8.14 → 1.8.15
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 +221 -25
- package/dist/engine.cjs +171 -12
- package/dist/engine.cjs.map +1 -1
- package/dist/engine.d.mts +62 -0
- package/dist/engine.d.ts +62 -0
- package/dist/engine.mjs +171 -12
- package/dist/engine.mjs.map +1 -1
- package/package.json +1 -1
- package/src/engine/host.ts +14 -0
- package/src/engine/scroll_anchor.ts +328 -11
- package/src/engine/session.ts +11 -1
package/dist/engine.cjs
CHANGED
|
@@ -2580,6 +2580,8 @@ function shouldRescueInFlightMessage(m, ctx) {
|
|
|
2580
2580
|
// src/engine/scroll_anchor.ts
|
|
2581
2581
|
var ROW_KEY_ATTR = "data-row-key";
|
|
2582
2582
|
var ROW_POS_ATTR = "data-row-pos";
|
|
2583
|
+
var MAX_ALTS = 2;
|
|
2584
|
+
var ALT_SCAN_LIMIT = 64;
|
|
2583
2585
|
var UNKNOWN_ROW_POS = "\0?";
|
|
2584
2586
|
function createScrollAnchor(options) {
|
|
2585
2587
|
var held = null;
|
|
@@ -2590,6 +2592,7 @@ function createScrollAnchor(options) {
|
|
|
2590
2592
|
var boxTop = box.getBoundingClientRect().top;
|
|
2591
2593
|
var kids = box.children;
|
|
2592
2594
|
var fallback = null;
|
|
2595
|
+
var fallbackAt = -1;
|
|
2593
2596
|
for (var i = 0; i < kids.length; i++) {
|
|
2594
2597
|
var el = kids[i];
|
|
2595
2598
|
if (!el || typeof el.getAttribute !== "function") continue;
|
|
@@ -2608,10 +2611,20 @@ function createScrollAnchor(options) {
|
|
|
2608
2611
|
scrollHeight: box.scrollHeight,
|
|
2609
2612
|
el
|
|
2610
2613
|
};
|
|
2611
|
-
if (rawPos === null)
|
|
2612
|
-
|
|
2614
|
+
if (rawPos === null) {
|
|
2615
|
+
cand.alts = collectAlts(box, boxTop, i + 1);
|
|
2616
|
+
return cand;
|
|
2617
|
+
}
|
|
2618
|
+
if (!fallback) {
|
|
2619
|
+
fallback = cand;
|
|
2620
|
+
fallbackAt = i;
|
|
2621
|
+
}
|
|
2622
|
+
}
|
|
2623
|
+
if (fallback) {
|
|
2624
|
+
fallback.alts = collectAlts(box, boxTop, fallbackAt + 1, true);
|
|
2625
|
+
return fallback;
|
|
2613
2626
|
}
|
|
2614
|
-
return
|
|
2627
|
+
return {
|
|
2615
2628
|
key: null,
|
|
2616
2629
|
top: 0,
|
|
2617
2630
|
pos: null,
|
|
@@ -2620,6 +2633,26 @@ function createScrollAnchor(options) {
|
|
|
2620
2633
|
el: null
|
|
2621
2634
|
};
|
|
2622
2635
|
}
|
|
2636
|
+
function collectAlts(box, boxTop, from, ordinaryOnly) {
|
|
2637
|
+
var out = [];
|
|
2638
|
+
var kids = box.children;
|
|
2639
|
+
var stop = Math.min(kids.length, from + ALT_SCAN_LIMIT);
|
|
2640
|
+
for (var i = from; i < stop && out.length < MAX_ALTS; i++) {
|
|
2641
|
+
var el = kids[i];
|
|
2642
|
+
if (!el || typeof el.getAttribute !== "function") continue;
|
|
2643
|
+
var key = el.getAttribute(ROW_KEY_ATTR);
|
|
2644
|
+
if (!key) continue;
|
|
2645
|
+
var rawPos = el.getAttribute(ROW_POS_ATTR);
|
|
2646
|
+
if (ordinaryOnly && rawPos !== null) continue;
|
|
2647
|
+
out.push({
|
|
2648
|
+
key,
|
|
2649
|
+
top: el.getBoundingClientRect().top - boxTop,
|
|
2650
|
+
pos: rawPos === null ? null : rawPos || UNKNOWN_ROW_POS,
|
|
2651
|
+
el
|
|
2652
|
+
});
|
|
2653
|
+
}
|
|
2654
|
+
return out.length ? out : void 0;
|
|
2655
|
+
}
|
|
2623
2656
|
function findRow(box, anchor) {
|
|
2624
2657
|
var el = anchor.el;
|
|
2625
2658
|
if (el && el.parentNode === box) return el;
|
|
@@ -2632,31 +2665,79 @@ function createScrollAnchor(options) {
|
|
|
2632
2665
|
}
|
|
2633
2666
|
return null;
|
|
2634
2667
|
}
|
|
2635
|
-
|
|
2668
|
+
var sawFrozen = false;
|
|
2669
|
+
var parked = null;
|
|
2670
|
+
var parkedStuck = false;
|
|
2671
|
+
var returning = false;
|
|
2672
|
+
var wroteTop = -1;
|
|
2673
|
+
var restoreExact = true;
|
|
2674
|
+
var restorePinned = false;
|
|
2675
|
+
function frozen() {
|
|
2676
|
+
var f = !!options.isFrozen && options.isFrozen();
|
|
2677
|
+
if (f) sawFrozen = true;
|
|
2678
|
+
return f;
|
|
2679
|
+
}
|
|
2680
|
+
function restore(anchor, unbounded) {
|
|
2681
|
+
if (frozen()) return;
|
|
2636
2682
|
var box = options.getBox();
|
|
2637
2683
|
if (!box || !anchor || options.isStuck()) return;
|
|
2638
2684
|
var el = findRow(box, anchor);
|
|
2639
2685
|
if (el) {
|
|
2640
2686
|
var livePos = el.getAttribute(ROW_POS_ATTR) || UNKNOWN_ROW_POS;
|
|
2641
|
-
if (anchor.pos !== null && anchor.pos !== UNKNOWN_ROW_POS && livePos !== UNKNOWN_ROW_POS && livePos !== anchor.pos)
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
}
|
|
2687
|
+
if (anchor.pos !== null && anchor.pos !== UNKNOWN_ROW_POS && livePos !== UNKNOWN_ROW_POS && livePos !== anchor.pos) el = null;
|
|
2688
|
+
}
|
|
2689
|
+
if (el) {
|
|
2645
2690
|
var boxTop = box.getBoundingClientRect().top;
|
|
2646
2691
|
var delta = el.getBoundingClientRect().top - boxTop - anchor.top;
|
|
2647
2692
|
var slack = Math.abs(box.scrollHeight - anchor.scrollHeight) + box.clientHeight;
|
|
2648
|
-
if (delta > slack || delta < -slack) {
|
|
2693
|
+
if (!unbounded && (delta > slack || delta < -slack)) {
|
|
2649
2694
|
lost(box, anchor);
|
|
2650
2695
|
return;
|
|
2651
2696
|
}
|
|
2697
|
+
var want = box.scrollTop + delta;
|
|
2652
2698
|
if (delta >= 1 || delta <= -1) box.scrollTop += delta;
|
|
2699
|
+
wroteTop = box.scrollTop;
|
|
2700
|
+
restorePinned = true;
|
|
2701
|
+
restoreExact = box.scrollTop >= want - 1 && box.scrollTop <= want + 1;
|
|
2653
2702
|
held = {
|
|
2654
2703
|
key: anchor.key,
|
|
2655
2704
|
top: anchor.top,
|
|
2656
2705
|
pos: anchor.pos,
|
|
2657
2706
|
scrollTop: box.scrollTop,
|
|
2658
2707
|
scrollHeight: box.scrollHeight,
|
|
2659
|
-
el
|
|
2708
|
+
el,
|
|
2709
|
+
// Carried, not dropped: one successful restore used to disarm the
|
|
2710
|
+
// standbys for every later hold.
|
|
2711
|
+
alts: anchor.alts
|
|
2712
|
+
};
|
|
2713
|
+
return;
|
|
2714
|
+
}
|
|
2715
|
+
var alts = anchor.alts;
|
|
2716
|
+
for (var ai = 0; alts && ai < alts.length; ai++) {
|
|
2717
|
+
var alt = alts[ai];
|
|
2718
|
+
var ael = findRow(box, { key: alt.key, top: alt.top, pos: alt.pos, scrollTop: anchor.scrollTop, scrollHeight: anchor.scrollHeight, el: alt.el });
|
|
2719
|
+
if (!ael) continue;
|
|
2720
|
+
if (alt.pos !== null && alt.pos !== UNKNOWN_ROW_POS) {
|
|
2721
|
+
var altLive = ael.getAttribute(ROW_POS_ATTR) || UNKNOWN_ROW_POS;
|
|
2722
|
+
if (altLive !== UNKNOWN_ROW_POS && altLive !== alt.pos) continue;
|
|
2723
|
+
}
|
|
2724
|
+
var aboxTop = box.getBoundingClientRect().top;
|
|
2725
|
+
var adelta = ael.getBoundingClientRect().top - aboxTop - alt.top;
|
|
2726
|
+
var aslack = Math.abs(box.scrollHeight - anchor.scrollHeight) + box.clientHeight;
|
|
2727
|
+
if (!unbounded && (adelta > aslack || adelta < -aslack)) continue;
|
|
2728
|
+
var awant = box.scrollTop + adelta;
|
|
2729
|
+
if (adelta >= 1 || adelta <= -1) box.scrollTop += adelta;
|
|
2730
|
+
wroteTop = box.scrollTop;
|
|
2731
|
+
restorePinned = true;
|
|
2732
|
+
restoreExact = box.scrollTop >= awant - 1 && box.scrollTop <= awant + 1;
|
|
2733
|
+
held = {
|
|
2734
|
+
key: alt.key,
|
|
2735
|
+
top: alt.top,
|
|
2736
|
+
pos: alt.pos,
|
|
2737
|
+
scrollTop: box.scrollTop,
|
|
2738
|
+
scrollHeight: box.scrollHeight,
|
|
2739
|
+
el: ael,
|
|
2740
|
+
alts: alts.slice(ai + 1)
|
|
2660
2741
|
};
|
|
2661
2742
|
return;
|
|
2662
2743
|
}
|
|
@@ -2667,9 +2748,13 @@ function createScrollAnchor(options) {
|
|
|
2667
2748
|
var grew = box.scrollHeight - anchor.scrollHeight;
|
|
2668
2749
|
if (grew > 0) {
|
|
2669
2750
|
box.scrollTop = anchor.scrollTop + grew;
|
|
2751
|
+
wroteTop = box.scrollTop;
|
|
2670
2752
|
return;
|
|
2671
2753
|
}
|
|
2672
|
-
if (options.rawFallback)
|
|
2754
|
+
if (options.rawFallback) {
|
|
2755
|
+
box.scrollTop = anchor.scrollTop;
|
|
2756
|
+
wroteTop = box.scrollTop;
|
|
2757
|
+
}
|
|
2673
2758
|
}
|
|
2674
2759
|
function preserve(mutate) {
|
|
2675
2760
|
var anchor = capture();
|
|
@@ -2678,9 +2763,21 @@ function createScrollAnchor(options) {
|
|
|
2678
2763
|
return result;
|
|
2679
2764
|
}
|
|
2680
2765
|
function remember() {
|
|
2766
|
+
var b0 = options.getBox();
|
|
2767
|
+
if (returning && b0 && b0.scrollTop !== wroteTop) {
|
|
2768
|
+
parked = null;
|
|
2769
|
+
parkedStuck = false;
|
|
2770
|
+
returning = false;
|
|
2771
|
+
}
|
|
2772
|
+
if (frozen()) return;
|
|
2681
2773
|
held = capture();
|
|
2682
2774
|
}
|
|
2683
2775
|
function hold() {
|
|
2776
|
+
if (frozen()) return;
|
|
2777
|
+
if (sawFrozen || returning) {
|
|
2778
|
+
settleReturn();
|
|
2779
|
+
return;
|
|
2780
|
+
}
|
|
2684
2781
|
var box = options.getBox();
|
|
2685
2782
|
if (!box || options.isStuck()) {
|
|
2686
2783
|
held = null;
|
|
@@ -2707,12 +2804,67 @@ function createScrollAnchor(options) {
|
|
|
2707
2804
|
if (prev === void 0) prev = 0;
|
|
2708
2805
|
var delta = h - prev;
|
|
2709
2806
|
if (delta === 0) return;
|
|
2807
|
+
if (frozen()) {
|
|
2808
|
+
foldFrozenGrowth(box, el, delta);
|
|
2809
|
+
return;
|
|
2810
|
+
}
|
|
2710
2811
|
if (el.getBoundingClientRect().top >= box.getBoundingClientRect().top) return;
|
|
2711
2812
|
box.scrollTop += delta;
|
|
2813
|
+
wroteTop = box.scrollTop;
|
|
2712
2814
|
if (held) held = capture();
|
|
2713
2815
|
}
|
|
2816
|
+
function park() {
|
|
2817
|
+
parked = capture();
|
|
2818
|
+
parkedStuck = !!options.isStuck();
|
|
2819
|
+
returning = true;
|
|
2820
|
+
}
|
|
2821
|
+
function pinBottom() {
|
|
2822
|
+
var box = options.getBox();
|
|
2823
|
+
if (!box) return;
|
|
2824
|
+
box.scrollTop = box.scrollHeight;
|
|
2825
|
+
wroteTop = box.scrollTop;
|
|
2826
|
+
}
|
|
2827
|
+
function settleReturn() {
|
|
2828
|
+
if (frozen()) return false;
|
|
2829
|
+
sawFrozen = false;
|
|
2830
|
+
if (parkedStuck) {
|
|
2831
|
+
pinBottom();
|
|
2832
|
+
return true;
|
|
2833
|
+
}
|
|
2834
|
+
var target = parked || held;
|
|
2835
|
+
restoreExact = true;
|
|
2836
|
+
restorePinned = false;
|
|
2837
|
+
restore(target, true);
|
|
2838
|
+
parked = !restorePinned || !restoreExact ? target : null;
|
|
2839
|
+
returning = !!parked;
|
|
2840
|
+
return false;
|
|
2841
|
+
}
|
|
2842
|
+
function isReturning() {
|
|
2843
|
+
return returning;
|
|
2844
|
+
}
|
|
2845
|
+
function thaw() {
|
|
2846
|
+
settleReturn();
|
|
2847
|
+
}
|
|
2848
|
+
function foldFrozenGrowth(box, el, delta) {
|
|
2849
|
+
var elTop = el.getBoundingClientRect().top;
|
|
2850
|
+
foldInto(box, held, elTop, delta);
|
|
2851
|
+
foldInto(box, parked, elTop, delta);
|
|
2852
|
+
}
|
|
2853
|
+
function foldInto(box, a, elTop, delta) {
|
|
2854
|
+
if (!a || a.top >= 0) return;
|
|
2855
|
+
var rowEl = findRow(box, a);
|
|
2856
|
+
if (!rowEl) return;
|
|
2857
|
+
var within = elTop - rowEl.getBoundingClientRect().top;
|
|
2858
|
+
if (within < 0 || within >= rowEl.offsetHeight) return;
|
|
2859
|
+
if (within >= -a.top) return;
|
|
2860
|
+
a.top -= delta;
|
|
2861
|
+
a.scrollHeight += delta;
|
|
2862
|
+
}
|
|
2714
2863
|
function forget() {
|
|
2715
2864
|
held = null;
|
|
2865
|
+
parked = null;
|
|
2866
|
+
parkedStuck = false;
|
|
2867
|
+
returning = false;
|
|
2716
2868
|
}
|
|
2717
2869
|
return {
|
|
2718
2870
|
capture,
|
|
@@ -2720,6 +2872,12 @@ function createScrollAnchor(options) {
|
|
|
2720
2872
|
preserve,
|
|
2721
2873
|
remember,
|
|
2722
2874
|
hold,
|
|
2875
|
+
park,
|
|
2876
|
+
settleReturn,
|
|
2877
|
+
isReturning,
|
|
2878
|
+
pinBottom,
|
|
2879
|
+
isFrozen: frozen,
|
|
2880
|
+
thaw,
|
|
2723
2881
|
absorb,
|
|
2724
2882
|
forget
|
|
2725
2883
|
};
|
|
@@ -5822,6 +5980,7 @@ var ChatSession = class {
|
|
|
5822
5980
|
releaseBgFlag();
|
|
5823
5981
|
self.updateHistoryCache();
|
|
5824
5982
|
self.host.notify();
|
|
5983
|
+
if (self.host.settleScroll) self.host.settleScroll();
|
|
5825
5984
|
}, function() {
|
|
5826
5985
|
releaseBgFlag();
|
|
5827
5986
|
self.host.notify();
|
|
@@ -5903,7 +6062,7 @@ var ChatSession = class {
|
|
|
5903
6062
|
self.drainBgTaskQueue();
|
|
5904
6063
|
}
|
|
5905
6064
|
if (!fetchMore) self.refreshLiveIndexState();
|
|
5906
|
-
if (!fetchMore) return self.host.scrollToBottomIfSticky();
|
|
6065
|
+
if (!fetchMore) return self.host.settleScroll ? self.host.settleScroll() : self.host.scrollToBottomIfSticky();
|
|
5907
6066
|
}).catch(function(err) {
|
|
5908
6067
|
console.warn("[chat-engine] getChatHistory failed", err);
|
|
5909
6068
|
}).then(function() {
|