@crowdedkingdomstudios/crowdyjs 3.0.0 → 4.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.
Files changed (49) hide show
  1. package/README.md +125 -57
  2. package/dist/client.d.ts.map +1 -1
  3. package/dist/client.js +3 -1
  4. package/dist/crowdy-client.d.ts +41 -13
  5. package/dist/crowdy-client.d.ts.map +1 -1
  6. package/dist/crowdy-client.js +41 -16
  7. package/dist/domains/apps.d.ts +48 -20
  8. package/dist/domains/apps.d.ts.map +1 -1
  9. package/dist/domains/apps.js +58 -35
  10. package/dist/domains/auth.d.ts +33 -22
  11. package/dist/domains/auth.d.ts.map +1 -1
  12. package/dist/domains/auth.js +51 -33
  13. package/dist/domains/udp.d.ts +9 -1
  14. package/dist/domains/udp.d.ts.map +1 -1
  15. package/dist/domains/udp.js +14 -1
  16. package/dist/domains/users.d.ts +19 -16
  17. package/dist/domains/users.d.ts.map +1 -1
  18. package/dist/domains/users.js +21 -39
  19. package/dist/generated/graphql.d.ts +1077 -7
  20. package/dist/generated/graphql.d.ts.map +1 -1
  21. package/dist/generated/graphql.js +16 -9
  22. package/dist/index.d.ts +29 -14
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +30 -15
  25. package/dist/realtime.d.ts +3 -0
  26. package/dist/realtime.d.ts.map +1 -1
  27. package/dist/realtime.js +3 -0
  28. package/dist/types.d.ts +2 -31
  29. package/dist/types.d.ts.map +1 -1
  30. package/dist/types.js +5 -33
  31. package/dist/world.d.ts +9 -0
  32. package/dist/world.d.ts.map +1 -1
  33. package/dist/world.js +17 -0
  34. package/package.json +2 -1
  35. package/dist/domains/appAccess.d.ts +0 -23
  36. package/dist/domains/appAccess.d.ts.map +0 -1
  37. package/dist/domains/appAccess.js +0 -42
  38. package/dist/domains/billing.d.ts +0 -17
  39. package/dist/domains/billing.d.ts.map +0 -1
  40. package/dist/domains/billing.js +0 -31
  41. package/dist/domains/organizations.d.ts +0 -33
  42. package/dist/domains/organizations.d.ts.map +0 -1
  43. package/dist/domains/organizations.js +0 -90
  44. package/dist/domains/payments.d.ts +0 -20
  45. package/dist/domains/payments.d.ts.map +0 -1
  46. package/dist/domains/payments.js +0 -28
  47. package/dist/domains/quotas.d.ts +0 -20
  48. package/dist/domains/quotas.d.ts.map +0 -1
  49. package/dist/domains/quotas.js +0 -34
package/README.md CHANGED
@@ -1,8 +1,6 @@
1
- # CrowdyJS SDK
1
+ # CrowdyJS
2
2
 
3
- Browser-first SDK for Crowded Kingdoms game clients. CrowdyJS wraps the GraphQL
4
- API, the UDP proxy subscription, auth/session state, and spatial send helpers in
5
- one typed client.
3
+ The official browser-first TypeScript SDK for **Crowded Kingdoms**. CrowdyJS gives you one typed client that handles auth, the world/replication GraphQL API, and the UDP proxy subscription stream behind a single shared session.
6
4
 
7
5
  ## Install
8
6
 
@@ -10,11 +8,9 @@ one typed client.
10
8
  npm install @crowdedkingdomstudios/crowdyjs
11
9
  ```
12
10
 
13
- CrowdyJS v3 targets browsers by default and uses native `fetch`, `WebSocket`,
14
- `crypto`, `btoa`, and `atob`. Node tools can still use the SDK, but must provide
15
- browser-compatible globals when they open realtime connections.
11
+ CrowdyJS v4 targets browsers by default and uses native `fetch`, `WebSocket`, `crypto`, `btoa`, and `atob`. Node tools can still use the SDK, but must provide browser-compatible globals when opening realtime connections.
16
12
 
17
- ## Quick Start
13
+ ## Quick start
18
14
 
19
15
  ```ts
20
16
  import {
@@ -23,8 +19,11 @@ import {
23
19
  } from '@crowdedkingdomstudios/crowdyjs';
24
20
 
25
21
  const client = createCrowdyClient({
26
- httpUrl: 'https://api.example.com/graphql',
27
- wsUrl: 'wss://api.example.com/graphql',
22
+ // Game API (world data + UDP proxy)
23
+ httpUrl: 'https://game.example.com',
24
+ wsUrl: 'wss://game.example.com',
25
+ // Management API (login, register, profile)
26
+ managementUrl: 'https://management.example.com',
28
27
  tokenStore: new BrowserLocalStorageTokenStore(),
29
28
  realtime: {
30
29
  retryAttempts: 8,
@@ -32,35 +31,78 @@ const client = createCrowdyClient({
32
31
  },
33
32
  });
34
33
 
34
+ // Restore a previous session if there is one, otherwise log in.
35
35
  await client.session.restore();
36
-
37
36
  if (!client.session.getToken()) {
38
37
  await client.auth.login({ email: 'player@example.com', password: 'secret' });
39
38
  }
40
39
 
40
+ // Fetch the per-app bootstrap (version requirements, UDP availability, spatial limits).
41
41
  const bootstrap = await client.serverStatus.gameClientBootstrap('1');
42
42
  console.log(bootstrap.versionInfo.minimumClientVersion);
43
43
  ```
44
44
 
45
- ## Game Loop Lifecycle
45
+ Both endpoints share a single `AuthState`, so once `client.auth.login()` returns, every subsequent SDK call (against either endpoint) carries the bearer token automatically.
46
+
47
+ If `managementUrl` is omitted, the SDK falls back to `httpUrl` for backwards-compat with the single-endpoint deployment.
48
+
49
+ ## Sub-clients at a glance
50
+
51
+ | Sub-client | What it does |
52
+ |---|---|
53
+ | `client.auth` | Register, log in, log out, password reset, email confirmation. |
54
+ | `client.users` | `me`, `updateGamertag`, profile reads. |
55
+ | `client.session` | Token store, `restore()`, `getToken()`, manual `setToken()`. |
56
+ | `client.serverStatus` | `gameClientBootstrap(appId)` — per-app version info, UDP status, spatial limits. |
57
+ | `client.chunks`, `client.voxels`, `client.actors`, `client.avatars`, `client.state` | World data reads + writes. |
58
+ | `client.teleport` | Teleport requests. |
59
+ | `client.udp` | UDP proxy subscriptions + spatial mutations (`sendActorUpdate`, `sendVoxelUpdate`, `sendAudioPacket`, `sendTextPacket`, `sendClientEvent`). |
60
+ | `client.realtime` | Connection status, manual `connect()` / `disconnect()`, `onStatus()` listener. |
61
+ | `client.world(appId)` | Higher-level helpers for browser games (`actor.join`, `actor.sendState`, `actor.sendText`). |
46
62
 
47
- 1. Authenticate with `client.auth.login()` or restore a previous token through
48
- `client.session.restore()`.
49
- 2. Subscribe to UDP proxy notifications with `client.udp.subscribe()` or
50
- `client.realtime.connect()`.
63
+ Auth and user reads always target `managementUrl`. Everything else targets `httpUrl` / `wsUrl`.
64
+
65
+ ## Game-loop lifecycle
66
+
67
+ 1. Authenticate with `client.auth.login()` or restore a previous token through `client.session.restore()`.
68
+ 2. Subscribe to UDP proxy notifications with `client.udp.subscribe()` (the SDK will open the realtime socket on demand).
51
69
  3. Join a chunk by sending an initial actor update.
52
- 4. Send actor, voxel, text, audio, and client-event updates through `client.udp`
53
- or the higher-level `client.world(appId)` helpers.
54
- 5. Call `client.udp.disconnect()` when leaving the world, then `client.close()`
55
- when disposing the SDK instance.
70
+ 4. Send actor, voxel, text, audio, and client-event updates through `client.udp` or the higher-level `client.world(appId)` helpers.
71
+ 5. Call `client.udp.disconnect()` when leaving the world.
72
+ 6. Call `client.close()` when disposing the SDK instance.
56
73
 
57
- ## Realtime Notifications
74
+ ## Per-app routing
75
+
76
+ When a player is about to join an app, query its routing fields on the management API first:
77
+
78
+ ```graphql
79
+ query AppForRouting($id: BigInt!) {
80
+ app(id: $id) {
81
+ appId
82
+ splitMode
83
+ gameApiUrl
84
+ }
85
+ }
86
+ ```
87
+
88
+ If `splitMode && gameApiUrl`, the app lives behind its own Game API deployment. Build a **second** `CrowdyClient` with `httpUrl: gameApiUrl` (and the matching `wsUrl`) **sharing the same `tokenStore` as the first client**, then drive gameplay through that client. Apps without `splitMode` keep working against the default `httpUrl` you configured.
89
+
90
+ ## Realtime notifications
58
91
 
59
92
  ```ts
60
93
  const unsubscribe = client.udp.subscribe({
61
94
  actorUpdate: (event) => {
62
95
  console.log(event.uuid, event.state);
63
96
  },
97
+ voxelUpdate: (event) => { /* ... */ },
98
+ text: (event) => { /* ... */ },
99
+ audio: (event) => { /* ... */ },
100
+ clientEvent: (event) => { /* ... */ },
101
+ serverEvent: (event) => { /* ... */ },
102
+ singleActorMessage: (event) => {
103
+ // A direct actor-to-actor message addressed to you.
104
+ console.log(event.uuid, event.payload); // payload is base64
105
+ },
64
106
  genericError: (event) => {
65
107
  console.warn(event.sequenceNumber, event.errorCode);
66
108
  },
@@ -75,20 +117,21 @@ const unsubscribe = client.udp.subscribe({
75
117
  client.realtime.onStatus((status) => {
76
118
  console.log('realtime:', status);
77
119
  });
120
+
121
+ // Later:
122
+ unsubscribe();
78
123
  ```
79
124
 
80
- The SDK uses the `graphql-transport-ws` protocol through `graphql-ws`, reconnects
81
- with backoff, re-reads the current token before reconnecting, and resubscribes to
82
- the generated `UdpNotifications` document.
125
+ The SDK uses the `graphql-transport-ws` protocol through `graphql-ws`, reconnects with backoff, re-reads the current token before reconnecting, and resubscribes automatically.
83
126
 
84
- ## Raw UDP Sends
127
+ ## Spatial sends
85
128
 
86
129
  ```ts
87
130
  const response = await client.udp.sendActorUpdateAndWait({
88
131
  appId: '1',
89
132
  chunk: { x: '0', y: '0', z: '0' },
90
133
  uuid: '0123456789abcdef0123456789abcdef',
91
- state: 'AA==',
134
+ state: 'AA==', // base64-encoded payload
92
135
  distance: 8,
93
136
  decayRate: 1,
94
137
  });
@@ -96,12 +139,24 @@ const response = await client.udp.sendActorUpdateAndWait({
96
139
  console.log(response.__typename, response.sequenceNumber);
97
140
  ```
98
141
 
99
- The plain `sendActorUpdate`, `sendVoxelUpdate`, `sendAudioPacket`,
100
- `sendTextPacket`, and `sendClientEvent` methods return the GraphQL mutation
101
- result immediately. The `AndWait` variants allocate a `sequenceNumber` when one
102
- is missing and wait for either a matching notification or `GenericErrorResponse`.
142
+ The plain `sendActorUpdate`, `sendVoxelUpdate`, `sendAudioPacket`, `sendTextPacket`, and `sendClientEvent` methods return the GraphQL mutation result immediately. The `AndWait` variants allocate a `sequenceNumber` when one is missing and wait for either a matching notification or `GenericErrorResponse`.
103
143
 
104
- ## World Helpers
144
+ ### Actor-to-actor messages
145
+
146
+ ```ts
147
+ // Delivered only to the actor whose UUID matches `targetUuid`; you must know
148
+ // that actor's current chunk. Fire-and-forget — the sender gets no echo, so
149
+ // there is no `AndWait` variant. The target receives a
150
+ // `SingleActorMessageNotification` on its subscription.
151
+ await client.udp.sendSingleActorMessage({
152
+ appId: '1',
153
+ chunk: { x: '7', y: '1', z: '2' }, // the TARGET actor's chunk
154
+ targetUuid: '0123456789abcdef0123456789abcdef',
155
+ payload: 'aGVsbG8=', // base64; embed sender identity here if you need it
156
+ });
157
+ ```
158
+
159
+ ## World helpers
105
160
 
106
161
  ```ts
107
162
  const world = client.world('1');
@@ -110,29 +165,48 @@ const actor = world.actor();
110
165
  await actor.join({ x: '0', y: '0', z: '0' });
111
166
  await actor.sendState('AA==');
112
167
  await actor.sendText('hello nearby players');
168
+
169
+ // Direct message to one other actor (you supply its UUID + current chunk):
170
+ await actor.sendToActor(
171
+ '0123456789abcdef0123456789abcdef',
172
+ 'aGVsbG8=', // base64 payload
173
+ { x: '7', y: '1', z: '2' },
174
+ );
113
175
  ```
114
176
 
115
- The world helpers are convenience wrappers for browser games. Advanced callers
116
- can always use `client.udp.*` with generated GraphQL input types.
177
+ The world helpers are thin wrappers over `client.udp.*` with the appId pre-bound — convenient for browser games. Advanced callers can always use `client.udp.*` with the generated GraphQL input types directly.
117
178
 
118
179
  ## Errors
119
180
 
120
- Transport and protocol failures use structured error classes:
181
+ Transport and protocol failures throw structured error classes:
182
+
183
+ - `CrowdyHttpError` — non-2xx response from a GraphQL endpoint.
184
+ - `CrowdyGraphQLError` — preserves every GraphQL error including `path` and `extensions.code`.
185
+ - `CrowdyNetworkError` — network-level failure (DNS, TLS, connection refused).
186
+ - `CrowdyTimeoutError` — request or `AndWait` timed out.
187
+ - `CrowdyRealtimeError` — realtime subscription couldn't be established or was dropped.
188
+ - `CrowdyProtocolError` — server response failed schema validation.
121
189
 
122
- - `CrowdyHttpError`
123
- - `CrowdyGraphQLError`
124
- - `CrowdyNetworkError`
125
- - `CrowdyTimeoutError`
126
- - `CrowdyRealtimeError`
127
- - `CrowdyProtocolError`
190
+ ## Auth notes
128
191
 
129
- `CrowdyGraphQLError` preserves every GraphQL error, including `path` and
130
- `extensions.code`.
192
+ - Use `client.auth.setToken(token)` if you need to seed a token externally (e.g. when restoring auth from a non-default storage).
193
+ - `client.session.restore()` reads from the configured `tokenStore`. `BrowserLocalStorageTokenStore` is provided; bring your own for SSR or Node usage.
194
+ - A single `AuthState` is observed by both the HTTP client and the realtime socket, so HTTP and WebSocket auth can never drift.
131
195
 
132
- ## Low-Level GraphQL Access
196
+ ## What's NOT in CrowdyJS
133
197
 
134
- Game-client methods are first-class, but generated operations are still
135
- available through the transport escape hatch:
198
+ CrowdyJS focuses on the **game-client surface**: auth, world data, UDP proxy, profile reads. The following operations are **not** exposed by the SDK and should be called against the management GraphQL API directly (with a server-side token, typically from a studio backend):
199
+
200
+ - Org / app / billing / payments / quotas operations
201
+ - Access-tier and runtime-permission administration
202
+ - Game-token issuance / revocation
203
+ - Marketplace and catalog management
204
+
205
+ The SDK is intentionally scoped to client-side, end-user-facing flows.
206
+
207
+ ## Low-level GraphQL access
208
+
209
+ Game-client methods are first-class, but generated operation documents are also available through a transport escape hatch:
136
210
 
137
211
  ```ts
138
212
  import { VersionInfoDocument } from '@crowdedkingdomstudios/crowdyjs/generated';
@@ -140,18 +214,12 @@ import { VersionInfoDocument } from '@crowdedkingdomstudios/crowdyjs/generated';
140
214
  const data = await client.graphql.request(VersionInfoDocument);
141
215
  ```
142
216
 
143
- Most consumers should prefer the methods on `client.auth`, `client.udp`,
144
- `client.serverStatus`, `client.users`, `client.apps`, and `client.world()`.
217
+ Most consumers should prefer the typed methods on `client.auth`, `client.users`, `client.udp`, `client.serverStatus`, and `client.world()`.
145
218
 
146
- ## Development
219
+ ## Migration
147
220
 
148
- ```bash
149
- npm install
150
- npm run codegen
151
- npm run build
152
- npm test
153
- ```
221
+ See [MIGRATION.md](MIGRATION.md) for breaking changes between SDK majors.
222
+
223
+ ## License
154
224
 
155
- `npm run codegen` syncs `../cks-graphql-api/schema.gql` when the API repo is
156
- checked out beside this SDK. `npm run check:schema` fails if the committed SDL or
157
- generated types drift from the API schema.
225
+ MIT
@@ -1 +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,MAAM,WAAW,mBAAmB;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB;AAED,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;gBAE1B,MAAM,EAAE,mBAAmB,YAAK,EAAE,OAAO,EAAE,YAAY;IAQnE,WAAW,IAAI,MAAM;IAIrB;;;OAGG;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;;;;OAIG;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,OAAO,EAAE,aAAa,IAAI,gBAAgB,EAAE,CAAC"}
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,MAAM,WAAW,mBAAmB;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB;AAED,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;gBAE1B,MAAM,EAAE,mBAAmB,YAAK,EAAE,OAAO,EAAE,YAAY;IAUnE,WAAW,IAAI,MAAM;IAIrB;;;OAGG;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;;;;OAIG;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,OAAO,EAAE,aAAa,IAAI,gBAAgB,EAAE,CAAC"}
package/dist/client.js CHANGED
@@ -12,7 +12,9 @@ import { CrowdyError, CrowdyGraphQLError, CrowdyHttpError, CrowdyNetworkError, C
12
12
  export class GraphQLClient {
13
13
  constructor(config = {}, session) {
14
14
  this.graphqlEndpoint =
15
- config.httpUrl || config.graphqlEndpoint || 'http://localhost:3000/graphql';
15
+ config.graphqlEndpoint ||
16
+ config.httpUrl ||
17
+ 'http://localhost:3000/graphql';
16
18
  this.timeout = config.timeout || 60000;
17
19
  this.session = session;
18
20
  this.logger = config.logger ?? silentLogger;
@@ -1,9 +1,24 @@
1
1
  /**
2
2
  * Public surface of the SDK. Construct one `CrowdyClient` per session and
3
3
  * access everything via the typed sub-clients (`client.auth`, `client.udp`,
4
- * `client.orgs`, ...). The legacy `client.login()` / `client.sendActorUpdate`
5
- * shortcuts are gone - use `client.auth.login()` / `client.udp.sendActorUpdate()`
6
- * instead.
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.
7
22
  */
8
23
  import { AuthState } from './auth-state.js';
9
24
  import { GraphQLClient } from './client.js';
@@ -13,12 +28,7 @@ import type { TokenStore } from './session.js';
13
28
  import { WorldClient } from './world.js';
14
29
  import { AuthAPI } from './domains/auth.js';
15
30
  import { UsersAPI } from './domains/users.js';
16
- import { OrganizationsAPI } from './domains/organizations.js';
17
31
  import { AppsAPI } from './domains/apps.js';
18
- import { AppAccessAPI } from './domains/appAccess.js';
19
- import { BillingAPI } from './domains/billing.js';
20
- import { QuotasAPI } from './domains/quotas.js';
21
- import { PaymentsAPI } from './domains/payments.js';
22
32
  import { ChunksAPI } from './domains/chunks.js';
23
33
  import { VoxelsAPI } from './domains/voxels.js';
24
34
  import { ActorsAPI } from './domains/actors.js';
@@ -27,10 +37,24 @@ import { StateAPI } from './domains/state.js';
27
37
  import { ServerStatusAPI } from './domains/serverStatus.js';
28
38
  import { UdpAPI } from './domains/udp.js';
29
39
  export interface CrowdyClientConfig {
40
+ /** game-api HTTP root (e.g. `https://dev-game-api.crowdedkingdoms.com`). */
30
41
  httpUrl?: string;
42
+ /** game-api WS root. */
31
43
  wsUrl?: string;
44
+ /** game-api GraphQL endpoint. Defaults to `${httpUrl}/graphql`. */
32
45
  graphqlEndpoint?: string;
46
+ /** game-api WS endpoint. Defaults to `${wsUrl}/graphql`. */
33
47
  wsEndpoint?: string;
48
+ /**
49
+ * management-api HTTP root (e.g.
50
+ * `https://dev-management-api.crowdedkingdoms.com`). When set,
51
+ * `client.auth` and `client.users` route here. If left empty the SDK
52
+ * falls back to `httpUrl` for backwards-compatibility with the legacy
53
+ * single-endpoint deployment, but new code should set this explicitly.
54
+ */
55
+ managementUrl?: string;
56
+ /** management-api GraphQL endpoint. Defaults to `${managementUrl}/graphql`. */
57
+ managementGraphqlEndpoint?: string;
34
58
  timeout?: number;
35
59
  tokenStore?: TokenStore;
36
60
  logger?: CrowdyLogger;
@@ -42,17 +66,17 @@ export interface CrowdyClientConfig {
42
66
  };
43
67
  }
44
68
  export declare class CrowdyClient {
69
+ /** Shared token state for both game-api and management-api requests. */
45
70
  readonly session: AuthState;
71
+ /** game-api HTTP client. */
46
72
  readonly graphql: GraphQLClient;
73
+ /** game-api WebSocket subscription manager. */
47
74
  readonly realtime: SubscriptionManager;
75
+ /** management-api HTTP client. Same `AuthState` as `graphql`. */
76
+ readonly management: GraphQLClient;
48
77
  readonly auth: AuthAPI;
49
78
  readonly users: UsersAPI;
50
- readonly orgs: OrganizationsAPI;
51
79
  readonly apps: AppsAPI;
52
- readonly appAccess: AppAccessAPI;
53
- readonly billing: BillingAPI;
54
- readonly quotas: QuotasAPI;
55
- readonly payments: PaymentsAPI;
56
80
  readonly chunks: ChunksAPI;
57
81
  readonly voxels: VoxelsAPI;
58
82
  readonly actors: ActorsAPI;
@@ -61,6 +85,10 @@ export declare class CrowdyClient {
61
85
  readonly serverStatus: ServerStatusAPI;
62
86
  readonly udp: UdpAPI;
63
87
  constructor(config?: CrowdyClientConfig);
88
+ /** Imperatively set the Bearer token (useful for SSO / token rehydrate). */
89
+ setToken(token: string | null): void;
90
+ /** Read the current Bearer token (null if no session). */
91
+ getToken(): string | null;
64
92
  world(appId: string): WorldClient;
65
93
  /** Closes the WebSocket and clears the in-memory auth token. */
66
94
  close(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"crowdy-client.d.ts","sourceRoot":"","sources":["../src/crowdy-client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"crowdy-client.d.ts","sourceRoot":"","sources":["../src/crowdy-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,MAAM,WAAW,kBAAkB;IAEjC,4EAA4E;IAC5E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,wBAAwB;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mEAAmE;IACnE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,4DAA4D;IAC5D,UAAU,CAAC,EAAE,MAAM,CAAC;IAGpB;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,+EAA+E;IAC/E,yBAAyB,CAAC,EAAE,MAAM,CAAC;IAGnC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,QAAQ,CAAC,EAAE;QACT,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,mBAAmB,CAAC,EAAE,MAAM,CAAC;QAC7B,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB,CAAC;CACH;AAED,qBAAa,YAAY;IACvB,wEAAwE;IACxE,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAC;IAC5B,4BAA4B;IAC5B,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;IAChC,+CAA+C;IAC/C,QAAQ,CAAC,QAAQ,EAAE,mBAAmB,CAAC;IACvC,iEAAiE;IACjE,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC;IAGnC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAGvB,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;IACzB,QAAQ,CAAC,YAAY,EAAE,eAAe,CAAC;IACvC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;gBAET,MAAM,GAAE,kBAAuB;IAsD3C,4EAA4E;IAC5E,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAIpC,0DAA0D;IAC1D,QAAQ,IAAI,MAAM,GAAG,IAAI;IAIzB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW;IAIjC,gEAAgE;IAChE,KAAK,IAAI,IAAI;CAId;AAED,wBAAgB,kBAAkB,CAChC,MAAM,GAAE,kBAAuB,GAC9B,YAAY,CAEd"}
@@ -1,9 +1,24 @@
1
1
  /**
2
2
  * Public surface of the SDK. Construct one `CrowdyClient` per session and
3
3
  * access everything via the typed sub-clients (`client.auth`, `client.udp`,
4
- * `client.orgs`, ...). The legacy `client.login()` / `client.sendActorUpdate`
5
- * shortcuts are gone - use `client.auth.login()` / `client.udp.sendActorUpdate()`
6
- * instead.
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.
7
22
  */
8
23
  import { AuthState } from './auth-state.js';
9
24
  import { GraphQLClient } from './client.js';
@@ -11,12 +26,7 @@ import { SubscriptionManager } from './subscriptions.js';
11
26
  import { WorldClient } from './world.js';
12
27
  import { AuthAPI } from './domains/auth.js';
13
28
  import { UsersAPI } from './domains/users.js';
14
- import { OrganizationsAPI } from './domains/organizations.js';
15
29
  import { AppsAPI } from './domains/apps.js';
16
- import { AppAccessAPI } from './domains/appAccess.js';
17
- import { BillingAPI } from './domains/billing.js';
18
- import { QuotasAPI } from './domains/quotas.js';
19
- import { PaymentsAPI } from './domains/payments.js';
20
30
  import { ChunksAPI } from './domains/chunks.js';
21
31
  import { VoxelsAPI } from './domains/voxels.js';
22
32
  import { ActorsAPI } from './domains/actors.js';
@@ -39,14 +49,21 @@ export class CrowdyClient {
39
49
  logger: config.logger,
40
50
  ...config.realtime,
41
51
  }, this.session);
42
- this.auth = new AuthAPI(this.graphql, this.session);
43
- this.users = new UsersAPI(this.graphql);
44
- this.orgs = new OrganizationsAPI(this.graphql);
45
- this.apps = new AppsAPI(this.graphql);
46
- this.appAccess = new AppAccessAPI(this.graphql);
47
- this.billing = new BillingAPI(this.graphql);
48
- this.quotas = new QuotasAPI(this.graphql);
49
- this.payments = new PaymentsAPI(this.graphql);
52
+ const managementGraphqlEndpoint = config.managementGraphqlEndpoint ??
53
+ (config.managementUrl
54
+ ? `${config.managementUrl.replace(/\/$/, '')}/graphql`
55
+ : config.graphqlEndpoint);
56
+ // Management-api client. Falls back to game-api endpoint if the caller
57
+ // hasn't configured `managementUrl` yet (single-endpoint legacy mode).
58
+ this.management = new GraphQLClient({
59
+ httpUrl: config.managementUrl ?? config.httpUrl,
60
+ graphqlEndpoint: managementGraphqlEndpoint,
61
+ timeout: config.timeout,
62
+ logger: config.logger,
63
+ }, this.session);
64
+ this.auth = new AuthAPI(this.management, this.session);
65
+ this.users = new UsersAPI(this.management);
66
+ this.apps = new AppsAPI(this.management);
50
67
  this.chunks = new ChunksAPI(this.graphql);
51
68
  this.voxels = new VoxelsAPI(this.graphql);
52
69
  this.actors = new ActorsAPI(this.graphql);
@@ -55,6 +72,14 @@ export class CrowdyClient {
55
72
  this.serverStatus = new ServerStatusAPI(this.graphql);
56
73
  this.udp = new UdpAPI(this.graphql, this.realtime);
57
74
  }
75
+ /** Imperatively set the Bearer token (useful for SSO / token rehydrate). */
76
+ setToken(token) {
77
+ this.session.setToken(token);
78
+ }
79
+ /** Read the current Bearer token (null if no session). */
80
+ getToken() {
81
+ return this.session.getToken();
82
+ }
58
83
  world(appId) {
59
84
  return new WorldClient(appId, this.udp);
60
85
  }
@@ -1,27 +1,55 @@
1
- import type { GraphQLClient } from '../client.js';
2
- import { type AppQuery, type AppQueryVariables, type AppBySlugQuery, type AppBySlugQueryVariables, type MyAppsQuery, type AppsForOrgQuery, type AppsForOrgQueryVariables, type MarketplaceAppsQuery, type MarketplaceAppsQueryVariables, type CreateAppMutation, type CreateAppMutationVariables, type UpdateAppMutation, type UpdateAppMutationVariables, type ArchiveAppMutationVariables, type SetAppVisibilityMutation, type SetAppVisibilityMutationVariables } from '../generated/graphql.js';
3
1
  /**
4
- * App (game / world) lifecycle and discovery. Exposed as `client.apps`.
2
+ * Apps sub-client. Targets `cks-management-api` (where the apps catalog
3
+ * lives). After the DB split each app may be served by its own per-tenant
4
+ * cks-game-api; the marketplace returns `gameApiUrl` for those rows so the
5
+ * caller can build a per-app `CrowdyClient` against the correct endpoint.
6
+ *
7
+ * Typical pattern:
5
8
  *
6
- * `marketplace()` is a public listing (no auth) of every app where
7
- * visibility = PUBLIC and status = LIVE; the rest of the methods require
8
- * either org-membership permissions or super admin.
9
+ * const baseClient = createCrowdyClient({
10
+ * managementUrl: 'https://api.example.com',
11
+ * httpUrl: 'https://legacy-game-api.example.com', // pre-split fallback
12
+ * });
13
+ * await baseClient.auth.login({ email, password });
14
+ *
15
+ * const route = await baseClient.apps.routeFor(appId);
16
+ * if (route.splitMode && route.gameApiUrl) {
17
+ * const perAppClient = createCrowdyClient({
18
+ * managementUrl: 'https://api.example.com',
19
+ * httpUrl: route.gameApiUrl,
20
+ * wsUrl: route.gameApiUrl.replace(/^https?/, 'wss'),
21
+ * tokenStore: baseClient.session.tokenStore,
22
+ * });
23
+ * // drive gameplay through perAppClient
24
+ * }
9
25
  */
26
+ import type { GraphQLClient } from '../client.js';
27
+ import { type AppQuery, type AppBySlugQuery, type MyAppsQuery } from '../generated/graphql.js';
28
+ /**
29
+ * Subset of an `App` row that the SDK exposes for routing decisions. The
30
+ * fields are typed loosely as `unknown` because the generated types lag
31
+ * behind the `splitMode` / `gameApiUrl` selection until codegen runs.
32
+ */
33
+ export interface AppRoute {
34
+ appId: string;
35
+ splitMode: boolean;
36
+ gameApiUrl: string | null;
37
+ }
10
38
  export declare class AppsAPI {
11
- private gql;
12
- constructor(gql: GraphQLClient);
13
- marketplace(args?: MarketplaceAppsQueryVariables): Promise<MarketplaceAppsQuery['apps']>;
14
- byId(appId: AppQueryVariables['appId']): Promise<AppQuery['app']>;
15
- bySlug(args: AppBySlugQueryVariables): Promise<AppBySlugQuery['appBySlug']>;
39
+ private readonly management;
40
+ constructor(management: GraphQLClient);
41
+ /** Fetch a single app by id. */
42
+ app(appId: string): Promise<AppQuery['app']>;
43
+ /** Fetch by org slug + app slug (marketplace links). */
44
+ appBySlug(orgSlug: string, appSlug: string): Promise<AppBySlugQuery['appBySlug']>;
45
+ /** Apps the caller can play (org membership OR active access). */
16
46
  myApps(): Promise<MyAppsQuery['myApps']>;
17
- forOrg(orgSlug: AppsForOrgQueryVariables['orgSlug']): Promise<AppsForOrgQuery['appsForOrg']>;
18
- create(input: CreateAppMutationVariables['input']): Promise<CreateAppMutation['createApp']>;
19
- update(args: UpdateAppMutationVariables): Promise<UpdateAppMutation['updateApp']>;
20
- archive(appId: ArchiveAppMutationVariables['appId']): Promise<{
21
- appId: any;
22
- status: string;
23
- updatedAt: any;
24
- }>;
25
- setVisibility(args: SetAppVisibilityMutationVariables): Promise<SetAppVisibilityMutation['setAppVisibility']>;
47
+ /**
48
+ * Convenience: returns just the routing tuple for a given app. If the
49
+ * app row is missing or the API does not expose split-mode fields yet,
50
+ * returns `{ appId, splitMode: false, gameApiUrl: null }` so the caller
51
+ * keeps using the legacy single-endpoint deployment.
52
+ */
53
+ routeFor(appId: string): Promise<AppRoute>;
26
54
  }
27
55
  //# sourceMappingURL=apps.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"apps.d.ts","sourceRoot":"","sources":["../../src/domains/apps.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,OAAO,EAEL,KAAK,QAAQ,EACb,KAAK,iBAAiB,EAEtB,KAAK,cAAc,EACnB,KAAK,uBAAuB,EAE5B,KAAK,WAAW,EAEhB,KAAK,eAAe,EACpB,KAAK,wBAAwB,EAE7B,KAAK,oBAAoB,EACzB,KAAK,6BAA6B,EAElC,KAAK,iBAAiB,EACtB,KAAK,0BAA0B,EAE/B,KAAK,iBAAiB,EACtB,KAAK,0BAA0B,EAE/B,KAAK,2BAA2B,EAEhC,KAAK,wBAAwB,EAC7B,KAAK,iCAAiC,EACvC,MAAM,yBAAyB,CAAC;AAEjC;;;;;;GAMG;AACH,qBAAa,OAAO;IACN,OAAO,CAAC,GAAG;gBAAH,GAAG,EAAE,aAAa;IAEhC,WAAW,CACf,IAAI,GAAE,6BAAkC,GACvC,OAAO,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAKlC,IAAI,CAAC,KAAK,EAAE,iBAAiB,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAKjE,MAAM,CACV,IAAI,EAAE,uBAAuB,GAC5B,OAAO,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;IAKjC,MAAM,IAAI,OAAO,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;IAKxC,MAAM,CACV,OAAO,EAAE,wBAAwB,CAAC,SAAS,CAAC,GAC3C,OAAO,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC;IAKnC,MAAM,CACV,KAAK,EAAE,0BAA0B,CAAC,OAAO,CAAC,GACzC,OAAO,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;IAKpC,MAAM,CACV,IAAI,EAAE,0BAA0B,GAC/B,OAAO,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;IAKpC,OAAO,CACX,KAAK,EAAE,2BAA2B,CAAC,OAAO,CAAC,GAC1C,OAAO,CAAC;QAAE,KAAK,EAAE,GAAG,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,GAAG,CAAA;KAAE,CAAC;IAKpD,aAAa,CACjB,IAAI,EAAE,iCAAiC,GACtC,OAAO,CAAC,wBAAwB,CAAC,kBAAkB,CAAC,CAAC;CAIzD"}
1
+ {"version":3,"file":"apps.d.ts","sourceRoot":"","sources":["../../src/domains/apps.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAIL,KAAK,QAAQ,EAEb,KAAK,cAAc,EAEnB,KAAK,WAAW,EACjB,MAAM,yBAAyB,CAAC;AAEjC;;;;GAIG;AACH,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAcD,qBAAa,OAAO;IACN,OAAO,CAAC,QAAQ,CAAC,UAAU;gBAAV,UAAU,EAAE,aAAa;IAEtD,gCAAgC;IAC1B,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAQlD,wDAAwD;IAClD,SAAS,CACb,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;IAQvC,kEAAkE;IAC5D,MAAM,IAAI,OAAO,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;IAQ9C;;;;;OAKG;IACG,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;CAUjD"}