Skip to content

Adopt the Bike Shaving house style - #386

Open
brainkim wants to merge 13 commits into
mainfrom
chore/b9g-eslint-config
Open

Adopt the Bike Shaving house style#386
brainkim wants to merge 13 commits into
mainfrom
chore/b9g-eslint-config

Conversation

@brainkim

Copy link
Copy Markdown
Member

Adopts the Bike Shaving house style (@b9g/eslint-config@0.1.2) across the repo, replacing ESLint 8 + .eslintrc.json + prettier with the flat config. Also restores the it.each tests, per request.

Note: this branch includes #385's two commits (it stacks on the bare-Function fix). Merging #385 first keeps this diff honest; a rebase after will drop the duplicates automatically.

What's in here

  1. it.each restored — reverts the nine for-of conversions from Run the package test suites through libuild #376. libuild 0.2.20 implements .each on node, so both platforms report 126 passed with per-case reporting back.
  2. The config swap — ESLint 9, eslint.config.js importing @b9g/eslint-config, prettier and its plugins removed. The lint script is just eslint ..
  3. The autofix sweep — ~1,500 mechanical fixes (operator position, array-simple, quotes, comment style, declaration padding).
  4. ~180 hand fixes — return types everywhere, ACROCase renames (oldHTMLValue, noReactSVGProps, escapeXML, iframeId, …), deep optional chains flattened, catches bind their errors, bare Function stragglers in tests typed.

Repo-level overrides (mirroring the old config's intent, plus three discoveries)

  • Examples stay space-indented; tests keep the crank plugin's component rules off — both carried over from .eslintrc.json.
  • Three JSX rules are off because their fixers change what renders in crank: jsx-one-expression-per-line splits adjacent text/expressions across lines (turned "render 2" into "render2" in a test), jsx-curly-brace-presence rewrites {"a"} children into whitespace-joined text (broke a hydration test), and consistent-type-imports converts the classic JSX factory import to import type because it can't see compiled usage. Worth knowing for other Crank projects adopting the config.
  • no-empty-object-type allows single-extends interfaces (the ProvisionMap/EventMap/ChildIterable extension points); no-unused-expressions allows tagged templates (tests invoke jsx to assert it throws).
  • Crank's deliberate class/interface declaration merging (Element, Context) and the global-namespace extension points carry reasoned inline disables.

Verification

  • Core: 606 passed on chromium and webkit.
  • eslint-plugin-crank: 126 passed on bun and node (with .each restored).
  • crankdown: typecheck clean, 28 passed on bun and node — and tsc caught that my Marked annotation had to be Array<Element | string>, its true return type.
  • eslint . fully clean; root tsc --noEmit clean.
  • Website has no typecheck in CI; its ~30 new component annotations are parser-verified, and the preexisting tsc failures there (import attributes vs its tsconfig) are untouched.

🤖 Generated with Claude Code

https://claude.ai/code/session_019pggktip8wsuxzy2VCY9p7

@brainkim
brainkim force-pushed the chore/b9g-eslint-config branch 3 times, most recently from cd4e509 to deb711c Compare August 28, 2026 07:12
brainkim and others added 3 commits September 4, 2026 21:14
libuild 0.2.20 implements .each on node, so the cases run on both
platforms with per-case reporting restored. 126 passed on bun and node.

This reverts commit c377f5b.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019pggktip8wsuxzy2VCY9p7
Replaces ESLint 8, .eslintrc.json and prettier with the flat house
config, and applies its autofixes across the repo. Overrides mirror the
old config's intent: examples stay space-indented, and tests keep the
crank plugin's component rules off. Two repo-specific settings: empty
single-extends interfaces are allowed because ProvisionMap, EventMap
and ChildIterable are extension points, and tagged templates are
allowed as statements because tests invoke the jsx tag to assert it
throws. One rule is off for tests: the jsx-curly-brace-presence fixer
joins adjacent string expression children into a single text node,
which changes rendered output that the tests assert exactly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019pggktip8wsuxzy2VCY9p7
Explicit return types on every function declaration and exported
component; real signatures for the remaining bare Function types;
ACROCase renames; deep optional chains flattened into named locals;
catch clauses bind their errors; reasoned inline disables for the
class/interface declaration merging behind Element and Context and for
the empty extension-point interfaces in the global Crank namespace.
crankdown's Marked returns Array<Element | string>, its real return
type.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019pggktip8wsuxzy2VCY9p7
@brainkim
brainkim force-pushed the chore/b9g-eslint-config branch from deb711c to 9ef6606 Compare September 5, 2026 01:16
brainkim and others added 10 commits September 9, 2026 00:05
Reformats the repo under the new esfold/breaks rule (eslint-plugin-esfold
0.1.5, whose fixer now converges) and answers the new design rules:
Element's members move from its merged interface into the class body, the
event method typings move from Context's merged interface into the class,
and the symbol slots on Context and CustomEventTarget move into their
merged interfaces. The examples override gains indent-binary-ops to match
its 2-space indent.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019pggktip8wsuxzy2VCY9p7
Stars now bind to the name (*[Symbol.iterator], async *[Symbol.asyncIterator]).
With @b9g/no-symbol-fields removed, the symbol slots return to class-body
declare fields, which drops Context's generic merged interface and its
unused-vars disable, and restores the inline handleEvent union now that
esfold 0.1.6 tiles it correctly.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019pggktip8wsuxzy2VCY9p7
The indent rule no longer has an opinion on class heritage clauses, so the
continuation line takes one level of indentation.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019pggktip8wsuxzy2VCY9p7
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019pggktip8wsuxzy2VCY9p7
The isHuggable fix unhugs object-pattern parameters which carry a type
literal, and long string arguments wrap again instead of joining past the
line limit. The indent carveouts do not rewrite existing code, so the
stair-stepped ternary chains and the cascaded scope assignment are
hand-flattened to the fresh-format shapes. JSX chains keep the staircase
by design.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019pggktip8wsuxzy2VCY9p7
One-parameter signatures returning a union break at the parameter list
again instead of stranding the union's tail.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019pggktip8wsuxzy2VCY9p7
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant