developmentseed / developmentseed/stac-react

Add Standalone Hooks (Context-Free Mode)

Open
#34 1 comment 1 reaction 0 assignees View on GitHub
Dominant language
TypeScript
Stars
34
Forks
4
PR merge metrics
No merged PRs in 30d

Description

## Problem
Currently, all stac-react hooks require the `StacApiProvider` context to function. This limits the library's flexibility when working with:
- Static STAC catalogs without a formal API
- Direct URL-based STAC resource fetching
- Multiple STAC sources in the same application
- File-based or uploaded STAC JSON

Projects like stac-map need to fetch arbitrary STAC resources by URL without committing to a single API endpoint via context.

## Current Behavior
```typescript
// This requires StacApiProvider wrapping the component
import { useCollection, useItem } from '@developmentseed/stac-react';

function MyComponent() {
const { collection } = useCollection('my-collection-id'); // Requires context
const { item } = useItem(url); // Requires context
}

// Must be wrapped:

```

## Desired Behavior
```typescript
// Make context optional
import { useItem } from '@developmentseed/stac-react';

function MyComponent() {
// Works without StacApiProvider when full URL provided
const { item } = useItem('https://example.com/items/item-id.json');
}
```

## Proposed Solution

### 1. Add Context-Free Variants
Create standalone versions of hooks that don't require `StacApiProvider`:
- `useStacResource(url)` - Generic hook for any STAC resource
- `useStacCollection(url)` - Fetch collection by URL
- `useStacItem(url)` - Fetch item by URL
- `useStacCatalog(url)` - Fetch catalog by URL

### 2. Make Existing Hooks Context-Aware
Modify existing hooks to detect whether they're inside a context:
```typescript
function useCollection(collectionIdOrUrl: string) {
const context = useStacApiContext();

if (context?.stacApi) {
// Use API-centric approach (current behavior)
return useApiCollection(collectionIdOrUrl);
} else if (isFullUrl(collectionIdOrUrl)) {
// Use standalone approach
return useStandaloneCollection(collectionIdOrUrl);
} else {
throw new Error('Either provide StacApiProvider context or use full URLs');
}
}
```

### 3. Export Standalone Variants Separately
```typescript
// src/standalone/index.ts
export { useStacResource } from './useStacResource';
export { useStacCollection } from './useStacCollection';
export { useStacItem } from './useStacItem';
```

## Implementation Details

### New Hook: `useStacResource`
```typescript
import { useQuery } from '@tanstack/react-query';

type StacResourceHook = {
data?: StacCatalog | StacCollection | StacItem;
isLoading: boolean;
isFetching: boolean;
error?: Error;
refetch: () => void;
};

function useStacResource(url: string, options?: RequestInit): StacResourceHook {
const { data, error, isLoading, isFetching, refetch } = useQuery({
queryKey: ['stac-resource', url],
queryFn: async () => {
const response = await fetch(url, {
headers: {
'Content-Type': 'application/json',
...options?.headers,
},
...options,
});

if (!response.ok) {
throw new Error(`Failed to fetch STAC resource: ${response.statusText}`);
}

return response.json();
},
enabled: !!url,
retry: false,
});

return { data, error, isLoading, isFetching, refetch };
}
```

## Benefits
- ✅ Use stac-react without requiring an API provider
- ✅ Fetch STAC resources from any URL
- ✅ Support static catalogs and file-based STAC
- ✅ Enable multi-source STAC applications
- ✅ Maintain backward compatibility with existing API-centric approach
- ✅ Align with how stac-map and other tools work with STAC

## Breaking Changes
None - this is additive functionality. Existing API-centric hooks remain unchanged.

## Testing Requirements
- [ ] Test hooks work without StacApiProvider
- [ ] Test hooks work with full URLs
- [ ] Test error handling for invalid URLs
- [ ] Test that existing API-centric behavior is unchanged
- [ ] Test with various STAC resource types (catalog, collection, item)

## Documentation Requirements
- [ ] Add examples for context-free usage
- [ ] Document when to use API-centric vs standalone approach
- [ ] Update README with standalone examples
- [ ] Add migration guide for projects using direct URLs

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.