diff --git a/bun.lockb b/bun.lockb index 85b4fad8f..04430777d 100644 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/packages/website-ue/package.json b/packages/website-ue/package.json index d1dd4b8f1..d93c754b9 100644 --- a/packages/website-ue/package.json +++ b/packages/website-ue/package.json @@ -29,6 +29,7 @@ "@types/semver": "^7.7.0", "@types/three": "^0.160.0", "astro": "^5.8.0", + "diff": "^8.0.2", "ffi-napi": "^4.0.3", "fuzzysort": "^3.1.0", "immer": "^10.1.1", diff --git a/packages/website-ue/src/pages/internal/differ/_index.tsx b/packages/website-ue/src/pages/internal/differ/_index.tsx index d28f4ef61..a015d7ce8 100644 --- a/packages/website-ue/src/pages/internal/differ/_index.tsx +++ b/packages/website-ue/src/pages/internal/differ/_index.tsx @@ -1,7 +1,7 @@ import type { MessageFns } from '@protos/blitz_static_profile_avatar_component'; import type { Any } from '@protos/google/protobuf/any'; import * as protos from '@protos/index'; -import { CommitIcon, ReaderIcon } from '@radix-ui/react-icons'; +import { ArrowBottomRightIcon, CommitIcon } from '@radix-ui/react-icons'; import { Badge, Box, @@ -12,6 +12,7 @@ import { Spinner, Text, } from '@radix-ui/themes'; +import { diffLines, type ChangeObject } from 'diff'; import { MetadataAccessor } from 'packages/core/src'; import type { CatalogItemAccessor } from 'packages/core/src/blitz/catalogItemAccessor'; import { PageWrapper } from 'packages/website-ue/src/components/PageWrapper'; @@ -25,6 +26,7 @@ export function Page({ servers }: { servers: DiscoveryServer[] }) { const [serverB, setSeverB] = useState(undefined); const [loading, setLoading] = useState(false); const [diff, setDiff] = useState(null); + const [isError, setIsError] = useState(false); return ( @@ -52,12 +54,18 @@ export function Page({ servers }: { servers: DiscoveryServer[] }) { size="3" disabled={!serverA || !serverB} onClick={async () => { + setDiff(null); setLoading(true); - const diff = await diffServers(serverA!.addr, serverB!.addr); + try { + const diff = await diffServers(serverA!.addr, serverB!.addr); + setDiff(diff); + } catch (error) { + console.error(error); + setIsError(true); + } setLoading(false); - setDiff(diff); }} > {loading ? : } @@ -83,12 +91,25 @@ export function Page({ servers }: { servers: DiscoveryServer[] }) { + {isError && ( + + There was an error generating the diff, check console + + )} {diff !== null && ( - entry.type !== CatalogItemDiffType.Unmodified, + <> + {diff.length === 0 ? ( + + Branches are identical + + ) : ( + entry.type !== CatalogItemDiffType.Unmodified, + )} + /> )} - /> + )} ); @@ -97,43 +118,33 @@ export function Page({ servers }: { servers: DiscoveryServer[] }) { function DiffDisplay({ diff }: { diff: CatalogDiffEntry[] }) { return ( - {diff.length === 0 && ( - - Branches are identical - - )} - {diff.map((entry) => ( - + {diffEmojis[entry.type]} {entry.name} - + - - {(entry.type === CatalogItemDiffType.Removed || - entry.type === CatalogItemDiffType.Unmodified) && ( - - )} - {entry.type === CatalogItemDiffType.Modified && ( - - )} + {(entry.type === CatalogItemDiffType.Added || entry.type === CatalogItemDiffType.Unmodified) && ( - + )} {entry.type === CatalogItemDiffType.Modified && ( - + <> + + + )} @@ -142,71 +153,132 @@ function DiffDisplay({ diff }: { diff: CatalogDiffEntry[] }) { ); } -function ItemDisplay({ item }: { item: CatalogItemAccessor }) { +function ItemDisplay({ + item, + full, + diff, +}: { + item: CatalogItemAccessor; + full?: boolean; + diff?: CatalogItemAccessor; +}) { const entries = Object.entries(item.components); - protos; - return ( {entries.length === 0 && No components} {entries.map(([key, value]) => ( - + ))} ); } -function ComponentDisplay({ name, value }: { name: string; value: Any }) { - const [code, setCode] = useState(null); +function ComponentDisplay({ + name, + value, + diff, +}: { + name: string; + value: Any; + diff?: Any; +}) { + const [code, setCode] = useState[] | null>( + null, + ); return ( - - + + { + if (code !== null) return setCode(null); + const messageName = value.type_url .slice(2) .split('.') .slice(1) .join('.'); - const json = ( - protos[messageName as keyof typeof protos] as MessageFns - ).decode(value.value); + const Message = protos[ + messageName as keyof typeof protos + ] as MessageFns; + const json = Message.decode(value.value); - setCode(JSON.stringify(json, null, 2)); + if (diff === undefined) { + setCode(JSON.stringify(json, null, 2)); + } else { + const b = JSON.stringify(json, null, 2); + const a = JSON.stringify(Message.decode(diff.value), null, 2); + + setCode(diffLines(a, b)); + } }} > - + - + {name} - {value.value.length.toLocaleString()}B + + {value.value.length.toLocaleString()}B + {code !== null && ( - - {code} - + {typeof code === 'string' ? ( + + ) : ( + code.map((line) => { + const modified = line.added || line.removed; + + return ( + + ); + }) + )} + )} );