@crowdedkingdomstudios/crowdyjs 5.2.0 → 5.2.1

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 (71) hide show
  1. package/MIGRATION.md +22 -0
  2. package/dist/client.d.ts +98 -5
  3. package/dist/client.d.ts.map +1 -1
  4. package/dist/client.js +74 -5
  5. package/dist/crowdy-client.d.ts +31 -0
  6. package/dist/crowdy-client.d.ts.map +1 -1
  7. package/dist/crowdy-client.js +8 -0
  8. package/dist/domains/actors.d.ts +87 -4
  9. package/dist/domains/actors.d.ts.map +1 -1
  10. package/dist/domains/actors.js +87 -4
  11. package/dist/domains/apps.d.ts +95 -41
  12. package/dist/domains/apps.d.ts.map +1 -1
  13. package/dist/domains/apps.js +80 -33
  14. package/dist/domains/auth.d.ts +139 -19
  15. package/dist/domains/auth.d.ts.map +1 -1
  16. package/dist/domains/auth.js +137 -17
  17. package/dist/domains/channels.d.ts +264 -5
  18. package/dist/domains/channels.d.ts.map +1 -1
  19. package/dist/domains/channels.js +264 -5
  20. package/dist/domains/chunks.d.ts +116 -3
  21. package/dist/domains/chunks.d.ts.map +1 -1
  22. package/dist/domains/chunks.js +116 -3
  23. package/dist/domains/gameModel.d.ts +412 -6
  24. package/dist/domains/gameModel.d.ts.map +1 -1
  25. package/dist/domains/gameModel.js +412 -6
  26. package/dist/domains/platform.d.ts +36 -20
  27. package/dist/domains/platform.d.ts.map +1 -1
  28. package/dist/domains/platform.js +29 -18
  29. package/dist/domains/serverStatus.d.ts +74 -6
  30. package/dist/domains/serverStatus.d.ts.map +1 -1
  31. package/dist/domains/serverStatus.js +74 -6
  32. package/dist/domains/state.d.ts +50 -2
  33. package/dist/domains/state.d.ts.map +1 -1
  34. package/dist/domains/state.js +50 -2
  35. package/dist/domains/teams.d.ts +263 -5
  36. package/dist/domains/teams.d.ts.map +1 -1
  37. package/dist/domains/teams.js +263 -5
  38. package/dist/domains/teleport.d.ts +30 -2
  39. package/dist/domains/teleport.d.ts.map +1 -1
  40. package/dist/domains/teleport.js +30 -2
  41. package/dist/domains/udp.d.ts +341 -5
  42. package/dist/domains/udp.d.ts.map +1 -1
  43. package/dist/domains/udp.js +341 -5
  44. package/dist/domains/users.d.ts +42 -11
  45. package/dist/domains/users.d.ts.map +1 -1
  46. package/dist/domains/users.js +41 -10
  47. package/dist/domains/voxels.d.ts +107 -2
  48. package/dist/domains/voxels.d.ts.map +1 -1
  49. package/dist/domains/voxels.js +107 -2
  50. package/dist/errors.d.ts +116 -0
  51. package/dist/errors.d.ts.map +1 -1
  52. package/dist/errors.js +100 -0
  53. package/dist/index.d.ts +2 -1
  54. package/dist/index.d.ts.map +1 -1
  55. package/dist/index.js +2 -1
  56. package/dist/realtime.d.ts +226 -0
  57. package/dist/realtime.d.ts.map +1 -1
  58. package/dist/realtime.js +90 -0
  59. package/dist/session.d.ts +46 -0
  60. package/dist/session.d.ts.map +1 -1
  61. package/dist/session.js +35 -0
  62. package/dist/types.d.ts +429 -0
  63. package/dist/types.d.ts.map +1 -1
  64. package/dist/types.js +53 -0
  65. package/dist/utils.d.ts +86 -0
  66. package/dist/utils.d.ts.map +1 -1
  67. package/dist/utils.js +86 -0
  68. package/dist/world.d.ts +192 -0
  69. package/dist/world.d.ts.map +1 -1
  70. package/dist/world.js +170 -0
  71. package/package.json +1 -1
@@ -1,22 +1,90 @@
1
1
  import type { GraphQLClient } from '../client.js';
2
2
  import { type ServerWithLeastClientsQuery, type GraphqlServersQuery, type ActiveGraphQlServersQuery, type VersionInfoQuery, type GameClientBootstrapQuery, type GameClientBootstrapQueryVariables } from '../generated/graphql.js';
3
3
  /**
4
- * Server status / version info queries.
5
- *
4
+ * Server discovery, version, and client-bootstrap queries on the **game-api**.
6
5
  * Exposed as `client.serverStatus`.
7
6
  *
8
- * NOTE: there is no separate "buddy server" query in the schema -- the
9
- * least-loaded UDP game server is selected automatically when a session
10
- * is opened. `serverWithLeastClients` returns a hint of which UDP server
11
- * a new session would land on.
7
+ * This is the **client bootstrap path**: call {@link ServerStatusAPI.gameClientBootstrap}
8
+ * once after login to get everything a play session needs (identity, version
9
+ * floors, UDP status, realtime protocol details, and spatial limits) in a single
10
+ * round-trip, and use {@link ServerStatusAPI.versionInfo} for standalone version
11
+ * discovery / update gating. The remaining queries expose UDP/GraphQL server
12
+ * fleet info for discovery and routing.
13
+ *
14
+ * NOTE: there is no separate "buddy server" query in the schema — the
15
+ * least-loaded UDP game server is selected automatically when a session is
16
+ * opened. {@link ServerStatusAPI.serverWithLeastClients} returns a hint of which
17
+ * UDP server a new session would land on.
18
+ *
19
+ * Auth varies per method: {@link ServerStatusAPI.gameClientBootstrap} and
20
+ * {@link ServerStatusAPI.serverWithLeastClients} require a Bearer game token (set
21
+ * via `client.auth.login()` or `client.setToken()`), while
22
+ * {@link ServerStatusAPI.listAll}, {@link ServerStatusAPI.listActiveGraphqlServers}
23
+ * and {@link ServerStatusAPI.versionInfo} need no authentication. `appId` is a
24
+ * `BigInt` sent as a decimal string.
12
25
  */
13
26
  export declare class ServerStatusAPI {
14
27
  private gql;
15
28
  constructor(gql: GraphQLClient);
29
+ /**
30
+ * Pick a low-load UDP game server for a **native (direct-UDP)** client to
31
+ * connect to: returns a random server from the least-loaded ~20% (by client
32
+ * count) of `ReadyForClients` servers to spread load. As a side effect it
33
+ * authorizes the token's P2P session with the chosen Buddy so the native
34
+ * client's spatial datagrams are accepted; connect the client to the returned
35
+ * `ip4` + `clientPort`. Browser clients should instead use the UDP proxy
36
+ * (`client.udp` / `udpNotifications`) and do not need this.
37
+ *
38
+ * @returns A {@link ServerStatus} describing the selected UDP server.
39
+ * @throws {CrowdyGraphQLError} `UNAUTHENTICATED` if no valid game token is
40
+ * present.
41
+ */
16
42
  serverWithLeastClients(): Promise<ServerWithLeastClientsQuery['serverWithLeastClients']>;
43
+ /**
44
+ * List every registered GraphQL API server (both `management-api` and
45
+ * `game-api` kinds), regardless of health/state — for service discovery. To
46
+ * route clients, prefer {@link ServerStatusAPI.listActiveGraphqlServers}
47
+ * (healthy only). No authentication required.
48
+ *
49
+ * @returns Every registered {@link GraphQLServer}.
50
+ */
17
51
  listAll(): Promise<GraphqlServersQuery['graphqlServers']>;
52
+ /**
53
+ * List only healthy GraphQL API servers (`status = ReadyForClients`) for client
54
+ * routing/discovery. No authentication required.
55
+ *
56
+ * @returns The healthy {@link GraphQLServer}s.
57
+ */
18
58
  listActiveGraphqlServers(): Promise<ActiveGraphQlServersQuery['activeGraphQLServers']>;
59
+ /**
60
+ * Get the current server version and the minimum client version the server
61
+ * accepts. No authentication required — compare your build against
62
+ * `minimumClientVersion` before connecting and prompt an update if it is too
63
+ * old.
64
+ *
65
+ * @returns A {@link ServerVersionInfo} (`serverVersion` + `minimumClientVersion`,
66
+ * each a major/minor/patch/build {@link VersionInfo}).
67
+ */
19
68
  versionInfo(): Promise<VersionInfoQuery['versionInfo']>;
69
+ /**
70
+ * Single startup payload for browser game clients: the authenticated user,
71
+ * server/min-client version requirements, current UDP proxy status, realtime
72
+ * protocol details (subprotocol + subscription name), and the spatial send
73
+ * limits/constants. Read-only — does **not** open a UDP proxy session. Call this
74
+ * once after login to initialize a play session instead of issuing several
75
+ * separate queries.
76
+ *
77
+ * @param appId - The app (game) the client is initializing for (`BigInt` as a
78
+ * decimal string). Scopes the returned UDP status and mirrors the app's
79
+ * entitlements; reuse the same `appId` when subscribing and on every spatial
80
+ * send.
81
+ * @returns A {@link GameClientBootstrap}: `me`, `versionInfo`,
82
+ * `udpProxyConnectionStatus`, `realtimeProtocol`, `subscriptionName`, and the
83
+ * spatial limits `maxReplicationDistance` (max `distance` fan-out, in chunk
84
+ * units), `maxDecayRate`, and `sequenceNumberModulo` (256).
85
+ * @throws {CrowdyGraphQLError} `UNAUTHENTICATED` without a valid game token, or
86
+ * `FORBIDDEN` if not entitled to the app.
87
+ */
20
88
  gameClientBootstrap(appId: GameClientBootstrapQueryVariables['appId']): Promise<GameClientBootstrapQuery['gameClientBootstrap']>;
21
89
  }
22
90
  //# sourceMappingURL=serverStatus.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"serverStatus.d.ts","sourceRoot":"","sources":["../../src/domains/serverStatus.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,OAAO,EAEL,KAAK,2BAA2B,EAEhC,KAAK,mBAAmB,EAExB,KAAK,yBAAyB,EAE9B,KAAK,gBAAgB,EAErB,KAAK,wBAAwB,EAC7B,KAAK,iCAAiC,EACvC,MAAM,yBAAyB,CAAC;AAEjC;;;;;;;;;GASG;AACH,qBAAa,eAAe;IACd,OAAO,CAAC,GAAG;gBAAH,GAAG,EAAE,aAAa;IAEhC,sBAAsB,IAAI,OAAO,CAAC,2BAA2B,CAAC,wBAAwB,CAAC,CAAC;IAKxF,OAAO,IAAI,OAAO,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,CAAC;IAKzD,wBAAwB,IAAI,OAAO,CAAC,yBAAyB,CAAC,sBAAsB,CAAC,CAAC;IAKtF,WAAW,IAAI,OAAO,CAAC,gBAAgB,CAAC,aAAa,CAAC,CAAC;IAKvD,mBAAmB,CACvB,KAAK,EAAE,iCAAiC,CAAC,OAAO,CAAC,GAChD,OAAO,CAAC,wBAAwB,CAAC,qBAAqB,CAAC,CAAC;CAI5D"}
1
+ {"version":3,"file":"serverStatus.d.ts","sourceRoot":"","sources":["../../src/domains/serverStatus.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,OAAO,EAEL,KAAK,2BAA2B,EAEhC,KAAK,mBAAmB,EAExB,KAAK,yBAAyB,EAE9B,KAAK,gBAAgB,EAErB,KAAK,wBAAwB,EAC7B,KAAK,iCAAiC,EACvC,MAAM,yBAAyB,CAAC;AAEjC;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,eAAe;IACd,OAAO,CAAC,GAAG;gBAAH,GAAG,EAAE,aAAa;IAEtC;;;;;;;;;;;;OAYG;IACG,sBAAsB,IAAI,OAAO,CAAC,2BAA2B,CAAC,wBAAwB,CAAC,CAAC;IAK9F;;;;;;;OAOG;IACG,OAAO,IAAI,OAAO,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,CAAC;IAK/D;;;;;OAKG;IACG,wBAAwB,IAAI,OAAO,CAAC,yBAAyB,CAAC,sBAAsB,CAAC,CAAC;IAK5F;;;;;;;;OAQG;IACG,WAAW,IAAI,OAAO,CAAC,gBAAgB,CAAC,aAAa,CAAC,CAAC;IAK7D;;;;;;;;;;;;;;;;;;OAkBG;IACG,mBAAmB,CACvB,KAAK,EAAE,iCAAiC,CAAC,OAAO,CAAC,GAChD,OAAO,CAAC,wBAAwB,CAAC,qBAAqB,CAAC,CAAC;CAI5D"}
@@ -1,34 +1,102 @@
1
1
  import { ServerWithLeastClientsDocument, GraphqlServersDocument, ActiveGraphQlServersDocument, VersionInfoDocument, GameClientBootstrapDocument, } from '../generated/graphql.js';
2
2
  /**
3
- * Server status / version info queries.
4
- *
3
+ * Server discovery, version, and client-bootstrap queries on the **game-api**.
5
4
  * Exposed as `client.serverStatus`.
6
5
  *
7
- * NOTE: there is no separate "buddy server" query in the schema -- the
8
- * least-loaded UDP game server is selected automatically when a session
9
- * is opened. `serverWithLeastClients` returns a hint of which UDP server
10
- * a new session would land on.
6
+ * This is the **client bootstrap path**: call {@link ServerStatusAPI.gameClientBootstrap}
7
+ * once after login to get everything a play session needs (identity, version
8
+ * floors, UDP status, realtime protocol details, and spatial limits) in a single
9
+ * round-trip, and use {@link ServerStatusAPI.versionInfo} for standalone version
10
+ * discovery / update gating. The remaining queries expose UDP/GraphQL server
11
+ * fleet info for discovery and routing.
12
+ *
13
+ * NOTE: there is no separate "buddy server" query in the schema — the
14
+ * least-loaded UDP game server is selected automatically when a session is
15
+ * opened. {@link ServerStatusAPI.serverWithLeastClients} returns a hint of which
16
+ * UDP server a new session would land on.
17
+ *
18
+ * Auth varies per method: {@link ServerStatusAPI.gameClientBootstrap} and
19
+ * {@link ServerStatusAPI.serverWithLeastClients} require a Bearer game token (set
20
+ * via `client.auth.login()` or `client.setToken()`), while
21
+ * {@link ServerStatusAPI.listAll}, {@link ServerStatusAPI.listActiveGraphqlServers}
22
+ * and {@link ServerStatusAPI.versionInfo} need no authentication. `appId` is a
23
+ * `BigInt` sent as a decimal string.
11
24
  */
12
25
  export class ServerStatusAPI {
13
26
  constructor(gql) {
14
27
  this.gql = gql;
15
28
  }
29
+ /**
30
+ * Pick a low-load UDP game server for a **native (direct-UDP)** client to
31
+ * connect to: returns a random server from the least-loaded ~20% (by client
32
+ * count) of `ReadyForClients` servers to spread load. As a side effect it
33
+ * authorizes the token's P2P session with the chosen Buddy so the native
34
+ * client's spatial datagrams are accepted; connect the client to the returned
35
+ * `ip4` + `clientPort`. Browser clients should instead use the UDP proxy
36
+ * (`client.udp` / `udpNotifications`) and do not need this.
37
+ *
38
+ * @returns A {@link ServerStatus} describing the selected UDP server.
39
+ * @throws {CrowdyGraphQLError} `UNAUTHENTICATED` if no valid game token is
40
+ * present.
41
+ */
16
42
  async serverWithLeastClients() {
17
43
  const data = await this.gql.request(ServerWithLeastClientsDocument, undefined);
18
44
  return data.serverWithLeastClients;
19
45
  }
46
+ /**
47
+ * List every registered GraphQL API server (both `management-api` and
48
+ * `game-api` kinds), regardless of health/state — for service discovery. To
49
+ * route clients, prefer {@link ServerStatusAPI.listActiveGraphqlServers}
50
+ * (healthy only). No authentication required.
51
+ *
52
+ * @returns Every registered {@link GraphQLServer}.
53
+ */
20
54
  async listAll() {
21
55
  const data = await this.gql.request(GraphqlServersDocument, undefined);
22
56
  return data.graphqlServers;
23
57
  }
58
+ /**
59
+ * List only healthy GraphQL API servers (`status = ReadyForClients`) for client
60
+ * routing/discovery. No authentication required.
61
+ *
62
+ * @returns The healthy {@link GraphQLServer}s.
63
+ */
24
64
  async listActiveGraphqlServers() {
25
65
  const data = await this.gql.request(ActiveGraphQlServersDocument, undefined);
26
66
  return data.activeGraphQLServers;
27
67
  }
68
+ /**
69
+ * Get the current server version and the minimum client version the server
70
+ * accepts. No authentication required — compare your build against
71
+ * `minimumClientVersion` before connecting and prompt an update if it is too
72
+ * old.
73
+ *
74
+ * @returns A {@link ServerVersionInfo} (`serverVersion` + `minimumClientVersion`,
75
+ * each a major/minor/patch/build {@link VersionInfo}).
76
+ */
28
77
  async versionInfo() {
29
78
  const data = await this.gql.request(VersionInfoDocument, undefined);
30
79
  return data.versionInfo;
31
80
  }
81
+ /**
82
+ * Single startup payload for browser game clients: the authenticated user,
83
+ * server/min-client version requirements, current UDP proxy status, realtime
84
+ * protocol details (subprotocol + subscription name), and the spatial send
85
+ * limits/constants. Read-only — does **not** open a UDP proxy session. Call this
86
+ * once after login to initialize a play session instead of issuing several
87
+ * separate queries.
88
+ *
89
+ * @param appId - The app (game) the client is initializing for (`BigInt` as a
90
+ * decimal string). Scopes the returned UDP status and mirrors the app's
91
+ * entitlements; reuse the same `appId` when subscribing and on every spatial
92
+ * send.
93
+ * @returns A {@link GameClientBootstrap}: `me`, `versionInfo`,
94
+ * `udpProxyConnectionStatus`, `realtimeProtocol`, `subscriptionName`, and the
95
+ * spatial limits `maxReplicationDistance` (max `distance` fan-out, in chunk
96
+ * units), `maxDecayRate`, and `sequenceNumberModulo` (256).
97
+ * @throws {CrowdyGraphQLError} `UNAUTHENTICATED` without a valid game token, or
98
+ * `FORBIDDEN` if not entitled to the app.
99
+ */
32
100
  async gameClientBootstrap(appId) {
33
101
  const data = await this.gql.request(GameClientBootstrapDocument, { appId });
34
102
  return data.gameClientBootstrap;
@@ -1,16 +1,64 @@
1
1
  import type { GraphQLClient } from '../client.js';
2
2
  import { type UserAppStateQuery, type UserAppStateQueryVariables, type UserAppStatesQuery, type UpdateUserAppStateMutation, type UpdateUserAppStateMutationVariables, type DeleteUserAppStateMutation, type DeleteUserAppStateMutationVariables } from '../generated/graphql.js';
3
3
  /**
4
- * Per-user, per-app state storage (formerly `userMapState`).
5
- *
4
+ * Per-user, per-app state storage on the **game-api** (formerly `userMapState`).
6
5
  * Exposed as `client.state`.
6
+ *
7
+ * Each row is the authenticated user's own opaque state blob scoped to one app
8
+ * (keyed by `appId` + `userId`) — a convenient place to persist small
9
+ * per-player, per-game data. The `state` blob is **base64-encoded** binary
10
+ * (null when cleared) and `appId` is a `BigInt` sent and received as a decimal
11
+ * string.
12
+ *
13
+ * Every method requires an authenticated session (a Bearer game token set via
14
+ * `client.auth.login()` or `client.setToken()`) and only ever reads or writes
15
+ * the **caller's own** state, otherwise {@link CrowdyGraphQLError} is thrown
16
+ * (`UNAUTHENTICATED`).
7
17
  */
8
18
  export declare class StateAPI {
9
19
  private gql;
10
20
  constructor(gql: GraphQLClient);
21
+ /**
22
+ * Read the authenticated user's per-app state for `appId`.
23
+ *
24
+ * @param appId - App (game) id the state is scoped to (`BigInt` as a decimal
25
+ * string).
26
+ * @returns The {@link UserAppState} (its `state` blob base64-encoded), or
27
+ * `null` when no row exists.
28
+ * @throws {CrowdyGraphQLError} `UNAUTHENTICATED`.
29
+ */
11
30
  getOne(appId: UserAppStateQueryVariables['appId']): Promise<UserAppStateQuery['userAppState']>;
31
+ /**
32
+ * List all of the authenticated user's per-app state rows, ordered
33
+ * newest-updated first. Takes no arguments.
34
+ *
35
+ * @returns The caller's {@link UserAppState} rows (each `state` blob
36
+ * base64-encoded).
37
+ * @throws {CrowdyGraphQLError} `UNAUTHENTICATED`.
38
+ */
12
39
  getAll(): Promise<UserAppStatesQuery['userAppStates']>;
40
+ /**
41
+ * Create or replace (upsert) the authenticated user's per-app state for
42
+ * `input.appId`, keyed by `appId` + `userId`. Always writes the caller's own
43
+ * state.
44
+ *
45
+ * @param input - {@link CreateUserAppStateInput}: the target `appId` (decimal
46
+ * string) and the new `state` blob (base64-encoded binary; omit/null to clear
47
+ * it).
48
+ * @returns The upserted {@link UserAppState}.
49
+ * @throws {CrowdyGraphQLError} `BAD_USER_INPUT` or `UNAUTHENTICATED`.
50
+ */
13
51
  update(input: UpdateUserAppStateMutationVariables['input']): Promise<UpdateUserAppStateMutation['updateUserAppState']>;
52
+ /**
53
+ * **Destructive:** delete the authenticated user's per-app state row for
54
+ * `appId` and return the deleted row. Acts only on the caller's own state.
55
+ *
56
+ * @param appId - App (game) id whose state row to delete (`BigInt` as a decimal
57
+ * string).
58
+ * @returns The deleted {@link UserAppState}.
59
+ * @throws {CrowdyGraphQLError} when no state row exists for `appId`
60
+ * (not-found), or `UNAUTHENTICATED`.
61
+ */
14
62
  delete(appId: DeleteUserAppStateMutationVariables['appId']): Promise<DeleteUserAppStateMutation['deleteUserAppState']>;
15
63
  }
16
64
  //# sourceMappingURL=state.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/domains/state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,OAAO,EAEL,KAAK,iBAAiB,EACtB,KAAK,0BAA0B,EAE/B,KAAK,kBAAkB,EAEvB,KAAK,0BAA0B,EAC/B,KAAK,mCAAmC,EAExC,KAAK,0BAA0B,EAC/B,KAAK,mCAAmC,EACzC,MAAM,yBAAyB,CAAC;AAEjC;;;;GAIG;AACH,qBAAa,QAAQ;IACP,OAAO,CAAC,GAAG;gBAAH,GAAG,EAAE,aAAa;IAEhC,MAAM,CACV,KAAK,EAAE,0BAA0B,CAAC,OAAO,CAAC,GACzC,OAAO,CAAC,iBAAiB,CAAC,cAAc,CAAC,CAAC;IAKvC,MAAM,IAAI,OAAO,CAAC,kBAAkB,CAAC,eAAe,CAAC,CAAC;IAKtD,MAAM,CACV,KAAK,EAAE,mCAAmC,CAAC,OAAO,CAAC,GAClD,OAAO,CAAC,0BAA0B,CAAC,oBAAoB,CAAC,CAAC;IAKtD,MAAM,CACV,KAAK,EAAE,mCAAmC,CAAC,OAAO,CAAC,GAClD,OAAO,CAAC,0BAA0B,CAAC,oBAAoB,CAAC,CAAC;CAI7D"}
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/domains/state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,OAAO,EAEL,KAAK,iBAAiB,EACtB,KAAK,0BAA0B,EAE/B,KAAK,kBAAkB,EAEvB,KAAK,0BAA0B,EAC/B,KAAK,mCAAmC,EAExC,KAAK,0BAA0B,EAC/B,KAAK,mCAAmC,EACzC,MAAM,yBAAyB,CAAC;AAEjC;;;;;;;;;;;;;;GAcG;AACH,qBAAa,QAAQ;IACP,OAAO,CAAC,GAAG;gBAAH,GAAG,EAAE,aAAa;IAEtC;;;;;;;;OAQG;IACG,MAAM,CACV,KAAK,EAAE,0BAA0B,CAAC,OAAO,CAAC,GACzC,OAAO,CAAC,iBAAiB,CAAC,cAAc,CAAC,CAAC;IAK7C;;;;;;;OAOG;IACG,MAAM,IAAI,OAAO,CAAC,kBAAkB,CAAC,eAAe,CAAC,CAAC;IAK5D;;;;;;;;;;OAUG;IACG,MAAM,CACV,KAAK,EAAE,mCAAmC,CAAC,OAAO,CAAC,GAClD,OAAO,CAAC,0BAA0B,CAAC,oBAAoB,CAAC,CAAC;IAK5D;;;;;;;;;OASG;IACG,MAAM,CACV,KAAK,EAAE,mCAAmC,CAAC,OAAO,CAAC,GAClD,OAAO,CAAC,0BAA0B,CAAC,oBAAoB,CAAC,CAAC;CAI7D"}
@@ -1,25 +1,73 @@
1
1
  import { UserAppStateDocument, UserAppStatesDocument, UpdateUserAppStateDocument, DeleteUserAppStateDocument, } from '../generated/graphql.js';
2
2
  /**
3
- * Per-user, per-app state storage (formerly `userMapState`).
4
- *
3
+ * Per-user, per-app state storage on the **game-api** (formerly `userMapState`).
5
4
  * Exposed as `client.state`.
5
+ *
6
+ * Each row is the authenticated user's own opaque state blob scoped to one app
7
+ * (keyed by `appId` + `userId`) — a convenient place to persist small
8
+ * per-player, per-game data. The `state` blob is **base64-encoded** binary
9
+ * (null when cleared) and `appId` is a `BigInt` sent and received as a decimal
10
+ * string.
11
+ *
12
+ * Every method requires an authenticated session (a Bearer game token set via
13
+ * `client.auth.login()` or `client.setToken()`) and only ever reads or writes
14
+ * the **caller's own** state, otherwise {@link CrowdyGraphQLError} is thrown
15
+ * (`UNAUTHENTICATED`).
6
16
  */
7
17
  export class StateAPI {
8
18
  constructor(gql) {
9
19
  this.gql = gql;
10
20
  }
21
+ /**
22
+ * Read the authenticated user's per-app state for `appId`.
23
+ *
24
+ * @param appId - App (game) id the state is scoped to (`BigInt` as a decimal
25
+ * string).
26
+ * @returns The {@link UserAppState} (its `state` blob base64-encoded), or
27
+ * `null` when no row exists.
28
+ * @throws {CrowdyGraphQLError} `UNAUTHENTICATED`.
29
+ */
11
30
  async getOne(appId) {
12
31
  const data = await this.gql.request(UserAppStateDocument, { appId });
13
32
  return data.userAppState;
14
33
  }
34
+ /**
35
+ * List all of the authenticated user's per-app state rows, ordered
36
+ * newest-updated first. Takes no arguments.
37
+ *
38
+ * @returns The caller's {@link UserAppState} rows (each `state` blob
39
+ * base64-encoded).
40
+ * @throws {CrowdyGraphQLError} `UNAUTHENTICATED`.
41
+ */
15
42
  async getAll() {
16
43
  const data = await this.gql.request(UserAppStatesDocument, undefined);
17
44
  return data.userAppStates;
18
45
  }
46
+ /**
47
+ * Create or replace (upsert) the authenticated user's per-app state for
48
+ * `input.appId`, keyed by `appId` + `userId`. Always writes the caller's own
49
+ * state.
50
+ *
51
+ * @param input - {@link CreateUserAppStateInput}: the target `appId` (decimal
52
+ * string) and the new `state` blob (base64-encoded binary; omit/null to clear
53
+ * it).
54
+ * @returns The upserted {@link UserAppState}.
55
+ * @throws {CrowdyGraphQLError} `BAD_USER_INPUT` or `UNAUTHENTICATED`.
56
+ */
19
57
  async update(input) {
20
58
  const data = await this.gql.request(UpdateUserAppStateDocument, { input });
21
59
  return data.updateUserAppState;
22
60
  }
61
+ /**
62
+ * **Destructive:** delete the authenticated user's per-app state row for
63
+ * `appId` and return the deleted row. Acts only on the caller's own state.
64
+ *
65
+ * @param appId - App (game) id whose state row to delete (`BigInt` as a decimal
66
+ * string).
67
+ * @returns The deleted {@link UserAppState}.
68
+ * @throws {CrowdyGraphQLError} when no state row exists for `appId`
69
+ * (not-found), or `UNAUTHENTICATED`.
70
+ */
23
71
  async delete(appId) {
24
72
  const data = await this.gql.request(DeleteUserAppStateDocument, { appId });
25
73
  return data.deleteUserAppState;