@uptimizr/collector-server 0.6.1 → 0.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +56 -19
  2. package/package.json +4 -4
package/README.md CHANGED
@@ -79,9 +79,10 @@ file; back up by copying the file).
79
79
 
80
80
  ### Ingestion
81
81
 
82
- - `POST /api/v1/collect` — accepts a batched `collectRequest`. Validates → enriches
83
- (server-set cookieless `visitorId = hash(ip + ua + dailySalt)`, raw IP never stored)
84
- → inserts into the configured `CollectorStore` (DuckDB by default).
82
+ - `POST /api/v1/collect` — accepts a batched `collectRequest`. Validates → rejects
83
+ mixed-project or unknown-project batches → enriches (server-set cookieless
84
+ `visitorId = hash(ip + ua + dailySalt)`, raw IP never stored) → inserts into the
85
+ configured `CollectorStore` (DuckDB by default) and publishes the live feed.
85
86
 
86
87
  ### Query (require `x-api-key`)
87
88
 
@@ -89,15 +90,41 @@ Aggregations are computed **at query time** (v1) — including the heatmap/perf
89
90
  aggregates, which run directly in the OSS DuckDB store. Every route is scoped to
90
91
  the project the API key resolves to.
91
92
 
92
- - `GET /api/v1/sessions`
93
- - `GET /api/v1/heatmaps/pointer`
94
- - `GET /api/v1/heatmaps/camera`
95
- - `GET /api/v1/meshes/top`
96
- - `GET /api/v1/perf`
93
+ - Sessions: `GET /api/v1/sessions`, `GET /api/v1/sessions/:id/meta`,
94
+ `GET /api/v1/sessions/:id/trajectory`.
95
+ - Heatmaps: `GET /api/v1/heatmaps/pointer`, `/camera`, `/position`, `/world`
96
+ (+ `/world/stats`), `/gaze` (+ `/gaze/stats`), `/mesh-uv`, `/click-rays`,
97
+ `/flow`, `/perf`, `/errors`.
98
+ - Mesh / interaction insights: `GET /api/v1/meshes/top`, `/sources`, `/trend`,
99
+ `/dwell`, `/blind-spots`, `/kinds`, `/reachability`, plus `/clicks/dead`,
100
+ `/clicks/rage`, `/hover/dwell`, `/camera-gestures`, `/interactions/sources`,
101
+ `/input-actions/top`.
102
+ - Performance / diagnostics: `GET /api/v1/perf`, `/perf/compile-stalls`,
103
+ `/perf/render-scale`, `/perf/resources`, `/perf/distribution`,
104
+ `/perf/fps-histogram`, `/perf/frame-time`, `/perf/jank`, `/perf/churn`,
105
+ `/perf/by-device`, `/perf/by-scene`, `/perf/resource-percentiles`,
106
+ `/perf/stability`, `/graphics-diagnostics`, `/rendering-technology`,
107
+ `/capabilities`.
108
+ - Scene / path / funnel analytics: `GET /api/v1/scenes`, `/scene-representations`,
109
+ `/timeseries`, `/event-counts`, `/coverage`, `/coverage/view-histogram`,
110
+ `/paths`, `/camera/distance`, `/navigation`, `/backtrack`, `/funnel`,
111
+ `/scene-retention`, `/load-bounce`, `/variant-leaderboard`, `/xr/rotation`,
112
+ `/xr/sources`, `/xr/abandonment`, `/xr/locomotion`.
113
+ - Scene representations: `PUT /api/v1/scenes/:sceneId/representation`,
114
+ `GET /api/v1/scenes/:sceneId/representation`.
97
115
  - `GET /api/v1/sessions/:id/events` — ordered replay timeline, **gated by**
98
- `ENABLE_RAW_SESSION_RETENTION` (returns `403` when disabled).
116
+ `ENABLE_RAW_SESSION_RETENTION` (returns `403` when disabled); supports buffered
117
+ JSON or NDJSON streaming (`Accept: application/x-ndjson` / `?format=ndjson`).
99
118
 
100
- Shared query params: `since`, `until` (epoch ms), `bins`, `limit`.
119
+ Live endpoints:
120
+
121
+ - `POST /api/v1/live/token` — exchange a query API key for a short-lived live token.
122
+ - `GET /api/v1/live/presence`, `/live/stream`, `/live/sessions/:id` — SSE streams
123
+ authenticated with `?token=...`; per-session live follow is also gated by raw
124
+ retention.
125
+
126
+ Common query params include `since`, `until` (epoch ms), `bins`, `limit`, `scene`,
127
+ `session`, `cameraMode`, `source`, and spatial `cellSize` / `region` where supported.
101
128
 
102
129
  - `GET /health` — liveness probe.
103
130
 
@@ -109,11 +136,13 @@ if `VISITOR_HASH_SECRET` is missing.
109
136
 
110
137
  ### Authentication: which endpoints need a key
111
138
 
112
- | Endpoint group | Auth | Why |
113
- | ------------------------------ | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
114
- | `POST /api/v1/collect` | **None (keyless)** | Runs in untrusted browsers; a key shipped to the client is not a secret. Ingestion is open by design and protected by validation + rate limits instead. |
115
- | All query routes (`/api/v1/*`) | `x-api-key` | Read access is scoped to the project the key resolves to. |
116
- | `GET /health` | None | Liveness probe. |
139
+ | Endpoint group | Auth | Why |
140
+ | ----------------------------------------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
141
+ | `POST /api/v1/collect` | **None (keyless)** | Runs in untrusted browsers; a key shipped to the client is not a secret. Ingestion is open by design and protected by validation + rate limits instead. |
142
+ | Query/read routes | `x-api-key` | Read access is scoped to the project the key resolves to. |
143
+ | `POST /api/v1/live/token` | `x-api-key` | Exchanges a project query key for a short-lived SSE token. |
144
+ | Live SSE routes (`/api/v1/live/*` `GET`s) | `?token=...` | Browser `EventSource` cannot attach custom headers, so live streams use short-lived bearer tokens. |
145
+ | `GET /health` | None | Liveness probe. |
117
146
 
118
147
  ### Threat model for keyless ingestion
119
148
 
@@ -135,10 +164,18 @@ Because `POST /api/v1/collect` accepts unauthenticated input, every request is t
135
164
 
136
165
  ## Configuration
137
166
 
138
- Environment-driven (see [`.env.example`](../../../.env.example)): `COLLECTOR_HOST`,
139
- `COLLECTOR_PORT`, `COLLECTOR_CORS_ORIGINS`, `VISITOR_HASH_SECRET`,
140
- `ENABLE_RAW_SESSION_RETENTION`, `COLLECTOR_DASHBOARD_DIR` (optional; serve a
141
- static dashboard all-in-one — see [above](#all-in-one-serve-the-dashboard-too)).
167
+ Environment-driven (see [`.env.example`](../../../.env.example)):
168
+
169
+ - Server / browser access: `COLLECTOR_HOST` (default `0.0.0.0`), `COLLECTOR_PORT`
170
+ (default `4318`), `COLLECTOR_CORS_ORIGINS`, `COLLECTOR_TRUST_PROXY`,
171
+ `COLLECTOR_BODY_LIMIT`.
172
+ - Privacy / replay / live: `VISITOR_HASH_SECRET` (required),
173
+ `ENABLE_RAW_SESSION_RETENTION`, `LIVE_TOKEN_SECRET`, `LIVE_TOKEN_TTL_MS`,
174
+ `LIVE_WINDOW_MS`, `LIVE_MAX_CONNECTIONS`, `LIVE_PRESENCE_INTERVAL_MS`.
175
+ - Rate limits: `COLLECTOR_RATE_LIMIT_MAX`, `COLLECTOR_RATE_LIMIT_WINDOW_MS`,
176
+ `COLLECTOR_INGEST_RATE_LIMIT_MAX`, `COLLECTOR_INGEST_RATE_LIMIT_WINDOW_MS`.
177
+ - All-in-one dashboard: `COLLECTOR_DASHBOARD_DIR` (optional; see
178
+ [above](#all-in-one-serve-the-dashboard-too)), `COLLECTOR_CSP` (`strict` or `off`).
142
179
 
143
180
  The storage backend is chosen with `COLLECTOR_STORE`:
144
181
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uptimizr/collector-server",
3
- "version": "0.6.1",
3
+ "version": "0.6.2",
4
4
  "description": "Uptimizr ingestion + query API (Fastify). Self-hostable collector for the OSS data-collector.",
5
5
  "keywords": [
6
6
  "uptimizr",
@@ -45,9 +45,9 @@
45
45
  "fastify": "^5.10.0",
46
46
  "fastify-type-provider-zod": "^7.0.0",
47
47
  "zod": "^4.4.3",
48
- "@uptimizr/db": "0.7.1",
49
- "@uptimizr/db-clickhouse": "0.3.3",
50
- "@uptimizr/schema": "0.5.0"
48
+ "@uptimizr/schema": "0.5.1",
49
+ "@uptimizr/db": "0.7.2",
50
+ "@uptimizr/db-clickhouse": "0.3.4"
51
51
  },
52
52
  "devDependencies": {
53
53
  "@types/node": "^26.1.0",