Refactor ApiServerContext to improve socket event handling and authentication

- Updated socket connection to use 'user' type for authentication.
- Refactored event handling methods for object updates and new objects to use more descriptive names.
- Enhanced subscription methods for object updates and types, ensuring better organization and clarity.
- Introduced new methods for fetching template previews, generating host OTP, and sending object actions.
- Improved logging for better debugging and tracking of socket events.
This commit is contained in:
Tom Butcher 2025-08-18 00:56:39 +01:00
parent e4ab4ea9c7
commit 93848602bb

View File

@ -77,20 +77,23 @@ const ApiServerProvider = ({ children }) => {
const newSocket = io(config.apiServerUrl, { const newSocket = io(config.apiServerUrl, {
reconnectionAttempts: 3, reconnectionAttempts: 3,
timeout: 3000, timeout: 3000,
auth: { token: token } auth: { type: 'user' }
}) })
setConnecting(true) setConnecting(true)
newSocket.on('connect', () => { newSocket.on('connect', () => {
logger.debug('Api Server connected') logger.debug('Api Server connected')
setConnecting(false) newSocket.emit('authenticate', { token: token }, (result) => {
setConnected(true) console.log('Auth result', result)
setError(null) setConnecting(false)
setConnected(true)
setError(null)
})
}) })
newSocket.on('notify_object_update', notifyObjectUpdate) newSocket.on('objectUpdate', handleObjectUpdate)
newSocket.on('notify_object_new', notifyObjectNew) newSocket.on('objectNew', handleObjectNew)
newSocket.on('notify_lock_update', notifyLockUpdate) newSocket.on('notify_lock_update', notifyLockUpdate)
newSocket.on('disconnect', () => { newSocket.on('disconnect', () => {
@ -181,34 +184,41 @@ const ApiServerProvider = ({ children }) => {
} }
} }
const notifyObjectUpdate = async (object) => { const handleObjectUpdate = async (data) => {
logger.debug('Notifying object update:', object) logger.debug('Notifying object update:', data)
const objectId = object._id || object.id const id = data._id
const objectType = data.objectType
if (objectId && subscribedCallbacksRef.current.has(objectId)) { const callbacksRefKey = `${objectType}:${id}`
const callbacks = subscribedCallbacksRef.current.get(objectId)
if (
id &&
objectType &&
subscribedCallbacksRef.current.has(callbacksRefKey)
) {
const callbacks = subscribedCallbacksRef.current.get(callbacksRefKey)
logger.debug( logger.debug(
`Calling ${callbacks.length} callbacks for object:`, `Calling ${callbacks.length} callbacks for object:`,
objectId callbacksRefKey
) )
callbacks.forEach((callback) => { callbacks.forEach((callback) => {
try { try {
callback(object) callback(data.object)
} catch (error) { } catch (error) {
logger.error('Error in object update callback:', error) logger.error('Error in object update callback:', error)
} }
}) })
} else { } else {
logger.debug( logger.debug(
`No callbacks found for object: ${objectId}, subscribed callbacks:`, `No callbacks found for object: ${callbacksRefKey}, subscribed callbacks:`,
Array.from(subscribedCallbacksRef.current.keys()) Array.from(subscribedCallbacksRef.current.keys())
) )
} }
} }
const notifyObjectNew = async (object) => { const handleObjectNew = async (data) => {
logger.debug('Notifying object new:', object) logger.debug('Notifying object new:', data)
const objectType = object.type || 'unknown' const objectType = data.objectType || 'unknown'
if (objectType && subscribedCallbacksRef.current.has(objectType)) { if (objectType && subscribedCallbacksRef.current.has(objectType)) {
const callbacks = subscribedCallbacksRef.current.get(objectType) const callbacks = subscribedCallbacksRef.current.get(objectType)
@ -218,7 +228,7 @@ const ApiServerProvider = ({ children }) => {
) )
callbacks.forEach((callback) => { callbacks.forEach((callback) => {
try { try {
callback(object) callback(data.object)
} catch (error) { } catch (error) {
logger.error('Error in object new callback:', error) logger.error('Error in object new callback:', error)
} }
@ -231,7 +241,7 @@ const ApiServerProvider = ({ children }) => {
} }
} }
const offUpdateEvent = useCallback((id, type, callback) => { const offObjectUpdatesEvent = useCallback((id, objectType, callback) => {
if (socketRef.current && socketRef.current.connected == true) { if (socketRef.current && socketRef.current.connected == true) {
// Remove callback from the subscribed callbacks map // Remove callback from the subscribed callbacks map
if (subscribedCallbacksRef.current.has(id)) { if (subscribedCallbacksRef.current.has(id)) {
@ -240,7 +250,7 @@ const ApiServerProvider = ({ children }) => {
.filter((cb) => cb !== callback) .filter((cb) => cb !== callback)
if (callbacks.length === 0) { if (callbacks.length === 0) {
subscribedCallbacksRef.current.delete(id) subscribedCallbacksRef.current.delete(id)
socketRef.current.emit('unsubscribe', { id: id, type: type }) socketRef.current.emit('unsubscribe', { id: id, type: objectType })
} else { } else {
subscribedCallbacksRef.current.set(id, callbacks) subscribedCallbacksRef.current.set(id, callbacks)
} }
@ -248,62 +258,82 @@ const ApiServerProvider = ({ children }) => {
} }
}, []) }, [])
const offTypeEvent = useCallback((type, callback) => { const offObjectTypeUpdatesEvent = useCallback((objectType, callback) => {
if (socketRef.current && socketRef.current.connected == true) { if (socketRef.current && socketRef.current.connected == true) {
// Remove callback from the subscribed callbacks map // Remove callback from the subscribed callbacks map
if (subscribedCallbacksRef.current.has(type)) { if (subscribedCallbacksRef.current.has(objectType)) {
const callbacks = subscribedCallbacksRef.current const callbacks = subscribedCallbacksRef.current
.get(type) .get(objectType)
.filter((cb) => cb !== callback) .filter((cb) => cb !== callback)
if (callbacks.length === 0) { if (callbacks.length === 0) {
subscribedCallbacksRef.current.delete(type) subscribedCallbacksRef.current.delete(objectType)
socketRef.current.emit('unsubscribe', { type: type }) socketRef.current.emit('unsubscribe', { objectType: objectType })
} else { } else {
subscribedCallbacksRef.current.set(type, callbacks) subscribedCallbacksRef.current.set(objectType, callbacks)
} }
} }
} }
}, []) }, [])
const subscribeToObject = useCallback( const subscribeToObjectUpdates = useCallback(
(id, type, callback) => { (id, objectType, callback) => {
if (socketRef.current && socketRef.current.connected == true) { if (socketRef.current && socketRef.current.connected == true) {
const callbacksRefKey = `${objectType}:${id}`
// Add callback to the subscribed callbacks map immediately // Add callback to the subscribed callbacks map immediately
if (!subscribedCallbacksRef.current.has(id)) { if (!subscribedCallbacksRef.current.has(callbacksRefKey)) {
subscribedCallbacksRef.current.set(id, []) subscribedCallbacksRef.current.set(callbacksRefKey, [])
} }
subscribedCallbacksRef.current.get(id).push(callback) subscribedCallbacksRef.current.get(callbacksRefKey).push(callback)
socketRef.current.emit('subscribe', { id: id, type: type }) socketRef.current.emit(
'subscribeToObjectUpdate',
// Return cleanup function {
return () => offUpdateEvent(id, type, callback) _id: id,
} objectType: objectType
}, },
[offUpdateEvent] (result) => {
) if (result.success) {
logger.info('Subscribed to id:', id, 'objectType:', objectType)
const subscribeToType = useCallback( }
(type, callback) => { }
logger.debug('Subscribing to type:', type)
if (socketRef.current && socketRef.current.connected == true) {
// Add callback to the subscribed callbacks map immediately
if (!subscribedCallbacksRef.current.has(type)) {
subscribedCallbacksRef.current.set(type, [])
}
subscribedCallbacksRef.current.get(type).push(callback)
logger.debug(
`Added callback for type ${type}, total callbacks: ${subscribedCallbacksRef.current.get(type).length}`
) )
socketRef.current.emit('subscribe', { type: type })
logger.debug('Registered update event listener for object:', type)
// Return cleanup function // Return cleanup function
return () => offTypeEvent(type, callback) return () => offObjectUpdatesEvent(id, objectType, callback)
} }
}, },
[offTypeEvent] [offObjectUpdatesEvent]
)
const subscribeToObjectTypeUpdates = useCallback(
(objectType, callback) => {
logger.debug('Subscribing to type updates:', objectType)
if (socketRef.current && socketRef.current.connected == true) {
// Add callback to the subscribed callbacks map immediately
if (!subscribedCallbacksRef.current.has(objectType)) {
subscribedCallbacksRef.current.set(objectType, [])
}
subscribedCallbacksRef.current.get(objectType).push(callback)
logger.debug(
`Added callback for type ${objectType}, total callbacks: ${subscribedCallbacksRef.current.get(objectType).length}`
)
socketRef.current.emit(
'subscribeToObjectTypeUpdate',
{ objectType: objectType },
(result) => {
if (result.success) {
logger.info('Subscribed to objectType:', objectType)
}
}
)
logger.debug('Registered update event listener for object:', objectType)
// Return cleanup function
return () => offObjectTypeUpdatesEvent(objectType, callback)
}
},
[offObjectTypeUpdatesEvent]
) )
const offLockEvent = useCallback((id, callback) => { const offLockEvent = useCallback((id, callback) => {
@ -324,7 +354,7 @@ const ApiServerProvider = ({ children }) => {
} }
}, []) }, [])
const subscribeToLock = useCallback( const subscribeToObjectLock = useCallback(
(id, type, callback) => { (id, type, callback) => {
logger.debug('Subscribing to lock for object:', id, 'type:', type) logger.debug('Subscribing to lock for object:', id, 'type:', type)
if (socketRef.current && socketRef.current.connected == true) { if (socketRef.current && socketRef.current.connected == true) {
@ -453,7 +483,7 @@ const ApiServerProvider = ({ children }) => {
// Fetch table data with pagination, filtering, and sorting // Fetch table data with pagination, filtering, and sorting
const fetchObjectsByProperty = async (type, params = {}) => { const fetchObjectsByProperty = async (type, params = {}) => {
const { filter = {}, properties = [] } = params const { filter = {}, properties = [], masterFilter = {} } = params
logger.debug('Fetching property object data from:', type, { logger.debug('Fetching property object data from:', type, {
properties, properties,
@ -466,7 +496,8 @@ const ApiServerProvider = ({ children }) => {
{ {
params: { params: {
...filter, ...filter,
properties: properties.join(',') // Convert array to comma-separated string properties: properties.join(','), // Convert array to comma-separated string
masterFilter: JSON.stringify(masterFilter)
}, },
headers: { headers: {
Accept: 'application/json', Accept: 'application/json',
@ -636,6 +667,56 @@ const ApiServerProvider = ({ children }) => {
} }
} }
const fetchTemplatePreview = async (
id,
content,
testObject,
scale,
callback
) => {
logger.debug('Fetching preview...')
if (socketRef.current && socketRef.current.connected) {
return socketRef.current.emit(
'previewTemplate',
{
_id: id,
content: content,
testObject: testObject,
scale: scale
},
callback
)
}
}
const fetchHostOTP = async (id, callback) => {
logger.debug('Fetching host OTP...')
if (socketRef.current && socketRef.current.connected) {
return socketRef.current.emit(
'generateHostOtp',
{
_id: id
},
callback
)
}
}
const sendObjectAction = async (id, objectType, action, callback) => {
logger.debug('Sending object action...')
if (socketRef.current && socketRef.current.connected) {
return socketRef.current.emit(
'objectAction',
{
_id: id,
objectType: objectType,
action: action
},
callback
)
}
}
return ( return (
<ApiServerContext.Provider <ApiServerContext.Provider
value={{ value={{
@ -649,10 +730,9 @@ const ApiServerProvider = ({ children }) => {
updateObject, updateObject,
createObject, createObject,
deleteObject, deleteObject,
subscribeToObject, subscribeToObjectUpdates,
subscribeToType, subscribeToObjectTypeUpdates,
subscribeToLock, subscribeToObjectLock,
offUpdateEvent,
fetchObject, fetchObject,
fetchObjects, fetchObjects,
fetchObjectsByProperty, fetchObjectsByProperty,
@ -660,7 +740,10 @@ const ApiServerProvider = ({ children }) => {
fetchLoading, fetchLoading,
showError, showError,
fetchObjectContent, fetchObjectContent,
fetchNotes fetchTemplatePreview,
fetchNotes,
fetchHostOTP,
sendObjectAction
}} }}
> >
{contextHolder} {contextHolder}