Skip to content

Commit e5f45e8

Browse files
committed
feat(chrono): add LogUseCase
1 parent e7bbab4 commit e5f45e8

File tree

8 files changed

+65
-9
lines changed

8 files changed

+65
-9
lines changed

packages/chrono/playground/PlayApp.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ async function run() {
4848
name: 'checkout',
4949
method: 'checkout',
5050
},
51+
{
52+
name: 'log',
53+
method: 'log',
54+
},
5155
]
5256

5357
const command = options.find((o) => o.name === commandName)

packages/chrono/src/ChronoApp.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,14 @@ import LocalHeadEntryRepository from './repositories/implementations/LocalHeadEn
1313

1414
import InitUseCase from './use-cases/InitUseCase'
1515
import CatFileUseCase from './use-cases/CatFileUseCase'
16-
import HashFileUseCase from './use-cases/HashEntryUseCase'
16+
import HashEntryUseCase from './use-cases/HashEntryUseCase'
1717
import RemoveUseCase from './use-cases/RemoveUseCase'
1818
import CommitUseCase from './use-cases/CommitUseCase'
1919
import StatusUseCase from './use-cases/StatusUseCase'
2020
import AddUseCase from './use-cases/AddUseCase'
2121
import ListFilesUseCase from './use-cases/ListFilesUseCase'
2222
import CheckoutUseCase from './use-cases/CheckoutUseCase'
23+
import LogUseCase from './use-cases/LogUseCase'
2324

2425
export default class ChronoApp {
2526
private readonly drive: IDrive
@@ -47,7 +48,7 @@ export default class ChronoApp {
4748
}
4849

4950
public async hashEntry(path: string) {
50-
const useCase = new HashFileUseCase(this.drive, this.objectRepository, this.blobRepository)
51+
const useCase = new HashEntryUseCase(this.drive, this.objectRepository, this.blobRepository)
5152

5253
return useCase.execute({ path })
5354
}
@@ -113,4 +114,10 @@ export default class ChronoApp {
113114

114115
return useCase.execute({ hash, path })
115116
}
117+
118+
public async log() {
119+
const useCase = new LogUseCase(this.objectRepository)
120+
121+
return useCase.execute()
122+
}
116123
}

packages/chrono/src/entities/ChronoObject.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export default class ChronoObject {
66
public static readonly HEAD_SEPARATOR = '\n\0\n'
77

88
public content = ''
9+
public hash = ''
910

1011
public get headText() {
1112
const [head] = this.content.split(ChronoObject.HEAD_SEPARATOR)
@@ -35,7 +36,11 @@ export default class ChronoObject {
3536
return this.head.type
3637
}
3738

38-
constructor(content: string | Uint8Array) {
39+
constructor(content: string | Uint8Array, hash?: string) {
40+
if (hash) {
41+
this.hash = hash
42+
}
43+
3944
if (typeof content === 'string') {
4045
this.content = content
4146
}

packages/chrono/src/entities/ChronoObjectCommit.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ export default class ChronoObjectCommit extends ChronoObject {
2020
return this.head.parent
2121
}
2222

23+
public get date() {
24+
return this.head.date
25+
}
26+
2327
public static from(payload: Payload) {
2428
const object = ChronoObject.fromObject({ ...payload, type: 'commit' }, payload.body)
2529

@@ -28,8 +32,12 @@ export default class ChronoObjectCommit extends ChronoObject {
2832

2933
public serialize() {
3034
return {
31-
...super.serialize(),
35+
hash: this.hash,
36+
type: this.type,
3237
message: this.message,
38+
tree: this.tree,
39+
parent: this.parent,
40+
date: this.date,
3341
}
3442
}
3543
}

packages/chrono/src/repositories/IObjectRepository.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import ChronoObject from '../entities/ChronoObject'
22

33
export default interface IObjectRepository {
4+
findAll(): Promise<ChronoObject[]>
45
find(objectHash: string): Promise<ChronoObject | null>
56
findOrFail(objectHash: string): Promise<ChronoObject>
67
save(object: ChronoObject): Promise<{ objectHash: string }>

packages/chrono/src/repositories/implementations/LocalObjectRepository.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,28 @@ export default class LocalObjectRepository implements IObjectRepository {
2525

2626
await this.drive.write(filePath, chronoObject.toBytes())
2727

28+
chronoObject.hash = objectHash
29+
2830
return {
2931
objectHash,
3032
}
3133
}
3234

35+
public findAll: IObjectRepository['findAll'] = async () => {
36+
const files = await this.drive.readdir(this.directory, {
37+
recursive: true,
38+
onlyFiles: true,
39+
})
40+
41+
const result: ChronoObject[] = []
42+
43+
for await (const file of files) {
44+
result.push(await this.findOrFail(file.replace('/', '')))
45+
}
46+
47+
return result
48+
}
49+
3350
public find: IObjectRepository['find'] = async (objectHash) => {
3451
const startHash = objectHash.slice(0, 2)
3552
const endHash = objectHash.slice(2)
@@ -60,7 +77,7 @@ export default class LocalObjectRepository implements IObjectRepository {
6077
return null
6178
}
6279

63-
const chronoObject = new ChronoObject(bytes)
80+
const chronoObject = new ChronoObject(bytes, objectHash)
6481

6582
return chronoObject
6683
}

packages/chrono/src/use-cases/CommitUseCase.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ export default class CommitUseCase {
143143
const payload: any = {
144144
message,
145145
tree: rooTreeHash,
146+
date: new Date().toISOString(),
146147
}
147148

148149
const headContents = await this.drive.read('.chrono/head')
@@ -166,9 +167,6 @@ export default class CommitUseCase {
166167

167168
await this.entryRepository.saveAll(entries)
168169

169-
return {
170-
commitHash,
171-
commit: commit.serialize(),
172-
}
170+
return commit.serialize()
173171
}
174172
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import ChronoObjectCommit from '../entities/ChronoObjectCommit'
2+
import IObjectRepository from '../repositories/IObjectRepository'
3+
4+
export default class LogUseCase {
5+
constructor(private readonly objectRepository: IObjectRepository) {}
6+
7+
public async execute() {
8+
const objects = await this.objectRepository.findAll()
9+
10+
return objects
11+
.filter((object) => object.type === 'commit')
12+
.map((o) => new ChronoObjectCommit(o.content, o.hash))
13+
.map((o) => o.serialize())
14+
.toSorted((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime())
15+
}
16+
}

0 commit comments

Comments
 (0)