@iann29/rastro 0.4.0 → 0.5.0
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 +122 -17
- package/agent/integration.md +26 -10
- package/agent/manifest.json +10 -5
- package/agent/manifest.schema.json +14 -5
- package/dist/client/federation.d.ts +28 -8
- package/dist/client/federation.d.ts.map +1 -1
- package/dist/client/federation.js +12 -1
- package/dist/client/federation.js.map +1 -1
- package/dist/client/index.d.ts +262 -9
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +119 -2
- package/dist/client/index.js.map +1 -1
- package/dist/component/_generated/api.d.ts +6 -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 +71 -1
- package/dist/component/_generated/component.d.ts.map +1 -1
- package/dist/component/constants.d.ts +2 -0
- package/dist/component/constants.d.ts.map +1 -1
- package/dist/component/constants.js +7 -0
- package/dist/component/constants.js.map +1 -1
- package/dist/component/coverage.d.ts +1 -0
- package/dist/component/coverage.d.ts.map +1 -1
- package/dist/component/coverage.js +6 -1
- package/dist/component/coverage.js.map +1 -1
- package/dist/component/eventStore.d.ts +2 -0
- package/dist/component/eventStore.d.ts.map +1 -1
- package/dist/component/http.d.ts.map +1 -1
- package/dist/component/http.js +51 -1
- package/dist/component/http.js.map +1 -1
- package/dist/component/ingest.d.ts +2 -0
- package/dist/component/ingest.d.ts.map +1 -1
- package/dist/component/ingest.js +42 -3
- package/dist/component/ingest.js.map +1 -1
- package/dist/component/origin.d.ts +70 -0
- package/dist/component/origin.d.ts.map +1 -0
- package/dist/component/origin.js +230 -0
- package/dist/component/origin.js.map +1 -0
- package/dist/component/platforms.d.ts +33 -0
- package/dist/component/platforms.d.ts.map +1 -0
- package/dist/component/platforms.js +328 -0
- package/dist/component/platforms.js.map +1 -0
- package/dist/component/reports.d.ts +27 -72
- package/dist/component/reports.d.ts.map +1 -1
- package/dist/component/reports.js +51 -10
- package/dist/component/reports.js.map +1 -1
- package/dist/component/sanitize.d.ts +5 -0
- package/dist/component/sanitize.d.ts.map +1 -1
- package/dist/component/sanitize.js +33 -1
- package/dist/component/sanitize.js.map +1 -1
- package/dist/component/schema.d.ts +62 -7
- package/dist/component/schema.js +16 -1
- package/dist/component/schema.js.map +1 -1
- package/dist/component/trackedLinks.d.ts +91 -0
- package/dist/component/trackedLinks.d.ts.map +1 -0
- package/dist/component/trackedLinks.js +314 -0
- package/dist/component/trackedLinks.js.map +1 -0
- package/dist/component/useragent.d.ts +6 -0
- package/dist/component/useragent.d.ts.map +1 -1
- package/dist/component/useragent.js +9 -0
- package/dist/component/useragent.js.map +1 -1
- package/dist/component/validators.d.ts +51 -11
- package/dist/component/validators.d.ts.map +1 -1
- package/dist/component/validators.js +35 -1
- package/dist/component/validators.js.map +1 -1
- package/dist/tracker/generated.d.ts +6 -6
- package/dist/tracker/generated.d.ts.map +1 -1
- package/dist/tracker/generated.js +6 -6
- package/dist/tracker/generated.js.map +1 -1
- package/dist/tracker/tracker.d.ts +1 -0
- package/dist/tracker/tracker.d.ts.map +1 -1
- package/dist/tracker/tracker.js +16 -4
- package/dist/tracker/tracker.js.map +1 -1
- package/dist/tracker.min.js +1 -1
- package/docs/upgrading.md +152 -19
- package/llms.txt +6 -1
- package/package.json +2 -2
- package/src/component/_generated/api.ts +6 -0
- package/src/component/_generated/component.ts +152 -1
- package/src/component/constants.ts +7 -0
- package/src/component/coverage.ts +7 -1
- package/src/component/http.ts +56 -1
- package/src/component/ingest.ts +54 -1
- package/src/component/origin.ts +273 -0
- package/src/component/platforms.ts +359 -0
- package/src/component/reports.ts +74 -10
- package/src/component/sanitize.ts +39 -1
- package/src/component/schema.ts +18 -0
- package/src/component/trackedLinks.ts +384 -0
- package/src/component/useragent.ts +11 -0
- package/src/component/validators.ts +71 -0
- package/src/tracker/generated.ts +6 -6
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The closed table origin.ts classifies against. Bump the version whenever a
|
|
3
|
+
* row changes, and add a corpus case (origin.test.ts) for the change.
|
|
4
|
+
*/
|
|
5
|
+
export const PLATFORM_TABLE_VERSION = 1;
|
|
6
|
+
// Ordered for `inAppPlatform`: the first row whose marker matches wins, so
|
|
7
|
+
// Messenger (its iOS agent carries `FBAN/`) precedes Facebook and Threads
|
|
8
|
+
// precedes Instagram. Sources per row: "spec" is the approved proposal's
|
|
9
|
+
// table; the rest is each platform's own domains, link shims, and Play Store
|
|
10
|
+
// package ids, and in-app agents as the apps send them.
|
|
11
|
+
export const PLATFORMS = [
|
|
12
|
+
// Social.
|
|
13
|
+
{
|
|
14
|
+
// Threads: spec (threads.net → threads.com); agent is the app's codename.
|
|
15
|
+
id: "threads",
|
|
16
|
+
channel: "organic_social",
|
|
17
|
+
domains: ["threads.net", "threads.com"],
|
|
18
|
+
packages: ["com.instagram.barcelona"],
|
|
19
|
+
agent: /Barcelona/,
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
// spec.
|
|
23
|
+
id: "instagram",
|
|
24
|
+
channel: "organic_social",
|
|
25
|
+
domains: ["instagram.com"],
|
|
26
|
+
packages: ["com.instagram.android"],
|
|
27
|
+
agent: /Instagram/,
|
|
28
|
+
aliases: ["ig", "insta"],
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
// spec; + com.facebook.mlite (Messenger Lite), "msg" is Meta's
|
|
32
|
+
// {{site_source_name}} value for Messenger placements.
|
|
33
|
+
id: "messenger",
|
|
34
|
+
channel: "messaging",
|
|
35
|
+
domains: ["messenger.com", "m.me"],
|
|
36
|
+
packages: ["com.facebook.orca", "com.facebook.mlite"],
|
|
37
|
+
agent: /Orca-Android|MessengerLite|MessengerForiOS/,
|
|
38
|
+
aliases: ["msg"],
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
// spec; + fb.watch (video short links).
|
|
42
|
+
id: "facebook",
|
|
43
|
+
channel: "organic_social",
|
|
44
|
+
domains: ["facebook.com", "fb.com", "fb.me", "fb.watch"],
|
|
45
|
+
packages: ["com.facebook.katana", "com.facebook.lite"],
|
|
46
|
+
agent: /FBAN\/|FBAV\/|FB_IAB/,
|
|
47
|
+
aliases: ["fb", "face"],
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
// spec: only an `fbclid` with nothing that tells Facebook from Instagram.
|
|
51
|
+
id: "meta",
|
|
52
|
+
channel: "organic_social",
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
// spec; + TikTok Lite (com.zhiliaoapp.musically.go).
|
|
56
|
+
id: "tiktok",
|
|
57
|
+
channel: "organic_social",
|
|
58
|
+
domains: ["tiktok.com"],
|
|
59
|
+
packages: [
|
|
60
|
+
"com.zhiliaoapp.musically",
|
|
61
|
+
"com.ss.android.ugc.trill",
|
|
62
|
+
"com.zhiliaoapp.musically.go",
|
|
63
|
+
],
|
|
64
|
+
agent: /BytedanceWebview|musical_ly|TikTok/,
|
|
65
|
+
aliases: ["tt"],
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
// spec.
|
|
69
|
+
id: "kwai",
|
|
70
|
+
channel: "organic_social",
|
|
71
|
+
domains: ["kwai.com", "kwai-video.com", "kw.ai"],
|
|
72
|
+
packages: ["com.kwai.video"],
|
|
73
|
+
agent: /Kwai/,
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
// spec.
|
|
77
|
+
id: "youtube",
|
|
78
|
+
channel: "organic_social",
|
|
79
|
+
domains: ["youtube.com", "youtu.be"],
|
|
80
|
+
packages: ["com.google.android.youtube"],
|
|
81
|
+
aliases: ["yt"],
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
// spec; + TwitterAndroid (the Android app's agent).
|
|
85
|
+
id: "x",
|
|
86
|
+
channel: "organic_social",
|
|
87
|
+
domains: ["x.com", "twitter.com", "t.co"],
|
|
88
|
+
packages: ["com.twitter.android"],
|
|
89
|
+
agent: /Twitter for |TwitterAndroid/,
|
|
90
|
+
aliases: ["twitter"],
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
// spec.
|
|
94
|
+
id: "linkedin",
|
|
95
|
+
channel: "organic_social",
|
|
96
|
+
domains: ["linkedin.com", "lnkd.in"],
|
|
97
|
+
packages: ["com.linkedin.android"],
|
|
98
|
+
agent: /LinkedInApp/,
|
|
99
|
+
aliases: ["li"],
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
id: "pinterest",
|
|
103
|
+
channel: "organic_social",
|
|
104
|
+
domains: ["pinterest.com", "pin.it"],
|
|
105
|
+
packages: ["com.pinterest"],
|
|
106
|
+
agent: /Pinterest\//,
|
|
107
|
+
aliases: ["pin"],
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
id: "reddit",
|
|
111
|
+
channel: "organic_social",
|
|
112
|
+
domains: ["reddit.com", "redd.it"],
|
|
113
|
+
packages: ["com.reddit.frontpage"],
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
id: "snapchat",
|
|
117
|
+
channel: "organic_social",
|
|
118
|
+
domains: ["snapchat.com"],
|
|
119
|
+
packages: ["com.snapchat.android"],
|
|
120
|
+
agent: /Snapchat/,
|
|
121
|
+
aliases: ["snap"],
|
|
122
|
+
},
|
|
123
|
+
// Messaging.
|
|
124
|
+
{
|
|
125
|
+
// spec; + wl.co (WhatsApp's link shim, l.wl.co).
|
|
126
|
+
id: "whatsapp",
|
|
127
|
+
channel: "messaging",
|
|
128
|
+
domains: ["whatsapp.com", "wa.me", "wl.co"],
|
|
129
|
+
packages: ["com.whatsapp", "com.whatsapp.w4b"],
|
|
130
|
+
aliases: ["wa", "zap", "whats"],
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
// spec; + Telegram X (org.thunderdog.challegram).
|
|
134
|
+
id: "telegram",
|
|
135
|
+
channel: "messaging",
|
|
136
|
+
domains: ["t.me", "telegram.me", "telegram.org"],
|
|
137
|
+
packages: ["org.telegram.messenger", "org.thunderdog.challegram"],
|
|
138
|
+
aliases: ["tg"],
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
id: "discord",
|
|
142
|
+
channel: "messaging",
|
|
143
|
+
domains: ["discord.com", "discordapp.com", "discord.gg"],
|
|
144
|
+
packages: ["com.discord"],
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
// The Android package is `com.Slack`; referrer hosts arrive lowercase.
|
|
148
|
+
id: "slack",
|
|
149
|
+
channel: "messaging",
|
|
150
|
+
domains: ["slack.com"],
|
|
151
|
+
packages: ["com.slack"],
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
id: "line",
|
|
155
|
+
channel: "messaging",
|
|
156
|
+
domains: ["line.me"],
|
|
157
|
+
packages: ["jp.naver.line.android"],
|
|
158
|
+
agent: / Line\//,
|
|
159
|
+
},
|
|
160
|
+
// Search. Google's country domains match one pattern, not a suffix, so
|
|
161
|
+
// mail, docs, drive and every other google.com role host stay out of it.
|
|
162
|
+
{
|
|
163
|
+
// spec: google.<tld>, googleadservices.com, the Google app and GSA/.
|
|
164
|
+
id: "google",
|
|
165
|
+
channel: "organic_search",
|
|
166
|
+
hostPattern: /^(?:www\.)?google\.[a-z.]{2,7}$/,
|
|
167
|
+
domains: ["news.google.com"],
|
|
168
|
+
paidDomains: ["googleadservices.com"],
|
|
169
|
+
packages: ["com.google.android.googlequicksearchbox"],
|
|
170
|
+
agent: /GSA\//,
|
|
171
|
+
paidAliases: ["gads", "adwords", "google-ads", "google_ads", "googleads"],
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
id: "bing",
|
|
175
|
+
channel: "organic_search",
|
|
176
|
+
domains: ["bing.com"],
|
|
177
|
+
packages: ["com.microsoft.bing"],
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
id: "duckduckgo",
|
|
181
|
+
channel: "organic_search",
|
|
182
|
+
domains: ["duckduckgo.com"],
|
|
183
|
+
packages: ["com.duckduckgo.mobile.android"],
|
|
184
|
+
aliases: ["ddg"],
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
// Search hosts only: yahoo.com itself is a portal, mail is yahoo_mail.
|
|
188
|
+
id: "yahoo",
|
|
189
|
+
channel: "organic_search",
|
|
190
|
+
domains: ["search.yahoo.com", "search.yahoo.co.jp"],
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
id: "ecosia",
|
|
194
|
+
channel: "organic_search",
|
|
195
|
+
domains: ["ecosia.org"],
|
|
196
|
+
packages: ["com.ecosia.android"],
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
id: "yandex",
|
|
200
|
+
channel: "organic_search",
|
|
201
|
+
domains: ["yandex.ru", "yandex.com", "ya.ru"],
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
id: "baidu",
|
|
205
|
+
channel: "organic_search",
|
|
206
|
+
domains: ["baidu.com"],
|
|
207
|
+
},
|
|
208
|
+
// E-mail.
|
|
209
|
+
{
|
|
210
|
+
// spec.
|
|
211
|
+
id: "gmail",
|
|
212
|
+
channel: "email",
|
|
213
|
+
domains: ["mail.google.com"],
|
|
214
|
+
packages: ["com.google.android.gm"],
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
id: "outlook",
|
|
218
|
+
channel: "email",
|
|
219
|
+
domains: [
|
|
220
|
+
"outlook.com",
|
|
221
|
+
"outlook.live.com",
|
|
222
|
+
"outlook.office.com",
|
|
223
|
+
"outlook.office365.com",
|
|
224
|
+
],
|
|
225
|
+
packages: ["com.microsoft.office.outlook"],
|
|
226
|
+
aliases: ["hotmail"],
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
id: "yahoo_mail",
|
|
230
|
+
channel: "email",
|
|
231
|
+
domains: ["mail.yahoo.com"],
|
|
232
|
+
packages: ["com.yahoo.mobile.client.android.mail"],
|
|
233
|
+
aliases: ["yahoomail"],
|
|
234
|
+
},
|
|
235
|
+
// AI assistants.
|
|
236
|
+
{
|
|
237
|
+
// spec. ChatGPT tags the links it cites with utm_source=chatgpt.com,
|
|
238
|
+
// which the host fallback in origin.ts resolves.
|
|
239
|
+
id: "chatgpt",
|
|
240
|
+
channel: "ai",
|
|
241
|
+
domains: ["chatgpt.com", "chat.openai.com"],
|
|
242
|
+
packages: ["com.openai.chatgpt"],
|
|
243
|
+
aliases: ["openai"],
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
id: "perplexity",
|
|
247
|
+
channel: "ai",
|
|
248
|
+
domains: ["perplexity.ai"],
|
|
249
|
+
packages: ["ai.perplexity.app.android"],
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
// spec: gemini.google.com; bard is the product's former name.
|
|
253
|
+
id: "gemini",
|
|
254
|
+
channel: "ai",
|
|
255
|
+
domains: ["gemini.google.com", "bard.google.com"],
|
|
256
|
+
packages: ["com.google.android.apps.bard"],
|
|
257
|
+
aliases: ["bard"],
|
|
258
|
+
},
|
|
259
|
+
{
|
|
260
|
+
id: "copilot",
|
|
261
|
+
channel: "ai",
|
|
262
|
+
domains: ["copilot.microsoft.com"],
|
|
263
|
+
packages: ["com.microsoft.copilot"],
|
|
264
|
+
},
|
|
265
|
+
{
|
|
266
|
+
id: "claude",
|
|
267
|
+
channel: "ai",
|
|
268
|
+
domains: ["claude.ai"],
|
|
269
|
+
packages: ["com.anthropic.claude"],
|
|
270
|
+
aliases: ["anthropic"],
|
|
271
|
+
},
|
|
272
|
+
// Display ad servers and a known referral: github.io pages belong to their
|
|
273
|
+
// authors, so only github.com itself is GitHub.
|
|
274
|
+
{
|
|
275
|
+
id: "doubleclick",
|
|
276
|
+
channel: "display",
|
|
277
|
+
domains: ["doubleclick.net"],
|
|
278
|
+
},
|
|
279
|
+
{
|
|
280
|
+
id: "taboola",
|
|
281
|
+
channel: "display",
|
|
282
|
+
domains: ["taboola.com"],
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
id: "outbrain",
|
|
286
|
+
channel: "display",
|
|
287
|
+
domains: ["outbrain.com"],
|
|
288
|
+
},
|
|
289
|
+
{
|
|
290
|
+
id: "github",
|
|
291
|
+
channel: "referral",
|
|
292
|
+
domains: ["github.com"],
|
|
293
|
+
packages: ["com.github.android"],
|
|
294
|
+
},
|
|
295
|
+
// A QR code is a tracked link printed off the web: the scan carries no
|
|
296
|
+
// referrer and no app, so the link's own declaration is the only evidence.
|
|
297
|
+
{
|
|
298
|
+
id: "qr",
|
|
299
|
+
channel: "offline",
|
|
300
|
+
aliases: ["qrcode", "qr_code", "qr-code"],
|
|
301
|
+
},
|
|
302
|
+
];
|
|
303
|
+
/**
|
|
304
|
+
* Click-ID keys the tracker may report by name, in priority order: the ad
|
|
305
|
+
* networks' own ids first, then the organic share ids, `fbclid` last because
|
|
306
|
+
* Meta adds it to organic clicks too. `unknown` platforms take the referrer's.
|
|
307
|
+
*/
|
|
308
|
+
export const CLICK_IDS = [
|
|
309
|
+
["gclid", "google", "paid_search"],
|
|
310
|
+
["gbraid", "google", "paid_search"],
|
|
311
|
+
["wbraid", "google", "paid_search"],
|
|
312
|
+
["msclkid", "bing", "paid_search"],
|
|
313
|
+
["ttclid", "tiktok", "paid_social"],
|
|
314
|
+
["twclid", "x", "paid_social"],
|
|
315
|
+
["li_fat_id", "linkedin", "paid_social"],
|
|
316
|
+
["ScCid", "snapchat", "paid_social"],
|
|
317
|
+
["rdt_cid", "reddit", "paid_social"],
|
|
318
|
+
["dclid", "doubleclick", "display"],
|
|
319
|
+
["epik", "pinterest", "organic_social"],
|
|
320
|
+
["srsltid", "google", "organic_search"],
|
|
321
|
+
["mc_cid", "unknown", "email"],
|
|
322
|
+
["mc_eid", "unknown", "email"],
|
|
323
|
+
["_hsenc", "unknown", "email"],
|
|
324
|
+
["igsh", "instagram", "organic_social"],
|
|
325
|
+
["igshid", "instagram", "organic_social"],
|
|
326
|
+
["fbclid", "meta", "organic_social"],
|
|
327
|
+
];
|
|
328
|
+
//# sourceMappingURL=platforms.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"platforms.js","sourceRoot":"","sources":["../../src/component/platforms.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Id } from "./_generated/dataModel.js";
|
|
1
|
+
import type { Doc, Id } from "./_generated/dataModel.js";
|
|
2
2
|
export declare const overview: import("convex/server").RegisteredQuery<"public", {
|
|
3
3
|
from: number;
|
|
4
4
|
interval?: "day" | "hour" | undefined;
|
|
@@ -75,6 +75,21 @@ export declare const overview: import("convex/server").RegisteredQuery<"public",
|
|
|
75
75
|
count: number;
|
|
76
76
|
revenueCents: number;
|
|
77
77
|
}[];
|
|
78
|
+
topPlatforms: {
|
|
79
|
+
value: string;
|
|
80
|
+
count: number;
|
|
81
|
+
revenueCents: number;
|
|
82
|
+
}[];
|
|
83
|
+
topChannels: {
|
|
84
|
+
value: string;
|
|
85
|
+
count: number;
|
|
86
|
+
revenueCents: number;
|
|
87
|
+
}[];
|
|
88
|
+
topEvidence: {
|
|
89
|
+
value: string;
|
|
90
|
+
count: number;
|
|
91
|
+
revenueCents: number;
|
|
92
|
+
}[];
|
|
78
93
|
metadata: {
|
|
79
94
|
visitors: {
|
|
80
95
|
basis: "bucketOccurrences" | "estimatedUnique";
|
|
@@ -94,6 +109,9 @@ export declare const overview: import("convex/server").RegisteredQuery<"public",
|
|
|
94
109
|
topGoals: "goalCompletionVolume";
|
|
95
110
|
topMediums: "eventVolume" | "sessions";
|
|
96
111
|
topOutbound: "eventVolume";
|
|
112
|
+
topPlatforms: "eventVolume" | "sessions";
|
|
113
|
+
topChannels: "eventVolume" | "sessions";
|
|
114
|
+
topEvidence: "eventVolume" | "sessions";
|
|
97
115
|
};
|
|
98
116
|
dimensionsSince: number | null;
|
|
99
117
|
engagement: "counted" | "unavailable";
|
|
@@ -227,45 +245,12 @@ export declare const siteMap: import("convex/server").RegisteredQuery<"public",
|
|
|
227
245
|
};
|
|
228
246
|
};
|
|
229
247
|
}>>;
|
|
248
|
+
type SessionRow = Omit<Doc<"sessions">, "geoLookupAttemptedAt" | "lastPageviewAt">;
|
|
230
249
|
/** Metadata for a selected session, independent of list pagination. */
|
|
231
250
|
export declare const getSession: import("convex/server").RegisteredQuery<"public", {
|
|
232
251
|
sessionId: string;
|
|
233
252
|
siteId: import("convex/values").GenericId<"sites">;
|
|
234
|
-
}, Promise<
|
|
235
|
-
_creationTime: number;
|
|
236
|
-
_id: import("convex/values").GenericId<"sessions">;
|
|
237
|
-
affiliateAttributedAt?: number | undefined;
|
|
238
|
-
affiliateExpiresAt?: number | undefined;
|
|
239
|
-
affiliateId?: import("convex/values").GenericId<"affiliates"> | undefined;
|
|
240
|
-
affiliateSlug?: string | undefined;
|
|
241
|
-
browser: string;
|
|
242
|
-
city?: string | undefined;
|
|
243
|
-
conversionCount: number;
|
|
244
|
-
country?: string | undefined;
|
|
245
|
-
currency?: string | undefined;
|
|
246
|
-
device: string;
|
|
247
|
-
durationMs: number;
|
|
248
|
-
entryPath: string;
|
|
249
|
-
eventCount: number;
|
|
250
|
-
exitPath: string;
|
|
251
|
-
lastSeenAt: number;
|
|
252
|
-
latitude?: number | undefined;
|
|
253
|
-
longitude?: number | undefined;
|
|
254
|
-
newVisitor?: boolean | undefined;
|
|
255
|
-
os: string;
|
|
256
|
-
pageviewCount: number;
|
|
257
|
-
referrer?: string | undefined;
|
|
258
|
-
revenueCents: number;
|
|
259
|
-
sessionId: string;
|
|
260
|
-
siteId: import("convex/values").GenericId<"sites">;
|
|
261
|
-
source: string;
|
|
262
|
-
startedAt: number;
|
|
263
|
-
utmCampaign?: string | undefined;
|
|
264
|
-
utmMedium?: string | undefined;
|
|
265
|
-
utmSource?: string | undefined;
|
|
266
|
-
visitorId: string;
|
|
267
|
-
visitorKey?: string | undefined;
|
|
268
|
-
} | null>>;
|
|
253
|
+
}, Promise<SessionRow | null>>;
|
|
269
254
|
/** Exact commissions alongside overview's period revenue/conversion totals. */
|
|
270
255
|
export declare const revenueSummary: import("convex/server").RegisteredQuery<"public", {
|
|
271
256
|
from: number;
|
|
@@ -287,41 +272,7 @@ export declare const listSessions: import("convex/server").RegisteredQuery<"publ
|
|
|
287
272
|
siteId: import("convex/values").GenericId<"sites">;
|
|
288
273
|
to: number;
|
|
289
274
|
}, Promise<{
|
|
290
|
-
page:
|
|
291
|
-
_creationTime: number;
|
|
292
|
-
_id: import("convex/values").GenericId<"sessions">;
|
|
293
|
-
affiliateAttributedAt?: number | undefined;
|
|
294
|
-
affiliateExpiresAt?: number | undefined;
|
|
295
|
-
affiliateId?: import("convex/values").GenericId<"affiliates"> | undefined;
|
|
296
|
-
affiliateSlug?: string | undefined;
|
|
297
|
-
browser: string;
|
|
298
|
-
city?: string | undefined;
|
|
299
|
-
conversionCount: number;
|
|
300
|
-
country?: string | undefined;
|
|
301
|
-
currency?: string | undefined;
|
|
302
|
-
device: string;
|
|
303
|
-
durationMs: number;
|
|
304
|
-
entryPath: string;
|
|
305
|
-
eventCount: number;
|
|
306
|
-
exitPath: string;
|
|
307
|
-
lastSeenAt: number;
|
|
308
|
-
latitude?: number | undefined;
|
|
309
|
-
longitude?: number | undefined;
|
|
310
|
-
newVisitor?: boolean | undefined;
|
|
311
|
-
os: string;
|
|
312
|
-
pageviewCount: number;
|
|
313
|
-
referrer?: string | undefined;
|
|
314
|
-
revenueCents: number;
|
|
315
|
-
sessionId: string;
|
|
316
|
-
siteId: import("convex/values").GenericId<"sites">;
|
|
317
|
-
source: string;
|
|
318
|
-
startedAt: number;
|
|
319
|
-
utmCampaign?: string | undefined;
|
|
320
|
-
utmMedium?: string | undefined;
|
|
321
|
-
utmSource?: string | undefined;
|
|
322
|
-
visitorId: string;
|
|
323
|
-
visitorKey?: string | undefined;
|
|
324
|
-
}[];
|
|
275
|
+
page: SessionRow[];
|
|
325
276
|
isDone: boolean;
|
|
326
277
|
continueCursor: string;
|
|
327
278
|
}>>;
|
|
@@ -353,9 +304,11 @@ export declare const sessionJourney: import("convex/server").RegisteredQuery<"pu
|
|
|
353
304
|
os: string;
|
|
354
305
|
device: string;
|
|
355
306
|
affiliateSlug?: string | undefined;
|
|
307
|
+
clid?: string[] | undefined;
|
|
356
308
|
currency?: string | undefined;
|
|
357
309
|
eventId: string;
|
|
358
310
|
href?: string | undefined;
|
|
311
|
+
inApp?: string | undefined;
|
|
359
312
|
name?: string | undefined;
|
|
360
313
|
path: string;
|
|
361
314
|
properties?: Record<string, string | number | boolean | null> | undefined;
|
|
@@ -426,9 +379,11 @@ export declare const visitorJourney: import("convex/server").RegisteredQuery<"pu
|
|
|
426
379
|
os: string;
|
|
427
380
|
device: string;
|
|
428
381
|
affiliateSlug?: string | undefined;
|
|
382
|
+
clid?: string[] | undefined;
|
|
429
383
|
currency?: string | undefined;
|
|
430
384
|
eventId: string;
|
|
431
385
|
href?: string | undefined;
|
|
386
|
+
inApp?: string | undefined;
|
|
432
387
|
name?: string | undefined;
|
|
433
388
|
path: string;
|
|
434
389
|
properties?: Record<string, string | number | boolean | null> | undefined;
|
|
@@ -629,7 +584,7 @@ export declare const dataCoverage: import("convex/server").RegisteredQuery<"publ
|
|
|
629
584
|
from: number;
|
|
630
585
|
to: number;
|
|
631
586
|
datasets: {
|
|
632
|
-
dataset: "affiliates" | "conversions" | "events" | "funnels" | "goals" | "overviewDay" | "overviewHour" | "overviewLocalDay" | "sessions" | "siteMap" | "vitals";
|
|
587
|
+
dataset: "affiliates" | "conversions" | "events" | "funnels" | "goals" | "origin" | "overviewDay" | "overviewHour" | "overviewLocalDay" | "sessions" | "siteMap" | "vitals";
|
|
633
588
|
coverage: {
|
|
634
589
|
state: "complete" | "partial" | "retained" | "unavailable";
|
|
635
590
|
generation: 1 | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reports.d.ts","sourceRoot":"","sources":["../../src/component/reports.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"reports.d.ts","sourceRoot":"","sources":["../../src/component/reports.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,6 +7,8 @@ import { fail } from "./errors.js";
|
|
|
7
7
|
import { isLocalDayAligned, localDayStart, localDayStarts, localDayTimezone, sharedLocalTimezone, } from "./localTime.js";
|
|
8
8
|
import { compareJourneyEvents, hydrateEventContexts, loadSessionJourneyEvents, loadVisitorJourneyEvents, } from "./eventStore.js";
|
|
9
9
|
import { isPlainRecord } from "./guards.js";
|
|
10
|
+
import { classifyOrigin } from "./origin.js";
|
|
11
|
+
import { externalReferrer } from "./sanitize.js";
|
|
10
12
|
import { affiliateFieldsValidator, eventFieldsValidator, funnelFieldsValidator, goalFieldsValidator, sessionFieldsValidator, vitalMetricValidator, } from "./validators.js";
|
|
11
13
|
import { resolveVisitorIdentities } from "./visitors.js";
|
|
12
14
|
import { mergeVitalHistograms, VITAL_ALL, VITAL_METRICS, vitalHistogramPercentile, vitalRatingCounts, } from "./vitals.js";
|
|
@@ -145,6 +147,11 @@ export const overview = query({
|
|
|
145
147
|
topMediums: v.array(topItemValidator),
|
|
146
148
|
// Destination hosts of outbound clicks, ranked by clicks.
|
|
147
149
|
topOutbound: v.array(topItemValidator),
|
|
150
|
+
// The session's origin (origin.ts), ranked like sources: platform ids,
|
|
151
|
+
// channel ids, and the evidence that decided them.
|
|
152
|
+
topPlatforms: v.array(topItemValidator),
|
|
153
|
+
topChannels: v.array(topItemValidator),
|
|
154
|
+
topEvidence: v.array(topItemValidator),
|
|
148
155
|
metadata: v.object({
|
|
149
156
|
visitors: v.object({
|
|
150
157
|
basis: v.union(v.literal("estimatedUnique"), v.literal("bucketOccurrences")),
|
|
@@ -164,6 +171,9 @@ export const overview = query({
|
|
|
164
171
|
topGoals: v.literal("goalCompletionVolume"),
|
|
165
172
|
topMediums: breakdownBasisValidator,
|
|
166
173
|
topOutbound: v.literal("eventVolume"),
|
|
174
|
+
topPlatforms: breakdownBasisValidator,
|
|
175
|
+
topChannels: breakdownBasisValidator,
|
|
176
|
+
topEvidence: breakdownBasisValidator,
|
|
167
177
|
}),
|
|
168
178
|
// Since when every site in the request records the medium and outbound
|
|
169
179
|
// slots; null while one of them has not stamped it. A range that starts
|
|
@@ -390,6 +400,9 @@ export const overview = query({
|
|
|
390
400
|
topGoals: top("goal", "eventVolume"),
|
|
391
401
|
topMediums: top("medium", sessionBasis),
|
|
392
402
|
topOutbound: top("outbound", "eventVolume"),
|
|
403
|
+
topPlatforms: top("platform", sessionBasis),
|
|
404
|
+
topChannels: top("channel", sessionBasis),
|
|
405
|
+
topEvidence: top("evidence", sessionBasis),
|
|
393
406
|
metadata: {
|
|
394
407
|
visitors: {
|
|
395
408
|
basis: visitorBasis,
|
|
@@ -409,6 +422,9 @@ export const overview = query({
|
|
|
409
422
|
topGoals: "goalCompletionVolume",
|
|
410
423
|
topMediums: sessionBasis,
|
|
411
424
|
topOutbound: "eventVolume",
|
|
425
|
+
topPlatforms: sessionBasis,
|
|
426
|
+
topChannels: sessionBasis,
|
|
427
|
+
topEvidence: sessionBasis,
|
|
412
428
|
},
|
|
413
429
|
dimensionsSince: controls.every((control) => control?.dimensionsSince !== undefined)
|
|
414
430
|
? Math.max(...controls.map((control) => control.dimensionsSince))
|
|
@@ -720,6 +736,22 @@ async function readRouteRollups(ctx, siteId, from, to, budget) {
|
|
|
720
736
|
}
|
|
721
737
|
return { rows, completeFrom: cutAt + DAY_MS };
|
|
722
738
|
}
|
|
739
|
+
/**
|
|
740
|
+
* A session recorded before origins existed, classified on read from what it
|
|
741
|
+
* kept (utm fields, referrer, affiliate) and marked `legacy`: it carries no
|
|
742
|
+
* click IDs or in-app signal, and it never enters the aggregates.
|
|
743
|
+
*/
|
|
744
|
+
function withOrigin(session, domains) {
|
|
745
|
+
if (session.platform !== undefined)
|
|
746
|
+
return session;
|
|
747
|
+
const origin = classifyOrigin({
|
|
748
|
+
utmSource: session.utmSource,
|
|
749
|
+
utmMedium: session.utmMedium,
|
|
750
|
+
referrer: externalReferrer(session.referrer, domains),
|
|
751
|
+
affiliate: session.affiliateSlug !== undefined,
|
|
752
|
+
});
|
|
753
|
+
return { ...session, ...origin, evidence: "legacy" };
|
|
754
|
+
}
|
|
723
755
|
/** Metadata for a selected session, independent of list pagination. */
|
|
724
756
|
export const getSession = query({
|
|
725
757
|
args: { siteId: v.id("sites"), sessionId: v.string() },
|
|
@@ -732,7 +764,8 @@ export const getSession = query({
|
|
|
732
764
|
if (!session)
|
|
733
765
|
return null;
|
|
734
766
|
const { geoLookupAttemptedAt: _geo, lastPageviewAt: _pageview, ...result } = session;
|
|
735
|
-
|
|
767
|
+
const site = await ctx.db.get("sites", args.siteId);
|
|
768
|
+
return withOrigin(result, site?.domains ?? []);
|
|
736
769
|
},
|
|
737
770
|
});
|
|
738
771
|
/** Exact commissions alongside overview's period revenue/conversion totals. */
|
|
@@ -844,7 +877,8 @@ export const listSessions = query({
|
|
|
844
877
|
.order("desc")
|
|
845
878
|
.take(take)));
|
|
846
879
|
}
|
|
847
|
-
const
|
|
880
|
+
const site = await ctx.db.get("sites", args.siteId);
|
|
881
|
+
const publicRows = rows.map(({ geoLookupAttemptedAt: _attemptedAt, lastPageviewAt: _lastPageviewAt, ...row }) => withOrigin(row, site?.domains ?? []));
|
|
848
882
|
return keysetPaginationResult(publicRows, pagination, (row) => ({
|
|
849
883
|
timestamp: row.lastSeenAt,
|
|
850
884
|
creationTime: row._creationTime,
|
|
@@ -1381,7 +1415,7 @@ export const vitalsReport = query({
|
|
|
1381
1415
|
};
|
|
1382
1416
|
},
|
|
1383
1417
|
});
|
|
1384
|
-
const coverageDatasetValidator = v.union(v.literal("overviewHour"), v.literal("overviewDay"), v.literal("overviewLocalDay"), v.literal("events"), v.literal("sessions"), v.literal("conversions"), v.literal("goals"), v.literal("funnels"), v.literal("affiliates"), v.literal("vitals"), v.literal("siteMap"));
|
|
1418
|
+
const coverageDatasetValidator = v.union(v.literal("overviewHour"), v.literal("overviewDay"), v.literal("overviewLocalDay"), v.literal("events"), v.literal("sessions"), v.literal("conversions"), v.literal("goals"), v.literal("funnels"), v.literal("affiliates"), v.literal("vitals"), v.literal("siteMap"), v.literal("origin"));
|
|
1385
1419
|
export const dataCoverage = query({
|
|
1386
1420
|
args: {
|
|
1387
1421
|
siteId: v.id("sites"),
|
|
@@ -1411,6 +1445,7 @@ export const dataCoverage = query({
|
|
|
1411
1445
|
"affiliates",
|
|
1412
1446
|
"vitals",
|
|
1413
1447
|
"siteMap",
|
|
1448
|
+
"origin",
|
|
1414
1449
|
];
|
|
1415
1450
|
return {
|
|
1416
1451
|
siteId: args.siteId,
|
|
@@ -1601,7 +1636,12 @@ async function assertSourceAvailable(ctx, siteIds, sources, from) {
|
|
|
1601
1636
|
}
|
|
1602
1637
|
async function datasetCoverageForRange(ctx, siteId, dataset, from, to) {
|
|
1603
1638
|
if (dataset === "siteMap") {
|
|
1604
|
-
return
|
|
1639
|
+
return stampedDatasetCoverage(ctx, siteId, from, to, "siteMapSince", siteMapCoverageDataset);
|
|
1640
|
+
}
|
|
1641
|
+
// Origins exist in sessions and aggregate slots from the site's stamp, and
|
|
1642
|
+
// the overview reads them from the daily aggregates retention trims.
|
|
1643
|
+
if (dataset === "origin") {
|
|
1644
|
+
return stampedDatasetCoverage(ctx, siteId, from, to, "originSince", "overviewDay");
|
|
1605
1645
|
}
|
|
1606
1646
|
// Vitals have no legacy fallback source; the rollup either covers the range
|
|
1607
1647
|
// or the coverage states say how much of it exists.
|
|
@@ -1635,17 +1675,18 @@ async function datasetCoverageForRange(ctx, siteId, dataset, from, to) {
|
|
|
1635
1675
|
return options.sort((left, right) => coverageRank(right.state) - coverageRank(left.state))[0];
|
|
1636
1676
|
}
|
|
1637
1677
|
/**
|
|
1638
|
-
*
|
|
1639
|
-
* `siteMapSince` and ends where retention cut
|
|
1640
|
-
* narrow the window when the range exceeds
|
|
1678
|
+
* A stamped dataset's coverage without reading its rows: it starts at the
|
|
1679
|
+
* site's stamp (`siteMapSince`, `originSince`) and ends where retention cut
|
|
1680
|
+
* it. The site map report may still narrow the window when the range exceeds
|
|
1681
|
+
* its row budget.
|
|
1641
1682
|
*/
|
|
1642
|
-
async function
|
|
1683
|
+
async function stampedDatasetCoverage(ctx, siteId, from, to, stamp, retainedDataset) {
|
|
1643
1684
|
const control = await ctx.db
|
|
1644
1685
|
.query("analyticsCoverage")
|
|
1645
1686
|
.withIndex("by_siteId", (range) => range.eq("siteId", siteId))
|
|
1646
1687
|
.unique();
|
|
1647
|
-
const since = control?.
|
|
1648
|
-
const retainedBefore = control?.retained.find((item) => item.dataset ===
|
|
1688
|
+
const since = control?.[stamp] ?? null;
|
|
1689
|
+
const retainedBefore = control?.retained.find((item) => item.dataset === retainedDataset)
|
|
1649
1690
|
?.before ?? null;
|
|
1650
1691
|
const unavailable = since === null ||
|
|
1651
1692
|
to < since ||
|