extism / js-pdk

Write Extism plugins in JavaScript & TypeScript
42 stars 16 forks source link

feat: add typed interface #60

Closed nilslice closed 1 month ago

nilslice commented 2 months ago

UPDATE: This has been tested to ensure it does not break non-bundler JS programs. However, we don't provide any typings for those. Idk enough JS trickery to know if we could supply the type information to the globals (in Rust? as jsDoc?)

~UPDATE: I think this will break non-bundler JS programs though, since all the globals are renamed. Maybe I should re-work this so that maybe there's a container class/object that Http, Vars, Config, etc all live in vs. competing with the previous global names..~

The same import syntax stands, but I've reassigned the globals created in Rust to __$NAME variants in the Typescript, and then wrapped them in renamed classes to export from the library.


If we publish this to a registry, it will enable something like:

import { Host, Http, Var, Config } from '@extism/js-pdk'

export function greet() {
  Var.set("name", "MAYBESteve");
  let extra = new TextEncoder().encode("aaa")
  let decoded = new TextDecoder().decode(extra)
  const res = Http.request({ url: "https://example.com", method: "GET" });
  const name = Var.getString("name") || "unknown";
  const apiKey = Config.get("SOME_API_KEY") || "unknown";
  Host.outputString(`Hello, ${Host.inputString()} (or is it ${name}???) ${decoded} ${new Date().toString()}\n\n${res.body}\n\n ==== KEY: ${apiKey}`);
}

To build:

make
cd examples/bundled
npm run build
extism call ../bundled.wasm greet --input "steve" --wasi --allow-host "*" --config SOME_API_KEY=123456789
nilslice commented 2 months ago

I've added a examples/kitchen-sink plugin to run through a broader set of the PDK API. Noticed that the last chunk in that greet function is broken & unsure why.

const mem = Memory.fromString(
    "Hello, " + body.data + " " + configLastName,
  );

This throws with a not a function error. But as far as I can tell, it is and calls through to the lower-level global Memory exposed from rust pdk.

Repro by running:

make kitchen

(this test is left out of the existing tests, so we'll need to add it to make test once it passes)