Revert "feat: sync individual content installation states on panel" (#7154)

Revert "feat: sync individual content installation states on panel (#6909)"

This reverts commit 9628b4c269.
This commit is contained in:
Prospector
2026-08-14 10:47:08 -07:00
committed by GitHub
parent 37a5e14657
commit 1dba3bfee8
54 changed files with 2428 additions and 2005 deletions
@@ -9,7 +9,6 @@ export type WebSocketEventHandler<
export interface WebSocketConnection {
serverId: string
socket: WebSocket
authenticated: boolean
reconnectAttempts: number
reconnectTimer?: ReturnType<typeof setTimeout>
isReconnecting: boolean
@@ -32,7 +31,6 @@ export abstract class AbstractWebSocketClient {
protected readonly MAX_RECONNECT_ATTEMPTS = 10
protected readonly RECONNECT_BASE_DELAY = 1000
protected readonly RECONNECT_MAX_DELAY = 30000
protected readonly AUTHENTICATION_TIMEOUT = 30000
constructor(
protected client: {
@@ -60,7 +58,6 @@ export abstract class AbstractWebSocketClient {
}
if (status && !status.connected && !options?.force) {
await this.waitForAuthentication(serverId)
return
}
@@ -72,28 +69,6 @@ export abstract class AbstractWebSocketClient {
await this.connect(serverId, auth)
}
protected async waitForAuthentication(serverId: string): Promise<void> {
await new Promise<void>((resolve, reject) => {
let unsubscribe = () => {}
const timeout = setTimeout(() => {
unsubscribe()
reject(new Error(`WebSocket authentication timed out for server ${serverId}`))
}, this.AUTHENTICATION_TIMEOUT)
unsubscribe = this.on(serverId, 'auth-ok', () => {
clearTimeout(timeout)
unsubscribe()
resolve()
})
if (this.getStatus(serverId)?.connected) {
clearTimeout(timeout)
unsubscribe()
resolve()
}
})
}
on<E extends Archon.Websocket.v0.WSEventType>(
serverId: string,
eventType: E,
@@ -113,7 +88,7 @@ export abstract class AbstractWebSocketClient {
if (!connection) return null
return {
connected: connection.socket.readyState === WebSocket.OPEN && connection.authenticated,
connected: connection.socket.readyState === WebSocket.OPEN,
reconnecting: connection.isReconnecting,
reconnectAttempts: connection.reconnectAttempts,
}
@@ -301,24 +301,13 @@ export namespace Archon {
environment?: Labrinth.Projects.v3.Environment | null
}
export type AddonStatus =
| 'pending'
| 'installed'
| {
failed: {
error: string
}
}
export type Addon = {
id: string
filename: string
filesize: number
btime?: string
disabled: boolean
kind: AddonKind
from_modpack: boolean
status: AddonStatus
pack_client_retained: boolean
pack_client_depends: boolean
has_update: string | null
@@ -334,10 +323,6 @@ export namespace Archon {
modloader_version: string | null
game_version: string | null
modpack: ModpackFields | null
installing?: 'loader' | 'modpack'
error?: {
message: string
}
addons: Addon[] | null
}
@@ -1004,78 +989,6 @@ export namespace Archon {
world_id: string
spec: Archon.Content.v1.Addons
}
export type WorldContentPlatform =
| 'forge'
| 'neoforge'
| 'fabric'
| 'quilt'
| 'paper'
| 'purpur'
| 'vanilla'
export type WorldContentPlatformData = {
platform: WorldContentPlatform
game_version: string
platform_version: string | null
}
export type WorldContentModpackSource =
| 'CurseForge'
| {
Modrinth: {
version_id: string
project_id: string
mrpack_sha1: string | null
}
}
| {
LocalMrPackFile: {
path: string
name: string
description: string | null
version_name: string | null
}
}
export type WorldContentModpack = {
spec: WorldContentModpackSource
downloads: number | null
followers: number | null
icon_url: string | null
owner: Archon.Content.v1.ContentOwner | null
title: string | null
description: string | null
version_number: string | null
date_published: string | null
environment: Labrinth.Projects.v3.Environment | null
has_update: string | null
}
export type WorldContentItem = {
parent_directory: string
file_sha1: string | null
filename: string
btime?: string
from_modpack: boolean
version_id: string | null
project_id: string | null
pack_client_retained: boolean
pack_client_depends: boolean
status: Archon.Content.v1.AddonStatus
filesize: number | null
name: string | null
version: Archon.Content.v1.AddonVersion | null
owner: Archon.Content.v1.ContentOwner | null
has_update: string | null
icon_url: string | null
}
export type WorldContentUpdateEvent = {
type: 'world.content.update'
world_id: string
platform_data: WorldContentPlatformData | null
linked_modpack: WorldContentModpack | null
installing?: 'loader' | 'modpack'
error?: {
message: string
}
content: WorldContentItem[]
}
export type SyncEvent =
| ProtocolResetEvent
@@ -1094,7 +1007,6 @@ export namespace Archon {
| WorldStartupPatchEvent
| WorldContentAddonPatchEvent
| WorldContentBaseUpdateEvent
| WorldContentUpdateEvent
}
}
@@ -1199,53 +1111,6 @@ export namespace Archon {
version_id: string
}
export type InstallProgressFileKey = {
type: 'file'
install_type: 'install' | 'update'
project_id: string
version_id: string
parent_directory: string
source_filename: string | null
target_filename?: string | null
}
export type InstallProgressModrinthModpackKey = {
type: 'modrinth_modpack'
project_id: string
version_id: string
}
export type InstallProgressLocalModpackKey = {
type: 'local_modpack'
filename: string
}
export type InstallProgressPlatformKey = {
type: 'platform'
platform: 'forge' | 'neoforge' | 'fabric' | 'quilt' | 'paper' | 'purpur' | 'vanilla'
platform_version: string
game_version: string
}
export type InstallProgressKey =
| InstallProgressFileKey
| InstallProgressModrinthModpackKey
| InstallProgressLocalModpackKey
| InstallProgressPlatformKey
export type InstallProgressItem = {
world_id: string
key: InstallProgressKey
id: string
progress: number | null
error: string | null
}
export type WSInstallProgressEvent = {
event: 'install-progress'
items: InstallProgressItem[]
}
export type FilesystemOpKind = 'unarchive'
export type FilesystemOpState =
@@ -1343,7 +1208,6 @@ export namespace Archon {
| WSInstallationResultEvent
| WSUptimeEvent
| WSNewModEvent
| WSInstallProgressEvent
| WSFilesystemOpsEvent
export type WSEventType = WSEvent['event']
@@ -19,60 +19,36 @@ export class GenericWebSocketClient extends AbstractWebSocketClient {
}
return new Promise((resolve, reject) => {
let settled = false
let authenticationTimeout: ReturnType<typeof setTimeout> | null = null
const resolveConnection = () => {
if (settled) return
settled = true
if (authenticationTimeout) clearTimeout(authenticationTimeout)
resolve()
}
const rejectConnection = (error: unknown) => {
if (settled) return
settled = true
if (authenticationTimeout) clearTimeout(authenticationTimeout)
reject(error)
}
try {
const ws = new WebSocket(getNodeWebSocketUrl(auth.url))
const connection: WebSocketConnection = {
serverId,
socket: ws,
authenticated: false,
reconnectAttempts: 0,
reconnectTimer: undefined,
isReconnecting: false,
}
this.connections.set(serverId, connection)
authenticationTimeout = setTimeout(() => {
rejectConnection(new Error(`WebSocket authentication timed out for server ${serverId}`))
if (this.connections.get(serverId) === connection) this.closeConnection(serverId)
}, this.AUTHENTICATION_TIMEOUT)
ws.onopen = () => {
ws.send(JSON.stringify({ event: 'auth', jwt: auth.token }))
connection.reconnectAttempts = 0
connection.isReconnecting = false
resolve()
}
ws.onmessage = (messageEvent) => {
try {
const data = JSON.parse(messageEvent.data) as Archon.Websocket.v0.WSEvent
if (data.event === 'auth-ok') {
connection.authenticated = true
} else if (data.event === 'auth-incorrect') {
connection.authenticated = false
}
const eventKey = `${serverId}:${data.event}` as keyof WSEventMap
// eslint-disable-next-line @typescript-eslint/no-explicit-any
this.emitter.emit(eventKey, data as any)
if (data.event === 'auth-ok') resolveConnection()
if (data.event === 'auth-expiring' || data.event === 'auth-incorrect') {
this.handleAuthExpiring(serverId).catch(console.error)
}
@@ -82,17 +58,11 @@ export class GenericWebSocketClient extends AbstractWebSocketClient {
}
ws.onclose = (event) => {
connection.authenticated = false
console.debug(`[WebSocket] Closed for server ${serverId}:`, {
code: event.code,
reason: event.reason,
wasClean: event.wasClean,
})
rejectConnection(
new Error(
`WebSocket closed before authentication for server ${serverId} (code: ${event.code})`,
),
)
if (event.code !== NORMAL_CLOSURE) {
this.scheduleReconnect(serverId, auth)
}
@@ -107,14 +77,14 @@ export class GenericWebSocketClient extends AbstractWebSocketClient {
readyStateLabel: ['CONNECTING', 'OPEN', 'CLOSING', 'CLOSED'][readyState],
type: (event as Event).type,
})
rejectConnection(
reject(
new Error(
`WebSocket connection failed for server ${serverId} (readyState: ${readyState})`,
),
)
}
} catch (error) {
rejectConnection(error)
reject(error)
}
})
}