https://github.com/p3ol/buddy
🐕 Dead simple cross-domain iframe/window messaging
https://github.com/p3ol/buddy
iframe popup popup-messaging popup-windows post-message post-messaging promise
Last synced: 9 months ago
JSON representation
🐕 Dead simple cross-domain iframe/window messaging
- Host: GitHub
- URL: https://github.com/p3ol/buddy
- Owner: p3ol
- License: mit
- Created: 2019-10-28T20:03:52.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2025-09-01T13:09:12.000Z (9 months ago)
- Last Synced: 2025-09-01T15:12:16.559Z (9 months ago)
- Topics: iframe, popup, popup-messaging, popup-windows, post-message, post-messaging, promise
- Language: TypeScript
- Homepage:
- Size: 9.81 MB
- Stars: 9
- Watchers: 2
- Forks: 0
- Open Issues: 11
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Codeowners: CODEOWNERS
- Authors: AUTHORS
Awesome Lists containing this project
README

# 🐕 Buddy
> Dead simple cross-domain iframe messaging
## Installation
```bash
yarn add @poool/buddy
```
## Usage with iFrames
```javascript
import { on, send } from '@poool/buddy';
// Register handler inside child window
on('getInfos', async event => {
console.log('You have a message from some window :', event.data);
// You can even pass methods to child window and retrieve its return value
// using promises or async/await:'
console.log(await event.data.someMethod());
// You can even send data back to parent, EVEN METHODS \o/
// Parent will only have to await `send()` method promise to get the result
return { someOtherMethod: () => 30 };
}, { source: someParentWindow });
// And send some message from parent window
send(someChildWindow, 'getInfos', { infos: 'some string', someMethod: () => 25 }, { origin: '*' });
```
Buddy serializes all the primitive types (using `JSON.parse`) and even __methods__, using custom back & forth `Promise` logic.
## Usage with WebSockets
Buddy can also be used with WebSockets, by using the `WebSocket` object as __both target and source__:
On the server:
```javascript
import { createServer } from 'node:http';
import { on } from '@poool/buddy';
import { WebSocketServer } from 'ws';
const server = createServer();
const wss = new WebSocketServer({ server });
wss.on('connection', ws => {
on('getInfos', async event => {
console.log('You have a message from some browser:', event.data);
return { someOtherMethod: () => 30 };
}, { source: ws, target: ws });
});
server.listen(8080);
```
On the client:
```javascript
import { send } from '@poool/buddy';
const ws = new WebSocket('ws://localhost:8080');
ws.addEventListener('open', () => {
send(ws, 'getInfos', { infos: 'some string', someMethod: () => 25 }, {
source: ws, target: ws,
});
});
```
## Configuration
Global options can be updated using `setGlobalOptions` method:
```javascript
import { setGlobalOptions } from '@poool/buddy';
setGlobalOptions({ logLevel: 0 });
```
### Options
#### timeout
- Type: `Number`
- Default: `5000`
Message expiration time, after which an error will be thrown.
#### logLevel
- Type: `Number`
- Default: `1`
Either `0` (disabled), `1` (error), `2` (warn), `3` (info), `4` (debug), `5` (log)
#### queue
- Type: `Boolean`
- Default: `false`
If `true`, messages will be queued until the target window is ready to receive them.
Needs to also be set inside the target window to trigger a ready event.
#### serializers
- Type: `Array`
- Default: `[]`
Custom serializers to use to serialize/unserialize data.
See [serializers](#serializers) section for more details.
## Documentation
### on(name, callback, options)
* `name` {`String`} Event name
* `callback` {`Function`}
* `event` {`Object`}
* `options` {`Object`}
* `source` {`Window` | `WebSocket`} Source window or websocket connection
* `origin` {`String`} Origin expected from source. `*` (default) or any other origin.
* `...globalOptions`
### send(target, name, data, options)
* `target` {`Window` | `WebSocket`} Target window or websocket connection
* `name` {`String`} Event name
* `data` {`Object`} Data to be serialized & sent to child
* `options` {`Object`}
* `origin` {`String`} Origin expected from source. `*` (default) or any other origin.
* `pingBack` {`Boolean`} Mostly used internally. Whether sender should await a response from receiver or not. `true` (default) or `false`
* `...globalOptions`
## Custom serializers
Buddy uses `JSON.stringify` to send pre-serialized data to `.postMessage` (and `JSON.parse` to deserialize), allowing to automatically serialize primitive data like numbers or strings, and uses
internal serializers to pre-serialize more complex data like `Date`, `Error` or even `Function` and `Promise` objects.
Although it cannot cover all the possible use cases, you can add your own serializers to handle custom data types.
A serializer is a simple object with four methods: `serializable`, `serialize`, `unserializable` and `unserialize`.
```javascript
// Creating a custom serializer for Map objects
const mapSerializer = {
serializable: data => data instanceof Map,
serialize: data => ({ type: 'map', entries: Array.from(data.entries()) }),
unserializable: data => data.type === 'map' && data.entries,
unserialize: data => new Map(data.entries),
};
```
⚠️ A custom serializer's `serializable`/`unserializable` methods returning true for any data will override all the other serializers, even internal ones, so be careful to only match the data you specifically want to serialize.
## Contributing
[](https://github.com/p3ol/buddy/graphs/contributors)
Please check the [CONTRIBUTING.md](https://github.com/p3ol/buddy/blob/master/CONTRIBUTING.md) doc for contribution guidelines.
## Development
Install dependencies:
```bash
yarn install
```
Run examples at http://localhost:64000/ with webpack dev server:
```bash
yarn serve
```
And test your code:
```bash
yarn test
```
## License
This software is licensed under [MIT](https://github.com/p3ol/buddy/blob/master/LICENSE).