bvisor 0.0.1 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -1
- package/index.ts +1 -0
- package/package.json +21 -8
- package/src/napi.ts +5 -0
- package/src/native.ts +23 -0
- package/src/sandbox.ts +60 -0
package/README.md
CHANGED
|
@@ -6,7 +6,23 @@ Node.js bindings for bVisor. Linux only.
|
|
|
6
6
|
|
|
7
7
|
Requires: Zig 0.16+, Docker
|
|
8
8
|
|
|
9
|
+
From the repo root (next to build.zig), run:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
zig build test-node
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
For a targeted test, from this directory, run:
|
|
9
16
|
```bash
|
|
10
|
-
|
|
17
|
+
# Install the latest published bvisor and run test.ts in a linux container
|
|
18
|
+
npm run test:published
|
|
11
19
|
```
|
|
12
20
|
|
|
21
|
+
## Publishing
|
|
22
|
+
|
|
23
|
+
Bump versions across all packages, then publish:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
bun run version:patch
|
|
27
|
+
bun run publish:all
|
|
28
|
+
```
|
package/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Sandbox } from "./src/sandbox";
|
package/package.json
CHANGED
|
@@ -1,25 +1,38 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bvisor",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": {
|
|
8
|
+
"bun": "./index.ts",
|
|
9
|
+
"default": "./dist/index.js"
|
|
10
|
+
}
|
|
11
|
+
},
|
|
6
12
|
"files": [
|
|
7
|
-
"dist/"
|
|
13
|
+
"dist/",
|
|
14
|
+
"index.ts",
|
|
15
|
+
"src/"
|
|
8
16
|
],
|
|
9
17
|
"scripts": {
|
|
10
18
|
"build": "tsc",
|
|
19
|
+
"prebuild": "cd ../../.. && zig build",
|
|
11
20
|
"prepublishOnly": "npm run build",
|
|
12
|
-
"
|
|
13
|
-
"
|
|
21
|
+
"test:published": "docker run --rm -v ./test.ts:/test.ts:ro oven/bun:alpine sh -c 'cd /tmp && echo {} > package.json && bun add bvisor && cp /test.ts . && bun test.ts'",
|
|
22
|
+
"version:patch": "npm version patch --workspaces --no-git-tag-version --force && npm version patch --no-git-tag-version --force",
|
|
23
|
+
"publish:all": "npm run prebuild && cd platforms/linux-arm64-musl && bun publish --access public && cd ../linux-arm64-gnu && bun publish --access public && cd ../linux-x64-musl && bun publish --access public && cd ../linux-x64-gnu && bun publish --access public && cd ../.. && bun publish --access public"
|
|
14
24
|
},
|
|
25
|
+
"workspaces": [
|
|
26
|
+
"platforms/*"
|
|
27
|
+
],
|
|
15
28
|
"dependencies": {
|
|
16
29
|
"detect-libc": "^2.0.3"
|
|
17
30
|
},
|
|
18
31
|
"optionalDependencies": {
|
|
19
|
-
"@bvisor/linux-arm64-musl": "0.0.
|
|
20
|
-
"@bvisor/linux-arm64-gnu": "0.0.
|
|
21
|
-
"@bvisor/linux-x64-musl": "0.0.
|
|
22
|
-
"@bvisor/linux-x64-gnu": "0.0.
|
|
32
|
+
"@bvisor/linux-arm64-musl": "0.0.2",
|
|
33
|
+
"@bvisor/linux-arm64-gnu": "0.0.2",
|
|
34
|
+
"@bvisor/linux-x64-musl": "0.0.2",
|
|
35
|
+
"@bvisor/linux-x64-gnu": "0.0.2"
|
|
23
36
|
},
|
|
24
37
|
"devDependencies": {
|
|
25
38
|
"@types/node": "^25.2.0",
|
package/src/napi.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// Phantom-typed opaque handle to a native object.
|
|
2
|
+
// N-API "externals" are opaque pointers that JS holds but can't inspect.
|
|
3
|
+
// The phantom T prevents accidentally swapping e.g. External<"Sandbox"> and External<"Stream">.
|
|
4
|
+
declare const __external: unique symbol;
|
|
5
|
+
export type External<T> = unknown & { [__external]: T };
|
package/src/native.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { arch, platform } from "os";
|
|
2
|
+
import { familySync, MUSL } from "detect-libc";
|
|
3
|
+
import { External } from "./napi";
|
|
4
|
+
|
|
5
|
+
if (platform() !== "linux") {
|
|
6
|
+
throw new Error("bVisor only supports Linux");
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/** FFI contract: typed interface for the native Zig module loaded via require(). */
|
|
10
|
+
export interface NativeModule {
|
|
11
|
+
createSandbox(): External<"Sandbox">;
|
|
12
|
+
sandboxRunCmd(
|
|
13
|
+
sandbox: External<"Sandbox">,
|
|
14
|
+
command: string
|
|
15
|
+
): {
|
|
16
|
+
stdout: External<"Stream">;
|
|
17
|
+
stderr: External<"Stream">;
|
|
18
|
+
};
|
|
19
|
+
streamNext(stream: External<"Stream">): Uint8Array | null;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const libc = familySync() === MUSL ? "musl" : "gnu";
|
|
23
|
+
export const native: NativeModule = require(`@bvisor/linux-${arch()}-${libc}`);
|
package/src/sandbox.ts
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { External } from "./napi";
|
|
2
|
+
import { native } from "./native";
|
|
3
|
+
|
|
4
|
+
class Stream {
|
|
5
|
+
private ptr: External<"Stream">;
|
|
6
|
+
|
|
7
|
+
constructor(ptr: External<"Stream">) {
|
|
8
|
+
this.ptr = ptr;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
toReadableStream(): ReadableStream<Uint8Array> {
|
|
12
|
+
const self = this;
|
|
13
|
+
return new ReadableStream({
|
|
14
|
+
async pull(controller) {
|
|
15
|
+
// TODO: make streamNext return a promise
|
|
16
|
+
const chunk = native.streamNext(self.ptr);
|
|
17
|
+
if (chunk) {
|
|
18
|
+
controller.enqueue(chunk);
|
|
19
|
+
} else {
|
|
20
|
+
controller.close();
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export class Sandbox {
|
|
28
|
+
private ptr: External<"Sandbox">;
|
|
29
|
+
|
|
30
|
+
constructor() {
|
|
31
|
+
this.ptr = native.createSandbox();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
runCmd(command: string) {
|
|
35
|
+
const result = native.sandboxRunCmd(this.ptr, command);
|
|
36
|
+
return createOutput(
|
|
37
|
+
new Stream(result.stdout).toReadableStream(),
|
|
38
|
+
new Stream(result.stderr).toReadableStream()
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface Output {
|
|
44
|
+
stdoutStream: ReadableStream<Uint8Array>;
|
|
45
|
+
stderrStream: ReadableStream<Uint8Array>;
|
|
46
|
+
stdout: () => Promise<string>;
|
|
47
|
+
stderr: () => Promise<string>;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function createOutput(
|
|
51
|
+
stdoutStream: ReadableStream<Uint8Array>,
|
|
52
|
+
stderrStream: ReadableStream<Uint8Array>
|
|
53
|
+
): Output {
|
|
54
|
+
return {
|
|
55
|
+
stdoutStream,
|
|
56
|
+
stderrStream,
|
|
57
|
+
stdout: () => new Response(stdoutStream).text(),
|
|
58
|
+
stderr: () => new Response(stderrStream).text(),
|
|
59
|
+
};
|
|
60
|
+
}
|