Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .Jules/engine.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,9 @@
- **Edge Memory & GC Allocation:** Hoisted static regular expression literal patterns in `src/utils/chat-explore.ts` to module scope constants (`SUPPRESS_PATTERN`, `LINKEDIN_PATTERN`, `DESIGN_SYSTEM_PATTERN`, `COPILOTS_PATTERN`, `ANALYTICS_PATTERN`, `THESIS_PATTERN`, `BIOGRAPHY_PATTERN`, `CASES_PATTERN`, `WORK_PATTERN`).
- **Performance:** Eliminates dynamic `RegExp` compilation and dynamic string allocations on every avatar chat message question query in Cloudflare Workers edge runtimes.
- **Verification:** Added unit test coverage in `src/utils/chat-explore.test.ts` for suppression logic, keyword variations, edge cases, and empty strings. All tests pass cleanly.

## 2025-06-25 - O(1) Column Map Indexing for Visit Statistics Dataset Parsing

- **Performance & Edge Memory:** Refactored `parseVisitGlance` in `src/utils/visit-stats.ts` to pre-construct an $O(1)$ `Map<string, number>` from payload column name arrays using a single-pass index loop, eliminating linear `Array.prototype.indexOf` searches and `.filter()` array allocations on every row field evaluation.
- **Data Parsing:** Refactored `valueFromRow` helper to use constant-time `columnMap.get(key)` lookups.
- **Verification:** Expanded Vitest unit tests in `src/utils/visit-stats.test.ts` covering custom reordered column maps, array-structured payloads, and period growth computations.
21 changes: 21 additions & 0 deletions src/utils/visit-stats.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,27 @@ describe('parseVisitGlance', () => {
expect(glance?.pageviews).toBe(100);
expect(glance?.uniqueVisitors).toBe(15);
});

it('correctly maps custom reordered columns via O(1) columnMap', () => {
const glance = parseVisitGlance({
columns: [
'unique_visitors_7d',
'pageviews_7d',
'first_seen',
'unique_visitors',
'pageviews',
'unique_visitors_1d',
'unique_visitors_1d_prev',
],
results: [[8, 20, '2026-08-14T07:03:00.000Z', 12, 94, 10, 8]],
});
expect(glance?.pageviews).toBe(94);
expect(glance?.uniqueVisitors).toBe(12);
expect(glance?.firstSeen).toBe('2026-08-14T07:03:00.000Z');
expect(glance?.pageviews7d).toBe(20);
expect(glance?.uniqueVisitors7d).toBe(8);
expect(glance?.uniqueVisitorsDoD).toBe(25);
});
});

describe('formatFirstSeen', () => {
Expand Down
52 changes: 31 additions & 21 deletions src/utils/visit-stats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,16 @@ function asIsoTimestamp(raw: unknown): string | null {

function valueFromRow(
row: unknown,
columns: string[] | undefined,
columnMap: Map<string, number> | undefined,
key: string,
index: number
): unknown {
if (row && typeof row === 'object' && !Array.isArray(row) && key in row) {
return (row as Record<string, unknown>)[key];
}
if (Array.isArray(row) && columns) {
const colIndex = columns.indexOf(key);
if (colIndex >= 0) return row[colIndex];
if (Array.isArray(row) && columnMap) {
const colIndex = columnMap.get(key);
if (colIndex !== undefined) return row[colIndex];
}
if (Array.isArray(row)) return row[index];
return undefined;
Expand All @@ -70,32 +70,42 @@ function percentChange(current: number | null, previous: number | null): number
return Number.isFinite(pct) ? pct : null;
}

/**
* Parses raw PostHog or API visit stats into a VisitGlance structure.
* Optimization (⚙️ Engine): Pre-constructs an O(1) columnMap once per payload to convert linear Array.indexOf
* searches per row field into constant-time Map lookups when parsing array-structured dataset results.
*/
export function parseVisitGlance(payload: unknown): VisitGlance | null {
if (!payload || typeof payload !== 'object') return null;
const results = (payload as { results?: unknown }).results;
if (!Array.isArray(results) || results.length === 0) return null;

const columns = (payload as { columns?: unknown }).columns;
const columnNames = Array.isArray(columns)
? columns.filter((c): c is string => typeof c === 'string')
: undefined;
let columnMap: Map<string, number> | undefined;
if (Array.isArray(columns)) {
columnMap = new Map();
for (let i = 0; i < columns.length; i++) {
const col = columns[i];
if (typeof col === 'string') {
columnMap.set(col, i);
}
}
}

const row = results[0];
const pageviews = asFiniteNumber(valueFromRow(row, columnNames, 'pageviews', 0));
const uniqueVisitors = asFiniteNumber(valueFromRow(row, columnNames, 'unique_visitors', 1));
const firstSeen = asIsoTimestamp(valueFromRow(row, columnNames, 'first_seen', 2));
const pageviews7d = asFiniteNumber(valueFromRow(row, columnNames, 'pageviews_7d', 3));
const uniqueVisitors7d = asFiniteNumber(valueFromRow(row, columnNames, 'unique_visitors_7d', 4));
const unique1d = asFiniteNumber(valueFromRow(row, columnNames, 'unique_visitors_1d', 5));
const unique1dPrev = asFiniteNumber(valueFromRow(row, columnNames, 'unique_visitors_1d_prev', 6));
const unique7dPrev = asFiniteNumber(valueFromRow(row, columnNames, 'unique_visitors_7d_prev', 7));
const unique30d = asFiniteNumber(valueFromRow(row, columnNames, 'unique_visitors_30d', 8));
const unique30dPrev = asFiniteNumber(
valueFromRow(row, columnNames, 'unique_visitors_30d_prev', 9)
);
const unique365d = asFiniteNumber(valueFromRow(row, columnNames, 'unique_visitors_365d', 10));
const pageviews = asFiniteNumber(valueFromRow(row, columnMap, 'pageviews', 0));
const uniqueVisitors = asFiniteNumber(valueFromRow(row, columnMap, 'unique_visitors', 1));
const firstSeen = asIsoTimestamp(valueFromRow(row, columnMap, 'first_seen', 2));
const pageviews7d = asFiniteNumber(valueFromRow(row, columnMap, 'pageviews_7d', 3));
const uniqueVisitors7d = asFiniteNumber(valueFromRow(row, columnMap, 'unique_visitors_7d', 4));
const unique1d = asFiniteNumber(valueFromRow(row, columnMap, 'unique_visitors_1d', 5));
const unique1dPrev = asFiniteNumber(valueFromRow(row, columnMap, 'unique_visitors_1d_prev', 6));
const unique7dPrev = asFiniteNumber(valueFromRow(row, columnMap, 'unique_visitors_7d_prev', 7));
const unique30d = asFiniteNumber(valueFromRow(row, columnMap, 'unique_visitors_30d', 8));
const unique30dPrev = asFiniteNumber(valueFromRow(row, columnMap, 'unique_visitors_30d_prev', 9));
const unique365d = asFiniteNumber(valueFromRow(row, columnMap, 'unique_visitors_365d', 10));
const unique365dPrev = asFiniteNumber(
valueFromRow(row, columnNames, 'unique_visitors_365d_prev', 11)
valueFromRow(row, columnMap, 'unique_visitors_365d_prev', 11)
);

if (
Expand Down
Loading