78 lines
2.1 KiB
JavaScript
78 lines
2.1 KiB
JavaScript
'use strict'
|
|
|
|
const assert = require('node:assert').strict
|
|
|
|
const noop = Function.prototype
|
|
|
|
function omit(source, keys, target = { __proto__: null }) {
|
|
for (const key of Object.keys(source)) {
|
|
if (!keys.has(key)) {
|
|
target[key] = source[key]
|
|
}
|
|
}
|
|
return target
|
|
}
|
|
|
|
const IGNORED_START_PROPS = new Set([
|
|
'end',
|
|
'infos',
|
|
'properties',
|
|
'result',
|
|
'status',
|
|
'tasks',
|
|
'timestamp',
|
|
'type',
|
|
'warnings',
|
|
])
|
|
|
|
exports.makeOnProgress = function ({ onRootTaskEnd = noop, onRootTaskStart = noop, onTaskUpdate = noop }) {
|
|
const taskLogs = new Map()
|
|
return function onProgress(event) {
|
|
const { id, type } = event
|
|
let taskLog
|
|
if (type === 'start') {
|
|
taskLog = omit(event, IGNORED_START_PROPS)
|
|
taskLog.start = event.timestamp
|
|
taskLog.status = 'pending'
|
|
taskLogs.set(id, taskLog)
|
|
|
|
const { parentId } = event
|
|
if (parentId === undefined) {
|
|
Object.defineProperty(taskLog, '$root', { value: taskLog })
|
|
|
|
// start of a root task
|
|
onRootTaskStart(taskLog)
|
|
} else {
|
|
// start of a subtask
|
|
const parent = taskLogs.get(parentId)
|
|
assert.notEqual(parent, undefined)
|
|
|
|
// inject a (non-enumerable) reference to the parent and the root task
|
|
Object.defineProperty(taskLog, { $parent: { value: parent }, $root: { value: parent.$root } })
|
|
;(parent.tasks ?? (parent.tasks = [])).push(taskLog)
|
|
}
|
|
} else {
|
|
taskLog = taskLogs.get(id)
|
|
assert.notEqual(taskLog, undefined)
|
|
|
|
if (type === 'info' || type === 'warning') {
|
|
const key = type + 's'
|
|
const { data, message } = event
|
|
;(taskLog[key] ?? (taskLog[key] = [])).push({ data, message })
|
|
} else if (type === 'property') {
|
|
;(taskLog.properties ?? (taskLog.properties = { __proto__: null }))[event.name] = event.value
|
|
} else if (type === 'end') {
|
|
taskLog.end = event.timestamp
|
|
taskLog.result = event.result
|
|
taskLog.status = event.status
|
|
}
|
|
|
|
if (type === 'end' && taskLog.$root === taskLog) {
|
|
onRootTaskEnd(taskLog)
|
|
}
|
|
}
|
|
|
|
onTaskUpdate(taskLog)
|
|
}
|
|
}
|