From bab3b24c4840ba198005daea25263235f930f6bb Mon Sep 17 00:00:00 2001 From: avivash Date: Tue, 14 Nov 2023 17:44:02 -0800 Subject: [PATCH] Feat: network events for activity page(will do homepage later) --- package-lock.json | 142 +++++++++++++++++++++++- package.json | 1 + src/components/settings/NodeInfo.svelte | 69 ++++++++++++ src/components/settings/PeerID.svelte | 36 ------ src/lib/health.ts | 32 ++++-- src/lib/network.ts | 98 +++++++++++++++- src/lib/rpc.ts | 22 +++- src/lib/stores.ts | 8 ++ src/routes/activity/+page.svelte | 8 +- src/routes/settings/+page.svelte | 4 +- src/routes/workflows/+page.svelte | 1 + 11 files changed, 356 insertions(+), 65 deletions(-) create mode 100644 src/components/settings/NodeInfo.svelte delete mode 100644 src/components/settings/PeerID.svelte diff --git a/package-lock.json b/package-lock.json index 428696b..04d5e1e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "dependencies": { "@fission-codes/homestar": "^0.6.0", "@oddjs/odd": "0.37.0", + "@open-rpc/client-js": "^1.8.1", "@types/three": "^0.156.0", "chart.js": "^4.4.0", "clipboard-copy": "^4.0.1", @@ -1068,6 +1069,17 @@ "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-9.9.0.tgz", "integrity": "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==" }, + "node_modules/@open-rpc/client-js": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@open-rpc/client-js/-/client-js-1.8.1.tgz", + "integrity": "sha512-vV+Hetl688nY/oWI9IFY0iKDrWuLdYhf7OIKI6U1DcnJV7r4gAgwRJjEr1QVYszUc0gjkHoQJzqevmXMGLyA0g==", + "dependencies": { + "isomorphic-fetch": "^3.0.0", + "isomorphic-ws": "^5.0.0", + "strict-event-emitter-types": "^2.0.0", + "ws": "^7.0.0" + } + }, "node_modules/@playwright/test": { "version": "1.29.2", "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.29.2.tgz", @@ -4429,6 +4441,23 @@ "node": ">= 4" } }, + "node_modules/isomorphic-fetch": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz", + "integrity": "sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==", + "dependencies": { + "node-fetch": "^2.6.1", + "whatwg-fetch": "^3.4.1" + } + }, + "node_modules/isomorphic-ws": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz", + "integrity": "sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==", + "peerDependencies": { + "ws": "*" + } + }, "node_modules/it-all": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/it-all/-/it-all-1.0.6.tgz", @@ -5138,6 +5167,25 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, "node_modules/node-gyp-build": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz", @@ -6240,6 +6288,11 @@ "node": ">=8" } }, + "node_modules/strict-event-emitter-types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strict-event-emitter-types/-/strict-event-emitter-types-2.0.0.tgz", + "integrity": "sha512-Nk/brWYpD85WlOgzw5h173aci0Teyv8YdIAEtV+N88nDB0dLlazZyJMIsN6eo1/AR61l+p6CJTG1JIyFaoNEEA==" + }, "node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", @@ -6824,6 +6877,11 @@ "node": ">=6" } }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, "node_modules/ts-node": { "version": "10.9.1", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", @@ -7141,6 +7199,11 @@ } } }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, "node_modules/well-known-symbols": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/well-known-symbols/-/well-known-symbols-2.0.0.tgz", @@ -7150,6 +7213,20 @@ "node": ">=6" } }, + "node_modules/whatwg-fetch": { + "version": "3.6.19", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.19.tgz", + "integrity": "sha512-d67JP4dHSbm2TrpFj8AbO8DnL1JXL5J9u0Kq2xW6d0TFDbCA3Muhdt8orXC22utleTVj7Prqt82baN6RBvnEgw==" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -7284,7 +7361,6 @@ "version": "7.5.9", "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", - "peer": true, "engines": { "node": ">=8.3.0" }, @@ -8131,6 +8207,17 @@ } } }, + "@open-rpc/client-js": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@open-rpc/client-js/-/client-js-1.8.1.tgz", + "integrity": "sha512-vV+Hetl688nY/oWI9IFY0iKDrWuLdYhf7OIKI6U1DcnJV7r4gAgwRJjEr1QVYszUc0gjkHoQJzqevmXMGLyA0g==", + "requires": { + "isomorphic-fetch": "^3.0.0", + "isomorphic-ws": "^5.0.0", + "strict-event-emitter-types": "^2.0.0", + "ws": "^7.0.0" + } + }, "@playwright/test": { "version": "1.29.2", "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.29.2.tgz", @@ -10532,6 +10619,21 @@ } } }, + "isomorphic-fetch": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz", + "integrity": "sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==", + "requires": { + "node-fetch": "^2.6.1", + "whatwg-fetch": "^3.4.1" + } + }, + "isomorphic-ws": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz", + "integrity": "sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==", + "requires": {} + }, "it-all": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/it-all/-/it-all-1.0.6.tgz", @@ -11050,6 +11152,14 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, + "node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "requires": { + "whatwg-url": "^5.0.0" + } + }, "node-gyp-build": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz", @@ -11781,6 +11891,11 @@ } } }, + "strict-event-emitter-types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strict-event-emitter-types/-/strict-event-emitter-types-2.0.0.tgz", + "integrity": "sha512-Nk/brWYpD85WlOgzw5h173aci0Teyv8YdIAEtV+N88nDB0dLlazZyJMIsN6eo1/AR61l+p6CJTG1JIyFaoNEEA==" + }, "string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", @@ -12177,6 +12292,11 @@ "integrity": "sha512-eM+pCBxXO/njtF7vdFsHuqb+ElbxqtI4r5EAvk6grfAFyJ6IvWlSkfZ5T9ozC6xWw3Fj1fGoSmrl0gUs46JVIw==", "dev": true }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, "ts-node": { "version": "10.9.1", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", @@ -12370,12 +12490,31 @@ "dev": true, "requires": {} }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, "well-known-symbols": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/well-known-symbols/-/well-known-symbols-2.0.0.tgz", "integrity": "sha512-ZMjC3ho+KXo0BfJb7JgtQ5IBuvnShdlACNkKkdsqBmYw3bPAaJfPeYUo6tLUaT5tG/Gkh7xkpBhKRQ9e7pyg9Q==", "dev": true }, + "whatwg-fetch": { + "version": "3.6.19", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.19.tgz", + "integrity": "sha512-d67JP4dHSbm2TrpFj8AbO8DnL1JXL5J9u0Kq2xW6d0TFDbCA3Muhdt8orXC22utleTVj7Prqt82baN6RBvnEgw==" + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -12476,7 +12615,6 @@ "version": "7.5.9", "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", - "peer": true, "requires": {} }, "xtend": { diff --git a/package.json b/package.json index fe73a35..1c12e9c 100644 --- a/package.json +++ b/package.json @@ -59,6 +59,7 @@ "dependencies": { "@fission-codes/homestar": "^0.6.0", "@oddjs/odd": "0.37.0", + "@open-rpc/client-js": "^1.8.1", "@types/three": "^0.156.0", "chart.js": "^4.4.0", "clipboard-copy": "^4.0.1", diff --git a/src/components/settings/NodeInfo.svelte b/src/components/settings/NodeInfo.svelte new file mode 100644 index 0000000..f835da2 --- /dev/null +++ b/src/components/settings/NodeInfo.svelte @@ -0,0 +1,69 @@ + + +{#if health} +
+

Peer ID

+
+

+ {health.nodeInfo.static.peer_id} +

+ +
+
+ +
+

Listener Addresses

+ + {#each health.nodeInfo.dynamic.listeners as listener} +
+

+ {listener} +

+ +
+ {/each} +
+{/if} diff --git a/src/components/settings/PeerID.svelte b/src/components/settings/PeerID.svelte deleted file mode 100644 index 6d572d3..0000000 --- a/src/components/settings/PeerID.svelte +++ /dev/null @@ -1,36 +0,0 @@ - - -{#if health} -
-

Peer ID

-
-

- {health.nodeInfo.peer_id} -

- -
-
-{/if} diff --git a/src/lib/health.ts b/src/lib/health.ts index 7a9a27a..1cfc565 100644 --- a/src/lib/health.ts +++ b/src/lib/health.ts @@ -1,12 +1,20 @@ // import type { InferError } from '@fission-codes/homestar/types' -import { homestar } from '$lib/rpc' +import { + // homestar, + rpcClient +} from '$lib/rpc' -type Metric = { - data: Data[] - help: string - metric_name: string - metric_type: string +type Health = { + healthy: boolean + nodeInfo: { + dynamic: { + listeners: string[] + } + static: { + peer_id: string + } + } } type Data = { @@ -15,13 +23,13 @@ type Data = { value: string } -export const requestHealth = async (): Promise => { +export const requestHealth = async (): Promise => { try { - const { error, result } = await homestar.health() - if (error) { - throw new Error(error) - } - + const result = await rpcClient.request({ method: 'health' }) + // const { error, result } = await homestar.health() + // if (error) { + // throw new Error(error) + // } return result } catch (error) { console.error(error) diff --git a/src/lib/network.ts b/src/lib/network.ts index f6f84e2..e37cf60 100644 --- a/src/lib/network.ts +++ b/src/lib/network.ts @@ -1,14 +1,100 @@ +// import { Homestar } from '@fission-codes/homestar' +// import { WebsocketTransport } from '@fission-codes/homestar/transports/ws.js' +// import { get as getStore } from 'svelte/store' +// import { WebSocket } from 'unws' + +import { networkStore } from '$lib/stores' import { homestar } from '$lib/rpc' +export type NetworkStore = { + loading: boolean + activeConnections: Connection[] + receiptsSent: number + receiptsReceived: number +} + +type Connection = { + address: string + peerId: string + type: string + timestamp: number +} + +const CONN_ESTABLISHED = 'network:connectionEstablished' +const CONN_CLOSED = 'network:connectionClosed' +const RECEIPT_RECEIVED = 'network:receivedReceiptPubsub' +const RECEIPT_SENT = 'network:publishedReceiptPubsub' + +// const homestar2 = new Homestar({ +// transport: new WebsocketTransport('ws://localhost:8070', { +// ws: WebSocket +// }) +// }) + export const subscribNetworkEvents = async (): Promise => { - await homestar.networkEvents(result => { - console.log('result', result) - if (result.error) { - console.error(result.error) - } else { - console.log('result', result) + await homestar.networkEvents(res => { + // console.log('node1 res', res) + if (res.error) { + console.error(res.error) + } + + // Handle connection established + if (res?.result?.type === CONN_ESTABLISHED) { + networkStore.update(state => ({ + ...state, + activeConnections: state.activeConnections.find( + con => con?.peerId === res?.result?.data?.peerId + ) + ? state.activeConnections + : [ + { + address: res?.result?.data?.address, + peerId: res?.result?.data?.peerId, + type: res?.result?.type, + timestamp: res?.result?.timestamp + }, + ...state.activeConnections + ] + })) + } + + // Handle connection closed + if (res?.result?.type === CONN_CLOSED) { + networkStore.update(state => ({ + ...state, + activeConnections: state.activeConnections.find( + con => con?.peerId === res?.result?.data?.peerId + ) + ? state.activeConnections.filter( + con => con?.peerId !== res?.result?.data?.peerId + ) + : state.activeConnections + })) + } + + // Handle receipt sent + if (res?.result?.type === RECEIPT_SENT) { + networkStore.update(state => ({ + ...state, + receiptsSent: state.receiptsSent + 1 + })) + } + + // Handle receipt received + if (res?.result?.type === RECEIPT_RECEIVED) { + networkStore.update(state => ({ + ...state, + receiptsReceived: state.receiptsReceived + 1 + })) } }) + + // await homestar2.networkEvents(result => { + // console.log('node2 result', result) + // if (result.error) { + // console.error(result.error) + // } + // }) } export default subscribNetworkEvents diff --git a/src/lib/rpc.ts b/src/lib/rpc.ts index 9508f7c..d3ab840 100644 --- a/src/lib/rpc.ts +++ b/src/lib/rpc.ts @@ -2,10 +2,26 @@ import { Homestar } from '@fission-codes/homestar' import { WebsocketTransport } from '@fission-codes/homestar/transports/ws.js' import { WebSocket } from 'unws' +import { + RequestManager, + Client, + WebSocketTransport as OpenRPCWebSocketTransport +} from '@open-rpc/client-js' + +const openRPCTransport = new OpenRPCWebSocketTransport( + import.meta.env.VITE_WEBSOCKET_ENDPOINT +) +const requestManager = new RequestManager([openRPCTransport]) +export const rpcClient = new Client(requestManager) + +const transport = new WebsocketTransport( + import.meta.env.VITE_WEBSOCKET_ENDPOINT, + { + ws: WebSocket + } +) // WS export const homestar = new Homestar({ - transport: new WebsocketTransport(import.meta.env.VITE_WEBSOCKET_ENDPOINT, { - ws: WebSocket, - }), + transport, }) /** diff --git a/src/lib/stores.ts b/src/lib/stores.ts index d75a36d..25328d6 100644 --- a/src/lib/stores.ts +++ b/src/lib/stores.ts @@ -12,6 +12,7 @@ import type { ProjectsStore } from '$lib/projects' import projects from '$routes/projects/lib/project-mocks' import type { FunctionsStore } from '$lib/functions' import functions from '$routes/functions/lib/function-mocks' +import type { NetworkStore } from '$lib/network' import type { Run, WorkflowsStore } from '$lib/workflows' import generateBuilderTemplate from '$lib/workflows/builder/builder-template' import workflows from '$routes/workflows/lib/workflow-mocks' @@ -53,4 +54,11 @@ export const workflowsStore: Writable = writable({ workflows }) +export const networkStore: Writable = writable({ + loading: false, + activeConnections: [], + receiptsSent: 0, + receiptsReceived: 0, +}) + export const unsavedRunStore: Writable>> = writable({}) diff --git a/src/routes/activity/+page.svelte b/src/routes/activity/+page.svelte index ccdfb1b..8119951 100644 --- a/src/routes/activity/+page.svelte +++ b/src/routes/activity/+page.svelte @@ -4,7 +4,7 @@ import { STATUS_COLOURS } from '$routes/workflows/lib/graph' import { requestMetrics } from '$lib/metrics' - import { themeStore, workflowsStore } from '$lib/stores' + import { networkStore, themeStore, workflowsStore } from '$lib/stores' import LoadingSpinner from '$components/common/LoadingSpinner.svelte' import ProgressBar from '$routes/activity/components/ProgressBar.svelte' @@ -86,17 +86,17 @@

Active connections

-

0

+

{$networkStore.activeConnections?.length}

Receipts received

-

0

+

{$networkStore.receiptsReceived}

Receipts sent

-

0

+

{$networkStore.receiptsSent}

diff --git a/src/routes/settings/+page.svelte b/src/routes/settings/+page.svelte index 485d834..f1e3530 100644 --- a/src/routes/settings/+page.svelte +++ b/src/routes/settings/+page.svelte @@ -5,7 +5,7 @@ import { sessionStore } from '$lib/stores' // import AvatarUpload from '$components/settings/AvatarUpload.svelte' import ConnectedDevices from '$components/settings/ConnectedDevices.svelte' - import PeerID from '$components/settings/PeerID.svelte' + import NodeInfo from '$components/settings/NodeInfo.svelte' // import RecoveryKit from '$components/settings/RecoveryKit.svelte' import ThemePreferences from '$components/settings/ThemePreferences.svelte' import Username from '$components/settings/Username.svelte' @@ -23,7 +23,7 @@
- + diff --git a/src/routes/workflows/+page.svelte b/src/routes/workflows/+page.svelte index 8d67cfe..41a8ee5 100644 --- a/src/routes/workflows/+page.svelte +++ b/src/routes/workflows/+page.svelte @@ -36,6 +36,7 @@
+
{#each workflows as workflow, i}