@crowdedkingdoms/crowdyjs 18.10.0 → 18.12.0-dev.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/MIGRATION.md +69 -0
  2. package/README.md +91 -30
  3. package/dist/crowdy-client.d.ts +11 -3
  4. package/dist/crowdy-client.d.ts.map +1 -1
  5. package/dist/crowdy-client.js +25 -4
  6. package/dist/default-origin.d.ts +6 -6
  7. package/dist/default-origin.d.ts.map +1 -1
  8. package/dist/default-origin.js +6 -6
  9. package/dist/domains/exec.d.ts +6 -0
  10. package/dist/domains/exec.d.ts.map +1 -1
  11. package/dist/domains/exec.js +28 -2
  12. package/dist/generated/graphql-schema.d.ts +1 -1
  13. package/dist/generated/graphql-schema.d.ts.map +1 -1
  14. package/dist/index.d.ts +3 -3
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +5 -3
  17. package/dist/kit/index.d.ts +22 -2
  18. package/dist/kit/index.d.ts.map +1 -1
  19. package/dist/kit/index.js +22 -2
  20. package/dist/kit/kit.d.ts +141 -7
  21. package/dist/kit/kit.d.ts.map +1 -1
  22. package/dist/kit/kit.js +138 -4
  23. package/dist/kit/mirror.d.ts +111 -0
  24. package/dist/kit/mirror.d.ts.map +1 -0
  25. package/dist/kit/mirror.js +295 -0
  26. package/dist/kit/modules/arenas.d.ts +87 -0
  27. package/dist/kit/modules/arenas.d.ts.map +1 -0
  28. package/dist/kit/modules/arenas.js +66 -0
  29. package/dist/kit/modules/encounters.d.ts +75 -0
  30. package/dist/kit/modules/encounters.d.ts.map +1 -0
  31. package/dist/kit/modules/encounters.js +57 -0
  32. package/dist/kit/modules/instances.d.ts +78 -0
  33. package/dist/kit/modules/instances.d.ts.map +1 -0
  34. package/dist/kit/modules/instances.js +72 -0
  35. package/dist/kit/modules/leaderboards.d.ts +79 -0
  36. package/dist/kit/modules/leaderboards.d.ts.map +1 -0
  37. package/dist/kit/modules/leaderboards.js +69 -0
  38. package/dist/kit/modules/matchmaking.d.ts +107 -0
  39. package/dist/kit/modules/matchmaking.d.ts.map +1 -0
  40. package/dist/kit/modules/matchmaking.js +109 -0
  41. package/dist/kit/modules/minigames.d.ts +59 -0
  42. package/dist/kit/modules/minigames.d.ts.map +1 -0
  43. package/dist/kit/modules/minigames.js +55 -0
  44. package/dist/kit/modules/npcs.d.ts +80 -0
  45. package/dist/kit/modules/npcs.d.ts.map +1 -0
  46. package/dist/kit/modules/npcs.js +102 -0
  47. package/dist/kit/modules/presence.d.ts +81 -0
  48. package/dist/kit/modules/presence.d.ts.map +1 -0
  49. package/dist/kit/modules/presence.js +99 -0
  50. package/dist/kit/modules/racing.d.ts +131 -0
  51. package/dist/kit/modules/racing.d.ts.map +1 -0
  52. package/dist/kit/modules/racing.js +113 -0
  53. package/dist/kit/modules/sessions.d.ts +91 -0
  54. package/dist/kit/modules/sessions.d.ts.map +1 -0
  55. package/dist/kit/modules/sessions.js +84 -0
  56. package/dist/kit/modules/tables.d.ts +76 -0
  57. package/dist/kit/modules/tables.d.ts.map +1 -0
  58. package/dist/kit/modules/tables.js +73 -0
  59. package/dist/kit/modules/tactics.d.ts +79 -0
  60. package/dist/kit/modules/tactics.d.ts.map +1 -0
  61. package/dist/kit/modules/tactics.js +67 -0
  62. package/dist/kit/modules/territory.d.ts +92 -0
  63. package/dist/kit/modules/territory.d.ts.map +1 -0
  64. package/dist/kit/modules/territory.js +84 -0
  65. package/dist/kit/modules/world.d.ts +69 -0
  66. package/dist/kit/modules/world.d.ts.map +1 -0
  67. package/dist/kit/modules/world.js +35 -0
  68. package/dist/kit/protocol.d.ts +128 -0
  69. package/dist/kit/protocol.d.ts.map +1 -0
  70. package/dist/kit/protocol.js +171 -0
  71. package/dist/kit/realtime.d.ts +72 -0
  72. package/dist/kit/realtime.d.ts.map +1 -0
  73. package/dist/kit/realtime.js +108 -0
  74. package/dist/kit/runtime.d.ts +90 -0
  75. package/dist/kit/runtime.d.ts.map +1 -0
  76. package/dist/kit/runtime.js +194 -0
  77. package/dist/kit/store.d.ts +20 -0
  78. package/dist/kit/store.d.ts.map +1 -0
  79. package/dist/kit/store.js +25 -0
  80. package/dist/kit/topology.d.ts +69 -0
  81. package/dist/kit/topology.d.ts.map +1 -0
  82. package/dist/kit/topology.js +156 -0
  83. package/dist/kit/wire.d.ts +45 -5
  84. package/dist/kit/wire.d.ts.map +1 -1
  85. package/dist/kit/wire.js +51 -5
  86. package/dist/live-coding/assets/browser-authoring-index.json +1 -1
  87. package/dist/live-coding/assets/manifest.json +1 -1
  88. package/dist/live-coding/browser-authoring-index.generated.d.ts.map +1 -1
  89. package/dist/live-coding/browser-authoring-index.generated.js +5092 -45
  90. package/package.json +1 -1
@@ -0,0 +1,57 @@
1
+ import { HubState } from '../mirror.js';
2
+ /** Waves, towers and bosses (the `director` starter): {@link encounter} by key. */
3
+ export class EncountersKit {
4
+ constructor(runtime, nodeType = 'director') {
5
+ this.runtime = runtime;
6
+ this.nodeType = nodeType;
7
+ this.encounters = new Map();
8
+ }
9
+ encounter(key) {
10
+ let e = this.encounters.get(key);
11
+ if (!e) {
12
+ e = new Encounter(this.runtime, this.nodeType, key);
13
+ this.encounters.set(key, e);
14
+ }
15
+ return e;
16
+ }
17
+ }
18
+ /**
19
+ * One encounter: waves of enemies down a lane to the players' base, towers the players build (a
20
+ * tower may not cut the lane), strikes on a cooldown, kills that pay gold, and a boss that changes
21
+ * phase as it weakens. {@link view} mirrors the `encounter` topic: snapshots once a second while it
22
+ * runs, and `event` messages (`type`: `wave_started`, `wave_cleared`, `boss_phase`, `won`, `lost`)
23
+ * through `view.onEvent`.
24
+ */
25
+ export class Encounter {
26
+ constructor(runtime, nodeType, key) {
27
+ this.runtime = runtime;
28
+ this.nodeType = nodeType;
29
+ this.key = key;
30
+ this.view = new HubState(runtime, nodeType, key, 'encounter');
31
+ }
32
+ watch() {
33
+ return this.view.start();
34
+ }
35
+ unwatch() {
36
+ return this.view.stop();
37
+ }
38
+ /** @throws {KitError} `full`. */
39
+ join() {
40
+ return this.runtime.call(this.nodeType, this.key, 'join', null, { action: true });
41
+ }
42
+ /** The first to join, or a developer. @throws {KitError} `forbidden`, `started`, `bad_request` (no way to the base). */
43
+ start() {
44
+ return this.runtime.call(this.nodeType, this.key, 'start', null, { action: true });
45
+ }
46
+ /**
47
+ * Builds a tower at `(x, z)`; resolves with the gold left.
48
+ * @throws {KitError} `blocks_lane`, `insufficient` (gold), `conflict` (taken), `bad_request`, `not_member`.
49
+ */
50
+ build(x, z) {
51
+ return this.runtime.call(this.nodeType, this.key, 'build', { x, z }, { action: true });
52
+ }
53
+ /** Strikes enemy `enemy`; resolves with its hp left. @throws {KitError} `cooldown`, `not_found`, `not_member`. */
54
+ hit(enemy) {
55
+ return this.runtime.call(this.nodeType, this.key, 'hit', { enemy }, { action: true });
56
+ }
57
+ }
@@ -0,0 +1,78 @@
1
+ import { HubState } from '../mirror.js';
2
+ import type { KitRuntime } from '../runtime.js';
3
+ export interface InstanceRoom {
4
+ kind: 'fight' | 'treasure' | 'rest' | 'boss';
5
+ /** What a fight here takes. */
6
+ power: number;
7
+ done: boolean;
8
+ }
9
+ export interface InstanceMember {
10
+ player: number;
11
+ hp: number;
12
+ max_hp: number;
13
+ power: number;
14
+ }
15
+ /** What the `run` topic carries. */
16
+ export interface InstanceRunView {
17
+ phase: 'unopened' | 'running' | 'cleared' | 'wiped' | 'abandoned' | 'expired';
18
+ owner: number | null;
19
+ /** The run's seed: the same seed lays out the same floors. */
20
+ seed: number;
21
+ floor: number;
22
+ floors: number;
23
+ /** The room the party is at on this floor. */
24
+ room: number;
25
+ rooms: InstanceRoom[];
26
+ members: InstanceMember[];
27
+ invited: number[];
28
+ gold: number;
29
+ relics: string[];
30
+ /** The grid reserved for the run, when the hub's config has a volume. */
31
+ grid: number | null;
32
+ log: string[];
33
+ }
34
+ /** Private runs for one party (the `instance` starter): {@link run} by key. */
35
+ export declare class InstancesKit {
36
+ private readonly runtime;
37
+ private readonly nodeType;
38
+ private readonly runs;
39
+ constructor(runtime: KitRuntime, nodeType?: string);
40
+ /** The run with key `key` (a key the game makes up, one per run). */
41
+ run(key: string): InstanceRun;
42
+ }
43
+ /**
44
+ * One run: a party plays down floors the hub generates from the run's seed, the hub resolves each
45
+ * room, a party with nobody standing is wiped (permadeath), and a run nobody touches expires. A
46
+ * cleared or wiped run posts each member's depth to a leaderboard when the hub's config names one.
47
+ */
48
+ export declare class InstanceRun {
49
+ private readonly runtime;
50
+ readonly nodeType: string;
51
+ readonly key: string;
52
+ readonly view: HubState<InstanceRunView>;
53
+ constructor(runtime: KitRuntime, nodeType: string, key: string);
54
+ watch(): Promise<InstanceRunView>;
55
+ unwatch(): Promise<void>;
56
+ /**
57
+ * Opens the run as its owner (a developer kit opens one for `party`); resolves with its seed.
58
+ * @throws {KitError} `started`, `bad_request` (party size), `conflict` (its grid could not be reserved).
59
+ */
60
+ open(options?: {
61
+ seed?: number;
62
+ party?: ReadonlyArray<number | string>;
63
+ }): Promise<number>;
64
+ /** The owner invites a player. @throws {KitError} `forbidden`, `full`. */
65
+ invite(player: number | string): Promise<boolean>;
66
+ /** An invited player joins. @throws {KitError} `forbidden`. */
67
+ join(): Promise<boolean>;
68
+ /**
69
+ * Resolves the room the party is at; resolves with what happened, as the log has it.
70
+ * @throws {KitError} `not_member`, `forbidden` (the caller is down), `conflict` (descend first), `finished`.
71
+ */
72
+ enter(): Promise<string>;
73
+ /** The owner leads the party to the next floor; resolves with it. @throws {KitError} `not_ready` (rooms left), `forbidden`. */
74
+ descend(): Promise<number>;
75
+ /** The owner (or a developer) ends the run. */
76
+ abandon(): Promise<boolean>;
77
+ }
78
+ //# sourceMappingURL=instances.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instances.d.ts","sourceRoot":"","sources":["../../../src/kit/modules/instances.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,OAAO,GAAG,UAAU,GAAG,MAAM,GAAG,MAAM,CAAC;IAC7C,+BAA+B;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAED,oCAAoC;AACpC,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,UAAU,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,WAAW,GAAG,SAAS,CAAC;IAC9E,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,8DAA8D;IAC9D,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,yEAAyE;IACzE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,GAAG,EAAE,MAAM,EAAE,CAAC;CACf;AAED,+EAA+E;AAC/E,qBAAa,YAAY;IAIrB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAJ3B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAkC;gBAGpC,OAAO,EAAE,UAAU,EACnB,QAAQ,SAAa;IAGxC,qEAAqE;IACrE,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW;CAQ9B;AAED;;;;GAIG;AACH,qBAAa,WAAW;IAIpB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM;IACzB,QAAQ,CAAC,GAAG,EAAE,MAAM;IALtB,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,eAAe,CAAC,CAAC;gBAGtB,OAAO,EAAE,UAAU,EAC3B,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,MAAM;IAKtB,KAAK,IAAI,OAAO,CAAC,eAAe,CAAC;IAIjC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAIxB;;;OAGG;IACH,IAAI,CAAC,OAAO,GAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,aAAa,CAAC,MAAM,GAAG,MAAM,CAAC,CAAA;KAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IAO9F,0EAA0E;IAC1E,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIjD,+DAA+D;IAC/D,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC;IAIxB;;;OAGG;IACH,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC;IAIxB,+HAA+H;IAC/H,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;IAI1B,+CAA+C;IAC/C,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC;CAG5B"}
@@ -0,0 +1,72 @@
1
+ import { HubState } from '../mirror.js';
2
+ /** Private runs for one party (the `instance` starter): {@link run} by key. */
3
+ export class InstancesKit {
4
+ constructor(runtime, nodeType = 'instance') {
5
+ this.runtime = runtime;
6
+ this.nodeType = nodeType;
7
+ this.runs = new Map();
8
+ }
9
+ /** The run with key `key` (a key the game makes up, one per run). */
10
+ run(key) {
11
+ let r = this.runs.get(key);
12
+ if (!r) {
13
+ r = new InstanceRun(this.runtime, this.nodeType, key);
14
+ this.runs.set(key, r);
15
+ }
16
+ return r;
17
+ }
18
+ }
19
+ /**
20
+ * One run: a party plays down floors the hub generates from the run's seed, the hub resolves each
21
+ * room, a party with nobody standing is wiped (permadeath), and a run nobody touches expires. A
22
+ * cleared or wiped run posts each member's depth to a leaderboard when the hub's config names one.
23
+ */
24
+ export class InstanceRun {
25
+ constructor(runtime, nodeType, key) {
26
+ this.runtime = runtime;
27
+ this.nodeType = nodeType;
28
+ this.key = key;
29
+ this.view = new HubState(runtime, nodeType, key, 'run');
30
+ }
31
+ watch() {
32
+ return this.view.start();
33
+ }
34
+ unwatch() {
35
+ return this.view.stop();
36
+ }
37
+ /**
38
+ * Opens the run as its owner (a developer kit opens one for `party`); resolves with its seed.
39
+ * @throws {KitError} `started`, `bad_request` (party size), `conflict` (its grid could not be reserved).
40
+ */
41
+ open(options = {}) {
42
+ const args = {};
43
+ if (options.seed !== undefined)
44
+ args.seed = options.seed;
45
+ if (options.party?.length)
46
+ args.party = options.party.map(Number);
47
+ return this.runtime.call(this.nodeType, this.key, 'open', args, { action: true });
48
+ }
49
+ /** The owner invites a player. @throws {KitError} `forbidden`, `full`. */
50
+ invite(player) {
51
+ return this.runtime.call(this.nodeType, this.key, 'invite', { player: Number(player) }, { action: true });
52
+ }
53
+ /** An invited player joins. @throws {KitError} `forbidden`. */
54
+ join() {
55
+ return this.runtime.call(this.nodeType, this.key, 'join', null, { action: true });
56
+ }
57
+ /**
58
+ * Resolves the room the party is at; resolves with what happened, as the log has it.
59
+ * @throws {KitError} `not_member`, `forbidden` (the caller is down), `conflict` (descend first), `finished`.
60
+ */
61
+ enter() {
62
+ return this.runtime.call(this.nodeType, this.key, 'enter', null, { action: true });
63
+ }
64
+ /** The owner leads the party to the next floor; resolves with it. @throws {KitError} `not_ready` (rooms left), `forbidden`. */
65
+ descend() {
66
+ return this.runtime.call(this.nodeType, this.key, 'descend', null, { action: true });
67
+ }
68
+ /** The owner (or a developer) ends the run. */
69
+ abandon() {
70
+ return this.runtime.call(this.nodeType, this.key, 'abandon', null, { action: true });
71
+ }
72
+ }
@@ -0,0 +1,79 @@
1
+ import { HubState } from '../mirror.js';
2
+ import type { KitRuntime } from '../runtime.js';
3
+ /** A player's place on a board. */
4
+ export interface LeaderboardRank {
5
+ rank: number;
6
+ player: number;
7
+ score: number;
8
+ }
9
+ /** What the `board` topic carries: the top of the board and the season. */
10
+ export interface LeaderboardView {
11
+ season: number;
12
+ /** When the season began (Unix ms). */
13
+ season_started: number;
14
+ /** Players with a score this season. */
15
+ entries: number;
16
+ top: LeaderboardRank[];
17
+ }
18
+ /** The season, and the last one's final standings. */
19
+ export interface LeaderboardSeason {
20
+ season: number;
21
+ started: number;
22
+ entries: number;
23
+ last: LeaderboardRank[];
24
+ }
25
+ /** A board's settings (developers). */
26
+ export interface LeaderboardConfig {
27
+ /** `best` (by `order`), `sum` or `latest` submission. */
28
+ keep?: 'best' | 'sum' | 'latest';
29
+ /** `high` scores rank first (points) or `low` (times). */
30
+ order?: 'high' | 'low';
31
+ top_size?: number;
32
+ /** A cron schedule that ends the season (`0 0 * * 1`: every Monday), or null for none. */
33
+ season_cron?: string | null;
34
+ max_entries?: number;
35
+ }
36
+ /** Leaderboards (the `leaderboard` starter): {@link board} by name. */
37
+ export declare class LeaderboardsKit {
38
+ private readonly runtime;
39
+ private readonly nodeType;
40
+ private readonly boards;
41
+ constructor(runtime: KitRuntime, nodeType?: string);
42
+ /** The board named `name` (`weekly-score`, `fastest-lap`, ...). */
43
+ board(name: string): LeaderboardHandle;
44
+ }
45
+ /**
46
+ * One board. The hub ranks players itself, and only other hubs and developers submit: a client
47
+ * never sends its own score, the hub that decided the result does (a session, a race, a run).
48
+ * {@link view} mirrors the `board` topic (at most once a second).
49
+ */
50
+ export declare class LeaderboardHandle {
51
+ private readonly runtime;
52
+ readonly nodeType: string;
53
+ readonly name: string;
54
+ /** The `board` topic: the top of the board and the season. */
55
+ readonly view: HubState<LeaderboardView>;
56
+ constructor(runtime: KitRuntime, nodeType: string, name: string);
57
+ watch(): Promise<LeaderboardView>;
58
+ unwatch(): Promise<void>;
59
+ /** A page of the board, best first. */
60
+ top(options?: {
61
+ limit?: number;
62
+ offset?: number;
63
+ }): Promise<LeaderboardRank[]>;
64
+ /** The places around a player (the caller's own, without `player`). */
65
+ around(options?: {
66
+ player?: number | string;
67
+ radius?: number;
68
+ }): Promise<LeaderboardRank[]>;
69
+ /** The caller's own place, or null without a score this season. */
70
+ me(): Promise<LeaderboardRank | null>;
71
+ season(): Promise<LeaderboardSeason>;
72
+ /** Submits a score for `player`. Developers only (a developer kit); players are refused. */
73
+ submit(player: number | string, score: number): Promise<number>;
74
+ /** Sets the board's config. Developers only. */
75
+ configure(config: LeaderboardConfig): Promise<boolean>;
76
+ /** Ends the season now; resolves with the new season. Developers only. */
77
+ roll(): Promise<number>;
78
+ }
79
+ //# sourceMappingURL=leaderboards.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"leaderboards.d.ts","sourceRoot":"","sources":["../../../src/kit/modules/leaderboards.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD,mCAAmC;AACnC,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAED,2EAA2E;AAC3E,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,uCAAuC;IACvC,cAAc,EAAE,MAAM,CAAC;IACvB,wCAAwC;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,eAAe,EAAE,CAAC;CACxB;AAED,sDAAsD;AACtD,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,eAAe,EAAE,CAAC;CACzB;AAED,uCAAuC;AACvC,MAAM,WAAW,iBAAiB;IAChC,yDAAyD;IACzD,IAAI,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,QAAQ,CAAC;IACjC,0DAA0D;IAC1D,KAAK,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0FAA0F;IAC1F,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,uEAAuE;AACvE,qBAAa,eAAe;IAIxB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAJ3B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAwC;gBAG5C,OAAO,EAAE,UAAU,EACnB,QAAQ,SAAgB;IAG3C,mEAAmE;IACnE,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB;CAQvC;AAED;;;;GAIG;AACH,qBAAa,iBAAiB;IAK1B,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM;IANvB,8DAA8D;IAC9D,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,eAAe,CAAC,CAAC;gBAGtB,OAAO,EAAE,UAAU,EAC3B,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM;IAKvB,KAAK,IAAI,OAAO,CAAC,eAAe,CAAC;IAIjC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAIxB,uCAAuC;IACvC,GAAG,CAAC,OAAO,GAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IAIlF,uEAAuE;IACvE,MAAM,CAAC,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IAO/F,mEAAmE;IACnE,EAAE,IAAI,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IAIrC,MAAM,IAAI,OAAO,CAAC,iBAAiB,CAAC;IAIpC,4FAA4F;IAC5F,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAI/D,gDAAgD;IAChD,SAAS,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC;IAItD,0EAA0E;IAC1E,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC;CAGxB"}
@@ -0,0 +1,69 @@
1
+ import { HubState } from '../mirror.js';
2
+ /** Leaderboards (the `leaderboard` starter): {@link board} by name. */
3
+ export class LeaderboardsKit {
4
+ constructor(runtime, nodeType = 'leaderboard') {
5
+ this.runtime = runtime;
6
+ this.nodeType = nodeType;
7
+ this.boards = new Map();
8
+ }
9
+ /** The board named `name` (`weekly-score`, `fastest-lap`, ...). */
10
+ board(name) {
11
+ let b = this.boards.get(name);
12
+ if (!b) {
13
+ b = new LeaderboardHandle(this.runtime, this.nodeType, name);
14
+ this.boards.set(name, b);
15
+ }
16
+ return b;
17
+ }
18
+ }
19
+ /**
20
+ * One board. The hub ranks players itself, and only other hubs and developers submit: a client
21
+ * never sends its own score, the hub that decided the result does (a session, a race, a run).
22
+ * {@link view} mirrors the `board` topic (at most once a second).
23
+ */
24
+ export class LeaderboardHandle {
25
+ constructor(runtime, nodeType, name) {
26
+ this.runtime = runtime;
27
+ this.nodeType = nodeType;
28
+ this.name = name;
29
+ this.view = new HubState(runtime, nodeType, name, 'board');
30
+ }
31
+ watch() {
32
+ return this.view.start();
33
+ }
34
+ unwatch() {
35
+ return this.view.stop();
36
+ }
37
+ /** A page of the board, best first. */
38
+ top(options = {}) {
39
+ return this.runtime.call(this.nodeType, this.name, 'top', options);
40
+ }
41
+ /** The places around a player (the caller's own, without `player`). */
42
+ around(options = {}) {
43
+ const args = {};
44
+ if (options.player !== undefined)
45
+ args.player = Number(options.player);
46
+ if (options.radius !== undefined)
47
+ args.radius = options.radius;
48
+ return this.runtime.call(this.nodeType, this.name, 'around', args);
49
+ }
50
+ /** The caller's own place, or null without a score this season. */
51
+ me() {
52
+ return this.runtime.call(this.nodeType, this.name, 'me');
53
+ }
54
+ season() {
55
+ return this.runtime.call(this.nodeType, this.name, 'season');
56
+ }
57
+ /** Submits a score for `player`. Developers only (a developer kit); players are refused. */
58
+ submit(player, score) {
59
+ return this.runtime.call(this.nodeType, this.name, 'submit', { player: Number(player), score }, { action: true });
60
+ }
61
+ /** Sets the board's config. Developers only. */
62
+ configure(config) {
63
+ return this.runtime.call(this.nodeType, this.name, 'configure', config, { action: true });
64
+ }
65
+ /** Ends the season now; resolves with the new season. Developers only. */
66
+ roll() {
67
+ return this.runtime.call(this.nodeType, this.name, 'roll', null, { action: true });
68
+ }
69
+ }
@@ -0,0 +1,107 @@
1
+ import { HubState } from '../mirror.js';
2
+ import type { KitRuntime } from '../runtime.js';
3
+ import { type KitStore } from '../store.js';
4
+ /** A player's place in a queue, as the matchmaker's `status` (and every change) answers it. */
5
+ export type MatchPlace = {
6
+ state: 'idle';
7
+ } | {
8
+ state: 'party';
9
+ leader: number;
10
+ members: number[];
11
+ confirmed: number[];
12
+ expires_in_ms: number;
13
+ } | {
14
+ state: 'queued';
15
+ rating: number;
16
+ waited_ms: number;
17
+ window: number;
18
+ } | {
19
+ state: 'proposed';
20
+ players: number[];
21
+ accepted: number[];
22
+ expires_in_ms: number;
23
+ } | {
24
+ state: 'matched';
25
+ session: string;
26
+ };
27
+ /** What the `queue` topic carries: how many, never who. */
28
+ export interface MatchQueueCounts {
29
+ waiting: number;
30
+ proposals: number;
31
+ forming: number;
32
+ }
33
+ /** A queue's settings (developers). */
34
+ export interface MatchmakerConfig {
35
+ players_per_match?: number;
36
+ /** The rating difference a player accepts at first, and how it widens each second. */
37
+ window?: number;
38
+ widen_per_sec?: number;
39
+ max_window?: number;
40
+ accept_ms?: number;
41
+ /** How long a party has for its members to confirm. */
42
+ party_ms?: number;
43
+ }
44
+ /** Joining a queue: alone, as a party's leader (`party`: the others), or confirming (`leader`). */
45
+ export interface MatchJoin {
46
+ rating: number;
47
+ party?: ReadonlyArray<number | string>;
48
+ leader?: number | string;
49
+ }
50
+ /** Where the matchmaker hubs are: type `matchmaker`, one per queue name, in the starter pack. */
51
+ export interface MatchmakingKitOptions {
52
+ nodeType?: string;
53
+ }
54
+ /** Matchmaking queues (the `matchmaker` starter): {@link queue} by name. */
55
+ export declare class MatchmakingKit {
56
+ private readonly runtime;
57
+ private readonly queues;
58
+ private readonly nodeType;
59
+ constructor(runtime: KitRuntime, options?: MatchmakingKitOptions);
60
+ /** The queue named `name` (`ranked`, `casual`, ...), one per name. */
61
+ queue(name: string): MatchQueue;
62
+ }
63
+ /**
64
+ * One queue. Every call's answer updates {@link place}; {@link watch} keeps it current while
65
+ * the player waits (the queue never names its players on its topic, so a waiting client asks)
66
+ * and fires {@link onMatched} with the session key once a match is made.
67
+ */
68
+ export declare class MatchQueue {
69
+ private readonly runtime;
70
+ readonly nodeType: string;
71
+ readonly name: string;
72
+ /** The `queue` topic: how many are waiting. */
73
+ readonly counts: HubState<MatchQueueCounts>;
74
+ private readonly placeStore;
75
+ private readonly matchedListeners;
76
+ private lastMatched;
77
+ private timer;
78
+ constructor(runtime: KitRuntime, nodeType: string, name: string);
79
+ /** The player's place, as last answered. */
80
+ get place(): KitStore<MatchPlace>;
81
+ private settle;
82
+ /**
83
+ * Joins the queue (or updates the rating). With `party`, the caller leads a party of them;
84
+ * each member then joins with `leader`, and the party queues once all have.
85
+ * @throws {KitError} `conflict` (a match to accept), `limit` (party size), `forbidden`, `full`.
86
+ */
87
+ join(req: MatchJoin): Promise<MatchPlace>;
88
+ /** Leaves the queue, a forming party, or a proposed match (the party leaves with you). */
89
+ leave(): Promise<boolean>;
90
+ /** Accepts the proposed match; the answer is `matched` once everyone has. */
91
+ accept(): Promise<MatchPlace>;
92
+ /** Declines the proposed match; the others go back to the queue. */
93
+ decline(): Promise<boolean>;
94
+ /** Asks for the player's place. */
95
+ status(): Promise<MatchPlace>;
96
+ /** Sets the queue's config. Developers only (a developer kit). */
97
+ configure(config: MatchmakerConfig): Promise<boolean>;
98
+ /**
99
+ * Asks for the player's place every `intervalMs` (default 2 000) while they wait in a party,
100
+ * the queue or a proposal. Returns the function that stops it.
101
+ */
102
+ watch(intervalMs?: number): () => void;
103
+ unwatch(): void;
104
+ /** Called with the session key when a match is made for the player. */
105
+ onMatched(listener: (session: string) => void): () => void;
106
+ }
107
+ //# sourceMappingURL=matchmaking.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"matchmaking.d.ts","sourceRoot":"","sources":["../../../src/kit/modules/matchmaking.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,109 @@
1
+ import { HubState } from '../mirror.js';
2
+ import { WritableKitStore } from '../store.js';
3
+ /** Matchmaking queues (the `matchmaker` starter): {@link queue} by name. */
4
+ export class MatchmakingKit {
5
+ constructor(runtime, options = {}) {
6
+ this.runtime = runtime;
7
+ this.queues = new Map();
8
+ this.nodeType = options.nodeType ?? 'matchmaker';
9
+ }
10
+ /** The queue named `name` (`ranked`, `casual`, ...), one per name. */
11
+ queue(name) {
12
+ let q = this.queues.get(name);
13
+ if (!q) {
14
+ q = new MatchQueue(this.runtime, this.nodeType, name);
15
+ this.queues.set(name, q);
16
+ }
17
+ return q;
18
+ }
19
+ }
20
+ const ACTIVE = new Set(['party', 'queued', 'proposed']);
21
+ /**
22
+ * One queue. Every call's answer updates {@link place}; {@link watch} keeps it current while
23
+ * the player waits (the queue never names its players on its topic, so a waiting client asks)
24
+ * and fires {@link onMatched} with the session key once a match is made.
25
+ */
26
+ export class MatchQueue {
27
+ constructor(runtime, nodeType, name) {
28
+ this.runtime = runtime;
29
+ this.nodeType = nodeType;
30
+ this.name = name;
31
+ this.placeStore = new WritableKitStore({ state: 'idle' });
32
+ this.matchedListeners = new Set();
33
+ this.lastMatched = null;
34
+ this.timer = null;
35
+ this.counts = new HubState(runtime, nodeType, name, 'queue');
36
+ }
37
+ /** The player's place, as last answered. */
38
+ get place() {
39
+ return this.placeStore;
40
+ }
41
+ settle(p) {
42
+ this.placeStore.set(p);
43
+ if (p.state === 'matched' && p.session !== this.lastMatched) {
44
+ this.lastMatched = p.session;
45
+ for (const l of [...this.matchedListeners])
46
+ l(p.session);
47
+ }
48
+ return p;
49
+ }
50
+ /**
51
+ * Joins the queue (or updates the rating). With `party`, the caller leads a party of them;
52
+ * each member then joins with `leader`, and the party queues once all have.
53
+ * @throws {KitError} `conflict` (a match to accept), `limit` (party size), `forbidden`, `full`.
54
+ */
55
+ async join(req) {
56
+ const args = { rating: req.rating };
57
+ if (req.party?.length)
58
+ args.party = req.party.map(Number);
59
+ if (req.leader !== undefined)
60
+ args.leader = Number(req.leader);
61
+ return this.settle(await this.runtime.call(this.nodeType, this.name, 'join', args, { action: true }));
62
+ }
63
+ /** Leaves the queue, a forming party, or a proposed match (the party leaves with you). */
64
+ async leave() {
65
+ const left = await this.runtime.call(this.nodeType, this.name, 'leave', null, { action: true });
66
+ this.settle({ state: 'idle' });
67
+ return left;
68
+ }
69
+ /** Accepts the proposed match; the answer is `matched` once everyone has. */
70
+ async accept() {
71
+ return this.settle(await this.runtime.call(this.nodeType, this.name, 'accept', null, { action: true }));
72
+ }
73
+ /** Declines the proposed match; the others go back to the queue. */
74
+ async decline() {
75
+ const done = await this.runtime.call(this.nodeType, this.name, 'decline', null, { action: true });
76
+ this.settle({ state: 'idle' });
77
+ return done;
78
+ }
79
+ /** Asks for the player's place. */
80
+ async status() {
81
+ return this.settle(await this.runtime.call(this.nodeType, this.name, 'status'));
82
+ }
83
+ /** Sets the queue's config. Developers only (a developer kit). */
84
+ configure(config) {
85
+ return this.runtime.call(this.nodeType, this.name, 'configure', config, { action: true });
86
+ }
87
+ /**
88
+ * Asks for the player's place every `intervalMs` (default 2 000) while they wait in a party,
89
+ * the queue or a proposal. Returns the function that stops it.
90
+ */
91
+ watch(intervalMs = 2000) {
92
+ this.unwatch();
93
+ this.timer = setInterval(() => {
94
+ if (ACTIVE.has(this.placeStore.get().state))
95
+ void this.status().catch(() => undefined);
96
+ }, Math.max(500, intervalMs));
97
+ return () => this.unwatch();
98
+ }
99
+ unwatch() {
100
+ if (this.timer)
101
+ clearInterval(this.timer);
102
+ this.timer = null;
103
+ }
104
+ /** Called with the session key when a match is made for the player. */
105
+ onMatched(listener) {
106
+ this.matchedListeners.add(listener);
107
+ return () => this.matchedListeners.delete(listener);
108
+ }
109
+ }
@@ -0,0 +1,59 @@
1
+ import { HubState } from '../mirror.js';
2
+ import type { KitRuntime } from '../runtime.js';
3
+ export interface DuelSeat {
4
+ player: number;
5
+ wins: number;
6
+ /** Whether this round's throw is in (never which). */
7
+ thrown: boolean;
8
+ }
9
+ export interface DuelReveal {
10
+ round: number;
11
+ /** Each seat's throw, in seat order; null when it was not in on time. */
12
+ hands: Array<string | null>;
13
+ winner: number | null;
14
+ }
15
+ /** What the `duel` topic carries: who has thrown, never what, until the reveal. */
16
+ export interface DuelView {
17
+ phase: 'waiting' | 'playing' | 'finished';
18
+ seats: DuelSeat[];
19
+ best_of: number;
20
+ round: number;
21
+ /** When this round closes (Unix ms). */
22
+ deadline: number | null;
23
+ last: DuelReveal | null;
24
+ winner: number | null;
25
+ }
26
+ /** Two-player duels of hidden throws (the `minigame` starter): {@link duel} by table. */
27
+ export declare class MinigamesKit {
28
+ private readonly runtime;
29
+ private readonly nodeType;
30
+ private readonly duels;
31
+ constructor(runtime: KitRuntime, nodeType?: string);
32
+ duel(key: string): Duel;
33
+ }
34
+ /**
35
+ * One duel: the hub keeps each round's throws until both are in (or the round's time runs out),
36
+ * then reveals them; the first to win a majority of `best_of` rounds wins. The starter's game is
37
+ * rock, paper, scissors.
38
+ */
39
+ export declare class Duel {
40
+ private readonly runtime;
41
+ readonly nodeType: string;
42
+ readonly key: string;
43
+ readonly view: HubState<DuelView>;
44
+ constructor(runtime: KitRuntime, nodeType: string, key: string);
45
+ watch(): Promise<DuelView>;
46
+ unwatch(): Promise<void>;
47
+ /** Takes a seat; resolves with whether this seat started the first round. @throws {KitError} `full`. */
48
+ join(): Promise<boolean>;
49
+ /** Before the duel starts. @throws {KitError} `started`. */
50
+ leave(): Promise<boolean>;
51
+ /**
52
+ * The caller's hidden throw this round; resolves with whether it completed the round.
53
+ * @throws {KitError} `conflict` (already in, or no round open), `bad_request` (not a hand), `not_member`.
54
+ */
55
+ throw(hand: string): Promise<boolean>;
56
+ /** Once it is over: play again. @throws {KitError} `conflict`, `not_member`. */
57
+ rematch(): Promise<boolean>;
58
+ }
59
+ //# sourceMappingURL=minigames.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"minigames.d.ts","sourceRoot":"","sources":["../../../src/kit/modules/minigames.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,sDAAsD;IACtD,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,yEAAyE;IACzE,KAAK,EAAE,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC5B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,mFAAmF;AACnF,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,SAAS,GAAG,SAAS,GAAG,UAAU,CAAC;IAC1C,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,wCAAwC;IACxC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,IAAI,EAAE,UAAU,GAAG,IAAI,CAAC;IACxB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,yFAAyF;AACzF,qBAAa,YAAY;IAIrB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAJ3B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA2B;gBAG9B,OAAO,EAAE,UAAU,EACnB,QAAQ,SAAa;IAGxC,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;CAQxB;AAED;;;;GAIG;AACH,qBAAa,IAAI;IAIb,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM;IACzB,QAAQ,CAAC,GAAG,EAAE,MAAM;IALtB,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC;gBAGf,OAAO,EAAE,UAAU,EAC3B,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,MAAM;IAKtB,KAAK,IAAI,OAAO,CAAC,QAAQ,CAAC;IAI1B,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAIxB,wGAAwG;IACxG,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC;IAIxB,4DAA4D;IAC5D,KAAK,IAAI,OAAO,CAAC,OAAO,CAAC;IAIzB;;;OAGG;IACH,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIrC,gFAAgF;IAChF,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC;CAG5B"}