@zenfs/core 0.0.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/README.md +293 -0
- package/dist/ApiError.d.ts +86 -0
- package/dist/ApiError.js +135 -0
- package/dist/backends/AsyncMirror.d.ts +102 -0
- package/dist/backends/AsyncMirror.js +252 -0
- package/dist/backends/AsyncStore.d.ts +166 -0
- package/dist/backends/AsyncStore.js +620 -0
- package/dist/backends/FolderAdapter.d.ts +52 -0
- package/dist/backends/FolderAdapter.js +184 -0
- package/dist/backends/InMemory.d.ts +25 -0
- package/dist/backends/InMemory.js +46 -0
- package/dist/backends/Locked.d.ts +64 -0
- package/dist/backends/Locked.js +302 -0
- package/dist/backends/OverlayFS.d.ts +120 -0
- package/dist/backends/OverlayFS.js +749 -0
- package/dist/backends/SyncStore.d.ts +223 -0
- package/dist/backends/SyncStore.js +479 -0
- package/dist/backends/backend.d.ts +73 -0
- package/dist/backends/backend.js +14 -0
- package/dist/backends/index.d.ts +11 -0
- package/dist/backends/index.js +15 -0
- package/dist/browser.min.js +12 -0
- package/dist/browser.min.js.map +7 -0
- package/dist/cred.d.ts +14 -0
- package/dist/cred.js +15 -0
- package/dist/emulation/callbacks.d.ts +382 -0
- package/dist/emulation/callbacks.js +422 -0
- package/dist/emulation/constants.d.ts +101 -0
- package/dist/emulation/constants.js +110 -0
- package/dist/emulation/fs.d.ts +7 -0
- package/dist/emulation/fs.js +5 -0
- package/dist/emulation/index.d.ts +5 -0
- package/dist/emulation/index.js +7 -0
- package/dist/emulation/promises.d.ts +309 -0
- package/dist/emulation/promises.js +521 -0
- package/dist/emulation/shared.d.ts +62 -0
- package/dist/emulation/shared.js +192 -0
- package/dist/emulation/sync.d.ts +278 -0
- package/dist/emulation/sync.js +392 -0
- package/dist/file.d.ts +449 -0
- package/dist/file.js +576 -0
- package/dist/filesystem.d.ts +367 -0
- package/dist/filesystem.js +542 -0
- package/dist/index.d.ts +78 -0
- package/dist/index.js +113 -0
- package/dist/inode.d.ts +51 -0
- package/dist/inode.js +112 -0
- package/dist/mutex.d.ts +12 -0
- package/dist/mutex.js +48 -0
- package/dist/stats.d.ts +98 -0
- package/dist/stats.js +226 -0
- package/dist/utils.d.ts +52 -0
- package/dist/utils.js +261 -0
- package/license.md +122 -0
- package/package.json +61 -0
|
@@ -0,0 +1,252 @@
|
|
|
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
|
+
var _a;
|
|
11
|
+
import { SynchronousFileSystem } from '../filesystem';
|
|
12
|
+
import { ApiError, ErrorCode } from '../ApiError';
|
|
13
|
+
import { FileFlag, PreloadFile } from '../file';
|
|
14
|
+
import * as path from 'path';
|
|
15
|
+
import { Cred } from '../cred';
|
|
16
|
+
import { CreateBackend } from './backend';
|
|
17
|
+
/**
|
|
18
|
+
* We define our own file to interpose on syncSync() for mirroring purposes.
|
|
19
|
+
*/
|
|
20
|
+
class MirrorFile extends PreloadFile {
|
|
21
|
+
constructor(fs, path, flag, stat, data) {
|
|
22
|
+
super(fs, path, flag, stat, data);
|
|
23
|
+
}
|
|
24
|
+
syncSync() {
|
|
25
|
+
if (this.isDirty()) {
|
|
26
|
+
this._fs._syncSync(this);
|
|
27
|
+
this.resetDirty();
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
closeSync() {
|
|
31
|
+
this.syncSync();
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* AsyncMirrorFS mirrors a synchronous filesystem into an asynchronous filesystem
|
|
36
|
+
* by:
|
|
37
|
+
*
|
|
38
|
+
* * Performing operations over the in-memory copy, while asynchronously pipelining them
|
|
39
|
+
* to the backing store.
|
|
40
|
+
* * During application loading, the contents of the async file system can be reloaded into
|
|
41
|
+
* the synchronous store, if desired.
|
|
42
|
+
*
|
|
43
|
+
* The two stores will be kept in sync. The most common use-case is to pair a synchronous
|
|
44
|
+
* in-memory filesystem with an asynchronous backing store.
|
|
45
|
+
*
|
|
46
|
+
* Example: Mirroring an IndexedDB file system to an in memory file system. Now, you can use
|
|
47
|
+
* IndexedDB synchronously.
|
|
48
|
+
*
|
|
49
|
+
* ```javascript
|
|
50
|
+
* ZenFS.configure({
|
|
51
|
+
* fs: "AsyncMirror",
|
|
52
|
+
* options: {
|
|
53
|
+
* sync: { fs: "InMemory" },
|
|
54
|
+
* async: { fs: "IndexedDB" }
|
|
55
|
+
* }
|
|
56
|
+
* }, function(e) {
|
|
57
|
+
* // ZenFS is initialized and ready-to-use!
|
|
58
|
+
* });
|
|
59
|
+
* ```
|
|
60
|
+
*
|
|
61
|
+
* Or, alternatively:
|
|
62
|
+
*
|
|
63
|
+
* ```javascript
|
|
64
|
+
* ZenFS.Backend.IndexedDB.Create(function(e, idbfs) {
|
|
65
|
+
* ZenFS.Backend.InMemory.Create(function(e, inMemory) {
|
|
66
|
+
* ZenFS.Backend.AsyncMirror({
|
|
67
|
+
* sync: inMemory, async: idbfs
|
|
68
|
+
* }, function(e, mirrored) {
|
|
69
|
+
* ZenFS.initialize(mirrored);
|
|
70
|
+
* });
|
|
71
|
+
* });
|
|
72
|
+
* });
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
export class AsyncMirror extends SynchronousFileSystem {
|
|
76
|
+
static isAvailable() {
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
*
|
|
81
|
+
* Mirrors the synchronous file system into the asynchronous file system.
|
|
82
|
+
*
|
|
83
|
+
* @param sync The synchronous file system to mirror the asynchronous file system to.
|
|
84
|
+
* @param async The asynchronous file system to mirror.
|
|
85
|
+
*/
|
|
86
|
+
constructor({ sync, async }) {
|
|
87
|
+
super();
|
|
88
|
+
/**
|
|
89
|
+
* Queue of pending asynchronous operations.
|
|
90
|
+
*/
|
|
91
|
+
this._queue = [];
|
|
92
|
+
this._queueRunning = false;
|
|
93
|
+
this._isInitialized = false;
|
|
94
|
+
this._initializeCallbacks = [];
|
|
95
|
+
this._sync = sync;
|
|
96
|
+
this._async = async;
|
|
97
|
+
this._ready = this._initialize();
|
|
98
|
+
}
|
|
99
|
+
get metadata() {
|
|
100
|
+
return Object.assign(Object.assign({}, super.metadata), { name: AsyncMirror.Name, synchronous: true, supportsProperties: this._sync.metadata.supportsProperties && this._async.metadata.supportsProperties });
|
|
101
|
+
}
|
|
102
|
+
_syncSync(fd) {
|
|
103
|
+
const stats = fd.getStats();
|
|
104
|
+
this._sync.writeFileSync(fd.getPath(), fd.getBuffer(), null, FileFlag.getFileFlag('w'), stats.mode, stats.getCred(0, 0));
|
|
105
|
+
this.enqueueOp({
|
|
106
|
+
apiMethod: 'writeFile',
|
|
107
|
+
arguments: [fd.getPath(), fd.getBuffer(), null, fd.getFlag(), stats.mode, stats.getCred(0, 0)],
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
renameSync(oldPath, newPath, cred) {
|
|
111
|
+
this._sync.renameSync(oldPath, newPath, cred);
|
|
112
|
+
this.enqueueOp({
|
|
113
|
+
apiMethod: 'rename',
|
|
114
|
+
arguments: [oldPath, newPath, cred],
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
statSync(p, cred) {
|
|
118
|
+
return this._sync.statSync(p, cred);
|
|
119
|
+
}
|
|
120
|
+
openSync(p, flag, mode, cred) {
|
|
121
|
+
// Sanity check: Is this open/close permitted?
|
|
122
|
+
const fd = this._sync.openSync(p, flag, mode, cred);
|
|
123
|
+
fd.closeSync();
|
|
124
|
+
return new MirrorFile(this, p, flag, this._sync.statSync(p, cred), this._sync.readFileSync(p, null, FileFlag.getFileFlag('r'), cred));
|
|
125
|
+
}
|
|
126
|
+
unlinkSync(p, cred) {
|
|
127
|
+
this._sync.unlinkSync(p, cred);
|
|
128
|
+
this.enqueueOp({
|
|
129
|
+
apiMethod: 'unlink',
|
|
130
|
+
arguments: [p, cred],
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
rmdirSync(p, cred) {
|
|
134
|
+
this._sync.rmdirSync(p, cred);
|
|
135
|
+
this.enqueueOp({
|
|
136
|
+
apiMethod: 'rmdir',
|
|
137
|
+
arguments: [p, cred],
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
mkdirSync(p, mode, cred) {
|
|
141
|
+
this._sync.mkdirSync(p, mode, cred);
|
|
142
|
+
this.enqueueOp({
|
|
143
|
+
apiMethod: 'mkdir',
|
|
144
|
+
arguments: [p, mode, cred],
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
readdirSync(p, cred) {
|
|
148
|
+
return this._sync.readdirSync(p, cred);
|
|
149
|
+
}
|
|
150
|
+
existsSync(p, cred) {
|
|
151
|
+
return this._sync.existsSync(p, cred);
|
|
152
|
+
}
|
|
153
|
+
chmodSync(p, mode, cred) {
|
|
154
|
+
this._sync.chmodSync(p, mode, cred);
|
|
155
|
+
this.enqueueOp({
|
|
156
|
+
apiMethod: 'chmod',
|
|
157
|
+
arguments: [p, mode, cred],
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
chownSync(p, new_uid, new_gid, cred) {
|
|
161
|
+
this._sync.chownSync(p, new_uid, new_gid, cred);
|
|
162
|
+
this.enqueueOp({
|
|
163
|
+
apiMethod: 'chown',
|
|
164
|
+
arguments: [p, new_uid, new_gid, cred],
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
utimesSync(p, atime, mtime, cred) {
|
|
168
|
+
this._sync.utimesSync(p, atime, mtime, cred);
|
|
169
|
+
this.enqueueOp({
|
|
170
|
+
apiMethod: 'utimes',
|
|
171
|
+
arguments: [p, atime, mtime, cred],
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Called once to load up files from async storage into sync storage.
|
|
176
|
+
*/
|
|
177
|
+
_initialize() {
|
|
178
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
179
|
+
if (!this._isInitialized) {
|
|
180
|
+
// First call triggers initialization, the rest wait.
|
|
181
|
+
const copyDirectory = (p, mode) => __awaiter(this, void 0, void 0, function* () {
|
|
182
|
+
if (p !== '/') {
|
|
183
|
+
const stats = yield this._async.stat(p, Cred.Root);
|
|
184
|
+
this._sync.mkdirSync(p, mode, stats.getCred());
|
|
185
|
+
}
|
|
186
|
+
const files = yield this._async.readdir(p, Cred.Root);
|
|
187
|
+
for (const file of files) {
|
|
188
|
+
yield copyItem(path.join(p, file));
|
|
189
|
+
}
|
|
190
|
+
}), copyFile = (p, mode) => __awaiter(this, void 0, void 0, function* () {
|
|
191
|
+
const data = yield this._async.readFile(p, null, FileFlag.getFileFlag('r'), Cred.Root);
|
|
192
|
+
this._sync.writeFileSync(p, data, null, FileFlag.getFileFlag('w'), mode, Cred.Root);
|
|
193
|
+
}), copyItem = (p) => __awaiter(this, void 0, void 0, function* () {
|
|
194
|
+
const stats = yield this._async.stat(p, Cred.Root);
|
|
195
|
+
if (stats.isDirectory()) {
|
|
196
|
+
yield copyDirectory(p, stats.mode);
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
yield copyFile(p, stats.mode);
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
try {
|
|
203
|
+
yield copyDirectory('/', 0);
|
|
204
|
+
this._isInitialized = true;
|
|
205
|
+
}
|
|
206
|
+
catch (e) {
|
|
207
|
+
this._isInitialized = false;
|
|
208
|
+
throw e;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
return this;
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
enqueueOp(op) {
|
|
215
|
+
this._queue.push(op);
|
|
216
|
+
if (!this._queueRunning) {
|
|
217
|
+
this._queueRunning = true;
|
|
218
|
+
const doNextOp = (err) => {
|
|
219
|
+
if (err) {
|
|
220
|
+
throw new Error(`WARNING: File system has desynchronized. Received following error: ${err}\n$`);
|
|
221
|
+
}
|
|
222
|
+
if (this._queue.length > 0) {
|
|
223
|
+
const op = this._queue.shift();
|
|
224
|
+
op.arguments.push(doNextOp);
|
|
225
|
+
this._async[op.apiMethod].apply(this._async, op.arguments);
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
this._queueRunning = false;
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
doNextOp();
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
_a = AsyncMirror;
|
|
236
|
+
AsyncMirror.Name = 'AsyncMirror';
|
|
237
|
+
AsyncMirror.Create = CreateBackend.bind(_a);
|
|
238
|
+
AsyncMirror.Options = {
|
|
239
|
+
sync: {
|
|
240
|
+
type: 'object',
|
|
241
|
+
description: 'The synchronous file system to mirror the asynchronous file system to.',
|
|
242
|
+
validator: (v) => __awaiter(void 0, void 0, void 0, function* () {
|
|
243
|
+
if (!(v === null || v === void 0 ? void 0 : v.metadata.synchronous)) {
|
|
244
|
+
throw new ApiError(ErrorCode.EINVAL, `'sync' option must be a file system that supports synchronous operations`);
|
|
245
|
+
}
|
|
246
|
+
}),
|
|
247
|
+
},
|
|
248
|
+
async: {
|
|
249
|
+
type: 'object',
|
|
250
|
+
description: 'The asynchronous file system to mirror.',
|
|
251
|
+
},
|
|
252
|
+
};
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { Cred } from '../cred';
|
|
3
|
+
import { PreloadFile, File, FileFlag } from '../file';
|
|
4
|
+
import { BaseFileSystem } from '../filesystem';
|
|
5
|
+
import { Stats } from '../stats';
|
|
6
|
+
/**
|
|
7
|
+
* Represents an *asynchronous* key-value store.
|
|
8
|
+
*/
|
|
9
|
+
export interface AsyncKeyValueStore {
|
|
10
|
+
/**
|
|
11
|
+
* The name of the key-value store.
|
|
12
|
+
*/
|
|
13
|
+
name(): string;
|
|
14
|
+
/**
|
|
15
|
+
* Empties the key-value store completely.
|
|
16
|
+
*/
|
|
17
|
+
clear(): Promise<void>;
|
|
18
|
+
/**
|
|
19
|
+
* Begins a read-write transaction.
|
|
20
|
+
*/
|
|
21
|
+
beginTransaction(type: 'readwrite'): AsyncKeyValueRWTransaction;
|
|
22
|
+
/**
|
|
23
|
+
* Begins a read-only transaction.
|
|
24
|
+
*/
|
|
25
|
+
beginTransaction(type: 'readonly'): AsyncKeyValueROTransaction;
|
|
26
|
+
beginTransaction(type: string): AsyncKeyValueROTransaction;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Represents an asynchronous read-only transaction.
|
|
30
|
+
*/
|
|
31
|
+
export interface AsyncKeyValueROTransaction {
|
|
32
|
+
/**
|
|
33
|
+
* Retrieves the data at the given key.
|
|
34
|
+
* @param key The key to look under for data.
|
|
35
|
+
*/
|
|
36
|
+
get(key: string): Promise<Buffer>;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Represents an asynchronous read-write transaction.
|
|
40
|
+
*/
|
|
41
|
+
export interface AsyncKeyValueRWTransaction extends AsyncKeyValueROTransaction {
|
|
42
|
+
/**
|
|
43
|
+
* Adds the data to the store under the given key. Overwrites any existing
|
|
44
|
+
* data.
|
|
45
|
+
* @param key The key to add the data under.
|
|
46
|
+
* @param data The data to add to the store.
|
|
47
|
+
* @param overwrite If 'true', overwrite any existing data. If 'false',
|
|
48
|
+
* avoids writing the data if the key exists.
|
|
49
|
+
*/
|
|
50
|
+
put(key: string, data: Buffer, overwrite: boolean): Promise<boolean>;
|
|
51
|
+
/**
|
|
52
|
+
* Deletes the data at the given key.
|
|
53
|
+
* @param key The key to delete from the store.
|
|
54
|
+
*/
|
|
55
|
+
del(key: string): Promise<void>;
|
|
56
|
+
/**
|
|
57
|
+
* Commits the transaction.
|
|
58
|
+
*/
|
|
59
|
+
commit(): Promise<void>;
|
|
60
|
+
/**
|
|
61
|
+
* Aborts and rolls back the transaction.
|
|
62
|
+
*/
|
|
63
|
+
abort(): Promise<void>;
|
|
64
|
+
}
|
|
65
|
+
export declare class AsyncKeyValueFile extends PreloadFile<AsyncKeyValueFileSystem> implements File {
|
|
66
|
+
constructor(_fs: AsyncKeyValueFileSystem, _path: string, _flag: FileFlag, _stat: Stats, contents?: Buffer);
|
|
67
|
+
sync(): Promise<void>;
|
|
68
|
+
close(): Promise<void>;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* An "Asynchronous key-value file system". Stores data to/retrieves data from
|
|
72
|
+
* an underlying asynchronous key-value store.
|
|
73
|
+
*/
|
|
74
|
+
export declare class AsyncKeyValueFileSystem extends BaseFileSystem {
|
|
75
|
+
static isAvailable(): boolean;
|
|
76
|
+
protected store: AsyncKeyValueStore;
|
|
77
|
+
private _cache;
|
|
78
|
+
constructor(cacheSize: number);
|
|
79
|
+
/**
|
|
80
|
+
* Initializes the file system. Typically called by subclasses' async
|
|
81
|
+
* constructors.
|
|
82
|
+
*/
|
|
83
|
+
init(store: AsyncKeyValueStore): Promise<void>;
|
|
84
|
+
getName(): string;
|
|
85
|
+
isReadOnly(): boolean;
|
|
86
|
+
supportsSymlinks(): boolean;
|
|
87
|
+
supportsProps(): boolean;
|
|
88
|
+
supportsSynch(): boolean;
|
|
89
|
+
/**
|
|
90
|
+
* Delete all contents stored in the file system.
|
|
91
|
+
*/
|
|
92
|
+
empty(): Promise<void>;
|
|
93
|
+
access(p: string, mode: number, cred: Cred): Promise<void>;
|
|
94
|
+
/**
|
|
95
|
+
* @todo Make rename compatible with the cache.
|
|
96
|
+
*/
|
|
97
|
+
rename(oldPath: string, newPath: string, cred: Cred): Promise<void>;
|
|
98
|
+
stat(p: string, cred: Cred): Promise<Stats>;
|
|
99
|
+
createFile(p: string, flag: FileFlag, mode: number, cred: Cred): Promise<File>;
|
|
100
|
+
openFile(p: string, flag: FileFlag, cred: Cred): Promise<File>;
|
|
101
|
+
unlink(p: string, cred: Cred): Promise<void>;
|
|
102
|
+
rmdir(p: string, cred: Cred): Promise<void>;
|
|
103
|
+
mkdir(p: string, mode: number, cred: Cred): Promise<void>;
|
|
104
|
+
readdir(p: string, cred: Cred): Promise<string[]>;
|
|
105
|
+
chmod(p: string, mode: number, cred: Cred): Promise<void>;
|
|
106
|
+
chown(p: string, new_uid: number, new_gid: number, cred: Cred): Promise<void>;
|
|
107
|
+
_sync(p: string, data: Buffer, stats: Stats): Promise<void>;
|
|
108
|
+
/**
|
|
109
|
+
* Checks if the root directory exists. Creates it if it doesn't.
|
|
110
|
+
*/
|
|
111
|
+
private makeRootDirectory;
|
|
112
|
+
/**
|
|
113
|
+
* Helper function for findINode.
|
|
114
|
+
* @param parent The parent directory of the file we are attempting to find.
|
|
115
|
+
* @param filename The filename of the inode we are attempting to find, minus
|
|
116
|
+
* the parent.
|
|
117
|
+
*/
|
|
118
|
+
private _findINode;
|
|
119
|
+
/**
|
|
120
|
+
* Finds the Inode of the given path.
|
|
121
|
+
* @param p The path to look up.
|
|
122
|
+
* @todo memoize/cache
|
|
123
|
+
*/
|
|
124
|
+
private findINode;
|
|
125
|
+
/**
|
|
126
|
+
* Given the ID of a node, retrieves the corresponding Inode.
|
|
127
|
+
* @param tx The transaction to use.
|
|
128
|
+
* @param p The corresponding path to the file (used for error messages).
|
|
129
|
+
* @param id The ID to look up.
|
|
130
|
+
*/
|
|
131
|
+
private getINode;
|
|
132
|
+
/**
|
|
133
|
+
* Given the Inode of a directory, retrieves the corresponding directory
|
|
134
|
+
* listing.
|
|
135
|
+
*/
|
|
136
|
+
private getDirListing;
|
|
137
|
+
/**
|
|
138
|
+
* Adds a new node under a random ID. Retries 5 times before giving up in
|
|
139
|
+
* the exceedingly unlikely chance that we try to reuse a random GUID.
|
|
140
|
+
*/
|
|
141
|
+
private addNewNode;
|
|
142
|
+
/**
|
|
143
|
+
* Commits a new file (well, a FILE or a DIRECTORY) to the file system with
|
|
144
|
+
* the given mode.
|
|
145
|
+
* Note: This will commit the transaction.
|
|
146
|
+
* @param p The path to the new file.
|
|
147
|
+
* @param type The type of the new file.
|
|
148
|
+
* @param mode The mode to create the new file with.
|
|
149
|
+
* @param cred The UID/GID to create the file with
|
|
150
|
+
* @param data The data to store at the file's data node.
|
|
151
|
+
*/
|
|
152
|
+
private commitNewFile;
|
|
153
|
+
/**
|
|
154
|
+
* Remove all traces of the given path from the file system.
|
|
155
|
+
* @param p The path to remove from the file system.
|
|
156
|
+
* @param isDir Does the path belong to a directory, or a file?
|
|
157
|
+
* @todo Update mtime.
|
|
158
|
+
*/
|
|
159
|
+
/**
|
|
160
|
+
* Remove all traces of the given path from the file system.
|
|
161
|
+
* @param p The path to remove from the file system.
|
|
162
|
+
* @param isDir Does the path belong to a directory, or a file?
|
|
163
|
+
* @todo Update mtime.
|
|
164
|
+
*/
|
|
165
|
+
private removeEntry;
|
|
166
|
+
}
|