network-services
Advanced tools
Comparing version 1.0.4 to 1.1.0
@@ -16,5 +16,2 @@ "use strict"; | ||
this.egressQueue = Buffer.allocUnsafe(0); | ||
if (stream.listenerCount('error') === 0) { | ||
stream.on('error', console.error); | ||
} | ||
this.stream.once('close', () => { | ||
@@ -35,3 +32,3 @@ delete this.ingressQueue; | ||
if (this.egressQueueSizeLimit && this.egressQueue.length > this.egressQueueSizeLimit) { | ||
throw new errors_1.QueueSizeLimitError(`The egress buffer exeeded ${this.egressQueueSizeLimit.toLocaleString()} bytes.`); | ||
throw new errors_1.QueueSizeLimitError(`The egress buffer exceeded ${this.egressQueueSizeLimit.toLocaleString()} bytes.`); | ||
} | ||
@@ -69,3 +66,3 @@ if (!this.stream.writableNeedDrain) { | ||
if (this.ingressQueueSizeLimit && this.ingressQueue.length > this.ingressQueueSizeLimit) { | ||
throw new errors_1.QueueSizeLimitError(`The ingress buffer exeeded ${this.ingressQueueSizeLimit.toLocaleString()} bytes.`); | ||
throw new errors_1.QueueSizeLimitError(`The ingress buffer exceeded ${this.ingressQueueSizeLimit.toLocaleString()} bytes.`); | ||
} | ||
@@ -72,0 +69,0 @@ if (this.messageSize === null) { |
@@ -13,5 +13,2 @@ "use strict"; | ||
this.egressQueueSizeLimit = options?.egressQueueSizeLimit; | ||
if (stream.listenerCount('error') === 0) { | ||
stream.on('error', console.error); | ||
} | ||
this.stream.once('close', () => { | ||
@@ -27,3 +24,3 @@ delete this.egressQueue; | ||
if (this.egressQueueSizeLimit && this.egressQueue.length > this.egressQueueSizeLimit) { | ||
throw new errors_1.QueueSizeLimitError(`The egress buffer exeeded ${this.egressQueueSizeLimit.toLocaleString()} bytes.`); | ||
throw new errors_1.QueueSizeLimitError(`The egress buffer exceeded ${this.egressQueueSizeLimit.toLocaleString()} bytes.`); | ||
} | ||
@@ -30,0 +27,0 @@ if (!this.stream.writableNeedDrain) { |
/// <reference types="node" /> | ||
/// <reference types="node" /> | ||
/// <reference types="node" /> | ||
import * as threads from "node:worker_threads"; | ||
import * as worker_threads from "node:worker_threads"; | ||
import * as stream from "node:stream"; | ||
import { CallMessage, ResultMessage } from "./messages"; | ||
export declare class PortStream extends stream.Duplex { | ||
port?: threads.MessagePort; | ||
port?: worker_threads.MessagePort | worker_threads.Worker; | ||
messageQueue: Array<CallMessage | ResultMessage>; | ||
constructor(options?: stream.DuplexOptions); | ||
constructor(port?: worker_threads.MessagePort | worker_threads.Worker, options?: stream.DuplexOptions); | ||
_write(chunk: CallMessage | ResultMessage, encoding: BufferEncoding, callback: (error?: Error | null) => void): Promise<void>; | ||
_read(size: number): void; | ||
} | ||
export declare function createPortStream(options?: stream.DuplexOptions): PortStream; | ||
export declare function createPortStream(port?: worker_threads.MessagePort | worker_threads.Worker, options?: stream.DuplexOptions): PortStream; |
@@ -27,3 +27,3 @@ "use strict"; | ||
exports.createPortStream = exports.PortStream = void 0; | ||
const threads = __importStar(require("node:worker_threads")); | ||
const worker_threads = __importStar(require("node:worker_threads")); | ||
const stream = __importStar(require("node:stream")); | ||
@@ -34,7 +34,7 @@ const $data = Symbol('data'); | ||
messageQueue; | ||
constructor(options) { | ||
constructor(port, options) { | ||
super({ ...options, ...{ objectMode: true } }); | ||
this.messageQueue = []; | ||
if (threads.parentPort) { | ||
this.port = threads.parentPort; | ||
this.port = port ? port : worker_threads.parentPort ? worker_threads.parentPort : undefined; | ||
if (this.port) { | ||
this.port.on('message', (message) => { | ||
@@ -88,5 +88,5 @@ this.messageQueue.push(message); | ||
exports.PortStream = PortStream; | ||
function createPortStream(options) { | ||
return new PortStream(options); | ||
function createPortStream(port, options) { | ||
return new PortStream(port, options); | ||
} | ||
exports.createPortStream = createPortStream; |
@@ -32,25 +32,10 @@ "use strict"; | ||
let base = this.app; | ||
for (let i = 0; i < props.length; i++) { | ||
const name = props[i]; | ||
if (typeof name == 'string') { | ||
const value = base[name]; | ||
if (typeof value == 'function' && name in base) { | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment | ||
const result = await value.call(base, ...message.args); | ||
this.mux.mux(new messages_1.ResultMessage({ type: 2, id, data: result })); | ||
return; | ||
} | ||
else if (value !== null && typeof value == 'object' && !Array.isArray(value)) { | ||
base = value; | ||
continue; | ||
} | ||
else { | ||
break; | ||
} | ||
} | ||
else { | ||
break; | ||
} | ||
for (let i = 0; i < props.length - 1; i++) { | ||
base = base[props[i]]; | ||
} | ||
throw new TypeError(`${propPath ?? props.join('.')} is not a function.`); | ||
if (typeof base[props[props.length - 1]] != 'function') { | ||
throw new TypeError(`${props[props.length - 1]} is not a function`); | ||
} | ||
const result = await base[props[props.length - 1]](...message.args); | ||
this.mux.mux(new messages_1.ResultMessage({ type: 2, id, data: result })); | ||
} | ||
@@ -72,3 +57,3 @@ catch (err) { | ||
const error = {}; | ||
for (const name of Object.getOwnPropertyNames(err)) { | ||
for (const name of Object.getOwnPropertyNames(err).concat(Object.getOwnPropertyNames(Object.getPrototypeOf(err)))) { | ||
error[name] = err[name]; | ||
@@ -75,0 +60,0 @@ } |
@@ -1,2 +0,2 @@ | ||
export type Callable = (...args: Array<any>) => any; | ||
export type Callable = (...args: Array<any>) => unknown; | ||
export type PropPath<T extends object> = { | ||
@@ -3,0 +3,0 @@ [k in keyof T]: (k extends string ? (T[k] extends Callable ? k : (T[k] extends Array<any> ? never : (T[k] extends object ? `${k}.${PropPath<T[k]>}` : never))) : never); |
{ | ||
"name": "network-services", | ||
"version": "1.0.4", | ||
"version": "1.1.0", | ||
"description": "", | ||
@@ -5,0 +5,0 @@ "main": "./dist/index.js", |
@@ -41,3 +41,3 @@ # *Network⬄Services* | ||
- [Message Protocol](#message-protocol) | ||
- [Default JSON Message Protocol](#default-json-communication-protocol) | ||
- [Default JSON Message Protocol](#default-json-message-protocol) | ||
- [Security](#security) | ||
@@ -79,3 +79,3 @@ - [Use TLS encryption.](#use-tls-encryption) | ||
A Service Pool is a utility feature that facilitates scaling Service Apps using Worker threads. The Service Pool implementation is just one of many [scaling](#scaling) models that could be used to scale a *Network-Services* app. You can create a Service Pool using the `network-services.createServicePool` helper function. Because a pool of Service Apps may be shared by many Service API clients (i.e., a many-to-many relationship), the Service Pool implementation is limited to request-response messaging; a request is made using a Service API and the response from the Service App is returned to the caller. However, a more sophisticated implementation could support coordinated bi-directional communication between many Service API clients and a pool of Service Apps. | ||
A Service Pool is a utility feature that facilitates scaling Service Apps using Worker threads. The Service Pool implementation is just one of many [scaling](#scaling) models that could be used to scale a *Network-Services* app. You can create a Service Pool using the `network-services.createServicePool` helper function. Because a pool of Service Apps may be shared by many Service API clients (i.e., a many-to-many relationship), the Service Pool implementation is limited to request-response messaging; a request (i.e., a method call) is made using a Service API and the response (i.e., the return value) from the Service App is returned to the caller. However, a more sophisticated implementation could support coordinated bi-directional communication between many Service API clients and a pool of Service Apps. | ||
@@ -93,3 +93,3 @@ Please see the [Scalable "Hello, World!"](https://github.com/faranalytics/network-services/tree/main/examples/scalable_hello_world) example for a working implementation using a Service Pool. | ||
import * as net from "node:net"; | ||
import { createService } from 'network-services'; | ||
import { createService } from "network-services"; | ||
``` | ||
@@ -194,7 +194,8 @@ | ||
### network-services.createPortStream(options) | ||
### network-services.createPortStream(port, options) | ||
- `port` `<worker_threads.MessagePort | worker_threads.Worker>` An optional `MessagePort` to be wrapped by a `stream.Duplex`. **Default**: `worker_threads.parentPort` | ||
- `options` `<internal.DuplexOptions>` An optional `internal.DuplexOptions` object to be passed to the `PortStream` parent class. | ||
- Returns: `<PortStream>` | ||
A `PortStream` wraps the `parentPort` of the Worker thread into a `stream.Duplex`. Hence, a `PortStream` *is a* `stream.Duplex`, so it can be passed to the *Network-Services* `createService` helper function. This is the stream adapter that is used in the Worker module. | ||
A `PortStream` defaults to wrapping the `parentPort` of the Worker thread into a `stream.Duplex`. Hence, a `PortStream` *is a* `stream.Duplex`, so it can be passed to the *Network-Services* `createService` helper function. This is the stream adapter that is used in the Worker module. | ||
@@ -201,0 +202,0 @@ ## Type Safety |
Deprecated
MaintenanceThe maintainer of the package marked it as deprecated. This could indicate that a single version should not be used, or that the package is no longer maintained and any new vulnerabilities will not be fixed.
Found 1 instance in 1 package
0
290
73323
1107