Skip to content

Commit 343ca1a

Browse files
committed
feat: add TextFile adapters
1 parent d75cc47 commit 343ca1a

11 files changed

+153
-68
lines changed

src/adapters/JSONFile.test.ts

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,24 +12,9 @@ test('should read and write', async (t) => {
1212
// Null if file doesn't exist
1313
t.is(await file.read(), null)
1414

15-
// Write obj
15+
// Write
1616
t.is(await file.write(obj), undefined)
1717

18-
// Read obj
18+
// Read
1919
t.deepEqual(await file.read(), obj)
2020
})
21-
22-
test('should preserve order', async (t) => {
23-
const filename = tempy.file()
24-
const file = new JSONFile(filename)
25-
const promises = []
26-
27-
let i = 0
28-
for (; i <= 100; i++) {
29-
promises.push(file.write(String(i)))
30-
}
31-
32-
await Promise.all(promises)
33-
34-
t.is(await file.read(), String(i - 1))
35-
})

src/adapters/JSONFile.ts

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,23 @@
1-
import fs from 'fs'
2-
import { Writer } from 'steno'
3-
41
import { Adapter } from '../Low.js'
2+
import { TextFile } from './TextFile.js'
53

64
export class JSONFile<T> implements Adapter<T> {
7-
private filename: string
8-
private writer: Writer
5+
private adapter: TextFile
96

107
constructor(filename: string) {
11-
this.filename = filename
12-
this.writer = new Writer(filename)
8+
this.adapter = new TextFile(filename)
139
}
1410

1511
async read(): Promise<T | null> {
16-
let data
17-
18-
try {
19-
data = await fs.promises.readFile(this.filename, 'utf-8')
20-
} catch (e) {
21-
if ((e as NodeJS.ErrnoException).code === 'ENOENT') {
22-
return null
23-
}
24-
throw e
12+
const data = await this.adapter.read()
13+
if (data === null) {
14+
return null
15+
} else {
16+
return JSON.parse(data) as T
2517
}
26-
27-
return JSON.parse(data) as T
2818
}
2919

30-
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
3120
write(obj: unknown): Promise<void> {
32-
return this.writer.write(JSON.stringify(obj, null, 2))
21+
return this.adapter.write(JSON.stringify(obj, null, 2))
3322
}
3423
}

src/adapters/JSONFileSync.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ test('should read and write', (t) => {
1212
// Null if file doesn't exist
1313
t.is(file.read(), null)
1414

15-
// Write obj
15+
// Write
1616
t.is(file.write(obj), undefined)
1717

18-
// Read obj
18+
// Read
1919
t.deepEqual(file.read(), obj)
2020
})

src/adapters/JSONFileSync.ts

Lines changed: 9 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,23 @@
1-
import fs from 'fs'
2-
import path from 'path'
3-
41
import { SyncAdapter } from '../LowSync.js'
2+
import { TextFileSync } from './TextFileSync.js'
53

64
export class JSONFileSync<T> implements SyncAdapter<T> {
7-
private tempFilename: string
8-
filename: string
5+
private adapter: TextFileSync
96

107
constructor(filename: string) {
11-
this.filename = filename
12-
this.tempFilename = path.join(
13-
path.dirname(filename),
14-
`.${path.basename(filename)}.tmp`,
15-
)
8+
this.adapter = new TextFileSync(filename)
169
}
1710

1811
read(): T | null {
19-
let data
20-
21-
try {
22-
data = fs.readFileSync(this.filename, 'utf-8')
23-
} catch (e) {
24-
if ((e as NodeJS.ErrnoException).code === 'ENOENT') {
25-
return null
26-
}
27-
throw e
12+
const data = this.adapter.read()
13+
if (data === null) {
14+
return null
15+
} else {
16+
return JSON.parse(data) as T
2817
}
29-
30-
return JSON.parse(data) as T
3118
}
3219

3320
write(obj: T): void {
34-
fs.writeFileSync(this.tempFilename, JSON.stringify(obj, null, 2))
35-
fs.renameSync(this.tempFilename, this.filename)
21+
this.adapter.write(JSON.stringify(obj, null, 2))
3622
}
3723
}

src/adapters/LocalStorage.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ test('should read and write', (t) => {
2525
const obj = { a: 1 }
2626
const storage = new LocalStorage('key')
2727

28-
// Write obj
28+
// Write
2929
t.is(storage.write(obj), undefined)
3030

31-
// Read obj
31+
// Read
3232
t.deepEqual(storage.read(), obj)
3333
})

src/adapters/Memory.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ test('should read and write', async (t) => {
1010
// Null by default
1111
t.is(await memory.read(), null)
1212

13-
// Write obj
13+
// Write
1414
t.is(await memory.write(obj), undefined)
1515

16-
// Read obj
16+
// Read
1717
t.deepEqual(await memory.read(), obj)
1818
})

src/adapters/MemorySync.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ test('should read and write', (t) => {
1010
// Null by default
1111
t.is(memory.read(), null)
1212

13-
// Write obj
13+
// Write
1414
t.is(memory.write(obj), undefined)
1515

16-
// Read obj
16+
// Read
1717
t.deepEqual(memory.read(), obj)
1818
})

src/adapters/TextFile.test.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import test from 'ava'
2+
import tempy from 'tempy'
3+
4+
import { TextFile } from './TextFile.js'
5+
6+
test('should read and write', async (t) => {
7+
const str = 'foo'
8+
9+
const filename = tempy.file()
10+
const file = new TextFile(filename)
11+
12+
// Null if file doesn't exist
13+
t.is(await file.read(), null)
14+
15+
// Write
16+
t.is(await file.write(str), undefined)
17+
18+
// Read
19+
t.deepEqual(await file.read(), str)
20+
})
21+
22+
test('should preserve order', async (t) => {
23+
const filename = tempy.file()
24+
const file = new TextFile(filename)
25+
const promises = []
26+
27+
let i = 0
28+
for (; i <= 100; i++) {
29+
promises.push(file.write(String(i)))
30+
}
31+
32+
await Promise.all(promises)
33+
34+
t.is(await file.read(), String(i - 1))
35+
})

src/adapters/TextFile.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import fs from 'fs'
2+
import { Writer } from 'steno'
3+
4+
import { Adapter } from '../Low.js'
5+
6+
export class TextFile implements Adapter<string> {
7+
private filename: string
8+
private writer: Writer
9+
10+
constructor(filename: string) {
11+
this.filename = filename
12+
this.writer = new Writer(filename)
13+
}
14+
15+
async read(): Promise<string | null> {
16+
let data
17+
18+
try {
19+
data = await fs.promises.readFile(this.filename, 'utf-8')
20+
} catch (e) {
21+
if ((e as NodeJS.ErrnoException).code === 'ENOENT') {
22+
return null
23+
}
24+
throw e
25+
}
26+
27+
return data
28+
}
29+
30+
write(str: string): Promise<void> {
31+
return this.writer.write(str)
32+
}
33+
}

src/adapters/TextFileSync.test.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import test from 'ava'
2+
import tempy from 'tempy'
3+
4+
import { TextFileSync } from './TextFileSync.js'
5+
6+
test('should read and write', (t) => {
7+
const str = 'foo'
8+
9+
const filename = tempy.file()
10+
const file = new TextFileSync(filename)
11+
12+
// Null if file doesn't exist
13+
t.is(file.read(), null)
14+
15+
// Write
16+
t.is(file.write(str), undefined)
17+
18+
// Read
19+
t.deepEqual(file.read(), str)
20+
})

0 commit comments

Comments
 (0)