GitHub

@studiocms/cfetch

Readme's Banner

NPM Version JSR Formatted with Biome Built with Astro

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

  1. Install the integration automatically using the Astro CLI:
pnpm astro add @studiocms/cfetch
npx astro add @studiocms/cfetch
yarn astro add @studiocms/cfetch

Or install it manually:

  1. Install the required dependencies
pnpm add @studiocms/cfetch
npm install @studiocms/cfetch
yarn add @studiocms/cfetch
  1. Install peer dependencies

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

pnpm add effect
npm install effect
yarn add effect
  1. 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 GET and HEAD requests are cached. You can change that by setting forceCache to true.

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
*/

Licensing

MIT Licensed.

Read the original on github.com ↗