refactor: replace hand-rolled debounce with @tanstack/react-pacer and extract useGracePeriod

- Add `@tanstack/react-pacer` and swap both hand-rolled `setTimeout`-based debounce patterns (project-name commit in `project-setup.tsx`, module search fetch in `site-search.tsx`) for `useDebouncedValue`; the search effect now runs directly against the debounced value with an abort controller rather than nesting the fetch inside the timer
- Extract `useGracePeriod` from `file-preview.tsx` into `src/hooks/use-grace-period.ts` so it can be reused independently
- Hoist `fileSelection`, `lastFileRef`, `activePath`, and `preview` above the reseed effect in `file-preview.tsx` so the effect can reference `defaultPath` and `lastFileRef` without stale-closure issues; expand ancestor directories when a hash-driven selection lands so the highlighted row is visible in the tree
This commit is contained in:
jake committed 2026-05-25 14:23:33 -04:00
1 parent 16295952a8
commit 6767362641
6 files changed
+149 -202

No files matched your search

+28 -93
View File
@@ -121,6 +121,9 @@ importers:
'@tanstack/react-hotkeys':
specifier: ^0.10.0
version: 0.10.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
'@tanstack/react-pacer':
specifier: ^0.22.1
version: 0.22.1(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
'@tanstack/react-router':
specifier: ^1.170.8
version: 1.170.8(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
@@ -241,10 +244,10 @@ importers:
version: '@voidzero-dev/vite-plus-core@0.1.22(@types/node@25.9.1)(esbuild@0.28.0)(jiti@2.7.0)(typescript@6.0.3)'
vite-plus:
specifier: 'catalog:'
version: 0.1.22(@opentelemetry/api@1.9.1)(@types/node@25.9.1)(@voidzero-dev/vite-plus-core@0.1.22(@types/node@25.9.1)(esbuild@0.28.0)(jiti@2.7.0)(typescript@6.0.3))(esbuild@0.28.0)(jiti@2.7.0)(jsdom@29.1.1(@noble/hashes@1.8.0))(typescript@6.0.3)
version: 0.1.22(@opentelemetry/api@1.9.1)(@types/node@25.9.1)(esbuild@0.28.0)(jiti@2.7.0)(jsdom@29.1.1(@noble/hashes@1.8.0))(typescript@6.0.3)(vite@8.0.14(@types/node@25.9.1)(esbuild@0.28.0)(jiti@2.7.0))
vitest:
specifier: npm:@voidzero-dev/vite-plus-test@^0.1.22
version: '@voidzero-dev/vite-plus-test@0.1.22(@opentelemetry/api@1.9.1)(@types/node@25.9.1)(@voidzero-dev/vite-plus-core@0.1.22(@types/node@25.9.1)(esbuild@0.28.0)(jiti@2.7.0)(typescript@6.0.3))(esbuild@0.28.0)(jiti@2.7.0)(jsdom@29.1.1(@noble/hashes@1.8.0))(typescript@6.0.3)'
version: '@voidzero-dev/vite-plus-test@0.1.22(@opentelemetry/api@1.9.1)(@types/node@25.9.1)(esbuild@0.28.0)(jiti@2.7.0)(jsdom@29.1.1(@noble/hashes@1.8.0))(typescript@6.0.3)(vite@8.0.14(@types/node@25.9.1)(esbuild@0.28.0)(jiti@2.7.0))'
web-vitals:
specifier: ^5.2.0
version: 5.2.0
@@ -2014,6 +2017,10 @@ packages:
resolution: {integrity: sha512-vqH7X9nb0MTJ/O08++dB5bP9jgj4+BIPOUu/U+6myG86lDsirZSVSobpq5UQpE7nBuk62i8eIYeOhd+OMl/UrA==}
engines: {node: '>=18'}
'@tanstack/pacer@0.21.1':
resolution: {integrity: sha512-hB01dd4rlsYcTCNP7wK186jgAe6K5qimgM1Y5Jtvz+9PUaILvpmeLLjmQNUNSO1l23lIt+CeQR6mO1mjlPvRtQ==}
engines: {node: '>=18'}
'@tanstack/query-core@5.100.14':
resolution: {integrity: sha512-5X41dGpxgeaHISCRW2oYwcSycZeULZzAunaudXT9ov1KOTj9xwt0CH6hbwqP1/z74ZWF7rYFnDpyYH07XFcZew==}
@@ -2033,6 +2040,13 @@ packages:
react: '>=16.8'
react-dom: '>=16.8'
'@tanstack/react-pacer@0.22.1':
resolution: {integrity: sha512-CenQqK0GluSPIrnsG1yuD7w5uMSQ/4lI9AcGEFxBrRd66r260boWcYRIsS5+eHtXb238FoZYhKmJPGlhRzmHRw==}
engines: {node: '>=18'}
peerDependencies:
react: '>=16.8'
react-dom: '>=16.8'
'@tanstack/react-query@5.100.14':
resolution: {integrity: sha512-oOr6aRdSFEwWhzxEkD/9ZcItM3+LjBSkeVmadWKwUssAHTsqd/7bOjWrX4AbvEkoEhgAxzN0Xk6H/aYzXiYBAw==}
peerDependencies:
@@ -6646,6 +6660,11 @@ snapshots:
dependencies:
'@tanstack/store': 0.11.0
'@tanstack/pacer@0.21.1':
dependencies:
'@tanstack/devtools-event-client': 0.4.3
'@tanstack/store': 0.11.0
'@tanstack/query-core@5.100.14': {}
'@tanstack/react-devtools@0.10.5(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(csstype@3.2.3)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(solid-js@1.9.13)':
@@ -6668,6 +6687,13 @@ snapshots:
react: 19.2.6
react-dom: 19.2.6(react@19.2.6)
'@tanstack/react-pacer@0.22.1(react-dom@19.2.6(react@19.2.6))(react@19.2.6)':
dependencies:
'@tanstack/pacer': 0.21.1
'@tanstack/react-store': 0.11.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
react: 19.2.6
react-dom: 19.2.6(react@19.2.6)
'@tanstack/react-query@5.100.14(react@19.2.6)':
dependencies:
'@tanstack/query-core': 5.100.14
@@ -7076,48 +7102,6 @@ snapshots:
'@voidzero-dev/vite-plus-linux-x64-musl@0.1.22':
optional: true
'@voidzero-dev/vite-plus-test@0.1.22(@opentelemetry/api@1.9.1)(@types/node@25.9.1)(@voidzero-dev/vite-plus-core@0.1.22(@types/node@25.9.1)(esbuild@0.28.0)(jiti@2.7.0)(typescript@6.0.3))(esbuild@0.28.0)(jiti@2.7.0)(jsdom@29.1.1(@noble/hashes@1.8.0))(typescript@6.0.3)':
dependencies:
'@standard-schema/spec': 1.1.0
'@types/chai': 5.2.3
'@voidzero-dev/vite-plus-core': 0.1.22(@types/node@25.9.1)(esbuild@0.28.0)(jiti@2.7.0)(typescript@6.0.3)
es-module-lexer: 1.7.0
obug: 2.1.1
pixelmatch: 7.2.0
pngjs: 7.0.0
sirv: 3.0.2
std-env: 4.1.0
tinybench: 2.9.0
tinyexec: 1.2.2
tinyglobby: 0.2.16
vite: '@voidzero-dev/vite-plus-core@0.1.22(@types/node@25.9.1)(esbuild@0.28.0)(jiti@2.7.0)(typescript@6.0.3)'
ws: 8.21.0
optionalDependencies:
'@opentelemetry/api': 1.9.1
'@types/node': 25.9.1
jsdom: 29.1.1(@noble/hashes@1.8.0)
transitivePeerDependencies:
- '@arethetypeswrong/core'
- '@tsdown/css'
- '@tsdown/exe'
- '@vitejs/devtools'
- bufferutil
- esbuild
- jiti
- less
- publint
- sass
- sass-embedded
- stylus
- sugarss
- terser
- tsx
- typescript
- unplugin-unused
- unrun
- utf-8-validate
- yaml
'@voidzero-dev/vite-plus-test@0.1.22(@opentelemetry/api@1.9.1)(@types/node@25.9.1)(esbuild@0.28.0)(jiti@2.7.0)(jsdom@29.1.1(@noble/hashes@1.8.0))(typescript@6.0.3)(vite@8.0.14(@types/node@25.9.1)(esbuild@0.28.0)(jiti@2.7.0))':
dependencies:
'@standard-schema/spec': 1.1.0
@@ -9973,55 +9957,6 @@ snapshots:
'@types/unist': 3.0.3
vfile-message: 4.0.3
vite-plus@0.1.22(@opentelemetry/api@1.9.1)(@types/node@25.9.1)(@voidzero-dev/vite-plus-core@0.1.22(@types/node@25.9.1)(esbuild@0.28.0)(jiti@2.7.0)(typescript@6.0.3))(esbuild@0.28.0)(jiti@2.7.0)(jsdom@29.1.1(@noble/hashes@1.8.0))(typescript@6.0.3):
dependencies:
'@oxc-project/types': 0.129.0
'@oxlint/plugins': 1.61.0
'@voidzero-dev/vite-plus-core': 0.1.22(@types/node@25.9.1)(esbuild@0.28.0)(jiti@2.7.0)(typescript@6.0.3)
'@voidzero-dev/vite-plus-test': 0.1.22(@opentelemetry/api@1.9.1)(@types/node@25.9.1)(@voidzero-dev/vite-plus-core@0.1.22(@types/node@25.9.1)(esbuild@0.28.0)(jiti@2.7.0)(typescript@6.0.3))(esbuild@0.28.0)(jiti@2.7.0)(jsdom@29.1.1(@noble/hashes@1.8.0))(typescript@6.0.3)
oxfmt: 0.48.0
oxlint: 1.63.0(oxlint-tsgolint@0.22.1)
oxlint-tsgolint: 0.22.1
optionalDependencies:
'@voidzero-dev/vite-plus-darwin-arm64': 0.1.22
'@voidzero-dev/vite-plus-darwin-x64': 0.1.22
'@voidzero-dev/vite-plus-linux-arm64-gnu': 0.1.22
'@voidzero-dev/vite-plus-linux-arm64-musl': 0.1.22
'@voidzero-dev/vite-plus-linux-x64-gnu': 0.1.22
'@voidzero-dev/vite-plus-linux-x64-musl': 0.1.22
'@voidzero-dev/vite-plus-win32-arm64-msvc': 0.1.22
'@voidzero-dev/vite-plus-win32-x64-msvc': 0.1.22
transitivePeerDependencies:
- '@arethetypeswrong/core'
- '@edge-runtime/vm'
- '@opentelemetry/api'
- '@tsdown/css'
- '@tsdown/exe'
- '@types/node'
- '@vitejs/devtools'
- '@vitest/coverage-istanbul'
- '@vitest/coverage-v8'
- '@vitest/ui'
- bufferutil
- esbuild
- happy-dom
- jiti
- jsdom
- less
- publint
- sass
- sass-embedded
- stylus
- sugarss
- terser
- tsx
- typescript
- unplugin-unused
- unrun
- utf-8-validate
- vite
- yaml
vite-plus@0.1.22(@opentelemetry/api@1.9.1)(@types/node@25.9.1)(esbuild@0.28.0)(jiti@2.7.0)(jsdom@29.1.1(@noble/hashes@1.8.0))(typescript@6.0.3)(vite@8.0.14(@types/node@25.9.1)(esbuild@0.28.0)(jiti@2.7.0)):
dependencies:
'@oxc-project/types': 0.129.0