@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.
- package/build/3rd_party/discord.cjs +1 -1
- package/build/3rd_party/discord.mjs +1 -1
- package/build/Auth.cjs +1 -1
- package/build/Auth.mjs +1 -1
- package/build/Client.cjs +2 -2
- package/build/Client.cjs.map +1 -1
- package/build/Client.d.ts +2 -1
- package/build/Client.mjs +2 -2
- package/build/Client.mjs.map +1 -1
- package/build/Connection.cjs +1 -1
- package/build/Connection.mjs +1 -1
- package/build/HTTP.cjs +17 -3
- package/build/HTTP.cjs.map +1 -1
- package/build/HTTP.d.ts +16 -6
- package/build/HTTP.mjs +18 -3
- package/build/HTTP.mjs.map +1 -1
- package/build/Room.cjs +1 -1
- package/build/Room.mjs +1 -1
- package/build/Storage.cjs +1 -1
- package/build/Storage.mjs +1 -1
- package/build/core/nanoevents.cjs +1 -1
- package/build/core/nanoevents.mjs +1 -1
- package/build/core/signal.cjs +1 -1
- package/build/core/signal.mjs +1 -1
- package/build/core/utils.cjs +1 -1
- package/build/core/utils.mjs +1 -1
- package/build/debug.cjs +1 -1
- package/build/debug.mjs +1 -1
- package/build/errors/Errors.cjs +1 -1
- package/build/errors/Errors.mjs +1 -1
- package/build/fetchXHR.cjs +91 -0
- package/build/fetchXHR.cjs.map +1 -0
- package/build/fetchXHR.d.ts +6 -0
- package/build/fetchXHR.mjs +84 -0
- package/build/fetchXHR.mjs.map +1 -0
- package/build/index.cjs +1 -1
- package/build/index.cjs.map +1 -1
- package/build/index.d.ts +1 -0
- package/build/index.mjs +1 -1
- package/build/index.mjs.map +1 -1
- package/build/legacy.cjs +1 -1
- package/build/legacy.mjs +1 -1
- package/build/serializer/NoneSerializer.cjs +1 -1
- package/build/serializer/NoneSerializer.mjs +1 -1
- package/build/serializer/SchemaSerializer.cjs +1 -1
- package/build/serializer/SchemaSerializer.mjs +1 -1
- package/build/serializer/Serializer.cjs +1 -1
- package/build/serializer/Serializer.mjs +1 -1
- package/build/transport/H3Transport.cjs +1 -1
- package/build/transport/H3Transport.mjs +1 -1
- package/build/transport/WebSocketTransport.cjs +1 -1
- package/build/transport/WebSocketTransport.mjs +1 -1
- package/dist/colyseus.js +96 -4
- package/dist/colyseus.js.map +1 -1
- package/dist/debug.js +1 -1
- package/package.json +6 -5
- package/src/Client.ts +3 -2
- package/src/HTTP.ts +49 -36
- package/src/fetchXHR.ts +88 -0
- package/src/index.ts +1 -0
- package/dist/colyseus-cocos-creator.js +0 -9667
- package/dist/colyseus-cocos-creator.js.map +0 -1
package/dist/debug.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@colyseus/sdk",
|
|
3
|
-
"version": "0.17.
|
|
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/
|
|
59
|
-
"@colyseus/
|
|
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.
|
|
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
|
|
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
|
|
96
|
-
?
|
|
97
|
-
|
|
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["
|
|
106
|
-
?
|
|
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
|
|
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') {
|
package/src/fetchXHR.ts
ADDED
|
@@ -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';
|