@zenfs/dom 0.0.3 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/backends/FileSystemAccess.d.ts +7 -8
- package/dist/backends/FileSystemAccess.js +155 -210
- package/dist/backends/HTTPRequest.d.ts +7 -10
- package/dist/backends/HTTPRequest.js +83 -104
- package/dist/backends/IndexedDB.d.ts +2 -3
- package/dist/backends/IndexedDB.js +2 -3
- package/dist/backends/Storage.d.ts +2 -3
- package/dist/backends/Storage.js +2 -2
- package/dist/backends/Worker.d.ts +4 -5
- package/dist/backends/Worker.js +26 -32
- package/dist/browser.min.js +3 -8
- package/dist/browser.min.js.map +4 -4
- package/dist/fetch.d.ts +2 -3
- package/dist/fetch.js +20 -35
- package/package.json +3 -14
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
1
|
var _a;
|
|
11
2
|
import { BaseFileSystem } from '@zenfs/core/filesystem.js';
|
|
12
3
|
import { ApiError, ErrorCode } from '@zenfs/core/ApiError.js';
|
|
@@ -16,7 +7,6 @@ import { fetchIsAvailable, fetchFile, fetchFileSize } from '../fetch.js';
|
|
|
16
7
|
import { FileIndex, isIndexFileInode, isIndexDirInode } from '@zenfs/core/FileIndex.js';
|
|
17
8
|
import { CreateBackend } from '@zenfs/core/backends/backend.js';
|
|
18
9
|
import { R_OK } from '@zenfs/core/emulation/constants.js';
|
|
19
|
-
import { Buffer } from 'buffer';
|
|
20
10
|
/**
|
|
21
11
|
* A simple filesystem backed by HTTP downloads. You must create a directory listing using the
|
|
22
12
|
* `make_http_index` tool provided by ZenFS.
|
|
@@ -64,11 +54,13 @@ export class HTTPRequest extends BaseFileSystem {
|
|
|
64
54
|
baseUrl = baseUrl + '/';
|
|
65
55
|
}
|
|
66
56
|
this.prefixUrl = baseUrl;
|
|
67
|
-
this._requestFileInternal = fetchFile;
|
|
68
|
-
this._requestFileSizeInternal = fetchFileSize;
|
|
69
57
|
}
|
|
70
58
|
get metadata() {
|
|
71
|
-
return
|
|
59
|
+
return {
|
|
60
|
+
...super.metadata,
|
|
61
|
+
name: _a.Name,
|
|
62
|
+
readonly: true,
|
|
63
|
+
};
|
|
72
64
|
}
|
|
73
65
|
empty() {
|
|
74
66
|
this._index.fileIterator(function (file) {
|
|
@@ -77,8 +69,8 @@ export class HTTPRequest extends BaseFileSystem {
|
|
|
77
69
|
}
|
|
78
70
|
/**
|
|
79
71
|
* Special HTTPFS function: Preload the given file into the index.
|
|
80
|
-
* @param
|
|
81
|
-
* @param
|
|
72
|
+
* @param path
|
|
73
|
+
* @param buffer
|
|
82
74
|
*/
|
|
83
75
|
preloadFile(path, buffer) {
|
|
84
76
|
const inode = this._index.getInode(path);
|
|
@@ -94,101 +86,88 @@ export class HTTPRequest extends BaseFileSystem {
|
|
|
94
86
|
throw ApiError.EISDIR(path);
|
|
95
87
|
}
|
|
96
88
|
}
|
|
97
|
-
stat(path, cred) {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
stats.size = yield this._requestFileSize(path);
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
else if (isIndexDirInode(inode)) {
|
|
115
|
-
stats = inode.getStats();
|
|
116
|
-
}
|
|
117
|
-
else {
|
|
118
|
-
throw ApiError.FileError(ErrorCode.EINVAL, path);
|
|
89
|
+
async stat(path, cred) {
|
|
90
|
+
const inode = this._index.getInode(path);
|
|
91
|
+
if (inode === null) {
|
|
92
|
+
throw ApiError.ENOENT(path);
|
|
93
|
+
}
|
|
94
|
+
if (!inode.toStats().hasAccess(R_OK, cred)) {
|
|
95
|
+
throw ApiError.EACCES(path);
|
|
96
|
+
}
|
|
97
|
+
let stats;
|
|
98
|
+
if (isIndexFileInode(inode)) {
|
|
99
|
+
stats = inode.getData();
|
|
100
|
+
// At this point, a non-opened file will still have default stats from the listing.
|
|
101
|
+
if (stats.size < 0) {
|
|
102
|
+
stats.size = await this._requestFileSize(path);
|
|
119
103
|
}
|
|
120
|
-
|
|
121
|
-
|
|
104
|
+
}
|
|
105
|
+
else if (isIndexDirInode(inode)) {
|
|
106
|
+
stats = inode.getStats();
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
throw ApiError.FileError(ErrorCode.EINVAL, path);
|
|
110
|
+
}
|
|
111
|
+
return stats;
|
|
122
112
|
}
|
|
123
|
-
open(path, flags, mode, cred) {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
throw new ApiError(ErrorCode.EINVAL, 'Invalid FileMode object.');
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
else {
|
|
164
|
-
throw ApiError.EPERM(path);
|
|
113
|
+
async open(path, flags, mode, cred) {
|
|
114
|
+
// INVARIANT: You can't write to files on this file system.
|
|
115
|
+
if (flags.isWriteable()) {
|
|
116
|
+
throw new ApiError(ErrorCode.EPERM, path);
|
|
117
|
+
}
|
|
118
|
+
// Check if the path exists, and is a file.
|
|
119
|
+
const inode = this._index.getInode(path);
|
|
120
|
+
if (inode === null) {
|
|
121
|
+
throw ApiError.ENOENT(path);
|
|
122
|
+
}
|
|
123
|
+
if (!inode.toStats().hasAccess(flags.getMode(), cred)) {
|
|
124
|
+
throw ApiError.EACCES(path);
|
|
125
|
+
}
|
|
126
|
+
if (isIndexFileInode(inode) || isIndexDirInode(inode)) {
|
|
127
|
+
switch (flags.pathExistsAction()) {
|
|
128
|
+
case ActionType.THROW_EXCEPTION:
|
|
129
|
+
case ActionType.TRUNCATE_FILE:
|
|
130
|
+
throw ApiError.EEXIST(path);
|
|
131
|
+
case ActionType.NOP:
|
|
132
|
+
if (isIndexDirInode(inode)) {
|
|
133
|
+
const stats = inode.getStats();
|
|
134
|
+
return new NoSyncFile(this, path, flags, stats, stats.fileData || undefined);
|
|
135
|
+
}
|
|
136
|
+
const stats = inode.getData();
|
|
137
|
+
// Use existing file contents.
|
|
138
|
+
// XXX: Uh, this maintains the previously-used flag.
|
|
139
|
+
if (stats.fileData) {
|
|
140
|
+
return new NoSyncFile(this, path, flags, Stats.clone(stats), stats.fileData);
|
|
141
|
+
}
|
|
142
|
+
// @todo be lazier about actually requesting the file
|
|
143
|
+
const buffer = await this._requestFile(path, 'buffer');
|
|
144
|
+
// we don't initially have file sizes
|
|
145
|
+
stats.size = buffer.length;
|
|
146
|
+
stats.fileData = buffer;
|
|
147
|
+
return new NoSyncFile(this, path, flags, Stats.clone(stats), buffer);
|
|
148
|
+
default:
|
|
149
|
+
throw new ApiError(ErrorCode.EINVAL, 'Invalid FileMode object.');
|
|
165
150
|
}
|
|
166
|
-
}
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
throw ApiError.EPERM(path);
|
|
154
|
+
}
|
|
167
155
|
}
|
|
168
|
-
readdir(path, cred) {
|
|
169
|
-
return
|
|
170
|
-
return this.readdirSync(path, cred);
|
|
171
|
-
});
|
|
156
|
+
async readdir(path, cred) {
|
|
157
|
+
return this.readdirSync(path, cred);
|
|
172
158
|
}
|
|
173
159
|
/**
|
|
174
160
|
* We have the entire file as a buffer; optimize readFile.
|
|
175
161
|
*/
|
|
176
|
-
readFile(fname,
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
}
|
|
186
|
-
return fdBuff.toString(encoding);
|
|
187
|
-
}
|
|
188
|
-
finally {
|
|
189
|
-
yield fd.close();
|
|
190
|
-
}
|
|
191
|
-
});
|
|
162
|
+
async readFile(fname, flag, cred) {
|
|
163
|
+
// Get file.
|
|
164
|
+
const fd = await this.open(fname, flag, 0o644, cred);
|
|
165
|
+
try {
|
|
166
|
+
return fd.getBuffer();
|
|
167
|
+
}
|
|
168
|
+
finally {
|
|
169
|
+
await fd.close();
|
|
170
|
+
}
|
|
192
171
|
}
|
|
193
172
|
_getHTTPPath(filePath) {
|
|
194
173
|
if (filePath.charAt(0) === '/') {
|
|
@@ -197,13 +176,13 @@ export class HTTPRequest extends BaseFileSystem {
|
|
|
197
176
|
return this.prefixUrl + filePath;
|
|
198
177
|
}
|
|
199
178
|
_requestFile(p, type) {
|
|
200
|
-
return
|
|
179
|
+
return fetchFile(this._getHTTPPath(p), type);
|
|
201
180
|
}
|
|
202
181
|
/**
|
|
203
182
|
* Only requests the HEAD content, for the file size.
|
|
204
183
|
*/
|
|
205
184
|
_requestFileSize(path) {
|
|
206
|
-
return
|
|
185
|
+
return fetchFileSize(this._getHTTPPath(path));
|
|
207
186
|
}
|
|
208
187
|
}
|
|
209
188
|
_a = HTTPRequest;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/// <reference types="node" resolution-mode="require"/>
|
|
2
1
|
import { AsyncKeyValueROTransaction, AsyncKeyValueRWTransaction, AsyncKeyValueStore, AsyncKeyValueFileSystem } from '@zenfs/core/backends/AsyncStore.js';
|
|
3
2
|
import { type BackendOptions } from '@zenfs/core/backends/backend.js';
|
|
4
3
|
/**
|
|
@@ -8,7 +7,7 @@ export declare class IndexedDBROTransaction implements AsyncKeyValueROTransactio
|
|
|
8
7
|
tx: IDBTransaction;
|
|
9
8
|
store: IDBObjectStore;
|
|
10
9
|
constructor(tx: IDBTransaction, store: IDBObjectStore);
|
|
11
|
-
get(key: string): Promise<
|
|
10
|
+
get(key: string): Promise<Uint8Array>;
|
|
12
11
|
}
|
|
13
12
|
/**
|
|
14
13
|
* @hidden
|
|
@@ -18,7 +17,7 @@ export declare class IndexedDBRWTransaction extends IndexedDBROTransaction imple
|
|
|
18
17
|
/**
|
|
19
18
|
* @todo return false when add has a key conflict (no error)
|
|
20
19
|
*/
|
|
21
|
-
put(key: string, data:
|
|
20
|
+
put(key: string, data: Uint8Array, overwrite: boolean): Promise<boolean>;
|
|
22
21
|
del(key: string): Promise<void>;
|
|
23
22
|
commit(): Promise<void>;
|
|
24
23
|
abort(): Promise<void>;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
var _a;
|
|
2
2
|
import { AsyncKeyValueFileSystem } from '@zenfs/core/backends/AsyncStore.js';
|
|
3
3
|
import { ApiError, ErrorCode } from '@zenfs/core/ApiError.js';
|
|
4
|
-
import { Buffer } from 'buffer';
|
|
5
4
|
import { CreateBackend } from '@zenfs/core/backends/backend.js';
|
|
6
5
|
/**
|
|
7
6
|
* Converts a DOMException or a DOMError from an IndexedDB event into a
|
|
@@ -53,8 +52,8 @@ export class IndexedDBROTransaction {
|
|
|
53
52
|
resolve(result);
|
|
54
53
|
}
|
|
55
54
|
else {
|
|
56
|
-
// IDB data is stored as an
|
|
57
|
-
resolve(
|
|
55
|
+
// IDB data is stored as an ArrayUint8Array
|
|
56
|
+
resolve(Uint8Array.from(result));
|
|
58
57
|
}
|
|
59
58
|
};
|
|
60
59
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/// <reference types="node" resolution-mode="require"/>
|
|
2
1
|
import { SyncKeyValueStore, SimpleSyncStore, SyncKeyValueFileSystem, SyncKeyValueRWTransaction } from '@zenfs/core/backends/SyncStore.js';
|
|
3
2
|
import { type BackendOptions } from '@zenfs/core/backends/backend.js';
|
|
4
3
|
/**
|
|
@@ -10,8 +9,8 @@ export declare class StorageStore implements SyncKeyValueStore, SimpleSyncStore
|
|
|
10
9
|
constructor(_storage: Storage);
|
|
11
10
|
clear(): void;
|
|
12
11
|
beginTransaction(type: string): SyncKeyValueRWTransaction;
|
|
13
|
-
get(key: string):
|
|
14
|
-
put(key: string, data:
|
|
12
|
+
get(key: string): Uint8Array | undefined;
|
|
13
|
+
put(key: string, data: Uint8Array, overwrite: boolean): boolean;
|
|
15
14
|
del(key: string): void;
|
|
16
15
|
}
|
|
17
16
|
export declare namespace StorageFileSystem {
|
package/dist/backends/Storage.js
CHANGED
|
@@ -2,7 +2,7 @@ var _a;
|
|
|
2
2
|
import { SyncKeyValueFileSystem, SimpleSyncRWTransaction } from '@zenfs/core/backends/SyncStore.js';
|
|
3
3
|
import { ApiError, ErrorCode } from '@zenfs/core/ApiError.js';
|
|
4
4
|
import { CreateBackend } from '@zenfs/core/backends/backend.js';
|
|
5
|
-
import {
|
|
5
|
+
import { encode } from '@zenfs/core/utils.js';
|
|
6
6
|
/**
|
|
7
7
|
* A synchronous key-value store backed by Storage.
|
|
8
8
|
*/
|
|
@@ -25,7 +25,7 @@ export class StorageStore {
|
|
|
25
25
|
if (typeof data != 'string') {
|
|
26
26
|
return;
|
|
27
27
|
}
|
|
28
|
-
return
|
|
28
|
+
return encode(data);
|
|
29
29
|
}
|
|
30
30
|
put(key, data, overwrite) {
|
|
31
31
|
try {
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
import { BaseFileSystem, FileContents, FileSystemMetadata } from '@zenfs/core/filesystem.js';
|
|
1
|
+
import { BaseFileSystem, FileSystemMetadata } from '@zenfs/core/filesystem.js';
|
|
3
2
|
import { File, FileFlag } from '@zenfs/core/file.js';
|
|
4
3
|
import { Stats } from '@zenfs/core/stats.js';
|
|
5
4
|
import { Cred } from '@zenfs/core/cred.js';
|
|
@@ -66,9 +65,9 @@ export declare class WorkerFS extends BaseFileSystem {
|
|
|
66
65
|
exists(p: string, cred: Cred): Promise<boolean>;
|
|
67
66
|
realpath(p: string, cred: Cred): Promise<string>;
|
|
68
67
|
truncate(p: string, len: number, cred: Cred): Promise<void>;
|
|
69
|
-
readFile(fname: string,
|
|
70
|
-
writeFile(fname: string, data:
|
|
71
|
-
appendFile(fname: string, data:
|
|
68
|
+
readFile(fname: string, flag: FileFlag, cred: Cred): Promise<Uint8Array>;
|
|
69
|
+
writeFile(fname: string, data: Uint8Array, flag: FileFlag, mode: number, cred: Cred): Promise<void>;
|
|
70
|
+
appendFile(fname: string, data: Uint8Array, flag: FileFlag, mode: number, cred: Cred): Promise<void>;
|
|
72
71
|
chmod(p: string, mode: number, cred: Cred): Promise<void>;
|
|
73
72
|
chown(p: string, new_uid: number, new_gid: number, cred: Cred): Promise<void>;
|
|
74
73
|
utimes(p: string, atime: Date, mtime: Date, cred: Cred): Promise<void>;
|
package/dist/backends/Worker.js
CHANGED
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
1
|
var _a;
|
|
11
2
|
import { BaseFileSystem } from '@zenfs/core/filesystem.js';
|
|
12
3
|
import { ApiError, ErrorCode } from '@zenfs/core/ApiError.js';
|
|
@@ -75,19 +66,22 @@ export class WorkerFS extends BaseFileSystem {
|
|
|
75
66
|
};
|
|
76
67
|
}
|
|
77
68
|
get metadata() {
|
|
78
|
-
return
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
69
|
+
return {
|
|
70
|
+
...super.metadata,
|
|
71
|
+
...this._metadata,
|
|
72
|
+
name: _a.Name,
|
|
73
|
+
synchronous: false,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
async _rpc(method, ...args) {
|
|
77
|
+
return new Promise((resolve, reject) => {
|
|
78
|
+
const id = this._currentID++;
|
|
79
|
+
this._requests.set(id, { resolve, reject });
|
|
80
|
+
this._worker.postMessage({
|
|
81
|
+
isBFS: true,
|
|
82
|
+
id,
|
|
83
|
+
method,
|
|
84
|
+
args,
|
|
91
85
|
});
|
|
92
86
|
});
|
|
93
87
|
}
|
|
@@ -121,14 +115,14 @@ export class WorkerFS extends BaseFileSystem {
|
|
|
121
115
|
truncate(p, len, cred) {
|
|
122
116
|
return this._rpc('truncate', p, len, cred);
|
|
123
117
|
}
|
|
124
|
-
readFile(fname,
|
|
125
|
-
return this._rpc('readFile', fname,
|
|
118
|
+
readFile(fname, flag, cred) {
|
|
119
|
+
return this._rpc('readFile', fname, flag, cred);
|
|
126
120
|
}
|
|
127
|
-
writeFile(fname, data,
|
|
128
|
-
return this._rpc('writeFile', fname, data,
|
|
121
|
+
writeFile(fname, data, flag, mode, cred) {
|
|
122
|
+
return this._rpc('writeFile', fname, data, flag, mode, cred);
|
|
129
123
|
}
|
|
130
|
-
appendFile(fname, data,
|
|
131
|
-
return this._rpc('appendFile', fname, data,
|
|
124
|
+
appendFile(fname, data, flag, mode, cred) {
|
|
125
|
+
return this._rpc('appendFile', fname, data, flag, mode, cred);
|
|
132
126
|
}
|
|
133
127
|
chmod(p, mode, cred) {
|
|
134
128
|
return this._rpc('chmod', p, mode, cred);
|
|
@@ -159,11 +153,11 @@ WorkerFS.Options = {
|
|
|
159
153
|
worker: {
|
|
160
154
|
type: 'object',
|
|
161
155
|
description: 'The target worker that you want to connect to, or the current worker if in a worker context.',
|
|
162
|
-
validator
|
|
156
|
+
validator(worker) {
|
|
163
157
|
// Check for a `postMessage` function.
|
|
164
|
-
if (typeof
|
|
165
|
-
throw new ApiError(ErrorCode.EINVAL,
|
|
158
|
+
if (typeof worker?.postMessage != 'function') {
|
|
159
|
+
throw new ApiError(ErrorCode.EINVAL, 'option must be a Web Worker instance.');
|
|
166
160
|
}
|
|
167
|
-
}
|
|
161
|
+
},
|
|
168
162
|
},
|
|
169
163
|
};
|