


Ein bidirektionales Protokoll-SDK in einem TypeScript-Monorepo pflegen, ohne die öffentliche API zu brechen
Für Änderungen an einem typisierten SDK aus mehreren Paketen, bei dem Client und Server Anfragen senden. Wählt öffentliche Exporte bewusst, ergänzt Operationen auf beiden Seiten mit Fähigkeitsprüfung, dokumentiert inkompatible Änderungen und führt Beispiele als Tests aus.
Diese KI-Regeln verwenden
## Prüfen, zu welcher Schicht eine Änderung gehört und ob sie die öffentliche API berührt
Diese Anleitung regelt die Arbeit innerhalb eines TypeScript-Arbeitsbereichs mit mehreren Paketen, der ein Protokoll-SDK veröffentlicht: einen gemeinsam genutzten internen Kern, ein Paket für die aufrufende Seite, ein Paket für die anbietende Seite, ein eigenständiges Paket mit den Prüfschemata sowie schlanke Anbindungspakete für einzelne Rahmenwerke oder Laufzeitumgebungen. Vorausgesetzt werden strenge Typprüfung, ES-Module und arbeitsbereichsweite Skripte, die von einer einzigen Paketverwaltung gesteuert werden.
Zwei Eigenschaften bestimmen jede Entscheidung. Erstens ist die veröffentlichte Schnittstelle ein verbindlicher Vertrag: Alles, was von einem Einstiegspunkt eines Pakets aus erreichbar ist, gilt als öffentliche Schnittstelle und darf nicht beiläufig verändert werden. Zweitens ist das Protokoll bidirektional – beide Gegenstellen dürfen Anfragen auslösen –, sodass eine Änderung auf der einen Seite in der Regel eine spiegelbildliche Verpflichtung auf der anderen Seite nach sich zieht.
Klären Sie vor dem Bearbeiten, zu welcher Schicht die Änderung gehört und ob sie die veröffentlichte Schnittstelle berührt. Ist das der Fall, behandeln Sie sie als Schnittstellenänderung und wenden Sie nicht nur die Stilregeln an, sondern auch die unten stehenden Regeln zu Schnittstelle und Umstellung.
## Beim Arbeiten einen Test, vor dem Abschluss alle Prüfungen ausführen
Der Arbeitsbereich stellt übergreifende Skripte für das gesamte Projektarchiv bereit: Abhängigkeiten installieren, alle Pakete bauen, Stil- und Formatprüfungen ausführen, Stil- und Formatfehler automatisch beheben, alle Pakete auf Typfehler prüfen, die vollständige Testreihe ausführen sowie ein kombiniertes Prüfskript, das Typprüfung und Stilprüfung zusammenfasst.
Halten Sie die Schleife während des Arbeitens eng. Nutzen Sie den Filterschalter der Paketverwaltung, um das Testskript eines einzelnen Pakets auszuführen, übergeben Sie einen Dateipfad, um eine einzelne Testdatei auszuführen, und übergeben Sie einen Namensfilter, um einen einzelnen Testfall auszuführen. Für enges Arbeiten steht zusätzlich ein Skript im Beobachtungsmodus bereit.
Heben Sie sich Durchläufe über den gesamten Arbeitsbereich für den Moment auf, bevor Sie eine Arbeit als abgeschlossen erklären, und führen Sie dann sowohl die kombinierte Prüfung als auch die Testreihe aus. Eine Typprüfung allein belegt kein Laufzeitverhalten – behaupten Sie niemals, eine Änderung funktioniere, ohne die Tests ausgeführt zu haben, die sie tatsächlich abdecken.
## Die Namens- und Formatregeln des Repositorys befolgen
- Durchgängig strenge Typprüfung; ausdrückliche Rückgabetypen bei ausgeführten Funktionen, die nach außen gegeben werden.
- Große Binnenschreibweise für Klassen und Typen; kleine Binnenschreibweise für Funktionen und Variablen.
- Dateinamen klein geschrieben und mit Bindestrichen getrennt; Testdateien tragen eine entsprechende Kennung in ihrer Dateiendung.
- Einbindungen als ES-Module. Richten Sie sich bei den Dateiendungen nach der eingestellten Modulauflösung des Projekts – bei bündelnaher Auflösung tragen relative Einbindungen keine Dateiendung. Gruppieren Sie Einbindungen sinnvoll.
- Einrückung mit zwei Leerzeichen, Semikolons verpflichtend, einfache Anführungszeichen bevorzugt.
- Tests liegen im dafür vorgesehenen Testverzeichnis des jeweiligen Pakets, damit das Suchmuster der Testausführung sie erfasst; verwenden Sie aussagekräftige Testnamen.
- Dokumentationskommentare an öffentlichen Schnittstellen; Kommentare im Quelltext bleiben wirklich nicht offensichtlicher Logik vorbehalten.
Ist eine Regel mehrdeutig, richten Sie sich nach der umgebenden Datei. Formatieren oder überarbeiten Sie innerhalb einer inhaltlichen Änderung keinen unbeteiligten Quelltext.
## Dokumentationsbeispiele aus kompilierten Beispieldateien übernehmen
Von Hand geschriebene Ausschnitte in Dokumentationskommentaren verfallen unbemerkt, weil sie von niemandem übersetzt werden. Holen Sie Beispielcode stattdessen aus begleitenden Beispielmodulen, die gemeinsam mit dem übrigen Quelltext übersetzt und auf Typfehler geprüft werden.
Eine Begleitdatei liegt unter einem passenden Namen neben dem Modul, auf das sie sich bezieht. Benannte Bereiche innerhalb der Begleitdatei werden aus dem Codeblock der Dokumentation über ein Quellenattribut angesprochen, das auf Datei und Bereich verweist. Die Bereichsnamen folgen einem vorhersehbaren Muster: der Name des nach außen gegebenen Symbols plus eine Variante, oder ein Klassenname plus Methodenname plus eine Variante. Lässt man den Verweis auf den Bereich weg, wird die gesamte Datei eingebunden, was bei jedem Dateityp funktioniert.
Führen Sie nach dem Bearbeiten von Beispielen das Skript zum Abgleich der Ausschnitte aus, damit der aktuelle Inhalt in die Dokumentationskommentare und die Markdown-Seiten übernommen wird, und übernehmen Sie das abgeglichene Ergebnis gemeinsam mit der Änderung in die Versionsverwaltung.
## Öffentliches namentlich exportieren und den Paketeinstieg laufzeitneutral halten
Trennen Sie ein internes Sammelmodul – das alles nach außen gibt, als privat gekennzeichnet ist und ausschließlich von Geschwisterpaketen innerhalb des Arbeitsbereichs genutzt wird – von einem sorgfältig gepflegten öffentlichen Ausgabemodul, das Typen, Fehlerklassen, Konstanten, Typprüffunktionen und gemeinsam genutzte Basisklassen bereitstellt. Die Einstiegspunkte der Pakete geben das gepflegte Modul weiter, zusätzlich zu ihren eigenen ausdrücklich benannten Ausgaben.
Regeln, über die nicht verhandelt wird:
- Verwenden Sie in Einstiegspunkten und im gepflegten Modul ausdrücklich benannte Ausgaben. Nutzen Sie dort niemals pauschale Weitergaben mit Platzhalter.
- Ein Symbol in den Einstiegspunkt eines Pakets aufzunehmen macht es zur öffentlichen Schnittstelle. Tun Sie das nur mit Absicht.
- Interne Hilfsfunktionen bleiben im internen Sammelmodul und werden niemals in das gepflegte Modul oder in einen Einstiegspunkt aufgenommen.
- Halten Sie den Haupteinstieg jedes Pakets laufzeitneutral, damit ihn Bündelwerkzeuge für Browser- und Edge-Laufzeitumgebungen verarbeiten können. Jede Ausgabe, deren Modulgeflecht mittelbar plattformspezifische Bordmittel wie das Starten von Prozessen oder rohe Netzwerkverbindungen erreicht, muss hinter einem benannten Unterpfad liegen und durch einen Test abgesichert sein, der belegt, dass das Sammelmodul der Wurzel frei davon bleibt.
- Halten Sie Typen der Prüfbibliothek aus veröffentlichten Schnittstellen heraus, die zusagen, frei davon zu bleiben; geben Sie stattdessen die rohen Laufzeitschemata aus dem dafür vorgesehenen Schemapaket heraus und lassen Sie Geschwisterpakete dieses Paket als echte externe Abhängigkeit auflösen, statt private Kopien der Schemata mitzuführen.
## Auf der Schemaschicht aufbauen und Transporte austauschbar halten
Gliedern Sie das SDK in drei Schichten.
1. Schicht der Typen und Schemata – Protokollnachrichtentypen, Prüfschemata und Konstanten, abgestimmt auf die Spezifikation. Sie ist die einzige verbindliche Quelle; jede andere Schicht leitet sich daraus ab.
2. Protokollschicht – eine abstrakte Basisklasse, die die Zustellung von Nachrichten, die Zuordnung von Anfragen und Antworten, das Aushandeln von Fähigkeiten und den Lebenszyklus des Transportwegs übernimmt. Beide Umsetzungen der Gegenstellen erben von ihr, weshalb das bidirektionale Verhalten von Bauart her symmetrisch ist.
3. Übergeordnete Schnittstellen – die Klassen der aufrufenden und der anbietenden Seite mit ihren typisierten Methoden sowie eine übergeordnete Hülle für die anbietende Seite, die eine vereinfachte Anmeldung von Werkzeugen, Ressourcen und Eingabevorlagen bietet.
Die Transportwege bilden eine eigene, austauschbare Schicht hinter einer einzigen Schnittstelle: ein Transportweg über HTTP mit fortlaufendem Datenstrom, empfohlen für entfernte Gegenstellen, ein älterer Transportweg über Ereignisströme, der aus Gründen der Abwärtskompatibilität erhalten bleibt, und ein Transportweg über Standardeingabe und Standardausgabe für die Anbindung lokal gestarteter Prozesse. Die Prüfung ist im selben Sinne austauschbar, mit einer Standardprüfung und Alternativen, die auch in eingeschränkten Laufzeitumgebungen laufen.
Anbindungspakete für Rahmenwerke und Laufzeitumgebungen sind schlanke Zwischenschichten. Sie dürfen niemals Protokollfunktionen ergänzen; alles, was das Protokollverhalten verändert, gehört in die Kernschichten.
## Den ausgehenden und eingehenden Anfragefluss auf beiden Seiten verstehen
Ausgehend. Eine übergeordnete Methode reicht an die Anfragemethode der Basisklasse weiter. Diese vergibt eine eindeutige Nachrichtenkennung, prüft, ob die entfernte Gegenstelle die für die Methode nötige Fähigkeit angemeldet hat, hinterlegt eine wartende Antwortbehandlung, übergibt die serialisierte Anfrage an den Transportweg und wartet auf die Auflösung, sobald die passende Antwort eintrifft.
Eingehend. Der Transportweg meldet eine eintreffende Nachricht, und die Zustellung in der Basisklasse leitet sie als Anfrage, als Antwort oder als Benachrichtigung weiter. Bei der Behandlung einer Anfrage wird die zuständige Behandlungsroutine über den Methodennamen nachgeschlagen, ein Kontextobjekt aufgebaut, der abgeleiteten Klasse Gelegenheit gegeben, diesen Kontext um transportspezifische Angaben zu ergänzen, die Routine aufgerufen und deren Ergebnis als Antwort über den Transportweg zurückgegeben.
Aufbau des Kontexts. Eine Sitzungskennung; eine Anfragegruppe mit der Nachrichtenkennung, dem Methodennamen, den Metadaten der Anfrage, einem Abbruchsignal für den Abbruch sowie Hilfsfunktionen, um eine zugehörige Anfrage oder Benachrichtigung an die Gegenstelle zu senden; und eine optionale Transportgruppe, die geprüfte Berechtigungsangaben mitführt, sofern der Transportweg sie bereitstellt. Der Kontext auf der anbietenden Seite ergänzt Protokollierung, Rückfragen an den Nutzer und Hilfsfunktionen für Modellabfragen.
Die Durchsetzung der Fähigkeiten greift in beide Richtungen und zusätzlich beim Anmelden von Behandlungsroutinen, sodass eine Gegenstelle keine Routine für etwas anmelden kann, das sie nie angemeldet hat.
## Eine neue Protokolloperation mit Fähigkeitsprüfung auf beiden Seiten hinzufügen
1. Legen Sie das Schema der Anfrageparameter und das Ergebnisschema in der Typenschicht fest.
2. Ergänzen Sie das zugehörige Fähigkeitskennzeichen im Fähigkeitstyp der aufrufenden oder der anbietenden Seite.
3. Setzen Sie die sendende Methode auf der Gegenstelle um, die die Operation auslöst.
4. Ergänzen Sie die Fähigkeitsprüfung innerhalb der Prüfroutine dieser Gegenstelle.
5. Melden Sie die empfangende Behandlungsroutine auf der jeweils anderen Gegenstelle an.
6. Ergänzen Sie eine übergeordnete Hülle in der vereinfachten Schnittstelle der anbietenden Seite, wenn die Operation eine rechtfertigt.
7. Ergänzen Sie Tests auf beiden Seiten sowie ein lauffähiges Beispiel, wenn die Operation für Anwender sichtbar ist.
Die Schritte zwei und vier werden am häufigsten übersprungen und sind zugleich am teuersten, wenn man sie überspringt: Eine Operation ohne ausgehandelte Fähigkeit scheitert erst zur Laufzeit gegenüber Gegenstellen, die sie nicht umsetzen, statt bereits bei der Initialisierung sauber zu scheitern.
## Inkompatible Änderungen mit Was, Warum und Migrationsweg festhalten
Halten Sie jede nicht abwärtskompatible Änderung im Umstellungsleitfaden fest, und zwar in dem Abschnitt zu dem Teilsystem, das sie betrifft. Suchen Sie nach verwandten Abschnitten und erweitern Sie diese, statt neue eigenständige Abschnitte anzuhängen – ein Leitfaden aus lauter nebeneinanderstehenden Einzeleinträgen wird genau dann unlesbar, wenn jemand ihn braucht. Änderungen, die sich auf eine einzelne Veröffentlichungsnotiz beschränken, gehören stattdessen dorthin.
Jeder Eintrag nennt drei Dinge: was sich geändert hat, warum es sich geändert hat und wie man umstellt.
Rein mechanische Umbenennungen gehören in die Zuordnungsdateien des automatischen Umstellungswerkzeugs. Verweisen Sie auf die Zuordnung, statt Umbenennungstabellen im Fließtext zu wiederholen; doppelt geführte Tabellen laufen mit dem Werkzeug auseinander, das die Umbenennung tatsächlich vornimmt.
Zur Abwägung: Bevorzugen Sie ergänzende Änderungen. Lässt sich ein Bruch nicht vermeiden, halten Sie den alten Weg nach Möglichkeit für einen Zyklus als veraltet gekennzeichnet weiter funktionsfähig und gestalten Sie den Bruch so, dass er als eindeutiger Fehler beim Übersetzen auffällt und nicht als stille Verhaltensänderung.
## Client-Server-Beispiele in der CI als Tests ausführen
Behandeln Sie Beispiele als Tests, nicht als Zierrat. Jedes Beispiel ist ein eigenes Paket im Arbeitsbereich und enthält eine zusammengehörige anbietende und aufrufende Seite; die aufrufende Seite verbindet sich, prüft die erwarteten Ergebnisse und beendet sich bei Abweichung mit einem Fehlerstatus. Eine Ausführungsroutine führt jedes Beispiel über alle eingerichteten Kombinationen aus Transportweg und Protokollgeneration aus, und dieser Vorgang ist Teil der automatisierten Integrationsprüfung bei jeder Änderung.
Die gemeinsam genutzte Grundausstattung der Beispiele liegt in einem einzigen gemeinsamen Paket, dessen Hauptausgabe schlank bleibt – Auswertung der Aufrufparameter, Hilfsfunktionen für Prüfungen, Auflösung der Pfade zu Geschwisterpaketen. Schwerere optionale Abhängigkeiten wie ein Berechtigungsdienst zu Vorführzwecken oder ein Ereignisspeicher im Arbeitsspeicher liegen hinter einem Unterpfad, damit unbeteiligte Beispiele sie nicht vorsorglich laden. Beispiele binden ausschließlich diese Grundausstattung ein und richten Transportwege direkt im Beispiel ein, sodass sich jedes Beispiel wie echte Verwendung liest und nicht wie eine Hülle um verborgene Vorbereitungen.
Die Seiten der Dokumentationsleitfäden erhalten je Seite eigene Begleitdateien für Ausschnitte, die vom selben Abgleichsschritt aktualisiert werden; die lauffähigen darunter werden ebenfalls in der Integrationsprüfung ausgeführt.
