{"version":3,"sources":["../../../src/messages/messages-provider.tsx"],"sourcesContent":["import mqtt, { MqttClient } from 'mqtt'\nimport { createContext, useCallback, useEffect, useMemo, useRef } from 'react'\n\nexport const MessagesContext = createContext<{\n  log: (...params: any[]) => void\n  connect: () => void\n  client: MqttClient | null\n  registerListener: (\n    topic: string,\n    listener: (topic: string, message: string) => void,\n  ) => (() => void) | undefined\n  removeListener: (topic: string, index: number) => void\n  disconnect: () => void\n} | null>(null)\n\ntype TListenerCallback = (topic: string, message: string) => void\ntype TListener = { queued?: boolean; callback: TListenerCallback }\n\nexport interface IMessagesProviderProps {\n  children?: React.ReactNode\n  url: string\n  enableDebugging?: boolean\n}\n\nexport default function MessagesProvider({\n  children,\n  url,\n  enableDebugging=false,\n}: IMessagesProviderProps) {\n  const clientRef = useRef<MqttClient | null>(null)\n\n  const listenersRef = useRef<Record<string, TListener>>({})\n\n  const log = useCallback(\n    (...params: any[]) => {\n      if (!enableDebugging) return\n      console.log('[mqtt]:', ...params)\n    },\n    [enableDebugging],\n  )\n\n  const subscribeTopics = useCallback(\n    (topic: string) => {\n      clientRef.current?.subscribe(topic, { qos: 0 })\n      log(`subscribed to topic:`, topic)\n    },\n    [clientRef.current],\n  )\n\n  const removeListener = useCallback(\n    (topic: string) => {\n      log(`removing the listener from topic: ${topic}`)\n      log(`unsubscribed to topic: ${topic}`)\n      clientRef.current?.unsubscribe(topic)\n    },\n    [clientRef.current],\n  )\n\n  const registerListener = useCallback(\n    (topic: string, listener: TListenerCallback) => {\n      listenersRef.current[topic] = {\n        queued: !clientRef.current || !clientRef.current.connected,\n        callback: listener,\n      }\n      subscribeTopics(topic)\n\n      return () => removeListener(topic)\n    },\n    [subscribeTopics, removeListener],\n  )\n\n  const connect = useCallback(() => {\n    if (clientRef.current && clientRef.current.connected) return\n\n    try {\n      const optionsMqtt: mqtt.IClientOptions = {\n        clientId: `computer-vision-${Math.random()\n          .toString(16)\n          .substring(2, 8)}`,\n      }\n\n      clientRef.current = mqtt.connect(url, optionsMqtt)\n\n      clientRef.current.on('connect', () => {\n        log('connected')\n\n        // Loop through all queued listeners and register them\n        Object.keys(listenersRef.current).forEach((topic) => {\n          const listener = listenersRef.current[topic]\n          if (!listener) return\n          if (listener.queued) {\n            subscribeTopics(topic)\n            listener.queued = false\n          }\n        })\n      })\n\n      clientRef.current.on('error', (err) => {\n        console.error('Connection error:', err)\n        clientRef.current?.end()\n      })\n\n      clientRef.current.on('reconnect', () => {\n        log(`reconnect`)\n      })\n\n      clientRef.current.on('message', (topic, message) => {\n        const listener = listenersRef.current[topic]\n        listener?.callback(topic, message.toString())\n      })\n\n      return clientRef.current\n    } catch (error) {\n      log(`error: `, error)\n    }\n  }, [url, subscribeTopics])\n\n  const disconnect = useCallback(() => {\n    clientRef.current?.end()\n    clientRef.current = null\n  }, [clientRef.current])\n\n  const options = useMemo(\n    () => ({\n      log,\n      connect,\n      client: clientRef.current,\n      registerListener,\n      removeListener,\n      disconnect,\n    }),\n    [connect, clientRef.current, registerListener, removeListener, disconnect],\n  )\n\n  const renderMqttProvider = () => {\n    return (\n      <MessagesContext.Provider value={options}>\n        {children}\n      </MessagesContext.Provider>\n    )\n  }\n\n  useEffect(() => {\n    const client = clientRef.current || connect()\n    return () => {\n      if (client && client.connected) {\n        client.end()\n        clientRef.current = null\n        log('disconnected: ' + client.disconnected)\n      }\n    }\n  }, [])\n\n  return renderMqttProvider()\n}\n"],"mappings":"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","names":["mqtt"]}