From 4db3b7274358097ba1a4fbdf93cfac5b3ec509ed Mon Sep 17 00:00:00 2001 From: LightFLP Date: Wed, 20 Sep 2023 10:00:37 +0200 Subject: [PATCH 01/10] Add react-fast-compare package --- package-lock.json | 6 ++++++ package.json | 1 + 2 files changed, 7 insertions(+) diff --git a/package-lock.json b/package-lock.json index b6863e3..b3ff159 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ "@mui/material": "^5.14.0", "framer-motion": "^10.15.1", "lodash": "^4.17.21", + "react-fast-compare": "^3.2.2", "react-resize-detector": "^8.0.4" }, "devDependencies": { @@ -4940,6 +4941,11 @@ "react": "^18.2.0" } }, + "node_modules/react-fast-compare": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz", + "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==" + }, "node_modules/react-is": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", diff --git a/package.json b/package.json index 61b48bb..8d72069 100644 --- a/package.json +++ b/package.json @@ -71,6 +71,7 @@ "@mui/material": "^5.14.0", "framer-motion": "^10.15.1", "lodash": "^4.17.21", + "react-fast-compare": "^3.2.2", "react-resize-detector": "^8.0.4" } } From 511ceeacba48fa934121c9a2386015748a4c91ac Mon Sep 17 00:00:00 2001 From: LightFLP Date: Wed, 20 Sep 2023 10:03:04 +0200 Subject: [PATCH 02/10] Use react-fast-compare in Structure-related components re-render checks --- src/viewer/structures/StructureDialog.tsx | 2 +- src/viewer/structures/StructureTable.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/viewer/structures/StructureDialog.tsx b/src/viewer/structures/StructureDialog.tsx index 216fcfe..87ddf85 100644 --- a/src/viewer/structures/StructureDialog.tsx +++ b/src/viewer/structures/StructureDialog.tsx @@ -29,7 +29,7 @@ import { structureDialogBackdropStyle, structureDialogDialogStyle, } from "../hooks/useStyleManager"; -import isEqual from "lodash/isEqual"; +import isEqual from "react-fast-compare"; import cloneDeep from "lodash/cloneDeep"; import ContextMenu from "../contextMenu/contextMenu"; import { styled } from "@mui/material/styles"; diff --git a/src/viewer/structures/StructureTable.tsx b/src/viewer/structures/StructureTable.tsx index 48fc23e..93648de 100644 --- a/src/viewer/structures/StructureTable.tsx +++ b/src/viewer/structures/StructureTable.tsx @@ -23,7 +23,7 @@ import { getStructureTableLinkStyle, } from "../hooks/useStyleManager"; import { getReactElementsFromCellContents } from "../hooks/useWildcardManager"; -import isEqual from "lodash/isEqual"; +import isEqual from "react-fast-compare"; interface Props { headerColumns: Header[]; From 23d03d7c6ac274e91963b785deef09333d129bb1 Mon Sep 17 00:00:00 2001 From: LightFLP Date: Wed, 20 Sep 2023 11:15:08 +0200 Subject: [PATCH 03/10] Fix ContextMenu not showing in StructureDialog --- src/viewer/contextMenu/contextMenu.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/viewer/contextMenu/contextMenu.tsx b/src/viewer/contextMenu/contextMenu.tsx index 4b7d8df..f1ea2f3 100644 --- a/src/viewer/contextMenu/contextMenu.tsx +++ b/src/viewer/contextMenu/contextMenu.tsx @@ -67,12 +67,13 @@ export default class ContextMenu extends React.PureComponent { handleContextMenu = (e) => { e.preventDefault(); + const path = e.composedPath(); this.setState({ xPos: e.pageX, yPos: e.pageY, showMenu: true, - anchorDivId: e.path[0].id, + anchorDivId: path[0].id, }); }; From c88801430eeffd9d1935ca1984481379219f18cb Mon Sep 17 00:00:00 2001 From: LightFLP Date: Mon, 25 Sep 2023 16:02:53 +0200 Subject: [PATCH 04/10] Implement maps instead of number arrays for logEntryRangess --- src/viewer/App.tsx | 28 +++++++------ src/viewer/hooks/useLogSearchManager.ts | 19 ++++----- .../useStructureRegularExpressionManager.ts | 42 +++++++++---------- src/viewer/types.d.ts | 5 +++ 4 files changed, 49 insertions(+), 45 deletions(-) diff --git a/src/viewer/App.tsx b/src/viewer/App.tsx index 531992f..991e588 100644 --- a/src/viewer/App.tsx +++ b/src/viewer/App.tsx @@ -3,7 +3,7 @@ import LogFile from "./LogFile"; import LogView from "./log/LogView"; import MinimapView from "./minimap/MinimapView"; import Tooltip from "@mui/material/Tooltip"; -import { LogViewState, StructureMatchId, RowProperty, Segment } from "./types"; +import { LogViewState, StructureMatchId, RowProperty, Segment, LogEntryCharRanges } from "./types"; import { LOG_HEADER_HEIGHT, MINIMAP_COLUMN_WIDTH, @@ -18,7 +18,7 @@ import { VSCodeOption, } from "@vscode/webview-ui-toolkit/react"; import { - useJsonObjectToTextRangesMap, + useGetCharIndicesForLogEntries, useStructureRegularExpressionSearch, } from "./hooks/useStructureRegularExpressionManager"; import { getRegularExpressionMatches, returnSearchIndices } from "./hooks/useLogSearchManager"; @@ -49,7 +49,7 @@ interface State { // Structure related logFileAsString: string; - logEntryRanges: number[][]; + logEntryCharRanges: LogEntryCharRanges; selectedLogRows: string[][]; // selectedRowsTypes: RowType[]; rowProperties: RowProperty[]; @@ -105,7 +105,7 @@ export default class App extends React.Component { caseSearch: false, selectedLogRows: [], rowProperties: [], - logEntryRanges: [], + logEntryCharRanges: {firstCharIndexMap: null, lastCharIndexMap: null}, showStructureDialog: false, structureMatches: [], structureMatchesLogRows: [], @@ -133,7 +133,7 @@ export default class App extends React.Component { const rules = message.rules.map((r) => Rule.fromJSON(r)).filter((r) => r); const lines = JSON.parse(message.text); const logFileText = JSON.stringify(lines, null, 2); - const textRanges = useJsonObjectToTextRangesMap(logFileText); + const charRangesMaps = useGetCharIndicesForLogEntries(logFileText); const logFile = LogFile.create(lines, rules); const newRowsProps = logFile.rows.map(() => constructNewRowProperty(true, true, SelectedRowType.None), @@ -141,7 +141,7 @@ export default class App extends React.Component { this.setState({ logFile, logFileAsString: logFileText, - logEntryRanges: textRanges, + logEntryCharRanges: charRangesMaps, rules, rowProperties: newRowsProps, }); @@ -181,11 +181,11 @@ export default class App extends React.Component { return constructNewRowProperty(true, true, SelectedRowType.None); else return constructNewRowProperty(false, false, SelectedRowType.None); }); - const textRanges = useJsonObjectToTextRangesMap(logFileText); + const charRangesMaps = useGetCharIndicesForLogEntries(logFileText); this.setState({ logFile, logFileAsString: logFileText, - logEntryRanges: textRanges, + logEntryCharRanges: charRangesMaps, rules, rowProperties: newRowsProps, }); @@ -319,13 +319,13 @@ export default class App extends React.Component { handleStructureMatching(expression: string) { const rowProperties = this.clearSelectedRowsTypes(); - const { logFileAsString, logEntryRanges } = this.state; + const { logFileAsString, logEntryCharRanges } = this.state; let { currentStructureMatch, currentStructureMatchIndex } = this.state; const structureMatches = useStructureRegularExpressionSearch( expression, logFileAsString, - logEntryRanges, + logEntryCharRanges, ); let structureMatchesLogRows: number[] = []; @@ -378,18 +378,20 @@ export default class App extends React.Component { } handleSegmentation(entryExpression: string, exitExpression: string) { - const { logFileAsString, logEntryRanges } = this.state; + const { logFileAsString, logEntryCharRanges } = this.state; const { collapsibleRows } = this.state; + console.log(entryExpression); + console.log(exitExpression); const entryMatches = getRegularExpressionMatches( entryExpression, logFileAsString, - logEntryRanges, + logEntryCharRanges, ); const exitMatches = getRegularExpressionMatches( exitExpression, logFileAsString, - logEntryRanges, + logEntryCharRanges, ); const stack: number[] = []; diff --git a/src/viewer/hooks/useLogSearchManager.ts b/src/viewer/hooks/useLogSearchManager.ts index 287c91e..7affd39 100644 --- a/src/viewer/hooks/useLogSearchManager.ts +++ b/src/viewer/hooks/useLogSearchManager.ts @@ -1,3 +1,5 @@ +import { LogEntryCharRanges } from "../types"; + export const escapeSpecialChars = (text: string): string => { let safeText = ""; @@ -135,29 +137,24 @@ export const returnSearchIndices = ( export const getRegularExpressionMatches = ( expression: string, logFileAsString: string, - logEntryRanges: number[][], + logEntryCharRanges: LogEntryCharRanges, ): number[] => { const searchIndices: number[] = []; const resultingMatches: number[] = []; const flags = "gs"; const query = new RegExp(expression, flags); let result; - let currentIndex = 0; while ((result = query.exec(logFileAsString)) !== null) { searchIndices.push(result.index); } if (searchIndices.length > 0) { - for (let i = 0; i < logEntryRanges.length; i++) { - if (searchIndices[currentIndex] >= logEntryRanges[i][0]) { - if (searchIndices[currentIndex] <= logEntryRanges[i][1]) { - currentIndex += 1; - if (i != resultingMatches[-1]) resultingMatches.push(i); - if (currentIndex === searchIndices.length) break; - } - } - } + searchIndices.forEach((searchIndex) => { + const indexOfMatchedEntry = logEntryCharRanges.firstCharIndexMap.get(searchIndex); + resultingMatches.push(indexOfMatchedEntry); + }); } + return resultingMatches; }; diff --git a/src/viewer/hooks/useStructureRegularExpressionManager.ts b/src/viewer/hooks/useStructureRegularExpressionManager.ts index ad54fb8..9310597 100644 --- a/src/viewer/hooks/useStructureRegularExpressionManager.ts +++ b/src/viewer/hooks/useStructureRegularExpressionManager.ts @@ -1,4 +1,4 @@ -import { CellContents, Header, StructureEntry, Wildcard } from "../types"; +import { CellContents, Header, LogEntryCharRanges, StructureEntry, Wildcard } from "../types"; import { StructureHeaderColumnType, StructureLinkDistance } from "../constants"; import { isSubstitutionFirstForWildcard } from "./useWildcardManager"; @@ -182,29 +182,33 @@ export const useStructureQueryConstructor = ( return regularExp; }; -export const useJsonObjectToTextRangesMap = (logFileAsString: string): number[][] => { +export const useGetCharIndicesForLogEntries = (logFileAsString: string): LogEntryCharRanges => { const perfStart = performance.now(); - const textRanges: number[][] = []; const jsonObjectsRegExp = new RegExp(regExpjsonObject, flags); + const firstCharIndexMap = new Map(); + const lastCharIndexMap = new Map(); + let logEntryIndex = 0; let result = jsonObjectsRegExp.exec(logFileAsString); if (result !== null) { do { - textRanges.push([result.index, jsonObjectsRegExp.lastIndex]); + firstCharIndexMap.set(result.index, logEntryIndex); + lastCharIndexMap.set(jsonObjectsRegExp.lastIndex, logEntryIndex); + logEntryIndex++; } while ((result = jsonObjectsRegExp.exec(logFileAsString)) !== null); } const perfEnd = performance.now(); console.log(`Execution time (mapLogFileTextIndicesToObject()): ${perfEnd - perfStart} ms`); - return textRanges; + return { firstCharIndexMap: firstCharIndexMap, lastCharIndexMap: lastCharIndexMap }; }; export const useStructureRegularExpressionSearch = ( expression: string, logFileAsString: string, - logEntryRanges: number[][], + logEntryCharRanges: LogEntryCharRanges, ): number[][] => { console.log("Starting Structure Matching"); const perfStart = performance.now(); @@ -213,35 +217,31 @@ export const useStructureRegularExpressionSearch = ( const structureQuery = new RegExp(expression, flags); let result; + while ((result = structureQuery.exec(logFileAsString)) !== null) { textRanges.push([result.index, structureQuery.lastIndex]); } const perfEnd = performance.now(); - console.log(`Execution time (useStructureRegularExpressionSearch()): ${perfEnd - perfStart} ms`); + console.log(`Execution time (regular expression run): ${perfEnd - perfStart} ms`); + + const transStart = performance.now(); textRanges.forEach((matchRanges) => { const indexesOfEntriesInMatch: number[] = []; - let startingIndexOfMatch = 0; - let endingIndexOfMatch = -1; - - for (let i = 0; i < logEntryRanges.length; i++) { - if (matchRanges[0] === logEntryRanges[i][0]) { - startingIndexOfMatch = i; - } - if (matchRanges[1] === logEntryRanges[i][1]) { - endingIndexOfMatch = i; - break; - } - } + const indexOfFirstObjectInMatch = logEntryCharRanges.firstCharIndexMap.get(matchRanges[0]); + const indexOfLastObjectInMatch = logEntryCharRanges.lastCharIndexMap.get(matchRanges[1]); - for (let o = startingIndexOfMatch; o <= endingIndexOfMatch; o++) { - indexesOfEntriesInMatch.push(o); + for (let i = indexOfFirstObjectInMatch; i <= indexOfLastObjectInMatch; i++) { + indexesOfEntriesInMatch.push(i); } resultingMatches.push(indexesOfEntriesInMatch); }); + const transEnd = performance.now(); + console.log(`Execution time (translation from char indices to logFile.rows indices): ${transEnd - transStart} ms`); + return resultingMatches; }; diff --git a/src/viewer/types.d.ts b/src/viewer/types.d.ts index 5f72b30..75f956f 100644 --- a/src/viewer/types.d.ts +++ b/src/viewer/types.d.ts @@ -57,3 +57,8 @@ export interface Segment { end: number; level: number; } + +export interface LogEntryCharRanges { + firstCharIndexMap; + lastCharIndexMap; +} From 685997222467bf52664bc6049cf9487619ec53d9 Mon Sep 17 00:00:00 2001 From: LightFLP Date: Tue, 26 Sep 2023 15:34:43 +0200 Subject: [PATCH 05/10] Remove console logs --- src/viewer/App.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/viewer/App.tsx b/src/viewer/App.tsx index 991e588..d5bb948 100644 --- a/src/viewer/App.tsx +++ b/src/viewer/App.tsx @@ -380,8 +380,6 @@ export default class App extends React.Component { handleSegmentation(entryExpression: string, exitExpression: string) { const { logFileAsString, logEntryCharRanges } = this.state; const { collapsibleRows } = this.state; - console.log(entryExpression); - console.log(exitExpression); const entryMatches = getRegularExpressionMatches( entryExpression, From da9e46eeeac17424dfcf17d3b43b2d4cbbeaef0d Mon Sep 17 00:00:00 2001 From: LightFLP Date: Tue, 26 Sep 2023 15:37:28 +0200 Subject: [PATCH 06/10] Enable text selection in LogView --- src/viewer/hooks/useStyleManager.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/viewer/hooks/useStyleManager.ts b/src/viewer/hooks/useStyleManager.ts index 23a8a44..ca9048f 100644 --- a/src/viewer/hooks/useStyleManager.ts +++ b/src/viewer/hooks/useStyleManager.ts @@ -21,7 +21,7 @@ const getLogViewRowStyle = (rowIndex: number, leftPadding: number): React.CSSPro height: LOG_ROW_HEIGHT, overflow: "hidden", top: rowIndex * LOG_ROW_HEIGHT, - userSelect: "none", + userSelect: "text", borderRadius: "5px", }; From ee6599618433bc641e3ef3af64bde733fddfc2d7 Mon Sep 17 00:00:00 2001 From: LightFLP Date: Tue, 26 Sep 2023 15:58:13 +0200 Subject: [PATCH 07/10] Disable default contextmenu --- src/viewer/App.tsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/viewer/App.tsx b/src/viewer/App.tsx index d5bb948..54f697f 100644 --- a/src/viewer/App.tsx +++ b/src/viewer/App.tsx @@ -30,7 +30,7 @@ import Rule from "./rules/Rule"; import MinimapHeader from "./minimap/MinimapHeader"; import SelectColDialog from "./log/SelectColDialog"; -interface Props {} +interface Props { } interface State { logFile: LogFile; logViewState: LogViewState | undefined; @@ -105,7 +105,7 @@ export default class App extends React.Component { caseSearch: false, selectedLogRows: [], rowProperties: [], - logEntryCharRanges: {firstCharIndexMap: null, lastCharIndexMap: null}, + logEntryCharRanges: { firstCharIndexMap: null, lastCharIndexMap: null }, showStructureDialog: false, structureMatches: [], structureMatchesLogRows: [], @@ -118,6 +118,9 @@ export default class App extends React.Component { this.onMessage = this.onMessage.bind(this); window.addEventListener("message", this.onMessage); + document.addEventListener("contextmenu", (event) => { + event.preventDefault(); + }); this.vscode.postMessage({ type: "readFile" }); } From 8d0c63eefb731e3811e9b5b9270ce05a85053220 Mon Sep 17 00:00:00 2001 From: LightFLP Date: Tue, 26 Sep 2023 16:13:03 +0200 Subject: [PATCH 08/10] Rename logEntryRanges to logEntryCharIndexMaps --- src/viewer/App.tsx | 24 +++++++++---------- .../useStructureRegularExpressionManager.ts | 10 ++++---- src/viewer/types.d.ts | 2 +- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/viewer/App.tsx b/src/viewer/App.tsx index 54f697f..93aea12 100644 --- a/src/viewer/App.tsx +++ b/src/viewer/App.tsx @@ -3,7 +3,7 @@ import LogFile from "./LogFile"; import LogView from "./log/LogView"; import MinimapView from "./minimap/MinimapView"; import Tooltip from "@mui/material/Tooltip"; -import { LogViewState, StructureMatchId, RowProperty, Segment, LogEntryCharRanges } from "./types"; +import { LogViewState, StructureMatchId, RowProperty, Segment, LogEntryCharMaps } from "./types"; import { LOG_HEADER_HEIGHT, MINIMAP_COLUMN_WIDTH, @@ -49,7 +49,7 @@ interface State { // Structure related logFileAsString: string; - logEntryCharRanges: LogEntryCharRanges; + logEntryCharIndexMaps: LogEntryCharMaps; selectedLogRows: string[][]; // selectedRowsTypes: RowType[]; rowProperties: RowProperty[]; @@ -105,7 +105,7 @@ export default class App extends React.Component { caseSearch: false, selectedLogRows: [], rowProperties: [], - logEntryCharRanges: { firstCharIndexMap: null, lastCharIndexMap: null }, + logEntryCharIndexMaps: { firstCharIndexMap: null, lastCharIndexMap: null }, showStructureDialog: false, structureMatches: [], structureMatchesLogRows: [], @@ -136,7 +136,7 @@ export default class App extends React.Component { const rules = message.rules.map((r) => Rule.fromJSON(r)).filter((r) => r); const lines = JSON.parse(message.text); const logFileText = JSON.stringify(lines, null, 2); - const charRangesMaps = useGetCharIndicesForLogEntries(logFileText); + const logEntryCharIndexMaps = useGetCharIndicesForLogEntries(logFileText); const logFile = LogFile.create(lines, rules); const newRowsProps = logFile.rows.map(() => constructNewRowProperty(true, true, SelectedRowType.None), @@ -144,7 +144,7 @@ export default class App extends React.Component { this.setState({ logFile, logFileAsString: logFileText, - logEntryCharRanges: charRangesMaps, + logEntryCharIndexMaps: logEntryCharIndexMaps, rules, rowProperties: newRowsProps, }); @@ -184,11 +184,11 @@ export default class App extends React.Component { return constructNewRowProperty(true, true, SelectedRowType.None); else return constructNewRowProperty(false, false, SelectedRowType.None); }); - const charRangesMaps = useGetCharIndicesForLogEntries(logFileText); + const logEntryCharIndexMaps = useGetCharIndicesForLogEntries(logFileText); this.setState({ logFile, logFileAsString: logFileText, - logEntryCharRanges: charRangesMaps, + logEntryCharIndexMaps: logEntryCharIndexMaps, rules, rowProperties: newRowsProps, }); @@ -322,13 +322,13 @@ export default class App extends React.Component { handleStructureMatching(expression: string) { const rowProperties = this.clearSelectedRowsTypes(); - const { logFileAsString, logEntryCharRanges } = this.state; + const { logFileAsString, logEntryCharIndexMaps } = this.state; let { currentStructureMatch, currentStructureMatchIndex } = this.state; const structureMatches = useStructureRegularExpressionSearch( expression, logFileAsString, - logEntryCharRanges, + logEntryCharIndexMaps, ); let structureMatchesLogRows: number[] = []; @@ -381,18 +381,18 @@ export default class App extends React.Component { } handleSegmentation(entryExpression: string, exitExpression: string) { - const { logFileAsString, logEntryCharRanges } = this.state; + const { logFileAsString, logEntryCharIndexMaps } = this.state; const { collapsibleRows } = this.state; const entryMatches = getRegularExpressionMatches( entryExpression, logFileAsString, - logEntryCharRanges, + logEntryCharIndexMaps, ); const exitMatches = getRegularExpressionMatches( exitExpression, logFileAsString, - logEntryCharRanges, + logEntryCharIndexMaps, ); const stack: number[] = []; diff --git a/src/viewer/hooks/useStructureRegularExpressionManager.ts b/src/viewer/hooks/useStructureRegularExpressionManager.ts index 9310597..4d3eb56 100644 --- a/src/viewer/hooks/useStructureRegularExpressionManager.ts +++ b/src/viewer/hooks/useStructureRegularExpressionManager.ts @@ -1,4 +1,4 @@ -import { CellContents, Header, LogEntryCharRanges, StructureEntry, Wildcard } from "../types"; +import { CellContents, Header, LogEntryCharMaps, StructureEntry, Wildcard } from "../types"; import { StructureHeaderColumnType, StructureLinkDistance } from "../constants"; import { isSubstitutionFirstForWildcard } from "./useWildcardManager"; @@ -182,7 +182,7 @@ export const useStructureQueryConstructor = ( return regularExp; }; -export const useGetCharIndicesForLogEntries = (logFileAsString: string): LogEntryCharRanges => { +export const useGetCharIndicesForLogEntries = (logFileAsString: string): LogEntryCharMaps => { const perfStart = performance.now(); const jsonObjectsRegExp = new RegExp(regExpjsonObject, flags); const firstCharIndexMap = new Map(); @@ -208,7 +208,7 @@ export const useGetCharIndicesForLogEntries = (logFileAsString: string): LogEntr export const useStructureRegularExpressionSearch = ( expression: string, logFileAsString: string, - logEntryCharRanges: LogEntryCharRanges, + logEntryCharIndexMaps: LogEntryCharMaps, ): number[][] => { console.log("Starting Structure Matching"); const perfStart = performance.now(); @@ -230,8 +230,8 @@ export const useStructureRegularExpressionSearch = ( textRanges.forEach((matchRanges) => { const indexesOfEntriesInMatch: number[] = []; - const indexOfFirstObjectInMatch = logEntryCharRanges.firstCharIndexMap.get(matchRanges[0]); - const indexOfLastObjectInMatch = logEntryCharRanges.lastCharIndexMap.get(matchRanges[1]); + const indexOfFirstObjectInMatch = logEntryCharIndexMaps.firstCharIndexMap.get(matchRanges[0]); + const indexOfLastObjectInMatch = logEntryCharIndexMaps.lastCharIndexMap.get(matchRanges[1]); for (let i = indexOfFirstObjectInMatch; i <= indexOfLastObjectInMatch; i++) { indexesOfEntriesInMatch.push(i); diff --git a/src/viewer/types.d.ts b/src/viewer/types.d.ts index 75f956f..659c9d3 100644 --- a/src/viewer/types.d.ts +++ b/src/viewer/types.d.ts @@ -58,7 +58,7 @@ export interface Segment { level: number; } -export interface LogEntryCharRanges { +export interface LogEntryCharMaps { firstCharIndexMap; lastCharIndexMap; } From 0b06de964c188495040471796b2da243f322841e Mon Sep 17 00:00:00 2001 From: LightFLP Date: Tue, 26 Sep 2023 16:13:50 +0200 Subject: [PATCH 09/10] Document LogEntryCharMaps type --- docs/developer-documentation/types/LogEntryCharMaps.md | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 docs/developer-documentation/types/LogEntryCharMaps.md diff --git a/docs/developer-documentation/types/LogEntryCharMaps.md b/docs/developer-documentation/types/LogEntryCharMaps.md new file mode 100644 index 0000000..2bd7e5d --- /dev/null +++ b/docs/developer-documentation/types/LogEntryCharMaps.md @@ -0,0 +1,10 @@ +# Name + +```TS +interface LogEntryCharMaps { + firstCharIndexMap; + lastCharIndexMap; +} +``` + +This type is used to represent an object containing two JavaScript [`Map`(s)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map). These maps store the first and last char indices of each log entry. These indices are used for the Segment Annotation and Structure Matching features and Search (with Regular Expressions). \ No newline at end of file From 789ecd51dc6a3e81922251f4bbf2720fabcf8148 Mon Sep 17 00:00:00 2001 From: LightFLP Date: Wed, 27 Sep 2023 15:23:39 +0200 Subject: [PATCH 10/10] Add Map types in LogEntryCharMaps --- src/viewer/hooks/useStructureRegularExpressionManager.ts | 6 ++++-- src/viewer/types.d.ts | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/viewer/hooks/useStructureRegularExpressionManager.ts b/src/viewer/hooks/useStructureRegularExpressionManager.ts index 4d3eb56..9bba0e2 100644 --- a/src/viewer/hooks/useStructureRegularExpressionManager.ts +++ b/src/viewer/hooks/useStructureRegularExpressionManager.ts @@ -233,8 +233,10 @@ export const useStructureRegularExpressionSearch = ( const indexOfFirstObjectInMatch = logEntryCharIndexMaps.firstCharIndexMap.get(matchRanges[0]); const indexOfLastObjectInMatch = logEntryCharIndexMaps.lastCharIndexMap.get(matchRanges[1]); - for (let i = indexOfFirstObjectInMatch; i <= indexOfLastObjectInMatch; i++) { - indexesOfEntriesInMatch.push(i); + if(indexOfFirstObjectInMatch && indexOfLastObjectInMatch) { + for (let i = indexOfFirstObjectInMatch; i <= indexOfLastObjectInMatch; i++) { + indexesOfEntriesInMatch.push(i); + } } resultingMatches.push(indexesOfEntriesInMatch); diff --git a/src/viewer/types.d.ts b/src/viewer/types.d.ts index 659c9d3..245709f 100644 --- a/src/viewer/types.d.ts +++ b/src/viewer/types.d.ts @@ -59,6 +59,6 @@ export interface Segment { } export interface LogEntryCharMaps { - firstCharIndexMap; - lastCharIndexMap; + firstCharIndexMap: Map; + lastCharIndexMap: Map; }