Closed chinonso098 closed 1 month ago
@chinonso098 --output
/-o
expects a file path, not a directory. It is used to customize the index JSON file path.
I've included the output of make-index --help
for your reference:
$ npx make-index --help
make-index <path> [...options]
path: The path to create a listing for
options:
--help, -h Outputs this help message
--quiet, -q The command will not generate any output, including error messages.
--verbose Output verbose messages
--output, -o <path> Path to the output file. Defaults to listing.
--ignore, -i <pattern> Ignores files which match the glob <pattern>. Can be passed multiple times.
Thanks
This is the index.json file created in ZenFS
This is the osdrive.json file created in BrowserFS
in BrowserFS, for me to access the contents of the filesystem, I did fs.readdir('/osdrive/Desktop' ......), and it would pull the contents in the Desktop folder.
In ZenFS, I tried fs.readdir('/Desktop' ......) and I get Error: No such file or directory. In ZenFS, I tried fs.readdir('/entries/Desktop' ......) and I get Error: No such file or directory. In ZenFS, I tried fs.readFile('/Desktop/fileexplorer.url' ......) and I get Error: No such file or directory.
fs.readdir('/Desktop')
should work. If it doesn't I can take a deeper look. What does fs.readdirSync('/')
give?
Here is what my code looks like
import osDriveFileSystemIndex1 from '../../../index.json';
import ini from 'ini';
import { configure, fs, Overlay, Fetch } from '@zenfs/core';
import { IndexedDB } from '@zenfs/dom';
@Injectable({
providedIn: 'root',
})
export class FileService {
private async initZenFSAsync(): Promise<void> {
return new Promise<void>((resolve, reject) => {
configure<typeof Overlay>({
mounts: {
'/': {
backend: Overlay,
readable: { backend: Fetch, index: osDriveFileSystemIndex1 },
writable: { backend: IndexedDB, storeName: 'fs-cache' },
},
},
});
resolve(console.log('ZenFS is Ready!!!'));
});
}
public async getFilesFromDirectoryAsync1(): Promise<void> {
// await this.initBrowserFsAsync();
await this.initZenFSAsync().then(() => {
fs.readdir('/', (err, files) => {
if (err) {
console.log("Oops! a boo boo happened, filesystem wasn't ready:", err);
} else {
console.log('Here are the files:', files);
}
});
});
}
public getFilesFromDirectorySync(): void {
const result = fs.readdirSync('/');
console.log(`Here are the files: ${result}`);
}
public async getFilesFromDirectoryAsync(dirPath: string): Promise<unknown> {
await this.initBrowserFsAsync();
// ...
}
// ...
}
For the readdir('/', (err, file)=>{})
, this is what I get:
[webpack-dev-server] Server started: Hot Module Replacement disabled, Live Reloading enabled, Progress disabled, Overlay enabled.
Angular is running in development mode.
ZenFS is Ready!!!
Here are the files: ► []
For the readdirSync('/')
, this is what I get:
[webpack-dev-server] Server started: Hot Module Replacement disabled, Live Reloading enabled, Progress disabled, Overlay enabled.
Angular is running in development mode.
ZenFS is Ready!!!
► ERROR
Error: Size mismatch: buffer length 2, stats size 4096
at new PreloadFile (file.js:176:19)
at StoreFS.openfileSync (fs.js:226:16)
at _openSync (sync.js:183:19)
at _readFileSync (sync.js:221:53)
at Module.readFileSync (sync.js:243:30)
at file.service.ts:130:28
at _ZoneDelegate.invoke (zone.js:365:28)
at Object.onInvoke (core.mjs:15931:33)
at _ZoneDelegate.invoke (zone.js:364: 34)
at ZoneImpl.run (zone.js:111:43)
I attempted to reproduce the error:
import { configure, fs, Overlay, Fetch } from '@zenfs/core';
import { IndexedDB } from '@zenfs/dom';
await configure({
mounts: {
'/': {
backend: Overlay,
readable: {
backend: Fetch,
index: './index.json',
baseUrl: 'data',
},
writable: { backend: IndexedDB, storeName: 'fs-cache' },
},
},
});
console.log('FS configured');
console.log('readdir / (async):', await fs.promises.readdir('/'));
console.log('readdir / (sync):', fs.readdirSync('/'));
console.log('readdir /nested:', await fs.promises.readdir('/nested'));
console.log('readFile /one.txt:', await fs.promises.readFile('/one.txt', 'utf8'));
Directory structure:
data
├ one.txt
└ nested
└ two.js
But it gave me the correct and expected output:
FS configured
readdir / (async): ► (2) ['nested', 'one.txt']
readdir / (sync): ► (2) ['nested', 'one.txt']
readdir /nested: ► ['two.js']
readFile /one.txt: OMG!
Hmmmm....... i guess it's something on my end. Let me keep digging
I recommend you rewrite 2 of the class methods, since they are somewhat difficult to read, and use async
/await
incorrectly. This may help you address the underlying issue:
export class FileService {
private async initZenFSAsync(): Promise<void> {
await configure<typeof Overlay>({
mounts: {
'/': {
backend: Overlay,
readable: { backend: Fetch, index: osDriveFileSystemIndex1 },
writable: { backend: IndexedDB, storeName: 'fs-cache' },
},
},
});
console.log('ZenFS is Ready!!!'));
}
public async getFilesFromDirectoryAsync1(): Promise<void> {
// await this.initBrowserFsAsync();
await this.initZenFSAsync();
try {
console.log('Here are the files:', await fs.promises.readdir('/'));
} catch (err) {
console.log("Ooops! a boo boo happened, filesystem wasn't ready:", err);
}
}
// ...
}
Again, thanks a lot for the assist. I will implement the changes and get back to you.
@chinonso098 What are the entries in the Index
?
You can log either fs.mounts.get('/').fs._readable.index
, or
const readable = await resolveMountConfig({ backend: Fetch, index: osDriveFileSystemIndex1 });
console.log(readable.index);
await configure<typeof Overlay>({
mounts: {
'/': {
backend: Overlay,
readable,
writable: { backend: IndexedDB, storeName: 'fs-cache' },
},
},
});
Note you may have to ignore a Typescript error about protected/private members.
here are some of the entries (Document, Games, Pictures, Music, icons ...)
Here is the Index file. index.json
I know the index.json has the files you mentioned... I'm refering to the runtime Index
's entries. Assuming that the Index
has all of the correct entries, could you provide me with the value of index.get('/')
? This will include the Stats.fileData
property, which contains the actual directory entries computed at runtime.
I tried to do what you asked, but i get a 'Type number is not assignable to 1' error
Also, for some strange reason, i missed informing you about this error
the error points to line 92 of the file.services.ts file. It seems like it is accessing the index file, but it fails to find the data on the server
I get the error : 'Property 'fs' does not exist on type FileSystem' when I try this code fs.mounts.get('/').fs._readble.index
I tried to do what you asked, but i get a 'Type number is not assignable to 1' error
This is because the imported index's type is not strict enough. You can cast the index object (as IndexJSON
), though you are telling Typescript that the version
property of the imported object is 1
.
the error points to line 92 of the file.services.ts file. It seems like it is accessing the index file, but it fails to find the data on the server
You probably need to set the baseUrl
in the Fetch
options, since it defaults to using /
as the base URL path.
I get the error : 'Property 'fs' does not exist on type FileSystem' when I try this code
fs.mounts.get('/').fs._readble.index
You should have an Overlay
instance mounted on /
. The Overlay
instance is a LockedFS
wrapping a UnlockedOverlayFS
. The UnlockedOverlayFS
should have the _readable
property set to a FetchFS
, which has the index
property.
Basically:
fs.mounts.get('/')
→LockedFS
.fs
→UnlockedOverlayFS
._readable
→FetchFS
.index
→Index
what do I set the baseUrl to?
Ok, minor progress. I set baseUrl to baseUrl:'osdrive'
osdrive is the actual folder containing the contents from which the index.json file was created.
The 404 error message is gone, but I still get an empty array for fs.promise.readdir('/')
And attempting to the cast the index object to IndexJSON fails
Basically:
fs.mounts.get('/')
→LockedFS
.fs
→UnlockedOverlayFS
._readable
→FetchFS
.index
→Index
Ummm.............um....ok
You need to import IndexJSON
, the type won't magically appear. I don't think it is exported by the index.ts, so you will need to import type { IndexJSON } from '@zenfs/core/backends/index/index'
As for the value of baseUrl
, it should be the URL to use for the root. For example, if you try to read dirA/file.txt
, the request will go to ${baseUrl}/dirA/file.txt
, so if your osdrive directory is at localhost:1234/osdrive/
, and the current origin is localhost:1234
, you can set the baseUrl
to osdrive
.
I tried to import IndexJSON
, but nothing is coming up. Is there some package that I need to install ?
No, It is defined in src/backends/index/index.ts:12 as IndexData
. Sorry for giving you the wrong name for the type.
Thank you, thank you, thank you
We have data 🙂🙂🙂
So was it because of baseUrl
?
Correct, it was the baseUrl
I have a number of functions that interact with the fileSystem. At the beginning of each function, will I have to call initZenFSAsync()
like the method below
Does the FileSystem know that it is already configured and skips ? because I added a flag to skip needless await configure
If the flag Is not needed. I'll take it out
No. configure
will reconfigure the FS every time you call it. It is intended to be run once, so I recommend you run it once during program initialization. If you have access to top-level await
, I strongly encourage you to use it.
If you would like to continue using a flag, A guard clause would be more readable (and decrease indentation):
private async initZenFSAsync(): Promise<void> {
if(this._isFileSystemInit) {
return;
}
await configure({
// ...
});
this._isFileSystemInit = true;
}
Also @chinonso098 Please stop posting screenshots of your code. It is next to impossible to copy the code, which is making helping you very difficult. As stated in the contributing.md, "Please copy logs, terminal output, and code into a code block in the issue or PR. Do not include screenshots since those are very difficult to debug." So far I've manually been rewriting your screenshots into code blocks but it is making me a little frustrated. Sorry to give you all this, but its important to follow the guidelines on issues.
Will do next time. Again Thanks a lot for the assist. 🙂
@chinonso098 No problem please let me know if you have more issues. I also encourage you to look at the documentation before opening an issue since many times the problem can be solved without opening an issue (like with baseUrl
).
When I run the command
npx make-index --output src\osdrive
ornpx make-index -o src\osdrive
, i get the same illegal operation on a directory error.What could be the cause? And again, thanks for the assist