@my-swu/simulator-client 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +355 -0
- package/dist/actionable.d.ts +61 -0
- package/dist/actionable.js +91 -0
- package/dist/client.d.ts +157 -0
- package/dist/client.js +92 -0
- package/dist/connection/handshake.d.ts +30 -0
- package/dist/connection/handshake.js +62 -0
- package/dist/connection/options.d.ts +36 -0
- package/dist/connection/options.js +1 -0
- package/dist/connection/url.d.ts +55 -0
- package/dist/connection/url.js +46 -0
- package/dist/connection/wait.d.ts +22 -0
- package/dist/connection/wait.js +10 -0
- package/dist/connection.d.ts +110 -0
- package/dist/connection.js +358 -0
- package/dist/generated/index.d.ts +121 -0
- package/dist/generated/index.js +1 -0
- package/dist/generated/public-types.d.ts +2 -0
- package/dist/generated/public-types.js +1 -0
- package/dist/generated/schemas.d.ts +27 -0
- package/dist/generated/schemas.js +21264 -0
- package/dist/generated/types/abandon-match-request.d.ts +1 -0
- package/dist/generated/types/abandon-match-request.js +2 -0
- package/dist/generated/types/abandon-match-response.d.ts +1 -0
- package/dist/generated/types/abandon-match-response.js +2 -0
- package/dist/generated/types/add-lobby-ai-player-request.d.ts +1 -0
- package/dist/generated/types/add-lobby-ai-player-request.js +2 -0
- package/dist/generated/types/ai-driver-error-report-list-response.d.ts +1 -0
- package/dist/generated/types/ai-driver-error-report-list-response.js +2 -0
- package/dist/generated/types/ai-driver-error-report-response.d.ts +1 -0
- package/dist/generated/types/ai-driver-error-report-response.js +2 -0
- package/dist/generated/types/api-error-response.d.ts +1 -0
- package/dist/generated/types/api-error-response.js +2 -0
- package/dist/generated/types/card-catalog-refresh-response.d.ts +1 -0
- package/dist/generated/types/card-catalog-refresh-response.js +2 -0
- package/dist/generated/types/cards-response.d.ts +1 -0
- package/dist/generated/types/cards-response.js +2 -0
- package/dist/generated/types/client-message.d.ts +1 -0
- package/dist/generated/types/client-message.js +2 -0
- package/dist/generated/types/close-tournament-room-request.d.ts +1 -0
- package/dist/generated/types/close-tournament-room-request.js +2 -0
- package/dist/generated/types/common.d.ts +5361 -0
- package/dist/generated/types/common.js +2 -0
- package/dist/generated/types/covered-cards-response.d.ts +47 -0
- package/dist/generated/types/covered-cards-response.js +2 -0
- package/dist/generated/types/create-limited-event-request.d.ts +1 -0
- package/dist/generated/types/create-limited-event-request.js +2 -0
- package/dist/generated/types/create-lobby-request.d.ts +1 -0
- package/dist/generated/types/create-lobby-request.js +2 -0
- package/dist/generated/types/create-match-request.d.ts +1 -0
- package/dist/generated/types/create-match-request.js +2 -0
- package/dist/generated/types/create-meta-window-request.d.ts +1 -0
- package/dist/generated/types/create-meta-window-request.js +2 -0
- package/dist/generated/types/create-tournament-room-request.d.ts +1 -0
- package/dist/generated/types/create-tournament-room-request.js +2 -0
- package/dist/generated/types/create-tournament-table-request.d.ts +1 -0
- package/dist/generated/types/create-tournament-table-request.js +2 -0
- package/dist/generated/types/error-payload.d.ts +1 -0
- package/dist/generated/types/error-payload.js +2 -0
- package/dist/generated/types/format-event-request.d.ts +1 -0
- package/dist/generated/types/format-event-request.js +2 -0
- package/dist/generated/types/format-event-response.d.ts +1 -0
- package/dist/generated/types/format-event-response.js +2 -0
- package/dist/generated/types/game-command.d.ts +1 -0
- package/dist/generated/types/game-command.js +2 -0
- package/dist/generated/types/game-event.d.ts +1 -0
- package/dist/generated/types/game-event.js +2 -0
- package/dist/generated/types/game-state.d.ts +1 -0
- package/dist/generated/types/game-state.js +2 -0
- package/dist/generated/types/get-match-response.d.ts +1 -0
- package/dist/generated/types/get-match-response.js +2 -0
- package/dist/generated/types/health-response.d.ts +1 -0
- package/dist/generated/types/health-response.js +2 -0
- package/dist/generated/types/join-limited-event-request.d.ts +1 -0
- package/dist/generated/types/join-limited-event-request.js +2 -0
- package/dist/generated/types/join-lobby-request.d.ts +1 -0
- package/dist/generated/types/join-lobby-request.js +2 -0
- package/dist/generated/types/join-match-request.d.ts +1 -0
- package/dist/generated/types/join-match-request.js +2 -0
- package/dist/generated/types/join-tournament-room-request.d.ts +1 -0
- package/dist/generated/types/join-tournament-room-request.js +2 -0
- package/dist/generated/types/join-tournament-table-request.d.ts +1 -0
- package/dist/generated/types/join-tournament-table-request.js +2 -0
- package/dist/generated/types/kick-lobby-player-request.d.ts +1 -0
- package/dist/generated/types/kick-lobby-player-request.js +2 -0
- package/dist/generated/types/kick-lobby-spectator-request.d.ts +1 -0
- package/dist/generated/types/kick-lobby-spectator-request.js +2 -0
- package/dist/generated/types/leave-lobby-request.d.ts +1 -0
- package/dist/generated/types/leave-lobby-request.js +2 -0
- package/dist/generated/types/leave-match-request.d.ts +1 -0
- package/dist/generated/types/leave-match-request.js +2 -0
- package/dist/generated/types/leave-match-response.d.ts +1 -0
- package/dist/generated/types/leave-match-response.js +2 -0
- package/dist/generated/types/leave-tournament-room-request.d.ts +1 -0
- package/dist/generated/types/leave-tournament-room-request.js +2 -0
- package/dist/generated/types/limited-event-access-response.d.ts +1 -0
- package/dist/generated/types/limited-event-access-response.js +2 -0
- package/dist/generated/types/limited-event-command-request.d.ts +1 -0
- package/dist/generated/types/limited-event-command-request.js +2 -0
- package/dist/generated/types/limited-event-preflight-response.d.ts +1 -0
- package/dist/generated/types/limited-event-preflight-response.js +2 -0
- package/dist/generated/types/limited-event-response.d.ts +1 -0
- package/dist/generated/types/limited-event-response.js +2 -0
- package/dist/generated/types/list-active-ai-matches-request.d.ts +1 -0
- package/dist/generated/types/list-active-ai-matches-request.js +2 -0
- package/dist/generated/types/list-active-ai-matches-response.d.ts +1 -0
- package/dist/generated/types/list-active-ai-matches-response.js +2 -0
- package/dist/generated/types/lobby-access-response.d.ts +1 -0
- package/dist/generated/types/lobby-access-response.js +2 -0
- package/dist/generated/types/lobby-chat-request.d.ts +1 -0
- package/dist/generated/types/lobby-chat-request.js +2 -0
- package/dist/generated/types/lobby-chat-response.d.ts +1 -0
- package/dist/generated/types/lobby-chat-response.js +2 -0
- package/dist/generated/types/lobby-list-response.d.ts +1 -0
- package/dist/generated/types/lobby-list-response.js +2 -0
- package/dist/generated/types/lobby-list-server-message.d.ts +1 -0
- package/dist/generated/types/lobby-list-server-message.js +2 -0
- package/dist/generated/types/lobby-matchmaking-decision-request.d.ts +1 -0
- package/dist/generated/types/lobby-matchmaking-decision-request.js +2 -0
- package/dist/generated/types/lobby-matchmaking-request.d.ts +1 -0
- package/dist/generated/types/lobby-matchmaking-request.js +2 -0
- package/dist/generated/types/lobby-response.d.ts +1 -0
- package/dist/generated/types/lobby-response.js +2 -0
- package/dist/generated/types/lobby-server-message.d.ts +1 -0
- package/dist/generated/types/lobby-server-message.js +2 -0
- package/dist/generated/types/lobby-sync-request.d.ts +1 -0
- package/dist/generated/types/lobby-sync-request.js +2 -0
- package/dist/generated/types/match-access-response.d.ts +1 -0
- package/dist/generated/types/match-access-response.js +2 -0
- package/dist/generated/types/match-chat-lookup-response.d.ts +1 -0
- package/dist/generated/types/match-chat-lookup-response.js +2 -0
- package/dist/generated/types/match-connection-role.d.ts +1 -0
- package/dist/generated/types/match-connection-role.js +2 -0
- package/dist/generated/types/match-history-deck-stats-request.d.ts +1 -0
- package/dist/generated/types/match-history-deck-stats-request.js +2 -0
- package/dist/generated/types/match-history-deck-stats-response.d.ts +1 -0
- package/dist/generated/types/match-history-deck-stats-response.js +2 -0
- package/dist/generated/types/match-history-entry.d.ts +1 -0
- package/dist/generated/types/match-history-entry.js +2 -0
- package/dist/generated/types/match-history-list-request.d.ts +1 -0
- package/dist/generated/types/match-history-list-request.js +2 -0
- package/dist/generated/types/match-history-list-response.d.ts +1 -0
- package/dist/generated/types/match-history-list-response.js +2 -0
- package/dist/generated/types/match-history-replay-request.d.ts +1 -0
- package/dist/generated/types/match-history-replay-request.js +2 -0
- package/dist/generated/types/match-history-replay-response.d.ts +1 -0
- package/dist/generated/types/match-history-replay-response.js +2 -0
- package/dist/generated/types/match-history-restore-request.d.ts +1 -0
- package/dist/generated/types/match-history-restore-request.js +2 -0
- package/dist/generated/types/match-save-payload.d.ts +1 -0
- package/dist/generated/types/match-save-payload.js +2 -0
- package/dist/generated/types/match-spectator-access-response.d.ts +1 -0
- package/dist/generated/types/match-spectator-access-response.js +2 -0
- package/dist/generated/types/meta-window.d.ts +1 -0
- package/dist/generated/types/meta-window.js +2 -0
- package/dist/generated/types/meta-windows-response.d.ts +1 -0
- package/dist/generated/types/meta-windows-response.js +2 -0
- package/dist/generated/types/prepare-lobby-limited-ai-decks-request.d.ts +1 -0
- package/dist/generated/types/prepare-lobby-limited-ai-decks-request.js +2 -0
- package/dist/generated/types/random-lobby-matchmaking-request.d.ts +173 -0
- package/dist/generated/types/random-lobby-matchmaking-request.js +2 -0
- package/dist/generated/types/ranked-admin-status.d.ts +1 -0
- package/dist/generated/types/ranked-admin-status.js +2 -0
- package/dist/generated/types/ranked-leaderboard-entry.d.ts +1 -0
- package/dist/generated/types/ranked-leaderboard-entry.js +2 -0
- package/dist/generated/types/ranked-leaderboard-query.d.ts +1 -0
- package/dist/generated/types/ranked-leaderboard-query.js +2 -0
- package/dist/generated/types/ranked-leaderboard-response.d.ts +1 -0
- package/dist/generated/types/ranked-leaderboard-response.js +2 -0
- package/dist/generated/types/ranked-matchmaking-request.d.ts +137 -0
- package/dist/generated/types/ranked-matchmaking-request.js +2 -0
- package/dist/generated/types/ranked-matchmaking-view.d.ts +1 -0
- package/dist/generated/types/ranked-matchmaking-view.js +2 -0
- package/dist/generated/types/ranked-profile-request.d.ts +1 -0
- package/dist/generated/types/ranked-profile-request.js +2 -0
- package/dist/generated/types/ranked-profile-response.d.ts +1 -0
- package/dist/generated/types/ranked-profile-response.js +2 -0
- package/dist/generated/types/ranked-queue.d.ts +1 -0
- package/dist/generated/types/ranked-queue.js +2 -0
- package/dist/generated/types/ready-tournament-table-request.d.ts +7 -0
- package/dist/generated/types/ready-tournament-table-request.js +2 -0
- package/dist/generated/types/rematch-match-request.d.ts +1 -0
- package/dist/generated/types/rematch-match-request.js +2 -0
- package/dist/generated/types/rematch-match-response.d.ts +1 -0
- package/dist/generated/types/rematch-match-response.js +2 -0
- package/dist/generated/types/resolve-card-ids-request.d.ts +1 -0
- package/dist/generated/types/resolve-card-ids-request.js +2 -0
- package/dist/generated/types/resolve-card-ids-response.d.ts +1 -0
- package/dist/generated/types/resolve-card-ids-response.js +2 -0
- package/dist/generated/types/restore-history-response.d.ts +1 -0
- package/dist/generated/types/restore-history-response.js +2 -0
- package/dist/generated/types/restore-match-save-request.d.ts +1 -0
- package/dist/generated/types/restore-match-save-request.js +2 -0
- package/dist/generated/types/restore-match-save-response.d.ts +1 -0
- package/dist/generated/types/restore-match-save-response.js +2 -0
- package/dist/generated/types/return-lobby-match-request.d.ts +1 -0
- package/dist/generated/types/return-lobby-match-request.js +2 -0
- package/dist/generated/types/return-tournament-match-request.d.ts +1 -0
- package/dist/generated/types/return-tournament-match-request.js +2 -0
- package/dist/generated/types/save-match-request.d.ts +1 -0
- package/dist/generated/types/save-match-request.js +2 -0
- package/dist/generated/types/server-message.d.ts +1 -0
- package/dist/generated/types/server-message.js +2 -0
- package/dist/generated/types/set-ai-paused-request.d.ts +1 -0
- package/dist/generated/types/set-ai-paused-request.js +2 -0
- package/dist/generated/types/set-ai-paused-response.d.ts +1 -0
- package/dist/generated/types/set-ai-paused-response.js +2 -0
- package/dist/generated/types/set-ranked-admission-request.d.ts +1 -0
- package/dist/generated/types/set-ranked-admission-request.js +2 -0
- package/dist/generated/types/set-simulator-maintenance-request.d.ts +1 -0
- package/dist/generated/types/set-simulator-maintenance-request.js +2 -0
- package/dist/generated/types/simulator-admin-status-response.d.ts +1 -0
- package/dist/generated/types/simulator-admin-status-response.js +2 -0
- package/dist/generated/types/simulator-availability-response.d.ts +1 -0
- package/dist/generated/types/simulator-availability-response.js +2 -0
- package/dist/generated/types/simulator-report-list-response.d.ts +1 -0
- package/dist/generated/types/simulator-report-list-response.js +2 -0
- package/dist/generated/types/simulator-report-response.d.ts +1 -0
- package/dist/generated/types/simulator-report-response.js +2 -0
- package/dist/generated/types/spectate-lobby-request.d.ts +1 -0
- package/dist/generated/types/spectate-lobby-request.js +2 -0
- package/dist/generated/types/spectate-match-request.d.ts +1 -0
- package/dist/generated/types/spectate-match-request.js +2 -0
- package/dist/generated/types/start-lobby-limited-match-request.d.ts +1 -0
- package/dist/generated/types/start-lobby-limited-match-request.js +2 -0
- package/dist/generated/types/start-lobby-request.d.ts +1 -0
- package/dist/generated/types/start-lobby-request.js +2 -0
- package/dist/generated/types/start-tournament-event-request.d.ts +1 -0
- package/dist/generated/types/start-tournament-event-request.js +2 -0
- package/dist/generated/types/stats-response.d.ts +5 -0
- package/dist/generated/types/stats-response.js +2 -0
- package/dist/generated/types/submit-lobby-limited-deck-request.d.ts +1 -0
- package/dist/generated/types/submit-lobby-limited-deck-request.js +2 -0
- package/dist/generated/types/submit-match-deck-request.d.ts +1 -0
- package/dist/generated/types/submit-match-deck-request.js +2 -0
- package/dist/generated/types/submit-match-deck-response.d.ts +1 -0
- package/dist/generated/types/submit-match-deck-response.js +2 -0
- package/dist/generated/types/submit-tournament-deck-request.d.ts +1 -0
- package/dist/generated/types/submit-tournament-deck-request.js +2 -0
- package/dist/generated/types/tournament-event-command-request.d.ts +1 -0
- package/dist/generated/types/tournament-event-command-request.js +2 -0
- package/dist/generated/types/tournament-room-access-response.d.ts +1 -0
- package/dist/generated/types/tournament-room-access-response.js +2 -0
- package/dist/generated/types/tournament-room-chat-request.d.ts +1 -0
- package/dist/generated/types/tournament-room-chat-request.js +2 -0
- package/dist/generated/types/tournament-room-chat-response.d.ts +1 -0
- package/dist/generated/types/tournament-room-chat-response.js +2 -0
- package/dist/generated/types/tournament-room-list-response.d.ts +1 -0
- package/dist/generated/types/tournament-room-list-response.js +2 -0
- package/dist/generated/types/tournament-room-response.d.ts +1 -0
- package/dist/generated/types/tournament-room-response.js +2 -0
- package/dist/generated/types/tournament-room-server-message.d.ts +1 -0
- package/dist/generated/types/tournament-room-server-message.js +2 -0
- package/dist/generated/types/tournament-room-sync-request.d.ts +1 -0
- package/dist/generated/types/tournament-room-sync-request.js +2 -0
- package/dist/generated/types/undo-match-request.d.ts +1 -0
- package/dist/generated/types/undo-match-request.js +2 -0
- package/dist/generated/types/undo-match-response.d.ts +1 -0
- package/dist/generated/types/undo-match-response.js +2 -0
- package/dist/generated/types/undo-respond-match-request.d.ts +1 -0
- package/dist/generated/types/undo-respond-match-request.js +2 -0
- package/dist/generated/types/update-lobby-ai-player-request.d.ts +1 -0
- package/dist/generated/types/update-lobby-ai-player-request.js +2 -0
- package/dist/generated/types/update-lobby-player-request.d.ts +1 -0
- package/dist/generated/types/update-lobby-player-request.js +2 -0
- package/dist/generated/types/update-lobby-settings-request.d.ts +1 -0
- package/dist/generated/types/update-lobby-settings-request.js +2 -0
- package/dist/generated/types/update-tournament-room-player-request.d.ts +1 -0
- package/dist/generated/types/update-tournament-room-player-request.js +2 -0
- package/dist/generated/types/update-tournament-room-settings-request.d.ts +1 -0
- package/dist/generated/types/update-tournament-room-settings-request.js +2 -0
- package/dist/generated/types/update-tournament-table-deck-request.d.ts +123 -0
- package/dist/generated/types/update-tournament-table-deck-request.js +2 -0
- package/dist/generated/types/welcome-payload.d.ts +1 -0
- package/dist/generated/types/welcome-payload.js +2 -0
- package/dist/generated/version.d.ts +16 -0
- package/dist/generated/version.js +16 -0
- package/dist/http/abort.d.ts +57 -0
- package/dist/http/abort.js +60 -0
- package/dist/http/json.d.ts +13 -0
- package/dist/http/json.js +24 -0
- package/dist/http/options.d.ts +40 -0
- package/dist/http/options.js +1 -0
- package/dist/http/request.d.ts +64 -0
- package/dist/http/request.js +182 -0
- package/dist/http/validated-json.d.ts +9 -0
- package/dist/http/validated-json.js +14 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.js +10 -0
- package/dist/internal/abort-error.d.ts +91 -0
- package/dist/internal/abort-error.js +62 -0
- package/dist/internal/authenticated-socket-session.d.ts +63 -0
- package/dist/internal/authenticated-socket-session.js +170 -0
- package/dist/internal/emitter.d.ts +18 -0
- package/dist/internal/emitter.js +34 -0
- package/dist/internal/errors.d.ts +233 -0
- package/dist/internal/errors.js +238 -0
- package/dist/internal/limits.d.ts +13 -0
- package/dist/internal/limits.js +13 -0
- package/dist/internal/reconnect-backoff.d.ts +33 -0
- package/dist/internal/reconnect-backoff.js +25 -0
- package/dist/internal/socket-frame.d.ts +43 -0
- package/dist/internal/socket-frame.js +47 -0
- package/dist/internal/transport.d.ts +78 -0
- package/dist/internal/transport.js +18 -0
- package/dist/internal/websocket-event.d.ts +15 -0
- package/dist/internal/websocket-event.js +31 -0
- package/dist/local/assets.d.ts +96 -0
- package/dist/local/assets.js +235 -0
- package/dist/local/client.d.ts +32 -0
- package/dist/local/client.js +211 -0
- package/dist/local/engine.d.ts +79 -0
- package/dist/local/engine.js +6 -0
- package/dist/local/index.d.ts +20 -0
- package/dist/local/index.js +17 -0
- package/dist/local/offline-engine.d.ts +46 -0
- package/dist/local/offline-engine.js +74 -0
- package/dist/local/protocol.d.ts +95 -0
- package/dist/local/protocol.js +10 -0
- package/dist/local/routing.d.ts +52 -0
- package/dist/local/routing.js +193 -0
- package/dist/local/server/ai-scheduler.d.ts +31 -0
- package/dist/local/server/ai-scheduler.js +93 -0
- package/dist/local/server/http-router.d.ts +35 -0
- package/dist/local/server/http-router.js +185 -0
- package/dist/local/server/index.d.ts +16 -0
- package/dist/local/server/index.js +140 -0
- package/dist/local/server/sockets.d.ts +25 -0
- package/dist/local/server/sockets.js +141 -0
- package/dist/local/wasm-engine.d.ts +61 -0
- package/dist/local/wasm-engine.js +63 -0
- package/dist/local/worker-boot.d.ts +17 -0
- package/dist/local/worker-boot.js +76 -0
- package/dist/local/worker.d.ts +6 -0
- package/dist/local/worker.js +9 -0
- package/dist/match-session/access.d.ts +6 -0
- package/dist/match-session/access.js +8 -0
- package/dist/match-session/controller.d.ts +63 -0
- package/dist/match-session/controller.js +513 -0
- package/dist/match-session/errors.d.ts +3 -0
- package/dist/match-session/errors.js +34 -0
- package/dist/match-session/methods.d.ts +433 -0
- package/dist/match-session/methods.js +1 -0
- package/dist/match-session/session-state.d.ts +235 -0
- package/dist/match-session/session-state.js +1 -0
- package/dist/match-session/types.d.ts +56 -0
- package/dist/match-session/types.js +1 -0
- package/dist/match-session.d.ts +3 -0
- package/dist/match-session.js +1 -0
- package/dist/messages.d.ts +195 -0
- package/dist/messages.js +240 -0
- package/dist/resources/admin.d.ts +63 -0
- package/dist/resources/admin.js +75 -0
- package/dist/resources/card-deck-json.d.ts +11 -0
- package/dist/resources/card-deck-json.js +164 -0
- package/dist/resources/card-resolution.d.ts +9 -0
- package/dist/resources/card-resolution.js +21 -0
- package/dist/resources/card-resource.d.ts +157 -0
- package/dist/resources/card-resource.js +28 -0
- package/dist/resources/card-types.d.ts +203 -0
- package/dist/resources/card-types.js +1 -0
- package/dist/resources/cards.d.ts +3 -0
- package/dist/resources/cards.js +1 -0
- package/dist/resources/limited-event-types.d.ts +252 -0
- package/dist/resources/limited-event-types.js +1 -0
- package/dist/resources/limited-events.d.ts +7 -0
- package/dist/resources/limited-events.js +49 -0
- package/dist/resources/lobbies.d.ts +53 -0
- package/dist/resources/lobbies.js +50 -0
- package/dist/resources/lobby-list-session.d.ts +13 -0
- package/dist/resources/lobby-list-session.js +198 -0
- package/dist/resources/lobby-session.d.ts +9 -0
- package/dist/resources/lobby-session.js +59 -0
- package/dist/resources/lobby-types.d.ts +357 -0
- package/dist/resources/lobby-types.js +1 -0
- package/dist/resources/match-history.d.ts +49 -0
- package/dist/resources/match-history.js +34 -0
- package/dist/resources/match-types.d.ts +448 -0
- package/dist/resources/match-types.js +1 -0
- package/dist/resources/matches.d.ts +16 -0
- package/dist/resources/matches.js +109 -0
- package/dist/resources/ranked.d.ts +24 -0
- package/dist/resources/ranked.js +47 -0
- package/dist/resources/session.d.ts +62 -0
- package/dist/resources/session.js +26 -0
- package/dist/resources/system.d.ts +51 -0
- package/dist/resources/system.js +9 -0
- package/dist/resources/tournament-room-session.d.ts +9 -0
- package/dist/resources/tournament-room-session.js +53 -0
- package/dist/resources/tournament-room-types.d.ts +44 -0
- package/dist/resources/tournament-room-types.js +1 -0
- package/dist/resources/tournament-rooms.d.ts +33 -0
- package/dist/resources/tournament-rooms.js +33 -0
- package/dist/session.d.ts +56 -0
- package/dist/session.js +1 -0
- package/dist/types.d.ts +73 -0
- package/dist/types.js +27 -0
- package/dist/validators/ajv.d.ts +51 -0
- package/dist/validators/ajv.js +121 -0
- package/dist/validators/discriminants.d.ts +36 -0
- package/dist/validators/discriminants.js +89 -0
- package/dist/validators/validator.d.ts +73 -0
- package/dist/validators/validator.js +26 -0
- package/dist/validators/warm-up.d.ts +25 -0
- package/dist/validators/warm-up.js +59 -0
- package/dist/validators.d.ts +173 -0
- package/dist/validators.js +85 -0
- package/package.json +88 -0
- package/schema/abandon-match-request.schema.json +15 -0
- package/schema/abandon-match-response.schema.json +15 -0
- package/schema/add-lobby-ai-player-request.schema.json +53 -0
- package/schema/api-error-response.schema.json +13 -0
- package/schema/card-catalog-refresh-response.schema.json +31 -0
- package/schema/cards-response.schema.json +17 -0
- package/schema/client-message.schema.json +203 -0
- package/schema/close-tournament-room-request.schema.json +18 -0
- package/schema/common.schema.json +14129 -0
- package/schema/create-limited-event-request.schema.json +60 -0
- package/schema/create-lobby-request.schema.json +67 -0
- package/schema/create-match-request.schema.json +124 -0
- package/schema/create-meta-window-request.schema.json +27 -0
- package/schema/create-tournament-room-request.schema.json +104 -0
- package/schema/create-tournament-table-request.schema.json +14 -0
- package/schema/error-payload.schema.json +34 -0
- package/schema/format-event-request.schema.json +20 -0
- package/schema/format-event-response.schema.json +15 -0
- package/schema/game-command.schema.json +775 -0
- package/schema/game-event.schema.json +2012 -0
- package/schema/game-state.schema.json +273 -0
- package/schema/get-match-response.schema.json +13 -0
- package/schema/health-response.schema.json +13 -0
- package/schema/join-limited-event-request.schema.json +6 -0
- package/schema/join-lobby-request.schema.json +40 -0
- package/schema/join-match-request.schema.json +79 -0
- package/schema/join-tournament-room-request.schema.json +39 -0
- package/schema/join-tournament-table-request.schema.json +14 -0
- package/schema/kick-lobby-player-request.schema.json +13 -0
- package/schema/kick-lobby-spectator-request.schema.json +14 -0
- package/schema/leave-lobby-request.schema.json +13 -0
- package/schema/leave-match-request.schema.json +15 -0
- package/schema/leave-match-response.schema.json +15 -0
- package/schema/leave-tournament-room-request.schema.json +14 -0
- package/schema/limited-event-access-response.schema.json +34 -0
- package/schema/limited-event-command-request.schema.json +20 -0
- package/schema/limited-event-preflight-response.schema.json +25 -0
- package/schema/limited-event-response.schema.json +15 -0
- package/schema/list-active-ai-matches-request.schema.json +23 -0
- package/schema/list-active-ai-matches-response.schema.json +17 -0
- package/schema/lobby-access-response.schema.json +31 -0
- package/schema/lobby-chat-request.schema.json +17 -0
- package/schema/lobby-chat-response.schema.json +17 -0
- package/schema/lobby-list-response.schema.json +16 -0
- package/schema/lobby-list-server-message.schema.json +49 -0
- package/schema/lobby-matchmaking-decision-request.schema.json +13 -0
- package/schema/lobby-matchmaking-request.schema.json +80 -0
- package/schema/lobby-response.schema.json +13 -0
- package/schema/lobby-server-message.schema.json +155 -0
- package/schema/lobby-sync-request.schema.json +13 -0
- package/schema/manifest.json +124 -0
- package/schema/match-access-response.schema.json +32 -0
- package/schema/match-chat-lookup-response.schema.json +34 -0
- package/schema/match-connection-role.schema.json +9 -0
- package/schema/match-history-deck-stats-request.schema.json +26 -0
- package/schema/match-history-deck-stats-response.schema.json +17 -0
- package/schema/match-history-entry.schema.json +78 -0
- package/schema/match-history-list-request.schema.json +48 -0
- package/schema/match-history-list-response.schema.json +25 -0
- package/schema/match-history-replay-request.schema.json +17 -0
- package/schema/match-history-replay-response.schema.json +14 -0
- package/schema/match-history-restore-request.schema.json +23 -0
- package/schema/match-save-payload.schema.json +71 -0
- package/schema/match-spectator-access-response.schema.json +22 -0
- package/schema/meta-window.schema.json +37 -0
- package/schema/meta-windows-response.schema.json +24 -0
- package/schema/prepare-lobby-limited-ai-decks-request.schema.json +14 -0
- package/schema/ranked-admin-status.schema.json +43 -0
- package/schema/ranked-leaderboard-entry.schema.json +61 -0
- package/schema/ranked-leaderboard-query.schema.json +34 -0
- package/schema/ranked-leaderboard-response.schema.json +23 -0
- package/schema/ranked-matchmaking-view.schema.json +15 -0
- package/schema/ranked-profile-request.schema.json +21 -0
- package/schema/ranked-profile-response.schema.json +59 -0
- package/schema/ranked-queue.schema.json +12 -0
- package/schema/rematch-match-request.schema.json +20 -0
- package/schema/rematch-match-response.schema.json +61 -0
- package/schema/resolve-card-ids-request.schema.json +17 -0
- package/schema/resolve-card-ids-response.schema.json +16 -0
- package/schema/restore-history-response.schema.json +15 -0
- package/schema/restore-match-save-request.schema.json +20 -0
- package/schema/restore-match-save-response.schema.json +29 -0
- package/schema/return-lobby-match-request.schema.json +13 -0
- package/schema/return-tournament-match-request.schema.json +14 -0
- package/schema/route-manifest.json +1014 -0
- package/schema/save-match-request.schema.json +15 -0
- package/schema/server-message.schema.json +192 -0
- package/schema/set-ai-paused-request.schema.json +19 -0
- package/schema/set-ai-paused-response.schema.json +18 -0
- package/schema/set-ranked-admission-request.schema.json +15 -0
- package/schema/set-simulator-maintenance-request.schema.json +20 -0
- package/schema/simulator-admin-status-response.schema.json +37 -0
- package/schema/simulator-availability-response.schema.json +27 -0
- package/schema/simulator-report-list-response.schema.json +23 -0
- package/schema/simulator-report-response.schema.json +77 -0
- package/schema/spectate-lobby-request.schema.json +32 -0
- package/schema/spectate-match-request.schema.json +32 -0
- package/schema/start-lobby-limited-match-request.schema.json +13 -0
- package/schema/start-lobby-request.schema.json +13 -0
- package/schema/start-tournament-event-request.schema.json +14 -0
- package/schema/submit-lobby-limited-deck-request.schema.json +33 -0
- package/schema/submit-match-deck-request.schema.json +45 -0
- package/schema/submit-match-deck-response.schema.json +14 -0
- package/schema/submit-tournament-deck-request.schema.json +34 -0
- package/schema/tournament-event-command-request.schema.json +18 -0
- package/schema/tournament-room-access-response.schema.json +32 -0
- package/schema/tournament-room-chat-request.schema.json +18 -0
- package/schema/tournament-room-chat-response.schema.json +18 -0
- package/schema/tournament-room-list-response.schema.json +17 -0
- package/schema/tournament-room-response.schema.json +14 -0
- package/schema/tournament-room-server-message.schema.json +127 -0
- package/schema/tournament-room-sync-request.schema.json +14 -0
- package/schema/undo-match-request.schema.json +14 -0
- package/schema/undo-match-response.schema.json +14 -0
- package/schema/undo-respond-match-request.schema.json +19 -0
- package/schema/update-lobby-ai-player-request.schema.json +65 -0
- package/schema/update-lobby-player-request.schema.json +81 -0
- package/schema/update-lobby-settings-request.schema.json +70 -0
- package/schema/update-tournament-room-player-request.schema.json +45 -0
- package/schema/update-tournament-room-settings-request.schema.json +33 -0
- package/schema/welcome-payload.schema.json +38 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Guillaume Chau
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
# @my-swu/simulator-client
|
|
2
|
+
|
|
3
|
+
Typed TypeScript SDK for the `swu-simulator` HTTP and WebSocket engine.
|
|
4
|
+
|
|
5
|
+
The SDK ships generated protocol types from the Rust server, validates runtime
|
|
6
|
+
payloads at the network boundary, and exposes a small resource-based client for
|
|
7
|
+
matches, card metadata, Limited Events, and system checks.
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
pnpm add @my-swu/simulator-client
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install @my-swu/simulator-client
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Runtime Requirements
|
|
20
|
+
|
|
21
|
+
- Node.js 18+ or a runtime with global `fetch`.
|
|
22
|
+
- A browser-style `WebSocket` global for live match connections.
|
|
23
|
+
- ESM only.
|
|
24
|
+
|
|
25
|
+
Node has `fetch` but not a browser WebSocket global. Keep the SDK lean by
|
|
26
|
+
injecting your socket implementation:
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
import WebSocket from 'ws'
|
|
30
|
+
import { createSimulatorClient } from '@my-swu/simulator-client'
|
|
31
|
+
import type { WebSocketFactory } from '@my-swu/simulator-client'
|
|
32
|
+
|
|
33
|
+
// Node examples use `ws` to provide the browser-compatible socket shape.
|
|
34
|
+
const nodeWebSocketFactory: WebSocketFactory = url => new WebSocket(url)
|
|
35
|
+
|
|
36
|
+
const simulatorClient = createSimulatorClient({
|
|
37
|
+
baseUrl: 'http://127.0.0.1:4000',
|
|
38
|
+
// Required only for live match sockets in runtimes without global WebSocket.
|
|
39
|
+
webSocketFactory: nodeWebSocketFactory,
|
|
40
|
+
})
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Card ids
|
|
44
|
+
|
|
45
|
+
Decks and commands use card ids. These are not collector numbers or
|
|
46
|
+
match-local `unitId` / `abilityId` handles. The
|
|
47
|
+
examples below use `46102` for Leia Organa - Someone Who Loves You, `46107` for
|
|
48
|
+
Darth Vader - Unstoppable, `308` for Echo Base, `309` for Tarkintown, `45` for
|
|
49
|
+
Alliance X-Wing, and `35` for TIE/ln Fighter.
|
|
50
|
+
|
|
51
|
+
Convert set code plus printed card number into card ids through the card
|
|
52
|
+
resource:
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
const krennicCardId = await simulatorClient.cards.resolveId({
|
|
56
|
+
setCode: 'SOR',
|
|
57
|
+
cardNumber: 1,
|
|
58
|
+
cardTypes: ['leader'],
|
|
59
|
+
})
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Import my-swu JSON decks with `SET_001` card ids before match creation:
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
const importedDeck = await simulatorClient.cards.convertDeckJson({
|
|
66
|
+
leader: { id: 'SOR_001', count: 1 },
|
|
67
|
+
base: { id: 'SOR_025', count: 1 },
|
|
68
|
+
deck: [{ id: 'SOR_010', count: 3 }],
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
await simulatorClient.matches.create({
|
|
72
|
+
format: 'premier',
|
|
73
|
+
playerCount: 2,
|
|
74
|
+
hostDeck: importedDeck,
|
|
75
|
+
hostName: 'Host',
|
|
76
|
+
hostAuthenticated: false,
|
|
77
|
+
historyIdentities: [],
|
|
78
|
+
aiOpponents: [],
|
|
79
|
+
})
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Quick Match
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
import { createSimulatorClient } from '@my-swu/simulator-client'
|
|
86
|
+
|
|
87
|
+
const simulatorClient = createSimulatorClient({
|
|
88
|
+
baseUrl: 'http://127.0.0.1:4000',
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
// Use card ids; these example card ids map to real cards.
|
|
92
|
+
const premierHostDeck = {
|
|
93
|
+
leader: 46102, // Leia Organa - Someone Who Loves You
|
|
94
|
+
leaders: [], // Twin Suns only; Premier uses the single `leader` above.
|
|
95
|
+
base: 308, // Echo Base
|
|
96
|
+
cards: Array.from({ length: 50 }, () => 45), // Alliance X-Wing
|
|
97
|
+
sideboard: [],
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const hostAccess = await simulatorClient.matches.create({
|
|
101
|
+
// Seeds make local examples and tests deterministic.
|
|
102
|
+
seed: 7,
|
|
103
|
+
format: 'premier',
|
|
104
|
+
// Twin Suns supports 2-4 players; every other format is exactly 2.
|
|
105
|
+
playerCount: 2,
|
|
106
|
+
hostDeck: premierHostDeck,
|
|
107
|
+
hostName: 'Host',
|
|
108
|
+
hostAuthenticated: false,
|
|
109
|
+
historyIdentities: [],
|
|
110
|
+
// One entry per AI-controlled seat; empty means a human opponent joins.
|
|
111
|
+
aiOpponents: [],
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
// The session stores matchId plus the private seat token for this seat.
|
|
115
|
+
const matchSession = simulatorClient.session.create(hostAccess)
|
|
116
|
+
await matchSession.connect()
|
|
117
|
+
|
|
118
|
+
matchSession.on('snapshot', matchSnapshot => {
|
|
119
|
+
// Render from snapshots; they are the authoritative game state.
|
|
120
|
+
console.log(matchSnapshot.prompt)
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
// Both seats must be ready before setup can advance.
|
|
124
|
+
matchSession.ready()
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## Resource API
|
|
128
|
+
|
|
129
|
+
```ts
|
|
130
|
+
// System health checks are cheap liveness checks.
|
|
131
|
+
const health = await simulatorClient.system.health()
|
|
132
|
+
|
|
133
|
+
// Card resources read canonical card metadata from the simulator server cache.
|
|
134
|
+
const requestedCardMetadata = await simulatorClient.cards.get([
|
|
135
|
+
46102, // Leia Organa - Someone Who Loves You
|
|
136
|
+
308, // Echo Base
|
|
137
|
+
])
|
|
138
|
+
const catalogCards = await simulatorClient.cards.catalog()
|
|
139
|
+
|
|
140
|
+
// Match creation validates decks before allocating seat credentials.
|
|
141
|
+
const premierHostDeck = {
|
|
142
|
+
leader: 46102, // Leia Organa - Someone Who Loves You
|
|
143
|
+
leaders: [], // Twin Suns only; Premier uses the single `leader` above.
|
|
144
|
+
base: 308, // Echo Base
|
|
145
|
+
cards: Array.from({ length: 50 }, () => 45), // Alliance X-Wing
|
|
146
|
+
sideboard: [],
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const premierGuestDeck = {
|
|
150
|
+
leader: 46107, // Darth Vader - Unstoppable
|
|
151
|
+
leaders: [],
|
|
152
|
+
base: 309, // Tarkintown
|
|
153
|
+
cards: Array.from({ length: 50 }, () => 35), // TIE/ln Fighter
|
|
154
|
+
sideboard: [],
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const hostAccess = await simulatorClient.matches.create({
|
|
158
|
+
format: 'premier',
|
|
159
|
+
playerCount: 2,
|
|
160
|
+
hostDeck: premierHostDeck,
|
|
161
|
+
hostName: 'Host',
|
|
162
|
+
hostAuthenticated: false,
|
|
163
|
+
historyIdentities: [],
|
|
164
|
+
aiOpponents: [],
|
|
165
|
+
})
|
|
166
|
+
const guestAccess = await simulatorClient.matches.join(hostAccess, {
|
|
167
|
+
deck: premierGuestDeck,
|
|
168
|
+
name: 'Guest',
|
|
169
|
+
authenticated: false,
|
|
170
|
+
historyIdentities: [],
|
|
171
|
+
})
|
|
172
|
+
const publicMatchSnapshot = await simulatorClient.matches.get(hostAccess)
|
|
173
|
+
const updatedMatchSnapshot = await simulatorClient.matches.applyFormatEvent(hostAccess, { type: 'readyNextGame' })
|
|
174
|
+
|
|
175
|
+
// Limited Events produce draft or sealed pools before normal match creation.
|
|
176
|
+
const draftEventAccess = await simulatorClient.limitedEvents.create({
|
|
177
|
+
kind: 'draft',
|
|
178
|
+
draftRounds: [],
|
|
179
|
+
pickTimerEnabled: false,
|
|
180
|
+
setCode: 'SOR',
|
|
181
|
+
playerCount: 4,
|
|
182
|
+
})
|
|
183
|
+
const draftSeatAccess = await simulatorClient.limitedEvents.join(draftEventAccess)
|
|
184
|
+
const limitedEventSnapshot = await simulatorClient.limitedEvents.get(draftSeatAccess)
|
|
185
|
+
const nextLimitedEventSnapshot = await simulatorClient.limitedEvents.applyCommand(
|
|
186
|
+
draftSeatAccess,
|
|
187
|
+
{ type: 'readyForNextDraft' },
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
console.log(
|
|
191
|
+
health.status,
|
|
192
|
+
requestedCardMetadata.length,
|
|
193
|
+
catalogCards.length,
|
|
194
|
+
guestAccess.seat,
|
|
195
|
+
publicMatchSnapshot.status,
|
|
196
|
+
updatedMatchSnapshot.status,
|
|
197
|
+
limitedEventSnapshot.phase.kind,
|
|
198
|
+
nextLimitedEventSnapshot.phase.kind,
|
|
199
|
+
)
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
## Cancellation and Timeouts
|
|
203
|
+
|
|
204
|
+
Every HTTP resource method takes an optional trailing options argument with a
|
|
205
|
+
caller-owned `signal` and a per-call `timeoutMs`. Omit it and nothing changes.
|
|
206
|
+
|
|
207
|
+
```ts
|
|
208
|
+
const unmountController = new AbortController()
|
|
209
|
+
|
|
210
|
+
// Cancel in-flight work when the view goes away, and bound the wait.
|
|
211
|
+
const publicMatchSnapshot = await simulatorClient.matches.get(hostAccess, {
|
|
212
|
+
signal: unmountController.signal,
|
|
213
|
+
timeoutMs: 5_000,
|
|
214
|
+
})
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
`createSimulatorClient({ timeoutMs })` sets a default for every call. A per-call
|
|
218
|
+
`timeoutMs` overrides it, and `0` opts a single call out of the default. When a
|
|
219
|
+
signal and a timeout are both in play, whichever fires first wins.
|
|
220
|
+
|
|
221
|
+
```ts
|
|
222
|
+
import { createSimulatorClient } from '@my-swu/simulator-client'
|
|
223
|
+
|
|
224
|
+
const boundedClient = createSimulatorClient({
|
|
225
|
+
baseUrl: 'http://127.0.0.1:4000',
|
|
226
|
+
timeoutMs: 10_000,
|
|
227
|
+
})
|
|
228
|
+
|
|
229
|
+
// The catalog is large; give this one call more room than the default.
|
|
230
|
+
const catalogCards = await boundedClient.cards.catalog({ timeoutMs: 60_000 })
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
## Runtime Validation
|
|
234
|
+
|
|
235
|
+
Runtime schema validation is **off by default**. Responses, request bodies and
|
|
236
|
+
socket frames come back as their generated TypeScript types without being
|
|
237
|
+
checked against the JSON schemas first.
|
|
238
|
+
|
|
239
|
+
The reason is bundle size. The generated schema map plus Ajv are 90% of the
|
|
240
|
+
minified SDK, and they are unreachable from `createSimulatorClient` unless you
|
|
241
|
+
name `createSchemaValidator`:
|
|
242
|
+
|
|
243
|
+
| Bundle | Minified | Gzip |
|
|
244
|
+
| --- | --- | --- |
|
|
245
|
+
| Default client | 39.1 KB | 9.9 KB |
|
|
246
|
+
| `validate: createSchemaValidator()` | 478.2 KB | 102.0 KB |
|
|
247
|
+
|
|
248
|
+
Measured with esbuild against `dist/index.js` for an entry that builds a client
|
|
249
|
+
and one match session: 322 KB of generated schemas and 115 KB of Ajv drop out.
|
|
250
|
+
Per frame, decoding a real 3.2 KB `server-message` snapshot costs about 5 µs
|
|
251
|
+
with validation off (the `JSON.parse` floor) against 13-15 µs with it on, so
|
|
252
|
+
validation adds 8-10 µs to every frame; each outbound envelope adds about
|
|
253
|
+
0.9 µs.
|
|
254
|
+
|
|
255
|
+
What you give up on the default:
|
|
256
|
+
|
|
257
|
+
- A malformed server payload is not rejected. It reaches your code typed as if
|
|
258
|
+
it were valid, so the mismatch shows up later as an `undefined` field.
|
|
259
|
+
- A malformed request body is not caught locally. You get the server's `400`
|
|
260
|
+
through `EngineHttpError` instead of an `SdkValidationError` naming the field.
|
|
261
|
+
- An unknown server message type is no longer dropped during decode. It cannot
|
|
262
|
+
be mis-dispatched — no router has a case for it — but it does reach the raw
|
|
263
|
+
`message` event.
|
|
264
|
+
|
|
265
|
+
Non-schema failures are unchanged: invalid JSON on a socket still emits
|
|
266
|
+
`sdk_invalid_server_message`, and a non-2xx response still throws
|
|
267
|
+
`EngineHttpError`.
|
|
268
|
+
|
|
269
|
+
Pass a validator to get the previous behaviour back, everywhere:
|
|
270
|
+
|
|
271
|
+
```ts
|
|
272
|
+
import {
|
|
273
|
+
createSchemaValidator,
|
|
274
|
+
createSimulatorClient,
|
|
275
|
+
} from '@my-swu/simulator-client'
|
|
276
|
+
|
|
277
|
+
const validatingSimulatorClient = createSimulatorClient({
|
|
278
|
+
baseUrl: 'http://127.0.0.1:4000',
|
|
279
|
+
validate: createSchemaValidator(),
|
|
280
|
+
})
|
|
281
|
+
|
|
282
|
+
// Throws SdkValidationError if the server answers off-contract.
|
|
283
|
+
const validatedHealth = await validatingSimulatorClient.system.health()
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
`parseSchema()` is unaffected: an explicit call always validates, whatever the
|
|
287
|
+
client is configured to do.
|
|
288
|
+
|
|
289
|
+
One validator serves the whole client: HTTP bodies and responses plus every
|
|
290
|
+
socket it opens — match sessions, lobby sessions, the public lobby list, and
|
|
291
|
+
tournament rooms all inherit it.
|
|
292
|
+
|
|
293
|
+
Schema compilation is lazy and the first compile is by far the most expensive
|
|
294
|
+
(~215 ms, because it pulls in the whole shared definition pool), so
|
|
295
|
+
`createSimulatorClient` schedules the validator's `warmUp()` on an idle callback
|
|
296
|
+
and gets it off the connect path — the first validated frame drops from 226 ms
|
|
297
|
+
to a 7.9 ms median. Nothing to configure, and with validation off it is a real
|
|
298
|
+
no-op: the pass-through validator does not implement `warmUp`.
|
|
299
|
+
|
|
300
|
+
## Match Session
|
|
301
|
+
|
|
302
|
+
`simulatorClient.session.create(access)` accepts a returned match access object
|
|
303
|
+
or any `{ matchId, seatToken }` value. `connect()` resolves after the socket
|
|
304
|
+
opens, `welcome` arrives, and the first `snapshot` arrives.
|
|
305
|
+
|
|
306
|
+
```ts
|
|
307
|
+
const matchSession = simulatorClient.session.create(hostAccess, {
|
|
308
|
+
handshakeTimeoutMs: 10_000,
|
|
309
|
+
})
|
|
310
|
+
await matchSession.connect()
|
|
311
|
+
|
|
312
|
+
// Wait helpers resolve immediately if the current snapshot already matches.
|
|
313
|
+
await matchSession.waitForSnapshot(
|
|
314
|
+
matchSnapshot => typeof matchSnapshot.prompt === 'object' && 'chooseInitiative' in matchSnapshot.prompt,
|
|
315
|
+
)
|
|
316
|
+
|
|
317
|
+
// Reconnect keeps registered listeners and requests a fresh snapshot.
|
|
318
|
+
await matchSession.reconnect({ handshakeTimeoutMs: 5_000 })
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
## Errors
|
|
322
|
+
|
|
323
|
+
- `EngineHttpError` is thrown for non-2xx HTTP responses and includes `status`,
|
|
324
|
+
`code`, `method`, `url`, `payload`, and `responseText` when available.
|
|
325
|
+
- `EngineRequestAbortedError` is thrown when an HTTP call is cancelled before the
|
|
326
|
+
server answers. `kind` is `'aborted'` for a caller-supplied signal and
|
|
327
|
+
`'timeout'` for an elapsed timeout.
|
|
328
|
+
- `SdkValidationError` is thrown by `parseSchema()`, and — when the client is
|
|
329
|
+
built with `validate` — when a request or response does not match the
|
|
330
|
+
generated schema. See [Runtime Validation](#runtime-validation).
|
|
331
|
+
- Socket decode failures emit an `error` event with
|
|
332
|
+
`code: 'sdk_invalid_server_message'`. Match, lobby, tournament-room, and
|
|
333
|
+
lobby-list sockets share one decoder, so all four report invalid JSON and
|
|
334
|
+
(with a validator) malformed known frames the same way, and all four ignore an
|
|
335
|
+
unknown frame `type` so the wire can grow.
|
|
336
|
+
|
|
337
|
+
## Schemas and Types
|
|
338
|
+
|
|
339
|
+
- Public protocol types are exported from the package root and
|
|
340
|
+
`@my-swu/simulator-client/generated`.
|
|
341
|
+
- The root export set is closed under reference: if an exported type names
|
|
342
|
+
another generated type in one of its fields, that one is exported too. Import
|
|
343
|
+
nested wire views by name instead of rebuilding them with indexed access.
|
|
344
|
+
- JSON schemas are published under `@my-swu/simulator-client/schema/*`.
|
|
345
|
+
- Shared definitions live once in `schema/common.schema.json`; every root schema
|
|
346
|
+
references them by its `$id`
|
|
347
|
+
(`https://simulator-sdk.my-swu.com/schema/common.json`) instead of inlining a
|
|
348
|
+
copy. Register that document with your validator before the roots, the way
|
|
349
|
+
`parseSchema` does — for Ajv, `ajv.addSchema(sdkSchemaCommon)` first.
|
|
350
|
+
- `schema/manifest.json` lists the roots in `files` and the shared document in
|
|
351
|
+
`shared`.
|
|
352
|
+
|
|
353
|
+
## License
|
|
354
|
+
|
|
355
|
+
MIT
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { GameCommand, GameState } from './generated/index.js';
|
|
2
|
+
import type { AbilityTarget, ActionAbilityView, LeaderActionView, LeaderDeployActionView, PendingAbilityView, PlayActionView, TargetSelectionGroup } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Every projected action that asks the player to pick targets.
|
|
5
|
+
*
|
|
6
|
+
* The engine splits these across two field names: `PendingAbilityView` nests
|
|
7
|
+
* its groups in `targetPlan`, while the three action views keep `targetGroups`
|
|
8
|
+
* inline. Walking both is what {@link targetGroupsOf} exists for.
|
|
9
|
+
*/
|
|
10
|
+
export type TargetingActionView = ActionAbilityView | LeaderActionView | PendingAbilityView | PlayActionView;
|
|
11
|
+
/**
|
|
12
|
+
* Reads the ordered target-selection groups of any targeting action.
|
|
13
|
+
*
|
|
14
|
+
* Hides the `targetPlan` / `targetGroups` split so a consumer that renders
|
|
15
|
+
* pending abilities and playable actions through one code path does not need
|
|
16
|
+
* its own accessor.
|
|
17
|
+
*
|
|
18
|
+
* @param action Projected action, or a nullish value while none is selected.
|
|
19
|
+
* @returns The action's groups in engine order; empty when there is no action.
|
|
20
|
+
*/
|
|
21
|
+
export declare function targetGroupsOf(action: TargetingActionView | null | undefined): TargetSelectionGroup[];
|
|
22
|
+
/**
|
|
23
|
+
* Concatenates every group's candidate targets, in group order.
|
|
24
|
+
*
|
|
25
|
+
* This is what the retired flat `validTargets` field on the action views
|
|
26
|
+
* carried, so "how many targets could this action pick from?" stays a
|
|
27
|
+
* one-liner. Duplicates are kept: one entity legal in two groups appears
|
|
28
|
+
* twice, matching the retired field.
|
|
29
|
+
*
|
|
30
|
+
* @param groups Groups from {@link targetGroupsOf}, or a nullish value.
|
|
31
|
+
* @returns Every candidate target across the groups.
|
|
32
|
+
*/
|
|
33
|
+
export declare function flattenTargetGroups(groups: readonly TargetSelectionGroup[] | null | undefined): AbilityTarget[];
|
|
34
|
+
/**
|
|
35
|
+
* Whether a plan is exactly one mandatory pick.
|
|
36
|
+
*
|
|
37
|
+
* That is the shape the engine synthesises for an ability with no structured
|
|
38
|
+
* clauses but with candidate targets, and it is the only plan a client can
|
|
39
|
+
* resolve from a single selection: one group, `min` and `max` both 1. An
|
|
40
|
+
* optional pick (`min: 0`) or a multi-target group still needs an explicit
|
|
41
|
+
* submit step.
|
|
42
|
+
*
|
|
43
|
+
* @param groups Groups from {@link targetGroupsOf}, or a nullish value.
|
|
44
|
+
*/
|
|
45
|
+
export declare function isSingleTargetPlan(groups: readonly TargetSelectionGroup[] | null | undefined): boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Returns whether the snapshot exposes at least one legal leader deploy action.
|
|
48
|
+
*/
|
|
49
|
+
export declare function canDeployAnyLeader(snapshot: GameState): boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Returns unique leader slot indices that have at least one legal deploy action.
|
|
52
|
+
*/
|
|
53
|
+
export declare function getDeployableLeaderIndices(snapshot: GameState): number[];
|
|
54
|
+
/**
|
|
55
|
+
* Builds the gameplay command for one projected leader deploy action.
|
|
56
|
+
*/
|
|
57
|
+
export declare function leaderDeployCommand(action: LeaderDeployActionView): GameCommand;
|
|
58
|
+
/**
|
|
59
|
+
* Builds gameplay commands for every projected leader deploy action.
|
|
60
|
+
*/
|
|
61
|
+
export declare function getLeaderDeployCommands(snapshot: GameState): GameCommand[];
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reads the ordered target-selection groups of any targeting action.
|
|
3
|
+
*
|
|
4
|
+
* Hides the `targetPlan` / `targetGroups` split so a consumer that renders
|
|
5
|
+
* pending abilities and playable actions through one code path does not need
|
|
6
|
+
* its own accessor.
|
|
7
|
+
*
|
|
8
|
+
* @param action Projected action, or a nullish value while none is selected.
|
|
9
|
+
* @returns The action's groups in engine order; empty when there is no action.
|
|
10
|
+
*/
|
|
11
|
+
export function targetGroupsOf(action) {
|
|
12
|
+
if (action == null)
|
|
13
|
+
return [];
|
|
14
|
+
// `targetPlan` is the structural discriminator between the two shapes: only
|
|
15
|
+
// `PendingAbilityView` carries it, and it is always present when it does.
|
|
16
|
+
return 'targetPlan' in action ? action.targetPlan.groups : action.targetGroups;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Concatenates every group's candidate targets, in group order.
|
|
20
|
+
*
|
|
21
|
+
* This is what the retired flat `validTargets` field on the action views
|
|
22
|
+
* carried, so "how many targets could this action pick from?" stays a
|
|
23
|
+
* one-liner. Duplicates are kept: one entity legal in two groups appears
|
|
24
|
+
* twice, matching the retired field.
|
|
25
|
+
*
|
|
26
|
+
* @param groups Groups from {@link targetGroupsOf}, or a nullish value.
|
|
27
|
+
* @returns Every candidate target across the groups.
|
|
28
|
+
*/
|
|
29
|
+
export function flattenTargetGroups(groups) {
|
|
30
|
+
return (groups ?? []).flatMap((group) => group.validTargets);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Whether a plan is exactly one mandatory pick.
|
|
34
|
+
*
|
|
35
|
+
* That is the shape the engine synthesises for an ability with no structured
|
|
36
|
+
* clauses but with candidate targets, and it is the only plan a client can
|
|
37
|
+
* resolve from a single selection: one group, `min` and `max` both 1. An
|
|
38
|
+
* optional pick (`min: 0`) or a multi-target group still needs an explicit
|
|
39
|
+
* submit step.
|
|
40
|
+
*
|
|
41
|
+
* @param groups Groups from {@link targetGroupsOf}, or a nullish value.
|
|
42
|
+
*/
|
|
43
|
+
export function isSingleTargetPlan(groups) {
|
|
44
|
+
if ((groups?.length ?? 0) !== 1)
|
|
45
|
+
return false;
|
|
46
|
+
const group = groups?.[0];
|
|
47
|
+
return group?.min === 1 && group.max === 1;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Returns whether the snapshot exposes at least one legal leader deploy action.
|
|
51
|
+
*/
|
|
52
|
+
export function canDeployAnyLeader(snapshot) {
|
|
53
|
+
return (snapshot.availableLeaderDeploys ?? []).length > 0;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Returns unique leader slot indices that have at least one legal deploy action.
|
|
57
|
+
*/
|
|
58
|
+
export function getDeployableLeaderIndices(snapshot) {
|
|
59
|
+
const indices = new Set();
|
|
60
|
+
for (const action of snapshot.availableLeaderDeploys ?? []) {
|
|
61
|
+
indices.add(action.leaderIndex);
|
|
62
|
+
}
|
|
63
|
+
return [...indices];
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Builds the gameplay command for one projected leader deploy action.
|
|
67
|
+
*/
|
|
68
|
+
export function leaderDeployCommand(action) {
|
|
69
|
+
if (action.mode === 'unit') {
|
|
70
|
+
return action.leaderIndex === 0
|
|
71
|
+
? 'deployLeader'
|
|
72
|
+
: { deployLeaderByIndex: { leaderIndex: action.leaderIndex } };
|
|
73
|
+
}
|
|
74
|
+
if (action.attachedToUnitId == null) {
|
|
75
|
+
throw new Error('pilot leader deploy action is missing attachedToUnitId');
|
|
76
|
+
}
|
|
77
|
+
return action.leaderIndex === 0
|
|
78
|
+
? { deployLeaderAsPilot: { attachedToUnitId: action.attachedToUnitId } }
|
|
79
|
+
: {
|
|
80
|
+
deployLeaderAsPilotByIndex: {
|
|
81
|
+
attachedToUnitId: action.attachedToUnitId,
|
|
82
|
+
leaderIndex: action.leaderIndex,
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Builds gameplay commands for every projected leader deploy action.
|
|
88
|
+
*/
|
|
89
|
+
export function getLeaderDeployCommands(snapshot) {
|
|
90
|
+
return (snapshot.availableLeaderDeploys ?? []).map(leaderDeployCommand);
|
|
91
|
+
}
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import type { FetchLike, WebSocketFactory } from './internal/transport.js';
|
|
2
|
+
import type { AdminResource } from './resources/admin.js';
|
|
3
|
+
import type { CardsResource } from './resources/card-resource.js';
|
|
4
|
+
import type { LimitedEventsResource } from './resources/limited-events.js';
|
|
5
|
+
import type { LobbiesResource } from './resources/lobbies.js';
|
|
6
|
+
import type { MatchHistoryResource } from './resources/match-history.js';
|
|
7
|
+
import type { MatchesResource } from './resources/matches.js';
|
|
8
|
+
import type { SessionResource } from './resources/session.js';
|
|
9
|
+
import type { SystemResource } from './resources/system.js';
|
|
10
|
+
import type { TournamentRoomsResource } from './resources/tournament-rooms.js';
|
|
11
|
+
import type { SchemaValidator } from './validators/validator.js';
|
|
12
|
+
/**
|
|
13
|
+
* Constructor options for the simulator client.
|
|
14
|
+
*
|
|
15
|
+
* `baseUrl` points at the HTTP origin for the simulator server. The SDK derives
|
|
16
|
+
* `/api/*`, `/health`, and the matching `/ws` socket origin from this value.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts
|
|
20
|
+
* import { createSimulatorClient } from '@my-swu/simulator-client'
|
|
21
|
+
*
|
|
22
|
+
* const simulatorClient = createSimulatorClient({
|
|
23
|
+
* baseUrl: 'http://127.0.0.1:4000',
|
|
24
|
+
* })
|
|
25
|
+
*
|
|
26
|
+
* console.log(await simulatorClient.system.health())
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* @see https://simulator-sdk.my-swu.com/guide/getting-started
|
|
30
|
+
* @see https://simulator-sdk.my-swu.com/guide/runtime-adapters
|
|
31
|
+
*/
|
|
32
|
+
export interface SimulatorClientOptions {
|
|
33
|
+
/**
|
|
34
|
+
* Base URL of the simulator HTTP API, for example `http://127.0.0.1:4000`.
|
|
35
|
+
* The trailing slash is optional.
|
|
36
|
+
*/
|
|
37
|
+
baseUrl: string;
|
|
38
|
+
/**
|
|
39
|
+
* Optional fetch implementation. Defaults to the global `fetch` when available.
|
|
40
|
+
*/
|
|
41
|
+
fetch?: FetchLike;
|
|
42
|
+
/**
|
|
43
|
+
* Optional default timeout, in milliseconds, for every HTTP resource call.
|
|
44
|
+
*
|
|
45
|
+
* A per-call `timeoutMs` overrides this value, and passing `0` for one call
|
|
46
|
+
* opts that call out. Leave it unset to keep requests unbounded, which is how
|
|
47
|
+
* the client behaved before timeouts existed.
|
|
48
|
+
*/
|
|
49
|
+
timeoutMs?: number | undefined;
|
|
50
|
+
/**
|
|
51
|
+
* Optional runtime validator for every payload crossing the network boundary.
|
|
52
|
+
*
|
|
53
|
+
* Off by default: HTTP responses, HTTP request bodies and socket frames are
|
|
54
|
+
* trusted as-is. Pass `createSchemaValidator()` to check all of them against
|
|
55
|
+
* the generated schemas, which is what the SDK did unconditionally before
|
|
56
|
+
* this option existed.
|
|
57
|
+
*
|
|
58
|
+
* The default exists for bundle size: naming `createSchemaValidator` is what
|
|
59
|
+
* makes the generated schema map and Ajv reachable from this module, and they
|
|
60
|
+
* are about 90% of the SDK's minified weight. A custom implementation of
|
|
61
|
+
* {@link SchemaValidator} is accepted too.
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```ts
|
|
65
|
+
* import { createSchemaValidator, createSimulatorClient } from '@my-swu/simulator-client'
|
|
66
|
+
*
|
|
67
|
+
* const simulatorClient = createSimulatorClient({
|
|
68
|
+
* baseUrl: 'http://127.0.0.1:4000',
|
|
69
|
+
* validate: createSchemaValidator(),
|
|
70
|
+
* })
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
validate?: SchemaValidator | undefined;
|
|
74
|
+
/**
|
|
75
|
+
* Optional WebSocket factory. Defaults to the global `WebSocket` when available.
|
|
76
|
+
*/
|
|
77
|
+
webSocketFactory?: WebSocketFactory;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Public typed client used to call simulator HTTP and WebSocket APIs.
|
|
81
|
+
*
|
|
82
|
+
* The client groups endpoints by workflow: system checks, card metadata, match
|
|
83
|
+
* lifecycle calls, Limited Events, and high-level match sessions.
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* ```ts
|
|
87
|
+
* import { createSimulatorClient } from '@my-swu/simulator-client'
|
|
88
|
+
*
|
|
89
|
+
* const simulatorClient = createSimulatorClient({
|
|
90
|
+
* baseUrl: 'http://127.0.0.1:4000',
|
|
91
|
+
* })
|
|
92
|
+
*
|
|
93
|
+
* const health = await simulatorClient.system.health()
|
|
94
|
+
* const requestedCardMetadata = await simulatorClient.cards.get([46102])
|
|
95
|
+
* console.log(health.status, requestedCardMetadata[0]?.title)
|
|
96
|
+
* ```
|
|
97
|
+
*
|
|
98
|
+
* @see https://simulator-sdk.my-swu.com/guide/client-api
|
|
99
|
+
*/
|
|
100
|
+
export interface SimulatorClient {
|
|
101
|
+
/**
|
|
102
|
+
* Simulator administration APIs.
|
|
103
|
+
*/
|
|
104
|
+
readonly admin: AdminResource;
|
|
105
|
+
/**
|
|
106
|
+
* Card metadata APIs.
|
|
107
|
+
*/
|
|
108
|
+
readonly cards: CardsResource;
|
|
109
|
+
/**
|
|
110
|
+
* Limited Event APIs.
|
|
111
|
+
*/
|
|
112
|
+
readonly limitedEvents: LimitedEventsResource;
|
|
113
|
+
/**
|
|
114
|
+
* Pre-match multiplayer lobby APIs.
|
|
115
|
+
*/
|
|
116
|
+
readonly lobbies: LobbiesResource;
|
|
117
|
+
/**
|
|
118
|
+
* Server-owned simulator history APIs.
|
|
119
|
+
*/
|
|
120
|
+
readonly matchHistory: MatchHistoryResource;
|
|
121
|
+
/**
|
|
122
|
+
* Match lifecycle APIs.
|
|
123
|
+
*/
|
|
124
|
+
readonly matches: MatchesResource;
|
|
125
|
+
/**
|
|
126
|
+
* High-level live match session APIs.
|
|
127
|
+
*/
|
|
128
|
+
readonly session: SessionResource;
|
|
129
|
+
/**
|
|
130
|
+
* System APIs.
|
|
131
|
+
*/
|
|
132
|
+
readonly system: SystemResource;
|
|
133
|
+
/**
|
|
134
|
+
* Tournament room APIs for sealed/draft events and duel tables.
|
|
135
|
+
*/
|
|
136
|
+
readonly tournamentRooms: TournamentRoomsResource;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Creates one typed simulator client.
|
|
140
|
+
*
|
|
141
|
+
* Use one client per simulator server origin. Payloads are returned as typed
|
|
142
|
+
* values without being checked at runtime; pass `validate` to have request
|
|
143
|
+
* bodies, responses and socket frames verified against the generated schemas.
|
|
144
|
+
*
|
|
145
|
+
* @example
|
|
146
|
+
* ```ts
|
|
147
|
+
* import { createSimulatorClient } from '@my-swu/simulator-client'
|
|
148
|
+
*
|
|
149
|
+
* const simulatorClient = createSimulatorClient({
|
|
150
|
+
* baseUrl: 'http://127.0.0.1:4000',
|
|
151
|
+
* })
|
|
152
|
+
*
|
|
153
|
+
* ```
|
|
154
|
+
*
|
|
155
|
+
* @see https://simulator-sdk.my-swu.com/guide/http-client
|
|
156
|
+
*/
|
|
157
|
+
export declare function createSimulatorClient(options: SimulatorClientOptions): SimulatorClient;
|