#!/usr/bin/env bun import { NativeConnection, Worker } from "@temporalio/worker"; import path from "node:path"; import { createTaskTreeActivities } from "../../internal/tasktree/activities.ts"; import { taskTreeRuntime } from "../../internal/tasktree/runtime.ts"; const runtime = taskTreeRuntime(); if (!runtime.temporalAddress) throw new Error("TASKTREE_TEMPORAL_ADDRESS is required"); await runtime.store.ensureSchema(); const connection = await NativeConnection.connect({ address: runtime.temporalAddress }); const worker = await Worker.create({ connection, namespace: runtime.temporalNamespace, taskQueue: runtime.taskQueue, workflowsPath: path.resolve(import.meta.dir, "../../internal/tasktree/workflows.ts"), activities: createTaskTreeActivities(runtime.store) }); const healthPort = Number.parseInt(process.env.TASKTREE_WORKER_HEALTH_PORT || "6674", 10); const health = Bun.serve({ hostname: process.env.TASKTREE_WORKER_HEALTH_HOST || "0.0.0.0", port: healthPort, fetch(request) { const pathname = new URL(request.url).pathname; if (pathname !== "/health/live" && pathname !== "/health/ready") return Response.json({ ok: false, error: "not_found" }, { status: 404 }); return Response.json({ ok: true, serviceId: "hwlab-tasktree-worker", namespace: runtime.temporalNamespace, taskQueue: runtime.taskQueue }); } }); process.stdout.write(`${JSON.stringify({ serviceId: "hwlab-tasktree-worker", status: "started", namespace: runtime.temporalNamespace, taskQueue: runtime.taskQueue })}\n`); for (const signal of ["SIGINT", "SIGTERM"] as const) process.once(signal, () => worker.shutdown()); try { await worker.run(); } finally { health.stop(true); await connection.close(); await runtime.store.close(); process.stdout.write(`${JSON.stringify({ serviceId: "hwlab-tasktree-worker", status: "stopped" })}\n`); }