Load user tooth logs (#816)
This commit is contained in:
parent
9c746cdf43
commit
2fbc2be2e0
3
.env
3
.env
|
@ -4,7 +4,4 @@ VITE_WEB_URL=http://localhost:5173
|
|||
VITE_SENTRY_DSN=
|
||||
VITE_GTM_ID=
|
||||
|
||||
# TODO: remove this later
|
||||
VITE_CDN_URL="https://public-bucket.speedytuner.app"
|
||||
|
||||
VITE_POCKETBASE_API_URL="https://api.hypertuner.cloud"
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import Pako from 'pako';
|
||||
import * as Sentry from '@sentry/browser';
|
||||
import { fetchEnv } from '../utils/env';
|
||||
import { API_URL } from '../pocketbase';
|
||||
import { Collections } from '../@types/pocketbase-types';
|
||||
import useDb from './useDb';
|
||||
|
@ -9,8 +8,6 @@ import {
|
|||
OnProgress,
|
||||
} from '../utils/http';
|
||||
|
||||
export const CDN_URL = fetchEnv('VITE_CDN_URL');
|
||||
|
||||
const useServerStorage = () => {
|
||||
const { getIni } = useDb();
|
||||
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
/* eslint-disable import/no-webpack-loader-syntax */
|
||||
import {
|
||||
generatePath,
|
||||
Link,
|
||||
useMatch,
|
||||
useNavigate,
|
||||
} from 'react-router-dom';
|
||||
import {
|
||||
useCallback,
|
||||
useEffect,
|
||||
|
@ -19,20 +24,16 @@ import {
|
|||
FileTextOutlined,
|
||||
GlobalOutlined,
|
||||
} from '@ant-design/icons';
|
||||
import * as Sentry from '@sentry/browser';
|
||||
import useBreakpoint from 'antd/lib/grid/hooks/useBreakpoint';
|
||||
import { connect } from 'react-redux';
|
||||
import PerfectScrollbar from 'react-perfect-scrollbar';
|
||||
import Pako from 'pako';
|
||||
import {
|
||||
AppState,
|
||||
ConfigState,
|
||||
LogsState,
|
||||
ToothLogsState,
|
||||
TuneDataState,
|
||||
UIState,
|
||||
} from '../types/state';
|
||||
import {
|
||||
loadCompositeLogs,
|
||||
loadToothLogs,
|
||||
} from '../utils/api';
|
||||
import store from '../store';
|
||||
import { formatBytes } from '../utils/numbers';
|
||||
import CompositeCanvas from '../components/TriggerLogs/CompositeCanvas';
|
||||
|
@ -43,6 +44,10 @@ import TriggerLogsParser, {
|
|||
import ToothCanvas from '../components/TriggerLogs/ToothCanvas';
|
||||
import Loader from '../components/Loader';
|
||||
import { Colors } from '../utils/colors';
|
||||
import { Routes } from '../routes';
|
||||
import { removeFilenameSuffix } from '../pocketbase';
|
||||
import useServerStorage from '../hooks/useServerStorage';
|
||||
import { isAbortedRequest } from '../utils/error';
|
||||
|
||||
const { Content } = Layout;
|
||||
const { Step } = Steps;
|
||||
|
@ -51,18 +56,27 @@ const edgeUnknown = 'Unknown';
|
|||
|
||||
const badgeStyle = { backgroundColor: Colors.TEXT };
|
||||
|
||||
const mapStateToProps = (state: AppState) => ({
|
||||
ui: state.ui,
|
||||
status: state.status,
|
||||
config: state.config,
|
||||
loadedLogs: state.logs,
|
||||
});
|
||||
|
||||
const margin = 30;
|
||||
const sidebarWidth = 250;
|
||||
const minCanvasHeightInner = 600;
|
||||
|
||||
const Diagnose = ({ ui, config, loadedLogs }: { ui: UIState, config: ConfigState, loadedLogs: LogsState }) => {
|
||||
const mapStateToProps = (state: AppState) => ({
|
||||
ui: state.ui,
|
||||
status: state.status,
|
||||
config: state.config,
|
||||
loadedToothLogs: state.toothLogs,
|
||||
tuneData: state.tuneData,
|
||||
});
|
||||
|
||||
const Diagnose = ({
|
||||
ui,
|
||||
loadedToothLogs,
|
||||
tuneData,
|
||||
}: {
|
||||
ui: UIState;
|
||||
loadedToothLogs: ToothLogsState;
|
||||
tuneData: TuneDataState;
|
||||
}) => {
|
||||
const { lg } = useBreakpoint();
|
||||
const { Sider } = Layout;
|
||||
const [progress, setProgress] = useState(0);
|
||||
|
@ -73,11 +87,15 @@ const Diagnose = ({ ui, config, loadedLogs }: { ui: UIState, config: ConfigState
|
|||
const contentRef = useRef<HTMLDivElement | null>(null);
|
||||
const [canvasWidth, setCanvasWidth] = useState(0);
|
||||
const [canvasHeight, setCanvasHeight] = useState(0);
|
||||
const routeMatch = useMatch(Routes.TUNE_DIAGNOSE_FILE);
|
||||
const { fetchLogFileWithProgress } = useServerStorage();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const calculateCanvasSize = useCallback(() => {
|
||||
setCanvasWidth((contentRef.current?.clientWidth || 0) - margin);
|
||||
|
||||
if (window.innerHeight > minCanvasHeightInner) {
|
||||
setCanvasHeight(Math.round((window.innerHeight - 250) / 2));
|
||||
setCanvasHeight(Math.round(window.innerHeight - 250));
|
||||
} else {
|
||||
setCanvasHeight(minCanvasHeightInner / 2);
|
||||
}
|
||||
|
@ -91,47 +109,92 @@ const Diagnose = ({ ui, config, loadedLogs }: { ui: UIState, config: ConfigState
|
|||
store.dispatch({ type: 'ui/sidebarCollapsed', payload: collapsed });
|
||||
},
|
||||
};
|
||||
const [logs, setLogs] = useState<CompositeLogEntry[]>();
|
||||
const [toothLogs, setToothLogs] = useState<ToothLogEntry[]>();
|
||||
|
||||
useEffect(() => {
|
||||
const controller = new AbortController();
|
||||
const { signal } = controller;
|
||||
|
||||
const loadData = async () => {
|
||||
const pako = await import('pako');
|
||||
const logFileName = routeMatch?.params.fileName;
|
||||
|
||||
if (!logFileName) {
|
||||
return;
|
||||
}
|
||||
|
||||
// user didn't upload any logs
|
||||
if (tuneData && (tuneData.toothLogFiles || []).length === 0) {
|
||||
navigate(Routes.HUB);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const compositeRaw = await loadCompositeLogs((percent, total, edge) => {
|
||||
const raw = await fetchLogFileWithProgress(tuneData.id, logFileName, (percent, total, edge) => {
|
||||
setProgress(percent);
|
||||
setFileSize(formatBytes(total));
|
||||
setEdgeLocation(edge || edgeUnknown);
|
||||
}, signal);
|
||||
|
||||
const toothRaw = await loadToothLogs(undefined, signal);
|
||||
|
||||
setFileSize(formatBytes(compositeRaw.byteLength));
|
||||
setFileSize(formatBytes(raw.byteLength));
|
||||
setStep(1);
|
||||
|
||||
const resultComposite = (new TriggerLogsParser(pako.inflate(new Uint8Array(compositeRaw))))
|
||||
.parse()
|
||||
.getCompositeLogs();
|
||||
const resultTooth = (new TriggerLogsParser(pako.inflate(new Uint8Array(toothRaw))))
|
||||
.parse()
|
||||
.getToothLogs();
|
||||
const parser = new TriggerLogsParser(Pako.inflate(new Uint8Array(raw))).parse();
|
||||
|
||||
setLogs(resultComposite);
|
||||
setToothLogs(resultTooth);
|
||||
let type = '';
|
||||
let result: CompositeLogEntry[] | ToothLogEntry[] = [];
|
||||
|
||||
if (parser.isComposite()) {
|
||||
type = 'composite';
|
||||
result = parser.getCompositeLogs();
|
||||
}
|
||||
|
||||
if (parser.isTooth()) {
|
||||
type = 'tooth';
|
||||
result = parser.getToothLogs();
|
||||
}
|
||||
|
||||
store.dispatch({
|
||||
type: 'toothLogs/load', payload: {
|
||||
fileName: logFileName,
|
||||
logs: result,
|
||||
type,
|
||||
},
|
||||
});
|
||||
|
||||
setStep(2);
|
||||
} catch (error) {
|
||||
if (isAbortedRequest(error as Error)) {
|
||||
return;
|
||||
}
|
||||
|
||||
setFetchError(error as Error);
|
||||
Sentry.captureException(error);
|
||||
console.error(error);
|
||||
}
|
||||
};
|
||||
|
||||
// first visit, logs are not loaded yet
|
||||
if (!loadedToothLogs.type && tuneData?.tuneId) {
|
||||
loadData();
|
||||
}
|
||||
|
||||
// file changed, reload
|
||||
if (loadedToothLogs.type && loadedToothLogs.fileName !== routeMatch?.params.fileName) {
|
||||
// setToothLogs(undefined);
|
||||
// setCompositeLogs(undefined);
|
||||
store.dispatch({ type: 'toothLogs/load', payload: {} });
|
||||
loadData();
|
||||
}
|
||||
|
||||
// user navigated to logs root page
|
||||
if (!routeMatch?.params.fileName && tuneData.toothLogFiles?.length) {
|
||||
// either redirect to the first log or to the latest selected
|
||||
if (loadedToothLogs.fileName) {
|
||||
navigate(generatePath(Routes.TUNE_DIAGNOSE_FILE, { tuneId: tuneData.tuneId, fileName: loadedToothLogs.fileName }));
|
||||
} else {
|
||||
const firstLogFile = (tuneData.toothLogFiles || [])[0];
|
||||
navigate(generatePath(Routes.TUNE_DIAGNOSE_FILE, { tuneId: tuneData.tuneId, fileName: firstLogFile }));
|
||||
}
|
||||
}
|
||||
|
||||
calculateCanvasSize();
|
||||
|
||||
window.addEventListener('resize', calculateCanvasSize);
|
||||
|
@ -140,12 +203,32 @@ const Diagnose = ({ ui, config, loadedLogs }: { ui: UIState, config: ConfigState
|
|||
controller.abort();
|
||||
window.removeEventListener('resize', calculateCanvasSize);
|
||||
};
|
||||
}, [calculateCanvasSize, loadedLogs, ui.sidebarCollapsed]);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [calculateCanvasSize, routeMatch?.params.fileName, ui.sidebarCollapsed, tuneData?.tuneId]);
|
||||
|
||||
const graphSection = () => {
|
||||
switch (loadedToothLogs.type) {
|
||||
case 'composite':
|
||||
return <CompositeCanvas
|
||||
data={loadedToothLogs.logs as CompositeLogEntry[]}
|
||||
width={canvasWidth}
|
||||
height={canvasHeight}
|
||||
/>;
|
||||
case 'tooth':
|
||||
return <ToothCanvas
|
||||
data={loadedToothLogs.logs}
|
||||
width={canvasWidth}
|
||||
height={canvasHeight}
|
||||
/>;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Sider {...(siderProps as any)} className="app-sidebar">
|
||||
{!logs && !(loadedLogs.logs || []).length ?
|
||||
{!loadedToothLogs.type ?
|
||||
<Loader />
|
||||
:
|
||||
!ui.sidebarCollapsed &&
|
||||
|
@ -155,15 +238,26 @@ const Diagnose = ({ ui, config, loadedLogs }: { ui: UIState, config: ConfigState
|
|||
items={[
|
||||
{
|
||||
label: (
|
||||
<Badge size="small" style={badgeStyle} count={1} offset={[10, -3]}>
|
||||
<Badge size="small" style={badgeStyle} count={tuneData?.toothLogFiles?.length} offset={[10, -3]}>
|
||||
<FileTextOutlined />Files
|
||||
</Badge>
|
||||
),
|
||||
key: 'files',
|
||||
children: (
|
||||
<PerfectScrollbar options={{ suppressScrollX: true }}>
|
||||
<Typography.Paragraph>tooth.csv</Typography.Paragraph>
|
||||
<Typography.Paragraph>composite.csv</Typography.Paragraph>
|
||||
{tuneData?.toothLogFiles?.map((fileName) => (
|
||||
<Typography.Paragraph key={fileName} ellipsis>
|
||||
<Link
|
||||
to={generatePath(Routes.TUNE_DIAGNOSE_FILE, { tuneId: tuneData.tuneId, fileName })}
|
||||
style={
|
||||
routeMatch?.params.fileName === fileName ?
|
||||
{} : { color: 'inherit' }
|
||||
}
|
||||
>
|
||||
{removeFilenameSuffix(fileName)}
|
||||
</Link>
|
||||
</Typography.Paragraph>
|
||||
))}
|
||||
</PerfectScrollbar>
|
||||
),
|
||||
},
|
||||
|
@ -174,22 +268,9 @@ const Diagnose = ({ ui, config, loadedLogs }: { ui: UIState, config: ConfigState
|
|||
<Layout style={{ width: '100%', textAlign: 'center', marginTop: 50 }}>
|
||||
<Content>
|
||||
<div ref={contentRef} style={{ width: '100%', marginRight: margin }}>
|
||||
{toothLogs && logs
|
||||
{loadedToothLogs.type
|
||||
?
|
||||
(
|
||||
<Space direction="vertical" size="large">
|
||||
<ToothCanvas
|
||||
data={toothLogs!}
|
||||
width={canvasWidth}
|
||||
height={canvasHeight}
|
||||
/>
|
||||
<CompositeCanvas
|
||||
data={logs!}
|
||||
width={canvasWidth}
|
||||
height={canvasHeight}
|
||||
/>
|
||||
</Space>
|
||||
)
|
||||
graphSection()
|
||||
:
|
||||
<Space
|
||||
direction="vertical"
|
||||
|
|
|
@ -61,6 +61,8 @@ import Loader from '../components/Loader';
|
|||
import { Colors } from '../utils/colors';
|
||||
import useServerStorage from '../hooks/useServerStorage';
|
||||
import { Routes } from '../routes';
|
||||
import { removeFilenameSuffix } from '../pocketbase';
|
||||
import { isAbortedRequest } from '../utils/error';
|
||||
|
||||
const { Content } = Layout;
|
||||
const { Step } = Steps;
|
||||
|
@ -84,10 +86,10 @@ const Logs = ({
|
|||
loadedLogs,
|
||||
tuneData,
|
||||
}: {
|
||||
ui: UIState,
|
||||
config: ConfigState,
|
||||
loadedLogs: LogsState,
|
||||
tuneData: TuneDataState,
|
||||
ui: UIState;
|
||||
config: ConfigState;
|
||||
loadedLogs: LogsState;
|
||||
tuneData: TuneDataState;
|
||||
}) => {
|
||||
const { lg } = useBreakpoint();
|
||||
const { Sider } = Layout;
|
||||
|
@ -188,8 +190,7 @@ const Logs = ({
|
|||
|
||||
setFileSize(formatBytes(raw.byteLength));
|
||||
|
||||
const pako = await import('pako');
|
||||
worker.postMessage(pako.inflate(new Uint8Array(raw)).buffer);
|
||||
worker.postMessage(raw);
|
||||
|
||||
worker.onmessage = ({ data }) => {
|
||||
switch (data.type) {
|
||||
|
@ -221,6 +222,10 @@ const Logs = ({
|
|||
}
|
||||
};
|
||||
} catch (error) {
|
||||
if (isAbortedRequest(error as Error)) {
|
||||
return;
|
||||
}
|
||||
|
||||
setFetchError(error as Error);
|
||||
}
|
||||
};
|
||||
|
@ -264,12 +269,12 @@ const Logs = ({
|
|||
window.removeEventListener('resize', calculateCanvasSize);
|
||||
};
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [calculateCanvasSize, config?.datalog, config?.outputChannels, loadedLogs, ui.sidebarCollapsed, routeMatch?.params.fileName]);
|
||||
}, [calculateCanvasSize, config?.datalog, config?.outputChannels, ui.sidebarCollapsed, routeMatch?.params.fileName]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Sider {...(siderProps as any)} className="app-sidebar">
|
||||
{!logs && !(loadedLogs.logs || []).length ?
|
||||
{!(loadedLogs.logs || []).length ?
|
||||
<Loader />
|
||||
:
|
||||
!ui.sidebarCollapsed &&
|
||||
|
@ -318,15 +323,15 @@ const Logs = ({
|
|||
},
|
||||
{
|
||||
label: (
|
||||
<Badge size="small" style={badgeStyle} count={tuneData.logFiles?.length} offset={[10, -3]}>
|
||||
<Badge size="small" style={badgeStyle} count={tuneData?.logFiles?.length} offset={[10, -3]}>
|
||||
<FileTextOutlined />Files
|
||||
</Badge>
|
||||
),
|
||||
key: 'files',
|
||||
children: (
|
||||
<PerfectScrollbar options={{ suppressScrollX: true }}>
|
||||
{tuneData.logFiles?.map((fileName) => (
|
||||
<Typography.Paragraph key={fileName}>
|
||||
{tuneData?.logFiles?.map((fileName) => (
|
||||
<Typography.Paragraph key={fileName} ellipsis>
|
||||
<Link
|
||||
to={generatePath(Routes.TUNE_LOGS_FILE, { tuneId: tuneData.tuneId, fileName })}
|
||||
style={
|
||||
|
@ -334,7 +339,7 @@ const Logs = ({
|
|||
{} : { color: 'inherit' }
|
||||
}
|
||||
>
|
||||
{fileName}
|
||||
{removeFilenameSuffix(fileName)}
|
||||
</Link>
|
||||
</Typography.Paragraph>
|
||||
))}
|
||||
|
|
|
@ -69,6 +69,7 @@ import {
|
|||
TunesRecordFull,
|
||||
TunesRecordPartial,
|
||||
} from '../types/dbData';
|
||||
import { removeFilenameSuffix } from '../pocketbase';
|
||||
|
||||
const { Item, useForm } = Form;
|
||||
|
||||
|
@ -139,8 +140,6 @@ const UploadPage = () => {
|
|||
|
||||
const noop = () => { };
|
||||
|
||||
const removeFilenameSuffix = (filename: string) => filename.replace(/(.+)(_\w{10})(\.\w+)$/, '$1$3');
|
||||
|
||||
const goToNewTune = () => navigate(generatePath(Routes.TUNE_TUNE, {
|
||||
tuneId: newTuneId!,
|
||||
}));
|
||||
|
|
|
@ -17,6 +17,8 @@ const formatError = (error: any) => {
|
|||
return message;
|
||||
};
|
||||
|
||||
const removeFilenameSuffix = (filename: string) => filename.replace(/(.+)(_\w{10})(\.\w+)$/, '$1$3');
|
||||
|
||||
// NOTE: PocketBase doesn't return ISO time, this may change here: https://github.com/pocketbase/pocketbase/issues/376
|
||||
const formatTime = (time: string) => new Date(`${time}Z`).toLocaleString();
|
||||
|
||||
|
@ -25,4 +27,5 @@ export {
|
|||
client,
|
||||
formatError,
|
||||
formatTime,
|
||||
removeFilenameSuffix,
|
||||
};
|
||||
|
|
|
@ -9,6 +9,7 @@ import {
|
|||
AppState,
|
||||
ConfigState,
|
||||
LogsState,
|
||||
ToothLogsState,
|
||||
TuneDataState,
|
||||
TuneState,
|
||||
UpdateTunePayload,
|
||||
|
@ -25,6 +26,7 @@ const setTuneId = createAction<string>('navigation/tuneId');
|
|||
|
||||
// logs
|
||||
const loadLogs = createAction<LogsState>('logs/load');
|
||||
const loadToothLogs = createAction<ToothLogsState>('toothLogs/load');
|
||||
|
||||
// status bar
|
||||
const setStatus = createAction<string>('status');
|
||||
|
@ -40,6 +42,7 @@ const initialState: AppState = {
|
|||
},
|
||||
tuneData: {} as any,
|
||||
logs: {} as any,
|
||||
toothLogs: {} as any,
|
||||
config: {} as any,
|
||||
ui: {
|
||||
sidebarCollapsed: false,
|
||||
|
@ -66,6 +69,9 @@ const rootReducer = createReducer(initialState, (builder) => {
|
|||
.addCase(loadLogs, (state: AppState, action) => {
|
||||
state.logs = action.payload;
|
||||
})
|
||||
.addCase(loadToothLogs, (state: AppState, action) => {
|
||||
state.toothLogs = action.payload;
|
||||
})
|
||||
.addCase(updateTune, (state: AppState, action) => {
|
||||
state.tune.constants[action.payload.name].value = action.payload.value;
|
||||
})
|
||||
|
|
|
@ -3,6 +3,10 @@ import {
|
|||
Logs,
|
||||
TuneWithDetails,
|
||||
} from '@hyper-tuner/types';
|
||||
import {
|
||||
CompositeLogEntry,
|
||||
ToothLogEntry,
|
||||
} from '../utils/logs/TriggerLogsParser';
|
||||
import { TunesRecordFull } from './dbData';
|
||||
|
||||
export interface ConfigState extends Config {}
|
||||
|
@ -16,6 +20,12 @@ export interface LogsState {
|
|||
logs: Logs;
|
||||
}
|
||||
|
||||
export interface ToothLogsState {
|
||||
fileName: string;
|
||||
type: 'tooth' | 'composite';
|
||||
logs: CompositeLogEntry[] | ToothLogEntry[];
|
||||
}
|
||||
|
||||
export interface UIState {
|
||||
sidebarCollapsed: boolean;
|
||||
}
|
||||
|
@ -33,6 +43,7 @@ export interface AppState {
|
|||
tuneData: TuneDataState;
|
||||
config: ConfigState;
|
||||
logs: LogsState,
|
||||
toothLogs: ToothLogsState,
|
||||
ui: UIState;
|
||||
status: StatusState;
|
||||
navigation: NavigationState;
|
||||
|
|
|
@ -4,20 +4,18 @@ import store from '../store';
|
|||
import stdDialogs from '../data/standardDialogs';
|
||||
import help from '../data/help';
|
||||
import { divider } from '../data/constants';
|
||||
import {
|
||||
fetchWithProgress,
|
||||
OnProgress,
|
||||
} from './http';
|
||||
import TuneParser from './tune/TuneParser';
|
||||
import useServerStorage, { CDN_URL } from '../hooks/useServerStorage';
|
||||
import useServerStorage from '../hooks/useServerStorage';
|
||||
import { TunesRecordFull } from '../types/dbData';
|
||||
import { iniLoadingError } from '../pages/auth/notifications';
|
||||
|
||||
// TODO: refactor this!!
|
||||
// eslint-disable-next-line import/prefer-default-export
|
||||
export const loadTune = async (tuneData: TunesRecordFull | null) => {
|
||||
if (tuneData === null) {
|
||||
store.dispatch({ type: 'config/load', payload: null });
|
||||
store.dispatch({ type: 'tune/load', payload: null });
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -62,24 +60,3 @@ export const loadTune = async (tuneData: TunesRecordFull | null) => {
|
|||
iniLoadingError((error as Error));
|
||||
}
|
||||
};
|
||||
|
||||
export const loadLogs = (onProgress?: OnProgress, signal?: AbortSignal) =>
|
||||
fetchWithProgress(
|
||||
`${CDN_URL}/public/temp/long.mlg.gz`,
|
||||
onProgress,
|
||||
signal,
|
||||
).then((response) => response);
|
||||
|
||||
export const loadCompositeLogs = (onProgress?: OnProgress, signal?: AbortSignal) =>
|
||||
fetchWithProgress(
|
||||
`${CDN_URL}/public/temp/composite_1.csv.gz`,
|
||||
onProgress,
|
||||
signal,
|
||||
).then((response) => response);
|
||||
|
||||
export const loadToothLogs = (onProgress?: OnProgress, signal?: AbortSignal) =>
|
||||
fetchWithProgress(
|
||||
`${CDN_URL}/public/temp/tooth_3.csv.gz`,
|
||||
onProgress,
|
||||
signal,
|
||||
).then((response) => response);
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
// eslint-disable-next-line import/prefer-default-export
|
||||
export const isAbortedRequest = (error: Error): boolean => error.message === 'The user aborted a request.';
|
|
@ -49,11 +49,9 @@ class TriggerLogsParser implements ParserInterface {
|
|||
this.parseCompositeLogs(this.raw);
|
||||
this.parseToothLogs(this.raw);
|
||||
|
||||
if (this.resultComposite.length > 0) {
|
||||
if (this.resultComposite.length > this.resultTooth.length) {
|
||||
this.isCompositeLogs = true;
|
||||
}
|
||||
|
||||
if (this.resultTooth.length > 0) {
|
||||
} else {
|
||||
this.isToothLogs = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/* eslint-disable no-bitwise */
|
||||
|
||||
import { Parser } from 'mlg-converter';
|
||||
import Pako from 'pako';
|
||||
|
||||
// eslint-disable-next-line no-restricted-globals
|
||||
const ctx: Worker = self as any;
|
||||
|
@ -8,7 +9,7 @@ const ctx: Worker = self as any;
|
|||
ctx.addEventListener('message', ({ data }: { data: ArrayBuffer }) => {
|
||||
try {
|
||||
const t0 = performance.now();
|
||||
const result = new Parser(data).parse((progress) => {
|
||||
const result = new Parser(Pako.inflate(new Uint8Array(data)).buffer).parse((progress) => {
|
||||
ctx.postMessage({
|
||||
type: 'progress',
|
||||
progress,
|
||||
|
|
Loading…
Reference in New Issue