-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathlines.ts
More file actions
114 lines (107 loc) · 3.14 KB
/
lines.ts
File metadata and controls
114 lines (107 loc) · 3.14 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
import * as readline from 'readline'
import StreamTree, { finishReadable, finishWritable, ReadableStreamTree } from 'tree-stream'
import { FileStatus, FileSystem } from './fs'
/**
* Reads every line from a file.
* @param url The URL of the file to read lines from.
* @param map Callback called for each line.
*/
export async function readLines<X>(
fileSystem: FileSystem,
url: string,
map: (x: string) => X
): Promise<X[]> {
return mapLines(await fileSystem.openReadableFile(url), map)
}
/**
* Reads every line from a file, treating the first line as a header.
* @param url The URL of the file to read lines from.
* @param map Callback called for every line succeeding the header.
* @param header Callback called for the first line.
*/
export async function readLinesWithHeader<X, H>(
fileSystem: FileSystem,
url: string,
map: (x: string) => X,
header?: (x: string) => H,
ret: X[] = []
): Promise<[H | undefined, X[]]> {
return mapLinesWithHeader(await fileSystem.openReadableFile(url), map, header, ret)
}
export async function parseLines(
stream: ReadableStreamTree,
callback: (x: string) => void
): Promise<void> {
return new Promise((resolve, reject) => {
const input = readline.createInterface({
input: finishReadable(stream, resolve, reject),
})
input.on('line', callback)
})
}
/**
* Maps lines from [[stream]]. Used to implement [[readLines]].
* @param stream The stream to read lines from.
*/
export async function mapLines<X>(stream: ReadableStreamTree, map: (x: string) => X): Promise<X[]> {
const ret: X[] = []
await parseLines(stream, (line) => ret.push(map(line)))
return ret
}
/**
* Parses lines (with header) from [[stream]]. Used to implement [[readLinesWithHeader]].
* @param stream The stream to read lines from.
*/
export async function mapLinesWithHeader<X, H>(
stream: ReadableStreamTree,
map: (x: string) => X,
header?: (y: string) => H,
ret: X[] = []
): Promise<[H | undefined, X[]]> {
return new Promise((resolve, reject) => {
let hdr: H | undefined
const input = readline.createInterface({
input: stream.finish((err) => {
if (err) reject(err)
else resolve([hdr, ret])
}),
})
input.on('line', (line) => {
if (header && !hdr) hdr = header(line)
else {
const mapped = map(line)
ret?.push(mapped)
}
})
})
}
/**
* Appends a line of text to a file.
* @param url The URL of the file to append a line to.
*/
export async function appendLine(
fileSystem: FileSystem,
urlText: string,
line: string
): Promise<FileStatus | null> {
return fileSystem.appendToFile(
urlText,
StreamTree.writer(async (stream) => {
stream.write(line + '\n')
stream.end()
})
)
}
/**
* Writes the string to a file.
* @param url The URL of the file to serialize the string to.
* @param value The string to serialize.
*/
export async function writeContent(fileSystem: FileSystem, url: string, value: string) {
const stream = await fileSystem.openWritableFile(url)
return new Promise<void>((resolve, reject) => {
const out = finishWritable(stream, resolve, reject)
out.write(value)
out.end()
})
}