@iann29/rastro 0.5.0 → 0.7.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 +53 -9
- package/agent/integration.md +48 -19
- package/agent/manifest.json +13 -7
- package/agent/manifest.schema.json +18 -8
- package/dist/client/federation.d.ts +18 -8
- package/dist/client/federation.d.ts.map +1 -1
- package/dist/client/federation.js +7 -1
- package/dist/client/federation.js.map +1 -1
- package/dist/client/identity.d.ts +11 -0
- package/dist/client/identity.d.ts.map +1 -0
- package/dist/client/identity.js +123 -0
- package/dist/client/identity.js.map +1 -0
- package/dist/client/index.d.ts +257 -7
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +110 -4
- package/dist/client/index.js.map +1 -1
- package/dist/component/_generated/api.d.ts +2 -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 +92 -0
- package/dist/component/_generated/component.d.ts.map +1 -1
- package/dist/component/ingest.d.ts.map +1 -1
- package/dist/component/ingest.js +37 -24
- package/dist/component/ingest.js.map +1 -1
- package/dist/component/people.d.ts +79 -0
- package/dist/component/people.d.ts.map +1 -0
- package/dist/component/people.js +249 -0
- package/dist/component/people.js.map +1 -0
- package/dist/component/reports.d.ts +13 -4
- package/dist/component/reports.d.ts.map +1 -1
- package/dist/component/reports.js +25 -10
- package/dist/component/reports.js.map +1 -1
- package/dist/component/sanitize.d.ts +3 -1
- package/dist/component/sanitize.d.ts.map +1 -1
- package/dist/component/sanitize.js +30 -1
- package/dist/component/sanitize.js.map +1 -1
- package/dist/component/schema.d.ts +42 -1
- package/dist/component/schema.js +30 -1
- package/dist/component/schema.js.map +1 -1
- package/dist/component/sites.d.ts +4 -0
- package/dist/component/sites.d.ts.map +1 -1
- package/dist/component/sites.js +13 -2
- package/dist/component/sites.js.map +1 -1
- package/dist/component/validators.d.ts +53 -1
- package/dist/component/validators.d.ts.map +1 -1
- package/dist/component/validators.js +28 -0
- package/dist/component/validators.js.map +1 -1
- package/dist/component/visitors.d.ts +38 -2
- package/dist/component/visitors.d.ts.map +1 -1
- package/dist/component/visitors.js +162 -42
- package/dist/component/visitors.js.map +1 -1
- package/dist/react/index.d.ts +9 -5
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +36 -5
- package/dist/react/index.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 +2 -1
- package/dist/tracker/tracker.d.ts.map +1 -1
- package/dist/tracker/tracker.js +41 -2
- package/dist/tracker/tracker.js.map +1 -1
- package/dist/tracker.min.js +1 -1
- package/docs/federation.md +24 -0
- package/docs/identity.md +307 -0
- package/docs/upgrading.md +85 -20
- package/llms.txt +6 -2
- package/package.json +5 -3
- package/src/component/_generated/api.ts +2 -0
- package/src/component/_generated/component.ts +104 -0
- package/src/component/ingest.ts +54 -30
- package/src/component/people.ts +321 -0
- package/src/component/reports.ts +34 -9
- package/src/component/sanitize.ts +46 -1
- package/src/component/schema.ts +35 -0
- package/src/component/sites.ts +14 -1
- package/src/component/validators.ts +50 -0
- package/src/component/visitors.ts +232 -55
- package/src/tracker/generated.ts +6 -6
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
import { v } from "convex/values";
|
|
2
|
+
import { query, mutation } from "./_generated/server.js";
|
|
3
|
+
import { fail } from "./errors.js";
|
|
4
|
+
import { personFilterValidator, visitorProfileValidator, } from "./validators.js";
|
|
5
|
+
export const personDocumentValidator = visitorProfileValidator.extend({
|
|
6
|
+
_id: v.id("visitorProfiles"),
|
|
7
|
+
_creationTime: v.number(),
|
|
8
|
+
siteId: v.id("sites"),
|
|
9
|
+
});
|
|
10
|
+
export function profileSearchFields(name, email) {
|
|
11
|
+
return {
|
|
12
|
+
searchName: normalizeSearch(name ?? ""),
|
|
13
|
+
searchEmail: normalizeSearch(email ?? ""),
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
function normalizeSearch(value) {
|
|
17
|
+
return value.normalize("NFKC").trim().toLowerCase();
|
|
18
|
+
}
|
|
19
|
+
export function mergePersonAttributes(previous = {}, patch) {
|
|
20
|
+
const attributes = { ...previous };
|
|
21
|
+
for (const [key, value] of Object.entries(patch ?? {})) {
|
|
22
|
+
validateAttributeKey(key);
|
|
23
|
+
if (value === null)
|
|
24
|
+
delete attributes[key];
|
|
25
|
+
else {
|
|
26
|
+
validateAttributeValue(value);
|
|
27
|
+
attributes[key] = value;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
if (Object.keys(attributes).length > 32 ||
|
|
31
|
+
new TextEncoder().encode(JSON.stringify(attributes)).length > 4096)
|
|
32
|
+
fail("INVALID_ARGUMENT", "attributes allow at most 32 keys and 4096 UTF-8 bytes");
|
|
33
|
+
return Object.fromEntries(Object.entries(attributes).sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0)));
|
|
34
|
+
}
|
|
35
|
+
function validateAttributeKey(key) {
|
|
36
|
+
if (!/^[A-Za-z][A-Za-z0-9_.-]{0,63}$/.test(key) ||
|
|
37
|
+
["__proto__", "constructor", "prototype"].includes(key))
|
|
38
|
+
fail("INVALID_ARGUMENT", "attribute keys must start with a letter and contain up to 64 ASCII letters, digits, dots, underscores or hyphens");
|
|
39
|
+
}
|
|
40
|
+
function validateAttributeValue(value) {
|
|
41
|
+
if ((typeof value === "string" && value.length > 512) ||
|
|
42
|
+
(typeof value === "number" && !Number.isFinite(value)))
|
|
43
|
+
fail("INVALID_ARGUMENT", "attribute values require finite numbers or strings up to 512 characters");
|
|
44
|
+
}
|
|
45
|
+
/** Index each current attribute once; ordinary reads never scan all profiles. */
|
|
46
|
+
export async function syncPersonAttributes(ctx, siteId, visitorId, attributes) {
|
|
47
|
+
const rows = await ctx.db
|
|
48
|
+
.query("visitorAttributes")
|
|
49
|
+
.withIndex("by_siteId_and_visitorId", (q) => q.eq("siteId", siteId).eq("visitorId", visitorId))
|
|
50
|
+
.take(33);
|
|
51
|
+
const present = new Set();
|
|
52
|
+
for (const row of rows) {
|
|
53
|
+
present.add(row.key);
|
|
54
|
+
if (!Object.hasOwn(attributes, row.key))
|
|
55
|
+
await ctx.db.delete("visitorAttributes", row._id);
|
|
56
|
+
else if (attributes[row.key] !== row.value)
|
|
57
|
+
await ctx.db.patch("visitorAttributes", row._id, {
|
|
58
|
+
value: attributes[row.key],
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
for (const [key, value] of Object.entries(attributes)) {
|
|
62
|
+
if (!present.has(key))
|
|
63
|
+
await ctx.db.insert("visitorAttributes", {
|
|
64
|
+
siteId,
|
|
65
|
+
visitorId,
|
|
66
|
+
key,
|
|
67
|
+
value,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
export function publicPerson(row) {
|
|
72
|
+
const { searchName: _name, searchEmail: _email, ...person } = row;
|
|
73
|
+
return person;
|
|
74
|
+
}
|
|
75
|
+
/** An optional, bounded upgrade for profiles created before the directory. */
|
|
76
|
+
export const backfillSearch = mutation({
|
|
77
|
+
args: { siteId: v.id("sites") },
|
|
78
|
+
returns: v.object({ updated: v.number(), isDone: v.boolean() }),
|
|
79
|
+
handler: async (ctx, { siteId }) => {
|
|
80
|
+
if (!(await ctx.db.get("sites", siteId)))
|
|
81
|
+
fail("NOT_FOUND", "site not found");
|
|
82
|
+
const rows = await ctx.db
|
|
83
|
+
.query("visitorProfiles")
|
|
84
|
+
.withIndex("by_siteId_and_searchName_and_visitorId", (q) => q.eq("siteId", siteId).eq("searchName", undefined))
|
|
85
|
+
.take(65);
|
|
86
|
+
for (const row of rows.slice(0, 64)) {
|
|
87
|
+
await ctx.db.patch("visitorProfiles", row._id, profileSearchFields(row.name, row.email));
|
|
88
|
+
await syncPersonAttributes(ctx, siteId, row.visitorId, row.attributes ?? {});
|
|
89
|
+
}
|
|
90
|
+
return { updated: Math.min(64, rows.length), isDone: rows.length <= 64 };
|
|
91
|
+
},
|
|
92
|
+
});
|
|
93
|
+
/** Exclusive upper bound for a Unicode prefix, including supplementary characters. */
|
|
94
|
+
function afterPrefix(prefix) {
|
|
95
|
+
const points = Array.from(prefix);
|
|
96
|
+
for (let i = points.length - 1; i >= 0; i--) {
|
|
97
|
+
const code = points[i].codePointAt(0);
|
|
98
|
+
if (code < 0x10ffff)
|
|
99
|
+
return (points.slice(0, i).join("") +
|
|
100
|
+
String.fromCodePoint(code + 1 === 0xd800 ? 0xe000 : code + 1));
|
|
101
|
+
}
|
|
102
|
+
return undefined;
|
|
103
|
+
}
|
|
104
|
+
function normalizedFilter(filter) {
|
|
105
|
+
if (!filter)
|
|
106
|
+
return undefined;
|
|
107
|
+
if (filter.field === "attribute") {
|
|
108
|
+
validateAttributeKey(filter.key);
|
|
109
|
+
validateAttributeValue(filter.value);
|
|
110
|
+
return { field: "attribute", key: filter.key, value: filter.value };
|
|
111
|
+
}
|
|
112
|
+
if (filter.prefix.length > 320)
|
|
113
|
+
fail("INVALID_ARGUMENT", "search prefix exceeds 320 characters");
|
|
114
|
+
const prefix = filter.field === "visitorId"
|
|
115
|
+
? filter.prefix.trim()
|
|
116
|
+
: normalizeSearch(filter.prefix);
|
|
117
|
+
return prefix ? { field: filter.field, prefix } : undefined;
|
|
118
|
+
}
|
|
119
|
+
export const list = query({
|
|
120
|
+
args: {
|
|
121
|
+
siteId: v.id("sites"),
|
|
122
|
+
filter: v.optional(personFilterValidator),
|
|
123
|
+
paginationOpts: v.object({
|
|
124
|
+
cursor: v.union(v.string(), v.null()),
|
|
125
|
+
numItems: v.number(),
|
|
126
|
+
}),
|
|
127
|
+
},
|
|
128
|
+
returns: v.object({
|
|
129
|
+
page: v.array(personDocumentValidator),
|
|
130
|
+
isDone: v.boolean(),
|
|
131
|
+
continueCursor: v.string(),
|
|
132
|
+
}),
|
|
133
|
+
handler: async (ctx, args) => {
|
|
134
|
+
const filter = normalizedFilter(args.filter);
|
|
135
|
+
const scope = JSON.stringify([args.siteId, filter ?? null]);
|
|
136
|
+
const limit = args.paginationOpts.numItems;
|
|
137
|
+
if (!Number.isSafeInteger(limit) || limit < 1 || limit > 50)
|
|
138
|
+
fail("INVALID_ARGUMENT", "numItems must be an integer between 1 and 50");
|
|
139
|
+
let after;
|
|
140
|
+
if (args.paginationOpts.cursor !== null) {
|
|
141
|
+
try {
|
|
142
|
+
// NFKC may expand one character into several, in both scope and value.
|
|
143
|
+
if (args.paginationOpts.cursor.length > 16_384)
|
|
144
|
+
throw new Error();
|
|
145
|
+
const cursor = JSON.parse(args.paginationOpts.cursor);
|
|
146
|
+
if (cursor.v !== 1 ||
|
|
147
|
+
cursor.scope !== scope ||
|
|
148
|
+
typeof cursor.value !== "string" ||
|
|
149
|
+
typeof cursor.visitorId !== "string")
|
|
150
|
+
throw new Error();
|
|
151
|
+
after = { value: cursor.value, visitorId: cursor.visitorId };
|
|
152
|
+
if (filter &&
|
|
153
|
+
filter.field !== "attribute" &&
|
|
154
|
+
!after.value.startsWith(filter.prefix))
|
|
155
|
+
throw new Error();
|
|
156
|
+
}
|
|
157
|
+
catch {
|
|
158
|
+
fail("INVALID_ARGUMENT", "cursor does not belong to this people query");
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
let rows;
|
|
162
|
+
const take = limit + 1;
|
|
163
|
+
if (filter?.field === "attribute") {
|
|
164
|
+
const matches = await ctx.db
|
|
165
|
+
.query("visitorAttributes")
|
|
166
|
+
.withIndex("by_siteId_and_key_and_value_and_visitorId", (q) => q
|
|
167
|
+
.eq("siteId", args.siteId)
|
|
168
|
+
.eq("key", filter.key)
|
|
169
|
+
.eq("value", filter.value)
|
|
170
|
+
.gt("visitorId", after?.visitorId ?? ""))
|
|
171
|
+
.take(take);
|
|
172
|
+
rows = await Promise.all(matches.map(async (match) => {
|
|
173
|
+
const row = await ctx.db
|
|
174
|
+
.query("visitorProfiles")
|
|
175
|
+
.withIndex("by_siteId_and_visitorId", (q) => q.eq("siteId", args.siteId).eq("visitorId", match.visitorId))
|
|
176
|
+
.unique();
|
|
177
|
+
if (!row)
|
|
178
|
+
fail("NOT_FOUND", "person attribute index has no profile");
|
|
179
|
+
return row;
|
|
180
|
+
}));
|
|
181
|
+
}
|
|
182
|
+
else if (filter && filter.field !== "visitorId") {
|
|
183
|
+
const pending = await ctx.db
|
|
184
|
+
.query("visitorProfiles")
|
|
185
|
+
.withIndex("by_siteId_and_searchName_and_visitorId", (q) => q.eq("siteId", args.siteId).eq("searchName", undefined))
|
|
186
|
+
.first();
|
|
187
|
+
if (pending)
|
|
188
|
+
fail("CONFLICT", "Run backfillVisitorProfiles for this site before searching existing profiles");
|
|
189
|
+
const field = filter.field === "name" ? "searchName" : "searchEmail";
|
|
190
|
+
const index = filter.field === "name"
|
|
191
|
+
? "by_siteId_and_searchName_and_visitorId"
|
|
192
|
+
: "by_siteId_and_searchEmail_and_visitorId";
|
|
193
|
+
rows = after
|
|
194
|
+
? await ctx.db
|
|
195
|
+
.query("visitorProfiles")
|
|
196
|
+
.withIndex(index, (q) => q
|
|
197
|
+
.eq("siteId", args.siteId)
|
|
198
|
+
.eq(field, after.value)
|
|
199
|
+
.gt("visitorId", after.visitorId))
|
|
200
|
+
.take(take)
|
|
201
|
+
: [];
|
|
202
|
+
if (rows.length < take) {
|
|
203
|
+
const upper = afterPrefix(filter.prefix);
|
|
204
|
+
const rest = await ctx.db
|
|
205
|
+
.query("visitorProfiles")
|
|
206
|
+
.withIndex(index, (q) => {
|
|
207
|
+
const lower = after
|
|
208
|
+
? q.eq("siteId", args.siteId).gt(field, after.value)
|
|
209
|
+
: q.eq("siteId", args.siteId).gte(field, filter.prefix);
|
|
210
|
+
return upper === undefined ? lower : lower.lt(field, upper);
|
|
211
|
+
})
|
|
212
|
+
.take(take - rows.length);
|
|
213
|
+
rows.push(...rest);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
const prefix = filter?.prefix ?? "";
|
|
218
|
+
const upper = afterPrefix(prefix);
|
|
219
|
+
rows = await ctx.db
|
|
220
|
+
.query("visitorProfiles")
|
|
221
|
+
.withIndex("by_siteId_and_visitorId", (q) => {
|
|
222
|
+
const lower = after
|
|
223
|
+
? q.eq("siteId", args.siteId).gt("visitorId", after.visitorId)
|
|
224
|
+
: q.eq("siteId", args.siteId).gte("visitorId", prefix);
|
|
225
|
+
return upper === undefined ? lower : lower.lt("visitorId", upper);
|
|
226
|
+
})
|
|
227
|
+
.take(take);
|
|
228
|
+
}
|
|
229
|
+
const page = rows.slice(0, limit);
|
|
230
|
+
const last = page.at(-1);
|
|
231
|
+
return {
|
|
232
|
+
page: page.map(publicPerson),
|
|
233
|
+
isDone: rows.length <= limit,
|
|
234
|
+
continueCursor: JSON.stringify({
|
|
235
|
+
v: 1,
|
|
236
|
+
scope,
|
|
237
|
+
visitorId: last?.visitorId ?? after?.visitorId ?? "",
|
|
238
|
+
value: last
|
|
239
|
+
? filter?.field === "name"
|
|
240
|
+
? last.searchName
|
|
241
|
+
: filter?.field === "email"
|
|
242
|
+
? last.searchEmail
|
|
243
|
+
: last.visitorId
|
|
244
|
+
: (after?.value ?? ""),
|
|
245
|
+
}),
|
|
246
|
+
};
|
|
247
|
+
},
|
|
248
|
+
});
|
|
249
|
+
//# sourceMappingURL=people.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"people.js","sourceRoot":"","sources":["../../src/component/people.ts"],"names":[],"mappings":"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"}
|
|
@@ -140,7 +140,7 @@ export declare const liveVisitors: import("convex/server").RegisteredQuery<"publ
|
|
|
140
140
|
limit?: number | undefined;
|
|
141
141
|
now: number;
|
|
142
142
|
siteIds: import("convex/values").GenericId<"sites">[];
|
|
143
|
-
}, Promise<{
|
|
143
|
+
}, Promise<({
|
|
144
144
|
_id: import("convex/values").GenericId<"liveSessions">;
|
|
145
145
|
_creationTime: number;
|
|
146
146
|
siteId: import("convex/values").GenericId<"sites">;
|
|
@@ -172,7 +172,9 @@ export declare const liveVisitors: import("convex/server").RegisteredQuery<"publ
|
|
|
172
172
|
step: number;
|
|
173
173
|
steps: number;
|
|
174
174
|
} | undefined;
|
|
175
|
-
}
|
|
175
|
+
} & {
|
|
176
|
+
profile?: import("./validators.js").VisitorProfile;
|
|
177
|
+
})[]>>;
|
|
176
178
|
/**
|
|
177
179
|
* Every route the sites served in the range and the transitions between
|
|
178
180
|
* them, read from the daily route rollups newest day first. Exits and
|
|
@@ -194,6 +196,9 @@ export declare const siteMap: import("convex/server").RegisteredQuery<"public",
|
|
|
194
196
|
from: number;
|
|
195
197
|
to: number;
|
|
196
198
|
} | null;
|
|
199
|
+
routePatterns: {
|
|
200
|
+
[k: string]: string[];
|
|
201
|
+
};
|
|
197
202
|
routes: {
|
|
198
203
|
route: string;
|
|
199
204
|
pageviews: number;
|
|
@@ -250,7 +255,9 @@ type SessionRow = Omit<Doc<"sessions">, "geoLookupAttemptedAt" | "lastPageviewAt
|
|
|
250
255
|
export declare const getSession: import("convex/server").RegisteredQuery<"public", {
|
|
251
256
|
sessionId: string;
|
|
252
257
|
siteId: import("convex/values").GenericId<"sites">;
|
|
253
|
-
}, Promise<SessionRow
|
|
258
|
+
}, Promise<(SessionRow & {
|
|
259
|
+
profile?: import("./validators.js").VisitorProfile;
|
|
260
|
+
}) | null>>;
|
|
254
261
|
/** Exact commissions alongside overview's period revenue/conversion totals. */
|
|
255
262
|
export declare const revenueSummary: import("convex/server").RegisteredQuery<"public", {
|
|
256
263
|
from: number;
|
|
@@ -272,7 +279,9 @@ export declare const listSessions: import("convex/server").RegisteredQuery<"publ
|
|
|
272
279
|
siteId: import("convex/values").GenericId<"sites">;
|
|
273
280
|
to: number;
|
|
274
281
|
}, Promise<{
|
|
275
|
-
page: SessionRow
|
|
282
|
+
page: (SessionRow & {
|
|
283
|
+
profile?: import("./validators.js").VisitorProfile;
|
|
284
|
+
})[];
|
|
276
285
|
isDone: boolean;
|
|
277
286
|
continueCursor: string;
|
|
278
287
|
}>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reports.d.ts","sourceRoot":"","sources":["../../src/component/reports.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"reports.d.ts","sourceRoot":"","sources":["../../src/component/reports.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,11 +8,12 @@ import { isLocalDayAligned, localDayStart, localDayStarts, localDayTimezone, sha
|
|
|
8
8
|
import { compareJourneyEvents, hydrateEventContexts, loadSessionJourneyEvents, loadVisitorJourneyEvents, } from "./eventStore.js";
|
|
9
9
|
import { isPlainRecord } from "./guards.js";
|
|
10
10
|
import { classifyOrigin } from "./origin.js";
|
|
11
|
-
import { externalReferrer } from "./sanitize.js";
|
|
12
|
-
import { affiliateFieldsValidator, eventFieldsValidator, funnelFieldsValidator, goalFieldsValidator, sessionFieldsValidator, vitalMetricValidator, } from "./validators.js";
|
|
13
|
-
import { resolveVisitorIdentities } from "./visitors.js";
|
|
11
|
+
import { externalReferrer, normalizeRoute } from "./sanitize.js";
|
|
12
|
+
import { affiliateFieldsValidator, eventFieldsValidator, funnelFieldsValidator, goalFieldsValidator, sessionFieldsValidator, vitalMetricValidator, visitorProfileValidator, } from "./validators.js";
|
|
13
|
+
import { resolveVisitorIdentities, withVisitorProfiles } from "./visitors.js";
|
|
14
14
|
import { mergeVitalHistograms, VITAL_ALL, VITAL_METRICS, vitalHistogramPercentile, vitalRatingCounts, } from "./vitals.js";
|
|
15
15
|
const sessionDocumentValidator = sessionFieldsValidator.extend({
|
|
16
|
+
profile: v.optional(visitorProfileValidator),
|
|
16
17
|
_id: v.id("sessions"),
|
|
17
18
|
_creationTime: v.number(),
|
|
18
19
|
});
|
|
@@ -21,6 +22,7 @@ const eventDocumentValidator = eventFieldsValidator.extend({
|
|
|
21
22
|
_creationTime: v.number(),
|
|
22
23
|
});
|
|
23
24
|
const liveSessionDocumentValidator = v.object({
|
|
25
|
+
profile: v.optional(visitorProfileValidator),
|
|
24
26
|
_id: v.id("liveSessions"),
|
|
25
27
|
_creationTime: v.number(),
|
|
26
28
|
siteId: v.id("sites"),
|
|
@@ -470,7 +472,7 @@ export const liveVisitors = query({
|
|
|
470
472
|
.order("desc")
|
|
471
473
|
.take(limit)));
|
|
472
474
|
}
|
|
473
|
-
|
|
475
|
+
const visible = rows
|
|
474
476
|
.sort((left, right) => right.lastSeenAt - left.lastSeenAt)
|
|
475
477
|
.slice(0, limit)
|
|
476
478
|
.map((row) => ({
|
|
@@ -504,6 +506,7 @@ export const liveVisitors = query({
|
|
|
504
506
|
: {}),
|
|
505
507
|
...(row.funnel ? { funnel: row.funnel } : {}),
|
|
506
508
|
}));
|
|
509
|
+
return withVisitorProfiles(ctx, visible);
|
|
507
510
|
},
|
|
508
511
|
});
|
|
509
512
|
const siteMapRouteValidator = v.object({
|
|
@@ -547,6 +550,7 @@ export const siteMap = query({
|
|
|
547
550
|
window: v.union(v.object({ from: v.number(), to: v.number() }), v.null()),
|
|
548
551
|
routes: v.array(siteMapRouteValidator),
|
|
549
552
|
transitions: v.array(siteMapTransitionValidator),
|
|
553
|
+
routePatterns: v.optional(v.record(v.string(), v.array(v.string()))),
|
|
550
554
|
truncated: v.object({ routes: v.boolean(), transitions: v.boolean() }),
|
|
551
555
|
metadata: reportMetadataValidator.extend({
|
|
552
556
|
visitors: v.object({
|
|
@@ -564,6 +568,10 @@ export const siteMap = query({
|
|
|
564
568
|
const siteIds = validateSiteIds(args.siteIds);
|
|
565
569
|
validateRange(args.from, args.to, MAX_FEATURE_ROLLUP_DAYS);
|
|
566
570
|
requireAlignedRange(args.from, args.to, DAY_MS, "site map");
|
|
571
|
+
const routePatterns = Object.fromEntries(await Promise.all(siteIds.map(async (siteId) => [
|
|
572
|
+
siteId,
|
|
573
|
+
(await ctx.db.get("sites", siteId))?.routePatterns ?? [],
|
|
574
|
+
])));
|
|
567
575
|
const controls = await Promise.all(siteIds.map((siteId) => ctx.db
|
|
568
576
|
.query("analyticsCoverage")
|
|
569
577
|
.withIndex("by_siteId", (range) => range.eq("siteId", siteId))
|
|
@@ -601,6 +609,7 @@ export const siteMap = query({
|
|
|
601
609
|
window: null,
|
|
602
610
|
routes: [],
|
|
603
611
|
transitions: [],
|
|
612
|
+
routePatterns,
|
|
604
613
|
truncated: { routes: false, transitions: false },
|
|
605
614
|
metadata: metadata("unavailable"),
|
|
606
615
|
};
|
|
@@ -639,7 +648,10 @@ export const siteMap = query({
|
|
|
639
648
|
for (const row of rows) {
|
|
640
649
|
if (row.bucketStart < completeFrom)
|
|
641
650
|
continue;
|
|
642
|
-
|
|
651
|
+
// Apply current patterns to retained rollups too, before merging sketches.
|
|
652
|
+
const patterns = routePatterns[row.siteId];
|
|
653
|
+
const route = normalizeRoute(row.route, patterns);
|
|
654
|
+
const current = totalsFor(route);
|
|
643
655
|
current.pageviews += row.pageviews;
|
|
644
656
|
current.entries += row.entries;
|
|
645
657
|
current.continued += row.continued;
|
|
@@ -648,10 +660,11 @@ export const siteMap = query({
|
|
|
648
660
|
current.sketch = unionVisitorSketches(current.sketch, row.visitorSketch);
|
|
649
661
|
current.daily.set(row.bucketStart, (current.daily.get(row.bucketStart) ?? 0) + row.pageviews);
|
|
650
662
|
for (const target of row.outgoing) {
|
|
651
|
-
const
|
|
663
|
+
const to = normalizeRoute(target.route, patterns);
|
|
664
|
+
const key = `${route}\u0000${to}`;
|
|
652
665
|
const edge = edges.get(key) ?? {
|
|
653
|
-
from:
|
|
654
|
-
to
|
|
666
|
+
from: route,
|
|
667
|
+
to,
|
|
655
668
|
count: 0,
|
|
656
669
|
};
|
|
657
670
|
edge.count += target.count;
|
|
@@ -695,6 +708,7 @@ export const siteMap = query({
|
|
|
695
708
|
from: args.from,
|
|
696
709
|
to: args.to,
|
|
697
710
|
window: completeFrom > args.to ? null : { from: windowFrom, to: args.to },
|
|
711
|
+
routePatterns,
|
|
698
712
|
routes: routeRows,
|
|
699
713
|
transitions: transitionRows,
|
|
700
714
|
truncated: {
|
|
@@ -765,7 +779,7 @@ export const getSession = query({
|
|
|
765
779
|
return null;
|
|
766
780
|
const { geoLookupAttemptedAt: _geo, lastPageviewAt: _pageview, ...result } = session;
|
|
767
781
|
const site = await ctx.db.get("sites", args.siteId);
|
|
768
|
-
return withOrigin(result, site?.domains ?? []);
|
|
782
|
+
return (await withVisitorProfiles(ctx, [withOrigin(result, site?.domains ?? [])]))[0];
|
|
769
783
|
},
|
|
770
784
|
});
|
|
771
785
|
/** Exact commissions alongside overview's period revenue/conversion totals. */
|
|
@@ -879,10 +893,11 @@ export const listSessions = query({
|
|
|
879
893
|
}
|
|
880
894
|
const site = await ctx.db.get("sites", args.siteId);
|
|
881
895
|
const publicRows = rows.map(({ geoLookupAttemptedAt: _attemptedAt, lastPageviewAt: _lastPageviewAt, ...row }) => withOrigin(row, site?.domains ?? []));
|
|
882
|
-
|
|
896
|
+
const result = keysetPaginationResult(publicRows, pagination, (row) => ({
|
|
883
897
|
timestamp: row.lastSeenAt,
|
|
884
898
|
creationTime: row._creationTime,
|
|
885
899
|
}));
|
|
900
|
+
return { ...result, page: await withVisitorProfiles(ctx, result.page) };
|
|
886
901
|
},
|
|
887
902
|
});
|
|
888
903
|
export const sessionJourney = query({
|