@bluebottle_gg/league-broadcast-client 0.1.0 → 0.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.
- package/README.md +275 -78
- package/dist/index.d.ts +1248 -141
- package/dist/index.js +1053 -111
- package/dist/index.js.map +1 -1
- package/package.json +9 -6
package/dist/index.js
CHANGED
|
@@ -326,6 +326,134 @@ function shallowEqual(a, b) {
|
|
|
326
326
|
return true;
|
|
327
327
|
}
|
|
328
328
|
|
|
329
|
+
// src/reactivity/ChampSelectStateStore.ts
|
|
330
|
+
var ChampSelectStateStore = class {
|
|
331
|
+
constructor(initialState) {
|
|
332
|
+
/** Global listeners — called on every state change regardless of selector. */
|
|
333
|
+
this.listeners = /* @__PURE__ */ new Set();
|
|
334
|
+
/** Monotonically increasing version — used for cheap stale checks. */
|
|
335
|
+
this.version = 0;
|
|
336
|
+
this.snapshot = Object.freeze({
|
|
337
|
+
champSelectData: initialState,
|
|
338
|
+
isActive: initialState.isActive,
|
|
339
|
+
version: this.version
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
// ---------------------------------------------------------------------------
|
|
343
|
+
// Core API
|
|
344
|
+
// ---------------------------------------------------------------------------
|
|
345
|
+
/** Return the current full snapshot. */
|
|
346
|
+
getSnapshot() {
|
|
347
|
+
return this.snapshot;
|
|
348
|
+
}
|
|
349
|
+
/** Return the current version number. */
|
|
350
|
+
getVersion() {
|
|
351
|
+
return this.version;
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Subscribe to **all** state changes (unfiltered).
|
|
355
|
+
* Returns an unsubscribe function.
|
|
356
|
+
*/
|
|
357
|
+
subscribe(listener) {
|
|
358
|
+
this.listeners.add(listener);
|
|
359
|
+
return () => {
|
|
360
|
+
this.listeners.delete(listener);
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
// ---------------------------------------------------------------------------
|
|
364
|
+
// Selectors
|
|
365
|
+
// ---------------------------------------------------------------------------
|
|
366
|
+
/**
|
|
367
|
+
* Create a **subscribable slice** that only triggers when the selected
|
|
368
|
+
* value changes according to `equalityFn` (defaults to `===`).
|
|
369
|
+
*/
|
|
370
|
+
select(selector, equalityFn = Object.is) {
|
|
371
|
+
let currentValue = selector(this.snapshot);
|
|
372
|
+
let lastVersion = this.version;
|
|
373
|
+
const sliceListeners = /* @__PURE__ */ new Set();
|
|
374
|
+
const getSnapshot = () => {
|
|
375
|
+
if (lastVersion !== this.version) {
|
|
376
|
+
const next = selector(this.snapshot);
|
|
377
|
+
if (!equalityFn(currentValue, next)) {
|
|
378
|
+
currentValue = next;
|
|
379
|
+
}
|
|
380
|
+
lastVersion = this.version;
|
|
381
|
+
}
|
|
382
|
+
return currentValue;
|
|
383
|
+
};
|
|
384
|
+
const subscribe = (listener) => {
|
|
385
|
+
sliceListeners.add(listener);
|
|
386
|
+
const unsub = this.subscribe(() => {
|
|
387
|
+
const prev = currentValue;
|
|
388
|
+
const next = selector(this.snapshot);
|
|
389
|
+
lastVersion = this.version;
|
|
390
|
+
if (!equalityFn(prev, next)) {
|
|
391
|
+
currentValue = next;
|
|
392
|
+
listener();
|
|
393
|
+
}
|
|
394
|
+
});
|
|
395
|
+
return () => {
|
|
396
|
+
sliceListeners.delete(listener);
|
|
397
|
+
unsub();
|
|
398
|
+
};
|
|
399
|
+
};
|
|
400
|
+
return { subscribe, getSnapshot };
|
|
401
|
+
}
|
|
402
|
+
// ---------------------------------------------------------------------------
|
|
403
|
+
// Convenience helpers
|
|
404
|
+
// ---------------------------------------------------------------------------
|
|
405
|
+
/**
|
|
406
|
+
* Watch a derived value and invoke `callback` whenever it changes.
|
|
407
|
+
* Returns an unsubscribe function.
|
|
408
|
+
*/
|
|
409
|
+
watch(selector, callback, equalityFn = Object.is) {
|
|
410
|
+
let prev = selector(this.snapshot);
|
|
411
|
+
return this.subscribe(() => {
|
|
412
|
+
const next = selector(this.snapshot);
|
|
413
|
+
if (!equalityFn(prev, next)) {
|
|
414
|
+
const old = prev;
|
|
415
|
+
prev = next;
|
|
416
|
+
callback(next, old);
|
|
417
|
+
}
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
/**
|
|
421
|
+
* Watch a derived value and invoke `callback` whenever it changes,
|
|
422
|
+
* **and** invoke it immediately with the current value.
|
|
423
|
+
*/
|
|
424
|
+
watchImmediate(selector, callback, equalityFn = Object.is) {
|
|
425
|
+
const current = selector(this.snapshot);
|
|
426
|
+
callback(current, void 0);
|
|
427
|
+
return this.watch(selector, callback, equalityFn);
|
|
428
|
+
}
|
|
429
|
+
// ---------------------------------------------------------------------------
|
|
430
|
+
// Internal — called by LeagueBroadcastClient
|
|
431
|
+
// ---------------------------------------------------------------------------
|
|
432
|
+
/** @internal Replace champ-select data snapshot and notify listeners. */
|
|
433
|
+
_setChampSelectData(data) {
|
|
434
|
+
this.version++;
|
|
435
|
+
this.snapshot = Object.freeze({
|
|
436
|
+
champSelectData: data,
|
|
437
|
+
isActive: data.isActive,
|
|
438
|
+
version: this.version
|
|
439
|
+
});
|
|
440
|
+
this.emit();
|
|
441
|
+
}
|
|
442
|
+
/** @internal Replace entire snapshot (used on champ select end / reset). */
|
|
443
|
+
_reset(data) {
|
|
444
|
+
this.version++;
|
|
445
|
+
this.snapshot = Object.freeze({
|
|
446
|
+
champSelectData: data,
|
|
447
|
+
isActive: data.isActive,
|
|
448
|
+
version: this.version
|
|
449
|
+
});
|
|
450
|
+
this.emit();
|
|
451
|
+
}
|
|
452
|
+
emit() {
|
|
453
|
+
this.listeners.forEach((l) => l());
|
|
454
|
+
}
|
|
455
|
+
};
|
|
456
|
+
|
|
329
457
|
// src/reactivity/structuralShare.ts
|
|
330
458
|
function structuralShare(prev, next) {
|
|
331
459
|
if (Object.is(prev, next)) {
|
|
@@ -358,6 +486,14 @@ function structuralShare(prev, next) {
|
|
|
358
486
|
const nextKeys = Object.keys(nextObj);
|
|
359
487
|
const prevKeys = Object.keys(prevObj);
|
|
360
488
|
let changed = nextKeys.length !== prevKeys.length;
|
|
489
|
+
if (!changed) {
|
|
490
|
+
for (const key of prevKeys) {
|
|
491
|
+
if (!Object.prototype.hasOwnProperty.call(nextObj, key)) {
|
|
492
|
+
changed = true;
|
|
493
|
+
break;
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
}
|
|
361
497
|
const result = Object.create(
|
|
362
498
|
Object.getPrototypeOf(next)
|
|
363
499
|
);
|
|
@@ -395,6 +531,591 @@ var ingameFrontendData = class {
|
|
|
395
531
|
this.playbackSpeed = 0;
|
|
396
532
|
this.gameVersion = "";
|
|
397
533
|
this.gameStatus = 0 /* OutOfGame */;
|
|
534
|
+
this.showTwitchPrediction = false;
|
|
535
|
+
this.showTwitchPoll = false;
|
|
536
|
+
this.showTwitchChatVote = false;
|
|
537
|
+
}
|
|
538
|
+
};
|
|
539
|
+
|
|
540
|
+
// types/pregame/champselectstatedata.ts
|
|
541
|
+
var champSelectStateData = class {
|
|
542
|
+
constructor() {
|
|
543
|
+
this.isActive = false;
|
|
544
|
+
this.isConnected = false;
|
|
545
|
+
this.isTestingEnvironment = false;
|
|
546
|
+
this.blueTeam = {};
|
|
547
|
+
this.redTeam = {};
|
|
548
|
+
this.metaData = {};
|
|
549
|
+
this.timer = {};
|
|
550
|
+
}
|
|
551
|
+
};
|
|
552
|
+
|
|
553
|
+
// src/api/ApiClient.ts
|
|
554
|
+
var ApiClient = class {
|
|
555
|
+
constructor(baseUrl) {
|
|
556
|
+
this.baseUrl = baseUrl;
|
|
557
|
+
}
|
|
558
|
+
/** Update the base URL (e.g. after reconnecting to a different host/port). */
|
|
559
|
+
updateBaseUrl(baseUrl) {
|
|
560
|
+
this.baseUrl = baseUrl;
|
|
561
|
+
}
|
|
562
|
+
/** Current base URL. */
|
|
563
|
+
getBaseUrl() {
|
|
564
|
+
return this.baseUrl;
|
|
565
|
+
}
|
|
566
|
+
// ── HTTP verbs ──────────────────────────────────────────────────────────
|
|
567
|
+
async get(path) {
|
|
568
|
+
return this.request("GET", path);
|
|
569
|
+
}
|
|
570
|
+
async post(path, body) {
|
|
571
|
+
return this.request("POST", path, body);
|
|
572
|
+
}
|
|
573
|
+
async put(path, body) {
|
|
574
|
+
return this.request("PUT", path, body);
|
|
575
|
+
}
|
|
576
|
+
async patch(path, body) {
|
|
577
|
+
return this.request("PATCH", path, body);
|
|
578
|
+
}
|
|
579
|
+
async delete(path) {
|
|
580
|
+
return this.request("DELETE", path);
|
|
581
|
+
}
|
|
582
|
+
/**
|
|
583
|
+
* POST with a raw string body (e.g. base64 image data).
|
|
584
|
+
* Sets Content-Type to text/plain instead of application/json.
|
|
585
|
+
*/
|
|
586
|
+
async postRaw(path, rawBody) {
|
|
587
|
+
return this.request("POST", path, rawBody, "text/plain");
|
|
588
|
+
}
|
|
589
|
+
/**
|
|
590
|
+
* PUT with a raw string body (e.g. base64 image data).
|
|
591
|
+
* Sets Content-Type to text/plain instead of application/json.
|
|
592
|
+
*/
|
|
593
|
+
async putRaw(path, rawBody) {
|
|
594
|
+
return this.request("PUT", path, rawBody, "text/plain");
|
|
595
|
+
}
|
|
596
|
+
// ── Internal ────────────────────────────────────────────────────────────
|
|
597
|
+
buildUrl(path) {
|
|
598
|
+
const base = this.baseUrl.endsWith("/") ? this.baseUrl.slice(0, -1) : this.baseUrl;
|
|
599
|
+
const cleanPath = path.startsWith("/") ? path.slice(1) : path;
|
|
600
|
+
return `${base}/${cleanPath}`;
|
|
601
|
+
}
|
|
602
|
+
async request(method, path, body, contentType) {
|
|
603
|
+
const url = this.buildUrl(path);
|
|
604
|
+
const headers = {};
|
|
605
|
+
let bodyStr;
|
|
606
|
+
if (body !== void 0) {
|
|
607
|
+
if (contentType === "text/plain") {
|
|
608
|
+
headers["Content-Type"] = "text/plain";
|
|
609
|
+
bodyStr = String(body);
|
|
610
|
+
} else {
|
|
611
|
+
headers["Content-Type"] = "application/json";
|
|
612
|
+
bodyStr = JSON.stringify(body);
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
const res = await fetch(url, {
|
|
616
|
+
method,
|
|
617
|
+
headers,
|
|
618
|
+
body: bodyStr
|
|
619
|
+
});
|
|
620
|
+
if (!res.ok) {
|
|
621
|
+
const errorBody = await res.text().catch(() => "");
|
|
622
|
+
throw new ApiError(res.status, res.statusText, errorBody, url);
|
|
623
|
+
}
|
|
624
|
+
return this.parseResponse(res);
|
|
625
|
+
}
|
|
626
|
+
async parseResponse(res) {
|
|
627
|
+
const text = await res.text();
|
|
628
|
+
if (!text || text.length === 0) return void 0;
|
|
629
|
+
try {
|
|
630
|
+
return JSON.parse(text);
|
|
631
|
+
} catch {
|
|
632
|
+
return text;
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
};
|
|
636
|
+
var ApiError = class extends Error {
|
|
637
|
+
constructor(status, statusText, body, url) {
|
|
638
|
+
super(`API Error ${status} (${statusText}) at ${url}`);
|
|
639
|
+
this.status = status;
|
|
640
|
+
this.statusText = statusText;
|
|
641
|
+
this.body = body;
|
|
642
|
+
this.url = url;
|
|
643
|
+
this.name = "ApiError";
|
|
644
|
+
}
|
|
645
|
+
};
|
|
646
|
+
|
|
647
|
+
// src/api/generated/PreGameApi.ts
|
|
648
|
+
var PreGameApi = class {
|
|
649
|
+
constructor(client) {
|
|
650
|
+
this.client = client;
|
|
651
|
+
}
|
|
652
|
+
/** `POST championselect/mock/{doMocking}` */
|
|
653
|
+
async mockChampionSelect(doMocking, randomizationinterval) {
|
|
654
|
+
return this.client.post(`championselect/mock/${doMocking}${randomizationinterval !== void 0 ? `?randomizationinterval=${encodeURIComponent(String(randomizationinterval))}` : ""}`);
|
|
655
|
+
}
|
|
656
|
+
/** `GET championselect/mock` */
|
|
657
|
+
async getMockingStatus() {
|
|
658
|
+
return this.client.get("championselect/mock");
|
|
659
|
+
}
|
|
660
|
+
/** `GET championselect/bans` */
|
|
661
|
+
async getBans() {
|
|
662
|
+
return this.client.get("championselect/bans");
|
|
663
|
+
}
|
|
664
|
+
/** `GET championselect/frontend` */
|
|
665
|
+
async getFrontendUrl() {
|
|
666
|
+
return this.client.get("championselect/frontend");
|
|
667
|
+
}
|
|
668
|
+
/** `GET championselect/stage/{stageSide}/teamid` */
|
|
669
|
+
async getTeamIdOnSide(stageSide) {
|
|
670
|
+
return this.client.get(`championselect/stage/${stageSide}/teamid`);
|
|
671
|
+
}
|
|
672
|
+
/** `POST championselect/frontend` */
|
|
673
|
+
async changeRouting(uri) {
|
|
674
|
+
return this.client.post(`championselect/frontend?uri=${encodeURIComponent(String(uri))}`);
|
|
675
|
+
}
|
|
676
|
+
/** `GET championselect/stage/{stageside}/{slotid}` */
|
|
677
|
+
async getPlayerPUUIDInSlot(stageside, slotid) {
|
|
678
|
+
return this.client.get(`championselect/stage/${stageside}/${slotid}`);
|
|
679
|
+
}
|
|
680
|
+
};
|
|
681
|
+
|
|
682
|
+
// src/api/generated/GameApi.ts
|
|
683
|
+
var GameApi = class {
|
|
684
|
+
constructor(client) {
|
|
685
|
+
this.client = client;
|
|
686
|
+
}
|
|
687
|
+
/** `GET game/current` */
|
|
688
|
+
async getCurrentGame() {
|
|
689
|
+
return this.client.get("game/current");
|
|
690
|
+
}
|
|
691
|
+
/** `GET game/previous` */
|
|
692
|
+
async getPreviousGame() {
|
|
693
|
+
return this.client.get("game/previous");
|
|
694
|
+
}
|
|
695
|
+
/** `GET game/{gameid}` */
|
|
696
|
+
async getGame(gameid) {
|
|
697
|
+
return this.client.get(`game/${gameid}`);
|
|
698
|
+
}
|
|
699
|
+
/** `PATCH game/{gameid}` */
|
|
700
|
+
async updateGame(gameid, game) {
|
|
701
|
+
return this.client.patch(`game/${gameid}`, game);
|
|
702
|
+
}
|
|
703
|
+
/** `PUT game/{gameid}/teams` */
|
|
704
|
+
async setSideSelection(gameid, teams) {
|
|
705
|
+
return this.client.put(`game/${gameid}/teams`, teams);
|
|
706
|
+
}
|
|
707
|
+
/** `GET game/{gameid}/teams` */
|
|
708
|
+
async getTeamsInGame(gameid) {
|
|
709
|
+
return this.client.get(`game/${gameid}/teams`);
|
|
710
|
+
}
|
|
711
|
+
/** `DELETE game/{gameid}/winner` */
|
|
712
|
+
async removeGameWinner(gameid) {
|
|
713
|
+
return this.client.delete(`game/${gameid}/winner`);
|
|
714
|
+
}
|
|
715
|
+
/** `PUT game/{gameid}/winner/{teamid}` */
|
|
716
|
+
async setGameWinner(gameid, teamid) {
|
|
717
|
+
return this.client.put(`game/${gameid}/winner/${teamid}`);
|
|
718
|
+
}
|
|
719
|
+
/** `GET game/{gameid}/bans` */
|
|
720
|
+
async getBans(gameid) {
|
|
721
|
+
return this.client.get(`game/${gameid}/bans`);
|
|
722
|
+
}
|
|
723
|
+
/** `GET game/{gameid}/bans/{teamid}` */
|
|
724
|
+
async getBansForTeam(gameid, teamid) {
|
|
725
|
+
return this.client.get(`game/${gameid}/bans/${teamid}`);
|
|
726
|
+
}
|
|
727
|
+
/** `PUT game/{gameid}/bans` */
|
|
728
|
+
async setBans(gameid, bans) {
|
|
729
|
+
return this.client.put(`game/${gameid}/bans`, bans);
|
|
730
|
+
}
|
|
731
|
+
/** `PUT game/{gameid}/bans/{teamid}` */
|
|
732
|
+
async setBansForTeam(gameid, teamid, bans) {
|
|
733
|
+
return this.client.put(`game/${gameid}/bans/${teamid}`, bans);
|
|
734
|
+
}
|
|
735
|
+
/** `GET game/{gameid}/picks` */
|
|
736
|
+
async getPicks(gameid) {
|
|
737
|
+
return this.client.get(`game/${gameid}/picks`);
|
|
738
|
+
}
|
|
739
|
+
/** `GET game/{gameid}/picks/{teamid}` */
|
|
740
|
+
async getPicksForTeam(gameid, teamid) {
|
|
741
|
+
return this.client.get(`game/${gameid}/picks/${teamid}`);
|
|
742
|
+
}
|
|
743
|
+
/** `PUT game/{gameid}/picks` */
|
|
744
|
+
async setPicks(gameid, picks) {
|
|
745
|
+
return this.client.put(`game/${gameid}/picks`, picks);
|
|
746
|
+
}
|
|
747
|
+
/** `PUT game/{gameid}/picks/{teamid}` */
|
|
748
|
+
async setPicksForTeam(gameid, teamid, picks) {
|
|
749
|
+
return this.client.put(`game/${gameid}/picks/${teamid}`, picks);
|
|
750
|
+
}
|
|
751
|
+
/** `GET game/{gameid}/teams/players` */
|
|
752
|
+
async getPlayersInGame(gameid) {
|
|
753
|
+
return this.client.get(`game/${gameid}/teams/players`);
|
|
754
|
+
}
|
|
755
|
+
};
|
|
756
|
+
|
|
757
|
+
// src/api/generated/GameStateApi.ts
|
|
758
|
+
var GameStateApi = class {
|
|
759
|
+
constructor(client) {
|
|
760
|
+
this.client = client;
|
|
761
|
+
}
|
|
762
|
+
/** `GET game/state/time` */
|
|
763
|
+
async getGameTime() {
|
|
764
|
+
return this.client.get("game/state/time");
|
|
765
|
+
}
|
|
766
|
+
/** `GET game/state/team/{teamId}/dragons` */
|
|
767
|
+
async getTeamDragons(teamId) {
|
|
768
|
+
return this.client.get(`game/state/team/${teamId}/dragons`);
|
|
769
|
+
}
|
|
770
|
+
/** `PATCH game/state/team/{teamId}/dragons` */
|
|
771
|
+
async updateTeamDragons(teamId, dragons) {
|
|
772
|
+
return this.client.patch(`game/state/team/${teamId}/dragons`, dragons);
|
|
773
|
+
}
|
|
774
|
+
/** `GET game/state/team/all/index` */
|
|
775
|
+
async getActiveTeams() {
|
|
776
|
+
return this.client.get("game/state/team/all/index");
|
|
777
|
+
}
|
|
778
|
+
/** `GET game/state/team/all/participant` */
|
|
779
|
+
async getAllTeamParticipants() {
|
|
780
|
+
return this.client.get("game/state/team/all/participant");
|
|
781
|
+
}
|
|
782
|
+
/** `GET game/state/team/{teamId}/participant` */
|
|
783
|
+
async getTeamParticipants(teamId) {
|
|
784
|
+
return this.client.get(`game/state/team/${teamId}/participant`);
|
|
785
|
+
}
|
|
786
|
+
/** `GET game/state/team/all/participant/order` */
|
|
787
|
+
async getTeamParticipantOrder() {
|
|
788
|
+
return this.client.get("game/state/team/all/participant/order");
|
|
789
|
+
}
|
|
790
|
+
/** `PUT game/state/team/all/participant/order` */
|
|
791
|
+
async updateTeamParticipantOrder(orderedNames) {
|
|
792
|
+
return this.client.put("game/state/team/all/participant/order", orderedNames);
|
|
793
|
+
}
|
|
794
|
+
};
|
|
795
|
+
|
|
796
|
+
// src/api/generated/MatchApi.ts
|
|
797
|
+
var MatchApi = class {
|
|
798
|
+
constructor(client) {
|
|
799
|
+
this.client = client;
|
|
800
|
+
}
|
|
801
|
+
/** `GET match/season/{seasonId}/simple` */
|
|
802
|
+
async getSimpleMatches(seasonId) {
|
|
803
|
+
return this.client.get(`match/season/${seasonId}/simple`);
|
|
804
|
+
}
|
|
805
|
+
/** `GET match/season/{seasonId}` */
|
|
806
|
+
async getMatches(seasonId) {
|
|
807
|
+
return this.client.get(`match/season/${seasonId}`);
|
|
808
|
+
}
|
|
809
|
+
/** `GET match/simple` */
|
|
810
|
+
async getAllSimpleMatches() {
|
|
811
|
+
return this.client.get("match/simple");
|
|
812
|
+
}
|
|
813
|
+
/** `GET match` */
|
|
814
|
+
async getAllMatches() {
|
|
815
|
+
return this.client.get("match");
|
|
816
|
+
}
|
|
817
|
+
/** `GET match/current` */
|
|
818
|
+
async getCurrentMatch() {
|
|
819
|
+
return this.client.get("match/current");
|
|
820
|
+
}
|
|
821
|
+
/** `POST match/current` */
|
|
822
|
+
async completeCurrentMatch() {
|
|
823
|
+
return this.client.post("match/current");
|
|
824
|
+
}
|
|
825
|
+
/** `GET match/current/id` */
|
|
826
|
+
async getCurrentMatchId() {
|
|
827
|
+
return this.client.get("match/current/id");
|
|
828
|
+
}
|
|
829
|
+
/** `GET match/previous/id` */
|
|
830
|
+
async getPreviousMatchId() {
|
|
831
|
+
return this.client.get("match/previous/id");
|
|
832
|
+
}
|
|
833
|
+
/** `POST match/current/{seriesid}` */
|
|
834
|
+
async setCurrentMatch(seriesid) {
|
|
835
|
+
return this.client.post(`match/current/${seriesid}`);
|
|
836
|
+
}
|
|
837
|
+
/** `GET match/current/bestof` */
|
|
838
|
+
async getCurrentMatchBestOf() {
|
|
839
|
+
return this.client.get("match/current/bestof");
|
|
840
|
+
}
|
|
841
|
+
/** `PUT match/current/bestof` */
|
|
842
|
+
async setCurrentMatchBestOf(type) {
|
|
843
|
+
return this.client.put("match/current/bestof", type);
|
|
844
|
+
}
|
|
845
|
+
/** `GET match/current/teams` */
|
|
846
|
+
async getCurrentMatchTeams() {
|
|
847
|
+
return this.client.get("match/current/teams");
|
|
848
|
+
}
|
|
849
|
+
/** `PUT match/current/teams` */
|
|
850
|
+
async setCurrentMatchTeams(teamIds) {
|
|
851
|
+
return this.client.put("match/current/teams", teamIds);
|
|
852
|
+
}
|
|
853
|
+
/** `GET match/current/game` */
|
|
854
|
+
async getCurrentGame() {
|
|
855
|
+
return this.client.get("match/current/game");
|
|
856
|
+
}
|
|
857
|
+
/** `GET match/current/ruleset` */
|
|
858
|
+
async getCurrentMatchRuleset() {
|
|
859
|
+
return this.client.get("match/current/ruleset");
|
|
860
|
+
}
|
|
861
|
+
/** `PUT match/current/ruleset/{ruleset}` */
|
|
862
|
+
async setCurrentMatchRuleset(ruleset) {
|
|
863
|
+
return this.client.put(`match/current/ruleset/${ruleset}`);
|
|
864
|
+
}
|
|
865
|
+
/** `GET match/current/fearless/bans` */
|
|
866
|
+
async getBans() {
|
|
867
|
+
return this.client.get("match/current/fearless/bans");
|
|
868
|
+
}
|
|
869
|
+
/** `GET match/current/onstage` */
|
|
870
|
+
async getCurrentMatchOnStage() {
|
|
871
|
+
return this.client.get("match/current/onstage");
|
|
872
|
+
}
|
|
873
|
+
/** `GET match/{matchid}` */
|
|
874
|
+
async getMatch(matchid) {
|
|
875
|
+
return this.client.get(`match/${matchid}`);
|
|
876
|
+
}
|
|
877
|
+
/** `DELETE match/{matchid}` */
|
|
878
|
+
async deleteMatch(matchid) {
|
|
879
|
+
return this.client.delete(`match/${matchid}`);
|
|
880
|
+
}
|
|
881
|
+
/** `GET match/{matchid}/teams` */
|
|
882
|
+
async getMatchTeams(matchid) {
|
|
883
|
+
return this.client.get(`match/${matchid}/teams`);
|
|
884
|
+
}
|
|
885
|
+
/** `PUT match/{matchid}/teams` */
|
|
886
|
+
async setMatchTeams(matchid, teamIds) {
|
|
887
|
+
return this.client.put(`match/${matchid}/teams`, teamIds);
|
|
888
|
+
}
|
|
889
|
+
/** `GET match/{matchid}/games` */
|
|
890
|
+
async getMatchGames(matchid) {
|
|
891
|
+
return this.client.get(`match/${matchid}/games`);
|
|
892
|
+
}
|
|
893
|
+
/** `GET match/{matchid}/winner` */
|
|
894
|
+
async getMatchWinner(matchid) {
|
|
895
|
+
return this.client.get(`match/${matchid}/winner`);
|
|
896
|
+
}
|
|
897
|
+
/** `PUT match/{matchid}/winner/{teamid}` */
|
|
898
|
+
async setMatchWinner(matchid, teamid) {
|
|
899
|
+
return this.client.put(`match/${matchid}/winner/${teamid}`);
|
|
900
|
+
}
|
|
901
|
+
/** `DELETE match/{matchid}/winner` */
|
|
902
|
+
async removeMatchWinner(matchid) {
|
|
903
|
+
return this.client.delete(`match/${matchid}/winner`);
|
|
904
|
+
}
|
|
905
|
+
/** `GET match/{matchid}/bestof` */
|
|
906
|
+
async getMatchBestOf(matchid) {
|
|
907
|
+
return this.client.get(`match/${matchid}/bestof`);
|
|
908
|
+
}
|
|
909
|
+
/** `PUT match/{matchid}/bestof/{type}` */
|
|
910
|
+
async setMatchBestOf(matchid, type) {
|
|
911
|
+
return this.client.put(`match/${matchid}/bestof/${type}`);
|
|
912
|
+
}
|
|
913
|
+
/** `GET match/{matchid}/ruleset` */
|
|
914
|
+
async getMatchRuleset(matchid) {
|
|
915
|
+
return this.client.get(`match/${matchid}/ruleset`);
|
|
916
|
+
}
|
|
917
|
+
/** `PUT match/{matchid}/ruleset/{ruleset}` */
|
|
918
|
+
async setMatchRuleset(matchid, ruleset) {
|
|
919
|
+
return this.client.put(`match/${matchid}/ruleset/${ruleset}`);
|
|
920
|
+
}
|
|
921
|
+
/** `GET match/{matchid}/name` */
|
|
922
|
+
async getMatchName(matchid) {
|
|
923
|
+
return this.client.get(`match/${matchid}/name`);
|
|
924
|
+
}
|
|
925
|
+
/** `PATCH match/{matchid}/name/{matchName}` */
|
|
926
|
+
async setMatchName(matchid, matchName) {
|
|
927
|
+
return this.client.patch(`match/${matchid}/name/${matchName}`);
|
|
928
|
+
}
|
|
929
|
+
/** `PATCH match/{matchid}` */
|
|
930
|
+
async updateMatch(matchid, matchUpdate) {
|
|
931
|
+
return this.client.patch(`match/${matchid}`, matchUpdate);
|
|
932
|
+
}
|
|
933
|
+
/** `GET match/{matchid}/fearless/bans` */
|
|
934
|
+
async getMatchBans(matchid) {
|
|
935
|
+
return this.client.get(`match/${matchid}/fearless/bans`);
|
|
936
|
+
}
|
|
937
|
+
/** `GET match/{seriesid}/onstage` */
|
|
938
|
+
async getMatchOnStage(seriesid) {
|
|
939
|
+
return this.client.get(`match/${seriesid}/onstage`);
|
|
940
|
+
}
|
|
941
|
+
/** `PUT match` */
|
|
942
|
+
async addMatch(match) {
|
|
943
|
+
return this.client.put("match", match);
|
|
944
|
+
}
|
|
945
|
+
/** `GET match/{matchId}/stage/team/{stageSide}` */
|
|
946
|
+
async getTeamOnStageSide(matchId, stageSide) {
|
|
947
|
+
return this.client.get(`match/${matchId}/stage/team/${stageSide}`);
|
|
948
|
+
}
|
|
949
|
+
/** `GET match/current/stage/team/{stageSide}` */
|
|
950
|
+
async getTeamOnStageSideCurrent(stageSide) {
|
|
951
|
+
return this.client.get(`match/current/stage/team/${stageSide}`);
|
|
952
|
+
}
|
|
953
|
+
};
|
|
954
|
+
|
|
955
|
+
// src/api/generated/SeasonApi.ts
|
|
956
|
+
var SeasonApi = class {
|
|
957
|
+
constructor(client) {
|
|
958
|
+
this.client = client;
|
|
959
|
+
}
|
|
960
|
+
/** `GET season/current` */
|
|
961
|
+
async getCurrentSeason() {
|
|
962
|
+
return this.client.get("season/current");
|
|
963
|
+
}
|
|
964
|
+
/** `GET season/current/match` */
|
|
965
|
+
async getCurrentSeasonScheduledMatch() {
|
|
966
|
+
return this.client.get("season/current/match");
|
|
967
|
+
}
|
|
968
|
+
/** `GET season/current/id` */
|
|
969
|
+
async getCurrentSeasonId() {
|
|
970
|
+
return this.client.get("season/current/id");
|
|
971
|
+
}
|
|
972
|
+
/** `POST season/current` */
|
|
973
|
+
async setCurrentSeason(newCurrentSeasonId) {
|
|
974
|
+
return this.client.post("season/current", newCurrentSeasonId);
|
|
975
|
+
}
|
|
976
|
+
/** `GET season/current/teams` */
|
|
977
|
+
async getCurrentSeasonTeams() {
|
|
978
|
+
return this.client.get("season/current/teams");
|
|
979
|
+
}
|
|
980
|
+
/** `GET season/current/teamswithmembers` */
|
|
981
|
+
async getCurrentSeasonTeamsWithMembers() {
|
|
982
|
+
return this.client.get("season/current/teamswithmembers");
|
|
983
|
+
}
|
|
984
|
+
/** `GET season/current/icon` */
|
|
985
|
+
async getCurrentSeasonIcon() {
|
|
986
|
+
return this.client.get("season/current/icon");
|
|
987
|
+
}
|
|
988
|
+
/** `PUT season/current/icon` */
|
|
989
|
+
async setCurrentSeasonIcon() {
|
|
990
|
+
return this.client.put("season/current/icon");
|
|
991
|
+
}
|
|
992
|
+
/** `GET season` */
|
|
993
|
+
async getAllSeasons() {
|
|
994
|
+
return this.client.get("season");
|
|
995
|
+
}
|
|
996
|
+
/** `GET season/{seasonId}` */
|
|
997
|
+
async getSeasonById(seasonId) {
|
|
998
|
+
return this.client.get(`season/${seasonId}`);
|
|
999
|
+
}
|
|
1000
|
+
/** `GET season/{seasonId}/matches` */
|
|
1001
|
+
async getMatchesInSeason(seasonId) {
|
|
1002
|
+
return this.client.get(`season/${seasonId}/matches`);
|
|
1003
|
+
}
|
|
1004
|
+
/** `GET season/{seasonId}/matches/count` */
|
|
1005
|
+
async getMatchesInSeasonCount(seasonId) {
|
|
1006
|
+
return this.client.get(`season/${seasonId}/matches/count`);
|
|
1007
|
+
}
|
|
1008
|
+
/** `GET season/{seasonId}/matches/day/{day}` */
|
|
1009
|
+
async getMatchesInSeasonOnDay(seasonId, day) {
|
|
1010
|
+
return this.client.get(`season/${seasonId}/matches/day/${day}`);
|
|
1011
|
+
}
|
|
1012
|
+
/** `GET season/{seasonId}/teams` */
|
|
1013
|
+
async getTeamsInSeason(seasonId) {
|
|
1014
|
+
return this.client.get(`season/${seasonId}/teams`);
|
|
1015
|
+
}
|
|
1016
|
+
/** `GET season/{seasonId}/teamswithmembers` */
|
|
1017
|
+
async getTeamsWithMembersInSeason(seasonId) {
|
|
1018
|
+
return this.client.get(`season/${seasonId}/teamswithmembers`);
|
|
1019
|
+
}
|
|
1020
|
+
/** `POST season` */
|
|
1021
|
+
async createOrUpdateSeason(seasonData) {
|
|
1022
|
+
return this.client.post("season", seasonData);
|
|
1023
|
+
}
|
|
1024
|
+
/** `GET season/{seasonId}/icon` */
|
|
1025
|
+
async getSeasonIcon(seasonId) {
|
|
1026
|
+
return this.client.get(`season/${seasonId}/icon`);
|
|
1027
|
+
}
|
|
1028
|
+
/** `PUT season/{seasonId}/icon` */
|
|
1029
|
+
async setSeasonIcon(seasonId) {
|
|
1030
|
+
return this.client.put(`season/${seasonId}/icon`);
|
|
1031
|
+
}
|
|
1032
|
+
/** `DELETE season/{seasonId}` */
|
|
1033
|
+
async deleteSeason(seasonId) {
|
|
1034
|
+
return this.client.delete(`season/${seasonId}`);
|
|
1035
|
+
}
|
|
1036
|
+
};
|
|
1037
|
+
|
|
1038
|
+
// src/api/generated/IngameApi.ts
|
|
1039
|
+
var IngameApi = class {
|
|
1040
|
+
constructor(client) {
|
|
1041
|
+
this.client = client;
|
|
1042
|
+
}
|
|
1043
|
+
/** `GET ingame/status` */
|
|
1044
|
+
async getGameState() {
|
|
1045
|
+
return this.client.get("ingame/status");
|
|
1046
|
+
}
|
|
1047
|
+
/** `POST ingame/enable` */
|
|
1048
|
+
async enableComponent() {
|
|
1049
|
+
return this.client.post("ingame/enable");
|
|
1050
|
+
}
|
|
1051
|
+
/** `POST ingame/disable` */
|
|
1052
|
+
async disableComponent() {
|
|
1053
|
+
return this.client.post("ingame/disable");
|
|
1054
|
+
}
|
|
1055
|
+
/** `POST ingame/mock/{doMocking}` */
|
|
1056
|
+
async mockIngame(doMocking) {
|
|
1057
|
+
return this.client.post(`ingame/mock/${doMocking}`);
|
|
1058
|
+
}
|
|
1059
|
+
/** `GET ingame/mock` */
|
|
1060
|
+
async getMockingStatus() {
|
|
1061
|
+
return this.client.get("ingame/mock");
|
|
1062
|
+
}
|
|
1063
|
+
/** `GET ingame/frontend` */
|
|
1064
|
+
async getFrontendUrl() {
|
|
1065
|
+
return this.client.get("ingame/frontend");
|
|
1066
|
+
}
|
|
1067
|
+
/** `GET ingame/showing` */
|
|
1068
|
+
async getCurrentCommonSerializationOptions() {
|
|
1069
|
+
return this.client.get("ingame/showing");
|
|
1070
|
+
}
|
|
1071
|
+
/** `POST ingame/showing` */
|
|
1072
|
+
async setCurrentCommonSerializationOptions(data) {
|
|
1073
|
+
return this.client.post("ingame/showing", data);
|
|
1074
|
+
}
|
|
1075
|
+
/** `GET ingame/showing/{socketid}` */
|
|
1076
|
+
async getCurrentFrontendSerializationOptions(socketid) {
|
|
1077
|
+
return this.client.get(`ingame/showing/${socketid}`);
|
|
1078
|
+
}
|
|
1079
|
+
/** `POST ingame/showing/{socketid}` */
|
|
1080
|
+
async setCurrentFrontendSerializationOptions(socketid, data) {
|
|
1081
|
+
return this.client.post(`ingame/showing/${socketid}`, data);
|
|
1082
|
+
}
|
|
1083
|
+
/** `GET ingame/stage/{stageSide}/{playerSlot}/networkId` */
|
|
1084
|
+
async getPlayerPUUIDInSlot(stageSide, playerSlot) {
|
|
1085
|
+
return this.client.get(`ingame/stage/${stageSide}/${playerSlot}/networkId`);
|
|
1086
|
+
}
|
|
1087
|
+
/** `GET ingame/stage/{stageSide}/ingameteamid` */
|
|
1088
|
+
async getIngameTeamOnStageSide(stageSide) {
|
|
1089
|
+
return this.client.get(`ingame/stage/${stageSide}/ingameteamid`);
|
|
1090
|
+
}
|
|
1091
|
+
/** `GET ingame/state/activeOverlays` */
|
|
1092
|
+
async getActiveOverlays() {
|
|
1093
|
+
return this.client.get("ingame/state/activeOverlays");
|
|
1094
|
+
}
|
|
1095
|
+
};
|
|
1096
|
+
|
|
1097
|
+
// src/api/RestApi.ts
|
|
1098
|
+
var RestApi = class {
|
|
1099
|
+
constructor(baseUrl) {
|
|
1100
|
+
this.client = new ApiClient(baseUrl);
|
|
1101
|
+
this.ingame = new IngameApi(this.client);
|
|
1102
|
+
this.game = new GameApi(this.client);
|
|
1103
|
+
this.match = new MatchApi(this.client);
|
|
1104
|
+
this.season = new SeasonApi(this.client);
|
|
1105
|
+
this.preGame = new PreGameApi(this.client);
|
|
1106
|
+
this.gameState = new GameStateApi(this.client);
|
|
1107
|
+
}
|
|
1108
|
+
/**
|
|
1109
|
+
* Update the base URL for all API modules (e.g. after changing host/port).
|
|
1110
|
+
*/
|
|
1111
|
+
updateBaseUrl(baseUrl) {
|
|
1112
|
+
this.client.updateBaseUrl(baseUrl);
|
|
1113
|
+
}
|
|
1114
|
+
/**
|
|
1115
|
+
* Get direct access to the underlying HTTP client for custom requests.
|
|
1116
|
+
*/
|
|
1117
|
+
getHttpClient() {
|
|
1118
|
+
return this.client;
|
|
398
1119
|
}
|
|
399
1120
|
};
|
|
400
1121
|
|
|
@@ -402,152 +1123,247 @@ var ingameFrontendData = class {
|
|
|
402
1123
|
var LeagueBroadcastClient = class {
|
|
403
1124
|
constructor(config) {
|
|
404
1125
|
this.gameState = 0 /* OutOfGame */;
|
|
405
|
-
this.
|
|
406
|
-
|
|
1126
|
+
this._isTestingEnvironment = false;
|
|
1127
|
+
this.champSelectWasActive = false;
|
|
1128
|
+
// -- In-game event handlers -------------------------------------------------
|
|
407
1129
|
this.stateUpdateHandlers = /* @__PURE__ */ new Set();
|
|
408
1130
|
this.gameStatusHandlers = /* @__PURE__ */ new Set();
|
|
409
|
-
this.
|
|
1131
|
+
this.ingameEventHandlers = {};
|
|
1132
|
+
// -- Pre-game event handlers ------------------------------------------------
|
|
1133
|
+
this.champSelectUpdateHandlers = /* @__PURE__ */ new Set();
|
|
1134
|
+
this.champSelectEventHandlers = {};
|
|
410
1135
|
this.config = {
|
|
411
1136
|
host: config.host,
|
|
412
1137
|
port: config.port ?? 58869,
|
|
413
|
-
|
|
1138
|
+
ingameWsRoute: config.ingameWsRoute ?? "/ws/in",
|
|
1139
|
+
preGameWsRoute: config.preGameWsRoute ?? "/ws/pre",
|
|
414
1140
|
apiRoute: config.apiRoute ?? "/api",
|
|
415
1141
|
cacheRoute: config.cacheRoute ?? "/cache",
|
|
416
1142
|
useHttps: config.useHttps ?? false,
|
|
417
1143
|
autoConnect: config.autoConnect ?? true
|
|
418
1144
|
};
|
|
419
|
-
this.
|
|
1145
|
+
const httpProtocol = this.config.useHttps ? "https" : "http";
|
|
1146
|
+
const apiBaseUrl = `${httpProtocol}://${this.config.host}:${this.config.port}${this.config.apiRoute}`;
|
|
1147
|
+
this.api = new RestApi(apiBaseUrl);
|
|
1148
|
+
this.ingameWs = new WebSocketManager();
|
|
420
1149
|
this.gameData = new ingameFrontendData();
|
|
421
|
-
this.
|
|
422
|
-
this.
|
|
1150
|
+
this.ingameStore = new GameStateStore(this.gameData, this.gameState);
|
|
1151
|
+
this.setupIngameMessageHandler();
|
|
1152
|
+
this.preGameWs = new WebSocketManager();
|
|
1153
|
+
this.champSelectData = new champSelectStateData();
|
|
1154
|
+
this.preGameStore = new ChampSelectStateStore(this.champSelectData);
|
|
1155
|
+
this.setupPreGameMessageHandler();
|
|
423
1156
|
if (this.config.autoConnect) {
|
|
424
1157
|
this.connect();
|
|
425
1158
|
}
|
|
426
1159
|
}
|
|
1160
|
+
// ===========================================================================
|
|
1161
|
+
// Connection management
|
|
1162
|
+
// ===========================================================================
|
|
427
1163
|
/**
|
|
428
|
-
* Connect to
|
|
1164
|
+
* Connect to both in-game and pre-game WebSocket endpoints.
|
|
1165
|
+
*
|
|
1166
|
+
* Both connections are attempted in parallel. If either fails the returned
|
|
1167
|
+
* promise rejects, but the other connection may still succeed.
|
|
429
1168
|
*/
|
|
430
1169
|
async connect() {
|
|
431
1170
|
const protocol = this.config.useHttps ? "wss" : "ws";
|
|
432
|
-
const
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
1171
|
+
const base = `${protocol}://${this.config.host}:${this.config.port}`;
|
|
1172
|
+
const ingameUrl = `${base}${this.config.ingameWsRoute}`;
|
|
1173
|
+
const preGameUrl = `${base}${this.config.preGameWsRoute}`;
|
|
1174
|
+
const results = await Promise.allSettled([
|
|
1175
|
+
this.ingameWs.connect(ingameUrl),
|
|
1176
|
+
this.preGameWs.connect(preGameUrl)
|
|
1177
|
+
]);
|
|
1178
|
+
const failures = results.filter((r) => r.status === "rejected");
|
|
1179
|
+
if (failures.length > 0) {
|
|
1180
|
+
const reasons = failures.map(
|
|
1181
|
+
(r) => r.reason
|
|
1182
|
+
);
|
|
1183
|
+
console.error(
|
|
1184
|
+
"[LeagueBroadcastClient] One or more connections failed:",
|
|
1185
|
+
reasons
|
|
1186
|
+
);
|
|
1187
|
+
throw reasons[0];
|
|
438
1188
|
}
|
|
439
1189
|
}
|
|
440
1190
|
/**
|
|
441
|
-
* Disconnect from
|
|
1191
|
+
* Disconnect from both WebSocket endpoints.
|
|
442
1192
|
*/
|
|
443
1193
|
disconnect() {
|
|
444
|
-
this.
|
|
1194
|
+
this.ingameWs.disconnect();
|
|
1195
|
+
this.preGameWs.disconnect();
|
|
445
1196
|
}
|
|
446
1197
|
/**
|
|
447
|
-
*
|
|
1198
|
+
* Whether the in-game WebSocket is connected.
|
|
448
1199
|
*/
|
|
449
|
-
|
|
450
|
-
return this.
|
|
1200
|
+
isIngameConnected() {
|
|
1201
|
+
return this.ingameWs.isConnected();
|
|
451
1202
|
}
|
|
452
1203
|
/**
|
|
453
|
-
*
|
|
1204
|
+
* Whether the pre-game WebSocket is connected.
|
|
454
1205
|
*/
|
|
455
|
-
|
|
1206
|
+
isPreGameConnected() {
|
|
1207
|
+
return this.preGameWs.isConnected();
|
|
1208
|
+
}
|
|
1209
|
+
// ===========================================================================
|
|
1210
|
+
// In-game data access
|
|
1211
|
+
// ===========================================================================
|
|
1212
|
+
/** Get the current in-game data. */
|
|
1213
|
+
getIngameData() {
|
|
456
1214
|
return this.gameData;
|
|
457
1215
|
}
|
|
458
|
-
/**
|
|
459
|
-
|
|
460
|
-
*/
|
|
461
|
-
getGameState() {
|
|
1216
|
+
/** Get the current game state. */
|
|
1217
|
+
getIngameState() {
|
|
462
1218
|
return this.gameState;
|
|
463
1219
|
}
|
|
464
|
-
/**
|
|
465
|
-
* Check if in testing environment
|
|
466
|
-
*/
|
|
1220
|
+
/** Whether the backend is in a testing / replay environment. */
|
|
467
1221
|
isInTestingEnvironment() {
|
|
468
|
-
return this.
|
|
1222
|
+
return this._isTestingEnvironment;
|
|
469
1223
|
}
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
1224
|
+
// ===========================================================================
|
|
1225
|
+
// Pre-game data access
|
|
1226
|
+
// ===========================================================================
|
|
1227
|
+
/** Get the current champion-select state. */
|
|
1228
|
+
getChampSelectData() {
|
|
1229
|
+
return this.champSelectData;
|
|
1230
|
+
}
|
|
1231
|
+
/** Whether champion select is currently active. */
|
|
1232
|
+
isChampSelectActive() {
|
|
1233
|
+
return this.champSelectData.isActive;
|
|
1234
|
+
}
|
|
1235
|
+
// ===========================================================================
|
|
1236
|
+
// In-game event handlers
|
|
1237
|
+
// ===========================================================================
|
|
1238
|
+
/** Register a handler for in-game state updates. */
|
|
1239
|
+
onIngameStateUpdate(handler) {
|
|
474
1240
|
this.stateUpdateHandlers.add(handler);
|
|
475
1241
|
return () => this.stateUpdateHandlers.delete(handler);
|
|
476
1242
|
}
|
|
477
|
-
/**
|
|
478
|
-
|
|
479
|
-
*/
|
|
480
|
-
onGameStatusChange(handler) {
|
|
1243
|
+
/** Register a handler for in-game status changes (running, paused, out of game). */
|
|
1244
|
+
onIngameStatusChange(handler) {
|
|
481
1245
|
this.gameStatusHandlers.add(handler);
|
|
482
1246
|
return () => this.gameStatusHandlers.delete(handler);
|
|
483
1247
|
}
|
|
484
|
-
/**
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
onGameEvents(handlers) {
|
|
488
|
-
this.eventHandlers = { ...this.eventHandlers, ...handlers };
|
|
1248
|
+
/** Register handlers for in-game events (kills, objectives, etc.). */
|
|
1249
|
+
onIngameEvents(handlers) {
|
|
1250
|
+
this.ingameEventHandlers = { ...this.ingameEventHandlers, ...handlers };
|
|
489
1251
|
}
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
1252
|
+
// ===========================================================================
|
|
1253
|
+
// Pre-game event handlers
|
|
1254
|
+
// ===========================================================================
|
|
1255
|
+
/** Register a handler for champ-select state updates. */
|
|
1256
|
+
onChampSelectUpdate(handler) {
|
|
1257
|
+
this.champSelectUpdateHandlers.add(handler);
|
|
1258
|
+
return () => this.champSelectUpdateHandlers.delete(handler);
|
|
495
1259
|
}
|
|
496
|
-
/**
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
1260
|
+
/** Register handlers for champ-select lifecycle and action events. */
|
|
1261
|
+
onChampSelectEvents(handlers) {
|
|
1262
|
+
this.champSelectEventHandlers = {
|
|
1263
|
+
...this.champSelectEventHandlers,
|
|
1264
|
+
...handlers
|
|
1265
|
+
};
|
|
501
1266
|
}
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
1267
|
+
// ===========================================================================
|
|
1268
|
+
// Connection event handlers
|
|
1269
|
+
// ===========================================================================
|
|
1270
|
+
/** Register a handler for in-game connection. */
|
|
1271
|
+
onIngameConnect(handler) {
|
|
1272
|
+
return this.ingameWs.onConnect(handler);
|
|
507
1273
|
}
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
1274
|
+
/** Register a handler for in-game disconnection. */
|
|
1275
|
+
onIngameDisconnect(handler) {
|
|
1276
|
+
return this.ingameWs.onDisconnect(handler);
|
|
1277
|
+
}
|
|
1278
|
+
/** Register a handler for in-game connection errors. */
|
|
1279
|
+
onIngameError(handler) {
|
|
1280
|
+
return this.ingameWs.onError(handler);
|
|
1281
|
+
}
|
|
1282
|
+
/** Register a handler for pre-game connection. */
|
|
1283
|
+
onPreGameConnect(handler) {
|
|
1284
|
+
return this.preGameWs.onConnect(handler);
|
|
1285
|
+
}
|
|
1286
|
+
/** Register a handler for pre-game disconnection. */
|
|
1287
|
+
onPreGameDisconnect(handler) {
|
|
1288
|
+
return this.preGameWs.onDisconnect(handler);
|
|
1289
|
+
}
|
|
1290
|
+
/** Register a handler for pre-game connection errors. */
|
|
1291
|
+
onPreGameError(handler) {
|
|
1292
|
+
return this.preGameWs.onError(handler);
|
|
1293
|
+
}
|
|
1294
|
+
// ===========================================================================
|
|
1295
|
+
// Reactive API — in-game (convenience wrappers around this.store)
|
|
1296
|
+
// ===========================================================================
|
|
511
1297
|
/**
|
|
512
|
-
* Create a subscribable slice of game state.
|
|
1298
|
+
* Create a subscribable slice of **in-game** state.
|
|
513
1299
|
* The slice only notifies listeners when the selected value actually changes.
|
|
514
1300
|
*
|
|
515
1301
|
* Works directly with React 18+ `useSyncExternalStore`:
|
|
516
1302
|
* ```tsx
|
|
517
|
-
* const kills = client.
|
|
1303
|
+
* const kills = client.selectIngame(s => s.gameData.scoreboard?.teams[0]?.kills);
|
|
518
1304
|
* function Kills() {
|
|
519
1305
|
* const value = useSyncExternalStore(kills.subscribe, kills.getSnapshot);
|
|
520
1306
|
* return <span>{value}</span>;
|
|
521
1307
|
* }
|
|
522
1308
|
* ```
|
|
523
1309
|
*/
|
|
524
|
-
|
|
525
|
-
return this.
|
|
1310
|
+
selectIngame(selector, equalityFn) {
|
|
1311
|
+
return this.ingameStore.select(selector, equalityFn);
|
|
526
1312
|
}
|
|
527
1313
|
/**
|
|
528
|
-
* Watch a derived value and invoke `callback` whenever it changes.
|
|
1314
|
+
* Watch a derived **in-game** value and invoke `callback` whenever it changes.
|
|
529
1315
|
* Returns an unsubscribe function.
|
|
530
1316
|
*
|
|
531
1317
|
* ```ts
|
|
532
|
-
* client.
|
|
1318
|
+
* client.watchIngame(
|
|
533
1319
|
* s => s.gameData.scoreboard?.teams[0]?.kills,
|
|
534
1320
|
* (kills, prev) => console.log(`Kills: ${prev} → ${kills}`),
|
|
535
1321
|
* );
|
|
536
1322
|
* ```
|
|
537
1323
|
*/
|
|
538
|
-
|
|
539
|
-
return this.
|
|
1324
|
+
watchIngame(selector, callback, equalityFn) {
|
|
1325
|
+
return this.ingameStore.watch(selector, callback, equalityFn);
|
|
540
1326
|
}
|
|
1327
|
+
// ===========================================================================
|
|
1328
|
+
// Reactive API — pre-game (convenience wrappers around this.preGameStore)
|
|
1329
|
+
// ===========================================================================
|
|
541
1330
|
/**
|
|
542
|
-
*
|
|
1331
|
+
* Create a subscribable slice of **pre-game** (champion select) state.
|
|
1332
|
+
*
|
|
1333
|
+
* ```tsx
|
|
1334
|
+
* const timer = client.selectChampSelect(s => s.champSelectData.timer);
|
|
1335
|
+
* function DraftTimer() {
|
|
1336
|
+
* const value = useSyncExternalStore(timer.subscribe, timer.getSnapshot);
|
|
1337
|
+
* return <span>{value?.timeRemaining}</span>;
|
|
1338
|
+
* }
|
|
1339
|
+
* ```
|
|
1340
|
+
*/
|
|
1341
|
+
selectChampSelect(selector, equalityFn) {
|
|
1342
|
+
return this.preGameStore.select(selector, equalityFn);
|
|
1343
|
+
}
|
|
1344
|
+
/**
|
|
1345
|
+
* Watch a derived **pre-game** value and invoke `callback` whenever it
|
|
1346
|
+
* changes. Returns an unsubscribe function.
|
|
1347
|
+
*
|
|
1348
|
+
* ```ts
|
|
1349
|
+
* client.watchChampSelect(
|
|
1350
|
+
* s => s.champSelectData.timer.timeRemaining,
|
|
1351
|
+
* (remaining, prev) => console.log(`Time: ${prev} → ${remaining}`),
|
|
1352
|
+
* );
|
|
1353
|
+
* ```
|
|
543
1354
|
*/
|
|
1355
|
+
watchChampSelect(selector, callback, equalityFn) {
|
|
1356
|
+
return this.preGameStore.watch(selector, callback, equalityFn);
|
|
1357
|
+
}
|
|
1358
|
+
// ===========================================================================
|
|
1359
|
+
// URLs
|
|
1360
|
+
// ===========================================================================
|
|
1361
|
+
/** Get the base HTTP URL for API requests. */
|
|
544
1362
|
getApiUrl() {
|
|
545
1363
|
const protocol = this.config.useHttps ? "https" : "http";
|
|
546
1364
|
return `${protocol}://${this.config.host}:${this.config.port}${this.config.apiRoute}`;
|
|
547
1365
|
}
|
|
548
|
-
/**
|
|
549
|
-
* Get the base URL for cache requests
|
|
550
|
-
*/
|
|
1366
|
+
/** Get the base URL for cache requests (optionally resolve a path). */
|
|
551
1367
|
getCacheUrl(path) {
|
|
552
1368
|
const protocol = this.config.useHttps ? "https" : "http";
|
|
553
1369
|
const baseUrl = `${protocol}://${this.config.host}:${this.config.port}${this.config.cacheRoute}`;
|
|
@@ -569,11 +1385,11 @@ var LeagueBroadcastClient = class {
|
|
|
569
1385
|
}
|
|
570
1386
|
return `${baseUrl}/${cleanPath}`;
|
|
571
1387
|
}
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
this.
|
|
1388
|
+
// ===========================================================================
|
|
1389
|
+
// Private — in-game message handling
|
|
1390
|
+
// ===========================================================================
|
|
1391
|
+
setupIngameMessageHandler() {
|
|
1392
|
+
this.ingameWs.onMessage((messageData) => {
|
|
577
1393
|
switch (messageData.type) {
|
|
578
1394
|
case "ingame-state-update":
|
|
579
1395
|
this.handleStateUpdate(messageData.state, messageData.events);
|
|
@@ -587,84 +1403,210 @@ var LeagueBroadcastClient = class {
|
|
|
587
1403
|
}
|
|
588
1404
|
});
|
|
589
1405
|
}
|
|
590
|
-
/**
|
|
591
|
-
* Handle state update from backend
|
|
592
|
-
*/
|
|
593
1406
|
handleStateUpdate(state, events) {
|
|
594
|
-
const nextData =
|
|
1407
|
+
const nextData = {
|
|
1408
|
+
gameTime: 0,
|
|
1409
|
+
playbackSpeed: 0,
|
|
1410
|
+
gameVersion: "",
|
|
1411
|
+
gameStatus: 0 /* OutOfGame */,
|
|
1412
|
+
...state
|
|
1413
|
+
};
|
|
595
1414
|
this.gameData = structuralShare(this.gameData, nextData);
|
|
596
1415
|
if (!state.gameTime || state.gameTime === 0) {
|
|
597
1416
|
this.handleGameStatusUpdate(0 /* OutOfGame */, false);
|
|
598
1417
|
}
|
|
599
|
-
this.
|
|
1418
|
+
this.ingameStore._setGameData(this.gameData);
|
|
600
1419
|
this.stateUpdateHandlers.forEach((handler) => handler(this.gameData));
|
|
601
1420
|
this.handleGameEvents(events);
|
|
602
1421
|
}
|
|
603
|
-
/**
|
|
604
|
-
* Handle game status update
|
|
605
|
-
*/
|
|
606
1422
|
handleGameStatusUpdate(gameStatus, isTestingEnvironment = false) {
|
|
607
|
-
this.
|
|
1423
|
+
this._isTestingEnvironment = isTestingEnvironment;
|
|
608
1424
|
if (gameStatus === 0 /* OutOfGame */ && this.gameState !== 0 /* OutOfGame */) {
|
|
609
1425
|
this.endGame();
|
|
610
1426
|
return;
|
|
611
1427
|
}
|
|
612
1428
|
this.gameState = gameStatus;
|
|
613
|
-
this.
|
|
1429
|
+
this.ingameStore._setGameState(gameStatus);
|
|
614
1430
|
this.gameStatusHandlers.forEach(
|
|
615
1431
|
(handler) => handler(gameStatus, isTestingEnvironment)
|
|
616
1432
|
);
|
|
617
1433
|
}
|
|
618
|
-
/**
|
|
619
|
-
* Handle game events
|
|
620
|
-
*/
|
|
621
1434
|
handleGameEvents(events) {
|
|
622
|
-
if (!events)
|
|
623
|
-
|
|
624
|
-
}
|
|
625
|
-
if (events.player && this.eventHandlers.onPlayerEvent) {
|
|
1435
|
+
if (!events) return;
|
|
1436
|
+
if (events.player && this.ingameEventHandlers.onPlayerEvent) {
|
|
626
1437
|
events.player.forEach(
|
|
627
|
-
(event) => this.
|
|
1438
|
+
(event) => this.ingameEventHandlers.onPlayerEvent(event)
|
|
628
1439
|
);
|
|
629
1440
|
}
|
|
630
|
-
if (events.team && this.
|
|
631
|
-
events.team.forEach(
|
|
1441
|
+
if (events.team && this.ingameEventHandlers.onTeamEvent) {
|
|
1442
|
+
events.team.forEach(
|
|
1443
|
+
(event) => this.ingameEventHandlers.onTeamEvent(event)
|
|
1444
|
+
);
|
|
632
1445
|
}
|
|
633
|
-
if (events.objective && this.
|
|
1446
|
+
if (events.objective && this.ingameEventHandlers.onObjectiveEvent) {
|
|
634
1447
|
events.objective.forEach(
|
|
635
|
-
(event) => this.
|
|
1448
|
+
(event) => this.ingameEventHandlers.onObjectiveEvent(event)
|
|
636
1449
|
);
|
|
637
1450
|
}
|
|
638
|
-
if (events.firstTower !== void 0 && this.
|
|
639
|
-
this.
|
|
1451
|
+
if (events.firstTower !== void 0 && this.ingameEventHandlers.onFirstTowerEvent) {
|
|
1452
|
+
this.ingameEventHandlers.onFirstTowerEvent(events.firstTower);
|
|
640
1453
|
}
|
|
641
|
-
if (events.announcements && this.
|
|
1454
|
+
if (events.announcements && this.ingameEventHandlers.onAnnouncementEvent) {
|
|
642
1455
|
events.announcements.forEach(
|
|
643
|
-
(event) => this.
|
|
1456
|
+
(event) => this.ingameEventHandlers.onAnnouncementEvent(event)
|
|
644
1457
|
);
|
|
645
1458
|
}
|
|
646
|
-
if (events.killFeed && this.
|
|
1459
|
+
if (events.killFeed && this.ingameEventHandlers.onKillFeedEvent) {
|
|
647
1460
|
events.killFeed.forEach(
|
|
648
|
-
(event) => this.
|
|
1461
|
+
(event) => this.ingameEventHandlers.onKillFeedEvent(event)
|
|
649
1462
|
);
|
|
650
1463
|
}
|
|
651
1464
|
}
|
|
652
|
-
/**
|
|
653
|
-
* End the game and reset state
|
|
654
|
-
*/
|
|
655
1465
|
endGame() {
|
|
656
1466
|
console.log("[LeagueBroadcastClient] Game ended, resetting data");
|
|
657
1467
|
this.gameData = new ingameFrontendData();
|
|
658
1468
|
this.gameState = 0 /* OutOfGame */;
|
|
659
|
-
this.
|
|
660
|
-
this.
|
|
1469
|
+
this._isTestingEnvironment = false;
|
|
1470
|
+
this.ingameStore._reset(this.gameData, 0 /* OutOfGame */);
|
|
661
1471
|
this.gameStatusHandlers.forEach(
|
|
662
1472
|
(handler) => handler(0 /* OutOfGame */, false)
|
|
663
1473
|
);
|
|
664
1474
|
this.stateUpdateHandlers.forEach((handler) => handler(this.gameData));
|
|
665
1475
|
}
|
|
1476
|
+
// ===========================================================================
|
|
1477
|
+
// Private — pre-game message handling
|
|
1478
|
+
// ===========================================================================
|
|
1479
|
+
setupPreGameMessageHandler() {
|
|
1480
|
+
this.preGameWs.onMessage((messageData) => {
|
|
1481
|
+
switch (messageData.type) {
|
|
1482
|
+
case "champion-select-state-update":
|
|
1483
|
+
this.handleChampSelectStateUpdate(messageData.state);
|
|
1484
|
+
break;
|
|
1485
|
+
case "champion-select-action":
|
|
1486
|
+
this.handleChampSelectAction(messageData.action);
|
|
1487
|
+
break;
|
|
1488
|
+
case "frontend-route-update":
|
|
1489
|
+
this.handleRouteUpdate(messageData.uri);
|
|
1490
|
+
break;
|
|
1491
|
+
}
|
|
1492
|
+
});
|
|
1493
|
+
}
|
|
1494
|
+
handleChampSelectStateUpdate(state) {
|
|
1495
|
+
const nextData = {
|
|
1496
|
+
isActive: false,
|
|
1497
|
+
isConnected: false,
|
|
1498
|
+
isTestingEnvironment: false,
|
|
1499
|
+
blueTeam: {},
|
|
1500
|
+
redTeam: {},
|
|
1501
|
+
metaData: {},
|
|
1502
|
+
timer: {},
|
|
1503
|
+
...state
|
|
1504
|
+
};
|
|
1505
|
+
this.champSelectData = structuralShare(this.champSelectData, nextData);
|
|
1506
|
+
if (nextData.isActive && !this.champSelectWasActive) {
|
|
1507
|
+
this.champSelectWasActive = true;
|
|
1508
|
+
this.champSelectEventHandlers.onChampSelectStart?.();
|
|
1509
|
+
} else if (!nextData.isActive && this.champSelectWasActive) {
|
|
1510
|
+
this.champSelectWasActive = false;
|
|
1511
|
+
this.endChampSelect();
|
|
1512
|
+
return;
|
|
1513
|
+
}
|
|
1514
|
+
this.preGameStore._setChampSelectData(this.champSelectData);
|
|
1515
|
+
this.champSelectUpdateHandlers.forEach(
|
|
1516
|
+
(handler) => handler(this.champSelectData)
|
|
1517
|
+
);
|
|
1518
|
+
}
|
|
1519
|
+
handleChampSelectAction(action) {
|
|
1520
|
+
this.champSelectEventHandlers.onAction?.(action);
|
|
1521
|
+
}
|
|
1522
|
+
handleRouteUpdate(uri) {
|
|
1523
|
+
this.champSelectEventHandlers.onRouteUpdate?.(uri);
|
|
1524
|
+
}
|
|
1525
|
+
endChampSelect() {
|
|
1526
|
+
console.log("[LeagueBroadcastClient] Champ select ended, resetting data");
|
|
1527
|
+
this.champSelectData = new champSelectStateData();
|
|
1528
|
+
this.preGameStore._reset(this.champSelectData);
|
|
1529
|
+
this.champSelectEventHandlers.onChampSelectEnd?.();
|
|
1530
|
+
this.champSelectUpdateHandlers.forEach(
|
|
1531
|
+
(handler) => handler(this.champSelectData)
|
|
1532
|
+
);
|
|
1533
|
+
}
|
|
666
1534
|
};
|
|
667
1535
|
|
|
668
|
-
|
|
1536
|
+
// types/pregame/pickbanphase.ts
|
|
1537
|
+
var PickBanPhase = /* @__PURE__ */ ((PickBanPhase2) => {
|
|
1538
|
+
PickBanPhase2[PickBanPhase2["BEGIN"] = 0] = "BEGIN";
|
|
1539
|
+
PickBanPhase2[PickBanPhase2["BAN1"] = 1] = "BAN1";
|
|
1540
|
+
PickBanPhase2[PickBanPhase2["BAN2"] = 2] = "BAN2";
|
|
1541
|
+
PickBanPhase2[PickBanPhase2["PICK1"] = 3] = "PICK1";
|
|
1542
|
+
PickBanPhase2[PickBanPhase2["PICK2"] = 4] = "PICK2";
|
|
1543
|
+
PickBanPhase2[PickBanPhase2["END"] = 5] = "END";
|
|
1544
|
+
PickBanPhase2[PickBanPhase2["WAIT"] = 6] = "WAIT";
|
|
1545
|
+
return PickBanPhase2;
|
|
1546
|
+
})(PickBanPhase || {});
|
|
1547
|
+
|
|
1548
|
+
// types/pregame/actiontype.ts
|
|
1549
|
+
var ActionType = /* @__PURE__ */ ((ActionType2) => {
|
|
1550
|
+
ActionType2[ActionType2["TEN_BANS_REVEAL"] = 0] = "TEN_BANS_REVEAL";
|
|
1551
|
+
ActionType2[ActionType2["PHASE_TRANSITION"] = 1] = "PHASE_TRANSITION";
|
|
1552
|
+
ActionType2[ActionType2["PICK"] = 2] = "PICK";
|
|
1553
|
+
ActionType2[ActionType2["BAN"] = 3] = "BAN";
|
|
1554
|
+
return ActionType2;
|
|
1555
|
+
})(ActionType || {});
|
|
1556
|
+
|
|
1557
|
+
// types/pregame/actionsubtype.ts
|
|
1558
|
+
var ActionSubType = /* @__PURE__ */ ((ActionSubType2) => {
|
|
1559
|
+
ActionSubType2[ActionSubType2["START"] = 0] = "START";
|
|
1560
|
+
ActionSubType2[ActionSubType2["HOVER"] = 1] = "HOVER";
|
|
1561
|
+
ActionSubType2[ActionSubType2["LOCK"] = 2] = "LOCK";
|
|
1562
|
+
return ActionSubType2;
|
|
1563
|
+
})(ActionSubType || {});
|
|
1564
|
+
|
|
1565
|
+
// types/pregame/timelineactiontype.ts
|
|
1566
|
+
var TimeLineActionType = /* @__PURE__ */ ((TimeLineActionType2) => {
|
|
1567
|
+
TimeLineActionType2[TimeLineActionType2["HoverPick"] = 0] = "HoverPick";
|
|
1568
|
+
TimeLineActionType2[TimeLineActionType2["Pick"] = 1] = "Pick";
|
|
1569
|
+
TimeLineActionType2[TimeLineActionType2["Ban"] = 2] = "Ban";
|
|
1570
|
+
return TimeLineActionType2;
|
|
1571
|
+
})(TimeLineActionType || {});
|
|
1572
|
+
|
|
1573
|
+
// types/shared/bestoftype.ts
|
|
1574
|
+
var BestOfType = /* @__PURE__ */ ((BestOfType2) => {
|
|
1575
|
+
BestOfType2[BestOfType2["BestOf1"] = 1] = "BestOf1";
|
|
1576
|
+
BestOfType2[BestOfType2["BestOf2"] = 2] = "BestOf2";
|
|
1577
|
+
BestOfType2[BestOfType2["BestOf3"] = 3] = "BestOf3";
|
|
1578
|
+
BestOfType2[BestOfType2["BestOf5"] = 5] = "BestOf5";
|
|
1579
|
+
BestOfType2[BestOfType2["BestOf7"] = 7] = "BestOf7";
|
|
1580
|
+
return BestOfType2;
|
|
1581
|
+
})(BestOfType || {});
|
|
1582
|
+
|
|
1583
|
+
// types/shared/matchruleset.ts
|
|
1584
|
+
var MatchRuleSet = /* @__PURE__ */ ((MatchRuleSet2) => {
|
|
1585
|
+
MatchRuleSet2[MatchRuleSet2["Standard"] = 0] = "Standard";
|
|
1586
|
+
MatchRuleSet2[MatchRuleSet2["PartialFearless"] = 1] = "PartialFearless";
|
|
1587
|
+
MatchRuleSet2[MatchRuleSet2["Fearless"] = 2] = "Fearless";
|
|
1588
|
+
return MatchRuleSet2;
|
|
1589
|
+
})(MatchRuleSet || {});
|
|
1590
|
+
|
|
1591
|
+
// src/util/ingameScoreboardBottomPlayerDataUtils.ts
|
|
1592
|
+
function getSortedInventory(playerData) {
|
|
1593
|
+
if (!playerData.items) return Array(6).fill({ id: 0 });
|
|
1594
|
+
const items = playerData.items?.filter((item) => item.slot < 6) ?? [];
|
|
1595
|
+
const regularItems = items.sort(
|
|
1596
|
+
(a, b) => (a?.cost ?? 0) - (b?.cost ?? 0)
|
|
1597
|
+
);
|
|
1598
|
+
while (regularItems.length < 6) {
|
|
1599
|
+
regularItems.unshift(void 0);
|
|
1600
|
+
}
|
|
1601
|
+
return regularItems ?? [];
|
|
1602
|
+
}
|
|
1603
|
+
function getTrinket(playerData) {
|
|
1604
|
+
return playerData.items?.find((item) => item.slot === 6);
|
|
1605
|
+
}
|
|
1606
|
+
function getRoleQuest(playerData) {
|
|
1607
|
+
return playerData.items?.find((item) => item.slot === 8);
|
|
1608
|
+
}
|
|
1609
|
+
|
|
1610
|
+
export { ActionSubType, ActionType, ApiClient, ApiError, BestOfType, ChampSelectStateStore, GameApi, GameState, GameStateApi, GameStateStore, IngameApi, LeagueBroadcastClient, MatchApi, MatchRuleSet, PickBanPhase, PreGameApi, RestApi, SeasonApi, TimeLineActionType, WebSocketManager, getRoleQuest, getSortedInventory, getTrinket, shallowEqual };
|
|
669
1611
|
//# sourceMappingURL=index.js.map
|
|
670
1612
|
//# sourceMappingURL=index.js.map
|