dgram-as-promised
Advanced tools
Comparing version 4.0.0 to 5.0.0
# Changelog | ||
## v5.0.0 2020-10-16 | ||
- `recv` returns `undefined` when socket is closed. | ||
- New `iterate` method returns asynchrounous iterator. | ||
- New `destroy` method cleans internal listeners. | ||
## v4.0.0 2020-10-15 | ||
@@ -4,0 +10,0 @@ |
@@ -12,4 +12,5 @@ /// <reference types="node" /> | ||
} | ||
export declare class SocketAsPromised { | ||
export declare class SocketAsPromised implements AsyncIterable<IncomingPacket> { | ||
readonly socket: Socket; | ||
_closed?: boolean; | ||
_errored?: Error; | ||
@@ -23,3 +24,3 @@ constructor(socket: Socket); | ||
send(msg: Buffer | string | Uint8Array, offset: number, length: number, port: number, address: string): Promise<number>; | ||
recv(): Promise<IncomingPacket>; | ||
recv(): Promise<IncomingPacket | undefined>; | ||
address(): AddressInfo | string; | ||
@@ -38,4 +39,8 @@ setBroadcast(flag: boolean): void; | ||
getSendBufferSize(): number; | ||
iterate(): AsyncIterableIterator<IncomingPacket>; | ||
[Symbol.asyncIterator](): AsyncIterableIterator<IncomingPacket>; | ||
destroy(): void; | ||
private readonly closeHandler; | ||
private readonly errorHandler; | ||
} | ||
export default SocketAsPromised; |
@@ -8,5 +8,9 @@ "use strict"; | ||
this.socket = socket; | ||
this.closeHandler = () => { | ||
this._closed = true; | ||
}; | ||
this.errorHandler = (err) => { | ||
this._errored = err; | ||
}; | ||
socket.on("close", this.closeHandler); | ||
socket.on("error", this.errorHandler); | ||
@@ -109,2 +113,10 @@ } | ||
} | ||
if (this._closed) { | ||
this._closed = undefined; | ||
return resolve(undefined); | ||
} | ||
const closeHandler = () => { | ||
removeListeners(); | ||
resolve(undefined); | ||
}; | ||
const errorHandler = (err) => { | ||
@@ -119,5 +131,7 @@ removeListeners(); | ||
const removeListeners = () => { | ||
socket.removeListener("close", closeHandler); | ||
socket.removeListener("error", errorHandler); | ||
socket.removeListener("message", messageHandler); | ||
}; | ||
socket.on("close", closeHandler); | ||
socket.on("error", errorHandler); | ||
@@ -168,2 +182,36 @@ socket.on("message", messageHandler); | ||
} | ||
iterate() { | ||
const socketAsPromised = this; | ||
let wasEof = false; | ||
return { | ||
[Symbol.asyncIterator]() { | ||
return this; | ||
}, | ||
async next() { | ||
if (wasEof) { | ||
return { value: "", done: true }; | ||
} | ||
else { | ||
const value = await socketAsPromised.recv(); | ||
if (value === undefined) { | ||
wasEof = true; | ||
return { value: "", done: true }; | ||
} | ||
else { | ||
return { value, done: false }; | ||
} | ||
} | ||
}, | ||
}; | ||
} | ||
[Symbol.asyncIterator]() { | ||
return this.iterate(); | ||
} | ||
destroy() { | ||
const socket = this.socket; | ||
if (socket) { | ||
socket.removeListener("close", this.closeHandler); | ||
socket.removeListener("error", this.errorHandler); | ||
} | ||
} | ||
} | ||
@@ -170,0 +218,0 @@ exports.SocketAsPromised = SocketAsPromised; |
{ | ||
"name": "dgram-as-promised", | ||
"version": "4.0.0", | ||
"version": "5.0.0", | ||
"description": "Promisify dgram module", | ||
@@ -30,2 +30,3 @@ "main": "lib/dgram-as-promised.js", | ||
"@types/chai-as-promised": "^7.1.3", | ||
"@types/dirty-chai": "^2.0.2", | ||
"@types/mocha": "^8.0.3", | ||
@@ -41,2 +42,3 @@ "@types/node": "^14.11.8", | ||
"cross-env": "^7.0.2", | ||
"dirty-chai": "^2.0.1", | ||
"dns-packet-typescript": "^5.3.0", | ||
@@ -43,0 +45,0 @@ "eslint": "^7.11.0", |
@@ -59,2 +59,4 @@ # dgram-as-promised | ||
### bind | ||
Method `bind` returns `Promise` object which resolves to address info when | ||
@@ -74,2 +76,4 @@ `listening` event is emitted. | ||
### send | ||
Method `send` returns `Promise` object which is fulfilled when message has been | ||
@@ -83,14 +87,21 @@ sent. | ||
### recv | ||
Method `recv` returns `Promise` object which resolves to the object with `msg` | ||
and `rinfo` properties as from `message` event. | ||
and `rinfo` properties as from `message` event or resolves to `undefined` when | ||
socket is already closed. | ||
```js | ||
const packet = await socket.recv() | ||
console.log(`Received message: ${packet.msg.toString()}`) | ||
console.log(`Received ${packet.rinfo.size} bytes`) | ||
if (packet) { | ||
console.log(`Received message: ${packet.msg.toString()}`) | ||
console.log(`Received ${packet.rinfo.size} bytes`) | ||
} | ||
``` | ||
Method `close` returns `Promise` object which resolves to number of bytes sent | ||
when `close` event is emitted. | ||
### close | ||
Method `close` returns `Promise` object which resolves when `close` event is | ||
emitted. | ||
```js | ||
@@ -101,2 +112,25 @@ await socket.close() | ||
### iterate | ||
Method `iterate` and the socket object return asynchronous iterator which will | ||
call `recv` method until socket is closed. | ||
```js | ||
for await (const packet of socket) { | ||
console.info(packet.msg.toString()) | ||
// Close socket if Ctrl-D is in the message | ||
if (packet.msg.indexOf(4) !== -1) { | ||
await socket.close() | ||
} | ||
} | ||
``` | ||
### destroy | ||
Method `destroy` cleans internal listeners. | ||
```js | ||
socket.destroy() | ||
``` | ||
## License | ||
@@ -103,0 +137,0 @@ |
@@ -16,6 +16,8 @@ /// <reference types="node" /> | ||
export class SocketAsPromised { | ||
export class SocketAsPromised implements AsyncIterable<IncomingPacket> { | ||
_closed?: boolean | ||
_errored?: Error | ||
constructor(public readonly socket: Socket) { | ||
socket.on("close", this.closeHandler) | ||
socket.on("error", this.errorHandler) | ||
@@ -129,3 +131,3 @@ } | ||
recv(): Promise<IncomingPacket> { | ||
recv(): Promise<IncomingPacket | undefined> { | ||
const socket = this.socket | ||
@@ -140,2 +142,12 @@ | ||
if (this._closed) { | ||
this._closed = undefined | ||
return resolve(undefined) | ||
} | ||
const closeHandler = () => { | ||
removeListeners() | ||
resolve(undefined) | ||
} | ||
const errorHandler = (err: Error) => { | ||
@@ -152,2 +164,3 @@ removeListeners() | ||
const removeListeners = () => { | ||
socket.removeListener("close", closeHandler) | ||
socket.removeListener("error", errorHandler) | ||
@@ -157,2 +170,3 @@ socket.removeListener("message", messageHandler) | ||
socket.on("close", closeHandler) | ||
socket.on("error", errorHandler) | ||
@@ -217,2 +231,44 @@ socket.on("message", messageHandler) | ||
iterate(): AsyncIterableIterator<IncomingPacket> { | ||
const socketAsPromised = this | ||
let wasEof = false | ||
return { | ||
[Symbol.asyncIterator](): AsyncIterableIterator<IncomingPacket> { | ||
return this | ||
}, | ||
async next(): Promise<IteratorResult<IncomingPacket>> { | ||
if (wasEof) { | ||
return {value: "", done: true} | ||
} else { | ||
const value = await socketAsPromised.recv() | ||
if (value === undefined) { | ||
wasEof = true | ||
return {value: "", done: true} | ||
} else { | ||
return {value, done: false} | ||
} | ||
} | ||
}, | ||
} | ||
} | ||
[Symbol.asyncIterator](): AsyncIterableIterator<IncomingPacket> { | ||
return this.iterate() | ||
} | ||
destroy(): void { | ||
const socket = this.socket | ||
if (socket) { | ||
socket.removeListener("close", this.closeHandler) | ||
socket.removeListener("error", this.errorHandler) | ||
} | ||
} | ||
private readonly closeHandler = (): void => { | ||
this._closed = true | ||
} | ||
private readonly errorHandler = (err: Error): void => { | ||
@@ -219,0 +275,0 @@ this._errored = err |
Sorry, the diff of this file is not supported yet
33768
562
137
28