@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,211 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Main-thread half of the local transport: a `FetchLike` + `WebSocketFactory`
|
|
3
|
+
* pair backed by the engine worker. Injecting these into
|
|
4
|
+
* `createSimulatorClient` lights up the entire existing SDK (resources,
|
|
5
|
+
* `MatchSession`, reconnect) against the in-browser engine with zero changes.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Creates the transport over a running engine worker (or a test double).
|
|
9
|
+
*/
|
|
10
|
+
export function createWorkerTransport(port) {
|
|
11
|
+
let nextId = 1;
|
|
12
|
+
let nextChannelId = 1;
|
|
13
|
+
const pending = new Map();
|
|
14
|
+
const sockets = new Map();
|
|
15
|
+
const rejectAll = (message) => {
|
|
16
|
+
for (const entry of pending.values()) {
|
|
17
|
+
entry.reject(new Error(message));
|
|
18
|
+
}
|
|
19
|
+
pending.clear();
|
|
20
|
+
};
|
|
21
|
+
/** Fails every established socket so the UI transitions instead of freezing. */
|
|
22
|
+
const failAllSockets = (message) => {
|
|
23
|
+
for (const socket of [...sockets.values()]) {
|
|
24
|
+
socket.handle({ kind: 'wsFailed', channelId: 0, message });
|
|
25
|
+
}
|
|
26
|
+
sockets.clear();
|
|
27
|
+
};
|
|
28
|
+
const onError = (event) => {
|
|
29
|
+
const message = `engine worker failed: ${event?.message ?? 'unknown error'}`;
|
|
30
|
+
rejectAll(message);
|
|
31
|
+
failAllSockets(message);
|
|
32
|
+
};
|
|
33
|
+
const onMessage = (event) => {
|
|
34
|
+
const response = event.data;
|
|
35
|
+
// A negative id is the worker's global failure signal (module or wasm
|
|
36
|
+
// init failed before any request could be served).
|
|
37
|
+
if (response.kind === 'error' && response.id < 0) {
|
|
38
|
+
rejectAll(response.message);
|
|
39
|
+
failAllSockets(response.message);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
switch (response.kind) {
|
|
43
|
+
case 'ok': {
|
|
44
|
+
const entry = pending.get(response.id);
|
|
45
|
+
if (entry?.kind === 'plain') {
|
|
46
|
+
pending.delete(response.id);
|
|
47
|
+
entry.resolve({ status: response.status, body: response.body });
|
|
48
|
+
}
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
case 'error': {
|
|
52
|
+
const entry = pending.get(response.id);
|
|
53
|
+
if (entry) {
|
|
54
|
+
pending.delete(response.id);
|
|
55
|
+
entry.reject(new Error(response.message));
|
|
56
|
+
}
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
case 'saved': {
|
|
60
|
+
const entry = pending.get(response.id);
|
|
61
|
+
if (entry?.kind === 'saved') {
|
|
62
|
+
pending.delete(response.id);
|
|
63
|
+
entry.resolve({
|
|
64
|
+
matchId: response.matchId,
|
|
65
|
+
seatToken: response.seatToken,
|
|
66
|
+
bytes: response.bytes,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
case 'wsOpened':
|
|
72
|
+
case 'wsMessage':
|
|
73
|
+
case 'wsClosed':
|
|
74
|
+
case 'wsFailed': {
|
|
75
|
+
sockets.get(response.channelId)?.handle(response);
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
port.addEventListener('message', onMessage);
|
|
81
|
+
port.addEventListener('error', onError);
|
|
82
|
+
const post = (request, transfer) => {
|
|
83
|
+
port.postMessage(request, transfer);
|
|
84
|
+
};
|
|
85
|
+
const call = (request, transfer) => new Promise((resolve, reject) => {
|
|
86
|
+
pending.set(request.id, { resolve, reject, kind: 'plain' });
|
|
87
|
+
post(request, transfer);
|
|
88
|
+
});
|
|
89
|
+
const fetchLike = async (input, init) => {
|
|
90
|
+
const url = typeof input === 'string' ? input : input instanceof URL ? input.toString() : input.url;
|
|
91
|
+
const parsed = new URL(url);
|
|
92
|
+
const method = init?.method ?? 'GET';
|
|
93
|
+
const body = typeof init?.body === 'string' ? init.body : undefined;
|
|
94
|
+
const result = await call({
|
|
95
|
+
kind: 'http',
|
|
96
|
+
id: nextId++,
|
|
97
|
+
method,
|
|
98
|
+
path: `${parsed.pathname}${parsed.search}`,
|
|
99
|
+
body,
|
|
100
|
+
});
|
|
101
|
+
return new Response(result.body, {
|
|
102
|
+
status: result.status ?? 200,
|
|
103
|
+
headers: { 'content-type': 'application/json' },
|
|
104
|
+
});
|
|
105
|
+
};
|
|
106
|
+
const webSocketFactory = (url, protocols) => {
|
|
107
|
+
const channelId = nextChannelId++;
|
|
108
|
+
const socket = new LocalWebSocket(channelId, () => sockets.delete(channelId), post);
|
|
109
|
+
sockets.set(channelId, socket);
|
|
110
|
+
post({
|
|
111
|
+
kind: 'wsOpen',
|
|
112
|
+
channelId,
|
|
113
|
+
url,
|
|
114
|
+
protocols: protocols == null ? [] : Array.isArray(protocols) ? protocols : [protocols],
|
|
115
|
+
});
|
|
116
|
+
return socket;
|
|
117
|
+
};
|
|
118
|
+
return {
|
|
119
|
+
fetch: fetchLike,
|
|
120
|
+
webSocketFactory,
|
|
121
|
+
init: async (wasmBytes, glueSource, catalogBytes) => {
|
|
122
|
+
const result = await call({ kind: 'init', id: nextId++, wasmBytes, glueSource, catalogBytes }, [wasmBytes, catalogBytes]);
|
|
123
|
+
return result.body ?? '';
|
|
124
|
+
},
|
|
125
|
+
applyCatalogSync: async (catalogSyncJson) => {
|
|
126
|
+
await call({ kind: 'syncCatalog', id: nextId++, catalogSyncJson });
|
|
127
|
+
},
|
|
128
|
+
saveRecord: () => new Promise((resolve, reject) => {
|
|
129
|
+
const id = nextId++;
|
|
130
|
+
pending.set(id, { resolve, reject, kind: 'saved' });
|
|
131
|
+
post({ kind: 'saveRecord', id });
|
|
132
|
+
}),
|
|
133
|
+
restoreRecord: async (bytes) => {
|
|
134
|
+
const result = await call({ kind: 'restoreRecord', id: nextId++, bytes }, [bytes]);
|
|
135
|
+
if (!result.body) {
|
|
136
|
+
throw new Error('restoreRecord returned no access info');
|
|
137
|
+
}
|
|
138
|
+
return JSON.parse(result.body);
|
|
139
|
+
},
|
|
140
|
+
dispose: () => {
|
|
141
|
+
port.removeEventListener('message', onMessage);
|
|
142
|
+
port.removeEventListener('error', onError);
|
|
143
|
+
rejectAll('local transport disposed');
|
|
144
|
+
for (const [channelId, socket] of [...sockets.entries()]) {
|
|
145
|
+
// Tell the worker so its scheduler stops ticking the AI.
|
|
146
|
+
post({ kind: 'wsClose', channelId });
|
|
147
|
+
socket.handle({ kind: 'wsClosed', channelId, code: 1001, reason: 'transport disposed' });
|
|
148
|
+
}
|
|
149
|
+
sockets.clear();
|
|
150
|
+
},
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
/** DOM-style `EngineWebSocket` over one worker channel. */
|
|
154
|
+
class LocalWebSocket {
|
|
155
|
+
#channelId;
|
|
156
|
+
#detach;
|
|
157
|
+
#post;
|
|
158
|
+
#listeners = new Map();
|
|
159
|
+
constructor(channelId, detach, post) {
|
|
160
|
+
this.#channelId = channelId;
|
|
161
|
+
this.#detach = detach;
|
|
162
|
+
this.#post = post;
|
|
163
|
+
}
|
|
164
|
+
addEventListener(type, listener) {
|
|
165
|
+
let set = this.#listeners.get(type);
|
|
166
|
+
if (!set) {
|
|
167
|
+
set = new Set();
|
|
168
|
+
this.#listeners.set(type, set);
|
|
169
|
+
}
|
|
170
|
+
set.add(listener);
|
|
171
|
+
}
|
|
172
|
+
removeEventListener(type, listener) {
|
|
173
|
+
this.#listeners.get(type)?.delete(listener);
|
|
174
|
+
}
|
|
175
|
+
send(data) {
|
|
176
|
+
this.#post({ kind: 'wsSend', channelId: this.#channelId, data });
|
|
177
|
+
}
|
|
178
|
+
close(code, reason) {
|
|
179
|
+
this.#post({ kind: 'wsClose', channelId: this.#channelId });
|
|
180
|
+
// Real WebSockets fire `close` asynchronously; matching that keeps
|
|
181
|
+
// still-attached listeners from re-entering inside the caller's stack.
|
|
182
|
+
queueMicrotask(() => {
|
|
183
|
+
this.handle({ kind: 'wsClosed', channelId: this.#channelId, code, reason });
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
/** Dispatches one worker frame as a DOM-style event. */
|
|
187
|
+
handle(response) {
|
|
188
|
+
switch (response.kind) {
|
|
189
|
+
case 'wsOpened':
|
|
190
|
+
this.#emit('open', {});
|
|
191
|
+
break;
|
|
192
|
+
case 'wsMessage':
|
|
193
|
+
this.#emit('message', { data: response.data });
|
|
194
|
+
break;
|
|
195
|
+
case 'wsFailed':
|
|
196
|
+
this.#emit('error', { message: response.message });
|
|
197
|
+
this.#emit('close', { code: 1006, reason: response.message });
|
|
198
|
+
this.#detach();
|
|
199
|
+
break;
|
|
200
|
+
case 'wsClosed':
|
|
201
|
+
this.#emit('close', { code: response.code ?? 1000, reason: response.reason ?? '' });
|
|
202
|
+
this.#detach();
|
|
203
|
+
break;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
#emit(type, event) {
|
|
207
|
+
for (const listener of this.#listeners.get(type) ?? []) {
|
|
208
|
+
listener(event);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed contract over the `swu-wasm` module, so the in-worker server
|
|
3
|
+
* ({@link createLocalEngineServer}) is testable with a scripted fake engine
|
|
4
|
+
* and never imports wasm glue directly.
|
|
5
|
+
*/
|
|
6
|
+
/** One ordered outbound wire batch produced by the Rust host. */
|
|
7
|
+
export interface LocalWireBatch {
|
|
8
|
+
/** Milliseconds to wait before sending this batch's messages. */
|
|
9
|
+
delayBeforeMs: number;
|
|
10
|
+
/** `ServerMessage` values, pre-serialized member by member on send. */
|
|
11
|
+
messages: unknown[];
|
|
12
|
+
}
|
|
13
|
+
/** Result of one AI tick. */
|
|
14
|
+
export interface LocalAiTick {
|
|
15
|
+
batches: LocalWireBatch[];
|
|
16
|
+
moreWork: boolean;
|
|
17
|
+
}
|
|
18
|
+
/** One live offline match inside the engine. */
|
|
19
|
+
export interface LocalEngineMatch {
|
|
20
|
+
matchId: string;
|
|
21
|
+
seatToken: string;
|
|
22
|
+
/** `ServerMessage[]` handshake for a fresh connection. */
|
|
23
|
+
connect: () => unknown[];
|
|
24
|
+
/** Applies one `ClientMessage` JSON string; returns ordered batches. */
|
|
25
|
+
handleMessage: (seatToken: string, messageJson: string, nowMs: number) => LocalWireBatch[];
|
|
26
|
+
aiHasWork: () => boolean;
|
|
27
|
+
tickAi: (nowMs: number) => LocalAiTick;
|
|
28
|
+
/** Server-compatible `MatchSavePayload` JSON. */
|
|
29
|
+
save: () => string;
|
|
30
|
+
/** Full local record bytes (undo + feed) for reload persistence. */
|
|
31
|
+
toRecordBytes: () => Uint8Array;
|
|
32
|
+
/** Viewer-projected `GameState` JSON. */
|
|
33
|
+
snapshot: () => string;
|
|
34
|
+
}
|
|
35
|
+
/** One offline limited lobby inside the engine. */
|
|
36
|
+
export interface LocalEngineLobby {
|
|
37
|
+
lobbyId: string;
|
|
38
|
+
/** Throws when the token is not the host's player token. */
|
|
39
|
+
authorize: (playerToken: string) => void;
|
|
40
|
+
/** All lobby mutators return `LobbyAccessResponse` JSON. */
|
|
41
|
+
addAiPlayer: (difficulty: string) => string;
|
|
42
|
+
setHostReady: (ready: boolean) => string;
|
|
43
|
+
start: (nowMs: number) => string;
|
|
44
|
+
/** `LimitedEventResponse` JSON (advances AI picks first). */
|
|
45
|
+
eventSnapshot: (seatToken: string | null, nowMs: number) => string;
|
|
46
|
+
eventApplyCommand: (seatToken: string, commandJson: string, nowMs: number) => string;
|
|
47
|
+
submitLimitedDeck: (requestJson: string) => string;
|
|
48
|
+
prepareLimitedAiDecks: () => string;
|
|
49
|
+
/** `CreateMatchRequest` JSON for the pod's two-player match. */
|
|
50
|
+
limitedMatchRequest: () => string;
|
|
51
|
+
storeStartedMatch: (accessJson: string) => string;
|
|
52
|
+
accessJson: () => string;
|
|
53
|
+
}
|
|
54
|
+
/** The engine capabilities the local server needs. */
|
|
55
|
+
export interface LocalSimulatorEngine {
|
|
56
|
+
/** Installs the card catalog. Must be called before anything else. */
|
|
57
|
+
install: (catalogBytes: Uint8Array) => void;
|
|
58
|
+
/** Replaces dynamic app catalog metadata for future local validation. */
|
|
59
|
+
applyCatalogSync: (catalogSyncJson: string) => void;
|
|
60
|
+
/** Creates a match from `CreateMatchRequest` JSON; returns access JSON. */
|
|
61
|
+
createMatch: (requestJson: string, nowMs: number) => {
|
|
62
|
+
match: LocalEngineMatch;
|
|
63
|
+
accessJson: string;
|
|
64
|
+
};
|
|
65
|
+
/** Restores a match from local record bytes. */
|
|
66
|
+
restoreRecord: (bytes: Uint8Array) => LocalEngineMatch;
|
|
67
|
+
/** `CardsResponse` JSON for the requested card ids. */
|
|
68
|
+
cardsGet: (ids: number[]) => string;
|
|
69
|
+
/** `LimitedEventPreflightResponse` JSON without retaining state. */
|
|
70
|
+
preflightLimitedEvent: (requestJson: string) => string;
|
|
71
|
+
/** Creates an offline limited lobby from `CreateLobbyRequest` JSON. */
|
|
72
|
+
createLobby: (requestJson: string) => {
|
|
73
|
+
lobby: LocalEngineLobby;
|
|
74
|
+
accessJson: string;
|
|
75
|
+
};
|
|
76
|
+
/** Difficulty ids the offline UI may offer. */
|
|
77
|
+
offlineDifficulties: () => string[];
|
|
78
|
+
engineVersion: () => string;
|
|
79
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Offline (in-browser) engine transport for the simulator SDK.
|
|
3
|
+
*
|
|
4
|
+
* `createWorkerTransport` runs on the main thread and produces the
|
|
5
|
+
* `fetch`/`webSocketFactory` pair to inject into `createSimulatorClient`;
|
|
6
|
+
* `createLocalEngineServer` runs inside the engine worker (see `worker.ts`).
|
|
7
|
+
*/
|
|
8
|
+
export type { LocalAiTick, LocalEngineLobby, LocalEngineMatch, LocalSimulatorEngine, LocalWireBatch } from './engine.js';
|
|
9
|
+
export type { LocalEngineRequest, LocalEngineResponse, WorkerLike } from './protocol.js';
|
|
10
|
+
export { createWorkerTransport } from './client.js';
|
|
11
|
+
export type { WorkerTransport } from './client.js';
|
|
12
|
+
export { createLocalEngineServer } from './server/index.js';
|
|
13
|
+
export type { LocalEngineWorkerBootOptions } from './worker-boot.js';
|
|
14
|
+
export { bootLocalEngineWorker } from './worker-boot.js';
|
|
15
|
+
export type { SwuWasmModule } from './wasm-engine.js';
|
|
16
|
+
export { createWasmEngine } from './wasm-engine.js';
|
|
17
|
+
export type { OfflineEngineHost, OfflineEngineHostOptions, OfflineEngineWorker } from './offline-engine.js';
|
|
18
|
+
export { createOfflineEngineHost } from './offline-engine.js';
|
|
19
|
+
export * from './assets.js';
|
|
20
|
+
export * from './routing.js';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Offline (in-browser) engine transport for the simulator SDK.
|
|
3
|
+
*
|
|
4
|
+
* `createWorkerTransport` runs on the main thread and produces the
|
|
5
|
+
* `fetch`/`webSocketFactory` pair to inject into `createSimulatorClient`;
|
|
6
|
+
* `createLocalEngineServer` runs inside the engine worker (see `worker.ts`).
|
|
7
|
+
*/
|
|
8
|
+
export { createWorkerTransport } from './client.js';
|
|
9
|
+
export { createLocalEngineServer } from './server/index.js';
|
|
10
|
+
export { bootLocalEngineWorker } from './worker-boot.js';
|
|
11
|
+
export { createWasmEngine } from './wasm-engine.js';
|
|
12
|
+
export { createOfflineEngineHost } from './offline-engine.js';
|
|
13
|
+
// Assets + routing also have their own light subpath exports
|
|
14
|
+
// (`./local/assets`, `./local/routing`) for boot-time imports that must not
|
|
15
|
+
// pull this barrel's transport/server modules.
|
|
16
|
+
export * from './assets.js';
|
|
17
|
+
export * from './routing.js';
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Offline engine host: owns the engine worker lifecycle (spawn, init with
|
|
3
|
+
* cached assets, save/restore, teardown) behind one object so consumers only
|
|
4
|
+
* wire UI state. The app-side composable is a thin reactive wrapper.
|
|
5
|
+
*/
|
|
6
|
+
import type { WorkerTransport } from './client.js';
|
|
7
|
+
import type { EngineAssetBytes } from './assets.js';
|
|
8
|
+
import type { WorkerLike } from './protocol.js';
|
|
9
|
+
/** A spawned engine worker (the DOM `Worker`, or a test double). */
|
|
10
|
+
export interface OfflineEngineWorker extends WorkerLike {
|
|
11
|
+
terminate?: () => void;
|
|
12
|
+
}
|
|
13
|
+
export interface OfflineEngineHostOptions {
|
|
14
|
+
/** Spawns the engine worker (the caller owns the module URL). */
|
|
15
|
+
createWorker: () => OfflineEngineWorker;
|
|
16
|
+
/** Reads the cached engine assets for the init frame. */
|
|
17
|
+
loadAssets: () => Promise<EngineAssetBytes>;
|
|
18
|
+
/** Reads current or cached app-owned catalog metadata for the worker. */
|
|
19
|
+
loadCatalogSync: () => Promise<string>;
|
|
20
|
+
/** Observes running-state flips (drive routing flags / UI refs). */
|
|
21
|
+
onRunningChange?: ((running: boolean) => void) | undefined;
|
|
22
|
+
}
|
|
23
|
+
export interface OfflineEngineHost {
|
|
24
|
+
/** The transport bound to the running worker (boots it on demand). */
|
|
25
|
+
ensureTransport: () => Promise<WorkerTransport>;
|
|
26
|
+
/** Whether the worker is up and the engine installed. */
|
|
27
|
+
isRunning: () => boolean;
|
|
28
|
+
/** Saves the active local match's record bytes (`null` when not running). */
|
|
29
|
+
saveActiveRecord: () => Promise<{
|
|
30
|
+
matchId: string;
|
|
31
|
+
seatToken: string;
|
|
32
|
+
bytes: ArrayBuffer;
|
|
33
|
+
} | null>;
|
|
34
|
+
/** Restores a match from record bytes before reconnecting to it. */
|
|
35
|
+
restoreRecord: (bytes: ArrayBuffer) => Promise<{
|
|
36
|
+
matchId: string;
|
|
37
|
+
seatToken: string;
|
|
38
|
+
}>;
|
|
39
|
+
/** Terminates the worker and drops all live matches. */
|
|
40
|
+
shutdown: () => void;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Creates the host. One instance per app; each `shutdown` + `ensureTransport`
|
|
44
|
+
* cycle spawns a fresh worker.
|
|
45
|
+
*/
|
|
46
|
+
export declare function createOfflineEngineHost(options: OfflineEngineHostOptions): OfflineEngineHost;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Offline engine host: owns the engine worker lifecycle (spawn, init with
|
|
3
|
+
* cached assets, save/restore, teardown) behind one object so consumers only
|
|
4
|
+
* wire UI state. The app-side composable is a thin reactive wrapper.
|
|
5
|
+
*/
|
|
6
|
+
import { createWorkerTransport } from './client.js';
|
|
7
|
+
/**
|
|
8
|
+
* Creates the host. One instance per app; each `shutdown` + `ensureTransport`
|
|
9
|
+
* cycle spawns a fresh worker.
|
|
10
|
+
*/
|
|
11
|
+
export function createOfflineEngineHost(options) {
|
|
12
|
+
let worker = null;
|
|
13
|
+
let transport = null;
|
|
14
|
+
let running = false;
|
|
15
|
+
let initPromise = null;
|
|
16
|
+
const setRunning = (next) => {
|
|
17
|
+
if (running !== next) {
|
|
18
|
+
running = next;
|
|
19
|
+
options.onRunningChange?.(next);
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
/** Applies latest app-owned metadata without changing any running local match. */
|
|
23
|
+
async function syncCatalog(activeTransport) {
|
|
24
|
+
await activeTransport.applyCatalogSync(await options.loadCatalogSync());
|
|
25
|
+
}
|
|
26
|
+
function shutdown() {
|
|
27
|
+
transport?.dispose();
|
|
28
|
+
worker?.terminate?.();
|
|
29
|
+
transport = null;
|
|
30
|
+
worker = null;
|
|
31
|
+
setRunning(false);
|
|
32
|
+
}
|
|
33
|
+
async function ensureTransport() {
|
|
34
|
+
if (transport && running) {
|
|
35
|
+
await syncCatalog(transport);
|
|
36
|
+
return transport;
|
|
37
|
+
}
|
|
38
|
+
if (initPromise) {
|
|
39
|
+
return await initPromise;
|
|
40
|
+
}
|
|
41
|
+
initPromise = (async () => {
|
|
42
|
+
const assets = await options.loadAssets();
|
|
43
|
+
worker = options.createWorker();
|
|
44
|
+
transport = createWorkerTransport(worker);
|
|
45
|
+
await transport.init(assets.wasmBytes, assets.glueSource, assets.catalogBytes);
|
|
46
|
+
await syncCatalog(transport);
|
|
47
|
+
setRunning(true);
|
|
48
|
+
return transport;
|
|
49
|
+
})()
|
|
50
|
+
.catch((error) => {
|
|
51
|
+
shutdown();
|
|
52
|
+
throw error;
|
|
53
|
+
})
|
|
54
|
+
.finally(() => {
|
|
55
|
+
initPromise = null;
|
|
56
|
+
});
|
|
57
|
+
return await initPromise;
|
|
58
|
+
}
|
|
59
|
+
return {
|
|
60
|
+
ensureTransport,
|
|
61
|
+
isRunning: () => running,
|
|
62
|
+
saveActiveRecord: async () => {
|
|
63
|
+
if (!transport || !running) {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
return await transport.saveRecord();
|
|
67
|
+
},
|
|
68
|
+
restoreRecord: async (bytes) => {
|
|
69
|
+
const activeTransport = await ensureTransport();
|
|
70
|
+
return await activeTransport.restoreRecord(bytes);
|
|
71
|
+
},
|
|
72
|
+
shutdown,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structured-clone-safe RPC frames between the main-thread local transport
|
|
3
|
+
* ({@link createWorkerTransport}) and the engine worker
|
|
4
|
+
* ({@link createLocalEngineServer}).
|
|
5
|
+
*
|
|
6
|
+
* The transport impersonates the Crucible server at the HTTP-route and
|
|
7
|
+
* WebSocket-envelope level, so payloads are always JSON strings of the same
|
|
8
|
+
* generated protocol types the network path uses.
|
|
9
|
+
*/
|
|
10
|
+
/** Main-thread → worker request frames. */
|
|
11
|
+
export type LocalEngineRequest = {
|
|
12
|
+
kind: 'init';
|
|
13
|
+
id: number;
|
|
14
|
+
/** Raw bytes of `swu_wasm_bg.wasm` (compiled in the worker). */
|
|
15
|
+
wasmBytes: ArrayBuffer;
|
|
16
|
+
/** wasm-bindgen ES module source served with the matching wasm binary. */
|
|
17
|
+
glueSource: string;
|
|
18
|
+
/** Decompressed bytes of `card_catalog.v1.json`. */
|
|
19
|
+
catalogBytes: ArrayBuffer;
|
|
20
|
+
} | {
|
|
21
|
+
kind: 'http';
|
|
22
|
+
id: number;
|
|
23
|
+
method: string;
|
|
24
|
+
/** Path + query, e.g. `/api/matches` or `/api/cards?ids=1,2`. */
|
|
25
|
+
path: string;
|
|
26
|
+
/** JSON request body, when the method carries one. */
|
|
27
|
+
body?: string | undefined;
|
|
28
|
+
} | {
|
|
29
|
+
/** Replaces app-owned dynamic catalog metadata after static catalog installs. */
|
|
30
|
+
kind: 'syncCatalog';
|
|
31
|
+
id: number;
|
|
32
|
+
catalogSyncJson: string;
|
|
33
|
+
} | {
|
|
34
|
+
kind: 'wsOpen';
|
|
35
|
+
channelId: number;
|
|
36
|
+
/** Socket URL as built by the SDK (`…/ws/{matchId}`). */
|
|
37
|
+
url: string;
|
|
38
|
+
/** Subprotocol list carrying the auth token off-URL. */
|
|
39
|
+
protocols: string[];
|
|
40
|
+
} | {
|
|
41
|
+
kind: 'wsSend';
|
|
42
|
+
channelId: number;
|
|
43
|
+
data: string;
|
|
44
|
+
} | {
|
|
45
|
+
kind: 'wsClose';
|
|
46
|
+
channelId: number;
|
|
47
|
+
} | {
|
|
48
|
+
/** Serializes the active match's full local record for persistence. */
|
|
49
|
+
kind: 'saveRecord';
|
|
50
|
+
id: number;
|
|
51
|
+
} | {
|
|
52
|
+
/** Restores a match from record bytes before any socket attaches. */
|
|
53
|
+
kind: 'restoreRecord';
|
|
54
|
+
id: number;
|
|
55
|
+
bytes: ArrayBuffer;
|
|
56
|
+
};
|
|
57
|
+
/** Worker → main-thread response/event frames. */
|
|
58
|
+
export type LocalEngineResponse = {
|
|
59
|
+
kind: 'ok';
|
|
60
|
+
id: number;
|
|
61
|
+
status?: number | undefined;
|
|
62
|
+
body?: string | undefined;
|
|
63
|
+
} | {
|
|
64
|
+
kind: 'error';
|
|
65
|
+
id: number;
|
|
66
|
+
message: string;
|
|
67
|
+
} | {
|
|
68
|
+
kind: 'saved';
|
|
69
|
+
id: number;
|
|
70
|
+
matchId: string;
|
|
71
|
+
seatToken: string;
|
|
72
|
+
bytes: ArrayBuffer;
|
|
73
|
+
} | {
|
|
74
|
+
kind: 'wsOpened';
|
|
75
|
+
channelId: number;
|
|
76
|
+
} | {
|
|
77
|
+
kind: 'wsMessage';
|
|
78
|
+
channelId: number;
|
|
79
|
+
data: string;
|
|
80
|
+
} | {
|
|
81
|
+
kind: 'wsClosed';
|
|
82
|
+
channelId: number;
|
|
83
|
+
code?: number | undefined;
|
|
84
|
+
reason?: string | undefined;
|
|
85
|
+
} | {
|
|
86
|
+
kind: 'wsFailed';
|
|
87
|
+
channelId: number;
|
|
88
|
+
message: string;
|
|
89
|
+
};
|
|
90
|
+
/** Minimal message-port shape shared by `Worker` and test doubles. */
|
|
91
|
+
export interface WorkerLike {
|
|
92
|
+
postMessage: (message: unknown, transfer?: Transferable[]) => void;
|
|
93
|
+
addEventListener: (type: 'message' | 'error', listener: (event: any) => void) => void;
|
|
94
|
+
removeEventListener: (type: 'message' | 'error', listener: (event: any) => void) => void;
|
|
95
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structured-clone-safe RPC frames between the main-thread local transport
|
|
3
|
+
* ({@link createWorkerTransport}) and the engine worker
|
|
4
|
+
* ({@link createLocalEngineServer}).
|
|
5
|
+
*
|
|
6
|
+
* The transport impersonates the Crucible server at the HTTP-route and
|
|
7
|
+
* WebSocket-envelope level, so payloads are always JSON strings of the same
|
|
8
|
+
* generated protocol types the network path uses.
|
|
9
|
+
*/
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Routing transport: network by default, the in-browser engine for offline
|
|
3
|
+
* matches. Injectable into `createSimulatorClient` as its `fetch` +
|
|
4
|
+
* `webSocketFactory`.
|
|
5
|
+
*
|
|
6
|
+
* Routing rules, in order:
|
|
7
|
+
* 1. `/api/availability` is ALWAYS network — it describes the real backend.
|
|
8
|
+
* 2. Requests inside a `runWithLocalScope` callback go local (how offline
|
|
9
|
+
* match/lobby creation is opted in).
|
|
10
|
+
* 3. Requests whose path references a registered local id go local — covers
|
|
11
|
+
* every post-create call including reconnect after a page reload.
|
|
12
|
+
* 4. `/api/cards*` goes local while the engine is running (offline metadata).
|
|
13
|
+
* 5. Everything else is network.
|
|
14
|
+
*
|
|
15
|
+
* This module must stay light: it lazily receives the heavy transport via
|
|
16
|
+
* `loadLocalTransport`, so the online path never loads the engine chunk.
|
|
17
|
+
*/
|
|
18
|
+
import type { EngineWebSocket, FetchLike, WebSocketFactory } from '../internal/transport.js';
|
|
19
|
+
/** The engine-backed transport pair, loaded lazily on first local request. */
|
|
20
|
+
export interface LocalTransportPair {
|
|
21
|
+
fetch: FetchLike;
|
|
22
|
+
webSocketFactory: WebSocketFactory;
|
|
23
|
+
}
|
|
24
|
+
export interface RoutingTransportOptions {
|
|
25
|
+
/** Lazily resolves the local transport (the only edge into the engine chunk). */
|
|
26
|
+
loadLocalTransport: () => Promise<LocalTransportPair>;
|
|
27
|
+
/** Network fetch (defaults to the global). */
|
|
28
|
+
networkFetch?: FetchLike | undefined;
|
|
29
|
+
/** Network socket factory (defaults to `new WebSocket`). */
|
|
30
|
+
createNetworkSocket?: ((url: string, protocols?: string | string[]) => EngineWebSocket) | undefined;
|
|
31
|
+
}
|
|
32
|
+
export interface RoutingTransport {
|
|
33
|
+
fetch: FetchLike;
|
|
34
|
+
webSocketFactory: WebSocketFactory;
|
|
35
|
+
/** Runs `operation` with local-engine routing for creation requests. */
|
|
36
|
+
runWithLocalScope: <T>(operation: () => Promise<T>) => Promise<T>;
|
|
37
|
+
/** Whether creation scope is active (exposed for tests). */
|
|
38
|
+
isLocalScopeActive: () => boolean;
|
|
39
|
+
/** Marks one id (match/lobby/limited event) as locally hosted. */
|
|
40
|
+
registerLocalId: (id: string) => void;
|
|
41
|
+
/** Whether this id belongs to the in-browser engine. */
|
|
42
|
+
isLocalId: (id: string | undefined | null) => boolean;
|
|
43
|
+
/** Engine liveness flag, mirrored for synchronous routing decisions. */
|
|
44
|
+
setEngineRunning: (running: boolean) => void;
|
|
45
|
+
isEngineRunning: () => boolean;
|
|
46
|
+
/** Test-only: clears ids, scope, and the running flag. */
|
|
47
|
+
reset: () => void;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Creates one routing transport (one per app/client).
|
|
51
|
+
*/
|
|
52
|
+
export declare function createRoutingTransport(options: RoutingTransportOptions): RoutingTransport;
|