From 2eec367e0521f8d170b1c4c003504c8d5327b964 Mon Sep 17 00:00:00 2001 From: Niklas Jensen Date: Tue, 30 Dec 2025 22:18:47 +0100 Subject: [PATCH] Absolutely gutting the listeners - VERY WIP --- app/src/lib/stores/socket.ts | 59 +++++++++++++++---------- platform_shared/websocket_message.proto | 6 +++ 2 files changed, 42 insertions(+), 23 deletions(-) diff --git a/app/src/lib/stores/socket.ts b/app/src/lib/stores/socket.ts index b1000b0..73a485f 100644 --- a/app/src/lib/stores/socket.ts +++ b/app/src/lib/stores/socket.ts @@ -1,12 +1,34 @@ import { writable } from 'svelte/store' import { encode, decode } from '@msgpack/msgpack' -import { WebsocketMessage, type MessageFns } from '$lib/platform_shared/websocket_message' +import { WebsocketMessage, type MessageFns, protoMetadata as websocket_md } from '$lib/platform_shared/websocket_message' import * as WebsocketMessages from '$lib/platform_shared/websocket_message' import type { BinaryWriter } from '@bufbuild/protobuf/wire' -// Auto-build reverse mapping from MessageFns to event key + +// -------- START PARSING PROTO DATA -------- +// Auto-build reverse mapping from MessageFns to event key and field number const MESSAGE_TYPE_TO_KEY = new Map, string>() -function get_event_from_messagetype(event_type: MessageFns) { +const MESSAGE_TYPE_TO_FIELD_NUMBER = new Map, number>() + +// Build the mapping using references from metadata +const websocketMessageType = websocket_md.fileDescriptor.messageType?.find( + msg => msg.name === 'WebsocketMessage' +) + +if (websocketMessageType?.field) { + for (const field of websocketMessageType.field) { + // Look up the MessageFns in references using the typeName + if (field.typeName) { + const messageFns = websocket_md.references[field.typeName] + if (messageFns && field.jsonName && field.number) { + MESSAGE_TYPE_TO_KEY.set(messageFns, field.jsonName) + MESSAGE_TYPE_TO_FIELD_NUMBER.set(messageFns, field.number) + } + } + } +} + +function get_name_from_messagetype(event_type: MessageFns): string { const event = MESSAGE_TYPE_TO_KEY.get(event_type) if (!event) { throw new Error("Event type not found in 'WebsocketMessage'. The MessageFns you passed doesn't correspond to any WebsocketMessage field."); @@ -14,27 +36,17 @@ function get_event_from_messagetype(event_type: MessageFns) { return event } -// Iterate through all exports and match them to WebsocketMessage fields -for (const [exportName, exportValue] of Object.entries(WebsocketMessages)) { - // Check if this export is a MessageFns (has encode/decode methods) - if (exportValue && typeof exportValue === 'object' && 'encode' in exportValue && 'decode' in exportValue) { - // Try to find matching key in WebsocketMessage by creating an instance and checking - const messageKeys = Object.keys(WebsocketMessage.create()) as Array - - for (const key of messageKeys) { - // Match by naming convention: exportName should match key in some pattern - // Common patterns: "IMUData" -> "imu", "RSSIData" -> "rssi" - const keyLower = key.toLowerCase() - const exportLower = exportName.toLowerCase().replace(/data$/, '') - - if (keyLower === exportLower) { - MESSAGE_TYPE_TO_KEY.set(exportValue as MessageFns, key) - break - } - } +// Get field number from MessageFns type +function get_field_number_from_messagetype(event_type: MessageFns): number { + const fieldNumber = MESSAGE_TYPE_TO_FIELD_NUMBER.get(event_type) + if (fieldNumber === undefined) { + throw new Error("Field number not found in 'WebsocketMessage'. The MessageFns you passed doesn't correspond to any WebsocketMessage field."); } + return fieldNumber } +// -------- END PARSING PROTO DATA -------- + const socketEvents = ['open', 'close', 'error', 'message', 'unresponsive'] as const type SocketEvent = (typeof socketEvents)[number] @@ -60,7 +72,8 @@ const encodeMessage = (data: WebsocketMessage): Uint8Array => { } function createWebSocket() { - const listeners = new Map void>>() + const msg_listeners = new Map void>>() + const event_listeners = new Map void>>() const { subscribe, set } = writable(false) const reconnectTimeoutTime = 5000 let unresponsiveTimeoutId: ReturnType @@ -74,7 +87,7 @@ function createWebSocket() { } function getListeners(event_type: MessageFns): Set<(data?: unknown) => void> { - const event = get_event_from_messagetype(event_type); + const event = get_field_number_from_messagetype(event_type); const event_listeners = listeners.get(event); if (event_listeners == undefined) { diff --git a/platform_shared/websocket_message.proto b/platform_shared/websocket_message.proto index 34abf9c..9a990be 100644 --- a/platform_shared/websocket_message.proto +++ b/platform_shared/websocket_message.proto @@ -27,6 +27,12 @@ message RSSIData { int32 rssi = 1; } message SubscribeNotification {} message UnsubscribeNotification {} +message InternalOpen {} +message InternalClose {} +message InternalError {} +message InternalMessage {} +message InternalUnresponsive {} + // WebSocket message wrapper // Only ONE field will be set at a time (oneof ensures this)