kanmi-perf-revenue 1.0.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 +251 -0
- package/dist/empirical/conversion-curve.d.ts +95 -0
- package/dist/empirical/conversion-curve.d.ts.map +1 -0
- package/dist/empirical/conversion-curve.js +240 -0
- package/dist/empirical/conversion-curve.js.map +1 -0
- package/dist/empirical/data-import.d.ts +59 -0
- package/dist/empirical/data-import.d.ts.map +1 -0
- package/dist/empirical/data-import.js +186 -0
- package/dist/empirical/data-import.js.map +1 -0
- package/dist/empirical/datadog-session-query.d.ts +66 -0
- package/dist/empirical/datadog-session-query.d.ts.map +1 -0
- package/dist/empirical/datadog-session-query.js +260 -0
- package/dist/empirical/datadog-session-query.js.map +1 -0
- package/dist/empirical/index.d.ts +109 -0
- package/dist/empirical/index.d.ts.map +1 -0
- package/dist/empirical/index.js +267 -0
- package/dist/empirical/index.js.map +1 -0
- package/dist/empirical/opportunity-calculator.d.ts +107 -0
- package/dist/empirical/opportunity-calculator.d.ts.map +1 -0
- package/dist/empirical/opportunity-calculator.js +238 -0
- package/dist/empirical/opportunity-calculator.js.map +1 -0
- package/dist/empirical/report.d.ts +37 -0
- package/dist/empirical/report.d.ts.map +1 -0
- package/dist/empirical/report.js +264 -0
- package/dist/empirical/report.js.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Data Import
|
|
3
|
+
*
|
|
4
|
+
* Import session data from CSV/JSON files.
|
|
5
|
+
* Bring your own data from any source.
|
|
6
|
+
*
|
|
7
|
+
* Expected format:
|
|
8
|
+
* - session_id: string
|
|
9
|
+
* - lcp_ms: number (optional)
|
|
10
|
+
* - inp_ms: number (optional)
|
|
11
|
+
* - cls: number (optional)
|
|
12
|
+
* - converted: boolean | 0 | 1
|
|
13
|
+
* - order_value: number (optional, defaults to 0)
|
|
14
|
+
* - device: 'mobile' | 'desktop' | 'tablet' (optional)
|
|
15
|
+
* - page_type: string (optional)
|
|
16
|
+
*
|
|
17
|
+
* @author Kanmi Obasa <i@kanmiobasa.com>
|
|
18
|
+
*/
|
|
19
|
+
import { readFileSync } from 'fs';
|
|
20
|
+
// =============================================================================
|
|
21
|
+
// IMPORT FUNCTIONS
|
|
22
|
+
// =============================================================================
|
|
23
|
+
/**
|
|
24
|
+
* Import sessions from a JSON file.
|
|
25
|
+
*/
|
|
26
|
+
export function importFromJson(filePath, options = {}) {
|
|
27
|
+
const content = readFileSync(filePath, 'utf-8');
|
|
28
|
+
const raw = JSON.parse(content);
|
|
29
|
+
// Handle both array and object with data property
|
|
30
|
+
const rows = Array.isArray(raw) ? raw : raw.data || raw.sessions || [];
|
|
31
|
+
return processRows(rows, options);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Import sessions from a CSV file.
|
|
35
|
+
*/
|
|
36
|
+
export function importFromCsv(filePath, options = {}) {
|
|
37
|
+
const content = readFileSync(filePath, 'utf-8');
|
|
38
|
+
const lines = content.trim().split('\n');
|
|
39
|
+
if (lines.length < 2) {
|
|
40
|
+
throw new Error('CSV must have header row and at least one data row');
|
|
41
|
+
}
|
|
42
|
+
const headers = parseCsvLine(lines[0]);
|
|
43
|
+
const rows = [];
|
|
44
|
+
for (let i = 1; i < lines.length; i++) {
|
|
45
|
+
const values = parseCsvLine(lines[i]);
|
|
46
|
+
const row = {};
|
|
47
|
+
headers.forEach((header, index) => {
|
|
48
|
+
const key = header.toLowerCase().trim().replace(/\s+/g, '_');
|
|
49
|
+
row[key] = values[index];
|
|
50
|
+
});
|
|
51
|
+
rows.push(row);
|
|
52
|
+
}
|
|
53
|
+
return processRows(rows, options);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Import from file (auto-detect format).
|
|
57
|
+
*/
|
|
58
|
+
export function importFromFile(filePath, options = {}) {
|
|
59
|
+
if (filePath.endsWith('.json')) {
|
|
60
|
+
return importFromJson(filePath, options);
|
|
61
|
+
}
|
|
62
|
+
if (filePath.endsWith('.csv')) {
|
|
63
|
+
return importFromCsv(filePath, options);
|
|
64
|
+
}
|
|
65
|
+
throw new Error('Unsupported file format. Use .json or .csv');
|
|
66
|
+
}
|
|
67
|
+
// =============================================================================
|
|
68
|
+
// ROW PROCESSING
|
|
69
|
+
// =============================================================================
|
|
70
|
+
function processRows(rows, options) {
|
|
71
|
+
const startTime = Date.now();
|
|
72
|
+
const sessions = [];
|
|
73
|
+
for (const row of rows) {
|
|
74
|
+
const session = normalizeRow(row);
|
|
75
|
+
if (session) {
|
|
76
|
+
sessions.push(session);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// Determine period
|
|
80
|
+
const timestamps = sessions
|
|
81
|
+
.map((s) => s.timestamp)
|
|
82
|
+
.filter((t) => t)
|
|
83
|
+
.sort();
|
|
84
|
+
const start = options.startDate || timestamps[0]?.split('T')[0] || new Date().toISOString().split('T')[0];
|
|
85
|
+
const end = options.endDate || timestamps[timestamps.length - 1]?.split('T')[0] || new Date().toISOString().split('T')[0];
|
|
86
|
+
const startDate = new Date(start);
|
|
87
|
+
const endDate = new Date(end);
|
|
88
|
+
const days = Math.max(1, Math.ceil((endDate.getTime() - startDate.getTime()) / (1000 * 60 * 60 * 24)) + 1);
|
|
89
|
+
return {
|
|
90
|
+
sessions,
|
|
91
|
+
metadata: {
|
|
92
|
+
total_sessions: sessions.length,
|
|
93
|
+
sessions_with_lcp: sessions.filter((s) => s.lcp_ms !== null).length,
|
|
94
|
+
sessions_with_conversions: sessions.filter((s) => s.has_purchase).length,
|
|
95
|
+
query_time_ms: Date.now() - startTime,
|
|
96
|
+
period: { start, end, days },
|
|
97
|
+
},
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
function normalizeRow(row) {
|
|
101
|
+
// Get session ID
|
|
102
|
+
const sessionId = row.session_id || row.sessionId || row.id;
|
|
103
|
+
if (!sessionId)
|
|
104
|
+
return null;
|
|
105
|
+
// Parse LCP
|
|
106
|
+
const lcpRaw = row.lcp_ms ?? row.lcp;
|
|
107
|
+
const lcp = parseNumber(lcpRaw);
|
|
108
|
+
// Parse INP
|
|
109
|
+
const inpRaw = row.inp_ms ?? row.inp;
|
|
110
|
+
const inp = parseNumber(inpRaw);
|
|
111
|
+
// Parse CLS
|
|
112
|
+
const cls = parseNumber(row.cls);
|
|
113
|
+
// Parse conversion
|
|
114
|
+
const convertedRaw = row.converted ?? row.has_purchase ?? row.purchased;
|
|
115
|
+
const converted = parseBoolean(convertedRaw);
|
|
116
|
+
// Parse order value
|
|
117
|
+
const valueRaw = row.order_value ?? row.purchase_value ?? row.revenue ?? row.value;
|
|
118
|
+
const orderValue = converted ? (parseNumber(valueRaw) || 0) : 0;
|
|
119
|
+
// Parse device
|
|
120
|
+
const deviceRaw = row.device || row.device_type || 'desktop';
|
|
121
|
+
const device = normalizeDevice(deviceRaw);
|
|
122
|
+
// Parse page type
|
|
123
|
+
const pageType = row.page_type || row.page || 'unknown';
|
|
124
|
+
// Parse timestamp
|
|
125
|
+
const timestamp = row.timestamp || row.date || new Date().toISOString();
|
|
126
|
+
return {
|
|
127
|
+
session_id: String(sessionId),
|
|
128
|
+
lcp_ms: lcp,
|
|
129
|
+
inp_ms: inp,
|
|
130
|
+
cls,
|
|
131
|
+
has_purchase: converted,
|
|
132
|
+
purchase_value: orderValue,
|
|
133
|
+
device,
|
|
134
|
+
page_type: pageType,
|
|
135
|
+
timestamp,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
// =============================================================================
|
|
139
|
+
// HELPERS
|
|
140
|
+
// =============================================================================
|
|
141
|
+
function parseNumber(value) {
|
|
142
|
+
if (value === null || value === undefined || value === '')
|
|
143
|
+
return null;
|
|
144
|
+
const num = Number(value);
|
|
145
|
+
return isNaN(num) ? null : num;
|
|
146
|
+
}
|
|
147
|
+
function parseBoolean(value) {
|
|
148
|
+
if (typeof value === 'boolean')
|
|
149
|
+
return value;
|
|
150
|
+
if (typeof value === 'number')
|
|
151
|
+
return value !== 0;
|
|
152
|
+
if (typeof value === 'string') {
|
|
153
|
+
const lower = value.toLowerCase().trim();
|
|
154
|
+
return lower === 'true' || lower === '1' || lower === 'yes';
|
|
155
|
+
}
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
function normalizeDevice(value) {
|
|
159
|
+
const lower = value.toLowerCase();
|
|
160
|
+
if (lower.includes('mobile') || lower.includes('phone'))
|
|
161
|
+
return 'mobile';
|
|
162
|
+
if (lower.includes('tablet') || lower.includes('ipad'))
|
|
163
|
+
return 'tablet';
|
|
164
|
+
return 'desktop';
|
|
165
|
+
}
|
|
166
|
+
function parseCsvLine(line) {
|
|
167
|
+
const result = [];
|
|
168
|
+
let current = '';
|
|
169
|
+
let inQuotes = false;
|
|
170
|
+
for (let i = 0; i < line.length; i++) {
|
|
171
|
+
const char = line[i];
|
|
172
|
+
if (char === '"') {
|
|
173
|
+
inQuotes = !inQuotes;
|
|
174
|
+
}
|
|
175
|
+
else if (char === ',' && !inQuotes) {
|
|
176
|
+
result.push(current.trim());
|
|
177
|
+
current = '';
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
current += char;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
result.push(current.trim());
|
|
184
|
+
return result;
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=data-import.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data-import.js","sourceRoot":"","sources":["../../src/empirical/data-import.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Datadog Session Query
|
|
3
|
+
*
|
|
4
|
+
* Queries Datadog RUM for session-level data with Core Web Vitals AND conversion outcomes.
|
|
5
|
+
* This is the foundation for building empirical conversion curves.
|
|
6
|
+
*
|
|
7
|
+
* Prerequisites:
|
|
8
|
+
* - Datadog RUM installed with session tracking
|
|
9
|
+
* - Conversion actions tracked: datadogRum.addAction('purchase', { value: orderTotal })
|
|
10
|
+
*
|
|
11
|
+
* @author Kanmi Obasa <i@kanmiobasa.com>
|
|
12
|
+
*/
|
|
13
|
+
export interface SessionData {
|
|
14
|
+
session_id: string;
|
|
15
|
+
lcp_ms: number | null;
|
|
16
|
+
inp_ms: number | null;
|
|
17
|
+
cls: number | null;
|
|
18
|
+
has_purchase: boolean;
|
|
19
|
+
purchase_value: number;
|
|
20
|
+
device: 'mobile' | 'desktop' | 'tablet';
|
|
21
|
+
page_type: string;
|
|
22
|
+
timestamp: string;
|
|
23
|
+
}
|
|
24
|
+
export interface DatadogQueryConfig {
|
|
25
|
+
apiKey: string;
|
|
26
|
+
appKey: string;
|
|
27
|
+
site?: string;
|
|
28
|
+
startDate: string;
|
|
29
|
+
endDate: string;
|
|
30
|
+
pageTypes?: string[];
|
|
31
|
+
devices?: ('mobile' | 'desktop' | 'tablet')[];
|
|
32
|
+
purchaseActionName?: string;
|
|
33
|
+
}
|
|
34
|
+
export interface QueryResult {
|
|
35
|
+
sessions: SessionData[];
|
|
36
|
+
metadata: {
|
|
37
|
+
total_sessions: number;
|
|
38
|
+
sessions_with_lcp: number;
|
|
39
|
+
sessions_with_conversions: number;
|
|
40
|
+
query_time_ms: number;
|
|
41
|
+
period: {
|
|
42
|
+
start: string;
|
|
43
|
+
end: string;
|
|
44
|
+
days: number;
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Query Datadog RUM for session-level data.
|
|
50
|
+
*
|
|
51
|
+
* Note: This uses the Datadog RUM Events API. In production, you'd want to
|
|
52
|
+
* use the RUM Analytics API for aggregations or export to a data warehouse.
|
|
53
|
+
*/
|
|
54
|
+
export declare function queryDatadogSessions(config: DatadogQueryConfig): Promise<QueryResult>;
|
|
55
|
+
/**
|
|
56
|
+
* Generate mock session data for testing without Datadog credentials.
|
|
57
|
+
* Models realistic e-commerce conversion patterns.
|
|
58
|
+
*/
|
|
59
|
+
export declare function generateMockSessions(options: {
|
|
60
|
+
count: number;
|
|
61
|
+
startDate: string;
|
|
62
|
+
endDate: string;
|
|
63
|
+
baseConversionRate?: number;
|
|
64
|
+
lcpConversionImpact?: number;
|
|
65
|
+
}): QueryResult;
|
|
66
|
+
//# sourceMappingURL=datadog-session-query.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"datadog-session-query.d.ts","sourceRoot":"","sources":["../../src/empirical/datadog-session-query.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IAEnB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAEnB,YAAY,EAAE,OAAO,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IAEvB,MAAM,EAAE,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,OAAO,CAAC,EAAE,CAAC,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC,EAAE,CAAC;IAC9C,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,QAAQ,EAAE;QACR,cAAc,EAAE,MAAM,CAAC;QACvB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,yBAAyB,EAAE,MAAM,CAAC;QAClC,aAAa,EAAE,MAAM,CAAC;QACtB,MAAM,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,GAAG,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC;KACtD,CAAC;CACH;AAMD;;;;;GAKG;AACH,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,WAAW,CAAC,CAuItB;AAMD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B,GAAG,WAAW,CAsEd"}
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Datadog Session Query
|
|
3
|
+
*
|
|
4
|
+
* Queries Datadog RUM for session-level data with Core Web Vitals AND conversion outcomes.
|
|
5
|
+
* This is the foundation for building empirical conversion curves.
|
|
6
|
+
*
|
|
7
|
+
* Prerequisites:
|
|
8
|
+
* - Datadog RUM installed with session tracking
|
|
9
|
+
* - Conversion actions tracked: datadogRum.addAction('purchase', { value: orderTotal })
|
|
10
|
+
*
|
|
11
|
+
* @author Kanmi Obasa <i@kanmiobasa.com>
|
|
12
|
+
*/
|
|
13
|
+
// =============================================================================
|
|
14
|
+
// DATADOG RUM API QUERY
|
|
15
|
+
// =============================================================================
|
|
16
|
+
/**
|
|
17
|
+
* Query Datadog RUM for session-level data.
|
|
18
|
+
*
|
|
19
|
+
* Note: This uses the Datadog RUM Events API. In production, you'd want to
|
|
20
|
+
* use the RUM Analytics API for aggregations or export to a data warehouse.
|
|
21
|
+
*/
|
|
22
|
+
export async function queryDatadogSessions(config) {
|
|
23
|
+
const startTime = Date.now();
|
|
24
|
+
const site = config.site || 'datadoghq.com';
|
|
25
|
+
const purchaseAction = config.purchaseActionName || 'purchase';
|
|
26
|
+
// Build the query filter
|
|
27
|
+
const filters = [
|
|
28
|
+
`@type:session`,
|
|
29
|
+
`@session.time_spent:>0`,
|
|
30
|
+
];
|
|
31
|
+
if (config.pageTypes?.length) {
|
|
32
|
+
filters.push(`@view.url_path:(${config.pageTypes.join(' OR ')})`);
|
|
33
|
+
}
|
|
34
|
+
if (config.devices?.length) {
|
|
35
|
+
filters.push(`@device.type:(${config.devices.join(' OR ')})`);
|
|
36
|
+
}
|
|
37
|
+
// Query sessions with their LCP, INP, CLS values
|
|
38
|
+
const response = await fetch(`https://api.${site}/api/v2/rum/events/search`, {
|
|
39
|
+
method: 'POST',
|
|
40
|
+
headers: {
|
|
41
|
+
'Content-Type': 'application/json',
|
|
42
|
+
'DD-API-KEY': config.apiKey,
|
|
43
|
+
'DD-APPLICATION-KEY': config.appKey,
|
|
44
|
+
},
|
|
45
|
+
body: JSON.stringify({
|
|
46
|
+
filter: {
|
|
47
|
+
query: filters.join(' '),
|
|
48
|
+
from: `${config.startDate}T00:00:00Z`,
|
|
49
|
+
to: `${config.endDate}T23:59:59Z`,
|
|
50
|
+
},
|
|
51
|
+
page: {
|
|
52
|
+
limit: 10000, // Datadog max per request
|
|
53
|
+
},
|
|
54
|
+
sort: '-timestamp',
|
|
55
|
+
}),
|
|
56
|
+
});
|
|
57
|
+
if (!response.ok) {
|
|
58
|
+
const error = await response.text();
|
|
59
|
+
throw new Error(`Datadog API error: ${response.status} - ${error}`);
|
|
60
|
+
}
|
|
61
|
+
const data = await response.json();
|
|
62
|
+
// Transform Datadog events to our session format
|
|
63
|
+
const sessions = [];
|
|
64
|
+
const sessionMap = new Map();
|
|
65
|
+
for (const event of data.data || []) {
|
|
66
|
+
const attrs = event.attributes;
|
|
67
|
+
const sessionId = attrs.session?.id;
|
|
68
|
+
if (!sessionId)
|
|
69
|
+
continue;
|
|
70
|
+
// Get or create session entry
|
|
71
|
+
let session = sessionMap.get(sessionId);
|
|
72
|
+
if (!session) {
|
|
73
|
+
session = {
|
|
74
|
+
session_id: sessionId,
|
|
75
|
+
lcp_ms: null,
|
|
76
|
+
inp_ms: null,
|
|
77
|
+
cls: null,
|
|
78
|
+
has_purchase: false,
|
|
79
|
+
purchase_value: 0,
|
|
80
|
+
device: normalizeDevice(attrs.device?.type),
|
|
81
|
+
page_type: extractPageType(attrs.view?.url_path),
|
|
82
|
+
timestamp: attrs['@timestamp'] || attrs.date,
|
|
83
|
+
};
|
|
84
|
+
sessionMap.set(sessionId, session);
|
|
85
|
+
}
|
|
86
|
+
// Update CWV if present (take worst/highest values)
|
|
87
|
+
if (attrs.view?.largest_contentful_paint != null) {
|
|
88
|
+
session.lcp_ms = Math.max(session.lcp_ms || 0, attrs.view.largest_contentful_paint);
|
|
89
|
+
}
|
|
90
|
+
if (attrs.view?.interaction_to_next_paint != null) {
|
|
91
|
+
session.inp_ms = Math.max(session.inp_ms || 0, attrs.view.interaction_to_next_paint);
|
|
92
|
+
}
|
|
93
|
+
if (attrs.view?.cumulative_layout_shift != null) {
|
|
94
|
+
session.cls = Math.max(session.cls || 0, attrs.view.cumulative_layout_shift);
|
|
95
|
+
}
|
|
96
|
+
// Check for purchase action
|
|
97
|
+
if (attrs.action?.type === 'custom' &&
|
|
98
|
+
attrs.action?.name === purchaseAction) {
|
|
99
|
+
session.has_purchase = true;
|
|
100
|
+
session.purchase_value += attrs.action?.custom?.value || 0;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
sessions.push(...sessionMap.values());
|
|
104
|
+
// Calculate metadata
|
|
105
|
+
const sessionsWithLcp = sessions.filter((s) => s.lcp_ms !== null).length;
|
|
106
|
+
const sessionsWithConversions = sessions.filter((s) => s.has_purchase).length;
|
|
107
|
+
const startDate = new Date(config.startDate);
|
|
108
|
+
const endDate = new Date(config.endDate);
|
|
109
|
+
const days = Math.ceil((endDate.getTime() - startDate.getTime()) / (1000 * 60 * 60 * 24)) + 1;
|
|
110
|
+
return {
|
|
111
|
+
sessions,
|
|
112
|
+
metadata: {
|
|
113
|
+
total_sessions: sessions.length,
|
|
114
|
+
sessions_with_lcp: sessionsWithLcp,
|
|
115
|
+
sessions_with_conversions: sessionsWithConversions,
|
|
116
|
+
query_time_ms: Date.now() - startTime,
|
|
117
|
+
period: {
|
|
118
|
+
start: config.startDate,
|
|
119
|
+
end: config.endDate,
|
|
120
|
+
days,
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
// =============================================================================
|
|
126
|
+
// MOCK DATA FOR TESTING
|
|
127
|
+
// =============================================================================
|
|
128
|
+
/**
|
|
129
|
+
* Generate mock session data for testing without Datadog credentials.
|
|
130
|
+
* Models realistic e-commerce conversion patterns.
|
|
131
|
+
*/
|
|
132
|
+
export function generateMockSessions(options) {
|
|
133
|
+
const startTime = Date.now();
|
|
134
|
+
const { count, startDate, endDate, baseConversionRate = 0.03, lcpConversionImpact = 0.85, } = options;
|
|
135
|
+
const sessions = [];
|
|
136
|
+
for (let i = 0; i < count; i++) {
|
|
137
|
+
// Generate realistic LCP distribution (log-normal)
|
|
138
|
+
const lcp = generateLogNormalLcp();
|
|
139
|
+
const inp = generateLogNormalInp();
|
|
140
|
+
const cls = generateCls();
|
|
141
|
+
// Calculate conversion probability based on LCP
|
|
142
|
+
// Empirical model: CVR drops as LCP increases
|
|
143
|
+
const lcpSeconds = lcp / 1000;
|
|
144
|
+
const lcpPenalty = Math.pow(lcpConversionImpact, Math.max(0, lcpSeconds - 1));
|
|
145
|
+
const conversionProbability = baseConversionRate * lcpPenalty;
|
|
146
|
+
const hasPurchase = Math.random() < conversionProbability;
|
|
147
|
+
const purchaseValue = hasPurchase ? generateOrderValue() : 0;
|
|
148
|
+
const device = weightedRandom([
|
|
149
|
+
{ value: 'mobile', weight: 0.65 },
|
|
150
|
+
{ value: 'desktop', weight: 0.30 },
|
|
151
|
+
{ value: 'tablet', weight: 0.05 },
|
|
152
|
+
]);
|
|
153
|
+
const pageType = weightedRandom([
|
|
154
|
+
{ value: 'pdp', weight: 0.40 },
|
|
155
|
+
{ value: 'plp', weight: 0.30 },
|
|
156
|
+
{ value: 'checkout', weight: 0.15 },
|
|
157
|
+
{ value: 'homepage', weight: 0.15 },
|
|
158
|
+
]);
|
|
159
|
+
sessions.push({
|
|
160
|
+
session_id: `mock-${i}-${Date.now()}`,
|
|
161
|
+
lcp_ms: lcp,
|
|
162
|
+
inp_ms: inp,
|
|
163
|
+
cls,
|
|
164
|
+
has_purchase: hasPurchase,
|
|
165
|
+
purchase_value: purchaseValue,
|
|
166
|
+
device,
|
|
167
|
+
page_type: pageType,
|
|
168
|
+
timestamp: generateRandomTimestamp(startDate, endDate),
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
const sessionsWithLcp = sessions.filter((s) => s.lcp_ms !== null).length;
|
|
172
|
+
const sessionsWithConversions = sessions.filter((s) => s.has_purchase).length;
|
|
173
|
+
const start = new Date(startDate);
|
|
174
|
+
const end = new Date(endDate);
|
|
175
|
+
const days = Math.ceil((end.getTime() - start.getTime()) / (1000 * 60 * 60 * 24)) + 1;
|
|
176
|
+
return {
|
|
177
|
+
sessions,
|
|
178
|
+
metadata: {
|
|
179
|
+
total_sessions: sessions.length,
|
|
180
|
+
sessions_with_lcp: sessionsWithLcp,
|
|
181
|
+
sessions_with_conversions: sessionsWithConversions,
|
|
182
|
+
query_time_ms: Date.now() - startTime,
|
|
183
|
+
period: { start: startDate, end: endDate, days },
|
|
184
|
+
},
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
// =============================================================================
|
|
188
|
+
// HELPERS
|
|
189
|
+
// =============================================================================
|
|
190
|
+
function normalizeDevice(type) {
|
|
191
|
+
if (!type)
|
|
192
|
+
return 'desktop';
|
|
193
|
+
const normalized = type.toLowerCase();
|
|
194
|
+
if (normalized.includes('mobile') || normalized.includes('phone'))
|
|
195
|
+
return 'mobile';
|
|
196
|
+
if (normalized.includes('tablet') || normalized.includes('ipad'))
|
|
197
|
+
return 'tablet';
|
|
198
|
+
return 'desktop';
|
|
199
|
+
}
|
|
200
|
+
function extractPageType(urlPath) {
|
|
201
|
+
if (!urlPath)
|
|
202
|
+
return 'unknown';
|
|
203
|
+
const path = urlPath.toLowerCase();
|
|
204
|
+
if (path.includes('/product/') || path.includes('/p/'))
|
|
205
|
+
return 'pdp';
|
|
206
|
+
if (path.includes('/category/') || path.includes('/c/') || path.includes('/shop/'))
|
|
207
|
+
return 'plp';
|
|
208
|
+
if (path.includes('/checkout') || path.includes('/cart'))
|
|
209
|
+
return 'checkout';
|
|
210
|
+
if (path === '/' || path.includes('/home'))
|
|
211
|
+
return 'homepage';
|
|
212
|
+
return 'other';
|
|
213
|
+
}
|
|
214
|
+
function generateLogNormalLcp() {
|
|
215
|
+
// Log-normal distribution centered around 2.5s with variance
|
|
216
|
+
const mu = Math.log(2500);
|
|
217
|
+
const sigma = 0.5;
|
|
218
|
+
const u1 = Math.random();
|
|
219
|
+
const u2 = Math.random();
|
|
220
|
+
const z = Math.sqrt(-2 * Math.log(u1)) * Math.cos(2 * Math.PI * u2);
|
|
221
|
+
return Math.round(Math.exp(mu + sigma * z));
|
|
222
|
+
}
|
|
223
|
+
function generateLogNormalInp() {
|
|
224
|
+
// INP centered around 150ms
|
|
225
|
+
const mu = Math.log(150);
|
|
226
|
+
const sigma = 0.6;
|
|
227
|
+
const u1 = Math.random();
|
|
228
|
+
const u2 = Math.random();
|
|
229
|
+
const z = Math.sqrt(-2 * Math.log(u1)) * Math.cos(2 * Math.PI * u2);
|
|
230
|
+
return Math.round(Math.exp(mu + sigma * z));
|
|
231
|
+
}
|
|
232
|
+
function generateCls() {
|
|
233
|
+
// CLS: most are low, some are high
|
|
234
|
+
const base = Math.random() * 0.1;
|
|
235
|
+
const spike = Math.random() < 0.1 ? Math.random() * 0.3 : 0;
|
|
236
|
+
return Math.round((base + spike) * 1000) / 1000;
|
|
237
|
+
}
|
|
238
|
+
function generateOrderValue() {
|
|
239
|
+
// Typical e-commerce AOV distribution
|
|
240
|
+
const base = 50 + Math.random() * 100;
|
|
241
|
+
const highValue = Math.random() < 0.1 ? Math.random() * 300 : 0;
|
|
242
|
+
return Math.round((base + highValue) * 100) / 100;
|
|
243
|
+
}
|
|
244
|
+
function weightedRandom(options) {
|
|
245
|
+
const total = options.reduce((sum, opt) => sum + opt.weight, 0);
|
|
246
|
+
let random = Math.random() * total;
|
|
247
|
+
for (const opt of options) {
|
|
248
|
+
random -= opt.weight;
|
|
249
|
+
if (random <= 0)
|
|
250
|
+
return opt.value;
|
|
251
|
+
}
|
|
252
|
+
return options[0].value;
|
|
253
|
+
}
|
|
254
|
+
function generateRandomTimestamp(start, end) {
|
|
255
|
+
const startMs = new Date(start).getTime();
|
|
256
|
+
const endMs = new Date(end).getTime();
|
|
257
|
+
const randomMs = startMs + Math.random() * (endMs - startMs);
|
|
258
|
+
return new Date(randomMs).toISOString();
|
|
259
|
+
}
|
|
260
|
+
//# sourceMappingURL=datadog-session-query.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"datadog-session-query.js","sourceRoot":"","sources":["../../src/empirical/datadog-session-query.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Empirical Performance Revenue Engine
|
|
4
|
+
*
|
|
5
|
+
* A simpler, more transparent approach to performance-revenue analysis.
|
|
6
|
+
* Uses actual session-level data to build empirical conversion curves.
|
|
7
|
+
*
|
|
8
|
+
* Key differences from coefficient-based models:
|
|
9
|
+
* - No assumed "0.5% CVR per 100ms LCP" coefficients
|
|
10
|
+
* - Measures actual CVR at each performance bucket from YOUR data
|
|
11
|
+
* - More honest about what we know vs. assume
|
|
12
|
+
*
|
|
13
|
+
* Usage:
|
|
14
|
+
* // With Datadog credentials
|
|
15
|
+
* const result = await analyzeWithDatadog({
|
|
16
|
+
* apiKey: 'xxx',
|
|
17
|
+
* appKey: 'xxx',
|
|
18
|
+
* startDate: '2024-01-01',
|
|
19
|
+
* endDate: '2024-01-14',
|
|
20
|
+
* });
|
|
21
|
+
*
|
|
22
|
+
* // With mock data (for testing)
|
|
23
|
+
* const result = analyzeWithMockData({
|
|
24
|
+
* sessionCount: 50000,
|
|
25
|
+
* startDate: '2024-01-01',
|
|
26
|
+
* endDate: '2024-01-14',
|
|
27
|
+
* });
|
|
28
|
+
*
|
|
29
|
+
* @author Kanmi Obasa <i@kanmiobasa.com>
|
|
30
|
+
*/
|
|
31
|
+
import { type DatadogQueryConfig } from './datadog-session-query.js';
|
|
32
|
+
import { type ConversionCurve } from './conversion-curve.js';
|
|
33
|
+
import { type OpportunityReport } from './opportunity-calculator.js';
|
|
34
|
+
export interface AnalysisResult {
|
|
35
|
+
/** Empirical conversion curves */
|
|
36
|
+
curves: {
|
|
37
|
+
lcp: ConversionCurve;
|
|
38
|
+
inp: ConversionCurve;
|
|
39
|
+
cls: ConversionCurve;
|
|
40
|
+
};
|
|
41
|
+
/** Revenue opportunity analysis */
|
|
42
|
+
opportunities: {
|
|
43
|
+
lcp: OpportunityReport;
|
|
44
|
+
inp: OpportunityReport;
|
|
45
|
+
cls: OpportunityReport;
|
|
46
|
+
};
|
|
47
|
+
/** The single highest-impact opportunity */
|
|
48
|
+
topOpportunity: {
|
|
49
|
+
metric: 'lcp' | 'inp' | 'cls';
|
|
50
|
+
monthlyRevenue: number;
|
|
51
|
+
summary: string;
|
|
52
|
+
} | null;
|
|
53
|
+
/** Generated markdown report */
|
|
54
|
+
report: string;
|
|
55
|
+
/** Query metadata */
|
|
56
|
+
metadata: {
|
|
57
|
+
totalSessions: number;
|
|
58
|
+
sessionsWithLcp: number;
|
|
59
|
+
sessionsWithConversions: number;
|
|
60
|
+
period: {
|
|
61
|
+
start: string;
|
|
62
|
+
end: string;
|
|
63
|
+
days: number;
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
export interface DatadogAnalysisOptions extends DatadogQueryConfig {
|
|
68
|
+
clientName?: string;
|
|
69
|
+
}
|
|
70
|
+
export interface MockAnalysisOptions {
|
|
71
|
+
sessionCount: number;
|
|
72
|
+
startDate: string;
|
|
73
|
+
endDate: string;
|
|
74
|
+
clientName?: string;
|
|
75
|
+
baseConversionRate?: number;
|
|
76
|
+
}
|
|
77
|
+
export interface FileAnalysisOptions {
|
|
78
|
+
filePath: string;
|
|
79
|
+
clientName?: string;
|
|
80
|
+
startDate?: string;
|
|
81
|
+
endDate?: string;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Run full analysis using Datadog RUM data.
|
|
85
|
+
*/
|
|
86
|
+
export declare function analyzeWithDatadog(options: DatadogAnalysisOptions): Promise<AnalysisResult>;
|
|
87
|
+
/**
|
|
88
|
+
* Run analysis with mock data (for testing/demo).
|
|
89
|
+
*/
|
|
90
|
+
export declare function analyzeWithMockData(options: MockAnalysisOptions): AnalysisResult;
|
|
91
|
+
/**
|
|
92
|
+
* Run analysis from CSV or JSON file.
|
|
93
|
+
* Bring your own data from any source.
|
|
94
|
+
*/
|
|
95
|
+
export declare function analyzeFromFile(options: FileAnalysisOptions): AnalysisResult;
|
|
96
|
+
/**
|
|
97
|
+
* CLI entry point.
|
|
98
|
+
*/
|
|
99
|
+
export declare function main(): Promise<void>;
|
|
100
|
+
export type { SessionData, DatadogQueryConfig, QueryResult } from './datadog-session-query.js';
|
|
101
|
+
export type { ConversionCurve, ConversionBucket, CurveBuilderConfig } from './conversion-curve.js';
|
|
102
|
+
export type { OpportunityReport, OpportunityScenario, OpportunityConfig } from './opportunity-calculator.js';
|
|
103
|
+
export type { ReportConfig, FullReport } from './report.js';
|
|
104
|
+
export { queryDatadogSessions, generateMockSessions } from './datadog-session-query.js';
|
|
105
|
+
export { buildConversionCurve, buildAllCurves, buildSegmentedCurves } from './conversion-curve.js';
|
|
106
|
+
export { calculateOpportunity, calculateAllOpportunities, getTopOpportunity } from './opportunity-calculator.js';
|
|
107
|
+
export { generateReport } from './report.js';
|
|
108
|
+
export { importFromFile, importFromCsv, importFromJson } from './data-import.js';
|
|
109
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/empirical/index.ts"],"names":[],"mappings":"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"}
|