refactor: initial restructure of LumeProvider to use kernel api's
This commit is contained in:
parent
3f4c89b3b1
commit
31c5ec8bbe
|
@ -16,6 +16,8 @@
|
||||||
"build-storybook": "storybook build"
|
"build-storybook": "storybook build"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@lumeweb/kernel-network-registry-client": "0.1.0-develop.10",
|
||||||
|
"@lumeweb/libkernel": "0.1.0-develop.65",
|
||||||
"@radix-ui/react-dialog": "^1.0.5",
|
"@radix-ui/react-dialog": "^1.0.5",
|
||||||
"@radix-ui/react-icons": "^1.3.0",
|
"@radix-ui/react-icons": "^1.3.0",
|
||||||
"@radix-ui/react-slot": "^1.0.2",
|
"@radix-ui/react-slot": "^1.0.2",
|
||||||
|
|
5356
pnpm-lock.yaml
5356
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
|
@ -1,62 +1,113 @@
|
||||||
import React, { useContext } from 'react';
|
import {
|
||||||
|
createContext,
|
||||||
|
useCallback,
|
||||||
|
useContext,
|
||||||
|
useEffect,
|
||||||
|
useRef,
|
||||||
|
useState,
|
||||||
|
} from "react";
|
||||||
|
import type { ReactNode } from "react";
|
||||||
|
import { createClient as createNetworkRegistryClient } from "@lumeweb/kernel-network-registry-client";
|
||||||
|
import { createNetworkClient } from "@lumeweb/libkernel/module";
|
||||||
|
|
||||||
type LumeSyncState = 'syncing' | 'done' | 'error'
|
export interface Network extends NetworkStatus {
|
||||||
|
name: string;
|
||||||
|
id: string;
|
||||||
|
type: string;
|
||||||
|
}
|
||||||
|
|
||||||
export type Chain = {
|
interface NetworkStatus {
|
||||||
syncState: LumeSyncState,
|
sync: number;
|
||||||
name: string,
|
peers: number;
|
||||||
chainId: string,
|
ready: boolean;
|
||||||
active: boolean,
|
|
||||||
progress: number, // in porcentage
|
|
||||||
logs: string[],
|
|
||||||
type: 'blockchain' | 'content',
|
|
||||||
peerCount?: number
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type LumeObject = {
|
type LumeObject = {
|
||||||
chains: Chain[],
|
networks: Network[];
|
||||||
activeResolver: 'local' | 'rpc'
|
};
|
||||||
}
|
|
||||||
|
|
||||||
type LumeContext = {
|
type LumeContext = {
|
||||||
lume: LumeObject
|
lume: LumeObject;
|
||||||
}
|
};
|
||||||
|
|
||||||
const LumeContext = React.createContext<LumeContext | undefined>(undefined);
|
const networkRegistry = createNetworkRegistryClient();
|
||||||
|
|
||||||
const LumeProvider = ({ children }: { children: React.ReactNode }) => {
|
const LumeContext = createContext<LumeContext | undefined>(undefined);
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
||||||
const [lume, _setLume] = React.useState<LumeObject>({
|
const LumeProvider = ({ children }: { children: ReactNode }) => {
|
||||||
chains: [
|
const [lume, setLume] = useState<LumeObject>({ networks: [] });
|
||||||
{
|
|
||||||
name: 'Ethereum',
|
// Map to store unsubscribe functions for client.status subscriptions
|
||||||
syncState: 'done',
|
const statusUnsubs = useRef(new Map());
|
||||||
chainId: '1',
|
|
||||||
active: true,
|
const handleStatusUpdate = useCallback(
|
||||||
progress: 100,
|
(id: string, newStatus: NetworkStatus) => {
|
||||||
logs: [],
|
setLume((prevLume) => {
|
||||||
type: 'blockchain'
|
const updatedNetworks = prevLume.networks.map((network) =>
|
||||||
},
|
network.id === id ? { ...network, ...newStatus } : network
|
||||||
{
|
);
|
||||||
name: "IPFS",
|
return { ...prevLume, networks: updatedNetworks };
|
||||||
syncState: 'syncing',
|
});
|
||||||
chainId: '2',
|
},
|
||||||
active: false,
|
[]
|
||||||
progress: 50,
|
);
|
||||||
logs: [],
|
|
||||||
type: 'content',
|
const update = async () => {
|
||||||
peerCount: 3
|
const types = await networkRegistry.getTypes();
|
||||||
|
const newNetworksMap = new Map(); // Use a Map to prevent duplicates based on chainId
|
||||||
|
const newStatusUnsubs = new Map();
|
||||||
|
|
||||||
|
for (const type of types) {
|
||||||
|
const list = await networkRegistry.getNetworksByType(type);
|
||||||
|
|
||||||
|
for (const module of list) {
|
||||||
|
const client = createNetworkClient(module);
|
||||||
|
const name = await client.name();
|
||||||
|
|
||||||
|
const network: Network = {
|
||||||
|
peers: 0,
|
||||||
|
ready: false,
|
||||||
|
sync: 0,
|
||||||
|
type,
|
||||||
|
name,
|
||||||
|
id: module,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Subscribe to status updates
|
||||||
|
const statusUnsub = client.status((newStatus: NetworkStatus) =>
|
||||||
|
handleStatusUpdate(module, newStatus)
|
||||||
|
);
|
||||||
|
newStatusUnsubs.set(module, statusUnsub);
|
||||||
|
|
||||||
|
newNetworksMap.set(module, network); // Store network in map to prevent duplicates
|
||||||
}
|
}
|
||||||
],
|
}
|
||||||
activeResolver: 'local',
|
|
||||||
});
|
|
||||||
|
|
||||||
// Here you can add the logic to update the lume state
|
// Unsubscribe from previous status updates
|
||||||
|
statusUnsubs.current.forEach((unsub) => unsub());
|
||||||
|
// Store new unsubscribe functions
|
||||||
|
statusUnsubs.current = newStatusUnsubs;
|
||||||
|
|
||||||
|
setLume((prevLume) => ({
|
||||||
|
...prevLume,
|
||||||
|
networks: Array.from(newNetworksMap.values()),
|
||||||
|
})); // Convert Map values to array
|
||||||
|
};
|
||||||
|
|
||||||
|
const subDone = networkRegistry.subscribeToUpdates(update);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
update(); // Initial update on component mount
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
subDone(); // Unsubscribe from network registry updates on component unmount
|
||||||
|
// Unsubscribe from all client.status updates
|
||||||
|
statusUnsubs.current.forEach((unsub) => unsub());
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<LumeContext.Provider value={{ lume }}>
|
<LumeContext.Provider value={{ lume }}>{children}</LumeContext.Provider>
|
||||||
{children}
|
|
||||||
</LumeContext.Provider>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -66,9 +117,9 @@ export function useLume() {
|
||||||
const ctx = useContext(LumeContext);
|
const ctx = useContext(LumeContext);
|
||||||
|
|
||||||
if (!ctx) {
|
if (!ctx) {
|
||||||
throw new Error('useLume must be used within a LumeProvider');
|
throw new Error("useLume must be used within a LumeProvider");
|
||||||
}
|
}
|
||||||
|
|
||||||
const { lume } = ctx;
|
const { lume } = ctx;
|
||||||
return lume
|
return lume;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
export { default as LumeProvider, useLume } from './components/lume/LumeProvider';
|
export { default as LumeProvider, useLume } from './components/lume/LumeProvider.tsx';
|
||||||
export { default as LumeDashboard } from './components/lume/LumeDashboard/LumeDashboard';
|
export { default as LumeDashboard } from './components/lume/LumeDashboard/LumeDashboard.tsx';
|
||||||
export { default as LumeIdentity } from './components/lume/LumeIdentity/LumeIdentity';
|
export { default as LumeIdentity } from './components/lume/LumeIdentity/LumeIdentity.tsx';
|
||||||
import "../styles/globals.css";
|
import "../styles/globals.css";
|
||||||
|
|
Loading…
Reference in New Issue