MCPcopy Create free account
hub / github.com/kpdecker/jsdiff / diffWithOptionsObj

Method diffWithOptionsObj

src/diff/base.ts:77–213  ·  view source on GitHub ↗
(
    oldTokens: TokenT[],
    newTokens: TokenT[],
    options: AllDiffOptions & Partial<TimeoutOption> & Partial<MaxEditLengthOption>,
    callback: DiffCallbackAbortable<ValueT> | DiffCallbackNonabortable<ValueT> | undefined
  )

Source from the content-addressed store, hash-verified

75 }
76
77 private diffWithOptionsObj(
78 oldTokens: TokenT[],
79 newTokens: TokenT[],
80 options: AllDiffOptions & Partial<TimeoutOption> & Partial<MaxEditLengthOption>,
81 callback: DiffCallbackAbortable<ValueT> | DiffCallbackNonabortable<ValueT> | undefined
82 ): ChangeObject<ValueT>[] | undefined {
83 const done = (value: ChangeObject<ValueT>[]) => {
84 value = this.postProcess(value, options);
85 if (callback) {
86 setTimeout(function() { callback(value); }, 0);
87 return undefined;
88 } else {
89 return value;
90 }
91 };
92
93 const newLen = newTokens.length, oldLen = oldTokens.length;
94 let editLength = 1;
95 let maxEditLength = newLen + oldLen;
96 if(options.maxEditLength != null) {
97 maxEditLength = Math.min(maxEditLength, options.maxEditLength);
98 }
99 const maxExecutionTime = options.timeout ?? Infinity;
100 const abortAfterTimestamp = Date.now() + maxExecutionTime;
101
102 const bestPath: Path[] = [{ oldPos: -1, lastComponent: undefined }];
103
104 // Seed editLength = 0, i.e. the content starts with the same values
105 let newPos = this.extractCommon(bestPath[0], newTokens, oldTokens, 0, options);
106 if (bestPath[0].oldPos + 1 >= oldLen && newPos + 1 >= newLen) {
107 // Identity per the equality and tokenizer
108 return done(this.buildValues(bestPath[0].lastComponent, newTokens, oldTokens));
109 }
110
111 // Once we hit the right edge of the edit graph on some diagonal k, we can
112 // definitely reach the end of the edit graph in no more than k edits, so
113 // there's no point in considering any moves to diagonal k+1 any more (from
114 // which we're guaranteed to need at least k+1 more edits).
115 // Similarly, once we've reached the bottom of the edit graph, there's no
116 // point considering moves to lower diagonals.
117 // We record this fact by setting minDiagonalToConsider and
118 // maxDiagonalToConsider to some finite value once we've hit the edge of
119 // the edit graph.
120 // This optimization is not faithful to the original algorithm presented in
121 // Myers's paper, which instead pointlessly extends D-paths off the end of
122 // the edit graph - see page 7 of Myers's paper which notes this point
123 // explicitly and illustrates it with a diagram. This has major performance
124 // implications for some common scenarios. For instance, to compute a diff
125 // where the new text simply appends d characters on the end of the
126 // original text of length n, the true Myers algorithm will take O(n+d^2)
127 // time while this optimization needs only O(n+d) time.
128 let minDiagonalToConsider = -Infinity, maxDiagonalToConsider = Infinity;
129
130 // Main worker method. checks all permutations of a given edit length for acceptance.
131 const execEditLength = () => {
132 for (
133 let diagonalPath = Math.max(minDiagonalToConsider, -editLength);
134 diagonalPath <= Math.min(maxDiagonalToConsider, editLength);

Callers 1

diffMethod · 0.95

Calls 2

extractCommonMethod · 0.95
buildValuesMethod · 0.95

Tested by

no test coverage detected