Skip to content

Commit a343e5e

Browse files
committed
feat: make piscina entrypoint easier for typescript
1 parent c43b078 commit a343e5e

File tree

6 files changed

+72
-2
lines changed

6 files changed

+72
-2
lines changed

docs/docs/getting-started/typescript.mdx

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,3 +112,32 @@ const piscina = new Piscina({
112112
})();
113113
```
114114

115+
## Using generics
116+
117+
You can use generics to the types for the worker function:
118+
119+
```typescript title='worker.ts'
120+
121+
interface Inputs {
122+
a: number;
123+
b: number;
124+
}
125+
126+
export default function addNumbers({ a, b }: Inputs): number {
127+
return a + b;
128+
}
129+
```
130+
131+
```typescript title='main.ts'
132+
133+
import Piscina from 'piscina';
134+
135+
const piscina = new Piscina<typeof import("./worker.ts").default>({
136+
filename: new URL("./worker.ts", import.meta.url).href,
137+
});
138+
139+
(async () => {
140+
const result = await piscina.run({ a: 2, b: 3 });
141+
console.log('Result:', result);
142+
})();
143+
```

package-lock.json

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
"c8": "^10.1.2",
5252
"concat-stream": "^2.0.0",
5353
"eslint": "^9.16.0",
54+
"expect-type": "^1.2.1",
5455
"gen-esm-wrapper": "^1.1.1",
5556
"neostandard": "^0.12.0",
5657
"tap": "^16.3.7",

src/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -720,7 +720,7 @@ class ThreadPool {
720720
}
721721
}
722722

723-
export default class Piscina<T = any, R = any> extends EventEmitterAsyncResource {
723+
export default class Piscina<F extends (payload: any) => any = (payload: any) => any> extends EventEmitterAsyncResource {
724724
#pool : ThreadPool;
725725
#histogram: PiscinaHistogram | null = null;
726726

@@ -793,7 +793,7 @@ export default class Piscina<T = any, R = any> extends EventEmitterAsyncResource
793793
this.#pool = new ThreadPool(this, options);
794794
}
795795

796-
run (task : T, options : RunOptions = kDefaultRunOptions): Promise<R> {
796+
run (task : Parameters<F>[0], options : RunOptions = kDefaultRunOptions): Promise<ReturnType<F>> {
797797
if (options === null || typeof options !== 'object') {
798798
return Promise.reject(
799799
new TypeError('options must be an object'));

test/fixtures/worker-type.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default function add({ a, b }: { a: number; b: number }): number {
2+
return a + b;
3+
}

test/types-entrypoint.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { resolve } from "node:path";
2+
import { expectTypeOf } from "expect-type";
3+
4+
import { test } from "tap";
5+
6+
import Piscina from "../dist";
7+
8+
test("types can be inferred from function", async (t) => {
9+
const pool = new Piscina<typeof import("./fixtures/worker-type.js").default>({
10+
filename: resolve(__dirname, "fixtures/worker-type.js"),
11+
concurrentTasksPerWorker: 1,
12+
});
13+
14+
expectTypeOf(pool.run).parameter(0).toEqualTypeOf<{ a: number; b: number }>();
15+
expectTypeOf(pool.run).returns.toEqualTypeOf<Promise<number>>();
16+
});
17+
18+
test("types can be manually specified", async (t) => {
19+
const pool = new Piscina<(payload: { a: number; b: number }) => number>({
20+
filename: resolve(__dirname, "fixtures/worker-type.js"),
21+
concurrentTasksPerWorker: 1,
22+
});
23+
24+
expectTypeOf(pool.run).parameter(0).toEqualTypeOf<{ a: number; b: number }>();
25+
expectTypeOf(pool.run).returns.toEqualTypeOf<Promise<number>>();
26+
});

0 commit comments

Comments
 (0)