@evolu/common 8.5.0 → 8.6.1

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.
Files changed (328) hide show
  1. package/dist/src/Array.d.ts +170 -97
  2. package/dist/src/Array.d.ts.map +1 -1
  3. package/dist/src/Array.js +67 -42
  4. package/dist/src/Assert.d.ts +233 -30
  5. package/dist/src/Assert.d.ts.map +1 -1
  6. package/dist/src/Assert.js +150 -30
  7. package/dist/src/BigInt.d.ts +3 -3
  8. package/dist/src/BigInt.js +3 -3
  9. package/dist/src/Brand.d.ts +7 -7
  10. package/dist/src/Buffer.d.ts +12 -4
  11. package/dist/src/Buffer.d.ts.map +1 -1
  12. package/dist/src/Cache.d.ts +8 -3
  13. package/dist/src/Cache.d.ts.map +1 -1
  14. package/dist/src/Cache.js +8 -3
  15. package/dist/src/Callbacks.d.ts +8 -4
  16. package/dist/src/Callbacks.d.ts.map +1 -1
  17. package/dist/src/Console.d.ts +45 -30
  18. package/dist/src/Console.d.ts.map +1 -1
  19. package/dist/src/Console.js +32 -21
  20. package/dist/src/Crypto.d.ts +13 -8
  21. package/dist/src/Crypto.d.ts.map +1 -1
  22. package/dist/src/Crypto.js +6 -3
  23. package/dist/src/Eq.d.ts +107 -58
  24. package/dist/src/Eq.d.ts.map +1 -1
  25. package/dist/src/Eq.js +308 -112
  26. package/dist/src/Function.d.ts +54 -24
  27. package/dist/src/Function.d.ts.map +1 -1
  28. package/dist/src/Function.js +34 -17
  29. package/dist/src/Http.d.ts +52 -19
  30. package/dist/src/Http.d.ts.map +1 -1
  31. package/dist/src/Identicon.d.ts +9 -4
  32. package/dist/src/Identicon.d.ts.map +1 -1
  33. package/dist/src/Identicon.js +9 -4
  34. package/dist/src/LockManager.d.ts +12 -10
  35. package/dist/src/LockManager.d.ts.map +1 -1
  36. package/dist/src/Lookup.d.ts +4 -2
  37. package/dist/src/Lookup.d.ts.map +1 -1
  38. package/dist/src/Lookup.js +4 -2
  39. package/dist/src/Number.d.ts +28 -24
  40. package/dist/src/Number.d.ts.map +1 -1
  41. package/dist/src/Number.js +16 -17
  42. package/dist/src/Object.d.ts +89 -47
  43. package/dist/src/Object.d.ts.map +1 -1
  44. package/dist/src/Object.js +88 -41
  45. package/dist/src/Option.d.ts +14 -5
  46. package/dist/src/Option.d.ts.map +1 -1
  47. package/dist/src/Option.js +14 -5
  48. package/dist/src/Order.d.ts +12 -12
  49. package/dist/src/Order.js +12 -12
  50. package/dist/src/Platform.d.ts +2 -2
  51. package/dist/src/Random.d.ts +7 -4
  52. package/dist/src/Random.d.ts.map +1 -1
  53. package/dist/src/Redacted.d.ts +13 -6
  54. package/dist/src/Redacted.d.ts.map +1 -1
  55. package/dist/src/Redacted.js +4 -2
  56. package/dist/src/Ref.d.ts +4 -4
  57. package/dist/src/Relation.d.ts +5 -7
  58. package/dist/src/Relation.d.ts.map +1 -1
  59. package/dist/src/Resource.d.ts +27 -12
  60. package/dist/src/Resource.d.ts.map +1 -1
  61. package/dist/src/Result.d.ts +258 -114
  62. package/dist/src/Result.d.ts.map +1 -1
  63. package/dist/src/Result.js +71 -34
  64. package/dist/src/Schedule.d.ts +233 -116
  65. package/dist/src/Schedule.d.ts.map +1 -1
  66. package/dist/src/Schedule.js +204 -110
  67. package/dist/src/Set.d.ts +43 -24
  68. package/dist/src/Set.d.ts.map +1 -1
  69. package/dist/src/Set.js +25 -13
  70. package/dist/src/Sqlite.d.ts +4 -4
  71. package/dist/src/Sqlite.d.ts.map +1 -1
  72. package/dist/src/Sqlite.js +9 -8
  73. package/dist/src/Task.d.ts +441 -212
  74. package/dist/src/Task.d.ts.map +1 -1
  75. package/dist/src/Task.js +238 -115
  76. package/dist/src/Test.d.ts +10 -4
  77. package/dist/src/Test.d.ts.map +1 -1
  78. package/dist/src/Test.js +10 -4
  79. package/dist/src/Time.d.ts +27 -17
  80. package/dist/src/Time.d.ts.map +1 -1
  81. package/dist/src/Time.js +16 -6
  82. package/dist/src/Type.d.ts +1096 -387
  83. package/dist/src/Type.d.ts.map +1 -1
  84. package/dist/src/Type.js +1046 -372
  85. package/dist/src/Types.d.ts +95 -40
  86. package/dist/src/Types.d.ts.map +1 -1
  87. package/dist/src/Types.js +13 -4
  88. package/dist/src/WebSocket.d.ts +14 -6
  89. package/dist/src/WebSocket.d.ts.map +1 -1
  90. package/dist/src/Worker.d.ts +10 -6
  91. package/dist/src/Worker.d.ts.map +1 -1
  92. package/dist/src/intl/_en.d.ts +3 -1
  93. package/dist/src/intl/_en.d.ts.map +1 -1
  94. package/dist/src/intl/_en.js +17 -3
  95. package/dist/src/intl/ar.d.ts +3 -1
  96. package/dist/src/intl/ar.d.ts.map +1 -1
  97. package/dist/src/intl/ar.js +15 -2
  98. package/dist/src/intl/bn.d.ts +3 -1
  99. package/dist/src/intl/bn.d.ts.map +1 -1
  100. package/dist/src/intl/bn.js +16 -3
  101. package/dist/src/intl/ca.d.ts +3 -1
  102. package/dist/src/intl/ca.d.ts.map +1 -1
  103. package/dist/src/intl/ca.js +16 -3
  104. package/dist/src/intl/cs.d.ts +3 -1
  105. package/dist/src/intl/cs.d.ts.map +1 -1
  106. package/dist/src/intl/cs.js +16 -3
  107. package/dist/src/intl/da.d.ts +3 -1
  108. package/dist/src/intl/da.d.ts.map +1 -1
  109. package/dist/src/intl/da.js +16 -3
  110. package/dist/src/intl/de.d.ts +3 -1
  111. package/dist/src/intl/de.d.ts.map +1 -1
  112. package/dist/src/intl/de.js +16 -3
  113. package/dist/src/intl/el.d.ts +3 -1
  114. package/dist/src/intl/el.d.ts.map +1 -1
  115. package/dist/src/intl/el.js +16 -3
  116. package/dist/src/intl/es.d.ts +3 -1
  117. package/dist/src/intl/es.d.ts.map +1 -1
  118. package/dist/src/intl/es.js +16 -3
  119. package/dist/src/intl/fa.d.ts +3 -1
  120. package/dist/src/intl/fa.d.ts.map +1 -1
  121. package/dist/src/intl/fa.js +16 -3
  122. package/dist/src/intl/fi.d.ts +3 -1
  123. package/dist/src/intl/fi.d.ts.map +1 -1
  124. package/dist/src/intl/fi.js +16 -3
  125. package/dist/src/intl/fil.d.ts +3 -1
  126. package/dist/src/intl/fil.d.ts.map +1 -1
  127. package/dist/src/intl/fil.js +16 -3
  128. package/dist/src/intl/fr.d.ts +3 -1
  129. package/dist/src/intl/fr.d.ts.map +1 -1
  130. package/dist/src/intl/fr.js +16 -3
  131. package/dist/src/intl/he.d.ts +3 -1
  132. package/dist/src/intl/he.d.ts.map +1 -1
  133. package/dist/src/intl/he.js +16 -3
  134. package/dist/src/intl/hi.d.ts +3 -1
  135. package/dist/src/intl/hi.d.ts.map +1 -1
  136. package/dist/src/intl/hi.js +16 -3
  137. package/dist/src/intl/hr.d.ts +3 -1
  138. package/dist/src/intl/hr.d.ts.map +1 -1
  139. package/dist/src/intl/hr.js +16 -3
  140. package/dist/src/intl/hu.d.ts +2 -1
  141. package/dist/src/intl/hu.d.ts.map +1 -1
  142. package/dist/src/intl/hu.js +15 -3
  143. package/dist/src/intl/id.d.ts +3 -1
  144. package/dist/src/intl/id.d.ts.map +1 -1
  145. package/dist/src/intl/id.js +16 -3
  146. package/dist/src/intl/it.d.ts +3 -1
  147. package/dist/src/intl/it.d.ts.map +1 -1
  148. package/dist/src/intl/it.js +16 -3
  149. package/dist/src/intl/ja.d.ts +3 -1
  150. package/dist/src/intl/ja.d.ts.map +1 -1
  151. package/dist/src/intl/ja.js +16 -3
  152. package/dist/src/intl/ko.d.ts +3 -1
  153. package/dist/src/intl/ko.d.ts.map +1 -1
  154. package/dist/src/intl/ko.js +16 -3
  155. package/dist/src/intl/ml.d.ts +3 -1
  156. package/dist/src/intl/ml.d.ts.map +1 -1
  157. package/dist/src/intl/ml.js +16 -3
  158. package/dist/src/intl/mr.d.ts +3 -1
  159. package/dist/src/intl/mr.d.ts.map +1 -1
  160. package/dist/src/intl/mr.js +16 -3
  161. package/dist/src/intl/ms.d.ts +3 -1
  162. package/dist/src/intl/ms.d.ts.map +1 -1
  163. package/dist/src/intl/ms.js +15 -2
  164. package/dist/src/intl/nb.d.ts +2 -1
  165. package/dist/src/intl/nb.d.ts.map +1 -1
  166. package/dist/src/intl/nb.js +14 -2
  167. package/dist/src/intl/nl.d.ts +3 -1
  168. package/dist/src/intl/nl.d.ts.map +1 -1
  169. package/dist/src/intl/nl.js +16 -3
  170. package/dist/src/intl/pa.d.ts +3 -1
  171. package/dist/src/intl/pa.d.ts.map +1 -1
  172. package/dist/src/intl/pa.js +16 -3
  173. package/dist/src/intl/pl.d.ts +2 -0
  174. package/dist/src/intl/pl.d.ts.map +1 -1
  175. package/dist/src/intl/pl.js +15 -2
  176. package/dist/src/intl/pt-BR.d.ts +3 -1
  177. package/dist/src/intl/pt-BR.d.ts.map +1 -1
  178. package/dist/src/intl/pt-BR.js +16 -3
  179. package/dist/src/intl/pt.d.ts +3 -1
  180. package/dist/src/intl/pt.d.ts.map +1 -1
  181. package/dist/src/intl/pt.js +15 -2
  182. package/dist/src/intl/ro.d.ts +3 -1
  183. package/dist/src/intl/ro.d.ts.map +1 -1
  184. package/dist/src/intl/ro.js +16 -3
  185. package/dist/src/intl/sk.d.ts +3 -1
  186. package/dist/src/intl/sk.d.ts.map +1 -1
  187. package/dist/src/intl/sk.js +15 -2
  188. package/dist/src/intl/sl.d.ts +3 -1
  189. package/dist/src/intl/sl.d.ts.map +1 -1
  190. package/dist/src/intl/sl.js +16 -3
  191. package/dist/src/intl/sv.d.ts +3 -1
  192. package/dist/src/intl/sv.d.ts.map +1 -1
  193. package/dist/src/intl/sv.js +16 -3
  194. package/dist/src/intl/sw.d.ts +1 -0
  195. package/dist/src/intl/sw.d.ts.map +1 -1
  196. package/dist/src/intl/sw.js +14 -2
  197. package/dist/src/intl/ta.d.ts +3 -1
  198. package/dist/src/intl/ta.d.ts.map +1 -1
  199. package/dist/src/intl/ta.js +16 -3
  200. package/dist/src/intl/te.d.ts +3 -1
  201. package/dist/src/intl/te.d.ts.map +1 -1
  202. package/dist/src/intl/te.js +16 -3
  203. package/dist/src/intl/th.d.ts +3 -1
  204. package/dist/src/intl/th.d.ts.map +1 -1
  205. package/dist/src/intl/th.js +16 -3
  206. package/dist/src/intl/tr.d.ts +3 -1
  207. package/dist/src/intl/tr.d.ts.map +1 -1
  208. package/dist/src/intl/tr.js +16 -3
  209. package/dist/src/intl/uk.d.ts +3 -1
  210. package/dist/src/intl/uk.d.ts.map +1 -1
  211. package/dist/src/intl/uk.js +16 -3
  212. package/dist/src/intl/ur.d.ts +3 -1
  213. package/dist/src/intl/ur.d.ts.map +1 -1
  214. package/dist/src/intl/ur.js +15 -2
  215. package/dist/src/intl/vi.d.ts +3 -1
  216. package/dist/src/intl/vi.d.ts.map +1 -1
  217. package/dist/src/intl/vi.js +16 -3
  218. package/dist/src/intl/zh-CN.d.ts +3 -1
  219. package/dist/src/intl/zh-CN.d.ts.map +1 -1
  220. package/dist/src/intl/zh-CN.js +16 -3
  221. package/dist/src/intl/zh-TW.d.ts +3 -1
  222. package/dist/src/intl/zh-TW.d.ts.map +1 -1
  223. package/dist/src/intl/zh-TW.js +16 -3
  224. package/dist/src/local-first/Evolu.d.ts +47 -24
  225. package/dist/src/local-first/Evolu.d.ts.map +1 -1
  226. package/dist/src/local-first/Owner.d.ts +10 -7
  227. package/dist/src/local-first/Owner.d.ts.map +1 -1
  228. package/dist/src/local-first/Owner.js +10 -7
  229. package/dist/src/local-first/Protocol.d.ts +5 -5
  230. package/dist/src/local-first/Protocol.js +7 -7
  231. package/dist/src/local-first/Query.d.ts +34 -21
  232. package/dist/src/local-first/Query.d.ts.map +1 -1
  233. package/dist/src/local-first/Query.js +25 -13
  234. package/dist/src/local-first/Relay.d.ts +12 -5
  235. package/dist/src/local-first/Relay.d.ts.map +1 -1
  236. package/dist/src/local-first/Schema.d.ts +19 -11
  237. package/dist/src/local-first/Schema.d.ts.map +1 -1
  238. package/dist/src/local-first/Schema.js +11 -6
  239. package/dist/src/local-first/Storage.d.ts +4 -2
  240. package/dist/src/local-first/Storage.d.ts.map +1 -1
  241. package/package.json +3 -4
  242. package/src/Array.ts +170 -97
  243. package/src/Assert.ts +336 -31
  244. package/src/BigInt.ts +3 -3
  245. package/src/Brand.ts +7 -7
  246. package/src/Buffer.ts +12 -4
  247. package/src/Cache.ts +8 -3
  248. package/src/Callbacks.ts +8 -4
  249. package/src/Console.ts +45 -30
  250. package/src/Crypto.ts +13 -8
  251. package/src/Eq.ts +450 -122
  252. package/src/Function.ts +54 -24
  253. package/src/Http.ts +52 -19
  254. package/src/Identicon.ts +9 -4
  255. package/src/LockManager.ts +12 -10
  256. package/src/Lookup.ts +4 -2
  257. package/src/Number.ts +28 -24
  258. package/src/Object.ts +115 -49
  259. package/src/Option.ts +14 -5
  260. package/src/Order.ts +12 -12
  261. package/src/Platform.ts +2 -2
  262. package/src/Random.ts +7 -4
  263. package/src/Redacted.ts +13 -6
  264. package/src/Ref.ts +4 -4
  265. package/src/Relation.ts +5 -7
  266. package/src/Resource.ts +27 -12
  267. package/src/Result.ts +258 -114
  268. package/src/Schedule.ts +233 -116
  269. package/src/Set.ts +43 -24
  270. package/src/Sqlite.ts +9 -8
  271. package/src/Task.ts +441 -212
  272. package/src/Test.ts +10 -4
  273. package/src/Time.ts +27 -17
  274. package/src/Type.ts +2077 -620
  275. package/src/Types.ts +108 -40
  276. package/src/WebSocket.ts +14 -6
  277. package/src/Worker.ts +10 -6
  278. package/src/intl/_en.ts +20 -4
  279. package/src/intl/ar.ts +17 -2
  280. package/src/intl/bn.ts +19 -4
  281. package/src/intl/ca.ts +19 -4
  282. package/src/intl/cs.ts +19 -4
  283. package/src/intl/da.ts +19 -4
  284. package/src/intl/de.ts +19 -4
  285. package/src/intl/el.ts +19 -4
  286. package/src/intl/es.ts +19 -4
  287. package/src/intl/fa.ts +19 -4
  288. package/src/intl/fi.ts +19 -4
  289. package/src/intl/fil.ts +19 -4
  290. package/src/intl/fr.ts +19 -4
  291. package/src/intl/he.ts +19 -4
  292. package/src/intl/hi.ts +19 -4
  293. package/src/intl/hr.ts +19 -4
  294. package/src/intl/hu.ts +18 -4
  295. package/src/intl/id.ts +19 -4
  296. package/src/intl/it.ts +19 -4
  297. package/src/intl/ja.ts +19 -4
  298. package/src/intl/ko.ts +19 -4
  299. package/src/intl/ml.ts +19 -4
  300. package/src/intl/mr.ts +19 -4
  301. package/src/intl/ms.ts +17 -2
  302. package/src/intl/nb.ts +16 -2
  303. package/src/intl/nl.ts +19 -4
  304. package/src/intl/pa.ts +19 -4
  305. package/src/intl/pl.ts +18 -2
  306. package/src/intl/pt-BR.ts +19 -4
  307. package/src/intl/pt.ts +17 -2
  308. package/src/intl/ro.ts +19 -4
  309. package/src/intl/sk.ts +17 -2
  310. package/src/intl/sl.ts +19 -4
  311. package/src/intl/sv.ts +19 -4
  312. package/src/intl/sw.ts +15 -2
  313. package/src/intl/ta.ts +19 -4
  314. package/src/intl/te.ts +19 -4
  315. package/src/intl/th.ts +19 -4
  316. package/src/intl/tr.ts +19 -4
  317. package/src/intl/uk.ts +19 -4
  318. package/src/intl/ur.ts +17 -2
  319. package/src/intl/vi.ts +19 -3
  320. package/src/intl/zh-CN.ts +19 -4
  321. package/src/intl/zh-TW.ts +19 -4
  322. package/src/local-first/Evolu.ts +47 -24
  323. package/src/local-first/Owner.ts +10 -7
  324. package/src/local-first/Protocol.ts +7 -7
  325. package/src/local-first/Query.ts +34 -21
  326. package/src/local-first/Relay.ts +12 -5
  327. package/src/local-first/Schema.ts +19 -11
  328. package/src/local-first/Storage.ts +4 -2
@@ -1,6 +1,4 @@
1
1
  /**
2
- * ## Intro
3
- *
4
2
  * JavaScript-native structured concurrency.
5
3
  *
6
4
  * Structured concurrency organizes running tasks into a tree. Every child
@@ -34,6 +32,8 @@
34
32
  *
35
33
  * ```ts
36
34
  * import {
35
+ * assertOk,
36
+ * assertType,
37
37
  * createRun,
38
38
  * err,
39
39
  * ok,
@@ -76,8 +76,8 @@
76
76
  * });
77
77
  *
78
78
  * const result = await run(getUser(user.id));
79
- * expectTypeOf(result).toEqualTypeOf<Result<User, UserNotFoundError>>();
80
- * expectOk(result, user);
79
+ * assertType<Result<User, UserNotFoundError>, typeof result>();
80
+ * assertOk(result, user);
81
81
  * ```
82
82
  *
83
83
  * In composition roots, prefer the lifecycle API from the matching Evolu
@@ -120,6 +120,8 @@
120
120
  *
121
121
  * ```ts
122
122
  * import {
123
+ * assertOk,
124
+ * assertType,
123
125
  * createRun,
124
126
  * err,
125
127
  * ok,
@@ -178,13 +180,14 @@
178
180
  *
179
181
  * await using run = createRun();
180
182
  * const result = await run(getUserWithProfile("user-1"));
181
- * expectTypeOf(result).toEqualTypeOf<
183
+ * assertType<
182
184
  * Result<
183
185
  * { readonly user: User; readonly profile: Profile },
184
186
  * UserNotFoundError | ProfileNotFoundError
185
- * >
187
+ * >,
188
+ * typeof result
186
189
  * >();
187
- * expectOk(result, {
190
+ * assertOk(result, {
188
191
  * user: { id: "user-1", profileId: "profile-1" },
189
192
  * profile: { id: "profile-1" },
190
193
  * });
@@ -203,6 +206,7 @@
203
206
  *
204
207
  * ```ts
205
208
  * import {
209
+ * assertType,
206
210
  * exponential,
207
211
  * fetch,
208
212
  * jitter,
@@ -223,8 +227,9 @@
223
227
  * jitter("100%")(maxDelay("20s")(take(2)(exponential("100ms")))),
224
228
  * );
225
229
  *
226
- * expectTypeOf(fetchWithRetry).returns.toEqualTypeOf<
227
- * Task<string, RetryTaskError<FetchError | TimeoutError>>
230
+ * assertType<
231
+ * Task<string, RetryTaskError<FetchError | TimeoutError>>,
232
+ * ReturnType<typeof fetchWithRetry>
228
233
  * >();
229
234
  * ```
230
235
  *
@@ -233,7 +238,15 @@
233
238
  * Run composed Tasks with a `concurrency` option and {@link all}:
234
239
  *
235
240
  * ```ts
236
- * import { all, createRun, ok, sleep, type Task } from "@evolu/common";
241
+ * import {
242
+ * assertEqual,
243
+ * assertOk,
244
+ * all,
245
+ * createRun,
246
+ * ok,
247
+ * sleep,
248
+ * type Task,
249
+ * } from "@evolu/common";
237
250
  *
238
251
  * await using run = createRun();
239
252
  *
@@ -256,8 +269,8 @@
256
269
  *
257
270
  * // At most 2 concurrent requests.
258
271
  * const result = await run(all(urls, fetchUrl, { concurrency: 2 }));
259
- * expectOk(result, urls);
260
- * expect(maxActiveRequests).toBe(2);
272
+ * assertOk(result, urls);
273
+ * assertEqual(maxActiveRequests, 2);
261
274
  * ```
262
275
  *
263
276
  * Task helpers compose Tasks; concurrency primitives are stateful objects that
@@ -289,7 +302,7 @@
289
302
  * resources, or services shared by all code running inside a Run.
290
303
  *
291
304
  * ```ts
292
- * import { createRun, ok, type Task } from "@evolu/common";
305
+ * import { assertOk, createRun, ok, type Task } from "@evolu/common";
293
306
  *
294
307
  * interface GreetingFormatter {
295
308
  * readonly format: (name: string) => string;
@@ -314,10 +327,10 @@
314
327
  * await using run = createRun({ greetingFormatter: formal });
315
328
  *
316
329
  * // Root dependencies are inherited.
317
- * expectOk(await run(greet("Ada")), "Hello, Ada");
330
+ * assertOk(await run(greet("Ada")), "Hello, Ada");
318
331
  *
319
332
  * // Child-specific dependencies replace the root's custom dependencies.
320
- * expectOk(
333
+ * assertOk(
321
334
  * await run(greet("Ada"), { greetingFormatter: casual }),
322
335
  * "Hi, Ada",
323
336
  * );
@@ -368,7 +381,15 @@
368
381
  * `undefined` should represent valid absence, not failure.
369
382
  *
370
383
  * ```ts
371
- * import { createRun, ok, type Task, type Typed } from "@evolu/common";
384
+ * import {
385
+ * assertEqual,
386
+ * assertFalse,
387
+ * assertTrue,
388
+ * createRun,
389
+ * ok,
390
+ * type Task,
391
+ * type Typed,
392
+ * } from "@evolu/common";
372
393
  *
373
394
  * interface Socket extends AsyncDisposable {
374
395
  * readonly send: (message: string) => string;
@@ -382,8 +403,9 @@
382
403
  * const openSocket: Task<Socket, ConnectionFailedError> = () =>
383
404
  * ok({
384
405
  * send: (message) => message,
385
- * [Symbol.asyncDispose]: async () => {
406
+ * [Symbol.asyncDispose]: () => {
386
407
  * socketDisposed = true;
408
+ * return Promise.resolve();
387
409
  * },
388
410
  * });
389
411
  *
@@ -415,11 +437,11 @@
415
437
  *
416
438
  * await using run = createRun();
417
439
  * const result = await run(createConnection);
418
- * assert(result.ok);
419
- * expect(socketDisposed).toBe(false);
420
- * expect(result.value.send("hello")).toBe("hello");
440
+ * assertTrue(result.ok);
441
+ * assertFalse(socketDisposed);
442
+ * assertEqual(result.value.send("hello"), "hello");
421
443
  * await result.value[Symbol.asyncDispose]();
422
- * expect(socketDisposed).toBe(true);
444
+ * assertTrue(socketDisposed);
423
445
  * ```
424
446
  *
425
447
  * Use {@link Run.ok} with `await using` when a Task whose error type is `never`
@@ -576,7 +598,7 @@
576
598
  * each iteration reuses the same stack frame:
577
599
  *
578
600
  * ```ts
579
- * import { createRun, ok, type Task } from "@evolu/common";
601
+ * import { assertOk, createRun, ok, type Task } from "@evolu/common";
580
602
  *
581
603
  * interface TreeNode {
582
604
  * readonly value: string;
@@ -600,7 +622,7 @@
600
622
  * };
601
623
  *
602
624
  * await using run = createRun();
603
- * expectOk(
625
+ * assertOk(
604
626
  * await run(
605
627
  * visitTree({
606
628
  * value: "root",
@@ -663,22 +685,34 @@ import type { Awaitable, ParameterIntersection, Predicate } from "./Types.ts";
663
685
  * A Task that can't fail with a domain error:
664
686
  *
665
687
  * ```ts
666
- * import { createRun, ok, type Task } from "@evolu/common";
688
+ * import {
689
+ * assertEqual,
690
+ * assertOk,
691
+ * createRun,
692
+ * ok,
693
+ * type Task,
694
+ * } from "@evolu/common";
667
695
  *
668
696
  * const greet: Task<string> = () => ok("Hello!");
669
- * const main: Task<string> = async (run) => await run(greet);
697
+ * const main: Task<string> = (run) => run(greet);
670
698
  *
671
699
  * await using run = createRun();
672
- * expectOk(await run(main), "Hello!");
700
+ * assertOk(await run(main), "Hello!");
673
701
  *
674
702
  * // Without domain errors, `run.ok` returns the Ok value.
675
- * expect(await run.ok(main)).toBe("Hello!");
703
+ * assertEqual(await run.ok(main), "Hello!");
676
704
  * ```
677
705
  *
678
706
  * A Task that can fail with a domain error:
679
707
  *
680
708
  * ```ts
681
- * import { createRun, err, type Task, type Typed } from "@evolu/common";
709
+ * import {
710
+ * assertErr,
711
+ * createRun,
712
+ * err,
713
+ * type Task,
714
+ * type Typed,
715
+ * } from "@evolu/common";
682
716
  *
683
717
  * const findUser =
684
718
  * (id: string): Task<string, UserNotFoundError> =>
@@ -690,7 +724,7 @@ import type { Awaitable, ParameterIntersection, Predicate } from "./Types.ts";
690
724
  * }
691
725
  *
692
726
  * await using run = createRun();
693
- * expectErr(await run(findUser("user-1")), {
727
+ * assertErr(await run(findUser("user-1")), {
694
728
  * type: "UserNotFound",
695
729
  * id: "user-1",
696
730
  * });
@@ -699,7 +733,7 @@ import type { Awaitable, ParameterIntersection, Predicate } from "./Types.ts";
699
733
  * A Task with dependencies:
700
734
  *
701
735
  * ```ts
702
- * import { createRun, ok, type Task } from "@evolu/common";
736
+ * import { assertOk, createRun, ok, type Task } from "@evolu/common";
703
737
  *
704
738
  * interface Config {
705
739
  * readonly greeting: string;
@@ -714,7 +748,7 @@ import type { Awaitable, ParameterIntersection, Predicate } from "./Types.ts";
714
748
  *
715
749
  * const config: Config = { greeting: "Hello" };
716
750
  * await using run = createRun({ config });
717
- * expectOk(await run(greet), "Hello!");
751
+ * assertOk(await run(greet), "Hello!");
718
752
  * ```
719
753
  *
720
754
  * Start Tasks with `run(task)`, as shown above.
@@ -849,7 +883,13 @@ export interface Run<D = unknown> {
849
883
  * ### Example
850
884
  *
851
885
  * ```ts
852
- * import { createRun, ok, type Task } from "@evolu/common";
886
+ * import {
887
+ * assertSame,
888
+ * assertOk,
889
+ * createRun,
890
+ * ok,
891
+ * type Task,
892
+ * } from "@evolu/common";
853
893
  *
854
894
  * interface Db {
855
895
  * readonly name: string;
@@ -862,15 +902,15 @@ export interface Run<D = unknown> {
862
902
  * const db: Db = { name: "main" };
863
903
  * const loadUser: Task<string> = () => ok("Ada");
864
904
  * const saveUser: Task<void, never, DbDep> = (run) => {
865
- * expect(run.deps.db).toBe(db);
905
+ * assertSame(run.deps.db, db);
866
906
  * return ok();
867
907
  * };
868
908
  *
869
909
  * await using run = createRun({ db });
870
910
  * const userResult = await run(loadUser);
871
911
  * const savedResult = await run(saveUser);
872
- * expectOk(userResult, "Ada");
873
- * expectOk(savedResult, undefined);
912
+ * assertOk(userResult, "Ada");
913
+ * assertOk(savedResult, undefined);
874
914
  * ```
875
915
  *
876
916
  * Start Tasks with `run(task)`, as shown above.
@@ -899,7 +939,13 @@ export interface Run<D = unknown> {
899
939
  * ### Example
900
940
  *
901
941
  * ```ts
902
- * import { createRun, ok, type Task, type Typed } from "@evolu/common";
942
+ * import {
943
+ * assertEqual,
944
+ * createRun,
945
+ * ok,
946
+ * type Task,
947
+ * type Typed,
948
+ * } from "@evolu/common";
903
949
  *
904
950
  * const loadConfig: Task<string, ConfigInvalidError> = () =>
905
951
  * ok("config");
@@ -907,7 +953,7 @@ export interface Run<D = unknown> {
907
953
  * interface ConfigInvalidError extends Typed<"ConfigInvalid"> {}
908
954
  *
909
955
  * await using run = createRun();
910
- * expect(await run.orThrow(loadConfig)).toBe("config");
956
+ * assertEqual(await run.orThrow(loadConfig), "config");
911
957
  * ```
912
958
  */
913
959
  readonly orThrow: {
@@ -923,7 +969,13 @@ export interface Run<D = unknown> {
923
969
  * ### Example
924
970
  *
925
971
  * ```ts
926
- * import { createRun, ok, type Task } from "@evolu/common";
972
+ * import {
973
+ * assertEqual,
974
+ * assertTrue,
975
+ * createRun,
976
+ * ok,
977
+ * type Task,
978
+ * } from "@evolu/common";
927
979
  *
928
980
  * interface Resource extends AsyncDisposable {
929
981
  * readonly value: string;
@@ -933,17 +985,18 @@ export interface Run<D = unknown> {
933
985
  * const openResource: Task<Resource> = () =>
934
986
  * ok({
935
987
  * value: "resource",
936
- * [Symbol.asyncDispose]: async () => {
988
+ * [Symbol.asyncDispose]: () => {
937
989
  * disposed = true;
990
+ * return Promise.resolve();
938
991
  * },
939
992
  * });
940
993
  *
941
994
  * await using run = createRun();
942
995
  * {
943
996
  * await using resource = await run.ok(openResource);
944
- * expect(resource.value).toBe("resource");
997
+ * assertEqual(resource.value, "resource");
945
998
  * }
946
- * expect(disposed).toBe(true);
999
+ * assertTrue(disposed);
947
1000
  * ```
948
1001
  */
949
1002
  readonly ok: {
@@ -968,6 +1021,9 @@ export interface Run<D = unknown> {
968
1021
  *
969
1022
  * ```ts
970
1023
  * import {
1024
+ * assertFalse,
1025
+ * assertType,
1026
+ * assertTrue,
971
1027
  * AbortError,
972
1028
  * createRun,
973
1029
  * ok,
@@ -988,13 +1044,11 @@ export interface Run<D = unknown> {
988
1044
  *
989
1045
  * await using run = createRun();
990
1046
  * const fiber = run.abortable(loadUser, { db });
991
- * expectTypeOf(fiber).toEqualTypeOf<
992
- * AbortableFiber<string, never, DbDep>
993
- * >();
1047
+ * assertType<AbortableFiber<string, never, DbDep>, typeof fiber>();
994
1048
  * fiber.abort();
995
1049
  * const userResult = await fiber;
996
- * assert(!userResult.ok);
997
- * expect(AbortError.is(userResult.error)).toBe(true);
1050
+ * assertFalse(userResult.ok);
1051
+ * assertTrue(AbortError.is(userResult.error));
998
1052
  * ```
999
1053
  */
1000
1054
  readonly abortable: {
@@ -1030,35 +1084,45 @@ export interface Run<D = unknown> {
1030
1084
  * ### Abort masks
1031
1085
  *
1032
1086
  * ```ts
1033
- * import { createRun, ok, unabortable, type Task } from "@evolu/common";
1087
+ * import {
1088
+ * assertEqual,
1089
+ * assertOk,
1090
+ * assertTrue,
1091
+ * createRun,
1092
+ * ok,
1093
+ * unabortable,
1094
+ * type Task,
1095
+ * } from "@evolu/common";
1034
1096
  *
1035
1097
  * const syncUsers: Task<string> = () => ok("synced");
1036
1098
  * const syncParent = unabortable(async (run) => {
1037
- * expect(run.snapshot().abortMask).toBe(1);
1099
+ * assertEqual(run.snapshot().abortMask, 1);
1038
1100
  *
1039
1101
  * // Plain daemon — the caller's mask does not follow it, so abort
1040
1102
  * // requests are observed.
1041
1103
  * const fiber = run.daemon(syncUsers);
1042
- * expect(fiber.run.snapshot().abortMask).toBe(0);
1104
+ * assertEqual(fiber.run.snapshot().abortMask, 0);
1043
1105
  *
1044
1106
  * // Explicitly masked daemon — finishes once started.
1045
1107
  * const maskedFiber = run.daemon(unabortable(syncUsers));
1046
- * expect(maskedFiber.run.snapshot().abortMask).toBe(1);
1108
+ * assertEqual(maskedFiber.run.snapshot().abortMask, 1);
1047
1109
  * const firstResult = await fiber;
1048
1110
  * const secondResult = await maskedFiber;
1049
- * assert(firstResult.ok);
1050
- * assert(secondResult.ok);
1111
+ * assertTrue(firstResult.ok);
1112
+ * assertTrue(secondResult.ok);
1051
1113
  * return ok([firstResult.value, secondResult.value] as const);
1052
1114
  * });
1053
1115
  *
1054
1116
  * await using run = createRun();
1055
- * expectOk(await run(syncParent), ["synced", "synced"]);
1117
+ * assertOk(await run(syncParent), ["synced", "synced"]);
1056
1118
  * ```
1057
1119
  *
1058
1120
  * ### Aborting a daemon
1059
1121
  *
1060
1122
  * ```ts
1061
1123
  * import {
1124
+ * assertFalse,
1125
+ * assertTrue,
1062
1126
  * AbortError,
1063
1127
  * createRun,
1064
1128
  * ok,
@@ -1080,14 +1144,21 @@ export interface Run<D = unknown> {
1080
1144
  * const fiber = run.daemon(syncUsers, { db });
1081
1145
  * fiber.abort();
1082
1146
  * const syncResult = await fiber;
1083
- * assert(!syncResult.ok);
1084
- * expect(AbortError.is(syncResult.error)).toBe(true);
1147
+ * assertFalse(syncResult.ok);
1148
+ * assertTrue(AbortError.is(syncResult.error));
1085
1149
  * ```
1086
1150
  *
1087
1151
  * ### Disposing a daemon
1088
1152
  *
1089
1153
  * ```ts
1090
- * import { createRun, ok, waitForAbort, type Task } from "@evolu/common";
1154
+ * import {
1155
+ * assertOk,
1156
+ * assertTrue,
1157
+ * createRun,
1158
+ * ok,
1159
+ * waitForAbort,
1160
+ * type Task,
1161
+ * } from "@evolu/common";
1091
1162
  *
1092
1163
  * let syncStopped = false;
1093
1164
  * const syncUsers: Task<never> = async (run) => {
@@ -1102,9 +1173,9 @@ export interface Run<D = unknown> {
1102
1173
  * {
1103
1174
  * // Async disposal requests abort and waits for the daemon to stop.
1104
1175
  * await using _syncFiber = run.daemon(syncUsers);
1105
- * expectOk(await run(loadUser), "Ada");
1176
+ * assertOk(await run(loadUser), "Ada");
1106
1177
  * }
1107
- * expect(syncStopped).toBe(true);
1178
+ * assertTrue(syncStopped);
1108
1179
  * ```
1109
1180
  */
1110
1181
  readonly daemon: {
@@ -1130,7 +1201,13 @@ export interface Run<D = unknown> {
1130
1201
  * ### Example
1131
1202
  *
1132
1203
  * ```ts
1133
- * import { createRun, ok, type Task } from "@evolu/common";
1204
+ * import {
1205
+ * assertEqual,
1206
+ * assertOk,
1207
+ * createRun,
1208
+ * ok,
1209
+ * type Task,
1210
+ * } from "@evolu/common";
1134
1211
  *
1135
1212
  * interface DbDep {
1136
1213
  * readonly db: { readonly users: Array<string> };
@@ -1148,9 +1225,9 @@ export interface Run<D = unknown> {
1148
1225
  * await using createdRun = run.create({ db });
1149
1226
  * const userResult = await createdRun(loadUser);
1150
1227
  * const savedResult = await createdRun(saveUser);
1151
- * expectOk(userResult, "Ada");
1152
- * expectOk(savedResult, undefined);
1153
- * expect(db.users).toEqual(["Ada", "Grace"]);
1228
+ * assertOk(userResult, "Ada");
1229
+ * assertOk(savedResult, undefined);
1230
+ * assertEqual(db.users, ["Ada", "Grace"]);
1154
1231
  * ```
1155
1232
  */
1156
1233
  readonly create: {
@@ -1201,20 +1278,27 @@ export interface Run<D = unknown> {
1201
1278
  * ### Example
1202
1279
  *
1203
1280
  * ```ts
1204
- * import { AbortError, createRun, ok, sleep } from "@evolu/common";
1281
+ * import {
1282
+ * assertFalse,
1283
+ * assertTrue,
1284
+ * AbortError,
1285
+ * createRun,
1286
+ * ok,
1287
+ * sleep,
1288
+ * } from "@evolu/common";
1205
1289
  *
1206
1290
  * let socketClosed = false;
1207
1291
  * const openSocket = () => ({
1208
1292
  * close: () => {
1209
1293
  * socketClosed = true;
1210
1294
  * },
1211
- * read: async () => "message",
1295
+ * read: () => Promise.resolve("message"),
1212
1296
  * });
1213
1297
  *
1214
1298
  * await using run = createRun();
1215
1299
  * const fiber = run.abortable(async (run) => {
1216
1300
  * const socket = openSocket();
1217
- * using closeOnAbort = run.onAbort(() => {
1301
+ * using _closeOnAbort = run.onAbort(() => {
1218
1302
  * socket.close();
1219
1303
  * });
1220
1304
  *
@@ -1224,9 +1308,9 @@ export interface Run<D = unknown> {
1224
1308
  * });
1225
1309
  * fiber.abort();
1226
1310
  * const result = await fiber;
1227
- * assert(!result.ok);
1228
- * expect(AbortError.is(result.error)).toBe(true);
1229
- * expect(socketClosed).toBe(true);
1311
+ * assertFalse(result.ok);
1312
+ * assertTrue(AbortError.is(result.error));
1313
+ * assertTrue(socketClosed);
1230
1314
  * ```
1231
1315
  */
1232
1316
  readonly onAbort: (callback: (abortError: AbortError) => void) => Disposable | null;
@@ -1291,7 +1375,7 @@ export interface DisposableRun<D = unknown> extends Run<D>, Disposable, AsyncDis
1291
1375
  * ### Example
1292
1376
  *
1293
1377
  * ```ts
1294
- * import { createRun } from "@evolu/common";
1378
+ * import { assertFalse, assertTrue, createRun } from "@evolu/common";
1295
1379
  *
1296
1380
  * let connectionClosed = false;
1297
1381
  * {
@@ -1300,9 +1384,9 @@ export interface DisposableRun<D = unknown> extends Run<D>, Disposable, AsyncDis
1300
1384
  * connectionClosed = true;
1301
1385
  * });
1302
1386
  *
1303
- * expect(connectionClosed).toBe(false);
1387
+ * assertFalse(connectionClosed);
1304
1388
  * }
1305
- * expect(connectionClosed).toBe(true);
1389
+ * assertTrue(connectionClosed);
1306
1390
  * ```
1307
1391
  */
1308
1392
  readonly defer: (finalizer: () => Awaitable<void>) => void;
@@ -1366,7 +1450,15 @@ export interface DisposableRun<D = unknown> extends Run<D>, Disposable, AsyncDis
1366
1450
  * ### Example
1367
1451
  *
1368
1452
  * ```ts
1369
- * import { createRun, ok, type Fiber, type Task } from "@evolu/common";
1453
+ * import {
1454
+ * assertEqual,
1455
+ * assertOk,
1456
+ * assertType,
1457
+ * createRun,
1458
+ * ok,
1459
+ * type Fiber,
1460
+ * type Task,
1461
+ * } from "@evolu/common";
1370
1462
  *
1371
1463
  * await using run = createRun();
1372
1464
  *
@@ -1376,9 +1468,9 @@ export interface DisposableRun<D = unknown> extends Run<D>, Disposable, AsyncDis
1376
1468
  * const userResult = await fiber;
1377
1469
  * const snapshot = fiber.run.snapshot();
1378
1470
  *
1379
- * expectTypeOf(fiber).toEqualTypeOf<Fiber<string, never>>();
1380
- * expectOk(userResult, "Ada");
1381
- * expect(snapshot.id).toBe(fiber.run.id);
1471
+ * assertType<Fiber<string, never>, typeof fiber>();
1472
+ * assertOk(userResult, "Ada");
1473
+ * assertEqual(snapshot.id, fiber.run.id);
1382
1474
  * ```
1383
1475
  *
1384
1476
  * @group Core
@@ -1428,6 +1520,9 @@ export type InferFiberDeps<TFiber extends AnyFiber> = TFiber extends Fiber<any,
1428
1520
  *
1429
1521
  * ```ts
1430
1522
  * import {
1523
+ * assertFalse,
1524
+ * assertType,
1525
+ * assertTrue,
1431
1526
  * AbortError,
1432
1527
  * createRun,
1433
1528
  * ok,
@@ -1444,11 +1539,11 @@ export type InferFiberDeps<TFiber extends AnyFiber> = TFiber extends Fiber<any,
1444
1539
  * };
1445
1540
  *
1446
1541
  * const fiber = run.abortable<string, never>(fetchData);
1447
- * expectTypeOf(fiber).toEqualTypeOf<AbortableFiber<string, never>>();
1542
+ * assertType<AbortableFiber<string, never>, typeof fiber>();
1448
1543
  * fiber.abort();
1449
1544
  * const result = await fiber;
1450
- * assert(!result.ok);
1451
- * expect(AbortError.is(result.error)).toBe(true);
1545
+ * assertFalse(result.ok);
1546
+ * assertTrue(AbortError.is(result.error));
1452
1547
  * ```
1453
1548
  *
1454
1549
  * @group Core
@@ -1821,7 +1916,7 @@ export interface CreateRun {
1821
1916
  * ### Example
1822
1917
  *
1823
1918
  * ```ts
1824
- * import { createRun, ok, type Task } from "@evolu/common";
1919
+ * import { assertOk, createRun, ok, type Task } from "@evolu/common";
1825
1920
  *
1826
1921
  * interface ConfigDep {
1827
1922
  * readonly config: { readonly apiUrl: string };
@@ -1833,7 +1928,7 @@ export interface CreateRun {
1833
1928
  * await using run = createRun({
1834
1929
  * config: { apiUrl: "https://api.example.com" },
1835
1930
  * });
1836
- * expectOk(await run(loadApiUrl), "https://api.example.com");
1931
+ * assertOk(await run(loadApiUrl), "https://api.example.com");
1837
1932
  * ```
1838
1933
  *
1839
1934
  * @group Run
@@ -1914,12 +2009,12 @@ export declare const testCreateDeps: (options?: {
1914
2009
  * ### Example
1915
2010
  *
1916
2011
  * ```ts
1917
- * import { ok, testCreateRun, type Task } from "@evolu/common";
2012
+ * import { assertOk, ok, testCreateRun, type Task } from "@evolu/common";
1918
2013
  *
1919
2014
  * const readTime: Task<number> = (run) => ok(run.deps.time.now());
1920
2015
  *
1921
2016
  * await using run = testCreateRun();
1922
- * expectOk(await run(readTime), 0);
2017
+ * assertOk(await run(readTime), 0);
1923
2018
  * ```
1924
2019
  *
1925
2020
  * @group Testing
@@ -1931,7 +2026,7 @@ export declare function testCreateRun(deps?: TestRunDefaultDeps): DisposableRun<
1931
2026
  * ### Example
1932
2027
  *
1933
2028
  * ```ts
1934
- * import { ok, testCreateRun, type Task } from "@evolu/common";
2029
+ * import { assertOk, ok, testCreateRun, type Task } from "@evolu/common";
1935
2030
  *
1936
2031
  * interface FeatureDep {
1937
2032
  * readonly feature: { readonly enabled: boolean };
@@ -1941,7 +2036,7 @@ export declare function testCreateRun(deps?: TestRunDefaultDeps): DisposableRun<
1941
2036
  * ok(run.deps.feature.enabled);
1942
2037
  *
1943
2038
  * await using run = testCreateRun({ feature: { enabled: true } });
1944
- * expectOk(await run(isFeatureEnabled), true);
2039
+ * assertOk(await run(isFeatureEnabled), true);
1945
2040
  * ```
1946
2041
  */
1947
2042
  export declare function testCreateRun<D extends object>(deps: RunCustomDeps<D>): DisposableRun<TestRunDefaultDeps & D>;
@@ -2029,6 +2124,9 @@ export type InferTasksOk<TTasks> = {
2029
2124
  *
2030
2125
  * ```ts
2031
2126
  * import {
2127
+ * assertErr,
2128
+ * assertEqual,
2129
+ * assertType,
2032
2130
  * all,
2033
2131
  * createRun,
2034
2132
  * err,
@@ -2059,14 +2157,12 @@ export type InferTasksOk<TTasks> = {
2059
2157
  * collect: false,
2060
2158
  * }),
2061
2159
  * );
2062
- * expectTypeOf(saveResult).toEqualTypeOf<
2063
- * Result<void, SaveUserFailedError>
2064
- * >();
2065
- * expectErr(saveResult, {
2160
+ * assertType<Result<void, SaveUserFailedError>, typeof saveResult>();
2161
+ * assertErr(saveResult, {
2066
2162
  * type: "SaveUserFailed",
2067
2163
  * userId: "missing",
2068
2164
  * });
2069
- * expect(savedUserIds).toEqual(["user-1"]);
2165
+ * assertEqual(savedUserIds, ["user-1"]);
2070
2166
  * ```
2071
2167
  *
2072
2168
  * @group Collection
@@ -2081,6 +2177,8 @@ export declare function all<const TTasks extends TaskRecord>(tasks: TTasks, opti
2081
2177
  *
2082
2178
  * ```ts
2083
2179
  * import {
2180
+ * assertOk,
2181
+ * assertType,
2084
2182
  * all,
2085
2183
  * createRun,
2086
2184
  * ok,
@@ -2102,10 +2200,11 @@ export declare function all<const TTasks extends TaskRecord>(tasks: TTasks, opti
2102
2200
  *
2103
2201
  * await using run = createRun();
2104
2202
  * const dashboard = await run(all([fetchUser, fetchPosts]));
2105
- * expectTypeOf(dashboard).toEqualTypeOf<
2106
- * Result<readonly [User, ReadonlyArray<Post>]>
2203
+ * assertType<
2204
+ * Result<readonly [User, ReadonlyArray<Post>]>,
2205
+ * typeof dashboard
2107
2206
  * >();
2108
- * expectOk(dashboard, [{ id: "user-1" }, [{ id: "post-1" }]]);
2207
+ * assertOk(dashboard, [{ id: "user-1" }, [{ id: "post-1" }]]);
2109
2208
  * ```
2110
2209
  */
2111
2210
  export declare function all<const TTasks extends ReadonlyArray<AnyTask>>(tasks: TTasks, options?: TaskCollectionOptions): Task<InferTasksOk<TTasks>, InferTaskErr<TTasks[number]>, InferTasksDeps<TTasks>>;
@@ -2116,6 +2215,8 @@ export declare function all<const TTasks extends ReadonlyArray<AnyTask>>(tasks:
2116
2215
  *
2117
2216
  * ```ts
2118
2217
  * import {
2218
+ * assertOk,
2219
+ * assertType,
2119
2220
  * all,
2120
2221
  * createRun,
2121
2222
  * ok,
@@ -2138,10 +2239,11 @@ export declare function all<const TTasks extends ReadonlyArray<AnyTask>>(tasks:
2138
2239
  * await using run = createRun();
2139
2240
  * const result = await run(all({ user: fetchUser, posts: fetchPosts }));
2140
2241
  *
2141
- * expectTypeOf(result).toEqualTypeOf<
2142
- * Result<{ readonly user: User; readonly posts: ReadonlyArray<Post> }>
2242
+ * assertType<
2243
+ * Result<{ readonly user: User; readonly posts: ReadonlyArray<Post> }>,
2244
+ * typeof result
2143
2245
  * >();
2144
- * expectOk(result, {
2246
+ * assertOk(result, {
2145
2247
  * user: { id: "user-1" },
2146
2248
  * posts: [{ id: "post-1" }],
2147
2249
  * });
@@ -2160,6 +2262,9 @@ export declare function all<const TValues extends Readonly<Record<string, unknow
2160
2262
  *
2161
2263
  * ```ts
2162
2264
  * import {
2265
+ * assertEqual,
2266
+ * assertOk,
2267
+ * assertType,
2163
2268
  * all,
2164
2269
  * createRun,
2165
2270
  * ok,
@@ -2184,12 +2289,12 @@ export declare function all<const TValues extends Readonly<Record<string, unknow
2184
2289
  * });
2185
2290
  *
2186
2291
  * // Mapping is eager: it happens before the returned Task starts.
2187
- * expect(indexes).toEqual([0, 1]);
2292
+ * assertEqual(indexes, [0, 1]);
2188
2293
  *
2189
2294
  * await using run = createRun();
2190
2295
  * const result = await run(loadUsers);
2191
- * expectTypeOf(result).toEqualTypeOf<Result<readonly [User, User]>>();
2192
- * expectOk(result, [{ id: "user-1" }, { id: "user-2" }]);
2296
+ * assertType<Result<readonly [User, User]>, typeof result>();
2297
+ * assertOk(result, [{ id: "user-1" }, { id: "user-2" }]);
2193
2298
  * ```
2194
2299
  */
2195
2300
  export declare function all<const TValues extends ReadonlyArray<unknown>, TTask extends AnyTask>(values: TValues, fn: (value: TValues[number], index: number) => TTask, options?: TaskCollectionOptions): Task<{
@@ -2202,6 +2307,9 @@ export declare function all<const TValues extends ReadonlyArray<unknown>, TTask
2202
2307
  *
2203
2308
  * ```ts
2204
2309
  * import {
2310
+ * assertEqual,
2311
+ * assertOk,
2312
+ * assertType,
2205
2313
  * all,
2206
2314
  * createRun,
2207
2315
  * ok,
@@ -2229,14 +2337,15 @@ export declare function all<const TValues extends ReadonlyArray<unknown>, TTask
2229
2337
  * });
2230
2338
  *
2231
2339
  * // Mapping is eager: it happens before the returned Task starts.
2232
- * expect(roles).toEqual(["admin", "reviewer"]);
2340
+ * assertEqual(roles, ["admin", "reviewer"]);
2233
2341
  *
2234
2342
  * await using run = createRun();
2235
2343
  * const result = await run(loadUsersByRole);
2236
- * expectTypeOf(result).toEqualTypeOf<
2237
- * Result<{ readonly admin: User; readonly reviewer: User }>
2344
+ * assertType<
2345
+ * Result<{ readonly admin: User; readonly reviewer: User }>,
2346
+ * typeof result
2238
2347
  * >();
2239
- * expectOk(result, {
2348
+ * assertOk(result, {
2240
2349
  * admin: { id: "user-1" },
2241
2350
  * reviewer: { id: "user-2" },
2242
2351
  * });
@@ -2279,6 +2388,9 @@ export type InferTasksSettled<TTasks> = {
2279
2388
  *
2280
2389
  * ```ts
2281
2390
  * import {
2391
+ * assertOk,
2392
+ * assertType,
2393
+ * assertTrue,
2282
2394
  * allSettled,
2283
2395
  * createRun,
2284
2396
  * err,
@@ -2301,20 +2413,21 @@ export type InferTasksSettled<TTasks> = {
2301
2413
  *
2302
2414
  * await using run = createRun();
2303
2415
  * const results = await run(allSettled([loadProfile, loadActivity]));
2304
- * expectTypeOf(results).toEqualTypeOf<
2416
+ * assertType<
2305
2417
  * Result<
2306
2418
  * readonly [
2307
2419
  * Result<string, ProfileNotFoundError>,
2308
2420
  * Result<ReadonlyArray<string>>,
2309
2421
  * ]
2310
- * >
2422
+ * >,
2423
+ * typeof results
2311
2424
  * >();
2312
- * expectOk(results, [
2425
+ * assertOk(results, [
2313
2426
  * { ok: false, error: { type: "ProfileNotFound" } },
2314
2427
  * { ok: true, value: ["signed-in"] },
2315
2428
  * ]);
2316
2429
  * // Unlike all, a later Task still runs after an Err.
2317
- * expect(activityLoaded).toBe(true);
2430
+ * assertTrue(activityLoaded);
2318
2431
  * ```
2319
2432
  *
2320
2433
  * @group Collection
@@ -2327,6 +2440,8 @@ export declare function allSettled<const TTasks extends ReadonlyArray<AnyTask>>(
2327
2440
  *
2328
2441
  * ```ts
2329
2442
  * import {
2443
+ * assertOk,
2444
+ * assertType,
2330
2445
  * allSettled,
2331
2446
  * createRun,
2332
2447
  * err,
@@ -2351,13 +2466,14 @@ export declare function allSettled<const TTasks extends ReadonlyArray<AnyTask>>(
2351
2466
  * allSettled({ user: fetchUser, profile: fetchProfile }),
2352
2467
  * );
2353
2468
  *
2354
- * expectTypeOf(results).toEqualTypeOf<
2469
+ * assertType<
2355
2470
  * Result<{
2356
2471
  * readonly user: Result<User>;
2357
2472
  * readonly profile: Result<string, ProfileNotFoundError>;
2358
- * }>
2473
+ * }>,
2474
+ * typeof results
2359
2475
  * >();
2360
- * expectOk(results, {
2476
+ * assertOk(results, {
2361
2477
  * user: { ok: true, value: { id: "user-1" } },
2362
2478
  * profile: { ok: false, error: { type: "ProfileNotFound" } },
2363
2479
  * });
@@ -2371,6 +2487,9 @@ export declare function allSettled<const TTasks extends TaskRecord>(tasks: TTask
2371
2487
  *
2372
2488
  * ```ts
2373
2489
  * import {
2490
+ * assertEqual,
2491
+ * assertOk,
2492
+ * assertType,
2374
2493
  * allSettled,
2375
2494
  * createRun,
2376
2495
  * err,
@@ -2399,19 +2518,20 @@ export declare function allSettled<const TTasks extends TaskRecord>(tasks: TTask
2399
2518
  * });
2400
2519
  *
2401
2520
  * // Mapping is eager: it happens before the returned Task starts.
2402
- * expect(indexes).toEqual([0, 1]);
2521
+ * assertEqual(indexes, [0, 1]);
2403
2522
  *
2404
2523
  * await using run = createRun();
2405
2524
  * const results = await run(loadUsers);
2406
- * expectTypeOf(results).toEqualTypeOf<
2525
+ * assertType<
2407
2526
  * Result<
2408
2527
  * readonly [
2409
2528
  * Result<User, UserNotFoundError>,
2410
2529
  * Result<User, UserNotFoundError>,
2411
2530
  * ]
2412
- * >
2531
+ * >,
2532
+ * typeof results
2413
2533
  * >();
2414
- * expectOk(results, [
2534
+ * assertOk(results, [
2415
2535
  * { ok: true, value: { id: "user-1" } },
2416
2536
  * { ok: false, error: { type: "UserNotFound" } },
2417
2537
  * ]);
@@ -2427,6 +2547,9 @@ export declare function allSettled<const TValues extends ReadonlyArray<unknown>,
2427
2547
  *
2428
2548
  * ```ts
2429
2549
  * import {
2550
+ * assertEqual,
2551
+ * assertOk,
2552
+ * assertType,
2430
2553
  * allSettled,
2431
2554
  * createRun,
2432
2555
  * err,
@@ -2455,17 +2578,18 @@ export declare function allSettled<const TValues extends ReadonlyArray<unknown>,
2455
2578
  * });
2456
2579
  *
2457
2580
  * // Mapping is eager: it happens before the returned Task starts.
2458
- * expect(roles).toEqual(["admin", "reviewer"]);
2581
+ * assertEqual(roles, ["admin", "reviewer"]);
2459
2582
  *
2460
2583
  * await using run = createRun();
2461
2584
  * const results = await run(loadUsersByRole);
2462
- * expectTypeOf(results).toEqualTypeOf<
2585
+ * assertType<
2463
2586
  * Result<{
2464
2587
  * readonly admin: Result<User, UserNotFoundError>;
2465
2588
  * readonly reviewer: Result<User, UserNotFoundError>;
2466
- * }>
2589
+ * }>,
2590
+ * typeof results
2467
2591
  * >();
2468
- * expectOk(results, {
2592
+ * assertOk(results, {
2469
2593
  * admin: { ok: true, value: { id: "user-1" } },
2470
2594
  * reviewer: { ok: false, error: { type: "UserNotFound" } },
2471
2595
  * });
@@ -2515,14 +2639,23 @@ export declare function allSettled<const TValues extends Readonly<Record<string,
2515
2639
  * ### Example
2516
2640
  *
2517
2641
  * ```ts
2518
- * import { callback, createRun, ok, type Task } from "@evolu/common";
2642
+ * import {
2643
+ * assertEqual,
2644
+ * assertOk,
2645
+ * callback,
2646
+ * createRun,
2647
+ * ok,
2648
+ * type Task,
2649
+ * } from "@evolu/common";
2519
2650
  *
2520
2651
  * const listeners = new Set<(message: string) => void>();
2521
2652
  * const subscribe = (
2522
2653
  * listener: (message: string) => void,
2523
2654
  * ): (() => void) => {
2524
2655
  * listeners.add(listener);
2525
- * return () => listeners.delete(listener);
2656
+ * return () => {
2657
+ * listeners.delete(listener);
2658
+ * };
2526
2659
  * };
2527
2660
  * const nextMessage: Task<string> = callback(({ resolve }) =>
2528
2661
  * subscribe((message) => resolve(ok(message))),
@@ -2530,11 +2663,11 @@ export declare function allSettled<const TValues extends Readonly<Record<string,
2530
2663
  *
2531
2664
  * await using run = createRun();
2532
2665
  * const fiber = run(nextMessage);
2533
- * expect(listeners.size).toBe(1);
2666
+ * assertEqual(listeners.size, 1);
2534
2667
  * for (const listener of listeners) listener("ready");
2535
- * expectOk(await fiber, "ready");
2668
+ * assertOk(await fiber, "ready");
2536
2669
  * // The callback cleanup unsubscribes after settlement.
2537
- * expect(listeners.size).toBe(0);
2670
+ * assertEqual(listeners.size, 0);
2538
2671
  * ```
2539
2672
  *
2540
2673
  * @group Interop
@@ -2552,10 +2685,10 @@ export declare const callback: <T, E = never, D = unknown>(fn: (options: {
2552
2685
  * ### Example
2553
2686
  *
2554
2687
  * ```ts
2555
- * import { createRun, sleep } from "@evolu/common";
2688
+ * import { assertOk, createRun, sleep } from "@evolu/common";
2556
2689
  *
2557
2690
  * await using run = createRun();
2558
- * expectOk(await run(sleep("1ms")), undefined);
2691
+ * assertOk(await run(sleep("1ms")), undefined);
2559
2692
  * ```
2560
2693
  *
2561
2694
  * @group Timing
@@ -2574,6 +2707,8 @@ export declare const sleep: (duration: PositiveDuration) => Task<void>;
2574
2707
  *
2575
2708
  * ```ts
2576
2709
  * import {
2710
+ * assertErr,
2711
+ * assertType,
2577
2712
  * createRun,
2578
2713
  * timeout,
2579
2714
  * timeoutError,
@@ -2585,8 +2720,8 @@ export declare const sleep: (duration: PositiveDuration) => Task<void>;
2585
2720
  * await using run = createRun();
2586
2721
  *
2587
2722
  * const result = await run(timeout(waitForAbort, "1ms"));
2588
- * expectTypeOf(result).toEqualTypeOf<Result<never, TimeoutError>>();
2589
- * expectErr(result, timeoutError);
2723
+ * assertType<Result<never, TimeoutError>, typeof result>();
2724
+ * assertErr(result, timeoutError);
2590
2725
  * ```
2591
2726
  *
2592
2727
  * @group Timing
@@ -2668,6 +2803,8 @@ export interface RetryAttempt<E, Output> extends ScheduleStep<Output> {
2668
2803
  *
2669
2804
  * ```ts
2670
2805
  * import {
2806
+ * assertErr,
2807
+ * assertType,
2671
2808
  * createRun,
2672
2809
  * err,
2673
2810
  * recurs,
@@ -2687,10 +2824,11 @@ export interface RetryAttempt<E, Output> extends ScheduleStep<Output> {
2687
2824
  *
2688
2825
  * await using run = createRun();
2689
2826
  * const result = await run(fetchWithRetry);
2690
- * expectTypeOf(result).toEqualTypeOf<
2691
- * Result<string, RetryTaskError<ServiceUnavailableError>>
2827
+ * assertType<
2828
+ * Result<string, RetryTaskError<ServiceUnavailableError>>,
2829
+ * typeof result
2692
2830
  * >();
2693
- * expectErr(result, {
2831
+ * assertErr(result, {
2694
2832
  * type: "RetryError",
2695
2833
  * attempts: 3,
2696
2834
  * lastError: { type: "ServiceUnavailable" },
@@ -2701,6 +2839,7 @@ export interface RetryAttempt<E, Output> extends ScheduleStep<Output> {
2701
2839
  *
2702
2840
  * ```ts
2703
2841
  * import {
2842
+ * assertErr,
2704
2843
  * createRun,
2705
2844
  * err,
2706
2845
  * recurs,
@@ -2723,7 +2862,8 @@ export interface RetryAttempt<E, Output> extends ScheduleStep<Output> {
2723
2862
  * });
2724
2863
  *
2725
2864
  * await using run = createRun();
2726
- * expectErr(await run(fetchWithRetry), {
2865
+ * const result = await run(fetchWithRetry);
2866
+ * assertErr(result, {
2727
2867
  * type: "RetryError",
2728
2868
  * attempts: 1,
2729
2869
  * lastError: { type: "PermanentFailure" },
@@ -2803,7 +2943,15 @@ export interface RepeatAttempt<T, Output> extends ScheduleStep<Output> {
2803
2943
  * ### Repeating successes
2804
2944
  *
2805
2945
  * ```ts
2806
- * import { createRun, ok, recurs, repeat, type Task } from "@evolu/common";
2946
+ * import {
2947
+ * assertEqual,
2948
+ * assertOk,
2949
+ * createRun,
2950
+ * ok,
2951
+ * recurs,
2952
+ * repeat,
2953
+ * type Task,
2954
+ * } from "@evolu/common";
2807
2955
  *
2808
2956
  * let attempts = 0;
2809
2957
  * const checkStatus: Task<string> = () => {
@@ -2814,14 +2962,16 @@ export interface RepeatAttempt<T, Output> extends ScheduleStep<Output> {
2814
2962
  * const poll = repeat(checkStatus, recurs(3));
2815
2963
  *
2816
2964
  * await using run = createRun();
2817
- * expectOk(await run(poll), "pending");
2818
- * expect(attempts).toBe(4);
2965
+ * assertOk(await run(poll), "pending");
2966
+ * assertEqual(attempts, 4);
2819
2967
  * ```
2820
2968
  *
2821
2969
  * ### Stopping with Done
2822
2970
  *
2823
2971
  * ```ts
2824
2972
  * import {
2973
+ * assertErr,
2974
+ * assertEqual,
2825
2975
  * createRun,
2826
2976
  * done,
2827
2977
  * err,
@@ -2844,8 +2994,8 @@ export interface RepeatAttempt<T, Output> extends ScheduleStep<Output> {
2844
2994
  *
2845
2995
  * await using run = createRun();
2846
2996
  * const result = await run(repeat(processQueue, spaced("1ms")));
2847
- * expectErr(result, done());
2848
- * expect(queue).toEqual([]);
2997
+ * assertErr(result, done());
2998
+ * assertEqual(queue, []);
2849
2999
  * ```
2850
3000
  *
2851
3001
  * @group Repetition
@@ -2880,6 +3030,9 @@ export type InferTasksResult<TTasks extends NonEmptyReadonlyArray<AnyTask>> = Re
2880
3030
  *
2881
3031
  * ```ts
2882
3032
  * import {
3033
+ * assertOk,
3034
+ * assertType,
3035
+ * assertTrue,
2883
3036
  * any,
2884
3037
  * createRun,
2885
3038
  * err,
@@ -2903,11 +3056,9 @@ export type InferTasksResult<TTasks extends NonEmptyReadonlyArray<AnyTask>> = Re
2903
3056
  * await using run = createRun();
2904
3057
  * const result = await run(any([unavailable, fallback]));
2905
3058
  *
2906
- * expectTypeOf(result).toEqualTypeOf<
2907
- * Result<string, ServiceUnavailableError>
2908
- * >();
2909
- * expectOk(result, "fallback");
2910
- * expect(fallbackStarted).toBe(true);
3059
+ * assertType<Result<string, ServiceUnavailableError>, typeof result>();
3060
+ * assertOk(result, "fallback");
3061
+ * assertTrue(fallbackStarted);
2911
3062
  * ```
2912
3063
  *
2913
3064
  * @group Racing
@@ -2939,6 +3090,7 @@ export declare const any: <TTasks extends NonEmptyReadonlyArray<AnyTask>>(tasks:
2939
3090
  *
2940
3091
  * ```ts
2941
3092
  * import {
3093
+ * assertOk,
2942
3094
  * createRun,
2943
3095
  * isNonEmptyArray,
2944
3096
  * ok,
@@ -2950,7 +3102,7 @@ export declare const any: <TTasks extends NonEmptyReadonlyArray<AnyTask>>(tasks:
2950
3102
  * await using run = createRun();
2951
3103
  * if (isNonEmptyArray(tasks)) {
2952
3104
  * const result = await run(race(tasks));
2953
- * expectOk(result, "first");
3105
+ * assertOk(result, "first");
2954
3106
  * }
2955
3107
  * ```
2956
3108
  *
@@ -2958,6 +3110,9 @@ export declare const any: <TTasks extends NonEmptyReadonlyArray<AnyTask>>(tasks:
2958
3110
  *
2959
3111
  * ```ts
2960
3112
  * import {
3113
+ * assertFalse,
3114
+ * assertOk,
3115
+ * assertType,
2961
3116
  * createRun,
2962
3117
  * ok,
2963
3118
  * race,
@@ -2979,9 +3134,9 @@ export declare const any: <TTasks extends NonEmptyReadonlyArray<AnyTask>>(tasks:
2979
3134
  * // Input order does not matter: the first settled Result wins, and the
2980
3135
  * // still-running loser is aborted.
2981
3136
  * const result = await run(race([slow, fast]));
2982
- * expectTypeOf(result).toEqualTypeOf<Result<string>>();
2983
- * expectOk(result, "fast");
2984
- * expect(slowCompleted).toBe(false);
3137
+ * assertType<Result<string>, typeof result>();
3138
+ * assertOk(result, "fast");
3139
+ * assertFalse(slowCompleted);
2985
3140
  * ```
2986
3141
  *
2987
3142
  * @group Racing
@@ -3003,6 +3158,8 @@ export declare const race: <TTasks extends NonEmptyReadonlyArray<AnyTask>>(tasks
3003
3158
  *
3004
3159
  * ```ts
3005
3160
  * import {
3161
+ * assertFalse,
3162
+ * assertOk,
3006
3163
  * createRun,
3007
3164
  * err,
3008
3165
  * firstN,
@@ -3033,8 +3190,8 @@ export declare const race: <TTasks extends NonEmptyReadonlyArray<AnyTask>>(tasks
3033
3190
  *
3034
3191
  * // Errs do not count. After two Ok values settle, the slow Task is aborted.
3035
3192
  * const result = await run(firstN(tasks, 2, { concurrency: 4 }));
3036
- * expectOk(result, ["fast-1", "fast-2"]);
3037
- * expect(slowCompleted).toBe(false);
3193
+ * assertOk(result, ["fast-1", "fast-2"]);
3194
+ * assertFalse(slowCompleted);
3038
3195
  * ```
3039
3196
  *
3040
3197
  * @group Racing
@@ -3056,6 +3213,8 @@ export declare const firstN: <TTasks extends NonEmptyReadonlyArray<AnyTask>>(tas
3056
3213
  *
3057
3214
  * ```ts
3058
3215
  * import {
3216
+ * assertFalse,
3217
+ * assertOk,
3059
3218
  * createRun,
3060
3219
  * err,
3061
3220
  * firstNSettled,
@@ -3081,11 +3240,11 @@ export declare const firstN: <TTasks extends NonEmptyReadonlyArray<AnyTask>>(tas
3081
3240
  *
3082
3241
  * // Err and Ok both count, and Results use settlement order.
3083
3242
  * const result = await run(firstNSettled(tasks, 2, { concurrency: 3 }));
3084
- * expectOk(result, [
3243
+ * assertOk(result, [
3085
3244
  * { ok: false, error: { type: "ServiceUnavailable" } },
3086
3245
  * { ok: true, value: "fast" },
3087
3246
  * ]);
3088
- * expect(slowCompleted).toBe(false);
3247
+ * assertFalse(slowCompleted);
3089
3248
  * ```
3090
3249
  *
3091
3250
  * @group Racing
@@ -3141,6 +3300,9 @@ export type EachCallback<TTasks extends NonEmptyReadonlyArray<AnyTask>> = (resul
3141
3300
  *
3142
3301
  * ```ts
3143
3302
  * import {
3303
+ * assertEqual,
3304
+ * assertFalse,
3305
+ * assertOk,
3144
3306
  * createRun,
3145
3307
  * each,
3146
3308
  * err,
@@ -3176,9 +3338,9 @@ export type EachCallback<TTasks extends NonEmptyReadonlyArray<AnyTask>> = (resul
3176
3338
  * ),
3177
3339
  * );
3178
3340
  *
3179
- * expectOk(result, undefined);
3180
- * expect(first).toEqual(["fast", 2]);
3181
- * expect(slowCompleted).toBe(false);
3341
+ * assertOk(result, undefined);
3342
+ * assertEqual(first, ["fast", 2]);
3343
+ * assertFalse(slowCompleted);
3182
3344
  * ```
3183
3345
  *
3184
3346
  * `onResult` is a synchronous scheduling decision, not a place to do work. It
@@ -3222,13 +3384,19 @@ export type TaskPriority = "user-blocking" | "user-visible" | "background";
3222
3384
  * ### Example
3223
3385
  *
3224
3386
  * ```ts
3225
- * import { createRun, ok, prioritized, type Task } from "@evolu/common";
3387
+ * import {
3388
+ * assertOk,
3389
+ * createRun,
3390
+ * ok,
3391
+ * prioritized,
3392
+ * type Task,
3393
+ * } from "@evolu/common";
3226
3394
  *
3227
3395
  * const rebuildSearchIndex: Task<string> = () => ok("indexed");
3228
3396
  * const backgroundIndexing = prioritized("background", rebuildSearchIndex);
3229
3397
  *
3230
3398
  * await using run = createRun();
3231
- * expectOk(await run(backgroundIndexing), "indexed");
3399
+ * assertOk(await run(backgroundIndexing), "indexed");
3232
3400
  * ```
3233
3401
  *
3234
3402
  * @group Scheduling
@@ -3248,7 +3416,13 @@ export declare const prioritized: <T, E, D = unknown>(priority: TaskPriority, ta
3248
3416
  * ### Example
3249
3417
  *
3250
3418
  * ```ts
3251
- * import { createRun, ok, yieldNow, type Task } from "@evolu/common";
3419
+ * import {
3420
+ * assertOk,
3421
+ * createRun,
3422
+ * ok,
3423
+ * yieldNow,
3424
+ * type Task,
3425
+ * } from "@evolu/common";
3252
3426
  *
3253
3427
  * const sumTo =
3254
3428
  * (count: number): Task<number> =>
@@ -3264,7 +3438,7 @@ export declare const prioritized: <T, E, D = unknown>(priority: TaskPriority, ta
3264
3438
  * };
3265
3439
  *
3266
3440
  * await using run = createRun();
3267
- * expectOk(await run(sumTo(1001)), 500500);
3441
+ * assertOk(await run(sumTo(1001)), 500500);
3268
3442
  * ```
3269
3443
  *
3270
3444
  * @group Scheduling
@@ -3281,6 +3455,10 @@ export declare const yieldNow: Task<void>;
3281
3455
  *
3282
3456
  * ```ts
3283
3457
  * import {
3458
+ * assertEqual,
3459
+ * assertFalse,
3460
+ * assertType,
3461
+ * assertTrue,
3284
3462
  * AbortError,
3285
3463
  * createRun,
3286
3464
  * ok,
@@ -3297,23 +3475,22 @@ export declare const yieldNow: Task<void>;
3297
3475
  * const serverStarted = Promise.withResolvers<void>();
3298
3476
  * let serverStopped = false;
3299
3477
  * const startServer: Task<Server, never, ServerDep> = (run) => {
3300
- * expect(run.deps.port).toBe(3000);
3478
+ * assertEqual(run.deps.port, 3000);
3301
3479
  * serverStarted.resolve();
3302
3480
  * return ok({
3303
- * [Symbol.asyncDispose]: async () => {
3481
+ * [Symbol.asyncDispose]: () => {
3304
3482
  * serverStopped = true;
3483
+ * return Promise.resolve();
3305
3484
  * },
3306
3485
  * });
3307
3486
  * };
3308
3487
  *
3309
3488
  * const serve = (): Task<never, never, ServerDep> => async (run) => {
3310
- * await using server = await run.ok(startServer);
3489
+ * await using _ = await run.ok(startServer);
3311
3490
  * return await run(waitForAbort);
3312
3491
  * };
3313
3492
  *
3314
- * expectTypeOf(serve).returns.toEqualTypeOf<
3315
- * Task<never, never, ServerDep>
3316
- * >();
3493
+ * assertType<Task<never, never, ServerDep>, ReturnType<typeof serve>>();
3317
3494
  *
3318
3495
  * await using run = createRun();
3319
3496
  * const fiber = run.abortable(serve(), { port: 3000 });
@@ -3321,9 +3498,9 @@ export declare const yieldNow: Task<void>;
3321
3498
  * fiber.abort();
3322
3499
  *
3323
3500
  * const result = await fiber;
3324
- * assert(!result.ok);
3325
- * expect(AbortError.is(result.error)).toBe(true);
3326
- * expect(serverStopped).toBe(true);
3501
+ * assertFalse(result.ok);
3502
+ * assertTrue(AbortError.is(result.error));
3503
+ * assertTrue(serverStopped);
3327
3504
  * ```
3328
3505
  *
3329
3506
  * @group Abortability
@@ -3373,6 +3550,9 @@ export declare const waitForAbort: Task<never>;
3373
3550
  *
3374
3551
  * ```ts
3375
3552
  * import {
3553
+ * assertEqual,
3554
+ * assertFalse,
3555
+ * assertTrue,
3376
3556
  * createRun,
3377
3557
  * daemon,
3378
3558
  * ok,
@@ -3393,18 +3573,24 @@ export declare const waitForAbort: Task<never>;
3393
3573
  * {
3394
3574
  * await using run = createRun();
3395
3575
  * const result = await run(timeout(daemon(taskNotUsingAbort), "1ms"));
3396
- * assert(!result.ok);
3397
- * expect(result.error.type).toBe("TimeoutError");
3398
- * expect(finished).toBe(false);
3576
+ * assertFalse(result.ok);
3577
+ * assertEqual(result.error.type, "TimeoutError");
3578
+ * assertFalse(finished);
3399
3579
  * finishTask();
3400
3580
  * }
3401
- * expect(finished).toBe(true);
3581
+ * assertTrue(finished);
3402
3582
  * ```
3403
3583
  *
3404
3584
  * Promise-returning functions should be called inside the Task, not before it.
3405
3585
  *
3406
3586
  * ```ts
3407
- * import { createRun, ok, type Result, type Task } from "@evolu/common";
3587
+ * import {
3588
+ * assertOk,
3589
+ * createRun,
3590
+ * ok,
3591
+ * type Result,
3592
+ * type Task,
3593
+ * } from "@evolu/common";
3408
3594
  *
3409
3595
  * type ResultValue = string;
3410
3596
  * const createPromiseReturningResult = (): Promise<Result<ResultValue>> =>
@@ -3413,14 +3599,20 @@ export declare const waitForAbort: Task<never>;
3413
3599
  * const task: Task<ResultValue> = () => createPromiseReturningResult();
3414
3600
  *
3415
3601
  * await using run = createRun();
3416
- * expectOk(await run(task), "value");
3602
+ * assertOk(await run(task), "value");
3417
3603
  * ```
3418
3604
  *
3419
3605
  * Do not reuse an already-running Promise. It started outside the Task, so the
3420
3606
  * Run cannot own its lifetime or request abort before it begins.
3421
3607
  *
3422
3608
  * ```ts
3423
- * import { ok, type Result, type Task } from "@evolu/common";
3609
+ * import {
3610
+ * assertType,
3611
+ * assertTrue,
3612
+ * ok,
3613
+ * type Result,
3614
+ * type Task,
3615
+ * } from "@evolu/common";
3424
3616
  *
3425
3617
  * type ResultValue = string;
3426
3618
  * let promiseStarted = false;
@@ -3435,8 +3627,8 @@ export declare const waitForAbort: Task<never>;
3435
3627
  * const promise = createPromiseReturningResult();
3436
3628
  * const task: Task<ResultValue> = () => promise;
3437
3629
  *
3438
- * expect(promiseStarted).toBe(true);
3439
- * expectTypeOf(task).toEqualTypeOf<Task<ResultValue>>();
3630
+ * assertTrue(promiseStarted);
3631
+ * assertType<Task<ResultValue>, typeof task>();
3440
3632
  * ```
3441
3633
  *
3442
3634
  * @group Lifetime
@@ -3457,14 +3649,21 @@ export declare const daemon: <T, E, D = unknown>(task: Task<T, E, D>) => Task<T,
3457
3649
  * ### Example
3458
3650
  *
3459
3651
  * ```ts
3460
- * import { createRun, ok, unabortable, type Task } from "@evolu/common";
3652
+ * import {
3653
+ * assertFalse,
3654
+ * assertOk,
3655
+ * createRun,
3656
+ * ok,
3657
+ * unabortable,
3658
+ * type Task,
3659
+ * } from "@evolu/common";
3461
3660
  *
3462
3661
  * const commitStarted = Promise.withResolvers<void>();
3463
3662
  * const finishCommit = Promise.withResolvers<void>();
3464
3663
  * const commit: Task<string> = unabortable(async (run) => {
3465
3664
  * commitStarted.resolve();
3466
3665
  * await finishCommit.promise;
3467
- * expect(run.signal.aborted).toBe(false);
3666
+ * assertFalse(run.signal.aborted);
3468
3667
  * return ok("committed");
3469
3668
  * });
3470
3669
  *
@@ -3474,7 +3673,7 @@ export declare const daemon: <T, E, D = unknown>(task: Task<T, E, D>) => Task<T,
3474
3673
  * fiber.abort();
3475
3674
  * finishCommit.resolve();
3476
3675
  *
3477
- * expectOk(await fiber, "committed");
3676
+ * assertOk(await fiber, "committed");
3478
3677
  * ```
3479
3678
  *
3480
3679
  * @group Abortability
@@ -3502,6 +3701,9 @@ export declare const unabortable: <T, E, D>(task: Task<T, E, D>) => Task<T, E, D
3502
3701
  *
3503
3702
  * ```ts
3504
3703
  * import {
3704
+ * assertEqual,
3705
+ * assertFalse,
3706
+ * assertTrue,
3505
3707
  * AbortError,
3506
3708
  * createRun,
3507
3709
  * ok,
@@ -3518,17 +3720,17 @@ export declare const unabortable: <T, E, D>(task: Task<T, E, D>) => Task<T, E, D
3518
3720
  * const operationStarted = Promise.withResolvers<void>();
3519
3721
  * const operate =
3520
3722
  * (resource: Resource): Task<never> =>
3521
- * async (run) => {
3522
- * expect(resource.id).toBe("resource-1");
3723
+ * (run) => {
3724
+ * assertEqual(resource.id, "resource-1");
3523
3725
  * operationStarted.resolve();
3524
- * return await run(waitForAbort);
3726
+ * return run(waitForAbort);
3525
3727
  * };
3526
3728
  * let released = false;
3527
3729
  * const release =
3528
3730
  * (_resource: Resource): Task<void> =>
3529
3731
  * (run) => {
3530
3732
  * // Release inherits the mask even after abort was requested.
3531
- * expect(run.signal.aborted).toBe(false);
3733
+ * assertFalse(run.signal.aborted);
3532
3734
  * released = true;
3533
3735
  * return ok();
3534
3736
  * };
@@ -3552,9 +3754,9 @@ export declare const unabortable: <T, E, D>(task: Task<T, E, D>) => Task<T, E, D
3552
3754
  * await operationStarted.promise;
3553
3755
  * fiber.abort();
3554
3756
  * const result = await fiber;
3555
- * assert(!result.ok);
3556
- * expect(AbortError.is(result.error)).toBe(true);
3557
- * expect(released).toBe(true);
3757
+ * assertFalse(result.ok);
3758
+ * assertTrue(AbortError.is(result.error));
3759
+ * assertTrue(released);
3558
3760
  * ```
3559
3761
  *
3560
3762
  * @group Abortability
@@ -3581,6 +3783,8 @@ export declare const unabortableMask: <T, E, D = unknown>(fn: (restore: <T2, E2,
3581
3783
  *
3582
3784
  * ```ts
3583
3785
  * import {
3786
+ * assertErr,
3787
+ * assertTrue,
3584
3788
  * acquireUseRelease,
3585
3789
  * createRun,
3586
3790
  * err,
@@ -3620,9 +3824,9 @@ export declare const unabortableMask: <T, E, D = unknown>(fn: (restore: <T2, E2,
3620
3824
  * );
3621
3825
  *
3622
3826
  * await using run = createRun();
3623
- * expectErr(await run(queryUser), { type: "UserUnavailable" });
3827
+ * assertErr(await run(queryUser), { type: "UserUnavailable" });
3624
3828
  * // Release still runs when use returns a domain error.
3625
- * expect(connectionClosed).toBe(true);
3829
+ * assertTrue(connectionClosed);
3626
3830
  * ```
3627
3831
  *
3628
3832
  * @group Lifetime
@@ -3656,6 +3860,10 @@ export interface Deferred<T, E = never> {
3656
3860
  *
3657
3861
  * ```ts
3658
3862
  * import {
3863
+ * assertFalse,
3864
+ * assertOk,
3865
+ * assertType,
3866
+ * assertTrue,
3659
3867
  * createDeferred,
3660
3868
  * createRun,
3661
3869
  * ok,
@@ -3666,22 +3874,28 @@ export interface Deferred<T, E = never> {
3666
3874
  * const deferred = createDeferred<string>();
3667
3875
  *
3668
3876
  * const fiber = run(deferred.task);
3669
- * expect(deferred.resolve(ok("ready"))).toBe(true);
3877
+ * assertTrue(deferred.resolve(ok("ready")));
3670
3878
  *
3671
3879
  * const result = await fiber;
3672
- * expectTypeOf(result).toEqualTypeOf<Result<string>>();
3673
- * expectOk(result, "ready");
3880
+ * assertType<Result<string>, typeof result>();
3881
+ * assertOk(result, "ready");
3674
3882
  *
3675
3883
  * // A Deferred is one-shot: later resolutions are ignored, and future
3676
3884
  * // waiters receive the original Result.
3677
- * expect(deferred.resolve(ok("late"))).toBe(false);
3678
- * expectOk(await run(deferred.task), "ready");
3885
+ * assertFalse(deferred.resolve(ok("late")));
3886
+ * assertOk(await run(deferred.task), "ready");
3679
3887
  * ```
3680
3888
  *
3681
3889
  * ### Aborting a waiter
3682
3890
  *
3683
3891
  * ```ts
3684
- * import { AbortError, createDeferred, createRun } from "@evolu/common";
3892
+ * import {
3893
+ * assertFalse,
3894
+ * assertTrue,
3895
+ * AbortError,
3896
+ * createDeferred,
3897
+ * createRun,
3898
+ * } from "@evolu/common";
3685
3899
  *
3686
3900
  * await using run = createRun();
3687
3901
  * const deferred = createDeferred<string>();
@@ -3690,8 +3904,8 @@ export interface Deferred<T, E = never> {
3690
3904
  * fiber.abort({ type: "NoLongerNeeded" });
3691
3905
  *
3692
3906
  * const result = await fiber;
3693
- * assert(!result.ok);
3694
- * expect(AbortError.is(result.error)).toBe(true);
3907
+ * assertFalse(result.ok);
3908
+ * assertTrue(AbortError.is(result.error));
3695
3909
  * ```
3696
3910
  *
3697
3911
  * @group Concurrency primitives
@@ -3733,7 +3947,15 @@ export interface Gate {
3733
3947
  * ### Example
3734
3948
  *
3735
3949
  * ```ts
3736
- * import { createGate, createRun, ok, type Task } from "@evolu/common";
3950
+ * import {
3951
+ * assertEqual,
3952
+ * assertOk,
3953
+ * assertTrue,
3954
+ * createGate,
3955
+ * createRun,
3956
+ * ok,
3957
+ * type Task,
3958
+ * } from "@evolu/common";
3737
3959
  *
3738
3960
  * await using run = createRun();
3739
3961
  * const networkGate = createGate();
@@ -3749,13 +3971,13 @@ export interface Gate {
3749
3971
  *
3750
3972
  * const first = run(syncOnce("first"));
3751
3973
  * const second = run(syncOnce("second"));
3752
- * expect(uploadedItems).toEqual([]);
3974
+ * assertEqual(uploadedItems, []);
3753
3975
  *
3754
3976
  * networkGate.open();
3755
- * expectOk(await first, undefined);
3756
- * expectOk(await second, undefined);
3757
- * expect(uploadedItems).toEqual(["first", "second"]);
3758
- * expect(networkGate.isOpen()).toBe(true);
3977
+ * assertOk(await first, undefined);
3978
+ * assertOk(await second, undefined);
3979
+ * assertEqual(uploadedItems, ["first", "second"]);
3980
+ * assertTrue(networkGate.isOpen());
3759
3981
  * ```
3760
3982
  *
3761
3983
  * @group Concurrency primitives
@@ -3907,6 +4129,7 @@ export interface SemaphoreSnapshot {
3907
4129
  *
3908
4130
  * ```ts
3909
4131
  * import {
4132
+ * assertEqual,
3910
4133
  * createRun,
3911
4134
  * createSemaphore,
3912
4135
  * getOk,
@@ -3938,8 +4161,8 @@ export interface SemaphoreSnapshot {
3938
4161
  * ]);
3939
4162
  *
3940
4163
  * const savedUsers = results.map(getOk);
3941
- * expect(savedUsers).toEqual(["saved:1", "saved:2", "saved:3"]);
3942
- * expect(maxActiveSaves).toBe(2);
4164
+ * assertEqual(savedUsers, ["saved:1", "saved:2", "saved:3"]);
4165
+ * assertEqual(maxActiveSaves, 2);
3943
4166
  * ```
3944
4167
  *
3945
4168
  * @group Concurrency primitives
@@ -3973,6 +4196,8 @@ export interface Mutex {
3973
4196
  *
3974
4197
  * ```ts
3975
4198
  * import {
4199
+ * assertEqual,
4200
+ * assertOk,
3976
4201
  * createMutex,
3977
4202
  * createRun,
3978
4203
  * ok,
@@ -3995,9 +4220,9 @@ export interface Mutex {
3995
4220
  * run(deposit(2)),
3996
4221
  * run(deposit(3)),
3997
4222
  * ]);
3998
- * expectOk(first, undefined);
3999
- * expectOk(second, undefined);
4000
- * expect(balance).toBe(5);
4223
+ * assertOk(first, undefined);
4224
+ * assertOk(second, undefined);
4225
+ * assertEqual(balance, 5);
4001
4226
  * ```
4002
4227
  *
4003
4228
  * @group Concurrency primitives
@@ -4043,6 +4268,8 @@ export interface CreateSemaphoreByKeyOptions<K, L = K> extends LookupOption<K, L
4043
4268
  *
4044
4269
  * ```ts
4045
4270
  * import {
4271
+ * assertOk,
4272
+ * assertTrue,
4046
4273
  * createRun,
4047
4274
  * createSemaphoreByKey,
4048
4275
  * ok,
@@ -4055,11 +4282,11 @@ export interface CreateSemaphoreByKeyOptions<K, L = K> extends LookupOption<K, L
4055
4282
  * downloadsByHost.withPermit(host, () => ok(`${host}/${file}`));
4056
4283
  *
4057
4284
  * await using run = createRun();
4058
- * expectOk(
4285
+ * assertOk(
4059
4286
  * await run(download("a.example", "index.json")),
4060
4287
  * "a.example/index.json",
4061
4288
  * );
4062
- * expect(downloadsByHost.isIdle("a.example")).toBe(true);
4289
+ * assertTrue(downloadsByHost.isIdle("a.example"));
4063
4290
  * ```
4064
4291
  *
4065
4292
  * @group Concurrency primitives
@@ -4095,6 +4322,8 @@ export interface CreateMutexByKeyOptions<K, L = K> extends LookupOption<K, L> {
4095
4322
  *
4096
4323
  * ```ts
4097
4324
  * import {
4325
+ * assertOk,
4326
+ * assertTrue,
4098
4327
  * createMutexByKey,
4099
4328
  * createRun,
4100
4329
  * ok,
@@ -4111,9 +4340,9 @@ export interface CreateMutexByKeyOptions<K, L = K> extends LookupOption<K, L> {
4111
4340
  * });
4112
4341
  *
4113
4342
  * await using run = createRun();
4114
- * expectOk(await run(deposit("checking", 2)), 2);
4115
- * expectOk(await run(deposit("checking", 3)), 5);
4116
- * expect(accountLocks.isIdle("checking")).toBe(true);
4343
+ * assertOk(await run(deposit("checking", 2)), 2);
4344
+ * assertOk(await run(deposit("checking", 3)), 5);
4345
+ * assertTrue(accountLocks.isIdle("checking"));
4117
4346
  * ```
4118
4347
  *
4119
4348
  * @group Concurrency primitives
@@ -4169,14 +4398,14 @@ export interface MutexRef<T> {
4169
4398
  * ### Example
4170
4399
  *
4171
4400
  * ```ts
4172
- * import { createMutexRef, createRun, ok } from "@evolu/common";
4401
+ * import { assertOk, createMutexRef, createRun, ok } from "@evolu/common";
4173
4402
  *
4174
4403
  * const counter = createMutexRef(0);
4175
4404
  * const increment = counter.updateAndGet((value) => () => ok(value + 1));
4176
4405
  *
4177
4406
  * await using run = createRun();
4178
- * expectOk(await run(increment), 1);
4179
- * expectOk(await run(counter.get), 1);
4407
+ * assertOk(await run(increment), 1);
4408
+ * assertOk(await run(counter.get), 1);
4180
4409
  * ```
4181
4410
  *
4182
4411
  * @group Concurrency primitives