Skip to content

Commit

Permalink
Bun Websockets starter
Browse files Browse the repository at this point in the history
  • Loading branch information
dayblox committed Sep 30, 2023
0 parents commit 8f50655
Show file tree
Hide file tree
Showing 13 changed files with 202 additions and 0 deletions.
23 changes: 23 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: CI

on:
push:
branches: main
pull_request:

jobs:
my-job:
name: Test
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3

- name: Setup Bun
uses: oven-sh/setup-bun@v1

- name: Install dependencies
run: bun i -p --frozen-lockfile

- name: Run tests
run: bun test
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Dependencies
/node_modules

# Environment variables
/.env*
3 changes: 3 additions & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"recommendations": ["biomejs.biome", "oven.bun-vscode"]
}
13 changes: 13 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"version": "0.2.0",
"configurations": [
{
"internalConsoleOptions": "openOnSessionStart",
"name": "Debug",
"program": "${workspaceFolder}/src/index.ts",
"request": "launch",
"type": "bun",
"watchMode": "hot"
}
]
}
7 changes: 7 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"editor.codeActionsOnSave": {
"source.organizeImports": "always"
},
"editor.defaultFormatter": "biomejs.biome",
"editor.formatOnSave": true
}
52 changes: 52 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Bun Websockets

A simple WebSocket server to get started using Bun.

![](../../actions/workflows/ci.yml/badge.svg)

[![](https://railway.app/button.svg)](https://railway.app/template/G3k1Tv?referralCode=bonus)

## Prerequisites

- [<img src="https://github-production-user-asset-6210df.s3.amazonaws.com/17180392/266803654-ac5f086c-71ec-493a-a377-784cec2dc525.svg" height=19.2 align=center /> Bun](https://bun.sh/) `>=1.0.0`
- [All-in-one toolkit](https://bun.sh/blog/bun-v1.0#bun-is-an-all-in-one-toolkit)
- [JavaScript runtime](https://bun.sh/blog/bun-v1.0#bun-is-a-javascript-runtime)
- [Package manager](https://bun.sh/blog/bun-v1.0#bun-is-a-package-manager)
- [Test runner](https://bun.sh/blog/bun-v1.0#bun-is-a-test-runner)
- [Bundler](https://bun.sh/blog/bun-v1.0#bun-is-a-bundler)

## Getting Started

1. **[Deploy on Railway](https://railway.app/template/G3k1Tv?referralCode=bonus)** or **[use this template](https://github.com/dayblox/bun-ts/generate)**

2. **Clone** the repository

3. **Install** dependencies

```sh
bun i
```

## Usage

- **Development** mode (**debug**)

`F5`

- Connecting to the Server using a WebSocket client

```sh
bunx wscat -c ws://localhost:3000
```

- Running **tests** (**watch** mode)

```sh
bun test --watch
```

- **Production** mode

```sh
bun src/index.ts
```
8 changes: 8 additions & 0 deletions biome.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"files": { "ignore": ["node_modules/*"] },
"javascript": {
"formatter": {
"semicolons": "asNeeded"
}
}
}
Binary file added bun.lockb
Binary file not shown.
8 changes: 8 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "bun-ts",
"author": "dayblox",
"description": "Bun + TypeScript starter",
"devDependencies": {
"bun-types": "latest"
}
}
7 changes: 7 additions & 0 deletions src/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { describe, expect, test } from "bun:test"

describe("bun env", () => {
test("should alias process env", () => {
expect(Bun.env).toBe(process.env)
})
})
34 changes: 34 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { handleRoom, handleUsername } from "./utils"

const user = {
room: "",
username: "",
}

export type User = typeof user

const server = Bun.serve<User>({
fetch(req, server) {
if (server.upgrade(req, { data: { ...user } })) return
return new Response(null, {
status: 301,
headers: {
Location: "https://github.com/dayblox/bun-ws#readme",
},
})
},
websocket: {
open(ws) {
ws.send("Username:")
},
message(ws, message) {
if (typeof message !== "string") return
if (!ws.data.username) return handleUsername(ws, message)
if (!ws.data.room) return handleRoom(ws, message)
ws.publish(ws.data.room, `${ws.data.username}: ${message}`)
},
close(ws) {
server.publish(ws.data.room, `${ws.data.username} has left the room`)
},
},
})
22 changes: 22 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { ServerWebSocket } from "bun"
import { User } from "."

export function handleUsername(ws: ServerWebSocket<User>, message: string) {
if (!message.length) {
ws.send("Username:")
return
}
ws.data.username = message
ws.send("Room:")
}

export function handleRoom(ws: ServerWebSocket<User>, message: string) {
if (!message.length) {
ws.send("Room:")
return
}
ws.data.room = message
ws.subscribe(ws.data.room)
ws.publish(ws.data.room, `${ws.data.username} has joined the room`)
ws.send(`You joined the '${ws.data.room}' room`)
}
20 changes: 20 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"compilerOptions": {
"allowImportingTsExtensions": true,
"allowJs": true,
"allowSyntheticDefaultImports": true,
"composite": true,
"downlevelIteration": true,
"forceConsistentCasingInFileNames": true,
"jsx": "react-jsx",
"lib": ["ESNext"],
"module": "ESNext",
"moduleDetection": "force",
"moduleResolution": "bundler",
"noEmit": true,
"skipLibCheck": true,
"strict": true,
"target": "ESNext",
"types": ["bun-types"]
}
}

0 comments on commit 8f50655

Please sign in to comment.