update
This commit is contained in:
@@ -0,0 +1,149 @@
|
||||
# Requirements: natsClient_JS
|
||||
|
||||
## 1. Business Context & Success Metrics
|
||||
|
||||
### Business Goal
|
||||
|
||||
Provide a single, reusable NATS WebSocket client for Svelte-based consuming applications. It
|
||||
handles the tedious, error-prone parts of talking to a NATS broker — connection lifecycle,
|
||||
reconnection, message decoding, request/reply, and msghandler envelope handling — so consuming
|
||||
apps can subscribe, publish, request, and reply without duplicating that logic.
|
||||
|
||||
### User Stories
|
||||
|
||||
- **US-001**: As a consuming app, I want to establish a NATS connection with reactive status so
|
||||
that I can display connectivity to the user.
|
||||
- **US-002**: As a consuming app, I want to subscribe to a subject and receive decoded messages so
|
||||
that I can react to events.
|
||||
- **US-003**: As a consuming app, I want to publish string or JSON messages so that I can emit
|
||||
events.
|
||||
- **US-004**: As a consuming app, I want to use request/reply for synchronous responses so that I
|
||||
can call backend functions.
|
||||
- **US-005**: As a consuming app, I want to register a reply handler so that I can serve requests.
|
||||
- **US-006**: As a consuming app, I want msghandler envelope wrapping/unwrapping so that I can talk
|
||||
to the sommpanion db backend.
|
||||
- **US-007**: As a consuming app, I want automatic reconnection so that I don't lose connectivity
|
||||
on a network blip.
|
||||
- **US-008**: As a consuming app, I want a clean disconnect that releases every subscription and
|
||||
the underlying socket.
|
||||
|
||||
### KPIs & Targets
|
||||
|
||||
- **KPI-001**: 100% of exported API functions covered by automated tests (validates FR-001..008).
|
||||
- **KPI-002**: A disconnected connection returns to the `connected` state after automatic
|
||||
reconnection (validates NFR-102).
|
||||
|
||||
## 2. Technical Boundaries
|
||||
|
||||
### In Scope
|
||||
- Connection lifecycle (`getNats`, `connectNATS`, `closeNats`).
|
||||
- Subscribe / publish / request / reply.
|
||||
- Connection-status tracking via a Svelte store.
|
||||
- msghandler envelope packing/unpacking via `msghandler-csr.js`.
|
||||
- URL resolution from explicit options, env vars, or config.
|
||||
|
||||
### Out of Scope
|
||||
- Business logic of consuming apps (this library only moves bytes).
|
||||
- Broker-side configuration or server deployment.
|
||||
- Any UI components.
|
||||
|
||||
### Dependencies
|
||||
- `nats.ws` — NATS WebSocket transport.
|
||||
- `svelte/store` — reactive `connectionStatus`.
|
||||
- `./msghandler-csr.js` — msghandler `smartpack` / `smartunpack`.
|
||||
- NATS broker at `wss://natsws.yiem.cc`.
|
||||
|
||||
### Deployment Constraints
|
||||
- **NFR-101**: Transport must be WebSocket (`nats.ws`) so it works in browsers behind proxies.
|
||||
- **NFR-501**: `closeNats` must unsubscribe all subscriptions and clear reconnect timers.
|
||||
|
||||
### System Context (C4 Level 1)
|
||||
|
||||
```mermaid
|
||||
%% C4 Level 1 - System Context
|
||||
flowchart LR
|
||||
app[Consuming App<br/>Svelte app]
|
||||
system[(natsClient.js<br/>NATS client lib)]
|
||||
extNats[NATS<br/>Broker wss://natsws.yiem.cc]
|
||||
extMsg[msghandler-csr.js<br/>Envelope codec]
|
||||
|
||||
app -->|imports| system
|
||||
system -->|nats.ws WSS| extNats
|
||||
system -->|smartpack/smartunpack| extMsg
|
||||
```
|
||||
|
||||
## 3. Functional Requirements (FR)
|
||||
|
||||
### FR-001: Establish a connection with URL resolution
|
||||
The library shall resolve the broker URL by precedence: `opts.servers`, then
|
||||
`import.meta.env.VITE_NATS_URL`, then `config.nats_server_info.url`, then `wss://natsws.yiem.cc`.
|
||||
- `getNats` transitions status to `connecting` then `connected`.
|
||||
**Traceability**: US-001
|
||||
|
||||
### FR-002: Subscribe and decode messages
|
||||
The library shall decode each message with `StringCodec`, then `JSON.parse` it, falling back to
|
||||
`{ text }` when the payload is not valid JSON.
|
||||
- `onMessage(parsed)` is called for each decoded message.
|
||||
**Traceability**: US-002
|
||||
|
||||
### FR-003: Publish messages
|
||||
The library shall stringify a non-string payload with `JSON.stringify`, or send a string payload
|
||||
verbatim.
|
||||
**Traceability**: US-003
|
||||
|
||||
### FR-004: Request/reply
|
||||
The library shall send a request and await the reply, with an optional `timeout`.
|
||||
**Traceability**: US-004
|
||||
|
||||
### FR-005: Reply handler
|
||||
The library shall subscribe to a subject, invoke `handler(parsed, msg)`, and publish the returned
|
||||
value back on `m.subject`.
|
||||
**Traceability**: US-005
|
||||
|
||||
### FR-006: msghandler request
|
||||
The library shall pack `[[db_request, {functioncall, args}, dictionary]]`, send a request, unpack
|
||||
the reply, and return the `jsontable`/`dictionary` payload or throw on a `text` payload.
|
||||
**Traceability**: US-006
|
||||
|
||||
### FR-007: Connection status tracking
|
||||
The library shall publish `connecting`, `connected`, `disconnected`, and `error` statuses to the
|
||||
`connectionStatus` store.
|
||||
**Traceability**: US-001
|
||||
|
||||
### FR-008: Close connection
|
||||
The library shall unsubscribe every tracked subscription, clear reconnect timers, and close the
|
||||
connection.
|
||||
**Traceability**: US-008
|
||||
|
||||
## 4. Non-Functional Requirements (NFRs)
|
||||
|
||||
### 4.1 Performance & Scalability
|
||||
- **NFR-102**: Automatic reconnection must restore the `connected` state without re-calling
|
||||
`getNats` from the consumer.
|
||||
|
||||
### 4.2 Availability & Reliability
|
||||
- **NFR-201**: Status must be observable through a reactive Svelte store (`connectionStatus`).
|
||||
- **NFR-302**: Per-message decode errors must not crash the subscription loop (`catch` around
|
||||
decode/parse/handler).
|
||||
|
||||
### 4.3 Privacy & Security
|
||||
- **NFR-301**: Config (broker URL, fileserver URL) is injected via `setConfig` / options, never
|
||||
hardcoded in a way that leaks secrets across environments.
|
||||
|
||||
### 4.4 Observability & Telemetry
|
||||
- **Required Logs**: `[NATS] ...` lines for connection, subscription, publish, and status events.
|
||||
- **Critical Metrics**: `connectionStatus.state`.
|
||||
- **Retention**: N/A (in-memory library state).
|
||||
|
||||
## 5. Acceptance Conditions
|
||||
|
||||
- [ ] **FR-001**: `getNats` returns a connection and sets `connected` status.
|
||||
- [ ] **FR-002**: `subscribe` decodes a JSON message and calls `onMessage`.
|
||||
- [ ] **FR-003**: `publish` sends both string and object payloads.
|
||||
- [ ] **FR-004**: `request` returns the decoded reply within `timeout`.
|
||||
- [ ] **FR-005**: `reply` auto-replies to each request.
|
||||
- [ ] **FR-006**: `sendMsghandlerRequest` returns the `dictionary` payload and throws on `text`.
|
||||
- [ ] **FR-007**: `connectionStatus` emits `connecting`/`connected`/`disconnected`/`error`.
|
||||
- [ ] **FR-008**: `closeNats` unsubscribes all and closes the socket.
|
||||
- [ ] **NFR-102**: A disconnect transitions status and auto-reconnects.
|
||||
- [ ] **NFR-501**: `closeNats` clears all subscriptions and timers.
|
||||
Reference in New Issue
Block a user