refactor: initial restructure of LumeProvider to use kernel api's

This commit is contained in:
Derrick Hammer 2023-10-09 01:48:40 -04:00
parent 3f4c89b3b1
commit 31c5ec8bbe
Signed by: pcfreak30
GPG Key ID: C997C339BE476FF2
4 changed files with 5024 additions and 487 deletions

View File

@ -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",

File diff suppressed because it is too large Load Diff

View File

@ -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;
} }

View File

@ -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";