chore: upgrade to latest waku, hydration improvevments

This commit is contained in:
Danish Arora 2025-10-23 18:20:16 +05:30
parent b7e271a0d7
commit 0ea489a37b
No known key found for this signature in database
GPG Key ID: 1C6EF37CDAE1426E
10 changed files with 76 additions and 58 deletions

View File

@ -38,7 +38,7 @@ const ActivityFeed: React.FC = () => {
const { content, network } = useForum(); const { content, network } = useForum();
const { posts, comments, cells, commentsByPost } = content; const { posts, comments, cells, commentsByPost } = content;
const { isConnected } = network; const { isHydrated } = network;
const combinedFeed: FeedItem[] = useMemo(() => { const combinedFeed: FeedItem[] = useMemo(() => {
@ -144,7 +144,8 @@ const ActivityFeed: React.FC = () => {
); );
}; };
if (!isConnected) { // Show loading skeleton only while store is hydrating
if (!isHydrated) {
return ( return (
<div className="space-y-3"> <div className="space-y-3">
{[...Array(5)].map((_, i) => ( {[...Array(5)].map((_, i) => (

View File

@ -1,6 +1,6 @@
import { useState, useMemo } from 'react'; import { useState, useMemo } from 'react';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { useContent, usePermissions } from '@/hooks'; import { useContent, usePermissions, useNetwork } from '@/hooks';
import { import {
Layout, Layout,
MessageSquare, MessageSquare,
@ -143,6 +143,7 @@ const CellList = () => {
const { cellsWithStats } = useContent(); const { cellsWithStats } = useContent();
const content = useContent(); const content = useContent();
const { canCreateCell } = usePermissions(); const { canCreateCell } = usePermissions();
const { isHydrated } = useNetwork();
const [sortOption, setSortOption] = useState<SortOption>('relevance'); const [sortOption, setSortOption] = useState<SortOption>('relevance');
// Apply sorting to cells // Apply sorting to cells
@ -150,7 +151,8 @@ const CellList = () => {
return sortCells(cellsWithStats, sortOption); return sortCells(cellsWithStats, sortOption);
}, [cellsWithStats, sortOption]); }, [cellsWithStats, sortOption]);
if (!cellsWithStats.length) { // Only show loading if store is not yet hydrated
if (!isHydrated && !cellsWithStats.length) {
return ( return (
<div className="container mx-auto px-4 pt-24 pb-16 text-center"> <div className="container mx-auto px-4 pt-24 pb-16 text-center">
<Loader2 className="w-8 h-8 mx-auto mb-4 animate-spin text-primary" /> <Loader2 className="w-8 h-8 mx-auto mb-4 animate-spin text-primary" />

View File

@ -1,4 +1,4 @@
import React, { useEffect, useState } from 'react'; import React, { useState } from 'react';
import { Link, useLocation } from 'react-router-dom'; import { Link, useLocation } from 'react-router-dom';
import { useAuth, useForum, useNetwork, useUIState } from '@/hooks'; import { useAuth, useForum, useNetwork, useUIState } from '@/hooks';
import { EVerificationStatus } from '@opchan/core'; import { EVerificationStatus } from '@opchan/core';

View File

@ -12,12 +12,13 @@ import {
import PostCard from '@/components/PostCard'; import PostCard from '@/components/PostCard';
import FeedSidebar from '@/components/FeedSidebar'; import FeedSidebar from '@/components/FeedSidebar';
import { ModerationToggle } from '@/components/ui/moderation-toggle'; import { ModerationToggle } from '@/components/ui/moderation-toggle';
import { useAuth, useContent } from '@/hooks'; import { useAuth, useContent, useNetwork } from '@/hooks';
import { EVerificationStatus } from '@opchan/core'; import { EVerificationStatus } from '@opchan/core';
import { sortPosts, SortOption } from '@/utils/sorting'; import { sortPosts, SortOption } from '@/utils/sorting';
const FeedPage: React.FC = () => { const FeedPage: React.FC = () => {
const content = useContent(); const content = useContent();
const { verificationStatus } = useAuth(); const { verificationStatus } = useAuth();
const { isHydrated } = useNetwork();
const [sortOption, setSortOption] = useState<SortOption>('relevance'); const [sortOption, setSortOption] = useState<SortOption>('relevance');
const allPosts = useMemo( const allPosts = useMemo(
@ -25,8 +26,9 @@ const FeedPage: React.FC = () => {
[content.posts, sortOption] [content.posts, sortOption]
); );
// Loading skeleton // Loading skeleton - only show if store is not yet hydrated
if ( if (
!isHydrated &&
!content.posts.length && !content.posts.length &&
!content.comments.length && !content.comments.length &&
!content.cells.length !content.cells.length

98
package-lock.json generated
View File

@ -5647,17 +5647,17 @@
} }
}, },
"node_modules/@waku/core": { "node_modules/@waku/core": {
"version": "0.0.40-79dfb35.0", "version": "0.0.40-ff9c430.0",
"resolved": "https://registry.npmjs.org/@waku/core/-/core-0.0.40-79dfb35.0.tgz", "resolved": "https://registry.npmjs.org/@waku/core/-/core-0.0.40-ff9c430.0.tgz",
"integrity": "sha512-+94ez/4zZDQffAK/ERzXOkqCOlMh28/EEtTmqdaahSLrpc3EgqdIsDC8uUPddkOSDoaJ2Y657gm4WZ4PjyRmOQ==", "integrity": "sha512-+ZY3OgAcIvazZrwX31lh3RDDtye/m4+WPyqNqrMEG+Ybd88ZJH8svdF9BxldPOltDBkM/5h2bsWoon6jLuGefw==",
"license": "MIT OR Apache-2.0", "license": "MIT OR Apache-2.0",
"dependencies": { "dependencies": {
"@libp2p/ping": "2.0.35", "@libp2p/ping": "2.0.35",
"@noble/hashes": "^1.3.2", "@noble/hashes": "^1.3.2",
"@waku/enr": "0.0.34-79dfb35.0", "@waku/enr": "0.0.34-ff9c430.0",
"@waku/interfaces": "0.0.35-79dfb35.0", "@waku/interfaces": "0.0.35-ff9c430.0",
"@waku/proto": "0.0.15-79dfb35.0", "@waku/proto": "0.0.15-ff9c430.0",
"@waku/utils": "0.0.28-79dfb35.0", "@waku/utils": "0.0.28-ff9c430.0",
"debug": "^4.3.4", "debug": "^4.3.4",
"it-all": "^3.0.4", "it-all": "^3.0.4",
"it-length-prefixed": "^9.0.4", "it-length-prefixed": "^9.0.4",
@ -5712,16 +5712,16 @@
} }
}, },
"node_modules/@waku/discovery": { "node_modules/@waku/discovery": {
"version": "0.0.13-79dfb35.0", "version": "0.0.13-ff9c430.0",
"resolved": "https://registry.npmjs.org/@waku/discovery/-/discovery-0.0.13-79dfb35.0.tgz", "resolved": "https://registry.npmjs.org/@waku/discovery/-/discovery-0.0.13-ff9c430.0.tgz",
"integrity": "sha512-YNR7ThBjerUqqK0dOPAartpx5OeQN3r3xmuabUm8SCnKKXFLbB7WFBtSwu3X0O4GoalhtC9fAJhkia91A6CZEQ==", "integrity": "sha512-FGmiaXawE9JxP2VTwVbFC8Qiafh8p1t4ahcDu6Rq0aWh5mNS0qVZj0vDCUMy3HjB9CtHO6+M6g/1u6FPYd9mXQ==",
"license": "MIT OR Apache-2.0", "license": "MIT OR Apache-2.0",
"dependencies": { "dependencies": {
"@waku/core": "0.0.40-79dfb35.0", "@waku/core": "0.0.40-ff9c430.0",
"@waku/enr": "0.0.34-79dfb35.0", "@waku/enr": "0.0.34-ff9c430.0",
"@waku/interfaces": "0.0.35-79dfb35.0", "@waku/interfaces": "0.0.35-ff9c430.0",
"@waku/proto": "0.0.15-79dfb35.0", "@waku/proto": "0.0.15-ff9c430.0",
"@waku/utils": "0.0.28-79dfb35.0", "@waku/utils": "0.0.28-ff9c430.0",
"debug": "^4.3.4", "debug": "^4.3.4",
"dns-over-http-resolver": "^3.0.8", "dns-over-http-resolver": "^3.0.8",
"hi-base32": "^0.5.1", "hi-base32": "^0.5.1",
@ -5732,9 +5732,9 @@
} }
}, },
"node_modules/@waku/enr": { "node_modules/@waku/enr": {
"version": "0.0.34-79dfb35.0", "version": "0.0.34-ff9c430.0",
"resolved": "https://registry.npmjs.org/@waku/enr/-/enr-0.0.34-79dfb35.0.tgz", "resolved": "https://registry.npmjs.org/@waku/enr/-/enr-0.0.34-ff9c430.0.tgz",
"integrity": "sha512-suGFUu94gizghRQ+gNjTqR4zXMDK91FBlIn0EeALwVIboHX1MUExMjd58qgQ8biWdcJpnB/NiyiobK+5X46U7Q==", "integrity": "sha512-bJc3IJ9b17B4nAa8S6n4a66fvx2eblyaS0MtzGqEcTTtEr+c//GScH8Xm/2oZ4bdyf/dm6iP1/ZeApvD9Wo+XQ==",
"license": "MIT OR Apache-2.0", "license": "MIT OR Apache-2.0",
"dependencies": { "dependencies": {
"@ethersproject/rlp": "^5.7.0", "@ethersproject/rlp": "^5.7.0",
@ -5742,7 +5742,7 @@
"@libp2p/peer-id": "5.1.7", "@libp2p/peer-id": "5.1.7",
"@multiformats/multiaddr": "^12.0.0", "@multiformats/multiaddr": "^12.0.0",
"@noble/secp256k1": "^1.7.1", "@noble/secp256k1": "^1.7.1",
"@waku/utils": "0.0.28-79dfb35.0", "@waku/utils": "0.0.28-ff9c430.0",
"debug": "^4.3.4", "debug": "^4.3.4",
"js-sha3": "^0.9.2" "js-sha3": "^0.9.2"
}, },
@ -5786,18 +5786,18 @@
} }
}, },
"node_modules/@waku/interfaces": { "node_modules/@waku/interfaces": {
"version": "0.0.35-79dfb35.0", "version": "0.0.35-ff9c430.0",
"resolved": "https://registry.npmjs.org/@waku/interfaces/-/interfaces-0.0.35-79dfb35.0.tgz", "resolved": "https://registry.npmjs.org/@waku/interfaces/-/interfaces-0.0.35-ff9c430.0.tgz",
"integrity": "sha512-3zBBpblsSrLHUAOjkQ+js0G5/TeNS4PERgR587caxn75xNn7Fd8WvgAM1xhMbtQU08twDZFGXKaJu3m9zCOOmA==", "integrity": "sha512-m6az/AVkCF7nSlZsxKtRgPmyPVEjKg6LREnOWNIyAA2uCvesx00JxEN7DhkmgST+wNrH5+1LgoyE6mXTcSDqTw==",
"license": "MIT OR Apache-2.0", "license": "MIT OR Apache-2.0",
"engines": { "engines": {
"node": ">=22" "node": ">=22"
} }
}, },
"node_modules/@waku/proto": { "node_modules/@waku/proto": {
"version": "0.0.15-79dfb35.0", "version": "0.0.15-ff9c430.0",
"resolved": "https://registry.npmjs.org/@waku/proto/-/proto-0.0.15-79dfb35.0.tgz", "resolved": "https://registry.npmjs.org/@waku/proto/-/proto-0.0.15-ff9c430.0.tgz",
"integrity": "sha512-lH2a74lNzXKNpALDWIMLFfNMmfJtd+lAFgLhMEu3lHBVCgu1SVXy54fBk3X08A/cfOZSzuW0kStlND6GsYQOyA==", "integrity": "sha512-JuPcioC2ry7do5Sa2TABjaJ4uQ4+jAbaZsjiir5OKmZI5krCv1BqKoZehY+BaX1lMerDfrGAXMpNQHjykfbthw==",
"license": "MIT OR Apache-2.0", "license": "MIT OR Apache-2.0",
"dependencies": { "dependencies": {
"protons-runtime": "^5.4.0" "protons-runtime": "^5.4.0"
@ -5807,9 +5807,9 @@
} }
}, },
"node_modules/@waku/sdk": { "node_modules/@waku/sdk": {
"version": "0.0.36-79dfb35.0", "version": "0.0.36-ff9c430.0",
"resolved": "https://registry.npmjs.org/@waku/sdk/-/sdk-0.0.36-79dfb35.0.tgz", "resolved": "https://registry.npmjs.org/@waku/sdk/-/sdk-0.0.36-ff9c430.0.tgz",
"integrity": "sha512-mbr8dzHLq5T4K4ShfJwOlPeAY2v9ABvZ5mUbViFsKgfwO14vQV4X80P/lgyiFYwQg8r6ZL7Mc9UkRz/FArgSDg==", "integrity": "sha512-BO6svBNw1B+HeCioKDYeFsmsxhBHzbLkxPYqVMm8FDTngmZGj1dywli4YDMm8cgwWux+Kp9TcoDEkqvKgE0ctw==",
"license": "MIT OR Apache-2.0", "license": "MIT OR Apache-2.0",
"dependencies": { "dependencies": {
"@chainsafe/libp2p-noise": "16.1.3", "@chainsafe/libp2p-noise": "16.1.3",
@ -5820,12 +5820,12 @@
"@libp2p/websockets": "9.2.16", "@libp2p/websockets": "9.2.16",
"@noble/hashes": "^1.3.3", "@noble/hashes": "^1.3.3",
"@types/lodash.debounce": "^4.0.9", "@types/lodash.debounce": "^4.0.9",
"@waku/core": "0.0.40-79dfb35.0", "@waku/core": "0.0.40-ff9c430.0",
"@waku/discovery": "0.0.13-79dfb35.0", "@waku/discovery": "0.0.13-ff9c430.0",
"@waku/interfaces": "0.0.35-79dfb35.0", "@waku/interfaces": "0.0.35-ff9c430.0",
"@waku/proto": "0.0.15-79dfb35.0", "@waku/proto": "0.0.15-ff9c430.0",
"@waku/sds": "0.0.8-79dfb35.0", "@waku/sds": "0.0.8-ff9c430.0",
"@waku/utils": "0.0.28-79dfb35.0", "@waku/utils": "0.0.28-ff9c430.0",
"libp2p": "2.8.11", "libp2p": "2.8.11",
"lodash.debounce": "^4.0.8" "lodash.debounce": "^4.0.8"
}, },
@ -5834,15 +5834,15 @@
} }
}, },
"node_modules/@waku/sds": { "node_modules/@waku/sds": {
"version": "0.0.8-79dfb35.0", "version": "0.0.8-ff9c430.0",
"resolved": "https://registry.npmjs.org/@waku/sds/-/sds-0.0.8-79dfb35.0.tgz", "resolved": "https://registry.npmjs.org/@waku/sds/-/sds-0.0.8-ff9c430.0.tgz",
"integrity": "sha512-hhzlLwgSsDYYmIBBZprJWkCUkI6oJfrgUgMAyrC04JIQbzvuOF0sRHHUY4C6VQKmxUJFU0Lj+RRPj1pR6ezk9w==", "integrity": "sha512-st2/2QeId6kFyK53L3aV4cNTyYCfrM7As77k21nlgo0PEHKHyPPFuoIkZUwRIWO6qM9ohXgiIU3RVTioEtZuTA==",
"license": "MIT OR Apache-2.0", "license": "MIT OR Apache-2.0",
"dependencies": { "dependencies": {
"@libp2p/interface": "2.10.4", "@libp2p/interface": "2.10.4",
"@noble/hashes": "^1.7.1", "@noble/hashes": "^1.7.1",
"@waku/proto": "0.0.15-79dfb35.0", "@waku/proto": "0.0.15-ff9c430.0",
"@waku/utils": "0.0.28-79dfb35.0", "@waku/utils": "0.0.28-ff9c430.0",
"chai": "^5.1.2", "chai": "^5.1.2",
"lodash": "^4.17.21" "lodash": "^4.17.21"
}, },
@ -5866,13 +5866,13 @@
} }
}, },
"node_modules/@waku/utils": { "node_modules/@waku/utils": {
"version": "0.0.28-79dfb35.0", "version": "0.0.28-ff9c430.0",
"resolved": "https://registry.npmjs.org/@waku/utils/-/utils-0.0.28-79dfb35.0.tgz", "resolved": "https://registry.npmjs.org/@waku/utils/-/utils-0.0.28-ff9c430.0.tgz",
"integrity": "sha512-wwNg+qGI5MmoT+DD+1+AUM6SMJvOgqcXawVVlXc83UMgWgU44YshBdfrhsxv/CPUfIN2l6i39uU6zhDN5INT4A==", "integrity": "sha512-6tBSQ/X+vzoLV3R573c80XLESZq4qWWSlyXtG4se/+RanQU1om9cSkAzrAlm9ZhO6IcrpLlNgeOsv/dIUIz+Fw==",
"license": "MIT OR Apache-2.0", "license": "MIT OR Apache-2.0",
"dependencies": { "dependencies": {
"@noble/hashes": "^1.3.2", "@noble/hashes": "^1.3.2",
"@waku/interfaces": "0.0.35-79dfb35.0", "@waku/interfaces": "0.0.35-ff9c430.0",
"chai": "^4.3.10", "chai": "^4.3.10",
"debug": "^4.3.4", "debug": "^4.3.4",
"uint8arrays": "^5.0.1" "uint8arrays": "^5.0.1"
@ -14409,9 +14409,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/quick-lru": { "node_modules/quick-lru": {
"version": "7.2.0", "version": "7.3.0",
"resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-7.2.0.tgz", "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-7.3.0.tgz",
"integrity": "sha512-fG4L8TlD1CacJiGMGPxM1/K8l/GaKL2eFQZ6DWAjxZYxSf07DkumbC/Mhh+u/NHvxkfQVL25By0pxBS8QE9ZrQ==", "integrity": "sha512-k9lSsjl36EJdK7I06v7APZCbyGT2vMTsYSRX1Q2nbYmnkBqgUhRkAuzH08Ciotteu/PLJmIF2+tti7o3C/ts2g==",
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">=18" "node": ">=18"
@ -17980,7 +17980,7 @@
"@reown/appkit-adapter-wagmi": "^1.7.17", "@reown/appkit-adapter-wagmi": "^1.7.17",
"@reown/appkit-common": "^1.7.17", "@reown/appkit-common": "^1.7.17",
"@reown/appkit-controllers": "^1.7.17", "@reown/appkit-controllers": "^1.7.17",
"@waku/sdk": "^0.0.36-79dfb35.0", "@waku/sdk": "0.0.36-ff9c430.0",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"ordiscan": "^1.3.0", "ordiscan": "^1.3.0",
"tailwind-merge": "^2.5.2", "tailwind-merge": "^2.5.2",
@ -18006,9 +18006,9 @@
}, },
"packages/react": { "packages/react": {
"name": "@opchan/react", "name": "@opchan/react",
"version": "1.0.2", "version": "1.1.0",
"dependencies": { "dependencies": {
"@opchan/core": "^1.0.0" "@opchan/core": "file:../core"
}, },
"devDependencies": { "devDependencies": {
"@types/react": "^18.2.66", "@types/react": "^18.2.66",

View File

@ -44,7 +44,7 @@
"@reown/appkit-adapter-wagmi": "^1.7.17", "@reown/appkit-adapter-wagmi": "^1.7.17",
"@reown/appkit-common": "^1.7.17", "@reown/appkit-common": "^1.7.17",
"@reown/appkit-controllers": "^1.7.17", "@reown/appkit-controllers": "^1.7.17",
"@waku/sdk": "^0.0.36-79dfb35.0", "@waku/sdk": "0.0.36-ff9c430.0",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"ordiscan": "^1.3.0", "ordiscan": "^1.3.0",
"tailwind-merge": "^2.5.2", "tailwind-merge": "^2.5.2",

View File

@ -135,7 +135,7 @@ export function Connect() {
- Functions: `canModerate(cellId)`, `check(action, cellId?) → { allowed, reason }`, `reasons`. - Functions: `canModerate(cellId)`, `check(action, cellId?) → { allowed, reason }`, `reasons`.
- **`useNetwork()`** → connection state - **`useNetwork()`** → connection state
- Data: `isConnected`, `statusMessage`, `issues`, `canRefresh`. - Data: `isConnected`, `statusMessage`, `issues`, `isHydrated`, `canRefresh`.
- Actions: `refresh()` — triggers a light data refresh via core. - Actions: `refresh()` — triggers a light data refresh via core.
- **`useUIState(key, defaultValue, category?)`** → persisted UI state - **`useUIState(key, defaultValue, category?)`** → persisted UI state

View File

@ -19,6 +19,7 @@ export function useNetwork() {
isConnected: network.isConnected, isConnected: network.isConnected,
statusMessage: network.statusMessage, statusMessage: network.statusMessage,
issues: network.issues, issues: network.issues,
isHydrated: network.isHydrated,
canRefresh: true, canRefresh: true,
refresh, refresh,
} as const; } as const;

View File

@ -78,6 +78,16 @@ export const StoreWiring: React.FC = () => {
} }
} catch (e) { } catch (e) {
console.error('Initial hydrate failed', e); console.error('Initial hydrate failed', e);
} finally {
// Mark hydration as complete regardless of success or failure
// This allows forum actions even when no content is loaded
setOpchanState(prev => ({
...prev,
network: {
...prev.network,
isHydrated: true,
},
}));
} }
}; };

View File

@ -46,6 +46,7 @@ export interface NetworkSlice {
isConnected: boolean; isConnected: boolean;
statusMessage: string; statusMessage: string;
issues: string[]; issues: string[];
isHydrated: boolean;
} }
export interface OpchanState { export interface OpchanState {
@ -85,6 +86,7 @@ const defaultState: OpchanState = {
isConnected: false, isConnected: false,
statusMessage: 'connecting…', statusMessage: 'connecting…',
issues: [], issues: [],
isHydrated: false,
}, },
}; };