Skip to content

Commit b72ea5a

Browse files
authored
Merge pull request #5 from maxgfr/maxgfr/async-hooks
2 parents 9890c9c + 95a2773 commit b72ea5a

File tree

3 files changed

+65
-55
lines changed

3 files changed

+65
-55
lines changed

README.md

Lines changed: 30 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
`node-simple-context` is an helper to create a context in node.
44

5+
This library is highly inspired by [nctx](https://github.com/devthejo/nctx).
6+
57
## Installation
68

79
```sh
@@ -40,39 +42,43 @@ console.log(contextA.get('xxx')); // undefined
4042

4143
### Complex
4244

45+
#### With [`async_hooks`](https://nodejs.org/api/async_hooks.html)
46+
4347
```ts
4448
const context = createSimpleContext();
4549

46-
const func = (forkId: string): string => {
47-
const foo = context.getForkProperty(forkId, 'foo');
50+
const func = (): string => {
51+
const foo = context.getForkProperty('foo');
4852
return `foo=${foo}`;
4953
};
5054

51-
context.fork('X');
52-
context.setForkProperty('X', 'foo', 'bar');
55+
context.fork();
56+
context.setForkProperty('foo', 'bar');
5357

5458
const res = await Promise.all([
5559
new Promise((resolve) => {
56-
context.fork('A');
57-
context.setForkProperty('A', 'foo', 'tata'),
58-
setTimeout(() => {
59-
resolve(func('A'));
60-
}, 400);
60+
setTimeout(() => {
61+
context.fork();
62+
context.setForkProperty('foo', 'tata');
63+
resolve(func());
64+
}, 400);
6165
}),
62-
func('X'),
66+
func(),
6367
new Promise((resolve) => {
64-
context.fork('B');
65-
context.setForkProperty('B', 'foo', 'toto'),
66-
setTimeout(() => {
67-
resolve(func('B'));
68-
}, 200);
68+
setTimeout(() => {
69+
context.fork();
70+
context.setForkProperty('foo', 'toto');
71+
resolve(func());
72+
}, 200);
6973
}),
7074
]);
7175

7276
console.log(res); // ['foo=tata', 'foo=bar', 'foo=toto']
7377
```
7478

75-
To achieve this, you can also define multiple contexts in the same file, like that:
79+
#### Without [`async_hooks`](https://nodejs.org/api/async_hooks.html)
80+
81+
Here, I define multiple contexts in the same file, like that:
7682

7783
```ts
7884
const contextA = createSimpleContext();
@@ -88,21 +94,19 @@ contextC.setProperty('foo', 'bar');
8894

8995
const res = await Promise.all([
9096
new Promise((resolve) => {
91-
contextA.setProperty('foo', 'tata'),
92-
setTimeout(() => {
93-
resolve(func(contextA));
94-
}, 400);
97+
setTimeout(() => {
98+
contextA.setProperty('foo', 'tata');
99+
resolve(func(contextA));
100+
}, 400);
95101
}),
96102
func(contextC),
97103
new Promise((resolve) => {
98-
contextB.setProperty('foo', 'toto'),
99-
setTimeout(() => {
100-
resolve(func(contextB));
101-
}, 200);
104+
setTimeout(() => {
105+
contextB.setProperty('foo', 'toto');
106+
resolve(func(contextB));
107+
}, 200);
102108
}),
103109
]);
104110

105111
console.log(res); // ['foo=tata', 'foo=bar', 'foo=toto']
106112
```
107-
108-
:warning: Otherwise, I advice you to use [nctx](https://github.com/devthejo/nctx) which uses `async_hooks` to detect dynamically the context in asynchronous call.

src/__tests__/context.test.ts

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -9,29 +9,29 @@ describe('SimpleContext', () => {
99
it('should display value in order with fork', async () => {
1010
const context = createSimpleContext();
1111

12-
const func = (forkId: string): string => {
13-
const foo = context.getForkProperty(forkId, 'foo');
12+
const func = (): string => {
13+
const foo = context.getForkProperty('foo');
1414
return `foo=${foo}`;
1515
};
1616

17-
context.fork('X');
18-
context.setForkProperty('X', 'foo', 'bar');
17+
context.fork();
18+
context.setForkProperty('foo', 'bar');
1919

2020
const res = await Promise.all([
2121
new Promise((resolve) => {
22-
context.fork('A');
23-
context.setForkProperty('A', 'foo', 'tata'),
24-
setTimeout(() => {
25-
resolve(func('A'));
26-
}, 400);
22+
setTimeout(() => {
23+
context.fork();
24+
context.setForkProperty('foo', 'tata');
25+
resolve(func());
26+
}, 400);
2727
}),
28-
func('X'),
28+
func(),
2929
new Promise((resolve) => {
30-
context.fork('B');
31-
context.setForkProperty('B', 'foo', 'toto'),
32-
setTimeout(() => {
33-
resolve(func('B'));
34-
}, 200);
30+
setTimeout(() => {
31+
context.fork();
32+
context.setForkProperty('foo', 'toto');
33+
resolve(func());
34+
}, 200);
3535
}),
3636
]);
3737
expect(res).toStrictEqual(['foo=tata', 'foo=bar', 'foo=toto']);
@@ -51,17 +51,17 @@ describe('SimpleContext', () => {
5151

5252
const res = await Promise.all([
5353
new Promise((resolve) => {
54-
contextA.setProperty('foo', 'tata'),
55-
setTimeout(() => {
56-
resolve(func(contextA));
57-
}, 400);
54+
setTimeout(() => {
55+
contextA.setProperty('foo', 'tata');
56+
resolve(func(contextA));
57+
}, 400);
5858
}),
5959
func(contextC),
6060
new Promise((resolve) => {
61-
contextB.setProperty('foo', 'toto'),
62-
setTimeout(() => {
63-
resolve(func(contextB));
64-
}, 200);
61+
setTimeout(() => {
62+
contextB.setProperty('foo', 'toto');
63+
resolve(func(contextB));
64+
}, 200);
6565
}),
6666
]);
6767
expect(res).toStrictEqual(['foo=tata', 'foo=bar', 'foo=toto']);

src/context.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { randomUUID } from 'crypto';
2+
import async_hooks from 'async_hooks';
23

34
export class SimpleContext {
45
private contextId: string;
@@ -17,18 +18,23 @@ export class SimpleContext {
1718
this.properties[key] = value;
1819
}
1920

20-
public fork(id: string): void {
21+
public fork(): void {
22+
const id = async_hooks.executionAsyncId().toString();
2123
this.forks = [...this.forks, new SimpleContext(id)];
2224
}
2325

24-
public setForkProperty(id: string, key: string, value: any): void {
25-
const fork = this.forks.find((fork) => fork.contextId === id);
26-
if (fork) {
27-
fork.setProperty(key, value);
26+
public setForkProperty(key: string, value: any): void {
27+
const id = async_hooks.executionAsyncId().toString();
28+
if (id) {
29+
const fork = this.forks.find((fork) => fork.contextId === id);
30+
if (fork) {
31+
fork.setProperty(key, value);
32+
}
2833
}
2934
}
3035

31-
public getForkProperty(id: string, key: string): any {
36+
public getForkProperty(key: string): any {
37+
const id = async_hooks.executionAsyncId().toString();
3238
const fork = this.forks.find((fork) => fork.contextId === id);
3339
if (fork) {
3440
return fork.getProperty(key);

0 commit comments

Comments
 (0)