source: trip-planner-front/node_modules/on-finished/index.js@ ceaed42

Last change on this file since ceaed42 was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 3.6 KB
Line 
1/*!
2 * on-finished
3 * Copyright(c) 2013 Jonathan Ong
4 * Copyright(c) 2014 Douglas Christopher Wilson
5 * MIT Licensed
6 */
7
8'use strict'
9
10/**
11 * Module exports.
12 * @public
13 */
14
15module.exports = onFinished
16module.exports.isFinished = isFinished
17
18/**
19 * Module dependencies.
20 * @private
21 */
22
23var first = require('ee-first')
24
25/**
26 * Variables.
27 * @private
28 */
29
30/* istanbul ignore next */
31var defer = typeof setImmediate === 'function'
32 ? setImmediate
33 : function(fn){ process.nextTick(fn.bind.apply(fn, arguments)) }
34
35/**
36 * Invoke callback when the response has finished, useful for
37 * cleaning up resources afterwards.
38 *
39 * @param {object} msg
40 * @param {function} listener
41 * @return {object}
42 * @public
43 */
44
45function onFinished(msg, listener) {
46 if (isFinished(msg) !== false) {
47 defer(listener, null, msg)
48 return msg
49 }
50
51 // attach the listener to the message
52 attachListener(msg, listener)
53
54 return msg
55}
56
57/**
58 * Determine if message is already finished.
59 *
60 * @param {object} msg
61 * @return {boolean}
62 * @public
63 */
64
65function isFinished(msg) {
66 var socket = msg.socket
67
68 if (typeof msg.finished === 'boolean') {
69 // OutgoingMessage
70 return Boolean(msg.finished || (socket && !socket.writable))
71 }
72
73 if (typeof msg.complete === 'boolean') {
74 // IncomingMessage
75 return Boolean(msg.upgrade || !socket || !socket.readable || (msg.complete && !msg.readable))
76 }
77
78 // don't know
79 return undefined
80}
81
82/**
83 * Attach a finished listener to the message.
84 *
85 * @param {object} msg
86 * @param {function} callback
87 * @private
88 */
89
90function attachFinishedListener(msg, callback) {
91 var eeMsg
92 var eeSocket
93 var finished = false
94
95 function onFinish(error) {
96 eeMsg.cancel()
97 eeSocket.cancel()
98
99 finished = true
100 callback(error)
101 }
102
103 // finished on first message event
104 eeMsg = eeSocket = first([[msg, 'end', 'finish']], onFinish)
105
106 function onSocket(socket) {
107 // remove listener
108 msg.removeListener('socket', onSocket)
109
110 if (finished) return
111 if (eeMsg !== eeSocket) return
112
113 // finished on first socket event
114 eeSocket = first([[socket, 'error', 'close']], onFinish)
115 }
116
117 if (msg.socket) {
118 // socket already assigned
119 onSocket(msg.socket)
120 return
121 }
122
123 // wait for socket to be assigned
124 msg.on('socket', onSocket)
125
126 if (msg.socket === undefined) {
127 // node.js 0.8 patch
128 patchAssignSocket(msg, onSocket)
129 }
130}
131
132/**
133 * Attach the listener to the message.
134 *
135 * @param {object} msg
136 * @return {function}
137 * @private
138 */
139
140function attachListener(msg, listener) {
141 var attached = msg.__onFinished
142
143 // create a private single listener with queue
144 if (!attached || !attached.queue) {
145 attached = msg.__onFinished = createListener(msg)
146 attachFinishedListener(msg, attached)
147 }
148
149 attached.queue.push(listener)
150}
151
152/**
153 * Create listener on message.
154 *
155 * @param {object} msg
156 * @return {function}
157 * @private
158 */
159
160function createListener(msg) {
161 function listener(err) {
162 if (msg.__onFinished === listener) msg.__onFinished = null
163 if (!listener.queue) return
164
165 var queue = listener.queue
166 listener.queue = null
167
168 for (var i = 0; i < queue.length; i++) {
169 queue[i](err, msg)
170 }
171 }
172
173 listener.queue = []
174
175 return listener
176}
177
178/**
179 * Patch ServerResponse.prototype.assignSocket for node.js 0.8.
180 *
181 * @param {ServerResponse} res
182 * @param {function} callback
183 * @private
184 */
185
186function patchAssignSocket(res, callback) {
187 var assignSocket = res.assignSocket
188
189 if (typeof assignSocket !== 'function') return
190
191 // res.on('socket', callback) is broken in 0.8
192 res.assignSocket = function _assignSocket(socket) {
193 assignSocket.call(this, socket)
194 callback(socket)
195 }
196}
Note: See TracBrowser for help on using the repository browser.