@ramme-io/create-app 1.1.4 → 1.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
package/template/pkg.json
CHANGED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import React, { createContext, useContext, useEffect, useRef, useState } from 'react';
|
|
2
|
+
import mqtt, { MqttClient } from 'mqtt';
|
|
3
|
+
|
|
4
|
+
interface MqttContextType {
|
|
5
|
+
isConnected: boolean;
|
|
6
|
+
lastMessage: Record<string, string>;
|
|
7
|
+
publish: (topic: string, message: string) => void;
|
|
8
|
+
subscribe: (topic: string) => void;
|
|
9
|
+
unsubscribe: (topic: string) => void;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const MqttContext = createContext<MqttContextType | null>(null);
|
|
13
|
+
|
|
14
|
+
// Public Test Broker for "Out of the Box" functionality
|
|
15
|
+
// In a real app, this comes from config.ts
|
|
16
|
+
const DEFAULT_BROKER = 'wss://test.mosquitto.org:8081';
|
|
17
|
+
|
|
18
|
+
export const MqttProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
|
|
19
|
+
const [isConnected, setIsConnected] = useState(false);
|
|
20
|
+
const [lastMessage, setLastMessage] = useState<Record<string, string>>({});
|
|
21
|
+
const clientRef = useRef<MqttClient | null>(null);
|
|
22
|
+
|
|
23
|
+
// Track active subscriptions to avoid double-subscribing
|
|
24
|
+
const subscriptions = useRef<Set<string>>(new Set());
|
|
25
|
+
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
console.log(`[MQTT] Connecting to ${DEFAULT_BROKER}...`);
|
|
28
|
+
|
|
29
|
+
const client = mqtt.connect(DEFAULT_BROKER);
|
|
30
|
+
clientRef.current = client;
|
|
31
|
+
|
|
32
|
+
client.on('connect', () => {
|
|
33
|
+
console.log('[MQTT] Connected ✅');
|
|
34
|
+
setIsConnected(true);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
client.on('message', (topic: any, message: { toString: () => any; }) => {
|
|
38
|
+
const payload = message.toString();
|
|
39
|
+
setLastMessage((prev) => ({ ...prev, [topic]: payload }));
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
client.on('error', (err: any) => {
|
|
43
|
+
console.error('[MQTT] Connection error: ', err);
|
|
44
|
+
client.end();
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
return () => {
|
|
48
|
+
console.log('[MQTT] Disconnecting...');
|
|
49
|
+
client.end();
|
|
50
|
+
};
|
|
51
|
+
}, []);
|
|
52
|
+
|
|
53
|
+
const subscribe = (topic: string) => {
|
|
54
|
+
if (clientRef.current && !subscriptions.current.has(topic)) {
|
|
55
|
+
console.log(`[MQTT] Subscribing to: ${topic}`);
|
|
56
|
+
clientRef.current.subscribe(topic);
|
|
57
|
+
subscriptions.current.add(topic);
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const unsubscribe = (topic: string) => {
|
|
62
|
+
if (clientRef.current && subscriptions.current.has(topic)) {
|
|
63
|
+
clientRef.current.unsubscribe(topic);
|
|
64
|
+
subscriptions.current.delete(topic);
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const publish = (topic: string, message: string) => {
|
|
69
|
+
if (clientRef.current) {
|
|
70
|
+
clientRef.current.publish(topic, message);
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
return (
|
|
75
|
+
<MqttContext.Provider value={{ isConnected, lastMessage, subscribe, unsubscribe, publish }}>
|
|
76
|
+
{children}
|
|
77
|
+
</MqttContext.Provider>
|
|
78
|
+
);
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
export const useMqtt = () => {
|
|
82
|
+
const context = useContext(MqttContext);
|
|
83
|
+
if (!context) throw new Error('useMqtt must be used within an MqttProvider');
|
|
84
|
+
return context;
|
|
85
|
+
};
|
package/template/src/main.tsx
CHANGED
|
@@ -3,7 +3,8 @@ import ReactDOM from 'react-dom/client';
|
|
|
3
3
|
import { BrowserRouter } from 'react-router-dom';
|
|
4
4
|
import App from './App.tsx';
|
|
5
5
|
import { ThemeProvider, ToastProvider } from '@ramme-io/ui';
|
|
6
|
-
import { AuthProvider } from './contexts/AuthContext';
|
|
6
|
+
import { AuthProvider } from './contexts/AuthContext';
|
|
7
|
+
import { MqttProvider } from './contexts/MqttContext';
|
|
7
8
|
import '@ramme-io/ui/style.css';
|
|
8
9
|
import './index.css';
|
|
9
10
|
|
|
@@ -15,9 +16,10 @@ ReactDOM.createRoot(document.getElementById('root')!).render(
|
|
|
15
16
|
<BrowserRouter>
|
|
16
17
|
<ThemeProvider>
|
|
17
18
|
<ToastProvider>
|
|
18
|
-
{/* 2. Wrap the entire App component with the AuthProvider */}
|
|
19
19
|
<AuthProvider>
|
|
20
|
-
<
|
|
20
|
+
<MqttProvider>
|
|
21
|
+
<App />
|
|
22
|
+
</MqttProvider>
|
|
21
23
|
</AuthProvider>
|
|
22
24
|
</ToastProvider>
|
|
23
25
|
</ThemeProvider>
|