Aller au contenu

@platform/socket

Location: modules/platform/socket/
Dependencies: @platform/core

Overview

@platform/socket provides the WebSocket transport layer of the platform using Socket.io. It handles:

  • Setting up the Socket.io server on the Express http server.
  • The ServerService registry — a central map of services that can be called over the socket.
  • The client-side SocketContext — connects a Socket.io client instance and exposes it to React components.
  • The useService hook — a Proxy-based RPC client that calls server services transparently.

Note: The pub/sub layer (publications, subscriptions, SubscriptionContext) lives in @platform/schema, not in this module.

Contexts

Context Entry point Contents
client src/client/index.ts SocketContext, useSocketContext, useService
server src/server/index.ts SocketServerModule, ServerService
common src/common/index.ts Service type

Common API

import type { Service } from '@platform/socket/common'
Export Description
Service<Name> Base interface for a named service: { name: Name }. Services extend this and add methods.

Server API

import { SocketServerModule, ServerService } from '@platform/socket/server'

SocketServerModule

Attaches Socket.io to the Express http.Server from ServerExpressService. Listens for incoming 'service' events and delegates to ServerService.handleServiceCall.

// Automatically initialized when imported. No setup needed.
import '@platform/socket/server'

The socket protocol for RPC calls is:

Client → Server:  socket.emit('service', name, method, args[])
Server → Client:  callback({ result }) or callback({ __error: CoreError })

ServerService

The central service registry on the server.

Method Signature Description
register(name, service) (name: string, service: Service) => void Register a service implementation by name
get(name) (name: string) => Service Retrieve a registered service
handleServiceCall(name, method, args, socket, callback) Dispatches an incoming socket call to the correct service method
import { ServerService } from '@platform/socket/server'

const myService = {
  name: 'myModule',
  getData: async (id: string) => {
    return await MyRepository.findById(id)
  }
}

ServerService.register('myModule', myService)

Client API

import { SocketContext, useSocketContext, useService } from '@platform/socket/client'

SocketContext

React context provider that creates and manages the Socket.io client connection.

// Wrap your app (already done by Application in @platform/core)
<SocketContext>
  <App />
</SocketContext>

useSocketContext

const { state: { socket, connected } } = useSocketContext()
Field Type Description
socket Socket The Socket.io client instance
connected boolean Whether the socket is currently connected

useService

Proxy-based RPC hook. Returns a service object whose methods call the matching server service method over the socket.

import { useService } from '@platform/socket/client'
import type { MyService } from '@myModule/common'

function MyComponent() {
  const myService = useService<MyService>('myModule')

  const handleClick = async () => {
    const data = await myService.getData('123')
    console.log(data)
  }
}

Errors thrown by the server (wrapped in CoreError) are re-thrown on the client.

Usage Example

// Server — define and register a service
import { ServerService } from '@platform/socket/server'
import type { Service } from '@platform/socket/common'

type NoteService = Service<'notes'> & {
  getAll(): Promise<Note[]>
  create(note: Omit<Note, '_id'>): Promise<Note>
}

const noteService: NoteService = {
  name: 'notes',
  getAll: async () => NoteRepo.findAll(),
  create: async (note) => NoteRepo.insert(note)
}

ServerService.register('notes', noteService)

// Client — call the service
import { useService } from '@platform/socket/client'

function NoteList() {
  const noteService = useService<NoteService>('notes')
  const [notes, setNotes] = useState<Note[]>([])

  useEffect(() => {
    noteService.getAll().then(setNotes)
  }, [])

  return <ul>{notes.map(n => <li key={n._id}>{n.title}</li>)}</ul>
}