@evolu/common 8.0.0-next.5 → 8.0.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/dist/src/Array.d.ts +279 -173
- package/dist/src/Array.d.ts.map +1 -1
- package/dist/src/Array.js +105 -101
- package/dist/src/Assert.d.ts +39 -44
- package/dist/src/Assert.d.ts.map +1 -1
- package/dist/src/Assert.js +38 -31
- package/dist/src/BigInt.d.ts +6 -3
- package/dist/src/BigInt.d.ts.map +1 -1
- package/dist/src/BigInt.js +5 -2
- package/dist/src/Brand.d.ts +27 -40
- package/dist/src/Brand.d.ts.map +1 -1
- package/dist/src/Buffer.d.ts +27 -11
- package/dist/src/Buffer.d.ts.map +1 -1
- package/dist/src/Cache.d.ts +9 -4
- package/dist/src/Cache.d.ts.map +1 -1
- package/dist/src/Cache.js +8 -3
- package/dist/src/Callbacks.d.ts +30 -19
- package/dist/src/Callbacks.d.ts.map +1 -1
- package/dist/src/Console.d.ts +145 -66
- package/dist/src/Console.d.ts.map +1 -1
- package/dist/src/Console.js +91 -43
- package/dist/src/Crypto.d.ts +85 -42
- package/dist/src/Crypto.d.ts.map +1 -1
- package/dist/src/Crypto.js +44 -20
- package/dist/src/Eq.d.ts +87 -21
- package/dist/src/Eq.d.ts.map +1 -1
- package/dist/src/Eq.js +67 -19
- package/dist/src/Error.d.ts +3 -3
- package/dist/src/Error.d.ts.map +1 -1
- package/dist/src/Function.d.ts +119 -58
- package/dist/src/Function.d.ts.map +1 -1
- package/dist/src/Function.js +86 -43
- package/dist/src/Http.d.ts +394 -0
- package/dist/src/Http.d.ts.map +1 -0
- package/dist/src/Http.js +102 -0
- package/dist/src/Identicon.d.ts +16 -7
- package/dist/src/Identicon.d.ts.map +1 -1
- package/dist/src/Identicon.js +14 -5
- package/dist/src/LeakDetector.d.ts +88 -0
- package/dist/src/LeakDetector.d.ts.map +1 -0
- package/dist/src/LeakDetector.js +86 -0
- package/dist/src/LockManager.d.ts +18 -9
- package/dist/src/LockManager.d.ts.map +1 -1
- package/dist/src/LockManager.js +7 -8
- package/dist/src/Lookup.d.ts +43 -13
- package/dist/src/Lookup.d.ts.map +1 -1
- package/dist/src/Lookup.js +28 -8
- package/dist/src/Microtask.d.ts +1 -1
- package/dist/src/Microtask.d.ts.map +1 -1
- package/dist/src/Microtask.js +3 -7
- package/dist/src/Number.d.ts +49 -13
- package/dist/src/Number.d.ts.map +1 -1
- package/dist/src/Number.js +34 -5
- package/dist/src/Object.d.ts +160 -40
- package/dist/src/Object.d.ts.map +1 -1
- package/dist/src/Object.js +92 -46
- package/dist/src/Option.d.ts +10 -7
- package/dist/src/Option.d.ts.map +1 -1
- package/dist/src/Option.js +9 -6
- package/dist/src/Order.d.ts +21 -21
- package/dist/src/Order.d.ts.map +1 -1
- package/dist/src/Order.js +18 -21
- package/dist/src/Platform.d.ts +31 -0
- package/dist/src/Platform.d.ts.map +1 -1
- package/dist/src/Platform.js +98 -0
- package/dist/src/Random.d.ts +32 -17
- package/dist/src/Random.d.ts.map +1 -1
- package/dist/src/Random.js +12 -8
- package/dist/src/Redacted.d.ts +43 -29
- package/dist/src/Redacted.d.ts.map +1 -1
- package/dist/src/Redacted.js +14 -3
- package/dist/src/Ref.d.ts +11 -3
- package/dist/src/Ref.d.ts.map +1 -1
- package/dist/src/Ref.js +2 -2
- package/dist/src/RefCount.d.ts +2 -6
- package/dist/src/RefCount.d.ts.map +1 -1
- package/dist/src/RefCount.js +33 -90
- package/dist/src/Relation.d.ts +70 -5
- package/dist/src/Relation.d.ts.map +1 -1
- package/dist/src/Relation.js +77 -2
- package/dist/src/Resource.d.ts +590 -155
- package/dist/src/Resource.d.ts.map +1 -1
- package/dist/src/Resource.js +592 -343
- package/dist/src/Result.d.ts +838 -191
- package/dist/src/Result.d.ts.map +1 -1
- package/dist/src/Result.js +163 -102
- package/dist/src/Schedule.d.ts +684 -231
- package/dist/src/Schedule.d.ts.map +1 -1
- package/dist/src/Schedule.js +766 -295
- package/dist/src/Set.d.ts +89 -40
- package/dist/src/Set.d.ts.map +1 -1
- package/dist/src/Set.js +50 -29
- package/dist/src/Sqlite.d.ts +29 -72
- package/dist/src/Sqlite.d.ts.map +1 -1
- package/dist/src/Sqlite.js +39 -45
- package/dist/src/StackTrace.d.ts +40 -0
- package/dist/src/StackTrace.d.ts.map +1 -0
- package/dist/src/StackTrace.js +140 -0
- package/dist/src/Store.d.ts +5 -4
- package/dist/src/Store.d.ts.map +1 -1
- package/dist/src/Store.js +5 -4
- package/dist/src/String.d.ts +7 -1
- package/dist/src/String.d.ts.map +1 -1
- package/dist/src/String.js +20 -7
- package/dist/src/Task.d.ts +3428 -1629
- package/dist/src/Task.d.ts.map +1 -1
- package/dist/src/Task.js +1876 -1279
- package/dist/src/Test.d.ts +17 -124
- package/dist/src/Test.d.ts.map +1 -1
- package/dist/src/Test.js +17 -68
- package/dist/src/Time.d.ts +108 -49
- package/dist/src/Time.d.ts.map +1 -1
- package/dist/src/Time.js +172 -73
- package/dist/src/Type.d.ts +3542 -1926
- package/dist/src/Type.d.ts.map +1 -1
- package/dist/src/Type.js +3070 -1784
- package/dist/src/Types.d.ts +200 -100
- package/dist/src/Types.d.ts.map +1 -1
- package/dist/src/Types.js +39 -8
- package/dist/src/WebSocket.d.ts +48 -23
- package/dist/src/WebSocket.d.ts.map +1 -1
- package/dist/src/WebSocket.js +15 -6
- package/dist/src/Worker.d.ts +94 -36
- package/dist/src/Worker.d.ts.map +1 -1
- package/dist/src/Worker.js +58 -24
- package/dist/src/index.d.ts +55 -52
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +3 -1
- package/dist/src/intl/cs.d.ts +94 -0
- package/dist/src/intl/cs.d.ts.map +1 -0
- package/dist/src/intl/cs.js +220 -0
- package/dist/src/intl/index.d.ts +7 -0
- package/dist/src/intl/index.d.ts.map +1 -0
- package/dist/src/intl/index.js +6 -0
- package/dist/src/local-first/Db.d.ts +12 -8
- package/dist/src/local-first/Db.d.ts.map +1 -1
- package/dist/src/local-first/Db.js +107 -130
- package/dist/src/local-first/Error.d.ts +4 -4
- package/dist/src/local-first/Evolu.d.ts +338 -92
- package/dist/src/local-first/Evolu.d.ts.map +1 -1
- package/dist/src/local-first/Evolu.js +47 -55
- package/dist/src/local-first/LocalAuth.d.ts +4 -4
- package/dist/src/local-first/LocalAuth.d.ts.map +1 -1
- package/dist/src/local-first/Owner.d.ts +61 -24
- package/dist/src/local-first/Owner.d.ts.map +1 -1
- package/dist/src/local-first/Owner.js +45 -8
- package/dist/src/local-first/Protocol.d.ts +44 -31
- package/dist/src/local-first/Protocol.d.ts.map +1 -1
- package/dist/src/local-first/Protocol.js +36 -13
- package/dist/src/local-first/Query.d.ts +147 -62
- package/dist/src/local-first/Query.d.ts.map +1 -1
- package/dist/src/local-first/Query.js +112 -58
- package/dist/src/local-first/Relay.d.ts +44 -14
- package/dist/src/local-first/Relay.d.ts.map +1 -1
- package/dist/src/local-first/Schema.d.ts +92 -41
- package/dist/src/local-first/Schema.d.ts.map +1 -1
- package/dist/src/local-first/Schema.js +25 -8
- package/dist/src/local-first/Shared.d.ts +23 -21
- package/dist/src/local-first/Shared.d.ts.map +1 -1
- package/dist/src/local-first/Shared.js +85 -42
- package/dist/src/local-first/Storage.d.ts +53 -32
- package/dist/src/local-first/Storage.d.ts.map +1 -1
- package/dist/src/local-first/Storage.js +194 -234
- package/dist/src/local-first/Timestamp.d.ts +21 -21
- package/dist/src/local-first/Timestamp.d.ts.map +1 -1
- package/dist/src/local-first/Timestamp.js +2 -2
- package/dist/src/local-first/index.d.ts +11 -11
- package/package.json +14 -13
- package/src/Array.ts +306 -205
- package/src/Assert.ts +48 -68
- package/src/BigInt.ts +6 -3
- package/src/Brand.ts +27 -40
- package/src/Buffer.ts +28 -12
- package/src/Cache.ts +9 -4
- package/src/Callbacks.ts +30 -19
- package/src/Console.ts +156 -84
- package/src/Crypto.ts +83 -41
- package/src/Eq.ts +95 -22
- package/src/Error.ts +5 -2
- package/src/Function.ts +167 -59
- package/src/Http.ts +549 -0
- package/src/Identicon.ts +16 -7
- package/src/LeakDetector.ts +182 -0
- package/src/LockManager.ts +43 -39
- package/src/Lookup.ts +62 -28
- package/src/Microtask.ts +19 -23
- package/src/Number.ts +64 -12
- package/src/Object.ts +173 -49
- package/src/Option.ts +10 -7
- package/src/Order.ts +23 -21
- package/src/Platform.ts +136 -0
- package/src/Polyfills.ts +6 -12
- package/src/Random.ts +32 -19
- package/src/Redacted.ts +44 -30
- package/src/Ref.ts +14 -6
- package/src/RefCount.ts +38 -80
- package/src/Relation.ts +202 -10
- package/src/Resource.ts +1199 -591
- package/src/Result.ts +930 -271
- package/src/Schedule.ts +859 -343
- package/src/Set.ts +89 -40
- package/src/Sqlite.ts +142 -137
- package/src/StackTrace.ts +230 -0
- package/src/Store.ts +8 -7
- package/src/String.ts +22 -5
- package/src/Task.ts +5109 -2845
- package/src/Test.ts +20 -167
- package/src/Time.ts +293 -90
- package/src/Type.ts +10034 -4117
- package/src/Types.ts +227 -101
- package/src/WebSocket.ts +64 -36
- package/src/Worker.ts +180 -72
- package/src/index.ts +55 -52
- package/src/intl/cs.ts +388 -0
- package/src/intl/index.ts +7 -0
- package/src/local-first/Db.ts +161 -190
- package/src/local-first/Error.ts +4 -4
- package/src/local-first/Evolu.ts +495 -250
- package/src/local-first/LocalAuth.ts +6 -12
- package/src/local-first/Owner.ts +58 -21
- package/src/local-first/Protocol.ts +49 -31
- package/src/local-first/Query.ts +146 -61
- package/src/local-first/Relay.ts +51 -21
- package/src/local-first/Schema.ts +109 -51
- package/src/local-first/Shared.ts +253 -214
- package/src/local-first/Storage.ts +266 -264
- package/src/local-first/Timestamp.ts +25 -18
- package/src/local-first/index.ts +11 -11
- package/dist/src/Skiplist.d.ts +0 -28
- package/dist/src/Skiplist.d.ts.map +0 -1
- package/dist/src/Skiplist.js +0 -64
- package/dist/src/Tracer.d.ts +0 -48
- package/dist/src/Tracer.d.ts.map +0 -1
- package/dist/src/Tracer.js +0 -6
- package/src/Skiplist.ts +0 -108
- package/src/Tracer.ts +0 -54
package/dist/src/Function.js
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
|
+
import { assertNotDisposed } from "./Assert.js";
|
|
7
|
+
import { isFunction } from "./Object.js";
|
|
6
8
|
/**
|
|
7
9
|
* Helper function to ensure exhaustive matching in a switch statement. Throws
|
|
8
10
|
* an error if an unhandled case is encountered.
|
|
@@ -10,32 +12,36 @@
|
|
|
10
12
|
* ### Example
|
|
11
13
|
*
|
|
12
14
|
* ```ts
|
|
15
|
+
* import { exhaustiveCheck } from "@evolu/common";
|
|
16
|
+
*
|
|
13
17
|
* type Color = "red" | "green" | "blue";
|
|
18
|
+
* const handled: Array<string> = [];
|
|
14
19
|
*
|
|
15
20
|
* const handleColor = (color: Color): void => {
|
|
16
21
|
* switch (color) {
|
|
17
22
|
* case "red":
|
|
18
|
-
*
|
|
23
|
+
* handled.push("Handling red");
|
|
19
24
|
* break;
|
|
20
25
|
* case "green":
|
|
21
|
-
*
|
|
26
|
+
* handled.push("Handling green");
|
|
22
27
|
* break;
|
|
23
28
|
* case "blue":
|
|
24
|
-
*
|
|
29
|
+
* handled.push("Handling blue");
|
|
25
30
|
* break;
|
|
26
31
|
* default:
|
|
27
|
-
* exhaustiveCheck(color);
|
|
32
|
+
* exhaustiveCheck(color);
|
|
28
33
|
* }
|
|
29
34
|
* };
|
|
35
|
+
*
|
|
36
|
+
* handleColor("blue");
|
|
37
|
+
* expect(handled).toEqual(["Handling blue"]);
|
|
30
38
|
* ```
|
|
31
39
|
*
|
|
32
40
|
* Use this primarily in side-effect switches (`void` branches). For
|
|
33
41
|
* value-producing switches, TypeScript can enforce exhaustiveness without a
|
|
34
|
-
* `default` branch.
|
|
35
|
-
*
|
|
36
|
-
* ### Example
|
|
42
|
+
* `default` branch in either of the following styles.
|
|
37
43
|
*
|
|
38
|
-
* Return from
|
|
44
|
+
* ### Return from every case
|
|
39
45
|
*
|
|
40
46
|
* ```ts
|
|
41
47
|
* type Color = "red" | "green" | "blue";
|
|
@@ -50,11 +56,11 @@
|
|
|
50
56
|
* return "#0000ff";
|
|
51
57
|
* }
|
|
52
58
|
* };
|
|
53
|
-
* ```
|
|
54
59
|
*
|
|
55
|
-
*
|
|
60
|
+
* expect(colorToHex("green")).toBe("#00ff00");
|
|
61
|
+
* ```
|
|
56
62
|
*
|
|
57
|
-
*
|
|
63
|
+
* ### Assign in every case
|
|
58
64
|
*
|
|
59
65
|
* ```ts
|
|
60
66
|
* type Input =
|
|
@@ -62,7 +68,7 @@
|
|
|
62
68
|
* | { readonly type: "Query" }
|
|
63
69
|
* | { readonly type: "Export" };
|
|
64
70
|
*
|
|
65
|
-
* const
|
|
71
|
+
* const inputToKind = (input: Input): "A" | "B" | "C" => {
|
|
66
72
|
* let result: "A" | "B" | "C";
|
|
67
73
|
*
|
|
68
74
|
* switch (input.type) {
|
|
@@ -77,12 +83,10 @@
|
|
|
77
83
|
* break;
|
|
78
84
|
* }
|
|
79
85
|
*
|
|
80
|
-
*
|
|
86
|
+
* return result;
|
|
81
87
|
* };
|
|
82
88
|
*
|
|
83
|
-
*
|
|
84
|
-
* console.log(kind);
|
|
85
|
-
* };
|
|
89
|
+
* expect(inputToKind({ type: "Query" })).toBe("B");
|
|
86
90
|
* ```
|
|
87
91
|
*/
|
|
88
92
|
export const exhaustiveCheck = (value) => {
|
|
@@ -97,41 +101,78 @@ export const exhaustiveCheck = (value) => {
|
|
|
97
101
|
* ### Example
|
|
98
102
|
*
|
|
99
103
|
* ```ts
|
|
100
|
-
*
|
|
101
|
-
* const same = values.map(identity); // [1, 2, 3]
|
|
104
|
+
* import { identity } from "@evolu/common";
|
|
102
105
|
*
|
|
106
|
+
* const values = [1, 2, 3];
|
|
107
|
+
* const object = { value: 1 };
|
|
103
108
|
* const getTransform = (shouldDouble: boolean) =>
|
|
104
|
-
* shouldDouble ? (
|
|
109
|
+
* shouldDouble ? (value: number) => value * 2 : identity;
|
|
110
|
+
*
|
|
111
|
+
* expect(values.map(identity)).toEqual([1, 2, 3]);
|
|
112
|
+
* expect(identity(object)).toBe(object);
|
|
113
|
+
* expect(getTransform(false)(2)).toBe(2);
|
|
105
114
|
* ```
|
|
106
115
|
*/
|
|
107
116
|
export const identity = (a) => a;
|
|
117
|
+
export function disposable(value, disposer = null) {
|
|
118
|
+
const mutableValue = value;
|
|
119
|
+
const ownedDisposer = disposer?.move() ?? new DisposableStack();
|
|
120
|
+
for (const [key, property] of Object.entries(value)) {
|
|
121
|
+
if (!isFunction(property))
|
|
122
|
+
continue;
|
|
123
|
+
mutableValue[key] = (...args) => {
|
|
124
|
+
assertNotDisposed(ownedDisposer);
|
|
125
|
+
return property(...args);
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
if (ownedDisposer instanceof AsyncDisposableStack) {
|
|
129
|
+
value[Symbol.asyncDispose] = () => ownedDisposer.disposeAsync();
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
value[Symbol.dispose] = () => ownedDisposer.dispose();
|
|
133
|
+
}
|
|
134
|
+
return value;
|
|
135
|
+
}
|
|
136
|
+
export const isDisposable = (value) => {
|
|
137
|
+
if (typeof value !== "object" || value === null)
|
|
138
|
+
return false;
|
|
139
|
+
return (isFunction(value[Symbol.dispose]) ||
|
|
140
|
+
isFunction(value[Symbol.asyncDispose]));
|
|
141
|
+
};
|
|
108
142
|
/**
|
|
109
|
-
* Creates a {@link
|
|
143
|
+
* Creates a {@link Thunk} that always returns a precomputed value.
|
|
110
144
|
*
|
|
111
|
-
* Use when the value is expensive to compute and want to compute it once at
|
|
145
|
+
* Use when the value is expensive to compute and you want to compute it once at
|
|
112
146
|
* definition time rather than on every call.
|
|
113
147
|
*
|
|
114
148
|
* ### Example
|
|
115
149
|
*
|
|
116
150
|
* ```ts
|
|
117
|
-
*
|
|
118
|
-
*
|
|
151
|
+
* import { constant } from "@evolu/common";
|
|
152
|
+
*
|
|
153
|
+
* let version = 0;
|
|
154
|
+
* const readConfig = () => ({ version: ++version });
|
|
155
|
+
* const getConstantConfig = constant(readConfig());
|
|
156
|
+
* const getFreshConfig = () => readConfig();
|
|
119
157
|
*
|
|
120
|
-
*
|
|
121
|
-
*
|
|
158
|
+
* expect(getConstantConfig()).toBe(getConstantConfig());
|
|
159
|
+
* expect(getConstantConfig().version).toBe(1);
|
|
160
|
+
* expect(getFreshConfig().version).toBe(2);
|
|
161
|
+
* expect(getFreshConfig().version).toBe(3);
|
|
122
162
|
* ```
|
|
123
163
|
*/
|
|
124
|
-
export const
|
|
125
|
-
/** A {@link
|
|
126
|
-
export const
|
|
127
|
-
/** A {@link
|
|
128
|
-
export const
|
|
129
|
-
/** A {@link
|
|
130
|
-
export const
|
|
131
|
-
/** A {@link
|
|
132
|
-
export const
|
|
133
|
-
|
|
134
|
-
|
|
164
|
+
export const constant = (value) => () => value;
|
|
165
|
+
/** A {@link Thunk} that returns `true`. */
|
|
166
|
+
export const constTrue = /*#__PURE__*/ constant(true);
|
|
167
|
+
/** A {@link Thunk} that returns `false`. */
|
|
168
|
+
export const constFalse = /*#__PURE__*/ constant(false);
|
|
169
|
+
/** A {@link Thunk} that returns `null`. */
|
|
170
|
+
export const constNull = /*#__PURE__*/ constant(null);
|
|
171
|
+
/** A {@link Thunk} that returns `undefined`. */
|
|
172
|
+
export const constUndefined =
|
|
173
|
+
/*#__PURE__*/ constant(undefined);
|
|
174
|
+
/** A {@link Thunk} that returns `undefined` for void callbacks. */
|
|
175
|
+
export const constVoid = constUndefined;
|
|
135
176
|
/**
|
|
136
177
|
* Development placeholder that always throws.
|
|
137
178
|
*
|
|
@@ -142,17 +183,19 @@ export const lazyVoid = lazyUndefined;
|
|
|
142
183
|
* ### Example
|
|
143
184
|
*
|
|
144
185
|
* ```ts
|
|
145
|
-
*
|
|
146
|
-
* const fetchUser = (id: UserId): Result<User, FetchError> => todo();
|
|
186
|
+
* import { todo } from "@evolu/common";
|
|
147
187
|
*
|
|
148
|
-
*
|
|
149
|
-
*
|
|
150
|
-
*
|
|
188
|
+
* interface Config {
|
|
189
|
+
* readonly theme: string;
|
|
190
|
+
* }
|
|
151
191
|
*
|
|
152
|
-
*
|
|
192
|
+
* const getCount = (): number => todo();
|
|
153
193
|
* const getConfig = () => todo<Config>();
|
|
154
194
|
*
|
|
155
|
-
* expectTypeOf
|
|
195
|
+
* expectTypeOf<
|
|
196
|
+
* [ReturnType<typeof getCount>, ReturnType<typeof getConfig>]
|
|
197
|
+
* >().toEqualTypeOf<[number, Config]>();
|
|
198
|
+
* expect(getCount).toThrow("not yet implemented");
|
|
156
199
|
* ```
|
|
157
200
|
*/
|
|
158
201
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters
|
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Task-aware HTTP helpers.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import { type Result } from "./Result.ts";
|
|
7
|
+
import type { Task } from "./Task.ts";
|
|
8
|
+
import type { Typed } from "./Type.ts";
|
|
9
|
+
import type { Awaitable } from "./Types.ts";
|
|
10
|
+
/**
|
|
11
|
+
* WHATWG-fetch-compatible function used by {@link fetch}.
|
|
12
|
+
*
|
|
13
|
+
* A default dependency, replaceable at the composition root — for a
|
|
14
|
+
* platform-optimized fetch such as React Native's, a configured undici
|
|
15
|
+
* instance, or a test double. Implementations must be pre-bound; unbound
|
|
16
|
+
* `globalThis.fetch` throws in browsers.
|
|
17
|
+
*
|
|
18
|
+
* @group Fetch
|
|
19
|
+
*/
|
|
20
|
+
export type NativeFetch = typeof globalThis.fetch;
|
|
21
|
+
/**
|
|
22
|
+
* Dependency wrapper for {@link NativeFetch}.
|
|
23
|
+
*
|
|
24
|
+
* @group Fetch
|
|
25
|
+
*/
|
|
26
|
+
export interface NativeFetchDep {
|
|
27
|
+
readonly nativeFetch: NativeFetch;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Body mode for {@link fetch}.
|
|
31
|
+
*
|
|
32
|
+
* A mode selects a built-in consumer that reads the {@link Response} inside the
|
|
33
|
+
* fetch Task:
|
|
34
|
+
*
|
|
35
|
+
* - `"bytes"` — reads the body as a `Uint8Array<ArrayBuffer>`.
|
|
36
|
+
* - `"headers"` — cancels the body and returns {@link FetchResponse}. Pair it with
|
|
37
|
+
* `{ method: "HEAD" }` when the server should not send a body.
|
|
38
|
+
* - `"json"` — parses the body as JSON and returns `unknown`. Narrow or decode at
|
|
39
|
+
* the call site; there is deliberately no generic to cast through.
|
|
40
|
+
* - `"text"` — reads the body as a string.
|
|
41
|
+
*
|
|
42
|
+
* Body modes (`"bytes"`, `"json"`, `"text"`) return {@link FetchStatusError} for
|
|
43
|
+
* non-2xx responses. `"headers"` does not judge status, because the status is
|
|
44
|
+
* usually the value being asked for.
|
|
45
|
+
*
|
|
46
|
+
* @group Fetch
|
|
47
|
+
*/
|
|
48
|
+
export type FetchMode = "text" | "json" | "bytes" | "headers";
|
|
49
|
+
/**
|
|
50
|
+
* Body-free {@link Response} view safe to return from {@link fetch}.
|
|
51
|
+
*
|
|
52
|
+
* {@link fetch} returns this view only after the native body has been drained,
|
|
53
|
+
* errored, or cancelled, so none of its usable members depends on the request
|
|
54
|
+
* signal. Body-reading members and `Response.clone` are omitted because they
|
|
55
|
+
* would be invalid after the fetch Task settles.
|
|
56
|
+
*
|
|
57
|
+
* This is a TypeScript contract, not a runtime security boundary: the runtime
|
|
58
|
+
* value can still be a native Response, and casts can access omitted members.
|
|
59
|
+
*
|
|
60
|
+
* @group Fetch
|
|
61
|
+
*/
|
|
62
|
+
export type FetchResponse = Omit<Response, "arrayBuffer" | "blob" | "body" | "bodyUsed" | "bytes" | "clone" | "formData" | "json" | "text">;
|
|
63
|
+
/**
|
|
64
|
+
* Error returned by {@link fetch} body modes.
|
|
65
|
+
*
|
|
66
|
+
* The union distinguishes native request failures, non-2xx responses, and body
|
|
67
|
+
* read failures. Narrow on `type` when handling a specific case. The
|
|
68
|
+
* distinction matters for retries: {@link FetchBodyError} means a 2xx response
|
|
69
|
+
* failed during reading, so the server may have committed the request.
|
|
70
|
+
*
|
|
71
|
+
* @group Fetch
|
|
72
|
+
*/
|
|
73
|
+
export type FetchError = FetchTransportError | FetchStatusError | FetchBodyError;
|
|
74
|
+
/**
|
|
75
|
+
* Error returned when the native fetch request fails before a response exists.
|
|
76
|
+
*
|
|
77
|
+
* @group Fetch
|
|
78
|
+
*/
|
|
79
|
+
export interface FetchTransportError extends Typed<"FetchTransportError"> {
|
|
80
|
+
readonly error: unknown;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Error returned when a body mode receives a non-2xx response.
|
|
84
|
+
*
|
|
85
|
+
* The response body is drained as text before this error is returned. Draining
|
|
86
|
+
* buffers the whole error body; error responses are expected to be small. If
|
|
87
|
+
* the drain itself fails, `body` contains the read error.
|
|
88
|
+
*
|
|
89
|
+
* @group Fetch
|
|
90
|
+
*/
|
|
91
|
+
export interface FetchStatusError extends Typed<"FetchStatusError"> {
|
|
92
|
+
readonly response: FetchResponse;
|
|
93
|
+
readonly body: Result<string, unknown>;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Error returned when a body mode cannot read or decode a 2xx response.
|
|
97
|
+
*
|
|
98
|
+
* This includes mid-stream network failures, decoding failures, and — for the
|
|
99
|
+
* `"json"` mode — empty bodies such as 204 responses, which are not JSON. Do
|
|
100
|
+
* not use `"json"` for endpoints that return no content.
|
|
101
|
+
*
|
|
102
|
+
* @group Fetch
|
|
103
|
+
*/
|
|
104
|
+
export interface FetchBodyError extends Typed<"FetchBodyError"> {
|
|
105
|
+
readonly response: FetchResponse;
|
|
106
|
+
readonly error: unknown;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Consumes a native {@link Response} before {@link fetch} settles.
|
|
110
|
+
*
|
|
111
|
+
* The callback runs inside the fetch Task, while the request signal is still
|
|
112
|
+
* alive. Return a Result error for expected domain failures. Throwing or
|
|
113
|
+
* rejecting with a non-abort error is a defect, like any other Task body.
|
|
114
|
+
*
|
|
115
|
+
* Consumers take values, not dependencies; close over anything they need. A
|
|
116
|
+
* consumer that needs its own timeout, retries, or child Tasks has outgrown
|
|
117
|
+
* being a consumer: fetch the body with a mode and compose Tasks on the plain
|
|
118
|
+
* value, or write a Task that owns the whole request.
|
|
119
|
+
*
|
|
120
|
+
* Consumers do not have to normalize abort. {@link fetch} rethrows Evolu
|
|
121
|
+
* {@link AbortError}, normalizes host abort errors after the Run aborts, and
|
|
122
|
+
* treats an Err returned after abort as abort control flow — so a consumer's
|
|
123
|
+
* `try`/`catch` around a body read cannot accidentally turn an abort into a
|
|
124
|
+
* domain error. An Ok returned after abort is kept; only errors are presumed to
|
|
125
|
+
* be abort in disguise.
|
|
126
|
+
*
|
|
127
|
+
* The Response and anything derived from its live body, such as a reader, must
|
|
128
|
+
* not escape the consumer. Consume to plain values before returning.
|
|
129
|
+
*
|
|
130
|
+
* @group Fetch
|
|
131
|
+
*/
|
|
132
|
+
export type FetchConsume<T, E = never> = (response: Response) => Awaitable<Result<T, E>>;
|
|
133
|
+
/**
|
|
134
|
+
* Fetches a resource and consumes the {@link Response} inside the Task, so the
|
|
135
|
+
* body is read while the request signal is still alive.
|
|
136
|
+
*
|
|
137
|
+
* The request runs through {@link NativeFetchDep | run.deps.nativeFetch}.
|
|
138
|
+
* Because native fetch is a default dependency, platforms and tests can replace
|
|
139
|
+
* it without changing call sites.
|
|
140
|
+
*
|
|
141
|
+
* With a {@link FetchMode}, non-2xx responses return {@link FetchStatusError}
|
|
142
|
+
* (except `"headers"`, which reports status as a value) and unreadable bodies
|
|
143
|
+
* return {@link FetchBodyError}. With a {@link FetchConsume} callback, native
|
|
144
|
+
* status semantics apply: HTTP error statuses resolve, and the consumer decides
|
|
145
|
+
* how to interpret the status and body.
|
|
146
|
+
*
|
|
147
|
+
* `signal` is not accepted in init because abort is controlled by the current
|
|
148
|
+
* Run.
|
|
149
|
+
*
|
|
150
|
+
* Aborting the Run aborts the underlying request, any response that arrives
|
|
151
|
+
* after abort, and any in-progress body read. Abort is represented as
|
|
152
|
+
* {@link AbortError}, not FetchError: `run(fetch(...))` rejects with AbortError,
|
|
153
|
+
* and `run.abortable(fetch(...))` returns it as an {@link Err}.
|
|
154
|
+
*
|
|
155
|
+
* Some runtimes reject aborted fetches with their own error instead of
|
|
156
|
+
* `signal.reason`. This wrapper normalizes abort rejections from native fetch,
|
|
157
|
+
* built-in body reads, and consumer callbacks back to the Run's AbortError.
|
|
158
|
+
*
|
|
159
|
+
* `fetch` owns request lifetime and Response containment. It does not transform
|
|
160
|
+
* requests or interpret app protocols beyond the built-in modes. Use Task
|
|
161
|
+
* helpers for resilience, app helpers for app conventions, a replacement
|
|
162
|
+
* {@link NativeFetch} for request-wide behavior (base URLs, auth, logging), and
|
|
163
|
+
* consumers for response interpretation.
|
|
164
|
+
*
|
|
165
|
+
* ### Composing fetch
|
|
166
|
+
*
|
|
167
|
+
* Resilience is ordinary Task composition: wrap `fetch(url, "json")` in
|
|
168
|
+
* {@link timeout}, then in {@link retry}.
|
|
169
|
+
*
|
|
170
|
+
* ```ts
|
|
171
|
+
* import {
|
|
172
|
+
* createRun,
|
|
173
|
+
* exponential,
|
|
174
|
+
* fetch,
|
|
175
|
+
* retry,
|
|
176
|
+
* take,
|
|
177
|
+
* timeout,
|
|
178
|
+
* type NativeFetch,
|
|
179
|
+
* } from "@evolu/common";
|
|
180
|
+
*
|
|
181
|
+
* const fetchWithRetry = (url: string) =>
|
|
182
|
+
* retry(
|
|
183
|
+
* timeout(fetch(url, "json"), "30s"),
|
|
184
|
+
* take(2)(exponential("100ms")),
|
|
185
|
+
* );
|
|
186
|
+
*
|
|
187
|
+
* let requestCount = 0;
|
|
188
|
+
* const nativeFetch: NativeFetch = () => {
|
|
189
|
+
* requestCount++;
|
|
190
|
+
* return Promise.resolve(
|
|
191
|
+
* requestCount === 1
|
|
192
|
+
* ? new Response("Try again", { status: 503 })
|
|
193
|
+
* : new Response('{"name":"Ada"}'),
|
|
194
|
+
* );
|
|
195
|
+
* };
|
|
196
|
+
* await using run = createRun({ nativeFetch });
|
|
197
|
+
*
|
|
198
|
+
* expectOk(await run(fetchWithRetry("/api/user")), { name: "Ada" });
|
|
199
|
+
* ```
|
|
200
|
+
*
|
|
201
|
+
* App conventions belong in small app-owned helpers. For example, posting JSON
|
|
202
|
+
* is native `init` plus two conventions worth centralizing — the content-type
|
|
203
|
+
* header and the stringify:
|
|
204
|
+
*
|
|
205
|
+
* ```ts
|
|
206
|
+
* import {
|
|
207
|
+
* createRun,
|
|
208
|
+
* fetch,
|
|
209
|
+
* type FetchError,
|
|
210
|
+
* type NativeFetch,
|
|
211
|
+
* type Task,
|
|
212
|
+
* } from "@evolu/common";
|
|
213
|
+
*
|
|
214
|
+
* const postJson = (
|
|
215
|
+
* url: string,
|
|
216
|
+
* data: unknown,
|
|
217
|
+
* ): Task<unknown, FetchError> =>
|
|
218
|
+
* fetch(url, "json", {
|
|
219
|
+
* method: "POST",
|
|
220
|
+
* headers: { "content-type": "application/json" },
|
|
221
|
+
* body: JSON.stringify(data),
|
|
222
|
+
* });
|
|
223
|
+
*
|
|
224
|
+
* const nativeFetch: NativeFetch = () =>
|
|
225
|
+
* Promise.resolve(new Response('{"id":"user-1"}'));
|
|
226
|
+
* await using run = createRun({ nativeFetch });
|
|
227
|
+
*
|
|
228
|
+
* expectOk(await run(postJson("/api/users", { name: "Ada" })), {
|
|
229
|
+
* id: "user-1",
|
|
230
|
+
* });
|
|
231
|
+
* ```
|
|
232
|
+
*
|
|
233
|
+
* Your app's version will grow your conventions — auth, envelopes, error
|
|
234
|
+
* mapping — which is why it belongs to the app, not to `fetch`.
|
|
235
|
+
*
|
|
236
|
+
* ### Intercepting requests
|
|
237
|
+
*
|
|
238
|
+
* Request-wide behavior belongs to a replacement {@link NativeFetch} installed
|
|
239
|
+
* at the composition root. This is the equivalent of interceptors or hooks in
|
|
240
|
+
* libraries that expose client instances.
|
|
241
|
+
*
|
|
242
|
+
* ```ts
|
|
243
|
+
* import { createRun, fetch, type NativeFetch } from "@evolu/common";
|
|
244
|
+
*
|
|
245
|
+
* const token = "secret-token";
|
|
246
|
+
* const baseUrl = "https://api.example.com/v1/";
|
|
247
|
+
* let interceptedRequest: Request | undefined;
|
|
248
|
+
* const baseFetch: NativeFetch = (input, init) => {
|
|
249
|
+
* interceptedRequest = new Request(input, init);
|
|
250
|
+
* return Promise.resolve(new Response("ok"));
|
|
251
|
+
* };
|
|
252
|
+
*
|
|
253
|
+
* const nativeFetch: NativeFetch = (input, init) => {
|
|
254
|
+
* const headers = new Headers(init?.headers);
|
|
255
|
+
* headers.set("authorization", `Bearer ${token}`);
|
|
256
|
+
*
|
|
257
|
+
* // Only string inputs are resolved against the base URL; URL and Request
|
|
258
|
+
* // inputs are passed through unchanged.
|
|
259
|
+
* const url =
|
|
260
|
+
* typeof input === "string" ? new URL(input, baseUrl) : input;
|
|
261
|
+
* return baseFetch(url, { ...init, headers });
|
|
262
|
+
* };
|
|
263
|
+
*
|
|
264
|
+
* await using run = createRun({ nativeFetch });
|
|
265
|
+
* expectOk(await run(fetch("users", "text")), "ok");
|
|
266
|
+
* expect({
|
|
267
|
+
* url: interceptedRequest?.url,
|
|
268
|
+
* authorization: interceptedRequest?.headers.get("authorization"),
|
|
269
|
+
* }).toEqual({
|
|
270
|
+
* url: "https://api.example.com/v1/users",
|
|
271
|
+
* authorization: "Bearer secret-token",
|
|
272
|
+
* });
|
|
273
|
+
* ```
|
|
274
|
+
*
|
|
275
|
+
* ### Consuming responses
|
|
276
|
+
*
|
|
277
|
+
* Built-in modes handle common bodies. Specialized response interpretation
|
|
278
|
+
* belongs in a consumer. Typed decoders, response envelopes, streaming, and
|
|
279
|
+
* custom status semantics can be built on top without changing `fetch`.
|
|
280
|
+
*
|
|
281
|
+
* ```ts
|
|
282
|
+
* import {
|
|
283
|
+
* createRun,
|
|
284
|
+
* fetch,
|
|
285
|
+
* ok,
|
|
286
|
+
* type FetchTransportError,
|
|
287
|
+
* type NativeFetch,
|
|
288
|
+
* type Task,
|
|
289
|
+
* } from "@evolu/common";
|
|
290
|
+
*
|
|
291
|
+
* const nativeFetch: NativeFetch = (input) =>
|
|
292
|
+
* Promise.resolve(
|
|
293
|
+
* String(input).endsWith("/metadata")
|
|
294
|
+
* ? new Response(null, {
|
|
295
|
+
* status: 204,
|
|
296
|
+
* headers: { "cache-control": "max-age=60" },
|
|
297
|
+
* })
|
|
298
|
+
* : new Response('{"name":"Ada"}'),
|
|
299
|
+
* );
|
|
300
|
+
* await using run = createRun({ nativeFetch });
|
|
301
|
+
*
|
|
302
|
+
* const user = await run(fetch("/api/user", "json"));
|
|
303
|
+
* const metadata = fetch("/api/user/metadata", (response) =>
|
|
304
|
+
* ok({
|
|
305
|
+
* status: response.status,
|
|
306
|
+
* cache: response.headers.get("cache-control"),
|
|
307
|
+
* }),
|
|
308
|
+
* );
|
|
309
|
+
* expectTypeOf(metadata).toEqualTypeOf<
|
|
310
|
+
* Task<{ status: number; cache: string | null }, FetchTransportError>
|
|
311
|
+
* >();
|
|
312
|
+
* expectOk(user, { name: "Ada" });
|
|
313
|
+
* expectOk(await run(metadata), { status: 204, cache: "max-age=60" });
|
|
314
|
+
* ```
|
|
315
|
+
*
|
|
316
|
+
* ### Aborting fetch
|
|
317
|
+
*
|
|
318
|
+
* Abort follows the standard Task rules: a Fiber from `run(fetch(...))` rejects
|
|
319
|
+
* with {@link AbortError}, and `run.abortable(fetch(...))` returns it as a
|
|
320
|
+
* Result error.
|
|
321
|
+
*
|
|
322
|
+
* ```ts
|
|
323
|
+
* import {
|
|
324
|
+
* AbortError,
|
|
325
|
+
* createRun,
|
|
326
|
+
* fetch,
|
|
327
|
+
* type NativeFetch,
|
|
328
|
+
* } from "@evolu/common";
|
|
329
|
+
*
|
|
330
|
+
* const nativeFetch: NativeFetch = (_input, init) =>
|
|
331
|
+
* new Promise<Response>((_resolve, reject) => {
|
|
332
|
+
* const signal = init?.signal;
|
|
333
|
+
* if (!signal) throw new Error("Missing signal");
|
|
334
|
+
* signal.addEventListener("abort", () => reject(signal.reason), {
|
|
335
|
+
* once: true,
|
|
336
|
+
* });
|
|
337
|
+
* });
|
|
338
|
+
* await using run = createRun({ nativeFetch });
|
|
339
|
+
*
|
|
340
|
+
* const fiber = run.abortable(fetch("/api/user", "json"));
|
|
341
|
+
* fiber.abort();
|
|
342
|
+
* const result = await fiber;
|
|
343
|
+
*
|
|
344
|
+
* expect(!result.ok && AbortError.is(result.error)).toBe(true);
|
|
345
|
+
* ```
|
|
346
|
+
*
|
|
347
|
+
* @group Fetch
|
|
348
|
+
*/
|
|
349
|
+
export declare function fetch(input: RequestInfo | URL, mode: "text", init?: Omit<RequestInit, "signal">): Task<string, FetchError>;
|
|
350
|
+
export declare function fetch(input: RequestInfo | URL, mode: "json", init?: Omit<RequestInit, "signal">): Task<unknown, FetchError>;
|
|
351
|
+
export declare function fetch(input: RequestInfo | URL, mode: "bytes", init?: Omit<RequestInit, "signal">): Task<Uint8Array<ArrayBuffer>, FetchError>;
|
|
352
|
+
export declare function fetch(input: RequestInfo | URL, mode: "headers", init?: Omit<RequestInit, "signal">): Task<FetchResponse, FetchTransportError>;
|
|
353
|
+
export declare function fetch<T, E = never>(input: RequestInfo | URL, consume: FetchConsume<T, E>, init?: Omit<RequestInit, "signal">): Task<T, FetchTransportError | E>;
|
|
354
|
+
/**
|
|
355
|
+
* Test {@link NativeFetch} that records calls and serves queued handlers.
|
|
356
|
+
*
|
|
357
|
+
* Each call shifts the next handler. Calling with an empty queue throws, so a
|
|
358
|
+
* test never silently reaches an unplanned request.
|
|
359
|
+
*
|
|
360
|
+
* @group Testing
|
|
361
|
+
*/
|
|
362
|
+
export interface TestNativeFetch extends NativeFetch {
|
|
363
|
+
readonly calls: ReadonlyArray<TestNativeFetchCall>;
|
|
364
|
+
readonly handle: (handler: TestNativeFetchHandler) => void;
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* Recorded {@link TestNativeFetch} call.
|
|
368
|
+
*
|
|
369
|
+
* @group Testing
|
|
370
|
+
*/
|
|
371
|
+
export interface TestNativeFetchCall {
|
|
372
|
+
readonly input: RequestInfo | URL;
|
|
373
|
+
readonly init: RequestInit | undefined;
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* Handler for one {@link TestNativeFetch} call.
|
|
377
|
+
*
|
|
378
|
+
* @group Testing
|
|
379
|
+
*/
|
|
380
|
+
export type TestNativeFetchHandler = (input: RequestInfo | URL, init: RequestInit | undefined) => Awaitable<Response>;
|
|
381
|
+
/**
|
|
382
|
+
* Creates {@link TestNativeFetch}.
|
|
383
|
+
*
|
|
384
|
+
* @group Testing
|
|
385
|
+
*/
|
|
386
|
+
export declare const testCreateNativeFetch: (...handlers: ReadonlyArray<TestNativeFetchHandler>) => TestNativeFetch;
|
|
387
|
+
/**
|
|
388
|
+
* Creates a Response body for {@link NativeFetch} tests that errors on first
|
|
389
|
+
* read.
|
|
390
|
+
*
|
|
391
|
+
* @group Testing
|
|
392
|
+
*/
|
|
393
|
+
export declare const testCreateNativeFetchErroringBody: (error?: unknown) => ReadableStream<Uint8Array>;
|
|
394
|
+
//# sourceMappingURL=Http.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Http.d.ts","sourceRoot":"","sources":["../../src/Http.ts"],"names":[],"mappings":"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"}
|