@@ -9,18 +9,18 @@ backends and reduce requests to those backends via batching.
99This library is especially useful for scenarios where you need to perform multiple asynchronous operations efficiently,
1010such as when making network requests or performing database queries.
1111
12- Heavily inspired by [ graphql/dataloader] ( https://github.com/graphql/dataloader ) but using classes and decorators 😜
12+ Heavily inspired by [ graphql/dataloader] ( https://github.com/graphql/dataloader ) but simpler using decorators (😜 really
13+ decoupled). Because of that the
14+ rest of your application doesn't event need to know about the batching/dataloader, it just works!
1315
1416## Table of Contents
1517
1618- [ Installation] ( #installation )
1719- [ Usage] ( #usage )
18- - [ Basic Usage ] ( #basic-usage )
19- - [ Using the ` @InBatches ` Decorator ] ( #using-the-inbatches-decorator )
20+ - [ Basic usage with ` @InBatches ` Decorator ] ( #basic-usage-with-inbatches-decorator )
21+ - [ Advanced usage with custom ` Batcher ` class ] ( #advanced-usage-with-custom-batcher-class )
2022- [ API] ( #api )
2123 - [ ` BatcherOptions ` ] ( #batcheroptions )
22- - [ ` Batcher<K, V> ` Class] ( #batcherk-v-class )
23- - [ ` InBatches<K, V> ` Decorator] ( #inbatches-decorator )
2424- [ Contributing] ( #contributing )
2525- [ License] ( #license )
2626
@@ -30,29 +30,45 @@ Heavily inspired by [graphql/dataloader](https://github.com/graphql/dataloader)
3030npm install inbatches
3131```
3232
33+ or
34+
35+ ``` bash
36+ yarn add inbatches
37+ ```
38+
3339## Usage
3440
35- ### Using the ` Batcher ` Class
41+ ### Basic usage with ` @InBatches ` Decorator
42+
43+ The simplest way to get the grown running is to use the ` @InBatches ` decorator. This decorator will wrap your method
44+ and will batch-enable it, like magic! 🧙♂️
3645
3746``` typescript
38- import { Batcher } from ' inbatches' ;
47+ import { InBatches } from ' inbatches' ;
3948
40- // Define a class that extends Batcher and implements the `run` method
41- // the `run` method will be called with an array of keys collected from the `enqueue` method
42- class MyBatcher extends Batcher <number , string > {
43- async run(ids : number []): Promise <string []> {
44- // Perform asynchronous operations using the keys
45- // you must return an array of results in the same order as the keys
46- return this .db .getMany (ids );
49+ class MyService {
50+
51+ // (optional) overloaded method, where you define the keys as `number` and the return type as `User` for typings
52+ async fetch(key : number ): Promise <User >;
53+
54+ // This method is now batch-enabled
55+ @InBatches ()
56+ async fetch(keys : number | number []): Promise <User | User []> {
57+ if (Array .isArray (keys )) return await this .db .getMany (keys );
58+
59+ // in reality the Decorator will wrap this method and it will never be called with a single key :)
60+ throw new Error (' It will never be called with a single key 😉' );
4761 }
4862}
63+ ```
4964
50- // Create an instance of your batcher
51- const batcher = new MyBatcher ();
65+ Profit! 🤑
66+
67+ ``` typescript
68+ const service = new MyService ();
5269
53- // Enqueue keys for batched execution
5470const result = [1 , 2 , 3 , 4 , 5 ].map (async id => {
55- return await batcher . enqueue (id );
71+ return await service . fetch (id );
5672});
5773
5874// The result will be an array of results in the same order as the keys
@@ -61,34 +77,33 @@ result.then(results => {
6177});
6278```
6379
64- ### Using the ` @InBatches ` Decorator
80+ ### Advanced usage with custom ` Batcher ` class
6581
66- The library also provides a decorator called ` InBatches ` that you can use to batch-enable methods of your class.
82+ Another way to use the library is to create a class that extends the ` Batcher ` class and implement the ` run ` method.
83+ This class will provide a ` enqueue ` method that you can use to enqueue keys for batched execution.
6784
6885``` typescript
69- import { InBatches } from ' inbatches' ;
70-
71- class MyService {
72-
73- // (optional) overloaded method, where you define the keys as `number` and the return type as `string` for typings
74- async fetch(keys : number ): Promise <string >;
75-
76- // in reality the Decorator will wrap this method and it will never be called with a single key :)
77- @InBatches () // This method is now batch-enabled
78- async fetch(keys : number | number []): Promise <string | string []> {
79- if (Array .isArray (keys )) {
80- return this .db .getMany (keys );
81- }
86+ import { Batcher } from ' inbatches' ;
8287
83- // the Decorator will wrap this method and because of that it will never be called with a single key
84- throw new Error (' It will never be called with a single key 😉' );
88+ // The `run` method will be called with an array of keys collected from the `enqueue` method
89+ class MyBatcher extends Batcher <number , string > {
90+ async run(ids : number []): Promise <string []> {
91+ // Perform asynchronous operations using the keys
92+ // you must return an array of results in the same order as the keys
93+ return this .db .getMany (ids );
8594 }
8695}
96+ ```
8797
88- const service = new MyService ();
98+ then
8999
100+ ``` typescript
101+ // Create an instance of your batcher
102+ const batcher = new MyBatcher ();
103+
104+ // Enqueue keys for batched execution
90105const result = [1 , 2 , 3 , 4 , 5 ].map (async id => {
91- return await service . fetch (id );
106+ return await batcher . enqueue (id );
92107});
93108
94109// The result will be an array of results in the same order as the keys
@@ -108,33 +123,6 @@ An interface to specify options for the batcher.
108123 is ` undefined ` and will use ` process.nextTick ` to dispatch the batch, which is highly efficient and fast. Only use
109124 this if you really want to accumulate promises calls in a window of time before dispatching the batch.
110125
111- ### ` Batcher<K, V> ` Class
112-
113- An abstract class that provides the core functionality for batching and executing asynchronous operations.
114-
115- - ` enqueue(key: K): Promise<V> ` : Enqueues a key for batching and returns a promise that resolves to the result when
116- available.
117-
118- ### ` InBatches ` Decorator
119-
120- A decorator function that can be applied to methods to enable batching.
121-
122- - Usage: ` @InBatches(options?: BatcherOptions) `
123- - Example:
124-
125- ``` typescript
126- class MyService {
127-
128- // (optional) overloaded method, where you define the keys as `number` and the return type as `string` for typings
129- async fetchResults(keys : number ): Promise <string >
130-
131- @InBatches ({ maxBatchSize: 10 })
132- async fetchResults(keys : number | number []): Promise <string | string []> {
133- // Batch-enabled method logic
134- }
135- }
136- ```
137-
138126## Contributing
139127
140128Contributions are welcome! Feel free to open issues or submit pull requests on
0 commit comments