-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathChange.ts
More file actions
124 lines (111 loc) · 3.85 KB
/
Change.ts
File metadata and controls
124 lines (111 loc) · 3.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import { array, monoid, nonEmptyArray, option, pipe, tagged } from '@code-expert/prelude';
import { eqFsNode, isFile } from '@/lib/tauri/fs';
import { FsDir, FsFile } from './FsNode';
import { LocalFileInfo } from './LocalFileInfo';
import { RemoteFileInfo, RemoteNodeInfo } from './RemoteNodeInfo';
export type RemoteChangeType =
| tagged.Tagged<'noChange'> // fixme: seems to be unused - remove
| tagged.Tagged<'updated', number>
| tagged.Tagged<'removed'>
| tagged.Tagged<'added', number>;
export const remoteChangeType = tagged.build<RemoteChangeType>();
export type LocalChangeType =
| tagged.Tagged<'noChange'> // fixme: seems to be unused - remove
| tagged.Tagged<'updated'>
| tagged.Tagged<'removed'>
| tagged.Tagged<'added'>;
export const localChangeType = tagged.build<LocalChangeType>();
export interface RemoteDirChange extends FsDir {
change: RemoteChangeType;
}
export interface RemoteFileChange extends FsFile {
change: RemoteChangeType;
}
export type RemoteNodeChange = RemoteDirChange | RemoteFileChange;
export interface LocalDirChange extends FsDir {
change: LocalChangeType;
}
export interface LocalFileChange extends FsFile {
change: LocalChangeType;
}
export type LocalNodeChange = LocalDirChange | LocalFileChange;
// -------------------------------------------------------------------------------------------------
export const getRemoteChanges = (
previous: Array<RemoteFileInfo>,
latest: Array<RemoteNodeInfo>,
): option.Option<NonEmptyArray<RemoteFileChange>> => {
const latestFiles = pipe(latest, array.filter(isFile));
const removed: Array<RemoteFileChange> = pipe(
previous,
array.difference<RemoteFileInfo>(eqFsNode)(latestFiles),
array.map(({ type, path }) => ({ type, path, change: remoteChangeType.removed() })),
);
const added: Array<RemoteFileChange> = pipe(
latestFiles,
array.difference<RemoteFileInfo>(eqFsNode)(previous),
array.map(({ type, path, version }) => ({
type,
path,
change: remoteChangeType.added(version),
})),
);
const updated: Array<RemoteFileChange> = pipe(
previous,
array.filter((ls) =>
pipe(
latestFiles,
array.findFirst((cs) => cs.path === ls.path),
option.exists((cs) => cs.version !== ls.version),
),
),
array.map(({ type, path, version }) => ({
type,
path,
change: remoteChangeType.updated(version), // fixme: use latest version here
})),
);
return pipe(
[removed, added, updated],
monoid.concatAll(array.getMonoid()),
nonEmptyArray.fromArray,
);
};
export const getLocalChanges = (
previous: Array<LocalFileInfo>,
latest: Array<LocalFileInfo>,
): option.Option<NonEmptyArray<LocalFileChange>> => {
const previousFiles = pipe(previous, array.filter(isFile));
const latestFiles = pipe(latest, array.filter(isFile));
const removed: Array<LocalFileChange> = pipe(
previousFiles,
array.difference<LocalFileInfo>(eqFsNode)(latestFiles),
array.map(({ type, path }) => ({ type, path, change: localChangeType.removed() })),
);
const added: Array<LocalFileChange> = pipe(
latestFiles,
array.difference<LocalFileInfo>(eqFsNode)(previousFiles),
array.map(({ type, path }) => ({ type, path, change: localChangeType.added() })),
);
const updated: Array<LocalFileChange> = pipe(
previousFiles,
array.bindTo('previous'),
array.bind('latest', ({ previous }) =>
pipe(
latestFiles,
array.findFirst((latest) => eqFsNode.equals(previous, latest)),
option.fold(() => [], array.of),
),
),
array.filter(({ latest, previous }) => latest.hash !== previous.hash),
array.map(({ latest: { type, path } }) => ({
type,
path,
change: localChangeType.updated(),
})),
);
return pipe(
[removed, added, updated],
monoid.concatAll(array.getMonoid()),
nonEmptyArray.fromArray,
);
};