Mqx
Mqx4w ago

Publish binaries to JSR and load them using Deno.dlopen()

Hey is it possible to publish binary files such as .dll or .so files and then access them via Import in an other package? I would like to publish binaries to JSR, for example like this: deno.json
{
"name": "@mypackage/binaries",
"version": "0.1.0",
"exports": {
"./bin.dll": "./path/to/bin.dll"
}
}
{
"name": "@mypackage/binaries",
"version": "0.1.0",
"exports": {
"./bin.dll": "./path/to/bin.dll"
}
}
So that I could then install the package and use the binary via an import, for example like this:
import bin from "@mypackage/binaries/bin.dll"

const lib = Deno.dlopen(bin, …);
import bin from "@mypackage/binaries/bin.dll"

const lib = Deno.dlopen(bin, …);
Is this somehow possible? I know there are 3rd party libraries like plug that do something like this, but I am just curious if I could get this to work without something like plug.
13 Replies
Mrcool 🇵🇸
Not currently possible you can follow https://github.com/denoland/deno/issues/30728 Even if bytes import were stabilized , dlopen can't open the bytes directly you need to first to write the dll to a temp file
Mqx
MqxOP2w ago
As far as I know, Deno.dlopen supports URLs. So would it be possible to publish a separate package where I export a variable that points to the binary in the package, so that I can install the package in my main app and import the binary that way? Fo example like this: Package: binary.ts
export default new URL('./path/to/binary.dll')
export default new URL('./path/to/binary.dll')
deno.json
{
"name": "@my-package/binary",
"version": "0.1.0",
"exports": {
".": "./path/to/binary.ts"
}
}
{
"name": "@my-package/binary",
"version": "0.1.0",
"exports": {
".": "./path/to/binary.ts"
}
}
Main project:
import bin from "@my-package/binary"

const lib = Deno.dlopen(bin, …);
import bin from "@my-package/binary"

const lib = Deno.dlopen(bin, …);
Mrcool 🇵🇸
It doesn't support url , if it mention this in it's type then it mean file:// url specifically
Mqx
MqxOP2w ago
Doesn’t it get automatically resolved to a file:// url if it is a relative path? And even if not, would I be able to specify it as a file type? Is there a way to test this without publishing a package to jsr? Because if this does not work I don’t want to publish a „useless“ package to jsr that I am than unable to remove
Mrcool 🇵🇸
you should just publish a useless package, its best to experiment , i have stuff in jsr like @scope/lab @scope/test its a normal thing to do (deno maintainers have some as well) and you can just archive it later if it really bother you
ud2
ud22w ago
The path or URL passed to Deno.dlopen must point to a real file on the local file system, which means that one way or another the binary needs to be written to a file before you load it. You can do something as simple as
const res = await fetch(import.meta.resolve("./lib.dll"));
if (!res.ok) {
throw new TypeError(`HTTP ${res.status}`);
}
await Deno.writeFile("./lib.dll", res.body);
Deno.dlopen("./lib.dll", { … });
const res = await fetch(import.meta.resolve("./lib.dll"));
if (!res.ok) {
throw new TypeError(`HTTP ${res.status}`);
}
await Deno.writeFile("./lib.dll", res.body);
Deno.dlopen("./lib.dll", { … });
Mqx
MqxOP7d ago
Why would I need to write it to a file if it geht’s uploaded in the JSR package contents. For example the README file which is neither JS nor TS, but you can still upload it to JSR and when you install the package, the file should also be downloaded as contents of the package. Which means if you install the package you should also have the file on your disk, which than means that you should be able to import it using the URL object that points to the local file from the installed package.
ud2
ud27d ago
For example the README file which is neither JS nor TS, but you can still upload it to JSR and when you install the package, the file should also be downloaded as contents of the package.
No. When you install a package, only importable modules are downloaded, not any assets (see the first comment under the aforementioned #30728). For example, if you do deno install jsr:@std/toml, these are all the files that will be downloaded, even though the package also contains a LICENSE and a bunch of tests.
Mqx
MqxOP6d ago
Okay Will check @ud2 what about using byte imports. Could that help?
ud2
ud24d ago
JSR doesn't support bytes imports yet. And even if it does, a bytes import would cause the binary to stay in memory forever, which is probably not ideal?
Mqx
MqxOP4d ago
Hmm so the only way is to export an URL object referencing the file and use the fetch function to fetch it The reason why I would like to publish the binary to JSR in the first place is is because I would like to leverage the versioning resolver the Deno uses That was I don’t have to do it myself What kind of imports does JSR support? An other way would be to convert the binary to a buffer and export it that way. But this is probably not very efficient
ud2
ud24d ago
JS, TS, Wasm and JSON, I think.
Mqx
MqxOP4d ago
Hmm okay

Did you find this page helpful?