diff options
Diffstat (limited to 'frontend/src/lib/draftGuard.ts')
| -rw-r--r-- | frontend/src/lib/draftGuard.ts | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/frontend/src/lib/draftGuard.ts b/frontend/src/lib/draftGuard.ts new file mode 100644 index 0000000..d6a5222 --- /dev/null +++ b/frontend/src/lib/draftGuard.ts @@ -0,0 +1,46 @@ +import { diffLines, diffWordsWithSpace } from 'diff'; + +export interface DiffStats { + added: number; + removed: number; +} + +export function unifiedDiffStats(before: string, after: string): DiffStats { + const parts = diffLines(before, after); + let added = 0; + let removed = 0; + for (const p of parts) { + if (p.added) added += p.value.replace(/\n$/, '').split('\n').length; + else if (p.removed) removed += p.value.replace(/\n$/, '').split('\n').length; + } + return { added, removed }; +} + +export interface ServerDraft { + generation: number; + code: string; +} + +export interface ConflictVerdict { + stale: boolean; + serverEqualsLocal: boolean; + localDirty: boolean; +} + +export class ConflictResolver { + constructor(private local: { generation: number; code: string }) {} + + onServerState(server: ServerDraft, lastKnownGeneration: number): ConflictVerdict { + const stale = server.generation !== lastKnownGeneration && lastKnownGeneration !== null; + const serverEqualsLocal = server.generation === this.local.generation && server.code === this.local.code; + return { stale, serverEqualsLocal, localDirty: true }; + } + + retryPlan(server: ServerDraft): { generation: number; code: string } { + return { generation: server.generation, code: this.local.code }; + } +} + +export function wordDiff(before: string, after: string) { + return diffWordsWithSpace(before, after); +} |
