vite-plugin-smart-prefetch 0.3.4 → 0.3.6

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/dist/index.cjs CHANGED
@@ -30,6 +30,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/index.ts
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
+ BigQueryAnalyticsConnector: () => BigQueryAnalyticsConnector,
33
34
  smartPrefetch: () => smartPrefetch
34
35
  });
35
36
  module.exports = __toCommonJS(index_exports);
@@ -42,7 +43,7 @@ var BigQueryAnalyticsConnector = class {
42
43
  constructor(projectId, datasetId, location = "asia-south1", debug = false) {
43
44
  this.projectId = projectId;
44
45
  this.datasetId = datasetId;
45
- this.location = location;
46
+ this.location = location && location !== "asia" ? location : "asia-south1";
46
47
  this.debug = debug;
47
48
  this.bigquery = new import_bigquery.BigQuery({
48
49
  projectId
@@ -51,7 +52,8 @@ var BigQueryAnalyticsConnector = class {
51
52
  console.log("\u2705 BigQuery Analytics connector initialized");
52
53
  console.log(` Project ID: ${projectId}`);
53
54
  console.log(` Dataset ID: ${datasetId}`);
54
- console.log(` Location: ${location}`);
55
+ console.log(` Location: ${this.location}`);
56
+ console.log(` Querying daily events tables: ${projectId}.${datasetId}.events_*`);
55
57
  }
56
58
  }
57
59
  /**
@@ -61,20 +63,27 @@ var BigQueryAnalyticsConnector = class {
61
63
  async fetchNavigationSequences(config = {}) {
62
64
  const { days = 30 } = config;
63
65
  const minSessions = 1;
64
- console.log(`\u{1F4CA} Fetching navigation data from BigQuery...`);
65
- console.log(` Dataset: ${this.datasetId}`);
66
+ console.log(`
67
+ ${"\u2550".repeat(60)}`);
68
+ console.log(`\u{1F4CA} STAGE 1: PREPARING BIGQUERY QUERY`);
69
+ console.log(`${"\u2550".repeat(60)}`);
70
+ console.log(` Project ID: ${this.projectId}`);
71
+ console.log(` Dataset ID: ${this.datasetId}`);
72
+ console.log(` Location: ${this.location}`);
66
73
  console.log(` Date range: Last ${days} days`);
74
+ console.log(` Daily tables pattern: events_*`);
75
+ console.log(` Event type filter: page_view`);
76
+ console.log(` Expected fields: user_pseudo_id, ga_session_id, page_path`);
67
77
  try {
68
78
  const query = `
69
79
  WITH page_sessions AS (
70
80
  SELECT
71
- user_id,
81
+ user_pseudo_id,
72
82
  (SELECT value.int_value FROM UNNEST(event_params) WHERE KEY = 'ga_session_id' LIMIT 1) as session_id,
73
- (SELECT value.string_value FROM UNNEST(event_params) WHERE KEY = 'page_location' LIMIT 1) as page_location,
74
83
  (SELECT value.string_value FROM UNNEST(event_params) WHERE KEY = 'page_path' LIMIT 1) as page_path,
75
84
  event_timestamp,
76
85
  ROW_NUMBER() OVER (
77
- PARTITION BY user_id, (SELECT value.int_value FROM UNNEST(event_params) WHERE KEY = 'ga_session_id' LIMIT 1)
86
+ PARTITION BY user_pseudo_id, (SELECT value.int_value FROM UNNEST(event_params) WHERE KEY = 'ga_session_id' LIMIT 1)
78
87
  ORDER BY event_timestamp
79
88
  ) as page_sequence
80
89
  FROM \`${this.projectId}.${this.datasetId}.events_*\`
@@ -88,7 +97,7 @@ var BigQueryAnalyticsConnector = class {
88
97
  SELECT
89
98
  COALESCE(curr.page_path, '(direct)') as from_page,
90
99
  LEAD(curr.page_path) OVER (
91
- PARTITION BY curr.user_id, curr.session_id
100
+ PARTITION BY curr.user_pseudo_id, curr.session_id
92
101
  ORDER BY curr.page_sequence
93
102
  ) as to_page
94
103
  FROM page_sessions curr
@@ -100,52 +109,132 @@ var BigQueryAnalyticsConnector = class {
100
109
  COUNT(*) as transition_count
101
110
  FROM transitions
102
111
  WHERE to_page IS NOT NULL
103
- GROUP BY from_page, to_page
112
+ GROUP BY previous_page_path, page_path
104
113
  ORDER BY transition_count DESC
105
114
  LIMIT 10000
106
115
  `;
107
116
  if (this.debug) {
108
- console.log(`\u{1F4E4} BigQuery Query:`);
117
+ console.log(`
118
+ \u{1F4E4} Full BigQuery Query:`);
119
+ console.log(`${"\u2500".repeat(60)}`);
109
120
  console.log(query);
121
+ console.log(`${"\u2500".repeat(60)}`);
110
122
  }
123
+ console.log(`
124
+ ${"\u2550".repeat(60)}`);
125
+ console.log(`\u{1F4CA} STAGE 2: EXECUTING QUERY`);
126
+ console.log(`${"\u2550".repeat(60)}`);
127
+ console.log(` \u23F3 Querying BigQuery...`);
111
128
  const [rows] = await this.bigquery.query({
112
129
  query,
113
130
  location: this.location
114
131
  });
115
- if (this.debug) {
116
- console.log(`\u2705 Query executed successfully`);
117
- console.log(` Rows returned: ${rows.length}`);
132
+ console.log(` \u2705 Query executed successfully`);
133
+ console.log(` \u{1F4C8} Total transitions returned: ${rows.length}`);
134
+ if (rows.length === 0) {
135
+ console.log(`
136
+ ${"\u2550".repeat(60)}`);
137
+ console.log(`\u26A0\uFE0F STAGE 2: NO DATA RETURNED!`);
138
+ console.log(`${"\u2550".repeat(60)}`);
139
+ console.log(` \u274C BigQuery returned 0 rows`);
140
+ console.log(`
141
+ Possible causes:`);
142
+ console.log(` 1. No event tables in date range (events_YYYYMMDD)`);
143
+ console.log(` 2. No page_view events in those tables`);
144
+ console.log(` 3. page_path parameter not being tracked`);
145
+ console.log(` 4. Wrong location (currently: ${this.location})`);
146
+ console.log(` 5. Wrong dataset name: ${this.datasetId}`);
147
+ console.log(`
148
+ Troubleshooting:`);
149
+ console.log(` \u2022 Check BigQuery console for available event tables`);
150
+ console.log(` \u2022 Verify GA4 property is exporting to BigQuery`);
151
+ console.log(` \u2022 Confirm page_path is being captured in GA4`);
152
+ console.log(`${"\u2550".repeat(60)}
153
+ `);
154
+ return [];
118
155
  }
156
+ console.log(`
157
+ ${"\u2550".repeat(60)}`);
158
+ console.log(`\u{1F4CA} STAGE 3: PROCESSING RAW DATA`);
159
+ console.log(`${"\u2550".repeat(60)}`);
160
+ console.log(` Processing ${rows.length} raw transitions...`);
119
161
  const navigationData = [];
162
+ let processedCount = 0;
163
+ let filteredCount = 0;
164
+ let emptyPathCount = 0;
165
+ let lowCountCount = 0;
120
166
  const rawData = rows.map((row) => ({
121
167
  previous_page_path: row.previous_page_path,
122
168
  page_path: row.page_path,
123
169
  transition_count: row.transition_count
124
170
  }));
125
- rows.forEach((row) => {
171
+ console.log(`
172
+ ${"\u2500".repeat(56)}`);
173
+ console.log(` Processing each transition row...`);
174
+ console.log(` ${"\u2500".repeat(56)}`);
175
+ rows.forEach((row, index) => {
126
176
  const previousPage = row.previous_page_path || "(direct)";
127
177
  const currentPage = row.page_path || "";
128
178
  const transitionCount = parseInt(row.transition_count || "0");
179
+ if (this.debug && index < 5) {
180
+ console.log(`
181
+ Row ${index + 1}:`);
182
+ console.log(` Raw: "${previousPage}" \u2192 "${currentPage}" (count: ${transitionCount})`);
183
+ }
129
184
  const normalizedPrevious = previousPage === "(direct)" || previousPage === "(not set)" ? "(direct)" : this.normalizeRoute(previousPage);
130
185
  const normalizedCurrent = this.normalizeRoute(currentPage);
186
+ if (this.debug && index < 5) {
187
+ console.log(` Normalized: "${normalizedPrevious}" \u2192 "${normalizedCurrent}"`);
188
+ }
131
189
  if (normalizedCurrent && transitionCount >= minSessions) {
132
190
  navigationData.push({
133
191
  from: normalizedPrevious,
134
192
  to: normalizedCurrent,
135
193
  count: transitionCount
136
194
  });
195
+ processedCount++;
196
+ if (this.debug && index < 5) {
197
+ console.log(` \u2705 ACCEPTED`);
198
+ }
199
+ } else {
200
+ filteredCount++;
201
+ if (!normalizedCurrent) {
202
+ emptyPathCount++;
203
+ if (this.debug && index < 5) {
204
+ console.log(` \u274C FILTERED: normalized to empty path (likely build artifact)`);
205
+ }
206
+ } else if (transitionCount < minSessions) {
207
+ lowCountCount++;
208
+ if (this.debug && index < 5) {
209
+ console.log(` \u274C FILTERED: transition count ${transitionCount} < minSessions ${minSessions}`);
210
+ }
211
+ }
137
212
  }
138
213
  });
214
+ console.log(`
215
+ ${"\u2500".repeat(56)}`);
216
+ console.log(` Processing Summary:`);
217
+ console.log(` \u2705 Accepted: ${processedCount}`);
218
+ console.log(` \u274C Filtered out: ${filteredCount}`);
219
+ console.log(` \u2022 Empty paths: ${emptyPathCount}`);
220
+ console.log(` \u2022 Low transition count: ${lowCountCount}`);
139
221
  this.saveDataForInspection(rawData, navigationData);
140
- if (this.debug) {
141
- console.log(`\u2705 Processed ${navigationData.length} navigation transitions`);
142
- if (navigationData.length > 0) {
143
- console.log(`
222
+ console.log(`
223
+ ${"\u2550".repeat(60)}`);
224
+ console.log(`\u{1F4CA} STAGE 4: FINAL RESULTS`);
225
+ console.log(`${"\u2550".repeat(60)}`);
226
+ console.log(` Total valid transitions: ${navigationData.length}`);
227
+ if (navigationData.length === 0) {
228
+ console.log(`
229
+ \u26A0\uFE0F WARNING: All transitions were filtered out!`);
230
+ console.log(` Check the logs above to see why rows were rejected.`);
231
+ console.log(` Raw data saved to: .bigquery-raw-data/raw-bigquery-response.json`);
232
+ } else {
233
+ console.log(`
144
234
  Top 5 transitions:`);
145
- navigationData.slice(0, 5).forEach((nav, i) => {
146
- console.log(` ${i + 1}. ${nav.from} \u2192 ${nav.to} (${nav.count} transitions)`);
147
- });
148
- }
235
+ navigationData.slice(0, 5).forEach((nav, i) => {
236
+ console.log(` ${i + 1}. ${nav.from} \u2192 ${nav.to} (${nav.count})`);
237
+ });
149
238
  const uniqueRoutes = /* @__PURE__ */ new Set();
150
239
  navigationData.forEach((nav) => {
151
240
  if (nav.from !== "(direct)") uniqueRoutes.add(nav.from);
@@ -155,85 +244,45 @@ var BigQueryAnalyticsConnector = class {
155
244
  \u{1F4CA} Unique routes: ${uniqueRoutes.size}`);
156
245
  console.log(` Routes: ${Array.from(uniqueRoutes).sort().join(", ")}`);
157
246
  console.log(`
158
- \u{1F4C1} Raw data saved to: .bigquery-raw-data/`);
247
+ \u{1F4C1} Data inspection files created:`);
248
+ console.log(` \u2022 .bigquery-raw-data/raw-bigquery-response.json`);
249
+ console.log(` \u2022 .bigquery-raw-data/processed-navigation-data.json`);
250
+ console.log(` \u2022 .bigquery-raw-data/data-transformation-summary.json`);
159
251
  }
252
+ console.log(`${"\u2550".repeat(60)}
253
+ `);
160
254
  return navigationData;
161
255
  } catch (error) {
162
- const errorMessage = error instanceof Error ? error.message : "Unknown error";
256
+ const errorMessage = error instanceof Error ? error.message : String(error) || "Unknown error";
257
+ console.log(`
258
+ ${"\u2550".repeat(60)}`);
259
+ console.log(`\u274C ERROR: QUERY EXECUTION FAILED`);
260
+ console.log(`${"\u2550".repeat(60)}`);
163
261
  if (errorMessage.includes("bigquery.jobs.create") || errorMessage.includes("PERMISSION_DENIED")) {
164
- console.error("\u274C Failed to fetch BigQuery data: Permission Denied");
165
- console.error(" Service account needs BigQuery Job User role in the project");
166
- console.error(" Error details:", errorMessage);
262
+ console.error(` \u274C Permission Denied`);
263
+ console.error(` Service account needs BigQuery Job User role in project: ${this.projectId}`);
264
+ console.error(` Error: ${errorMessage}`);
265
+ } else if (errorMessage.includes("was not found")) {
266
+ console.error(` \u274C Dataset not found`);
267
+ console.error(` Cannot find dataset: ${this.projectId}.${this.datasetId}`);
268
+ console.error(` Try a different location or check dataset name`);
269
+ console.error(` Current location: ${this.location}`);
270
+ console.error(` Error: ${errorMessage}`);
167
271
  } else {
168
- console.error("\u274C Failed to fetch BigQuery data:", error);
272
+ const errorType = error instanceof Error ? error.constructor.name : "Unknown";
273
+ console.error(` Error type: ${errorType}`);
274
+ console.error(` Message: ${errorMessage}`);
169
275
  }
276
+ console.log(`${"\u2550".repeat(60)}
277
+ `);
170
278
  throw new Error(
171
279
  `BigQuery Analytics error: ${errorMessage}`
172
280
  );
173
281
  }
174
282
  }
175
- /**
176
- * Map friendly page names (with spaces/capitals) back to route paths
177
- * GA4 may log display names instead of URL paths
178
- * Examples: "Audit Logs" → "/audit-logs", "API Documentation" → "/api-docs", "Home" → "/"
179
- */
180
- friendlyNameToRoute(name) {
181
- const friendlyToRoute = {
182
- // Exact matches (with spaces and capitals)
183
- "API Documentation": "/api-docs",
184
- "Audit Logs": "/audit-logs",
185
- "/Home": "/",
186
- "/home": "/",
187
- "Home": "/",
188
- "/Dashboard": "/dashboard",
189
- "Dashboard": "/dashboard",
190
- // PascalCase variants (all 27 routes)
191
- "Profile": "/profile",
192
- "Settings": "/settings",
193
- "Preferences": "/preferences",
194
- "Privacy": "/privacy",
195
- "Security": "/security",
196
- "Analytics": "/analytics",
197
- "Reports": "/reports",
198
- "Metrics": "/metrics",
199
- "Projects": "/projects",
200
- "Tasks": "/tasks",
201
- "Teams": "/teams",
202
- "Workspaces": "/workspaces",
203
- "Workflows": "/workflows",
204
- "Templates": "/templates",
205
- "Logs": "/logs",
206
- "AuditLogs": "/audit-logs",
207
- "Integrations": "/integrations",
208
- "ApiDocs": "/api-docs",
209
- "Support": "/support",
210
- "Help": "/help",
211
- "Billing": "/billing",
212
- "Plans": "/plans",
213
- "Usage": "/usage",
214
- "Permissions": "/permissions",
215
- "Notifications": "/notifications"
216
- };
217
- if (friendlyToRoute[name]) {
218
- return friendlyToRoute[name];
219
- }
220
- const lowerName = name.toLowerCase();
221
- for (const [key, value] of Object.entries(friendlyToRoute)) {
222
- if (key.toLowerCase() === lowerName) {
223
- return value;
224
- }
225
- }
226
- if (name.startsWith("/")) {
227
- if (name === "/") {
228
- return "/";
229
- }
230
- return name.toLowerCase();
231
- }
232
- return "/" + lowerName;
233
- }
234
283
  /**
235
284
  * Normalize route paths
236
- * Converts dynamic segments to parameters and friendly names to route paths
285
+ * Converts dynamic segments to parameters and standardizes format
237
286
  */
238
287
  normalizeRoute(path2) {
239
288
  const buildArtifacts = [
@@ -247,7 +296,7 @@ var BigQueryAnalyticsConnector = class {
247
296
  if (buildArtifacts.some((pattern) => pattern.test(path2))) {
248
297
  return "";
249
298
  }
250
- let normalized = this.friendlyNameToRoute(path2);
299
+ let normalized = path2;
251
300
  normalized = normalized.split("?")[0].split("#")[0];
252
301
  if (normalized.length > 1 && normalized.endsWith("/")) {
253
302
  normalized = normalized.slice(0, -1);
@@ -304,28 +353,49 @@ var BigQueryAnalyticsConnector = class {
304
353
  }
305
354
  }
306
355
  /**
307
- * Fetch navigation data WITH segment information
308
- * Includes segment/role field so plugin can group by any role dynamically
309
- * @param config - Data range configuration
310
- * @returns Navigation data with segment field included
356
+ * Fetch navigation data WITH optional segment information
357
+ * Only includes segment/grouping field when explicitly requested
358
+ * @param config - Data range configuration with optional segmentField
359
+ * @returns Navigation data, optionally with segment field included
311
360
  */
312
361
  async fetchNavigationWithSegments(config = {}) {
313
- const { days = 30 } = config;
314
- console.log(`\u{1F4CA} Fetching navigation data with segments from BigQuery...`);
315
- console.log(` Dataset: ${this.datasetId}`);
362
+ const { days = 30, segmentField } = config;
363
+ if (!segmentField) {
364
+ console.log(`
365
+ ${"\u2550".repeat(60)}`);
366
+ console.log(`\u{1F4CA} STAGE 1: PREPARING BIGQUERY QUERY (SEGMENTED)`);
367
+ console.log(`${"\u2550".repeat(60)}`);
368
+ console.log(` \u26A0\uFE0F No segment field specified`);
369
+ console.log(` Falling back to fetchNavigationSequences (base data only)`);
370
+ console.log(` To include segments, pass: { segmentField: 'field_name' }`);
371
+ console.log(`${"\u2550".repeat(60)}
372
+ `);
373
+ return this.fetchNavigationSequences(config);
374
+ }
375
+ console.log(`
376
+ ${"\u2550".repeat(60)}`);
377
+ console.log(`\u{1F4CA} STAGE 1: PREPARING SEGMENTED BIGQUERY QUERY`);
378
+ console.log(`${"\u2550".repeat(60)}`);
379
+ console.log(` Project ID: ${this.projectId}`);
380
+ console.log(` Dataset ID: ${this.datasetId}`);
381
+ console.log(` Location: ${this.location}`);
316
382
  console.log(` Date range: Last ${days} days`);
383
+ console.log(` Daily tables pattern: events_*`);
384
+ console.log(` Event type filter: page_view`);
385
+ console.log(` Segment field: ${segmentField}`);
386
+ console.log(` Expected fields: user_pseudo_id, ga_session_id, page_path, ${segmentField}`);
317
387
  try {
388
+ const segmentParam = `(SELECT value.string_value FROM UNNEST(event_params) WHERE KEY = '${segmentField}' LIMIT 1) as segment_value`;
318
389
  const query = `
319
390
  WITH page_sessions AS (
320
391
  SELECT
321
- user_id,
392
+ user_pseudo_id,
322
393
  (SELECT value.int_value FROM UNNEST(event_params) WHERE KEY = 'ga_session_id' LIMIT 1) as session_id,
323
394
  (SELECT value.string_value FROM UNNEST(event_params) WHERE KEY = 'page_path' LIMIT 1) as page_path,
324
- (SELECT value.string_value FROM UNNEST(event_params) WHERE KEY = 'user_role' LIMIT 1) as user_role,
325
- (SELECT value.string_value FROM UNNEST(event_params) WHERE KEY = 'user_segment' LIMIT 1) as user_segment,
395
+ ${segmentParam},
326
396
  event_timestamp,
327
397
  ROW_NUMBER() OVER (
328
- PARTITION BY user_id, (SELECT value.int_value FROM UNNEST(event_params) WHERE KEY = 'ga_session_id' LIMIT 1)
398
+ PARTITION BY user_pseudo_id, (SELECT value.int_value FROM UNNEST(event_params) WHERE KEY = 'ga_session_id' LIMIT 1)
329
399
  ORDER BY event_timestamp
330
400
  ) as page_sequence
331
401
  FROM \`${this.projectId}.${this.datasetId}.events_*\`
@@ -339,10 +409,10 @@ var BigQueryAnalyticsConnector = class {
339
409
  SELECT
340
410
  COALESCE(curr.page_path, '(direct)') as from_page,
341
411
  LEAD(curr.page_path) OVER (
342
- PARTITION BY curr.user_id, curr.session_id
412
+ PARTITION BY curr.user_pseudo_id, curr.session_id
343
413
  ORDER BY curr.page_sequence
344
414
  ) as to_page,
345
- COALESCE(curr.user_role, curr.user_segment, 'unknown') as segment
415
+ COALESCE(curr.segment_value, 'unknown') as segment
346
416
  FROM page_sessions curr
347
417
  WHERE curr.page_sequence > 0
348
418
  )
@@ -353,45 +423,104 @@ var BigQueryAnalyticsConnector = class {
353
423
  COUNT(*) as transition_count
354
424
  FROM transitions
355
425
  WHERE to_page IS NOT NULL
356
- GROUP BY from_page, to_page, segment
426
+ GROUP BY previous_page_path, page_path, segment
357
427
  ORDER BY segment, transition_count DESC
358
428
  LIMIT 50000
359
429
  `;
360
430
  if (this.debug) {
361
- console.log(`\u{1F4E4} Query with segments:`);
431
+ console.log(`
432
+ \u{1F4E4} Full Query with segment field (${segmentField}):`);
433
+ console.log(`${"\u2500".repeat(60)}`);
362
434
  console.log(query);
435
+ console.log(`${"\u2500".repeat(60)}`);
363
436
  }
437
+ console.log(`
438
+ ${"\u2550".repeat(60)}`);
439
+ console.log(`\u{1F4CA} STAGE 2: EXECUTING QUERY`);
440
+ console.log(`${"\u2550".repeat(60)}`);
441
+ console.log(` \u23F3 Querying BigQuery with segment field: ${segmentField}`);
364
442
  const [rows] = await this.bigquery.query({
365
443
  query,
366
444
  location: this.location
367
445
  });
368
- if (this.debug) {
369
- console.log(`\u2705 Query executed successfully`);
370
- console.log(` Rows returned: ${rows.length}`);
446
+ console.log(` \u2705 Query executed successfully`);
447
+ console.log(` \u{1F4C8} Total transitions returned: ${rows.length}`);
448
+ if (rows.length === 0) {
449
+ console.log(`
450
+ ${"\u2550".repeat(60)}`);
451
+ console.log(`\u26A0\uFE0F STAGE 2: NO DATA RETURNED!`);
452
+ console.log(`${"\u2550".repeat(60)}`);
453
+ console.log(` \u274C BigQuery returned 0 rows for segmented query`);
454
+ console.log(` Segment field: ${segmentField}`);
455
+ console.log(` Check if this field exists in your GA4 event_params`);
456
+ console.log(`${"\u2550".repeat(60)}
457
+ `);
458
+ return [];
371
459
  }
460
+ console.log(`
461
+ ${"\u2550".repeat(60)}`);
462
+ console.log(`\u{1F4CA} STAGE 3: PROCESSING SEGMENTED DATA`);
463
+ console.log(`${"\u2550".repeat(60)}`);
464
+ console.log(` Processing ${rows.length} raw transitions with segments...`);
372
465
  const navigationData = [];
373
- rows.forEach((row) => {
466
+ let processedCount = 0;
467
+ let filteredCount = 0;
468
+ const segmentCounts = /* @__PURE__ */ new Map();
469
+ console.log(`
470
+ ${"\u2500".repeat(56)}`);
471
+ console.log(` Processing each transition row...`);
472
+ console.log(` ${"\u2500".repeat(56)}`);
473
+ rows.forEach((row, index) => {
374
474
  const previousPage = row.previous_page_path || "(direct)";
375
475
  const currentPage = row.page_path || "";
376
476
  const transitionCount = parseInt(row.transition_count || "0");
377
477
  const segment = row.segment || "unknown";
478
+ if (this.debug && index < 3) {
479
+ console.log(`
480
+ Row ${index + 1}:`);
481
+ console.log(` Raw: "${previousPage}" \u2192 "${currentPage}" | segment: "${segment}" (count: ${transitionCount})`);
482
+ }
378
483
  const normalizedPrevious = previousPage === "(direct)" || previousPage === "(not set)" ? "(direct)" : this.normalizeRoute(previousPage);
379
484
  const normalizedCurrent = this.normalizeRoute(currentPage);
485
+ if (this.debug && index < 3) {
486
+ console.log(` Normalized: "${normalizedPrevious}" \u2192 "${normalizedCurrent}" | segment: "${segment}"`);
487
+ }
380
488
  if (normalizedCurrent && transitionCount >= 1) {
381
489
  navigationData.push({
382
490
  from: normalizedPrevious,
383
491
  to: normalizedCurrent,
384
492
  count: transitionCount,
385
493
  segment
386
- // Include segment/role field
387
494
  });
495
+ processedCount++;
496
+ segmentCounts.set(segment, (segmentCounts.get(segment) || 0) + 1);
497
+ if (this.debug && index < 3) {
498
+ console.log(` \u2705 ACCEPTED`);
499
+ }
500
+ } else {
501
+ filteredCount++;
502
+ if (this.debug && index < 3) {
503
+ console.log(` \u274C FILTERED`);
504
+ }
388
505
  }
389
506
  });
390
- if (this.debug && navigationData.length > 0) {
391
- console.log(`\u2705 Processed ${navigationData.length} transitions with segment data`);
392
- const uniqueSegments = new Set(navigationData.map((d) => d.segment));
507
+ console.log(`
508
+ ${"\u2500".repeat(56)}`);
509
+ console.log(` Processing Summary:`);
510
+ console.log(` \u2705 Accepted: ${processedCount}`);
511
+ console.log(` \u274C Filtered out: ${filteredCount}`);
512
+ console.log(`
513
+ ${"\u2550".repeat(60)}`);
514
+ console.log(`\u{1F4CA} STAGE 4: FINAL RESULTS (SEGMENTED)`);
515
+ console.log(`${"\u2550".repeat(60)}`);
516
+ console.log(` Total valid transitions: ${navigationData.length}`);
517
+ if (navigationData.length > 0) {
518
+ const uniqueSegments = Array.from(segmentCounts.keys()).sort();
393
519
  console.log(`
394
- Detected segments: ${Array.from(uniqueSegments).sort().join(", ")}`);
520
+ \u{1F4CA} Detected segments: ${uniqueSegments.length}`);
521
+ uniqueSegments.forEach((seg) => {
522
+ console.log(` \u2022 ${seg} (${segmentCounts.get(seg)} transitions)`);
523
+ });
395
524
  const bySegment = /* @__PURE__ */ new Map();
396
525
  navigationData.forEach((d) => {
397
526
  if (!bySegment.has(d.segment)) {
@@ -401,42 +530,31 @@ var BigQueryAnalyticsConnector = class {
401
530
  });
402
531
  bySegment.forEach((transitions, segment) => {
403
532
  console.log(`
404
- Top 3 transitions for ${segment}:`);
533
+ Top 3 transitions for segment "${segment}":`);
405
534
  transitions.sort((a, b) => b.count - a.count).slice(0, 3).forEach((nav, i) => {
406
- console.log(` ${i + 1}. ${nav.from} \u2192 ${nav.to} (${nav.count} transitions)`);
535
+ console.log(` ${i + 1}. ${nav.from} \u2192 ${nav.to} (${nav.count})`);
407
536
  });
408
537
  });
538
+ } else {
539
+ console.log(` \u26A0\uFE0F WARNING: All transitions were filtered out!`);
409
540
  }
541
+ console.log(`${"\u2550".repeat(60)}
542
+ `);
410
543
  return navigationData;
411
544
  } catch (error) {
412
545
  const errorMessage = error instanceof Error ? error.message : "Unknown error";
546
+ console.log(`
547
+ ${"\u2550".repeat(60)}`);
548
+ console.log(`\u274C ERROR: SEGMENTED QUERY EXECUTION FAILED`);
549
+ console.log(`${"\u2550".repeat(60)}`);
550
+ console.log(` Segment field: ${segmentField}`);
551
+ console.log(` Error: ${errorMessage}`);
552
+ console.log(`${"\u2550".repeat(60)}
553
+ `);
413
554
  console.warn(`\u26A0\uFE0F Failed to fetch navigation data with segments: ${errorMessage}`);
414
555
  return [];
415
556
  }
416
557
  }
417
- /**
418
- * Test connection to BigQuery
419
- * Note: May fail if service account lacks bigquery.jobs.create permission
420
- * but actual queries may still work. This is expected for viewer-only accounts.
421
- */
422
- async testConnection() {
423
- try {
424
- const query = `SELECT 1 as test_value`;
425
- await this.bigquery.query({
426
- query,
427
- location: this.location
428
- });
429
- if (this.debug) {
430
- console.log("\u2705 BigQuery connection test successful");
431
- }
432
- return true;
433
- } catch (error) {
434
- if (this.debug) {
435
- console.warn("\u26A0\uFE0F BigQuery connection test failed (may be expected for read-only accounts)");
436
- }
437
- return false;
438
- }
439
- }
440
558
  };
441
559
 
442
560
  // src/plugin/model/guessjs-ml-trainer.ts
@@ -1855,6 +1973,7 @@ function generateDashboard(config) {
1855
1973
  }
1856
1974
  // Annotate the CommonJS export names for ESM import in node:
1857
1975
  0 && (module.exports = {
1976
+ BigQueryAnalyticsConnector,
1858
1977
  smartPrefetch
1859
1978
  });
1860
1979
  //# sourceMappingURL=index.cjs.map