@midwayjs/async-hooks-context-manager 3.4.0-beta.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,9 @@
1
+ # midway-async-hooks-context-manager
2
+
3
+ this is a sub package for midway.
4
+
5
+ Document: [https://midwayjs.org](https://midwayjs.org)
6
+
7
+ ## License
8
+
9
+ [MIT]((http://github.com/midwayjs/midway/blob/master/LICENSE))
@@ -0,0 +1,49 @@
1
+ import { AsyncContext, AsyncContextManager } from '@midwayjs/core';
2
+ export declare class AsyncHooksContextManager implements AsyncContextManager {
3
+ private _asyncHook;
4
+ private _contexts;
5
+ private _stack;
6
+ constructor();
7
+ active(): AsyncContext;
8
+ with<A extends unknown[], F extends (...args: A) => ReturnType<F>>(context: AsyncContext, fn: F, thisArg?: ThisParameterType<F>, ...args: A): ReturnType<F>;
9
+ enable(): this;
10
+ disable(): this;
11
+ /**
12
+ * Init hook will be called when userland create a async context, setting the
13
+ * context as the current one if it exist.
14
+ * @param uid id of the async context
15
+ * @param type the resource type
16
+ */
17
+ private _init;
18
+ /**
19
+ * Destroy hook will be called when a given context is no longer used so we can
20
+ * remove its attached context.
21
+ * @param uid uid of the async context
22
+ */
23
+ private _destroy;
24
+ /**
25
+ * Before hook is called just before executing a async context.
26
+ * @param uid uid of the async context
27
+ */
28
+ private _before;
29
+ /**
30
+ * After hook is called just after completing the execution of a async context.
31
+ */
32
+ private _after;
33
+ /**
34
+ * Set the given context as active
35
+ */
36
+ private _enterContext;
37
+ /**
38
+ * Remove the context at the root of the stack
39
+ */
40
+ private _exitContext;
41
+ /**
42
+ * Binds a the certain context or the active one to the target function and then returns the target
43
+ * @param context A context (span) to be bind to target
44
+ * @param target a function. When target or one of its callbacks is called,
45
+ * the provided context will be used as the active context for the duration of the call.
46
+ */
47
+ bind<T>(context: AsyncContext, target: T): T;
48
+ }
49
+ //# sourceMappingURL=asyncHooksContextManager.d.ts.map
@@ -0,0 +1,140 @@
1
+ "use strict";
2
+ /*
3
+ * Copyright The OpenTelemetry Authors
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * https://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.AsyncHooksContextManager = void 0;
19
+ const core_1 = require("@midwayjs/core");
20
+ const asyncHooks = require("async_hooks");
21
+ class AsyncHooksContextManager {
22
+ constructor() {
23
+ this._contexts = new Map();
24
+ this._stack = [];
25
+ this._asyncHook = asyncHooks.createHook({
26
+ init: this._init.bind(this),
27
+ before: this._before.bind(this),
28
+ after: this._after.bind(this),
29
+ destroy: this._destroy.bind(this),
30
+ promiseResolve: this._destroy.bind(this),
31
+ });
32
+ }
33
+ active() {
34
+ var _a;
35
+ return (_a = this._stack[this._stack.length - 1]) !== null && _a !== void 0 ? _a : core_1.ASYNC_ROOT_CONTEXT;
36
+ }
37
+ with(context, fn, thisArg, ...args) {
38
+ this._enterContext(context);
39
+ try {
40
+ return fn.call(thisArg, ...args);
41
+ }
42
+ finally {
43
+ this._exitContext();
44
+ }
45
+ }
46
+ enable() {
47
+ this._asyncHook.enable();
48
+ return this;
49
+ }
50
+ disable() {
51
+ this._asyncHook.disable();
52
+ this._contexts.clear();
53
+ this._stack = [];
54
+ return this;
55
+ }
56
+ /**
57
+ * Init hook will be called when userland create a async context, setting the
58
+ * context as the current one if it exist.
59
+ * @param uid id of the async context
60
+ * @param type the resource type
61
+ */
62
+ _init(uid, type) {
63
+ // ignore TIMERWRAP as they combine timers with same timeout which can lead to
64
+ // false context propagation. TIMERWRAP has been removed in node 11
65
+ // every timer has it's own `Timeout` resource anyway which is used to propagete
66
+ // context.
67
+ if (type === 'TIMERWRAP')
68
+ return;
69
+ const context = this._stack[this._stack.length - 1];
70
+ if (context !== undefined) {
71
+ this._contexts.set(uid, context);
72
+ }
73
+ }
74
+ /**
75
+ * Destroy hook will be called when a given context is no longer used so we can
76
+ * remove its attached context.
77
+ * @param uid uid of the async context
78
+ */
79
+ _destroy(uid) {
80
+ this._contexts.delete(uid);
81
+ }
82
+ /**
83
+ * Before hook is called just before executing a async context.
84
+ * @param uid uid of the async context
85
+ */
86
+ _before(uid) {
87
+ const context = this._contexts.get(uid);
88
+ if (context !== undefined) {
89
+ this._enterContext(context);
90
+ }
91
+ }
92
+ /**
93
+ * After hook is called just after completing the execution of a async context.
94
+ */
95
+ _after() {
96
+ this._exitContext();
97
+ }
98
+ /**
99
+ * Set the given context as active
100
+ */
101
+ _enterContext(context) {
102
+ this._stack.push(context);
103
+ }
104
+ /**
105
+ * Remove the context at the root of the stack
106
+ */
107
+ _exitContext() {
108
+ this._stack.pop();
109
+ }
110
+ /**
111
+ * Binds a the certain context or the active one to the target function and then returns the target
112
+ * @param context A context (span) to be bind to target
113
+ * @param target a function. When target or one of its callbacks is called,
114
+ * the provided context will be used as the active context for the duration of the call.
115
+ */
116
+ bind(context, target) {
117
+ if (typeof target === 'function') {
118
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
119
+ const manager = this;
120
+ const contextWrapper = function (...args) {
121
+ return manager.with(context, () => target.apply(this, args));
122
+ };
123
+ Object.defineProperty(contextWrapper, 'length', {
124
+ enumerable: false,
125
+ configurable: true,
126
+ writable: false,
127
+ value: target.length,
128
+ });
129
+ /**
130
+ * It isn't possible to tell Typescript that contextWrapper is the same as T
131
+ * so we forced to cast as any here.
132
+ */
133
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
134
+ return contextWrapper;
135
+ }
136
+ return target;
137
+ }
138
+ }
139
+ exports.AsyncHooksContextManager = AsyncHooksContextManager;
140
+ //# sourceMappingURL=asyncHooksContextManager.js.map
@@ -0,0 +1,17 @@
1
+ import { AsyncContext, AsyncContextManager } from '@midwayjs/core';
2
+ export declare class AsyncLocalStorageContextManager implements AsyncContextManager {
3
+ private _asyncLocalStorage;
4
+ constructor();
5
+ active(): AsyncContext;
6
+ with<A extends unknown[], F extends (...args: A) => ReturnType<F>>(context: AsyncContext, fn: F, thisArg?: ThisParameterType<F>, ...args: A): ReturnType<F>;
7
+ enable(): this;
8
+ disable(): this;
9
+ /**
10
+ * Binds a the certain context or the active one to the target function and then returns the target
11
+ * @param context A context (span) to be bind to target
12
+ * @param target a function. When target or one of its callbacks is called,
13
+ * the provided context will be used as the active context for the duration of the call.
14
+ */
15
+ bind<T>(context: AsyncContext, target: T): T;
16
+ }
17
+ //# sourceMappingURL=asyncLocalStorageContextManager.d.ts.map
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ /*
3
+ * Copyright The OpenTelemetry Authors
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * https://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.AsyncLocalStorageContextManager = void 0;
19
+ const core_1 = require("@midwayjs/core");
20
+ const async_hooks_1 = require("async_hooks");
21
+ class AsyncLocalStorageContextManager {
22
+ constructor() {
23
+ this._asyncLocalStorage = new async_hooks_1.AsyncLocalStorage();
24
+ }
25
+ active() {
26
+ var _a;
27
+ return (_a = this._asyncLocalStorage.getStore()) !== null && _a !== void 0 ? _a : core_1.ASYNC_ROOT_CONTEXT;
28
+ }
29
+ with(context, fn, thisArg, ...args) {
30
+ const cb = thisArg == null ? fn : fn.bind(thisArg);
31
+ return this._asyncLocalStorage.run(context, cb, ...args);
32
+ }
33
+ enable() {
34
+ return this;
35
+ }
36
+ disable() {
37
+ this._asyncLocalStorage.disable();
38
+ return this;
39
+ }
40
+ /**
41
+ * Binds a the certain context or the active one to the target function and then returns the target
42
+ * @param context A context (span) to be bind to target
43
+ * @param target a function. When target or one of its callbacks is called,
44
+ * the provided context will be used as the active context for the duration of the call.
45
+ */
46
+ bind(context, target) {
47
+ if (typeof target === 'function') {
48
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
49
+ const manager = this;
50
+ const contextWrapper = function (...args) {
51
+ return manager.with(context, () => target.apply(this, args));
52
+ };
53
+ Object.defineProperty(contextWrapper, 'length', {
54
+ enumerable: false,
55
+ configurable: true,
56
+ writable: false,
57
+ value: target.length,
58
+ });
59
+ /**
60
+ * It isn't possible to tell Typescript that contextWrapper is the same as T
61
+ * so we forced to cast as any here.
62
+ */
63
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
64
+ return contextWrapper;
65
+ }
66
+ return target;
67
+ }
68
+ }
69
+ exports.AsyncLocalStorageContextManager = AsyncLocalStorageContextManager;
70
+ //# sourceMappingURL=asyncLocalStorageContextManager.js.map
@@ -0,0 +1,4 @@
1
+ export * from './asyncHooksContextManager';
2
+ export * from './asyncLocalStorageContextManager';
3
+ export { isSemverGreaterThanOrEqualTo, createContextManager } from './util';
4
+ //# sourceMappingURL=index.d.ts.map
package/dist/index.js ADDED
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.createContextManager = exports.isSemverGreaterThanOrEqualTo = void 0;
18
+ __exportStar(require("./asyncHooksContextManager"), exports);
19
+ __exportStar(require("./asyncLocalStorageContextManager"), exports);
20
+ var util_1 = require("./util");
21
+ Object.defineProperty(exports, "isSemverGreaterThanOrEqualTo", { enumerable: true, get: function () { return util_1.isSemverGreaterThanOrEqualTo; } });
22
+ Object.defineProperty(exports, "createContextManager", { enumerable: true, get: function () { return util_1.createContextManager; } });
23
+ //# sourceMappingURL=index.js.map
package/dist/util.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ import { AsyncLocalStorageContextManager } from './asyncLocalStorageContextManager';
2
+ import { AsyncHooksContextManager } from './asyncHooksContextManager';
3
+ export declare function isSemverGreaterThanOrEqualTo(currentVersion: string, targetVersion: string): boolean;
4
+ export declare function createContextManager(): AsyncHooksContextManager | AsyncLocalStorageContextManager;
5
+ //# sourceMappingURL=util.d.ts.map
package/dist/util.js ADDED
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createContextManager = exports.isSemverGreaterThanOrEqualTo = void 0;
4
+ const asyncLocalStorageContextManager_1 = require("./asyncLocalStorageContextManager");
5
+ const asyncHooksContextManager_1 = require("./asyncHooksContextManager");
6
+ const semver = /^[v^~<>=]*?(\d+)(?:\.([x*]|\d+)(?:\.([x*]|\d+)(?:\.([x*]|\d+))?(?:-([\da-z-]+(?:\.[\da-z-]+)*))?(?:\+[\da-z-]+(?:\.[\da-z-]+)*)?)?)?$/i;
7
+ // 判断 semver 大于等于 v14.8.0
8
+ function isSemverGreaterThanOrEqualTo(currentVersion, targetVersion) {
9
+ const v = semver.exec(currentVersion);
10
+ const t = semver.exec(targetVersion);
11
+ if (v && t) {
12
+ if (v[1] === t[1] && v[2] === t[2] && v[3] === t[3] && v[4] === t[4]) {
13
+ return true;
14
+ }
15
+ return (gteString(v[1], t[1]) ||
16
+ (v[1] === t[1] && gteString(v[2], t[2])) ||
17
+ (v[1] === t[1] && v[2] === t[2] && gteString(v[3], t[3])) ||
18
+ (v[1] === t[1] && v[2] === t[2] && v[3] === t[3] && gteString(v[4], t[4])));
19
+ }
20
+ return false;
21
+ }
22
+ exports.isSemverGreaterThanOrEqualTo = isSemverGreaterThanOrEqualTo;
23
+ function gteString(v1, v2) {
24
+ // compare string with parseInt
25
+ const v1Int = parseInt(v1, 10);
26
+ const v2Int = parseInt(v2, 10);
27
+ return v1Int > v2Int;
28
+ }
29
+ function createContextManager() {
30
+ const ContextManager = isSemverGreaterThanOrEqualTo(process.version, '14.8.0')
31
+ ? asyncLocalStorageContextManager_1.AsyncLocalStorageContextManager
32
+ : asyncHooksContextManager_1.AsyncHooksContextManager;
33
+ return new ContextManager();
34
+ }
35
+ exports.createContextManager = createContextManager;
36
+ //# sourceMappingURL=util.js.map
package/package.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "@midwayjs/async-hooks-context-manager",
3
+ "version": "3.4.0-beta.8",
4
+ "description": "midway async hooks context manager",
5
+ "main": "dist/index",
6
+ "typings": "dist/index.d.ts",
7
+ "scripts": {
8
+ "build": "tsc",
9
+ "test": "node --require=ts-node/register ../../node_modules/.bin/jest --runInBand",
10
+ "cov": "node --require=ts-node/register ../../node_modules/.bin/jest --runInBand --coverage --forceExit"
11
+ },
12
+ "keywords": [
13
+ "midway",
14
+ "async",
15
+ "context manager"
16
+ ],
17
+ "files": [
18
+ "dist/**/*.js",
19
+ "dist/**/*.d.ts"
20
+ ],
21
+ "license": "MIT",
22
+ "devDependencies": {
23
+ "@midwayjs/core": "^3.4.0-beta.8"
24
+ },
25
+ "author": "Harry Chen <czy88840616@gmail.com>",
26
+ "repository": {
27
+ "type": "git",
28
+ "url": "http://github.com/midwayjs/midway.git"
29
+ },
30
+ "engines": {
31
+ "node": ">=12.17.0"
32
+ },
33
+ "gitHead": "a603d2348d6141f8f723901498f03a162a037708"
34
+ }