11cb0ef41Sopenharmony_ci'use strict' 21cb0ef41Sopenharmony_ci 31cb0ef41Sopenharmony_ciconst Dispatcher = require('./dispatcher') 41cb0ef41Sopenharmony_ciconst { 51cb0ef41Sopenharmony_ci ClientDestroyedError, 61cb0ef41Sopenharmony_ci ClientClosedError, 71cb0ef41Sopenharmony_ci InvalidArgumentError 81cb0ef41Sopenharmony_ci} = require('./core/errors') 91cb0ef41Sopenharmony_ciconst { kDestroy, kClose, kDispatch, kInterceptors } = require('./core/symbols') 101cb0ef41Sopenharmony_ci 111cb0ef41Sopenharmony_ciconst kDestroyed = Symbol('destroyed') 121cb0ef41Sopenharmony_ciconst kClosed = Symbol('closed') 131cb0ef41Sopenharmony_ciconst kOnDestroyed = Symbol('onDestroyed') 141cb0ef41Sopenharmony_ciconst kOnClosed = Symbol('onClosed') 151cb0ef41Sopenharmony_ciconst kInterceptedDispatch = Symbol('Intercepted Dispatch') 161cb0ef41Sopenharmony_ci 171cb0ef41Sopenharmony_ciclass DispatcherBase extends Dispatcher { 181cb0ef41Sopenharmony_ci constructor () { 191cb0ef41Sopenharmony_ci super() 201cb0ef41Sopenharmony_ci 211cb0ef41Sopenharmony_ci this[kDestroyed] = false 221cb0ef41Sopenharmony_ci this[kOnDestroyed] = null 231cb0ef41Sopenharmony_ci this[kClosed] = false 241cb0ef41Sopenharmony_ci this[kOnClosed] = [] 251cb0ef41Sopenharmony_ci } 261cb0ef41Sopenharmony_ci 271cb0ef41Sopenharmony_ci get destroyed () { 281cb0ef41Sopenharmony_ci return this[kDestroyed] 291cb0ef41Sopenharmony_ci } 301cb0ef41Sopenharmony_ci 311cb0ef41Sopenharmony_ci get closed () { 321cb0ef41Sopenharmony_ci return this[kClosed] 331cb0ef41Sopenharmony_ci } 341cb0ef41Sopenharmony_ci 351cb0ef41Sopenharmony_ci get interceptors () { 361cb0ef41Sopenharmony_ci return this[kInterceptors] 371cb0ef41Sopenharmony_ci } 381cb0ef41Sopenharmony_ci 391cb0ef41Sopenharmony_ci set interceptors (newInterceptors) { 401cb0ef41Sopenharmony_ci if (newInterceptors) { 411cb0ef41Sopenharmony_ci for (let i = newInterceptors.length - 1; i >= 0; i--) { 421cb0ef41Sopenharmony_ci const interceptor = this[kInterceptors][i] 431cb0ef41Sopenharmony_ci if (typeof interceptor !== 'function') { 441cb0ef41Sopenharmony_ci throw new InvalidArgumentError('interceptor must be an function') 451cb0ef41Sopenharmony_ci } 461cb0ef41Sopenharmony_ci } 471cb0ef41Sopenharmony_ci } 481cb0ef41Sopenharmony_ci 491cb0ef41Sopenharmony_ci this[kInterceptors] = newInterceptors 501cb0ef41Sopenharmony_ci } 511cb0ef41Sopenharmony_ci 521cb0ef41Sopenharmony_ci close (callback) { 531cb0ef41Sopenharmony_ci if (callback === undefined) { 541cb0ef41Sopenharmony_ci return new Promise((resolve, reject) => { 551cb0ef41Sopenharmony_ci this.close((err, data) => { 561cb0ef41Sopenharmony_ci return err ? reject(err) : resolve(data) 571cb0ef41Sopenharmony_ci }) 581cb0ef41Sopenharmony_ci }) 591cb0ef41Sopenharmony_ci } 601cb0ef41Sopenharmony_ci 611cb0ef41Sopenharmony_ci if (typeof callback !== 'function') { 621cb0ef41Sopenharmony_ci throw new InvalidArgumentError('invalid callback') 631cb0ef41Sopenharmony_ci } 641cb0ef41Sopenharmony_ci 651cb0ef41Sopenharmony_ci if (this[kDestroyed]) { 661cb0ef41Sopenharmony_ci queueMicrotask(() => callback(new ClientDestroyedError(), null)) 671cb0ef41Sopenharmony_ci return 681cb0ef41Sopenharmony_ci } 691cb0ef41Sopenharmony_ci 701cb0ef41Sopenharmony_ci if (this[kClosed]) { 711cb0ef41Sopenharmony_ci if (this[kOnClosed]) { 721cb0ef41Sopenharmony_ci this[kOnClosed].push(callback) 731cb0ef41Sopenharmony_ci } else { 741cb0ef41Sopenharmony_ci queueMicrotask(() => callback(null, null)) 751cb0ef41Sopenharmony_ci } 761cb0ef41Sopenharmony_ci return 771cb0ef41Sopenharmony_ci } 781cb0ef41Sopenharmony_ci 791cb0ef41Sopenharmony_ci this[kClosed] = true 801cb0ef41Sopenharmony_ci this[kOnClosed].push(callback) 811cb0ef41Sopenharmony_ci 821cb0ef41Sopenharmony_ci const onClosed = () => { 831cb0ef41Sopenharmony_ci const callbacks = this[kOnClosed] 841cb0ef41Sopenharmony_ci this[kOnClosed] = null 851cb0ef41Sopenharmony_ci for (let i = 0; i < callbacks.length; i++) { 861cb0ef41Sopenharmony_ci callbacks[i](null, null) 871cb0ef41Sopenharmony_ci } 881cb0ef41Sopenharmony_ci } 891cb0ef41Sopenharmony_ci 901cb0ef41Sopenharmony_ci // Should not error. 911cb0ef41Sopenharmony_ci this[kClose]() 921cb0ef41Sopenharmony_ci .then(() => this.destroy()) 931cb0ef41Sopenharmony_ci .then(() => { 941cb0ef41Sopenharmony_ci queueMicrotask(onClosed) 951cb0ef41Sopenharmony_ci }) 961cb0ef41Sopenharmony_ci } 971cb0ef41Sopenharmony_ci 981cb0ef41Sopenharmony_ci destroy (err, callback) { 991cb0ef41Sopenharmony_ci if (typeof err === 'function') { 1001cb0ef41Sopenharmony_ci callback = err 1011cb0ef41Sopenharmony_ci err = null 1021cb0ef41Sopenharmony_ci } 1031cb0ef41Sopenharmony_ci 1041cb0ef41Sopenharmony_ci if (callback === undefined) { 1051cb0ef41Sopenharmony_ci return new Promise((resolve, reject) => { 1061cb0ef41Sopenharmony_ci this.destroy(err, (err, data) => { 1071cb0ef41Sopenharmony_ci return err ? /* istanbul ignore next: should never error */ reject(err) : resolve(data) 1081cb0ef41Sopenharmony_ci }) 1091cb0ef41Sopenharmony_ci }) 1101cb0ef41Sopenharmony_ci } 1111cb0ef41Sopenharmony_ci 1121cb0ef41Sopenharmony_ci if (typeof callback !== 'function') { 1131cb0ef41Sopenharmony_ci throw new InvalidArgumentError('invalid callback') 1141cb0ef41Sopenharmony_ci } 1151cb0ef41Sopenharmony_ci 1161cb0ef41Sopenharmony_ci if (this[kDestroyed]) { 1171cb0ef41Sopenharmony_ci if (this[kOnDestroyed]) { 1181cb0ef41Sopenharmony_ci this[kOnDestroyed].push(callback) 1191cb0ef41Sopenharmony_ci } else { 1201cb0ef41Sopenharmony_ci queueMicrotask(() => callback(null, null)) 1211cb0ef41Sopenharmony_ci } 1221cb0ef41Sopenharmony_ci return 1231cb0ef41Sopenharmony_ci } 1241cb0ef41Sopenharmony_ci 1251cb0ef41Sopenharmony_ci if (!err) { 1261cb0ef41Sopenharmony_ci err = new ClientDestroyedError() 1271cb0ef41Sopenharmony_ci } 1281cb0ef41Sopenharmony_ci 1291cb0ef41Sopenharmony_ci this[kDestroyed] = true 1301cb0ef41Sopenharmony_ci this[kOnDestroyed] = this[kOnDestroyed] || [] 1311cb0ef41Sopenharmony_ci this[kOnDestroyed].push(callback) 1321cb0ef41Sopenharmony_ci 1331cb0ef41Sopenharmony_ci const onDestroyed = () => { 1341cb0ef41Sopenharmony_ci const callbacks = this[kOnDestroyed] 1351cb0ef41Sopenharmony_ci this[kOnDestroyed] = null 1361cb0ef41Sopenharmony_ci for (let i = 0; i < callbacks.length; i++) { 1371cb0ef41Sopenharmony_ci callbacks[i](null, null) 1381cb0ef41Sopenharmony_ci } 1391cb0ef41Sopenharmony_ci } 1401cb0ef41Sopenharmony_ci 1411cb0ef41Sopenharmony_ci // Should not error. 1421cb0ef41Sopenharmony_ci this[kDestroy](err).then(() => { 1431cb0ef41Sopenharmony_ci queueMicrotask(onDestroyed) 1441cb0ef41Sopenharmony_ci }) 1451cb0ef41Sopenharmony_ci } 1461cb0ef41Sopenharmony_ci 1471cb0ef41Sopenharmony_ci [kInterceptedDispatch] (opts, handler) { 1481cb0ef41Sopenharmony_ci if (!this[kInterceptors] || this[kInterceptors].length === 0) { 1491cb0ef41Sopenharmony_ci this[kInterceptedDispatch] = this[kDispatch] 1501cb0ef41Sopenharmony_ci return this[kDispatch](opts, handler) 1511cb0ef41Sopenharmony_ci } 1521cb0ef41Sopenharmony_ci 1531cb0ef41Sopenharmony_ci let dispatch = this[kDispatch].bind(this) 1541cb0ef41Sopenharmony_ci for (let i = this[kInterceptors].length - 1; i >= 0; i--) { 1551cb0ef41Sopenharmony_ci dispatch = this[kInterceptors][i](dispatch) 1561cb0ef41Sopenharmony_ci } 1571cb0ef41Sopenharmony_ci this[kInterceptedDispatch] = dispatch 1581cb0ef41Sopenharmony_ci return dispatch(opts, handler) 1591cb0ef41Sopenharmony_ci } 1601cb0ef41Sopenharmony_ci 1611cb0ef41Sopenharmony_ci dispatch (opts, handler) { 1621cb0ef41Sopenharmony_ci if (!handler || typeof handler !== 'object') { 1631cb0ef41Sopenharmony_ci throw new InvalidArgumentError('handler must be an object') 1641cb0ef41Sopenharmony_ci } 1651cb0ef41Sopenharmony_ci 1661cb0ef41Sopenharmony_ci try { 1671cb0ef41Sopenharmony_ci if (!opts || typeof opts !== 'object') { 1681cb0ef41Sopenharmony_ci throw new InvalidArgumentError('opts must be an object.') 1691cb0ef41Sopenharmony_ci } 1701cb0ef41Sopenharmony_ci 1711cb0ef41Sopenharmony_ci if (this[kDestroyed] || this[kOnDestroyed]) { 1721cb0ef41Sopenharmony_ci throw new ClientDestroyedError() 1731cb0ef41Sopenharmony_ci } 1741cb0ef41Sopenharmony_ci 1751cb0ef41Sopenharmony_ci if (this[kClosed]) { 1761cb0ef41Sopenharmony_ci throw new ClientClosedError() 1771cb0ef41Sopenharmony_ci } 1781cb0ef41Sopenharmony_ci 1791cb0ef41Sopenharmony_ci return this[kInterceptedDispatch](opts, handler) 1801cb0ef41Sopenharmony_ci } catch (err) { 1811cb0ef41Sopenharmony_ci if (typeof handler.onError !== 'function') { 1821cb0ef41Sopenharmony_ci throw new InvalidArgumentError('invalid onError method') 1831cb0ef41Sopenharmony_ci } 1841cb0ef41Sopenharmony_ci 1851cb0ef41Sopenharmony_ci handler.onError(err) 1861cb0ef41Sopenharmony_ci 1871cb0ef41Sopenharmony_ci return false 1881cb0ef41Sopenharmony_ci } 1891cb0ef41Sopenharmony_ci } 1901cb0ef41Sopenharmony_ci} 1911cb0ef41Sopenharmony_ci 1921cb0ef41Sopenharmony_cimodule.exports = DispatcherBase 193