@evolu/common 6.0.1-preview.2 → 6.0.1-preview.21
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/Assert.d.ts +6 -3
- package/dist/src/Assert.d.ts.map +1 -1
- package/dist/src/Assert.js +7 -4
- package/dist/src/Brand.d.ts +75 -0
- package/dist/src/Brand.d.ts.map +1 -0
- package/dist/src/Brand.js +1 -0
- package/dist/src/Buffer.d.ts +1 -1
- package/dist/src/Buffer.d.ts.map +1 -1
- package/dist/src/Buffer.js +1 -1
- package/dist/src/CallbackRegistry.d.ts +53 -0
- package/dist/src/CallbackRegistry.d.ts.map +1 -0
- package/dist/src/CallbackRegistry.js +25 -0
- package/dist/src/Console.d.ts +31 -6
- package/dist/src/Console.d.ts.map +1 -1
- package/dist/src/Console.js +72 -9
- package/dist/src/Crypto.d.ts +61 -34
- package/dist/src/Crypto.d.ts.map +1 -1
- package/dist/src/Crypto.js +29 -42
- package/dist/src/Evolu/Db.d.ts +159 -66
- package/dist/src/Evolu/Db.d.ts.map +1 -1
- package/dist/src/Evolu/Db.js +300 -705
- package/dist/src/Evolu/Diff.d.ts +3 -3
- package/dist/src/Evolu/Diff.d.ts.map +1 -1
- package/dist/src/Evolu/Diff.js +7 -5
- package/dist/src/Evolu/Evolu.d.ts +200 -115
- package/dist/src/Evolu/Evolu.d.ts.map +1 -1
- package/dist/src/Evolu/Evolu.js +287 -157
- package/dist/src/Evolu/Internal.d.ts +0 -2
- package/dist/src/Evolu/Internal.d.ts.map +1 -1
- package/dist/src/Evolu/Internal.js +0 -2
- package/dist/src/Evolu/LocalAuth.d.ts +144 -0
- package/dist/src/Evolu/LocalAuth.d.ts.map +1 -0
- package/dist/src/Evolu/LocalAuth.js +171 -0
- package/dist/src/Evolu/Owner.d.ts +209 -124
- package/dist/src/Evolu/Owner.d.ts.map +1 -1
- package/dist/src/Evolu/Owner.js +118 -104
- package/dist/src/Evolu/Platform.d.ts +9 -7
- package/dist/src/Evolu/Platform.d.ts.map +1 -1
- package/dist/src/Evolu/Protocol.d.ts +256 -211
- package/dist/src/Evolu/Protocol.d.ts.map +1 -1
- package/dist/src/Evolu/Protocol.js +558 -359
- package/dist/src/Evolu/Public.d.ts +6 -8
- package/dist/src/Evolu/Public.d.ts.map +1 -1
- package/dist/src/Evolu/Public.js +2 -3
- package/dist/src/Evolu/PublicKysely.js +3 -3
- package/dist/src/Evolu/Query.d.ts +2 -1
- package/dist/src/Evolu/Query.d.ts.map +1 -1
- package/dist/src/Evolu/Relay.d.ts +72 -4
- package/dist/src/Evolu/Relay.d.ts.map +1 -1
- package/dist/src/Evolu/Relay.js +124 -13
- package/dist/src/Evolu/Schema.d.ts +129 -73
- package/dist/src/Evolu/Schema.d.ts.map +1 -1
- package/dist/src/Evolu/Schema.js +169 -89
- package/dist/src/Evolu/Storage.d.ts +159 -14
- package/dist/src/Evolu/Storage.d.ts.map +1 -1
- package/dist/src/Evolu/Storage.js +42 -32
- package/dist/src/Evolu/Sync.d.ts +68 -13
- package/dist/src/Evolu/Sync.d.ts.map +1 -1
- package/dist/src/Evolu/Sync.js +414 -20
- package/dist/src/Evolu/Timestamp.d.ts +35 -27
- package/dist/src/Evolu/Timestamp.d.ts.map +1 -1
- package/dist/src/Evolu/Timestamp.js +27 -18
- package/dist/src/ManyToManyMap.d.ts +74 -10
- package/dist/src/ManyToManyMap.d.ts.map +1 -1
- package/dist/src/ManyToManyMap.js +41 -6
- package/dist/src/Number.d.ts +2 -1
- package/dist/src/Number.d.ts.map +1 -1
- package/dist/src/Random.d.ts +3 -2
- package/dist/src/Random.d.ts.map +1 -1
- package/dist/src/RefCountedResourceManager.d.ts +119 -0
- package/dist/src/RefCountedResourceManager.d.ts.map +1 -0
- package/dist/src/RefCountedResourceManager.js +197 -0
- package/dist/src/Result.d.ts +176 -51
- package/dist/src/Result.d.ts.map +1 -1
- package/dist/src/Result.js +30 -241
- package/dist/src/Sqlite.d.ts +21 -4
- package/dist/src/Sqlite.d.ts.map +1 -1
- package/dist/src/Sqlite.js +50 -8
- package/dist/src/Task.d.ts +511 -0
- package/dist/src/Task.d.ts.map +1 -0
- package/dist/src/Task.js +410 -0
- package/dist/src/Time.d.ts +59 -0
- package/dist/src/Time.d.ts.map +1 -1
- package/dist/src/Time.js +87 -4
- package/dist/src/Type.d.ts +474 -327
- package/dist/src/Type.d.ts.map +1 -1
- package/dist/src/Type.js +502 -436
- package/dist/src/Types.d.ts +0 -74
- package/dist/src/Types.d.ts.map +1 -1
- package/dist/src/WebSocket.d.ts +5 -2
- package/dist/src/WebSocket.d.ts.map +1 -1
- package/dist/src/WebSocket.js +12 -13
- package/dist/src/Worker.d.ts +39 -11
- package/dist/src/Worker.d.ts.map +1 -1
- package/dist/src/Worker.js +22 -4
- package/dist/src/index.d.ts +3 -3
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +3 -3
- package/package.json +14 -13
- package/src/Assert.ts +8 -7
- package/src/Brand.ts +75 -0
- package/src/Buffer.ts +1 -1
- package/src/CallbackRegistry.ts +84 -0
- package/src/Console.ts +91 -11
- package/src/Crypto.ts +94 -79
- package/src/Evolu/Db.ts +528 -1027
- package/src/Evolu/Diff.ts +7 -5
- package/src/Evolu/Evolu.ts +682 -329
- package/src/Evolu/Internal.ts +0 -2
- package/src/Evolu/LocalAuth.ts +422 -0
- package/src/Evolu/Owner.ts +282 -227
- package/src/Evolu/Platform.ts +9 -9
- package/src/Evolu/Protocol.ts +788 -640
- package/src/Evolu/Public.ts +7 -14
- package/src/Evolu/PublicKysely.ts +3 -3
- package/src/Evolu/Query.ts +2 -1
- package/src/Evolu/Relay.ts +238 -18
- package/src/Evolu/Schema.ts +391 -191
- package/src/Evolu/Storage.ts +275 -55
- package/src/Evolu/Sync.ts +708 -37
- package/src/Evolu/Timestamp.ts +38 -35
- package/src/ManyToManyMap.ts +127 -24
- package/src/Number.ts +2 -6
- package/src/Random.ts +3 -2
- package/src/RefCountedResourceManager.ts +368 -0
- package/src/Result.ts +183 -53
- package/src/Sqlite.ts +59 -23
- package/src/Task.ts +779 -0
- package/src/Time.ts +168 -4
- package/src/Type.ts +708 -660
- package/src/Types.ts +0 -76
- package/src/WebSocket.ts +23 -17
- package/src/Worker.ts +72 -23
- package/src/index.ts +3 -3
- package/dist/src/Callbacks.d.ts +0 -20
- package/dist/src/Callbacks.d.ts.map +0 -1
- package/dist/src/Callbacks.js +0 -18
- package/dist/src/Evolu/Config.d.ts +0 -69
- package/dist/src/Evolu/Config.d.ts.map +0 -1
- package/dist/src/Evolu/Config.js +0 -9
- package/dist/src/Evolu/Kysely.d.ts +0 -6
- package/dist/src/Evolu/Kysely.d.ts.map +0 -1
- package/dist/src/Evolu/Kysely.js +0 -21
- package/dist/src/NanoId.d.ts +0 -27
- package/dist/src/NanoId.d.ts.map +0 -1
- package/dist/src/NanoId.js +0 -6
- package/dist/src/Promise.d.ts +0 -180
- package/dist/src/Promise.d.ts.map +0 -1
- package/dist/src/Promise.js +0 -176
- package/src/Callbacks.ts +0 -43
- package/src/Evolu/Config.ts +0 -83
- package/src/Evolu/Kysely.ts +0 -38
- package/src/NanoId.ts +0 -39
- package/src/Promise.ts +0 -295
package/src/Promise.ts
DELETED
|
@@ -1,295 +0,0 @@
|
|
|
1
|
-
import { constTrue } from "./Function.js";
|
|
2
|
-
import { Result, err, ok } from "./Result.js";
|
|
3
|
-
import { Predicate } from "./Types.js";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Helper function to delay execution for a specified number of milliseconds.
|
|
7
|
-
*
|
|
8
|
-
* ### Example
|
|
9
|
-
*
|
|
10
|
-
* ```ts
|
|
11
|
-
* await wait(10);
|
|
12
|
-
* ```
|
|
13
|
-
*/
|
|
14
|
-
export const wait = (ms: number): Promise<Result<void, never>> =>
|
|
15
|
-
new Promise((resolve) =>
|
|
16
|
-
setTimeout(() => {
|
|
17
|
-
resolve(ok());
|
|
18
|
-
}, ms),
|
|
19
|
-
);
|
|
20
|
-
|
|
21
|
-
/** Options for configuring retry behavior. */
|
|
22
|
-
export interface RetryOptions<E> {
|
|
23
|
-
/**
|
|
24
|
-
* Maximum number of retry attempts after the initial attempt (default: 3).
|
|
25
|
-
* For example, with maxRetries = 3, the function will be called up to 4 times
|
|
26
|
-
* (1 initial attempt + 3 retries).
|
|
27
|
-
*/
|
|
28
|
-
maxRetries?: number;
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Initial delay between retry attempts in milliseconds (default: 100). This
|
|
32
|
-
* is the delay after the first failed attempt. Subsequent delays increase
|
|
33
|
-
* exponentially according to the factor option.
|
|
34
|
-
*/
|
|
35
|
-
initialDelay?: number;
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Maximum delay between retry attempts in milliseconds (default: 10000). This
|
|
39
|
-
* caps the exponential backoff to prevent extremely long delays after many
|
|
40
|
-
* retries.
|
|
41
|
-
*/
|
|
42
|
-
maxDelay?: number;
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Multiplier that determines how quickly the delay increases (default: 2).
|
|
46
|
-
* With the default value, each successive delay is twice as long as the
|
|
47
|
-
* previous one (e.g., 100ms, 200ms, 400ms, 800ms, etc).
|
|
48
|
-
*/
|
|
49
|
-
factor?: number;
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Random jitter factor between 0 and 1 (default: 0.1). Adds randomness to
|
|
53
|
-
* delay times to prevent retry storms in distributed systems.
|
|
54
|
-
*/
|
|
55
|
-
jitter?: number;
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Optional AbortSignal to cancel retries. If the signal is aborted, the retry
|
|
59
|
-
* operation stops and returns a RetryAbortError.
|
|
60
|
-
*/
|
|
61
|
-
signal?: AbortSignal;
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Optional predicate to determine if an error should be retried. Returns true
|
|
65
|
-
* if the error is retryable, false otherwise. This allows selectively
|
|
66
|
-
* retrying only certain types of errors. By default, all errors are
|
|
67
|
-
* considered retryable.
|
|
68
|
-
*/
|
|
69
|
-
retryable?: Predicate<E>;
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Optional callback called before each retry attempt. Receives the error that
|
|
73
|
-
* caused the retry, the current attempt number (starting at 1), and the delay
|
|
74
|
-
* in milliseconds before the next attempt.
|
|
75
|
-
*/
|
|
76
|
-
onRetry?: (error: E, attempt: number, delay: number) => void;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/** Error representing a retry operation that failed after multiple attempts. */
|
|
80
|
-
export interface RetryError<E> {
|
|
81
|
-
readonly type: "RetryError";
|
|
82
|
-
/** The original error that caused the retry to fail */
|
|
83
|
-
readonly cause: E;
|
|
84
|
-
/** Number of retry attempts made */
|
|
85
|
-
readonly attempts: number;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/** Error representing a retry operation that was aborted. */
|
|
89
|
-
export interface RetryAbortError {
|
|
90
|
-
readonly type: "RetryAbortError";
|
|
91
|
-
readonly abortedBeforeExecution: boolean;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Executes a function with retry logic using exponential backoff and jitter.
|
|
96
|
-
*
|
|
97
|
-
* ### Example with Result-based API
|
|
98
|
-
*
|
|
99
|
-
* ```ts
|
|
100
|
-
* interface ApiError {
|
|
101
|
-
* type: "ApiError";
|
|
102
|
-
* statusCode: number;
|
|
103
|
-
* }
|
|
104
|
-
*
|
|
105
|
-
* const fetchData = async (
|
|
106
|
-
* url: string,
|
|
107
|
-
* ): Promise<Result<Data, ApiError>> => {
|
|
108
|
-
* // Implementation that returns Result
|
|
109
|
-
* };
|
|
110
|
-
*
|
|
111
|
-
* const result = await retry(
|
|
112
|
-
* async () => fetchData("https://api.example.com/data"),
|
|
113
|
-
* {
|
|
114
|
-
* maxRetries: 5,
|
|
115
|
-
* initialDelay: 200,
|
|
116
|
-
* // Only retry on specific status codes
|
|
117
|
-
* retryable: (error) =>
|
|
118
|
-
* error.type === "ApiError" && [429, 503].includes(error.statusCode),
|
|
119
|
-
* },
|
|
120
|
-
* );
|
|
121
|
-
*
|
|
122
|
-
* if (!result.ok) {
|
|
123
|
-
* if (result.error.type === "RetryAbortError") {
|
|
124
|
-
* console.log("Operation was aborted");
|
|
125
|
-
* } else {
|
|
126
|
-
* console.log(`Failed after ${result.error.attempts} attempts`);
|
|
127
|
-
* }
|
|
128
|
-
* return;
|
|
129
|
-
* }
|
|
130
|
-
*
|
|
131
|
-
* // Use result.value
|
|
132
|
-
* ```
|
|
133
|
-
*
|
|
134
|
-
* ### Example with tryAsync for exception-based API
|
|
135
|
-
*
|
|
136
|
-
* ```ts
|
|
137
|
-
* interface FetchError {
|
|
138
|
-
* type: "FetchError";
|
|
139
|
-
* message: string;
|
|
140
|
-
* }
|
|
141
|
-
*
|
|
142
|
-
* const controller = new AbortController();
|
|
143
|
-
*
|
|
144
|
-
* const result = await retry(
|
|
145
|
-
* async () =>
|
|
146
|
-
* tryAsync(
|
|
147
|
-
* async () => {
|
|
148
|
-
* const response = await fetch("https://api.example.com/data", {
|
|
149
|
-
* signal: controller.signal,
|
|
150
|
-
* });
|
|
151
|
-
*
|
|
152
|
-
* if (!response.ok) {
|
|
153
|
-
* throw new Error(`HTTP error ${response.status}`);
|
|
154
|
-
* }
|
|
155
|
-
*
|
|
156
|
-
* return await response.json();
|
|
157
|
-
* },
|
|
158
|
-
* (error): FetchError => ({
|
|
159
|
-
* type: "FetchError",
|
|
160
|
-
* message: String(error),
|
|
161
|
-
* }),
|
|
162
|
-
* ),
|
|
163
|
-
* {
|
|
164
|
-
* maxRetries: 3,
|
|
165
|
-
* signal: controller.signal,
|
|
166
|
-
* },
|
|
167
|
-
* );
|
|
168
|
-
* ```
|
|
169
|
-
*
|
|
170
|
-
* ## HTTP Request Recommendations
|
|
171
|
-
*
|
|
172
|
-
* For HTTP requests, configure the `retryable` option to only retry on
|
|
173
|
-
* appropriate errors:
|
|
174
|
-
*
|
|
175
|
-
* - **DO retry**: 429 (Too Many Requests), 503 (Service Unavailable), network
|
|
176
|
-
* errors
|
|
177
|
-
* - **DON'T retry**: 4xx client errors (except 429), most 5xx server errors
|
|
178
|
-
*/
|
|
179
|
-
export const retry = async <T, E>(
|
|
180
|
-
fn: () => Promise<Result<T, E>>,
|
|
181
|
-
options: RetryOptions<E> = {},
|
|
182
|
-
): Promise<Result<T, RetryError<E> | RetryAbortError>> => {
|
|
183
|
-
const {
|
|
184
|
-
maxRetries = 3,
|
|
185
|
-
initialDelay = 100,
|
|
186
|
-
maxDelay = 10000,
|
|
187
|
-
factor = 2,
|
|
188
|
-
jitter = 0.1,
|
|
189
|
-
signal,
|
|
190
|
-
retryable = constTrue,
|
|
191
|
-
onRetry,
|
|
192
|
-
} = options;
|
|
193
|
-
|
|
194
|
-
let attempt = 0;
|
|
195
|
-
|
|
196
|
-
if (signal?.aborted) {
|
|
197
|
-
return err({ type: "RetryAbortError", abortedBeforeExecution: true });
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
201
|
-
while (true) {
|
|
202
|
-
const result = await fn();
|
|
203
|
-
|
|
204
|
-
if (result.ok) {
|
|
205
|
-
return result;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
attempt += 1;
|
|
209
|
-
|
|
210
|
-
if (attempt > maxRetries || !retryable(result.error)) {
|
|
211
|
-
return err({
|
|
212
|
-
type: "RetryError",
|
|
213
|
-
cause: result.error,
|
|
214
|
-
attempts: attempt,
|
|
215
|
-
});
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
// Calculate delay with exponential backoff
|
|
219
|
-
const exponentialDelay = initialDelay * Math.pow(factor, attempt);
|
|
220
|
-
const cappedDelay = Math.min(exponentialDelay, maxDelay);
|
|
221
|
-
|
|
222
|
-
// Apply jitter to prevent thundering herd problem
|
|
223
|
-
const randomFactor = 1 - jitter + Math.random() * jitter * 2;
|
|
224
|
-
const delay = Math.floor(cappedDelay * randomFactor);
|
|
225
|
-
|
|
226
|
-
if (onRetry) {
|
|
227
|
-
onRetry(result.error, attempt, delay);
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
if (signal?.aborted) {
|
|
231
|
-
return err({ type: "RetryAbortError", abortedBeforeExecution: false });
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
// Wait with abort support
|
|
235
|
-
if (signal) {
|
|
236
|
-
const abortPromise = new Promise<Result<never, RetryAbortError>>(
|
|
237
|
-
(resolve) => {
|
|
238
|
-
const onAbort = () => {
|
|
239
|
-
resolve(
|
|
240
|
-
err({ type: "RetryAbortError", abortedBeforeExecution: false }),
|
|
241
|
-
);
|
|
242
|
-
};
|
|
243
|
-
signal.addEventListener("abort", onAbort, { once: true });
|
|
244
|
-
},
|
|
245
|
-
);
|
|
246
|
-
|
|
247
|
-
const delayPromise = wait(delay);
|
|
248
|
-
const raceResult = await Promise.race([abortPromise, delayPromise]);
|
|
249
|
-
|
|
250
|
-
if (!raceResult.ok) {
|
|
251
|
-
return raceResult;
|
|
252
|
-
}
|
|
253
|
-
} else {
|
|
254
|
-
await wait(delay);
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
};
|
|
258
|
-
|
|
259
|
-
export interface TimeoutError {
|
|
260
|
-
readonly type: "TimeoutError";
|
|
261
|
-
readonly timeoutMs: number;
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
/**
|
|
265
|
-
* Wraps an async function with a timeout, returning {@link Result} that fails
|
|
266
|
-
* with {@link TimeoutError} if the timeout is exceeded. The provided function
|
|
267
|
-
* must accept an AbortSignal and return a Result.
|
|
268
|
-
*
|
|
269
|
-
* ### Example
|
|
270
|
-
*
|
|
271
|
-
* ```ts
|
|
272
|
-
* const fetchWithTimeout = () =>
|
|
273
|
-
* withTimeout((signal) => fetch("url", signal), 5000);
|
|
274
|
-
* const result = await retry(fetchWithTimeout, { maxRetries: 3 });
|
|
275
|
-
* ```
|
|
276
|
-
*/
|
|
277
|
-
export const withTimeout = async <T, E>(
|
|
278
|
-
fn: (signal: AbortSignal) => Promise<Result<T, E>>,
|
|
279
|
-
timeoutMs: number,
|
|
280
|
-
): Promise<Result<T, E | TimeoutError>> => {
|
|
281
|
-
const controller = new AbortController();
|
|
282
|
-
const signal = controller.signal;
|
|
283
|
-
const timeoutId = setTimeout(() => {
|
|
284
|
-
controller.abort();
|
|
285
|
-
}, timeoutMs);
|
|
286
|
-
|
|
287
|
-
const result = await fn(signal);
|
|
288
|
-
clearTimeout(timeoutId);
|
|
289
|
-
|
|
290
|
-
if (signal.aborted) {
|
|
291
|
-
return err({ type: "TimeoutError", timeoutMs });
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
return result;
|
|
295
|
-
};
|