Skip to content

Nuxt Recipe

The SDK is framework-agnostic. Keep Vue-specific glue in the consuming app so the SDK stays testable and portable.

Singleton client

ts
// composables/useSimulatorClient.ts
import { 
createSimulatorClient
} from '@my-swu/simulator-client'
import type { SimulatorClient } from '@my-swu/simulator-client' let
simulatorClient
: SimulatorClient | undefined
export function
useSimulatorClient
(): SimulatorClient {
if (
simulatorClient
== null) {
const
config
=
useRuntimeConfig
()
// Keep one client instance per app runtime.
simulatorClient
=
createSimulatorClient
({
baseUrl
:
config
.
public
.
simulatorBaseUrl
})
} return
simulatorClient
}

Expose simulatorBaseUrl via nuxt.config.ts:

ts
export default 
defineNuxtConfig
({
runtimeConfig
: {
public
: {
// Public because browser clients need this origin for HTTP and sockets.
simulatorBaseUrl
: 'http://127.0.0.1:4000',
}, }, })

Reactive match state

ts
// composables/useMatch.ts
import type { 
GameEvent
, GameState, MatchSession } from '@my-swu/simulator-client'
export function
useMatch
() {
const
simulatorClient
=
useSimulatorClient
()
// Store authoritative state and append-only event log separately. const
matchSnapshot
=
ref
<GameState | null>(null)
const
gameEvents
=
ref
<
GameEvent
[]>([])
let
matchSession
: MatchSession | undefined
async function
connect
(
matchId
: string,
seatToken
: string) {
// Seat token is private; pass it only to the socket-owning client.
matchSession
=
simulatorClient
.
session
.
create
({
matchId
,
seatToken
})
await
matchSession
.
connect
()
matchSnapshot
.
value
=
matchSession
.
snapshot
?? null
matchSession
.
on
('snapshot',
nextMatchSnapshot
=> {
// Replace state on each snapshot.
matchSnapshot
.
value
=
nextMatchSnapshot
})
matchSession
.
on
('event',
gameEvent
=> {
// Events drive timeline UI and animations.
gameEvents
.
value
.
push
(
gameEvent
)
}) } // Close sockets when the composable owner unmounts.
onBeforeUnmount
(() =>
matchSession
?.
close
())
return {
connect
,
session
: () =>
matchSession
,
events
:
gameEvents
,
snapshot
:
matchSnapshot
}
}

SSR safety

The SDK uses fetch and WebSocket globals. In Nuxt 3 server contexts:

  • fetch is available natively.
  • WebSocket is not. Guard matchSession.connect() behind a client-only boundary, for example inside onMounted or a <ClientOnly> wrapper.

Released under the MIT License.