Skip to content

Commit

Permalink
react-experiment: rename log prop to onLog (#190)
Browse files Browse the repository at this point in the history
also includes some speed improvements.
  • Loading branch information
QuentinRoy authored Nov 27, 2023
1 parent 2d3d87e commit f01d46f
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 34 deletions.
5 changes: 5 additions & 0 deletions .changeset/poor-horses-love.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@lightmill/react-experiment': major
---

Rename Run log prop to onLog
61 changes: 31 additions & 30 deletions packages/react-experiment/src/run.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export function Run<T extends RegisteredTask>({
confirmBeforeUnload = true,
...useRunParameter
}: RunProps<T, RegisteredLog>): JSX.Element | null {
const { log, ...state } = useRun(useRunParameter);
const { onLog, ...state } = useRun(useRunParameter);
useConfirmBeforeUnload(confirmBeforeUnload && state.status !== 'completed');

switch (state.status) {
Expand All @@ -36,7 +36,7 @@ export function Run<T extends RegisteredTask>({
throw new Error(`No task registered for type ${state.task.type}`);
}
return (
<loggerContext.Provider value={log}>
<loggerContext.Provider value={onLog}>
<timelineContext.Provider value={state}>
{elements.tasks[type]}
</timelineContext.Provider>
Expand All @@ -46,7 +46,7 @@ export function Run<T extends RegisteredTask>({

case 'completed':
return elements.completed == null ? null : (
<loggerContext.Provider value={log}>
<loggerContext.Provider value={onLog}>
{elements.completed}
</loggerContext.Provider>
);
Expand All @@ -58,7 +58,7 @@ export function Run<T extends RegisteredTask>({
case 'canceled':
case 'loading':
return (
<loggerContext.Provider value={log}>
<loggerContext.Provider value={onLog}>
{elements.loading}
</loggerContext.Provider>
);
Expand All @@ -71,23 +71,23 @@ export function Run<T extends RegisteredTask>({

type UseRunParameter<Task extends { type: string }, Log> = {
onCompleted?: () => void;
log?: Logger<Log>;
onLog?: Logger<Log>;
resumeAfter?: { type: Task['type']; number: number };
} & (
| { timeline: Timeline<Task>; loading?: boolean }
| { timeline?: Timeline<Task> | null; loading: true }
);
type RunState<Task, Log> = Exclude<TimelineState<Task>, { status: 'error' }> & {
log: ((newLog: Log) => void) | null;
onLog: ((newLog: Log) => void) | null;
};
function useRun<T extends { type: string }, L>({
onCompleted,
timeline,
resumeAfter,
loading = false,
log,
onLog,
}: UseRunParameter<T, L>): RunState<T, L> {
const { log: logWrapper, ...loggerState } = useLogWrapper(log);
const { onLog: logWrapper, ...loggerState } = useLogWrapper(onLog);

let timelineRef = React.useRef(timeline);
// Prevent changes to timeline once set.
Expand All @@ -112,38 +112,39 @@ function useRun<T extends { type: string }, L>({
throw loggerState.error;
}
if (loading) {
return { status: 'loading', log: logWrapper };
return { status: 'loading', onLog: logWrapper };
} else if (timeline == null) {
throw new Error('Timeline must be set when loading is false');
}
return { ...timelineState, log: logWrapper };
return { ...timelineState, onLog: logWrapper };
}

type LoggerState = { status: 'ok' } | { status: 'error'; error: Error };
function useLogWrapper<L>(log?: Logger<L>): LoggerState & {
log: ((newLog: L) => void) | null;
} {
const [loggerState, setLoggerState] = React.useState<LoggerState>({
status: 'ok',
});

type LoggerState<L> =
| { status: 'ok'; onLog: ((newLog: L) => void) | null }
| { status: 'error'; error: Error; onLog: ((newLog: L) => void) | null };
function useLogWrapper<L>(onLog?: Logger<L>): LoggerState<L> {
const logWrapper = React.useMemo(() => {
if (log == null) return null;
const thisLogger = log;
if (onLog == null) return null;
const thisLogger = onLog;
return function logWrapper(newLog: L) {
thisLogger(newLog).catch((error) => {
if (error instanceof Error) {
let newError = new Error(`Could not add log : ${error.message}`);
newError.stack = error.stack;
setLoggerState({ status: 'error', error: newError });
} else {
let newError = new Error('Could not add log');
setLoggerState({ status: 'error', error: newError });
}
let newError: Error =
error instanceof Error
? new Error(`Could not add log : ${error.message}`, {
cause: error,
})
: new Error('Could not add log');
setLoggerState({ status: 'error', error: newError, onLog: logWrapper });
});
};
}, [log]);
return { ...loggerState, log: logWrapper };
}, [onLog]);

const [loggerState, setLoggerState] = React.useState<LoggerState<L>>({
status: 'ok',
onLog: logWrapper,
});

return loggerState;
}

function useConfirmBeforeUnload(isEnabled: boolean) {
Expand Down
2 changes: 1 addition & 1 deletion packages/react-experiment/tsconfig.build.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"$schema": "https://json.schemastore.org/tsconfig",
"extends": "../../tsconfig.json",
"compilerOptions": {
"lib": ["DOM", "ES2020"],
"lib": ["DOM", "ES2022"],
"rootDir": "./src",
"outDir": "dist",
"jsx": "react-jsx"
Expand Down
2 changes: 1 addition & 1 deletion packages/react-experiment/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"$schema": "https://json.schemastore.org/tsconfig",
"extends": "../../tsconfig.json",
"compilerOptions": {
"lib": ["DOM", "ES2020"],
"lib": ["DOM", "ES2022"],
"jsx": "react-jsx",
"types": ["vitest/globals", "@testing-library/jest-dom"],
"noEmit": true
Expand Down
4 changes: 2 additions & 2 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"compilerOptions": {
"target": "es2020",
"lib": ["es2020"],
"target": "es2022",
"lib": ["es2022"],
"module": "Node16",
"moduleResolution": "Node16",
"noImplicitAny": true,
Expand Down

0 comments on commit f01d46f

Please sign in to comment.