swipl-devel icon indicating copy to clipboard operation
swipl-devel copied to clipboard

Import swipl-web.wasm and swipl-web.data relative to `swipl-web.js` rather than the global script.

Open jeswr opened this issue 2 years ago • 7 comments

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

jeswr avatar Aug 25 '22 01:08 jeswr

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.

jan-swi-prolog-01 avatar Aug 25 '22 06:08 jan-swi-prolog-01

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.

jeswr avatar Aug 25 '22 08:08 jeswr

With that directory structure you likely want

locateFile: (file: string) => `./swipl/${file}`

in the module options.

rla avatar Aug 26 '22 14:08 rla

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.

rla avatar Aug 26 '22 15:08 rla

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).

rla avatar Aug 26 '22 15:08 rla

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

rla avatar Aug 26 '22 15:08 rla

(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.

rla avatar Aug 26 '22 15:08 rla