@iann29/rastro 0.1.0-alpha.4 → 0.1.0-alpha.6
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.
- package/README.md +203 -56
- package/agent/integration.md +17 -15
- package/agent/manifest.json +6 -4
- package/agent/manifest.schema.json +8 -5
- package/dist/client/federation.d.ts +34 -8
- package/dist/client/federation.d.ts.map +1 -1
- package/dist/client/federation.js +17 -3
- package/dist/client/federation.js.map +1 -1
- package/dist/client/index.d.ts +486 -31
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +209 -41
- package/dist/client/index.js.map +1 -1
- package/dist/component/_generated/api.d.ts +8 -0
- package/dist/component/_generated/api.d.ts.map +1 -1
- package/dist/component/_generated/api.js.map +1 -1
- package/dist/component/_generated/component.d.ts +82 -8
- package/dist/component/_generated/component.d.ts.map +1 -1
- package/dist/component/affiliates.d.ts.map +1 -1
- package/dist/component/affiliates.js +6 -2
- package/dist/component/affiliates.js.map +1 -1
- package/dist/component/cardinality.d.ts.map +1 -1
- package/dist/component/cardinality.js.map +1 -1
- package/dist/component/constants.d.ts +6 -0
- package/dist/component/constants.d.ts.map +1 -1
- package/dist/component/constants.js +12 -0
- package/dist/component/constants.js.map +1 -1
- package/dist/component/diagnostics.d.ts.map +1 -1
- package/dist/component/diagnostics.js.map +1 -1
- package/dist/component/eventStore.d.ts +3 -1
- package/dist/component/eventStore.d.ts.map +1 -1
- package/dist/component/eventStore.js +13 -10
- package/dist/component/eventStore.js.map +1 -1
- package/dist/component/funnels.d.ts.map +1 -1
- package/dist/component/funnels.js +5 -3
- package/dist/component/funnels.js.map +1 -1
- package/dist/component/geo.d.ts.map +1 -1
- package/dist/component/geo.js +3 -2
- package/dist/component/geo.js.map +1 -1
- package/dist/component/goals.d.ts.map +1 -1
- package/dist/component/goals.js +8 -5
- package/dist/component/goals.js.map +1 -1
- package/dist/component/guards.d.ts.map +1 -1
- package/dist/component/guards.js.map +1 -1
- package/dist/component/http.d.ts.map +1 -1
- package/dist/component/http.js +71 -37
- package/dist/component/http.js.map +1 -1
- package/dist/component/identity.d.ts +13 -0
- package/dist/component/identity.d.ts.map +1 -0
- package/dist/component/identity.js +58 -0
- package/dist/component/identity.js.map +1 -0
- package/dist/component/ingest.d.ts +3 -1
- package/dist/component/ingest.d.ts.map +1 -1
- package/dist/component/ingest.js +168 -29
- package/dist/component/ingest.js.map +1 -1
- package/dist/component/live.d.ts.map +1 -1
- package/dist/component/live.js +1 -3
- package/dist/component/live.js.map +1 -1
- package/dist/component/reports.d.ts +70 -4
- package/dist/component/reports.d.ts.map +1 -1
- package/dist/component/reports.js +232 -59
- package/dist/component/reports.js.map +1 -1
- package/dist/component/retention.d.ts +4 -4
- package/dist/component/retention.d.ts.map +1 -1
- package/dist/component/retention.js +54 -22
- package/dist/component/retention.js.map +1 -1
- package/dist/component/sanitize.d.ts.map +1 -1
- package/dist/component/sanitize.js +42 -11
- package/dist/component/sanitize.js.map +1 -1
- package/dist/component/schema.d.ts +83 -10
- package/dist/component/schema.js +34 -1
- package/dist/component/schema.js.map +1 -1
- package/dist/component/sites.d.ts.map +1 -1
- package/dist/component/sites.js +6 -6
- package/dist/component/sites.js.map +1 -1
- package/dist/component/useragent.d.ts +9 -0
- package/dist/component/useragent.d.ts.map +1 -0
- package/dist/component/useragent.js +152 -0
- package/dist/component/useragent.js.map +1 -0
- package/dist/component/validators.d.ts +29 -18
- package/dist/component/validators.d.ts.map +1 -1
- package/dist/component/validators.js +8 -2
- package/dist/component/validators.js.map +1 -1
- package/dist/component/visitors.d.ts +19 -0
- package/dist/component/visitors.d.ts.map +1 -0
- package/dist/component/visitors.js +86 -0
- package/dist/component/visitors.js.map +1 -0
- package/dist/component/vitals.d.ts +41 -0
- package/dist/component/vitals.d.ts.map +1 -0
- package/dist/component/vitals.js +115 -0
- package/dist/component/vitals.js.map +1 -0
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js.map +1 -1
- package/dist/tracker/generated.d.ts +8 -4
- package/dist/tracker/generated.d.ts.map +1 -1
- package/dist/tracker/generated.js +8 -4
- package/dist/tracker/generated.js.map +1 -1
- package/dist/tracker/tracker.d.ts.map +1 -1
- package/dist/tracker/tracker.js +23 -11
- package/dist/tracker/tracker.js.map +1 -1
- package/dist/tracker/vitals.d.ts +10 -0
- package/dist/tracker/vitals.d.ts.map +1 -0
- package/dist/tracker/vitals.js +137 -0
- package/dist/tracker/vitals.js.map +1 -0
- package/dist/tracker.min.js +1 -1
- package/dist/vitals.min.js +1 -0
- package/docs/benchmarks/2026-08-20-realistic.md +71 -71
- package/docs/benchmarks/2026-08-21-formal-certification.md +50 -30
- package/docs/benchmarks/2026-08-30-alpha6-recertification.md +206 -0
- package/docs/federation.md +1 -1
- package/package.json +27 -9
- package/scripts/benchmark-ingest.mjs +101 -48
- package/src/component/_generated/api.ts +8 -0
- package/src/component/_generated/component.ts +87 -5
- package/src/component/affiliates.ts +20 -5
- package/src/component/cardinality.ts +8 -7
- package/src/component/constants.ts +12 -0
- package/src/component/diagnostics.ts +3 -2
- package/src/component/eventStore.ts +53 -46
- package/src/component/funnels.ts +19 -16
- package/src/component/geo.ts +16 -14
- package/src/component/goals.ts +29 -21
- package/src/component/guards.ts +3 -1
- package/src/component/http.ts +126 -78
- package/src/component/identity.ts +74 -0
- package/src/component/ingest.ts +349 -130
- package/src/component/live.ts +5 -4
- package/src/component/reports.ts +572 -221
- package/src/component/retention.ts +221 -98
- package/src/component/sanitize.ts +77 -27
- package/src/component/schema.ts +46 -5
- package/src/component/sites.ts +22 -11
- package/src/component/useragent.ts +171 -0
- package/src/component/validators.ts +19 -7
- package/src/component/visitors.ts +116 -0
- package/src/component/vitals.ts +146 -0
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
Privacy-first, real-time web analytics built as an isolated Convex component.
|
|
6
6
|
|
|
7
|
-
Amage Rastro combines a 1
|
|
7
|
+
Amage Rastro combines a 1.1 KB gzip browser tracker with reactive traffic
|
|
8
8
|
metrics, a live visitor atlas, journey timelines, trusted payment attribution,
|
|
9
9
|
goals, funnels, affiliates, and multi-site reports. Data and functions stay
|
|
10
10
|
inside your Convex deployment.
|
|
@@ -27,26 +27,32 @@ Public integration documentation is available at
|
|
|
27
27
|
should start with [`llms.txt`](https://www.amagerastro.com/llms.txt) and verify
|
|
28
28
|
the [machine manifest](https://www.amagerastro.com/agent/manifest.json).
|
|
29
29
|
|
|
30
|
-
Current evidence supports more than
|
|
31
|
-
traffic
|
|
32
|
-
|
|
33
|
-
|
|
30
|
+
Current evidence supports more than 140 million stored events/day for realistic
|
|
31
|
+
traffic and more than 178 million for lean traffic. Near-limit heavy payloads
|
|
32
|
+
are certified at 55.26 million/day on a data-heavy store (76.62 million/day on a
|
|
33
|
+
fresh store, 2026-08-22). The feature-saturated profile currently fails
|
|
34
|
+
certification on a known rollup-contention defect
|
|
35
|
+
([#52](https://github.com/amageweb/amage-rastro/issues/52)). Workload-specific
|
|
36
|
+
results and caveats are reported separately rather than collapsed into one
|
|
37
|
+
capacity claim.
|
|
34
38
|
|
|
35
39
|
## What ships
|
|
36
40
|
|
|
37
|
-
| Capability | Implementation
|
|
38
|
-
| --------------------------- |
|
|
39
|
-
| Live visitor map | Reactive live sessions with coarse city-level coordinates and TTL expiry
|
|
40
|
-
| Traffic analytics | Sharded hour/day rollups, time series, top pages, sources, countries, devices, browsers, and events
|
|
41
|
-
|
|
|
42
|
-
|
|
|
43
|
-
|
|
|
44
|
-
|
|
|
45
|
-
|
|
|
46
|
-
|
|
|
47
|
-
|
|
|
48
|
-
|
|
|
49
|
-
|
|
|
41
|
+
| Capability | Implementation |
|
|
42
|
+
| --------------------------- | -------------------------------------------------------------------------------------------------------- |
|
|
43
|
+
| Live visitor map | Reactive live sessions with coarse city-level coordinates and TTL expiry |
|
|
44
|
+
| Traffic analytics | Sharded hour/day rollups, time series, top pages, sources, countries, devices, browsers, and events |
|
|
45
|
+
| Field Web Vitals | Opt-in tracker module reporting LCP, CLS, INP, FCP, and TTFB into bounded per-page daily histograms |
|
|
46
|
+
| Journey replay | Bounded pageview/click/custom-event timelines; no DOM, keystroke, or form-value recording |
|
|
47
|
+
| Payment conversion tracking | Trusted server-side ledger with idempotent event IDs and canonical site currency |
|
|
48
|
+
| Goals and funnels | Exact pageview/custom-event goals and ordered conversion funnels |
|
|
49
|
+
| Affiliates | Referral attribution, trusted revenue, and commission accounting |
|
|
50
|
+
| Cross-site analytics | Reports over up to ten authorized site IDs with a preloaded pseudonymous visitor ID |
|
|
51
|
+
| Automatic GeoIP | Opt-in native request metadata plus IPinfo/IPWhois fallback; bounded quota and no raw-IP persistence |
|
|
52
|
+
| Auto-captured clicks | Anchors, buttons, and `data-rastro-event` controls with a bounded visible label; outbound origin+path |
|
|
53
|
+
| Bot filtering | Self-declared crawlers, unfurlers, monitors, HTTP libraries, and headless browsers rejected at ingestion |
|
|
54
|
+
| Cookieless mode | Session-scoped pseudonymous IDs in `sessionStorage`; no cookies |
|
|
55
|
+
| Tiny tracker | 2,132 bytes raw, 1,127 bytes gzip; the test suite enforces `< 1,280` bytes gzip |
|
|
50
56
|
|
|
51
57
|
## Quickstart
|
|
52
58
|
|
|
@@ -89,11 +95,12 @@ app.use(rastro, { httpPrefix: "/rastro/" });
|
|
|
89
95
|
export default app;
|
|
90
96
|
```
|
|
91
97
|
|
|
92
|
-
This creates isolated component tables and
|
|
98
|
+
This creates isolated component tables and five HTTP routes:
|
|
93
99
|
|
|
94
100
|
- `POST /rastro/events` — browser event ingestion
|
|
95
101
|
- `OPTIONS /rastro/events` — CORS preflight
|
|
96
102
|
- `GET /rastro/tracker.js` — the pre-gzipped tracker
|
|
103
|
+
- `GET /rastro/vitals.js` — the pre-gzipped, opt-in Web Vitals module
|
|
97
104
|
- `GET /rastro/health` — integration health
|
|
98
105
|
|
|
99
106
|
Push the component and regenerate host bindings before importing
|
|
@@ -175,6 +182,40 @@ the internal `geo:probe` action. If health reports no usable client IP, use
|
|
|
175
182
|
trusted Vercel/Cloudflare geographic headers with `RASTRO_TRUST_PROXY` or fix
|
|
176
183
|
the deployment's proxy forwarding.
|
|
177
184
|
|
|
185
|
+
### Browser and device classification
|
|
186
|
+
|
|
187
|
+
The tracker sends no client identification. Ingestion derives `browser`, `os`,
|
|
188
|
+
and `device` from headers the browser attaches itself, and persists only those
|
|
189
|
+
three normalized values; the raw `User-Agent` never reaches a mutation or a
|
|
190
|
+
component table.
|
|
191
|
+
|
|
192
|
+
Chromium attaches the low-entropy `Sec-CH-UA`, `Sec-CH-UA-Mobile`, and
|
|
193
|
+
`Sec-CH-UA-Platform` client hints to cross-origin requests from secure origins,
|
|
194
|
+
with no `Accept-CH` opt-in required of the tracked site. They are preferred when
|
|
195
|
+
present, because they are the only signal separating Brave, Opera, Vivaldi,
|
|
196
|
+
Samsung Internet, Yandex, and bare Chromium from Chrome: Brave ships Chrome's
|
|
197
|
+
`User-Agent` verbatim by design. Hint brands are allowlisted, so an unrecognized
|
|
198
|
+
or forged brand falls back to the `User-Agent` instead of entering the browser
|
|
199
|
+
dimension verbatim.
|
|
200
|
+
|
|
201
|
+
The `User-Agent` remains the fallback for Firefox and Safari, which implement no
|
|
202
|
+
client hints, and for insecure origins, which receive none. Known limits of that
|
|
203
|
+
path:
|
|
204
|
+
|
|
205
|
+
- iPadOS 13+ requests sites with a Macintosh `User-Agent` by default and Safari
|
|
206
|
+
sends no hints, so those sessions are reported as desktop macOS.
|
|
207
|
+
- Without hints every Android client is reported as mobile;
|
|
208
|
+
`Sec-CH-UA-Mobile: ?0` on the Android platform is the only available tablet
|
|
209
|
+
signal, because the explicit `Sec-CH-UA-Form-Factors` hint is high entropy and
|
|
210
|
+
would require an `Accept-CH` opt-in and a permissions-policy delegation from
|
|
211
|
+
every tracked site.
|
|
212
|
+
- Known bots are rejected at ingestion by `User-Agent`: self-declared crawlers,
|
|
213
|
+
link unfurlers, uptime monitors, HTTP libraries, headless browsers, and any
|
|
214
|
+
agent carrying a URL. The response keeps the usual counters with `rejected`
|
|
215
|
+
set and adds `X-Rastro-Rejected: bot`; overview metadata reports
|
|
216
|
+
`botDetection` as `userAgent`. A scripted browser that spoofs a stock
|
|
217
|
+
`User-Agent` is still counted as an ordinary session.
|
|
218
|
+
|
|
178
219
|
### 3. Create a site
|
|
179
220
|
|
|
180
221
|
Components cannot read the host app's authentication state. The host must
|
|
@@ -264,6 +305,29 @@ serves the script and ingestion from different origins:
|
|
|
264
305
|
></script>
|
|
265
306
|
```
|
|
266
307
|
|
|
308
|
+
### Field Web Vitals (optional)
|
|
309
|
+
|
|
310
|
+
A second, separate module measures real-visitor LCP, CLS, INP, FCP, and TTFB
|
|
311
|
+
with `PerformanceObserver` and reports them once per page load, when the tab is
|
|
312
|
+
first hidden. It stays out of `tracker.js` so the base tracker keeps its byte
|
|
313
|
+
budget; add it only where you want performance data:
|
|
314
|
+
|
|
315
|
+
```html
|
|
316
|
+
<script
|
|
317
|
+
defer
|
|
318
|
+
data-site="YOUR_SITE_ID"
|
|
319
|
+
src="https://YOUR_DEPLOYMENT.convex.site/rastro/vitals.js"
|
|
320
|
+
></script>
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
The module shares the tracker's session identity through `sessionStorage`,
|
|
324
|
+
accepts the same `data-endpoint` and `data-visitor` overrides, and works with or
|
|
325
|
+
without the base tracker on the page. Measurements are attributed to the landing
|
|
326
|
+
path of the page load, never to later SPA routes. Vitals feed only the
|
|
327
|
+
`vitalsReport` histograms — analytics event counts, sessions, and live presence
|
|
328
|
+
do not change. Browsers without an entry type simply skip that metric (Safari
|
|
329
|
+
reports no LCP, CLS, or INP).
|
|
330
|
+
|
|
267
331
|
### React
|
|
268
332
|
|
|
269
333
|
React is an optional peer dependency. It is required only when importing the
|
|
@@ -332,6 +396,12 @@ For declarative click capture:
|
|
|
332
396
|
</button>
|
|
333
397
|
```
|
|
334
398
|
|
|
399
|
+
Auto-captured clicks record the control's visible text, bounded to 64 characters
|
|
400
|
+
and whitespace-normalized, so journeys read "Clicked «View pricing»" without
|
|
401
|
+
annotation. `data-rastro-label` replaces that text; use it on controls whose
|
|
402
|
+
copy may contain personal data. Input values are never read. Outbound links keep
|
|
403
|
+
their origin and pathname; internal links keep the pathname.
|
|
404
|
+
|
|
335
405
|
Properties accept bounded string, number, boolean, or null values. Never send
|
|
336
406
|
emails, names, form values, secrets, or other personal data as analytics
|
|
337
407
|
properties.
|
|
@@ -342,6 +412,46 @@ session or with a timestamp in another minute is allowed. The tracker preserves
|
|
|
342
412
|
timestamps when retrying. Trusted payment event IDs remain separately
|
|
343
413
|
payload-bound by the site's financial ledger.
|
|
344
414
|
|
|
415
|
+
## Attribute campaigns
|
|
416
|
+
|
|
417
|
+
The tracker reads `utm_source`, `utm_medium`, `utm_campaign`, `utm_term`, and
|
|
418
|
+
`utm_content` from the landing URL, keeps them in `sessionStorage` for the rest
|
|
419
|
+
of the session, and sends them as properties of every pageview; no other query
|
|
420
|
+
parameter ever leaves the page. A session's `source` is the lowercase
|
|
421
|
+
`utm_source` when present and the referrer host otherwise, so campaign traffic
|
|
422
|
+
no longer reads as `direct`. `utmSource`, `utmMedium`, and `utmCampaign` stay on
|
|
423
|
+
the session for journeys, and `overview.topCampaigns` ranks `utm_campaign` by
|
|
424
|
+
event volume next to `topSources`.
|
|
425
|
+
|
|
426
|
+
## Identify visitors after signup
|
|
427
|
+
|
|
428
|
+
Anonymous sessions carry a random `visitorId` until the host supplies a
|
|
429
|
+
pseudonymous one through `data-visitor` or the `RastroScript` `visitorId` prop.
|
|
430
|
+
To keep the anonymous history when a visitor creates an account or signs in,
|
|
431
|
+
link the two ids from the trusted server path, never from the browser:
|
|
432
|
+
|
|
433
|
+
```js
|
|
434
|
+
const { visitorId: anonymousVisitorId } = window.rastro("context");
|
|
435
|
+
// Send anonymousVisitorId with the signup or sign-in request.
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
```ts
|
|
439
|
+
await analytics.linkVisitor(ctx, {
|
|
440
|
+
siteId,
|
|
441
|
+
visitorId: user.analyticsId, // the value later passed to the tracker
|
|
442
|
+
previousVisitorId: anonymousVisitorId,
|
|
443
|
+
});
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
`visitorJourney` for either id then returns one chronological journey; every
|
|
447
|
+
event keeps the id it was recorded with. Links are idempotent, an anonymous id
|
|
448
|
+
belongs to at most one identity, a linked id cannot be linked again, chains and
|
|
449
|
+
identity merges are rejected, and an identity holds at most ten aliases. The
|
|
450
|
+
tracker still sets no cookie: the host's own session identifies the account and
|
|
451
|
+
the anonymous id lives only in `sessionStorage`. Linking anonymous history to an
|
|
452
|
+
account turns it into personal data under the host's privacy policy; disclose it
|
|
453
|
+
and offer an opt-out.
|
|
454
|
+
|
|
345
455
|
## Attribute trusted payments
|
|
346
456
|
|
|
347
457
|
Browser-created conversion events are untrusted telemetry and never affect
|
|
@@ -428,8 +538,8 @@ functions.
|
|
|
428
538
|
|
|
429
539
|
### Federated dashboard backend
|
|
430
540
|
|
|
431
|
-
The reference control plane in `
|
|
432
|
-
telemetry remains in the customer's deployment. It uses
|
|
541
|
+
The reference control plane in `control-plane/` can connect a central dashboard
|
|
542
|
+
while telemetry remains in the customer's deployment. It uses
|
|
433
543
|
`exposeFederatedAnalyticsApi` with issuer and connection-resolver options. The
|
|
434
544
|
helper constructs its authorization boundary internally; it cannot accept a
|
|
435
545
|
permissive host authorizer. Its surface contains a public protocol v1 manifest,
|
|
@@ -455,7 +565,7 @@ runbook.
|
|
|
455
565
|
The `Rastro` class wraps the component boundary for host functions:
|
|
456
566
|
|
|
457
567
|
- Sites: `createSite`, `updateSite`, `getSite`, `listSites`
|
|
458
|
-
- Ingestion: `ingest`, `trackConversion`
|
|
568
|
+
- Ingestion: `ingest`, `trackConversion`, `linkVisitor`
|
|
459
569
|
- Reports: `overview`, `liveVisitors`, `listSessions`, `sessionJourney`,
|
|
460
570
|
`listConversions`, `visitorJourney`, `goalsReport`, `funnelsReport`,
|
|
461
571
|
`affiliatesReport`, `dataCoverage`
|
|
@@ -472,10 +582,15 @@ cost stays constant instead of increasing with an offset.
|
|
|
472
582
|
|
|
473
583
|
Overview responses label visitor values as either HLL-estimated unique visitors
|
|
474
584
|
or legacy `bucketOccurrences`; legacy aggregate rows are never presented as
|
|
475
|
-
exact uniques.
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
585
|
+
exact uniques. Anonymous sessions from the same device and network within one
|
|
586
|
+
UTC day count as one visitor through a salted daily key, so cookieless visitor
|
|
587
|
+
counts no longer collapse into session counts; runtimes without a client IP fall
|
|
588
|
+
back to one visitor per session, which `/rastro/health` reports as
|
|
589
|
+
`uniqueVisitors: "session"` instead of `"dailyHash"`. Breakdown metadata
|
|
590
|
+
likewise identifies page, source, country, device, browser, and event rankings
|
|
591
|
+
as event-volume counts. Feature status is explicit: outbound-link event volume
|
|
592
|
+
is supported, bot detection rejects self-declared agents by `User-Agent`, and
|
|
593
|
+
session replay and error insights are currently unsupported.
|
|
479
594
|
|
|
480
595
|
All report ranges use integer Unix milliseconds with inclusive `from` and `to`
|
|
481
596
|
boundaries. Range metadata reports `boundary: "inclusive"` and
|
|
@@ -504,6 +619,10 @@ boundaries use different bucket alignment.
|
|
|
504
619
|
- Events per batch: 50
|
|
505
620
|
- Session-minute groups per batch: 4
|
|
506
621
|
- Active goals per exact matcher: 1
|
|
622
|
+
- Web Vitals pages per site and UTC day: 48 tracked page rows, then `(other)`;
|
|
623
|
+
device classes are fixed (desktop, mobile, tablet, unknown)
|
|
624
|
+
- Web Vitals report: complete reads bounded to 5,000 rollup rows across at most
|
|
625
|
+
90 UTC days; wider saturated ranges fail with `REPORT_INCOMPLETE`
|
|
507
626
|
- Primary aggregate shards: 256 hourly and 128 daily, derived from stable
|
|
508
627
|
session identity
|
|
509
628
|
- Funnel and affiliate aggregate shards: 16
|
|
@@ -533,31 +652,42 @@ separately. The browser `feature` profile exercises configured goals, funnels,
|
|
|
533
652
|
and affiliate attribution; trusted conversions require a separate server-side
|
|
534
653
|
driver and certification result.
|
|
535
654
|
|
|
536
|
-
###
|
|
655
|
+
### Certified ingest evidence (2026-08-30)
|
|
537
656
|
|
|
538
657
|
| Profile | Workload | Certified stored/day | p95 latency | 100M/day target |
|
|
539
658
|
| --------- | ------------------------------------------------- | -------------------: | ----------: | --------------- |
|
|
540
|
-
| Lean | Minimal events, maximum batches |
|
|
541
|
-
| Realistic | Reused sessions, browser mix, context, heartbeats |
|
|
542
|
-
| Heavy | 62 KiB requests with bounded custom properties |
|
|
543
|
-
| Feature | Goals, funnels, and affiliate attribution |
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
not
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
659
|
+
| Lean | Minimal events, maximum batches | 178.95M | 4,167 ms | Pass |
|
|
660
|
+
| Realistic | Reused sessions, browser mix, context, heartbeats | 142.04M | 4,953 ms | Pass |
|
|
661
|
+
| Heavy | 62 KiB requests with bounded custom properties | 55.26M | 7,702 ms | Below target |
|
|
662
|
+
| Feature | Goals, funnels, and affiliate attribution | **failed** | — | Defect [#52] |
|
|
663
|
+
|
|
664
|
+
[#52]: https://github.com/amageweb/amage-rastro/issues/52
|
|
665
|
+
|
|
666
|
+
Lean, realistic, and heavy each ran at least ten minutes, completed with zero
|
|
667
|
+
request failures, duplicates, or rejected events, and exactly reconciled the
|
|
668
|
+
expected stored events (the realistic run's reconciliation was re-executed
|
|
669
|
+
exactly after a client-side DNS failure — see the report). The realistic row's
|
|
670
|
+
driver session pool is 4,096: at current speed the historical 2,048-session pool
|
|
671
|
+
pushes single sessions past the documented 120 events/minute budget. Results
|
|
672
|
+
came from one client process against the same non-production Synapse DEV
|
|
673
|
+
deployment and site as the 2026-08-21 certification; they are engineering
|
|
674
|
+
evidence, not a production SLA.
|
|
675
|
+
|
|
676
|
+
Two caveats stand deliberately. The heavy row measured a store already holding
|
|
677
|
+
the battery's own multi-million-event history; the 2026-08-22 fresh-store result
|
|
678
|
+
(76.62M/day) remains valid for that state, and neither number overwrites the
|
|
679
|
+
other. The feature profile cannot currently be certified at all: affiliate
|
|
680
|
+
daily-rollup contention loses ~4–5% of batches under concurrent load
|
|
681
|
+
([#52](https://github.com/amageweb/amage-rastro/issues/52)), so no
|
|
682
|
+
feature-profile capacity is claimed until the fix lands. GeoIP with a provider
|
|
683
|
+
enabled, trusted server-side conversions, and vitals-bearing traffic remain
|
|
684
|
+
separate pending certifications.
|
|
685
|
+
|
|
686
|
+
The full evidence is recorded in
|
|
687
|
+
[`docs/benchmarks/2026-08-30-alpha6-recertification.md`](docs/benchmarks/2026-08-30-alpha6-recertification.md).
|
|
688
|
+
Prior results remain in
|
|
689
|
+
[`docs/benchmarks/2026-08-21-formal-certification.md`](docs/benchmarks/2026-08-21-formal-certification.md)
|
|
690
|
+
and
|
|
561
691
|
[`docs/benchmarks/2026-08-20-realistic.md`](docs/benchmarks/2026-08-20-realistic.md).
|
|
562
692
|
|
|
563
693
|
From a repository checkout, run a duration-based profile against a confirmed
|
|
@@ -637,15 +767,26 @@ Amage Rastro's default tracker:
|
|
|
637
767
|
- sets no cookies;
|
|
638
768
|
- stores a pseudonymous session ID and referral slug in `sessionStorage`;
|
|
639
769
|
- never persists raw visitor IP addresses in component tables;
|
|
770
|
+
- counts anonymous unique visitors through a salted hash of the request IP and
|
|
771
|
+
`User-Agent` that rotates every UTC day, derived in the HTTP action from a
|
|
772
|
+
per-deployment secret; a host-supplied `visitorId` always takes precedence,
|
|
773
|
+
and the raw IP never reaches a mutation or a table;
|
|
774
|
+
- never persists the raw `User-Agent`, only a normalized browser, operating
|
|
775
|
+
system, and device;
|
|
640
776
|
- processes an IP only when an edge supplies geography or an operator enables a
|
|
641
777
|
GeoIP provider, which receives that IP under its own privacy terms;
|
|
642
778
|
- stores only country, city, and coordinates rounded to one decimal place;
|
|
643
|
-
- does not record the DOM, screenshots, keystrokes, form values,
|
|
644
|
-
page text;
|
|
645
|
-
- captures only bounded paths, explicit properties,
|
|
646
|
-
|
|
779
|
+
- does not record the DOM, screenshots, keystrokes, form values, input contents,
|
|
780
|
+
or arbitrary page text;
|
|
781
|
+
- captures only bounded paths, explicit properties, the visible label of a
|
|
782
|
+
clicked link or button (at most 64 characters, replaced by `data-rastro-label`
|
|
783
|
+
when present), and outbound link origins and pathnames;
|
|
647
784
|
- strips query strings and fragments from stored paths and links.
|
|
648
785
|
|
|
786
|
+
The optional Web Vitals module inherits this contract: it reports at most five
|
|
787
|
+
timing numbers per page load (milliseconds, or CLS scaled by 1000) against the
|
|
788
|
+
landing path, and nothing else.
|
|
789
|
+
|
|
649
790
|
Cookieless does not automatically mean consent-exempt in every jurisdiction.
|
|
650
791
|
Review your collection purpose, custom properties, identity strategy, retention
|
|
651
792
|
policy, and local law.
|
|
@@ -666,6 +807,10 @@ synapse dev --once
|
|
|
666
807
|
npm run dev:frontend
|
|
667
808
|
```
|
|
668
809
|
|
|
810
|
+
The root `convex.json` targets the control plane in `control-plane/convex`. The
|
|
811
|
+
reference consumer host in `example/` is a separate Convex app; see
|
|
812
|
+
[`example/README.md`](example/README.md) to run, seed, and pair it.
|
|
813
|
+
|
|
669
814
|
Quality gates:
|
|
670
815
|
|
|
671
816
|
```bash
|
|
@@ -683,11 +828,13 @@ affiliate commission, cross-site journeys, keyset pagination beyond 1,000 rows,
|
|
|
683
828
|
retention, request metadata and GeoIP, exact byte boundaries, HTTP routes, React
|
|
684
829
|
integration, and tracker size/behavior.
|
|
685
830
|
|
|
686
|
-
## Synapse
|
|
831
|
+
## Synapse deployments
|
|
687
832
|
|
|
688
|
-
The
|
|
689
|
-
|
|
690
|
-
`.synapse/` are gitignored.
|
|
833
|
+
The repository root is linked to the private Synapse project whose DEV and PROD
|
|
834
|
+
deployments run the control plane in `control-plane/`. The public-facing site
|
|
835
|
+
URL is resolved from `.env.local`; credentials and `.synapse/` are gitignored.
|
|
836
|
+
The consumer host in `example/` is a separate Convex app with its own deployment
|
|
837
|
+
link; run its CLI commands from that directory.
|
|
691
838
|
|
|
692
839
|
## License
|
|
693
840
|
|
package/agent/integration.md
CHANGED
|
@@ -470,6 +470,7 @@ export const {
|
|
|
470
470
|
goalsReport,
|
|
471
471
|
funnelsReport,
|
|
472
472
|
affiliatesReport,
|
|
473
|
+
vitalsReport,
|
|
473
474
|
dataCoverage,
|
|
474
475
|
} = federated;
|
|
475
476
|
```
|
|
@@ -479,21 +480,22 @@ requires both a valid JWT and a matching, non-revoked local grant.
|
|
|
479
480
|
|
|
480
481
|
## Function contract
|
|
481
482
|
|
|
482
|
-
| Function | Input summary | Important output/behavior
|
|
483
|
-
| ------------------ | ------------------------------------------------------- |
|
|
484
|
-
| `manifest` | `{}` | Static protocol, capabilities, names, and limits; no auth
|
|
485
|
-
| `connectionStatus` | `{}` | Redacted status, protocol version, capabilities, site count
|
|
486
|
-
| `listSites` | `{}` | Only `siteId`, `name`, `currency`, `timezone`, `cookieless`
|
|
487
|
-
| `overview` | `siteIds`, `from`, `to`, optional hour/day interval | Aggregate metrics and time series
|
|
488
|
-
| `liveVisitors` | `siteIds`, `now`, optional limit | At most 500 current visitors
|
|
489
|
-
| `listSessions` | one `siteId`, range, `{numItems,cursor}` keyset options | Paginated sessions
|
|
490
|
-
| `sessionJourney` | one site/session, range, `{numItems,cursor}` options | Paginated bounded events
|
|
491
|
-
| `listConversions` | one site, range, `{numItems,cursor}` options | Paginated trusted server-side conversion ledger
|
|
492
|
-
| `visitorJourney` | site IDs, visitor ID, range, optional limit | Cross-site journey inside the grant only
|
|
493
|
-
| `goalsReport` | one site and range | Read-only goal definitions plus aggregates
|
|
494
|
-
| `funnelsReport` | one site and complete UTC-day range | Read-only definitions/steps plus aggregates; max 90 days
|
|
495
|
-
| `affiliatesReport` | one site and complete UTC-day range | Read-only affiliate definitions plus aggregates
|
|
496
|
-
| `
|
|
483
|
+
| Function | Input summary | Important output/behavior |
|
|
484
|
+
| ------------------ | ------------------------------------------------------- | ---------------------------------------------------------------- |
|
|
485
|
+
| `manifest` | `{}` | Static protocol, capabilities, names, and limits; no auth |
|
|
486
|
+
| `connectionStatus` | `{}` | Redacted status, protocol version, capabilities, site count |
|
|
487
|
+
| `listSites` | `{}` | Only `siteId`, `name`, `currency`, `timezone`, `cookieless` |
|
|
488
|
+
| `overview` | `siteIds`, `from`, `to`, optional hour/day interval | Aggregate metrics and time series |
|
|
489
|
+
| `liveVisitors` | `siteIds`, `now`, optional limit | At most 500 current visitors |
|
|
490
|
+
| `listSessions` | one `siteId`, range, `{numItems,cursor}` keyset options | Paginated sessions |
|
|
491
|
+
| `sessionJourney` | one site/session, range, `{numItems,cursor}` options | Paginated bounded events |
|
|
492
|
+
| `listConversions` | one site, range, `{numItems,cursor}` options | Paginated trusted server-side conversion ledger |
|
|
493
|
+
| `visitorJourney` | site IDs, visitor ID, range, optional limit | Cross-site journey inside the grant only |
|
|
494
|
+
| `goalsReport` | one site and range | Read-only goal definitions plus aggregates |
|
|
495
|
+
| `funnelsReport` | one site and complete UTC-day range | Read-only definitions/steps plus aggregates; max 90 days |
|
|
496
|
+
| `affiliatesReport` | one site and complete UTC-day range | Read-only affiliate definitions plus aggregates |
|
|
497
|
+
| `vitalsReport` | one site and complete UTC-day range | Web Vitals p75/ratings per metric, page, and device; max 90 days |
|
|
498
|
+
| `dataCoverage` | one site and inclusive integer range | Coverage metadata; echoes site ID, no event/visitor/session IDs |
|
|
497
499
|
|
|
498
500
|
The federated surface deliberately excludes ingestion, site mutation, retention
|
|
499
501
|
writes, configuration writes, domains, owner IDs, network IDs, and arbitrary
|
package/agent/manifest.json
CHANGED
|
@@ -15,9 +15,9 @@
|
|
|
15
15
|
"upgrading": "https://www.amagerastro.com/docs/reference/upgrading.md",
|
|
16
16
|
"integrity": {
|
|
17
17
|
"algorithm": "sha256",
|
|
18
|
-
"agent": "
|
|
18
|
+
"agent": "e2faf12674afb40409c268048595856a248d4a4373af4c7a013089364fc9f28b",
|
|
19
19
|
"llms": "8c1da1fea23f95a618c4d636840b793195fceedf05f81394df74e1ed5e3fc4da",
|
|
20
|
-
"protocol": "
|
|
20
|
+
"protocol": "3a5cba45befc3ff0b56828cb207d8ce67ddc0df6bf0280a977d4db8d7f50aaee",
|
|
21
21
|
"setup": "04c61ecef029a99ba95e1002439dbd1e42ca1ce351e6deb0988fb556ffce649e",
|
|
22
22
|
"upgrading": "9ff81b8a5e4a615e284916aeae8c7602f3249093599f60b97066a614db406c5a"
|
|
23
23
|
}
|
|
@@ -67,7 +67,8 @@
|
|
|
67
67
|
"goalsReport": "goalsReport",
|
|
68
68
|
"funnelsReport": "funnelsReport",
|
|
69
69
|
"affiliatesReport": "affiliatesReport",
|
|
70
|
-
"dataCoverage": "dataCoverage"
|
|
70
|
+
"dataCoverage": "dataCoverage",
|
|
71
|
+
"vitalsReport": "vitalsReport"
|
|
71
72
|
},
|
|
72
73
|
"capabilities": [
|
|
73
74
|
"siteSummaries",
|
|
@@ -80,7 +81,8 @@
|
|
|
80
81
|
"goals",
|
|
81
82
|
"funnels",
|
|
82
83
|
"affiliates",
|
|
83
|
-
"dataCoverage"
|
|
84
|
+
"dataCoverage",
|
|
85
|
+
"vitals"
|
|
84
86
|
],
|
|
85
87
|
"limits": {
|
|
86
88
|
"maxSitesPerRequest": 10,
|
|
@@ -167,7 +167,8 @@
|
|
|
167
167
|
"goalsReport",
|
|
168
168
|
"funnelsReport",
|
|
169
169
|
"affiliatesReport",
|
|
170
|
-
"dataCoverage"
|
|
170
|
+
"dataCoverage",
|
|
171
|
+
"vitalsReport"
|
|
171
172
|
],
|
|
172
173
|
"properties": {
|
|
173
174
|
"manifest": { "const": "manifest" },
|
|
@@ -182,14 +183,15 @@
|
|
|
182
183
|
"goalsReport": { "const": "goalsReport" },
|
|
183
184
|
"funnelsReport": { "const": "funnelsReport" },
|
|
184
185
|
"affiliatesReport": { "const": "affiliatesReport" },
|
|
185
|
-
"dataCoverage": { "const": "dataCoverage" }
|
|
186
|
+
"dataCoverage": { "const": "dataCoverage" },
|
|
187
|
+
"vitalsReport": { "const": "vitalsReport" }
|
|
186
188
|
},
|
|
187
189
|
"additionalProperties": false
|
|
188
190
|
},
|
|
189
191
|
"capabilities": {
|
|
190
192
|
"type": "array",
|
|
191
|
-
"minItems":
|
|
192
|
-
"maxItems":
|
|
193
|
+
"minItems": 12,
|
|
194
|
+
"maxItems": 12,
|
|
193
195
|
"uniqueItems": true,
|
|
194
196
|
"items": {
|
|
195
197
|
"enum": [
|
|
@@ -203,7 +205,8 @@
|
|
|
203
205
|
"goals",
|
|
204
206
|
"funnels",
|
|
205
207
|
"affiliates",
|
|
206
|
-
"dataCoverage"
|
|
208
|
+
"dataCoverage",
|
|
209
|
+
"vitals"
|
|
207
210
|
]
|
|
208
211
|
}
|
|
209
212
|
},
|
|
@@ -14,6 +14,27 @@ export declare const FEDERATED_ANALYTICS_ERROR_CODES: Readonly<{
|
|
|
14
14
|
readonly INVALID_SCOPE: "FEDERATION_INVALID_SCOPE";
|
|
15
15
|
readonly SITE_DENIED: "FEDERATION_SITE_DENIED";
|
|
16
16
|
}>;
|
|
17
|
+
/**
|
|
18
|
+
* The protocol-v1 baseline every compatible host must serve. Newer hosts may
|
|
19
|
+
* advertise more functions and capabilities; a dashboard must require only
|
|
20
|
+
* this frozen set, or older hosts would fail verification on every addition.
|
|
21
|
+
*/
|
|
22
|
+
export declare const FEDERATED_ANALYTICS_REQUIRED_FUNCTIONS: Readonly<{
|
|
23
|
+
readonly manifest: "manifest";
|
|
24
|
+
readonly connectionStatus: "connectionStatus";
|
|
25
|
+
readonly listSites: "listSites";
|
|
26
|
+
readonly overview: "overview";
|
|
27
|
+
readonly liveVisitors: "liveVisitors";
|
|
28
|
+
readonly listSessions: "listSessions";
|
|
29
|
+
readonly sessionJourney: "sessionJourney";
|
|
30
|
+
readonly listConversions: "listConversions";
|
|
31
|
+
readonly visitorJourney: "visitorJourney";
|
|
32
|
+
readonly goalsReport: "goalsReport";
|
|
33
|
+
readonly funnelsReport: "funnelsReport";
|
|
34
|
+
readonly affiliatesReport: "affiliatesReport";
|
|
35
|
+
readonly dataCoverage: "dataCoverage";
|
|
36
|
+
}>;
|
|
37
|
+
export declare const FEDERATED_ANALYTICS_REQUIRED_CAPABILITIES: readonly ["siteSummaries", "overview", "liveVisitors", "sessions", "sessionJourney", "conversions", "visitorJourney", "goals", "funnels", "affiliates", "dataCoverage"];
|
|
17
38
|
export declare const FEDERATED_ANALYTICS_CONNECTOR_MANIFEST: Readonly<{
|
|
18
39
|
readonly protocol: "amage-rastro-analytics";
|
|
19
40
|
readonly protocolVersion: 1;
|
|
@@ -32,8 +53,9 @@ export declare const FEDERATED_ANALYTICS_CONNECTOR_MANIFEST: Readonly<{
|
|
|
32
53
|
readonly funnelsReport: "funnelsReport";
|
|
33
54
|
readonly affiliatesReport: "affiliatesReport";
|
|
34
55
|
readonly dataCoverage: "dataCoverage";
|
|
56
|
+
readonly vitalsReport: "vitalsReport";
|
|
35
57
|
}>;
|
|
36
|
-
readonly capabilities: readonly ["siteSummaries", "overview", "liveVisitors", "sessions", "sessionJourney", "conversions", "visitorJourney", "goals", "funnels", "affiliates", "dataCoverage"];
|
|
58
|
+
readonly capabilities: readonly ["siteSummaries", "overview", "liveVisitors", "sessions", "sessionJourney", "conversions", "visitorJourney", "goals", "funnels", "affiliates", "dataCoverage", "vitals"];
|
|
37
59
|
readonly limits: Readonly<{
|
|
38
60
|
readonly maxSitesPerRequest: 10;
|
|
39
61
|
readonly maxSitesPerConnection: 10;
|
|
@@ -75,7 +97,7 @@ export interface FederatedAnalyticsAuthorizerOptions {
|
|
|
75
97
|
resolveConnection: ResolveFederatedAnalyticsConnection;
|
|
76
98
|
}
|
|
77
99
|
export declare const federatedAnalyticsManifestValidator: import("convex/values").VObject<{
|
|
78
|
-
capabilities: ("affiliates" | "conversions" | "dataCoverage" | "funnels" | "goals" | "liveVisitors" | "overview" | "sessionJourney" | "sessions" | "siteSummaries" | "visitorJourney")[];
|
|
100
|
+
capabilities: ("affiliates" | "conversions" | "dataCoverage" | "funnels" | "goals" | "liveVisitors" | "overview" | "sessionJourney" | "sessions" | "siteSummaries" | "visitorJourney" | "vitals")[];
|
|
79
101
|
functions: {
|
|
80
102
|
affiliatesReport: "affiliatesReport";
|
|
81
103
|
connectionStatus: "connectionStatus";
|
|
@@ -90,6 +112,7 @@ export declare const federatedAnalyticsManifestValidator: import("convex/values"
|
|
|
90
112
|
overview: "overview";
|
|
91
113
|
sessionJourney: "sessionJourney";
|
|
92
114
|
visitorJourney: "visitorJourney";
|
|
115
|
+
vitalsReport: "vitalsReport";
|
|
93
116
|
};
|
|
94
117
|
limits: {
|
|
95
118
|
maxJourneyEvents: number;
|
|
@@ -119,6 +142,7 @@ export declare const federatedAnalyticsManifestValidator: import("convex/values"
|
|
|
119
142
|
overview: "overview";
|
|
120
143
|
sessionJourney: "sessionJourney";
|
|
121
144
|
visitorJourney: "visitorJourney";
|
|
145
|
+
vitalsReport: "vitalsReport";
|
|
122
146
|
}, {
|
|
123
147
|
manifest: import("convex/values").VLiteral<"manifest", "required">;
|
|
124
148
|
connectionStatus: import("convex/values").VLiteral<"connectionStatus", "required">;
|
|
@@ -133,8 +157,9 @@ export declare const federatedAnalyticsManifestValidator: import("convex/values"
|
|
|
133
157
|
funnelsReport: import("convex/values").VLiteral<"funnelsReport", "required">;
|
|
134
158
|
affiliatesReport: import("convex/values").VLiteral<"affiliatesReport", "required">;
|
|
135
159
|
dataCoverage: import("convex/values").VLiteral<"dataCoverage", "required">;
|
|
136
|
-
|
|
137
|
-
|
|
160
|
+
vitalsReport: import("convex/values").VLiteral<"vitalsReport", "required">;
|
|
161
|
+
}, "required", "affiliatesReport" | "connectionStatus" | "dataCoverage" | "funnelsReport" | "goalsReport" | "listConversions" | "listSessions" | "listSites" | "liveVisitors" | "manifest" | "overview" | "sessionJourney" | "visitorJourney" | "vitalsReport">;
|
|
162
|
+
capabilities: import("convex/values").VArray<("affiliates" | "conversions" | "dataCoverage" | "funnels" | "goals" | "liveVisitors" | "overview" | "sessionJourney" | "sessions" | "siteSummaries" | "visitorJourney" | "vitals")[], import("convex/values").VUnion<"affiliates" | "conversions" | "dataCoverage" | "funnels" | "goals" | "liveVisitors" | "overview" | "sessionJourney" | "sessions" | "siteSummaries" | "visitorJourney" | "vitals", [import("convex/values").VLiteral<"siteSummaries", "required">, import("convex/values").VLiteral<"overview", "required">, import("convex/values").VLiteral<"liveVisitors", "required">, import("convex/values").VLiteral<"sessions", "required">, import("convex/values").VLiteral<"sessionJourney", "required">, import("convex/values").VLiteral<"conversions", "required">, import("convex/values").VLiteral<"visitorJourney", "required">, import("convex/values").VLiteral<"goals", "required">, import("convex/values").VLiteral<"funnels", "required">, import("convex/values").VLiteral<"affiliates", "required">, import("convex/values").VLiteral<"dataCoverage", "required">, import("convex/values").VLiteral<"vitals", "required">], "required", never>, "required">;
|
|
138
163
|
limits: import("convex/values").VObject<{
|
|
139
164
|
maxJourneyEvents: number;
|
|
140
165
|
maxLiveVisitors: number;
|
|
@@ -148,16 +173,16 @@ export declare const federatedAnalyticsManifestValidator: import("convex/values"
|
|
|
148
173
|
maxLiveVisitors: import("convex/values").VFloat64<number, "required">;
|
|
149
174
|
maxJourneyEvents: import("convex/values").VFloat64<number, "required">;
|
|
150
175
|
}, "required", "maxJourneyEvents" | "maxLiveVisitors" | "maxReportRangeDays" | "maxSitesPerConnection" | "maxSitesPerRequest">;
|
|
151
|
-
}, "required", "capabilities" | "functions" | "functions.affiliatesReport" | "functions.connectionStatus" | "functions.dataCoverage" | "functions.funnelsReport" | "functions.goalsReport" | "functions.listConversions" | "functions.listSessions" | "functions.listSites" | "functions.liveVisitors" | "functions.manifest" | "functions.overview" | "functions.sessionJourney" | "functions.visitorJourney" | "limits" | "limits.maxJourneyEvents" | "limits.maxLiveVisitors" | "limits.maxReportRangeDays" | "limits.maxSitesPerConnection" | "limits.maxSitesPerRequest" | "moduleName" | "protocol" | "protocolVersion">;
|
|
176
|
+
}, "required", "capabilities" | "functions" | "functions.affiliatesReport" | "functions.connectionStatus" | "functions.dataCoverage" | "functions.funnelsReport" | "functions.goalsReport" | "functions.listConversions" | "functions.listSessions" | "functions.listSites" | "functions.liveVisitors" | "functions.manifest" | "functions.overview" | "functions.sessionJourney" | "functions.visitorJourney" | "functions.vitalsReport" | "limits" | "limits.maxJourneyEvents" | "limits.maxLiveVisitors" | "limits.maxReportRangeDays" | "limits.maxSitesPerConnection" | "limits.maxSitesPerRequest" | "moduleName" | "protocol" | "protocolVersion">;
|
|
152
177
|
export declare const federatedAnalyticsConnectionStatusValidator: import("convex/values").VObject<{
|
|
153
|
-
capabilities: ("affiliates" | "conversions" | "dataCoverage" | "funnels" | "goals" | "liveVisitors" | "overview" | "sessionJourney" | "sessions" | "siteSummaries" | "visitorJourney")[];
|
|
178
|
+
capabilities: ("affiliates" | "conversions" | "dataCoverage" | "funnels" | "goals" | "liveVisitors" | "overview" | "sessionJourney" | "sessions" | "siteSummaries" | "visitorJourney" | "vitals")[];
|
|
154
179
|
protocolVersion: 1;
|
|
155
180
|
siteCount: number;
|
|
156
181
|
status: "connected";
|
|
157
182
|
}, {
|
|
158
183
|
status: import("convex/values").VLiteral<"connected", "required">;
|
|
159
184
|
protocolVersion: import("convex/values").VLiteral<1, "required">;
|
|
160
|
-
capabilities: import("convex/values").VArray<("affiliates" | "conversions" | "dataCoverage" | "funnels" | "goals" | "liveVisitors" | "overview" | "sessionJourney" | "sessions" | "siteSummaries" | "visitorJourney")[], import("convex/values").VUnion<"affiliates" | "conversions" | "dataCoverage" | "funnels" | "goals" | "liveVisitors" | "overview" | "sessionJourney" | "sessions" | "siteSummaries" | "visitorJourney", [import("convex/values").VLiteral<"siteSummaries", "required">, import("convex/values").VLiteral<"overview", "required">, import("convex/values").VLiteral<"liveVisitors", "required">, import("convex/values").VLiteral<"sessions", "required">, import("convex/values").VLiteral<"sessionJourney", "required">, import("convex/values").VLiteral<"conversions", "required">, import("convex/values").VLiteral<"visitorJourney", "required">, import("convex/values").VLiteral<"goals", "required">, import("convex/values").VLiteral<"funnels", "required">, import("convex/values").VLiteral<"affiliates", "required">, import("convex/values").VLiteral<"dataCoverage", "required">], "required", never>, "required">;
|
|
185
|
+
capabilities: import("convex/values").VArray<("affiliates" | "conversions" | "dataCoverage" | "funnels" | "goals" | "liveVisitors" | "overview" | "sessionJourney" | "sessions" | "siteSummaries" | "visitorJourney" | "vitals")[], import("convex/values").VUnion<"affiliates" | "conversions" | "dataCoverage" | "funnels" | "goals" | "liveVisitors" | "overview" | "sessionJourney" | "sessions" | "siteSummaries" | "visitorJourney" | "vitals", [import("convex/values").VLiteral<"siteSummaries", "required">, import("convex/values").VLiteral<"overview", "required">, import("convex/values").VLiteral<"liveVisitors", "required">, import("convex/values").VLiteral<"sessions", "required">, import("convex/values").VLiteral<"sessionJourney", "required">, import("convex/values").VLiteral<"conversions", "required">, import("convex/values").VLiteral<"visitorJourney", "required">, import("convex/values").VLiteral<"goals", "required">, import("convex/values").VLiteral<"funnels", "required">, import("convex/values").VLiteral<"affiliates", "required">, import("convex/values").VLiteral<"dataCoverage", "required">, import("convex/values").VLiteral<"vitals", "required">], "required", never>, "required">;
|
|
161
186
|
siteCount: import("convex/values").VFloat64<number, "required">;
|
|
162
187
|
}, "required", "capabilities" | "protocolVersion" | "siteCount" | "status">;
|
|
163
188
|
export declare const federatedSiteSummaryValidator: import("convex/values").VObject<{
|
|
@@ -191,8 +216,9 @@ export declare function createFederatedAnalyticsManifest(): {
|
|
|
191
216
|
funnelsReport: "funnelsReport";
|
|
192
217
|
affiliatesReport: "affiliatesReport";
|
|
193
218
|
dataCoverage: "dataCoverage";
|
|
219
|
+
vitalsReport: "vitalsReport";
|
|
194
220
|
};
|
|
195
|
-
capabilities: ("affiliates" | "conversions" | "dataCoverage" | "funnels" | "goals" | "liveVisitors" | "overview" | "sessionJourney" | "sessions" | "siteSummaries" | "visitorJourney")[];
|
|
221
|
+
capabilities: ("affiliates" | "conversions" | "dataCoverage" | "funnels" | "goals" | "liveVisitors" | "overview" | "sessionJourney" | "sessions" | "siteSummaries" | "visitorJourney" | "vitals")[];
|
|
196
222
|
limits: {
|
|
197
223
|
maxSitesPerRequest: 10;
|
|
198
224
|
maxSitesPerConnection: 10;
|