@hadoku/prefs-client 1.1.13 → 1.1.15
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/avatar.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { A as AvatarCosmetics, C as CosmeticsView, L as LoadoutUpdate } from './cosmetics-contract-
|
|
2
|
-
export { a as CosmeticSlot, b as Loadout, P as Placement } from './cosmetics-contract-
|
|
1
|
+
import { A as AvatarCosmetics, C as CosmeticsView, L as LoadoutUpdate } from './cosmetics-contract-CzRH-ZG0.js';
|
|
2
|
+
export { a as CosmeticSlot, b as Loadout, P as Placement } from './cosmetics-contract-CzRH-ZG0.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Avatars — the wire contract, shared by prefs-api and the client.
|
|
@@ -7,7 +7,11 @@
|
|
|
7
7
|
*
|
|
8
8
|
* Rules the catalogue keeps (operator, 2026-11-01; design:
|
|
9
9
|
* docs/planning/avatar-cosmetics-2026-11-02.md):
|
|
10
|
-
* -
|
|
10
|
+
* - Almost everything is free to everyone. Three items are earned, and kept for
|
|
11
|
+
* good once earned: Twinkle (bronze or better in a Major), Decode (silver or
|
|
12
|
+
* better) and the Crown (winning one). Never bought; no levels.
|
|
13
|
+
* - At most six items show per slot. The rest are archived (`hidden`): kept
|
|
14
|
+
* in the catalogue, shown to nobody but admins, and selectable by nobody.
|
|
11
15
|
* - One item per slot.
|
|
12
16
|
* - Name effects, gradients and message reveals derive every colour from the
|
|
13
17
|
* person's character colour. Overlays may bring their own (the crown is gold).
|
|
@@ -35,8 +39,13 @@ interface CosmeticItem {
|
|
|
35
39
|
id: string;
|
|
36
40
|
slot: CosmeticSlot;
|
|
37
41
|
label: string;
|
|
38
|
-
/**
|
|
39
|
-
|
|
42
|
+
/**
|
|
43
|
+
* How it is earned, as the inventory shows it to someone who has not.
|
|
44
|
+
* Absent: free, owned by everyone.
|
|
45
|
+
*/
|
|
46
|
+
earn?: string;
|
|
47
|
+
/** Archived: shown to nobody but admins, and selectable by nobody. */
|
|
48
|
+
hidden?: true;
|
|
40
49
|
art?: OverlayArt;
|
|
41
50
|
}
|
|
42
51
|
/**
|
|
@@ -47,6 +56,13 @@ interface CosmeticItem {
|
|
|
47
56
|
*/
|
|
48
57
|
declare const COSMETICS: readonly CosmeticItem[];
|
|
49
58
|
declare const COSMETICS_BY_ID: ReadonlyMap<string, CosmeticItem>;
|
|
59
|
+
/** Earned items: the only ones a grant can give. */
|
|
60
|
+
declare const EARNED_COSMETICS: readonly CosmeticItem[];
|
|
61
|
+
/**
|
|
62
|
+
* What a person can wear: every visible free item, and the earned items they
|
|
63
|
+
* were granted. A grant of an archived item gives nothing.
|
|
64
|
+
*/
|
|
65
|
+
declare function ownedFrom(granted: Iterable<string>): Set<string>;
|
|
50
66
|
/**
|
|
51
67
|
* A person's adjustment of an overlay image, relative to its default spot:
|
|
52
68
|
* x/y in % of the avatar's size, r in degrees, s in % of the default size.
|
|
@@ -116,9 +132,17 @@ interface AvatarCosmetics {
|
|
|
116
132
|
message?: string;
|
|
117
133
|
placement?: Placement;
|
|
118
134
|
}
|
|
135
|
+
/**
|
|
136
|
+
* What someone wears, as an app relays it over its own wire (a room's presence),
|
|
137
|
+
* made safe to render: known, shown items in their own slots only, and the
|
|
138
|
+
* placement refitted to the allowed area. Ownership was decided by prefs-api,
|
|
139
|
+
* which only ever serves what a person owns; this guards the shape, not the
|
|
140
|
+
* inventory. Undefined when nothing valid is worn.
|
|
141
|
+
*/
|
|
142
|
+
declare function cleanWorn(raw: unknown): AvatarCosmetics | undefined;
|
|
119
143
|
/** In AvatarSettings: what the owner has earned and what they wear. */
|
|
120
144
|
interface CosmeticsView {
|
|
121
|
-
/**
|
|
145
|
+
/** What the person can wear: free items and the earned ones granted, in catalogue order. */
|
|
122
146
|
owned: string[];
|
|
123
147
|
loadout: Loadout;
|
|
124
148
|
}
|
|
@@ -155,4 +179,4 @@ interface CosmeticGrantList {
|
|
|
155
179
|
}[];
|
|
156
180
|
}
|
|
157
181
|
|
|
158
|
-
export { type AvatarCosmetics as A, type Box as B, type CosmeticsView as C, type LoadoutUpdate as L, type OverlayArt as O, type Placement as P, type CosmeticSlot as a, type Loadout as b, COSMETICS as c, COSMETICS_BY_ID as d, COSMETIC_ID_PATTERN as e, COSMETIC_SLOTS as f, type CosmeticGrantList as g, type CosmeticGrantRequest as h, type CosmeticItem as i, PLACEMENT_DEFAULT as j, PLACEMENT_LIMITS as k, PLACEMENT_ZONE as l, cleanLoadout as m,
|
|
182
|
+
export { type AvatarCosmetics as A, type Box as B, type CosmeticsView as C, EARNED_COSMETICS as E, type LoadoutUpdate as L, type OverlayArt as O, type Placement as P, type CosmeticSlot as a, type Loadout as b, COSMETICS as c, COSMETICS_BY_ID as d, COSMETIC_ID_PATTERN as e, COSMETIC_SLOTS as f, type CosmeticGrantList as g, type CosmeticGrantRequest as h, type CosmeticItem as i, PLACEMENT_DEFAULT as j, PLACEMENT_LIMITS as k, PLACEMENT_ZONE as l, cleanLoadout as m, cleanWorn as n, emptyLoadout as o, fitPlacement as p, overlayBounds as q, ownedFrom as r, wornCosmetics as w };
|
package/dist/cosmetics.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { A as AvatarCosmetics, P as Placement } from './cosmetics-contract-
|
|
2
|
-
export { B as Box, c as COSMETICS, d as COSMETICS_BY_ID, e as COSMETIC_ID_PATTERN, f as COSMETIC_SLOTS, g as CosmeticGrantList, h as CosmeticGrantRequest, i as CosmeticItem, a as CosmeticSlot, C as CosmeticsView, b as Loadout, L as LoadoutUpdate, O as OverlayArt, j as PLACEMENT_DEFAULT, k as PLACEMENT_LIMITS, l as PLACEMENT_ZONE, m as cleanLoadout, n as
|
|
1
|
+
import { A as AvatarCosmetics, P as Placement } from './cosmetics-contract-CzRH-ZG0.js';
|
|
2
|
+
export { B as Box, c as COSMETICS, d as COSMETICS_BY_ID, e as COSMETIC_ID_PATTERN, f as COSMETIC_SLOTS, g as CosmeticGrantList, h as CosmeticGrantRequest, i as CosmeticItem, a as CosmeticSlot, C as CosmeticsView, E as EARNED_COSMETICS, b as Loadout, L as LoadoutUpdate, O as OverlayArt, j as PLACEMENT_DEFAULT, k as PLACEMENT_LIMITS, l as PLACEMENT_ZONE, m as cleanLoadout, n as cleanWorn, o as emptyLoadout, p as fitPlacement, q as overlayBounds, r as ownedFrom, w as wornCosmetics } from './cosmetics-contract-CzRH-ZG0.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Avatar cosmetics — the renderer every app uses, so a name, an avatar and a
|
package/dist/cosmetics.js
CHANGED
|
@@ -1,79 +1,101 @@
|
|
|
1
1
|
// src/cosmetics-contract.ts
|
|
2
2
|
var COSMETIC_SLOTS = ["effect", "gradient", "font", "overlay", "message"];
|
|
3
3
|
var COSMETIC_ID_PATTERN = /^(effect|gradient|font|overlay|message)\.[a-z0-9-]{1,32}$/;
|
|
4
|
-
var item = (slot, name, label,
|
|
4
|
+
var item = (slot, name, label, opts = {}) => ({ id: `${slot}.${name}`, slot, label, ...opts });
|
|
5
|
+
var archived = { hidden: true };
|
|
5
6
|
var COSMETICS = [
|
|
6
|
-
item("effect", "glint", "Glint"
|
|
7
|
-
item("effect", "aura", "Aura"
|
|
8
|
-
item("effect", "hop", "Hop"
|
|
9
|
-
item("effect", "outline", "Outline"
|
|
10
|
-
item("effect", "twinkle", "Twinkle", "
|
|
11
|
-
item("gradient", "gild", "Gilded"
|
|
12
|
-
item("gradient", "gloss", "Gloss"
|
|
13
|
-
item("gradient", "split", "Split"
|
|
14
|
-
item("gradient", "brushed", "Brushed"
|
|
15
|
-
item("gradient", "lumen", "Lumen"
|
|
16
|
-
item("font", "
|
|
17
|
-
item("font", "
|
|
18
|
-
item("font", "
|
|
19
|
-
item("font", "
|
|
20
|
-
item("font", "
|
|
21
|
-
item("font", "
|
|
22
|
-
item("font", "
|
|
23
|
-
item("font", "
|
|
24
|
-
item("font", "
|
|
25
|
-
item("font", "
|
|
26
|
-
item("font", "
|
|
27
|
-
item("font", "
|
|
28
|
-
item("font", "
|
|
29
|
-
item("font", "pixel", "Pixel",
|
|
30
|
-
item("overlay", "crown", "Crown",
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
7
|
+
item("effect", "glint", "Glint"),
|
|
8
|
+
item("effect", "aura", "Aura"),
|
|
9
|
+
item("effect", "hop", "Hop"),
|
|
10
|
+
item("effect", "outline", "Outline"),
|
|
11
|
+
item("effect", "twinkle", "Twinkle", { earn: "Bronze or better in a Major" }),
|
|
12
|
+
item("gradient", "gild", "Gilded"),
|
|
13
|
+
item("gradient", "gloss", "Gloss"),
|
|
14
|
+
item("gradient", "split", "Split"),
|
|
15
|
+
item("gradient", "brushed", "Brushed"),
|
|
16
|
+
item("gradient", "lumen", "Lumen"),
|
|
17
|
+
item("font", "script", "Script"),
|
|
18
|
+
item("font", "surf", "Surf"),
|
|
19
|
+
item("font", "gothic", "Gothic"),
|
|
20
|
+
item("font", "runic", "Runic"),
|
|
21
|
+
item("font", "arcade", "Arcade"),
|
|
22
|
+
item("font", "caps", "Small caps", archived),
|
|
23
|
+
item("font", "wide", "Wide", archived),
|
|
24
|
+
item("font", "corsair", "Corsair", archived),
|
|
25
|
+
item("font", "metal", "Metal", archived),
|
|
26
|
+
item("font", "comic", "Comic", archived),
|
|
27
|
+
item("font", "circuit", "Circuit", archived),
|
|
28
|
+
item("font", "hover", "Hover", archived),
|
|
29
|
+
item("font", "retro", "Retro", archived),
|
|
30
|
+
item("font", "pixel", "Pixel", archived),
|
|
31
|
+
item("overlay", "crown", "Crown", {
|
|
32
|
+
earn: "Win a Major",
|
|
33
|
+
art: {
|
|
34
|
+
file: "crown.webp",
|
|
35
|
+
top: -40,
|
|
36
|
+
width: 70,
|
|
37
|
+
tilt: -8,
|
|
38
|
+
pixel: false,
|
|
39
|
+
visible: [0.027, 0.137, 0.973, 0.863]
|
|
40
|
+
}
|
|
37
41
|
}),
|
|
38
|
-
item("overlay", "halo", "Halo",
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
item("overlay", "halo", "Halo", {
|
|
43
|
+
art: {
|
|
44
|
+
file: "halo.webp",
|
|
45
|
+
top: -34,
|
|
46
|
+
width: 76,
|
|
47
|
+
tilt: 0,
|
|
48
|
+
pixel: true,
|
|
49
|
+
visible: [0.033, 0.333, 0.967, 0.667]
|
|
50
|
+
}
|
|
45
51
|
}),
|
|
46
|
-
item("overlay", "
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
52
|
+
item("overlay", "flowers", "Flower crown", {
|
|
53
|
+
art: {
|
|
54
|
+
file: "flowers.webp",
|
|
55
|
+
top: -22,
|
|
56
|
+
width: 96,
|
|
57
|
+
tilt: 0,
|
|
58
|
+
pixel: false,
|
|
59
|
+
visible: [0.027, 0.258, 0.969, 0.746]
|
|
60
|
+
}
|
|
53
61
|
}),
|
|
54
|
-
item("overlay", "
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
62
|
+
item("overlay", "petals", "Petals"),
|
|
63
|
+
item("overlay", "horns", "Horns", {
|
|
64
|
+
...archived,
|
|
65
|
+
art: {
|
|
66
|
+
file: "horns.webp",
|
|
67
|
+
top: -26,
|
|
68
|
+
width: 100,
|
|
69
|
+
tilt: 0,
|
|
70
|
+
pixel: true,
|
|
71
|
+
visible: [0.033, 0.133, 0.967, 0.867]
|
|
72
|
+
}
|
|
61
73
|
}),
|
|
62
|
-
item("overlay", "runes", "Runes",
|
|
63
|
-
item("overlay", "comet", "Comet",
|
|
64
|
-
item("overlay", "shine", "Shine",
|
|
65
|
-
item("overlay", "glow", "Glow",
|
|
66
|
-
item("
|
|
67
|
-
item("message", "
|
|
68
|
-
item("message", "
|
|
69
|
-
item("message", "
|
|
70
|
-
item("message", "
|
|
71
|
-
item("message", "
|
|
72
|
-
item("message", "drift", "Drift", "Attend 20 watchparties")
|
|
74
|
+
item("overlay", "runes", "Runes", archived),
|
|
75
|
+
item("overlay", "comet", "Comet", archived),
|
|
76
|
+
item("overlay", "shine", "Shine", archived),
|
|
77
|
+
item("overlay", "glow", "Glow", archived),
|
|
78
|
+
item("message", "type", "Typewriter"),
|
|
79
|
+
item("message", "decode", "Decode", { earn: "Silver or better in a Major" }),
|
|
80
|
+
item("message", "cascade", "Cascade"),
|
|
81
|
+
item("message", "words", "Word by word"),
|
|
82
|
+
item("message", "bubble", "Bubble", archived),
|
|
83
|
+
item("message", "drift", "Drift")
|
|
73
84
|
];
|
|
74
85
|
var COSMETICS_BY_ID = new Map(
|
|
75
86
|
COSMETICS.map((i) => [i.id, i])
|
|
76
87
|
);
|
|
88
|
+
var EARNED_COSMETICS = COSMETICS.filter(
|
|
89
|
+
(i) => i.earn !== void 0 && !i.hidden
|
|
90
|
+
);
|
|
91
|
+
function ownedFrom(granted) {
|
|
92
|
+
const out = new Set(COSMETICS.filter((i) => !i.hidden && i.earn === void 0).map((i) => i.id));
|
|
93
|
+
for (const id of granted) {
|
|
94
|
+
const it = COSMETICS_BY_ID.get(id);
|
|
95
|
+
if (it && !it.hidden) out.add(id);
|
|
96
|
+
}
|
|
97
|
+
return out;
|
|
98
|
+
}
|
|
77
99
|
var PLACEMENT_DEFAULT = { x: 0, y: 0, r: 0, s: 100, flip: false, back: false };
|
|
78
100
|
var PLACEMENT_LIMITS = {
|
|
79
101
|
x: [-60, 60],
|
|
@@ -157,18 +179,35 @@ function emptyLoadout() {
|
|
|
157
179
|
placement: {}
|
|
158
180
|
};
|
|
159
181
|
}
|
|
182
|
+
function cleanWorn(raw) {
|
|
183
|
+
if (!raw || typeof raw !== "object") return void 0;
|
|
184
|
+
const src = raw;
|
|
185
|
+
const worn = {};
|
|
186
|
+
for (const slot of COSMETIC_SLOTS) {
|
|
187
|
+
const id = src[slot];
|
|
188
|
+
const it = typeof id === "string" ? COSMETICS_BY_ID.get(id) : void 0;
|
|
189
|
+
if (it && !it.hidden && it.slot === slot) worn[slot] = it.id;
|
|
190
|
+
}
|
|
191
|
+
const art = worn.overlay ? COSMETICS_BY_ID.get(worn.overlay)?.art : void 0;
|
|
192
|
+
if (art && src.placement && typeof src.placement === "object") {
|
|
193
|
+
worn.placement = fitPlacement(art, src.placement);
|
|
194
|
+
}
|
|
195
|
+
return Object.keys(worn).length ? worn : void 0;
|
|
196
|
+
}
|
|
160
197
|
function cleanLoadout(raw, owned) {
|
|
161
198
|
const out = emptyLoadout();
|
|
162
199
|
const src = raw && typeof raw === "object" ? raw : {};
|
|
163
200
|
for (const slot of COSMETIC_SLOTS) {
|
|
164
201
|
const id = src.equipped?.[slot];
|
|
165
|
-
|
|
166
|
-
|
|
202
|
+
const it = typeof id === "string" ? COSMETICS_BY_ID.get(id) : void 0;
|
|
203
|
+
if (it && !it.hidden && owned.has(it.id) && it.slot === slot) {
|
|
204
|
+
out.equipped[slot] = it.id;
|
|
167
205
|
}
|
|
168
206
|
}
|
|
169
207
|
for (const [id, p] of Object.entries(src.placement ?? {})) {
|
|
170
|
-
const
|
|
171
|
-
|
|
208
|
+
const it = COSMETICS_BY_ID.get(id);
|
|
209
|
+
const art = it?.art;
|
|
210
|
+
if (art && !it.hidden && owned.has(id) && p && typeof p === "object") {
|
|
172
211
|
out.placement[id] = fitPlacement(art, p);
|
|
173
212
|
}
|
|
174
213
|
}
|
|
@@ -480,11 +519,13 @@ export {
|
|
|
480
519
|
COSMETICS_BY_ID,
|
|
481
520
|
COSMETIC_ID_PATTERN,
|
|
482
521
|
COSMETIC_SLOTS,
|
|
522
|
+
EARNED_COSMETICS,
|
|
483
523
|
PLACEMENT_DEFAULT,
|
|
484
524
|
PLACEMENT_LIMITS,
|
|
485
525
|
PLACEMENT_ZONE,
|
|
486
526
|
avatarHtml,
|
|
487
527
|
cleanLoadout,
|
|
528
|
+
cleanWorn,
|
|
488
529
|
colourStyle,
|
|
489
530
|
cosmeticsCss,
|
|
490
531
|
decorHtml,
|
|
@@ -494,6 +535,7 @@ export {
|
|
|
494
535
|
messageHtml,
|
|
495
536
|
nameHtml,
|
|
496
537
|
overlayBounds,
|
|
538
|
+
ownedFrom,
|
|
497
539
|
placementTransform,
|
|
498
540
|
wornCosmetics
|
|
499
541
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hadoku/prefs-client",
|
|
3
|
-
"version": "1.1.
|
|
4
|
-
"gitHead": "
|
|
3
|
+
"version": "1.1.15",
|
|
4
|
+
"gitHead": "bdf1c74cc458107cf5cb7a427fbfc319cb5f5b95",
|
|
5
5
|
"description": "Client SDK for the hadoku unified preferences store. Wraps /prefs/api/v1/* with localStorage caching, debounced writes, Zod-validated reads, and a usePrefs() React hook, plus match history, ratings and leaderboards for every game (./games), the one resolved avatar per user (./avatar), and the avatar cosmetics renderer (./cosmetics).",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "./dist/index.js",
|