From a4d6393859cb6e0bb61b77c2952d2b63b89ecb6a Mon Sep 17 00:00:00 2001 From: Jovi De Croock Date: Wed, 22 Jul 2026 16:23:16 +0200 Subject: [PATCH 1/3] Add reorder1k benchmark Measures moving the first 3 of 1,000 keyed rows to the end of the list (3 warmup runs plus a measured run). This displacement pattern is the worst case for reconciliation heuristics that only handle shifts: the whole suffix gets moved instead of the short displaced prefix. Adds a displace(n) mutation to the shared store and exposes it from the preact, preact-class, and preact-hooks table-app implementations. --- apps/table-app/_shared/store.js | 5 ++ apps/table-app/preact-class/index.jsx | 7 +++ apps/table-app/preact-hooks/index.jsx | 5 ++ apps/table-app/preact/index.jsx | 5 ++ apps/table-app/reorder1k.html | 69 +++++++++++++++++++++++++++ 5 files changed, 91 insertions(+) create mode 100644 apps/table-app/reorder1k.html diff --git a/apps/table-app/_shared/store.js b/apps/table-app/_shared/store.js index 555b627..f717952 100644 --- a/apps/table-app/_shared/store.js +++ b/apps/table-app/_shared/store.js @@ -146,4 +146,9 @@ export class Store { this.data[998] = a; } } + /** Move the first `n` rows to the end of the list. + * @param {number} n */ + displace(n) { + this.data = this.data.slice(n).concat(this.data.slice(0, n)); + } } diff --git a/apps/table-app/preact-class/index.jsx b/apps/table-app/preact-class/index.jsx index e713084..3ee4d2f 100644 --- a/apps/table-app/preact-class/index.jsx +++ b/apps/table-app/preact-class/index.jsx @@ -101,6 +101,11 @@ export class Main extends Component { this.state.store.swapRows(); this.setState({ store: this.state.store }); } + /** @param {number} n */ + displace(n) { + this.state.store.displace(n); + this.setState({ store: this.state.store }); + } render() { let rows = this.state.store.data.map((d, i) => { return createElement(Row, { @@ -143,6 +148,7 @@ export function render(rootDom, props) { runLots: app.runLots.bind(app), clear: app.clear.bind(app), swapRows: app.swapRows.bind(app), + displace: app.displace.bind(app), }; } @@ -163,5 +169,6 @@ export function hydrate(rootDom, props) { runLots: app.runLots.bind(app), clear: app.clear.bind(app), swapRows: app.swapRows.bind(app), + displace: app.displace.bind(app), }; } diff --git a/apps/table-app/preact-hooks/index.jsx b/apps/table-app/preact-hooks/index.jsx index a6e03aa..fd061c7 100644 --- a/apps/table-app/preact-hooks/index.jsx +++ b/apps/table-app/preact-hooks/index.jsx @@ -87,6 +87,11 @@ function Main({ store: initialStore }) { store.swapRows(); forceUpdate(); }, + /** @param {number} n */ + displace(n) { + store.displace(n); + forceUpdate(); + }, }; }, []); diff --git a/apps/table-app/preact/index.jsx b/apps/table-app/preact/index.jsx index e5666b1..1a0b83d 100644 --- a/apps/table-app/preact/index.jsx +++ b/apps/table-app/preact/index.jsx @@ -98,6 +98,11 @@ function createTableApp(store, rootDom) { store.swapRows(); rerender(); }, + /** @param {number} n */ + displace(n) { + store.displace(n); + rerender(); + }, }; rerender = () => diff --git a/apps/table-app/reorder1k.html b/apps/table-app/reorder1k.html new file mode 100644 index 0000000..f5cfe72 --- /dev/null +++ b/apps/table-app/reorder1k.html @@ -0,0 +1,69 @@ + + + + + + reorder rows + + + + +
+ + + From a6626fadd06809a6e135ba7b2e773317eb093779 Mon Sep 17 00:00:00 2001 From: Jovi De Croock Date: Wed, 22 Jul 2026 16:28:46 +0200 Subject: [PATCH 2/3] Add displace to the TableApp typedef --- apps/table-app/_shared/store.js | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/table-app/_shared/store.js b/apps/table-app/_shared/store.js index f717952..f3d418b 100644 --- a/apps/table-app/_shared/store.js +++ b/apps/table-app/_shared/store.js @@ -13,6 +13,7 @@ function _random(max) { * @property {() => void} runLots * @property {() => void} clear * @property {() => void} swapRows + * @property {(n: number) => void} displace */ /** @typedef {{id: number; label: string}} Data */ From 43375b258b184b7d8ef672c95cb7d4cade5c303c Mon Sep 17 00:00:00 2001 From: Jovi De Croock Date: Wed, 22 Jul 2026 16:32:09 +0200 Subject: [PATCH 3/3] Detect the installed Chrome version when installing chromedriver The lockfile pins whatever chromedriver major was current when it was last refreshed (131 right now), while the CI runner image ships a newer Chrome (150). detect_chromedriver_version makes the chromedriver package download the driver matching the installed browser, so the two can no longer drift apart. --- .npmrc | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .npmrc diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..3a2d378 --- /dev/null +++ b/.npmrc @@ -0,0 +1,3 @@ +# Make the chromedriver package download the driver matching the installed +# Chrome instead of the version pinned in the lockfile. +detect_chromedriver_version=true