feat: overhaul with Vite, React 19, Tailwind, Builder, Structure View#77
Merged
wemeetagain merged 37 commits intomasterfrom Mar 19, 2026
Merged
feat: overhaul with Vite, React 19, Tailwind, Builder, Structure View#77wemeetagain merged 37 commits intomasterfrom
wemeetagain merged 37 commits intomasterfrom
Conversation
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Address critical gaps: patchSszTypes preservation, worker data contracts, mode-specific input behavior, structure view data source, dead YAML schema code, and biome config retention. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
13 tasks covering: Vite scaffold, core lib migration, worker setup, hooks, UI components, structure view, app wiring, cleanup, and Dockerfile update. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace Webpack+Babel+Bulma+SCSS build stack with Vite+React 19+Tailwind CSS 4. Delete old config files and entry points, add minimal app shell. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Also fixes type errors in lib/types.ts and lib/formats.ts to pass strict TypeScript checking. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- useWorker: switch from useRef to useState so worker initialization triggers re-renders and downstream hooks receive the worker - handleModeChange: clear input and parsed value when switching modes to prevent stale YAML being sent as hex in deserialize mode - CopyButton: wrap clipboard API call in try/catch Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The SSZ hashing library (as-sha256) uses Buffer.allocUnsafe which doesn't exist in browser environments. Add the buffer polyfill to both main thread and worker entry points. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
React's setState treats callable values as updater functions. Comlink.wrap() returns a Proxy that React tries to invoke, causing "rawValue.apply is not a function". Wrap in arrow function so React calls the arrow (updater) which returns the proxy (value). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Deep black surface palette (#0c0e14 / #12151e / #181c28) - Ethereum blue (#627eea) as accent color throughout - ETH diamond logo in header - Google Fonts: Inter for UI, JetBrains Mono for data - Custom scrollbar styling, consistent focus rings - Smaller, denser typography for dev-tool feel - Polished controls: ghost buttons, inset shadow tabs - Hash tree root highlighted in eth-blue - Sticky header with backdrop blur - Better spacing and max-width constraint - Copy button with "Copied!" feedback state - Download toast notification Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Form-based builder that introspects SSZ types and generates appropriate input controls: - Containers: collapsible field groups with labeled inputs - uint types: number/text inputs (bigint for 8-byte) - boolean: toggle buttons - bytes: hex input with length validation - lists: add/remove items with element type inputs - vectors: fixed-length element inputs Toggle between Editor (text) and Builder (form) modes on the input panel. Builder syncs values to the text editor and serialization output in real-time. Available in serialize mode. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Clickable bit grid where each bit is a toggle (0/1). Shows bit count and set count in the header. Controls for add/remove bit (BitList only), set all 1, set all 0. Caps visual grid at 256 bits with overflow indicator. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
SSZ bit types use BitArray objects (Uint8Array + bitLen), not plain boolean arrays. Convert to bool[] for the UI grid, and back to BitArray via BitArray.fromBoolArray() when emitting changes. BitVector now initializes with the correct fixed length. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When switching serialize→deserialize, the serialized hex bytes now flow into the deserialize input for seamless round-trip testing. When switching deserialize→serialize, the deserialized value flows back as YAML. Eliminates the brief error from the empty intermediate state. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
result.serialized is already a Uint8Array — don't pass it through inputFormats.hex.dump which tries to type.serialize() it again. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
toHexString may not handle Comlink-transferred Uint8Array correctly. Use the same hex dump path that the output panel uses successfully. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The 300ms debounce means the first deserialize attempt after a mode switch still has the old YAML text. Guard against this by checking that input starts with 0x before calling worker.deserialize. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…e mode Mirror of the deserialize guard: when in serialize mode with a non-hex format (yaml/json), skip if the debounced input is still hex data from the previous deserialize mode. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The auto-generate effect was firing on every mode switch (because serializeMode and inputFormat were in the dependency chain), overwriting the carefully placed round-trip data. Now the auto- trigger only depends on worker/typeName/forkName — mode switches preserve the user's data. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
BitArray objects were falling through to String() giving [object Object]. Now shows "N bits, M set" summary. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- BitArray: renders as binary string (e.g., "0000101100...") - Bytes: renders full hex without truncation - Long values (>64 chars): truncated with "... (N chars)" suffix, click to expand/collapse the full value Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Truncated values now show meaningful context instead of character count: bytes show "N bytes", bits show "N bits, M set". Uses a valueSuffix field on TreeNodeData to carry the semantic description from formatValue to the tree node renderer. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Rows of 32 bits with the starting index (0, 32, 64...) displayed on the left of each row. Bumped max visible bits to 512. Makes it much easier to count and locate specific bit positions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Header: slim branding bar (logo, title, spec/GitHub links) - New toolbar: fork, type, and serialize/deserialize mode toggle in a dedicated row below the header — always visible, not cramped - Mode toggle moved from output panel to toolbar (it's a global control, not an output concern) - Main area: CSS grid layout for better proportions - Footer: minimal single-line with versions - Output panel simplified (no more mode tabs) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Favicon: Lodestar icon (favicon.ico, icon-192.png, icon-512.png) - Title: "SSZ Playground | Lodestar" - Meta description for SEO - Header: "Lodestar" label linking to lodestar.chainsafe.io, subtitle with spec link, GitHub icon - Footer: "A Lodestar tool by ChainSafe Systems" - Matches enr-app branding pattern Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add base64 as a deserialize input format alongside hex. The input panel now shows hex/base64 tabs in deserialize mode. The worker decodes base64 via atob before deserializing. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove unused fromBase64 function - Add biome-ignore for intentionally incomplete useEffect deps - Fix undeclared React type with import() syntax - Disable noArrayIndexKey rule (SSZ list items have no stable key) - Auto-format fixes applied Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
What changed
Removed (20+ packages): Webpack, Babel, Bulma, SCSS, threads, react-alert, react-loading-overlay, react-spinners, eyzy-tree, file-saver, bn.js, core-js, and all associated loaders/plugins
Added (3 packages): Comlink, Sonner, Tailwind CSS
New features:
Architecture:
Test plan
npm run build)🤖 Generated with Claude Code