@colyseus/sdk 0.17.38 → 0.17.40

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 (62) hide show
  1. package/build/3rd_party/discord.cjs +1 -1
  2. package/build/3rd_party/discord.mjs +1 -1
  3. package/build/Auth.cjs +1 -1
  4. package/build/Auth.mjs +1 -1
  5. package/build/Client.cjs +2 -2
  6. package/build/Client.cjs.map +1 -1
  7. package/build/Client.d.ts +2 -1
  8. package/build/Client.mjs +2 -2
  9. package/build/Client.mjs.map +1 -1
  10. package/build/Connection.cjs +1 -1
  11. package/build/Connection.mjs +1 -1
  12. package/build/HTTP.cjs +17 -3
  13. package/build/HTTP.cjs.map +1 -1
  14. package/build/HTTP.d.ts +16 -6
  15. package/build/HTTP.mjs +18 -3
  16. package/build/HTTP.mjs.map +1 -1
  17. package/build/Room.cjs +1 -1
  18. package/build/Room.mjs +1 -1
  19. package/build/Storage.cjs +1 -1
  20. package/build/Storage.mjs +1 -1
  21. package/build/core/nanoevents.cjs +1 -1
  22. package/build/core/nanoevents.mjs +1 -1
  23. package/build/core/signal.cjs +1 -1
  24. package/build/core/signal.mjs +1 -1
  25. package/build/core/utils.cjs +1 -1
  26. package/build/core/utils.mjs +1 -1
  27. package/build/debug.cjs +1 -1
  28. package/build/debug.mjs +1 -1
  29. package/build/errors/Errors.cjs +1 -1
  30. package/build/errors/Errors.mjs +1 -1
  31. package/build/fetchXHR.cjs +91 -0
  32. package/build/fetchXHR.cjs.map +1 -0
  33. package/build/fetchXHR.d.ts +6 -0
  34. package/build/fetchXHR.mjs +84 -0
  35. package/build/fetchXHR.mjs.map +1 -0
  36. package/build/index.cjs +1 -1
  37. package/build/index.cjs.map +1 -1
  38. package/build/index.d.ts +1 -0
  39. package/build/index.mjs +1 -1
  40. package/build/index.mjs.map +1 -1
  41. package/build/legacy.cjs +1 -1
  42. package/build/legacy.mjs +1 -1
  43. package/build/serializer/NoneSerializer.cjs +1 -1
  44. package/build/serializer/NoneSerializer.mjs +1 -1
  45. package/build/serializer/SchemaSerializer.cjs +1 -1
  46. package/build/serializer/SchemaSerializer.mjs +1 -1
  47. package/build/serializer/Serializer.cjs +1 -1
  48. package/build/serializer/Serializer.mjs +1 -1
  49. package/build/transport/H3Transport.cjs +1 -1
  50. package/build/transport/H3Transport.mjs +1 -1
  51. package/build/transport/WebSocketTransport.cjs +1 -1
  52. package/build/transport/WebSocketTransport.mjs +1 -1
  53. package/dist/colyseus.js +96 -4
  54. package/dist/colyseus.js.map +1 -1
  55. package/dist/debug.js +1 -1
  56. package/package.json +6 -5
  57. package/src/Client.ts +3 -2
  58. package/src/HTTP.ts +49 -36
  59. package/src/fetchXHR.ts +88 -0
  60. package/src/index.ts +1 -0
  61. package/dist/colyseus-cocos-creator.js +0 -9667
  62. package/dist/colyseus-cocos-creator.js.map +0 -1
package/dist/debug.js CHANGED
@@ -3,7 +3,7 @@
3
3
  // This software is released under the MIT License.
4
4
  // https://opensource.org/license/MIT
5
5
  //
6
- // colyseus.js@0.17.38
6
+ // colyseus.js@0.17.40
7
7
  (function (Client_ts, sharedTypes) {
8
8
  'use strict';
9
9
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@colyseus/sdk",
3
- "version": "0.17.38",
3
+ "version": "0.17.40",
4
4
  "description": "Colyseus Multiplayer SDK for JavaScript/TypeScript",
5
5
  "author": "Endel Dreyer",
6
6
  "license": "MIT",
@@ -55,8 +55,8 @@
55
55
  "@colyseus/schema": "^4.0.7",
56
56
  "tslib": "^2.1.0",
57
57
  "ws": "^8.13.0",
58
- "@colyseus/shared-types": "^0.17.6",
59
- "@colyseus/better-call": "^1.3.1"
58
+ "@colyseus/better-call": "^1.3.1",
59
+ "@colyseus/shared-types": "^0.17.6"
60
60
  },
61
61
  "devDependencies": {
62
62
  "@rollup/plugin-alias": "^5.1.1",
@@ -82,7 +82,7 @@
82
82
  "typescript": "^5.9.3",
83
83
  "vite": "^5.0.11",
84
84
  "vitest": "^2.1.1",
85
- "@colyseus/core": "^0.17.40"
85
+ "@colyseus/core": "^0.17.41"
86
86
  },
87
87
  "peerDependencies": {
88
88
  "@colyseus/core": "0.17.x"
@@ -103,9 +103,10 @@
103
103
  "build-ci": "tsc && npm run build && npm run build-dist-dts && npm run build-release-assets",
104
104
  "build-release-assets": "zip --junk-paths colyseus-sdk dist/colyseus*",
105
105
  "build-all": "tsc && npm run build && npm run build-dist-dts && npm run copy-cocos-creator-files && npm run copy-construct3-files",
106
+ "copy-cocos-creator-files": "tsc test/dist-types-check.ts --noEmit --skipLibCheck && cp dist/colyseus.js cocos-creator-3-extension/colyseus-sdk/runtime/colyseus.js && cp dist/debug.js cocos-creator-3-extension/colyseus-sdk/runtime/debug.js && cp dist/colyseus.d.ts cocos-creator-3-extension/colyseus-sdk/runtime",
106
107
  "copy-construct3-files": "cp dist/colyseus.js ../../../colyseus-construct3/plugin/colyseus.js && cp dist/debug.js ../../../colyseus-construct3/plugin/colyseus-debug.js",
107
- "copy-cocos-creator-files": "tsc test/dist-types-check.ts --noEmit --skipLibCheck && cp dist/colyseus-cocos-creator.js cocos-creator-3-extension/colyseus-sdk/runtime/colyseus.js && cp dist/debug.js cocos-creator-3-extension/colyseus-sdk/runtime/debug.js && cp dist/colyseus.d.ts cocos-creator-3-extension/colyseus-sdk/runtime",
108
108
  "watch": "tsc -w",
109
+ "typecheck": "tsc --noEmit",
109
110
  "tslint": "tslint --project ."
110
111
  }
111
112
  }
package/src/Client.ts CHANGED
@@ -3,7 +3,7 @@ import { CloseCode, Protocol, type InferState, type SDKTypes, type ServerRoomLik
3
3
  import { MatchMakeError, ServerError } from './errors/Errors.ts';
4
4
  import { Room } from './Room.ts';
5
5
  import { SchemaConstructor } from './serializer/SchemaSerializer.ts';
6
- import { HTTP } from './HTTP.ts';
6
+ import { HTTP, type FetchFn } from './HTTP.ts';
7
7
  import { Auth } from './Auth.ts';
8
8
  import { Connection } from './Connection.ts';
9
9
  import { discordURLBuilder } from './3rd_party/discord.ts';
@@ -30,6 +30,7 @@ export interface ClientOptions {
30
30
  headers?: { [id: string]: string };
31
31
  urlBuilder?: (url: URL) => string;
32
32
  protocol?: "ws" | "h3";
33
+ fetchFn?: FetchFn;
33
34
  }
34
35
 
35
36
  export interface LatencyOptions {
@@ -108,7 +109,7 @@ export class ColyseusSDK<ServerType extends SDKTypes = any, UserData = any> {
108
109
 
109
110
  this.http = new HTTP(this, {
110
111
  headers: options?.headers || {},
111
- });
112
+ }, options?.fetchFn);
112
113
  this.auth = new Auth(this.http);
113
114
 
114
115
  this.urlBuilder = options?.urlBuilder;
package/src/HTTP.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import type { Router, HasRequiredKeys, Prettify, UnionToIntersection, Endpoint, HTTPMethod } from "@colyseus/better-call";
2
2
  import { ColyseusSDK } from "./Client.ts";
3
3
  import { ServerError } from "./errors/Errors.ts";
4
+ import { xhrFetch } from "./fetchXHR.ts";
4
5
 
5
6
  /**
6
7
  * TODO: we should clean up the types repetition in this file.
@@ -29,27 +30,7 @@ type HasRequired<
29
30
  query?: any;
30
31
  params?: any;
31
32
  },
32
- > = T["body"] extends object
33
- ? HasRequiredKeys<T["body"]> extends true
34
- ? true
35
- : T["query"] extends object
36
- ? HasRequiredKeys<T["query"]> extends true
37
- ? true
38
- : T["params"] extends object
39
- ? HasRequiredKeys<T["params"]>
40
- : false
41
- : T["params"] extends object
42
- ? HasRequiredKeys<T["params"]>
43
- : false
44
- : T["query"] extends object
45
- ? HasRequiredKeys<T["query"]> extends true
46
- ? true
47
- : T["params"] extends object
48
- ? HasRequiredKeys<T["params"]>
49
- : false
50
- : T["params"] extends object
51
- ? HasRequiredKeys<T["params"]>
52
- : false;
33
+ > = keyof RequiredOptionKeys<T> extends never ? false : true;
53
34
 
54
35
  type InferContext<T> = T extends (ctx: infer Ctx) => any
55
36
  ? Ctx extends object
@@ -86,27 +67,42 @@ type MethodOptions<API, M extends HTTPMethod> = API extends { [key: string]: inf
86
67
  : {}
87
68
  : {};
88
69
 
70
+ // When the endpoint didn't declare a schema, better-call infers:
71
+ // - body: `any`
72
+ // - query: `Record<string, any> | undefined`
73
+ // - params: `Record<string, any> | undefined` (no `:param` in path)
74
+ // Under `strictNullChecks: false`, `undefined extends T` is vacuously true and
75
+ // `undefined extends object` is also true, so the previous `extends object`
76
+ // guard wrongly classified these undeclared slots as required. The checks
77
+ // below use `IsAny` for body and `string extends keyof NonNullable<…>` to
78
+ // detect the fallback index signature — both are immune to null-check mode.
79
+ type IsUndeclaredSchema<T> = [T] extends [never]
80
+ ? true
81
+ : string extends keyof NonNullable<T> ? true : false;
82
+
89
83
  export type RequiredOptionKeys<
90
84
  C extends {
91
85
  body?: any;
92
86
  query?: any;
93
87
  params?: any;
94
88
  },
95
- > = (C["body"] extends object
96
- ? HasRequiredKeys<C["body"]> extends true
97
- ? { body: true }
98
- : {}
99
- : {}) &
100
- (C["query"] extends object
101
- ? HasRequiredKeys<C["query"]> extends true
102
- ? { query: true }
89
+ > = (IsAny<C["body"]> extends true
90
+ ? {}
91
+ : NonNullable<C["body"]> extends object
92
+ ? HasRequiredKeys<NonNullable<C["body"]>> extends true
93
+ ? { body: true }
103
94
  : {}
104
- : {}) &
105
- (C["params"] extends object
106
- ? HasRequiredKeys<C["params"]> extends true
95
+ : { body: true }) &
96
+ (IsUndeclaredSchema<C["query"]> extends true
97
+ ? {}
98
+ : HasRequiredKeys<NonNullable<C["query"]>> extends true
99
+ ? { query: true }
100
+ : {}) &
101
+ (IsUndeclaredSchema<C["params"]> extends true
102
+ ? {}
103
+ : HasRequiredKeys<NonNullable<C["params"]>> extends true
107
104
  ? { params: true }
108
- : {}
109
- : {});
105
+ : {});
110
106
 
111
107
 
112
108
  type CommonHeaders = {
@@ -249,18 +245,35 @@ type InferReturnType<R, OPT, K extends keyof OPT> =
249
245
  ? any
250
246
  : Awaited<ReturnType<OPT[K] extends Endpoint ? OPT[K] : never>>;
251
247
 
248
+ export type FetchFn = (url: string | URL | Request, init?: RequestInit) => Promise<Response>;
249
+
252
250
  export class HTTP<R extends Router | Router["endpoints"]> {
253
251
  public authToken: string | undefined;
254
252
  public options: FetchRequestOptions;
255
253
 
256
254
  private sdk: ColyseusSDK;
255
+ private _fetchFn: FetchFn | undefined;
257
256
 
258
257
  // alias "del()" to "delete()"
259
258
  public del = this.delete;
260
259
 
261
- constructor(sdk: ColyseusSDK, baseOptions: FetchRequestOptions) {
260
+ constructor(sdk: ColyseusSDK, baseOptions: FetchRequestOptions, fetchFn?: FetchFn) {
262
261
  this.sdk = sdk;
263
262
  this.options = baseOptions;
263
+ this._fetchFn = fetchFn;
264
+ }
265
+
266
+ /**
267
+ * Lazily resolve the fetch implementation.
268
+ * Falls back to XMLHttpRequest when fetch is unavailable (e.g. Cocos Creator Native).
269
+ */
270
+ private get fetchFn(): FetchFn {
271
+ if (!this._fetchFn) {
272
+ this._fetchFn = (typeof(globalThis.fetch) !== 'undefined')
273
+ ? globalThis.fetch.bind(globalThis)
274
+ : xhrFetch;
275
+ }
276
+ return this._fetchFn;
264
277
  }
265
278
 
266
279
  private async request<
@@ -509,7 +522,7 @@ export class HTTP<R extends Router | Router["endpoints"]> {
509
522
 
510
523
  let raw: Response;
511
524
  try {
512
- raw = await fetch(url, mergedOptions);
525
+ raw = await this.fetchFn(url, mergedOptions);
513
526
  } catch (err: any) {
514
527
  // If it's an AbortError, re-throw as-is
515
528
  if (err.name === 'AbortError') {
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Minimal fetch-compatible wrapper around XMLHttpRequest.
3
+ * Used as an automatic fallback when globalThis.fetch is unavailable
4
+ * (e.g. Cocos Creator Native).
5
+ */
6
+ export function xhrFetch(url: string | URL | Request, init?: RequestInit): Promise<Response> {
7
+ return new Promise((resolve, reject) => {
8
+ const xhr = new XMLHttpRequest();
9
+ const method = init?.method || "GET";
10
+
11
+ xhr.open(method, url.toString());
12
+ xhr.withCredentials = (init?.credentials === "include");
13
+
14
+ // Apply request headers
15
+ if (init?.headers) {
16
+ const headers = (init.headers instanceof Headers)
17
+ ? init.headers
18
+ : new Headers(init.headers as HeadersInit);
19
+ headers.forEach((value, key) => {
20
+ xhr.setRequestHeader(key, value);
21
+ });
22
+ }
23
+
24
+ xhr.onload = () => {
25
+ // Parse response headers
26
+ const headers = new Headers();
27
+ const rawHeaders = xhr.getAllResponseHeaders().trim();
28
+ if (rawHeaders) {
29
+ for (const line of rawHeaders.split(/[\r\n]+/)) {
30
+ const idx = line.indexOf(": ");
31
+ if (idx > 0) {
32
+ headers.append(line.substring(0, idx), line.substring(idx + 2));
33
+ }
34
+ }
35
+ }
36
+
37
+ const responseBody = xhr.response ?? xhr.responseText;
38
+
39
+ resolve(new XHRResponse(responseBody, {
40
+ status: xhr.status,
41
+ statusText: xhr.statusText,
42
+ headers,
43
+ }) as unknown as Response);
44
+ };
45
+
46
+ xhr.onerror = () => reject(new TypeError("Network request failed"));
47
+ xhr.ontimeout = () => reject(new TypeError("Network request timed out"));
48
+
49
+ xhr.send(init?.body as XMLHttpRequestBodyInit | null ?? null);
50
+ });
51
+ }
52
+
53
+ /**
54
+ * Minimal Response-compatible class backed by XHR response data.
55
+ * Implements only the surface used by HTTP.executeRequest().
56
+ */
57
+ class XHRResponse {
58
+ readonly status: number;
59
+ readonly statusText: string;
60
+ readonly headers: Headers;
61
+ readonly ok: boolean;
62
+
63
+ private body: any;
64
+
65
+ constructor(body: any, init: { status: number; statusText: string; headers: Headers }) {
66
+ this.body = body;
67
+ this.status = init.status;
68
+ this.statusText = init.statusText;
69
+ this.headers = init.headers;
70
+ this.ok = init.status >= 200 && init.status < 300;
71
+ }
72
+
73
+ async json(): Promise<any> {
74
+ return typeof this.body === "string"
75
+ ? JSON.parse(this.body)
76
+ : this.body;
77
+ }
78
+
79
+ async text(): Promise<string> {
80
+ return typeof this.body === "string"
81
+ ? this.body
82
+ : JSON.stringify(this.body);
83
+ }
84
+
85
+ async blob(): Promise<Blob> {
86
+ return new Blob([this.body]);
87
+ }
88
+ }
package/src/index.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import './legacy';
2
2
 
3
3
  export { ColyseusSDK, Client, type JoinOptions, type EndpointSettings, type ClientOptions, type ISeatReservation as SeatReservation } from './Client.ts';
4
+ export { type FetchFn } from './HTTP.ts';
4
5
  export { Room, type RoomAvailable } from './Room.ts';
5
6
  export { Auth, type AuthSettings, type PopupSettings, type AuthResponse, type UserDataResponse, type ForgotPasswordResponse, type AuthData } from "./Auth.ts";
6
7
  export { ServerError, AbortError, MatchMakeError } from './errors/Errors.ts';