bvisor 0.0.1 → 0.0.2

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 CHANGED
@@ -7,6 +7,21 @@ Node.js bindings for bVisor. Linux only.
7
7
  Requires: Zig 0.16+, Docker
8
8
 
9
9
  ```bash
10
- npm run dev # builds native binaries (zig build), then runs test.ts in a linux container
10
+ # Build native binaries (zig build), then run test.ts in a linux container
11
+ npm run dev
12
+ ```
13
+
14
+ ```bash
15
+ # Install the latest published bvisor and run test.ts in a linux container
16
+ npm run test:published
17
+ ```
18
+
19
+ ## Publishing
20
+
21
+ Bump versions across all packages, then publish:
22
+
23
+ ```bash
24
+ bun run version:patch
25
+ bun publish --access public
11
26
  ```
12
27
 
package/index.ts ADDED
@@ -0,0 +1 @@
1
+ export { Sandbox } from "./src/sandbox";
package/package.json CHANGED
@@ -1,25 +1,39 @@
1
1
  {
2
2
  "name": "bvisor",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
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",
11
19
  "prepublishOnly": "npm run build",
12
20
  "predev": "cd ../../.. && zig build",
13
- "dev": "docker run --rm -v .:/app -w /app oven/bun:alpine sh -c 'bun install && bun test.ts'"
21
+ "dev": "docker run --rm -v .:/app -w /app oven/bun:alpine sh -c 'bun install && bun test.ts'",
22
+ "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'",
23
+ "version:patch": "npm version patch --workspaces --no-git-tag-version --force && npm version patch --no-git-tag-version --force",
24
+ "publish:all": "bun publish --access public && 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"
14
25
  },
26
+ "workspaces": [
27
+ "platforms/*"
28
+ ],
15
29
  "dependencies": {
16
30
  "detect-libc": "^2.0.3"
17
31
  },
18
32
  "optionalDependencies": {
19
- "@bvisor/linux-arm64-musl": "0.0.1",
20
- "@bvisor/linux-arm64-gnu": "0.0.1",
21
- "@bvisor/linux-x64-musl": "0.0.1",
22
- "@bvisor/linux-x64-gnu": "0.0.1"
33
+ "@bvisor/linux-arm64-musl": "0.0.2",
34
+ "@bvisor/linux-arm64-gnu": "0.0.2",
35
+ "@bvisor/linux-x64-musl": "0.0.2",
36
+ "@bvisor/linux-x64-gnu": "0.0.2"
23
37
  },
24
38
  "devDependencies": {
25
39
  "@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
+ }