astro-tractstack 2.0.0-rc.27 → 2.0.0-rc.29

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "astro-tractstack",
3
- "version": "2.0.0-rc.27",
3
+ "version": "2.0.0-rc.29",
4
4
  "description": "Astro integration for TractStack - redeeming the web from boring experiences",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1,4 +1,4 @@
1
- import { useEffect, useCallback, useRef, useState } from 'react';
1
+ import { useEffect, useRef } from 'react';
2
2
  import { useStore } from '@nanostores/react';
3
3
  import { epinetCustomFilters } from '@/stores/analytics';
4
4
  import { TractStackAPI } from '@/utils/api';
@@ -69,7 +69,6 @@ export const GET: APIRoute = async ({ request }) => {
69
69
  status: 200,
70
70
  headers: {
71
71
  'Content-Type': 'application/json',
72
- 'Cache-Control': 'public, max-age=300', // Cache for 5 minutes
73
72
  },
74
73
  });
75
74
  } catch (fetchError) {
@@ -161,11 +161,10 @@ const pollingState = new Map<
161
161
  }
162
162
  >();
163
163
 
164
- // Constants for polling configuration
165
- const MAX_POLLING_ATTEMPTS = 10;
166
- const MAX_POLLING_DURATION = 5 * 60 * 1000; // 5 minutes in milliseconds
167
- const BASE_POLLING_INTERVAL = 2000; // 2 seconds base interval
168
- const MAX_POLLING_INTERVAL = 32000; // 32 seconds max interval
164
+ const MAX_POLLING_ATTEMPTS = 25;
165
+ const MAX_POLLING_DURATION = 10 * 60 * 1000; // 10 minutes
166
+ const BASE_POLLING_INTERVAL = 10000; // 10 seconds
167
+ const MAX_POLLING_INTERVAL = 30000; // 30 seconds
169
168
 
170
169
  const fetchingStates = new Map<string, boolean>();
171
170
 
@@ -203,7 +202,7 @@ export async function loadOrphanAnalysis(): Promise<void> {
203
202
 
204
203
  updateTenantState(tenantId, {
205
204
  data,
206
- isLoading: false,
205
+ isLoading: data.status === 'loading', // Only stop loading if complete
207
206
  error: null,
208
207
  lastFetched: Date.now(),
209
208
  });
@@ -239,7 +238,7 @@ function startPolling(tenantId: string): void {
239
238
  lastAttemptTime: startTime,
240
239
  });
241
240
 
242
- // Start the first poll immediately
241
+ // Start the first poll
243
242
  scheduleNextPoll(tenantId);
244
243
  }
245
244
 
@@ -260,21 +259,21 @@ function scheduleNextPoll(tenantId: string): void {
260
259
  const elapsed = Date.now() - state.startTime;
261
260
  if (elapsed >= MAX_POLLING_DURATION) {
262
261
  console.warn(
263
- `Orphan analysis polling stopped: Maximum duration (${MAX_POLLING_DURATION}ms) exceeded for tenant ${tenantId}`
262
+ `Orphan analysis polling stopped: Maximum duration (${
263
+ MAX_POLLING_DURATION / 1000
264
+ }s) exceeded for tenant ${tenantId}`
264
265
  );
265
266
  handlePollingFailure(tenantId, 'Polling timeout exceeded');
266
267
  return;
267
268
  }
268
269
 
269
- // Calculate delay using exponential backoff for consecutive errors
270
- let delay = BASE_POLLING_INTERVAL;
271
- if (state.consecutiveErrors > 0) {
272
- // Exponential backoff: 2s → 4s → 8s → 16s → 32s (capped)
273
- delay = Math.min(
274
- BASE_POLLING_INTERVAL * Math.pow(2, state.consecutiveErrors),
275
- MAX_POLLING_INTERVAL
276
- );
277
- }
270
+ // This is more suitable for long-running jobs, as it spaces out requests
271
+ // even when the server responds successfully with a 'loading' status.
272
+ // Polling sequence: 10s → 20s → 30s → 30s...
273
+ const delay = Math.min(
274
+ BASE_POLLING_INTERVAL * Math.pow(2, state.attempts),
275
+ MAX_POLLING_INTERVAL
276
+ );
278
277
 
279
278
  // Schedule the next poll
280
279
  const timeoutId = setTimeout(() => executePoll(tenantId), delay);
@@ -304,6 +303,7 @@ async function executePoll(tenantId: string): Promise<void> {
304
303
 
305
304
  // Check if analysis is complete
306
305
  if (data.status === 'complete') {
306
+ updateTenantState(tenantId, { isLoading: false });
307
307
  stopPolling(tenantId);
308
308
  return;
309
309
  }
@@ -329,7 +329,6 @@ async function executePoll(tenantId: string): Promise<void> {
329
329
  error instanceof Error ? error.message : 'Unknown polling error';
330
330
  updateTenantState(tenantId, {
331
331
  error: `Polling error (attempt ${state.attempts}/${MAX_POLLING_ATTEMPTS}): ${errorMessage}`,
332
- lastFetched: Date.now(),
333
332
  });
334
333
 
335
334
  // Check if we should stop polling due to consecutive errors
@@ -344,7 +343,7 @@ async function executePoll(tenantId: string): Promise<void> {
344
343
  return;
345
344
  }
346
345
 
347
- // Schedule next poll with exponential backoff
346
+ // Schedule next poll (will use exponential backoff due to increased consecutiveErrors)
348
347
  scheduleNextPoll(tenantId);
349
348
  }
350
349
  }
@@ -357,8 +356,7 @@ function handlePollingFailure(tenantId: string, reason: string): void {
357
356
  // Update tenant state with final error
358
357
  updateTenantState(tenantId, {
359
358
  isLoading: false,
360
- error: `Orphan analysis polling failed: ${reason}. Please try refreshing the page or contact support if the issue persists.`,
361
- lastFetched: Date.now(),
359
+ error: `Orphan analysis failed: ${reason}. Please try refreshing the page.`,
362
360
  });
363
361
 
364
362
  // Clean up polling state