@crowdedkingdoms/crowdyjs 18.20.0 → 18.21.0-test.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.
package/README.md CHANGED
@@ -12,19 +12,23 @@ gameplay, minted per app through `client.portal`.
12
12
 
13
13
  Start here:
14
14
 
15
- - [SDK guide](https://docs.crowdedkingdoms.com/crowdyjs/readme) — the canonical
15
+ - [SDK guide](https://docs.dev.crowdedkingdoms.com/crowdyjs/readme) — the canonical
16
16
  walkthrough of everything in this README.
17
- - [Build a game](https://docs.crowdedkingdoms.com/build-a-game/intro) — a
17
+ - [Build a game](https://docs.dev.crowdedkingdoms.com/build-a-game/intro) — a
18
18
  hands-on tutorial from sign-in to a playable voxel game.
19
- - [Platform overview](https://docs.crowdedkingdoms.com/overview/client-workflow)
19
+ - [Platform overview](https://docs.dev.crowdedkingdoms.com/overview/client-workflow)
20
20
  — how a client session flows through the platform.
21
21
 
22
22
  ## Install
23
23
 
24
24
  ```bash
25
- npm install @crowdedkingdoms/crowdyjs
25
+ npm install @crowdedkingdoms/crowdyjs@dev
26
26
  ```
27
27
 
28
+ This README is the `dev` branch's: it documents the release on the `dev` dist-tag
29
+ (`npm view @crowdedkingdoms/crowdyjs dist-tags`), and its links go to the dev docs site. A
30
+ plain `npm install` resolves `latest`, the production release, which has no `client.exec`.
31
+
28
32
  **Server compatibility.** A release selects fields the Game API it was built against has,
29
33
  so it needs that Game API or newer; promote the Game API before the SDK on each tier.
30
34
 
@@ -196,8 +200,8 @@ Notes:
196
200
  - Use `client.auth.setToken(token)` to seed a token externally (e.g. when
197
201
  restoring auth from a non-default storage).
198
202
 
199
- Deeper reading: [Portals & app-scoped tokens](https://docs.crowdedkingdoms.com/management-api/portals-and-app-tokens)
200
- and [Sign in](https://docs.crowdedkingdoms.com/management-api/authentication).
203
+ Deeper reading: [Portals & app-scoped tokens](https://docs.dev.crowdedkingdoms.com/management-api/portals-and-app-tokens)
204
+ and [Sign in](https://docs.dev.crowdedkingdoms.com/management-api/authentication).
201
205
 
202
206
  ### Org-managed players
203
207
 
@@ -394,7 +398,7 @@ query AppForRouting($appId: BigInt!) {
394
398
  `CrowdyClient` with `httpUrl: gameApiUrl` (and the matching `wsUrl`) holding
395
399
  that app's app-scoped token, then drive gameplay through that client. Apps
396
400
  with no `gameApiUrl` keep working against the default `httpUrl` you
397
- configured. See [Loading an app's Game API](https://docs.crowdedkingdoms.com/crowdyjs/shared-environment-routing).
401
+ configured. See [Loading an app's Game API](https://docs.dev.crowdedkingdoms.com/crowdyjs/shared-environment-routing).
398
402
 
399
403
  ## Realtime notifications
400
404
 
@@ -557,7 +561,10 @@ first awaited send of each session (the first connect, a reconnect, or a move to
557
561
  another instance) is retried once with a fresh `sequenceNumber` if it is refused
558
562
  `UNAUTHORIZED` or, for the actor and voxel updates the server echoes, if it times
559
563
  out (`UDP_SEQUENCE_TIMEOUT`), which is how a realtime server older than v0.42.0
560
- answers a session's first message. A send whose `sequenceNumber` you chose is
564
+ answers a session's first message. An actor or voxel update still waiting when
565
+ the client reconnects or moves to another instance is resent as soon as the new
566
+ session is up, rather than at its timeout, since its echo went to the session it
567
+ left; that is its one retry. A send whose `sequenceNumber` you chose is
561
568
  not retried, and an audio, text or event send's timeout (its normal success) is
562
569
  never retried. `sendChannelMessage` broadcasts an opaque payload on a
563
570
  channel. `sendRangedChannelMessage` publishes on a channel too, but only members
@@ -827,7 +834,7 @@ reach your bundle. Reads are synchronous snapshots and writes happen on
827
834
  WebSocket events (not `requestAnimationFrame`), so render loops read freely
828
835
  and a backgrounded tab keeps ingesting updates; pass `workerTicker()` to also
829
836
  keep timer-driven sends at full rate while hidden. See the
830
- [World Stores guide](https://docs.crowdedkingdoms.com/crowdyjs/stores).
837
+ [World Stores guide](https://docs.dev.crowdedkingdoms.com/crowdyjs/stores).
831
838
 
832
839
  ## Game Kit
833
840
 
@@ -905,7 +912,7 @@ The protocol is held to ck-exec's golden record of the starters
905
912
  (`test/unit/fixtures/kit-protocol.json`): every module call and topic in it is replayed in
906
913
  `test/unit/game-kit.test.mjs`. The blueprints, `kit.deploy`, the engines and the model-backed
907
914
  helpers went with the game model in 18.0.0; the hub modules replace them. See the
908
- [Game Kit docs](https://docs.crowdedkingdoms.com/game-kit/intro) and
915
+ [Game Kit docs](https://docs.dev.crowdedkingdoms.com/game-kit/intro) and
909
916
  [MIGRATION.md](MIGRATION.md).
910
917
 
911
918
  ## ck-exec
@@ -969,7 +976,7 @@ Integers above 2^53 decode as `number` and lose precision unless you pass
969
976
  `{ decode: { useBigInt64: true } }`. A call's whole numbers outside 32 bits (a timestamp in
970
977
  milliseconds, a player id) go out as 64-bit integers (18.11.0; before, as floats, which a
971
978
  hub's integer fields refuse). The wire format is in the
972
- [ck-exec docs](https://docs.crowdedkingdoms.com/exec/intro).
979
+ [ck-exec docs](https://docs.dev.crowdedkingdoms.com/exec/intro).
973
980
 
974
981
  ### A mod's CLIENT half
975
982
 
@@ -1040,7 +1047,7 @@ counts what was dropped); `invoke` sends at most 256 KiB each way and is refused
1040
1047
  module is not running. `NOT_FOUND` holds a CLIENT half back 15 s and `RATE_LIMITED` 60 s. The
1041
1048
  grid's owner is asked about their own CLIENT halves like anyone; answer yes in `confirm` when
1042
1049
  `prompt.authorId` is the player. See
1043
- [CLIENT halves](https://docs.crowdedkingdoms.com/exec/client-halves).
1050
+ [CLIENT halves](https://docs.dev.crowdedkingdoms.com/exec/client-halves).
1044
1051
 
1045
1052
  ## Hosting a game on Crowdy Games
1046
1053
 
@@ -1159,8 +1166,8 @@ CLIENT project needs ck-api `v2.25.1` or later. A CLIENT crate still on the lega
1159
1166
  `mountCrowdyStudio` and the controller take `mods: client.exec`. Crowdy Studio runs nothing
1160
1167
  on legacy player compute since 18.0.0.
1161
1168
 
1162
- See [CLIENT halves](https://docs.crowdedkingdoms.com/exec/client-halves), [mods](https://docs.crowdedkingdoms.com/exec/mods)
1163
- and [Embed Crowdy Studio in your game](https://docs.crowdedkingdoms.com/crowdyjs/crowdy-studio-embed).
1169
+ See [CLIENT halves](https://docs.dev.crowdedkingdoms.com/exec/client-halves), [mods](https://docs.dev.crowdedkingdoms.com/exec/mods)
1170
+ and [Embed Crowdy Studio in your game](https://docs.dev.crowdedkingdoms.com/crowdyjs/crowdy-studio-embed).
1164
1171
 
1165
1172
  ### The Studio agent (DeepSeek Harness in the browser)
1166
1173
 
@@ -1351,7 +1358,7 @@ no other repositories and no network access required:
1351
1358
  `src/generated/graphql-schema.ts`, the generated schema types.
1352
1359
 
1353
1360
  Schema refresh is explicit, from the published
1354
- [SDL](https://docs.crowdedkingdoms.com/schema/game-api.graphql):
1361
+ [SDL](https://docs.dev.crowdedkingdoms.com/schema/game-api.graphql):
1355
1362
 
1356
1363
  ```bash
1357
1364
  npm run schema:sync:prod
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * GENERATED — do not edit. The operator tooling's
3
- * `sync-client-origins.mjs --write --tier prod` writes this file, and
3
+ * `sync-client-origins.mjs --write --tier test` writes this file, and
4
4
  * `check-sdk-default-origin.mjs` refuses it when it names the wrong tier or a
5
5
  * host that declaration does not carry. Regenerate; never hand-edit.
6
6
  *
@@ -10,14 +10,14 @@
10
10
  * than no default at all. Every fallback this SDK ever removed named a host that
11
11
  * was already dead. A generated file plus a gate is what makes this one different.
12
12
  *
13
- * Source: the operator's per-tier public CK API origin declaration, tier 'prod'
13
+ * Source: the operator's per-tier public CK API origin declaration, tier 'test'
14
14
  */
15
15
  /** The tier this build of the SDK is published for. */
16
- export declare const CROWDY_DEFAULT_TIER = "prod";
16
+ export declare const CROWDY_DEFAULT_TIER = "test";
17
17
  /** The public CK API origin for that tier. */
18
- export declare const CROWDY_DEFAULT_HTTP_ORIGIN = "https://ck.prod.crowdedkingdoms.com";
18
+ export declare const CROWDY_DEFAULT_HTTP_ORIGIN = "https://ck.test.crowdedkingdoms.com";
19
19
  /** The same host over WebSocket. A scheme is composed; a hostname is looked up. */
20
- export declare const CROWDY_DEFAULT_WS_ORIGIN = "wss://ck.prod.crowdedkingdoms.com";
20
+ export declare const CROWDY_DEFAULT_WS_ORIGIN = "wss://ck.test.crowdedkingdoms.com";
21
21
  /** The bare hostname, for callers that need to compare rather than dial. */
22
- export declare const CROWDY_DEFAULT_HOST = "ck.prod.crowdedkingdoms.com";
22
+ export declare const CROWDY_DEFAULT_HOST = "ck.test.crowdedkingdoms.com";
23
23
  //# sourceMappingURL=default-origin.d.ts.map
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * GENERATED — do not edit. The operator tooling's
3
- * `sync-client-origins.mjs --write --tier prod` writes this file, and
3
+ * `sync-client-origins.mjs --write --tier test` writes this file, and
4
4
  * `check-sdk-default-origin.mjs` refuses it when it names the wrong tier or a
5
5
  * host that declaration does not carry. Regenerate; never hand-edit.
6
6
  *
@@ -10,13 +10,13 @@
10
10
  * than no default at all. Every fallback this SDK ever removed named a host that
11
11
  * was already dead. A generated file plus a gate is what makes this one different.
12
12
  *
13
- * Source: the operator's per-tier public CK API origin declaration, tier 'prod'
13
+ * Source: the operator's per-tier public CK API origin declaration, tier 'test'
14
14
  */
15
15
  /** The tier this build of the SDK is published for. */
16
- export const CROWDY_DEFAULT_TIER = 'prod';
16
+ export const CROWDY_DEFAULT_TIER = 'test';
17
17
  /** The public CK API origin for that tier. */
18
- export const CROWDY_DEFAULT_HTTP_ORIGIN = 'https://ck.prod.crowdedkingdoms.com';
18
+ export const CROWDY_DEFAULT_HTTP_ORIGIN = 'https://ck.test.crowdedkingdoms.com';
19
19
  /** The same host over WebSocket. A scheme is composed; a hostname is looked up. */
20
- export const CROWDY_DEFAULT_WS_ORIGIN = 'wss://ck.prod.crowdedkingdoms.com';
20
+ export const CROWDY_DEFAULT_WS_ORIGIN = 'wss://ck.test.crowdedkingdoms.com';
21
21
  /** The bare hostname, for callers that need to compare rather than dial. */
22
- export const CROWDY_DEFAULT_HOST = 'ck.prod.crowdedkingdoms.com';
22
+ export const CROWDY_DEFAULT_HOST = 'ck.test.crowdedkingdoms.com';
@@ -38,8 +38,10 @@ import { type VideoCodec } from '../media/video-frames.js';
38
38
  * loaded (realtime server v0.42.0 and later); an older server dropped or
39
39
  * refused them. Against one, the SDK retries the first awaited send of each
40
40
  * session once (see {@link sendActorUpdateAndWait}), but a plain `send*` may
41
- * still be lost. To receive any `...AndWait` echo or notification you must have
42
- * an active {@link subscribe}.
41
+ * still be lost. An awaited actor or voxel update still waiting when the client
42
+ * reconnects or moves to another instance is resent as soon as the new session
43
+ * is up. To receive any `...AndWait` echo or notification you must have an
44
+ * active {@link subscribe}.
43
45
  */
44
46
  export declare class UdpAPI {
45
47
  private gql;
@@ -176,6 +178,10 @@ export declare class UdpAPI {
176
178
  * the resolved notification then carries the retry's sequence number. A
177
179
  * send whose `sequenceNumber` you chose is not retried, and neither is the
178
180
  * timeout of an audio, text or event send, which is how those succeed.
181
+ * - An actor or voxel update still waiting when the client reconnects or moves
182
+ * to another instance is resent, with a fresh sequence number, as soon as
183
+ * the new session is up, rather than at its timeout: its echo went to the
184
+ * session the client left. That is the send's one retry.
179
185
  *
180
186
  * @param options - `timeoutMs`: how long to wait for the echo once the send
181
187
  * is accepted, in milliseconds; defaults to the client's realtime
@@ -622,9 +628,14 @@ export declare class UdpAPI {
622
628
  * its echo times out: a game server from before the one that holds a
623
629
  * session's first messages refuses or drops them while the session's
624
630
  * permissions load. A send the server does not echo (audio, text, a client
625
- * event) succeeds by timing out, so its timeout is never retried. Only when
626
- * the SDK chose the sequence number, because the retry needs one of its own
627
- * and a caller who chose theirs is correlating by it.
631
+ * event) succeeds by timing out, so its timeout is never retried.
632
+ *
633
+ * A send the server echoes that is still waiting when a new session is
634
+ * established is resent then, once, rather than at its timeout: its echo went
635
+ * to the session the client left. That retry is the send's one retry.
636
+ *
637
+ * Only when the SDK chose the sequence number, because a retry needs one of
638
+ * its own and a caller who chose theirs is correlating by it.
628
639
  */
629
640
  private sendAndWait;
630
641
  private sendOnceAndWait;
@@ -1 +1 @@
1
- {"version":3,"file":"udp.d.ts","sourceRoot":"","sources":["../../src/domains/udp.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,KAAK,EACV,mBAAmB,EACnB,uBAAuB,EACxB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAEL,KAAK,uBAAuB,EAG5B,KAAK,6BAA6B,EAElC,KAAK,gCAAgC,EAErC,KAAK,gCAAgC,EAErC,KAAK,gCAAgC,EAErC,KAAK,gCAAgC,EAErC,KAAK,+BAA+B,EAEpC,KAAK,gCAAgC,EAErC,KAAK,uCAAuC,EAE5C,KAAK,mCAAmC,EAExC,KAAK,iCAAiC,EAEtC,KAAK,yCAAyC,EAC/C,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAErD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAkB1D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAiB,KAAK,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAG1E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,qBAAa,MAAM;IAOf,OAAO,CAAC,GAAG;IACX,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,OAAO,CAAC;IAChB;;;;OAIG;IACH,OAAO,CAAC,2BAA2B,CAAC;IAdtC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA2B;IACrD,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAA+B;IACpE,oEAAoE;IACpE,OAAO,CAAC,cAAc,CAAM;gBAGlB,GAAG,EAAE,aAAa,EAClB,IAAI,EAAE,mBAAmB,EACzB,OAAO,CAAC,EAAE,eAAe,YAAA;IACjC;;;;OAIG;IACK,2BAA2B,CAAC,GAAE,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,aAAA;IAGjF;;;;OAIG;IACG,2BAA2B,IAAI,OAAO,CAAC,IAAI,CAAC;YAKpC,uBAAuB;IAWrC,OAAO,CAAC,gBAAgB;IAOxB,mEAAmE;IACnE,OAAO,CAAC,MAAM;IAId;;;;OAIG;YACW,YAAY;IAoB1B;;;;;;;;;;;;;OAaG;IACG,OAAO,IAAI,OAAO,CAAC,uBAAuB,CAAC,iBAAiB,CAAC,CAAC;IAkBpE;;;;;;;;OAQG;IACH;;;;;OAKG;IACH,UAAU,IAAI,IAAI;IAIZ,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC;IASpC;;;;;;;OAOG;IACG,gBAAgB,IAAI,OAAO,CAC/B,6BAA6B,CAAC,0BAA0B,CAAC,CAC1D;IAQD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA8BG;IACG,eAAe,CACnB,KAAK,EAAE,gCAAgC,CAAC,OAAO,CAAC,GAC/C,OAAO,CAAC,OAAO,CAAC;YAKL,mBAAmB;IAyCjC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAiDG;IACG,sBAAsB,CAC1B,KAAK,EAAE,gCAAgC,CAAC,OAAO,CAAC,EAChD,OAAO,GAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAO,GACnC,OAAO,CAAC,mBAAmB,CAAC;IAM/B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA8BG;IACG,eAAe,CACnB,KAAK,EAAE,IAAI,CAAC,gCAAgC,CAAC,OAAO,CAAC,EAAE,YAAY,CAAC,GAAG;QACrE,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,GACA,OAAO,CAAC,OAAO,CAAC;IAiBnB;;;;;;;;;;;;;;;;;;OAkBG;IACG,sBAAsB,CAC1B,KAAK,EAAE,IAAI,CAAC,gCAAgC,CAAC,OAAO,CAAC,EAAE,YAAY,CAAC,GAAG;QACrE,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,EACD,OAAO,GAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAO,GACnC,OAAO,CAAC,mBAAmB,CAAC;IAM/B;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;IACG,eAAe,CACnB,KAAK,EAAE,gCAAgC,CAAC,OAAO,CAAC,GAC/C,OAAO,CAAC,OAAO,CAAC;IAcnB;;;;;;;;;;;;;;;;;OAiBG;IACG,sBAAsB,CAC1B,KAAK,EAAE,gCAAgC,CAAC,OAAO,CAAC,EAChD,OAAO,GAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAO,GACnC,OAAO,CAAC,mBAAmB,CAAC;IAM/B;;;;;;;;;;;;;;;;OAgBG;IACG,eAAe,CACnB,KAAK,EAAE,gCAAgC,CAAC,OAAO,CAAC,GAC/C,OAAO,CAAC,OAAO,CAAC;IAcnB;;;;;;;;;;;;OAYG;IACG,cAAc,CAAC,KAAK,EAAE;QAC1B,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE;YAAE,CAAC,EAAE,MAAM,CAAC;YAAC,CAAC,EAAE,MAAM,CAAC;YAAC,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QAC3C,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,UAAU,CAAC;QAClB,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,UAAU,CAAC;QACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,GAAG,OAAO,CAAC,MAAM,CAAC;IAgBnB;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACG,cAAc,CAClB,KAAK,EAAE,+BAA+B,CAAC,OAAO,CAAC,GAC9C,OAAO,CAAC,OAAO,CAAC;IAcnB;;;;;;;;;;;;;;;;;OAiBG;IACG,qBAAqB,CACzB,KAAK,EAAE,+BAA+B,CAAC,OAAO,CAAC,EAC/C,OAAO,GAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAO,GACnC,OAAO,CAAC,mBAAmB,CAAC;IAM/B;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACG,eAAe,CACnB,KAAK,EAAE,gCAAgC,CAAC,OAAO,CAAC,GAC/C,OAAO,CAAC,OAAO,CAAC;IAcnB;;;;;;;;;;;;;;;;;;OAkBG;IACG,sBAAsB,CAC1B,KAAK,EAAE,gCAAgC,CAAC,OAAO,CAAC,EAChD,OAAO,GAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAO,GACnC,OAAO,CAAC,mBAAmB,CAAC;IAM/B;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACG,sBAAsB,CAC1B,KAAK,EAAE,uCAAuC,CAAC,OAAO,CAAC,GACtD,OAAO,CAAC,OAAO,CAAC;IAgBnB;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACG,kBAAkB,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,OAAO,CAAC;IActE;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACG,kBAAkB,CACtB,KAAK,EAAE,mCAAmC,CAAC,OAAO,CAAC,GAClD,OAAO,CAAC,OAAO,CAAC;IAcnB;;;;;;;;;;;;;;;OAeG;IACG,gBAAgB,CACpB,KAAK,EAAE,iCAAiC,CAAC,OAAO,CAAC,GAChD,OAAO,CAAC,OAAO,CAAC;IAcnB;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACG,wBAAwB,CAC5B,KAAK,EAAE,yCAAyC,CAAC,OAAO,CAAC,GACxD,OAAO,CAAC,OAAO,CAAC;IAcnB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAqCG;IACH,SAAS,CAAC,QAAQ,EAAE,uBAAuB,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,IAAI;IAIvE;;;;;;;;;;;;;;;;;OAiBG;YACW,WAAW;YAgCX,eAAe;IAmB7B,OAAO,CAAC,YAAY;CAQrB"}
1
+ {"version":3,"file":"udp.d.ts","sourceRoot":"","sources":["../../src/domains/udp.ts"],"names":[],"mappings":"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"}
@@ -38,8 +38,10 @@ import { encodeBase64 } from '../utils.js';
38
38
  * loaded (realtime server v0.42.0 and later); an older server dropped or
39
39
  * refused them. Against one, the SDK retries the first awaited send of each
40
40
  * session once (see {@link sendActorUpdateAndWait}), but a plain `send*` may
41
- * still be lost. To receive any `...AndWait` echo or notification you must have
42
- * an active {@link subscribe}.
41
+ * still be lost. An awaited actor or voxel update still waiting when the client
42
+ * reconnects or moves to another instance is resent as soon as the new session
43
+ * is up. To receive any `...AndWait` echo or notification you must have an
44
+ * active {@link subscribe}.
43
45
  */
44
46
  export class UdpAPI {
45
47
  constructor(gql, subs, metrics,
@@ -278,6 +280,10 @@ export class UdpAPI {
278
280
  * the resolved notification then carries the retry's sequence number. A
279
281
  * send whose `sequenceNumber` you chose is not retried, and neither is the
280
282
  * timeout of an audio, text or event send, which is how those succeed.
283
+ * - An actor or voxel update still waiting when the client reconnects or moves
284
+ * to another instance is resent, with a fresh sequence number, as soon as
285
+ * the new session is up, rather than at its timeout: its echo went to the
286
+ * session the client left. That is the send's one retry.
281
287
  *
282
288
  * @param options - `timeoutMs`: how long to wait for the echo once the send
283
289
  * is accepted, in milliseconds; defaults to the client's realtime
@@ -828,31 +834,45 @@ export class UdpAPI {
828
834
  * its echo times out: a game server from before the one that holds a
829
835
  * session's first messages refuses or drops them while the session's
830
836
  * permissions load. A send the server does not echo (audio, text, a client
831
- * event) succeeds by timing out, so its timeout is never retried. Only when
832
- * the SDK chose the sequence number, because the retry needs one of its own
833
- * and a caller who chose theirs is correlating by it.
837
+ * event) succeeds by timing out, so its timeout is never retried.
838
+ *
839
+ * A send the server echoes that is still waiting when a new session is
840
+ * established is resent then, once, rather than at its timeout: its echo went
841
+ * to the session the client left. That retry is the send's one retry.
842
+ *
843
+ * Only when the SDK chose the sequence number, because a retry needs one of
844
+ * its own and a caller who chose theirs is correlating by it.
834
845
  */
835
846
  async sendAndWait(input, timeoutMs, echoed, send) {
836
847
  const epoch = this.subs.sessionEpoch();
837
- const retryable = epoch !== this.confirmedEpoch && input.sequenceNumber == null;
848
+ const ownSequence = input.sequenceNumber == null;
849
+ const retryable = epoch !== this.confirmedEpoch && ownSequence;
850
+ // The session the answered attempt went to.
851
+ let sentEpoch = epoch;
852
+ const again = () => {
853
+ sentEpoch = this.subs.sessionEpoch();
854
+ return this.sendOnceAndWait(this.withSequence({ ...input, sequenceNumber: undefined }), timeoutMs, send, false);
855
+ };
838
856
  try {
839
- const echo = await this.sendOnceAndWait(this.withSequence(input), timeoutMs, send).catch((error) => {
857
+ const echo = await this.sendOnceAndWait(this.withSequence(input), timeoutMs, send, echoed && ownSequence).catch((error) => {
858
+ if (error instanceof SessionChanged)
859
+ return again();
840
860
  if (!retryable || !isFirstSendFailure(error, echoed))
841
861
  throw error;
842
- return this.sendOnceAndWait(this.withSequence({ ...input, sequenceNumber: undefined }), timeoutMs, send);
862
+ return again();
843
863
  });
844
- this.confirmedEpoch = epoch;
864
+ this.confirmedEpoch = sentEpoch;
845
865
  return echo;
846
866
  }
847
867
  catch (error) {
848
868
  // A send the server does not echo succeeds by timing out, and that
849
869
  // answers for the session as well as an echo would.
850
870
  if (!echoed && isTimeout(error))
851
- this.confirmedEpoch = epoch;
871
+ this.confirmedEpoch = sentEpoch;
852
872
  throw error;
853
873
  }
854
874
  }
855
- async sendOnceAndWait(request, timeoutMs, send) {
875
+ async sendOnceAndWait(request, timeoutMs, send, endOnNewSession) {
856
876
  const wait = this.subs.expectSequence(request.sequenceNumber, timeoutMs);
857
877
  try {
858
878
  await send(request);
@@ -865,7 +885,24 @@ export class UdpAPI {
865
885
  // send for up to bundleWindowMs, so put it on the wire before waiting.
866
886
  this.subs.flushSends();
867
887
  wait.start();
868
- return wait.promise;
888
+ if (!endOnNewSession)
889
+ return wait.promise;
890
+ // A session established while this waits (a reconnect, or the new instance
891
+ // after a move) will not carry the echo, which went to the session the
892
+ // client left: end the wait then rather than at its timeout. onStatus
893
+ // reports the current status at once; only a later `connected` counts.
894
+ const epoch = this.subs.sessionEpoch();
895
+ let stop = () => undefined;
896
+ const changed = new Promise((_, reject) => {
897
+ stop = this.subs.onStatus((status) => {
898
+ if (status !== 'connected' || this.subs.sessionEpoch() === epoch)
899
+ return;
900
+ wait.cancel();
901
+ reject(new SessionChanged());
902
+ });
903
+ });
904
+ changed.catch(() => undefined);
905
+ return Promise.race([wait.promise, changed]).finally(() => stop());
869
906
  }
870
907
  withSequence(input) {
871
908
  return {
@@ -874,6 +911,9 @@ export class UdpAPI {
874
911
  };
875
912
  }
876
913
  }
914
+ /** A new realtime session was established while an echoed send waited. */
915
+ class SessionChanged extends Error {
916
+ }
877
917
  /** How a session's first message failed on a game server that did not hold it. */
878
918
  function isFirstSendFailure(error, echoed) {
879
919
  return (error instanceof CrowdyRealtimeError &&
@@ -4609,7 +4609,7 @@ export type ManagedPlayer = {
4609
4609
  export type ManagedPlayerSpecInput = {
4610
4610
  /** The id your organization knows the player by. */
4611
4611
  externalId: Scalars['String']['input'];
4612
- /** Display name (at most 64 characters). */
4612
+ /** Display name (at most 64 characters, none of them control, line-break or bidirectional-formatting characters). */
4613
4613
  gamertag?: InputMaybe<Scalars['String']['input']>;
4614
4614
  };
4615
4615
  /** One page of an org’s managed players, by user id. */
@@ -4638,7 +4638,7 @@ export type MintManagedPlayerTokenInput = {
4638
4638
  appId: Scalars['BigInt']['input'];
4639
4639
  /** The id your organization knows the player by (1-256 characters, no control characters). Use your own stable account id, not an email address. The first sign-in creates the player. */
4640
4640
  externalId: Scalars['String']['input'];
4641
- /** Display name (at most 64 characters). Set when the player is created; later sign-ins leave it (rename with updateManagedPlayer). */
4641
+ /** Display name (at most 64 characters, none of them control, line-break or bidirectional-formatting characters). Set when the player is created; later sign-ins leave it (rename with updateManagedPlayer). */
4642
4642
  gamertag?: InputMaybe<Scalars['String']['input']>;
4643
4643
  /** How long this sign-in lasts, in seconds (default and maximum: the org's settings). The app token refreshes (refreshAppToken) until then; after it, sign the player in again. */
4644
4644
  sessionTtlSeconds?: InputMaybe<Scalars['Int']['input']>;
@@ -8003,7 +8003,7 @@ export type RegisterUserInput = {
8003
8003
  attestAgeOfMajority?: InputMaybe<Scalars['Boolean']['input']>;
8004
8004
  /** Email for the new account; the confirmation email is sent here. */
8005
8005
  email: Scalars['String']['input'];
8006
- /** Optional initial public gamertag (min 3 characters). Can be set later via updateGamertag. */
8006
+ /** Optional initial public gamertag (3 to 64 characters, none of them control, line-break or bidirectional-formatting characters). Can be set later via updateGamertag. */
8007
8007
  gamertag?: InputMaybe<Scalars['String']['input']>;
8008
8008
  /** Password for the new account (min 8 characters). */
8009
8009
  password: Scalars['String']['input'];
@@ -9088,9 +9088,9 @@ export type UpdateChunkStateInput = {
9088
9088
  coordinates: ChunkCoordinatesInput;
9089
9089
  };
9090
9090
  export type UpdateGamertagInput = {
9091
- /** Discriminator paired with `gamertag` (max 128 characters) to form a unique handle. */
9091
+ /** Discriminator paired with `gamertag` (max 128 characters, the same characters refused as in `gamertag`) to form a unique handle. */
9092
9092
  disambiguation: Scalars['String']['input'];
9093
- /** New gamertag (max 64 characters). Must be unique in combination with `disambiguation`. */
9093
+ /** New gamertag (max 64 characters, none of them control, line-break or bidirectional-formatting characters). Must be unique in combination with `disambiguation`. */
9094
9094
  gamertag: Scalars['String']['input'];
9095
9095
  };
9096
9096
  /** Update a custom group role. Omitted fields are left unchanged. */
@@ -9107,10 +9107,10 @@ export type UpdateGroupRoleInput = {
9107
9107
  export type UpdateManagedPlayerInput = {
9108
9108
  /** True disables the player (no sign-in; every session ends now, Buddy and ck-exec included). False enables a player the org disabled. */
9109
9109
  disabled?: InputMaybe<Scalars['Boolean']['input']>;
9110
- /** New disambiguation (at most 128 characters). */
9110
+ /** New disambiguation (at most 128 characters, the same characters refused as in the display name). */
9111
9111
  disambiguation?: InputMaybe<Scalars['String']['input']>;
9112
9112
  externalId: Scalars['String']['input'];
9113
- /** New display name. */
9113
+ /** New display name (at most 64 characters, none of them control, line-break or bidirectional-formatting characters). */
9114
9114
  gamertag?: InputMaybe<Scalars['String']['input']>;
9115
9115
  orgId: Scalars['BigInt']['input'];
9116
9116
  };