@iann29/rastro 0.1.0-alpha.0 → 0.1.0-alpha.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.
- package/README.md +98 -18
- package/dist/component/_generated/api.d.ts +7 -1
- package/dist/component/_generated/api.d.ts.map +1 -1
- package/dist/component/_generated/api.js.map +1 -1
- package/dist/component/constants.d.ts +11 -6
- package/dist/component/constants.d.ts.map +1 -1
- package/dist/component/constants.js +11 -6
- package/dist/component/constants.js.map +1 -1
- package/dist/component/convex.config.d.ts +2 -2
- package/dist/component/convex.config.d.ts.map +1 -1
- package/dist/component/convex.config.js +4 -1
- package/dist/component/convex.config.js.map +1 -1
- package/dist/component/eventStore.d.ts +102 -0
- package/dist/component/eventStore.d.ts.map +1 -0
- package/dist/component/eventStore.js +463 -0
- package/dist/component/eventStore.js.map +1 -0
- package/dist/component/goals.d.ts.map +1 -1
- package/dist/component/goals.js +17 -4
- package/dist/component/goals.js.map +1 -1
- package/dist/component/http.d.ts.map +1 -1
- package/dist/component/http.js +39 -7
- package/dist/component/http.js.map +1 -1
- package/dist/component/ingest.d.ts.map +1 -1
- package/dist/component/ingest.js +520 -207
- package/dist/component/ingest.js.map +1 -1
- package/dist/component/live.d.ts +8 -0
- package/dist/component/live.d.ts.map +1 -1
- package/dist/component/live.js +72 -8
- package/dist/component/live.js.map +1 -1
- package/dist/component/migrations.d.ts +17 -0
- package/dist/component/migrations.d.ts.map +1 -0
- package/dist/component/migrations.js +44 -0
- package/dist/component/migrations.js.map +1 -0
- package/dist/component/reports.d.ts +16 -16
- package/dist/component/reports.d.ts.map +1 -1
- package/dist/component/reports.js +228 -65
- package/dist/component/reports.js.map +1 -1
- package/dist/component/retention.d.ts.map +1 -1
- package/dist/component/retention.js +15 -10
- package/dist/component/retention.js.map +1 -1
- package/dist/component/sanitize.d.ts.map +1 -1
- package/dist/component/sanitize.js +11 -3
- package/dist/component/sanitize.js.map +1 -1
- package/dist/component/schema.d.ts +132 -9
- package/dist/component/schema.js +32 -7
- package/dist/component/schema.js.map +1 -1
- package/dist/component/sites.d.ts.map +1 -1
- package/dist/component/sites.js +27 -18
- package/dist/component/sites.js.map +1 -1
- package/dist/component/validators.d.ts +96 -0
- package/dist/component/validators.d.ts.map +1 -1
- package/dist/component/validators.js +12 -0
- package/dist/component/validators.js.map +1 -1
- package/dist/tracker/generated.d.ts +4 -4
- package/dist/tracker/generated.d.ts.map +1 -1
- package/dist/tracker/generated.js +4 -4
- package/dist/tracker/generated.js.map +1 -1
- package/dist/tracker/tracker.js +33 -22
- package/dist/tracker/tracker.js.map +1 -1
- package/dist/tracker.min.js +1 -1
- package/docs/benchmarks/2026-08-20-realistic.md +171 -0
- package/package.json +15 -5
- package/scripts/benchmark-ingest.mjs +499 -0
- package/src/component/_generated/api.ts +7 -1
- package/src/component/constants.ts +11 -6
- package/src/component/convex.config.ts +5 -1
- package/src/component/eventStore.ts +684 -0
- package/src/component/goals.ts +25 -4
- package/src/component/http.ts +49 -6
- package/src/component/ingest.ts +671 -215
- package/src/component/live.ts +83 -8
- package/src/component/migrations.ts +52 -0
- package/src/component/reports.ts +295 -86
- package/src/component/retention.ts +15 -12
- package/src/component/sanitize.ts +10 -3
- package/src/component/schema.ts +35 -7
- package/src/component/sites.ts +31 -18
- package/src/component/validators.ts +16 -0
- package/src/test.ts +2 -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
|
|
7
|
+
Amage Rastro combines a 1,022-byte 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.
|
|
@@ -24,7 +24,7 @@ inside your Convex deployment.
|
|
|
24
24
|
| Cross-site analytics | Reports over up to ten authorized site IDs with a preloaded pseudonymous visitor ID |
|
|
25
25
|
| Auto-captured clicks | Anchors, buttons, outbound links, and explicit `data-rastro-event` controls |
|
|
26
26
|
| Cookieless mode | Session-scoped pseudonymous IDs in `sessionStorage`; no cookies |
|
|
27
|
-
| Tiny tracker | 1,
|
|
27
|
+
| Tiny tracker | 1,909 bytes raw, 1,022 bytes gzip; the test suite enforces `< 1,024` bytes |
|
|
28
28
|
|
|
29
29
|
## Install
|
|
30
30
|
|
|
@@ -172,6 +172,12 @@ Properties accept bounded string, number, boolean, or null values. Never send
|
|
|
172
172
|
emails, names, form values, secrets, or other personal data as analytics
|
|
173
173
|
properties.
|
|
174
174
|
|
|
175
|
+
Browser telemetry exact retries are idempotent within
|
|
176
|
+
`(siteId, sessionId, event-minute, eventId)`. Reusing an event ID in another
|
|
177
|
+
session or with a timestamp in another minute is allowed. The tracker preserves
|
|
178
|
+
timestamps when retrying. Trusted payment event IDs remain separately
|
|
179
|
+
payload-bound by the site's financial ledger.
|
|
180
|
+
|
|
175
181
|
## Attribute trusted payments
|
|
176
182
|
|
|
177
183
|
Browser-created conversion events are untrusted telemetry and never affect
|
|
@@ -271,25 +277,99 @@ The `Rastro` class wraps the component boundary for host functions:
|
|
|
271
277
|
- Retention: `cleanup`
|
|
272
278
|
|
|
273
279
|
Every public function has argument and return validators. Growing reads are
|
|
274
|
-
indexed and bounded. Component pagination uses
|
|
275
|
-
because native `.paginate()` is not supported inside Convex components
|
|
280
|
+
indexed and bounded. Component pagination uses scope-bound opaque keyset cursors
|
|
281
|
+
because native `.paginate()` is not supported inside Convex components; page
|
|
282
|
+
cost stays constant instead of increasing with an offset.
|
|
276
283
|
|
|
277
284
|
## Operational limits
|
|
278
285
|
|
|
279
286
|
- HTTP body: 64 KiB
|
|
280
|
-
- Events per batch:
|
|
281
|
-
-
|
|
282
|
-
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
287
|
+
- Events per batch: 50
|
|
288
|
+
- Session-minute groups per batch: 4
|
|
289
|
+
- Active goals per exact matcher: 1
|
|
290
|
+
- Primary aggregate shards: 256 hourly and 128 daily, derived from stable
|
|
291
|
+
session identity
|
|
292
|
+
- Funnel and affiliate aggregate shards: 16
|
|
293
|
+
- Site ingress budget: 4,096 deterministic per-minute shards, each capped at
|
|
294
|
+
300 events and 512 KiB (1,228,800 admitted events/minute at uniform load)
|
|
295
|
+
- Rate-window storage: one reusable row per active session and site shard
|
|
296
|
+
- Live session timeout: 60 seconds with one bounded five-second expiry sweep per
|
|
297
|
+
site; legacy per-session jobs hand off to that sweep during the cutover
|
|
286
298
|
- Dashboard overview: up to ten sites and bounded report ranges
|
|
299
|
+
- Hourly overview: up to 24 hours; wider ranges use daily buckets
|
|
287
300
|
- Retention cleanup: bounded batches; schedule host maintenance for the data
|
|
288
|
-
classes your policy retains
|
|
301
|
+
classes your policy retains. The `events` cleanup kind covers both legacy
|
|
302
|
+
event rows and new event batches and processes at most 32 heavy batches per
|
|
303
|
+
transaction.
|
|
304
|
+
|
|
305
|
+
Capacity claims use declared workload profiles. Complete release evidence
|
|
306
|
+
reports ten-minute `lean`, `realistic`, `heavy`, and browser `feature` profiles
|
|
307
|
+
separately. The browser `feature` profile exercises configured goals, funnels,
|
|
308
|
+
and affiliate attribution; trusted conversions require a separate server-side
|
|
309
|
+
driver and certification result.
|
|
310
|
+
|
|
311
|
+
The historical development evidence and its certification caveats are recorded
|
|
312
|
+
in [`docs/benchmarks/2026-08-20-realistic.md`](docs/benchmarks/2026-08-20-realistic.md).
|
|
313
|
+
|
|
314
|
+
From a repository checkout, run a duration-based profile against a confirmed
|
|
315
|
+
non-production deployment and a dedicated idle benchmark site:
|
|
316
|
+
|
|
317
|
+
```bash
|
|
318
|
+
npm run --silent benchmark:ingest -- \
|
|
319
|
+
--url https://example.site/rastro/events \
|
|
320
|
+
--convex-url https://example.convex-backend \
|
|
321
|
+
--site-id your_site_id \
|
|
322
|
+
--origin https://your-allowed-origin.example \
|
|
323
|
+
--profile realistic \
|
|
324
|
+
--duration 600 \
|
|
325
|
+
--concurrency 100 \
|
|
326
|
+
--certify
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
Profiles are `lean`, `realistic`, `heavy`, and `feature`. The realistic profile
|
|
330
|
+
reuses sessions and sends geographic and user-agent headers so the same load is
|
|
331
|
+
visible in Live Atlas. Only `feature` intentionally matches the demo goal,
|
|
332
|
+
funnel, and affiliate definitions; it does not call the trusted conversion API.
|
|
333
|
+
Use `--dry-run` to inspect generated request size without sending traffic. When
|
|
334
|
+
`--convex-url` is supplied, it must identify the same deployment as `--url` and
|
|
335
|
+
expose this repository's `example:overview` query. The final reconciliation is
|
|
336
|
+
a site-wide before/after delta, so unrelated traffic on that site invalidates
|
|
337
|
+
the result. Reports distinguish accepted ingress, heartbeats, and stored events.
|
|
338
|
+
Shorter completed runs report extrapolated daily estimates only. `--certify`
|
|
339
|
+
requires at least ten minutes and successful reconciliation before emitting
|
|
340
|
+
certified daily capacity fields or exiting successfully as a certification.
|
|
341
|
+
|
|
342
|
+
The ingestion transaction folds metric/dimension deltas, session rate counters,
|
|
343
|
+
site-shard counters, session/live state, visitor attribution, and exact funnel
|
|
344
|
+
progress before writing. Accepted non-heartbeat telemetry from one request is
|
|
345
|
+
grouped into one immutable raw document per session and event-minute, without
|
|
346
|
+
duplicating session geo or user-agent context. A 50-event same-session,
|
|
347
|
+
same-minute baseline stays within 10 document writes. Each touched aggregate
|
|
348
|
+
bucket is written at most once per batch, and dimension overflow folds into an
|
|
349
|
+
explicit `(other)` bucket instead of relabeling old counts.
|
|
350
|
+
Click/outbound/browser-conversion telemetry skips goal and funnel work that
|
|
351
|
+
cannot match those event types.
|
|
352
|
+
|
|
353
|
+
New telemetry is written only to `eventBatches`. Existing `events` rows remain
|
|
354
|
+
readable until an operator runs the resumable migration mounted inside the
|
|
355
|
+
Rastro component:
|
|
356
|
+
|
|
357
|
+
```bash
|
|
358
|
+
npx convex run --component rastroAnalytics migrations:migrateLegacyEvents \
|
|
359
|
+
'{"dryRun":true,"reset":true}'
|
|
360
|
+
npx convex run --component rastroAnalytics migrations:migrateLegacyEvents '{}'
|
|
361
|
+
npx convex run --component rastroAnalytics migrations:legacyEventsStatus '{}'
|
|
362
|
+
```
|
|
289
363
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
364
|
+
Replace `rastroAnalytics` if the host mounted the component under another name.
|
|
365
|
+
Proceed only when status returns `complete: true`, which requires both durable
|
|
366
|
+
migration success and an empty legacy source. A source refilled after completion
|
|
367
|
+
requires an explicit `{"reset":true}` rerun. Migrated rows are compacted into
|
|
368
|
+
bounded canonical batches and retain their original per-event browser and geo
|
|
369
|
+
context. Journey `_id` values remain stable strings for both formats during the
|
|
370
|
+
cutover, and session-journey cursors use timestamp, creation time, and ID. The
|
|
371
|
+
compatibility logic remains isolated in `src/component/eventStore.ts` until a
|
|
372
|
+
later release removes the empty legacy table and its read paths.
|
|
293
373
|
|
|
294
374
|
## Privacy contract
|
|
295
375
|
|
|
@@ -336,10 +416,10 @@ cd example && npx vite build
|
|
|
336
416
|
```
|
|
337
417
|
|
|
338
418
|
The test suite covers origin enforcement, event/privacy sanitization,
|
|
339
|
-
idempotency, session/site rate limits, live expiry
|
|
340
|
-
writes, goals, funnels, trusted payments, currency safety,
|
|
341
|
-
cross-site journeys,
|
|
342
|
-
integration, and tracker size/behavior.
|
|
419
|
+
idempotency, reusable session/site rate limits, bounded live expiry chains,
|
|
420
|
+
folded aggregate writes, goals, funnels, trusted payments, currency safety,
|
|
421
|
+
affiliate commission, cross-site journeys, keyset pagination beyond 1,000 rows,
|
|
422
|
+
retention, HTTP routes, React integration, and tracker size/behavior.
|
|
343
423
|
|
|
344
424
|
## Synapse demo
|
|
345
425
|
|
|
@@ -9,12 +9,14 @@
|
|
|
9
9
|
import type * as affiliates from "../affiliates.js";
|
|
10
10
|
import type * as constants from "../constants.js";
|
|
11
11
|
import type * as errors from "../errors.js";
|
|
12
|
+
import type * as eventStore from "../eventStore.js";
|
|
12
13
|
import type * as funnels from "../funnels.js";
|
|
13
14
|
import type * as goals from "../goals.js";
|
|
14
15
|
import type * as guards from "../guards.js";
|
|
15
16
|
import type * as http from "../http.js";
|
|
16
17
|
import type * as ingest from "../ingest.js";
|
|
17
18
|
import type * as live from "../live.js";
|
|
19
|
+
import type * as migrations from "../migrations.js";
|
|
18
20
|
import type * as reports from "../reports.js";
|
|
19
21
|
import type * as retention from "../retention.js";
|
|
20
22
|
import type * as sanitize from "../sanitize.js";
|
|
@@ -25,12 +27,14 @@ declare const fullApi: ApiFromModules<{
|
|
|
25
27
|
affiliates: typeof affiliates;
|
|
26
28
|
constants: typeof constants;
|
|
27
29
|
errors: typeof errors;
|
|
30
|
+
eventStore: typeof eventStore;
|
|
28
31
|
funnels: typeof funnels;
|
|
29
32
|
goals: typeof goals;
|
|
30
33
|
guards: typeof guards;
|
|
31
34
|
http: typeof http;
|
|
32
35
|
ingest: typeof ingest;
|
|
33
36
|
live: typeof live;
|
|
37
|
+
migrations: typeof migrations;
|
|
34
38
|
reports: typeof reports;
|
|
35
39
|
retention: typeof retention;
|
|
36
40
|
sanitize: typeof sanitize;
|
|
@@ -55,6 +59,8 @@ export declare const api: FilterApi<typeof fullApi, FunctionReference<any, "publ
|
|
|
55
59
|
* ```
|
|
56
60
|
*/
|
|
57
61
|
export declare const internal: FilterApi<typeof fullApi, FunctionReference<any, "internal">>;
|
|
58
|
-
export declare const components: {
|
|
62
|
+
export declare const components: {
|
|
63
|
+
migrations: import("@convex-dev/migrations/_generated/component.js").ComponentApi<"migrations">;
|
|
64
|
+
};
|
|
59
65
|
export {};
|
|
60
66
|
//# sourceMappingURL=api.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../src/component/_generated/api.ts"],"names":[],"mappings":"AACA;;;;;;;GAOG;AAEH,OAAO,KAAK,KAAK,UAAU,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,KAAK,SAAS,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,KAAK,MAAM,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,KAAK,OAAO,MAAM,eAAe,CAAC;AAC9C,OAAO,KAAK,KAAK,KAAK,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,KAAK,MAAM,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,KAAK,IAAI,MAAM,YAAY,CAAC;AACxC,OAAO,KAAK,KAAK,MAAM,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,KAAK,IAAI,MAAM,YAAY,CAAC;AACxC,OAAO,KAAK,KAAK,OAAO,MAAM,eAAe,CAAC;AAC9C,OAAO,KAAK,KAAK,SAAS,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,KAAK,KAAK,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,KAAK,UAAU,MAAM,kBAAkB,CAAC;AAEpD,OAAO,KAAK,EACV,cAAc,EACd,SAAS,EACT,iBAAiB,EAClB,MAAM,eAAe,CAAC;AAGvB,QAAA,MAAM,OAAO,EAAE,cAAc,CAAC;IAC5B,UAAU,EAAE,OAAO,UAAU,CAAC;IAC9B,SAAS,EAAE,OAAO,SAAS,CAAC;IAC5B,MAAM,EAAE,OAAO,MAAM,CAAC;IACtB,OAAO,EAAE,OAAO,OAAO,CAAC;IACxB,KAAK,EAAE,OAAO,KAAK,CAAC;IACpB,MAAM,EAAE,OAAO,MAAM,CAAC;IACtB,IAAI,EAAE,OAAO,IAAI,CAAC;IAClB,MAAM,EAAE,OAAO,MAAM,CAAC;IACtB,IAAI,EAAE,OAAO,IAAI,CAAC;IAClB,OAAO,EAAE,OAAO,OAAO,CAAC;IACxB,SAAS,EAAE,OAAO,SAAS,CAAC;IAC5B,QAAQ,EAAE,OAAO,QAAQ,CAAC;IAC1B,KAAK,EAAE,OAAO,KAAK,CAAC;IACpB,UAAU,EAAE,OAAO,UAAU,CAAC;CAC/B,CAAiB,CAAC;AAEnB;;;;;;;GAOG;AACH,eAAO,MAAM,GAAG,EAAE,SAAS,CACzB,OAAO,OAAO,EACd,iBAAiB,CAAC,GAAG,EAAE,QAAQ,CAAC,CACjB,CAAC;AAElB;;;;;;;GAOG;AACH,eAAO,MAAM,QAAQ,EAAE,SAAS,CAC9B,OAAO,OAAO,EACd,iBAAiB,CAAC,GAAG,EAAE,UAAU,CAAC,CACnB,CAAC;AAElB,eAAO,MAAM,UAAU,EAAqC,EAAE,CAAC"}
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../src/component/_generated/api.ts"],"names":[],"mappings":"AACA;;;;;;;GAOG;AAEH,OAAO,KAAK,KAAK,UAAU,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,KAAK,SAAS,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,KAAK,MAAM,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,KAAK,UAAU,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,KAAK,OAAO,MAAM,eAAe,CAAC;AAC9C,OAAO,KAAK,KAAK,KAAK,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,KAAK,MAAM,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,KAAK,IAAI,MAAM,YAAY,CAAC;AACxC,OAAO,KAAK,KAAK,MAAM,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,KAAK,IAAI,MAAM,YAAY,CAAC;AACxC,OAAO,KAAK,KAAK,UAAU,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,KAAK,OAAO,MAAM,eAAe,CAAC;AAC9C,OAAO,KAAK,KAAK,SAAS,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,KAAK,KAAK,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,KAAK,UAAU,MAAM,kBAAkB,CAAC;AAEpD,OAAO,KAAK,EACV,cAAc,EACd,SAAS,EACT,iBAAiB,EAClB,MAAM,eAAe,CAAC;AAGvB,QAAA,MAAM,OAAO,EAAE,cAAc,CAAC;IAC5B,UAAU,EAAE,OAAO,UAAU,CAAC;IAC9B,SAAS,EAAE,OAAO,SAAS,CAAC;IAC5B,MAAM,EAAE,OAAO,MAAM,CAAC;IACtB,UAAU,EAAE,OAAO,UAAU,CAAC;IAC9B,OAAO,EAAE,OAAO,OAAO,CAAC;IACxB,KAAK,EAAE,OAAO,KAAK,CAAC;IACpB,MAAM,EAAE,OAAO,MAAM,CAAC;IACtB,IAAI,EAAE,OAAO,IAAI,CAAC;IAClB,MAAM,EAAE,OAAO,MAAM,CAAC;IACtB,IAAI,EAAE,OAAO,IAAI,CAAC;IAClB,UAAU,EAAE,OAAO,UAAU,CAAC;IAC9B,OAAO,EAAE,OAAO,OAAO,CAAC;IACxB,SAAS,EAAE,OAAO,SAAS,CAAC;IAC5B,QAAQ,EAAE,OAAO,QAAQ,CAAC;IAC1B,KAAK,EAAE,OAAO,KAAK,CAAC;IACpB,UAAU,EAAE,OAAO,UAAU,CAAC;CAC/B,CAAiB,CAAC;AAEnB;;;;;;;GAOG;AACH,eAAO,MAAM,GAAG,EAAE,SAAS,CACzB,OAAO,OAAO,EACd,iBAAiB,CAAC,GAAG,EAAE,QAAQ,CAAC,CACjB,CAAC;AAElB;;;;;;;GAOG;AACH,eAAO,MAAM,QAAQ,EAAE,SAAS,CAC9B,OAAO,OAAO,EACd,iBAAiB,CAAC,GAAG,EAAE,UAAU,CAAC,CACnB,CAAC;AAElB,eAAO,MAAM,UAAU,EAAqC;IAC1D,UAAU,EAAE,OAAO,gDAAgD,EAAE,YAAY,CAAC,YAAY,CAAC,CAAC;CACjG,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/component/_generated/api.ts"],"names":[],"mappings":"AAAA,oBAAoB;AACpB;;;;;;;GAOG;
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/component/_generated/api.ts"],"names":[],"mappings":"AAAA,oBAAoB;AACpB;;;;;;;GAOG;AAwBH,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAE1D,MAAM,OAAO,GAiBR,MAAa,CAAC;AAEnB;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,GAAG,GAGZ,MAAa,CAAC;AAElB;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,QAAQ,GAGjB,MAAa,CAAC;AAElB,MAAM,CAAC,MAAM,UAAU,GAAG,iBAAiB,EAE1C,CAAC"}
|
|
@@ -1,13 +1,17 @@
|
|
|
1
|
-
export declare const MAX_BATCH_EVENTS =
|
|
1
|
+
export declare const MAX_BATCH_EVENTS = 50;
|
|
2
|
+
export declare const MAX_BATCH_EVENT_GROUPS = 4;
|
|
2
3
|
export declare const MAX_BATCH_BYTES: number;
|
|
3
4
|
export declare const MAX_EVENTS_PER_SESSION_WINDOW = 120;
|
|
4
5
|
export declare const RATE_LIMIT_WINDOW_MS = 60000;
|
|
5
6
|
export declare const MAX_BYTES_PER_SESSION_WINDOW: number;
|
|
6
|
-
export declare const SITE_INGEST_SHARDS =
|
|
7
|
-
export declare const MAX_SITE_EVENTS_PER_SHARD_WINDOW =
|
|
7
|
+
export declare const SITE_INGEST_SHARDS = 4096;
|
|
8
|
+
export declare const MAX_SITE_EVENTS_PER_SHARD_WINDOW = 300;
|
|
8
9
|
export declare const MAX_SITE_BYTES_PER_SHARD_WINDOW: number;
|
|
9
10
|
export declare const LIVE_SESSION_TTL_MS = 60000;
|
|
10
|
-
export declare const
|
|
11
|
+
export declare const LIVE_SWEEP_INTERVAL_MS = 5000;
|
|
12
|
+
export declare const AGGREGATE_SHARDS = 128;
|
|
13
|
+
export declare const HOURLY_AGGREGATE_SHARDS = 256;
|
|
14
|
+
export declare const SECONDARY_AGGREGATE_SHARDS = 16;
|
|
11
15
|
export declare const DIMENSION_SLOTS = 16;
|
|
12
16
|
export declare const MAX_SITE_DOMAINS = 32;
|
|
13
17
|
export declare const MAX_SITES_PER_OWNER = 100;
|
|
@@ -20,9 +24,10 @@ export declare const MAX_REPORT_SITES = 10;
|
|
|
20
24
|
export declare const MAX_REPORT_RANGE_DAYS = 366;
|
|
21
25
|
export declare const MAX_LIVE_VISITORS = 500;
|
|
22
26
|
export declare const MAX_JOURNEY_EVENTS = 500;
|
|
27
|
+
export declare const JOURNEY_READ_BYTE_RESERVE: number;
|
|
28
|
+
export declare const JOURNEY_READ_DOCUMENT_RESERVE = 1000;
|
|
23
29
|
export declare const MAX_RETENTION_BATCH = 500;
|
|
24
|
-
export declare const MAX_OVERVIEW_AGGREGATE_ROWS =
|
|
30
|
+
export declare const MAX_OVERVIEW_AGGREGATE_ROWS = 13000;
|
|
25
31
|
export declare const DAY_MS = 86400000;
|
|
26
32
|
export declare const HOUR_MS = 3600000;
|
|
27
|
-
export declare const MAX_MANUAL_PAGINATION_OFFSET = 1000;
|
|
28
33
|
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/component/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,KAAK,CAAC;AACnC,eAAO,MAAM,eAAe,QAAY,CAAC;AACzC,eAAO,MAAM,6BAA6B,MAAM,CAAC;AACjD,eAAO,MAAM,oBAAoB,QAAS,CAAC;AAC3C,eAAO,MAAM,4BAA4B,QAAa,CAAC;AACvD,eAAO,MAAM,kBAAkB,
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/component/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,KAAK,CAAC;AACnC,eAAO,MAAM,sBAAsB,IAAI,CAAC;AACxC,eAAO,MAAM,eAAe,QAAY,CAAC;AACzC,eAAO,MAAM,6BAA6B,MAAM,CAAC;AACjD,eAAO,MAAM,oBAAoB,QAAS,CAAC;AAC3C,eAAO,MAAM,4BAA4B,QAAa,CAAC;AACvD,eAAO,MAAM,kBAAkB,OAAQ,CAAC;AACxC,eAAO,MAAM,gCAAgC,MAAM,CAAC;AACpD,eAAO,MAAM,+BAA+B,QAAa,CAAC;AAC1D,eAAO,MAAM,mBAAmB,QAAS,CAAC;AAC1C,eAAO,MAAM,sBAAsB,OAAQ,CAAC;AAC5C,eAAO,MAAM,gBAAgB,MAAM,CAAC;AACpC,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAC3C,eAAO,MAAM,0BAA0B,KAAK,CAAC;AAC7C,eAAO,MAAM,eAAe,KAAK,CAAC;AAClC,eAAO,MAAM,gBAAgB,KAAK,CAAC;AACnC,eAAO,MAAM,mBAAmB,MAAM,CAAC;AACvC,eAAO,MAAM,kBAAkB,KAAK,CAAC;AACrC,eAAO,MAAM,oBAAoB,KAAK,CAAC;AACvC,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAC3C,eAAO,MAAM,gBAAgB,KAAK,CAAC;AACnC,eAAO,MAAM,cAAc,KAAK,CAAC;AACjC,eAAO,MAAM,gBAAgB,KAAK,CAAC;AACnC,eAAO,MAAM,qBAAqB,MAAM,CAAC;AACzC,eAAO,MAAM,iBAAiB,MAAM,CAAC;AACrC,eAAO,MAAM,kBAAkB,MAAM,CAAC;AACtC,eAAO,MAAM,yBAAyB,QAAkB,CAAC;AACzD,eAAO,MAAM,6BAA6B,OAAQ,CAAC;AACnD,eAAO,MAAM,mBAAmB,MAAM,CAAC;AACvC,eAAO,MAAM,2BAA2B,QAAS,CAAC;AAElD,eAAO,MAAM,MAAM,WAAa,CAAC;AACjC,eAAO,MAAM,OAAO,UAAY,CAAC"}
|
|
@@ -1,13 +1,17 @@
|
|
|
1
|
-
export const MAX_BATCH_EVENTS =
|
|
1
|
+
export const MAX_BATCH_EVENTS = 50;
|
|
2
|
+
export const MAX_BATCH_EVENT_GROUPS = 4;
|
|
2
3
|
export const MAX_BATCH_BYTES = 64 * 1024;
|
|
3
4
|
export const MAX_EVENTS_PER_SESSION_WINDOW = 120;
|
|
4
5
|
export const RATE_LIMIT_WINDOW_MS = 60_000;
|
|
5
6
|
export const MAX_BYTES_PER_SESSION_WINDOW = 256 * 1024;
|
|
6
|
-
export const SITE_INGEST_SHARDS =
|
|
7
|
-
export const MAX_SITE_EVENTS_PER_SHARD_WINDOW =
|
|
7
|
+
export const SITE_INGEST_SHARDS = 4_096;
|
|
8
|
+
export const MAX_SITE_EVENTS_PER_SHARD_WINDOW = 300;
|
|
8
9
|
export const MAX_SITE_BYTES_PER_SHARD_WINDOW = 512 * 1024;
|
|
9
10
|
export const LIVE_SESSION_TTL_MS = 60_000;
|
|
10
|
-
export const
|
|
11
|
+
export const LIVE_SWEEP_INTERVAL_MS = 5_000;
|
|
12
|
+
export const AGGREGATE_SHARDS = 128;
|
|
13
|
+
export const HOURLY_AGGREGATE_SHARDS = 256;
|
|
14
|
+
export const SECONDARY_AGGREGATE_SHARDS = 16;
|
|
11
15
|
export const DIMENSION_SLOTS = 16;
|
|
12
16
|
export const MAX_SITE_DOMAINS = 32;
|
|
13
17
|
export const MAX_SITES_PER_OWNER = 100;
|
|
@@ -20,9 +24,10 @@ export const MAX_REPORT_SITES = 10;
|
|
|
20
24
|
export const MAX_REPORT_RANGE_DAYS = 366;
|
|
21
25
|
export const MAX_LIVE_VISITORS = 500;
|
|
22
26
|
export const MAX_JOURNEY_EVENTS = 500;
|
|
27
|
+
export const JOURNEY_READ_BYTE_RESERVE = 4 * 1024 * 1024;
|
|
28
|
+
export const JOURNEY_READ_DOCUMENT_RESERVE = 1_000;
|
|
23
29
|
export const MAX_RETENTION_BATCH = 500;
|
|
24
|
-
export const MAX_OVERVIEW_AGGREGATE_ROWS =
|
|
30
|
+
export const MAX_OVERVIEW_AGGREGATE_ROWS = 13_000;
|
|
25
31
|
export const DAY_MS = 86_400_000;
|
|
26
32
|
export const HOUR_MS = 3_600_000;
|
|
27
|
-
export const MAX_MANUAL_PAGINATION_OFFSET = 1_000;
|
|
28
33
|
//# sourceMappingURL=constants.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/component/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,gBAAgB,GAAG,EAAE,CAAC;AACnC,MAAM,CAAC,MAAM,eAAe,GAAG,EAAE,GAAG,IAAI,CAAC;AACzC,MAAM,CAAC,MAAM,6BAA6B,GAAG,GAAG,CAAC;AACjD,MAAM,CAAC,MAAM,oBAAoB,GAAG,MAAM,CAAC;AAC3C,MAAM,CAAC,MAAM,4BAA4B,GAAG,GAAG,GAAG,IAAI,CAAC;AACvD,MAAM,CAAC,MAAM,kBAAkB,GAAG,
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/component/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,gBAAgB,GAAG,EAAE,CAAC;AACnC,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC;AACxC,MAAM,CAAC,MAAM,eAAe,GAAG,EAAE,GAAG,IAAI,CAAC;AACzC,MAAM,CAAC,MAAM,6BAA6B,GAAG,GAAG,CAAC;AACjD,MAAM,CAAC,MAAM,oBAAoB,GAAG,MAAM,CAAC;AAC3C,MAAM,CAAC,MAAM,4BAA4B,GAAG,GAAG,GAAG,IAAI,CAAC;AACvD,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,CAAC;AACxC,MAAM,CAAC,MAAM,gCAAgC,GAAG,GAAG,CAAC;AACpD,MAAM,CAAC,MAAM,+BAA+B,GAAG,GAAG,GAAG,IAAI,CAAC;AAC1D,MAAM,CAAC,MAAM,mBAAmB,GAAG,MAAM,CAAC;AAC1C,MAAM,CAAC,MAAM,sBAAsB,GAAG,KAAK,CAAC;AAC5C,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAG,CAAC;AACpC,MAAM,CAAC,MAAM,uBAAuB,GAAG,GAAG,CAAC;AAC3C,MAAM,CAAC,MAAM,0BAA0B,GAAG,EAAE,CAAC;AAC7C,MAAM,CAAC,MAAM,eAAe,GAAG,EAAE,CAAC;AAClC,MAAM,CAAC,MAAM,gBAAgB,GAAG,EAAE,CAAC;AACnC,MAAM,CAAC,MAAM,mBAAmB,GAAG,GAAG,CAAC;AACvC,MAAM,CAAC,MAAM,kBAAkB,GAAG,EAAE,CAAC;AACrC,MAAM,CAAC,MAAM,oBAAoB,GAAG,EAAE,CAAC;AACvC,MAAM,CAAC,MAAM,uBAAuB,GAAG,GAAG,CAAC;AAC3C,MAAM,CAAC,MAAM,gBAAgB,GAAG,EAAE,CAAC;AACnC,MAAM,CAAC,MAAM,cAAc,GAAG,EAAE,CAAC;AACjC,MAAM,CAAC,MAAM,gBAAgB,GAAG,EAAE,CAAC;AACnC,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAG,CAAC;AACzC,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,CAAC;AACrC,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAG,CAAC;AACtC,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;AACzD,MAAM,CAAC,MAAM,6BAA6B,GAAG,KAAK,CAAC;AACnD,MAAM,CAAC,MAAM,mBAAmB,GAAG,GAAG,CAAC;AACvC,MAAM,CAAC,MAAM,2BAA2B,GAAG,MAAM,CAAC;AAElD,MAAM,CAAC,MAAM,MAAM,GAAG,UAAU,CAAC;AACjC,MAAM,CAAC,MAAM,OAAO,GAAG,SAAS,CAAC"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
declare const
|
|
2
|
-
export default
|
|
1
|
+
declare const component: import("convex/server").ComponentDefinition<any, {}>;
|
|
2
|
+
export default component;
|
|
3
3
|
//# sourceMappingURL=convex.config.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"convex.config.d.ts","sourceRoot":"","sources":["../../src/component/convex.config.ts"],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"convex.config.d.ts","sourceRoot":"","sources":["../../src/component/convex.config.ts"],"names":[],"mappings":"AAGA,QAAA,MAAM,SAAS,sDAAqC,CAAC;eAGtC,SAAS"}
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import migrations from "@convex-dev/migrations/convex.config.js";
|
|
1
2
|
import { defineComponent } from "convex/server";
|
|
2
|
-
|
|
3
|
+
const component = defineComponent("rastroAnalytics");
|
|
4
|
+
component.use(migrations);
|
|
5
|
+
export default component;
|
|
3
6
|
//# sourceMappingURL=convex.config.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"convex.config.js","sourceRoot":"","sources":["../../src/component/convex.config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD,
|
|
1
|
+
{"version":3,"file":"convex.config.js","sourceRoot":"","sources":["../../src/component/convex.config.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,yCAAyC,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD,MAAM,SAAS,GAAG,eAAe,CAAC,iBAAiB,CAAC,CAAC;AACrD,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;AAE1B,eAAe,SAAS,CAAC"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import type { Doc, Id } from "./_generated/dataModel.js";
|
|
2
|
+
import type { MutationCtx, QueryCtx } from "./_generated/server.js";
|
|
3
|
+
import type { TrackerEvent } from "./validators.js";
|
|
4
|
+
export type TelemetryMatch = {
|
|
5
|
+
sessionId: string;
|
|
6
|
+
visitorId: string;
|
|
7
|
+
country?: string;
|
|
8
|
+
city?: string;
|
|
9
|
+
latitude?: number;
|
|
10
|
+
longitude?: number;
|
|
11
|
+
browser?: string;
|
|
12
|
+
os?: string;
|
|
13
|
+
device?: string;
|
|
14
|
+
};
|
|
15
|
+
type BufferedEventBatch = {
|
|
16
|
+
siteId: Id<"sites">;
|
|
17
|
+
sessionId: string;
|
|
18
|
+
visitorId: string;
|
|
19
|
+
bucketStart: number;
|
|
20
|
+
events: TrackerEvent[];
|
|
21
|
+
};
|
|
22
|
+
export type EventBatchBuffer = Map<string, BufferedEventBatch>;
|
|
23
|
+
export type JourneyCursor = {
|
|
24
|
+
timestamp: number;
|
|
25
|
+
creationTime: number;
|
|
26
|
+
id: string;
|
|
27
|
+
};
|
|
28
|
+
export type RawJourneyEvent = Omit<Doc<"events">, "_id"> & {
|
|
29
|
+
_id: string;
|
|
30
|
+
};
|
|
31
|
+
export declare function eventBucketStart(timestamp: number): number;
|
|
32
|
+
export declare function eventBatchKey(sessionId: string, bucketStart: number): string;
|
|
33
|
+
export declare function inspectTelemetryMinute(ctx: MutationCtx, input: {
|
|
34
|
+
siteId: Id<"sites">;
|
|
35
|
+
sessionId: string;
|
|
36
|
+
bucketStart: number;
|
|
37
|
+
candidateEventIds: Set<string>;
|
|
38
|
+
}): Promise<{
|
|
39
|
+
eventIds: Set<string>;
|
|
40
|
+
persistedCount: number;
|
|
41
|
+
}>;
|
|
42
|
+
export declare function findTelemetry(ctx: MutationCtx, siteId: Id<"sites">, event: TrackerEvent): Promise<{
|
|
43
|
+
match: TelemetryMatch | null;
|
|
44
|
+
saturated: boolean;
|
|
45
|
+
}>;
|
|
46
|
+
export declare function bufferEventBatch(siteId: Id<"sites">, event: TrackerEvent, buffer: EventBatchBuffer): void;
|
|
47
|
+
export declare function insertEventBatch(ctx: MutationCtx, siteId: Id<"sites">, event: TrackerEvent): Promise<void>;
|
|
48
|
+
export declare function flushEventBatches(ctx: MutationCtx, buffer: EventBatchBuffer): Promise<void>;
|
|
49
|
+
export declare function migrateLegacyEventToBatch(ctx: MutationCtx, event: Doc<"events">): Promise<void>;
|
|
50
|
+
export declare function loadSessionJourneyEvents(ctx: QueryCtx, input: {
|
|
51
|
+
siteId: Id<"sites">;
|
|
52
|
+
sessionId: string;
|
|
53
|
+
from: number;
|
|
54
|
+
to: number;
|
|
55
|
+
cursor: JourneyCursor | null;
|
|
56
|
+
resultLimit: number;
|
|
57
|
+
}): Promise<RawJourneyEvent[]>;
|
|
58
|
+
export declare function loadVisitorJourneyEvents(ctx: QueryCtx, input: {
|
|
59
|
+
siteId: Id<"sites">;
|
|
60
|
+
visitorId: string;
|
|
61
|
+
from: number;
|
|
62
|
+
to: number;
|
|
63
|
+
resultLimit: number;
|
|
64
|
+
}): Promise<RawJourneyEvent[]>;
|
|
65
|
+
export declare function compareJourneyEvents(left: Pick<RawJourneyEvent, "timestamp" | "_creationTime" | "_id">, right: Pick<RawJourneyEvent, "timestamp" | "_creationTime" | "_id">): number;
|
|
66
|
+
export declare function hydrateEventContexts(ctx: QueryCtx, rows: RawJourneyEvent[]): Promise<{
|
|
67
|
+
_creationTime: number;
|
|
68
|
+
_id: string;
|
|
69
|
+
country?: string | undefined;
|
|
70
|
+
city?: string | undefined;
|
|
71
|
+
latitude?: number | undefined;
|
|
72
|
+
longitude?: number | undefined;
|
|
73
|
+
browser: string;
|
|
74
|
+
os: string;
|
|
75
|
+
device: string;
|
|
76
|
+
affiliateSlug?: string | undefined;
|
|
77
|
+
currency?: string | undefined;
|
|
78
|
+
eventId: string;
|
|
79
|
+
href?: string | undefined;
|
|
80
|
+
name?: string | undefined;
|
|
81
|
+
path: string;
|
|
82
|
+
properties?: Record<string, string | number | boolean | null> | undefined;
|
|
83
|
+
referrer?: string | undefined;
|
|
84
|
+
revenueCents?: number | undefined;
|
|
85
|
+
sequence: number;
|
|
86
|
+
sessionId: string;
|
|
87
|
+
siteId: import("convex/values").GenericId<"sites">;
|
|
88
|
+
target?: string | undefined;
|
|
89
|
+
timestamp: number;
|
|
90
|
+
type: "click" | "conversion" | "custom" | "heartbeat" | "outbound" | "pageview";
|
|
91
|
+
visitorId: string;
|
|
92
|
+
}[]>;
|
|
93
|
+
export declare function deleteTelemetryBefore(ctx: MutationCtx, input: {
|
|
94
|
+
siteId: Id<"sites">;
|
|
95
|
+
before: number;
|
|
96
|
+
batchSize: number;
|
|
97
|
+
}): Promise<{
|
|
98
|
+
deleted: number;
|
|
99
|
+
hasMore: boolean;
|
|
100
|
+
}>;
|
|
101
|
+
export {};
|
|
102
|
+
//# sourceMappingURL=eventStore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eventStore.d.ts","sourceRoot":"","sources":["../../src/component/eventStore.ts"],"names":[],"mappings":"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"}
|