UNPKG

one

Version:

One is a React framework for web, iOS, and Android apps.

1 lines • 31.2 kB
{"version":3,"file":"server.js","names":[],"sources":["esm/daemon/server.js"],"sourcesContent":["import * as http from \"node:http\";\nimport * as fs from \"node:fs\";\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport {\n createRegistry,\n findServersByBundleId,\n findServerById,\n getAllServers,\n getRoute,\n setRoute,\n clearRoute,\n touchServer,\n pruneDeadServers,\n checkServerAlive,\n registerServer\n} from \"./registry\";\nimport { createIPCServer, getSocketPath, cleanupSocket, readServerFiles } from \"./ipc\";\nimport { proxyHttpRequest, proxyWebSocket } from \"./proxy\";\nimport { getBootedSimulators, resolvePendingPicker } from \"./picker\";\nimport colors from \"picocolors\";\nconst debugLogPath = path.join(os.homedir(), \".one\", \"daemon-debug.log\");\nfunction debugLog(msg) {\n fs.appendFileSync(debugLogPath, `${(/* @__PURE__ */ new Date()).toISOString()} ${msg}\n`);\n}\nconst serverAppNames = /* @__PURE__ */ new Map();\nsetInterval(() => {\n if (serverAppNames.size > 100) {\n const keys = [...serverAppNames.keys()];\n const toDelete = keys.slice(0, keys.length - 100);\n for (const key of toDelete) {\n serverAppNames.delete(key);\n }\n debugLog(`Pruned ${toDelete.length} stale app name entries`);\n }\n}, 6e5);\nasync function getAppNameForServer(root) {\n const cached = serverAppNames.get(root);\n if (cached) return cached;\n try {\n const appJsonPath = path.join(root, \"app.json\");\n if (fs.existsSync(appJsonPath)) {\n const content = JSON.parse(fs.readFileSync(appJsonPath, \"utf-8\"));\n const name = content.expo?.name || content.name;\n if (name) {\n serverAppNames.set(root, name);\n return name;\n }\n }\n for (const ext of [\"ts\", \"js\"]) {\n const configPath = path.join(root, `app.config.${ext}`);\n if (fs.existsSync(configPath)) {\n const content = fs.readFileSync(configPath, \"utf-8\");\n const nameMatch = content.match(/name:\\s*['\"]([^'\"]+)['\"]/);\n if (nameMatch) {\n const name = nameMatch[1];\n serverAppNames.set(root, name);\n return name;\n }\n }\n }\n const dirName = path.basename(root);\n if (dirName) {\n serverAppNames.set(root, dirName);\n return dirName;\n }\n } catch (err) {\n debugLog(`Failed to get app name for ${root}: ${err}`);\n }\n return null;\n}\nconst clientMappings = /* @__PURE__ */ new Map();\nconst MAPPING_TTL_MS = 36e5;\nsetInterval(() => {\n const now = Date.now();\n let cleaned = 0;\n for (const [key, info] of clientMappings) {\n if (now - info.lastUsed > MAPPING_TTL_MS) {\n clientMappings.delete(key);\n cleaned++;\n }\n }\n if (cleaned > 0) {\n debugLog(`Cleaned ${cleaned} stale mappings`);\n }\n}, 3e4);\nfunction getRouteIdFromCookies(req) {\n const cookieHeader = req.headers.cookie;\n if (!cookieHeader) return null;\n const match = cookieHeader.match(/one-route-id=([^;]+)/);\n return match ? match[1] : null;\n}\nconst pendingMappings = /* @__PURE__ */ new Map();\nfunction setPendingMapping(serverId, simulatorUdid) {\n pendingMappings.set(serverId, simulatorUdid);\n debugLog(\n `Pending mapping: next request to server ${serverId} will map to sim ${simulatorUdid}`\n );\n}\nfunction clearMappingsForSimulator(simulatorUdid) {\n let count = 0;\n for (const [key, info] of clientMappings) {\n if (info.simulatorUdid === simulatorUdid) {\n clientMappings.delete(key);\n count++;\n }\n }\n debugLog(`Cleared ${count} mappings for simulator ${simulatorUdid}`);\n}\nfunction clearAllMappings() {\n const count = clientMappings.size;\n clientMappings.clear();\n debugLog(`Cleared all ${count} client mappings`);\n}\nfunction getSimulatorMappings() {\n const result = /* @__PURE__ */ new Map();\n for (const [_key, info] of clientMappings) {\n if (info.simulatorUdid) {\n result.set(info.simulatorUdid, info.serverId);\n }\n }\n return result;\n}\nfunction setSimulatorMapping(simulatorUdid, serverId) {\n const key = `tui:${simulatorUdid}`;\n clientMappings.set(key, {\n serverId,\n simulatorUdid,\n matchedBy: \"tui\",\n lastUsed: Date.now()\n });\n debugLog(`TUI set mapping: sim=${simulatorUdid} -> server=${serverId}`);\n}\nasync function matchUserAgentToServer(headers, servers) {\n const userAgent = headers[\"user-agent\"];\n if (!userAgent || typeof userAgent !== \"string\") return null;\n const uaAppName = userAgent.split(\"/\")[0];\n if (!uaAppName) return null;\n debugLog(`Trying to match user-agent app \"${uaAppName}\" to servers`);\n for (const server of servers) {\n const appName = await getAppNameForServer(server.root);\n if (!appName) continue;\n const normalizedUa = uaAppName.toLowerCase().replace(/\\s+/g, \"\");\n const normalizedApp = appName.toLowerCase().replace(/\\s+/g, \"\");\n debugLog(` Comparing \"${normalizedUa}\" to server app \"${normalizedApp}\"`);\n if (normalizedUa === normalizedApp || normalizedUa.includes(normalizedApp) || normalizedApp.includes(normalizedUa)) {\n debugLog(` Matched! ${uaAppName} -> ${server.root}`);\n return server;\n }\n }\n return null;\n}\nfunction isGenericExpoAgent(ua) {\n return ua.startsWith(\"Expo/\") || ua.startsWith(\"Exponent/\");\n}\nfunction extractAppNameFromUA(ua) {\n const firstPart = ua.split(\" \")[0] || \"\";\n const appName = firstPart.split(\"/\")[0];\n return appName || null;\n}\nconst recentConnections = /* @__PURE__ */ new Map();\nconst CONNECTION_MEMORY_MS = 5e3;\nsetInterval(() => {\n const now = Date.now();\n let cleaned = 0;\n for (const [key, entry] of recentConnections) {\n if (now - entry.timestamp > CONNECTION_MEMORY_MS) {\n recentConnections.delete(key);\n cleaned++;\n }\n }\n if (cleaned > 0) {\n debugLog(`Cleaned ${cleaned} stale connection mappings`);\n }\n}, 1e4);\nfunction getPrimaryIdentifier(headers) {\n const userAgent = headers[\"user-agent\"] || \"\";\n if (!isGenericExpoAgent(userAgent)) {\n const appName = extractAppNameFromUA(userAgent);\n if (appName) {\n return `app:${appName}`;\n }\n }\n const easClientId = headers[\"eas-client-id\"];\n if (easClientId && typeof easClientId === \"string\") {\n return `eas:${easClientId}`;\n }\n if (userAgent) {\n return `ua:${userAgent}`;\n }\n return null;\n}\nfunction lookupClient(headers) {\n const identifier = getPrimaryIdentifier(headers);\n if (!identifier) {\n return { info: null, identifier: null };\n }\n const info = clientMappings.get(identifier);\n if (info) {\n info.lastUsed = Date.now();\n }\n return { info: info || null, identifier };\n}\nfunction saveClientMapping(identifier, serverId, simulatorUdid, matchedBy) {\n clientMappings.set(identifier, {\n serverId,\n simulatorUdid,\n matchedBy,\n lastUsed: Date.now()\n });\n debugLog(\n `Saved mapping: ${identifier} -> server=${serverId}, sim=${simulatorUdid || \"unknown\"}, via=${matchedBy}`\n );\n}\nconst DEFAULT_PORT = 8081;\nlet routeModeOverride = null;\nfunction setRouteMode(mode) {\n routeModeOverride = mode;\n}\nlet activeDaemonState = null;\nasync function inferSimulator(clientInfo) {\n if (clientInfo?.simulatorUdid) return clientInfo.simulatorUdid;\n const simulators = await getBootedSimulators();\n const existingMappings = getSimulatorMappings();\n const unmappedSims = simulators.filter((s) => !existingMappings.has(s.udid));\n return unmappedSims[0]?.udid || simulators[0]?.udid;\n}\nasync function resolveServer(state, headers, servers, bundleId) {\n const { info: clientInfo, identifier } = lookupClient(headers);\n debugLog(\n `resolveServer: identifier=${identifier}, clientInfo=${JSON.stringify(clientInfo)}`\n );\n const learnMapping = async (server, matchedBy) => {\n if (identifier && !clientInfo?.simulatorUdid) {\n const simUdid = await inferSimulator(clientInfo);\n if (simUdid) {\n saveClientMapping(identifier, server.id, simUdid, matchedBy);\n return true;\n }\n }\n return false;\n };\n if (servers.length === 1) {\n const server = servers[0];\n const learned = await learnMapping(server, \"auto\");\n debugLog(`Single server: ${server.root}`);\n return { server, learned };\n }\n if (pendingMappings.size > 0 && identifier) {\n for (const [serverId, simUdid] of pendingMappings) {\n const server = findServerById(state, serverId);\n if (server && servers.some((s) => s.id === serverId)) {\n debugLog(`TUI pending mapping: ${server.root}, sim=${simUdid}`);\n saveClientMapping(identifier, serverId, simUdid, \"tui\");\n pendingMappings.delete(serverId);\n return { server, learned: true };\n }\n }\n }\n if (clientInfo?.simulatorUdid) {\n const simRoute = getRoute(state, `sim:${clientInfo.simulatorUdid}`);\n if (simRoute) {\n const server = findServerById(state, simRoute.serverId);\n if (server) {\n debugLog(`TUI cable route: sim=${clientInfo.simulatorUdid} -> ${server.root}`);\n return { server, learned: false };\n }\n }\n }\n if (clientInfo?.serverId) {\n const server = findServerById(state, clientInfo.serverId);\n if (server) {\n debugLog(`Cached mapping: ${identifier} -> ${server.root}`);\n return { server, learned: false };\n }\n }\n const userAgent = headers[\"user-agent\"] || \"\";\n if (!isGenericExpoAgent(userAgent)) {\n const matchedServer = await matchUserAgentToServer(headers, servers);\n if (matchedServer) {\n debugLog(`UA match: ${extractAppNameFromUA(userAgent)} -> ${matchedServer.root}`);\n await learnMapping(matchedServer, \"user-agent\");\n return { server: matchedServer, learned: true };\n }\n }\n const routeKey = bundleId || \"default\";\n const fallbackRoute = getRoute(state, bundleId || \"\") || getRoute(state, \"default\");\n if (fallbackRoute) {\n const server = findServerById(state, fallbackRoute.serverId);\n if (server) {\n debugLog(`Fallback route: ${server.root}`);\n await learnMapping(server, \"auto\");\n return { server, learned: true };\n }\n }\n const mostRecent = [...servers].sort((a, b) => b.registeredAt - a.registeredAt)[0];\n debugLog(`Most recent fallback: ${mostRecent.root}`);\n setRoute(state, routeKey, mostRecent.id);\n await learnMapping(mostRecent, \"auto\");\n return { server: mostRecent, learned: true };\n}\nfunction proxyAndTouch(req, res, server) {\n const pendingSimId = pendingMappings.get(server.id);\n if (pendingSimId) {\n const identifier = getPrimaryIdentifier(req.headers);\n if (identifier) {\n saveClientMapping(identifier, server.id, pendingSimId, \"tui\");\n pendingMappings.delete(server.id);\n }\n }\n if (activeDaemonState) {\n touchServer(activeDaemonState, server.id);\n }\n proxyHttpRequest(req, res, server);\n}\nasync function startDaemon(options = {}) {\n const port = options.port || DEFAULT_PORT;\n const host = options.host || \"0.0.0.0\";\n const quiet = options.quiet || false;\n const log = quiet ? (..._args) => {\n } : console.log;\n const state = createRegistry();\n activeDaemonState = state;\n const persistedServers = readServerFiles();\n for (const ps of persistedServers) {\n const alive = await checkServerAlive({ port: ps.port });\n if (alive) {\n registerServer(state, {\n port: ps.port,\n bundleId: ps.bundleId,\n root: ps.root\n });\n log(colors.cyan(`[daemon] Recovered server: ${ps.bundleId} \\u2192 :${ps.port}`));\n }\n }\n const ipcServer = createIPCServer(\n state,\n (id) => {\n const server = findServerById(state, id);\n if (server) {\n const shortRoot = server.root.replace(process.env.HOME || \"\", \"~\");\n log(\n colors.green(\n `[daemon] Server registered: ${server.bundleId} \\u2192 :${server.port} (${shortRoot})`\n )\n );\n }\n },\n (id) => {\n log(colors.yellow(`[daemon] Server unregistered: ${id}`));\n }\n );\n const httpServer = http.createServer(async (req, res) => {\n debugLog(`${req.method} ${req.url}`);\n if (req.url?.startsWith(\"/__daemon\")) {\n await handleDaemonEndpoint(req, res, state);\n return;\n }\n const url = new URL(req.url || \"/\", `http://${req.headers.host}`);\n const bundleId = url.searchParams.get(\"app\");\n const servers = bundleId ? findServersByBundleId(state, bundleId) : getAllServers(state);\n if (servers.length === 0) {\n res.writeHead(404);\n res.end(bundleId ? `No server for app: ${bundleId}` : \"No servers registered\");\n return;\n }\n const { server } = await resolveServer(state, req.headers, servers, bundleId);\n res.setHeader(\"Set-Cookie\", `one-route-id=${server.id}; Path=/; Max-Age=3600`);\n const remotePort = req.socket?.remotePort;\n if (remotePort) {\n recentConnections.set(remotePort, { serverId: server.id, timestamp: Date.now() });\n debugLog(`HTTP: port ${remotePort} -> ${server.root}`);\n }\n proxyAndTouch(req, res, server);\n });\n httpServer.on(\"upgrade\", async (req, rawSocket, head) => {\n const socket = rawSocket;\n const url = new URL(req.url || \"/\", `http://${req.headers.host}`);\n const bundleId = url.searchParams.get(\"app\");\n const servers = bundleId ? findServersByBundleId(state, bundleId) : getAllServers(state);\n if (servers.length === 0) {\n socket.end(\"HTTP/1.1 404 Not Found\\r\\n\\r\\n\");\n return;\n }\n let server;\n const routeIdFromCookie = getRouteIdFromCookies(req);\n if (routeIdFromCookie) {\n server = findServerById(state, routeIdFromCookie);\n if (server && servers.some((s) => s.id === server.id)) {\n debugLog(`WebSocket: cookie route -> ${server.root}`);\n } else {\n server = void 0;\n }\n }\n if (!server) {\n const remotePort = req.socket?.remotePort;\n if (remotePort) {\n const recent = recentConnections.get(remotePort);\n if (recent && Date.now() - recent.timestamp < CONNECTION_MEMORY_MS) {\n server = findServerById(state, recent.serverId);\n if (server) {\n debugLog(`WebSocket: port ${remotePort} matched to ${server.root}`);\n }\n }\n }\n }\n if (!server) {\n const result = await resolveServer(state, req.headers, servers, bundleId);\n server = result.server;\n debugLog(`WebSocket: fallback -> ${server.root}`);\n }\n touchServer(state, server.id);\n proxyWebSocket(req, socket, head, server);\n });\n httpServer.listen(port, host, () => {\n log(colors.cyan(\"\\n\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\"));\n log(colors.cyan(\" one daemon\"));\n log(colors.cyan(\"\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\"));\n log(\n `\n Listening on ${colors.green(`http://${host === \"0.0.0.0\" ? \"localhost\" : host}:${port}`)}`\n );\n log(` IPC socket: ${colors.dim(getSocketPath())}`);\n log(\"\");\n log(colors.dim(\" Waiting for dev servers to register...\"));\n log(colors.dim(\" Run 'one dev' in your project directories\"));\n log(\"\");\n });\n const HEALTH_CHECK_INTERVAL = 5e3;\n const healthCheckInterval = setInterval(async () => {\n const prunedCount = await pruneDeadServers(state, (server) => {\n log(\n colors.yellow(\n `[daemon] Pruned dead server: ${server.bundleId} (port ${server.port})`\n )\n );\n });\n if (prunedCount > 0) {\n log(colors.dim(`[daemon] Pruned ${prunedCount} dead server(s)`));\n }\n }, HEALTH_CHECK_INTERVAL);\n const shutdown = () => {\n log(colors.yellow(\"\\n[daemon] Shutting down...\"));\n clearInterval(healthCheckInterval);\n httpServer.close();\n ipcServer.close();\n cleanupSocket();\n process.exit(0);\n };\n process.on(\"SIGINT\", shutdown);\n process.on(\"SIGTERM\", shutdown);\n return {\n httpServer,\n ipcServer,\n state,\n shutdown,\n healthCheckInterval\n };\n}\nasync function handleDaemonEndpoint(req, res, state) {\n const url = new URL(req.url || \"/\", `http://${req.headers.host}`);\n if (url.pathname === \"/__daemon/status\") {\n const servers = getAllServers(state);\n const simulators = await getBootedSimulators();\n const simMappings = getSimulatorMappings();\n const simulatorRoutes = {};\n for (const [udid, serverId] of simMappings) {\n simulatorRoutes[udid] = serverId;\n }\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(\n JSON.stringify(\n {\n servers: servers.map((s) => ({\n id: s.id,\n port: s.port,\n bundleId: s.bundleId,\n root: s.root\n })),\n simulators,\n simulatorRoutes,\n routeMode: routeModeOverride || \"most-recent\"\n },\n null,\n 2\n )\n );\n return;\n }\n if (url.pathname === \"/__daemon/route\" && req.method === \"POST\") {\n const bundleId = url.searchParams.get(\"bundleId\");\n const serverId = url.searchParams.get(\"serverId\");\n if (!bundleId || !serverId) {\n res.writeHead(400);\n res.end(\"Missing bundleId or serverId\");\n return;\n }\n const server = findServerById(state, serverId);\n if (!server) {\n res.writeHead(404);\n res.end(\"Server not found\");\n return;\n }\n setRoute(state, bundleId, serverId);\n resolvePendingPicker(bundleId, serverId);\n res.writeHead(200);\n res.end(\"Route set\");\n return;\n }\n if (url.pathname === \"/__daemon/simulator-route\" && req.method === \"POST\") {\n const simulatorUdid = url.searchParams.get(\"simulatorUdid\");\n const serverId = url.searchParams.get(\"serverId\");\n if (!simulatorUdid || !serverId) {\n res.writeHead(400);\n res.end(\"Missing simulatorUdid or serverId\");\n return;\n }\n const server = findServerById(state, serverId);\n if (!server) {\n res.writeHead(404);\n res.end(\"Server not found\");\n return;\n }\n setSimulatorMapping(simulatorUdid, serverId);\n setPendingMapping(serverId, simulatorUdid);\n setRoute(state, `sim:${simulatorUdid}`, serverId);\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ ok: true }));\n return;\n }\n if (url.pathname === \"/__daemon/simulator-route\" && req.method === \"DELETE\") {\n const simulatorUdid = url.searchParams.get(\"simulatorUdid\");\n if (!simulatorUdid) {\n res.writeHead(400);\n res.end(\"Missing simulatorUdid\");\n return;\n }\n clearMappingsForSimulator(simulatorUdid);\n clearRoute(state, `sim:${simulatorUdid}`);\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ ok: true }));\n return;\n }\n res.writeHead(404);\n res.end(\"Not found\");\n}\nexport {\n clearAllMappings,\n clearMappingsForSimulator,\n getSimulatorMappings,\n setPendingMapping,\n setRouteMode,\n setSimulatorMapping,\n startDaemon\n};\n//# sourceMappingURL=server.js.map\n"],"mappings":"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"}