Files
wren/example/web_chat_demo.wren
T
retoor 5a4054ec66 feat: add example scripts for argparse, bytes, dataset, html, markdown, uuid, wdantic, and web chat modules
Add comprehensive demo scripts showcasing the usage of multiple Wren modules including argument parsing, byte manipulation, in-memory dataset operations, HTML encoding/slugification, markdown-to-HTML conversion, UUID generation/validation, schema validation with wdantic, and a full web chat application with REST endpoints.
2026-01-24 22:40:22 +00:00

123 lines
3.4 KiB
JavaScript
Vendored

// retoor <retoor@molodetz.nl>
import "web" for Application, Response, View
import "wdantic" for Schema, Field
import "dataset" for Dataset
import "uuid" for Uuid
import "json" for Json
var db = Dataset.memory()
var messages = db["messages"]
var messageSchema = Schema.new({
"username": Field.string({"minLength": 1, "maxLength": 50}),
"content": Field.string({"minLength": 1, "maxLength": 500})
})
class MessagesView is View {
get(request) {
var allMessages = messages.all()
return Response.json(allMessages)
}
post(request) {
var data = request.json
var result = messageSchema.validate(data)
if (!result.isValid) {
var r = Response.json({"error": "Validation failed", "details": result.errors.map { |e| e.toString }.toList})
r.status = 400
return r
}
var msg = messages.insert({
"username": data["username"],
"content": data["content"]
})
return Response.json(msg)
}
}
class MessageView is View {
get(request) {
var id = request.params["id"]
var msg = messages.findOne({"uid": id})
if (msg == null) {
var r = Response.json({"error": "Message not found"})
r.status = 404
return r
}
return Response.json(msg)
}
delete(request) {
var id = request.params["id"]
var deleted = messages.delete(id)
if (!deleted) {
var r = Response.json({"error": "Message not found"})
r.status = 404
return r
}
return Response.json({"status": "deleted"})
}
}
var indexHtml = "<!DOCTYPE html>
<html>
<head>
<title>Chat Demo</title>
<style>
body { font-family: sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; }
#messages { border: 1px solid #ccc; padding: 10px; height: 300px; overflow-y: auto; margin-bottom: 10px; }
.message { margin: 5px 0; padding: 5px; background: #f5f5f5; }
.message .username { font-weight: bold; }
form { display: flex; gap: 10px; }
input, button { padding: 8px; }
input[name=content] { flex: 1; }
</style>
</head>
<body>
<h1>Chat Demo</h1>
<div id=\"messages\"></div>
<form id=\"form\">
<input name=\"username\" placeholder=\"Username\" required>
<input name=\"content\" placeholder=\"Message\" required>
<button type=\"submit\">Send</button>
</form>
<script>
async function loadMessages() {
const res = await fetch('/api/messages');
const msgs = await res.json();
const div = document.getElementById('messages');
div.innerHTML = msgs.map(m =>
'<div class=\"message\"><span class=\"username\">' + m.username + ':</span> ' + m.content + '</div>'
).join('');
div.scrollTop = div.scrollHeight;
}
document.getElementById('form').onsubmit = async (e) => {
e.preventDefault();
const form = e.target;
await fetch('/api/messages', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
username: form.username.value,
content: form.content.value
})
});
form.content.value = '';
loadMessages();
};
loadMessages();
setInterval(loadMessages, 3000);
</script>
</body>
</html>"
var app = Application.new()
app.get("/", Fn.new { |req| Response.html(indexHtml) })
app.addView("/api/messages", MessagesView)
app.addView("/api/messages/:id", MessageView)
System.print("Chat demo running on http://localhost:8080")
app.run("0.0.0.0", 8080)