mirror of
https://github.com/openclaw/openclaw.git
synced 2026-10-03 09:39:25 +00:00
* refactor: remove narrowly used helper dependencies Replace markdown-it-task-lists and grammY runner sequencing with their local owners. Remove direct ms/pretty-ms usage and share the existing duration factors and formatting. Preserve rendering and parsing contracts, and keep overlapping Telegram lanes ordered when a predecessor fails. Remove obsolete mocks, declarations, dependency metadata, and build references; regenerate the lockfile and Control UI boot manifest. Deduplicate an inherited over-limit replay test without changing coverage. Closes #158499 Co-authored-by: steipete <58493+steipete@users.noreply.github.com> * refactor: remove narrowly used helper dependencies Worked on by: - @steipete Co-authored-by: steipete <58493+steipete@users.noreply.github.com> OpenClaw-Publication: f4ef665a-7e2b-47ce-a454-adc19e798bee * refactor: remove narrowly used helper dependencies Worked on by: - @steipete Co-authored-by: steipete <58493+steipete@users.noreply.github.com> OpenClaw-Publication: abec5219-5bd0-4480-8604-a57c1063f638 * fix(ci): preserve base-only dependencies in UI comparison Materialize removed dependency declarations from the archived base lockfile before overlaying the candidate toolchain. Keep both builds on the same Vite and compressor without restoring removed application dependencies. Extend the real build regression with a dependency absent from the candidate and verify the original comparator fails to resolve it. Co-authored-by: steipete <58493+steipete@users.noreply.github.com> * refactor: remove narrowly used helper dependencies Worked on by: - @steipete Co-authored-by: steipete <58493+steipete@users.noreply.github.com> OpenClaw-Publication: 2db2eea4-87fe-4071-ab37-28da02f1bd24 * refactor: remove narrowly used helper dependencies Worked on by: - @steipete Co-authored-by: steipete <58493+steipete@users.noreply.github.com> OpenClaw-Publication: 8c381a6d-38f2-417f-85ee-9353cb5694dc --------- Co-authored-by: steipete <58493+steipete@users.noreply.github.com>
46 lines
1.8 KiB
TypeScript
46 lines
1.8 KiB
TypeScript
import { durationUnitMs } from "../../src/infra/format-time/duration-units.ts";
|
|
import { resolveExactDurationParts } from "../../src/infra/format-time/format-duration-exact.ts";
|
|
import {
|
|
formatDurationParts,
|
|
type DurationPart,
|
|
} from "../../src/infra/format-time/format-duration-internal.ts";
|
|
|
|
/** Formats non-negative, pre-rounded script timings with fractional seconds. */
|
|
export function formatDurationElapsed(
|
|
ms: number,
|
|
options: { secondsDecimalDigits?: 1 | 2; unitCount?: 1 | 2; showYears?: boolean } = {},
|
|
): string {
|
|
const exact = resolveExactDurationParts(ms);
|
|
if (!exact) {
|
|
throw new TypeError("Expected a non-negative finite number");
|
|
}
|
|
if (ms < durationUnitMs.second) {
|
|
return `${ms}ms`;
|
|
}
|
|
const daysPerYear = BigInt(durationUnitMs.year / durationUnitMs.day);
|
|
const wholeParts = exact.flatMap(({ value, unit }): DurationPart[] => {
|
|
if (unit === "second" || unit === "millisecond") {
|
|
return [];
|
|
}
|
|
if (unit !== "day" || options.showYears === false) {
|
|
return [{ value, unit }];
|
|
}
|
|
const days = BigInt(value);
|
|
const dayParts: DurationPart[] = [
|
|
{ value: days / daysPerYear, unit: "year" },
|
|
{ value: days % daysPerYear, unit: "day" },
|
|
];
|
|
return dayParts.filter((part) => part.value !== 0n);
|
|
});
|
|
const decimals = options.secondsDecimalDigits ?? 1;
|
|
const scale = 10 ** decimals;
|
|
// Avoid dropping a displayed decimal when binary division lands just below it.
|
|
const seconds = Math.floor(((ms / durationUnitMs.second) % 60) * scale + 0.000_000_1) / scale;
|
|
const unitCount = options.unitCount ?? Infinity;
|
|
const units = wholeParts.slice(0, unitCount);
|
|
const result = [formatDurationParts(units)];
|
|
if (seconds > 0 && units.length < unitCount) {
|
|
result.push(`${seconds.toFixed(decimals).replace(/\.0+$/, "")}s`);
|
|
}
|
|
return result.filter(Boolean).join(" ") || "0ms";
|
|
}
|