Skip to content

Commit 6bb05f9

Browse files
authored
[FEAT] Manger.exists API (#28)
1 parent daa960b commit 6bb05f9

File tree

6 files changed

+53
-16
lines changed

6 files changed

+53
-16
lines changed

README.md

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# node-execution-context
22
A straightforward library that provides a persistent process-level context wrapper using node "async_hooks" feature.
3-
This library will try to use by default [`AsyncLocalStorage`](https://nodejs.org/api/async_hooks.html#async_hooks_class_asynclocalstorage) implementation based if current node version supports it, otherwise it will fallback to raw [`async_hooks`](https://nodejs.org/api/async_hooks.html) implementation for lower versions which mimics this behaviour.
3+
This library will try to use by default [`AsyncLocalStorage`](https://nodejs.org/api/async_hooks.html#async_hooks_class_asynclocalstorage) implementation based if current node version supports it, otherwise it will fallback to raw [`async_hooks`](https://nodejs.org/api/async_hooks.html) implementation for lower versions which mimics this behaviour.
44

55
## Installation
66

@@ -10,7 +10,7 @@ npm i node-execution-context
1010

1111
## Getting started
1212

13-
Let't start with creating the context initialisation point of our app, well take an simples express app for this example
13+
Let's start with creating the context initialisation point of our app, we will take a simple express app for this example
1414

1515
```js
1616
// main.js
@@ -32,7 +32,7 @@ app.listen(port);
3232

3333
```
3434

35-
This will expose any point of your code form this point that handles that request.
35+
This will expose any point of your code form this point that handles that request.
3636

3737
```js
3838
// ./controller/user/index.js
@@ -44,12 +44,12 @@ const logger = require('../service/logger');
4444
export class UserController {
4545
async create (req) {
4646
const { user } = req.body;
47-
47+
4848
// This will return the reference number set by out ContextMiddleware (generated by Math.random())
4949
const { reference } = Context.get();
50-
50+
5151
logger.info('Created user for reference: ', reference);
52-
52+
5353
return await mongo.create('user', user);
5454
}
5555
}
@@ -66,7 +66,7 @@ The context will be exposed to all callbacks and promise chains triggered from t
6666

6767
Gets the current asynchronous execution context.
6868

69-
> The `get` result is returned by `reference` meaning if you wish any immutability applied, it will have to be manually applied.
69+
> The `get` result is returned by `reference` meaning if you wish any immutability applied, it will have to be manually applied.
7070
7171
> This API may throw CONTEXT_DOES_NOT_EXIST error if accessed without initializing the context properly.
7272
@@ -81,7 +81,7 @@ Sets the current asynchronous execution context to given value.
8181
Creates a given context for the current asynchronous execution.
8282
It is recommended to use the `run` method. This method should be used in special cases in which the `run` method cannot be used directly.
8383

84-
> Note that if this method will be called not within a AsyncResource context, it will effect current execution context and should be used with caution.
84+
> Note that if this method will be called not within a AsyncResource context, it will effect current execution context and should be used with caution.
8585
8686
#### Example
8787

@@ -97,7 +97,7 @@ emitter.on('contextual-event', () => {
9797

9898
// service.js
9999
emitter.on('contextual-event', () => {
100-
Context.get(); // Returns { id: random }
100+
Context.get(); // Returns { id: random }
101101
});
102102

103103
// main.js
@@ -144,26 +144,26 @@ Context.create({
144144

145145
Promise.resolve().then(() => {
146146
console.log(Context.get()); // outputs: {"value": true}
147-
147+
148148
Context.set({
149149
value: false
150150
});
151-
151+
152152
return new Promise((resolve) => {
153153
setTimeout(() => {
154154
console.log(Context.get()); // outputs: {"value": false}
155-
155+
156156
Context.set({
157157
butter: 'fly'
158158
});
159-
159+
160160
process.nextTick(() => {
161161
console.log(Context.get()); // outputs: {"butter": 'fly'}
162162
resolve();
163163
});
164-
164+
165165
}, 1000);
166-
166+
167167
console.log(Context.get()); // outputs: {"value": false}
168168
});
169169
});

src/ExecutionContext/index.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,14 @@ class ExecutionContext {
4040
this.manager.update(context);
4141
}
4242

43+
/**
44+
* Check if the current asynchronous execution context exists.
45+
* @return {boolean}
46+
*/
47+
exists() {
48+
return this.manager.exists();
49+
}
50+
4351
/**
4452
* Gets the current asynchronous execution context.
4553
* @return {*}

src/ExecutionContext/spec.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,20 @@ describe('Context', () => {
1717
});
1818
});
1919

20+
describe('Exists', () => {
21+
it('Returns false when context is not created', () => {
22+
expect(Context.exists()).toBeFalsy();
23+
});
24+
25+
describe('When context is exists', () => {
26+
it('Returns true', () => {
27+
Context.create({ val: 'value' });
28+
29+
expect(() => Context.exists()).toBeTruthy();
30+
});
31+
});
32+
});
33+
2034
describe('Get', () => {
2135
it('Throws an error when context is not created', () => {
2236
expect(() => Context.get())

src/managers/asyncHooks/index.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,12 @@ class AsyncHooksContext {
8484
});
8585
}
8686

87+
exists() {
88+
const asyncId = asyncHooks.executionAsyncId();
89+
90+
return executionContextMap.has(asyncId);
91+
}
92+
8793
get() {
8894
const asyncId = asyncHooks.executionAsyncId();
8995

src/managers/asyncLocalStorage/index.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ class AsyncLocalStorageContext {
3131
);
3232
}
3333

34+
exists() {
35+
return validateStore(this.asyncLocaleStorage);
36+
}
37+
3438
get() {
3539
if (!validateStore(this.asyncLocaleStorage)) {
3640
return handleError(ExecutionContextErrors.CONTEXT_DOES_NOT_EXIST);

src/types.d.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ interface ExecutionContextAPI {
2323
*/
2424
update(context: Record<string, unknown>): void;
2525

26+
/**
27+
* Checks if the current asynchronous execution context exists.
28+
*/
29+
exists(): boolean;
30+
2631
/**
2732
* Gets the current asynchronous execution context.
2833
*/
@@ -63,4 +68,4 @@ export {
6368
ExecutionContextAPI
6469
};
6570

66-
export default context;
71+
export default context;

0 commit comments

Comments
 (0)