generated from githuhsername/simple-template-advanced
-
Notifications
You must be signed in to change notification settings - Fork 0
/
esnext.async-disposable-stack.constructor.js
130 lines (114 loc) · 4.6 KB
/
esnext.async-disposable-stack.constructor.js
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
'use strict';
// https://github.com/tc39/proposal-async-explicit-resource-management
var $ = require('../internals/export');
var DESCRIPTORS = require('../internals/descriptors');
var getBuiltIn = require('../internals/get-built-in');
var aCallable = require('../internals/a-callable');
var anInstance = require('../internals/an-instance');
var defineBuiltIn = require('../internals/define-built-in');
var defineBuiltIns = require('../internals/define-built-ins');
var defineBuiltInAccessor = require('../internals/define-built-in-accessor');
var wellKnownSymbol = require('../internals/well-known-symbol');
var InternalStateModule = require('../internals/internal-state');
var addDisposableResource = require('../internals/add-disposable-resource');
var Promise = getBuiltIn('Promise');
var SuppressedError = getBuiltIn('SuppressedError');
var $ReferenceError = ReferenceError;
var ASYNC_DISPOSE = wellKnownSymbol('asyncDispose');
var TO_STRING_TAG = wellKnownSymbol('toStringTag');
var ASYNC_DISPOSABLE_STACK = 'AsyncDisposableStack';
var setInternalState = InternalStateModule.set;
var getAsyncDisposableStackInternalState = InternalStateModule.getterFor(ASYNC_DISPOSABLE_STACK);
var HINT = 'async-dispose';
var DISPOSED = 'disposed';
var PENDING = 'pending';
var getPendingAsyncDisposableStackInternalState = function (stack) {
var internalState = getAsyncDisposableStackInternalState(stack);
if (internalState.state === DISPOSED) throw new $ReferenceError(ASYNC_DISPOSABLE_STACK + ' already disposed');
return internalState;
};
var $AsyncDisposableStack = function AsyncDisposableStack() {
setInternalState(anInstance(this, AsyncDisposableStackPrototype), {
type: ASYNC_DISPOSABLE_STACK,
state: PENDING,
stack: []
});
if (!DESCRIPTORS) this.disposed = false;
};
var AsyncDisposableStackPrototype = $AsyncDisposableStack.prototype;
defineBuiltIns(AsyncDisposableStackPrototype, {
disposeAsync: function disposeAsync() {
var asyncDisposableStack = this;
return new Promise(function (resolve, reject) {
var internalState = getAsyncDisposableStackInternalState(asyncDisposableStack);
if (internalState.state === DISPOSED) return resolve(undefined);
internalState.state = DISPOSED;
if (!DESCRIPTORS) asyncDisposableStack.disposed = true;
var stack = internalState.stack;
var i = stack.length;
var thrown = false;
var suppressed;
var handleError = function (result) {
if (thrown) {
suppressed = new SuppressedError(result, suppressed);
} else {
thrown = true;
suppressed = result;
}
loop();
};
var loop = function () {
if (i) {
var disposeMethod = stack[--i];
stack[i] = undefined;
try {
Promise.resolve(disposeMethod()).then(loop, handleError);
} catch (error) {
handleError(error);
}
} else {
internalState.stack = undefined;
thrown ? reject(suppressed) : resolve(undefined);
}
};
loop();
});
},
use: function use(value) {
addDisposableResource(getPendingAsyncDisposableStackInternalState(this), value, HINT);
return value;
},
adopt: function adopt(value, onDispose) {
var internalState = getPendingAsyncDisposableStackInternalState(this);
aCallable(onDispose);
addDisposableResource(internalState, undefined, HINT, function () {
return onDispose(value);
});
return value;
},
defer: function defer(onDispose) {
var internalState = getPendingAsyncDisposableStackInternalState(this);
aCallable(onDispose);
addDisposableResource(internalState, undefined, HINT, onDispose);
},
move: function move() {
var internalState = getPendingAsyncDisposableStackInternalState(this);
var newAsyncDisposableStack = new $AsyncDisposableStack();
getAsyncDisposableStackInternalState(newAsyncDisposableStack).stack = internalState.stack;
internalState.stack = [];
internalState.state = DISPOSED;
if (!DESCRIPTORS) this.disposed = true;
return newAsyncDisposableStack;
}
});
if (DESCRIPTORS) defineBuiltInAccessor(AsyncDisposableStackPrototype, 'disposed', {
configurable: true,
get: function disposed() {
return getAsyncDisposableStackInternalState(this).state === DISPOSED;
}
});
defineBuiltIn(AsyncDisposableStackPrototype, ASYNC_DISPOSE, AsyncDisposableStackPrototype.disposeAsync, { name: 'disposeAsync' });
defineBuiltIn(AsyncDisposableStackPrototype, TO_STRING_TAG, ASYNC_DISPOSABLE_STACK, { nonWritable: true });
$({ global: true, constructor: true }, {
AsyncDisposableStack: $AsyncDisposableStack
});