refactor: port backend and frontend to TypeScript classes (bun + vite)
Build and Publish / Metadata (push) Successful in 4s
Build and Publish / BuildAndDeployAmd64 (push) Successful in 14s
eventsourced-ai live check live check

Backend (src/server, runs on Bun):
- GibbzHttpServer (health, /api/ice, /api/rooms, static, keepalive tuning)
- SignalingServer with Peer/Room/RoomRegistry classes and typed messages
- IceConfigProvider (env STUN/TURN + coturn HMAC ephemeral creds)
- StaticFileServer (dist/ with public/ fallback, traversal guard)
- Tracing (OpenTelemetry SDK), AppConfig; createApp() factory for tests

Frontend (src/client, built by Vite):
- VoiceApp orchestrator implementing VoiceAppContext
- WebRtcManager + PeerSession (perfect negotiation, pc rebuild, quality monitor)
- SignalingClient + ReconnectController, AudioManager, SpatialAudio,
  Microphone/ScreenShare controllers, ScreensUi/RosterUi/SpatialMap/
  SpeakingMonitor, Settings/Welcome dialogs, LayoutManager, MatrixChat

Tooling: bun scripts (dev/start/test/typecheck), vite.config.ts root
src/client with publicDir public/static, vitest-config for CI-less runs,
bun-based Dockerfile (oven/bun:1), Makefile + README updated, legacy
server.js/tracing.js/test.js/public js removed.

Verified locally: tsc --noEmit clean, vitest run 6/6 green, vite build ok,
server smoke-tested serving dist + signaling endpoints under Node. Local
bun binary segfaults (SIGILL) on this host, so 'bun test' itself was not
executable here; tests are vitest-API compatible which bun test maps.
This commit is contained in:
developer committed 2026-09-24 07:43:04 +00:00
1 parent 9b8c2a9599
commit 2b950e4953
48 files changed
+4589 -9200

No files matched your search

+75
View File
@@ -0,0 +1,75 @@
// OpenTelemetry tracing and logging initialization for the gibbz backend.
// Loaded before HTTP / network modules start serving traffic.
import process from 'node:process';
import { NodeSDK } from '@opentelemetry/sdk-node';
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
import { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-http';
import { BatchLogRecordProcessor } from '@opentelemetry/sdk-logs';
import { resourceFromAttributes } from '@opentelemetry/resources';
import { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION } from '@opentelemetry/semantic-conventions';
export class Tracing {
private sdk: NodeSDK | undefined;
start(
env: Record<string, string | undefined> = process.env,
onFatal?: (err: unknown) => void,
): void {
const serviceName = env.OTEL_SERVICE_NAME || 'gibbz';
const serviceRelease = env.SERVICE_RELEASE || env.OTEL_SERVICE_RELEASE || env.APP_RELEASE || 'dev';
const environment = env.ENVIRONMENT || env.NODE_ENV || 'production';
const otelUrl = (env.OTEL_EXPORTER_OTLP_ENDPOINT || env.OTEL_URL || 'https://otel.k6n.net').replace(/\/+$/, '');
const ingestKey = env.OTEL_INGEST_KEY || '';
const headers: Record<string, string> = {};
if (ingestKey) headers['X-Otel-Ingest-Key'] = ingestKey;
const resource = resourceFromAttributes({
[ATTR_SERVICE_NAME]: serviceName,
[ATTR_SERVICE_VERSION]: serviceRelease,
'service.release': serviceRelease,
'service.environment': environment,
});
const sdk = new NodeSDK({
resource,
traceExporter: new OTLPTraceExporter({ url: `${otelUrl}/v1/traces`, headers }),
logRecordProcessor: new BatchLogRecordProcessor({
exporter: new OTLPLogExporter({ url: `${otelUrl}/v1/logs`, headers }),
}),
instrumentations: [
getNodeAutoInstrumentations({
'@opentelemetry/instrumentation-fs': { enabled: false },
}),
],
});
this.sdk = sdk;
try {
sdk.start();
console.log(
`[otel] Initialized OpenTelemetry for ${serviceName} (release: ${serviceRelease}, env: ${environment}) -> ${otelUrl}`,
);
} catch (err) {
console.error('[otel] Failed to start OpenTelemetry SDK:', err);
onFatal?.(err);
}
process.on('SIGTERM', () => {
this.shutdown()
.then(() => {
console.log('[otel] SDK shut down successfully');
process.exit(0);
})
.catch((err) => {
console.error('[otel] Error shutting down SDK', err);
process.exit(0);
});
});
}
async shutdown(): Promise<void> {
await this.sdk?.shutdown();
}
}