@effectionx/fetch 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,9 @@
1
+ MIT License
2
+
3
+ Copyright 2024 The Frontside Software, Inc
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,167 @@
1
+ # fetch
2
+
3
+ Effection-native fetch with structured concurrency and streaming response support.
4
+
5
+ ---
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ npm install @effectionx/fetch effection
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ ```ts
16
+ import { main } from "effection";
17
+ import { fetch } from "@effectionx/fetch";
18
+
19
+ await main(function* () {
20
+ let users = yield* fetch("https://api.example.com/users").json();
21
+ console.log(users);
22
+ });
23
+ ```
24
+
25
+ ### Fluent API
26
+
27
+ Chain methods directly on `fetch()` for concise one-liners:
28
+
29
+ ```ts
30
+ // JSON
31
+ let data = yield* fetch("https://api.example.com/users").json();
32
+
33
+ // Text
34
+ let html = yield* fetch("https://example.com").text();
35
+
36
+ // With validation - throws HttpError on non-2xx
37
+ let data = yield* fetch("https://api.example.com/users").expect().json();
38
+ ```
39
+
40
+ ### Traditional API
41
+
42
+ You can also get the response first, then consume the body:
43
+
44
+ ```ts
45
+ let response = yield* fetch("https://api.example.com/users");
46
+ let data = yield* response.json();
47
+ ```
48
+
49
+ ### Streaming response bodies
50
+
51
+ ```ts
52
+ import { each } from "effection";
53
+ import { fetch } from "@effectionx/fetch";
54
+
55
+ function* example() {
56
+ for (let chunk of yield* each(fetch("https://example.com/large-file.bin").body())) {
57
+ console.log(chunk.length);
58
+ yield* each.next();
59
+ }
60
+ }
61
+ ```
62
+
63
+ ### Concurrent requests
64
+
65
+ ```ts
66
+ import { all } from "effection";
67
+ import { fetch } from "@effectionx/fetch";
68
+
69
+ function* fetchMultiple() {
70
+ let [users, posts, comments] = yield* all([
71
+ fetch("https://api.example.com/users").json(),
72
+ fetch("https://api.example.com/posts").json(),
73
+ fetch("https://api.example.com/comments").json(),
74
+ ]);
75
+
76
+ return { users, posts, comments };
77
+ }
78
+ ```
79
+
80
+ ### Validate JSON while parsing
81
+
82
+ ```ts
83
+ import { fetch } from "@effectionx/fetch";
84
+
85
+ interface User {
86
+ id: string;
87
+ name: string;
88
+ }
89
+
90
+ function parseUser(value: unknown): User {
91
+ if (
92
+ typeof value === "object" &&
93
+ value !== null &&
94
+ "id" in value &&
95
+ "name" in value
96
+ ) {
97
+ return value as User;
98
+ }
99
+
100
+ throw new Error("invalid user payload");
101
+ }
102
+
103
+ function* getUser() {
104
+ return yield* fetch("https://api.example.com/user").json(parseUser);
105
+ }
106
+ ```
107
+
108
+ ### Handle non-2xx responses
109
+
110
+ ```ts
111
+ import { HttpError, fetch } from "@effectionx/fetch";
112
+
113
+ function* getUser(id: string) {
114
+ try {
115
+ return yield* fetch(`https://api.example.com/users/${id}`).expect().json();
116
+ } catch (error) {
117
+ if (error instanceof HttpError) {
118
+ console.error(error.status, error.statusText);
119
+ }
120
+ throw error;
121
+ }
122
+ }
123
+ ```
124
+
125
+ ## API
126
+
127
+ ### `fetch(input, init?)`
128
+
129
+ Returns a `FetchOperation` that supports both fluent chaining and traditional usage.
130
+
131
+ - `input` - URL string, `URL` object, or `Request` object
132
+ - `init` - Optional `FetchInit` options (same as `RequestInit` but without `signal`)
133
+
134
+ Cancellation is handled automatically via Effection's structured concurrency. When the
135
+ scope exits, the request is aborted. The `signal` option is intentionally omitted since
136
+ Effection manages cancellation for you.
137
+
138
+ ### `FetchOperation`
139
+
140
+ Chainable fetch operation returned by `fetch()`.
141
+
142
+ - `json<T>()`, `json<T>(parse)` - parse response as JSON
143
+ - `text()` - get response as text
144
+ - `arrayBuffer()` - get response as ArrayBuffer
145
+ - `blob()` - get response as Blob
146
+ - `formData()` - get response as FormData
147
+ - `body()` - stream response body as `Stream<Uint8Array, void>`
148
+ - `expect()` - returns a new `FetchOperation` that throws `HttpError` on non-2xx
149
+
150
+ Can also be yielded directly to get a `FetchResponse`:
151
+
152
+ ```ts
153
+ let response = yield* fetch("https://api.example.com/users");
154
+ ```
155
+
156
+ ### `FetchResponse`
157
+
158
+ Effection wrapper around native `Response` with operation-based body readers.
159
+
160
+ - `json<T>()`, `json<T>(parse)`
161
+ - `text()`
162
+ - `arrayBuffer()`
163
+ - `blob()`
164
+ - `formData()`
165
+ - `body(): Stream<Uint8Array, void>`
166
+ - `expect()` - throws `HttpError` for non-2xx responses
167
+ - `raw` - access the underlying native `Response`
@@ -0,0 +1,136 @@
1
+ import { type Operation, type Stream } from "effection";
2
+ /**
3
+ * Request options for fetch, excluding `signal` since cancellation
4
+ * is handled automatically via Effection's structured concurrency.
5
+ */
6
+ export type FetchInit = Omit<RequestInit, "signal"> & {
7
+ signal?: never;
8
+ };
9
+ /**
10
+ * Chainable fetch operation that supports fluent API.
11
+ *
12
+ * Can be yielded directly to get a {@link FetchResponse}, or chained
13
+ * with methods like `.json()`, `.text()`, `.body()` for direct consumption.
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * // Fluent API - single yield*
18
+ * let data = yield* fetch("/api/users").json();
19
+ *
20
+ * // With validation - throws HttpError on non-2xx
21
+ * let data = yield* fetch("/api/users").expect().json();
22
+ *
23
+ * // Traditional API - get response first
24
+ * let response = yield* fetch("/api/users");
25
+ * let data = yield* response.json();
26
+ * ```
27
+ */
28
+ export interface FetchOperation extends Operation<FetchResponse> {
29
+ /** Parse response body as JSON. */
30
+ json<T = unknown>(): Operation<T>;
31
+ /** Parse response body as JSON with a custom parser. */
32
+ json<T>(parse: (value: unknown) => T): Operation<T>;
33
+ /** Get response body as text. */
34
+ text(): Operation<string>;
35
+ /** Get response body as ArrayBuffer. */
36
+ arrayBuffer(): Operation<ArrayBuffer>;
37
+ /** Get response body as Blob. */
38
+ blob(): Operation<Blob>;
39
+ /** Get response body as FormData. */
40
+ formData(): Operation<FormData>;
41
+ /** Stream response body as chunks. */
42
+ body(): Stream<Uint8Array, void>;
43
+ /** Return a new FetchOperation that throws {@link HttpError} on non-2xx responses. */
44
+ expect(): FetchOperation;
45
+ }
46
+ /**
47
+ * Effection wrapper around the native {@link Response} object.
48
+ *
49
+ * Provides operation-based methods for consuming the response body,
50
+ * and exposes common response properties.
51
+ */
52
+ export interface FetchResponse {
53
+ /** The underlying native Response object. */
54
+ readonly raw: Response;
55
+ /** Whether the response body has been consumed. */
56
+ readonly bodyUsed: boolean;
57
+ /** Whether the response status is in the 200-299 range. */
58
+ readonly ok: boolean;
59
+ /** The HTTP status code. */
60
+ readonly status: number;
61
+ /** The HTTP status message. */
62
+ readonly statusText: string;
63
+ /** The response headers. */
64
+ readonly headers: Headers;
65
+ /** The final URL after redirects. */
66
+ readonly url: string;
67
+ /** Whether the response was redirected. */
68
+ readonly redirected: boolean;
69
+ /** The response type (e.g., "basic", "cors"). */
70
+ readonly type: ResponseType;
71
+ /** Parse response body as JSON. */
72
+ json<T = unknown>(): Operation<T>;
73
+ /** Parse response body as JSON with a custom parser. */
74
+ json<T>(parse: (value: unknown) => T): Operation<T>;
75
+ /** Get response body as text. */
76
+ text(): Operation<string>;
77
+ /** Get response body as ArrayBuffer. */
78
+ arrayBuffer(): Operation<ArrayBuffer>;
79
+ /** Get response body as Blob. */
80
+ blob(): Operation<Blob>;
81
+ /** Get response body as FormData. */
82
+ formData(): Operation<FormData>;
83
+ /** Stream response body as chunks. */
84
+ body(): Stream<Uint8Array, void>;
85
+ /** Throw {@link HttpError} if response is not ok (non-2xx status). */
86
+ expect(): Operation<this>;
87
+ }
88
+ /**
89
+ * Error thrown when an HTTP response has a non-2xx status code.
90
+ *
91
+ * Thrown by {@link FetchOperation.expect} and {@link FetchResponse.expect}
92
+ * when the response is not ok.
93
+ */
94
+ export declare class HttpError extends Error {
95
+ readonly name = "HttpError";
96
+ /** The HTTP status code. */
97
+ readonly status: number;
98
+ /** The HTTP status message. */
99
+ readonly statusText: string;
100
+ /** The request URL. */
101
+ readonly url: string;
102
+ /** The response that triggered this error. */
103
+ readonly response: FetchResponse;
104
+ constructor(status: number, statusText: string, url: string, response: FetchResponse);
105
+ }
106
+ /**
107
+ * Perform an HTTP request using the Fetch API with Effection structured concurrency.
108
+ *
109
+ * Cancellation is automatically handled via the current Effection scope.
110
+ * When the scope exits, the request is aborted.
111
+ *
112
+ * @param input - The URL or Request object
113
+ * @param init - Optional request configuration (same as RequestInit, but without signal)
114
+ * @returns A chainable {@link FetchOperation}
115
+ *
116
+ * @example
117
+ * ```ts
118
+ * // Simple GET request
119
+ * let data = yield* fetch("https://api.example.com/users").json();
120
+ *
121
+ * // POST request with body
122
+ * let result = yield* fetch("https://api.example.com/users", {
123
+ * method: "POST",
124
+ * headers: { "Content-Type": "application/json" },
125
+ * body: JSON.stringify({ name: "Alice" }),
126
+ * }).expect().json();
127
+ *
128
+ * // Stream response body
129
+ * for (let chunk of yield* each(fetch("/large-file").body())) {
130
+ * console.log(chunk.length);
131
+ * yield* each.next();
132
+ * }
133
+ * ```
134
+ */
135
+ export declare function fetch(input: RequestInfo | URL, init?: FetchInit): FetchOperation;
136
+ //# sourceMappingURL=fetch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../fetch.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,SAAS,EACd,KAAK,MAAM,EAGZ,MAAM,WAAW,CAAC;AAEnB;;;GAGG;AACH,MAAM,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,GAAG;IAAE,MAAM,CAAC,EAAE,KAAK,CAAA;CAAE,CAAC;AAEzE;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,cAAe,SAAQ,SAAS,CAAC,aAAa,CAAC;IAC9D,mCAAmC;IACnC,IAAI,CAAC,CAAC,GAAG,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC;IAClC,wDAAwD;IACxD,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;IACpD,iCAAiC;IACjC,IAAI,IAAI,SAAS,CAAC,MAAM,CAAC,CAAC;IAC1B,wCAAwC;IACxC,WAAW,IAAI,SAAS,CAAC,WAAW,CAAC,CAAC;IACtC,iCAAiC;IACjC,IAAI,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC;IACxB,qCAAqC;IACrC,QAAQ,IAAI,SAAS,CAAC,QAAQ,CAAC,CAAC;IAChC,sCAAsC;IACtC,IAAI,IAAI,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;IACjC,sFAAsF;IACtF,MAAM,IAAI,cAAc,CAAC;CAC1B;AAED;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,6CAA6C;IAC7C,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC;IACvB,mDAAmD;IACnD,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC;IACrB,4BAA4B;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,+BAA+B;IAC/B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,4BAA4B;IAC5B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,qCAAqC;IACrC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,2CAA2C;IAC3C,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,iDAAiD;IACjD,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,mCAAmC;IACnC,IAAI,CAAC,CAAC,GAAG,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC;IAClC,wDAAwD;IACxD,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;IACpD,iCAAiC;IACjC,IAAI,IAAI,SAAS,CAAC,MAAM,CAAC,CAAC;IAC1B,wCAAwC;IACxC,WAAW,IAAI,SAAS,CAAC,WAAW,CAAC,CAAC;IACtC,iCAAiC;IACjC,IAAI,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC;IACxB,qCAAqC;IACrC,QAAQ,IAAI,SAAS,CAAC,QAAQ,CAAC,CAAC;IAChC,sCAAsC;IACtC,IAAI,IAAI,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;IACjC,sEAAsE;IACtE,MAAM,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC;CAC3B;AAED;;;;;GAKG;AACH,qBAAa,SAAU,SAAQ,KAAK;IAClC,QAAQ,CAAC,IAAI,eAAe;IAC5B,4BAA4B;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,+BAA+B;IAC/B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,uBAAuB;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,8CAA8C;IAC9C,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;gBAG/B,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,aAAa;CAS1B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,KAAK,CACnB,KAAK,EAAE,WAAW,GAAG,GAAG,EACxB,IAAI,CAAC,EAAE,SAAS,GACf,cAAc,CAEhB"}
package/dist/fetch.js ADDED
@@ -0,0 +1,165 @@
1
+ import { stream, until, useAbortSignal, } from "effection";
2
+ /**
3
+ * Error thrown when an HTTP response has a non-2xx status code.
4
+ *
5
+ * Thrown by {@link FetchOperation.expect} and {@link FetchResponse.expect}
6
+ * when the response is not ok.
7
+ */
8
+ export class HttpError extends Error {
9
+ name = "HttpError";
10
+ /** The HTTP status code. */
11
+ status;
12
+ /** The HTTP status message. */
13
+ statusText;
14
+ /** The request URL. */
15
+ url;
16
+ /** The response that triggered this error. */
17
+ response;
18
+ constructor(status, statusText, url, response) {
19
+ super(`HTTP ${status}: ${statusText}`);
20
+ Object.setPrototypeOf(this, new.target.prototype);
21
+ this.status = status;
22
+ this.statusText = statusText;
23
+ this.url = url;
24
+ this.response = response;
25
+ }
26
+ }
27
+ /**
28
+ * Perform an HTTP request using the Fetch API with Effection structured concurrency.
29
+ *
30
+ * Cancellation is automatically handled via the current Effection scope.
31
+ * When the scope exits, the request is aborted.
32
+ *
33
+ * @param input - The URL or Request object
34
+ * @param init - Optional request configuration (same as RequestInit, but without signal)
35
+ * @returns A chainable {@link FetchOperation}
36
+ *
37
+ * @example
38
+ * ```ts
39
+ * // Simple GET request
40
+ * let data = yield* fetch("https://api.example.com/users").json();
41
+ *
42
+ * // POST request with body
43
+ * let result = yield* fetch("https://api.example.com/users", {
44
+ * method: "POST",
45
+ * headers: { "Content-Type": "application/json" },
46
+ * body: JSON.stringify({ name: "Alice" }),
47
+ * }).expect().json();
48
+ *
49
+ * // Stream response body
50
+ * for (let chunk of yield* each(fetch("/large-file").body())) {
51
+ * console.log(chunk.length);
52
+ * yield* each.next();
53
+ * }
54
+ * ```
55
+ */
56
+ export function fetch(input, init) {
57
+ return createFetchOperation(input, init, false);
58
+ }
59
+ function createFetchOperation(input, init, shouldExpect) {
60
+ function* doFetch() {
61
+ let signal = yield* useAbortSignal();
62
+ let response = yield* until(globalThis.fetch(input, { ...init, signal }));
63
+ let fetchResponse = createFetchResponse(response);
64
+ if (shouldExpect && !response.ok) {
65
+ throw new HttpError(response.status, response.statusText, response.url, fetchResponse);
66
+ }
67
+ return fetchResponse;
68
+ }
69
+ return {
70
+ *[Symbol.iterator]() {
71
+ return yield* doFetch();
72
+ },
73
+ *json(parse) {
74
+ let response = yield* doFetch();
75
+ return yield* response.json(parse);
76
+ },
77
+ *text() {
78
+ let response = yield* doFetch();
79
+ return yield* response.text();
80
+ },
81
+ *arrayBuffer() {
82
+ let response = yield* doFetch();
83
+ return yield* response.arrayBuffer();
84
+ },
85
+ *blob() {
86
+ let response = yield* doFetch();
87
+ return yield* response.blob();
88
+ },
89
+ *formData() {
90
+ let response = yield* doFetch();
91
+ return yield* response.formData();
92
+ },
93
+ body() {
94
+ return {
95
+ *[Symbol.iterator]() {
96
+ let response = yield* doFetch();
97
+ return yield* response.body();
98
+ },
99
+ };
100
+ },
101
+ expect() {
102
+ return createFetchOperation(input, init, true);
103
+ },
104
+ };
105
+ }
106
+ function createFetchResponse(response) {
107
+ let self = {
108
+ get ok() {
109
+ return response.ok;
110
+ },
111
+ get status() {
112
+ return response.status;
113
+ },
114
+ get statusText() {
115
+ return response.statusText;
116
+ },
117
+ get headers() {
118
+ return response.headers;
119
+ },
120
+ get url() {
121
+ return response.url;
122
+ },
123
+ get redirected() {
124
+ return response.redirected;
125
+ },
126
+ get type() {
127
+ return response.type;
128
+ },
129
+ get bodyUsed() {
130
+ return response.bodyUsed;
131
+ },
132
+ get raw() {
133
+ return response;
134
+ },
135
+ *json(parse) {
136
+ let value = yield* until(response.json());
137
+ return parse ? parse(value) : value;
138
+ },
139
+ *text() {
140
+ return yield* until(response.text());
141
+ },
142
+ *arrayBuffer() {
143
+ return yield* until(response.arrayBuffer());
144
+ },
145
+ *blob() {
146
+ return yield* until(response.blob());
147
+ },
148
+ *formData() {
149
+ return yield* until(response.formData());
150
+ },
151
+ body() {
152
+ if (!response.body) {
153
+ throw new Error("Response has no body");
154
+ }
155
+ return stream(response.body);
156
+ },
157
+ *expect() {
158
+ if (!response.ok) {
159
+ throw new HttpError(response.status, response.statusText, response.url, self);
160
+ }
161
+ return self;
162
+ },
163
+ };
164
+ return self;
165
+ }
package/dist/mod.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export * from "./fetch.ts";
2
+ //# sourceMappingURL=mod.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../mod.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC"}
package/dist/mod.js ADDED
@@ -0,0 +1 @@
1
+ export * from "./fetch.js";
@@ -0,0 +1 @@
1
+ {"fileNames":["../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es5.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2016.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2021.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.dom.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.dom.iterable.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.core.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.collection.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.generator.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.iterable.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.promise.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.proxy.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.reflect.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.symbol.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2016.array.include.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2016.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.date.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.object.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.string.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.promise.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.regexp.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.array.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.object.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.string.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.symbol.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.bigint.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.date.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.promise.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.string.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.number.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2021.promise.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2021.string.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2021.weakref.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2021.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.array.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.error.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.object.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.string.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.regexp.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.decorators.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.decorators.legacy.d.ts","../../node_modules/.pnpm/effection@4.0.0/node_modules/effection/esm/lib/result.d.ts","../../node_modules/.pnpm/effection@4.0.0/node_modules/effection/esm/lib/types.d.ts","../../node_modules/.pnpm/effection@4.0.0/node_modules/effection/esm/lib/action.d.ts","../../node_modules/.pnpm/effection@4.0.0/node_modules/effection/esm/lib/context.d.ts","../../node_modules/.pnpm/effection@4.0.0/node_modules/effection/esm/lib/scope.d.ts","../../node_modules/.pnpm/effection@4.0.0/node_modules/effection/esm/lib/suspend.d.ts","../../node_modules/.pnpm/effection@4.0.0/node_modules/effection/esm/lib/sleep.d.ts","../../node_modules/.pnpm/effection@4.0.0/node_modules/effection/esm/lib/interval.d.ts","../../node_modules/.pnpm/effection@4.0.0/node_modules/effection/esm/lib/run.d.ts","../../node_modules/.pnpm/effection@4.0.0/node_modules/effection/esm/lib/spawn.d.ts","../../node_modules/.pnpm/effection@4.0.0/node_modules/effection/esm/lib/resource.d.ts","../../node_modules/.pnpm/effection@4.0.0/node_modules/effection/esm/lib/call.d.ts","../../node_modules/.pnpm/effection@4.0.0/node_modules/effection/esm/lib/race.d.ts","../../node_modules/.pnpm/effection@4.0.0/node_modules/effection/esm/lib/all.d.ts","../../node_modules/.pnpm/effection@4.0.0/node_modules/effection/esm/lib/lift.d.ts","../../node_modules/.pnpm/effection@4.0.0/node_modules/effection/esm/lib/queue.d.ts","../../node_modules/.pnpm/effection@4.0.0/node_modules/effection/esm/lib/signal.d.ts","../../node_modules/.pnpm/effection@4.0.0/node_modules/effection/esm/lib/channel.d.ts","../../node_modules/.pnpm/effection@4.0.0/node_modules/effection/esm/lib/each.d.ts","../../node_modules/.pnpm/effection@4.0.0/node_modules/effection/esm/lib/ensure.d.ts","../../node_modules/.pnpm/effection@4.0.0/node_modules/effection/esm/lib/events.d.ts","../../node_modules/.pnpm/effection@4.0.0/node_modules/effection/esm/lib/abort-signal.d.ts","../../node_modules/.pnpm/effection@4.0.0/node_modules/effection/esm/lib/main.d.ts","../../node_modules/.pnpm/effection@4.0.0/node_modules/effection/esm/lib/with-resolvers.d.ts","../../node_modules/.pnpm/effection@4.0.0/node_modules/effection/esm/lib/async.d.ts","../../node_modules/.pnpm/effection@4.0.0/node_modules/effection/esm/lib/scoped.d.ts","../../node_modules/.pnpm/effection@4.0.0/node_modules/effection/esm/lib/until.d.ts","../../node_modules/.pnpm/effection@4.0.0/node_modules/effection/esm/lib/mod.d.ts","../../node_modules/.pnpm/effection@4.0.0/node_modules/effection/esm/mod.d.ts","../fetch.ts","../mod.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/compatibility/disposable.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/compatibility/indexable.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/compatibility/iterators.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/compatibility/index.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/globals.typedarray.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/buffer.buffer.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/globals.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/web-globals/abortcontroller.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/web-globals/domexception.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/web-globals/events.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/header.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/readable.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/file.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/fetch.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/formdata.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/connector.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/client.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/errors.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/dispatcher.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/global-dispatcher.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/global-origin.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/pool-stats.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/pool.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/handlers.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/balanced-pool.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/agent.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/mock-interceptor.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/mock-agent.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/mock-client.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/mock-pool.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/mock-errors.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/proxy-agent.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/env-http-proxy-agent.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/retry-handler.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/retry-agent.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/api.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/interceptors.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/util.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/cookies.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/patch.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/websocket.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/eventsource.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/filereader.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/diagnostics-channel.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/content-type.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/cache.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/index.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/web-globals/fetch.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/web-globals/navigator.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/web-globals/storage.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/assert.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/assert/strict.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/async_hooks.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/buffer.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/child_process.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/cluster.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/console.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/constants.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/crypto.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/dgram.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/diagnostics_channel.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/dns.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/dns/promises.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/domain.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/events.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/fs.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/fs/promises.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/http.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/http2.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/https.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/inspector.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/inspector.generated.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/module.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/net.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/os.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/path.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/perf_hooks.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/process.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/punycode.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/querystring.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/readline.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/readline/promises.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/repl.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/sea.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/sqlite.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/stream.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/stream/promises.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/stream/consumers.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/stream/web.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/string_decoder.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/test.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/timers.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/timers/promises.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/tls.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/trace_events.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/tty.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/url.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/util.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/v8.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/vm.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/wasi.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/worker_threads.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/zlib.d.ts","../../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/index.d.ts","../../node_modules/.pnpm/@types+semver@7.7.1/node_modules/@types/semver/functions/inc.d.ts","../../node_modules/.pnpm/@types+semver@7.7.1/node_modules/@types/semver/classes/semver.d.ts","../../node_modules/.pnpm/@types+semver@7.7.1/node_modules/@types/semver/functions/parse.d.ts","../../node_modules/.pnpm/@types+semver@7.7.1/node_modules/@types/semver/functions/valid.d.ts","../../node_modules/.pnpm/@types+semver@7.7.1/node_modules/@types/semver/functions/clean.d.ts","../../node_modules/.pnpm/@types+semver@7.7.1/node_modules/@types/semver/functions/diff.d.ts","../../node_modules/.pnpm/@types+semver@7.7.1/node_modules/@types/semver/functions/major.d.ts","../../node_modules/.pnpm/@types+semver@7.7.1/node_modules/@types/semver/functions/minor.d.ts","../../node_modules/.pnpm/@types+semver@7.7.1/node_modules/@types/semver/functions/patch.d.ts","../../node_modules/.pnpm/@types+semver@7.7.1/node_modules/@types/semver/functions/prerelease.d.ts","../../node_modules/.pnpm/@types+semver@7.7.1/node_modules/@types/semver/functions/compare.d.ts","../../node_modules/.pnpm/@types+semver@7.7.1/node_modules/@types/semver/functions/rcompare.d.ts","../../node_modules/.pnpm/@types+semver@7.7.1/node_modules/@types/semver/functions/compare-loose.d.ts","../../node_modules/.pnpm/@types+semver@7.7.1/node_modules/@types/semver/functions/compare-build.d.ts","../../node_modules/.pnpm/@types+semver@7.7.1/node_modules/@types/semver/functions/sort.d.ts","../../node_modules/.pnpm/@types+semver@7.7.1/node_modules/@types/semver/functions/rsort.d.ts","../../node_modules/.pnpm/@types+semver@7.7.1/node_modules/@types/semver/functions/gt.d.ts","../../node_modules/.pnpm/@types+semver@7.7.1/node_modules/@types/semver/functions/lt.d.ts","../../node_modules/.pnpm/@types+semver@7.7.1/node_modules/@types/semver/functions/eq.d.ts","../../node_modules/.pnpm/@types+semver@7.7.1/node_modules/@types/semver/functions/neq.d.ts","../../node_modules/.pnpm/@types+semver@7.7.1/node_modules/@types/semver/functions/gte.d.ts","../../node_modules/.pnpm/@types+semver@7.7.1/node_modules/@types/semver/functions/lte.d.ts","../../node_modules/.pnpm/@types+semver@7.7.1/node_modules/@types/semver/functions/cmp.d.ts","../../node_modules/.pnpm/@types+semver@7.7.1/node_modules/@types/semver/functions/coerce.d.ts","../../node_modules/.pnpm/@types+semver@7.7.1/node_modules/@types/semver/classes/comparator.d.ts","../../node_modules/.pnpm/@types+semver@7.7.1/node_modules/@types/semver/classes/range.d.ts","../../node_modules/.pnpm/@types+semver@7.7.1/node_modules/@types/semver/functions/satisfies.d.ts","../../node_modules/.pnpm/@types+semver@7.7.1/node_modules/@types/semver/ranges/max-satisfying.d.ts","../../node_modules/.pnpm/@types+semver@7.7.1/node_modules/@types/semver/ranges/min-satisfying.d.ts","../../node_modules/.pnpm/@types+semver@7.7.1/node_modules/@types/semver/ranges/to-comparators.d.ts","../../node_modules/.pnpm/@types+semver@7.7.1/node_modules/@types/semver/ranges/min-version.d.ts","../../node_modules/.pnpm/@types+semver@7.7.1/node_modules/@types/semver/ranges/valid.d.ts","../../node_modules/.pnpm/@types+semver@7.7.1/node_modules/@types/semver/ranges/outside.d.ts","../../node_modules/.pnpm/@types+semver@7.7.1/node_modules/@types/semver/ranges/gtr.d.ts","../../node_modules/.pnpm/@types+semver@7.7.1/node_modules/@types/semver/ranges/ltr.d.ts","../../node_modules/.pnpm/@types+semver@7.7.1/node_modules/@types/semver/ranges/intersects.d.ts","../../node_modules/.pnpm/@types+semver@7.7.1/node_modules/@types/semver/ranges/simplify.d.ts","../../node_modules/.pnpm/@types+semver@7.7.1/node_modules/@types/semver/ranges/subset.d.ts","../../node_modules/.pnpm/@types+semver@7.7.1/node_modules/@types/semver/internals/identifiers.d.ts","../../node_modules/.pnpm/@types+semver@7.7.1/node_modules/@types/semver/index.d.ts"],"fileIdsList":[[88,96,144,161,162],[89,96,144,161,162],[96,141,142,144,161,162],[96,143,144,161,162],[144,161,162],[96,144,149,161,162,179],[96,144,145,150,155,161,162,164,176,187],[96,144,145,146,155,161,162,164],[96,144,161,162],[91,92,93,96,144,161,162],[96,144,147,161,162,188],[96,144,148,149,156,161,162,165],[96,144,149,161,162,176,184],[96,144,150,152,155,161,162,164],[96,143,144,151,161,162],[96,144,152,153,161,162],[96,144,154,155,161,162],[96,143,144,155,161,162],[96,144,155,156,157,161,162,176,187],[96,144,155,156,157,161,162,171,176,179],[96,137,144,152,155,158,161,162,164,176,187],[96,144,155,156,158,159,161,162,164,176,184,187],[96,144,158,160,161,162,176,184,187],[94,95,96,97,98,99,100,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193],[96,144,155,161,162],[96,144,161,162,163,187],[96,144,152,155,161,162,164,176],[96,144,161,162,165],[96,144,161,162,166],[96,143,144,161,162,167],[96,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193],[96,144,161,162,169],[96,144,161,162,170],[96,144,155,161,162,171,172],[96,144,161,162,171,173,188,190],[96,144,156,161,162],[96,144,155,161,162,176,177,179],[96,144,161,162,178,179],[96,144,161,162,176,177],[96,144,161,162,179],[96,144,161,162,180],[96,141,144,161,162,176,181],[96,144,155,161,162,182,183],[96,144,161,162,182,183],[96,144,149,161,162,164,176,184],[96,144,161,162,185],[96,144,161,162,164,186],[96,144,158,161,162,170,187],[96,144,149,161,162,188],[96,144,161,162,176,189],[96,144,161,162,163,190],[96,144,161,162,191],[96,137,144,161,162],[96,137,144,155,157,161,162,167,176,179,187,189,190,192],[96,144,161,162,176,193],[96,144,161,162,196,234],[96,144,161,162,196,219,234],[96,144,161,162,195,234],[96,144,161,162,234],[96,144,161,162,196],[96,144,161,162,196,220,234],[96,144,161,162,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233],[96,144,161,162,220,234],[61,96,144,161,162],[60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,96,144,161,162],[61,75,96,144,161,162],[60,96,144,161,162],[87,96,144,161,162],[96,109,113,144,161,162,187],[96,109,144,161,162,176,187],[96,104,144,161,162],[96,106,109,144,161,162,184,187],[96,144,161,162,164,184],[96,144,161,162,194],[96,104,144,161,162,194],[96,106,109,144,161,162,164,187],[96,101,102,105,108,144,155,161,162,176,187],[96,109,116,144,161,162],[96,101,107,144,161,162],[96,109,130,131,144,161,162],[96,105,109,144,161,162,179,187,194],[96,130,144,161,162,194],[96,103,104,144,161,162,194],[96,109,144,161,162],[96,103,104,105,106,107,108,109,110,111,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,131,132,133,134,135,136,144,161,162],[96,109,124,144,161,162],[96,109,116,117,144,161,162],[96,107,109,117,118,144,161,162],[96,108,144,161,162],[96,101,104,109,144,161,162],[96,109,113,117,118,144,161,162],[96,113,144,161,162],[96,107,109,112,144,161,162,187],[96,101,106,109,116,144,161,162],[96,144,161,162,176],[96,104,109,130,144,161,162,192,194]],"fileInfos":[{"version":"c430d44666289dae81f30fa7b2edebf186ecc91a2d4c71266ea6ae76388792e1","affectsGlobalScope":true,"impliedFormat":1},{"version":"45b7ab580deca34ae9729e97c13cfd999df04416a79116c3bfb483804f85ded4","impliedFormat":1},{"version":"3facaf05f0c5fc569c5649dd359892c98a85557e3e0c847964caeb67076f4d75","impliedFormat":1},{"version":"e44bb8bbac7f10ecc786703fe0a6a4b952189f908707980ba8f3c8975a760962","impliedFormat":1},{"version":"5e1c4c362065a6b95ff952c0eab010f04dcd2c3494e813b493ecfd4fcb9fc0d8","impliedFormat":1},{"version":"68d73b4a11549f9c0b7d352d10e91e5dca8faa3322bfb77b661839c42b1ddec7","impliedFormat":1},{"version":"5efce4fc3c29ea84e8928f97adec086e3dc876365e0982cc8479a07954a3efd4","impliedFormat":1},{"version":"feecb1be483ed332fad555aff858affd90a48ab19ba7272ee084704eb7167569","impliedFormat":1},{"version":"ee7bad0c15b58988daa84371e0b89d313b762ab83cb5b31b8a2d1162e8eb41c2","impliedFormat":1},{"version":"080941d9f9ff9307f7e27a83bcd888b7c8270716c39af943532438932ec1d0b9","affectsGlobalScope":true,"impliedFormat":1},{"version":"2e80ee7a49e8ac312cc11b77f1475804bee36b3b2bc896bead8b6e1266befb43","affectsGlobalScope":true,"impliedFormat":1},{"version":"c57796738e7f83dbc4b8e65132f11a377649c00dd3eee333f672b8f0a6bea671","affectsGlobalScope":true,"impliedFormat":1},{"version":"dc2df20b1bcdc8c2d34af4926e2c3ab15ffe1160a63e58b7e09833f616efff44","affectsGlobalScope":true,"impliedFormat":1},{"version":"515d0b7b9bea2e31ea4ec968e9edd2c39d3eebf4a2d5cbd04e88639819ae3b71","affectsGlobalScope":true,"impliedFormat":1},{"version":"0559b1f683ac7505ae451f9a96ce4c3c92bdc71411651ca6ddb0e88baaaad6a3","affectsGlobalScope":true,"impliedFormat":1},{"version":"0dc1e7ceda9b8b9b455c3a2d67b0412feab00bd2f66656cd8850e8831b08b537","affectsGlobalScope":true,"impliedFormat":1},{"version":"ce691fb9e5c64efb9547083e4a34091bcbe5bdb41027e310ebba8f7d96a98671","affectsGlobalScope":true,"impliedFormat":1},{"version":"8d697a2a929a5fcb38b7a65594020fcef05ec1630804a33748829c5ff53640d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ff2a353abf8a80ee399af572debb8faab2d33ad38c4b4474cff7f26e7653b8d","affectsGlobalScope":true,"impliedFormat":1},{"version":"fb0f136d372979348d59b3f5020b4cdb81b5504192b1cacff5d1fbba29378aa1","affectsGlobalScope":true,"impliedFormat":1},{"version":"d15bea3d62cbbdb9797079416b8ac375ae99162a7fba5de2c6c505446486ac0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"68d18b664c9d32a7336a70235958b8997ebc1c3b8505f4f1ae2b7e7753b87618","affectsGlobalScope":true,"impliedFormat":1},{"version":"eb3d66c8327153d8fa7dd03f9c58d351107fe824c79e9b56b462935176cdf12a","affectsGlobalScope":true,"impliedFormat":1},{"version":"38f0219c9e23c915ef9790ab1d680440d95419ad264816fa15009a8851e79119","affectsGlobalScope":true,"impliedFormat":1},{"version":"69ab18c3b76cd9b1be3d188eaf8bba06112ebbe2f47f6c322b5105a6fbc45a2e","affectsGlobalScope":true,"impliedFormat":1},{"version":"a680117f487a4d2f30ea46f1b4b7f58bef1480456e18ba53ee85c2746eeca012","affectsGlobalScope":true,"impliedFormat":1},{"version":"2f11ff796926e0832f9ae148008138ad583bd181899ab7dd768a2666700b1893","affectsGlobalScope":true,"impliedFormat":1},{"version":"4de680d5bb41c17f7f68e0419412ca23c98d5749dcaaea1896172f06435891fc","affectsGlobalScope":true,"impliedFormat":1},{"version":"954296b30da6d508a104a3a0b5d96b76495c709785c1d11610908e63481ee667","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac9538681b19688c8eae65811b329d3744af679e0bdfa5d842d0e32524c73e1c","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a969edff4bd52585473d24995c5ef223f6652d6ef46193309b3921d65dd4376","affectsGlobalScope":true,"impliedFormat":1},{"version":"9e9fbd7030c440b33d021da145d3232984c8bb7916f277e8ffd3dc2e3eae2bdb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811ec78f7fefcabbda4bfa93b3eb67d9ae166ef95f9bff989d964061cbf81a0c","affectsGlobalScope":true,"impliedFormat":1},{"version":"717937616a17072082152a2ef351cb51f98802fb4b2fdabd32399843875974ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"d7e7d9b7b50e5f22c915b525acc5a49a7a6584cf8f62d0569e557c5cfc4b2ac2","affectsGlobalScope":true,"impliedFormat":1},{"version":"71c37f4c9543f31dfced6c7840e068c5a5aacb7b89111a4364b1d5276b852557","affectsGlobalScope":true,"impliedFormat":1},{"version":"576711e016cf4f1804676043e6a0a5414252560eb57de9faceee34d79798c850","affectsGlobalScope":true,"impliedFormat":1},{"version":"89c1b1281ba7b8a96efc676b11b264de7a8374c5ea1e6617f11880a13fc56dc6","affectsGlobalScope":true,"impliedFormat":1},{"version":"74f7fa2d027d5b33eb0471c8e82a6c87216223181ec31247c357a3e8e2fddc5b","affectsGlobalScope":true,"impliedFormat":1},{"version":"d6d7ae4d1f1f3772e2a3cde568ed08991a8ae34a080ff1151af28b7f798e22ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"063600664504610fe3e99b717a1223f8b1900087fab0b4cad1496a114744f8df","affectsGlobalScope":true,"impliedFormat":1},{"version":"934019d7e3c81950f9a8426d093458b65d5aff2c7c1511233c0fd5b941e608ab","affectsGlobalScope":true,"impliedFormat":1},{"version":"52ada8e0b6e0482b728070b7639ee42e83a9b1c22d205992756fe020fd9f4a47","affectsGlobalScope":true,"impliedFormat":1},{"version":"3bdefe1bfd4d6dee0e26f928f93ccc128f1b64d5d501ff4a8cf3c6371200e5e6","affectsGlobalScope":true,"impliedFormat":1},{"version":"59fb2c069260b4ba00b5643b907ef5d5341b167e7d1dbf58dfd895658bda2867","affectsGlobalScope":true,"impliedFormat":1},{"version":"639e512c0dfc3fad96a84caad71b8834d66329a1f28dc95e3946c9b58176c73a","affectsGlobalScope":true,"impliedFormat":1},{"version":"368af93f74c9c932edd84c58883e736c9e3d53cec1fe24c0b0ff451f529ceab1","affectsGlobalScope":true,"impliedFormat":1},{"version":"af3dd424cf267428f30ccfc376f47a2c0114546b55c44d8c0f1d57d841e28d74","affectsGlobalScope":true,"impliedFormat":1},{"version":"995c005ab91a498455ea8dfb63aa9f83fa2ea793c3d8aa344be4a1678d06d399","affectsGlobalScope":true,"impliedFormat":1},{"version":"959d36cddf5e7d572a65045b876f2956c973a586da58e5d26cde519184fd9b8a","affectsGlobalScope":true,"impliedFormat":1},{"version":"965f36eae237dd74e6cca203a43e9ca801ce38824ead814728a2807b1910117d","affectsGlobalScope":true,"impliedFormat":1},{"version":"3925a6c820dcb1a06506c90b1577db1fdbf7705d65b62b99dce4be75c637e26b","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a3d63ef2b853447ec4f749d3f368ce642264246e02911fcb1590d8c161b8005","affectsGlobalScope":true,"impliedFormat":1},{"version":"8cdf8847677ac7d20486e54dd3fcf09eda95812ac8ace44b4418da1bbbab6eb8","affectsGlobalScope":true,"impliedFormat":1},{"version":"8444af78980e3b20b49324f4a16ba35024fef3ee069a0eb67616ea6ca821c47a","affectsGlobalScope":true,"impliedFormat":1},{"version":"3287d9d085fbd618c3971944b65b4be57859f5415f495b33a6adc994edd2f004","affectsGlobalScope":true,"impliedFormat":1},{"version":"b4b67b1a91182421f5df999988c690f14d813b9850b40acd06ed44691f6727ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e7f8264d0fb4c5339605a15daadb037bf238c10b654bb3eee14208f860a32ea","affectsGlobalScope":true,"impliedFormat":1},{"version":"782dec38049b92d4e85c1585fbea5474a219c6984a35b004963b00beb1aab538","affectsGlobalScope":true,"impliedFormat":1},{"version":"e32de52f3ffc3f0215daff1a7659206129d27ff9ad6d9d238d8690f617320ae1","impliedFormat":99},{"version":"3576d56b68bbb031b5b3272df4ad1dd8c4dcabcf74a8adb7c991aab25f791e9c","impliedFormat":99},{"version":"fab327816ac28cf1416dc55d8a7a11379cf3389d041feab1705a45fa32833d37","impliedFormat":99},{"version":"ca457ee0d78324892b4c8620c0f9b98997f82b8961f001839666a0d517f05f9d","impliedFormat":99},{"version":"70300a19bf0d810196c877fc850b877f7f76c35ac0f833bd27faf1099c43a70b","impliedFormat":99},{"version":"5876b0820db56ccac866e3cdc65fc1831b45adfa4cf60a96ac241a0033b9e5f9","impliedFormat":99},{"version":"384c14dba2c101c16907a016718c5810d803141f7e387016944ff097b724f772","impliedFormat":99},{"version":"138f9e90609b865bc32a00ef663515f5cf1f99194b108fc6e7457ff9ea2c67ba","impliedFormat":99},{"version":"9b3df5b39bd7b05de2bad2de1705d91751de4bf890dc89e49907fda39b5e3985","impliedFormat":99},{"version":"681e219477b42f2d28a448385579ebade44f2c69eec101560f504a01f44caf77","impliedFormat":99},{"version":"fc2f142af29f7c4579af8767a1a042ef9a8f8ee3c7f4de4129709017c3e4d37b","impliedFormat":99},{"version":"263698308657a3a163a3902f15c649fec9d1f3a0149b3788d86e85470b37d528","impliedFormat":99},{"version":"cc597920aca8d41fa235c5b6e740c493736cedcc6018da86e4cff58f1cc07013","impliedFormat":99},{"version":"4d80236469a38bda46fca261abb6e1b1280f46a60627bdfc28bf01281fc1108c","impliedFormat":99},{"version":"0a6fd4f2fc2a8f8859b9684aefef052bdd16ac4578491de39683a17afaa92921","impliedFormat":99},{"version":"07e3a5afd9c77935503c00a777665c9da5f7c507bbd22ef9d15f58373d6d815c","impliedFormat":99},{"version":"dbf0ec15156f1f18a94cfcbe0e5ff132bf5cddd3d3715705acd92b5405e94b56","impliedFormat":99},{"version":"adac9de93c7bbb078d85defc6a14f801fabeefce49121ef57c98d57b7140047f","impliedFormat":99},{"version":"f144ec90d6d2cc4799dd69bd651102816a62445b196c302d64f3c9af780a93b8","impliedFormat":99},{"version":"ad9eb36e4ec484a4111649db56daeeb926b1ab0d10104efdedd9197f7073809f","impliedFormat":99},{"version":"e9dcace6b450961972ed1ae9737be0aa3d6e72b49301536d7fe2a39b01224730","impliedFormat":99},{"version":"83b0cc7dad96cdc9591d57b858e4af4ecacac33d55dff4b92ea6f91baa356e4d","impliedFormat":99},{"version":"cd2952ebecad4d1eaab1150ff561064bff40e4e25903ddffbdedd3643415228b","impliedFormat":99},{"version":"76e3eccb2104ea0b8aa63ab70a00c1a74a5c6aa02cb475f05dadb85fb7d237af","impliedFormat":99},{"version":"02c6ee8bad964f26fc1397aa3172aae0c17a12ba921b045811ed2ce24c3fcc41","impliedFormat":99},{"version":"997863a7254d8eadb6b9993b9c50ba196aa7510a50585dc61bcb64acad68097d","impliedFormat":99},{"version":"54ba5885d706c6cf1c98a3856a9894919cca7d38aa23839f5e76a128ea723004","impliedFormat":99},{"version":"68fda81abab3797d5e1c5ea465e621995ef711a9c0939afdb923e1b8c421e407","impliedFormat":99},{"version":"009ac8daf7b0e45eecc7856ff1302ecc1d52d9cc63e8396129e1baabf967e1a8","impliedFormat":99},{"version":"2c18f7649d787046b04b14d0befe9e06d5b9add58ccde69ab46e07ecae4d946d","signature":"7b46d093a6b9d7b09c69fc32dc1663d9816ea4b33d85c84c71fcbe55da94a04d","impliedFormat":99},{"version":"8eec4e9c8336ab91c99724fc1e147b84c10d123d50025d6562418b3a6db1a731","impliedFormat":99},{"version":"6c7176368037af28cb72f2392010fa1cef295d6d6744bca8cfb54985f3a18c3e","affectsGlobalScope":true,"impliedFormat":1},{"version":"ab41ef1f2cdafb8df48be20cd969d875602483859dc194e9c97c8a576892c052","affectsGlobalScope":true,"impliedFormat":1},{"version":"437e20f2ba32abaeb7985e0afe0002de1917bc74e949ba585e49feba65da6ca1","affectsGlobalScope":true,"impliedFormat":1},{"version":"21d819c173c0cf7cc3ce57c3276e77fd9a8a01d35a06ad87158781515c9a438a","impliedFormat":1},{"version":"98cffbf06d6bab333473c70a893770dbe990783904002c4f1a960447b4b53dca","affectsGlobalScope":true,"impliedFormat":1},{"version":"3af97acf03cc97de58a3a4bc91f8f616408099bc4233f6d0852e72a8ffb91ac9","affectsGlobalScope":true,"impliedFormat":1},{"version":"808069bba06b6768b62fd22429b53362e7af342da4a236ed2d2e1c89fcca3b4a","affectsGlobalScope":true,"impliedFormat":1},{"version":"1db0b7dca579049ca4193d034d835f6bfe73096c73663e5ef9a0b5779939f3d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"9798340ffb0d067d69b1ae5b32faa17ab31b82466a3fc00d8f2f2df0c8554aaa","affectsGlobalScope":true,"impliedFormat":1},{"version":"f26b11d8d8e4b8028f1c7d618b22274c892e4b0ef5b3678a8ccbad85419aef43","affectsGlobalScope":true,"impliedFormat":1},{"version":"5929864ce17fba74232584d90cb721a89b7ad277220627cc97054ba15a98ea8f","impliedFormat":1},{"version":"763fe0f42b3d79b440a9b6e51e9ba3f3f91352469c1e4b3b67bfa4ff6352f3f4","impliedFormat":1},{"version":"25c8056edf4314820382a5fdb4bb7816999acdcb929c8f75e3f39473b87e85bc","impliedFormat":1},{"version":"c464d66b20788266e5353b48dc4aa6bc0dc4a707276df1e7152ab0c9ae21fad8","impliedFormat":1},{"version":"78d0d27c130d35c60b5e5566c9f1e5be77caf39804636bc1a40133919a949f21","impliedFormat":1},{"version":"c6fd2c5a395f2432786c9cb8deb870b9b0e8ff7e22c029954fabdd692bff6195","impliedFormat":1},{"version":"1d6e127068ea8e104a912e42fc0a110e2aa5a66a356a917a163e8cf9a65e4a75","impliedFormat":1},{"version":"5ded6427296cdf3b9542de4471d2aa8d3983671d4cac0f4bf9c637208d1ced43","impliedFormat":1},{"version":"7f182617db458e98fc18dfb272d40aa2fff3a353c44a89b2c0ccb3937709bfb5","impliedFormat":1},{"version":"cadc8aced301244057c4e7e73fbcae534b0f5b12a37b150d80e5a45aa4bebcbd","impliedFormat":1},{"version":"385aab901643aa54e1c36f5ef3107913b10d1b5bb8cbcd933d4263b80a0d7f20","impliedFormat":1},{"version":"9670d44354bab9d9982eca21945686b5c24a3f893db73c0dae0fd74217a4c219","impliedFormat":1},{"version":"0b8a9268adaf4da35e7fa830c8981cfa22adbbe5b3f6f5ab91f6658899e657a7","impliedFormat":1},{"version":"11396ed8a44c02ab9798b7dca436009f866e8dae3c9c25e8c1fbc396880bf1bb","impliedFormat":1},{"version":"ba7bc87d01492633cb5a0e5da8a4a42a1c86270e7b3d2dea5d156828a84e4882","impliedFormat":1},{"version":"4893a895ea92c85345017a04ed427cbd6a1710453338df26881a6019432febdd","impliedFormat":1},{"version":"c21dc52e277bcfc75fac0436ccb75c204f9e1b3fa5e12729670910639f27343e","impliedFormat":1},{"version":"13f6f39e12b1518c6650bbb220c8985999020fe0f21d818e28f512b7771d00f9","impliedFormat":1},{"version":"9b5369969f6e7175740bf51223112ff209f94ba43ecd3bb09eefff9fd675624a","impliedFormat":1},{"version":"4fe9e626e7164748e8769bbf74b538e09607f07ed17c2f20af8d680ee49fc1da","impliedFormat":1},{"version":"24515859bc0b836719105bb6cc3d68255042a9f02a6022b3187948b204946bd2","impliedFormat":1},{"version":"ea0148f897b45a76544ae179784c95af1bd6721b8610af9ffa467a518a086a43","impliedFormat":1},{"version":"24c6a117721e606c9984335f71711877293a9651e44f59f3d21c1ea0856f9cc9","impliedFormat":1},{"version":"dd3273ead9fbde62a72949c97dbec2247ea08e0c6952e701a483d74ef92d6a17","impliedFormat":1},{"version":"405822be75ad3e4d162e07439bac80c6bcc6dbae1929e179cf467ec0b9ee4e2e","impliedFormat":1},{"version":"0db18c6e78ea846316c012478888f33c11ffadab9efd1cc8bcc12daded7a60b6","impliedFormat":1},{"version":"e61be3f894b41b7baa1fbd6a66893f2579bfad01d208b4ff61daef21493ef0a8","impliedFormat":1},{"version":"bd0532fd6556073727d28da0edfd1736417a3f9f394877b6d5ef6ad88fba1d1a","impliedFormat":1},{"version":"89167d696a849fce5ca508032aabfe901c0868f833a8625d5a9c6e861ef935d2","impliedFormat":1},{"version":"615ba88d0128ed16bf83ef8ccbb6aff05c3ee2db1cc0f89ab50a4939bfc1943f","impliedFormat":1},{"version":"a4d551dbf8746780194d550c88f26cf937caf8d56f102969a110cfaed4b06656","impliedFormat":1},{"version":"8bd86b8e8f6a6aa6c49b71e14c4ffe1211a0e97c80f08d2c8cc98838006e4b88","impliedFormat":1},{"version":"317e63deeb21ac07f3992f5b50cdca8338f10acd4fbb7257ebf56735bf52ab00","impliedFormat":1},{"version":"4732aec92b20fb28c5fe9ad99521fb59974289ed1e45aecb282616202184064f","impliedFormat":1},{"version":"2e85db9e6fd73cfa3d7f28e0ab6b55417ea18931423bd47b409a96e4a169e8e6","impliedFormat":1},{"version":"c46e079fe54c76f95c67fb89081b3e399da2c7d109e7dca8e4b58d83e332e605","impliedFormat":1},{"version":"bf67d53d168abc1298888693338cb82854bdb2e69ef83f8a0092093c2d562107","impliedFormat":1},{"version":"2cbe0621042e2a68c7cbce5dfed3906a1862a16a7d496010636cdbdb91341c0f","affectsGlobalScope":true,"impliedFormat":1},{"version":"f9501cc13ce624c72b61f12b3963e84fad210fbdf0ffbc4590e08460a3f04eba","affectsGlobalScope":true,"impliedFormat":1},{"version":"e7721c4f69f93c91360c26a0a84ee885997d748237ef78ef665b153e622b36c1","affectsGlobalScope":true,"impliedFormat":1},{"version":"0fa06ada475b910e2106c98c68b10483dc8811d0c14a8a8dd36efb2672485b29","impliedFormat":1},{"version":"33e5e9aba62c3193d10d1d33ae1fa75c46a1171cf76fef750777377d53b0303f","impliedFormat":1},{"version":"2b06b93fd01bcd49d1a6bd1f9b65ddcae6480b9a86e9061634d6f8e354c1468f","impliedFormat":1},{"version":"6a0cd27e5dc2cfbe039e731cf879d12b0e2dded06d1b1dedad07f7712de0d7f4","affectsGlobalScope":true,"impliedFormat":1},{"version":"13f5c844119c43e51ce777c509267f14d6aaf31eafb2c2b002ca35584cd13b29","impliedFormat":1},{"version":"e60477649d6ad21542bd2dc7e3d9ff6853d0797ba9f689ba2f6653818999c264","impliedFormat":1},{"version":"c2510f124c0293ab80b1777c44d80f812b75612f297b9857406468c0f4dafe29","affectsGlobalScope":true,"impliedFormat":1},{"version":"5524481e56c48ff486f42926778c0a3cce1cc85dc46683b92b1271865bcf015a","impliedFormat":1},{"version":"4c829ab315f57c5442c6667b53769975acbf92003a66aef19bce151987675bd1","affectsGlobalScope":true,"impliedFormat":1},{"version":"b2ade7657e2db96d18315694789eff2ddd3d8aea7215b181f8a0b303277cc579","impliedFormat":1},{"version":"9855e02d837744303391e5623a531734443a5f8e6e8755e018c41d63ad797db2","impliedFormat":1},{"version":"4d631b81fa2f07a0e63a9a143d6a82c25c5f051298651a9b69176ba28930756d","impliedFormat":1},{"version":"836a356aae992ff3c28a0212e3eabcb76dd4b0cc06bcb9607aeef560661b860d","impliedFormat":1},{"version":"1e0d1f8b0adfa0b0330e028c7941b5a98c08b600efe7f14d2d2a00854fb2f393","impliedFormat":1},{"version":"41670ee38943d9cbb4924e436f56fc19ee94232bc96108562de1a734af20dc2c","affectsGlobalScope":true,"impliedFormat":1},{"version":"c906fb15bd2aabc9ed1e3f44eb6a8661199d6c320b3aa196b826121552cb3695","impliedFormat":1},{"version":"22295e8103f1d6d8ea4b5d6211e43421fe4564e34d0dd8e09e520e452d89e659","impliedFormat":1},{"version":"bb45cd435da536500f1d9692a9b49d0c570b763ccbf00473248b777f5c1f353b","impliedFormat":1},{"version":"6b4e081d55ac24fc8a4631d5dd77fe249fa25900abd7d046abb87d90e3b45645","impliedFormat":1},{"version":"a10f0e1854f3316d7ee437b79649e5a6ae3ae14ffe6322b02d4987071a95362e","impliedFormat":1},{"version":"e208f73ef6a980104304b0d2ca5f6bf1b85de6009d2c7e404028b875020fa8f2","impliedFormat":1},{"version":"d163b6bc2372b4f07260747cbc6c0a6405ab3fbcea3852305e98ac43ca59f5bc","impliedFormat":1},{"version":"e6fa9ad47c5f71ff733744a029d1dc472c618de53804eae08ffc243b936f87ff","affectsGlobalScope":true,"impliedFormat":1},{"version":"83e63d6ccf8ec004a3bb6d58b9bb0104f60e002754b1e968024b320730cc5311","impliedFormat":1},{"version":"24826ed94a78d5c64bd857570fdbd96229ad41b5cb654c08d75a9845e3ab7dde","impliedFormat":1},{"version":"8b479a130ccb62e98f11f136d3ac80f2984fdc07616516d29881f3061f2dd472","impliedFormat":1},{"version":"928af3d90454bf656a52a48679f199f64c1435247d6189d1caf4c68f2eaf921f","affectsGlobalScope":true,"impliedFormat":1},{"version":"d2bc7425ef40526650d6db7e072c1ff4a51101c3ac2cc4b666623b19496a6e27","affectsGlobalScope":true,"impliedFormat":1},{"version":"3f16a7e4deafa527ed9995a772bb380eb7d3c2c0fd4ae178c5263ed18394db2c","impliedFormat":1},{"version":"933921f0bb0ec12ef45d1062a1fc0f27635318f4d294e4d99de9a5493e618ca2","impliedFormat":1},{"version":"71a0f3ad612c123b57239a7749770017ecfe6b66411488000aba83e4546fde25","impliedFormat":1},{"version":"77fbe5eecb6fac4b6242bbf6eebfc43e98ce5ccba8fa44e0ef6a95c945ff4d98","impliedFormat":1},{"version":"4f9d8ca0c417b67b69eeb54c7ca1bedd7b56034bb9bfd27c5d4f3bc4692daca7","impliedFormat":1},{"version":"814118df420c4e38fe5ae1b9a3bafb6e9c2aa40838e528cde908381867be6466","impliedFormat":1},{"version":"a3fc63c0d7b031693f665f5494412ba4b551fe644ededccc0ab5922401079c95","impliedFormat":1},{"version":"f27524f4bef4b6519c604bdb23bf4465bddcccbf3f003abb901acbd0d7404d99","impliedFormat":1},{"version":"37ba7b45141a45ce6e80e66f2a96c8a5ab1bcef0fc2d0f56bb58df96ec67e972","impliedFormat":1},{"version":"45650f47bfb376c8a8ed39d4bcda5902ab899a3150029684ee4c10676d9fbaee","impliedFormat":1},{"version":"dba28a419aec76ed864ef43e5f577a5c99a010c32e5949fe4e17a4d57c58dd11","affectsGlobalScope":true,"impliedFormat":1},{"version":"18fd40412d102c5564136f29735e5d1c3b455b8a37f920da79561f1fde068208","impliedFormat":1},{"version":"c959a391a75be9789b43c8468f71e3fa06488b4d691d5729dde1416dcd38225b","impliedFormat":1},{"version":"f0be1b8078cd549d91f37c30c222c2a187ac1cf981d994fb476a1adc61387b14","affectsGlobalScope":true,"impliedFormat":1},{"version":"0aaed1d72199b01234152f7a60046bc947f1f37d78d182e9ae09c4289e06a592","impliedFormat":1},{"version":"0dba70b3fb0dcd713fda33c2df64fa6751fff6460e536971cee917260fb17882","impliedFormat":1},{"version":"66ba1b2c3e3a3644a1011cd530fb444a96b1b2dfe2f5e837a002d41a1a799e60","impliedFormat":1},{"version":"7e514f5b852fdbc166b539fdd1f4e9114f29911592a5eb10a94bb3a13ccac3c4","impliedFormat":1},{"version":"5b7aa3c4c1a5d81b411e8cb302b45507fea9358d3569196b27eb1a27ae3a90ef","affectsGlobalScope":true,"impliedFormat":1},{"version":"5987a903da92c7462e0b35704ce7da94d7fdc4b89a984871c0e2b87a8aae9e69","affectsGlobalScope":true,"impliedFormat":1},{"version":"ea08a0345023ade2b47fbff5a76d0d0ed8bff10bc9d22b83f40858a8e941501c","impliedFormat":1},{"version":"47613031a5a31510831304405af561b0ffaedb734437c595256bb61a90f9311b","impliedFormat":1},{"version":"ae062ce7d9510060c5d7e7952ae379224fb3f8f2dd74e88959878af2057c143b","impliedFormat":1},{"version":"8a1a0d0a4a06a8d278947fcb66bf684f117bf147f89b06e50662d79a53be3e9f","affectsGlobalScope":true,"impliedFormat":1},{"version":"9f663c2f91127ef7024e8ca4b3b4383ff2770e5f826696005de382282794b127","impliedFormat":1},{"version":"9f55299850d4f0921e79b6bf344b47c420ce0f507b9dcf593e532b09ea7eeea1","impliedFormat":1},{"version":"ce6a3f09b8db73a7e9701aca91a04b4fabaf77436dd35b24482f9ee816016b17","impliedFormat":1},{"version":"20e086e5b64fdd52396de67761cc0e94693494deadb731264aac122adf08de3f","impliedFormat":1},{"version":"6e78f75403b3ec65efb41c70d392aeda94360f11cedc9fb2c039c9ea23b30962","impliedFormat":1},{"version":"c863198dae89420f3c552b5a03da6ed6d0acfa3807a64772b895db624b0de707","impliedFormat":1},{"version":"8b03a5e327d7db67112ebbc93b4f744133eda2c1743dbb0a990c61a8007823ef","impliedFormat":1},{"version":"42fad1f540271e35ca37cecda12c4ce2eef27f0f5cf0f8dd761d723c744d3159","impliedFormat":1},{"version":"ff3743a5de32bee10906aff63d1de726f6a7fd6ee2da4b8229054dfa69de2c34","impliedFormat":1},{"version":"83acd370f7f84f203e71ebba33ba61b7f1291ca027d7f9a662c6307d74e4ac22","impliedFormat":1},{"version":"1445cec898f90bdd18b2949b9590b3c012f5b7e1804e6e329fb0fe053946d5ec","impliedFormat":1},{"version":"0e5318ec2275d8da858b541920d9306650ae6ac8012f0e872fe66eb50321a669","impliedFormat":1},{"version":"cf530297c3fb3a92ec9591dd4fa229d58b5981e45fe6702a0bd2bea53a5e59be","impliedFormat":1},{"version":"c1f6f7d08d42148ddfe164d36d7aba91f467dbcb3caa715966ff95f55048b3a4","impliedFormat":1},{"version":"eefd2bbc8edb14c3bd1246794e5c070a80f9b8f3730bd42efb80df3cc50b9039","impliedFormat":1},{"version":"0c1ee27b8f6a00097c2d6d91a21ee4d096ab52c1e28350f6362542b55380059a","impliedFormat":1},{"version":"7677d5b0db9e020d3017720f853ba18f415219fb3a9597343b1b1012cfd699f7","impliedFormat":1},{"version":"bc1c6bc119c1784b1a2be6d9c47addec0d83ef0d52c8fbe1f14a51b4dfffc675","impliedFormat":1},{"version":"52cf2ce99c2a23de70225e252e9822a22b4e0adb82643ab0b710858810e00bf1","impliedFormat":1},{"version":"770625067bb27a20b9826255a8d47b6b5b0a2d3dfcbd21f89904c731f671ba77","impliedFormat":1},{"version":"d1ed6765f4d7906a05968fb5cd6d1db8afa14dbe512a4884e8ea5c0f5e142c80","impliedFormat":1},{"version":"799c0f1b07c092626cf1efd71d459997635911bb5f7fc1196efe449bba87e965","impliedFormat":1},{"version":"2a184e4462b9914a30b1b5c41cf80c6d3428f17b20d3afb711fff3f0644001fd","impliedFormat":1},{"version":"9eabde32a3aa5d80de34af2c2206cdc3ee094c6504a8d0c2d6d20c7c179503cc","impliedFormat":1},{"version":"397c8051b6cfcb48aa22656f0faca2553c5f56187262135162ee79d2b2f6c966","impliedFormat":1},{"version":"a8ead142e0c87dcd5dc130eba1f8eeed506b08952d905c47621dc2f583b1bff9","impliedFormat":1},{"version":"a02f10ea5f73130efca046429254a4e3c06b5475baecc8f7b99a0014731be8b3","impliedFormat":1},{"version":"c2576a4083232b0e2d9bd06875dd43d371dee2e090325a9eac0133fd5650c1cb","impliedFormat":1},{"version":"4c9a0564bb317349de6a24eb4efea8bb79898fa72ad63a1809165f5bd42970dd","impliedFormat":1},{"version":"f40ac11d8859092d20f953aae14ba967282c3bb056431a37fced1866ec7a2681","impliedFormat":1},{"version":"cc11e9e79d4746cc59e0e17473a59d6f104692fd0eeea1bdb2e206eabed83b03","impliedFormat":1},{"version":"b444a410d34fb5e98aa5ee2b381362044f4884652e8bc8a11c8fe14bbd85518e","impliedFormat":1},{"version":"c35808c1f5e16d2c571aa65067e3cb95afeff843b259ecfa2fc107a9519b5392","impliedFormat":1},{"version":"14d5dc055143e941c8743c6a21fa459f961cbc3deedf1bfe47b11587ca4b3ef5","impliedFormat":1},{"version":"a3ad4e1fc542751005267d50a6298e6765928c0c3a8dce1572f2ba6ca518661c","impliedFormat":1},{"version":"f237e7c97a3a89f4591afd49ecb3bd8d14f51a1c4adc8fcae3430febedff5eb6","impliedFormat":1},{"version":"3ffdfbec93b7aed71082af62b8c3e0cc71261cc68d796665faa1e91604fbae8f","impliedFormat":1},{"version":"662201f943ed45b1ad600d03a90dffe20841e725203ced8b708c91fcd7f9379a","impliedFormat":1},{"version":"c9ef74c64ed051ea5b958621e7fb853fe3b56e8787c1587aefc6ea988b3c7e79","impliedFormat":1},{"version":"2462ccfac5f3375794b861abaa81da380f1bbd9401de59ffa43119a0b644253d","impliedFormat":1},{"version":"34baf65cfee92f110d6653322e2120c2d368ee64b3c7981dff08ed105c4f19b0","impliedFormat":1},{"version":"a56fe175741cc8841835eb72e61fa5a34adcbc249ede0e3494c229f0750f6b85","impliedFormat":1}],"root":[89,90],"options":{"composite":true,"declaration":true,"declarationMap":true,"module":199,"outDir":"./","rewriteRelativeImportExtensions":true,"rootDir":"..","skipLibCheck":true,"strict":true,"target":9},"referencedMap":[[89,1],[90,2],[141,3],[142,3],[143,4],[96,5],[144,6],[145,7],[146,8],[91,9],[94,10],[92,9],[93,9],[147,11],[148,12],[149,13],[150,14],[151,15],[152,16],[153,16],[154,17],[155,18],[156,19],[157,20],[97,9],[95,9],[158,21],[159,22],[160,23],[194,24],[161,25],[162,9],[163,26],[164,27],[165,28],[166,29],[167,30],[168,31],[169,32],[170,33],[171,34],[172,34],[173,35],[174,9],[175,36],[176,37],[178,38],[177,39],[179,40],[180,41],[181,42],[182,43],[183,44],[184,45],[185,46],[186,47],[187,48],[188,49],[189,50],[190,51],[191,52],[98,9],[99,9],[100,9],[138,53],[139,9],[140,9],[192,54],[193,55],[219,56],[220,57],[196,58],[199,59],[217,56],[218,56],[208,56],[207,60],[205,56],[200,56],[213,56],[211,56],[215,56],[195,56],[212,56],[216,56],[201,56],[202,56],[214,56],[197,56],[203,56],[204,56],[206,56],[210,56],[221,61],[209,56],[198,56],[234,62],[233,9],[228,61],[230,63],[229,61],[222,61],[223,61],[225,61],[227,61],[231,63],[232,63],[224,63],[226,63],[81,64],[62,64],[73,64],[84,64],[71,64],[77,64],[63,64],[78,64],[79,64],[80,64],[67,64],[74,64],[82,64],[87,65],[75,64],[72,64],[70,64],[60,9],[68,64],[64,64],[85,64],[76,66],[66,64],[69,64],[65,64],[61,67],[86,64],[83,64],[88,68],[58,9],[59,9],[10,9],[11,9],[13,9],[12,9],[2,9],[14,9],[15,9],[16,9],[17,9],[18,9],[19,9],[20,9],[21,9],[3,9],[22,9],[23,9],[4,9],[24,9],[28,9],[25,9],[26,9],[27,9],[29,9],[30,9],[31,9],[5,9],[32,9],[33,9],[34,9],[35,9],[6,9],[39,9],[36,9],[37,9],[38,9],[40,9],[7,9],[41,9],[46,9],[47,9],[42,9],[43,9],[44,9],[45,9],[8,9],[51,9],[48,9],[49,9],[50,9],[52,9],[9,9],[53,9],[54,9],[55,9],[57,9],[56,9],[1,9],[116,69],[126,70],[115,69],[136,71],[107,72],[106,73],[135,74],[129,75],[134,76],[109,77],[123,78],[108,79],[132,80],[104,81],[103,74],[133,82],[105,83],[110,84],[111,9],[114,84],[101,9],[137,85],[127,86],[118,87],[119,88],[121,89],[117,90],[120,91],[130,74],[112,92],[113,93],[122,94],[102,95],[125,86],[124,84],[128,9],[131,96]],"latestChangedDtsFile":"./mod.d.ts","version":"5.9.3"}
package/fetch.test.ts ADDED
@@ -0,0 +1,200 @@
1
+ import { beforeEach, describe, it } from "@effectionx/bdd";
2
+ import { expect } from "expect";
3
+
4
+ import {
5
+ type IncomingMessage,
6
+ type ServerResponse,
7
+ createServer,
8
+ } from "node:http";
9
+ import {
10
+ Err,
11
+ Ok,
12
+ type Operation,
13
+ type Result,
14
+ call,
15
+ each,
16
+ ensure,
17
+ withResolvers,
18
+ } from "effection";
19
+
20
+ import { HttpError, fetch } from "./fetch.ts";
21
+
22
+ function box<T>(content: () => Operation<T>): Operation<Result<T>> {
23
+ return {
24
+ *[Symbol.iterator]() {
25
+ try {
26
+ return Ok(yield* content());
27
+ } catch (error) {
28
+ return Err(error as Error);
29
+ }
30
+ },
31
+ };
32
+ }
33
+
34
+ describe("fetch()", () => {
35
+ let url: string;
36
+
37
+ beforeEach(function* () {
38
+ let server = createServer((req: IncomingMessage, res: ServerResponse) => {
39
+ if (req.url === "/json") {
40
+ res.writeHead(200, { "Content-Type": "application/json" });
41
+ res.end(JSON.stringify({ id: 1, title: "do things" }));
42
+ return;
43
+ }
44
+
45
+ if (req.url === "/text") {
46
+ res.writeHead(200, { "Content-Type": "text/plain" });
47
+ res.end("hello");
48
+ return;
49
+ }
50
+
51
+ if (req.url === "/stream") {
52
+ res.writeHead(200, { "Content-Type": "application/octet-stream" });
53
+ res.write("chunk-1");
54
+ res.write("chunk-2");
55
+ res.end("chunk-3");
56
+ return;
57
+ }
58
+
59
+ res.writeHead(404, { "Content-Type": "text/plain" });
60
+ res.end("not found");
61
+ });
62
+
63
+ let ready = withResolvers<void>();
64
+ server.listen(0, () => ready.resolve());
65
+ yield* ready.operation;
66
+
67
+ let addr = server.address();
68
+ let port = typeof addr === "object" && addr ? addr.port : 0;
69
+
70
+ url = `http://localhost:${port}`;
71
+ yield* ensure(() =>
72
+ call(() => new Promise<void>((resolve) => server.close(() => resolve()))),
73
+ );
74
+ });
75
+
76
+ describe("traditional API", () => {
77
+ it("reads JSON responses", function* () {
78
+ let response = yield* fetch(`${url}/json`);
79
+ let data = yield* response.json<{ id: number; title: string }>();
80
+
81
+ expect(data).toEqual({ id: 1, title: "do things" });
82
+ });
83
+
84
+ it("supports parser-based json()", function* () {
85
+ let response = yield* fetch(`${url}/json`);
86
+ let data = yield* response.json((value) => {
87
+ if (
88
+ typeof value !== "object" ||
89
+ value === null ||
90
+ !("id" in value) ||
91
+ !("title" in value)
92
+ ) {
93
+ throw new Error("invalid payload");
94
+ }
95
+
96
+ return { id: value.id as number, title: value.title as string };
97
+ });
98
+
99
+ expect(data).toEqual({ id: 1, title: "do things" });
100
+ });
101
+
102
+ it("streams response bodies", function* () {
103
+ let response = yield* fetch(`${url}/stream`);
104
+ let body = response.body();
105
+ let decoder = new TextDecoder();
106
+ let chunks: string[] = [];
107
+
108
+ for (let chunk of yield* each(body)) {
109
+ chunks.push(decoder.decode(chunk, { stream: true }));
110
+ yield* each.next();
111
+ }
112
+
113
+ chunks.push(decoder.decode());
114
+ expect(chunks.join("")).toEqual("chunk-1chunk-2chunk-3");
115
+ });
116
+
117
+ it("throws HttpError for expect() when response is not ok", function* () {
118
+ let response = yield* fetch(`${url}/missing`);
119
+ let result = yield* box(() => response.expect());
120
+
121
+ expect(result.ok).toBe(false);
122
+ if (!result.ok) {
123
+ expect(result.error).toBeInstanceOf(HttpError);
124
+ expect(result.error).toMatchObject({
125
+ status: 404,
126
+ statusText: "Not Found",
127
+ });
128
+ }
129
+ });
130
+ });
131
+
132
+ describe("fluent API", () => {
133
+ it("reads JSON with fetch().json()", function* () {
134
+ let data = yield* fetch(`${url}/json`).json<{
135
+ id: number;
136
+ title: string;
137
+ }>();
138
+
139
+ expect(data).toEqual({ id: 1, title: "do things" });
140
+ });
141
+
142
+ it("reads text with fetch().text()", function* () {
143
+ let text = yield* fetch(`${url}/text`).text();
144
+
145
+ expect(text).toEqual("hello");
146
+ });
147
+
148
+ it("supports parser with fetch().json(parse)", function* () {
149
+ let data = yield* fetch(`${url}/json`).json((value) => {
150
+ if (
151
+ typeof value !== "object" ||
152
+ value === null ||
153
+ !("id" in value) ||
154
+ !("title" in value)
155
+ ) {
156
+ throw new Error("invalid payload");
157
+ }
158
+
159
+ return { id: value.id as number, title: value.title as string };
160
+ });
161
+
162
+ expect(data).toEqual({ id: 1, title: "do things" });
163
+ });
164
+
165
+ it("streams response bodies with fetch().body()", function* () {
166
+ let body = fetch(`${url}/stream`).body();
167
+ let decoder = new TextDecoder();
168
+ let chunks: string[] = [];
169
+
170
+ for (let chunk of yield* each(body)) {
171
+ chunks.push(decoder.decode(chunk, { stream: true }));
172
+ yield* each.next();
173
+ }
174
+
175
+ chunks.push(decoder.decode());
176
+ expect(chunks.join("")).toEqual("chunk-1chunk-2chunk-3");
177
+ });
178
+
179
+ it("throws HttpError with fetch().expect().json()", function* () {
180
+ let result = yield* box(() => fetch(`${url}/missing`).expect().json());
181
+
182
+ expect(result.ok).toBe(false);
183
+ if (!result.ok) {
184
+ expect(result.error).toBeInstanceOf(HttpError);
185
+ expect(result.error).toMatchObject({
186
+ status: 404,
187
+ statusText: "Not Found",
188
+ });
189
+ }
190
+ });
191
+
192
+ it("chains expect() before json() successfully", function* () {
193
+ let data = yield* fetch(`${url}/json`)
194
+ .expect()
195
+ .json<{ id: number; title: string }>();
196
+
197
+ expect(data).toEqual({ id: 1, title: "do things" });
198
+ });
199
+ });
200
+ });
package/fetch.ts ADDED
@@ -0,0 +1,300 @@
1
+ import {
2
+ stream,
3
+ type Operation,
4
+ type Stream,
5
+ until,
6
+ useAbortSignal,
7
+ } from "effection";
8
+
9
+ /**
10
+ * Request options for fetch, excluding `signal` since cancellation
11
+ * is handled automatically via Effection's structured concurrency.
12
+ */
13
+ export type FetchInit = Omit<RequestInit, "signal"> & { signal?: never };
14
+
15
+ /**
16
+ * Chainable fetch operation that supports fluent API.
17
+ *
18
+ * Can be yielded directly to get a {@link FetchResponse}, or chained
19
+ * with methods like `.json()`, `.text()`, `.body()` for direct consumption.
20
+ *
21
+ * @example
22
+ * ```ts
23
+ * // Fluent API - single yield*
24
+ * let data = yield* fetch("/api/users").json();
25
+ *
26
+ * // With validation - throws HttpError on non-2xx
27
+ * let data = yield* fetch("/api/users").expect().json();
28
+ *
29
+ * // Traditional API - get response first
30
+ * let response = yield* fetch("/api/users");
31
+ * let data = yield* response.json();
32
+ * ```
33
+ */
34
+ export interface FetchOperation extends Operation<FetchResponse> {
35
+ /** Parse response body as JSON. */
36
+ json<T = unknown>(): Operation<T>;
37
+ /** Parse response body as JSON with a custom parser. */
38
+ json<T>(parse: (value: unknown) => T): Operation<T>;
39
+ /** Get response body as text. */
40
+ text(): Operation<string>;
41
+ /** Get response body as ArrayBuffer. */
42
+ arrayBuffer(): Operation<ArrayBuffer>;
43
+ /** Get response body as Blob. */
44
+ blob(): Operation<Blob>;
45
+ /** Get response body as FormData. */
46
+ formData(): Operation<FormData>;
47
+ /** Stream response body as chunks. */
48
+ body(): Stream<Uint8Array, void>;
49
+ /** Return a new FetchOperation that throws {@link HttpError} on non-2xx responses. */
50
+ expect(): FetchOperation;
51
+ }
52
+
53
+ /**
54
+ * Effection wrapper around the native {@link Response} object.
55
+ *
56
+ * Provides operation-based methods for consuming the response body,
57
+ * and exposes common response properties.
58
+ */
59
+ export interface FetchResponse {
60
+ /** The underlying native Response object. */
61
+ readonly raw: Response;
62
+ /** Whether the response body has been consumed. */
63
+ readonly bodyUsed: boolean;
64
+ /** Whether the response status is in the 200-299 range. */
65
+ readonly ok: boolean;
66
+ /** The HTTP status code. */
67
+ readonly status: number;
68
+ /** The HTTP status message. */
69
+ readonly statusText: string;
70
+ /** The response headers. */
71
+ readonly headers: Headers;
72
+ /** The final URL after redirects. */
73
+ readonly url: string;
74
+ /** Whether the response was redirected. */
75
+ readonly redirected: boolean;
76
+ /** The response type (e.g., "basic", "cors"). */
77
+ readonly type: ResponseType;
78
+ /** Parse response body as JSON. */
79
+ json<T = unknown>(): Operation<T>;
80
+ /** Parse response body as JSON with a custom parser. */
81
+ json<T>(parse: (value: unknown) => T): Operation<T>;
82
+ /** Get response body as text. */
83
+ text(): Operation<string>;
84
+ /** Get response body as ArrayBuffer. */
85
+ arrayBuffer(): Operation<ArrayBuffer>;
86
+ /** Get response body as Blob. */
87
+ blob(): Operation<Blob>;
88
+ /** Get response body as FormData. */
89
+ formData(): Operation<FormData>;
90
+ /** Stream response body as chunks. */
91
+ body(): Stream<Uint8Array, void>;
92
+ /** Throw {@link HttpError} if response is not ok (non-2xx status). */
93
+ expect(): Operation<this>;
94
+ }
95
+
96
+ /**
97
+ * Error thrown when an HTTP response has a non-2xx status code.
98
+ *
99
+ * Thrown by {@link FetchOperation.expect} and {@link FetchResponse.expect}
100
+ * when the response is not ok.
101
+ */
102
+ export class HttpError extends Error {
103
+ readonly name = "HttpError";
104
+ /** The HTTP status code. */
105
+ readonly status: number;
106
+ /** The HTTP status message. */
107
+ readonly statusText: string;
108
+ /** The request URL. */
109
+ readonly url: string;
110
+ /** The response that triggered this error. */
111
+ readonly response: FetchResponse;
112
+
113
+ constructor(
114
+ status: number,
115
+ statusText: string,
116
+ url: string,
117
+ response: FetchResponse,
118
+ ) {
119
+ super(`HTTP ${status}: ${statusText}`);
120
+ Object.setPrototypeOf(this, new.target.prototype);
121
+ this.status = status;
122
+ this.statusText = statusText;
123
+ this.url = url;
124
+ this.response = response;
125
+ }
126
+ }
127
+
128
+ /**
129
+ * Perform an HTTP request using the Fetch API with Effection structured concurrency.
130
+ *
131
+ * Cancellation is automatically handled via the current Effection scope.
132
+ * When the scope exits, the request is aborted.
133
+ *
134
+ * @param input - The URL or Request object
135
+ * @param init - Optional request configuration (same as RequestInit, but without signal)
136
+ * @returns A chainable {@link FetchOperation}
137
+ *
138
+ * @example
139
+ * ```ts
140
+ * // Simple GET request
141
+ * let data = yield* fetch("https://api.example.com/users").json();
142
+ *
143
+ * // POST request with body
144
+ * let result = yield* fetch("https://api.example.com/users", {
145
+ * method: "POST",
146
+ * headers: { "Content-Type": "application/json" },
147
+ * body: JSON.stringify({ name: "Alice" }),
148
+ * }).expect().json();
149
+ *
150
+ * // Stream response body
151
+ * for (let chunk of yield* each(fetch("/large-file").body())) {
152
+ * console.log(chunk.length);
153
+ * yield* each.next();
154
+ * }
155
+ * ```
156
+ */
157
+ export function fetch(
158
+ input: RequestInfo | URL,
159
+ init?: FetchInit,
160
+ ): FetchOperation {
161
+ return createFetchOperation(input, init, false);
162
+ }
163
+
164
+ function createFetchOperation(
165
+ input: RequestInfo | URL,
166
+ init: FetchInit | undefined,
167
+ shouldExpect: boolean,
168
+ ): FetchOperation {
169
+ function* doFetch(): Operation<FetchResponse> {
170
+ let signal = yield* useAbortSignal();
171
+
172
+ let response = yield* until(globalThis.fetch(input, { ...init, signal }));
173
+ let fetchResponse = createFetchResponse(response);
174
+
175
+ if (shouldExpect && !response.ok) {
176
+ throw new HttpError(
177
+ response.status,
178
+ response.statusText,
179
+ response.url,
180
+ fetchResponse,
181
+ );
182
+ }
183
+
184
+ return fetchResponse;
185
+ }
186
+
187
+ return {
188
+ *[Symbol.iterator]() {
189
+ return yield* doFetch();
190
+ },
191
+
192
+ *json<T = unknown>(parse?: (value: unknown) => T): Operation<T> {
193
+ let response = yield* doFetch();
194
+ return yield* response.json(parse as (value: unknown) => T);
195
+ },
196
+
197
+ *text(): Operation<string> {
198
+ let response = yield* doFetch();
199
+ return yield* response.text();
200
+ },
201
+
202
+ *arrayBuffer(): Operation<ArrayBuffer> {
203
+ let response = yield* doFetch();
204
+ return yield* response.arrayBuffer();
205
+ },
206
+
207
+ *blob(): Operation<Blob> {
208
+ let response = yield* doFetch();
209
+ return yield* response.blob();
210
+ },
211
+
212
+ *formData(): Operation<FormData> {
213
+ let response = yield* doFetch();
214
+ return yield* response.formData();
215
+ },
216
+
217
+ body(): Stream<Uint8Array, void> {
218
+ return {
219
+ *[Symbol.iterator]() {
220
+ let response = yield* doFetch();
221
+ return yield* response.body();
222
+ },
223
+ };
224
+ },
225
+
226
+ expect(): FetchOperation {
227
+ return createFetchOperation(input, init, true);
228
+ },
229
+ };
230
+ }
231
+
232
+ function createFetchResponse(response: Response): FetchResponse {
233
+ let self: FetchResponse = {
234
+ get ok() {
235
+ return response.ok;
236
+ },
237
+ get status() {
238
+ return response.status;
239
+ },
240
+ get statusText() {
241
+ return response.statusText;
242
+ },
243
+ get headers() {
244
+ return response.headers;
245
+ },
246
+ get url() {
247
+ return response.url;
248
+ },
249
+ get redirected() {
250
+ return response.redirected;
251
+ },
252
+ get type() {
253
+ return response.type;
254
+ },
255
+ get bodyUsed() {
256
+ return response.bodyUsed;
257
+ },
258
+ get raw() {
259
+ return response;
260
+ },
261
+ *json<T = unknown>(parse?: (value: unknown) => T): Operation<T> {
262
+ let value: unknown = yield* until(response.json());
263
+ return parse ? parse(value) : (value as T);
264
+ },
265
+ *text(): Operation<string> {
266
+ return yield* until(response.text());
267
+ },
268
+ *arrayBuffer(): Operation<ArrayBuffer> {
269
+ return yield* until(response.arrayBuffer());
270
+ },
271
+ *blob(): Operation<Blob> {
272
+ return yield* until(response.blob());
273
+ },
274
+ *formData(): Operation<FormData> {
275
+ return yield* until(response.formData());
276
+ },
277
+ body(): Stream<Uint8Array, void> {
278
+ if (!response.body) {
279
+ throw new Error("Response has no body");
280
+ }
281
+
282
+ return stream(
283
+ response.body as unknown as AsyncIterable<Uint8Array, void>,
284
+ );
285
+ },
286
+ *expect(): Operation<FetchResponse> {
287
+ if (!response.ok) {
288
+ throw new HttpError(
289
+ response.status,
290
+ response.statusText,
291
+ response.url,
292
+ self,
293
+ );
294
+ }
295
+ return self;
296
+ },
297
+ };
298
+
299
+ return self;
300
+ }
package/mod.ts ADDED
@@ -0,0 +1 @@
1
+ export * from "./fetch.ts";
package/package.json ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "@effectionx/fetch",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "main": "./dist/mod.js",
6
+ "types": "./dist/mod.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "development": "./mod.ts",
10
+ "default": "./dist/mod.js"
11
+ }
12
+ },
13
+ "peerDependencies": {
14
+ "effection": "^3 || ^4"
15
+ },
16
+ "license": "MIT",
17
+ "author": "engineering@frontside.com",
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git+https://github.com/thefrontside/effectionx.git"
21
+ },
22
+ "bugs": {
23
+ "url": "https://github.com/thefrontside/effectionx/issues"
24
+ },
25
+ "engines": {
26
+ "node": ">= 22"
27
+ },
28
+ "sideEffects": false,
29
+ "devDependencies": {
30
+ "@effectionx/bdd": "0.4.2"
31
+ }
32
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,11 @@
1
+ {
2
+ "extends": "../tsconfig.json",
3
+ "compilerOptions": {
4
+ "outDir": "dist",
5
+ "rootDir": ".",
6
+ "lib": ["ES2022", "DOM", "DOM.Iterable"]
7
+ },
8
+ "include": ["**/*.ts"],
9
+ "exclude": ["**/*.test.ts", "dist"],
10
+ "references": [{ "path": "../bdd" }]
11
+ }