@ughuuu/game_server 1.0.382 → 1.0.791

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.
Files changed (179) hide show
  1. package/README.md +174 -24
  2. package/dist/ApiClient.js +2 -2
  3. package/dist/api/AchievementsApi.js +224 -0
  4. package/dist/api/AdminAchievementsApi.js +356 -0
  5. package/dist/api/AdminChatApi.js +2 -2
  6. package/dist/api/AdminGroupsApi.js +2 -2
  7. package/dist/api/AdminKVApi.js +2 -2
  8. package/dist/api/AdminLeaderboardsApi.js +2 -2
  9. package/dist/api/AdminLobbiesApi.js +2 -2
  10. package/dist/api/AdminNotificationsApi.js +2 -2
  11. package/dist/api/AdminSessionsApi.js +2 -2
  12. package/dist/api/AdminUsersApi.js +2 -2
  13. package/dist/api/AuthenticationApi.js +2 -2
  14. package/dist/api/ChatApi.js +141 -12
  15. package/dist/api/FriendsApi.js +2 -2
  16. package/dist/api/GroupsApi.js +69 -27
  17. package/dist/api/HealthApi.js +2 -2
  18. package/dist/api/HooksApi.js +2 -2
  19. package/dist/api/KVApi.js +2 -2
  20. package/dist/api/LeaderboardsApi.js +43 -2
  21. package/dist/api/LobbiesApi.js +44 -2
  22. package/dist/api/NotificationsApi.js +2 -2
  23. package/dist/api/PartiesApi.js +206 -22
  24. package/dist/api/UsersApi.js +2 -2
  25. package/dist/index.js +157 -10
  26. package/dist/model/AcceptPartyInviteRequest.js +109 -0
  27. package/dist/model/AdminCreateAchievementRequest.js +182 -0
  28. package/dist/model/AdminCreateKvEntry200Response.js +2 -2
  29. package/dist/model/AdminCreateKvEntryRequest.js +2 -2
  30. package/dist/model/AdminCreateLeaderboardRequest.js +2 -2
  31. package/dist/model/AdminCreateNotification400Response.js +2 -2
  32. package/dist/model/AdminCreateNotificationRequest.js +2 -2
  33. package/dist/model/AdminDeleteChatConversation200Response.js +2 -2
  34. package/dist/model/AdminEndLeaderboard200Response.js +2 -2
  35. package/dist/model/AdminEndLeaderboard200ResponseData.js +2 -2
  36. package/dist/model/AdminIncrementAchievementRequest.js +130 -0
  37. package/dist/model/AdminListAchievements200Response.js +118 -0
  38. package/dist/model/AdminListChatMessages200Response.js +2 -2
  39. package/dist/model/AdminListChatMessages200ResponseDataInner.js +20 -3
  40. package/dist/model/AdminListGroups200Response.js +2 -2
  41. package/dist/model/AdminListKvEntries200Response.js +2 -2
  42. package/dist/model/AdminListKvEntries200ResponseDataInner.js +2 -2
  43. package/dist/model/AdminListLobbies200Response.js +2 -2
  44. package/dist/model/AdminListLobbies200ResponseDataInner.js +32 -2
  45. package/dist/model/AdminListNotifications200Response.js +2 -2
  46. package/dist/model/AdminListNotifications200ResponseDataInner.js +15 -2
  47. package/dist/model/AdminListNotifications200ResponseMeta.js +2 -2
  48. package/dist/model/AdminListSessions200Response.js +2 -2
  49. package/dist/model/AdminListSessions200ResponseDataInner.js +2 -2
  50. package/dist/model/AdminRevokeAchievementRequest.js +118 -0
  51. package/dist/model/AdminSubmitLeaderboardScore200Response.js +2 -2
  52. package/dist/model/AdminSubmitLeaderboardScore200ResponseData.js +14 -2
  53. package/dist/model/AdminSubmitLeaderboardScoreRequest.js +20 -8
  54. package/dist/model/AdminUnlockAchievementRequest.js +122 -0
  55. package/dist/model/AdminUpdateAchievement200Response.js +181 -0
  56. package/dist/model/AdminUpdateAchievementRequest.js +145 -0
  57. package/dist/model/AdminUpdateGroup200Response.js +23 -2
  58. package/dist/model/AdminUpdateGroupRequest.js +11 -2
  59. package/dist/model/AdminUpdateKvEntryRequest.js +2 -2
  60. package/dist/model/AdminUpdateLeaderboardRecordRequest.js +2 -2
  61. package/dist/model/AdminUpdateLeaderboardRequest.js +2 -2
  62. package/dist/model/AdminUpdateLobby200Response.js +2 -2
  63. package/dist/model/AdminUpdateLobbyRequest.js +11 -2
  64. package/dist/model/AdminUpdateUser200Response.js +2 -2
  65. package/dist/model/AdminUpdateUser200ResponseData.js +2 -2
  66. package/dist/model/AdminUpdateUserRequest.js +2 -2
  67. package/dist/model/CallHook200Response.js +2 -2
  68. package/dist/model/CallHookRequest.js +2 -2
  69. package/dist/model/CancelGroupInvite200Response.js +2 -2
  70. package/dist/model/CancelJoinRequest200Response.js +2 -2
  71. package/dist/model/CancelPartyInviteRequest.js +109 -0
  72. package/dist/model/ChatUnreadCount200Response.js +2 -2
  73. package/dist/model/CreateFriendRequestRequest.js +2 -2
  74. package/dist/model/CreateGroupRequest.js +11 -2
  75. package/dist/model/CreateLobbyRequest.js +11 -2
  76. package/dist/model/CreatePartyRequest.js +2 -2
  77. package/dist/model/DeclinePartyInviteRequest.js +109 -0
  78. package/dist/model/DeleteNotifications200Response.js +2 -2
  79. package/dist/model/DeleteNotificationsRequest.js +2 -2
  80. package/dist/model/DemoteGroupMemberRequest.js +2 -2
  81. package/dist/model/DeviceLoginRequest.js +2 -2
  82. package/dist/model/ErrorResponse.js +2 -2
  83. package/dist/model/GetChatMessage200Response.js +196 -0
  84. package/dist/model/GetCurrentUser200Response.js +2 -2
  85. package/dist/model/GetCurrentUser200ResponseLinkedProviders.js +2 -2
  86. package/dist/model/GetKv200Response.js +2 -2
  87. package/dist/model/GetLobby200Response.js +133 -0
  88. package/dist/model/GetLobby200ResponseMembersInner.js +146 -0
  89. package/dist/model/GetMyRecord200Response.js +2 -2
  90. package/dist/model/HealthResponse.js +2 -2
  91. package/dist/model/InviteToGroup200Response.js +90 -0
  92. package/dist/model/InviteToGroupRequest.js +2 -2
  93. package/dist/model/InviteToPartyRequest.js +109 -0
  94. package/dist/model/KickGroupMemberRequest.js +2 -2
  95. package/dist/model/KickUserRequest.js +2 -2
  96. package/dist/model/LinkDeviceRequest.js +2 -2
  97. package/dist/model/ListBlockedFriends200Response.js +2 -2
  98. package/dist/model/ListBlockedFriends200ResponseDataInner.js +2 -2
  99. package/dist/model/ListBlockedFriends200ResponseDataInnerRequester.js +2 -2
  100. package/dist/model/ListChatMessages200Response.js +6 -6
  101. package/dist/model/ListFriendRequests200Response.js +2 -2
  102. package/dist/model/ListFriendRequests200ResponseIncomingInner.js +2 -2
  103. package/dist/model/ListFriendRequests200ResponseIncomingInnerRequester.js +11 -2
  104. package/dist/model/ListFriendRequests200ResponseMeta.js +2 -2
  105. package/dist/model/ListFriends200Response.js +2 -2
  106. package/dist/model/ListFriends200ResponseDataInner.js +11 -2
  107. package/dist/model/ListGroupInvitations200Response.js +2 -2
  108. package/dist/model/ListGroupInvitations200ResponseDataInner.js +48 -3
  109. package/dist/model/ListGroupMembers200Response.js +2 -2
  110. package/dist/model/ListGroupMembers200ResponseDataInner.js +2 -2
  111. package/dist/model/ListJoinRequests200Response.js +2 -2
  112. package/dist/model/ListLeaderboardRecords200Response.js +2 -2
  113. package/dist/model/ListLeaderboardRecords200ResponseDataInner.js +4 -4
  114. package/dist/model/ListLeaderboards200Response.js +2 -2
  115. package/dist/model/ListLeaderboards200ResponseDataInner.js +2 -2
  116. package/dist/model/ListLobbies200Response.js +2 -2
  117. package/dist/model/ListLobbies200ResponseDataInner.js +24 -2
  118. package/dist/model/ListMyGroups200Response.js +2 -2
  119. package/dist/model/ListMyGroups200ResponseDataInner.js +24 -2
  120. package/dist/model/ListNotifications200Response.js +2 -2
  121. package/dist/model/ListNotifications200ResponseDataInner.js +15 -2
  122. package/dist/model/ListPartyInvitations200ResponseInner.js +155 -0
  123. package/dist/model/ListRecordsAroundUser200Response.js +2 -2
  124. package/dist/model/ListSentInvitations200Response.js +2 -2
  125. package/dist/model/ListSentInvitations200ResponseDataInner.js +26 -2
  126. package/dist/model/Login200Response.js +2 -2
  127. package/dist/model/Login200ResponseData.js +15 -2
  128. package/dist/model/LoginRequest.js +2 -2
  129. package/dist/model/MarkChatReadRequest.js +8 -3
  130. package/dist/model/NotifyGroup200Response.js +2 -2
  131. package/dist/model/NotifyGroupRequest.js +3 -3
  132. package/dist/model/OAuthSessionData.js +15 -2
  133. package/dist/model/OAuthSessionDataDetails.js +2 -2
  134. package/dist/model/OAuthSessionStatus.js +2 -2
  135. package/dist/model/OauthApiCallback200Response.js +2 -2
  136. package/dist/model/OauthApiCallbackRequest.js +2 -2
  137. package/dist/model/OauthCallbackApiAppleIosRequest.js +2 -2
  138. package/dist/model/OauthGoogleIdTokenRequest.js +2 -2
  139. package/dist/model/OauthRequest200Response.js +2 -2
  140. package/dist/model/OauthSessionStatus404Response.js +2 -2
  141. package/dist/model/PartyCreateLobbyRequest.js +2 -2
  142. package/dist/model/PartyJoinLobbyRequest.js +2 -2
  143. package/dist/model/PromoteGroupMemberRequest.js +2 -2
  144. package/dist/model/QuickJoinRequest.js +2 -2
  145. package/dist/model/RefreshToken200Response.js +2 -2
  146. package/dist/model/RefreshToken200ResponseData.js +15 -2
  147. package/dist/model/RefreshTokenRequest.js +2 -2
  148. package/dist/model/ResolveLeaderboardSlugs200Response.js +89 -0
  149. package/dist/model/ResolveLeaderboardSlugsRequest.js +113 -0
  150. package/dist/model/SearchUsers200Response.js +2 -2
  151. package/dist/model/SearchUsers200ResponseDataInner.js +11 -2
  152. package/dist/model/SendChatMessageRequest.js +10 -5
  153. package/dist/model/SendNotificationRequest.js +2 -2
  154. package/dist/model/ShowParty200Response.js +13 -13
  155. package/dist/model/ShowParty200ResponseMembersInner.js +11 -2
  156. package/dist/model/UpdateChatMessageRequest.js +99 -0
  157. package/dist/model/UpdateCurrentUserDisplayNameRequest.js +2 -2
  158. package/dist/model/UpdateCurrentUserPassword400Response.js +2 -2
  159. package/dist/model/UpdateCurrentUserPasswordRequest.js +2 -2
  160. package/dist/model/UpdateGroupRequest.js +11 -2
  161. package/dist/model/UpdateLobbyRequest.js +11 -2
  162. package/dist/model/UpdatePartyRequest.js +2 -2
  163. package/dist/model/UserAchievements200Response.js +124 -0
  164. package/dist/model/UserAchievements200ResponseDataInner.js +192 -0
  165. package/dist/realtime.js +247 -0
  166. package/dist/webrtc.js +375 -0
  167. package/package.json +16 -23
  168. package/dist/model/CreateLobby401Response.js +0 -89
  169. package/dist/model/JoinLobby200Response.js +0 -89
  170. package/dist/model/JoinLobbyRequest.js +0 -90
  171. package/dist/model/JoinPartyByCodeRequest.js +0 -113
  172. package/dist/model/KickUser200Response.js +0 -89
  173. package/dist/model/LeaveLobby200Response.js +0 -89
  174. package/dist/model/ListChatMessages200ResponseDataInner.js +0 -170
  175. package/dist/model/ListLeaderboardRecords200ResponseMeta.js +0 -125
  176. package/dist/model/ListLobbies200ResponseInner.js +0 -153
  177. package/dist/model/ListLobbies200ResponseMeta.js +0 -125
  178. package/dist/model/Login200ResponseDataUser.js +0 -97
  179. package/dist/model/RemoveFriendship401Response.js +0 -89
@@ -0,0 +1,247 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports["default"] = exports.GameRealtime = void 0;
7
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
8
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
9
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
10
+ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
11
+ function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
12
+ function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
13
+ function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
14
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
15
+ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
16
+ /**
17
+ * GameRealtime — Phoenix WebSocket client for game_server.
18
+ *
19
+ * Wraps Phoenix.Socket to provide helpers for common game_server channel topics.
20
+ * Requires the `phoenix` npm package (peer dependency).
21
+ *
22
+ * Usage (browser / Node.js with bundler):
23
+ *
24
+ * import { GameRealtime } from '@ughuuu/game_server'
25
+ *
26
+ * const realtime = new GameRealtime('https://your-server.com', accessToken)
27
+ *
28
+ * // Join the authenticated user channel
29
+ * const userChannel = realtime.joinUserChannel(userId)
30
+ * userChannel.on('notification', (payload) => console.log('notification:', payload))
31
+ * userChannel.on('updated', (payload) => console.log('user updated:', payload))
32
+ *
33
+ * // Join a lobby channel
34
+ * const lobbyChannel = realtime.joinLobbyChannel(lobbyId)
35
+ * lobbyChannel.on('updated', (payload) => console.log('lobby event:', payload))
36
+ *
37
+ * realtime.disconnect()
38
+ *
39
+ * Peer dependency:
40
+ *
41
+ * npm install phoenix
42
+ */
43
+
44
+ var _Socket = null;
45
+ try {
46
+ // Works in Node (bundled) and browser environments
47
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
48
+ _Socket = require('phoenix').Socket;
49
+ } catch (_) {
50
+ // Swallow — will throw a descriptive error at instantiation time
51
+ }
52
+ var GameRealtime = exports.GameRealtime = /*#__PURE__*/function () {
53
+ /**
54
+ * @param {string} serverUrl - Base HTTP(S) or WS(S) server URL,
55
+ * e.g. "https://game.example.com" or "wss://game.example.com"
56
+ * @param {string} token - JWT access token from the REST login endpoints
57
+ * @param {Object} socketOpts - Optional Phoenix.Socket constructor options
58
+ */
59
+ function GameRealtime(serverUrl, token) {
60
+ var socketOpts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
61
+ _classCallCheck(this, GameRealtime);
62
+ if (!_Socket) {
63
+ throw new Error('GameRealtime requires the "phoenix" npm package. Install it: npm install phoenix');
64
+ }
65
+
66
+ // Normalise URL: strip trailing slash, ensure ws(s):// scheme, append /socket
67
+ var wsUrl = serverUrl.replace(/\/$/, '').replace(/^http(s?):\/\//, function (_m, s) {
68
+ return "ws".concat(s, "://");
69
+ }) + '/socket';
70
+ this._token = token;
71
+ this._socket = new _Socket(wsUrl, _objectSpread({
72
+ params: {
73
+ token: token
74
+ }
75
+ }, socketOpts));
76
+ this._socket.connect();
77
+ /** @type {Map<string, Object>} topic → Phoenix Channel */
78
+ this._channels = new Map();
79
+ }
80
+
81
+ // ── Channel helpers ──────────────────────────────────────────────────────
82
+
83
+ /**
84
+ * Join the user channel for notifications, presence, and real-time events.
85
+ * Topic: `"user:<userId>"`
86
+ * @param {string|number} userId
87
+ * @param {Object} params - Extra join params merged with the auth token
88
+ * @returns {Object} Phoenix Channel
89
+ */
90
+ return _createClass(GameRealtime, [{
91
+ key: "joinUserChannel",
92
+ value: function joinUserChannel(userId) {
93
+ var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
94
+ return this._join("user:".concat(userId), params);
95
+ }
96
+
97
+ /**
98
+ * Join a lobby channel for in-lobby events (member joins/leaves, updates).
99
+ * Topic: `"lobby:<lobbyId>"`
100
+ * @param {string|number} lobbyId
101
+ * @param {Object} params
102
+ * @returns {Object} Phoenix Channel
103
+ */
104
+ }, {
105
+ key: "joinLobbyChannel",
106
+ value: function joinLobbyChannel(lobbyId) {
107
+ var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
108
+ return this._join("lobby:".concat(lobbyId), params);
109
+ }
110
+
111
+ /**
112
+ * Join the global lobbies feed (lobby list changes).
113
+ * Topic: `"lobbies"`
114
+ * @param {Object} params
115
+ * @returns {Object} Phoenix Channel
116
+ */
117
+ }, {
118
+ key: "joinLobbiesChannel",
119
+ value: function joinLobbiesChannel() {
120
+ var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
121
+ return this._join('lobbies', params);
122
+ }
123
+
124
+ /**
125
+ * Join a group channel for group events.
126
+ * Topic: `"group:<groupId>"`
127
+ * @param {string|number} groupId
128
+ * @param {Object} params
129
+ * @returns {Object} Phoenix Channel
130
+ */
131
+ }, {
132
+ key: "joinGroupChannel",
133
+ value: function joinGroupChannel(groupId) {
134
+ var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
135
+ return this._join("group:".concat(groupId), params);
136
+ }
137
+
138
+ /**
139
+ * Join the global groups feed.
140
+ * Topic: `"groups"`
141
+ * @param {Object} params
142
+ * @returns {Object} Phoenix Channel
143
+ */
144
+ }, {
145
+ key: "joinGroupsChannel",
146
+ value: function joinGroupsChannel() {
147
+ var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
148
+ return this._join('groups', params);
149
+ }
150
+
151
+ /**
152
+ * Join a party channel for party events.
153
+ * Topic: `"party:<partyId>"`
154
+ * @param {string|number} partyId
155
+ * @param {Object} params
156
+ * @returns {Object} Phoenix Channel
157
+ */
158
+ }, {
159
+ key: "joinPartyChannel",
160
+ value: function joinPartyChannel(partyId) {
161
+ var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
162
+ return this._join("party:".concat(partyId), params);
163
+ }
164
+
165
+ /**
166
+ * Join an arbitrary channel topic.
167
+ * @param {string} topic - Full Phoenix channel topic string
168
+ * @param {Object} params - Join params merged with the auth token
169
+ * @returns {Object} Phoenix Channel
170
+ */
171
+ }, {
172
+ key: "joinChannel",
173
+ value: function joinChannel(topic) {
174
+ var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
175
+ return this._join(topic, params);
176
+ }
177
+
178
+ /**
179
+ * Leave and remove a channel by topic.
180
+ * @param {string} topic
181
+ */
182
+ }, {
183
+ key: "leaveChannel",
184
+ value: function leaveChannel(topic) {
185
+ var ch = this._channels.get(topic);
186
+ if (ch) {
187
+ ch.leave();
188
+ this._channels["delete"](topic);
189
+ }
190
+ }
191
+
192
+ /**
193
+ * Retrieve an already-joined channel by topic.
194
+ * @param {string} topic
195
+ * @returns {Object|undefined} Phoenix Channel or undefined if not joined
196
+ */
197
+ }, {
198
+ key: "channel",
199
+ value: function channel(topic) {
200
+ return this._channels.get(topic);
201
+ }
202
+
203
+ /**
204
+ * Access the underlying Phoenix.Socket instance.
205
+ * @returns {Object}
206
+ */
207
+ }, {
208
+ key: "socket",
209
+ get: function get() {
210
+ return this._socket;
211
+ }
212
+
213
+ /**
214
+ * Disconnect the socket and leave all channels.
215
+ */
216
+ }, {
217
+ key: "disconnect",
218
+ value: function disconnect() {
219
+ this._channels.forEach(function (ch) {
220
+ try {
221
+ ch.leave();
222
+ } catch (_) {}
223
+ });
224
+ this._channels.clear();
225
+ this._socket.disconnect();
226
+ }
227
+
228
+ // ── Private ────────────────────────────────────────────────────────────────
229
+ }, {
230
+ key: "_join",
231
+ value: function _join(topic) {
232
+ var extraParams = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
233
+ if (this._channels.has(topic)) {
234
+ return this._channels.get(topic);
235
+ }
236
+ var ch = this._socket.channel(topic, _objectSpread({
237
+ token: this._token
238
+ }, extraParams));
239
+ ch.join().receive('error', function (err) {
240
+ return console.error("GameRealtime: failed to join channel \"".concat(topic, "\""), err);
241
+ });
242
+ this._channels.set(topic, ch);
243
+ return ch;
244
+ }
245
+ }]);
246
+ }();
247
+ var _default = exports["default"] = GameRealtime;
package/dist/webrtc.js ADDED
@@ -0,0 +1,375 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports["default"] = exports.GameWebRTC = void 0;
7
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
8
+ function _regenerator() { /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */ var e, t, r = "function" == typeof Symbol ? Symbol : {}, n = r.iterator || "@@iterator", o = r.toStringTag || "@@toStringTag"; function i(r, n, o, i) { var c = n && n.prototype instanceof Generator ? n : Generator, u = Object.create(c.prototype); return _regeneratorDefine2(u, "_invoke", function (r, n, o) { var i, c, u, f = 0, p = o || [], y = !1, G = { p: 0, n: 0, v: e, a: d, f: d.bind(e, 4), d: function d(t, r) { return i = t, c = 0, u = e, G.n = r, a; } }; function d(r, n) { for (c = r, u = n, t = 0; !y && f && !o && t < p.length; t++) { var o, i = p[t], d = G.p, l = i[2]; r > 3 ? (o = l === n) && (u = i[(c = i[4]) ? 5 : (c = 3, 3)], i[4] = i[5] = e) : i[0] <= d && ((o = r < 2 && d < i[1]) ? (c = 0, G.v = n, G.n = i[1]) : d < l && (o = r < 3 || i[0] > n || n > l) && (i[4] = r, i[5] = n, G.n = l, c = 0)); } if (o || r > 1) return a; throw y = !0, n; } return function (o, p, l) { if (f > 1) throw TypeError("Generator is already running"); for (y && 1 === p && d(p, l), c = p, u = l; (t = c < 2 ? e : u) || !y;) { i || (c ? c < 3 ? (c > 1 && (G.n = -1), d(c, u)) : G.n = u : G.v = u); try { if (f = 2, i) { if (c || (o = "next"), t = i[o]) { if (!(t = t.call(i, u))) throw TypeError("iterator result is not an object"); if (!t.done) return t; u = t.value, c < 2 && (c = 0); } else 1 === c && (t = i["return"]) && t.call(i), c < 2 && (u = TypeError("The iterator does not provide a '" + o + "' method"), c = 1); i = e; } else if ((t = (y = G.n < 0) ? u : r.call(n, G)) !== a) break; } catch (t) { i = e, c = 1, u = t; } finally { f = 1; } } return { value: t, done: y }; }; }(r, o, i), !0), u; } var a = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} t = Object.getPrototypeOf; var c = [][n] ? t(t([][n]())) : (_regeneratorDefine2(t = {}, n, function () { return this; }), t), u = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(c); function f(e) { return Object.setPrototypeOf ? Object.setPrototypeOf(e, GeneratorFunctionPrototype) : (e.__proto__ = GeneratorFunctionPrototype, _regeneratorDefine2(e, o, "GeneratorFunction")), e.prototype = Object.create(u), e; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, _regeneratorDefine2(u, "constructor", GeneratorFunctionPrototype), _regeneratorDefine2(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = "GeneratorFunction", _regeneratorDefine2(GeneratorFunctionPrototype, o, "GeneratorFunction"), _regeneratorDefine2(u), _regeneratorDefine2(u, o, "Generator"), _regeneratorDefine2(u, n, function () { return this; }), _regeneratorDefine2(u, "toString", function () { return "[object Generator]"; }), (_regenerator = function _regenerator() { return { w: i, m: f }; })(); }
9
+ function _regeneratorDefine2(e, r, n, t) { var i = Object.defineProperty; try { i({}, "", {}); } catch (e) { i = 0; } _regeneratorDefine2 = function _regeneratorDefine(e, r, n, t) { function o(r, n) { _regeneratorDefine2(e, r, function (e) { return this._invoke(r, n, e); }); } r ? i ? i(e, r, { value: n, enumerable: !t, configurable: !t, writable: !t }) : e[r] = n : (o("next", 0), o("throw", 1), o("return", 2)); }, _regeneratorDefine2(e, r, n, t); }
10
+ function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
11
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
12
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
13
+ function asyncGeneratorStep(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); }
14
+ function _asyncToGenerator(n) { return function () { var t = this, e = arguments; return new Promise(function (r, o) { var a = n.apply(t, e); function _next(n) { asyncGeneratorStep(a, r, o, _next, _throw, "next", n); } function _throw(n) { asyncGeneratorStep(a, r, o, _next, _throw, "throw", n); } _next(void 0); }); }; }
15
+ function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
16
+ function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
17
+ function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
18
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
19
+ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
20
+ /**
21
+ * GameWebRTC — Browser WebRTC DataChannel client for game_server.
22
+ *
23
+ * Uses an existing Phoenix channel (e.g. from GameRealtime.joinUserChannel)
24
+ * for SDP/ICE signaling. Once connected, named DataChannels carry game data
25
+ * alongside the WebSocket at lower latency.
26
+ *
27
+ * Requires a browser with native WebRTC support (RTCPeerConnection).
28
+ * Does NOT work in Node.js without a WebRTC polyfill.
29
+ *
30
+ * Usage:
31
+ *
32
+ * import { GameRealtime, GameWebRTC } from '@ughuuu/game_server'
33
+ *
34
+ * const realtime = new GameRealtime('https://your-server.com', token)
35
+ * const userChannel = realtime.joinUserChannel(userId)
36
+ *
37
+ * const webrtc = new GameWebRTC(userChannel, {
38
+ * dataChannels: [
39
+ * { label: 'events', ordered: true },
40
+ * { label: 'state', ordered: false, maxRetransmits: 0 },
41
+ * ],
42
+ * onData: (label, data) => console.log('data', label, data),
43
+ * onChannelOpen: (label) => console.log('channel open', label),
44
+ * onChannelClose: (label) => console.log('channel close', label),
45
+ * onStateChange: (state) => console.log('state', state),
46
+ * })
47
+ *
48
+ * await webrtc.connect()
49
+ * webrtc.send('events', JSON.stringify({ type: 'player_move', x: 10, y: 20 }))
50
+ * webrtc.close()
51
+ */
52
+
53
+ /**
54
+ * Default DataChannel definitions.
55
+ * - "events": reliable, ordered — important game events
56
+ * - "state": unreliable, unordered — high-frequency position/state sync
57
+ */
58
+ var DEFAULT_DATA_CHANNELS = [{
59
+ label: 'events',
60
+ ordered: true
61
+ }, {
62
+ label: 'state',
63
+ ordered: false,
64
+ maxRetransmits: 0
65
+ }];
66
+ var DEFAULT_ICE_SERVERS = [{
67
+ urls: 'stun:stun.l.google.com:19302'
68
+ }];
69
+ var GameWebRTC = exports.GameWebRTC = /*#__PURE__*/function () {
70
+ /**
71
+ * @param {Object} channel — A joined Phoenix channel (e.g. from GameRealtime.joinUserChannel)
72
+ * @param {Object} opts
73
+ * @param {Array} opts.dataChannels — Array of {label, ordered, maxRetransmits?} definitions
74
+ * @param {Array} opts.iceServers — RTCIceServer configs (default: Google STUN)
75
+ * @param {Function} opts.onData — (label: string, data: ArrayBuffer|string) => void
76
+ * @param {Function} opts.onChannelOpen — (label: string) => void
77
+ * @param {Function} opts.onChannelClose — (label: string) => void
78
+ * @param {Function} opts.onStateChange — (state: string) => void
79
+ * @param {Function} opts.onError — (error: Error) => void
80
+ */
81
+ function GameWebRTC(channel) {
82
+ var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
83
+ _classCallCheck(this, GameWebRTC);
84
+ this.channel = channel;
85
+ this.opts = opts;
86
+ this.iceServers = opts.iceServers || DEFAULT_ICE_SERVERS;
87
+ this.dataChannelDefs = opts.dataChannels || DEFAULT_DATA_CHANNELS;
88
+
89
+ /** @type {RTCPeerConnection|null} */
90
+ this.pc = null;
91
+ /** @type {Map<string, RTCDataChannel>} label → RTCDataChannel */
92
+ this.channels = new Map();
93
+ /** @type {string} */
94
+ this.connectionState = 'new';
95
+ this._resolveConnect = null;
96
+ this._rejectConnect = null;
97
+ this._setupChannelListeners();
98
+ }
99
+
100
+ // ── Public API ─────────────────────────────────────────────────────────────
101
+
102
+ /**
103
+ * Initiate the WebRTC connection.
104
+ * Creates an RTCPeerConnection, opens DataChannels, sends an SDP offer
105
+ * over the Phoenix channel, and exchanges ICE candidates.
106
+ *
107
+ * @returns {Promise<void>} Resolves when at least one DataChannel is open.
108
+ */
109
+ return _createClass(GameWebRTC, [{
110
+ key: "connect",
111
+ value: function () {
112
+ var _connect = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee() {
113
+ var _this = this;
114
+ var _iterator, _step, def, dcOpts, dc, offer;
115
+ return _regenerator().w(function (_context) {
116
+ while (1) switch (_context.n) {
117
+ case 0:
118
+ this.pc = new RTCPeerConnection({
119
+ iceServers: this.iceServers
120
+ });
121
+ this.pc.onicecandidate = function (event) {
122
+ return _this._onIceCandidate(event);
123
+ };
124
+ this.pc.onconnectionstatechange = function () {
125
+ return _this._onConnectionStateChange();
126
+ };
127
+
128
+ // Create DataChannels on the client side (client-initiated)
129
+ _iterator = _createForOfIteratorHelper(this.dataChannelDefs);
130
+ try {
131
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
132
+ def = _step.value;
133
+ dcOpts = {
134
+ ordered: def.ordered !== false
135
+ };
136
+ if (def.maxRetransmits !== undefined) dcOpts.maxRetransmits = def.maxRetransmits;
137
+ if (def.maxPacketLifeTime !== undefined) dcOpts.maxPacketLifeTime = def.maxPacketLifeTime;
138
+ dc = this.pc.createDataChannel(def.label, dcOpts);
139
+ this._wireDataChannel(dc);
140
+ this.channels.set(def.label, dc);
141
+ }
142
+
143
+ // Create and send SDP offer
144
+ } catch (err) {
145
+ _iterator.e(err);
146
+ } finally {
147
+ _iterator.f();
148
+ }
149
+ _context.n = 1;
150
+ return this.pc.createOffer();
151
+ case 1:
152
+ offer = _context.v;
153
+ _context.n = 2;
154
+ return this.pc.setLocalDescription(offer);
155
+ case 2:
156
+ return _context.a(2, new Promise(function (resolve, reject) {
157
+ _this.channel.push('webrtc:offer', {
158
+ sdp: offer.sdp,
159
+ type: offer.type
160
+ }).receive('ok', function () {
161
+ // Offer accepted — wait for webrtc:answer from server
162
+ _this._resolveConnect = resolve;
163
+ _this._rejectConnect = reject;
164
+ }).receive('error', function (resp) {
165
+ reject(new Error(resp.error || 'webrtc:offer rejected'));
166
+ });
167
+
168
+ // Timeout after 15 seconds
169
+ setTimeout(function () {
170
+ if (_this._resolveConnect) {
171
+ _this._resolveConnect = null;
172
+ reject(new Error('WebRTC connection timed out'));
173
+ }
174
+ }, 15000);
175
+ }));
176
+ }
177
+ }, _callee, this);
178
+ }));
179
+ function connect() {
180
+ return _connect.apply(this, arguments);
181
+ }
182
+ return connect;
183
+ }()
184
+ /**
185
+ * Send data over a named DataChannel.
186
+ * @param {string} label — channel label (e.g. "events" or "state")
187
+ * @param {string|ArrayBuffer|Blob} data
188
+ * @returns {boolean} true if sent, false if channel is not open
189
+ */
190
+ }, {
191
+ key: "send",
192
+ value: function send(label, data) {
193
+ var dc = this.channels.get(label);
194
+ if (!dc || dc.readyState !== 'open') return false;
195
+ dc.send(data);
196
+ return true;
197
+ }
198
+
199
+ /**
200
+ * Check if a specific DataChannel is open.
201
+ * @param {string} label
202
+ * @returns {boolean}
203
+ */
204
+ }, {
205
+ key: "isChannelOpen",
206
+ value: function isChannelOpen(label) {
207
+ var dc = this.channels.get(label);
208
+ return dc ? dc.readyState === 'open' : false;
209
+ }
210
+
211
+ /**
212
+ * Check if the WebRTC connection is active.
213
+ * @returns {boolean}
214
+ */
215
+ }, {
216
+ key: "isConnected",
217
+ value: function isConnected() {
218
+ return this.pc != null && this.connectionState === 'connected';
219
+ }
220
+
221
+ /**
222
+ * Close the WebRTC connection and all DataChannels.
223
+ * Notifies the server via the Phoenix channel.
224
+ */
225
+ }, {
226
+ key: "close",
227
+ value: function close() {
228
+ this._removeChannelListeners();
229
+
230
+ // Close all DataChannels
231
+ var _iterator2 = _createForOfIteratorHelper(this.channels.values()),
232
+ _step2;
233
+ try {
234
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
235
+ var dc = _step2.value;
236
+ try {
237
+ dc.close();
238
+ } catch (_) {}
239
+ }
240
+ } catch (err) {
241
+ _iterator2.e(err);
242
+ } finally {
243
+ _iterator2.f();
244
+ }
245
+ this.channels.clear();
246
+
247
+ // Close PeerConnection
248
+ if (this.pc) {
249
+ try {
250
+ this.pc.close();
251
+ } catch (_) {}
252
+ this.pc = null;
253
+ }
254
+
255
+ // Notify server
256
+ this.channel.push('webrtc:close', {});
257
+ this.connectionState = 'closed';
258
+ }
259
+
260
+ // ── Private: signaling channel listeners ──────────────────────────────────
261
+ }, {
262
+ key: "_setupChannelListeners",
263
+ value: function _setupChannelListeners() {
264
+ var _this2 = this;
265
+ // Server sends SDP answer
266
+ this._answerRef = this.channel.on('webrtc:answer', function (payload) {
267
+ if (_this2.pc) {
268
+ _this2.pc.setRemoteDescription(new RTCSessionDescription({
269
+ sdp: payload.sdp,
270
+ type: payload.type
271
+ }));
272
+ }
273
+ });
274
+
275
+ // Server sends ICE candidate
276
+ this._iceRef = this.channel.on('webrtc:ice', function (payload) {
277
+ if (_this2.pc && payload.candidate) {
278
+ _this2.pc.addIceCandidate(new RTCIceCandidate(payload))["catch"](function (err) {
279
+ return _this2._emitError(err);
280
+ });
281
+ }
282
+ });
283
+
284
+ // Server notifies about connection state changes
285
+ this._stateRef = this.channel.on('webrtc:state', function (payload) {
286
+ var cb = _this2.opts.onStateChange;
287
+ if (cb) cb(payload.state);
288
+ });
289
+
290
+ // Server relays DataChannel data back via WebSocket (fallback)
291
+ this._dataRef = this.channel.on('webrtc:data', function (payload) {
292
+ var cb = _this2.opts.onData;
293
+ if (cb) cb(payload.channel, payload.data);
294
+ });
295
+
296
+ // Server confirms channel open
297
+ this._openRef = this.channel.on('webrtc:channel_open', function (payload) {
298
+ var cb = _this2.opts.onChannelOpen;
299
+ if (cb) cb(payload.channel);
300
+ });
301
+ }
302
+ }, {
303
+ key: "_removeChannelListeners",
304
+ value: function _removeChannelListeners() {
305
+ if (this._answerRef) this.channel.off('webrtc:answer', this._answerRef);
306
+ if (this._iceRef) this.channel.off('webrtc:ice', this._iceRef);
307
+ if (this._stateRef) this.channel.off('webrtc:state', this._stateRef);
308
+ if (this._dataRef) this.channel.off('webrtc:data', this._dataRef);
309
+ if (this._openRef) this.channel.off('webrtc:channel_open', this._openRef);
310
+ }
311
+
312
+ // ── Private: RTCPeerConnection event handlers ─────────────────────────────
313
+ }, {
314
+ key: "_onIceCandidate",
315
+ value: function _onIceCandidate(event) {
316
+ if (event.candidate) {
317
+ this.channel.push('webrtc:ice', event.candidate.toJSON());
318
+ }
319
+ }
320
+ }, {
321
+ key: "_onConnectionStateChange",
322
+ value: function _onConnectionStateChange() {
323
+ var state = this.pc.connectionState;
324
+ this.connectionState = state;
325
+ var cb = this.opts.onStateChange;
326
+ if (cb) cb(state);
327
+ if (state === 'connected' && this._resolveConnect) {
328
+ this._resolveConnect();
329
+ this._resolveConnect = null;
330
+ this._rejectConnect = null;
331
+ }
332
+ if (state === 'failed' && this._rejectConnect) {
333
+ this._rejectConnect(new Error('WebRTC connection failed'));
334
+ this._resolveConnect = null;
335
+ this._rejectConnect = null;
336
+ }
337
+ }
338
+
339
+ // ── Private: DataChannel wiring ───────────────────────────────────────────
340
+ }, {
341
+ key: "_wireDataChannel",
342
+ value: function _wireDataChannel(dc) {
343
+ var _this3 = this;
344
+ dc.onopen = function () {
345
+ var cb = _this3.opts.onChannelOpen;
346
+ if (cb) cb(dc.label);
347
+
348
+ // Resolve connect() promise when the FIRST channel opens
349
+ if (_this3._resolveConnect) {
350
+ _this3._resolveConnect();
351
+ _this3._resolveConnect = null;
352
+ _this3._rejectConnect = null;
353
+ }
354
+ };
355
+ dc.onclose = function () {
356
+ var cb = _this3.opts.onChannelClose;
357
+ if (cb) cb(dc.label);
358
+ };
359
+ dc.onmessage = function (event) {
360
+ var cb = _this3.opts.onData;
361
+ if (cb) cb(dc.label, event.data);
362
+ };
363
+ dc.onerror = function (event) {
364
+ _this3._emitError(event.error || event);
365
+ };
366
+ }
367
+ }, {
368
+ key: "_emitError",
369
+ value: function _emitError(error) {
370
+ var cb = this.opts.onError;
371
+ if (cb) cb(error);
372
+ }
373
+ }]);
374
+ }();
375
+ var _default = exports["default"] = GameWebRTC;