global-object-server
Try this
client
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="stylesheet" href="./src/style.css" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Chat on global objects</title>
</head>
<body>
<div id="chats">
<h1>Chats</h1>
<section id="listOfChats">Loading...</section>
</div>
<div id="chat" style="display: none">
<section class="messages">Loading...</section>
<div class="inputSection">
<input class="inputMessage" />
<button class="sendBtn">send</button>
</div>
</div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>
src/main.ts
import { GlobalObject } from 'global-object-client'
import { Chat } from './chat'
interface Chat {
id: string
name: string
}
;(async () => {
const chatsSection = document.querySelector('#chats') as HTMLDivElement
const listOfChats = document.querySelector('#listOfChats') as HTMLDivElement
const chats = await GlobalObject.get<Chat[]>(SERVER_URL + '/chats')
function render() {
if (!Array.isArray(chats)) return
listOfChats.innerHTML = ''
chats.forEach(({ id, name }) => {
const chat = document.createElement('button')
chat.classList.add('chat')
chat.textContent = name
chat.addEventListener('click', () => {
chatsSection.style.display = 'none'
Chat(id)
})
listOfChats.appendChild(chat)
})
}
render()
chats.addEventListener('change', render)
})()
src/chats.ts
import { GlobalObject } from 'global-object-client'
import { SERVER_URL } from './env.json'
interface Message {
author: string
text: string
time: number
}
const userName = localStorage.getItem('userName') || Math.random().toString()
localStorage.setItem('userName', userName)
const messages = document.querySelector('.messages') as HTMLDivElement
const inputMessage = document.querySelector('.inputMessage') as HTMLInputElement
const sendBtn = document.querySelector('.sendBtn') as HTMLButtonElement
const chat = document.querySelector('#chat') as HTMLDivElement
export function Chat(id: string) {
chat.style.display = 'block'
GlobalObject.get<Message[]>(SERVER_URL + `/chat/${id}`).then((gObj) => {
function render() {
if (!Array.isArray(gObj)) return
if (GlobalObject.getState(gObj) !== 'added') return
messages.innerHTML = ''
gObj.forEach(({ text, time, author }) => {
const messageDiv = document.createElement('div')
const messageDivInner = document.createElement('div')
const timeSpan = document.createElement('span')
const textSpan = document.createElement('span')
messageDiv.classList.add('message')
if (author === userName) messageDiv.classList.add('myMessage')
textSpan.classList.add('text')
textSpan.textContent = text
timeSpan.classList.add('time')
const date = new Date(time)
timeSpan.textContent =
date.getHours() +
':' +
(date.getMinutes() < 10 ? '0' : '') +
date.getMinutes()
messageDivInner.appendChild(textSpan)
messageDivInner.appendChild(timeSpan)
messageDiv.appendChild(messageDivInner)
messages.appendChild(messageDiv)
})
}
function sendMassage() {
if (!Array.isArray(gObj) || !inputMessage.value.trim()) return
const message: Message = {
author: userName,
text: inputMessage.value,
time: Date.now(),
}
gObj.push(message)
inputMessage.value = ''
}
render()
gObj.addEventListener('change', render)
gObj.addEventListener('remove', render)
sendBtn.addEventListener('click', sendMassage)
document.addEventListener(
'keypress',
({ key }) => key === 'Enter' && sendMassage()
)
})
}
server
main.ts
import { GlobalObject } from 'global-object-server'
import express from 'express'
import { createServer } from 'node:http'
interface Message {
author: string
text: string
time: number
}
interface Chat {
id: string
name: string
}
const app = express()
app.use(function (_, res, next) {
res.header('Access-Control-Allow-Origin', '*')
res.header('Access-Control-Allow-Headers', 'X-Requested-With')
res.header('Access-Control-Allow-Headers', 'Content-Type')
res.header(
'Access-Control-Allow-Methods',
'PUT, GET, POST, DELETE, OPTIONS'
)
next()
})
const server = createServer(app)
GlobalObject.config.server = server
const chats = GlobalObject.create<Chat[]>([])
for (let i = 1; i <= 10; i++) {
chats[i - 1] = {
name: String(i),
id: String(i),
}
const chat = GlobalObject.create<Message[]>([
{
author: 'Server',
text: `Chat ${i} started`,
time: Date.now(),
},
])
GlobalObject.send(chat, PORT, `/chat/${i}`)
}
GlobalObject.send(chats, PORT, '/chats')