-
-
Notifications
You must be signed in to change notification settings - Fork 5.6k
/
usingCtx.ts
104 lines (96 loc) 路 3 KB
/
usingCtx.ts
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
/* @minVersion 7.23.9 */
const enum DisposeFlag {
// set when the dispose function is a [Symbol.asyncDispose] method
ASYNC_DISPOSE = 1,
// alias of AWAIT_USING: set when the resource is an `await using` disposable
ASYNC_DISPOSE_MASK = 2,
}
const enum DisposeKind {
USING_DISPOSE = 0,
// AWAIT_FLAG
AWAIT_USING_DISPOSE = 2,
// Flag.AWAIT_USING | Flag.ASYNC_DISPOSE
AWAIT_USING_ASYNC_DISPOSE = 3,
}
type Stack = {
v?: any;
d: null | undefined | (() => any);
k: DisposeKind;
};
export default function _usingCtx() {
var _disposeSuppressedError =
typeof SuppressedError === "function"
? // eslint-disable-next-line no-undef
SuppressedError
: (function (error: Error, suppressed: Error) {
var err = new Error() as SuppressedError;
err.name = "SuppressedError";
err.error = error;
err.suppressed = suppressed;
return err;
} as SuppressedErrorConstructor),
empty = {},
stack: Stack[] = [];
function using(isAwait: boolean, value: any) {
if (value != null) {
if (Object(value) !== value) {
throw new TypeError(
"using declarations can only be used with objects, functions, null, or undefined.",
);
}
// core-js-pure uses Symbol.for for polyfilling well-known symbols
if (isAwait) {
var dispose =
value[Symbol.asyncDispose || Symbol.for("Symbol.asyncDispose")],
kind = DisposeKind.AWAIT_USING_ASYNC_DISPOSE;
}
if (dispose === undefined) {
dispose = value[Symbol.dispose || Symbol.for("Symbol.dispose")];
kind &= DisposeFlag.ASYNC_DISPOSE_MASK;
}
if (typeof dispose !== "function") {
throw new TypeError("Object is not disposable.");
}
stack.push({ v: value, d: dispose, k: kind });
} else if (isAwait) {
// provide the nullish `value` as `d` for minification gain
stack.push({ d: value, k: DisposeKind.AWAIT_USING_DISPOSE });
}
return value;
}
return {
// error
e: empty,
// using
u: using.bind(null, false),
// await using
a: using.bind(null, true),
// dispose
d: function () {
var error = this.e;
function next(): any {
// eslint-disable-next-line @typescript-eslint/no-use-before-define
while ((resource = stack.pop())) {
try {
var resource,
disposalResult = resource.d && resource.d.call(resource.v);
if (resource.k) {
return Promise.resolve(
// do not await the promise returned from the sync @@dispose
resource.k & DisposeFlag.ASYNC_DISPOSE && disposalResult,
).then(next, err);
}
} catch (e) {
return err(e);
}
}
if (error !== empty) throw error;
}
function err(e: Error) {
error = error !== empty ? new _disposeSuppressedError(e, error) : e;
return next();
}
return next();
},
};
}