@techolution-ai/computer-vision
Advanced tools
Comparing version
@@ -6,2 +6,3 @@ import * as react_jsx_runtime from 'react/jsx-runtime'; | ||
declare const MessagesContext: React$1.Context<{ | ||
log: (...params: any[]) => void; | ||
connect: () => void; | ||
@@ -16,5 +17,6 @@ client: MqttClient | null; | ||
url: string; | ||
enableDebugging?: boolean; | ||
} | ||
declare function MessagesProvider({ children, url, }: IMessagesProviderProps): react_jsx_runtime.JSX.Element; | ||
declare function MessagesProvider({ children, url, enableDebugging, }: IMessagesProviderProps): react_jsx_runtime.JSX.Element; | ||
export { type IMessagesProviderProps, MessagesContext, MessagesProvider as default }; |
// src/messages/messages-provider.tsx | ||
import mqtt from "mqtt"; | ||
import { createContext, useCallback, useEffect, useRef } from "react"; | ||
import { createContext, useCallback, useEffect, useMemo, useRef } from "react"; | ||
import { jsx } from "react/jsx-runtime"; | ||
@@ -8,33 +8,42 @@ var MessagesContext = createContext(null); | ||
children, | ||
url | ||
url, | ||
enableDebugging = false | ||
}) { | ||
const clientRef = useRef(null); | ||
const listenersRef = useRef({}); | ||
const subscribeTopics = (topic, index) => { | ||
clientRef.current?.subscribe(topic, { qos: 0 }); | ||
}; | ||
const registerListener = (topic, listener) => { | ||
if (!listenersRef.current[topic]) { | ||
listenersRef.current[topic] = []; | ||
} | ||
listenersRef.current[topic].push({ | ||
queued: !clientRef.current || !clientRef.current.connected, | ||
callback: listener | ||
}); | ||
const index = listenersRef.current[topic].length - 1; | ||
subscribeTopics(topic, index); | ||
return () => removeListener(topic, index); | ||
}; | ||
const removeListener = (topic, index) => { | ||
if (!listenersRef.current[topic]) { | ||
listenersRef.current[topic] = []; | ||
} | ||
if (index >= 0 && index < listenersRef.current[topic].length) { | ||
listenersRef.current[topic].splice(index, 1); | ||
} | ||
if (listenersRef.current[topic].length === 0 && clientRef.current && clientRef.current.connected) { | ||
const log = useCallback( | ||
(...params) => { | ||
if (!enableDebugging) return; | ||
console.log("[mqtt]:", ...params); | ||
}, | ||
[enableDebugging] | ||
); | ||
const subscribeTopics = useCallback( | ||
(topic) => { | ||
clientRef.current?.subscribe(topic, { qos: 0 }); | ||
log(`subscribed to topic:`, topic); | ||
}, | ||
[clientRef.current] | ||
); | ||
const removeListener = useCallback( | ||
(topic) => { | ||
log(`removing the listener from topic: ${topic}`); | ||
log(`unsubscribed to topic: ${topic}`); | ||
clientRef.current?.unsubscribe(topic); | ||
} | ||
}; | ||
}, | ||
[clientRef.current] | ||
); | ||
const registerListener = useCallback( | ||
(topic, listener) => { | ||
listenersRef.current[topic] = { | ||
queued: !clientRef.current || !clientRef.current.connected, | ||
callback: listener | ||
}; | ||
subscribeTopics(topic); | ||
return () => removeListener(topic); | ||
}, | ||
[subscribeTopics, removeListener] | ||
); | ||
const connect = useCallback(() => { | ||
if (clientRef.current && clientRef.current.connected) return; | ||
try { | ||
@@ -46,44 +55,45 @@ const optionsMqtt = { | ||
clientRef.current.on("connect", () => { | ||
log("connected"); | ||
Object.keys(listenersRef.current).forEach((topic) => { | ||
listenersRef.current[topic].forEach((listener, index) => { | ||
if (listener.queued) { | ||
subscribeTopics(topic, index); | ||
listener.queued = false; | ||
} | ||
}); | ||
const listener = listenersRef.current[topic]; | ||
if (!listener) return; | ||
if (listener.queued) { | ||
subscribeTopics(topic); | ||
listener.queued = false; | ||
} | ||
}); | ||
}); | ||
clientRef.current.on("error", (err) => { | ||
console.error("[mqtt]: Connection error:", err); | ||
console.error("Connection error:", err); | ||
clientRef.current?.end(); | ||
}); | ||
clientRef.current.on("reconnect", () => { | ||
log(`reconnect`); | ||
}); | ||
clientRef.current.on("message", (topic, message) => { | ||
for (const listener of listenersRef.current[topic] || []) { | ||
listener.callback(topic, message.toString()); | ||
} | ||
const listener = listenersRef.current[topic]; | ||
listener?.callback(topic, message.toString()); | ||
}); | ||
return clientRef.current; | ||
} catch (error) { | ||
log(`error: `, error); | ||
} | ||
}, []); | ||
}, [url, subscribeTopics]); | ||
const disconnect = useCallback(() => { | ||
clientRef.current?.end(); | ||
clientRef.current = null; | ||
}, []); | ||
}, [clientRef.current]); | ||
const options = useMemo( | ||
() => ({ | ||
log, | ||
connect, | ||
client: clientRef.current, | ||
registerListener, | ||
removeListener, | ||
disconnect | ||
}), | ||
[connect, clientRef.current, registerListener, removeListener, disconnect] | ||
); | ||
const renderMqttProvider = () => { | ||
return /* @__PURE__ */ jsx( | ||
MessagesContext.Provider, | ||
{ | ||
value: { | ||
connect, | ||
client: clientRef.current, | ||
registerListener, | ||
removeListener, | ||
disconnect | ||
}, | ||
children | ||
} | ||
); | ||
return /* @__PURE__ */ jsx(MessagesContext.Provider, { value: options, children }); | ||
}; | ||
@@ -96,5 +106,6 @@ useEffect(() => { | ||
clientRef.current = null; | ||
log("disconnected: " + client.disconnected); | ||
} | ||
}; | ||
}, [connect]); | ||
}, []); | ||
return renderMqttProvider(); | ||
@@ -101,0 +112,0 @@ } |
@@ -14,5 +14,5 @@ interface IUseMessagesProps<TTopic extends string> { | ||
removeListener: (topic: string) => void; | ||
registerListener: (topic: string) => () => void; | ||
registerListener: (topic: string) => void; | ||
}; | ||
export { useMessages as default }; |
@@ -10,4 +10,3 @@ // src/messages/use-messages.tsx | ||
}, | ||
onMessage = () => { | ||
}, | ||
onMessage, | ||
onClose = () => { | ||
@@ -23,62 +22,52 @@ } | ||
(topic, message) => { | ||
const item = map[topic]; | ||
if (item) { | ||
setMap((prev) => { | ||
const newMap = { ...prev }; | ||
newMap[topic].messages.push(message); | ||
return newMap; | ||
}); | ||
} | ||
setMap((prev) => { | ||
const newMap = { ...prev }; | ||
if (!newMap[topic]) { | ||
newMap[topic] = { messages: [], removeListener: () => { | ||
} }; | ||
} | ||
newMap[topic].messages.push(message); | ||
return newMap; | ||
}); | ||
if (onMessage) onMessage(topic, message); | ||
}, | ||
[onMessage, map] | ||
[onMessage] | ||
); | ||
const registerListener = useCallback( | ||
(topic) => { | ||
if (map[topic]) { | ||
return; | ||
} | ||
const removeFn = context?.registerListener( | ||
topic, | ||
handleOnMessageReceiveFromContext | ||
); | ||
if (!removeFn) return; | ||
setMap((prev) => { | ||
if (prev[topic]) return prev; | ||
const removeFn = context?.registerListener( | ||
topic, | ||
handleOnMessageReceiveFromContext | ||
); | ||
if (!removeFn) return prev; | ||
return { ...prev, [topic]: { messages: [], removeListener: removeFn } }; | ||
}); | ||
return removeFn; | ||
}, | ||
[context, map, handleOnMessageReceiveFromContext] | ||
[context, handleOnMessageReceiveFromContext] | ||
); | ||
const removeListener = useCallback( | ||
(topic) => { | ||
const item = map[topic]; | ||
if (item) { | ||
item.removeListener(); | ||
setMap((prev) => { | ||
const newMap = { ...prev }; | ||
delete newMap[topic]; | ||
return newMap; | ||
}); | ||
} | ||
}, | ||
[map] | ||
); | ||
const removeListener = useCallback((topic) => { | ||
setMap((prev) => { | ||
if (!prev[topic]) return prev; | ||
prev[topic].removeListener(); | ||
const newMap = { ...prev }; | ||
delete newMap[topic]; | ||
return newMap; | ||
}); | ||
}, []); | ||
useEffect(() => { | ||
topics.forEach((topic) => { | ||
registerListener(topic); | ||
if (!map[topic]) { | ||
registerListener(topic); | ||
} | ||
}); | ||
return () => { | ||
topics.forEach((topic) => { | ||
removeListener(topic); | ||
Object.keys(map).forEach((topic) => { | ||
if (!topics.includes(topic)) { | ||
removeListener(topic); | ||
} | ||
}); | ||
}; | ||
}, [topics, registerListener, removeListener]); | ||
useEffect(() => { | ||
return () => { | ||
topics.forEach((topic) => { | ||
removeListener(topic); | ||
}); | ||
}; | ||
}, [removeListener, topics]); | ||
return useMemo( | ||
@@ -85,0 +74,0 @@ () => ({ messages: map, removeListener, registerListener }), |
{ | ||
"name": "@techolution-ai/computer-vision", | ||
"version": "0.0.6", | ||
"version": "0.0.7", | ||
"private": false, | ||
@@ -5,0 +5,0 @@ "license": "MIT", |
@@ -200,2 +200,3 @@ # @techolution-ai/computer-vision | ||
| url | string | -- | Required | | ||
| enableDebugging | boolean | false | Optional, to enable logging | | ||
@@ -202,0 +203,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
727300
0.02%1653
0.12%274
0.37%