• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

forst-lang / forst / 24748538374

21 Apr 2026 09:55PM UTC coverage: 76.33% (+0.04%) from 76.292%
24748538374

Pull #96

github

haveyaseen
feat(sidecar)!: stream invoke/raw bodies and add route-to-Forst middleware

Add createRouteToForstMiddleware with route-request-stream JSON (prefix + streamed
base64 body + suffix), invokeFunctionRawWithReadableBody, and split ForstSidecar
into forst-sidecar; document and test the flow.

BREAKING CHANGE: pipeInvokeRawStream(packageName, functionName, body, destination) now
takes body: ReadableStream<Uint8Array> instead of args: unknown[]. Build the stream
from JSON.stringify([args]) or from createInvokeRawJsonBodyReadable for Express.

Example:

```typescript
    import { Readable } from "node:stream";
    const body = Readable.toWeb(nodeReadable) as ReadableStream<Uint8Array>;
    await client.pipeInvokeRawStream("main", "StreamFn", body, res);
```

docs: rewrite root README for sidecar-first positioning

Reframe intro, comparisons, migration walkthrough, and package pointers around Node +
sidecar adoption.

refactor(devserver): extract dev HTTP server into internal/devserver

Move the dev server out of forst/cmd/forst into forst/internal/devserver: dedicated
handlers (health, version, functions, invoke, invoke/raw), shared response helpers,
invoke execution, and tests. Drop the old dev_server_http* surface from cmd in favor
of the internal package and slimmer runtime wiring.
Pull Request #96: feat(sidecar)!: stream request bodies and add route middleware

286 of 289 new or added lines in 11 files covered. (98.96%)

288 existing lines in 9 files now uncovered.

21387 of 28019 relevant lines covered (76.33%)

89.17 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

90.63
/forst/internal/devserver/handler_invoke_raw.go
1
package devserver
2

3
import (
4
        "encoding/json"
5
        "fmt"
6
        "io"
7
        "net/http"
8
)
9

10
// handleInvokeRaw is like handleInvoke but the POST body is **only** the JSON array of arguments.
11
// Package and function come from query parameters: package, function, optional streaming=true.
12
// Node clients can forward the raw request body (e.g. after express.raw) without parsing into V8 objects first.
13
func (s *DevServer) handleInvokeRaw(w http.ResponseWriter, r *http.Request) {
8✔
14
        if r.Method != http.MethodPost {
10✔
15
                s.sendError(w, "Method not allowed", http.StatusMethodNotAllowed)
2✔
16
                return
2✔
17
        }
2✔
18
        pkg := r.URL.Query().Get("package")
6✔
19
        fn := r.URL.Query().Get("function")
6✔
20
        if pkg == "" || fn == "" {
7✔
21
                s.sendError(w, "query parameters package and function are required", http.StatusBadRequest)
1✔
22
                return
1✔
23
        }
1✔
24
        streaming := r.URL.Query().Get("streaming") == "true"
5✔
25

5✔
26
        raw, err := io.ReadAll(r.Body)
5✔
27
        if err != nil {
5✔
NEW
28
                s.sendError(w, fmt.Sprintf("read body: %v", err), http.StatusBadRequest)
×
NEW
29
                return
×
NEW
30
        }
×
31
        if len(raw) == 0 {
6✔
32
                s.sendError(w, "body is required (JSON array of arguments)", http.StatusBadRequest)
1✔
33
                return
1✔
34
        }
1✔
35
        if !json.Valid(raw) {
5✔
36
                s.sendError(w, "body must be valid JSON", http.StatusBadRequest)
1✔
37
                return
1✔
38
        }
1✔
39
        var probe []json.RawMessage
3✔
40
        if err := json.Unmarshal(raw, &probe); err != nil {
4✔
41
                s.sendError(w, "body must be a JSON array", http.StatusBadRequest)
1✔
42
                return
1✔
43
        }
1✔
44

45
        s.invokeWithArgs(w, r, pkg, fn, json.RawMessage(raw), streaming)
2✔
46
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc