Skip to content

@studiocms/cfetch

This is an Astro integration^ that provides a cacheable fetch function for Astro SSR

  • 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.
  1. Install the integration automatically using the Astro CLI:

    Terminal window
    npm run studiocms add @studiocms/cfetch

    Or install it manually:

    Terminal window
    npm i @studiocms/cfetch
  2. Install peer dependencies

    If your package manager does not automatically install peer dependencies, you will need to ensure Effect is installed.

    Terminal window
    npm i effect
  3. Add the integration to your astro config

    astro.config.mts
    import { defineConfig } from 'astro/config';
    import cFetch from "@studiocms/cfetch";
    export default defineConfig({
    integrations: [
    cFetch(),
    ],
    });

This integration includes various versions of cached fetch functions and Effects^ to allow full control of how you work with your data.

All Effects have the following return pattern or derivatives there of

Effect.Effect<CachedResponse<T>, FetchError, never>;
interface CachedResponse<T> {
data: T;
ok: boolean;
status: number;
statusText: string;
headers: Record<string, string>;
}
interface CFetchConfig {
ttl?: Duration.DurationInput;
tags?: string[];
key?: string;
verbose?: boolean;
}
const cFetchEffect: <T>(
url: string | URL,
parser: (response: Response) => Promise<T>,
options?: RequestInit | undefined,
cacheConfig?: CFetchConfig | undefined
) => Effect.Effect<CachedResponse<T>, FetchError, never>
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>
*/
const cFetchEffectJson: <T>(
url: string | URL,
options?: RequestInit | undefined,
cacheConfig?: CFetchConfig | undefined
) => Effect.Effect<CachedResponse<T>, FetchError, never>
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>
*/
const cFetchEffectText: (
url: string | URL,
options?: RequestInit | undefined,
cacheConfig?: CFetchConfig | undefined
) => Effect.Effect<CachedResponse<string>, FetchError, never>
import { cFetchEffectText } from "c:fetch"
const effect = cFetchEffectText(
'https://example.com',
{ method: "GET" }
);
/*
Return type:
Effect.Effect<CachedResponse<string>, FetchError, never>
*/
const cFetchEffectBlob: (
url: string | URL,
options?: RequestInit | undefined,
cacheConfig?: CFetchConfig | undefined
) => Effect.Effect<CachedResponse<Blob>, FetchError, never>
import { cFetchEffectBlob } from "c:fetch"
const effect = cFetchEffectBlob(
'https://example.com/image.png',
{ method: "GET" }
);
/*
Return type:
Effect.Effect<CachedResponse<Blob>, FetchError, never>
*/

All Functions have the following return pattern or derivatives there of

CachedResponse<T>;
const cFetch: <T>(
url: string | URL,
parser: (response: Response) => Promise<T>,
options?: RequestInit | undefined,
cacheConfig?: CFetchConfig | undefined
) => Promise<CachedResponse<T>>
import { cFetch } from "c:fetch"
const effect = await cFetch<{ foo: string; bar: number; }>(
'https://api.example.com/data',
(res) => res.json(),
{ method: "GET" }
);
/*
Return type:
CachedResponse<{ foo: string; bar: number; }>
*/
const cFetchJson: <T>(
url: string | URL,
options?: RequestInit | undefined,
cacheConfig?: CFetchConfig | undefined
) => Promise<CachedResponse<T>>
import { cFetchJson } from "c:fetch"
const effect = await cFetchJson<{ foo: string; bar: number; }>(
'https://api.example.com/data',
{ method: "GET" }
);
/*
Return type:
CachedResponse<{ foo: string; bar: number; }>
*/
const cFetchText: (
url: string | URL,
options?: RequestInit | undefined,
cacheConfig?: CFetchConfig | undefined
) => Promise<CachedResponse<string>>
import { cFetchText } from "c:fetch"
const effect = await cFetchText(
'https://example.com',
{ method: "GET" }
);
/*
Return type:
CachedResponse<string>
*/
const cFetchBlob: (
url: string | URL,
options?: RequestInit | undefined,
cacheConfig?: CFetchConfig | undefined
) => Promise<CachedResponse<Blob>>
import { cFetchBlob } from "c:fetch"
const effect = await cFetchBlob(
'https://example.com/image.png',
{ method: "GET" }
);
/*
Return type:
CachedResponse<Blob>
*/