@studiocms/cfetch
v0.4.0
Published
Astro integration that allows you to have a cached fetch function in your Astro SSR project.
Readme
@studiocms/cfetch

This is an Astro integration that provides a cacheable fetch function for Astro SSR
Usage
Prerequisites
- Using with an Astro SSR project, While you could import and use this in an Astro SSG (static) project, it would have no benefit as Astro Static pages are pre-rendered.
Installation
- Install the integration automatically using the Astro CLI:
pnpm astro add @studiocms/cfetchnpx astro add @studiocms/cfetchyarn astro add @studiocms/cfetchOr install it manually:
- Install the required dependencies
pnpm add @studiocms/cfetchnpm install @studiocms/cfetchyarn add @studiocms/cfetch- Install peer dependencies
If your package manager does not automatically install peer dependencies, you will need to ensure Effect is installed.
pnpm add effectnpm install effectyarn add effect- Add the integration to your astro config
+import cFetch from "@studiocms/cfetch";
export default defineConfig({
integrations: [
+ cFetch(),
],
});Usage
This integration includes various versions of cached fetch functions and Effects to allow full control of how you work with your data.
Effects
All Effects have the following return pattern or derivatives there of
Effect.Effect<CachedResponse<T>, FetchError, never>;CachedResponse<T> type
interface CachedResponse<T> {
data: T;
ok: boolean;
status: number;
statusText: string;
headers: Record<string, string>;
}CFetchConfig type
interface CFetchConfig {
forceCache?: true | undefined;
ttl?: Duration.DurationInput;
tags?: string[];
key?: string;
verbose?: boolean;
}[!NOTE] By default only
GETandHEADrequests are cached. You can change that by settingforceCachetotrue.
InvalidateCacheOptions type
interface InvalidateCacheOptions {
keys?: string[];
tags?: string[];
}cFetchEffect
Interface
const cFetchEffect: <T>(
url: string | URL,
parser: (response: Response) => Promise<T>,
options?: RequestInit | undefined,
cacheConfig?: CFetchConfig | undefined
) => Effect.Effect<CachedResponse<T>, FetchError, never>Example Usage
import { cFetchEffect, Duration } from "c:fetch"
const effect = cFetchEffect<{ foo: string; bar: number; }>(
'https://api.example.com/data',
(res) => res.json(),
{ method: "GET" },
{ ttl?: Duration.hours(1), tags?: ['example'], key?: "api-data-fetch", verbose?: false }
);
/*
Return type:
Effect.Effect<CachedResponse<{ foo: string; bar: number; }>, FetchError, never>
*/invalidateCacheEffect
Interface
const invalidateCacheEffect: (opts: InvalidateCacheOptions) => Effect.Effect<void, never, never>Example Usage
const effect = invalidateCacheEffect({
tags: ['user'],
keys: ['user:123', 'user:456']
})
/*
Return type:
Effect.Effect<void, never, never>
*/cFetchEffectJson
Interface
const cFetchEffectJson: <T>(
url: string | URL,
options?: RequestInit | undefined,
cacheConfig?: CFetchConfig | undefined
) => Effect.Effect<CachedResponse<T>, FetchError, never>Example Usage
import { cFetchEffectJson } from "c:fetch"
const effect = cFetchEffectJson<{ foo: string; bar: number; }>(
'https://api.example.com/data',
{ method: "GET" }
);
/*
Return type:
Effect.Effect<CachedResponse<{ foo: string; bar: number; }>, FetchError, never>
*/cFetchEffectText
Interface
const cFetchEffectText: (
url: string | URL,
options?: RequestInit | undefined,
cacheConfig?: CFetchConfig | undefined
) => Effect.Effect<CachedResponse<string>, FetchError, never>Example Usage
import { cFetchEffectText } from "c:fetch"
const effect = cFetchEffectText(
'https://example.com',
{ method: "GET" }
);
/*
Return type:
Effect.Effect<CachedResponse<string>, FetchError, never>
*/cFetchEffectBlob
Interface
const cFetchEffectBlob: (
url: string | URL,
options?: RequestInit | undefined,
cacheConfig?: CFetchConfig | undefined
) => Effect.Effect<CachedResponse<Blob>, FetchError, never>Example Usage
import { cFetchEffectBlob } from "c:fetch"
const effect = cFetchEffectBlob(
'https://example.com/image.png',
{ method: "GET" }
);
/*
Return type:
Effect.Effect<CachedResponse<Blob>, FetchError, never>
*/Functions
All Functions have the following return pattern or derivatives there of
CachedResponse<T>;cFetch
Interface
const cFetch: <T>(
url: string | URL,
parser: (response: Response) => Promise<T>,
options?: RequestInit | undefined,
cacheConfig?: CFetchConfig | undefined
) => Promise<CachedResponse<T>>Example Usage
import { cFetch } from "c:fetch"
const response = await cFetch<{ foo: string; bar: number; }>(
'https://api.example.com/data',
(res) => res.json(),
{ method: "GET" }
);
/*
Return type:
CachedResponse<{ foo: string; bar: number; }>
*/cFetchJson
Interface
const cFetchJson: <T>(
url: string | URL,
options?: RequestInit | undefined,
cacheConfig?: CFetchConfig | undefined
) => Promise<CachedResponse<T>>Example Usage
import { cFetchJson } from "c:fetch"
const response = await cFetchJson<{ foo: string; bar: number; }>(
'https://api.example.com/data',
{ method: "GET" }
);
/*
Return type:
CachedResponse<{ foo: string; bar: number; }>
*/cFetchText
Interface
const cFetchText: (
url: string | URL,
options?: RequestInit | undefined,
cacheConfig?: CFetchConfig | undefined
) => Promise<CachedResponse<string>>Example Usage
import { cFetchText } from "c:fetch"
const response = await cFetchText(
'https://example.com',
{ method: "GET" }
);
/*
Return type:
CachedResponse<string>
*/cFetchBlob
Interface
const cFetchBlob: (
url: string | URL,
options?: RequestInit | undefined,
cacheConfig?: CFetchConfig | undefined
) => Promise<CachedResponse<Blob>>Example Usage
import { cFetchBlob } from "c:fetch"
const response = await cFetchBlob(
'https://example.com/image.png',
{ method: "GET" }
);
/*
Return type:
CachedResponse<Blob>
*/invalidateCache
Interface
const invalidateCache: (opts: InvalidateCacheOptions) => Promise<void>Example Usage
const res = await invalidateCache({
tags: ['user'],
keys: ['user:123', 'user:456']
})
/*
Return type:
void
*/