forked from skozin/nyc-babel-issue-repro
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
106 lines (85 loc) · 2.27 KB
/
index.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
export const STATE_NORMAL = 0
export const STATE_WAITING_FOR_PUBLISHER = 1
export const STATE_CLOSING = 2
export const STATE_CLOSED = 3
export const TYPE_VALUE = 0
export const TYPE_ERROR = 1
export const CLOSED = {}
export const FAILED = {}
export class Chan {
constructor() {
this._state = STATE_WAITING_FOR_PUBLISHER
this._buffer = []
}
take(passResolve, passReject, needsCancelFn) {
return new Promise(resolve => {
this._take(
passResolve ? resolve : undefined,
passReject ? resolve : undefined,
needsCancelFn)
})
}
_take(fnVal, fnErr, needsCancelFn) {
if (this._state == STATE_CLOSED) {
fnVal && fnVal(CLOSED)
return nop
}
let prevState = this._state
if (prevState != STATE_WAITING_FOR_PUBLISHER) {
let item = this._takeFromWaitingPublisher()
if (item === FAILED) {
if (this._state == STATE_CLOSED) {
fnVal && fnVal(CLOSED)
return nop
}
} else {
assert(item.type == TYPE_VALUE || item.type == TYPE_ERROR)
let fn = item.type == TYPE_VALUE ? fnVal : fnErr
item.fnVal && item.fnVal()
fn && fn(item.value)
if (this._state != STATE_CLOSED) {
this._triggerWaiters(true)
}
return nop
}
}
assert(this._state == STATE_WAITING_FOR_PUBLISHER)
let item = { fnVal, fnErr }
let buf = []
buf.push(item)
if (prevState == STATE_NORMAL) {
// notify all waiters for the opportunity to publish
this._triggerWaiters(true)
this._emitDrain()
}
return needsCancelFn ? () => { item.fnVal = item.fnErr = undefined } : nop
}
_takeFromWaitingPublisher() {
assert(this._state == STATE_NORMAL || this._state == STATE_CLOSING)
let len = this._buffer.length
if (len == 0) {
this._state = STATE_WAITING_FOR_PUBLISHER
return FAILED
}
let item = this._buffer.shift()
--len
assert(item != undefined)
assert(item.type == TYPE_VALUE || item.type == TYPE_ERROR)
if (item.type == TYPE_VALUE) {
this._value = item.value
}
return item
}
_triggerWaiters() {
return undefined
}
_emitDrain() {
return undefined
}
}
function assert() {
return undefined
}
function nop() {
return undefined
}