fatsify核心功能示例测试!!!
This commit is contained in:
45
node_modules/avvio/lib/create-promise.js
generated
vendored
Normal file
45
node_modules/avvio/lib/create-promise.js
generated
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
'use strict'
|
||||
|
||||
/**
|
||||
* @callback PromiseResolve
|
||||
* @param {any|PromiseLike<any>} value
|
||||
* @returns {void}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback PromiseReject
|
||||
* @param {any} reason
|
||||
* @returns {void}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef PromiseObject
|
||||
* @property {Promise} promise
|
||||
* @property {PromiseResolve} resolve
|
||||
* @property {PromiseReject} reject
|
||||
*/
|
||||
|
||||
/**
|
||||
* @returns {PromiseObject}
|
||||
*/
|
||||
function createPromise () {
|
||||
/**
|
||||
* @type {PromiseObject}
|
||||
*/
|
||||
const obj = {
|
||||
resolve: null,
|
||||
reject: null,
|
||||
promise: null
|
||||
}
|
||||
|
||||
obj.promise = new Promise((resolve, reject) => {
|
||||
obj.resolve = resolve
|
||||
obj.reject = reject
|
||||
})
|
||||
|
||||
return obj
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
createPromise
|
||||
}
|
||||
19
node_modules/avvio/lib/debug.js
generated
vendored
Normal file
19
node_modules/avvio/lib/debug.js
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
'use strict'
|
||||
|
||||
const { debuglog } = require('node:util')
|
||||
|
||||
/**
|
||||
* @callback DebugLogger
|
||||
* @param {string} msg
|
||||
* @param {...unknown} param
|
||||
* @returns {void}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @type {DebugLogger}
|
||||
*/
|
||||
const debug = debuglog('avvio')
|
||||
|
||||
module.exports = {
|
||||
debug
|
||||
}
|
||||
38
node_modules/avvio/lib/errors.js
generated
vendored
Normal file
38
node_modules/avvio/lib/errors.js
generated
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
'use strict'
|
||||
|
||||
const { createError } = require('@fastify/error')
|
||||
|
||||
module.exports = {
|
||||
AVV_ERR_EXPOSE_ALREADY_DEFINED: createError(
|
||||
'AVV_ERR_EXPOSE_ALREADY_DEFINED',
|
||||
"'%s' is already defined, specify an expose option for '%s'"
|
||||
),
|
||||
AVV_ERR_ATTRIBUTE_ALREADY_DEFINED: createError(
|
||||
'AVV_ERR_ATTRIBUTE_ALREADY_DEFINED',
|
||||
"'%s' is already defined"
|
||||
),
|
||||
AVV_ERR_CALLBACK_NOT_FN: createError(
|
||||
'AVV_ERR_CALLBACK_NOT_FN',
|
||||
"Callback for '%s' hook is not a function. Received: '%s'"
|
||||
),
|
||||
AVV_ERR_PLUGIN_NOT_VALID: createError(
|
||||
'AVV_ERR_PLUGIN_NOT_VALID',
|
||||
"Plugin must be a function or a promise. Received: '%s'"
|
||||
),
|
||||
AVV_ERR_ROOT_PLG_BOOTED: createError(
|
||||
'AVV_ERR_ROOT_PLG_BOOTED',
|
||||
'Root plugin has already booted'
|
||||
),
|
||||
AVV_ERR_PARENT_PLG_LOADED: createError(
|
||||
'AVV_ERR_PARENT_PLG_LOADED',
|
||||
"Impossible to load '%s' plugin because the parent '%s' was already loaded"
|
||||
),
|
||||
AVV_ERR_READY_TIMEOUT: createError(
|
||||
'AVV_ERR_READY_TIMEOUT',
|
||||
"Plugin did not start in time: '%s'. You may have forgotten to call 'done' function or to resolve a Promise"
|
||||
),
|
||||
AVV_ERR_PLUGIN_EXEC_TIMEOUT: createError(
|
||||
'AVV_ERR_PLUGIN_EXEC_TIMEOUT',
|
||||
"Plugin did not start in time: '%s'. You may have forgotten to call 'done' function or to resolve a Promise"
|
||||
)
|
||||
}
|
||||
28
node_modules/avvio/lib/execute-with-thenable.js
generated
vendored
Normal file
28
node_modules/avvio/lib/execute-with-thenable.js
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
'use strict'
|
||||
const { isPromiseLike } = require('./is-promise-like')
|
||||
const { kAvvio } = require('./symbols')
|
||||
|
||||
/**
|
||||
* @callback ExecuteWithThenableCallback
|
||||
* @param {Error} error
|
||||
* @returns {void}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {Function} func
|
||||
* @param {Array<any>} args
|
||||
* @param {ExecuteWithThenableCallback} [callback]
|
||||
*/
|
||||
function executeWithThenable (func, args, callback) {
|
||||
const result = func.apply(func, args)
|
||||
if (isPromiseLike(result) && !result[kAvvio]) {
|
||||
// process promise but not avvio mock thenable
|
||||
result.then(() => process.nextTick(callback), (error) => process.nextTick(callback, error))
|
||||
} else if (callback) {
|
||||
process.nextTick(callback)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
executeWithThenable
|
||||
}
|
||||
34
node_modules/avvio/lib/get-plugin-name.js
generated
vendored
Normal file
34
node_modules/avvio/lib/get-plugin-name.js
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
'use strict'
|
||||
|
||||
// this symbol is assigned by fastify-plugin
|
||||
const { kPluginMeta } = require('./symbols')
|
||||
|
||||
/**
|
||||
* @param {function} plugin
|
||||
* @param {object} [options]
|
||||
* @param {string} [options.name]
|
||||
* @returns {string}
|
||||
*/
|
||||
function getPluginName (plugin, options) {
|
||||
// use explicit function metadata if set
|
||||
if (plugin[kPluginMeta] && plugin[kPluginMeta].name) {
|
||||
return plugin[kPluginMeta].name
|
||||
}
|
||||
|
||||
// use explicit name option if set
|
||||
if (options && options.name) {
|
||||
return options.name
|
||||
}
|
||||
|
||||
// determine from the function
|
||||
if (plugin.name) {
|
||||
return plugin.name
|
||||
} else {
|
||||
// takes the first two lines of the function if nothing else works
|
||||
return plugin.toString().split('\n').slice(0, 2).map(s => s.trim()).join(' -- ')
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getPluginName
|
||||
}
|
||||
23
node_modules/avvio/lib/is-bundled-or-typescript-plugin.js
generated
vendored
Normal file
23
node_modules/avvio/lib/is-bundled-or-typescript-plugin.js
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
'use strict'
|
||||
|
||||
/**
|
||||
* bundled or typescript plugin
|
||||
* @typedef {object} BundledOrTypescriptPlugin
|
||||
* @property {function} default
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {any} maybeBundledOrTypescriptPlugin
|
||||
* @returns {plugin is BundledOrTypescriptPlugin}
|
||||
*/
|
||||
function isBundledOrTypescriptPlugin (maybeBundledOrTypescriptPlugin) {
|
||||
return (
|
||||
maybeBundledOrTypescriptPlugin !== null &&
|
||||
typeof maybeBundledOrTypescriptPlugin === 'object' &&
|
||||
typeof maybeBundledOrTypescriptPlugin.default === 'function'
|
||||
)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
isBundledOrTypescriptPlugin
|
||||
}
|
||||
17
node_modules/avvio/lib/is-promise-like.js
generated
vendored
Normal file
17
node_modules/avvio/lib/is-promise-like.js
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
'use strict'
|
||||
|
||||
/**
|
||||
* @param {any} maybePromiseLike
|
||||
* @returns {maybePromiseLike is PromiseLike}
|
||||
*/
|
||||
function isPromiseLike (maybePromiseLike) {
|
||||
return (
|
||||
maybePromiseLike !== null &&
|
||||
typeof maybePromiseLike === 'object' &&
|
||||
typeof maybePromiseLike.then === 'function'
|
||||
)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
isPromiseLike
|
||||
}
|
||||
279
node_modules/avvio/lib/plugin.js
generated
vendored
Normal file
279
node_modules/avvio/lib/plugin.js
generated
vendored
Normal file
@@ -0,0 +1,279 @@
|
||||
'use strict'
|
||||
|
||||
const { EventEmitter } = require('node:events')
|
||||
const { inherits } = require('node:util')
|
||||
const { debug } = require('./debug')
|
||||
const { createPromise } = require('./create-promise')
|
||||
const { AVV_ERR_PLUGIN_EXEC_TIMEOUT } = require('./errors')
|
||||
const { getPluginName } = require('./get-plugin-name')
|
||||
const { isPromiseLike } = require('./is-promise-like')
|
||||
|
||||
/**
|
||||
* @param {*} queue
|
||||
* @param {*} func
|
||||
* @param {*} options
|
||||
* @param {boolean} isAfter
|
||||
* @param {number} [timeout]
|
||||
*/
|
||||
function Plugin (queue, func, options, isAfter, timeout) {
|
||||
this.queue = queue
|
||||
this.func = func
|
||||
this.options = options
|
||||
|
||||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.isAfter = isAfter
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.timeout = timeout
|
||||
|
||||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.started = false
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
this.name = getPluginName(func, options)
|
||||
|
||||
this.queue.pause()
|
||||
|
||||
/**
|
||||
* @type {Error|null}
|
||||
*/
|
||||
this._error = null
|
||||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.loaded = false
|
||||
|
||||
this._promise = null
|
||||
|
||||
this.startTime = null
|
||||
}
|
||||
|
||||
inherits(Plugin, EventEmitter)
|
||||
|
||||
/**
|
||||
* @callback ExecCallback
|
||||
* @param {Error|null} execErr
|
||||
* @returns
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {*} server
|
||||
* @param {ExecCallback} callback
|
||||
* @returns
|
||||
*/
|
||||
Plugin.prototype.exec = function (server, callback) {
|
||||
debug('exec', this.name)
|
||||
|
||||
this.server = server
|
||||
const func = this.func
|
||||
const name = this.name
|
||||
let completed = false
|
||||
|
||||
this.options = typeof this.options === 'function' ? this.options(this.server) : this.options
|
||||
|
||||
let timer = null
|
||||
|
||||
/**
|
||||
* @param {Error} [execErr]
|
||||
*/
|
||||
const done = (execErr) => {
|
||||
if (completed) {
|
||||
debug('loading complete', name)
|
||||
return
|
||||
}
|
||||
|
||||
this._error = execErr
|
||||
|
||||
if (execErr) {
|
||||
debug('exec errored', name)
|
||||
} else {
|
||||
debug('exec completed', name)
|
||||
}
|
||||
|
||||
completed = true
|
||||
|
||||
if (timer) {
|
||||
clearTimeout(timer)
|
||||
}
|
||||
|
||||
callback(execErr)
|
||||
}
|
||||
|
||||
if (this.timeout > 0) {
|
||||
debug('setting up timeout', name, this.timeout)
|
||||
timer = setTimeout(function () {
|
||||
debug('timed out', name)
|
||||
timer = null
|
||||
const readyTimeoutErr = new AVV_ERR_PLUGIN_EXEC_TIMEOUT(name)
|
||||
// TODO Remove reference to function
|
||||
readyTimeoutErr.fn = func
|
||||
done(readyTimeoutErr)
|
||||
}, this.timeout)
|
||||
}
|
||||
|
||||
this.started = true
|
||||
this.startTime = Date.now()
|
||||
this.emit('start', this.server ? this.server.name : null, this.name, Date.now())
|
||||
|
||||
const maybePromiseLike = func(this.server, this.options, done)
|
||||
|
||||
if (isPromiseLike(maybePromiseLike)) {
|
||||
debug('exec: resolving promise', name)
|
||||
|
||||
maybePromiseLike.then(
|
||||
() => process.nextTick(done),
|
||||
(e) => process.nextTick(done, e))
|
||||
} else if (func.length < 3) {
|
||||
done()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Promise}
|
||||
*/
|
||||
Plugin.prototype.loadedSoFar = function () {
|
||||
debug('loadedSoFar', this.name)
|
||||
|
||||
if (this.loaded) {
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
const setup = () => {
|
||||
this.server.after((afterErr, callback) => {
|
||||
this._error = afterErr
|
||||
this.queue.pause()
|
||||
|
||||
if (this._promise) {
|
||||
if (afterErr) {
|
||||
debug('rejecting promise', this.name, afterErr)
|
||||
this._promise.reject(afterErr)
|
||||
} else {
|
||||
debug('resolving promise', this.name)
|
||||
this._promise.resolve()
|
||||
}
|
||||
this._promise = null
|
||||
}
|
||||
|
||||
process.nextTick(callback, afterErr)
|
||||
})
|
||||
this.queue.resume()
|
||||
}
|
||||
|
||||
let res
|
||||
|
||||
if (!this._promise) {
|
||||
this._promise = createPromise()
|
||||
res = this._promise.promise
|
||||
|
||||
if (!this.server) {
|
||||
this.on('start', setup)
|
||||
} else {
|
||||
setup()
|
||||
}
|
||||
} else {
|
||||
res = Promise.resolve()
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
/**
|
||||
* @callback EnqueueCallback
|
||||
* @param {Error|null} enqueueErr
|
||||
* @param {Plugin} result
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Plugin} plugin
|
||||
* @param {EnqueueCallback} callback
|
||||
*/
|
||||
Plugin.prototype.enqueue = function (plugin, callback) {
|
||||
debug('enqueue', this.name, plugin.name)
|
||||
|
||||
this.emit('enqueue', this.server ? this.server.name : null, this.name, Date.now())
|
||||
this.queue.push(plugin, callback)
|
||||
}
|
||||
|
||||
/**
|
||||
* @callback FinishCallback
|
||||
* @param {Error|null} finishErr
|
||||
* @returns
|
||||
*/
|
||||
/**
|
||||
*
|
||||
* @param {Error|null} err
|
||||
* @param {FinishCallback} callback
|
||||
* @returns
|
||||
*/
|
||||
Plugin.prototype.finish = function (err, callback) {
|
||||
debug('finish', this.name, err)
|
||||
|
||||
const done = () => {
|
||||
if (this.loaded) {
|
||||
return
|
||||
}
|
||||
|
||||
debug('loaded', this.name)
|
||||
this.emit('loaded', this.server ? this.server.name : null, this.name, Date.now())
|
||||
this.loaded = true
|
||||
|
||||
callback(err)
|
||||
}
|
||||
|
||||
if (err) {
|
||||
if (this._promise) {
|
||||
this._promise.reject(err)
|
||||
this._promise = null
|
||||
}
|
||||
done()
|
||||
return
|
||||
}
|
||||
|
||||
const check = () => {
|
||||
debug('check', this.name, this.queue.length(), this.queue.running(), this._promise)
|
||||
if (this.queue.length() === 0 && this.queue.running() === 0) {
|
||||
if (this._promise) {
|
||||
const wrap = () => {
|
||||
debug('wrap')
|
||||
queueMicrotask(check)
|
||||
}
|
||||
this._promise.resolve()
|
||||
this._promise.promise.then(wrap, wrap)
|
||||
this._promise = null
|
||||
} else {
|
||||
done()
|
||||
}
|
||||
} else {
|
||||
debug('delayed', this.name)
|
||||
// finish when the queue of nested plugins to load is empty
|
||||
this.queue.drain = () => {
|
||||
debug('drain', this.name)
|
||||
this.queue.drain = noop
|
||||
|
||||
// we defer the check, as a safety net for things
|
||||
// that might be scheduled in the loading callback
|
||||
queueMicrotask(check)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
queueMicrotask(check)
|
||||
|
||||
// we start loading the dependents plugins only once
|
||||
// the current level is finished
|
||||
this.queue.resume()
|
||||
}
|
||||
|
||||
function noop () {}
|
||||
|
||||
module.exports = {
|
||||
Plugin
|
||||
}
|
||||
26
node_modules/avvio/lib/symbols.js
generated
vendored
Normal file
26
node_modules/avvio/lib/symbols.js
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
'use strict'
|
||||
|
||||
// Internal Symbols
|
||||
const kAvvio = Symbol('avvio.Boot')
|
||||
const kIsOnCloseHandler = Symbol('isOnCloseHandler')
|
||||
const kThenifyDoNotWrap = Symbol('avvio.ThenifyDoNotWrap')
|
||||
const kUntrackNode = Symbol('avvio.TimeTree.untrackNode')
|
||||
const kTrackNode = Symbol('avvio.TimeTree.trackNode')
|
||||
const kGetParent = Symbol('avvio.TimeTree.getParent')
|
||||
const kGetNode = Symbol('avvio.TimeTree.getNode')
|
||||
const kAddNode = Symbol('avvio.TimeTree.addNode')
|
||||
|
||||
// Public Symbols
|
||||
const kPluginMeta = Symbol.for('plugin-meta')
|
||||
|
||||
module.exports = {
|
||||
kAvvio,
|
||||
kIsOnCloseHandler,
|
||||
kThenifyDoNotWrap,
|
||||
kUntrackNode,
|
||||
kTrackNode,
|
||||
kGetParent,
|
||||
kGetNode,
|
||||
kAddNode,
|
||||
kPluginMeta
|
||||
}
|
||||
60
node_modules/avvio/lib/thenify.js
generated
vendored
Normal file
60
node_modules/avvio/lib/thenify.js
generated
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
'use strict'
|
||||
|
||||
const { debug } = require('./debug')
|
||||
const { kThenifyDoNotWrap } = require('./symbols')
|
||||
|
||||
/**
|
||||
* @callback PromiseConstructorLikeResolve
|
||||
* @param {any} value
|
||||
* @returns {void}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback PromiseConstructorLikeReject
|
||||
* @param {reason} error
|
||||
* @returns {void}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback PromiseConstructorLike
|
||||
* @param {PromiseConstructorLikeResolve} resolve
|
||||
* @param {PromiseConstructorLikeReject} reject
|
||||
* @returns {void}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @returns {PromiseConstructorLike}
|
||||
*/
|
||||
function thenify () {
|
||||
// If the instance is ready, then there is
|
||||
// nothing to await. This is true during
|
||||
// await server.ready() as ready() resolves
|
||||
// with the server, end we will end up here
|
||||
// because of automatic promise chaining.
|
||||
if (this.booted) {
|
||||
debug('thenify returning undefined because we are already booted')
|
||||
return
|
||||
}
|
||||
|
||||
// Calling resolve(this._server) would fetch the then
|
||||
// property on the server, which will lead it here.
|
||||
// If we do not break the recursion, we will loop
|
||||
// forever.
|
||||
if (this[kThenifyDoNotWrap]) {
|
||||
this[kThenifyDoNotWrap] = false
|
||||
return
|
||||
}
|
||||
|
||||
debug('thenify')
|
||||
return (resolve, reject) => {
|
||||
const p = this._loadRegistered()
|
||||
return p.then(() => {
|
||||
this[kThenifyDoNotWrap] = true
|
||||
return resolve(this._server)
|
||||
}, reject)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
thenify
|
||||
}
|
||||
200
node_modules/avvio/lib/time-tree.js
generated
vendored
Normal file
200
node_modules/avvio/lib/time-tree.js
generated
vendored
Normal file
@@ -0,0 +1,200 @@
|
||||
'use strict'
|
||||
|
||||
const {
|
||||
kUntrackNode,
|
||||
kTrackNode,
|
||||
kGetParent,
|
||||
kGetNode,
|
||||
kAddNode
|
||||
} = require('./symbols')
|
||||
|
||||
/**
|
||||
* Node of the TimeTree
|
||||
* @typedef {object} TimeTreeNode
|
||||
* @property {string} id
|
||||
* @property {string|null} parent
|
||||
* @property {string} label
|
||||
* @property {Array<TimeTreeNode>} nodes
|
||||
* @property {number} start
|
||||
* @property {number|undefined} stop
|
||||
* @property {number|undefined} diff
|
||||
*/
|
||||
|
||||
class TimeTree {
|
||||
constructor () {
|
||||
/**
|
||||
* @type {TimeTreeNode|null} root
|
||||
* @public
|
||||
*/
|
||||
this.root = null
|
||||
|
||||
/**
|
||||
* @type {Map<string, TimeTreeNode>} tableId
|
||||
* @public
|
||||
*/
|
||||
this.tableId = new Map()
|
||||
|
||||
/**
|
||||
* @type {Map<string, Array<TimeTreeNode>>} tableLabel
|
||||
* @public
|
||||
*/
|
||||
this.tableLabel = new Map()
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {TimeTreeNode} node
|
||||
*/
|
||||
[kTrackNode] (node) {
|
||||
this.tableId.set(node.id, node)
|
||||
if (this.tableLabel.has(node.label)) {
|
||||
this.tableLabel.get(node.label).push(node)
|
||||
} else {
|
||||
this.tableLabel.set(node.label, [node])
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {TimeTreeNode} node
|
||||
*/
|
||||
[kUntrackNode] (node) {
|
||||
this.tableId.delete(node.id)
|
||||
|
||||
const labelNode = this.tableLabel.get(node.label)
|
||||
labelNode.pop()
|
||||
|
||||
if (labelNode.length === 0) {
|
||||
this.tableLabel.delete(node.label)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} parent
|
||||
* @returns {TimeTreeNode}
|
||||
*/
|
||||
[kGetParent] (parent) {
|
||||
if (parent === null) {
|
||||
return null
|
||||
} else if (this.tableLabel.has(parent)) {
|
||||
const parentNode = this.tableLabel.get(parent)
|
||||
return parentNode[parentNode.length - 1]
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} nodeId
|
||||
* @returns {TimeTreeNode}
|
||||
*/
|
||||
[kGetNode] (nodeId) {
|
||||
return this.tableId.get(nodeId)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} parent
|
||||
* @param {string} label
|
||||
* @param {number} start
|
||||
* @returns {TimeTreeNode["id"]}
|
||||
*/
|
||||
[kAddNode] (parent, label, start) {
|
||||
const parentNode = this[kGetParent](parent)
|
||||
const isRoot = parentNode === null
|
||||
|
||||
if (isRoot) {
|
||||
this.root = {
|
||||
parent: null,
|
||||
id: 'root',
|
||||
label,
|
||||
nodes: [],
|
||||
start,
|
||||
stop: null,
|
||||
diff: -1
|
||||
}
|
||||
this[kTrackNode](this.root)
|
||||
return this.root.id
|
||||
}
|
||||
|
||||
const nodeId = `${label}-${Math.random()}`
|
||||
/**
|
||||
* @type {TimeTreeNode}
|
||||
*/
|
||||
const childNode = {
|
||||
parent,
|
||||
id: nodeId,
|
||||
label,
|
||||
nodes: [],
|
||||
start,
|
||||
stop: null,
|
||||
diff: -1
|
||||
}
|
||||
parentNode.nodes.push(childNode)
|
||||
this[kTrackNode](childNode)
|
||||
return nodeId
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} parent
|
||||
* @param {string} label
|
||||
* @param {number|undefined} start
|
||||
* @returns {TimeTreeNode["id"]}
|
||||
*/
|
||||
start (parent, label, start = Date.now()) {
|
||||
return this[kAddNode](parent, label, start)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} nodeId
|
||||
* @param {number|undefined} stop
|
||||
*/
|
||||
stop (nodeId, stop = Date.now()) {
|
||||
const node = this[kGetNode](nodeId)
|
||||
if (node) {
|
||||
node.stop = stop
|
||||
node.diff = (node.stop - node.start) || 0
|
||||
this[kUntrackNode](node)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {TimeTreeNode}
|
||||
*/
|
||||
toJSON () {
|
||||
return Object.assign({}, this.root)
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string}
|
||||
*/
|
||||
prettyPrint () {
|
||||
return prettyPrintTimeTree(this.toJSON())
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {TimeTreeNode} obj
|
||||
* @param {string|undefined} prefix
|
||||
* @returns {string}
|
||||
*/
|
||||
function prettyPrintTimeTree (obj, prefix = '') {
|
||||
let result = prefix
|
||||
|
||||
const nodesCount = obj.nodes.length
|
||||
const lastIndex = nodesCount - 1
|
||||
result += `${obj.label} ${obj.diff} ms\n`
|
||||
|
||||
for (let i = 0; i < nodesCount; ++i) {
|
||||
const node = obj.nodes[i]
|
||||
const prefix_ = prefix + (i === lastIndex ? ' ' : '│ ')
|
||||
|
||||
result += prefix
|
||||
result += (i === lastIndex ? '└─' : '├─')
|
||||
result += (node.nodes.length === 0 ? '─ ' : '┬ ')
|
||||
result += prettyPrintTimeTree(node, prefix_).slice(prefix.length + 2)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
TimeTree
|
||||
}
|
||||
26
node_modules/avvio/lib/validate-plugin.js
generated
vendored
Normal file
26
node_modules/avvio/lib/validate-plugin.js
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
'use strict'
|
||||
|
||||
const { AVV_ERR_PLUGIN_NOT_VALID } = require('./errors')
|
||||
|
||||
/**
|
||||
* @param {any} maybePlugin
|
||||
* @throws {AVV_ERR_PLUGIN_NOT_VALID}
|
||||
*
|
||||
* @returns {asserts plugin is Function|PromiseLike}
|
||||
*/
|
||||
function validatePlugin (maybePlugin) {
|
||||
// validate if plugin is a function or Promise
|
||||
if (!(maybePlugin && (typeof maybePlugin === 'function' || typeof maybePlugin.then === 'function'))) {
|
||||
if (Array.isArray(maybePlugin)) {
|
||||
throw new AVV_ERR_PLUGIN_NOT_VALID('array')
|
||||
} else if (maybePlugin === null) {
|
||||
throw new AVV_ERR_PLUGIN_NOT_VALID('null')
|
||||
} else {
|
||||
throw new AVV_ERR_PLUGIN_NOT_VALID(typeof maybePlugin)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
validatePlugin
|
||||
}
|
||||
Reference in New Issue
Block a user