@nomyx/gun-sync
Version:
A lightweight, powerful library for synchronizing application state in real-time using Gun.js.
52 lines (51 loc) • 2.19 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.useGunPresence = useGunPresence;
const react_1 = require("react");
const context_1 = require("./context");
// Simple unique ID for the session
const sessionId = Math.random().toString(36).substring(2);
/**
* A React hook to track user presence within a specific scope.
*
* @param scope - A string to namespace the presence data.
* @param gunInstance - Optional Gun instance. If not provided, uses context.
* @returns An array of `PresenceInfo` objects for all active users.
*/
function useGunPresence(scope, gunInstance) {
const gun = gunInstance || (0, context_1.useGun)();
const [presentUsers, setPresentUsers] = (0, react_1.useState)([]);
// Memoize the reference to the presence set in Gun
const presenceSet = (0, react_1.useMemo)(() => gun.get(scope).get('presence'), [gun, scope]);
(0, react_1.useEffect)(() => {
// Heartbeat function to keep our session alive
const heartbeat = () => {
presenceSet.get(sessionId).put({ lastSeen: Date.now() });
};
// Set an interval to send a heartbeat every 10 seconds
const heartbeatInterval = setInterval(heartbeat, 10000);
heartbeat(); // Initial heartbeat
// Subscribe to the presence set
const subscription = presenceSet.map().on((data, id) => {
setPresentUsers(users => {
const now = Date.now();
// Filter out users who haven't been seen in 30 seconds
const updatedUsers = users.filter(u => u.id !== id && (now - u.lastSeen < 30000));
// Add or update the current user
if (data) {
updatedUsers.push({ id, lastSeen: data.lastSeen });
}
return updatedUsers;
});
});
// Cleanup on unmount
return () => {
clearInterval(heartbeatInterval);
// Remove our presence from the set
presenceSet.get(sessionId).put(null);
if (subscription)
subscription.off();
};
}, [presenceSet]);
return presentUsers;
}