@betterer/tasks
Advanced tools
Comparing version 5.0.0-alpha.0 to 5.0.0
@@ -6,2 +6,10 @@ # Change Log | ||
# [5.0.0](https://github.com/phenomnomnominal/betterer/compare/v4.4.1...v5.0.0) (2021-11-12) | ||
**Note:** Version bump only for package @betterer/tasks | ||
# [5.0.0-alpha.0](https://github.com/phenomnomnominal/betterer/compare/v4.4.1...v5.0.0-alpha.0) (2021-08-27) | ||
@@ -8,0 +16,0 @@ |
import { FC } from 'react'; | ||
import { BettererError } from '@betterer/errors'; | ||
export declare type BettererErrorLogProps = { | ||
/** | ||
* @public `props` type for {@link BettererErrorLog | `<BettererErrorLog/>`}. | ||
*/ | ||
export interface BettererErrorLogProps { | ||
/** | ||
* the `Error` or {@link @betterer/errors#BettererError | `BettererError`} to render. | ||
*/ | ||
error: Error | BettererError; | ||
}; | ||
} | ||
/** | ||
* @public Ink component for rendering a {@link @betterer/errors#BettererError | `BettererError` } | ||
* and all its additional information. The `message`, `stack` and `details` of the `error` will be | ||
* printed. If any `detail` is an `Error` or {@link @betterer/errors#BettererError | `BettererError`}, | ||
* the component will be rendered recursively. | ||
*/ | ||
export declare const BettererErrorLog: FC<BettererErrorLogProps>; | ||
//# sourceMappingURL=error-log.d.ts.map |
@@ -8,2 +8,8 @@ "use strict"; | ||
const ink_1 = require("ink"); | ||
/** | ||
* @public Ink component for rendering a {@link @betterer/errors#BettererError | `BettererError` } | ||
* and all its additional information. The `message`, `stack` and `details` of the `error` will be | ||
* printed. If any `detail` is an `Error` or {@link @betterer/errors#BettererError | `BettererError`}, | ||
* the component will be rendered recursively. | ||
*/ | ||
const BettererErrorLog = function BettererErrorLog({ error }) { | ||
@@ -10,0 +16,0 @@ let errors = []; |
@@ -0,3 +1,11 @@ | ||
/** | ||
* Task runner and logger used within {@link https://github.com/phenomnomnominal/betterer | **Betterer**}. | ||
* | ||
* π¨ THIS PACKAGE SHOULD ONLY BE USED WITHIN THE BETTERER MONOREPO π¨ | ||
* | ||
* @packageDocumentation | ||
*/ | ||
export { BettererErrorLog, BettererErrorLogProps } from './error-log'; | ||
export { BettererLogo } from './logo'; | ||
export { getTask, reset, BettererTaskColour, BettererTaskLog, BettererTaskLogger, BettererTaskLoggerProps, BettererTaskRun, BettererTasksDone, BettererTasksLogger, BettererTasksLoggerProps, BettererTasksState, BettererTasksStatusUpdate } from './tasks/public'; | ||
export { BettererTask, BettererTaskLogger, BettererTaskLoggerProps, BettererTasksDone, BettererTasksLogger, BettererTasksLoggerProps, BettererTasksState, BettererTasksStatusUpdate } from './tasks/public'; | ||
//# sourceMappingURL=index.d.ts.map |
"use strict"; | ||
/** | ||
* Task runner and logger used within {@link https://github.com/phenomnomnominal/betterer | **Betterer**}. | ||
* | ||
* π¨ THIS PACKAGE SHOULD ONLY BE USED WITHIN THE BETTERER MONOREPO π¨ | ||
* | ||
* @packageDocumentation | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.BettererTasksLogger = exports.BettererTaskLogger = exports.reset = exports.getTask = exports.BettererLogo = exports.BettererErrorLog = void 0; | ||
exports.BettererTasksLogger = exports.BettererTaskLogger = exports.BettererLogo = exports.BettererErrorLog = void 0; | ||
var error_log_1 = require("./error-log"); | ||
@@ -9,6 +16,4 @@ Object.defineProperty(exports, "BettererErrorLog", { enumerable: true, get: function () { return error_log_1.BettererErrorLog; } }); | ||
var public_1 = require("./tasks/public"); | ||
Object.defineProperty(exports, "getTask", { enumerable: true, get: function () { return public_1.getTask; } }); | ||
Object.defineProperty(exports, "reset", { enumerable: true, get: function () { return public_1.reset; } }); | ||
Object.defineProperty(exports, "BettererTaskLogger", { enumerable: true, get: function () { return public_1.BettererTaskLogger; } }); | ||
Object.defineProperty(exports, "BettererTasksLogger", { enumerable: true, get: function () { return public_1.BettererTasksLogger; } }); | ||
//# sourceMappingURL=index.js.map |
import { FC } from 'react'; | ||
/** | ||
* @public Ink component for rendering an ASCII version of the {@link https://github.com/phenomnomnominal/betterer | **Betterer**} | ||
* logo. | ||
*/ | ||
export declare const BettererLogo: FC; | ||
//# sourceMappingURL=logo.d.ts.map |
@@ -14,2 +14,6 @@ "use strict"; | ||
`; | ||
/** | ||
* @public Ink component for rendering an ASCII version of the {@link https://github.com/phenomnomnominal/betterer | **Betterer**} | ||
* logo. | ||
*/ | ||
const BettererLogo = function BettererLogo() { | ||
@@ -16,0 +20,0 @@ return react_1.default.createElement(ink_1.Text, { color: "yellowBright" }, LOGO); |
export { BettererTasksState } from './useTasksState'; | ||
export { BettererTaskLogger, BettererTaskLoggerProps } from './TaskLogger'; | ||
export { getTask, reset } from './tasks'; | ||
export { BettererTasksLogger, BettererTasksLoggerProps } from './TasksLogger'; | ||
export { BettererTaskColour, BettererTaskLog, BettererTaskRun, BettererTasksDone, BettererTasksStatusUpdate } from './types'; | ||
export { BettererTask, BettererTasksDone, BettererTasksStatusUpdate } from './types'; | ||
//# sourceMappingURL=public.d.ts.map |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.BettererTasksLogger = exports.reset = exports.getTask = exports.BettererTaskLogger = void 0; | ||
exports.BettererTasksLogger = exports.BettererTaskLogger = void 0; | ||
var TaskLogger_1 = require("./TaskLogger"); | ||
Object.defineProperty(exports, "BettererTaskLogger", { enumerable: true, get: function () { return TaskLogger_1.BettererTaskLogger; } }); | ||
var tasks_1 = require("./tasks"); | ||
Object.defineProperty(exports, "getTask", { enumerable: true, get: function () { return tasks_1.getTask; } }); | ||
Object.defineProperty(exports, "reset", { enumerable: true, get: function () { return tasks_1.reset; } }); | ||
var TasksLogger_1 = require("./TasksLogger"); | ||
Object.defineProperty(exports, "BettererTasksLogger", { enumerable: true, get: function () { return TasksLogger_1.BettererTasksLogger; } }); | ||
//# sourceMappingURL=public.js.map |
import { FC } from 'react'; | ||
import { BettererTaskLog } from './types'; | ||
export declare type BettererTaskStatusProps = { | ||
export interface BettererTaskStatusProps { | ||
name: string; | ||
status: BettererTaskLog; | ||
}; | ||
} | ||
export declare const BettererTaskStatus: FC<BettererTaskStatusProps>; | ||
//# sourceMappingURL=status.d.ts.map |
import { FC } from 'react'; | ||
import { BettererTaskRun } from './types'; | ||
export declare type BettererTaskLoggerProps = { | ||
import { BettererTask } from './types'; | ||
/** | ||
* @public `props` type for {@link BettererTaskLogger | `<BettererTaskLogger/>`}. | ||
*/ | ||
export interface BettererTaskLoggerProps { | ||
/** | ||
* The name of the task that is shown to the user. | ||
*/ | ||
name: string; | ||
run: BettererTaskRun; | ||
}; | ||
/** | ||
* The task to be run. | ||
*/ | ||
task: BettererTask; | ||
} | ||
/** | ||
* @public Ink component for rendering the output of a single {@link BettererTask | `BettererTask`}. | ||
* The output will update based on the status of the task. Once the task is finished, it will | ||
* output any logging and any errors (if the task failed). | ||
*/ | ||
export declare const BettererTaskLogger: FC<BettererTaskLoggerProps>; | ||
//# sourceMappingURL=TaskLogger.d.ts.map |
@@ -12,11 +12,16 @@ "use strict"; | ||
const useTaskState_1 = require("./useTaskState"); | ||
const tasks_1 = require("./tasks"); | ||
const useTasksState_1 = require("./useTasksState"); | ||
/** | ||
* @public Ink component for rendering the output of a single {@link BettererTask | `BettererTask`}. | ||
* The output will update based on the status of the task. Once the task is finished, it will | ||
* output any logging and any errors (if the task failed). | ||
*/ | ||
exports.BettererTaskLogger = (0, react_1.memo)(function BettererTaskLogger(props) { | ||
const { name, run } = props; | ||
const [state, taskApi] = (0, useTaskState_1.useTaskState)(); | ||
const { error, finalLogs, status } = state; | ||
const { name, task } = props; | ||
const [tasksState] = (0, useTasksState_1.useTasks)(); | ||
const [taskState, taskApi] = (0, useTaskState_1.useTaskState)(); | ||
const { error, logs, status } = taskState; | ||
(0, react_1.useEffect)(() => { | ||
void (async () => { | ||
taskApi.reset(); | ||
(0, tasks_1.addTask)(name, run); | ||
async function statusError(status) { | ||
@@ -32,3 +37,3 @@ await taskApi.status(['π₯', 'redBright', status]); | ||
async function logCode(codeInfo) { | ||
const codeFrame = (0, logger_1.codeΞ)(codeInfo); | ||
const codeFrame = (0, logger_1.code__)(codeInfo); | ||
await taskApi.log(['π»', 'whiteBright', codeFrame]); | ||
@@ -53,3 +58,3 @@ } | ||
try { | ||
const result = await run({ | ||
const result = await task({ | ||
progress: statusProgress, | ||
@@ -66,8 +71,5 @@ code: logCode, | ||
} | ||
else if (!result) { | ||
else { | ||
await statusSuccess('done!'); | ||
} | ||
else { | ||
await taskApi.status(result); | ||
} | ||
taskApi.stop(); | ||
@@ -81,6 +83,6 @@ } | ||
})(); | ||
}, [name, run, taskApi]); | ||
}, [name, task, taskApi]); | ||
return (react_1.default.createElement(ink_1.Box, { flexDirection: "column" }, | ||
status && react_1.default.createElement(status_1.BettererTaskStatus, { name: name, status: status }), | ||
finalLogs.length ? (react_1.default.createElement(ink_1.Box, { flexDirection: "column" }, finalLogs.map((log, index) => (react_1.default.createElement(ink_1.Text, { key: index }, prependLogBlock(log)))))) : null, | ||
tasksState.endTime != null && logs.length ? (react_1.default.createElement(ink_1.Box, { flexDirection: "column" }, logs.map((log, index) => (react_1.default.createElement(ink_1.Text, { key: index }, prependLogBlock(log)))))) : null, | ||
error && react_1.default.createElement(error_log_1.BettererErrorLog, { error: error }))); | ||
@@ -87,0 +89,0 @@ }); |
import { FC } from 'react'; | ||
import { BettererTasksDone, BettererTasksStatusUpdate } from './types'; | ||
export declare type BettererTasksLoggerProps = { | ||
/** | ||
* @public `props` type for {@link BettererTasksLogger | `<BettererTasksLogger/>`}. | ||
*/ | ||
export interface BettererTasksLoggerProps { | ||
/** | ||
* Whether the Ink renderer instance should quit after the tasks are complete. | ||
* | ||
* @remarks Should be set to `false` if the Ink instance is rendering any other components. | ||
* | ||
* @defaultValue `true` | ||
*/ | ||
exit?: boolean; | ||
/** | ||
* The name of group of task that is shown to the user | ||
*/ | ||
name: string; | ||
update: BettererTasksStatusUpdate; | ||
/** | ||
* An optional hook to customise the output of the task status summary. | ||
* | ||
* @defaultValue `() => ${nRunning} tasks running... ${nDone} tasks done! ${nErrored} tasks errored!` | ||
*/ | ||
update?: BettererTasksStatusUpdate; | ||
/** | ||
* An optional callback function that is called whenever a set of tasks are completed. | ||
*/ | ||
done?: BettererTasksDone; | ||
}; | ||
} | ||
/** | ||
* @public Ink component for rendering the output of a set of {@link BettererTask | `BettererTask`s}. | ||
* The output will update based on the current status of the tasks. | ||
*/ | ||
export declare const BettererTasksLogger: FC<BettererTasksLoggerProps>; | ||
//# sourceMappingURL=TasksLogger.d.ts.map |
@@ -7,30 +7,20 @@ "use strict"; | ||
const react_1 = (0, tslib_1.__importStar)(require("react")); | ||
const perf_hooks_1 = require("perf_hooks"); | ||
const status_1 = require("./status"); | ||
const useTasksState_1 = require("./useTasksState"); | ||
const DEFAULT_TASK_TIME_INTERVAL = 100; | ||
const useTimer_1 = require("./useTimer"); | ||
/** | ||
* @public Ink component for rendering the output of a set of {@link BettererTask | `BettererTask`s}. | ||
* The output will update based on the current status of the tasks. | ||
*/ | ||
exports.BettererTasksLogger = (0, react_1.memo)(function BettererTasksLogger(props) { | ||
const { children, done, exit = true, name, update } = props; | ||
const { children, done = () => void 0, exit = true, name, update = defaultUpdate } = props; | ||
const app = (0, ink_1.useApp)(); | ||
const [state, api] = (0, useTasksState_1.useTasksState)(); | ||
const timer = (0, react_1.useRef)(null); | ||
const [runningTime, setRunningTime] = (0, react_1.useState)(perf_hooks_1.performance.now()); | ||
const { errors, endTime, startTime } = state; | ||
const updateTime = (0, react_1.useCallback)(() => { | ||
setRunningTime(perf_hooks_1.performance.now()); | ||
}, [perf_hooks_1.performance]); | ||
const clearTime = (0, react_1.useCallback)(() => { | ||
if (timer.current) { | ||
clearInterval(timer.current); | ||
} | ||
}, []); | ||
const [time, clear] = (0, useTimer_1.useTimer)(); | ||
const [state, tasks] = (0, useTasksState_1.useTasksState)(); | ||
const { startTime, endTime, errors } = state; | ||
(0, react_1.useEffect)(() => { | ||
if (endTime) { | ||
clearTime(); | ||
return; | ||
if (endTime != null) { | ||
clear(); | ||
} | ||
timer.current = setInterval(updateTime, DEFAULT_TASK_TIME_INTERVAL); | ||
updateTime(); | ||
return clearTime; | ||
}, [updateTime, clearTime, endTime]); | ||
}, [endTime, clear]); | ||
const result = `${update(state)}`; | ||
@@ -49,9 +39,7 @@ let status = ['π', 'whiteBright', result]; | ||
} | ||
if (done) { | ||
done(); | ||
} | ||
done(); | ||
} | ||
return (react_1.default.createElement(useTasksState_1.BettererTasksStateContext.Provider, { value: api }, | ||
return (react_1.default.createElement(useTasksState_1.BettererTasksContext.Provider, { value: [state, tasks] }, | ||
react_1.default.createElement(ink_1.Box, { flexDirection: "column" }, | ||
react_1.default.createElement(status_1.BettererTaskStatus, { name: `${name} (${getTime(startTime, endTime || runningTime)}ms)`, status: status }), | ||
react_1.default.createElement(status_1.BettererTaskStatus, { name: `${name} (${getTime(startTime, endTime || time)}ms)`, status: status }), | ||
children))); | ||
@@ -63,2 +51,12 @@ }); | ||
} | ||
function defaultUpdate(state) { | ||
const { done, errors, running } = state; | ||
const runningStatus = running ? `${tasks(running)} running... ` : ''; | ||
const doneStatus = done ? `${tasks(done)} done! ` : ''; | ||
const errorStatus = errors ? `${tasks(errors)} errored! ` : ''; | ||
return `${runningStatus}${doneStatus}${errorStatus}`; | ||
} | ||
function tasks(n) { | ||
return `${n} ${n === 1 ? 'task' : 'tasks'}`; | ||
} | ||
//# sourceMappingURL=TasksLogger.js.map |
@@ -5,6 +5,23 @@ import { BettererLogger } from '@betterer/logger'; | ||
export declare type BettererTaskColour = typeof ForegroundColor; | ||
export declare type BettererTaskRun = (logger: BettererLogger) => Promise<BettererTaskLog | string | void>; | ||
/** | ||
* @public An asynchronous task that will be orchestrated by the {@link @betterer/tasks#BettererTasksLogger | `BettererTasksLogger`}. | ||
* | ||
* @param logger - Parameter provides access to asynchronous logging which will be shown to the | ||
* user once the task is complete. | ||
* @returns If the task returns it is a "success". | ||
* @throws If the task throws it is a "failure". | ||
*/ | ||
export declare type BettererTask = (logger: BettererLogger) => Promise<string | void>; | ||
export declare type BettererTaskLog = [indicator: string, colour: BettererTaskColour, message: string]; | ||
export declare type BettererTaskLogs = Array<BettererTaskLog>; | ||
/** | ||
* @public A function that is called whenever a set of tasks are completed. | ||
*/ | ||
export declare type BettererTasksDone = () => void; | ||
/** | ||
* @public A function that can be used to customise the output of the task status summary. | ||
* | ||
* @remarks Useful for custom pluralisation and internationalisation. | ||
*/ | ||
export declare type BettererTasksStatusUpdate = (state: BettererTasksState) => string; | ||
//# sourceMappingURL=types.d.ts.map |
/// <reference types="react" /> | ||
export declare type BettererTasksState = { | ||
/** | ||
* @public The state of the running tasks. `endTime` will only be present when there are no more | ||
* `running` tasks. | ||
*/ | ||
export interface BettererTasksState { | ||
running: number; | ||
@@ -8,3 +12,3 @@ done: number; | ||
endTime: number | null; | ||
}; | ||
} | ||
export declare type BettererTasksAction = { | ||
@@ -18,8 +22,10 @@ type: 'start'; | ||
}; | ||
export declare type BettererTasksStateAPI = { | ||
export interface BettererTasksAPI { | ||
error(error: Error): void; | ||
start(): void; | ||
stop(): void; | ||
}; | ||
export declare function useTasksState(): [BettererTasksState, BettererTasksStateAPI]; | ||
export declare const BettererTasksStateContext: import("react").Context<BettererTasksStateAPI>; | ||
} | ||
export declare function useTasksState(): [BettererTasksState, BettererTasksAPI]; | ||
export declare const BettererTasksContext: import("react").Context<[BettererTasksState, BettererTasksAPI] | null>; | ||
export declare function useTasks(): [BettererTasksState, BettererTasksAPI]; | ||
//# sourceMappingURL=useTasksState.d.ts.map |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.BettererTasksStateContext = exports.useTasksState = void 0; | ||
exports.useTasks = exports.BettererTasksContext = exports.useTasksState = void 0; | ||
const react_1 = require("react"); | ||
const perf_hooks_1 = require("perf_hooks"); | ||
const errors_1 = require("@betterer/errors"); | ||
function useTasksState() { | ||
@@ -31,13 +32,11 @@ const [state, dispatch] = (0, react_1.useReducer)(reducer, getInitialState()); | ||
} | ||
exports.BettererTasksStateContext = (0, react_1.createContext)({ | ||
error() { | ||
throw new Error(); | ||
}, | ||
start() { | ||
throw new Error(); | ||
}, | ||
stop() { | ||
throw new Error(); | ||
exports.BettererTasksContext = (0, react_1.createContext)(null); | ||
function useTasks() { | ||
const context = (0, react_1.useContext)(exports.BettererTasksContext); | ||
if (context === null) { | ||
throw new errors_1.BettererError('Trying to use `BettererTasksContext` before it was created` π₯'); | ||
} | ||
}); | ||
return context; | ||
} | ||
exports.useTasks = useTasks; | ||
function reducer(state, action) { | ||
@@ -44,0 +43,0 @@ switch (action.type) { |
@@ -1,4 +0,3 @@ | ||
import { BettererTasksStateAPI } from './useTasksState'; | ||
import { BettererTaskLog, BettererTaskLogs } from './types'; | ||
declare type BettererTaskState = { | ||
interface BettererTaskState { | ||
done: boolean; | ||
@@ -8,11 +7,14 @@ running: boolean; | ||
logs: BettererTaskLogs; | ||
finalLogs: BettererTaskLogs; | ||
error: Error | null; | ||
}; | ||
declare type BettererTaskStateAPI = BettererTasksStateAPI & { | ||
} | ||
interface BettererTaskStateAPI { | ||
error(error: Error): void; | ||
start(): void; | ||
stop(): void; | ||
reset(): void; | ||
status(status: BettererTaskLog): Promise<void>; | ||
log(status: BettererTaskLog): Promise<void>; | ||
}; | ||
} | ||
export declare function useTaskState(): [BettererTaskState, BettererTaskStateAPI]; | ||
export {}; | ||
//# sourceMappingURL=useTaskState.d.ts.map |
@@ -11,3 +11,2 @@ "use strict"; | ||
logs: [], | ||
finalLogs: [], | ||
error: null | ||
@@ -17,3 +16,3 @@ }; | ||
const [state, dispatch] = (0, react_1.useReducer)(reducer, INITIAL_STATE); | ||
const tasks = (0, react_1.useContext)(useTasksState_1.BettererTasksStateContext); | ||
const [, tasks] = (0, useTasksState_1.useTasks)(); | ||
const api = (0, react_1.useRef)({ | ||
@@ -55,6 +54,6 @@ reset() { | ||
case 'stop': { | ||
return Object.assign(Object.assign({}, state), { running: false, done: true, finalLogs: state.logs }); | ||
return Object.assign(Object.assign({}, state), { running: false, done: true }); | ||
} | ||
case 'error': { | ||
return Object.assign(Object.assign({}, state), { error: action.data, running: false, done: true, finalLogs: state.logs }); | ||
return Object.assign(Object.assign({}, state), { error: action.data, running: false, done: true }); | ||
} | ||
@@ -61,0 +60,0 @@ default: { |
{ | ||
"name": "@betterer/tasks", | ||
"description": "task runner and loggerr for @betterer/betterer", | ||
"version": "5.0.0-alpha.0", | ||
"version": "5.0.0", | ||
"license": "MIT", | ||
@@ -24,3 +24,4 @@ "publishConfig": { | ||
"scripts": { | ||
"compile": "tsc -b ." | ||
"compile": "tsc -b .", | ||
"api": "api-extractor run --local --verbose" | ||
}, | ||
@@ -31,3 +32,3 @@ "engines": { | ||
"dependencies": { | ||
"@betterer/errors": "^4.0.0", | ||
"@betterer/errors": "^5.0.0", | ||
"chalk": "^4.1.2", | ||
@@ -38,3 +39,3 @@ "ink": "^3.0.9", | ||
}, | ||
"gitHead": "0176888b938dd85bb987857746472dc2abad5439" | ||
"gitHead": "2a19f45ea49f8df4b53e3608216253d25e1ad047" | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
53293
49
592
0
+ Added@betterer/errors@5.3.0(transitive)
- Removed@betterer/errors@4.0.0(transitive)
Updated@betterer/errors@^5.0.0