Files
objdiff-web/webview/diff.ts
T
2025-09-03 20:24:20 -06:00

83 lines
2.2 KiB
TypeScript

import { diff } from 'objdiff-wasm';
import { useMemo } from 'react';
import type { ConfigProperties } from '../shared/config';
import type { BuildStatus } from '../shared/messages';
import { buildDiffConfig } from './state';
export type DiffInput = {
leftStatus: BuildStatus | null;
rightStatus: BuildStatus | null;
leftObject: ArrayBuffer | null;
rightObject: ArrayBuffer | null;
configProperties: ConfigProperties;
mappingConfig: diff.MappingConfig;
};
export type DiffOutput = {
leftStatus: BuildStatus | null;
rightStatus: BuildStatus | null;
diff: diff.DiffResult | null;
lastBuilt: number | null;
isMapping: boolean;
};
export const useDiff = ({
leftStatus,
rightStatus,
leftObject,
rightObject,
configProperties,
mappingConfig,
}: DiffInput) =>
useMemo(() => {
const start = performance.now();
const diffConfig = buildDiffConfig(configProperties);
let left: diff.Object | undefined;
let right: diff.Object | undefined;
try {
left =
leftObject?.byteLength && leftStatus?.success
? diff.Object.parse(new Uint8Array(leftObject), diffConfig, 'target')
: undefined;
} catch (e) {
leftStatus = {
success: false,
cmdline: leftStatus?.cmdline ?? '',
stdout: '',
stderr: `Failed to parse left object: ${e}`,
};
}
try {
right =
rightObject?.byteLength && rightStatus?.success
? diff.Object.parse(new Uint8Array(rightObject), diffConfig, 'base')
: undefined;
} catch (e) {
rightStatus = {
success: false,
cmdline: rightStatus?.cmdline ?? '',
stdout: '',
stderr: `Failed to parse right object: ${e}`,
};
}
const result = diff.runDiff(left, right, diffConfig, mappingConfig);
const end = performance.now();
console.debug('Diff time:', end - start, 'ms');
return {
leftStatus,
rightStatus,
diff: result,
lastBuilt: Date.now(),
isMapping:
mappingConfig.selectingLeft != null ||
mappingConfig.selectingRight != null,
};
}, [
leftStatus,
rightStatus,
leftObject,
rightObject,
configProperties,
mappingConfig,
]);