Skip to content

Commit 51298e1

Browse files
Add ChainSpec selector for InspectStateViewer (#3)
- Change StateViewer from 2 tabs to 3 tabs (Encoded/Decoded Tiny/Decoded Full) - Add chainSpec prop to InspectStateViewer to select between tinyChainSpec and fullChainSpec - Update useLoadState hook to dynamically select chain spec based on prop - Update tests to handle new tab structure and mock fullChainSpec - Maintain backward compatibility with chainSpec defaulting to 'tiny' Fixes #3 Co-Authored-By: Tomek Drwięga <tomusdrw+github@gmail.com>
1 parent 4f4e30e commit 51298e1

4 files changed

Lines changed: 39 additions & 15 deletions

File tree

src/components/InspectStateViewer.test.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ import { describe, it, expect, beforeEach, vi } from 'vitest';
55
vi.mock('@typeberry/state-merkleization', () => ({
66
loadState: vi.fn(),
77
config: {
8-
tinyChainSpec: {}
8+
tinyChainSpec: {},
9+
fullChainSpec: {}
910
},
1011
bytes: {
1112
Bytes: {

src/components/InspectStateViewer.tsx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,24 @@ interface InspectStateViewerProps {
1313
state: Record<string, string>;
1414
title?: string;
1515
searchTerm?: string;
16+
chainSpec?: 'tiny' | 'full';
1617
}
1718

1819

1920

20-
const spec = config.tinyChainSpec;
2121

2222
const useLoadState = (
2323
state: Record<string, string> | undefined,
2424
setError: (error: string | null) => void,
2525
ctx: string,
26+
chainSpec: 'tiny' | 'full',
2627
) => {
2728
return useMemo(() => {
2829
if (!state) return null;
2930

3031
try {
3132
setError(null);
33+
const spec = chainSpec === 'tiny' ? config.tinyChainSpec : config.fullChainSpec;
3234
return loadState(spec, Object.entries(state).map(([key, value]) => {
3335
return [
3436
bytes.Bytes.parseBytes(key, 31),
@@ -40,21 +42,22 @@ const useLoadState = (
4042
setError(`${ctx}: ${errorMessage}`);
4143
return null;
4244
}
43-
}, [state, setError, ctx]);
45+
}, [state, setError, ctx, chainSpec]);
4446
}
4547

4648
const InspectStateViewer = ({
4749
preState,
4850
state,
4951
title = "State Data",
5052
searchTerm: externalSearchTerm,
53+
chainSpec = 'tiny',
5154
}: InspectStateViewerProps) => {
5255
const [error, setError] = useState<string | null>(null);
5356
const searchTerm = externalSearchTerm || '';
5457
const isDiffMode = preState !== undefined;
5558

56-
const preStateAccess = useLoadState(preState, setError, 'preState');
57-
const stateAccess = useLoadState(state, setError, 'postState');
59+
const preStateAccess = useLoadState(preState, setError, 'preState', chainSpec);
60+
const stateAccess = useLoadState(state, setError, 'postState', chainSpec);
5861

5962
// Expose all states to the global window object for DevTools inspection.
6063
(window as unknown as { preState: unknown }).preState = preStateAccess;

src/components/StateViewer.test.tsx

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ describe('StateViewer', () => {
6363

6464
// Component should render without throwing errors
6565
expect(screen.getByText('Encoded')).toBeInTheDocument();
66-
expect(screen.getByText('Decoded')).toBeInTheDocument();
66+
expect(screen.getByText('Decoded Tiny')).toBeInTheDocument();
67+
expect(screen.getByText('Decoded Full')).toBeInTheDocument();
6768
});
6869

6970
it('should default to inspect tab', () => {
@@ -400,13 +401,21 @@ describe('StateViewer', () => {
400401
// Should be on Raw tab by default
401402
expect(screen.getByText('CHANGED')).toBeInTheDocument();
402403

403-
// Switch to Decoded tab
404-
const decodedTab = screen.getByText('Decoded');
405-
fireEvent.click(decodedTab);
404+
// Switch to Decoded Tiny tab
405+
const decodedTinyTab = screen.getByText('Decoded Tiny');
406+
fireEvent.click(decodedTinyTab);
406407

407408
// Note: The decoded view might show errors due to mock limitations
408409
// but the component should still render without crashing
409-
expect(decodedTab).toBeInTheDocument();
410+
expect(decodedTinyTab).toBeInTheDocument();
411+
412+
// Switch to Decoded Full tab
413+
const decodedFullTab = screen.getByText('Decoded Full');
414+
fireEvent.click(decodedFullTab);
415+
416+
// Note: The decoded view might show errors due to mock limitations
417+
// but the component should still render without crashing
418+
expect(decodedFullTab).toBeInTheDocument();
410419
});
411420

412421
it('should maintain backward compatibility with single state prop', () => {
@@ -501,4 +510,4 @@ describe('StateViewer', () => {
501510
});
502511
});
503512
});
504-
});
513+
});

src/components/StateViewer.tsx

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,11 @@ const StateViewer = ({
2626
className="pb-2"
2727
/>
2828

29-
<Tabs defaultValue="inspect" className="w-full">
30-
<TabsList className="grid w-full grid-cols-2 pb-2">
29+
<Tabs defaultValue="inspect-tiny" className="w-full">
30+
<TabsList className="grid w-full grid-cols-3 pb-2">
3131
<TabsTrigger value="raw">Encoded</TabsTrigger>
32-
<TabsTrigger value="inspect">Decoded</TabsTrigger>
32+
<TabsTrigger value="inspect-tiny">Decoded Tiny</TabsTrigger>
33+
<TabsTrigger value="inspect-full">Decoded Full</TabsTrigger>
3334
</TabsList>
3435

3536
<TabsContent value="raw" className="mt-0 border rounded-lg">
@@ -41,11 +42,21 @@ const StateViewer = ({
4142
/>
4243
</TabsContent>
4344

44-
<TabsContent value="inspect" className="mt-0">
45+
<TabsContent value="inspect-tiny" className="mt-0">
4546
<InspectStateViewer
4647
preState={preState}
4748
state={state}
4849
searchTerm={searchTerm}
50+
chainSpec="tiny"
51+
/>
52+
</TabsContent>
53+
54+
<TabsContent value="inspect-full" className="mt-0">
55+
<InspectStateViewer
56+
preState={preState}
57+
state={state}
58+
searchTerm={searchTerm}
59+
chainSpec="full"
4960
/>
5061
</TabsContent>
5162
</Tabs>

0 commit comments

Comments
 (0)