Socket
Socket
Sign inDemoInstall

nanolith

Package Overview
Dependencies
1
Maintainers
1
Versions
95
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.4.5 to 0.4.6

2

build/constants/pool.js

@@ -1,1 +0,1 @@

export var ConcurrencyOption;!function(n){n.Quarter="Quarter",n.Half="Half",n.Default="x2",n.x1="x1",n.x2="x2",n.x4="x4",n.x6="x6",n.x8="x8",n.x10="x10"}(ConcurrencyOption||(ConcurrencyOption={}));export const concurrencyOptionMultipliers={[ConcurrencyOption.Quarter]:.25,[ConcurrencyOption.Half]:.5,[ConcurrencyOption.x1]:1,[ConcurrencyOption.Default]:2,[ConcurrencyOption.x4]:4,[ConcurrencyOption.x6]:6,[ConcurrencyOption.x8]:8,[ConcurrencyOption.x10]:10};
export var ConcurrencyOption;!function(n){n.Quarter="Quarter",n.Half="Half",n.Default="x2",n.x1="x1",n.x2="x2",n.x4="x4",n.x6="x6",n.x8="x8",n.x10="x10"}(ConcurrencyOption||(ConcurrencyOption={}));export const concurrencyOptionMultipliers={[ConcurrencyOption.Quarter]:.25,[ConcurrencyOption.Half]:.5,[ConcurrencyOption.x1]:1,[ConcurrencyOption.x2]:2,[ConcurrencyOption.x4]:4,[ConcurrencyOption.x6]:6,[ConcurrencyOption.x8]:8,[ConcurrencyOption.x10]:10};

@@ -22,2 +22,2 @@ import type { DefineOptions, TaskDefinitions } from '../types/definitions.js';

*/
export declare function define<Definitions extends TaskDefinitions>(definitions: Definitions, { identifier, file: fileFromOptions, safeMode }?: DefineOptions): Promise<Nanolith<Definitions>>;
export declare function define<Definitions extends TaskDefinitions>(definitions: Definitions, { identifier, file: fileFromOptions, safeMode, }?: DefineOptions): Promise<Nanolith<Definitions>>;

@@ -1,1 +0,1 @@

import{isMainThread,workerData}from"worker_threads";import{workerHandler}from"../handlers/index.js";import{runTaskWorker,runServiceWorker}from"../runners/index.js";import{assertCurrentFileNotEqual,getAutoIdentifier,getCurrentFile}from"./utilities.js";import{ServiceCluster}from"../service_cluster/index.js";export async function define(e,{identifier:r,file:t,safeMode:i=!0}={}){const n=r||getAutoIdentifier(e),s=t??getCurrentFile(),a=Object.freeze(Object.assign((async e=>(i&&assertCurrentFileNotEqual(s),runTaskWorker(s,n,e))),{launchService:Object.freeze((async(e={})=>(i&&assertCurrentFileNotEqual(s),runServiceWorker(s,n,e)))),clusterize:Object.freeze((async function(e=1,r={}){i&&assertCurrentFileNotEqual(s);const t=new ServiceCluster(this,{autoRenew:r.autoRenew});return await t.launch(e,r),t})),file:s,identifier:n}));if(!isMainThread){if(workerData.identifier!==n)return a;workerHandler(e)}return a}
import{isMainThread,workerData}from"worker_threads";import{workerHandler}from"../handlers/index.js";import{runTaskWorker,runServiceWorker}from"../runners/index.js";import{assertCurrentFileNotEqual,getAutoIdentifier,getCurrentFile}from"./utilities.js";import{ServiceCluster}from"../service_cluster/index.js";export async function define(e,{identifier:r=getAutoIdentifier(e),file:t,safeMode:i=!0}={}){const n=t??getCurrentFile(),s=Object.freeze(Object.assign((async e=>(i&&assertCurrentFileNotEqual(n),runTaskWorker(n,r,e))),{launchService:Object.freeze((async(e={})=>(i&&assertCurrentFileNotEqual(n),runServiceWorker(n,r,e)))),clusterize:Object.freeze((async function(e=1,r={}){i&&assertCurrentFileNotEqual(n);const t=new ServiceCluster(this,{autoRenew:r.autoRenew});return await t.launch(e,r),t})),file:n,identifier:r}));return isMainThread||workerData.identifier!==r||workerHandler(e),s}

@@ -58,3 +58,3 @@ /// <reference types="node" resolution-mode="require"/>

*/
get uniqueKey(): string;
get uniqueKey(): `${string}-${string}-${string}-${string}-${string}`;
/**

@@ -61,0 +61,0 @@ * Create a {@link Writable} instance that can be piped into in order to stream data to

@@ -1,1 +0,1 @@

import{Worker,SHARE_ENV}from"worker_threads";import{generateConcurrencyValue,getConcurrencyCounter,getActiveCounter}from"./utilities.js";import{ConcurrencyOption}from"../constants/pool.js";import{PoolItem}from"./pool_item.js";import{getCount,incr,decr,getValue,setValue}from"../utilities/index.js";export const pool=Object.seal(new class{#e=getConcurrencyCounter();#t=getActiveCounter();#r=[];option=ConcurrencyOption;get maxConcurrency(){return getValue(this.#e)}get maxed(){return getCount(this.#t)>=getValue(this.#e)}get queueLength(){return this.#r.length}get activeCount(){return getCount(this.#t)}get idle(){return!getCount(this.#t)}get next(){return this.#r[0].options}setConcurrency(e){if(!Object.values(ConcurrencyOption).includes(e))throw new Error(`${e} is not a valid and safe ConcurrencyOption!`);setValue(this.#e,(()=>generateConcurrencyValue(e)))}__enqueue(e){if(!(e instanceof PoolItem))throw new Error("The provided item cannot be enqueued.");e.options.priority?this.#r.unshift(e):this.#r.push(e),this.maxed||this.#n()}#n(){if(this.maxed||!this.#r.length)return;incr(this.#t);const e=this.#r.shift(),{file:t,workerData:r,options:n,reffed:o,shareEnv:i}=e.options,u=new Worker(t,{...n,workerData:{...r,pool:{active:this.#t,concurrency:this.#e}},...i?{env:SHARE_ENV}:void 0});o?u.ref():u.unref(),e.emit("created",u),u.once("exit",(()=>{decr(this.#t),this.#n()}))}});
import{Worker,SHARE_ENV}from"worker_threads";import{generateConcurrencyValue,getConcurrencyCounter,getActiveCounter}from"./utilities.js";import{ConcurrencyOption}from"../constants/pool.js";import{PoolItem}from"./pool_item.js";import{SharedCounter,SharedU32Integer}from"../utilities/index.js";export const pool=Object.seal(new class{#e=getConcurrencyCounter();#t=getActiveCounter();#r=[];option=ConcurrencyOption;get maxConcurrency(){return SharedU32Integer.getValue(this.#e)}get maxed(){return SharedCounter.getCount(this.#t)>=SharedU32Integer.getValue(this.#e)}get queueLength(){return this.#r.length}get activeCount(){return SharedCounter.getCount(this.#t)}get idle(){return!SharedCounter.getCount(this.#t)}get next(){return this.#r[0].options}setConcurrency(e){if(!Object.values(ConcurrencyOption).includes(e))throw new Error(`${e} is not a valid and safe ConcurrencyOption!`);SharedU32Integer.setValue(this.#e,(()=>generateConcurrencyValue(e)))}__enqueue(e){if(!(e instanceof PoolItem))throw new Error("The provided item cannot be enqueued.");e.options.priority?this.#r.unshift(e):this.#r.push(e),this.maxed||this.#n()}#n(){if(this.maxed||!this.#r.length)return;SharedCounter.incr(this.#t);const e=this.#r.shift(),{file:t,workerData:r,options:n,reffed:o,shareEnv:i}=e.options,u=new Worker(t,{...n,workerData:{...r,pool:{active:this.#t,concurrency:this.#e}},env:i?SHARE_ENV:void 0});o?u.ref():u.unref(),e.emit("created",u),u.once("exit",(()=>{SharedCounter.decr(this.#t),this.#n()}))}});
import { ConcurrencyOption } from '../constants/pool.js';
import { SharedU32Integer } from '../utilities/index.js';
import type { PoolItemOptions, PoolItemConfig } from '../types/pool.js';

@@ -6,3 +7,3 @@ export declare const cleanPoolConfig: <Options extends PoolItemConfig<import("../constants/workers.js").WorkerType>>({ file, workerData, priority, options, reffed, messengers, shareEnv, }: Options) => PoolItemOptions;

export declare const getDefaultPoolConcurrency: () => number;
export declare const getActiveCounter: () => import("../utilities/index.js").SharedUint32;
export declare const getConcurrencyCounter: () => import("../utilities/index.js").SharedUint32;
export declare const getActiveCounter: () => SharedU32Integer.SharedUint32;
export declare const getConcurrencyCounter: () => SharedU32Integer.SharedUint32;

@@ -1,1 +0,1 @@

import{cpus}from"os";import{concurrencyOptionMultipliers}from"../constants/pool.js";import{ConcurrencyOption}from"../constants/pool.js";import{isMainThread,workerData}from"worker_threads";import{createCounter,createSharedUint32,setValue}from"../utilities/index.js";export const cleanPoolConfig=({file:r,workerData:e,priority:o=!1,options:n={},reffed:t=!0,messengers:c=[],shareEnv:i=!0})=>{if(!r)throw new Error("Filename not provided.");return{file:r,workerData:{...e,messengerTransfers:c.map((r=>r.raw)),messengers:{}},priority:o,options:n,reffed:t,shareEnv:i}};export const generateConcurrencyValue=r=>Math.round(cpus().length*concurrencyOptionMultipliers[r]);export const getDefaultPoolConcurrency=()=>{return r=ConcurrencyOption.Default,Math.round(cpus().length*concurrencyOptionMultipliers[r]);var r};export const getActiveCounter=()=>{if(isMainThread)return createCounter();const{pool:r}=workerData;if(!r||!r.active)throw new Error("Pool corruption. Counter data not found.");return r.active};export const getConcurrencyCounter=()=>{if(isMainThread){const r=createSharedUint32();return setValue(r,(()=>{return r=ConcurrencyOption.Default,Math.round(cpus().length*concurrencyOptionMultipliers[r]);var r})),r}const{pool:r}=workerData;if(!r||!r.concurrency)throw new Error("Pool corruption. Concurrency data not found.");return r.concurrency};
import{cpus}from"os";import{concurrencyOptionMultipliers}from"../constants/pool.js";import{ConcurrencyOption}from"../constants/pool.js";import{isMainThread,workerData}from"worker_threads";import{SharedCounter,SharedU32Integer}from"../utilities/index.js";export const cleanPoolConfig=({file:r,workerData:e,priority:o=!1,options:n={},reffed:t=!0,messengers:c=[],shareEnv:i=!0})=>{if(!r)throw new Error("Filename not provided.");return{file:r,workerData:{...e,messengerTransfers:c.map((r=>r.raw)),messengers:{}},priority:o,options:n,reffed:t,shareEnv:i}};export const generateConcurrencyValue=r=>Math.round(cpus().length*concurrencyOptionMultipliers[r]);export const getDefaultPoolConcurrency=()=>{return r=ConcurrencyOption.Default,Math.round(cpus().length*concurrencyOptionMultipliers[r]);var r};export const getActiveCounter=()=>{if(isMainThread)return SharedCounter.create();const{pool:r}=workerData;if(!r||!r.active)throw new Error("Pool corruption. Counter data not found.");return r.active};export const getConcurrencyCounter=()=>{if(isMainThread){const r=SharedU32Integer.create();return SharedU32Integer.setValue(r,(()=>{return r=ConcurrencyOption.Default,Math.round(cpus().length*concurrencyOptionMultipliers[r]);var r})),r}const{pool:r}=workerData;if(!r||!r.concurrency)throw new Error("Pool corruption. Concurrency data not found.");return r.concurrency};

@@ -70,3 +70,3 @@ /// <reference types="node" resolution-mode="require"/>

*/
use(identifier: string): Service<Definitions>;
use(identifier: string): Service<Definitions> | undefined;
/**

@@ -73,0 +73,0 @@ * @returns The {@link Service} instance on the cluster that is currently the least active.

@@ -1,1 +0,1 @@

import{randomUUID as v4}from"crypto";import{pool}from"../pool/index.js";import{Service}from"../service/index.js";export class ServiceCluster{#e;#r=new Map;#i=!1;constructor(e,r){this.#i=!!r?.autoRenew,this.#e=e}get activeServices(){return this.#r.size}get currentServices(){return[...this.#r.values()]}get activeServiceCalls(){let e=0;return this.#r.forEach((({service:r})=>e+=r.activeCalls)),e}async launch(e,r={}){if(!e||1===e)return[await this.#s(r)];const i=[];for(let s=1;s<=e;s++)i.push(this.#s(r));return Promise.all(i)}async#s(e={}){if(this.#r.size>=pool.maxConcurrency)return;const r=await this.#e.launchService(e);return this.#t(r),r}addService(e){if(!(e instanceof Service))throw new Error("Can only provide Service instances to .addService().");this.#t(e)}#t(e){const r=v4();this.#r.set(r,{service:e,identifier:r}),e.once("terminated",(async e=>{this.#r.delete(r),this.#i&&0!==e&&await this.launch(1)}))}use(e){if("string"==typeof e&&this.#r.has(e))return this.#r.get(e);if(!this.#r.size)throw new Error("No running services found on this ServiceCluster!");const r=this.#r.values();if(1===this.#r.size)return r.next().value.service;const i=[...r];return i.reduce(((e,r)=>r.service.activeCalls<e.service.activeCalls?r:e),i[0]).service}notifyAll(e,r){this.#r.forEach((({service:i})=>{i.sendMessage(e,r)}))}closeAll(){const e=[];return this.#r.forEach((({service:r})=>e.push(r.close()))),Promise.all(e)}closeAllIdle(){const e=[];return this.#r.forEach((({service:r})=>{r.activeCalls<=0&&e.push(r.close())})),Promise.all(e)}}
import{randomUUID as v4}from"crypto";import{pool}from"../pool/index.js";import{Service}from"../service/index.js";export class ServiceCluster{#e;#r=new Map;#i=!1;constructor(e,r){this.#i=!!r?.autoRenew,this.#e=e}get activeServices(){return this.#r.size}get currentServices(){return[...this.#r.values()]}get activeServiceCalls(){let e=0;return this.#r.forEach((({service:r})=>e+=r.activeCalls)),e}async launch(e,r={}){if(!e||1===e)return[await this.#s(r)];const i=[];for(let s=1;s<=e;s++)i.push(this.#s(r));return Promise.all(i)}async#s(e={}){if(this.#r.size>=pool.maxConcurrency)return;const r=await this.#e.launchService(e);return this.#t(r),r}addService(e){if(!(e instanceof Service))throw new Error("Can only provide Service instances to .addService().");this.#t(e)}#t(e){const r=v4();this.#r.set(r,{service:e,identifier:r}),e.once("terminated",(async e=>{this.#r.delete(r),this.#i&&0!==e&&await this.launch(1)}))}use(e){if("string"==typeof e&&this.#r.has(e))return this.#r.get(e);if(!this.#r.size)throw new Error("No running services found on this ServiceCluster!");const r=this.#r.values();let i=r.next().value.service;if(1===this.#r.size||0===i.activeCalls)return i;for(const{service:e}of r){if(0===e.activeCalls)return e;i.activeCalls<e.activeCalls||(i=e)}return i}notifyAll(e,r){this.#r.forEach((({service:i})=>{i.sendMessage(e,r)}))}closeAll(){const e=[];return this.#r.forEach((({service:r})=>e.push(r.close()))),Promise.all(e)}closeAllIdle(){const e=[];return this.#r.forEach((({service:r})=>{r.activeCalls<=0&&e.push(r.close())})),Promise.all(e)}}

@@ -8,62 +8,7 @@ /// <reference types="node" resolution-mode="require"/>

import type { OnStreamCallback } from '../types/streams.js';
/**
* @param data The data to send to the main thread.
* @param transferList An optional array of {@link TransferListItem}s. See the
* [Node.js documentation](https://nodejs.org/api/worker_threads.html#workerpostmessagevalue-transferlist) for more information.
*
* @example
* ParentThread.sendMessage('foo');
* ParentThread.sendMessage({ hello: 'world' });
*/
declare function sendMessage<Data = any>(data: Data, transferList?: readonly TransferListItem[]): void;
/**
* Wait for specific messages coming from the main thread.
*
* @param callback A function returning a boolean that will be run each time a message is received the main thread.
* Once the condition is met and the function returns `true`, the promise will resolve with the data received.
*
* @returns A promise of the received data.
*
* @example
* const data = await ParentThread.waitForMessage<{ foo: string }>(({ foo }) => foo === 'bar');
*
* console.log(data);
*/
declare function waitForMessage<Data = any>(callback: (body: Data) => Awaitable<boolean>): Promise<Data>;
/**
* Listen for messages coming from the main thread.
*
* @param callback A function to run each time a message is received from the main thread.
*
* @returns A function that will remove the listener when called.
*
* @example
* ParentThread.onMessage<string>((data) => console.log(data, 'received!'));
*/
declare function onMessage<Data = any>(callback: (body: Data) => Awaitable<void>): RemoveListenerFunction;
/**
* Listen for {@link Messenger}s being sent to the worker from the main thread.
*
* @param callback A function to run each time a `Messenger` is received from the main thread.
*
* @returns A function that will remove the listener when called.
*
* @example
* ParentThread.onMessengerReceived((messenger) => console.log(messenger.ID));
*/
declare function onMessengerReceived(callback: (messenger: Messenger) => Awaitable<any>): () => import("worker_threads").MessagePort;
/**
* Receive data streams from the main thread.
*
* @param callback The callback to run once the stream has been initialized and is ready to consume.
*/
declare function onStream(callback: OnStreamCallback<Exclude<typeof parentPort, null>>): RemoveListenerFunction;
/**
* Create a {@link Writable} instance that can be piped into in order to stream data to
* the main thread. The main thread can listen for incoming streams with the
* `service.onStream()` listener.
*
* @param metaData Any specific data about the stream that should be accessible when
* using it.
*/
declare function createStream(metaData?: Record<string | number, any>): Promise<import("../streams/index.js").WritableToPort<import("worker_threads").MessagePort>>;

@@ -81,9 +26,64 @@ /**

export declare const ParentThread: Readonly<{
/**
* @param data The data to send to the main thread.
* @param transferList An optional array of {@link TransferListItem}s. See the
* [Node.js documentation](https://nodejs.org/api/worker_threads.html#workerpostmessagevalue-transferlist) for more information.
*
* @example
* ParentThread.sendMessage('foo');
* ParentThread.sendMessage({ hello: 'world' });
*/
sendMessage: typeof sendMessage;
/**
* Listen for messages coming from the main thread.
*
* @param callback A function to run each time a message is received from the main thread.
*
* @returns A function that will remove the listener when called.
*
* @example
* ParentThread.onMessage<string>((data) => console.log(data, 'received!'));
*/
onMessage: typeof onMessage;
/**
* Listen for {@link Messenger}s being sent to the worker from the main thread.
*
* @param callback A function to run each time a `Messenger` is received from the main thread.
*
* @returns A function that will remove the listener when called.
*
* @example
* ParentThread.onMessengerReceived((messenger) => console.log(messenger.ID));
*/
onMessengerReceived: typeof onMessengerReceived;
/**
* Wait for specific messages coming from the main thread.
*
* @param callback A function returning a boolean that will be run each time a message is received the main thread.
* Once the condition is met and the function returns `true`, the promise will resolve with the data received.
*
* @returns A promise of the received data.
*
* @example
* const data = await ParentThread.waitForMessage<{ foo: string }>(({ foo }) => foo === 'bar');
*
* console.log(data);
*/
waitForMessage: typeof waitForMessage;
/**
* Receive data streams from the main thread.
*
* @param callback The callback to run once the stream has been initialized and is ready to consume.
*/
onStream: typeof onStream;
/**
* Create a {@link Writable} instance that can be piped into in order to stream data to
* the main thread. The main thread can listen for incoming streams with the
* `service.onStream()` listener.
*
* @param metaData Any specific data about the stream that should be accessible when
* using it.
*/
createStream: typeof createStream;
}>;
export {};

@@ -32,6 +32,2 @@ /// <reference types="node" resolution-mode="require"/>

/**
* The thread ID of the underlying worker for the Service` instance.
*/
get threadID(): number;
/**
* Returns the raw underlying {@link Worker} instance being used by the service.

@@ -93,3 +89,3 @@ */

*/
onStream(callback: OnStreamCallback<typeof this['worker']>): RemoveListenerFunction;
onStream(callback: OnStreamCallback<(typeof this)['worker']>): RemoveListenerFunction;
/**

@@ -96,0 +92,0 @@ * Listen for messages coming from the service.

@@ -1,1 +0,1 @@

import{randomUUID as v4}from"crypto";import{TypedEmitter}from"tiny-typed-emitter";import{listenForStream,prepareWritableToPortStream}from"../streams/index.js";export class Service extends TypedEmitter{#e;#t=!1;#r=0;#s=new Map;constructor(e){super(),this.#e=e;const t=e=>{this.#s.forEach((({resolve:t,reject:r},s)=>{if(8===e.type){const{code:s}=e;return 0!==s?r(new Error(`Worker exited early with code ${s}!`)):t(void 0)}if(e.key===s)switch(e.type){case 3:t(e.data);break;case 4:r(e.data);break;default:return}}))};this.#e.on("message",t),this.#e.once("exit",(r=>{this.#t=!0,this.#s.clear(),this.emit("terminated",r),e.off("message",t)}))}get activeCalls(){return this.#r}get closed(){return this.#t}get threadID(){return this.#e.threadId}get worker(){return this.#e}#a(){if(this.#t)throw new Error("Attempting to execute operations on a service with an exited process!")}async call({name:e,params:t,transferList:r}){this.#a(),this.#r++;const s=v4(),a={type:1,name:e,params:t??[],key:s},i=new Promise(((e,t)=>{const r=this.#i({key:s,resolve:t=>{e(t),r()},reject:t})}));return this.#e.postMessage(a,r),i.finally((()=>this.#r--))}#i({key:e,...t}){return this.#s.set(e,t),()=>{this.#s.delete(e)}}setRef(e){if(e)return this.#e.ref();this.#e.unref()}async close(e){this.#t=!0,this.#e.emit("exit",e??0),this.#s.clear(),await this.#e.terminate()}sendMessage(e,t){this.#a();const r={type:0,data:e};this.#e.postMessage(r,t)}createStream(e){return this.#a(),prepareWritableToPortStream(this.#e,e??{})}onStream(e){return this.#a(),listenForStream(this.#e,e)}onMessage(e){this.#a();const t=async t=>{0===t.type&&await e(t.data)};return this.#e.on("message",t),()=>this.#e.off("message",t)}async waitForMessage(e){return this.#a(),new Promise((t=>{const r=async s=>{if(0!==s.type)return;const{data:a}=s;e(a)&&(t(a),this.#e.off("message",r))};this.#e.on("message",r)}))}sendMessenger(e){this.#a();const t=e.raw,r={type:3,data:t},s=new Promise((e=>{const r=s=>{5===s.type&&s.data===t.__messengerID&&(e(void 0),this.#e.off("message",r))};this.#e.on("message",r)}));return this.#e.postMessage(r),s}}
import{randomUUID as v4}from"crypto";import{TypedEmitter}from"tiny-typed-emitter";import{listenForStream,prepareWritableToPortStream}from"../streams/index.js";export class Service extends TypedEmitter{#e;#t=!1;#r=0;#s=new Map;constructor(e){super(),this.#e=e;const t=e=>{if(8===e.type)return this.#s.forEach((({resolve:t,reject:r})=>{const{code:s}=e;return 0!==s?r(new Error(`Worker exited early with code ${s}!`)):t(void 0)}));const t=e.key;if(!t)return;const{resolve:r,reject:s}=this.#s.get(t);switch(e.type){case 3:r(e.data);break;case 4:s(e.data);break;default:return}};this.#e.on("message",t),this.#e.once("exit",(r=>{this.#t=!0,this.#s.clear(),this.emit("terminated",r),e.off("message",t)}))}get activeCalls(){return this.#r}get closed(){return this.#t}get worker(){return this.#e}#a(){if(this.#t)throw new Error("Attempting to execute operations on a service with an exited process!")}async call({name:e,params:t,transferList:r}){this.#a(),this.#r++;const s=v4(),a={type:1,name:e,params:t??[],key:s},i=new Promise(((e,t)=>{const r=this.#i({key:s,resolve:t=>{e(t),r()},reject:t})}));return this.#e.postMessage(a,r),i.finally((()=>this.#r--))}#i({key:e,...t}){return this.#s.set(e,t),()=>{this.#s.delete(e)}}setRef(e){if(e)return this.#e.ref();this.#e.unref()}async close(e){this.#t=!0,this.#e.emit("exit",e??0),this.#s.clear(),await this.#e.terminate()}sendMessage(e,t){this.#a();const r={type:0,data:e};this.#e.postMessage(r,t)}createStream(e){return this.#a(),prepareWritableToPortStream(this.#e,e??{})}onStream(e){return this.#a(),listenForStream(this.#e,e)}onMessage(e){this.#a();const t=async t=>{0===t.type&&await e(t.data)};return this.#e.on("message",t),()=>this.#e.off("message",t)}async waitForMessage(e){return this.#a(),new Promise((t=>{const r=async s=>{if(0!==s.type)return;const{data:a}=s;e(a)&&(t(a),this.#e.off("message",r))};this.#e.on("message",r)}))}sendMessenger(e){this.#a();const t=e.raw,r={type:3,data:t},s=new Promise((e=>{const r=s=>{5===s.type&&s.data===t.__messengerID&&(e(void 0),this.#e.off("message",r))};this.#e.on("message",r)}));return this.#e.postMessage(r),s}}

@@ -1,1 +0,1 @@

export const createKey=({name:e,start:t,end:a})=>`${e}(${t},${a});`;export const parseKey=e=>{const[t,a]=e.match(/(?<=\()\d+|\d+(?=\))/g);return{name:e.match(/.*(?=\(\d+,\d+\);)/)[0],start:+t,end:+a}};export const createKeyRegex=(e,t="g")=>new RegExp(`${e}\\(\\d+,\\d+\\);`,t);export const matchKey=(e,t)=>e.match(createKeyRegex(t,""))?.[0];
export const createKey=({name:e,start:t,end:a})=>`${e}(${t},${a});`;export const parseKey=e=>{const[t,a]=e.match(/(?<=\()\d+|\d+(?=\))/g),[c]=e.match(/.*(?=\(\d+,\d+\);)/);return{name:c,start:+t,end:+a}};export const createKeyRegex=(e,t="g")=>new RegExp(`${e}\\(\\d+,\\d+\\);`,t);export const matchKey=(e,t)=>e.match(createKeyRegex(t,""))?.[0];

@@ -15,3 +15,3 @@ import { Bytes } from '../constants/shared_map.js';

*/
get uniqueKey(): string;
get uniqueKey(): `${string}-${string}-${string}-${string}-${string}`;
/**

@@ -18,0 +18,0 @@ * A single ID assigned to the entire group of SharedMap instances using the

@@ -1,1 +0,1 @@

import{randomUUID as v4}from"crypto";import{createSharedArrayBuffer,encodeValue,isSharedMapRawData}from"./utilities.js";import*as Keys from"./keys.js";import{Bytes,NULL_ENCODED,ENCODER,DECODER,NULL}from"../constants/shared_map.js";import{createMutex,lockMutex,unlockMutex}from"../utilities/index.js";export class SharedMap{#e;#t;#s;#r=v4();#n;get uniqueKey(){return this.#r}get ID(){return this.#n}static option=Bytes;option=Bytes;get raw(){return Object.freeze({__keys:this.#e,__values:this.#t,__identifier:this.#n,__mutex:this.#s})}constructor(e,{bytes:t,multiplier:s=10}={}){if("object"!=typeof e||Array.isArray(e))throw new Error("Can only provide objects to SharedMap.");if(isSharedMapRawData(e))return this.#e=e.__keys,this.#t=e.__values,this.#n=e.__identifier,void(this.#s=e.__mutex);const r=Object.entries(e),{preppedKeys:n,preppedValues:a,totalLength:i}=r.reduce(((e,[t,s])=>{let r=null==s?NULL_ENCODED:encodeValue(ENCODER,s);r.byteLength<=0&&(r=NULL_ENCODED);const n=r.byteLength-1+e.totalLength,a=Keys.createKey({name:t,start:e.totalLength,end:n});return e.preppedKeys.push(a),e.preppedValues.push(r),e.totalLength+=r.byteLength,e}),{preppedKeys:[],preppedValues:[],totalLength:0}),o=ENCODER.encode(n.join(""));if(this.#e=createSharedArrayBuffer(o.byteLength*s||Bytes.kilobyte),this.#e.set(o),t&&t<i)throw new Error(`${t} isn't enough bytes to store all values. Total byteLength of values is ${i}.`);this.#t=createSharedArrayBuffer(t||i*s||3*Bytes.kilobyte),a.reduce(((e,t)=>(this.#t.set(t,e),e+=t.byteLength)),0),this.#n=v4(),this.#s=createMutex()}async#a(e){await lockMutex(this.#s);const t=await e();return unlockMutex(this.#s),t}async*entries(){const e=(await this.#a((()=>DECODER.decode(this.#e)))).match(/[^;]+\(\d+,\d+\);/g)??[];for(const t of e){const e=Keys.parseKey(t);yield[e.name,this.#i(e)]}}#o(e){const t=DECODER.decode(this.#e),s=Keys.matchKey(t,e);return s||null}#i({start:e,end:t}){if(void 0===e||void 0===t)throw new Error("Failed to parse key");const s=this.#t.subarray(e,t+1);if(this.#y(s))return null;return DECODER.decode(this.#t.subarray(e,t+1))}#h(e){const t=this.#o(e);return t?this.#i(Keys.parseKey(t)):null}#y(e){if(e.length!==NULL_ENCODED.length)return!1;for(let t=0;t<NULL_ENCODED.length;t++)if(NULL_ENCODED[t]!==e[t])return!1;return!0}get(e){return this.#a((()=>this.#h(e)))}#u(e,t){const s=DECODER.decode(this.#e).replace(/\x00/g,""),r=s.match(/\d+(?=\);($|\x00))/g)?.[0];let n=encodeValue(ENCODER,t);if(n.byteLength<=0&&(n=NULL_ENCODED),!r||!Keys.createKeyRegex(e).test(s)){const t=r?+r+1:0,a=t+n.byteLength-1,i=Keys.createKey({name:e,start:t,end:a});return this.#e.set(ENCODER.encode(s.concat(i))),this.#t.set(n,t),n}const a=Keys.matchKey(s,e);if(!a)throw new Error("Failed to parse keys.");const{start:i,end:o}=Keys.parseKey(a),y=o-i+1;if(y===n.byteLength)return this.#t.set(n,i),n;const h=i+n.byteLength;if(o!==+r){const e=this.#t.subarray(o+1,+r+1);this.#t.set(e,h)}this.#t.set(n,i);const u=s.split(/(?<=;)/g),l=u.findIndex((t=>Keys.createKeyRegex(e).test(t))),c=Keys.createKey({name:e,start:i,end:h-1});u.splice(l,1,c);for(let e=l+1;e<u.length;e++){const{name:t,start:s,end:r}=Keys.parseKey(u[e]),a=r-s+1,i=s-y+n.byteLength,o=i+a-1;u.splice(e,1,Keys.createKey({name:t,start:i,end:o}))}let d=u.join("");return d.length<s.length&&(d+="\0".repeat(s.length-d.length)),this.#e.set(ENCODER.encode(d)),n}set(e,t){return this.#a((async()=>{const s="function"!=typeof t?t:await t(this.#h(e));this.#u(e,s)}))}async delete(e){await this.#a((()=>{if(this.#o(e))return this.#u(e,NULL)}))}}
import{randomUUID as v4}from"crypto";import{createSharedArrayBuffer,encodeValue,isSharedMapRawData}from"./utilities.js";import*as Keys from"./keys.js";import{Bytes,NULL_ENCODED,ENCODER,DECODER,NULL}from"../constants/shared_map.js";import{createMutex,lockMutex,unlockMutex}from"../utilities/index.js";export class SharedMap{#e;#t;#s;#r=v4();#a;get uniqueKey(){return this.#r}get ID(){return this.#a}static option=Bytes;option=Bytes;get raw(){return Object.freeze({__keys:this.#e,__values:this.#t,__identifier:this.#a,__mutex:this.#s})}constructor(e,{bytes:t,multiplier:s=10}={}){if("object"!=typeof e||Array.isArray(e))throw new Error("Can only provide objects to SharedMap.");if(isSharedMapRawData(e))return this.#e=e.__keys,this.#t=e.__values,this.#a=e.__identifier,void(this.#s=e.__mutex);const r=Object.entries(e),{preppedKeys:a,preppedValues:n,totalLength:i}=r.reduce(((e,[t,s])=>{let r=null==s?NULL_ENCODED:encodeValue(ENCODER,s);r.byteLength<=0&&(r=NULL_ENCODED);const a=r.byteLength-1+e.totalLength,n=Keys.createKey({name:t,start:e.totalLength,end:a});return e.preppedKeys.push(n),e.preppedValues.push(r),e.totalLength+=r.byteLength,e}),{preppedKeys:[],preppedValues:[],totalLength:0}),o=ENCODER.encode(a.join(""));if(this.#e=createSharedArrayBuffer(o.byteLength*s||Bytes.kilobyte),this.#e.set(o),t&&t<i)throw new Error(`${t} isn't enough bytes to store all values. Total byteLength of values is ${i}.`);this.#t=createSharedArrayBuffer(t||i*s||3*Bytes.kilobyte),n.reduce(((e,t)=>(this.#t.set(t,e),e+=t.byteLength)),0),this.#a=v4(),this.#s=createMutex()}async#n(e){await lockMutex(this.#s);const t=await e();return unlockMutex(this.#s),t}async*entries(){const e=(await this.#n((()=>DECODER.decode(this.#e)))).match(/[^;]+\(\d+,\d+\);/g)??[];for(const t of e){const e=Keys.parseKey(t);yield[e.name,this.#i(e)]}}#o(e){const t=DECODER.decode(this.#e),s=Keys.matchKey(t,e);return s||null}#i({start:e,end:t}){if(void 0===e||void 0===t)throw new Error("Failed to parse key");const s=this.#t.subarray(e,t+1);if(this.#y(s))return null;return DECODER.decode(this.#t.subarray(e,t+1))}#h(e){const t=this.#o(e);return t?this.#i(Keys.parseKey(t)):null}#y(e){return e.length===NULL_ENCODED.length&&!NULL_ENCODED.some(((t,s)=>t!==e[s]))}get(e){return this.#n((()=>this.#h(e)))}#u(e,t){const s=DECODER.decode(this.#e).replace(/\x00/g,""),r=s.match(/\d+(?=\);($|\x00))/g)?.[0];let a=encodeValue(ENCODER,t);if(a.byteLength<=0&&(a=NULL_ENCODED),!r||!Keys.createKeyRegex(e).test(s)){const t=r?+r+1:0,n=t+a.byteLength-1,i=Keys.createKey({name:e,start:t,end:n});return this.#e.set(ENCODER.encode(s.concat(i))),this.#t.set(a,t),a}const n=Keys.matchKey(s,e);if(!n)throw new Error("Failed to parse keys.");const{start:i,end:o}=Keys.parseKey(n),y=o-i+1;if(y===a.byteLength)return this.#t.set(a,i),a;const h=i+a.byteLength;if(o!==+r){const e=this.#t.subarray(o+1,+r+1);this.#t.set(e,h)}this.#t.set(a,i);const u=s.split(/(?<=;)/g),l=u.findIndex((t=>Keys.createKeyRegex(e).test(t))),c=Keys.createKey({name:e,start:i,end:h-1});u.splice(l,1,c);for(let e=l+1;e<u.length;e++){const{name:t,start:s,end:r}=Keys.parseKey(u[e]),n=r-s+1,i=s-y+a.byteLength,o=i+n-1;u.splice(e,1,Keys.createKey({name:t,start:i,end:o}))}let d=u.join("");return d.length<s.length&&(d+="\0".repeat(s.length-d.length)),this.#e.set(ENCODER.encode(d)),a}set(e,t){return this.#n((async()=>{const s="function"!=typeof t?t:await t(this.#h(e));this.#u(e,s)}))}async delete(e){await this.#n((()=>{if(this.#o(e))return this.#u(e,NULL)}))}}

@@ -1,1 +0,1 @@

import{ReadableFromPort}from"./readable_from_port.js";export function listenForStream(e,t,a=0){const r=async r=>{if("stream-start"!==r.type)return;const o=()=>{const t=new ReadableFromPort(r.id,e,r.meta??{}),a={type:"stream-ready-to-consume",id:r.id};return e.postMessage(a),t};0!==a?1===a&&await t({metaData:r.meta,accept:()=>o()}):await t(o())};return e.on("message",r),()=>{e.off("message",r)}}
import{ReadableFromPort}from"./readable_from_port.js";export function listenForStream(e,t,a=0){const r=async r=>{if("stream-start"!==r.type)return;const o=()=>{const t=new ReadableFromPort(r.id,e,r.meta??{}),a={type:"stream-ready-to-consume",id:r.id};return e.postMessage(a),t};switch(a){default:return;case 0:return void await t(o());case 1:return void await t({metaData:r.meta,accept:()=>o()})}};return e.on("message",r),()=>{e.off("message",r)}}

@@ -6,2 +6,2 @@ import { WritableToPort } from './writable_to_port.js';

*/
export declare function prepareWritableToPortStream<Target extends Messagable>(target: Target, metaData: Record<any, any>, timeoutSecs?: number): Promise<WritableToPort<Target>>;
export declare function prepareWritableToPortStream<Target extends Messagable>(target: Target, metaData: Record<any, any>, timeoutMs?: number): Promise<WritableToPort<Target>>;

@@ -1,1 +0,1 @@

import{randomUUID as v4}from"crypto";import{WritableToPort}from"./writable_to_port.js";export function prepareWritableToPortStream(e,t,r=15e3){const o=v4();return new Promise(((a,s)=>{const i=setTimeout(s.bind(void 0,new Error('Stream creation failed after 15 seconds. Receiver failed to notify of its ready status. If you are using the Messenger API, make sure you are using the ".onStream()" listener on one of the receiving ends and that at least one receiver is accepting the stream with the "accept()" function.')),r),n=r=>{"stream-ready-to-consume"===r.type&&r.id===o&&(clearTimeout(i),a(new WritableToPort(e,o,t)),e.off("message",n))};e.on("message",n);const m={type:"stream-start",id:o,meta:t};e.postMessage(m)}))}
import{randomUUID as v4}from"crypto";import{WritableToPort}from"./writable_to_port.js";export function prepareWritableToPortStream(e,t,r=15e3){const o=v4();return new Promise(((a,s)=>{const i=setTimeout(s.bind(void 0,new Error(`Stream creation failed after ${r/1e3}s. Receiver failed to notify of its ready status. If you are using the Messenger API, make sure you are using the ".onStream()" listener on one of the receiving ends and that at least one receiver is accepting the stream with the "accept()" function.`)),r),n=r=>{"stream-ready-to-consume"===r.type&&r.id===o&&(clearTimeout(i),a(new WritableToPort(e,o,t)),e.off("message",n))};e.on("message",n);const m={type:"stream-start",id:o,meta:t};e.postMessage(m)}))}

@@ -1,15 +0,3 @@

/// <reference types="node" resolution-mode="require"/>
import type { Awaitable, Except } from './utilities.js';
type AcceptableValue = string | number | boolean | null | undefined | void | SharedArrayBuffer | ArrayBuffer | Buffer | Int8Array | Int16Array | Int32Array | Uint8Array | Uint16Array | Uint32Array;
interface AcceptableObject {
[key: string | number]: Acceptable;
}
type AcceptableArray = Acceptable[];
/**
* A union of all the data types that can be sent across threads.
*
* **Note:** To be used in the future.
*/
export type Acceptable = AcceptableValue | AcceptableObject | AcceptableArray;
/**
* A function that can be used in the `define` function when defining

@@ -80,2 +68,1 @@ * a collection of tasks.

};
export {};
import type { SharedUint32 } from './shared_uint32.js';
export type Counter = SharedUint32;
export declare const createCounter: () => Counter;
export declare const create: () => Counter;
export declare const getCount: (counter: Counter) => number;
export declare const incr: (counter: Counter) => void;
export declare const decr: (counter: Counter) => void;

@@ -1,1 +0,1 @@

import{createSharedUint32,getValue,setValue}from"./shared_uint32.js";export const createCounter=()=>createSharedUint32();export const getCount=e=>getValue(e);export const incr=e=>{setValue(e,(e=>e+1))};export const decr=e=>{setValue(e,(e=>e-1))};
import{create as createSharedUint32,getValue,setValue}from"./shared_uint32.js";export const create=()=>createSharedUint32();export const getCount=e=>getValue(e);export const incr=e=>{setValue(e,(e=>e+1))};export const decr=e=>{setValue(e,(e=>e-1))};
export { assertIsNotMainThread } from './assertions.js';
export { createMutex, lockMutexSync, lockMutex, unlockMutex } from './mutex.js';
export { createSharedUint32, getValue, setValue } from './shared_uint32.js';
export { createCounter, getCount, incr, decr } from './counter.js';
export * as SharedU32Integer from './shared_uint32.js';
export * as SharedCounter from './counter.js';
export { callsites } from './callsites.js';

@@ -6,0 +6,0 @@ export type { Mutex } from './mutex.js';

@@ -1,1 +0,1 @@

export{assertIsNotMainThread}from"./assertions.js";export{createMutex,lockMutexSync,lockMutex,unlockMutex}from"./mutex.js";export{createSharedUint32,getValue,setValue}from"./shared_uint32.js";export{createCounter,getCount,incr,decr}from"./counter.js";export{callsites}from"./callsites.js";
export{assertIsNotMainThread}from"./assertions.js";export{createMutex,lockMutexSync,lockMutex,unlockMutex}from"./mutex.js";export*as SharedU32Integer from"./shared_uint32.js";export*as SharedCounter from"./counter.js";export{callsites}from"./callsites.js";

@@ -7,5 +7,5 @@ import type { Mutex } from './mutex.js';

};
export declare const createSharedUint32: () => SharedUint32;
export declare const create: () => SharedUint32;
export declare const getValue: (data: SharedUint32) => number;
export declare const setValue: (data: SharedUint32, callback: (int: number) => number) => void;
export {};

@@ -1,1 +0,1 @@

import{createMutex,lockMutexSync,unlockMutex}from"./mutex.js";export const createSharedUint32=()=>({lock:createMutex(),value:new Uint32Array(new SharedArrayBuffer(4))});export const getValue=e=>e.value[0];export const setValue=(e,t)=>{lockMutexSync(e.lock),e.value[0]=t(getValue(e)),unlockMutex(e.lock)};
import{createMutex,lockMutexSync,unlockMutex}from"./mutex.js";export const create=()=>({lock:createMutex(),value:new Uint32Array(new SharedArrayBuffer(4))});export const getValue=e=>e.value[0];export const setValue=(e,t)=>{lockMutexSync(e.lock),e.value[0]=t(getValue(e)),unlockMutex(e.lock)};

@@ -1,1 +0,1 @@

{"name":"nanolith","version":"0.4.5","type":"module","author":"Matt Stephens","description":"Multi-threading in no time with seamless TypeScript support.","license":"MIT","repository":{"type":"git","url":"https://github.com/mstephen19/nanolith"},"homepage":"https://github.com/mstephen19/nanolith#readme","bugs":{"url":"https://github.com/mstephen19/nanolith/issues"},"main":"./build/index.js","exports":"./build/index.js","dependencies":{"tiny-typed-emitter":"^2.1.0"},"keywords":["nanoservices","nanoservice","microservice","microservices","thread","threads","threadz","multithreading","thread pool","child process","workers","worker","worker threads","piscina","pool","threading","concurrent","concurrency","parallel","performance","scalability","async","tasks"]}
{"name":"nanolith","version":"0.4.6","type":"module","author":"Matt Stephens","description":"Multi-threading in no time with seamless TypeScript support.","license":"MIT","repository":{"type":"git","url":"https://github.com/mstephen19/nanolith"},"homepage":"https://github.com/mstephen19/nanolith#readme","bugs":{"url":"https://github.com/mstephen19/nanolith/issues"},"main":"./build/index.js","exports":"./build/index.js","dependencies":{"tiny-typed-emitter":"^2.1.0"},"keywords":["nanoservices","nanoservice","microservice","microservices","thread","threads","threadz","multithreading","thread pool","child process","workers","worker","worker threads","piscina","pool","threading","concurrent","concurrency","parallel","performance","scalability","async","tasks"]}

@@ -212,3 +212,2 @@ # Nanolith

| `closed` | **Property** | Whether or not the underlying `Worker` instance has exited its process. |
| `threadID` | **Property** | The thread ID of the underlying `Worker`. |
| `worker` | **Property** | The raw `Worker` instance being used by the service. |

@@ -215,0 +214,0 @@ | `call()` | **Method** | Call a task to be run within the service worker. Usage is similar to [running a task normally](#-running-a-task) |

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc