Skip to content

Commit f3181ed

Browse files
committed
Add SyncMessagePort.receiveMessageIfAvailable()
1 parent 13e5d5c commit f3181ed

File tree

4 files changed

+83
-2
lines changed

4 files changed

+83
-2
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
## 1.1.0
2+
3+
* Add `SyncMessagePort.receiveMessageIfAvailable()`.
4+
5+
## 1.0.0
6+
7+
* Initial release

lib/index.test.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,60 @@ describe('SyncMessagePort', () => {
7373
});
7474
});
7575

76+
describe('receiveMessageIfAvailable()', () => {
77+
it('without a queued message', () => {
78+
const channel = SyncMessagePort.createChannel();
79+
const port = new SyncMessagePort(channel.port1);
80+
expect(port.receiveMessageIfAvailable()).toBe(undefined);
81+
port.close();
82+
});
83+
84+
it('with a queued message', () => {
85+
const channel = SyncMessagePort.createChannel();
86+
const port1 = new SyncMessagePort(channel.port1);
87+
const port2 = new SyncMessagePort(channel.port2);
88+
89+
port1.postMessage('done!');
90+
expect(port2.receiveMessageIfAvailable()?.message).toBe('done!');
91+
port1.close();
92+
});
93+
94+
it('on a closed channel', () => {
95+
const channel = SyncMessagePort.createChannel();
96+
const port1 = new SyncMessagePort(channel.port1);
97+
const port2 = new SyncMessagePort(channel.port2);
98+
99+
port1.close();
100+
expect(port2.receiveMessageIfAvailable()).toBe(undefined);
101+
});
102+
103+
it('bewteen receiving blocking messages', () => {
104+
const channel = SyncMessagePort.createChannel();
105+
const port = new SyncMessagePort(channel.port1);
106+
107+
spawnWorker(
108+
`
109+
// Wait a little bit just to make entirely sure that the parent thread
110+
// is awaiting a message.
111+
setTimeout(() => {
112+
port.postMessage('first');
113+
port.postMessage('second');
114+
115+
setTimeout(() => {
116+
port.postMessage('third');
117+
port.close();
118+
}, 100);
119+
}, 100);
120+
`,
121+
channel.port2,
122+
);
123+
124+
expect(port.receiveMessage()).toEqual('first');
125+
expect(port.receiveMessageIfAvailable()?.message).toEqual('second');
126+
expect(port.receiveMessage()).toEqual('third');
127+
});
128+
});
129+
76130
describe('with an asynchronous listener', () => {
77131
it('receives a message sent before listening', async () => {
78132
const channel = SyncMessagePort.createChannel();

lib/index.ts

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,28 @@ export class SyncMessagePort extends EventEmitter {
110110
}
111111
}
112112

113+
/**
114+
* Returns the message sent by the other port, if one is available. This *does
115+
* not* block, and will return `undefined` immediately if no message is
116+
* available. In order to distinguish between a message with value `undefined`
117+
* and no message, a message is return in an object with a `message` field.
118+
*
119+
* This may not be called while this has a listener for the `'message'` event.
120+
* It does *not* throw an error if the port is closed when this is called;
121+
* instead, it just returns `undefined`.
122+
*/
123+
receiveMessageIfAvailable(): {message: unknown} | undefined {
124+
if (this.listenerCount('message')) {
125+
throw new Error(
126+
'SyncMessageChannel.receiveMessageIfAvailable() may not be called ' +
127+
'while there are message listeners.',
128+
);
129+
}
130+
131+
return receiveMessageOnPort(this.port);
132+
}
133+
113134
// TODO(nex3):
114-
// * Add a non-blocking `receiveMessage()`
115135
// * Add a timeout option to `receiveMessage()`
116136
// * Add an option to `receiveMessage()` to return a special value if the
117137
// channel is closed.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "sync-message-port",
3-
"version": "1.0.0",
3+
"version": "1.1.0",
44
"description": "A Node.js communication port that can pass messages synchronously between workers",
55
"repository": "sass/sync-message-port",
66
"author": "Google Inc.",

0 commit comments

Comments
 (0)