docs: document image tracing endpoint

This commit is contained in:
2026-08-08 14:51:40 +08:00
parent 445dbc1781
commit dc8127dba1
3 changed files with 53 additions and 5 deletions
+11 -3
View File
@@ -46,7 +46,8 @@ apps/web ──► apps/proxy ──► packages/tts ──► packages/shared
### Edges
- **`apps/web``apps/proxy`** — calls `/search`, `/items/:id`,
`/items/:id/file`, and `/asset` (CORS-safe asset proxy) over HTTP.
`/items/:id/file`, `/asset` (CORS-safe asset proxy), and `/trace`
(image → vector shape) over HTTP.
- **`apps/web``packages/extract`** — uses `buildTree` / `collectRefs`
to analyze a loaded `TTSMod` in the browser (tree sidebar + asset refs).
- **`apps/proxy``packages/tts`** — calls `fetchMod` / `getFileName` to serve
@@ -80,6 +81,9 @@ apps/web ──► apps/proxy ──► packages/tts ──► packages/shared
| `@hono/node-server`| Node adapter for Hono | `apps/proxy` |
| `@hono/cors` | CORS middleware | `apps/proxy` |
| `bson` | BSON deserialization of TTS save files | `packages/tts` |
| `@visioncortex/vtracer` | Raster-to-SVG vectorization (wasm) | `apps/proxy` |
| `sharp` | Image decoding to RGBA | `apps/proxy` |
| `svgpath` | SVG path parsing for traced shapes | `apps/proxy` |
| `cheerio` | Workshop browse page scraping | `apps/proxy` |
| `zod` | Runtime validation | `apps/proxy`, `packages/shared` |
| `three` | 3D rendering | `apps/web` |
@@ -91,7 +95,11 @@ apps/web ──► apps/proxy ──► packages/tts ──► packages/shared
- **`cheerio` is backend-only** — it never appears in `packages/extract`, which
must stay isomorphic.
- **`bson` is Node-only** — used by the fetcher, not the analysis layer.
- **`bson` is Node-only** — used by the fetcher and the trace route, not the
analysis layer.
- **`@visioncortex/vtracer`, `sharp`, `svgpath` are backend-only** — the trace
route lives in `apps/proxy`; they never appear in `packages/extract`, which
must stay isomorphic.
- **`packages/extract` has zero external runtime deps** — it relies only on
platform `fetch` / `Blob`, keeping it portable to a future frontend.
@@ -107,7 +115,7 @@ apps/web ──► apps/proxy ──► packages/tts ──► packages/shared
- The proxy runs as a single Node process via `@hono/node-server`.
- `apps/web` is a static Vite build served separately; during development it
proxies `/search`, `/items`, `/health`, and `/asset` to the proxy.
proxies `/search`, `/items`, `/health`, `/asset`, and `/trace` to the proxy.
- `packages/extract` is published/consumed as a plain ESM module usable from a
browser bundle or Node.
- No shared state between requests; each request fetches fresh.
+21
View File
@@ -158,3 +158,24 @@ browser. Routing asset fetches through the proxy makes them loadable.
**Alternatives considered:** Loading assets directly in the browser. Rejected —
CORS failures on common Workshop hosts would break the viewers.
## D13 — Server-side image tracing to a mesh-ready shape
**Decision:** The proxy exposes `GET /trace?url=...`, which fetches an image,
traces it into a vector shape, and returns the result BSON-encoded. Tracing is
configurable: `mode` (`alpha` default, `bw`, `color`) selects how the region is
derived, and `format` (`shape` default, `svg`) selects the response. The
`shape` format returns a parsed `{ outline, holes }` polygon matching
`@tts/mesh`'s `Shape` interface.
**Context:** The user wants to build a mesh from an image (e.g. a token or tile
art) using `@tts/mesh`. vtracer only returns SVG, but the mesh package consumes
`{ outline, holes }`. Tracing on the server keeps the SVG-to-shape parsing out
of the browser and lets the BSON response carry a ready-to-extrude shape.
`sharp` decodes the image to RGBA so alpha/luminance masks can be built before
feeding vtracer's `convertPixels`.
**Alternatives considered:** Returning only the raw SVG and parsing in the web
app near `@tts/mesh`; tracing by color only (no alpha). Rejected — server-side
parsing yields a shape the mesh package can consume directly, and alpha-based
tracing (the default) is the common case for token/tile art.
+20 -1
View File
@@ -63,6 +63,8 @@ tts-workshop/
│ │ │ ├── search.ts # GET /search?q=...&page=1
│ │ │ ├── items.ts # GET /items/:id, /items/:id/file
│ │ │ ├── asset.ts # GET /asset?url=... (CORS-safe asset proxy)
│ │ │ ├── trace.ts # GET /trace?url=... (image → vector shape)
│ │ │ ├── svgShape.ts # parse vtracer SVG into { outline, holes }
│ │ │ └── health.ts # GET /health
│ │ └── env.ts # zod env validation
│ └── web/
@@ -202,6 +204,17 @@ Hono server exposing search + fetch.
it back with a `Content-Type` header. Workshop hosts often omit CORS
headers, which would block three.js loaders in the browser; routing through
the proxy makes those assets loadable. Only `http(s)` URLs are allowed.
- `routes/trace.ts`
- `GET /trace?url=...&mode=alpha&threshold=128&format=shape` — fetch an
image, trace it into a vector shape, and return the result BSON-encoded.
`mode` is `alpha` (default), `bw`, or `color`; `format` is `shape`
(default) or `svg`. `shape` returns a parsed `{ outline, holes }` polygon
matching `@tts/mesh`'s `Shape` interface, ready to extrude.
- `routes/svgShape.ts`
- `parseSvgShape(svg)` — parse a vtracer SVG into a `TracedShape`
(`{ outline, holes }`): flatten beziers to polylines, split subpaths into
rings, classify by winding (CCW outline / CW hole), and assign holes to
their containing outline.
- `routes/health.ts`
- `GET /health` — liveness.
- `env.ts` — zod validation of `STEAM_API_KEY`, `PORT`.
@@ -259,6 +272,7 @@ proxy API and `packages/extract` directly for analysis.
| GET | `/items/:id` | Full parsed `TTSMod` (`?fileUrl=` skips key) | key* |
| GET | `/items/:id/file` | Raw save bytes, filename from header | key* |
| GET | `/asset?url=` | CORS-safe proxy for external assets | — |
| GET | `/trace?url=&mode=&format=` | Trace an image into a vector shape (BSON) | — |
\* `STEAM_API_KEY` is optional; `/items/*` works without it when a `fileUrl`
query param is supplied.
@@ -275,12 +289,17 @@ query param is supplied.
download BSON → parse → TTSMod
packages/extract → flatten objects / extract refs / download assets
/trace?url=... → sharp decode → vtracer → parse SVG → BSON shape
```
## Dependencies
- `hono`, `@hono/node-server`, `@hono/cors` — server.
- `bson` — BSON deserialization.
- `bson` — BSON deserialization (save files + trace results).
- `@visioncortex/vtracer` — raster-to-SVG vectorization (wasm).
- `sharp` — image decoding to RGBA for tracing.
- `svgpath` — SVG path parsing for traced shapes.
- `cheerio` — Workshop browse page scraping (backend only).
- `zod` — validation.
- `react`, `react-dom`, `react-router-dom`, `zustand` — frontend.