react-broadcast-sync 1.0.0 → 1.1.1

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.
Files changed (46) hide show
  1. package/.eslintignore +5 -0
  2. package/.github/workflows/ci.yml +3 -3
  3. package/.github/workflows/release.yml +39 -0
  4. package/.husky/pre-commit +0 -1
  5. package/.nvmrc +1 -0
  6. package/.prettierignore +1 -0
  7. package/.prettierrc +5 -1
  8. package/CHANGELOG.md +27 -0
  9. package/README.md +118 -47
  10. package/demo/react-broadcast-sync-demo/README.md +130 -0
  11. package/demo/react-broadcast-sync-demo/index.html +14 -0
  12. package/demo/react-broadcast-sync-demo/package-lock.json +6379 -0
  13. package/demo/react-broadcast-sync-demo/package.json +42 -0
  14. package/demo/react-broadcast-sync-demo/public/assets/react-broadcast-sync-logo.png +0 -0
  15. package/demo/react-broadcast-sync-demo/src/App.tsx +277 -0
  16. package/demo/react-broadcast-sync-demo/src/components/Counter.tsx +63 -0
  17. package/demo/react-broadcast-sync-demo/src/components/TextSync.tsx +61 -0
  18. package/demo/react-broadcast-sync-demo/src/components/TodoList.tsx +186 -0
  19. package/demo/react-broadcast-sync-demo/src/hooks/useCounterBroadcast.ts +96 -0
  20. package/demo/react-broadcast-sync-demo/src/hooks/useTextBroadcast.ts +37 -0
  21. package/demo/react-broadcast-sync-demo/src/hooks/useTodoBroadcast.ts +249 -0
  22. package/demo/react-broadcast-sync-demo/src/main.tsx +11 -0
  23. package/demo/react-broadcast-sync-demo/src/theme.ts +62 -0
  24. package/demo/react-broadcast-sync-demo/tsconfig.json +26 -0
  25. package/demo/react-broadcast-sync-demo/tsconfig.node.json +10 -0
  26. package/demo/react-broadcast-sync-demo/vite.config.ts +12 -0
  27. package/dist/index.cjs.js +1 -1
  28. package/dist/index.cjs.js.map +1 -1
  29. package/dist/index.d.ts +1 -1
  30. package/dist/index.esm.js +1 -1
  31. package/dist/index.esm.js.map +1 -1
  32. package/eslint.config.js +14 -5
  33. package/jest.config.cjs +8 -9
  34. package/package.json +63 -33
  35. package/rollup.config.mjs +27 -21
  36. package/src/BroadcastProvider.tsx +6 -6
  37. package/src/hooks/useBroadcastChannel.ts +122 -95
  38. package/src/index.ts +1 -1
  39. package/src/tests/BroadcastProvider.test.tsx +7 -7
  40. package/src/tests/debug.test.ts +65 -25
  41. package/src/tests/messageUtils.test.ts +20 -15
  42. package/src/tests/useBroadcastChannel.test.tsx +48 -33
  43. package/src/types/types.ts +19 -23
  44. package/src/utils/debug.ts +1 -1
  45. package/src/utils/messageUtils.ts +19 -24
  46. package/dist/useBroadcastChannel.d.ts +0 -3
package/.eslintignore ADDED
@@ -0,0 +1,5 @@
1
+ node_modules/
2
+ dist/
3
+ coverage/
4
+ demo/react-broadcast-sync/node_modules
5
+ demo/react-broadcast-sync/dist
@@ -7,7 +7,7 @@ on:
7
7
  branches: [main]
8
8
 
9
9
  jobs:
10
- llint-and-typecheck:
10
+ lint-and-typecheck:
11
11
  runs-on: ubuntu-latest
12
12
  steps:
13
13
  - uses: actions/checkout@v3
@@ -15,7 +15,7 @@ jobs:
15
15
  - name: Setup Node.js
16
16
  uses: actions/setup-node@v4
17
17
  with:
18
- node-version: 18
18
+ node-version: 20.11.1
19
19
 
20
20
  - name: Install dependencies
21
21
  run: npm ci
@@ -34,7 +34,7 @@ jobs:
34
34
 
35
35
  strategy:
36
36
  matrix:
37
- node-version: [18, 20]
37
+ node-version: [20.11.1]
38
38
 
39
39
  steps:
40
40
  - uses: actions/checkout@v3
@@ -0,0 +1,39 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+
8
+ permissions:
9
+ contents: write
10
+ issues: write
11
+ pull-requests: write
12
+
13
+ jobs:
14
+ release:
15
+ name: Release
16
+ runs-on: ubuntu-latest
17
+ steps:
18
+ - name: Checkout
19
+ uses: actions/checkout@v4
20
+ with:
21
+ fetch-depth: 0
22
+
23
+ - name: Setup Node.js
24
+ uses: actions/setup-node@v4
25
+ with:
26
+ node-version: 20.11.1
27
+ cache: 'npm'
28
+
29
+ - name: Install dependencies
30
+ run: npm ci
31
+
32
+ - name: Build
33
+ run: npm run build
34
+
35
+ - name: Release
36
+ env:
37
+ GH_TOKEN: ${{ secrets.GH_PAT }}
38
+ NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
39
+ run: npx semantic-release
package/.husky/pre-commit CHANGED
@@ -3,4 +3,3 @@
3
3
 
4
4
  npx lint-staged
5
5
  npm run typecheck
6
- npm run lint-staged
package/.nvmrc ADDED
@@ -0,0 +1 @@
1
+ 20.11.1
package/.prettierignore CHANGED
@@ -1,3 +1,4 @@
1
1
  node_modules
2
2
  dist
3
3
  coverage
4
+ CHANGELOG.md
package/.prettierrc CHANGED
@@ -1,5 +1,9 @@
1
1
  {
2
2
  "semi": true,
3
+ "tabWidth": 2,
4
+ "printWidth": 100,
3
5
  "singleQuote": true,
4
- "trailingComma": "es5"
6
+ "trailingComma": "es5",
7
+ "bracketSpacing": true,
8
+ "arrowParens": "avoid"
5
9
  }
package/CHANGELOG.md ADDED
@@ -0,0 +1,27 @@
1
+ ## [1.1.1](https://github.com/IdanShalem/react-broadcast-sync/compare/v1.1.0...v1.1.1) (2025-06-03)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * fixed sync problem in counter demo app ([481bda7](https://github.com/IdanShalem/react-broadcast-sync/commit/481bda79f55b3b902861877d4446bc4adaa76941))
7
+
8
+ # [1.1.0](https://github.com/IdanShalem/react-broadcast-sync/compare/v1.0.0...v1.1.0) (2025-06-03)
9
+
10
+
11
+ ### Features
12
+
13
+ * added demo app deployment ([755bee2](https://github.com/IdanShalem/react-broadcast-sync/commit/755bee2c11bafcaa0653917bae8e288500f6dec6))
14
+
15
+ # 1.0.0 (2025-05-30)
16
+
17
+
18
+ ### Bug Fixes
19
+
20
+ * update favicon path and remove duplicate link ([c6bb7d8](https://github.com/IdanShalem/react-broadcast-sync/commit/c6bb7d85f09e36eb2e3c5da71485c247bd29ba37))
21
+ * updated readme and fixed ci ([56d76d0](https://github.com/IdanShalem/react-broadcast-sync/commit/56d76d0ee342cce9e29968e9fb8b0fe9ee8b89fd))
22
+
23
+
24
+ ### Features
25
+
26
+ * demo app ([0717637](https://github.com/IdanShalem/react-broadcast-sync/commit/07176372544f2c29ad184d8107fc176881397e5b))
27
+ * fix ci flow ([3dfd575](https://github.com/IdanShalem/react-broadcast-sync/commit/3dfd575db288b2f1923859ccc2acc3d52de4c70c))
package/README.md CHANGED
@@ -2,17 +2,57 @@
2
2
  <img src="./assets/react-broadcast-sync-logo.png" alt="react-broadcast-sync logo" width="300" />
3
3
  </p>
4
4
 
5
+ <p align="center">
6
+
5
7
  # react-broadcast-sync
6
8
 
7
- ![CI](https://github.com/IdanShalem/react-broadcast-sync/actions/workflows/ci.yml/badge.svg)
8
- [![codecov](https://codecov.io/gh/IdanShalem/react-broadcast-sync/branch/main/graph/badge.svg)](https://codecov.io/gh/IdanShalem/react-broadcast-sync)
9
- [![npm version](https://img.shields.io/npm/v/react-broadcast-sync.svg)](https://www.npmjs.com/package/react-broadcast-sync)
10
- [![npm downloads](https://img.shields.io/npm/dm/react-broadcast-sync.svg)](https://www.npmjs.com/package/react-broadcast-sync)
11
- [![bundlephobia](https://badgen.net/bundlephobia/minzip/react-broadcast-sync)](https://bundlephobia.com/result?p=react-broadcast-sync)
12
- [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
13
- [![Issues](https://img.shields.io/github/issues/IdanShalem/react-broadcast-sync)](https://github.com/IdanShalem/react-broadcast-sync/issues)
9
+ </p>
10
+
11
+ <p align="center">
12
+ <a href="https://github.com/IdanShalem/react-broadcast-sync/actions/workflows/ci.yml">
13
+ <img alt="CI" src="https://github.com/IdanShalem/react-broadcast-sync/actions/workflows/ci.yml/badge.svg" />
14
+ </a>
15
+ <a href="https://codecov.io/gh/IdanShalem/react-broadcast-sync">
16
+ <img alt="Coverage" src="https://codecov.io/gh/IdanShalem/react-broadcast-sync/branch/main/graph/badge.svg" />
17
+ </a>
18
+ <a href="https://www.npmjs.com/package/react-broadcast-sync">
19
+ <img alt="NPM Version" src="https://img.shields.io/npm/v/react-broadcast-sync.svg" />
20
+ </a>
21
+ <a href="https://www.npmjs.com/package/react-broadcast-sync">
22
+ <img alt="NPM Downloads" src="https://img.shields.io/npm/dm/react-broadcast-sync.svg" />
23
+ </a>
24
+ <a href="https://bundlephobia.com/result?p=react-broadcast-sync">
25
+ <img alt="Bundlephobia" src="https://badgen.net/bundlephobia/minzip/react-broadcast-sync" />
26
+ </a>
27
+ <a href="https://opensource.org/licenses/MIT">
28
+ <img alt="License: MIT" src="https://img.shields.io/badge/License-MIT-blue.svg" />
29
+ </a>
30
+ <a href="https://github.com/IdanShalem/react-broadcast-sync/issues">
31
+ <img alt="GitHub issues" src="https://img.shields.io/github/issues/IdanShalem/react-broadcast-sync" />
32
+ </a>
33
+ </p>
14
34
 
15
- A lightweight React hook for syncing state and communication across browser tabs using the BroadcastChannel API. This package provides a clean and type-safe abstraction over the native API, enabling efficient, scoped, and reliable cross-tab messaging.
35
+ Easily sync UI state or user events across browser tabs in React apps — notifications, presence, forms, and more. This package provides a clean and type-safe abstraction over the native API, enabling efficient, scoped, and reliable cross-tab messaging.
36
+
37
+ ## 📚 Table of Contents
38
+
39
+ - [Features](#-features)
40
+ - [Demo App](#-demo-app)
41
+ - [Installation](#-installation)
42
+ - [Quick Start](#-quick-start)
43
+ - [Advanced Usage](#️-advanced-usage)
44
+ - [BroadcastProvider](#-using-broadcastprovider)
45
+ - [API Reference](#-api-reference)
46
+ - [Best Practices](#-best-practices)
47
+ - [Common Use Cases](#-common-use-cases)
48
+ - [Performance Considerations](#-performance-considerations)
49
+ - [Troubleshooting](#-troubleshooting)
50
+ - [Testing](#-testing)
51
+ - [Browser Support](#-browser-support)
52
+ - [Coming Soon](#-coming-soon)
53
+ - [📦 Versioning & Releases](#-versioning--releases)
54
+ - [Contributing](#-contributing)
55
+ - [License](#-license)
16
56
 
17
57
  ## ✨ Features
18
58
 
@@ -27,6 +67,31 @@ A lightweight React hook for syncing state and communication across browser tabs
27
67
  - ✅ Only accept allowed message types (optional)
28
68
  - 🧠 `BroadcastProvider` for context-based usage
29
69
 
70
+ ## 🎮 Demo App
71
+
72
+ Check out our [live demo](https://react-broadcast-sync-3w3m.vercel.app/) to see the library in action! The demo showcases three main features:
73
+
74
+ 1. **Counter Synchronization**
75
+
76
+ - Real-time counter updates across tabs
77
+ - Visual feedback for sync status
78
+ - Smooth animations
79
+
80
+ 2. **Text Synchronization**
81
+
82
+ - Real-time text input sync
83
+ - Multi-line support
84
+ - Instant updates
85
+
86
+ 3. **Todo List**
87
+ - Synchronized todo items
88
+ - Real-time hover effects
89
+ - Scroll position sync
90
+ - Completion status sync
91
+ - Delete functionality
92
+
93
+ The demo is built with React 19, TypeScript, Material-UI, and Framer Motion. You can find the source code in the [demo directory](./demo/react-broadcast-sync-demo).
94
+
30
95
  ---
31
96
 
32
97
  ## 📦 Installation
@@ -49,8 +114,7 @@ pnpm add react-broadcast-sync
49
114
  import { useBroadcastChannel } from 'react-broadcast-sync';
50
115
 
51
116
  function MyComponent() {
52
- const { messages, postMessage, clearMessage } =
53
- useBroadcastChannel('my-channel');
117
+ const { messages, postMessage, clearMessage } = useBroadcastChannel('my-channel');
54
118
 
55
119
  const handleSend = () => {
56
120
  postMessage('greeting', { text: 'Hello from another tab!' });
@@ -59,7 +123,7 @@ function MyComponent() {
59
123
  return (
60
124
  <>
61
125
  <button onClick={handleSend}>Send</button>
62
- {messages.map((msg) => (
126
+ {messages.map(msg => (
63
127
  <div key={msg.id}>
64
128
  {msg.message.text}
65
129
  <button onClick={() => clearMessage(msg.id)}>Clear</button>
@@ -98,11 +162,7 @@ const {
98
162
  #### 💬 Sending a message with expiration:
99
163
 
100
164
  ```tsx
101
- postMessage(
102
- 'notification',
103
- { text: 'This disappears in 5s' },
104
- { expirationDuration: 5000 }
105
- );
165
+ postMessage('notification', { text: 'This disappears in 5s' }, { expirationDuration: 5000 });
106
166
  ```
107
167
 
108
168
  ---
@@ -127,7 +187,7 @@ function NotificationBar() {
127
187
 
128
188
  return (
129
189
  <div>
130
- {messages.map((msg) => (
190
+ {messages.map(msg => (
131
191
  <p key={msg.id}>{msg.message.text}</p>
132
192
  ))}
133
193
  </div>
@@ -187,11 +247,7 @@ interface BroadcastActions {
187
247
  channelName: string; // The resolved channel name (includes namespace)
188
248
  messages: BroadcastMessage[]; // Received messages
189
249
  sentMessages: BroadcastMessage[]; // Messages sent by this instance
190
- postMessage: (
191
- type: string,
192
- content: any,
193
- options?: SendMessageOptions
194
- ) => void;
250
+ postMessage: (type: string, content: any, options?: SendMessageOptions) => void;
195
251
  clearMessage: (id: string) => void;
196
252
  clearAllMessages: () => void;
197
253
  clearSentMessage: (id: string) => void;
@@ -261,7 +317,7 @@ function NotificationSystem() {
261
317
 
262
318
  return (
263
319
  <div>
264
- {messages.map((msg) => (
320
+ {messages.map(msg => (
265
321
  <Notification key={msg.id} type={msg.type} content={msg.message} />
266
322
  ))}
267
323
  </div>
@@ -279,11 +335,7 @@ function FormSync() {
279
335
  });
280
336
 
281
337
  const handleChange = (field: string, value: string) => {
282
- postMessage(
283
- 'field-update',
284
- { field, value },
285
- { expirationDuration: 300000 }
286
- ); // 5 minutes
338
+ postMessage('field-update', { field, value }, { expirationDuration: 300000 }); // 5 minutes
287
339
  };
288
340
 
289
341
  return <Form onChange={handleChange} />;
@@ -310,6 +362,24 @@ function TabStatus() {
310
362
 
311
363
  ## 🔧 Performance Considerations
312
364
 
365
+ ### Message Size
366
+
367
+ - Keep messages small and serializable
368
+ - Avoid sending large objects or circular references
369
+ - Consider using message IDs to reference larger data
370
+
371
+ ### Message Frequency
372
+
373
+ - Use `keepLatestMessage: true` for high-frequency updates
374
+ - Implement debouncing for rapid state changes
375
+ - Consider using `expirationDuration` for temporary messages
376
+
377
+ ### Memory Management\*\*
378
+
379
+ - Clear messages when they're no longer needed
380
+ - Use `cleaningInterval` to automatically remove expired messages
381
+ - Implement proper cleanup in component unmount
382
+
313
383
  ### Message Deduplication
314
384
 
315
385
  The `deduplicationTTL` option creates a time window (in milliseconds) during which messages with the same content and type from the same source are considered duplicates and will be ignored. This is particularly useful for:
@@ -390,25 +460,6 @@ This will log:
390
460
  - Cleanup operations
391
461
  - Error states
392
462
 
393
- ## ⚡ Performance Considerations
394
-
395
- 1. **Message Size**
396
-
397
- - Keep messages small and serializable
398
- - Avoid sending large objects or circular references
399
- - Consider using message IDs to reference larger data
400
-
401
- 2. **Message Frequency**
402
-
403
- - Use `keepLatestMessage: true` for high-frequency updates
404
- - Implement debouncing for rapid state changes
405
- - Consider using `expirationDuration` for temporary messages
406
-
407
- 3. **Memory Management**
408
- - Clear messages when they're no longer needed
409
- - Use `cleaningInterval` to automatically remove expired messages
410
- - Implement proper cleanup in component unmount
411
-
412
463
  ## 🧪 Testing
413
464
 
414
465
  ### Unit Testing
@@ -484,6 +535,25 @@ Your feedback and contributions are welcome — feel free to [open an issue](htt
484
535
 
485
536
  ---
486
537
 
538
+ ## 📦 Versioning & Releases
539
+
540
+ This project uses [Semantic Release](https://semantic-release.gitbook.io/) for fully automated versioning and changelog generation.
541
+
542
+ Every push to the `main` branch with a [Conventional Commit](https://www.conventionalcommits.org/en/v1.0.0/) message triggers a release that includes:
543
+
544
+ - ✅ Automatic semantic version bump (`major`, `minor`, or `patch`)
545
+ - ✅ Changelog generation and publishing to GitHub Releases
546
+ - ✅ Publishing to [npm](https://www.npmjs.com/package/react-broadcast-sync)
547
+
548
+ ### 🔧 Example Commit Messages
549
+
550
+ ```bash
551
+ feat: add support for per-type callbacks
552
+ fix: debounce cleanup runs properly on tab reload
553
+ chore: update dependencies
554
+
555
+ ---
556
+
487
557
  ## 🤝 Contributing
488
558
 
489
559
  PRs and feature suggestions welcome! Open an issue or submit a pull request.
@@ -493,3 +563,4 @@ PRs and feature suggestions welcome! Open an issue or submit a pull request.
493
563
  ## 🪪 License
494
564
 
495
565
  MIT © [Idan Shalem](https://github.com/IdanShalem)
566
+ ```
@@ -0,0 +1,130 @@
1
+ # React Broadcast Sync Demo
2
+
3
+ A showcase application demonstrating the capabilities of `react-broadcast-sync` - a library for synchronizing state across browser tabs.
4
+
5
+ ## 🚀 Live Demo
6
+
7
+ Check out the [live demo](https://react-broadcast-sync.vercel.app) to see the synchronization in action!
8
+
9
+ ## 🎯 Features
10
+
11
+ The demo showcases three main features:
12
+
13
+ 1. **Counter Synchronization**
14
+
15
+ - Real-time counter updates across tabs
16
+ - Visual feedback for sync status
17
+ - Smooth animations
18
+
19
+ 2. **Text Synchronization**
20
+
21
+ - Real-time text input sync
22
+ - Multi-line support
23
+ - Instant updates
24
+
25
+ 3. **Todo List**
26
+ - Synchronized todo items
27
+ - Real-time hover effects
28
+ - Scroll position sync
29
+ - Completion status sync
30
+ - Delete functionality
31
+
32
+ ## 🛠️ Technologies Used
33
+
34
+ - React 19
35
+ - TypeScript
36
+ - Material-UI
37
+ - Framer Motion
38
+ - Vite
39
+
40
+ ## 🚀 Getting Started
41
+
42
+ 1. Clone the repository:
43
+
44
+ ```bash
45
+ git clone https://github.com/IdanShalem/react-broadcast-sync.git
46
+ cd react-broadcast-sync/demo/react-broadcast-sync-demo
47
+ ```
48
+
49
+ 2. Install dependencies:
50
+
51
+ ```bash
52
+ npm install
53
+ ```
54
+
55
+ 3. Start the development server:
56
+
57
+ ```bash
58
+ npm run dev
59
+ ```
60
+
61
+ 4. Open multiple browser tabs to see the synchronization in action!
62
+
63
+ ## 📁 Project Structure
64
+
65
+ ```
66
+ src/
67
+ ├── components/
68
+ │ ├── Counter.tsx
69
+ │ ├── TextSync.tsx
70
+ │ └── TodoList.tsx
71
+ ├── hooks/
72
+ │ ├── useCounterBroadcast.ts
73
+ │ ├── useTextBroadcast.ts
74
+ │ └── useTodoBroadcast.ts
75
+ ├── App.tsx
76
+ ├── main.tsx
77
+ └── theme.ts
78
+ ```
79
+
80
+ ## 💡 Implementation Details
81
+
82
+ ### Counter Synchronization
83
+
84
+ ```typescript
85
+ const { messages, postMessage } = useBroadcastChannel('counter', {
86
+ keepLatestMessage: true,
87
+ namespace: 'demo-app',
88
+ });
89
+ ```
90
+
91
+ ### Text Synchronization
92
+
93
+ ```typescript
94
+ const { messages, postMessage } = useBroadcastChannel('text', {
95
+ keepLatestMessage: true,
96
+ namespace: 'demo-app',
97
+ });
98
+ ```
99
+
100
+ ### Todo List Synchronization
101
+
102
+ ```typescript
103
+ const { messages, postMessage } = useBroadcastChannel('todos', {
104
+ keepLatestMessage: true,
105
+ namespace: 'demo-app',
106
+ });
107
+ ```
108
+
109
+ ## 🎨 UI/UX Features
110
+
111
+ - Responsive design
112
+ - Smooth animations
113
+ - Visual feedback for sync status
114
+ - Modern Material-UI components
115
+ - Dark mode support
116
+
117
+ ## 🤝 Contributing
118
+
119
+ Contributions are welcome! Please feel free to submit a Pull Request.
120
+
121
+ ## 📝 License
122
+
123
+ This project is licensed under the MIT License - see the [LICENSE](../../LICENSE) file for details.
124
+
125
+ ## 👥 Author
126
+
127
+ Idan Shalem
128
+
129
+ - GitHub: [@IdanShalem](https://github.com/IdanShalem)
130
+ - LinkedIn: [Idan Shalem](https://www.linkedin.com/in/idan-shalem-3a1781169/)
@@ -0,0 +1,14 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <link rel="icon" type="image/png" href="/assets/react-broadcast-sync-logo.png" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>React Broadcast Sync Demo</title>
8
+ </head>
9
+
10
+ <body>
11
+ <div id="root"></div>
12
+ <script type="module" src="/src/main.tsx"></script>
13
+ </body>
14
+ </html>