Files
2026-09-18 22:03:10 +07:00

121 lines
4.3 KiB
Markdown

# Specification: natsClient_JS
The technical contract for the module's exports. Each item carries an `SP-XXX` ID and traces to a
Requirement (FR/NFR) and Solution Design decision (SD).
## 1. Module Exports
- `connectionStatus` — Svelte writable store of `{ state, message }`.
- `setConfig(cfg)` — inject config (broker/fileserver URLs).
- `getNats(opts)` — establish the shared connection.
- `subscribe(subject, onMessage)` — subscribe and decode.
- `publish(subject, payload, opts)` — publish.
- `closeNats()` — close and cleanup.
- `connectNATS(brokerUrl, cfg)` — connect using a broker URL or config.
- `request(subject, payload, opts)` — request/reply.
- `reply(subject, handler, opts)` — reply handler.
- `sendMsghandlerRequest(subject, functioncall, args, config)` — msghandler request.
## 2. API Contract
### SP-001: getNats(opts)
```
getNats(opts?: { servers?: string }) => Promise<connection>
```
- URL resolution precedence: `opts.servers` → `import.meta.env.VITE_NATS_URL` →
`config.nats_server_info.url` → `wss://natsws.yiem.cc`.
- Emits `connecting` then `connected` on `connectionStatus`.
- Returns the NATS connection object.
- Throws on connection failure.
**Traceability**: FR-001, FR-007, SD-001, SD-002, SD-004
### SP-002: subscribe(subject, onMessage)
```
subscribe(subject: string, onMessage: (parsed) => void) => Promise<{ unsubscribe(): Promise<void> }>
```
- Auto-connects via `getNats` if not connected.
- Decodes each message with `StringCodec`, then `JSON.parse`, falling back to `{ text }`.
- Registers the subscription in the `Map` registry for cleanup (SD-005).
**Traceability**: FR-002, SD-003, SD-005
### SP-003: publish(subject, payload, opts)
```
publish(subject: string, payload: object | string = {}, opts?: object) => Promise<void>
```
- Auto-connects via `getNats` if not connected.
- String payloads are sent verbatim; other payloads are `JSON.stringify`ed.
**Traceability**: FR-003, SD-001, SD-003
### SP-004: request(subject, payload, opts)
```
request(subject: string, payload: object | string, opts?: { timeout?: number }) => Promise<object>
```
- Sends a request with `nc.request`, encoding non-strings via `JSON.stringify`.
- Decodes the reply (`JSON.parse`, else `{ text }`).
**Traceability**: FR-004, SD-003
### SP-005: reply(subject, handler, opts)
```
reply(subject: string, handler: (parsed, msg) => object | string, opts?: object)
=> Promise<{ unsubscribe(): Promise<void> }>
```
- Invokes `handler(parsed, msg)` and publishes the returned value on `m.subject`.
**Traceability**: FR-005, SD-005
### SP-006: sendMsghandlerRequest(subject, functioncall, args, config)
```
sendMsghandlerRequest(subject: string, functioncall: string, args: object, config: object)
=> Promise<object>
```
- Packs `[[db_request, { functioncall, args }, "dictionary"]]` via `msghandlerCSR.smartpack`.
- Sends a request, unpacks via `msghandlerCSR.smartunpack`.
- Returns the `jsontable`/`dictionary` `data`; throws if `type === "text"`.
**Traceability**: FR-006, SD-006
### SP-007: closeNats()
```
closeNats() => Promise<void>
```
- Unsubscribes every tracked subscription, clears reconnect timers, closes the connection.
**Traceability**: FR-008, NFR-501, SD-005
### SP-008: connectionStatus store
```
connectionStatus: Writable<{ state: "connecting" | "connected" | "disconnected" | "error", message: string }>
```
**Traceability**: FR-007, NFR-201, SD-004
## 3. Payload Format
All payloads are JSON text encoded via `StringCodec`:
- Publish/request: `JSON.stringify(payload)` for objects; string sent verbatim.
- Decode: `JSON.parse(text)`, fallback `{ text }`.
## 4. Msghandler Envelope Format
### SP-010: Request envelope
Built by `msghandlerCSR.smartpack(subject, [["db_request", { functioncall, args }, "dictionary"]], { broker_url, fileserver_url })`.
### SP-011: Response envelope
Returned by `msghandlerCSR.smartunpack`; `.payloads` is an array of `[dataname, data, type]`.
`sendMsghandlerRequest` returns `data` when `type` is `jsontable` or `dictionary`, and throws when
`type === "text"`.
## 5. Error Codes
| Condition | Behavior | Traceability |
|-----------|----------|--------------|
| `type === "text"` in msghandler reply | `throw new Error(data)` | FR-006, SP-011 |
| `getNats` fails | sets `error` status, throws | FR-001, SP-001 |
| No `jsontable`/`dictionary` payload | `throw new Error('No valid response found')` | FR-006 |