-
Notifications
You must be signed in to change notification settings - Fork 221
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
EmscriptenFS
and preloading
#325
Comments
@pmp-p Have you tried with 2.0.0-beta? |
nvm i only use preload plugin now for libraries and it was an emscripten bug emscripten-core/emscripten#17956, forgot to close sorry |
re-opening and quoting an emscripten expert on that "I guess FS.analyzePath in browserfs isn't setting .object.contents on the return value" if it can help to sched light. Binary files that are expected to be preloaded by the emscripten plugins are truncated. |
I'm not sure which parts of the BFS code you're referring to. If possible, could you create a minimally reproducible example with the latest code? Please note that the latest commit supports import { configure, BFSRequire, ZipFS } from 'browserfs';
const mfs = await configure({
fs: 'MountableFileSystem',
options: {
'/': {
fs: 'OverlayFS',
options: {
readable: READABLE_FS,
writable: { fs: 'InMemory' }
}
}
}
});
const zipfs = await ZipFS.Create({ zipData: ZIP_FILE_BUFFER });
mfs.mount('/mnt/zip', zipfs); |
So i built from git, using npm from emsdk with "npm run build" and used the un-minified
let consider "test.apk" zip file which contains a text file "assets/main.py" The goal is to mount in emscripten FS at path "/data/data/test" an overlayfs that read the zip file content and still allow to read/write/remove files and create/list/remove folders under "/data/data/test" i tried without success ( folder and file structure is ok, reading zipped file content is corrupt) var track_media
if (!vm) {
vm={}
// how is passed the FS object ???
vm.BFS = new BrowserFS.EmscriptenFS() // {FS:vm.FS}
vm.BFS.Buffer = BrowserFS.BFSRequire('buffer').Buffer
const data = await (await fetch('test.apk')).arrayBuffer()
track_media = await vm.BFS.Buffer.from(data)
} else {
track_media = MM[trackid].media
}
// how is passed the FS object ???
vm.BFS = new BrowserFS.EmscriptenFS() // {FS:vm.FS}
vm.BFS.Buffer = BrowserFS.BFSRequire('buffer').Buffer
const data = await (await fetch('test.apk')).arrayBuffer()
const track_media = await vm.BFS.Buffer.from(data)
const zipfs = await BrowserFS.ZipFS.Create({
zipData: track_media,
"name": hint
})
const memfs = await BrowserFS.InMemory.Create();
const ovfs = await BrowserFS.OverlayFS.Create({
writable : memfs,
readable: zipfs
})
// this alone does not work ? why ??
// const mfs = await BrowserFS.MountableFileSystem.Create({"/" : ovfs})
// console.log( mfs )
const mfs = await BrowserFS.initialize( await BrowserFS.MountableFileSystem.Create({"/" : ovfs}) )
// where is the link beetween (BFSEmscriptenFS)vm.BFS and MountableFileSystem(mfs) ?
// vm.BFS.mount( ???????? )
const emfs = await vm.FS.mount(vm.BFS, {root: "/"}, "/data/data/test" ); needless to say i'm not very fond of javascript so i don't get some things in init sequence hence the above confused comments. The working code (apart from corner case in preloading ) for older BFS var bfs2 = false
if (!BrowserFS.InMemory) {
console.warn(" ==================== BFS1 ===============")
BrowserFS.InMemory = BrowserFS.FileSystem.InMemory
BrowserFS.OverlayFS = BrowserFS.FileSystem.OverlayFS
BrowserFS.MountableFileSystem = BrowserFS.FileSystem.MountableFileSystem
BrowserFS.ZipFS = BrowserFS.FileSystem.ZipFS
} else {
console.warn(" ==================== BFS2 ===============")
bfs2 = true
}
function apk_cb(e, apkfs){
BrowserFS.InMemory.Create(
function(e, memfs) {
BrowserFS.OverlayFS.Create({"writable" : memfs, "readable" : apkfs },
function(e, ovfs) {
BrowserFS.MountableFileSystem.Create({
'/' : ovfs
}, async function(e, mfs) {
await BrowserFS.initialize(mfs);
await vm.FS.mount(vm.BFS, {root: "/"}, "/data/data/test");
//setTimeout(()=>{track.ready=true}, 0)
})
}
);
}
);
}
//await BrowserFS.FileSystem.ZipFS.Create(
await BrowserFS.ZipFS.Create(
{"zipData" : track_media, "name": "test.apk"},
apk_cb
) i'm starting to think that code worked by accident and that my construction is broken. |
@pmp-p The non-fs polyfills have been removed (BFS is not a buffer/path/process polyfill, it is an FS polyfill). I recommend you use import { configure, BFSRequire, EmscriptenFS } from 'browserfs';
import ( Buffer } from 'buffer'; // polyfill. If running on node this is not needed.
const data = await (await fetch('test.apk')).arrayBuffer();
const track_media = await Buffer.from(data);
// assuming FS is from Emscripten
await configure({
fs: 'MountableFileSystem',
options: {
'/': {
fs: 'OverlayFS',
options: {
readable: { fs: 'ZipFS', options: { zipData: track_media, name: 'hint' } },
writable: { fs: 'InMemory' }
}
}
}
});
const fs = new EmscriptenFS();
// ... set up emscripten ...
FS.mount(fs, { root: '/', }, '/data'); |
so
did not work for me ( syntax error, also i think import is not supported on some old/obsoleted mobile targets i have like safari/ios ). i load BrowserFS this way so i tried instead const data = await (await fetch('test.apk')).arrayBuffer();
const track_media = await vm.BFS.Buffer.from(data);
// assuming FS is from Emscripten
await BrowserFS.configure({
fs: 'MountableFileSystem',
options: {
'/': {
fs: 'OverlayFS',
options: {
readable: { fs: 'ZipFS', options: { zipData: track_media, name: 'hint' } },
writable: { fs: 'InMemory' }
}
}
}
});
vm.FS.mount(vm.BFS, { root: '/', }, '/data/data/test'); but same result zip content is garbled, folder structure is ok, file/folder creation works but reading newly created files back is garbled too. |
My bad... I had accidentally put a import { configure, BFSRequire, EmscriptenFS } from 'browserfs';
import { Buffer } from 'buffer'; // polyfill. If running on node this is not needed.
const data = await (await fetch('test.apk')).arrayBuffer();
const track_media = await Buffer.from(data);
// assuming FS is from Emscripten
await configure({
fs: 'MountableFileSystem',
options: {
'/': {
fs: 'OverlayFS',
options: {
readable: { fs: 'ZipFS', options: { zipData: track_media, name: 'hint' } },
writable: { fs: 'InMemory' }
}
}
}
});
const fs = new EmscriptenFS();
// ... set up emscripten ...
FS.mount(fs, { root: '/', }, '/data'); If you aren't using ESM, you will need to use BrowserFS from the |
Maybe you are assuming all emscripten users have javascript knowledge, but that's not my case i only do C and python not even C++ ( emscripten is a C/C++ sdk ). Please don't take too much javscript shortcuts i'd really want to help solve that issue. |
You will have to install a buffer polyfill separately: npm i buffer |
Also i think i've made a shortcut too : the env testcase is not Node at all but only browser environnement ( emscripten target=web) and i'm testing on v8 not firefox |
I recommend you use a bundler (esbuild is fantastic) to bundle your code before running tests. This bundles dependencies which means you no longer need to worry about modules and imports. If you use esbuild, make sure you set |
Please use zen-fs/core#22 |
Hi, I have the following layout for running Pygame games apk directly on web
but emscripten_run_preload_plugins() cannot operate on Wasm/Image/Audio files located under /data/data//.
error messages are all like
Image blob:http://localhost:8000/b5c7a41e-0824-4c8c-b1b2-672608468e73 could not be decoded
`
browserfs 1.4.3
ref: https://emscripten.org/docs/api_reference/emscripten.h.html#c.emscripten_run_preload_plugins
The text was updated successfully, but these errors were encountered: