@rubriclab/bunl 0.0.9 → 0.0.11

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
@@ -2,32 +2,64 @@
2
2
 
3
3
  ## A Bun WebSocket re-write of LocalTunnel
4
4
 
5
+ ### Usage
6
+
5
7
  To try it:
6
8
 
7
9
  ```bash
8
10
  bun x bunl -p 3000 -d dev.rubric.me -s my-name
9
11
  ```
10
12
 
13
+ ### Development
14
+
11
15
  To install dependencies:
12
16
 
13
17
  ```bash
14
18
  bun i
15
19
  ```
16
20
 
21
+ To run the server:
22
+
23
+ ```bash
24
+ bun server
25
+ ```
26
+
27
+ (Optional) to run a dummy process on localhost:3000:
28
+
29
+ ```bash
30
+ bun demo
31
+ ```
32
+
17
33
  To run the client:
18
34
 
19
35
  ```bash
20
- bun lt
36
+ bun client -p 3000
21
37
  ```
22
38
 
23
- To run the server:
39
+ With full args:
24
40
 
25
41
  ```bash
26
- bun server
42
+ bun client --port 3000 --domain localhost:1234 --subdomain my-subdomain
27
43
  ```
28
44
 
29
- To run a dummy server on localhost:3000:
45
+ ### [WIP] Deployment
46
+
47
+ To build the client code:
30
48
 
31
49
  ```bash
32
- bun demo
50
+ bun run build
33
51
  ```
52
+
53
+ To deploy the server, for example on [Fly](https://fly.io):
54
+
55
+ ```bash
56
+ fly launch && fly deploy
57
+ ```
58
+
59
+ Making sure to set `DOMAIN` to your domain:
60
+
61
+ ```bash
62
+ fly secrets set DOMAIN=example.so
63
+ ```
64
+
65
+ Open to PRs!
package/build/client.js CHANGED
@@ -1,4 +1,5 @@
1
- #! /usr/bin/env node
1
+ #! /usr/bin/env bun
2
+ // client.ts
2
3
  import { parseArgs } from "util";
3
4
  async function main({ url, domain, subdomain }) {
4
5
  const serverUrl = `ws://${domain || "localhost:1234"}?new${
@@ -14,14 +15,11 @@ async function main({ url, domain, subdomain }) {
14
15
  headers: data.headers,
15
16
  })
16
17
  .then((res) => res.text())
17
- .then((res) => {
18
- socket.send(res);
19
- });
18
+ .then((res) => socket.send(res));
20
19
  }
21
20
  });
22
21
  socket.addEventListener("open", (event) => {
23
- console.log("socket ready:", !!event.target.readyState);
24
- socket.ping();
22
+ if (!event.target.readyState) throw "Not ready";
25
23
  });
26
24
  }
27
25
  var { values } = parseArgs({
@@ -43,7 +41,7 @@ var { values } = parseArgs({
43
41
  },
44
42
  allowPositionals: true,
45
43
  });
46
- if (!values.port) throw "pass --port 3000";
44
+ if (!values.port) throw "pass -p 3000";
47
45
  main({
48
46
  url: `localhost:${values.port}`,
49
47
  domain: values.domain,
package/client.ts CHANGED
@@ -24,15 +24,12 @@ async function main({
24
24
  headers: data.headers,
25
25
  })
26
26
  .then((res) => res.text())
27
- .then((res) => {
28
- socket.send(res);
29
- });
27
+ .then((res) => socket.send(res));
30
28
  }
31
29
  });
32
30
 
33
31
  socket.addEventListener("open", (event) => {
34
- console.log("socket ready:", !!(event.target as any).readyState);
35
- socket.ping();
32
+ if (!(event.target as any).readyState) throw "Not ready";
36
33
  });
37
34
  }
38
35
 
@@ -60,7 +57,7 @@ const { values } = parseArgs({
60
57
  allowPositionals: true,
61
58
  });
62
59
 
63
- if (!values.port) throw "pass --port 3000";
60
+ if (!values.port) throw "pass -p 3000";
64
61
 
65
62
  main({
66
63
  url: `localhost:${values.port}`,
package/package.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "bin": {
3
- "bunl": "./build/client.js"
3
+ "bunl": "build/client.js"
4
4
  },
5
5
  "name": "@rubriclab/bunl",
6
6
  "description": "expose localhost to the world",
7
- "version": "0.0.9",
7
+ "version": "0.0.11",
8
8
  "license": "MIT",
9
9
  "repository": {
10
10
  "type": "git",
11
- "url": "https://github.com/RubricLab/bunl.git"
11
+ "url": "git+https://github.com/RubricLab/bunl.git"
12
12
  },
13
13
  "dependencies": {
14
14
  "human-id": "^4.1.1"
@@ -16,11 +16,12 @@
16
16
  "devDependencies": {
17
17
  "@types/bun": "latest"
18
18
  },
19
- "main": "./build/client.js",
19
+ "main": "build/client.js",
20
20
  "scripts": {
21
- "server": "bun --hot server.ts",
22
- "lt": "bun --hot client.ts",
23
- "demo": "bun --hot demo.ts"
21
+ "server": "bun server.ts",
22
+ "client": "bun --hot client.ts",
23
+ "demo": "bun --hot demo.ts",
24
+ "build": "BUILD=build/client.js && bun build client.ts --outdir build --target node && echo -e \"#! /usr/bin/env bun\n$(cat $BUILD)\" > $BUILD"
24
25
  },
25
26
  "type": "module",
26
27
  "peerDependencies": {
package/server.ts CHANGED
@@ -4,7 +4,7 @@ import { uid } from "./utils";
4
4
  type Client = { id: string };
5
5
 
6
6
  const port = Bun.env.PORT || 1234;
7
- const protocol = "http";
7
+ const scheme = Bun.env.SCHEME || "http";
8
8
  const domain = Bun.env.DOMAIN || `localhost:${port}`;
9
9
 
10
10
  const clients = new Map<string, ServerWebSocket<Client>>();
@@ -16,17 +16,17 @@ serve<Client>({
16
16
  const reqUrl = new URL(req.url);
17
17
 
18
18
  if (reqUrl.searchParams.has("new")) {
19
- const id = reqUrl.searchParams.get("subdomain") || uid();
19
+ const requested = reqUrl.searchParams.get("subdomain");
20
+ const id = requested && !clients.has(requested) ? requested : uid();
20
21
  const upgraded = server.upgrade(req, { data: { id } });
21
22
  if (upgraded) return;
22
- else return new Response("Upgrade failed :(", { status: 500 });
23
+ else return new Response("upgrade failed", { status: 500 });
23
24
  }
24
25
 
25
26
  const subdomain = reqUrl.hostname.split(".")[0];
26
27
 
27
28
  if (!clients.has(subdomain)) {
28
- console.log(`\x1b[31m${subdomain} not found \x1b[0m`);
29
- return new Response("client not found :(", { status: 404 });
29
+ return new Response("client not found", { status: 404 });
30
30
  }
31
31
 
32
32
  // The magic: forward the req to the client
@@ -42,7 +42,7 @@ serve<Client>({
42
42
  let res = clientData.get(subdomain);
43
43
 
44
44
  // Poll every second for the client to respond
45
- // TODO: replace this with a way for the client to trigger this
45
+ // TODO: replace poll with a client-triggered callback
46
46
  while (!res) {
47
47
  await sleep(1000);
48
48
  retries--;
@@ -63,8 +63,7 @@ serve<Client>({
63
63
  clients.set(ws.data.id, ws);
64
64
  ws.send(
65
65
  JSON.stringify({
66
- id: ws.data.id,
67
- url: `${protocol}://${ws.data.id}.${domain}`,
66
+ url: `${scheme}://${ws.data.id}.${domain}`,
68
67
  })
69
68
  );
70
69
  },
@@ -73,7 +72,7 @@ serve<Client>({
73
72
  clientData.set(ws.data.id, message);
74
73
  },
75
74
  close(ws) {
76
- console.log(`closing ${ws.data.id}`);
75
+ console.log("closing", ws.data.id);
77
76
  clients.delete(ws.data.id);
78
77
  },
79
78
  },