{"_id":"@byteflavour/goatcounter-stats-client","_rev":"5-702f861cc21e98c8cec718e63e7ff1f8","name":"@byteflavour/goatcounter-stats-client","dist-tags":{"latest":"0.3.2"},"versions":{"0.2.0":{"name":"@byteflavour/goatcounter-stats-client","version":"0.2.0","license":"MIT","_id":"@byteflavour/goatcounter-stats-client@0.2.0","maintainers":[{"name":"byteflavour","email":"synapse@byteflavour.dev"}],"dist":{"shasum":"87cfcd4b0ffede4872b68a6350b5aaf6dd3f2140","tarball":"https://registry.npmjs.org/@byteflavour/goatcounter-stats-client/-/goatcounter-stats-client-0.2.0.tgz","fileCount":9,"integrity":"sha512-ConGCZC5FT05lJZu5h2MEHuNQzQAF8YFWRuxlDM05znKjHW4O2AWM+fbFX5FyqPMfaB8Qv5VX9Sbty+Ew5E9eg==","signatures":[{"sig":"MEYCIQDzNjqlEq20DUQyJ9/m/HV0wCRarKlqQmgXTDBY2NaOsgIhAODCjkxINF/UEwBcrTMm7l5pONrxBjYyi6xj67ZwMajH","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":14489},"type":"module","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./element":{"types":"./dist/element.d.ts","default":"./dist/element.js"}},"gitHead":"b742d9ec54e247cbbf75a786115e042ba176c5c9","_npmUser":{"name":"byteflavour","email":"synapse@byteflavour.dev"},"repository":{"url":"https://git.byteflavour.dev/synapse/goatcounter-stats-gateway","type":"git"},"_npmVersion":"11.17.0","description":"Typed client + web component for goatcounter-stats-gateway — public, cached stats in front of a private GoatCounter","directories":{},"sideEffects":["./dist/element.js"],"_nodeVersion":"24.19.0","dependencies":{},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/goatcounter-stats-client_0.2.0_1787344315162_0.2931612676975106","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@byteflavour/goatcounter-stats-client","version":"0.2.1","license":"MIT","_id":"@byteflavour/goatcounter-stats-client@0.2.1","maintainers":[{"name":"byteflavour","email":"synapse@byteflavour.dev"}],"dist":{"shasum":"8c1887d05ca279ad8a69a52121ac5fb315a515c8","tarball":"https://registry.npmjs.org/@byteflavour/goatcounter-stats-client/-/goatcounter-stats-client-0.2.1.tgz","fileCount":10,"integrity":"sha512-Iqwuwc5g2T0gXeY4zCYnZquG1kpv19F3/Gjh8/EUJumgeZkJfUKLDqq2nAeD4YdnumWMlKn37IcRJosxMawoJw==","signatures":[{"sig":"MEUCIQDBs5PiZUhM7JW9/b4JUN3AldE88G032HViEliyPY9+eAIgHq5ajRAJgPxGBULiVazZ+QaCf4oeQ+fLsgdMeljMyxQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":17495},"type":"module","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./element":{"types":"./dist/element.d.ts","default":"./dist/element.js"}},"gitHead":"2fa6376c2e94707f23eeddc43f31407813cea3cf","_npmUser":{"name":"byteflavour","email":"synapse@byteflavour.dev"},"repository":{"url":"https://git.byteflavour.dev/synapse/goatcounter-stats-gateway","type":"git"},"_npmVersion":"11.17.0","description":"Typed client + web component for goatcounter-stats-gateway — public, cached stats in front of a private GoatCounter","directories":{},"sideEffects":["./dist/element.js"],"_nodeVersion":"24.19.0","dependencies":{},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/goatcounter-stats-client_0.2.1_1787346748904_0.4453322355928486","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@byteflavour/goatcounter-stats-client","version":"0.3.0","license":"MIT","_id":"@byteflavour/goatcounter-stats-client@0.3.0","maintainers":[{"name":"byteflavour","email":"synapse@byteflavour.dev"}],"dist":{"shasum":"cc10cc5859579a60ad3304f89acd02f2a228e259","tarball":"https://registry.npmjs.org/@byteflavour/goatcounter-stats-client/-/goatcounter-stats-client-0.3.0.tgz","fileCount":10,"integrity":"sha512-YDC5MVf7fmqBPn0vasbfFVDqqOdsyZrTkoPNkztRmo4ep6NTM1JfJZCnB6Qk7t1GCmXCFjgN8UF/F95gAJYYUA==","signatures":[{"sig":"MEQCIBdd2jsZFvpfBueFEC66PtcC6FjcmWXyY5fTNLzCOJ5lAiBWxOCeWDvf9yP/4iK05kPuwCpQemC/C1rOz+WN5aJHeg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":24448},"type":"module","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./element":{"types":"./dist/element.d.ts","default":"./dist/element.js"}},"gitHead":"fc1e642300951d654c7c0442c3f8f8210bcea73e","_npmUser":{"name":"byteflavour","email":"synapse@byteflavour.dev"},"repository":{"url":"https://git.byteflavour.dev/synapse/goatcounter-stats-gateway","type":"git"},"_npmVersion":"11.17.0","description":"Typed client + web component for goatcounter-stats-gateway — public, cached stats in front of a private GoatCounter","directories":{},"sideEffects":["./dist/element.js"],"_nodeVersion":"24.19.0","dependencies":{},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/goatcounter-stats-client_0.3.0_1787355508731_0.8299438828679695","host":"s3://npm-registry-packages-npm-production"}},"0.3.1":{"name":"@byteflavour/goatcounter-stats-client","version":"0.3.1","license":"MIT","_id":"@byteflavour/goatcounter-stats-client@0.3.1","maintainers":[{"name":"byteflavour","email":"synapse@byteflavour.dev"}],"dist":{"shasum":"7b9fdcbdcae76ce79e249d14cd1e21f348a9cfe9","tarball":"https://registry.npmjs.org/@byteflavour/goatcounter-stats-client/-/goatcounter-stats-client-0.3.1.tgz","fileCount":10,"integrity":"sha512-5Skjz6+Prf0upEPnduYonR/bBc7vES12E4XNCOWxfMXj28p4HhRaGAG+hJYnQ28Fimz8+JNzTu1JYoH6W6qu+g==","signatures":[{"sig":"MEQCIAJT0I+5TkofJbCMDOtEfQVl2XqoawR32HfKdHIGOtdrAiBcnsxouAWws1soDYz5x6o2OuS0TuyilVSI554c7LP+qw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":25321},"type":"module","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./element":{"types":"./dist/element.d.ts","default":"./dist/element.js"}},"gitHead":"8001f46bc6c36bd5c140415f0c01247a6c1cff19","_npmUser":{"name":"byteflavour","email":"synapse@byteflavour.dev"},"repository":{"url":"https://git.byteflavour.dev/synapse/goatcounter-stats-gateway","type":"git"},"_npmVersion":"11.17.0","description":"Typed client + web component for goatcounter-stats-gateway — public, cached stats in front of a private GoatCounter","directories":{},"sideEffects":["./dist/element.js"],"_nodeVersion":"24.19.0","dependencies":{},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/goatcounter-stats-client_0.3.1_1787359615017_0.46499190686581615","host":"s3://npm-registry-packages-npm-production"}},"0.3.2":{"name":"@byteflavour/goatcounter-stats-client","version":"0.3.2","description":"Typed client + web component for goatcounter-stats-gateway — public, cached stats in front of a private GoatCounter","license":"MIT","type":"module","repository":{"type":"git","url":"https://git.byteflavour.dev/synapse/goatcounter-stats-gateway"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./element":{"types":"./dist/element.d.ts","default":"./dist/element.js"}},"sideEffects":["./dist/element.js"],"dependencies":{},"gitHead":"0928e0c55a2faff210feb8981eaf5b91e9abb2da","_id":"@byteflavour/goatcounter-stats-client@0.3.2","_nodeVersion":"24.19.0","_npmVersion":"11.17.0","dist":{"integrity":"sha512-UXnWWhr/aplHkrK6CZwm1/6w4tdr+P88tAS3LCVGyyScgyPZy6Nz8j9ZNb4JT//ignPRvc8JD96xvTx4521Rew==","shasum":"e1b8f310b43dba4c35289db0117e586c523ebc46","tarball":"https://registry.npmjs.org/@byteflavour/goatcounter-stats-client/-/goatcounter-stats-client-0.3.2.tgz","fileCount":10,"unpackedSize":25321,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIBtiivDf87TG6BmBHxrZdKPlznJxyUqPzF8pr0ldD+IvAiBZU2EhfetWQfKGIWCEcYFOB8KSQrreXqkYY9pavLLWgQ=="}]},"_npmUser":{"name":"byteflavour","email":"synapse@byteflavour.dev"},"directories":{},"maintainers":[{"name":"byteflavour","email":"synapse@byteflavour.dev"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/goatcounter-stats-client_0.3.2_1787394004246_0.8545017093069491"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-21T20:31:54.893Z","modified":"2026-08-22T10:20:04.546Z","0.2.0":"2026-08-21T20:31:55.310Z","0.2.1":"2026-08-21T21:12:29.048Z","0.3.0":"2026-08-21T23:38:28.876Z","0.3.1":"2026-08-22T00:46:55.159Z","0.3.2":"2026-08-22T10:20:04.388Z"},"license":"MIT","repository":{"type":"git","url":"https://git.byteflavour.dev/synapse/goatcounter-stats-gateway"},"description":"Typed client + web component for goatcounter-stats-gateway — public, cached stats in front of a private GoatCounter","maintainers":[{"name":"byteflavour","email":"synapse@byteflavour.dev"}],"readme":"# @byteflavour/goatcounter-stats-client\n\nTyped, zero-dependency client — plus a drop-in `<goatcounter-stats>` web\ncomponent — for [goatcounter-stats-gateway](https://git.byteflavour.dev/synapse/goatcounter-stats-gateway),\na small public gateway that serves cached, aggregate pageview stats from a\nprivate [GoatCounter](https://www.goatcounter.com/) instance.\n\nThe package version always equals the gateway version it was released\nwith, and its types are build-gated against the gateway's committed\nOpenAPI contract: client and server cannot drift apart.\n\n## Install\n\n```bash\nnpm add @byteflavour/goatcounter-stats-client\n```\n\nOr without any toolchain, straight from a CDN:\n\n```html\n<script type=\"module\"\n  src=\"https://esm.sh/@byteflavour/goatcounter-stats-client/element\"></script>\n<goatcounter-stats gateway=\"https://stats.example.com\" period=\"7d\"></goatcounter-stats>\n```\n\n## Headless client\n\nWorks anywhere `fetch` exists — browsers, node, bun, deno, SSR. Expected\nfailures are values, never exceptions:\n\n```ts\nimport { fetchSummary, fetchPages } from \"@byteflavour/goatcounter-stats-client\";\n\nconst summary = await fetchSummary(\"https://stats.example.com\", { period: \"7d\" });\nif (summary.ok) {\n  summary.data.total;         // number\n  summary.data.days;          // [{ day: \"2026-08-21\", count: 12 }, ...] gap-free\n  summary.data.generated_at;  // when the data was actually fetched upstream\n} else {\n  summary.code; // \"invalid_period\" | \"upstream_unavailable\" | \"network\" | \"invalid_response\"\n}\n\nconst pages = await fetchPages(\"https://stats.example.com\"); // top 20, count desc\n```\n\nDeployments choose which stats **panels** they expose (referrers,\nbrowsers, systems, sizes, locations, languages, campaigns — all\naggregate). The policy is discoverable, and every panel shares one shape:\n\n```ts\nimport { fetchPanels, fetchPanel } from \"@byteflavour/goatcounter-stats-client\";\n\nconst policy = await fetchPanels(base);            // { panels: [\"summary\", ...] }\nconst refs = await fetchPanel(base, \"referrers\");  // { items: [{ name, count }] }\n// panel disabled by the deployment -> { ok: false, code: \"panel_disabled\" }\n```\n\n`generated_at` is the honesty field: the gateway serves cached — and\nduring backend outages, stale — data by design; this tells your UI how\nfresh the numbers are.\n\n## `<goatcounter-stats>` element\n\n```ts\nimport \"@byteflavour/goatcounter-stats-client/element\";\n```\n\n```html\n<goatcounter-stats gateway=\"https://stats.example.com\" period=\"30d\"></goatcounter-stats>\n```\n\n| Attribute | Meaning |\n|---|---|\n| `gateway` | Base URL of the gateway (required) |\n| `period`  | `7d` or `30d` (default `30d`) |\n| `panels`  | Optional restriction (e.g. `summary,referrers`), intersected with the deployment's policy |\n\nState: `data-state=\"loading\" | \"ready\" | \"error\"` on the host element.\n\nThe element is **self-configuring**: it discovers the deployment's\nenabled panels and renders them all (empty ones skipped) — server-side\npolicy changes reshape every embedding page automatically.\n\n### Styling\n\nShadow DOM inside; the public interface is CSS custom properties and parts:\n\n```css\ngoatcounter-stats {\n  --gcs-accent: #e91e63;   /* total figure + default bar color */\n  --gcs-bar: #7b1fa2;      /* chart bars */\n  --gcs-text: inherit;\n  --gcs-muted: #999;       /* captions, per-page counts */\n  --gcs-gap: 2px;\n  --gcs-chart-height: 4rem;\n}\ngoatcounter-stats::part(page) { border-bottom: 1px solid #eee; }\ngoatcounter-stats[data-state=\"error\"] { opacity: 0.6; }\n```\n\nParts: `total`, `chart`, `bar`, `pages`, `page`, `panel`, `panel-title`, `error`.\n\nIt's a standard custom element — plain HTML, Vue, React, Angular, no\nwrappers needed. (Vue/Nuxt: mark the tag as a custom element in\n`compilerOptions.isCustomElement`.)\n\n## License\n\nMIT. Part of the goatcounter-stats-gateway project — full documentation\nships with each gateway release.\n","readmeFilename":"README.md"}