import { getContext as t, setContext as e, take as o } from "redux-saga/effects"
import { ENV_CONTEXT_KEY as s } from "../../constants"
export const TIME_CONTEXT_KEY = "time-context"
export const FLOW_TYPE = {
STEP: "STEP",
SEQUENCE: "SEQUENCE",
PARALLEL: "PARALLEL",
ERROR: "ERROR",
}
const n = (t) =>
t.type === FLOW_TYPE.SEQUENCE
? t.items.reduce((t, e) => t + n(e), 0)
: t.type === FLOW_TYPE.PARALLEL
? t.items.reduce((t, e) => Math.max(t, n(e)), 0)
: (t.taskTime ?? 0)
export const sequence = (t, e, o) => ({
type: FLOW_TYPE.SEQUENCE,
name: t,
items: e,
title: o?.title,
})
export const parallel = (t, e) => ({
type: FLOW_TYPE.PARALLEL,
items: t,
title: e?.title,
name: e?.name,
})
export const step = (t, { startTime: e, doneTime: o }) => ({
type: FLOW_TYPE.STEP,
action: t,
startTime: e,
doneTime: o,
taskTime: o - e,
})
export function* takeStep(e) {
const s = yield t("time-context"),
n = s.currentTime,
r = yield o(e),
i = Date.now()
return (i > s.currentTime && (s.currentTime = i), step(r, { startTime: n, doneTime: i }))
}
export function* initFlowTime({ currentTime: t }) {
const o = { currentTime: t ?? 0 }
yield e({ [TIME_CONTEXT_KEY]: o })
}
export const stepError = (t) => ({ type: FLOW_TYPE.ERROR, message: t })
export const createTimeContext = (t = 0) => ({
currentTime: t,
setCurrentTime(t) {
this.currentTime = t
},
})
export function* printFlow(e, o) {
const { parentStep: r } = o || {},
{ timeStats: i } = yield t(s),
{ log: c, groupLogStart: p, groupLogEnd: E } = i || {},
a = (t, { parentStep: e }) => {
let o = 0
const s = n(t)
switch (t.type) {
case FLOW_TYPE.SEQUENCE: {
const { name: n, title: r, items: i } = t
;(p(`${e ? `step ${e}: ` : ""}"${n}" (${s} msec) ${r ? `<${r}>` : ""}`),
i.forEach((t, s) => {
const n = s + 1
if (t.type === FLOW_TYPE.STEP) {
const { action: s, taskTime: r, info: i } = t
o += r
const p = i ? `<${i}>` : ""
c(`step ${e ? `${e}.${n}` : n}: ${s.type}: (${r} msec) ${p}`)
} else {
const s = a(t, { parentStep: e ? `${e}.${n}` : n })
o += s
}
}),
c(`total: (${o} msec)`),
E())
break
}
case FLOW_TYPE.PARALLEL: {
const { items: n, title: r, name: i } = t,
T = e ?? 1
;(p(`step ${T}: ||${i ? ` "${i}" ` : " "}(${s} msec) ${r ? `<${r}>` : ""}`),
n.forEach((t, e) => {
const s = `${T}-${e + 1}`
if (t.type === FLOW_TYPE.STEP) {
const { action: e, taskTime: n, info: r } = t,
i = r ? `<${r}>` : ""
;(c(`step ${s}: ${e.type}: (${n} msec) ${i}`), n > o && (o = n))
} else {
const e = a(t, { parentStep: s })
e > o && (o = e)
}
}),
c(`total: (${o} msec)`),
E())
break
}
}
return o
}
return a(e, { parentStep: r })
}
export const TIME_STATS_LOGGER_TYPE = { STATS: "stats" }
const r = 512
export const createTimeStatsLog = (t = !1) => {
let e = [],
o = 0,
s = 0
const n = () => `${s}-${o}`,
i = (t) => `${new Array(o).fill("\t").join("")}${t}`
return {
type: "stats",
getItems: () => [...e],
clearItems: () => {
e = []
},
groupLogStart: (c) => {
if (((s += 1), 0 === o && e.length > r)) {
const t = e.findIndex((t, e) => e > 256 && t.isGroupTop)
e.splice(0, t)
}
;(e.push({ key: n(), value: i(c), isGroupTop: 0 === o }), t && console.log(i(c)), (o += 1))
},
groupLogEnd: () => {
o = Math.max(0, o - 1)
},
log: (o) => {
;((s += 1), e.push({ key: n(), value: i(o), isGroupTop: !1 }), t && console.log(i(o)))
},
}
}