@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
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { EngineRequestAbortedError } from '../internal/abort-error.js';
|
|
2
|
+
import { EngineHttpError } from '../internal/errors.js';
|
|
3
|
+
import { passthroughValidator } from '../validators/validator.js';
|
|
4
|
+
import { createRequestAbortPlan, resolveRequestTimeoutMs } from './abort.js';
|
|
5
|
+
import { parseJsonForSchema } from './json.js';
|
|
6
|
+
/**
|
|
7
|
+
* Minimal HTTP helper shared by all SDK resources.
|
|
8
|
+
*
|
|
9
|
+
* Whether request bodies and responses are checked against the generated
|
|
10
|
+
* schemas is decided once, here, by the injected validator.
|
|
11
|
+
*/
|
|
12
|
+
export class EngineHttpRequester {
|
|
13
|
+
#baseUrl;
|
|
14
|
+
#defaultTimeoutMs;
|
|
15
|
+
#fetch;
|
|
16
|
+
#validator;
|
|
17
|
+
/**
|
|
18
|
+
* Creates one requester.
|
|
19
|
+
*/
|
|
20
|
+
constructor(options) {
|
|
21
|
+
this.#baseUrl = options.baseUrl;
|
|
22
|
+
this.#defaultTimeoutMs = options.defaultTimeoutMs;
|
|
23
|
+
this.#fetch = options.fetch;
|
|
24
|
+
this.#validator = options.validate ?? passthroughValidator;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Validates one outbound payload built by a resource method.
|
|
28
|
+
*
|
|
29
|
+
* Resources call this instead of `parseSchema` so a client without a
|
|
30
|
+
* validator neither pays for the check nor pulls the schema map into the
|
|
31
|
+
* bundle. With validation off it is the identity.
|
|
32
|
+
*
|
|
33
|
+
* @param schemaName Generated schema name the payload must match.
|
|
34
|
+
* @param value Payload about to be serialized into a request.
|
|
35
|
+
*/
|
|
36
|
+
validate(schemaName, value) {
|
|
37
|
+
return this.#validator.parse(schemaName, value);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Sends one request and validates the JSON response against one schema.
|
|
41
|
+
*
|
|
42
|
+
* `init` carries the transport shape owned by the calling resource method;
|
|
43
|
+
* `options` carries the caller's cancellation controls. Both the network call
|
|
44
|
+
* and the body read run under the composed signal, so a timeout also cancels
|
|
45
|
+
* a response that streams forever.
|
|
46
|
+
*/
|
|
47
|
+
async request(schemaName, pathname, init = {}, options = {}) {
|
|
48
|
+
const url = this.resolveUrl(pathname);
|
|
49
|
+
const method = init.method ?? 'GET';
|
|
50
|
+
const context = { method, url: url.toString() };
|
|
51
|
+
// An already-aborted caller signal never reaches the network.
|
|
52
|
+
if (options.signal?.aborted === true) {
|
|
53
|
+
throw new EngineRequestAbortedError('aborted', context);
|
|
54
|
+
}
|
|
55
|
+
const plan = createRequestAbortPlan(options.signal, resolveRequestTimeoutMs(options.timeoutMs, this.#defaultTimeoutMs));
|
|
56
|
+
let response;
|
|
57
|
+
let responseText;
|
|
58
|
+
try {
|
|
59
|
+
response = await this.#fetch(url, plan.signal == null ? init : { ...init, signal: plan.signal });
|
|
60
|
+
responseText = await response.text();
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
throw plan.abortErrorFor(context) ?? error;
|
|
64
|
+
}
|
|
65
|
+
finally {
|
|
66
|
+
plan.dispose();
|
|
67
|
+
}
|
|
68
|
+
// A fetch adapter that ignores `signal` still resolves after the deadline
|
|
69
|
+
// passed. Honour the cancellation the caller asked for either way.
|
|
70
|
+
const abortError = plan.abortErrorFor(context);
|
|
71
|
+
if (abortError != null) {
|
|
72
|
+
throw abortError;
|
|
73
|
+
}
|
|
74
|
+
if (!response.ok) {
|
|
75
|
+
throw this.#buildHttpError(response, responseText, method, url);
|
|
76
|
+
}
|
|
77
|
+
return this.#validator.parse(schemaName, parseJsonForSchema(schemaName, responseText));
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Resolves one API pathname against the configured base URL.
|
|
81
|
+
*/
|
|
82
|
+
resolveUrl(pathname) {
|
|
83
|
+
return new URL(pathname.replace(/^\//, ''), this.#baseUrl);
|
|
84
|
+
}
|
|
85
|
+
#buildHttpError(response, responseText, method, url) {
|
|
86
|
+
const parsed = parseOptionalJson(responseText);
|
|
87
|
+
const rawText = responseText === '' ? undefined : responseText;
|
|
88
|
+
if (parsed.ok) {
|
|
89
|
+
const apiError = this.#parseApiError(parsed.value);
|
|
90
|
+
if (apiError != null) {
|
|
91
|
+
return new EngineHttpError(apiError.error.message, {
|
|
92
|
+
code: apiError.error.code,
|
|
93
|
+
method,
|
|
94
|
+
payload: parsed.value,
|
|
95
|
+
responseText: rawText,
|
|
96
|
+
status: response.status,
|
|
97
|
+
url: url.toString(),
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return new EngineHttpError(`HTTP ${response.status} ${responseStatusText(response)}`, {
|
|
102
|
+
method,
|
|
103
|
+
payload: parsed.ok ? parsed.value : undefined,
|
|
104
|
+
responseText: rawText,
|
|
105
|
+
status: response.status,
|
|
106
|
+
url: url.toString(),
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Returns one API error payload, or `undefined` when the body's shape differs.
|
|
111
|
+
*
|
|
112
|
+
* The structural check runs in both modes on purpose. An error body is the
|
|
113
|
+
* one payload the SDK must never trust blindly: with validation off `parse`
|
|
114
|
+
* is the identity, and reading `error.message` off an arbitrary gateway error
|
|
115
|
+
* page would turn a server failure into a `TypeError`.
|
|
116
|
+
*/
|
|
117
|
+
#parseApiError(value) {
|
|
118
|
+
try {
|
|
119
|
+
return asApiErrorResponse(this.#validator.parse('api-error-response', value));
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
return undefined;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Returns browser status text or a concise fallback for test/runtime parity.
|
|
128
|
+
*/
|
|
129
|
+
function responseStatusText(response) {
|
|
130
|
+
if (response.statusText !== '') {
|
|
131
|
+
return response.statusText;
|
|
132
|
+
}
|
|
133
|
+
return statusTextByCode(response.status);
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Maps common HTTP status codes when runtime Response omits `statusText`.
|
|
137
|
+
*/
|
|
138
|
+
function statusTextByCode(status) {
|
|
139
|
+
switch (status) {
|
|
140
|
+
case 400:
|
|
141
|
+
return 'Bad Request';
|
|
142
|
+
case 401:
|
|
143
|
+
return 'Unauthorized';
|
|
144
|
+
case 403:
|
|
145
|
+
return 'Forbidden';
|
|
146
|
+
case 404:
|
|
147
|
+
return 'Not Found';
|
|
148
|
+
case 500:
|
|
149
|
+
return 'Internal Server Error';
|
|
150
|
+
case 503:
|
|
151
|
+
return 'Service Unavailable';
|
|
152
|
+
default:
|
|
153
|
+
return 'Error';
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Parses one optional JSON error body without throwing.
|
|
158
|
+
*/
|
|
159
|
+
function parseOptionalJson(responseText) {
|
|
160
|
+
if (responseText === '') {
|
|
161
|
+
return { ok: false };
|
|
162
|
+
}
|
|
163
|
+
try {
|
|
164
|
+
return { ok: true, value: JSON.parse(responseText) };
|
|
165
|
+
}
|
|
166
|
+
catch {
|
|
167
|
+
return { ok: false };
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Narrows one parsed body to an API error payload by shape alone.
|
|
172
|
+
*
|
|
173
|
+
* `api-error-response` is one required `error` object of two required strings,
|
|
174
|
+
* so this check is the schema for every field the SDK reads off it.
|
|
175
|
+
*/
|
|
176
|
+
function asApiErrorResponse(value) {
|
|
177
|
+
const error = value?.error;
|
|
178
|
+
if (typeof error?.code !== 'string' || typeof error.message !== 'string') {
|
|
179
|
+
return undefined;
|
|
180
|
+
}
|
|
181
|
+
return value;
|
|
182
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { EngineHttpRequester } from './request.js';
|
|
2
|
+
import type { SchemaTypeMap } from '../validators.js';
|
|
3
|
+
/**
|
|
4
|
+
* Creates validated JSON POST request initializers bound to one SDK requester.
|
|
5
|
+
*
|
|
6
|
+
* Resource modules retain their public methods while sharing their request
|
|
7
|
+
* validation and JSON serialization boundary.
|
|
8
|
+
*/
|
|
9
|
+
export declare function createValidatedJsonPost(requester: EngineHttpRequester): <TName extends keyof SchemaTypeMap>(schemaName: TName, body: unknown) => RequestInit;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { jsonBody, jsonHeaders } from './json.js';
|
|
2
|
+
/**
|
|
3
|
+
* Creates validated JSON POST request initializers bound to one SDK requester.
|
|
4
|
+
*
|
|
5
|
+
* Resource modules retain their public methods while sharing their request
|
|
6
|
+
* validation and JSON serialization boundary.
|
|
7
|
+
*/
|
|
8
|
+
export function createValidatedJsonPost(requester) {
|
|
9
|
+
return (schemaName, body) => ({
|
|
10
|
+
body: jsonBody(requester.validate(schemaName, body)),
|
|
11
|
+
headers: jsonHeaders(),
|
|
12
|
+
method: 'POST',
|
|
13
|
+
});
|
|
14
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export { createSimulatorClient } from './client.js';
|
|
2
|
+
export type * from './generated/public-types.js';
|
|
3
|
+
export type { AdminResource, RankedLeaderboardOptions, SimulatorAdminAuth, } from './resources/admin.js';
|
|
4
|
+
export type { AddLobbyAiPlayerRequest, CreateLobbyRequest, JoinLobbyRequest, KickLobbyPlayerRequest, KickLobbySpectatorRequest, LeaveLobbyRequest, LobbiesResource, LobbyAccessInput, LobbyAccessResponse, LobbyChatMessage, LobbyChatRequest, LobbyChatResponse, LobbyConfig, LobbyDeckPreview, LobbyDeckSetPreview, LobbyKickedPayload, LobbyListAutoReconnect, LobbyListResponse, LobbyListServerMessage, LobbyListSession, LobbyListSessionEvents, LobbyListSessionOptions, LobbyListSessionState, LobbyMatchmakingDecisionRequest, LobbyMatchmakingKind, LobbyMatchmakingView, LobbyParticipantRole, LobbyPlayerController, PlayerPresenceStatus, RoomPlayerPresenceEvent, LobbyPlayerView, LobbyPrivateAiPlayerView, LobbyPrivateView, LobbyRemovalReason, LobbyResponse, LobbyServerMessage, LobbySession, LobbySessionEvents, LobbySnapshot, LobbySpectatorView, LobbyStartedAccess, LobbyStatus, LobbySyncRequest, LobbyVisibility, PrepareLobbyLimitedAiDecksRequest, PublicLobbySummary, LobbyMatchmakingConfig, LobbyMatchmakingRequest, ReturnLobbyMatchRequest, StartLobbyLimitedMatchRequest, StartLobbyRequest, SpectateLobbyRequest, SubmitLobbyLimitedDeckRequest, UpdateLobbyAiPlayerRequest, UpdateLobbyPlayerRequest, UpdateLobbySettingsRequest, } from './resources/lobbies.js';
|
|
5
|
+
export type { CloseTournamentRoomRequest, CreateTournamentRoomRequest, CreateTournamentTableRequest, JoinTournamentRoomRequest, JoinTournamentTableRequest, LeaveTournamentRoomRequest, PublicTournamentRoomSummary, ReturnTournamentMatchRequest, StartTournamentEventRequest, SubmitTournamentDeckRequest, TournamentEventCommandRequest, TournamentRoomsResource, TournamentRoomAccessInput, TournamentRoomAccessResponse, TournamentRoomChatRequest, TournamentRoomChatResponse, TournamentRoomListResponse, TournamentRoomResponse, TournamentRoomServerMessage, TournamentRoomSession, TournamentRoomSessionEvents, TournamentRoomSnapshot, TournamentRoomSyncRequest, UpdateTournamentRoomPlayerRequest, UpdateTournamentRoomSettingsRequest, } from './resources/tournament-rooms.js';
|
|
6
|
+
export { canDeployAnyLeader, flattenTargetGroups, getDeployableLeaderIndices, getLeaderDeployCommands, isSingleTargetPlan, leaderDeployCommand, targetGroupsOf, } from './actionable.js';
|
|
7
|
+
export type { TargetingActionView } from './actionable.js';
|
|
8
|
+
export type { SimulatorClient, SimulatorClientOptions } from './client.js';
|
|
9
|
+
export type { AbandonMatchRequest, AbandonMatchResponse, ApiErrorResponse, AiStatusPayload, CardsResponse, CardCatalogRefreshResponse, ClientMessage, CreateLimitedEventRequest, CreateMetaWindowRequest, CreateMatchRequest, ErrorPayload, FormatEventResponse, FormatEventRequest, GameCommand, GameEvent, GameState, GetMatchResponse, HealthResponse, JoinLimitedEventRequest, JoinMatchRequest, LeaveMatchRequest, LeaveMatchResponse, LimitedEventAccessResponse, LimitedEventCommandRequest, LimitedEventPreflightResponse, LimitedEventResponse, ListActiveAiMatchesRequest, ListActiveAiMatchesResponse, MatchAccessResponse, MatchChatLookupResponse, MatchConnectionRole, MatchHistoryDeckStatsRequest, MatchHistoryDeckStatsResponse, MatchHistoryListRequest, MatchHistoryListResponse, MatchHistoryReplayRequest, MatchHistoryReplayResponse, MatchHistoryRestoreRequest, RestoreHistoryResponse, MatchSavePayload, MatchSpectatorAccessResponse, MetaWindow, MetaWindowsResponse, ResolveCardIdsRequest, ResolveCardIdsResponse, RankedAdminStatus, RankedLeaderboardEntry, RankedLeaderboardQuery, RankedLeaderboardResponse, RankedMatchmakingView, RankedProfileRequest, RankedProfileResponse, RankedQueue, RematchMatchRequest, RematchMatchResponse, RestoreMatchSaveRequest, RestoreMatchSaveResponse, SaveMatchRequest, ServerMessage, SetAiPausedRequest, SetRankedAdmissionRequest, SetSimulatorMaintenanceRequest, SimulatorAdminStatusResponse, SimulatorAvailabilityResponse, SpectateMatchRequest, SubmitMatchDeckRequest, SubmitMatchDeckResponse, UndoMatchRequest, UndoMatchResponse, UndoRespondMatchRequest, WelcomePayload, } from './generated/index.js';
|
|
10
|
+
export type { UndoCancelReason } from './generated/types/game-event.js';
|
|
11
|
+
export type { LimitedSideboardPoolView } from './generated/types/game-state.js';
|
|
12
|
+
export type { HistoryIdentityInput, HistorySection, HistoryStatus, } from './generated/types/match-history-list-request.js';
|
|
13
|
+
export type { MatchHistoryEntry, MatchHistoryPlayerSummary, } from './generated/types/match-history-entry.js';
|
|
14
|
+
export type { MatchHistoryReplayArchive } from './generated/types/match-history-replay-response.js';
|
|
15
|
+
export type { DeckArchetype, DeckArchetypeMatchup, DeckEndReasonCount, DeckFormatStats, DeckOpponentStats, DeckStats, DeckStatsArchetype, DeckStatsOpponentKind, WinLossDrawRecord, } from './generated/types/match-history-deck-stats-response.js';
|
|
16
|
+
export { schemaVersion } from './generated/version.js';
|
|
17
|
+
export type { FormatEventCommand } from './generated/types/format-event-request.js';
|
|
18
|
+
export { EngineHttpError, SdkValidationError, SimulatorSocketError, SIMULATOR_REJECTION_CLOSE_CODE, } from './internal/errors.js';
|
|
19
|
+
export type { EngineHttpErrorOptions, SimulatorSocketErrorKind, WebSocketCloseInfo, } from './internal/errors.js';
|
|
20
|
+
export { EngineRequestAbortedError } from './internal/abort-error.js';
|
|
21
|
+
export type { EngineRequestAbortKind, EngineRequestAbortedErrorOptions, } from './internal/abort-error.js';
|
|
22
|
+
export type { SimulatorRequestOptions } from './http/options.js';
|
|
23
|
+
export type { EngineWebSocket, FetchLike, WebSocketFactory } from './internal/transport.js';
|
|
24
|
+
export { aiFormatEventMessage, commandMessage, formatEventMessage, interactionCueMessage, pingMessage, readyMessage, setAiPausedMessage, syncRequestMessage, undoMessage, undoResponseMessage, chatMessage, } from './messages.js';
|
|
25
|
+
export type { CardInteractionCueRequest, } from './generated/types/client-message.js';
|
|
26
|
+
export type { CardInteractionCue, CardInteractionCueKind, CardInteractionCueState, CardInteractionDragOffset, MatchChatMessage, MatchHistoryFeedEntry, MatchHistorySnapshot, MatchQuickPhrase, } from './generated/types/server-message.js';
|
|
27
|
+
export type { CardIdResolution, CardMetadata, CardReferenceInput, CardReferenceType, DeckInput, DeckJson, DeckJsonCard, } from './resources/card-types.js';
|
|
28
|
+
export type { CardsResource } from './resources/card-resource.js';
|
|
29
|
+
export type { LimitedEventAccess, LimitedEventAccessInput, LimitedEventCommand, LimitedEventPreflight, LimitedEventReference, LimitedEventSnapshot, LimitedEventsResource, } from './resources/limited-events.js';
|
|
30
|
+
export type { MatchHistoryResource, MatchHistoryReplayInput, MatchHistoryRestoreInput, } from './resources/match-history.js';
|
|
31
|
+
export type { MatchAccess, MatchAccessInput, MatchConnectionAccessInput, MatchReference, MatchSpectatorAccess, MatchSpectatorAccessInput, MatchesResource, } from './resources/matches.js';
|
|
32
|
+
export type { SessionResource } from './resources/session.js';
|
|
33
|
+
export type { SystemResource } from './resources/system.js';
|
|
34
|
+
export type { MatchSeat, MatchSession, MatchSessionAccess, MatchSessionAutoReconnectOptions, MatchSessionAutoReconnectPolicy, MatchSessionConnectOptions, MatchSessionEvents, MatchSessionOptions, MatchSessionReconnectState, MatchSessionSnapshotPredicate, MatchSessionState, MatchSessionWaitOptions, } from './match-session.js';
|
|
35
|
+
export type { ConnectionState, PongPayload } from './session.js';
|
|
36
|
+
export { createSchemaValidator, parseSchema } from './validators.js';
|
|
37
|
+
export type { SchemaTypeMap } from './validators.js';
|
|
38
|
+
export type { SchemaValidator } from './validators/validator.js';
|
|
39
|
+
export type { AbilityTarget, AbilityWindow, ActionAbilitySource, ActionAbilityView, ActiveAiMatchLimitScope, ActiveAiMatchRecoveryEntry, ActiveEffectDescriptionView, ActiveEffectView, AiDifficulty, AiOpponentConfig, AiSeatStatusPayload, AiTrilogyFormatMode, AspectCount, AttachmentMode, AttackChoiceView, AttackTarget, AvailableAttackView, CapturedUnitView, CaptureOptionsView, CaptureSelection, CardArena, CardChoiceResourcePaymentOptionView, CardDrawSource, CardInstanceView, CardReferenceMatchView, CloseTournamentRoomActiveMatches, ConstructedFormat, CurrentAttackStateView, CurrentAttackView, DeckRegistrationView, DelayedEffectDescriptionView, DelayedEffectTimingView, DelayedEffectView, DistributionAssignment, DistributionDamageKindView, DistributionItemView, DistributionTargetView, DistributionTokenKindView, DraftRoundConfig, DynamicPowerLimit, EffectCardScopeView, EffectDurationView, EffectRestrictionView, EffectSourceView, EffectTargetView, ExploitOptionsView, FormatSeatView, FormatSetupInput, GameTimerActiveClockView, GameTimerReserveView, GameTimerStateView, HiddenCardChoiceMode, HiddenZoneKind, InitiativeChoiceReason, InitiativeState, InstructedAttackView, LeaderActionView, LeaderDeployActionView, LeaderDeployCostView, LeaderDeployMode, LeaderDeployThresholdBonus, LeaderStateView, LimitedCardSlot, LimitedCardTreatment, LimitedDeckSourceView, LimitedEventKind, LimitedEventPhaseView, LimitedEventPreflightIssue, LimitedEventSeatView, LimitedEventView, LimitedEventViewerView, LimitedPackCardView, LobbyWelcomePayload, MaintenanceStatus, MatchEndReason, MatchFormat, MatchHistoryDeckSummary, MatchPhase, MatchResult, MatchSaveSeat, MatchScenarioInput, MatchSeriesView, MatchStatus, MctsConfigOverride, ModeChoiceView, NamedCardEffectDescriptionView, PendingAbilityAspectChoiceView, PendingAbilityAttackChoiceView, PendingAbilityCardChoiceView, PendingAbilityFamily, PendingAbilityModeChoiceView, PendingAbilityNameChoiceView, PendingAbilityOrderAbilityView, PendingAbilityOrderChoiceView, PendingAbilityOrderGroupView, PendingAbilityView, PendingChoiceView, PendingDistributionView, PendingUndoRequest, PlayActionView, PlayCardSourceView, PlayCardZone, PlayerTargetPattern, PresenceFilter, PromptShape, PromptState, RejectedPlayView, RelationFilter, ResourceCardView, ResourcePaymentOptionView, Seat, SeatDirection, SeatOfferIntent, SeatState, SelectionScope, SeriesEndReason, SeriesGameRecord, SeriesResultView, SharedCounterState, SimulatorRuntimeStats, SmuggleActionView, SmuggleKind, TargetGroupPurpose, TargetSelectionGroup, TargetSelectionPlanView, TournamentRoomMatchReadyPayload, TournamentRoomPlayerView, TournamentRoomPrivateView, TournamentRoomStatus, TournamentRoomWelcomePayload, TournamentTableStatus, TournamentTableView, TriggerWindowView, TurnPassSource, TwinSunsCounter, TwinSunsCountersView, UndoRequestReason, UniquenessFilter, UnitAbilitySuppressionView, UnitCopiedCardEntry, UnitDefeatCause, UnitExtremum, UnitFilter, UnitStateView, UpgradeStateView, } from './types.js';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export { createSimulatorClient } from './client.js';
|
|
2
|
+
export { canDeployAnyLeader, flattenTargetGroups, getDeployableLeaderIndices, getLeaderDeployCommands, isSingleTargetPlan, leaderDeployCommand, targetGroupsOf, } from './actionable.js';
|
|
3
|
+
// Routed through the standalone version module on purpose: re-exporting it
|
|
4
|
+
// from `./generated/schemas.js` would drag the multi-MB schema map into every
|
|
5
|
+
// consumer that only needs the wire marker.
|
|
6
|
+
export { schemaVersion } from './generated/version.js';
|
|
7
|
+
export { EngineHttpError, SdkValidationError, SimulatorSocketError, SIMULATOR_REJECTION_CLOSE_CODE, } from './internal/errors.js';
|
|
8
|
+
export { EngineRequestAbortedError } from './internal/abort-error.js';
|
|
9
|
+
export { aiFormatEventMessage, commandMessage, formatEventMessage, interactionCueMessage, pingMessage, readyMessage, setAiPausedMessage, syncRequestMessage, undoMessage, undoResponseMessage, chatMessage, } from './messages.js';
|
|
10
|
+
export { createSchemaValidator, parseSchema } from './validators.js';
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Why one simulator HTTP request stopped before the server answered.
|
|
3
|
+
*
|
|
4
|
+
* - `aborted`: the caller's own `AbortSignal` fired.
|
|
5
|
+
* - `timeout`: the per-call or client-level timeout elapsed first.
|
|
6
|
+
*
|
|
7
|
+
* When a caller passes both a signal and a timeout, whichever fired first
|
|
8
|
+
* names the kind.
|
|
9
|
+
*/
|
|
10
|
+
export type EngineRequestAbortKind = 'aborted' | 'timeout';
|
|
11
|
+
/**
|
|
12
|
+
* Context captured for one cancelled HTTP request.
|
|
13
|
+
*
|
|
14
|
+
* These fields mirror {@link EngineHttpErrorOptions} so a UI can log both
|
|
15
|
+
* failure channels the same way.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```ts
|
|
19
|
+
* import type { EngineRequestAbortedErrorOptions } from '@my-swu/simulator-client'
|
|
20
|
+
*
|
|
21
|
+
* const timedOutOptions: EngineRequestAbortedErrorOptions = {
|
|
22
|
+
* method: 'GET',
|
|
23
|
+
* timeoutMs: 5_000,
|
|
24
|
+
* url: 'http://127.0.0.1:4000/api/matches/match_123',
|
|
25
|
+
* }
|
|
26
|
+
*
|
|
27
|
+
* console.log(timedOutOptions.timeoutMs)
|
|
28
|
+
* ```
|
|
29
|
+
*
|
|
30
|
+
* @see https://simulator-sdk.my-swu.com/guide/errors
|
|
31
|
+
*/
|
|
32
|
+
export interface EngineRequestAbortedErrorOptions {
|
|
33
|
+
/**
|
|
34
|
+
* HTTP method used for the cancelled request.
|
|
35
|
+
*/
|
|
36
|
+
method?: string | undefined;
|
|
37
|
+
/**
|
|
38
|
+
* Timeout that applied to the request, when one did.
|
|
39
|
+
*/
|
|
40
|
+
timeoutMs?: number | undefined;
|
|
41
|
+
/**
|
|
42
|
+
* Fully resolved request URL.
|
|
43
|
+
*/
|
|
44
|
+
url?: string | undefined;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Error thrown when a simulator HTTP request is cancelled before it answers.
|
|
48
|
+
*
|
|
49
|
+
* This is the fourth SDK failure channel next to `EngineHttpError` (the server
|
|
50
|
+
* answered with a non-2xx status), `SdkValidationError` (a payload did not
|
|
51
|
+
* match the schema), and `SimulatorSocketError` (a socket failed). Read
|
|
52
|
+
* [`kind`](#) to tell a caller-initiated abort from a timeout.
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```ts
|
|
56
|
+
* import { EngineRequestAbortedError, createSimulatorClient } from '@my-swu/simulator-client'
|
|
57
|
+
*
|
|
58
|
+
* const simulatorClient = createSimulatorClient({ baseUrl: 'http://127.0.0.1:4000' })
|
|
59
|
+
*
|
|
60
|
+
* try {
|
|
61
|
+
* await simulatorClient.system.health({ timeoutMs: 2_000 })
|
|
62
|
+
* }
|
|
63
|
+
* catch (error) {
|
|
64
|
+
* if (error instanceof EngineRequestAbortedError && error.kind === 'timeout') {
|
|
65
|
+
* console.warn('health check timed out after', error.timeoutMs)
|
|
66
|
+
* }
|
|
67
|
+
* }
|
|
68
|
+
* ```
|
|
69
|
+
*
|
|
70
|
+
* @see https://simulator-sdk.my-swu.com/guide/errors
|
|
71
|
+
*/
|
|
72
|
+
export declare class EngineRequestAbortedError extends Error {
|
|
73
|
+
/**
|
|
74
|
+
* Stable classification of the cancellation.
|
|
75
|
+
*/
|
|
76
|
+
readonly kind: EngineRequestAbortKind;
|
|
77
|
+
/**
|
|
78
|
+
* HTTP method used for the cancelled request.
|
|
79
|
+
*/
|
|
80
|
+
readonly method: string | undefined;
|
|
81
|
+
/**
|
|
82
|
+
* Timeout that applied to the request, when one did.
|
|
83
|
+
*/
|
|
84
|
+
readonly timeoutMs: number | undefined;
|
|
85
|
+
/**
|
|
86
|
+
* Fully resolved request URL.
|
|
87
|
+
*/
|
|
88
|
+
readonly url: string | undefined;
|
|
89
|
+
/** Creates one classified cancellation error with its request context. */
|
|
90
|
+
constructor(kind: EngineRequestAbortKind, options?: EngineRequestAbortedErrorOptions);
|
|
91
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error thrown when a simulator HTTP request is cancelled before it answers.
|
|
3
|
+
*
|
|
4
|
+
* This is the fourth SDK failure channel next to `EngineHttpError` (the server
|
|
5
|
+
* answered with a non-2xx status), `SdkValidationError` (a payload did not
|
|
6
|
+
* match the schema), and `SimulatorSocketError` (a socket failed). Read
|
|
7
|
+
* [`kind`](#) to tell a caller-initiated abort from a timeout.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* import { EngineRequestAbortedError, createSimulatorClient } from '@my-swu/simulator-client'
|
|
12
|
+
*
|
|
13
|
+
* const simulatorClient = createSimulatorClient({ baseUrl: 'http://127.0.0.1:4000' })
|
|
14
|
+
*
|
|
15
|
+
* try {
|
|
16
|
+
* await simulatorClient.system.health({ timeoutMs: 2_000 })
|
|
17
|
+
* }
|
|
18
|
+
* catch (error) {
|
|
19
|
+
* if (error instanceof EngineRequestAbortedError && error.kind === 'timeout') {
|
|
20
|
+
* console.warn('health check timed out after', error.timeoutMs)
|
|
21
|
+
* }
|
|
22
|
+
* }
|
|
23
|
+
* ```
|
|
24
|
+
*
|
|
25
|
+
* @see https://simulator-sdk.my-swu.com/guide/errors
|
|
26
|
+
*/
|
|
27
|
+
export class EngineRequestAbortedError extends Error {
|
|
28
|
+
/**
|
|
29
|
+
* Stable classification of the cancellation.
|
|
30
|
+
*/
|
|
31
|
+
kind;
|
|
32
|
+
/**
|
|
33
|
+
* HTTP method used for the cancelled request.
|
|
34
|
+
*/
|
|
35
|
+
method;
|
|
36
|
+
/**
|
|
37
|
+
* Timeout that applied to the request, when one did.
|
|
38
|
+
*/
|
|
39
|
+
timeoutMs;
|
|
40
|
+
/**
|
|
41
|
+
* Fully resolved request URL.
|
|
42
|
+
*/
|
|
43
|
+
url;
|
|
44
|
+
/** Creates one classified cancellation error with its request context. */
|
|
45
|
+
constructor(kind, options = {}) {
|
|
46
|
+
super(engineRequestAbortMessage(kind, options.timeoutMs));
|
|
47
|
+
this.name = 'EngineRequestAbortedError';
|
|
48
|
+
this.kind = kind;
|
|
49
|
+
this.method = options.method;
|
|
50
|
+
this.timeoutMs = options.timeoutMs;
|
|
51
|
+
this.url = options.url;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/** Human-readable developer message for one cancellation kind. */
|
|
55
|
+
function engineRequestAbortMessage(kind, timeoutMs) {
|
|
56
|
+
if (kind === 'aborted') {
|
|
57
|
+
return 'request aborted by the caller';
|
|
58
|
+
}
|
|
59
|
+
return timeoutMs == null
|
|
60
|
+
? 'request timed out'
|
|
61
|
+
: `request timed out after ${timeoutMs}ms`;
|
|
62
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { WebSocketFactory } from './transport.js';
|
|
2
|
+
import { type WebSocketCloseInfo } from './errors.js';
|
|
3
|
+
import type { SocketFrameSchemaName } from './socket-frame.js';
|
|
4
|
+
import type { ConnectionState } from '../session.js';
|
|
5
|
+
import type { SchemaValidator } from '../validators/validator.js';
|
|
6
|
+
/** Events every authenticated room socket session emits. */
|
|
7
|
+
export interface AuthenticatedSocketSessionEvents<TMessage, TSnapshot, TError> {
|
|
8
|
+
change: AuthenticatedSocketSessionState<TSnapshot, TError>;
|
|
9
|
+
connectionState: ConnectionState;
|
|
10
|
+
error: TError;
|
|
11
|
+
message: TMessage;
|
|
12
|
+
snapshot: TSnapshot;
|
|
13
|
+
}
|
|
14
|
+
/** Shared observable state for authenticated room socket sessions. */
|
|
15
|
+
export interface AuthenticatedSocketSessionState<TSnapshot, TError> {
|
|
16
|
+
connectionState: ConnectionState;
|
|
17
|
+
errors: readonly TError[];
|
|
18
|
+
snapshot: TSnapshot | undefined;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Lifecycle shared by authenticated lobby-like sockets.
|
|
22
|
+
*
|
|
23
|
+
* Subclasses only route their protocol-specific server messages, naming the
|
|
24
|
+
* generated schema those messages must match; decoding and validating the
|
|
25
|
+
* frame is done here, once, so every room socket answers a malformed known
|
|
26
|
+
* frame the same way the match socket does. Tokens always travel through the
|
|
27
|
+
* WebSocket subprotocol list instead of the connection URL.
|
|
28
|
+
*/
|
|
29
|
+
export declare abstract class AuthenticatedSocketSessionController<TMessage, TSnapshot, TError extends {
|
|
30
|
+
code: string;
|
|
31
|
+
message: string;
|
|
32
|
+
}, TEvents extends AuthenticatedSocketSessionEvents<TMessage, TSnapshot, TError>> {
|
|
33
|
+
#private;
|
|
34
|
+
readonly __v_skip = true;
|
|
35
|
+
protected constructor(options: {
|
|
36
|
+
/** Generated schema every inbound frame of this protocol must match. */
|
|
37
|
+
messageSchema: SocketFrameSchemaName;
|
|
38
|
+
playerToken: string;
|
|
39
|
+
socketError: (info: WebSocketCloseInfo) => TError;
|
|
40
|
+
socketUrl: string;
|
|
41
|
+
/** Boundary validator; defaults to the pass-through, which checks nothing. */
|
|
42
|
+
validate?: SchemaValidator | undefined;
|
|
43
|
+
webSocketFactory: WebSocketFactory;
|
|
44
|
+
});
|
|
45
|
+
get connectionState(): ConnectionState;
|
|
46
|
+
get errorMessages(): readonly string[];
|
|
47
|
+
get errors(): readonly TError[];
|
|
48
|
+
get snapshot(): TSnapshot | undefined;
|
|
49
|
+
connect(): Promise<this>;
|
|
50
|
+
close(): void;
|
|
51
|
+
on<TKey extends keyof TEvents>(event: TKey, listener: (value: TEvents[TKey]) => void): () => void;
|
|
52
|
+
ping(nonce?: string): void;
|
|
53
|
+
/** Emits one protocol-specific event from a subclass message router. */
|
|
54
|
+
protected emit<TKey extends keyof TEvents>(event: TKey, value: TEvents[TKey]): void;
|
|
55
|
+
/** Stores and emits a protocol snapshot from a subclass message router. */
|
|
56
|
+
protected setSnapshot(snapshot: TSnapshot): void;
|
|
57
|
+
/** Stores and emits a protocol error from a subclass message router. */
|
|
58
|
+
protected pushError(error: TError): void;
|
|
59
|
+
/** Routes one parsed server message into protocol-specific events. */
|
|
60
|
+
protected abstract handleServerMessage(message: TMessage): void;
|
|
61
|
+
}
|
|
62
|
+
/** Builds a token-free authenticated room socket URL. */
|
|
63
|
+
export declare function authenticatedSocketUrl(base: string, path: string): string;
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { TypedEmitter } from './emitter.js';
|
|
2
|
+
import { websocketCloseInfo } from './websocket-event.js';
|
|
3
|
+
import { SIMULATOR_REJECTION_CLOSE_CODE } from './errors.js';
|
|
4
|
+
import { DEFAULT_ERROR_HISTORY_LIMIT } from './limits.js';
|
|
5
|
+
import { decodeSocketFrame } from './socket-frame.js';
|
|
6
|
+
import { playerTokenProtocols } from '../connection/url.js';
|
|
7
|
+
import { passthroughValidator } from '../validators/validator.js';
|
|
8
|
+
/**
|
|
9
|
+
* Lifecycle shared by authenticated lobby-like sockets.
|
|
10
|
+
*
|
|
11
|
+
* Subclasses only route their protocol-specific server messages, naming the
|
|
12
|
+
* generated schema those messages must match; decoding and validating the
|
|
13
|
+
* frame is done here, once, so every room socket answers a malformed known
|
|
14
|
+
* frame the same way the match socket does. Tokens always travel through the
|
|
15
|
+
* WebSocket subprotocol list instead of the connection URL.
|
|
16
|
+
*/
|
|
17
|
+
export class AuthenticatedSocketSessionController {
|
|
18
|
+
__v_skip = true;
|
|
19
|
+
#emitter = new TypedEmitter();
|
|
20
|
+
#messageSchema;
|
|
21
|
+
#socketError;
|
|
22
|
+
#socketUrl;
|
|
23
|
+
#validator;
|
|
24
|
+
#webSocketFactory;
|
|
25
|
+
#connectionState = 'idle';
|
|
26
|
+
#errors = [];
|
|
27
|
+
/** Previous live socket held until its replacement has opened. */
|
|
28
|
+
#replacedSocket;
|
|
29
|
+
#socket;
|
|
30
|
+
#snapshot;
|
|
31
|
+
constructor(options) {
|
|
32
|
+
this.#messageSchema = options.messageSchema;
|
|
33
|
+
this.#socketError = options.socketError;
|
|
34
|
+
this.#socketUrl = options.socketUrl;
|
|
35
|
+
this.#validator = options.validate ?? passthroughValidator;
|
|
36
|
+
this.#webSocketFactory = options.webSocketFactory;
|
|
37
|
+
this.#playerToken = options.playerToken;
|
|
38
|
+
}
|
|
39
|
+
#playerToken;
|
|
40
|
+
get connectionState() {
|
|
41
|
+
return this.#connectionState;
|
|
42
|
+
}
|
|
43
|
+
get errorMessages() {
|
|
44
|
+
return this.#errors.map(error => `${error.code} - ${error.message}`);
|
|
45
|
+
}
|
|
46
|
+
get errors() {
|
|
47
|
+
return [...this.#errors];
|
|
48
|
+
}
|
|
49
|
+
get snapshot() {
|
|
50
|
+
return this.#snapshot;
|
|
51
|
+
}
|
|
52
|
+
async connect() {
|
|
53
|
+
// Keep current room socket open until replacement reaches `open`. This
|
|
54
|
+
// makes a recovery handoff one logical presence on server, rather than a
|
|
55
|
+
// final disconnect followed by reconnect.
|
|
56
|
+
this.#replacedSocket?.close();
|
|
57
|
+
const previousSocket = this.#socket;
|
|
58
|
+
this.#replacedSocket = previousSocket;
|
|
59
|
+
this.#setConnectionState('connecting');
|
|
60
|
+
const socket = this.#webSocketFactory(this.#socketUrl, playerTokenProtocols(this.#playerToken));
|
|
61
|
+
this.#socket = socket;
|
|
62
|
+
let opened = false;
|
|
63
|
+
socket.addEventListener('open', () => {
|
|
64
|
+
if (this.#socket !== socket)
|
|
65
|
+
return;
|
|
66
|
+
opened = true;
|
|
67
|
+
this.#setConnectionState('open');
|
|
68
|
+
const replaced = this.#replacedSocket;
|
|
69
|
+
this.#replacedSocket = undefined;
|
|
70
|
+
replaced?.close();
|
|
71
|
+
});
|
|
72
|
+
socket.addEventListener('close', (event) => {
|
|
73
|
+
if (this.#socket !== socket)
|
|
74
|
+
return;
|
|
75
|
+
// The replacement never opened, so old socket cannot be retained.
|
|
76
|
+
// Closing it makes the following disconnect truthful rather than leaked.
|
|
77
|
+
if (!opened) {
|
|
78
|
+
const replaced = this.#replacedSocket;
|
|
79
|
+
this.#replacedSocket = undefined;
|
|
80
|
+
replaced?.close();
|
|
81
|
+
}
|
|
82
|
+
this.#setConnectionState('closed');
|
|
83
|
+
// The server refuses user-relevant connections by completing the
|
|
84
|
+
// upgrade and closing with the rejection code — surface that refusal
|
|
85
|
+
// (with the engine error code in the reason) instead of losing it.
|
|
86
|
+
const info = websocketCloseInfo(event);
|
|
87
|
+
if (info.closeCode === SIMULATOR_REJECTION_CLOSE_CODE) {
|
|
88
|
+
this.pushError(this.#socketError(info));
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
// Transport `error` events are opaque; they carry no code or message.
|
|
92
|
+
socket.addEventListener('error', () => {
|
|
93
|
+
if (this.#socket === socket)
|
|
94
|
+
this.pushError(this.#socketError({}));
|
|
95
|
+
});
|
|
96
|
+
socket.addEventListener('message', (event) => {
|
|
97
|
+
if (this.#socket === socket)
|
|
98
|
+
this.#handleMessage(event);
|
|
99
|
+
});
|
|
100
|
+
return this;
|
|
101
|
+
}
|
|
102
|
+
close() {
|
|
103
|
+
const socket = this.#socket;
|
|
104
|
+
const replaced = this.#replacedSocket;
|
|
105
|
+
this.#socket = undefined;
|
|
106
|
+
this.#replacedSocket = undefined;
|
|
107
|
+
socket?.close();
|
|
108
|
+
replaced?.close();
|
|
109
|
+
this.#setConnectionState('closed');
|
|
110
|
+
}
|
|
111
|
+
on(event, listener) {
|
|
112
|
+
return this.#emitter.on(event, listener);
|
|
113
|
+
}
|
|
114
|
+
ping(nonce) {
|
|
115
|
+
this.#socket?.send(JSON.stringify({ type: 'ping', payload: { nonce } }));
|
|
116
|
+
}
|
|
117
|
+
/** Emits one protocol-specific event from a subclass message router. */
|
|
118
|
+
emit(event, value) {
|
|
119
|
+
this.#emitter.emit(event, value);
|
|
120
|
+
}
|
|
121
|
+
/** Stores and emits a protocol snapshot from a subclass message router. */
|
|
122
|
+
setSnapshot(snapshot) {
|
|
123
|
+
this.#snapshot = snapshot;
|
|
124
|
+
this.emit('snapshot', snapshot);
|
|
125
|
+
this.#emitChange();
|
|
126
|
+
}
|
|
127
|
+
/** Stores and emits a protocol error from a subclass message router. */
|
|
128
|
+
pushError(error) {
|
|
129
|
+
// Bounded: a flapping room socket pushes one error per failed attempt.
|
|
130
|
+
this.#errors = [...this.#errors, error].slice(-DEFAULT_ERROR_HISTORY_LIMIT);
|
|
131
|
+
this.emit('error', error);
|
|
132
|
+
this.#emitChange();
|
|
133
|
+
}
|
|
134
|
+
#handleMessage(event) {
|
|
135
|
+
// The schema name is protocol-specific, so the decoded shapes are erased to
|
|
136
|
+
// this session's `TMessage` / `TError` — the subclass pairing them is what
|
|
137
|
+
// ties `messageSchema` to the message and error types it routes.
|
|
138
|
+
const decoded = decodeSocketFrame(event, this.#validator, this.#messageSchema);
|
|
139
|
+
if (decoded.type === 'ignored')
|
|
140
|
+
return;
|
|
141
|
+
// A malformed known frame is a contract violation, but a socket `message`
|
|
142
|
+
// listener is the wrong place to throw from: it escapes into the transport
|
|
143
|
+
// instead of reaching the consumer. Report it on the session's own error
|
|
144
|
+
// channel, exactly as the match socket does.
|
|
145
|
+
if (decoded.type === 'error') {
|
|
146
|
+
this.pushError(decoded.error);
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
const message = decoded.message;
|
|
150
|
+
this.emit('message', message);
|
|
151
|
+
this.handleServerMessage(message);
|
|
152
|
+
}
|
|
153
|
+
#setConnectionState(state) {
|
|
154
|
+
this.#connectionState = state;
|
|
155
|
+
this.emit('connectionState', state);
|
|
156
|
+
this.#emitChange();
|
|
157
|
+
}
|
|
158
|
+
#emitChange() {
|
|
159
|
+
this.emit('change', {
|
|
160
|
+
connectionState: this.#connectionState,
|
|
161
|
+
errors: this.errors,
|
|
162
|
+
snapshot: this.#snapshot,
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
/** Builds a token-free authenticated room socket URL. */
|
|
167
|
+
export function authenticatedSocketUrl(base, path) {
|
|
168
|
+
const root = base.endsWith('/') ? base : `${base}/`;
|
|
169
|
+
return new URL(path, root).toString();
|
|
170
|
+
}
|