import { } from "@effectionx/fetch"fetch
Effection-native fetch with structured concurrency and streaming response support.
Installation
npm install @effectionx/fetch effection
Usage
import { main } from "effection";
import { fetch } from "@effectionx/fetch";
await main(function* () {
let users = yield* fetch("https://api.example.com/users").json();
console.log(users);
});
Fluent API
Chain methods directly on fetch() for concise one-liners:
// JSON
let data = yield* fetch("https://api.example.com/users").json();
// Text
let html = yield* fetch("https://example.com").text();
// With validation - throws HttpError on non-2xx
let data = yield* fetch("https://api.example.com/users").expect().json();
Traditional API
You can also get the response first, then consume the body:
let response = yield* fetch("https://api.example.com/users");
let data = yield* response.json();
Streaming response bodies
import { each } from "effection";
import { fetch } from "@effectionx/fetch";
function* example() {
for (let chunk of yield* each(fetch("https://example.com/large-file.bin").body())) {
console.log(chunk.length);
yield* each.next();
}
}
Concurrent requests
import { all } from "effection";
import { fetch } from "@effectionx/fetch";
function* fetchMultiple() {
let [users, posts, comments] = yield* all([
fetch("https://api.example.com/users").json(),
fetch("https://api.example.com/posts").json(),
fetch("https://api.example.com/comments").json(),
]);
return { users, posts, comments };
}
Validate JSON while parsing
import { fetch } from "@effectionx/fetch";
interface User {
id: string;
name: string;
}
function parseUser(value: unknown): User {
if (
typeof value === "object" &&
value !== null &&
"id" in value &&
"name" in value
) {
return value as User;
}
throw new Error("invalid user payload");
}
function* getUser() {
return yield* fetch("https://api.example.com/user").json(parseUser);
}
Handle non-2xx responses
import { HttpError, fetch } from "@effectionx/fetch";
function* getUser(id: string) {
try {
return yield* fetch(`https://api.example.com/users/${id}`).expect().json();
} catch (error) {
if (error instanceof HttpError) {
console.error(error.status, error.statusText);
}
throw error;
}
}
API
fetch(input, init?)
Returns a FetchOperation that supports both fluent chaining and traditional usage.
input- URL string,URLobject, orRequestobjectinit- OptionalFetchInitoptions (same asRequestInitbut withoutsignal)
Cancellation is handled automatically via Effection's structured concurrency. When the
scope exits, the request is aborted. The signal option is intentionally omitted since
Effection manages cancellation for you.
FetchOperation
Chainable fetch operation returned by fetch().
json<T>(),json<T>(parse)- parse response as JSONtext()- get response as textarrayBuffer()- get response as ArrayBufferblob()- get response as BlobformData()- get response as FormDatabody()- stream response body asStream<Uint8Array, void>expect()- returns a newFetchOperationthat throwsHttpErroron non-2xx
Can also be yielded directly to get a FetchResponse:
let response = yield* fetch("https://api.example.com/users");
FetchResponse
Effection wrapper around native Response with operation-based body readers.
json<T>(),json<T>(parse)text()arrayBuffer()blob()formData()body(): Stream<Uint8Array, void>expect()- throwsHttpErrorfor non-2xx responsesraw- access the underlying nativeResponse
API Reference
Request options for fetch, excluding signal since cancellation
is handled automatically via Effection's structured concurrency.
Chainable fetch operation that supports fluent API.
Can be yielded directly to get a FetchResponse, or chained
with methods like .json(), .text(), .body() for direct consumption.
Examples
Example 1
// Fluent API - single yield*
let data = yield* fetch("/api/users").json();
// With validation - throws HttpError on non-2xx
let data = yield* fetch("/api/users").expect().json();
// Traditional API - get response first
let response = yield* fetch("/api/users");
let data = yield* response.json();
Methods
json
<T = unknown>(): Operation<T>Parse response body as JSON.
json
<T>(parse: (value: unknown) => T): Operation<T>Parse response body as JSON with a custom parser.
text
(): Operation<string>Get response body as text.
arrayBuffer
(): Operation<ArrayBuffer>Get response body as ArrayBuffer.
blob
(): Operation<Blob>Get response body as Blob.
formData
(): Operation<FormData>Get response body as FormData.
body
(): Stream<Uint8Array, void>Stream response body as chunks.
expect
(): FetchOperationReturn a new FetchOperation that throws HttpError on non-2xx responses.
Effection wrapper around the native Response object.
Provides operation-based methods for consuming the response body, and exposes common response properties.
Properties
- rawreadonly: Response
The underlying native Response object.
- bodyUsedreadonly: boolean
Whether the response body has been consumed.
- okreadonly: boolean
Whether the response status is in the 200-299 range.
- statusreadonly: number
The HTTP status code.
- statusTextreadonly: string
The HTTP status message.
- headersreadonly: Headers
The response headers.
- urlreadonly: string
The final URL after redirects.
- redirectedreadonly: boolean
Whether the response was redirected.
- typereadonly: ResponseType
The response type (e.g., "basic", "cors").
Methods
json
<T = unknown>(): Operation<T>Parse response body as JSON.
json
<T>(parse: (value: unknown) => T): Operation<T>Parse response body as JSON with a custom parser.
text
(): Operation<string>Get response body as text.
arrayBuffer
(): Operation<ArrayBuffer>Get response body as ArrayBuffer.
blob
(): Operation<Blob>Get response body as Blob.
formData
(): Operation<FormData>Get response body as FormData.
body
(): Stream<Uint8Array, void>Stream response body as chunks.
expect
(): OperationThrow HttpError if response is not ok (non-2xx status).
Error thrown when an HTTP response has a non-2xx status code.
Thrown by FetchOperation and FetchResponse when the response is not ok.
Constructors
- new HttpError(status: number, statusText: string, url: string, response: FetchResponse)
Perform an HTTP request using the Fetch API with Effection structured concurrency.
Cancellation is automatically handled via the current Effection scope. When the scope exits, the request is aborted.
Examples
Example 1
// Simple GET request
let data = yield* fetch("https://api.example.com/users").json();
// POST request with body
let result = yield* fetch("https://api.example.com/users", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ name: "Alice" }),
}).expect().json();
// Stream response body
for (let chunk of yield* each(fetch("/large-file").body())) {
console.log(chunk.length);
yield* each.next();
}
Parameters
input: RequestInfo | URL
- The URL or Request object
initoptional: FetchInit
- Optional request configuration (same as RequestInit, but without signal)
Return Type
A chainable FetchOperation