From 8de9a65c03a7cf8e4f81ee6f4cf76a7e63939071 Mon Sep 17 00:00:00 2001 From: narawat Date: Fri, 22 May 2026 18:59:23 +0700 Subject: [PATCH] update docs --- AI_prompt.md | 35 +++++++++++++ docs/walkthrough.md | 124 ++++++++++++++++++++++++++++++++++++++------ 2 files changed, 142 insertions(+), 17 deletions(-) diff --git a/AI_prompt.md b/AI_prompt.md index 11ffb4a..5cbb13a 100644 --- a/AI_prompt.md +++ b/AI_prompt.md @@ -248,5 +248,40 @@ I already setup the project structure. Can you implement the app? To test whether this Dioxus project can be build, you may use this command "dx bundle --web --release --debug-symbols=false" P.S. In a Dioxus single-page application (SPA), switching screens can be handled perfectly using standard Rust state matching (often called conditional rendering or state-based routing). + + + + +read the following files: +./docs/requirements.md +./docs/solution-design.md +./docs/specification.md +./docs/walkthrough.md +What is the main interface of this package? + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/walkthrough.md b/docs/walkthrough.md index a3c83bb..11f2716 100644 --- a/docs/walkthrough.md +++ b/docs/walkthrough.md @@ -109,7 +109,68 @@ flowchart TB A JavaScript chat webapp wants to send mixed payloads (text message + user avatar image) to a Julia backend, and receive mixed payloads (text response + AI-generated image) back. -### Step-by-Step Flow +### Complete End-to-End Round-Trip Flow + +msghandler implements a **transport-agnostic** messaging pattern. The library handles serialization and envelope building, while the caller is responsible for publishing/subscribing via their chosen transport (NATS, MQTT, WebSocket, HTTP, etc.). + +``` +┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ END-TO-END ROUND-TRIP FLOW │ +└─────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + +SENDER (JavaScript Webapp) TRANSPORT LAYER RECEIVER (Julia Backend) +┌─────────────────────┐ ┌───────────────────┐ ┌─────────────────────┐ +│ │ │ │ │ │ +│ 1. Prepare data │ │ │ │ │ +│ [(msg, data, │ │ │ │ │ +│ type)] │ │ │ │ │ +│ │ │ │ │ │ +│ 2. Call smartpack() │──────────────────────────────────────>│ │ │ │ +│ Returns (env, │ │ JSON Message │ │ │ +│ json_str) │ │ (json_str) │ │ │ +│ │ │ │ │ │ +│ 3. Publish via │ │ │ │ │ +│ transport: │──────────────────────────────────────>│ (NATS/MQTT/ │────────────────────────>│ 4. Subscribe via │ +│ MY_TRANSPORT. │ │ WebSocket, etc.) │ │ transport: │ +│ publish(subject, │ │ │ │ msg = │ +│ msgJson) │ │ │ │ SUBSCRIBE() │ +│ │ │ │ │ │ +│ │ │ │ │ 5. Call │ +│ │ │ │ │ smartunpack( │ +│ │ │ │ │ String( │ +│ │ │ │ │ msg.payload) │ +│ │ │ │ │ │ +│ │ │ │ │ 6. Receive │ +│ │ │ │ │ payloads: │ +│ │ │ │ │ [(msg, data, │ +│ │ │ │ │ type), ...] │ +│ │ │ │ │ │ +└─────────────────────┘ └───────────────────┘ └─────────────────────┘ + +┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ JULIA BACKEND RESPONSE (Reverse Flow) │ +└─────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + +RECEIVER (Julia Backend) TRANSPORT LAYER SENDER (JavaScript Webapp) +┌─────────────────────┐ ┌───────────────────┐ ┌─────────────────────┐ +│ │ │ │ │ │ +│ 7. Process data │ │ │ │ │ +│ (AI inference) │ │ │ │ │ +│ │ │ │ │ │ +│ 8. Call smartpack() │──────────────────────────────────────>│ │ │ │ +│ Returns (env, │ │ JSON Message │ │ │ +│ json_str) │ │ (json_str) │ │ │ +│ │ │ │ │ │ +│ 9. Publish reply │ │ │ │ │ +│ via transport: │──────────────────────────────────────>│ (NATS/MQTT/ │────────────────────────>│ 10. Subscribe via │ +│ MY_TRANSPORT. │ │ WebSocket, etc.) │ │ reply_to topic │ +│ publish(replyTo, │ │ │ │ │ +│ msgJson) │ │ │ │ │ +│ │ │ │ │ │ +└─────────────────────┘ └───────────────────┘ └─────────────────────┘ +``` + +### Step-by-Step Flow (Sender Perspective) #### 3.1 Step 1: JavaScript Webapp Sends Mixed Payloads @@ -212,30 +273,54 @@ msghandler builds the message envelope: #### 3.5 Step 5: Publish to Transport (Caller's Responsibility) +**Choose your transport** (replace `MY_TRANSPORT` with your actual library): + ```javascript -// Publishing via the transport layer is the caller's responsibility -// Example with any transport (NATS, MQTT, WebSocket, etc.) -// const conn = await transportClient.connect({ servers: "ws://localhost:4222" }); -// await conn.publish("/agent/wine/api/v1/prompt", msgJson); +// Example 1: NATS (Node.js) +import { connect } from 'nats'; +const nats = connect({ servers: 'ws://localhost:4222' }); +await nats.publish("/agent/wine/api/v1/prompt", msgJson); + +// Example 2: MQTT (Node.js) +import * as mqtt from 'mqtt'; +const client = mqtt.connect('ws://localhost:1883'); +client.publish("/agent/wine/api/v1/prompt", msgJson); + +// Example 3: WebSocket (Browser) +const ws = new WebSocket('ws://localhost:4222/ws'); +ws.send(msgJson); + +// Example 4: Custom HTTP POST +fetch('http://localhost:8000/publish', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: msgJson +}); ``` -**Rationale**: -- The transport layer provides message delivery (NATS, MQTT, WebSocket, etc.) -- JSON format ensures cross-platform compatibility -- `smartpack()` returns `(env, msgJson)` - caller handles publishing via their chosen transport +**Why caller responsibility?** +- **Transport agnostic**: msghandler supports NATS, MQTT, WebSocket, HTTP, or any custom transport +- **Connection reuse**: Callers can manage connection pools efficiently +- **Flexibility**: No library lock-in; use whatever transport best fits your stack #### 3.6 Step 6: Julia Backend Receives Message ```julia # Julia backend -transport_msg = transport_subscription.next() # Get message from transport -env = smartunpack(String(transport_msg.payload)) +# Choose your transport (replace MY_TRANSPORT with your actual library) -# env["payloads"] is now: -# [ -# ("msg", "Hello! I'm Ton.", "text"), -# ("avatar", binary_data, "image") -# ] +# Example: NATS subscription +using NATS +conn = NATS.connect("nats.yiem.cc") +NATS.subscribe(conn, "/agent/wine/api/v1/prompt") do msg + env = smartunpack(String(msg.payload)) + + # env["payloads"] is now: + # [ + # ("msg", "Hello! I'm Ton.", "text"), + # ("avatar", binary_data, "image") + # ] +end ``` **Rationale**: @@ -257,8 +342,13 @@ env, msg_json = smartpack( ("generated_image", generated_image, "image") ], reply_to = "/chat/user/v1/message", - reply_to_msg_id = msg["msg_id"] + reply_to_msg_id = env["msg_id"] ); + +# Publish response via transport (caller's responsibility) +# Example: NATS +using NATS +NATS.publish(conn, "/agent/wine/api/v1/response", msg_json) ``` **Rationale**: