Giter Club home page Giter Club logo

plug's Introduction

plug

Tags Checks Dependencies License

Plug is a drop in extension for using remote dynamic libraries in deno. It automatically handles caching and loading with minimal overhead. It can automatically create the URL for your cross-operating-system, cross-architecture libraries if you so wish using a simple configuration which deviates from the standard URL/string path input.

Installation

Plug is published to jsr.io and deno.land. The recommended way to use it is to use JSR:

deno add @denosaurs/plug

or without the CLI:

import * as plug from "jsr:@denosaurs/plug";

Example using plug as an almost drop in replacement for Deno.dlopen

import { dlopen } from "@denosaurs/plug";

// Drop-in replacement for `Deno.dlopen` which fetches the following depending
// on operating system:
// * darwin: "https://example.com/some/path/libexample.dylib"
// * windows: "https://example.com/some/path/example.dll"
// * linux: "https://example.com/some/path/libexample.so"
const library = await dlopen("https://example.com/some/path/", {
  noop: { parameters: [], result: "void" },
});

library.symbols.noop();

Example using automatic binary name guessing

import { dlopen, FetchOptions } from "@denosaurs/plug";

// If you want plug to guess your binary names
const options: FetchOptions = {
  name: "example",
  url: "https://example.com/some/path/",
  // Becomes:
  // darwin: "https://example.com/some/path/libexample.dylib"
  // windows: "https://example.com/some/path/example.dll"
  // linux: "https://example.com/some/path/libexample.so"
};

const library = await dlopen(options, {
  noop: { parameters: [], result: "void" },
});

library.symbols.noop();

Example using nested cross-platform options

import { dlopen, FetchOptions } from "@denosaurs/plug";

// Also you can specify the path for certain architecture
const options: FetchOptions = {
  name: "example",
  url: {
    darwin: {
      aarch64: `https://example.com/some/path/libexample.aarch64.dylib`,
      x86_64: `https://example.com/some/path/libexample.x86_64.dylib`,
    },
    windows: `https://example.com/some/path/example.dll`,
    linux: `https://example.com/some/path/libexample.so`,
    freebsd: "https://example.com/some/path/libexample_freebsd.so",
    netbsd: "https://example.com/some/path/libexample_netbsd.so",
    aix: "https://example.com/some/path/libexample_aix.so",
    solaris: "https://example.com/some/path/libexample_solaris.so",
    illumos: "https://example.com/some/path/libexample_illumos.so",
  },
};

await dlopen(options, {});

Example using nested cross-platform options and automatic binary name guessing

import { dlopen, FetchOptions } from "@denosaurs/plug";

// Or even configure plug to automatically guess the binary names for you,
// even when there are special rules for naming on specific architectures
const options: FetchOptions = {
  name: "test",
  url: "https://example.com/some/path/",
  suffixes: {
    darwin: {
      aarch64: ".aarch64",
      x86_64: ".x86_64",
    },
  },
  // Becomes:
  // darwin-aarch64: "https://example.com/some/path/libexample.aarch64.dylib"
  // darwin-x86_64: "https://example.com/some/path/libexample.x86_64.dylib"
};

await dlopen(options, {});

Testing

To run the plug tests, you can use the following command:

deno test --import-map test_import_map.json -A --doc

The test_import_map.json file is used to map the @denosaurs/plug import to the local mod.ts file instead of the remote one for the documentation tests.

Other

Related

Contribution

Pull request, issues and feedback are very welcome. Code style is formatted with deno fmt and commit messages are done following Conventional Commits spec.

Licence

Copyright 2020-2024, the denosaurs team. All rights reserved. MIT license.

plug's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

plug's Issues

Type error

$ ../deno --unstable check -r --all https://deno.land/x/[email protected]/mod.ts 
Check https://deno.land/x/[email protected]/mod.ts
error: TS2345 [ERROR]: Argument of type 'S' is not assignable to parameter of type 'Cast<S, [] | (S extends string | number | bigint | boolean ? S : never) | { [K in keyof S]: Cast<S[K], [] | (S[K] extends string | number | bigint | boolean ? S[K] : never) | { [K in keyof S[K]]: Cast<...>; }>; }>'.
  Type 'ForeignLibraryInterface' is not assignable to type 'Cast<S, [] | (S extends string | number | bigint | boolean ? S : never) | { [K in keyof S]: Cast<S[K], [] | (S[K] extends string | number | bigint | boolean ? S[K] : never) | { [K in keyof S[K]]: Cast<...>; }>; }>'.
  return Deno.dlopen(await download(options), symbols);
                                              ~~~~~~~
    at https://deno.land/x/[email protected]/mod.ts:145:47

Pipe Download messages to stderr

I've been making a couple of deno scripts, and using their stdout to feed other scripts. I noticed that the use of this library outputs messages to stdout and not stderr. Perhaps this should be changed?

Performance issues with using automatic url detection

When running the tests using the options

const options: Plug.Options = {
  name: "test_plugin",
  url: path,
  cache: resolveTest("cache"),
};

instead of

const options: Plug.Options = {
  name: "test_plugin",
  urls: {
    darwin: `${path}/libtest_plugin.dylib`,
    windows: `${path}/test_plugin.dll`,
    linux: `${path}/libtest_plugin.so`,
  },
  cache: resolveTest("cache"),
};

the results differ with around a second in delay per test. Using automatic url detection:

running 3 tests
test remote | prepare ... Check file:///F:/code/denosaurs/plug/test/remote.ts
/test_plugin/target/debug/test_plugin.dll
Hello from plugin.
zero_copy[0]: test
zero_copy[1]: test
Hello from plugin.
zero_copy[0]: test
zero_copy[1]: test
ok (2317ms)
test local | prepare | relative ... Check file:///F:/code/denosaurs/plug/test/local.ts
Hello from plugin.
zero_copy[0]: test
zero_copy[1]: test
Hello from plugin.
zero_copy[0]: test
zero_copy[1]: test
ok (2136ms)
test local | prepare | absolute ... Check file:///F:/code/denosaurs/plug/test/abs.ts
Hello from plugin.
zero_copy[0]: test
zero_copy[1]: test
Hello from plugin.
zero_copy[0]: test
zero_copy[1]: test
ok (2084ms)

test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out (6537ms)

normal:

running 3 tests
test remote | prepare ... Check file:///F:/code/denosaurs/plug/test/remote.ts
/test_plugin/target/debug/test_plugin.dll
Hello from plugin.
zero_copy[0]: test
zero_copy[1]: test
Hello from plugin.
zero_copy[0]: test
zero_copy[1]: test
ok (1192ms)
test local | prepare | relative ... Check file:///F:/code/denosaurs/plug/test/local.ts
Hello from plugin.
zero_copy[0]: test
zero_copy[1]: test
Hello from plugin.
zero_copy[0]: test
zero_copy[1]: test
ok (1001ms)
test local | prepare | absolute ... Check file:///F:/code/denosaurs/plug/test/abs.ts
Hello from plugin.
zero_copy[0]: test
zero_copy[1]: test
Hello from plugin.
zero_copy[0]: test
zero_copy[1]: test
ok (969ms)

test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out (3165ms)

Support for downloading archives

In certain cases, often involving dll hell or just downloading associated data and assets it would be nice to be able to specify a download for an archive and automatically unwrap it and cache the unwrapped contents then deleting the original archive to save space.

Formats with planned support:

  • zip
  • tar

Formats which may be supported if there is a need for it:

  • 7z
  • rar

Support for downloading compressed files

Support for downloading compressed files in addition to archives (#25) would allow users to greatly decrease memory bandwidth and improve download times.

Formats with planned support:

  • lz4
  • gzip

Formats which may be supported if there is a need for it:

  • brotli
  • zlib
  • deflate

download PermissionDenied. make file writable after copy to cache

plug/download.ts

Lines 255 to 259 in 7e85fa9

case "file:": {
console.log(`${colors.green("Copying")} ${url}`);
await Deno.copyFile(fromFileUrl(url), cacheFilePath);
break;
}

when the source file is read-only (chmod 0555)
then the cached file is also read-only

future calls to download fail
because the target file in cache is read-only

first call:

Copying file:///tmp/tmp.aGowOqCn9e/vscode/vscode-deno/libwebview.so

second call:

Copying file:///tmp/tmp.aGowOqCn9e/vscode/vscode-deno/libwebview.so
error: Uncaught (in promise) PermissionDenied: Permission denied (os error 13), copy '/tmp/tmp.aGowOqCn9e/vscode/vscode-deno/libwebview.so' -> '/home/user/.cache/deno/plug/file/a8eb18dc8f0f8199d82db2f57b5f04a3f527e44095eca509c3960f4760b36e4e.so'
        await Deno.copyFile(fromFileUrl(url), cacheFilePath);
        ^
    at async Object.copyFile (deno:runtime/js/30_fs.js:64:5)
    at async download (https://deno.land/x/[email protected]/download.ts:257:9)
    at async dlopen (https://deno.land/x/[email protected]/mod.ts:145:22)
    at async file:///tmp/tmp.aGowOqCn9e/vscode/vscode-deno/webview_deno/src/ffi.ts:154:20

called from https://deno.land/x/webview

discuss: should preserve the execution bit of the original file? or just chmod 0644 all files?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.