import { - coreFetch,
- fetch,
- type Fetch,
- FetchApi,
- type FetchInit,
- type FetchOperation,
- type FetchResponse,
- HttpError
} 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, an in-flight request is aborted. A native fetch that has already settled is
left intact. 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
Methods
fetch
(input: RequestInfo | URL, init: FetchInit | undefined, shouldExpect: boolean): Operation<FetchResponse>No documentation available.
Type
Api<Fetch>
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, an in-flight 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