Skip to content

Commit c8764a6

Browse files
authored
Merge pull request #13 from dropdevrahul/feat/v0.3-persistence
feat: restore request payload model with persisted responses
2 parents 358463c + 51e6286 commit c8764a6

14 files changed

Lines changed: 1059 additions & 435 deletions

File tree

CHANGELOG.md

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
88
## [Unreleased]
99

1010
### Added
11+
- **Autosave to localStorage:** the working session (all open requests + payloads) is
12+
mirrored to browser `localStorage` on every change, in addition to the durable Go store.
13+
On launch the local draft is restored instantly (falling back to the Go store), and an
14+
"Autosaved HH:MM:SS" indicator in the top bar shows the last save time.
15+
- **Two-level request/payload model:** the UI now has top-level **request tabs** (each with
16+
its own URL, method, auth, and settings) and, within each, inner **payload tabs** that share
17+
the request's URL/method/auth/settings but each carry their own headers, params, body, and
18+
response. This restores Hypr's core premise — comparing multiple payloads against one URL —
19+
while letting several independent requests stay open side by side. "New Request" (sidebar +
20+
top "+") adds a top-level request; the "+" on the Payloads strip adds a payload.
1121
- **v0.3 — Persistence:** JSON store at `$OS_CONFIG_DIR/hypr/store.json`; data survives restart.
1222
- **Collections:** create named collections, save requests to them (name + target collection dialog),
1323
load saved requests into any tab with one click, delete collections and individual requests.
@@ -17,10 +27,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1727
on every meaningful action and restored on the next launch.
1828
- **Sidebar:** collapsible left panel (toggle via `PanelLeftClose`/`PanelLeftOpen` icon) with
1929
Collections and History sections; each section independently collapsible.
20-
- Per-tab method and URL are now properly isolated — switching tabs restores each tab's method+URL
21-
(previously method and URL were shared across all tabs).
22-
- 5 new Go tests in `store_test.go` covering collection CRUD, request save/delete,
23-
history append/clear/cap, and session save/restore (total: 34 tests).
30+
- Go tests in `store_test.go` covering collection CRUD, request save/delete (incl. payload
31+
round-trip), history append/clear/cap, and session save/restore.
2432

2533
### Changed
2634
- Backend: added `Store` type backed by JSON, 10 new bound methods

CLAUDE.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,15 @@ The frontend↔backend boundary is the only non-obvious part. Wails binds the Go
3333

3434
**Curl parsing** (`parse_curl.go`): a hand-written state machine over `go-shellwords` tokens. Supports `-X/--request`, `-H/--header`, `-d/--data[-ascii|-raw]`, `-A/--user-agent`, `-u/--user` (→ Basic auth), `-I/--head`, `-b/--cookie`. Does **not** handle `--data-binary`, `--data-urlencode`, or multipart. Input must start with `curl `.
3535

36-
**Frontend state** (`frontend/src/App.tsx`): the UI is multi-tab ("Request 1", "Request 2", …). State is held as **parallel arrays indexed by tab**`reqBodies[]`, `reqHeaders[][]`, `responses[]` — all kept in sync in `addNewTab`/`closeTab`. When editing tab logic, update all three arrays together or they desync. Headers in the UI are `{Key, Value}` objects (`src/lib/header.ts`); they're converted to a plain `Record<string, string>` before being passed to Go (which expects `main.Headers`).
36+
**Core premise:** Hypr's reason to exist vs. Postman/Insomnia is testing **multiple payloads against a single request URL** on one screen. This is encoded in a **two-level tab model** — don't collapse it.
37+
38+
**Frontend state** (`frontend/src/App.tsx`, types in `src/lib/model.ts`): a single nested structure, **not** parallel arrays.
39+
- Top level: `requests: RequestTab[]` + `activeRequest` index. Each `RequestTab` owns the **shared** `method`, `url`, `auth`, `settings`, plus `payloads: Payload[]` and `activePayload`.
40+
- Inner level: each `Payload` owns its own `headers`, `params`, `bodyType`/`jsonBody`/`rawBody`/`formRows`, and `response`. All payloads of a request share that request's url/method/auth/settings.
41+
- All edits go through the immutable updaters `updateRequest(requests, ri, patch)` and `updatePayload(requests, ri, pi, patch)` in `model.ts`. Per-payload KV-row edits use `setRow`/`dropRow`/`appendRow` from `src/lib/kv.ts`.
42+
- **URL ↔ params is one-way at send time only**: the URL bar is the shared base URL; the Params tab edits the active payload; `buildSpec()` merges `req.url` + payload params + auth query when sending. Editing one does not rewrite the other.
43+
- `response` is **never persisted**; `toStoredPayload()` strips it before saving. Session/collections persist via the Go store (`store.go`): `Session.openRequests`/`activeRequest`, `SavedRequest` carries all payloads.
44+
- Headers in the UI are `{Key, Value}` objects (`src/lib/kv.ts`); converted to a plain `Record<string, string>` before being passed to Go.
3745

3846
**UI stack**: the frontend uses **Tailwind CSS + shadcn/ui** (Radix primitives in `frontend/src/components/ui/`, `cn` helper in `src/lib/utils.ts`, design tokens as CSS variables in `src/index.css`, theme in `tailwind.config.js`). Icons are `lucide-react`. JSON responses are highlighted by the in-house `src/components/json-view.tsx` (no `react-json-pretty`). The `@/*` import alias maps to `src/`.
3947

frontend/package.json.md5

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
d3c70ad3166b11f53dac87fb2b41f3c2
1+
cec421cd25fd35fe8f5916df0826d3d0

0 commit comments

Comments
 (0)