@zenfs/core 0.0.12 → 0.2.0

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.
Files changed (54) hide show
  1. package/dist/ApiError.d.ts +52 -15
  2. package/dist/ApiError.js +77 -50
  3. package/dist/FileIndex.d.ts +32 -35
  4. package/dist/FileIndex.js +93 -109
  5. package/dist/backends/AsyncMirror.d.ts +42 -43
  6. package/dist/backends/AsyncMirror.js +154 -147
  7. package/dist/backends/AsyncStore.d.ts +29 -28
  8. package/dist/backends/AsyncStore.js +375 -482
  9. package/dist/backends/FolderAdapter.js +8 -19
  10. package/dist/backends/InMemory.d.ts +16 -13
  11. package/dist/backends/InMemory.js +29 -14
  12. package/dist/backends/Locked.d.ts +8 -28
  13. package/dist/backends/Locked.js +74 -224
  14. package/dist/backends/OverlayFS.d.ts +26 -34
  15. package/dist/backends/OverlayFS.js +303 -511
  16. package/dist/backends/SyncStore.d.ts +54 -72
  17. package/dist/backends/SyncStore.js +159 -161
  18. package/dist/backends/backend.d.ts +45 -29
  19. package/dist/backends/backend.js +83 -13
  20. package/dist/backends/index.d.ts +6 -7
  21. package/dist/backends/index.js +5 -6
  22. package/dist/browser.min.js +21 -6
  23. package/dist/browser.min.js.map +4 -4
  24. package/dist/emulation/callbacks.d.ts +119 -113
  25. package/dist/emulation/callbacks.js +129 -92
  26. package/dist/emulation/constants.js +1 -1
  27. package/dist/emulation/dir.d.ts +55 -0
  28. package/dist/emulation/dir.js +104 -0
  29. package/dist/emulation/fs.d.ts +1 -2
  30. package/dist/emulation/fs.js +0 -1
  31. package/dist/emulation/index.d.ts +3 -0
  32. package/dist/emulation/index.js +3 -0
  33. package/dist/emulation/promises.d.ts +265 -145
  34. package/dist/emulation/promises.js +526 -383
  35. package/dist/emulation/shared.d.ts +20 -6
  36. package/dist/emulation/shared.js +22 -23
  37. package/dist/emulation/streams.d.ts +102 -0
  38. package/dist/emulation/streams.js +55 -0
  39. package/dist/emulation/sync.d.ts +98 -69
  40. package/dist/emulation/sync.js +280 -133
  41. package/dist/file.d.ts +175 -173
  42. package/dist/file.js +257 -273
  43. package/dist/filesystem.d.ts +71 -244
  44. package/dist/filesystem.js +67 -472
  45. package/dist/index.d.ts +7 -44
  46. package/dist/index.js +22 -75
  47. package/dist/inode.d.ts +37 -28
  48. package/dist/inode.js +123 -65
  49. package/dist/stats.d.ts +91 -36
  50. package/dist/stats.js +138 -110
  51. package/dist/utils.d.ts +26 -13
  52. package/dist/utils.js +79 -107
  53. package/package.json +7 -4
  54. package/readme.md +2 -40
@@ -1,19 +1,8 @@
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.js';
1
+ import { SyncFileSystem } from '../filesystem.js';
12
2
  import { ApiError, ErrorCode } from '../ApiError.js';
13
3
  import { FileFlag, PreloadFile } from '../file.js';
14
4
  import { join } from '../emulation/path.js';
15
5
  import { Cred } from '../cred.js';
16
- import { CreateBackend } from './backend.js';
17
6
  /**
18
7
  * We define our own file to interpose on syncSync() for mirroring purposes.
19
8
  */
@@ -21,12 +10,18 @@ class MirrorFile extends PreloadFile {
21
10
  constructor(fs, path, flag, stat, data) {
22
11
  super(fs, path, flag, stat, data);
23
12
  }
13
+ async sync() {
14
+ this.syncSync();
15
+ }
24
16
  syncSync() {
25
17
  if (this.isDirty()) {
26
- this._fs._syncSync(this);
18
+ this.fs.syncSync(this.path, this._buffer, this.stats);
27
19
  this.resetDirty();
28
20
  }
29
21
  }
22
+ async close() {
23
+ this.closeSync();
24
+ }
30
25
  closeSync() {
31
26
  this.syncSync();
32
27
  }
@@ -43,38 +38,11 @@ class MirrorFile extends PreloadFile {
43
38
  * The two stores will be kept in sync. The most common use-case is to pair a synchronous
44
39
  * in-memory filesystem with an asynchronous backing store.
45
40
  *
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
41
  */
75
- export class AsyncMirror extends SynchronousFileSystem {
76
- static isAvailable() {
77
- return true;
42
+ export class AsyncMirrorFS extends SyncFileSystem {
43
+ async ready() {
44
+ await this._ready;
45
+ return this;
78
46
  }
79
47
  /**
80
48
  *
@@ -91,25 +59,58 @@ export class AsyncMirror extends SynchronousFileSystem {
91
59
  this._queue = [];
92
60
  this._queueRunning = false;
93
61
  this._isInitialized = false;
94
- this._initializeCallbacks = [];
95
62
  this._sync = sync;
96
63
  this._async = async;
97
64
  this._ready = this._initialize();
98
65
  }
99
66
  get metadata() {
100
- return Object.assign(Object.assign({}, super.metadata), { name: AsyncMirror.Name, synchronous: true, supportsProperties: this._sync.metadata.supportsProperties && this._async.metadata.supportsProperties });
67
+ return {
68
+ ...super.metadata,
69
+ name: AsyncMirrorFS.name,
70
+ synchronous: true,
71
+ supportsProperties: this._sync.metadata.supportsProperties && this._async.metadata.supportsProperties,
72
+ };
101
73
  }
102
- _syncSync(fd) {
103
- const stats = fd.getStats();
104
- this._sync.writeFileSync(fd.getPath(), fd.getBuffer(), FileFlag.getFileFlag('w'), stats.mode, stats.getCred(0, 0));
105
- this.enqueueOp({
74
+ /*public _syncSync(file: PreloadFile<AsyncMirror>, cred: Cred) {
75
+ const sync = this._sync.openFileSync(file.path, FileFlag.FromString('w'), cred);
76
+ sync.writeSync(file.buffer);
77
+
78
+ this.enqueue({
106
79
  apiMethod: 'writeFile',
107
- arguments: [fd.getPath(), fd.getBuffer(), fd.getFlag(), stats.mode, stats.getCred(0, 0)],
80
+ arguments: [file.path, file.buffer, file.flag, file.stats.mode, cred],
81
+ });
82
+ }*/
83
+ syncSync(path, data, stats) {
84
+ this._sync.syncSync(path, data, stats);
85
+ this.enqueue({
86
+ apiMethod: 'sync',
87
+ arguments: [path, data, stats],
88
+ });
89
+ }
90
+ openFileSync(path, flag, cred) {
91
+ return this._sync.openFileSync(path, flag, cred);
92
+ }
93
+ createFileSync(path, flag, mode, cred) {
94
+ const file = this._sync.createFileSync(path, flag, mode, cred);
95
+ this.enqueue({
96
+ apiMethod: 'createFile',
97
+ arguments: [path, flag, mode, cred],
98
+ });
99
+ const stats = file.statSync();
100
+ const buffer = new Uint8Array(stats.size);
101
+ file.readSync(buffer);
102
+ return new MirrorFile(this, path, flag, stats, buffer);
103
+ }
104
+ linkSync(srcpath, dstpath, cred) {
105
+ this._sync.linkSync(srcpath, dstpath, cred);
106
+ this.enqueue({
107
+ apiMethod: 'link',
108
+ arguments: [srcpath, dstpath, cred],
108
109
  });
109
110
  }
110
111
  renameSync(oldPath, newPath, cred) {
111
112
  this._sync.renameSync(oldPath, newPath, cred);
112
- this.enqueueOp({
113
+ this.enqueue({
113
114
  apiMethod: 'rename',
114
115
  arguments: [oldPath, newPath, cred],
115
116
  });
@@ -117,29 +118,23 @@ export class AsyncMirror extends SynchronousFileSystem {
117
118
  statSync(p, cred) {
118
119
  return this._sync.statSync(p, cred);
119
120
  }
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, FileFlag.getFileFlag('r'), cred));
125
- }
126
121
  unlinkSync(p, cred) {
127
122
  this._sync.unlinkSync(p, cred);
128
- this.enqueueOp({
123
+ this.enqueue({
129
124
  apiMethod: 'unlink',
130
125
  arguments: [p, cred],
131
126
  });
132
127
  }
133
128
  rmdirSync(p, cred) {
134
129
  this._sync.rmdirSync(p, cred);
135
- this.enqueueOp({
130
+ this.enqueue({
136
131
  apiMethod: 'rmdir',
137
132
  arguments: [p, cred],
138
133
  });
139
134
  }
140
135
  mkdirSync(p, mode, cred) {
141
136
  this._sync.mkdirSync(p, mode, cred);
142
- this.enqueueOp({
137
+ this.enqueue({
143
138
  apiMethod: 'mkdir',
144
139
  arguments: [p, mode, cred],
145
140
  });
@@ -150,103 +145,115 @@ export class AsyncMirror extends SynchronousFileSystem {
150
145
  existsSync(p, cred) {
151
146
  return this._sync.existsSync(p, cred);
152
147
  }
153
- chmodSync(p, mode, cred) {
154
- this._sync.chmodSync(p, mode, cred);
155
- this.enqueueOp({
156
- apiMethod: 'chmod',
157
- arguments: [p, mode, cred],
158
- });
148
+ /**
149
+ * @internal
150
+ */
151
+ async crossCopyDirectory(p, mode) {
152
+ if (p !== '/') {
153
+ const stats = await this._async.stat(p, Cred.Root);
154
+ this._sync.mkdirSync(p, mode, stats.getCred());
155
+ }
156
+ const files = await this._async.readdir(p, Cred.Root);
157
+ for (const file of files) {
158
+ await this.crossCopy(join(p, file));
159
+ }
159
160
  }
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
- });
161
+ /**
162
+ * @internal
163
+ */
164
+ async crossCopyFile(p, mode) {
165
+ const asyncFile = await this._async.openFile(p, FileFlag.FromString('r'), Cred.Root);
166
+ const syncFile = this._sync.createFileSync(p, FileFlag.FromString('w'), mode, Cred.Root);
167
+ try {
168
+ const { size } = await asyncFile.stat();
169
+ const buffer = new Uint8Array(size);
170
+ await asyncFile.read(buffer);
171
+ syncFile.writeSync(buffer);
172
+ }
173
+ finally {
174
+ await asyncFile.close();
175
+ syncFile.closeSync();
176
+ }
166
177
  }
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
- });
178
+ /**
179
+ * @internal
180
+ */
181
+ async crossCopy(p) {
182
+ const stats = await this._async.stat(p, Cred.Root);
183
+ if (stats.isDirectory()) {
184
+ await this.crossCopyDirectory(p, stats.mode);
185
+ }
186
+ else {
187
+ await this.crossCopyFile(p, stats.mode);
188
+ }
173
189
  }
174
190
  /**
175
191
  * Called once to load up files from async storage into sync storage.
176
192
  */
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(join(p, file));
189
- }
190
- }), copyFile = (p, mode) => __awaiter(this, void 0, void 0, function* () {
191
- const data = yield this._async.readFile(p, FileFlag.getFileFlag('r'), Cred.Root);
192
- this._sync.writeFileSync(p, data, 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
- });
193
+ async _initialize() {
194
+ if (this._isInitialized) {
195
+ return;
196
+ }
197
+ try {
198
+ await this.crossCopy('/');
199
+ this._isInitialized = true;
200
+ }
201
+ catch (e) {
202
+ this._isInitialized = false;
203
+ throw e;
204
+ }
213
205
  }
214
- enqueueOp(op) {
206
+ /**
207
+ * @internal
208
+ */
209
+ async _next() {
210
+ if (this._queue.length == 0) {
211
+ this._queueRunning = false;
212
+ return;
213
+ }
214
+ const op = this._queue.shift();
215
+ try {
216
+ // @ts-expect-error 2556 (since ...args is not correctly picked up as being a tuple)
217
+ await this._async[op.apiMethod](...op.arguments);
218
+ }
219
+ catch (e) {
220
+ throw new ApiError(ErrorCode.EIO, 'AsyncMirror desync: ' + e);
221
+ }
222
+ await this._next();
223
+ }
224
+ /**
225
+ * @internal
226
+ */
227
+ enqueue(op) {
215
228
  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();
229
+ if (this._queueRunning) {
230
+ return;
232
231
  }
232
+ this._queueRunning = true;
233
+ this._next();
233
234
  }
234
235
  }
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
- }),
236
+ export const AsyncMirror = {
237
+ name: 'AsyncMirror',
238
+ options: {
239
+ sync: {
240
+ type: 'object',
241
+ description: 'The synchronous file system to mirror the asynchronous file system to.',
242
+ validator: async (v) => {
243
+ if (!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
+ },
253
+ isAvailable() {
254
+ return true;
247
255
  },
248
- async: {
249
- type: 'object',
250
- description: 'The asynchronous file system to mirror.',
256
+ create(options) {
257
+ return new AsyncMirrorFS(options);
251
258
  },
252
259
  };
@@ -1,15 +1,16 @@
1
1
  import { Cred } from '../cred.js';
2
2
  import { PreloadFile, File, FileFlag } from '../file.js';
3
- import { BaseFileSystem } from '../filesystem.js';
3
+ import { AsyncFileSystem } from '../filesystem.js';
4
+ import { type Ino } from '../inode.js';
4
5
  import { Stats } from '../stats.js';
5
6
  /**
6
7
  * Represents an *asynchronous* key-value store.
7
8
  */
8
- export interface AsyncKeyValueStore {
9
+ export interface AsyncStore {
9
10
  /**
10
11
  * The name of the key-value store.
11
12
  */
12
- name(): string;
13
+ name: string;
13
14
  /**
14
15
  * Empties the key-value store completely.
15
16
  */
@@ -17,27 +18,27 @@ export interface AsyncKeyValueStore {
17
18
  /**
18
19
  * Begins a read-write transaction.
19
20
  */
20
- beginTransaction(type: 'readwrite'): AsyncKeyValueRWTransaction;
21
+ beginTransaction(type: 'readwrite'): AsyncRWTransaction;
21
22
  /**
22
23
  * Begins a read-only transaction.
23
24
  */
24
- beginTransaction(type: 'readonly'): AsyncKeyValueROTransaction;
25
- beginTransaction(type: string): AsyncKeyValueROTransaction;
25
+ beginTransaction(type: 'readonly'): AsyncROTransaction;
26
+ beginTransaction(type: string): AsyncROTransaction;
26
27
  }
27
28
  /**
28
29
  * Represents an asynchronous read-only transaction.
29
30
  */
30
- export interface AsyncKeyValueROTransaction {
31
+ export interface AsyncROTransaction {
31
32
  /**
32
33
  * Retrieves the data at the given key.
33
34
  * @param key The key to look under for data.
34
35
  */
35
- get(key: string): Promise<Uint8Array>;
36
+ get(key: Ino): Promise<Uint8Array>;
36
37
  }
37
38
  /**
38
39
  * Represents an asynchronous read-write transaction.
39
40
  */
40
- export interface AsyncKeyValueRWTransaction extends AsyncKeyValueROTransaction {
41
+ export interface AsyncRWTransaction extends AsyncROTransaction {
41
42
  /**
42
43
  * Adds the data to the store under the given key. Overwrites any existing
43
44
  * data.
@@ -46,12 +47,12 @@ export interface AsyncKeyValueRWTransaction extends AsyncKeyValueROTransaction {
46
47
  * @param overwrite If 'true', overwrite any existing data. If 'false',
47
48
  * avoids writing the data if the key exists.
48
49
  */
49
- put(key: string, data: Uint8Array, overwrite: boolean): Promise<boolean>;
50
+ put(key: Ino, data: Uint8Array, overwrite: boolean): Promise<boolean>;
50
51
  /**
51
52
  * Deletes the data at the given key.
52
53
  * @param key The key to delete from the store.
53
54
  */
54
- del(key: string): Promise<void>;
55
+ remove(key: Ino): Promise<void>;
55
56
  /**
56
57
  * Commits the transaction.
57
58
  */
@@ -61,35 +62,32 @@ export interface AsyncKeyValueRWTransaction extends AsyncKeyValueROTransaction {
61
62
  */
62
63
  abort(): Promise<void>;
63
64
  }
64
- export declare class AsyncKeyValueFile extends PreloadFile<AsyncKeyValueFileSystem> implements File {
65
- constructor(_fs: AsyncKeyValueFileSystem, _path: string, _flag: FileFlag, _stat: Stats, contents?: Uint8Array);
65
+ export declare class AsyncFile extends PreloadFile<AsyncStoreFileSystem> {
66
+ constructor(_fs: AsyncStoreFileSystem, _path: string, _flag: FileFlag, _stat: Stats, contents?: Uint8Array);
66
67
  sync(): Promise<void>;
68
+ syncSync(): void;
67
69
  close(): Promise<void>;
70
+ closeSync(): void;
68
71
  }
69
72
  /**
70
73
  * An "Asynchronous key-value file system". Stores data to/retrieves data from
71
74
  * an underlying asynchronous key-value store.
72
75
  */
73
- export declare class AsyncKeyValueFileSystem extends BaseFileSystem {
74
- static isAvailable(): boolean;
75
- protected store: AsyncKeyValueStore;
76
- private _cache;
76
+ export declare class AsyncStoreFileSystem extends AsyncFileSystem {
77
+ protected store: AsyncStore;
78
+ private _cache?;
79
+ protected _ready: Promise<this>;
80
+ ready(): Promise<this>;
77
81
  constructor(cacheSize: number);
78
82
  /**
79
83
  * Initializes the file system. Typically called by subclasses' async
80
84
  * constructors.
81
85
  */
82
- init(store: AsyncKeyValueStore): Promise<void>;
83
- getName(): string;
84
- isReadOnly(): boolean;
85
- supportsSymlinks(): boolean;
86
- supportsProps(): boolean;
87
- supportsSynch(): boolean;
86
+ init(store: AsyncStore): Promise<void>;
88
87
  /**
89
88
  * Delete all contents stored in the file system.
90
89
  */
91
90
  empty(): Promise<void>;
92
- access(p: string, mode: number, cred: Cred): Promise<void>;
93
91
  /**
94
92
  * @todo Make rename compatible with the cache.
95
93
  */
@@ -101,9 +99,12 @@ export declare class AsyncKeyValueFileSystem extends BaseFileSystem {
101
99
  rmdir(p: string, cred: Cred): Promise<void>;
102
100
  mkdir(p: string, mode: number, cred: Cred): Promise<void>;
103
101
  readdir(p: string, cred: Cred): Promise<string[]>;
104
- chmod(p: string, mode: number, cred: Cred): Promise<void>;
105
- chown(p: string, new_uid: number, new_gid: number, cred: Cred): Promise<void>;
106
- _sync(p: string, data: Uint8Array, stats: Stats): Promise<void>;
102
+ /**
103
+ * Updated the inode and data node at the given path
104
+ * @todo Ensure mtime updates properly, and use that to determine if a data update is required.
105
+ */
106
+ sync(p: string, data: Uint8Array, stats: Readonly<Stats>): Promise<void>;
107
+ link(existing: string, newpath: string, cred: Cred): Promise<void>;
107
108
  /**
108
109
  * Checks if the root directory exists. Creates it if it doesn't.
109
110
  */
@@ -135,7 +136,7 @@ export declare class AsyncKeyValueFileSystem extends BaseFileSystem {
135
136
  private getDirListing;
136
137
  /**
137
138
  * Adds a new node under a random ID. Retries 5 times before giving up in
138
- * the exceedingly unlikely chance that we try to reuse a random GUID.
139
+ * the exceedingly unlikely chance that we try to reuse a random ino.
139
140
  */
140
141
  private addNewNode;
141
142
  /**