Clear Biome 2.x lint backlog in packages/*/src; add CI gate - #83
Conversation
Clears the ~128 error / ~88 warning backlog surfaced by the Biome 1.9.4 -> 2.5.3 upgrade across packages/*/src. Result: 0 errors, 43 warnings (all noExplicitAny, configured as a non-blocking warn). Safe autofixes (89 files): formatting, organizeImports, unused imports, optional chaining, useConst, etc. Reverted 4 regressions that Biome's "safe" autofixes introduced (each caught via `pnpm build`): - noPrototypeBuiltins rewrote Object.prototype.hasOwnProperty.call -> Object.hasOwn (x2). Instead of leaving it broken under lib:ES2020, bumped lib ES2020 -> ES2022 across the 6 package tsconfigs (target stays ES2020; Object.hasOwn is a runtime API, not syntax) and kept the Object.hasOwn form. - noTsIgnore rewrote //@ts-ignore -> //@ts-expect-error on two `let x: any` lines with no error, tripping TS2578. Removed the now-pointless directives. - noUselessConstructor deleted a load-bearing `constructor(...args)` on LabelsBitmaskTileLayer that widens the base XRLayer signature; restored with a biome-ignore. - noUnusedVariables renamed a dead React component Repr -> _Repr, breaking the PascalCase hooks heuristic; restored + biome-ignore (dev-only <Repr/> scaffolding). Manual fixes: typed a `let footer`, dropped a redundant non-null assertion, fixed a precision-loss literal (value-identical), removed dead destructured params/vars, and suppressed two a11y drag-handle findings inline with TODOs. biome.json: disabled useExhaustiveDependencies and useHookAtTopLevel. React-hooks correctness is owned by eslint (lint:react) + babel-plugin-react-compiler, and the flagged sites are intentional stable-key-dep patterns already carrying eslint-disable comments. CI: added a biome-lint job (pnpm lint:biome = `biome ci packages/*/src`) as an errors-only gate over the cleaned library source. Demo, scripts, and tests are intentionally out of scope (still carry ~15 errors); this gate is narrower than `pnpm lint`. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Warning Review limit reached
Next review available in: 45 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (7)
📝 WalkthroughWalkthroughThe pull request adds a Biome CI job and script, updates package TypeScript targets to ES2022, and applies broad lint-driven import, export, formatting, unused-parameter, hook-suppression, and selected layer-data cleanup changes across the monorepo. ChangesRepository linting and cleanup
Estimated code review effort: 4 (Complex) | ~45 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (3)
packages/avivatorish/src/utils.ts (1)
17-19: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueRemove redundant
as booleantype assertion.
Array.isArray()already returnsboolean, which is directly assignable to thevalue is unknown[]type predicate. Theas booleanassertion is unnecessary and violates the coding guideline to avoid type assertions when the type system can already express the fact.As per coding guidelines: "Avoid type assertions (
as ...) in TypeScript when a library overload, local type guard, schema parser, discriminated union, or narrower API contract can express the same fact."♻️ Proposed fix
function _isArray(value: unknown): value is unknown[] { - return Array.isArray(value) as boolean; + return Array.isArray(value); }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/avivatorish/src/utils.ts` around lines 17 - 19, Remove the redundant boolean type assertion from the return statement in _isArray, returning Array.isArray(value) directly while preserving the existing type-predicate signature.Source: Coding guidelines
packages/core/src/workers/points-worker.ts (1)
267-267: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueRemove dead
_hasZvariable instead of underscore-prefixing it.
_hasZis computed but never read anywhere inscanPayloadByFeatureCodes. The callerhandleScanParquetByFeatureCodes(line 336) computes its ownhasZ. The rename silences the lint warning but leaves dead code — prefer deleting the line entirely.♻️ Proposed fix
- const _hasZ = request.axisNames.includes('z'); const columns = [🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/core/src/workers/points-worker.ts` at line 267, Remove the unused _hasZ declaration from scanPayloadByFeatureCodes; do not replace or rename it, and leave handleScanParquetByFeatureCodes’s separate hasZ calculation unchanged.packages/vis/src/SpatialCanvas/useLayerData.ts (1)
1206-1210: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winNarrow
AvailableElementinstead of asserting its payload type.Use an
isPointsAvailableElementguard and the existing shapes guard soelem.elementnarrows naturally. This also rejects mismatched config/element types rather than hiding them withas PointsElementoras ShapesElement.As per coding guidelines, avoid type assertions when a local type guard or narrower API contract can express the same fact.
Also applies to: 1323-1351
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/vis/src/SpatialCanvas/useLayerData.ts` around lines 1206 - 1210, Update resolvePointsTarget to use the existing isPointsAvailableElement guard so the resolved element and payload narrow naturally without asserting elem.element as PointsElement. Apply the same pattern in the corresponding shapes handling around the additional referenced range, using the existing shapes guard to reject mismatched configuration and element types.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/vis/src/SpatialCanvas/LayerOrderList.tsx`:
- Around line 75-82: Add keyboard-accessible reordering to the layer-order
control around the drag handlers in LayerOrderList, using focusable semantic
controls or equivalent key handling to move the targeted layer and update the
same ordering state as onDrop. Ensure assistive technologies can identify and
operate the reorder action, then remove both biome-ignore accessibility
suppressions for the drop target and drag handle.
In `@packages/vis/src/SpatialCanvas/useLayerData.ts`:
- Around line 1140-1165: Update reloadElement to trigger a rerender after
clearing caches, and use resolveLayerElement to determine the element associated
with each shapes layer before deleting its shapePrebuiltData and
shapeFillColorData. Preserve the existing cache invalidation for all element
types while ensuring the load effect runs immediately after reloadElement.
---
Nitpick comments:
In `@packages/avivatorish/src/utils.ts`:
- Around line 17-19: Remove the redundant boolean type assertion from the return
statement in _isArray, returning Array.isArray(value) directly while preserving
the existing type-predicate signature.
In `@packages/core/src/workers/points-worker.ts`:
- Line 267: Remove the unused _hasZ declaration from scanPayloadByFeatureCodes;
do not replace or rename it, and leave handleScanParquetByFeatureCodes’s
separate hasZ calculation unchanged.
In `@packages/vis/src/SpatialCanvas/useLayerData.ts`:
- Around line 1206-1210: Update resolvePointsTarget to use the existing
isPointsAvailableElement guard so the resolved element and payload narrow
naturally without asserting elem.element as PointsElement. Apply the same
pattern in the corresponding shapes handling around the additional referenced
range, using the existing shapes guard to reject mismatched configuration and
element types.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 523a92c4-ad7a-4bb6-995f-2bf7abc6bd89
📒 Files selected for processing (101)
.github/workflows/test.ymlbiome.jsonpackage.jsonpackages/avivatorish/src/hooks.tspackages/avivatorish/src/index.tspackages/avivatorish/src/layerChannelState.tspackages/avivatorish/src/state.tsxpackages/avivatorish/src/useChannelSelectionStats.tspackages/avivatorish/src/utils.tspackages/avivatorish/tsconfig.jsonpackages/core/src/index.tspackages/core/src/models/VAnnDataSource.tspackages/core/src/models/VPointsSource.tspackages/core/src/models/VShapesSource.tspackages/core/src/models/VTableSource.tspackages/core/src/models/VZarrDataSource.tspackages/core/src/models/index.tspackages/core/src/parquetFooterStats.tspackages/core/src/pointsFeatures.tspackages/core/src/pointsLimits.tspackages/core/src/pointsLoader.tspackages/core/src/schemas/index.tspackages/core/src/store/index.tspackages/core/src/tooltip.tspackages/core/src/transformations/index.tspackages/core/src/transformations/operations.tspackages/core/src/transformations/transformations.tspackages/core/src/types.tspackages/core/src/workers/index.tspackages/core/src/workers/points-worker.tspackages/core/src/workers/pointsWorkerClient.tspackages/core/src/workers/pointsWorkerProtocol.tspackages/core/src/workers/pointsWorkerScan.tspackages/core/tsconfig.jsonpackages/layers/src/LabelsBitmaskTileLayer.tspackages/layers/src/PointsLayer.tspackages/layers/src/SpatialLayer.tspackages/layers/src/engine/PointsDataEngine.tspackages/layers/src/geoArrowStrategies.tspackages/layers/src/index.tspackages/layers/src/mortonTiledStrategy.tspackages/layers/src/pointsBbox.tspackages/layers/src/pointsFeatureCodes.tspackages/layers/src/pointsFeatureColor.tspackages/layers/src/pointsFeatureColorExtension.tspackages/layers/src/pointsLoadPlan.tspackages/layers/src/pointsLoader.tspackages/layers/src/pointsLoaderAdapter.tspackages/layers/src/pointsRenderStrategies.tspackages/layers/src/pointsScatterLayer.tspackages/layers/src/pointsTileDebug.tspackages/layers/src/pointsTileLoadCallbacks.tspackages/layers/src/pointsTiledDebugHooks.tspackages/layers/src/preloadedScatterStrategy.tspackages/layers/src/renderStack.tspackages/layers/src/resolvePointsRenderResource.tspackages/layers/src/shapesLayer.tspackages/layers/src/spatialLayerProps.tspackages/layers/tsconfig.jsonpackages/react/src/index.tspackages/react/src/provider/SpatialDataProvider.tsxpackages/react/tsconfig.jsonpackages/vis/src/ImageView/index.tsxpackages/vis/src/Sketch/index.tsxpackages/vis/src/SpatialCanvas/ImageChannelPanel.tsxpackages/vis/src/SpatialCanvas/ImageLayerContext.tsxpackages/vis/src/SpatialCanvas/LayerOrderList.tsxpackages/vis/src/SpatialCanvas/PointsFeatureFilterPanel.tsxpackages/vis/src/SpatialCanvas/PointsFeatureState.tsxpackages/vis/src/SpatialCanvas/PointsLayerPanel.tsxpackages/vis/src/SpatialCanvas/ShapeFillColorPanel.tsxpackages/vis/src/SpatialCanvas/SpatialCanvasViewer.tsxpackages/vis/src/SpatialCanvas/SpatialFeatureTooltip.tsxpackages/vis/src/SpatialCanvas/SpatialViewer.tsxpackages/vis/src/SpatialCanvas/VivLoaderRegistry.tsxpackages/vis/src/SpatialCanvas/VivSpatialViewer.tsxpackages/vis/src/SpatialCanvas/context.tsxpackages/vis/src/SpatialCanvas/featureTooltipHover.tspackages/vis/src/SpatialCanvas/hooks.tspackages/vis/src/SpatialCanvas/imageLoaderChannelDefaults.tspackages/vis/src/SpatialCanvas/index.tsxpackages/vis/src/SpatialCanvas/public.tspackages/vis/src/SpatialCanvas/renderStackAdapters.tspackages/vis/src/SpatialCanvas/renderers/imageRenderer.tspackages/vis/src/SpatialCanvas/renderers/index.tspackages/vis/src/SpatialCanvas/renderers/labelsRenderer.tspackages/vis/src/SpatialCanvas/renderers/shapesRenderer.tspackages/vis/src/SpatialCanvas/stores.tspackages/vis/src/SpatialCanvas/types.tspackages/vis/src/SpatialCanvas/useLayerData.tspackages/vis/src/SpatialCanvas/vivImagePassthrough.tspackages/vis/src/Table/index.tsxpackages/vis/src/Tree/index.tsxpackages/vis/src/index.tspackages/vis/tsconfig.jsonpackages/zarrextra/src/chunkDecode.tspackages/zarrextra/src/index.tspackages/zarrextra/src/omeZarr.tspackages/zarrextra/src/workers/codec-worker-init.tspackages/zarrextra/src/workers/workerControls.tspackages/zarrextra/tsconfig.json
💤 Files with no reviewable changes (1)
- packages/layers/src/geoArrowStrategies.ts
| // biome-ignore lint/a11y/noStaticElementInteractions: drag-reorder drop target; keyboard a11y not yet implemented for this dev panel. | ||
| <div | ||
| key={id} | ||
| style={rowStyle(selectedLayerId === id)} | ||
| onDragOver={onDragOver} | ||
| onDrop={(e) => onDrop(e, id)} | ||
| > | ||
| {/* biome-ignore lint/a11y/noStaticElementInteractions: drag handle; keyboard a11y not yet implemented for this dev panel. */} |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift
Do not suppress the accessibility error without adding keyboard reordering.
The layer-order control is operable only through drag events on a div/span; keyboard and assistive-technology users cannot reorder layers. Add keyboard-accessible move controls or equivalent key handling, then remove these suppressions.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/vis/src/SpatialCanvas/LayerOrderList.tsx` around lines 75 - 82, Add
keyboard-accessible reordering to the layer-order control around the drag
handlers in LayerOrderList, using focusable semantic controls or equivalent key
handling to move the targeted layer and update the same ordering state as
onDrop. Ensure assistive technologies can identify and operate the reorder
action, then remove both biome-ignore accessibility suppressions for the drop
target and drag handle.
There was a problem hiding this comment.
The general quality of these UI components is somewhat basic, this is out-of-scope to fix here.
There was a problem hiding this comment.
@xinaesthete, understood — makes sense to keep this out of scope for this lint-cleanup PR. Let me know if you'd like me to open a follow-up issue to track adding keyboard-accessible reordering to LayerOrderList, and I'll file it with a link back to this discussion.
| const reloadElement = useCallback( | ||
| (type: string, key: string) => { | ||
| const loaded = loadedDataRef.current; | ||
| if (type === 'shapes') { | ||
| loaded.shapes.delete(key); | ||
| loaded.worldBounds.delete(`shapes:${key}`); | ||
| // Clear prebuilt data for every layer that maps to this element key. | ||
| for (const [layerId, config] of Object.entries(layersRef.current)) { | ||
| if (config.type === 'shapes' && config.elementKey === key) { | ||
| loaded.shapePrebuiltData.delete(layerId); | ||
| loaded.shapeFillColorData.delete(layerId); | ||
| } | ||
| } | ||
| } else if (type === 'points') { | ||
| pointsEngine.evict(key); | ||
| loaded.worldBounds.delete(`points:${key}`); | ||
| } else if (type === 'image') { | ||
| loaded.images.delete(key); | ||
| loaded.worldBounds.delete(`image:${key}`); | ||
| } else if (type === 'labels') { | ||
| loaded.labels.delete(key); | ||
| loaded.worldBounds.delete(`labels:${key}`); | ||
| } | ||
| } else if (type === 'points') { | ||
| pointsEngine.evict(key); | ||
| loaded.worldBounds.delete(`points:${key}`); | ||
| } else if (type === 'image') { | ||
| loaded.images.delete(key); | ||
| loaded.worldBounds.delete(`image:${key}`); | ||
| } else if (type === 'labels') { | ||
| loaded.labels.delete(key); | ||
| loaded.worldBounds.delete(`labels:${key}`); | ||
| } | ||
| // The useEffect will pick up the missing data and reload | ||
| }, [pointsEngine]); | ||
| // The useEffect will pick up the missing data and reload | ||
| }, | ||
| [pointsEngine] |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
file="packages/vis/src/SpatialCanvas/useLayerData.ts"
echo "== file size =="
wc -l "$file"
echo "== outline =="
ast-grep outline "$file" --view expanded || true
echo "== search for resolveLayerElement and reload-related symbols =="
rg -n "resolveLayerElement|reloadRevision|reloadElement|useEffect\\(|loadedDataRef|shapePrebuiltData|shapeFillColorData|elementKey" "$file"Repository: Taylor-CCB-Group/SpatialData.js
Length of output: 10960
🏁 Script executed:
#!/bin/bash
set -euo pipefail
file="packages/vis/src/SpatialCanvas/useLayerData.ts"
echo "== lines 560-680 =="
sed -n '560,680p' "$file" | cat -n
echo "== lines 1136-1160 =="
sed -n '1136,1160p' "$file" | cat -n
echo "== lines 340-370 =="
sed -n '340,370p' "$file" | cat -n
echo "== lines 1210-1235 =="
sed -n '1210,1235p' "$file" | cat -nRepository: Taylor-CCB-Group/SpatialData.js
Length of output: 9801
🏁 Script executed:
#!/bin/bash
set -euo pipefail
file="packages/vis/src/SpatialCanvas/useLayerData.ts"
echo "== lines 680-910 =="
sed -n '680,910p' "$file" | cat -n
echo "== lines 910-1120 =="
sed -n '910,1120p' "$file" | cat -n
echo "== lines 1120-1188 =="
sed -n '1120,1188p' "$file" | cat -n
echo "== call sites of reloadElement =="
rg -n "reloadElement\\(" -g '!**/node_modules/**' .Repository: Taylor-CCB-Group/SpatialData.js
Length of output: 26528
🏁 Script executed:
#!/bin/bash
set -euo pipefail
file="packages/vis/src/SpatialCanvas/useLayerData.ts"
echo "== lines 680-910 =="
sed -n '680,910p' "$file" | cat -n
echo "== lines 910-1120 =="
sed -n '910,1120p' "$file" | cat -n
echo "== lines 1120-1188 =="
sed -n '1120,1188p' "$file" | cat -n
echo "== call sites of reloadElement =="
rg -n "reloadElement\\(" .Repository: Taylor-CCB-Group/SpatialData.js
Length of output: 26528
🏁 Script executed:
#!/bin/bash
set -euo pipefail
file="packages/vis/src/SpatialCanvas/useLayerData.ts"
echo "== lines 475-560 =="
sed -n '475,560p' "$file" | cat -n
echo "== elementMap assignments =="
rg -n "elementMap\\.(current|set|delete)|getElementMapKey\\(" "$file"Repository: Taylor-CCB-Group/SpatialData.js
Length of output: 5750
Schedule a rerender after clearing caches, and resolve shapes before deleting layer caches. reloadElement only mutates refs, so the load effect won’t see a changed dependency and the cleared data can stay unloaded until some unrelated update. The config.elementKey check also skips layers that fall back to resolveLayerElement via layerId, leaving stale shape prebuilt/fill-color entries behind.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/vis/src/SpatialCanvas/useLayerData.ts` around lines 1140 - 1165,
Update reloadElement to trigger a rerender after clearing caches, and use
resolveLayerElement to determine the element associated with each shapes layer
before deleting its shapePrebuiltData and shapeFillColorData. Preserve the
existing cache invalidation for all element types while ensuring the load effect
runs immediately after reloadElement.
There was a problem hiding this comment.
This should be addressed in a subsequent pass where we'll be substantially reviewing and refactoring things around useLayerData.
There was a problem hiding this comment.
@xinaesthete, understood — thanks for the context. I'll leave this as-is for now and defer to the upcoming refactor pass on useLayerData. Feel free to ping this thread again if it's still relevant once that work is underway.
Reverts the biome.json disable of useExhaustiveDependencies and useHookAtTopLevel. Instead of turning the rules off repo-wide (which loses signal for future code), the 6 intentional-violation sites now carry per-site `// biome-ignore` comments with rationale. Biome and eslint don't share a suppression syntax, so sites linted by both tools need both comments: - avivatorish/* (biome-only; not in lint:react scope): biome-ignore added alongside the existing eslint-disable comments. - layerChannelState.ts useMemo (deps = [layerId] by design) - state.tsx useMetadata (hooks called in try/catch, out-of-Viv guard) - useChannelSelectionStats.ts useLayoutEffect + useEffect (stable-key deps) - vis/SpatialCanvasViewer.tsx useMemo (linted by both): biome-ignore added; the eslint-disable was already present. biome ci packages/*/src stays at 0 errors with the rules active. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
`codec-worker.js` is emitted by a second vite pass (--mode codec-worker),
but the default pass had emptyOutDir: true. So `dev` (vite build --watch)
emptied dist and never ran the codec-worker pass, deleting codec-worker.js
while `workers.js` still references it via
`new URL('./codec-worker.js', import.meta.url)`.
Anything consuming zarrextra/dist after a `dev` run then failed to resolve
it — e.g. the docs dev server:
ERROR in ../packages/zarrextra/dist/workers.js
Module not found: Can't resolve './codec-worker.js'
- vite.config.ts: emptyOutDir: false in both modes.
- build: explicit `rm -rf dist` so clean builds stay stale-free.
- dev: build the codec worker once, then watch.
Verified: clean build emits codec-worker.js + .d.ts (27 files); the watch
pass and subsequent rebuilds no longer delete it; docs dev server renders
with no module-resolution error.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Three pre-existing bugs that broke consuming zarrextra/core from a
bundler (surfaced by the docs Docusaurus/webpack build).
1. parquetWasmLoader gated its Node-only WASM init on
`import.meta.url.startsWith('file:')`. Bundlers rewrite import.meta.url
to a file:// URL inside a *browser* bundle, so this was true in the
browser too, sending us into the Node branch where vite had replaced
node:fs/node:url/node:path with empty stubs:
TypeError: t is not a function (t = fileURLToPath, undefined)
Detect the Node runtime itself instead (process.versions.node + no
window). Correctly false in browser and in web workers.
2. Package exports maps declared only "types" + "import" with no
"default"/"require" fallback. Any resolver using a non-import
condition — e.g. Docusaurus' SSR/server webpack pass — got
ERR_PACKAGE_PATH_NOT_EXPORTED:
Can't resolve 'zarrextra/workers' / '@spatialdata/core'
ESM-only packages (zarrextra, avivatorish, layers, react, vis) now use
"default"; core, which really does emit CJS, gets a proper
"require": "./dist/index.cjs".
3. core's "./workers" export pointed at ./dist/workers/index.js, which is
never emitted (that dir holds only .d.ts) — the JS is ./dist/workers.js.
Latent: nothing imports that subpath yet.
Verified: all 9 subpaths resolve under both import and require conditions
with existing targets; `docusaurus build` compiles clean (Server + Client);
root build, unit tests, and lint:biome all pass.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
What
Clears the ~128 error / ~88 warning Biome backlog surfaced by the 1.9.4 → 2.5.3 upgrade (#82) across
packages/*/src. Result: 0 errors, 40 warnings (allnoExplicitAny, configured as a non-blocking warn). Build green, formatting clean, unit tests pass.Changes
Safe autofixes (89 files): formatting,
organizeImports, unused imports, optional chaining,useConst, etc.4 regressions that Biome's "safe" autofixes introduced — each caught via
pnpm buildand repaired:noPrototypeBuiltinsrewroteObject.prototype.hasOwnProperty.call→Object.hasOwn(×2), which fails underlib: ES2020. BumpedlibES2020 → ES2022 across the 6 package tsconfigs (targetstays ES2020 —Object.hasOwnis a runtime API, not syntax) and kept the modern form.noTsIgnorerewrote//@ts-ignore→//@ts-expect-erroron twolet x: anylines with no error (TS2578). Removed the now-pointless directives.noUselessConstructordeleted a load-bearingconstructor(...args)onLabelsBitmaskTileLayerthat widens the baseXRLayersignature. Restored +biome-ignore.noUnusedVariablesrenamed a dead componentRepr→_Repr, breaking the PascalCase hooks heuristic. Restored +biome-ignore(dev-only<Repr/>scaffolding).Manual fixes: typed a
let footer, dropped a redundant non-null assertion, fixed a precision-loss literal (value-identical), removed dead destructured params/vars, suppressed two a11y drag-handle findings inline with TODOs.React-hooks rules: kept
useExhaustiveDependencies+useHookAtTopLevelenabled (they retain signal for future code). The 6 intentional-violation sites carry per-site// biome-ignorecomments with rationale. Biome and eslint don't share a suppression syntax, sovissites (linted by both) get both abiome-ignoreand the pre-existingeslint-disable;avivatorishsites (biome-only — outsidelint:reactscope) get abiome-ignorealongside their existingeslint-disable. These are intentional stable-key-dep patterns and the out-of-VivuseMetadatatry/catch guard.CI: added a
biome-lintjob (pnpm lint:biome=biome ci packages/*/src) as an errors-only gate over the cleaned library source.Also: zarrextra
devbuild fix (unrelated, folded in)Pre-existing bug found while testing, not caused by the lint work (
vite.config.ts/package.jsonwere untouched by it; it reproduces onmain).codec-worker.jsis emitted by a second vite pass (--mode codec-worker), but the default pass hademptyOutDir: true. Sodev(vite build --watch) emptieddistand never ran the codec-worker pass — deletingcodec-worker.jswhileworkers.jsstill references it vianew URL('./codec-worker.js', import.meta.url). Any consumer ofzarrextra/distafter adevrun then broke, e.g. the docs dev server:vite.config.ts:emptyOutDir: falsein both modes.build: explicitrm -rf distso clean builds stay stale-free.dev: build the codec worker once, then watch.Verified: clean build emits
codec-worker.js+.d.ts(27 files); the watch pass and subsequent rebuilds no longer delete it; docs dev server renders with no module-resolution error.Reviewer notes
packages/*/src(the cleaned code). Demo, scripts, tests, and dev_scripts still carry ~15 biome errors and are intentionally out of scope — sopnpm lint(biome check ., whole repo) is still red. Clearing those to enable a repo-wide gate is a reasonable follow-up.lib→ ES2022 bump touches the recently-upgraded TS toolchain;targetis unchanged, so no downlevel-emit impact.biome-ignoreand aneslint-disablecomment (no shared syntax) — seeSpatialCanvasViewer.tsx.🤖 Generated with Claude Code
Summary by CodeRabbit