@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
@@ -23,22 +23,32 @@ import {
23
23
  type SqliteSchema,
24
24
  SqliteValue,
25
25
  } from "../Sqlite.ts";
26
+ import type { Millis } from "../Time.ts";
26
27
  import {
27
28
  assertType,
29
+ createIdFromString,
28
30
  DateIso,
29
31
  type FiniteNumber,
30
32
  type Id,
33
+ id,
31
34
  IdBytes,
32
35
  type InferType,
36
+ NonEmptyTrimmedString100,
33
37
  Null,
34
38
  nullOr,
35
39
  object,
36
40
  type ObjectType,
37
41
  type UnionType,
42
+ type withDefault,
38
43
  } from "../Type.ts";
39
44
  import type { CompileTimeError, Simplify } from "../Types.ts";
40
- import type { AppOwner } from "./Owner.ts";
41
- import { OwnerId } from "./Owner.ts";
45
+ import type { AppOwner, OwnerIdBytes } from "./Owner.ts";
46
+ import {
47
+ OwnerEncryptionKey,
48
+ OwnerId,
49
+ OwnerSecret,
50
+ OwnerWriteKey,
51
+ } from "./Owner.ts";
42
52
  import type {
43
53
  evoluJsonArrayFrom,
44
54
  evoluJsonObjectFrom,
@@ -48,7 +58,11 @@ import type {
48
58
  import type { CrdtMessage, DbChange } from "./Storage.ts";
49
59
  import { TimestampBytes } from "./Timestamp.ts";
50
60
 
51
- /** Any Standard Schema V1 declaration. */
61
+ /**
62
+ * Any Standard Schema V1 declaration.
63
+ *
64
+ * @group Core
65
+ */
52
66
  export type AnyStandardSchemaV1 = StandardSchemaV1<any, any>;
53
67
 
54
68
  /**
@@ -65,6 +79,16 @@ export type AnyStandardSchemaV1 = StandardSchemaV1<any, any>;
65
79
  * Table schema defines columns that are required for table rows. For optional
66
80
  * columns, use a schema whose output type includes `null`.
67
81
  *
82
+ * Prefer applying defaults when reading or displaying data. A nullable column
83
+ * can preserve the distinction between "not specified" and an explicitly chosen
84
+ * value. For example, `null` can mean no notification preference, while an
85
+ * explicit false value means notifications were disabled.
86
+ *
87
+ * Use {@link withDefault} only when replacing absence is intentional. Storing
88
+ * defaulted values can add unnecessary data to database rows and erase that
89
+ * distinction. Store a value when it represents a user's decision or another
90
+ * fact your application needs to retain.
91
+ *
68
92
  * ### Example
69
93
  *
70
94
  * ```ts
@@ -110,6 +134,8 @@ export type AnyStandardSchemaV1 = StandardSchemaV1<any, any>;
110
134
  * };
111
135
  * assertTrue(ZodSchema.todo.title.safeParse("Write docs").success);
112
136
  * ```
137
+ *
138
+ * @group Core
113
139
  */
114
140
  export type EvoluSchema = ReadonlyRecord<
115
141
  string,
@@ -117,9 +143,127 @@ export type EvoluSchema = ReadonlyRecord<
117
143
  TableSchema
118
144
  >;
119
145
 
120
- /** A table schema: column names mapped to Standard Schema validators. */
146
+ /**
147
+ * A table schema: column names mapped to Standard Schema validators.
148
+ *
149
+ * @group Core
150
+ */
121
151
  export type TableSchema = ReadonlyRecord<string, AnyStandardSchemaV1>;
122
152
 
153
+ /**
154
+ * Whether a table is local-only: its name starts with an underscore, so its
155
+ * changes are stored without synchronization.
156
+ *
157
+ * @group Core
158
+ */
159
+ export const isLocalOnlyTable = (table: string): boolean =>
160
+ table.startsWith("_");
161
+
162
+ /**
163
+ * Todo ID Type for {@link testEvoluSchema}.
164
+ *
165
+ * @group Testing
166
+ */
167
+ export const TestTodoId = /*#__PURE__*/ id("Todo");
168
+ export type TestTodoId = typeof TestTodoId.Output;
169
+
170
+ /**
171
+ * Deterministic {@link TestTodoId} for tests and examples.
172
+ *
173
+ * @group Testing
174
+ */
175
+ export const testTodoId = /*#__PURE__*/ TestTodoId.orThrow(
176
+ /*#__PURE__*/ createIdFromString("testTodo"),
177
+ );
178
+
179
+ /**
180
+ * Project ID Type for {@link testEvoluSchema}.
181
+ *
182
+ * @group Testing
183
+ */
184
+ export const TestProjectId = /*#__PURE__*/ id("Project");
185
+ export type TestProjectId = typeof TestProjectId.Output;
186
+
187
+ /**
188
+ * Deterministic {@link TestProjectId} for tests and examples.
189
+ *
190
+ * @group Testing
191
+ */
192
+ export const testProjectId = /*#__PURE__*/ TestProjectId.orThrow(
193
+ /*#__PURE__*/ createIdFromString("testProject"),
194
+ );
195
+
196
+ /**
197
+ * Todo and project schema for tests and examples. A todo can belong to a
198
+ * project or have no project. Use an explicit schema when teaching schema
199
+ * definition.
200
+ *
201
+ * ### Example
202
+ *
203
+ * ```ts
204
+ * import {
205
+ * assertOk,
206
+ * testEvoluSchema,
207
+ * testProjectId,
208
+ * testTodoId,
209
+ * } from "@evolu/common";
210
+ *
211
+ * assertOk(testEvoluSchema.todo.id.from(testTodoId), testTodoId);
212
+ * assertOk(
213
+ * testEvoluSchema.todo.projectId.from(testProjectId),
214
+ * testProjectId,
215
+ * );
216
+ * ```
217
+ *
218
+ * @group Testing
219
+ */
220
+ export const testEvoluSchema = {
221
+ todo: {
222
+ id: TestTodoId,
223
+ title: NonEmptyTrimmedString100,
224
+ isCompleted: /*#__PURE__*/ nullOr(SqliteBoolean),
225
+ projectId: /*#__PURE__*/ nullOr(TestProjectId),
226
+ },
227
+ project: {
228
+ id: TestProjectId,
229
+ name: NonEmptyTrimmedString100,
230
+ },
231
+ } as const satisfies EvoluSchema;
232
+
233
+ /**
234
+ * Schema type of {@link testEvoluSchema}.
235
+ *
236
+ * @group Testing
237
+ */
238
+ export type TestEvoluSchema = typeof testEvoluSchema;
239
+
240
+ /**
241
+ * App-owner registry schema with local tables for tests and examples.
242
+ *
243
+ * Stores operational keys separately from optional recovery material. A null
244
+ * secret represents an owner whose recovery material is managed elsewhere or
245
+ * unavailable. Names are optional device-local labels; identicons can be
246
+ * derived from the owner identity without an additional column.
247
+ *
248
+ * This fixture does not define the production registry's persistence contract.
249
+ *
250
+ * @group Testing
251
+ */
252
+ export const testLocalOnlyEvoluSchema = {
253
+ _appOwner: {
254
+ id: OwnerId,
255
+ encryptionKey: OwnerEncryptionKey,
256
+ writeKey: OwnerWriteKey,
257
+ secret: /*#__PURE__*/ nullOr(OwnerSecret),
258
+ name: /*#__PURE__*/ nullOr(NonEmptyTrimmedString100),
259
+ },
260
+ } as const satisfies EvoluSchema;
261
+
262
+ /**
263
+ * Dependency wrapper for {@link SqliteSchema}.
264
+ *
265
+ * @group SQLite
266
+ */
123
267
  export interface SqliteSchemaDep {
124
268
  readonly sqliteSchema: SqliteSchema;
125
269
  }
@@ -136,6 +280,8 @@ export interface SqliteSchemaDep {
136
280
  * 2. The 'id' column output type must extend {@link Id}
137
281
  * 3. Tables cannot use system column names (createdAt, updatedAt, isDeleted)
138
282
  * 4. All column output types must be compatible with SQLite (extend SqliteValue)
283
+ *
284
+ * @group Validation
139
285
  */
140
286
  export type ValidateSchema<S extends EvoluSchema> =
141
287
  ValidateSchemaHasId<S> extends never
@@ -148,10 +294,106 @@ export type ValidateSchema<S extends EvoluSchema> =
148
294
  : ValidateIdColumnType<S>
149
295
  : ValidateSchemaHasId<S>;
150
296
 
297
+ /**
298
+ * Defines SQLite indexes with Kysely's index builder.
299
+ *
300
+ * @group SQLite
301
+ */
151
302
  export type IndexesConfig = (
152
303
  create: (indexName: string) => Kysely.CreateIndexBuilder,
153
304
  ) => ReadonlyArray<Kysely.CreateIndexBuilder<any>>;
154
305
 
306
+ /**
307
+ * Why a message is stored in `evolu_message_quarantine` instead of being
308
+ * applied to its table. Persisted codes: names may change, but numbers must not
309
+ * be reassigned.
310
+ *
311
+ * Quarantine is queryable state, not an error. An application subscribes to a
312
+ * query over `evolu_message_quarantine` to tell the user what is waiting. Each
313
+ * row is one column of a message, so distinct `ownerId` and `timestamp` pairs
314
+ * count messages. `origin` records whether this database stamped the message
315
+ * for a local mutation or received it from sync, see {@link QuarantineOrigin}.
316
+ * `quarantinedAt` is the system time captured for the request that quarantined
317
+ * the row, in milliseconds; it is null for rows written before Evolu recorded
318
+ * it. The clock-drift rules are described in the Timestamp module.
319
+ *
320
+ * ### Example
321
+ *
322
+ * ```ts
323
+ * import {
324
+ * assertType,
325
+ * createQueryBuilder,
326
+ * type Millis,
327
+ * type OwnerIdBytes,
328
+ * type QuarantineOrigin,
329
+ * QuarantineReason,
330
+ * testEvoluSchema,
331
+ * type TimestampBytes,
332
+ * } from "@evolu/common";
333
+ *
334
+ * const createQuery = createQueryBuilder(testEvoluSchema);
335
+ *
336
+ * // Messages waiting in drift quarantine, one row per message.
337
+ * const driftQuarantineQuery = createQuery((db) =>
338
+ * db
339
+ * .selectFrom("evolu_message_quarantine")
340
+ * .select(["ownerId", "timestamp", "origin", "quarantinedAt"])
341
+ * .where("reason", "=", QuarantineReason.TimestampDrift)
342
+ * .distinct(),
343
+ * );
344
+ *
345
+ * assertType<
346
+ * typeof driftQuarantineQuery.Row,
347
+ * {
348
+ * ownerId: OwnerIdBytes;
349
+ * timestamp: TimestampBytes;
350
+ * origin: QuarantineOrigin;
351
+ * quarantinedAt: Millis | null;
352
+ * }
353
+ * >();
354
+ * ```
355
+ *
356
+ * @group Queries
357
+ */
358
+ export const QuarantineReason = {
359
+ /**
360
+ * The message has a table or column the current schema does not define. It is
361
+ * applied automatically once a schema update defines them. A received change
362
+ * to a {@link isLocalOnlyTable | local-only} table is also stored here and is
363
+ * never applied.
364
+ */
365
+ Schema: 0,
366
+ /**
367
+ * The message's timestamp exceeded the drift limit when it was stored. It is
368
+ * applied when the database worker starts, once system time comes within the
369
+ * limit of the timestamp.
370
+ */
371
+ TimestampDrift: 1,
372
+ } as const;
373
+
374
+ export type QuarantineReason =
375
+ (typeof QuarantineReason)[keyof typeof QuarantineReason];
376
+
377
+ /**
378
+ * Whether a quarantined message was stamped by this database for a local
379
+ * mutation or received from sync. Persisted codes: names may change, but
380
+ * numbers must not be reassigned.
381
+ *
382
+ * @group Queries
383
+ */
384
+ export const QuarantineOrigin = {
385
+ LocalMutation: 0,
386
+ ReceivedMessage: 1,
387
+ } as const;
388
+
389
+ export type QuarantineOrigin =
390
+ (typeof QuarantineOrigin)[keyof typeof QuarantineOrigin];
391
+
392
+ /**
393
+ * Typed query factory returned by {@link createQueryBuilder}.
394
+ *
395
+ * @group Queries
396
+ */
155
397
  export type CreateQuery<S extends EvoluSchema> = <R extends Row>(
156
398
  queryCallback: (
157
399
  db: Pick<
@@ -164,6 +406,7 @@ export type CreateQuery<S extends EvoluSchema> = <R extends Row>(
164
406
  } & SystemColumns;
165
407
  } & {
166
408
  readonly evolu_history: {
409
+ readonly ownerId: OwnerIdBytes;
167
410
  readonly timestamp: TimestampBytes;
168
411
  readonly table: keyof S;
169
412
  readonly id: IdBytes;
@@ -171,11 +414,15 @@ export type CreateQuery<S extends EvoluSchema> = <R extends Row>(
171
414
  readonly value: SqliteValue;
172
415
  };
173
416
  readonly evolu_message_quarantine: {
417
+ readonly ownerId: OwnerIdBytes;
174
418
  readonly timestamp: TimestampBytes;
175
419
  readonly table: string;
176
420
  readonly id: IdBytes;
177
421
  readonly column: string;
178
422
  readonly value: SqliteValue;
423
+ readonly reason: QuarantineReason;
424
+ readonly origin: QuarantineOrigin;
425
+ readonly quarantinedAt: Millis | null;
179
426
  };
180
427
  }
181
428
  >,
@@ -193,6 +440,8 @@ export type CreateQuery<S extends EvoluSchema> = <R extends Row>(
193
440
  * - `isDeleted`: Soft delete flag created by Evolu and used by the developer to
194
441
  * mark rows as deleted.
195
442
  * - `ownerId`: Represents ownership and logically partitions the database.
443
+ *
444
+ * @group Core
196
445
  */
197
446
  export const SystemColumns: ObjectType<{
198
447
  readonly createdAt: typeof DateIso;
@@ -207,6 +456,11 @@ export const SystemColumns: ObjectType<{
207
456
  });
208
457
  export interface SystemColumns extends InferType<typeof SystemColumns> {}
209
458
 
459
+ /**
460
+ * Kind of a {@link Mutation}: insert, update, or upsert.
461
+ *
462
+ * @group Mutations
463
+ */
210
464
  export type MutationKind = "insert" | "update" | "upsert";
211
465
 
212
466
  /**
@@ -228,6 +482,8 @@ export type MutationKind = "insert" | "update" | "upsert";
228
482
  * `id` omitted (auto-generated)
229
483
  * - **update**: only `id` required, everything else optional
230
484
  * - **upsert**: like insert but `id` required too
485
+ *
486
+ * @group Mutations
231
487
  */
232
488
  export type Mutation<S extends EvoluSchema, Kind extends MutationKind> = <
233
489
  TableName extends keyof S,
@@ -237,11 +493,26 @@ export type Mutation<S extends EvoluSchema, Kind extends MutationKind> = <
237
493
  options?: MutationOptions,
238
494
  ) => { readonly id: StandardSchemaV1.InferOutput<S[TableName]["id"]> };
239
495
 
496
+ /**
497
+ * Options accepted by every {@link Mutation}.
498
+ *
499
+ * @group Mutations
500
+ */
240
501
  export interface MutationOptions {
241
502
  /**
242
- * Called after the mutation is completed and the local state is updated.
243
- * Useful for triggering side effects (e.g., notifications, UI updates) after
244
- * insert, update, or upsert.
503
+ * Called after the mutation's changes are stored and subscribed queries
504
+ * reflect them. Useful for follow-up work (e.g., notifications, navigation)
505
+ * after insert, update, or upsert. It never runs when the database is
506
+ * unavailable.
507
+ *
508
+ * Stored does not always mean visible. A change quarantined for
509
+ * {@link QuarantineReason.TimestampDrift} is stored in
510
+ * `evolu_message_quarantine` without changing application rows. `onComplete`
511
+ * still fires after storage commits; no drift error is reported. Applications
512
+ * can subscribe to the quarantine table; those query results reflect the
513
+ * change before `onComplete` runs. See the
514
+ * {@link @evolu/common!"local-first/Timestamp" | Timestamp module} for drift
515
+ * and release behavior.
245
516
  */
246
517
  readonly onComplete?: () => void;
247
518
 
@@ -306,6 +577,12 @@ export interface MutationOptions {
306
577
  readonly ownerId?: OwnerId;
307
578
  }
308
579
 
580
+ /**
581
+ * Database change produced by a {@link Mutation}, attributed to the
582
+ * {@link OwnerId} that owns the row.
583
+ *
584
+ * @group Mutations
585
+ */
309
586
  export interface MutationChange extends DbChange {
310
587
  readonly ownerId: OwnerId;
311
588
  }
@@ -313,6 +590,8 @@ export interface MutationChange extends DbChange {
313
590
  /**
314
591
  * Derives the expected values type for a mutation from a table's column schemas
315
592
  * and a {@link MutationKind}.
593
+ *
594
+ * @group Mutations
316
595
  */
317
596
  export type MutationValues<
318
597
  T extends TableSchema,
@@ -328,6 +607,8 @@ export type MutationValues<
328
607
  /**
329
608
  * Insert values: `id` omitted (auto-generated), nullable columns optional,
330
609
  * non-nullable columns required.
610
+ *
611
+ * @group Mutations
331
612
  */
332
613
  export type InsertValues<T extends TableSchema> = Omit<
333
614
  NullableColumnsToOptional<T>,
@@ -337,6 +618,8 @@ export type InsertValues<T extends TableSchema> = Omit<
337
618
  /**
338
619
  * Update values: `id` required, all other columns optional. Includes
339
620
  * `isDeleted` for soft deletes.
621
+ *
622
+ * @group Mutations
340
623
  */
341
624
  export type UpdateValues<T extends TableSchema> = {
342
625
  readonly id: StandardSchemaV1.InferOutput<T["id"]>;
@@ -349,12 +632,19 @@ export type UpdateValues<T extends TableSchema> = {
349
632
  /**
350
633
  * Upsert values: `id` required, nullable columns optional, non-nullable columns
351
634
  * required. Includes `isDeleted` for soft deletes.
635
+ *
636
+ * @group Mutations
352
637
  */
353
638
  export type UpsertValues<T extends TableSchema> =
354
639
  NullableColumnsToOptional<T> & {
355
640
  readonly isDeleted?: SqliteBoolean;
356
641
  };
357
642
 
643
+ /**
644
+ * Requires an `id` column in every table.
645
+ *
646
+ * @group Validation
647
+ */
358
648
  export type ValidateSchemaHasId<S extends EvoluSchema> =
359
649
  keyof S extends infer TableName
360
650
  ? TableName extends keyof S
@@ -364,6 +654,11 @@ export type ValidateSchemaHasId<S extends EvoluSchema> =
364
654
  : never
365
655
  : never;
366
656
 
657
+ /**
658
+ * Requires every `id` column output type to extend {@link Id}.
659
+ *
660
+ * @group Validation
661
+ */
367
662
  export type ValidateIdColumnType<S extends EvoluSchema> =
368
663
  keyof S extends infer TableName
369
664
  ? TableName extends keyof S
@@ -375,6 +670,11 @@ export type ValidateIdColumnType<S extends EvoluSchema> =
375
670
  : never
376
671
  : never;
377
672
 
673
+ /**
674
+ * Rejects tables that define system column names.
675
+ *
676
+ * @group Validation
677
+ */
378
678
  export type ValidateNoSystemColumns<S extends EvoluSchema> =
379
679
  keyof S extends infer TableName
380
680
  ? TableName extends keyof S
@@ -389,6 +689,11 @@ export type ValidateNoSystemColumns<S extends EvoluSchema> =
389
689
  : never
390
690
  : never;
391
691
 
692
+ /**
693
+ * Requires every column output type to be compatible with SQLite.
694
+ *
695
+ * @group Validation
696
+ */
392
697
  export type ValidateColumnTypes<S extends EvoluSchema> =
393
698
  keyof S extends infer TableName
394
699
  ? TableName extends keyof S
@@ -403,36 +708,69 @@ export type ValidateColumnTypes<S extends EvoluSchema> =
403
708
  : never
404
709
  : never;
405
710
 
406
- /** Schema validation error that shows clear, readable messages */
711
+ /**
712
+ * Schema validation error that shows clear, readable messages
713
+ *
714
+ * @group Validation
715
+ */
407
716
  export type SchemaValidationError<Message extends string> = CompileTimeError<
408
717
  "Schema",
409
718
  Message
410
719
  >;
411
720
 
412
- /** Makes columns whose output type includes `null` optional. */
721
+ /**
722
+ * Makes columns whose output type includes `null` optional.
723
+ *
724
+ * @group Mutations
725
+ */
413
726
  export type NullableColumnsToOptional<T extends TableSchema> = {
414
727
  readonly [K in RequiredColumnKeys<T>]: StandardSchemaV1.InferOutput<T[K]>;
415
728
  } & {
416
729
  readonly [K in OptionalColumnKeys<T>]?: StandardSchemaV1.InferOutput<T[K]>;
417
730
  };
418
731
 
732
+ /**
733
+ * Column names whose output type excludes `null`.
734
+ *
735
+ * @group Mutations
736
+ */
419
737
  export type RequiredColumnKeys<T extends TableSchema> = {
420
738
  [K in keyof T]: null extends StandardSchemaV1.InferOutput<T[K]> ? never : K;
421
739
  }[keyof T];
422
740
 
741
+ /**
742
+ * Column names whose output type includes `null`.
743
+ *
744
+ * @group Mutations
745
+ */
423
746
  export type OptionalColumnKeys<T extends TableSchema> = {
424
747
  [K in keyof T]: null extends StandardSchemaV1.InferOutput<T[K]> ? K : never;
425
748
  }[keyof T];
426
749
 
750
+ /**
751
+ * Names of {@link SystemColumns}.
752
+ *
753
+ * @group Core
754
+ */
427
755
  export const systemColumns: ReadonlySet<string> = /*#__PURE__*/ new Set(
428
756
  /*#__PURE__*/ Object.keys(SystemColumns.props),
429
757
  );
430
758
 
759
+ /**
760
+ * Names of {@link SystemColumns} together with `id`.
761
+ *
762
+ * @group Core
763
+ */
431
764
  export const systemColumnsWithId: ReadonlyArray<string> = [
432
765
  ...systemColumns,
433
766
  "id",
434
767
  ];
435
768
 
769
+ /**
770
+ * Derives {@link SqliteSchema} tables and indexes from an {@link EvoluSchema}.
771
+ *
772
+ * @group SQLite
773
+ */
436
774
  export const evoluSchemaToSqliteSchema = <S extends EvoluSchema>(
437
775
  schema: ValidateSchema<S> extends never ? S : ValidateSchema<S>,
438
776
  indexesConfig?: IndexesConfig,
@@ -469,24 +807,14 @@ export const evoluSchemaToSqliteSchema = <S extends EvoluSchema>(
469
807
  * import {
470
808
  * assertType,
471
809
  * createQueryBuilder,
472
- * id,
810
+ * testEvoluSchema,
811
+ * type TestTodoId,
473
812
  * NonEmptyTrimmedString100,
474
- * nullOr,
475
813
  * SqliteBoolean,
476
814
  * } from "@evolu/common";
477
815
  *
478
- * const TodoId = id("Todo");
479
- * type TodoId = typeof TodoId.Output;
480
- * const Schema = {
481
- * todo: {
482
- * id: TodoId,
483
- * title: NonEmptyTrimmedString100,
484
- * isCompleted: nullOr(SqliteBoolean),
485
- * },
486
- * };
487
- *
488
816
  * // Create one typed builder per schema and reuse it for every query.
489
- * const createQuery = createQueryBuilder(Schema);
817
+ * const createQuery = createQueryBuilder(testEvoluSchema);
490
818
  * const todosQuery = createQuery((db) =>
491
819
  * db.selectFrom("todo").select(["id", "title", "isCompleted"]),
492
820
  * );
@@ -494,12 +822,14 @@ export const evoluSchemaToSqliteSchema = <S extends EvoluSchema>(
494
822
  * assertType<
495
823
  * typeof todosQuery.Row,
496
824
  * {
497
- * id: TodoId;
825
+ * id: TestTodoId;
498
826
  * title: NonEmptyTrimmedString100 | null;
499
827
  * isCompleted: SqliteBoolean | null;
500
828
  * }
501
829
  * >();
502
830
  * ```
831
+ *
832
+ * @group Queries
503
833
  */
504
834
  export const createQueryBuilder = <S extends EvoluSchema>(
505
835
  _schema: S,
@@ -519,6 +849,12 @@ export const createQueryBuilder = <S extends EvoluSchema>(
519
849
  return createQuery;
520
850
  };
521
851
 
852
+ /**
853
+ * Creates missing tables, columns, and indexes, and drops indexes that the new
854
+ * schema no longer defines.
855
+ *
856
+ * @group SQLite
857
+ */
522
858
  export const ensureSqliteSchema =
523
859
  (deps: SqliteDep) =>
524
860
  (newSchema: SqliteSchema, currentSchema?: SqliteSchema): void => {
@@ -570,10 +906,24 @@ export const ensureSqliteSchema =
570
906
  }
571
907
  };
572
908
 
909
+ /**
910
+ * Reads the current application {@link SqliteSchema}, excluding Evolu's internal
911
+ * indexes.
912
+ *
913
+ * @group SQLite
914
+ */
573
915
  export const getEvoluSqliteSchema = (deps: SqliteDep) => (): SqliteSchema =>
574
916
  getSqliteSchema(deps)({ excludeIndexNamePrefix: "evolu_" });
575
917
 
576
- // https://kysely.dev/docs/recipes/splitting-query-building-and-execution
918
+ /**
919
+ * Kysely instance that only compiles queries to SQL. It never executes them;
920
+ * Evolu runs the compiled SQL itself.
921
+ *
922
+ * See [Splitting query building and
923
+ * execution](https://kysely.dev/docs/recipes/splitting-query-building-and-execution).
924
+ *
925
+ * @group Queries
926
+ */
577
927
  export const kysely = /*#__PURE__*/ new Kysely.Kysely({
578
928
  dialect: {
579
929
  createAdapter: () => new Kysely.SqliteAdapter(),