From fae9965bdf2ec26e345389beeacd09cf0bedf709 Mon Sep 17 00:00:00 2001 From: sergeych Date: Sun, 26 Apr 2026 17:23:21 +0300 Subject: [PATCH] fix CLI boostrap of http server --- docs/ai_notes_cli_release.md | 14 ++++++++++++++ docs/ai_stdlib_reference.md | 1 + examples/http_server.lyng | 19 +++++++++++++++++++ lyng/src/commonMain/kotlin/Common.kt | 7 +++++-- .../sergeych/lyng_cli/CliNetworkJvmTest.kt | 2 ++ 5 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 docs/ai_notes_cli_release.md create mode 100644 examples/http_server.lyng diff --git a/docs/ai_notes_cli_release.md b/docs/ai_notes_cli_release.md new file mode 100644 index 0000000..d452bf9 --- /dev/null +++ b/docs/ai_notes_cli_release.md @@ -0,0 +1,14 @@ +# AI notes: publish JVM CLI updates with `bin/local_jrelease` + +[//]: # (excludeFromIndex) + +When a change affects the JVM CLI launcher used as `jlyng`, refresh the installed local distribution with: + +```bash +bin/local_jrelease +``` + +Why: +- `jlyng` in this repo is installed from `~/bin/jlyng-jvm/lyng-jvm`, not directly from `lyng/build/install`. +- Manual copying from Gradle build output can leave the actual launcher on `PATH` stale. +- `bin/local_jrelease` rebuilds `lyng/build/distributions/lyng-jvm.zip`, reinstalls it under `~/bin/jlyng-jvm`, and recreates the `~/bin/jlyng` symlink. diff --git a/docs/ai_stdlib_reference.md b/docs/ai_stdlib_reference.md index 5c51dae..68a858f 100644 --- a/docs/ai_stdlib_reference.md +++ b/docs/ai_stdlib_reference.md @@ -90,6 +90,7 @@ Requires installing `lyngio` into the import manager from host code. - `import lyng.io.process` (process execution API) - `import lyng.io.console` (console capabilities, geometry, ANSI/output, events) - `import lyng.io.http` (HTTP/HTTPS client API) +- `import lyng.io.http.server` (minimal HTTP/1.1 and WebSocket server API) - `import lyng.io.ws` (WebSocket client API; currently supported on JVM, capability-gated elsewhere) - `import lyng.io.net` (TCP/UDP transport API; currently supported on JVM, capability-gated elsewhere) - Shared network value-type packages are also available when installed by host code: diff --git a/examples/http_server.lyng b/examples/http_server.lyng new file mode 100644 index 0000000..250a0f6 --- /dev/null +++ b/examples/http_server.lyng @@ -0,0 +1,19 @@ +import lyng.io.http.server + +closed class CreateUserRequest(name: String, age: Int) +closed class CreateUserResponse(id: Int, name: String, age: Int) + +val server = HttpServer() + +server.postPath("/api/users") { + val req = jsonBody() + + if (req.name.isBlank()) { + respondJson({ error: "name must not be empty" }, 400) + return + } + + respondJson(CreateUserResponse(101, req.name, req.age), 201) +} + +server.listen(8080, "127.0.0.1") diff --git a/lyng/src/commonMain/kotlin/Common.kt b/lyng/src/commonMain/kotlin/Common.kt index f38f28d..120bf1e 100644 --- a/lyng/src/commonMain/kotlin/Common.kt +++ b/lyng/src/commonMain/kotlin/Common.kt @@ -17,8 +17,8 @@ package net.sergeych -import com.github.ajalt.clikt.core.CoreCliktCommand import com.github.ajalt.clikt.core.Context +import com.github.ajalt.clikt.core.CoreCliktCommand import com.github.ajalt.clikt.core.main import com.github.ajalt.clikt.core.subcommands import com.github.ajalt.clikt.parameters.arguments.argument @@ -46,15 +46,16 @@ import net.sergeych.lyng.io.db.jdbc.createJdbcModule import net.sergeych.lyng.io.db.sqlite.createSqliteModule import net.sergeych.lyng.io.fs.createFs import net.sergeych.lyng.io.http.createHttpModule +import net.sergeych.lyng.io.http.server.createHttpServerModule import net.sergeych.lyng.io.net.createNetModule import net.sergeych.lyng.io.ws.createWsModule import net.sergeych.lyng.obj.* import net.sergeych.lyng.pacman.ImportManager -import net.sergeych.lyngio.net.shutdownSystemNetEngine import net.sergeych.lyngio.console.security.PermitAllConsoleAccessPolicy import net.sergeych.lyngio.fs.security.PermitAllAccessPolicy import net.sergeych.lyngio.http.security.PermitAllHttpAccessPolicy import net.sergeych.lyngio.net.security.PermitAllNetAccessPolicy +import net.sergeych.lyngio.net.shutdownSystemNetEngine import net.sergeych.lyngio.ws.security.PermitAllWsAccessPolicy import net.sergeych.mp_tools.globalDefer import okio.* @@ -146,6 +147,7 @@ private fun ImportManager.invalidateCliModuleCaches() { invalidatePackageCache("lyng.io.db.jdbc") invalidatePackageCache("lyng.io.db.sqlite") invalidatePackageCache("lyng.io.http") + invalidatePackageCache("lyng.io.http.server") invalidatePackageCache("lyng.io.ws") invalidatePackageCache("lyng.io.net") } @@ -236,6 +238,7 @@ private fun installCliModules(manager: ImportManager) { createJdbcModule(manager) createSqliteModule(manager) createHttpModule(PermitAllHttpAccessPolicy, manager) + createHttpServerModule(PermitAllNetAccessPolicy, manager) createWsModule(PermitAllWsAccessPolicy, manager) createNetModule(PermitAllNetAccessPolicy, manager) } diff --git a/lyng/src/jvmTest/kotlin/net/sergeych/lyng_cli/CliNetworkJvmTest.kt b/lyng/src/jvmTest/kotlin/net/sergeych/lyng_cli/CliNetworkJvmTest.kt index 973212f..f9e9e85 100644 --- a/lyng/src/jvmTest/kotlin/net/sergeych/lyng_cli/CliNetworkJvmTest.kt +++ b/lyng/src/jvmTest/kotlin/net/sergeych/lyng_cli/CliNetworkJvmTest.kt @@ -73,10 +73,12 @@ class CliNetworkJvmTest { try { val script = """ import lyng.io.http + import lyng.io.http.server import lyng.io.ws import lyng.io.net assert(Http.isSupported()) + assert(HttpServer() is HttpServer) println("ws=" + Ws.isSupported()) println("net=" + Net.isSupported())