@evolu/common 8.9.0 → 8.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (337) hide show
  1. package/dist/src/Bytes.d.ts +647 -0
  2. package/dist/src/Bytes.d.ts.map +1 -0
  3. package/dist/src/{Binary.js → Bytes.js} +266 -16
  4. package/dist/src/Config.d.ts +142 -0
  5. package/dist/src/Config.d.ts.map +1 -0
  6. package/dist/src/Config.js +181 -0
  7. package/dist/src/Console.d.ts +62 -7
  8. package/dist/src/Console.d.ts.map +1 -1
  9. package/dist/src/Console.js +20 -4
  10. package/dist/src/Crypto.d.ts +76 -4
  11. package/dist/src/Crypto.d.ts.map +1 -1
  12. package/dist/src/Crypto.js +55 -4
  13. package/dist/src/Error.d.ts +45 -0
  14. package/dist/src/Error.d.ts.map +1 -1
  15. package/dist/src/Error.js +69 -0
  16. package/dist/src/Fs.d.ts +376 -0
  17. package/dist/src/Fs.d.ts.map +1 -0
  18. package/dist/src/Fs.js +113 -0
  19. package/dist/src/Identicon.d.ts +2 -2
  20. package/dist/src/Identicon.js +2 -2
  21. package/dist/src/LeakDetector.d.ts +22 -3
  22. package/dist/src/LeakDetector.d.ts.map +1 -1
  23. package/dist/src/LeakDetector.js +12 -2
  24. package/dist/src/LockManager.d.ts +8 -0
  25. package/dist/src/LockManager.d.ts.map +1 -1
  26. package/dist/src/LockManager.js +6 -0
  27. package/dist/src/Number.d.ts +50 -7
  28. package/dist/src/Number.d.ts.map +1 -1
  29. package/dist/src/Number.js +47 -8
  30. package/dist/src/Object.d.ts +32 -0
  31. package/dist/src/Object.d.ts.map +1 -1
  32. package/dist/src/Object.js +46 -0
  33. package/dist/src/Platform.d.ts +47 -7
  34. package/dist/src/Platform.d.ts.map +1 -1
  35. package/dist/src/Platform.js +24 -5
  36. package/dist/src/Random.d.ts +25 -2
  37. package/dist/src/Random.d.ts.map +1 -1
  38. package/dist/src/Random.js +14 -2
  39. package/dist/src/Resource.d.ts +156 -1
  40. package/dist/src/Resource.d.ts.map +1 -1
  41. package/dist/src/Resource.js +201 -72
  42. package/dist/src/Schedule.d.ts +11 -10
  43. package/dist/src/Schedule.d.ts.map +1 -1
  44. package/dist/src/Schedule.js +1 -1
  45. package/dist/src/Sqlite.d.ts +132 -16
  46. package/dist/src/Sqlite.d.ts.map +1 -1
  47. package/dist/src/Sqlite.js +64 -10
  48. package/dist/src/Task.d.ts +15 -4
  49. package/dist/src/Task.d.ts.map +1 -1
  50. package/dist/src/Task.js +41 -15
  51. package/dist/src/Test.d.ts +9 -0
  52. package/dist/src/Test.d.ts.map +1 -1
  53. package/dist/src/Test.js +4 -0
  54. package/dist/src/Time.d.ts +179 -20
  55. package/dist/src/Time.d.ts.map +1 -1
  56. package/dist/src/Time.js +95 -6
  57. package/dist/src/Type.d.ts +3056 -1539
  58. package/dist/src/Type.d.ts.map +1 -1
  59. package/dist/src/Type.js +2548 -584
  60. package/dist/src/WebSocket.d.ts +164 -13
  61. package/dist/src/WebSocket.d.ts.map +1 -1
  62. package/dist/src/WebSocket.js +133 -24
  63. package/dist/src/Worker.d.ts +90 -8
  64. package/dist/src/Worker.d.ts.map +1 -1
  65. package/dist/src/Worker.js +28 -2
  66. package/dist/src/index.d.ts +9 -8
  67. package/dist/src/index.d.ts.map +1 -1
  68. package/dist/src/index.js +5 -4
  69. package/dist/src/intl/_en.d.ts +24 -1
  70. package/dist/src/intl/_en.d.ts.map +1 -1
  71. package/dist/src/intl/_en.js +20 -0
  72. package/dist/src/intl/ar.d.ts +24 -1
  73. package/dist/src/intl/ar.d.ts.map +1 -1
  74. package/dist/src/intl/ar.js +20 -0
  75. package/dist/src/intl/bn.d.ts +24 -1
  76. package/dist/src/intl/bn.d.ts.map +1 -1
  77. package/dist/src/intl/bn.js +20 -0
  78. package/dist/src/intl/ca.d.ts +24 -1
  79. package/dist/src/intl/ca.d.ts.map +1 -1
  80. package/dist/src/intl/ca.js +20 -0
  81. package/dist/src/intl/cs.d.ts +24 -1
  82. package/dist/src/intl/cs.d.ts.map +1 -1
  83. package/dist/src/intl/cs.js +20 -0
  84. package/dist/src/intl/da.d.ts +24 -1
  85. package/dist/src/intl/da.d.ts.map +1 -1
  86. package/dist/src/intl/da.js +20 -0
  87. package/dist/src/intl/de.d.ts +24 -1
  88. package/dist/src/intl/de.d.ts.map +1 -1
  89. package/dist/src/intl/de.js +20 -0
  90. package/dist/src/intl/el.d.ts +24 -1
  91. package/dist/src/intl/el.d.ts.map +1 -1
  92. package/dist/src/intl/el.js +20 -0
  93. package/dist/src/intl/es.d.ts +24 -1
  94. package/dist/src/intl/es.d.ts.map +1 -1
  95. package/dist/src/intl/es.js +20 -0
  96. package/dist/src/intl/fa.d.ts +24 -1
  97. package/dist/src/intl/fa.d.ts.map +1 -1
  98. package/dist/src/intl/fa.js +20 -0
  99. package/dist/src/intl/fi.d.ts +24 -1
  100. package/dist/src/intl/fi.d.ts.map +1 -1
  101. package/dist/src/intl/fi.js +20 -0
  102. package/dist/src/intl/fil.d.ts +24 -1
  103. package/dist/src/intl/fil.d.ts.map +1 -1
  104. package/dist/src/intl/fil.js +20 -0
  105. package/dist/src/intl/fr.d.ts +24 -1
  106. package/dist/src/intl/fr.d.ts.map +1 -1
  107. package/dist/src/intl/fr.js +20 -0
  108. package/dist/src/intl/he.d.ts +24 -1
  109. package/dist/src/intl/he.d.ts.map +1 -1
  110. package/dist/src/intl/he.js +20 -0
  111. package/dist/src/intl/hi.d.ts +24 -1
  112. package/dist/src/intl/hi.d.ts.map +1 -1
  113. package/dist/src/intl/hi.js +20 -0
  114. package/dist/src/intl/hr.d.ts +24 -1
  115. package/dist/src/intl/hr.d.ts.map +1 -1
  116. package/dist/src/intl/hr.js +20 -0
  117. package/dist/src/intl/hu.d.ts +22 -1
  118. package/dist/src/intl/hu.d.ts.map +1 -1
  119. package/dist/src/intl/hu.js +18 -0
  120. package/dist/src/intl/id.d.ts +24 -1
  121. package/dist/src/intl/id.d.ts.map +1 -1
  122. package/dist/src/intl/id.js +20 -0
  123. package/dist/src/intl/it.d.ts +24 -1
  124. package/dist/src/intl/it.d.ts.map +1 -1
  125. package/dist/src/intl/it.js +20 -0
  126. package/dist/src/intl/ja.d.ts +24 -1
  127. package/dist/src/intl/ja.d.ts.map +1 -1
  128. package/dist/src/intl/ja.js +20 -0
  129. package/dist/src/intl/ko.d.ts +24 -1
  130. package/dist/src/intl/ko.d.ts.map +1 -1
  131. package/dist/src/intl/ko.js +20 -0
  132. package/dist/src/intl/ml.d.ts +24 -1
  133. package/dist/src/intl/ml.d.ts.map +1 -1
  134. package/dist/src/intl/ml.js +20 -0
  135. package/dist/src/intl/mr.d.ts +24 -1
  136. package/dist/src/intl/mr.d.ts.map +1 -1
  137. package/dist/src/intl/mr.js +20 -0
  138. package/dist/src/intl/ms.d.ts +24 -1
  139. package/dist/src/intl/ms.d.ts.map +1 -1
  140. package/dist/src/intl/ms.js +20 -0
  141. package/dist/src/intl/nb.d.ts +22 -1
  142. package/dist/src/intl/nb.d.ts.map +1 -1
  143. package/dist/src/intl/nb.js +18 -0
  144. package/dist/src/intl/nl.d.ts +24 -1
  145. package/dist/src/intl/nl.d.ts.map +1 -1
  146. package/dist/src/intl/nl.js +20 -0
  147. package/dist/src/intl/pa.d.ts +24 -1
  148. package/dist/src/intl/pa.d.ts.map +1 -1
  149. package/dist/src/intl/pa.js +20 -0
  150. package/dist/src/intl/pl.d.ts +23 -0
  151. package/dist/src/intl/pl.d.ts.map +1 -1
  152. package/dist/src/intl/pl.js +20 -0
  153. package/dist/src/intl/pt-BR.d.ts +24 -1
  154. package/dist/src/intl/pt-BR.d.ts.map +1 -1
  155. package/dist/src/intl/pt-BR.js +20 -0
  156. package/dist/src/intl/pt.d.ts +24 -1
  157. package/dist/src/intl/pt.d.ts.map +1 -1
  158. package/dist/src/intl/pt.js +20 -0
  159. package/dist/src/intl/ro.d.ts +24 -1
  160. package/dist/src/intl/ro.d.ts.map +1 -1
  161. package/dist/src/intl/ro.js +20 -0
  162. package/dist/src/intl/sk.d.ts +24 -1
  163. package/dist/src/intl/sk.d.ts.map +1 -1
  164. package/dist/src/intl/sk.js +20 -0
  165. package/dist/src/intl/sl.d.ts +24 -1
  166. package/dist/src/intl/sl.d.ts.map +1 -1
  167. package/dist/src/intl/sl.js +20 -0
  168. package/dist/src/intl/sv.d.ts +24 -1
  169. package/dist/src/intl/sv.d.ts.map +1 -1
  170. package/dist/src/intl/sv.js +20 -0
  171. package/dist/src/intl/sw.d.ts +21 -0
  172. package/dist/src/intl/sw.d.ts.map +1 -1
  173. package/dist/src/intl/sw.js +18 -0
  174. package/dist/src/intl/ta.d.ts +24 -1
  175. package/dist/src/intl/ta.d.ts.map +1 -1
  176. package/dist/src/intl/ta.js +20 -0
  177. package/dist/src/intl/te.d.ts +24 -1
  178. package/dist/src/intl/te.d.ts.map +1 -1
  179. package/dist/src/intl/te.js +20 -0
  180. package/dist/src/intl/th.d.ts +24 -1
  181. package/dist/src/intl/th.d.ts.map +1 -1
  182. package/dist/src/intl/th.js +20 -0
  183. package/dist/src/intl/tr.d.ts +24 -1
  184. package/dist/src/intl/tr.d.ts.map +1 -1
  185. package/dist/src/intl/tr.js +20 -0
  186. package/dist/src/intl/uk.d.ts +80 -57
  187. package/dist/src/intl/uk.d.ts.map +1 -1
  188. package/dist/src/intl/uk.js +174 -149
  189. package/dist/src/intl/ur.d.ts +24 -1
  190. package/dist/src/intl/ur.d.ts.map +1 -1
  191. package/dist/src/intl/ur.js +20 -0
  192. package/dist/src/intl/vi.d.ts +24 -1
  193. package/dist/src/intl/vi.d.ts.map +1 -1
  194. package/dist/src/intl/vi.js +20 -0
  195. package/dist/src/intl/zh-CN.d.ts +24 -1
  196. package/dist/src/intl/zh-CN.d.ts.map +1 -1
  197. package/dist/src/intl/zh-CN.js +20 -0
  198. package/dist/src/intl/zh-TW.d.ts +24 -1
  199. package/dist/src/intl/zh-TW.d.ts.map +1 -1
  200. package/dist/src/intl/zh-TW.js +20 -0
  201. package/dist/src/local-first/Db.d.ts +52 -3
  202. package/dist/src/local-first/Db.d.ts.map +1 -1
  203. package/dist/src/local-first/Db.js +412 -137
  204. package/dist/src/local-first/Evolu.d.ts +336 -211
  205. package/dist/src/local-first/Evolu.d.ts.map +1 -1
  206. package/dist/src/local-first/Evolu.js +102 -15
  207. package/dist/src/local-first/Owner.d.ts +13 -30
  208. package/dist/src/local-first/Owner.d.ts.map +1 -1
  209. package/dist/src/local-first/Owner.js +13 -30
  210. package/dist/src/local-first/Protocol.d.ts +95 -17
  211. package/dist/src/local-first/Protocol.d.ts.map +1 -1
  212. package/dist/src/local-first/Protocol.js +119 -39
  213. package/dist/src/local-first/Query.d.ts +8 -15
  214. package/dist/src/local-first/Query.d.ts.map +1 -1
  215. package/dist/src/local-first/Schema.d.ts +345 -21
  216. package/dist/src/local-first/Schema.d.ts.map +1 -1
  217. package/dist/src/local-first/Schema.js +214 -17
  218. package/dist/src/local-first/Shared.d.ts +537 -22
  219. package/dist/src/local-first/Shared.d.ts.map +1 -1
  220. package/dist/src/local-first/Shared.js +1437 -234
  221. package/dist/src/local-first/Storage.d.ts +192 -14
  222. package/dist/src/local-first/Storage.d.ts.map +1 -1
  223. package/dist/src/local-first/Storage.js +82 -21
  224. package/dist/src/local-first/Timestamp.d.ts +392 -41
  225. package/dist/src/local-first/Timestamp.d.ts.map +1 -1
  226. package/dist/src/local-first/Timestamp.js +404 -82
  227. package/dist/src/local-first/index.d.ts +0 -1
  228. package/dist/src/local-first/index.d.ts.map +1 -1
  229. package/dist/src/local-first/index.js +0 -1
  230. package/package.json +1 -1
  231. package/src/Assert.test.ts +2 -5
  232. package/src/{Binary.test.ts → Bytes.test.ts} +286 -1
  233. package/src/{Binary.ts → Bytes.ts} +652 -21
  234. package/src/Config.test.ts +668 -0
  235. package/src/Config.ts +410 -0
  236. package/src/Console.ts +62 -7
  237. package/src/Crypto.ts +76 -4
  238. package/src/Eq.test.ts +2 -3
  239. package/src/Error.test.ts +76 -3
  240. package/src/Error.ts +71 -0
  241. package/src/Fs.test.ts +105 -0
  242. package/src/Fs.ts +488 -0
  243. package/src/Identicon.ts +2 -2
  244. package/src/LeakDetector.ts +22 -3
  245. package/src/LockManager.ts +8 -0
  246. package/src/Number.test.ts +82 -18
  247. package/src/Number.ts +76 -8
  248. package/src/Object.test.ts +139 -10
  249. package/src/Object.ts +49 -0
  250. package/src/Platform.ts +50 -8
  251. package/src/Random.ts +25 -2
  252. package/src/Resource.test.ts +837 -0
  253. package/src/Resource.ts +235 -15
  254. package/src/Schedule.test.ts +50 -12
  255. package/src/Schedule.ts +24 -14
  256. package/src/Sqlite.ts +138 -18
  257. package/src/Task.test.ts +189 -8
  258. package/src/Task.ts +56 -17
  259. package/src/Test.ts +9 -0
  260. package/src/Time.test.ts +82 -11
  261. package/src/Time.ts +246 -24
  262. package/src/Type.test.ts +3994 -1119
  263. package/src/Type.ts +7258 -3842
  264. package/src/Types.test.ts +4 -14
  265. package/src/WebSocket.ts +313 -40
  266. package/src/Worker.ts +90 -8
  267. package/src/index.ts +18 -7
  268. package/src/intl/_en.ts +70 -0
  269. package/src/intl/ar.ts +71 -0
  270. package/src/intl/bn.ts +70 -0
  271. package/src/intl/ca.ts +70 -0
  272. package/src/intl/cs.ts +70 -0
  273. package/src/intl/da.ts +70 -0
  274. package/src/intl/de.ts +70 -0
  275. package/src/intl/el.ts +70 -0
  276. package/src/intl/es.ts +70 -0
  277. package/src/intl/fa.ts +70 -0
  278. package/src/intl/fi.ts +70 -0
  279. package/src/intl/fil.ts +70 -0
  280. package/src/intl/fr.ts +70 -0
  281. package/src/intl/he.ts +70 -0
  282. package/src/intl/hi.ts +70 -0
  283. package/src/intl/hr.ts +70 -0
  284. package/src/intl/hu.ts +69 -0
  285. package/src/intl/id.ts +70 -0
  286. package/src/intl/intl.test.ts +819 -1
  287. package/src/intl/it.ts +70 -0
  288. package/src/intl/ja.ts +70 -0
  289. package/src/intl/ko.ts +68 -0
  290. package/src/intl/ml.ts +70 -0
  291. package/src/intl/mr.ts +70 -0
  292. package/src/intl/ms.ts +71 -0
  293. package/src/intl/nb.ts +69 -0
  294. package/src/intl/nl.ts +70 -0
  295. package/src/intl/pa.ts +70 -0
  296. package/src/intl/pl.ts +63 -0
  297. package/src/intl/pt-BR.ts +70 -0
  298. package/src/intl/pt.ts +71 -0
  299. package/src/intl/ro.ts +70 -0
  300. package/src/intl/sk.ts +71 -0
  301. package/src/intl/sl.ts +70 -0
  302. package/src/intl/sv.ts +70 -0
  303. package/src/intl/sw.ts +62 -0
  304. package/src/intl/ta.ts +70 -0
  305. package/src/intl/te.ts +70 -0
  306. package/src/intl/th.ts +68 -0
  307. package/src/intl/tr.ts +70 -0
  308. package/src/intl/uk.ts +228 -155
  309. package/src/intl/ur.ts +70 -0
  310. package/src/intl/vi.ts +70 -0
  311. package/src/intl/zh-CN.ts +68 -0
  312. package/src/intl/zh-TW.ts +68 -0
  313. package/src/local-first/Db.ts +644 -339
  314. package/src/local-first/Evolu.test.ts +686 -21
  315. package/src/local-first/Evolu.ts +450 -228
  316. package/src/local-first/Owner.ts +13 -30
  317. package/src/local-first/Protocol.test.ts +618 -11
  318. package/src/local-first/Protocol.ts +197 -73
  319. package/src/local-first/Query.ts +8 -15
  320. package/src/local-first/Schema.test.ts +143 -0
  321. package/src/local-first/Schema.ts +374 -24
  322. package/src/local-first/Shared.test.ts +7731 -559
  323. package/src/local-first/Shared.ts +2036 -267
  324. package/src/local-first/Storage.ts +219 -33
  325. package/src/local-first/Timestamp.test.ts +344 -70
  326. package/src/local-first/Timestamp.ts +435 -119
  327. package/src/local-first/index.ts +0 -1
  328. package/dist/src/Binary.d.ts +0 -254
  329. package/dist/src/Binary.d.ts.map +0 -1
  330. package/dist/src/local-first/Error.d.ts +0 -12
  331. package/dist/src/local-first/Error.d.ts.map +0 -1
  332. package/dist/src/local-first/Error.js +0 -6
  333. package/dist/src/local-first/LocalAuth.d.ts +0 -150
  334. package/dist/src/local-first/LocalAuth.d.ts.map +0 -1
  335. package/dist/src/local-first/LocalAuth.js +0 -179
  336. package/src/local-first/Error.ts +0 -17
  337. package/src/local-first/LocalAuth.ts +0 -457
package/src/Time.ts CHANGED
@@ -1,15 +1,31 @@
1
1
  /**
2
2
  * Time representations, durations, and scheduling utilities.
3
3
  *
4
+ * Durations follow a pattern that other quantities in Evolu repeat, such as
5
+ * sizes in Bytes.ts:
6
+ *
7
+ * - {@link Millis} is the canonical unit, a validated number of milliseconds.
8
+ * - {@link DurationLiteral} is the human-readable form, such as `"1.5s"`,
9
+ * validated at compile time and runtime.
10
+ * - {@link Duration} is what APIs accept: `DurationLiteral | Millis`.
11
+ * - {@link durationToMillis} normalizes a `Duration` to `Millis`.
12
+ *
4
13
  * @module
5
14
  */
6
15
 
16
+ import { safelyStringifyUnknownValue } from "./String.ts";
7
17
  import { assert } from "./Assert.ts";
8
18
  import type { Brand } from "./Brand.ts";
9
19
  import { exhaustiveCheck } from "./Function.ts";
10
20
  import type { yieldNow } from "./Task.ts";
11
21
  import {
12
22
  brand,
23
+ createTypeWithError,
24
+ type Type,
25
+ type TypeError,
26
+ type UnionError,
27
+ type UnionType,
28
+ type TemplateLiteralType,
13
29
  type DateIso,
14
30
  Digit,
15
31
  Digit1To23,
@@ -26,7 +42,11 @@ import {
26
42
  union,
27
43
  } from "./Type.ts";
28
44
 
29
- /** Time and timer operations. */
45
+ /**
46
+ * Time and timer operations.
47
+ *
48
+ * @group Core
49
+ */
30
50
  export interface Time {
31
51
  readonly now: {
32
52
  /** Returns current time as Unix epoch milliseconds. */
@@ -64,6 +84,11 @@ export interface Time {
64
84
  readonly clearTimeout: (id: TimeoutId) => void;
65
85
  }
66
86
 
87
+ /**
88
+ * Dependency wrapper for {@link Time}.
89
+ *
90
+ * @group Core
91
+ */
67
92
  export interface TimeDep {
68
93
  readonly time: Time;
69
94
  }
@@ -72,6 +97,8 @@ export interface TimeDep {
72
97
  * Opaque type for timeout handles.
73
98
  *
74
99
  * Use with {@link Time.clearTimeout} to cancel a pending timeout.
100
+ *
101
+ * @group Core
75
102
  */
76
103
  export type TimeoutId = Brand<"TimeoutId">;
77
104
 
@@ -91,6 +118,8 @@ interface TimeoutIdInternal {
91
118
  *
92
119
  * Throws if the system clock returns an out-of-range value. This is intentional
93
120
  * — there's no reasonable fallback for a misconfigured clock.
121
+ *
122
+ * @group Core
94
123
  */
95
124
  export const createTime = (): Time => {
96
125
  const timeoutOwner = Symbol("Time");
@@ -188,6 +217,8 @@ const clearTimeoutId = (owner: symbol, id: TimeoutId): void => {
188
217
  * Test {@link Time} with controllable timers.
189
218
  *
190
219
  * Call `advance(ms)` to move time forward and trigger any pending timeouts.
220
+ *
221
+ * @group Testing
191
222
  */
192
223
  export interface TestTime extends Time {
193
224
  /**
@@ -199,6 +230,11 @@ export interface TestTime extends Time {
199
230
  readonly advance: (duration: Duration) => void;
200
231
  }
201
232
 
233
+ /**
234
+ * Dependency wrapper for {@link TestTime}.
235
+ *
236
+ * @group Testing
237
+ */
202
238
  export interface TestTimeDep {
203
239
  readonly time: TestTime;
204
240
  }
@@ -214,6 +250,8 @@ export interface TestTimeDep {
214
250
  * wall-clock or performance `now()` call. `"microtask"` increments after the
215
251
  * current turn, while `"sync"` increments immediately after each read. Omit it
216
252
  * to keep time fixed until `advance()` is called.
253
+ *
254
+ * @group Testing
217
255
  */
218
256
  export const testCreateTime = (options?: {
219
257
  readonly startAt?: Millis;
@@ -325,6 +363,8 @@ const maxMillisWithInfinity = 281474976710655;
325
363
  *
326
364
  * If a system clock exceeds this range, operations will throw. This is
327
365
  * intentional — there's no reasonable fallback for a misconfigured clock.
366
+ *
367
+ * @group Millis
328
368
  */
329
369
  export const Millis = /*#__PURE__*/ brand(
330
370
  "Millis",
@@ -332,19 +372,33 @@ export const Millis = /*#__PURE__*/ brand(
332
372
  );
333
373
  export type Millis = typeof Millis.Output;
334
374
 
335
- /** Positive {@link Millis} value. */
375
+ /**
376
+ * Positive {@link Millis} value.
377
+ *
378
+ * @group Millis
379
+ */
336
380
  export const PositiveMillis = /*#__PURE__*/ positive(Millis);
337
381
  export type PositiveMillis = typeof PositiveMillis.Output;
338
382
 
339
- /** Minimum {@link Millis} value. */
383
+ /**
384
+ * Minimum {@link Millis} value.
385
+ *
386
+ * @group Millis
387
+ */
340
388
  export const minMillis = 0 as Millis;
341
389
 
342
- /** Maximum {@link Millis} value. */
390
+ /**
391
+ * Maximum {@link Millis} value.
392
+ *
393
+ * @group Millis
394
+ */
343
395
  export const maxMillis = (maxMillisWithInfinity - 1) as Millis;
344
396
 
345
397
  /**
346
398
  * Converts a number to {@link Millis}, rounding to the nearest millisecond and
347
399
  * saturating overflow at {@link maxMillis}.
400
+ *
401
+ * @group Millis
348
402
  */
349
403
  export const saturateMillis = (value: NonNaNNumber): Millis =>
350
404
  Millis.orNull(Math.max(0, Math.round(value))) ?? maxMillis;
@@ -354,23 +408,39 @@ export const saturateMillis = (value: NonNaNNumber): Millis =>
354
408
  *
355
409
  * This is a safe cast because {@link Millis} guarantees a valid timestamp range
356
410
  * that always produces a valid ISO string.
411
+ *
412
+ * @group Millis
357
413
  */
358
414
  export const millisToDateIso = (value: Millis): DateIso =>
359
415
  new Date(value).toISOString() as DateIso;
360
416
 
361
- /** Unix epoch milliseconds used as the origin for {@link PerformanceTime}. */
417
+ /**
418
+ * Unix epoch milliseconds used as the origin for {@link PerformanceTime}.
419
+ *
420
+ * @group Performance
421
+ */
362
422
  export type PerformanceTimeOrigin = number & Brand<"PerformanceTimeOrigin">;
363
423
 
364
- /** High-resolution milliseconds elapsed since {@link PerformanceTimeOrigin}. */
424
+ /**
425
+ * High-resolution milliseconds elapsed since {@link PerformanceTimeOrigin}.
426
+ *
427
+ * @group Performance
428
+ */
365
429
  export type PerformanceTime = number & Brand<"PerformanceTime">;
366
430
 
367
- /** Elapsed fractional milliseconds measured using {@link PerformanceTime}. */
431
+ /**
432
+ * Elapsed fractional milliseconds measured using {@link PerformanceTime}.
433
+ *
434
+ * @group Performance
435
+ */
368
436
  export type PerformanceDuration = number & Brand<"PerformanceDuration">;
369
437
 
370
438
  /**
371
439
  * Returns the elapsed fractional milliseconds between two performance times.
372
440
  *
373
441
  * Throws if `end` precedes `start`.
442
+ *
443
+ * @group Performance
374
444
  */
375
445
  export const performanceDurationBetween = (
376
446
  start: PerformanceTime,
@@ -396,6 +466,8 @@ export const performanceDurationBetween = (
396
466
  *
397
467
  * assertType<typeof readableSchedule, typeof validatedSchedule>();
398
468
  * ```
469
+ *
470
+ * @group Durations
399
471
  */
400
472
  export type Duration = DurationLiteral | Millis;
401
473
 
@@ -415,11 +487,27 @@ export type Duration = DurationLiteral | Millis;
415
487
  *
416
488
  * assertType<typeof readableSleep, typeof validatedSleep>();
417
489
  * ```
490
+ *
491
+ * @group Durations
418
492
  */
419
493
  export type PositiveDuration = DurationLiteral | PositiveMillis;
420
494
 
421
- /** Milliseconds duration: `"1ms"` to `"999ms"`. See {@link DurationLiteral}. */
422
- export const DurationLiteralMilliseconds = /*#__PURE__*/ union(
495
+ // Keep these annotations concrete. Generic unit wrappers add thousands of
496
+ // compiler instantiations to pnpm bench:type.
497
+ /**
498
+ * Milliseconds duration: `"1ms"` to `"999ms"`. See {@link DurationLiteral}.
499
+ *
500
+ * @group Durations
501
+ */
502
+ export const DurationLiteralMilliseconds: UnionType<
503
+ readonly [
504
+ TemplateLiteralType<readonly [typeof Digit1To9, "ms"]>,
505
+ TemplateLiteralType<readonly [typeof Digit1To9, typeof Digit, "ms"]>,
506
+ TemplateLiteralType<
507
+ readonly [typeof Digit1To9, typeof Digit, typeof Digit, "ms"]
508
+ >,
509
+ ]
510
+ > = /*#__PURE__*/ union(
423
511
  /*#__PURE__*/ templateLiteral(Digit1To9, "ms"),
424
512
  /*#__PURE__*/ templateLiteral(Digit1To9, Digit, "ms"),
425
513
  /*#__PURE__*/ templateLiteral(Digit1To9, Digit, Digit, "ms"),
@@ -430,8 +518,17 @@ export type DurationLiteralMilliseconds =
430
518
  /**
431
519
  * Seconds duration: `"1s"` to `"59s"` or `"1.1s"` to `"59.9s"`. See
432
520
  * {@link DurationLiteral}.
521
+ *
522
+ * @group Durations
433
523
  */
434
- export const DurationLiteralSeconds = /*#__PURE__*/ union(
524
+ export const DurationLiteralSeconds: UnionType<
525
+ readonly [
526
+ TemplateLiteralType<readonly [typeof Digit1To59, "s"]>,
527
+ TemplateLiteralType<
528
+ readonly [typeof Digit1To59, ".", typeof Digit1To9, "s"]
529
+ >,
530
+ ]
531
+ > = /*#__PURE__*/ union(
435
532
  /*#__PURE__*/ templateLiteral(Digit1To59, "s"),
436
533
  /*#__PURE__*/ templateLiteral(Digit1To59, ".", Digit1To9, "s"),
437
534
  );
@@ -440,8 +537,17 @@ export type DurationLiteralSeconds = typeof DurationLiteralSeconds.Output;
440
537
  /**
441
538
  * Minutes duration: `"1m"` to `"59m"` or `"1.1m"` to `"59.9m"`. See
442
539
  * {@link DurationLiteral}.
540
+ *
541
+ * @group Durations
443
542
  */
444
- export const DurationLiteralMinutes = /*#__PURE__*/ union(
543
+ export const DurationLiteralMinutes: UnionType<
544
+ readonly [
545
+ TemplateLiteralType<readonly [typeof Digit1To59, "m"]>,
546
+ TemplateLiteralType<
547
+ readonly [typeof Digit1To59, ".", typeof Digit1To9, "m"]
548
+ >,
549
+ ]
550
+ > = /*#__PURE__*/ union(
445
551
  /*#__PURE__*/ templateLiteral(Digit1To59, "m"),
446
552
  /*#__PURE__*/ templateLiteral(Digit1To59, ".", Digit1To9, "m"),
447
553
  );
@@ -450,8 +556,17 @@ export type DurationLiteralMinutes = typeof DurationLiteralMinutes.Output;
450
556
  /**
451
557
  * Hours duration: `"1h"` to `"23h"` or `"1.1h"` to `"23.9h"`. See
452
558
  * {@link DurationLiteral}.
559
+ *
560
+ * @group Durations
453
561
  */
454
- export const DurationLiteralHours = /*#__PURE__*/ union(
562
+ export const DurationLiteralHours: UnionType<
563
+ readonly [
564
+ TemplateLiteralType<readonly [typeof Digit1To23, "h"]>,
565
+ TemplateLiteralType<
566
+ readonly [typeof Digit1To23, ".", typeof Digit1To9, "h"]
567
+ >,
568
+ ]
569
+ > = /*#__PURE__*/ union(
455
570
  /*#__PURE__*/ templateLiteral(Digit1To23, "h"),
456
571
  /*#__PURE__*/ templateLiteral(Digit1To23, ".", Digit1To9, "h"),
457
572
  );
@@ -460,8 +575,17 @@ export type DurationLiteralHours = typeof DurationLiteralHours.Output;
460
575
  /**
461
576
  * Days duration: `"1d"` to `"6d"` or `"1.1d"` to `"6.9d"`. See
462
577
  * {@link DurationLiteral}.
578
+ *
579
+ * @group Durations
463
580
  */
464
- export const DurationLiteralDays = /*#__PURE__*/ union(
581
+ export const DurationLiteralDays: UnionType<
582
+ readonly [
583
+ TemplateLiteralType<readonly [typeof Digit1To6, "d"]>,
584
+ TemplateLiteralType<
585
+ readonly [typeof Digit1To6, ".", typeof Digit1To9, "d"]
586
+ >,
587
+ ]
588
+ > = /*#__PURE__*/ union(
465
589
  /*#__PURE__*/ templateLiteral(Digit1To6, "d"),
466
590
  /*#__PURE__*/ templateLiteral(Digit1To6, ".", Digit1To9, "d"),
467
591
  );
@@ -470,8 +594,17 @@ export type DurationLiteralDays = typeof DurationLiteralDays.Output;
470
594
  /**
471
595
  * Weeks duration: `"1w"` to `"51w"` or `"1.1w"` to `"51.9w"`. See
472
596
  * {@link DurationLiteral}.
597
+ *
598
+ * @group Durations
473
599
  */
474
- export const DurationLiteralWeeks = /*#__PURE__*/ union(
600
+ export const DurationLiteralWeeks: UnionType<
601
+ readonly [
602
+ TemplateLiteralType<readonly [typeof Digit1To51, "w"]>,
603
+ TemplateLiteralType<
604
+ readonly [typeof Digit1To51, ".", typeof Digit1To9, "w"]
605
+ >,
606
+ ]
607
+ > = /*#__PURE__*/ union(
475
608
  /*#__PURE__*/ templateLiteral(Digit1To51, "w"),
476
609
  /*#__PURE__*/ templateLiteral(Digit1To51, ".", Digit1To9, "w"),
477
610
  );
@@ -480,13 +613,47 @@ export type DurationLiteralWeeks = typeof DurationLiteralWeeks.Output;
480
613
  /**
481
614
  * Years duration: `"1y"` to `"99y"` or `"1.1y"` to `"99.9y"`. See
482
615
  * {@link DurationLiteral}.
616
+ *
617
+ * @group Durations
483
618
  */
484
- export const DurationLiteralYears = /*#__PURE__*/ union(
619
+ export const DurationLiteralYears: UnionType<
620
+ readonly [
621
+ TemplateLiteralType<readonly [typeof Digit1To99, "y"]>,
622
+ TemplateLiteralType<
623
+ readonly [typeof Digit1To99, ".", typeof Digit1To9, "y"]
624
+ >,
625
+ ]
626
+ > = /*#__PURE__*/ union(
485
627
  /*#__PURE__*/ templateLiteral(Digit1To99, "y"),
486
628
  /*#__PURE__*/ templateLiteral(Digit1To99, ".", Digit1To9, "y"),
487
629
  );
488
630
  export type DurationLiteralYears = typeof DurationLiteralYears.Output;
489
631
 
632
+ /**
633
+ * Duration literal string, from {@link DurationLiteralMilliseconds} to
634
+ * {@link DurationLiteralYears}.
635
+ *
636
+ * @group Durations
637
+ */
638
+ export type DurationLiteral =
639
+ | DurationLiteralMilliseconds
640
+ | DurationLiteralSeconds
641
+ | DurationLiteralMinutes
642
+ | DurationLiteralHours
643
+ | DurationLiteralDays
644
+ | DurationLiteralWeeks
645
+ | DurationLiteralYears;
646
+
647
+ const durationLiteralSyntax = /*#__PURE__*/ union(
648
+ DurationLiteralMilliseconds,
649
+ DurationLiteralSeconds,
650
+ DurationLiteralMinutes,
651
+ DurationLiteralHours,
652
+ DurationLiteralDays,
653
+ DurationLiteralWeeks,
654
+ DurationLiteralYears,
655
+ );
656
+
490
657
  /**
491
658
  * Duration literal Type with compile-time and runtime validation.
492
659
  *
@@ -514,17 +681,61 @@ export type DurationLiteralYears = typeof DurationLiteralYears.Output;
514
681
  *
515
682
  * See {@link Duration} for a type that also accepts {@link Millis}. Use
516
683
  * {@link durationToMillis} to convert to milliseconds.
684
+ *
685
+ * Invalid values produce a {@link DurationLiteralError}.
686
+ *
687
+ * ### Example
688
+ *
689
+ * ```ts
690
+ * import {
691
+ * assertFalse,
692
+ * assertOk,
693
+ * assertType,
694
+ * DurationLiteral,
695
+ * } from "@evolu/common";
696
+ *
697
+ * // The TypeScript type accepts valid spellings and rejects the rest.
698
+ * const literal: DurationLiteral = "1.5s";
699
+ * assertType<Extract<DurationLiteral, "1000ms" | "60s" | "0s">, never>();
700
+ *
701
+ * // The runtime Type validates the same grammar.
702
+ * assertOk(DurationLiteral.fromUnknown(literal), "1.5s");
703
+ * assertFalse(DurationLiteral.is("1000ms"));
704
+ * ```
705
+ *
706
+ * @group Durations
517
707
  */
518
- export const DurationLiteral = /*#__PURE__*/ union(
519
- DurationLiteralMilliseconds,
520
- DurationLiteralSeconds,
521
- DurationLiteralMinutes,
522
- DurationLiteralHours,
523
- DurationLiteralDays,
524
- DurationLiteralWeeks,
525
- DurationLiteralYears,
708
+ export const DurationLiteral: Type<
709
+ "DurationLiteral",
710
+ DurationLiteral,
711
+ DurationLiteral,
712
+ DurationLiteralError
713
+ > = /*#__PURE__*/ createTypeWithError(
714
+ "DurationLiteral",
715
+ durationLiteralSyntax,
716
+ (cause, value): DurationLiteralError => ({
717
+ type: "DurationLiteral",
718
+ value,
719
+ cause,
720
+ }),
721
+ (error) =>
722
+ `The value ${safelyStringifyUnknownValue(error.value)} is not a duration literal. Use a value such as "500ms" or "1.5s".`,
526
723
  );
527
- export type DurationLiteral = typeof DurationLiteral.Output;
724
+
725
+ /**
726
+ * Error returned when {@link DurationLiteral} rejects a value.
727
+ *
728
+ * @group Durations
729
+ */
730
+ export interface DurationLiteralError extends TypeError<"DurationLiteral"> {
731
+ readonly value: unknown;
732
+ /**
733
+ * The underlying union failure, retained for diagnostics.
734
+ *
735
+ * With `{ errors: "all" }`, includes every failed alternative.
736
+ */
737
+ readonly cause: UnionError;
738
+ }
528
739
 
529
740
  /**
530
741
  * Converts a duration to milliseconds.
@@ -543,6 +754,8 @@ export type DurationLiteral = typeof DurationLiteral.Output;
543
754
  * assertEqual(durationToMillis("1w"), 604800000);
544
755
  * assertEqual(durationToMillis(Millis.orThrow(5000)), 5000);
545
756
  * ```
757
+ *
758
+ * @group Durations
546
759
  */
547
760
  export function durationToMillis(
548
761
  duration: DurationLiteral | PositiveMillis,
@@ -579,6 +792,8 @@ const durationUnits = {
579
792
  * Frame budget at 60fps (16ms).
580
793
  *
581
794
  * Work exceeding this blocks a frame, causing visible jank in animations.
795
+ *
796
+ * @group Millis
582
797
  */
583
798
  export const ms60fps = 16 as Millis;
584
799
 
@@ -586,6 +801,8 @@ export const ms60fps = 16 as Millis;
586
801
  * Frame budget at 120fps (8ms).
587
802
  *
588
803
  * For high refresh rate displays. Work exceeding this blocks a frame.
804
+ *
805
+ * @group Millis
589
806
  */
590
807
  export const ms120fps = 8 as Millis;
591
808
 
@@ -595,6 +812,7 @@ export const ms120fps = 8 as Millis;
595
812
  * Tasks exceeding this are "long tasks" per web standards. Use with
596
813
  * {@link yieldNow} to yield periodically and keep UI responsive.
597
814
  *
815
+ * @group Millis
598
816
  * @see https://web.dev/articles/optimize-long-tasks
599
817
  */
600
818
  export const msLongTask = 50 as Millis;
@@ -627,6 +845,8 @@ export const msLongTask = 50 as Millis;
627
845
  * "1d1h1m1.000s",
628
846
  * );
629
847
  * ```
848
+ *
849
+ * @group Millis
630
850
  */
631
851
  export const formatMillisAsDuration = (millis: Millis): string => {
632
852
  const seconds = ((millis % durationUnits.m) / durationUnits.s).toFixed(3);
@@ -671,6 +891,8 @@ export const formatMillisAsDuration = (millis: Millis): string => {
671
891
  * "14:32:15.234",
672
892
  * );
673
893
  * ```
894
+ *
895
+ * @group Millis
674
896
  */
675
897
  export const formatMillisAsClockTime = (millis: Millis): string => {
676
898
  const date = new Date(millis);