@aiquants/virtualscroll 3.6.0 → 3.6.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.
@@ -39,7 +39,7 @@ export type UseGridTapScrollParams = {
39
39
  getMaxHx: () => number;
40
40
  /** y apply seam: wraps `scrollBy(delta)` AND syncs `vyRef.current = applied` before returning (§3.5-8 — NOT a bare handle passthrough). / y 適用シーム: `scrollBy(delta)` をラップし `vyRef.current = applied` を同期してから返す (§3.5-8 — 素のハンドル素通しではない)。 */
41
41
  applyVy: (delta: number) => number;
42
- /** Synchronous-fresh vy read. / vy の同期・最新読み。 */
42
+ /** Synchronous-fresh vy read — MUST read the same authority `applyVy` resolves against (the embedded pane's position), never a notification mirror with a second writer (v3.6.1 — a lagging mirror base overstates `actualDelta` and drives the residual negative = yo-yo). / vy の同期・最新読み — `applyVy` が解決するのと同一権威 (埋め込みペイン位置) を読むこと。第 2 の書き手を持つ通知鏡像は禁止 (v3.6.1 — 遅延鏡像基準は `actualDelta` を過大化し残差を負へ落とすヨーヨー)。 */
43
43
  getVy: () => number;
44
44
  /** y extent read through the embedded handle's freshness channel (never re-derived). / 埋め込みハンドルの鮮度チャネル経由の y 延長 (再導出禁止)。 */
45
45
  getMaxVy: () => number;
@@ -39,7 +39,7 @@ export type UseGridTapScrollParams = {
39
39
  getMaxHx: () => number;
40
40
  /** y apply seam: wraps `scrollBy(delta)` AND syncs `vyRef.current = applied` before returning (§3.5-8 — NOT a bare handle passthrough). / y 適用シーム: `scrollBy(delta)` をラップし `vyRef.current = applied` を同期してから返す (§3.5-8 — 素のハンドル素通しではない)。 */
41
41
  applyVy: (delta: number) => number;
42
- /** Synchronous-fresh vy read. / vy の同期・最新読み。 */
42
+ /** Synchronous-fresh vy read — MUST read the same authority `applyVy` resolves against (the embedded pane's position), never a notification mirror with a second writer (v3.6.1 — a lagging mirror base overstates `actualDelta` and drives the residual negative = yo-yo). / vy の同期・最新読み — `applyVy` が解決するのと同一権威 (埋め込みペイン位置) を読むこと。第 2 の書き手を持つ通知鏡像は禁止 (v3.6.1 — 遅延鏡像基準は `actualDelta` を過大化し残差を負へ落とすヨーヨー)。 */
43
43
  getVy: () => number;
44
44
  /** y extent read through the embedded handle's freshness channel (never re-derived). / 埋め込みハンドルの鮮度チャネル経由の y 延長 (再導出禁止)。 */
45
45
  getMaxVy: () => number;
@@ -1 +1 @@
1
- {"version":3,"file":"useGridTapScroll.d.ts","sourceRoot":"","sources":["../src/useGridTapScroll.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAA4B,KAAK,wBAAwB,EAAE,MAAM,+BAA+B,CAAA;AAEvG,OAAO,KAAK,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAA;AAG5F;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,8BAA8B,OAAO,CAAA;AAalD,4MAA4M;AAC5M,MAAM,MAAM,sBAAsB,GAAG;IACjC,uIAAuI;IACvI,OAAO,EAAE,OAAO,CAAA;IAChB,mGAAmG;IACnG,WAAW,EAAE,MAAM,CAAA;IACnB,oEAAoE;IACpE,YAAY,EAAE,wBAAwB,CAAA;IACtC,oEAAoE;IACpE,YAAY,EAAE,wBAAwB,CAAA;IACtC,sHAAsH;IACtH,UAAU,EAAE;QAAE,QAAQ,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAA;KAAE,CAAA;IAC1D,gDAAgD;IAChD,KAAK,EAAE,MAAM,MAAM,CAAA;IACnB,4GAA4G;IAC5G,QAAQ,EAAE,MAAM,MAAM,CAAA;IACtB,4OAA4O;IAC5O,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAA;IAClC,gDAAgD;IAChD,KAAK,EAAE,MAAM,MAAM,CAAA;IACnB,2HAA2H;IAC3H,QAAQ,EAAE,MAAM,MAAM,CAAA;IACtB,0IAA0I;IAC1I,mBAAmB,EAAE;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAA;IACzC,uHAAuH;IACvH,gBAAgB,EAAE,OAAO,CAAA;IACzB,8GAA8G;IAC9G,gBAAgB,EAAE,OAAO,CAAA;CAC5B,CAAA;AAED,+DAA+D;AAC/D,MAAM,MAAM,sBAAsB,GAAG;IACjC,4FAA4F;IAC5F,WAAW,EAAE,OAAO,CAAA;IACpB,qGAAqG;IACrG,yBAAyB,EAAE,CAAC,KAAK,EAAE,wBAAwB,KAAK,IAAI,CAAA;IACpE,4HAA4H;IAC5H,kBAAkB,EAAE,KAAK,CAAC,SAAS,CAAC,qBAAqB,GAAG,IAAI,CAAC,CAAA;CACpE,CAAA;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,gBAAgB,GAAI,QAAQ,sBAAsB,KAAG,sBAuQjE,CAAA"}
1
+ {"version":3,"file":"useGridTapScroll.d.ts","sourceRoot":"","sources":["../src/useGridTapScroll.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAA4B,KAAK,wBAAwB,EAAE,MAAM,+BAA+B,CAAA;AAEvG,OAAO,KAAK,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAA;AAG5F;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,8BAA8B,OAAO,CAAA;AAalD,4MAA4M;AAC5M,MAAM,MAAM,sBAAsB,GAAG;IACjC,uIAAuI;IACvI,OAAO,EAAE,OAAO,CAAA;IAChB,mGAAmG;IACnG,WAAW,EAAE,MAAM,CAAA;IACnB,oEAAoE;IACpE,YAAY,EAAE,wBAAwB,CAAA;IACtC,oEAAoE;IACpE,YAAY,EAAE,wBAAwB,CAAA;IACtC,sHAAsH;IACtH,UAAU,EAAE;QAAE,QAAQ,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAA;KAAE,CAAA;IAC1D,gDAAgD;IAChD,KAAK,EAAE,MAAM,MAAM,CAAA;IACnB,4GAA4G;IAC5G,QAAQ,EAAE,MAAM,MAAM,CAAA;IACtB,4OAA4O;IAC5O,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAA;IAClC,8YAA8Y;IAC9Y,KAAK,EAAE,MAAM,MAAM,CAAA;IACnB,2HAA2H;IAC3H,QAAQ,EAAE,MAAM,MAAM,CAAA;IACtB,0IAA0I;IAC1I,mBAAmB,EAAE;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAA;IACzC,uHAAuH;IACvH,gBAAgB,EAAE,OAAO,CAAA;IACzB,8GAA8G;IAC9G,gBAAgB,EAAE,OAAO,CAAA;CAC5B,CAAA;AAED,+DAA+D;AAC/D,MAAM,MAAM,sBAAsB,GAAG;IACjC,4FAA4F;IAC5F,WAAW,EAAE,OAAO,CAAA;IACpB,qGAAqG;IACrG,yBAAyB,EAAE,CAAC,KAAK,EAAE,wBAAwB,KAAK,IAAI,CAAA;IACpE,4HAA4H;IAC5H,kBAAkB,EAAE,KAAK,CAAC,SAAS,CAAC,qBAAqB,GAAG,IAAI,CAAC,CAAA;CACpE,CAAA;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,gBAAgB,GAAI,QAAQ,sBAAsB,KAAG,sBAuQjE,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiquants/virtualscroll",
3
- "version": "3.6.0",
3
+ "version": "3.6.1",
4
4
  "description": "High-performance virtual scrolling component for React with variable item heights",
5
5
  "sideEffects": [
6
6
  "**/*.css"
@@ -1349,7 +1349,33 @@ const VirtualGridInner = <T,>(
1349
1349
  curve: resolvedTapY.maxSpeedCurve,
1350
1350
  }
1351
1351
  const getHx = useCallback(() => hxRef.current, [])
1352
- const getVy = useCallback(() => vyRef.current, [])
1352
+ /**
1353
+ * Fresh y position through the embedded handle — the SAME authority `applyVy`'s `scrollBy`
1354
+ * resolves its updater against (the pane's internal position ref), symmetric with
1355
+ * `getMaxVy`'s freshness channel and with the x side, where `getHx` reads the very cell
1356
+ * `applyHx` writes. NEVER read `vyRef` here: that mirror has a second writer — the
1357
+ * throttled `onScroll` relay (`handleVerticalScroll`) — which regresses it by up to the
1358
+ * `callbackThrottleMs` window mid-drive; a driver base read from the mirror overstates
1359
+ * `actualDelta` by the staleness gap, drives the axis residual negative, and the driver
1360
+ * then issues REAL backward `scrollBy` writes (the 3.6.0 y-axis tap yo-yo — v3.6.1).
1361
+ * 埋め込みハンドル経由の鮮度 y 位置 — `applyVy` の `scrollBy` が updater を解決するのと
1362
+ * **同一の権威** (ペイン内部 ref)。`getMaxVy` の鮮度チャネル、および「`getHx` が `applyHx`
1363
+ * の書き先セルそのものを読む」x 側と対称。ここで `vyRef` を読んではならない: あの鏡像には
1364
+ * 第 2 の書き手 (スロットル済み `onScroll` 中継 = `handleVerticalScroll`) が居て、駆動中に
1365
+ * 最大 `callbackThrottleMs` 窓ぶん巻き戻す。鏡像基準の `actualDelta` は staleness ギャップ
1366
+ * ぶん過大になり、軸残差が負へ落ちて、ドライバ自身が**実後退**の `scrollBy` を発行する
1367
+ * (3.6.0 の y 軸タップヨーヨー — v3.6.1)。
1368
+ */
1369
+ const getVy = useCallback(() => {
1370
+ const inner = scrollHandleRef.current
1371
+ if (inner === null) {
1372
+ // ハンドル未接続時は applyVy と同じ「動かない」姿勢 — 同じ座標 (vyRef) を基準に返す
1373
+ return vyRef.current
1374
+ }
1375
+ const position = inner.getScrollPosition()
1376
+ // ペイン未接続の番兵 (-1) も applyVy の不動姿勢と同じ座標へ落とす (負位置は実在しない)
1377
+ return position < 0 ? vyRef.current : position
1378
+ }, [])
1353
1379
  /**
1354
1380
  * Fresh y extent through the embedded handle — the same freshness channel the vertical bar
1355
1381
  * uses (`contentSize − viewportSize` floored at 0). Never re-derived from grid-side trees.
@@ -63,7 +63,7 @@ export type UseGridTapScrollParams = {
63
63
  getMaxHx: () => number
64
64
  /** y apply seam: wraps `scrollBy(delta)` AND syncs `vyRef.current = applied` before returning (§3.5-8 — NOT a bare handle passthrough). / y 適用シーム: `scrollBy(delta)` をラップし `vyRef.current = applied` を同期してから返す (§3.5-8 — 素のハンドル素通しではない)。 */
65
65
  applyVy: (delta: number) => number
66
- /** Synchronous-fresh vy read. / vy の同期・最新読み。 */
66
+ /** Synchronous-fresh vy read — MUST read the same authority `applyVy` resolves against (the embedded pane's position), never a notification mirror with a second writer (v3.6.1 — a lagging mirror base overstates `actualDelta` and drives the residual negative = yo-yo). / vy の同期・最新読み — `applyVy` が解決するのと同一権威 (埋め込みペイン位置) を読むこと。第 2 の書き手を持つ通知鏡像は禁止 (v3.6.1 — 遅延鏡像基準は `actualDelta` を過大化し残差を負へ落とすヨーヨー)。 */
67
67
  getVy: () => number
68
68
  /** y extent read through the embedded handle's freshness channel (never re-derived). / 埋め込みハンドルの鮮度チャネル経由の y 延長 (再導出禁止)。 */
69
69
  getMaxVy: () => number
@@ -142,7 +142,7 @@ export const useGridTapScroll = (params: UseGridTapScrollParams): UseGridTapScro
142
142
  * @param drive Axis bookkeeping (mutated in place). / 軸別内部状態 (この場で更新)。
143
143
  * @param velocity Signed axis velocity (px/s). / 符号付き軸速度 (px/s)。
144
144
  * @param dt Frame delta (s). / フレーム時間 (秒)。
145
- * @param getPos Fresh position read. / 位置の最新読み。
145
+ * @param getPos Fresh position read from the SAME authority `applyDelta` resolves against (the residual feedback `residual -= applied − before` is only exact on one shared authority — v3.6.1). / `applyDelta` が解決するのと同一権威からの位置最新読み (残差フィードバック `residual -= applied − before` は権威共有時のみ正確 — v3.6.1)。
146
146
  * @param getMax Fresh extent read. / 延長の最新読み。
147
147
  * @param applyDelta Applies a delta and returns the applied position. / 差分を適用し適用後位置を返す。
148
148
  * @returns Applied delta and the per-frame boundary flag. / 適用デルタと毎フレーム境界フラグ。