@evolu/common 7.4.1 → 8.0.0-next.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 (250) hide show
  1. package/README.md +4 -61
  2. package/dist/src/Array.d.ts +343 -102
  3. package/dist/src/Array.d.ts.map +1 -1
  4. package/dist/src/Array.js +181 -85
  5. package/dist/src/Assert.d.ts +57 -11
  6. package/dist/src/Assert.d.ts.map +1 -1
  7. package/dist/src/Assert.js +47 -11
  8. package/dist/src/BigInt.d.ts +6 -1
  9. package/dist/src/BigInt.d.ts.map +1 -1
  10. package/dist/src/BigInt.js +5 -0
  11. package/dist/src/Brand.d.ts +40 -12
  12. package/dist/src/Brand.d.ts.map +1 -1
  13. package/dist/src/Brand.js +5 -0
  14. package/dist/src/Buffer.d.ts +6 -1
  15. package/dist/src/Buffer.d.ts.map +1 -1
  16. package/dist/src/Buffer.js +7 -2
  17. package/dist/src/Cache.d.ts +10 -2
  18. package/dist/src/Cache.d.ts.map +1 -1
  19. package/dist/src/Cache.js +6 -0
  20. package/dist/src/Callbacks.d.ts +10 -7
  21. package/dist/src/Callbacks.d.ts.map +1 -1
  22. package/dist/src/Callbacks.js +23 -13
  23. package/dist/src/Console.d.ts +361 -69
  24. package/dist/src/Console.d.ts.map +1 -1
  25. package/dist/src/Console.js +217 -117
  26. package/dist/src/Crypto.d.ts +70 -21
  27. package/dist/src/Crypto.d.ts.map +1 -1
  28. package/dist/src/Crypto.js +72 -27
  29. package/dist/src/Eq.d.ts +22 -2
  30. package/dist/src/Eq.d.ts.map +1 -1
  31. package/dist/src/Eq.js +21 -1
  32. package/dist/src/Error.d.ts +23 -12
  33. package/dist/src/Error.d.ts.map +1 -1
  34. package/dist/src/Error.js +27 -11
  35. package/dist/src/Function.d.ts +128 -56
  36. package/dist/src/Function.d.ts.map +1 -1
  37. package/dist/src/Function.js +118 -14
  38. package/dist/src/Identicon.d.ts +5 -0
  39. package/dist/src/Identicon.d.ts.map +1 -1
  40. package/dist/src/Identicon.js +6 -1
  41. package/dist/src/Lookup.d.ts +162 -0
  42. package/dist/src/Lookup.d.ts.map +1 -0
  43. package/dist/src/Lookup.js +200 -0
  44. package/dist/src/Microtask.d.ts +21 -0
  45. package/dist/src/Microtask.d.ts.map +1 -0
  46. package/dist/src/Microtask.js +37 -0
  47. package/dist/src/Number.d.ts +18 -4
  48. package/dist/src/Number.d.ts.map +1 -1
  49. package/dist/src/Number.js +23 -1
  50. package/dist/src/Object.d.ts +110 -5
  51. package/dist/src/Object.d.ts.map +1 -1
  52. package/dist/src/Object.js +108 -5
  53. package/dist/src/Option.d.ts +58 -0
  54. package/dist/src/Option.d.ts.map +1 -0
  55. package/dist/src/Option.js +43 -0
  56. package/dist/src/Order.d.ts +5 -0
  57. package/dist/src/Order.d.ts.map +1 -1
  58. package/dist/src/Order.js +8 -3
  59. package/dist/src/Platform.d.ts +36 -2
  60. package/dist/src/Platform.d.ts.map +1 -1
  61. package/dist/src/Platform.js +10 -6
  62. package/dist/src/Polyfills.d.ts +29 -0
  63. package/dist/src/Polyfills.d.ts.map +1 -0
  64. package/dist/src/Polyfills.js +329 -0
  65. package/dist/src/Random.d.ts +18 -7
  66. package/dist/src/Random.d.ts.map +1 -1
  67. package/dist/src/Random.js +9 -7
  68. package/dist/src/Redacted.d.ts +7 -4
  69. package/dist/src/Redacted.d.ts.map +1 -1
  70. package/dist/src/Redacted.js +5 -0
  71. package/dist/src/Ref.d.ts +31 -16
  72. package/dist/src/Ref.d.ts.map +1 -1
  73. package/dist/src/Ref.js +35 -7
  74. package/dist/src/RefCount.d.ts +62 -0
  75. package/dist/src/RefCount.d.ts.map +1 -0
  76. package/dist/src/RefCount.js +83 -0
  77. package/dist/src/Relation.d.ts +84 -29
  78. package/dist/src/Relation.d.ts.map +1 -1
  79. package/dist/src/Relation.js +83 -105
  80. package/dist/src/Resource.d.ts +263 -0
  81. package/dist/src/Resource.d.ts.map +1 -0
  82. package/dist/src/Resource.js +389 -0
  83. package/dist/src/Result.d.ts +390 -374
  84. package/dist/src/Result.d.ts.map +1 -1
  85. package/dist/src/Result.js +142 -70
  86. package/dist/src/Schedule.d.ts +953 -0
  87. package/dist/src/Schedule.d.ts.map +1 -0
  88. package/dist/src/Schedule.js +1199 -0
  89. package/dist/src/Set.d.ts +181 -0
  90. package/dist/src/Set.d.ts.map +1 -0
  91. package/dist/src/Set.js +137 -0
  92. package/dist/src/Skiplist.d.ts +6 -1
  93. package/dist/src/Skiplist.d.ts.map +1 -1
  94. package/dist/src/Skiplist.js +5 -0
  95. package/dist/src/Sqlite.d.ts +160 -60
  96. package/dist/src/Sqlite.d.ts.map +1 -1
  97. package/dist/src/Sqlite.js +290 -190
  98. package/dist/src/Store.d.ts +36 -28
  99. package/dist/src/Store.d.ts.map +1 -1
  100. package/dist/src/Store.js +55 -15
  101. package/dist/src/String.d.ts +5 -0
  102. package/dist/src/String.d.ts.map +1 -1
  103. package/dist/src/String.js +5 -0
  104. package/dist/src/Task.d.ts +2274 -423
  105. package/dist/src/Task.d.ts.map +1 -1
  106. package/dist/src/Task.js +1499 -348
  107. package/dist/src/Test.d.ts +150 -0
  108. package/dist/src/Test.d.ts.map +1 -0
  109. package/dist/src/Test.js +97 -0
  110. package/dist/src/Time.d.ts +202 -48
  111. package/dist/src/Time.d.ts.map +1 -1
  112. package/dist/src/Time.js +199 -88
  113. package/dist/src/Tracer.d.ts +48 -0
  114. package/dist/src/Tracer.d.ts.map +1 -0
  115. package/dist/src/Tracer.js +6 -0
  116. package/dist/src/Type.d.ts +587 -209
  117. package/dist/src/Type.d.ts.map +1 -1
  118. package/dist/src/Type.js +370 -240
  119. package/dist/src/Types.d.ts +160 -6
  120. package/dist/src/Types.d.ts.map +1 -1
  121. package/dist/src/Types.js +22 -2
  122. package/dist/src/WebSocket.d.ts +130 -58
  123. package/dist/src/WebSocket.d.ts.map +1 -1
  124. package/dist/src/WebSocket.js +274 -113
  125. package/dist/src/Worker.d.ts +245 -60
  126. package/dist/src/Worker.d.ts.map +1 -1
  127. package/dist/src/Worker.js +220 -64
  128. package/dist/src/index.d.ts +25 -3
  129. package/dist/src/index.d.ts.map +1 -1
  130. package/dist/src/index.js +19 -3
  131. package/dist/src/local-first/Db.d.ts +24 -213
  132. package/dist/src/local-first/Db.d.ts.map +1 -1
  133. package/dist/src/local-first/Db.js +621 -293
  134. package/dist/src/local-first/Error.d.ts +12 -0
  135. package/dist/src/local-first/Error.d.ts.map +1 -0
  136. package/dist/src/local-first/Error.js +6 -0
  137. package/dist/src/local-first/Evolu.d.ts +330 -285
  138. package/dist/src/local-first/Evolu.d.ts.map +1 -1
  139. package/dist/src/local-first/Evolu.js +472 -402
  140. package/dist/src/local-first/LocalAuth.d.ts +10 -10
  141. package/dist/src/local-first/LocalAuth.d.ts.map +1 -1
  142. package/dist/src/local-first/LocalAuth.js +6 -1
  143. package/dist/src/local-first/Owner.d.ts +70 -27
  144. package/dist/src/local-first/Owner.d.ts.map +1 -1
  145. package/dist/src/local-first/Owner.js +27 -14
  146. package/dist/src/local-first/Protocol.d.ts +58 -50
  147. package/dist/src/local-first/Protocol.d.ts.map +1 -1
  148. package/dist/src/local-first/Protocol.js +253 -155
  149. package/dist/src/local-first/Query.d.ts +133 -43
  150. package/dist/src/local-first/Query.d.ts.map +1 -1
  151. package/dist/src/local-first/Query.js +139 -90
  152. package/dist/src/local-first/Relay.d.ts +34 -49
  153. package/dist/src/local-first/Relay.d.ts.map +1 -1
  154. package/dist/src/local-first/Relay.js +59 -177
  155. package/dist/src/local-first/Schema.d.ts +139 -144
  156. package/dist/src/local-first/Schema.d.ts.map +1 -1
  157. package/dist/src/local-first/Schema.js +78 -163
  158. package/dist/src/local-first/Shared.d.ts +125 -0
  159. package/dist/src/local-first/Shared.d.ts.map +1 -0
  160. package/dist/src/local-first/Shared.js +569 -0
  161. package/dist/src/local-first/Storage.d.ts +54 -58
  162. package/dist/src/local-first/Storage.d.ts.map +1 -1
  163. package/dist/src/local-first/Storage.js +127 -179
  164. package/dist/src/local-first/Timestamp.d.ts +28 -35
  165. package/dist/src/local-first/Timestamp.d.ts.map +1 -1
  166. package/dist/src/local-first/Timestamp.js +24 -25
  167. package/dist/src/local-first/index.d.ts +2 -15
  168. package/dist/src/local-first/index.d.ts.map +1 -1
  169. package/dist/src/local-first/index.js +2 -15
  170. package/package.json +37 -24
  171. package/src/Array.ts +467 -106
  172. package/src/Assert.ts +87 -12
  173. package/src/BigInt.ts +7 -1
  174. package/src/Brand.ts +41 -12
  175. package/src/Buffer.ts +10 -4
  176. package/src/Cache.ts +11 -2
  177. package/src/Callbacks.ts +33 -23
  178. package/src/Console.ts +567 -178
  179. package/src/Crypto.ts +111 -62
  180. package/src/Eq.ts +30 -3
  181. package/src/Error.ts +50 -34
  182. package/src/Function.ts +140 -68
  183. package/src/Identicon.ts +7 -1
  184. package/src/Lookup.ts +429 -0
  185. package/src/Microtask.ts +58 -0
  186. package/src/Number.ts +40 -7
  187. package/src/Object.ts +155 -16
  188. package/src/Option.ts +74 -0
  189. package/src/Order.ts +11 -3
  190. package/src/Platform.ts +43 -7
  191. package/src/Polyfills.ts +520 -0
  192. package/src/Random.ts +25 -11
  193. package/src/Redacted.ts +8 -4
  194. package/src/Ref.ts +72 -21
  195. package/src/RefCount.ts +170 -0
  196. package/src/Relation.ts +188 -136
  197. package/src/Resource.ts +864 -0
  198. package/src/Result.ts +548 -381
  199. package/src/Schedule.ts +1471 -0
  200. package/src/Set.ts +247 -0
  201. package/src/Skiplist.ts +7 -1
  202. package/src/Sqlite.ts +409 -304
  203. package/src/Store.ts +94 -48
  204. package/src/String.ts +6 -0
  205. package/src/Task.ts +3696 -740
  206. package/src/Test.ts +202 -0
  207. package/src/Time.ts +357 -147
  208. package/src/Tracer.ts +54 -0
  209. package/src/Type.ts +866 -430
  210. package/src/Types.ts +202 -7
  211. package/src/WebSocket.ts +404 -167
  212. package/src/Worker.ts +527 -147
  213. package/src/index.ts +74 -3
  214. package/src/local-first/Db.ts +867 -597
  215. package/src/local-first/Error.ts +17 -0
  216. package/src/local-first/Evolu.ts +884 -824
  217. package/src/local-first/LocalAuth.ts +10 -10
  218. package/src/local-first/Owner.ts +94 -42
  219. package/src/local-first/Protocol.ts +441 -307
  220. package/src/local-first/Query.ts +243 -194
  221. package/src/local-first/Relay.ts +119 -273
  222. package/src/local-first/Schema.ts +284 -394
  223. package/src/local-first/Shared.ts +932 -0
  224. package/src/local-first/Storage.ts +211 -283
  225. package/src/local-first/Timestamp.ts +38 -45
  226. package/src/local-first/index.ts +2 -16
  227. package/dist/src/Instances.d.ts +0 -34
  228. package/dist/src/Instances.d.ts.map +0 -1
  229. package/dist/src/Instances.js +0 -44
  230. package/dist/src/Resources.d.ts +0 -118
  231. package/dist/src/Resources.d.ts.map +0 -1
  232. package/dist/src/Resources.js +0 -197
  233. package/dist/src/local-first/Platform.d.ts +0 -25
  234. package/dist/src/local-first/Platform.d.ts.map +0 -1
  235. package/dist/src/local-first/Platform.js +0 -1
  236. package/dist/src/local-first/Public.d.ts +0 -22
  237. package/dist/src/local-first/Public.d.ts.map +0 -1
  238. package/dist/src/local-first/Public.js +0 -15
  239. package/dist/src/local-first/PublicKysely.d.ts +0 -148
  240. package/dist/src/local-first/PublicKysely.d.ts.map +0 -1
  241. package/dist/src/local-first/PublicKysely.js +0 -184
  242. package/dist/src/local-first/Sync.d.ts +0 -112
  243. package/dist/src/local-first/Sync.d.ts.map +0 -1
  244. package/dist/src/local-first/Sync.js +0 -526
  245. package/src/Instances.ts +0 -92
  246. package/src/Resources.ts +0 -367
  247. package/src/local-first/Platform.ts +0 -27
  248. package/src/local-first/Public.ts +0 -42
  249. package/src/local-first/PublicKysely.ts +0 -239
  250. package/src/local-first/Sync.ts +0 -949
package/dist/src/Type.js CHANGED
@@ -1,9 +1,14 @@
1
+ /**
2
+ * Runtime type validation, parsing, and branded types.
3
+ *
4
+ * @module
5
+ */
1
6
  import { utf8ToBytes } from "@noble/ciphers/utils.js";
2
7
  import { sha256 } from "@noble/hashes/sha2.js";
3
8
  import * as bip39 from "@scure/bip39";
4
9
  import { wordlist } from "@scure/bip39/wordlists/english.js";
5
- import { pack } from "msgpackr";
6
- import { isPlainObject } from "./Object.js";
10
+ import { exhaustiveCheck } from "./Function.js";
11
+ import { isFunction, isPlainObject } from "./Object.js";
7
12
  import { hasNodeBuffer } from "./Platform.js";
8
13
  import { err, getOrNull, getOrThrow, ok, trySync } from "./Result.js";
9
14
  import { safelyStringifyUnknownValue } from "./String.js";
@@ -11,7 +16,7 @@ const EvoluTypeSymbol = Symbol("evolu.Type");
11
16
  /**
12
17
  * Checks if the given value is an {@link Type}.
13
18
  *
14
- * @category Utilities
19
+ * @group Utilities
15
20
  */
16
21
  export const isType = (value) => typeof value === "object" && value !== null && EvoluTypeSymbol in value;
17
22
  const createType = (name, definition) => ({
@@ -36,9 +41,8 @@ const createType = (name, definition) => ({
36
41
  if (result.ok) {
37
42
  return { value: result.value };
38
43
  }
39
- cachedStandardSchemaFormatTypeError ??= createFormatTypeError();
40
44
  return {
41
- issues: typeErrorToStandardSchemaIssues(result.error, cachedStandardSchemaFormatTypeError),
45
+ issues: typeErrorToStandardSchemaIssues(result.error),
42
46
  };
43
47
  },
44
48
  types: {
@@ -61,7 +65,7 @@ const createType = (name, definition) => ({
61
65
  * );
62
66
  * ```
63
67
  *
64
- * @category Utilities
68
+ * @group Utilities
65
69
  */
66
70
  export const createTypeErrorFormatter = (format) => (error) => format({ ...error, value: safelyStringifyUnknownValue(error.value) });
67
71
  /**
@@ -85,7 +89,7 @@ export const createTypeErrorFormatter = (format) => (error) => format({ ...error
85
89
  * );
86
90
  * ```
87
91
  *
88
- * @category Base Factories
92
+ * @group Base factories
89
93
  */
90
94
  export const base = (name, fromUnknown) => createType(name, {
91
95
  fromUnknown,
@@ -104,52 +108,66 @@ export const base = (name, fromUnknown) => createType(name, {
104
108
  * createBaseTypeErrorFormatter<StringError>();
105
109
  * ```
106
110
  *
107
- * @category Utilities
111
+ * @group Utilities
108
112
  */
109
113
  export const createBaseTypeErrorFormatter = () => createTypeErrorFormatter((error) => `A value ${error.value} is not a ${error.type.toLowerCase()}.`);
110
- /** @category Base Types */
111
- export const Unknown = base("Unknown", ok);
114
+ /** @group Base Types */
115
+ export const Unknown = /*#__PURE__*/ base("Unknown", ok);
112
116
  /**
113
- * @category Base Types
114
- * @category String
117
+ * @group Base Types
118
+ * @group String
115
119
  */
116
- export const String = base("String", (value) => typeof value === "string"
120
+ export const String = /*#__PURE__*/ base("String", (value) => typeof value === "string"
117
121
  ? ok(value)
118
122
  : err({ type: "String", value }));
119
- export const formatStringError = createBaseTypeErrorFormatter();
120
- /** @category Base Types */
121
- export const Number = base("Number", (value) => typeof value === "number"
123
+ export const formatStringError =
124
+ /*#__PURE__*/ createBaseTypeErrorFormatter();
125
+ /** @group Base Types */
126
+ export const Number = /*#__PURE__*/ base("Number", (value) => typeof value === "number"
122
127
  ? ok(value)
123
128
  : err({ type: "Number", value }));
124
- export const formatNumberError = createBaseTypeErrorFormatter();
125
- /** @category Base Types */
126
- export const BigInt = base("BigInt", (value) => typeof value === "bigint"
129
+ export const formatNumberError =
130
+ /*#__PURE__*/ createBaseTypeErrorFormatter();
131
+ /** @group Base Types */
132
+ export const BigInt = /*#__PURE__*/ base("BigInt", (value) => typeof value === "bigint"
127
133
  ? ok(value)
128
134
  : err({ type: "BigInt", value }));
129
- export const formatBigIntError = createBaseTypeErrorFormatter();
130
- /** @category Base Types */
131
- export const Boolean = base("Boolean", (value) => typeof value === "boolean"
135
+ export const formatBigIntError =
136
+ /*#__PURE__*/ createBaseTypeErrorFormatter();
137
+ /** @group Base Types */
138
+ export const Boolean = /*#__PURE__*/ base("Boolean", (value) => typeof value === "boolean"
132
139
  ? ok(value)
133
140
  : err({ type: "Boolean", value }));
134
- export const formatBooleanError = createBaseTypeErrorFormatter();
135
- /** @category Base Types */
136
- export const Undefined = base("Undefined", (value) => value === undefined
141
+ export const formatBooleanError =
142
+ /*#__PURE__*/ createBaseTypeErrorFormatter();
143
+ /** @group Base Types */
144
+ export const Undefined = /*#__PURE__*/ base("Undefined", (value) => value === undefined
137
145
  ? ok(value)
138
146
  : err({ type: "Undefined", value }));
139
- export const formatUndefinedError = createBaseTypeErrorFormatter();
140
- /** @category Base Types */
141
- export const Null = base("Null", (value) => value === null ? ok(value) : err({ type: "Null", value }));
142
- export const formatNullError = createBaseTypeErrorFormatter();
143
- /** @category Base Types */
144
- export const Function = base("Function", (value) => typeof value === "function"
147
+ export const formatUndefinedError =
148
+ /*#__PURE__*/ createBaseTypeErrorFormatter();
149
+ /** @group Base Types */
150
+ export const Null = /*#__PURE__*/ base("Null", (value) => value === null ? ok(value) : err({ type: "Null", value }));
151
+ export const formatNullError =
152
+ /*#__PURE__*/ createBaseTypeErrorFormatter();
153
+ /** @group Base Types */
154
+ export const Function = /*#__PURE__*/ base("Function", (value) => isFunction(value)
145
155
  ? ok(value)
146
156
  : err({ type: "Function", value }));
147
- export const formatFunctionError = createBaseTypeErrorFormatter();
148
- /** @category Base Types */
149
- export const Uint8Array = base("Uint8Array", (value) => value instanceof globalThis.Uint8Array
157
+ export const formatFunctionError =
158
+ /*#__PURE__*/ createBaseTypeErrorFormatter();
159
+ /** @group Base Types */
160
+ export const Uint8Array = /*#__PURE__*/ base("Uint8Array", (value) => Object.prototype.toString.call(value) === "[object Uint8Array]"
150
161
  ? ok(value)
151
162
  : err({ type: "Uint8Array", value }));
152
- export const formatUint8ArrayError = createBaseTypeErrorFormatter();
163
+ export const formatUint8ArrayError =
164
+ /*#__PURE__*/ createBaseTypeErrorFormatter();
165
+ /** @group Base Types */
166
+ export const ArrayBuffer = /*#__PURE__*/ base("ArrayBuffer", (value) => Object.prototype.toString.call(value) === "[object ArrayBuffer]"
167
+ ? ok(value)
168
+ : err({ type: "ArrayBuffer", value }));
169
+ export const formatArrayBufferError =
170
+ /*#__PURE__*/ createBaseTypeErrorFormatter();
153
171
  /**
154
172
  * `instanceof` {@link Type}.
155
173
  *
@@ -168,7 +186,7 @@ export const formatUint8ArrayError = createBaseTypeErrorFormatter();
168
186
  * const error = UserInstance.from({}); // err
169
187
  * ```
170
188
  *
171
- * @category Base Factories
189
+ * @group Base factories
172
190
  */
173
191
  export const instanceOf = (ctor) => ({
174
192
  ...base("InstanceOf", (value) => value instanceof ctor
@@ -176,13 +194,14 @@ export const instanceOf = (ctor) => ({
176
194
  : err({ type: "InstanceOf", value, ctor: ctor.name })),
177
195
  ctor,
178
196
  });
179
- export const formatInstanceOfError = createTypeErrorFormatter((error) => `The value ${error.value} is not an instance of ${error.ctor}.`);
197
+ export const formatInstanceOfError =
198
+ /*#__PURE__*/ createTypeErrorFormatter((error) => `The value ${error.value} is not an instance of ${error.ctor}.`);
180
199
  /**
181
200
  * JavaScript Date.
182
201
  *
183
- * @category Base Types
202
+ * @group Base Types
184
203
  */
185
- export const Date = instanceOf(globalThis.Date);
204
+ export const Date = /*#__PURE__*/ instanceOf(globalThis.Date);
186
205
  /**
187
206
  * Validates that an unknown value is an Evolu {@link Type} (i.e., satisfies
188
207
  * `AnyType`).
@@ -195,13 +214,14 @@ export const Date = instanceOf(globalThis.Date);
195
214
  * ```
196
215
  */
197
216
  // TODO: Rename to TypeInstance or something like that.
198
- export const EvoluType = base("EvoluType", (value) => isType(value)
217
+ export const EvoluType = /*#__PURE__*/ base("EvoluType", (value) => isType(value)
199
218
  ? ok(value)
200
219
  : err({
201
220
  type: "EvoluType",
202
221
  value,
203
222
  }));
204
- export const formatIsTypeError = createTypeErrorFormatter((error) => `Value ${error.value} is not a valid Evolu Type.`);
223
+ export const formatIsTypeError =
224
+ /*#__PURE__*/ createTypeErrorFormatter((error) => `Value ${error.value} is not a valid Evolu Type.`);
205
225
  export function brand(name, parent, refine) {
206
226
  const fromUnknown = refine
207
227
  ? (value) => {
@@ -232,12 +252,13 @@ export function brand(name, parent, refine) {
232
252
  /**
233
253
  * A three-letter ISO 4217 currency code (e.g., USD, EUR).
234
254
  *
235
- * @category String
255
+ * @group String
236
256
  */
237
- export const CurrencyCode = brand("CurrencyCode", String, (value) => /^[A-Z]{3}$/.test(value)
257
+ export const CurrencyCode = /*#__PURE__*/ brand("CurrencyCode", String, (value) => /^[A-Z]{3}$/.test(value)
238
258
  ? ok(value)
239
259
  : err({ type: "CurrencyCode", value }));
240
- export const formatCurrencyCodeError = createTypeErrorFormatter((error) => `Invalid currency code: ${error.value}.`);
260
+ export const formatCurrencyCodeError =
261
+ /*#__PURE__*/ createTypeErrorFormatter((error) => `Invalid currency code: ${error.value}.`);
241
262
  /**
242
263
  * ISO 8601 date-time string.
243
264
  *
@@ -257,9 +278,9 @@ export const formatCurrencyCodeError = createTypeErrorFormatter((error) => `Inva
257
278
  * const error = DateIso.from("10000-01-01T00:00:00.000Z"); // err
258
279
  * ```
259
280
  *
260
- * @category String
281
+ * @group String
261
282
  */
262
- export const DateIso = brand("DateIso", String, (value) => {
283
+ export const DateIso = /*#__PURE__*/ brand("DateIso", String, (value) => {
263
284
  if (value.length !== 24) {
264
285
  return err({ type: "DateIso", value });
265
286
  }
@@ -274,7 +295,8 @@ export const DateIso = brand("DateIso", String, (value) => {
274
295
  }
275
296
  return ok(value);
276
297
  });
277
- export const formatDateIsoError = createTypeErrorFormatter((error) => `The value ${error.value} is not a valid ISO 8601 date string.`);
298
+ export const formatDateIsoError =
299
+ /*#__PURE__*/ createTypeErrorFormatter((error) => `The value ${error.value} is not a valid ISO 8601 date string.`);
278
300
  export const dateToDateIso = (value) => DateIso.fromParent(value.toISOString());
279
301
  export const dateIsoToDate = (value) => new globalThis.Date(value);
280
302
  /**
@@ -291,25 +313,28 @@ export const dateIsoToDate = (value) => new globalThis.Date(value);
291
313
  * type TrimmedNonEmptyString = typeof TrimmedNonEmptyString.Type;
292
314
  * ```
293
315
  *
294
- * @category String
316
+ * @group String
295
317
  */
296
318
  export const trimmed = (parent) => brand("Trimmed", parent, (value) => value.trim().length === value.length
297
319
  ? ok(value)
298
320
  : err({ type: "Trimmed", value }));
299
- export const formatTrimmedError = createTypeErrorFormatter((error) => `The value ${error.value} must be trimmed.`);
321
+ export const formatTrimmedError =
322
+ /*#__PURE__*/ createTypeErrorFormatter((error) => `The value ${error.value} must be trimmed.`);
300
323
  /**
301
324
  * Trimmed string
302
325
  *
303
326
  * - Use `TrimmedString.is` to check if an unknown value is trimmed.
304
327
  * - Use `TrimmedString.from` to check if a string is trimmed.
305
328
  *
306
- * @category String
329
+ * @group String
307
330
  */
308
- export const TrimmedString = trimmed(String);
331
+ export const TrimmedString = /*#__PURE__*/ trimmed(String);
309
332
  export const trim = (value) => value.trim();
310
333
  /**
311
334
  * Minimum length.
312
335
  *
336
+ * Use numeric literal, not expression. See {@link BrandFactory}.
337
+ *
313
338
  * ### Example
314
339
  *
315
340
  * ```ts
@@ -317,14 +342,17 @@ export const trim = (value) => value.trim();
317
342
  * const NonEmptyString = minLength(1)(String);
318
343
  * ```
319
344
  *
320
- * @category String
321
- * @category Array
345
+ * @group String
346
+ * @group Array
322
347
  */
323
348
  export const minLength = (min) => (parent) => brand(`MinLength${min}`, parent, (value) => value.length >= min ? ok(value) : err({ type: "MinLength", value, min }));
324
- export const formatMinLengthError = createTypeErrorFormatter((error) => `The value ${error.value} does not meet the minimum length of ${error.min}.`);
349
+ export const formatMinLengthError =
350
+ /*#__PURE__*/ createTypeErrorFormatter((error) => `The value ${error.value} does not meet the minimum length of ${error.min}.`);
325
351
  /**
326
352
  * Maximum length.
327
353
  *
354
+ * Use numeric literal, not expression. See {@link BrandFactory}.
355
+ *
328
356
  * ### Example
329
357
  *
330
358
  * ```ts
@@ -332,14 +360,17 @@ export const formatMinLengthError = createTypeErrorFormatter((error) => `The val
332
360
  * const String100 = maxLength(100)(String);
333
361
  * ```
334
362
  *
335
- * @category String
336
- * @category Array
363
+ * @group String
364
+ * @group Array
337
365
  */
338
366
  export const maxLength = (max) => (parent) => brand(`MaxLength${max}`, parent, (value) => value.length <= max ? ok(value) : err({ type: "MaxLength", value, max }));
339
- export const formatMaxLengthError = createTypeErrorFormatter((error) => `The value ${error.value} exceeds the maximum length of ${error.max}.`);
367
+ export const formatMaxLengthError =
368
+ /*#__PURE__*/ createTypeErrorFormatter((error) => `The value ${error.value} exceeds the maximum length of ${error.max}.`);
340
369
  /**
341
370
  * Exact length.
342
371
  *
372
+ * Use numeric literal, not expression. See {@link BrandFactory}.
373
+ *
343
374
  * ### Example
344
375
  *
345
376
  * ```ts
@@ -347,33 +378,36 @@ export const formatMaxLengthError = createTypeErrorFormatter((error) => `The val
347
378
  * const Length1String = length(1)(String);
348
379
  * ```
349
380
  *
350
- * @category String
351
- * @category Array
381
+ * @group String
382
+ * @group Array
352
383
  */
353
384
  export const length = (exact) => (parent) => brand(`Length${exact}`, parent, (value) => value.length === exact
354
385
  ? ok(value)
355
386
  : err({ type: "Length", value, exact }));
356
- export const formatLengthError = createTypeErrorFormatter((error) => `The value ${error.value} does not have the required length of ${error.exact}.`);
357
- /** @category String */
358
- export const NonEmptyString = minLength(1)(String);
359
- /** @category String */
360
- export const String100 = maxLength(100)(String);
361
- /** @category String */
362
- export const String1000 = maxLength(1000)(String);
363
- /** @category String */
364
- export const NonEmptyString100 = minLength(1)(String100);
365
- /** @category String */
366
- export const NonEmptyString1000 = minLength(1)(String1000);
367
- /** @category String */
368
- export const NonEmptyTrimmedString = minLength(1)(TrimmedString);
369
- /** @category String */
370
- export const TrimmedString100 = maxLength(100)(TrimmedString);
371
- /** @category String */
372
- export const TrimmedString1000 = maxLength(1000)(TrimmedString);
373
- /** @category String */
374
- export const NonEmptyTrimmedString100 = minLength(1)(TrimmedString100);
375
- /** @category String */
376
- export const NonEmptyTrimmedString1000 = minLength(1)(TrimmedString1000);
387
+ export const formatLengthError =
388
+ /*#__PURE__*/ createTypeErrorFormatter((error) => `The value ${error.value} does not have the required length of ${error.exact}.`);
389
+ /** @group String */
390
+ export const NonEmptyString = /*#__PURE__*/ minLength(1)(String);
391
+ /** @group String */
392
+ export const String100 = /*#__PURE__*/ maxLength(100)(String);
393
+ /** @group String */
394
+ export const String1000 = /*#__PURE__*/ maxLength(1000)(String);
395
+ /** @group String */
396
+ export const NonEmptyString100 = /*#__PURE__*/ minLength(1)(String100);
397
+ /** @group String */
398
+ export const NonEmptyString1000 = /*#__PURE__*/ minLength(1)(String1000);
399
+ /** @group String */
400
+ export const NonEmptyTrimmedString = /*#__PURE__*/ minLength(1)(TrimmedString);
401
+ /** @group String */
402
+ export const TrimmedString100 = /*#__PURE__*/ maxLength(100)(TrimmedString);
403
+ /** @group String */
404
+ export const TrimmedString1000 = /*#__PURE__*/ maxLength(1000)(TrimmedString);
405
+ /** @group String */
406
+ export const NonEmptyTrimmedString100 =
407
+ /*#__PURE__*/ minLength(1)(TrimmedString100);
408
+ /** @group String */
409
+ export const NonEmptyTrimmedString1000 =
410
+ /*#__PURE__*/ minLength(1)(TrimmedString1000);
377
411
  /**
378
412
  * The mnemonic, also known as a "seed phrase," is a set of 12 words in a
379
413
  * specific order chosen from a predefined list (BIP39). It provides a
@@ -381,12 +415,13 @@ export const NonEmptyTrimmedString1000 = minLength(1)(TrimmedString1000);
381
415
  * safely on the user's device using cryptographically secure random number
382
416
  * generation, ensuring it remains private and unique.
383
417
  *
384
- * @category String
418
+ * @group String
385
419
  */
386
- export const Mnemonic = brand("Mnemonic", NonEmptyTrimmedString, (value) => bip39.validateMnemonic(value, wordlist)
420
+ export const Mnemonic = /*#__PURE__*/ brand("Mnemonic", NonEmptyTrimmedString, (value) => bip39.validateMnemonic(value, wordlist)
387
421
  ? ok(value)
388
422
  : err({ type: "Mnemonic", value }));
389
- export const formatMnemonicError = createTypeErrorFormatter((error) => `Invalid BIP39 mnemonic: ${error.value}.`);
423
+ export const formatMnemonicError =
424
+ /*#__PURE__*/ createTypeErrorFormatter((error) => `Invalid BIP39 mnemonic: ${error.value}.`);
390
425
  /**
391
426
  * String matching a regular expression.
392
427
  *
@@ -396,7 +431,7 @@ export const formatMnemonicError = createTypeErrorFormatter((error) => `Invalid
396
431
  * const Alphanumeric = regex("Alphanumeric", /^[a-z0-9]+$/i)(String);
397
432
  * ```
398
433
  *
399
- * @category String
434
+ * @group String
400
435
  */
401
436
  export const regex = (name, pattern) => {
402
437
  // Clone the regex to avoid shared state.
@@ -410,7 +445,8 @@ export const regex = (name, pattern) => {
410
445
  : err({ type: "Regex", name, value, pattern });
411
446
  });
412
447
  };
413
- export const formatRegexError = createTypeErrorFormatter((error) => `The value ${error.value} does not match the pattern for ${error.name}: ${error.pattern}.`);
448
+ export const formatRegexError =
449
+ /*#__PURE__*/ createTypeErrorFormatter((error) => `The value ${error.value} does not match the pattern for ${error.name}: ${error.pattern}.`);
414
450
  /**
415
451
  * URL-safe string.
416
452
  *
@@ -436,18 +472,18 @@ export const formatRegexError = createTypeErrorFormatter((error) => `The value $
436
472
  * }
437
473
  * ```
438
474
  *
439
- * @category String
475
+ * @group String
440
476
  */
441
- export const UrlSafeString = regex("UrlSafeString", /^[A-Za-z0-9_-]+$/)(String);
477
+ export const UrlSafeString = /*#__PURE__*/ regex("UrlSafeString", /^[A-Za-z0-9_-]+$/)(String);
442
478
  /**
443
479
  * Base64Url without padding.
444
480
  *
445
481
  * Encode with {@link uint8ArrayToBase64Url}, decode with
446
482
  * {@link base64UrlToUint8Array}.
447
483
  *
448
- * @category String
484
+ * @group String
449
485
  */
450
- export const Base64Url = brand("Base64Url", String, (value) => {
486
+ export const Base64Url = /*#__PURE__*/ brand("Base64Url", String, (value) => {
451
487
  // Round-trip validation ensures consistency across different base64url
452
488
  // implementations (Node.js Buffer, native browser API, manual fallback).
453
489
  // Only strings that decode and encode identically are accepted.
@@ -462,7 +498,8 @@ export const Base64Url = brand("Base64Url", String, (value) => {
462
498
  ? ok(value)
463
499
  : err({ type: "Base64Url", value });
464
500
  });
465
- export const formatBase64UrlError = createTypeErrorFormatter((error) => `The value ${error.value} is not a valid Base64Url string.`);
501
+ export const formatBase64UrlError =
502
+ /*#__PURE__*/ createTypeErrorFormatter((error) => `The value ${error.value} is not a valid Base64Url string.`);
466
503
  const base64UrlOptions = { alphabet: "base64url", omitPadding: true };
467
504
  /** Encodes a Uint8Array to a {@link Base64Url} string. */
468
505
  export const uint8ArrayToBase64Url = hasNodeBuffer
@@ -500,29 +537,30 @@ export const base64UrlToUint8Array = hasNodeBuffer
500
537
  return globalThis.Uint8Array.from(binaryString, (c) => c.charCodeAt(0));
501
538
  };
502
539
  /**
503
- * Simple alphanumeric string for naming in file systems, URLs, and identifiers.
540
+ * Alphanumeric string for naming in file systems, URLs, and identifiers.
504
541
  *
505
542
  * Uses the same safe alphabet as {@link UrlSafeString} (letters, digits, `-`,
506
- * `_`). See `UrlSafeString` for details.
543
+ * `_`).
507
544
  *
508
545
  * The string must be between 1 and 64 characters.
509
546
  *
510
547
  * ### Example
511
548
  *
512
549
  * ```ts
513
- * const result = SimpleName.from("data-report-123");
550
+ * const result = Name.from("data-report-123");
514
551
  * if (result.ok) {
515
- * console.log("Valid SimpleName string:", result.value);
552
+ * console.log("Valid Name string:", result.value);
516
553
  * } else {
517
- * console.error("Invalid SimpleName string:", result.error);
554
+ * console.error("Invalid Name string:", result.error);
518
555
  * }
519
556
  * ```
520
557
  *
521
- * @category String
558
+ * @group String
522
559
  */
523
- export const SimpleName = brand("SimpleName", UrlSafeString, (value) => value.length >= 1 && value.length <= 64
560
+ export const Name = /*#__PURE__*/ brand("Name", UrlSafeString, (value) => value.length >= 1 && value.length <= 64
524
561
  ? ok(value)
525
- : err({ type: "SimpleName", value }));
562
+ : err({ type: "Name", value }));
563
+ export const testName = /*#__PURE__*/ Name.orThrow("Name");
526
564
  /**
527
565
  * Trimmed string between 8 and 64 characters, branded as `SimplePassword`.
528
566
  *
@@ -545,9 +583,10 @@ export const SimpleName = brand("SimpleName", UrlSafeString, (value) => value.le
545
583
  * // |> brand("SimplePassword", %)
546
584
  * ```
547
585
  *
548
- * @category String
586
+ * @group String
549
587
  */
550
- export const SimplePassword = brand("SimplePassword", minLength(8)(maxLength(64)(TrimmedString)));
588
+ export const SimplePassword = /*#__PURE__*/ brand("SimplePassword",
589
+ /*#__PURE__*/ minLength(8)(/*#__PURE__*/ maxLength(64)(TrimmedString)));
551
590
  export const formatSimplePasswordError = (formatTypeError) => createTypeErrorFormatter((error) => `Invalid password: ${formatTypeError(error.parentError)}`);
552
591
  /**
553
592
  * Evolu Id: 16 bytes encoded as a 22‑character Base64Url string.
@@ -565,19 +604,19 @@ export const formatSimplePasswordError = (formatTypeError) => createTypeErrorFor
565
604
  * copied (logs, URLs, exports); only use it when you explicitly want insertion
566
605
  * locality for very large write‑heavy tables and accept timestamp exposure.
567
606
  *
568
- * ### Future
607
+ * ## Future
569
608
  *
570
609
  * A possible hybrid masked‑time approach (`timestamp ^ H(cluster_id, timestamp
571
610
  *
572
611
  * > > N)`) could provide locality without exposing raw creation time. See
573
612
  * > > https://brooker.co.za/blog/2025/10/22/uuidv7.html
574
613
  *
575
- * @category String
614
+ * @group String
576
615
  */
577
- export const Id = brand("Id", String, (value) => value.length === 22 && Base64Url.fromParent(value).ok
616
+ export const Id = /*#__PURE__*/ brand("Id", String, (value) => value.length === 22 && Base64Url.fromParent(value).ok
578
617
  ? ok(value)
579
618
  : err({ type: "Id", value }));
580
- export const formatIdError = createTypeErrorFormatter((error) => `The value ${error.value} is not a valid Id.`);
619
+ export const formatIdError = /*#__PURE__*/ createTypeErrorFormatter((error) => `The value ${error.value} is not a valid Id.`);
581
620
  /**
582
621
  * Creates a random {@link Id}. This is the recommended default.
583
622
  *
@@ -626,7 +665,7 @@ export const createId = (deps) => {
626
665
  * external string from the generated {@link Id}. If you need to preserve the
627
666
  * original external ID, store it in a separate column.
628
667
  *
629
- * @category String
668
+ * @group String
630
669
  */
631
670
  export const createIdFromString = (value) => {
632
671
  const hash = sha256(utf8ToBytes(value));
@@ -661,7 +700,7 @@ export const createIdAsUuidv7 = (deps) => {
661
700
  id[5] = globalThis.Number(timestamp & 0xffn);
662
701
  id[6] = (id[6] & 0x0f) | 0x70;
663
702
  id[8] = (id[8] & 0x3f) | 0x80;
664
- return id;
703
+ return uint8ArrayToBase64Url(id);
665
704
  };
666
705
  /**
667
706
  * Creates a branded {@link Id} Type for a table's primary key.
@@ -676,7 +715,7 @@ export const createIdAsUuidv7 = (deps) => {
676
715
  * type TodoId = typeof TodoId.Type;
677
716
  * ```
678
717
  *
679
- * @category String
718
+ * @group String
680
719
  */
681
720
  export const id = (table) => {
682
721
  const fromUnknown = (value) => {
@@ -697,9 +736,11 @@ export const id = (table) => {
697
736
  table,
698
737
  };
699
738
  };
700
- export const formatTableIdError = createTypeErrorFormatter((error) => `Invalid Id for table ${error.table}: ${error.value}.`);
739
+ export const formatTableIdError =
740
+ /*#__PURE__*/ createTypeErrorFormatter((error) => `Invalid Id for table ${error.table}: ${error.value}.`);
701
741
  /** Binary representation of an {@link Id}. */
702
- export const IdBytes = brand("IdBytes", length(16)(Uint8Array));
742
+ export const IdBytes = /*#__PURE__*/ brand("IdBytes",
743
+ /*#__PURE__*/ length(16)(Uint8Array));
703
744
  export const idBytesTypeValueLength = 16;
704
745
  export const idToIdBytes = (id) =>
705
746
  // Id is Base64Url (validated by Id.from), cast is safe
@@ -719,10 +760,11 @@ uint8ArrayToBase64Url(idBytes);
719
760
  * const errorResult = PositiveNumber.from(-5); // err
720
761
  * ```
721
762
  *
722
- * @category Number
763
+ * @group Number
723
764
  */
724
765
  export const positive = (parent) => brand("Positive", parent, (value) => value > 0 ? ok(value) : err({ type: "Positive", value }));
725
- export const formatPositiveError = createTypeErrorFormatter((error) => `The value ${error.value} must be positive (> 0).`);
766
+ export const formatPositiveError =
767
+ /*#__PURE__*/ createTypeErrorFormatter((error) => `The value ${error.value} must be positive (> 0).`);
726
768
  /**
727
769
  * Negative number (< 0).
728
770
  *
@@ -732,10 +774,11 @@ export const formatPositiveError = createTypeErrorFormatter((error) => `The valu
732
774
  * const NegativeNumber = negative(Number);
733
775
  * ```
734
776
  *
735
- * @category Number
777
+ * @group Number
736
778
  */
737
779
  export const negative = (parent) => brand("Negative", parent, (value) => value < 0 ? ok(value) : err({ type: "Negative", value }));
738
- export const formatNegativeError = createTypeErrorFormatter((error) => `The value ${error.value} must be negative (< 0).`);
780
+ export const formatNegativeError =
781
+ /*#__PURE__*/ createTypeErrorFormatter((error) => `The value ${error.value} must be negative (< 0).`);
739
782
  /**
740
783
  * Non-positive number (≤ 0).
741
784
  *
@@ -745,12 +788,13 @@ export const formatNegativeError = createTypeErrorFormatter((error) => `The valu
745
788
  * const NonPositiveNumber = nonPositive(Number);
746
789
  * ```
747
790
  *
748
- * @category Number
791
+ * @group Number
749
792
  */
750
793
  export const nonPositive = (parent) => brand("NonPositive", parent, (value) => value <= 0
751
794
  ? ok(value)
752
795
  : err({ type: "NonPositive", value }));
753
- export const formatNonPositiveError = createTypeErrorFormatter((error) => `The value ${error.value} must be non-positive (≤ 0).`);
796
+ export const formatNonPositiveError =
797
+ /*#__PURE__*/ createTypeErrorFormatter((error) => `The value ${error.value} must be non-positive (≤ 0).`);
754
798
  /**
755
799
  * Non-negative number (≥ 0).
756
800
  *
@@ -760,133 +804,156 @@ export const formatNonPositiveError = createTypeErrorFormatter((error) => `The v
760
804
  * const NonNegativeNumber = nonNegative(Number);
761
805
  * ```
762
806
  *
763
- * @category Number
807
+ * @group Number
764
808
  */
765
809
  export const nonNegative = (parent) => brand("NonNegative", parent, (value) => value >= 0
766
810
  ? ok(value)
767
811
  : err({ type: "NonNegative", value }));
768
- export const formatNonNegativeError = createTypeErrorFormatter((error) => `The value ${error.value} must be non-negative (≥ 0).`);
812
+ export const formatNonNegativeError =
813
+ /*#__PURE__*/ createTypeErrorFormatter((error) => `The value ${error.value} must be non-negative (≥ 0).`);
769
814
  /**
770
815
  * Non-negative number (≥ 0).
771
816
  *
772
- * @category Number
817
+ * @group Number
773
818
  */
774
- export const NonNegativeNumber = nonNegative(Number);
819
+ export const NonNegativeNumber = /*#__PURE__*/ nonNegative(Number);
775
820
  /**
776
821
  * Positive number (> 0).
777
822
  *
778
- * @category Number
823
+ * @group Number
779
824
  */
780
- export const PositiveNumber = positive(NonNegativeNumber);
825
+ export const PositiveNumber = /*#__PURE__*/ positive(NonNegativeNumber);
781
826
  /**
782
827
  * Non-positive number (≤ 0).
783
828
  *
784
- * @category Number
829
+ * @group Number
785
830
  */
786
- export const NonPositiveNumber = nonPositive(Number);
831
+ export const NonPositiveNumber = /*#__PURE__*/ nonPositive(Number);
787
832
  /**
788
833
  * Negative number (< 0).
789
834
  *
790
- * @category Number
835
+ * @group Number
791
836
  */
792
- export const NegativeNumber = negative(NonPositiveNumber);
837
+ export const NegativeNumber = /*#__PURE__*/ negative(NonPositiveNumber);
793
838
  /**
794
839
  * Integer within the safe range of JavaScript numbers.
795
840
  *
796
841
  * ### Example
797
842
  *
798
843
  * ```ts
799
- * const Int = int(Number);
844
+ * const Int = safeInt(Number);
800
845
  * ```
801
846
  *
802
- * @category Number
847
+ * Note: This helper was previously named `int`. A Next.js regression produced
848
+ * runtime `int is not defined`, so we keep the implementation under the
849
+ * `safeInt` alias.
850
+ *
851
+ * @group Number
803
852
  */
804
- export const int = (parent) => brand("Int", parent, (value) => globalThis.Number.isSafeInteger(value)
853
+ const safeInt = (parent) => brand("Int", parent, (value) => globalThis.Number.isSafeInteger(value)
805
854
  ? ok(value)
806
855
  : err({ type: "Int", value }));
807
- export const formatIntError = createTypeErrorFormatter((error) => `The value ${error.value} must be an integer.`);
856
+ export const formatIntError = /*#__PURE__*/ createTypeErrorFormatter((error) => `The value ${error.value} must be an integer.`);
808
857
  /**
809
858
  * Integer within the safe range of JavaScript numbers.
810
859
  *
811
- * @category Number
860
+ * @group Number
812
861
  */
813
- export const Int = int(Number);
862
+ export const Int = /*#__PURE__*/ safeInt(Number);
814
863
  /**
815
864
  * Non-negative integer (≥ 0).
816
865
  *
817
- * @category Number
866
+ * @group Number
818
867
  */
819
- export const NonNegativeInt = nonNegative(Int);
868
+ export const NonNegativeInt = /*#__PURE__*/ nonNegative(Int);
869
+ /** Minimum {@link NonNegativeInt} value (0). */
870
+ export const zeroNonNegativeInt = /*#__PURE__*/ NonNegativeInt.orThrow(0);
820
871
  /**
821
872
  * Positive integer (> 0).
822
873
  *
823
- * @category Number
874
+ * @group Number
824
875
  */
825
- export const PositiveInt = positive(NonNegativeInt);
826
- /** Maximum safe positive integer value for practically infinite operations. */
827
- export const maxPositiveInt = PositiveInt.orThrow(globalThis.Number.MAX_SAFE_INTEGER);
876
+ export const PositiveInt = /*#__PURE__*/ positive(NonNegativeInt);
877
+ /** {@link PositiveInt} value 1. */
878
+ export const onePositiveInt = /*#__PURE__*/ PositiveInt.orThrow(1);
879
+ /** Maximum {@link PositiveInt} value (MAX_SAFE_INTEGER). */
880
+ export const maxPositiveInt = /*#__PURE__*/ PositiveInt.orThrow(globalThis.Number.MAX_SAFE_INTEGER);
828
881
  /**
829
882
  * Non-positive integer (≤ 0).
830
883
  *
831
- * @category Number
884
+ * @group Number
832
885
  */
833
- export const NonPositiveInt = nonPositive(Int);
886
+ export const NonPositiveInt = /*#__PURE__*/ nonPositive(Int);
834
887
  /**
835
888
  * Negative integer (< 0).
836
889
  *
837
- * @category Number
890
+ * @group Number
838
891
  */
839
- export const NegativeInt = negative(NonPositiveInt);
892
+ export const NegativeInt = /*#__PURE__*/ negative(NonPositiveInt);
840
893
  /**
841
894
  * Number greater than a specified value.
842
895
  *
843
- * @category Number
896
+ * Use numeric literal, not expression. See {@link BrandFactory}.
897
+ *
898
+ * @group Number
844
899
  */
845
900
  export const greaterThan = (min) => (parent) => brand(`GreaterThan${min}`, parent, (value) => value > min ? ok(value) : err({ type: "GreaterThan", value, min }));
846
- export const formatGreaterThanError = createTypeErrorFormatter((error) => `The value ${error.value} is not > ${error.min}.`);
901
+ export const formatGreaterThanError =
902
+ /*#__PURE__*/ createTypeErrorFormatter((error) => `The value ${error.value} is not > ${error.min}.`);
847
903
  /**
848
904
  * Number less than a specified value.
849
905
  *
850
- * @category Number
906
+ * Use numeric literal, not expression. See {@link BrandFactory}.
907
+ *
908
+ * @group Number
851
909
  */
852
910
  export const lessThan = (max) => (parent) => brand(`LessThan${max}`, parent, (value) => value < max ? ok(value) : err({ type: "LessThan", value, max }));
853
- export const formatLessThanError = createTypeErrorFormatter((error) => `The value ${error.value} is not < ${error.max}.`);
911
+ export const formatLessThanError =
912
+ /*#__PURE__*/ createTypeErrorFormatter((error) => `The value ${error.value} is not < ${error.max}.`);
854
913
  /**
855
914
  * Number ≥ a specified value.
856
915
  *
857
- * @category Number
916
+ * Use numeric literal, not expression. See {@link BrandFactory}.
917
+ *
918
+ * @group Number
858
919
  */
859
920
  export const greaterThanOrEqualTo = (min) => (parent) => brand(`GreaterThanOrEqualTo${min}`, parent, (value) => value >= min
860
921
  ? ok(value)
861
922
  : err({ type: "GreaterThanOrEqualTo", value, min }));
862
- export const formatGreaterThanOrEqualToError = createTypeErrorFormatter((error) => `The value ${error.value} is not >= ${error.min}.`);
923
+ export const formatGreaterThanOrEqualToError =
924
+ /*#__PURE__*/ createTypeErrorFormatter((error) => `The value ${error.value} is not >= ${error.min}.`);
863
925
  /**
864
926
  * Number ≤ a specified value.
865
927
  *
866
- * @category Number
928
+ * Use numeric literal, not expression. See {@link BrandFactory}.
929
+ *
930
+ * @group Number
867
931
  */
868
932
  export const lessThanOrEqualTo = (max) => (parent) => brand(`LessThanOrEqualTo${max}`, parent, (value) => value <= max ? ok(value) : err({ type: "LessThanOrEqualTo", value, max }));
869
- export const formatLessThanOrEqualToError = createTypeErrorFormatter((error) => `The value ${error.value} is not <= ${error.max}.`);
933
+ export const formatLessThanOrEqualToError =
934
+ /*#__PURE__*/ createTypeErrorFormatter((error) => `The value ${error.value} is not <= ${error.max}.`);
870
935
  /**
871
936
  * Number that is not NaN.
872
937
  *
873
- * @category Number
938
+ * @group Number
874
939
  */
875
940
  export const nonNaN = (parent) => brand("NonNaN", parent, (value) => !globalThis.Number.isNaN(value)
876
941
  ? ok(value)
877
942
  : err({ type: "NonNaN", value }));
878
- export const formatNonNaNError = createTypeErrorFormatter(() => `The value must not be NaN.`);
879
- /** @category Number */
880
- export const NonNaNNumber = nonNaN(Number);
943
+ export const formatNonNaNError =
944
+ /*#__PURE__*/ createTypeErrorFormatter(() => `The value must not be NaN.`);
945
+ /** @group Number */
946
+ export const NonNaNNumber = /*#__PURE__*/ nonNaN(Number);
881
947
  /**
882
948
  * Finite number.
883
949
  *
884
- * @category Number
950
+ * @group Number
885
951
  */
886
952
  export const finite = (parent) => brand("Finite", parent, (value) => globalThis.Number.isFinite(value)
887
953
  ? ok(value)
888
954
  : err({ type: "Finite", value }));
889
- export const formatFiniteError = createTypeErrorFormatter((error) => `The value ${error.value} must be finite.`);
955
+ export const formatFiniteError =
956
+ /*#__PURE__*/ createTypeErrorFormatter((error) => `The value ${error.value} must be finite.`);
890
957
  /**
891
958
  * Finite number.
892
959
  *
@@ -898,21 +965,26 @@ export const formatFiniteError = createTypeErrorFormatter((error) => `The value
898
965
  * finite (e.g., `Infinity`, `-Infinity`, or `NaN`). Using `FiniteNumber` helps
899
966
  * prevent these unexpected behaviors when working with JSON serialization.
900
967
  *
901
- * @category Number
968
+ * @group Number
902
969
  */
903
- export const FiniteNumber = finite(Number);
970
+ export const FiniteNumber = /*#__PURE__*/ finite(Number);
904
971
  /**
905
972
  * Number that is a multiple of a divisor.
906
973
  *
907
- * @category Number
974
+ * Use numeric literal, not expression. See {@link BrandFactory}.
975
+ *
976
+ * @group Number
908
977
  */
909
978
  export const multipleOf = (divisor) => (parent) => brand(`MultipleOf${divisor}`, parent, (value) => value % divisor === 0
910
979
  ? ok(value)
911
980
  : err({ type: "MultipleOf", value, divisor }));
912
- export const formatMultipleOfError = createTypeErrorFormatter((error) => `The value ${error.value} is not a multiple of ${error.divisor}.`);
981
+ export const formatMultipleOfError =
982
+ /*#__PURE__*/ createTypeErrorFormatter((error) => `The value ${error.value} is not a multiple of ${error.divisor}.`);
913
983
  /**
914
984
  * Number within a range, inclusive.
915
985
  *
986
+ * Use numeric literal, not expression. See {@link BrandFactory}.
987
+ *
916
988
  * ### Example
917
989
  *
918
990
  * ```ts
@@ -921,12 +993,13 @@ export const formatMultipleOfError = createTypeErrorFormatter((error) => `The va
921
993
  * const errorResult = Between1And10.from(11); // err
922
994
  * ```
923
995
  *
924
- * @category Number
996
+ * @group Number
925
997
  */
926
998
  export const between = (min, max) => (parent) => brand(`Between${min}-${max}`, parent, (value) => value >= min && value <= max
927
999
  ? ok(value)
928
1000
  : err({ type: "Between", value, min, max }));
929
- export const formatBetweenError = createTypeErrorFormatter((error) => `The value ${error.value} is not between ${error.min} and ${error.max}, inclusive.`);
1001
+ export const formatBetweenError =
1002
+ /*#__PURE__*/ createTypeErrorFormatter((error) => `The value ${error.value} is not between ${error.min} and ${error.max}, inclusive.`);
930
1003
  /**
931
1004
  * Literal {@link Type}.
932
1005
  *
@@ -942,7 +1015,7 @@ export const formatBetweenError = createTypeErrorFormatter((error) => `The value
942
1015
  *
943
1016
  * TODO: Add JsonValue
944
1017
  *
945
- * @category Base Factories
1018
+ * @group Base factories
946
1019
  */
947
1020
  export const literal = (expected) => {
948
1021
  const fromUnknown = (value) => value === expected
@@ -956,11 +1029,12 @@ export const literal = (expected) => {
956
1029
  expected,
957
1030
  };
958
1031
  };
959
- export const formatLiteralError = createTypeErrorFormatter((error) => `The value ${error.value} is not strictly equal to the expected literal: ${globalThis.String(error.expected)}.`);
1032
+ export const formatLiteralError =
1033
+ /*#__PURE__*/ createTypeErrorFormatter((error) => `The value ${error.value} is not strictly equal to the expected literal: ${globalThis.String(error.expected)}.`);
960
1034
  /**
961
1035
  * Array of a specific {@link Type}.
962
1036
  *
963
- * Usage:
1037
+ * ### Example
964
1038
  *
965
1039
  * ```ts
966
1040
  * const NumberArray = array(Number);
@@ -969,8 +1043,8 @@ export const formatLiteralError = createTypeErrorFormatter((error) => `The value
969
1043
  * const result2 = NumberArray.from(["a", "b"]); // err(...)
970
1044
  * ```
971
1045
  *
972
- * @category Base Factories
973
- * @category Array
1046
+ * @group Base factories
1047
+ * @group Array
974
1048
  */
975
1049
  export const array = (element) => {
976
1050
  const fromUnknown = (value) => {
@@ -1043,7 +1117,7 @@ export const formatArrayError = (formatTypeError) => createTypeErrorFormatter((e
1043
1117
  * const result2 = NumberSet.from(new Set(["a", "b"])); // err(...)
1044
1118
  * ```
1045
1119
  *
1046
- * @category Base Factories
1120
+ * @group Base factories
1047
1121
  */
1048
1122
  export const set = (element) => {
1049
1123
  const fromUnknown = (value) => {
@@ -1128,8 +1202,8 @@ export const formatSetError = (formatTypeError) => createTypeErrorFormatter((err
1128
1202
  * StringToNumberRecord.from({ a: "x", b: 2 });
1129
1203
  * ```
1130
1204
  *
1131
- * @category Base Factories
1132
- * @category Object
1205
+ * @group Base factories
1206
+ * @group Object
1133
1207
  */
1134
1208
  export const record = (keyType, valueType) => {
1135
1209
  const fromUnknown = (value) => {
@@ -1375,6 +1449,9 @@ export const formatObjectWithRecordError = (formatTypeError) => createTypeErrorF
1375
1449
  return `Invalid value at index key ${error.reason.key}: ${formatTypeError(error.reason.error)}`;
1376
1450
  }
1377
1451
  });
1452
+ export function typed(tag, props) {
1453
+ return object({ type: literal(tag), ...props });
1454
+ }
1378
1455
  export function union(...args) {
1379
1456
  /**
1380
1457
  * Good First Issue:
@@ -1420,6 +1497,75 @@ export const formatUnionError = (formatTypeError) => createTypeErrorFormatter((e
1420
1497
  return `Value ${error.value} does not match any member of the union.\nErrors:\n${formattedErrors}`;
1421
1498
  });
1422
1499
  export const isUnionType = (t) => t.name === "Union" && Array.isArray(t.members);
1500
+ /**
1501
+ * Creates a {@link Type} for {@link Result} values.
1502
+ *
1503
+ * Use for validating serialized Results from storage, APIs, or message passing.
1504
+ *
1505
+ * ### Example
1506
+ *
1507
+ * ```ts
1508
+ * const SyncResponse = result(
1509
+ * object({ timestamp: NonNegativeInt }),
1510
+ * typed("SyncError", { message: String }),
1511
+ * );
1512
+ *
1513
+ * // Validate response from worker or API
1514
+ * const validated = SyncResponse.from(JSON.parse(message));
1515
+ * if (!validated.ok) return validated; // validation error
1516
+ * // validated.value is Result<{ timestamp }, SyncError>
1517
+ * ```
1518
+ *
1519
+ * @group Composite factories
1520
+ */
1521
+ export const result = (okType, errType) => union(object({ ok: literal(true), value: okType }), object({ ok: literal(false), error: errType }));
1522
+ /**
1523
+ * A {@link result} type for `Result<unknown, unknown>`.
1524
+ *
1525
+ * Useful for serializing Results where the value and error types are unknown.
1526
+ *
1527
+ * @group Composite factories
1528
+ */
1529
+ export const UnknownResult = /*#__PURE__*/ result(Unknown, Unknown);
1530
+ /**
1531
+ * Creates a {@link Type} for {@link NextResult} with three outcomes.
1532
+ *
1533
+ * Validates results where the producer responds with:
1534
+ *
1535
+ * - `Ok<A>` — produced a value
1536
+ * - `Err<Done<D>>` — completed normally with a done value
1537
+ * - `Err<E>` — failed with an error
1538
+ *
1539
+ * ### Example
1540
+ *
1541
+ * ```ts
1542
+ * const MyNextResult = nextResult(Item, MyError, Summary);
1543
+ *
1544
+ * const validated = MyNextResult.fromUnknown(data);
1545
+ * if (!validated.ok) return validated;
1546
+ *
1547
+ * const result = validated.value;
1548
+ * if (result.ok) {
1549
+ * console.log(result.value);
1550
+ * } else if (result.error.type === "Done") {
1551
+ * console.log("Done:", result.error.done);
1552
+ * } else {
1553
+ * console.error(result.error);
1554
+ * }
1555
+ * ```
1556
+ *
1557
+ * @group Composite factories
1558
+ */
1559
+ export const nextResult = (valueType, errorType, doneType) => result(valueType, union(errorType, typed("Done", { done: doneType })));
1560
+ /**
1561
+ * A {@link nextResult} type for `NextResult<unknown, unknown, unknown>`.
1562
+ *
1563
+ * Useful for checking if a value is a {@link NextResult} via
1564
+ * `UnknownNextResult.is(value)`.
1565
+ *
1566
+ * @group Composite factories
1567
+ */
1568
+ export const UnknownNextResult = /*#__PURE__*/ nextResult(Unknown, Unknown, Unknown);
1423
1569
  /**
1424
1570
  * Recursive {@link Type}.
1425
1571
  *
@@ -1453,7 +1599,7 @@ export const isUnionType = (t) => t.name === "Union" && Array.isArray(t.members)
1453
1599
  * );
1454
1600
  * ```
1455
1601
  *
1456
- * @category Base Factories
1602
+ * @group Base factories
1457
1603
  */
1458
1604
  export const recursive = (create) => {
1459
1605
  let type;
@@ -1494,7 +1640,7 @@ export const recursive = (create) => {
1494
1640
  * NullOrString.from(42); // err(...)
1495
1641
  * ```
1496
1642
  *
1497
- * @category Base Factories
1643
+ * @group Base factories
1498
1644
  */
1499
1645
  export const nullOr = (type) => union(Null, type);
1500
1646
  /**
@@ -1509,7 +1655,7 @@ export const nullOr = (type) => union(Null, type);
1509
1655
  * UndefinedOrString.from(42); // err(...)
1510
1656
  * ```
1511
1657
  *
1512
- * @category Base Factories
1658
+ * @group Base factories
1513
1659
  */
1514
1660
  export const undefinedOr = (type) => union(Undefined, type);
1515
1661
  /**
@@ -1528,7 +1674,7 @@ export const undefinedOr = (type) => union(Undefined, type);
1528
1674
  * NullishOrString.from(42); // err(...)
1529
1675
  * ```
1530
1676
  *
1531
- * @category Base Factories
1677
+ * @group Base factories
1532
1678
  */
1533
1679
  export const nullishOr = (type) => union(Undefined, Null, type);
1534
1680
  /**
@@ -1545,7 +1691,7 @@ export const nullishOr = (type) => union(Undefined, Null, type);
1545
1691
  * const error = NameAndAge.from(["Alice", -10]); // err
1546
1692
  * ```
1547
1693
  *
1548
- * @category Base Factories
1694
+ * @group Base factories
1549
1695
  */
1550
1696
  export const tuple = (...elements) => {
1551
1697
  const fromUnknown = (value) => {
@@ -1631,42 +1777,44 @@ export const formatTupleError = (formatTypeError) => createTypeErrorFormatter((e
1631
1777
  *
1632
1778
  * https://www.sqlite.org/c3ref/int64.html
1633
1779
  *
1634
- * @category Number
1780
+ * @group Number
1635
1781
  */
1636
- export const Int64 = brand("Int64", BigInt, (value) => value >= -9223372036854775808n && value <= 9223372036854775807n
1782
+ export const Int64 = /*#__PURE__*/ brand("Int64", BigInt, (value) => value >= -9223372036854775808n && value <= 9223372036854775807n
1637
1783
  ? ok(value)
1638
1784
  : err({ type: "Int64", value }));
1639
- export const formatInt64Error = createTypeErrorFormatter((error) => `The value ${error.value} is not a valid 64-bit signed integer (Int64).`);
1785
+ export const formatInt64Error =
1786
+ /*#__PURE__*/ createTypeErrorFormatter((error) => `The value ${error.value} is not a valid 64-bit signed integer (Int64).`);
1640
1787
  /**
1641
1788
  * Stringified {@link Int64}.
1642
1789
  *
1643
- * @category String
1790
+ * @group String
1644
1791
  */
1645
- export const Int64String = brand("Int64", NonEmptyTrimmedString, (value) => trySync(() => {
1792
+ export const Int64String = /*#__PURE__*/ brand("Int64", NonEmptyTrimmedString, (value) => trySync(() => {
1646
1793
  const maybeInt = globalThis.BigInt(value);
1647
1794
  Int64.orThrow(maybeInt);
1648
1795
  return value;
1649
1796
  }, () => ({ type: "Int64String", value })));
1650
- export const formatInt64StringError = createTypeErrorFormatter((error) => `The value ${error.value} is not a valid Int64 string.`);
1797
+ export const formatInt64StringError =
1798
+ /*#__PURE__*/ createTypeErrorFormatter((error) => `The value ${error.value} is not a valid Int64 string.`);
1651
1799
  /**
1652
1800
  * JSON-compatible value: string, {@link FiniteNumber}, boolean, null,
1653
1801
  * {@link JsonArray}, or {@link JsonObject}.
1654
1802
  *
1655
- * @category Base Types
1803
+ * @group Base Types
1656
1804
  */
1657
- export const JsonValue = recursive(() => union(String, FiniteNumber, Boolean, Null, JsonArray, JsonObject));
1805
+ export const JsonValue = /*#__PURE__*/ recursive(() => union(String, FiniteNumber, Boolean, Null, JsonArray, JsonObject));
1658
1806
  /**
1659
1807
  * JSON-compatible array of {@link JsonValue} elements.
1660
1808
  *
1661
- * @category Array
1809
+ * @group Array
1662
1810
  */
1663
- export const JsonArray = array(JsonValue);
1811
+ export const JsonArray = /*#__PURE__*/ array(JsonValue);
1664
1812
  /**
1665
1813
  * JSON-compatible object with string keys and {@link JsonValue} values.
1666
1814
  *
1667
- * @category Object
1815
+ * @group Object
1668
1816
  */
1669
- export const JsonObject = record(String, JsonValue);
1817
+ export const JsonObject = /*#__PURE__*/ record(String, JsonValue);
1670
1818
  export const parseJson = (value) => trySync(() => JSON.parse(value), (error) => ({
1671
1819
  type: `Json`,
1672
1820
  value,
@@ -1682,15 +1830,16 @@ export const parseJson = (value) => trySync(() => JSON.parse(value), (error) =>
1682
1830
  * const error = Json.from("invalid json"); // err
1683
1831
  * ```
1684
1832
  *
1685
- * @category String
1833
+ * @group String
1686
1834
  */
1687
- export const Json = brand("Json", String, (value) => {
1835
+ export const Json = /*#__PURE__*/ brand("Json", String, (value) => {
1688
1836
  const result = parseJson(value);
1689
1837
  if (!result.ok)
1690
1838
  return result;
1691
1839
  return ok(value);
1692
1840
  });
1693
- export const formatJsonError = createTypeErrorFormatter((error) => `Invalid JSON: ${error.value}. Error: ${error.message}`);
1841
+ export const formatJsonError =
1842
+ /*#__PURE__*/ createTypeErrorFormatter((error) => `Invalid JSON: ${error.value}. Error: ${error.message}`);
1694
1843
  export const jsonValueToJson = (value) => JSON.stringify(value);
1695
1844
  export const jsonToJsonValue = (value) => JSON.parse(value);
1696
1845
  /**
@@ -1713,7 +1862,7 @@ export const jsonToJsonValue = (value) => JSON.parse(value);
1713
1862
  * name: NonEmptyString100,
1714
1863
  * age: FiniteNumber,
1715
1864
  * });
1716
- * type Person = typeof Person.Type;
1865
+ * interface Person extends InferType<typeof Person> {}
1717
1866
  *
1718
1867
  * const [PersonJson, personToPersonJson, personJsonToPerson] = json(
1719
1868
  * Person,
@@ -1738,11 +1887,7 @@ export const json = (type, name) => {
1738
1887
  return validationResult;
1739
1888
  return ok(value);
1740
1889
  });
1741
- return [
1742
- BrandedJsonType,
1743
- jsonValueToJson,
1744
- jsonToJsonValue,
1745
- ];
1890
+ return [BrandedJsonType, jsonValueToJson, jsonToJsonValue];
1746
1891
  };
1747
1892
  /**
1748
1893
  * Optional {@link Type}.
@@ -1799,7 +1944,7 @@ export const isOptionalType = (x) => typeof x === "object" && x != null && "name
1799
1944
  * PartialUser.from({ age: -5 });
1800
1945
  * ```
1801
1946
  *
1802
- * @category Object
1947
+ * @group Object
1803
1948
  */
1804
1949
  export const partial = (props) => {
1805
1950
  const optionalProps = {};
@@ -1816,7 +1961,7 @@ export const partial = (props) => {
1816
1961
  * entirely, or set it to `null`, or set it to the non-null member of the
1817
1962
  * union.
1818
1963
  *
1819
- * @category Object
1964
+ * @group Object
1820
1965
  */
1821
1966
  export const nullableToOptional = (props) => {
1822
1967
  const transformedProps = {};
@@ -1836,9 +1981,9 @@ export const nullableToOptional = (props) => {
1836
1981
  /**
1837
1982
  * Create a new `object` {@link Type} by omitting some keys.
1838
1983
  *
1839
- * @category Object
1984
+ * @group Object
1840
1985
  */
1841
- export function omit(objectType, ...keys) {
1986
+ export const omit = (objectType, ...keys) => {
1842
1987
  const newProps = {};
1843
1988
  for (const key in objectType.props) {
1844
1989
  if (!keys.includes(key)) {
@@ -1847,18 +1992,7 @@ export function omit(objectType, ...keys) {
1847
1992
  }
1848
1993
  }
1849
1994
  return object(newProps);
1850
- }
1851
- export const maxMutationSize = 655360;
1852
- /**
1853
- * Evolu has to limit the maximum mutation size. Otherwise, sync couldn't use
1854
- * the `maxProtocolMessageRangesSize`. The max size is 640KB in bytes, measured
1855
- * via MessagePack. Evolu Protocol DbChange will be smaller thanks to various
1856
- * optimizations.
1857
- */
1858
- export const validMutationSize = (type) => brand("ValidMutationSize", type, (value) => pack(value).byteLength <= maxMutationSize
1859
- ? ok(value)
1860
- : err({ type: "ValidMutationSize", value }));
1861
- export const formatValidMutationSizeError = createTypeErrorFormatter((error) => `The mutation size exceeds the maximum limit of ${maxMutationSize} bytes. The provided mutation has a size of ${pack(error.value).byteLength} bytes.`);
1995
+ };
1862
1996
  /**
1863
1997
  * Formats Evolu Type errors into user-friendly messages.
1864
1998
  *
@@ -1937,7 +2071,7 @@ export const formatValidMutationSizeError = createTypeErrorFormatter((error) =>
1937
2071
  * };
1938
2072
  * ```
1939
2073
  *
1940
- * @category Utilities
2074
+ * @group Utilities
1941
2075
  */
1942
2076
  export const createFormatTypeError = (extraFormatter) => {
1943
2077
  const formatTypeError = (error) => {
@@ -1962,6 +2096,8 @@ export const createFormatTypeError = (extraFormatter) => {
1962
2096
  return formatFunctionError(error);
1963
2097
  case "Uint8Array":
1964
2098
  return formatUint8ArrayError(error);
2099
+ case "ArrayBuffer":
2100
+ return formatArrayBufferError(error);
1965
2101
  case "InstanceOf":
1966
2102
  return formatInstanceOfError(error);
1967
2103
  case "EvoluType":
@@ -2020,8 +2156,6 @@ export const createFormatTypeError = (extraFormatter) => {
2020
2156
  return formatInt64StringError(error);
2021
2157
  case "Json":
2022
2158
  return formatJsonError(error);
2023
- case "ValidMutationSize":
2024
- return formatValidMutationSizeError(error);
2025
2159
  // Composite Types
2026
2160
  case "SimplePassword":
2027
2161
  return formatSimplePasswordError(formatTypeError)(error);
@@ -2052,82 +2186,78 @@ export const createFormatTypeError = (extraFormatter) => {
2052
2186
  * Converts an Evolu {@link TypeError} to Standard Schema V1 issues format.
2053
2187
  *
2054
2188
  * This function recursively converts Evolu's typed errors into the Standard
2055
- * Schema issue format with proper path tracking for nested structures.
2189
+ * Schema issue format with proper path tracking for nested structures. The
2190
+ * `message` field contains the JSON-serialized typed error, which users can
2191
+ * deserialize and format using appropriate {@link TypeErrorFormatter}s.
2056
2192
  *
2057
- * @category Utilities
2193
+ * @group Utilities
2058
2194
  */
2059
- export const typeErrorToStandardSchemaIssues = (error, formatTypeError, path = []) => {
2195
+ export const typeErrorToStandardSchemaIssues = (error, path = []) => {
2060
2196
  if (error.type === "Array") {
2061
2197
  const arrayError = error;
2062
2198
  if (arrayError.reason.kind === "NotArray") {
2063
- return [{ message: formatTypeError(error), path }];
2199
+ return [{ message: JSON.stringify(error), path }];
2064
2200
  }
2065
- return typeErrorToStandardSchemaIssues(arrayError.reason.error, formatTypeError, [...path, arrayError.reason.index]);
2201
+ return typeErrorToStandardSchemaIssues(arrayError.reason.error, [...path, arrayError.reason.index]);
2066
2202
  }
2067
2203
  if (error.type === "Set") {
2068
2204
  const setError = error;
2069
2205
  if (setError.reason.kind === "NotSet") {
2070
- return [{ message: formatTypeError(error), path }];
2206
+ return [{ message: JSON.stringify(error), path }];
2071
2207
  }
2072
- return typeErrorToStandardSchemaIssues(setError.reason.error, formatTypeError, [...path, setError.reason.index]);
2208
+ return typeErrorToStandardSchemaIssues(setError.reason.error, [...path, setError.reason.index]);
2073
2209
  }
2074
2210
  if (error.type === "Object") {
2075
2211
  const objectError = error;
2076
2212
  if (objectError.reason.kind === "NotObject" ||
2077
2213
  objectError.reason.kind === "ExtraKeys") {
2078
- return [{ message: formatTypeError(error), path }];
2214
+ return [{ message: JSON.stringify(error), path }];
2079
2215
  }
2080
2216
  const issues = [];
2081
2217
  for (const [key, propError] of Object.entries(objectError.reason.errors)) {
2082
- issues.push(...typeErrorToStandardSchemaIssues(propError, formatTypeError, [...path, key]));
2218
+ issues.push(...typeErrorToStandardSchemaIssues(propError, [...path, key]));
2083
2219
  }
2084
2220
  return issues;
2085
2221
  }
2086
2222
  if (error.type === "ObjectWithRecord") {
2087
2223
  const objectWithRecordError = error;
2088
2224
  if (objectWithRecordError.reason.kind === "NotObject") {
2089
- return [{ message: formatTypeError(error), path }];
2225
+ return [{ message: JSON.stringify(error), path }];
2090
2226
  }
2091
2227
  if (objectWithRecordError.reason.kind === "IndexKey" ||
2092
2228
  objectWithRecordError.reason.kind === "IndexValue") {
2093
- return typeErrorToStandardSchemaIssues(objectWithRecordError.reason.error, formatTypeError, [...path, objectWithRecordError.reason.key]);
2229
+ return typeErrorToStandardSchemaIssues(objectWithRecordError.reason.error, [...path, objectWithRecordError.reason.key]);
2094
2230
  }
2095
2231
  const issues = [];
2096
2232
  for (const [key, propError] of Object.entries(objectWithRecordError.reason.errors)) {
2097
- issues.push(...typeErrorToStandardSchemaIssues(propError, formatTypeError, [...path, key]));
2233
+ issues.push(...typeErrorToStandardSchemaIssues(propError, [...path, key]));
2098
2234
  }
2099
2235
  return issues;
2100
2236
  }
2101
2237
  if (error.type === "Record") {
2102
2238
  const recordError = error;
2103
2239
  if (recordError.reason.kind === "NotRecord") {
2104
- return [{ message: formatTypeError(error), path }];
2240
+ return [{ message: JSON.stringify(error), path }];
2105
2241
  }
2106
- return typeErrorToStandardSchemaIssues(recordError.reason.error, formatTypeError, [...path, recordError.reason.key]);
2242
+ return typeErrorToStandardSchemaIssues(recordError.reason.error, [...path, recordError.reason.key]);
2107
2243
  }
2108
2244
  if (error.type === "Tuple") {
2109
2245
  const tupleError = error;
2110
2246
  if (tupleError.reason.kind === "InvalidLength") {
2111
- return [{ message: formatTypeError(error), path }];
2247
+ return [{ message: JSON.stringify(error), path }];
2112
2248
  }
2113
- return typeErrorToStandardSchemaIssues(tupleError.reason.error, formatTypeError, [...path, tupleError.reason.index]);
2249
+ return typeErrorToStandardSchemaIssues(tupleError.reason.error, [...path, tupleError.reason.index]);
2114
2250
  }
2115
2251
  if (error.type === "Union") {
2116
2252
  const unionError = error;
2117
- return unionError.errors.flatMap((err) => typeErrorToStandardSchemaIssues(err, formatTypeError, path));
2253
+ return unionError.errors.flatMap((err) => typeErrorToStandardSchemaIssues(err, path));
2118
2254
  }
2119
2255
  if (error.type === "Brand") {
2120
2256
  const brandError = error;
2121
2257
  if ("parentError" in brandError) {
2122
- return typeErrorToStandardSchemaIssues(brandError.parentError, formatTypeError, path);
2258
+ return typeErrorToStandardSchemaIssues(brandError.parentError, path);
2123
2259
  }
2124
- return [{ message: formatTypeError(error), path }];
2260
+ return [{ message: JSON.stringify(error), path }];
2125
2261
  }
2126
- return [{ message: formatTypeError(error), path }];
2262
+ return [{ message: JSON.stringify(error), path }];
2127
2263
  };
2128
- /**
2129
- * Shared formatter cache for Standard Schema integration - avoids circular
2130
- * dependency by lazily creating the formatter on first use rather than during
2131
- * module initialization.
2132
- */
2133
- let cachedStandardSchemaFormatTypeError;