@pithy-sh/leaderboard 0.2.5 → 0.2.6

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.
@@ -2,6 +2,7 @@
2
2
  // SPDX-License-Identifier: MIT
3
3
  import { type Capability } from "@pithy-sh/core/src/capability/capability";
4
4
  import { LeaderboardConfig, type LeaderboardConfigInput } from "./config/config";
5
+ import { type LeaderboardPeer } from "./peer";
5
6
  /**
6
7
  * Where leaderboard's migrations sort in the app database. Unique per database; the registry composes
7
8
  * keys like `0400_leaderboard_0001_entries`. Sits after media (300) and audit (250).
@@ -13,6 +14,12 @@ export type LeaderboardOptions = LeaderboardConfigInput & {
13
14
  };
14
15
  export interface LeaderboardCapability extends Capability {
15
16
  leaderboardConfig: LeaderboardConfig;
17
+ /**
18
+ * What a capability composed beside this one publishes through — `multiplayer`, submitting a session's
19
+ * result to a board. Found in its `compose` hook, so it never imports this package and a project without it
20
+ * bundles multiplayer (#645). See `peer.ts`.
21
+ */
22
+ leaderboardPeer: LeaderboardPeer;
16
23
  }
17
24
  /**
18
25
  * The leaderboard capability: submit a score, read the standings, read your own rank — across windows.
@@ -1 +1 @@
1
- {"version":3,"file":"capability.d.ts","sourceRoot":"","sources":["../src/capability.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,UAAU,EAAoB,MAAM,0CAA0C,CAAC;AAE7F,OAAO,EAAE,iBAAiB,EAAE,KAAK,sBAAsB,EAAuB,MAAM,iBAAiB,CAAC;AAOtG;;;GAGG;AACH,eAAO,MAAM,2BAA2B,MAAM,CAAC;AAE/C,MAAM,MAAM,kBAAkB,GAAG,sBAAsB,GAAG;IACxD,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,WAAW,qBAAsB,SAAQ,UAAU;IACvD,iBAAiB,EAAE,iBAAiB,CAAC;CACtC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,WAAW,CAAC,OAAO,GAAE,kBAAmC,GAAG,qBAAqB,CAiC/F;AAED,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,UAAU,GAAG,UAAU,IAAI,qBAAqB,CAEnG;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAGlE"}
1
+ {"version":3,"file":"capability.d.ts","sourceRoot":"","sources":["../src/capability.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,UAAU,EAAoB,MAAM,0CAA0C,CAAC;AAE7F,OAAO,EAAE,iBAAiB,EAAE,KAAK,sBAAsB,EAAuB,MAAM,iBAAiB,CAAC;AAItG,OAAO,EAAE,KAAK,eAAe,EAAmB,MAAM,QAAQ,CAAC;AAI/D;;;GAGG;AACH,eAAO,MAAM,2BAA2B,MAAM,CAAC;AAE/C,MAAM,MAAM,kBAAkB,GAAG,sBAAsB,GAAG;IACxD,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,WAAW,qBAAsB,SAAQ,UAAU;IACvD,iBAAiB,EAAE,iBAAiB,CAAC;IACrC;;;;OAIG;IACH,eAAe,EAAE,eAAe,CAAC;CAClC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,WAAW,CAAC,OAAO,GAAE,kBAAmC,GAAG,qBAAqB,CAiC/F;AAED,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,UAAU,GAAG,UAAU,IAAI,qBAAqB,CAEnG;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAGlE"}
@@ -4,6 +4,7 @@ import { LeaderboardConfig, materializeSchedule } from "./config/config.js";
4
4
  import { leaderboardTables } from "./data/tables.js";
5
5
  import { registerLeaderboardRoutes } from "./http/routes.js";
6
6
  import { leaderboard_0001_entries } from "./migrations/0001_entries.js";
7
+ import { leaderboardPeer } from "./peer.js";
7
8
  import { leaderboardExampleSeed } from "./seeds/example.js";
8
9
  import { PACKAGE_NAME, PACKAGE_VERSION } from "./version.generated.js";
9
10
  import { defineCapability } from "@pithy-sh/core/src/capability/capability";
@@ -55,7 +56,10 @@ function leaderboard(options = { boards: [] }) {
55
56
  }),
56
57
  seeds: [leaderboardExampleSeed]
57
58
  });
58
- return Object.assign(capability, { leaderboardConfig: resolved });
59
+ return Object.assign(capability, {
60
+ leaderboardConfig: resolved,
61
+ leaderboardPeer
62
+ });
59
63
  }
60
64
  function isLeaderboardCapability(capability) {
61
65
  return capability.name === "leaderboard" && "leaderboardConfig" in capability;
package/dist/peer.d.ts ADDED
@@ -0,0 +1,49 @@
1
+ // SPDX-FileCopyrightText: 2026 Pithy
2
+ // SPDX-License-Identifier: MIT
3
+ import { leaderboardDatabase } from "./data/tables";
4
+ import { entryStore } from "./entry/store";
5
+ import { windowKeyAt } from "./window/schedule";
6
+ /**
7
+ * **What a capability composed beside the leaderboard may use — handed to it, never imported by it** (#645).
8
+ *
9
+ * `@pithy-sh/leaderboard` is an optional peer of `multiplayer`, which publishes a resolved session's result to
10
+ * a board through the board's own submit path. It used to reach these modules by import, and a specifier naming
11
+ * an optional package is one a bundler resolves whether or not the branch holding it ever runs — so a project
12
+ * without the leaderboard could not bundle multiplayer at all.
13
+ *
14
+ * So `leaderboard()` carries this object as `leaderboardPeer`, and a dependent finds it among the composed
15
+ * capabilities in its `compose` hook. The dependent names this package only in a type, which a bundler never
16
+ * sees.
17
+ */
18
+ export declare const leaderboardPeer: {
19
+ readonly LeaderboardBoard: import("zod").ZodObject<{
20
+ key: import("zod").ZodString;
21
+ store: import("zod").ZodDefault<import("zod").ZodLiteral<"d1">>;
22
+ direction: import("zod").ZodEnum<{
23
+ asc: "asc";
24
+ desc: "desc";
25
+ }>;
26
+ aggregation: import("zod").ZodDefault<import("zod").ZodEnum<{
27
+ best: "best";
28
+ latest: "latest";
29
+ sum: "sum";
30
+ }>>;
31
+ window: import("zod").ZodOptional<import("zod").ZodString>;
32
+ retain: import("zod").ZodOptional<import("zod").ZodNumber>;
33
+ retainDays: import("zod").ZodOptional<import("zod").ZodNumber>;
34
+ min: import("zod").ZodOptional<import("zod").ZodNumber>;
35
+ max: import("zod").ZodOptional<import("zod").ZodNumber>;
36
+ tiers: import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodObject<{
37
+ key: import("zod").ZodString;
38
+ from: import("zod").ZodNumber;
39
+ }, import("zod/v4/core").$strip>>>;
40
+ trackActivity: import("zod").ZodDefault<import("zod").ZodBoolean>;
41
+ }, import("zod/v4/core").$strip>;
42
+ readonly leaderboardDatabase: typeof leaderboardDatabase;
43
+ readonly entryStore: typeof entryStore;
44
+ readonly ALL_TIME_WINDOW: "all";
45
+ readonly windowKeyAt: typeof windowKeyAt;
46
+ };
47
+ /** The leaderboard's peer surface, by type — what `leaderboardPeer` holds. */
48
+ export type LeaderboardPeer = typeof leaderboardPeer;
49
+ //# sourceMappingURL=peer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"peer.d.ts","sourceRoot":"","sources":["../src/peer.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAmB,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEjE;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAMlB,CAAC;AAEX,8EAA8E;AAC9E,MAAM,MAAM,eAAe,GAAG,OAAO,eAAe,CAAC"}
package/dist/peer.js ADDED
@@ -0,0 +1,28 @@
1
+ // SPDX-FileCopyrightText: 2026 Pithy
2
+ // SPDX-License-Identifier: MIT
3
+ import { windowKeyAt } from "./window/schedule.js";
4
+ import { LeaderboardBoard } from "./config/config.js";
5
+ import { leaderboardDatabase } from "./data/tables.js";
6
+ import { entryStore } from "./entry/store.js";
7
+ //#region src/peer.ts
8
+ /**
9
+ * **What a capability composed beside the leaderboard may use — handed to it, never imported by it** (#645).
10
+ *
11
+ * `@pithy-sh/leaderboard` is an optional peer of `multiplayer`, which publishes a resolved session's result to
12
+ * a board through the board's own submit path. It used to reach these modules by import, and a specifier naming
13
+ * an optional package is one a bundler resolves whether or not the branch holding it ever runs — so a project
14
+ * without the leaderboard could not bundle multiplayer at all.
15
+ *
16
+ * So `leaderboard()` carries this object as `leaderboardPeer`, and a dependent finds it among the composed
17
+ * capabilities in its `compose` hook. The dependent names this package only in a type, which a bundler never
18
+ * sees.
19
+ */
20
+ const leaderboardPeer = {
21
+ LeaderboardBoard,
22
+ leaderboardDatabase,
23
+ entryStore,
24
+ ALL_TIME_WINDOW: "all",
25
+ windowKeyAt
26
+ };
27
+ //#endregion
28
+ export { leaderboardPeer };
@@ -3,5 +3,5 @@
3
3
  /** This package's npm name — the join key against a release feed. */
4
4
  export declare const PACKAGE_NAME = "@pithy-sh/leaderboard";
5
5
  /** This package's version, stamped from its own package.json at generation time. */
6
- export declare const PACKAGE_VERSION = "0.2.5";
6
+ export declare const PACKAGE_VERSION = "0.2.6";
7
7
  //# sourceMappingURL=version.generated.d.ts.map
@@ -4,6 +4,6 @@
4
4
  /** This package's npm name — the join key against a release feed. */
5
5
  const PACKAGE_NAME = "@pithy-sh/leaderboard";
6
6
  /** This package's version, stamped from its own package.json at generation time. */
7
- const PACKAGE_VERSION = "0.2.5";
7
+ const PACKAGE_VERSION = "0.2.6";
8
8
  //#endregion
9
9
  export { PACKAGE_NAME, PACKAGE_VERSION };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pithy-sh/leaderboard",
3
- "version": "0.2.5",
3
+ "version": "0.2.6",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -41,7 +41,7 @@
41
41
  "croner": "^10.0.1"
42
42
  },
43
43
  "peerDependencies": {
44
- "@pithy-sh/core": "^0.7.3",
44
+ "@pithy-sh/core": "^0.7.4",
45
45
  "hono": "^4.13.2",
46
46
  "kysely": "^0.29.0",
47
47
  "zod": "^4.4.0"
package/src/capability.ts CHANGED
@@ -8,6 +8,7 @@ import { LeaderboardConfig, type LeaderboardConfigInput, materializeSchedule } f
8
8
  import { leaderboardTables } from "./data/tables";
9
9
  import { registerLeaderboardRoutes } from "./http/routes";
10
10
  import { leaderboard_0001_entries } from "./migrations/0001_entries";
11
+ import { type LeaderboardPeer, leaderboardPeer } from "./peer";
11
12
  import { leaderboardExampleSeed } from "./seeds/example";
12
13
  import { PACKAGE_NAME, PACKAGE_VERSION } from "./version.generated";
13
14
 
@@ -24,6 +25,12 @@ export type LeaderboardOptions = LeaderboardConfigInput & {
24
25
 
25
26
  export interface LeaderboardCapability extends Capability {
26
27
  leaderboardConfig: LeaderboardConfig;
28
+ /**
29
+ * What a capability composed beside this one publishes through — `multiplayer`, submitting a session's
30
+ * result to a board. Found in its `compose` hook, so it never imports this package and a project without it
31
+ * bundles multiplayer (#645). See `peer.ts`.
32
+ */
33
+ leaderboardPeer: LeaderboardPeer;
27
34
  }
28
35
 
29
36
  /**
@@ -75,7 +82,7 @@ export function leaderboard(options: LeaderboardOptions = { boards: [] }): Leade
75
82
  seeds: [leaderboardExampleSeed],
76
83
  });
77
84
 
78
- return Object.assign(capability, { leaderboardConfig: resolved });
85
+ return Object.assign(capability, { leaderboardConfig: resolved, leaderboardPeer });
79
86
  }
80
87
 
81
88
  export function isLeaderboardCapability(capability: Capability): capability is LeaderboardCapability {
package/src/peer.ts ADDED
@@ -0,0 +1,30 @@
1
+ // SPDX-FileCopyrightText: 2026 Pithy
2
+ // SPDX-License-Identifier: MIT
3
+
4
+ import { LeaderboardBoard } from "./config/config";
5
+ import { leaderboardDatabase } from "./data/tables";
6
+ import { entryStore } from "./entry/store";
7
+ import { ALL_TIME_WINDOW, windowKeyAt } from "./window/schedule";
8
+
9
+ /**
10
+ * **What a capability composed beside the leaderboard may use — handed to it, never imported by it** (#645).
11
+ *
12
+ * `@pithy-sh/leaderboard` is an optional peer of `multiplayer`, which publishes a resolved session's result to
13
+ * a board through the board's own submit path. It used to reach these modules by import, and a specifier naming
14
+ * an optional package is one a bundler resolves whether or not the branch holding it ever runs — so a project
15
+ * without the leaderboard could not bundle multiplayer at all.
16
+ *
17
+ * So `leaderboard()` carries this object as `leaderboardPeer`, and a dependent finds it among the composed
18
+ * capabilities in its `compose` hook. The dependent names this package only in a type, which a bundler never
19
+ * sees.
20
+ */
21
+ export const leaderboardPeer = {
22
+ LeaderboardBoard,
23
+ leaderboardDatabase,
24
+ entryStore,
25
+ ALL_TIME_WINDOW,
26
+ windowKeyAt,
27
+ } as const;
28
+
29
+ /** The leaderboard's peer surface, by type — what `leaderboardPeer` holds. */
30
+ export type LeaderboardPeer = typeof leaderboardPeer;
@@ -13,4 +13,4 @@
13
13
  export const PACKAGE_NAME = "@pithy-sh/leaderboard";
14
14
 
15
15
  /** This package's version, stamped from its own package.json at generation time. */
16
- export const PACKAGE_VERSION = "0.2.5";
16
+ export const PACKAGE_VERSION = "0.2.6";