@diffenderfer-games/hub 2.0.0-next.7 → 2.0.0-next.8
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/CHANGELOG.md +24 -4
- package/dist/auto.d.ts +2 -2
- package/dist/auto.js +2 -2
- package/dist/doctor/cli.mjs +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/shared/client-version.gen.js +1 -1
- package/dist/shared/daily.js +1 -1
- package/dist/shared/index.d.ts +87 -10
- package/dist/shared/index.d.ts.map +1 -1
- package/dist/shared/src.js +172 -28
- package/dist/shared/src.js.map +1 -1
- package/dist/turns-rules.d.ts +2 -0
- package/dist/turns-rules.js +1 -0
- package/dist/turns.d.ts +23 -1
- package/dist/turns.d.ts.map +1 -1
- package/dist/turns.js +79 -13
- package/dist/turns.js.map +1 -1
- package/package.json +7 -2
- package/src/core/turns/hub-turns.ts +25 -4
- package/src/core/turns/turn-game.ts +143 -21
- package/src/core/turns/your-turn-buzz.ts +69 -0
- package/src/core/version/client-version.gen.ts +1 -1
- package/src/index.ts +68 -67
- package/src/turns-kit/check-rules.ts +116 -17
- package/src/turns-rules.ts +12 -0
- package/src/turns.ts +4 -3
package/dist/shared/src.js
CHANGED
|
@@ -5097,6 +5097,50 @@ function isSavedEntry(candidate) {
|
|
|
5097
5097
|
return typeof readField(candidate, "path") === "string" && typeof readField(candidate, "progress") === "object";
|
|
5098
5098
|
}
|
|
5099
5099
|
//#endregion
|
|
5100
|
+
//#region src/core/turns/your-turn-buzz.ts
|
|
5101
|
+
/** The pattern: two short pulses, ms. */
|
|
5102
|
+
const YOUR_TURN_BUZZ = [
|
|
5103
|
+
60,
|
|
5104
|
+
40,
|
|
5105
|
+
60
|
|
5106
|
+
];
|
|
5107
|
+
/** Where this device keeps the player's choice (`off` turns it off). */
|
|
5108
|
+
const YOUR_TURN_BUZZ_KEY = "dg:your-turn-buzz";
|
|
5109
|
+
/** Whether going from `previous` to `next` makes this player newly due (the moment to buzz). */
|
|
5110
|
+
function isNewlyDue(previous, next) {
|
|
5111
|
+
const wasDue = previous.phase === "playing" && previous.isMyTurn;
|
|
5112
|
+
return next.phase === "playing" && next.isMyTurn && !wasDue && !next.isMuted;
|
|
5113
|
+
}
|
|
5114
|
+
/** The player's own switch on this device (on unless they turned it off). */
|
|
5115
|
+
function readYourTurnBuzz() {
|
|
5116
|
+
try {
|
|
5117
|
+
return localStorage.getItem(YOUR_TURN_BUZZ_KEY) !== "off";
|
|
5118
|
+
} catch {
|
|
5119
|
+
return true;
|
|
5120
|
+
}
|
|
5121
|
+
}
|
|
5122
|
+
/** Save the player's switch on this device. */
|
|
5123
|
+
function saveYourTurnBuzz(isOn) {
|
|
5124
|
+
try {
|
|
5125
|
+
localStorage.setItem(YOUR_TURN_BUZZ_KEY, isOn ? "on" : "off");
|
|
5126
|
+
} catch {}
|
|
5127
|
+
}
|
|
5128
|
+
/** Whether the page asks for less motion (the hub's setting, else the system's). */
|
|
5129
|
+
function prefersLessMotion() {
|
|
5130
|
+
if (typeof document !== "undefined" && document.documentElement.dataset.hubMotion === "reduce") return true;
|
|
5131
|
+
return typeof matchMedia === "function" && matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
5132
|
+
}
|
|
5133
|
+
/** Buzz now, when this page is visible and nothing says not to; fails silently. Answers whether it buzzed. */
|
|
5134
|
+
function buzzYourTurn() {
|
|
5135
|
+
if (typeof document === "undefined" || document.visibilityState !== "visible" || !readYourTurnBuzz() || prefersLessMotion()) return false;
|
|
5136
|
+
if (typeof navigator === "undefined" || typeof navigator.vibrate !== "function") return false;
|
|
5137
|
+
try {
|
|
5138
|
+
return navigator.vibrate([...YOUR_TURN_BUZZ]);
|
|
5139
|
+
} catch {
|
|
5140
|
+
return false;
|
|
5141
|
+
}
|
|
5142
|
+
}
|
|
5143
|
+
//#endregion
|
|
5100
5144
|
//#region src/core/turns/turn-game.ts
|
|
5101
5145
|
/** The window event the social runtime fires for each `ev:turn`. */
|
|
5102
5146
|
const TURN_EVENT = "hub:turn";
|
|
@@ -5106,9 +5150,13 @@ const TURN_RESYNC_EVENT = "hub:turn-resync";
|
|
|
5106
5150
|
const TURN_CHAT_EVENT = "hub:turn-chat";
|
|
5107
5151
|
/** How often a page without the live runtime looks for moves, ms. */
|
|
5108
5152
|
const TURN_POLL_MS = 2e4;
|
|
5153
|
+
/** How long a visible page waiting on another player's move may hear nothing before it fetches the game again, ms. */
|
|
5154
|
+
const TURN_QUIET_MS = 15e3;
|
|
5155
|
+
/** How often the page checks whether it should fetch, ms. */
|
|
5156
|
+
const TURN_CHECK_MS = 5e3;
|
|
5109
5157
|
/** One online game. `View`, `Move` and `Ev` (its events) are the game's own JSON types from its rules. */
|
|
5110
5158
|
var TurnGame = class TurnGame {
|
|
5111
|
-
constructor(host, initial) {
|
|
5159
|
+
constructor(host, initial, options = {}) {
|
|
5112
5160
|
_defineProperty(this, "id", void 0);
|
|
5113
5161
|
_defineProperty(this, "state", void 0);
|
|
5114
5162
|
_defineProperty(this, "host", void 0);
|
|
@@ -5122,7 +5170,11 @@ var TurnGame = class TurnGame {
|
|
|
5122
5170
|
_defineProperty(this, "isClosed", false);
|
|
5123
5171
|
_defineProperty(this, "catchingUp", null);
|
|
5124
5172
|
_defineProperty(this, "ownSeq", null);
|
|
5173
|
+
_defineProperty(this, "heardAt", Date.now());
|
|
5174
|
+
_defineProperty(this, "options", void 0);
|
|
5175
|
+
_defineProperty(this, "isBuzzOn", true);
|
|
5125
5176
|
this.host = host;
|
|
5177
|
+
this.options = options;
|
|
5126
5178
|
this.id = initial.id;
|
|
5127
5179
|
this.state = initial;
|
|
5128
5180
|
host.opened(this);
|
|
@@ -5156,20 +5208,44 @@ var TurnGame = class TurnGame {
|
|
|
5156
5208
|
get link() {
|
|
5157
5209
|
return this.state.link === null ? null : new URL(this.state.link, location.origin).href;
|
|
5158
5210
|
}
|
|
5211
|
+
/** Whether this player may move now without it being their turn (the rules' `mayAct`: a jump-in, calling or catching "UNO"): offer that action. */
|
|
5212
|
+
get mayActNow() {
|
|
5213
|
+
const { mySeat } = this.state;
|
|
5214
|
+
return mySeat !== null && this.state.summary.phase === "playing" && (this.state.summary.mayAct ?? []).includes(mySeat);
|
|
5215
|
+
}
|
|
5216
|
+
/** The tournament match this game is, or `null` (show it if you like: "Saturday Cup: your match"). */
|
|
5217
|
+
get tournament() {
|
|
5218
|
+
return this.state.tournament ?? null;
|
|
5219
|
+
}
|
|
5220
|
+
/**
|
|
5221
|
+
* The "your turn" buzz for this game: a short vibration when this player
|
|
5222
|
+
* becomes due on a live update while the page is visible (never for the
|
|
5223
|
+
* next step of their own turn, a move out of turn, a game just opened or a
|
|
5224
|
+
* catch-up; never when the player turned it off or asks for less motion;
|
|
5225
|
+
* silently nothing where the device can't vibrate). On by default.
|
|
5226
|
+
*/
|
|
5227
|
+
setYourTurnBuzz(isOn) {
|
|
5228
|
+
this.isBuzzOn = isOn;
|
|
5229
|
+
}
|
|
5159
5230
|
/** Creator: start the game (empty seats go to the computer when the game allows). */
|
|
5160
5231
|
async start() {
|
|
5161
5232
|
this.update(await this.host.start(this.id));
|
|
5162
5233
|
}
|
|
5163
5234
|
/**
|
|
5164
|
-
* Make a move
|
|
5165
|
-
*
|
|
5166
|
-
*
|
|
5235
|
+
* Make a move: when it is your turn (`summary.isMyTurn`), or out of turn
|
|
5236
|
+
* when the rules allow it (`mayActNow`). Rejects with a `HubError`: 403
|
|
5237
|
+
* `not_your_turn`, 409 `stale` (the game moved on, or another player's
|
|
5238
|
+
* move got there first: the view is refreshed first), 422 `illegal` with
|
|
5239
|
+
* the rules' own code in `rule`, 500 `rules_error` or 503 `rules_busy`
|
|
5240
|
+
* (the move was not made; the game is fetched again). The answer's `view` is the newest this
|
|
5241
|
+
* page has: moves that arrived live while the answer was on its way (the
|
|
5242
|
+
* computer's, another player's) are never rolled back.
|
|
5167
5243
|
*/
|
|
5168
5244
|
async move(move) {
|
|
5169
5245
|
this.ownSeq = this.state.summary.seq + 1;
|
|
5170
5246
|
try {
|
|
5171
5247
|
const answer = await this.host.move(this.id, this.state.summary.seq, toPayload(move));
|
|
5172
|
-
this.update(answer.game);
|
|
5248
|
+
if (answer.game.summary.seq >= this.state.summary.seq) this.update(answer.game);
|
|
5173
5249
|
return {
|
|
5174
5250
|
seq: answer.game.summary.seq,
|
|
5175
5251
|
view: this.view,
|
|
@@ -5177,6 +5253,7 @@ var TurnGame = class TurnGame {
|
|
|
5177
5253
|
};
|
|
5178
5254
|
} catch (failure) {
|
|
5179
5255
|
if (failure instanceof HubError && failure.code === "stale") await this.refresh();
|
|
5256
|
+
else if (failure instanceof HubError && (failure.code === "rules_error" || failure.code === "rules_busy")) await this.catchUp();
|
|
5180
5257
|
throw failure;
|
|
5181
5258
|
} finally {
|
|
5182
5259
|
this.ownSeq = null;
|
|
@@ -5205,7 +5282,7 @@ var TurnGame = class TurnGame {
|
|
|
5205
5282
|
}
|
|
5206
5283
|
/** A finished game: a new one with the same friends (they get an invite). */
|
|
5207
5284
|
async rematch() {
|
|
5208
|
-
return new TurnGame(this.host, await this.host.rematch(this.id));
|
|
5285
|
+
return new TurnGame(this.host, await this.host.rematch(this.id), this.options);
|
|
5209
5286
|
}
|
|
5210
5287
|
/** Creator, before the start: add an invite link (`link: true`, then read `link`) or list the open seats for anyone (`public`). */
|
|
5211
5288
|
async share(share) {
|
|
@@ -5215,7 +5292,33 @@ var TurnGame = class TurnGame {
|
|
|
5215
5292
|
async invite(userIds) {
|
|
5216
5293
|
this.update(await this.host.invite(this.id, userIds));
|
|
5217
5294
|
}
|
|
5218
|
-
/**
|
|
5295
|
+
/**
|
|
5296
|
+
* Whether "Let the computer play for <name>" may work now: another
|
|
5297
|
+
* player is due, the hub's hand-over wait (`summary.handOverAt`) has
|
|
5298
|
+
* passed and a due player isn't connected (`TurnSeat.connected` false
|
|
5299
|
+
* or unknown), or the turn's `deadline` passed. `false` in a
|
|
5300
|
+
* tournament match, and from a hub too old to say. Re-check it on each
|
|
5301
|
+
* `turn` event (a player coming or going fires one) and when
|
|
5302
|
+
* `handOverAt` comes.
|
|
5303
|
+
*/
|
|
5304
|
+
canLetComputerPlay(now = Date.now()) {
|
|
5305
|
+
const { summary, mySeat } = this.state;
|
|
5306
|
+
if (summary.phase !== "playing" || mySeat === null || this.state.tournament !== void 0) return false;
|
|
5307
|
+
const due = summary.seats.filter((seat) => summary.toAct.includes(seat.seat) && seat.seat !== mySeat && seat.status === "joined");
|
|
5308
|
+
if (due.length === 0) return false;
|
|
5309
|
+
if (summary.deadline !== null && summary.deadline <= now) return true;
|
|
5310
|
+
const { handOverAt } = summary;
|
|
5311
|
+
return handOverAt !== void 0 && handOverAt !== null && handOverAt <= now && due.some((seat) => seat.connected !== true);
|
|
5312
|
+
}
|
|
5313
|
+
/**
|
|
5314
|
+
* Let the computer play for whoever is due: a turn whose deadline passed
|
|
5315
|
+
* (or whose player is suspended) is played once; otherwise, when that
|
|
5316
|
+
* player has been due a while (2 minutes) and isn't connected at all, the
|
|
5317
|
+
* computer plays their seat for the rest of the game (it shows as `bot`,
|
|
5318
|
+
* named with who chose it) until they open the game again. Rejects with
|
|
5319
|
+
* 409 `deadline_not_passed` when neither (it never says whether they are
|
|
5320
|
+
* online), and 409 `not_supported` in a tournament match.
|
|
5321
|
+
*/
|
|
5219
5322
|
async letComputerPlay() {
|
|
5220
5323
|
this.update(await this.host.autoPlay(this.id));
|
|
5221
5324
|
}
|
|
@@ -5223,20 +5326,28 @@ var TurnGame = class TurnGame {
|
|
|
5223
5326
|
say(send) {
|
|
5224
5327
|
return this.host.chat(this.id, send);
|
|
5225
5328
|
}
|
|
5226
|
-
/**
|
|
5329
|
+
/**
|
|
5330
|
+
* Fetch the game again, and replay moves missed since the last one this
|
|
5331
|
+
* page saw. An answer older than what the page has by then (live moves
|
|
5332
|
+
* arrived while it was on its way) is dropped, never rolled back to, and
|
|
5333
|
+
* a move that arrived live is never replayed twice.
|
|
5334
|
+
*/
|
|
5227
5335
|
async refresh() {
|
|
5228
|
-
const before = this.state.summary.seq;
|
|
5229
5336
|
const fresh = await this.host.get(this.id);
|
|
5230
|
-
|
|
5231
|
-
|
|
5337
|
+
const seen = this.state.summary.seq;
|
|
5338
|
+
if (fresh.summary.seq <= seen) {
|
|
5232
5339
|
this.update(fresh);
|
|
5233
|
-
|
|
5234
|
-
|
|
5235
|
-
|
|
5236
|
-
|
|
5237
|
-
|
|
5238
|
-
|
|
5239
|
-
|
|
5340
|
+
return;
|
|
5341
|
+
}
|
|
5342
|
+
const missed = await this.host.history(this.id, seen);
|
|
5343
|
+
const since = this.state.summary.seq;
|
|
5344
|
+
this.update(fresh);
|
|
5345
|
+
for (const move of missed) if (move.seq > since && move.seq <= fresh.summary.seq) this.emit("move", {
|
|
5346
|
+
seq: move.seq,
|
|
5347
|
+
seat: move.seat,
|
|
5348
|
+
view: this.view,
|
|
5349
|
+
events: move.events.map((event) => toGameData(event))
|
|
5350
|
+
});
|
|
5240
5351
|
}
|
|
5241
5352
|
/** Hear moves, turn changes, the end and chat; returns a function that stops listening. */
|
|
5242
5353
|
on(eventName, listener) {
|
|
@@ -5253,11 +5364,13 @@ var TurnGame = class TurnGame {
|
|
|
5253
5364
|
for (const stop of this.stopListening) stop();
|
|
5254
5365
|
this.host.closed(this);
|
|
5255
5366
|
}
|
|
5256
|
-
/** Take a fresh answer from the hub; fire `turn` and `ended` when they changed. */
|
|
5367
|
+
/** Take a fresh answer from the hub (one older than what the page has is dropped: no rollback); fire `turn` and `ended` when they changed. */
|
|
5257
5368
|
update(next) {
|
|
5369
|
+
this.heardAt = Date.now();
|
|
5258
5370
|
const previous = this.state;
|
|
5371
|
+
if (next.summary.seq < previous.summary.seq) return;
|
|
5259
5372
|
this.state = next;
|
|
5260
|
-
if (previous.summary.seq !== next.summary.seq || previous.summary.phase !== next.summary.phase || !sameSeats(previous.summary, next.summary) || previous.chatMode !== next.chatMode || previous.link !== next.link) this.emit("turn", next.summary);
|
|
5373
|
+
if (previous.summary.seq !== next.summary.seq || previous.summary.phase !== next.summary.phase || !sameSeats(previous.summary, next.summary) || previous.summary.handOverAt !== next.summary.handOverAt || previous.chatMode !== next.chatMode || previous.link !== next.link) this.emit("turn", next.summary);
|
|
5261
5374
|
if (previous.summary.phase !== "ended" && next.summary.phase === "ended") this.emit("ended", {
|
|
5262
5375
|
outcome: next.outcome,
|
|
5263
5376
|
view: this.view
|
|
@@ -5267,8 +5380,14 @@ var TurnGame = class TurnGame {
|
|
|
5267
5380
|
const set = this.listeners[eventName];
|
|
5268
5381
|
for (const listener of set) listener(payload);
|
|
5269
5382
|
}
|
|
5383
|
+
/** Whether it is another player's move now (the page is waiting on someone). */
|
|
5384
|
+
isWaitingOnOthers() {
|
|
5385
|
+
const { summary } = this.state;
|
|
5386
|
+
return summary.phase === "playing" && !summary.isMyTurn;
|
|
5387
|
+
}
|
|
5270
5388
|
/** A live `hub:turn` for this game: a move (or a missed run of them), or another change. */
|
|
5271
5389
|
onLive(detail) {
|
|
5390
|
+
this.heardAt = Date.now();
|
|
5272
5391
|
const seq = readField(detail, "seq");
|
|
5273
5392
|
const view = readField(detail, "view");
|
|
5274
5393
|
const summary = readField(detail, "summary");
|
|
@@ -5277,17 +5396,20 @@ var TurnGame = class TurnGame {
|
|
|
5277
5396
|
this.catchUp();
|
|
5278
5397
|
return;
|
|
5279
5398
|
}
|
|
5399
|
+
if (seq < this.state.summary.seq) return;
|
|
5280
5400
|
const seat = readField(detail, "seat");
|
|
5281
5401
|
const events = readField(detail, "events");
|
|
5282
5402
|
const outcome = readField(detail, "outcome");
|
|
5283
5403
|
const isMove = typeof seat === "number" && seq === this.state.summary.seq + 1 && seq !== this.ownSeq;
|
|
5284
5404
|
if (summary.phase !== this.state.summary.phase || !sameSeating(this.state.summary, summary)) this.catchUp();
|
|
5405
|
+
const before = this.state.summary;
|
|
5285
5406
|
this.update({
|
|
5286
5407
|
...this.state,
|
|
5287
5408
|
summary,
|
|
5288
5409
|
view: toPayloadJson(view),
|
|
5289
5410
|
outcome: isOutcome(outcome) ? outcome : this.state.outcome
|
|
5290
5411
|
});
|
|
5412
|
+
if (this.isBuzzOn && (this.options.isBuzzOn?.() ?? true) && isNewlyDue(before, this.state.summary)) buzzYourTurn();
|
|
5291
5413
|
if (isMove) this.emit("move", {
|
|
5292
5414
|
seq,
|
|
5293
5415
|
seat,
|
|
@@ -5332,8 +5454,13 @@ var TurnGame = class TurnGame {
|
|
|
5332
5454
|
window.addEventListener(TURN_RESYNC_EVENT, onResync);
|
|
5333
5455
|
document.addEventListener("visibilitychange", onVisible);
|
|
5334
5456
|
const poll = setInterval(() => {
|
|
5335
|
-
if (
|
|
5336
|
-
|
|
5457
|
+
if (document.visibilityState !== "visible" || this.catchingUp !== null) return;
|
|
5458
|
+
const quietMs = Date.now() - this.heardAt;
|
|
5459
|
+
if (this.host.isLive() ? this.isWaitingOnOthers() && quietMs >= 15e3 : quietMs >= 2e4) {
|
|
5460
|
+
this.heardAt = Date.now();
|
|
5461
|
+
this.catchUp();
|
|
5462
|
+
}
|
|
5463
|
+
}, TURN_CHECK_MS);
|
|
5337
5464
|
this.stopListening.push(() => {
|
|
5338
5465
|
window.removeEventListener(TURN_EVENT, onTurn);
|
|
5339
5466
|
}, () => {
|
|
@@ -5358,9 +5485,9 @@ function eachSeat(a, b, same) {
|
|
|
5358
5485
|
function sameSeating(a, b) {
|
|
5359
5486
|
return eachSeat(a, b, (seat, other) => seat.status === other.status && seat.userId === other.userId);
|
|
5360
5487
|
}
|
|
5361
|
-
/** The same seating, and
|
|
5488
|
+
/** The same seating, looks and who is connected (a player's new avatar, or a player coming or going, is a change: `turn` fires). */
|
|
5362
5489
|
function sameSeats(a, b) {
|
|
5363
|
-
return sameSeating(a, b) && eachSeat(a, b, (seat, other) => seat.look === other.look);
|
|
5490
|
+
return sameSeating(a, b) && eachSeat(a, b, (seat, other) => seat.look === other.look && seat.connected === other.connected);
|
|
5364
5491
|
}
|
|
5365
5492
|
/** A game's move as the JSON the hub takes. */
|
|
5366
5493
|
function toPayload(move) {
|
|
@@ -5414,8 +5541,25 @@ function isGameId(idOrKey) {
|
|
|
5414
5541
|
var HubTurns = class {
|
|
5415
5542
|
constructor(host) {
|
|
5416
5543
|
_defineProperty(this, "host", void 0);
|
|
5544
|
+
_defineProperty(this, "isBuzzOn", true);
|
|
5545
|
+
_defineProperty(this, "gameOptions", { isBuzzOn: () => this.isBuzzOn });
|
|
5417
5546
|
this.host = host;
|
|
5418
5547
|
}
|
|
5548
|
+
/**
|
|
5549
|
+
* This page's "your turn" buzz (a short vibration when the player becomes
|
|
5550
|
+
* due in an open game, see `TurnGame.setYourTurnBuzz`): pass `false` if
|
|
5551
|
+
* your game gives its own signal. On by default.
|
|
5552
|
+
*/
|
|
5553
|
+
setYourTurnBuzz(isOn) {
|
|
5554
|
+
this.isBuzzOn = isOn;
|
|
5555
|
+
}
|
|
5556
|
+
/** The player's own "Buzz when it's my turn" switch on this device (the menu's Settings show it too). */
|
|
5557
|
+
get playerYourTurnBuzz() {
|
|
5558
|
+
return readYourTurnBuzz();
|
|
5559
|
+
}
|
|
5560
|
+
set playerYourTurnBuzz(isOn) {
|
|
5561
|
+
saveYourTurnBuzz(isOn);
|
|
5562
|
+
}
|
|
5419
5563
|
/** The invite link key this page was opened with (`?hub_turn_link=`), taken out of the address bar; `null` when none. Synchronous. */
|
|
5420
5564
|
get link() {
|
|
5421
5565
|
return linkOnPage();
|
|
@@ -5434,16 +5578,16 @@ var HubTurns = class {
|
|
|
5434
5578
|
...options.deadline === void 0 ? {} : { deadline: options.deadline },
|
|
5435
5579
|
...options.autoStart === void 0 ? {} : { autoStart: options.autoStart }
|
|
5436
5580
|
};
|
|
5437
|
-
return new TurnGame(this.host, await this.host.create(body));
|
|
5581
|
+
return new TurnGame(this.host, await this.host.create(body), this.gameOptions);
|
|
5438
5582
|
}
|
|
5439
5583
|
/** Take a seat: by the game's id (an invite, an open seat) or by an invite link's key. */
|
|
5440
5584
|
async join(idOrLinkKey) {
|
|
5441
5585
|
const joined = isGameId(idOrLinkKey) ? await this.host.join(idOrLinkKey) : await this.host.joinByLink(idOrLinkKey);
|
|
5442
|
-
return new TurnGame(this.host, joined);
|
|
5586
|
+
return new TurnGame(this.host, joined, this.gameOptions);
|
|
5443
5587
|
}
|
|
5444
5588
|
/** Open a game the player sits in (from `hub.saved.opened`, the Continue list, an invite). */
|
|
5445
5589
|
async open(id) {
|
|
5446
|
-
return new TurnGame(this.host, await this.host.get(id));
|
|
5590
|
+
return new TurnGame(this.host, await this.host.get(id), this.gameOptions);
|
|
5447
5591
|
}
|
|
5448
5592
|
/** This game's online games the player sits in (the same rows as `hub.saved.list({ kinds: ['turns'] })`). */
|
|
5449
5593
|
list() {
|
|
@@ -5900,6 +6044,6 @@ function createHub(options = {}) {
|
|
|
5900
6044
|
return new Hub(options);
|
|
5901
6045
|
}
|
|
5902
6046
|
//#endregion
|
|
5903
|
-
export {
|
|
6047
|
+
export { OUTBOX_MAX_ENTRIES as A, savedGameUrl as C, CLIENT_VERSION_HEADER as D, RESUME_MAX_STATE_BYTES as E, SAVE_UNKNOWN_CODE as F, UNSUPPORTED_BY_HUB as I, HubAvatar as L, ContentRejectedError as M, HubError as N, OUTBOX_FULL_CODE as O, OfflineError as P, SAVED_OPEN_PARAM as S, RESUME_DEBOUNCE_MS as T, HubSaved as _, TURN_LINK_PARAM as a, SAVED_KIND_PARAM as b, TURN_POLL_MS as c, TurnGame as d, YOUR_TURN_BUZZ as f, saveYourTurnBuzz as g, readYourTurnBuzz as h, HubTurns as i, OfflineApi as j, OUTBOX_MAX_CHARS as k, TURN_QUIET_MS as l, isNewlyDue as m, createHub as n, TURN_CHAT_EVENT as o, YOUR_TURN_BUZZ_KEY as p, hub as r, TURN_EVENT as s, Hub as t, TURN_RESYNC_EVENT as u, SAVED_CHANGE_QUIET_MS as v, HubResume as w, SAVED_OPEN_EVENT as x, SAVED_CHANGE_EVENT as y };
|
|
5904
6048
|
|
|
5905
6049
|
//# sourceMappingURL=src.js.map
|