GitHub
Skizzepackages/bit-mask/src

Bit Mask

@ralphschuler/bit-mask

Packt mehrere unabhängige boolesche Features in eine Zahl und prüft sie über Bitoperationen.

flagsbitwisecompact state

01 · Problem

Wofür braucht man das?

Viele kleine Ja/Nein-Zustände können kompakt gespeichert und sehr schnell kombiniert werden, wenn jeder Zustand genau ein Bit besitzt.

02 · Denkmodell

Das mentale Modell

Jede erlaubte Flag ist eine Zweierpotenz. OR setzt Bits, AND mit invertierter Maske löscht Bits und AND prüft eine einzelne oder kombinierte Maske.

Im Repository

BitwiseFeatureFlags implementiert enable, disable und isEnabled intern, exportiert aber nichts. Erlaubte Enum-Werte werden nicht auf Zweierpotenzen geprüft und JavaScript begrenzt Number-Bitoperationen auf 32 Bit.

03 · Kontrollfluss

Was passiert in welcher Reihenfolge?

  1. Jeder Feature-ID genau eine Zweierpotenz zuweisen.
  2. Angeforderte Flags gegen eine erlaubte Menge validieren.
  3. Maske mit OR setzen oder mit AND-NOT löschen.
  4. Bei Abfrage alle angeforderten Bits vergleichen.

04 · Bauteile

Die entscheidenden Verträge

BitwiseFeatureFlags (intern) Nicht exportierte Klasse mit einer numerischen Gesamtmaske.
enableFlag / disableFlag Setzen oder löschen Bits nach einer Validierung.
isFlagEnabled Prüft, ob alle Bits einer Flagmaske gesetzt sind.

05 · Build it yourself

Selbst implementieren

Validiere das Datenmodell beim Erzeugen; ungültige Flags sollten später nicht nur geloggt werden.

  1. Akzeptiere nur positive einzelne Zweierpotenzen als Basisflags.
  2. Wirf bei unbekannten Flags einen definierten Fehler.
  3. Nutze bigint, sobald mehr als 31 unabhängige Bits benötigt werden.
minimal.ts · unabhängig vom Package
class Flags {
  private mask = 0;
  constructor(private allowed: ReadonlySet<number>) {}

  private check(flag: number) {
    if (!this.allowed.has(flag)) throw new RangeError("Unknown flag");
  }
  enable(flag: number) { this.check(flag); this.mask |= flag; }
  disable(flag: number) { this.check(flag); this.mask &= ~flag; }
  has(flag: number) { this.check(flag); return (this.mask & flag) === flag; }
  value() { return this.mask; }
}

06 · Verifizieren

Was du testen solltest

  • Jedes erlaubte Bit lässt sich unabhängig setzen und löschen.
  • Kombinierte Abfragen bestehen nur, wenn alle enthaltenen Bits gesetzt sind.
  • Null, Nicht-Zweierpotenzen, unbekannte und zu große Flags werden abgelehnt.

07 · Grenzen

Kompromisse und Stolperfallen

  • Number-Bitoperatoren arbeiten als signed 32-bit Integer.
  • Bitmasken sind kompakt, aber ohne Symboltabelle schlecht lesbar und migrationsanfällig.
Wichtig

Numerische TypeScript-Enums besitzen Reverse-Mappings. Object.values enthält daher nicht automatisch nur gültige Zahlenflags.

08 · Weiterdenken

Quellcode und Nachbarn

Originalcode auf GitHub ansehen