@pixl-app/sdk 0.1.1 → 1.0.0
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/CHANGELOG.md +20 -0
- package/README.md +8 -3
- package/dist/api-types/device-apps.d.ts +1 -1
- package/dist/api-types/index.d.ts +3 -0
- package/dist/api-types/modules.d.ts +1 -1
- package/dist/api-types/payloads.d.ts +389 -0
- package/dist/api-types/templates.d.ts +6 -0
- package/dist/api-types/widgets.d.ts +555 -0
- package/dist/bindings.d.ts +22 -0
- package/dist/chat.d.ts +1 -1
- package/dist/client.d.ts +127 -164
- package/dist/errors.d.ts +17 -0
- package/dist/events.d.ts +41 -0
- package/dist/feed.d.ts +21 -29
- package/dist/fonts.d.ts +19 -0
- package/dist/frame.d.ts +2 -0
- package/dist/index-nb1y5rx1.js +1932 -0
- package/dist/index.d.ts +12 -3
- package/dist/index.js +38 -873
- package/dist/live-value.d.ts +18 -0
- package/dist/pixl-ui.js +278 -0
- package/dist/pixl.js +4 -4
- package/dist/spotify.d.ts +22 -0
- package/dist/stream.d.ts +30 -0
- package/dist/streamelements.d.ts +14 -0
- package/dist/tts.d.ts +18 -9
- package/dist/twitch.d.ts +68 -0
- package/dist/ui/checkbox.d.ts +27 -0
- package/dist/ui/define.d.ts +2 -0
- package/dist/ui/dialog.d.ts +15 -0
- package/dist/ui/dropdown-helpers.d.ts +48 -0
- package/dist/ui/dropdown.d.ts +65 -0
- package/dist/ui/field.d.ts +48 -0
- package/dist/ui/index.d.ts +14 -0
- package/dist/ui/index.js +1919 -0
- package/dist/ui/inputs.d.ts +29 -0
- package/dist/ui/list.d.ts +31 -0
- package/dist/ui/runtime.d.ts +18 -0
- package/dist/ui/section.d.ts +13 -0
- package/dist/ui/styles.d.ts +6 -0
- package/dist/widget.d.ts +141 -0
- package/package.json +11 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.0.0
|
|
4
|
+
|
|
5
|
+
Neu geschrieben, bricht bestehende Widgets. Wer 0.1 braucht, bindet es mit fester Version über jsDelivr ein (`@pixl-app/sdk@0.1.1`).
|
|
6
|
+
|
|
7
|
+
- Spricht Protokoll 2: einheitliche Payloads (Personen als `user` mit ID, Login, Name und Avatar, Geld als `{ value, currency }`, `count` statt `amount`, `viewers` statt `viewerCount`), Chat-Nachrichten mit fertigem `html`.
|
|
8
|
+
- Handler bekommen ein Event-Objekt `{ type, data, id, at, source }` mit Typen pro Event, `on()` gibt eine Funktion zum Abmelden zurück.
|
|
9
|
+
- Live-Werte mit `value` und `subscribe()`: `status`, `channel`, `twitch.subs`, `twitch.hypeTrain`, `twitch.poll`, `twitch.prediction`, `twitch.goal`, `twitch.charity`, `twitch.adBreak`, `spotify.nowPlaying`.
|
|
10
|
+
- `await pixl.ready`, Fehler als `PixlError` mit festem `code`.
|
|
11
|
+
- Historie unter `pixl.events`: `list()` (blättert selbst), `all()`, `feed()`.
|
|
12
|
+
- `pixl.sendTestEvent(type, felder)` und Demo-Modus (`new Pixl({ demo: true })`) mit einer Vorlage pro Event-Typ.
|
|
13
|
+
- Gehostete Widgets: `pixl.widget()` mit `settings` und `values` als Live-Werte, Änderungen per `set`, `add`, `batch` und Listen-Operationen, Uploads über `files`. Auf Steuer-Seiten kommt der Zugang vom Dashboard.
|
|
14
|
+
- Schriften: `font`-Felder lädt `pixl.widget()` von selbst, von Bunny Fonts (dieselben Schriften wie Google Fonts, ohne dass Google die IP-Adresse bekommt). Dazu `Pixl.fontFamily(name)` für den CSS-Wert und `Pixl.loadFont(name)` für feste Schriften, über npm als `fontFamily` und `loadFont`. `<pixl-field>` schlägt für Schriften beliebte Google Fonts vor.
|
|
15
|
+
- Fertige Bausteine für Steuer-Seiten im Stil von pixl unter `@pixl-app/sdk/ui` bzw. `/sdk/pixl-ui.js`: `<pixl-field>` (mit Kurzformen wie `<pixl-toggle>`), `<pixl-list>`, `<pixl-dialog>`, `<pixl-section>`, dazu `<pixl-dropdown>` (Auswahl mit eigener Liste statt der des Systems, auch in Feldern und Listen) und `<pixl-checkbox>`. Klassen für eigene Elemente: `pixl-btn`, `pixl-input`, `pixl-checkbox`, `pixl-select` (nur als Rückfall), `pixl-card`. Höhe und Farben des Dashboards gelten auch für Seiten ohne eigenes `Pixl`-Objekt.
|
|
16
|
+
- Gehostete Widgets ohne eigenen Code: Felder stehen als CSS-Variablen auf `<html>` (`accentColor` → `--pixl-accent-color`, Texte für `content`, Schalter als 1 oder 0, Dateien als `url(…)`). Ohne `new Pixl()` verbindet das SDK dann selbst.
|
|
17
|
+
- `pixl.fields` (auch `widget.fields`): alle Felder als einfaches Objekt, immer aktuell, Steuerelemente vor Einstellungen, z.B. `const { text, color } = pixl.fields`.
|
|
18
|
+
- `<pixl-field>` zeigt geheime Einstellungen (`sensitive`) verdeckt mit Auge und kennt Stimmen (`voice`) als Auswahl. Dazu `widget.voices()` für eigene Steuer-Seiten, ohne `tts:read`.
|
|
19
|
+
- In der Vorschau im Dashboard gelten Werte, die das Widget selbst setzt, nur dort, die Felder kommen aus dem gespeicherten Entwurf.
|
|
20
|
+
- `tts.speak()` liest in der Vorschau in pixl nur dort vor, der Player der Vorschau spielt es ab. Beim Bedienen mit verbundener Browserquelle liest die vor, die Vorschau spielt es mit ab und `speak()` wirft dort einen `PixlError` mit `problem: "preview"`.
|
|
21
|
+
- Weggefallen: States (`state()`, `getState()`, `fetchStates()`), `org()` (jetzt `channel`), `nowPlaying()` und `Pixl.progress()` (jetzt `spotify.nowPlaying` und `spotify.progress()`), `subs()` (jetzt `twitch.subs`), `streamElements()` (jetzt `streamElements.get()`), `onStatus()` (jetzt `status.subscribe()`), `PixlApiError` (jetzt `PixlError`).
|
|
22
|
+
|
|
3
23
|
## 0.1.1
|
|
4
24
|
|
|
5
25
|
Das Script nimmt die eigene Adresse nur noch als Server, wenn es von einer pixl-Instanz kommt (`/sdk/pixl.js`). Von jsDelivr, unpkg oder einem lokalen Dev-Server geladen, verbindet es sich mit pixl.lennox.zip statt mit dem CDN. `baseUrl` geht weiter vor, an `https://pixl.lennox.zip/sdk/pixl.js` ändert sich nichts.
|
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ Per Script-Tag, ohne Installation:
|
|
|
12
12
|
<script src="https://pixl.lennox.zip/sdk/pixl.js"></script>
|
|
13
13
|
<script>
|
|
14
14
|
const pixl = new Pixl({ key: "pixl_DEIN_SCHLÜSSEL" });
|
|
15
|
-
pixl.on("twitch.follow", (
|
|
15
|
+
pixl.on("twitch.follow", (e) => console.log(`${e.data.user.name} folgt jetzt`));
|
|
16
16
|
</script>
|
|
17
17
|
```
|
|
18
18
|
|
|
@@ -32,7 +32,12 @@ bun add @pixl-app/sdk # oder: npm i @pixl-app/sdk
|
|
|
32
32
|
import { Pixl } from "@pixl-app/sdk";
|
|
33
33
|
|
|
34
34
|
const pixl = new Pixl({ key: "pixl_DEIN_SCHLÜSSEL" });
|
|
35
|
-
pixl.on("twitch.follow", (
|
|
35
|
+
pixl.on("twitch.follow", (e) => console.log(`${e.data.user.name} folgt jetzt`));
|
|
36
|
+
pixl.twitch.subs.subscribe((subs) => console.log(`${subs?.total ?? "?"} Subs`));
|
|
37
|
+
|
|
38
|
+
// Ohne Schlüssel ausprobieren: Demo-Modus mit Vorlagen
|
|
39
|
+
const demo = new Pixl({ demo: true });
|
|
40
|
+
demo.sendTestEvent("twitch.raid", { viewers: 50 });
|
|
36
41
|
```
|
|
37
42
|
|
|
38
43
|
Den API-Schlüssel legst du in pixl unter „API & SDK“ an. Welche Felder jedes Event mitbringt, steht in der Doku unter [Events](https://docs.pixl.lennox.zip/sdk/events).
|
|
@@ -52,7 +57,7 @@ Ein Overlay mit dem Dev-SDK testen: `<script src="http://localhost:4400/pixl.js"
|
|
|
52
57
|
|
|
53
58
|
Die Typen der pixl-API liegen als Kopie aus dem pixl-Monorepo in `src/api-types/`, bis es dafür ein npm-Paket gibt. Geändert werden sie dort, nicht hier.
|
|
54
59
|
|
|
55
|
-
Gegen eine lokale pixl-Instanz: `new Pixl({ key, baseUrl: "http://localhost:5173" })`.
|
|
60
|
+
Gegen eine lokale pixl-Instanz: `new Pixl({ key, baseUrl: "http://localhost:5173" })`. Version 1 braucht einen pixl-Server mit Protokoll 2 (`/api/v1/stream?v=2`).
|
|
56
61
|
|
|
57
62
|
## Versionen und Releases
|
|
58
63
|
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const DEVICE_APP_SCOPES: readonly ["spotify"];
|
|
1
|
+
export declare const DEVICE_APP_SCOPES: readonly ["spotify", "widgets"];
|
|
2
2
|
export type DeviceAppScope = (typeof DEVICE_APP_SCOPES)[number];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const CHANNEL_MODULES: readonly ["music", "tts"];
|
|
1
|
+
export declare const CHANNEL_MODULES: readonly ["music", "tts", "widgets"];
|
|
2
2
|
export type ChannelModule = (typeof CHANNEL_MODULES)[number];
|
|
3
3
|
/** Fehlercode in API-Antworten, wenn das Modul aus ist */
|
|
4
4
|
export declare const MODULE_DISABLED_CODE = "module_disabled";
|
|
@@ -0,0 +1,389 @@
|
|
|
1
|
+
import type { ChatBadge, ChatEmote } from "./chat.js";
|
|
2
|
+
import type { SpotifyNowPlaying } from "./spotify.js";
|
|
3
|
+
import type { StreamWidgetMessage, WidgetState } from "./widgets.js";
|
|
4
|
+
/** Eine Person auf Twitch */
|
|
5
|
+
export type User = {
|
|
6
|
+
/** Twitch-ID. null nur bei alten Einträgen aus der Historie, die pixl nicht mehr zuordnen kann */
|
|
7
|
+
id: string | null;
|
|
8
|
+
/** Login, klein geschrieben */
|
|
9
|
+
login: string;
|
|
10
|
+
/** Anzeigename */
|
|
11
|
+
name: string;
|
|
12
|
+
/** Profilbild, null wenn Twitch keins liefert */
|
|
13
|
+
avatar: string | null;
|
|
14
|
+
};
|
|
15
|
+
/** Geldbetrag, immer als Dezimalzahl (4.2 = 4,20) */
|
|
16
|
+
export type Money = {
|
|
17
|
+
value: number;
|
|
18
|
+
currency: string;
|
|
19
|
+
};
|
|
20
|
+
/** Sub-Stufe. Prime zählt bei Twitch als Stufe 1, steht hier aber eigens */
|
|
21
|
+
export type Tier = "prime" | "1" | "2" | "3";
|
|
22
|
+
/** Woher ein Event kommt */
|
|
23
|
+
export type ChannelEventSource = "live" | "history" | "replay" | "test";
|
|
24
|
+
export type PollChoice = {
|
|
25
|
+
title: string;
|
|
26
|
+
votes: number;
|
|
27
|
+
};
|
|
28
|
+
export type PredictionOutcome = {
|
|
29
|
+
title: string;
|
|
30
|
+
points: number;
|
|
31
|
+
};
|
|
32
|
+
export type HypeTrain = {
|
|
33
|
+
level: number;
|
|
34
|
+
/** Fortschritt im aktuellen Level und Ziel des Levels */
|
|
35
|
+
progress: number;
|
|
36
|
+
goal: number;
|
|
37
|
+
/** Summe aller Beiträge */
|
|
38
|
+
total: number;
|
|
39
|
+
/** Wann der Zug ohne weitere Beiträge endet, ISO */
|
|
40
|
+
expiresAt: string | null;
|
|
41
|
+
startedAt: string | null;
|
|
42
|
+
/** `regular`, `golden_kappa` oder `treasure` */
|
|
43
|
+
type: string;
|
|
44
|
+
/** Geteilter Zug mehrerer Kanäle */
|
|
45
|
+
shared: boolean;
|
|
46
|
+
participants: {
|
|
47
|
+
login: string;
|
|
48
|
+
name: string;
|
|
49
|
+
}[];
|
|
50
|
+
topContributions: {
|
|
51
|
+
user: User;
|
|
52
|
+
type: "bits" | "subscription" | "other";
|
|
53
|
+
total: number;
|
|
54
|
+
}[];
|
|
55
|
+
/** Rekord des Kanals, nur beim Start bekannt */
|
|
56
|
+
record: {
|
|
57
|
+
level: number;
|
|
58
|
+
total: number;
|
|
59
|
+
} | null;
|
|
60
|
+
};
|
|
61
|
+
/** Payload jedes Events, das bei Clients ankommen kann */
|
|
62
|
+
export type EventPayloads = {
|
|
63
|
+
"stream.online": {
|
|
64
|
+
streamId: string;
|
|
65
|
+
title: string | null;
|
|
66
|
+
category: string | null;
|
|
67
|
+
url: string;
|
|
68
|
+
thumbnailUrl: string | null;
|
|
69
|
+
};
|
|
70
|
+
"stream.offline": {
|
|
71
|
+
durationSec: number | null;
|
|
72
|
+
};
|
|
73
|
+
"twitch.follow": {
|
|
74
|
+
user: User;
|
|
75
|
+
};
|
|
76
|
+
"twitch.sub": {
|
|
77
|
+
user: User;
|
|
78
|
+
tier: Tier;
|
|
79
|
+
/** Monate insgesamt, 1 bei einem neuen Sub */
|
|
80
|
+
months: number;
|
|
81
|
+
/** Monate am Stück, null wenn die Person sie nicht teilt */
|
|
82
|
+
streak: number | null;
|
|
83
|
+
/** Im Voraus bezahlte Monate */
|
|
84
|
+
durationMonths: number;
|
|
85
|
+
message: string | null;
|
|
86
|
+
};
|
|
87
|
+
"twitch.sub_gift": {
|
|
88
|
+
/** null = anonym */
|
|
89
|
+
user: User | null;
|
|
90
|
+
tier: Tier;
|
|
91
|
+
/** Anzahl verschenkter Subs */
|
|
92
|
+
count: number;
|
|
93
|
+
/** An zufällige Zuschauer (Gift-Bombe) statt an eine Person */
|
|
94
|
+
community: boolean;
|
|
95
|
+
/** Geschenkte Monate pro Empfänger (Gift-Bomben immer 1) */
|
|
96
|
+
months: number;
|
|
97
|
+
/** Empfänger. Bei Gift-Bomben live noch leer, in der Historie nach ein paar Sekunden vollständig */
|
|
98
|
+
recipients: User[];
|
|
99
|
+
/** Alle bisher verschenkten Subs der Person, null wenn anonym oder unbekannt */
|
|
100
|
+
totalGifted: number | null;
|
|
101
|
+
};
|
|
102
|
+
"twitch.cheer": {
|
|
103
|
+
user: User | null;
|
|
104
|
+
bits: number;
|
|
105
|
+
message: string | null;
|
|
106
|
+
};
|
|
107
|
+
"twitch.raid": {
|
|
108
|
+
user: User;
|
|
109
|
+
viewers: number;
|
|
110
|
+
};
|
|
111
|
+
"twitch.channel_point": {
|
|
112
|
+
user: User;
|
|
113
|
+
reward: string;
|
|
114
|
+
cost: number;
|
|
115
|
+
input: string | null;
|
|
116
|
+
};
|
|
117
|
+
"twitch.channel_point_resolved": {
|
|
118
|
+
user: User;
|
|
119
|
+
reward: string;
|
|
120
|
+
status: "fulfilled" | "canceled";
|
|
121
|
+
};
|
|
122
|
+
"twitch.power_up": {
|
|
123
|
+
user: User;
|
|
124
|
+
title: string;
|
|
125
|
+
bits: number;
|
|
126
|
+
input: string | null;
|
|
127
|
+
};
|
|
128
|
+
"twitch.watch_streak": {
|
|
129
|
+
user: User;
|
|
130
|
+
streak: number;
|
|
131
|
+
channelPoints: number;
|
|
132
|
+
};
|
|
133
|
+
"twitch.modiversary": {
|
|
134
|
+
user: User;
|
|
135
|
+
months: number;
|
|
136
|
+
};
|
|
137
|
+
"twitch.shoutout_sent": {
|
|
138
|
+
user: User;
|
|
139
|
+
viewers: number;
|
|
140
|
+
};
|
|
141
|
+
"twitch.poll_started": {
|
|
142
|
+
title: string;
|
|
143
|
+
choices: PollChoice[];
|
|
144
|
+
};
|
|
145
|
+
"twitch.poll_progress": {
|
|
146
|
+
title: string;
|
|
147
|
+
choices: PollChoice[];
|
|
148
|
+
};
|
|
149
|
+
"twitch.poll_ended": {
|
|
150
|
+
title: string;
|
|
151
|
+
status: "completed" | "archived" | "terminated";
|
|
152
|
+
choices: PollChoice[];
|
|
153
|
+
};
|
|
154
|
+
"twitch.prediction_started": {
|
|
155
|
+
title: string;
|
|
156
|
+
outcomes: PredictionOutcome[];
|
|
157
|
+
};
|
|
158
|
+
"twitch.prediction_progress": {
|
|
159
|
+
title: string;
|
|
160
|
+
outcomes: PredictionOutcome[];
|
|
161
|
+
};
|
|
162
|
+
"twitch.prediction_locked": {
|
|
163
|
+
title: string;
|
|
164
|
+
outcomes: PredictionOutcome[];
|
|
165
|
+
};
|
|
166
|
+
"twitch.prediction_ended": {
|
|
167
|
+
title: string;
|
|
168
|
+
status: "resolved" | "canceled";
|
|
169
|
+
/** Titel des Gewinners, null wenn abgebrochen */
|
|
170
|
+
winner: string | null;
|
|
171
|
+
outcomes: PredictionOutcome[];
|
|
172
|
+
};
|
|
173
|
+
"twitch.hype_train_started": HypeTrain;
|
|
174
|
+
"twitch.hype_train_progress": HypeTrain;
|
|
175
|
+
"twitch.hype_train_ended": HypeTrain;
|
|
176
|
+
"twitch.goal_started": {
|
|
177
|
+
type: string;
|
|
178
|
+
description: string;
|
|
179
|
+
current: number;
|
|
180
|
+
target: number;
|
|
181
|
+
};
|
|
182
|
+
"twitch.goal_progress": {
|
|
183
|
+
current: number;
|
|
184
|
+
target: number;
|
|
185
|
+
};
|
|
186
|
+
"twitch.goal_ended": {
|
|
187
|
+
type: string;
|
|
188
|
+
description: string;
|
|
189
|
+
current: number;
|
|
190
|
+
target: number;
|
|
191
|
+
achieved: boolean;
|
|
192
|
+
};
|
|
193
|
+
"twitch.charity_started": {
|
|
194
|
+
charity: string;
|
|
195
|
+
target: Money;
|
|
196
|
+
};
|
|
197
|
+
"twitch.charity_progress": {
|
|
198
|
+
current: Money;
|
|
199
|
+
target: Money;
|
|
200
|
+
};
|
|
201
|
+
"twitch.charity_donated": {
|
|
202
|
+
user: User;
|
|
203
|
+
charity: string;
|
|
204
|
+
amount: Money;
|
|
205
|
+
};
|
|
206
|
+
"twitch.charity_stopped": {
|
|
207
|
+
charity: string;
|
|
208
|
+
current: Money;
|
|
209
|
+
target: Money;
|
|
210
|
+
};
|
|
211
|
+
"twitch.ad_break": {
|
|
212
|
+
durationSec: number;
|
|
213
|
+
automatic: boolean;
|
|
214
|
+
startedAt: string | null;
|
|
215
|
+
};
|
|
216
|
+
"twitch.title_changed": {
|
|
217
|
+
title: string;
|
|
218
|
+
};
|
|
219
|
+
"twitch.category_changed": {
|
|
220
|
+
category: string;
|
|
221
|
+
};
|
|
222
|
+
"twitch.ban": {
|
|
223
|
+
user: User;
|
|
224
|
+
moderator: User | null;
|
|
225
|
+
reason: string | null;
|
|
226
|
+
permanent: boolean;
|
|
227
|
+
endsAt: string | null;
|
|
228
|
+
};
|
|
229
|
+
"twitch.unban": {
|
|
230
|
+
user: User;
|
|
231
|
+
moderator: User | null;
|
|
232
|
+
};
|
|
233
|
+
"twitch.vip_added": {
|
|
234
|
+
user: User;
|
|
235
|
+
};
|
|
236
|
+
"twitch.vip_removed": {
|
|
237
|
+
user: User;
|
|
238
|
+
};
|
|
239
|
+
"twitch.moderator_added": {
|
|
240
|
+
user: User;
|
|
241
|
+
};
|
|
242
|
+
"twitch.moderator_removed": {
|
|
243
|
+
user: User;
|
|
244
|
+
};
|
|
245
|
+
"twitch.chat_message": {
|
|
246
|
+
user: User;
|
|
247
|
+
messageId: string;
|
|
248
|
+
text: string;
|
|
249
|
+
/** Fertiges HTML mit Emotes, Text ist escaped */
|
|
250
|
+
html: string;
|
|
251
|
+
color: string | null;
|
|
252
|
+
emotes: Record<string, ChatEmote>;
|
|
253
|
+
badges: ChatBadge[];
|
|
254
|
+
/** ID des 7TV-Paints, Definition über `pixl.chat.paint(id)` */
|
|
255
|
+
paint: string | null;
|
|
256
|
+
};
|
|
257
|
+
"twitch.chat_cleared": Record<string, never>;
|
|
258
|
+
"twitch.chat_user_cleared": {
|
|
259
|
+
user: User;
|
|
260
|
+
};
|
|
261
|
+
"twitch.chat_message_deleted": {
|
|
262
|
+
user: User;
|
|
263
|
+
messageId: string;
|
|
264
|
+
};
|
|
265
|
+
"twitch.chat_settings_updated": {
|
|
266
|
+
emoteMode: boolean;
|
|
267
|
+
followerMode: boolean;
|
|
268
|
+
followerModeDuration: number | null;
|
|
269
|
+
slowMode: boolean;
|
|
270
|
+
slowModeWait: number | null;
|
|
271
|
+
subscriberMode: boolean;
|
|
272
|
+
uniqueChatMode: boolean;
|
|
273
|
+
};
|
|
274
|
+
"twitch.chat_message_held": {
|
|
275
|
+
user: User;
|
|
276
|
+
text: string;
|
|
277
|
+
messageId: string;
|
|
278
|
+
};
|
|
279
|
+
"twitch.chat_message_held_updated": {
|
|
280
|
+
user: User;
|
|
281
|
+
status: string;
|
|
282
|
+
messageId: string;
|
|
283
|
+
};
|
|
284
|
+
"twitch.shared_chat_started": {
|
|
285
|
+
sessionId: string;
|
|
286
|
+
participants: number;
|
|
287
|
+
};
|
|
288
|
+
"twitch.shared_chat_updated": {
|
|
289
|
+
sessionId: string;
|
|
290
|
+
participants: number;
|
|
291
|
+
};
|
|
292
|
+
"twitch.shared_chat_ended": {
|
|
293
|
+
sessionId: string;
|
|
294
|
+
};
|
|
295
|
+
"twitch.guest_star_session_started": {
|
|
296
|
+
sessionId: string;
|
|
297
|
+
};
|
|
298
|
+
"twitch.guest_star_session_ended": {
|
|
299
|
+
sessionId: string;
|
|
300
|
+
};
|
|
301
|
+
"twitch.guest_star_guest_updated": {
|
|
302
|
+
sessionId: string;
|
|
303
|
+
user: User | null;
|
|
304
|
+
state: string;
|
|
305
|
+
slotId: string | null;
|
|
306
|
+
};
|
|
307
|
+
"twitch.guest_star_settings_updated": {
|
|
308
|
+
slotCount: number;
|
|
309
|
+
groupLayout: string;
|
|
310
|
+
};
|
|
311
|
+
"seventv.emote_added": {
|
|
312
|
+
emote: ChatEmote;
|
|
313
|
+
actor: string | null;
|
|
314
|
+
};
|
|
315
|
+
"seventv.emote_removed": {
|
|
316
|
+
emote: ChatEmote;
|
|
317
|
+
actor: string | null;
|
|
318
|
+
};
|
|
319
|
+
"seventv.emote_renamed": {
|
|
320
|
+
emote: ChatEmote;
|
|
321
|
+
oldName: string;
|
|
322
|
+
actor: string | null;
|
|
323
|
+
};
|
|
324
|
+
"seventv.emote_set_changed": {
|
|
325
|
+
setId: string;
|
|
326
|
+
name: string | null;
|
|
327
|
+
actor: string | null;
|
|
328
|
+
};
|
|
329
|
+
"streamelements.tip": {
|
|
330
|
+
/** Name, den die Person angegeben hat (kein Twitch-Login) */
|
|
331
|
+
name: string;
|
|
332
|
+
amount: Money;
|
|
333
|
+
message: string | null;
|
|
334
|
+
tipId: string;
|
|
335
|
+
};
|
|
336
|
+
"subs.updated": {
|
|
337
|
+
total: number;
|
|
338
|
+
points: number;
|
|
339
|
+
at: string;
|
|
340
|
+
};
|
|
341
|
+
"spotify.now_playing": SpotifyNowPlaying;
|
|
342
|
+
/** Audio liegt bereit, abrufbar über `/api/v1/tts/<id>/audio` */
|
|
343
|
+
"tts.ready": {
|
|
344
|
+
id: string;
|
|
345
|
+
voice: string;
|
|
346
|
+
text: string;
|
|
347
|
+
source: string;
|
|
348
|
+
eventId: string | null;
|
|
349
|
+
};
|
|
350
|
+
"tts.skip": {
|
|
351
|
+
id: string | null;
|
|
352
|
+
};
|
|
353
|
+
"tts.clear": Record<string, never>;
|
|
354
|
+
};
|
|
355
|
+
export type ChannelEventType = keyof EventPayloads;
|
|
356
|
+
/** Ein Event, wie es bei Clients ankommt (Live-Stream ab Protokoll 2, Historie mit `v=2`) */
|
|
357
|
+
export type ChannelEvent<T extends ChannelEventType = ChannelEventType> = {
|
|
358
|
+
[K in T]: {
|
|
359
|
+
type: K;
|
|
360
|
+
data: EventPayloads[K];
|
|
361
|
+
/** ID der Eventlog-Zeile, nur bei Events, die im Eventlog stehen */
|
|
362
|
+
id?: string;
|
|
363
|
+
/** Zeitpunkt, ISO */
|
|
364
|
+
at: string;
|
|
365
|
+
source: ChannelEventSource;
|
|
366
|
+
};
|
|
367
|
+
}[T];
|
|
368
|
+
export declare const STREAM_PROTOCOL = 2;
|
|
369
|
+
/** Erste Nachricht jeder Verbindung */
|
|
370
|
+
export type StreamConnected = {
|
|
371
|
+
type: "connected";
|
|
372
|
+
protocol: typeof STREAM_PROTOCOL;
|
|
373
|
+
channel: {
|
|
374
|
+
id: string;
|
|
375
|
+
name: string;
|
|
376
|
+
login: string | null;
|
|
377
|
+
avatar: string | null;
|
|
378
|
+
};
|
|
379
|
+
/** Rechte des Zugangs, z.B. `["events:read"]` */
|
|
380
|
+
scopes: string[];
|
|
381
|
+
/** Nur bei Zugängen eines gehosteten Widgets: dessen Stand */
|
|
382
|
+
widget?: WidgetState;
|
|
383
|
+
};
|
|
384
|
+
/** Zugang widerrufen: die Verbindung endet, nicht neu verbinden */
|
|
385
|
+
export type StreamAccessRevoked = {
|
|
386
|
+
type: "access_revoked";
|
|
387
|
+
};
|
|
388
|
+
/** Alles, was über den Live-Stream ab Protokoll 2 kommt */
|
|
389
|
+
export type StreamMessage = StreamConnected | StreamAccessRevoked | StreamWidgetMessage | ChannelEvent;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { EventPayloads, ChannelEventType, User } from "./payloads.js";
|
|
2
|
+
/** Beispiel-Person für Vorlagen */
|
|
3
|
+
export declare function templateUser(name: string, id?: string): User;
|
|
4
|
+
export declare const EVENT_TEMPLATES: {
|
|
5
|
+
[K in ChannelEventType]: EventPayloads[K];
|
|
6
|
+
};
|