Skip to content

Commit bb8e331

Browse files
committed
tidy up some stuff
1 parent 79a5dce commit bb8e331

File tree

4 files changed

+131
-86
lines changed

4 files changed

+131
-86
lines changed

src/adapters/indexeddb.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ class Sink {
9797
: reject(new DOMException(...GONE))
9898
}
9999
tx.oncomplete = () => resolve()
100+
tx.onerror = reject
101+
tx.onabort = reject
100102
})
101103
}
102104
}
@@ -117,21 +119,24 @@ class FileHandle {
117119
}
118120

119121
/** @param {FileHandle} other */
120-
isSameEntry (other) {
122+
async isSameEntry (other) {
121123
return this._id === other._id
122124
}
123125

124126
async getFile () {
125127
/** @type {File} */
126-
const file = await new Promise(resolve => {
127-
store(this._db)[1].get(this._id).onsuccess = evt => resolve(evt.target.result)
128+
const file = await new Promise((resolve, reject) => {
129+
const req = store(this._db)[1].get(this._id)
130+
req.onsuccess = evt => resolve(evt.target.result)
131+
req.onerror = evt => reject(evt.target.error)
128132
})
129133
if (!file) throw new DOMException(...GONE)
130134
return file
131135
}
132136

133137
async createWritable (opts) {
134-
const file = await this.getFile()
138+
let file = await this.getFile() // Used directly to test existences
139+
file = opts.keepExistingData ? file : new File([], this.name)
135140
return new Sink(this._db, this._id, file.size, file)
136141
}
137142
}
@@ -179,6 +184,7 @@ class FolderHandle {
179184
this.writable = true
180185
}
181186

187+
/** @returns {AsyncGenerator<[string, FileHandle | FolderHandle]>} */
182188
async * entries () {
183189
const entries = await new Promise(resolve => {
184190
store(this._db)[1].get(this._id).onsuccess = evt => resolve(evt.target.result)

src/adapters/memory.js

Lines changed: 41 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,18 @@ const Blob = globalThis.Blob || await import('fetch-blob').then(m => m.Blob)
77
const { INVALID, GONE, MISMATCH, MOD_ERR, SYNTAX, SECURITY, DISALLOWED } = errors
88

99
export class Sink {
10-
/** @param {FileHandle} fileHandle */
11-
constructor (fileHandle) {
10+
11+
/**
12+
* @param {FileHandle} fileHandle
13+
* @param {File} file
14+
*/
15+
constructor (fileHandle, file) {
1216
this.fileHandle = fileHandle
13-
this.file = fileHandle.file
14-
this.size = fileHandle.file.size
17+
this.file = file
18+
this.size = file.size
1519
this.position = 0
1620
}
21+
1722
write (chunk) {
1823
let file = this.file
1924

@@ -86,8 +91,8 @@ export class Sink {
8691
this.file = blob
8792
}
8893
close () {
89-
if (this.fileHandle.deleted) throw new DOMException(...GONE)
90-
this.fileHandle.file = this.file
94+
if (this.fileHandle._deleted) throw new DOMException(...GONE)
95+
this.fileHandle._file = this.file
9196
this.file =
9297
this.position =
9398
this.size = null
@@ -99,32 +104,37 @@ export class Sink {
99104

100105
export class FileHandle {
101106
constructor (name = '', file = new File([], name), writable = true) {
102-
this.file = file
107+
this._file = file
103108
this.name = name
104109
this.kind = 'file'
105-
this.deleted = false
110+
this._deleted = false
106111
this.writable = writable
107112
this.readable = true
108113
}
109114

110-
getFile () {
111-
if (this.deleted) throw new DOMException(...GONE)
112-
return this.file
115+
async getFile () {
116+
if (this._deleted) throw new DOMException(...GONE)
117+
return this._file
113118
}
114119

115-
createWritable (opts) {
120+
async createWritable (opts) {
116121
if (!this.writable) throw new DOMException(...DISALLOWED)
117-
if (this.deleted) throw new DOMException(...GONE)
118-
return new Sink(this)
122+
if (this._deleted) throw new DOMException(...GONE)
123+
124+
const file = opts.keepExistingData
125+
? await this.getFile()
126+
: new File([], this.name)
127+
128+
return new Sink(this, file)
119129
}
120130

121-
isSameEntry (other) {
131+
async isSameEntry (other) {
122132
return this === other
123133
}
124134

125-
destroy () {
126-
this.deleted = true
127-
this.file = null
135+
async _destroy () {
136+
this._deleted = true
137+
this._file = null
128138
}
129139
}
130140

@@ -134,29 +144,29 @@ export class FolderHandle {
134144
constructor (name, writable = true) {
135145
this.name = name
136146
this.kind = 'directory'
137-
this.deleted = false
147+
this._deleted = false
138148
/** @type {Object.<string, (FolderHandle|FileHandle)>} */
139149
this._entries = {}
140150
this.writable = writable
141151
this.readable = true
142152
}
143153

154+
/** @returns {AsyncGenerator<[string, FileHandle | FolderHandle]>} */
144155
async * entries () {
145-
if (this.deleted) throw new DOMException(...GONE)
156+
if (this._deleted) throw new DOMException(...GONE)
146157
yield* Object.entries(this._entries)
147158
}
148159

149-
isSameEntry (other) {
160+
async isSameEntry (other) {
150161
return this === other
151162
}
152163

153-
154164
/**
155165
* @param {string} name
156166
* @param {{ create: boolean; }} opts
157167
*/
158-
getDirectoryHandle (name, opts) {
159-
if (this.deleted) throw new DOMException(...GONE)
168+
async getDirectoryHandle (name, opts) {
169+
if (this._deleted) throw new DOMException(...GONE)
160170
const entry = this._entries[name]
161171
if (entry) { // entry exist
162172
if (entry instanceof FileHandle) {
@@ -177,7 +187,7 @@ export class FolderHandle {
177187
* @param {string} name
178188
* @param {{ create: boolean; }} opts
179189
*/
180-
getFileHandle (name, opts) {
190+
async getFileHandle (name, opts) {
181191
const entry = this._entries[name]
182192
const isFile = entry instanceof FileHandle
183193
if (entry && isFile) return entry
@@ -188,23 +198,23 @@ export class FolderHandle {
188198
}
189199
}
190200

191-
removeEntry (name, opts) {
201+
async removeEntry (name, opts) {
192202
const entry = this._entries[name]
193203
if (!entry) throw new DOMException(...GONE)
194-
entry.destroy(opts.recursive)
204+
await entry._destroy(opts.recursive)
195205
delete this._entries[name]
196206
}
197207

198-
destroy (recursive) {
208+
async _destroy (recursive) {
199209
for (let x of Object.values(this._entries)) {
200210
if (!recursive) throw new DOMException(...MOD_ERR)
201-
x.destroy(recursive)
211+
await x._destroy(recursive)
202212
}
203213
this._entries = {}
204-
this.deleted = true
214+
this._deleted = true
205215
}
206216
}
207217

208218
const fs = new FolderHandle('')
209219

210-
export default opts => fs
220+
export default () => fs

src/adapters/node.js

Lines changed: 36 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -9,46 +9,53 @@ import { errors } from '../util.js'
99
const { INVALID, GONE, MISMATCH, MOD_ERR, SYNTAX } = errors
1010

1111
export class Sink {
12+
13+
/**
14+
* @param {fs.FileHandle} fileHandle
15+
* @param {number} size
16+
*/
1217
constructor (fileHandle, size) {
13-
this.fileHandle = fileHandle
14-
this.size = size
15-
this.position = 0
18+
this._fileHandle = fileHandle
19+
this._size = size
20+
this._position = 0
1621
}
22+
1723
async abort() {
18-
await this.fileHandle.close()
24+
await this._fileHandle.close()
1925
}
26+
2027
async write (chunk) {
2128
if (typeof chunk === 'object') {
2229
if (chunk.type === 'write') {
2330
if (Number.isInteger(chunk.position) && chunk.position >= 0) {
24-
this.position = chunk.position
31+
this._position = chunk.position
2532
}
2633
if (!('data' in chunk)) {
27-
await this.fileHandle.close()
34+
await this._fileHandle.close()
2835
throw new DOMException(...SYNTAX('write requires a data argument'))
2936
}
3037
chunk = chunk.data
3138
} else if (chunk.type === 'seek') {
3239
if (Number.isInteger(chunk.position) && chunk.position >= 0) {
33-
if (this.size < chunk.position) {
40+
if (this._size < chunk.position) {
3441
throw new DOMException(...INVALID)
3542
}
36-
this.position = chunk.position
43+
this._position = chunk.position
3744
return
3845
} else {
39-
await this.fileHandle.close()
46+
await this._fileHandle.close()
4047
throw new DOMException(...SYNTAX('seek requires a position argument'))
4148
}
4249
} else if (chunk.type === 'truncate') {
4350
if (Number.isInteger(chunk.size) && chunk.size >= 0) {
44-
await this.fileHandle.truncate(chunk.size)
45-
this.size = chunk.size
46-
if (this.position > this.size) {
47-
this.position = this.size
51+
await this._fileHandle.truncate(chunk.size)
52+
this._size = chunk.size
53+
if (this._position > this._size) {
54+
this._position = this._size
4855
}
4956
return
5057
} else {
51-
await this.fileHandle.close()
58+
await this._fileHandle.close()
5259
throw new DOMException(...SYNTAX('truncate requires a size argument'))
5360
}
5461
}
@@ -60,25 +67,25 @@ export class Sink {
6067
chunk = Buffer.from(chunk)
6168
} else if (chunk instanceof Blob) {
6269
for await (const data of chunk.stream()) {
63-
const res = await this.fileHandle.writev([data], this.position)
64-
this.position += res.bytesWritten
65-
this.size += res.bytesWritten
70+
const res = await this._fileHandle.writev([data], this._position)
71+
this._position += res.bytesWritten
72+
this._size += res.bytesWritten
6673
}
6774
return
6875
}
6976

70-
const res = await this.fileHandle.writev([chunk], this.position)
71-
this.position += res.bytesWritten
72-
this.size += res.bytesWritten
77+
const res = await this._fileHandle.writev([chunk], this._position)
78+
this._position += res.bytesWritten
79+
this._size += res.bytesWritten
7380
}
7481

7582
async close () {
76-
await this.fileHandle.close()
83+
// First make sure we close the handle
84+
await this._fileHandle.close()
7785
}
7886
}
7987

8088
export class FileHandle {
81-
_path
8289

8390
/**
8491
* @param {string} path
@@ -97,11 +104,11 @@ export class FileHandle {
97104
return fileFrom(this._path)
98105
}
99106

100-
isSameEntry (other) {
101-
return this._path === this.#getPath.apply(other)
107+
async isSameEntry (other) {
108+
return this._path === this._getPath.apply(other)
102109
}
103110

104-
#getPath() {
111+
_getPath() {
105112
return this._path
106113
}
107114

@@ -118,17 +125,18 @@ export class FileHandle {
118125
export class FolderHandle {
119126
_path = ''
120127

121-
/** @param {string} path */
122-
constructor (path, name = '') {
128+
constructor (path = '', name = '') {
123129
this.name = name
124130
this.kind = 'directory'
125131
this._path = path
126132
}
127133

128-
isSameEntry (other) {
134+
/** @param {FolderHandle} other */
135+
async isSameEntry (other) {
129136
return this._path === other._path
130137
}
131138

139+
/** @returns {AsyncGenerator<[string, FileHandle | FolderHandle]>} */
132140
async * entries () {
133141
const dir = this._path
134142
const items = await fs.readdir(dir).catch(err => {

0 commit comments

Comments
 (0)