{"_id":"@digilabscz/sync-hub-js","_rev":"9-cbabcead7adc45e5481b4eae25c3499e","name":"@digilabscz/sync-hub-js","dist-tags":{"latest":"1.0.8"},"versions":{"1.0.0":{"name":"@digilabscz/sync-hub-js","version":"1.0.0","keywords":["sync","browser","tab communication","broadcastchannel"],"author":{"name":"Petr Hladík"},"license":"MIT","_id":"@digilabscz/sync-hub-js@1.0.0","maintainers":[{"name":"hladpe","email":"hladpe@gmail.com"},{"name":"cerv0077","email":"cervenkaondra@gmail.com"}],"dist":{"shasum":"fad4af30332c8573903a317ba3e0a53b97603da6","tarball":"https://registry.npmjs.org/@digilabscz/sync-hub-js/-/sync-hub-js-1.0.0.tgz","fileCount":5,"integrity":"sha512-nruxXrf4ph02VPF3pgvM3QPsK3wkKBMIhsEVWxI3bG1bms1fYJILvBxlOo4rIhE8+o0QQf8a4j9yRwpzeyRVgg==","signatures":[{"sig":"MEUCIQCAEqkDRFe9glRxvI7bUtmu27hjlPM+8idvSIQJaWT5mAIgH2GjR6PXZE2rIBr7Z0sS2MdDU3oWTABTAarz7Lpe0eA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":17109},"main":"dist/sync-hub.min.js","type":"module","module":"dist/sync-hub.min.js","gitHead":"788281c24d2d3ae757c44ba65ee33ef01cce99c7","scripts":{"build":"rollup -c"},"_npmUser":{"name":"hladpe","email":"hladpe@gmail.com"},"_npmVersion":"10.9.2","description":"Lightweight master-slave tab synchronization hub for browsers","directories":{},"_nodeVersion":"22.14.0","_hasShrinkwrap":false,"devDependencies":{"rollup":"^4.37.0"},"_npmOperationalInternal":{"tmp":"tmp/sync-hub-js_1.0.0_1742908962078_0.5896348726823364","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@digilabscz/sync-hub-js","version":"1.0.1","keywords":["sync","browser","tab communication","broadcastchannel"],"author":{"name":"Petr Hladík"},"license":"MIT","_id":"@digilabscz/sync-hub-js@1.0.1","maintainers":[{"name":"hladpe","email":"hladpe@gmail.com"},{"name":"cerv0077","email":"cervenkaondra@gmail.com"}],"dist":{"shasum":"3f2fa033915eb4c8a7b825b4d9d14ea9b59e174b","tarball":"https://registry.npmjs.org/@digilabscz/sync-hub-js/-/sync-hub-js-1.0.1.tgz","fileCount":5,"integrity":"sha512-8WZf7n9WV5V5mlwo6rDruMP8waI1b5xtNZmgj7t1FYbJYMMnaq0YNGetTZCKS93uQWaHmHu7p1+M7QcwV/WU2Q==","signatures":[{"sig":"MEUCIQCjVmHSaGg6AlR0IYCDgIJZFZWxhqbWDoQUjNh7NA4idAIgcpQcglXVr0BrZY0CmPDoQ6L6XBeQEq8g2a6TlCpa4ps=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":17388},"main":"dist/sync-hub.min.js","type":"module","module":"dist/sync-hub.min.js","gitHead":"4fedc48096b0e4c14919a24b36b9198487786f9b","scripts":{"build":"rollup -c"},"_npmUser":{"name":"hladpe","email":"hladpe@gmail.com"},"_npmVersion":"10.9.2","description":"Lightweight master-slave tab synchronization hub for browsers","directories":{},"_nodeVersion":"22.14.0","_hasShrinkwrap":false,"devDependencies":{"rollup":"^4.37.0"},"_npmOperationalInternal":{"tmp":"tmp/sync-hub-js_1.0.1_1742909300465_0.5528237170146884","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"@digilabscz/sync-hub-js","version":"1.0.2","keywords":["sync","browser","tab communication","broadcastchannel"],"author":{"name":"Petr Hladík"},"license":"MIT","_id":"@digilabscz/sync-hub-js@1.0.2","maintainers":[{"name":"hladpe","email":"hladpe@gmail.com"},{"name":"cerv0077","email":"cervenkaondra@gmail.com"}],"dist":{"shasum":"756b7ed8c4be54427450c81172b4feded6dc1870","tarball":"https://registry.npmjs.org/@digilabscz/sync-hub-js/-/sync-hub-js-1.0.2.tgz","fileCount":5,"integrity":"sha512-Udu06fFFreM6n0vEVtG+dIOoXcDOjvLaLRtE82GVqUWvEjjLHmFT0eI4qqDTBdzbuK8No4y7R3qz7xcRbbY8/A==","signatures":[{"sig":"MEQCIDCfiJo79MhtRw9FKcewOjhxoIXS/oKwTsVFLXMHZMVOAiAF2D429/zcaIGjF3shm5tPeSHq/sx7y0yvZYIih1z4JA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":17515},"main":"dist/sync-hub.min.js","type":"module","module":"dist/sync-hub.min.js","gitHead":"816d235824435d20604ca115e8ed12c8ff7ea605","scripts":{"build":"rollup -c"},"_npmUser":{"name":"hladpe","email":"hladpe@gmail.com"},"_npmVersion":"10.9.2","description":"Lightweight master-slave tab synchronization hub for browsers","directories":{},"_nodeVersion":"22.14.0","_hasShrinkwrap":false,"devDependencies":{"rollup":"^4.37.0"},"_npmOperationalInternal":{"tmp":"tmp/sync-hub-js_1.0.2_1743149850444_0.5748495324062446","host":"s3://npm-registry-packages-npm-production"}},"1.0.3":{"name":"@digilabscz/sync-hub-js","version":"1.0.3","keywords":["sync","browser","tab communication","broadcastchannel"],"author":{"name":"Petr Hladík"},"license":"MIT","_id":"@digilabscz/sync-hub-js@1.0.3","maintainers":[{"name":"hladpe","email":"hladpe@gmail.com"},{"name":"cerv0077","email":"cervenkaondra@gmail.com"}],"dist":{"shasum":"9d227b0a8779fd670817c09d1e665a2e6b7a5a11","tarball":"https://registry.npmjs.org/@digilabscz/sync-hub-js/-/sync-hub-js-1.0.3.tgz","fileCount":5,"integrity":"sha512-uXUDRd2Wvg3r2bWAaZknQwA3+SSROBT+xC+JX89eZemdGJPS5n67kKpSeUmtoinzMVlnsbtNtQWfwOVJIBlBmg==","signatures":[{"sig":"MEQCIA1O/K/N2RgrovMxP2RoSFY+jaEvTDAzQrOKD29Bc2cQAiBuoblIVGHj4lsiNArGe9XkZ2w94AIw0biN1ybOKo7p1w==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":17547},"main":"dist/sync-hub.min.js","type":"module","module":"dist/sync-hub.min.js","gitHead":"d2bf2bded9d05fd56d4ddf8805cea8e37f330b71","scripts":{"build":"rollup -c"},"_npmUser":{"name":"hladpe","email":"hladpe@gmail.com"},"_npmVersion":"10.9.2","description":"Lightweight master-slave tab synchronization hub for browsers","directories":{},"_nodeVersion":"22.14.0","_hasShrinkwrap":false,"devDependencies":{"rollup":"^4.37.0"},"_npmOperationalInternal":{"tmp":"tmp/sync-hub-js_1.0.3_1743150031158_0.9451795586277809","host":"s3://npm-registry-packages-npm-production"}},"1.0.4":{"name":"@digilabscz/sync-hub-js","version":"1.0.4","keywords":["sync","browser","tab communication","broadcastchannel"],"author":{"name":"Petr Hladík"},"license":"MIT","_id":"@digilabscz/sync-hub-js@1.0.4","maintainers":[{"name":"hladpe","email":"hladpe@gmail.com"},{"name":"cerv0077","email":"cervenkaondra@gmail.com"}],"dist":{"shasum":"6385b150da25081840b623d24bc41615b29e3854","tarball":"https://registry.npmjs.org/@digilabscz/sync-hub-js/-/sync-hub-js-1.0.4.tgz","fileCount":5,"integrity":"sha512-AawcdxVmDff6e/qe6ttwo67Qj5/Th4oDMVZrqzxj1YoURf1z4kBJI12TmLRjT8TtFdvGJ2pM+lagCBf6S7nA/A==","signatures":[{"sig":"MEUCIQCzWRlwVG8Xw4yIBoyi96K2eB7BTNHJcM5WfblOSJzQ1gIgb26F5o58UlJiM8RGhL7CWyKEBR7ZYVuxCbqWFWmwR4k=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":17636},"main":"dist/sync-hub.min.js","type":"module","module":"dist/sync-hub.min.js","gitHead":"e09ec725f4336e79980049d0d085935cb4043c17","scripts":{"build":"rollup -c"},"_npmUser":{"name":"hladpe","email":"hladpe@gmail.com"},"_npmVersion":"10.9.2","description":"Lightweight master-slave tab synchronization hub for browsers","directories":{},"_nodeVersion":"22.14.0","_hasShrinkwrap":false,"devDependencies":{"rollup":"^4.37.0"},"_npmOperationalInternal":{"tmp":"tmp/sync-hub-js_1.0.4_1743150339561_0.228302668065268","host":"s3://npm-registry-packages-npm-production"}},"1.0.5":{"name":"@digilabscz/sync-hub-js","version":"1.0.5","keywords":["sync","browser","tab communication","broadcastchannel"],"author":{"name":"Petr Hladík"},"license":"MIT","_id":"@digilabscz/sync-hub-js@1.0.5","maintainers":[{"name":"hladpe","email":"hladpe@gmail.com"},{"name":"cerv0077","email":"cervenkaondra@gmail.com"}],"dist":{"shasum":"7be8255ed263bbcc62a4fa5ce7cca84f6ff45ce6","tarball":"https://registry.npmjs.org/@digilabscz/sync-hub-js/-/sync-hub-js-1.0.5.tgz","fileCount":5,"integrity":"sha512-7/iW7zHPFxGzWmj4Pvgdyj2Zpd5di1eFydU4nYw8oQPlwj9wXrE2T0u+jESYLs4D9IrnYa5uz6BlfynIY+Ephg==","signatures":[{"sig":"MEUCIDdBi1KMfexHM8Yf72xCFfGBVbjKgz8sCAm1QeJ+j8rwAiEAixqNNrnEuPNkmhiKd8drQt57JNvWCiTK6P88VAHr1Cc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":17660},"main":"dist/sync-hub.min.js","type":"module","module":"dist/sync-hub.min.js","gitHead":"fc9032335827cefcd3404b5888814f8c20327bf4","scripts":{"build":"rollup -c"},"_npmUser":{"name":"hladpe","email":"hladpe@gmail.com"},"_npmVersion":"10.9.2","description":"Lightweight master-slave tab synchronization hub for browsers","directories":{},"_nodeVersion":"22.14.0","_hasShrinkwrap":false,"devDependencies":{"rollup":"^4.37.0"},"_npmOperationalInternal":{"tmp":"tmp/sync-hub-js_1.0.5_1743157655809_0.7394692033739494","host":"s3://npm-registry-packages-npm-production"}},"1.0.6":{"name":"@digilabscz/sync-hub-js","version":"1.0.6","keywords":["sync","browser","tab communication","broadcastchannel"],"author":{"name":"Petr Hladík"},"license":"MIT","_id":"@digilabscz/sync-hub-js@1.0.6","maintainers":[{"name":"hladpe","email":"hladpe@gmail.com"},{"name":"cerv0077","email":"cervenkaondra@gmail.com"}],"dist":{"shasum":"3025a5da905d86e5460aef0490b44edbeaab5dbf","tarball":"https://registry.npmjs.org/@digilabscz/sync-hub-js/-/sync-hub-js-1.0.6.tgz","fileCount":5,"integrity":"sha512-PmRwzy6/jFoVox9Q0hpKM6wKNGKJjVdsuNOBu/5En1aCKPmr8d38tPV41mykuX6WIKXec0JhTSZ6mH4VRhanZA==","signatures":[{"sig":"MEYCIQDTS73KL9d8IrSrPs7szeR+rsQQKT3d35Euig7Tdj08FgIhAM/5QPuPLXRuHBSBX9ZvEfU1/TxwIkn8AqyDsbFBvsA5","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":17952},"main":"dist/sync-hub.min.js","type":"module","module":"dist/sync-hub.min.js","gitHead":"89107d3dc0f7b9eb9bf96426614483be807341be","scripts":{"build":"rollup -c"},"_npmUser":{"name":"hladpe","email":"hladpe@gmail.com"},"_npmVersion":"10.9.2","description":"Lightweight master-slave tab synchronization hub for browsers","directories":{},"_nodeVersion":"22.14.0","_hasShrinkwrap":false,"devDependencies":{"rollup":"^4.37.0"},"_npmOperationalInternal":{"tmp":"tmp/sync-hub-js_1.0.6_1743159455233_0.8699170967729839","host":"s3://npm-registry-packages-npm-production"}},"1.0.8":{"name":"@digilabscz/sync-hub-js","version":"1.0.8","keywords":["sync","browser","tab communication","broadcastchannel"],"author":{"name":"Petr Hladík"},"license":"MIT","_id":"@digilabscz/sync-hub-js@1.0.8","maintainers":[{"name":"hladpe","email":"hladpe@gmail.com"},{"name":"cerv0077","email":"cervenkaondra@gmail.com"}],"dist":{"shasum":"f00d58e62b12c9dbdfe90fe9bfcf4a5b82becc20","tarball":"https://registry.npmjs.org/@digilabscz/sync-hub-js/-/sync-hub-js-1.0.8.tgz","fileCount":5,"integrity":"sha512-5uWJSKwqqMo17oj1Q6SxhTM1EGFwHLzQnmy6l9uYCmsdsV/dUcTQXI7XlG7J2zxcwwjTtaSgtmuRadHkf3OstA==","signatures":[{"sig":"MEUCIQCwUgK6JBrjZwXAetUKNkro9A2K2da8qIsz+hgIgTNttwIgHukGzr0cQzxMvY7OScAMQ6GkG/mB7sxTd43aH2i0v1s=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":17736},"main":"dist/sync-hub.min.js","type":"module","module":"dist/sync-hub.min.js","gitHead":"50504614273a6f0110094ba9814da780378b6f49","scripts":{"build":"rollup -c"},"_npmUser":{"name":"hladpe","email":"hladpe@gmail.com"},"_npmVersion":"10.9.2","description":"Lightweight master-slave tab synchronization hub for browsers","directories":{},"_nodeVersion":"22.14.0","_hasShrinkwrap":false,"devDependencies":{"rollup":"^4.37.0"},"_npmOperationalInternal":{"tmp":"tmp/sync-hub-js_1.0.8_1743189326205_0.8626585523543404","host":"s3://npm-registry-packages-npm-production"}}},"time":{"created":"2025-03-25T13:22:41.995Z","modified":"2025-12-10T08:30:43.164Z","1.0.0":"2025-03-25T13:22:42.275Z","1.0.1":"2025-03-25T13:28:20.685Z","1.0.2":"2025-03-28T08:17:30.671Z","1.0.3":"2025-03-28T08:20:31.324Z","1.0.4":"2025-03-28T08:25:39.720Z","1.0.5":"2025-03-28T10:27:35.980Z","1.0.6":"2025-03-28T10:57:35.419Z","1.0.8":"2025-03-28T19:15:26.493Z"},"author":{"name":"Petr Hladík"},"license":"MIT","keywords":["sync","browser","tab communication","broadcastchannel"],"description":"Lightweight master-slave tab synchronization hub for browsers","maintainers":[{"email":"hladpe@gmail.com","name":"hladpe"},{"email":"cervenkaondra@gmail.com","name":"cerv0077"},{"email":"dominik.smolinsky@icloud.com","name":"smola14"}],"readme":"# 📡 SyncHub - Master/Slave Tab Synchronization for Browsers\n\nSyncHub is a lightweight JavaScript library that enables master-slave synchronization between browser tabs using BroadcastChannel and localStorage. It prevents excessive server requests and ensures data consistency across tabs.\n\n- ✅ Master tab handles data fetching\n- ✅ Slave tabs stay passive and react to updates\n- ✅ Automatic master re-election if the active tab changes\n- ✅ Supports periodic data fetching or manual updates\n- ✅ Designed for e-commerce carts, notifications, and any shared browser state\n\n---\n\n## 🚀 Installation\n\n### NPM\n\n```shell\nnpm i @digilabscz/sync-hub-js\n```\n\nThen:\n\n```js\nimport SyncHub from '@digilabscz/sync-hub-js';\nSyncHub.init();\n```\n\nor (CommonJS)\n\n```js\nconst SyncHub = require('@digilabscz/sync-hub-js');\nSyncHub.init();\n```\n\n### CDN\n\n```html\n<script src=\"https://unpkg.com/@digilabscz/sync-hub-js@latest/dist/sync-hub.min.js\"></script>\n```\nor\n\n```html\n<script src=\"https://cdn.jsdelivr.net/npm/@digilabscz/sync-hub-js@latest/dist/sync-hub.min.js\"></script>\n```\n\nThe library will automatically call `init()` method and register as `window.SyncHub`.\n\n---\n## Examples\n\n### 🔄 Example 1 - Static Data Synchronization\n\n```html\n<div id=\"notifications-badge\" style=\"padding:10px; background:orange;\"></div>\n\n<script>\n    // Initialize task for static data\n    let task = window.SyncHub.registerTask('notifications-badge')\n        .onUpdate((newState, prevState) => {\n            renderNotificationBadge(newState, prevState);\n        });\n\n    // Manually update the task (can be triggered by button or event)\n    task.update(5);\n\n    function renderNotificationBadge(newState, prevState) {\n        const node = document.querySelector('#notifications-badge');\n\n        if (window.SyncHub.isMaster()) {\n            node.classList.add('master');\n        } else {\n            node.classList.remove('master');\n        }\n\n        node.innerHTML = `<strong>${newState}</strong><sup>/${prevState !== undefined ? prevState : 0}</sup>`;\n    }\n\n    // Render initial state (if any)\n    renderNotificationBadge(task.getState());\n</script>\n```\n\n### 🌐 Example 2 - Auto Fetch from API (Notifications Badge)\n\n```html\n<div id=\"notifications-badge\" style=\"padding:10px; background:orange;\"></div>\n\n<script>\n    // Create a task that fetches data every 5 seconds (only master tab runs fetch)\n    let task = window.SyncHub.registerTask('notifications-badge')\n        .onInterval(async (task) => {\n            const response = await fetch('https://api.example.com/notifications-count', { cache: \"no-store\" });\n            const count = await response.text();\n            return parseInt(count);\n        }, 5000, true) // true = run immediately\n        .onUpdate((newState, prevState) => {\n            renderNotificationBadge(newState, prevState);\n        });\n\n    function renderNotificationBadge(newState, prevState) {\n        const node = document.querySelector('#notifications-badge');\n\n        if (window.SyncHub.isMaster()) {\n            node.classList.add('master');\n        } else {\n            node.classList.remove('master');\n        }\n\n        if (newState > 0) {\n            node.classList.add('active');\n        } else {\n            node.classList.remove('active');\n        }\n\n        node.innerHTML = `<strong>${newState}</strong><sup>/${prevState !== undefined ? prevState : 0}</sup>`;\n    }\n\n    // Render initial state (if any)\n    renderNotificationBadge(task.getState());\n</script>\n```\n---\n\n## ⚙️ API Summary\n\n| Method                                                        | Description                                            |\n|---------------------------------------------------------------|--------------------------------------------------------|\n| SyncHub.registerTask(taskName)                                | Register a new named task                              |\n| task.onInterval(callback, intervalMs, runImmediately = false) | Define a periodic action the master tab should execute |\n| task.onUpdate(callback)                                       | React to data updates in all tabs                      |\n| task.update(newData)                                          | Manually trigger a new update                          |\n| task.getState()                                               | Get the last known state of the task                   |\n| SyncHub.isMaster()                                            | Check if the current tab is master                     |\n\n---\n","readmeFilename":"README.md"}