wuira 0.1.5 → 0.1.7

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 (63) hide show
  1. package/CHANGELOG.md +70 -1
  2. package/README.md +242 -0
  3. package/lib/Spells.d.ts +11 -0
  4. package/lib/Spells.lua +22 -0
  5. package/lib/datasources/KnownSpells.d.ts +21 -0
  6. package/lib/datasources/KnownSpells.lua +794 -0
  7. package/lib/datasources/ManaRegenTimer.d.ts +29 -0
  8. package/lib/datasources/ManaRegenTimer.lua +674 -0
  9. package/lib/datasources/ProgressSource.lua +15 -2
  10. package/lib/datasources/Resources.d.ts +13 -1
  11. package/lib/datasources/Resources.lua +118 -39
  12. package/lib/datasources/SpellCooldown.d.ts +4 -2
  13. package/lib/datasources/SpellCooldown.lua +13 -2
  14. package/lib/datasources/SpellSource.d.ts +14 -0
  15. package/lib/datasources/SpellSource.lua +224 -0
  16. package/lib/datasources/TimerSource.d.ts +2 -0
  17. package/lib/datasources/TimerSource.lua +54 -0
  18. package/lib/datasources/TotemTimer.d.ts +10 -0
  19. package/lib/datasources/TotemTimer.lua +260 -0
  20. package/lib/datasources/index.d.ts +7 -0
  21. package/lib/datasources/index.lua +16 -0
  22. package/lib/index.d.ts +8 -0
  23. package/lib/index.lua +16 -0
  24. package/lib/platform/ActionBars.d.ts +27 -0
  25. package/lib/platform/ActionBars.lua +726 -0
  26. package/lib/platform/AddonSettings.d.ts +9 -0
  27. package/lib/platform/AddonSettings.lua +36 -0
  28. package/lib/platform/BlizzardUI.d.ts +5 -0
  29. package/lib/platform/BlizzardUI.lua +357 -20
  30. package/lib/platform/MicroMenu.d.ts +15 -0
  31. package/lib/platform/MicroMenu.lua +219 -0
  32. package/lib/platform/SecureButton.d.ts +5 -0
  33. package/lib/platform/SecureButton.lua +196 -0
  34. package/lib/platform/SlashCommands.d.ts +3 -0
  35. package/lib/platform/SlashCommands.lua +309 -0
  36. package/lib/platform/forever.d.ts +78 -3
  37. package/lib/skins/MicroBar.d.ts +8 -0
  38. package/lib/skins/MicroBar.lua +65 -0
  39. package/lib/skins/NativeSkin.d.ts +26 -0
  40. package/lib/skins/NativeSkin.lua +601 -0
  41. package/lib/skins/index.d.ts +3 -0
  42. package/lib/skins/index.lua +11 -0
  43. package/lib/store/index.lua +13 -0
  44. package/lib/ui/Button.d.ts +10 -0
  45. package/lib/ui/Button.lua +9 -0
  46. package/lib/ui/Cell.d.ts +5 -1
  47. package/lib/ui/FrameMover.d.ts +21 -0
  48. package/lib/ui/FrameMover.lua +123 -0
  49. package/lib/ui/HoverTracker.d.ts +20 -0
  50. package/lib/ui/HoverTracker.lua +88 -0
  51. package/lib/ui/KeybindCapture.d.ts +20 -0
  52. package/lib/ui/KeybindCapture.lua +488 -0
  53. package/lib/ui/SecureButton.d.ts +44 -0
  54. package/lib/ui/SecureButton.lua +9 -0
  55. package/lib/ui/index.d.ts +9 -0
  56. package/lib/ui/index.lua +20 -0
  57. package/lib/ui/layout/measureLayout.lua +4 -2
  58. package/lib/ui/mount.lua +500 -117
  59. package/lib/ui/primitives/jsx.d.ts +9 -1
  60. package/lib/wuira.d.ts +3 -0
  61. package/lib/wuira.lua +5 -0
  62. package/package.json +8 -1
  63. package/tools/build-library.mjs +1 -1
package/CHANGELOG.md CHANGED
@@ -7,7 +7,76 @@ with the release date and highlight breaking changes explicitly.
7
7
 
8
8
  ## Unreleased
9
9
 
10
- No changes yet.
10
+ ## 0.1.7 — 2026-10-14
11
+
12
+ ### Added
13
+
14
+ - README AI disclosure describing AI assistance, line-by-line code review,
15
+ release validation, and maintainer responsibility.
16
+
17
+ ## 0.1.6 — 2026-10-14
18
+
19
+ ### Added
20
+
21
+ - `wuira.registerCommand("/command", callback)` registers native slash commands,
22
+ passes parsed arguments as `(...args: string[])` and returns idempotent cleanup.
23
+ Quoted arguments preserve spaces and empty values. Names are case-insensitive;
24
+ existing commands are preserved and native hash/proxy entries are cleaned up.
25
+ - Native `AddonSettings` canvas registration, normal JSX `Button` controls and
26
+ Cell `onMount` lifecycle callbacks with cleanup.
27
+ - Generic `FrameMover` drag proxies and `KeybindCapture` hover-to-bind overlays.
28
+ Both stop editing in combat; protected actions remain configured outside combat.
29
+ - `KnownSpells` caches learned player spellbook IDs, with rank-aware `Has`,
30
+ event-driven `onChange` subscriptions and disposal. World entry, level,
31
+ training and talent events refresh the list; reading it never polls the book.
32
+ - `Cell.alpha` accepts fixed opacity or a live visual callback, including on
33
+ secure buttons. Opacity updates do not enable, disable or rewrite actions.
34
+ - Named `Spells.HolyShock` and `Spells.Exorcism` identifiers.
35
+ - Named Paladin utility spell identifiers: Divine Favor, Lay on Hands, Blessing
36
+ of Protection, Blessing of Freedom, Voice of Truth, and Hammer of Justice.
37
+ - `TotemTimer` reads player-owned ground effects by spell ID or localized name,
38
+ matching ranks and passing opaque native durations directly to progress bars.
39
+ Restricted effect identities are not inspected or guessed.
40
+ - `SecureButton`, a Cell-compatible JSX primitive backed by Forever's native
41
+ `SecureActionButtonTemplate`. Supports static spell, item, existing macro,
42
+ action-slot and target actions, a selected mouse button, and one visual child.
43
+ Native click handlers are preserved; actions execute on mouse release.
44
+ Protected trees must mount outside combat; visibility and unmount are deferred
45
+ until combat ends. Click-cast presets are not included yet.
46
+ - Secure buttons accept temporary `binding` overrides with native key labels,
47
+ radial `cooldown` sources and a native completion flash through `finishGlow`.
48
+ Overrides are removed on unmount without changing saved key bindings.
49
+ - `SpellSource` exposes localized secure actions, textures and cooldowns that
50
+ ignore the global cooldown. Added Judgement, Holy Strike and Consecration IDs.
51
+ - `BlizzardUI.SkinMicroMenu()` styles Forever's existing micro menu with a flat
52
+ panel, muted icons and accent highlights. Native click handlers, tooltips,
53
+ notifications and layout remain owned by the game; styling waits during combat.
54
+ - `wuira/skins` with `MicroBar` and a shared `NativeSkin` adapter. `render` receives
55
+ the adapter, including `mount(view, anchor)` and `OnHover`; custom mounts are
56
+ disposed with the skin without replacing native button scripts.
57
+ - Generic `HoverTracker` secure trigger/popup frames, configurable auto-hide delay
58
+ and extra hover regions. Addons own layout, launcher presentation and themes.
59
+ - Explicit action-slot capture/clear/restore APIs and opt-in empty native bars.
60
+ New backups require a manual reload before the explicit clear command. Native bar
61
+ descendants, event/update managers, and action UI registrations are disabled;
62
+ suppression runs independently of slot operations. Clear/restore never run
63
+ from world-entry or cursor events; refused calls are reported without automatic
64
+ retries. A restore command re-enables the stock UI after manual reload. No replacement bar
65
+ is created. Unsupported action types and conflicting restores are rejected.
66
+ - Resource `onChange` subscriptions with unsubscribe callbacks. Widgets and
67
+ observers share one lazy native event listener per resource, reading its
68
+ current value once per event. Secret amounts never reach user callbacks.
69
+ - `Mana.UseRegenTimer()` and its `RegenTimer` accessory: a cast-driven five-second
70
+ window followed by estimated two-second sweeps kept alive by mana events.
71
+ Full readable mana stops the clock; native alpha curves mask full secret mana.
72
+ Unmount cancels timers and detaches the accessory without stopping other users.
73
+
74
+ ### Fixed
75
+
76
+ - Preserve saved entries in initially empty Store records when loading a new
77
+ registry; Lua's empty-table ambiguity no longer resets custom binding maps.
78
+ - Honor explicit non-top-left anchors on a Cell's child, allowing thin overlays
79
+ to sit on the bottom edge of a progress bar.
11
80
 
12
81
  ## 0.1.5 — 2026-10-14
13
82
 
package/README.md CHANGED
@@ -142,6 +142,241 @@ overlays require the native health scale, so min/max/current overrides are rejec
142
142
  Prediction reads pause while the parent HP condition is inactive. The renderer
143
143
  cleans up the overlays and resource subscriptions on unmount.
144
144
 
145
+ ### Slash commands
146
+
147
+ ```ts
148
+ import { wuira } from "wuira";
149
+
150
+ const unregister = wuira.registerCommand("/myaddon", (...args: string[]) => {
151
+ console.log("Arguments:", ...args);
152
+ });
153
+
154
+ // /myaddon arg1 arg2 arg3 passes three string arguments.
155
+ // /myaddon alone calls the callback with no arguments.
156
+ // Call unregister() when the command is no longer needed.
157
+ ```
158
+
159
+ Command names start with a slash and a letter, followed by letters, digits,
160
+ underscores or hyphens. Names are case-insensitive and cannot replace an existing
161
+ command. Register aliases separately with the same callback.
162
+
163
+ Arguments are separated by whitespace and retain their case. Single or double
164
+ quotes group words into one argument; `""` passes an empty string. Within quotes,
165
+ a backslash can escape the matching quote or another backslash. An unclosed quote
166
+ reports an error without calling the callback. Argument counts are unrestricted;
167
+ validate required arguments inside your callback.
168
+
169
+ ### Addon settings and editing tools
170
+
171
+ Register a normal JSX view in Forever's native addon settings list:
172
+
173
+ ```tsx
174
+ import { UI, AddonSettings } from "wuira";
175
+ import { FlowLayout, Button, Label } from "wuira/ui";
176
+
177
+ const settings = new AddonSettings("MyAddon", () => (
178
+ <FlowLayout width={560} height={300} padding={20} gap={12}>
179
+ <Label height={28} text="MyAddon settings" />
180
+ <Button width={180} height={32} onClick={() => console.log("Settings opened")}>
181
+ <Label text="Example control" align="CENTER" />
182
+ </Button>
183
+ </FlowLayout>
184
+ ));
185
+ settings.Open();
186
+ ```
187
+
188
+ `Cell.onMount` receives the configured native frame and may return an unmount
189
+ cleanup. `FrameMover` provides a drag proxy with screen-center coordinates
190
+ (positive y down). `KeybindCapture` provides hover-to-bind overlays, modifier keys,
191
+ Delete/Backspace clearing, and an Escape callback. These tools stop editing in
192
+ combat. Addons own mode controls, saved positions, binding conflict policy and
193
+ rebuilding protected buttons outside combat.
194
+
195
+ ### Learned spells
196
+
197
+ `KnownSpells` keeps a cached snapshot of learned player spellbook IDs. It refreshes
198
+ on world entry, level, training and talent events without polling. Named entries
199
+ in `Spells` are numeric IDs; `Has` also matches a representative ID against learned
200
+ ranks by localized name. Future and inactive-spec spellbook entries are excluded.
201
+
202
+ ```ts
203
+ import { Spells } from "wuira";
204
+ import { KnownSpells } from "wuira/datasources";
205
+
206
+ const known = new KnownSpells();
207
+ const spellIds = known.Value; // readonly number[], read from the cache
208
+ const canJudge = known.Has(Spells.Judgement);
209
+ const stop = known.onChange(ids => console.log("Learned spells:", ids.length));
210
+ // On disposal: stop(); known.Dispose();
211
+ ```
212
+
213
+ Protected button trees must be rebuilt outside combat; applications can defer a
214
+ changed selection until `PLAYER_REGEN_ENABLED`. `Cell.alpha` changes appearance
215
+ without changing a button's protected action or its interaction state.
216
+
217
+ ### Empty native action bars
218
+
219
+ This is opt-in and removes real action-slot assignments, not just their visuals.
220
+ Declare a character-specific backup variable in the addon's TOC:
221
+
222
+ ```text
223
+ ## SavedVariablesPerCharacter: MyAddonActionBarBackup
224
+ ```
225
+
226
+ ```ts
227
+ import { ActionBars } from "wuira";
228
+
229
+ ActionBars.InstallEmptyMode({
230
+ addon: "MyAddon",
231
+ variable: "MyAddonActionBarBackup",
232
+ clearCommand: "/myaddonclearbars",
233
+ restoreCommand: "/myaddonrestorebars",
234
+ });
235
+ ```
236
+
237
+ The first world entry captures supported spell, item, and macro assignments.
238
+ Use `/reload` to persist a new backup, then `/myaddonclearbars` outside combat to
239
+ clear the 180 action slots used by the installed Forever implementation. Slot
240
+ changes run directly from the command, never from world-entry or cursor events.
241
+ Independently, initialization hides stock bars, removes their descendant event/update handlers, disables their
242
+ shared action-bar event managers, and detaches native action UI registrations.
243
+ It does not create a replacement bar or remove key-binding assignments.
244
+ Changes wait until combat ends, and a busy cursor blocks slot changes.
245
+
246
+ The restore command puts assignments back into empty or identical slots. Use
247
+ `/reload` afterwards to restore native handlers and visibility. The stock bars
248
+ remain enabled on future loads. A refused slot operation leaves bar suppression
249
+ active and is not automatically retried. Blocked/forbidden native calls report
250
+ their API name in the local console; command execution does not bypass client restrictions.
251
+ Unsupported action types, secret slot data, uncovered assignments, and conflicting
252
+ restores stop the operation. `Capture()`, `Clear(backup)`, and `Restore(backup)` are
253
+ also available for applications that manage their own persistence and lifecycle.
254
+
255
+ ### Secure action buttons
256
+
257
+ `SecureButton` extends Cell's descriptor and props, including size, positioning,
258
+ decorations and one child. Mount it like any other component:
259
+
260
+ ```tsx
261
+ import { UI, wuira } from "wuira";
262
+ import { SecureButton, Label } from "wuira/ui";
263
+
264
+ wuira.Mount(() => (
265
+ <SecureButton width={80} height={24}
266
+ action={{ type: "spell", spell: 635, unit: "player" }}>
267
+ <Label text="Holy Light" align="CENTER" />
268
+ </SecureButton>
269
+ ));
270
+ ```
271
+
272
+ Supported actions are `{ type: "spell", spell, unit? }`,
273
+ `{ type: "item", item, unit? }`, `{ type: "macro", macro }`,
274
+ `{ type: "action", slot, unit? }` and `{ type: "target", unit }`.
275
+ Spell and macro references accept IDs/indices or names. Items accept an ID
276
+ (converted to `item:ID`) or the native item string. Macros refer to existing
277
+ game macros, not arbitrary Lua callbacks or generated macro text.
278
+
279
+ The default is left-button release; `button="RightButton"` selects another
280
+ button. Secure buttons always receive mouse input, while visual children remain
281
+ click-through by default. Omitting `action` creates an inert secure button.
282
+
283
+ Actions and units are static mount-time attributes. Changing the descriptor
284
+ later does not rewrite them. Mounting a protected tree during combat raises an
285
+ error before any frame is created. Visibility changes and unmount requests wait
286
+ until combat ends, including changes to ancestors containing secure buttons.
287
+ Click-cast presets are not provided by this primitive yet. The native action mapping
288
+ follows [Forever's secure templates](https://github.com/Gethe/wow-ui-source/blob/forever/Interface/AddOns/Blizzard_FrameXML/SecureTemplates.lua).
289
+
290
+ For an icon action with a radial cooldown and temporary key binding:
291
+
292
+ ```tsx
293
+ import { Spells } from "wuira";
294
+ import { SpellSource } from "wuira/datasources";
295
+ import { Icon } from "wuira/ui";
296
+
297
+ const judgement = new SpellSource(Spells.Judgement);
298
+ const button = (
299
+ <SecureButton width={40} height={40} action={judgement.Action}
300
+ binding="1" cooldown={judgement.Cooldown} finishGlow>
301
+ <Icon textureSource={judgement.Texture} />
302
+ </SecureButton>
303
+ );
304
+ ```
305
+
306
+ `binding` temporarily routes the key to this native button and adds its label;
307
+ `showHotkey={false}` suppresses the label. Unmount removes the override and leaves
308
+ saved bindings intact. The radial widget owns countdown timing and the short
309
+ completion flash, including opaque combat durations. `SpellSource.Cooldown`
310
+ ignores the GCD so unrelated casts do not trigger a completion flash.
311
+
312
+ ### Native skins
313
+
314
+ Skin Forever's existing character, professions, spellbook and other micro-menu
315
+ buttons while keeping the game's click handlers, tooltips and notifications:
316
+
317
+ ```tsx
318
+ import { UI } from "wuira";
319
+ import { MicroBar } from "wuira/skins";
320
+ import { Cell, Background } from "wuira/ui";
321
+
322
+ const micro = new MicroBar();
323
+ micro.render(bar => {
324
+ bar.Style({
325
+ background: { r: 0.035, g: 0.045, b: 0.065, a: 0.9 },
326
+ accent: { r: 0.4, g: 0.75, b: 1 },
327
+ padding: 6,
328
+ });
329
+ bar.mount(() => (
330
+ <Cell width={12} height={2} decorations={{
331
+ background: new Background({ color: { r: 0.4, g: 0.75, b: 1 } }),
332
+ }} />
333
+ ), "TOP");
334
+ bar.OnHover(hovered => console.log("Micro menu hover:", hovered));
335
+ return bar;
336
+ });
337
+ ```
338
+
339
+ `render` receives the skin adapter once its game-owned frame is ready. The same
340
+ object exposes `Frame`, `Style`, `OnHover`, and `mount`; mounts become children of
341
+ the native frame and are released by `Dispose()`. Native clicks, events and
342
+ tooltips remain intact. Rendering waits until combat ends.
343
+
344
+ `HoverTracker` supplies generic secure trigger/popup frames and auto-hide regions;
345
+ the addon owns their visuals, contents and positioning. Compact menu launchers
346
+ and themes belong in the consuming UI rather than the framework. Hover callbacks
347
+ are ordinary addon callbacks; use secure hover visibility for protected panels.
348
+
349
+ `BlizzardUI.SkinMicroMenu(options)` is also available for styling alone. Stopping
350
+ styling hides its added panel; reload restores original native textures.
351
+
352
+ ### Resource observation and mana regen
353
+
354
+ Resource changes can also be observed without mounting a widget:
355
+
356
+ ```ts
357
+ const mana = new Mana(Unit.Player).UseRegenTimer();
358
+ const unsubscribe = mana.onChange(value => console.log(value));
359
+ // Call unsubscribe() when this consumer is removed.
360
+ ```
361
+
362
+ `onChange` reports future readable value changes, with no initial callback.
363
+ It honors `.When()` and never sends secret values to user code. Native bar
364
+ bindings still accept secret values directly. Bars, observers, and the regen
365
+ accessory share one lazy native event listener; it unregisters when the last
366
+ consumer detaches. `.Value` is still available for a one-time read.
367
+
368
+ `mana.RegenTimer` can be bound to a thin `ProgressBar`. Its `Phase` is
369
+ `fiveSecondRule`, `estimatedTick`, or `inactive`. Successful mana-cost casts
370
+ start/restart a five-second window, followed by estimated two-second cycles.
371
+ Mana events keep those cycles alive without resetting a running cycle. No
372
+ server tick clock is exposed: this is an estimate, including when the cost is
373
+ secret. Zero-cost casts do not restart the window. The native widget animates
374
+ the fill; one-shot callbacks handle phase transitions, with no Lua frame polling.
375
+ Full readable mana cancels the clock. When mana is secret, a native step curve
376
+ hides full mana visually; Lua cannot use that hidden result to dispose the timer,
377
+ so the estimate stops when mana events cease. The frame is reused on the next
378
+ cast. Configure this player-only accessory before mounting.
379
+
145
380
  ### Native aura, cooldown, and cast timers
146
381
 
147
382
  ```tsx
@@ -505,6 +740,13 @@ Cell is the basic visual box. FlowLayout and GridLayout arrange children. Progre
505
740
 
506
741
  Licensed under MIT; see [LICENSE](LICENSE).
507
742
 
743
+ ## AI disclosure
744
+
745
+ wuira is developed with AI assistance for implementation, documentation, and
746
+ tests. AI-assisted code is reviewed line by line. Releases also undergo
747
+ TypeScript checks, Lua runtime tests, and package build validation. Project
748
+ maintainers remain responsible for the code and release decisions.
749
+
508
750
  ## Releases
509
751
 
510
752
  See [CHANGELOG.md](CHANGELOG.md) for release history. Record new changes under
package/lib/Spells.d.ts CHANGED
@@ -1,5 +1,16 @@
1
1
  /** Representative spell IDs; aura sources resolve localized names across ranks. */
2
2
  export declare enum Spells {
3
+ Judgement = 20271,
4
+ HolyStrike = 679,
5
+ Consecration = 26573,
6
+ HolyShock = 20473,
7
+ Exorcism = 879,
8
+ DivineFavor = 20216,
9
+ LayOnHands = 633,
10
+ BlessingOfProtection = 1022,
11
+ BlessingOfFreedom = 1044,
12
+ VoiceOfTruth = 1310897,
13
+ HammerOfJustice = 853,
3
14
  SealOfRighteousness = 21084,
4
15
  SealOfTheCrusader = 21082,
5
16
  SealOfCommand = 20375,
package/lib/Spells.lua CHANGED
@@ -2,6 +2,28 @@
2
2
  local ____exports = {}
3
3
  --- Representative spell IDs; aura sources resolve localized names across ranks.
4
4
  ____exports.Spells = ____exports.Spells or ({})
5
+ ____exports.Spells.Judgement = 20271
6
+ ____exports.Spells[____exports.Spells.Judgement] = "Judgement"
7
+ ____exports.Spells.HolyStrike = 679
8
+ ____exports.Spells[____exports.Spells.HolyStrike] = "HolyStrike"
9
+ ____exports.Spells.Consecration = 26573
10
+ ____exports.Spells[____exports.Spells.Consecration] = "Consecration"
11
+ ____exports.Spells.HolyShock = 20473
12
+ ____exports.Spells[____exports.Spells.HolyShock] = "HolyShock"
13
+ ____exports.Spells.Exorcism = 879
14
+ ____exports.Spells[____exports.Spells.Exorcism] = "Exorcism"
15
+ ____exports.Spells.DivineFavor = 20216
16
+ ____exports.Spells[____exports.Spells.DivineFavor] = "DivineFavor"
17
+ ____exports.Spells.LayOnHands = 633
18
+ ____exports.Spells[____exports.Spells.LayOnHands] = "LayOnHands"
19
+ ____exports.Spells.BlessingOfProtection = 1022
20
+ ____exports.Spells[____exports.Spells.BlessingOfProtection] = "BlessingOfProtection"
21
+ ____exports.Spells.BlessingOfFreedom = 1044
22
+ ____exports.Spells[____exports.Spells.BlessingOfFreedom] = "BlessingOfFreedom"
23
+ ____exports.Spells.VoiceOfTruth = 1310897
24
+ ____exports.Spells[____exports.Spells.VoiceOfTruth] = "VoiceOfTruth"
25
+ ____exports.Spells.HammerOfJustice = 853
26
+ ____exports.Spells[____exports.Spells.HammerOfJustice] = "HammerOfJustice"
5
27
  ____exports.Spells.SealOfRighteousness = 21084
6
28
  ____exports.Spells[____exports.Spells.SealOfRighteousness] = "SealOfRighteousness"
7
29
  ____exports.Spells.SealOfTheCrusader = 21082
@@ -0,0 +1,21 @@
1
+ import { DataSource } from "./DataSource";
2
+ export type KnownSpellsStatus = "ready" | "unavailable" | "restricted";
3
+ /** Cached learned player spellbook IDs. Native events refresh the snapshot; no polling. */
4
+ export declare class KnownSpells extends DataSource<readonly number[]> {
5
+ private ids;
6
+ private names;
7
+ private status;
8
+ private readonly listeners;
9
+ private readonly frame;
10
+ private disposed;
11
+ constructor();
12
+ get Status(): KnownSpellsStatus;
13
+ protected GetValue(): readonly number[];
14
+ protected HasSecretFields(): boolean;
15
+ /** Representative enum IDs match any learned rank through its localized name. */
16
+ Has(spell: number | string): boolean;
17
+ /** No initial emission; only changed, readable snapshots reach observers. */
18
+ onChange(listener: (spells: readonly number[]) => void): () => void;
19
+ private Refresh;
20
+ Dispose(): void;
21
+ }