From 149a7d47394aeaf6b109eced541a8330ce9928be Mon Sep 17 00:00:00 2001
From: Magnus Madsen
Date: Wed, 25 Mar 2026 07:22:42 +0100
Subject: [PATCH] refactor: remove unused websocket playground, replace with
code example
Remove the websocket connection to evaluator.flix.dev and the Codebox
playground component, which were no longer in use. Replace with a static
InlineEditor snippet showcasing Flix HTTP middleware composition.
- Delete Codebox.jsx, Editor.jsx
- Remove reconnecting-websocket dependency
- Strip websocket setup and state from App.jsx
- Remove .editor-output CSS rules
- Add Flix HTTP middleware example to Home page
Co-Authored-By: Claude Opus 4.6 (1M context)
---
package-lock.json | 13 +------
package.json | 3 +-
src/App.css | 12 ------
src/App.jsx | 57 +--------------------------
src/page/Home.jsx | 37 ++++++++++++++++--
src/util/Codebox.jsx | 92 --------------------------------------------
src/util/Editor.jsx | 22 -----------
7 files changed, 37 insertions(+), 199 deletions(-)
delete mode 100644 src/util/Codebox.jsx
delete mode 100644 src/util/Editor.jsx
diff --git a/package-lock.json b/package-lock.json
index 58f4c06..ad0f457 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -16,8 +16,7 @@
"react-router": "^7.13.2",
"react-router-dom": "^7.13.2",
"react-spinners": "^0.17.0",
- "reactstrap": "^9.2.3",
- "reconnecting-websocket": "^4.4.0"
+ "reactstrap": "^9.2.3"
},
"devDependencies": {
"@vitejs/plugin-react": "^6.0.1",
@@ -998,11 +997,6 @@
"react-dom": "^16.8.0 || ^17 || ^18"
}
},
- "node_modules/reconnecting-websocket": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/reconnecting-websocket/-/reconnecting-websocket-4.4.0.tgz",
- "integrity": "sha512-D2E33ceRPga0NvTDhJmphEgJ7FUYF0v4lr1ki0csq06OdlxKfugGzN0dSkxM/NfqCxYELK4KcaTOUOjTV6Dcng=="
- },
"node_modules/regenerator-runtime": {
"version": "0.13.11",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
@@ -1763,11 +1757,6 @@
}
}
},
- "reconnecting-websocket": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/reconnecting-websocket/-/reconnecting-websocket-4.4.0.tgz",
- "integrity": "sha512-D2E33ceRPga0NvTDhJmphEgJ7FUYF0v4lr1ki0csq06OdlxKfugGzN0dSkxM/NfqCxYELK4KcaTOUOjTV6Dcng=="
- },
"regenerator-runtime": {
"version": "0.13.11",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
diff --git a/package.json b/package.json
index 28a7359..786d9a9 100644
--- a/package.json
+++ b/package.json
@@ -11,8 +11,7 @@
"react-router": "^7.13.2",
"react-router-dom": "^7.13.2",
"react-spinners": "^0.17.0",
- "reactstrap": "^9.2.3",
- "reconnecting-websocket": "^4.4.0"
+ "reactstrap": "^9.2.3"
},
"scripts": {
"build-script": "node build-scripts/main.mjs",
diff --git a/src/App.css b/src/App.css
index e592428..5d94835 100644
--- a/src/App.css
+++ b/src/App.css
@@ -41,18 +41,6 @@ p:last-child {
font-size: 1.35rem;
}
-.editor-output h5 {
- font-size: 1.1rem;
- color: gray;
- text-align: center;
- padding-bottom: 0.5rem;
- border-bottom: 1px solid #b7b7b7;
-}
-
-.editor-output pre {
- font-family: monospace;
-}
-
.inline-editor-frame {
margin-top: 1em;
margin-bottom: 1.5em;
diff --git a/src/App.jsx b/src/App.jsx
index 4043cd6..569798b 100644
--- a/src/App.jsx
+++ b/src/App.jsx
@@ -1,4 +1,3 @@
-import { useState, useEffect, useRef, useCallback } from 'react';
import './App.css';
import Home from "./page/Home";
@@ -12,64 +11,10 @@ import { Container, Navbar, Nav, NavItem, NavLink, Row } from 'reactstrap';
import { Route, Routes } from "react-router";
import { Link } from "react-router-dom";
-import ReconnectingWebSocket from 'reconnecting-websocket';
import Blog from "./page/Blog";
import Internships from "./page/Internships";
-const SocketAddress = 'wss://evaluator.flix.dev/ws';
-
function App() {
- const [connected, setConnected] = useState(false);
- const websocketRef = useRef(null);
-
- useEffect(() => {
- console.log("Connecting to: " + SocketAddress);
-
- let options = {
- connectionTimeout: 2500
- };
-
- const ws = new ReconnectingWebSocket(SocketAddress, [], options);
-
- ws.addEventListener("open", () => {
- console.log("Connected to: " + SocketAddress);
- setConnected(true);
- });
- ws.addEventListener("close", event => {
- console.log("Disconnected from: " + SocketAddress);
- console.log(event);
- setConnected(false);
- });
- ws.addEventListener("error", event => {
- console.log("Disconnected from: " + SocketAddress);
- console.log(event);
- setConnected(false);
- });
-
- websocketRef.current = ws;
-
- return () => {
- ws.close();
- };
- }, []);
-
- const runProgram = useCallback((src, callback) => {
- if (!connected) {
- console.log("Not connected yet");
- return;
- }
-
- websocketRef.current.onmessage = event => {
- console.log("Received reply from: " + SocketAddress);
- const data = JSON.parse(event.data);
-
- console.log(data);
- callback(data);
- };
-
- websocketRef.current.send(JSON.stringify({ src }));
- }, [connected]);
-
return (
@@ -114,7 +59,7 @@ function App() {
- } />
+ } />
} />
} />
} />
diff --git a/src/page/Home.jsx b/src/page/Home.jsx
index f2388ff..be0d88a 100644
--- a/src/page/Home.jsx
+++ b/src/page/Home.jsx
@@ -10,7 +10,6 @@ import {
Row,
UncontrolledCarousel
} from 'reactstrap';
-import Codebox from "../util/Codebox";
import InlineEditor from "../util/InlineEditor";
const carousel = [
@@ -36,7 +35,7 @@ const carousel = [
}
];
-function Home({ flix }) {
+function Home() {
useEffect(() => {
document.title = "The Flix Programming Language";
}, []);
@@ -88,7 +87,39 @@ function Home({ flix }) {
-
+ {`/// Demonstrates composing multiple HTTP middleware
+/// via \`with\` clauses. Stacks base URL, default
+/// headers, retry, circuit breaker, and logging.
+/// Each \`with\` wraps the
+/// preceding block. The \`Http\` and \`Logger\` effects
+/// propagate to \`main\` and are handled automatically
+/// via their default handlers. Relative paths are
+/// resolved against the base URL; absolute URLs
+/// bypass it.
+def main(): Unit \\ { Clock, Http, Logger, IO } =
+ let defaultHeaders = Map#{
+ "Accept" => List#{"application/json"},
+ "Authorization" => List#{"Bearer tok123"}
+ };
+ run {
+ let urls = List#{"/api/users", "/api/posts"};
+ foreach (url <- urls) {
+ match Http.get(url) {
+ case Ok(res) => println("\${url} -> \${status(res)}")
+ case Err(err) => println("\${url} -> \${err}")
+ }
+ };
+ match Http.get("https://notfound.flix.dev/") {
+ case Ok(res) => println("notfound -> \${status(res)}")
+ case Err(err) => println("notfound -> \${err}")
+ }
+ } with Http.withBaseUrl("https://flix.dev")
+ with Http.withDefaultHeaders(defaultHeaders)
+ with Http.withRetry(
+ Retry.linear(maxRetries = 2, delay = milliseconds(100)))
+ with Http.withCircuitBreaker(
+ failureThreshold = 3, cooldown = seconds(5))
+ with Http.withLogging`}
diff --git a/src/util/Codebox.jsx b/src/util/Codebox.jsx
deleted file mode 100644
index 4fcc928..0000000
--- a/src/util/Codebox.jsx
+++ /dev/null
@@ -1,92 +0,0 @@
-import { useState } from "react";
-import SamplesData from "../data/Samples";
-import Editor from "./Editor";
-import {
- Button, Col, Container, InputGroup, Row
-} from "reactstrap";
-import { FaExternalLinkAlt } from 'react-icons/fa';
-import PulseLoader from 'react-spinners/PulseLoader';
-
-function getRandomInt(max) {
- return Math.floor(Math.random() * Math.floor(max));
-}
-
-function Codebox({ flix }) {
- const [initialChoice] = useState(() => getRandomInt(SamplesData.length));
- const [choice, setChoice] = useState(initialChoice);
- const [input, setInput] = useState(SamplesData[initialChoice].code);
- const [output, setOutput] = useState(undefined);
-
- function onDropdownChoice(event) {
- let newChoice = Number(event.target.value);
- setChoice(newChoice);
- setInput(SamplesData[newChoice].code);
- setOutput(undefined);
- }
-
- function onRunClick() {
- setOutput(null);
- flix.run(input, data => setOutput(data));
- }
-
- function getRunButton() {
- return
- ;
- }
-
- function getDropDown() {
- return
- }
-
- function getEditor() {
- return
- }
-
- function getOutput() {
- if (output === undefined) {
- return undefined;
- } else if (output === null) {
- return
-
-
-
-
- } else {
- return (
-
- Standard Output
- {output.result}
- );
- }
- }
-
- return (
-
-
- {getDropDown()}
- {getRunButton()}
-
- {getEditor()}
- {getOutput()}
-
- );
-}
-
-export default Codebox;
diff --git a/src/util/Editor.jsx b/src/util/Editor.jsx
deleted file mode 100644
index 1f7d539..0000000
--- a/src/util/Editor.jsx
+++ /dev/null
@@ -1,22 +0,0 @@
-import AceEditor from 'react-ace'
-
-import 'ace-builds/src-noconflict/mode-flix'
-import 'ace-builds/src-noconflict/theme-chrome'
-
-function Editor({ code, notifyTextChanged }) {
- return (
-
- )
-}
-
-export default Editor