diff --git a/apps/demo/src/main.ts b/apps/demo/src/main.ts index b7d3a39a9..b50319ff9 100644 --- a/apps/demo/src/main.ts +++ b/apps/demo/src/main.ts @@ -55,7 +55,7 @@ const DEMO_THEME: DiffsThemeNames | ThemesType = DEFAULT_THEMES; const WORKER_POOL = true; const VIRTUALIZE = true; const CRAZY_FILE = false; -const LARGE_CONFLICT_FILE = false; +const LARGE_CONFLICT_FILE = true; const CODE_VIEW_OLD_NEW_FILE = true; const FileStreamCodeConfigs: FileStreamCodeConfigsItem[] = [ diff --git a/packages/diffs/src/components/File.ts b/packages/diffs/src/components/File.ts index 5bcbe78cd..31ec9558a 100644 --- a/packages/diffs/src/components/File.ts +++ b/packages/diffs/src/components/File.ts @@ -56,7 +56,7 @@ import { isStyleNode } from '../utils/isStyleNode'; import { prerenderHTMLIfNecessary } from '../utils/prerenderHTMLIfNecessary'; import { getMeasuredScrollbarGutter } from '../utils/scrollbarGutter'; import { setPreNodeProperties } from '../utils/setWrapperNodeProps'; -import type { WorkerPoolManager } from '../worker'; +import type { HighlightRequestMetadata, WorkerPoolManager } from '../worker'; import { DiffsContainerLoaded } from './web-components'; const EMPTY_STRINGS: string[] = []; @@ -174,7 +174,7 @@ export class File { ) { this.fileRenderer = new FileRenderer( options, - this.handleHighlightRender, + (metadata) => this.handleHighlightRender(metadata), this.workerManager ); this.resizeManager = new ResizeManager(); @@ -185,9 +185,9 @@ export class File { this.workerManager?.subscribeToThemeChanges(this); } - private handleHighlightRender = (): void => { + private handleHighlightRender(_metadata?: HighlightRequestMetadata): void { this.rerender(); - }; + } public rerender(): void { if (!this.enabled || this.file == null) return; diff --git a/packages/diffs/src/components/FileDiff.ts b/packages/diffs/src/components/FileDiff.ts index cf03eefec..5f170e86d 100644 --- a/packages/diffs/src/components/FileDiff.ts +++ b/packages/diffs/src/components/FileDiff.ts @@ -71,7 +71,7 @@ import { parseDiffFromFile } from '../utils/parseDiffFromFile'; import { prerenderHTMLIfNecessary } from '../utils/prerenderHTMLIfNecessary'; import { getMeasuredScrollbarGutter } from '../utils/scrollbarGutter'; import { setPreNodeProperties } from '../utils/setWrapperNodeProps'; -import type { WorkerPoolManager } from '../worker'; +import type { HighlightRequestMetadata, WorkerPoolManager } from '../worker'; import { DiffsContainerLoaded } from './web-components'; export interface FileDiffRenderProps { @@ -252,9 +252,9 @@ export class FileDiff { this.enabled = true; } - protected handleHighlightRender = (): void => { + protected handleHighlightRender(_metadata?: HighlightRequestMetadata): void { this.rerender(); - }; + } protected getHunksRendererOptions( options: FileDiffOptions @@ -267,7 +267,7 @@ export class FileDiff { ): DiffHunksRenderer { return new DiffHunksRenderer( this.getHunksRendererOptions(options), - this.handleHighlightRender, + (metadata) => this.handleHighlightRender(metadata), this.workerManager ); } diff --git a/packages/diffs/src/components/UnresolvedFile.ts b/packages/diffs/src/components/UnresolvedFile.ts index 2213472fa..d5c815928 100644 --- a/packages/diffs/src/components/UnresolvedFile.ts +++ b/packages/diffs/src/components/UnresolvedFile.ts @@ -14,6 +14,7 @@ import type { MergeConflictRegion, MergeConflictResolution, PostRenderPhase, + RenderRange, } from '../types'; import { areFilesEqual } from '../utils/areFilesEqual'; import { areMergeConflictActionsEqual } from '../utils/areMergeConflictActionsEqual'; @@ -27,7 +28,7 @@ import { } from '../utils/parseMergeConflictDiffFromFile'; import { resolveConflict as resolveConflictDiff } from '../utils/resolveConflict'; import { splitFileContents } from '../utils/splitFileContents'; -import type { WorkerPoolManager } from '../worker'; +import type { HighlightRequestMetadata, WorkerPoolManager } from '../worker'; import { FileDiff, type FileDiffOptions, @@ -108,6 +109,24 @@ interface ResolveConflictReturn { markerRows: MergeConflictMarkerRow[]; } +interface PendingRender { + fileDiff: FileDiffMetadata; + actions: (MergeConflictDiffAction | undefined)[]; + markerRows: MergeConflictMarkerRow[]; + lineAnnotations: UnresolvedFileRenderProps['lineAnnotations']; + renderRange: RenderRange | undefined; + preventEmit: boolean; + forceRender?: boolean; + fileContainer?: HTMLElement; + containerWrapper?: HTMLElement; +} + +interface ActiveMergeConflictState { + actions: (MergeConflictDiffAction | undefined)[]; + markerRows: MergeConflictMarkerRow[]; + fileDiff: FileDiffMetadata | undefined; +} + type UnresolvedFileDataCache = GetOrComputeDiffProps; let instanceId = -1; @@ -128,6 +147,7 @@ export class UnresolvedFile< private markerRows: MergeConflictMarkerRow[] = []; private conflictActionCache: Map = new Map(); + private pendingRender: PendingRender | undefined; constructor( public override options: UnresolvedFileOptions = { @@ -179,7 +199,7 @@ export class UnresolvedFile< ): UnresolvedFileHunksRenderer { const renderer = new UnresolvedFileHunksRenderer( this.getHunksRendererOptions(options), - this.handleHighlightRender, + (metadata) => this.handleHighlightRender(metadata), this.workerManager ); return renderer; @@ -210,6 +230,7 @@ export class UnresolvedFile< markerRows: undefined, }; this.conflictActions = []; + this.pendingRender = undefined; super.cleanUp(); } @@ -359,7 +380,7 @@ export class UnresolvedFile< return; } this.hydrateElements(fileContainer, prerenderedHTML); - this.setActiveMergeConflictState(source.actions, source.markerRows); + this.setActiveMergeConflictState(source); // If necessary hydration elements don't exist, we should assume a full // render if ( @@ -391,6 +412,27 @@ export class UnresolvedFile< this.render({ forceRender: true, renderRange: this.renderRange }); } + protected override handleHighlightRender( + metadata?: HighlightRequestMetadata + ): void { + console.log('handleHighlightRender', metadata); + const { pendingRender } = this; + if (metadata != null) { + if (metadata === pendingRender) { + this.pendingRender = undefined; + console.log('handleHighlightRender.rendering a pre render'); + this.renderResolvedState(pendingRender, true); + } + console.log('handleHighlightRender.throwing away a render'); + // If we get in here, then it means we are waiting on a render that's + // been invalidated, so drop it + return; + } + + console.log('handleHighlightRender.rendering normie render'); + super.handleHighlightRender(metadata); + } + override render(props: UnresolvedFileRenderProps = {}): boolean { let { file, @@ -410,20 +452,30 @@ export class UnresolvedFile< if (source == null) { return false; } - this.setActiveMergeConflictState(source.actions, source.markerRows); - const didRender = super.render({ - ...rest, + const nextRender: PendingRender = { fileDiff: source.fileDiff, + actions: source.actions, + markerRows: source.markerRows, lineAnnotations, - preventEmit: true, - }); - if (didRender) { - this.renderMergeConflictActionSlots(); - if (!preventEmit) { - this.emitPostRender(); - } + renderRange: rest.renderRange, + preventEmit, + forceRender: rest.forceRender, + fileContainer: rest.fileContainer, + containerWrapper: rest.containerWrapper, + }; + + if (this.shouldDeferRender(source.fileDiff)) { + console.log('queing render'); + this.queuePendingRender(nextRender); + return false; } - return didRender; + + // if (this.pendingRender?.fileDiff === source.fileDiff) { + // } + + console.log('linear render'); + this.pendingRender = undefined; + return this.renderResolvedState(nextRender); } public resolveConflict( @@ -491,37 +543,93 @@ export class UnresolvedFile< } this.computedCache = { file, fileDiff, actions, markerRows }; - this.setActiveMergeConflictState(actions, markerRows); - // NOTE(amadeus): This is a bit jank, but helps to ensure we don't see a - // bunch of jittery re-renders as things resolve out. In a more perfect - // world we would have a more elegant way to kick off a render to the - // highlighter and then resolve actions in a cleaner way, but time is short - // right now. Can't let perfect be the enemy of good - if (this.workerManager != null) { - // Because we are using a workerManager, if we fire off the renderDiff - // call, it will eventually get back to us in a callback which will - // trigger a re-render - this.hunksRenderer.renderDiff(fileDiff); + const nextRender: PendingRender = { + fileDiff, + actions, + markerRows, + lineAnnotations: this.lineAnnotations, + renderRange: this.renderRange, + preventEmit: false, + forceRender: true, + }; + if (this.shouldDeferRender(fileDiff)) { + console.log('resolveConflictAndRender: queued'); + this.queuePendingRender(nextRender); } else { - this.render({ forceRender: true }); + console.log('resolveConflictAndRender: linear'); + this.pendingRender = undefined; + this.renderResolvedState(nextRender); } this.options.onMergeConflictResolve?.(file, payload); } - private setActiveMergeConflictState( - actions: (MergeConflictDiffAction | undefined)[] = this.conflictActions, - markerRows: MergeConflictMarkerRow[] = this.markerRows - ): void { + private shouldDeferRender(fileDiff: FileDiffMetadata): boolean { + return ( + fileDiff !== this.fileDiff && + this.hunksRenderer.willTriggerAsyncHighlight(fileDiff) + ); + } + + // The pending render payload is also the metadata passed through async + // highlighting so the completion callback can promote only the latest render. + private queuePendingRender(pendingRender: PendingRender): void { + this.pendingRender = pendingRender; + this.hunksRenderer.renderDiff( + pendingRender.fileDiff, + pendingRender.renderRange, + pendingRender + ); + } + + private renderResolvedState( + pendingRender: PendingRender, + forceRenderOverride = false + ): boolean { + const { + fileDiff, + actions, + markerRows, + lineAnnotations, + renderRange, + preventEmit, + forceRender = false, + fileContainer, + containerWrapper, + } = pendingRender; + this.setActiveMergeConflictState({ actions, markerRows, fileDiff }); + const didRender = super.render({ + fileDiff, + lineAnnotations, + renderRange, + forceRender: forceRenderOverride || forceRender, + fileContainer, + containerWrapper, + preventEmit: true, + }); + if (didRender) { + this.renderMergeConflictActionSlots(); + if (!preventEmit) { + this.emitPostRender(); + } + } + return didRender; + } + + private setActiveMergeConflictState({ + actions = this.conflictActions, + markerRows = this.markerRows, + fileDiff = this.fileDiff, + }: ActiveMergeConflictState): void { this.conflictActions = actions; this.markerRows = markerRows; if ( - this.computedCache.fileDiff != null && + fileDiff != null && this.hunksRenderer instanceof UnresolvedFileHunksRenderer ) { this.hunksRenderer.setConflictState( this.options.mergeConflictActionsType === 'none' ? [] : actions, markerRows, - this.computedCache.fileDiff + fileDiff ); } } @@ -539,6 +647,12 @@ export class UnresolvedFile< "UnresolvedFile.handleMergeConflictActionClick: conflictIndex and conflictAction don't match" ); } + // NOTE(amadeus): Not sure if this will bite us or not... maybe we could + // take the active pending render data for this and still allow things to + // get triggered? I'll need to test this ont he demo + if (this.pendingRender != null) { + return; + } const payload: MergeConflictActionPayload = { resolution: target.resolution, conflict: action.conflict, @@ -551,7 +665,7 @@ export class UnresolvedFile< }; private renderMergeConflictActionSlots(): void { - const { fileDiff } = this.computedCache; + const { fileDiff } = this; if ( this.isContainerManaged || this.fileContainer == null || diff --git a/packages/diffs/src/renderers/DiffHunksRenderer.ts b/packages/diffs/src/renderers/DiffHunksRenderer.ts index 719c6708e..ddbcc05fb 100644 --- a/packages/diffs/src/renderers/DiffHunksRenderer.ts +++ b/packages/diffs/src/renderers/DiffHunksRenderer.ts @@ -65,7 +65,7 @@ import { iterateOverDiff } from '../utils/iterateOverDiff'; import { renderDiffWithHighlighter } from '../utils/renderDiffWithHighlighter'; import { shouldUseTokenTransformer } from '../utils/shouldUseTokenTransformer'; import { getTrailingContextRangeSize } from '../utils/virtualDiffLayout'; -import type { WorkerPoolManager } from '../worker'; +import type { HighlightRequestMetadata, WorkerPoolManager } from '../worker'; interface PushLineWithAnnotation { diffStyle: 'unified' | 'split'; @@ -216,7 +216,7 @@ export class DiffHunksRenderer { constructor( public options: DiffHunksRendererOptions = { theme: DEFAULT_THEMES }, - private onRenderUpdate?: () => unknown, + private onRenderUpdate?: (metadata?: HighlightRequestMetadata) => unknown, private workerManager?: WorkerPoolManager | undefined ) { if (workerManager?.isWorkingPool() !== true) { @@ -457,9 +457,45 @@ export class DiffHunksRenderer { return { options, forceHighlight: false }; } + public willTriggerAsyncHighlight(diff: FileDiffMetadata): boolean { + // If fileDiff is the same and we have the highlighted renderCache, then we + // know we'll always have a synchronous render + if ( + this.renderCache == null || + diff === this.renderCache?.diff || + this.renderCache?.highlighted === false + ) { + return false; + } + + // If we have an updated fileDiff and are using the Worker Pool, async + // highlighting depends on whether we are plainText or not + if (this.workerManager?.isWorkingPool() === true) { + if (isDiffPlainText(diff)) { + return false; + } else { + return true; + } + } + + // If we aren't using the Worker Pool, then we gotta make sure we have a + // highlighter instantiated (async) + if (this.highlighter == null) { + return true; + } + + // And that we have all the languages and themes loaded (also async) + const { options } = this.getRenderOptions(diff); + const computedLang = diff.lang ?? getFiletypeFromFileName(diff.name); + const hasThemes = areThemesAttached(options.theme); + const hasLangs = areLanguagesAttached(computedLang); + return !hasThemes || !hasLangs; + } + public renderDiff( diff: FileDiffMetadata | undefined = this.renderCache?.diff, - renderRange: RenderRange = DEFAULT_RENDER_RANGE + renderRange: RenderRange = DEFAULT_RENDER_RANGE, + metadata?: HighlightRequestMetadata ): HunksRenderResult | undefined { if (diff == null) { return undefined; @@ -533,7 +569,7 @@ export class DiffHunksRenderer { hasContent && (!this.renderCache.highlighted || forceHighlight) ) { - this.workerManager.highlightDiffAST(this, diff); + this.workerManager.highlightDiffAST(this, diff, metadata); } } else { this.computedLang = diff.lang ?? getFiletypeFromFileName(diff.name); @@ -579,7 +615,13 @@ export class DiffHunksRenderer { if (this.renderCache != null) { this.renderCache.highlighted = false; } - this.onHighlightSuccess(diff, result, options, !forcePlainText); + this.onHighlightSuccess( + diff, + result, + options, + metadata, + !forcePlainText + ); }); } } @@ -663,8 +705,10 @@ export class DiffHunksRenderer { diff: FileDiffMetadata, result: ThemedDiffResult, options: RenderDiffOptions, + metadata?: HighlightRequestMetadata, highlighted = true ): void { + console.log('onHighlightSuccess', metadata); // NOTE(amadeus): This is a bad assumption, and I should figure out // something better... If renderCache was blown away, we can assume we've // run cleanUp() @@ -685,7 +729,7 @@ export class DiffHunksRenderer { renderRange: undefined, }; if (triggerRenderUpdate) { - this.onRenderUpdate?.(); + this.onRenderUpdate?.(metadata); } } diff --git a/packages/diffs/src/renderers/FileRenderer.ts b/packages/diffs/src/renderers/FileRenderer.ts index 2a569052e..66d3d9c31 100644 --- a/packages/diffs/src/renderers/FileRenderer.ts +++ b/packages/diffs/src/renderers/FileRenderer.ts @@ -48,7 +48,7 @@ import { iterateOverFile } from '../utils/iterateOverFile'; import { renderFileWithHighlighter } from '../utils/renderFileWithHighlighter'; import { shouldUseTokenTransformer } from '../utils/shouldUseTokenTransformer'; import { splitFileContents } from '../utils/splitFileContents'; -import type { WorkerPoolManager } from '../worker'; +import type { HighlightRequestMetadata, WorkerPoolManager } from '../worker'; type AnnotationLineMap = Record< number, @@ -96,7 +96,7 @@ export class FileRenderer { constructor( public options: FileRendererOptions = { theme: DEFAULT_THEMES }, - private onRenderUpdate?: () => unknown, + private onRenderUpdate?: (metadata?: HighlightRequestMetadata) => unknown, private workerManager?: WorkerPoolManager | undefined ) { if (workerManager?.isWorkingPool() !== true) { @@ -221,7 +221,8 @@ export class FileRenderer { public renderFile( file: FileContents | undefined = this.renderCache?.file, - renderRange: RenderRange = DEFAULT_RENDER_RANGE + renderRange: RenderRange = DEFAULT_RENDER_RANGE, + metadata?: HighlightRequestMetadata ): FileRenderResult | undefined { if (file == null) { return undefined; @@ -286,7 +287,7 @@ export class FileRenderer { hasContent && (!this.renderCache.highlighted || forceHighlight) ) { - this.workerManager.highlightFileAST(this, file); + this.workerManager.highlightFileAST(this, file, metadata); } } else { this.computedLang = file.lang ?? getFiletypeFromFileName(file.name); @@ -332,7 +333,13 @@ export class FileRenderer { if (this.renderCache != null) { this.renderCache.highlighted = false; } - this.onHighlightSuccess(file, result, options, !forcePlainText); + this.onHighlightSuccess( + file, + result, + options, + metadata, + !forcePlainText + ); }); } } @@ -532,6 +539,7 @@ export class FileRenderer { file: FileContents, result: ThemedFileResult, options: RenderFileOptions, + metadata?: HighlightRequestMetadata, highlighted = true ): void { if (this.renderCache == null) { @@ -551,7 +559,7 @@ export class FileRenderer { }; if (triggerRenderUpdate) { - this.onRenderUpdate?.(); + this.onRenderUpdate?.(metadata); } } diff --git a/packages/diffs/src/renderers/UnresolvedFileHunksRenderer.ts b/packages/diffs/src/renderers/UnresolvedFileHunksRenderer.ts index beb45fe42..42634ff4a 100644 --- a/packages/diffs/src/renderers/UnresolvedFileHunksRenderer.ts +++ b/packages/diffs/src/renderers/UnresolvedFileHunksRenderer.ts @@ -17,7 +17,7 @@ import { getMergeConflictActionAnchor, type MergeConflictDiffAction, } from '../utils/parseMergeConflictDiffFromFile'; -import type { WorkerPoolManager } from '../worker'; +import type { HighlightRequestMetadata, WorkerPoolManager } from '../worker'; import { DiffHunksRenderer, type DiffHunksRendererOptions, @@ -82,7 +82,7 @@ export class UnresolvedFileHunksRenderer< options: UnresolvedFileHunksRendererOptions = { theme: DEFAULT_THEMES, }, - onRenderUpdate?: () => unknown, + onRenderUpdate?: (metadata?: HighlightRequestMetadata) => unknown, workerManager?: WorkerPoolManager | undefined ) { super(undefined, onRenderUpdate, workerManager); @@ -142,7 +142,8 @@ export class UnresolvedFileHunksRenderer< public override renderDiff( diff?: FileDiffMetadata | undefined, - renderRange: RenderRange = DEFAULT_RENDER_RANGE + renderRange: RenderRange = DEFAULT_RENDER_RANGE, + metadata?: HighlightRequestMetadata ): HunksRenderResult | undefined { if (diff != null) { this.syncInjectedRows( @@ -151,7 +152,7 @@ export class UnresolvedFileHunksRenderer< diff ); } - return super.renderDiff(diff, renderRange); + return super.renderDiff(diff, renderRange, metadata); } public override async asyncRender( diff --git a/packages/diffs/src/worker/WorkerPoolManager.ts b/packages/diffs/src/worker/WorkerPoolManager.ts index 16f3db8f6..e5af64e94 100644 --- a/packages/diffs/src/worker/WorkerPoolManager.ts +++ b/packages/diffs/src/worker/WorkerPoolManager.ts @@ -43,6 +43,7 @@ import type { AllWorkerTasks, DiffRendererInstance, FileRendererInstance, + HighlightRequestMetadata, InitializeWorkerRequest, InitializeWorkerTask, RenderDiffRequest, @@ -552,7 +553,8 @@ export class WorkerPoolManager { public highlightFileAST( instance: FileRendererInstance, - file: FileContents + file: FileContents, + metadata?: HighlightRequestMetadata ): void { const cachedResult = this.getFileResultCache(file); // If we've already highlighted the file or it's plain text, we should not @@ -568,8 +570,8 @@ export class WorkerPoolManager { ) { return; } - if (!this.hasMatchingFileInstanceTask(instance, file)) { - this.submitTask(instance, { type: 'file', file }); + if (!this.hasMatchingFileInstanceTask(instance, file, metadata)) { + this.submitTask(instance, { type: 'file', file }, metadata); } } @@ -621,7 +623,8 @@ export class WorkerPoolManager { public highlightDiffAST( instance: DiffRendererInstance, - diff: FileDiffMetadata + diff: FileDiffMetadata, + metadata?: HighlightRequestMetadata ): void { const cachedResult = this.getDiffResultCache(diff); // If we've already highlighted the diff or it's plain text, we should not @@ -637,8 +640,9 @@ export class WorkerPoolManager { ) { return; } - if (!this.hasMatchingDiffInstanceTask(instance, diff)) { - this.submitTask(instance, { type: 'diff', diff }); + if (!this.hasMatchingDiffInstanceTask(instance, diff, metadata)) { + console.log('highlightDiffAST', metadata); + this.submitTask(instance, { type: 'diff', diff }, metadata); } } @@ -757,15 +761,18 @@ export class WorkerPoolManager { private submitTask( instance: FileRendererInstance, - request: Omit + request: Omit, + metadata?: HighlightRequestMetadata ): void; private submitTask( instance: DiffRendererInstance, - request: Omit + request: Omit, + metadata?: HighlightRequestMetadata ): void; private submitTask( instance: FileRendererInstance | DiffRendererInstance, - request: SubmitRequest + request: SubmitRequest, + metadata?: HighlightRequestMetadata ): void { if (this.initialized === false) { this.queueInitialization(); @@ -798,6 +805,7 @@ export class WorkerPoolManager { primeCache: false, highlightKey, renderOptionsVersion, + metadata, requestStart, }; case 'diff': @@ -809,6 +817,7 @@ export class WorkerPoolManager { primeCache: false, highlightKey, renderOptionsVersion, + metadata, requestStart, }; } @@ -1272,7 +1281,12 @@ export class WorkerPoolManager { ): void { for (const instance of task.instances) { if (this.activeRequestByInstance.get(instance) === task.id) { - instance.onHighlightSuccess(task.request.file, result, options); + instance.onHighlightSuccess( + task.request.file, + result, + options, + task.metadata + ); } } } @@ -1284,7 +1298,12 @@ export class WorkerPoolManager { ): void { for (const instance of task.instances) { if (this.activeRequestByInstance.get(instance) === task.id) { - instance.onHighlightSuccess(task.request.diff, result, options); + instance.onHighlightSuccess( + task.request.diff, + result, + options, + task.metadata + ); } } } @@ -1292,14 +1311,15 @@ export class WorkerPoolManager { private notifyHighlightError(task: RenderTask, error: unknown): void { for (const instance of getInstances(task)) { if (this.activeRequestByInstance.get(instance) === task.id) { - instance.onHighlightError(error); + instance.onHighlightError(error, task.metadata); } } } private hasMatchingFileInstanceTask( instance: FileRendererInstance, - file: FileContents + file: FileContents, + metadata?: HighlightRequestMetadata ): boolean { for (const task of this.iterateRenderTasks()) { if ( @@ -1308,6 +1328,7 @@ export class WorkerPoolManager { task.instances.has(instance) && areFilesEqual(file, task.request.file) ) { + task.metadata = metadata; return true; } } @@ -1316,7 +1337,8 @@ export class WorkerPoolManager { private hasMatchingDiffInstanceTask( instance: DiffRendererInstance, - diff: FileDiffMetadata + diff: FileDiffMetadata, + metadata?: HighlightRequestMetadata ): boolean { for (const task of this.iterateRenderTasks()) { if ( @@ -1325,6 +1347,7 @@ export class WorkerPoolManager { task.instances.has(instance) && areDiffTargetsEqual(task.request.diff, diff) ) { + task.metadata = metadata; return true; } } diff --git a/packages/diffs/src/worker/types.ts b/packages/diffs/src/worker/types.ts index ed1701ff0..45ab9ed4a 100644 --- a/packages/diffs/src/worker/types.ts +++ b/packages/diffs/src/worker/types.ts @@ -16,6 +16,7 @@ import type { } from '../types'; export type WorkerRequestId = string; +export type HighlightRequestMetadata = unknown; export interface WorkerRenderingOptions { theme: DiffsThemeNames | ThemesType; @@ -30,9 +31,13 @@ export interface FileRendererInstance { onHighlightSuccess( file: FileContents, result: ThemedFileResult, - options: RenderFileOptions + options: RenderFileOptions, + metadata?: HighlightRequestMetadata + ): unknown; + onHighlightError( + error: unknown, + metadata?: HighlightRequestMetadata ): unknown; - onHighlightError(error: unknown): unknown; } export interface DiffRendererInstance { @@ -40,9 +45,13 @@ export interface DiffRendererInstance { onHighlightSuccess( diff: FileDiffMetadata, result: ThemedDiffResult, - options: RenderDiffOptions + options: RenderDiffOptions, + metadata?: HighlightRequestMetadata + ): unknown; + onHighlightError( + error: unknown, + metadata?: HighlightRequestMetadata ): unknown; - onHighlightError(error: unknown): unknown; } export interface RenderFileRequest { @@ -194,6 +203,7 @@ export interface RenderFileTask { primeCache: boolean; highlightKey?: string; renderOptionsVersion: number; + metadata?: HighlightRequestMetadata; requestStart: number; } @@ -207,6 +217,7 @@ export interface RenderDiffTask { primeCache: boolean; highlightKey?: string; renderOptionsVersion: number; + metadata?: HighlightRequestMetadata; requestStart: number; }