@iann29/rastro 0.5.0 → 0.6.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.
Files changed (70) hide show
  1. package/README.md +26 -9
  2. package/agent/integration.md +40 -19
  3. package/agent/manifest.json +13 -7
  4. package/agent/manifest.schema.json +18 -8
  5. package/dist/client/federation.d.ts +18 -8
  6. package/dist/client/federation.d.ts.map +1 -1
  7. package/dist/client/federation.js +7 -1
  8. package/dist/client/federation.js.map +1 -1
  9. package/dist/client/identity.d.ts +11 -0
  10. package/dist/client/identity.d.ts.map +1 -0
  11. package/dist/client/identity.js +123 -0
  12. package/dist/client/identity.js.map +1 -0
  13. package/dist/client/index.d.ts +242 -5
  14. package/dist/client/index.d.ts.map +1 -1
  15. package/dist/client/index.js +102 -3
  16. package/dist/client/index.js.map +1 -1
  17. package/dist/component/_generated/api.d.ts +2 -0
  18. package/dist/component/_generated/api.d.ts.map +1 -1
  19. package/dist/component/_generated/api.js.map +1 -1
  20. package/dist/component/_generated/component.d.ts +87 -0
  21. package/dist/component/_generated/component.d.ts.map +1 -1
  22. package/dist/component/ingest.d.ts.map +1 -1
  23. package/dist/component/ingest.js +30 -19
  24. package/dist/component/ingest.js.map +1 -1
  25. package/dist/component/people.d.ts +79 -0
  26. package/dist/component/people.d.ts.map +1 -0
  27. package/dist/component/people.js +249 -0
  28. package/dist/component/people.js.map +1 -0
  29. package/dist/component/reports.d.ts +10 -4
  30. package/dist/component/reports.d.ts.map +1 -1
  31. package/dist/component/reports.js +9 -5
  32. package/dist/component/reports.js.map +1 -1
  33. package/dist/component/schema.d.ts +39 -0
  34. package/dist/component/schema.js +30 -1
  35. package/dist/component/schema.js.map +1 -1
  36. package/dist/component/validators.d.ts +50 -0
  37. package/dist/component/validators.d.ts.map +1 -1
  38. package/dist/component/validators.js +27 -0
  39. package/dist/component/validators.js.map +1 -1
  40. package/dist/component/visitors.d.ts +38 -2
  41. package/dist/component/visitors.d.ts.map +1 -1
  42. package/dist/component/visitors.js +162 -42
  43. package/dist/component/visitors.js.map +1 -1
  44. package/dist/react/index.d.ts +9 -5
  45. package/dist/react/index.d.ts.map +1 -1
  46. package/dist/react/index.js +36 -5
  47. package/dist/react/index.js.map +1 -1
  48. package/dist/tracker/generated.d.ts +6 -6
  49. package/dist/tracker/generated.d.ts.map +1 -1
  50. package/dist/tracker/generated.js +6 -6
  51. package/dist/tracker/generated.js.map +1 -1
  52. package/dist/tracker/tracker.d.ts +2 -1
  53. package/dist/tracker/tracker.d.ts.map +1 -1
  54. package/dist/tracker/tracker.js +41 -2
  55. package/dist/tracker/tracker.js.map +1 -1
  56. package/dist/tracker.min.js +1 -1
  57. package/docs/federation.md +24 -0
  58. package/docs/identity.md +307 -0
  59. package/docs/upgrading.md +58 -20
  60. package/llms.txt +6 -2
  61. package/package.json +5 -3
  62. package/src/component/_generated/api.ts +2 -0
  63. package/src/component/_generated/component.ts +99 -0
  64. package/src/component/ingest.ts +46 -27
  65. package/src/component/people.ts +321 -0
  66. package/src/component/reports.ts +11 -4
  67. package/src/component/schema.ts +35 -0
  68. package/src/component/validators.ts +49 -0
  69. package/src/component/visitors.ts +232 -55
  70. package/src/tracker/generated.ts +6 -6
@@ -0,0 +1,79 @@
1
+ import { type MutationCtx } from "./_generated/server.js";
2
+ import type { Doc, Id } from "./_generated/dataModel.js";
3
+ import { type PersonAttributes } from "./validators.js";
4
+ export declare const personDocumentValidator: import("convex/values").VObject<{
5
+ _creationTime: number;
6
+ _id: import("convex/values").GenericId<"visitorProfiles">;
7
+ attributes?: Record<string, string | number | boolean> | undefined;
8
+ email?: string | undefined;
9
+ identifiedAt: number;
10
+ name?: string | undefined;
11
+ siteId: import("convex/values").GenericId<"sites">;
12
+ updatedAt: number;
13
+ visitorId: string;
14
+ }, {
15
+ visitorId: import("convex/values").VString<string, "required">;
16
+ name: import("convex/values").VString<string | undefined, "optional">;
17
+ email: import("convex/values").VString<string | undefined, "optional">;
18
+ attributes: import("convex/values").VRecord<Record<string, string | number | boolean> | undefined, import("convex/values").VString<string, "required">, import("convex/values").VUnion<string | number | boolean, [import("convex/values").VString<string, "required">, import("convex/values").VFloat64<number, "required">, import("convex/values").VBoolean<boolean, "required">], "required", never>, "optional", string>;
19
+ identifiedAt: import("convex/values").VFloat64<number, "required">;
20
+ updatedAt: import("convex/values").VFloat64<number, "required">;
21
+ _id: import("convex/values").VId<import("convex/values").GenericId<"visitorProfiles">, "required">;
22
+ _creationTime: import("convex/values").VFloat64<number, "required">;
23
+ siteId: import("convex/values").VId<import("convex/values").GenericId<"sites">, "required">;
24
+ }, "required", "_creationTime" | "_id" | "attributes" | "email" | "identifiedAt" | "name" | "siteId" | "updatedAt" | "visitorId" | `attributes.${string}`>;
25
+ export declare function profileSearchFields(name?: string, email?: string): {
26
+ searchName: string;
27
+ searchEmail: string;
28
+ };
29
+ export declare function mergePersonAttributes(previous?: PersonAttributes, patch?: Record<string, string | number | boolean | null>): PersonAttributes;
30
+ /** Index each current attribute once; ordinary reads never scan all profiles. */
31
+ export declare function syncPersonAttributes(ctx: MutationCtx, siteId: Id<"sites">, visitorId: string, attributes: PersonAttributes): Promise<void>;
32
+ export declare function publicPerson(row: Doc<"visitorProfiles">): {
33
+ _creationTime: number;
34
+ _id: import("convex/values").GenericId<"visitorProfiles">;
35
+ attributes?: Record<string, string | number | boolean> | undefined;
36
+ email?: string | undefined;
37
+ identifiedAt: number;
38
+ name?: string | undefined;
39
+ siteId: import("convex/values").GenericId<"sites">;
40
+ updatedAt: number;
41
+ visitorId: string;
42
+ };
43
+ /** An optional, bounded upgrade for profiles created before the directory. */
44
+ export declare const backfillSearch: import("convex/server").RegisteredMutation<"public", {
45
+ siteId: import("convex/values").GenericId<"sites">;
46
+ }, Promise<{
47
+ updated: number;
48
+ isDone: boolean;
49
+ }>>;
50
+ export declare const list: import("convex/server").RegisteredQuery<"public", {
51
+ filter?: {
52
+ field: "email" | "name" | "visitorId";
53
+ prefix: string;
54
+ } | {
55
+ field: "attribute";
56
+ key: string;
57
+ value: string | number | boolean;
58
+ } | undefined;
59
+ paginationOpts: {
60
+ cursor: string | null;
61
+ numItems: number;
62
+ };
63
+ siteId: import("convex/values").GenericId<"sites">;
64
+ }, Promise<{
65
+ page: {
66
+ _creationTime: number;
67
+ _id: import("convex/values").GenericId<"visitorProfiles">;
68
+ attributes?: Record<string, string | number | boolean> | undefined;
69
+ email?: string | undefined;
70
+ identifiedAt: number;
71
+ name?: string | undefined;
72
+ siteId: import("convex/values").GenericId<"sites">;
73
+ updatedAt: number;
74
+ visitorId: string;
75
+ }[];
76
+ isDone: boolean;
77
+ continueCursor: string;
78
+ }>>;
79
+ //# sourceMappingURL=people.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"people.d.ts","sourceRoot":"","sources":["../../src/component/people.ts"],"names":[],"mappings":"AACA,OAAO,EAAmB,KAAK,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC3E,OAAO,KAAK,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,2BAA2B,CAAC;AAEzD,OAAO,EAGL,KAAK,gBAAgB,EAEtB,MAAM,iBAAiB,CAAC;AAEzB,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;0JAIlC,CAAC;AAEH,wBAAgB,mBAAmB,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM;IAE7D,UAAU;IACV,WAAW;EAEd;AAMD,wBAAgB,qBAAqB,CACnC,QAAQ,GAAE,gBAAqB,EAC/B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC,GACvD,gBAAgB,CAqBlB;AAwBD,iFAAiF;AACjF,wBAAsB,oBAAoB,CACxC,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,EAAE,CAAC,OAAO,CAAC,EACnB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,gBAAgB,iBA2B7B;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,GAAG,CAAC,iBAAiB,CAAC;;;;;;;;;;EAGvD;AAED,8EAA8E;AAC9E,eAAO,MAAM,cAAc;;;;;GA2BzB,CAAC;AAgCH,eAAO,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiJf,CAAC"}
@@ -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
@@ -250,7 +252,9 @@ type SessionRow = Omit<Doc<"sessions">, "geoLookupAttemptedAt" | "lastPageviewAt
250
252
  export declare const getSession: import("convex/server").RegisteredQuery<"public", {
251
253
  sessionId: string;
252
254
  siteId: import("convex/values").GenericId<"sites">;
253
- }, Promise<SessionRow | null>>;
255
+ }, Promise<(SessionRow & {
256
+ profile?: import("./validators.js").VisitorProfile;
257
+ }) | null>>;
254
258
  /** Exact commissions alongside overview's period revenue/conversion totals. */
255
259
  export declare const revenueSummary: import("convex/server").RegisteredQuery<"public", {
256
260
  from: number;
@@ -272,7 +276,9 @@ export declare const listSessions: import("convex/server").RegisteredQuery<"publ
272
276
  siteId: import("convex/values").GenericId<"sites">;
273
277
  to: number;
274
278
  }, Promise<{
275
- page: SessionRow[];
279
+ page: (SessionRow & {
280
+ profile?: import("./validators.js").VisitorProfile;
281
+ })[];
276
282
  isDone: boolean;
277
283
  continueCursor: string;
278
284
  }>>;
@@ -1 +1 @@
1
- {"version":3,"file":"reports.d.ts","sourceRoot":"","sources":["../../src/component/reports.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"reports.d.ts","sourceRoot":"","sources":["../../src/component/reports.ts"],"names":[],"mappings":"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"}
@@ -9,10 +9,11 @@ import { compareJourneyEvents, hydrateEventContexts, loadSessionJourneyEvents, l
9
9
  import { isPlainRecord } from "./guards.js";
10
10
  import { classifyOrigin } from "./origin.js";
11
11
  import { externalReferrer } from "./sanitize.js";
12
- import { affiliateFieldsValidator, eventFieldsValidator, funnelFieldsValidator, goalFieldsValidator, sessionFieldsValidator, vitalMetricValidator, } from "./validators.js";
13
- import { resolveVisitorIdentities } from "./visitors.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
- return rows
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({
@@ -765,7 +768,7 @@ export const getSession = query({
765
768
  return null;
766
769
  const { geoLookupAttemptedAt: _geo, lastPageviewAt: _pageview, ...result } = session;
767
770
  const site = await ctx.db.get("sites", args.siteId);
768
- return withOrigin(result, site?.domains ?? []);
771
+ return (await withVisitorProfiles(ctx, [withOrigin(result, site?.domains ?? [])]))[0];
769
772
  },
770
773
  });
771
774
  /** Exact commissions alongside overview's period revenue/conversion totals. */
@@ -879,10 +882,11 @@ export const listSessions = query({
879
882
  }
880
883
  const site = await ctx.db.get("sites", args.siteId);
881
884
  const publicRows = rows.map(({ geoLookupAttemptedAt: _attemptedAt, lastPageviewAt: _lastPageviewAt, ...row }) => withOrigin(row, site?.domains ?? []));
882
- return keysetPaginationResult(publicRows, pagination, (row) => ({
885
+ const result = keysetPaginationResult(publicRows, pagination, (row) => ({
883
886
  timestamp: row.lastSeenAt,
884
887
  creationTime: row._creationTime,
885
888
  }));
889
+ return { ...result, page: await withVisitorProfiles(ctx, result.page) };
886
890
  },
887
891
  });
888
892
  export const sessionJourney = query({