Archived
init
This commit is contained in:
@@ -0,0 +1,281 @@
|
||||
# Supwr - Framework-Agnostic SWR Library (Under development)
|
||||
|
||||
A modern, framework-agnostic Stale-While-Revalidate (SWR) data fetching library with adapters for React, Svelte, Solid, and Vue.
|
||||
|
||||
## Features
|
||||
|
||||
### Core Library (`@supwr/core`)
|
||||
- **Framework-agnostic**: Core logic separated from framework-specific code
|
||||
- **Advanced Caching**: LRU cache with TTL support
|
||||
- **Request Deduplication**: Prevent duplicate requests automatically
|
||||
- **Event System**: Subscribe to state changes
|
||||
- **Mutation Support**: Optimistic updates with rollback
|
||||
- **Revalidation Strategies**: Focus, reconnect, interval-based
|
||||
- **TypeScript**: Full type safety throughout
|
||||
- **Error Handling**: Comprehensive error management with retry logic
|
||||
|
||||
### Framework Adapters
|
||||
- **React** (`@supwr/react`): Hooks-based API with `useSyncExternalStore`
|
||||
- **Svelte** (`@supwr/svelte`): Store-based API with Svelte reactivity
|
||||
- **Solid** (`@supwr/solid`): Signal-based API with Solid reactivity
|
||||
- **Vue** (`@supwr/vue`): Composable API with Vue 3 reactivity
|
||||
|
||||
## Installation
|
||||
|
||||
### Core Library
|
||||
```bash
|
||||
npm install @supwr/core
|
||||
```
|
||||
|
||||
### Framework Adapters
|
||||
```bash
|
||||
# React
|
||||
npm install @supwr/react
|
||||
|
||||
# Svelte
|
||||
npm install @supwr/svelte
|
||||
|
||||
# Solid
|
||||
npm install @supwr/solid
|
||||
|
||||
# Vue
|
||||
npm install @supwr/vue
|
||||
```
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Core Usage
|
||||
```typescript
|
||||
import { createSWR } from '@supwr/core'
|
||||
|
||||
const swr = createSWR({
|
||||
fetcher: (key) => fetch(key).then(res => res.json()),
|
||||
refreshInterval: 5000,
|
||||
revalidateOnFocus: true
|
||||
})
|
||||
|
||||
// Subscribe to changes
|
||||
const unsubscribe = swr.subscribe('/api/user', (data, error, isValidating, isLoading) => {
|
||||
console.log('Data:', data)
|
||||
console.log('Loading:', isLoading)
|
||||
})
|
||||
|
||||
// Manual mutation
|
||||
await swr.mutate('/api/user', { name: 'New Name' })
|
||||
```
|
||||
|
||||
### React Adapter
|
||||
```tsx
|
||||
import useSWR from '@supwr/react'
|
||||
|
||||
function UserProfile() {
|
||||
const { data, error, isLoading, mutate } = useSWR(
|
||||
'/api/user',
|
||||
(key) => fetch(key).then(res => res.json())
|
||||
)
|
||||
|
||||
if (isLoading) return <div>Loading...</div>
|
||||
if (error) return <div>Error: {error.message}</div>
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h1>{data?.name}</h1>
|
||||
<button onClick={() => mutate({ name: 'Updated Name' })}>
|
||||
Update Name
|
||||
</button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
### Svelte Adapter
|
||||
```svelte
|
||||
<script>
|
||||
import { createSWRStores } from '@supwr/svelte'
|
||||
|
||||
const { data, error, isLoading, mutate } = createSWRStores(
|
||||
'/api/user',
|
||||
(key) => fetch(key).then(res => res.json())
|
||||
)
|
||||
</script>
|
||||
|
||||
{#if $isLoading}
|
||||
<div>Loading...</div>
|
||||
{:else if $error}
|
||||
<div>Error: {$error.message}</div>
|
||||
{:else}
|
||||
<div>
|
||||
<h1>{$data?.name}</h1>
|
||||
<button on:click={() => mutate({ name: 'Updated Name' })}>
|
||||
Update Name
|
||||
</button>
|
||||
</div>
|
||||
{/if}
|
||||
```
|
||||
|
||||
### Solid Adapter
|
||||
```tsx
|
||||
import { createSWRSignals } from '@supwr/solid'
|
||||
|
||||
function UserProfile() {
|
||||
const { data, error, isLoading, mutate } = createSWRSignals(
|
||||
'/api/user',
|
||||
(key) => fetch(key).then(res => res.json())
|
||||
)
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Show when={isLoading()}>
|
||||
<div>Loading...</div>
|
||||
</Show>
|
||||
<Show when={error()}>
|
||||
<div>Error: {error()?.message}</div>
|
||||
</Show>
|
||||
<Show when={data()}>
|
||||
<div>
|
||||
<h1>{data()?.name}</h1>
|
||||
<button onClick={() => mutate({ name: 'Updated Name' })}>
|
||||
Update Name
|
||||
</button>
|
||||
</div>
|
||||
</Show>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
### Vue Adapter
|
||||
```vue
|
||||
<template>
|
||||
<div>
|
||||
<div v-if="isLoading">Loading...</div>
|
||||
<div v-else-if="error">Error: {{ error.message }}</div>
|
||||
<div v-else>
|
||||
<h1>{{ data?.name }}</h1>
|
||||
<button @click="updateName">Update Name</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useSWR } from '@supwr/vue'
|
||||
|
||||
const { data, error, isLoading, mutate } = useSWR(
|
||||
'/api/user',
|
||||
(key) => fetch(key).then(res => res.json())
|
||||
)
|
||||
|
||||
const updateName = () => {
|
||||
mutate({ name: 'Updated Name' })
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
## Architecture
|
||||
|
||||
### Core Components
|
||||
- **Cache**: LRU cache with TTL and automatic cleanup
|
||||
- **Events**: Key-specific and global event management
|
||||
- **Fetcher**: Request deduplication and abort support
|
||||
- **Revalidation**: Multiple revalidation strategies
|
||||
- **Mutation**: Optimistic updates with rollback
|
||||
- **Configuration**: Extensible configuration system
|
||||
|
||||
### Adapter Pattern
|
||||
Each adapter:
|
||||
1. Imports the core library
|
||||
2. Provides framework-specific reactivity integration
|
||||
3. Exports idiomatic API for the framework
|
||||
4. Handles framework lifecycle management
|
||||
|
||||
## API Reference
|
||||
|
||||
### Core API
|
||||
```typescript
|
||||
interface SWRCore<Data, Error> {
|
||||
get(key: Key): CacheEntry<Data, Error> | undefined
|
||||
subscribe(key: Key, callback: Callback): Unsubscribe
|
||||
mutate(key: Key, data?, options?): Promise<Data>
|
||||
revalidate(key: Key, options?): Promise<boolean>
|
||||
delete(key: Key): void
|
||||
clear(): void
|
||||
}
|
||||
```
|
||||
|
||||
### Configuration Options
|
||||
```typescript
|
||||
interface SWRConfig<Data, Error> {
|
||||
fetcher?: Fetcher<Data>
|
||||
ttl?: number
|
||||
refreshInterval?: number
|
||||
revalidateOnFocus?: boolean
|
||||
revalidateOnReconnect?: boolean
|
||||
dedupingInterval?: number
|
||||
errorRetryCount?: number
|
||||
errorRetryInterval?: number
|
||||
loadingTimeout?: number
|
||||
onSuccess?: (data: Data, key: Key) => void
|
||||
onError?: (error: Error, key: Key) => void
|
||||
onErrorRetry?: (error, key, config, revalidate, options) => void
|
||||
isPaused?: () => boolean
|
||||
compare?: (a: Data, b: Data) => boolean
|
||||
fallback?: Record<string, Data>
|
||||
}
|
||||
```
|
||||
|
||||
## Development
|
||||
|
||||
### Setup
|
||||
```bash
|
||||
# Clone repository
|
||||
git clone <repository-url>
|
||||
cd supwr
|
||||
|
||||
# Install dependencies
|
||||
npm install
|
||||
|
||||
# Build all packages
|
||||
npm run build
|
||||
|
||||
# Run tests
|
||||
npm run test
|
||||
|
||||
# Start development
|
||||
npm run dev
|
||||
```
|
||||
|
||||
### Project Structure
|
||||
```
|
||||
supwr/
|
||||
├── src/
|
||||
│ ├── core/ # Core SWR library
|
||||
│ └── adapters/ # Framework adapters
|
||||
│ ├── react/ # React adapter
|
||||
│ ├── svelte/ # Svelte adapter
|
||||
│ ├── solid/ # Solid adapter
|
||||
│ └── vue/ # Vue adapter
|
||||
├── package.json # Workspace configuration
|
||||
└── README.md
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
1. Fork the repository
|
||||
2. Create a feature branch
|
||||
3. Make your changes
|
||||
4. Add tests for new functionality
|
||||
5. Ensure all tests pass
|
||||
6. Submit a pull request
|
||||
|
||||
## License
|
||||
|
||||
MIT © [Supwr](https://github.com/shishantbiswas/supwr)
|
||||
|
||||
## Acknowledgments
|
||||
|
||||
Inspired by:
|
||||
- [SWR](https://swr.vercel.app/) - React Hooks library for data fetching
|
||||
- [swrev](https://github.com/ConsoleTVs/swrev) - Framework-agnostic SWR implementation
|
||||
- [solid-swr](https://github.com/tronikelis/solid-swr) - Solid implementation
|
||||
- [sswr](https://github.com/ConsoleTVs/sswr) - Svelte implementation
|
||||
- [swrv](https://github.com/Kong/swrv) - Vue implementation
|
||||
Reference in New Issue
Block a user