@iann29/rastro 0.1.0-alpha.0 → 0.1.0-alpha.10
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 +579 -57
- package/agent/integration.md +661 -0
- package/agent/manifest.json +187 -0
- package/agent/manifest.schema.json +411 -0
- package/dist/client/federation.d.ts +236 -0
- package/dist/client/federation.d.ts.map +1 -0
- package/dist/client/federation.js +196 -0
- package/dist/client/federation.js.map +1 -0
- package/dist/client/index.d.ts +2467 -18
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +461 -32
- package/dist/client/index.js.map +1 -1
- package/dist/component/_generated/api.d.ts +18 -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 +302 -4
- package/dist/component/_generated/component.d.ts.map +1 -1
- package/dist/component/_generated/server.d.ts +4 -0
- package/dist/component/_generated/server.d.ts.map +1 -1
- package/dist/component/_generated/server.js.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 +12 -0
- package/dist/component/cardinality.d.ts.map +1 -0
- package/dist/component/cardinality.js +94 -0
- package/dist/component/cardinality.js.map +1 -0
- package/dist/component/constants.d.ts +34 -7
- package/dist/component/constants.d.ts.map +1 -1
- package/dist/component/constants.js +47 -7
- package/dist/component/constants.js.map +1 -1
- package/dist/component/convex.config.d.ts +6 -1
- package/dist/component/convex.config.js +9 -1
- package/dist/component/convex.config.js.map +1 -1
- package/dist/component/coverage.d.ts +19 -0
- package/dist/component/coverage.d.ts.map +1 -0
- package/dist/component/coverage.js +30 -0
- package/dist/component/coverage.js.map +1 -0
- package/dist/component/diagnostics.d.ts +9 -0
- package/dist/component/diagnostics.d.ts.map +1 -0
- package/dist/component/diagnostics.js +47 -0
- package/dist/component/diagnostics.js.map +1 -0
- package/dist/component/errors.d.ts +1 -1
- package/dist/component/errors.d.ts.map +1 -1
- package/dist/component/errors.js.map +1 -1
- package/dist/component/eventStore.d.ts +106 -0
- package/dist/component/eventStore.d.ts.map +1 -0
- package/dist/component/eventStore.js +294 -0
- package/dist/component/eventStore.js.map +1 -0
- 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 +71 -0
- package/dist/component/geo.d.ts.map +1 -0
- package/dist/component/geo.js +611 -0
- package/dist/component/geo.js.map +1 -0
- package/dist/component/goals.d.ts.map +1 -1
- package/dist/component/goals.js +25 -9
- 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 +284 -53
- 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 +1105 -243
- 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 +74 -9
- package/dist/component/live.js.map +1 -1
- package/dist/component/reports.d.ts +273 -24
- package/dist/component/reports.d.ts.map +1 -1
- package/dist/component/reports.js +1320 -150
- package/dist/component/reports.js.map +1 -1
- package/dist/component/retention.d.ts +75 -1
- package/dist/component/retention.d.ts.map +1 -1
- package/dist/component/retention.js +541 -31
- package/dist/component/retention.js.map +1 -1
- package/dist/component/sanitize.d.ts +24 -1
- package/dist/component/sanitize.d.ts.map +1 -1
- package/dist/component/sanitize.js +107 -19
- package/dist/component/sanitize.js.map +1 -1
- package/dist/component/schema.d.ts +462 -55
- package/dist/component/schema.js +195 -15
- package/dist/component/schema.js.map +1 -1
- package/dist/component/sites.d.ts.map +1 -1
- package/dist/component/sites.js +38 -25
- 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 +101 -16
- package/dist/component/validators.d.ts.map +1 -1
- package/dist/component/validators.js +19 -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 +1 -1
- package/dist/tracker/tracker.d.ts.map +1 -1
- package/dist/tracker/tracker.js +81 -33
- 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 +140 -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 +171 -0
- package/docs/benchmarks/2026-08-21-formal-certification.md +353 -0
- package/docs/benchmarks/2026-08-30-alpha6-recertification.md +206 -0
- package/docs/federation-setup.md +397 -0
- package/docs/federation.md +262 -0
- package/docs/upgrading.md +259 -0
- package/llms.txt +71 -0
- package/package.json +61 -11
- package/scripts/benchmark-ingest.mjs +601 -0
- package/scripts/generate-federation-keys.mjs +20 -0
- package/src/component/_generated/api.ts +18 -0
- package/src/component/_generated/component.ts +366 -4
- package/src/component/_generated/server.ts +4 -0
- package/src/component/affiliates.ts +20 -5
- package/src/component/cardinality.ts +117 -0
- package/src/component/constants.ts +47 -7
- package/src/component/convex.config.ts +11 -1
- package/src/component/coverage.ts +36 -0
- package/src/component/diagnostics.ts +65 -0
- package/src/component/errors.ts +2 -1
- package/src/component/eventStore.ts +489 -0
- package/src/component/funnels.ts +19 -16
- package/src/component/geo.ts +781 -0
- package/src/component/goals.ts +45 -16
- package/src/component/guards.ts +3 -1
- package/src/component/http.ts +403 -60
- package/src/component/identity.ts +74 -0
- package/src/component/ingest.ts +1652 -291
- package/src/component/live.ts +90 -9
- package/src/component/reports.ts +1929 -199
- package/src/component/retention.ts +774 -97
- package/src/component/sanitize.ts +154 -32
- package/src/component/schema.ts +219 -15
- package/src/component/sites.ts +56 -28
- package/src/component/useragent.ts +171 -0
- package/src/component/validators.ts +29 -1
- package/src/component/visitors.ts +116 -0
- package/src/component/vitals.ts +146 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type Infer } from "convex/values";
|
|
2
|
-
export declare const eventTypeValidator: import("convex/values").VUnion<"click" | "conversion" | "custom" | "heartbeat" | "outbound" | "pageview", [import("convex/values").VLiteral<"pageview", "required">, import("convex/values").VLiteral<"click", "required">, import("convex/values").VLiteral<"custom", "required">, import("convex/values").VLiteral<"conversion", "required">, import("convex/values").VLiteral<"heartbeat", "required">, import("convex/values").VLiteral<"outbound", "required">], "required", never>;
|
|
2
|
+
export declare const eventTypeValidator: import("convex/values").VUnion<"click" | "conversion" | "custom" | "heartbeat" | "leave" | "outbound" | "pageview" | "vital", [import("convex/values").VLiteral<"pageview", "required">, import("convex/values").VLiteral<"click", "required">, import("convex/values").VLiteral<"custom", "required">, import("convex/values").VLiteral<"conversion", "required">, import("convex/values").VLiteral<"heartbeat", "required">, import("convex/values").VLiteral<"leave", "required">, import("convex/values").VLiteral<"outbound", "required">, import("convex/values").VLiteral<"vital", "required">], "required", never>;
|
|
3
|
+
export declare const vitalMetricValidator: import("convex/values").VUnion<"CLS" | "FCP" | "INP" | "LCP" | "TTFB", [import("convex/values").VLiteral<"LCP", "required">, import("convex/values").VLiteral<"CLS", "required">, import("convex/values").VLiteral<"INP", "required">, import("convex/values").VLiteral<"FCP", "required">, import("convex/values").VLiteral<"TTFB", "required">], "required", never>;
|
|
3
4
|
export declare const propertyValueValidator: import("convex/values").VUnion<string | number | boolean | null, [import("convex/values").VString<string, "required">, import("convex/values").VFloat64<number, "required">, import("convex/values").VBoolean<boolean, "required">, import("convex/values").VNull<null, "required">], "required", never>;
|
|
4
5
|
export declare const eventPropertiesValidator: import("convex/values").VRecord<Record<string, string | number | boolean | null>, import("convex/values").VString<string, "required">, import("convex/values").VUnion<string | number | boolean | null, [import("convex/values").VString<string, "required">, import("convex/values").VFloat64<number, "required">, import("convex/values").VBoolean<boolean, "required">, import("convex/values").VNull<null, "required">], "required", never>, "required", string>;
|
|
5
6
|
export declare const trackerEventValidator: import("convex/values").VObject<{
|
|
@@ -16,13 +17,14 @@ export declare const trackerEventValidator: import("convex/values").VObject<{
|
|
|
16
17
|
sessionId: string;
|
|
17
18
|
target?: string | undefined;
|
|
18
19
|
timestamp: number;
|
|
19
|
-
type: "click" | "conversion" | "custom" | "heartbeat" | "outbound" | "pageview";
|
|
20
|
+
type: "click" | "conversion" | "custom" | "heartbeat" | "leave" | "outbound" | "pageview" | "vital";
|
|
21
|
+
value?: number | undefined;
|
|
20
22
|
visitorId: string;
|
|
21
23
|
}, {
|
|
22
24
|
eventId: import("convex/values").VString<string, "required">;
|
|
23
25
|
sessionId: import("convex/values").VString<string, "required">;
|
|
24
26
|
visitorId: import("convex/values").VString<string, "required">;
|
|
25
|
-
type: import("convex/values").VUnion<"click" | "conversion" | "custom" | "heartbeat" | "outbound" | "pageview", [import("convex/values").VLiteral<"pageview", "required">, import("convex/values").VLiteral<"click", "required">, import("convex/values").VLiteral<"custom", "required">, import("convex/values").VLiteral<"conversion", "required">, import("convex/values").VLiteral<"heartbeat", "required">, import("convex/values").VLiteral<"outbound", "required">], "required", never>;
|
|
27
|
+
type: import("convex/values").VUnion<"click" | "conversion" | "custom" | "heartbeat" | "leave" | "outbound" | "pageview" | "vital", [import("convex/values").VLiteral<"pageview", "required">, import("convex/values").VLiteral<"click", "required">, import("convex/values").VLiteral<"custom", "required">, import("convex/values").VLiteral<"conversion", "required">, import("convex/values").VLiteral<"heartbeat", "required">, import("convex/values").VLiteral<"leave", "required">, import("convex/values").VLiteral<"outbound", "required">, import("convex/values").VLiteral<"vital", "required">], "required", never>;
|
|
26
28
|
name: import("convex/values").VString<string | undefined, "optional">;
|
|
27
29
|
path: import("convex/values").VString<string, "required">;
|
|
28
30
|
referrer: import("convex/values").VString<string | undefined, "optional">;
|
|
@@ -34,7 +36,8 @@ export declare const trackerEventValidator: import("convex/values").VObject<{
|
|
|
34
36
|
revenueCents: import("convex/values").VFloat64<number | undefined, "optional">;
|
|
35
37
|
currency: import("convex/values").VString<string | undefined, "optional">;
|
|
36
38
|
affiliateSlug: import("convex/values").VString<string | undefined, "optional">;
|
|
37
|
-
|
|
39
|
+
value: import("convex/values").VFloat64<number | undefined, "optional">;
|
|
40
|
+
}, "required", "affiliateSlug" | "currency" | "eventId" | "href" | "name" | "path" | "properties" | "referrer" | "revenueCents" | "sequence" | "sessionId" | "target" | "timestamp" | "type" | "value" | "visitorId" | `properties.${string}`>;
|
|
38
41
|
export declare const ingestContextValidator: import("convex/values").VObject<{
|
|
39
42
|
browser?: string | undefined;
|
|
40
43
|
city?: string | undefined;
|
|
@@ -43,6 +46,7 @@ export declare const ingestContextValidator: import("convex/values").VObject<{
|
|
|
43
46
|
latitude?: number | undefined;
|
|
44
47
|
longitude?: number | undefined;
|
|
45
48
|
os?: string | undefined;
|
|
49
|
+
visitorKey?: string | undefined;
|
|
46
50
|
}, {
|
|
47
51
|
country: import("convex/values").VString<string | undefined, "optional">;
|
|
48
52
|
city: import("convex/values").VString<string | undefined, "optional">;
|
|
@@ -51,7 +55,61 @@ export declare const ingestContextValidator: import("convex/values").VObject<{
|
|
|
51
55
|
browser: import("convex/values").VString<string | undefined, "optional">;
|
|
52
56
|
os: import("convex/values").VString<string | undefined, "optional">;
|
|
53
57
|
device: import("convex/values").VString<string | undefined, "optional">;
|
|
54
|
-
|
|
58
|
+
visitorKey: import("convex/values").VString<string | undefined, "optional">;
|
|
59
|
+
}, "required", "browser" | "city" | "country" | "device" | "latitude" | "longitude" | "os" | "visitorKey">;
|
|
60
|
+
export declare const batchedEventValidator: import("convex/values").VObject<{
|
|
61
|
+
affiliateSlug?: string | undefined;
|
|
62
|
+
aggregateCountry?: string | undefined;
|
|
63
|
+
browser?: string | undefined;
|
|
64
|
+
city?: string | undefined;
|
|
65
|
+
country?: string | undefined;
|
|
66
|
+
currency?: string | undefined;
|
|
67
|
+
device?: string | undefined;
|
|
68
|
+
eventId: string;
|
|
69
|
+
href?: string | undefined;
|
|
70
|
+
latitude?: number | undefined;
|
|
71
|
+
longitude?: number | undefined;
|
|
72
|
+
name?: string | undefined;
|
|
73
|
+
os?: string | undefined;
|
|
74
|
+
path: string;
|
|
75
|
+
properties?: Record<string, string | number | boolean | null> | undefined;
|
|
76
|
+
referrer?: string | undefined;
|
|
77
|
+
revenueCents?: number | undefined;
|
|
78
|
+
sequence: number;
|
|
79
|
+
sessionId: string;
|
|
80
|
+
target?: string | undefined;
|
|
81
|
+
timestamp: number;
|
|
82
|
+
type: "click" | "conversion" | "custom" | "heartbeat" | "leave" | "outbound" | "pageview" | "vital";
|
|
83
|
+
value?: number | undefined;
|
|
84
|
+
visitorId: string;
|
|
85
|
+
visitorKey?: string | undefined;
|
|
86
|
+
}, {
|
|
87
|
+
eventId: import("convex/values").VString<string, "required">;
|
|
88
|
+
sessionId: import("convex/values").VString<string, "required">;
|
|
89
|
+
visitorId: import("convex/values").VString<string, "required">;
|
|
90
|
+
type: import("convex/values").VUnion<"click" | "conversion" | "custom" | "heartbeat" | "leave" | "outbound" | "pageview" | "vital", [import("convex/values").VLiteral<"pageview", "required">, import("convex/values").VLiteral<"click", "required">, import("convex/values").VLiteral<"custom", "required">, import("convex/values").VLiteral<"conversion", "required">, import("convex/values").VLiteral<"heartbeat", "required">, import("convex/values").VLiteral<"leave", "required">, import("convex/values").VLiteral<"outbound", "required">, import("convex/values").VLiteral<"vital", "required">], "required", never>;
|
|
91
|
+
name: import("convex/values").VString<string | undefined, "optional">;
|
|
92
|
+
path: import("convex/values").VString<string, "required">;
|
|
93
|
+
referrer: import("convex/values").VString<string | undefined, "optional">;
|
|
94
|
+
timestamp: import("convex/values").VFloat64<number, "required">;
|
|
95
|
+
sequence: import("convex/values").VFloat64<number, "required">;
|
|
96
|
+
target: import("convex/values").VString<string | undefined, "optional">;
|
|
97
|
+
href: import("convex/values").VString<string | undefined, "optional">;
|
|
98
|
+
properties: import("convex/values").VRecord<Record<string, string | number | boolean | null> | undefined, import("convex/values").VString<string, "required">, import("convex/values").VUnion<string | number | boolean | null, [import("convex/values").VString<string, "required">, import("convex/values").VFloat64<number, "required">, import("convex/values").VBoolean<boolean, "required">, import("convex/values").VNull<null, "required">], "required", never>, "optional", string>;
|
|
99
|
+
revenueCents: import("convex/values").VFloat64<number | undefined, "optional">;
|
|
100
|
+
currency: import("convex/values").VString<string | undefined, "optional">;
|
|
101
|
+
affiliateSlug: import("convex/values").VString<string | undefined, "optional">;
|
|
102
|
+
value: import("convex/values").VFloat64<number | undefined, "optional">;
|
|
103
|
+
country: import("convex/values").VString<string | undefined, "optional">;
|
|
104
|
+
city: import("convex/values").VString<string | undefined, "optional">;
|
|
105
|
+
latitude: import("convex/values").VFloat64<number | undefined, "optional">;
|
|
106
|
+
longitude: import("convex/values").VFloat64<number | undefined, "optional">;
|
|
107
|
+
browser: import("convex/values").VString<string | undefined, "optional">;
|
|
108
|
+
os: import("convex/values").VString<string | undefined, "optional">;
|
|
109
|
+
device: import("convex/values").VString<string | undefined, "optional">;
|
|
110
|
+
visitorKey: import("convex/values").VString<string | undefined, "optional">;
|
|
111
|
+
aggregateCountry: import("convex/values").VString<string | undefined, "optional">;
|
|
112
|
+
}, "required", "affiliateSlug" | "aggregateCountry" | "browser" | "city" | "country" | "currency" | "device" | "eventId" | "href" | "latitude" | "longitude" | "name" | "os" | "path" | "properties" | "referrer" | "revenueCents" | "sequence" | "sessionId" | "target" | "timestamp" | "type" | "value" | "visitorId" | "visitorKey" | `properties.${string}`>;
|
|
55
113
|
export declare const siteFieldsValidator: import("convex/values").VObject<{
|
|
56
114
|
cookieless: boolean;
|
|
57
115
|
createdAt: number;
|
|
@@ -103,10 +161,12 @@ export declare const sessionFieldsValidator: import("convex/values").VObject<{
|
|
|
103
161
|
utmMedium?: string | undefined;
|
|
104
162
|
utmSource?: string | undefined;
|
|
105
163
|
visitorId: string;
|
|
164
|
+
visitorKey?: string | undefined;
|
|
106
165
|
}, {
|
|
107
166
|
siteId: import("convex/values").VId<import("convex/values").GenericId<"sites">, "required">;
|
|
108
167
|
sessionId: import("convex/values").VString<string, "required">;
|
|
109
168
|
visitorId: import("convex/values").VString<string, "required">;
|
|
169
|
+
visitorKey: import("convex/values").VString<string | undefined, "optional">;
|
|
110
170
|
startedAt: import("convex/values").VFloat64<number, "required">;
|
|
111
171
|
lastSeenAt: import("convex/values").VFloat64<number, "required">;
|
|
112
172
|
entryPath: import("convex/values").VString<string, "required">;
|
|
@@ -133,7 +193,7 @@ export declare const sessionFieldsValidator: import("convex/values").VObject<{
|
|
|
133
193
|
affiliateId: import("convex/values").VId<import("convex/values").GenericId<"affiliates"> | undefined, "optional">;
|
|
134
194
|
affiliateAttributedAt: import("convex/values").VFloat64<number | undefined, "optional">;
|
|
135
195
|
affiliateExpiresAt: import("convex/values").VFloat64<number | undefined, "optional">;
|
|
136
|
-
}, "required", "affiliateAttributedAt" | "affiliateExpiresAt" | "affiliateId" | "affiliateSlug" | "browser" | "city" | "conversionCount" | "country" | "currency" | "device" | "durationMs" | "entryPath" | "eventCount" | "exitPath" | "lastSeenAt" | "latitude" | "longitude" | "os" | "pageviewCount" | "referrer" | "revenueCents" | "sessionId" | "siteId" | "source" | "startedAt" | "utmCampaign" | "utmMedium" | "utmSource" | "visitorId">;
|
|
196
|
+
}, "required", "affiliateAttributedAt" | "affiliateExpiresAt" | "affiliateId" | "affiliateSlug" | "browser" | "city" | "conversionCount" | "country" | "currency" | "device" | "durationMs" | "entryPath" | "eventCount" | "exitPath" | "lastSeenAt" | "latitude" | "longitude" | "os" | "pageviewCount" | "referrer" | "revenueCents" | "sessionId" | "siteId" | "source" | "startedAt" | "utmCampaign" | "utmMedium" | "utmSource" | "visitorId" | "visitorKey">;
|
|
137
197
|
export declare const eventFieldsValidator: import("convex/values").VObject<{
|
|
138
198
|
affiliateSlug?: string | undefined;
|
|
139
199
|
browser: string;
|
|
@@ -156,14 +216,14 @@ export declare const eventFieldsValidator: import("convex/values").VObject<{
|
|
|
156
216
|
siteId: import("convex/values").GenericId<"sites">;
|
|
157
217
|
target?: string | undefined;
|
|
158
218
|
timestamp: number;
|
|
159
|
-
type: "click" | "conversion" | "custom" | "heartbeat" | "outbound" | "pageview";
|
|
219
|
+
type: "click" | "conversion" | "custom" | "heartbeat" | "leave" | "outbound" | "pageview" | "vital";
|
|
160
220
|
visitorId: string;
|
|
161
221
|
}, {
|
|
162
222
|
siteId: import("convex/values").VId<import("convex/values").GenericId<"sites">, "required">;
|
|
163
223
|
eventId: import("convex/values").VString<string, "required">;
|
|
164
224
|
sessionId: import("convex/values").VString<string, "required">;
|
|
165
225
|
visitorId: import("convex/values").VString<string, "required">;
|
|
166
|
-
type: import("convex/values").VUnion<"click" | "conversion" | "custom" | "heartbeat" | "outbound" | "pageview", [import("convex/values").VLiteral<"pageview", "required">, import("convex/values").VLiteral<"click", "required">, import("convex/values").VLiteral<"custom", "required">, import("convex/values").VLiteral<"conversion", "required">, import("convex/values").VLiteral<"heartbeat", "required">, import("convex/values").VLiteral<"outbound", "required">], "required", never>;
|
|
226
|
+
type: import("convex/values").VUnion<"click" | "conversion" | "custom" | "heartbeat" | "leave" | "outbound" | "pageview" | "vital", [import("convex/values").VLiteral<"pageview", "required">, import("convex/values").VLiteral<"click", "required">, import("convex/values").VLiteral<"custom", "required">, import("convex/values").VLiteral<"conversion", "required">, import("convex/values").VLiteral<"heartbeat", "required">, import("convex/values").VLiteral<"leave", "required">, import("convex/values").VLiteral<"outbound", "required">, import("convex/values").VLiteral<"vital", "required">], "required", never>;
|
|
167
227
|
name: import("convex/values").VString<string | undefined, "optional">;
|
|
168
228
|
path: import("convex/values").VString<string, "required">;
|
|
169
229
|
referrer: import("convex/values").VString<string | undefined, "optional">;
|
|
@@ -183,20 +243,29 @@ export declare const eventFieldsValidator: import("convex/values").VObject<{
|
|
|
183
243
|
os: import("convex/values").VString<string, "required">;
|
|
184
244
|
device: import("convex/values").VString<string, "required">;
|
|
185
245
|
}, "required", "affiliateSlug" | "browser" | "city" | "country" | "currency" | "device" | "eventId" | "href" | "latitude" | "longitude" | "name" | "os" | "path" | "properties" | "referrer" | "revenueCents" | "sequence" | "sessionId" | "siteId" | "target" | "timestamp" | "type" | "visitorId" | `properties.${string}`>;
|
|
186
|
-
export declare const dimensionTypeValidator: import("convex/values").VUnion<"browser" | "country" | "device" | "event" | "goal" | "page" | "source", [import("convex/values").VLiteral<"source", "required">, import("convex/values").VLiteral<"page", "required">, import("convex/values").VLiteral<"country", "required">, import("convex/values").VLiteral<"device", "required">, import("convex/values").VLiteral<"browser", "required">, import("convex/values").VLiteral<"event", "required">, import("convex/values").VLiteral<"goal", "required">], "required", never>;
|
|
246
|
+
export declare const dimensionTypeValidator: import("convex/values").VUnion<"browser" | "campaign" | "country" | "device" | "event" | "goal" | "page" | "source", [import("convex/values").VLiteral<"source", "required">, import("convex/values").VLiteral<"campaign", "required">, import("convex/values").VLiteral<"page", "required">, import("convex/values").VLiteral<"country", "required">, import("convex/values").VLiteral<"device", "required">, import("convex/values").VLiteral<"browser", "required">, import("convex/values").VLiteral<"event", "required">, import("convex/values").VLiteral<"goal", "required">], "required", never>;
|
|
187
247
|
export declare const dimensionSlotValidator: import("convex/values").VObject<{
|
|
188
248
|
count: number;
|
|
189
249
|
revenueCents: number;
|
|
190
250
|
slot: number;
|
|
191
|
-
type: "browser" | "country" | "device" | "event" | "goal" | "page" | "source";
|
|
251
|
+
type: "browser" | "campaign" | "country" | "device" | "event" | "goal" | "page" | "source";
|
|
192
252
|
value: string;
|
|
193
253
|
}, {
|
|
194
|
-
type: import("convex/values").VUnion<"browser" | "country" | "device" | "event" | "goal" | "page" | "source", [import("convex/values").VLiteral<"source", "required">, import("convex/values").VLiteral<"page", "required">, import("convex/values").VLiteral<"country", "required">, import("convex/values").VLiteral<"device", "required">, import("convex/values").VLiteral<"browser", "required">, import("convex/values").VLiteral<"event", "required">, import("convex/values").VLiteral<"goal", "required">], "required", never>;
|
|
254
|
+
type: import("convex/values").VUnion<"browser" | "campaign" | "country" | "device" | "event" | "goal" | "page" | "source", [import("convex/values").VLiteral<"source", "required">, import("convex/values").VLiteral<"campaign", "required">, import("convex/values").VLiteral<"page", "required">, import("convex/values").VLiteral<"country", "required">, import("convex/values").VLiteral<"device", "required">, import("convex/values").VLiteral<"browser", "required">, import("convex/values").VLiteral<"event", "required">, import("convex/values").VLiteral<"goal", "required">], "required", never>;
|
|
195
255
|
slot: import("convex/values").VFloat64<number, "required">;
|
|
196
256
|
value: import("convex/values").VString<string, "required">;
|
|
197
257
|
count: import("convex/values").VFloat64<number, "required">;
|
|
198
258
|
revenueCents: import("convex/values").VFloat64<number, "required">;
|
|
199
259
|
}, "required", "count" | "revenueCents" | "slot" | "type" | "value">;
|
|
260
|
+
export declare const visitorSketchValidator: import("convex/values").VObject<{
|
|
261
|
+
precision: number;
|
|
262
|
+
registers: ArrayBuffer;
|
|
263
|
+
version: 1;
|
|
264
|
+
}, {
|
|
265
|
+
version: import("convex/values").VLiteral<1, "required">;
|
|
266
|
+
precision: import("convex/values").VFloat64<number, "required">;
|
|
267
|
+
registers: import("convex/values").VBytes<ArrayBuffer, "required">;
|
|
268
|
+
}, "required", "precision" | "registers" | "version">;
|
|
200
269
|
export declare const aggregateFieldsValidator: import("convex/values").VObject<{
|
|
201
270
|
bucketStart: number;
|
|
202
271
|
clicks: number;
|
|
@@ -206,7 +275,7 @@ export declare const aggregateFieldsValidator: import("convex/values").VObject<{
|
|
|
206
275
|
count: number;
|
|
207
276
|
revenueCents: number;
|
|
208
277
|
slot: number;
|
|
209
|
-
type: "browser" | "country" | "device" | "event" | "goal" | "page" | "source";
|
|
278
|
+
type: "browser" | "campaign" | "country" | "device" | "event" | "goal" | "page" | "source";
|
|
210
279
|
value: string;
|
|
211
280
|
}[];
|
|
212
281
|
events: number;
|
|
@@ -217,6 +286,12 @@ export declare const aggregateFieldsValidator: import("convex/values").VObject<{
|
|
|
217
286
|
sessions: number;
|
|
218
287
|
shard: number;
|
|
219
288
|
siteId: import("convex/values").GenericId<"sites">;
|
|
289
|
+
visitorSketch?: {
|
|
290
|
+
precision: number;
|
|
291
|
+
registers: ArrayBuffer;
|
|
292
|
+
version: 1;
|
|
293
|
+
} | undefined;
|
|
294
|
+
visitorSketchComplete?: boolean | undefined;
|
|
220
295
|
visitors: number;
|
|
221
296
|
}, {
|
|
222
297
|
siteId: import("convex/values").VId<import("convex/values").GenericId<"sites">, "required">;
|
|
@@ -230,28 +305,38 @@ export declare const aggregateFieldsValidator: import("convex/values").VObject<{
|
|
|
230
305
|
outboundClicks: import("convex/values").VFloat64<number, "required">;
|
|
231
306
|
sessions: import("convex/values").VFloat64<number, "required">;
|
|
232
307
|
visitors: import("convex/values").VFloat64<number, "required">;
|
|
308
|
+
visitorSketch: import("convex/values").VObject<{
|
|
309
|
+
precision: number;
|
|
310
|
+
registers: ArrayBuffer;
|
|
311
|
+
version: 1;
|
|
312
|
+
} | undefined, {
|
|
313
|
+
version: import("convex/values").VLiteral<1, "required">;
|
|
314
|
+
precision: import("convex/values").VFloat64<number, "required">;
|
|
315
|
+
registers: import("convex/values").VBytes<ArrayBuffer, "required">;
|
|
316
|
+
}, "optional", "precision" | "registers" | "version">;
|
|
317
|
+
visitorSketchComplete: import("convex/values").VBoolean<boolean | undefined, "optional">;
|
|
233
318
|
conversions: import("convex/values").VFloat64<number, "required">;
|
|
234
319
|
revenueCents: import("convex/values").VFloat64<number, "required">;
|
|
235
320
|
dimensions: import("convex/values").VArray<{
|
|
236
321
|
count: number;
|
|
237
322
|
revenueCents: number;
|
|
238
323
|
slot: number;
|
|
239
|
-
type: "browser" | "country" | "device" | "event" | "goal" | "page" | "source";
|
|
324
|
+
type: "browser" | "campaign" | "country" | "device" | "event" | "goal" | "page" | "source";
|
|
240
325
|
value: string;
|
|
241
326
|
}[], import("convex/values").VObject<{
|
|
242
327
|
count: number;
|
|
243
328
|
revenueCents: number;
|
|
244
329
|
slot: number;
|
|
245
|
-
type: "browser" | "country" | "device" | "event" | "goal" | "page" | "source";
|
|
330
|
+
type: "browser" | "campaign" | "country" | "device" | "event" | "goal" | "page" | "source";
|
|
246
331
|
value: string;
|
|
247
332
|
}, {
|
|
248
|
-
type: import("convex/values").VUnion<"browser" | "country" | "device" | "event" | "goal" | "page" | "source", [import("convex/values").VLiteral<"source", "required">, import("convex/values").VLiteral<"page", "required">, import("convex/values").VLiteral<"country", "required">, import("convex/values").VLiteral<"device", "required">, import("convex/values").VLiteral<"browser", "required">, import("convex/values").VLiteral<"event", "required">, import("convex/values").VLiteral<"goal", "required">], "required", never>;
|
|
333
|
+
type: import("convex/values").VUnion<"browser" | "campaign" | "country" | "device" | "event" | "goal" | "page" | "source", [import("convex/values").VLiteral<"source", "required">, import("convex/values").VLiteral<"campaign", "required">, import("convex/values").VLiteral<"page", "required">, import("convex/values").VLiteral<"country", "required">, import("convex/values").VLiteral<"device", "required">, import("convex/values").VLiteral<"browser", "required">, import("convex/values").VLiteral<"event", "required">, import("convex/values").VLiteral<"goal", "required">], "required", never>;
|
|
249
334
|
slot: import("convex/values").VFloat64<number, "required">;
|
|
250
335
|
value: import("convex/values").VString<string, "required">;
|
|
251
336
|
count: import("convex/values").VFloat64<number, "required">;
|
|
252
337
|
revenueCents: import("convex/values").VFloat64<number, "required">;
|
|
253
338
|
}, "required", "count" | "revenueCents" | "slot" | "type" | "value">, "required">;
|
|
254
|
-
}, "required", "bucketStart" | "clicks" | "conversions" | "customEvents" | "dimensions" | "events" | "granularity" | "outboundClicks" | "pageviews" | "revenueCents" | "sessions" | "shard" | "siteId" | "visitors">;
|
|
339
|
+
}, "required", "bucketStart" | "clicks" | "conversions" | "customEvents" | "dimensions" | "events" | "granularity" | "outboundClicks" | "pageviews" | "revenueCents" | "sessions" | "shard" | "siteId" | "visitorSketch" | "visitorSketch.precision" | "visitorSketch.registers" | "visitorSketch.version" | "visitorSketchComplete" | "visitors">;
|
|
255
340
|
export declare const goalMatchTypeValidator: import("convex/values").VUnion<"custom" | "pageview", [import("convex/values").VLiteral<"pageview", "required">, import("convex/values").VLiteral<"custom", "required">], "required", never>;
|
|
256
341
|
export declare const goalFieldsValidator: import("convex/values").VObject<{
|
|
257
342
|
active: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validators.d.ts","sourceRoot":"","sources":["../../src/component/validators.ts"],"names":[],"mappings":"AAAA,OAAO,EAAK,KAAK,KAAK,EAAE,MAAM,eAAe,CAAC;AAE9C,eAAO,MAAM,kBAAkB,
|
|
1
|
+
{"version":3,"file":"validators.d.ts","sourceRoot":"","sources":["../../src/component/validators.ts"],"names":[],"mappings":"AAAA,OAAO,EAAK,KAAK,KAAK,EAAE,MAAM,eAAe,CAAC;AAE9C,eAAO,MAAM,kBAAkB,4lBAS9B,CAAC;AAEF,eAAO,MAAM,oBAAoB,uWAMhC,CAAC;AAEF,eAAO,MAAM,sBAAsB,0SAKlC,CAAC;AAEF,eAAO,MAAM,wBAAwB,scAGpC,CAAC;AAEF,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8OAmBhC,CAAC;AAEH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;0GASjC,CAAC;AAEH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gWAGhC,CAAC;AAEH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;iIAU9B,CAAC;AAEH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kcA+BjC,CAAC;AAEH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6TAwB/B,CAAC;AAEH,eAAO,MAAM,sBAAsB,0kBASlC,CAAC;AAEF,eAAO,MAAM,sBAAsB;;;;;;;;;;;;oEAMjC,CAAC;AAEH,eAAO,MAAM,sBAAsB;;;;;;;;qDAIjC,CAAC;AAEH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kVAiBnC,CAAC;AAEH,eAAO,MAAM,sBAAsB,8LAGlC,CAAC;AAEF,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;4HAU9B,CAAC;AAEH,eAAO,MAAM,mBAAmB;;;;;;;;yCAI9B,CAAC;AAEH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iHAShC,CAAC;AAEH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;6HASnC,CAAC;AAEH,eAAO,MAAM,qBAAqB;;;;;;;;sDAIhC,CAAC;AAEH,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;yKAWrC,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAC/D,MAAM,MAAM,aAAa,GAAG,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AACjE,MAAM,MAAM,eAAe,GAAG,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AACrE,MAAM,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAC3D,MAAM,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { v } from "convex/values";
|
|
2
|
-
export const eventTypeValidator = v.union(v.literal("pageview"), v.literal("click"), v.literal("custom"), v.literal("conversion"), v.literal("heartbeat"), v.literal("outbound"));
|
|
2
|
+
export const eventTypeValidator = v.union(v.literal("pageview"), v.literal("click"), v.literal("custom"), v.literal("conversion"), v.literal("heartbeat"), v.literal("leave"), v.literal("outbound"), v.literal("vital"));
|
|
3
|
+
export const vitalMetricValidator = v.union(v.literal("LCP"), v.literal("CLS"), v.literal("INP"), v.literal("FCP"), v.literal("TTFB"));
|
|
3
4
|
export const propertyValueValidator = v.union(v.string(), v.number(), v.boolean(), v.null());
|
|
4
5
|
export const eventPropertiesValidator = v.record(v.string(), propertyValueValidator);
|
|
5
6
|
export const trackerEventValidator = v.object({
|
|
@@ -18,6 +19,9 @@ export const trackerEventValidator = v.object({
|
|
|
18
19
|
revenueCents: v.optional(v.number()),
|
|
19
20
|
currency: v.optional(v.string()),
|
|
20
21
|
affiliateSlug: v.optional(v.string()),
|
|
22
|
+
// Web Vitals measurement: milliseconds, or CLS scaled by 1000. Only "vital"
|
|
23
|
+
// events carry it; sanitization strips it from every other type.
|
|
24
|
+
value: v.optional(v.number()),
|
|
21
25
|
});
|
|
22
26
|
export const ingestContextValidator = v.object({
|
|
23
27
|
country: v.optional(v.string()),
|
|
@@ -27,6 +31,11 @@ export const ingestContextValidator = v.object({
|
|
|
27
31
|
browser: v.optional(v.string()),
|
|
28
32
|
os: v.optional(v.string()),
|
|
29
33
|
device: v.optional(v.string()),
|
|
34
|
+
visitorKey: v.optional(v.string()),
|
|
35
|
+
});
|
|
36
|
+
export const batchedEventValidator = trackerEventValidator.extend({
|
|
37
|
+
...ingestContextValidator.fields,
|
|
38
|
+
aggregateCountry: v.optional(v.string()),
|
|
30
39
|
});
|
|
31
40
|
export const siteFieldsValidator = v.object({
|
|
32
41
|
ownerId: v.string(),
|
|
@@ -43,6 +52,7 @@ export const sessionFieldsValidator = v.object({
|
|
|
43
52
|
siteId: v.id("sites"),
|
|
44
53
|
sessionId: v.string(),
|
|
45
54
|
visitorId: v.string(),
|
|
55
|
+
visitorKey: v.optional(v.string()),
|
|
46
56
|
startedAt: v.number(),
|
|
47
57
|
lastSeenAt: v.number(),
|
|
48
58
|
entryPath: v.string(),
|
|
@@ -95,7 +105,7 @@ export const eventFieldsValidator = v.object({
|
|
|
95
105
|
os: v.string(),
|
|
96
106
|
device: v.string(),
|
|
97
107
|
});
|
|
98
|
-
export const dimensionTypeValidator = v.union(v.literal("source"), v.literal("page"), v.literal("country"), v.literal("device"), v.literal("browser"), v.literal("event"), v.literal("goal"));
|
|
108
|
+
export const dimensionTypeValidator = v.union(v.literal("source"), v.literal("campaign"), v.literal("page"), v.literal("country"), v.literal("device"), v.literal("browser"), v.literal("event"), v.literal("goal"));
|
|
99
109
|
export const dimensionSlotValidator = v.object({
|
|
100
110
|
type: dimensionTypeValidator,
|
|
101
111
|
slot: v.number(),
|
|
@@ -103,6 +113,11 @@ export const dimensionSlotValidator = v.object({
|
|
|
103
113
|
count: v.number(),
|
|
104
114
|
revenueCents: v.number(),
|
|
105
115
|
});
|
|
116
|
+
export const visitorSketchValidator = v.object({
|
|
117
|
+
version: v.literal(1),
|
|
118
|
+
precision: v.number(),
|
|
119
|
+
registers: v.bytes(),
|
|
120
|
+
});
|
|
106
121
|
export const aggregateFieldsValidator = v.object({
|
|
107
122
|
siteId: v.id("sites"),
|
|
108
123
|
granularity: v.union(v.literal("hour"), v.literal("day")),
|
|
@@ -115,6 +130,8 @@ export const aggregateFieldsValidator = v.object({
|
|
|
115
130
|
outboundClicks: v.number(),
|
|
116
131
|
sessions: v.number(),
|
|
117
132
|
visitors: v.number(),
|
|
133
|
+
visitorSketch: v.optional(visitorSketchValidator),
|
|
134
|
+
visitorSketchComplete: v.optional(v.boolean()),
|
|
118
135
|
conversions: v.number(),
|
|
119
136
|
revenueCents: v.number(),
|
|
120
137
|
dimensions: v.array(dimensionSlotValidator),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validators.js","sourceRoot":"","sources":["../../src/component/validators.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAc,MAAM,eAAe,CAAC;AAE9C,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CACvC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,EACrB,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,EAClB,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,EACnB,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,EACvB,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,EACtB,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,
|
|
1
|
+
{"version":3,"file":"validators.js","sourceRoot":"","sources":["../../src/component/validators.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Id } from "./_generated/dataModel.js";
|
|
2
|
+
import { type QueryCtx } from "./_generated/server.js";
|
|
3
|
+
/**
|
|
4
|
+
* Folds an anonymous visitor id into the pseudonymous identity the host
|
|
5
|
+
* supplies after signup or sign-in. Links are one level deep: an alias can
|
|
6
|
+
* belong to one identity, an identity can never become an alias, and an
|
|
7
|
+
* alias can never own aliases, so journeys stay bounded and unambiguous.
|
|
8
|
+
*/
|
|
9
|
+
export declare const link: import("convex/server").RegisteredMutation<"public", {
|
|
10
|
+
previousVisitorId: string;
|
|
11
|
+
siteId: import("convex/values").GenericId<"sites">;
|
|
12
|
+
visitorId: string;
|
|
13
|
+
}, Promise<{
|
|
14
|
+
linked: boolean;
|
|
15
|
+
aliasCount: number;
|
|
16
|
+
}>>;
|
|
17
|
+
/** The identity a visitor id resolves to, followed by every alias it owns. */
|
|
18
|
+
export declare function resolveVisitorIdentities(ctx: QueryCtx, siteId: Id<"sites">, visitorId: string): Promise<string[]>;
|
|
19
|
+
//# sourceMappingURL=visitors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"visitors.d.ts","sourceRoot":"","sources":["../../src/component/visitors.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,2BAA2B,CAAC;AACpD,OAAO,EAAY,KAAK,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAEjE;;;;;GAKG;AACH,eAAO,MAAM,IAAI;;;;;;;GAwEf,CAAC;AAEH,8EAA8E;AAC9E,wBAAsB,wBAAwB,CAC5C,GAAG,EAAE,QAAQ,EACb,MAAM,EAAE,EAAE,CAAC,OAAO,CAAC,EACnB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,EAAE,CAAC,CAUnB"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { v } from "convex/values";
|
|
2
|
+
import { MAX_VISITOR_ALIASES } from "./constants.js";
|
|
3
|
+
import { fail } from "./errors.js";
|
|
4
|
+
import { sanitizeOpaqueId } from "./sanitize.js";
|
|
5
|
+
import { mutation } from "./_generated/server.js";
|
|
6
|
+
/**
|
|
7
|
+
* Folds an anonymous visitor id into the pseudonymous identity the host
|
|
8
|
+
* supplies after signup or sign-in. Links are one level deep: an alias can
|
|
9
|
+
* belong to one identity, an identity can never become an alias, and an
|
|
10
|
+
* alias can never own aliases, so journeys stay bounded and unambiguous.
|
|
11
|
+
*/
|
|
12
|
+
export const link = mutation({
|
|
13
|
+
args: {
|
|
14
|
+
siteId: v.id("sites"),
|
|
15
|
+
visitorId: v.string(),
|
|
16
|
+
previousVisitorId: v.string(),
|
|
17
|
+
},
|
|
18
|
+
returns: v.object({ linked: v.boolean(), aliasCount: v.number() }),
|
|
19
|
+
handler: async (ctx, args) => {
|
|
20
|
+
const site = await ctx.db.get("sites", args.siteId);
|
|
21
|
+
if (!site)
|
|
22
|
+
fail("NOT_FOUND", "site not found");
|
|
23
|
+
let visitorId;
|
|
24
|
+
let previousVisitorId;
|
|
25
|
+
try {
|
|
26
|
+
visitorId = sanitizeOpaqueId(args.visitorId, "visitorId");
|
|
27
|
+
previousVisitorId = sanitizeOpaqueId(args.previousVisitorId, "previousVisitorId");
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
fail("INVALID_ARGUMENT", error instanceof Error ? error.message : "invalid visitor id");
|
|
31
|
+
}
|
|
32
|
+
if (visitorId === previousVisitorId) {
|
|
33
|
+
fail("INVALID_ARGUMENT", "previousVisitorId must differ from visitorId");
|
|
34
|
+
}
|
|
35
|
+
if (await findAlias(ctx, args.siteId, visitorId)) {
|
|
36
|
+
fail("CONFLICT", "visitorId is already linked to another visitor");
|
|
37
|
+
}
|
|
38
|
+
const previousOwnsAliases = await ctx.db
|
|
39
|
+
.query("visitorAliases")
|
|
40
|
+
.withIndex("by_siteId_and_visitorId", (range) => range.eq("siteId", args.siteId).eq("visitorId", previousVisitorId))
|
|
41
|
+
.first();
|
|
42
|
+
if (previousOwnsAliases) {
|
|
43
|
+
fail("CONFLICT", "previousVisitorId already owns linked visitors");
|
|
44
|
+
}
|
|
45
|
+
const aliases = await ctx.db
|
|
46
|
+
.query("visitorAliases")
|
|
47
|
+
.withIndex("by_siteId_and_visitorId", (range) => range.eq("siteId", args.siteId).eq("visitorId", visitorId))
|
|
48
|
+
.take(MAX_VISITOR_ALIASES);
|
|
49
|
+
const existing = await findAlias(ctx, args.siteId, previousVisitorId);
|
|
50
|
+
if (existing) {
|
|
51
|
+
if (existing.visitorId !== visitorId) {
|
|
52
|
+
fail("CONFLICT", "previousVisitorId is already linked to a different visitor");
|
|
53
|
+
}
|
|
54
|
+
return { linked: false, aliasCount: aliases.length };
|
|
55
|
+
}
|
|
56
|
+
if (aliases.length >= MAX_VISITOR_ALIASES) {
|
|
57
|
+
fail("LIMIT_EXCEEDED", `a visitor can hold at most ${MAX_VISITOR_ALIASES} aliases`, {
|
|
58
|
+
limit: MAX_VISITOR_ALIASES,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
await ctx.db.insert("visitorAliases", {
|
|
62
|
+
siteId: args.siteId,
|
|
63
|
+
visitorId,
|
|
64
|
+
previousVisitorId,
|
|
65
|
+
linkedAt: Date.now(),
|
|
66
|
+
});
|
|
67
|
+
return { linked: true, aliasCount: aliases.length + 1 };
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
/** The identity a visitor id resolves to, followed by every alias it owns. */
|
|
71
|
+
export async function resolveVisitorIdentities(ctx, siteId, visitorId) {
|
|
72
|
+
const alias = await findAlias(ctx, siteId, visitorId);
|
|
73
|
+
const identity = alias?.visitorId ?? visitorId;
|
|
74
|
+
const aliases = await ctx.db
|
|
75
|
+
.query("visitorAliases")
|
|
76
|
+
.withIndex("by_siteId_and_visitorId", (range) => range.eq("siteId", siteId).eq("visitorId", identity))
|
|
77
|
+
.take(MAX_VISITOR_ALIASES);
|
|
78
|
+
return [identity, ...aliases.map((row) => row.previousVisitorId)];
|
|
79
|
+
}
|
|
80
|
+
function findAlias(ctx, siteId, previousVisitorId) {
|
|
81
|
+
return ctx.db
|
|
82
|
+
.query("visitorAliases")
|
|
83
|
+
.withIndex("by_siteId_and_previousVisitorId", (range) => range.eq("siteId", siteId).eq("previousVisitorId", previousVisitorId))
|
|
84
|
+
.unique();
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=visitors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"visitors.js","sourceRoot":"","sources":["../../src/component/visitors.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Field-measured Web Vitals. Values are integers: milliseconds for the time
|
|
3
|
+
* metrics, and CLS scaled by 1000 so one shared histogram covers every metric.
|
|
4
|
+
*/
|
|
5
|
+
export declare const VITAL_METRICS: readonly ["LCP", "CLS", "INP", "FCP", "TTFB"];
|
|
6
|
+
export type VitalMetric = (typeof VITAL_METRICS)[number];
|
|
7
|
+
/**
|
|
8
|
+
* The Google-published rating thresholds. Every threshold is also a histogram
|
|
9
|
+
* edge, so good/needs-improvement/poor counts are exact, never interpolated.
|
|
10
|
+
*/
|
|
11
|
+
export declare const VITAL_THRESHOLDS: Record<VitalMetric, {
|
|
12
|
+
good: number;
|
|
13
|
+
poor: number;
|
|
14
|
+
}>;
|
|
15
|
+
/** Sentinel row keys; sanitized paths always start with "/" so neither collides. */
|
|
16
|
+
export declare const VITAL_ALL = "(all)";
|
|
17
|
+
export declare const VITAL_OTHER_PAGES = "(other)";
|
|
18
|
+
/** Bounded device classes; anything else folds into "unknown". */
|
|
19
|
+
export declare const VITAL_DEVICES: readonly ["desktop", "mobile", "tablet"];
|
|
20
|
+
export declare function vitalDevice(device: string | undefined): string;
|
|
21
|
+
export declare const VITAL_HISTOGRAM_BUCKETS: number;
|
|
22
|
+
export declare function isVitalMetric(value: string): value is VitalMetric;
|
|
23
|
+
export declare function isValidVitalValue(value: number): boolean;
|
|
24
|
+
export declare function emptyVitalHistogram(): number[];
|
|
25
|
+
/** Bucket i holds values in (edge[i-1], edge[i]]; the last bucket is open. */
|
|
26
|
+
export declare function vitalHistogramBucket(value: number): number;
|
|
27
|
+
export declare function addToVitalHistogram(histogram: number[], value: number): number[];
|
|
28
|
+
export declare function mergeVitalHistograms(left: number[], right: number[]): number[];
|
|
29
|
+
/**
|
|
30
|
+
* Percentile estimated by linear interpolation inside the winning bucket. The
|
|
31
|
+
* top bucket is open-ended, so estimates saturate at the highest edge; a
|
|
32
|
+
* reported p75 equal to that edge means "at least this much".
|
|
33
|
+
*/
|
|
34
|
+
export declare function vitalHistogramPercentile(histogram: number[], fraction: number): number;
|
|
35
|
+
/** Exact rating counts; every threshold is a bucket edge by construction. */
|
|
36
|
+
export declare function vitalRatingCounts(histogram: number[], metric: VitalMetric): {
|
|
37
|
+
good: number;
|
|
38
|
+
needsImprovement: number;
|
|
39
|
+
poor: number;
|
|
40
|
+
};
|
|
41
|
+
//# sourceMappingURL=vitals.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vitals.d.ts","sourceRoot":"","sources":["../../src/component/vitals.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,eAAO,MAAM,aAAa,YAAI,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAU,CAAC;AAE3E,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC;AAEzD;;;GAGG;AACH,eAAO,MAAM,gBAAgB,EAAE,MAAM,CACnC,WAAW,EACX;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAO/B,CAAC;AAEF,oFAAoF;AACpF,eAAO,MAAM,SAAS,UAAU,CAAC;AACjC,eAAO,MAAM,iBAAiB,YAAY,CAAC;AAE3C,kEAAkE;AAClE,eAAO,MAAM,aAAa,YAAI,SAAS,EAAE,QAAQ,EAAE,QAAQ,CAAU,CAAC;AAEtE,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAI9D;AAED,eAAO,MAAM,uBAAuB,QAAmC,CAAC;AAExE,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,WAAW,CAEjE;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAExD;AAED,wBAAgB,mBAAmB,IAAI,MAAM,EAAE,CAE9C;AAED,8EAA8E;AAC9E,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAK1D;AAED,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,MAAM,EAAE,EACnB,KAAK,EAAE,MAAM,GACZ,MAAM,EAAE,CAIV;AAED,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,EAAE,EACd,KAAK,EAAE,MAAM,EAAE,GACd,MAAM,EAAE,CAOV;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,MAAM,EAAE,EACnB,QAAQ,EAAE,MAAM,GACf,MAAM,CAqBR;AAED,6EAA6E;AAC7E,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,MAAM,EAAE,EACnB,MAAM,EAAE,WAAW,GAClB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,gBAAgB,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAgB1D"}
|