@crowdedkingdoms/crowdyjs 1.0.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/MIGRATION.md +247 -0
- package/README.md +303 -0
- package/dist/auth-state.d.ts +11 -0
- package/dist/auth-state.d.ts.map +1 -0
- package/dist/auth-state.js +13 -0
- package/dist/client.d.ts +135 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +150 -0
- package/dist/crowdy-client.d.ts +182 -0
- package/dist/crowdy-client.d.ts.map +1 -0
- package/dist/crowdy-client.js +146 -0
- package/dist/domains/actors.d.ts +117 -0
- package/dist/domains/actors.d.ts.map +1 -0
- package/dist/domains/actors.js +140 -0
- package/dist/domains/admin.d.ts +61 -0
- package/dist/domains/admin.d.ts.map +1 -0
- package/dist/domains/admin.js +33 -0
- package/dist/domains/appAccess.d.ts +141 -0
- package/dist/domains/appAccess.d.ts.map +1 -0
- package/dist/domains/appAccess.js +198 -0
- package/dist/domains/apps.d.ts +192 -0
- package/dist/domains/apps.d.ts.map +1 -0
- package/dist/domains/apps.js +217 -0
- package/dist/domains/auth.d.ts +163 -0
- package/dist/domains/auth.d.ts.map +1 -0
- package/dist/domains/auth.js +208 -0
- package/dist/domains/avatars.d.ts +94 -0
- package/dist/domains/avatars.d.ts.map +1 -0
- package/dist/domains/avatars.js +137 -0
- package/dist/domains/billing.d.ts +97 -0
- package/dist/domains/billing.d.ts.map +1 -0
- package/dist/domains/billing.js +131 -0
- package/dist/domains/channels.d.ts +293 -0
- package/dist/domains/channels.d.ts.map +1 -0
- package/dist/domains/channels.js +353 -0
- package/dist/domains/chunks.d.ts +133 -0
- package/dist/domains/chunks.d.ts.map +1 -0
- package/dist/domains/chunks.js +153 -0
- package/dist/domains/controlPlane.d.ts +174 -0
- package/dist/domains/controlPlane.d.ts.map +1 -0
- package/dist/domains/controlPlane.js +252 -0
- package/dist/domains/environments.d.ts +155 -0
- package/dist/domains/environments.d.ts.map +1 -0
- package/dist/domains/environments.js +223 -0
- package/dist/domains/gameApps.d.ts +114 -0
- package/dist/domains/gameApps.d.ts.map +1 -0
- package/dist/domains/gameApps.js +169 -0
- package/dist/domains/gameModel.d.ts +668 -0
- package/dist/domains/gameModel.d.ts.map +1 -0
- package/dist/domains/gameModel.js +816 -0
- package/dist/domains/host.d.ts +35 -0
- package/dist/domains/host.d.ts.map +1 -0
- package/dist/domains/host.js +40 -0
- package/dist/domains/organizations.d.ts +179 -0
- package/dist/domains/organizations.d.ts.map +1 -0
- package/dist/domains/organizations.js +269 -0
- package/dist/domains/payments.d.ts +104 -0
- package/dist/domains/payments.d.ts.map +1 -0
- package/dist/domains/payments.js +129 -0
- package/dist/domains/platform.d.ts +49 -0
- package/dist/domains/platform.d.ts.map +1 -0
- package/dist/domains/platform.js +50 -0
- package/dist/domains/quotas.d.ts +62 -0
- package/dist/domains/quotas.d.ts.map +1 -0
- package/dist/domains/quotas.js +79 -0
- package/dist/domains/serverStatus.d.ts +90 -0
- package/dist/domains/serverStatus.d.ts.map +1 -0
- package/dist/domains/serverStatus.js +104 -0
- package/dist/domains/sharedEnvironment.d.ts +133 -0
- package/dist/domains/sharedEnvironment.d.ts.map +1 -0
- package/dist/domains/sharedEnvironment.js +179 -0
- package/dist/domains/state.d.ts +64 -0
- package/dist/domains/state.d.ts.map +1 -0
- package/dist/domains/state.js +75 -0
- package/dist/domains/teams.d.ts +292 -0
- package/dist/domains/teams.d.ts.map +1 -0
- package/dist/domains/teams.js +352 -0
- package/dist/domains/teleport.d.ts +41 -0
- package/dist/domains/teleport.d.ts.map +1 -0
- package/dist/domains/teleport.js +43 -0
- package/dist/domains/udp.d.ts +405 -0
- package/dist/domains/udp.d.ts.map +1 -0
- package/dist/domains/udp.js +457 -0
- package/dist/domains/usage.d.ts +76 -0
- package/dist/domains/usage.d.ts.map +1 -0
- package/dist/domains/usage.js +110 -0
- package/dist/domains/users.d.ts +147 -0
- package/dist/domains/users.d.ts.map +1 -0
- package/dist/domains/users.js +195 -0
- package/dist/domains/voxels.d.ts +136 -0
- package/dist/domains/voxels.d.ts.map +1 -0
- package/dist/domains/voxels.js +153 -0
- package/dist/errors.d.ts +158 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +142 -0
- package/dist/generated/graphql.d.ts +12206 -0
- package/dist/generated/graphql.d.ts.map +1 -0
- package/dist/generated/graphql.js +474 -0
- package/dist/index.d.ts +84 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +85 -0
- package/dist/logger.d.ts +8 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +1 -0
- package/dist/realtime.d.ts +319 -0
- package/dist/realtime.d.ts.map +1 -0
- package/dist/realtime.js +390 -0
- package/dist/session.d.ts +73 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +96 -0
- package/dist/subscriptions.d.ts +2 -0
- package/dist/subscriptions.d.ts.map +1 -0
- package/dist/subscriptions.js +1 -0
- package/dist/types.d.ts +658 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +61 -0
- package/dist/utils.d.ts +98 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +136 -0
- package/dist/world.d.ts +236 -0
- package/dist/world.d.ts.map +1 -0
- package/dist/world.js +275 -0
- package/package.json +73 -0
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal HTTP GraphQL client. Reads its bearer token from `AuthState` so the
|
|
3
|
+
* WebSocket subscription manager and HTTP client always agree on who's
|
|
4
|
+
* authenticated. The `login` / `register` / `connectUdpProxy` /
|
|
5
|
+
* `sendActorUpdate` / etc. shortcuts that used to live here are gone -
|
|
6
|
+
* everything goes through the typed sub-clients on `CrowdyClient` (e.g.
|
|
7
|
+
* `client.auth.login`, `client.udp.sendActorUpdate`).
|
|
8
|
+
*/
|
|
9
|
+
import type { TypedDocumentNode } from '@graphql-typed-document-node/core';
|
|
10
|
+
import type { SessionStore } from './session.js';
|
|
11
|
+
import type { CrowdyLogger } from './logger.js';
|
|
12
|
+
/**
|
|
13
|
+
* Configuration for {@link GraphQLClient}, the low-level HTTP transport. You
|
|
14
|
+
* normally don't build this yourself — `CrowdyClient` constructs the transport
|
|
15
|
+
* from its own config — but it is exported for advanced or standalone use.
|
|
16
|
+
*/
|
|
17
|
+
export interface GraphQLClientConfig {
|
|
18
|
+
/**
|
|
19
|
+
* Absolute base URL of the GraphQL HTTP service (e.g.
|
|
20
|
+
* `https://game.example.com/graphql`). Used when {@link graphqlEndpoint} is
|
|
21
|
+
* not set. When both are omitted the client falls back to
|
|
22
|
+
* `http://localhost:3000/graphql`.
|
|
23
|
+
*/
|
|
24
|
+
httpUrl?: string;
|
|
25
|
+
/**
|
|
26
|
+
* Explicit GraphQL endpoint URL. Takes precedence over {@link httpUrl} when
|
|
27
|
+
* both are provided.
|
|
28
|
+
*/
|
|
29
|
+
graphqlEndpoint?: string;
|
|
30
|
+
/**
|
|
31
|
+
* Per-request timeout in **milliseconds**. When it elapses the request is
|
|
32
|
+
* aborted and a {@link CrowdyTimeoutError} is thrown. Defaults to `60000`
|
|
33
|
+
* (60 seconds).
|
|
34
|
+
*/
|
|
35
|
+
timeout?: number;
|
|
36
|
+
/**
|
|
37
|
+
* Optional logger for transport diagnostics. Defaults to a silent logger
|
|
38
|
+
* that discards all output.
|
|
39
|
+
*/
|
|
40
|
+
logger?: CrowdyLogger;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Low-level HTTP transport for GraphQL operations against the game or
|
|
44
|
+
* management API. It POSTs operations to a single endpoint, attaches the
|
|
45
|
+
* shared Bearer token read fresh from the {@link SessionStore} on every
|
|
46
|
+
* request (so the HTTP client and the realtime socket never disagree about who
|
|
47
|
+
* is authenticated), enforces a timeout, and normalizes every failure into a
|
|
48
|
+
* typed {@link CrowdyError} subclass.
|
|
49
|
+
*
|
|
50
|
+
* Most consumers should use the typed sub-clients on `CrowdyClient` instead;
|
|
51
|
+
* reach for this directly only via the low-level escape hatch
|
|
52
|
+
* (`client.graphql.request(...)`).
|
|
53
|
+
*
|
|
54
|
+
* Failure modes:
|
|
55
|
+
* - {@link CrowdyHttpError} — the endpoint returned a non-2xx HTTP status.
|
|
56
|
+
* - {@link CrowdyGraphQLError} — a 200 response whose `errors[]` was non-empty.
|
|
57
|
+
* - {@link CrowdyNetworkError} — `fetch` itself failed (DNS, TLS, refused).
|
|
58
|
+
* - {@link CrowdyTimeoutError} — the request exceeded
|
|
59
|
+
* {@link GraphQLClientConfig.timeout}.
|
|
60
|
+
*
|
|
61
|
+
* Also exported under the alias {@link GraphQLTransport}.
|
|
62
|
+
*/
|
|
63
|
+
export declare class GraphQLClient {
|
|
64
|
+
private readonly graphqlEndpoint;
|
|
65
|
+
private readonly timeout;
|
|
66
|
+
private readonly session;
|
|
67
|
+
private readonly logger;
|
|
68
|
+
/**
|
|
69
|
+
* @param config - Endpoint, timeout, and logger options; see
|
|
70
|
+
* {@link GraphQLClientConfig}.
|
|
71
|
+
* @param session - Shared session/token store. Its current token is read
|
|
72
|
+
* fresh on every request and sent as `Authorization: Bearer <token>`, so
|
|
73
|
+
* HTTP auth always tracks the active session.
|
|
74
|
+
*/
|
|
75
|
+
constructor(config: GraphQLClientConfig | undefined, session: SessionStore);
|
|
76
|
+
/**
|
|
77
|
+
* The resolved GraphQL endpoint URL this client POSTs to.
|
|
78
|
+
*
|
|
79
|
+
* @returns The absolute endpoint URL.
|
|
80
|
+
*/
|
|
81
|
+
getEndpoint(): string;
|
|
82
|
+
/**
|
|
83
|
+
* Execute a typed GraphQL operation produced by codegen and return its
|
|
84
|
+
* `data` payload. This is the preferred entry point: the
|
|
85
|
+
* {@link TypedDocumentNode} ties `variables` and the result together so both
|
|
86
|
+
* are fully type-checked.
|
|
87
|
+
*
|
|
88
|
+
* @typeParam TResult - The operation's result (`data`) type.
|
|
89
|
+
* @typeParam TVariables - The operation's variables type.
|
|
90
|
+
* @param document - The typed operation document (e.g. `ActorDocument`).
|
|
91
|
+
* @param variables - Variables for the operation; omit for operations that
|
|
92
|
+
* take none.
|
|
93
|
+
* @param options - Optional `signal` to abort the request from your own
|
|
94
|
+
* `AbortController` (in addition to the built-in timeout).
|
|
95
|
+
* @returns The operation's `data` payload.
|
|
96
|
+
* @throws {CrowdyHttpError} on a non-2xx HTTP status.
|
|
97
|
+
* @throws {CrowdyGraphQLError} when the response carries a non-empty
|
|
98
|
+
* `errors[]` array.
|
|
99
|
+
* @throws {CrowdyNetworkError} on a network-level `fetch` failure.
|
|
100
|
+
* @throws {CrowdyTimeoutError} when the request exceeds the configured
|
|
101
|
+
* timeout.
|
|
102
|
+
*/
|
|
103
|
+
request<TResult, TVariables>(document: TypedDocumentNode<TResult, TVariables>, variables?: TVariables, options?: {
|
|
104
|
+
signal?: AbortSignal;
|
|
105
|
+
}): Promise<TResult>;
|
|
106
|
+
/**
|
|
107
|
+
* Escape hatch for executing a **raw** GraphQL query string. Prefer
|
|
108
|
+
* {@link request} with a {@link TypedDocumentNode}; this exists for
|
|
109
|
+
* hand-written adapters that haven't migrated to typed documents yet. It
|
|
110
|
+
* POSTs `{ query, variables }`, attaches the Bearer token, applies the
|
|
111
|
+
* timeout, and unwraps the response's `data`.
|
|
112
|
+
*
|
|
113
|
+
* @typeParam T - Expected shape of the returned `data` (defaults to `any`).
|
|
114
|
+
* @param query - The GraphQL document text.
|
|
115
|
+
* @param variables - Variable values keyed by name. Defaults to `{}`.
|
|
116
|
+
* @param options - Optional `signal` to abort from your own
|
|
117
|
+
* `AbortController`; otherwise the internal timeout controls abortion.
|
|
118
|
+
* @returns The response's `data` payload, typed as `T`.
|
|
119
|
+
* @throws {CrowdyHttpError} on a non-2xx HTTP status.
|
|
120
|
+
* @throws {CrowdyGraphQLError} when the response carries a non-empty
|
|
121
|
+
* `errors[]` array.
|
|
122
|
+
* @throws {CrowdyNetworkError} on a network-level `fetch` failure.
|
|
123
|
+
* @throws {CrowdyTimeoutError} when the request exceeds the configured
|
|
124
|
+
* timeout.
|
|
125
|
+
*/
|
|
126
|
+
query<T = any>(query: string, variables?: Record<string, unknown>, options?: {
|
|
127
|
+
signal?: AbortSignal;
|
|
128
|
+
}): Promise<T>;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Alias for {@link GraphQLClient}, provided so callers can refer to the HTTP
|
|
132
|
+
* layer as a "transport". The two names are the exact same class.
|
|
133
|
+
*/
|
|
134
|
+
export { GraphQLClient as GraphQLTransport };
|
|
135
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAC3E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAWhD;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAe;IACvC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;IAEtC;;;;;;OAMG;gBACS,MAAM,EAAE,mBAAmB,YAAK,EAAE,OAAO,EAAE,YAAY;IAUnE;;;;OAIG;IACH,WAAW,IAAI,MAAM;IAIrB;;;;;;;;;;;;;;;;;;;;OAoBG;IACG,OAAO,CAAC,OAAO,EAAE,UAAU,EAC/B,QAAQ,EAAE,iBAAiB,CAAC,OAAO,EAAE,UAAU,CAAC,EAChD,SAAS,CAAC,EAAE,UAAU,EACtB,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAO,GACrC,OAAO,CAAC,OAAO,CAAC;IASnB;;;;;;;;;;;;;;;;;;;OAmBG;IACG,KAAK,CAAC,CAAC,GAAG,GAAG,EACjB,KAAK,EAAE,MAAM,EACb,SAAS,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACvC,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAO,GACrC,OAAO,CAAC,CAAC,CAAC;CA+Cd;AAED;;;GAGG;AACH,OAAO,EAAE,aAAa,IAAI,gBAAgB,EAAE,CAAC"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal HTTP GraphQL client. Reads its bearer token from `AuthState` so the
|
|
3
|
+
* WebSocket subscription manager and HTTP client always agree on who's
|
|
4
|
+
* authenticated. The `login` / `register` / `connectUdpProxy` /
|
|
5
|
+
* `sendActorUpdate` / etc. shortcuts that used to live here are gone -
|
|
6
|
+
* everything goes through the typed sub-clients on `CrowdyClient` (e.g.
|
|
7
|
+
* `client.auth.login`, `client.udp.sendActorUpdate`).
|
|
8
|
+
*/
|
|
9
|
+
import { print } from 'graphql';
|
|
10
|
+
import { silentLogger } from './logger.js';
|
|
11
|
+
import { CrowdyError, CrowdyGraphQLError, CrowdyHttpError, CrowdyNetworkError, CrowdyTimeoutError, } from './errors.js';
|
|
12
|
+
/**
|
|
13
|
+
* Low-level HTTP transport for GraphQL operations against the game or
|
|
14
|
+
* management API. It POSTs operations to a single endpoint, attaches the
|
|
15
|
+
* shared Bearer token read fresh from the {@link SessionStore} on every
|
|
16
|
+
* request (so the HTTP client and the realtime socket never disagree about who
|
|
17
|
+
* is authenticated), enforces a timeout, and normalizes every failure into a
|
|
18
|
+
* typed {@link CrowdyError} subclass.
|
|
19
|
+
*
|
|
20
|
+
* Most consumers should use the typed sub-clients on `CrowdyClient` instead;
|
|
21
|
+
* reach for this directly only via the low-level escape hatch
|
|
22
|
+
* (`client.graphql.request(...)`).
|
|
23
|
+
*
|
|
24
|
+
* Failure modes:
|
|
25
|
+
* - {@link CrowdyHttpError} — the endpoint returned a non-2xx HTTP status.
|
|
26
|
+
* - {@link CrowdyGraphQLError} — a 200 response whose `errors[]` was non-empty.
|
|
27
|
+
* - {@link CrowdyNetworkError} — `fetch` itself failed (DNS, TLS, refused).
|
|
28
|
+
* - {@link CrowdyTimeoutError} — the request exceeded
|
|
29
|
+
* {@link GraphQLClientConfig.timeout}.
|
|
30
|
+
*
|
|
31
|
+
* Also exported under the alias {@link GraphQLTransport}.
|
|
32
|
+
*/
|
|
33
|
+
export class GraphQLClient {
|
|
34
|
+
/**
|
|
35
|
+
* @param config - Endpoint, timeout, and logger options; see
|
|
36
|
+
* {@link GraphQLClientConfig}.
|
|
37
|
+
* @param session - Shared session/token store. Its current token is read
|
|
38
|
+
* fresh on every request and sent as `Authorization: Bearer <token>`, so
|
|
39
|
+
* HTTP auth always tracks the active session.
|
|
40
|
+
*/
|
|
41
|
+
constructor(config = {}, session) {
|
|
42
|
+
this.graphqlEndpoint =
|
|
43
|
+
config.graphqlEndpoint ||
|
|
44
|
+
config.httpUrl ||
|
|
45
|
+
'http://localhost:3000/graphql';
|
|
46
|
+
this.timeout = config.timeout || 60000;
|
|
47
|
+
this.session = session;
|
|
48
|
+
this.logger = config.logger ?? silentLogger;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* The resolved GraphQL endpoint URL this client POSTs to.
|
|
52
|
+
*
|
|
53
|
+
* @returns The absolute endpoint URL.
|
|
54
|
+
*/
|
|
55
|
+
getEndpoint() {
|
|
56
|
+
return this.graphqlEndpoint;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Execute a typed GraphQL operation produced by codegen and return its
|
|
60
|
+
* `data` payload. This is the preferred entry point: the
|
|
61
|
+
* {@link TypedDocumentNode} ties `variables` and the result together so both
|
|
62
|
+
* are fully type-checked.
|
|
63
|
+
*
|
|
64
|
+
* @typeParam TResult - The operation's result (`data`) type.
|
|
65
|
+
* @typeParam TVariables - The operation's variables type.
|
|
66
|
+
* @param document - The typed operation document (e.g. `ActorDocument`).
|
|
67
|
+
* @param variables - Variables for the operation; omit for operations that
|
|
68
|
+
* take none.
|
|
69
|
+
* @param options - Optional `signal` to abort the request from your own
|
|
70
|
+
* `AbortController` (in addition to the built-in timeout).
|
|
71
|
+
* @returns The operation's `data` payload.
|
|
72
|
+
* @throws {CrowdyHttpError} on a non-2xx HTTP status.
|
|
73
|
+
* @throws {CrowdyGraphQLError} when the response carries a non-empty
|
|
74
|
+
* `errors[]` array.
|
|
75
|
+
* @throws {CrowdyNetworkError} on a network-level `fetch` failure.
|
|
76
|
+
* @throws {CrowdyTimeoutError} when the request exceeds the configured
|
|
77
|
+
* timeout.
|
|
78
|
+
*/
|
|
79
|
+
async request(document, variables, options = {}) {
|
|
80
|
+
const queryStr = print(document);
|
|
81
|
+
return this.query(queryStr, (variables ?? {}), options);
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Escape hatch for executing a **raw** GraphQL query string. Prefer
|
|
85
|
+
* {@link request} with a {@link TypedDocumentNode}; this exists for
|
|
86
|
+
* hand-written adapters that haven't migrated to typed documents yet. It
|
|
87
|
+
* POSTs `{ query, variables }`, attaches the Bearer token, applies the
|
|
88
|
+
* timeout, and unwraps the response's `data`.
|
|
89
|
+
*
|
|
90
|
+
* @typeParam T - Expected shape of the returned `data` (defaults to `any`).
|
|
91
|
+
* @param query - The GraphQL document text.
|
|
92
|
+
* @param variables - Variable values keyed by name. Defaults to `{}`.
|
|
93
|
+
* @param options - Optional `signal` to abort from your own
|
|
94
|
+
* `AbortController`; otherwise the internal timeout controls abortion.
|
|
95
|
+
* @returns The response's `data` payload, typed as `T`.
|
|
96
|
+
* @throws {CrowdyHttpError} on a non-2xx HTTP status.
|
|
97
|
+
* @throws {CrowdyGraphQLError} when the response carries a non-empty
|
|
98
|
+
* `errors[]` array.
|
|
99
|
+
* @throws {CrowdyNetworkError} on a network-level `fetch` failure.
|
|
100
|
+
* @throws {CrowdyTimeoutError} when the request exceeds the configured
|
|
101
|
+
* timeout.
|
|
102
|
+
*/
|
|
103
|
+
async query(query, variables = {}, options = {}) {
|
|
104
|
+
const controller = new AbortController();
|
|
105
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
106
|
+
const token = this.session.getToken();
|
|
107
|
+
const signal = options.signal ?? controller.signal;
|
|
108
|
+
try {
|
|
109
|
+
const requestBody = { query, variables };
|
|
110
|
+
const response = await fetch(this.graphqlEndpoint, {
|
|
111
|
+
method: 'POST',
|
|
112
|
+
headers: {
|
|
113
|
+
'Content-Type': 'application/json',
|
|
114
|
+
...(token ? { Authorization: `Bearer ${token}` } : {}),
|
|
115
|
+
},
|
|
116
|
+
body: JSON.stringify(requestBody),
|
|
117
|
+
signal,
|
|
118
|
+
});
|
|
119
|
+
clearTimeout(timeoutId);
|
|
120
|
+
if (!response.ok) {
|
|
121
|
+
const errorText = await response.text();
|
|
122
|
+
throw new CrowdyHttpError(response.status, errorText);
|
|
123
|
+
}
|
|
124
|
+
const result = await response.json();
|
|
125
|
+
if (result.errors) {
|
|
126
|
+
throw new CrowdyGraphQLError(result.errors);
|
|
127
|
+
}
|
|
128
|
+
return result.data;
|
|
129
|
+
}
|
|
130
|
+
catch (error) {
|
|
131
|
+
clearTimeout(timeoutId);
|
|
132
|
+
if (error instanceof Error && error.name === 'AbortError') {
|
|
133
|
+
throw new CrowdyTimeoutError(this.timeout);
|
|
134
|
+
}
|
|
135
|
+
if (error instanceof CrowdyError) {
|
|
136
|
+
throw error;
|
|
137
|
+
}
|
|
138
|
+
if (error instanceof Error) {
|
|
139
|
+
throw new CrowdyNetworkError(error);
|
|
140
|
+
}
|
|
141
|
+
this.logger.error?.('GraphQL request failed', error);
|
|
142
|
+
throw new CrowdyNetworkError(error);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Alias for {@link GraphQLClient}, provided so callers can refer to the HTTP
|
|
148
|
+
* layer as a "transport". The two names are the exact same class.
|
|
149
|
+
*/
|
|
150
|
+
export { GraphQLClient as GraphQLTransport };
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public surface of the SDK. Construct one `CrowdyClient` per session and
|
|
3
|
+
* access everything via the typed sub-clients (`client.auth`, `client.udp`,
|
|
4
|
+
* `client.chunks`, ...).
|
|
5
|
+
*
|
|
6
|
+
* The management/game-api split means CrowdyJS now talks to **two** GraphQL
|
|
7
|
+
* endpoints behind the scenes:
|
|
8
|
+
*
|
|
9
|
+
* - `managementUrl` / `managementGraphqlEndpoint` -> `cks-management-api`
|
|
10
|
+
* used by `auth` (login, register, logout, password / email flows) and
|
|
11
|
+
* `users` (me, updateGamertag, deleteMyAccount). This is also where
|
|
12
|
+
* `game_tokens` are minted.
|
|
13
|
+
*
|
|
14
|
+
* - `httpUrl` / `graphqlEndpoint` -> `cks-game-api`
|
|
15
|
+
* used by every game / world / replication sub-client
|
|
16
|
+
* (`chunks`, `voxels`, `actors`, `teleport`, `state`, `serverStatus`,
|
|
17
|
+
* `udp`). WebSocket subscriptions (`wsUrl`) also target this endpoint.
|
|
18
|
+
*
|
|
19
|
+
* A single `AuthState` is shared across both clients, so once
|
|
20
|
+
* `client.auth.login()` returns, every subsequent SDK call (against either
|
|
21
|
+
* endpoint) carries the Bearer token automatically.
|
|
22
|
+
*/
|
|
23
|
+
import { AuthState } from './auth-state.js';
|
|
24
|
+
import { GraphQLClient } from './client.js';
|
|
25
|
+
import { SubscriptionManager } from './subscriptions.js';
|
|
26
|
+
import type { CrowdyLogger } from './logger.js';
|
|
27
|
+
import type { TokenStore } from './session.js';
|
|
28
|
+
import { WorldClient } from './world.js';
|
|
29
|
+
import { AuthAPI } from './domains/auth.js';
|
|
30
|
+
import { UsersAPI } from './domains/users.js';
|
|
31
|
+
import { AppsAPI } from './domains/apps.js';
|
|
32
|
+
import { PlatformAPI } from './domains/platform.js';
|
|
33
|
+
import { OrganizationsAPI } from './domains/organizations.js';
|
|
34
|
+
import { AppAccessAPI } from './domains/appAccess.js';
|
|
35
|
+
import { BillingAPI } from './domains/billing.js';
|
|
36
|
+
import { PaymentsAPI } from './domains/payments.js';
|
|
37
|
+
import { QuotasAPI } from './domains/quotas.js';
|
|
38
|
+
import { EnvironmentsAPI } from './domains/environments.js';
|
|
39
|
+
import { UsageAPI } from './domains/usage.js';
|
|
40
|
+
import { SharedEnvironmentAPI } from './domains/sharedEnvironment.js';
|
|
41
|
+
import { ControlPlaneAPI } from './domains/controlPlane.js';
|
|
42
|
+
import { AdminAPI } from './domains/admin.js';
|
|
43
|
+
import { ChunksAPI } from './domains/chunks.js';
|
|
44
|
+
import { AvatarsAPI } from './domains/avatars.js';
|
|
45
|
+
import { HostAPI } from './domains/host.js';
|
|
46
|
+
import { GameAppsAPI } from './domains/gameApps.js';
|
|
47
|
+
import { VoxelsAPI } from './domains/voxels.js';
|
|
48
|
+
import { ActorsAPI } from './domains/actors.js';
|
|
49
|
+
import { TeleportAPI } from './domains/teleport.js';
|
|
50
|
+
import { StateAPI } from './domains/state.js';
|
|
51
|
+
import { ServerStatusAPI } from './domains/serverStatus.js';
|
|
52
|
+
import { ChannelsAPI } from './domains/channels.js';
|
|
53
|
+
import { TeamsAPI } from './domains/teams.js';
|
|
54
|
+
import { UdpAPI } from './domains/udp.js';
|
|
55
|
+
import { GameModelAPI } from './domains/gameModel.js';
|
|
56
|
+
export interface CrowdyClientConfig {
|
|
57
|
+
/** game-api HTTP root (e.g. `https://dev-game-api.crowdedkingdoms.com`). */
|
|
58
|
+
httpUrl?: string;
|
|
59
|
+
/** game-api WS root. */
|
|
60
|
+
wsUrl?: string;
|
|
61
|
+
/** game-api GraphQL endpoint. Defaults to `${httpUrl}/graphql`. */
|
|
62
|
+
graphqlEndpoint?: string;
|
|
63
|
+
/** game-api WS endpoint. Defaults to `${wsUrl}/graphql`. */
|
|
64
|
+
wsEndpoint?: string;
|
|
65
|
+
/**
|
|
66
|
+
* management-api HTTP root (e.g.
|
|
67
|
+
* `https://dev-management-api.crowdedkingdoms.com`). When set,
|
|
68
|
+
* `client.auth` and `client.users` route here. If left empty the SDK
|
|
69
|
+
* falls back to `httpUrl` for backwards-compatibility with the legacy
|
|
70
|
+
* single-endpoint deployment, but new code should set this explicitly.
|
|
71
|
+
*/
|
|
72
|
+
managementUrl?: string;
|
|
73
|
+
/** management-api GraphQL endpoint. Defaults to `${managementUrl}/graphql`. */
|
|
74
|
+
managementGraphqlEndpoint?: string;
|
|
75
|
+
/** Per-request HTTP timeout in milliseconds (applies to both endpoints). */
|
|
76
|
+
timeout?: number;
|
|
77
|
+
/**
|
|
78
|
+
* Persistence for the Bearer token across reloads. `BrowserLocalStorageTokenStore`
|
|
79
|
+
* is provided; supply your own for SSR/Node. When omitted the token lives only
|
|
80
|
+
* in memory for the lifetime of the client.
|
|
81
|
+
*/
|
|
82
|
+
tokenStore?: TokenStore;
|
|
83
|
+
/** Optional logger for SDK diagnostics (request/realtime lifecycle). */
|
|
84
|
+
logger?: CrowdyLogger;
|
|
85
|
+
/** Realtime (WebSocket) tuning for reconnect backoff and `...AndWait` timeouts. */
|
|
86
|
+
realtime?: {
|
|
87
|
+
/** Max reconnect attempts before giving up (default tuned for browsers). */
|
|
88
|
+
retryAttempts?: number;
|
|
89
|
+
/** Initial reconnect backoff in milliseconds. */
|
|
90
|
+
retryInitialDelayMs?: number;
|
|
91
|
+
/** Maximum reconnect backoff in milliseconds (the backoff is capped here). */
|
|
92
|
+
retryMaxDelayMs?: number;
|
|
93
|
+
/** Default timeout for `...AndWait` round-trips that await a matching echo. */
|
|
94
|
+
waitTimeoutMs?: number;
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
export declare class CrowdyClient {
|
|
98
|
+
/** Shared token state for both game-api and management-api requests. */
|
|
99
|
+
readonly session: AuthState;
|
|
100
|
+
/** game-api HTTP client. */
|
|
101
|
+
readonly graphql: GraphQLClient;
|
|
102
|
+
/** game-api WebSocket subscription manager. */
|
|
103
|
+
readonly realtime: SubscriptionManager;
|
|
104
|
+
/** management-api HTTP client. Same `AuthState` as `graphql`. */
|
|
105
|
+
readonly management: GraphQLClient;
|
|
106
|
+
/** Auth + session: login, register, logout, password/email flows. */
|
|
107
|
+
readonly auth: AuthAPI;
|
|
108
|
+
/** Current-user identity: `me`, gamertag, account deletion. */
|
|
109
|
+
readonly users: UsersAPI;
|
|
110
|
+
/** App discovery + routing (which game-api serves a given app). */
|
|
111
|
+
readonly apps: AppsAPI;
|
|
112
|
+
/** Public platform discovery (shared game-api URL, free app quota). */
|
|
113
|
+
readonly platform: PlatformAPI;
|
|
114
|
+
/** Organizations, members, RBAC roles, and org API tokens (studio admin). */
|
|
115
|
+
readonly organizations: OrganizationsAPI;
|
|
116
|
+
/** App access tiers + per-user access grants (studio admin). */
|
|
117
|
+
readonly appAccess: AppAccessAPI;
|
|
118
|
+
/** Org wallet + per-app spend budgets (studio admin). */
|
|
119
|
+
readonly billing: BillingAPI;
|
|
120
|
+
/** Payment checkouts: wallet top-ups, plan purchases (studio admin). */
|
|
121
|
+
readonly payments: PaymentsAPI;
|
|
122
|
+
/** Usage quotas at the org/app scope (studio admin). */
|
|
123
|
+
readonly quotas: QuotasAPI;
|
|
124
|
+
/** Dedicated customer environments: provision, scale, deploy (studio admin). */
|
|
125
|
+
readonly environments: EnvironmentsAPI;
|
|
126
|
+
/** Replication + GraphQL usage reporting (studio admin). */
|
|
127
|
+
readonly usage: UsageAPI;
|
|
128
|
+
/** Shared-environment publishing, runtime gating, auto-billing (studio admin). */
|
|
129
|
+
readonly sharedEnvironment: SharedEnvironmentAPI;
|
|
130
|
+
/** Operator (control-plane) surface — requires `is_operator`. */
|
|
131
|
+
readonly operator: ControlPlaneAPI;
|
|
132
|
+
/**
|
|
133
|
+
* Studio-admin facade grouping the privileged management sub-clients
|
|
134
|
+
* (`organizations`, `appAccess`, `billing`, `payments`, `quotas`,
|
|
135
|
+
* `environments`, `usage`, `sharedEnvironment`, `grids`) under one namespace.
|
|
136
|
+
*/
|
|
137
|
+
readonly admin: AdminAPI;
|
|
138
|
+
/** Chunk reads/writes: terrain, LODs, chunk state, distance queries. */
|
|
139
|
+
readonly chunks: ChunksAPI;
|
|
140
|
+
/** Voxel reads/writes: list, history, rollback, single-voxel edits. */
|
|
141
|
+
readonly voxels: VoxelsAPI;
|
|
142
|
+
/** Persisted-actor CRUD (durable records; realtime is `udp`/`world`). */
|
|
143
|
+
readonly actors: ActorsAPI;
|
|
144
|
+
/** Teleport: move an actor to a destination chunk/world. */
|
|
145
|
+
readonly teleport: TeleportAPI;
|
|
146
|
+
/** Per-user/per-app persisted state blobs. */
|
|
147
|
+
readonly state: StateAPI;
|
|
148
|
+
/** Server status + version discovery (UDP availability, version floors). */
|
|
149
|
+
readonly serverStatus: ServerStatusAPI;
|
|
150
|
+
/** Channels: location-independent pub/sub messaging groups. */
|
|
151
|
+
readonly channels: ChannelsAPI;
|
|
152
|
+
/** Teams: app-scoped player groups with roles and delegated management. */
|
|
153
|
+
readonly teams: TeamsAPI;
|
|
154
|
+
/** UDP proxy: spatial sends + the shared realtime notification subscription. */
|
|
155
|
+
readonly udp: UdpAPI;
|
|
156
|
+
/** Abstract game model: containers, properties, functions, sessions. */
|
|
157
|
+
readonly gameModel: GameModelAPI;
|
|
158
|
+
/** Durable avatars + per-app avatar state (owner-aware reads). */
|
|
159
|
+
readonly avatars: AvatarsAPI;
|
|
160
|
+
/** Game-host election + actor liveness heartbeat. */
|
|
161
|
+
readonly host: HostAPI;
|
|
162
|
+
/** App grids + grid runtime-permission administration (app admin). */
|
|
163
|
+
readonly gameApps: GameAppsAPI;
|
|
164
|
+
constructor(config?: CrowdyClientConfig);
|
|
165
|
+
/** Imperatively set the Bearer token (useful for SSO / token rehydrate). */
|
|
166
|
+
setToken(token: string | null): void;
|
|
167
|
+
/** Read the current Bearer token (null if no session). */
|
|
168
|
+
getToken(): string | null;
|
|
169
|
+
/**
|
|
170
|
+
* Ergonomic, app-scoped realtime facade. `client.world(appId)` returns a
|
|
171
|
+
* {@link WorldClient} whose `actor()` and `subscribe()` helpers pass `appId`
|
|
172
|
+
* for you and manage chunk/sequence bookkeeping — the recommended entry point
|
|
173
|
+
* for game loops. The lower-level `client.udp` remains available.
|
|
174
|
+
*
|
|
175
|
+
* @param appId - The app to scope realtime traffic to (BigInt as a decimal string).
|
|
176
|
+
*/
|
|
177
|
+
world(appId: string): WorldClient;
|
|
178
|
+
/** Closes the WebSocket and clears the in-memory auth token. */
|
|
179
|
+
close(): void;
|
|
180
|
+
}
|
|
181
|
+
export declare function createCrowdyClient(config?: CrowdyClientConfig): CrowdyClient;
|
|
182
|
+
//# sourceMappingURL=crowdy-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crowdy-client.d.ts","sourceRoot":"","sources":["../src/crowdy-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public surface of the SDK. Construct one `CrowdyClient` per session and
|
|
3
|
+
* access everything via the typed sub-clients (`client.auth`, `client.udp`,
|
|
4
|
+
* `client.chunks`, ...).
|
|
5
|
+
*
|
|
6
|
+
* The management/game-api split means CrowdyJS now talks to **two** GraphQL
|
|
7
|
+
* endpoints behind the scenes:
|
|
8
|
+
*
|
|
9
|
+
* - `managementUrl` / `managementGraphqlEndpoint` -> `cks-management-api`
|
|
10
|
+
* used by `auth` (login, register, logout, password / email flows) and
|
|
11
|
+
* `users` (me, updateGamertag, deleteMyAccount). This is also where
|
|
12
|
+
* `game_tokens` are minted.
|
|
13
|
+
*
|
|
14
|
+
* - `httpUrl` / `graphqlEndpoint` -> `cks-game-api`
|
|
15
|
+
* used by every game / world / replication sub-client
|
|
16
|
+
* (`chunks`, `voxels`, `actors`, `teleport`, `state`, `serverStatus`,
|
|
17
|
+
* `udp`). WebSocket subscriptions (`wsUrl`) also target this endpoint.
|
|
18
|
+
*
|
|
19
|
+
* A single `AuthState` is shared across both clients, so once
|
|
20
|
+
* `client.auth.login()` returns, every subsequent SDK call (against either
|
|
21
|
+
* endpoint) carries the Bearer token automatically.
|
|
22
|
+
*/
|
|
23
|
+
import { AuthState } from './auth-state.js';
|
|
24
|
+
import { GraphQLClient } from './client.js';
|
|
25
|
+
import { SubscriptionManager } from './subscriptions.js';
|
|
26
|
+
import { WorldClient } from './world.js';
|
|
27
|
+
import { AuthAPI } from './domains/auth.js';
|
|
28
|
+
import { UsersAPI } from './domains/users.js';
|
|
29
|
+
import { AppsAPI } from './domains/apps.js';
|
|
30
|
+
import { PlatformAPI } from './domains/platform.js';
|
|
31
|
+
import { OrganizationsAPI } from './domains/organizations.js';
|
|
32
|
+
import { AppAccessAPI } from './domains/appAccess.js';
|
|
33
|
+
import { BillingAPI } from './domains/billing.js';
|
|
34
|
+
import { PaymentsAPI } from './domains/payments.js';
|
|
35
|
+
import { QuotasAPI } from './domains/quotas.js';
|
|
36
|
+
import { EnvironmentsAPI } from './domains/environments.js';
|
|
37
|
+
import { UsageAPI } from './domains/usage.js';
|
|
38
|
+
import { SharedEnvironmentAPI } from './domains/sharedEnvironment.js';
|
|
39
|
+
import { ControlPlaneAPI } from './domains/controlPlane.js';
|
|
40
|
+
import { AdminAPI } from './domains/admin.js';
|
|
41
|
+
import { ChunksAPI } from './domains/chunks.js';
|
|
42
|
+
import { AvatarsAPI } from './domains/avatars.js';
|
|
43
|
+
import { HostAPI } from './domains/host.js';
|
|
44
|
+
import { GameAppsAPI } from './domains/gameApps.js';
|
|
45
|
+
import { VoxelsAPI } from './domains/voxels.js';
|
|
46
|
+
import { ActorsAPI } from './domains/actors.js';
|
|
47
|
+
import { TeleportAPI } from './domains/teleport.js';
|
|
48
|
+
import { StateAPI } from './domains/state.js';
|
|
49
|
+
import { ServerStatusAPI } from './domains/serverStatus.js';
|
|
50
|
+
import { ChannelsAPI } from './domains/channels.js';
|
|
51
|
+
import { TeamsAPI } from './domains/teams.js';
|
|
52
|
+
import { UdpAPI } from './domains/udp.js';
|
|
53
|
+
import { GameModelAPI } from './domains/gameModel.js';
|
|
54
|
+
export class CrowdyClient {
|
|
55
|
+
constructor(config = {}) {
|
|
56
|
+
this.session = new AuthState(config.tokenStore);
|
|
57
|
+
this.graphql = new GraphQLClient({
|
|
58
|
+
httpUrl: config.httpUrl,
|
|
59
|
+
graphqlEndpoint: config.graphqlEndpoint,
|
|
60
|
+
timeout: config.timeout,
|
|
61
|
+
logger: config.logger,
|
|
62
|
+
}, this.session);
|
|
63
|
+
this.realtime = new SubscriptionManager({
|
|
64
|
+
wsUrl: config.wsUrl,
|
|
65
|
+
wsEndpoint: config.wsEndpoint,
|
|
66
|
+
logger: config.logger,
|
|
67
|
+
...config.realtime,
|
|
68
|
+
}, this.session);
|
|
69
|
+
const managementGraphqlEndpoint = config.managementGraphqlEndpoint ??
|
|
70
|
+
(config.managementUrl
|
|
71
|
+
? `${config.managementUrl.replace(/\/$/, '')}/graphql`
|
|
72
|
+
: config.graphqlEndpoint);
|
|
73
|
+
// Management-api client. Falls back to game-api endpoint if the caller
|
|
74
|
+
// hasn't configured `managementUrl` yet (single-endpoint legacy mode).
|
|
75
|
+
this.management = new GraphQLClient({
|
|
76
|
+
httpUrl: config.managementUrl ?? config.httpUrl,
|
|
77
|
+
graphqlEndpoint: managementGraphqlEndpoint,
|
|
78
|
+
timeout: config.timeout,
|
|
79
|
+
logger: config.logger,
|
|
80
|
+
}, this.session);
|
|
81
|
+
this.auth = new AuthAPI(this.management, this.session);
|
|
82
|
+
this.users = new UsersAPI(this.management);
|
|
83
|
+
this.apps = new AppsAPI(this.management);
|
|
84
|
+
this.platform = new PlatformAPI(this.management);
|
|
85
|
+
this.organizations = new OrganizationsAPI(this.management);
|
|
86
|
+
this.appAccess = new AppAccessAPI(this.management);
|
|
87
|
+
this.billing = new BillingAPI(this.management);
|
|
88
|
+
this.payments = new PaymentsAPI(this.management);
|
|
89
|
+
this.quotas = new QuotasAPI(this.management);
|
|
90
|
+
this.environments = new EnvironmentsAPI(this.management);
|
|
91
|
+
this.usage = new UsageAPI(this.management);
|
|
92
|
+
this.sharedEnvironment = new SharedEnvironmentAPI(this.management);
|
|
93
|
+
this.operator = new ControlPlaneAPI(this.management);
|
|
94
|
+
this.chunks = new ChunksAPI(this.graphql);
|
|
95
|
+
this.voxels = new VoxelsAPI(this.graphql);
|
|
96
|
+
this.actors = new ActorsAPI(this.graphql);
|
|
97
|
+
this.teleport = new TeleportAPI(this.graphql);
|
|
98
|
+
this.state = new StateAPI(this.graphql);
|
|
99
|
+
this.serverStatus = new ServerStatusAPI(this.graphql);
|
|
100
|
+
this.channels = new ChannelsAPI(this.graphql);
|
|
101
|
+
this.teams = new TeamsAPI(this.graphql);
|
|
102
|
+
this.udp = new UdpAPI(this.graphql, this.realtime);
|
|
103
|
+
this.gameModel = new GameModelAPI(this.graphql);
|
|
104
|
+
this.avatars = new AvatarsAPI(this.graphql);
|
|
105
|
+
this.host = new HostAPI(this.graphql);
|
|
106
|
+
this.gameApps = new GameAppsAPI(this.graphql);
|
|
107
|
+
this.admin = new AdminAPI({
|
|
108
|
+
organizations: this.organizations,
|
|
109
|
+
appAccess: this.appAccess,
|
|
110
|
+
billing: this.billing,
|
|
111
|
+
payments: this.payments,
|
|
112
|
+
quotas: this.quotas,
|
|
113
|
+
environments: this.environments,
|
|
114
|
+
usage: this.usage,
|
|
115
|
+
sharedEnvironment: this.sharedEnvironment,
|
|
116
|
+
grids: this.gameApps,
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
/** Imperatively set the Bearer token (useful for SSO / token rehydrate). */
|
|
120
|
+
setToken(token) {
|
|
121
|
+
this.session.setToken(token);
|
|
122
|
+
}
|
|
123
|
+
/** Read the current Bearer token (null if no session). */
|
|
124
|
+
getToken() {
|
|
125
|
+
return this.session.getToken();
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Ergonomic, app-scoped realtime facade. `client.world(appId)` returns a
|
|
129
|
+
* {@link WorldClient} whose `actor()` and `subscribe()` helpers pass `appId`
|
|
130
|
+
* for you and manage chunk/sequence bookkeeping — the recommended entry point
|
|
131
|
+
* for game loops. The lower-level `client.udp` remains available.
|
|
132
|
+
*
|
|
133
|
+
* @param appId - The app to scope realtime traffic to (BigInt as a decimal string).
|
|
134
|
+
*/
|
|
135
|
+
world(appId) {
|
|
136
|
+
return new WorldClient(appId, this.udp);
|
|
137
|
+
}
|
|
138
|
+
/** Closes the WebSocket and clears the in-memory auth token. */
|
|
139
|
+
close() {
|
|
140
|
+
this.realtime.close();
|
|
141
|
+
this.session.setToken(null);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
export function createCrowdyClient(config = {}) {
|
|
145
|
+
return new CrowdyClient(config);
|
|
146
|
+
}
|