Última actividad 2 weeks ago

nuno revisó este gist 2 weeks ago. Ir a la revisión

1 file changed, 100 insertions

gistfile1.txt(archivo creado)

@@ -0,0 +1,100 @@
1 + /**
2 + * CharacterRegistry — central lookup for Character objects.
3 + *
4 + * Usage:
5 + * import { CharacterRegistry } from "@registry/CharacterRegistry";
6 + *
7 + * const char = CharacterRegistry.find("«Flash»");
8 + * const chars = CharacterRegistry.forUser("flash");
9 + * const active = CharacterRegistry.getActive("flash");
10 + */
11 +
12 + import fs from "fs";
13 + import path from "path";
14 + import { Character, UserKey, CharName } from "@types";
15 + import { Paths } from "@helpers/paths";
16 +
17 + const CHARS_PATH = Paths.data("characters.json");
18 +
19 + let _cache: Record<string, { characters: Character[] }> | null = null;
20 +
21 + function loadChars(): Record<string, { characters: Character[] }> {
22 + if (!_cache) {
23 + try {
24 + _cache = JSON.parse(fs.readFileSync(CHARS_PATH, "utf8"));
25 + console.log("[CharacterRegistry] cache miss — loading from disk");
26 + }
27 + catch { _cache = {}; }
28 + }
29 +
30 + return _cache!;
31 + }
32 +
33 + export const CharacterRegistry = {
34 + /**
35 + * Find a character by name across all users.
36 + * Character names are unique across users (enforced by conflict system).
37 + */
38 + find(charName: CharName): Character | null {
39 + const chars = loadChars();
40 + for (const data of Object.values(chars)) {
41 + const found = data.characters?.find(
42 + (c) => c.name.toLowerCase() === charName.toLowerCase()
43 + );
44 + if (found) return found;
45 + }
46 + return null;
47 + },
48 +
49 + all(): Character[] {
50 + const chars = loadChars();
51 + return Object.values(chars).flatMap((data: any) => data.characters ?? []);
52 + },
53 +
54 + /**
55 + * Find a character by name for a specific user.
56 + */
57 + findForUser(userKey: UserKey, charName: CharName): Character | null {
58 + const chars = loadChars();
59 + return chars[userKey]?.characters?.find(
60 + (c) => c.name.toLowerCase() === charName.toLowerCase()
61 + ) ?? null;
62 + },
63 +
64 + /**
65 + * Get all characters for a user.
66 + */
67 + forUser(userKey: UserKey): Character[] {
68 + const chars = loadChars();
69 + return chars[userKey]?.characters ?? [];
70 + },
71 +
72 + /**
73 + * Get the active character for a user (from characters.json only, no borrow).
74 + * For effective char (including borrows), use getEffectiveCharacter from borrow.ts.
75 + */
76 + getActive(userKey: UserKey): Character | null {
77 + return CharacterRegistry.forUser(userKey).find((c) => c.active) ?? null;
78 + },
79 +
80 + /**
81 + * Get all characters shared with a given user across all owners.
82 + */
83 + sharedWith(userKey: UserKey): { char: Character; ownerKey: UserKey }[] {
84 + const chars = loadChars();
85 + const result: { char: Character; ownerKey: UserKey }[] = [];
86 + for (const [ownerKey, data] of Object.entries(chars)) {
87 + if (ownerKey === userKey) continue;
88 + for (const char of data.characters ?? []) {
89 + if (char.sharedWith?.includes(userKey)) {
90 + result.push({ char, ownerKey });
91 + }
92 + }
93 + }
94 + return result;
95 + },
96 +
97 + invalidateCache(): void {
98 + _cache = null;
99 + },
100 + };
Siguiente Anterior