Comparing version 2.4.1 to 2.5.0
@@ -1,4 +0,3 @@ | ||
import Worker from './worker'; | ||
import type { FN, Methods, Options, Task } from './types'; | ||
declare class WorkTank<MethodName extends string, MethodFunction extends FN> { | ||
import type { Methods, MethodsNames, MethodsProxied, MethodArguments, MethodReturn, Options } from './types'; | ||
declare class WorkTank<T extends Methods> { | ||
private terminated; | ||
@@ -15,9 +14,10 @@ private terminateTimeout; | ||
private workersReady; | ||
constructor(options: Options<MethodName, MethodFunction>); | ||
_autoterminate(): void; | ||
_getMethods(methods: Methods<MethodName, MethodFunction> | URL | string): string; | ||
_getTaskReady(): Task<MethodName, MethodFunction> | undefined; | ||
_getWorkerName(): string; | ||
_getWorkerReady(): Worker<MethodName, MethodFunction> | undefined; | ||
exec(method: MethodName, args: Parameters<Methods<MethodName, MethodFunction>[MethodName]>): Promise<Awaited<ReturnType<Methods<MethodName, MethodFunction>[MethodName]>>>; | ||
constructor(options: Options<T>); | ||
private _autoterminate; | ||
private _getMethods; | ||
private _getTaskReady; | ||
private _getWorkerName; | ||
private _getWorkerReady; | ||
exec<U extends MethodsNames<T>>(method: U, args: MethodArguments<T, U>): Promise<Awaited<MethodReturn<T, U>>>; | ||
proxy(): MethodsProxied<T>; | ||
terminate(): void; | ||
@@ -24,0 +24,0 @@ tick(): void; |
@@ -86,2 +86,13 @@ /* IMPORT */ | ||
} | ||
proxy() { | ||
return new Proxy({}, { | ||
get: (_, method) => { | ||
if (typeof method !== 'string') | ||
throw new Error('Unsupported method name'); | ||
return (...args) => { | ||
return this.exec(method, args); | ||
}; | ||
} | ||
}); | ||
} | ||
terminate() { | ||
@@ -88,0 +99,0 @@ this.terminated = true; |
@@ -27,4 +27,13 @@ type FN = (...args: any[]) => any; | ||
type Message = MessageExec | MessageInit | MessageReady | MessageResult; | ||
type Methods<MethodName extends string = string, MethodFunction extends FN = FN> = Record<MethodName, MethodFunction>; | ||
type Options<MethodName extends string = string, MethodFunction extends FN = FN> = { | ||
type Methods = Record<string, FN>; | ||
type MethodsNames<T extends Methods> = keyof T; | ||
type MethodsFunctions<T extends Methods> = T[keyof T]; | ||
type MethodsProxied<T extends Methods> = { | ||
[K in keyof T]: (...args: Parameters<T[K]>) => Promise<Awaited<ReturnType<T[K]>>>; | ||
}; | ||
type MethodFunction<T extends Methods, U extends MethodsNames<T>> = T[U]; | ||
type MethodArguments<T extends Methods, U extends MethodsNames<T>> = Parameters<MethodFunction<T, U>>; | ||
type MethodReturn<T extends Methods, U extends MethodsNames<T>> = ReturnType<MethodFunction<T, U>>; | ||
type MethodProxied<T extends FN> = (...args: Parameters<T>) => Promise<Awaited<ReturnType<T>>>; | ||
type Options<T extends Methods> = { | ||
name?: string; | ||
@@ -34,9 +43,9 @@ size?: number; | ||
autoterminate?: number; | ||
methods: Methods<MethodName, MethodFunction> | URL | string; | ||
methods: T | URL | string; | ||
}; | ||
type Task<MethodName extends string = string, MethodFunction extends FN = FN> = { | ||
method: MethodName; | ||
args: Parameters<Methods<MethodName, MethodFunction>[MethodName]>; | ||
promise: Promise<ReturnType<Methods<MethodName, MethodFunction>[MethodName]>>; | ||
resolve: (result: ReturnType<Methods<MethodName, MethodFunction>[MethodName]>) => void; | ||
type Task<T extends Methods, U extends MethodsNames<T> = MethodsNames<T>> = { | ||
method: U; | ||
args: MethodArguments<T, U>; | ||
promise: Promise<Awaited<MethodReturn<T, U>>>; | ||
resolve: (result: MethodReturn<T, U>) => void; | ||
reject: (error: Error) => void; | ||
@@ -46,2 +55,3 @@ }; | ||
export type { MessageExec, MessageInit, MessageReady, MessageResult, Message }; | ||
export type { Methods, Options, Task }; | ||
export type { Methods, MethodsNames, MethodsFunctions, MethodsProxied, MethodFunction, MethodArguments, MethodReturn, MethodProxied }; | ||
export type { Options, Task }; |
@@ -1,3 +0,3 @@ | ||
import type { FN, Message, MessageReady, MessageResult, Task } from '../types'; | ||
declare class Worker<MethodName extends string, MethodFunction extends FN> { | ||
import type { Message, MessageReady, MessageResult, Methods, Task } from '../types'; | ||
declare class Worker<T extends Methods> { | ||
busy: boolean; | ||
@@ -15,3 +15,3 @@ loaded: boolean; | ||
init(): void; | ||
exec(task: Task<MethodName, MethodFunction>): void; | ||
exec(task: Task<T>): void; | ||
terminate(): void; | ||
@@ -18,0 +18,0 @@ tick(): void; |
@@ -62,2 +62,4 @@ /* IMPORT */ | ||
const { method, args } = this.task; | ||
if (typeof method !== 'string') | ||
throw new Error('Unsupported method name'); | ||
this.busy = true; | ||
@@ -64,0 +66,0 @@ this.worker.send({ type: 'exec', method, args }); |
@@ -5,3 +5,3 @@ { | ||
"description": "A simple isomorphic library for executing functions inside WebWorkers or Node Threads pools.", | ||
"version": "2.4.1", | ||
"version": "2.5.0", | ||
"type": "module", | ||
@@ -8,0 +8,0 @@ "main": "dist/index.js", |
@@ -6,7 +6,7 @@ | ||
import Worker from '~/worker'; | ||
import type {FN, Methods, Options, Task} from '~/types'; | ||
import type {Methods, MethodsNames, MethodsProxied, MethodArguments, MethodFunction, MethodReturn, MethodProxied, Options, Task} from '~/types'; | ||
/* MAIN */ | ||
class WorkTank <MethodName extends string, MethodFunction extends FN> { | ||
class WorkTank<T extends Methods> { | ||
@@ -22,10 +22,10 @@ /* VARIABLES */ | ||
private methods: string; | ||
private tasksBusy: Set<Task<MethodName, MethodFunction>>; | ||
private tasksReady: Set<Task<MethodName, MethodFunction>>; | ||
private workersBusy: Set<Worker<MethodName, MethodFunction>>; | ||
private workersReady: Set<Worker<MethodName, MethodFunction>>; | ||
private tasksBusy: Set<Task<T>>; | ||
private tasksReady: Set<Task<T>>; | ||
private workersBusy: Set<Worker<T>>; | ||
private workersReady: Set<Worker<T>>; | ||
/* CONSTRUCTOR */ | ||
constructor ( options: Options<MethodName, MethodFunction> ) { | ||
constructor ( options: Options<T> ) { | ||
@@ -47,3 +47,3 @@ this.terminated = true; | ||
_autoterminate (): void { | ||
private _autoterminate (): void { | ||
@@ -74,3 +74,3 @@ if ( this.terminateTimeoutId ) return; | ||
_getMethods ( methods: Methods<MethodName, MethodFunction> | URL | string ): string { | ||
private _getMethods ( methods: T | URL | string ): string { | ||
@@ -99,3 +99,3 @@ if ( typeof methods === 'string' ) { // Already serialized methods, or URL to import, useful for complex and/or bundled workers | ||
const names = Object.keys ( methods ); | ||
const values = Object.values<MethodFunction> ( methods ); | ||
const values = Object.values ( methods ); | ||
const serialized = names.map ( ( name, index ) => `WorkTankWorkerBackend.register ( '${name}', ${values[index].toString ()} );` ).join ( '\n' ); | ||
@@ -109,3 +109,3 @@ | ||
_getTaskReady (): Task<MethodName, MethodFunction> | undefined { | ||
private _getTaskReady (): Task<T> | undefined { | ||
@@ -116,3 +116,3 @@ for ( const task of this.tasksReady ) return task; | ||
_getWorkerName (): string { | ||
private _getWorkerName (): string { | ||
@@ -127,3 +127,3 @@ if ( this.size < 2 ) return this.name; | ||
_getWorkerReady (): Worker<MethodName, MethodFunction> | undefined { | ||
private _getWorkerReady (): Worker<T> | undefined { | ||
@@ -136,3 +136,3 @@ for ( const worker of this.workersReady ) return worker; | ||
const worker = new Worker<MethodName, MethodFunction> ( this.methods, name ); | ||
const worker = new Worker<T> ( this.methods, name ); | ||
@@ -147,5 +147,5 @@ this.workersReady.add ( worker ); | ||
exec ( method: MethodName, args: Parameters<Methods<MethodName, MethodFunction>[MethodName]> ): Promise<Awaited<ReturnType<Methods<MethodName, MethodFunction>[MethodName]>>> { | ||
exec <U extends MethodsNames<T>> ( method: U, args: MethodArguments<T, U> ): Promise<Awaited<MethodReturn<T, U>>> { | ||
const {promise, resolve, reject} = makeNakedPromise<any> (); | ||
const {promise, resolve, reject} = makeNakedPromise<Awaited<MethodReturn<T, U>>> (); | ||
const task = { method, args, promise, resolve, reject }; | ||
@@ -164,2 +164,21 @@ | ||
proxy (): MethodsProxied<T> { | ||
return new Proxy ( {} as MethodsProxied<T>, { | ||
get: <U extends MethodsNames<T>> ( _: unknown, method: U | symbol | number ): MethodProxied<MethodFunction<T, U>> => { | ||
if ( typeof method !== 'string' ) throw new Error ( 'Unsupported method name' ); | ||
return ( ...args: MethodArguments<T, U> ): Promise<Awaited<MethodReturn<T, U>>> => { | ||
return this.exec ( method, args ); | ||
}; | ||
} | ||
}); | ||
} | ||
terminate (): void { | ||
@@ -166,0 +185,0 @@ |
@@ -40,7 +40,23 @@ | ||
/* METHODS */ | ||
type Methods = Record<string, FN>; | ||
type MethodsNames<T extends Methods> = keyof T; | ||
type MethodsFunctions<T extends Methods> = T[keyof T]; | ||
type MethodsProxied<T extends Methods> = { [K in keyof T]: (...args: Parameters<T[K]>) => Promise<Awaited<ReturnType<T[K]>>> }; | ||
type MethodFunction<T extends Methods, U extends MethodsNames<T>> = T[U]; | ||
type MethodArguments<T extends Methods, U extends MethodsNames<T>> = Parameters<MethodFunction<T, U>>; | ||
type MethodReturn<T extends Methods, U extends MethodsNames<T>> = ReturnType<MethodFunction<T, U>>; | ||
type MethodProxied<T extends FN> = (...args: Parameters<T>) => Promise<Awaited<ReturnType<T>>>; | ||
/* POOL */ | ||
type Methods <MethodName extends string = string, MethodFunction extends FN = FN> = Record<MethodName, MethodFunction>; | ||
type Options <MethodName extends string = string, MethodFunction extends FN = FN> = { | ||
type Options<T extends Methods> = { | ||
name?: string, | ||
@@ -50,10 +66,10 @@ size?: number, | ||
autoterminate?: number, | ||
methods: Methods<MethodName, MethodFunction> | URL | string | ||
methods: T | URL | string | ||
}; | ||
type Task <MethodName extends string = string, MethodFunction extends FN = FN> = { | ||
method: MethodName, | ||
args: Parameters<Methods<MethodName, MethodFunction>[MethodName]>, | ||
promise: Promise<ReturnType<Methods<MethodName, MethodFunction>[MethodName]>>, | ||
resolve: ( result: ReturnType<Methods<MethodName, MethodFunction>[MethodName]> ) => void, | ||
type Task<T extends Methods, U extends MethodsNames<T> = MethodsNames<T>> = { | ||
method: U, | ||
args: MethodArguments<T, U>, | ||
promise: Promise<Awaited<MethodReturn<T, U>>>, | ||
resolve: ( result: MethodReturn<T, U> ) => void, | ||
reject: ( error: Error ) => void | ||
@@ -66,2 +82,3 @@ }; | ||
export type {MessageExec, MessageInit, MessageReady, MessageResult, Message}; | ||
export type {Methods, Options, Task}; | ||
export type {Methods, MethodsNames, MethodsFunctions, MethodsProxied, MethodFunction, MethodArguments, MethodReturn, MethodProxied}; | ||
export type {Options, Task}; |
@@ -5,7 +5,7 @@ | ||
import WorkerFrontend from '~/worker/frontend'; | ||
import type {FN, Message, MessageReady, MessageResult, Task} from '~/types'; | ||
import type {Message, MessageReady, MessageResult, Methods, Task} from '~/types'; | ||
/* MAIN */ | ||
class Worker <MethodName extends string, MethodFunction extends FN> { | ||
class Worker<T extends Methods> { | ||
@@ -20,3 +20,3 @@ /* VARIABLES */ | ||
private methods: string; | ||
private task?: Task<MethodName, MethodFunction>; | ||
private task?: Task<T>; | ||
private worker: WorkerFrontend; | ||
@@ -88,3 +88,3 @@ | ||
exec ( task: Task<MethodName, MethodFunction> ): void { | ||
exec ( task: Task<T> ): void { | ||
@@ -121,2 +121,4 @@ if ( this.terminated || this.task || this.busy ) throw new Error ( `WorkTank Worker (${this.name}): already busy or terminated` ); | ||
if ( typeof method !== 'string' ) throw new Error ( 'Unsupported method name' ); | ||
this.busy = true; | ||
@@ -123,0 +125,0 @@ |
@@ -61,2 +61,31 @@ | ||
it ( 'can return a proxy to the pooled methods', async t => { | ||
const pool = new WorkTank ({ | ||
name: 'example', | ||
methods: { | ||
sep: async () => { | ||
const {default: path} = await import ( 'node:path' ); | ||
return path.sep; | ||
}, | ||
sum: ( a, b ) => { | ||
return a + b; | ||
} | ||
} | ||
}); | ||
const proxy = pool.proxy (); | ||
const sumResult = await proxy.sum ( 10, 20 ); | ||
t.is ( sumResult, 30 ); | ||
const sepResult = await proxy.sep (); | ||
t.is ( sepResult, path.sep ); | ||
pool.terminate (); | ||
}); | ||
}); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
36417
830