UNPKG

@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
"use strict"; 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; }