@artkit-ai/react 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cache.d.ts +7 -11
- package/dist/cache.d.ts.map +1 -1
- package/dist/cache.js +32 -53
- package/dist/cache.js.map +1 -1
- package/dist/client.d.ts +4 -15
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +2 -29
- package/dist/client.js.map +1 -1
- package/dist/components/card.d.ts +2 -2
- package/dist/components/card.d.ts.map +1 -1
- package/dist/components/card.js +3 -3
- package/dist/components/card.js.map +1 -1
- package/dist/components/editor.d.ts +31 -18
- package/dist/components/editor.d.ts.map +1 -1
- package/dist/components/editor.js +81 -131
- package/dist/components/editor.js.map +1 -1
- package/dist/components/icons.d.ts +2 -2
- package/dist/components/icons.d.ts.map +1 -1
- package/dist/components/icons.js +2 -2
- package/dist/components/icons.js.map +1 -1
- package/dist/components/panel.d.ts +13 -16
- package/dist/components/panel.d.ts.map +1 -1
- package/dist/components/panel.js +13 -97
- package/dist/components/panel.js.map +1 -1
- package/dist/components/shared.d.ts +2 -6
- package/dist/components/shared.d.ts.map +1 -1
- package/dist/components/shared.js +2 -6
- package/dist/components/shared.js.map +1 -1
- package/dist/components/view.d.ts +7 -8
- package/dist/components/view.d.ts.map +1 -1
- package/dist/components/view.js +16 -15
- package/dist/components/view.js.map +1 -1
- package/dist/context.d.ts +14 -9
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js.map +1 -1
- package/dist/editor-session.d.ts +77 -165
- package/dist/editor-session.d.ts.map +1 -1
- package/dist/editor-session.js +164 -586
- package/dist/editor-session.js.map +1 -1
- package/dist/hooks.d.ts +2 -23
- package/dist/hooks.d.ts.map +1 -1
- package/dist/hooks.js +24 -116
- package/dist/hooks.js.map +1 -1
- package/dist/i18n.d.ts +4 -66
- package/dist/i18n.d.ts.map +1 -1
- package/dist/i18n.js +6 -68
- package/dist/i18n.js.map +1 -1
- package/dist/index.d.ts +6 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -8
- package/dist/index.js.map +1 -1
- package/dist/provider.d.ts +1 -1
- package/dist/provider.d.ts.map +1 -1
- package/dist/provider.js +12 -12
- package/dist/provider.js.map +1 -1
- package/dist/styles.d.ts +1 -1
- package/dist/styles.d.ts.map +1 -1
- package/dist/styles.js +4 -4
- package/package.json +2 -2
- package/src/cache.ts +32 -55
- package/src/client.ts +7 -55
- package/src/components/card.tsx +6 -7
- package/src/components/editor.tsx +208 -308
- package/src/components/icons.tsx +2 -2
- package/src/components/panel.tsx +43 -300
- package/src/components/shared.tsx +3 -12
- package/src/components/view.tsx +26 -29
- package/src/context.ts +16 -11
- package/src/editor-session.ts +197 -675
- package/src/hooks.ts +25 -140
- package/src/i18n.ts +6 -68
- package/src/index.ts +7 -39
- package/src/provider.tsx +13 -13
- package/src/styles.ts +4 -4
- package/dist/components/approval.d.ts +0 -34
- package/dist/components/approval.d.ts.map +0 -1
- package/dist/components/approval.js +0 -80
- package/dist/components/approval.js.map +0 -1
- package/dist/components/version-diff.d.ts +0 -35
- package/dist/components/version-diff.d.ts.map +0 -1
- package/dist/components/version-diff.js +0 -85
- package/dist/components/version-diff.js.map +0 -1
- package/dist/line-diff.d.ts +0 -25
- package/dist/line-diff.d.ts.map +0 -1
- package/dist/line-diff.js +0 -96
- package/dist/line-diff.js.map +0 -1
- package/src/components/approval.tsx +0 -219
- package/src/components/version-diff.tsx +0 -266
- package/src/line-diff.ts +0 -111
|
@@ -1,266 +0,0 @@
|
|
|
1
|
-
import type { Artifact, ChangeSummary } from '@artkit-ai/core';
|
|
2
|
-
import { Columns2, Rows2 } from 'lucide-react';
|
|
3
|
-
import { useMemo, useState } from 'react';
|
|
4
|
-
import { type ArtkitContextValue, useArtkit } from '../context.js';
|
|
5
|
-
import { useArtifact } from '../hooks.js';
|
|
6
|
-
import { diffLines, type LineDiffEntry, toSplitRows } from '../line-diff.js';
|
|
7
|
-
import { ChangeList, cx, ErrorMessage, Loading, rootAttributes, type Slots, slot } from './shared.js';
|
|
8
|
-
|
|
9
|
-
export type DiffLayout = 'unified' | 'split';
|
|
10
|
-
export type ArtifactVersionDiffPart = 'toolbar' | 'changes' | 'lines';
|
|
11
|
-
|
|
12
|
-
export interface ArtifactVersionDiffProps {
|
|
13
|
-
/** Load both versions by id. */
|
|
14
|
-
id?: string;
|
|
15
|
-
/** Older version; defaults to the one before `to`. */
|
|
16
|
-
from?: number;
|
|
17
|
-
/** Newer version; defaults to the latest. */
|
|
18
|
-
to?: number;
|
|
19
|
-
/** Or pass both artifacts directly. */
|
|
20
|
-
before?: Artifact;
|
|
21
|
-
after?: Artifact;
|
|
22
|
-
layout?: DiffLayout;
|
|
23
|
-
defaultLayout?: DiffLayout;
|
|
24
|
-
onLayoutChange?(layout: DiffLayout): void;
|
|
25
|
-
/** Show the structural change list from `kind.diff` (default true). */
|
|
26
|
-
showChanges?: boolean;
|
|
27
|
-
/** Show the line diff of the full projections (default true). */
|
|
28
|
-
showLines?: boolean;
|
|
29
|
-
className?: string;
|
|
30
|
-
slots?: Slots<ArtifactVersionDiffPart>;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export interface VersionComparison {
|
|
34
|
-
changes: ChangeSummary[];
|
|
35
|
-
lines: LineDiffEntry[];
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/** Structural changes plus a line diff of the full text projections. `before` undefined means empty. */
|
|
39
|
-
export function compareVersions(
|
|
40
|
-
ctx: ArtkitContextValue,
|
|
41
|
-
before: Artifact | undefined,
|
|
42
|
-
after: Artifact,
|
|
43
|
-
): VersionComparison {
|
|
44
|
-
const kind = ctx.registry.get(after.kind);
|
|
45
|
-
const beforeContent = before?.content ?? kind.empty();
|
|
46
|
-
const changes: ChangeSummary[] = [];
|
|
47
|
-
if (before && before.title !== after.title) {
|
|
48
|
-
changes.push({
|
|
49
|
-
type: 'changed',
|
|
50
|
-
target: 'envelope:title',
|
|
51
|
-
summary: `'${before.title}' → '${after.title}'`,
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
try {
|
|
55
|
-
changes.push(...kind.diff(beforeContent, after.content));
|
|
56
|
-
} catch {
|
|
57
|
-
// The text diff below still shows what changed.
|
|
58
|
-
}
|
|
59
|
-
const project = (content: unknown, artifact: Artifact) => {
|
|
60
|
-
try {
|
|
61
|
-
return kind.project(content, {
|
|
62
|
-
mode: 'full',
|
|
63
|
-
locale: artifact.locale,
|
|
64
|
-
theme: ctx.themeFor(artifact.themeId),
|
|
65
|
-
}).text;
|
|
66
|
-
} catch {
|
|
67
|
-
return JSON.stringify(content, null, 2);
|
|
68
|
-
}
|
|
69
|
-
};
|
|
70
|
-
const lines = diffLines(before ? project(beforeContent, before) : '', project(after.content, after));
|
|
71
|
-
return { changes, lines };
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/** Side-by-side or highlighted comparison between two versions (spec §13.1). */
|
|
75
|
-
export function ArtifactVersionDiff(props: ArtifactVersionDiffProps) {
|
|
76
|
-
const ctx = useArtkit();
|
|
77
|
-
const { t } = ctx;
|
|
78
|
-
const [ownLayout, setOwnLayout] = useState<DiffLayout>(props.defaultLayout ?? 'unified');
|
|
79
|
-
const layout = props.layout ?? ownLayout;
|
|
80
|
-
const setLayout = (next: DiffLayout) => {
|
|
81
|
-
setOwnLayout(next);
|
|
82
|
-
props.onLayoutChange?.(next);
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
const afterQuery = useArtifact(
|
|
86
|
-
props.after ? undefined : props.id,
|
|
87
|
-
props.to === undefined ? {} : { version: props.to },
|
|
88
|
-
);
|
|
89
|
-
const after = props.after ?? afterQuery.artifact;
|
|
90
|
-
const fromVersion = props.from ?? (after && after.version > 1 ? after.version - 1 : undefined);
|
|
91
|
-
const beforeQuery = useArtifact(
|
|
92
|
-
props.before || fromVersion === undefined ? undefined : (props.id ?? after?.id),
|
|
93
|
-
{
|
|
94
|
-
...(fromVersion === undefined ? {} : { version: fromVersion }),
|
|
95
|
-
},
|
|
96
|
-
);
|
|
97
|
-
const before = props.before ?? (fromVersion === undefined ? undefined : beforeQuery.artifact);
|
|
98
|
-
|
|
99
|
-
const comparison = useMemo(
|
|
100
|
-
() => (after && ctx.registry.has(after.kind) ? compareVersions(ctx, before, after) : undefined),
|
|
101
|
-
[ctx, before, after],
|
|
102
|
-
);
|
|
103
|
-
|
|
104
|
-
const error = afterQuery.error ?? beforeQuery.error;
|
|
105
|
-
const waiting = !after || (fromVersion !== undefined && !before);
|
|
106
|
-
const attrs = rootAttributes(ctx, after?.themeId);
|
|
107
|
-
if (error) {
|
|
108
|
-
return (
|
|
109
|
-
<div className={cx('ak-root ak-diff', props.className)} {...attrs}>
|
|
110
|
-
<ErrorMessage error={error} />
|
|
111
|
-
</div>
|
|
112
|
-
);
|
|
113
|
-
}
|
|
114
|
-
if (waiting || !comparison || !after) {
|
|
115
|
-
return (
|
|
116
|
-
<div className={cx('ak-root ak-diff', props.className)} {...attrs}>
|
|
117
|
-
<Loading />
|
|
118
|
-
</div>
|
|
119
|
-
);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
const beforeLabel = before ? t('diffBefore', { version: before.version }) : '—';
|
|
123
|
-
const afterLabel = t('diffAfter', { version: after.version });
|
|
124
|
-
|
|
125
|
-
return (
|
|
126
|
-
<div className={cx('ak-root ak-diff', props.className)} {...attrs}>
|
|
127
|
-
{props.showChanges === false ? null : (
|
|
128
|
-
<section aria-label={t('changes')}>
|
|
129
|
-
<ChangeList changes={comparison.changes} {...slot(props.slots, 'changes', '')} />
|
|
130
|
-
</section>
|
|
131
|
-
)}
|
|
132
|
-
{props.showLines === false ? null : (
|
|
133
|
-
<>
|
|
134
|
-
<fieldset {...slot(props.slots, 'toolbar', 'ak-diff-toolbar')}>
|
|
135
|
-
<legend className="ak-sr-only">{t('diffViewLabel')}</legend>
|
|
136
|
-
{(['unified', 'split'] as const).map((option) => (
|
|
137
|
-
<button
|
|
138
|
-
key={option}
|
|
139
|
-
type="button"
|
|
140
|
-
className="ak-button"
|
|
141
|
-
aria-pressed={layout === option}
|
|
142
|
-
onClick={() => setLayout(option)}
|
|
143
|
-
>
|
|
144
|
-
{option === 'unified' ? <Rows2 aria-hidden="true" /> : <Columns2 aria-hidden="true" />}
|
|
145
|
-
{option === 'unified' ? t('diffUnified') : t('diffSplit')}
|
|
146
|
-
</button>
|
|
147
|
-
))}
|
|
148
|
-
</fieldset>
|
|
149
|
-
{layout === 'unified' ? (
|
|
150
|
-
<UnifiedLines
|
|
151
|
-
lines={comparison.lines}
|
|
152
|
-
caption={`${beforeLabel} → ${afterLabel}`}
|
|
153
|
-
slots={props.slots}
|
|
154
|
-
/>
|
|
155
|
-
) : (
|
|
156
|
-
<SplitLines
|
|
157
|
-
lines={comparison.lines}
|
|
158
|
-
beforeLabel={beforeLabel}
|
|
159
|
-
afterLabel={afterLabel}
|
|
160
|
-
slots={props.slots}
|
|
161
|
-
/>
|
|
162
|
-
)}
|
|
163
|
-
</>
|
|
164
|
-
)}
|
|
165
|
-
</div>
|
|
166
|
-
);
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
function Marker({ type }: { type: LineDiffEntry['type'] }) {
|
|
170
|
-
const { t } = useArtkit();
|
|
171
|
-
if (type === 'equal') return <td className="ak-diff-marker" />;
|
|
172
|
-
return (
|
|
173
|
-
<td className="ak-diff-marker">
|
|
174
|
-
<span aria-hidden="true">{type === 'insert' ? '+' : '−'}</span>
|
|
175
|
-
<span className="ak-sr-only">{type === 'insert' ? t('lineAdded') : t('lineRemoved')}</span>
|
|
176
|
-
</td>
|
|
177
|
-
);
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
function UnifiedLines({
|
|
181
|
-
lines,
|
|
182
|
-
caption,
|
|
183
|
-
slots,
|
|
184
|
-
}: {
|
|
185
|
-
lines: LineDiffEntry[];
|
|
186
|
-
caption: string;
|
|
187
|
-
slots?: Slots<ArtifactVersionDiffPart> | undefined;
|
|
188
|
-
}) {
|
|
189
|
-
return (
|
|
190
|
-
<table {...slot(slots, 'lines', 'ak-diff-lines')} data-layout="unified">
|
|
191
|
-
<caption className="ak-sr-only">{caption}</caption>
|
|
192
|
-
<tbody>
|
|
193
|
-
{lines.map((line) => (
|
|
194
|
-
<tr
|
|
195
|
-
key={`${line.type}:${line.oldLine ?? '-'}:${line.newLine ?? '-'}`}
|
|
196
|
-
className="ak-diff-line"
|
|
197
|
-
data-type={line.type}
|
|
198
|
-
>
|
|
199
|
-
<th scope="row">{line.oldLine ?? ''}</th>
|
|
200
|
-
<th scope="row">{line.newLine ?? ''}</th>
|
|
201
|
-
<Marker type={line.type} />
|
|
202
|
-
<td>{line.text}</td>
|
|
203
|
-
</tr>
|
|
204
|
-
))}
|
|
205
|
-
</tbody>
|
|
206
|
-
</table>
|
|
207
|
-
);
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
function SplitLines({
|
|
211
|
-
lines,
|
|
212
|
-
beforeLabel,
|
|
213
|
-
afterLabel,
|
|
214
|
-
slots,
|
|
215
|
-
}: {
|
|
216
|
-
lines: LineDiffEntry[];
|
|
217
|
-
beforeLabel: string;
|
|
218
|
-
afterLabel: string;
|
|
219
|
-
slots?: Slots<ArtifactVersionDiffPart> | undefined;
|
|
220
|
-
}) {
|
|
221
|
-
const rows = useMemo(() => toSplitRows(lines), [lines]);
|
|
222
|
-
return (
|
|
223
|
-
<table {...slot(slots, 'lines', 'ak-diff-lines')} data-layout="split">
|
|
224
|
-
<thead>
|
|
225
|
-
<tr>
|
|
226
|
-
<th scope="col" colSpan={3}>
|
|
227
|
-
{beforeLabel}
|
|
228
|
-
</th>
|
|
229
|
-
<th scope="col" colSpan={3}>
|
|
230
|
-
{afterLabel}
|
|
231
|
-
</th>
|
|
232
|
-
</tr>
|
|
233
|
-
</thead>
|
|
234
|
-
<tbody>
|
|
235
|
-
{rows.map((row) => (
|
|
236
|
-
<tr key={`${row.left?.oldLine ?? '-'}:${row.right?.newLine ?? '-'}`}>
|
|
237
|
-
<th scope="row">{row.left?.oldLine ?? ''}</th>
|
|
238
|
-
{row.left && row.left.type !== 'equal' ? (
|
|
239
|
-
<Marker type="delete" />
|
|
240
|
-
) : (
|
|
241
|
-
<td className="ak-diff-marker" />
|
|
242
|
-
)}
|
|
243
|
-
<td
|
|
244
|
-
className="ak-diff-cell"
|
|
245
|
-
data-type={row.left && row.left.type !== 'equal' ? 'delete' : undefined}
|
|
246
|
-
>
|
|
247
|
-
{row.left?.text ?? ''}
|
|
248
|
-
</td>
|
|
249
|
-
<th scope="row">{row.right?.newLine ?? ''}</th>
|
|
250
|
-
{row.right && row.right.type !== 'equal' ? (
|
|
251
|
-
<Marker type="insert" />
|
|
252
|
-
) : (
|
|
253
|
-
<td className="ak-diff-marker" />
|
|
254
|
-
)}
|
|
255
|
-
<td
|
|
256
|
-
className="ak-diff-cell"
|
|
257
|
-
data-type={row.right && row.right.type !== 'equal' ? 'insert' : undefined}
|
|
258
|
-
>
|
|
259
|
-
{row.right?.text ?? ''}
|
|
260
|
-
</td>
|
|
261
|
-
</tr>
|
|
262
|
-
))}
|
|
263
|
-
</tbody>
|
|
264
|
-
</table>
|
|
265
|
-
);
|
|
266
|
-
}
|
package/src/line-diff.ts
DELETED
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
export type LineDiffType = 'equal' | 'insert' | 'delete';
|
|
2
|
-
|
|
3
|
-
export interface LineDiffEntry {
|
|
4
|
-
type: LineDiffType;
|
|
5
|
-
text: string;
|
|
6
|
-
/** 1-based line number in the old text (equal and delete). */
|
|
7
|
-
oldLine?: number;
|
|
8
|
-
/** 1-based line number in the new text (equal and insert). */
|
|
9
|
-
newLine?: number;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export interface LineDiffOptions {
|
|
13
|
-
/**
|
|
14
|
-
* Upper bound for the LCS table (rows × columns) after trimming the common prefix and suffix.
|
|
15
|
-
* Above it the middle is reported as a block replacement, keeping memory bounded on huge projections.
|
|
16
|
-
*/
|
|
17
|
-
maxCells?: number;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const splitLines = (text: string) => (text === '' ? [] : text.replace(/\r\n?/g, '\n').split('\n'));
|
|
21
|
-
|
|
22
|
-
/** Line diff based on the longest common subsequence, with common prefix/suffix trimmed first. */
|
|
23
|
-
export function diffLines(before: string, after: string, options: LineDiffOptions = {}): LineDiffEntry[] {
|
|
24
|
-
const a = splitLines(before);
|
|
25
|
-
const b = splitLines(after);
|
|
26
|
-
const maxCells = options.maxCells ?? 4_000_000;
|
|
27
|
-
let start = 0;
|
|
28
|
-
while (start < a.length && start < b.length && a[start] === b[start]) start++;
|
|
29
|
-
let endA = a.length;
|
|
30
|
-
let endB = b.length;
|
|
31
|
-
while (endA > start && endB > start && a[endA - 1] === b[endB - 1]) {
|
|
32
|
-
endA--;
|
|
33
|
-
endB--;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const out: LineDiffEntry[] = [];
|
|
37
|
-
for (let i = 0; i < start; i++) out.push({ type: 'equal', text: a[i]!, oldLine: i + 1, newLine: i + 1 });
|
|
38
|
-
|
|
39
|
-
const midA = a.slice(start, endA);
|
|
40
|
-
const midB = b.slice(start, endB);
|
|
41
|
-
const n = midA.length;
|
|
42
|
-
const m = midB.length;
|
|
43
|
-
if (n > 0 && m > 0 && n * m <= maxCells) {
|
|
44
|
-
// lengths[i][j] = LCS length of midA[i..] and midB[j..], stored flat.
|
|
45
|
-
const width = m + 1;
|
|
46
|
-
const lengths = new Uint32Array((n + 1) * width);
|
|
47
|
-
for (let i = n - 1; i >= 0; i--) {
|
|
48
|
-
for (let j = m - 1; j >= 0; j--) {
|
|
49
|
-
lengths[i * width + j] =
|
|
50
|
-
midA[i] === midB[j]
|
|
51
|
-
? lengths[(i + 1) * width + j + 1]! + 1
|
|
52
|
-
: Math.max(lengths[(i + 1) * width + j]!, lengths[i * width + j + 1]!);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
let i = 0;
|
|
56
|
-
let j = 0;
|
|
57
|
-
while (i < n && j < m) {
|
|
58
|
-
if (midA[i] === midB[j]) {
|
|
59
|
-
out.push({ type: 'equal', text: midA[i]!, oldLine: start + i + 1, newLine: start + j + 1 });
|
|
60
|
-
i++;
|
|
61
|
-
j++;
|
|
62
|
-
} else if (lengths[(i + 1) * width + j]! >= lengths[i * width + j + 1]!) {
|
|
63
|
-
out.push({ type: 'delete', text: midA[i]!, oldLine: start + i + 1 });
|
|
64
|
-
i++;
|
|
65
|
-
} else {
|
|
66
|
-
out.push({ type: 'insert', text: midB[j]!, newLine: start + j + 1 });
|
|
67
|
-
j++;
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
for (; i < n; i++) out.push({ type: 'delete', text: midA[i]!, oldLine: start + i + 1 });
|
|
71
|
-
for (; j < m; j++) out.push({ type: 'insert', text: midB[j]!, newLine: start + j + 1 });
|
|
72
|
-
} else {
|
|
73
|
-
for (let k = 0; k < n; k++) out.push({ type: 'delete', text: midA[k]!, oldLine: start + k + 1 });
|
|
74
|
-
for (let k = 0; k < m; k++) out.push({ type: 'insert', text: midB[k]!, newLine: start + k + 1 });
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
for (let k = 0; k < a.length - endA; k++) {
|
|
78
|
-
out.push({ type: 'equal', text: a[endA + k]!, oldLine: endA + k + 1, newLine: endB + k + 1 });
|
|
79
|
-
}
|
|
80
|
-
return out;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
export interface SplitRow {
|
|
84
|
-
left?: LineDiffEntry;
|
|
85
|
-
right?: LineDiffEntry;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/** Pairs deletions with the insertions that follow them, for a side-by-side layout. */
|
|
89
|
-
export function toSplitRows(entries: LineDiffEntry[]): SplitRow[] {
|
|
90
|
-
const rows: SplitRow[] = [];
|
|
91
|
-
let index = 0;
|
|
92
|
-
while (index < entries.length) {
|
|
93
|
-
const entry = entries[index]!;
|
|
94
|
-
if (entry.type === 'equal') {
|
|
95
|
-
rows.push({ left: entry, right: entry });
|
|
96
|
-
index++;
|
|
97
|
-
continue;
|
|
98
|
-
}
|
|
99
|
-
const deletes: LineDiffEntry[] = [];
|
|
100
|
-
const inserts: LineDiffEntry[] = [];
|
|
101
|
-
while (index < entries.length && entries[index]!.type === 'delete') deletes.push(entries[index++]!);
|
|
102
|
-
while (index < entries.length && entries[index]!.type === 'insert') inserts.push(entries[index++]!);
|
|
103
|
-
for (let k = 0; k < Math.max(deletes.length, inserts.length); k++) {
|
|
104
|
-
const row: SplitRow = {};
|
|
105
|
-
if (deletes[k]) row.left = deletes[k];
|
|
106
|
-
if (inserts[k]) row.right = inserts[k];
|
|
107
|
-
rows.push(row);
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
return rows;
|
|
111
|
-
}
|