@irtio/client 0.3.0 → 0.5.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/dist/index.d.ts CHANGED
@@ -776,6 +776,15 @@ interface JoinOptions<S, Role extends string = string> {
776
776
  readonly rpc?: ClientImplementations<ClientRpcs<SchemaRpc<S>>>;
777
777
  /** Endpoint override. Otherwise resolved as described in `resolveUrl`. */
778
778
  readonly url?: string;
779
+ /**
780
+ * The hosted region this project is deployed to, e.g. `'us'`. Used only when no `url` and no
781
+ * `IRT_URL` is set and the page is not on localhost, where the endpoint becomes
782
+ * `wss://<region>.irt.io`; omitted ⇒ `eu`, which is exactly what every client resolved to
783
+ * before regions existed. It must match the region the project is set to in the dashboard,
784
+ * which `irtio deploy` prints as the URL it reports the deployment reachable at. A label that
785
+ * is not a region label throws rather than quietly falling back.
786
+ */
787
+ readonly region?: string;
779
788
  /**
780
789
  * Public project key. Defaults to `schema.project`, or `'dev'` against a localhost endpoint
781
790
  * (which is what `irtio dev` uses when there is no `irtio.json`).
@@ -818,6 +827,8 @@ interface JoinRelayOptions {
818
827
  readonly role?: string;
819
828
  readonly name?: string;
820
829
  readonly url?: string;
830
+ /** The hosted region, as in `JoinOptions.region`. Omitted ⇒ `eu`. */
831
+ readonly region?: string;
821
832
  /** Public project key; defaults to `'dev'`. */
822
833
  readonly key?: string;
823
834
  readonly onStatus?: (status: Status) => void;
@@ -940,15 +951,29 @@ interface RelayRoom {
940
951
  * The builder writes no URL and no env var in the common case: the schema carries the project id,
941
952
  * `location.hostname` decides localhost vs the region, and the room code lives in the URL.
942
953
  */
943
- /** The region every project resolves to (single-region hosting). */
954
+ /** The region a project resolves to when neither a URL nor a `region` says otherwise. */
944
955
  declare const DEFAULT_REGION = "eu";
956
+ /**
957
+ * The shape of a region label. There is no list of regions to check against: a region exists
958
+ * because servers joined the fleet carrying that label and a router terminates TLS for
959
+ * `<label>.irt.io`, so the set is operational. What is checked is that the label is a label,
960
+ * because it goes straight into a hostname. Same rule the control plane applies when a project
961
+ * declares its region; the SDK keeps its own copy rather than depending on a private package.
962
+ */
963
+ declare const REGION_RE: RegExp;
945
964
  /** `irtio dev`'s default port. */
946
965
  declare const DEV_PORT = 7070;
947
966
  /**
948
967
  * Resolution order: explicit `url` > `IRT_URL` / `window.IRT_URL` > `ws://localhost:7070` when the
949
- * page is on localhost (or there is no page at all — Node, bots, tests) > `wss://eu.irt.io`.
968
+ * page is on localhost (or there is no page at all — Node, bots, tests) > `wss://<region>.irt.io`,
969
+ * where `region` defaults to `eu`.
970
+ *
971
+ * `region` only decides the last step. A page on localhost still gets the local dev server, which
972
+ * is what a developer running `irtio dev` wants no matter which region the deployed project lives
973
+ * in, and an explicit `url` or `IRT_URL` still wins outright. The label is validated whichever
974
+ * step wins, because a typo in it is a bug either way.
950
975
  */
951
- declare function resolveUrl(explicit?: string): string;
976
+ declare function resolveUrl(explicit?: string, region?: string): string;
952
977
  /**
953
978
  * A room option may be a bare code (`ABCD`) or a whole share link. Returns the code, or `''`
954
979
  * when the argument names no room (create-by-join).
@@ -1244,4 +1269,4 @@ declare function joinRoom<S extends AnySchema, Role extends string = RoleOf<S> &
1244
1269
  */
1245
1270
  declare function joinRelay(options?: JoinRelayOptions): Promise<RelayRoom>;
1246
1271
 
1247
- export { CALL_TIMEOUT_MS, type ClientBodySpec, type ClientCollection, type ClientPhysicsOptions, type ClientRapierBody, type ClientRapierModule, type ClientRapierWorld, type ClientState, ClientStore, type ClientVector3, type Correction, DEFAULT_REGION, DEFAULT_WRITE_INTERVAL_MS, DEV_PORT, E_CONNECT_FAILED, type FrameHook, type JoinOptions, type JoinRelayOptions, MAX_PREDICTED_BODIES, type MessageTarget, PING_INTERVAL_MS, PREDICTION_EPSILON, type PredictionStats, type PredictionStatus, RESIM_DEPTH, type RelayRoom, type Room, type RoomCallProxy, type RoomError, type RoomEvents, SMOOTHING_HALF_LIFE_MS, SMOOTHING_SNAP_UNITS, type Scheduler, Session, type Status, type Transport, type TransportSocket, type Unsubscribe, defaultScheduler, joinRelay, joinRoom, linkForUrl, resolveUrl, roomIdFrom, webSocketTransport };
1272
+ export { CALL_TIMEOUT_MS, type ClientBodySpec, type ClientCollection, type ClientPhysicsOptions, type ClientRapierBody, type ClientRapierModule, type ClientRapierWorld, type ClientState, ClientStore, type ClientVector3, type Correction, DEFAULT_REGION, DEFAULT_WRITE_INTERVAL_MS, DEV_PORT, E_CONNECT_FAILED, type FrameHook, type JoinOptions, type JoinRelayOptions, MAX_PREDICTED_BODIES, type MessageTarget, PING_INTERVAL_MS, PREDICTION_EPSILON, type PredictionStats, type PredictionStatus, REGION_RE, RESIM_DEPTH, type RelayRoom, type Room, type RoomCallProxy, type RoomError, type RoomEvents, SMOOTHING_HALF_LIFE_MS, SMOOTHING_SNAP_UNITS, type Scheduler, Session, type Status, type Transport, type TransportSocket, type Unsubscribe, defaultScheduler, joinRelay, joinRoom, linkForUrl, resolveUrl, roomIdFrom, webSocketTransport };
package/dist/index.js CHANGED
@@ -11,6 +11,8 @@ import {
11
11
 
12
12
  // src/endpoint.ts
13
13
  var DEFAULT_REGION = "eu";
14
+ var HOSTED_DOMAIN = "irt.io";
15
+ var REGION_RE = /^[a-z][a-z0-9]{0,15}$/;
14
16
  var DEV_PORT = 7070;
15
17
  function currentLocation() {
16
18
  const loc = globalThis.location;
@@ -28,13 +30,23 @@ function envUrl() {
28
30
  if (typeof fromEnv === "string" && fromEnv !== "") return fromEnv;
29
31
  return void 0;
30
32
  }
31
- function resolveUrl(explicit) {
33
+ function regionLabel(region) {
34
+ if (region === void 0 || region === "") return DEFAULT_REGION;
35
+ if (!REGION_RE.test(region)) {
36
+ throw new Error(
37
+ `irtio: ${JSON.stringify(region)} is not a region label. Use lowercase letters and digits starting with a letter, e.g. "eu" or "us", matching the region your project is set to in the dashboard.`
38
+ );
39
+ }
40
+ return region;
41
+ }
42
+ function resolveUrl(explicit, region) {
43
+ const label = regionLabel(region);
32
44
  if (explicit !== void 0 && explicit !== "") return explicit;
33
45
  const fromEnv = envUrl();
34
46
  if (fromEnv !== void 0) return fromEnv;
35
47
  const loc = currentLocation();
36
48
  if (!loc || isLocalHostname(loc.hostname)) return `ws://localhost:${DEV_PORT}`;
37
- return `wss://${DEFAULT_REGION}.irt.io`;
49
+ return `wss://${label}.${HOSTED_DOMAIN}`;
38
50
  }
39
51
  function isLocalUrl(url) {
40
52
  try {
@@ -1191,7 +1203,7 @@ function callProxy(session) {
1191
1203
  });
1192
1204
  }
1193
1205
  async function joinRoom(schema, options = {}) {
1194
- const url = resolveUrl(options.url);
1206
+ const url = resolveUrl(options.url, options.region);
1195
1207
  const key = resolveKey(options.key, schema, url);
1196
1208
  const explicitRoom = options.room !== void 0;
1197
1209
  const fromLocation = !explicitRoom && currentLocation() !== void 0;
@@ -1269,7 +1281,7 @@ function makeRoom(session) {
1269
1281
  return room;
1270
1282
  }
1271
1283
  async function joinRelay(options = {}) {
1272
- const url = resolveUrl(options.url);
1284
+ const url = resolveUrl(options.url, options.region);
1273
1285
  const explicitRoom = options.room !== void 0;
1274
1286
  const fromLocation = !explicitRoom && currentLocation() !== void 0;
1275
1287
  const roomId = explicitRoom ? roomIdFrom(options.room ?? "") : fromLocation ? roomIdFromLocation() : "";
@@ -1322,6 +1334,7 @@ export {
1322
1334
  MAX_PREDICTED_BODIES,
1323
1335
  PING_INTERVAL_MS,
1324
1336
  PREDICTION_EPSILON,
1337
+ REGION_RE,
1325
1338
  RESIM_DEPTH,
1326
1339
  SMOOTHING_HALF_LIFE_MS,
1327
1340
  SMOOTHING_SNAP_UNITS,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@irtio/client",
3
- "version": "0.3.0",
3
+ "version": "0.5.0",
4
4
  "description": "irtio client SDK: joinRoom, owned-write batching, corrections, typed RPCs, presence, reconnection",
5
5
  "license": "MIT",
6
6
  "publishConfig": {
@@ -19,8 +19,8 @@
19
19
  "dist"
20
20
  ],
21
21
  "dependencies": {
22
- "@irtio/schema": "0.3.0",
23
- "@irtio/protocol": "0.3.0"
22
+ "@irtio/protocol": "0.5.0",
23
+ "@irtio/schema": "0.5.0"
24
24
  },
25
25
  "peerDependencies": {
26
26
  "@dimforge/rapier3d-compat": ">=0.20.0"