11cb0ef41Sopenharmony_ci'use strict'; 21cb0ef41Sopenharmony_ci 31cb0ef41Sopenharmony_ciconst { 41cb0ef41Sopenharmony_ci ArrayPrototypeIndexOf, 51cb0ef41Sopenharmony_ci ArrayPrototypePush, 61cb0ef41Sopenharmony_ci ArrayPrototypeSplice, 71cb0ef41Sopenharmony_ci SafeFinalizationRegistry, 81cb0ef41Sopenharmony_ci ObjectGetPrototypeOf, 91cb0ef41Sopenharmony_ci ObjectSetPrototypeOf, 101cb0ef41Sopenharmony_ci Promise, 111cb0ef41Sopenharmony_ci PromisePrototypeThen, 121cb0ef41Sopenharmony_ci PromiseResolve, 131cb0ef41Sopenharmony_ci PromiseReject, 141cb0ef41Sopenharmony_ci ReflectApply, 151cb0ef41Sopenharmony_ci SafeMap, 161cb0ef41Sopenharmony_ci SymbolHasInstance, 171cb0ef41Sopenharmony_ci} = primordials; 181cb0ef41Sopenharmony_ci 191cb0ef41Sopenharmony_ciconst { 201cb0ef41Sopenharmony_ci codes: { 211cb0ef41Sopenharmony_ci ERR_INVALID_ARG_TYPE, 221cb0ef41Sopenharmony_ci }, 231cb0ef41Sopenharmony_ci} = require('internal/errors'); 241cb0ef41Sopenharmony_ciconst { 251cb0ef41Sopenharmony_ci validateFunction, 261cb0ef41Sopenharmony_ci} = require('internal/validators'); 271cb0ef41Sopenharmony_ci 281cb0ef41Sopenharmony_ciconst { triggerUncaughtException } = internalBinding('errors'); 291cb0ef41Sopenharmony_ci 301cb0ef41Sopenharmony_ciconst { WeakReference } = internalBinding('util'); 311cb0ef41Sopenharmony_ci 321cb0ef41Sopenharmony_ci// Can't delete when weakref count reaches 0 as it could increment again. 331cb0ef41Sopenharmony_ci// Only GC can be used as a valid time to clean up the channels map. 341cb0ef41Sopenharmony_ciclass WeakRefMap extends SafeMap { 351cb0ef41Sopenharmony_ci #finalizers = new SafeFinalizationRegistry((key) => { 361cb0ef41Sopenharmony_ci this.delete(key); 371cb0ef41Sopenharmony_ci }); 381cb0ef41Sopenharmony_ci 391cb0ef41Sopenharmony_ci set(key, value) { 401cb0ef41Sopenharmony_ci this.#finalizers.register(value, key); 411cb0ef41Sopenharmony_ci return super.set(key, new WeakReference(value)); 421cb0ef41Sopenharmony_ci } 431cb0ef41Sopenharmony_ci 441cb0ef41Sopenharmony_ci get(key) { 451cb0ef41Sopenharmony_ci return super.get(key)?.get(); 461cb0ef41Sopenharmony_ci } 471cb0ef41Sopenharmony_ci 481cb0ef41Sopenharmony_ci incRef(key) { 491cb0ef41Sopenharmony_ci return super.get(key)?.incRef(); 501cb0ef41Sopenharmony_ci } 511cb0ef41Sopenharmony_ci 521cb0ef41Sopenharmony_ci decRef(key) { 531cb0ef41Sopenharmony_ci return super.get(key)?.decRef(); 541cb0ef41Sopenharmony_ci } 551cb0ef41Sopenharmony_ci} 561cb0ef41Sopenharmony_ci 571cb0ef41Sopenharmony_cifunction markActive(channel) { 581cb0ef41Sopenharmony_ci // eslint-disable-next-line no-use-before-define 591cb0ef41Sopenharmony_ci ObjectSetPrototypeOf(channel, ActiveChannel.prototype); 601cb0ef41Sopenharmony_ci channel._subscribers = []; 611cb0ef41Sopenharmony_ci channel._stores = new SafeMap(); 621cb0ef41Sopenharmony_ci} 631cb0ef41Sopenharmony_ci 641cb0ef41Sopenharmony_cifunction maybeMarkInactive(channel) { 651cb0ef41Sopenharmony_ci // When there are no more active subscribers or bound, restore to fast prototype. 661cb0ef41Sopenharmony_ci if (!channel._subscribers.length && !channel._stores.size) { 671cb0ef41Sopenharmony_ci // eslint-disable-next-line no-use-before-define 681cb0ef41Sopenharmony_ci ObjectSetPrototypeOf(channel, Channel.prototype); 691cb0ef41Sopenharmony_ci channel._subscribers = undefined; 701cb0ef41Sopenharmony_ci channel._stores = undefined; 711cb0ef41Sopenharmony_ci } 721cb0ef41Sopenharmony_ci} 731cb0ef41Sopenharmony_ci 741cb0ef41Sopenharmony_cifunction defaultTransform(data) { 751cb0ef41Sopenharmony_ci return data; 761cb0ef41Sopenharmony_ci} 771cb0ef41Sopenharmony_ci 781cb0ef41Sopenharmony_cifunction wrapStoreRun(store, data, next, transform = defaultTransform) { 791cb0ef41Sopenharmony_ci return () => { 801cb0ef41Sopenharmony_ci let context; 811cb0ef41Sopenharmony_ci try { 821cb0ef41Sopenharmony_ci context = transform(data); 831cb0ef41Sopenharmony_ci } catch (err) { 841cb0ef41Sopenharmony_ci process.nextTick(() => { 851cb0ef41Sopenharmony_ci triggerUncaughtException(err, false); 861cb0ef41Sopenharmony_ci }); 871cb0ef41Sopenharmony_ci return next(); 881cb0ef41Sopenharmony_ci } 891cb0ef41Sopenharmony_ci 901cb0ef41Sopenharmony_ci return store.run(context, next); 911cb0ef41Sopenharmony_ci }; 921cb0ef41Sopenharmony_ci} 931cb0ef41Sopenharmony_ci 941cb0ef41Sopenharmony_ci// TODO(qard): should there be a C++ channel interface? 951cb0ef41Sopenharmony_ciclass ActiveChannel { 961cb0ef41Sopenharmony_ci subscribe(subscription) { 971cb0ef41Sopenharmony_ci validateFunction(subscription, 'subscription'); 981cb0ef41Sopenharmony_ci ArrayPrototypePush(this._subscribers, subscription); 991cb0ef41Sopenharmony_ci channels.incRef(this.name); 1001cb0ef41Sopenharmony_ci } 1011cb0ef41Sopenharmony_ci 1021cb0ef41Sopenharmony_ci unsubscribe(subscription) { 1031cb0ef41Sopenharmony_ci const index = ArrayPrototypeIndexOf(this._subscribers, subscription); 1041cb0ef41Sopenharmony_ci if (index === -1) return false; 1051cb0ef41Sopenharmony_ci 1061cb0ef41Sopenharmony_ci ArrayPrototypeSplice(this._subscribers, index, 1); 1071cb0ef41Sopenharmony_ci 1081cb0ef41Sopenharmony_ci channels.decRef(this.name); 1091cb0ef41Sopenharmony_ci maybeMarkInactive(this); 1101cb0ef41Sopenharmony_ci 1111cb0ef41Sopenharmony_ci return true; 1121cb0ef41Sopenharmony_ci } 1131cb0ef41Sopenharmony_ci 1141cb0ef41Sopenharmony_ci bindStore(store, transform) { 1151cb0ef41Sopenharmony_ci const replacing = this._stores.has(store); 1161cb0ef41Sopenharmony_ci if (!replacing) channels.incRef(this.name); 1171cb0ef41Sopenharmony_ci this._stores.set(store, transform); 1181cb0ef41Sopenharmony_ci } 1191cb0ef41Sopenharmony_ci 1201cb0ef41Sopenharmony_ci unbindStore(store) { 1211cb0ef41Sopenharmony_ci if (!this._stores.has(store)) { 1221cb0ef41Sopenharmony_ci return false; 1231cb0ef41Sopenharmony_ci } 1241cb0ef41Sopenharmony_ci 1251cb0ef41Sopenharmony_ci this._stores.delete(store); 1261cb0ef41Sopenharmony_ci 1271cb0ef41Sopenharmony_ci channels.decRef(this.name); 1281cb0ef41Sopenharmony_ci maybeMarkInactive(this); 1291cb0ef41Sopenharmony_ci 1301cb0ef41Sopenharmony_ci return true; 1311cb0ef41Sopenharmony_ci } 1321cb0ef41Sopenharmony_ci 1331cb0ef41Sopenharmony_ci get hasSubscribers() { 1341cb0ef41Sopenharmony_ci return true; 1351cb0ef41Sopenharmony_ci } 1361cb0ef41Sopenharmony_ci 1371cb0ef41Sopenharmony_ci publish(data) { 1381cb0ef41Sopenharmony_ci for (let i = 0; i < this._subscribers.length; i++) { 1391cb0ef41Sopenharmony_ci try { 1401cb0ef41Sopenharmony_ci const onMessage = this._subscribers[i]; 1411cb0ef41Sopenharmony_ci onMessage(data, this.name); 1421cb0ef41Sopenharmony_ci } catch (err) { 1431cb0ef41Sopenharmony_ci process.nextTick(() => { 1441cb0ef41Sopenharmony_ci triggerUncaughtException(err, false); 1451cb0ef41Sopenharmony_ci }); 1461cb0ef41Sopenharmony_ci } 1471cb0ef41Sopenharmony_ci } 1481cb0ef41Sopenharmony_ci } 1491cb0ef41Sopenharmony_ci 1501cb0ef41Sopenharmony_ci runStores(data, fn, thisArg, ...args) { 1511cb0ef41Sopenharmony_ci let run = () => { 1521cb0ef41Sopenharmony_ci this.publish(data); 1531cb0ef41Sopenharmony_ci return ReflectApply(fn, thisArg, args); 1541cb0ef41Sopenharmony_ci }; 1551cb0ef41Sopenharmony_ci 1561cb0ef41Sopenharmony_ci for (const entry of this._stores.entries()) { 1571cb0ef41Sopenharmony_ci const store = entry[0]; 1581cb0ef41Sopenharmony_ci const transform = entry[1]; 1591cb0ef41Sopenharmony_ci run = wrapStoreRun(store, data, run, transform); 1601cb0ef41Sopenharmony_ci } 1611cb0ef41Sopenharmony_ci 1621cb0ef41Sopenharmony_ci return run(); 1631cb0ef41Sopenharmony_ci } 1641cb0ef41Sopenharmony_ci} 1651cb0ef41Sopenharmony_ci 1661cb0ef41Sopenharmony_ciclass Channel { 1671cb0ef41Sopenharmony_ci constructor(name) { 1681cb0ef41Sopenharmony_ci this._subscribers = undefined; 1691cb0ef41Sopenharmony_ci this._stores = undefined; 1701cb0ef41Sopenharmony_ci this.name = name; 1711cb0ef41Sopenharmony_ci 1721cb0ef41Sopenharmony_ci channels.set(name, this); 1731cb0ef41Sopenharmony_ci } 1741cb0ef41Sopenharmony_ci 1751cb0ef41Sopenharmony_ci static [SymbolHasInstance](instance) { 1761cb0ef41Sopenharmony_ci const prototype = ObjectGetPrototypeOf(instance); 1771cb0ef41Sopenharmony_ci return prototype === Channel.prototype || 1781cb0ef41Sopenharmony_ci prototype === ActiveChannel.prototype; 1791cb0ef41Sopenharmony_ci } 1801cb0ef41Sopenharmony_ci 1811cb0ef41Sopenharmony_ci subscribe(subscription) { 1821cb0ef41Sopenharmony_ci markActive(this); 1831cb0ef41Sopenharmony_ci this.subscribe(subscription); 1841cb0ef41Sopenharmony_ci } 1851cb0ef41Sopenharmony_ci 1861cb0ef41Sopenharmony_ci unsubscribe() { 1871cb0ef41Sopenharmony_ci return false; 1881cb0ef41Sopenharmony_ci } 1891cb0ef41Sopenharmony_ci 1901cb0ef41Sopenharmony_ci bindStore(store, transform) { 1911cb0ef41Sopenharmony_ci markActive(this); 1921cb0ef41Sopenharmony_ci this.bindStore(store, transform); 1931cb0ef41Sopenharmony_ci } 1941cb0ef41Sopenharmony_ci 1951cb0ef41Sopenharmony_ci unbindStore() { 1961cb0ef41Sopenharmony_ci return false; 1971cb0ef41Sopenharmony_ci } 1981cb0ef41Sopenharmony_ci 1991cb0ef41Sopenharmony_ci get hasSubscribers() { 2001cb0ef41Sopenharmony_ci return false; 2011cb0ef41Sopenharmony_ci } 2021cb0ef41Sopenharmony_ci 2031cb0ef41Sopenharmony_ci publish() {} 2041cb0ef41Sopenharmony_ci 2051cb0ef41Sopenharmony_ci runStores(data, fn, thisArg, ...args) { 2061cb0ef41Sopenharmony_ci return ReflectApply(fn, thisArg, args); 2071cb0ef41Sopenharmony_ci } 2081cb0ef41Sopenharmony_ci} 2091cb0ef41Sopenharmony_ci 2101cb0ef41Sopenharmony_ciconst channels = new WeakRefMap(); 2111cb0ef41Sopenharmony_ci 2121cb0ef41Sopenharmony_cifunction channel(name) { 2131cb0ef41Sopenharmony_ci const channel = channels.get(name); 2141cb0ef41Sopenharmony_ci if (channel) return channel; 2151cb0ef41Sopenharmony_ci 2161cb0ef41Sopenharmony_ci if (typeof name !== 'string' && typeof name !== 'symbol') { 2171cb0ef41Sopenharmony_ci throw new ERR_INVALID_ARG_TYPE('channel', ['string', 'symbol'], name); 2181cb0ef41Sopenharmony_ci } 2191cb0ef41Sopenharmony_ci 2201cb0ef41Sopenharmony_ci return new Channel(name); 2211cb0ef41Sopenharmony_ci} 2221cb0ef41Sopenharmony_ci 2231cb0ef41Sopenharmony_cifunction subscribe(name, subscription) { 2241cb0ef41Sopenharmony_ci return channel(name).subscribe(subscription); 2251cb0ef41Sopenharmony_ci} 2261cb0ef41Sopenharmony_ci 2271cb0ef41Sopenharmony_cifunction unsubscribe(name, subscription) { 2281cb0ef41Sopenharmony_ci return channel(name).unsubscribe(subscription); 2291cb0ef41Sopenharmony_ci} 2301cb0ef41Sopenharmony_ci 2311cb0ef41Sopenharmony_cifunction hasSubscribers(name) { 2321cb0ef41Sopenharmony_ci const channel = channels.get(name); 2331cb0ef41Sopenharmony_ci if (!channel) return false; 2341cb0ef41Sopenharmony_ci 2351cb0ef41Sopenharmony_ci return channel.hasSubscribers; 2361cb0ef41Sopenharmony_ci} 2371cb0ef41Sopenharmony_ci 2381cb0ef41Sopenharmony_ciconst traceEvents = [ 2391cb0ef41Sopenharmony_ci 'start', 2401cb0ef41Sopenharmony_ci 'end', 2411cb0ef41Sopenharmony_ci 'asyncStart', 2421cb0ef41Sopenharmony_ci 'asyncEnd', 2431cb0ef41Sopenharmony_ci 'error', 2441cb0ef41Sopenharmony_ci]; 2451cb0ef41Sopenharmony_ci 2461cb0ef41Sopenharmony_cifunction assertChannel(value, name) { 2471cb0ef41Sopenharmony_ci if (!(value instanceof Channel)) { 2481cb0ef41Sopenharmony_ci throw new ERR_INVALID_ARG_TYPE(name, ['Channel'], value); 2491cb0ef41Sopenharmony_ci } 2501cb0ef41Sopenharmony_ci} 2511cb0ef41Sopenharmony_ci 2521cb0ef41Sopenharmony_ciclass TracingChannel { 2531cb0ef41Sopenharmony_ci constructor(nameOrChannels) { 2541cb0ef41Sopenharmony_ci if (typeof nameOrChannels === 'string') { 2551cb0ef41Sopenharmony_ci this.start = channel(`tracing:${nameOrChannels}:start`); 2561cb0ef41Sopenharmony_ci this.end = channel(`tracing:${nameOrChannels}:end`); 2571cb0ef41Sopenharmony_ci this.asyncStart = channel(`tracing:${nameOrChannels}:asyncStart`); 2581cb0ef41Sopenharmony_ci this.asyncEnd = channel(`tracing:${nameOrChannels}:asyncEnd`); 2591cb0ef41Sopenharmony_ci this.error = channel(`tracing:${nameOrChannels}:error`); 2601cb0ef41Sopenharmony_ci } else if (typeof nameOrChannels === 'object') { 2611cb0ef41Sopenharmony_ci const { start, end, asyncStart, asyncEnd, error } = nameOrChannels; 2621cb0ef41Sopenharmony_ci 2631cb0ef41Sopenharmony_ci assertChannel(start, 'nameOrChannels.start'); 2641cb0ef41Sopenharmony_ci assertChannel(end, 'nameOrChannels.end'); 2651cb0ef41Sopenharmony_ci assertChannel(asyncStart, 'nameOrChannels.asyncStart'); 2661cb0ef41Sopenharmony_ci assertChannel(asyncEnd, 'nameOrChannels.asyncEnd'); 2671cb0ef41Sopenharmony_ci assertChannel(error, 'nameOrChannels.error'); 2681cb0ef41Sopenharmony_ci 2691cb0ef41Sopenharmony_ci this.start = start; 2701cb0ef41Sopenharmony_ci this.end = end; 2711cb0ef41Sopenharmony_ci this.asyncStart = asyncStart; 2721cb0ef41Sopenharmony_ci this.asyncEnd = asyncEnd; 2731cb0ef41Sopenharmony_ci this.error = error; 2741cb0ef41Sopenharmony_ci } else { 2751cb0ef41Sopenharmony_ci throw new ERR_INVALID_ARG_TYPE('nameOrChannels', 2761cb0ef41Sopenharmony_ci ['string', 'object', 'Channel'], 2771cb0ef41Sopenharmony_ci nameOrChannels); 2781cb0ef41Sopenharmony_ci } 2791cb0ef41Sopenharmony_ci } 2801cb0ef41Sopenharmony_ci 2811cb0ef41Sopenharmony_ci subscribe(handlers) { 2821cb0ef41Sopenharmony_ci for (const name of traceEvents) { 2831cb0ef41Sopenharmony_ci if (!handlers[name]) continue; 2841cb0ef41Sopenharmony_ci 2851cb0ef41Sopenharmony_ci this[name]?.subscribe(handlers[name]); 2861cb0ef41Sopenharmony_ci } 2871cb0ef41Sopenharmony_ci } 2881cb0ef41Sopenharmony_ci 2891cb0ef41Sopenharmony_ci unsubscribe(handlers) { 2901cb0ef41Sopenharmony_ci let done = true; 2911cb0ef41Sopenharmony_ci 2921cb0ef41Sopenharmony_ci for (const name of traceEvents) { 2931cb0ef41Sopenharmony_ci if (!handlers[name]) continue; 2941cb0ef41Sopenharmony_ci 2951cb0ef41Sopenharmony_ci if (!this[name]?.unsubscribe(handlers[name])) { 2961cb0ef41Sopenharmony_ci done = false; 2971cb0ef41Sopenharmony_ci } 2981cb0ef41Sopenharmony_ci } 2991cb0ef41Sopenharmony_ci 3001cb0ef41Sopenharmony_ci return done; 3011cb0ef41Sopenharmony_ci } 3021cb0ef41Sopenharmony_ci 3031cb0ef41Sopenharmony_ci traceSync(fn, context = {}, thisArg, ...args) { 3041cb0ef41Sopenharmony_ci const { start, end, error } = this; 3051cb0ef41Sopenharmony_ci 3061cb0ef41Sopenharmony_ci return start.runStores(context, () => { 3071cb0ef41Sopenharmony_ci try { 3081cb0ef41Sopenharmony_ci const result = ReflectApply(fn, thisArg, args); 3091cb0ef41Sopenharmony_ci context.result = result; 3101cb0ef41Sopenharmony_ci return result; 3111cb0ef41Sopenharmony_ci } catch (err) { 3121cb0ef41Sopenharmony_ci context.error = err; 3131cb0ef41Sopenharmony_ci error.publish(context); 3141cb0ef41Sopenharmony_ci throw err; 3151cb0ef41Sopenharmony_ci } finally { 3161cb0ef41Sopenharmony_ci end.publish(context); 3171cb0ef41Sopenharmony_ci } 3181cb0ef41Sopenharmony_ci }); 3191cb0ef41Sopenharmony_ci } 3201cb0ef41Sopenharmony_ci 3211cb0ef41Sopenharmony_ci tracePromise(fn, context = {}, thisArg, ...args) { 3221cb0ef41Sopenharmony_ci const { start, end, asyncStart, asyncEnd, error } = this; 3231cb0ef41Sopenharmony_ci 3241cb0ef41Sopenharmony_ci function reject(err) { 3251cb0ef41Sopenharmony_ci context.error = err; 3261cb0ef41Sopenharmony_ci error.publish(context); 3271cb0ef41Sopenharmony_ci asyncStart.publish(context); 3281cb0ef41Sopenharmony_ci // TODO: Is there a way to have asyncEnd _after_ the continuation? 3291cb0ef41Sopenharmony_ci asyncEnd.publish(context); 3301cb0ef41Sopenharmony_ci return PromiseReject(err); 3311cb0ef41Sopenharmony_ci } 3321cb0ef41Sopenharmony_ci 3331cb0ef41Sopenharmony_ci function resolve(result) { 3341cb0ef41Sopenharmony_ci context.result = result; 3351cb0ef41Sopenharmony_ci asyncStart.publish(context); 3361cb0ef41Sopenharmony_ci // TODO: Is there a way to have asyncEnd _after_ the continuation? 3371cb0ef41Sopenharmony_ci asyncEnd.publish(context); 3381cb0ef41Sopenharmony_ci return result; 3391cb0ef41Sopenharmony_ci } 3401cb0ef41Sopenharmony_ci 3411cb0ef41Sopenharmony_ci return start.runStores(context, () => { 3421cb0ef41Sopenharmony_ci try { 3431cb0ef41Sopenharmony_ci let promise = ReflectApply(fn, thisArg, args); 3441cb0ef41Sopenharmony_ci // Convert thenables to native promises 3451cb0ef41Sopenharmony_ci if (!(promise instanceof Promise)) { 3461cb0ef41Sopenharmony_ci promise = PromiseResolve(promise); 3471cb0ef41Sopenharmony_ci } 3481cb0ef41Sopenharmony_ci return PromisePrototypeThen(promise, resolve, reject); 3491cb0ef41Sopenharmony_ci } catch (err) { 3501cb0ef41Sopenharmony_ci context.error = err; 3511cb0ef41Sopenharmony_ci error.publish(context); 3521cb0ef41Sopenharmony_ci throw err; 3531cb0ef41Sopenharmony_ci } finally { 3541cb0ef41Sopenharmony_ci end.publish(context); 3551cb0ef41Sopenharmony_ci } 3561cb0ef41Sopenharmony_ci }); 3571cb0ef41Sopenharmony_ci } 3581cb0ef41Sopenharmony_ci 3591cb0ef41Sopenharmony_ci traceCallback(fn, position = -1, context = {}, thisArg, ...args) { 3601cb0ef41Sopenharmony_ci const { start, end, asyncStart, asyncEnd, error } = this; 3611cb0ef41Sopenharmony_ci 3621cb0ef41Sopenharmony_ci function wrappedCallback(err, res) { 3631cb0ef41Sopenharmony_ci if (err) { 3641cb0ef41Sopenharmony_ci context.error = err; 3651cb0ef41Sopenharmony_ci error.publish(context); 3661cb0ef41Sopenharmony_ci } else { 3671cb0ef41Sopenharmony_ci context.result = res; 3681cb0ef41Sopenharmony_ci } 3691cb0ef41Sopenharmony_ci 3701cb0ef41Sopenharmony_ci // Using runStores here enables manual context failure recovery 3711cb0ef41Sopenharmony_ci asyncStart.runStores(context, () => { 3721cb0ef41Sopenharmony_ci try { 3731cb0ef41Sopenharmony_ci if (callback) { 3741cb0ef41Sopenharmony_ci return ReflectApply(callback, this, arguments); 3751cb0ef41Sopenharmony_ci } 3761cb0ef41Sopenharmony_ci } finally { 3771cb0ef41Sopenharmony_ci asyncEnd.publish(context); 3781cb0ef41Sopenharmony_ci } 3791cb0ef41Sopenharmony_ci }); 3801cb0ef41Sopenharmony_ci } 3811cb0ef41Sopenharmony_ci 3821cb0ef41Sopenharmony_ci const callback = args.at(position); 3831cb0ef41Sopenharmony_ci if (typeof callback !== 'function') { 3841cb0ef41Sopenharmony_ci throw new ERR_INVALID_ARG_TYPE('callback', ['function'], callback); 3851cb0ef41Sopenharmony_ci } 3861cb0ef41Sopenharmony_ci ArrayPrototypeSplice(args, position, 1, wrappedCallback); 3871cb0ef41Sopenharmony_ci 3881cb0ef41Sopenharmony_ci return start.runStores(context, () => { 3891cb0ef41Sopenharmony_ci try { 3901cb0ef41Sopenharmony_ci return ReflectApply(fn, thisArg, args); 3911cb0ef41Sopenharmony_ci } catch (err) { 3921cb0ef41Sopenharmony_ci context.error = err; 3931cb0ef41Sopenharmony_ci error.publish(context); 3941cb0ef41Sopenharmony_ci throw err; 3951cb0ef41Sopenharmony_ci } finally { 3961cb0ef41Sopenharmony_ci end.publish(context); 3971cb0ef41Sopenharmony_ci } 3981cb0ef41Sopenharmony_ci }); 3991cb0ef41Sopenharmony_ci } 4001cb0ef41Sopenharmony_ci} 4011cb0ef41Sopenharmony_ci 4021cb0ef41Sopenharmony_cifunction tracingChannel(nameOrChannels) { 4031cb0ef41Sopenharmony_ci return new TracingChannel(nameOrChannels); 4041cb0ef41Sopenharmony_ci} 4051cb0ef41Sopenharmony_ci 4061cb0ef41Sopenharmony_cimodule.exports = { 4071cb0ef41Sopenharmony_ci channel, 4081cb0ef41Sopenharmony_ci hasSubscribers, 4091cb0ef41Sopenharmony_ci subscribe, 4101cb0ef41Sopenharmony_ci tracingChannel, 4111cb0ef41Sopenharmony_ci unsubscribe, 4121cb0ef41Sopenharmony_ci Channel, 4131cb0ef41Sopenharmony_ci}; 414