1 — Timeseries split

- writer.py: timeseries is now written to {id}.timeseries.json as a separate file. The detail JSON gets a timeseries_url field instead. finalize_pending and cleanup_pending handle the extra file.
  - merge.py (merge_one): symlinks the .timeseries.json file alongside the detail JSON. merge_all already handles it transparently (the .timeseries.json stem doesn't match any activity
  ID in to_merge, so it falls through to the symlink branch).
  - types.ts: timeseries is now timeseries?: Timeseries | null, and timeseries_url?: string | null added.
  - dataloader.ts: new loadTimeseries(url, detailUrl, base) function that resolves paths correctly in both single- and multi-user modes (uses the fetched detail URL's directory as the base).
  - ActivityDetail.svelte: loads timeseries separately after detail loads; uses detail.timeseries for IDB activities (embedded) or fetches via detail.timeseries_url for server activities. Charts show a pulse placeholder while loading.

 2 — GZip

  - GZipMiddleware (min 1 KB) added to both bincio/serve/server.py and bincio/edit/server.py — all API JSON responses are now gzip-compressed.
  - For static files (the big timeseries JSONs), nginx should be configured with gzip on; gzip_types application/json application/geo+json; — no code change needed on the server side.

  Net effect: opening an activity page now fetches ~1.4 KB (detail) instead of ~586 KB. The timeseries fetches ~60–150 KB gzip-compressed shortly after (it loads concurrently with the map rendering).
This commit is contained in:
Davide Scaini
2026-04-09 14:01:02 +02:00
parent 76b7b9ac7e
commit 8118f6f316
7 changed files with 90 additions and 11 deletions
+2
View File
@@ -9,6 +9,7 @@ from typing import Any
from fastapi import FastAPI, File, HTTPException, Request, UploadFile
from fastapi.middleware.cors import CORSMiddleware
from fastapi.middleware.gzip import GZipMiddleware
from fastapi.responses import HTMLResponse, JSONResponse, RedirectResponse
from bincio.edit.ops import SPORTS, STAT_PANELS, VALID_ACTIVITY_ID
@@ -21,6 +22,7 @@ strava_client_secret: str = ""
app = FastAPI(title="BincioActivity Edit Server", docs_url=None, redoc_url=None)
app.add_middleware(GZipMiddleware, minimum_size=1024)
# Allow localhost origins only — this server is never meant to be public
app.add_middleware(
CORSMiddleware,