v1.0.0 #1

Merged
ton merged 14 commits from v1.0.0 into main 2026-05-22 22:16:17 +00:00
2 changed files with 142 additions and 17 deletions
Showing only changes of commit 8de9a65c03 - Show all commits

View File

@@ -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" 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). 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?

View File

@@ -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. 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 #### 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) #### 3.5 Step 5: Publish to Transport (Caller's Responsibility)
**Choose your transport** (replace `MY_TRANSPORT` with your actual library):
```javascript ```javascript
// Publishing via the transport layer is the caller's responsibility // Example 1: NATS (Node.js)
// Example with any transport (NATS, MQTT, WebSocket, etc.) import { connect } from 'nats';
// const conn = await transportClient.connect({ servers: "ws://localhost:4222" }); const nats = connect({ servers: 'ws://localhost:4222' });
// await conn.publish("/agent/wine/api/v1/prompt", msgJson); 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**: **Why caller responsibility?**
- The transport layer provides message delivery (NATS, MQTT, WebSocket, etc.) - **Transport agnostic**: msghandler supports NATS, MQTT, WebSocket, HTTP, or any custom transport
- JSON format ensures cross-platform compatibility - **Connection reuse**: Callers can manage connection pools efficiently
- `smartpack()` returns `(env, msgJson)` - caller handles publishing via their chosen transport - **Flexibility**: No library lock-in; use whatever transport best fits your stack
#### 3.6 Step 6: Julia Backend Receives Message #### 3.6 Step 6: Julia Backend Receives Message
```julia ```julia
# Julia backend # Julia backend
transport_msg = transport_subscription.next() # Get message from transport # Choose your transport (replace MY_TRANSPORT with your actual library)
env = smartunpack(String(transport_msg.payload))
# 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: # env["payloads"] is now:
# [ # [
# ("msg", "Hello! I'm Ton.", "text"), # ("msg", "Hello! I'm Ton.", "text"),
# ("avatar", binary_data, "image") # ("avatar", binary_data, "image")
# ] # ]
end
``` ```
**Rationale**: **Rationale**:
@@ -257,8 +342,13 @@ env, msg_json = smartpack(
("generated_image", generated_image, "image") ("generated_image", generated_image, "image")
], ],
reply_to = "/chat/user/v1/message", 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**: **Rationale**: