@zenfs/dom 0.0.6 → 0.1.1
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/FileSystemAccess.d.ts +55 -0
- package/dist/FileSystemAccess.js +216 -0
- package/dist/IndexedDB.d.ts +56 -0
- package/dist/IndexedDB.js +201 -0
- package/dist/Storage.d.ts +29 -0
- package/dist/Storage.js +68 -0
- package/dist/browser.min.js +1 -3
- package/dist/browser.min.js.map +4 -4
- package/dist/index.d.ts +3 -5
- package/dist/index.js +3 -5
- package/package.json +7 -7
- package/readme.md +12 -20
- package/dist/backends/FileSystemAccess.d.ts +0 -44
- package/dist/backends/FileSystemAccess.js +0 -208
- package/dist/backends/HTTPRequest.d.ts +0 -85
- package/dist/backends/HTTPRequest.js +0 -202
- package/dist/backends/IndexedDB.d.ts +0 -63
- package/dist/backends/IndexedDB.js +0 -221
- package/dist/backends/Storage.d.ts +0 -39
- package/dist/backends/Storage.js +0 -75
- package/dist/backends/Worker.d.ts +0 -78
- package/dist/backends/Worker.js +0 -163
- package/dist/fetch.d.ts +0 -16
- package/dist/fetch.js +0 -37
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import { AsyncKeyValueROTransaction, AsyncKeyValueRWTransaction, AsyncKeyValueStore, AsyncKeyValueFileSystem } from '@zenfs/core/backends/AsyncStore.js';
|
|
2
|
-
import { type BackendOptions } from '@zenfs/core/backends/backend.js';
|
|
3
|
-
/**
|
|
4
|
-
* @hidden
|
|
5
|
-
*/
|
|
6
|
-
export declare class IndexedDBROTransaction implements AsyncKeyValueROTransaction {
|
|
7
|
-
tx: IDBTransaction;
|
|
8
|
-
store: IDBObjectStore;
|
|
9
|
-
constructor(tx: IDBTransaction, store: IDBObjectStore);
|
|
10
|
-
get(key: string): Promise<Uint8Array>;
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* @hidden
|
|
14
|
-
*/
|
|
15
|
-
export declare class IndexedDBRWTransaction extends IndexedDBROTransaction implements AsyncKeyValueRWTransaction, AsyncKeyValueROTransaction {
|
|
16
|
-
constructor(tx: IDBTransaction, store: IDBObjectStore);
|
|
17
|
-
/**
|
|
18
|
-
* @todo return false when add has a key conflict (no error)
|
|
19
|
-
*/
|
|
20
|
-
put(key: string, data: Uint8Array, overwrite: boolean): Promise<boolean>;
|
|
21
|
-
del(key: string): Promise<void>;
|
|
22
|
-
commit(): Promise<void>;
|
|
23
|
-
abort(): Promise<void>;
|
|
24
|
-
}
|
|
25
|
-
export declare class IndexedDBStore implements AsyncKeyValueStore {
|
|
26
|
-
private db;
|
|
27
|
-
private storeName;
|
|
28
|
-
static Create(storeName: string, indexedDB: IDBFactory): Promise<IndexedDBStore>;
|
|
29
|
-
constructor(db: IDBDatabase, storeName: string);
|
|
30
|
-
name(): string;
|
|
31
|
-
clear(): Promise<void>;
|
|
32
|
-
beginTransaction(type: 'readonly'): AsyncKeyValueROTransaction;
|
|
33
|
-
beginTransaction(type: 'readwrite'): AsyncKeyValueRWTransaction;
|
|
34
|
-
}
|
|
35
|
-
export declare namespace IndexedDBFileSystem {
|
|
36
|
-
/**
|
|
37
|
-
* Configuration options for the IndexedDB file system.
|
|
38
|
-
*/
|
|
39
|
-
interface Options {
|
|
40
|
-
/**
|
|
41
|
-
* The name of this file system. You can have multiple IndexedDB file systems operating at once, but each must have a different name.
|
|
42
|
-
*/
|
|
43
|
-
storeName?: string;
|
|
44
|
-
/**
|
|
45
|
-
* The size of the inode cache. Defaults to 100. A size of 0 or below disables caching.
|
|
46
|
-
*/
|
|
47
|
-
cacheSize?: number;
|
|
48
|
-
/**
|
|
49
|
-
* The IDBFactory to use. Defaults to `globalThis.indexedDB`.
|
|
50
|
-
*/
|
|
51
|
-
idbFactory?: IDBFactory;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* A file system that uses the IndexedDB key value file system.
|
|
56
|
-
*/
|
|
57
|
-
export declare class IndexedDBFileSystem extends AsyncKeyValueFileSystem {
|
|
58
|
-
static readonly Name = "IndexedDB";
|
|
59
|
-
static Create: any;
|
|
60
|
-
static readonly Options: BackendOptions;
|
|
61
|
-
static isAvailable(idbFactory?: IDBFactory): boolean;
|
|
62
|
-
constructor({ cacheSize, storeName, idbFactory }: IndexedDBFileSystem.Options);
|
|
63
|
-
}
|
|
@@ -1,221 +0,0 @@
|
|
|
1
|
-
var _a;
|
|
2
|
-
import { AsyncKeyValueFileSystem } from '@zenfs/core/backends/AsyncStore.js';
|
|
3
|
-
import { ApiError, ErrorCode } from '@zenfs/core/ApiError.js';
|
|
4
|
-
import { CreateBackend } from '@zenfs/core/backends/backend.js';
|
|
5
|
-
/**
|
|
6
|
-
* Converts a DOMException or a DOMError from an IndexedDB event into a
|
|
7
|
-
* standardized ZenFS API error.
|
|
8
|
-
* @hidden
|
|
9
|
-
*/
|
|
10
|
-
function convertError(e, message = e.toString()) {
|
|
11
|
-
switch (e.name) {
|
|
12
|
-
case 'NotFoundError':
|
|
13
|
-
return new ApiError(ErrorCode.ENOENT, message);
|
|
14
|
-
case 'QuotaExceededError':
|
|
15
|
-
return new ApiError(ErrorCode.ENOSPC, message);
|
|
16
|
-
default:
|
|
17
|
-
// The rest do not seem to map cleanly to standard error codes.
|
|
18
|
-
return new ApiError(ErrorCode.EIO, message);
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Produces a new onerror handler for IDB. Our errors are always fatal, so we
|
|
23
|
-
* handle them generically: Call the user-supplied callback with a translated
|
|
24
|
-
* version of the error, and let the error bubble up.
|
|
25
|
-
* @hidden
|
|
26
|
-
*/
|
|
27
|
-
function onErrorHandler(cb, code = ErrorCode.EIO, message = null) {
|
|
28
|
-
return function (e) {
|
|
29
|
-
// Prevent the error from canceling the transaction.
|
|
30
|
-
e.preventDefault();
|
|
31
|
-
cb(new ApiError(code, message !== null ? message : undefined));
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* @hidden
|
|
36
|
-
*/
|
|
37
|
-
export class IndexedDBROTransaction {
|
|
38
|
-
constructor(tx, store) {
|
|
39
|
-
this.tx = tx;
|
|
40
|
-
this.store = store;
|
|
41
|
-
}
|
|
42
|
-
get(key) {
|
|
43
|
-
return new Promise((resolve, reject) => {
|
|
44
|
-
try {
|
|
45
|
-
const r = this.store.get(key);
|
|
46
|
-
r.onerror = onErrorHandler(reject);
|
|
47
|
-
r.onsuccess = event => {
|
|
48
|
-
// IDB returns the value 'undefined' when you try to get keys that
|
|
49
|
-
// don't exist. The caller expects this behavior.
|
|
50
|
-
const result = event.target.result;
|
|
51
|
-
if (result === undefined) {
|
|
52
|
-
resolve(result);
|
|
53
|
-
}
|
|
54
|
-
else {
|
|
55
|
-
// IDB data is stored as an ArrayUint8Array
|
|
56
|
-
resolve(Uint8Array.from(result));
|
|
57
|
-
}
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
catch (e) {
|
|
61
|
-
reject(convertError(e));
|
|
62
|
-
}
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* @hidden
|
|
68
|
-
*/
|
|
69
|
-
export class IndexedDBRWTransaction extends IndexedDBROTransaction {
|
|
70
|
-
constructor(tx, store) {
|
|
71
|
-
super(tx, store);
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* @todo return false when add has a key conflict (no error)
|
|
75
|
-
*/
|
|
76
|
-
put(key, data, overwrite) {
|
|
77
|
-
return new Promise((resolve, reject) => {
|
|
78
|
-
try {
|
|
79
|
-
const r = overwrite ? this.store.put(data, key) : this.store.add(data, key);
|
|
80
|
-
r.onerror = onErrorHandler(reject);
|
|
81
|
-
r.onsuccess = () => {
|
|
82
|
-
resolve(true);
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
catch (e) {
|
|
86
|
-
reject(convertError(e));
|
|
87
|
-
}
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
del(key) {
|
|
91
|
-
return new Promise((resolve, reject) => {
|
|
92
|
-
try {
|
|
93
|
-
const r = this.store.delete(key);
|
|
94
|
-
r.onerror = onErrorHandler(reject);
|
|
95
|
-
r.onsuccess = () => {
|
|
96
|
-
resolve();
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
catch (e) {
|
|
100
|
-
reject(convertError(e));
|
|
101
|
-
}
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
commit() {
|
|
105
|
-
return new Promise(resolve => {
|
|
106
|
-
// Return to the event loop to commit the transaction.
|
|
107
|
-
setTimeout(resolve, 0);
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
|
-
abort() {
|
|
111
|
-
return new Promise((resolve, reject) => {
|
|
112
|
-
try {
|
|
113
|
-
this.tx.abort();
|
|
114
|
-
resolve();
|
|
115
|
-
}
|
|
116
|
-
catch (e) {
|
|
117
|
-
reject(convertError(e));
|
|
118
|
-
}
|
|
119
|
-
});
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
export class IndexedDBStore {
|
|
123
|
-
static Create(storeName, indexedDB) {
|
|
124
|
-
return new Promise((resolve, reject) => {
|
|
125
|
-
const openReq = indexedDB.open(storeName, 1);
|
|
126
|
-
openReq.onupgradeneeded = event => {
|
|
127
|
-
const db = event.target.result;
|
|
128
|
-
// Huh. This should never happen; we're at version 1. Why does another
|
|
129
|
-
// database exist?
|
|
130
|
-
if (db.objectStoreNames.contains(storeName)) {
|
|
131
|
-
db.deleteObjectStore(storeName);
|
|
132
|
-
}
|
|
133
|
-
db.createObjectStore(storeName);
|
|
134
|
-
};
|
|
135
|
-
openReq.onsuccess = event => {
|
|
136
|
-
resolve(new IndexedDBStore(event.target.result, storeName));
|
|
137
|
-
};
|
|
138
|
-
openReq.onerror = onErrorHandler(reject, ErrorCode.EACCES);
|
|
139
|
-
});
|
|
140
|
-
}
|
|
141
|
-
constructor(db, storeName) {
|
|
142
|
-
this.db = db;
|
|
143
|
-
this.storeName = storeName;
|
|
144
|
-
}
|
|
145
|
-
name() {
|
|
146
|
-
return IndexedDBFileSystem.Name + ' - ' + this.storeName;
|
|
147
|
-
}
|
|
148
|
-
clear() {
|
|
149
|
-
return new Promise((resolve, reject) => {
|
|
150
|
-
try {
|
|
151
|
-
const tx = this.db.transaction(this.storeName, 'readwrite'), objectStore = tx.objectStore(this.storeName), r = objectStore.clear();
|
|
152
|
-
r.onsuccess = () => {
|
|
153
|
-
// Use setTimeout to commit transaction.
|
|
154
|
-
setTimeout(resolve, 0);
|
|
155
|
-
};
|
|
156
|
-
r.onerror = onErrorHandler(reject);
|
|
157
|
-
}
|
|
158
|
-
catch (e) {
|
|
159
|
-
reject(convertError(e));
|
|
160
|
-
}
|
|
161
|
-
});
|
|
162
|
-
}
|
|
163
|
-
beginTransaction(type = 'readonly') {
|
|
164
|
-
const tx = this.db.transaction(this.storeName, type), objectStore = tx.objectStore(this.storeName);
|
|
165
|
-
if (type === 'readwrite') {
|
|
166
|
-
return new IndexedDBRWTransaction(tx, objectStore);
|
|
167
|
-
}
|
|
168
|
-
else if (type === 'readonly') {
|
|
169
|
-
return new IndexedDBROTransaction(tx, objectStore);
|
|
170
|
-
}
|
|
171
|
-
else {
|
|
172
|
-
throw new ApiError(ErrorCode.EINVAL, 'Invalid transaction type.');
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
/**
|
|
177
|
-
* A file system that uses the IndexedDB key value file system.
|
|
178
|
-
*/
|
|
179
|
-
export class IndexedDBFileSystem extends AsyncKeyValueFileSystem {
|
|
180
|
-
static isAvailable(idbFactory = globalThis.indexedDB) {
|
|
181
|
-
try {
|
|
182
|
-
if (!(idbFactory instanceof IDBFactory)) {
|
|
183
|
-
return false;
|
|
184
|
-
}
|
|
185
|
-
const req = idbFactory.open('__zenfs_test__');
|
|
186
|
-
if (!req) {
|
|
187
|
-
return false;
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
catch (e) {
|
|
191
|
-
return false;
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
constructor({ cacheSize = 100, storeName = 'zenfs', idbFactory = globalThis.indexedDB }) {
|
|
195
|
-
super(cacheSize);
|
|
196
|
-
this._ready = IndexedDBStore.Create(storeName, idbFactory).then(store => {
|
|
197
|
-
this.init(store);
|
|
198
|
-
return this;
|
|
199
|
-
});
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
_a = IndexedDBFileSystem;
|
|
203
|
-
IndexedDBFileSystem.Name = 'IndexedDB';
|
|
204
|
-
IndexedDBFileSystem.Create = CreateBackend.bind(_a);
|
|
205
|
-
IndexedDBFileSystem.Options = {
|
|
206
|
-
storeName: {
|
|
207
|
-
type: 'string',
|
|
208
|
-
optional: true,
|
|
209
|
-
description: 'The name of this file system. You can have multiple IndexedDB file systems operating at once, but each must have a different name.',
|
|
210
|
-
},
|
|
211
|
-
cacheSize: {
|
|
212
|
-
type: 'number',
|
|
213
|
-
optional: true,
|
|
214
|
-
description: 'The size of the inode cache. Defaults to 100. A size of 0 or below disables caching.',
|
|
215
|
-
},
|
|
216
|
-
idbFactory: {
|
|
217
|
-
type: 'object',
|
|
218
|
-
optional: true,
|
|
219
|
-
description: 'The IDBFactory to use. Defaults to globalThis.indexedDB.',
|
|
220
|
-
},
|
|
221
|
-
};
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { SyncKeyValueStore, SimpleSyncStore, SyncKeyValueFileSystem, SyncKeyValueRWTransaction } from '@zenfs/core/backends/SyncStore.js';
|
|
2
|
-
import { type BackendOptions } from '@zenfs/core/backends/backend.js';
|
|
3
|
-
/**
|
|
4
|
-
* A synchronous key-value store backed by Storage.
|
|
5
|
-
*/
|
|
6
|
-
export declare class StorageStore implements SyncKeyValueStore, SimpleSyncStore {
|
|
7
|
-
protected _storage: Storage;
|
|
8
|
-
name(): string;
|
|
9
|
-
constructor(_storage: Storage);
|
|
10
|
-
clear(): void;
|
|
11
|
-
beginTransaction(type: string): SyncKeyValueRWTransaction;
|
|
12
|
-
get(key: string): Uint8Array | undefined;
|
|
13
|
-
put(key: string, data: Uint8Array, overwrite: boolean): boolean;
|
|
14
|
-
del(key: string): void;
|
|
15
|
-
}
|
|
16
|
-
export declare namespace StorageFileSystem {
|
|
17
|
-
/**
|
|
18
|
-
* Options to pass to the StorageFileSystem
|
|
19
|
-
*/
|
|
20
|
-
interface Options {
|
|
21
|
-
/**
|
|
22
|
-
* The Storage to use. Defaults to globalThis.localStorage.
|
|
23
|
-
*/
|
|
24
|
-
storage: Storage;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* A synchronous file system backed by a `Storage` (e.g. localStorage).
|
|
29
|
-
*/
|
|
30
|
-
export declare class StorageFileSystem extends SyncKeyValueFileSystem {
|
|
31
|
-
static readonly Name = "Storage";
|
|
32
|
-
static Create: any;
|
|
33
|
-
static readonly Options: BackendOptions;
|
|
34
|
-
static isAvailable(storage?: Storage): boolean;
|
|
35
|
-
/**
|
|
36
|
-
* Creates a new Storage file system using the contents of `Storage`.
|
|
37
|
-
*/
|
|
38
|
-
constructor({ storage }: StorageFileSystem.Options);
|
|
39
|
-
}
|
package/dist/backends/Storage.js
DELETED
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
var _a;
|
|
2
|
-
import { SyncKeyValueFileSystem, SimpleSyncRWTransaction } from '@zenfs/core/backends/SyncStore.js';
|
|
3
|
-
import { ApiError, ErrorCode } from '@zenfs/core/ApiError.js';
|
|
4
|
-
import { CreateBackend } from '@zenfs/core/backends/backend.js';
|
|
5
|
-
import { decode, encode } from '@zenfs/core/utils.js';
|
|
6
|
-
/**
|
|
7
|
-
* A synchronous key-value store backed by Storage.
|
|
8
|
-
*/
|
|
9
|
-
export class StorageStore {
|
|
10
|
-
name() {
|
|
11
|
-
return StorageFileSystem.Name;
|
|
12
|
-
}
|
|
13
|
-
constructor(_storage) {
|
|
14
|
-
this._storage = _storage;
|
|
15
|
-
}
|
|
16
|
-
clear() {
|
|
17
|
-
this._storage.clear();
|
|
18
|
-
}
|
|
19
|
-
beginTransaction(type) {
|
|
20
|
-
// No need to differentiate.
|
|
21
|
-
return new SimpleSyncRWTransaction(this);
|
|
22
|
-
}
|
|
23
|
-
get(key) {
|
|
24
|
-
const data = this._storage.getItem(key);
|
|
25
|
-
if (typeof data != 'string') {
|
|
26
|
-
return;
|
|
27
|
-
}
|
|
28
|
-
return encode(data);
|
|
29
|
-
}
|
|
30
|
-
put(key, data, overwrite) {
|
|
31
|
-
try {
|
|
32
|
-
if (!overwrite && this._storage.getItem(key) !== null) {
|
|
33
|
-
// Don't want to overwrite the key!
|
|
34
|
-
return false;
|
|
35
|
-
}
|
|
36
|
-
this._storage.setItem(key, decode(data));
|
|
37
|
-
return true;
|
|
38
|
-
}
|
|
39
|
-
catch (e) {
|
|
40
|
-
throw new ApiError(ErrorCode.ENOSPC, 'Storage is full.');
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
del(key) {
|
|
44
|
-
try {
|
|
45
|
-
this._storage.removeItem(key);
|
|
46
|
-
}
|
|
47
|
-
catch (e) {
|
|
48
|
-
throw new ApiError(ErrorCode.EIO, 'Unable to delete key ' + key + ': ' + e);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* A synchronous file system backed by a `Storage` (e.g. localStorage).
|
|
54
|
-
*/
|
|
55
|
-
export class StorageFileSystem extends SyncKeyValueFileSystem {
|
|
56
|
-
static isAvailable(storage = globalThis.localStorage) {
|
|
57
|
-
return storage instanceof Storage;
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* Creates a new Storage file system using the contents of `Storage`.
|
|
61
|
-
*/
|
|
62
|
-
constructor({ storage = globalThis.localStorage }) {
|
|
63
|
-
super({ store: new StorageStore(storage) });
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
_a = StorageFileSystem;
|
|
67
|
-
StorageFileSystem.Name = 'Storage';
|
|
68
|
-
StorageFileSystem.Create = CreateBackend.bind(_a);
|
|
69
|
-
StorageFileSystem.Options = {
|
|
70
|
-
storage: {
|
|
71
|
-
type: 'object',
|
|
72
|
-
optional: true,
|
|
73
|
-
description: 'The Storage to use. Defaults to globalThis.localStorage.',
|
|
74
|
-
},
|
|
75
|
-
};
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import { BaseFileSystem, FileSystemMetadata } from '@zenfs/core/filesystem.js';
|
|
2
|
-
import { File, FileFlag } from '@zenfs/core/file.js';
|
|
3
|
-
import { Stats } from '@zenfs/core/stats.js';
|
|
4
|
-
import { Cred } from '@zenfs/core/cred.js';
|
|
5
|
-
import { type BackendOptions } from '@zenfs/core/backends/backend.js';
|
|
6
|
-
export declare namespace WorkerFS {
|
|
7
|
-
interface Options {
|
|
8
|
-
/**
|
|
9
|
-
* The target worker that you want to connect to, or the current worker if in a worker context.
|
|
10
|
-
*/
|
|
11
|
-
worker: Worker;
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* WorkerFS lets you access a ZenFS instance that is running in a different
|
|
16
|
-
* JavaScript context (e.g. access ZenFS in one of your WebWorkers, or
|
|
17
|
-
* access ZenFS running on the main page from a WebWorker).
|
|
18
|
-
*
|
|
19
|
-
* For example, to have a WebWorker access files in the main browser thread,
|
|
20
|
-
* do the following:
|
|
21
|
-
*
|
|
22
|
-
* MAIN BROWSER THREAD:
|
|
23
|
-
*
|
|
24
|
-
* ```javascript
|
|
25
|
-
* // Listen for remote file system requests.
|
|
26
|
-
* ZenFS.Backend.WorkerFS.attachRemoteListener(webWorkerObject);
|
|
27
|
-
* ```
|
|
28
|
-
*
|
|
29
|
-
* WEBWORKER THREAD:
|
|
30
|
-
*
|
|
31
|
-
* ```javascript
|
|
32
|
-
* // Set the remote file system as the root file system.
|
|
33
|
-
* ZenFS.configure({ fs: "WorkerFS", options: { worker: self }}, function(e) {
|
|
34
|
-
* // Ready!
|
|
35
|
-
* });
|
|
36
|
-
* ```
|
|
37
|
-
*
|
|
38
|
-
* Note that synchronous operations are not permitted on the WorkerFS, regardless
|
|
39
|
-
* of the configuration option of the remote FS.
|
|
40
|
-
*/
|
|
41
|
-
export declare class WorkerFS extends BaseFileSystem {
|
|
42
|
-
static readonly Name = "WorkerFS";
|
|
43
|
-
static Create: any;
|
|
44
|
-
static readonly Options: BackendOptions;
|
|
45
|
-
static isAvailable(): boolean;
|
|
46
|
-
private _worker;
|
|
47
|
-
private _currentID;
|
|
48
|
-
private _requests;
|
|
49
|
-
private _isInitialized;
|
|
50
|
-
private _metadata;
|
|
51
|
-
/**
|
|
52
|
-
* Constructs a new WorkerFS instance that connects with ZenFS running on
|
|
53
|
-
* the specified worker.
|
|
54
|
-
*/
|
|
55
|
-
constructor({ worker }: WorkerFS.Options);
|
|
56
|
-
get metadata(): FileSystemMetadata;
|
|
57
|
-
private _rpc;
|
|
58
|
-
rename(oldPath: string, newPath: string, cred: Cred): Promise<void>;
|
|
59
|
-
stat(p: string, cred: Cred): Promise<Stats>;
|
|
60
|
-
open(p: string, flag: FileFlag, mode: number, cred: Cred): Promise<File>;
|
|
61
|
-
unlink(p: string, cred: Cred): Promise<void>;
|
|
62
|
-
rmdir(p: string, cred: Cred): Promise<void>;
|
|
63
|
-
mkdir(p: string, mode: number, cred: Cred): Promise<void>;
|
|
64
|
-
readdir(p: string, cred: Cred): Promise<string[]>;
|
|
65
|
-
exists(p: string, cred: Cred): Promise<boolean>;
|
|
66
|
-
realpath(p: string, cred: Cred): Promise<string>;
|
|
67
|
-
truncate(p: string, len: number, cred: Cred): Promise<void>;
|
|
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>;
|
|
71
|
-
chmod(p: string, mode: number, cred: Cred): Promise<void>;
|
|
72
|
-
chown(p: string, new_uid: number, new_gid: number, cred: Cred): Promise<void>;
|
|
73
|
-
utimes(p: string, atime: Date, mtime: Date, cred: Cred): Promise<void>;
|
|
74
|
-
link(srcpath: string, dstpath: string, cred: Cred): Promise<void>;
|
|
75
|
-
symlink(srcpath: string, dstpath: string, type: string, cred: Cred): Promise<void>;
|
|
76
|
-
readlink(p: string, cred: Cred): Promise<string>;
|
|
77
|
-
syncClose(method: string, fd: File): Promise<void>;
|
|
78
|
-
}
|
package/dist/backends/Worker.js
DELETED
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
var _a;
|
|
2
|
-
import { BaseFileSystem } from '@zenfs/core/filesystem.js';
|
|
3
|
-
import { ApiError, ErrorCode } from '@zenfs/core/ApiError.js';
|
|
4
|
-
import { CreateBackend } from '@zenfs/core/backends/backend.js';
|
|
5
|
-
function isRPCMessage(arg) {
|
|
6
|
-
return typeof arg == 'object' && 'isBFS' in arg && !!arg.isBFS;
|
|
7
|
-
}
|
|
8
|
-
/**
|
|
9
|
-
* WorkerFS lets you access a ZenFS instance that is running in a different
|
|
10
|
-
* JavaScript context (e.g. access ZenFS in one of your WebWorkers, or
|
|
11
|
-
* access ZenFS running on the main page from a WebWorker).
|
|
12
|
-
*
|
|
13
|
-
* For example, to have a WebWorker access files in the main browser thread,
|
|
14
|
-
* do the following:
|
|
15
|
-
*
|
|
16
|
-
* MAIN BROWSER THREAD:
|
|
17
|
-
*
|
|
18
|
-
* ```javascript
|
|
19
|
-
* // Listen for remote file system requests.
|
|
20
|
-
* ZenFS.Backend.WorkerFS.attachRemoteListener(webWorkerObject);
|
|
21
|
-
* ```
|
|
22
|
-
*
|
|
23
|
-
* WEBWORKER THREAD:
|
|
24
|
-
*
|
|
25
|
-
* ```javascript
|
|
26
|
-
* // Set the remote file system as the root file system.
|
|
27
|
-
* ZenFS.configure({ fs: "WorkerFS", options: { worker: self }}, function(e) {
|
|
28
|
-
* // Ready!
|
|
29
|
-
* });
|
|
30
|
-
* ```
|
|
31
|
-
*
|
|
32
|
-
* Note that synchronous operations are not permitted on the WorkerFS, regardless
|
|
33
|
-
* of the configuration option of the remote FS.
|
|
34
|
-
*/
|
|
35
|
-
export class WorkerFS extends BaseFileSystem {
|
|
36
|
-
static isAvailable() {
|
|
37
|
-
return typeof importScripts !== 'undefined' || typeof Worker !== 'undefined';
|
|
38
|
-
}
|
|
39
|
-
/**
|
|
40
|
-
* Constructs a new WorkerFS instance that connects with ZenFS running on
|
|
41
|
-
* the specified worker.
|
|
42
|
-
*/
|
|
43
|
-
constructor({ worker }) {
|
|
44
|
-
super();
|
|
45
|
-
this._currentID = 0;
|
|
46
|
-
this._requests = new Map();
|
|
47
|
-
this._isInitialized = false;
|
|
48
|
-
this._worker = worker;
|
|
49
|
-
this._worker.onmessage = (event) => {
|
|
50
|
-
if (!isRPCMessage(event.data)) {
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
const { id, method, value } = event.data;
|
|
54
|
-
if (method === 'metadata') {
|
|
55
|
-
this._metadata = value;
|
|
56
|
-
this._isInitialized = true;
|
|
57
|
-
return;
|
|
58
|
-
}
|
|
59
|
-
const { resolve, reject } = this._requests.get(id);
|
|
60
|
-
this._requests.delete(id);
|
|
61
|
-
if (value instanceof Error || value instanceof ApiError) {
|
|
62
|
-
reject(value);
|
|
63
|
-
return;
|
|
64
|
-
}
|
|
65
|
-
resolve(value);
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
get metadata() {
|
|
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,
|
|
85
|
-
});
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
rename(oldPath, newPath, cred) {
|
|
89
|
-
return this._rpc('rename', oldPath, newPath, cred);
|
|
90
|
-
}
|
|
91
|
-
stat(p, cred) {
|
|
92
|
-
return this._rpc('stat', p, cred);
|
|
93
|
-
}
|
|
94
|
-
open(p, flag, mode, cred) {
|
|
95
|
-
return this._rpc('open', p, flag, mode, cred);
|
|
96
|
-
}
|
|
97
|
-
unlink(p, cred) {
|
|
98
|
-
return this._rpc('unlink', p, cred);
|
|
99
|
-
}
|
|
100
|
-
rmdir(p, cred) {
|
|
101
|
-
return this._rpc('rmdir', p, cred);
|
|
102
|
-
}
|
|
103
|
-
mkdir(p, mode, cred) {
|
|
104
|
-
return this._rpc('mkdir', p, mode, cred);
|
|
105
|
-
}
|
|
106
|
-
readdir(p, cred) {
|
|
107
|
-
return this._rpc('readdir', p, cred);
|
|
108
|
-
}
|
|
109
|
-
exists(p, cred) {
|
|
110
|
-
return this._rpc('exists', p, cred);
|
|
111
|
-
}
|
|
112
|
-
realpath(p, cred) {
|
|
113
|
-
return this._rpc('realpath', p, cred);
|
|
114
|
-
}
|
|
115
|
-
truncate(p, len, cred) {
|
|
116
|
-
return this._rpc('truncate', p, len, cred);
|
|
117
|
-
}
|
|
118
|
-
readFile(fname, flag, cred) {
|
|
119
|
-
return this._rpc('readFile', fname, flag, cred);
|
|
120
|
-
}
|
|
121
|
-
writeFile(fname, data, flag, mode, cred) {
|
|
122
|
-
return this._rpc('writeFile', fname, data, flag, mode, cred);
|
|
123
|
-
}
|
|
124
|
-
appendFile(fname, data, flag, mode, cred) {
|
|
125
|
-
return this._rpc('appendFile', fname, data, flag, mode, cred);
|
|
126
|
-
}
|
|
127
|
-
chmod(p, mode, cred) {
|
|
128
|
-
return this._rpc('chmod', p, mode, cred);
|
|
129
|
-
}
|
|
130
|
-
chown(p, new_uid, new_gid, cred) {
|
|
131
|
-
return this._rpc('chown', p, new_uid, new_gid, cred);
|
|
132
|
-
}
|
|
133
|
-
utimes(p, atime, mtime, cred) {
|
|
134
|
-
return this._rpc('utimes', p, atime, mtime, cred);
|
|
135
|
-
}
|
|
136
|
-
link(srcpath, dstpath, cred) {
|
|
137
|
-
return this._rpc('link', srcpath, dstpath, cred);
|
|
138
|
-
}
|
|
139
|
-
symlink(srcpath, dstpath, type, cred) {
|
|
140
|
-
return this._rpc('symlink', srcpath, dstpath, type, cred);
|
|
141
|
-
}
|
|
142
|
-
readlink(p, cred) {
|
|
143
|
-
return this._rpc('readlink', p, cred);
|
|
144
|
-
}
|
|
145
|
-
syncClose(method, fd) {
|
|
146
|
-
return this._rpc('syncClose', method, fd);
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
_a = WorkerFS;
|
|
150
|
-
WorkerFS.Name = 'WorkerFS';
|
|
151
|
-
WorkerFS.Create = CreateBackend.bind(_a);
|
|
152
|
-
WorkerFS.Options = {
|
|
153
|
-
worker: {
|
|
154
|
-
type: 'object',
|
|
155
|
-
description: 'The target worker that you want to connect to, or the current worker if in a worker context.',
|
|
156
|
-
validator(worker) {
|
|
157
|
-
// Check for a `postMessage` function.
|
|
158
|
-
if (typeof worker?.postMessage != 'function') {
|
|
159
|
-
throw new ApiError(ErrorCode.EINVAL, 'option must be a Web Worker instance.');
|
|
160
|
-
}
|
|
161
|
-
},
|
|
162
|
-
},
|
|
163
|
-
};
|
package/dist/fetch.d.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
export declare const fetchIsAvailable: boolean;
|
|
2
|
-
/**
|
|
3
|
-
* Asynchronously download a file as a buffer or a JSON object.
|
|
4
|
-
* Note that the third function signature with a non-specialized type is
|
|
5
|
-
* invalid, but TypeScript requires it when you specialize string arguments to
|
|
6
|
-
* constants.
|
|
7
|
-
* @hidden
|
|
8
|
-
*/
|
|
9
|
-
export declare function fetchFile(p: string, type: 'buffer'): Promise<Uint8Array>;
|
|
10
|
-
export declare function fetchFile(p: string, type: 'json'): Promise<any>;
|
|
11
|
-
export declare function fetchFile(p: string, type: 'buffer' | 'json'): Promise<any>;
|
|
12
|
-
/**
|
|
13
|
-
* Asynchronously retrieves the size of the given file in bytes.
|
|
14
|
-
* @hidden
|
|
15
|
-
*/
|
|
16
|
-
export declare function fetchFileSize(p: string): Promise<number>;
|
package/dist/fetch.js
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Contains utility methods for network I/O (using fetch)
|
|
3
|
-
*/
|
|
4
|
-
import { ApiError, ErrorCode } from '@zenfs/core/ApiError.js';
|
|
5
|
-
export const fetchIsAvailable = typeof fetch !== 'undefined' && fetch !== null;
|
|
6
|
-
/**
|
|
7
|
-
* @hidden
|
|
8
|
-
*/
|
|
9
|
-
function convertError(e) {
|
|
10
|
-
throw new ApiError(ErrorCode.EIO, e.message);
|
|
11
|
-
}
|
|
12
|
-
export async function fetchFile(p, type) {
|
|
13
|
-
const response = await fetch(p).catch(convertError);
|
|
14
|
-
if (!response.ok) {
|
|
15
|
-
throw new ApiError(ErrorCode.EIO, `fetch error: response returned code ${response.status}`);
|
|
16
|
-
}
|
|
17
|
-
switch (type) {
|
|
18
|
-
case 'buffer':
|
|
19
|
-
const arrayBuffer = await response.arrayBuffer().catch(convertError);
|
|
20
|
-
return new Uint8Array(arrayBuffer);
|
|
21
|
-
case 'json':
|
|
22
|
-
return response.json().catch(convertError);
|
|
23
|
-
default:
|
|
24
|
-
throw new ApiError(ErrorCode.EINVAL, 'Invalid download type: ' + type);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Asynchronously retrieves the size of the given file in bytes.
|
|
29
|
-
* @hidden
|
|
30
|
-
*/
|
|
31
|
-
export async function fetchFileSize(p) {
|
|
32
|
-
const response = await fetch(p, { method: 'HEAD' }).catch(convertError);
|
|
33
|
-
if (!response.ok) {
|
|
34
|
-
throw new ApiError(ErrorCode.EIO, `fetch HEAD error: response returned code ${response.status}`);
|
|
35
|
-
}
|
|
36
|
-
return parseInt(response.headers.get('Content-Length') || '-1', 10);
|
|
37
|
-
}
|