swipl-devel
swipl-devel copied to clipboard
Import swipl-web.wasm and swipl-web.data relative to `swipl-web.js` rather than the global script.
Related to #1024
Otherwise, if I have the folder structure
- script.js
- swipl/
- swipl-web.data
- swipl-web.js
- swipl-web.wasm
- index.js
With
index.js
export default async function SWIPL(module) {
await require('./swipl-web.js')(module);
}
script.js
import SWIPL from './swipl';
async function createSWIPLModule(options: SwiplOptions = {}): Promise<SwiplModule> {
const Module = {
noInitialRun: true,
arguments: [],
locateFile: (file: string) => `./${file}`,
print: (str: string) => {},
printErr: (line: any) => {},
...options,
} as any;
await SWIPL(Module);
return Module
}
createSWIPLModule()
Then I get the error
[jeswr@orangejuly lib]$ node script.js
/home/jeswr/Documents/rdfstar/eye.js/lib/swipl/swipl-web.js:1132
throw ex
^
RuntimeError: Aborted(Error: ENOENT: no such file or directory, open 'swipl-web.wasm'). Build with -sASSERTIONS for more info.
at abort (/home/jeswr/Documents/rdfstar/eye.js/lib/swipl/swipl-web.js:1436:25)
at getBinary (/home/jeswr/Documents/rdfstar/eye.js/lib/swipl/swipl-web.js:1465:21)
at /home/jeswr/Documents/rdfstar/eye.js/lib/swipl/swipl-web.js:1493:28
at processTicksAndRejections (node:internal/process/task_queues:95:5)
Node.js v18.4.0
AFAIK this is all generated code by Emscripten, so there is little we can do. Of course, I could be wrong. I'm a Prolog and C programmer.
This would indicate it should be possible https://web.dev/emscripten-npm/. I'm guessing the current issue would be that here locateFile
is not doing the relative loading I will expect.
I haven't had the chance to dig in deep enough to see if there are any bugs the emscripten team would need to resolve or if a bundler can do what is needed.
With that directory structure you likely want
locateFile: (file: string) => `./swipl/${file}`
in the module options.
How do you put a devel and a stable version side by side on the same server?
locateFile can return host-relative absolute path like /devel/lib/swipl.data for this use case.
The problem I am trying to adress is rather, how do you make a locateFile that you almost never need to rewrite?
Since you define it in your own script, example: https://github.com/SWI-Prolog/swipl-devel/blob/master/src/wasm/test.html#L26
You can make it conditional wrt current URL (check if window.location contains stable/devel/etc).
Self orienting means
What if you leave it empty? By docs it might try to find the files from the right location then: https://emscripten.org/docs/api_reference/module.html#Module.locateFile
(top of thread)
The top of thread has this issue when running in Node.js with ES modules. Node.js uses different file/module resolution than browsers. Different approaches are necessary but they should be achivable with returning approriate path from locateFile. Node.js CommonJS modules always have __dirname (https://nodejs.org/api/modules.html#__dirname), in ES setting you would need to use something else (https://blog.logrocket.com/alternatives-dirname-node-js-es-modules/), and in browser you can use window.location to get the current file/path and then rewrite actual locations against it.