Compare commits

..

No commits in common. "8740802bc6fb91e48a85077ff07d7d439380bf9b" and "457092328703b7cc4ec9d1c8b464934e284a75cd" have entirely different histories.

15 changed files with 63 additions and 1997 deletions

View File

@ -1,28 +0,0 @@
async function main() {
const results = await Bun.build({
entrypoints: [ "./frontend/index.js" ],
outdir: "./static/js/",
verbose: true
});
if (!results.success) {
for (const message of results.logs) {
console.error(message);
}
return false;
}
return true;
}
main()
.then(() => {
process.exit(0)
})
.catch((e) => {
console.error(e);
process.exit(1);
});

Binary file not shown.

View File

@ -1,71 +0,0 @@
import m from "mithril";
import { createWebSocket } from "./websocket";
// on new message event, call m.redraw();
const messages = [];
const socket = createWebSocket();
socket.onmessage = function (event) {
if (event.type === "message") {
const message = JSON.parse(event.data);
messages.push(message);
m.redraw();
}
}
function newMessageText(name, message) {
return [
m("span.chatter", name + ": "),
m("span.chatter-message", message)
];
}
const MessageBox = {
view: function () {
return m(".messages", messages.map(function(message) {
return m(".message", newMessageText(message.chatter, message.message));
}));
}
};
function clearMessageBox() {
const messageBox = document.getElementById("message");
messageBox.value = "";
}
function sendMessage(e) {
e.preventDefault();
const form = new FormData(e.target);
const message = {};
for (const [key, value] of form.entries()) {
message[key] = value;
}
socket.send(JSON.stringify(message));
clearMessageBox();
}
const MessageInput = {
view: function () {
return m("div.chat-input", [
m("form", { method: "post", onsubmit: sendMessage }, [
m("input", { name: "chatter", placeholder: "Name" }),
m("input", { name: "message", placeholder: "Message", id: "message", required: true }),
m("input", { type: "submit", value: "Send" })
])
]);
}
};
const Chat = {
view: function(vnode) {
return m("div", [
m(MessageBox),
m(MessageInput)
])
}
};
m.mount(document.getElementById("app"), Chat);

View File

@ -1,14 +0,0 @@
import m from 'mithril';
// login to the server
function login(e) {
}
export const Login = {
return m("form", { action: "/login", method: "post", onsubmit: login }, [
m("label", { for: "username" }, "Username"),
m("input", { type: "text", name: "username" }),
m("input", { type: "submit", value: "Login" })
]);
};

View File

@ -1,2 +0,0 @@
const state = {};

View File

@ -1,3 +0,0 @@
export function createWebSocket() {
return new WebSocket("ws://localhost:3000/chat-service");
}

View File

@ -1,8 +0,0 @@
build:
bun build.ts
clean:
rm -r static/js/*
test:
bun test

View File

@ -1,17 +1,12 @@
{
"name": "chat-app",
"scripts": {
"dev": "bun run --hot src/index.ts",
"build": "rm -r static/js; bun build.ts"
"dev": "bun run --hot src/index.ts"
},
"dependencies": {
"@types/mithril": "^2.2.7",
"hono": "^4.6.3",
"js-cookie": "^3.0.5",
"js-guid": "^1.0.2",
"mithril": "^2.2.5"
"hono": "^4.6.3"
},
"devDependencies": {
"@types/bun": "latest"
}
}
}

View File

@ -8,8 +8,8 @@ export const chatters = new Array<Chatter>();
export type Message = {
message: string,
timestamp: Date,
chatter: string,
timestamp: Date
chatter: Chatter
};
export function createMessageString(message: Message): string {
@ -20,8 +20,7 @@ export class ChatRoom extends EventEmitter {
protected messages: Message[];
public constructor() {
super();
this.messages = new Array<Message>();
this.message = new Array<Message>();
}
public getMessages(): Message[] {
@ -40,11 +39,6 @@ export class ChatRoom extends EventEmitter {
public getNewestMessage(): Message {
const message = this.messages[this.messages - 1];
}
// set up the lifetime to clear messages in memory
protected pruneMessages(lifetime: number): void {
}
}
export const chatRoom = new ChatRoom();
export const chatRomm = new ChatRoom();

View File

@ -4,55 +4,44 @@ import type { ServerWebSocket } from "hono";
import {
chatRoom,
createMessageString,
type Chatter,
type Message
} from "./chat-room.ts";
const app = new Hono();
const users: string[] = [];
// Set up the chat socket
const { upgradeWebSocket, websocket } = createBunWebSocket<ServerWebSocket>();
app.get("/chat-service", upgradeWebSocket((c) => {
app.get("/chat-socket", upgradeWebSocket((c) => {
return {
onOpen(_event, ws) {
chatRoom.addListener('message-added', function (e) {
ws.send(JSON.stringify({
message: e.message.message,
chatter: e.message.chatter,
timestamp: e.message.timestamp
}));
});
},
onMessage(event, ws) {
const { data } = event;
const message = JSON.parse(data);
message.timestamp = Date.now() as string;
const data = JSON.parse(event.data);
if (!chatters.find(c => c.name == data.chatter.name)) {
chatters.push(data.chatter);
}
const message: Message = {
chatter: { data.chatter },
message: data.message,
timestamp: Date.now() as string;
};
chatRoom.addMessage(message);
ws.send(JSON.stringify({ message: createMessageString(message) }));
},
onClose() {
console.log("Connection closed.");
},
onError(event, ws) {
console.error(event);
ws.close();
onError(event) {
console.log(event);
}
}
}));
// set up the username, somehow
// set the session for a user
app.post("/login", async (c) => {
const user = await c.req.parseBody();
let success: boolean = false;
if (!users.find((u) => u == user.username)) {
users.push(user.username);
success = true;
}
return c.json({ success });
});
// get the HTML and JS from the static repo
app.use("/", serveStatic({ path: "/static/index.html" }));
app.use("/*", serveStatic({ root: "/static" }));

View File

@ -1,23 +0,0 @@
.messages .message {
padding: 0.5em;
border: 1px solid #aaa;
border-radius: 5px;
margin-bottom: 0.5em;
}
.chatter {
font-weight: bold;
}
.chat-input > form {
display: flex;
width: 100%;
}
.chat-input > form > input {
padding: 0.7em;
}
.chat-input > form > input[name="chatter"] {
width: 20%;
}
.chat-input > form > input[name="message"] {
width: 75%;
}

View File

@ -2,10 +2,19 @@
<html lang="en">
<head>
<title>A Dumb Chat Application</title>
<link rel="stylesheet" type="text/css" href="/css/main.css" />
</head>
<body>
<div id="app"></div>
<script src="/js/index.js"></script>
<script src="https://unpkg.com/mithril/mithril.js"></script>
<script src="/js/chat-service.js"></script>
<script>
// start the chat web socket
initChatService();
// render the application
const root = document.body;
m.render(root, m("h1", "A Stupid Chat"));
</script>
</body>
</html>

View File

@ -0,0 +1,17 @@
function initChatService() {
const ws = new WebSocket("ws://localhost:3000/chat-socket");
ws.onmessage = function (event) {
console.log(event);
};
ws.onopen = function (event) {
console.log("Opening the socket");
ws.send(JSON.stringify({ hello: "world" }));
};
ws.onclose = function (event) {
console.log("Closing the socket");
};
ws.onerror = function (event) {
console.log(event);
};
}

File diff suppressed because it is too large Load Diff

View File

@ -13,23 +13,17 @@ Deploy the talk on the blog as well
## The Dumb Idea
A simple Chat application built with Hono and Mithril.js
Simple application that does something, like a guess the number or tik-tak-toe
Something with a frontend and backend to talk about deploying multiple applications.
Or build it with React
## Talk About the History
A simple twitte clone
Mesages on a timeline, living in memory.
What was my first deployment?
Multiplayer tic-tac-toe?
Chat?
Using the file manager in cPanel.
Then using SVN on the server.
Upgrading to Git, on the server.
A lot WHM
Developing with Vagrant and virtual machines
Moving to AWS, EC2
Using VPS providers like DigitalOcean
Building Container images
## What is Deployment
@ -47,7 +41,7 @@ show some diagrams
Talk about the SSL cert situation
Talk about building VM images or containers for deployment
"What about K8s?" I don't know or really care, honestly
"What about K8s?" I don't know or really care
## What does Dokku do for us?