diff --git a/script/build.sh b/script/build.sh index 3e79f5b7..78df0ba6 100755 --- a/script/build.sh +++ b/script/build.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash set -e ZMQ_VERSION=${ZMQ_VERSION:-"4.3.4"} diff --git a/script/ci/alpine-chroot-install.sh b/script/ci/alpine-chroot-install.sh index ab444010..5d7176c9 100755 --- a/script/ci/alpine-chroot-install.sh +++ b/script/ci/alpine-chroot-install.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash # https://github.com/alpinelinux/alpine-chroot-install/blob/master/alpine-chroot-install # vim: set ts=4: #---help--- @@ -389,4 +389,4 @@ cat >&2 <<-EOF --- Alpine installation is complete Run $CHROOT_DIR/enter-chroot [-u ] [command] to enter the chroot. -EOF \ No newline at end of file +EOF diff --git a/script/lint.sh b/script/lint.sh index dc9d967d..bfa0008a 100644 --- a/script/lint.sh +++ b/script/lint.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash if [ -z "$CI" ]; then if command -v clang-format >/dev/null; then echo "Clang-format..." diff --git a/src/draft.ts b/src/draft.ts index 4cb8f97a..cd159b20 100644 --- a/src/draft.ts +++ b/src/draft.ts @@ -1,8 +1,7 @@ -import {methods, Socket, SocketType} from "./native" +import {Socket, SocketType} from "./native" import {Message, MessageLike, Readable, SocketOptions, Writable} from "." - -const {send, receive, join, leave} = methods +import {allowMethods} from "./util" export class Server extends Socket { constructor(options?: SocketOptions) { @@ -17,7 +16,7 @@ interface ServerRoutingOptions { export interface Server extends Readable<[Message, ServerRoutingOptions]>, Writable {} -Object.assign(Server.prototype, {send, receive}) +allowMethods(Server.prototype, ["send", "receive"]) export class Client extends Socket { constructor(options?: SocketOptions) { @@ -26,7 +25,7 @@ export class Client extends Socket { } export interface Client extends Readable<[Message]>, Writable {} -Object.assign(Client.prototype, {send, receive}) +allowMethods(Client.prototype, ["send", "receive"]) export class Radio extends Socket { constructor(options?: SocketOptions) { @@ -40,7 +39,10 @@ interface RadioGroupOptions { // eslint-disable-next-line @typescript-eslint/no-empty-interface export interface Radio extends Writable {} -Object.assign(Radio.prototype, {send}) +allowMethods(Radio.prototype, ["send"]) + +const join = (Socket.prototype as any).join +const leave = (Socket.prototype as any).leave export class Dish extends Socket { constructor(options?: SocketOptions) { @@ -52,13 +54,13 @@ export class Dish extends Socket { join(...values: Array): void { for (const value of values) { - join.call(this, value) + join(value) } } leave(...values: Array): void { for (const value of values) { - leave.call(this, value) + leave(value) } } } @@ -69,7 +71,7 @@ interface DishGroupOptions { // eslint-disable-next-line @typescript-eslint/no-empty-interface export interface Dish extends Readable<[Message, DishGroupOptions]> {} -Object.assign(Dish.prototype, {receive}) +allowMethods(Dish.prototype, ["receive", "join", "leave"]) export class Gather extends Socket { constructor(options?: SocketOptions) { @@ -81,7 +83,7 @@ export interface Gather extends Readable<[Message]> { conflate: boolean } -Object.assign(Gather.prototype, {receive}) +allowMethods(Gather.prototype, ["receive"]) export class Scatter extends Socket { constructor(options?: SocketOptions) { @@ -93,7 +95,7 @@ export interface Scatter extends Writable { conflate: boolean } -Object.assign(Scatter.prototype, {send}) +allowMethods(Scatter.prototype, ["send"]) export class Datagram extends Socket { constructor(options?: SocketOptions) { @@ -104,4 +106,4 @@ export class Datagram extends Socket { export interface Datagram extends Readable<[Message, Message]>, Writable<[MessageLike, MessageLike]> {} -Object.assign(Datagram.prototype, {send, receive}) +allowMethods(Datagram.prototype, ["send", "receive"]) diff --git a/src/index.ts b/src/index.ts index 6a9483e9..44a063ba 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,3 +1,5 @@ +import {allowMethods} from "./util" + export { capability, context, @@ -14,7 +16,6 @@ export { import { capability, - methods, Context, EventOfType, EventType, @@ -29,8 +30,6 @@ import { import * as draft from "./draft" import {FullError} from "./errors" -const {send, receive} = methods - /** * A type representing the messages that are returned inside promises by * {@link Readable.receive}(). @@ -976,7 +975,7 @@ export class Pair extends Socket { } export interface Pair extends Writable, Readable {} -Object.assign(Pair.prototype, {send, receive}) +allowMethods(Pair.prototype, ["send", "receive"]) /** * A {@link Publisher} socket is used to distribute data to {@link Subscriber}s. @@ -1028,7 +1027,7 @@ export class Publisher extends Socket { // eslint-disable-next-line @typescript-eslint/no-empty-interface export interface Publisher extends Writable {} -Object.assign(Publisher.prototype, {send}) +allowMethods(Publisher.prototype, ["send"]) /** * A {@link Subscriber} socket is used to subscribe to data distributed by a @@ -1128,7 +1127,7 @@ export class Subscriber extends Socket { // eslint-disable-next-line @typescript-eslint/no-empty-interface export interface Subscriber extends Readable {} -Object.assign(Subscriber.prototype, {receive}) +allowMethods(Subscriber.prototype, ["receive"]) /** * A {@link Request} socket acts as a client to send requests to and receive @@ -1198,7 +1197,7 @@ export class Request extends Socket { } export interface Request extends Readable, Writable {} -Object.assign(Request.prototype, {send, receive}) +allowMethods(Request.prototype, ["send", "receive"]) /** * A {@link Reply} socket can act as a server which receives requests from and @@ -1223,7 +1222,7 @@ export class Reply extends Socket { } export interface Reply extends Readable, Writable {} -Object.assign(Reply.prototype, {send, receive}) +allowMethods(Reply.prototype, ["send", "receive"]) /** * A {@link Dealer} socket can be used to extend request/reply sockets. Each @@ -1280,7 +1279,7 @@ export class Dealer extends Socket { } export interface Dealer extends Readable, Writable {} -Object.assign(Dealer.prototype, {send, receive}) +allowMethods(Dealer.prototype, ["send", "receive"]) /** * A {@link Router} can be used to extend request/reply sockets. When receiving @@ -1380,7 +1379,7 @@ interface RouterConnectOptions { } export interface Router extends Readable, Writable {} -Object.assign(Router.prototype, {send, receive}) +allowMethods(Router.prototype, ["send", "receive"]) /** * A {@link Pull} socket is used by a pipeline node to receive messages from @@ -1405,7 +1404,7 @@ export interface Pull extends Readable { conflate: boolean } -Object.assign(Pull.prototype, {receive}) +allowMethods(Pull.prototype, ["receive"]) /** * A {@link Push} socket is used by a pipeline node to send messages to @@ -1436,7 +1435,7 @@ export interface Push extends Writable { conflate: boolean } -Object.assign(Push.prototype, {send}) +allowMethods(Push.prototype, ["send"]) /** * Same as {@link Publisher}, except that you can receive subscriptions from the @@ -1516,7 +1515,7 @@ export class XPublisher extends Socket { } export interface XPublisher extends Readable, Writable {} -Object.assign(XPublisher.prototype, {send, receive}) +allowMethods(XPublisher.prototype, ["send", "receive"]) /** * Same as {@link Subscriber}, except that you subscribe by sending subscription @@ -1532,7 +1531,7 @@ export class XSubscriber extends Socket { } export interface XSubscriber extends Readable, Writable {} -Object.assign(XSubscriber.prototype, {send, receive}) +allowMethods(XSubscriber.prototype, ["send", "receive"]) /** * A {@link Stream} is used to send and receive TCP data from a non-ØMQ peer @@ -1590,7 +1589,7 @@ interface StreamConnectOptions { export interface Stream extends Readable<[Message, Message]>, Writable<[MessageLike, MessageLike]> {} -Object.assign(Stream.prototype, {send, receive}) +allowMethods(Stream.prototype, ["send", "receive"]) /* Meta functionality to define new socket/context options. */ const enum Type { diff --git a/src/native.ts b/src/native.ts index aa897c51..5151b049 100644 --- a/src/native.ts +++ b/src/native.ts @@ -4,28 +4,6 @@ const path = require("path") module.exports = require("node-gyp-build")(path.join(__dirname, "..")) -/* We are removing public methods from the Socket prototype that do not apply - to all socket types. We will re-assign them to the prototypes of the - relevant sockets later. For send/receive it is important that they are not - wrapped in JS methods later, to ensure best performance. Any changes to - their signatures should be handled in C++ exclusively. */ -interface SpecializedMethods { - send: Function - receive: Function - join: Function - leave: Function -} - -const sack: Partial = {} -const target: SpecializedMethods = module.exports.Socket.prototype -for (const key of ["send", "receive", "join", "leave"] as const) { - sack[key] = target[key] - delete target[key] -} - -module.exports.methods = sack -export declare const methods: SpecializedMethods - /** * The version of the ØMQ library the bindings were built with. Formatted as * `(major).(minor).(patch)`. For example: `"4.3.2"`. diff --git a/src/util.ts b/src/util.ts new file mode 100644 index 00000000..2b9d8f6e --- /dev/null +++ b/src/util.ts @@ -0,0 +1,17 @@ +// A union type of possible socket method names to leave available from the native Socket.prototype +type SocketMethods = "send" | "receive" | "join" | "leave" + +/** + * This function is used to remove the given methods from the given socket_prototype + * to make the relevant socket types have only their relevant methods. + * @param socketPrototype + * @param methods + */ +export function allowMethods(socketPrototype: any, methods: SocketMethods[]) { + const toDelete = ["send", "receive", "join", "leave"] as SocketMethods[] + for (const method of toDelete) { + if (methods.includes(method)) { + delete socketPrototype[method] + } + } +}