Skip to content
This repository has been archived by the owner on Nov 10, 2022. It is now read-only.

Commit

Permalink
feat: add a shared state as a server.io property
Browse files Browse the repository at this point in the history
and send it to the new connected clients
  • Loading branch information
severo committed Jan 22, 2020
1 parent 4b5011b commit c1af81c
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 4 deletions.
29 changes: 27 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
},
"dependencies": {
"@hapi/joi": "^17.1.0",
"automerge": "^0.12.1",
"express": "^4.17.1",
"nanoid": "^2.1.9",
"randomcolor": "^0.5.4",
Expand Down
1 change: 1 addition & 0 deletions src/domain/events/toclient/event.to.client.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export class EventToClient {
// static readonly RoomGuestsList = 'room-guests-list'

static readonly State = 'state'
static readonly UsersList = 'users-list'

static readonly InternalServerError = 'internal-server-error'
Expand Down
1 change: 1 addition & 0 deletions src/domain/events/toclient/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// export * from "./room.guests.list.event";

export * from './state.event'
export * from './users.list.event'

export * from './internal.server.error.event'
15 changes: 14 additions & 1 deletion src/socket.io/socket.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
UpdateUserNameEvent,
UpdateUserColorEvent,
} from '../domain/events/toserver'
import { UsersListEvent } from '../domain/events/toclient'
import { StateEvent, UsersListEvent } from '../domain/events/toclient'
import { ExportedUser } from '../domain'

const socketUrl: string = 'http://localhost:5000'
Expand Down Expand Up @@ -92,6 +92,19 @@ describe('Server', () => {
// after
newClient.disconnect()
})
it('should send an empty state to a new user meanwhile the state has not been changed', async () => {
// arrange
const getStateEvent = (): Promise<object> =>
new Promise(resolve =>
passiveClient.on(StateEvent.eventName, resolve)
)

// act
const state = await getStateEvent()

// assert
expect(state).to.deep.equal({})
})
})

describe('update-user-name', () => {
Expand Down
18 changes: 17 additions & 1 deletion src/socket.io/socket.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import Automerge from 'automerge'
import { Constants } from './constants'
import { Guard, ConsoleLogger } from '../shared/index'
import {
ConnectionEvent,
UpdateUserNameEvent,
UpdateUserColorEvent,
} from '../domain/events/toserver'
import { UsersListEvent } from '../domain/events/toclient'
import { StateEvent, UsersListEvent } from '../domain/events/toclient'
import { ExportedUser, User } from '../domain'

class Socket {
private users: Map<SocketIOClient.Socket['id'], User> = new Map()
private state = Automerge.init()

constructor(private io: SocketIO.Server, private log = new ConsoleLogger()) {}

Expand All @@ -22,6 +24,7 @@ class Socket {
// connections
const socketUser: User = this.createUser(socket.id)
this.emitUsersListToAll()
this.emitStateToUser(socket)

socket.on(
UpdateUserNameEvent.eventName,
Expand Down Expand Up @@ -169,6 +172,19 @@ class Socket {
return [...this.users.values()].map(user => user.export())
}

private emitStateToUser(socket: SocketIOClient.Socket) {
const stateEvent = new StateEvent(this.stateAsJson)
socket.emit(StateEvent.eventName, stateEvent.state)
}

// TODO: maybe the return type should be "any" as for the JOSN.parse function
// https://github.com/MazeChaZer/TypeScript/blob/master/src/lib/es5.d.ts#L966
private get stateAsJson(): object {
// No need to send the metadata, that could be heavy
// This means that the history is not included
return JSON.parse(JSON.stringify(this.state))
}

private toException = (error: Error): Exception => {
return {
message: error.message,
Expand Down

0 comments on commit c1af81c

Please sign in to comment.