@pithy-sh/leaderboard 0.2.4 → 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.
- package/dist/capability.d.ts +7 -0
- package/dist/capability.d.ts.map +1 -1
- package/dist/capability.js +7 -2
- package/dist/peer.d.ts +49 -0
- package/dist/peer.d.ts.map +1 -0
- package/dist/peer.js +28 -0
- package/dist/version.generated.d.ts +1 -1
- package/dist/version.generated.js +1 -1
- package/package.json +2 -2
- package/src/capability.ts +14 -4
- package/src/peer.ts +30 -0
- package/src/version.generated.ts +1 -1
package/dist/capability.d.ts
CHANGED
|
@@ -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.
|
package/dist/capability.d.ts.map
CHANGED
|
@@ -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;
|
|
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"}
|
package/dist/capability.js
CHANGED
|
@@ -4,8 +4,9 @@ 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
|
-
import { PACKAGE_VERSION } from "./version.generated.js";
|
|
9
|
+
import { PACKAGE_NAME, PACKAGE_VERSION } from "./version.generated.js";
|
|
9
10
|
import { defineCapability } from "@pithy-sh/core/src/capability/capability";
|
|
10
11
|
//#region src/capability.ts
|
|
11
12
|
/**
|
|
@@ -37,6 +38,7 @@ function leaderboard(options = { boards: [] }) {
|
|
|
37
38
|
const capability = defineCapability({
|
|
38
39
|
name: "leaderboard",
|
|
39
40
|
version: PACKAGE_VERSION,
|
|
41
|
+
package: PACKAGE_NAME,
|
|
40
42
|
requiredBindings: [{
|
|
41
43
|
type: "d1",
|
|
42
44
|
name: "DB"
|
|
@@ -54,7 +56,10 @@ function leaderboard(options = { boards: [] }) {
|
|
|
54
56
|
}),
|
|
55
57
|
seeds: [leaderboardExampleSeed]
|
|
56
58
|
});
|
|
57
|
-
return Object.assign(capability, {
|
|
59
|
+
return Object.assign(capability, {
|
|
60
|
+
leaderboardConfig: resolved,
|
|
61
|
+
leaderboardPeer
|
|
62
|
+
});
|
|
58
63
|
}
|
|
59
64
|
function isLeaderboardCapability(capability) {
|
|
60
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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,8 +8,9 @@ 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
|
-
import { PACKAGE_VERSION } from "./version.generated";
|
|
13
|
+
import { PACKAGE_NAME, PACKAGE_VERSION } from "./version.generated";
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
* Where leaderboard's migrations sort in the app database. Unique per database; the registry composes
|
|
@@ -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
|
/**
|
|
@@ -55,9 +62,12 @@ export function leaderboard(options: LeaderboardOptions = { boards: [] }): Leade
|
|
|
55
62
|
|
|
56
63
|
const capability = defineCapability({
|
|
57
64
|
name: "leaderboard",
|
|
58
|
-
// The package
|
|
59
|
-
// cannot read its own package.json. Reported per capability by
|
|
65
|
+
// The package this capability ships in and the version it ships at, both stamped by
|
|
66
|
+
// `scripts/stampVersions.ts` — a Worker cannot read its own package.json. Reported per capability by
|
|
67
|
+
// the control-plane manifest, and reported together: a release feed is keyed by package name, so the
|
|
68
|
+
// version alone leaves a client guessing the key (#626).
|
|
60
69
|
version: PACKAGE_VERSION,
|
|
70
|
+
package: PACKAGE_NAME,
|
|
61
71
|
requiredBindings,
|
|
62
72
|
config: LeaderboardConfig,
|
|
63
73
|
databases: {
|
|
@@ -72,7 +82,7 @@ export function leaderboard(options: LeaderboardOptions = { boards: [] }): Leade
|
|
|
72
82
|
seeds: [leaderboardExampleSeed],
|
|
73
83
|
});
|
|
74
84
|
|
|
75
|
-
return Object.assign(capability, { leaderboardConfig: resolved });
|
|
85
|
+
return Object.assign(capability, { leaderboardConfig: resolved, leaderboardPeer });
|
|
76
86
|
}
|
|
77
87
|
|
|
78
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;
|
package/src/version.generated.ts
CHANGED