From 13b28fdc913568db5e91b98f5748308ec2b5e450 Mon Sep 17 00:00:00 2001 From: Andre <200930841+Andre-Bzk@users.noreply.github.com> Date: Fri, 15 May 2026 08:49:31 +0200 Subject: [PATCH] refactor: consolidate IPC types into src/shared/types.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The 12 cross-process data types were manually copied across src/preload/index.ts and src/renderer/src/types/t4sd.d.ts. A silent field addition or rename in either file would not produce a compile error in the other — the divergence only surfaces at runtime. A shared module makes the compiler enforce consistency. Preload imports from shared/types and re-exports for downstream consumers. The renderer's t4sd.d.ts re-exports the same types from shared/types, so all existing screen imports continue to work without modification. Both tsconfigs are extended to include src/shared so the module is reachable from both composite projects. --- src/main/playback/types.ts | 8 +-- src/preload/index.ts | 112 +++++++---------------------- src/renderer/src/types/t4sd.d.ts | 119 +++++++++---------------------- src/shared/types.ts | 86 ++++++++++++++++++++++ tsconfig.node.json | 3 +- tsconfig.web.json | 6 +- 6 files changed, 153 insertions(+), 181 deletions(-) create mode 100644 src/shared/types.ts diff --git a/src/main/playback/types.ts b/src/main/playback/types.ts index 024d27e..9f8a6dd 100644 --- a/src/main/playback/types.ts +++ b/src/main/playback/types.ts @@ -8,10 +8,4 @@ export type Quality = | 'audio_only' | 'worst' -export interface PlaybackEvent { - kind: 'started' | 'stopped' | 'error' - channelLogin?: string - message?: string - durationSeconds?: number - isLive?: boolean -} +export type { PlaybackEvent } from '../../shared/types' diff --git a/src/preload/index.ts b/src/preload/index.ts index 645722d..0d492e1 100644 --- a/src/preload/index.ts +++ b/src/preload/index.ts @@ -1,91 +1,33 @@ import { contextBridge, ipcRenderer, type IpcRendererEvent } from 'electron' import { IPC } from '../main/ipc/channels' +import type { + AuthStatus, + DeviceFlowStartInfo, + AuthEvent, + FollowedChannelInfo, + OwnUserInfo, + PlaybackEvent, + HlsUrlPayload, + GameInfo, + VodInfo, + VodProgress, + VodChapter, + TopStreamsResult +} from '../shared/types' -export type AuthStatus = 'logged-out' | 'logged-in' - -export interface DeviceFlowStartInfo { - userCode: string - verificationUri: string - expiresInSec: number -} - -export type AuthEvent = - | { kind: 'authorized' } - | { kind: 'denied' } - | { kind: 'expired' } - | { kind: 'cancelled' } - | { kind: 'error'; message: string } - -export interface FollowedChannelInfo { - broadcasterId: string - broadcasterLogin: string - broadcasterName: string - profileImageUrl: string - isLive: boolean - streamTitle?: string - gameId?: string - gameName?: string - viewerCount?: number - thumbnailUrl?: string - startedAt?: string - language?: string -} - -export interface OwnUserInfo { - id: string - login: string - displayName: string - profileImageUrl: string -} - -export interface PlaybackEvent { - kind: 'started' | 'stopped' | 'error' - channelLogin?: string - message?: string - durationSeconds?: number - isLive?: boolean -} - -export interface HlsUrlPayload { - url: string - isLive: boolean - startPosition: number - durationSeconds: number - vodId?: string -} - -export interface GameInfo { - id: string - name: string - boxArtUrl: string - viewerCount?: number -} - -export interface VodInfo { - id: string - title: string - createdAt: string - durationSeconds: number - viewCount: number - thumbnailUrl: string -} - -export interface VodProgress { - resumePositionSeconds: number - watchedAt: number - completed: boolean -} - -export interface VodChapter { - positionSeconds: number - durationSeconds: number - gameName: string - gameId: string | null -} - -export interface TopStreamsResult { - streams: FollowedChannelInfo[] - cursor?: string +export type { + AuthStatus, + DeviceFlowStartInfo, + AuthEvent, + FollowedChannelInfo, + OwnUserInfo, + PlaybackEvent, + HlsUrlPayload, + GameInfo, + VodInfo, + VodProgress, + VodChapter, + TopStreamsResult } const api = { diff --git a/src/renderer/src/types/t4sd.d.ts b/src/renderer/src/types/t4sd.d.ts index b08baa5..c958958 100644 --- a/src/renderer/src/types/t4sd.d.ts +++ b/src/renderer/src/types/t4sd.d.ts @@ -1,92 +1,37 @@ -// Spiegel der Preload-API. Manuell synchron halten zu src/preload/index.ts. -// IPC-Channel-Namen: src/main/ipc/channels.ts (Renderer kann nicht direkt importieren). +// Data types: src/shared/types.ts (canonical source, compiler-enforced). +// T4sdApi: keep manually in sync with src/preload/index.ts. +// Direct import is not possible: tsconfig.web.json and tsconfig.node.json are separate +// composite projects — preload/index.ts is not reachable from the renderer build. -export type AuthStatus = 'logged-out' | 'logged-in' +export type { + AuthStatus, + DeviceFlowStartInfo, + AuthEvent, + FollowedChannelInfo, + OwnUserInfo, + PlaybackEvent, + HlsUrlPayload, + GameInfo, + VodInfo, + VodProgress, + VodChapter, + TopStreamsResult +} from '../../../shared/types' -export interface DeviceFlowStartInfo { - userCode: string - verificationUri: string - expiresInSec: number -} - -export type AuthEvent = - | { kind: 'authorized' } - | { kind: 'denied' } - | { kind: 'expired' } - | { kind: 'cancelled' } - | { kind: 'error'; message: string } - -export interface FollowedChannelInfo { - broadcasterId: string - broadcasterLogin: string - broadcasterName: string - profileImageUrl: string - isLive: boolean - streamTitle?: string - gameId?: string - gameName?: string - viewerCount?: number - thumbnailUrl?: string - startedAt?: string - language?: string -} - -export interface OwnUserInfo { - id: string - login: string - displayName: string - profileImageUrl: string -} - -export interface GameInfo { - id: string - name: string - boxArtUrl: string - viewerCount?: number -} - -export interface PlaybackEvent { - kind: 'started' | 'stopped' | 'error' - channelLogin?: string - message?: string - durationSeconds?: number - isLive?: boolean -} - -export interface HlsUrlPayload { - url: string - isLive: boolean - startPosition: number - durationSeconds: number - vodId?: string -} - -export interface VodInfo { - id: string - title: string - createdAt: string - durationSeconds: number - viewCount: number - thumbnailUrl: string -} - -export interface VodProgress { - resumePositionSeconds: number - watchedAt: number - completed: boolean -} - -export interface VodChapter { - positionSeconds: number - durationSeconds: number - gameName: string - gameId: string | null -} - -export interface TopStreamsResult { - streams: FollowedChannelInfo[] - cursor?: string -} +import type { + AuthStatus, + DeviceFlowStartInfo, + AuthEvent, + FollowedChannelInfo, + OwnUserInfo, + PlaybackEvent, + HlsUrlPayload, + GameInfo, + VodInfo, + VodProgress, + VodChapter, + TopStreamsResult +} from '../../../shared/types' export interface T4sdApi { appVersion: string diff --git a/src/shared/types.ts b/src/shared/types.ts new file mode 100644 index 0000000..ceda20a --- /dev/null +++ b/src/shared/types.ts @@ -0,0 +1,86 @@ +export type AuthStatus = 'logged-out' | 'logged-in' + +export interface DeviceFlowStartInfo { + userCode: string + verificationUri: string + expiresInSec: number +} + +export type AuthEvent = + | { kind: 'authorized' } + | { kind: 'denied' } + | { kind: 'expired' } + | { kind: 'cancelled' } + | { kind: 'error'; message: string } + +export interface FollowedChannelInfo { + broadcasterId: string + broadcasterLogin: string + broadcasterName: string + profileImageUrl: string + isLive: boolean + streamTitle?: string + gameId?: string + gameName?: string + viewerCount?: number + thumbnailUrl?: string + startedAt?: string + language?: string +} + +export interface OwnUserInfo { + id: string + login: string + displayName: string + profileImageUrl: string +} + +export interface PlaybackEvent { + kind: 'started' | 'stopped' | 'error' + channelLogin?: string + message?: string + durationSeconds?: number + isLive?: boolean +} + +export interface HlsUrlPayload { + url: string + isLive: boolean + startPosition: number + durationSeconds: number + vodId?: string +} + +export interface GameInfo { + id: string + name: string + boxArtUrl: string + viewerCount?: number +} + +export interface VodInfo { + id: string + title: string + createdAt: string + durationSeconds: number + viewCount: number + thumbnailUrl: string +} + +export interface VodProgress { + resumePositionSeconds: number + watchedAt: number + completed: boolean +} + +export interface VodChapter { + positionSeconds: number + durationSeconds: number + gameName: string + gameId: string | null +} + +export interface TopStreamsResult { + streams: FollowedChannelInfo[] + cursor?: string +} diff --git a/tsconfig.node.json b/tsconfig.node.json index 87080ce..19f8d0a 100644 --- a/tsconfig.node.json +++ b/tsconfig.node.json @@ -20,6 +20,7 @@ "src/main/**/*.ts", "src/main/**/*.d.ts", "src/preload/**/*.ts", - "src/preload/**/*.d.ts" + "src/preload/**/*.d.ts", + "src/shared/**/*.ts" ] } diff --git a/tsconfig.web.json b/tsconfig.web.json index f20bd43..2b32fd6 100644 --- a/tsconfig.web.json +++ b/tsconfig.web.json @@ -17,5 +17,9 @@ "resolveJsonModule": true, "allowSyntheticDefaultImports": true }, - "include": ["src/renderer/**/*.ts", "src/renderer/**/*.tsx"] + "include": [ + "src/renderer/**/*.ts", + "src/renderer/**/*.tsx", + "src/shared/**/*.ts" + ] }