Skip to content

Commit

Permalink
feat(server): basic implementation of server runtime and SDK
Browse files Browse the repository at this point in the history
  • Loading branch information
nekomeowww committed Jan 15, 2025
1 parent 6161477 commit 65aef1d
Show file tree
Hide file tree
Showing 18 changed files with 514 additions and 259 deletions.
2 changes: 2 additions & 0 deletions cspell.config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ words:
- bumpp
- cientos
- composables
- crossws
- csmmap
- csmvector
- cubismbreath
Expand Down Expand Up @@ -50,6 +51,7 @@ words:
- Kawaii
- kwaa
- libsodium
- listhen
- live2dcubismcore
- live2dcubismframework
- Llmmarker
Expand Down
13 changes: 10 additions & 3 deletions packages/server-runtime/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"type": "module",
"version": "0.1.1",
"private": false,
"description": "Server runtime and utility implementation for Airi running in different environments",
"description": "Server runtime implementation for Airi running in different environments",
"author": {
"name": "Neko Ayaka",
"email": "[email protected]",
Expand All @@ -30,9 +30,16 @@
"dist",
"package.json"
],
"scripts": {},
"scripts": {
"dev": "listhen -w --ws --port 6121 ./src/index.ts",
"start": "listhen --ws --port 6121 ./src/index.ts"
},
"dependencies": {
"@guiiai/logg": "^1.0.6",
"@proj-airi/server-shared": "workspace:^",
"crossws": "^0.3.1",
"defu": "^6.1.4",
"h3": "^1.13.1"
"h3": "^1.13.1",
"listhen": "^1.9.0"
}
}
45 changes: 33 additions & 12 deletions packages/server-runtime/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,38 @@
// Import h3 as npm dependency
import { createApp, createRouter, defineEventHandler } from 'h3'
import type { WebSocketEvent } from '@proj-airi/server-shared/types'
import { Format, LogLevel, setGlobalFormat, setGlobalLogLevel, useLogg } from '@guiiai/logg'
import { createApp, createRouter, defineWebSocketHandler } from 'h3'

// Create an app instance
export const app = createApp()
setGlobalFormat(Format.Pretty)
setGlobalLogLevel(LogLevel.Log)

const appLogger = useLogg('App').useGlobalConfig()
const websocketLogger = useLogg('WebSocket').useGlobalConfig()

export const app = createApp({
onError: error => appLogger.withError(error).error('an error occurred'),
})

// Create a new router and register it in app
const router = createRouter()
app.use(router)

// Add a new route that matches GET requests to / path
router.get(
'/',
defineEventHandler(() => {
return { message: '⚡️ Tadaa!' }
}),
)
router.get('/ws', defineWebSocketHandler({
open: (peer) => {
websocketLogger.withFields({ peer: peer.id }).log('connected')
},
message: (peer, message) => {
const event = message.json() as WebSocketEvent

websocketLogger.withFields({ peer: peer.id, message: event }).log('received message')
switch (event.type) {
case 'input:voice:discord:transcription':
websocketLogger.withFields({ message: event }).log('transcribed')
break
}
},
error: (peer, error) => {
websocketLogger.withFields({ peer: peer.id }).withError(error).error('an error occurred')
},
close: (peer, details) => {
websocketLogger.withFields({ peer: peer.id, details }).log('closed')
},
}))
43 changes: 43 additions & 0 deletions packages/server-sdk/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
"name": "@proj-airi/server-sdk",
"type": "module",
"version": "0.1.1",
"private": false,
"description": "Client-side SDK implementation for connecting to Airi server components and runtimes",
"author": {
"name": "Neko Ayaka",
"email": "[email protected]",
"url": "https://github.com/nekomeowww"
},
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/moeru-ai/airi.git",
"directory": "packages/server-sdk"
},
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.mjs",
"require": "./dist/index.cjs"
}
},
"main": "./dist/index.cjs",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"files": [
"README.md",
"dist",
"package.json"
],
"scripts": {
"dev": "pnpm run stub",
"stub": "unbuild --stub",
"build": "unbuild",
"package:publish": "pnpm build && pnpm publish --access public --no-git-checks"
},
"dependencies": {
"@proj-airi/server-shared": "workspace:^",
"crossws": "^0.3.1"
}
}
19 changes: 19 additions & 0 deletions packages/server-sdk/src/client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import type { WebSocketEvent } from '@proj-airi/server-shared/types'
import type { Blob } from 'node:buffer'
import WebSocket from 'crossws/websocket'

export class Client {
private websocket: WebSocket

constructor(url: string) {
this.websocket = new WebSocket(url)
}

send(data: WebSocketEvent): void {
this.websocket.send(JSON.stringify(data))
}

sendRaw(data: string | ArrayBufferLike | Blob | ArrayBufferView): void {
this.websocket.send(data)
}
}
1 change: 1 addition & 0 deletions packages/server-sdk/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './client'
18 changes: 18 additions & 0 deletions packages/server-sdk/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"compilerOptions": {
"target": "ESNext",
"lib": [
"ESNext"
],
"module": "ESNext",
"moduleResolution": "bundler",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"isolatedModules": true,
"verbatimModuleSyntax": true,
"skipLibCheck": true
},
"include": [
"src/**/*.ts"
]
}
42 changes: 42 additions & 0 deletions packages/server-shared/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
"name": "@proj-airi/server-shared",
"type": "module",
"version": "0.1.1",
"private": false,
"description": "Server shared types, utilities for Airi server components and runtimes",
"author": {
"name": "Neko Ayaka",
"email": "[email protected]",
"url": "https://github.com/nekomeowww"
},
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/moeru-ai/airi.git",
"directory": "packages/server-shared"
},
"exports": {
"./types": {
"types": "./dist/types/index.d.ts",
"import": "./dist/types/index.mjs",
"require": "./dist/types/index.cjs"
}
},
"main": "./dist/types/index.cjs",
"module": "./dist/types/index.mjs",
"types": "./dist/types/index.d.ts",
"files": [
"README.md",
"dist",
"package.json"
],
"scripts": {
"dev": "pnpm run stub",
"stub": "unbuild --stub",
"build": "unbuild",
"package:publish": "pnpm build && pnpm publish --access public --no-git-checks"
},
"dependencies": {
"crossws": "^0.3.1"
}
}
Empty file.
1 change: 1 addition & 0 deletions packages/server-shared/src/types/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './websocket'
24 changes: 24 additions & 0 deletions packages/server-shared/src/types/websocket/events.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
export interface WebSocketBaseEvent<T, D> {
type: T
data: D
}

// Thanks to:
//
// A little hack for creating extensible discriminated unions : r/typescript
// https://www.reddit.com/r/typescript/comments/1064ibt/a_little_hack_for_creating_extensible/
export interface WebSocketEvents {
'module:announce': {
name: string
}
'input:voice:discord:transcription': {
text: string
username: string
userDisplayName: string
userId: string
}
}

export type WebSocketEvent = {
[K in keyof WebSocketEvents]: WebSocketBaseEvent<K, WebSocketEvents[K]>;
}[keyof WebSocketEvents]
1 change: 1 addition & 0 deletions packages/server-shared/src/types/websocket/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './events'
18 changes: 18 additions & 0 deletions packages/server-shared/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"compilerOptions": {
"target": "ESNext",
"lib": [
"ESNext"
],
"module": "ESNext",
"moduleResolution": "bundler",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"isolatedModules": true,
"verbatimModuleSyntax": true,
"skipLibCheck": true
},
"include": [
"src/**/*.ts"
]
}
Loading

0 comments on commit 65aef1d

Please sign in to comment.