source: node_modules/undici/lib/dispatcher-base.js

main
Last change on this file was d24f17c, checked in by Aleksandar Panovski <apano77@…>, 15 months ago

Initial commit

  • Property mode set to 100644
File size: 4.5 KB
RevLine 
[d24f17c]1'use strict'
2
3const Dispatcher = require('./dispatcher')
4const {
5 ClientDestroyedError,
6 ClientClosedError,
7 InvalidArgumentError
8} = require('./core/errors')
9const { kDestroy, kClose, kDispatch, kInterceptors } = require('./core/symbols')
10
11const kDestroyed = Symbol('destroyed')
12const kClosed = Symbol('closed')
13const kOnDestroyed = Symbol('onDestroyed')
14const kOnClosed = Symbol('onClosed')
15const kInterceptedDispatch = Symbol('Intercepted Dispatch')
16
17class DispatcherBase extends Dispatcher {
18 constructor () {
19 super()
20
21 this[kDestroyed] = false
22 this[kOnDestroyed] = null
23 this[kClosed] = false
24 this[kOnClosed] = []
25 }
26
27 get destroyed () {
28 return this[kDestroyed]
29 }
30
31 get closed () {
32 return this[kClosed]
33 }
34
35 get interceptors () {
36 return this[kInterceptors]
37 }
38
39 set interceptors (newInterceptors) {
40 if (newInterceptors) {
41 for (let i = newInterceptors.length - 1; i >= 0; i--) {
42 const interceptor = this[kInterceptors][i]
43 if (typeof interceptor !== 'function') {
44 throw new InvalidArgumentError('interceptor must be an function')
45 }
46 }
47 }
48
49 this[kInterceptors] = newInterceptors
50 }
51
52 close (callback) {
53 if (callback === undefined) {
54 return new Promise((resolve, reject) => {
55 this.close((err, data) => {
56 return err ? reject(err) : resolve(data)
57 })
58 })
59 }
60
61 if (typeof callback !== 'function') {
62 throw new InvalidArgumentError('invalid callback')
63 }
64
65 if (this[kDestroyed]) {
66 queueMicrotask(() => callback(new ClientDestroyedError(), null))
67 return
68 }
69
70 if (this[kClosed]) {
71 if (this[kOnClosed]) {
72 this[kOnClosed].push(callback)
73 } else {
74 queueMicrotask(() => callback(null, null))
75 }
76 return
77 }
78
79 this[kClosed] = true
80 this[kOnClosed].push(callback)
81
82 const onClosed = () => {
83 const callbacks = this[kOnClosed]
84 this[kOnClosed] = null
85 for (let i = 0; i < callbacks.length; i++) {
86 callbacks[i](null, null)
87 }
88 }
89
90 // Should not error.
91 this[kClose]()
92 .then(() => this.destroy())
93 .then(() => {
94 queueMicrotask(onClosed)
95 })
96 }
97
98 destroy (err, callback) {
99 if (typeof err === 'function') {
100 callback = err
101 err = null
102 }
103
104 if (callback === undefined) {
105 return new Promise((resolve, reject) => {
106 this.destroy(err, (err, data) => {
107 return err ? /* istanbul ignore next: should never error */ reject(err) : resolve(data)
108 })
109 })
110 }
111
112 if (typeof callback !== 'function') {
113 throw new InvalidArgumentError('invalid callback')
114 }
115
116 if (this[kDestroyed]) {
117 if (this[kOnDestroyed]) {
118 this[kOnDestroyed].push(callback)
119 } else {
120 queueMicrotask(() => callback(null, null))
121 }
122 return
123 }
124
125 if (!err) {
126 err = new ClientDestroyedError()
127 }
128
129 this[kDestroyed] = true
130 this[kOnDestroyed] = this[kOnDestroyed] || []
131 this[kOnDestroyed].push(callback)
132
133 const onDestroyed = () => {
134 const callbacks = this[kOnDestroyed]
135 this[kOnDestroyed] = null
136 for (let i = 0; i < callbacks.length; i++) {
137 callbacks[i](null, null)
138 }
139 }
140
141 // Should not error.
142 this[kDestroy](err).then(() => {
143 queueMicrotask(onDestroyed)
144 })
145 }
146
147 [kInterceptedDispatch] (opts, handler) {
148 if (!this[kInterceptors] || this[kInterceptors].length === 0) {
149 this[kInterceptedDispatch] = this[kDispatch]
150 return this[kDispatch](opts, handler)
151 }
152
153 let dispatch = this[kDispatch].bind(this)
154 for (let i = this[kInterceptors].length - 1; i >= 0; i--) {
155 dispatch = this[kInterceptors][i](dispatch)
156 }
157 this[kInterceptedDispatch] = dispatch
158 return dispatch(opts, handler)
159 }
160
161 dispatch (opts, handler) {
162 if (!handler || typeof handler !== 'object') {
163 throw new InvalidArgumentError('handler must be an object')
164 }
165
166 try {
167 if (!opts || typeof opts !== 'object') {
168 throw new InvalidArgumentError('opts must be an object.')
169 }
170
171 if (this[kDestroyed] || this[kOnDestroyed]) {
172 throw new ClientDestroyedError()
173 }
174
175 if (this[kClosed]) {
176 throw new ClientClosedError()
177 }
178
179 return this[kInterceptedDispatch](opts, handler)
180 } catch (err) {
181 if (typeof handler.onError !== 'function') {
182 throw new InvalidArgumentError('invalid onError method')
183 }
184
185 handler.onError(err)
186
187 return false
188 }
189 }
190}
191
192module.exports = DispatcherBase
Note: See TracBrowser for help on using the repository browser.