-
-
Notifications
You must be signed in to change notification settings - Fork 35.4k
Expand file tree
/
Copy pathasync_context_frame.js
More file actions
82 lines (67 loc) · 1.7 KB
/
async_context_frame.js
File metadata and controls
82 lines (67 loc) · 1.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
'use strict';
const {
ObjectIs,
ReflectApply,
} = primordials;
const {
validateObject,
} = require('internal/validators');
const AsyncContextFrame = require('internal/async_context_frame');
const { AsyncResource } = require('async_hooks');
class AsyncLocalStorage {
#defaultValue = undefined;
#name = undefined;
/**
* @typedef {object} AsyncLocalStorageOptions
* @property {any} [defaultValue] - The default value to use when no value is set.
* @property {string} [name] - The name of the storage.
*/
/**
* @param {AsyncLocalStorageOptions} [options]
*/
constructor(options = {}) {
validateObject(options, 'options');
this.#defaultValue = options.defaultValue;
if (options.name !== undefined) {
this.#name = `${options.name}`;
}
}
/** @type {string} */
get name() { return this.#name || ''; }
static bind(fn) {
return AsyncResource.bind(fn);
}
static snapshot() {
return AsyncLocalStorage.bind((cb, ...args) => cb(...args));
}
disable() {
AsyncContextFrame.disable(this);
}
enterWith(data) {
const frame = new AsyncContextFrame(this, data);
AsyncContextFrame.set(frame);
}
run(data, fn, ...args) {
const prior = this.getStore();
if (ObjectIs(prior, data)) {
return ReflectApply(fn, null, args);
}
this.enterWith(data);
try {
return ReflectApply(fn, null, args);
} finally {
this.enterWith(prior);
}
}
exit(fn, ...args) {
return this.run(undefined, fn, ...args);
}
getStore() {
const frame = AsyncContextFrame.current();
if (!frame?.has(this)) {
return this.#defaultValue;
}
return frame?.get(this);
}
}
module.exports = AsyncLocalStorage;