Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,18 @@
// CSS Variable autocomplete
"vunguyentuan.vscode-css-variables",

// Formatter/linter
"biomejs.biome",

// Typescript help
"orta.vscode-twoslash-queries",

// Vue
"Vue.volar",

// Docker (compose) files
"docker.docker"
"docker.docker",

// Formatting and linting
"oxc.oxc-vscode",
"esbenp.prettier-vscode",
"dbaeumer.vscode-eslint"
]
}
17 changes: 7 additions & 10 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,5 @@
{
"cssVariables.lookupFiles": [
"sync3-web/src/syncds.css"
],
"cssVariables.languages": [
"vue",
"vue-html",
"css",
"source.css.styled"
],
"cssVariables.lookupFiles": ["web/src/syncds.css"],
"editor.tabSize": 4,
"editor.indentSize": "tabSize",
"editor.detectIndentation": false,
Expand All @@ -19,4 +11,9 @@
"Dockerfile": "nginx.conf",
"vite.config.ts": "histoire.config.ts"
},
}

"editor.defaultFormatter": "esbenp.prettier-vscode",
"[vue]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
}
6 changes: 5 additions & 1 deletion backend/src/handlers/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,11 @@ export const COMMON_HANDLERS = {
// TODO: Rate limit.

ws.data.user.room.owner?.webSocket?.send(
serializeMsg('playbackReport', { userId: ws.data.user.id, stats: msg.body }),
serializeMsg('playbackReport', {
userId: ws.data.user.id,
stats: msg.body,
timestamp: Date.now(),
}),
)
},
} satisfies Partial<HandlerMap>
6 changes: 4 additions & 2 deletions backend/src/models/Room.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { MediaManager } from '../services/MediaManager.ts'
import { type User } from './User.ts'
import type { ChatMessage, SyncState, WireRoom } from '@sync/wire/types'

const SLUG_REGEX = /^[a-zA-Z0-9-_]{3,64}$/
const SLUG_REGEX = /^[a-zA-Z0-9-_]{1,64}$/

/**
* A representation of a room. It contains websockets
Expand Down Expand Up @@ -184,7 +184,9 @@ export class Room {
name: this.name,
slug: this.slug,
},
users: Array.from(this.users.values()).map((u) => u.toWire()),
users: Array.from(this.users.values())
.filter((x) => x.state !== 'new')
.map((u) => u.toWire()),
ownerId: this._owner?.id ?? '',

chat: this.chat,
Expand Down
3 changes: 3 additions & 0 deletions backend/src/reaper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import type { SyncServer } from './server'
import { RoomManager } from './services/RoomManager'
import { SessionManager } from './services/SessionManager'

// TODO: If this is a performance issue, we can probably track rooms that need to be checked
// (add to a set when created until first user joins or when a user leaves)

export function reap(server: SyncServer) {
const roomsToDestroy = new Set<string>()
const usersToRemove = new Set<User>()
Expand Down
43 changes: 35 additions & 8 deletions backend/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ const app = new Elysia()

return {
roomSlug: r.slug,
sessionID: u.sessionId,
sessionId: u.sessionId,

you: u.toWire(),
}
Expand All @@ -72,6 +72,24 @@ const app = new Elysia()
}),
},
)
.post(
'/room/:roomId/info',
({ params, status }) => {
const room = RoomManager.getRoom(params.roomId)

if (!room) return status(404)

return {
name: room.name,
/* TODO: we could pass the array of users here */
}
},
{
params: t.Object({
roomId: t.String(),
}),
},
)
.post(
'/room/join',
({ body, status }) => {
Expand All @@ -91,7 +109,7 @@ const app = new Elysia()

return {
roomSlug: room.slug,
sessionID: u.sessionId,
sessionId: u.sessionId,

you: u.toWire(),
}
Expand Down Expand Up @@ -164,6 +182,7 @@ export const server = Bun.serve({

console.log(`[${user.room.slug}:${user.displayName}] Open`)

const pstate = user.state
// Set the user as present
user.state = 'present'
user.lastStateChangeTimestamp = Date.now()
Expand All @@ -175,11 +194,13 @@ export const server = Bun.serve({
} else {
server.publish(
user.room.topic,
serializeMsg('userState', {
userId: user.id,
timestamp: Date.now(),
state: 'present',
}),
pstate === 'new'
? serializeMsg('userJoined', user.toWire())
: serializeMsg('userState', {
userId: user.id,
timestamp: Date.now(),
state: 'present',
}),
)
}

Expand Down Expand Up @@ -250,7 +271,11 @@ export const server = Bun.serve({
console.log(`[${user.room.slug}:${user.displayName}] Close: ${code} (${reason})`)

// When setting closedByServer, we don't want to run the normal close logic
if (ws.data.closedByServer) return
if (ws.data.closedByServer) {
ws.data.closedByServer = false // ???
console.log('[WebSocket] Closed by server, skipping close handling')
return
}

if (code === CloseCode.Leave) {
// User intentionally left
Expand All @@ -261,13 +286,15 @@ export const server = Bun.serve({
user.webSocket = undefined

server.publish(user.room.topic, serializeMsg('userLeft', { userId: user.id }))
console.log(`[${user.room.slug}:${user.displayName}] Leave ${code} (${reason})`)

return
}

// User disconnected unexpectedly (or wrongly)
user.state = 'reconnecting'
user.lastStateChangeTimestamp = Date.now()
console.log('[WebSocket] updating userstate')

server.publish(
user.room.topic,
Expand Down
Loading