diff --git a/package-lock.json b/package-lock.json
index 74314ac..49016f6 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,6 +9,7 @@
"version": "0.0.1",
"dependencies": {
"@fontsource/fira-mono": "^4.5.0",
+ "@zerodevx/svelte-json-view": "^0.2.1",
"cookie": "^0.4.1",
"highlight.js": "^11.6.0",
"svelte-highlight": "^6.2.1"
@@ -17,8 +18,7 @@
"@sveltejs/adapter-auto": "next",
"@sveltejs/kit": "next",
"@types/cookie": "^0.5.1",
- "@zerodevx/svelte-json-view": "^0.2.1",
- "eslint": "^8.16.0",
+ "eslint": "^8.22.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-svelte3": "^4.0.0",
"prettier": "^2.6.2",
@@ -395,8 +395,7 @@
"node_modules/@zerodevx/svelte-json-view": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/@zerodevx/svelte-json-view/-/svelte-json-view-0.2.1.tgz",
- "integrity": "sha512-yaLojLYTi08vccUKRg/XSRCCPoyzCZqrG+W8mVhJEGiOfFKAmWqNH6b+/il1gG3V1UaEe7amj2mzmo1mo4q1iA==",
- "dev": true
+ "integrity": "sha512-yaLojLYTi08vccUKRg/XSRCCPoyzCZqrG+W8mVhJEGiOfFKAmWqNH6b+/il1gG3V1UaEe7amj2mzmo1mo4q1iA=="
},
"node_modules/abbrev": {
"version": "1.1.1",
@@ -3515,8 +3514,7 @@
"@zerodevx/svelte-json-view": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/@zerodevx/svelte-json-view/-/svelte-json-view-0.2.1.tgz",
- "integrity": "sha512-yaLojLYTi08vccUKRg/XSRCCPoyzCZqrG+W8mVhJEGiOfFKAmWqNH6b+/il1gG3V1UaEe7amj2mzmo1mo4q1iA==",
- "dev": true
+ "integrity": "sha512-yaLojLYTi08vccUKRg/XSRCCPoyzCZqrG+W8mVhJEGiOfFKAmWqNH6b+/il1gG3V1UaEe7amj2mzmo1mo4q1iA=="
},
"abbrev": {
"version": "1.1.1",
diff --git a/package.json b/package.json
index f06807c..a49c17e 100644
--- a/package.json
+++ b/package.json
@@ -1,5 +1,5 @@
{
- "name": "my-app",
+ "name": "kafka-dance-frontend",
"version": "0.0.1",
"scripts": {
"dev": "vite dev",
@@ -15,7 +15,7 @@
"@sveltejs/adapter-auto": "next",
"@sveltejs/kit": "next",
"@types/cookie": "^0.5.1",
- "eslint": "^8.16.0",
+ "eslint": "^8.22.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-svelte3": "^4.0.0",
"prettier": "^2.6.2",
diff --git a/src/app.css b/src/app.css
index e0c17f0..a4cb029 100644
--- a/src/app.css
+++ b/src/app.css
@@ -144,7 +144,8 @@ button {
padding: 1em;
background-color: #e2eaff;
height: 86vh;
- max-width: 70vw;
+ max-width: 65vw;
+ min-width: 65vw;
overflow-y: scroll;
}
diff --git a/src/lib/constants.js b/src/lib/constants.js
index 55854c7..cd1f009 100644
--- a/src/lib/constants.js
+++ b/src/lib/constants.js
@@ -5,4 +5,6 @@ export const queryMode = {
export const backendAddressAndPort = 'localhost:3000'
-export const backendUrl = `http://${backendAddressAndPort}`
\ No newline at end of file
+export const backendUrl = `http://${backendAddressAndPort}`
+
+export const saslAuthMethods = ['PLAIN', 'SCRAM-SHA-256', 'SCRAM-SHA-512', 'AWS']
\ No newline at end of file
diff --git a/src/lib/header/Header.svelte b/src/lib/header/Header.svelte
index aced15c..ee57d05 100644
--- a/src/lib/header/Header.svelte
+++ b/src/lib/header/Header.svelte
@@ -1,6 +1,7 @@
@@ -13,7 +14,16 @@
-
+ {#if testMode}
+
TEST MODE ENABLED
+ {/if}
+
@@ -28,6 +38,7 @@
font-size: 18px;
color: black;
height: 3em;
+ padding: 1em;
}
.corner a {
diff --git a/src/lib/state.js b/src/lib/state.js
index 676a4ae..6c01296 100644
--- a/src/lib/state.js
+++ b/src/lib/state.js
@@ -17,15 +17,15 @@ const mockItems = [
{
"eventType": "Movie",
"broughtToYouBy": "20th Century Fox",
- "title": "Star Wars 2"
+ "title": "Star Wars 2: The Star Warsening, brought to you by the Big Stink Corporation, a division of PepsiCo and somehow also Disney."
},
].map(o => ({ value: o, timestamp: new Date().getTime() }))
-const testMode = false
+export const testMode = true
export const state = writable({
items: [],
itemCount: undefined,
- error: null,
+ error: 'Connecting to WebSocket...',
})
const updateClearError = updater => state.update(s => {
s.error = null
@@ -38,6 +38,7 @@ let disconnected = false
const getRandomFromArray = array => array[Math.floor(Math.random() * array.length)]
+const testTimeout = 200
const testQuery = (mode, jsFilter, queryCode) => {
try {
const f = new Function('message', 'value', queryCode)
@@ -46,16 +47,17 @@ const testQuery = (mode, jsFilter, queryCode) => {
const item = getRandomFromArray(mockItems)
if (!jsFilter || f(item, item.value)) {
item.timestamp = new Date().getTime()
- updateClearError(s => ({ ...s, items: [item, ...s.items].slice(0, itemLimit), itemCount: 0 }))
+ state.update(s => ({ ...s, items: [item, ...s.items].slice(0, itemLimit), itemCount: 0 }))
}
- setTimeout(addItem, 2000)
+ setTimeout(addItem, testTimeout)
}
- setTimeout(addItem, 2000)
+ setTimeout(addItem, testTimeout)
} else {
- updateClearError(s => ({ ...s, items: mockItems.filter(item => !jsFilter || f(item, item.value)), itemCount: 0 }))
+ state.update(s => ({ ...s, items: mockItems.filter(item => !jsFilter || f(item, item.value)), itemCount: 0 }))
}
} catch (e) {
- updateClearError(s => ({ ...s, error: e.toString() }))
+ console.log('Caught an error:', e.toString())
+ state.update(s => ({ ...s, error: e.toString() }))
}
}
@@ -83,16 +85,16 @@ export const query = async ({ cluster, topic, mode, jsFilter, queryCode, maxItem
}
export const connect = () => {
- ws = new WebSocket(`ws://${backendAddressAndPort}`)
+ try {
+ ws = new WebSocket(`ws://${backendAddressAndPort}`)
+ } catch (e) {
+ console.error(e.toString())
+ }
if (!ws) {
updateClearError(s => ({ ...s, error: 'Unable to connect to websocket.' }))
return
}
- ws.addEventListener('close', () => {
- disconnected = true
- })
-
ws.addEventListener('open', () => {
console.log('WebSocket opened')
})
@@ -101,7 +103,6 @@ export const connect = () => {
let data;
try {
data = JSON.parse(message.data)
- console.log('WebSocket message received', data)
switch (data?.type.toLowerCase()) {
case 'complete':
updateClearError(s => ({
@@ -128,6 +129,15 @@ export const connect = () => {
})
ws.addEventListener('close', () => {
- console.log('WebSocket closed')
+ disconnected = true
+ state.update(s => ({ ...s, error: 'WebSocket connection closed.' }))
})
+
+ ws.addEventListener('error', () => {
+ state.update(s => ({ ...s, error: 'WebSocket connection error.' }))
+ })
+
+ if (ws.readyState === ws.CLOSED || ws.readyState === ws.CLOSING) {
+ state.update(s => ({ ...s, error: 'WebSocket connection closed.' }))
+ }
}
diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte
index bbc1a94..e901c83 100644
--- a/src/routes/+page.svelte
+++ b/src/routes/+page.svelte
@@ -2,7 +2,8 @@
import { onMount } from 'svelte'
import { JsonView } from '@zerodevx/svelte-json-view'
import { state, connect, query } from '$lib/state';
- import { queryMode, backendUrl } from "../lib/constants.js";
+ import { queryMode } from "../lib/constants.js";
+ import { apiFetch } from "../utils.js";
let expandAll = true
let showMetadata = true
@@ -24,28 +25,22 @@ return message.value.eventType === "Television";`
let topics = []
let clusters = []
const updateTopics = async () => {
- topics = []
- try {
- const response = await fetch(`${backendUrl}/topics/${querySettings.cluster}`)
- topics = await response.json()
- topics.sort()
- console.log('topics', topics)
- querySettings.topic = topics[0]
- } catch (e) {
- console.log('fetch error:', e.toString())
- }
+ topics = await apiFetch(`/topics/${querySettings.cluster}`)
+ topics ??= []
+ topics.sort()
+ console.log('topics', topics)
+ querySettings.topic = topics[0]
}
onMount(async () => {
connect();
- const response = await fetch(`${backendUrl}/clusters`)
- clusters = Object.keys(await response.json())
+ clusters = Object.keys((await apiFetch('/clusters')) || {})
querySettings.cluster = clusters[0]
await updateTopics()
})
- {querySettings.topic} - Kafka Dance
+ {querySettings.topic ? `${querySettings.topic} - ` : ''}Kafka Dance
diff --git a/src/routes/settings/+page.svelte b/src/routes/settings/+page.svelte
index 3774399..4282d21 100644
--- a/src/routes/settings/+page.svelte
+++ b/src/routes/settings/+page.svelte
@@ -1,6 +1,7 @@