diff --git a/party/src/index.ts b/party/src/index.ts index b6424cf..bc9ec75 100644 --- a/party/src/index.ts +++ b/party/src/index.ts @@ -1,5 +1,5 @@ import type * as Party from "partykit/server"; -import type { Connection, MaybeUserDetails, RemoveMessage, SyncMessage, UpdateMessage, UserDetails } from "./types"; +import type { Connection, Cursor, Event, MaybeUserDetails, RemoveMessage, SyncMessage, UpdateMessage, UpdateUserDetailsBody, UserDetails } from "./types"; export default class Server implements Party.Server { constructor(readonly room: Party.Room) { } @@ -27,40 +27,68 @@ export default class Server implements Party.Server { onMessage(message: string, sender: Connection) { console.log(`onMessage: ${sender.id} sent message: ${message}`); - const data = JSON.parse(message) + const data = JSON.parse(message) as UpdateUserDetailsBody - const userDetails = { - id: sender.id, - x: data.x, - y: data.y, - cursor: data.cursor, - spent: data.spent, - lastUpdate: Date.now() - } - - this.updateDetails(sender, userDetails) + const details = this.updateDetails(sender, data) - const msg = userDetails.x && userDetails.y ? { + const msg = { type: 'update', - details: userDetails - } : ({ type: 'remove', id: sender.id, }) + details: details + } this.room.broadcast(JSON.stringify(msg), [sender.id]) } - updateDetails(connection: Connection, details: UserDetails) { - const prevDetails = connection.state + onClose(connection: Party.Connection) { + const message = ({ type: 'remove', id: connection.id, }) + this.room.broadcast(JSON.stringify(message)) + } - const needsNew = prevDetails?.lastUpdate && details.lastUpdate as number - (prevDetails.lastUpdate || 0) > 100 + updateDetails(connection: Connection, body: UpdateUserDetailsBody) { + const prevDetails = connection.state as MaybeUserDetails - if (!prevDetails || needsNew) { - connection.setState(details) + const updatedUserDetails = { + id: connection.id, + spent: body.spent, + cursor: prevDetails?.cursor, + lastEvent: prevDetails?.lastEvent } - } - onClose(connection: Party.Connection) { - const message = ({ type: 'remove', id: connection.id, }) - this.room.broadcast(JSON.stringify(message)) + const prevCursor = prevDetails?.cursor + const needsNewCursor = body.cursor && Date.now() - (prevCursor?.lastUpdate || 0) > 100 + + if (needsNewCursor) { + Object.assign(updatedUserDetails, { + cursor: { + x: body.cursor?.x, + y: body.cursor?.y, + type: body.cursor?.type, + lastUpdate: Date.now() + } as Cursor + }) + } + + const prevLastEvent = prevDetails?.lastEvent + const updateLastEvent = body.event && prevLastEvent?.id !== body.event?.id || prevLastEvent?.type === body.event?.type && body.event?.completed + + if (updateLastEvent) { + Object.assign(updatedUserDetails, { + lastEvent: { + id: (body.event as Event).id, + type: (body.event as Event).type, + completed: (body.event as Event).completed, + image: body.event?.image, + timestamp: Date.now() + } as Event + }) + } + + if (!prevDetails || needsNewCursor || updateLastEvent) { + console.log(`Updating details: ${connection.id} with ${JSON.stringify(updatedUserDetails)}`); + connection.setState(updatedUserDetails) + } + + return updatedUserDetails } } diff --git a/party/src/types/index.ts b/party/src/types/index.ts index 053d231..68008b6 100644 --- a/party/src/types/index.ts +++ b/party/src/types/index.ts @@ -1,19 +1,39 @@ import { type Connection as PartyConnection } from "partykit/server" -type Cursor = { +type CursorType = 'touch' | 'mouse' + +export type Cursor = { x: number y: number - cursor?: 'touch' | 'mouse' + type?: CursorType lastUpdate?: number } +type EventType = 'drop_generating' | 'drop_minting' | 'drop_minted' + +export type Event = { + id: string, + type: EventType + image?: string + completed?: boolean + timestamp: number +} + export type UserDetails = { id: string spent?: number -} & Cursor + cursor?: Cursor + lastEvent?: Event +} export type MaybeUserDetails = UserDetails | null +export type UpdateUserDetailsBody = { + spent?: number + event?: Omit + cursor?: Omit +} + export type UpdateMessage = { type: 'update', details: UserDetails