TypeScript SDK with TanStack Query hooks for RouteFlow API
npm install @routeflow/sdkTypeScript SDK with TanStack Query hooks for the RouteFlow API.
``bash`
npm install @routeflow/sdk @tanstack/react-queryor
yarn add @routeflow/sdk @tanstack/react-queryor
pnpm add @routeflow/sdk @tanstack/react-query
Configure the SDK at your app's entry point:
`typescript
// app/providers.tsx or similar
import { configureSDK } from '@routeflow/sdk';
configureSDK({
baseURL: process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3001',
getAccessToken: () => {
if (typeof window !== 'undefined') {
return localStorage.getItem('accessToken');
}
return null;
},
refreshAccessToken: async () => {
// Implement token refresh logic
const refreshToken = localStorage.getItem('refreshToken');
if (!refreshToken) return null;
const response = await fetch('/api/auth/refresh', {
method: 'POST',
body: JSON.stringify({ refreshToken }),
});
const data = await response.json();
localStorage.setItem('accessToken', data.accessToken);
return data.accessToken;
},
onUnauthorized: () => {
// Redirect to login
window.location.href = '/login';
},
});
`
`typescript
// app/providers.tsx
'use client';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { useState } from 'react';
export function Providers({ children }: { children: React.ReactNode }) {
const [queryClient] = useState(() => new QueryClient({
defaultOptions: {
queries: {
staleTime: 60 * 1000, // 1 minute
retry: 1,
},
},
}));
return (
{children}
);
}
`
`typescript
import { useRuns, useRun, useDrivers, useCurrentUser } from '@routeflow/sdk';
// Get paginated list of runs
function RunsList() {
const { data, isLoading, error } = useRuns({
status: 'IN_PROGRESS',
page: 1,
limit: 10,
});
if (isLoading) return
if (error) return
return (
// Get single run
function RunDetail({ runId }: { runId: string }) {
const { data: run, isLoading } = useRun(runId);
// ...
}
// Get current user
function Profile() {
const { data: user, isLoading } = useCurrentUser();
// ...
}
// Get drivers
function DriversList() {
const { data: drivers } = useDrivers({ onlineOnly: true });
// ...
}
`
`typescript
import {
useCreateRun,
useUpdateRun,
useDeleteRun,
useAssignDriver,
useLogin,
useLogout,
} from '@routeflow/sdk';
// Create a run
function CreateRunForm() {
const { mutate: createRun, isPending } = useCreateRun({
onSuccess: (run) => {
console.log('Created run:', run.id);
router.push(/runs/${run.id});
},
onError: (error) => {
toast.error(error.message);
},
});
const handleSubmit = (data: CreateRunRequest) => {
createRun(data);
};
return
;// Update a run
function EditRunForm({ runId }: { runId: string }) {
const { mutate: updateRun, isPending } = useUpdateRun();
const handleSave = (data: UpdateRunRequest) => {
updateRun({ id: runId, data });
};
}
// Delete a run
function DeleteRunButton({ runId }: { runId: string }) {
const { mutate: deleteRun, isPending } = useDeleteRun({
onSuccess: () => router.push('/runs'),
});
return (
);
}
// Assign driver
function AssignDriverSelect({ runId }: { runId: string }) {
const { mutate: assignDriver } = useAssignDriver();
return (
);
}
// Login
function LoginForm() {
const { mutate: login, isPending, error } = useLogin({
onSuccess: (data) => {
localStorage.setItem('accessToken', data.accessToken);
localStorage.setItem('refreshToken', data.refreshToken);
router.push('/dashboard');
},
});
return (
$3
`typescript
import { useTrackingStatus, useTrackingLocation } from '@routeflow/sdk';// Public tracking page
function TrackingPage({ token }: { token: string }) {
const { data: status, isLoading: statusLoading } = useTrackingStatus(token);
const { data: location, isLoading: locationLoading } = useTrackingLocation(token);
if (statusLoading) return ;
return (
{status?.runName}
Status: {status?.status}
ETA: {status?.eta?.estimatedTime}
{location?.available && (
)}
);
}
`Available Hooks
$3
- useCurrentUser() - Get authenticated user
- useRuns(params?) - List runs with pagination/filters
- useRun(id) - Get single run
- useDrivers(params?) - List drivers
- useDriver(id) - Get single driver
- useTrackingStatus(token) - Public tracking status
- useTrackingLocation(token) - Public driver location$3
- useLogin() - Login
- useRegister() - Register
- useLogout() - Logout
- useCreateRun() - Create run
- useUpdateRun() - Update run
- useDeleteRun() - Delete run
- useAssignDriver() - Assign driver to run
- useUnassignDriver() - Remove driver from run
- useStartRun() - Start run
- useCompleteRun() - Complete run
- useOptimizeRoute() - Optimize run route
- useCreateStop() - Add stop to run
- useUpdateStop() - Update stop
- useDeleteStop() - Delete stop
- useUpdateStopStatus() - Update stop status
- useReorderStops() - Reorder stopsTypes
All types are re-exported from
@routeflow/types:`typescript
import type {
Run,
Stop,
Driver,
User,
RunStatus,
StopStatus,
ApiResponse,
PaginatedResponse,
} from '@routeflow/sdk';
`Query Keys
For manual cache invalidation:
`typescript
import { queryKeys } from '@routeflow/sdk';
import { useQueryClient } from '@tanstack/react-query';const queryClient = useQueryClient();
// Invalidate all runs
queryClient.invalidateQueries({ queryKey: queryKeys.runs.all });
// Invalidate specific run
queryClient.invalidateQueries({ queryKey: queryKeys.runs.detail('run-123') });
// Invalidate all drivers
queryClient.invalidateQueries({ queryKey: queryKeys.drivers.all });
``MIT